[SCM] vlc/master: New upstream version 2.2.6
sramacher at users.alioth.debian.org
sramacher at users.alioth.debian.org
Sun Jun 18 15:03:29 UTC 2017
The following commit has been merged in the master branch:
commit 1f6a3b3e2866bcbe4c438fb5f4fe09a7e75488cf
Author: Sebastian Ramacher <sramacher at debian.org>
Date: Sun Jun 18 16:58:10 2017 +0200
New upstream version 2.2.6
diff --git a/ffmpeg-2-8-11/Changelog b/ffmpeg-2-8-11/Changelog
deleted file mode 100644
index 83004c4..0000000
--- a/ffmpeg-2-8-11/Changelog
+++ /dev/null
@@ -1,1909 +0,0 @@
-Entries are sorted chronologically from oldest to youngest within each release,
-releases are sorted from youngest to oldest.
-
-version 2.8.11
-- avcodec/h264_slice: Clear ref_counts on redundant slices
-- lavf/mov.c: Avoid heap allocation wrap in mov_read_uuid
-- lavf/mov.c: Avoid heap allocation wrap in mov_read_hdlr
-- avcodec/pictordec: Fix logic error
-- avcodec/movtextdec: Fix decode_styl() cleanup
-- lavf/matroskadec: fix is_keyframe for early Blocks
-- configure: bump year
-- avcodec/pngdec: Check trns more completely
-- avcodec/interplayvideo: Move parameter change check up
-- avcodec/mjpegdec: Check for for the bitstream end in mjpeg_decode_scan_progressive_ac()
-- avformat/flacdec: Check avio_read result when reading flac block header.
-- avcodec/utils: correct align value for interplay
-- avcodec/vp56: Check for the bitstream end, pass error codes on
-- avcodec/mjpegdec: Check remaining bitstream in ljpeg_decode_yuv_scan()
-- avcodec/pngdec: Fix off by 1 size in decode_zbuf()
-- avformat/avidec: skip odml master index chunks in avi_sync
-- avcodec/mjpegdec: Check for rgb before flipping
-- avutil/random_seed: Reduce the time needed on systems with very low precision clock()
-- avutil/random_seed: Improve get_generic_seed() with higher precision clock()
-- avformat/utils: Print verbose error message if stream count exceeds max_streams
-- avformat/options_table: Set the default maximum number of streams to 1000
-- avutil: Add av_image_check_size2()
-- avformat: Add max_streams option
-- avcodec/ffv1enc: Allocate smaller packet if the worst case size cannot be allocated
-- avcodec/mpeg4videodec: Fix undefined shifts in mpeg4_decode_sprite_trajectory()
-- avformat/oggdec: Skip streams in duration correction that did not had their duration set.
-- avcodec/ffv1enc: Fix size of first slice
-- pgssubdec: reset rle_data_len/rle_remaining_len on allocation error
-
-version 2.8.10
-- avformat/http: Match chunksize checks to master..3.0
-- Changelog: fix typos
-- ffserver: Check chunk size
-- Avoid using the term "file" and prefer "url" in some docs and comments
-- avformat/rtmppkt: Check for packet size mismatches
-- zmqsend: Initialize ret to 0
-- configure: check for strtoull on msvc
-- http: move chunk handling from http_read_stream() to http_buf_read().
-- http: make length/offset-related variables unsigned.
-
-version 2.8.9
-- avcodec/flacdec: Fix undefined shift in decode_subframe()
-- avcodec/get_bits: Fix get_sbits_long(0)
-- avformat/ffmdec: Check media type for chunks
-- avcodec/flacdec: Fix signed integer overflow in decode_subframe_fixed()
-- avcodec/flacdsp_template: Fix undefined shift in flac_decorrelate_indep_c
-- avformat/oggparsespeex: Check frames_per_packet and packet_size
-- avformat/utils: Check start/end before computing duration in update_stream_timings()
-- avcodec/flac_parser: Update nb_headers_buffered
-- avformat/idroqdec: Check chunk_size for being too large
-- filmstripdec: correctly check image dimensions
-- mss2: only use error correction for matching block counts
-- softfloat: decrease MIN_EXP to cover full float range
-- libopusdec: default to stereo for invalid number of channels
-- sbgdec: prevent NULL pointer access
-- smacker: limit recursion depth of smacker_decode_bigtree
-- mxfdec: fix NULL pointer dereference in mxf_read_packet_old
-- libschroedingerdec: fix leaking of framewithpts
-- libschroedingerdec: don't produce empty frames
-- softfloat: handle -INT_MAX correctly
-- pnmdec: make sure v is capped by maxval
-- smvjpegdec: make sure cur_frame is not negative
-- icodec: correctly check avio_read return value
-- icodec: fix leaking pkt on error
-- dvbsubdec: fix division by zero in compute_default_clut
-- proresdec_lgpl: explicitly check coff[3] against slice_data_size
-- escape124: reject codebook size 0
-- mpegts: prevent division by zero
-- matroskadec: fix NULL pointer dereference in webm_dash_manifest_read_header
-- mpegaudio_parser: don't return AVERROR_PATCHWELCOME
-- mxfdec: fix NULL pointer dereference
-- diracdec: check return code of get_buffer_with_edge
-- ppc: pixblockdsp: do unaligned block accesses correctly again
-- mpeg12dec: unref discarded picture from extradata
-- cavsdec: unref frame before referencing again
-- avformat: prevent triggering request_probe assert in ff_read_packet
-- avformat/mpeg: Adjust vid probe threshold to correct mis-detection
-- avcodec/rv40: Test remaining space in loop of get_dimension()
-- avcodec/ituh263dec: Avoid spending a long time in slice sync
-- avcodec/movtextdec: Add error message for tsmb_size check
-- avcodec/movtextdec: Fix tsmb_size check==0 check
-- avcodec/movtextdec: Fix potential integer overflow
-- avcodec/sunrast: Fix input buffer pointer check
-- avcodec/tscc: Check side data size before use
-- avcodec/rawdec: Check side data size before use
-- avcodec/msvideo1: Check side data size before use
-- avcodec/qpeg: Check side data size before use
-- avcodec/qtrle: Check side data size before use
-- avcodec/msrle: Check side data size before use
-- avcodec/kmvc: Check side data size before use
-- avcodec/idcinvideo: Check side data size before use
-- avcodec/cinepak: Check side data size before use
-- avcodec/8bps: Check side data size before use
-- avcodec/dvdsubdec: Fix off by 1 error
-- avcodec/dvdsubdec: Fix buf_size check
-- vp9: change order of operations in adapt_prob().
-- avcodec/interplayvideo: Check side data size before use
-- avformat/mxfdec: Check size to avoid integer overflow in mxf_read_utf16_string()
-- avcodec/mpegvideo_enc: Clear mmx state in ff_mpv_reallocate_putbitbuffer()
-- avcodec/utils: Clear MMX state before returning from avcodec_default_execute*()
-- cmdutils: fix typos
-- lavfi: fix typos
-- lavc: fix typos
-- tools: fix grammar error
-- avutil/mips/generic_macros_msa: rename macro variable which causes segfault for mips r6
-- videodsp: fix 1-byte overread in top/bottom READ_NUM_BYTES iterations.
-- avformat/avidec: Check nb_streams in read_gab2_sub()
-- avformat/avidec: Remove ancient assert
-- lavc/movtextdec.c: Avoid infinite loop on invalid data.
-- avcodec/ansi: Check dimensions
-- avcodec/cavsdsp: use av_clip_uint8() for idct
-
-version 2.8.8
-- avformat/movenc: Check packet in mov_write_single_packet() too
-- avformat/movenc: Factor check_pkt() out
-- avformat/utils: fix timebase error in avformat_seek_file()
-- avcodec/g726: Add missing ADDB output mask
-- avcodec/avpacket: clear side_data_elems
-- avcodec/ccaption_dec: Use simple array instead of AVBuffer
-- swscale/swscale_unscaled: Try to fix Rgb16ToPlanarRgb16Wrapper() with slices
-- swscale/swscale_unscaled: Fix packed_16bpc_bswap() with slices
-- avformat/avidec: Fix infinite loop in avi_read_nikon()
-- cmdutils: fix implicit declaration of SetDllDirectory function
-- cmdutils: check for SetDllDirectory() availability
-- avcodec/aacenc: Tighter input checks
-- libavcodec/wmalosslessdec: Check the remaining bits
-- avcodec/diracdec: Check numx/y
-- avcodec/indeo2: check ctab
-- avformat/swfdec: Fix inflate() error code check
-- avcodec/h264: Put context_count check back
-- cmdutils: remove the current working directory from the DLL search path on win32
-- avcodec/raw: Fix decoding of ilacetest.mov
-- avcodec/ffv1enc: Fix assertion failure with non zero bits per sample
-- avformat/oggdec: Fix integer overflow with invalid pts
-- ffplay: Fix invalid array index
-- avcodec/vp9_parser: Check the input frame sizes for being consistent
-- libavformat/rtpdec_asf: zero initialize the AVIOContext struct
-- libavutil/opt: Small bugfix in example.
-- libx264: Increase x264 opts character limit to 4096
-- avformat/mov: Check sample size
-- avformat/format: Fix registering a format more than once and related races
-- avcodec/flac_parser: Raise threshold for detecting invalid data
-- avfilter/vf_telecine: Make frame writable before writing into it
-- avcodec/mpc8: Correct end truncation
-- avcodec/mpegvideo: Do not clear the parse context during init
-- MAINTAINERs cleanup (remove myself from things i de facto do not maintain)
-- avcodec/h264: Fix off by 1 context count
-- avcodec/alsdec: Check r to prevent out of array read
-- avcodec/alsdec: fix max bits in ltp prefix code
-- avcodec/utils: check skip_samples signedness
-- avformat/mpegts: Do not trust BSSD descriptor, it is sometimes not an S302M stream
-- avcodec/bmp_parser: Check fsize
-- avcodec/bmp_parser: reset state
-- avcodec/bmp_parser: Fix remaining size
-- avcodec/bmp_parser: Fix frame_start_found in cross frame cases
-- avfilter/af_amix: do not fail if there are no samples in output_frame()
-- avformat/allformats: Making av_register_all() thread-safe.
-- avcodec/mpegvideo: Deallocate last/next picture earlier
-- avcodec/bmp_parser: Fix state
-- avformat/oggparseopus: Fix Undefined behavior in oggparseopus.c and libavformat/utils.c
-- doc/developer.texi: Add a code of conduct
-- avformat/avidec: Detect index with too short entries
-- avformat/utils: Check negative bps before shifting in ff_get_pcm_codec_id()
-- avformat/utils: Do not compute the bitrate from duration == 0
-- ffmpeg: Check that r_frame_rate is set before attempting to use it
-- swresample/rematrix: Use clipping s16 rematrixing if overflows are possible
-- swresample/rematrix: Use error diffusion to avoid error in the DC component of the matrix
-- libavformat/oggdec: Free stream private when header parsing fails.
-- avformat/utils: Check bps before using it in a shift in ff_get_pcm_codec_id()
-- avformat/oggparseopus: Check that granule pos is within the supported range
-- avcodec/mjpegdec: Do not try to detect last scan but apply idct after all scans for progressive jpeg
-- avformat/options_table: Add missing identifier for very strict compliance
-- librtmp: Avoid an infiniloop setting connection arguments
-- avformat/oggparsevp8: fix pts calculation on pages ending with an invisible frame
-
-
-version 2.8.7
-- avcodec/motion_est: Attempt to fix "short data segment overflowed" on IA64
-- avformat/ffmdec: Check pix_fmt
-- avcodec/ttaenc: Reallocate packet if its too small
-- pgssubdec: fix subpicture output colorspace and range
-- avcodec/ac3dec: Reset SPX when switching from EAC3 to AC3
-- avfilter/vf_drawtext: Check return code of load_glyph()
-- avcodec/takdec: add code that got somehow lost in process of REing
-- avcodec/apedec: fix decoding of stereo files with one channel full of silence
-- avcodec/avpacket: Fix off by 5 error
-- avcodec/h264: Fix for H.264 configuration parsing
-- avcodec/bmp_parser: Ensure remaining_size is not too small in startcode packet crossing corner case
-- avfilter/src_movie: fix how we check for overflows with seek_point
-- avcodec/j2kenc: Add attribution to OpenJPEG project:
-- avcodec/h264_slice: Check PPS more extensively when its not copied
-- avcodec/libutvideodec: copy frame so it has reference counters when refcounted_frames is set
-- avformat/rtpdec_jpeg: fix low contrast image on low quality setting
-- avcodec/mjpegenc_common: Store approximate aspect if exact cannot be stored
-- lavc/hevc: Allow arbitrary garbage in bytestream as long as at least one NAL unit is found.
-- avcodec/resample: Remove disabled and faulty code
-- indeo2: Fix banding artefacts
-- indeo2data: K&R formatting cosmetics
-- avcodec/imgconvert: Support non-planar colorspaces while padding
-- avutil/random_seed: Add the runtime in cycles of the main loop to the entropy pool
-- avutil/channel_layout: AV_CH_LAYOUT_6POINT1_BACK not reachable in parsing
-- avformat/concatdec: set safe mode to enabled instead of auto
-- avformat/utils: fix dts from pts code in compute_pkt_fields() during ascending delay
-- avformat/rtpenc: Fix integer overflow in NTP_TO_RTP_FORMAT
-- avformat/cache: Fix memleak of tree entries
-- lavf/mov: downgrade sidx errors to non-fatal warnings; fixes trac #5216 (cherry picked from commit 22dbc1caaf13e4bb17c9e0164a5b1ccaf490e428)
-- lavf/mov: fix sidx with edit lists (cherry picked from commit 3617e69d50dd9dd07b5011dfb9477a9d1a630354)
-- avcodec/mjpegdec: Fix decoding slightly odd progressive jpeg
-- libwebpenc_animencoder: print library messages in verbose log levels
-- libwebpenc_animencoder: zero initialize the WebPAnimEncoderOptions struct
-- doc/utils: fix typo for min() description
-- avcodec/avpacket: clear priv in av_init_packet()
-- swscale/utils: Fix chrSrcHSubSample for GBRAP16
-- swscale/input: Fix GBRAP16 input
-- postproc: fix unaligned access
-- avutil/pixdesc: Make get_color_type() aware of CIE XYZ formats
-- avcodec/h264: Execute error concealment before marking the frame as done.
-- swscale/x86/output: Fix yuv2planeX_16* with unaligned destination
-- swscale/x86/output: Move code into yuv2planeX_mainloop
-- avutil/frame: Free destination qp_table_buf in frame_copy_props()
-
-
-version 2.8.6
-- avcodec/jpeg2000dec: More completely check cdef
-- avutil/opt: check for and handle errors in av_opt_set_dict2()
-- avcodec/flacenc: fix calculation of bits required in case of custom sample rate
-- avformat: Document urls a bit
-- avformat/libquvi: Set default demuxer and protocol limitations
-- avformat/concat: Check protocol prefix
-- doc/demuxers: Document enable_drefs and use_absolute_path
-- avcodec/mjpegdec: Check for end for both bytes in unescaping
-- avcodec/mpegvideo_enc: Check for integer overflow in ff_mpv_reallocate_putbitbuffer()
-- avformat/avformat: Replace some references to filenames by urls
-- avcodec/wmaenc: Check ff_wma_init() for failure
-- avcodec/mpeg12enc: Move high resolution thread check to before initializing threads
-- avformat/img2dec: Use AVOpenCallback
-- avformat/avio: Limit url option parsing to the documented cases
-- avformat/img2dec: do not interpret the filename by default if a IO context has been opened
-- avcodec/ass_split: Fix null pointer dereference in ff_ass_style_get()
-- mov: Add an option to toggle dref opening
-- avcodec/gif: Fix lzw buffer size
-- avcodec/put_bits: Assert buf_ptr in flush_put_bits()
-- avcodec/tiff: Check subsample & rps values more completely
-- swscale/swscale: Add some sanity checks for srcSlice* parameters
-- swscale/x86/rgb2rgb_template: Fix planar2x() for short width
-- swscale/swscale_unscaled: Fix odd height inputs for bayer_to_yv12_wrapper()
-- swscale/swscale_unscaled: Fix odd height inputs for bayer_to_rgb24_wrapper()
-- avcodec/aacenc: Check both channels for finiteness
-- asfdec_o: check for too small size in asf_read_unknown
-- asfdec_o: break if EOF is reached after asf_read_packet_header
-- asfdec_o: make sure packet_size is non-zero before seeking
-- asfdec_o: prevent overflow causing seekback
-- asfdec_o: check avio_skip in asf_read_simple_index
-- asfdec_o: reject size > INT64_MAX in asf_read_unknown
-- asfdec_o: only set asf_pkt->data_size after sanity checks
-- Merge commit '8375dc1dd101d51baa430f34c0bcadfa37873896'
-- dca: fix misaligned access in avpriv_dca_convert_bitstream
-- brstm: fix missing closing brace
-- brstm: also allocate b->table in read_packet
-- brstm: make sure an ADPC chunk was read for adpcm_thp
-- vorbisdec: reject rangebits 0 with non-0 partitions
-- vorbisdec: reject channel mapping with less than two channels
-- ffmdec: reset packet_end in case of failure
-- avformat/ipmovie: put video decoding_map_size into packet and use it in decoder
-- avformat/brstm: fix overflow
-
-
-version 2.8.5
-- avformat/hls: Even stricter URL checks
-- avformat/hls: More strict url checks
-- avcodec/pngenc: Fix mixed up linesizes
-- avcodec/pngenc: Replace memcpy by av_image_copy()
-- swscale/vscale: Check that 2 tap filters are bilinear before using bilinear code
-- swscale: Move VScalerContext into vscale.c
-- swscale/utils: Detect and skip unneeded sws_setColorspaceDetails() calls
-- swscale/yuv2rgb: Increase YUV2RGB table headroom
-- swscale/yuv2rgb: Factor YUVRGB_TABLE_LUMA_HEADROOM out
-- avformat/hls: forbid all protocols except http(s) & file
-- avformat/aviobuf: Fix end check in put_str16()
-- avformat/asfenc: Check pts
-- avcodec/mpeg4video: Check time_incr
-- avcodec/wavpackenc: Check the number of channels
-- avcodec/wavpackenc: Headers are per channel
-- avcodec/aacdec_template: Check id_map
-- avcodec/dvdec: Fix "left shift of negative value -254"
-- avcodec/g2meet: Check for ff_els_decode_bit() failure in epic_decode_run_length()
-- avcodec/mjpegdec: Fix negative shift
-- avcodec/mss2: Check for repeat overflow
-- avformat: Add integer fps from 31 to 60 to get_std_framerate()
-- avformat/ivfenc: fix division by zero
-- avcodec/mpegvideo_enc: Clip bits_per_raw_sample within valid range
-- avfilter/vf_scale: set proper out frame color range
-- avcodec/motion_est: Fix mv_penalty table size
-- avcodec/h264_slice: Fix integer overflow in implicit weight computation
-- swscale/utils: Use normal bilinear scaler if fast cannot be used due to tiny dimensions
-- avcodec/put_bits: Always check buffer end before writing
-- mjpegdec: extend check for incompatible values of s->rgb and s->ls
-- swscale/utils: Fix intermediate format for cascaded alpha downscaling
-- avformat/mov: Update handbrake_version threshold for full mp3 parsing
-- x86/float_dsp: zero extend offset from ff_scalarproduct_float_sse
-- avfilter/vf_zoompan: do not free frame we pushed to lavfi
-- nuv: sanitize negative fps rate
-- nutdec: reject negative value_len in read_sm_data
-- xwddec: prevent overflow of lsize * avctx->height
-- nutdec: only copy the header if it exists
-- exr: fix out of bounds read in get_code
-- on2avc: limit number of bits to 30 in get_egolomb
-
-
-version 2.8.4
-- rawdec: only exempt BIT0 with need_copy from buffer sanity check
-- mlvdec: check that index_entries exist
-- avcodec/mpeg4videodec: also for empty partitioned slices
-- avcodec/h264_refs: Fix long_idx check
-- avcodec/h264_mc_template: prefetch list1 only if it is used in the MB
-- avcodec/h264_slice: Simplify ref2frm indexing
-- avfilter/vf_mpdecimate: Add missing emms_c()
-- sonic: make sure num_taps * channels is not larger than frame_size
-- opus_silk: fix typo causing overflow in silk_stabilize_lsf
-- ffm: reject invalid codec_id and codec_type
-- golomb: always check for invalid UE golomb codes in get_ue_golomb
-- sbr_qmf_analysis: sanitize input for 32-bit imdct
-- sbrdsp_fixed: assert that input values are in the valid range
-- aacsbr: ensure strictly monotone time borders
-- aacenc: update max_sfb when num_swb changes
-- aaccoder: prevent crash of anmr coder
-- ffmdec: reject zero-sized chunks
-- swscale/x86/rgb2rgb_template: Fallback to mmx in interleaveBytes() if the alignment is insufficient for SSE*
-- swscale/x86/rgb2rgb_template: Do not crash on misaligend stride
-- avformat/mxfenc: Do not crash if there is no packet in the first stream
-- lavf/tee: fix side data double free.
-- avformat/hlsenc: Check the return code of avformat_write_header()
-- avformat/mov: Enable parser for mp3s by old HandBrake
-- avformat/mxfenc: Fix integer overflow in length computation
-- avformat/utils: estimate_timings_from_pts - increase retry counter, fixes invalid duration for ts files with hevc codec
-- avformat/matroskaenc: Check codecdelay before use
-- avutil/mathematics: Fix division by 0
-- mjpegdec: consider chroma subsampling in size check
-- libvpxenc: remove some unused ctrl id mappings
-- avcodec/vp3: ensure header is parsed successfully before tables
-- avcodec/jpeg2000dec: Check bpno in decode_cblk()
-- avcodec/pgssubdec: Fix left shift of 255 by 24 places cannot be represented in type int
-- swscale/utils: Fix for runtime error: left shift of negative value -1
-- avcodec/hevc: Fix integer overflow of entry_point_offset
-- avcodec/dirac_parser: Check that there is a previous PU before accessing it
-- avcodec/dirac_parser: Add basic validity checks for next_pu_offset and prev_pu_offset
-- avcodec/dirac_parser: Fix potential overflows in pointer checks
-- avcodec/wmaprodec: Check bits per sample to be within the range not causing integer overflows
-- avcodec/wmaprodec: Fix overflow of cutoff
-- avformat/smacker: fix integer overflow with pts_inc
-- avcodec/vp3: Fix "runtime error: left shift of negative value"
-- avformat/riffdec: Initialize bitrate
-- mpegencts: Fix overflow in cbr mode period calculations
-- avutil/timecode: Fix fps check
-- avutil/mathematics: return INT64_MIN (=AV_NOPTS_VALUE) from av_rescale_rnd() for overflows
-- avcodec/apedec: Check length in long_filter_high_3800()
-- avcodec/vp3: always set pix_fmt in theora_decode_header()
-- avcodec/mpeg4videodec: Check available data before reading custom matrix
-- avutil/mathematics: Do not treat INT64_MIN as positive in av_rescale_rnd
-- avutil/integer: Fix av_mod_i() with negative dividend
-- avformat/dump: Fix integer overflow in av_dump_format()
-- avcodec/h264_refs: Check that long references match before use
-- avcodec/utils: Clear dimensions in ff_get_buffer() on failure
-- avcodec/utils: Use 64bit for aspect ratio calculation in avcodec_string()
-- avcodec/hevc: Check max ctb addresses for WPP
-- avcodec/vp3: Clear context on reinitialization failure
-- avcodec/hevc: allocate entries unconditionally
-- avcodec/hevc_cabac: Fix multiple integer overflows
-- avcodec/jpeg2000dwt: Check ndeclevels before calling dwt_encode*()
-- avcodec/jpeg2000dwt: Check ndeclevels before calling dwt_decode*()
-- avcodec/hevc: Check entry_point_offsets
-- lavf/rtpenc_jpeg: Less strict check for standard Huffman tables.
-- avcodec/ffv1dec: Clear quant_table_count if its invalid
-- avcodec/ffv1dec: Print an error if the quant table count is invalid
-- doc/filters/drawtext: fix centering example
-
-
-version 2.8.3
-- avcodec/cabac: Check initial cabac decoder state
-- avcodec/cabac_functions: Fix "left shift of negative value -31767"
-- avcodec/h264_slice: Limit max_contexts when slice_context_count is initialized
-- rtmpcrypt: Do the xtea decryption in little endian mode
-- avformat/matroskadec: Check subtitle stream before dereferencing
-- avcodec/pngdec: Replace assert by request for sample for unsupported TRNS cases
-- avformat/utils: Do not init parser if probing is unfinished
-- avcodec/jpeg2000dec: Fix potential integer overflow with tile dimensions
-- avcodec/jpeg2000: Use av_image_check_size() in ff_jpeg2000_init_component()
-- avcodec/wmaprodec: Check for overread in decode_packet()
-- avcodec/smacker: Check that the data size is a multiple of a sample vector
-- avcodec/takdec: Skip last p2 sample (which is unused)
-- avcodec/dxtory: Fix input size check in dxtory_decode_v1_410()
-- avcodec/dxtory: Fix input size check in dxtory_decode_v1_420()
-- avcodec/error_resilience: avoid accessing previous or next frames tables beyond height
-- avcodec/dpx: Move need_align to act per line
-- avcodec/flashsv: Check size before updating it
-- avcodec/ivi: Check image dimensions
-- avcodec/utils: Better check for channels in av_get_audio_frame_duration()
-- avcodec/jpeg2000dec: Check for duplicate SIZ marker
-- aacsbr: don't call sbr_dequant twice without intermediate read_sbr_data
-- hqx: correct type and size check of info_offset
-- mxfdec: check edit_rate also for physical_track
-- avcodec/jpeg2000: Change coord to 32bit to support larger than 32k width or height
-- avcodec/jpeg2000dec: Check SIZ dimensions to be within the supported range
-- avcodec/jpeg2000: Check comp coords to be within the supported size
-- mpegvideo: clear overread in clear_context
-- avcodec/avrndec: Use the AVFrame format instead of the context
-- dds: disable palette flag for compressed images
-- dds: validate compressed source buffer size
-- dds: validate source buffer size before copying
-- dvdsubdec: validate offset2 similar to offset1
-- brstm: reject negative sample rate
-- aacps: avoid division by zero in stereo_processing
-- softfloat: assert when the argument of av_sqrt_sf is negative
-
-version 2.8.2
-- various fixes in the aac_fixed decoder
-- various fixes in softfloat
-- swresample/resample: increase precision for compensation
-- lavf/mov: add support for sidx fragment indexes
-- avformat/mxfenc: Only store user comment related tags when needed
-- tests/fate/avformat: Fix fate-lavf
-- doc/ffmpeg: Clarify that the sdp_file option requires an rtp output.
-- ffmpeg: Don't try and write sdp info if none of the outputs had an rtp format.
-- apng: use correct size for output buffer
-- jvdec: avoid unsigned overflow in comparison
-- avcodec/jpeg2000dec: Clip all tile coordinates
-- avcodec/microdvddec: Check for string end in 'P' case
-- avcodec/dirac_parser: Fix undefined memcpy() use
-- avformat/xmv: Discard remainder of packet on error
-- avformat/xmv: factor return check out of if/else
-- avcodec/mpeg12dec: Do not call show_bits() with invalid bits
-- avcodec/faxcompr: Add missing runs check in decode_uncompressed()
-- libavutil/channel_layout: Check strtol*() for failure
-- avformat/mpegts: Only start probing data streams within probe_packets
-- avcodec/hevc_ps: Check chroma_format_idc
-- avcodec/ffv1dec: Check for 0 quant tables
-- avcodec/mjpegdec: Reinitialize IDCT on BPP changes
-- avcodec/mjpegdec: Check index in ljpeg_decode_yuv_scan() before using it
-- avutil/file_open: avoid file handle inheritance on Windows
-- avcodec/h264_slice: Disable slice threads if there are multiple access units in a packet
-- avformat/hls: update cookies on setcookie response
-- opusdec: Don't run vector_fmul_scalar on zero length arrays
-- avcodec/opusdec: Fix extra samples read index
-- avcodec/ffv1: Initialize vlc_state on allocation
-- avcodec/ffv1dec: update progress in case of broken pointer chains
-- avcodec/ffv1dec: Clear slice coordinates if they are invalid or slice header decoding fails for other reasons
-- rtsp: Allow $ as interleaved packet indicator before a complete response header
-- videodsp: don't overread edges in vfix3 emu_edge.
-- avformat/mp3dec: improve junk skipping heuristic
-- concatdec: fix file_start_time calculation regression
-- avcodec: loongson optimize h264dsp idct and loop filter with mmi
-- avcodec/jpeg2000dec: Clear properties in jpeg2000_dec_cleanup() too
-- avformat/hls: add support for EXT-X-MAP
-- avformat/hls: fix segment selection regression on track changes of live streams
-- configure: Require libkvazaar < 0.7.
-- avcodec/vp8: Do not use num_coeff_partitions in thread/buffer setup
-
-
-version 2.8.1:
-- swscale: fix ticket #4881
-- doc: fix spelling errors
-- hls: only seek if there is an offset
-- asfdec: add more checks for size left in asf packet buffer
-- asfdec: alloc enough space for storing name in asf_read_metadata_obj
-- avcodec/pngdec: Check blend_op.
-- h264_mp4toannexb: fix pps offfset fault when there are more than one sps in avcc
-- avcodec/h264_mp4toannexb_bsf: Use av_freep() to free spspps_buf
-- avformat/avidec: Workaround broken initial frame
-- avformat/hls: fix some cases of HLS streams which require cookies
-- avcodec/pngdec: reset has_trns after every decode_frame_png()
-- lavf/img2dec: Fix memory leak
-- avcodec/mp3: fix skipping zeros
-- avformat/srtdec: make sure we probe a number
-- configure: check for ID3D11VideoContext
-- avformat/vobsub: compare correct packet stream IDs
-- avformat/srtdec: more lenient first line probing
-- avformat/srtdec: fix number check for the first character
-- avcodec/mips: build fix for MSA 64bit
-- avcodec/mips: build fix for MSA
-- avformat/httpauth: Add space after commas in HTTP/RTSP auth header
-- libavformat/hlsenc: Use of uninitialized memory unlinking old files
-- avcodec/x86/sbrdsp: Fix using uninitialized upper 32bit of noise
-- avcodec/ffv1dec: Fix off by 1 error in quant_table_count check
-- avcodec/ffv1dec: Explicitly check read_quant_table() return value
-- dnxhddata: correct weight tables
-- dnxhddec: decode and use interlace mb flag
-- swscale: fix ticket #4877
-- avcodec/rangecoder: Check e
-- avcodec/ffv1: separate slice_count from max_slice_count
-- swscale: fix ticket 4850
-- cmdutils: Filter dst/srcw/h
-- avutil/log: fix zero length gnu_printf format string warning
-- lavf/webvttenc: Require webvtt file to contain exactly one WebVTT stream.
-- swscale/swscale: Fix "unused variable" warning
-- avcodec/mjpegdec: Fix decoding RGBA RCT LJPEG
-- MAINTAINERS: add 2.8, drop 2.2
-- doc: mention libavcodec can decode Opus natively
-- hevc: properly handle no_rasl_output_flag when removing pictures from the DPB
-- avfilter/af_ladspa: process all channels for nb_handles > 1
-- configure: add libsoxr to swresample's pkgconfig
-- lavc: Fix compilation with --disable-everything --enable-parser=mpeg4video.
-
-version 2.8:
-- colorkey video filter
-- BFSTM/BCSTM demuxer
-- little-endian ADPCM_THP decoder
-- Hap decoder and encoder
-- DirectDraw Surface image/texture decoder
-- ssim filter
-- optional new ASF demuxer
-- showvolume filter
-- Many improvements to the JPEG 2000 decoder
-- Go2Meeting decoding support
-- adrawgraph audio and drawgraph video filter
-- removegrain video filter
-- Intel QSV-accelerated MPEG-2 video and HEVC encoding
-- Intel QSV-accelerated MPEG-2 video and HEVC decoding
-- Intel QSV-accelerated VC-1 video decoding
-- libkvazaar HEVC encoder
-- erosion, dilation, deflate and inflate video filters
-- Dynamic Audio Normalizer as dynaudnorm filter
-- Reverse video and areverse audio filter
-- Random filter
-- deband filter
-- AAC fixed-point decoding
-- sidechaincompress audio filter
-- bitstream filter for converting HEVC from MP4 to Annex B
-- acrossfade audio filter
-- allyuv and allrgb video sources
-- atadenoise video filter
-- OS X VideoToolbox support
-- aphasemeter filter
-- showfreqs filter
-- vectorscope filter
-- waveform filter
-- hstack and vstack filter
-- Support DNx100 (1440x1080 at 8)
-- VAAPI hevc hwaccel
-- VDPAU hevc hwaccel
-- framerate filter
-- Switched default encoders for webm to VP9 and Opus
-- Removed experimental flag from the JPEG 2000 encoder
-
-
-version 2.7:
-- FFT video filter
-- TDSC decoder
-- DTS lossless extension (XLL) decoding (not lossless, disabled by default)
-- showwavespic filter
-- DTS decoding through libdcadec
-- Drop support for nvenc API before 5.0
-- nvenc HEVC encoder
-- Detelecine filter
-- Intel QSV-accelerated H.264 encoding
-- MMAL-accelerated H.264 decoding
-- basic APNG encoder and muxer with default extension "apng"
-- unpack DivX-style packed B-frames in MPEG-4 bitstream filter
-- WebM Live Chunk Muxer
-- nvenc level and tier options
-- chorus filter
-- Canopus HQ/HQA decoder
-- Automatically rotate videos based on metadata in ffmpeg
-- improved Quickdraw compatibility
-- VP9 high bit-depth and extended colorspaces decoding support
-- WebPAnimEncoder API when available for encoding and muxing WebP
-- Direct3D11-accelerated decoding
-- Support Secure Transport
-- Multipart JPEG demuxer
-
-
-version 2.6:
-- nvenc encoder
-- 10bit spp filter
-- colorlevels filter
-- RIFX format for *.wav files
-- RTP/mpegts muxer
-- non continuous cache protocol support
-- tblend filter
-- cropdetect support for non 8bpp, absolute (if limit >= 1) and relative (if limit < 1.0) threshold
-- Camellia symmetric block cipher
-- OpenH264 encoder wrapper
-- VOC seeking support
-- Closed caption Decoder
-- fspp, uspp, pp7 MPlayer postprocessing filters ported to native filters
-- showpalette filter
-- Twofish symmetric block cipher
-- Support DNx100 (960x720 at 8)
-- eq2 filter ported from libmpcodecs as eq filter
-- removed libmpcodecs
-- Changed default DNxHD colour range in QuickTime .mov derivatives to mpeg range
-- ported softpulldown filter from libmpcodecs as repeatfields filter
-- dcshift filter
-- RTP depacketizer for loss tolerant payload format for MP3 audio (RFC 5219)
-- RTP depacketizer for AC3 payload format (RFC 4184)
-- palettegen and paletteuse filters
-- VP9 RTP payload format (draft 0) experimental depacketizer
-- RTP depacketizer for DV (RFC 6469)
-- DXVA2-accelerated HEVC decoding
-- AAC ELD 480 decoding
-- Intel QSV-accelerated H.264 decoding
-- DSS SP decoder and DSS demuxer
-- Fix stsd atom corruption in DNxHD QuickTimes
-- Canopus HQX decoder
-- RTP depacketization of T.140 text (RFC 4103)
-- Port MIPS optimizations to 64-bit
-
-
-version 2.5:
-- HEVC/H.265 RTP payload format (draft v6) packetizer
-- SUP/PGS subtitle demuxer
-- ffprobe -show_pixel_formats option
-- CAST128 symmetric block cipher, ECB mode
-- STL subtitle demuxer and decoder
-- libutvideo YUV 4:2:2 10bit support
-- XCB-based screen-grabber
-- UDP-Lite support (RFC 3828)
-- xBR scaling filter
-- AVFoundation screen capturing support
-- ffserver supports codec private options
-- creating DASH compatible fragmented MP4, MPEG-DASH segmenting muxer
-- WebP muxer with animated WebP support
-- zygoaudio decoding support
-- APNG demuxer
-- postproc visualization support
-
-
-version 2.4:
-- Icecast protocol
-- ported lenscorrection filter from frei0r filter
-- large optimizations in dctdnoiz to make it usable
-- ICY metadata are now requested by default with the HTTP protocol
-- support for using metadata in stream specifiers in fftools
-- LZMA compression support in TIFF decoder
-- H.261 RTP payload format (RFC 4587) depacketizer and experimental packetizer
-- HEVC/H.265 RTP payload format (draft v6) depacketizer
-- added codecview filter to visualize information exported by some codecs
-- Matroska 3D support thorugh side data
-- HTML generation using texi2html is deprecated in favor of makeinfo/texi2any
-- silenceremove filter
-
-
-version 2.3:
-- AC3 fixed-point decoding
-- shuffleplanes filter
-- subfile protocol
-- Phantom Cine demuxer
-- replaygain data export
-- VP7 video decoder
-- Alias PIX image encoder and decoder
-- Improvements to the BRender PIX image decoder
-- Improvements to the XBM decoder
-- QTKit input device
-- improvements to OpenEXR image decoder
-- support decoding 16-bit RLE SGI images
-- GDI screen grabbing for Windows
-- alternative rendition support for HTTP Live Streaming
-- AVFoundation input device
-- Direct Stream Digital (DSD) decoder
-- Magic Lantern Video (MLV) demuxer
-- On2 AVC (Audio for Video) decoder
-- support for decoding through DXVA2 in ffmpeg
-- libbs2b-based stereo-to-binaural audio filter
-- libx264 reference frames count limiting depending on level
-- native Opus decoder
-- display matrix export and rotation API
-- WebVTT encoder
-- showcqt multimedia filter
-- zoompan filter
-- signalstats filter
-- hqx filter (hq2x, hq3x, hq4x)
-- flanger filter
-- Image format auto-detection
-- LRC demuxer and muxer
-- Samba protocol (via libsmbclient)
-- WebM DASH Manifest muxer
-- libfribidi support in drawtext
-
-
-version 2.2:
-
-- HNM version 4 demuxer and video decoder
-- Live HDS muxer
-- setsar/setdar filters now support variables in ratio expressions
-- elbg filter
-- string validation in ffprobe
-- support for decoding through VDPAU in ffmpeg (the -hwaccel option)
-- complete Voxware MetaSound decoder
-- remove mp3_header_compress bitstream filter
-- Windows resource files for shared libraries
-- aeval filter
-- stereoscopic 3d metadata handling
-- WebP encoding via libwebp
-- ATRAC3+ decoder
-- VP8 in Ogg demuxing
-- side & metadata support in NUT
-- framepack filter
-- XYZ12 rawvideo support in NUT
-- Exif metadata support in WebP decoder
-- OpenGL device
-- Use metadata_header_padding to control padding in ID3 tags (currently used in
- MP3, AIFF, and OMA files), FLAC header, and the AVI "junk" block.
-- Mirillis FIC video decoder
-- Support DNx444
-- libx265 encoder
-- dejudder filter
-- Autodetect VDA like all other hardware accelerations
-- aliases and defaults for Ogg subtypes (opus, spx)
-
-
-version 2.1:
-
-- aecho filter
-- perspective filter ported from libmpcodecs
-- ffprobe -show_programs option
-- compand filter
-- RTMP seek support
-- when transcoding with ffmpeg (i.e. not streamcopying), -ss is now accurate
- even when used as an input option. Previous behavior can be restored with
- the -noaccurate_seek option.
-- ffmpeg -t option can now be used for inputs, to limit the duration of
- data read from an input file
-- incomplete Voxware MetaSound decoder
-- read EXIF metadata from JPEG
-- DVB teletext decoder
-- phase filter ported from libmpcodecs
-- w3fdif filter
-- Opus support in Matroska
-- FFV1 version 1.3 is stable and no longer experimental
-- FFV1: YUVA(444,422,420) 9, 10 and 16 bit support
-- changed DTS stream id in lavf mpeg ps muxer from 0x8a to 0x88, to be
- more consistent with other muxers.
-- adelay filter
-- pullup filter ported from libmpcodecs
-- ffprobe -read_intervals option
-- Lossless and alpha support for WebP decoder
-- Error Resilient AAC syntax (ER AAC LC) decoding
-- Low Delay AAC (ER AAC LD) decoding
-- mux chapters in ASF files
-- SFTP protocol (via libssh)
-- libx264: add ability to encode in YUVJ422P and YUVJ444P
-- Fraps: use BT.709 colorspace by default for yuv, as reference fraps decoder does
-- make decoding alpha optional for prores, ffv1 and vp6 by setting
- the skip_alpha flag.
-- ladspa wrapper filter
-- native VP9 decoder
-- dpx parser
-- max_error_rate parameter in ffmpeg
-- PulseAudio output device
-- ReplayGain scanner
-- Enhanced Low Delay AAC (ER AAC ELD) decoding (no LD SBR support)
-- Linux framebuffer output device
-- HEVC decoder
-- raw HEVC, HEVC in MOV/MP4, HEVC in Matroska, HEVC in MPEG-TS demuxing
-- mergeplanes filter
-
-
-version 2.0:
-
-- curves filter
-- reference-counting for AVFrame and AVPacket data
-- ffmpeg now fails when input options are used for output file
- or vice versa
-- support for Monkey's Audio versions from 3.93
-- perms and aperms filters
-- audio filtering support in ffplay
-- 10% faster aac encoding on x86 and MIPS
-- sine audio filter source
-- WebP demuxing and decoding support
-- ffmpeg options -filter_script and -filter_complex_script, which allow a
- filtergraph description to be read from a file
-- OpenCL support
-- audio phaser filter
-- separatefields filter
-- libquvi demuxer
-- uniform options syntax across all filters
-- telecine filter
-- interlace filter
-- smptehdbars source
-- inverse telecine filters (fieldmatch and decimate)
-- colorbalance filter
-- colorchannelmixer filter
-- The matroska demuxer can now output proper verbatim ASS packets. It will
- become the default at the next libavformat major bump.
-- decent native animated GIF encoding
-- asetrate filter
-- interleave filter
-- timeline editing with filters
-- vidstabdetect and vidstabtransform filters for video stabilization using
- the vid.stab library
-- astats filter
-- trim and atrim filters
-- ffmpeg -t and -ss (output-only) options are now sample-accurate when
- transcoding audio
-- Matroska muxer can now put the index at the beginning of the file.
-- extractplanes filter
-- avectorscope filter
-- ADPCM DTK decoder
-- ADP demuxer
-- RSD demuxer
-- RedSpark demuxer
-- ADPCM IMA Radical decoder
-- zmq filters
-- DCT denoiser filter (dctdnoiz)
-- Wavelet denoiser filter ported from libmpcodecs as owdenoise (formerly "ow")
-- Apple Intermediate Codec decoder
-- Escape 130 video decoder
-- FTP protocol support
-- V4L2 output device
-- 3D LUT filter (lut3d)
-- SMPTE 302M audio encoder
-- support for slice multithreading in libavfilter
-- Hald CLUT support (generation and filtering)
-- VC-1 interlaced B-frame support
-- support for WavPack muxing (raw and in Matroska)
-- XVideo output device
-- vignette filter
-- True Audio (TTA) encoder
-- Go2Webinar decoder
-- mcdeint filter ported from libmpcodecs
-- sab filter ported from libmpcodecs
-- ffprobe -show_chapters option
-- WavPack encoding through libwavpack
-- rotate filter
-- spp filter ported from libmpcodecs
-- libgme support
-- psnr filter
-
-
-version 1.2:
-
-- VDPAU hardware acceleration through normal hwaccel
-- SRTP support
-- Error diffusion dither in Swscale
-- Chained Ogg support
-- Theora Midstream reconfiguration support
-- EVRC decoder
-- audio fade filter
-- filtering audio with unknown channel layout
-- allpass, bass, bandpass, bandreject, biquad, equalizer, highpass, lowpass
- and treble audio filter
-- improved showspectrum filter, with multichannel support and sox-like colors
-- histogram filter
-- tee muxer
-- il filter ported from libmpcodecs
-- support ID3v2 tags in ASF files
-- encrypted TTA stream decoding support
-- RF64 support in WAV muxer
-- noise filter ported from libmpcodecs
-- Subtitles character encoding conversion
-- blend filter
-- stereo3d filter ported from libmpcodecs
-
-
-version 1.1:
-
-- stream disposition information printing in ffprobe
-- filter for loudness analysis following EBU R128
-- Opus encoder using libopus
-- ffprobe -select_streams option
-- Pinnacle TARGA CineWave YUV16 decoder
-- TAK demuxer, decoder and parser
-- DTS-HD demuxer
-- remove -same_quant, it hasn't worked for years
-- FFM2 support
-- X-Face image encoder and decoder
-- 24-bit FLAC encoding
-- multi-channel ALAC encoding up to 7.1
-- metadata (INFO tag) support in WAV muxer
-- subtitles raw text decoder
-- support for building DLLs using MSVC
-- LVF demuxer
-- ffescape tool
-- metadata (info chunk) support in CAF muxer
-- field filter ported from libmpcodecs
-- AVR demuxer
-- geq filter ported from libmpcodecs
-- remove ffserver daemon mode
-- AST muxer/demuxer
-- new expansion syntax for drawtext
-- BRender PIX image decoder
-- ffprobe -show_entries option
-- ffprobe -sections option
-- ADPCM IMA Dialogic decoder
-- BRSTM demuxer
-- animated GIF decoder and demuxer
-- PVF demuxer
-- subtitles filter
-- IRCAM muxer/demuxer
-- Paris Audio File demuxer
-- Virtual concatenation demuxer
-- VobSub demuxer
-- JSON captions for TED talks decoding support
-- SOX Resampler support in libswresample
-- aselect filter
-- SGI RLE 8-bit / Silicon Graphics RLE 8-bit video decoder
-- Silicon Graphics Motion Video Compressor 1 & 2 decoder
-- Silicon Graphics Movie demuxer
-- apad filter
-- Resolution & pixel format change support with multithreading for H.264
-- documentation split into per-component manuals
-- pp (postproc) filter ported from MPlayer
-- NIST Sphere demuxer
-- MPL2, VPlayer, MPlayer, AQTitle, PJS and SubViewer v1 subtitles demuxers and decoders
-- Sony Wave64 muxer
-- adobe and limelight publisher authentication in RTMP
-- data: URI scheme
-- support building on the Plan 9 operating system
-- kerndeint filter ported from MPlayer
-- histeq filter ported from VirtualDub
-- Megalux Frame demuxer
-- 012v decoder
-- Improved AVC Intra decoding support
-
-
-version 1.0:
-
-- INI and flat output in ffprobe
-- Scene detection in libavfilter
-- Indeo Audio decoder
-- channelsplit audio filter
-- setnsamples audio filter
-- atempo filter
-- ffprobe -show_data option
-- RTMPT protocol support
-- iLBC encoding/decoding via libilbc
-- Microsoft Screen 1 decoder
-- join audio filter
-- audio channel mapping filter
-- Microsoft ATC Screen decoder
-- RTSP listen mode
-- TechSmith Screen Codec 2 decoder
-- AAC encoding via libfdk-aac
-- Microsoft Expression Encoder Screen decoder
-- RTMPS protocol support
-- RTMPTS protocol support
-- RTMPE protocol support
-- RTMPTE protocol support
-- showwaves and showspectrum filter
-- LucasArts SMUSH SANM playback support
-- LucasArts SMUSH VIMA audio decoder (ADPCM)
-- LucasArts SMUSH demuxer
-- SAMI, RealText and SubViewer demuxers and decoders
-- Heart Of Darkness PAF playback support
-- iec61883 device
-- asettb filter
-- new option: -progress
-- 3GPP Timed Text encoder/decoder
-- GeoTIFF decoder support
-- ffmpeg -(no)stdin option
-- Opus decoder using libopus
-- caca output device using libcaca
-- alphaextract and alphamerge filters
-- concat filter
-- flite filter
-- Canopus Lossless Codec decoder
-- bitmap subtitles in filters (experimental and temporary)
-- MP2 encoding via TwoLAME
-- bmp parser
-- smptebars source
-- asetpts filter
-- hue filter
-- ICO muxer
-- SubRip encoder and decoder without embedded timing
-- edge detection filter
-- framestep filter
-- ffmpeg -shortest option is now per-output file
- -pass and -passlogfile are now per-output stream
-- volume measurement filter
-- Ut Video encoder
-- Microsoft Screen 2 decoder
-- smartblur filter ported from MPlayer
-- CPiA decoder
-- decimate filter ported from MPlayer
-- RTP depacketization of JPEG
-- Smooth Streaming live segmenter muxer
-- F4V muxer
-- sendcmd and asendcmd filters
-- WebVTT demuxer and decoder (simple tags supported)
-- RTP packetization of JPEG
-- faststart option in the MOV/MP4 muxer
-- support for building with MSVC
-
-
-version 0.11:
-
-- Fixes: CVE-2012-2772, CVE-2012-2774, CVE-2012-2775, CVE-2012-2776, CVE-2012-2777,
- CVE-2012-2779, CVE-2012-2782, CVE-2012-2783, CVE-2012-2784, CVE-2012-2785,
- CVE-2012-2786, CVE-2012-2787, CVE-2012-2788, CVE-2012-2789, CVE-2012-2790,
- CVE-2012-2791, CVE-2012-2792, CVE-2012-2793, CVE-2012-2794, CVE-2012-2795,
- CVE-2012-2796, CVE-2012-2797, CVE-2012-2798, CVE-2012-2799, CVE-2012-2800,
- CVE-2012-2801, CVE-2012-2802, CVE-2012-2803, CVE-2012-2804,
-- v408 Quicktime and Microsoft AYUV Uncompressed 4:4:4:4 encoder and decoder
-- setfield filter
-- CDXL demuxer and decoder
-- Apple ProRes encoder
-- ffprobe -count_packets and -count_frames options
-- Sun Rasterfile Encoder
-- ID3v2 attached pictures reading and writing
-- WMA Lossless decoder
-- bluray protocol
-- blackdetect filter
-- libutvideo encoder wrapper (--enable-libutvideo)
-- swapuv filter
-- bbox filter
-- XBM encoder and decoder
-- RealAudio Lossless decoder
-- ZeroCodec decoder
-- tile video filter
-- Metal Gear Solid: The Twin Snakes demuxer
-- OpenEXR image decoder
-- removelogo filter
-- drop support for ffmpeg without libavfilter
-- drawtext video filter: fontconfig support
-- ffmpeg -benchmark_all option
-- super2xsai filter ported from libmpcodecs
-- add libavresample audio conversion library for compatibility
-- MicroDVD decoder
-- Avid Meridien (AVUI) encoder and decoder
-- accept + prefix to -pix_fmt option to disable automatic conversions.
-- complete audio filtering in libavfilter and ffmpeg
-- add fps filter
-- vorbis parser
-- png parser
-- audio mix filter
-- ffv1: support (draft) version 1.3
-
-
-version 0.10:
-
-- Fixes: CVE-2011-3929, CVE-2011-3934, CVE-2011-3935, CVE-2011-3936,
- CVE-2011-3937, CVE-2011-3940, CVE-2011-3941, CVE-2011-3944,
- CVE-2011-3945, CVE-2011-3946, CVE-2011-3947, CVE-2011-3949,
- CVE-2011-3950, CVE-2011-3951, CVE-2011-3952
-- v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder
-- SBaGen (SBG) binaural beats script demuxer
-- OpenMG Audio muxer
-- Timecode extraction in DV and MOV
-- thumbnail video filter
-- XML output in ffprobe
-- asplit audio filter
-- tinterlace video filter
-- astreamsync audio filter
-- amerge audio filter
-- ISMV (Smooth Streaming) muxer
-- GSM audio parser
-- SMJPEG muxer
-- XWD encoder and decoder
-- Automatic thread count based on detection number of (available) CPU cores
-- y41p Brooktree Uncompressed 4:1:1 12-bit encoder and decoder
-- ffprobe -show_error option
-- Avid 1:1 10-bit RGB Packer codec
-- v308 Quicktime Uncompressed 4:4:4 encoder and decoder
-- yuv4 libquicktime packed 4:2:0 encoder and decoder
-- ffprobe -show_frames option
-- silencedetect audio filter
-- ffprobe -show_program_version, -show_library_versions, -show_versions options
-- rv34: frame-level multi-threading
-- optimized iMDCT transform on x86 using SSE for for mpegaudiodec
-- Improved PGS subtitle decoder
-- dumpgraph option to lavfi device
-- r210 and r10k encoders
-- ffwavesynth decoder
-- aviocat tool
-- ffeval tool
-- support encoding and decoding 4-channel SGI images
-
-
-version 0.9:
-
-- openal input device added
-- boxblur filter added
-- BWF muxer
-- Flash Screen Video 2 decoder
-- lavfi input device added
-- added avconv, which is almost the same for now, except
-for a few incompatible changes in the options, which will hopefully make them
-easier to use. The changes are:
- * The options placement is now strictly enforced! While in theory the
- options for ffmpeg should be given in [input options] -i INPUT [output
- options] OUTPUT order, in practice it was possible to give output options
- before the -i and it mostly worked. Except when it didn't - the behavior was
- a bit inconsistent. In avconv, it is not possible to mix input and output
- options. All non-global options are reset after an input or output filename.
- * All per-file options are now truly per-file - they apply only to the next
- input or output file and specifying different values for different files
- will now work properly (notably -ss and -t options).
- * All per-stream options are now truly per-stream - it is possible to
- specify which stream(s) should a given option apply to. See the Stream
- specifiers section in the avconv manual for details.
- * In ffmpeg some options (like -newvideo/-newaudio/...) are irregular in the
- sense that they're specified after the output filename instead of before,
- like all other options. In avconv this irregularity is removed, all options
- apply to the next input or output file.
- * -newvideo/-newaudio/-newsubtitle options were removed. Not only were they
- irregular and highly confusing, they were also redundant. In avconv the -map
- option will create new streams in the output file and map input streams to
- them. E.g. avconv -i INPUT -map 0 OUTPUT will create an output stream for
- each stream in the first input file.
- * The -map option now has slightly different and more powerful syntax:
- + Colons (':') are used to separate file index/stream type/stream index
- instead of dots. Comma (',') is used to separate the sync stream instead
- of colon.. This is done for consistency with other options.
- + It's possible to specify stream type. E.g. -map 0:a:2 creates an
- output stream from the third input audio stream.
- + Omitting the stream index now maps all the streams of the given type,
- not just the first. E.g. -map 0:s creates output streams for all the
- subtitle streams in the first input file.
- + Since -map can now match multiple streams, negative mappings were
- introduced. Negative mappings disable some streams from an already
- defined map. E.g. '-map 0 -map -0:a:1' means 'create output streams for
- all the stream in the first input file, except for the second audio
- stream'.
- * There is a new option -c (or -codec) for choosing the decoder/encoder to
- use, which makes it possible to precisely specify target stream(s) consistently with
- other options. E.g. -c:v lib264 sets the codec for all video streams, -c:a:0
- libvorbis sets the codec for the first audio stream and -c copy copies all
- the streams without reencoding. Old -vcodec/-acodec/-scodec options are now
- aliases to -c:v/a/s
- * It is now possible to precisely specify which stream should an AVOption
- apply to. E.g. -b:v:0 2M sets the bitrate for the first video stream, while
- -b:a 128k sets the bitrate for all audio streams. Note that the old -ab 128k
- syntax is deprecated and will stop working soon.
- * -map_chapters now takes only an input file index and applies to the next
- output file. This is consistent with how all the other options work.
- * -map_metadata now takes only an input metadata specifier and applies to
- the next output file. Output metadata specifier is now part of the option
- name, similarly to the AVOptions/map/codec feature above.
- * -metadata can now be used to set metadata on streams and chapters, e.g.
- -metadata:s:1 language=eng sets the language of the first stream to 'eng'.
- This made -vlang/-alang/-slang options redundant, so they were removed.
- * -qscale option now uses stream specifiers and applies to all streams, not
- just video. I.e. plain -qscale number would now apply to all streams. To get
- the old behavior, use -qscale:v. Also there is now a shortcut -q for -qscale
- and -aq is now an alias for -q:a.
- * -vbsf/-absf/-sbsf options were removed and replaced by a -bsf option which
- uses stream specifiers. Use -bsf:v/a/s instead of the old options.
- * -itsscale option now uses stream specifiers, so its argument is only the
- scale parameter.
- * -intra option was removed, use -g 0 for the same effect.
- * -psnr option was removed, use -flags +psnr for the same effect.
- * -vf option is now an alias to the new -filter option, which uses stream specifiers.
- * -vframes/-aframes/-dframes options are now aliases to the new -frames option.
- * -vtag/-atag/-stag options are now aliases to the new -tag option.
-- XMV demuxer
-- LOAS demuxer
-- ashowinfo filter added
-- Windows Media Image decoder
-- amovie source added
-- LATM muxer/demuxer
-- Speex encoder via libspeex
-- JSON output in ffprobe
-- WTV muxer
-- Optional C++ Support (needed for libstagefright)
-- H.264 Decoding on Android via Stagefright
-- Prores decoder
-- BIN/XBIN/ADF/IDF text file decoder
-- aconvert audio filter added
-- audio support to lavfi input device added
-- libcdio-paranoia input device for audio CD grabbing
-- Apple ProRes decoder
-- CELT in Ogg demuxing
-- G.723.1 demuxer and decoder
-- libmodplug support (--enable-libmodplug)
-- VC-1 interlaced decoding
-- libutvideo wrapper (--enable-libutvideo)
-- aevalsrc audio source added
-- Ut Video decoder
-- Speex encoding via libspeex
-- 4:2:2 H.264 decoding support
-- 4:2:2 and 4:4:4 H.264 encoding with libx264
-- Pulseaudio input device
-- Prores encoder
-- Video Decoder Acceleration (VDA) HWAccel module.
-- replacement Indeo 3 decoder
-- new ffmpeg option: -map_channel
-- volume audio filter added
-- earwax audio filter added
-- libv4l2 support (--enable-libv4l2)
-- TLS/SSL and HTTPS protocol support
-- AVOptions API rewritten and documented
-- most of CODEC_FLAG2_*, some CODEC_FLAG_* and many codec-specific fields in
- AVCodecContext deprecated. Codec private options should be used instead.
-- Properly working defaults in libx264 wrapper, support for native presets.
-- Encrypted OMA files support
-- Discworld II BMV decoding support
-- VBLE Decoder
-- OS X Video Decoder Acceleration (VDA) support
-- compact and csv output in ffprobe
-- pan audio filter
-- IFF Amiga Continuous Bitmap (ACBM) decoder
-- ass filter
-- CRI ADX audio format muxer and demuxer
-- Playstation Portable PMP format demuxer
-- Microsoft Windows ICO demuxer
-- life source
-- PCM format support in OMA demuxer
-- CLJR encoder
-- new option: -report
-- Dxtory capture format decoder
-- cellauto source
-- Simple segmenting muxer
-- Indeo 4 decoder
-- SMJPEG demuxer
-
-
-version 0.8:
-
-- many many things we forgot because we rather write code than changelogs
-- WebM support in Matroska de/muxer
-- low overhead Ogg muxing
-- MMS-TCP support
-- VP8 de/encoding via libvpx
-- Demuxer for On2's IVF format
-- Pictor/PC Paint decoder
-- HE-AAC v2 decoder
-- HE-AAC v2 encoding with libaacplus
-- libfaad2 wrapper removed
-- DTS-ES extension (XCh) decoding support
-- native VP8 decoder
-- RTSP tunneling over HTTP
-- RTP depacketization of SVQ3
-- -strict inofficial replaced by -strict unofficial
-- ffplay -exitonkeydown and -exitonmousedown options added
-- native GSM / GSM MS decoder
-- RTP depacketization of QDM2
-- ANSI/ASCII art playback system
-- Lego Mindstorms RSO de/muxer
-- libavcore added (and subsequently removed)
-- SubRip subtitle file muxer and demuxer
-- Chinese AVS encoding via libxavs
-- ffprobe -show_packets option added
-- RTP packetization of Theora and Vorbis
-- RTP depacketization of MP4A-LATM
-- RTP packetization and depacketization of VP8
-- hflip filter
-- Apple HTTP Live Streaming demuxer
-- a64 codec
-- MMS-HTTP support
-- G.722 ADPCM audio encoder/decoder
-- R10k video decoder
-- ocv_smooth filter
-- frei0r wrapper filter
-- change crop filter syntax to width:height:x:y
-- make the crop filter accept parametric expressions
-- make ffprobe accept AVFormatContext options
-- yadif filter
-- blackframe filter
-- Demuxer for Leitch/Harris' VR native stream format (LXF)
-- RTP depacketization of the X-QT QuickTime format
-- SAP (Session Announcement Protocol, RFC 2974) muxer and demuxer
-- cropdetect filter
-- ffmpeg -crop* options removed
-- transpose filter added
-- ffmpeg -force_key_frames option added
-- demuxer for receiving raw rtp:// URLs without an SDP description
-- single stream LATM/LOAS decoder
-- setpts filter added
-- Win64 support for optimized x86 assembly functions
-- MJPEG/AVI1 to JPEG/JFIF bitstream filter
-- ASS subtitle encoder and decoder
-- IEC 61937 encapsulation for E-AC-3, TrueHD, DTS-HD (for HDMI passthrough)
-- overlay filter added
-- rename aspect filter to setdar, and pixelaspect to setsar
-- IEC 61937 demuxer
-- Mobotix .mxg demuxer
-- frei0r source added
-- hqdn3d filter added
-- RTP depacketization of QCELP
-- FLAC parser added
-- gradfun filter added
-- AMR-WB decoder
-- replace the ocv_smooth filter with a more generic ocv filter
-- Windows Televison (WTV) demuxer
-- FFmpeg metadata format muxer and demuxer
-- SubRip (srt) subtitle encoder and decoder
-- floating-point AC-3 encoder added
-- Lagarith decoder
-- ffmpeg -copytb option added
-- IVF muxer added
-- Wing Commander IV movies decoder added
-- movie source added
-- Bink version 'b' audio and video decoder
-- Bitmap Brothers JV playback system
-- Apple HTTP Live Streaming protocol handler
-- sndio support for playback and record
-- Linux framebuffer input device added
-- Chronomaster DFA decoder
-- DPX image encoder
-- MicroDVD subtitle file muxer and demuxer
-- Playstation Portable PMP format demuxer
-- fieldorder video filter added
-- AAC encoding via libvo-aacenc
-- AMR-WB encoding via libvo-amrwbenc
-- xWMA demuxer
-- Mobotix MxPEG decoder
-- VP8 frame-multithreading
-- NEON optimizations for VP8
-- Lots of deprecated API cruft removed
-- fft and imdct optimizations for AVX (Sandy Bridge) processors
-- showinfo filter added
-- SMPTE 302M AES3 audio decoder
-- Apple Core Audio Format muxer
-- 9bit and 10bit per sample support in the H.264 decoder
-- 9bit and 10bit FFV1 encoding / decoding
-- split filter added
-- select filter added
-- sdl output device added
-- libmpcodecs video filter support (3 times as many filters than before)
-- mpeg2 aspect ratio dection fixed
-- libxvid aspect pickiness fixed
-- Frame multithreaded decoding
-- E-AC-3 audio encoder
-- ac3enc: add channel coupling support
-- floating-point sample format support to the ac3, eac3, dca, aac, and vorbis decoders.
-- H264/MPEG frame-level multi-threading
-- All av_metadata_* functions renamed to av_dict_* and moved to libavutil
-- 4:4:4 H.264 decoding support
-- 10-bit H.264 optimizations for x86
-- lut, lutrgb, and lutyuv filters added
-- buffersink libavfilter sink added
-- Bump libswscale for recently reported ABI break
-- New J2K encoder (via OpenJPEG)
-
-
-version 0.7:
-
-- all the changes for 0.8, but keeping API/ABI compatibility with the 0.6 release
-
-
-version 0.6:
-
-- PB-frame decoding for H.263
-- deprecated vhook subsystem removed
-- deprecated old scaler removed
-- VQF demuxer
-- Alpha channel scaler
-- PCX encoder
-- RTP packetization of H.263
-- RTP packetization of AMR
-- RTP depacketization of Vorbis
-- CorePNG decoding support
-- Cook multichannel decoding support
-- introduced avlanguage helpers in libavformat
-- 8088flex TMV demuxer and decoder
-- per-stream language-tags extraction in asfdec
-- V210 decoder and encoder
-- remaining GPL parts in AC-3 decoder converted to LGPL
-- QCP demuxer
-- SoX native format muxer and demuxer
-- AMR-NB decoding/encoding, AMR-WB decoding via OpenCORE libraries
-- DPX image decoder
-- Electronic Arts Madcow decoder
-- DivX (XSUB) subtitle encoder
-- nonfree libamr support for AMR-NB/WB decoding/encoding removed
-- experimental AAC encoder
-- RTP depacketization of ASF and RTSP from WMS servers
-- RTMP support in libavformat
-- noX handling for OPT_BOOL X options
-- Wave64 demuxer
-- IEC-61937 compatible Muxer
-- TwinVQ decoder
-- Bluray (PGS) subtitle decoder
-- LPCM support in MPEG-TS (HDMV RID as found on Blu-ray disks)
-- WMA Pro decoder
-- Core Audio Format demuxer
-- ATRAC1 decoder
-- MD STUDIO audio demuxer
-- RF64 support in WAV demuxer
-- MPEG-4 Audio Lossless Coding (ALS) decoder
-- -formats option split into -formats, -codecs, -bsfs, and -protocols
-- IV8 demuxer
-- CDG demuxer and decoder
-- R210 decoder
-- Auravision Aura 1 and 2 decoders
-- Deluxe Paint Animation playback system
-- SIPR decoder
-- Adobe Filmstrip muxer and demuxer
-- RTP depacketization of H.263
-- Bink demuxer and audio/video decoders
-- enable symbol versioning by default for linkers that support it
-- IFF PBM/ILBM bitmap decoder
-- concat protocol
-- Indeo 5 decoder
-- RTP depacketization of AMR
-- WMA Voice decoder
-- ffprobe tool
-- AMR-NB decoder
-- RTSP muxer
-- HE-AAC v1 decoder
-- Kega Game Video (KGV1) decoder
-- VorbisComment writing for FLAC, Ogg FLAC and Ogg Speex files
-- RTP depacketization of Theora
-- HTTP Digest authentication
-- RTMP/RTMPT/RTMPS/RTMPE/RTMPTE protocol support via librtmp
-- Psygnosis YOP demuxer and video decoder
-- spectral extension support in the E-AC-3 decoder
-- unsharp video filter
-- RTP hinting in the mov/3gp/mp4 muxer
-- Dirac in Ogg demuxing
-- seek to keyframes in Ogg
-- 4:2:2 and 4:4:4 Theora decoding
-- 35% faster VP3/Theora decoding
-- faster AAC decoding
-- faster H.264 decoding
-- RealAudio 1.0 (14.4K) encoder
-
-
-version 0.5:
-
-- DV50 AKA DVCPRO50 encoder, decoder, muxer and demuxer
-- TechSmith Camtasia (TSCC) video decoder
-- IBM Ultimotion (ULTI) video decoder
-- Sierra Online audio file demuxer and decoder
-- Apple QuickDraw (qdrw) video decoder
-- Creative ADPCM audio decoder (16 bits as well as 8 bits schemes)
-- Electronic Arts Multimedia (WVE/UV2/etc.) file demuxer
-- Miro VideoXL (VIXL) video decoder
-- H.261 video encoder
-- QPEG video decoder
-- Nullsoft Video (NSV) file demuxer
-- Shorten audio decoder
-- LOCO video decoder
-- Apple Lossless Audio Codec (ALAC) decoder
-- Winnov WNV1 video decoder
-- Autodesk Animator Studio Codec (AASC) decoder
-- Indeo 2 video decoder
-- Fraps FPS1 video decoder
-- Snow video encoder/decoder
-- Sonic audio encoder/decoder
-- Vorbis audio decoder
-- Macromedia ADPCM decoder
-- Duck TrueMotion 2 video decoder
-- support for decoding FLX and DTA extensions in FLIC files
-- H.264 custom quantization matrices support
-- ffserver fixed, it should now be usable again
-- QDM2 audio decoder
-- Real Cooker audio decoder
-- TrueSpeech audio decoder
-- WMA2 audio decoder fixed, now all files should play correctly
-- RealAudio 14.4 and 28.8 decoders fixed
-- JPEG-LS decoder
-- build system improvements
-- tabs and trailing whitespace removed from the codebase
-- CamStudio video decoder
-- AIFF/AIFF-C audio format, encoding and decoding
-- ADTS AAC file reading and writing
-- Creative VOC file reading and writing
-- American Laser Games multimedia (*.mm) playback system
-- Zip Motion Blocks Video decoder
-- improved Theora/VP3 decoder
-- True Audio (TTA) decoder
-- AVS demuxer and video decoder
-- JPEG-LS encoder
-- Smacker demuxer and decoder
-- NuppelVideo/MythTV demuxer and RTjpeg decoder
-- KMVC decoder
-- MPEG-2 intra VLC support
-- MPEG-2 4:2:2 encoder
-- Flash Screen Video decoder
-- GXF demuxer
-- Chinese AVS decoder
-- GXF muxer
-- MXF demuxer
-- VC-1/WMV3/WMV9 video decoder
-- MacIntel support
-- AviSynth support
-- VMware video decoder
-- VP5 video decoder
-- VP6 video decoder
-- WavPack lossless audio decoder
-- Targa (.TGA) picture decoder
-- Vorbis audio encoder
-- Delphine Software .cin demuxer/audio and video decoder
-- Tiertex .seq demuxer/video decoder
-- MTV demuxer
-- TIFF picture encoder and decoder
-- GIF picture decoder
-- Intel Music Coder decoder
-- Zip Motion Blocks Video encoder
-- Musepack decoder
-- Flash Screen Video encoder
-- Theora encoding via libtheora
-- BMP encoder
-- WMA encoder
-- GSM-MS encoder and decoder
-- DCA decoder
-- DXA demuxer and decoder
-- DNxHD decoder
-- Gamecube movie (.THP) playback system
-- Blackfin optimizations
-- Interplay C93 demuxer and video decoder
-- Bethsoft VID demuxer and video decoder
-- CRYO APC demuxer
-- ATRAC3 decoder
-- V.Flash PTX decoder
-- RoQ muxer, RoQ audio encoder
-- Renderware TXD demuxer and decoder
-- extern C declarations for C++ removed from headers
-- sws_flags command line option
-- codebook generator
-- RoQ video encoder
-- QTRLE encoder
-- OS/2 support removed and restored again
-- AC-3 decoder
-- NUT muxer
-- additional SPARC (VIS) optimizations
-- Matroska muxer
-- slice-based parallel H.264 decoding
-- Monkey's Audio demuxer and decoder
-- AMV audio and video decoder
-- DNxHD encoder
-- H.264 PAFF decoding
-- Nellymoser ASAO decoder
-- Beam Software SIFF demuxer and decoder
-- libvorbis Vorbis decoding removed in favor of native decoder
-- IntraX8 (J-Frame) subdecoder for WMV2 and VC-1
-- Ogg (Theora, Vorbis and FLAC) muxer
-- The "device" muxers and demuxers are now in a new libavdevice library
-- PC Paintbrush PCX decoder
-- Sun Rasterfile decoder
-- TechnoTrend PVA demuxer
-- Linux Media Labs MPEG-4 (LMLM4) demuxer
-- AVM2 (Flash 9) SWF muxer
-- QT variant of IMA ADPCM encoder
-- VFW grabber
-- iPod/iPhone compatible mp4 muxer
-- Mimic decoder
-- MSN TCP Webcam stream demuxer
-- RL2 demuxer / decoder
-- IFF demuxer
-- 8SVX audio decoder
-- non-recursive Makefiles
-- BFI demuxer
-- MAXIS EA XA (.xa) demuxer / decoder
-- BFI video decoder
-- OMA demuxer
-- MLP/TrueHD decoder
-- Electronic Arts CMV decoder
-- Motion Pixels Video decoder
-- Motion Pixels MVI demuxer
-- removed animated GIF decoder/demuxer
-- D-Cinema audio muxer
-- Electronic Arts TGV decoder
-- Apple Lossless Audio Codec (ALAC) encoder
-- AAC decoder
-- floating point PCM encoder/decoder
-- MXF muxer
-- DV100 AKA DVCPRO HD decoder and demuxer
-- E-AC-3 support added to AC-3 decoder
-- Nellymoser ASAO encoder
-- ASS and SSA demuxer and muxer
-- liba52 wrapper removed
-- SVQ3 watermark decoding support
-- Speex decoding via libspeex
-- Electronic Arts TGQ decoder
-- RV40 decoder
-- QCELP / PureVoice decoder
-- RV30 decoder
-- hybrid WavPack support
-- R3D REDCODE demuxer
-- ALSA support for playback and record
-- Electronic Arts TQI decoder
-- OpenJPEG based JPEG 2000 decoder
-- NC (NC4600) camera file demuxer
-- Gopher client support
-- MXF D-10 muxer
-- generic metadata API
-- flash ScreenVideo2 encoder
-
-
-version 0.4.9-pre1:
-
-- DV encoder, DV muxer
-- Microsoft RLE video decoder
-- Microsoft Video-1 decoder
-- Apple Animation (RLE) decoder
-- Apple Graphics (SMC) decoder
-- Apple Video (RPZA) decoder
-- Cinepak decoder
-- Sega FILM (CPK) file demuxer
-- Westwood multimedia support (VQA & AUD files)
-- Id Quake II CIN playback support
-- 8BPS video decoder
-- FLIC playback support
-- RealVideo 2.0 (RV20) decoder
-- Duck TrueMotion v1 (DUCK) video decoder
-- Sierra VMD demuxer and video decoder
-- MSZH and ZLIB decoder support
-- SVQ1 video encoder
-- AMR-WB support
-- PPC optimizations
-- rate distortion optimal cbp support
-- rate distorted optimal ac prediction for MPEG-4
-- rate distorted optimal lambda->qp support
-- AAC encoding with libfaac
-- Sunplus JPEG codec (SP5X) support
-- use Lagrange multipler instead of QP for ratecontrol
-- Theora/VP3 decoding support
-- XA and ADX ADPCM codecs
-- export MPEG-2 active display area / pan scan
-- Add support for configuring with IBM XLC
-- floating point AAN DCT
-- initial support for zygo video (not complete)
-- RGB ffv1 support
-- new audio/video parser API
-- av_log() system
-- av_read_frame() and av_seek_frame() support
-- missing last frame fixes
-- seek by mouse in ffplay
-- noise reduction of DCT coefficients
-- H.263 OBMC & 4MV support
-- H.263 alternative inter vlc support
-- H.263 loop filter
-- H.263 slice structured mode
-- interlaced DCT support for MPEG-2 encoding
-- stuffing to stay above min_bitrate
-- MB type & QP visualization
-- frame stepping for ffplay
-- interlaced motion estimation
-- alternate scantable support
-- SVCD scan offset support
-- closed GOP support
-- SSE2 FDCT
-- quantizer noise shaping
-- G.726 ADPCM audio codec
-- MS ADPCM encoding
-- multithreaded/SMP motion estimation
-- multithreaded/SMP encoding for MPEG-1/MPEG-2/MPEG-4/H.263
-- multithreaded/SMP decoding for MPEG-2
-- FLAC decoder
-- Metrowerks CodeWarrior suppport
-- H.263+ custom pcf support
-- nicer output for 'ffmpeg -formats'
-- Matroska demuxer
-- SGI image format, encoding and decoding
-- H.264 loop filter support
-- H.264 CABAC support
-- nicer looking arrows for the motion vector visualization
-- improved VCD support
-- audio timestamp drift compensation
-- MPEG-2 YUV 422/444 support
-- polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample
-- better image scaling
-- H.261 support
-- correctly interleave packets during encoding
-- VIS optimized motion compensation
-- intra_dc_precision>0 encoding support
-- support reuse of motion vectors/MB types/field select values of the source video
-- more accurate deblock filter
-- padding support
-- many optimizations and bugfixes
-- FunCom ISS audio file demuxer and according ADPCM decoding
-
-
-version 0.4.8:
-
-- MPEG-2 video encoding (Michael)
-- Id RoQ playback subsystem (Mike Melanson and Tim Ferguson)
-- Wing Commander III Movie (.mve) file playback subsystem (Mike Melanson
- and Mario Brito)
-- Xan DPCM audio decoder (Mario Brito)
-- Interplay MVE playback subsystem (Mike Melanson)
-- Duck DK3 and DK4 ADPCM audio decoders (Mike Melanson)
-
-
-version 0.4.7:
-
-- RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, code from mplayerhq
- (originally from public domain player for Amiga at http://www.honeypot.net/audio)
-- current version now also compiles with older GCC (Fabrice)
-- 4X multimedia playback system including 4xm file demuxer (Mike
- Melanson), and 4X video and audio codecs (Michael)
-- Creative YUV (CYUV) decoder (Mike Melanson)
-- FFV1 codec (our very simple lossless intra only codec, compresses much better
- than HuffYUV) (Michael)
-- ASV1 (Asus), H.264, Intel indeo3 codecs have been added (various)
-- tiny PNG encoder and decoder, tiny GIF decoder, PAM decoder (PPM with
- alpha support), JPEG YUV colorspace support. (Fabrice Bellard)
-- ffplay has been replaced with a newer version which uses SDL (optionally)
- for multiplatform support (Fabrice)
-- Sorenson Version 3 codec (SVQ3) support has been added (decoding only) - donated
- by anonymous
-- AMR format has been added (Johannes Carlsson)
-- 3GP support has been added (Johannes Carlsson)
-- VP3 codec has been added (Mike Melanson)
-- more MPEG-1/2 fixes
-- better multiplatform support, MS Visual Studio fixes (various)
-- AltiVec optimizations (Magnus Damn and others)
-- SH4 processor support has been added (BERO)
-- new public interfaces (avcodec_get_pix_fmt) (Roman Shaposhnick)
-- VOB streaming support (Brian Foley)
-- better MP3 autodetection (Andriy Rysin)
-- qpel encoding (Michael)
-- 4mv+b frames encoding finally fixed (Michael)
-- chroma ME (Michael)
-- 5 comparison functions for ME (Michael)
-- B-frame encoding speedup (Michael)
-- WMV2 codec (unfinished - Michael)
-- user specified diamond size for EPZS (Michael)
-- Playstation STR playback subsystem, still experimental (Mike and Michael)
-- ASV2 codec (Michael)
-- CLJR decoder (Alex)
-
-.. And lots more new enhancements and fixes.
-
-
-version 0.4.6:
-
-- completely new integer only MPEG audio layer 1/2/3 decoder rewritten
- from scratch
-- Recoded DCT and motion vector search with gcc (no longer depends on nasm)
-- fix quantization bug in AC3 encoder
-- added PCM codecs and format. Corrected WAV/AVI/ASF PCM issues
-- added prototype ffplay program
-- added GOB header parsing on H.263/H.263+ decoder (Juanjo)
-- bug fix on MCBPC tables of H.263 (Juanjo)
-- bug fix on DC coefficients of H.263 (Juanjo)
-- added Advanced Prediction Mode on H.263/H.263+ decoder (Juanjo)
-- now we can decode H.263 streams found in QuickTime files (Juanjo)
-- now we can decode H.263 streams found in VIVO v1 files(Juanjo)
-- preliminary RTP "friendly" mode for H.263/H.263+ coding. (Juanjo)
-- added GOB header for H.263/H.263+ coding on RTP mode (Juanjo)
-- now H.263 picture size is returned on the first decoded frame (Juanjo)
-- added first regression tests
-- added MPEG-2 TS demuxer
-- new demux API for libav
-- more accurate and faster IDCT (Michael)
-- faster and entropy-controlled motion search (Michael)
-- two pass video encoding (Michael)
-- new video rate control (Michael)
-- added MSMPEG4V1, MSMPEGV2 and WMV1 support (Michael)
-- great performance improvement of video encoders and decoders (Michael)
-- new and faster bit readers and vlc parsers (Michael)
-- high quality encoding mode: tries all macroblock/VLC types (Michael)
-- added DV video decoder
-- preliminary RTP/RTSP support in ffserver and libavformat
-- H.263+ AIC decoding/encoding support (Juanjo)
-- VCD MPEG-PS mode (Juanjo)
-- PSNR stuff (Juanjo)
-- simple stats output (Juanjo)
-- 16-bit and 15-bit RGB/BGR/GBR support (Bisqwit)
-
-
-version 0.4.5:
-
-- some header fixes (Zdenek Kabelac <kabi at informatics.muni.cz>)
-- many MMX optimizations (Nick Kurshev <nickols_k at mail.ru>)
-- added configure system (actually a small shell script)
-- added MPEG audio layer 1/2/3 decoding using LGPL'ed mpglib by
- Michael Hipp (temporary solution - waiting for integer only
- decoder)
-- fixed VIDIOCSYNC interrupt
-- added Intel H.263 decoding support ('I263' AVI fourCC)
-- added Real Video 1.0 decoding (needs further testing)
-- simplified image formats again. Added PGM format (=grey
- pgm). Renamed old PGM to PGMYUV.
-- fixed msmpeg4 slice issues (tell me if you still find problems)
-- fixed OpenDivX bugs with newer versions (added VOL header decoding)
-- added support for MPlayer interface
-- added macroblock skip optimization
-- added MJPEG decoder
-- added mmx/mmxext IDCT from libmpeg2
-- added pgmyuvpipe, ppm, and ppm_pipe formats (original patch by Celer
- <celer at shell.scrypt.net>)
-- added pixel format conversion layer (e.g. for MJPEG or PPM)
-- added deinterlacing option
-- MPEG-1/2 fixes
-- MPEG-4 vol header fixes (Jonathan Marsden <snmjbm at pacbell.net>)
-- ARM optimizations (Lionel Ulmer <lionel.ulmer at free.fr>).
-- Windows porting of file converter
-- added MJPEG raw format (input/output)
-- added JPEG image format support (input/output)
-
-
-version 0.4.4:
-
-- fixed some std header definitions (Bjorn Lindgren
- <bjorn.e.lindgren at telia.com>).
-- added MPEG demuxer (MPEG-1 and 2 compatible).
-- added ASF demuxer
-- added prototype RM demuxer
-- added AC3 decoding (done with libac3 by Aaron Holtzman)
-- added decoding codec parameter guessing (.e.g. for MPEG, because the
- header does not include them)
-- fixed header generation in MPEG-1, AVI and ASF muxer: wmplayer can now
- play them (only tested video)
-- fixed H.263 white bug
-- fixed phase rounding in img resample filter
-- add MMX code for polyphase img resample filter
-- added CPU autodetection
-- added generic title/author/copyright/comment string handling (ASF and RM
- use them)
-- added SWF demux to extract MP3 track (not usable yet because no MP3
- decoder)
-- added fractional frame rate support
-- codecs are no longer searched by read_header() (should fix ffserver
- segfault)
-
-
-version 0.4.3:
-
-- BGR24 patch (initial patch by Jeroen Vreeken <pe1rxq at amsat.org>)
-- fixed raw yuv output
-- added motion rounding support in MPEG-4
-- fixed motion bug rounding in MSMPEG4
-- added B-frame handling in video core
-- added full MPEG-1 decoding support
-- added partial (frame only) MPEG-2 support
-- changed the FOURCC code for H.263 to "U263" to be able to see the
- +AVI/H.263 file with the UB Video H.263+ decoder. MPlayer works with
- this +codec ;) (JuanJo).
-- Halfpel motion estimation after MB type selection (JuanJo)
-- added pgm and .Y.U.V output format
-- suppressed 'img:' protocol. Simply use: /tmp/test%d.[pgm|Y] as input or
- output.
-- added pgmpipe I/O format (original patch from Martin Aumueller
- <lists at reserv.at>, but changed completely since we use a format
- instead of a protocol)
-
-
-version 0.4.2:
-
-- added H.263/MPEG-4/MSMPEG4 decoding support. MPEG-4 decoding support
- (for OpenDivX) is almost complete: 8x8 MVs and rounding are
- missing. MSMPEG4 support is complete.
-- added prototype MPEG-1 decoder. Only I- and P-frames handled yet (it
- can decode ffmpeg MPEGs :-)).
-- added libavcodec API documentation (see apiexample.c).
-- fixed image polyphase bug (the bottom of some images could be
- greenish)
-- added support for non clipped motion vectors (decoding only)
- and image sizes non-multiple of 16
-- added support for AC prediction (decoding only)
-- added file overwrite confirmation (can be disabled with -y)
-- added custom size picture to H.263 using H.263+ (Juanjo)
-
-
-version 0.4.1:
-
-- added MSMPEG4 (aka DivX) compatible encoder. Changed default codec
- of AVI and ASF to DIV3.
-- added -me option to set motion estimation method
- (default=log). suppressed redundant -hq option.
-- added options -acodec and -vcodec to force a given codec (useful for
- AVI for example)
-- fixed -an option
-- improved dct_quantize speed
-- factorized some motion estimation code
-
-
-version 0.4.0:
-
-- removing grab code from ffserver and moved it to ffmpeg. Added
- multistream support to ffmpeg.
-- added timeshifting support for live feeds (option ?date=xxx in the
- URL)
-- added high quality image resize code with polyphase filter (need
- mmx/see optimization). Enable multiple image size support in ffserver.
-- added multi live feed support in ffserver
-- suppressed master feature from ffserver (it should be done with an
- external program which opens the .ffm url and writes it to another
- ffserver)
-- added preliminary support for video stream parsing (WAV and AVI half
- done). Added proper support for audio/video file conversion in
- ffmpeg.
-- added preliminary support for video file sending from ffserver
-- redesigning I/O subsystem: now using URL based input and output
- (see avio.h)
-- added WAV format support
-- added "tty user interface" to ffmpeg to stop grabbing gracefully
-- added MMX/SSE optimizations to SAD (Sums of Absolutes Differences)
- (Juan J. Sierralta P. a.k.a. "Juanjo" <juanjo at atmlab.utfsm.cl>)
-- added MMX DCT from mpeg2_movie 1.5 (Juanjo)
-- added new motion estimation algorithms, log and phods (Juanjo)
-- changed directories: libav for format handling, libavcodec for
- codecs
-
-
-version 0.3.4:
-
-- added stereo in MPEG audio encoder
-
-
-version 0.3.3:
-
-- added 'high quality' mode which use motion vectors. It can be used in
- real time at low resolution.
-- fixed rounding problems which caused quality problems at high
- bitrates and large GOP size
-
-
-version 0.3.2: small fixes
-
-- ASF fixes
-- put_seek bug fix
-
-
-version 0.3.1: added avi/divx support
-
-- added AVI support
-- added MPEG-4 codec compatible with OpenDivX. It is based on the H.263 codec
-- added sound for flash format (not tested)
-
-
-version 0.3: initial public release
diff --git a/ffmpeg-2-8-11/RELEASE b/ffmpeg-2-8-11/RELEASE
deleted file mode 100644
index 38bc521..0000000
--- a/ffmpeg-2-8-11/RELEASE
+++ /dev/null
@@ -1 +0,0 @@
-2.8.11
diff --git a/ffmpeg-2-8-11/VERSION b/ffmpeg-2-8-11/VERSION
deleted file mode 100644
index 38bc521..0000000
--- a/ffmpeg-2-8-11/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-2.8.11
diff --git a/ffmpeg-2-8-11/doc/Doxyfile b/ffmpeg-2-8-11/doc/Doxyfile
deleted file mode 100644
index 7776739..0000000
--- a/ffmpeg-2-8-11/doc/Doxyfile
+++ /dev/null
@@ -1,1626 +0,0 @@
-# Doxyfile 1.7.1
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-# TAG = value [value, ...]
-# For lists items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all
-# text before the first occurrence of this tag. Doxygen uses libiconv (or the
-# iconv built into libc) for the transcoding. See
-# http://www.gnu.org/software/libiconv for the list of possible encodings.
-
-DOXYFILE_ENCODING = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-
-PROJECT_NAME = FFmpeg
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-
-PROJECT_NUMBER = 2.8.11
-
-# With the PROJECT_LOGO tag one can specify a logo or icon that is included
-# in the documentation. The maximum height of the logo should not exceed 55
-# pixels and the maximum width should not exceed 200 pixels. Doxygen will
-# copy the logo to the output directory.
-PROJECT_LOGO =
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = doc/doxy
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
-# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
-# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
-# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
-# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
-# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
-
-OUTPUT_LANGUAGE = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF =
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = YES
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
-# path to strip.
-
-STRIP_FROM_PATH = .
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like regular Qt-style comments
-# (thus requiring an explicit @brief command for a brief description.)
-
-JAVADOC_AUTOBRIEF = YES
-
-# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
-# interpret the first line (until the first dot) of a Qt-style
-# comment as the brief description. If set to NO, the comments
-# will behave just like regular Qt-style comments (thus requiring
-# an explicit \brief command for a brief description.)
-
-QT_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# re-implements.
-
-INHERIT_DOCS = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
-# a new page for each member. If set to NO, the documentation of a member will
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE = 8
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
-# sources only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C = YES
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
-# sources only. Doxygen will then generate output that is more tailored for
-# Java. For instance, namespaces will be presented as packages, qualified
-# scopes will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
-# sources only. Doxygen will then generate output that is more tailored for
-# Fortran.
-
-OPTIMIZE_FOR_FORTRAN = NO
-
-# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
-# sources. Doxygen will then generate output that is tailored for
-# VHDL.
-
-OPTIMIZE_OUTPUT_VHDL = NO
-
-# Doxygen selects the parser to use depending on the extension of the files it
-# parses. With this tag you can assign which parser to use for a given extension.
-# Doxygen has a built-in mapping, but you can override or extend it using this
-# tag. The format is ext=language, where ext is a file extension, and language
-# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
-# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
-# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
-# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
-# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
-
-EXTENSION_MAPPING =
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
-# to include (a tag file for) the STL sources as input, then you should
-# set this tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
-# func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-
-BUILTIN_STL_SUPPORT = NO
-
-# If you use Microsoft's C++/CLI language, you should set this option to YES to
-# enable parsing support.
-
-CPP_CLI_SUPPORT = NO
-
-# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
-# Doxygen will parse them like normal C++ but will assume all classes use public
-# instead of private inheritance when no explicit protection keyword is present.
-
-SIP_SUPPORT = NO
-
-# For Microsoft's IDL there are propget and propput attributes to indicate getter
-# and setter methods for a property. Setting this option to YES (the default)
-# will make doxygen to replace the get and set methods by a property in the
-# documentation. This will only work if the methods are indeed getting or
-# setting a simple type. If this is not the case, or you want to show the
-# methods anyway, you should set this option to NO.
-
-IDL_PROPERTY_SUPPORT = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
-# the \nosubgrouping command.
-
-SUBGROUPING = YES
-
-# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
-# is documented as struct, union, or enum with the name of the typedef. So
-# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
-# with name TypeT. When disabled the typedef will appear as a member of a file,
-# namespace, or class. And the struct will be named TypeS. This can typically
-# be useful for C code in case the coding convention dictates that all compound
-# types are typedef'ed and only the typedef is referenced, never the tag name.
-
-TYPEDEF_HIDES_STRUCT = YES
-
-# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
-# determine which symbols to keep in memory and which to flush to disk.
-# When the cache is full, less often used symbols will be written to disk.
-# For small to medium size projects (<1000 input files) the default value is
-# probably good enough. For larger projects a too small cache size can cause
-# doxygen to be busy swapping symbols to and from disk most of the time
-# causing a significant performance penality.
-# If the system has enough physical memory increasing the cache will improve the
-# performance by keeping more symbols in memory. Note that the value works on
-# a logarithmic scale so increasing the size by one will roughly double the
-# memory usage. The cache size is given by this formula:
-# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
-# corresponding to a cache size of 2^16 = 65536 symbols
-
-SYMBOL_CACHE_SIZE = 0
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = YES
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES = YES
-
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If this flag is set to YES, the members of anonymous namespaces will be
-# extracted and appear in the documentation as a namespace called
-# 'anonymous_namespace{file}', where file will be replaced with the base
-# name of the file that contains the anonymous namespace. By default
-# anonymous namespace are hidden.
-
-EXTRACT_ANON_NSPACES = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = NO
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
-# will list include files with double quotes in the documentation
-# rather than with sharp brackets.
-
-FORCE_LOCAL_INCLUDES = NO
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS = NO
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
-# declaration order.
-
-SORT_BRIEF_DOCS = NO
-
-# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
-# will sort the (brief and detailed) documentation of class members so that
-# constructors and destructors are listed first. If set to NO (the default)
-# the constructors will appear in the respective orders defined by
-# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
-# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
-# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
-
-SORT_MEMBERS_CTORS_1ST = NO
-
-# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
-# hierarchy of group names into alphabetical order. If set to NO (the default)
-# the group names will appear in their defined order.
-
-SORT_GROUP_NAMES = NO
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME = NO
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES = YES
-
-# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
-# This will remove the Files entry from the Quick Index and from the
-# Folder Tree View (if specified). The default is YES.
-
-SHOW_FILES = YES
-
-# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
-# Namespaces page.
-# This will remove the Namespaces entry from the Quick Index
-# and from the Folder Tree View (if specified). The default is YES.
-
-SHOW_NAMESPACES = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from
-# the version control system). Doxygen will invoke the program by executing (via
-# popen()) the command <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the program writes to standard output
-# is used as the file version. See the manual for examples.
-
-FILE_VERSION_FILTER =
-
-# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
-# by doxygen. The layout file controls the global structure of the generated
-# output files in an output format independent way. The create the layout file
-# that represents doxygen's defaults, run doxygen with the -l option.
-# You can optionally specify a file name after the option, if omitted
-# DoxygenLayout.xml will be used as the name of the layout file.
-
-LAYOUT_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET = YES
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for
-# functions that are documented, but have no documentation for their parameters
-# or return value. If set to NO (the default) doxygen will only warn about
-# wrong or incomplete parameter documentation, but not about the absence of
-# documentation.
-
-WARN_NO_PARAMDOC = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text. Optionally the format may contain
-# $version, which will be replaced by the version of the file (if it could
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
-INPUT =
-
-# This tag can be used to specify the character encoding of the source files
-# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
-# also the default input encoding. Doxygen uses libiconv (or the iconv built
-# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
-# the list of possible encodings.
-
-INPUT_ENCODING = UTF-8
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
-# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
-
-FILE_PATTERNS =
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE =
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix filesystem feature) are excluded
-# from the input.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories. Note that the wildcards are matched
-# against the file with absolute path, so to exclude all test directories
-# for example use the pattern */test/*
-
-EXCLUDE_PATTERNS = *.git \
- *.d
-
-# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
-# (namespaces, classes, functions, etc.) that should be excluded from the
-# output. The symbol name can be a fully qualified name, a word, or if the
-# wildcard * is used, a substring. Examples: ANamespace, AClass,
-# AClass::ANamespace, ANamespace::*Test
-
-EXCLUDE_SYMBOLS =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
-EXAMPLE_PATH = doc/examples/
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS = *.c
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output.
-# If FILTER_PATTERNS is specified, this tag will be
-# ignored.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis.
-# Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match.
-# The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
-# is applied to all files.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS = NO
-
-# If the REFERENCED_BY_RELATION tag is set to YES
-# then for each documented function all documented
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES
-# then for each documented function all documented entities
-# called/used by that function will be listed.
-
-REFERENCES_RELATION = NO
-
-# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
-# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
-# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
-# link to the source code.
-# Otherwise they will link to the documentation.
-
-REFERENCES_LINK_SOURCE = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code
-# will point to the HTML generated by the htags(1) tool instead of doxygen
-# built-in source browser. The htags tool is part of GNU's global source
-# tagging system (see http://www.gnu.org/software/global/global.html). You
-# will need version 4.8.6 or higher.
-
-USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = YES
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT = html
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
-
-HTML_HEADER =
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET =
-
-# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
-# Doxygen will adjust the colors in the stylesheet and background images
-# according to this color. Hue is specified as an angle on a colorwheel,
-# see http://en.wikipedia.org/wiki/Hue for more information.
-# For instance the value 0 represents red, 60 is yellow, 120 is green,
-# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
-# The allowed range is 0 to 359.
-
-#HTML_COLORSTYLE_HUE = 120
-
-# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
-# the colors in the HTML output. For a value of 0 the output will use
-# grayscales only. A value of 255 will produce the most vivid colors.
-
-HTML_COLORSTYLE_SAT = 100
-
-# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
-# the luminance component of the colors in the HTML output. Values below
-# 100 gradually make the output lighter, whereas values above 100 make
-# the output darker. The value divided by 100 is the actual gamma applied,
-# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
-# and 100 does not change the gamma.
-
-HTML_COLORSTYLE_GAMMA = 80
-
-# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
-# page will contain the date and time when the page was generated. Setting
-# this to NO can help when comparing the output of multiple runs.
-
-HTML_TIMESTAMP = YES
-
-# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
-# documentation will contain sections that can be hidden and shown after the
-# page has loaded. For this to work a browser that supports
-# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
-# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
-
-HTML_DYNAMIC_SECTIONS = NO
-
-# If the GENERATE_DOCSET tag is set to YES, additional index files
-# will be generated that can be used as input for Apple's Xcode 3
-# integrated development environment, introduced with OS X 10.5 (Leopard).
-# To create a documentation set, doxygen will generate a Makefile in the
-# HTML output directory. Running make will produce the docset in that
-# directory and running "make install" will install the docset in
-# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
-# it at startup.
-# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
-# for more information.
-
-GENERATE_DOCSET = NO
-
-# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
-# feed. A documentation feed provides an umbrella under which multiple
-# documentation sets from a single provider (such as a company or product suite)
-# can be grouped.
-
-DOCSET_FEEDNAME = "Doxygen generated docs"
-
-# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
-# should uniquely identify the documentation set bundle. This should be a
-# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
-# will append .docset to the name.
-
-DOCSET_BUNDLE_ID = org.doxygen.Project
-
-# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
-# the documentation publisher. This should be a reverse domain-name style
-# string, e.g. com.mycompany.MyDocSet.documentation.
-
-DOCSET_PUBLISHER_ID = org.doxygen.Publisher
-
-# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
-
-DOCSET_PUBLISHER_NAME = Publisher
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
-# written to the html output directory.
-
-CHM_FILE =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
-# is used to encode HtmlHelp index (hhk), content (hhc) and project file
-# content.
-
-CHM_INDEX_ENCODING =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND = NO
-
-# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
-# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
-# that can be used as input for Qt's qhelpgenerator to generate a
-# Qt Compressed Help (.qch) of the generated HTML documentation.
-
-GENERATE_QHP = NO
-
-# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
-# be used to specify the file name of the resulting .qch file.
-# The path specified is relative to the HTML output folder.
-
-QCH_FILE =
-
-# The QHP_NAMESPACE tag specifies the namespace to use when generating
-# Qt Help Project output. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#namespace
-
-QHP_NAMESPACE = org.doxygen.Project
-
-# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
-# Qt Help Project output. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#virtual-folders
-
-QHP_VIRTUAL_FOLDER = doc
-
-# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
-# add. For more information please see
-# http://doc.trolltech.com/qthelpproject.html#custom-filters
-
-QHP_CUST_FILTER_NAME =
-
-# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
-# custom filter to add. For more information please see
-# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
-# Qt Help Project / Custom Filters</a>.
-
-QHP_CUST_FILTER_ATTRS =
-
-# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
-# project's
-# filter section matches.
-# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
-# Qt Help Project / Filter Attributes</a>.
-
-QHP_SECT_FILTER_ATTRS =
-
-# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
-# be used to specify the location of Qt's qhelpgenerator.
-# If non-empty doxygen will try to run qhelpgenerator on the generated
-# .qhp file.
-
-QHG_LOCATION =
-
-# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
-# will be generated, which together with the HTML files, form an Eclipse help
-# plugin. To install this plugin and make it available under the help contents
-# menu in Eclipse, the contents of the directory containing the HTML and XML
-# files needs to be copied into the plugins directory of eclipse. The name of
-# the directory within the plugins directory should be the same as
-# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
-# the help appears.
-
-GENERATE_ECLIPSEHELP = NO
-
-# A unique identifier for the eclipse help plugin. When installing the plugin
-# the directory name containing the HTML and XML files should also have
-# this name.
-
-ECLIPSE_DOC_ID = org.doxygen.Project
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
-
-DISABLE_INDEX = NO
-
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 4
-
-# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
-# structure should be generated to display hierarchical information.
-# If the tag value is set to YES, a side panel will be generated
-# containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
-# Windows users are probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
-# links to external symbols imported via tag files in a separate window.
-
-EXT_LINKS_IN_WINDOW = NO
-
-# Use this tag to change the font size of Latex formulas included
-# as images in the HTML documentation. The default is 10. Note that
-# when you change the font size after a successful doxygen run you need
-# to manually remove any form_*.png images from the HTML output directory
-# to force them to be regenerated.
-
-FORMULA_FONTSIZE = 10
-
-# Use the FORMULA_TRANPARENT tag to determine whether or not the images
-# generated for formulas are transparent PNGs. Transparent PNGs are
-# not supported properly for IE 6.0, but are supported on all modern browsers.
-# Note that when changing this option you need to delete any form_*.png files
-# in the HTML output before the changes have effect.
-
-FORMULA_TRANSPARENT = YES
-
-# When the SEARCHENGINE tag is enabled doxygen will generate a search box
-# for the HTML output. The underlying search engine uses javascript
-# and DHTML and should work on any modern browser. Note that when using
-# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
-# (GENERATE_DOCSET) there is already a search function so this one should
-# typically be disabled. For large projects the javascript based search engine
-# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
-
-SEARCHENGINE = YES
-
-# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
-# implemented using a PHP enabled web server instead of at the web client
-# using Javascript. Doxygen will generate the search PHP script and index
-# file to put on the web server. The advantage of the server
-# based approach is that it scales better to large projects and allows
-# full text search. The disadvances is that it is more difficult to setup
-# and does not have live searching capabilities.
-
-SERVER_BASED_SEARCH = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked. If left blank `latex' will be used as the default command name.
-# Note that when enabling USE_PDFLATEX this option is only used for
-# generating bitmaps for formulas in the HTML output, but not in the
-# Makefile that is written to the output directory.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
-# default command name.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX = NO
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
-# in the output.
-
-LATEX_HIDE_INDICES = NO
-
-# If LATEX_SOURCE_CODE is set to YES then doxygen will include
-# source code with syntax highlighting in the LaTeX output.
-# Note that which sources are shown also depends on other settings
-# such as SOURCE_BROWSER.
-
-LATEX_SOURCE_CODE = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT = man
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation.
-
-GENERATE_XML = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD =
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader.
-# This is useful
-# if you want to understand what is going on.
-# On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION = YES
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_DEFINED tags.
-
-EXPAND_ONLY_PREDEF = YES
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
-# instead of the = operator.
-
-PREDEFINED = "__attribute__(x)=" \
- "DECLARE_ALIGNED(a,t,n)=t n" \
- "offsetof(x,y)=0x42" \
- av_alloc_size \
- AV_GCC_VERSION_AT_LEAST(x,y)=1 \
- __GNUC__=1 \
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED = declare_idct \
- READ_PAR_DATA \
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and will confuse
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-#
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-#
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
-# be listed.
-
-EXTERNAL_GROUPS = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
-# or super classes. Setting the tag to NO turns the diagrams off. Note that
-# this option is superseded by the HAVE_DOT option below. This is only a
-# fallback. It is recommended to install and use dot, since it yields more
-# powerful graphs.
-
-CLASS_DIAGRAMS = YES
-
-# You can define message sequence charts within doxygen comments using the \msc
-# command. Doxygen will then run the mscgen tool (see
-# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
-# documentation. The MSCGEN_PATH tag allows you to specify the directory where
-# the mscgen tool resides. If left empty the tool is assumed to be found in the
-# default search path.
-
-MSCGEN_PATH =
-
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = NO
-
-# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
-# allowed to run in parallel. When set to 0 (the default) doxygen will
-# base this on the number of processors available in the system. You can set it
-# explicitly to a value larger than 0 to get control over the balance
-# between CPU load and processing speed.
-
-DOT_NUM_THREADS = 0
-
-# By default doxygen will write a font called FreeSans.ttf to the output
-# directory and reference it in all dot files that doxygen generates. This
-# font does not include all possible unicode characters however, so when you need
-# these (or just want a differently looking font) you can specify the font name
-# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
-# which can be done by putting it in a standard location or by setting the
-# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
-# containing the font.
-
-DOT_FONTNAME = FreeSans
-
-# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
-# The default size is 10pt.
-
-DOT_FONTSIZE = 10
-
-# By default doxygen will tell dot to use the output directory to look for the
-# FreeSans.ttf font (which doxygen will put there itself). If you specify a
-# different font using DOT_FONTNAME you can set the path where dot
-# can find it using this tag.
-
-DOT_FONTPATH =
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-
-UML_LOOK = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH and HAVE_DOT options are set to YES then
-# doxygen will generate a call dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable call graphs
-# for selected functions only using the \callgraph command.
-
-CALL_GRAPH = NO
-
-# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
-# doxygen will generate a caller dependency graph for every global function
-# or class method. Note that enabling this option will significantly increase
-# the time of a run. So in most cases it will be better to enable caller
-# graphs for selected functions only using the \callergraph command.
-
-CALLER_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS =
-
-# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
-# nodes that will be shown in the graph. If the number of nodes in a graph
-# becomes larger than this value, doxygen will truncate the graph, which is
-# visualized by representing a node as a red box. Note that doxygen if the
-# number of direct children of the root node in a graph is already larger than
-# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
-# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
-
-DOT_GRAPH_MAX_NODES = 50
-
-# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
-# graphs generated by dot. A depth value of 3 means that only nodes reachable
-# from the root by following a path via at most 3 edges will be shown. Nodes
-# that lay further from the root node will be omitted. Note that setting this
-# option to 1 or 2 may greatly reduce the computation time needed for large
-# code bases. Also note that the size of a graph can be further restricted by
-# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
-
-MAX_DOT_GRAPH_DEPTH = 0
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, because dot on Windows does not
-# seem to support this out of the box. Warning: Depending on the platform used,
-# enabling this option may lead to badly anti-aliased labels on the edges of
-# a graph (i.e. they become hard to read).
-
-DOT_TRANSPARENT = YES
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS = NO
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP = YES
diff --git a/ffmpeg-2-8-11/doc/filters.texi b/ffmpeg-2-8-11/doc/filters.texi
deleted file mode 100644
index 2a2fab6..0000000
--- a/ffmpeg-2-8-11/doc/filters.texi
+++ /dev/null
@@ -1,13524 +0,0 @@
- at chapter Filtering Introduction
- at c man begin FILTERING INTRODUCTION
-
-Filtering in FFmpeg is enabled through the libavfilter library.
-
-In libavfilter, a filter can have multiple inputs and multiple
-outputs.
-To illustrate the sorts of things that are possible, we consider the
-following filtergraph.
-
- at verbatim
- [main]
-input --> split ---------------------> overlay --> output
- | ^
- |[tmp] [flip]|
- +-----> crop --> vflip -------+
- at end verbatim
-
-This filtergraph splits the input stream in two streams, then sends one
-stream through the crop filter and the vflip filter, before merging it
-back with the other stream by overlaying it on top. You can use the
-following command to achieve this:
-
- at example
-ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT
- at end example
-
-The result will be that the top half of the video is mirrored
-onto the bottom half of the output video.
-
-Filters in the same linear chain are separated by commas, and distinct
-linear chains of filters are separated by semicolons. In our example,
- at var{crop,vflip} are in one linear chain, @var{split} and
- at var{overlay} are separately in another. The points where the linear
-chains join are labelled by names enclosed in square brackets. In the
-example, the split filter generates two outputs that are associated to
-the labels @var{[main]} and @var{[tmp]}.
-
-The stream sent to the second output of @var{split}, labelled as
- at var{[tmp]}, is processed through the @var{crop} filter, which crops
-away the lower half part of the video, and then vertically flipped. The
- at var{overlay} filter takes in input the first unchanged output of the
-split filter (which was labelled as @var{[main]}), and overlay on its
-lower half the output generated by the @var{crop,vflip} filterchain.
-
-Some filters take in input a list of parameters: they are specified
-after the filter name and an equal sign, and are separated from each other
-by a colon.
-
-There exist so-called @var{source filters} that do not have an
-audio/video input, and @var{sink filters} that will not have audio/video
-output.
-
- at c man end FILTERING INTRODUCTION
-
- at chapter graph2dot
- at c man begin GRAPH2DOT
-
-The @file{graph2dot} program included in the FFmpeg @file{tools}
-directory can be used to parse a filtergraph description and issue a
-corresponding textual representation in the dot language.
-
-Invoke the command:
- at example
-graph2dot -h
- at end example
-
-to see how to use @file{graph2dot}.
-
-You can then pass the dot description to the @file{dot} program (from
-the graphviz suite of programs) and obtain a graphical representation
-of the filtergraph.
-
-For example the sequence of commands:
- at example
-echo @var{GRAPH_DESCRIPTION} | \
-tools/graph2dot -o graph.tmp && \
-dot -Tpng graph.tmp -o graph.png && \
-display graph.png
- at end example
-
-can be used to create and display an image representing the graph
-described by the @var{GRAPH_DESCRIPTION} string. Note that this string must be
-a complete self-contained graph, with its inputs and outputs explicitly defined.
-For example if your command line is of the form:
- at example
-ffmpeg -i infile -vf scale=640:360 outfile
- at end example
-your @var{GRAPH_DESCRIPTION} string will need to be of the form:
- at example
-nullsrc,scale=640:360,nullsink
- at end example
-you may also need to set the @var{nullsrc} parameters and add a @var{format}
-filter in order to simulate a specific input file.
-
- at c man end GRAPH2DOT
-
- at chapter Filtergraph description
- at c man begin FILTERGRAPH DESCRIPTION
-
-A filtergraph is a directed graph of connected filters. It can contain
-cycles, and there can be multiple links between a pair of
-filters. Each link has one input pad on one side connecting it to one
-filter from which it takes its input, and one output pad on the other
-side connecting it to one filter accepting its output.
-
-Each filter in a filtergraph is an instance of a filter class
-registered in the application, which defines the features and the
-number of input and output pads of the filter.
-
-A filter with no input pads is called a "source", and a filter with no
-output pads is called a "sink".
-
- at anchor{Filtergraph syntax}
- at section Filtergraph syntax
-
-A filtergraph has a textual representation, which is recognized by the
- at option{-filter}/@option{-vf}/@option{-af} and
- at option{-filter_complex} options in @command{ffmpeg} and
- at option{-vf}/@option{-af} in @command{ffplay}, and by the
- at code{avfilter_graph_parse_ptr()} function defined in
- at file{libavfilter/avfilter.h}.
-
-A filterchain consists of a sequence of connected filters, each one
-connected to the previous one in the sequence. A filterchain is
-represented by a list of ","-separated filter descriptions.
-
-A filtergraph consists of a sequence of filterchains. A sequence of
-filterchains is represented by a list of ";"-separated filterchain
-descriptions.
-
-A filter is represented by a string of the form:
-[@var{in_link_1}]...[@var{in_link_N}]@var{filter_name}=@var{arguments}[@var{out_link_1}]...[@var{out_link_M}]
-
- at var{filter_name} is the name of the filter class of which the
-described filter is an instance of, and has to be the name of one of
-the filter classes registered in the program.
-The name of the filter class is optionally followed by a string
-"=@var{arguments}".
-
- at var{arguments} is a string which contains the parameters used to
-initialize the filter instance. It may have one of two forms:
- at itemize
-
- at item
-A ':'-separated list of @var{key=value} pairs.
-
- at item
-A ':'-separated list of @var{value}. In this case, the keys are assumed to be
-the option names in the order they are declared. E.g. the @code{fade} filter
-declares three options in this order -- @option{type}, @option{start_frame} and
- at option{nb_frames}. Then the parameter list @var{in:0:30} means that the value
- at var{in} is assigned to the option @option{type}, @var{0} to
- at option{start_frame} and @var{30} to @option{nb_frames}.
-
- at item
-A ':'-separated list of mixed direct @var{value} and long @var{key=value}
-pairs. The direct @var{value} must precede the @var{key=value} pairs, and
-follow the same constraints order of the previous point. The following
- at var{key=value} pairs can be set in any preferred order.
-
- at end itemize
-
-If the option value itself is a list of items (e.g. the @code{format} filter
-takes a list of pixel formats), the items in the list are usually separated by
- at samp{|}.
-
-The list of arguments can be quoted using the character @samp{'} as initial
-and ending mark, and the character @samp{\} for escaping the characters
-within the quoted text; otherwise the argument string is considered
-terminated when the next special character (belonging to the set
- at samp{[]=;,}) is encountered.
-
-The name and arguments of the filter are optionally preceded and
-followed by a list of link labels.
-A link label allows one to name a link and associate it to a filter output
-or input pad. The preceding labels @var{in_link_1}
-... @var{in_link_N}, are associated to the filter input pads,
-the following labels @var{out_link_1} ... @var{out_link_M}, are
-associated to the output pads.
-
-When two link labels with the same name are found in the
-filtergraph, a link between the corresponding input and output pad is
-created.
-
-If an output pad is not labelled, it is linked by default to the first
-unlabelled input pad of the next filter in the filterchain.
-For example in the filterchain
- at example
-nullsrc, split[L1], [L2]overlay, nullsink
- at end example
-the split filter instance has two output pads, and the overlay filter
-instance two input pads. The first output pad of split is labelled
-"L1", the first input pad of overlay is labelled "L2", and the second
-output pad of split is linked to the second input pad of overlay,
-which are both unlabelled.
-
-In a filter description, if the input label of the first filter is not
-specified, "in" is assumed; if the output label of the last filter is not
-specified, "out" is assumed.
-
-In a complete filterchain all the unlabelled filter input and output
-pads must be connected. A filtergraph is considered valid if all the
-filter input and output pads of all the filterchains are connected.
-
-Libavfilter will automatically insert @ref{scale} filters where format
-conversion is required. It is possible to specify swscale flags
-for those automatically inserted scalers by prepending
- at code{sws_flags=@var{flags};}
-to the filtergraph description.
-
-Here is a BNF description of the filtergraph syntax:
- at example
- at var{NAME} ::= sequence of alphanumeric characters and '_'
- at var{LINKLABEL} ::= "[" @var{NAME} "]"
- at var{LINKLABELS} ::= @var{LINKLABEL} [@var{LINKLABELS}]
- at var{FILTER_ARGUMENTS} ::= sequence of chars (possibly quoted)
- at var{FILTER} ::= [@var{LINKLABELS}] @var{NAME} ["=" @var{FILTER_ARGUMENTS}] [@var{LINKLABELS}]
- at var{FILTERCHAIN} ::= @var{FILTER} [, at var{FILTERCHAIN}]
- at var{FILTERGRAPH} ::= [sws_flags=@var{flags};] @var{FILTERCHAIN} [;@var{FILTERGRAPH}]
- at end example
-
- at section Notes on filtergraph escaping
-
-Filtergraph description composition entails several levels of
-escaping. See @ref{quoting_and_escaping,,the "Quoting and escaping"
-section in the ffmpeg-utils(1) manual,ffmpeg-utils} for more
-information about the employed escaping procedure.
-
-A first level escaping affects the content of each filter option
-value, which may contain the special character @code{:} used to
-separate values, or one of the escaping characters @code{\'}.
-
-A second level escaping affects the whole filter description, which
-may contain the escaping characters @code{\'} or the special
-characters @code{[],;} used by the filtergraph description.
-
-Finally, when you specify a filtergraph on a shell commandline, you
-need to perform a third level escaping for the shell special
-characters contained within it.
-
-For example, consider the following string to be embedded in
-the @ref{drawtext} filter description @option{text} value:
- at example
-this is a 'string': may contain one, or more, special characters
- at end example
-
-This string contains the @code{'} special escaping character, and the
- at code{:} special character, so it needs to be escaped in this way:
- at example
-text=this is a \'string\'\: may contain one, or more, special characters
- at end example
-
-A second level of escaping is required when embedding the filter
-description in a filtergraph description, in order to escape all the
-filtergraph special characters. Thus the example above becomes:
- at example
-drawtext=text=this is a \\\'string\\\'\\: may contain one\, or more\, special characters
- at end example
-(note that in addition to the @code{\'} escaping special characters,
-also @code{,} needs to be escaped).
-
-Finally an additional level of escaping is needed when writing the
-filtergraph description in a shell command, which depends on the
-escaping rules of the adopted shell. For example, assuming that
- at code{\} is special and needs to be escaped with another @code{\}, the
-previous string will finally result in:
- at example
--vf "drawtext=text=this is a \\\\\\'string\\\\\\'\\\\: may contain one\\, or more\\, special characters"
- at end example
-
- at chapter Timeline editing
-
-Some filters support a generic @option{enable} option. For the filters
-supporting timeline editing, this option can be set to an expression which is
-evaluated before sending a frame to the filter. If the evaluation is non-zero,
-the filter will be enabled, otherwise the frame will be sent unchanged to the
-next filter in the filtergraph.
-
-The expression accepts the following values:
- at table @samp
- at item t
-timestamp expressed in seconds, NAN if the input timestamp is unknown
-
- at item n
-sequential number of the input frame, starting from 0
-
- at item pos
-the position in the file of the input frame, NAN if unknown
-
- at item w
- at item h
-width and height of the input frame if video
- at end table
-
-Additionally, these filters support an @option{enable} command that can be used
-to re-define the expression.
-
-Like any other filtering option, the @option{enable} option follows the same
-rules.
-
-For example, to enable a blur filter (@ref{smartblur}) from 10 seconds to 3
-minutes, and a @ref{curves} filter starting at 3 seconds:
- at example
-smartblur = enable='between(t,10,3*60)',
-curves = enable='gte(t,3)' : preset=cross_process
- at end example
-
- at c man end FILTERGRAPH DESCRIPTION
-
- at chapter Audio Filters
- at c man begin AUDIO FILTERS
-
-When you configure your FFmpeg build, you can disable any of the
-existing filters using @code{--disable-filters}.
-The configure output will show the audio filters included in your
-build.
-
-Below is a description of the currently available audio filters.
-
- at section acrossfade
-
-Apply cross fade from one input audio stream to another input audio stream.
-The cross fade is applied for specified duration near the end of first stream.
-
-The filter accepts the following options:
-
- at table @option
- at item nb_samples, ns
-Specify the number of samples for which the cross fade effect has to last.
-At the end of the cross fade effect the first input audio will be completely
-silent. Default is 44100.
-
- at item duration, d
-Specify the duration of the cross fade effect. See
- at ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}
-for the accepted syntax.
-By default the duration is determined by @var{nb_samples}.
-If set this option is used instead of @var{nb_samples}.
-
- at item overlap, o
-Should first stream end overlap with second stream start. Default is enabled.
-
- at item curve1
-Set curve for cross fade transition for first stream.
-
- at item curve2
-Set curve for cross fade transition for second stream.
-
-For description of available curve types see @ref{afade} filter description.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Cross fade from one input to another:
- at example
-ffmpeg -i first.flac -i second.flac -filter_complex acrossfade=d=10:c1=exp:c2=exp output.flac
- at end example
-
- at item
-Cross fade from one input to another but without overlapping:
- at example
-ffmpeg -i first.flac -i second.flac -filter_complex acrossfade=d=10:o=0:c1=exp:c2=exp output.flac
- at end example
- at end itemize
-
- at section adelay
-
-Delay one or more audio channels.
-
-Samples in delayed channel are filled with silence.
-
-The filter accepts the following option:
-
- at table @option
- at item delays
-Set list of delays in milliseconds for each channel separated by '|'.
-At least one delay greater than 0 should be provided.
-Unused delays will be silently ignored. If number of given delays is
-smaller than number of channels all remaining channels will not be delayed.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Delay first channel by 1.5 seconds, the third channel by 0.5 seconds and leave
-the second channel (and any other channels that may be present) unchanged.
- at example
-adelay=1500|0|500
- at end example
- at end itemize
-
- at section aecho
-
-Apply echoing to the input audio.
-
-Echoes are reflected sound and can occur naturally amongst mountains
-(and sometimes large buildings) when talking or shouting; digital echo
-effects emulate this behaviour and are often used to help fill out the
-sound of a single instrument or vocal. The time difference between the
-original signal and the reflection is the @code{delay}, and the
-loudness of the reflected signal is the @code{decay}.
-Multiple echoes can have different delays and decays.
-
-A description of the accepted parameters follows.
-
- at table @option
- at item in_gain
-Set input gain of reflected signal. Default is @code{0.6}.
-
- at item out_gain
-Set output gain of reflected signal. Default is @code{0.3}.
-
- at item delays
-Set list of time intervals in milliseconds between original signal and reflections
-separated by '|'. Allowed range for each @code{delay} is @code{(0 - 90000.0]}.
-Default is @code{1000}.
-
- at item decays
-Set list of loudnesses of reflected signals separated by '|'.
-Allowed range for each @code{decay} is @code{(0 - 1.0]}.
-Default is @code{0.5}.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Make it sound as if there are twice as many instruments as are actually playing:
- at example
-aecho=0.8:0.88:60:0.4
- at end example
-
- at item
-If delay is very short, then it sound like a (metallic) robot playing music:
- at example
-aecho=0.8:0.88:6:0.4
- at end example
-
- at item
-A longer delay will sound like an open air concert in the mountains:
- at example
-aecho=0.8:0.9:1000:0.3
- at end example
-
- at item
-Same as above but with one more mountain:
- at example
-aecho=0.8:0.9:1000|1800:0.3|0.25
- at end example
- at end itemize
-
- at section aeval
-
-Modify an audio signal according to the specified expressions.
-
-This filter accepts one or more expressions (one for each channel),
-which are evaluated and used to modify a corresponding audio signal.
-
-It accepts the following parameters:
-
- at table @option
- at item exprs
-Set the '|'-separated expressions list for each separate channel. If
-the number of input channels is greater than the number of
-expressions, the last specified expression is used for the remaining
-output channels.
-
- at item channel_layout, c
-Set output channel layout. If not specified, the channel layout is
-specified by the number of expressions. If set to @samp{same}, it will
-use by default the same input channel layout.
- at end table
-
-Each expression in @var{exprs} can contain the following constants and functions:
-
- at table @option
- at item ch
-channel number of the current expression
-
- at item n
-number of the evaluated sample, starting from 0
-
- at item s
-sample rate
-
- at item t
-time of the evaluated sample expressed in seconds
-
- at item nb_in_channels
- at item nb_out_channels
-input and output number of channels
-
- at item val(CH)
-the value of input channel with number @var{CH}
- at end table
-
-Note: this filter is slow. For faster processing you should use a
-dedicated filter.
-
- at subsection Examples
-
- at itemize
- at item
-Half volume:
- at example
-aeval=val(ch)/2:c=same
- at end example
-
- at item
-Invert phase of the second channel:
- at example
-aeval=val(0)|-val(1)
- at end example
- at end itemize
-
- at anchor{afade}
- at section afade
-
-Apply fade-in/out effect to input audio.
-
-A description of the accepted parameters follows.
-
- at table @option
- at item type, t
-Specify the effect type, can be either @code{in} for fade-in, or
- at code{out} for a fade-out effect. Default is @code{in}.
-
- at item start_sample, ss
-Specify the number of the start sample for starting to apply the fade
-effect. Default is 0.
-
- at item nb_samples, ns
-Specify the number of samples for which the fade effect has to last. At
-the end of the fade-in effect the output audio will have the same
-volume as the input audio, at the end of the fade-out transition
-the output audio will be silence. Default is 44100.
-
- at item start_time, st
-Specify the start time of the fade effect. Default is 0.
-The value must be specified as a time duration; see
- at ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}
-for the accepted syntax.
-If set this option is used instead of @var{start_sample}.
-
- at item duration, d
-Specify the duration of the fade effect. See
- at ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}
-for the accepted syntax.
-At the end of the fade-in effect the output audio will have the same
-volume as the input audio, at the end of the fade-out transition
-the output audio will be silence.
-By default the duration is determined by @var{nb_samples}.
-If set this option is used instead of @var{nb_samples}.
-
- at item curve
-Set curve for fade transition.
-
-It accepts the following values:
- at table @option
- at item tri
-select triangular, linear slope (default)
- at item qsin
-select quarter of sine wave
- at item hsin
-select half of sine wave
- at item esin
-select exponential sine wave
- at item log
-select logarithmic
- at item ipar
-select inverted parabola
- at item qua
-select quadratic
- at item cub
-select cubic
- at item squ
-select square root
- at item cbr
-select cubic root
- at item par
-select parabola
- at item exp
-select exponential
- at item iqsin
-select inverted quarter of sine wave
- at item ihsin
-select inverted half of sine wave
- at item dese
-select double-exponential seat
- at item desi
-select double-exponential sigmoid
- at end table
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Fade in first 15 seconds of audio:
- at example
-afade=t=in:ss=0:d=15
- at end example
-
- at item
-Fade out last 25 seconds of a 900 seconds audio:
- at example
-afade=t=out:st=875:d=25
- at end example
- at end itemize
-
- at anchor{aformat}
- at section aformat
-
-Set output format constraints for the input audio. The framework will
-negotiate the most appropriate format to minimize conversions.
-
-It accepts the following parameters:
- at table @option
-
- at item sample_fmts
-A '|'-separated list of requested sample formats.
-
- at item sample_rates
-A '|'-separated list of requested sample rates.
-
- at item channel_layouts
-A '|'-separated list of requested channel layouts.
-
-See @ref{channel layout syntax,,the Channel Layout section in the ffmpeg-utils(1) manual,ffmpeg-utils}
-for the required syntax.
- at end table
-
-If a parameter is omitted, all values are allowed.
-
-Force the output to either unsigned 8-bit or signed 16-bit stereo
- at example
-aformat=sample_fmts=u8|s16:channel_layouts=stereo
- at end example
-
- at section allpass
-
-Apply a two-pole all-pass filter with central frequency (in Hz)
- at var{frequency}, and filter-width @var{width}.
-An all-pass filter changes the audio's frequency to phase relationship
-without changing its frequency to amplitude relationship.
-
-The filter accepts the following options:
-
- at table @option
- at item frequency, f
-Set frequency in Hz.
-
- at item width_type
-Set method to specify band-width of filter.
- at table @option
- at item h
-Hz
- at item q
-Q-Factor
- at item o
-octave
- at item s
-slope
- at end table
-
- at item width, w
-Specify the band-width of a filter in width_type units.
- at end table
-
- at anchor{amerge}
- at section amerge
-
-Merge two or more audio streams into a single multi-channel stream.
-
-The filter accepts the following options:
-
- at table @option
-
- at item inputs
-Set the number of inputs. Default is 2.
-
- at end table
-
-If the channel layouts of the inputs are disjoint, and therefore compatible,
-the channel layout of the output will be set accordingly and the channels
-will be reordered as necessary. If the channel layouts of the inputs are not
-disjoint, the output will have all the channels of the first input then all
-the channels of the second input, in that order, and the channel layout of
-the output will be the default value corresponding to the total number of
-channels.
-
-For example, if the first input is in 2.1 (FL+FR+LF) and the second input
-is FC+BL+BR, then the output will be in 5.1, with the channels in the
-following order: a1, a2, b1, a3, b2, b3 (a1 is the first channel of the
-first input, b1 is the first channel of the second input).
-
-On the other hand, if both input are in stereo, the output channels will be
-in the default order: a1, a2, b1, b2, and the channel layout will be
-arbitrarily set to 4.0, which may or may not be the expected value.
-
-All inputs must have the same sample rate, and format.
-
-If inputs do not have the same duration, the output will stop with the
-shortest.
-
- at subsection Examples
-
- at itemize
- at item
-Merge two mono files into a stereo stream:
- at example
-amovie=left.wav [l] ; amovie=right.mp3 [r] ; [l] [r] amerge
- at end example
-
- at item
-Multiple merges assuming 1 video stream and 6 audio streams in @file{input.mkv}:
- at example
-ffmpeg -i input.mkv -filter_complex "[0:1][0:2][0:3][0:4][0:5][0:6] amerge=inputs=6" -c:a pcm_s16le output.mkv
- at end example
- at end itemize
-
- at section amix
-
-Mixes multiple audio inputs into a single output.
-
-Note that this filter only supports float samples (the @var{amerge}
-and @var{pan} audio filters support many formats). If the @var{amix}
-input has integer samples then @ref{aresample} will be automatically
-inserted to perform the conversion to float samples.
-
-For example
- at example
-ffmpeg -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex amix=inputs=3:duration=first:dropout_transition=3 OUTPUT
- at end example
-will mix 3 input audio streams to a single output with the same duration as the
-first input and a dropout transition time of 3 seconds.
-
-It accepts the following parameters:
- at table @option
-
- at item inputs
-The number of inputs. If unspecified, it defaults to 2.
-
- at item duration
-How to determine the end-of-stream.
- at table @option
-
- at item longest
-The duration of the longest input. (default)
-
- at item shortest
-The duration of the shortest input.
-
- at item first
-The duration of the first input.
-
- at end table
-
- at item dropout_transition
-The transition time, in seconds, for volume renormalization when an input
-stream ends. The default value is 2 seconds.
-
- at end table
-
- at section anull
-
-Pass the audio source unchanged to the output.
-
- at section apad
-
-Pad the end of an audio stream with silence.
-
-This can be used together with @command{ffmpeg} @option{-shortest} to
-extend audio streams to the same length as the video stream.
-
-A description of the accepted options follows.
-
- at table @option
- at item packet_size
-Set silence packet size. Default value is 4096.
-
- at item pad_len
-Set the number of samples of silence to add to the end. After the
-value is reached, the stream is terminated. This option is mutually
-exclusive with @option{whole_len}.
-
- at item whole_len
-Set the minimum total number of samples in the output audio stream. If
-the value is longer than the input audio length, silence is added to
-the end, until the value is reached. This option is mutually exclusive
-with @option{pad_len}.
- at end table
-
-If neither the @option{pad_len} nor the @option{whole_len} option is
-set, the filter will add silence to the end of the input stream
-indefinitely.
-
- at subsection Examples
-
- at itemize
- at item
-Add 1024 samples of silence to the end of the input:
- at example
-apad=pad_len=1024
- at end example
-
- at item
-Make sure the audio output will contain at least 10000 samples, pad
-the input with silence if required:
- at example
-apad=whole_len=10000
- at end example
-
- at item
-Use @command{ffmpeg} to pad the audio input with silence, so that the
-video stream will always result the shortest and will be converted
-until the end in the output file when using the @option{shortest}
-option:
- at example
-ffmpeg -i VIDEO -i AUDIO -filter_complex "[1:0]apad" -shortest OUTPUT
- at end example
- at end itemize
-
- at section aphaser
-Add a phasing effect to the input audio.
-
-A phaser filter creates series of peaks and troughs in the frequency spectrum.
-The position of the peaks and troughs are modulated so that they vary over time, creating a sweeping effect.
-
-A description of the accepted parameters follows.
-
- at table @option
- at item in_gain
-Set input gain. Default is 0.4.
-
- at item out_gain
-Set output gain. Default is 0.74
-
- at item delay
-Set delay in milliseconds. Default is 3.0.
-
- at item decay
-Set decay. Default is 0.4.
-
- at item speed
-Set modulation speed in Hz. Default is 0.5.
-
- at item type
-Set modulation type. Default is triangular.
-
-It accepts the following values:
- at table @samp
- at item triangular, t
- at item sinusoidal, s
- at end table
- at end table
-
- at anchor{aresample}
- at section aresample
-
-Resample the input audio to the specified parameters, using the
-libswresample library. If none are specified then the filter will
-automatically convert between its input and output.
-
-This filter is also able to stretch/squeeze the audio data to make it match
-the timestamps or to inject silence / cut out audio to make it match the
-timestamps, do a combination of both or do neither.
-
-The filter accepts the syntax
-[@var{sample_rate}:]@var{resampler_options}, where @var{sample_rate}
-expresses a sample rate and @var{resampler_options} is a list of
- at var{key}=@var{value} pairs, separated by ":". See the
-ffmpeg-resampler manual for the complete list of supported options.
-
- at subsection Examples
-
- at itemize
- at item
-Resample the input audio to 44100Hz:
- at example
-aresample=44100
- at end example
-
- at item
-Stretch/squeeze samples to the given timestamps, with a maximum of 1000
-samples per second compensation:
- at example
-aresample=async=1000
- at end example
- at end itemize
-
- at section asetnsamples
-
-Set the number of samples per each output audio frame.
-
-The last output packet may contain a different number of samples, as
-the filter will flush all the remaining samples when the input audio
-signal its end.
-
-The filter accepts the following options:
-
- at table @option
-
- at item nb_out_samples, n
-Set the number of frames per each output audio frame. The number is
-intended as the number of samples @emph{per each channel}.
-Default value is 1024.
-
- at item pad, p
-If set to 1, the filter will pad the last audio frame with zeroes, so
-that the last frame will contain the same number of samples as the
-previous ones. Default value is 1.
- at end table
-
-For example, to set the number of per-frame samples to 1234 and
-disable padding for the last frame, use:
- at example
-asetnsamples=n=1234:p=0
- at end example
-
- at section asetrate
-
-Set the sample rate without altering the PCM data.
-This will result in a change of speed and pitch.
-
-The filter accepts the following options:
-
- at table @option
- at item sample_rate, r
-Set the output sample rate. Default is 44100 Hz.
- at end table
-
- at section ashowinfo
-
-Show a line containing various information for each input audio frame.
-The input audio is not modified.
-
-The shown line contains a sequence of key/value pairs of the form
- at var{key}:@var{value}.
-
-The following values are shown in the output:
-
- at table @option
- at item n
-The (sequential) number of the input frame, starting from 0.
-
- at item pts
-The presentation timestamp of the input frame, in time base units; the time base
-depends on the filter input pad, and is usually 1/@var{sample_rate}.
-
- at item pts_time
-The presentation timestamp of the input frame in seconds.
-
- at item pos
-position of the frame in the input stream, -1 if this information in
-unavailable and/or meaningless (for example in case of synthetic audio)
-
- at item fmt
-The sample format.
-
- at item chlayout
-The channel layout.
-
- at item rate
-The sample rate for the audio frame.
-
- at item nb_samples
-The number of samples (per channel) in the frame.
-
- at item checksum
-The Adler-32 checksum (printed in hexadecimal) of the audio data. For planar
-audio, the data is treated as if all the planes were concatenated.
-
- at item plane_checksums
-A list of Adler-32 checksums for each data plane.
- at end table
-
- at anchor{astats}
- at section astats
-
-Display time domain statistical information about the audio channels.
-Statistics are calculated and displayed for each audio channel and,
-where applicable, an overall figure is also given.
-
-It accepts the following option:
- at table @option
- at item length
-Short window length in seconds, used for peak and trough RMS measurement.
-Default is @code{0.05} (50 milliseconds). Allowed range is @code{[0.1 - 10]}.
-
- at item metadata
-
-Set metadata injection. All the metadata keys are prefixed with @code{lavfi.astats.X},
-where @code{X} is channel number starting from 1 or string @code{Overall}. Default is
-disabled.
-
-Available keys for each channel are:
-DC_offset
-Min_level
-Max_level
-Min_difference
-Max_difference
-Mean_difference
-Peak_level
-RMS_peak
-RMS_trough
-Crest_factor
-Flat_factor
-Peak_count
-Bit_depth
-
-and for Overall:
-DC_offset
-Min_level
-Max_level
-Min_difference
-Max_difference
-Mean_difference
-Peak_level
-RMS_level
-RMS_peak
-RMS_trough
-Flat_factor
-Peak_count
-Bit_depth
-Number_of_samples
-
-For example full key look like this @code{lavfi.astats.1.DC_offset} or
-this @code{lavfi.astats.Overall.Peak_count}.
-
-For description what each key means read below.
-
- at item reset
-Set number of frame after which stats are going to be recalculated.
-Default is disabled.
- at end table
-
-A description of each shown parameter follows:
-
- at table @option
- at item DC offset
-Mean amplitude displacement from zero.
-
- at item Min level
-Minimal sample level.
-
- at item Max level
-Maximal sample level.
-
- at item Min difference
-Minimal difference between two consecutive samples.
-
- at item Max difference
-Maximal difference between two consecutive samples.
-
- at item Mean difference
-Mean difference between two consecutive samples.
-The average of each difference between two consecutive samples.
-
- at item Peak level dB
- at item RMS level dB
-Standard peak and RMS level measured in dBFS.
-
- at item RMS peak dB
- at item RMS trough dB
-Peak and trough values for RMS level measured over a short window.
-
- at item Crest factor
-Standard ratio of peak to RMS level (note: not in dB).
-
- at item Flat factor
-Flatness (i.e. consecutive samples with the same value) of the signal at its peak levels
-(i.e. either @var{Min level} or @var{Max level}).
-
- at item Peak count
-Number of occasions (not the number of samples) that the signal attained either
- at var{Min level} or @var{Max level}.
-
- at item Bit depth
-Overall bit depth of audio. Number of bits used for each sample.
- at end table
-
- at section astreamsync
-
-Forward two audio streams and control the order the buffers are forwarded.
-
-The filter accepts the following options:
-
- at table @option
- at item expr, e
-Set the expression deciding which stream should be
-forwarded next: if the result is negative, the first stream is forwarded; if
-the result is positive or zero, the second stream is forwarded. It can use
-the following variables:
-
- at table @var
- at item b1 b2
-number of buffers forwarded so far on each stream
- at item s1 s2
-number of samples forwarded so far on each stream
- at item t1 t2
-current timestamp of each stream
- at end table
-
-The default value is @code{t1-t2}, which means to always forward the stream
-that has a smaller timestamp.
- at end table
-
- at subsection Examples
-
-Stress-test @code{amerge} by randomly sending buffers on the wrong
-input, while avoiding too much of a desynchronization:
- at example
-amovie=file.ogg [a] ; amovie=file.mp3 [b] ;
-[a] [b] astreamsync=(2*random(1))-1+tanh(5*(t1-t2)) [a2] [b2] ;
-[a2] [b2] amerge
- at end example
-
- at section asyncts
-
-Synchronize audio data with timestamps by squeezing/stretching it and/or
-dropping samples/adding silence when needed.
-
-This filter is not built by default, please use @ref{aresample} to do squeezing/stretching.
-
-It accepts the following parameters:
- at table @option
-
- at item compensate
-Enable stretching/squeezing the data to make it match the timestamps. Disabled
-by default. When disabled, time gaps are covered with silence.
-
- at item min_delta
-The minimum difference between timestamps and audio data (in seconds) to trigger
-adding/dropping samples. The default value is 0.1. If you get an imperfect
-sync with this filter, try setting this parameter to 0.
-
- at item max_comp
-The maximum compensation in samples per second. Only relevant with compensate=1.
-The default value is 500.
-
- at item first_pts
-Assume that the first PTS should be this value. The time base is 1 / sample
-rate. This allows for padding/trimming at the start of the stream. By default,
-no assumption is made about the first frame's expected PTS, so no padding or
-trimming is done. For example, this could be set to 0 to pad the beginning with
-silence if an audio stream starts after the video stream or to trim any samples
-with a negative PTS due to encoder delay.
-
- at end table
-
- at section atempo
-
-Adjust audio tempo.
-
-The filter accepts exactly one parameter, the audio tempo. If not
-specified then the filter will assume nominal 1.0 tempo. Tempo must
-be in the [0.5, 2.0] range.
-
- at subsection Examples
-
- at itemize
- at item
-Slow down audio to 80% tempo:
- at example
-atempo=0.8
- at end example
-
- at item
-To speed up audio to 125% tempo:
- at example
-atempo=1.25
- at end example
- at end itemize
-
- at section atrim
-
-Trim the input so that the output contains one continuous subpart of the input.
-
-It accepts the following parameters:
- at table @option
- at item start
-Timestamp (in seconds) of the start of the section to keep. I.e. the audio
-sample with the timestamp @var{start} will be the first sample in the output.
-
- at item end
-Specify time of the first audio sample that will be dropped, i.e. the
-audio sample immediately preceding the one with the timestamp @var{end} will be
-the last sample in the output.
-
- at item start_pts
-Same as @var{start}, except this option sets the start timestamp in samples
-instead of seconds.
-
- at item end_pts
-Same as @var{end}, except this option sets the end timestamp in samples instead
-of seconds.
-
- at item duration
-The maximum duration of the output in seconds.
-
- at item start_sample
-The number of the first sample that should be output.
-
- at item end_sample
-The number of the first sample that should be dropped.
- at end table
-
- at option{start}, @option{end}, and @option{duration} are expressed as time
-duration specifications; see
- at ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
-
-Note that the first two sets of the start/end options and the @option{duration}
-option look at the frame timestamp, while the _sample options simply count the
-samples that pass through the filter. So start/end_pts and start/end_sample will
-give different results when the timestamps are wrong, inexact or do not start at
-zero. Also note that this filter does not modify the timestamps. If you wish
-to have the output timestamps start at zero, insert the asetpts filter after the
-atrim filter.
-
-If multiple start or end options are set, this filter tries to be greedy and
-keep all samples that match at least one of the specified constraints. To keep
-only the part that matches all the constraints at once, chain multiple atrim
-filters.
-
-The defaults are such that all the input is kept. So it is possible to set e.g.
-just the end values to keep everything before the specified time.
-
-Examples:
- at itemize
- at item
-Drop everything except the second minute of input:
- at example
-ffmpeg -i INPUT -af atrim=60:120
- at end example
-
- at item
-Keep only the first 1000 samples:
- at example
-ffmpeg -i INPUT -af atrim=end_sample=1000
- at end example
-
- at end itemize
-
- at section bandpass
-
-Apply a two-pole Butterworth band-pass filter with central
-frequency @var{frequency}, and (3dB-point) band-width width.
-The @var{csg} option selects a constant skirt gain (peak gain = Q)
-instead of the default: constant 0dB peak gain.
-The filter roll off at 6dB per octave (20dB per decade).
-
-The filter accepts the following options:
-
- at table @option
- at item frequency, f
-Set the filter's central frequency. Default is @code{3000}.
-
- at item csg
-Constant skirt gain if set to 1. Defaults to 0.
-
- at item width_type
-Set method to specify band-width of filter.
- at table @option
- at item h
-Hz
- at item q
-Q-Factor
- at item o
-octave
- at item s
-slope
- at end table
-
- at item width, w
-Specify the band-width of a filter in width_type units.
- at end table
-
- at section bandreject
-
-Apply a two-pole Butterworth band-reject filter with central
-frequency @var{frequency}, and (3dB-point) band-width @var{width}.
-The filter roll off at 6dB per octave (20dB per decade).
-
-The filter accepts the following options:
-
- at table @option
- at item frequency, f
-Set the filter's central frequency. Default is @code{3000}.
-
- at item width_type
-Set method to specify band-width of filter.
- at table @option
- at item h
-Hz
- at item q
-Q-Factor
- at item o
-octave
- at item s
-slope
- at end table
-
- at item width, w
-Specify the band-width of a filter in width_type units.
- at end table
-
- at section bass
-
-Boost or cut the bass (lower) frequencies of the audio using a two-pole
-shelving filter with a response similar to that of a standard
-hi-fi's tone-controls. This is also known as shelving equalisation (EQ).
-
-The filter accepts the following options:
-
- at table @option
- at item gain, g
-Give the gain at 0 Hz. Its useful range is about -20
-(for a large cut) to +20 (for a large boost).
-Beware of clipping when using a positive gain.
-
- at item frequency, f
-Set the filter's central frequency and so can be used
-to extend or reduce the frequency range to be boosted or cut.
-The default value is @code{100} Hz.
-
- at item width_type
-Set method to specify band-width of filter.
- at table @option
- at item h
-Hz
- at item q
-Q-Factor
- at item o
-octave
- at item s
-slope
- at end table
-
- at item width, w
-Determine how steep is the filter's shelf transition.
- at end table
-
- at section biquad
-
-Apply a biquad IIR filter with the given coefficients.
-Where @var{b0}, @var{b1}, @var{b2} and @var{a0}, @var{a1}, @var{a2}
-are the numerator and denominator coefficients respectively.
-
- at section bs2b
-Bauer stereo to binaural transformation, which improves headphone listening of
-stereo audio records.
-
-It accepts the following parameters:
- at table @option
-
- at item profile
-Pre-defined crossfeed level.
- at table @option
-
- at item default
-Default level (fcut=700, feed=50).
-
- at item cmoy
-Chu Moy circuit (fcut=700, feed=60).
-
- at item jmeier
-Jan Meier circuit (fcut=650, feed=95).
-
- at end table
-
- at item fcut
-Cut frequency (in Hz).
-
- at item feed
-Feed level (in Hz).
-
- at end table
-
- at section channelmap
-
-Remap input channels to new locations.
-
-It accepts the following parameters:
- at table @option
- at item channel_layout
-The channel layout of the output stream.
-
- at item map
-Map channels from input to output. The argument is a '|'-separated list of
-mappings, each in the @code{@var{in_channel}- at var{out_channel}} or
- at var{in_channel} form. @var{in_channel} can be either the name of the input
-channel (e.g. FL for front left) or its index in the input channel layout.
- at var{out_channel} is the name of the output channel or its index in the output
-channel layout. If @var{out_channel} is not given then it is implicitly an
-index, starting with zero and increasing by one for each mapping.
- at end table
-
-If no mapping is present, the filter will implicitly map input channels to
-output channels, preserving indices.
-
-For example, assuming a 5.1+downmix input MOV file,
- at example
-ffmpeg -i in.mov -filter 'channelmap=map=DL-FL|DR-FR' out.wav
- at end example
-will create an output WAV file tagged as stereo from the downmix channels of
-the input.
-
-To fix a 5.1 WAV improperly encoded in AAC's native channel order
- at example
-ffmpeg -i in.wav -filter 'channelmap=1|2|0|5|3|4:5.1' out.wav
- at end example
-
- at section channelsplit
-
-Split each channel from an input audio stream into a separate output stream.
-
-It accepts the following parameters:
- at table @option
- at item channel_layout
-The channel layout of the input stream. The default is "stereo".
- at end table
-
-For example, assuming a stereo input MP3 file,
- at example
-ffmpeg -i in.mp3 -filter_complex channelsplit out.mkv
- at end example
-will create an output Matroska file with two audio streams, one containing only
-the left channel and the other the right channel.
-
-Split a 5.1 WAV file into per-channel files:
- at example
-ffmpeg -i in.wav -filter_complex
-'channelsplit=channel_layout=5.1[FL][FR][FC][LFE][SL][SR]'
--map '[FL]' front_left.wav -map '[FR]' front_right.wav -map '[FC]'
-front_center.wav -map '[LFE]' lfe.wav -map '[SL]' side_left.wav -map '[SR]'
-side_right.wav
- at end example
-
- at section chorus
-Add a chorus effect to the audio.
-
-Can make a single vocal sound like a chorus, but can also be applied to instrumentation.
-
-Chorus resembles an echo effect with a short delay, but whereas with echo the delay is
-constant, with chorus, it is varied using using sinusoidal or triangular modulation.
-The modulation depth defines the range the modulated delay is played before or after
-the delay. Hence the delayed sound will sound slower or faster, that is the delayed
-sound tuned around the original one, like in a chorus where some vocals are slightly
-off key.
-
-It accepts the following parameters:
- at table @option
- at item in_gain
-Set input gain. Default is 0.4.
-
- at item out_gain
-Set output gain. Default is 0.4.
-
- at item delays
-Set delays. A typical delay is around 40ms to 60ms.
-
- at item decays
-Set decays.
-
- at item speeds
-Set speeds.
-
- at item depths
-Set depths.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-A single delay:
- at example
-chorus=0.7:0.9:55:0.4:0.25:2
- at end example
-
- at item
-Two delays:
- at example
-chorus=0.6:0.9:50|60:0.4|0.32:0.25|0.4:2|1.3
- at end example
-
- at item
-Fuller sounding chorus with three delays:
- at example
-chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3
- at end example
- at end itemize
-
- at section compand
-Compress or expand the audio's dynamic range.
-
-It accepts the following parameters:
-
- at table @option
-
- at item attacks
- at item decays
-A list of times in seconds for each channel over which the instantaneous level
-of the input signal is averaged to determine its volume. @var{attacks} refers to
-increase of volume and @var{decays} refers to decrease of volume. For most
-situations, the attack time (response to the audio getting louder) should be
-shorter than the decay time, because the human ear is more sensitive to sudden
-loud audio than sudden soft audio. A typical value for attack is 0.3 seconds and
-a typical value for decay is 0.8 seconds.
-If specified number of attacks & decays is lower than number of channels, the last
-set attack/decay will be used for all remaining channels.
-
- at item points
-A list of points for the transfer function, specified in dB relative to the
-maximum possible signal amplitude. Each key points list must be defined using
-the following syntax: @code{x0/y0|x1/y1|x2/y2|....} or
- at code{x0/y0 x1/y1 x2/y2 ....}
-
-The input values must be in strictly increasing order but the transfer function
-does not have to be monotonically rising. The point @code{0/0} is assumed but
-may be overridden (by @code{0/out-dBn}). Typical values for the transfer
-function are @code{-70/-70|-60/-20}.
-
- at item soft-knee
-Set the curve radius in dB for all joints. It defaults to 0.01.
-
- at item gain
-Set the additional gain in dB to be applied at all points on the transfer
-function. This allows for easy adjustment of the overall gain.
-It defaults to 0.
-
- at item volume
-Set an initial volume, in dB, to be assumed for each channel when filtering
-starts. This permits the user to supply a nominal level initially, so that, for
-example, a very large gain is not applied to initial signal levels before the
-companding has begun to operate. A typical value for audio which is initially
-quiet is -90 dB. It defaults to 0.
-
- at item delay
-Set a delay, in seconds. The input audio is analyzed immediately, but audio is
-delayed before being fed to the volume adjuster. Specifying a delay
-approximately equal to the attack/decay times allows the filter to effectively
-operate in predictive rather than reactive mode. It defaults to 0.
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Make music with both quiet and loud passages suitable for listening to in a
-noisy environment:
- at example
-compand=.3|.3:1|1:-90/-60|-60/-40|-40/-30|-20/-20:6:0:-90:0.2
- at end example
-
-Another example for audio with whisper and explosion parts:
- at example
-compand=0|0:1|1:-90/-900|-70/-70|-30/-9|0/-3:6:0:0:0
- at end example
-
- at item
-A noise gate for when the noise is at a lower level than the signal:
- at example
-compand=.1|.1:.2|.2:-900/-900|-50.1/-900|-50/-50:.01:0:-90:.1
- at end example
-
- at item
-Here is another noise gate, this time for when the noise is at a higher level
-than the signal (making it, in some ways, similar to squelch):
- at example
-compand=.1|.1:.1|.1:-45.1/-45.1|-45/-900|0/-900:.01:45:-90:.1
- at end example
- at end itemize
-
- at section dcshift
-Apply a DC shift to the audio.
-
-This can be useful to remove a DC offset (caused perhaps by a hardware problem
-in the recording chain) from the audio. The effect of a DC offset is reduced
-headroom and hence volume. The @ref{astats} filter can be used to determine if
-a signal has a DC offset.
-
- at table @option
- at item shift
-Set the DC shift, allowed range is [-1, 1]. It indicates the amount to shift
-the audio.
-
- at item limitergain
-Optional. It should have a value much less than 1 (e.g. 0.05 or 0.02) and is
-used to prevent clipping.
- at end table
-
- at section dynaudnorm
-Dynamic Audio Normalizer.
-
-This filter applies a certain amount of gain to the input audio in order
-to bring its peak magnitude to a target level (e.g. 0 dBFS). However, in
-contrast to more "simple" normalization algorithms, the Dynamic Audio
-Normalizer *dynamically* re-adjusts the gain factor to the input audio.
-This allows for applying extra gain to the "quiet" sections of the audio
-while avoiding distortions or clipping the "loud" sections. In other words:
-The Dynamic Audio Normalizer will "even out" the volume of quiet and loud
-sections, in the sense that the volume of each section is brought to the
-same target level. Note, however, that the Dynamic Audio Normalizer achieves
-this goal *without* applying "dynamic range compressing". It will retain 100%
-of the dynamic range *within* each section of the audio file.
-
- at table @option
- at item f
-Set the frame length in milliseconds. In range from 10 to 8000 milliseconds.
-Default is 500 milliseconds.
-The Dynamic Audio Normalizer processes the input audio in small chunks,
-referred to as frames. This is required, because a peak magnitude has no
-meaning for just a single sample value. Instead, we need to determine the
-peak magnitude for a contiguous sequence of sample values. While a "standard"
-normalizer would simply use the peak magnitude of the complete file, the
-Dynamic Audio Normalizer determines the peak magnitude individually for each
-frame. The length of a frame is specified in milliseconds. By default, the
-Dynamic Audio Normalizer uses a frame length of 500 milliseconds, which has
-been found to give good results with most files.
-Note that the exact frame length, in number of samples, will be determined
-automatically, based on the sampling rate of the individual input audio file.
-
- at item g
-Set the Gaussian filter window size. In range from 3 to 301, must be odd
-number. Default is 31.
-Probably the most important parameter of the Dynamic Audio Normalizer is the
- at code{window size} of the Gaussian smoothing filter. The filter's window size
-is specified in frames, centered around the current frame. For the sake of
-simplicity, this must be an odd number. Consequently, the default value of 31
-takes into account the current frame, as well as the 15 preceding frames and
-the 15 subsequent frames. Using a larger window results in a stronger
-smoothing effect and thus in less gain variation, i.e. slower gain
-adaptation. Conversely, using a smaller window results in a weaker smoothing
-effect and thus in more gain variation, i.e. faster gain adaptation.
-In other words, the more you increase this value, the more the Dynamic Audio
-Normalizer will behave like a "traditional" normalization filter. On the
-contrary, the more you decrease this value, the more the Dynamic Audio
-Normalizer will behave like a dynamic range compressor.
-
- at item p
-Set the target peak value. This specifies the highest permissible magnitude
-level for the normalized audio input. This filter will try to approach the
-target peak magnitude as closely as possible, but at the same time it also
-makes sure that the normalized signal will never exceed the peak magnitude.
-A frame's maximum local gain factor is imposed directly by the target peak
-magnitude. The default value is 0.95 and thus leaves a headroom of 5%*.
-It is not recommended to go above this value.
-
- at item m
-Set the maximum gain factor. In range from 1.0 to 100.0. Default is 10.0.
-The Dynamic Audio Normalizer determines the maximum possible (local) gain
-factor for each input frame, i.e. the maximum gain factor that does not
-result in clipping or distortion. The maximum gain factor is determined by
-the frame's highest magnitude sample. However, the Dynamic Audio Normalizer
-additionally bounds the frame's maximum gain factor by a predetermined
-(global) maximum gain factor. This is done in order to avoid excessive gain
-factors in "silent" or almost silent frames. By default, the maximum gain
-factor is 10.0, For most inputs the default value should be sufficient and
-it usually is not recommended to increase this value. Though, for input
-with an extremely low overall volume level, it may be necessary to allow even
-higher gain factors. Note, however, that the Dynamic Audio Normalizer does
-not simply apply a "hard" threshold (i.e. cut off values above the threshold).
-Instead, a "sigmoid" threshold function will be applied. This way, the
-gain factors will smoothly approach the threshold value, but never exceed that
-value.
-
- at item r
-Set the target RMS. In range from 0.0 to 1.0. Default is 0.0 - disabled.
-By default, the Dynamic Audio Normalizer performs "peak" normalization.
-This means that the maximum local gain factor for each frame is defined
-(only) by the frame's highest magnitude sample. This way, the samples can
-be amplified as much as possible without exceeding the maximum signal
-level, i.e. without clipping. Optionally, however, the Dynamic Audio
-Normalizer can also take into account the frame's root mean square,
-abbreviated RMS. In electrical engineering, the RMS is commonly used to
-determine the power of a time-varying signal. It is therefore considered
-that the RMS is a better approximation of the "perceived loudness" than
-just looking at the signal's peak magnitude. Consequently, by adjusting all
-frames to a constant RMS value, a uniform "perceived loudness" can be
-established. If a target RMS value has been specified, a frame's local gain
-factor is defined as the factor that would result in exactly that RMS value.
-Note, however, that the maximum local gain factor is still restricted by the
-frame's highest magnitude sample, in order to prevent clipping.
-
- at item n
-Enable channels coupling. By default is enabled.
-By default, the Dynamic Audio Normalizer will amplify all channels by the same
-amount. This means the same gain factor will be applied to all channels, i.e.
-the maximum possible gain factor is determined by the "loudest" channel.
-However, in some recordings, it may happen that the volume of the different
-channels is uneven, e.g. one channel may be "quieter" than the other one(s).
-In this case, this option can be used to disable the channel coupling. This way,
-the gain factor will be determined independently for each channel, depending
-only on the individual channel's highest magnitude sample. This allows for
-harmonizing the volume of the different channels.
-
- at item c
-Enable DC bias correction. By default is disabled.
-An audio signal (in the time domain) is a sequence of sample values.
-In the Dynamic Audio Normalizer these sample values are represented in the
--1.0 to 1.0 range, regardless of the original input format. Normally, the
-audio signal, or "waveform", should be centered around the zero point.
-That means if we calculate the mean value of all samples in a file, or in a
-single frame, then the result should be 0.0 or at least very close to that
-value. If, however, there is a significant deviation of the mean value from
-0.0, in either positive or negative direction, this is referred to as a
-DC bias or DC offset. Since a DC bias is clearly undesirable, the Dynamic
-Audio Normalizer provides optional DC bias correction.
-With DC bias correction enabled, the Dynamic Audio Normalizer will determine
-the mean value, or "DC correction" offset, of each input frame and subtract
-that value from all of the frame's sample values which ensures those samples
-are centered around 0.0 again. Also, in order to avoid "gaps" at the frame
-boundaries, the DC correction offset values will be interpolated smoothly
-between neighbouring frames.
-
- at item b
-Enable alternative boundary mode. By default is disabled.
-The Dynamic Audio Normalizer takes into account a certain neighbourhood
-around each frame. This includes the preceding frames as well as the
-subsequent frames. However, for the "boundary" frames, located at the very
-beginning and at the very end of the audio file, not all neighbouring
-frames are available. In particular, for the first few frames in the audio
-file, the preceding frames are not known. And, similarly, for the last few
-frames in the audio file, the subsequent frames are not known. Thus, the
-question arises which gain factors should be assumed for the missing frames
-in the "boundary" region. The Dynamic Audio Normalizer implements two modes
-to deal with this situation. The default boundary mode assumes a gain factor
-of exactly 1.0 for the missing frames, resulting in a smooth "fade in" and
-"fade out" at the beginning and at the end of the input, respectively.
-
- at item s
-Set the compress factor. In range from 0.0 to 30.0. Default is 0.0.
-By default, the Dynamic Audio Normalizer does not apply "traditional"
-compression. This means that signal peaks will not be pruned and thus the
-full dynamic range will be retained within each local neighbourhood. However,
-in some cases it may be desirable to combine the Dynamic Audio Normalizer's
-normalization algorithm with a more "traditional" compression.
-For this purpose, the Dynamic Audio Normalizer provides an optional compression
-(thresholding) function. If (and only if) the compression feature is enabled,
-all input frames will be processed by a soft knee thresholding function prior
-to the actual normalization process. Put simply, the thresholding function is
-going to prune all samples whose magnitude exceeds a certain threshold value.
-However, the Dynamic Audio Normalizer does not simply apply a fixed threshold
-value. Instead, the threshold value will be adjusted for each individual
-frame.
-In general, smaller parameters result in stronger compression, and vice versa.
-Values below 3.0 are not recommended, because audible distortion may appear.
- at end table
-
- at section earwax
-
-Make audio easier to listen to on headphones.
-
-This filter adds `cues' to 44.1kHz stereo (i.e. audio CD format) audio
-so that when listened to on headphones the stereo image is moved from
-inside your head (standard for headphones) to outside and in front of
-the listener (standard for speakers).
-
-Ported from SoX.
-
- at section equalizer
-
-Apply a two-pole peaking equalisation (EQ) filter. With this
-filter, the signal-level at and around a selected frequency can
-be increased or decreased, whilst (unlike bandpass and bandreject
-filters) that at all other frequencies is unchanged.
-
-In order to produce complex equalisation curves, this filter can
-be given several times, each with a different central frequency.
-
-The filter accepts the following options:
-
- at table @option
- at item frequency, f
-Set the filter's central frequency in Hz.
-
- at item width_type
-Set method to specify band-width of filter.
- at table @option
- at item h
-Hz
- at item q
-Q-Factor
- at item o
-octave
- at item s
-slope
- at end table
-
- at item width, w
-Specify the band-width of a filter in width_type units.
-
- at item gain, g
-Set the required gain or attenuation in dB.
-Beware of clipping when using a positive gain.
- at end table
-
- at subsection Examples
- at itemize
- at item
-Attenuate 10 dB at 1000 Hz, with a bandwidth of 200 Hz:
- at example
-equalizer=f=1000:width_type=h:width=200:g=-10
- at end example
-
- at item
-Apply 2 dB gain at 1000 Hz with Q 1 and attenuate 5 dB at 100 Hz with Q 2:
- at example
-equalizer=f=1000:width_type=q:width=1:g=2,equalizer=f=100:width_type=q:width=2:g=-5
- at end example
- at end itemize
-
- at section flanger
-Apply a flanging effect to the audio.
-
-The filter accepts the following options:
-
- at table @option
- at item delay
-Set base delay in milliseconds. Range from 0 to 30. Default value is 0.
-
- at item depth
-Set added swep delay in milliseconds. Range from 0 to 10. Default value is 2.
-
- at item regen
-Set percentage regeneration (delayed signal feedback). Range from -95 to 95.
-Default value is 0.
-
- at item width
-Set percentage of delayed signal mixed with original. Range from 0 to 100.
-Default value is 71.
-
- at item speed
-Set sweeps per second (Hz). Range from 0.1 to 10. Default value is 0.5.
-
- at item shape
-Set swept wave shape, can be @var{triangular} or @var{sinusoidal}.
-Default value is @var{sinusoidal}.
-
- at item phase
-Set swept wave percentage-shift for multi channel. Range from 0 to 100.
-Default value is 25.
-
- at item interp
-Set delay-line interpolation, @var{linear} or @var{quadratic}.
-Default is @var{linear}.
- at end table
-
- at section highpass
-
-Apply a high-pass filter with 3dB point frequency.
-The filter can be either single-pole, or double-pole (the default).
-The filter roll off at 6dB per pole per octave (20dB per pole per decade).
-
-The filter accepts the following options:
-
- at table @option
- at item frequency, f
-Set frequency in Hz. Default is 3000.
-
- at item poles, p
-Set number of poles. Default is 2.
-
- at item width_type
-Set method to specify band-width of filter.
- at table @option
- at item h
-Hz
- at item q
-Q-Factor
- at item o
-octave
- at item s
-slope
- at end table
-
- at item width, w
-Specify the band-width of a filter in width_type units.
-Applies only to double-pole filter.
-The default is 0.707q and gives a Butterworth response.
- at end table
-
- at section join
-
-Join multiple input streams into one multi-channel stream.
-
-It accepts the following parameters:
- at table @option
-
- at item inputs
-The number of input streams. It defaults to 2.
-
- at item channel_layout
-The desired output channel layout. It defaults to stereo.
-
- at item map
-Map channels from inputs to output. The argument is a '|'-separated list of
-mappings, each in the @code{@var{input_idx}. at var{in_channel}- at var{out_channel}}
-form. @var{input_idx} is the 0-based index of the input stream. @var{in_channel}
-can be either the name of the input channel (e.g. FL for front left) or its
-index in the specified input stream. @var{out_channel} is the name of the output
-channel.
- at end table
-
-The filter will attempt to guess the mappings when they are not specified
-explicitly. It does so by first trying to find an unused matching input channel
-and if that fails it picks the first unused input channel.
-
-Join 3 inputs (with properly set channel layouts):
- at example
-ffmpeg -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex join=inputs=3 OUTPUT
- at end example
-
-Build a 5.1 output from 6 single-channel streams:
- at example
-ffmpeg -i fl -i fr -i fc -i sl -i sr -i lfe -filter_complex
-'join=inputs=6:channel_layout=5.1:map=0.0-FL|1.0-FR|2.0-FC|3.0-SL|4.0-SR|5.0-LFE'
-out
- at end example
-
- at section ladspa
-
-Load a LADSPA (Linux Audio Developer's Simple Plugin API) plugin.
-
-To enable compilation of this filter you need to configure FFmpeg with
- at code{--enable-ladspa}.
-
- at table @option
- at item file, f
-Specifies the name of LADSPA plugin library to load. If the environment
-variable @env{LADSPA_PATH} is defined, the LADSPA plugin is searched in
-each one of the directories specified by the colon separated list in
- at env{LADSPA_PATH}, otherwise in the standard LADSPA paths, which are in
-this order: @file{HOME/.ladspa/lib/}, @file{/usr/local/lib/ladspa/},
- at file{/usr/lib/ladspa/}.
-
- at item plugin, p
-Specifies the plugin within the library. Some libraries contain only
-one plugin, but others contain many of them. If this is not set filter
-will list all available plugins within the specified library.
-
- at item controls, c
-Set the '|' separated list of controls which are zero or more floating point
-values that determine the behavior of the loaded plugin (for example delay,
-threshold or gain).
-Controls need to be defined using the following syntax:
-c0=@var{value0}|c1=@var{value1}|c2=@var{value2}|..., where
- at var{valuei} is the value set on the @var{i}-th control.
-If @option{controls} is set to @code{help}, all available controls and
-their valid ranges are printed.
-
- at item sample_rate, s
-Specify the sample rate, default to 44100. Only used if plugin have
-zero inputs.
-
- at item nb_samples, n
-Set the number of samples per channel per each output frame, default
-is 1024. Only used if plugin have zero inputs.
-
- at item duration, d
-Set the minimum duration of the sourced audio. See
- at ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}
-for the accepted syntax.
-Note that the resulting duration may be greater than the specified duration,
-as the generated audio is always cut at the end of a complete frame.
-If not specified, or the expressed duration is negative, the audio is
-supposed to be generated forever.
-Only used if plugin have zero inputs.
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-List all available plugins within amp (LADSPA example plugin) library:
- at example
-ladspa=file=amp
- at end example
-
- at item
-List all available controls and their valid ranges for @code{vcf_notch}
-plugin from @code{VCF} library:
- at example
-ladspa=f=vcf:p=vcf_notch:c=help
- at end example
-
- at item
-Simulate low quality audio equipment using @code{Computer Music Toolkit} (CMT)
-plugin library:
- at example
-ladspa=file=cmt:plugin=lofi:controls=c0=22|c1=12|c2=12
- at end example
-
- at item
-Add reverberation to the audio using TAP-plugins
-(Tom's Audio Processing plugins):
- at example
-ladspa=file=tap_reverb:tap_reverb
- at end example
-
- at item
-Generate white noise, with 0.2 amplitude:
- at example
-ladspa=file=cmt:noise_source_white:c=c0=.2
- at end example
-
- at item
-Generate 20 bpm clicks using plugin @code{C* Click - Metronome} from the
- at code{C* Audio Plugin Suite} (CAPS) library:
- at example
-ladspa=file=caps:Click:c=c1=20'
- at end example
-
- at item
-Apply @code{C* Eq10X2 - Stereo 10-band equaliser} effect:
- at example
-ladspa=caps:Eq10X2:c=c0=-48|c9=-24|c3=12|c4=2
- at end example
- at end itemize
-
- at subsection Commands
-
-This filter supports the following commands:
- at table @option
- at item cN
-Modify the @var{N}-th control value.
-
-If the specified value is not valid, it is ignored and prior one is kept.
- at end table
-
- at section lowpass
-
-Apply a low-pass filter with 3dB point frequency.
-The filter can be either single-pole or double-pole (the default).
-The filter roll off at 6dB per pole per octave (20dB per pole per decade).
-
-The filter accepts the following options:
-
- at table @option
- at item frequency, f
-Set frequency in Hz. Default is 500.
-
- at item poles, p
-Set number of poles. Default is 2.
-
- at item width_type
-Set method to specify band-width of filter.
- at table @option
- at item h
-Hz
- at item q
-Q-Factor
- at item o
-octave
- at item s
-slope
- at end table
-
- at item width, w
-Specify the band-width of a filter in width_type units.
-Applies only to double-pole filter.
-The default is 0.707q and gives a Butterworth response.
- at end table
-
- at anchor{pan}
- at section pan
-
-Mix channels with specific gain levels. The filter accepts the output
-channel layout followed by a set of channels definitions.
-
-This filter is also designed to efficiently remap the channels of an audio
-stream.
-
-The filter accepts parameters of the form:
-"@var{l}|@var{outdef}|@var{outdef}|..."
-
- at table @option
- at item l
-output channel layout or number of channels
-
- at item outdef
-output channel specification, of the form:
-"@var{out_name}=[@var{gain}*]@var{in_name}[+[@var{gain}*]@var{in_name}...]"
-
- at item out_name
-output channel to define, either a channel name (FL, FR, etc.) or a channel
-number (c0, c1, etc.)
-
- at item gain
-multiplicative coefficient for the channel, 1 leaving the volume unchanged
-
- at item in_name
-input channel to use, see out_name for details; it is not possible to mix
-named and numbered input channels
- at end table
-
-If the `=' in a channel specification is replaced by `<', then the gains for
-that specification will be renormalized so that the total is 1, thus
-avoiding clipping noise.
-
- at subsection Mixing examples
-
-For example, if you want to down-mix from stereo to mono, but with a bigger
-factor for the left channel:
- at example
-pan=1c|c0=0.9*c0+0.1*c1
- at end example
-
-A customized down-mix to stereo that works automatically for 3-, 4-, 5- and
-7-channels surround:
- at example
-pan=stereo| FL < FL + 0.5*FC + 0.6*BL + 0.6*SL | FR < FR + 0.5*FC + 0.6*BR + 0.6*SR
- at end example
-
-Note that @command{ffmpeg} integrates a default down-mix (and up-mix) system
-that should be preferred (see "-ac" option) unless you have very specific
-needs.
-
- at subsection Remapping examples
-
-The channel remapping will be effective if, and only if:
-
- at itemize
- at item gain coefficients are zeroes or ones,
- at item only one input per channel output,
- at end itemize
-
-If all these conditions are satisfied, the filter will notify the user ("Pure
-channel mapping detected"), and use an optimized and lossless method to do the
-remapping.
-
-For example, if you have a 5.1 source and want a stereo audio stream by
-dropping the extra channels:
- at example
-pan="stereo| c0=FL | c1=FR"
- at end example
-
-Given the same source, you can also switch front left and front right channels
-and keep the input channel layout:
- at example
-pan="5.1| c0=c1 | c1=c0 | c2=c2 | c3=c3 | c4=c4 | c5=c5"
- at end example
-
-If the input is a stereo audio stream, you can mute the front left channel (and
-still keep the stereo channel layout) with:
- at example
-pan="stereo|c1=c1"
- at end example
-
-Still with a stereo audio stream input, you can copy the right channel in both
-front left and right:
- at example
-pan="stereo| c0=FR | c1=FR"
- at end example
-
- at section replaygain
-
-ReplayGain scanner filter. This filter takes an audio stream as an input and
-outputs it unchanged.
-At end of filtering it displays @code{track_gain} and @code{track_peak}.
-
- at section resample
-
-Convert the audio sample format, sample rate and channel layout. It is
-not meant to be used directly.
-
- at section sidechaincompress
-
-This filter acts like normal compressor but has the ability to compress
-detected signal using second input signal.
-It needs two input streams and returns one output stream.
-First input stream will be processed depending on second stream signal.
-The filtered signal then can be filtered with other filters in later stages of
-processing. See @ref{pan} and @ref{amerge} filter.
-
-The filter accepts the following options:
-
- at table @option
- at item threshold
-If a signal of second stream raises above this level it will affect the gain
-reduction of first stream.
-By default is 0.125. Range is between 0.00097563 and 1.
-
- at item ratio
-Set a ratio about which the signal is reduced. 1:2 means that if the level
-raised 4dB above the threshold, it will be only 2dB above after the reduction.
-Default is 2. Range is between 1 and 20.
-
- at item attack
-Amount of milliseconds the signal has to rise above the threshold before gain
-reduction starts. Default is 20. Range is between 0.01 and 2000.
-
- at item release
-Amount of milliseconds the signal has to fall below the threshold before
-reduction is decreased again. Default is 250. Range is between 0.01 and 9000.
-
- at item makeup
-Set the amount by how much signal will be amplified after processing.
-Default is 2. Range is from 1 and 64.
-
- at item knee
-Curve the sharp knee around the threshold to enter gain reduction more softly.
-Default is 2.82843. Range is between 1 and 8.
-
- at item link
-Choose if the @code{average} level between all channels of side-chain stream
-or the louder(@code{maximum}) channel of side-chain stream affects the
-reduction. Default is @code{average}.
-
- at item detection
-Should the exact signal be taken in case of @code{peak} or an RMS one in case
-of @code{rms}. Default is @code{rms} which is mainly smoother.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Full ffmpeg example taking 2 audio inputs, 1st input to be compressed
-depending on the signal of 2nd input and later compressed signal to be
-merged with 2nd input:
- at example
-ffmpeg -i main.flac -i sidechain.flac -filter_complex "[1:a]asplit=2[sc][mix];[0:a][sc]sidechaincompress[compr];[compr][mix]amerge"
- at end example
- at end itemize
-
- at section silencedetect
-
-Detect silence in an audio stream.
-
-This filter logs a message when it detects that the input audio volume is less
-or equal to a noise tolerance value for a duration greater or equal to the
-minimum detected noise duration.
-
-The printed times and duration are expressed in seconds.
-
-The filter accepts the following options:
-
- at table @option
- at item duration, d
-Set silence duration until notification (default is 2 seconds).
-
- at item noise, n
-Set noise tolerance. Can be specified in dB (in case "dB" is appended to the
-specified value) or amplitude ratio. Default is -60dB, or 0.001.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Detect 5 seconds of silence with -50dB noise tolerance:
- at example
-silencedetect=n=-50dB:d=5
- at end example
-
- at item
-Complete example with @command{ffmpeg} to detect silence with 0.0001 noise
-tolerance in @file{silence.mp3}:
- at example
-ffmpeg -i silence.mp3 -af silencedetect=noise=0.0001 -f null -
- at end example
- at end itemize
-
- at section silenceremove
-
-Remove silence from the beginning, middle or end of the audio.
-
-The filter accepts the following options:
-
- at table @option
- at item start_periods
-This value is used to indicate if audio should be trimmed at beginning of
-the audio. A value of zero indicates no silence should be trimmed from the
-beginning. When specifying a non-zero value, it trims audio up until it
-finds non-silence. Normally, when trimming silence from beginning of audio
-the @var{start_periods} will be @code{1} but it can be increased to higher
-values to trim all audio up to specific count of non-silence periods.
-Default value is @code{0}.
-
- at item start_duration
-Specify the amount of time that non-silence must be detected before it stops
-trimming audio. By increasing the duration, bursts of noises can be treated
-as silence and trimmed off. Default value is @code{0}.
-
- at item start_threshold
-This indicates what sample value should be treated as silence. For digital
-audio, a value of @code{0} may be fine but for audio recorded from analog,
-you may wish to increase the value to account for background noise.
-Can be specified in dB (in case "dB" is appended to the specified value)
-or amplitude ratio. Default value is @code{0}.
-
- at item stop_periods
-Set the count for trimming silence from the end of audio.
-To remove silence from the middle of a file, specify a @var{stop_periods}
-that is negative. This value is then treated as a positive value and is
-used to indicate the effect should restart processing as specified by
- at var{start_periods}, making it suitable for removing periods of silence
-in the middle of the audio.
-Default value is @code{0}.
-
- at item stop_duration
-Specify a duration of silence that must exist before audio is not copied any
-more. By specifying a higher duration, silence that is wanted can be left in
-the audio.
-Default value is @code{0}.
-
- at item stop_threshold
-This is the same as @option{start_threshold} but for trimming silence from
-the end of audio.
-Can be specified in dB (in case "dB" is appended to the specified value)
-or amplitude ratio. Default value is @code{0}.
-
- at item leave_silence
-This indicate that @var{stop_duration} length of audio should be left intact
-at the beginning of each period of silence.
-For example, if you want to remove long pauses between words but do not want
-to remove the pauses completely. Default value is @code{0}.
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-The following example shows how this filter can be used to start a recording
-that does not contain the delay at the start which usually occurs between
-pressing the record button and the start of the performance:
- at example
-silenceremove=1:5:0.02
- at end example
- at end itemize
-
- at section treble
-
-Boost or cut treble (upper) frequencies of the audio using a two-pole
-shelving filter with a response similar to that of a standard
-hi-fi's tone-controls. This is also known as shelving equalisation (EQ).
-
-The filter accepts the following options:
-
- at table @option
- at item gain, g
-Give the gain at whichever is the lower of ~22 kHz and the
-Nyquist frequency. Its useful range is about -20 (for a large cut)
-to +20 (for a large boost). Beware of clipping when using a positive gain.
-
- at item frequency, f
-Set the filter's central frequency and so can be used
-to extend or reduce the frequency range to be boosted or cut.
-The default value is @code{3000} Hz.
-
- at item width_type
-Set method to specify band-width of filter.
- at table @option
- at item h
-Hz
- at item q
-Q-Factor
- at item o
-octave
- at item s
-slope
- at end table
-
- at item width, w
-Determine how steep is the filter's shelf transition.
- at end table
-
- at section volume
-
-Adjust the input audio volume.
-
-It accepts the following parameters:
- at table @option
-
- at item volume
-Set audio volume expression.
-
-Output values are clipped to the maximum value.
-
-The output audio volume is given by the relation:
- at example
- at var{output_volume} = @var{volume} * @var{input_volume}
- at end example
-
-The default value for @var{volume} is "1.0".
-
- at item precision
-This parameter represents the mathematical precision.
-
-It determines which input sample formats will be allowed, which affects the
-precision of the volume scaling.
-
- at table @option
- at item fixed
-8-bit fixed-point; this limits input sample format to U8, S16, and S32.
- at item float
-32-bit floating-point; this limits input sample format to FLT. (default)
- at item double
-64-bit floating-point; this limits input sample format to DBL.
- at end table
-
- at item replaygain
-Choose the behaviour on encountering ReplayGain side data in input frames.
-
- at table @option
- at item drop
-Remove ReplayGain side data, ignoring its contents (the default).
-
- at item ignore
-Ignore ReplayGain side data, but leave it in the frame.
-
- at item track
-Prefer the track gain, if present.
-
- at item album
-Prefer the album gain, if present.
- at end table
-
- at item replaygain_preamp
-Pre-amplification gain in dB to apply to the selected replaygain gain.
-
-Default value for @var{replaygain_preamp} is 0.0.
-
- at item eval
-Set when the volume expression is evaluated.
-
-It accepts the following values:
- at table @samp
- at item once
-only evaluate expression once during the filter initialization, or
-when the @samp{volume} command is sent
-
- at item frame
-evaluate expression for each incoming frame
- at end table
-
-Default value is @samp{once}.
- at end table
-
-The volume expression can contain the following parameters.
-
- at table @option
- at item n
-frame number (starting at zero)
- at item nb_channels
-number of channels
- at item nb_consumed_samples
-number of samples consumed by the filter
- at item nb_samples
-number of samples in the current frame
- at item pos
-original frame position in the file
- at item pts
-frame PTS
- at item sample_rate
-sample rate
- at item startpts
-PTS at start of stream
- at item startt
-time at start of stream
- at item t
-frame time
- at item tb
-timestamp timebase
- at item volume
-last set volume value
- at end table
-
-Note that when @option{eval} is set to @samp{once} only the
- at var{sample_rate} and @var{tb} variables are available, all other
-variables will evaluate to NAN.
-
- at subsection Commands
-
-This filter supports the following commands:
- at table @option
- at item volume
-Modify the volume expression.
-The command accepts the same syntax of the corresponding option.
-
-If the specified expression is not valid, it is kept at its current
-value.
- at item replaygain_noclip
-Prevent clipping by limiting the gain applied.
-
-Default value for @var{replaygain_noclip} is 1.
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Halve the input audio volume:
- at example
-volume=volume=0.5
-volume=volume=1/2
-volume=volume=-6.0206dB
- at end example
-
-In all the above example the named key for @option{volume} can be
-omitted, for example like in:
- at example
-volume=0.5
- at end example
-
- at item
-Increase input audio power by 6 decibels using fixed-point precision:
- at example
-volume=volume=6dB:precision=fixed
- at end example
-
- at item
-Fade volume after time 10 with an annihilation period of 5 seconds:
- at example
-volume='if(lt(t,10),1,max(1-(t-10)/5,0))':eval=frame
- at end example
- at end itemize
-
- at section volumedetect
-
-Detect the volume of the input video.
-
-The filter has no parameters. The input is not modified. Statistics about
-the volume will be printed in the log when the input stream end is reached.
-
-In particular it will show the mean volume (root mean square), maximum
-volume (on a per-sample basis), and the beginning of a histogram of the
-registered volume values (from the maximum value to a cumulated 1/1000 of
-the samples).
-
-All volumes are in decibels relative to the maximum PCM value.
-
- at subsection Examples
-
-Here is an excerpt of the output:
- at example
-[Parsed_volumedetect_0 @ 0xa23120] mean_volume: -27 dB
-[Parsed_volumedetect_0 @ 0xa23120] max_volume: -4 dB
-[Parsed_volumedetect_0 @ 0xa23120] histogram_4db: 6
-[Parsed_volumedetect_0 @ 0xa23120] histogram_5db: 62
-[Parsed_volumedetect_0 @ 0xa23120] histogram_6db: 286
-[Parsed_volumedetect_0 @ 0xa23120] histogram_7db: 1042
-[Parsed_volumedetect_0 @ 0xa23120] histogram_8db: 2551
-[Parsed_volumedetect_0 @ 0xa23120] histogram_9db: 4609
-[Parsed_volumedetect_0 @ 0xa23120] histogram_10db: 8409
- at end example
-
-It means that:
- at itemize
- at item
-The mean square energy is approximately -27 dB, or 10^-2.7.
- at item
-The largest sample is at -4 dB, or more precisely between -4 dB and -5 dB.
- at item
-There are 6 samples at -4 dB, 62 at -5 dB, 286 at -6 dB, etc.
- at end itemize
-
-In other words, raising the volume by +4 dB does not cause any clipping,
-raising it by +5 dB causes clipping for 6 samples, etc.
-
- at c man end AUDIO FILTERS
-
- at chapter Audio Sources
- at c man begin AUDIO SOURCES
-
-Below is a description of the currently available audio sources.
-
- at section abuffer
-
-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}.
-
-It accepts the following parameters:
- at table @option
-
- at item time_base
-The timebase which will be used for timestamps of submitted frames. It must be
-either a floating-point number or in @var{numerator}/@var{denominator} form.
-
- at item sample_rate
-The sample rate of the incoming audio buffers.
-
- at item sample_fmt
-The sample format of the incoming audio buffers.
-Either a sample format name or its corresponding integer representation from
-the enum AVSampleFormat in @file{libavutil/samplefmt.h}
-
- at item channel_layout
-The channel layout of the incoming audio buffers.
-Either a channel layout name from channel_layout_map in
- at file{libavutil/channel_layout.c} or its corresponding integer representation
-from the AV_CH_LAYOUT_* macros in @file{libavutil/channel_layout.h}
-
- at item channels
-The number of channels of the incoming audio buffers.
-If both @var{channels} and @var{channel_layout} are specified, then they
-must be consistent.
-
- at end table
-
- at subsection Examples
-
- at example
-abuffer=sample_rate=44100:sample_fmt=s16p:channel_layout=stereo
- at end example
-
-will instruct the source to accept planar 16bit signed stereo at 44100Hz.
-Since the sample format with name "s16p" corresponds to the number
-6 and the "stereo" channel layout corresponds to the value 0x3, this is
-equivalent to:
- at example
-abuffer=sample_rate=44100:sample_fmt=6:channel_layout=0x3
- at end example
-
- at section aevalsrc
-
-Generate an audio signal specified by an expression.
-
-This source accepts in input one or more expressions (one for each
-channel), which are evaluated and used to generate a corresponding
-audio signal.
-
-This source accepts the following options:
-
- at table @option
- at item exprs
-Set the '|'-separated expressions list for each separate channel. In case the
- at option{channel_layout} option is not specified, the selected channel layout
-depends on the number of provided expressions. Otherwise the last
-specified expression is applied to the remaining output channels.
-
- at item channel_layout, c
-Set the channel layout. The number of channels in the specified layout
-must be equal to the number of specified expressions.
-
- at item duration, d
-Set the minimum duration of the sourced audio. See
- at ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}
-for the accepted syntax.
-Note that the resulting duration may be greater than the specified
-duration, as the generated audio is always cut at the end of a
-complete frame.
-
-If not specified, or the expressed duration is negative, the audio is
-supposed to be generated forever.
-
- at item nb_samples, n
-Set the number of samples per channel per each output frame,
-default to 1024.
-
- at item sample_rate, s
-Specify the sample rate, default to 44100.
- at end table
-
-Each expression in @var{exprs} can contain the following constants:
-
- at table @option
- at item n
-number of the evaluated sample, starting from 0
-
- at item t
-time of the evaluated sample expressed in seconds, starting from 0
-
- at item s
-sample rate
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Generate silence:
- at example
-aevalsrc=0
- at end example
-
- at item
-Generate a sin signal with frequency of 440 Hz, set sample rate to
-8000 Hz:
- at example
-aevalsrc="sin(440*2*PI*t):s=8000"
- at end example
-
- at item
-Generate a two channels signal, specify the channel layout (Front
-Center + Back Center) explicitly:
- at example
-aevalsrc="sin(420*2*PI*t)|cos(430*2*PI*t):c=FC|BC"
- at end example
-
- at item
-Generate white noise:
- at example
-aevalsrc="-2+random(0)"
- at end example
-
- at item
-Generate an amplitude modulated signal:
- at example
-aevalsrc="sin(10*2*PI*t)*sin(880*2*PI*t)"
- at end example
-
- at item
-Generate 2.5 Hz binaural beats on a 360 Hz carrier:
- at example
-aevalsrc="0.1*sin(2*PI*(360-2.5/2)*t) | 0.1*sin(2*PI*(360+2.5/2)*t)"
- at end example
-
- at end itemize
-
- at section anullsrc
-
-The null audio source, return unprocessed audio frames. It is mainly useful
-as a template and to be employed in analysis / debugging tools, or as
-the source for filters which ignore the input data (for example the sox
-synth filter).
-
-This source accepts the following options:
-
- at table @option
-
- at item channel_layout, cl
-
-Specifies the channel layout, and can be either an integer or a string
-representing a channel layout. The default value of @var{channel_layout}
-is "stereo".
-
-Check the channel_layout_map definition in
- at file{libavutil/channel_layout.c} for the mapping between strings and
-channel layout values.
-
- at item sample_rate, r
-Specifies the sample rate, and defaults to 44100.
-
- at item nb_samples, n
-Set the number of samples per requested frames.
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Set the sample rate to 48000 Hz and the channel layout to AV_CH_LAYOUT_MONO.
- at example
-anullsrc=r=48000:cl=4
- at end example
-
- at item
-Do the same operation with a more obvious syntax:
- at example
-anullsrc=r=48000:cl=mono
- at end example
- at end itemize
-
-All the parameters need to be explicitly defined.
-
- at section flite
-
-Synthesize a voice utterance using the libflite library.
-
-To enable compilation of this filter you need to configure FFmpeg with
- at code{--enable-libflite}.
-
-Note that the flite library is not thread-safe.
-
-The filter accepts the following options:
-
- at table @option
-
- at item list_voices
-If set to 1, list the names of the available voices and exit
-immediately. Default value is 0.
-
- at item nb_samples, n
-Set the maximum number of samples per frame. Default value is 512.
-
- at item textfile
-Set the filename containing the text to speak.
-
- at item text
-Set the text to speak.
-
- at item voice, v
-Set the voice to use for the speech synthesis. Default value is
- at code{kal}. See also the @var{list_voices} option.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Read from file @file{speech.txt}, and synthesize the text using the
-standard flite voice:
- at example
-flite=textfile=speech.txt
- at end example
-
- at item
-Read the specified text selecting the @code{slt} voice:
- at example
-flite=text='So fare thee well, poor devil of a Sub-Sub, whose commentator I am':voice=slt
- at end example
-
- at item
-Input text to ffmpeg:
- at example
-ffmpeg -f lavfi -i flite=text='So fare thee well, poor devil of a Sub-Sub, whose commentator I am':voice=slt
- at end example
-
- at item
-Make @file{ffplay} speak the specified text, using @code{flite} and
-the @code{lavfi} device:
- at example
-ffplay -f lavfi flite=text='No more be grieved for which that thou hast done.'
- at end example
- at end itemize
-
-For more information about libflite, check:
- at url{http://www.speech.cs.cmu.edu/flite/}
-
- at section sine
-
-Generate an audio signal made of a sine wave with amplitude 1/8.
-
-The audio signal is bit-exact.
-
-The filter accepts the following options:
-
- at table @option
-
- at item frequency, f
-Set the carrier frequency. Default is 440 Hz.
-
- at item beep_factor, b
-Enable a periodic beep every second with frequency @var{beep_factor} times
-the carrier frequency. Default is 0, meaning the beep is disabled.
-
- at item sample_rate, r
-Specify the sample rate, default is 44100.
-
- at item duration, d
-Specify the duration of the generated audio stream.
-
- at item samples_per_frame
-Set the number of samples per output frame, default is 1024.
- at end table
-
- at subsection Examples
-
- at itemize
-
- at item
-Generate a simple 440 Hz sine wave:
- at example
-sine
- at end example
-
- at item
-Generate a 220 Hz sine wave with a 880 Hz beep each second, for 5 seconds:
- at example
-sine=220:4:d=5
-sine=f=220:b=4:d=5
-sine=frequency=220:beep_factor=4:duration=5
- at end example
-
- at end itemize
-
- at c man end AUDIO SOURCES
-
- at chapter Audio Sinks
- at c man begin AUDIO SINKS
-
-Below is a description of the currently available audio sinks.
-
- at section abuffersink
-
-Buffer audio frames, and make them available to the end of filter chain.
-
-This sink is mainly intended for programmatic use, in particular
-through the interface defined in @file{libavfilter/buffersink.h}
-or the options system.
-
-It accepts a pointer to an AVABufferSinkContext structure, which
-defines the incoming buffers' formats, to be passed as the opaque
-parameter to @code{avfilter_init_filter} for initialization.
- at section anullsink
-
-Null audio sink; do absolutely nothing with the input audio. It is
-mainly useful as a template and for use in analysis / debugging
-tools.
-
- at c man end AUDIO SINKS
-
- at chapter Video Filters
- at c man begin VIDEO FILTERS
-
-When you configure your FFmpeg build, you can disable any of the
-existing filters using @code{--disable-filters}.
-The configure output will show the video filters included in your
-build.
-
-Below is a description of the currently available video filters.
-
- at section alphaextract
-
-Extract the alpha component from the input as a grayscale video. This
-is especially useful with the @var{alphamerge} filter.
-
- at section alphamerge
-
-Add or replace the alpha component of the primary input with the
-grayscale value of a second input. This is intended for use with
- at var{alphaextract} to allow the transmission or storage of frame
-sequences that have alpha in a format that doesn't support an alpha
-channel.
-
-For example, to reconstruct full frames from a normal YUV-encoded video
-and a separate video created with @var{alphaextract}, you might use:
- at example
-movie=in_alpha.mkv [alpha]; [in][alpha] alphamerge [out]
- at 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.
-
- at section ass
-
-Same as the @ref{subtitles} filter, except that it doesn't require libavcodec
-and libavformat to work. On the other hand, it is limited to ASS (Advanced
-Substation Alpha) subtitles files.
-
-This filter accepts the following option in addition to the common options from
-the @ref{subtitles} filter:
-
- at table @option
- at item shaping
-Set the shaping engine
-
-Available values are:
- at table @samp
- at item auto
-The default libass shaping engine, which is the best available.
- at item simple
-Fast, font-agnostic shaper that can do only substitutions
- at item complex
-Slower shaper using OpenType for substitutions and positioning
- at end table
-
-The default is @code{auto}.
- at end table
-
- at section atadenoise
-Apply an Adaptive Temporal Averaging Denoiser to the video input.
-
-The filter accepts the following options:
-
- at table @option
- at item 0a
-Set threshold A for 1st plane. Default is 0.02.
-Valid range is 0 to 0.3.
-
- at item 0b
-Set threshold B for 1st plane. Default is 0.04.
-Valid range is 0 to 5.
-
- at item 1a
-Set threshold A for 2nd plane. Default is 0.02.
-Valid range is 0 to 0.3.
-
- at item 1b
-Set threshold B for 2nd plane. Default is 0.04.
-Valid range is 0 to 5.
-
- at item 2a
-Set threshold A for 3rd plane. Default is 0.02.
-Valid range is 0 to 0.3.
-
- at item 2b
-Set threshold B for 3rd plane. Default is 0.04.
-Valid range is 0 to 5.
-
-Threshold A is designed to react on abrupt changes in the input signal and
-threshold B is designed to react on continuous changes in the input signal.
-
- at item s
-Set number of frames filter will use for averaging. Default is 33. Must be odd
-number in range [5, 129].
- at end table
-
- at section bbox
-
-Compute the bounding box for the non-black pixels in the input frame
-luminance plane.
-
-This filter computes the bounding box containing all the pixels with a
-luminance value greater than the minimum allowed value.
-The parameters describing the bounding box are printed on the filter
-log.
-
-The filter accepts the following option:
-
- at table @option
- at item min_val
-Set the minimal luminance value. Default is @code{16}.
- at end table
-
- at section blackdetect
-
-Detect video intervals that are (almost) completely black. Can be
-useful to detect chapter transitions, commercials, or invalid
-recordings. Output lines contains the time for the start, end and
-duration of the detected black interval expressed in seconds.
-
-In order to display the output lines, you need to set the loglevel at
-least to the AV_LOG_INFO value.
-
-The filter accepts the following options:
-
- at table @option
- at item black_min_duration, d
-Set the minimum detected black duration expressed in seconds. It must
-be a non-negative floating point number.
-
-Default value is 2.0.
-
- at item picture_black_ratio_th, pic_th
-Set the threshold for considering a picture "black".
-Express the minimum value for the ratio:
- at example
- at var{nb_black_pixels} / @var{nb_pixels}
- at end example
-
-for which a picture is considered black.
-Default value is 0.98.
-
- at item pixel_black_th, pix_th
-Set the threshold for considering a pixel "black".
-
-The threshold expresses the maximum pixel luminance value for which a
-pixel is considered "black". The provided value is scaled according to
-the following equation:
- at example
- at var{absolute_threshold} = @var{luminance_minimum_value} + @var{pixel_black_th} * @var{luminance_range_size}
- at end example
-
- at var{luminance_range_size} and @var{luminance_minimum_value} depend on
-the input video format, the range is [0-255] for YUV full-range
-formats and [16-235] for YUV non full-range formats.
-
-Default value is 0.10.
- at end table
-
-The following example sets the maximum pixel threshold to the minimum
-value, and detects only black intervals of 2 or more seconds:
- at example
-blackdetect=d=2:pix_th=0.00
- at end example
-
- at section blackframe
-
-Detect frames that are (almost) completely black. Can be useful to
-detect chapter transitions or commercials. Output lines consist of
-the frame number of the detected frame, the percentage of blackness,
-the position in the file if known or -1 and the timestamp in seconds.
-
-In order to display the output lines, you need to set the loglevel at
-least to the AV_LOG_INFO value.
-
-It accepts the following parameters:
-
- at table @option
-
- at item amount
-The percentage of the pixels that have to be below the threshold; it defaults to
- at code{98}.
-
- at item threshold, thresh
-The threshold below which a pixel value is considered black; it defaults to
- at code{32}.
-
- at end table
-
- at section blend, tblend
-
-Blend two video frames into each other.
-
-The @code{blend} filter takes two input streams and outputs one
-stream, the first input is the "top" layer and second input is
-"bottom" layer. Output terminates when shortest input terminates.
-
-The @code{tblend} (time blend) filter takes two consecutive frames
-from one single stream, and outputs the result obtained by blending
-the new frame on top of the old frame.
-
-A description of the accepted options follows.
-
- at table @option
- at item c0_mode
- at item c1_mode
- at item c2_mode
- at item c3_mode
- at item all_mode
-Set blend mode for specific pixel component or all pixel components in case
-of @var{all_mode}. Default value is @code{normal}.
-
-Available values for component modes are:
- at table @samp
- at item addition
- at item and
- at item average
- at item burn
- at item darken
- at item difference
- at item difference128
- at item divide
- at item dodge
- at item exclusion
- at item glow
- at item hardlight
- at item hardmix
- at item lighten
- at item linearlight
- at item multiply
- at item negation
- at item normal
- at item or
- at item overlay
- at item phoenix
- at item pinlight
- at item reflect
- at item screen
- at item softlight
- at item subtract
- at item vividlight
- at item xor
- at end table
-
- at item c0_opacity
- at item c1_opacity
- at item c2_opacity
- at item c3_opacity
- at item all_opacity
-Set blend opacity for specific pixel component or all pixel components in case
-of @var{all_opacity}. Only used in combination with pixel component blend modes.
-
- at item c0_expr
- at item c1_expr
- at item c2_expr
- at item c3_expr
- at item all_expr
-Set blend expression for specific pixel component or all pixel components in case
-of @var{all_expr}. Note that related mode options will be ignored if those are set.
-
-The expressions can use the following variables:
-
- at table @option
- at item N
-The sequential number of the filtered frame, starting from @code{0}.
-
- at item X
- at item Y
-the coordinates of the current sample
-
- at item W
- at item H
-the width and height of currently filtered plane
-
- at item SW
- at item SH
-Width and height scale depending on the currently filtered plane. It is the
-ratio between the corresponding luma plane number of pixels and the current
-plane ones. E.g. for YUV4:2:0 the values are @code{1,1} for the luma plane, and
- at code{0.5,0.5} for chroma planes.
-
- at item T
-Time of the current frame, expressed in seconds.
-
- at item TOP, A
-Value of pixel component at current location for first video frame (top layer).
-
- at item BOTTOM, B
-Value of pixel component at current location for second video frame (bottom layer).
- at end table
-
- at item shortest
-Force termination when the shortest input terminates. Default is
- at code{0}. This option is only defined for the @code{blend} filter.
-
- at item repeatlast
-Continue applying the last bottom frame after the end of the stream. A value of
- at code{0} disable the filter after the last frame of the bottom layer is reached.
-Default is @code{1}. This option is only defined for the @code{blend} filter.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Apply transition from bottom layer to top layer in first 10 seconds:
- at example
-blend=all_expr='A*(if(gte(T,10),1,T/10))+B*(1-(if(gte(T,10),1,T/10)))'
- at end example
-
- at item
-Apply 1x1 checkerboard effect:
- at example
-blend=all_expr='if(eq(mod(X,2),mod(Y,2)),A,B)'
- at end example
-
- at item
-Apply uncover left effect:
- at example
-blend=all_expr='if(gte(N*SW+X,W),A,B)'
- at end example
-
- at item
-Apply uncover down effect:
- at example
-blend=all_expr='if(gte(Y-N*SH,0),A,B)'
- at end example
-
- at item
-Apply uncover up-left effect:
- at example
-blend=all_expr='if(gte(T*SH*40+Y,H)*gte((T*40*SW+X)*W/H,W),A,B)'
- at end example
-
- at item
-Display differences between the current and the previous frame:
- at example
-tblend=all_mode=difference128
- at end example
- at end itemize
-
- at section boxblur
-
-Apply a boxblur algorithm to the input video.
-
-It accepts the following parameters:
-
- at table @option
-
- at item luma_radius, lr
- at item luma_power, lp
- at item chroma_radius, cr
- at item chroma_power, cp
- at item alpha_radius, ar
- at item alpha_power, ap
-
- at end table
-
-A description of the accepted options follows.
-
- at table @option
- at item luma_radius, lr
- at item chroma_radius, cr
- at item alpha_radius, ar
-Set an expression for the box radius in pixels used for blurring the
-corresponding input plane.
-
-The radius value must be a non-negative number, and must not be
-greater than the value of the expression @code{min(w,h)/2} for the
-luma and alpha planes, and of @code{min(cw,ch)/2} for the chroma
-planes.
-
-Default value for @option{luma_radius} is "2". If not specified,
- at option{chroma_radius} and @option{alpha_radius} default to the
-corresponding value set for @option{luma_radius}.
-
-The expressions can contain the following constants:
- at table @option
- at item w
- at item h
-The input width and height in pixels.
-
- at item cw
- at item ch
-The input chroma image width and height in pixels.
-
- at item hsub
- at item vsub
-The horizontal and vertical chroma subsample values. For example, for the
-pixel format "yuv422p", @var{hsub} is 2 and @var{vsub} is 1.
- at end table
-
- at item luma_power, lp
- at item chroma_power, cp
- at item alpha_power, ap
-Specify how many times the boxblur filter is applied to the
-corresponding plane.
-
-Default value for @option{luma_power} is 2. If not specified,
- at option{chroma_power} and @option{alpha_power} default to the
-corresponding value set for @option{luma_power}.
-
-A value of 0 will disable the effect.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Apply a boxblur filter with the luma, chroma, and alpha radii
-set to 2:
- at example
-boxblur=luma_radius=2:luma_power=1
-boxblur=2:1
- at end example
-
- at item
-Set the luma radius to 2, and alpha and chroma radius to 0:
- at example
-boxblur=2:1:cr=0:ar=0
- at end example
-
- at item
-Set the luma and chroma radii to a fraction of the video dimension:
- at example
-boxblur=luma_radius=min(h\,w)/10:luma_power=1:chroma_radius=min(cw\,ch)/10:chroma_power=1
- at end example
- at end itemize
-
- at section codecview
-
-Visualize information exported by some codecs.
-
-Some codecs can export information through frames using side-data or other
-means. For example, some MPEG based codecs export motion vectors through the
- at var{export_mvs} flag in the codec @option{flags2} option.
-
-The filter accepts the following option:
-
- at table @option
- at item mv
-Set motion vectors to visualize.
-
-Available flags for @var{mv} are:
-
- at table @samp
- at item pf
-forward predicted MVs of P-frames
- at item bf
-forward predicted MVs of B-frames
- at item bb
-backward predicted MVs of B-frames
- at end table
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Visualizes multi-directionals MVs from P and B-Frames using @command{ffplay}:
- at example
-ffplay -flags2 +export_mvs input.mpg -vf codecview=mv=pf+bf+bb
- at end example
- at end itemize
-
- at section colorbalance
-Modify intensity of primary colors (red, green and blue) of input frames.
-
-The filter allows an input frame to be adjusted in the shadows, midtones or highlights
-regions for the red-cyan, green-magenta or blue-yellow balance.
-
-A positive adjustment value shifts the balance towards the primary color, a negative
-value towards the complementary color.
-
-The filter accepts the following options:
-
- at table @option
- at item rs
- at item gs
- at item bs
-Adjust red, green and blue shadows (darkest pixels).
-
- at item rm
- at item gm
- at item bm
-Adjust red, green and blue midtones (medium pixels).
-
- at item rh
- at item gh
- at item bh
-Adjust red, green and blue highlights (brightest pixels).
-
-Allowed ranges for options are @code{[-1.0, 1.0]}. Defaults are @code{0}.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Add red color cast to shadows:
- at example
-colorbalance=rs=.3
- at end example
- at end itemize
-
- at section colorkey
-RGB colorspace color keying.
-
-The filter accepts the following options:
-
- at table @option
- at item color
-The color which will be replaced with transparency.
-
- at item similarity
-Similarity percentage with the key color.
-
-0.01 matches only the exact key color, while 1.0 matches everything.
-
- at item blend
-Blend percentage.
-
-0.0 makes pixels either fully transparent, or not transparent at all.
-
-Higher values result in semi-transparent pixels, with a higher transparency
-the more similar the pixels color is to the key color.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Make every green pixel in the input image transparent:
- at example
-ffmpeg -i input.png -vf colorkey=green out.png
- at end example
-
- at item
-Overlay a greenscreen-video on top of a static background image.
- at example
-ffmpeg -i background.png -i video.mp4 -filter_complex "[1:v]colorkey=0x3BBD1E:0.3:0.2[ckout];[0:v][ckout]overlay[out]" -map "[out]" output.flv
- at end example
- at end itemize
-
- at section colorlevels
-
-Adjust video input frames using levels.
-
-The filter accepts the following options:
-
- at table @option
- at item rimin
- at item gimin
- at item bimin
- at item aimin
-Adjust red, green, blue and alpha input black point.
-Allowed ranges for options are @code{[-1.0, 1.0]}. Defaults are @code{0}.
-
- at item rimax
- at item gimax
- at item bimax
- at item aimax
-Adjust red, green, blue and alpha input white point.
-Allowed ranges for options are @code{[-1.0, 1.0]}. Defaults are @code{1}.
-
-Input levels are used to lighten highlights (bright tones), darken shadows
-(dark tones), change the balance of bright and dark tones.
-
- at item romin
- at item gomin
- at item bomin
- at item aomin
-Adjust red, green, blue and alpha output black point.
-Allowed ranges for options are @code{[0, 1.0]}. Defaults are @code{0}.
-
- at item romax
- at item gomax
- at item bomax
- at item aomax
-Adjust red, green, blue and alpha output white point.
-Allowed ranges for options are @code{[0, 1.0]}. Defaults are @code{1}.
-
-Output levels allows manual selection of a constrained output level range.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Make video output darker:
- at example
-colorlevels=rimin=0.058:gimin=0.058:bimin=0.058
- at end example
-
- at item
-Increase contrast:
- at example
-colorlevels=rimin=0.039:gimin=0.039:bimin=0.039:rimax=0.96:gimax=0.96:bimax=0.96
- at end example
-
- at item
-Make video output lighter:
- at example
-colorlevels=rimax=0.902:gimax=0.902:bimax=0.902
- at end example
-
- at item
-Increase brightness:
- at example
-colorlevels=romin=0.5:gomin=0.5:bomin=0.5
- at end example
- at end itemize
-
- at section colorchannelmixer
-
-Adjust video input frames by re-mixing color channels.
-
-This filter modifies a color channel by adding the values associated to
-the other channels of the same pixels. For example if the value to
-modify is red, the output value will be:
- at example
- at var{red}=@var{red}*@var{rr} + @var{blue}*@var{rb} + @var{green}*@var{rg} + @var{alpha}*@var{ra}
- at end example
-
-The filter accepts the following options:
-
- at table @option
- at item rr
- at item rg
- at item rb
- at item ra
-Adjust contribution of input red, green, blue and alpha channels for output red channel.
-Default is @code{1} for @var{rr}, and @code{0} for @var{rg}, @var{rb} and @var{ra}.
-
- at item gr
- at item gg
- at item gb
- at item ga
-Adjust contribution of input red, green, blue and alpha channels for output green channel.
-Default is @code{1} for @var{gg}, and @code{0} for @var{gr}, @var{gb} and @var{ga}.
-
- at item br
- at item bg
- at item bb
- at item ba
-Adjust contribution of input red, green, blue and alpha channels for output blue channel.
-Default is @code{1} for @var{bb}, and @code{0} for @var{br}, @var{bg} and @var{ba}.
-
- at item ar
- at item ag
- at item ab
- at item aa
-Adjust contribution of input red, green, blue and alpha channels for output alpha channel.
-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]}.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Convert source to grayscale:
- at example
-colorchannelmixer=.3:.4:.3:0:.3:.4:.3:0:.3:.4:.3
- at end example
- at item
-Simulate sepia tones:
- at example
-colorchannelmixer=.393:.769:.189:0:.349:.686:.168:0:.272:.534:.131
- at end example
- at end itemize
-
- at section colormatrix
-
-Convert color matrix.
-
-The filter accepts the following options:
-
- at table @option
- at item src
- at item dst
-Specify the source and destination color matrix. Both values must be
-specified.
-
-The accepted values are:
- at table @samp
- at item bt709
-BT.709
-
- at item bt601
-BT.601
-
- at item smpte240m
-SMPTE-240M
-
- at item fcc
-FCC
- at end table
- at end table
-
-For example to convert from BT.601 to SMPTE-240M, use the command:
- at example
-colormatrix=bt601:smpte240m
- at end example
-
- at section copy
-
-Copy the input source unchanged to the output. This is mainly useful for
-testing purposes.
-
- at section crop
-
-Crop the input video to given dimensions.
-
-It accepts the following parameters:
-
- at table @option
- at item w, out_w
-The width of the output video. It defaults to @code{iw}.
-This expression is evaluated only once during the filter
-configuration, or when the @samp{w} or @samp{out_w} command is sent.
-
- at item h, out_h
-The height of the output video. It defaults to @code{ih}.
-This expression is evaluated only once during the filter
-configuration, or when the @samp{h} or @samp{out_h} command is sent.
-
- at item x
-The horizontal position, in the input video, of the left edge of the output
-video. It defaults to @code{(in_w-out_w)/2}.
-This expression is evaluated per-frame.
-
- at item y
-The vertical position, in the input video, of the top edge of the output video.
-It defaults to @code{(in_h-out_h)/2}.
-This expression is evaluated per-frame.
-
- at item keep_aspect
-If set to 1 will force the output display aspect ratio
-to be the same of the input, by changing the output sample aspect
-ratio. It defaults to 0.
- at end table
-
-The @var{out_w}, @var{out_h}, @var{x}, @var{y} parameters are
-expressions containing the following constants:
-
- at table @option
- at item x
- at item y
-The computed values for @var{x} and @var{y}. They are evaluated for
-each new frame.
-
- at item in_w
- at item in_h
-The input width and height.
-
- at item iw
- at item ih
-These are the same as @var{in_w} and @var{in_h}.
-
- at item out_w
- at item out_h
-The output (cropped) width and height.
-
- at item ow
- at item oh
-These are the same as @var{out_w} and @var{out_h}.
-
- at item a
-same as @var{iw} / @var{ih}
-
- at item sar
-input sample aspect ratio
-
- at item dar
-input display aspect ratio, it is the same as (@var{iw} / @var{ih}) * @var{sar}
-
- at item hsub
- at item vsub
-horizontal and vertical chroma subsample values. For example for the
-pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
-
- at item n
-The number of the input frame, starting from 0.
-
- at item pos
-the position in the file of the input frame, NAN if unknown
-
- at item t
-The timestamp expressed in seconds. It's NAN if the input timestamp is unknown.
-
- at end table
-
-The expression for @var{out_w} may depend on the value of @var{out_h},
-and the expression for @var{out_h} may depend on @var{out_w}, but they
-cannot depend on @var{x} and @var{y}, as @var{x} and @var{y} are
-evaluated after @var{out_w} and @var{out_h}.
-
-The @var{x} and @var{y} parameters specify the expressions for the
-position of the top-left corner of the output (non-cropped) area. They
-are evaluated for each frame. If the evaluated value is not valid, it
-is approximated to the nearest valid value.
-
-The expression for @var{x} may depend on @var{y}, and the expression
-for @var{y} may depend on @var{x}.
-
- at subsection Examples
-
- at itemize
- at item
-Crop area with size 100x100 at position (12,34).
- at example
-crop=100:100:12:34
- at end example
-
-Using named options, the example above becomes:
- at example
-crop=w=100:h=100:x=12:y=34
- at end example
-
- at item
-Crop the central input area with size 100x100:
- at example
-crop=100:100
- at end example
-
- at item
-Crop the central input area with size 2/3 of the input video:
- at example
-crop=2/3*in_w:2/3*in_h
- at end example
-
- at item
-Crop the input video central square:
- at example
-crop=out_w=in_h
-crop=in_h
- at end example
-
- at item
-Delimit the rectangle with the top-left corner placed at position
-100:100 and the right-bottom corner corresponding to the right-bottom
-corner of the input image.
- at example
-crop=in_w-100:in_h-100:100:100
- at end example
-
- at item
-Crop 10 pixels from the left and right borders, and 20 pixels from
-the top and bottom borders
- at example
-crop=in_w-2*10:in_h-2*20
- at end example
-
- at item
-Keep only the bottom right quarter of the input image:
- at example
-crop=in_w/2:in_h/2:in_w/2:in_h/2
- at end example
-
- at item
-Crop height for getting Greek harmony:
- at example
-crop=in_w:1/PHI*in_w
- at end example
-
- at item
-Apply trembling effect:
- at example
-crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(n/10):(in_h-out_h)/2 +((in_h-out_h)/2)*sin(n/7)
- at end example
-
- at item
-Apply erratic camera effect depending on timestamp:
- at example
-crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(t*10):(in_h-out_h)/2 +((in_h-out_h)/2)*sin(t*13)"
- at end example
-
- at item
-Set x depending on the value of y:
- at example
-crop=in_w/2:in_h/2:y:10+10*sin(n/10)
- at end example
- at end itemize
-
- at subsection Commands
-
-This filter supports the following commands:
- at table @option
- at item w, out_w
- at item h, out_h
- at item x
- at item y
-Set width/height of the output video and the horizontal/vertical position
-in the input video.
-The command accepts the same syntax of the corresponding option.
-
-If the specified expression is not valid, it is kept at its current
-value.
- at end table
-
- at section cropdetect
-
-Auto-detect the crop size.
-
-It calculates the necessary cropping parameters and prints the
-recommended parameters via the logging system. The detected dimensions
-correspond to the non-black area of the input video.
-
-It accepts the following parameters:
-
- at table @option
-
- at item limit
-Set higher black value threshold, which can be optionally specified
-from nothing (0) to everything (255 for 8bit based formats). An intensity
-value greater to the set value is considered non-black. It defaults to 24.
-You can also specify a value between 0.0 and 1.0 which will be scaled depending
-on the bitdepth of the pixel format.
-
- at item round
-The value which the width/height should be divisible by. It defaults to
-16. The offset is automatically adjusted to center the video. Use 2 to
-get only even dimensions (needed for 4:2:2 video). 16 is best when
-encoding to most video codecs.
-
- at 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
-detect the current optimal crop area. Default value is 0.
-
-This can be useful when channel logos distort the video area. 0
-indicates 'never reset', and returns the largest area encountered during
-playback.
- at end table
-
- at anchor{curves}
- at section curves
-
-Apply color adjustments using curves.
-
-This filter is similar to the Adobe Photoshop and GIMP curves tools. Each
-component (red, green and blue) has its values defined by @var{N} key points
-tied from each other using a smooth curve. The x-axis represents the pixel
-values from the input frame, and the y-axis the new pixel values to be set for
-the output frame.
-
-By default, a component curve is defined by the two points @var{(0;0)} and
- at var{(1;1)}. This creates a straight line where each original pixel value is
-"adjusted" to its own value, which means no change to the image.
-
-The filter allows you to redefine these two points and add some more. A new
-curve (using a natural cubic spline interpolation) will be define to pass
-smoothly through all these new coordinates. The new defined points needs to be
-strictly increasing over the x-axis, and their @var{x} and @var{y} values must
-be in the @var{[0;1]} interval. If the computed curves happened to go outside
-the vector spaces, the values will be clipped accordingly.
-
-If there is no key point defined in @code{x=0}, the filter will automatically
-insert a @var{(0;0)} point. In the same way, if there is no key point defined
-in @code{x=1}, the filter will automatically insert a @var{(1;1)} point.
-
-The filter accepts the following options:
-
- at table @option
- at item preset
-Select one of the available color presets. This option can be used in addition
-to the @option{r}, @option{g}, @option{b} parameters; in this case, the later
-options takes priority on the preset values.
-Available presets are:
- at table @samp
- at item none
- at item color_negative
- at item cross_process
- at item darker
- at item increase_contrast
- at item lighter
- at item linear_contrast
- at item medium_contrast
- at item negative
- at item strong_contrast
- at item vintage
- at end table
-Default is @code{none}.
- at item master, m
-Set the master key points. These points will define a second pass mapping. It
-is sometimes called a "luminance" or "value" mapping. It can be used with
- at option{r}, @option{g}, @option{b} or @option{all} since it acts like a
-post-processing LUT.
- at item red, r
-Set the key points for the red component.
- at item green, g
-Set the key points for the green component.
- at item blue, b
-Set the key points for the blue component.
- at item all
-Set the key points for all components (not including master).
-Can be used in addition to the other key points component
-options. In this case, the unset component(s) will fallback on this
- at option{all} setting.
- at item psfile
-Specify a Photoshop curves file (@code{.asv}) to import the settings from.
- at end table
-
-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 ...}.
-
- at subsection Examples
-
- at itemize
- at item
-Increase slightly the middle level of blue:
- at example
-curves=blue='0.5/0.58'
- at end example
-
- at item
-Vintage effect:
- at example
-curves=r='0/0.11 .42/.51 1/0.95':g='0.50/0.48':b='0/0.22 .49/.44 1/0.8'
- at end example
-Here we obtain the following coordinates for each components:
- at table @var
- at item red
- at code{(0;0.11) (0.42;0.51) (1;0.95)}
- at item green
- at code{(0;0) (0.50;0.48) (1;1)}
- at item blue
- at code{(0;0.22) (0.49;0.44) (1;0.80)}
- at end table
-
- at item
-The previous example can also be achieved with the associated built-in preset:
- at example
-curves=preset=vintage
- at end example
-
- at item
-Or simply:
- at example
-curves=vintage
- at end example
-
- at item
-Use a Photoshop preset and redefine the points of the green component:
- at example
-curves=psfile='MyCurvesPresets/purple.asv':green='0.45/0.53'
- at end example
- at end itemize
-
- at section dctdnoiz
-
-Denoise frames using 2D DCT (frequency domain filtering).
-
-This filter is not designed for real time.
-
-The filter accepts the following options:
-
- at table @option
- at item sigma, s
-Set the noise sigma constant.
-
-This @var{sigma} defines a hard threshold of @code{3 * sigma}; every DCT
-coefficient (absolute value) below this threshold with be dropped.
-
-If you need a more advanced filtering, see @option{expr}.
-
-Default is @code{0}.
-
- at item overlap
-Set number overlapping pixels for each block. Since the filter can be slow, you
-may want to reduce this value, at the cost of a less effective filter and the
-risk of various artefacts.
-
-If the overlapping value doesn't permit processing the whole input width or
-height, a warning will be displayed and according borders won't be denoised.
-
-Default value is @var{blocksize}-1, which is the best possible setting.
-
- at item expr, e
-Set the coefficient factor expression.
-
-For each coefficient of a DCT block, this expression will be evaluated as a
-multiplier value for the coefficient.
-
-If this is option is set, the @option{sigma} option will be ignored.
-
-The absolute value of the coefficient can be accessed through the @var{c}
-variable.
-
- at item n
-Set the @var{blocksize} using the number of bits. @code{1<<@var{n}} defines the
- at var{blocksize}, which is the width and height of the processed blocks.
-
-The default value is @var{3} (8x8) and can be raised to @var{4} for a
- at var{blocksize} of 16x16. Note that changing this setting has huge consequences
-on the speed processing. Also, a larger block size does not necessarily means a
-better de-noising.
- at end table
-
- at subsection Examples
-
-Apply a denoise with a @option{sigma} of @code{4.5}:
- at example
-dctdnoiz=4.5
- at end example
-
-The same operation can be achieved using the expression system:
- at example
-dctdnoiz=e='gte(c, 4.5*3)'
- at end example
-
-Violent denoise using a block size of @code{16x16}:
- at example
-dctdnoiz=15:n=4
- at end example
-
- at section deband
-
-Remove banding artifacts from input video.
-It works by replacing banded pixels with average value of referenced pixels.
-
-The filter accepts the following options:
-
- at table @option
- at item 1thr
- at item 2thr
- at item 3thr
- at item 4thr
-Set banding detection threshold for each plane. Default is 0.02.
-Valid range is 0.00003 to 0.5.
-If difference between current pixel and reference pixel is less than threshold,
-it will be considered as banded.
-
- at item range, r
-Banding detection range in pixels. Default is 16. If positive, random number
-in range 0 to set value will be used. If negative, exact absolute value
-will be used.
-The range defines square of four pixels around current pixel.
-
- at item direction, d
-Set direction in radians from which four pixel will be compared. If positive,
-random direction from 0 to set direction will be picked. If negative, exact of
-absolute value will be picked. For example direction 0, -PI or -2*PI radians
-will pick only pixels on same row and -PI/2 will pick only pixels on same
-column.
-
- at item blur
-If enabled, current pixel is compared with average value of all four
-surrounding pixels. The default is enabled. If disabled current pixel is
-compared with all four surrounding pixels. The pixel is considered banded
-if only all four differences with surrounding pixels are less than threshold.
- at end table
-
- at anchor{decimate}
- at section decimate
-
-Drop duplicated frames at regular intervals.
-
-The filter accepts the following options:
-
- at table @option
- at item cycle
-Set the number of frames from which one will be dropped. Setting this to
- at var{N} means one frame in every batch of @var{N} frames will be dropped.
-Default is @code{5}.
-
- at item dupthresh
-Set the threshold for duplicate detection. If the difference metric for a frame
-is less than or equal to this value, then it is declared as duplicate. Default
-is @code{1.1}
-
- at item scthresh
-Set scene change threshold. Default is @code{15}.
-
- at item blockx
- at item blocky
-Set the size of the x and y-axis blocks used during metric calculations.
-Larger blocks give better noise suppression, but also give worse detection of
-small movements. Must be a power of two. Default is @code{32}.
-
- at item ppsrc
-Mark main input as a pre-processed input and activate clean source input
-stream. This allows the input to be pre-processed with various filters to help
-the metrics calculation while keeping the frame selection lossless. When set to
- at code{1}, the first stream is for the pre-processed input, and the second
-stream is the clean source from where the kept frames are chosen. Default is
- at code{0}.
-
- at item chroma
-Set whether or not chroma is considered in the metric calculations. Default is
- at code{1}.
- at end table
-
- at section deflate
-
-Apply deflate effect to the video.
-
-This filter replaces the pixel by the local(3x3) average by taking into account
-only values lower than the pixel.
-
-It accepts the following options:
-
- at table @option
- at item threshold0
- at item threshold1
- at item threshold2
- at item threshold3
-Limit the maximum change for each plane, default is 65535.
-If 0, plane will remain unchanged.
- at end table
-
- at section dejudder
-
-Remove judder produced by partially interlaced telecined content.
-
-Judder can be introduced, for instance, by @ref{pullup} filter. If the original
-source was partially telecined content then the output of @code{pullup,dejudder}
-will have a variable frame rate. May change the recorded frame rate of the
-container. Aside from that change, this filter will not affect constant frame
-rate video.
-
-The option available in this filter is:
- at table @option
-
- at item cycle
-Specify the length of the window over which the judder repeats.
-
-Accepts any integer greater than 1. Useful values are:
- at table @samp
-
- at item 4
-If the original was telecined from 24 to 30 fps (Film to NTSC).
-
- at item 5
-If the original was telecined from 25 to 30 fps (PAL to NTSC).
-
- at item 20
-If a mixture of the two.
- at end table
-
-The default is @samp{4}.
- at end table
-
- at section delogo
-
-Suppress a TV station logo by a simple interpolation of the surrounding
-pixels. Just set a rectangle covering the logo and watch it disappear
-(and sometimes something even uglier appear - your mileage may vary).
-
-It accepts the following parameters:
- at table @option
-
- at item x
- at item y
-Specify the top left corner coordinates of the logo. They must be
-specified.
-
- at item w
- at item h
-Specify the width and height of the logo to clear. They must be
-specified.
-
- at item band, t
-Specify the thickness of the fuzzy edge of the rectangle (added to
- at var{w} and @var{h}). The default value is 4.
-
- at 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.
-The default value is 0.
-
-The rectangle is drawn on the outermost pixels which will be (partly)
-replaced with interpolated values. The values of the next pixels
-immediately outside this rectangle in each direction will be used to
-compute the interpolated pixel values inside the rectangle.
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Set a rectangle covering the area with top left corner coordinates 0,0
-and size 100x77, and a band of size 10:
- at example
-delogo=x=0:y=0:w=100:h=77:band=10
- at end example
-
- at end itemize
-
- at section deshake
-
-Attempt to fix small changes in horizontal and/or vertical shift. This
-filter helps remove camera shake from hand-holding a camera, bumping a
-tripod, moving on a vehicle, etc.
-
-The filter accepts the following options:
-
- at table @option
-
- at item x
- at item y
- at item w
- at item h
-Specify a rectangular area where to limit the search for motion
-vectors.
-If desired the search for motion vectors can be limited to a
-rectangular area of the frame defined by its top left corner, width
-and height. These parameters have the same meaning as the drawbox
-filter which can be used to visualise the position of the bounding
-box.
-
-This is useful when simultaneous movement of subjects within the frame
-might be confused for camera motion by the motion vector search.
-
-If any or all of @var{x}, @var{y}, @var{w} and @var{h} are set to -1
-then the full frame is used. This allows later options to be set
-without specifying the bounding box for the motion vector search.
-
-Default - search the whole frame.
-
- at item rx
- at item ry
-Specify the maximum extent of movement in x and y directions in the
-range 0-64 pixels. Default 16.
-
- at item edge
-Specify how to generate pixels to fill blanks at the edge of the
-frame. Available values are:
- at table @samp
- at item blank, 0
-Fill zeroes at blank locations
- at item original, 1
-Original image at blank locations
- at item clamp, 2
-Extruded edge value at blank locations
- at item mirror, 3
-Mirrored edge at blank locations
- at end table
-Default value is @samp{mirror}.
-
- at item blocksize
-Specify the blocksize to use for motion search. Range 4-128 pixels,
-default 8.
-
- at item contrast
-Specify the contrast threshold for blocks. Only blocks with more than
-the specified contrast (difference between darkest and lightest
-pixels) will be considered. Range 1-255, default 125.
-
- at item search
-Specify the search strategy. Available values are:
- at table @samp
- at item exhaustive, 0
-Set exhaustive search
- at item less, 1
-Set less exhaustive search.
- at end table
-Default value is @samp{exhaustive}.
-
- at item filename
-If set then a detailed log of the motion search is written to the
-specified file.
-
- at item opencl
-If set to 1, specify using OpenCL capabilities, only available if
-FFmpeg was configured with @code{--enable-opencl}. Default value is 0.
-
- at end table
-
- at section detelecine
-
-Apply an exact inverse of the telecine operation. It requires a predefined
-pattern specified using the pattern option which must be the same as that passed
-to the telecine filter.
-
-This filter accepts the following options:
-
- at table @option
- at item first_field
- at table @samp
- at item top, t
-top field first
- at item bottom, b
-bottom field first
-The default value is @code{top}.
- at end table
-
- at item pattern
-A string of numbers representing the pulldown pattern you wish to apply.
-The default value is @code{23}.
-
- at item start_frame
-A number representing position of the first frame with respect to the telecine
-pattern. This is to be used if the stream is cut. The default value is @code{0}.
- at end table
-
- at section dilation
-
-Apply dilation effect to the video.
-
-This filter replaces the pixel by the local(3x3) maximum.
-
-It accepts the following options:
-
- at table @option
- at item threshold0
- at item threshold1
- at item threshold2
- at item threshold3
-Limit the maximum change for each plane, default is 65535.
-If 0, plane will remain unchanged.
-
- at item coordinates
-Flag which specifies the pixel to refer to. Default is 255 i.e. all eight
-pixels are used.
-
-Flags to local 3x3 coordinates maps like this:
-
- 1 2 3
- 4 5
- 6 7 8
- at end table
-
- at section drawbox
-
-Draw a colored box on the input image.
-
-It accepts the following parameters:
-
- at table @option
- at item x
- at item y
-The expressions which specify the top left corner coordinates of the box. It defaults to 0.
-
- at item width, w
- at item height, h
-The expressions which specify the width and height of the box; if 0 they are interpreted as
-the input width and height. It defaults to 0.
-
- at item color, c
-Specify the color of the box to write. For the general syntax of this option,
-check the "Color" section in the ffmpeg-utils manual. If the special
-value @code{invert} is used, the box edge color is the same as the
-video with inverted luma.
-
- at item thickness, t
-The expression which sets the thickness of the box edge. Default value is @code{3}.
-
-See below for the list of accepted constants.
- at end table
-
-The parameters for @var{x}, @var{y}, @var{w} and @var{h} and @var{t} are expressions containing the
-following constants:
-
- at table @option
- at item dar
-The input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar}.
-
- at item hsub
- at item vsub
-horizontal and vertical chroma subsample values. For example for the
-pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
-
- at item in_h, ih
- at item in_w, iw
-The input width and height.
-
- at item sar
-The input sample aspect ratio.
-
- at item x
- at item y
-The x and y offset coordinates where the box is drawn.
-
- at item w
- at item h
-The width and height of the drawn box.
-
- at item t
-The thickness of the drawn box.
-
-These constants allow the @var{x}, @var{y}, @var{w}, @var{h} and @var{t} expressions to refer to
-each other, so you may for example specify @code{y=x/dar} or @code{h=w/dar}.
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Draw a black box around the edge of the input image:
- at example
-drawbox
- at end example
-
- at item
-Draw a box with color red and an opacity of 50%:
- at example
-drawbox=10:20:200:60:red@@0.5
- at end example
-
-The previous example can be specified as:
- at example
-drawbox=x=10:y=20:w=200:h=60:color=red@@0.5
- at end example
-
- at item
-Fill the box with pink color:
- at example
-drawbox=x=10:y=10:w=100:h=100:color=pink@@0.5:t=max
- at end example
-
- at item
-Draw a 2-pixel red 2.40:1 mask:
- at example
-drawbox=x=-t:y=0.5*(ih-iw/2.4)-t:w=iw+t*2:h=iw/2.4+t*2:t=2:c=red
- at end example
- at end itemize
-
- at section drawgraph, adrawgraph
-
-Draw a graph using input video or audio metadata.
-
-It accepts the following parameters:
-
- at table @option
- at item m1
-Set 1st frame metadata key from which metadata values will be used to draw a graph.
-
- at item fg1
-Set 1st foreground color expression.
-
- at item m2
-Set 2nd frame metadata key from which metadata values will be used to draw a graph.
-
- at item fg2
-Set 2nd foreground color expression.
-
- at item m3
-Set 3rd frame metadata key from which metadata values will be used to draw a graph.
-
- at item fg3
-Set 3rd foreground color expression.
-
- at item m4
-Set 4th frame metadata key from which metadata values will be used to draw a graph.
-
- at item fg4
-Set 4th foreground color expression.
-
- at item min
-Set minimal value of metadata value.
-
- at item max
-Set maximal value of metadata value.
-
- at item bg
-Set graph background color. Default is white.
-
- at item mode
-Set graph mode.
-
-Available values for mode is:
- at table @samp
- at item bar
- at item dot
- at item line
- at end table
-
-Default is @code{line}.
-
- at item slide
-Set slide mode.
-
-Available values for slide is:
- at table @samp
- at item frame
-Draw new frame when right border is reached.
-
- at item replace
-Replace old columns with new ones.
-
- at item scroll
-Scroll from right to left.
-
- at item rscroll
-Scroll from left to right.
- at end table
-
-Default is @code{frame}.
-
- at item size
-Set size of graph video. For the syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-The default value is @code{900x256}.
-
-The foreground color expressions can use the following variables:
- at table @option
- at item MIN
-Minimal value of metadata value.
-
- at item MAX
-Maximal value of metadata value.
-
- at item VAL
-Current metadata key value.
- at end table
-
-The color is defined as 0xAABBGGRR.
- at end table
-
-Example using metadata from @ref{signalstats} filter:
- at example
-signalstats,drawgraph=lavfi.signalstats.YAVG:min=0:max=255
- at end example
-
-Example using metadata from @ref{ebur128} filter:
- at example
-ebur128=metadata=1,adrawgraph=lavfi.r128.M:min=-120:max=5
- at end example
-
- at section drawgrid
-
-Draw a grid on the input image.
-
-It accepts the following parameters:
-
- at table @option
- at item x
- at item y
-The expressions which specify the coordinates of some point of grid intersection (meant to configure offset). Both default to 0.
-
- at item width, w
- at item height, h
-The expressions which specify the width and height of the grid cell, if 0 they are interpreted as the
-input width and height, respectively, minus @code{thickness}, so image gets
-framed. Default to 0.
-
- at item color, c
-Specify the color of the grid. For the general syntax of this option,
-check the "Color" section in the ffmpeg-utils manual. If the special
-value @code{invert} is used, the grid color is the same as the
-video with inverted luma.
-
- at item thickness, t
-The expression which sets the thickness of the grid line. Default value is @code{1}.
-
-See below for the list of accepted constants.
- at end table
-
-The parameters for @var{x}, @var{y}, @var{w} and @var{h} and @var{t} are expressions containing the
-following constants:
-
- at table @option
- at item dar
-The input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar}.
-
- at item hsub
- at item vsub
-horizontal and vertical chroma subsample values. For example for the
-pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
-
- at item in_h, ih
- at item in_w, iw
-The input grid cell width and height.
-
- at item sar
-The input sample aspect ratio.
-
- at item x
- at item y
-The x and y coordinates of some point of grid intersection (meant to configure offset).
-
- at item w
- at item h
-The width and height of the drawn cell.
-
- at item t
-The thickness of the drawn cell.
-
-These constants allow the @var{x}, @var{y}, @var{w}, @var{h} and @var{t} expressions to refer to
-each other, so you may for example specify @code{y=x/dar} or @code{h=w/dar}.
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Draw a grid with cell 100x100 pixels, thickness 2 pixels, with color red and an opacity of 50%:
- at example
-drawgrid=width=100:height=100:thickness=2:color=red@@0.5
- at end example
-
- at item
-Draw a white 3x3 grid with an opacity of 50%:
- at example
-drawgrid=w=iw/3:h=ih/3:t=2:c=white@@0.5
- at end example
- at end itemize
-
- at anchor{drawtext}
- at section drawtext
-
-Draw a text string or text from a specified file on top of a video, using the
-libfreetype library.
-
-To enable compilation of this filter, you need to configure FFmpeg with
- at code{--enable-libfreetype}.
-To enable default font fallback and the @var{font} option you need to
-configure FFmpeg with @code{--enable-libfontconfig}.
-To enable the @var{text_shaping} option, you need to configure FFmpeg with
- at code{--enable-libfribidi}.
-
- at subsection Syntax
-
-It accepts the following parameters:
-
- at table @option
-
- at item box
-Used to draw a box around text using the background color.
-The value must be either 1 (enable) or 0 (disable).
-The default value of @var{box} is 0.
-
- at item boxborderw
-Set the width of the border to be drawn around the box using @var{boxcolor}.
-The default value of @var{boxborderw} is 0.
-
- at item boxcolor
-The color to be used for drawing box around text. For the syntax of this
-option, check the "Color" section in the ffmpeg-utils manual.
-
-The default value of @var{boxcolor} is "white".
-
- at item borderw
-Set the width of the border to be drawn around the text using @var{bordercolor}.
-The default value of @var{borderw} is 0.
-
- at item bordercolor
-Set the color to be used for drawing border around text. For the syntax of this
-option, check the "Color" section in the ffmpeg-utils manual.
-
-The default value of @var{bordercolor} is "black".
-
- at item expansion
-Select how the @var{text} is expanded. Can be either @code{none},
- at code{strftime} (deprecated) or
- at code{normal} (default). See the @ref{drawtext_expansion, Text expansion} section
-below for details.
-
- at item fix_bounds
-If true, check and fix text coords to avoid clipping.
-
- at item fontcolor
-The color to be used for drawing fonts. For the syntax of this option, check
-the "Color" section in the ffmpeg-utils manual.
-
-The default value of @var{fontcolor} is "black".
-
- at item fontcolor_expr
-String which is expanded the same way as @var{text} to obtain dynamic
- at var{fontcolor} value. By default this option has empty value and is not
-processed. When this option is set, it overrides @var{fontcolor} option.
-
- at item font
-The font family to be used for drawing text. By default Sans.
-
- at item fontfile
-The font file to be used for drawing text. The path must be included.
-This parameter is mandatory if the fontconfig support is disabled.
-
- at item draw
-This option does not exist, please see the timeline system
-
- at item alpha
-Draw the text applying alpha blending. The value can
-be either a number between 0.0 and 1.0
-The expression accepts the same variables @var{x, y} do.
-The default value is 1.
-Please see fontcolor_expr
-
- at item fontsize
-The font size to be used for drawing text.
-The default value of @var{fontsize} is 16.
-
- at item text_shaping
-If set to 1, attempt to shape the text (for example, reverse the order of
-right-to-left text and join Arabic characters) before drawing it.
-Otherwise, just draw the text exactly as given.
-By default 1 (if supported).
-
- at item ft_load_flags
-The flags to be used for loading the fonts.
-
-The flags map the corresponding flags supported by libfreetype, and are
-a combination of the following values:
- at table @var
- at item default
- at item no_scale
- at item no_hinting
- at item render
- at item no_bitmap
- at item vertical_layout
- at item force_autohint
- at item crop_bitmap
- at item pedantic
- at item ignore_global_advance_width
- at item no_recurse
- at item ignore_transform
- at item monochrome
- at item linear_design
- at item no_autohint
- at end table
-
-Default value is "default".
-
-For more information consult the documentation for the FT_LOAD_*
-libfreetype flags.
-
- at item shadowcolor
-The color to be used for drawing a shadow behind the drawn text. For the
-syntax of this option, check the "Color" section in the ffmpeg-utils manual.
-
-The default value of @var{shadowcolor} is "black".
-
- at item shadowx
- at item shadowy
-The x and y offsets for the text shadow position with respect to the
-position of the text. They can be either positive or negative
-values. The default value for both is "0".
-
- at item start_number
-The starting frame number for the n/frame_num variable. The default value
-is "0".
-
- at item tabsize
-The size in number of spaces to use for rendering the tab.
-Default value is 4.
-
- at item timecode
-Set the initial timecode representation in "hh:mm:ss[:;.]ff"
-format. It can be used with or without text parameter. @var{timecode_rate}
-option must be specified.
-
- at item timecode_rate, rate, r
-Set the timecode frame rate (timecode only).
-
- at item text
-The text string to be drawn. The text must be a sequence of UTF-8
-encoded characters.
-This parameter is mandatory if no file is specified with the parameter
- at var{textfile}.
-
- at item textfile
-A text file containing text to be drawn. The text must be a sequence
-of UTF-8 encoded characters.
-
-This parameter is mandatory if no text string is specified with the
-parameter @var{text}.
-
-If both @var{text} and @var{textfile} are specified, an error is thrown.
-
- at item reload
-If set to 1, the @var{textfile} will be reloaded before each frame.
-Be sure to update it atomically, or it may be read partially, or even fail.
-
- at item x
- at item y
-The expressions which specify the offsets where text will be drawn
-within the video frame. They are relative to the top/left border of the
-output image.
-
-The default value of @var{x} and @var{y} is "0".
-
-See below for the list of accepted constants and functions.
- at end table
-
-The parameters for @var{x} and @var{y} are expressions containing the
-following constants and functions:
-
- at table @option
- at item dar
-input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar}
-
- at item hsub
- at item vsub
-horizontal and vertical chroma subsample values. For example for the
-pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
-
- at item line_h, lh
-the height of each text line
-
- at item main_h, h, H
-the input height
-
- at item main_w, w, W
-the input width
-
- at item max_glyph_a, ascent
-the maximum distance from the baseline to the highest/upper grid
-coordinate used to place a glyph outline point, for all the rendered
-glyphs.
-It is a positive value, due to the grid's orientation with the Y axis
-upwards.
-
- at item max_glyph_d, descent
-the maximum distance from the baseline to the lowest grid coordinate
-used to place a glyph outline point, for all the rendered glyphs.
-This is a negative value, due to the grid's orientation, with the Y axis
-upwards.
-
- at item max_glyph_h
-maximum glyph height, that is the maximum height for all the glyphs
-contained in the rendered text, it is equivalent to @var{ascent} -
- at var{descent}.
-
- at item max_glyph_w
-maximum glyph width, that is the maximum width for all the glyphs
-contained in the rendered text
-
- at item n
-the number of input frame, starting from 0
-
- at item rand(min, max)
-return a random number included between @var{min} and @var{max}
-
- at item sar
-The input sample aspect ratio.
-
- at item t
-timestamp expressed in seconds, NAN if the input timestamp is unknown
-
- at item text_h, th
-the height of the rendered text
-
- at item text_w, tw
-the width of the rendered text
-
- at item x
- at item y
-the x and y offset coordinates where the text is drawn.
-
-These parameters allow the @var{x} and @var{y} expressions to refer
-each other, so you can for example specify @code{y=x/dar}.
- at end table
-
- at anchor{drawtext_expansion}
- at subsection Text expansion
-
-If @option{expansion} is set to @code{strftime},
-the filter recognizes strftime() sequences in the provided text and
-expands them accordingly. Check the documentation of strftime(). This
-feature is deprecated.
-
-If @option{expansion} is set to @code{none}, the text is printed verbatim.
-
-If @option{expansion} is set to @code{normal} (which is the default),
-the following expansion mechanism is used.
-
-The backslash character @samp{\}, followed by any character, always expands to
-the second character.
-
-Sequence of the form @code{%@{...@}} are expanded. The text between the
-braces is a function name, possibly followed by arguments separated by ':'.
-If the arguments contain special characters or delimiters (':' or '@}'),
-they should be escaped.
-
-Note that they probably must also be escaped as the value for the
- at option{text} option in the filter argument string and as the filter
-argument in the filtergraph description, and possibly also for the shell,
-that makes up to four levels of escaping; using a text file avoids these
-problems.
-
-The following functions are available:
-
- at table @command
-
- at item expr, e
-The expression evaluation result.
-
-It must take one argument specifying the expression to be evaluated,
-which accepts the same constants and functions as the @var{x} and
- at var{y} values. Note that not all constants should be used, for
-example the text size is not known when evaluating the expression, so
-the constants @var{text_w} and @var{text_h} will have an undefined
-value.
-
- at item expr_int_format, eif
-Evaluate the expression's value and output as formatted integer.
-
-The first argument is the expression to be evaluated, just as for the @var{expr} function.
-The second argument specifies the output format. Allowed values are @samp{x},
- at samp{X}, @samp{d} and @samp{u}. They are treated exactly as in the
- at code{printf} function.
-The third parameter is optional and sets the number of positions taken by the output.
-It can be used to add padding with zeros from the left.
-
- at item gmtime
-The time at which the filter is running, expressed in UTC.
-It can accept an argument: a strftime() format string.
-
- at item localtime
-The time at which the filter is running, expressed in the local time zone.
-It can accept an argument: a strftime() format string.
-
- at item metadata
-Frame metadata. It must take one argument specifying metadata key.
-
- at item n, frame_num
-The frame number, starting from 0.
-
- at item pict_type
-A 1 character description of the current picture type.
-
- at item pts
-The timestamp of the current frame.
-It can take up to two arguments.
-
-The first argument is the format of the timestamp; it defaults to @code{flt}
-for seconds as a decimal number with microsecond accuracy; @code{hms} stands
-for a formatted @var{[-]HH:MM:SS.mmm} timestamp with millisecond accuracy.
-
-The second argument is an offset added to the timestamp.
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Draw "Test Text" with font FreeSerif, using the default values for the
-optional parameters.
-
- at example
-drawtext="fontfile=/usr/share/fonts/truetype/freefont/FreeSerif.ttf: text='Test Text'"
- at end example
-
- at item
-Draw 'Test Text' with font FreeSerif of size 24 at position x=100
-and y=50 (counting from the top-left corner of the screen), text is
-yellow with a red box around it. Both the text and the box have an
-opacity of 20%.
-
- at example
-drawtext="fontfile=/usr/share/fonts/truetype/freefont/FreeSerif.ttf: text='Test Text':\
- x=100: y=50: fontsize=24: fontcolor=yellow@@0.2: box=1: boxcolor=red@@0.2"
- at end example
-
-Note that the double quotes are not necessary if spaces are not used
-within the parameter list.
-
- at item
-Show the text at the center of the video frame:
- at example
-drawtext="fontsize=30:fontfile=FreeSerif.ttf:text='hello world':x=(w-text_w)/2:y=(h-text_h)/2"
- at end example
-
- at item
-Show a text line sliding from right to left in the last row of the video
-frame. The file @file{LONG_LINE} is assumed to contain a single line
-with no newlines.
- at example
-drawtext="fontsize=15:fontfile=FreeSerif.ttf:text=LONG_LINE:y=h-line_h:x=-50*t"
- at end example
-
- at item
-Show the content of file @file{CREDITS} off the bottom of the frame and scroll up.
- at example
-drawtext="fontsize=20:fontfile=FreeSerif.ttf:textfile=CREDITS:y=h-20*t"
- at end example
-
- at item
-Draw a single green letter "g", at the center of the input video.
-The glyph baseline is placed at half screen height.
- at example
-drawtext="fontsize=60:fontfile=FreeSerif.ttf:fontcolor=green:text=g:x=(w-max_glyph_w)/2:y=h/2-ascent"
- at end example
-
- at item
-Show text for 1 second every 3 seconds:
- at example
-drawtext="fontfile=FreeSerif.ttf:fontcolor=white:x=100:y=x/dar:enable=lt(mod(t\,3)\,1):text='blink'"
- at end example
-
- at item
-Use fontconfig to set the font. Note that the colons need to be escaped.
- at example
-drawtext='fontfile=Linux Libertine O-40\:style=Semibold:text=FFmpeg'
- at end example
-
- at item
-Print the date of a real-time encoding (see strftime(3)):
- at example
-drawtext='fontfile=FreeSans.ttf:text=%@{localtime\:%a %b %d %Y@}'
- at end example
-
- at item
-Show text fading in and out (appearing/disappearing):
- at example
-#!/bin/sh
-DS=1.0 # display start
-DE=10.0 # display end
-FID=1.5 # fade in duration
-FOD=5 # fade out duration
-ffplay -f lavfi "color,drawtext=text=TEST:fontsize=50:fontfile=FreeSerif.ttf:fontcolor_expr=ff0000%@{eif\\\\: clip(255*(1*between(t\\, $DS + $FID\\, $DE - $FOD) + ((t - $DS)/$FID)*between(t\\, $DS\\, $DS + $FID) + (-(t - $DE)/$FOD)*between(t\\, $DE - $FOD\\, $DE) )\\, 0\\, 255) \\\\: x\\\\: 2 @}"
- at end example
-
- at end itemize
-
-For more information about libfreetype, check:
- at url{http://www.freetype.org/}.
-
-For more information about fontconfig, check:
- at url{http://freedesktop.org/software/fontconfig/fontconfig-user.html}.
-
-For more information about libfribidi, check:
- at url{http://fribidi.org/}.
-
- at section edgedetect
-
-Detect and draw edges. The filter uses the Canny Edge Detection algorithm.
-
-The filter accepts the following options:
-
- at table @option
- at item low
- at item high
-Set low and high threshold values used by the Canny thresholding
-algorithm.
-
-The high threshold selects the "strong" edge pixels, which are then
-connected through 8-connectivity with the "weak" edge pixels selected
-by the low threshold.
-
- at var{low} and @var{high} threshold values must be chosen in the range
-[0,1], and @var{low} should be lesser or equal to @var{high}.
-
-Default value for @var{low} is @code{20/255}, and default value for @var{high}
-is @code{50/255}.
-
- at item mode
-Define the drawing mode.
-
- at table @samp
- at item wires
-Draw white/gray wires on black background.
-
- at item colormix
-Mix the colors to create a paint/cartoon effect.
- at end table
-
-Default value is @var{wires}.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Standard edge detection with custom values for the hysteresis thresholding:
- at example
-edgedetect=low=0.1:high=0.4
- at end example
-
- at item
-Painting effect without thresholding:
- at example
-edgedetect=mode=colormix:high=0
- at end example
- at end itemize
-
- at section eq
-Set brightness, contrast, saturation and approximate gamma adjustment.
-
-The filter accepts the following options:
-
- at table @option
- at item contrast
-Set the contrast expression. The value must be a float value in range
- at code{-2.0} to @code{2.0}. The default value is "0".
-
- at item brightness
-Set the brightness expression. The value must be a float value in
-range @code{-1.0} to @code{1.0}. The default value is "0".
-
- at item saturation
-Set the saturation expression. The value must be a float in
-range @code{0.0} to @code{3.0}. The default value is "1".
-
- at item gamma
-Set the gamma expression. The value must be a float in range
- at code{0.1} to @code{10.0}. The default value is "1".
-
- at item gamma_r
-Set the gamma expression for red. The value must be a float in
-range @code{0.1} to @code{10.0}. The default value is "1".
-
- at item gamma_g
-Set the gamma expression for green. The value must be a float in range
- at code{0.1} to @code{10.0}. The default value is "1".
-
- at item gamma_b
-Set the gamma expression for blue. The value must be a float in range
- at code{0.1} to @code{10.0}. The default value is "1".
-
- at item gamma_weight
-Set the gamma weight expression. It can be used to reduce the effect
-of a high gamma value on bright image areas, e.g. keep them from
-getting overamplified and just plain white. The value must be a float
-in range @code{0.0} to @code{1.0}. A value of @code{0.0} turns the
-gamma correction all the way down while @code{1.0} leaves it at its
-full strength. Default is "1".
-
- at item eval
-Set when the expressions for brightness, contrast, saturation and
-gamma expressions are evaluated.
-
-It accepts the following values:
- at table @samp
- at item init
-only evaluate expressions once during the filter initialization or
-when a command is processed
-
- at item frame
-evaluate expressions for each incoming frame
- at end table
-
-Default value is @samp{init}.
- at end table
-
-The expressions accept the following parameters:
- at table @option
- at item n
-frame count of the input frame starting from 0
-
- at item pos
-byte position of the corresponding packet in the input file, NAN if
-unspecified
-
- at item r
-frame rate of the input video, NAN if the input frame rate is unknown
-
- at item t
-timestamp expressed in seconds, NAN if the input timestamp is unknown
- at end table
-
- at subsection Commands
-The filter supports the following commands:
-
- at table @option
- at item contrast
-Set the contrast expression.
-
- at item brightness
-Set the brightness expression.
-
- at item saturation
-Set the saturation expression.
-
- at item gamma
-Set the gamma expression.
-
- at item gamma_r
-Set the gamma_r expression.
-
- at item gamma_g
-Set gamma_g expression.
-
- at item gamma_b
-Set gamma_b expression.
-
- at item gamma_weight
-Set gamma_weight expression.
-
-The command accepts the same syntax of the corresponding option.
-
-If the specified expression is not valid, it is kept at its current
-value.
-
- at end table
-
- at section erosion
-
-Apply erosion effect to the video.
-
-This filter replaces the pixel by the local(3x3) minimum.
-
-It accepts the following options:
-
- at table @option
- at item threshold0
- at item threshold1
- at item threshold2
- at item threshold3
-Limit the maximum change for each plane, default is 65535.
-If 0, plane will remain unchanged.
-
- at item coordinates
-Flag which specifies the pixel to refer to. Default is 255 i.e. all eight
-pixels are used.
-
-Flags to local 3x3 coordinates maps like this:
-
- 1 2 3
- 4 5
- 6 7 8
- at end table
-
- at section extractplanes
-
-Extract color channel components from input video stream into
-separate grayscale video streams.
-
-The filter accepts the following option:
-
- at table @option
- at item planes
-Set plane(s) to extract.
-
-Available values for planes are:
- at table @samp
- at item y
- at item u
- at item v
- at item a
- at item r
- at item g
- at item b
- at end table
-
-Choosing planes not available in the input will result in an error.
-That means you cannot select @code{r}, @code{g}, @code{b} planes
-with @code{y}, @code{u}, @code{v} planes at same time.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Extract luma, u and v color channel component from input video frame
-into 3 grayscale outputs:
- at example
-ffmpeg -i video.avi -filter_complex 'extractplanes=y+u+v[y][u][v]' -map '[y]' y.avi -map '[u]' u.avi -map '[v]' v.avi
- at end example
- at end itemize
-
- at section elbg
-
-Apply a posterize effect using the ELBG (Enhanced LBG) algorithm.
-
-For each input image, the filter will compute the optimal mapping from
-the input to the output given the codebook length, that is the number
-of distinct output colors.
-
-This filter accepts the following options.
-
- at table @option
- at item codebook_length, l
-Set codebook length. The value must be a positive integer, and
-represents the number of distinct output colors. Default value is 256.
-
- at item nb_steps, n
-Set the maximum number of iterations to apply for computing the optimal
-mapping. The higher the value the better the result and the higher the
-computation time. Default value is 1.
-
- at item seed, s
-Set a random seed, must be an integer included between 0 and
-UINT32_MAX. If not specified, or if explicitly set to -1, the filter
-will try to use a good random seed on a best effort basis.
-
- at item pal8
-Set pal8 output pixel format. This option does not work with codebook
-length greater than 256.
- at end table
-
- at section fade
-
-Apply a fade-in/out effect to the input video.
-
-It accepts the following parameters:
-
- at table @option
- at item type, t
-The effect type can be either "in" for a fade-in, or "out" for a fade-out
-effect.
-Default is @code{in}.
-
- at item start_frame, s
-Specify the number of the frame to start applying the fade
-effect at. Default is 0.
-
- at item nb_frames, n
-The number of frames that the fade effect lasts. At the end of the
-fade-in effect, the output video will have the same intensity as the input video.
-At the end of the fade-out transition, the output video will be filled with the
-selected @option{color}.
-Default is 25.
-
- at item alpha
-If set to 1, fade only alpha channel, if one exists on the input.
-Default value is 0.
-
- at item start_time, st
-Specify the timestamp (in seconds) of the frame to start to apply the fade
-effect. If both start_frame and start_time are specified, the fade will start at
-whichever comes last. Default is 0.
-
- at item duration, d
-The number of seconds for which the fade effect has to last. At the end of the
-fade-in effect the output video will have the same intensity as the input video,
-at the end of the fade-out transition the output video will be filled with the
-selected @option{color}.
-If both duration and nb_frames are specified, duration is used. Default is 0
-(nb_frames is used by default).
-
- at item color, c
-Specify the color of the fade. Default is "black".
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Fade in the first 30 frames of video:
- at example
-fade=in:0:30
- at end example
-
-The command above is equivalent to:
- at example
-fade=t=in:s=0:n=30
- at end example
-
- at item
-Fade out the last 45 frames of a 200-frame video:
- at example
-fade=out:155:45
-fade=type=out:start_frame=155:nb_frames=45
- at end example
-
- at item
-Fade in the first 25 frames and fade out the last 25 frames of a 1000-frame video:
- at example
-fade=in:0:25, fade=out:975:25
- at end example
-
- at item
-Make the first 5 frames yellow, then fade in from frame 5-24:
- at example
-fade=in:5:20:color=yellow
- at end example
-
- at item
-Fade in alpha over first 25 frames of video:
- at example
-fade=in:0:25:alpha=1
- at end example
-
- at item
-Make the first 5.5 seconds black, then fade in for 0.5 seconds:
- at example
-fade=t=in:st=5.5:d=0.5
- at end example
-
- at end itemize
-
- at section fftfilt
-Apply arbitrary expressions to samples in frequency domain
-
- at table @option
- at item dc_Y
-Adjust the dc value (gain) of the luma plane of the image. The filter
-accepts an integer value in range @code{0} to @code{1000}. The default
-value is set to @code{0}.
-
- at item dc_U
-Adjust the dc value (gain) of the 1st chroma plane of the image. The
-filter accepts an integer value in range @code{0} to @code{1000}. The
-default value is set to @code{0}.
-
- at item dc_V
-Adjust the dc value (gain) of the 2nd chroma plane of the image. The
-filter accepts an integer value in range @code{0} to @code{1000}. The
-default value is set to @code{0}.
-
- at item weight_Y
-Set the frequency domain weight expression for the luma plane.
-
- at item weight_U
-Set the frequency domain weight expression for the 1st chroma plane.
-
- at item weight_V
-Set the frequency domain weight expression for the 2nd chroma plane.
-
-The filter accepts the following variables:
- at item X
- at item Y
-The coordinates of the current sample.
-
- at item W
- at item H
-The width and height of the image.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-High-pass:
- at example
-fftfilt=dc_Y=128:weight_Y='squish(1-(Y+X)/100)'
- at end example
-
- at item
-Low-pass:
- at example
-fftfilt=dc_Y=0:weight_Y='squish((Y+X)/100-1)'
- at end example
-
- at item
-Sharpen:
- at example
-fftfilt=dc_Y=0:weight_Y='1+squish(1-(Y+X)/100)'
- at end example
-
- at end itemize
-
- at section field
-
-Extract a single field from an interlaced image using stride
-arithmetic to avoid wasting CPU time. The output frames are marked as
-non-interlaced.
-
-The filter accepts the following options:
-
- at table @option
- at item type
-Specify whether to extract the top (if the value is @code{0} or
- at code{top}) or the bottom field (if the value is @code{1} or
- at code{bottom}).
- at end table
-
- at section fieldmatch
-
-Field matching filter for inverse telecine. It is meant to reconstruct the
-progressive frames from a telecined stream. The filter does not drop duplicated
-frames, so to achieve a complete inverse telecine @code{fieldmatch} needs to be
-followed by a decimation filter such as @ref{decimate} in the filtergraph.
-
-The separation of the field matching and the decimation is notably motivated by
-the possibility of inserting a de-interlacing filter fallback between the two.
-If the source has mixed telecined and real interlaced content,
- at code{fieldmatch} will not be able to match fields for the interlaced parts.
-But these remaining combed frames will be marked as interlaced, and thus can be
-de-interlaced by a later filter such as @ref{yadif} before decimation.
-
-In addition to the various configuration options, @code{fieldmatch} can take an
-optional second stream, activated through the @option{ppsrc} option. If
-enabled, the frames reconstruction will be based on the fields and frames from
-this second stream. This allows the first input to be pre-processed in order to
-help the various algorithms of the filter, while keeping the output lossless
-(assuming the fields are matched properly). Typically, a field-aware denoiser,
-or brightness/contrast adjustments can help.
-
-Note that this filter uses the same algorithms as TIVTC/TFM (AviSynth project)
-and VIVTC/VFM (VapourSynth project). The later is a light clone of TFM from
-which @code{fieldmatch} is based on. While the semantic and usage are very
-close, some behaviour and options names can differ.
-
-The @ref{decimate} filter currently only works for constant frame rate input.
-If your input has mixed telecined (30fps) and progressive content with a lower
-framerate like 24fps use the following filterchain to produce the necessary cfr
-stream: @code{dejudder,fps=30000/1001,fieldmatch,decimate}.
-
-The filter accepts the following options:
-
- at table @option
- at item order
-Specify the assumed field order of the input stream. Available values are:
-
- at table @samp
- at item auto
-Auto detect parity (use FFmpeg's internal parity value).
- at item bff
-Assume bottom field first.
- at item tff
-Assume top field first.
- at end table
-
-Note that it is sometimes recommended not to trust the parity announced by the
-stream.
-
-Default value is @var{auto}.
-
- at item mode
-Set the matching mode or strategy to use. @option{pc} mode is the safest in the
-sense that it won't risk creating jerkiness due to duplicate frames when
-possible, but if there are bad edits or blended fields it will end up
-outputting combed frames when a good match might actually exist. On the other
-hand, @option{pcn_ub} mode is the most risky in terms of creating jerkiness,
-but will almost always find a good frame if there is one. The other values are
-all somewhere in between @option{pc} and @option{pcn_ub} in terms of risking
-jerkiness and creating duplicate frames versus finding good matches in sections
-with bad edits, orphaned fields, blended fields, etc.
-
-More details about p/c/n/u/b are available in @ref{p/c/n/u/b meaning} section.
-
-Available values are:
-
- at table @samp
- at item pc
-2-way matching (p/c)
- at item pc_n
-2-way matching, and trying 3rd match if still combed (p/c + n)
- at item pc_u
-2-way matching, and trying 3rd match (same order) if still combed (p/c + u)
- at item pc_n_ub
-2-way matching, trying 3rd match if still combed, and trying 4th/5th matches if
-still combed (p/c + n + u/b)
- at item pcn
-3-way matching (p/c/n)
- at item pcn_ub
-3-way matching, and trying 4th/5th matches if all 3 of the original matches are
-detected as combed (p/c/n + u/b)
- at end table
-
-The parenthesis at the end indicate the matches that would be used for that
-mode assuming @option{order}=@var{tff} (and @option{field} on @var{auto} or
- at var{top}).
-
-In terms of speed @option{pc} mode is by far the fastest and @option{pcn_ub} is
-the slowest.
-
-Default value is @var{pc_n}.
-
- at item ppsrc
-Mark the main input stream as a pre-processed input, and enable the secondary
-input stream as the clean source to pick the fields from. See the filter
-introduction for more details. It is similar to the @option{clip2} feature from
-VFM/TFM.
-
-Default value is @code{0} (disabled).
-
- at item field
-Set the field to match from. It is recommended to set this to the same value as
- at option{order} unless you experience matching failures with that setting. In
-certain circumstances changing the field that is used to match from can have a
-large impact on matching performance. Available values are:
-
- at table @samp
- at item auto
-Automatic (same value as @option{order}).
- at item bottom
-Match from the bottom field.
- at item top
-Match from the top field.
- at end table
-
-Default value is @var{auto}.
-
- at item mchroma
-Set whether or not chroma is included during the match comparisons. In most
-cases it is recommended to leave this enabled. You should set this to @code{0}
-only if your clip has bad chroma problems such as heavy rainbowing or other
-artifacts. Setting this to @code{0} could also be used to speed things up at
-the cost of some accuracy.
-
-Default value is @code{1}.
-
- at item y0
- at item y1
-These define an exclusion band which excludes the lines between @option{y0} and
- at option{y1} from being included in the field matching decision. An exclusion
-band can be used to ignore subtitles, a logo, or other things that may
-interfere with the matching. @option{y0} sets the starting scan line and
- at option{y1} sets the ending line; all lines in between @option{y0} and
- at option{y1} (including @option{y0} and @option{y1}) will be ignored. Setting
- at option{y0} and @option{y1} to the same value will disable the feature.
- at option{y0} and @option{y1} defaults to @code{0}.
-
- at item scthresh
-Set the scene change detection threshold as a percentage of maximum change on
-the luma plane. Good values are in the @code{[8.0, 14.0]} range. Scene change
-detection is only relevant in case @option{combmatch}=@var{sc}. The range for
- at option{scthresh} is @code{[0.0, 100.0]}.
-
-Default value is @code{12.0}.
-
- at item combmatch
-When @option{combatch} is not @var{none}, @code{fieldmatch} will take into
-account the combed scores of matches when deciding what match to use as the
-final match. Available values are:
-
- at table @samp
- at item none
-No final matching based on combed scores.
- at item sc
-Combed scores are only used when a scene change is detected.
- at item full
-Use combed scores all the time.
- at end table
-
-Default is @var{sc}.
-
- at item combdbg
-Force @code{fieldmatch} to calculate the combed metrics for certain matches and
-print them. This setting is known as @option{micout} in TFM/VFM vocabulary.
-Available values are:
-
- at table @samp
- at item none
-No forced calculation.
- at item pcn
-Force p/c/n calculations.
- at item pcnub
-Force p/c/n/u/b calculations.
- at end table
-
-Default value is @var{none}.
-
- at item cthresh
-This is the area combing threshold used for combed frame detection. This
-essentially controls how "strong" or "visible" combing must be to be detected.
-Larger values mean combing must be more visible and smaller values mean combing
-can be less visible or strong and still be detected. Valid settings are from
- at code{-1} (every pixel will be detected as combed) to @code{255} (no pixel will
-be detected as combed). This is basically a pixel difference value. A good
-range is @code{[8, 12]}.
-
-Default value is @code{9}.
-
- at item chroma
-Sets whether or not chroma is considered in the combed frame decision. Only
-disable this if your source has chroma problems (rainbowing, etc.) that are
-causing problems for the combed frame detection with chroma enabled. Actually,
-using @option{chroma}=@var{0} is usually more reliable, except for the case
-where there is chroma only combing in the source.
-
-Default value is @code{0}.
-
- at item blockx
- at item blocky
-Respectively set the x-axis and y-axis size of the window used during combed
-frame detection. This has to do with the size of the area in which
- at option{combpel} pixels are required to be detected as combed for a frame to be
-declared combed. See the @option{combpel} parameter description for more info.
-Possible values are any number that is a power of 2 starting at 4 and going up
-to 512.
-
-Default value is @code{16}.
-
- at item combpel
-The number of combed pixels inside any of the @option{blocky} by
- at option{blockx} size blocks on the frame for the frame to be detected as
-combed. While @option{cthresh} controls how "visible" the combing must be, this
-setting controls "how much" combing there must be in any localized area (a
-window defined by the @option{blockx} and @option{blocky} settings) on the
-frame. Minimum value is @code{0} and maximum is @code{blocky x blockx} (at
-which point no frames will ever be detected as combed). This setting is known
-as @option{MI} in TFM/VFM vocabulary.
-
-Default value is @code{80}.
- at end table
-
- at anchor{p/c/n/u/b meaning}
- at subsection p/c/n/u/b meaning
-
- at subsubsection p/c/n
-
-We assume the following telecined stream:
-
- at example
-Top fields: 1 2 2 3 4
-Bottom fields: 1 2 3 4 4
- at end example
-
-The numbers correspond to the progressive frame the fields relate to. Here, the
-first two frames are progressive, the 3rd and 4th are combed, and so on.
-
-When @code{fieldmatch} is configured to run a matching from bottom
-(@option{field}=@var{bottom}) this is how this input stream get transformed:
-
- at example
-Input stream:
- T 1 2 2 3 4
- B 1 2 3 4 4 <-- matching reference
-
-Matches: c c n n c
-
-Output stream:
- T 1 2 3 4 4
- B 1 2 3 4 4
- at end example
-
-As a result of the field matching, we can see that some frames get duplicated.
-To perform a complete inverse telecine, you need to rely on a decimation filter
-after this operation. See for instance the @ref{decimate} filter.
-
-The same operation now matching from top fields (@option{field}=@var{top})
-looks like this:
-
- at example
-Input stream:
- T 1 2 2 3 4 <-- matching reference
- B 1 2 3 4 4
-
-Matches: c c p p c
-
-Output stream:
- T 1 2 2 3 4
- B 1 2 2 3 4
- at end example
-
-In these examples, we can see what @var{p}, @var{c} and @var{n} mean;
-basically, they refer to the frame and field of the opposite parity:
-
- at itemize
- at item @var{p} matches the field of the opposite parity in the previous frame
- at item @var{c} matches the field of the opposite parity in the current frame
- at item @var{n} matches the field of the opposite parity in the next frame
- at end itemize
-
- at subsubsection u/b
-
-The @var{u} and @var{b} matching are a bit special in the sense that they match
-from the opposite parity flag. In the following examples, we assume that we are
-currently matching the 2nd frame (Top:2, bottom:2). According to the match, a
-'x' is placed above and below each matched fields.
-
-With bottom matching (@option{field}=@var{bottom}):
- at example
-Match: c p n b u
-
- x x x x x
- Top 1 2 2 1 2 2 1 2 2 1 2 2 1 2 2
- Bottom 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
- x x x x x
-
-Output frames:
- 2 1 2 2 2
- 2 2 2 1 3
- at end example
-
-With top matching (@option{field}=@var{top}):
- at example
-Match: c p n b u
-
- x x x x x
- Top 1 2 2 1 2 2 1 2 2 1 2 2 1 2 2
- Bottom 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
- x x x x x
-
-Output frames:
- 2 2 2 1 2
- 2 1 3 2 2
- at end example
-
- at subsection Examples
-
-Simple IVTC of a top field first telecined stream:
- at example
-fieldmatch=order=tff:combmatch=none, decimate
- at end example
-
-Advanced IVTC, with fallback on @ref{yadif} for still combed frames:
- at example
-fieldmatch=order=tff:combmatch=full, yadif=deint=interlaced, decimate
- at end example
-
- at section fieldorder
-
-Transform the field order of the input video.
-
-It accepts the following parameters:
-
- at table @option
-
- at item order
-The output field order. Valid values are @var{tff} for top field first or @var{bff}
-for bottom field first.
- at end table
-
-The default value is @samp{tff}.
-
-The transformation is done by shifting the picture content up or down
-by one line, and filling the remaining line with appropriate picture content.
-This method is consistent with most broadcast field order converters.
-
-If the input video is not flagged as being interlaced, or it is already
-flagged as being of the required output field order, then this filter does
-not alter the incoming video.
-
-It is very useful when converting to or from PAL DV material,
-which is bottom field first.
-
-For example:
- at example
-ffmpeg -i in.vob -vf "fieldorder=bff" out.dv
- at end example
-
- at section fifo
-
-Buffer input images and send them when they are requested.
-
-It is mainly useful when auto-inserted by the libavfilter
-framework.
-
-It does not take parameters.
-
- at section find_rect
-
-Find a rectangular object
-
-It accepts the following options:
-
- at table @option
- at item object
-Filepath of the object image, needs to be in gray8.
-
- at item threshold
-Detection threshold, default is 0.5.
-
- at item mipmaps
-Number of mipmaps, default is 3.
-
- at item xmin, ymin, xmax, ymax
-Specifies the rectangle in which to search.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Generate a representative palette of a given video using @command{ffmpeg}:
- at example
-ffmpeg -i file.ts -vf find_rect=newref.pgm,cover_rect=cover.jpg:mode=cover new.mkv
- at end example
- at end itemize
-
- at section cover_rect
-
-Cover a rectangular object
-
-It accepts the following options:
-
- at table @option
- at item cover
-Filepath of the optional cover image, needs to be in yuv420.
-
- at item mode
-Set covering mode.
-
-It accepts the following values:
- at table @samp
- at item cover
-cover it by the supplied image
- at item blur
-cover it by interpolating the surrounding pixels
- at end table
-
-Default value is @var{blur}.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Generate a representative palette of a given video using @command{ffmpeg}:
- at example
-ffmpeg -i file.ts -vf find_rect=newref.pgm,cover_rect=cover.jpg:mode=cover new.mkv
- at end example
- at end itemize
-
- at anchor{format}
- at section format
-
-Convert the input video to one of the specified pixel formats.
-Libavfilter will try to pick one that is suitable as input to
-the next filter.
-
-It accepts the following parameters:
- at table @option
-
- at item pix_fmts
-A '|'-separated list of pixel format names, such as
-"pix_fmts=yuv420p|monow|rgb24".
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Convert the input video to the @var{yuv420p} format
- at example
-format=pix_fmts=yuv420p
- at end example
-
-Convert the input video to any of the formats in the list
- at example
-format=pix_fmts=yuv420p|yuv444p|yuv410p
- at end example
- at end itemize
-
- at anchor{fps}
- at section fps
-
-Convert the video to specified constant frame rate by duplicating or dropping
-frames as necessary.
-
-It accepts the following parameters:
- at table @option
-
- at item fps
-The desired output frame rate. The default is @code{25}.
-
- at item round
-Rounding method.
-
-Possible values are:
- at table @option
- at item zero
-zero round towards 0
- at item inf
-round away from 0
- at item down
-round towards -infinity
- at item up
-round towards +infinity
- at item near
-round to nearest
- at end table
-The default is @code{near}.
-
- at item start_time
-Assume the first PTS should be the given value, in seconds. This allows for
-padding/trimming at the start of stream. By default, no assumption is made
-about the first frame's expected PTS, so no padding or trimming is done.
-For example, this could be set to 0 to pad the beginning with duplicates of
-the first frame if a video stream starts after the audio stream or to trim any
-frames with a negative PTS.
-
- at end table
-
-Alternatively, the options can be specified as a flat string:
- at var{fps}[:@var{round}].
-
-See also the @ref{setpts} filter.
-
- at subsection Examples
-
- at itemize
- at item
-A typical usage in order to set the fps to 25:
- at example
-fps=fps=25
- at end example
-
- at item
-Sets the fps to 24, using abbreviation and rounding method to round to nearest:
- at example
-fps=fps=film:round=near
- at end example
- at end itemize
-
- at section framepack
-
-Pack two different video streams into a stereoscopic video, setting proper
-metadata on supported codecs. The two views should have the same size and
-framerate and processing will stop when the shorter video ends. Please note
-that you may conveniently adjust view properties with the @ref{scale} and
- at ref{fps} filters.
-
-It accepts the following parameters:
- at table @option
-
- at item format
-The desired packing format. Supported values are:
-
- at table @option
-
- at item sbs
-The views are next to each other (default).
-
- at item tab
-The views are on top of each other.
-
- at item lines
-The views are packed by line.
-
- at item columns
-The views are packed by column.
-
- at item frameseq
-The views are temporally interleaved.
-
- at end table
-
- at end table
-
-Some examples:
-
- at example
-# Convert left and right views into a frame-sequential video
-ffmpeg -i LEFT -i RIGHT -filter_complex framepack=frameseq OUTPUT
-
-# Convert views into a side-by-side video with the same output resolution as the input
-ffmpeg -i LEFT -i RIGHT -filter_complex [0:v]scale=w=iw/2[left],[1:v]scale=w=iw/2[right],[left][right]framepack=sbs OUTPUT
- at end example
-
- at section framerate
-
-Change the frame rate by interpolating new video output frames from the source
-frames.
-
-This filter is not designed to function correctly with interlaced media. If
-you wish to change the frame rate of interlaced media then you are required
-to deinterlace before this filter and re-interlace after this filter.
-
-A description of the accepted options follows.
-
- at table @option
- at item fps
-Specify the output frames per second. This option can also be specified
-as a value alone. The default is @code{50}.
-
- at item interp_start
-Specify the start of a range where the output frame will be created as a
-linear interpolation of two frames. The range is [@code{0}- at code{255}],
-the default is @code{15}.
-
- at item interp_end
-Specify the end of a range where the output frame will be created as a
-linear interpolation of two frames. The range is [@code{0}- at code{255}],
-the default is @code{240}.
-
- at item scene
-Specify the level at which a scene change is detected as a value between
-0 and 100 to indicate a new scene; a low value reflects a low
-probability for the current frame to introduce a new scene, while a higher
-value means the current frame is more likely to be one.
-The default is @code{7}.
-
- at item flags
-Specify flags influencing the filter process.
-
-Available value for @var{flags} is:
-
- at table @option
- at item scene_change_detect, scd
-Enable scene change detection using the value of the option @var{scene}.
-This flag is enabled by default.
- at end table
- at end table
-
- at section framestep
-
-Select one frame every N-th frame.
-
-This filter accepts the following option:
- at table @option
- at item step
-Select frame after every @code{step} frames.
-Allowed values are positive integers higher than 0. Default value is @code{1}.
- at end table
-
- at anchor{frei0r}
- at section frei0r
-
-Apply a frei0r effect to the input video.
-
-To enable the compilation of this filter, you need to install the frei0r
-header and configure FFmpeg with @code{--enable-frei0r}.
-
-It accepts the following parameters:
-
- at table @option
-
- at item filter_name
-The name of the frei0r effect to load. If the environment variable
- at env{FREI0R_PATH} is defined, the frei0r effect is searched for in each of the
-directories specified by the colon-separated list in @env{FREIOR_PATH}.
-Otherwise, the standard frei0r paths are searched, in this order:
- at file{HOME/.frei0r-1/lib/}, @file{/usr/local/lib/frei0r-1/},
- at file{/usr/lib/frei0r-1/}.
-
- at item filter_params
-A '|'-separated list of parameters to pass to the frei0r effect.
-
- at end table
-
-A frei0r effect parameter can be a boolean (its value is either
-"y" or "n"), a double, a color (specified as
- at var{R}/@var{G}/@var{B}, where @var{R}, @var{G}, and @var{B} are floating point
-numbers between 0.0 and 1.0, inclusive) or by a color description specified in the "Color"
-section in the ffmpeg-utils manual), a position (specified as @var{X}/@var{Y}, where
- at var{X} and @var{Y} are floating point numbers) and/or a string.
-
-The number and types of parameters depend on the loaded effect. If an
-effect parameter is not specified, the default value is set.
-
- at subsection Examples
-
- at itemize
- at item
-Apply the distort0r effect, setting the first two double parameters:
- at example
-frei0r=filter_name=distort0r:filter_params=0.5|0.01
- at end example
-
- at item
-Apply the colordistance effect, taking a color as the first parameter:
- at example
-frei0r=colordistance:0.2/0.3/0.4
-frei0r=colordistance:violet
-frei0r=colordistance:0x112233
- at end example
-
- at item
-Apply the perspective effect, specifying the top left and top right image
-positions:
- at example
-frei0r=perspective:0.2/0.2|0.8/0.2
- at end example
- at end itemize
-
-For more information, see
- at url{http://frei0r.dyne.org}
-
- at section fspp
-
-Apply fast and simple postprocessing. It is a faster version of @ref{spp}.
-
-It splits (I)DCT into horizontal/vertical passes. Unlike the simple post-
-processing filter, one of them is performed once per block, not per pixel.
-This allows for much higher speed.
-
-The filter accepts the following options:
-
- at table @option
- at item quality
-Set quality. This option defines the number of levels for averaging. It accepts
-an integer in the range 4-5. Default value is @code{4}.
-
- at item qp
-Force a constant quantization parameter. It accepts an integer in range 0-63.
-If not set, the filter will use the QP from the video stream (if available).
-
- at item strength
-Set filter strength. It accepts an integer in range -15 to 32. Lower values mean
-more details but also more artifacts, while higher values make the image smoother
-but also blurrier. Default value is @code{0} − PSNR optimal.
-
- at item use_bframe_qp
-Enable the use of the QP from the B-Frames if set to @code{1}. Using this
-option may cause flicker since the B-Frames have often larger QP. Default is
- at code{0} (not enabled).
-
- at end table
-
- at section geq
-
-The filter accepts the following options:
-
- at table @option
- at item lum_expr, lum
-Set the luminance expression.
- at item cb_expr, cb
-Set the chrominance blue expression.
- at item cr_expr, cr
-Set the chrominance red expression.
- at item alpha_expr, a
-Set the alpha expression.
- at item red_expr, r
-Set the red expression.
- at item green_expr, g
-Set the green expression.
- at item blue_expr, b
-Set the blue expression.
- at end table
-
-The colorspace is selected according to the specified options. If one
-of the @option{lum_expr}, @option{cb_expr}, or @option{cr_expr}
-options is specified, the filter will automatically select a YCbCr
-colorspace. If one of the @option{red_expr}, @option{green_expr}, or
- at option{blue_expr} options is specified, it will select an RGB
-colorspace.
-
-If one of the chrominance expression is not defined, it falls back on the other
-one. If no alpha expression is specified it will evaluate to opaque value.
-If none of chrominance expressions are specified, they will evaluate
-to the luminance expression.
-
-The expressions can use the following variables and functions:
-
- at table @option
- at item N
-The sequential number of the filtered frame, starting from @code{0}.
-
- at item X
- at item Y
-The coordinates of the current sample.
-
- at item W
- at item H
-The width and height of the image.
-
- at item SW
- at item SH
-Width and height scale depending on the currently filtered plane. It is the
-ratio between the corresponding luma plane number of pixels and the current
-plane ones. E.g. for YUV4:2:0 the values are @code{1,1} for the luma plane, and
- at code{0.5,0.5} for chroma planes.
-
- at item T
-Time of the current frame, expressed in seconds.
-
- at item p(x, y)
-Return the value of the pixel at location (@var{x}, at var{y}) of the current
-plane.
-
- at item lum(x, y)
-Return the value of the pixel at location (@var{x}, at var{y}) of the luminance
-plane.
-
- at item cb(x, y)
-Return the value of the pixel at location (@var{x}, at var{y}) of the
-blue-difference chroma plane. Return 0 if there is no such plane.
-
- at item cr(x, y)
-Return the value of the pixel at location (@var{x}, at var{y}) of the
-red-difference chroma plane. Return 0 if there is no such plane.
-
- at item r(x, y)
- at item g(x, y)
- at item b(x, y)
-Return the value of the pixel at location (@var{x}, at var{y}) of the
-red/green/blue component. Return 0 if there is no such component.
-
- at item alpha(x, y)
-Return the value of the pixel at location (@var{x}, at var{y}) of the alpha
-plane. Return 0 if there is no such plane.
- at end table
-
-For functions, if @var{x} and @var{y} are outside the area, the value will be
-automatically clipped to the closer edge.
-
- at subsection Examples
-
- at itemize
- at item
-Flip the image horizontally:
- at example
-geq=p(W-X\,Y)
- at end example
-
- at item
-Generate a bidimensional sine wave, with angle @code{PI/3} and a
-wavelength of 100 pixels:
- at example
-geq=128 + 100*sin(2*(PI/100)*(cos(PI/3)*(X-50*T) + sin(PI/3)*Y)):128:128
- at end example
-
- at item
-Generate a fancy enigmatic moving light:
- at example
-nullsrc=s=256x256,geq=random(1)/hypot(X-cos(N*0.07)*W/2-W/2\,Y-sin(N*0.09)*H/2-H/2)^2*1000000*sin(N*0.02):128:128
- at end example
-
- at item
-Generate a quick emboss effect:
- at example
-format=gray,geq=lum_expr='(p(X,Y)+(256-p(X-4,Y-4)))/2'
- at end example
-
- at item
-Modify RGB components depending on pixel position:
- at example
-geq=r='X/W*r(X,Y)':g='(1-X/W)*g(X,Y)':b='(H-Y)/H*b(X,Y)'
- at end example
-
- at item
-Create a radial gradient that is the same size as the input (also see
-the @ref{vignette} filter):
- at example
-geq=lum=255*gauss((X/W-0.5)*3)*gauss((Y/H-0.5)*3)/gauss(0)/gauss(0),format=gray
- at end example
-
- at item
-Create a linear gradient to use as a mask for another filter, then
-compose with @ref{overlay}. In this example the video will gradually
-become more blurry from the top to the bottom of the y-axis as defined
-by the linear gradient:
- at example
-ffmpeg -i input.mp4 -filter_complex "geq=lum=255*(Y/H),format=gray[grad];[0:v]boxblur=4[blur];[blur][grad]alphamerge[alpha];[0:v][alpha]overlay" output.mp4
- at end example
- at end itemize
-
- at section gradfun
-
-Fix the banding artifacts that are sometimes introduced into nearly flat
-regions by truncation to 8bit color depth.
-Interpolate the gradients that should go where the bands are, and
-dither them.
-
-It is designed for playback only. Do not use it prior to
-lossy compression, because compression tends to lose the dither and
-bring back the bands.
-
-It accepts the following parameters:
-
- at table @option
-
- at item strength
-The maximum amount by which the filter will change any one pixel. This is also
-the threshold for detecting nearly flat regions. Acceptable values range from
-.51 to 64; the default value is 1.2. Out-of-range values will be clipped to the
-valid range.
-
- at item radius
-The neighborhood to fit the gradient to. A larger radius makes for smoother
-gradients, but also prevents the filter from modifying the pixels near detailed
-regions. Acceptable values are 8-32; the default value is 16. Out-of-range
-values will be clipped to the valid range.
-
- at end table
-
-Alternatively, the options can be specified as a flat string:
- at var{strength}[:@var{radius}]
-
- at subsection Examples
-
- at itemize
- at item
-Apply the filter with a @code{3.5} strength and radius of @code{8}:
- at example
-gradfun=3.5:8
- at end example
-
- at item
-Specify radius, omitting the strength (which will fall-back to the default
-value):
- at example
-gradfun=radius=8
- at end example
-
- at end itemize
-
- at anchor{haldclut}
- at section haldclut
-
-Apply a Hald CLUT to a video stream.
-
-First input is the video stream to process, and second one is the Hald CLUT.
-The Hald CLUT input can be a simple picture or a complete video stream.
-
-The filter accepts the following options:
-
- at table @option
- at item shortest
-Force termination when the shortest input terminates. Default is @code{0}.
- at item repeatlast
-Continue applying the last CLUT after the end of the stream. A value of
- at code{0} disable the filter after the last frame of the CLUT is reached.
-Default is @code{1}.
- at end table
-
- at code{haldclut} also has the same interpolation options as @ref{lut3d} (both
-filters share the same internals).
-
-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}.
-
- at subsection Workflow examples
-
- at subsubsection Hald CLUT video stream
-
-Generate an identity Hald CLUT stream altered with various effects:
- at example
-ffmpeg -f lavfi -i @ref{haldclutsrc}=8 -vf "hue=H=2*PI*t:s=sin(2*PI*t)+1, curves=cross_process" -t 10 -c:v ffv1 clut.nut
- at end example
-
-Note: make sure you use a lossless codec.
-
-Then use it with @code{haldclut} to apply it on some random stream:
- at example
-ffmpeg -f lavfi -i mandelbrot -i clut.nut -filter_complex '[0][1] haldclut' -t 20 mandelclut.mkv
- at end example
-
-The Hald CLUT will be applied to the 10 first seconds (duration of
- at file{clut.nut}), then the latest picture of that CLUT stream will be applied
-to the remaining frames of the @code{mandelbrot} stream.
-
- at subsubsection Hald CLUT with preview
-
-A Hald CLUT is supposed to be a squared image of @code{Level*Level*Level} by
- at code{Level*Level*Level} pixels. For a given Hald CLUT, FFmpeg will select the
-biggest possible square starting at the top left of the picture. The remaining
-padding pixels (bottom or right) will be ignored. This area can be used to add
-a preview of the Hald CLUT.
-
-Typically, the following generated Hald CLUT will be supported by the
- at code{haldclut} filter:
-
- at example
-ffmpeg -f lavfi -i @ref{haldclutsrc}=8 -vf "
- pad=iw+320 [padded_clut];
- smptebars=s=320x256, split [a][b];
- [padded_clut][a] overlay=W-320:h, curves=color_negative [main];
- [main][b] overlay=W-320" -frames:v 1 clut.png
- at end example
-
-It contains the original and a preview of the effect of the CLUT: SMPTE color
-bars are displayed on the right-top, and below the same color bars processed by
-the color changes.
-
-Then, the effect of this Hald CLUT can be visualized with:
- at example
-ffplay input.mkv -vf "movie=clut.png, [in] haldclut"
- at end example
-
- at section hflip
-
-Flip the input video horizontally.
-
-For example, to horizontally flip the input video with @command{ffmpeg}:
- at example
-ffmpeg -i in.avi -vf "hflip" out.avi
- at end example
-
- at section histeq
-This filter applies a global color histogram equalization on a
-per-frame basis.
-
-It can be used to correct video that has a compressed range of pixel
-intensities. The filter redistributes the pixel intensities to
-equalize their distribution across the intensity range. It may be
-viewed as an "automatically adjusting contrast filter". This filter is
-useful only for correcting degraded or poorly captured source
-video.
-
-The filter accepts the following options:
-
- at table @option
- at item strength
-Determine the amount of equalization to be applied. As the strength
-is reduced, the distribution of pixel intensities more-and-more
-approaches that of the input frame. The value must be a float number
-in the range [0,1] and defaults to 0.200.
-
- at item intensity
-Set the maximum intensity that can generated and scale the output
-values appropriately. The strength should be set as desired and then
-the intensity can be limited if needed to avoid washing-out. The value
-must be a float number in the range [0,1] and defaults to 0.210.
-
- at item antibanding
-Set the antibanding level. If enabled the filter will randomly vary
-the luminance of output pixels by a small amount to avoid banding of
-the histogram. Possible values are @code{none}, @code{weak} or
- at code{strong}. It defaults to @code{none}.
- at end table
-
- at section histogram
-
-Compute and draw a color distribution histogram for the input video.
-
-The computed histogram is a representation of the color component
-distribution in an image.
-
-The filter accepts the following options:
-
- at table @option
- at item mode
-Set histogram mode.
-
-It accepts the following values:
- at table @samp
- at item levels
-Standard histogram that displays the color components distribution in an
-image. Displays color graph for each color component. Shows distribution of
-the Y, U, V, A or R, G, B components, depending on input format, in the
-current frame. Below each graph a color component scale meter is shown.
-
- at item color
-Displays chroma values (U/V color placement) in a two dimensional
-graph (which is called a vectorscope). The brighter a pixel in the
-vectorscope, the more pixels of the input frame correspond to that pixel
-(i.e., more pixels have this chroma value). The V component is displayed on
-the horizontal (X) axis, with the leftmost side being V = 0 and the rightmost
-side being V = 255. The U component is displayed on the vertical (Y) axis,
-with the top representing U = 0 and the bottom representing U = 255.
-
-The position of a white pixel in the graph corresponds to the chroma value of
-a pixel of the input clip. The graph can therefore be used to read the hue
-(color flavor) and the saturation (the dominance of the hue in the color). As
-the hue of a color changes, it moves around the square. At the center of the
-square the saturation is zero, which means that the corresponding pixel has no
-color. If the amount of a specific color is increased (while leaving the other
-colors unchanged) the saturation increases, and the indicator moves towards
-the edge of the square.
-
- at item color2
-Chroma values in vectorscope, similar as @code{color} but actual chroma values
-are displayed.
-
- at item waveform
-Per row/column color component graph. In row mode, the graph on the left side
-represents color component value 0 and the right side represents value = 255.
-In column mode, the top side represents color component value = 0 and bottom
-side represents value = 255.
- at end table
-Default value is @code{levels}.
-
- at item level_height
-Set height of level in @code{levels}. Default value is @code{200}.
-Allowed range is [50, 2048].
-
- at item scale_height
-Set height of color scale in @code{levels}. Default value is @code{12}.
-Allowed range is [0, 40].
-
- at item step
-Set step for @code{waveform} mode. Smaller values are useful to find out how
-many values of the same luminance are distributed across input rows/columns.
-Default value is @code{10}. Allowed range is [1, 255].
-
- at item waveform_mode
-Set mode for @code{waveform}. Can be either @code{row}, or @code{column}.
-Default is @code{row}.
-
- at item waveform_mirror
-Set mirroring mode for @code{waveform}. @code{0} means unmirrored, @code{1}
-means mirrored. In mirrored mode, higher values will be represented on the left
-side for @code{row} mode and at the top for @code{column} mode. Default is
- at code{0} (unmirrored).
-
- at item display_mode
-Set display mode for @code{waveform} and @code{levels}.
-It accepts the following values:
- at table @samp
- at item parade
-Display separate graph for the color components side by side in
- at code{row} waveform mode or one below the other in @code{column} waveform mode
-for @code{waveform} histogram mode. For @code{levels} histogram mode,
-per color component graphs are placed below each other.
-
-Using this display mode in @code{waveform} histogram mode makes it easy to
-spot color casts in the highlights and shadows of an image, by comparing the
-contours of the top and the bottom graphs of each waveform. Since whites,
-grays, and blacks are characterized by exactly equal amounts of red, green,
-and blue, neutral areas of the picture should display three waveforms of
-roughly equal width/height. If not, the correction is easy to perform by
-making level adjustments the three waveforms.
-
- at item overlay
-Presents information identical to that in the @code{parade}, except
-that the graphs representing color components are superimposed directly
-over one another.
-
-This display mode in @code{waveform} histogram mode makes it easier to spot
-relative differences or similarities in overlapping areas of the color
-components that are supposed to be identical, such as neutral whites, grays,
-or blacks.
- at end table
-Default is @code{parade}.
-
- at item levels_mode
-Set mode for @code{levels}. Can be either @code{linear}, or @code{logarithmic}.
-Default is @code{linear}.
-
- at item components
-Set what color components to display for mode @code{levels}.
-Default is @code{7}.
- at end table
-
- at subsection Examples
-
- at itemize
-
- at item
-Calculate and draw histogram:
- at example
-ffplay -i input -vf histogram
- at end example
-
- at end itemize
-
- at anchor{hqdn3d}
- at section hqdn3d
-
-This is a high precision/quality 3d denoise filter. It aims to reduce
-image noise, producing smooth images and making still images really
-still. It should enhance compressibility.
-
-It accepts the following optional parameters:
-
- at table @option
- at item luma_spatial
-A non-negative floating point number which specifies spatial luma strength.
-It defaults to 4.0.
-
- at item chroma_spatial
-A non-negative floating point number which specifies spatial chroma strength.
-It defaults to 3.0*@var{luma_spatial}/4.0.
-
- at item luma_tmp
-A floating point number which specifies luma temporal strength. It defaults to
-6.0*@var{luma_spatial}/4.0.
-
- at item chroma_tmp
-A floating point number which specifies chroma temporal strength. It defaults to
- at var{luma_tmp}*@var{chroma_spatial}/@var{luma_spatial}.
- at end table
-
- at section hqx
-
-Apply a high-quality magnification filter designed for pixel art. This filter
-was originally created by Maxim Stepin.
-
-It accepts the following option:
-
- at table @option
- at item n
-Set the scaling dimension: @code{2} for @code{hq2x}, @code{3} for
- at code{hq3x} and @code{4} for @code{hq4x}.
-Default is @code{3}.
- at end table
-
- at section hstack
-Stack input videos horizontally.
-
-All streams must be of same pixel format and of same height.
-
-Note that this filter is faster than using @ref{overlay} and @ref{pad} filter
-to create same output.
-
-The filter accept the following option:
-
- at table @option
- at item nb_inputs
-Set number of input streams. Default is 2.
- at end table
-
- at section hue
-
-Modify the hue and/or the saturation of the input.
-
-It accepts the following parameters:
-
- at table @option
- at item h
-Specify the hue angle as a number of degrees. It accepts an expression,
-and defaults to "0".
-
- at item s
-Specify the saturation in the [-10,10] range. It accepts an expression and
-defaults to "1".
-
- at item H
-Specify the hue angle as a number of radians. It accepts an
-expression, and defaults to "0".
-
- at item b
-Specify the brightness in the [-10,10] range. It accepts an expression and
-defaults to "0".
- at end table
-
- at option{h} and @option{H} are mutually exclusive, and can't be
-specified at the same time.
-
-The @option{b}, @option{h}, @option{H} and @option{s} option values are
-expressions containing the following constants:
-
- at table @option
- at item n
-frame count of the input frame starting from 0
-
- at item pts
-presentation timestamp of the input frame expressed in time base units
-
- at item r
-frame rate of the input video, NAN if the input frame rate is unknown
-
- at item t
-timestamp expressed in seconds, NAN if the input timestamp is unknown
-
- at item tb
-time base of the input video
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Set the hue to 90 degrees and the saturation to 1.0:
- at example
-hue=h=90:s=1
- at end example
-
- at item
-Same command but expressing the hue in radians:
- at example
-hue=H=PI/2:s=1
- at end example
-
- at item
-Rotate hue and make the saturation swing between 0
-and 2 over a period of 1 second:
- at example
-hue="H=2*PI*t: s=sin(2*PI*t)+1"
- at end example
-
- at item
-Apply a 3 seconds saturation fade-in effect starting at 0:
- at example
-hue="s=min(t/3\,1)"
- at end example
-
-The general fade-in expression can be written as:
- at example
-hue="s=min(0\, max((t-START)/DURATION\, 1))"
- at end example
-
- at item
-Apply a 3 seconds saturation fade-out effect starting at 5 seconds:
- at example
-hue="s=max(0\, min(1\, (8-t)/3))"
- at end example
-
-The general fade-out expression can be written as:
- at example
-hue="s=max(0\, min(1\, (START+DURATION-t)/DURATION))"
- at end example
-
- at end itemize
-
- at subsection Commands
-
-This filter supports the following commands:
- at table @option
- at item b
- at item s
- at item h
- at item H
-Modify the hue and/or the saturation and/or brightness of the input video.
-The command accepts the same syntax of the corresponding option.
-
-If the specified expression is not valid, it is kept at its current
-value.
- at end table
-
- at section idet
-
-Detect video interlacing type.
-
-This filter tries to detect if the input frames as interlaced, progressive,
-top or bottom field first. It will also try and detect fields that are
-repeated between adjacent frames (a sign of telecine).
-
-Single frame detection considers only immediately adjacent frames when classifying each frame.
-Multiple frame detection incorporates the classification history of previous frames.
-
-The filter will log these metadata values:
-
- at table @option
- at item single.current_frame
-Detected type of current frame using single-frame detection. One of:
-``tff'' (top field first), ``bff'' (bottom field first),
-``progressive'', or ``undetermined''
-
- at item single.tff
-Cumulative number of frames detected as top field first using single-frame detection.
-
- at item multiple.tff
-Cumulative number of frames detected as top field first using multiple-frame detection.
-
- at item single.bff
-Cumulative number of frames detected as bottom field first using single-frame detection.
-
- at item multiple.current_frame
-Detected type of current frame using multiple-frame detection. One of:
-``tff'' (top field first), ``bff'' (bottom field first),
-``progressive'', or ``undetermined''
-
- at item multiple.bff
-Cumulative number of frames detected as bottom field first using multiple-frame detection.
-
- at item single.progressive
-Cumulative number of frames detected as progressive using single-frame detection.
-
- at item multiple.progressive
-Cumulative number of frames detected as progressive using multiple-frame detection.
-
- at item single.undetermined
-Cumulative number of frames that could not be classified using single-frame detection.
-
- at item multiple.undetermined
-Cumulative number of frames that could not be classified using multiple-frame detection.
-
- at item repeated.current_frame
-Which field in the current frame is repeated from the last. One of ``neither'', ``top'', or ``bottom''.
-
- at item repeated.neither
-Cumulative number of frames with no repeated field.
-
- at item repeated.top
-Cumulative number of frames with the top field repeated from the previous frame's top field.
-
- at item repeated.bottom
-Cumulative number of frames with the bottom field repeated from the previous frame's bottom field.
- at end table
-
-The filter accepts the following options:
-
- at table @option
- at item intl_thres
-Set interlacing threshold.
- at item prog_thres
-Set progressive threshold.
- at item repeat_thres
-Threshold for repeated field detection.
- at item half_life
-Number of frames after which a given frame's contribution to the
-statistics is halved (i.e., it contributes only 0.5 to it's
-classification). The default of 0 means that all frames seen are given
-full weight of 1.0 forever.
- at item analyze_interlaced_flag
-When this is not 0 then idet will use the specified number of frames to determine
-if the interlaced flag is accurate, it will not count undetermined frames.
-If the flag is found to be accurate it will be used without any further
-computations, if it is found to be inaccurate it will be cleared without any
-further computations. This allows inserting the idet filter as a low computational
-method to clean up the interlaced flag
- at end table
-
- at section il
-
-Deinterleave or interleave fields.
-
-This filter allows one to process interlaced images fields without
-deinterlacing them. Deinterleaving splits the input frame into 2
-fields (so called half pictures). Odd lines are moved to the top
-half of the output image, even lines to the bottom half.
-You can process (filter) them independently and then re-interleave them.
-
-The filter accepts the following options:
-
- at table @option
- at item luma_mode, l
- at item chroma_mode, c
- at item alpha_mode, a
-Available values for @var{luma_mode}, @var{chroma_mode} and
- at var{alpha_mode} are:
-
- at table @samp
- at item none
-Do nothing.
-
- at item deinterleave, d
-Deinterleave fields, placing one above the other.
-
- at item interleave, i
-Interleave fields. Reverse the effect of deinterleaving.
- at end table
-Default value is @code{none}.
-
- at item luma_swap, ls
- at item chroma_swap, cs
- at item alpha_swap, as
-Swap luma/chroma/alpha fields. Exchange even & odd lines. Default value is @code{0}.
- at end table
-
- at section inflate
-
-Apply inflate effect to the video.
-
-This filter replaces the pixel by the local(3x3) average by taking into account
-only values higher than the pixel.
-
-It accepts the following options:
-
- at table @option
- at item threshold0
- at item threshold1
- at item threshold2
- at item threshold3
-Limit the maximum change for each plane, default is 65535.
-If 0, plane will remain unchanged.
- at end table
-
- at section interlace
-
-Simple interlacing filter from progressive contents. This interleaves upper (or
-lower) lines from odd frames with lower (or upper) lines from even frames,
-halving the frame rate and preserving image height.
-
- at example
- Original Original New Frame
- Frame 'j' Frame 'j+1' (tff)
- ========== =========== ==================
- Line 0 --------------------> Frame 'j' Line 0
- Line 1 Line 1 ----> Frame 'j+1' Line 1
- Line 2 ---------------------> Frame 'j' Line 2
- Line 3 Line 3 ----> Frame 'j+1' Line 3
- ... ... ...
-New Frame + 1 will be generated by Frame 'j+2' and Frame 'j+3' and so on
- at end example
-
-It accepts the following optional parameters:
-
- at table @option
- at item scan
-This determines whether the interlaced frame is taken from the even
-(tff - default) or odd (bff) lines of the progressive frame.
-
- at item lowpass
-Enable (default) or disable the vertical lowpass filter to avoid twitter
-interlacing and reduce moire patterns.
- at end table
-
- at section kerndeint
-
-Deinterlace input video by applying Donald Graft's adaptive kernel
-deinterling. Work on interlaced parts of a video to produce
-progressive frames.
-
-The description of the accepted parameters follows.
-
- at table @option
- at item thresh
-Set the threshold which affects the filter's tolerance when
-determining if a pixel line must be processed. It must be an integer
-in the range [0,255] and defaults to 10. A value of 0 will result in
-applying the process on every pixels.
-
- at item map
-Paint pixels exceeding the threshold value to white if set to 1.
-Default is 0.
-
- at item order
-Set the fields order. Swap fields if set to 1, leave fields alone if
-0. Default is 0.
-
- at item sharp
-Enable additional sharpening if set to 1. Default is 0.
-
- at item twoway
-Enable twoway sharpening if set to 1. Default is 0.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Apply default values:
- at example
-kerndeint=thresh=10:map=0:order=0:sharp=0:twoway=0
- at end example
-
- at item
-Enable additional sharpening:
- at example
-kerndeint=sharp=1
- at end example
-
- at item
-Paint processed pixels in white:
- at example
-kerndeint=map=1
- at end example
- at end itemize
-
- at section lenscorrection
-
-Correct radial lens distortion
-
-This filter can be used to correct for radial distortion as can result from the use
-of wide angle lenses, and thereby re-rectify the image. To find the right parameters
-one can use tools available for example as part of opencv or simply trial-and-error.
-To use opencv use the calibration sample (under samples/cpp) from the opencv sources
-and extract the k1 and k2 coefficients from the resulting matrix.
-
-Note that effectively the same filter is available in the open-source tools Krita and
-Digikam from the KDE project.
-
-In contrast to the @ref{vignette} filter, which can also be used to compensate lens errors,
-this filter corrects the distortion of the image, whereas @ref{vignette} corrects the
-brightness distribution, so you may want to use both filters together in certain
-cases, though you will have to take care of ordering, i.e. whether vignetting should
-be applied before or after lens correction.
-
- at subsection Options
-
-The filter accepts the following options:
-
- at table @option
- at item cx
-Relative x-coordinate of the focal point of the image, and thereby the center of the
-distortion. This value has a range [0,1] and is expressed as fractions of the image
-width.
- at item cy
-Relative y-coordinate of the focal point of the image, and thereby the center of the
-distortion. This value has a range [0,1] and is expressed as fractions of the image
-height.
- at item k1
-Coefficient of the quadratic correction term. 0.5 means no correction.
- at item k2
-Coefficient of the double quadratic correction term. 0.5 means no correction.
- at end table
-
-The formula that generates the correction is:
-
- at var{r_src} = @var{r_tgt} * (1 + @var{k1} * (@var{r_tgt} / @var{r_0})^2 + @var{k2} * (@var{r_tgt} / @var{r_0})^4)
-
-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.
-
- at anchor{lut3d}
- at section lut3d
-
-Apply a 3D LUT to an input video.
-
-The filter accepts the following options:
-
- at table @option
- at item file
-Set the 3D LUT file name.
-
-Currently supported formats:
- at table @samp
- at item 3dl
-AfterEffects
- at item cube
-Iridas
- at item dat
-DaVinci
- at item m3d
-Pandora
- at end table
- at item interp
-Select interpolation mode.
-
-Available values are:
-
- at table @samp
- at item nearest
-Use values from the nearest defined point.
- at item trilinear
-Interpolate values using the 8 points defining a cube.
- at item tetrahedral
-Interpolate values using a tetrahedron.
- at end table
- at end table
-
- at section lut, lutrgb, lutyuv
-
-Compute a look-up table for binding each pixel component input value
-to an output value, and apply it to the input video.
-
- at var{lutyuv} applies a lookup table to a YUV input video, @var{lutrgb}
-to an RGB input video.
-
-These filters accept the following parameters:
- at table @option
- at item c0
-set first pixel component expression
- at item c1
-set second pixel component expression
- at item c2
-set third pixel component expression
- at item c3
-set fourth pixel component expression, corresponds to the alpha component
-
- at item r
-set red component expression
- at item g
-set green component expression
- at item b
-set blue component expression
- at item a
-alpha component expression
-
- at item y
-set Y/luminance component expression
- at item u
-set U/Cb component expression
- at item v
-set V/Cr component expression
- at end table
-
-Each of them specifies the expression to use for computing the lookup table for
-the corresponding pixel component values.
-
-The exact component associated to each of the @var{c*} options depends on the
-format in input.
-
-The @var{lut} filter requires either YUV or RGB pixel formats in input,
- at var{lutrgb} requires RGB pixel formats in input, and @var{lutyuv} requires YUV.
-
-The expressions can contain the following constants and functions:
-
- at table @option
- at item w
- at item h
-The input width and height.
-
- at item val
-The input value for the pixel component.
-
- at item clipval
-The input value, clipped to the @var{minval}- at var{maxval} range.
-
- at item maxval
-The maximum value for the pixel component.
-
- at item minval
-The minimum value for the pixel component.
-
- at item negval
-The negated value for the pixel component value, clipped to the
- at var{minval}- at var{maxval} range; it corresponds to the expression
-"maxval-clipval+minval".
-
- at item clip(val)
-The computed value in @var{val}, clipped to the
- at var{minval}- at var{maxval} range.
-
- at item gammaval(gamma)
-The computed gamma correction value of the pixel component value,
-clipped to the @var{minval}- at var{maxval} range. It corresponds to the
-expression
-"pow((clipval-minval)/(maxval-minval)\, at var{gamma})*(maxval-minval)+minval"
-
- at end table
-
-All expressions default to "val".
-
- at subsection Examples
-
- at itemize
- at item
-Negate input video:
- at example
-lutrgb="r=maxval+minval-val:g=maxval+minval-val:b=maxval+minval-val"
-lutyuv="y=maxval+minval-val:u=maxval+minval-val:v=maxval+minval-val"
- at end example
-
-The above is the same as:
- at example
-lutrgb="r=negval:g=negval:b=negval"
-lutyuv="y=negval:u=negval:v=negval"
- at end example
-
- at item
-Negate luminance:
- at example
-lutyuv=y=negval
- at end example
-
- at item
-Remove chroma components, turning the video into a graytone image:
- at example
-lutyuv="u=128:v=128"
- at end example
-
- at item
-Apply a luma burning effect:
- at example
-lutyuv="y=2*val"
- at end example
-
- at item
-Remove green and blue components:
- at example
-lutrgb="g=0:b=0"
- at end example
-
- at item
-Set a constant alpha channel value on input:
- at example
-format=rgba,lutrgb=a="maxval-minval/2"
- at end example
-
- at item
-Correct luminance gamma by a factor of 0.5:
- at example
-lutyuv=y=gammaval(0.5)
- at end example
-
- at item
-Discard least significant bits of luma:
- at example
-lutyuv=y='bitand(val, 128+64+32)'
- at end example
- at end itemize
-
- at section mergeplanes
-
-Merge color channel components from several video streams.
-
-The filter accepts up to 4 input streams, and merge selected input
-planes to the output video.
-
-This filter accepts the following options:
- at table @option
- at item mapping
-Set input to output plane mapping. Default is @code{0}.
-
-The mappings is specified as a bitmap. It should be specified as a
-hexadecimal number in the form 0xAa[Bb[Cc[Dd]]]. 'Aa' describes the
-mapping for the first plane of the output stream. 'A' sets the number of
-the input stream to use (from 0 to 3), and 'a' the plane number of the
-corresponding input to use (from 0 to 3). The rest of the mappings is
-similar, 'Bb' describes the mapping for the output stream second
-plane, 'Cc' describes the mapping for the output stream third plane and
-'Dd' describes the mapping for the output stream fourth plane.
-
- at item format
-Set output pixel format. Default is @code{yuva444p}.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Merge three gray video streams of same width and height into single video stream:
- at example
-[a0][a1][a2]mergeplanes=0x001020:yuv444p
- at end example
-
- at item
-Merge 1st yuv444p stream and 2nd gray video stream into yuva444p video stream:
- at example
-[a0][a1]mergeplanes=0x00010210:yuva444p
- at end example
-
- at item
-Swap Y and A plane in yuva444p stream:
- at example
-format=yuva444p,mergeplanes=0x03010200:yuva444p
- at end example
-
- at item
-Swap U and V plane in yuv420p stream:
- at example
-format=yuv420p,mergeplanes=0x000201:yuv420p
- at end example
-
- at item
-Cast a rgb24 clip to yuv444p:
- at example
-format=rgb24,mergeplanes=0x000102:yuv444p
- at end example
- at end itemize
-
- at section mcdeint
-
-Apply motion-compensation deinterlacing.
-
-It needs one field per frame as input and must thus be used together
-with yadif=1/3 or equivalent.
-
-This filter accepts the following options:
- at table @option
- at item mode
-Set the deinterlacing mode.
-
-It accepts one of the following values:
- at table @samp
- at item fast
- at item medium
- at item slow
-use iterative motion estimation
- at item extra_slow
-like @samp{slow}, but use multiple reference frames.
- at end table
-Default value is @samp{fast}.
-
- at item parity
-Set the picture field parity assumed for the input video. It must be
-one of the following values:
-
- at table @samp
- at item 0, tff
-assume top field first
- at item 1, bff
-assume bottom field first
- at end table
-
-Default value is @samp{bff}.
-
- at item qp
-Set per-block quantization parameter (QP) used by the internal
-encoder.
-
-Higher values should result in a smoother motion vector field but less
-optimal individual vectors. Default value is 1.
- at end table
-
- at section mpdecimate
-
-Drop frames that do not differ greatly from the previous frame in
-order to reduce frame rate.
-
-The main use of this filter is for very-low-bitrate encoding
-(e.g. streaming over dialup modem), but it could in theory be used for
-fixing movies that were inverse-telecined incorrectly.
-
-A description of the accepted options follows.
-
- at table @option
- at item max
-Set the maximum number of consecutive frames which can be dropped (if
-positive), or the minimum interval between dropped frames (if
-negative). If the value is 0, the frame is dropped unregarding the
-number of previous sequentially dropped frames.
-
-Default value is 0.
-
- at item hi
- at item lo
- at item frac
-Set the dropping threshold values.
-
-Values for @option{hi} and @option{lo} are for 8x8 pixel blocks and
-represent actual pixel value differences, so a threshold of 64
-corresponds to 1 unit of difference for each pixel, or the same spread
-out differently over the block.
-
-A frame is a candidate for dropping if no 8x8 blocks differ by more
-than a threshold of @option{hi}, and if no more than @option{frac} blocks (1
-meaning the whole image) differ by more than a threshold of @option{lo}.
-
-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.
- at end table
-
-
- at section negate
-
-Negate input video.
-
-It accepts an integer in input; if non-zero it negates the
-alpha component (if available). The default value in input is 0.
-
- at section noformat
-
-Force libavfilter not to use any of the specified pixel formats for the
-input to the next filter.
-
-It accepts the following parameters:
- at table @option
-
- at item pix_fmts
-A '|'-separated list of pixel format names, such as
-apix_fmts=yuv420p|monow|rgb24".
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Force libavfilter to use a format different from @var{yuv420p} for the
-input to the vflip filter:
- at example
-noformat=pix_fmts=yuv420p,vflip
- at end example
-
- at item
-Convert the input video to any of the formats not contained in the list:
- at example
-noformat=yuv420p|yuv444p|yuv410p
- at end example
- at end itemize
-
- at section noise
-
-Add noise on video input frame.
-
-The filter accepts the following options:
-
- at table @option
- at item all_seed
- at item c0_seed
- at item c1_seed
- at item c2_seed
- at item c3_seed
-Set noise seed for specific pixel component or all pixel components in case
-of @var{all_seed}. Default value is @code{123457}.
-
- at item all_strength, alls
- at item c0_strength, c0s
- at item c1_strength, c1s
- at item c2_strength, c2s
- at item c3_strength, c3s
-Set noise strength for specific pixel component or all pixel components in case
- at var{all_strength}. Default value is @code{0}. Allowed range is [0, 100].
-
- at item all_flags, allf
- at item c0_flags, c0f
- at item c1_flags, c1f
- at item c2_flags, c2f
- at item c3_flags, c3f
-Set pixel component flags or set flags for all components if @var{all_flags}.
-Available values for component flags are:
- at table @samp
- at item a
-averaged temporal noise (smoother)
- at item p
-mix random noise with a (semi)regular pattern
- at item t
-temporal noise (noise pattern changes between frames)
- at item u
-uniform noise (gaussian otherwise)
- at end table
- at end table
-
- at subsection Examples
-
-Add temporal and uniform noise to input video:
- at example
-noise=alls=20:allf=t+u
- at end example
-
- at section null
-
-Pass the video source unchanged to the output.
-
- at section ocv
-
-Apply a video transform using libopencv.
-
-To enable this filter, install the libopencv library and headers and
-configure FFmpeg with @code{--enable-libopencv}.
-
-It accepts the following parameters:
-
- at table @option
-
- at item filter_name
-The name of the libopencv filter to apply.
-
- at item filter_params
-The parameters to pass to the libopencv filter. If not specified, the default
-values are assumed.
-
- at end table
-
-Refer to the official libopencv documentation for more precise
-information:
- at url{http://docs.opencv.org/master/modules/imgproc/doc/filtering.html}
-
-Several libopencv filters are supported; see the following subsections.
-
- at anchor{dilate}
- at subsection dilate
-
-Dilate an image by using a specific structuring element.
-It corresponds to the libopencv function @code{cvDilate}.
-
-It accepts the parameters: @var{struct_el}|@var{nb_iterations}.
-
- at var{struct_el} represents a structuring element, and has the syntax:
- at var{cols}x at var{rows}+ at var{anchor_x}x at var{anchor_y}/@var{shape}
-
- at var{cols} and @var{rows} represent the number of columns and rows of
-the structuring element, @var{anchor_x} and @var{anchor_y} the anchor
-point, and @var{shape} the shape for the structuring element. @var{shape}
-must be "rect", "cross", "ellipse", or "custom".
-
-If the value for @var{shape} is "custom", it must be followed by a
-string of the form "=@var{filename}". The file with name
- at var{filename} is assumed to represent a binary image, with each
-printable character corresponding to a bright pixel. When a custom
- at var{shape} is used, @var{cols} and @var{rows} are ignored, the number
-or columns and rows of the read file are assumed instead.
-
-The default value for @var{struct_el} is "3x3+0x0/rect".
-
- at var{nb_iterations} specifies the number of times the transform is
-applied to the image, and defaults to 1.
-
-Some examples:
- at example
-# Use the default values
-ocv=dilate
-
-# Dilate using a structuring element with a 5x5 cross, iterating two times
-ocv=filter_name=dilate:filter_params=5x5+2x2/cross|2
-
-# Read the shape from the file diamond.shape, iterating two times.
-# The file diamond.shape may contain a pattern of characters like this
-# *
-# ***
-# *****
-# ***
-# *
-# The specified columns and rows are ignored
-# but the anchor point coordinates are not
-ocv=dilate:0x0+2x2/custom=diamond.shape|2
- at end example
-
- at subsection erode
-
-Erode an image by using a specific structuring element.
-It corresponds to the libopencv function @code{cvErode}.
-
-It accepts the parameters: @var{struct_el}:@var{nb_iterations},
-with the same syntax and semantics as the @ref{dilate} filter.
-
- at subsection smooth
-
-Smooth the input video.
-
-The filter takes the following parameters:
- at var{type}|@var{param1}|@var{param2}|@var{param3}|@var{param4}.
-
- at var{type} is the type of smooth filter to apply, and must be one of
-the following values: "blur", "blur_no_scale", "median", "gaussian",
-or "bilateral". The default value is "gaussian".
-
-The meaning of @var{param1}, @var{param2}, @var{param3}, and @var{param4}
-depend on the smooth type. @var{param1} and
- at var{param2} accept integer positive values or 0. @var{param3} and
- at var{param4} accept floating point values.
-
-The default value for @var{param1} is 3. The default value for the
-other parameters is 0.
-
-These parameters correspond to the parameters assigned to the
-libopencv function @code{cvSmooth}.
-
- at anchor{overlay}
- at section overlay
-
-Overlay one video on top of another.
-
-It takes two inputs and has one output. The first input is the "main"
-video on which the second input is overlaid.
-
-It accepts the following parameters:
-
-A description of the accepted options follows.
-
- at table @option
- at item x
- at item y
-Set the expression for the x and y coordinates of the overlaid video
-on the main video. Default value is "0" for both expressions. In case
-the expression is invalid, it is set to a huge value (meaning that the
-overlay will not be displayed within the output visible area).
-
- at item eof_action
-The action to take when EOF is encountered on the secondary input; it accepts
-one of the following values:
-
- at table @option
- at item repeat
-Repeat the last frame (the default).
- at item endall
-End both streams.
- at item pass
-Pass the main input through.
- at end table
-
- at item eval
-Set when the expressions for @option{x}, and @option{y} are evaluated.
-
-It accepts the following values:
- at table @samp
- at item init
-only evaluate expressions once during the filter initialization or
-when a command is processed
-
- at item frame
-evaluate expressions for each incoming frame
- at end table
-
-Default value is @samp{frame}.
-
- at item shortest
-If set to 1, force the output to terminate when the shortest input
-terminates. Default value is 0.
-
- at item format
-Set the format for the output video.
-
-It accepts the following values:
- at table @samp
- at item yuv420
-force YUV420 output
-
- at item yuv422
-force YUV422 output
-
- at item yuv444
-force YUV444 output
-
- at item rgb
-force RGB output
- at end table
-
-Default value is @samp{yuv420}.
-
- at item rgb @emph{(deprecated)}
-If set to 1, force the filter to accept inputs in the RGB
-color space. Default value is 0. This option is deprecated, use
- at option{format} instead.
-
- at item repeatlast
-If set to 1, force the filter to draw the last overlay frame over the
-main input until the end of the stream. A value of 0 disables this
-behavior. Default value is 1.
- at end table
-
-The @option{x}, and @option{y} expressions can contain the following
-parameters.
-
- at table @option
- at item main_w, W
- at item main_h, H
-The main input width and height.
-
- at item overlay_w, w
- at item overlay_h, h
-The overlay input width and height.
-
- at item x
- at item y
-The computed values for @var{x} and @var{y}. They are evaluated for
-each new frame.
-
- at item hsub
- at item vsub
-horizontal and vertical chroma subsample values of the output
-format. For example for the pixel format "yuv422p" @var{hsub} is 2 and
- at var{vsub} is 1.
-
- at item n
-the number of input frame, starting from 0
-
- at item pos
-the position in the file of the input frame, NAN if unknown
-
- at item t
-The timestamp, expressed in seconds. It's NAN if the input timestamp is unknown.
-
- at end table
-
-Note that the @var{n}, @var{pos}, @var{t} variables are available only
-when evaluation is done @emph{per frame}, and will evaluate to NAN
-when @option{eval} is set to @samp{init}.
-
-Be aware that frames are taken from each input video in timestamp
-order, hence, if their initial timestamps differ, it is a good idea
-to pass the two inputs through a @var{setpts=PTS-STARTPTS} filter to
-have them begin in the same zero timestamp, as the example for
-the @var{movie} filter does.
-
-You can chain together more overlays but you should test the
-efficiency of such approach.
-
- at subsection Commands
-
-This filter supports the following commands:
- at table @option
- at item x
- at item y
-Modify the x and y of the overlay input.
-The command accepts the same syntax of the corresponding option.
-
-If the specified expression is not valid, it is kept at its current
-value.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Draw the overlay at 10 pixels from the bottom right corner of the main
-video:
- at example
-overlay=main_w-overlay_w-10:main_h-overlay_h-10
- at end example
-
-Using named options the example above becomes:
- at example
-overlay=x=main_w-overlay_w-10:y=main_h-overlay_h-10
- at end example
-
- at item
-Insert a transparent PNG logo in the bottom left corner of the input,
-using the @command{ffmpeg} tool with the @code{-filter_complex} option:
- at example
-ffmpeg -i input -i logo -filter_complex 'overlay=10:main_h-overlay_h-10' output
- at end example
-
- at item
-Insert 2 different transparent PNG logos (second logo on bottom
-right corner) using the @command{ffmpeg} tool:
- at example
-ffmpeg -i input -i logo1 -i logo2 -filter_complex 'overlay=x=10:y=H-h-10,overlay=x=W-w-10:y=H-h-10' output
- at end example
-
- at item
-Add a transparent color layer on top of the main video; @code{WxH}
-must specify the size of the main input to the overlay filter:
- at example
-color=color=red@@.3:size=WxH [over]; [in][over] overlay [out]
- at end example
-
- at item
-Play an original video and a filtered version (here with the deshake
-filter) side by side using the @command{ffplay} tool:
- at example
-ffplay input.avi -vf 'split[a][b]; [a]pad=iw*2:ih[src]; [b]deshake[filt]; [src][filt]overlay=w'
- at end example
-
-The above command is the same as:
- at example
-ffplay input.avi -vf 'split[b], pad=iw*2[src], [b]deshake, [src]overlay=w'
- at end example
-
- at item
-Make a sliding overlay appearing from the left to the right top part of the
-screen starting since time 2:
- at example
-overlay=x='if(gte(t,2), -w+(t-2)*20, NAN)':y=0
- at end example
-
- at item
-Compose output by putting two input videos side to side:
- at example
-ffmpeg -i left.avi -i right.avi -filter_complex "
-nullsrc=size=200x100 [background];
-[0:v] setpts=PTS-STARTPTS, scale=100x100 [left];
-[1:v] setpts=PTS-STARTPTS, scale=100x100 [right];
-[background][left] overlay=shortest=1 [background+left];
-[background+left][right] overlay=shortest=1:x=100 [left+right]
-"
- at end example
-
- at item
-Mask 10-20 seconds of a video by applying the delogo filter to a section
- at example
-ffmpeg -i test.avi -codec:v:0 wmv2 -ar 11025 -b:v 9000k
--vf '[in]split[split_main][split_delogo];[split_delogo]trim=start=360:end=371,delogo=0:0:640:480[delogoed];[split_main][delogoed]overlay=eof_action=pass[out]'
-masked.avi
- at end example
-
- at item
-Chain several overlays in cascade:
- at example
-nullsrc=s=200x200 [bg];
-testsrc=s=100x100, split=4 [in0][in1][in2][in3];
-[in0] lutrgb=r=0, [bg] overlay=0:0 [mid0];
-[in1] lutrgb=g=0, [mid0] overlay=100:0 [mid1];
-[in2] lutrgb=b=0, [mid1] overlay=0:100 [mid2];
-[in3] null, [mid2] overlay=100:100 [out0]
- at end example
-
- at end itemize
-
- at section owdenoise
-
-Apply Overcomplete Wavelet denoiser.
-
-The filter accepts the following options:
-
- at table @option
- at item depth
-Set depth.
-
-Larger depth values will denoise lower frequency components more, but
-slow down filtering.
-
-Must be an int in the range 8-16, default is @code{8}.
-
- at item luma_strength, ls
-Set luma strength.
-
-Must be a double value in the range 0-1000, default is @code{1.0}.
-
- at item chroma_strength, cs
-Set chroma strength.
-
-Must be a double value in the range 0-1000, default is @code{1.0}.
- at end table
-
- at anchor{pad}
- at section pad
-
-Add paddings to the input image, and place the original input at the
-provided @var{x}, @var{y} coordinates.
-
-It accepts the following parameters:
-
- at table @option
- at item width, w
- at item height, h
-Specify an expression for the size of the output image with the
-paddings added. If the value for @var{width} or @var{height} is 0, the
-corresponding input size is used for the output.
-
-The @var{width} expression can reference the value set by the
- at var{height} expression, and vice versa.
-
-The default value of @var{width} and @var{height} is 0.
-
- at item x
- at item y
-Specify the offsets to place the input image at within the padded area,
-with respect to the top/left border of the output image.
-
-The @var{x} expression can reference the value set by the @var{y}
-expression, and vice versa.
-
-The default value of @var{x} and @var{y} is 0.
-
- at item color
-Specify the color of the padded area. For the syntax of this option,
-check the "Color" section in the ffmpeg-utils manual.
-
-The default value of @var{color} is "black".
- at end table
-
-The value for the @var{width}, @var{height}, @var{x}, and @var{y}
-options are expressions containing the following constants:
-
- at table @option
- at item in_w
- at item in_h
-The input video width and height.
-
- at item iw
- at item ih
-These are the same as @var{in_w} and @var{in_h}.
-
- at item out_w
- at item out_h
-The output width and height (the size of the padded area), as
-specified by the @var{width} and @var{height} expressions.
-
- at item ow
- at item oh
-These are the same as @var{out_w} and @var{out_h}.
-
- at item x
- at item y
-The x and y offsets as specified by the @var{x} and @var{y}
-expressions, or NAN if not yet specified.
-
- at item a
-same as @var{iw} / @var{ih}
-
- at item sar
-input sample aspect ratio
-
- at item dar
-input display aspect ratio, it is the same as (@var{iw} / @var{ih}) * @var{sar}
-
- at item hsub
- at item vsub
-The horizontal and vertical chroma subsample values. For example for the
-pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Add paddings with the color "violet" to the input video. The output video
-size is 640x480, and the top-left corner of the input video is placed at
-column 0, row 40
- at example
-pad=640:480:0:40:violet
- at end example
-
-The example above is equivalent to the following command:
- at example
-pad=width=640:height=480:x=0:y=40:color=violet
- at end example
-
- at item
-Pad the input to get an output with dimensions increased by 3/2,
-and put the input video at the center of the padded area:
- at example
-pad="3/2*iw:3/2*ih:(ow-iw)/2:(oh-ih)/2"
- at end example
-
- at item
-Pad the input to get a squared output with size equal to the maximum
-value between the input width and height, and put the input video at
-the center of the padded area:
- at example
-pad="max(iw\,ih):ow:(ow-iw)/2:(oh-ih)/2"
- at end example
-
- at item
-Pad the input to get a final w/h ratio of 16:9:
- at example
-pad="ih*16/9:ih:(ow-iw)/2:(oh-ih)/2"
- at end example
-
- at item
-In case of anamorphic video, in order to set the output display aspect
-correctly, it is necessary to use @var{sar} in the expression,
-according to the relation:
- at example
-(ih * X / ih) * sar = output_dar
-X = output_dar / sar
- at end example
-
-Thus the previous example needs to be modified to:
- at example
-pad="ih*16/9/sar:ih:(ow-iw)/2:(oh-ih)/2"
- at end example
-
- at item
-Double the output size and put the input video in the bottom-right
-corner of the output padded area:
- at example
-pad="2*iw:2*ih:ow-iw:oh-ih"
- at end example
- at end itemize
-
- at anchor{palettegen}
- at section palettegen
-
-Generate one palette for a whole video stream.
-
-It accepts the following options:
-
- at table @option
- at item max_colors
-Set the maximum number of colors to quantize in the palette.
-Note: the palette will still contain 256 colors; the unused palette entries
-will be black.
-
- at item reserve_transparent
-Create a palette of 255 colors maximum and reserve the last one for
-transparency. Reserving the transparency color is useful for GIF optimization.
-If not set, the maximum of colors in the palette will be 256. You probably want
-to disable this option for a standalone image.
-Set by default.
-
- at item stats_mode
-Set statistics mode.
-
-It accepts the following values:
- at table @samp
- at item full
-Compute full frame histograms.
- at item diff
-Compute histograms only for the part that differs from previous frame. This
-might be relevant to give more importance to the moving part of your input if
-the background is static.
- at end table
-
-Default value is @var{full}.
- at end table
-
-The filter also exports the frame metadata @code{lavfi.color_quant_ratio}
-(@code{nb_color_in / nb_color_out}) which you can use to evaluate the degree of
-color quantization of the palette. This information is also visible at
- at var{info} logging level.
-
- at subsection Examples
-
- at itemize
- at item
-Generate a representative palette of a given video using @command{ffmpeg}:
- at example
-ffmpeg -i input.mkv -vf palettegen palette.png
- at end example
- at end itemize
-
- at section paletteuse
-
-Use a palette to downsample an input video stream.
-
-The filter takes two inputs: one video stream and a palette. The palette must
-be a 256 pixels image.
-
-It accepts the following options:
-
- at table @option
- at item dither
-Select dithering mode. Available algorithms are:
- at table @samp
- at item bayer
-Ordered 8x8 bayer dithering (deterministic)
- at item heckbert
-Dithering as defined by Paul Heckbert in 1982 (simple error diffusion).
-Note: this dithering is sometimes considered "wrong" and is included as a
-reference.
- at item floyd_steinberg
-Floyd and Steingberg dithering (error diffusion)
- at item sierra2
-Frankie Sierra dithering v2 (error diffusion)
- at item sierra2_4a
-Frankie Sierra dithering v2 "Lite" (error diffusion)
- at end table
-
-Default is @var{sierra2_4a}.
-
- at item bayer_scale
-When @var{bayer} dithering is selected, this option defines the scale of the
-pattern (how much the crosshatch pattern is visible). A low value means more
-visible pattern for less banding, and higher value means less visible pattern
-at the cost of more banding.
-
-The option must be an integer value in the range [0,5]. Default is @var{2}.
-
- at item diff_mode
-If set, define the zone to process
-
- at table @samp
- at item rectangle
-Only the changing rectangle will be reprocessed. This is similar to GIF
-cropping/offsetting compression mechanism. This option can be useful for speed
-if only a part of the image is changing, and has use cases such as limiting the
-scope of the error diffusal @option{dither} to the rectangle that bounds the
-moving scene (it leads to more deterministic output if the scene doesn't change
-much, and as a result less moving noise and better GIF compression).
- at end table
-
-Default is @var{none}.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Use a palette (generated for example with @ref{palettegen}) to encode a GIF
-using @command{ffmpeg}:
- at example
-ffmpeg -i input.mkv -i palette.png -lavfi paletteuse output.gif
- at end example
- at end itemize
-
- at section perspective
-
-Correct perspective of video not recorded perpendicular to the screen.
-
-A description of the accepted parameters follows.
-
- at table @option
- at item x0
- at item y0
- at item x1
- at item y1
- at item x2
- at item y2
- at item x3
- at item y3
-Set coordinates expression for top left, top right, bottom left and bottom right corners.
-Default values are @code{0:0:W:0:0:H:W:H} with which perspective will remain unchanged.
-If the @code{sense} option is set to @code{source}, then the specified points will be sent
-to the corners of the destination. If the @code{sense} option is set to @code{destination},
-then the corners of the source will be sent to the specified coordinates.
-
-The expressions can use the following variables:
-
- at table @option
- at item W
- at item H
-the width and height of video frame.
- at end table
-
- at item interpolation
-Set interpolation for perspective correction.
-
-It accepts the following values:
- at table @samp
- at item linear
- at item cubic
- at end table
-
-Default value is @samp{linear}.
-
- at item sense
-Set interpretation of coordinate options.
-
-It accepts the following values:
- at table @samp
- at item 0, source
-
-Send point in the source specified by the given coordinates to
-the corners of the destination.
-
- at item 1, destination
-
-Send the corners of the source to the point in the destination specified
-by the given coordinates.
-
-Default value is @samp{source}.
- at end table
- at end table
-
- at section phase
-
-Delay interlaced video by one field time so that the field order changes.
-
-The intended use is to fix PAL movies that have been captured with the
-opposite field order to the film-to-video transfer.
-
-A description of the accepted parameters follows.
-
- at table @option
- at item mode
-Set phase mode.
-
-It accepts the following values:
- at table @samp
- at item t
-Capture field order top-first, transfer bottom-first.
-Filter will delay the bottom field.
-
- at item b
-Capture field order bottom-first, transfer top-first.
-Filter will delay the top field.
-
- at item p
-Capture and transfer with the same field order. This mode only exists
-for the documentation of the other options to refer to, but if you
-actually select it, the filter will faithfully do nothing.
-
- at item a
-Capture field order determined automatically by field flags, transfer
-opposite.
-Filter selects among @samp{t} and @samp{b} modes on a frame by frame
-basis using field flags. If no field information is available,
-then this works just like @samp{u}.
-
- at item u
-Capture unknown or varying, transfer opposite.
-Filter selects among @samp{t} and @samp{b} on a frame by frame basis by
-analyzing the images and selecting the alternative that produces best
-match between the fields.
-
- at item T
-Capture top-first, transfer unknown or varying.
-Filter selects among @samp{t} and @samp{p} using image analysis.
-
- at item B
-Capture bottom-first, transfer unknown or varying.
-Filter selects among @samp{b} and @samp{p} using image analysis.
-
- at item A
-Capture determined by field flags, transfer unknown or varying.
-Filter selects among @samp{t}, @samp{b} and @samp{p} using field flags and
-image analysis. If no field information is available, then this works just
-like @samp{U}. This is the default mode.
-
- at item U
-Both capture and transfer unknown or varying.
-Filter selects among @samp{t}, @samp{b} and @samp{p} using image analysis only.
- at end table
- at end table
-
- at section pixdesctest
-
-Pixel format descriptor test filter, mainly useful for internal
-testing. The output video should be equal to the input video.
-
-For example:
- at example
-format=monow, pixdesctest
- at end example
-
-can be used to test the monowhite pixel format descriptor definition.
-
- at section pp
-
-Enable the specified chain of postprocessing subfilters using libpostproc. This
-library should be automatically selected with a GPL build (@code{--enable-gpl}).
-Subfilters must be separated by '/' and can be disabled by prepending a '-'.
-Each subfilter and some options have a short and a long name that can be used
-interchangeably, i.e. dr/dering are the same.
-
-The filters accept the following options:
-
- at table @option
- at item subfilters
-Set postprocessing subfilters string.
- at end table
-
-All subfilters share common options to determine their scope:
-
- at table @option
- at item a/autoq
-Honor the quality commands for this subfilter.
-
- at item c/chrom
-Do chrominance filtering, too (default).
-
- at item y/nochrom
-Do luminance filtering only (no chrominance).
-
- at item n/noluma
-Do chrominance filtering only (no luminance).
- at end table
-
-These options can be appended after the subfilter name, separated by a '|'.
-
-Available subfilters are:
-
- at table @option
- at item hb/hdeblock[|difference[|flatness]]
-Horizontal deblocking filter
- at table @option
- at item difference
-Difference factor where higher values mean more deblocking (default: @code{32}).
- at item flatness
-Flatness threshold where lower values mean more deblocking (default: @code{39}).
- at end table
-
- at item vb/vdeblock[|difference[|flatness]]
-Vertical deblocking filter
- at table @option
- at item difference
-Difference factor where higher values mean more deblocking (default: @code{32}).
- at item flatness
-Flatness threshold where lower values mean more deblocking (default: @code{39}).
- at end table
-
- at item ha/hadeblock[|difference[|flatness]]
-Accurate horizontal deblocking filter
- at table @option
- at item difference
-Difference factor where higher values mean more deblocking (default: @code{32}).
- at item flatness
-Flatness threshold where lower values mean more deblocking (default: @code{39}).
- at end table
-
- at item va/vadeblock[|difference[|flatness]]
-Accurate vertical deblocking filter
- at table @option
- at item difference
-Difference factor where higher values mean more deblocking (default: @code{32}).
- at item flatness
-Flatness threshold where lower values mean more deblocking (default: @code{39}).
- at end table
- at end table
-
-The horizontal and vertical deblocking filters share the difference and
-flatness values so you cannot set different horizontal and vertical
-thresholds.
-
- at table @option
- at item h1/x1hdeblock
-Experimental horizontal deblocking filter
-
- at item v1/x1vdeblock
-Experimental vertical deblocking filter
-
- at item dr/dering
-Deringing filter
-
- at item tn/tmpnoise[|threshold1[|threshold2[|threshold3]]], temporal noise reducer
- at table @option
- at item threshold1
-larger -> stronger filtering
- at item threshold2
-larger -> stronger filtering
- at item threshold3
-larger -> stronger filtering
- at end table
-
- at item al/autolevels[:f/fullyrange], automatic brightness / contrast correction
- at table @option
- at item f/fullyrange
-Stretch luminance to @code{0-255}.
- at end table
-
- at item lb/linblenddeint
-Linear blend deinterlacing filter that deinterlaces the given block by
-filtering all lines with a @code{(1 2 1)} filter.
-
- at item li/linipoldeint
-Linear interpolating deinterlacing filter that deinterlaces the given block by
-linearly interpolating every second line.
-
- at item ci/cubicipoldeint
-Cubic interpolating deinterlacing filter deinterlaces the given block by
-cubically interpolating every second line.
-
- at item md/mediandeint
-Median deinterlacing filter that deinterlaces the given block by applying a
-median filter to every second line.
-
- at item fd/ffmpegdeint
-FFmpeg deinterlacing filter that deinterlaces the given block by filtering every
-second line with a @code{(-1 4 2 4 -1)} filter.
-
- at item l5/lowpass5
-Vertically applied FIR lowpass deinterlacing filter that deinterlaces the given
-block by filtering all lines with a @code{(-1 2 6 2 -1)} filter.
-
- at item fq/forceQuant[|quantizer]
-Overrides the quantizer table from the input with the constant quantizer you
-specify.
- at table @option
- at item quantizer
-Quantizer to use
- at end table
-
- at item de/default
-Default pp filter combination (@code{hb|a,vb|a,dr|a})
-
- at item fa/fast
-Fast pp filter combination (@code{h1|a,v1|a,dr|a})
-
- at item ac
-High quality pp filter combination (@code{ha|a|128|7,va|a,dr|a})
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Apply horizontal and vertical deblocking, deringing and automatic
-brightness/contrast:
- at example
-pp=hb/vb/dr/al
- at end example
-
- at item
-Apply default filters without brightness/contrast correction:
- at example
-pp=de/-al
- at end example
-
- at item
-Apply default filters and temporal denoiser:
- at example
-pp=default/tmpnoise|1|2|3
- at end example
-
- at item
-Apply deblocking on luminance only, and switch vertical deblocking on or off
-automatically depending on available CPU time:
- at example
-pp=hb|y/vb|a
- at end example
- at end itemize
-
- at section pp7
-Apply Postprocessing filter 7. It is variant of the @ref{spp} filter,
-similar to spp = 6 with 7 point DCT, where only the center sample is
-used after IDCT.
-
-The filter accepts the following options:
-
- at table @option
- at item qp
-Force a constant quantization parameter. It accepts an integer in range
-0 to 63. If not set, the filter will use the QP from the video stream
-(if available).
-
- at item mode
-Set thresholding mode. Available modes are:
-
- at table @samp
- at item hard
-Set hard thresholding.
- at item soft
-Set soft thresholding (better de-ringing effect, but likely blurrier).
- at item medium
-Set medium thresholding (good results, default).
- at end table
- at end table
-
- at section psnr
-
-Obtain the average, maximum and minimum PSNR (Peak Signal to Noise
-Ratio) between two input videos.
-
-This filter takes in input two input videos, the first input is
-considered the "main" source and is passed unchanged to the
-output. The second input is used as a "reference" video for computing
-the PSNR.
-
-Both video inputs 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 PSNR is printed through the logging system.
-
-The filter stores the accumulated MSE (mean squared error) of each
-frame, and at the end of the processing it is averaged across all frames
-equally, and the following formula is applied to obtain the PSNR:
-
- at example
-PSNR = 10*log10(MAX^2/MSE)
- at end example
-
-Where MAX is the average of the maximum values of each component of the
-image.
-
-The description of the accepted parameters follows.
-
- at table @option
- at item stats_file, f
-If specified the filter will use the named file to save the PSNR of
-each individual frame.
- at end table
-
-The file printed if @var{stats_file} is selected, contains a sequence of
-key/value pairs of the form @var{key}:@var{value} for each compared
-couple of frames.
-
-A description of each shown parameter follows:
-
- at table @option
- at item n
-sequential number of the input frame, starting from 1
-
- at item mse_avg
-Mean Square Error pixel-by-pixel average difference of the compared
-frames, averaged over all the image components.
-
- at item mse_y, mse_u, mse_v, mse_r, mse_g, mse_g, mse_a
-Mean Square Error pixel-by-pixel average difference of the compared
-frames for the component specified by the suffix.
-
- at item psnr_y, psnr_u, psnr_v, psnr_r, psnr_g, psnr_b, psnr_a
-Peak Signal to Noise ratio of the compared frames for the component
-specified by the suffix.
- at end table
-
-For example:
- at example
-movie=ref_movie.mpg, setpts=PTS-STARTPTS [main];
-[main][ref] psnr="stats_file=stats.log" [out]
- at end example
-
-On this example the input file being processed is compared with the
-reference file @file{ref_movie.mpg}. The PSNR of each individual frame
-is stored in @file{stats.log}.
-
- at anchor{pullup}
- at section pullup
-
-Pulldown reversal (inverse telecine) filter, capable of handling mixed
-hard-telecine, 24000/1001 fps progressive, and 30000/1001 fps progressive
-content.
-
-The pullup filter is designed to take advantage of future context in making
-its decisions. This filter is stateless in the sense that it does not lock
-onto a pattern to follow, but it instead looks forward to the following
-fields in order to identify matches and rebuild progressive frames.
-
-To produce content with an even framerate, insert the fps filter after
-pullup, use @code{fps=24000/1001} if the input frame rate is 29.97fps,
- at code{fps=24} for 30fps and the (rare) telecined 25fps input.
-
-The filter accepts the following options:
-
- at table @option
- at item jl
- at item jr
- at item jt
- at item jb
-These options set the amount of "junk" to ignore at the left, right, top, and
-bottom of the image, respectively. Left and right are in units of 8 pixels,
-while top and bottom are in units of 2 lines.
-The default is 8 pixels on each side.
-
- at item sb
-Set the strict breaks. Setting this option to 1 will reduce the chances of
-filter generating an occasional mismatched frame, but it may also cause an
-excessive number of frames to be dropped during high motion sequences.
-Conversely, setting it to -1 will make filter match fields more easily.
-This may help processing of video where there is slight blurring between
-the fields, but may also cause there to be interlaced frames in the output.
-Default value is @code{0}.
-
- at item mp
-Set the metric plane to use. It accepts the following values:
- at table @samp
- at item l
-Use luma plane.
-
- at item u
-Use chroma blue plane.
-
- at item v
-Use chroma red plane.
- at end table
-
-This option may be set to use chroma plane instead of the default luma plane
-for doing filter's computations. This may improve accuracy on very clean
-source material, but more likely will decrease accuracy, especially if there
-is chroma noise (rainbow effect) or any grayscale video.
-The main purpose of setting @option{mp} to a chroma plane is to reduce CPU
-load and make pullup usable in realtime on slow machines.
- at end table
-
-For best results (without duplicated frames in the output file) it is
-necessary to change the output frame rate. For example, to inverse
-telecine NTSC input:
- at example
-ffmpeg -i input -vf pullup -r 24000/1001 ...
- at end example
-
- at section qp
-
-Change video quantization parameters (QP).
-
-The filter accepts the following option:
-
- at table @option
- at item qp
-Set expression for quantization parameter.
- at end table
-
-The expression is evaluated through the eval API and can contain, among others,
-the following constants:
-
- at table @var
- at item known
-1 if index is not 129, 0 otherwise.
-
- at item qp
-Sequentional index starting from -129 to 128.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Some equation like:
- at example
-qp=2+2*sin(PI*qp)
- at end example
- at end itemize
-
- at section random
-
-Flush video frames from internal cache of frames into a random order.
-No frame is discarded.
-Inspired by @ref{frei0r} nervous filter.
-
- at table @option
- at item frames
-Set size in number of frames of internal cache, in range from @code{2} to
- at code{512}. Default is @code{30}.
-
- at item seed
-Set seed for random number generator, must be an integer included between
- at code{0} and @code{UINT32_MAX}. If not specified, or if explicitly set to
-less than @code{0}, the filter will try to use a good random seed on a
-best effort basis.
- at end table
-
- at section removegrain
-
-The removegrain filter is a spatial denoiser for progressive video.
-
- at table @option
- at item m0
-Set mode for the first plane.
-
- at item m1
-Set mode for the second plane.
-
- at item m2
-Set mode for the third plane.
-
- at item m3
-Set mode for the fourth plane.
- at end table
-
-Range of mode is from 0 to 24. Description of each mode follows:
-
- at table @var
- at item 0
-Leave input plane unchanged. Default.
-
- at item 1
-Clips the pixel with the minimum and maximum of the 8 neighbour pixels.
-
- at item 2
-Clips the pixel with the second minimum and maximum of the 8 neighbour pixels.
-
- at item 3
-Clips the pixel with the third minimum and maximum of the 8 neighbour pixels.
-
- at item 4
-Clips the pixel with the fourth minimum and maximum of the 8 neighbour pixels.
-This is equivalent to a median filter.
-
- at item 5
-Line-sensitive clipping giving the minimal change.
-
- at item 6
-Line-sensitive clipping, intermediate.
-
- at item 7
-Line-sensitive clipping, intermediate.
-
- at item 8
-Line-sensitive clipping, intermediate.
-
- at item 9
-Line-sensitive clipping on a line where the neighbours pixels are the closest.
-
- at item 10
-Replaces the target pixel with the closest neighbour.
-
- at item 11
-[1 2 1] horizontal and vertical kernel blur.
-
- at item 12
-Same as mode 11.
-
- at item 13
-Bob mode, interpolates top field from the line where the neighbours
-pixels are the closest.
-
- at item 14
-Bob mode, interpolates bottom field from the line where the neighbours
-pixels are the closest.
-
- at item 15
-Bob mode, interpolates top field. Same as 13 but with a more complicated
-interpolation formula.
-
- at item 16
-Bob mode, interpolates bottom field. Same as 14 but with a more complicated
-interpolation formula.
-
- at item 17
-Clips the pixel with the minimum and maximum of respectively the maximum and
-minimum of each pair of opposite neighbour pixels.
-
- at item 18
-Line-sensitive clipping using opposite neighbours whose greatest distance from
-the current pixel is minimal.
-
- at item 19
-Replaces the pixel with the average of its 8 neighbours.
-
- at item 20
-Averages the 9 pixels ([1 1 1] horizontal and vertical blur).
-
- at item 21
-Clips pixels using the averages of opposite neighbour.
-
- at item 22
-Same as mode 21 but simpler and faster.
-
- at item 23
-Small edge and halo removal, but reputed useless.
-
- at item 24
-Similar as 23.
- at end table
-
- at section removelogo
-
-Suppress a TV station logo, using an image file to determine which
-pixels comprise the logo. It works by filling in the pixels that
-comprise the logo with neighboring pixels.
-
-The filter accepts the following options:
-
- at table @option
- at item filename, f
-Set the filter bitmap file, which can be any image format supported by
-libavformat. The width and height of the image file must match those of the
-video stream being processed.
- at end table
-
-Pixels in the provided bitmap image with a value of zero are not
-considered part of the logo, non-zero pixels are considered part of
-the logo. If you use white (255) for the logo and black (0) for the
-rest, you will be safe. For making the filter bitmap, it is
-recommended to take a screen capture of a black frame with the logo
-visible, and then using a threshold filter followed by the erode
-filter once or twice.
-
-If needed, little splotches can be fixed manually. Remember that if
-logo pixels are not covered, the filter quality will be much
-reduced. Marking too many pixels as part of the logo does not hurt as
-much, but it will increase the amount of blurring needed to cover over
-the image and will destroy more information than necessary, and extra
-pixels will slow things down on a large logo.
-
- at section repeatfields
-
-This filter uses the repeat_field flag from the Video ES headers and hard repeats
-fields based on its value.
-
- at section reverse, areverse
-
-Reverse a clip.
-
-Warning: This filter requires memory to buffer the entire clip, so trimming
-is suggested.
-
- at subsection Examples
-
- at itemize
- at item
-Take the first 5 seconds of a clip, and reverse it.
- at example
-trim=end=5,reverse
- at end example
- at end itemize
-
- at section rotate
-
-Rotate video by an arbitrary angle expressed in radians.
-
-The filter accepts the following options:
-
-A description of the optional parameters follows.
- at table @option
- at item angle, a
-Set an expression for the angle by which to rotate the input video
-clockwise, expressed as a number of radians. A negative value will
-result in a counter-clockwise rotation. By default it is set to "0".
-
-This expression is evaluated for each frame.
-
- at item out_w, ow
-Set the output width expression, default value is "iw".
-This expression is evaluated just once during configuration.
-
- at item out_h, oh
-Set the output height expression, default value is "ih".
-This expression is evaluated just once during configuration.
-
- at item bilinear
-Enable bilinear interpolation if set to 1, a value of 0 disables
-it. Default value is 1.
-
- at item fillcolor, c
-Set the color used to fill the output area not covered by the rotated
-image. For the general syntax of this option, check the "Color" section in the
-ffmpeg-utils manual. 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".
- at end table
-
-The expressions for the angle and the output size can contain the
-following constants and functions:
-
- at table @option
- at item n
-sequential number of the input frame, starting from 0. It is always NAN
-before the first frame is filtered.
-
- at item t
-time in seconds of the input frame, it is set to 0 when the filter is
-configured. It is always NAN before the first frame is filtered.
-
- at item hsub
- at item vsub
-horizontal and vertical chroma subsample values. For example for the
-pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
-
- at item in_w, iw
- at item in_h, ih
-the input video width and height
-
- at item out_w, ow
- at item out_h, oh
-the output width and height, that is the size of the padded area as
-specified by the @var{width} and @var{height} expressions
-
- at item rotw(a)
- at item roth(a)
-the minimal width/height required for completely containing the input
-video rotated by @var{a} radians.
-
-These are only available when computing the @option{out_w} and
- at option{out_h} expressions.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Rotate the input by PI/6 radians clockwise:
- at example
-rotate=PI/6
- at end example
-
- at item
-Rotate the input by PI/6 radians counter-clockwise:
- at example
-rotate=-PI/6
- at end example
-
- at item
-Rotate the input by 45 degrees clockwise:
- at example
-rotate=45*PI/180
- at end example
-
- at item
-Apply a constant rotation with period T, starting from an angle of PI/3:
- at example
-rotate=PI/3+2*PI*t/T
- at end example
-
- at item
-Make the input video rotation oscillating with a period of T
-seconds and an amplitude of A radians:
- at example
-rotate=A*sin(2*PI/T*t)
- at end example
-
- at item
-Rotate the video, output size is chosen so that the whole rotating
-input video is always completely contained in the output:
- at example
-rotate='2*PI*t:ow=hypot(iw,ih):oh=ow'
- at end example
-
- at item
-Rotate the video, reduce the output size so that no background is ever
-shown:
- at example
-rotate=2*PI*t:ow='min(iw,ih)/sqrt(2)':oh=ow:c=none
- at end example
- at end itemize
-
- at subsection Commands
-
-The filter supports the following commands:
-
- at table @option
- at item a, angle
-Set the angle expression.
-The command accepts the same syntax of the corresponding option.
-
-If the specified expression is not valid, it is kept at its current
-value.
- at end table
-
- at section sab
-
-Apply Shape Adaptive Blur.
-
-The filter accepts the following options:
-
- at table @option
- at item luma_radius, lr
-Set luma blur filter strength, must be a value in range 0.1-4.0, default
-value is 1.0. A greater value will result in a more blurred image, and
-in slower processing.
-
- at item luma_pre_filter_radius, lpfr
-Set luma pre-filter radius, must be a value in the 0.1-2.0 range, default
-value is 1.0.
-
- at item luma_strength, ls
-Set luma maximum difference between pixels to still be considered, must
-be a value in the 0.1-100.0 range, default value is 1.0.
-
- at item chroma_radius, cr
-Set chroma blur filter strength, must be a value in range 0.1-4.0. A
-greater value will result in a more blurred image, and in slower
-processing.
-
- at item chroma_pre_filter_radius, cpfr
-Set chroma pre-filter radius, must be a value in the 0.1-2.0 range.
-
- at item chroma_strength, cs
-Set chroma maximum difference between pixels to still be considered,
-must be a value in the 0.1-100.0 range.
- at end table
-
-Each chroma option value, if not explicitly specified, is set to the
-corresponding luma option value.
-
- at anchor{scale}
- at section scale
-
-Scale (resize) the input video, using the libswscale library.
-
-The scale filter forces the output display aspect ratio to be the same
-of the input, by changing the output sample aspect ratio.
-
-If the input image format is different from the format requested by
-the next filter, the scale filter will convert the input to the
-requested format.
-
- at subsection Options
-The filter accepts the following options, or any of the options
-supported by the libswscale scaler.
-
-See @ref{scaler_options,,the ffmpeg-scaler manual,ffmpeg-scaler} for
-the complete list of scaler options.
-
- at table @option
- at item width, w
- at item height, h
-Set the output video dimension expression. Default value is the input
-dimension.
-
-If the value is 0, the input width is used for the output.
-
-If one of the values is -1, the scale filter will use a value that
-maintains the aspect ratio of the input image, calculated from the
-other specified dimension. If both of them are -1, the input size is
-used
-
-If one of the values is -n with n > 1, the scale filter will also use a value
-that maintains the aspect ratio of the input image, calculated from the other
-specified dimension. After that it will, however, make sure that the calculated
-dimension is divisible by n and adjust the value if necessary.
-
-See below for the list of accepted constants for use in the dimension
-expression.
-
- at item interl
-Set the interlacing mode. It accepts the following values:
-
- at table @samp
- at item 1
-Force interlaced aware scaling.
-
- at item 0
-Do not apply interlaced scaling.
-
- at item -1
-Select interlaced aware scaling depending on whether the source frames
-are flagged as interlaced or not.
- at end table
-
-Default value is @samp{0}.
-
- at item flags
-Set libswscale scaling flags. See
- at ref{sws_flags,,the ffmpeg-scaler manual,ffmpeg-scaler} for the
-complete list of values. If not explicitly specified the filter applies
-the default flags.
-
- at item size, s
-Set the video size. For the syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-
- at item in_color_matrix
- at item out_color_matrix
-Set in/output YCbCr color space type.
-
-This allows the autodetected value to be overridden as well as allows forcing
-a specific value used for the output and encoder.
-
-If not specified, the color space type depends on the pixel format.
-
-Possible values:
-
- at table @samp
- at item auto
-Choose automatically.
-
- at item bt709
-Format conforming to International Telecommunication Union (ITU)
-Recommendation BT.709.
-
- at item fcc
-Set color space conforming to the United States Federal Communications
-Commission (FCC) Code of Federal Regulations (CFR) Title 47 (2003) 73.682 (a).
-
- at item bt601
-Set color space conforming to:
-
- at itemize
- at item
-ITU Radiocommunication Sector (ITU-R) Recommendation BT.601
-
- at item
-ITU-R Rec. BT.470-6 (1998) Systems B, B1, and G
-
- at item
-Society of Motion Picture and Television Engineers (SMPTE) ST 170:2004
-
- at end itemize
-
- at item smpte240m
-Set color space conforming to SMPTE ST 240:1999.
- at end table
-
- at item in_range
- at item out_range
-Set in/output YCbCr sample range.
-
-This allows the autodetected value to be overridden as well as allows forcing
-a specific value used for the output and encoder. If not specified, the
-range depends on the pixel format. Possible values:
-
- at table @samp
- at item auto
-Choose automatically.
-
- at item jpeg/full/pc
-Set full range (0-255 in case of 8-bit luma).
-
- at item mpeg/tv
-Set "MPEG" range (16-235 in case of 8-bit luma).
- at end table
-
- at item force_original_aspect_ratio
-Enable decreasing or increasing output video width or height if necessary to
-keep the original aspect ratio. Possible values:
-
- at table @samp
- at item disable
-Scale the video as specified and disable this feature.
-
- at item decrease
-The output video dimensions will automatically be decreased if needed.
-
- at item increase
-The output video dimensions will automatically be increased if needed.
-
- at end table
-
-One useful instance of this option is that when you know a specific device's
-maximum allowed resolution, you can use this to limit the output video to
-that, while retaining the aspect ratio. For example, device A allows
-1280x720 playback, and your video is 1920x800. Using this option (set it to
-decrease) and specifying 1280x720 to the command line makes the output
-1280x533.
-
-Please note that this is a different thing than specifying -1 for @option{w}
-or @option{h}, you still need to specify the output resolution for this option
-to work.
-
- at end table
-
-The values of the @option{w} and @option{h} options are expressions
-containing the following constants:
-
- at table @var
- at item in_w
- at item in_h
-The input width and height
-
- at item iw
- at item ih
-These are the same as @var{in_w} and @var{in_h}.
-
- at item out_w
- at item out_h
-The output (scaled) width and height
-
- at item ow
- at item oh
-These are the same as @var{out_w} and @var{out_h}
-
- at item a
-The same as @var{iw} / @var{ih}
-
- at item sar
-input sample aspect ratio
-
- at item dar
-The input display aspect ratio. Calculated from @code{(iw / ih) * sar}.
-
- at item hsub
- at item vsub
-horizontal and vertical input chroma subsample values. For example for the
-pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
-
- at item ohsub
- at item ovsub
-horizontal and vertical output chroma subsample values. For example for the
-pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Scale the input video to a size of 200x100
- at example
-scale=w=200:h=100
- at end example
-
-This is equivalent to:
- at example
-scale=200:100
- at end example
-
-or:
- at example
-scale=200x100
- at end example
-
- at item
-Specify a size abbreviation for the output size:
- at example
-scale=qcif
- at end example
-
-which can also be written as:
- at example
-scale=size=qcif
- at end example
-
- at item
-Scale the input to 2x:
- at example
-scale=w=2*iw:h=2*ih
- at end example
-
- at item
-The above is the same as:
- at example
-scale=2*in_w:2*in_h
- at end example
-
- at item
-Scale the input to 2x with forced interlaced scaling:
- at example
-scale=2*iw:2*ih:interl=1
- at end example
-
- at item
-Scale the input to half size:
- at example
-scale=w=iw/2:h=ih/2
- at end example
-
- at item
-Increase the width, and set the height to the same size:
- at example
-scale=3/2*iw:ow
- at end example
-
- at item
-Seek Greek harmony:
- at example
-scale=iw:1/PHI*iw
-scale=ih*PHI:ih
- at end example
-
- at item
-Increase the height, and set the width to 3/2 of the height:
- at example
-scale=w=3/2*oh:h=3/5*ih
- at end example
-
- at item
-Increase the size, making the size a multiple of the chroma
-subsample values:
- at example
-scale="trunc(3/2*iw/hsub)*hsub:trunc(3/2*ih/vsub)*vsub"
- at end example
-
- at item
-Increase the width to a maximum of 500 pixels,
-keeping the same aspect ratio as the input:
- at example
-scale=w='min(500\, iw*3/2):h=-1'
- at end example
- at end itemize
-
- at subsection Commands
-
-This filter supports the following commands:
- at table @option
- at item width, w
- at item height, h
-Set the output video dimension expression.
-The command accepts the same syntax of the corresponding option.
-
-If the specified expression is not valid, it is kept at its current
-value.
- at end table
-
- at section scale2ref
-
-Scale (resize) the input video, based on a reference video.
-
-See the scale filter for available options, scale2ref supports the same but
-uses the reference video instead of the main input as basis.
-
- at subsection Examples
-
- at itemize
- at item
-Scale a subtitle stream to match the main video in size before overlaying
- at example
-'scale2ref[b][a];[a][b]overlay'
- at end example
- at end itemize
-
- at section separatefields
-
-The @code{separatefields} takes a frame-based video input and splits
-each frame into its components fields, producing a new half height clip
-with twice the frame rate and twice the frame count.
-
-This filter use field-dominance information in frame to decide which
-of each pair of fields to place first in the output.
-If it gets it wrong use @ref{setfield} filter before @code{separatefields} filter.
-
- at section setdar, setsar
-
-The @code{setdar} filter sets the Display Aspect Ratio for the filter
-output video.
-
-This is done by changing the specified Sample (aka Pixel) Aspect
-Ratio, according to the following equation:
- at example
- at var{DAR} = @var{HORIZONTAL_RESOLUTION} / @var{VERTICAL_RESOLUTION} * @var{SAR}
- at end example
-
-Keep in mind that the @code{setdar} filter does not modify the pixel
-dimensions of the video frame. Also, the display aspect ratio set by
-this filter may be changed by later filters in the filterchain,
-e.g. in case of scaling or if another "setdar" or a "setsar" filter is
-applied.
-
-The @code{setsar} filter sets the Sample (aka Pixel) Aspect Ratio for
-the filter output video.
-
-Note that as a consequence of the application of this filter, the
-output display aspect ratio will change according to the equation
-above.
-
-Keep in mind that the sample aspect ratio set by the @code{setsar}
-filter may be changed by later filters in the filterchain, e.g. if
-another "setsar" or a "setdar" filter is applied.
-
-It accepts the following parameters:
-
- at table @option
- at item r, ratio, dar (@code{setdar} only), sar (@code{setsar} only)
-Set the aspect ratio used by the filter.
-
-The parameter can be a floating point number string, an expression, or
-a string of the form @var{num}:@var{den}, where @var{num} and
- at var{den} are the numerator and denominator of the aspect ratio. If
-the parameter is not specified, it is assumed the value "0".
-In case the form "@var{num}:@var{den}" is used, the @code{:} character
-should be escaped.
-
- at item max
-Set the maximum integer value to use for expressing numerator and
-denominator when reducing the expressed aspect ratio to a rational.
-Default value is @code{100}.
-
- at end table
-
-The parameter @var{sar} is an expression containing
-the following constants:
-
- at table @option
- at item E, PI, PHI
-These are approximated values for the mathematical constants e
-(Euler's number), pi (Greek pi), and phi (the golden ratio).
-
- at item w, h
-The input width and height.
-
- at item a
-These are the same as @var{w} / @var{h}.
-
- at item sar
-The input sample aspect ratio.
-
- at item dar
-The input display aspect ratio. It is the same as
-(@var{w} / @var{h}) * @var{sar}.
-
- at item hsub, vsub
-Horizontal and vertical chroma subsample values. For example, for the
-pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
- at end table
-
- at subsection Examples
-
- at itemize
-
- at item
-To change the display aspect ratio to 16:9, specify one of the following:
- at example
-setdar=dar=1.77777
-setdar=dar=16/9
-setdar=dar=1.77777
- at end example
-
- at item
-To change the sample aspect ratio to 10:11, specify:
- at example
-setsar=sar=10/11
- at end example
-
- at item
-To set a display aspect ratio of 16:9, and specify a maximum integer value of
-1000 in the aspect ratio reduction, use the command:
- at example
-setdar=ratio=16/9:max=1000
- at end example
-
- at end itemize
-
- at anchor{setfield}
- at section setfield
-
-Force field for the output video frame.
-
-The @code{setfield} filter marks the interlace type field for the
-output frames. It does not change the input frame, but only sets the
-corresponding property, which affects how the frame is treated by
-following filters (e.g. @code{fieldorder} or @code{yadif}).
-
-The filter accepts the following options:
-
- at table @option
-
- at item mode
-Available values are:
-
- at table @samp
- at item auto
-Keep the same field property.
-
- at item bff
-Mark the frame as bottom-field-first.
-
- at item tff
-Mark the frame as top-field-first.
-
- at item prog
-Mark the frame as progressive.
- at end table
- at end table
-
- at section showinfo
-
-Show a line containing various information for each input video frame.
-The input video is not modified.
-
-The shown line contains a sequence of key/value pairs of the form
- at var{key}:@var{value}.
-
-The following values are shown in the output:
-
- at table @option
- at item n
-The (sequential) number of the input frame, starting from 0.
-
- at item pts
-The Presentation TimeStamp of the input frame, expressed as a number of
-time base units. The time base unit depends on the filter input pad.
-
- at item pts_time
-The Presentation TimeStamp of the input frame, expressed as a number of
-seconds.
-
- at item pos
-The position of the frame in the input stream, or -1 if this information is
-unavailable and/or meaningless (for example in case of synthetic video).
-
- at item fmt
-The pixel format name.
-
- at item sar
-The sample aspect ratio of the input frame, expressed in the form
- at var{num}/@var{den}.
-
- at item s
-The size of the input frame. For the syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-
- at item i
-The type of interlaced mode ("P" for "progressive", "T" for top field first, "B"
-for bottom field first).
-
- at item iskey
-This is 1 if the frame is a key frame, 0 otherwise.
-
- at item type
-The picture type of the input frame ("I" for an I-frame, "P" for a
-P-frame, "B" for a B-frame, or "?" for an unknown type).
-Also refer to the documentation of the @code{AVPictureType} enum and of
-the @code{av_get_picture_type_char} function defined in
- at file{libavutil/avutil.h}.
-
- at item checksum
-The Adler-32 checksum (printed in hexadecimal) of all the planes of the input frame.
-
- at item plane_checksum
-The Adler-32 checksum (printed in hexadecimal) of each plane of the input frame,
-expressed in the form "[@var{c0} @var{c1} @var{c2} @var{c3}]".
- at end table
-
- at section showpalette
-
-Displays the 256 colors palette of each frame. This filter is only relevant for
- at var{pal8} pixel format frames.
-
-It accepts the following option:
-
- at table @option
- at item s
-Set the size of the box used to represent one palette color entry. Default is
- at code{30} (for a @code{30x30} pixel box).
- at end table
-
- at section shuffleplanes
-
-Reorder and/or duplicate video planes.
-
-It accepts the following parameters:
-
- at table @option
-
- at item map0
-The index of the input plane to be used as the first output plane.
-
- at item map1
-The index of the input plane to be used as the second output plane.
-
- at item map2
-The index of the input plane to be used as the third output plane.
-
- at item map3
-The index of the input plane to be used as the fourth output plane.
-
- at end table
-
-The first plane has the index 0. The default is to keep the input unchanged.
-
-Swap the second and third planes of the input:
- at example
-ffmpeg -i INPUT -vf shuffleplanes=0:2:1:3 OUTPUT
- at end example
-
- at anchor{signalstats}
- at section signalstats
-Evaluate various visual metrics that assist in determining issues associated
-with the digitization of analog video media.
-
-By default the filter will log these metadata values:
-
- at table @option
- at item YMIN
-Display the minimal Y value contained within the input frame. Expressed in
-range of [0-255].
-
- at item YLOW
-Display the Y value at the 10% percentile within the input frame. Expressed in
-range of [0-255].
-
- at item YAVG
-Display the average Y value within the input frame. Expressed in range of
-[0-255].
-
- at item YHIGH
-Display the Y value at the 90% percentile within the input frame. Expressed in
-range of [0-255].
-
- at item YMAX
-Display the maximum Y value contained within the input frame. Expressed in
-range of [0-255].
-
- at item UMIN
-Display the minimal U value contained within the input frame. Expressed in
-range of [0-255].
-
- at item ULOW
-Display the U value at the 10% percentile within the input frame. Expressed in
-range of [0-255].
-
- at item UAVG
-Display the average U value within the input frame. Expressed in range of
-[0-255].
-
- at item UHIGH
-Display the U value at the 90% percentile within the input frame. Expressed in
-range of [0-255].
-
- at item UMAX
-Display the maximum U value contained within the input frame. Expressed in
-range of [0-255].
-
- at item VMIN
-Display the minimal V value contained within the input frame. Expressed in
-range of [0-255].
-
- at item VLOW
-Display the V value at the 10% percentile within the input frame. Expressed in
-range of [0-255].
-
- at item VAVG
-Display the average V value within the input frame. Expressed in range of
-[0-255].
-
- at item VHIGH
-Display the V value at the 90% percentile within the input frame. Expressed in
-range of [0-255].
-
- at item VMAX
-Display the maximum V value contained within the input frame. Expressed in
-range of [0-255].
-
- at item SATMIN
-Display the minimal saturation value contained within the input frame.
-Expressed in range of [0-~181.02].
-
- at item SATLOW
-Display the saturation value at the 10% percentile within the input frame.
-Expressed in range of [0-~181.02].
-
- at item SATAVG
-Display the average saturation value within the input frame. Expressed in range
-of [0-~181.02].
-
- at item SATHIGH
-Display the saturation value at the 90% percentile within the input frame.
-Expressed in range of [0-~181.02].
-
- at item SATMAX
-Display the maximum saturation value contained within the input frame.
-Expressed in range of [0-~181.02].
-
- at item HUEMED
-Display the median value for hue within the input frame. Expressed in range of
-[0-360].
-
- at item HUEAVG
-Display the average value for hue within the input frame. Expressed in range of
-[0-360].
-
- at item YDIF
-Display the average of sample value difference between all values of the Y
-plane in the current frame and corresponding values of the previous input frame.
-Expressed in range of [0-255].
-
- at item UDIF
-Display the average of sample value difference between all values of the U
-plane in the current frame and corresponding values of the previous input frame.
-Expressed in range of [0-255].
-
- at item VDIF
-Display the average of sample value difference between all values of the V
-plane in the current frame and corresponding values of the previous input frame.
-Expressed in range of [0-255].
- at end table
-
-The filter accepts the following options:
-
- at table @option
- at item stat
- at item out
-
- at option{stat} specify an additional form of image analysis.
- at option{out} output video with the specified type of pixel highlighted.
-
-Both options accept the following values:
-
- at table @samp
- at item tout
-Identify @var{temporal outliers} pixels. A @var{temporal outlier} is a pixel
-unlike the neighboring pixels of the same field. Examples of temporal outliers
-include the results of video dropouts, head clogs, or tape tracking issues.
-
- at item vrep
-Identify @var{vertical line repetition}. Vertical line repetition includes
-similar rows of pixels within a frame. In born-digital video vertical line
-repetition is common, but this pattern is uncommon in video digitized from an
-analog source. When it occurs in video that results from the digitization of an
-analog source it can indicate concealment from a dropout compensator.
-
- at item brng
-Identify pixels that fall outside of legal broadcast range.
- at end table
-
- at item color, c
-Set the highlight color for the @option{out} option. The default color is
-yellow.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Output data of various video metrics:
- at example
-ffprobe -f lavfi movie=example.mov,signalstats="stat=tout+vrep+brng" -show_frames
- at end example
-
- at item
-Output specific data about the minimum and maximum values of the Y plane per frame:
- at example
-ffprobe -f lavfi movie=example.mov,signalstats -show_entries frame_tags=lavfi.signalstats.YMAX,lavfi.signalstats.YMIN
- at end example
-
- at item
-Playback video while highlighting pixels that are outside of broadcast range in red.
- at example
-ffplay example.mov -vf signalstats="out=brng:color=red"
- at end example
-
- at item
-Playback video with signalstats metadata drawn over the frame.
- at example
-ffplay example.mov -vf signalstats=stat=brng+vrep+tout,drawtext=fontfile=FreeSerif.ttf:textfile=signalstat_drawtext.txt
- at end example
-
-The contents of signalstat_drawtext.txt used in the command are:
- at example
-time %@{pts:hms@}
-Y (%@{metadata:lavfi.signalstats.YMIN@}-%@{metadata:lavfi.signalstats.YMAX@})
-U (%@{metadata:lavfi.signalstats.UMIN@}-%@{metadata:lavfi.signalstats.UMAX@})
-V (%@{metadata:lavfi.signalstats.VMIN@}-%@{metadata:lavfi.signalstats.VMAX@})
-saturation maximum: %@{metadata:lavfi.signalstats.SATMAX@}
-
- at end example
- at end itemize
-
- at anchor{smartblur}
- at section smartblur
-
-Blur the input video without impacting the outlines.
-
-It accepts the following options:
-
- at table @option
- at item luma_radius, lr
-Set the luma radius. The option value must be a float number in
-the range [0.1,5.0] that specifies the variance of the gaussian filter
-used to blur the image (slower if larger). Default value is 1.0.
-
- at item luma_strength, ls
-Set the luma strength. The option value must be a float number
-in the range [-1.0,1.0] that configures the blurring. A value included
-in [0.0,1.0] will blur the image whereas a value included in
-[-1.0,0.0] will sharpen the image. Default value is 1.0.
-
- at item luma_threshold, lt
-Set the luma threshold used as a coefficient to determine
-whether a pixel should be blurred or not. The option value must be an
-integer in the range [-30,30]. A value of 0 will filter all the image,
-a value included in [0,30] will filter flat areas and a value included
-in [-30,0] will filter edges. Default value is 0.
-
- at item chroma_radius, cr
-Set the chroma radius. The option value must be a float number in
-the range [0.1,5.0] that specifies the variance of the gaussian filter
-used to blur the image (slower if larger). Default value is 1.0.
-
- at item chroma_strength, cs
-Set the chroma strength. The option value must be a float number
-in the range [-1.0,1.0] that configures the blurring. A value included
-in [0.0,1.0] will blur the image whereas a value included in
-[-1.0,0.0] will sharpen the image. Default value is 1.0.
-
- at item chroma_threshold, ct
-Set the chroma threshold used as a coefficient to determine
-whether a pixel should be blurred or not. The option value must be an
-integer in the range [-30,30]. A value of 0 will filter all the image,
-a value included in [0,30] will filter flat areas and a value included
-in [-30,0] will filter edges. Default value is 0.
- at end table
-
-If a chroma option is not explicitly set, the corresponding luma value
-is set.
-
- at section ssim
-
-Obtain the SSIM (Structural SImilarity Metric) between two input videos.
-
-This filter takes in input two input videos, the first input is
-considered the "main" source and is passed unchanged to the
-output. The second input is used as a "reference" video for computing
-the SSIM.
-
-Both video inputs 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 filter stores the calculated SSIM of each frame.
-
-The description of the accepted parameters follows.
-
- at table @option
- at item stats_file, f
-If specified the filter will use the named file to save the SSIM of
-each individual frame.
- at end table
-
-The file printed if @var{stats_file} is selected, contains a sequence of
-key/value pairs of the form @var{key}:@var{value} for each compared
-couple of frames.
-
-A description of each shown parameter follows:
-
- at table @option
- at item n
-sequential number of the input frame, starting from 1
-
- at item Y, U, V, R, G, B
-SSIM of the compared frames for the component specified by the suffix.
-
- at item All
-SSIM of the compared frames for the whole frame.
-
- at item dB
-Same as above but in dB representation.
- at end table
-
-For example:
- at example
-movie=ref_movie.mpg, setpts=PTS-STARTPTS [main];
-[main][ref] ssim="stats_file=stats.log" [out]
- at end example
-
-On this example the input file being processed is compared with the
-reference file @file{ref_movie.mpg}. The SSIM of each individual frame
-is stored in @file{stats.log}.
-
-Another example with both psnr and ssim at same time:
- at example
-ffmpeg -i main.mpg -i ref.mpg -lavfi "ssim;[0:v][1:v]psnr" -f null -
- at end example
-
- at section stereo3d
-
-Convert between different stereoscopic image formats.
-
-The filters accept the following options:
-
- at table @option
- at item in
-Set stereoscopic image format of input.
-
-Available values for input image formats are:
- at table @samp
- at item sbsl
-side by side parallel (left eye left, right eye right)
-
- at item sbsr
-side by side crosseye (right eye left, left eye right)
-
- at item sbs2l
-side by side parallel with half width resolution
-(left eye left, right eye right)
-
- at item sbs2r
-side by side crosseye with half width resolution
-(right eye left, left eye right)
-
- at item abl
-above-below (left eye above, right eye below)
-
- at item abr
-above-below (right eye above, left eye below)
-
- at item ab2l
-above-below with half height resolution
-(left eye above, right eye below)
-
- at item ab2r
-above-below with half height resolution
-(right eye above, left eye below)
-
- at item al
-alternating frames (left eye first, right eye second)
-
- at item ar
-alternating frames (right eye first, left eye second)
-
-Default value is @samp{sbsl}.
- at end table
-
- at item out
-Set stereoscopic image format of output.
-
-Available values for output image formats are all the input formats as well as:
- at table @samp
- at item arbg
-anaglyph red/blue gray
-(red filter on left eye, blue filter on right eye)
-
- at item argg
-anaglyph red/green gray
-(red filter on left eye, green filter on right eye)
-
- at item arcg
-anaglyph red/cyan gray
-(red filter on left eye, cyan filter on right eye)
-
- at item arch
-anaglyph red/cyan half colored
-(red filter on left eye, cyan filter on right eye)
-
- at item arcc
-anaglyph red/cyan color
-(red filter on left eye, cyan filter on right eye)
-
- at item arcd
-anaglyph red/cyan color optimized with the least squares projection of dubois
-(red filter on left eye, cyan filter on right eye)
-
- at item agmg
-anaglyph green/magenta gray
-(green filter on left eye, magenta filter on right eye)
-
- at item agmh
-anaglyph green/magenta half colored
-(green filter on left eye, magenta filter on right eye)
-
- at item agmc
-anaglyph green/magenta colored
-(green filter on left eye, magenta filter on right eye)
-
- at item agmd
-anaglyph green/magenta color optimized with the least squares projection of dubois
-(green filter on left eye, magenta filter on right eye)
-
- at item aybg
-anaglyph yellow/blue gray
-(yellow filter on left eye, blue filter on right eye)
-
- at item aybh
-anaglyph yellow/blue half colored
-(yellow filter on left eye, blue filter on right eye)
-
- at item aybc
-anaglyph yellow/blue colored
-(yellow filter on left eye, blue filter on right eye)
-
- at item aybd
-anaglyph yellow/blue color optimized with the least squares projection of dubois
-(yellow filter on left eye, blue filter on right eye)
-
- at item irl
-interleaved rows (left eye has top row, right eye starts on next row)
-
- at item irr
-interleaved rows (right eye has top row, left eye starts on next row)
-
- at item ml
-mono output (left eye only)
-
- at item mr
-mono output (right eye only)
- at end table
-
-Default value is @samp{arcd}.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Convert input video from side by side parallel to anaglyph yellow/blue dubois:
- at example
-stereo3d=sbsl:aybd
- at end example
-
- at item
-Convert input video from above below (left eye above, right eye below) to side by side crosseye.
- at example
-stereo3d=abl:sbsr
- at end example
- at end itemize
-
- at anchor{spp}
- at section spp
-
-Apply a simple postprocessing filter that compresses and decompresses the image
-at several (or - in the case of @option{quality} level @code{6} - all) shifts
-and average the results.
-
-The filter accepts the following options:
-
- at table @option
- at item quality
-Set quality. This option defines the number of levels for averaging. It accepts
-an integer in the range 0-6. If set to @code{0}, the filter will have no
-effect. A value of @code{6} means the higher quality. For each increment of
-that value the speed drops by a factor of approximately 2. Default value is
- at code{3}.
-
- at item qp
-Force a constant quantization parameter. If not set, the filter will use the QP
-from the video stream (if available).
-
- at item mode
-Set thresholding mode. Available modes are:
-
- at table @samp
- at item hard
-Set hard thresholding (default).
- at item soft
-Set soft thresholding (better de-ringing effect, but likely blurrier).
- at end table
-
- at item use_bframe_qp
-Enable the use of the QP from the B-Frames if set to @code{1}. Using this
-option may cause flicker since the B-Frames have often larger QP. Default is
- at code{0} (not enabled).
- at end table
-
- at anchor{subtitles}
- at section subtitles
-
-Draw subtitles on top of input video using the libass library.
-
-To enable compilation of this filter you need to configure FFmpeg with
- at code{--enable-libass}. This filter also requires a build with libavcodec and
-libavformat to convert the passed subtitles file to ASS (Advanced Substation
-Alpha) subtitles format.
-
-The filter accepts the following options:
-
- at table @option
- at item filename, f
-Set the filename of the subtitle file to read. It must be specified.
-
- at item original_size
-Specify the size of the original video, the video for which the ASS file
-was composed. For the syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-Due to a misdesign in ASS aspect ratio arithmetic, this is necessary to
-correctly scale the fonts if the aspect ratio has been changed.
-
- at item fontsdir
-Set a directory path containing fonts that can be used by the filter.
-These fonts will be used in addition to whatever the font provider uses.
-
- at item charenc
-Set subtitles input character encoding. @code{subtitles} filter only. Only
-useful if not UTF-8.
-
- at item stream_index, si
-Set subtitles stream index. @code{subtitles} filter only.
-
- at item force_style
-Override default style or script info parameters of the subtitles. It accepts a
-string containing ASS style format @code{KEY=VALUE} couples separated by ",".
- at end table
-
-If the first key is not specified, it is assumed that the first value
-specifies the @option{filename}.
-
-For example, to render the file @file{sub.srt} on top of the input
-video, use the command:
- at example
-subtitles=sub.srt
- at end example
-
-which is equivalent to:
- at example
-subtitles=filename=sub.srt
- at end example
-
-To render the default subtitles stream from file @file{video.mkv}, use:
- at example
-subtitles=video.mkv
- at end example
-
-To render the second subtitles stream from that file, use:
- at example
-subtitles=video.mkv:si=1
- at end example
-
-To make the subtitles stream from @file{sub.srt} appear in transparent green
- at code{DejaVu Serif}, use:
- at example
-subtitles=sub.srt:force_style='FontName=DejaVu Serif,PrimaryColour=&HAA00FF00'
- at end example
-
- at section super2xsai
-
-Scale the input by 2x and smooth using the Super2xSaI (Scale and
-Interpolate) pixel art scaling algorithm.
-
-Useful for enlarging pixel art images without reducing sharpness.
-
- at section swapuv
-Swap U & V plane.
-
- at section telecine
-
-Apply telecine process to the video.
-
-This filter accepts the following options:
-
- at table @option
- at item first_field
- at table @samp
- at item top, t
-top field first
- at item bottom, b
-bottom field first
-The default value is @code{top}.
- at end table
-
- at item pattern
-A string of numbers representing the pulldown pattern you wish to apply.
-The default value is @code{23}.
- at end table
-
- at example
-Some typical patterns:
-
-NTSC output (30i):
-27.5p: 32222
-24p: 23 (classic)
-24p: 2332 (preferred)
-20p: 33
-18p: 334
-16p: 3444
-
-PAL output (25i):
-27.5p: 12222
-24p: 222222222223 ("Euro pulldown")
-16.67p: 33
-16p: 33333334
- at end example
-
- at section thumbnail
-Select the most representative frame in a given sequence of consecutive frames.
-
-The filter accepts the following options:
-
- at table @option
- at item n
-Set the frames batch size to analyze; in a set of @var{n} frames, the filter
-will pick one of them, and then handle the next batch of @var{n} frames until
-the end. Default is @code{100}.
- at end table
-
-Since the filter keeps track of the whole frames sequence, a bigger @var{n}
-value will result in a higher memory usage, so a high value is not recommended.
-
- at subsection Examples
-
- at itemize
- at item
-Extract one picture each 50 frames:
- at example
-thumbnail=50
- at end example
-
- at item
-Complete example of a thumbnail creation with @command{ffmpeg}:
- at example
-ffmpeg -i in.avi -vf thumbnail,scale=300:200 -frames:v 1 out.png
- at end example
- at end itemize
-
- at section tile
-
-Tile several successive frames together.
-
-The filter accepts the following options:
-
- at table @option
-
- at item layout
-Set the grid size (i.e. the number of lines and columns). For the syntax of
-this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-
- at item nb_frames
-Set the maximum number of frames to render in the given area. It must be less
-than or equal to @var{w}x at var{h}. The default value is @code{0}, meaning all
-the area will be used.
-
- at item margin
-Set the outer border margin in pixels.
-
- at item padding
-Set the inner border thickness (i.e. the number of pixels between frames). For
-more advanced padding options (such as having different values for the edges),
-refer to the pad video filter.
-
- at item color
-Specify the color of the unused area. For the syntax of this option, check the
-"Color" section in the ffmpeg-utils manual. The default value of @var{color}
-is "black".
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Produce 8x8 PNG tiles of all keyframes (@option{-skip_frame nokey}) in a movie:
- at example
-ffmpeg -skip_frame nokey -i file.avi -vf 'scale=128:72,tile=8x8' -an -vsync 0 keyframes%03d.png
- at end example
-The @option{-vsync 0} is necessary to prevent @command{ffmpeg} from
-duplicating each output frame to accommodate the originally detected frame
-rate.
-
- at item
-Display @code{5} pictures in an area of @code{3x2} frames,
-with @code{7} pixels between them, and @code{2} pixels of initial margin, using
-mixed flat and named options:
- at example
-tile=3x2:nb_frames=5:padding=7:margin=2
- at end example
- at end itemize
-
- at section tinterlace
-
-Perform various types of temporal field interlacing.
-
-Frames are counted starting from 1, so the first input frame is
-considered odd.
-
-The filter accepts the following options:
-
- at table @option
-
- at item mode
-Specify the mode of the interlacing. This option can also be specified
-as a value alone. See below for a list of values for this option.
-
-Available values are:
-
- at table @samp
- at item merge, 0
-Move odd frames into the upper field, even into the lower field,
-generating a double height frame at half frame rate.
- at example
- ------> time
-Input:
-Frame 1 Frame 2 Frame 3 Frame 4
-
-11111 22222 33333 44444
-11111 22222 33333 44444
-11111 22222 33333 44444
-11111 22222 33333 44444
-
-Output:
-11111 33333
-22222 44444
-11111 33333
-22222 44444
-11111 33333
-22222 44444
-11111 33333
-22222 44444
- at end example
-
- at item drop_odd, 1
-Only output even frames, odd frames are dropped, generating a frame with
-unchanged height at half frame rate.
-
- at example
- ------> time
-Input:
-Frame 1 Frame 2 Frame 3 Frame 4
-
-11111 22222 33333 44444
-11111 22222 33333 44444
-11111 22222 33333 44444
-11111 22222 33333 44444
-
-Output:
- 22222 44444
- 22222 44444
- 22222 44444
- 22222 44444
- at end example
-
- at item drop_even, 2
-Only output odd frames, even frames are dropped, generating a frame with
-unchanged height at half frame rate.
-
- at example
- ------> time
-Input:
-Frame 1 Frame 2 Frame 3 Frame 4
-
-11111 22222 33333 44444
-11111 22222 33333 44444
-11111 22222 33333 44444
-11111 22222 33333 44444
-
-Output:
-11111 33333
-11111 33333
-11111 33333
-11111 33333
- at end example
-
- at item pad, 3
-Expand each frame to full height, but pad alternate lines with black,
-generating a frame with double height at the same input frame rate.
-
- at example
- ------> time
-Input:
-Frame 1 Frame 2 Frame 3 Frame 4
-
-11111 22222 33333 44444
-11111 22222 33333 44444
-11111 22222 33333 44444
-11111 22222 33333 44444
-
-Output:
-11111 ..... 33333 .....
-..... 22222 ..... 44444
-11111 ..... 33333 .....
-..... 22222 ..... 44444
-11111 ..... 33333 .....
-..... 22222 ..... 44444
-11111 ..... 33333 .....
-..... 22222 ..... 44444
- at end example
-
-
- at item interleave_top, 4
-Interleave the upper field from odd frames with the lower field from
-even frames, generating a frame with unchanged height at half frame rate.
-
- at example
- ------> time
-Input:
-Frame 1 Frame 2 Frame 3 Frame 4
-
-11111<- 22222 33333<- 44444
-11111 22222<- 33333 44444<-
-11111<- 22222 33333<- 44444
-11111 22222<- 33333 44444<-
-
-Output:
-11111 33333
-22222 44444
-11111 33333
-22222 44444
- at end example
-
-
- at item interleave_bottom, 5
-Interleave the lower field from odd frames with the upper field from
-even frames, generating a frame with unchanged height at half frame rate.
-
- at example
- ------> time
-Input:
-Frame 1 Frame 2 Frame 3 Frame 4
-
-11111 22222<- 33333 44444<-
-11111<- 22222 33333<- 44444
-11111 22222<- 33333 44444<-
-11111<- 22222 33333<- 44444
-
-Output:
-22222 44444
-11111 33333
-22222 44444
-11111 33333
- at end example
-
-
- at item interlacex2, 6
-Double frame rate with unchanged height. Frames are inserted each
-containing the second temporal field from the previous input frame and
-the first temporal field from the next input frame. This mode relies on
-the top_field_first flag. Useful for interlaced video displays with no
-field synchronisation.
-
- at example
- ------> time
-Input:
-Frame 1 Frame 2 Frame 3 Frame 4
-
-11111 22222 33333 44444
- 11111 22222 33333 44444
-11111 22222 33333 44444
- 11111 22222 33333 44444
-
-Output:
-11111 22222 22222 33333 33333 44444 44444
- 11111 11111 22222 22222 33333 33333 44444
-11111 22222 22222 33333 33333 44444 44444
- 11111 11111 22222 22222 33333 33333 44444
- at end example
-
-
- at end table
-
-Numeric values are deprecated but are accepted for backward
-compatibility reasons.
-
-Default mode is @code{merge}.
-
- at item flags
-Specify flags influencing the filter process.
-
-Available value for @var{flags} is:
-
- at table @option
- at item low_pass_filter, vlfp
-Enable vertical low-pass filtering in the filter.
-Vertical low-pass filtering is required when creating an interlaced
-destination from a progressive source which contains high-frequency
-vertical detail. Filtering will reduce interlace 'twitter' and Moire
-patterning.
-
-Vertical low-pass filtering can only be enabled for @option{mode}
- at var{interleave_top} and @var{interleave_bottom}.
-
- at end table
- at end table
-
- at section transpose
-
-Transpose rows with columns in the input video and optionally flip it.
-
-It accepts the following parameters:
-
- at table @option
-
- at item dir
-Specify the transposition direction.
-
-Can assume the following values:
- at table @samp
- at item 0, 4, cclock_flip
-Rotate by 90 degrees counterclockwise and vertically flip (default), that is:
- at example
-L.R L.l
-. . -> . .
-l.r R.r
- at end example
-
- at item 1, 5, clock
-Rotate by 90 degrees clockwise, that is:
- at example
-L.R l.L
-. . -> . .
-l.r r.R
- at end example
-
- at item 2, 6, cclock
-Rotate by 90 degrees counterclockwise, that is:
- at example
-L.R R.r
-. . -> . .
-l.r L.l
- at end example
-
- at item 3, 7, clock_flip
-Rotate by 90 degrees clockwise and vertically flip, that is:
- at example
-L.R r.R
-. . -> . .
-l.r l.L
- at end example
- at end table
-
-For values between 4-7, the transposition is only done if the input
-video geometry is portrait and not landscape. These values are
-deprecated, the @code{passthrough} option should be used instead.
-
-Numerical values are deprecated, and should be dropped in favor of
-symbolic constants.
-
- at item passthrough
-Do not apply the transposition if the input geometry matches the one
-specified by the specified value. It accepts the following values:
- at table @samp
- at item none
-Always apply transposition.
- at item portrait
-Preserve portrait geometry (when @var{height} >= @var{width}).
- at item landscape
-Preserve landscape geometry (when @var{width} >= @var{height}).
- at end table
-
-Default value is @code{none}.
- at end table
-
-For example to rotate by 90 degrees clockwise and preserve portrait
-layout:
- at example
-transpose=dir=1:passthrough=portrait
- at end example
-
-The command above can also be specified as:
- at example
-transpose=1:portrait
- at end example
-
- at section trim
-Trim the input so that the output contains one continuous subpart of the input.
-
-It accepts the following parameters:
- at table @option
- at item start
-Specify the time of the start of the kept section, i.e. the frame with the
-timestamp @var{start} will be the first frame in the output.
-
- at item end
-Specify the time of the first frame that will be dropped, i.e. the frame
-immediately preceding the one with the timestamp @var{end} will be the last
-frame in the output.
-
- at item start_pts
-This is the same as @var{start}, except this option sets the start timestamp
-in timebase units instead of seconds.
-
- at item end_pts
-This is the same as @var{end}, except this option sets the end timestamp
-in timebase units instead of seconds.
-
- at item duration
-The maximum duration of the output in seconds.
-
- at item start_frame
-The number of the first frame that should be passed to the output.
-
- at item end_frame
-The number of the first frame that should be dropped.
- at end table
-
- at option{start}, @option{end}, and @option{duration} are expressed as time
-duration specifications; see
- at ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}
-for the accepted syntax.
-
-Note that the first two sets of the start/end options and the @option{duration}
-option look at the frame timestamp, while the _frame variants simply count the
-frames that pass through the filter. Also note that this filter does not modify
-the timestamps. If you wish for the output timestamps to start at zero, insert a
-setpts filter after the trim filter.
-
-If multiple start or end options are set, this filter tries to be greedy and
-keep all the frames that match at least one of the specified constraints. To keep
-only the part that matches all the constraints at once, chain multiple trim
-filters.
-
-The defaults are such that all the input is kept. So it is possible to set e.g.
-just the end values to keep everything before the specified time.
-
-Examples:
- at itemize
- at item
-Drop everything except the second minute of input:
- at example
-ffmpeg -i INPUT -vf trim=60:120
- at end example
-
- at item
-Keep only the first second:
- at example
-ffmpeg -i INPUT -vf trim=duration=1
- at end example
-
- at end itemize
-
-
- at anchor{unsharp}
- at section unsharp
-
-Sharpen or blur the input video.
-
-It accepts the following parameters:
-
- at table @option
- at item luma_msize_x, lx
-Set the luma matrix horizontal size. It must be an odd integer between
-3 and 63. The default value is 5.
-
- at item luma_msize_y, ly
-Set the luma matrix vertical size. It must be an odd integer between 3
-and 63. The default value is 5.
-
- at item luma_amount, la
-Set the luma effect strength. It must be a floating point number, reasonable
-values lay between -1.5 and 1.5.
-
-Negative values will blur the input video, while positive values will
-sharpen it, a value of zero will disable the effect.
-
-Default value is 1.0.
-
- at item chroma_msize_x, cx
-Set the chroma matrix horizontal size. It must be an odd integer
-between 3 and 63. The default value is 5.
-
- at item chroma_msize_y, cy
-Set the chroma matrix vertical size. It must be an odd integer
-between 3 and 63. The default value is 5.
-
- at item chroma_amount, ca
-Set the chroma effect strength. It must be a floating point number, reasonable
-values lay between -1.5 and 1.5.
-
-Negative values will blur the input video, while positive values will
-sharpen it, a value of zero will disable the effect.
-
-Default value is 0.0.
-
- at item opencl
-If set to 1, specify using OpenCL capabilities, only available if
-FFmpeg was configured with @code{--enable-opencl}. Default value is 0.
-
- at end table
-
-All parameters are optional and default to the equivalent of the
-string '5:5:1.0:5:5:0.0'.
-
- at subsection Examples
-
- at itemize
- at item
-Apply strong luma sharpen effect:
- at example
-unsharp=luma_msize_x=7:luma_msize_y=7:luma_amount=2.5
- at end example
-
- at item
-Apply a strong blur of both luma and chroma parameters:
- at example
-unsharp=7:7:-2:7:7:-2
- at end example
- at end itemize
-
- at section uspp
-
-Apply ultra slow/simple postprocessing filter that compresses and decompresses
-the image at several (or - in the case of @option{quality} level @code{8} - all)
-shifts and average the results.
-
-The way this differs from the behavior of spp is that uspp actually encodes &
-decodes each case with libavcodec Snow, whereas spp uses a simplified intra only 8x8
-DCT similar to MJPEG.
-
-The filter accepts the following options:
-
- at table @option
- at item quality
-Set quality. This option defines the number of levels for averaging. It accepts
-an integer in the range 0-8. If set to @code{0}, the filter will have no
-effect. A value of @code{8} means the higher quality. For each increment of
-that value the speed drops by a factor of approximately 2. Default value is
- at code{3}.
-
- at item qp
-Force a constant quantization parameter. If not set, the filter will use the QP
-from the video stream (if available).
- at end table
-
- at section vectorscope
-
-Display 2 color component values in the two dimensional graph (which is called
-a vectorscope).
-
-This filter accepts the following options:
-
- at table @option
- at item mode, m
-Set vectorscope mode.
-
-It accepts the following values:
- at table @samp
- at item gray
-Gray values are displayed on graph, higher brightness means more pixels have
-same component color value on location in graph. This is the default mode.
-
- at item color
-Gray values are displayed on graph. Surrounding pixels values which are not
-present in video frame are drawn in gradient of 2 color components which are
-set by option @code{x} and @code{y}.
-
- at item color2
-Actual color components values present in video frame are displayed on graph.
-
- at item color3
-Similar as color2 but higher frequency of same values @code{x} and @code{y}
-on graph increases value of another color component, which is luminance by
-default values of @code{x} and @code{y}.
-
- at item color4
-Actual colors present in video frame are displayed on graph. If two different
-colors map to same position on graph then color with higher value of component
-not present in graph is picked.
- at end table
-
- at item x
-Set which color component will be represented on X-axis. Default is @code{1}.
-
- at item y
-Set which color component will be represented on Y-axis. Default is @code{2}.
-
- at item intensity, i
-Set intensity, used by modes: gray, color and color3 for increasing brightness
-of color component which represents frequency of (X, Y) location in graph.
-
- at item envelope, e
- at table @samp
- at item none
-No envelope, this is default.
-
- at item instant
-Instant envelope, even darkest single pixel will be clearly highlighted.
-
- at item peak
-Hold maximum and minimum values presented in graph over time. This way you
-can still spot out of range values without constantly looking at vectorscope.
-
- at item peak+instant
-Peak and instant envelope combined together.
- at end table
- at end table
-
- at anchor{vidstabdetect}
- at section vidstabdetect
-
-Analyze video stabilization/deshaking. Perform pass 1 of 2, see
- at ref{vidstabtransform} for pass 2.
-
-This filter generates a file with relative translation and rotation
-transform information about subsequent frames, which is then used by
-the @ref{vidstabtransform} filter.
-
-To enable compilation of this filter you need to configure FFmpeg with
- at code{--enable-libvidstab}.
-
-This filter accepts the following options:
-
- at table @option
- at item result
-Set the path to the file used to write the transforms information.
-Default value is @file{transforms.trf}.
-
- at item shakiness
-Set how shaky the video is and how quick the camera is. It accepts an
-integer in the range 1-10, a value of 1 means little shakiness, a
-value of 10 means strong shakiness. Default value is 5.
-
- at item accuracy
-Set the accuracy of the detection process. It must be a value in the
-range 1-15. A value of 1 means low accuracy, a value of 15 means high
-accuracy. Default value is 15.
-
- at item stepsize
-Set stepsize of the search process. The region around minimum is
-scanned with 1 pixel resolution. Default value is 6.
-
- at item mincontrast
-Set minimum contrast. Below this value a local measurement field is
-discarded. Must be a floating point value in the range 0-1. Default
-value is 0.3.
-
- at item tripod
-Set reference frame number for tripod mode.
-
-If enabled, the motion of the frames is compared to a reference frame
-in the filtered stream, identified by the specified number. The idea
-is to compensate all movements in a more-or-less static scene and keep
-the camera view absolutely still.
-
-If set to 0, it is disabled. The frames are counted starting from 1.
-
- at item show
-Show fields and transforms in the resulting frames. It accepts an
-integer in the range 0-2. Default value is 0, which disables any
-visualization.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Use default values:
- at example
-vidstabdetect
- at end example
-
- at item
-Analyze strongly shaky movie and put the results in file
- at file{mytransforms.trf}:
- at example
-vidstabdetect=shakiness=10:accuracy=15:result="mytransforms.trf"
- at end example
-
- at item
-Visualize the result of internal transformations in the resulting
-video:
- at example
-vidstabdetect=show=1
- at end example
-
- at item
-Analyze a video with medium shakiness using @command{ffmpeg}:
- at example
-ffmpeg -i input -vf vidstabdetect=shakiness=5:show=1 dummy.avi
- at end example
- at end itemize
-
- at anchor{vidstabtransform}
- at section vidstabtransform
-
-Video stabilization/deshaking: pass 2 of 2,
-see @ref{vidstabdetect} for pass 1.
-
-Read a file with transform information for each frame and
-apply/compensate them. Together with the @ref{vidstabdetect}
-filter this can be used to deshake videos. See also
- at url{http://public.hronopik.de/vid.stab}. It is important to also use
-the @ref{unsharp} filter, see below.
-
-To enable compilation of this filter you need to configure FFmpeg with
- at code{--enable-libvidstab}.
-
- at subsection Options
-
- at table @option
- at item input
-Set path to the file used to read the transforms. Default value is
- at file{transforms.trf}.
-
- at item smoothing
-Set the number of frames (value*2 + 1) used for lowpass filtering the
-camera movements. Default value is 10.
-
-For example a number of 10 means that 21 frames are used (10 in the
-past and 10 in the future) to smoothen the motion in the video. A
-larger value leads to a smoother video, but limits the acceleration of
-the camera (pan/tilt movements). 0 is a special case where a static
-camera is simulated.
-
- at item optalgo
-Set the camera path optimization algorithm.
-
-Accepted values are:
- at table @samp
- at item gauss
-gaussian kernel low-pass filter on camera motion (default)
- at item avg
-averaging on transformations
- at end table
-
- at item maxshift
-Set maximal number of pixels to translate frames. Default value is -1,
-meaning no limit.
-
- at item maxangle
-Set maximal angle in radians (degree*PI/180) to rotate frames. Default
-value is -1, meaning no limit.
-
- at item crop
-Specify how to deal with borders that may be visible due to movement
-compensation.
-
-Available values are:
- at table @samp
- at item keep
-keep image information from previous frame (default)
- at item black
-fill the border black
- at end table
-
- at item invert
-Invert transforms if set to 1. Default value is 0.
-
- at item relative
-Consider transforms as relative to previous frame if set to 1,
-absolute if set to 0. Default value is 0.
-
- at item zoom
-Set percentage to zoom. A positive value will result in a zoom-in
-effect, a negative value in a zoom-out effect. Default value is 0 (no
-zoom).
-
- at item optzoom
-Set optimal zooming to avoid borders.
-
-Accepted values are:
- at table @samp
- at item 0
-disabled
- at item 1
-optimal static zoom value is determined (only very strong movements
-will lead to visible borders) (default)
- at item 2
-optimal adaptive zoom value is determined (no borders will be
-visible), see @option{zoomspeed}
- at end table
-
-Note that the value given at zoom is added to the one calculated here.
-
- at item zoomspeed
-Set percent to zoom maximally each frame (enabled when
- at option{optzoom} is set to 2). Range is from 0 to 5, default value is
-0.25.
-
- at item interpol
-Specify type of interpolation.
-
-Available values are:
- at table @samp
- at item no
-no interpolation
- at item linear
-linear only horizontal
- at item bilinear
-linear in both directions (default)
- at item bicubic
-cubic in both directions (slow)
- at end table
-
- at item tripod
-Enable virtual tripod mode if set to 1, which is equivalent to
- at code{relative=0:smoothing=0}. Default value is 0.
-
-Use also @code{tripod} option of @ref{vidstabdetect}.
-
- at item debug
-Increase log verbosity if set to 1. Also the detected global motions
-are written to the temporary file @file{global_motions.trf}. Default
-value is 0.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Use @command{ffmpeg} for a typical stabilization with default values:
- at example
-ffmpeg -i inp.mpeg -vf vidstabtransform,unsharp=5:5:0.8:3:3:0.4 inp_stabilized.mpeg
- at end example
-
-Note the use of the @ref{unsharp} filter which is always recommended.
-
- at item
-Zoom in a bit more and load transform data from a given file:
- at example
-vidstabtransform=zoom=5:input="mytransforms.trf"
- at end example
-
- at item
-Smoothen the video even more:
- at example
-vidstabtransform=smoothing=30
- at end example
- at end itemize
-
- at section vflip
-
-Flip the input video vertically.
-
-For example, to vertically flip a video with @command{ffmpeg}:
- at example
-ffmpeg -i in.avi -vf "vflip" out.avi
- at end example
-
- at anchor{vignette}
- at section vignette
-
-Make or reverse a natural vignetting effect.
-
-The filter accepts the following options:
-
- at table @option
- at item angle, a
-Set lens angle expression as a number of radians.
-
-The value is clipped in the @code{[0,PI/2]} range.
-
-Default value: @code{"PI/5"}
-
- at item x0
- at item y0
-Set center coordinates expressions. Respectively @code{"w/2"} and @code{"h/2"}
-by default.
-
- at item mode
-Set forward/backward mode.
-
-Available modes are:
- at table @samp
- at item forward
-The larger the distance from the central point, the darker the image becomes.
-
- at item backward
-The larger the distance from the central point, the brighter the image becomes.
-This can be used to reverse a vignette effect, though there is no automatic
-detection to extract the lens @option{angle} and other settings (yet). It can
-also be used to create a burning effect.
- at end table
-
-Default value is @samp{forward}.
-
- at item eval
-Set evaluation mode for the expressions (@option{angle}, @option{x0}, @option{y0}).
-
-It accepts the following values:
- at table @samp
- at item init
-Evaluate expressions only once during the filter initialization.
-
- at item frame
-Evaluate expressions for each incoming frame. This is way slower than the
- at samp{init} mode since it requires all the scalers to be re-computed, but it
-allows advanced dynamic expressions.
- at end table
-
-Default value is @samp{init}.
-
- at item dither
-Set dithering to reduce the circular banding effects. Default is @code{1}
-(enabled).
-
- at item aspect
-Set vignette aspect. This setting allows one to adjust the shape of the vignette.
-Setting this value to the SAR of the input will make a rectangular vignetting
-following the dimensions of the video.
-
-Default is @code{1/1}.
- at end table
-
- at subsection Expressions
-
-The @option{alpha}, @option{x0} and @option{y0} expressions can contain the
-following parameters.
-
- at table @option
- at item w
- at item h
-input width and height
-
- at item n
-the number of input frame, starting from 0
-
- at item pts
-the PTS (Presentation TimeStamp) time of the filtered video frame, expressed in
- at var{TB} units, NAN if undefined
-
- at item r
-frame rate of the input video, NAN if the input frame rate is unknown
-
- at item t
-the PTS (Presentation TimeStamp) of the filtered video frame,
-expressed in seconds, NAN if undefined
-
- at item tb
-time base of the input video
- at end table
-
-
- at subsection Examples
-
- at itemize
- at item
-Apply simple strong vignetting effect:
- at example
-vignette=PI/4
- at end example
-
- at item
-Make a flickering vignetting:
- at example
-vignette='PI/4+random(1)*PI/50':eval=frame
- at end example
-
- at end itemize
-
- at section vstack
-Stack input videos vertically.
-
-All streams must be of same pixel format and of same width.
-
-Note that this filter is faster than using @ref{overlay} and @ref{pad} filter
-to create same output.
-
-The filter accept the following option:
-
- at table @option
- at item nb_inputs
-Set number of input streams. Default is 2.
- at end table
-
- at section w3fdif
-
-Deinterlace the input video ("w3fdif" stands for "Weston 3 Field
-Deinterlacing Filter").
-
-Based on the process described by Martin Weston for BBC R&D, and
-implemented based on the de-interlace algorithm written by Jim
-Easterbrook for BBC R&D, the Weston 3 field deinterlacing filter
-uses filter coefficients calculated by BBC R&D.
-
-There are two sets of filter coefficients, so called "simple":
-and "complex". Which set of filter coefficients is used can
-be set by passing an optional parameter:
-
- at table @option
- at item filter
-Set the interlacing filter coefficients. Accepts one of the following values:
-
- at table @samp
- at item simple
-Simple filter coefficient set.
- at item complex
-More-complex filter coefficient set.
- at end table
-Default value is @samp{complex}.
-
- at item deint
-Specify which frames to deinterlace. Accept one of the following values:
-
- at table @samp
- at item all
-Deinterlace all frames,
- at item interlaced
-Only deinterlace frames marked as interlaced.
- at end table
-
-Default value is @samp{all}.
- at end table
-
- at section waveform
-Video waveform monitor.
-
-The waveform monitor plots color component intensity. By default luminance
-only. Each column of the waveform corresponds to a column of pixels in the
-source video.
-
-It accepts the following options:
-
- at table @option
- at item mode, m
-Can be either @code{row}, or @code{column}. Default is @code{column}.
-In row mode, the graph on the left side represents color component value 0 and
-the right side represents value = 255. In column mode, the top side represents
-color component value = 0 and bottom side represents value = 255.
-
- at item intensity, i
-Set intensity. Smaller values are useful to find out how many values of the same
-luminance are distributed across input rows/columns.
-Default value is @code{0.04}. Allowed range is [0, 1].
-
- at item mirror, r
-Set mirroring mode. @code{0} means unmirrored, @code{1} means mirrored.
-In mirrored mode, higher values will be represented on the left
-side for @code{row} mode and at the top for @code{column} mode. Default is
- at code{1} (mirrored).
-
- at item display, d
-Set display mode.
-It accepts the following values:
- at table @samp
- at item overlay
-Presents information identical to that in the @code{parade}, except
-that the graphs representing color components are superimposed directly
-over one another.
-
-This display mode makes it easier to spot relative differences or similarities
-in overlapping areas of the color components that are supposed to be identical,
-such as neutral whites, grays, or blacks.
-
- at item parade
-Display separate graph for the color components side by side in
- at code{row} mode or one below the other in @code{column} mode.
-
-Using this display mode makes it easy to spot color casts in the highlights
-and shadows of an image, by comparing the contours of the top and the bottom
-graphs of each waveform. Since whites, grays, and blacks are characterized
-by exactly equal amounts of red, green, and blue, neutral areas of the picture
-should display three waveforms of roughly equal width/height. If not, the
-correction is easy to perform by making level adjustments the three waveforms.
- at end table
-Default is @code{parade}.
-
- at item components, c
-Set which color components to display. Default is 1, which means only luminance
-or red color component if input is in RGB colorspace. If is set for example to
-7 it will display all 3 (if) available color components.
-
- at item envelope, e
- at table @samp
- at item none
-No envelope, this is default.
-
- at item instant
-Instant envelope, minimum and maximum values presented in graph will be easily
-visible even with small @code{step} value.
-
- at item peak
-Hold minimum and maximum values presented in graph across time. This way you
-can still spot out of range values without constantly looking at waveforms.
-
- at item peak+instant
-Peak and instant envelope combined together.
- at end table
-
- at item filter, f
- at table @samp
- at item lowpass
-No filtering, this is default.
-
- at item flat
-Luma and chroma combined together.
-
- at item aflat
-Similar as above, but shows difference between blue and red chroma.
-
- at item chroma
-Displays only chroma.
-
- at item achroma
-Similar as above, but shows difference between blue and red chroma.
-
- at item color
-Displays actual color value on waveform.
- at end table
- at end table
-
- at section xbr
-Apply the xBR high-quality magnification filter which is designed for pixel
-art. It follows a set of edge-detection rules, see
- at url{http://www.libretro.com/forums/viewtopic.php?f=6&t=134}.
-
-It accepts the following option:
-
- at table @option
- at item n
-Set the scaling dimension: @code{2} for @code{2xBR}, @code{3} for
- at code{3xBR} and @code{4} for @code{4xBR}.
-Default is @code{3}.
- at end table
-
- at anchor{yadif}
- at section yadif
-
-Deinterlace the input video ("yadif" means "yet another deinterlacing
-filter").
-
-It accepts the following parameters:
-
-
- at table @option
-
- at item mode
-The interlacing mode to adopt. It accepts one of the following values:
-
- at table @option
- at item 0, send_frame
-Output one frame for each frame.
- at item 1, send_field
-Output one frame for each field.
- at item 2, send_frame_nospatial
-Like @code{send_frame}, but it skips the spatial interlacing check.
- at item 3, send_field_nospatial
-Like @code{send_field}, but it skips the spatial interlacing check.
- at end table
-
-The default value is @code{send_frame}.
-
- at item parity
-The picture field parity assumed for the input interlaced video. It accepts one
-of the following values:
-
- at table @option
- at item 0, tff
-Assume the top field is first.
- at item 1, bff
-Assume the bottom field is first.
- at item -1, auto
-Enable automatic detection of field parity.
- at 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.
-
- at item deint
-Specify which frames to deinterlace. Accept one of the following
-values:
-
- at table @option
- at item 0, all
-Deinterlace all frames.
- at item 1, interlaced
-Only deinterlace frames marked as interlaced.
- at end table
-
-The default value is @code{all}.
- at end table
-
- at section zoompan
-
-Apply Zoom & Pan effect.
-
-This filter accepts the following options:
-
- at table @option
- at item zoom, z
-Set the zoom expression. Default is 1.
-
- at item x
- at item y
-Set the x and y expression. Default is 0.
-
- at 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.
-
- at item s
-Set the output image size, default is 'hd720'.
- at end table
-
-Each expression can contain the following constants:
-
- at table @option
- at item in_w, iw
-Input width.
-
- at item in_h, ih
-Input height.
-
- at item out_w, ow
-Output width.
-
- at item out_h, oh
-Output height.
-
- at item in
-Input frame count.
-
- at item on
-Output frame count.
-
- at item x
- at item y
-Last calculated 'x' and 'y' position from 'x' and 'y' expression
-for current input frame.
-
- at item px
- at item py
-'x' and 'y' of last output frame of previous input frame or 0 when there was
-not yet such frame (first input frame).
-
- at item zoom
-Last calculated zoom from 'z' expression for current input frame.
-
- at item pzoom
-Last calculated zoom of last output frame of previous input frame.
-
- at item duration
-Number of output frames for current input frame. Calculated from 'd' expression
-for each input frame.
-
- at item pduration
-number of output frames created for previous input frame
-
- at item a
-Rational number: input width / input height
-
- at item sar
-sample aspect ratio
-
- at item dar
-display aspect ratio
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Zoom-in up to 1.5 and pan at same time to some spot near center of picture:
- at 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
- at end example
-
- at item
-Zoom-in up to 1.5 and pan always at center of picture:
- at example
-zoompan=z='min(zoom+0.0015,1.5)':d=700:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)'
- at end example
- at end itemize
-
- at c man end VIDEO FILTERS
-
- at chapter Video Sources
- at c man begin VIDEO SOURCES
-
-Below is a description of the currently available video sources.
-
- at section buffer
-
-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}.
-
-It accepts the following parameters:
-
- at table @option
-
- at item video_size
-Specify the size (width and height) of the buffered video frames. For the
-syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-
- at item width
-The input video width.
-
- at item height
-The input video height.
-
- at item pix_fmt
-A string representing the pixel format of the buffered video frames.
-It may be a number corresponding to a pixel format, or a pixel format
-name.
-
- at item time_base
-Specify the timebase assumed by the timestamps of the buffered frames.
-
- at item frame_rate
-Specify the frame rate expected for the video stream.
-
- at item pixel_aspect, sar
-The sample (pixel) aspect ratio of the input video.
-
- at item sws_param
-Specify the optional parameters to be used for the scale filter which
-is automatically inserted when an input change is detected in the
-input size or format.
- at end table
-
-For example:
- at example
-buffer=width=320:height=240:pix_fmt=yuv410p:time_base=1/24:sar=1
- at end example
-
-will instruct the source to accept video frames with size 320x240 and
-with format "yuv410p", assuming 1/24 as the timestamps timebase and
-square pixels (1:1 sample aspect ratio).
-Since the pixel format with name "yuv410p" corresponds to the number 6
-(check the enum AVPixelFormat definition in @file{libavutil/pixfmt.h}),
-this example corresponds to:
- at example
-buffer=size=320x240:pixfmt=6:time_base=1/24:pixel_aspect=1/1
- at end example
-
-Alternatively, the options can be specified as a flat string, but this
-syntax is deprecated:
-
- at var{width}:@var{height}:@var{pix_fmt}:@var{time_base.num}:@var{time_base.den}:@var{pixel_aspect.num}:@var{pixel_aspect.den}[:@var{sws_param}]
-
- at section cellauto
-
-Create a pattern generated by an elementary cellular automaton.
-
-The initial state of the cellular automaton can be defined through the
- at option{filename}, and @option{pattern} options. If such options are
-not specified an initial state is created randomly.
-
-At each new frame a new row in the video is filled with the result of
-the cellular automaton next generation. The behavior when the whole
-frame is filled is defined by the @option{scroll} option.
-
-This source accepts the following options:
-
- at table @option
- at item filename, f
-Read the initial cellular automaton state, i.e. the starting row, from
-the specified file.
-In the file, each non-whitespace character is considered an alive
-cell, a newline will terminate the row, and further characters in the
-file will be ignored.
-
- at item pattern, p
-Read the initial cellular automaton state, i.e. the starting row, from
-the specified string.
-
-Each non-whitespace character in the string is considered an alive
-cell, a newline will terminate the row, and further characters in the
-string will be ignored.
-
- at item rate, r
-Set the video rate, that is the number of frames generated per second.
-Default is 25.
-
- at item random_fill_ratio, ratio
-Set the random fill ratio for the initial cellular automaton row. It
-is a floating point number value ranging from 0 to 1, defaults to
-1/PHI.
-
-This option is ignored when a file or a pattern is specified.
-
- at item random_seed, seed
-Set the seed for filling randomly the initial row, must be an integer
-included between 0 and UINT32_MAX. If not specified, or if explicitly
-set to -1, the filter will try to use a good random seed on a best
-effort basis.
-
- at item rule
-Set the cellular automaton rule, it is a number ranging from 0 to 255.
-Default value is 110.
-
- at item size, s
-Set the size of the output video. For the syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-
-If @option{filename} or @option{pattern} is specified, the size is set
-by default to the width of the specified initial state row, and the
-height is set to @var{width} * PHI.
-
-If @option{size} is set, it must contain the width of the specified
-pattern string, and the specified pattern will be centered in the
-larger row.
-
-If a filename or a pattern string is not specified, the size value
-defaults to "320x518" (used for a randomly generated initial state).
-
- at item scroll
-If set to 1, scroll the output upward when all the rows in the output
-have been already filled. If set to 0, the new generated row will be
-written over the top row just after the bottom row is filled.
-Defaults to 1.
-
- at item start_full, full
-If set to 1, completely fill the output with generated rows before
-outputting the first frame.
-This is the default behavior, for disabling set the value to 0.
-
- at item stitch
-If set to 1, stitch the left and right row edges together.
-This is the default behavior, for disabling set the value to 0.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Read the initial state from @file{pattern}, and specify an output of
-size 200x400.
- at example
-cellauto=f=pattern:s=200x400
- at end example
-
- at item
-Generate a random initial row with a width of 200 cells, with a fill
-ratio of 2/3:
- at example
-cellauto=ratio=2/3:s=200x200
- at end example
-
- at item
-Create a pattern generated by rule 18 starting by a single alive cell
-centered on an initial row with width 100:
- at example
-cellauto=p=@@:s=100x400:full=0:rule=18
- at end example
-
- at item
-Specify a more elaborated initial pattern:
- at example
-cellauto=p='@@@@ @@ @@@@':s=100x400:full=0:rule=18
- at end example
-
- at end itemize
-
- at section mandelbrot
-
-Generate a Mandelbrot set fractal, and progressively zoom towards the
-point specified with @var{start_x} and @var{start_y}.
-
-This source accepts the following options:
-
- at table @option
-
- at item end_pts
-Set the terminal pts value. Default value is 400.
-
- at item end_scale
-Set the terminal scale value.
-Must be a floating point value. Default value is 0.3.
-
- at item inner
-Set the inner coloring mode, that is the algorithm used to draw the
-Mandelbrot fractal internal region.
-
-It shall assume one of the following values:
- at table @option
- at item black
-Set black mode.
- at item convergence
-Show time until convergence.
- at item mincol
-Set color based on point closest to the origin of the iterations.
- at item period
-Set period mode.
- at end table
-
-Default value is @var{mincol}.
-
- at item bailout
-Set the bailout value. Default value is 10.0.
-
- at item maxiter
-Set the maximum of iterations performed by the rendering
-algorithm. Default value is 7189.
-
- at item outer
-Set outer coloring mode.
-It shall assume one of following values:
- at table @option
- at item iteration_count
-Set iteration cound mode.
- at item normalized_iteration_count
-set normalized iteration count mode.
- at end table
-Default value is @var{normalized_iteration_count}.
-
- at item rate, r
-Set frame rate, expressed as number of frames per second. Default
-value is "25".
-
- at item size, s
-Set frame size. For the syntax of this option, check the "Video
-size" section in the ffmpeg-utils manual. Default value is "640x480".
-
- at item start_scale
-Set the initial scale value. Default value is 3.0.
-
- at item start_x
-Set the initial x position. Must be a floating point value between
--100 and 100. Default value is -0.743643887037158704752191506114774.
-
- at item start_y
-Set the initial y position. Must be a floating point value between
--100 and 100. Default value is -0.131825904205311970493132056385139.
- at end table
-
- at section mptestsrc
-
-Generate various test patterns, as generated by the MPlayer test filter.
-
-The size of the generated video is fixed, and is 256x256.
-This source is useful in particular for testing encoding features.
-
-This source accepts the following options:
-
- at table @option
-
- at item rate, r
-Specify the frame rate of the sourced video, as the number of frames
-generated per second. It has to be a string in the format
- at var{frame_rate_num}/@var{frame_rate_den}, an integer number, a floating point
-number or a valid video frame rate abbreviation. The default value is
-"25".
-
- at item duration, d
-Set the duration of the sourced video. See
- at 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.
-
- at item test, t
-
-Set the number or the name of the test to perform. Supported tests are:
- at table @option
- at item dc_luma
- at item dc_chroma
- at item freq_luma
- at item freq_chroma
- at item amp_luma
- at item amp_chroma
- at item cbp
- at item mv
- at item ring1
- at item ring2
- at item all
-
- at end table
-
-Default value is "all", which will cycle through the list of all tests.
- at end table
-
-Some examples:
- at example
-mptestsrc=t=dc_luma
- at end example
-
-will generate a "dc_luma" test pattern.
-
- at section frei0r_src
-
-Provide a frei0r source.
-
-To enable compilation of this filter you need to install the frei0r
-header and configure FFmpeg with @code{--enable-frei0r}.
-
-This source accepts the following parameters:
-
- at table @option
-
- at item size
-The size of the video to generate. For the syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-
- at item framerate
-The framerate of the generated video. It may be a string of the form
- at var{num}/@var{den} or a frame rate abbreviation.
-
- at item filter_name
-The name to the frei0r source to load. For more information regarding frei0r and
-how to set the parameters, read the @ref{frei0r} section in the video filters
-documentation.
-
- at item filter_params
-A '|'-separated list of parameters to pass to the frei0r source.
-
- at end table
-
-For example, to generate a frei0r partik0l source with size 200x200
-and frame rate 10 which is overlaid on the overlay filter main input:
- at example
-frei0r_src=size=200x200:framerate=10:filter_name=partik0l:filter_params=1234 [overlay]; [in][overlay] overlay
- at end example
-
- at section life
-
-Generate a life pattern.
-
-This source is based on a generalization of John Conway's life game.
-
-The sourced input represents a life grid, each pixel represents a cell
-which can be in one of two possible states, alive or dead. Every cell
-interacts with its eight neighbours, which are the cells that are
-horizontally, vertically, or diagonally adjacent.
-
-At each interaction the grid evolves according to the adopted rule,
-which specifies the number of neighbor alive cells which will make a
-cell stay alive or born. The @option{rule} option allows one to specify
-the rule to adopt.
-
-This source accepts the following options:
-
- at table @option
- at item filename, f
-Set the file from which to read the initial grid state. In the file,
-each non-whitespace character is considered an alive cell, and newline
-is used to delimit the end of each row.
-
-If this option is not specified, the initial grid is generated
-randomly.
-
- at item rate, r
-Set the video rate, that is the number of frames generated per second.
-Default is 25.
-
- at item random_fill_ratio, ratio
-Set the random fill ratio for the initial random grid. It is a
-floating point number value ranging from 0 to 1, defaults to 1/PHI.
-It is ignored when a file is specified.
-
- at item random_seed, seed
-Set the seed for filling the initial random grid, must be an integer
-included between 0 and UINT32_MAX. If not specified, or if explicitly
-set to -1, the filter will try to use a good random seed on a best
-effort basis.
-
- at item rule
-Set the life rule.
-
-A rule can be specified with a code of the kind "S at var{NS}/B at var{NB}",
-where @var{NS} and @var{NB} are sequences of numbers in the range 0-8,
- at var{NS} specifies the number of alive neighbor cells which make a
-live cell stay alive, and @var{NB} the number of alive neighbor cells
-which make a dead cell to become alive (i.e. to "born").
-"s" and "b" can be used in place of "S" and "B", respectively.
-
-Alternatively a rule can be specified by an 18-bits integer. The 9
-high order bits are used to encode the next cell state if it is alive
-for each number of neighbor alive cells, the low order bits specify
-the rule for "borning" new cells. Higher order bits encode for an
-higher number of neighbor cells.
-For example the number 6153 = @code{(12<<9)+9} specifies a stay alive
-rule of 12 and a born rule of 9, which corresponds to "S23/B03".
-
-Default value is "S23/B3", which is the original Conway's game of life
-rule, and will keep a cell alive if it has 2 or 3 neighbor alive
-cells, and will born a new cell if there are three alive cells around
-a dead cell.
-
- at item size, s
-Set the size of the output video. For the syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-
-If @option{filename} is specified, the size is set by default to the
-same size of the input file. If @option{size} is set, it must contain
-the size specified in the input file, and the initial grid defined in
-that file is centered in the larger resulting area.
-
-If a filename is not specified, the size value defaults to "320x240"
-(used for a randomly generated initial grid).
-
- at item stitch
-If set to 1, stitch the left and right grid edges together, and the
-top and bottom edges also. Defaults to 1.
-
- at item mold
-Set cell mold speed. If set, a dead cell will go from @option{death_color} to
- at option{mold_color} with a step of @option{mold}. @option{mold} can have a
-value from 0 to 255.
-
- at item life_color
-Set the color of living (or new born) cells.
-
- at item death_color
-Set the color of dead cells. If @option{mold} is set, this is the first color
-used to represent a dead cell.
-
- at item mold_color
-Set mold color, for definitely dead and moldy cells.
-
-For the syntax of these 3 color options, check the "Color" section in the
-ffmpeg-utils manual.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Read a grid from @file{pattern}, and center it on a grid of size
-300x300 pixels:
- at example
-life=f=pattern:s=300x300
- at end example
-
- at item
-Generate a random grid of size 200x200, with a fill ratio of 2/3:
- at example
-life=ratio=2/3:s=200x200
- at end example
-
- at item
-Specify a custom rule for evolving a randomly generated grid:
- at example
-life=rule=S14/B34
- at end example
-
- at item
-Full example with slow death effect (mold) using @command{ffplay}:
- at example
-ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_color=#00ff00,scale=1200:800:flags=16
- at end example
- at end itemize
-
- at anchor{allrgb}
- at anchor{allyuv}
- at anchor{color}
- at anchor{haldclutsrc}
- at anchor{nullsrc}
- at anchor{rgbtestsrc}
- at anchor{smptebars}
- at anchor{smptehdbars}
- at anchor{testsrc}
- at section allrgb, allyuv, color, haldclutsrc, nullsrc, rgbtestsrc, smptebars, smptehdbars, testsrc
-
-The @code{allrgb} source returns frames of size 4096x4096 of all rgb colors.
-
-The @code{allyuv} source returns frames of size 4096x4096 of all yuv colors.
-
-The @code{color} source provides an uniformly colored input.
-
-The @code{haldclutsrc} source provides an identity Hald CLUT. See also
- at ref{haldclut} filter.
-
-The @code{nullsrc} source returns unprocessed video frames. It is
-mainly useful to be employed in analysis / debugging tools, or as the
-source for filters which ignore the input data.
-
-The @code{rgbtestsrc} source generates an RGB test pattern useful for
-detecting RGB vs BGR issues. You should see a red, green and blue
-stripe from top to bottom.
-
-The @code{smptebars} source generates a color bars pattern, based on
-the SMPTE Engineering Guideline EG 1-1990.
-
-The @code{smptehdbars} source generates a color bars pattern, based on
-the SMPTE RP 219-2002.
-
-The @code{testsrc} source generates a test video pattern, showing a
-color pattern, a scrolling gradient and a timestamp. This is mainly
-intended for testing purposes.
-
-The sources accept the following parameters:
-
- at table @option
-
- at item color, c
-Specify the color of the source, only available in the @code{color}
-source. For the syntax of this option, check the "Color" section in the
-ffmpeg-utils manual.
-
- at item level
-Specify the level of the Hald CLUT, only available in the @code{haldclutsrc}
-source. A level of @code{N} generates a picture of @code{N*N*N} by @code{N*N*N}
-pixels to be used as identity matrix for 3D lookup tables. Each component is
-coded on a @code{1/(N*N)} scale.
-
- at item size, s
-Specify the size of the sourced video. For the syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-The default value is @code{320x240}.
-
-This option is not available with the @code{haldclutsrc} filter.
-
- at item rate, r
-Specify the frame rate of the sourced video, as the number of frames
-generated per second. It has to be a string in the format
- at var{frame_rate_num}/@var{frame_rate_den}, an integer number, a floating point
-number or a valid video frame rate abbreviation. The default value is
-"25".
-
- at item sar
-Set the sample aspect ratio of the sourced video.
-
- at item duration, d
-Set the duration of the sourced video. See
- at 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.
-
- at item decimals, n
-Set the number of decimals to show in the timestamp, only available in the
- at code{testsrc} source.
-
-The displayed timestamp value will correspond to the original
-timestamp value multiplied by the power of 10 of the specified
-value. Default value is 0.
- at end table
-
-For example the following:
- at example
-testsrc=duration=5.3:size=qcif:rate=10
- at end example
-
-will generate a video with a duration of 5.3 seconds, with size
-176x144 and a frame rate of 10 frames per second.
-
-The following graph description will generate a red source
-with an opacity of 0.2, with size "qcif" and a frame rate of 10
-frames per second.
- at example
-color=c=red@@0.2:s=qcif:r=10
- at end example
-
-If the input content is to be ignored, @code{nullsrc} can be used. The
-following command generates noise in the luminance plane by employing
-the @code{geq} filter:
- at example
-nullsrc=s=256x256, geq=random(1)*255:128:128
- at end example
-
- at subsection Commands
-
-The @code{color} source supports the following commands:
-
- at table @option
- at item c, color
-Set the color of the created image. Accepts the same syntax of the
-corresponding @option{color} option.
- at end table
-
- at c man end VIDEO SOURCES
-
- at chapter Video Sinks
- at c man begin VIDEO SINKS
-
-Below is a description of the currently available video sinks.
-
- at section buffersink
-
-Buffer video frames, and make them available to the end of the filter
-graph.
-
-This sink is mainly intended for programmatic use, in particular
-through the interface defined in @file{libavfilter/buffersink.h}
-or the options system.
-
-It accepts a pointer to an AVBufferSinkContext structure, which
-defines the incoming buffers' formats, to be passed as the opaque
-parameter to @code{avfilter_init_filter} for initialization.
-
- at section nullsink
-
-Null video sink: do absolutely nothing with the input video. It is
-mainly useful as a template and for use in analysis / debugging
-tools.
-
- at c man end VIDEO SINKS
-
- at chapter Multimedia Filters
- at c man begin MULTIMEDIA FILTERS
-
-Below is a description of the currently available multimedia filters.
-
- at section aphasemeter
-
-Convert input audio to a video output, displaying the audio phase.
-
-The filter accepts the following options:
-
- at table @option
- at item rate, r
-Set the output frame rate. Default value is @code{25}.
-
- at item size, s
-Set the video size for the output. For the syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-Default value is @code{800x400}.
-
- at item rc
- at item gc
- at item bc
-Specify the red, green, blue contrast. Default values are @code{2},
- at code{7} and @code{1}.
-Allowed range is @code{[0, 255]}.
-
- at item mpc
-Set color which will be used for drawing median phase. If color is
- at code{none} which is default, no median phase value will be drawn.
- at end table
-
-The filter also exports the frame metadata @code{lavfi.aphasemeter.phase} which
-represents mean phase of current audio frame. Value is in range @code{[-1, 1]}.
-The @code{-1} means left and right channels are completely out of phase and
- at code{1} means channels are in phase.
-
- at section avectorscope
-
-Convert input audio to a video output, representing the audio vector
-scope.
-
-The filter is used to measure the difference between channels of stereo
-audio stream. A monoaural signal, consisting of identical left and right
-signal, results in straight vertical line. Any stereo separation is visible
-as a deviation from this line, creating a Lissajous figure.
-If the straight (or deviation from it) but horizontal line appears this
-indicates that the left and right channels are out of phase.
-
-The filter accepts the following options:
-
- at table @option
- at item mode, m
-Set the vectorscope mode.
-
-Available values are:
- at table @samp
- at item lissajous
-Lissajous rotated by 45 degrees.
-
- at item lissajous_xy
-Same as above but not rotated.
-
- at item polar
-Shape resembling half of circle.
- at end table
-
-Default value is @samp{lissajous}.
-
- at item size, s
-Set the video size for the output. For the syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-Default value is @code{400x400}.
-
- at item rate, r
-Set the output frame rate. Default value is @code{25}.
-
- at item rc
- at item gc
- at item bc
- at item ac
-Specify the red, green, blue and alpha contrast. Default values are @code{40},
- at code{160}, @code{80} and @code{255}.
-Allowed range is @code{[0, 255]}.
-
- at item rf
- at item gf
- at item bf
- at item af
-Specify the red, green, blue and alpha fade. Default values are @code{15},
- at code{10}, @code{5} and @code{5}.
-Allowed range is @code{[0, 255]}.
-
- at item zoom
-Set the zoom factor. Default value is @code{1}. Allowed range is @code{[1, 10]}.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Complete example using @command{ffplay}:
- at example
-ffplay -f lavfi 'amovie=input.mp3, asplit [a][out1];
- [a] avectorscope=zoom=1.3:rc=2:gc=200:bc=10:rf=1:gf=8:bf=7 [out0]'
- at end example
- at end itemize
-
- at section concat
-
-Concatenate audio and video streams, joining them together one after the
-other.
-
-The filter works on segments of synchronized video and audio streams. All
-segments must have the same number of streams of each type, and that will
-also be the number of streams at output.
-
-The filter accepts the following options:
-
- at table @option
-
- at item n
-Set the number of segments. Default is 2.
-
- at item v
-Set the number of output video streams, that is also the number of video
-streams in each segment. Default is 1.
-
- at item a
-Set the number of output audio streams, that is also the number of audio
-streams in each segment. Default is 0.
-
- at item unsafe
-Activate unsafe mode: do not fail if segments have a different format.
-
- at end table
-
-The filter has @var{v}+ at var{a} outputs: first @var{v} video outputs, then
- at var{a} audio outputs.
-
-There are @var{n}x(@var{v}+ at var{a}) inputs: first the inputs for the first
-segment, in the same order as the outputs, then the inputs for the second
-segment, etc.
-
-Related streams do not always have exactly the same duration, for various
-reasons including codec frame size or sloppy authoring. For that reason,
-related synchronized streams (e.g. a video and its audio track) should be
-concatenated at once. The concat filter will use the duration of the longest
-stream in each segment (except the last one), and if necessary pad shorter
-audio streams with silence.
-
-For this filter to work correctly, all segments must start at timestamp 0.
-
-All corresponding streams must have the same parameters in all segments; the
-filtering system will automatically select a common pixel format for video
-streams, and a common sample format, sample rate and channel layout for
-audio streams, but other settings, such as resolution, must be converted
-explicitly by the user.
-
-Different frame rates are acceptable but will result in variable frame rate
-at output; be sure to configure the output file to handle it.
-
- at subsection Examples
-
- at itemize
- at item
-Concatenate an opening, an episode and an ending, all in bilingual version
-(video in stream 0, audio in streams 1 and 2):
- at example
-ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv -filter_complex \
- '[0:0] [0:1] [0:2] [1:0] [1:1] [1:2] [2:0] [2:1] [2:2]
- concat=n=3:v=1:a=2 [v] [a1] [a2]' \
- -map '[v]' -map '[a1]' -map '[a2]' output.mkv
- at end example
-
- at item
-Concatenate two parts, handling audio and video separately, using the
-(a)movie sources, and adjusting the resolution:
- at example
-movie=part1.mp4, scale=512:288 [v1] ; amovie=part1.mp4 [a1] ;
-movie=part2.mp4, scale=512:288 [v2] ; amovie=part2.mp4 [a2] ;
-[v1] [v2] concat [outv] ; [a1] [a2] concat=v=0:a=1 [outa]
- at end example
-Note that a desync will happen at the stitch if the audio and video streams
-do not have exactly the same duration in the first file.
-
- at end itemize
-
- at anchor{ebur128}
- at section ebur128
-
-EBU R128 scanner filter. This filter takes an audio stream as input and outputs
-it unchanged. By default, it logs a message at a frequency of 10Hz with the
-Momentary loudness (identified by @code{M}), Short-term loudness (@code{S}),
-Integrated loudness (@code{I}) and Loudness Range (@code{LRA}).
-
-The filter also has a video output (see the @var{video} option) with a real
-time graph to observe the loudness evolution. The graphic contains the logged
-message mentioned above, so it is not printed anymore when this option is set,
-unless the verbose logging is set. The main graphing area contains the
-short-term loudness (3 seconds of analysis), and the gauge on the right is for
-the momentary loudness (400 milliseconds).
-
-More information about the Loudness Recommendation EBU R128 on
- at url{http://tech.ebu.ch/loudness}.
-
-The filter accepts the following options:
-
- at table @option
-
- at item video
-Activate the video output. The audio stream is passed unchanged whether this
-option is set or no. The video stream will be the first output stream if
-activated. Default is @code{0}.
-
- at item size
-Set the video size. This option is for video only. For the syntax of this
-option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-Default and minimum resolution is @code{640x480}.
-
- at item meter
-Set the EBU scale meter. Default is @code{9}. Common values are @code{9} and
- at code{18}, respectively for EBU scale meter +9 and EBU scale meter +18. Any
-other integer value between this range is allowed.
-
- at item metadata
-Set metadata injection. If set to @code{1}, the audio input will be segmented
-into 100ms output frames, each of them containing various loudness information
-in metadata. All the metadata keys are prefixed with @code{lavfi.r128.}.
-
-Default is @code{0}.
-
- at item framelog
-Force the frame logging level.
-
-Available values are:
- at table @samp
- at item info
-information logging level
- at item verbose
-verbose logging level
- at end table
-
-By default, the logging level is set to @var{info}. If the @option{video} or
-the @option{metadata} options are set, it switches to @var{verbose}.
-
- at item peak
-Set peak mode(s).
-
-Available modes can be cumulated (the option is a @code{flag} type). Possible
-values are:
- at table @samp
- at item none
-Disable any peak mode (default).
- at item sample
-Enable sample-peak mode.
-
-Simple peak mode looking for the higher sample value. It logs a message
-for sample-peak (identified by @code{SPK}).
- at item true
-Enable true-peak mode.
-
-If enabled, the peak lookup is done on an over-sampled version of the input
-stream for better peak accuracy. It logs a message for true-peak.
-(identified by @code{TPK}) and true-peak per frame (identified by @code{FTPK}).
-This mode requires a build with @code{libswresample}.
- at end table
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Real-time graph using @command{ffplay}, with a EBU scale meter +18:
- at example
-ffplay -f lavfi -i "amovie=input.mp3,ebur128=video=1:meter=18 [out0][out1]"
- at end example
-
- at item
-Run an analysis with @command{ffmpeg}:
- at example
-ffmpeg -nostats -i input.mp3 -filter_complex ebur128 -f null -
- at end example
- at end itemize
-
- at section interleave, ainterleave
-
-Temporally interleave frames from several inputs.
-
- at code{interleave} works with video inputs, @code{ainterleave} with audio.
-
-These filters read frames from several inputs and send the oldest
-queued frame to the output.
-
-Input streams must have a well defined, monotonically increasing frame
-timestamp values.
-
-In order to submit one frame to output, these filters need to enqueue
-at least one frame for each input, so they cannot work in case one
-input is not yet terminated and will not receive incoming frames.
-
-For example consider the case when one input is a @code{select} filter
-which always drop input frames. The @code{interleave} filter will keep
-reading from that input, but it will never be able to send new frames
-to output until the input will send an end-of-stream signal.
-
-Also, depending on inputs synchronization, the filters will drop
-frames in case one input receives more frames than the other ones, and
-the queue is already filled.
-
-These filters accept the following options:
-
- at table @option
- at item nb_inputs, n
-Set the number of different inputs, it is 2 by default.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Interleave frames belonging to different streams using @command{ffmpeg}:
- at example
-ffmpeg -i bambi.avi -i pr0n.mkv -filter_complex "[0:v][1:v] interleave" out.avi
- at end example
-
- at item
-Add flickering blur effect:
- at example
-select='if(gt(random(0), 0.2), 1, 2)':n=2 [tmp], boxblur=2:2, [tmp] interleave
- at end example
- at end itemize
-
- at section perms, aperms
-
-Set read/write permissions for the output frames.
-
-These filters are mainly aimed at developers to test direct path in the
-following filter in the filtergraph.
-
-The filters accept the following options:
-
- at table @option
- at item mode
-Select the permissions mode.
-
-It accepts the following values:
- at table @samp
- at item none
-Do nothing. This is the default.
- at item ro
-Set all the output frames read-only.
- at item rw
-Set all the output frames directly writable.
- at item toggle
-Make the frame read-only if writable, and writable if read-only.
- at item random
-Set each output frame read-only or writable randomly.
- at end table
-
- at item seed
-Set the seed for the @var{random} mode, must be an integer included between
- at code{0} and @code{UINT32_MAX}. If not specified, or if explicitly set to
- at code{-1}, the filter will try to use a good random seed on a best effort
-basis.
- at end table
-
-Note: in case of auto-inserted filter between the permission filter and the
-following one, the permission might not be received as expected in that
-following filter. Inserting a @ref{format} or @ref{aformat} filter before the
-perms/aperms filter can avoid this problem.
-
- at section select, aselect
-
-Select frames to pass in output.
-
-This filter accepts the following options:
-
- at table @option
-
- at item expr, e
-Set expression, which is evaluated for each input frame.
-
-If the expression is evaluated to zero, the frame is discarded.
-
-If the evaluation result is negative or NaN, the frame is sent to the
-first output; otherwise it is sent to the output with index
- at code{ceil(val)-1}, assuming that the input index starts from 0.
-
-For example a value of @code{1.2} corresponds to the output with index
- at code{ceil(1.2)-1 = 2-1 = 1}, that is the second output.
-
- at item outputs, n
-Set the number of outputs. The output to which to send the selected
-frame is based on the result of the evaluation. Default value is 1.
- at end table
-
-The expression can contain the following constants:
-
- at table @option
- at item n
-The (sequential) number of the filtered frame, starting from 0.
-
- at item selected_n
-The (sequential) number of the selected frame, starting from 0.
-
- at item prev_selected_n
-The sequential number of the last selected frame. It's NAN if undefined.
-
- at item TB
-The timebase of the input timestamps.
-
- at item pts
-The PTS (Presentation TimeStamp) of the filtered video frame,
-expressed in @var{TB} units. It's NAN if undefined.
-
- at item t
-The PTS of the filtered video frame,
-expressed in seconds. It's NAN if undefined.
-
- at item prev_pts
-The PTS of the previously filtered video frame. It's NAN if undefined.
-
- at item prev_selected_pts
-The PTS of the last previously filtered video frame. It's NAN if undefined.
-
- at item prev_selected_t
-The PTS of the last previously selected video frame. It's NAN if undefined.
-
- at item start_pts
-The PTS of the first video frame in the video. It's NAN if undefined.
-
- at item start_t
-The time of the first video frame in the video. It's NAN if undefined.
-
- at item pict_type @emph{(video only)}
-The type of the filtered frame. It can assume one of the following
-values:
- at table @option
- at item I
- at item P
- at item B
- at item S
- at item SI
- at item SP
- at item BI
- at end table
-
- at item interlace_type @emph{(video only)}
-The frame interlace type. It can assume one of the following values:
- at table @option
- at item PROGRESSIVE
-The frame is progressive (not interlaced).
- at item TOPFIRST
-The frame is top-field-first.
- at item BOTTOMFIRST
-The frame is bottom-field-first.
- at end table
-
- at item consumed_sample_n @emph{(audio only)}
-the number of selected samples before the current frame
-
- at item samples_n @emph{(audio only)}
-the number of samples in the current frame
-
- at item sample_rate @emph{(audio only)}
-the input sample rate
-
- at item key
-This is 1 if the filtered frame is a key-frame, 0 otherwise.
-
- at item pos
-the position in the file of the filtered frame, -1 if the information
-is not available (e.g. for synthetic video)
-
- at item scene @emph{(video only)}
-value between 0 and 1 to indicate a new scene; a low value reflects a low
-probability for the current frame to introduce a new scene, while a higher
-value means the current frame is more likely to be one (see the example below)
-
- at end table
-
-The default value of the select expression is "1".
-
- at subsection Examples
-
- at itemize
- at item
-Select all frames in input:
- at example
-select
- at end example
-
-The example above is the same as:
- at example
-select=1
- at end example
-
- at item
-Skip all frames:
- at example
-select=0
- at end example
-
- at item
-Select only I-frames:
- at example
-select='eq(pict_type\,I)'
- at end example
-
- at item
-Select one frame every 100:
- at example
-select='not(mod(n\,100))'
- at end example
-
- at item
-Select only frames contained in the 10-20 time interval:
- at example
-select=between(t\,10\,20)
- at end example
-
- at item
-Select only I frames contained in the 10-20 time interval:
- at example
-select=between(t\,10\,20)*eq(pict_type\,I)
- at end example
-
- at item
-Select frames with a minimum distance of 10 seconds:
- at example
-select='isnan(prev_selected_t)+gte(t-prev_selected_t\,10)'
- at end example
-
- at item
-Use aselect to select only audio frames with samples number > 100:
- at example
-aselect='gt(samples_n\,100)'
- at end example
-
- at item
-Create a mosaic of the first scenes:
- at example
-ffmpeg -i video.avi -vf select='gt(scene\,0.4)',scale=160:120,tile -frames:v 1 preview.png
- at end example
-
-Comparing @var{scene} against a value between 0.3 and 0.5 is generally a sane
-choice.
-
- at item
-Send even and odd frames to separate outputs, and compose them:
- at example
-select=n=2:e='mod(n, 2)+1' [odd][even]; [odd] pad=h=2*ih [tmp]; [tmp][even] overlay=y=h
- at end example
- at end itemize
-
- at section sendcmd, asendcmd
-
-Send commands to filters in the filtergraph.
-
-These filters read commands to be sent to other filters in the
-filtergraph.
-
- at code{sendcmd} must be inserted between two video filters,
- at code{asendcmd} must be inserted between two audio filters, but apart
-from that they act the same way.
-
-The specification of commands can be provided in the filter arguments
-with the @var{commands} option, or in a file specified by the
- at var{filename} option.
-
-These filters accept the following options:
- at table @option
- at item commands, c
-Set the commands to be read and sent to the other filters.
- at item filename, f
-Set the filename of the commands to be read and sent to the other
-filters.
- at end table
-
- at subsection Commands syntax
-
-A commands description consists of a sequence of interval
-specifications, comprising a list of commands to be executed when a
-particular event related to that interval occurs. The occurring event
-is typically the current frame time entering or leaving a given time
-interval.
-
-An interval is specified by the following syntax:
- at example
- at var{START}[- at var{END}] @var{COMMANDS};
- at end example
-
-The time interval is specified by the @var{START} and @var{END} times.
- at var{END} is optional and defaults to the maximum time.
-
-The current frame time is considered within the specified interval if
-it is included in the interval [@var{START}, @var{END}), that is when
-the time is greater or equal to @var{START} and is lesser than
- at var{END}.
-
- at var{COMMANDS} consists of a sequence of one or more command
-specifications, separated by ",", relating to that interval. The
-syntax of a command specification is given by:
- at example
-[@var{FLAGS}] @var{TARGET} @var{COMMAND} @var{ARG}
- at end example
-
- at var{FLAGS} is optional and specifies the type of events relating to
-the time interval which enable sending the specified command, and must
-be a non-null sequence of identifier flags separated by "+" or "|" and
-enclosed between "[" and "]".
-
-The following flags are recognized:
- at table @option
- at item enter
-The command is sent when the current frame timestamp enters the
-specified interval. In other words, the command is sent when the
-previous frame timestamp was not in the given interval, and the
-current is.
-
- at item leave
-The command is sent when the current frame timestamp leaves the
-specified interval. In other words, the command is sent when the
-previous frame timestamp was in the given interval, and the
-current is not.
- at end table
-
-If @var{FLAGS} is not specified, a default value of @code{[enter]} is
-assumed.
-
- at var{TARGET} specifies the target of the command, usually the name of
-the filter class or a specific filter instance name.
-
- at var{COMMAND} specifies the name of the command for the target filter.
-
- at var{ARG} is optional and specifies the optional list of argument for
-the given @var{COMMAND}.
-
-Between one interval specification and another, whitespaces, or
-sequences of characters starting with @code{#} until the end of line,
-are ignored and can be used to annotate comments.
-
-A simplified BNF description of the commands specification syntax
-follows:
- at example
- at var{COMMAND_FLAG} ::= "enter" | "leave"
- at var{COMMAND_FLAGS} ::= @var{COMMAND_FLAG} [(+|"|")@var{COMMAND_FLAG}]
- at var{COMMAND} ::= ["[" @var{COMMAND_FLAGS} "]"] @var{TARGET} @var{COMMAND} [@var{ARG}]
- at var{COMMANDS} ::= @var{COMMAND} [, at var{COMMANDS}]
- at var{INTERVAL} ::= @var{START}[- at var{END}] @var{COMMANDS}
- at var{INTERVALS} ::= @var{INTERVAL}[;@var{INTERVALS}]
- at end example
-
- at subsection Examples
-
- at itemize
- at item
-Specify audio tempo change at second 4:
- at example
-asendcmd=c='4.0 atempo tempo 1.5',atempo
- at end example
-
- at item
-Specify a list of drawtext and hue commands in a file.
- at example
-# show text in the interval 5-10
-5.0-10.0 [enter] drawtext reinit 'fontfile=FreeSerif.ttf:text=hello world',
- [leave] drawtext reinit 'fontfile=FreeSerif.ttf:text=';
-
-# desaturate the image in the interval 15-20
-15.0-20.0 [enter] hue s 0,
- [enter] drawtext reinit 'fontfile=FreeSerif.ttf:text=nocolor',
- [leave] hue s 1,
- [leave] drawtext reinit 'fontfile=FreeSerif.ttf:text=color';
-
-# apply an exponential saturation fade-out effect, starting from time 25
-25 [enter] hue s exp(25-t)
- at end example
-
-A filtergraph allowing to read and process the above command list
-stored in a file @file{test.cmd}, can be specified with:
- at example
-sendcmd=f=test.cmd,drawtext=fontfile=FreeSerif.ttf:text='',hue
- at end example
- at end itemize
-
- at anchor{setpts}
- at section setpts, asetpts
-
-Change the PTS (presentation timestamp) of the input frames.
-
- at code{setpts} works on video frames, @code{asetpts} on audio frames.
-
-This filter accepts the following options:
-
- at table @option
-
- at item expr
-The expression which is evaluated for each frame to construct its timestamp.
-
- at end table
-
-The expression is evaluated through the eval API and can contain the following
-constants:
-
- at table @option
- at item FRAME_RATE
-frame rate, only defined for constant frame-rate video
-
- at item PTS
-The presentation timestamp in input
-
- at item N
-The count of the input frame for video or the number of consumed samples,
-not including the current frame for audio, starting from 0.
-
- at item NB_CONSUMED_SAMPLES
-The number of consumed samples, not including the current frame (only
-audio)
-
- at item NB_SAMPLES, S
-The number of samples in the current frame (only audio)
-
- at item SAMPLE_RATE, SR
-The audio sample rate.
-
- at item STARTPTS
-The PTS of the first frame.
-
- at item STARTT
-the time in seconds of the first frame
-
- at item INTERLACED
-State whether the current frame is interlaced.
-
- at item T
-the time in seconds of the current frame
-
- at item POS
-original position in the file of the frame, or undefined if undefined
-for the current frame
-
- at item PREV_INPTS
-The previous input PTS.
-
- at item PREV_INT
-previous input time in seconds
-
- at item PREV_OUTPTS
-The previous output PTS.
-
- at item PREV_OUTT
-previous output time in seconds
-
- at item RTCTIME
-The wallclock (RTC) time in microseconds. This is deprecated, use time(0)
-instead.
-
- at item RTCSTART
-The wallclock (RTC) time at the start of the movie in microseconds.
-
- at item TB
-The timebase of the input timestamps.
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Start counting PTS from zero
- at example
-setpts=PTS-STARTPTS
- at end example
-
- at item
-Apply fast motion effect:
- at example
-setpts=0.5*PTS
- at end example
-
- at item
-Apply slow motion effect:
- at example
-setpts=2.0*PTS
- at end example
-
- at item
-Set fixed rate of 25 frames per second:
- at example
-setpts=N/(25*TB)
- at end example
-
- at item
-Set fixed rate 25 fps with some jitter:
- at example
-setpts='1/(25*TB) * (N + 0.05 * sin(N*2*PI/25))'
- at end example
-
- at item
-Apply an offset of 10 seconds to the input PTS:
- at example
-setpts=PTS+10/TB
- at end example
-
- at item
-Generate timestamps from a "live source" and rebase onto the current timebase:
- at example
-setpts='(RTCTIME - RTCSTART) / (TB * 1000000)'
- at end example
-
- at item
-Generate timestamps by counting samples:
- at example
-asetpts=N/SR/TB
- at end example
-
- at end itemize
-
- at section settb, asettb
-
-Set the timebase to use for the output frames timestamps.
-It is mainly useful for testing timebase configuration.
-
-It accepts the following parameters:
-
- at table @option
-
- at item expr, tb
-The expression which is evaluated into the output timebase.
-
- at end table
-
-The value for @option{tb} is an arithmetic expression representing a
-rational. The expression can contain the constants "AVTB" (the default
-timebase), "intb" (the input timebase) and "sr" (the sample rate,
-audio only). Default value is "intb".
-
- at subsection Examples
-
- at itemize
- at item
-Set the timebase to 1/25:
- at example
-settb=expr=1/25
- at end example
-
- at item
-Set the timebase to 1/10:
- at example
-settb=expr=0.1
- at end example
-
- at item
-Set the timebase to 1001/1000:
- at example
-settb=1+0.001
- at end example
-
- at item
-Set the timebase to 2*intb:
- at example
-settb=2*intb
- at end example
-
- at item
-Set the default timebase value:
- at example
-settb=AVTB
- at end example
- at end itemize
-
- at section showcqt
-Convert input audio to a video output representing
-frequency spectrum logarithmically (using constant Q transform with
-Brown-Puckette algorithm), with musical tone scale, from E0 to D#10 (10 octaves).
-
-The filter accepts the following options:
-
- at table @option
- at item volume
-Specify transform volume (multiplier) expression. The expression can contain
-variables:
- at table @option
- at item frequency, freq, f
-the frequency where transform is evaluated
- at item timeclamp, tc
-value of timeclamp option
- at end table
-and functions:
- at table @option
- at item a_weighting(f)
-A-weighting of equal loudness
- at item b_weighting(f)
-B-weighting of equal loudness
- at item c_weighting(f)
-C-weighting of equal loudness
- at end table
-Default value is @code{16}.
-
- at item tlength
-Specify transform length expression. The expression can contain variables:
- at table @option
- at item frequency, freq, f
-the frequency where transform is evaluated
- at item timeclamp, tc
-value of timeclamp option
- at end table
-Default value is @code{384/f*tc/(384/f+tc)}.
-
- at item timeclamp
-Specify the transform timeclamp. At low frequency, there is trade-off between
-accuracy in time domain and frequency domain. If timeclamp is lower,
-event in time domain is represented more accurately (such as fast bass drum),
-otherwise event in frequency domain is represented more accurately
-(such as bass guitar). Acceptable value is [0.1, 1.0]. Default value is @code{0.17}.
-
- at item coeffclamp
-Specify the transform coeffclamp. If coeffclamp is lower, transform is
-more accurate, otherwise transform is faster. Acceptable value is [0.1, 10.0].
-Default value is @code{1.0}.
-
- at item gamma
-Specify gamma. Lower gamma makes the spectrum more contrast, higher gamma
-makes the spectrum having more range. Acceptable value is [1.0, 7.0].
-Default value is @code{3.0}.
-
- at item gamma2
-Specify gamma of bargraph. Acceptable value is [1.0, 7.0].
-Default value is @code{1.0}.
-
- at item fontfile
-Specify font file for use with freetype. If not specified, use embedded font.
-
- at item fontcolor
-Specify font color expression. This is arithmetic expression that should return
-integer value 0xRRGGBB. The expression can contain variables:
- at table @option
- at item frequency, freq, f
-the frequency where transform is evaluated
- at item timeclamp, tc
-value of timeclamp option
- at end table
-and functions:
- at table @option
- at item midi(f)
-midi number of frequency f, some midi numbers: E0(16), C1(24), C2(36), A4(69)
- at item r(x), g(x), b(x)
-red, green, and blue value of intensity x
- at end table
-Default value is @code{st(0, (midi(f)-59.5)/12);
-st(1, if(between(ld(0),0,1), 0.5-0.5*cos(2*PI*ld(0)), 0));
-r(1-ld(1)) + b(ld(1))}
-
- at item fullhd
-If set to 1 (the default), the video size is 1920x1080 (full HD),
-if set to 0, the video size is 960x540. Use this option to make CPU usage lower.
-
- at item fps
-Specify video fps. Default value is @code{25}.
-
- at item count
-Specify number of transform per frame, so there are fps*count transforms
-per second. Note that audio data rate must be divisible by fps*count.
-Default value is @code{6}.
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Playing audio while showing the spectrum:
- at example
-ffplay -f lavfi 'amovie=a.mp3, asplit [a][out1]; [a] showcqt [out0]'
- at end example
-
- at item
-Same as above, but with frame rate 30 fps:
- at example
-ffplay -f lavfi 'amovie=a.mp3, asplit [a][out1]; [a] showcqt=fps=30:count=5 [out0]'
- at end example
-
- at item
-Playing at 960x540 and lower CPU usage:
- at example
-ffplay -f lavfi 'amovie=a.mp3, asplit [a][out1]; [a] showcqt=fullhd=0:count=3 [out0]'
- at end example
-
- at item
-A1 and its harmonics: A1, A2, (near)E3, A3:
- at example
-ffplay -f lavfi 'aevalsrc=0.1*sin(2*PI*55*t)+0.1*sin(4*PI*55*t)+0.1*sin(6*PI*55*t)+0.1*sin(8*PI*55*t),
- asplit[a][out1]; [a] showcqt [out0]'
- at end example
-
- at item
-Same as above, but with more accuracy in frequency domain (and slower):
- at example
-ffplay -f lavfi 'aevalsrc=0.1*sin(2*PI*55*t)+0.1*sin(4*PI*55*t)+0.1*sin(6*PI*55*t)+0.1*sin(8*PI*55*t),
- asplit[a][out1]; [a] showcqt=timeclamp=0.5 [out0]'
- at end example
-
- at item
-B-weighting of equal loudness
- at example
-volume=16*b_weighting(f)
- at end example
-
- at item
-Lower Q factor
- at example
-tlength=100/f*tc/(100/f+tc)
- at end example
-
- at item
-Custom fontcolor, C-note is colored green, others are colored blue
- at example
-fontcolor='if(mod(floor(midi(f)+0.5),12), 0x0000FF, g(1))'
- at end example
-
- at item
-Custom gamma, now spectrum is linear to the amplitude.
- at example
-gamma=2:gamma2=2
- at end example
-
- at end itemize
-
- at section showfreqs
-
-Convert input audio to video output representing the audio power spectrum.
-Audio amplitude is on Y-axis while frequency is on X-axis.
-
-The filter accepts the following options:
-
- at table @option
- at item size, s
-Specify size of video. For the syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-Default is @code{1024x512}.
-
- at item mode
-Set display mode.
-This set how each frequency bin will be represented.
-
-It accepts the following values:
- at table @samp
- at item line
- at item bar
- at item dot
- at end table
-Default is @code{bar}.
-
- at item ascale
-Set amplitude scale.
-
-It accepts the following values:
- at table @samp
- at item lin
-Linear scale.
-
- at item sqrt
-Square root scale.
-
- at item cbrt
-Cubic root scale.
-
- at item log
-Logarithmic scale.
- at end table
-Default is @code{log}.
-
- at item fscale
-Set frequency scale.
-
-It accepts the following values:
- at table @samp
- at item lin
-Linear scale.
-
- at item log
-Logarithmic scale.
-
- at item rlog
-Reverse logarithmic scale.
- at end table
-Default is @code{lin}.
-
- at item win_size
-Set window size.
-
-It accepts the following values:
- at table @samp
- at item w16
- at item w32
- at item w64
- at item w128
- at item w256
- at item w512
- at item w1024
- at item w2048
- at item w4096
- at item w8192
- at item w16384
- at item w32768
- at item w65536
- at end table
-Default is @code{w2048}
-
- at item win_func
-Set windowing function.
-
-It accepts the following values:
- at table @samp
- at item rect
- at item bartlett
- at item hanning
- at item hamming
- at item blackman
- at item welch
- at item flattop
- at item bharris
- at item bnuttall
- at item bhann
- at item sine
- at item nuttall
- at end table
-Default is @code{hanning}.
-
- at item overlap
-Set window overlap. In range @code{[0, 1]}. Default is @code{1},
-which means optimal overlap for selected window function will be picked.
-
- at item averaging
-Set time averaging. Setting this to 0 will display current maximal peaks.
-Default is @code{1}, which means time averaging is disabled.
-
- at item color
-Specify list of colors separated by space or by '|' which will be used to
-draw channel frequencies. Unrecognized or missing colors will be replaced
-by white color.
- at end table
-
- at section showspectrum
-
-Convert input audio to a video output, representing the audio frequency
-spectrum.
-
-The filter accepts the following options:
-
- at table @option
- at item size, s
-Specify the video size for the output. For the syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-Default value is @code{640x512}.
-
- at item slide
-Specify how the spectrum should slide along the window.
-
-It accepts the following values:
- at table @samp
- at item replace
-the samples start again on the left when they reach the right
- at item scroll
-the samples scroll from right to left
- at item fullframe
-frames are only produced when the samples reach the right
- at end table
-
-Default value is @code{replace}.
-
- at item mode
-Specify display mode.
-
-It accepts the following values:
- at table @samp
- at item combined
-all channels are displayed in the same row
- at item separate
-all channels are displayed in separate rows
- at end table
-
-Default value is @samp{combined}.
-
- at item color
-Specify display color mode.
-
-It accepts the following values:
- at table @samp
- at item channel
-each channel is displayed in a separate color
- at item intensity
-each channel is is displayed using the same color scheme
- at end table
-
-Default value is @samp{channel}.
-
- at item scale
-Specify scale used for calculating intensity color values.
-
-It accepts the following values:
- at table @samp
- at item lin
-linear
- at item sqrt
-square root, default
- at item cbrt
-cubic root
- at item log
-logarithmic
- at end table
-
-Default value is @samp{sqrt}.
-
- at item saturation
-Set saturation modifier for displayed colors. Negative values provide
-alternative color scheme. @code{0} is no saturation at all.
-Saturation must be in [-10.0, 10.0] range.
-Default value is @code{1}.
-
- at item win_func
-Set window function.
-
-It accepts the following values:
- at table @samp
- at item none
-No samples pre-processing (do not expect this to be faster)
- at item hann
-Hann window
- at item hamming
-Hamming window
- at item blackman
-Blackman window
- at end table
-
-Default value is @code{hann}.
- at end table
-
-The usage is very similar to the showwaves filter; see the examples in that
-section.
-
- at subsection Examples
-
- at itemize
- at item
-Large window with logarithmic color scaling:
- at example
-showspectrum=s=1280x480:scale=log
- at end example
-
- at item
-Complete example for a colored and sliding spectrum per channel using @command{ffplay}:
- at example
-ffplay -f lavfi 'amovie=input.mp3, asplit [a][out1];
- [a] showspectrum=mode=separate:color=intensity:slide=1:scale=cbrt [out0]'
- at end example
- at end itemize
-
- at section showvolume
-
-Convert input audio volume to a video output.
-
-The filter accepts the following options:
-
- at table @option
- at item rate, r
-Set video rate.
-
- at item b
-Set border width, allowed range is [0, 5]. Default is 1.
-
- at item w
-Set channel width, allowed range is [40, 1080]. Default is 400.
-
- at item h
-Set channel height, allowed range is [1, 100]. Default is 20.
-
- at item f
-Set fade, allowed range is [1, 255]. Default is 20.
-
- at item c
-Set volume color expression.
-
-The expression can use the following variables:
-
- at table @option
- at item VOLUME
-Current max volume of channel in dB.
-
- at item CHANNEL
-Current channel number, starting from 0.
- at end table
-
- at item t
-If set, displays channel names. Default is enabled.
- at end table
-
- at section showwaves
-
-Convert input audio to a video output, representing the samples waves.
-
-The filter accepts the following options:
-
- at table @option
- at item size, s
-Specify the video size for the output. For the syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-Default value is @code{600x240}.
-
- at item mode
-Set display mode.
-
-Available values are:
- at table @samp
- at item point
-Draw a point for each sample.
-
- at item line
-Draw a vertical line for each sample.
-
- at item p2p
-Draw a point for each sample and a line between them.
-
- at item cline
-Draw a centered vertical line for each sample.
- at end table
-
-Default value is @code{point}.
-
- at item n
-Set the number of samples which are printed on the same column. A
-larger value will decrease the frame rate. Must be a positive
-integer. This option can be set only if the value for @var{rate}
-is not explicitly specified.
-
- at item rate, r
-Set the (approximate) output frame rate. This is done by setting the
-option @var{n}. Default value is "25".
-
- at item split_channels
-Set if channels should be drawn separately or overlap. Default value is 0.
-
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Output the input file audio and the corresponding video representation
-at the same time:
- at example
-amovie=a.mp3,asplit[out0],showwaves[out1]
- at end example
-
- at item
-Create a synthetic signal and show it with showwaves, forcing a
-frame rate of 30 frames per second:
- at example
-aevalsrc=sin(1*2*PI*t)*sin(880*2*PI*t):cos(2*PI*200*t),asplit[out0],showwaves=r=30[out1]
- at end example
- at end itemize
-
- at section showwavespic
-
-Convert input audio to a single video frame, representing the samples waves.
-
-The filter accepts the following options:
-
- at table @option
- at item size, s
-Specify the video size for the output. For the syntax of this option, check the
- at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
-Default value is @code{600x240}.
-
- at item split_channels
-Set if channels should be drawn separately or overlap. Default value is 0.
- at end table
-
- at subsection Examples
-
- at itemize
- at item
-Extract a channel split representation of the wave form of a whole audio track
-in a 1024x800 picture using @command{ffmpeg}:
- at example
-ffmpeg -i audio.flac -lavfi showwavespic=split_channels=1:s=1024x800 waveform.png
- at end example
- at end itemize
-
- at section split, asplit
-
-Split input into several identical outputs.
-
- at code{asplit} works with audio input, @code{split} with video.
-
-The filter accepts a single parameter which specifies the number of outputs. If
-unspecified, it defaults to 2.
-
- at subsection Examples
-
- at itemize
- at item
-Create two separate outputs from the same input:
- at example
-[in] split [out0][out1]
- at end example
-
- at item
-To create 3 or more outputs, you need to specify the number of
-outputs, like in:
- at example
-[in] asplit=3 [out0][out1][out2]
- at end example
-
- at item
-Create two separate outputs from the same input, one cropped and
-one padded:
- at example
-[in] split [splitout1][splitout2];
-[splitout1] crop=100:100:0:0 [cropout];
-[splitout2] pad=200:200:100:100 [padout];
- at end example
-
- at item
-Create 5 copies of the input audio with @command{ffmpeg}:
- at example
-ffmpeg -i INPUT -filter_complex asplit=5 OUTPUT
- at end example
- at end itemize
-
- at section zmq, azmq
-
-Receive commands sent through a libzmq client, and forward them to
-filters in the filtergraph.
-
- at code{zmq} and @code{azmq} work as a pass-through filters. @code{zmq}
-must be inserted between two video filters, @code{azmq} between two
-audio filters.
-
-To enable these filters you need to install the libzmq library and
-headers and configure FFmpeg with @code{--enable-libzmq}.
-
-For more information about libzmq see:
- at url{http://www.zeromq.org/}
-
-The @code{zmq} and @code{azmq} filters work as a libzmq server, which
-receives messages sent through a network interface defined by the
- at option{bind_address} option.
-
-The received message must be in the form:
- at example
- at var{TARGET} @var{COMMAND} [@var{ARG}]
- at end example
-
- at var{TARGET} specifies the target of the command, usually the name of
-the filter class or a specific filter instance name.
-
- at var{COMMAND} specifies the name of the command for the target filter.
-
- at var{ARG} is optional and specifies the optional argument list for the
-given @var{COMMAND}.
-
-Upon reception, the message is processed and the corresponding command
-is injected into the filtergraph. Depending on the result, the filter
-will send a reply to the client, adopting the format:
- at example
- at var{ERROR_CODE} @var{ERROR_REASON}
- at var{MESSAGE}
- at end example
-
- at var{MESSAGE} is optional.
-
- at subsection Examples
-
-Look at @file{tools/zmqsend} for an example of a zmq client which can
-be used to send commands processed by these filters.
-
-Consider the following filtergraph generated by @command{ffplay}
- at example
-ffplay -dumpgraph 1 -f lavfi "
-color=s=100x100:c=red [l];
-color=s=100x100:c=blue [r];
-nullsrc=s=200x100, zmq [bg];
-[bg][l] overlay [bg+l];
-[bg+l][r] overlay=x=100 "
- at end example
-
-To change the color of the left side of the video, the following
-command can be used:
- at example
-echo Parsed_color_0 c yellow | tools/zmqsend
- at end example
-
-To change the right side:
- at example
-echo Parsed_color_1 c pink | tools/zmqsend
- at end example
-
- at c man end MULTIMEDIA FILTERS
-
- at chapter Multimedia Sources
- at c man begin MULTIMEDIA SOURCES
-
-Below is a description of the currently available multimedia sources.
-
- at section amovie
-
-This is the same as @ref{movie} source, except it selects an audio
-stream by default.
-
- at anchor{movie}
- at section movie
-
-Read audio and/or video stream(s) from a movie container.
-
-It accepts the following parameters:
-
- at table @option
- at item filename
-The name of the resource to read (not necessarily a file; it can also be a
-device or a stream accessed through some protocol).
-
- at item format_name, f
-Specifies the format assumed for the movie to read, and can be either
-the name of a container or an input device. If not specified, the
-format is guessed from @var{movie_name} or by probing.
-
- at item seek_point, sp
-Specifies the seek point in seconds. The frames will be output
-starting from this seek point. The parameter is evaluated with
- at code{av_strtod}, so the numerical value may be suffixed by an IS
-postfix. The default value is "0".
-
- at item streams, s
-Specifies the streams to read. Several streams can be specified,
-separated by "+". The source will then have as many outputs, in the
-same order. The syntax is explained in the ``Stream specifiers''
-section in the ffmpeg manual. Two special names, "dv" and "da" specify
-respectively the default (best suited) video and audio stream. Default
-is "dv", or "da" if the filter is called as "amovie".
-
- at item stream_index, si
-Specifies the index of the video stream to read. If the value is -1,
-the most suitable video stream will be automatically selected. The default
-value is "-1". Deprecated. If the filter is called "amovie", it will select
-audio instead of video.
-
- at item loop
-Specifies how many times to read the stream in sequence.
-If the value is less than 1, the stream will be read again and again.
-Default value is "1".
-
-Note that when the movie is looped the source timestamps are not
-changed, so it will generate non monotonically increasing timestamps.
- at end table
-
-It allows overlaying a second video on top of the main input of
-a filtergraph, as shown in this graph:
- at example
-input -----------> deltapts0 --> overlay --> output
- ^
- |
-movie --> scale--> deltapts1 -------+
- at end example
- at subsection Examples
-
- at itemize
- at item
-Skip 3.2 seconds from the start of the AVI file in.avi, and overlay it
-on top of the input labelled "in":
- at example
-movie=in.avi:seek_point=3.2, scale=180:-1, setpts=PTS-STARTPTS [over];
-[in] setpts=PTS-STARTPTS [main];
-[main][over] overlay=16:16 [out]
- at end example
-
- at item
-Read from a video4linux2 device, and overlay it on top of the input
-labelled "in":
- at example
-movie=/dev/video0:f=video4linux2, scale=180:-1, setpts=PTS-STARTPTS [over];
-[in] setpts=PTS-STARTPTS [main];
-[main][over] overlay=16:16 [out]
- at end example
-
- at item
-Read the first video stream and the audio stream with id 0x81 from
-dvd.vob; the video is connected to the pad named "video" and the audio is
-connected to the pad named "audio":
- at example
-movie=dvd.vob:s=v:0+#0x81 [video] [audio]
- at end example
- at end itemize
-
- at c man end MULTIMEDIA SOURCES
diff --git a/ffmpeg-2-8-11/libavcodec/aac_defines.h b/ffmpeg-2-8-11/libavcodec/aac_defines.h
deleted file mode 100644
index 3c45742..0000000
--- a/ffmpeg-2-8-11/libavcodec/aac_defines.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * AAC defines
- *
- * 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_AAC_DEFINES_H
-#define AVCODEC_AAC_DEFINES_H
-
-#ifndef USE_FIXED
-#define USE_FIXED 0
-#endif
-
-#if USE_FIXED
-
-#include "libavutil/softfloat.h"
-
-#define FFT_FLOAT 0
-#define FFT_FIXED_32 1
-
-#define AAC_RENAME(x) x ## _fixed
-#define AAC_RENAME_32(x) x ## _fixed_32
-#define INTFLOAT int
-#define INT64FLOAT int64_t
-#define SHORTFLOAT int16_t
-#define AAC_FLOAT SoftFloat
-#define AAC_SIGNE int
-#define FIXR(a) ((int)((a) * 1 + 0.5))
-#define FIXR10(a) ((int)((a) * 1024.0 + 0.5))
-#define Q23(a) (int)((a) * 8388608.0 + 0.5)
-#define Q30(x) (int)((x)*1073741824.0 + 0.5)
-#define Q31(x) (int)((x)*2147483648.0 + 0.5)
-#define RANGE15(x) x
-#define GET_GAIN(x, y) (-(y) << (x)) + 1024
-#define AAC_MUL16(x, y) (int)(((int64_t)(x) * (y) + 0x8000) >> 16)
-#define AAC_MUL26(x, y) (int)(((int64_t)(x) * (y) + 0x2000000) >> 26)
-#define AAC_MUL30(x, y) (int)(((int64_t)(x) * (y) + 0x20000000) >> 30)
-#define AAC_MUL31(x, y) (int)(((int64_t)(x) * (y) + 0x40000000) >> 31)
-#define AAC_MADD28(x, y, a, b) (int)((((int64_t)(x) * (y)) + \
- ((int64_t)(a) * (b)) + \
- 0x8000000) >> 28)
-#define AAC_MADD30(x, y, a, b) (int)((((int64_t)(x) * (y)) + \
- ((int64_t)(a) * (b)) + \
- 0x20000000) >> 30)
-#define AAC_MADD30_V8(x, y, a, b, c, d, e, f) (int)((((int64_t)(x) * (y)) + \
- ((int64_t)(a) * (b)) + \
- ((int64_t)(c) * (d)) + \
- ((int64_t)(e) * (f)) + \
- 0x20000000) >> 30)
-#define AAC_MSUB30(x, y, a, b) (int)((((int64_t)(x) * (y)) - \
- ((int64_t)(a) * (b)) + \
- 0x20000000) >> 30)
-#define AAC_MSUB30_V8(x, y, a, b, c, d, e, f) (int)((((int64_t)(x) * (y)) + \
- ((int64_t)(a) * (b)) - \
- ((int64_t)(c) * (d)) - \
- ((int64_t)(e) * (f)) + \
- 0x20000000) >> 30)
-#define AAC_MSUB31_V3(x, y, z) (int)((((int64_t)(x) * (z)) - \
- ((int64_t)(y) * (z)) + \
- 0x40000000) >> 31)
-#define AAC_HALF_SUM(x, y) (x) >> 1 + (y) >> 1
-#define AAC_SRA_R(x, y) (int)(((x) + (1 << ((y) - 1))) >> (y))
-
-#else
-
-#define FFT_FLOAT 1
-#define FFT_FIXED_32 0
-
-#define AAC_RENAME(x) x
-#define AAC_RENAME_32(x) x
-#define INTFLOAT float
-#define INT64FLOAT float
-#define SHORTFLOAT float
-#define AAC_FLOAT float
-#define AAC_SIGNE unsigned
-#define FIXR(x) ((float)(x))
-#define FIXR10(x) ((float)(x))
-#define Q23(x) x
-#define Q30(x) x
-#define Q31(x) x
-#define RANGE15(x) (32768.0 * (x))
-#define GET_GAIN(x, y) powf((x), -(y))
-#define AAC_MUL16(x, y) ((x) * (y))
-#define AAC_MUL26(x, y) ((x) * (y))
-#define AAC_MUL30(x, y) ((x) * (y))
-#define AAC_MUL31(x, y) ((x) * (y))
-#define AAC_MADD28(x, y, a, b) ((x) * (y) + (a) * (b))
-#define AAC_MADD30(x, y, a, b) ((x) * (y) + (a) * (b))
-#define AAC_MADD30_V8(x, y, a, b, c, d, e, f) ((x) * (y) + (a) * (b) + \
- (c) * (d) + (e) * (f))
-#define AAC_MSUB30(x, y, a, b) ((x) * (y) - (a) * (b))
-#define AAC_MSUB30_V8(x, y, a, b, c, d, e, f) ((x) * (y) + (a) * (b) - \
- (c) * (d) - (e) * (f))
-#define AAC_MSUB31_V3(x, y, z) ((x) - (y)) * (z)
-#define AAC_HALF_SUM(x, y) ((x) + (y)) * 0.5f
-#define AAC_SRA_R(x, y) (x)
-
-#endif /* USE_FIXED */
-
-#endif /* AVCODEC_AAC_DEFINES_H */
diff --git a/ffmpeg-2-8-11/libavcodec/aacdec.c b/ffmpeg-2-8-11/libavcodec/aacdec.c
deleted file mode 100644
index 837102f..0000000
--- a/ffmpeg-2-8-11/libavcodec/aacdec.c
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * AAC decoder
- * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
- * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
- * Copyright (c) 2008-2013 Alex Converse <alex.converse at gmail.com>
- *
- * AAC LATM decoder
- * Copyright (c) 2008-2010 Paul Kendall <paul at kcbbs.gen.nz>
- * Copyright (c) 2010 Janne Grunau <janne-libav at jannau.net>
- *
- * 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
- * AAC decoder
- * @author Oded Shimon ( ods15 ods15 dyndns org )
- * @author Maxim Gavrilov ( maxim.gavrilov gmail com )
- */
-
-#define FFT_FLOAT 1
-#define FFT_FIXED_32 0
-#define USE_FIXED 0
-
-#include "libavutil/float_dsp.h"
-#include "libavutil/opt.h"
-#include "avcodec.h"
-#include "internal.h"
-#include "get_bits.h"
-#include "fft.h"
-#include "imdct15.h"
-#include "lpc.h"
-#include "kbdwin.h"
-#include "sinewin.h"
-
-#include "aac.h"
-#include "aactab.h"
-#include "aacdectab.h"
-#include "cbrt_tablegen.h"
-#include "sbr.h"
-#include "aacsbr.h"
-#include "mpeg4audio.h"
-#include "aacadtsdec.h"
-#include "libavutil/intfloat.h"
-
-#include <errno.h>
-#include <math.h>
-#include <stdint.h>
-#include <string.h>
-
-#if ARCH_ARM
-# include "arm/aac.h"
-#elif ARCH_MIPS
-# include "mips/aacdec_mips.h"
-#endif
-
-static av_always_inline void reset_predict_state(PredictorState *ps)
-{
- ps->r0 = 0.0f;
- ps->r1 = 0.0f;
- ps->cor0 = 0.0f;
- ps->cor1 = 0.0f;
- ps->var0 = 1.0f;
- ps->var1 = 1.0f;
-}
-
-#ifndef VMUL2
-static inline float *VMUL2(float *dst, const float *v, unsigned idx,
- const float *scale)
-{
- float s = *scale;
- *dst++ = v[idx & 15] * s;
- *dst++ = v[idx>>4 & 15] * s;
- return dst;
-}
-#endif
-
-#ifndef VMUL4
-static inline float *VMUL4(float *dst, const float *v, unsigned idx,
- const float *scale)
-{
- float s = *scale;
- *dst++ = v[idx & 3] * s;
- *dst++ = v[idx>>2 & 3] * s;
- *dst++ = v[idx>>4 & 3] * s;
- *dst++ = v[idx>>6 & 3] * s;
- return dst;
-}
-#endif
-
-#ifndef VMUL2S
-static inline float *VMUL2S(float *dst, const float *v, unsigned idx,
- unsigned sign, const float *scale)
-{
- union av_intfloat32 s0, s1;
-
- s0.f = s1.f = *scale;
- s0.i ^= sign >> 1 << 31;
- s1.i ^= sign << 31;
-
- *dst++ = v[idx & 15] * s0.f;
- *dst++ = v[idx>>4 & 15] * s1.f;
-
- return dst;
-}
-#endif
-
-#ifndef VMUL4S
-static inline float *VMUL4S(float *dst, const float *v, unsigned idx,
- unsigned sign, const float *scale)
-{
- unsigned nz = idx >> 12;
- union av_intfloat32 s = { .f = *scale };
- union av_intfloat32 t;
-
- t.i = s.i ^ (sign & 1U<<31);
- *dst++ = v[idx & 3] * t.f;
-
- sign <<= nz & 1; nz >>= 1;
- t.i = s.i ^ (sign & 1U<<31);
- *dst++ = v[idx>>2 & 3] * t.f;
-
- sign <<= nz & 1; nz >>= 1;
- t.i = s.i ^ (sign & 1U<<31);
- *dst++ = v[idx>>4 & 3] * t.f;
-
- sign <<= nz & 1;
- t.i = s.i ^ (sign & 1U<<31);
- *dst++ = v[idx>>6 & 3] * t.f;
-
- return dst;
-}
-#endif
-
-static av_always_inline float flt16_round(float pf)
-{
- union av_intfloat32 tmp;
- tmp.f = pf;
- tmp.i = (tmp.i + 0x00008000U) & 0xFFFF0000U;
- return tmp.f;
-}
-
-static av_always_inline float flt16_even(float pf)
-{
- union av_intfloat32 tmp;
- tmp.f = pf;
- tmp.i = (tmp.i + 0x00007FFFU + (tmp.i & 0x00010000U >> 16)) & 0xFFFF0000U;
- return tmp.f;
-}
-
-static av_always_inline float flt16_trunc(float pf)
-{
- union av_intfloat32 pun;
- pun.f = pf;
- pun.i &= 0xFFFF0000U;
- return pun.f;
-}
-
-static av_always_inline void predict(PredictorState *ps, float *coef,
- int output_enable)
-{
- const float a = 0.953125; // 61.0 / 64
- const float alpha = 0.90625; // 29.0 / 32
- float e0, e1;
- float pv;
- float k1, k2;
- float r0 = ps->r0, r1 = ps->r1;
- float cor0 = ps->cor0, cor1 = ps->cor1;
- float var0 = ps->var0, var1 = ps->var1;
-
- k1 = var0 > 1 ? cor0 * flt16_even(a / var0) : 0;
- k2 = var1 > 1 ? cor1 * flt16_even(a / var1) : 0;
-
- pv = flt16_round(k1 * r0 + k2 * r1);
- if (output_enable)
- *coef += pv;
-
- e0 = *coef;
- e1 = e0 - k1 * r0;
-
- ps->cor1 = flt16_trunc(alpha * cor1 + r1 * e1);
- ps->var1 = flt16_trunc(alpha * var1 + 0.5f * (r1 * r1 + e1 * e1));
- ps->cor0 = flt16_trunc(alpha * cor0 + r0 * e0);
- ps->var0 = flt16_trunc(alpha * var0 + 0.5f * (r0 * r0 + e0 * e0));
-
- ps->r1 = flt16_trunc(a * (r0 - k1 * e0));
- ps->r0 = flt16_trunc(a * e0);
-}
-
-/**
- * Apply dependent channel coupling (applied before IMDCT).
- *
- * @param index index into coupling gain array
- */
-static void apply_dependent_coupling(AACContext *ac,
- SingleChannelElement *target,
- ChannelElement *cce, int index)
-{
- IndividualChannelStream *ics = &cce->ch[0].ics;
- const uint16_t *offsets = ics->swb_offset;
- float *dest = target->coeffs;
- const float *src = cce->ch[0].coeffs;
- int g, i, group, k, idx = 0;
- if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Dependent coupling is not supported together with LTP\n");
- return;
- }
- for (g = 0; g < ics->num_window_groups; g++) {
- for (i = 0; i < ics->max_sfb; i++, idx++) {
- if (cce->ch[0].band_type[idx] != ZERO_BT) {
- const float gain = cce->coup.gain[index][idx];
- for (group = 0; group < ics->group_len[g]; group++) {
- for (k = offsets[i]; k < offsets[i + 1]; k++) {
- // FIXME: SIMDify
- dest[group * 128 + k] += gain * src[group * 128 + k];
- }
- }
- }
- }
- dest += ics->group_len[g] * 128;
- src += ics->group_len[g] * 128;
- }
-}
-
-/**
- * Apply independent channel coupling (applied after IMDCT).
- *
- * @param index index into coupling gain array
- */
-static void apply_independent_coupling(AACContext *ac,
- SingleChannelElement *target,
- ChannelElement *cce, int index)
-{
- int i;
- const float gain = cce->coup.gain[index][0];
- const float *src = cce->ch[0].ret;
- float *dest = target->ret;
- const int len = 1024 << (ac->oc[1].m4ac.sbr == 1);
-
- for (i = 0; i < len; i++)
- dest[i] += gain * src[i];
-}
-
-#include "aacdec_template.c"
-
-#define LOAS_SYNC_WORD 0x2b7 ///< 11 bits LOAS sync word
-
-struct LATMContext {
- AACContext aac_ctx; ///< containing AACContext
- int initialized; ///< initialized after a valid extradata was seen
-
- // parser data
- int audio_mux_version_A; ///< LATM syntax version
- int frame_length_type; ///< 0/1 variable/fixed frame length
- int frame_length; ///< frame length for fixed frame length
-};
-
-static inline uint32_t latm_get_value(GetBitContext *b)
-{
- int length = get_bits(b, 2);
-
- return get_bits_long(b, (length+1)*8);
-}
-
-static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
- GetBitContext *gb, int asclen)
-{
- AACContext *ac = &latmctx->aac_ctx;
- AVCodecContext *avctx = ac->avctx;
- MPEG4AudioConfig m4ac = { 0 };
- int config_start_bit = get_bits_count(gb);
- int sync_extension = 0;
- int bits_consumed, esize;
-
- if (asclen) {
- sync_extension = 1;
- asclen = FFMIN(asclen, get_bits_left(gb));
- } else
- asclen = get_bits_left(gb);
-
- if (config_start_bit % 8) {
- avpriv_request_sample(latmctx->aac_ctx.avctx,
- "Non-byte-aligned audio-specific config");
- return AVERROR_PATCHWELCOME;
- }
- if (asclen <= 0)
- return AVERROR_INVALIDDATA;
- bits_consumed = decode_audio_specific_config(NULL, avctx, &m4ac,
- gb->buffer + (config_start_bit / 8),
- asclen, sync_extension);
-
- if (bits_consumed < 0)
- return AVERROR_INVALIDDATA;
-
- if (!latmctx->initialized ||
- ac->oc[1].m4ac.sample_rate != m4ac.sample_rate ||
- ac->oc[1].m4ac.chan_config != m4ac.chan_config) {
-
- if(latmctx->initialized) {
- av_log(avctx, AV_LOG_INFO, "audio config changed\n");
- } else {
- av_log(avctx, AV_LOG_DEBUG, "initializing latmctx\n");
- }
- latmctx->initialized = 0;
-
- esize = (bits_consumed+7) / 8;
-
- if (avctx->extradata_size < esize) {
- av_free(avctx->extradata);
- avctx->extradata = av_malloc(esize + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!avctx->extradata)
- return AVERROR(ENOMEM);
- }
-
- avctx->extradata_size = esize;
- memcpy(avctx->extradata, gb->buffer + (config_start_bit/8), esize);
- memset(avctx->extradata+esize, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- }
- skip_bits_long(gb, bits_consumed);
-
- return bits_consumed;
-}
-
-static int read_stream_mux_config(struct LATMContext *latmctx,
- GetBitContext *gb)
-{
- int ret, audio_mux_version = get_bits(gb, 1);
-
- latmctx->audio_mux_version_A = 0;
- if (audio_mux_version)
- latmctx->audio_mux_version_A = get_bits(gb, 1);
-
- if (!latmctx->audio_mux_version_A) {
-
- if (audio_mux_version)
- latm_get_value(gb); // taraFullness
-
- skip_bits(gb, 1); // allStreamSameTimeFraming
- skip_bits(gb, 6); // numSubFrames
- // numPrograms
- if (get_bits(gb, 4)) { // numPrograms
- avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple programs");
- return AVERROR_PATCHWELCOME;
- }
-
- // for each program (which there is only one in DVB)
-
- // for each layer (which there is only one in DVB)
- if (get_bits(gb, 3)) { // numLayer
- avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple layers");
- return AVERROR_PATCHWELCOME;
- }
-
- // for all but first stream: use_same_config = get_bits(gb, 1);
- if (!audio_mux_version) {
- if ((ret = latm_decode_audio_specific_config(latmctx, gb, 0)) < 0)
- return ret;
- } else {
- int ascLen = latm_get_value(gb);
- if ((ret = latm_decode_audio_specific_config(latmctx, gb, ascLen)) < 0)
- return ret;
- ascLen -= ret;
- skip_bits_long(gb, ascLen);
- }
-
- latmctx->frame_length_type = get_bits(gb, 3);
- switch (latmctx->frame_length_type) {
- case 0:
- skip_bits(gb, 8); // latmBufferFullness
- break;
- case 1:
- latmctx->frame_length = get_bits(gb, 9);
- break;
- case 3:
- case 4:
- case 5:
- skip_bits(gb, 6); // CELP frame length table index
- break;
- case 6:
- case 7:
- skip_bits(gb, 1); // HVXC frame length table index
- break;
- }
-
- if (get_bits(gb, 1)) { // other data
- if (audio_mux_version) {
- latm_get_value(gb); // other_data_bits
- } else {
- int esc;
- do {
- esc = get_bits(gb, 1);
- skip_bits(gb, 8);
- } while (esc);
- }
- }
-
- if (get_bits(gb, 1)) // crc present
- skip_bits(gb, 8); // config_crc
- }
-
- return 0;
-}
-
-static int read_payload_length_info(struct LATMContext *ctx, GetBitContext *gb)
-{
- uint8_t tmp;
-
- if (ctx->frame_length_type == 0) {
- int mux_slot_length = 0;
- do {
- tmp = get_bits(gb, 8);
- mux_slot_length += tmp;
- } while (tmp == 255);
- return mux_slot_length;
- } else if (ctx->frame_length_type == 1) {
- return ctx->frame_length;
- } else if (ctx->frame_length_type == 3 ||
- ctx->frame_length_type == 5 ||
- ctx->frame_length_type == 7) {
- skip_bits(gb, 2); // mux_slot_length_coded
- }
- return 0;
-}
-
-static int read_audio_mux_element(struct LATMContext *latmctx,
- GetBitContext *gb)
-{
- int err;
- uint8_t use_same_mux = get_bits(gb, 1);
- if (!use_same_mux) {
- if ((err = read_stream_mux_config(latmctx, gb)) < 0)
- return err;
- } else if (!latmctx->aac_ctx.avctx->extradata) {
- av_log(latmctx->aac_ctx.avctx, AV_LOG_DEBUG,
- "no decoder config found\n");
- return AVERROR(EAGAIN);
- }
- if (latmctx->audio_mux_version_A == 0) {
- int mux_slot_length_bytes = read_payload_length_info(latmctx, gb);
- if (mux_slot_length_bytes * 8 > get_bits_left(gb)) {
- av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, "incomplete frame\n");
- return AVERROR_INVALIDDATA;
- } else if (mux_slot_length_bytes * 8 + 256 < get_bits_left(gb)) {
- av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR,
- "frame length mismatch %d << %d\n",
- mux_slot_length_bytes * 8, get_bits_left(gb));
- return AVERROR_INVALIDDATA;
- }
- }
- return 0;
-}
-
-
-static int latm_decode_frame(AVCodecContext *avctx, void *out,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- struct LATMContext *latmctx = avctx->priv_data;
- int muxlength, err;
- GetBitContext gb;
-
- if ((err = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
- return err;
-
- // check for LOAS sync word
- if (get_bits(&gb, 11) != LOAS_SYNC_WORD)
- return AVERROR_INVALIDDATA;
-
- muxlength = get_bits(&gb, 13) + 3;
- // not enough data, the parser should have sorted this out
- if (muxlength > avpkt->size)
- return AVERROR_INVALIDDATA;
-
- if ((err = read_audio_mux_element(latmctx, &gb)) < 0)
- return err;
-
- if (!latmctx->initialized) {
- if (!avctx->extradata) {
- *got_frame_ptr = 0;
- return avpkt->size;
- } else {
- push_output_configuration(&latmctx->aac_ctx);
- if ((err = decode_audio_specific_config(
- &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.oc[1].m4ac,
- avctx->extradata, avctx->extradata_size*8LL, 1)) < 0) {
- pop_output_configuration(&latmctx->aac_ctx);
- return err;
- }
- latmctx->initialized = 1;
- }
- }
-
- if (show_bits(&gb, 12) == 0xfff) {
- av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR,
- "ADTS header detected, probably as result of configuration "
- "misparsing\n");
- return AVERROR_INVALIDDATA;
- }
-
- switch (latmctx->aac_ctx.oc[1].m4ac.object_type) {
- case AOT_ER_AAC_LC:
- case AOT_ER_AAC_LTP:
- case AOT_ER_AAC_LD:
- case AOT_ER_AAC_ELD:
- err = aac_decode_er_frame(avctx, out, got_frame_ptr, &gb);
- break;
- default:
- err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb, avpkt);
- }
- if (err < 0)
- return err;
-
- return muxlength;
-}
-
-static av_cold int latm_decode_init(AVCodecContext *avctx)
-{
- struct LATMContext *latmctx = avctx->priv_data;
- int ret = aac_decode_init(avctx);
-
- if (avctx->extradata_size > 0)
- latmctx->initialized = !ret;
-
- return ret;
-}
-
-AVCodec ff_aac_decoder = {
- .name = "aac",
- .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_AAC,
- .priv_data_size = sizeof(AACContext),
- .init = aac_decode_init,
- .close = aac_decode_close,
- .decode = aac_decode_frame,
- .sample_fmts = (const enum AVSampleFormat[]) {
- AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
- },
- .capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
- .channel_layouts = aac_channel_layout,
- .flush = flush,
- .priv_class = &aac_decoder_class,
- .profiles = profiles,
-};
-
-/*
- Note: This decoder filter is intended to decode LATM streams transferred
- in MPEG transport streams which only contain one program.
- To do a more complex LATM demuxing a separate LATM demuxer should be used.
-*/
-AVCodec ff_aac_latm_decoder = {
- .name = "aac_latm",
- .long_name = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Coding LATM syntax)"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_AAC_LATM,
- .priv_data_size = sizeof(struct LATMContext),
- .init = latm_decode_init,
- .close = aac_decode_close,
- .decode = latm_decode_frame,
- .sample_fmts = (const enum AVSampleFormat[]) {
- AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
- },
- .capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
- .channel_layouts = aac_channel_layout,
- .flush = flush,
- .profiles = profiles,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/aacdec_fixed.c b/ffmpeg-2-8-11/libavcodec/aacdec_fixed.c
deleted file mode 100644
index 875ef58..0000000
--- a/ffmpeg-2-8-11/libavcodec/aacdec_fixed.c
+++ /dev/null
@@ -1,443 +0,0 @@
-/*
- * Copyright (c) 2013
- * MIPS Technologies, Inc., California.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * AAC decoder fixed-point implementation
- *
- * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
- * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * AAC decoder
- * @author Oded Shimon ( ods15 ods15 dyndns org )
- * @author Maxim Gavrilov ( maxim.gavrilov gmail com )
- *
- * Fixed point implementation
- * @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com )
- */
-
-#define FFT_FLOAT 0
-#define FFT_FIXED_32 1
-#define USE_FIXED 1
-
-#include "libavutil/fixed_dsp.h"
-#include "libavutil/opt.h"
-#include "avcodec.h"
-#include "internal.h"
-#include "get_bits.h"
-#include "fft.h"
-#include "lpc.h"
-#include "kbdwin.h"
-#include "sinewin.h"
-
-#include "aac.h"
-#include "aactab.h"
-#include "aacdectab.h"
-#include "cbrt_tablegen.h"
-#include "sbr.h"
-#include "aacsbr.h"
-#include "mpeg4audio.h"
-#include "aacadtsdec.h"
-#include "libavutil/intfloat.h"
-
-#include <math.h>
-#include <string.h>
-
-static av_always_inline void reset_predict_state(PredictorState *ps)
-{
- ps->r0.mant = 0;
- ps->r0.exp = 0;
- ps->r1.mant = 0;
- ps->r1.exp = 0;
- ps->cor0.mant = 0;
- ps->cor0.exp = 0;
- ps->cor1.mant = 0;
- ps->cor1.exp = 0;
- ps->var0.mant = 0x20000000;
- ps->var0.exp = 1;
- ps->var1.mant = 0x20000000;
- ps->var1.exp = 1;
-}
-
-static const int exp2tab[4] = { Q31(1.0000000000/2), Q31(1.1892071150/2), Q31(1.4142135624/2), Q31(1.6817928305/2) }; // 2^0, 2^0.25, 2^0.5, 2^0.75
-
-static inline int *DEC_SPAIR(int *dst, unsigned idx)
-{
- dst[0] = (idx & 15) - 4;
- dst[1] = (idx >> 4 & 15) - 4;
-
- return dst + 2;
-}
-
-static inline int *DEC_SQUAD(int *dst, unsigned idx)
-{
- dst[0] = (idx & 3) - 1;
- dst[1] = (idx >> 2 & 3) - 1;
- dst[2] = (idx >> 4 & 3) - 1;
- dst[3] = (idx >> 6 & 3) - 1;
-
- return dst + 4;
-}
-
-static inline int *DEC_UPAIR(int *dst, unsigned idx, unsigned sign)
-{
- dst[0] = (idx & 15) * (1 - (sign & 0xFFFFFFFE));
- dst[1] = (idx >> 4 & 15) * (1 - ((sign & 1) << 1));
-
- return dst + 2;
-}
-
-static inline int *DEC_UQUAD(int *dst, unsigned idx, unsigned sign)
-{
- unsigned nz = idx >> 12;
-
- dst[0] = (idx & 3) * (1 + (((int)sign >> 31) << 1));
- sign <<= nz & 1;
- nz >>= 1;
- dst[1] = (idx >> 2 & 3) * (1 + (((int)sign >> 31) << 1));
- sign <<= nz & 1;
- nz >>= 1;
- dst[2] = (idx >> 4 & 3) * (1 + (((int)sign >> 31) << 1));
- sign <<= nz & 1;
- nz >>= 1;
- dst[3] = (idx >> 6 & 3) * (1 + (((int)sign >> 31) << 1));
-
- return dst + 4;
-}
-
-static void vector_pow43(int *coefs, int len)
-{
- int i, coef;
-
- for (i=0; i<len; i++) {
- coef = coefs[i];
- if (coef < 0)
- coef = -(int)cbrt_tab[-coef];
- else
- coef = (int)cbrt_tab[coef];
- coefs[i] = coef;
- }
-}
-
-static void subband_scale(int *dst, int *src, int scale, int offset, int len)
-{
- int ssign = scale < 0 ? -1 : 1;
- int s = FFABS(scale);
- unsigned int round;
- int i, out, c = exp2tab[s & 3];
-
- s = offset - (s >> 2);
-
- if (s > 0) {
- round = 1 << (s-1);
- for (i=0; i<len; i++) {
- out = (int)(((int64_t)src[i] * c) >> 32);
- dst[i] = ((int)(out+round) >> s) * ssign;
- }
- }
- else {
- s = s + 32;
- round = 1 << (s-1);
- for (i=0; i<len; i++) {
- out = (int)((int64_t)((int64_t)src[i] * c + round) >> s);
- dst[i] = out * ssign;
- }
- }
-}
-
-static void noise_scale(int *coefs, int scale, int band_energy, int len)
-{
- int ssign = scale < 0 ? -1 : 1;
- int s = FFABS(scale);
- unsigned int round;
- int i, out, c = exp2tab[s & 3];
- int nlz = 0;
-
- while (band_energy > 0x7fff) {
- band_energy >>= 1;
- nlz++;
- }
- c /= band_energy;
- s = 21 + nlz - (s >> 2);
-
- if (s > 0) {
- round = 1 << (s-1);
- for (i=0; i<len; i++) {
- out = (int)(((int64_t)coefs[i] * c) >> 32);
- coefs[i] = ((int)(out+round) >> s) * ssign;
- }
- }
- else {
- s = s + 32;
- round = 1 << (s-1);
- for (i=0; i<len; i++) {
- out = (int)((int64_t)((int64_t)coefs[i] * c + round) >> s);
- coefs[i] = out * ssign;
- }
- }
-}
-
-static av_always_inline SoftFloat flt16_round(SoftFloat pf)
-{
- SoftFloat tmp;
- int s;
-
- tmp.exp = pf.exp;
- s = pf.mant >> 31;
- tmp.mant = (pf.mant ^ s) - s;
- tmp.mant = (tmp.mant + 0x00200000U) & 0xFFC00000U;
- tmp.mant = (tmp.mant ^ s) - s;
-
- return tmp;
-}
-
-static av_always_inline SoftFloat flt16_even(SoftFloat pf)
-{
- SoftFloat tmp;
- int s;
-
- tmp.exp = pf.exp;
- s = pf.mant >> 31;
- tmp.mant = (pf.mant ^ s) - s;
- tmp.mant = (tmp.mant + 0x001FFFFFU + (tmp.mant & 0x00400000U >> 16)) & 0xFFC00000U;
- tmp.mant = (tmp.mant ^ s) - s;
-
- return tmp;
-}
-
-static av_always_inline SoftFloat flt16_trunc(SoftFloat pf)
-{
- SoftFloat pun;
- int s;
-
- pun.exp = pf.exp;
- s = pf.mant >> 31;
- pun.mant = (pf.mant ^ s) - s;
- pun.mant = pun.mant & 0xFFC00000U;
- pun.mant = (pun.mant ^ s) - s;
-
- return pun;
-}
-
-static av_always_inline void predict(PredictorState *ps, int *coef,
- int output_enable)
-{
- const SoftFloat a = { 1023410176, 0 }; // 61.0 / 64
- const SoftFloat alpha = { 973078528, 0 }; // 29.0 / 32
- SoftFloat e0, e1;
- SoftFloat pv;
- SoftFloat k1, k2;
- SoftFloat r0 = ps->r0, r1 = ps->r1;
- SoftFloat cor0 = ps->cor0, cor1 = ps->cor1;
- SoftFloat var0 = ps->var0, var1 = ps->var1;
- SoftFloat tmp;
-
- if (var0.exp > 1 || (var0.exp == 1 && var0.mant > 0x20000000)) {
- k1 = av_mul_sf(cor0, flt16_even(av_div_sf(a, var0)));
- }
- else {
- k1.mant = 0;
- k1.exp = 0;
- }
-
- if (var1.exp > 1 || (var1.exp == 1 && var1.mant > 0x20000000)) {
- k2 = av_mul_sf(cor1, flt16_even(av_div_sf(a, var1)));
- }
- else {
- k2.mant = 0;
- k2.exp = 0;
- }
-
- tmp = av_mul_sf(k1, r0);
- pv = flt16_round(av_add_sf(tmp, av_mul_sf(k2, r1)));
- if (output_enable) {
- int shift = 28 - pv.exp;
-
- if (shift < 31)
- *coef += (pv.mant + (1 << (shift - 1))) >> shift;
- }
-
- e0 = av_int2sf(*coef, 2);
- e1 = av_sub_sf(e0, tmp);
-
- ps->cor1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor1), av_mul_sf(r1, e1)));
- tmp = av_add_sf(av_mul_sf(r1, r1), av_mul_sf(e1, e1));
- tmp.exp--;
- ps->var1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var1), tmp));
- ps->cor0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor0), av_mul_sf(r0, e0)));
- tmp = av_add_sf(av_mul_sf(r0, r0), av_mul_sf(e0, e0));
- tmp.exp--;
- ps->var0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var0), tmp));
-
- ps->r1 = flt16_trunc(av_mul_sf(a, av_sub_sf(r0, av_mul_sf(k1, e0))));
- ps->r0 = flt16_trunc(av_mul_sf(a, e0));
-}
-
-
-static const int cce_scale_fixed[8] = {
- Q30(1.0), //2^(0/8)
- Q30(1.0905077327), //2^(1/8)
- Q30(1.1892071150), //2^(2/8)
- Q30(1.2968395547), //2^(3/8)
- Q30(1.4142135624), //2^(4/8)
- Q30(1.5422108254), //2^(5/8)
- Q30(1.6817928305), //2^(6/8)
- Q30(1.8340080864), //2^(7/8)
-};
-
-/**
- * Apply dependent channel coupling (applied before IMDCT).
- *
- * @param index index into coupling gain array
- */
-static void apply_dependent_coupling_fixed(AACContext *ac,
- SingleChannelElement *target,
- ChannelElement *cce, int index)
-{
- IndividualChannelStream *ics = &cce->ch[0].ics;
- const uint16_t *offsets = ics->swb_offset;
- int *dest = target->coeffs;
- const int *src = cce->ch[0].coeffs;
- int g, i, group, k, idx = 0;
- if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Dependent coupling is not supported together with LTP\n");
- return;
- }
- for (g = 0; g < ics->num_window_groups; g++) {
- for (i = 0; i < ics->max_sfb; i++, idx++) {
- if (cce->ch[0].band_type[idx] != ZERO_BT) {
- const int gain = cce->coup.gain[index][idx];
- int shift, round, c, tmp;
-
- if (gain < 0) {
- c = -cce_scale_fixed[-gain & 7];
- shift = (-gain-1024) >> 3;
- }
- else {
- c = cce_scale_fixed[gain & 7];
- shift = (gain-1024) >> 3;
- }
-
- if (shift < 0) {
- shift = -shift;
- round = 1 << (shift - 1);
-
- for (group = 0; group < ics->group_len[g]; group++) {
- for (k = offsets[i]; k < offsets[i + 1]; k++) {
- tmp = (int)(((int64_t)src[group * 128 + k] * c + \
- (int64_t)0x1000000000) >> 37);
- dest[group * 128 + k] += (tmp + round) >> shift;
- }
- }
- }
- else {
- for (group = 0; group < ics->group_len[g]; group++) {
- for (k = offsets[i]; k < offsets[i + 1]; k++) {
- tmp = (int)(((int64_t)src[group * 128 + k] * c + \
- (int64_t)0x1000000000) >> 37);
- dest[group * 128 + k] += tmp << shift;
- }
- }
- }
- }
- }
- dest += ics->group_len[g] * 128;
- src += ics->group_len[g] * 128;
- }
-}
-
-/**
- * Apply independent channel coupling (applied after IMDCT).
- *
- * @param index index into coupling gain array
- */
-static void apply_independent_coupling_fixed(AACContext *ac,
- SingleChannelElement *target,
- ChannelElement *cce, int index)
-{
- int i, c, shift, round, tmp;
- const int gain = cce->coup.gain[index][0];
- const int *src = cce->ch[0].ret;
- int *dest = target->ret;
- const int len = 1024 << (ac->oc[1].m4ac.sbr == 1);
-
- c = cce_scale_fixed[gain & 7];
- shift = (gain-1024) >> 3;
- if (shift < 0) {
- shift = -shift;
- round = 1 << (shift - 1);
-
- for (i = 0; i < len; i++) {
- tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
- dest[i] += (tmp + round) >> shift;
- }
- }
- else {
- for (i = 0; i < len; i++) {
- tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
- dest[i] += tmp << shift;
- }
- }
-}
-
-#include "aacdec_template.c"
-
-AVCodec ff_aac_fixed_decoder = {
- .name = "aac_fixed",
- .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_AAC,
- .priv_data_size = sizeof(AACContext),
- .init = aac_decode_init,
- .close = aac_decode_close,
- .decode = aac_decode_frame,
- .sample_fmts = (const enum AVSampleFormat[]) {
- AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_NONE
- },
- .capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
- .channel_layouts = aac_channel_layout,
- .flush = flush,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/aacdec_template.c b/ffmpeg-2-8-11/libavcodec/aacdec_template.c
deleted file mode 100644
index ec8264e..0000000
--- a/ffmpeg-2-8-11/libavcodec/aacdec_template.c
+++ /dev/null
@@ -1,3238 +0,0 @@
-/*
- * AAC decoder
- * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
- * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
- * Copyright (c) 2008-2013 Alex Converse <alex.converse at gmail.com>
- *
- * AAC LATM decoder
- * Copyright (c) 2008-2010 Paul Kendall <paul at kcbbs.gen.nz>
- * Copyright (c) 2010 Janne Grunau <janne-libav at jannau.net>
- *
- * AAC decoder fixed-point implementation
- * Copyright (c) 2013
- * MIPS Technologies, Inc., California.
- *
- * 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
- * AAC decoder
- * @author Oded Shimon ( ods15 ods15 dyndns org )
- * @author Maxim Gavrilov ( maxim.gavrilov gmail com )
- *
- * AAC decoder fixed-point implementation
- * @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com )
- * @author Nedeljko Babic ( nedeljko.babic imgtec com )
- */
-
-/*
- * supported tools
- *
- * Support? Name
- * N (code in SoC repo) gain control
- * Y block switching
- * Y window shapes - standard
- * N window shapes - Low Delay
- * Y filterbank - standard
- * N (code in SoC repo) filterbank - Scalable Sample Rate
- * Y Temporal Noise Shaping
- * Y Long Term Prediction
- * Y intensity stereo
- * Y channel coupling
- * Y frequency domain prediction
- * Y Perceptual Noise Substitution
- * Y Mid/Side stereo
- * N Scalable Inverse AAC Quantization
- * N Frequency Selective Switch
- * N upsampling filter
- * Y quantization & coding - AAC
- * N quantization & coding - TwinVQ
- * N quantization & coding - BSAC
- * N AAC Error Resilience tools
- * N Error Resilience payload syntax
- * N Error Protection tool
- * N CELP
- * N Silence Compression
- * N HVXC
- * N HVXC 4kbits/s VR
- * N Structured Audio tools
- * N Structured Audio Sample Bank Format
- * N MIDI
- * N Harmonic and Individual Lines plus Noise
- * N Text-To-Speech Interface
- * Y Spectral Band Replication
- * Y (not in this code) Layer-1
- * Y (not in this code) Layer-2
- * Y (not in this code) Layer-3
- * N SinuSoidal Coding (Transient, Sinusoid, Noise)
- * Y Parametric Stereo
- * N Direct Stream Transfer
- * Y (not in fixed point code) Enhanced AAC Low Delay (ER AAC ELD)
- *
- * Note: - HE AAC v1 comprises LC AAC with Spectral Band Replication.
- * - HE AAC v2 comprises LC AAC with Spectral Band Replication and
- Parametric Stereo.
- */
-
-static VLC vlc_scalefactors;
-static VLC vlc_spectral[11];
-
-static int output_configure(AACContext *ac,
- uint8_t layout_map[MAX_ELEM_ID*4][3], int tags,
- enum OCStatus oc_type, int get_new_frame);
-
-#define overread_err "Input buffer exhausted before END element found\n"
-
-static int count_channels(uint8_t (*layout)[3], int tags)
-{
- int i, sum = 0;
- for (i = 0; i < tags; i++) {
- int syn_ele = layout[i][0];
- int pos = layout[i][2];
- sum += (1 + (syn_ele == TYPE_CPE)) *
- (pos != AAC_CHANNEL_OFF && pos != AAC_CHANNEL_CC);
- }
- return sum;
-}
-
-/**
- * Check for the channel element in the current channel position configuration.
- * If it exists, make sure the appropriate element is allocated and map the
- * channel order to match the internal FFmpeg channel layout.
- *
- * @param che_pos current channel position configuration
- * @param type channel element type
- * @param id channel element id
- * @param channels count of the number of channels in the configuration
- *
- * @return Returns error status. 0 - OK, !0 - error
- */
-static av_cold int che_configure(AACContext *ac,
- enum ChannelPosition che_pos,
- int type, int id, int *channels)
-{
- if (*channels >= MAX_CHANNELS)
- return AVERROR_INVALIDDATA;
- if (che_pos) {
- if (!ac->che[type][id]) {
- if (!(ac->che[type][id] = av_mallocz(sizeof(ChannelElement))))
- return AVERROR(ENOMEM);
- AAC_RENAME(ff_aac_sbr_ctx_init)(ac, &ac->che[type][id]->sbr);
- }
- if (type != TYPE_CCE) {
- if (*channels >= MAX_CHANNELS - (type == TYPE_CPE || (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1))) {
- av_log(ac->avctx, AV_LOG_ERROR, "Too many channels\n");
- return AVERROR_INVALIDDATA;
- }
- ac->output_element[(*channels)++] = &ac->che[type][id]->ch[0];
- if (type == TYPE_CPE ||
- (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1)) {
- ac->output_element[(*channels)++] = &ac->che[type][id]->ch[1];
- }
- }
- } else {
- if (ac->che[type][id])
- AAC_RENAME(ff_aac_sbr_ctx_close)(&ac->che[type][id]->sbr);
- av_freep(&ac->che[type][id]);
- }
- return 0;
-}
-
-static int frame_configure_elements(AVCodecContext *avctx)
-{
- AACContext *ac = avctx->priv_data;
- int type, id, ch, ret;
-
- /* set channel pointers to internal buffers by default */
- for (type = 0; type < 4; type++) {
- for (id = 0; id < MAX_ELEM_ID; id++) {
- ChannelElement *che = ac->che[type][id];
- if (che) {
- che->ch[0].ret = che->ch[0].ret_buf;
- che->ch[1].ret = che->ch[1].ret_buf;
- }
- }
- }
-
- /* get output buffer */
- av_frame_unref(ac->frame);
- if (!avctx->channels)
- return 1;
-
- ac->frame->nb_samples = 2048;
- if ((ret = ff_get_buffer(avctx, ac->frame, 0)) < 0)
- return ret;
-
- /* map output channel pointers to AVFrame data */
- for (ch = 0; ch < avctx->channels; ch++) {
- if (ac->output_element[ch])
- ac->output_element[ch]->ret = (INTFLOAT *)ac->frame->extended_data[ch];
- }
-
- return 0;
-}
-
-struct elem_to_channel {
- uint64_t av_position;
- uint8_t syn_ele;
- uint8_t elem_id;
- uint8_t aac_position;
-};
-
-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)
-{
- if (layout_map[offset][0] == TYPE_CPE) {
- e2c_vec[offset] = (struct elem_to_channel) {
- .av_position = left | right,
- .syn_ele = TYPE_CPE,
- .elem_id = layout_map[offset][1],
- .aac_position = pos
- };
- return 1;
- } else {
- e2c_vec[offset] = (struct elem_to_channel) {
- .av_position = left,
- .syn_ele = TYPE_SCE,
- .elem_id = layout_map[offset][1],
- .aac_position = pos
- };
- e2c_vec[offset + 1] = (struct elem_to_channel) {
- .av_position = right,
- .syn_ele = TYPE_SCE,
- .elem_id = layout_map[offset + 1][1],
- .aac_position = pos
- };
- return 2;
- }
-}
-
-static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos,
- int *current)
-{
- int num_pos_channels = 0;
- int first_cpe = 0;
- int sce_parity = 0;
- int i;
- for (i = *current; i < tags; i++) {
- if (layout_map[i][2] != pos)
- break;
- if (layout_map[i][0] == TYPE_CPE) {
- if (sce_parity) {
- if (pos == AAC_CHANNEL_FRONT && !first_cpe) {
- sce_parity = 0;
- } else {
- return -1;
- }
- }
- num_pos_channels += 2;
- first_cpe = 1;
- } else {
- num_pos_channels++;
- sce_parity ^= 1;
- }
- }
- if (sce_parity &&
- ((pos == AAC_CHANNEL_FRONT && first_cpe) || pos == AAC_CHANNEL_SIDE))
- return -1;
- *current = i;
- return num_pos_channels;
-}
-
-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;
-
- if (FF_ARRAY_ELEMS(e2c_vec) < tags)
- return 0;
-
- i = 0;
- num_front_channels =
- count_paired_channels(layout_map, tags, AAC_CHANNEL_FRONT, &i);
- if (num_front_channels < 0)
- return 0;
- num_side_channels =
- count_paired_channels(layout_map, tags, AAC_CHANNEL_SIDE, &i);
- if (num_side_channels < 0)
- return 0;
- num_back_channels =
- count_paired_channels(layout_map, tags, AAC_CHANNEL_BACK, &i);
- if (num_back_channels < 0)
- return 0;
-
- if (num_side_channels == 0 && num_back_channels >= 4) {
- num_side_channels = 2;
- num_back_channels -= 2;
- }
-
- i = 0;
- if (num_front_channels & 1) {
- e2c_vec[i] = (struct elem_to_channel) {
- .av_position = AV_CH_FRONT_CENTER,
- .syn_ele = TYPE_SCE,
- .elem_id = layout_map[i][1],
- .aac_position = AAC_CHANNEL_FRONT
- };
- i++;
- num_front_channels--;
- }
- if (num_front_channels >= 4) {
- i += assign_pair(e2c_vec, layout_map, i,
- AV_CH_FRONT_LEFT_OF_CENTER,
- AV_CH_FRONT_RIGHT_OF_CENTER,
- AAC_CHANNEL_FRONT);
- 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);
- num_front_channels -= 2;
- }
- while (num_front_channels >= 2) {
- i += assign_pair(e2c_vec, layout_map, i,
- UINT64_MAX,
- UINT64_MAX,
- AAC_CHANNEL_FRONT);
- num_front_channels -= 2;
- }
-
- if (num_side_channels >= 2) {
- i += assign_pair(e2c_vec, layout_map, i,
- AV_CH_SIDE_LEFT,
- AV_CH_SIDE_RIGHT,
- AAC_CHANNEL_FRONT);
- num_side_channels -= 2;
- }
- while (num_side_channels >= 2) {
- i += assign_pair(e2c_vec, layout_map, i,
- UINT64_MAX,
- UINT64_MAX,
- AAC_CHANNEL_SIDE);
- num_side_channels -= 2;
- }
-
- while (num_back_channels >= 4) {
- i += assign_pair(e2c_vec, layout_map, i,
- UINT64_MAX,
- UINT64_MAX,
- AAC_CHANNEL_BACK);
- 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);
- num_back_channels -= 2;
- }
- if (num_back_channels) {
- e2c_vec[i] = (struct elem_to_channel) {
- .av_position = AV_CH_BACK_CENTER,
- .syn_ele = TYPE_SCE,
- .elem_id = layout_map[i][1],
- .aac_position = AAC_CHANNEL_BACK
- };
- i++;
- num_back_channels--;
- }
-
- if (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) {
- e2c_vec[i] = (struct elem_to_channel) {
- .av_position = AV_CH_LOW_FREQUENCY,
- .syn_ele = TYPE_LFE,
- .elem_id = layout_map[i][1],
- .aac_position = AAC_CHANNEL_LFE
- };
- i++;
- }
- while (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) {
- e2c_vec[i] = (struct elem_to_channel) {
- .av_position = UINT64_MAX,
- .syn_ele = TYPE_LFE,
- .elem_id = layout_map[i][1],
- .aac_position = AAC_CHANNEL_LFE
- };
- i++;
- }
-
- // Must choose a stable sort
- 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);
-
- 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;
-}
-
-/**
- * Save current output configuration if and only if it has been locked.
- */
-static void push_output_configuration(AACContext *ac) {
- if (ac->oc[1].status == OC_LOCKED || ac->oc[0].status == OC_NONE) {
- ac->oc[0] = ac->oc[1];
- }
- ac->oc[1].status = OC_NONE;
-}
-
-/**
- * Restore the previous output configuration if and only if the current
- * configuration is unlocked.
- */
-static void pop_output_configuration(AACContext *ac) {
- if (ac->oc[1].status != OC_LOCKED && ac->oc[0].status != OC_NONE) {
- ac->oc[1] = ac->oc[0];
- ac->avctx->channels = ac->oc[1].channels;
- ac->avctx->channel_layout = ac->oc[1].channel_layout;
- output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags,
- ac->oc[1].status, 0);
- }
-}
-
-/**
- * Configure output channel order based on the current program
- * configuration element.
- *
- * @return Returns error status. 0 - OK, !0 - error
- */
-static int output_configure(AACContext *ac,
- uint8_t layout_map[MAX_ELEM_ID * 4][3], int tags,
- enum OCStatus oc_type, int get_new_frame)
-{
- AVCodecContext *avctx = ac->avctx;
- int i, channels = 0, ret;
- uint64_t layout = 0;
- uint8_t id_map[TYPE_END][MAX_ELEM_ID] = {{ 0 }};
- uint8_t type_counts[TYPE_END] = { 0 };
-
- if (ac->oc[1].layout_map != layout_map) {
- memcpy(ac->oc[1].layout_map, layout_map, tags * sizeof(layout_map[0]));
- ac->oc[1].layout_map_tags = tags;
- }
- for (i = 0; i < tags; i++) {
- int type = layout_map[i][0];
- int id = layout_map[i][1];
- id_map[type][id] = type_counts[type]++;
- if (id_map[type][id] >= MAX_ELEM_ID) {
- avpriv_request_sample(ac->avctx, "Remapped id too large\n");
- return AVERROR_PATCHWELCOME;
- }
- }
- // Try to sniff a reasonable channel order, otherwise output the
- // channels in the order the PCE declared them.
- if (avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE)
- layout = sniff_channel_order(layout_map, tags);
- for (i = 0; i < tags; i++) {
- int type = layout_map[i][0];
- int id = layout_map[i][1];
- int iid = id_map[type][id];
- int position = layout_map[i][2];
- // Allocate or free elements depending on if they are in the
- // current program configuration.
- ret = che_configure(ac, position, type, iid, &channels);
- if (ret < 0)
- return ret;
- ac->tag_che_map[type][id] = ac->che[type][iid];
- }
- if (ac->oc[1].m4ac.ps == 1 && channels == 2) {
- if (layout == AV_CH_FRONT_CENTER) {
- layout = AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT;
- } else {
- layout = 0;
- }
- }
-
- if (layout) avctx->channel_layout = layout;
- ac->oc[1].channel_layout = layout;
- avctx->channels = ac->oc[1].channels = channels;
- ac->oc[1].status = oc_type;
-
- if (get_new_frame) {
- if ((ret = frame_configure_elements(ac->avctx)) < 0)
- return ret;
- }
-
- return 0;
-}
-
-static void flush(AVCodecContext *avctx)
-{
- AACContext *ac= avctx->priv_data;
- int type, i, j;
-
- for (type = 3; type >= 0; type--) {
- for (i = 0; i < MAX_ELEM_ID; i++) {
- ChannelElement *che = ac->che[type][i];
- if (che) {
- for (j = 0; j <= 1; j++) {
- memset(che->ch[j].saved, 0, sizeof(che->ch[j].saved));
- }
- }
- }
- }
-}
-
-/**
- * Set up channel positions based on a default channel configuration
- * as specified in table 1.17.
- *
- * @return Returns error status. 0 - OK, !0 - error
- */
-static int set_default_channel_config(AVCodecContext *avctx,
- uint8_t (*layout_map)[3],
- int *tags,
- int channel_config)
-{
- if (channel_config < 1 || (channel_config > 7 && channel_config < 11) ||
- channel_config > 12) {
- av_log(avctx, AV_LOG_ERROR,
- "invalid default channel configuration (%d)\n",
- channel_config);
- return AVERROR_INVALIDDATA;
- }
- *tags = tags_per_config[channel_config];
- memcpy(layout_map, aac_channel_layout_map[channel_config - 1],
- *tags * sizeof(*layout_map));
-
- /*
- * AAC specification has 7.1(wide) as a default layout for 8-channel streams.
- * However, at least Nero AAC encoder encodes 7.1 streams using the default
- * channel config 7, mapping the side channels of the original audio stream
- * to the second AAC_CHANNEL_FRONT pair in the AAC stream. Similarly, e.g. FAAD
- * decodes the second AAC_CHANNEL_FRONT pair as side channels, therefore decoding
- * the incorrect streams as if they were correct (and as the encoder intended).
- *
- * As actual intended 7.1(wide) streams are very rare, default to assuming a
- * 7.1 layout was intended.
- */
- if (channel_config == 7 && avctx->strict_std_compliance < FF_COMPLIANCE_STRICT) {
- av_log(avctx, AV_LOG_INFO, "Assuming an incorrectly encoded 7.1 channel layout"
- " instead of a spec-compliant 7.1(wide) layout, use -strict %d to decode"
- " according to the specification instead.\n", FF_COMPLIANCE_STRICT);
- layout_map[2][2] = AAC_CHANNEL_SIDE;
- }
-
- return 0;
-}
-
-static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
-{
- /* For PCE based channel configurations map the channels solely based
- * on tags. */
- if (!ac->oc[1].m4ac.chan_config) {
- return ac->tag_che_map[type][elem_id];
- }
- // Allow single CPE stereo files to be signalled with mono configuration.
- if (!ac->tags_mapped && type == TYPE_CPE &&
- ac->oc[1].m4ac.chan_config == 1) {
- uint8_t layout_map[MAX_ELEM_ID*4][3];
- int layout_map_tags;
- push_output_configuration(ac);
-
- av_log(ac->avctx, AV_LOG_DEBUG, "mono with CPE\n");
-
- if (set_default_channel_config(ac->avctx, layout_map,
- &layout_map_tags, 2) < 0)
- return NULL;
- if (output_configure(ac, layout_map, layout_map_tags,
- OC_TRIAL_FRAME, 1) < 0)
- return NULL;
-
- ac->oc[1].m4ac.chan_config = 2;
- ac->oc[1].m4ac.ps = 0;
- }
- // And vice-versa
- if (!ac->tags_mapped && type == TYPE_SCE &&
- ac->oc[1].m4ac.chan_config == 2) {
- uint8_t layout_map[MAX_ELEM_ID * 4][3];
- int layout_map_tags;
- push_output_configuration(ac);
-
- av_log(ac->avctx, AV_LOG_DEBUG, "stereo with SCE\n");
-
- if (set_default_channel_config(ac->avctx, layout_map,
- &layout_map_tags, 1) < 0)
- return NULL;
- if (output_configure(ac, layout_map, layout_map_tags,
- OC_TRIAL_FRAME, 1) < 0)
- return NULL;
-
- ac->oc[1].m4ac.chan_config = 1;
- if (ac->oc[1].m4ac.sbr)
- ac->oc[1].m4ac.ps = -1;
- }
- /* For indexed channel configurations map the channels solely based
- * on position. */
- switch (ac->oc[1].m4ac.chan_config) {
- case 12:
- case 7:
- if (ac->tags_mapped == 3 && type == TYPE_CPE) {
- ac->tags_mapped++;
- return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][2];
- }
- case 11:
- if (ac->tags_mapped == 2 &&
- ac->oc[1].m4ac.chan_config == 11 &&
- type == TYPE_SCE) {
- ac->tags_mapped++;
- return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1];
- }
- case 6:
- /* Some streams incorrectly code 5.1 audio as
- * SCE[0] CPE[0] CPE[1] SCE[1]
- * instead of
- * SCE[0] CPE[0] CPE[1] LFE[0].
- * If we seem to have encountered such a stream, transfer
- * the LFE[0] element to the SCE[1]'s mapping */
- if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) {
- if (!ac->warned_remapping_once && (type != TYPE_LFE || elem_id != 0)) {
- av_log(ac->avctx, AV_LOG_WARNING,
- "This stream seems to incorrectly report its last channel as %s[%d], mapping to LFE[0]\n",
- type == TYPE_SCE ? "SCE" : "LFE", elem_id);
- ac->warned_remapping_once++;
- }
- ac->tags_mapped++;
- return ac->tag_che_map[type][elem_id] = ac->che[TYPE_LFE][0];
- }
- case 5:
- if (ac->tags_mapped == 2 && type == TYPE_CPE) {
- ac->tags_mapped++;
- return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][1];
- }
- case 4:
- /* Some streams incorrectly code 4.0 audio as
- * SCE[0] CPE[0] LFE[0]
- * instead of
- * SCE[0] CPE[0] SCE[1].
- * If we seem to have encountered such a stream, transfer
- * the SCE[1] element to the LFE[0]'s mapping */
- if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) {
- if (!ac->warned_remapping_once && (type != TYPE_SCE || elem_id != 1)) {
- av_log(ac->avctx, AV_LOG_WARNING,
- "This stream seems to incorrectly report its last channel as %s[%d], mapping to SCE[1]\n",
- type == TYPE_SCE ? "SCE" : "LFE", elem_id);
- ac->warned_remapping_once++;
- }
- ac->tags_mapped++;
- return ac->tag_che_map[type][elem_id] = ac->che[TYPE_SCE][1];
- }
- if (ac->tags_mapped == 2 &&
- ac->oc[1].m4ac.chan_config == 4 &&
- type == TYPE_SCE) {
- ac->tags_mapped++;
- return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1];
- }
- case 3:
- case 2:
- if (ac->tags_mapped == (ac->oc[1].m4ac.chan_config != 2) &&
- type == TYPE_CPE) {
- ac->tags_mapped++;
- return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][0];
- } else if (ac->oc[1].m4ac.chan_config == 2) {
- return NULL;
- }
- case 1:
- if (!ac->tags_mapped && type == TYPE_SCE) {
- ac->tags_mapped++;
- return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][0];
- }
- default:
- return NULL;
- }
-}
-
-/**
- * Decode an array of 4 bit element IDs, optionally interleaved with a
- * stereo/mono switching bit.
- *
- * @param type speaker type/position for these channels
- */
-static void decode_channel_map(uint8_t layout_map[][3],
- enum ChannelPosition type,
- GetBitContext *gb, int n)
-{
- while (n--) {
- enum RawDataBlockType syn_ele;
- switch (type) {
- case AAC_CHANNEL_FRONT:
- case AAC_CHANNEL_BACK:
- case AAC_CHANNEL_SIDE:
- syn_ele = get_bits1(gb);
- break;
- case AAC_CHANNEL_CC:
- skip_bits1(gb);
- syn_ele = TYPE_CCE;
- break;
- case AAC_CHANNEL_LFE:
- syn_ele = TYPE_LFE;
- break;
- default:
- // AAC_CHANNEL_OFF has no channel map
- av_assert0(0);
- }
- layout_map[0][0] = syn_ele;
- layout_map[0][1] = get_bits(gb, 4);
- layout_map[0][2] = type;
- layout_map++;
- }
-}
-
-/**
- * Decode program configuration element; reference: table 4.2.
- *
- * @return Returns error status. 0 - OK, !0 - error
- */
-static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac,
- uint8_t (*layout_map)[3],
- GetBitContext *gb)
-{
- int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc;
- int sampling_index;
- int comment_len;
- int tags;
-
- skip_bits(gb, 2); // object_type
-
- sampling_index = get_bits(gb, 4);
- if (m4ac->sampling_index != sampling_index)
- av_log(avctx, AV_LOG_WARNING,
- "Sample rate index in program config element does not "
- "match the sample rate index configured by the container.\n");
-
- num_front = get_bits(gb, 4);
- num_side = get_bits(gb, 4);
- num_back = get_bits(gb, 4);
- num_lfe = get_bits(gb, 2);
- num_assoc_data = get_bits(gb, 3);
- num_cc = get_bits(gb, 4);
-
- if (get_bits1(gb))
- skip_bits(gb, 4); // mono_mixdown_tag
- if (get_bits1(gb))
- skip_bits(gb, 4); // stereo_mixdown_tag
-
- if (get_bits1(gb))
- skip_bits(gb, 3); // mixdown_coeff_index and pseudo_surround
-
- if (get_bits_left(gb) < 4 * (num_front + num_side + num_back + num_lfe + num_assoc_data + num_cc)) {
- av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err);
- return -1;
- }
- decode_channel_map(layout_map , AAC_CHANNEL_FRONT, gb, num_front);
- tags = num_front;
- decode_channel_map(layout_map + tags, AAC_CHANNEL_SIDE, gb, num_side);
- tags += num_side;
- decode_channel_map(layout_map + tags, AAC_CHANNEL_BACK, gb, num_back);
- tags += num_back;
- decode_channel_map(layout_map + tags, AAC_CHANNEL_LFE, gb, num_lfe);
- tags += num_lfe;
-
- skip_bits_long(gb, 4 * num_assoc_data);
-
- decode_channel_map(layout_map + tags, AAC_CHANNEL_CC, gb, num_cc);
- tags += num_cc;
-
- align_get_bits(gb);
-
- /* comment field, first byte is length */
- comment_len = get_bits(gb, 8) * 8;
- if (get_bits_left(gb) < comment_len) {
- av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err);
- return AVERROR_INVALIDDATA;
- }
- skip_bits_long(gb, comment_len);
- return tags;
-}
-
-/**
- * Decode GA "General Audio" specific configuration; reference: table 4.1.
- *
- * @param ac pointer to AACContext, may be null
- * @param avctx pointer to AVCCodecContext, used for logging
- *
- * @return Returns error status. 0 - OK, !0 - error
- */
-static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx,
- GetBitContext *gb,
- MPEG4AudioConfig *m4ac,
- int channel_config)
-{
- int extension_flag, ret, ep_config, res_flags;
- uint8_t layout_map[MAX_ELEM_ID*4][3];
- int tags = 0;
-
- if (get_bits1(gb)) { // frameLengthFlag
- avpriv_request_sample(avctx, "960/120 MDCT window");
- return AVERROR_PATCHWELCOME;
- }
- m4ac->frame_length_short = 0;
-
- if (get_bits1(gb)) // dependsOnCoreCoder
- skip_bits(gb, 14); // coreCoderDelay
- extension_flag = get_bits1(gb);
-
- if (m4ac->object_type == AOT_AAC_SCALABLE ||
- m4ac->object_type == AOT_ER_AAC_SCALABLE)
- skip_bits(gb, 3); // layerNr
-
- if (channel_config == 0) {
- skip_bits(gb, 4); // element_instance_tag
- tags = decode_pce(avctx, m4ac, layout_map, gb);
- if (tags < 0)
- return tags;
- } else {
- if ((ret = set_default_channel_config(avctx, layout_map,
- &tags, channel_config)))
- return ret;
- }
-
- if (count_channels(layout_map, tags) > 1) {
- m4ac->ps = 0;
- } else if (m4ac->sbr == 1 && m4ac->ps == -1)
- m4ac->ps = 1;
-
- if (ac && (ret = output_configure(ac, layout_map, tags, OC_GLOBAL_HDR, 0)))
- return ret;
-
- if (extension_flag) {
- switch (m4ac->object_type) {
- case AOT_ER_BSAC:
- skip_bits(gb, 5); // numOfSubFrame
- skip_bits(gb, 11); // layer_length
- break;
- case AOT_ER_AAC_LC:
- case AOT_ER_AAC_LTP:
- case AOT_ER_AAC_SCALABLE:
- case AOT_ER_AAC_LD:
- res_flags = get_bits(gb, 3);
- if (res_flags) {
- avpriv_report_missing_feature(avctx,
- "AAC data resilience (flags %x)",
- res_flags);
- return AVERROR_PATCHWELCOME;
- }
- break;
- }
- skip_bits1(gb); // extensionFlag3 (TBD in version 3)
- }
- switch (m4ac->object_type) {
- case AOT_ER_AAC_LC:
- case AOT_ER_AAC_LTP:
- case AOT_ER_AAC_SCALABLE:
- case AOT_ER_AAC_LD:
- ep_config = get_bits(gb, 2);
- if (ep_config) {
- avpriv_report_missing_feature(avctx,
- "epConfig %d", ep_config);
- return AVERROR_PATCHWELCOME;
- }
- }
- return 0;
-}
-
-static int decode_eld_specific_config(AACContext *ac, AVCodecContext *avctx,
- GetBitContext *gb,
- MPEG4AudioConfig *m4ac,
- int channel_config)
-{
- int ret, ep_config, res_flags;
- uint8_t layout_map[MAX_ELEM_ID*4][3];
- int tags = 0;
- const int ELDEXT_TERM = 0;
-
- m4ac->ps = 0;
- m4ac->sbr = 0;
-#if USE_FIXED
- if (get_bits1(gb)) { // frameLengthFlag
- avpriv_request_sample(avctx, "960/120 MDCT window");
- return AVERROR_PATCHWELCOME;
- }
-#else
- m4ac->frame_length_short = get_bits1(gb);
-#endif
- res_flags = get_bits(gb, 3);
- if (res_flags) {
- avpriv_report_missing_feature(avctx,
- "AAC data resilience (flags %x)",
- res_flags);
- return AVERROR_PATCHWELCOME;
- }
-
- if (get_bits1(gb)) { // ldSbrPresentFlag
- avpriv_report_missing_feature(avctx,
- "Low Delay SBR");
- return AVERROR_PATCHWELCOME;
- }
-
- while (get_bits(gb, 4) != ELDEXT_TERM) {
- int len = get_bits(gb, 4);
- if (len == 15)
- len += get_bits(gb, 8);
- if (len == 15 + 255)
- len += get_bits(gb, 16);
- if (get_bits_left(gb) < len * 8 + 4) {
- av_log(avctx, AV_LOG_ERROR, overread_err);
- return AVERROR_INVALIDDATA;
- }
- skip_bits_long(gb, 8 * len);
- }
-
- if ((ret = set_default_channel_config(avctx, layout_map,
- &tags, channel_config)))
- return ret;
-
- if (ac && (ret = output_configure(ac, layout_map, tags, OC_GLOBAL_HDR, 0)))
- return ret;
-
- ep_config = get_bits(gb, 2);
- if (ep_config) {
- avpriv_report_missing_feature(avctx,
- "epConfig %d", ep_config);
- return AVERROR_PATCHWELCOME;
- }
- return 0;
-}
-
-/**
- * Decode audio specific configuration; reference: table 1.13.
- *
- * @param ac pointer to AACContext, may be null
- * @param avctx pointer to AVCCodecContext, used for logging
- * @param m4ac pointer to MPEG4AudioConfig, used for parsing
- * @param data pointer to buffer holding an audio specific config
- * @param bit_size size of audio specific config or data in bits
- * @param sync_extension look for an appended sync extension
- *
- * @return Returns error status or number of consumed bits. <0 - error
- */
-static int decode_audio_specific_config(AACContext *ac,
- AVCodecContext *avctx,
- MPEG4AudioConfig *m4ac,
- const uint8_t *data, int64_t bit_size,
- int sync_extension)
-{
- GetBitContext gb;
- int i, ret;
-
- if (bit_size < 0 || bit_size > INT_MAX) {
- av_log(avctx, AV_LOG_ERROR, "Audio specific config size is invalid\n");
- return AVERROR_INVALIDDATA;
- }
-
- ff_dlog(avctx, "audio specific config size %d\n", (int)bit_size >> 3);
- for (i = 0; i < bit_size >> 3; i++)
- ff_dlog(avctx, "%02x ", data[i]);
- ff_dlog(avctx, "\n");
-
- if ((ret = init_get_bits(&gb, data, bit_size)) < 0)
- return ret;
-
- if ((i = avpriv_mpeg4audio_get_config(m4ac, data, bit_size,
- sync_extension)) < 0)
- return AVERROR_INVALIDDATA;
- if (m4ac->sampling_index > 12) {
- av_log(avctx, AV_LOG_ERROR,
- "invalid sampling rate index %d\n",
- m4ac->sampling_index);
- return AVERROR_INVALIDDATA;
- }
- if (m4ac->object_type == AOT_ER_AAC_LD &&
- (m4ac->sampling_index < 3 || m4ac->sampling_index > 7)) {
- av_log(avctx, AV_LOG_ERROR,
- "invalid low delay sampling rate index %d\n",
- m4ac->sampling_index);
- return AVERROR_INVALIDDATA;
- }
-
- skip_bits_long(&gb, i);
-
- switch (m4ac->object_type) {
- case AOT_AAC_MAIN:
- case AOT_AAC_LC:
- case AOT_AAC_LTP:
- case AOT_ER_AAC_LC:
- case AOT_ER_AAC_LD:
- if ((ret = decode_ga_specific_config(ac, avctx, &gb,
- m4ac, m4ac->chan_config)) < 0)
- return ret;
- break;
- case AOT_ER_AAC_ELD:
- if ((ret = decode_eld_specific_config(ac, avctx, &gb,
- m4ac, m4ac->chan_config)) < 0)
- return ret;
- break;
- default:
- avpriv_report_missing_feature(avctx,
- "Audio object type %s%d",
- m4ac->sbr == 1 ? "SBR+" : "",
- m4ac->object_type);
- return AVERROR(ENOSYS);
- }
-
- ff_dlog(avctx,
- "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n",
- m4ac->object_type, m4ac->chan_config, m4ac->sampling_index,
- m4ac->sample_rate, m4ac->sbr,
- m4ac->ps);
-
- return get_bits_count(&gb);
-}
-
-/**
- * linear congruential pseudorandom number generator
- *
- * @param previous_val pointer to the current state of the generator
- *
- * @return Returns a 32-bit pseudorandom integer
- */
-static av_always_inline int lcg_random(unsigned previous_val)
-{
- union { unsigned u; int s; } v = { previous_val * 1664525u + 1013904223 };
- return v.s;
-}
-
-static void reset_all_predictors(PredictorState *ps)
-{
- int i;
- for (i = 0; i < MAX_PREDICTORS; i++)
- reset_predict_state(&ps[i]);
-}
-
-static int sample_rate_idx (int rate)
-{
- if (92017 <= rate) return 0;
- else if (75132 <= rate) return 1;
- else if (55426 <= rate) return 2;
- else if (46009 <= rate) return 3;
- else if (37566 <= rate) return 4;
- else if (27713 <= rate) return 5;
- else if (23004 <= rate) return 6;
- else if (18783 <= rate) return 7;
- else if (13856 <= rate) return 8;
- else if (11502 <= rate) return 9;
- else if (9391 <= rate) return 10;
- else return 11;
-}
-
-static void reset_predictor_group(PredictorState *ps, int group_num)
-{
- int i;
- for (i = group_num - 1; i < MAX_PREDICTORS; i += 30)
- 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 int aac_decode_init(AVCodecContext *avctx)
-{
- AACContext *ac = avctx->priv_data;
- int ret;
-
- ac->avctx = avctx;
- ac->oc[1].m4ac.sample_rate = avctx->sample_rate;
-
- aacdec_init(ac);
-#if USE_FIXED
- avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
-#else
- avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
-#endif /* USE_FIXED */
-
- if (avctx->extradata_size > 0) {
- if ((ret = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
- avctx->extradata,
- avctx->extradata_size * 8LL,
- 1)) < 0)
- return ret;
- } else {
- int sr, i;
- uint8_t layout_map[MAX_ELEM_ID*4][3];
- int layout_map_tags;
-
- sr = sample_rate_idx(avctx->sample_rate);
- ac->oc[1].m4ac.sampling_index = sr;
- ac->oc[1].m4ac.channels = avctx->channels;
- ac->oc[1].m4ac.sbr = -1;
- ac->oc[1].m4ac.ps = -1;
-
- for (i = 0; i < FF_ARRAY_ELEMS(ff_mpeg4audio_channels); i++)
- if (ff_mpeg4audio_channels[i] == avctx->channels)
- break;
- if (i == FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) {
- i = 0;
- }
- ac->oc[1].m4ac.chan_config = i;
-
- if (ac->oc[1].m4ac.chan_config) {
- int ret = set_default_channel_config(avctx, layout_map,
- &layout_map_tags, ac->oc[1].m4ac.chan_config);
- if (!ret)
- output_configure(ac, layout_map, layout_map_tags,
- OC_GLOBAL_HDR, 0);
- else if (avctx->err_recognition & AV_EF_EXPLODE)
- return AVERROR_INVALIDDATA;
- }
- }
-
- if (avctx->channels > MAX_CHANNELS) {
- av_log(avctx, AV_LOG_ERROR, "Too many channels\n");
- return AVERROR_INVALIDDATA;
- }
-
- 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);
-
- AAC_RENAME(ff_aac_sbr_init)();
-
-#if USE_FIXED
- ac->fdsp = avpriv_alloc_fixed_dsp(avctx->flags & AV_CODEC_FLAG_BITEXACT);
-#else
- ac->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
-#endif /* USE_FIXED */
- if (!ac->fdsp) {
- return AVERROR(ENOMEM);
- }
-
- ac->random_state = 0x1f2e3d4c;
-
- ff_aac_tableinit();
-
- INIT_VLC_STATIC(&vlc_scalefactors, 7,
- FF_ARRAY_ELEMS(ff_aac_scalefactor_code),
- ff_aac_scalefactor_bits,
- sizeof(ff_aac_scalefactor_bits[0]),
- sizeof(ff_aac_scalefactor_bits[0]),
- ff_aac_scalefactor_code,
- sizeof(ff_aac_scalefactor_code[0]),
- sizeof(ff_aac_scalefactor_code[0]),
- 352);
-
- AAC_RENAME_32(ff_mdct_init)(&ac->mdct, 11, 1, 1.0 / RANGE15(1024.0));
- AAC_RENAME_32(ff_mdct_init)(&ac->mdct_ld, 10, 1, 1.0 / RANGE15(512.0));
- AAC_RENAME_32(ff_mdct_init)(&ac->mdct_small, 8, 1, 1.0 / RANGE15(128.0));
- AAC_RENAME_32(ff_mdct_init)(&ac->mdct_ltp, 11, 0, RANGE15(-2.0));
-#if !USE_FIXED
- ret = ff_imdct15_init(&ac->mdct480, 5);
- if (ret < 0)
- return ret;
-#endif
- // 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);
- 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(cbrt_tableinit)();
-
- return 0;
-}
-
-/**
- * Skip data_stream_element; reference: table 4.10.
- */
-static int skip_data_stream_element(AACContext *ac, GetBitContext *gb)
-{
- int byte_align = get_bits1(gb);
- int count = get_bits(gb, 8);
- if (count == 255)
- count += get_bits(gb, 8);
- if (byte_align)
- align_get_bits(gb);
-
- if (get_bits_left(gb) < 8 * count) {
- av_log(ac->avctx, AV_LOG_ERROR, "skip_data_stream_element: "overread_err);
- return AVERROR_INVALIDDATA;
- }
- skip_bits_long(gb, 8 * count);
- return 0;
-}
-
-static int decode_prediction(AACContext *ac, IndividualChannelStream *ics,
- GetBitContext *gb)
-{
- int sfb;
- if (get_bits1(gb)) {
- ics->predictor_reset_group = get_bits(gb, 5);
- if (ics->predictor_reset_group == 0 ||
- ics->predictor_reset_group > 30) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Invalid Predictor Reset Group.\n");
- return AVERROR_INVALIDDATA;
- }
- }
- for (sfb = 0; sfb < FFMIN(ics->max_sfb, ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index]); sfb++) {
- ics->prediction_used[sfb] = get_bits1(gb);
- }
- return 0;
-}
-
-/**
- * Decode Long Term Prediction data; reference: table 4.xx.
- */
-static void decode_ltp(LongTermPrediction *ltp,
- GetBitContext *gb, uint8_t max_sfb)
-{
- int sfb;
-
- ltp->lag = get_bits(gb, 11);
- ltp->coef = ltp_coef[get_bits(gb, 3)];
- for (sfb = 0; sfb < FFMIN(max_sfb, MAX_LTP_LONG_SFB); sfb++)
- ltp->used[sfb] = get_bits1(gb);
-}
-
-/**
- * Decode Individual Channel Stream info; reference: table 4.6.
- */
-static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
- GetBitContext *gb)
-{
- const MPEG4AudioConfig *const m4ac = &ac->oc[1].m4ac;
- const int aot = m4ac->object_type;
- const int sampling_index = m4ac->sampling_index;
- if (aot != AOT_ER_AAC_ELD) {
- if (get_bits1(gb)) {
- av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n");
- if (ac->avctx->err_recognition & AV_EF_BITSTREAM)
- return AVERROR_INVALIDDATA;
- }
- ics->window_sequence[1] = ics->window_sequence[0];
- ics->window_sequence[0] = get_bits(gb, 2);
- if (aot == AOT_ER_AAC_LD &&
- ics->window_sequence[0] != ONLY_LONG_SEQUENCE) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "AAC LD is only defined for ONLY_LONG_SEQUENCE but "
- "window sequence %d found.\n", ics->window_sequence[0]);
- ics->window_sequence[0] = ONLY_LONG_SEQUENCE;
- return AVERROR_INVALIDDATA;
- }
- ics->use_kb_window[1] = ics->use_kb_window[0];
- ics->use_kb_window[0] = get_bits1(gb);
- }
- ics->num_window_groups = 1;
- ics->group_len[0] = 1;
- if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
- int i;
- ics->max_sfb = get_bits(gb, 4);
- for (i = 0; i < 7; i++) {
- if (get_bits1(gb)) {
- ics->group_len[ics->num_window_groups - 1]++;
- } else {
- ics->num_window_groups++;
- ics->group_len[ics->num_window_groups - 1] = 1;
- }
- }
- ics->num_windows = 8;
- ics->swb_offset = ff_swb_offset_128[sampling_index];
- ics->num_swb = ff_aac_num_swb_128[sampling_index];
- ics->tns_max_bands = ff_tns_max_bands_128[sampling_index];
- ics->predictor_present = 0;
- } else {
- ics->max_sfb = get_bits(gb, 6);
- ics->num_windows = 1;
- if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) {
- if (m4ac->frame_length_short) {
- ics->swb_offset = ff_swb_offset_480[sampling_index];
- ics->num_swb = ff_aac_num_swb_480[sampling_index];
- ics->tns_max_bands = ff_tns_max_bands_480[sampling_index];
- } else {
- ics->swb_offset = ff_swb_offset_512[sampling_index];
- ics->num_swb = ff_aac_num_swb_512[sampling_index];
- ics->tns_max_bands = ff_tns_max_bands_512[sampling_index];
- }
- if (!ics->num_swb || !ics->swb_offset)
- return AVERROR_BUG;
- } else {
- ics->swb_offset = ff_swb_offset_1024[sampling_index];
- ics->num_swb = ff_aac_num_swb_1024[sampling_index];
- ics->tns_max_bands = ff_tns_max_bands_1024[sampling_index];
- }
- if (aot != AOT_ER_AAC_ELD) {
- ics->predictor_present = get_bits1(gb);
- ics->predictor_reset_group = 0;
- }
- if (ics->predictor_present) {
- if (aot == AOT_AAC_MAIN) {
- if (decode_prediction(ac, ics, gb)) {
- goto fail;
- }
- } else if (aot == AOT_AAC_LC ||
- aot == AOT_ER_AAC_LC) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Prediction is not allowed in AAC-LC.\n");
- goto fail;
- } else {
- if (aot == AOT_ER_AAC_LD) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "LTP in ER AAC LD not yet implemented.\n");
- return AVERROR_PATCHWELCOME;
- }
- if ((ics->ltp.present = get_bits(gb, 1)))
- decode_ltp(&ics->ltp, gb, ics->max_sfb);
- }
- }
- }
-
- if (ics->max_sfb > ics->num_swb) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Number of scalefactor bands in group (%d) "
- "exceeds limit (%d).\n",
- ics->max_sfb, ics->num_swb);
- goto fail;
- }
-
- return 0;
-fail:
- ics->max_sfb = 0;
- return AVERROR_INVALIDDATA;
-}
-
-/**
- * Decode band types (section_data payload); reference: table 4.46.
- *
- * @param band_type array of the used band type
- * @param band_type_run_end array of the last scalefactor band of a band type run
- *
- * @return Returns error status. 0 - OK, !0 - error
- */
-static int decode_band_types(AACContext *ac, enum BandType band_type[120],
- int band_type_run_end[120], GetBitContext *gb,
- IndividualChannelStream *ics)
-{
- int g, idx = 0;
- const int bits = (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) ? 3 : 5;
- for (g = 0; g < ics->num_window_groups; g++) {
- int k = 0;
- while (k < ics->max_sfb) {
- uint8_t sect_end = k;
- int sect_len_incr;
- int sect_band_type = get_bits(gb, 4);
- if (sect_band_type == 12) {
- av_log(ac->avctx, AV_LOG_ERROR, "invalid band type\n");
- return AVERROR_INVALIDDATA;
- }
- do {
- sect_len_incr = get_bits(gb, bits);
- sect_end += sect_len_incr;
- if (get_bits_left(gb) < 0) {
- av_log(ac->avctx, AV_LOG_ERROR, "decode_band_types: "overread_err);
- return AVERROR_INVALIDDATA;
- }
- if (sect_end > ics->max_sfb) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Number of bands (%d) exceeds limit (%d).\n",
- sect_end, ics->max_sfb);
- return AVERROR_INVALIDDATA;
- }
- } while (sect_len_incr == (1 << bits) - 1);
- for (; k < sect_end; k++) {
- band_type [idx] = sect_band_type;
- band_type_run_end[idx++] = sect_end;
- }
- }
- }
- return 0;
-}
-
-/**
- * Decode scalefactors; reference: table 4.47.
- *
- * @param global_gain first scalefactor value as scalefactors are differentially coded
- * @param band_type array of the used band type
- * @param band_type_run_end array of the last scalefactor band of a band type run
- * @param sf array of scalefactors or intensity stereo positions
- *
- * @return Returns error status. 0 - OK, !0 - error
- */
-static int decode_scalefactors(AACContext *ac, INTFLOAT sf[120], GetBitContext *gb,
- unsigned int global_gain,
- IndividualChannelStream *ics,
- enum BandType band_type[120],
- int band_type_run_end[120])
-{
- int g, i, idx = 0;
- int offset[3] = { global_gain, global_gain - NOISE_OFFSET, 0 };
- int clipped_offset;
- int noise_flag = 1;
- for (g = 0; g < ics->num_window_groups; g++) {
- for (i = 0; i < ics->max_sfb;) {
- int run_end = band_type_run_end[idx];
- if (band_type[idx] == ZERO_BT) {
- for (; i < run_end; i++, idx++)
- sf[idx] = FIXR(0.);
- } else if ((band_type[idx] == INTENSITY_BT) ||
- (band_type[idx] == INTENSITY_BT2)) {
- for (; i < run_end; i++, idx++) {
- offset[2] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - SCALE_DIFF_ZERO;
- clipped_offset = av_clip(offset[2], -155, 100);
- if (offset[2] != clipped_offset) {
- avpriv_request_sample(ac->avctx,
- "If you heard an audible artifact, there may be a bug in the decoder. "
- "Clipped intensity stereo position (%d -> %d)",
- offset[2], clipped_offset);
- }
-#if USE_FIXED
- sf[idx] = 100 - clipped_offset;
-#else
- sf[idx] = ff_aac_pow2sf_tab[-clipped_offset + POW_SF2_ZERO];
-#endif /* USE_FIXED */
- }
- } else if (band_type[idx] == NOISE_BT) {
- for (; i < run_end; i++, idx++) {
- if (noise_flag-- > 0)
- offset[1] += get_bits(gb, NOISE_PRE_BITS) - NOISE_PRE;
- else
- offset[1] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - SCALE_DIFF_ZERO;
- clipped_offset = av_clip(offset[1], -100, 155);
- if (offset[1] != clipped_offset) {
- avpriv_request_sample(ac->avctx,
- "If you heard an audible artifact, there may be a bug in the decoder. "
- "Clipped noise gain (%d -> %d)",
- offset[1], clipped_offset);
- }
-#if USE_FIXED
- sf[idx] = -(100 + clipped_offset);
-#else
- sf[idx] = -ff_aac_pow2sf_tab[clipped_offset + POW_SF2_ZERO];
-#endif /* USE_FIXED */
- }
- } else {
- for (; i < run_end; i++, idx++) {
- offset[0] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - SCALE_DIFF_ZERO;
- if (offset[0] > 255U) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Scalefactor (%d) out of range.\n", offset[0]);
- return AVERROR_INVALIDDATA;
- }
-#if USE_FIXED
- sf[idx] = -offset[0];
-#else
- sf[idx] = -ff_aac_pow2sf_tab[offset[0] - 100 + POW_SF2_ZERO];
-#endif /* USE_FIXED */
- }
- }
- }
- }
- return 0;
-}
-
-/**
- * Decode pulse data; reference: table 4.7.
- */
-static int decode_pulses(Pulse *pulse, GetBitContext *gb,
- const uint16_t *swb_offset, int num_swb)
-{
- int i, pulse_swb;
- pulse->num_pulse = get_bits(gb, 2) + 1;
- pulse_swb = get_bits(gb, 6);
- if (pulse_swb >= num_swb)
- return -1;
- pulse->pos[0] = swb_offset[pulse_swb];
- pulse->pos[0] += get_bits(gb, 5);
- if (pulse->pos[0] >= swb_offset[num_swb])
- return -1;
- pulse->amp[0] = get_bits(gb, 4);
- for (i = 1; i < pulse->num_pulse; i++) {
- pulse->pos[i] = get_bits(gb, 5) + pulse->pos[i - 1];
- if (pulse->pos[i] >= swb_offset[num_swb])
- return -1;
- pulse->amp[i] = get_bits(gb, 4);
- }
- return 0;
-}
-
-/**
- * Decode Temporal Noise Shaping data; reference: table 4.48.
- *
- * @return Returns error status. 0 - OK, !0 - error
- */
-static int decode_tns(AACContext *ac, TemporalNoiseShaping *tns,
- GetBitContext *gb, const IndividualChannelStream *ics)
-{
- int w, filt, i, coef_len, coef_res, coef_compress;
- const int is8 = ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE;
- const int tns_max_order = is8 ? 7 : ac->oc[1].m4ac.object_type == AOT_AAC_MAIN ? 20 : 12;
- for (w = 0; w < ics->num_windows; w++) {
- if ((tns->n_filt[w] = get_bits(gb, 2 - is8))) {
- coef_res = get_bits1(gb);
-
- for (filt = 0; filt < tns->n_filt[w]; filt++) {
- int tmp2_idx;
- tns->length[w][filt] = get_bits(gb, 6 - 2 * is8);
-
- if ((tns->order[w][filt] = get_bits(gb, 5 - 2 * is8)) > tns_max_order) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "TNS filter order %d is greater than maximum %d.\n",
- tns->order[w][filt], tns_max_order);
- tns->order[w][filt] = 0;
- return AVERROR_INVALIDDATA;
- }
- if (tns->order[w][filt]) {
- tns->direction[w][filt] = get_bits1(gb);
- coef_compress = get_bits1(gb);
- coef_len = coef_res + 3 - coef_compress;
- tmp2_idx = 2 * coef_compress + coef_res;
-
- for (i = 0; i < tns->order[w][filt]; i++)
- tns->coef[w][filt][i] = tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)];
- }
- }
- }
- }
- return 0;
-}
-
-/**
- * Decode Mid/Side data; reference: table 4.54.
- *
- * @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s;
- * [1] mask is decoded from bitstream; [2] mask is all 1s;
- * [3] reserved for scalable AAC
- */
-static void decode_mid_side_stereo(ChannelElement *cpe, GetBitContext *gb,
- int ms_present)
-{
- int idx;
- int max_idx = cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb;
- if (ms_present == 1) {
- for (idx = 0; idx < max_idx; idx++)
- cpe->ms_mask[idx] = get_bits1(gb);
- } else if (ms_present == 2) {
- memset(cpe->ms_mask, 1, max_idx * sizeof(cpe->ms_mask[0]));
- }
-}
-
-/**
- * Decode spectral data; reference: table 4.50.
- * Dequantize and scale spectral data; reference: 4.6.3.3.
- *
- * @param coef array of dequantized, scaled spectral data
- * @param sf array of scalefactors or intensity stereo positions
- * @param pulse_present set if pulses are present
- * @param pulse pointer to pulse data struct
- * @param band_type array of the used band type
- *
- * @return Returns error status. 0 - OK, !0 - error
- */
-static int decode_spectrum_and_dequant(AACContext *ac, INTFLOAT coef[1024],
- GetBitContext *gb, const INTFLOAT sf[120],
- int pulse_present, const Pulse *pulse,
- const IndividualChannelStream *ics,
- enum BandType band_type[120])
-{
- int i, k, g, idx = 0;
- const int c = 1024 / ics->num_windows;
- const uint16_t *offsets = ics->swb_offset;
- INTFLOAT *coef_base = coef;
-
- for (g = 0; g < ics->num_windows; g++)
- memset(coef + g * 128 + offsets[ics->max_sfb], 0,
- sizeof(INTFLOAT) * (c - offsets[ics->max_sfb]));
-
- for (g = 0; g < ics->num_window_groups; g++) {
- unsigned g_len = ics->group_len[g];
-
- for (i = 0; i < ics->max_sfb; i++, idx++) {
- const unsigned cbt_m1 = band_type[idx] - 1;
- INTFLOAT *cfo = coef + offsets[i];
- int off_len = offsets[i + 1] - offsets[i];
- int group;
-
- if (cbt_m1 >= INTENSITY_BT2 - 1) {
- for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
- memset(cfo, 0, off_len * sizeof(*cfo));
- }
- } else if (cbt_m1 == NOISE_BT - 1) {
- for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
-#if !USE_FIXED
- float scale;
-#endif /* !USE_FIXED */
- INTFLOAT band_energy;
-
- for (k = 0; k < off_len; k++) {
- ac->random_state = lcg_random(ac->random_state);
-#if USE_FIXED
- cfo[k] = ac->random_state >> 3;
-#else
- cfo[k] = ac->random_state;
-#endif /* USE_FIXED */
- }
-
-#if USE_FIXED
- band_energy = ac->fdsp->scalarproduct_fixed(cfo, cfo, off_len);
- band_energy = fixed_sqrt(band_energy, 31);
- noise_scale(cfo, sf[idx], band_energy, off_len);
-#else
- band_energy = ac->fdsp->scalarproduct_float(cfo, cfo, off_len);
- scale = sf[idx] / sqrtf(band_energy);
- ac->fdsp->vector_fmul_scalar(cfo, cfo, scale, off_len);
-#endif /* USE_FIXED */
- }
- } else {
-#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);
-
- switch (cbt_m1 >> 1) {
- case 0:
- for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
- INTFLOAT *cf = cfo;
- int len = off_len;
-
- do {
- int code;
- unsigned cb_idx;
-
- UPDATE_CACHE(re, gb);
- GET_VLC(code, re, gb, vlc_tab, 8, 2);
- cb_idx = cb_vector_idx[code];
-#if USE_FIXED
- cf = DEC_SQUAD(cf, cb_idx);
-#else
- cf = VMUL4(cf, vq, cb_idx, sf + idx);
-#endif /* USE_FIXED */
- } while (len -= 4);
- }
- break;
-
- case 1:
- for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
- INTFLOAT *cf = cfo;
- int len = off_len;
-
- do {
- int code;
- unsigned nnz;
- unsigned cb_idx;
- uint32_t bits;
-
- UPDATE_CACHE(re, gb);
- GET_VLC(code, re, gb, vlc_tab, 8, 2);
- cb_idx = cb_vector_idx[code];
- nnz = cb_idx >> 8 & 15;
- bits = nnz ? GET_CACHE(re, gb) : 0;
- LAST_SKIP_BITS(re, gb, nnz);
-#if USE_FIXED
- cf = DEC_UQUAD(cf, cb_idx, bits);
-#else
- cf = VMUL4S(cf, vq, cb_idx, bits, sf + idx);
-#endif /* USE_FIXED */
- } while (len -= 4);
- }
- break;
-
- case 2:
- for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
- INTFLOAT *cf = cfo;
- int len = off_len;
-
- do {
- int code;
- unsigned cb_idx;
-
- UPDATE_CACHE(re, gb);
- GET_VLC(code, re, gb, vlc_tab, 8, 2);
- cb_idx = cb_vector_idx[code];
-#if USE_FIXED
- cf = DEC_SPAIR(cf, cb_idx);
-#else
- cf = VMUL2(cf, vq, cb_idx, sf + idx);
-#endif /* USE_FIXED */
- } while (len -= 2);
- }
- break;
-
- case 3:
- case 4:
- for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
- INTFLOAT *cf = cfo;
- int len = off_len;
-
- do {
- int code;
- unsigned nnz;
- unsigned cb_idx;
- unsigned sign;
-
- UPDATE_CACHE(re, gb);
- GET_VLC(code, re, gb, vlc_tab, 8, 2);
- cb_idx = cb_vector_idx[code];
- nnz = cb_idx >> 8 & 15;
- sign = nnz ? SHOW_UBITS(re, gb, nnz) << (cb_idx >> 12) : 0;
- LAST_SKIP_BITS(re, gb, nnz);
-#if USE_FIXED
- cf = DEC_UPAIR(cf, cb_idx, sign);
-#else
- cf = VMUL2S(cf, vq, cb_idx, sign, sf + idx);
-#endif /* USE_FIXED */
- } while (len -= 2);
- }
- break;
-
- default:
- for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
-#if USE_FIXED
- int *icf = cfo;
- int v;
-#else
- float *cf = cfo;
- uint32_t *icf = (uint32_t *) cf;
-#endif /* USE_FIXED */
- int len = off_len;
-
- do {
- int code;
- unsigned nzt, nnz;
- unsigned cb_idx;
- uint32_t bits;
- int j;
-
- UPDATE_CACHE(re, gb);
- GET_VLC(code, re, gb, vlc_tab, 8, 2);
-
- if (!code) {
- *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);
- LAST_SKIP_BITS(re, gb, nnz);
-
- for (j = 0; j < 2; j++) {
- if (nzt & 1<<j) {
- uint32_t b;
- int n;
- /* The total length of escape_sequence must be < 22 bits according
- to the specification (i.e. max is 111111110xxxxxxxxxxxx). */
- UPDATE_CACHE(re, gb);
- b = GET_CACHE(re, gb);
- b = 31 - av_log2(~b);
-
- if (b > 8) {
- av_log(ac->avctx, AV_LOG_ERROR, "error in spectral data, ESC overflow\n");
- return AVERROR_INVALIDDATA;
- }
-
- SKIP_BITS(re, gb, b + 1);
- b += 4;
- n = (1 << b) + SHOW_UBITS(re, gb, b);
- LAST_SKIP_BITS(re, gb, b);
-#if USE_FIXED
- v = n;
- if (bits & 1U<<31)
- v = -v;
- *icf++ = v;
-#else
- *icf++ = cbrt_tab[n] | (bits & 1U<<31);
-#endif /* USE_FIXED */
- bits <<= 1;
- } else {
-#if USE_FIXED
- v = cb_idx & 15;
- if (bits & 1U<<31)
- v = -v;
- *icf++ = v;
-#else
- unsigned v = ((const uint32_t*)vq)[cb_idx & 15];
- *icf++ = (bits & 1U<<31) | v;
-#endif /* USE_FIXED */
- bits <<= !!v;
- }
- cb_idx >>= 4;
- }
- } while (len -= 2);
-#if !USE_FIXED
- ac->fdsp->vector_fmul_scalar(cfo, cfo, sf[idx], off_len);
-#endif /* !USE_FIXED */
- }
- }
-
- CLOSE_READER(re, gb);
- }
- }
- coef += g_len << 7;
- }
-
- if (pulse_present) {
- idx = 0;
- for (i = 0; i < pulse->num_pulse; i++) {
- INTFLOAT co = coef_base[ pulse->pos[i] ];
- while (offsets[idx + 1] <= pulse->pos[i])
- idx++;
- if (band_type[idx] != NOISE_BT && sf[idx]) {
- INTFLOAT ico = -pulse->amp[i];
-#if USE_FIXED
- if (co) {
- ico = co + (co > 0 ? -ico : ico);
- }
- coef_base[ pulse->pos[i] ] = ico;
-#else
- if (co) {
- co /= sf[idx];
- ico = co / sqrtf(sqrtf(fabsf(co))) + (co > 0 ? -ico : ico);
- }
- coef_base[ pulse->pos[i] ] = cbrtf(fabsf(ico)) * ico * sf[idx];
-#endif /* USE_FIXED */
- }
- }
- }
-#if USE_FIXED
- coef = coef_base;
- idx = 0;
- for (g = 0; g < ics->num_window_groups; g++) {
- unsigned g_len = ics->group_len[g];
-
- for (i = 0; i < ics->max_sfb; i++, idx++) {
- const unsigned cbt_m1 = band_type[idx] - 1;
- int *cfo = coef + offsets[i];
- int off_len = offsets[i + 1] - offsets[i];
- int group;
-
- if (cbt_m1 < NOISE_BT - 1) {
- for (group = 0; group < (int)g_len; group++, cfo+=128) {
- ac->vector_pow43(cfo, off_len);
- ac->subband_scale(cfo, cfo, sf[idx], 34, off_len);
- }
- }
- }
- coef += g_len << 7;
- }
-#endif /* USE_FIXED */
- return 0;
-}
-
-/**
- * Apply AAC-Main style frequency domain prediction.
- */
-static void apply_prediction(AACContext *ac, SingleChannelElement *sce)
-{
- int sfb, k;
-
- if (!sce->ics.predictor_initialized) {
- reset_all_predictors(sce->predictor_state);
- sce->ics.predictor_initialized = 1;
- }
-
- if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
- for (sfb = 0;
- sfb < ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index];
- sfb++) {
- for (k = sce->ics.swb_offset[sfb];
- k < sce->ics.swb_offset[sfb + 1];
- k++) {
- predict(&sce->predictor_state[k], &sce->coeffs[k],
- sce->ics.predictor_present &&
- sce->ics.prediction_used[sfb]);
- }
- }
- if (sce->ics.predictor_reset_group)
- reset_predictor_group(sce->predictor_state,
- sce->ics.predictor_reset_group);
- } else
- reset_all_predictors(sce->predictor_state);
-}
-
-/**
- * Decode an individual_channel_stream payload; reference: table 4.44.
- *
- * @param common_window Channels have independent [0], or shared [1], Individual Channel Stream information.
- * @param scale_flag scalable [1] or non-scalable [0] AAC (Unused until scalable AAC is implemented.)
- *
- * @return Returns error status. 0 - OK, !0 - error
- */
-static int decode_ics(AACContext *ac, SingleChannelElement *sce,
- GetBitContext *gb, int common_window, int scale_flag)
-{
- Pulse pulse;
- TemporalNoiseShaping *tns = &sce->tns;
- IndividualChannelStream *ics = &sce->ics;
- INTFLOAT *out = sce->coeffs;
- int global_gain, eld_syntax, er_syntax, pulse_present = 0;
- int ret;
-
- eld_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD;
- er_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC ||
- ac->oc[1].m4ac.object_type == AOT_ER_AAC_LTP ||
- ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD ||
- ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD;
-
- /* This assignment is to silence a GCC warning about the variable being used
- * uninitialized when in fact it always is.
- */
- pulse.num_pulse = 0;
-
- global_gain = get_bits(gb, 8);
-
- if (!common_window && !scale_flag) {
- if (decode_ics_info(ac, ics, gb) < 0)
- return AVERROR_INVALIDDATA;
- }
-
- if ((ret = decode_band_types(ac, sce->band_type,
- sce->band_type_run_end, gb, ics)) < 0)
- return ret;
- if ((ret = decode_scalefactors(ac, sce->sf, gb, global_gain, ics,
- sce->band_type, sce->band_type_run_end)) < 0)
- return ret;
-
- pulse_present = 0;
- if (!scale_flag) {
- if (!eld_syntax && (pulse_present = get_bits1(gb))) {
- if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Pulse tool not allowed in eight short sequence.\n");
- return AVERROR_INVALIDDATA;
- }
- if (decode_pulses(&pulse, gb, ics->swb_offset, ics->num_swb)) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Pulse data corrupt or invalid.\n");
- return AVERROR_INVALIDDATA;
- }
- }
- tns->present = get_bits1(gb);
- if (tns->present && !er_syntax)
- if (decode_tns(ac, tns, gb, ics) < 0)
- return AVERROR_INVALIDDATA;
- if (!eld_syntax && get_bits1(gb)) {
- avpriv_request_sample(ac->avctx, "SSR");
- return AVERROR_PATCHWELCOME;
- }
- // I see no textual basis in the spec for this occurring after SSR gain
- // control, but this is what both reference and real implmentations do
- if (tns->present && er_syntax)
- if (decode_tns(ac, tns, gb, ics) < 0)
- return AVERROR_INVALIDDATA;
- }
-
- if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present,
- &pulse, ics, sce->band_type) < 0)
- return AVERROR_INVALIDDATA;
-
- if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN && !common_window)
- apply_prediction(ac, sce);
-
- return 0;
-}
-
-/**
- * Mid/Side stereo decoding; reference: 4.6.8.1.3.
- */
-static void apply_mid_side_stereo(AACContext *ac, ChannelElement *cpe)
-{
- const IndividualChannelStream *ics = &cpe->ch[0].ics;
- INTFLOAT *ch0 = cpe->ch[0].coeffs;
- INTFLOAT *ch1 = cpe->ch[1].coeffs;
- int g, i, group, idx = 0;
- const uint16_t *offsets = ics->swb_offset;
- for (g = 0; g < ics->num_window_groups; g++) {
- for (i = 0; i < ics->max_sfb; i++, idx++) {
- if (cpe->ms_mask[idx] &&
- cpe->ch[0].band_type[idx] < NOISE_BT &&
- cpe->ch[1].band_type[idx] < NOISE_BT) {
-#if USE_FIXED
- for (group = 0; group < ics->group_len[g]; group++) {
- ac->fdsp->butterflies_fixed(ch0 + group * 128 + offsets[i],
- ch1 + group * 128 + offsets[i],
- offsets[i+1] - offsets[i]);
-#else
- for (group = 0; group < ics->group_len[g]; group++) {
- ac->fdsp->butterflies_float(ch0 + group * 128 + offsets[i],
- ch1 + group * 128 + offsets[i],
- offsets[i+1] - offsets[i]);
-#endif /* USE_FIXED */
- }
- }
- }
- ch0 += ics->group_len[g] * 128;
- ch1 += ics->group_len[g] * 128;
- }
-}
-
-/**
- * intensity stereo decoding; reference: 4.6.8.2.3
- *
- * @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s;
- * [1] mask is decoded from bitstream; [2] mask is all 1s;
- * [3] reserved for scalable AAC
- */
-static void apply_intensity_stereo(AACContext *ac,
- ChannelElement *cpe, int ms_present)
-{
- const IndividualChannelStream *ics = &cpe->ch[1].ics;
- SingleChannelElement *sce1 = &cpe->ch[1];
- INTFLOAT *coef0 = cpe->ch[0].coeffs, *coef1 = cpe->ch[1].coeffs;
- const uint16_t *offsets = ics->swb_offset;
- int g, group, i, idx = 0;
- int c;
- INTFLOAT scale;
- for (g = 0; g < ics->num_window_groups; g++) {
- for (i = 0; i < ics->max_sfb;) {
- if (sce1->band_type[idx] == INTENSITY_BT ||
- sce1->band_type[idx] == INTENSITY_BT2) {
- const int bt_run_end = sce1->band_type_run_end[idx];
- for (; i < bt_run_end; i++, idx++) {
- c = -1 + 2 * (sce1->band_type[idx] - 14);
- if (ms_present)
- c *= 1 - 2 * cpe->ms_mask[idx];
- scale = c * sce1->sf[idx];
- for (group = 0; group < ics->group_len[g]; group++)
-#if USE_FIXED
- ac->subband_scale(coef1 + group * 128 + offsets[i],
- coef0 + group * 128 + offsets[i],
- scale,
- 23,
- offsets[i + 1] - offsets[i]);
-#else
- ac->fdsp->vector_fmul_scalar(coef1 + group * 128 + offsets[i],
- coef0 + group * 128 + offsets[i],
- scale,
- offsets[i + 1] - offsets[i]);
-#endif /* USE_FIXED */
- }
- } else {
- int bt_run_end = sce1->band_type_run_end[idx];
- idx += bt_run_end - i;
- i = bt_run_end;
- }
- }
- coef0 += ics->group_len[g] * 128;
- coef1 += ics->group_len[g] * 128;
- }
-}
-
-/**
- * Decode a channel_pair_element; reference: table 4.4.
- *
- * @return Returns error status. 0 - OK, !0 - error
- */
-static int decode_cpe(AACContext *ac, GetBitContext *gb, ChannelElement *cpe)
-{
- int i, ret, common_window, ms_present = 0;
- int eld_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD;
-
- common_window = eld_syntax || get_bits1(gb);
- if (common_window) {
- if (decode_ics_info(ac, &cpe->ch[0].ics, gb))
- return AVERROR_INVALIDDATA;
- i = cpe->ch[1].ics.use_kb_window[0];
- cpe->ch[1].ics = cpe->ch[0].ics;
- cpe->ch[1].ics.use_kb_window[1] = i;
- if (cpe->ch[1].ics.predictor_present &&
- (ac->oc[1].m4ac.object_type != AOT_AAC_MAIN))
- if ((cpe->ch[1].ics.ltp.present = get_bits(gb, 1)))
- decode_ltp(&cpe->ch[1].ics.ltp, gb, cpe->ch[1].ics.max_sfb);
- ms_present = get_bits(gb, 2);
- if (ms_present == 3) {
- av_log(ac->avctx, AV_LOG_ERROR, "ms_present = 3 is reserved.\n");
- return AVERROR_INVALIDDATA;
- } else if (ms_present)
- decode_mid_side_stereo(cpe, gb, ms_present);
- }
- if ((ret = decode_ics(ac, &cpe->ch[0], gb, common_window, 0)))
- return ret;
- if ((ret = decode_ics(ac, &cpe->ch[1], gb, common_window, 0)))
- return ret;
-
- if (common_window) {
- if (ms_present)
- apply_mid_side_stereo(ac, cpe);
- if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN) {
- apply_prediction(ac, &cpe->ch[0]);
- apply_prediction(ac, &cpe->ch[1]);
- }
- }
-
- apply_intensity_stereo(ac, cpe, ms_present);
- return 0;
-}
-
-static const float cce_scale[] = {
- 1.09050773266525765921, //2^(1/8)
- 1.18920711500272106672, //2^(1/4)
- M_SQRT2,
- 2,
-};
-
-/**
- * Decode coupling_channel_element; reference: table 4.8.
- *
- * @return Returns error status. 0 - OK, !0 - error
- */
-static int decode_cce(AACContext *ac, GetBitContext *gb, ChannelElement *che)
-{
- int num_gain = 0;
- int c, g, sfb, ret;
- int sign;
- INTFLOAT scale;
- SingleChannelElement *sce = &che->ch[0];
- ChannelCoupling *coup = &che->coup;
-
- coup->coupling_point = 2 * get_bits1(gb);
- coup->num_coupled = get_bits(gb, 3);
- for (c = 0; c <= coup->num_coupled; c++) {
- num_gain++;
- coup->type[c] = get_bits1(gb) ? TYPE_CPE : TYPE_SCE;
- coup->id_select[c] = get_bits(gb, 4);
- if (coup->type[c] == TYPE_CPE) {
- coup->ch_select[c] = get_bits(gb, 2);
- if (coup->ch_select[c] == 3)
- num_gain++;
- } else
- coup->ch_select[c] = 2;
- }
- coup->coupling_point += get_bits1(gb) || (coup->coupling_point >> 1);
-
- sign = get_bits(gb, 1);
- scale = AAC_RENAME(cce_scale)[get_bits(gb, 2)];
-
- if ((ret = decode_ics(ac, sce, gb, 0, 0)))
- return ret;
-
- for (c = 0; c < num_gain; c++) {
- int idx = 0;
- int cge = 1;
- int gain = 0;
- INTFLOAT gain_cache = FIXR10(1.);
- if (c) {
- cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb);
- gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0;
- gain_cache = GET_GAIN(scale, gain);
- }
- if (coup->coupling_point == AFTER_IMDCT) {
- coup->gain[c][0] = gain_cache;
- } else {
- for (g = 0; g < sce->ics.num_window_groups; g++) {
- for (sfb = 0; sfb < sce->ics.max_sfb; sfb++, idx++) {
- if (sce->band_type[idx] != ZERO_BT) {
- if (!cge) {
- int t = get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60;
- if (t) {
- int s = 1;
- t = gain += t;
- if (sign) {
- s -= 2 * (t & 0x1);
- t >>= 1;
- }
- gain_cache = GET_GAIN(scale, t) * s;
- }
- }
- coup->gain[c][idx] = gain_cache;
- }
- }
- }
- }
- }
- return 0;
-}
-
-/**
- * Parse whether channels are to be excluded from Dynamic Range Compression; reference: table 4.53.
- *
- * @return Returns number of bytes consumed.
- */
-static int decode_drc_channel_exclusions(DynamicRangeControl *che_drc,
- GetBitContext *gb)
-{
- int i;
- int num_excl_chan = 0;
-
- do {
- for (i = 0; i < 7; i++)
- che_drc->exclude_mask[num_excl_chan++] = get_bits1(gb);
- } while (num_excl_chan < MAX_CHANNELS - 7 && get_bits1(gb));
-
- return num_excl_chan / 7;
-}
-
-/**
- * Decode dynamic range information; reference: table 4.52.
- *
- * @return Returns number of bytes consumed.
- */
-static int decode_dynamic_range(DynamicRangeControl *che_drc,
- GetBitContext *gb)
-{
- int n = 1;
- int drc_num_bands = 1;
- int i;
-
- /* pce_tag_present? */
- if (get_bits1(gb)) {
- che_drc->pce_instance_tag = get_bits(gb, 4);
- skip_bits(gb, 4); // tag_reserved_bits
- n++;
- }
-
- /* excluded_chns_present? */
- if (get_bits1(gb)) {
- n += decode_drc_channel_exclusions(che_drc, gb);
- }
-
- /* drc_bands_present? */
- if (get_bits1(gb)) {
- che_drc->band_incr = get_bits(gb, 4);
- che_drc->interpolation_scheme = get_bits(gb, 4);
- n++;
- drc_num_bands += che_drc->band_incr;
- for (i = 0; i < drc_num_bands; i++) {
- che_drc->band_top[i] = get_bits(gb, 8);
- n++;
- }
- }
-
- /* prog_ref_level_present? */
- if (get_bits1(gb)) {
- che_drc->prog_ref_level = get_bits(gb, 7);
- skip_bits1(gb); // prog_ref_level_reserved_bits
- n++;
- }
-
- for (i = 0; i < drc_num_bands; i++) {
- che_drc->dyn_rng_sgn[i] = get_bits1(gb);
- che_drc->dyn_rng_ctl[i] = get_bits(gb, 7);
- n++;
- }
-
- return n;
-}
-
-static int decode_fill(AACContext *ac, GetBitContext *gb, int len) {
- uint8_t buf[256];
- int i, major, minor;
-
- if (len < 13+7*8)
- goto unknown;
-
- get_bits(gb, 13); len -= 13;
-
- for(i=0; i+1<sizeof(buf) && len>=8; i++, len-=8)
- buf[i] = get_bits(gb, 8);
-
- buf[i] = 0;
- if (ac->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(ac->avctx, AV_LOG_DEBUG, "FILL:%s\n", buf);
-
- if (sscanf(buf, "libfaac %d.%d", &major, &minor) == 2){
- ac->avctx->internal->skip_samples = 1024;
- }
-
-unknown:
- skip_bits_long(gb, len);
-
- return 0;
-}
-
-/**
- * Decode extension data (incomplete); reference: table 4.51.
- *
- * @param cnt length of TYPE_FIL syntactic element in bytes
- *
- * @return Returns number of bytes consumed
- */
-static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt,
- ChannelElement *che, enum RawDataBlockType elem_type)
-{
- int crc_flag = 0;
- int res = cnt;
- int type = get_bits(gb, 4);
-
- if (ac->avctx->debug & FF_DEBUG_STARTCODE)
- av_log(ac->avctx, AV_LOG_DEBUG, "extension type: %d len:%d\n", type, cnt);
-
- switch (type) { // extension type
- case EXT_SBR_DATA_CRC:
- crc_flag++;
- case EXT_SBR_DATA:
- if (!che) {
- av_log(ac->avctx, AV_LOG_ERROR, "SBR was found before the first channel element.\n");
- return res;
- } else if (!ac->oc[1].m4ac.sbr) {
- av_log(ac->avctx, AV_LOG_ERROR, "SBR signaled to be not-present but was found in the bitstream.\n");
- skip_bits_long(gb, 8 * cnt - 4);
- return res;
- } else if (ac->oc[1].m4ac.sbr == -1 && ac->oc[1].status == OC_LOCKED) {
- av_log(ac->avctx, AV_LOG_ERROR, "Implicit SBR was found with a first occurrence after the first frame.\n");
- skip_bits_long(gb, 8 * cnt - 4);
- return res;
- } else if (ac->oc[1].m4ac.ps == -1 && ac->oc[1].status < OC_LOCKED && ac->avctx->channels == 1) {
- ac->oc[1].m4ac.sbr = 1;
- ac->oc[1].m4ac.ps = 1;
- ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
- output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags,
- ac->oc[1].status, 1);
- } else {
- ac->oc[1].m4ac.sbr = 1;
- ac->avctx->profile = FF_PROFILE_AAC_HE;
- }
- res = AAC_RENAME(ff_decode_sbr_extension)(ac, &che->sbr, gb, crc_flag, cnt, elem_type);
- break;
- case EXT_DYNAMIC_RANGE:
- res = decode_dynamic_range(&ac->che_drc, gb);
- break;
- case EXT_FILL:
- decode_fill(ac, gb, 8 * cnt - 4);
- break;
- case EXT_FILL_DATA:
- case EXT_DATA_ELEMENT:
- default:
- skip_bits_long(gb, 8 * cnt - 4);
- break;
- };
- return res;
-}
-
-/**
- * Decode Temporal Noise Shaping filter coefficients and apply all-pole filters; reference: 4.6.9.3.
- *
- * @param decode 1 if tool is used normally, 0 if tool is used in LTP.
- * @param coef spectral coefficients
- */
-static void apply_tns(INTFLOAT coef[1024], TemporalNoiseShaping *tns,
- IndividualChannelStream *ics, int decode)
-{
- const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
- int w, filt, m, i;
- int bottom, top, order, start, end, size, inc;
- INTFLOAT lpc[TNS_MAX_ORDER];
- INTFLOAT tmp[TNS_MAX_ORDER+1];
-
- for (w = 0; w < ics->num_windows; w++) {
- bottom = ics->num_swb;
- for (filt = 0; filt < tns->n_filt[w]; filt++) {
- top = bottom;
- bottom = FFMAX(0, top - tns->length[w][filt]);
- order = tns->order[w][filt];
- if (order == 0)
- continue;
-
- // tns_decode_coef
- AAC_RENAME(compute_lpc_coefs)(tns->coef[w][filt], order, lpc, 0, 0, 0);
-
- start = ics->swb_offset[FFMIN(bottom, mmm)];
- end = ics->swb_offset[FFMIN( top, mmm)];
- if ((size = end - start) <= 0)
- continue;
- if (tns->direction[w][filt]) {
- inc = -1;
- start = end - 1;
- } else {
- inc = 1;
- }
- start += w * 128;
-
- if (decode) {
- // ar filter
- for (m = 0; m < size; m++, start += inc)
- for (i = 1; i <= FFMIN(m, order); i++)
- coef[start] -= AAC_MUL26(coef[start - i * inc], lpc[i - 1]);
- } else {
- // ma filter
- for (m = 0; m < size; m++, start += inc) {
- tmp[0] = coef[start];
- for (i = 1; i <= FFMIN(m, order); i++)
- coef[start] += AAC_MUL26(tmp[i], lpc[i - 1]);
- for (i = order; i > 0; i--)
- tmp[i] = tmp[i - 1];
- }
- }
- }
- }
-}
-
-/**
- * Apply windowing and MDCT to obtain the spectral
- * coefficient from the predicted sample by LTP.
- */
-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);
-
- if (ics->window_sequence[0] != LONG_STOP_SEQUENCE) {
- ac->fdsp->vector_fmul(in, in, lwindow_prev, 1024);
- } else {
- memset(in, 0, 448 * sizeof(*in));
- ac->fdsp->vector_fmul(in + 448, in + 448, swindow_prev, 128);
- }
- if (ics->window_sequence[0] != LONG_START_SEQUENCE) {
- ac->fdsp->vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024);
- } else {
- ac->fdsp->vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128);
- memset(in + 1024 + 576, 0, 448 * sizeof(*in));
- }
- ac->mdct_ltp.mdct_calc(&ac->mdct_ltp, out, in);
-}
-
-/**
- * Apply the long term prediction
- */
-static void apply_ltp(AACContext *ac, SingleChannelElement *sce)
-{
- const LongTermPrediction *ltp = &sce->ics.ltp;
- const uint16_t *offsets = sce->ics.swb_offset;
- int i, sfb;
-
- if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
- INTFLOAT *predTime = sce->ret;
- INTFLOAT *predFreq = ac->buf_mdct;
- int16_t num_samples = 2048;
-
- if (ltp->lag < 1024)
- num_samples = ltp->lag + 1024;
- for (i = 0; i < num_samples; i++)
- predTime[i] = AAC_MUL30(sce->ltp_state[i + 2048 - ltp->lag], ltp->coef);
- memset(&predTime[i], 0, (2048 - i) * sizeof(*predTime));
-
- ac->windowing_and_mdct_ltp(ac, predFreq, predTime, &sce->ics);
-
- if (sce->tns.present)
- ac->apply_tns(predFreq, &sce->tns, &sce->ics, 0);
-
- for (sfb = 0; sfb < FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++)
- if (ltp->used[sfb])
- for (i = offsets[sfb]; i < offsets[sfb + 1]; i++)
- sce->coeffs[i] += predFreq[i];
- }
-}
-
-/**
- * Update the LTP buffer for next frame
- */
-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);
- int i;
-
- if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
- memcpy(saved_ltp, saved, 512 * sizeof(*saved_ltp));
- memset(saved_ltp + 576, 0, 448 * sizeof(*saved_ltp));
- ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
-
- for (i = 0; i < 64; i++)
- saved_ltp[i + 512] = AAC_MUL31(ac->buf_mdct[1023 - i], swindow[63 - i]);
- } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
- memcpy(saved_ltp, ac->buf_mdct + 512, 448 * sizeof(*saved_ltp));
- memset(saved_ltp + 576, 0, 448 * sizeof(*saved_ltp));
- ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
-
- for (i = 0; i < 64; i++)
- saved_ltp[i + 512] = AAC_MUL31(ac->buf_mdct[1023 - i], swindow[63 - i]);
- } else { // LONG_STOP or ONLY_LONG
- ac->fdsp->vector_fmul_reverse(saved_ltp, ac->buf_mdct + 512, &lwindow[512], 512);
-
- for (i = 0; i < 512; i++)
- saved_ltp[i + 512] = AAC_MUL31(ac->buf_mdct[1023 - i], lwindow[511 - i]);
- }
-
- memcpy(sce->ltp_state, sce->ltp_state+1024, 1024 * sizeof(*sce->ltp_state));
- memcpy(sce->ltp_state+1024, sce->ret, 1024 * sizeof(*sce->ltp_state));
- memcpy(sce->ltp_state+2048, saved_ltp, 1024 * sizeof(*sce->ltp_state));
-}
-
-/**
- * Conduct IMDCT and windowing.
- */
-static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce)
-{
- IndividualChannelStream *ics = &sce->ics;
- 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);
- INTFLOAT *buf = ac->buf_mdct;
- INTFLOAT *temp = ac->temp;
- int i;
-
- // imdct
- if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
- for (i = 0; i < 1024; i += 128)
- ac->mdct_small.imdct_half(&ac->mdct_small, buf + i, in + i);
- } else {
- ac->mdct.imdct_half(&ac->mdct, buf, in);
-#if USE_FIXED
- for (i=0; i<1024; i++)
- buf[i] = (buf[i] + 4) >> 3;
-#endif /* USE_FIXED */
- }
-
- /* window overlapping
- * NOTE: To simplify the overlapping code, all 'meaningless' short to long
- * and long to short transitions are considered to be short to short
- * transitions. This leaves just two cases (long to long and short to short)
- * with a little special sauce for EIGHT_SHORT_SEQUENCE.
- */
- if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
- (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
- ac->fdsp->vector_fmul_window( out, saved, buf, lwindow_prev, 512);
- } else {
- memcpy( out, saved, 448 * sizeof(*out));
-
- if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
- ac->fdsp->vector_fmul_window(out + 448 + 0*128, saved + 448, buf + 0*128, swindow_prev, 64);
- ac->fdsp->vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow, 64);
- ac->fdsp->vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow, 64);
- ac->fdsp->vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow, 64);
- ac->fdsp->vector_fmul_window(temp, buf + 3*128 + 64, buf + 4*128, swindow, 64);
- memcpy( out + 448 + 4*128, temp, 64 * sizeof(*out));
- } else {
- ac->fdsp->vector_fmul_window(out + 448, saved + 448, buf, swindow_prev, 64);
- memcpy( out + 576, buf + 64, 448 * sizeof(*out));
- }
- }
-
- // buffer update
- if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
- memcpy( saved, temp + 64, 64 * sizeof(*saved));
- ac->fdsp->vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, swindow, 64);
- ac->fdsp->vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
- ac->fdsp->vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
- memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(*saved));
- } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
- memcpy( saved, buf + 512, 448 * sizeof(*saved));
- memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(*saved));
- } else { // LONG_STOP or ONLY_LONG
- memcpy( saved, buf + 512, 512 * sizeof(*saved));
- }
-}
-
-static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce)
-{
- IndividualChannelStream *ics = &sce->ics;
- INTFLOAT *in = sce->coeffs;
- INTFLOAT *out = sce->ret;
- INTFLOAT *saved = sce->saved;
- INTFLOAT *buf = ac->buf_mdct;
-#if USE_FIXED
- int i;
-#endif /* USE_FIXED */
-
- // imdct
- ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
-
-#if USE_FIXED
- for (i = 0; i < 1024; i++)
- buf[i] = (buf[i] + 2) >> 2;
-#endif /* USE_FIXED */
-
- // window overlapping
- 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);
- memcpy( out + 320, buf + 64, 192 * sizeof(*out));
- } else {
- ac->fdsp->vector_fmul_window(out, saved, buf, AAC_RENAME(ff_sine_512), 256);
- }
-
- // buffer update
- memcpy(saved, buf + 256, 256 * sizeof(*saved));
-}
-
-static void imdct_and_windowing_eld(AACContext *ac, SingleChannelElement *sce)
-{
- INTFLOAT *in = sce->coeffs;
- INTFLOAT *out = sce->ret;
- INTFLOAT *saved = sce->saved;
- INTFLOAT *buf = ac->buf_mdct;
- int i;
- const int n = ac->oc[1].m4ac.frame_length_short ? 480 : 512;
- const int n2 = n >> 1;
- const int n4 = n >> 2;
- const INTFLOAT *const window = n == 480 ? AAC_RENAME(ff_aac_eld_window_480) :
- AAC_RENAME(ff_aac_eld_window_512);
-
- // Inverse transform, mapped to the conventional IMDCT by
- // Chivukula, R.K.; Reznik, Y.A.; Devarajan, V.,
- // "Efficient algorithms for MPEG-4 AAC-ELD, AAC-LD and AAC-LC filterbanks,"
- // International Conference on Audio, Language and Image Processing, ICALIP 2008.
- // URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=4590245&isnumber=4589950
- for (i = 0; i < n2; i+=2) {
- INTFLOAT temp;
- temp = in[i ]; in[i ] = -in[n - 1 - i]; in[n - 1 - i] = temp;
- temp = -in[i + 1]; in[i + 1] = in[n - 2 - i]; in[n - 2 - i] = temp;
- }
-#if !USE_FIXED
- if (n == 480)
- ac->mdct480->imdct_half(ac->mdct480, buf, in, 1, -1.f/(16*1024*960));
- else
-#endif
- ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
-
-#if USE_FIXED
- for (i = 0; i < 1024; i++)
- buf[i] = (buf[i] + 1) >> 1;
-#endif /* USE_FIXED */
-
- for (i = 0; i < n; i+=2) {
- buf[i] = -buf[i];
- }
- // Like with the regular IMDCT at this point we still have the middle half
- // of a transform but with even symmetry on the left and odd symmetry on
- // the right
-
- // window overlapping
- // The spec says to use samples [0..511] but the reference decoder uses
- // samples [128..639].
- for (i = n4; i < n2; i ++) {
- out[i - n4] = AAC_MUL31( buf[ n2 - 1 - i] , window[i - n4]) +
- AAC_MUL31( saved[ i + n2] , window[i + n - n4]) +
- AAC_MUL31(-saved[n + n2 - 1 - i] , window[i + 2*n - n4]) +
- AAC_MUL31(-saved[ 2*n + n2 + i] , window[i + 3*n - n4]);
- }
- for (i = 0; i < n2; i ++) {
- out[n4 + i] = AAC_MUL31( buf[ i] , window[i + n2 - n4]) +
- AAC_MUL31(-saved[ n - 1 - i] , window[i + n2 + n - n4]) +
- AAC_MUL31(-saved[ n + i] , window[i + n2 + 2*n - n4]) +
- AAC_MUL31( saved[2*n + n - 1 - i] , window[i + n2 + 3*n - n4]);
- }
- for (i = 0; i < n4; i ++) {
- out[n2 + n4 + i] = AAC_MUL31( buf[ i + n2] , window[i + n - n4]) +
- AAC_MUL31(-saved[n2 - 1 - i] , window[i + 2*n - n4]) +
- AAC_MUL31(-saved[n + n2 + i] , window[i + 3*n - n4]);
- }
-
- // buffer update
- memmove(saved + n, saved, 2 * n * sizeof(*saved));
- memcpy( saved, buf, n * sizeof(*saved));
-}
-
-/**
- * channel coupling transformation interface
- *
- * @param apply_coupling_method pointer to (in)dependent coupling function
- */
-static void apply_channel_coupling(AACContext *ac, ChannelElement *cc,
- enum RawDataBlockType type, int elem_id,
- enum CouplingPoint coupling_point,
- void (*apply_coupling_method)(AACContext *ac, SingleChannelElement *target, ChannelElement *cce, int index))
-{
- int i, c;
-
- for (i = 0; i < MAX_ELEM_ID; i++) {
- ChannelElement *cce = ac->che[TYPE_CCE][i];
- int index = 0;
-
- if (cce && cce->coup.coupling_point == coupling_point) {
- ChannelCoupling *coup = &cce->coup;
-
- for (c = 0; c <= coup->num_coupled; c++) {
- if (coup->type[c] == type && coup->id_select[c] == elem_id) {
- if (coup->ch_select[c] != 1) {
- apply_coupling_method(ac, &cc->ch[0], cce, index);
- if (coup->ch_select[c] != 0)
- index++;
- }
- if (coup->ch_select[c] != 2)
- apply_coupling_method(ac, &cc->ch[1], cce, index++);
- } else
- index += 1 + (coup->ch_select[c] == 3);
- }
- }
- }
-}
-
-/**
- * Convert spectral data to samples, applying all supported tools as appropriate.
- */
-static void spectral_to_sample(AACContext *ac, int samples)
-{
- int i, type;
- void (*imdct_and_window)(AACContext *ac, SingleChannelElement *sce);
- switch (ac->oc[1].m4ac.object_type) {
- case AOT_ER_AAC_LD:
- imdct_and_window = imdct_and_windowing_ld;
- break;
- case AOT_ER_AAC_ELD:
- imdct_and_window = imdct_and_windowing_eld;
- break;
- default:
- imdct_and_window = ac->imdct_and_windowing;
- }
- for (type = 3; type >= 0; type--) {
- for (i = 0; i < MAX_ELEM_ID; i++) {
- ChannelElement *che = ac->che[type][i];
- if (che && che->present) {
- if (type <= TYPE_CPE)
- apply_channel_coupling(ac, che, type, i, BEFORE_TNS, AAC_RENAME(apply_dependent_coupling));
- if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
- if (che->ch[0].ics.predictor_present) {
- if (che->ch[0].ics.ltp.present)
- ac->apply_ltp(ac, &che->ch[0]);
- if (che->ch[1].ics.ltp.present && type == TYPE_CPE)
- ac->apply_ltp(ac, &che->ch[1]);
- }
- }
- if (che->ch[0].tns.present)
- ac->apply_tns(che->ch[0].coeffs, &che->ch[0].tns, &che->ch[0].ics, 1);
- if (che->ch[1].tns.present)
- ac->apply_tns(che->ch[1].coeffs, &che->ch[1].tns, &che->ch[1].ics, 1);
- if (type <= TYPE_CPE)
- apply_channel_coupling(ac, che, type, i, BETWEEN_TNS_AND_IMDCT, AAC_RENAME(apply_dependent_coupling));
- if (type != TYPE_CCE || che->coup.coupling_point == AFTER_IMDCT) {
- imdct_and_window(ac, &che->ch[0]);
- if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP)
- ac->update_ltp(ac, &che->ch[0]);
- if (type == TYPE_CPE) {
- imdct_and_window(ac, &che->ch[1]);
- if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP)
- ac->update_ltp(ac, &che->ch[1]);
- }
- if (ac->oc[1].m4ac.sbr > 0) {
- AAC_RENAME(ff_sbr_apply)(ac, &che->sbr, type, che->ch[0].ret, che->ch[1].ret);
- }
- }
- if (type <= TYPE_CCE)
- apply_channel_coupling(ac, che, type, i, AFTER_IMDCT, AAC_RENAME(apply_independent_coupling));
-
-#if USE_FIXED
- {
- int j;
- /* preparation for resampler */
- for(j = 0; j<samples; j++){
- che->ch[0].ret[j] = (int32_t)av_clipl_int32((int64_t)che->ch[0].ret[j]<<7)+0x8000;
- if(type == TYPE_CPE)
- che->ch[1].ret[j] = (int32_t)av_clipl_int32((int64_t)che->ch[1].ret[j]<<7)+0x8000;
- }
- }
-#endif /* USE_FIXED */
- che->present = 0;
- } else if (che) {
- av_log(ac->avctx, AV_LOG_VERBOSE, "ChannelElement %d.%d missing \n", type, i);
- }
- }
- }
-}
-
-static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb)
-{
- int size;
- AACADTSHeaderInfo hdr_info;
- uint8_t layout_map[MAX_ELEM_ID*4][3];
- int layout_map_tags, ret;
-
- size = avpriv_aac_parse_header(gb, &hdr_info);
- if (size > 0) {
- if (!ac->warned_num_aac_frames && hdr_info.num_aac_frames != 1) {
- // This is 2 for "VLB " audio in NSV files.
- // See samples/nsv/vlb_audio.
- avpriv_report_missing_feature(ac->avctx,
- "More than one AAC RDB per ADTS frame");
- ac->warned_num_aac_frames = 1;
- }
- push_output_configuration(ac);
- if (hdr_info.chan_config) {
- ac->oc[1].m4ac.chan_config = hdr_info.chan_config;
- if ((ret = set_default_channel_config(ac->avctx,
- layout_map,
- &layout_map_tags,
- hdr_info.chan_config)) < 0)
- return ret;
- if ((ret = output_configure(ac, layout_map, layout_map_tags,
- FFMAX(ac->oc[1].status,
- OC_TRIAL_FRAME), 0)) < 0)
- return ret;
- } else {
- ac->oc[1].m4ac.chan_config = 0;
- /**
- * dual mono frames in Japanese DTV can have chan_config 0
- * WITHOUT specifying PCE.
- * thus, set dual mono as default.
- */
- if (ac->dmono_mode && ac->oc[0].status == OC_NONE) {
- layout_map_tags = 2;
- layout_map[0][0] = layout_map[1][0] = TYPE_SCE;
- layout_map[0][2] = layout_map[1][2] = AAC_CHANNEL_FRONT;
- layout_map[0][1] = 0;
- layout_map[1][1] = 1;
- if (output_configure(ac, layout_map, layout_map_tags,
- OC_TRIAL_FRAME, 0))
- return -7;
- }
- }
- ac->oc[1].m4ac.sample_rate = hdr_info.sample_rate;
- ac->oc[1].m4ac.sampling_index = hdr_info.sampling_index;
- ac->oc[1].m4ac.object_type = hdr_info.object_type;
- ac->oc[1].m4ac.frame_length_short = 0;
- if (ac->oc[0].status != OC_LOCKED ||
- ac->oc[0].m4ac.chan_config != hdr_info.chan_config ||
- ac->oc[0].m4ac.sample_rate != hdr_info.sample_rate) {
- ac->oc[1].m4ac.sbr = -1;
- ac->oc[1].m4ac.ps = -1;
- }
- if (!hdr_info.crc_absent)
- skip_bits(gb, 16);
- }
- return size;
-}
-
-static int aac_decode_er_frame(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, GetBitContext *gb)
-{
- AACContext *ac = avctx->priv_data;
- const MPEG4AudioConfig *const m4ac = &ac->oc[1].m4ac;
- ChannelElement *che;
- int err, i;
- int samples = m4ac->frame_length_short ? 960 : 1024;
- int chan_config = m4ac->chan_config;
- int aot = m4ac->object_type;
-
- if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD)
- samples >>= 1;
-
- ac->frame = data;
-
- if ((err = frame_configure_elements(avctx)) < 0)
- return err;
-
- // The FF_PROFILE_AAC_* defines are all object_type - 1
- // This may lead to an undefined profile being signaled
- ac->avctx->profile = aot - 1;
-
- ac->tags_mapped = 0;
-
- if (chan_config < 0 || (chan_config >= 8 && chan_config < 11) || chan_config >= 13) {
- avpriv_request_sample(avctx, "Unknown ER channel configuration %d",
- chan_config);
- return AVERROR_INVALIDDATA;
- }
- for (i = 0; i < tags_per_config[chan_config]; i++) {
- const int elem_type = aac_channel_layout_map[chan_config-1][i][0];
- const int elem_id = aac_channel_layout_map[chan_config-1][i][1];
- if (!(che=get_che(ac, elem_type, elem_id))) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "channel element %d.%d is not allocated\n",
- elem_type, elem_id);
- return AVERROR_INVALIDDATA;
- }
- che->present = 1;
- if (aot != AOT_ER_AAC_ELD)
- skip_bits(gb, 4);
- switch (elem_type) {
- case TYPE_SCE:
- err = decode_ics(ac, &che->ch[0], gb, 0, 0);
- break;
- case TYPE_CPE:
- err = decode_cpe(ac, gb, che);
- break;
- case TYPE_LFE:
- err = decode_ics(ac, &che->ch[0], gb, 0, 0);
- break;
- }
- if (err < 0)
- return err;
- }
-
- spectral_to_sample(ac, samples);
-
- if (!ac->frame->data[0] && samples) {
- av_log(avctx, AV_LOG_ERROR, "no frame data found\n");
- return AVERROR_INVALIDDATA;
- }
-
- ac->frame->nb_samples = samples;
- ac->frame->sample_rate = avctx->sample_rate;
- *got_frame_ptr = 1;
-
- skip_bits_long(gb, get_bits_left(gb));
- return 0;
-}
-
-static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, GetBitContext *gb, AVPacket *avpkt)
-{
- AACContext *ac = avctx->priv_data;
- ChannelElement *che = NULL, *che_prev = NULL;
- enum RawDataBlockType elem_type, elem_type_prev = TYPE_END;
- int err, elem_id;
- int samples = 0, multiplier, audio_found = 0, pce_found = 0;
- int is_dmono, sce_count = 0;
-
- ac->frame = data;
-
- if (show_bits(gb, 12) == 0xfff) {
- if ((err = parse_adts_frame_header(ac, gb)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "Error decoding AAC frame header.\n");
- goto fail;
- }
- if (ac->oc[1].m4ac.sampling_index > 12) {
- av_log(ac->avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->oc[1].m4ac.sampling_index);
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
- }
-
- if ((err = frame_configure_elements(avctx)) < 0)
- goto fail;
-
- // The FF_PROFILE_AAC_* defines are all object_type - 1
- // This may lead to an undefined profile being signaled
- ac->avctx->profile = ac->oc[1].m4ac.object_type - 1;
-
- ac->tags_mapped = 0;
- // parse
- while ((elem_type = get_bits(gb, 3)) != TYPE_END) {
- elem_id = get_bits(gb, 4);
-
- if (avctx->debug & FF_DEBUG_STARTCODE)
- av_log(avctx, AV_LOG_DEBUG, "Elem type:%x id:%x\n", elem_type, elem_id);
-
- if (!avctx->channels && elem_type != TYPE_PCE) {
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
-
- if (elem_type < TYPE_DSE) {
- if (!(che=get_che(ac, elem_type, elem_id))) {
- av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n",
- elem_type, elem_id);
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
- samples = 1024;
- che->present = 1;
- }
-
- switch (elem_type) {
-
- case TYPE_SCE:
- err = decode_ics(ac, &che->ch[0], gb, 0, 0);
- audio_found = 1;
- sce_count++;
- break;
-
- case TYPE_CPE:
- err = decode_cpe(ac, gb, che);
- audio_found = 1;
- break;
-
- case TYPE_CCE:
- err = decode_cce(ac, gb, che);
- break;
-
- case TYPE_LFE:
- err = decode_ics(ac, &che->ch[0], gb, 0, 0);
- audio_found = 1;
- break;
-
- case TYPE_DSE:
- err = skip_data_stream_element(ac, gb);
- break;
-
- case TYPE_PCE: {
- uint8_t layout_map[MAX_ELEM_ID*4][3];
- int tags;
- push_output_configuration(ac);
- tags = decode_pce(avctx, &ac->oc[1].m4ac, layout_map, gb);
- if (tags < 0) {
- err = tags;
- break;
- }
- if (pce_found) {
- av_log(avctx, AV_LOG_ERROR,
- "Not evaluating a further program_config_element as this construct is dubious at best.\n");
- } else {
- err = output_configure(ac, layout_map, tags, OC_TRIAL_PCE, 1);
- if (!err)
- ac->oc[1].m4ac.chan_config = 0;
- pce_found = 1;
- }
- break;
- }
-
- case TYPE_FIL:
- if (elem_id == 15)
- elem_id += get_bits(gb, 8) - 1;
- if (get_bits_left(gb) < 8 * elem_id) {
- av_log(avctx, AV_LOG_ERROR, "TYPE_FIL: "overread_err);
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
- while (elem_id > 0)
- elem_id -= decode_extension_payload(ac, gb, elem_id, che_prev, elem_type_prev);
- err = 0; /* FIXME */
- break;
-
- default:
- err = AVERROR_BUG; /* should not happen, but keeps compiler happy */
- break;
- }
-
- che_prev = che;
- elem_type_prev = elem_type;
-
- if (err)
- goto fail;
-
- if (get_bits_left(gb) < 3) {
- av_log(avctx, AV_LOG_ERROR, overread_err);
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
- }
-
- if (!avctx->channels) {
- *got_frame_ptr = 0;
- return 0;
- }
-
- multiplier = (ac->oc[1].m4ac.sbr == 1) ? ac->oc[1].m4ac.ext_sample_rate > ac->oc[1].m4ac.sample_rate : 0;
- samples <<= multiplier;
-
- spectral_to_sample(ac, samples);
-
- if (ac->oc[1].status && audio_found) {
- avctx->sample_rate = ac->oc[1].m4ac.sample_rate << multiplier;
- avctx->frame_size = samples;
- ac->oc[1].status = OC_LOCKED;
- }
-
- if (multiplier) {
- int side_size;
- const uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
- if (side && side_size>=4)
- AV_WL32(side, 2*AV_RL32(side));
- }
-
- if (!ac->frame->data[0] && samples) {
- av_log(avctx, AV_LOG_ERROR, "no frame data found\n");
- err = AVERROR_INVALIDDATA;
- goto fail;
- }
-
- if (samples) {
- ac->frame->nb_samples = samples;
- ac->frame->sample_rate = avctx->sample_rate;
- } else
- av_frame_unref(ac->frame);
- *got_frame_ptr = !!samples;
-
- /* for dual-mono audio (SCE + SCE) */
- is_dmono = ac->dmono_mode && sce_count == 2 &&
- ac->oc[1].channel_layout == (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT);
- if (is_dmono) {
- if (ac->dmono_mode == 1)
- ((AVFrame *)data)->data[1] =((AVFrame *)data)->data[0];
- else if (ac->dmono_mode == 2)
- ((AVFrame *)data)->data[0] =((AVFrame *)data)->data[1];
- }
-
- return 0;
-fail:
- pop_output_configuration(ac);
- return err;
-}
-
-static int aac_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- AACContext *ac = avctx->priv_data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- GetBitContext gb;
- int buf_consumed;
- int buf_offset;
- int err;
- int 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;
- const uint8_t *jp_dualmono = av_packet_get_side_data(avpkt,
- AV_PKT_DATA_JP_DUALMONO,
- &jp_dualmono_size);
-
- if (new_extradata && 0) {
- av_free(avctx->extradata);
- avctx->extradata = av_mallocz(new_extradata_size +
- AV_INPUT_BUFFER_PADDING_SIZE);
- if (!avctx->extradata)
- return AVERROR(ENOMEM);
- avctx->extradata_size = new_extradata_size;
- memcpy(avctx->extradata, new_extradata, new_extradata_size);
- push_output_configuration(ac);
- if (decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
- avctx->extradata,
- avctx->extradata_size*8LL, 1) < 0) {
- pop_output_configuration(ac);
- return AVERROR_INVALIDDATA;
- }
- }
-
- ac->dmono_mode = 0;
- if (jp_dualmono && jp_dualmono_size > 0)
- ac->dmono_mode = 1 + *jp_dualmono;
- if (ac->force_dmono_mode >= 0)
- ac->dmono_mode = ac->force_dmono_mode;
-
- if (INT_MAX / 8 <= buf_size)
- return AVERROR_INVALIDDATA;
-
- if ((err = init_get_bits8(&gb, buf, buf_size)) < 0)
- return err;
-
- switch (ac->oc[1].m4ac.object_type) {
- case AOT_ER_AAC_LC:
- case AOT_ER_AAC_LTP:
- case AOT_ER_AAC_LD:
- case AOT_ER_AAC_ELD:
- err = aac_decode_er_frame(avctx, data, got_frame_ptr, &gb);
- break;
- default:
- err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb, avpkt);
- }
- if (err < 0)
- return err;
-
- buf_consumed = (get_bits_count(&gb) + 7) >> 3;
- for (buf_offset = buf_consumed; buf_offset < buf_size; buf_offset++)
- if (buf[buf_offset])
- break;
-
- return buf_size > buf_offset ? buf_consumed : buf_size;
-}
-
-static av_cold int aac_decode_close(AVCodecContext *avctx)
-{
- AACContext *ac = avctx->priv_data;
- int i, type;
-
- for (i = 0; i < MAX_ELEM_ID; i++) {
- for (type = 0; type < 4; type++) {
- if (ac->che[type][i])
- AAC_RENAME(ff_aac_sbr_ctx_close)(&ac->che[type][i]->sbr);
- av_freep(&ac->che[type][i]);
- }
- }
-
- ff_mdct_end(&ac->mdct);
- ff_mdct_end(&ac->mdct_small);
- ff_mdct_end(&ac->mdct_ld);
- ff_mdct_end(&ac->mdct_ltp);
-#if !USE_FIXED
- ff_imdct15_uninit(&ac->mdct480);
-#endif
- av_freep(&ac->fdsp);
- return 0;
-}
-
-static void aacdec_init(AACContext *c)
-{
- c->imdct_and_windowing = imdct_and_windowing;
- c->apply_ltp = apply_ltp;
- c->apply_tns = apply_tns;
- c->windowing_and_mdct_ltp = windowing_and_mdct_ltp;
- c->update_ltp = update_ltp;
-#if USE_FIXED
- c->vector_pow43 = vector_pow43;
- c->subband_scale = subband_scale;
-#endif
-
-#if !USE_FIXED
- if(ARCH_MIPS)
- ff_aacdec_init_mips(c);
-#endif /* !USE_FIXED */
-}
-/**
- * AVOptions for Japanese DTV specific extensions (ADTS only)
- */
-#define AACDEC_FLAGS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
-static const AVOption options[] = {
- {"dual_mono_mode", "Select the channel to decode for dual mono",
- offsetof(AACContext, force_dmono_mode), AV_OPT_TYPE_INT, {.i64=-1}, -1, 2,
- AACDEC_FLAGS, "dual_mono_mode"},
-
- {"auto", "autoselection", 0, AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"},
- {"main", "Select Main/Left channel", 0, AV_OPT_TYPE_CONST, {.i64= 1}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"},
- {"sub" , "Select Sub/Right channel", 0, AV_OPT_TYPE_CONST, {.i64= 2}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"},
- {"both", "Select both channels", 0, AV_OPT_TYPE_CONST, {.i64= 0}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"},
-
- {NULL},
-};
-
-static const AVClass aac_decoder_class = {
- .class_name = "AAC decoder",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-static const AVProfile profiles[] = {
- { FF_PROFILE_AAC_MAIN, "Main" },
- { FF_PROFILE_AAC_LOW, "LC" },
- { FF_PROFILE_AAC_SSR, "SSR" },
- { FF_PROFILE_AAC_LTP, "LTP" },
- { FF_PROFILE_AAC_HE, "HE-AAC" },
- { FF_PROFILE_AAC_HE_V2, "HE-AACv2" },
- { FF_PROFILE_AAC_LD, "LD" },
- { FF_PROFILE_AAC_ELD, "ELD" },
- { FF_PROFILE_UNKNOWN },
-};
diff --git a/ffmpeg-2-8-11/libavcodec/aacps.c b/ffmpeg-2-8-11/libavcodec/aacps.c
deleted file mode 100644
index ccc79ff..0000000
--- a/ffmpeg-2-8-11/libavcodec/aacps.c
+++ /dev/null
@@ -1,1049 +0,0 @@
-/*
- * MPEG-4 Parametric Stereo decoding functions
- * Copyright (c) 2010 Alex Converse <alex.converse at gmail.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
- *
- * Note: Rounding-to-nearest used unless otherwise stated
- *
- */
-
-#include <stdint.h>
-#include "libavutil/common.h"
-#include "libavutil/mathematics.h"
-#include "avcodec.h"
-#include "get_bits.h"
-#include "aacps.h"
-#if USE_FIXED
-#include "aacps_fixed_tablegen.h"
-#else
-#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 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 -1; \
-}
-
-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;
- for (i = 0; i < PS_MAX_NR_IPDOPD; i++) {
- opd_hist[i] = 0;
- ipd_hist[i] = 0;
- }
-}
-
-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);
- } 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)
-{
- int i, j;
- for (i = 0; i < len; i++, in++) {
- INT64FLOAT re_in = AAC_MUL31(filter[6], in[6][0]); //real inphase
- INT64FLOAT re_op = 0.0f; //real out of phase
- INT64FLOAT im_in = AAC_MUL31(filter[6], in[6][1]); //imag inphase
- INT64FLOAT im_op = 0.0f; //imag out of phase
- for (j = 0; j < 6; j += 2) {
- re_op += (INT64FLOAT)filter[j+1] * (in[j+1][0] + in[12-j-1][0]);
- im_op += (INT64FLOAT)filter[j+1] * (in[j+1][1] + in[12-j-1][1]);
- }
-
-#if USE_FIXED
- re_op = (re_op + 0x40000000) >> 31;
- im_op = (im_op + 0x40000000) >> 31;
-#endif /* USE_FIXED */
-
- out[ reverse][i][0] = (INTFLOAT)(re_in + re_op);
- out[ reverse][i][1] = (INTFLOAT)(im_in + im_op);
- out[!reverse][i][0] = (INTFLOAT)(re_in - re_op);
- out[!reverse][i][1] = (INTFLOAT)(im_in - im_op);
- }
-}
-
-/** Split one subband into 6 subsubbands with a complex filter */
-static void hybrid6_cx(PSDSPContext *dsp, INTFLOAT (*in)[2], INTFLOAT (*out)[32][2],
- TABLE_CONST INTFLOAT (*filter)[8][2], int len)
-{
- int i;
- int N = 8;
- LOCAL_ALIGNED_16(INTFLOAT, temp, [8], [2]);
-
- for (i = 0; i < len; i++, in++) {
- dsp->hybrid_analysis(temp, in, (const INTFLOAT (*)[8][2]) filter, 1, N);
- out[0][i][0] = temp[6][0];
- out[0][i][1] = temp[6][1];
- out[1][i][0] = temp[7][0];
- out[1][i][1] = temp[7][1];
- out[2][i][0] = temp[0][0];
- out[2][i][1] = temp[0][1];
- out[3][i][0] = temp[1][0];
- out[3][i][1] = temp[1][1];
- out[4][i][0] = temp[2][0] + temp[5][0];
- out[4][i][1] = temp[2][1] + temp[5][1];
- out[5][i][0] = temp[3][0] + temp[4][0];
- out[5][i][1] = temp[3][1] + temp[4][1];
- }
-}
-
-static void hybrid4_8_12_cx(PSDSPContext *dsp,
- INTFLOAT (*in)[2], INTFLOAT (*out)[32][2],
- TABLE_CONST INTFLOAT (*filter)[8][2], int N, int len)
-{
- int i;
-
- for (i = 0; i < len; i++, in++) {
- dsp->hybrid_analysis(out[0] + i, in, (const INTFLOAT (*)[8][2]) filter, 32, N);
- }
-}
-
-static void hybrid_analysis(PSDSPContext *dsp, INTFLOAT out[91][32][2],
- INTFLOAT in[5][44][2], INTFLOAT L[2][38][64],
- int is34, int len)
-{
- int i, j;
- for (i = 0; i < 5; i++) {
- for (j = 0; j < 38; j++) {
- in[i][j+6][0] = L[0][j][i];
- in[i][j+6][1] = L[1][j][i];
- }
- }
- if (is34) {
- hybrid4_8_12_cx(dsp, in[0], out, f34_0_12, 12, len);
- hybrid4_8_12_cx(dsp, in[1], out+12, f34_1_8, 8, len);
- hybrid4_8_12_cx(dsp, in[2], out+20, f34_2_4, 4, len);
- hybrid4_8_12_cx(dsp, in[3], out+24, f34_2_4, 4, len);
- hybrid4_8_12_cx(dsp, in[4], out+28, f34_2_4, 4, len);
- dsp->hybrid_analysis_ileave(out + 27, L, 5, len);
- } else {
- hybrid6_cx(dsp, in[0], out, f20_0_8, len);
- hybrid2_re(in[1], out+6, g1_Q2, len, 1);
- hybrid2_re(in[2], out+8, g1_Q2, len, 0);
- dsp->hybrid_analysis_ileave(out + 7, L, 3, len);
- }
- //update in_buf
- for (i = 0; i < 5; i++) {
- memcpy(in[i], in[i]+32, 6 * sizeof(in[i][0]));
- }
-}
-
-static void hybrid_synthesis(PSDSPContext *dsp, INTFLOAT out[2][38][64],
- INTFLOAT in[91][32][2], int is34, int len)
-{
- int i, n;
- if (is34) {
- for (n = 0; n < len; n++) {
- memset(out[0][n], 0, 5*sizeof(out[0][n][0]));
- memset(out[1][n], 0, 5*sizeof(out[1][n][0]));
- for (i = 0; i < 12; i++) {
- out[0][n][0] += in[ i][n][0];
- out[1][n][0] += in[ i][n][1];
- }
- for (i = 0; i < 8; i++) {
- out[0][n][1] += in[12+i][n][0];
- out[1][n][1] += in[12+i][n][1];
- }
- for (i = 0; i < 4; i++) {
- out[0][n][2] += in[20+i][n][0];
- out[1][n][2] += in[20+i][n][1];
- out[0][n][3] += in[24+i][n][0];
- out[1][n][3] += in[24+i][n][1];
- out[0][n][4] += in[28+i][n][0];
- out[1][n][4] += in[28+i][n][1];
- }
- }
- dsp->hybrid_synthesis_deint(out, in + 27, 5, len);
- } else {
- for (n = 0; n < len; n++) {
- out[0][n][0] = in[0][n][0] + in[1][n][0] + in[2][n][0] +
- in[3][n][0] + in[4][n][0] + in[5][n][0];
- out[1][n][0] = in[0][n][1] + in[1][n][1] + in[2][n][1] +
- in[3][n][1] + in[4][n][1] + in[5][n][1];
- out[0][n][1] = in[6][n][0] + in[7][n][0];
- out[1][n][1] = in[6][n][1] + in[7][n][1];
- out[0][n][2] = in[8][n][0] + in[9][n][0];
- out[1][n][2] = in[8][n][1] + in[9][n][1];
- }
- dsp->hybrid_synthesis_deint(out, in + 7, 3, len);
- }
-}
-
-/// All-pass filter decay slope
-#define DECAY_SLOPE Q30(0.05f)
-/// Number of frequency bands that can be addressed by the parameter index, b(k)
-static const int NR_PAR_BANDS[] = { 20, 34 };
-static const int NR_IPDOPD_BANDS[] = { 11, 17 };
-/// Number of frequency bands that can be addressed by the sub subband index, k
-static const int NR_BANDS[] = { 71, 91 };
-/// Start frequency band for the all-pass filter decay slope
-static const int DECAY_CUTOFF[] = { 10, 32 };
-/// Number of all-pass filer bands
-static const int NR_ALLPASS_BANDS[] = { 30, 50 };
-/// First stereo band using the short one sample delay
-static const int SHORT_DELAY_BAND[] = { 42, 62 };
-
-/** Table 8.46 */
-static void map_idx_10_to_20(int8_t *par_mapped, const int8_t *par, int full)
-{
- int b;
- if (full)
- b = 9;
- else {
- b = 4;
- par_mapped[10] = 0;
- }
- for (; b >= 0; b--) {
- par_mapped[2*b+1] = par_mapped[2*b] = par[b];
- }
-}
-
-static void map_idx_34_to_20(int8_t *par_mapped, const int8_t *par, int full)
-{
- par_mapped[ 0] = (2*par[ 0] + par[ 1]) / 3;
- par_mapped[ 1] = ( par[ 1] + 2*par[ 2]) / 3;
- par_mapped[ 2] = (2*par[ 3] + par[ 4]) / 3;
- par_mapped[ 3] = ( par[ 4] + 2*par[ 5]) / 3;
- par_mapped[ 4] = ( par[ 6] + par[ 7]) / 2;
- par_mapped[ 5] = ( par[ 8] + par[ 9]) / 2;
- par_mapped[ 6] = par[10];
- par_mapped[ 7] = par[11];
- par_mapped[ 8] = ( par[12] + par[13]) / 2;
- par_mapped[ 9] = ( par[14] + par[15]) / 2;
- par_mapped[10] = par[16];
- if (full) {
- par_mapped[11] = par[17];
- par_mapped[12] = par[18];
- par_mapped[13] = par[19];
- par_mapped[14] = ( par[20] + par[21]) / 2;
- par_mapped[15] = ( par[22] + par[23]) / 2;
- par_mapped[16] = ( par[24] + par[25]) / 2;
- par_mapped[17] = ( par[26] + par[27]) / 2;
- par_mapped[18] = ( par[28] + par[29] + par[30] + par[31]) / 4;
- par_mapped[19] = ( par[32] + par[33]) / 2;
- }
-}
-
-static void map_val_34_to_20(INTFLOAT par[PS_MAX_NR_IIDICC])
-{
-#if USE_FIXED
- par[ 0] = (int)(((int64_t)(par[ 0] + (par[ 1]>>1)) * 1431655765 + \
- 0x40000000) >> 31);
- par[ 1] = (int)(((int64_t)((par[ 1]>>1) + par[ 2]) * 1431655765 + \
- 0x40000000) >> 31);
- par[ 2] = (int)(((int64_t)(par[ 3] + (par[ 4]>>1)) * 1431655765 + \
- 0x40000000) >> 31);
- par[ 3] = (int)(((int64_t)((par[ 4]>>1) + par[ 5]) * 1431655765 + \
- 0x40000000) >> 31);
-#else
- par[ 0] = (2*par[ 0] + par[ 1]) * 0.33333333f;
- par[ 1] = ( par[ 1] + 2*par[ 2]) * 0.33333333f;
- par[ 2] = (2*par[ 3] + par[ 4]) * 0.33333333f;
- par[ 3] = ( par[ 4] + 2*par[ 5]) * 0.33333333f;
-#endif /* USE_FIXED */
- par[ 4] = AAC_HALF_SUM(par[ 6], par[ 7]);
- par[ 5] = AAC_HALF_SUM(par[ 8], par[ 9]);
- par[ 6] = par[10];
- par[ 7] = par[11];
- par[ 8] = AAC_HALF_SUM(par[12], par[13]);
- par[ 9] = AAC_HALF_SUM(par[14], par[15]);
- par[10] = par[16];
- par[11] = par[17];
- par[12] = par[18];
- par[13] = par[19];
- par[14] = AAC_HALF_SUM(par[20], par[21]);
- par[15] = AAC_HALF_SUM(par[22], par[23]);
- par[16] = AAC_HALF_SUM(par[24], par[25]);
- par[17] = AAC_HALF_SUM(par[26], par[27]);
-#if USE_FIXED
- par[18] = (((par[28]+2)>>2) + ((par[29]+2)>>2) + ((par[30]+2)>>2) + ((par[31]+2)>>2));
-#else
- par[18] = ( par[28] + par[29] + par[30] + par[31]) * 0.25f;
-#endif /* USE_FIXED */
- par[19] = AAC_HALF_SUM(par[32], par[33]);
-}
-
-static void map_idx_10_to_34(int8_t *par_mapped, const int8_t *par, int full)
-{
- if (full) {
- par_mapped[33] = par[9];
- par_mapped[32] = par[9];
- par_mapped[31] = par[9];
- par_mapped[30] = par[9];
- par_mapped[29] = par[9];
- par_mapped[28] = par[9];
- par_mapped[27] = par[8];
- par_mapped[26] = par[8];
- par_mapped[25] = par[8];
- par_mapped[24] = par[8];
- par_mapped[23] = par[7];
- par_mapped[22] = par[7];
- par_mapped[21] = par[7];
- par_mapped[20] = par[7];
- par_mapped[19] = par[6];
- par_mapped[18] = par[6];
- par_mapped[17] = par[5];
- par_mapped[16] = par[5];
- } else {
- par_mapped[16] = 0;
- }
- par_mapped[15] = par[4];
- par_mapped[14] = par[4];
- par_mapped[13] = par[4];
- par_mapped[12] = par[4];
- par_mapped[11] = par[3];
- par_mapped[10] = par[3];
- par_mapped[ 9] = par[2];
- par_mapped[ 8] = par[2];
- par_mapped[ 7] = par[2];
- par_mapped[ 6] = par[2];
- par_mapped[ 5] = par[1];
- par_mapped[ 4] = par[1];
- par_mapped[ 3] = par[1];
- par_mapped[ 2] = par[0];
- par_mapped[ 1] = par[0];
- par_mapped[ 0] = par[0];
-}
-
-static void map_idx_20_to_34(int8_t *par_mapped, const int8_t *par, int full)
-{
- if (full) {
- par_mapped[33] = par[19];
- par_mapped[32] = par[19];
- par_mapped[31] = par[18];
- par_mapped[30] = par[18];
- par_mapped[29] = par[18];
- par_mapped[28] = par[18];
- par_mapped[27] = par[17];
- par_mapped[26] = par[17];
- par_mapped[25] = par[16];
- par_mapped[24] = par[16];
- par_mapped[23] = par[15];
- par_mapped[22] = par[15];
- par_mapped[21] = par[14];
- par_mapped[20] = par[14];
- par_mapped[19] = par[13];
- par_mapped[18] = par[12];
- par_mapped[17] = par[11];
- }
- par_mapped[16] = par[10];
- par_mapped[15] = par[ 9];
- par_mapped[14] = par[ 9];
- par_mapped[13] = par[ 8];
- par_mapped[12] = par[ 8];
- par_mapped[11] = par[ 7];
- par_mapped[10] = par[ 6];
- par_mapped[ 9] = par[ 5];
- par_mapped[ 8] = par[ 5];
- par_mapped[ 7] = par[ 4];
- par_mapped[ 6] = par[ 4];
- par_mapped[ 5] = par[ 3];
- par_mapped[ 4] = (par[ 2] + par[ 3]) / 2;
- par_mapped[ 3] = par[ 2];
- par_mapped[ 2] = par[ 1];
- par_mapped[ 1] = (par[ 0] + par[ 1]) / 2;
- par_mapped[ 0] = par[ 0];
-}
-
-static void map_val_20_to_34(INTFLOAT par[PS_MAX_NR_IIDICC])
-{
- par[33] = par[19];
- par[32] = par[19];
- par[31] = par[18];
- par[30] = par[18];
- par[29] = par[18];
- par[28] = par[18];
- par[27] = par[17];
- par[26] = par[17];
- par[25] = par[16];
- par[24] = par[16];
- par[23] = par[15];
- par[22] = par[15];
- par[21] = par[14];
- par[20] = par[14];
- par[19] = par[13];
- par[18] = par[12];
- par[17] = par[11];
- par[16] = par[10];
- par[15] = par[ 9];
- par[14] = par[ 9];
- par[13] = par[ 8];
- par[12] = par[ 8];
- par[11] = par[ 7];
- par[10] = par[ 6];
- par[ 9] = par[ 5];
- par[ 8] = par[ 5];
- par[ 7] = par[ 4];
- par[ 6] = par[ 4];
- par[ 5] = par[ 3];
- par[ 4] = AAC_HALF_SUM(par[ 2], par[ 3]);
- par[ 3] = par[ 2];
- par[ 2] = par[ 1];
- par[ 1] = AAC_HALF_SUM(par[ 0], par[ 1]);
-}
-
-static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
-{
- LOCAL_ALIGNED_16(INTFLOAT, power, [34], [PS_QMF_TIME_SLOTS]);
- LOCAL_ALIGNED_16(INTFLOAT, transient_gain, [34], [PS_QMF_TIME_SLOTS]);
- INTFLOAT *peak_decay_nrg = ps->peak_decay_nrg;
- INTFLOAT *power_smooth = ps->power_smooth;
- INTFLOAT *peak_decay_diff_smooth = ps->peak_decay_diff_smooth;
- INTFLOAT (*delay)[PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2] = ps->delay;
- INTFLOAT (*ap_delay)[PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2] = ps->ap_delay;
-#if !USE_FIXED
- 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;
- 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) {
- 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));
- memset(ps->delay, 0, sizeof(ps->delay));
- memset(ps->ap_delay, 0, sizeof(ps->ap_delay));
- }
-
- for (k = 0; k < NR_BANDS[is34]; k++) {
- int i = k_to_i[k];
- ps->dsp.add_squares(power[i], s[k], nL - n0);
- }
-
- //Transient detection
-#if USE_FIXED
- for (i = 0; i < NR_PAR_BANDS[is34]; i++) {
- for (n = n0; n < nL; n++) {
- int decayed_peak;
- int denom;
-
- decayed_peak = (int)(((int64_t)peak_decay_factor * \
- peak_decay_nrg[i] + 0x40000000) >> 31);
- peak_decay_nrg[i] = FFMAX(decayed_peak, power[i][n]);
- power_smooth[i] += (power[i][n] - power_smooth[i] + 2) >> 2;
- peak_decay_diff_smooth[i] += (peak_decay_nrg[i] - power[i][n] - \
- peak_decay_diff_smooth[i] + 2) >> 2;
- denom = peak_decay_diff_smooth[i] + (peak_decay_diff_smooth[i] >> 1);
- if (denom > power_smooth[i]) {
- int p = power_smooth[i];
- while (denom < 0x40000000) {
- denom <<= 1;
- p <<= 1;
- }
- transient_gain[i][n] = p / (denom >> 16);
- }
- else {
- transient_gain[i][n] = 1 << 16;
- }
- }
- }
-#else
- for (i = 0; i < NR_PAR_BANDS[is34]; i++) {
- for (n = n0; n < nL; n++) {
- float decayed_peak = peak_decay_factor * peak_decay_nrg[i];
- float denom;
- peak_decay_nrg[i] = FFMAX(decayed_peak, power[i][n]);
- power_smooth[i] += a_smooth * (power[i][n] - power_smooth[i]);
- peak_decay_diff_smooth[i] += a_smooth * (peak_decay_nrg[i] - power[i][n] - peak_decay_diff_smooth[i]);
- denom = transient_impact * peak_decay_diff_smooth[i];
- transient_gain[i][n] = (denom > power_smooth[i]) ?
- power_smooth[i] / denom : 1.0f;
- }
- }
-
-#endif /* USE_FIXED */
- //Decorrelation and transient reduction
- // PS_AP_LINKS - 1
- // -----
- // | | Q_fract_allpass[k][m]*z^-link_delay[m] - a[m]*g_decay_slope[k]
- //H[k][z] = z^-2 * phi_fract[k] * | | ----------------------------------------------------------------
- // | | 1 - a[m]*g_decay_slope[k]*Q_fract_allpass[k][m]*z^-link_delay[m]
- // m = 0
- //d[k][z] (out) = transient_gain_mapped[k][z] * H[k][z] * s[k][z]
- for (k = 0; k < NR_ALLPASS_BANDS[is34]; k++) {
- int b = k_to_i[k];
-#if USE_FIXED
- int g_decay_slope;
-
- if (k - DECAY_CUTOFF[is34] <= 0) {
- g_decay_slope = 1 << 30;
- }
- else if (k - DECAY_CUTOFF[is34] >= 20) {
- g_decay_slope = 0;
- }
- else {
- g_decay_slope = (1 << 30) - DECAY_SLOPE * (k - DECAY_CUTOFF[is34]);
- }
-#else
- float g_decay_slope = 1.f - DECAY_SLOPE * (k - DECAY_CUTOFF[is34]);
- g_decay_slope = av_clipf(g_decay_slope, 0.f, 1.f);
-#endif /* USE_FIXED */
- memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0]));
- memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0]));
- for (m = 0; m < PS_AP_LINKS; m++) {
- memcpy(ap_delay[k][m], ap_delay[k][m]+numQMFSlots, 5*sizeof(ap_delay[k][m][0]));
- }
- ps->dsp.decorrelate(out[k], delay[k] + PS_MAX_DELAY - 2, ap_delay[k],
- phi_fract[is34][k],
- (const INTFLOAT (*)[2]) Q_fract_allpass[is34][k],
- transient_gain[b], g_decay_slope, nL - n0);
- }
- for (; k < SHORT_DELAY_BAND[is34]; k++) {
- int i = k_to_i[k];
- memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0]));
- memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0]));
- //H = delay 14
- ps->dsp.mul_pair_single(out[k], delay[k] + PS_MAX_DELAY - 14,
- transient_gain[i], nL - n0);
- }
- for (; k < NR_BANDS[is34]; k++) {
- int i = k_to_i[k];
- memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0]));
- memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0]));
- //H = delay 1
- ps->dsp.mul_pair_single(out[k], delay[k] + PS_MAX_DELAY - 1,
- transient_gain[i], nL - n0);
- }
-}
-
-static void remap34(int8_t (**p_par_mapped)[PS_MAX_NR_IIDICC],
- int8_t (*par)[PS_MAX_NR_IIDICC],
- int num_par, int num_env, int full)
-{
- int8_t (*par_mapped)[PS_MAX_NR_IIDICC] = *p_par_mapped;
- int e;
- if (num_par == 20 || num_par == 11) {
- for (e = 0; e < num_env; e++) {
- map_idx_20_to_34(par_mapped[e], par[e], full);
- }
- } else if (num_par == 10 || num_par == 5) {
- for (e = 0; e < num_env; e++) {
- map_idx_10_to_34(par_mapped[e], par[e], full);
- }
- } else {
- *p_par_mapped = par;
- }
-}
-
-static void remap20(int8_t (**p_par_mapped)[PS_MAX_NR_IIDICC],
- int8_t (*par)[PS_MAX_NR_IIDICC],
- int num_par, int num_env, int full)
-{
- int8_t (*par_mapped)[PS_MAX_NR_IIDICC] = *p_par_mapped;
- int e;
- if (num_par == 34 || num_par == 17) {
- for (e = 0; e < num_env; e++) {
- map_idx_34_to_20(par_mapped[e], par[e], full);
- }
- } else if (num_par == 10 || num_par == 5) {
- for (e = 0; e < num_env; e++) {
- map_idx_10_to_20(par_mapped[e], par[e], full);
- }
- } else {
- *p_par_mapped = par;
- }
-}
-
-static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)[32][2], int is34)
-{
- int e, b, k;
-
- 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;
- INTFLOAT (*H22)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H22;
- int8_t *opd_hist = ps->opd_hist;
- int8_t *ipd_hist = ps->ipd_hist;
- int8_t iid_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];
- int8_t icc_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];
- int8_t ipd_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];
- int8_t opd_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];
- int8_t (*iid_mapped)[PS_MAX_NR_IIDICC] = iid_mapped_buf;
- 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;
-
- //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 (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);
- }
- if (!ps->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]);
- map_val_20_to_34(H12[1][0]);
- map_val_20_to_34(H21[0][0]);
- map_val_20_to_34(H21[1][0]);
- map_val_20_to_34(H22[0][0]);
- map_val_20_to_34(H22[1][0]);
- 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);
- }
- if (ps->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]);
- map_val_34_to_20(H12[1][0]);
- map_val_34_to_20(H21[0][0]);
- map_val_34_to_20(H21[1][0]);
- map_val_34_to_20(H22[0][0]);
- map_val_34_to_20(H22[1][0]);
- ipdopd_reset(ipd_hist, opd_hist);
- }
- }
-
- //Mixing
- for (e = 0; e < ps->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];
-
- if (!PS_BASELINE && ps->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;
- INTFLOAT ipd_adj_re, ipd_adj_im;
- int opd_idx = opd_hist[b] * 8 + opd_mapped[e][b];
- int ipd_idx = ipd_hist[b] * 8 + ipd_mapped[e][b];
- INTFLOAT opd_re = pd_re_smooth[opd_idx];
- INTFLOAT opd_im = pd_im_smooth[opd_idx];
- INTFLOAT ipd_re = pd_re_smooth[ipd_idx];
- INTFLOAT ipd_im = pd_im_smooth[ipd_idx];
- opd_hist[b] = opd_idx & 0x3F;
- ipd_hist[b] = ipd_idx & 0x3F;
-
- ipd_adj_re = AAC_MADD30(opd_re, ipd_re, opd_im, ipd_im);
- ipd_adj_im = AAC_MSUB30(opd_im, ipd_re, opd_re, ipd_im);
- h11i = AAC_MUL30(h11, opd_im);
- h11 = AAC_MUL30(h11, opd_re);
- h12i = AAC_MUL30(h12, ipd_adj_im);
- h12 = AAC_MUL30(h12, ipd_adj_re);
- h21i = AAC_MUL30(h21, opd_im);
- h21 = AAC_MUL30(h21, opd_re);
- h22i = AAC_MUL30(h22, ipd_adj_im);
- h22 = AAC_MUL30(h22, ipd_adj_re);
- H11[1][e+1][b] = h11i;
- H12[1][e+1][b] = h12i;
- H21[1][e+1][b] = h21i;
- H22[1][e+1][b] = h22i;
- }
- H11[0][e+1][b] = h11;
- H12[0][e+1][b] = h12;
- H21[0][e+1][b] = h21;
- H22[0][e+1][b] = h22;
- }
- 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];
- INTFLOAT width = Q30(1.f) / ((stop - start) ? (stop - start) : 1);
-#if USE_FIXED
- width <<= 1;
-#endif
- b = k_to_i[k];
- h[0][0] = H11[0][e][b];
- 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) {
- //Is this necessary? ps_04_new seems unchanged
- if ((is34 && k <= 13 && k >= 9) || (!is34 && k <= 1)) {
- h[1][0] = -H11[1][e][b];
- h[1][1] = -H12[1][e][b];
- h[1][2] = -H21[1][e][b];
- h[1][3] = -H22[1][e][b];
- } else {
- h[1][0] = H11[1][e][b];
- h[1][1] = H12[1][e][b];
- h[1][2] = H21[1][e][b];
- h[1][3] = H22[1][e][b];
- }
- }
- //Interpolation
- h_step[0][0] = AAC_MSUB31_V3(H11[0][e+1][b], h[0][0], width);
- 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) {
- 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);
- }
- ps->dsp.stereo_interpolate[!PS_BASELINE && ps->enable_ipdopd](
- l[k] + start + 1, r[k] + start + 1,
- h, h_step, stop - start);
- }
- }
-}
-
-int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top)
-{
- INTFLOAT (*Lbuf)[32][2] = ps->Lbuf;
- INTFLOAT (*Rbuf)[32][2] = ps->Rbuf;
- const int len = 32;
- int is34 = ps->is34bands;
-
- top += NR_BANDS[is34] - 64;
- memset(ps->delay+top, 0, (NR_BANDS[is34] - top)*sizeof(ps->delay[0]));
- if (top < NR_ALLPASS_BANDS[is34])
- memset(ps->ap_delay + top, 0, (NR_ALLPASS_BANDS[is34] - top)*sizeof(ps->ap_delay[0]));
-
- hybrid_analysis(&ps->dsp, Lbuf, ps->in_buf, L, is34, len);
- decorrelation(ps, Rbuf, (const INTFLOAT (*)[32][2]) Lbuf, is34);
- stereo_processing(ps, Lbuf, Rbuf, is34);
- hybrid_synthesis(&ps->dsp, L, Lbuf, is34, len);
- hybrid_synthesis(&ps->dsp, R, Rbuf, is34, len);
-
- 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();
-}
-
-av_cold void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps)
-{
- AAC_RENAME(ff_psdsp_init)(&ps->dsp);
-}
diff --git a/ffmpeg-2-8-11/libavcodec/aacsbr_fixed.c b/ffmpeg-2-8-11/libavcodec/aacsbr_fixed.c
deleted file mode 100644
index b4e3ac7..0000000
--- a/ffmpeg-2-8-11/libavcodec/aacsbr_fixed.c
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
- * Copyright (c) 2013
- * MIPS Technologies, Inc., California.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * AAC Spectral Band Replication decoding functions (fixed-point)
- * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
- * Copyright (c) 2009-2010 Alex Converse <alex.converse at gmail.com>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * AAC Spectral Band Replication decoding functions (fixed-point)
- * Note: Rounding-to-nearest used unless otherwise stated
- * @author Robert Swain ( rob opendot cl )
- * @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com )
- */
-#define USE_FIXED 1
-
-#include "aac.h"
-#include "sbr.h"
-#include "aacsbr.h"
-#include "aacsbrdata.h"
-#include "aacsbr_fixed_tablegen.h"
-#include "fft.h"
-#include "aacps.h"
-#include "sbrdsp.h"
-#include "libavutil/internal.h"
-#include "libavutil/libm.h"
-#include "libavutil/avassert.h"
-
-#include <stdint.h>
-#include <float.h>
-#include <math.h>
-
-static VLC vlc_sbr[10];
-static void aacsbr_func_ptr_init(AACSBRContext *c);
-static const int CONST_LN2 = Q31(0.6931471806/256); // ln(2)/256
-static const int CONST_RECIP_LN2 = Q31(0.7213475204); // 0.5/ln(2)
-static const int CONST_076923 = Q31(0.76923076923076923077f);
-
-static const int fixed_log_table[10] =
-{
- Q31(1.0/2), Q31(1.0/3), Q31(1.0/4), Q31(1.0/5), Q31(1.0/6),
- Q31(1.0/7), Q31(1.0/8), Q31(1.0/9), Q31(1.0/10), Q31(1.0/11)
-};
-
-static int fixed_log(int x)
-{
- int i, ret, xpow, tmp;
-
- ret = x;
- xpow = x;
- for (i=0; i<10; i+=2){
- xpow = (int)(((int64_t)xpow * x + 0x40000000) >> 31);
- tmp = (int)(((int64_t)xpow * fixed_log_table[i] + 0x40000000) >> 31);
- ret -= tmp;
-
- xpow = (int)(((int64_t)xpow * x + 0x40000000) >> 31);
- tmp = (int)(((int64_t)xpow * fixed_log_table[i+1] + 0x40000000) >> 31);
- ret += tmp;
- }
-
- return ret;
-}
-
-static const int fixed_exp_table[7] =
-{
- Q31(1.0/2), Q31(1.0/6), Q31(1.0/24), Q31(1.0/120),
- Q31(1.0/720), Q31(1.0/5040), Q31(1.0/40320)
-};
-
-static int fixed_exp(int x)
-{
- int i, ret, xpow, tmp;
-
- ret = 0x800000 + x;
- xpow = x;
- for (i=0; i<7; i++){
- xpow = (int)(((int64_t)xpow * x + 0x400000) >> 23);
- tmp = (int)(((int64_t)xpow * fixed_exp_table[i] + 0x40000000) >> 31);
- ret += tmp;
- }
-
- return ret;
-}
-
-static void make_bands(int16_t* bands, int start, int stop, int num_bands)
-{
- int k, previous, present;
- int base, prod, nz = 0;
-
- base = (stop << 23) / start;
- while (base < 0x40000000){
- base <<= 1;
- nz++;
- }
- base = fixed_log(base - 0x80000000);
- base = (((base + 0x80) >> 8) + (8-nz)*CONST_LN2) / num_bands;
- base = fixed_exp(base);
-
- previous = start;
- prod = start << 23;
-
- for (k = 0; k < num_bands-1; k++) {
- prod = (int)(((int64_t)prod * base + 0x400000) >> 23);
- present = (prod + 0x400000) >> 23;
- bands[k] = present - previous;
- previous = present;
- }
- bands[num_bands-1] = stop - previous;
-}
-
-/// Dequantization and stereo decoding (14496-3 sp04 p203)
-static void sbr_dequant(SpectralBandReplication *sbr, int id_aac)
-{
- int k, e;
- int ch;
-
- if (id_aac == TYPE_CPE && sbr->bs_coupling) {
- int alpha = sbr->data[0].bs_amp_res ? 2 : 1;
- int pan_offset = sbr->data[0].bs_amp_res ? 12 : 24;
- for (e = 1; e <= sbr->data[0].bs_num_env; e++) {
- for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) {
- SoftFloat temp1, temp2, fac;
-
- temp1.exp = sbr->data[0].env_facs[e][k].mant * alpha + 14;
- if (temp1.exp & 1)
- temp1.mant = 759250125;
- else
- temp1.mant = 0x20000000;
- temp1.exp = (temp1.exp >> 1) + 1;
- if (temp1.exp > 66) { // temp1 > 1E20
- av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n");
- temp1 = FLOAT_1;
- }
-
- temp2.exp = (pan_offset - sbr->data[1].env_facs[e][k].mant) * alpha;
- if (temp2.exp & 1)
- temp2.mant = 759250125;
- else
- temp2.mant = 0x20000000;
- temp2.exp = (temp2.exp >> 1) + 1;
- fac = av_div_sf(temp1, av_add_sf(FLOAT_1, temp2));
- sbr->data[0].env_facs[e][k] = fac;
- sbr->data[1].env_facs[e][k] = av_mul_sf(fac, temp2);
- }
- }
- for (e = 1; e <= sbr->data[0].bs_num_noise; e++) {
- for (k = 0; k < sbr->n_q; k++) {
- SoftFloat temp1, temp2, fac;
-
- temp1.exp = NOISE_FLOOR_OFFSET - \
- sbr->data[0].noise_facs[e][k].mant + 2;
- temp1.mant = 0x20000000;
- if (temp1.exp > 66) { // temp1 > 1E20
- av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n");
- temp1 = FLOAT_1;
- }
- temp2.exp = 12 - sbr->data[1].noise_facs[e][k].mant + 1;
- temp2.mant = 0x20000000;
- fac = av_div_sf(temp1, av_add_sf(FLOAT_1, temp2));
- sbr->data[0].noise_facs[e][k] = fac;
- sbr->data[1].noise_facs[e][k] = av_mul_sf(fac, temp2);
- }
- }
- } else { // SCE or one non-coupled CPE
- for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) {
- int alpha = sbr->data[ch].bs_amp_res ? 2 : 1;
- for (e = 1; e <= sbr->data[ch].bs_num_env; e++)
- for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++){
- SoftFloat temp1;
-
- temp1.exp = alpha * sbr->data[ch].env_facs[e][k].mant + 12;
- if (temp1.exp & 1)
- temp1.mant = 759250125;
- else
- temp1.mant = 0x20000000;
- temp1.exp = (temp1.exp >> 1) + 1;
- if (temp1.exp > 66) { // temp1 > 1E20
- av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n");
- temp1 = FLOAT_1;
- }
- sbr->data[ch].env_facs[e][k] = temp1;
- }
- for (e = 1; e <= sbr->data[ch].bs_num_noise; e++)
- for (k = 0; k < sbr->n_q; k++){
- sbr->data[ch].noise_facs[e][k].exp = NOISE_FLOOR_OFFSET - \
- sbr->data[ch].noise_facs[e][k].mant + 1;
- sbr->data[ch].noise_facs[e][k].mant = 0x20000000;
- }
- }
- }
-}
-
-/** High Frequency Generation (14496-3 sp04 p214+) and Inverse Filtering
- * (14496-3 sp04 p214)
- * Warning: This routine does not seem numerically stable.
- */
-static void sbr_hf_inverse_filter(SBRDSPContext *dsp,
- int (*alpha0)[2], int (*alpha1)[2],
- const int X_low[32][40][2], int k0)
-{
- int k;
- int shift, round;
-
- for (k = 0; k < k0; k++) {
- SoftFloat phi[3][2][2];
- SoftFloat a00, a01, a10, a11;
- SoftFloat dk;
-
- dsp->autocorrelate(X_low[k], phi);
-
- dk = av_sub_sf(av_mul_sf(phi[2][1][0], phi[1][0][0]),
- av_mul_sf(av_add_sf(av_mul_sf(phi[1][1][0], phi[1][1][0]),
- av_mul_sf(phi[1][1][1], phi[1][1][1])), FLOAT_0999999));
-
- if (!dk.mant) {
- a10 = FLOAT_0;
- a11 = FLOAT_0;
- } else {
- SoftFloat temp_real, temp_im;
- temp_real = av_sub_sf(av_sub_sf(av_mul_sf(phi[0][0][0], phi[1][1][0]),
- av_mul_sf(phi[0][0][1], phi[1][1][1])),
- av_mul_sf(phi[0][1][0], phi[1][0][0]));
- temp_im = av_sub_sf(av_add_sf(av_mul_sf(phi[0][0][0], phi[1][1][1]),
- av_mul_sf(phi[0][0][1], phi[1][1][0])),
- av_mul_sf(phi[0][1][1], phi[1][0][0]));
-
- a10 = av_div_sf(temp_real, dk);
- a11 = av_div_sf(temp_im, dk);
- }
-
- if (!phi[1][0][0].mant) {
- a00 = FLOAT_0;
- a01 = FLOAT_0;
- } else {
- SoftFloat temp_real, temp_im;
- temp_real = av_add_sf(phi[0][0][0],
- av_add_sf(av_mul_sf(a10, phi[1][1][0]),
- av_mul_sf(a11, phi[1][1][1])));
- temp_im = av_add_sf(phi[0][0][1],
- av_sub_sf(av_mul_sf(a11, phi[1][1][0]),
- av_mul_sf(a10, phi[1][1][1])));
-
- temp_real.mant = -temp_real.mant;
- temp_im.mant = -temp_im.mant;
- a00 = av_div_sf(temp_real, phi[1][0][0]);
- a01 = av_div_sf(temp_im, phi[1][0][0]);
- }
-
- shift = a00.exp;
- if (shift >= 3)
- alpha0[k][0] = 0x7fffffff;
- else {
- a00.mant <<= 1;
- shift = 2-shift;
- if (shift == 0)
- alpha0[k][0] = a00.mant;
- else {
- round = 1 << (shift-1);
- alpha0[k][0] = (a00.mant + round) >> shift;
- }
- }
-
- shift = a01.exp;
- if (shift >= 3)
- alpha0[k][1] = 0x7fffffff;
- else {
- a01.mant <<= 1;
- shift = 2-shift;
- if (shift == 0)
- alpha0[k][1] = a01.mant;
- else {
- round = 1 << (shift-1);
- alpha0[k][1] = (a01.mant + round) >> shift;
- }
- }
- shift = a10.exp;
- if (shift >= 3)
- alpha1[k][0] = 0x7fffffff;
- else {
- a10.mant <<= 1;
- shift = 2-shift;
- if (shift == 0)
- alpha1[k][0] = a10.mant;
- else {
- round = 1 << (shift-1);
- alpha1[k][0] = (a10.mant + round) >> shift;
- }
- }
-
- shift = a11.exp;
- if (shift >= 3)
- alpha1[k][1] = 0x7fffffff;
- else {
- a11.mant <<= 1;
- shift = 2-shift;
- if (shift == 0)
- alpha1[k][1] = a11.mant;
- else {
- round = 1 << (shift-1);
- alpha1[k][1] = (a11.mant + round) >> shift;
- }
- }
-
- shift = (int)(((int64_t)(alpha1[k][0]>>1) * (alpha1[k][0]>>1) + \
- (int64_t)(alpha1[k][1]>>1) * (alpha1[k][1]>>1) + \
- 0x40000000) >> 31);
- if (shift >= 0x20000000){
- alpha1[k][0] = 0;
- alpha1[k][1] = 0;
- alpha0[k][0] = 0;
- alpha0[k][1] = 0;
- }
-
- shift = (int)(((int64_t)(alpha0[k][0]>>1) * (alpha0[k][0]>>1) + \
- (int64_t)(alpha0[k][1]>>1) * (alpha0[k][1]>>1) + \
- 0x40000000) >> 31);
- if (shift >= 0x20000000){
- alpha1[k][0] = 0;
- alpha1[k][1] = 0;
- alpha0[k][0] = 0;
- alpha0[k][1] = 0;
- }
- }
-}
-
-/// Chirp Factors (14496-3 sp04 p214)
-static void sbr_chirp(SpectralBandReplication *sbr, SBRData *ch_data)
-{
- int i;
- int new_bw;
- static const int bw_tab[] = { 0, 1610612736, 1932735283, 2104533975 };
- int64_t accu;
-
- for (i = 0; i < sbr->n_q; i++) {
- if (ch_data->bs_invf_mode[0][i] + ch_data->bs_invf_mode[1][i] == 1)
- new_bw = 1288490189;
- else
- new_bw = bw_tab[ch_data->bs_invf_mode[0][i]];
-
- if (new_bw < ch_data->bw_array[i]){
- accu = (int64_t)new_bw * 1610612736;
- accu += (int64_t)ch_data->bw_array[i] * 0x20000000;
- new_bw = (int)((accu + 0x40000000) >> 31);
- } else {
- accu = (int64_t)new_bw * 1946157056;
- accu += (int64_t)ch_data->bw_array[i] * 201326592;
- new_bw = (int)((accu + 0x40000000) >> 31);
- }
- ch_data->bw_array[i] = new_bw < 0x2000000 ? 0 : new_bw;
- }
-}
-
-/**
- * Calculation of levels of additional HF signal components (14496-3 sp04 p219)
- * and Calculation of gain (14496-3 sp04 p219)
- */
-static void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr,
- SBRData *ch_data, const int e_a[2])
-{
- int e, k, m;
- // max gain limits : -3dB, 0dB, 3dB, inf dB (limiter off)
- static const SoftFloat limgain[4] = { { 760155524, 0 }, { 0x20000000, 1 },
- { 758351638, 1 }, { 625000000, 34 } };
-
- for (e = 0; e < ch_data->bs_num_env; e++) {
- int delta = !((e == e_a[1]) || (e == e_a[0]));
- for (k = 0; k < sbr->n_lim; k++) {
- SoftFloat gain_boost, gain_max;
- SoftFloat sum[2];
- sum[0] = sum[1] = FLOAT_0;
- for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
- const SoftFloat temp = av_div_sf(sbr->e_origmapped[e][m],
- av_add_sf(FLOAT_1, sbr->q_mapped[e][m]));
- sbr->q_m[e][m] = av_sqrt_sf(av_mul_sf(temp, sbr->q_mapped[e][m]));
- sbr->s_m[e][m] = av_sqrt_sf(av_mul_sf(temp, av_int2sf(ch_data->s_indexmapped[e + 1][m], 0)));
- if (!sbr->s_mapped[e][m]) {
- if (delta) {
- sbr->gain[e][m] = av_sqrt_sf(av_div_sf(sbr->e_origmapped[e][m],
- av_mul_sf(av_add_sf(FLOAT_1, sbr->e_curr[e][m]),
- av_add_sf(FLOAT_1, sbr->q_mapped[e][m]))));
- } else {
- sbr->gain[e][m] = av_sqrt_sf(av_div_sf(sbr->e_origmapped[e][m],
- av_add_sf(FLOAT_1, sbr->e_curr[e][m])));
- }
- } else {
- sbr->gain[e][m] = av_sqrt_sf(
- av_div_sf(
- av_mul_sf(sbr->e_origmapped[e][m], sbr->q_mapped[e][m]),
- av_mul_sf(
- av_add_sf(FLOAT_1, sbr->e_curr[e][m]),
- av_add_sf(FLOAT_1, sbr->q_mapped[e][m]))));
- }
- }
- for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
- sum[0] = av_add_sf(sum[0], sbr->e_origmapped[e][m]);
- sum[1] = av_add_sf(sum[1], sbr->e_curr[e][m]);
- }
- gain_max = av_mul_sf(limgain[sbr->bs_limiter_gains],
- av_sqrt_sf(
- av_div_sf(
- av_add_sf(FLOAT_EPSILON, sum[0]),
- av_add_sf(FLOAT_EPSILON, sum[1]))));
- if (av_gt_sf(gain_max, FLOAT_100000))
- gain_max = FLOAT_100000;
- for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
- SoftFloat q_m_max = av_div_sf(
- av_mul_sf(sbr->q_m[e][m], gain_max),
- sbr->gain[e][m]);
- if (av_gt_sf(sbr->q_m[e][m], q_m_max))
- sbr->q_m[e][m] = q_m_max;
- if (av_gt_sf(sbr->gain[e][m], gain_max))
- sbr->gain[e][m] = gain_max;
- }
- sum[0] = sum[1] = FLOAT_0;
- for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
- sum[0] = av_add_sf(sum[0], sbr->e_origmapped[e][m]);
- sum[1] = av_add_sf(sum[1],
- av_mul_sf(
- av_mul_sf(sbr->e_curr[e][m],
- sbr->gain[e][m]),
- sbr->gain[e][m]));
- sum[1] = av_add_sf(sum[1],
- av_mul_sf(sbr->s_m[e][m], sbr->s_m[e][m]));
- if (delta && !sbr->s_m[e][m].mant)
- sum[1] = av_add_sf(sum[1],
- av_mul_sf(sbr->q_m[e][m], sbr->q_m[e][m]));
- }
- gain_boost = av_sqrt_sf(
- av_div_sf(
- av_add_sf(FLOAT_EPSILON, sum[0]),
- av_add_sf(FLOAT_EPSILON, sum[1])));
- if (av_gt_sf(gain_boost, FLOAT_1584893192))
- gain_boost = FLOAT_1584893192;
-
- for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
- sbr->gain[e][m] = av_mul_sf(sbr->gain[e][m], gain_boost);
- sbr->q_m[e][m] = av_mul_sf(sbr->q_m[e][m], gain_boost);
- sbr->s_m[e][m] = av_mul_sf(sbr->s_m[e][m], gain_boost);
- }
- }
- }
-}
-
-/// Assembling HF Signals (14496-3 sp04 p220)
-static void sbr_hf_assemble(int Y1[38][64][2],
- const int X_high[64][40][2],
- SpectralBandReplication *sbr, SBRData *ch_data,
- const int e_a[2])
-{
- int e, i, j, m;
- const int h_SL = 4 * !sbr->bs_smoothing_mode;
- const int kx = sbr->kx[1];
- const int m_max = sbr->m[1];
- static const SoftFloat h_smooth[5] = {
- { 715827883, -1 },
- { 647472402, -1 },
- { 937030863, -2 },
- { 989249804, -3 },
- { 546843842, -4 },
- };
- SoftFloat (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp;
- int indexnoise = ch_data->f_indexnoise;
- int indexsine = ch_data->f_indexsine;
-
- if (sbr->reset) {
- for (i = 0; i < h_SL; i++) {
- memcpy(g_temp[i + 2*ch_data->t_env[0]], sbr->gain[0], m_max * sizeof(sbr->gain[0][0]));
- memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0], m_max * sizeof(sbr->q_m[0][0]));
- }
- } else if (h_SL) {
- for (i = 0; i < 4; i++) {
- memcpy(g_temp[i + 2 * ch_data->t_env[0]],
- g_temp[i + 2 * ch_data->t_env_num_env_old],
- sizeof(g_temp[0]));
- memcpy(q_temp[i + 2 * ch_data->t_env[0]],
- q_temp[i + 2 * ch_data->t_env_num_env_old],
- sizeof(q_temp[0]));
- }
- }
-
- for (e = 0; e < ch_data->bs_num_env; e++) {
- for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) {
- memcpy(g_temp[h_SL + i], sbr->gain[e], m_max * sizeof(sbr->gain[0][0]));
- memcpy(q_temp[h_SL + i], sbr->q_m[e], m_max * sizeof(sbr->q_m[0][0]));
- }
- }
-
- for (e = 0; e < ch_data->bs_num_env; e++) {
- for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) {
- SoftFloat g_filt_tab[48];
- SoftFloat q_filt_tab[48];
- SoftFloat *g_filt, *q_filt;
-
- if (h_SL && e != e_a[0] && e != e_a[1]) {
- g_filt = g_filt_tab;
- q_filt = q_filt_tab;
- for (m = 0; m < m_max; m++) {
- const int idx1 = i + h_SL;
- g_filt[m].mant = g_filt[m].exp = 0;
- q_filt[m].mant = q_filt[m].exp = 0;
- for (j = 0; j <= h_SL; j++) {
- g_filt[m] = av_add_sf(g_filt[m],
- av_mul_sf(g_temp[idx1 - j][m],
- h_smooth[j]));
- q_filt[m] = av_add_sf(q_filt[m],
- av_mul_sf(q_temp[idx1 - j][m],
- h_smooth[j]));
- }
- }
- } else {
- g_filt = g_temp[i + h_SL];
- q_filt = q_temp[i];
- }
-
- sbr->dsp.hf_g_filt(Y1[i] + kx, X_high + kx, g_filt, m_max,
- i + ENVELOPE_ADJUSTMENT_OFFSET);
-
- if (e != e_a[0] && e != e_a[1]) {
- sbr->dsp.hf_apply_noise[indexsine](Y1[i] + kx, sbr->s_m[e],
- q_filt, indexnoise,
- kx, m_max);
- } else {
- int idx = indexsine&1;
- int A = (1-((indexsine+(kx & 1))&2));
- int B = (A^(-idx)) + idx;
- int *out = &Y1[i][kx][idx];
- int shift, round;
-
- SoftFloat *in = sbr->s_m[e];
- for (m = 0; m+1 < m_max; m+=2) {
- shift = 22 - in[m ].exp;
- round = 1 << (shift-1);
- out[2*m ] += (in[m ].mant * A + round) >> shift;
-
- shift = 22 - in[m+1].exp;
- round = 1 << (shift-1);
- out[2*m+2] += (in[m+1].mant * B + round) >> shift;
- }
- if(m_max&1)
- {
- shift = 22 - in[m ].exp;
- round = 1 << (shift-1);
-
- out[2*m ] += (in[m ].mant * A + round) >> shift;
- }
- }
- indexnoise = (indexnoise + m_max) & 0x1ff;
- indexsine = (indexsine + 1) & 3;
- }
- }
- ch_data->f_indexnoise = indexnoise;
- ch_data->f_indexsine = indexsine;
-}
-
-#include "aacsbr_template.c"
diff --git a/ffmpeg-2-8-11/libavcodec/aacsbr_template.c b/ffmpeg-2-8-11/libavcodec/aacsbr_template.c
deleted file mode 100644
index b36c266..0000000
--- a/ffmpeg-2-8-11/libavcodec/aacsbr_template.c
+++ /dev/null
@@ -1,1563 +0,0 @@
-/*
- * AAC Spectral Band Replication decoding functions
- * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
- * Copyright (c) 2009-2010 Alex Converse <alex.converse at gmail.com>
- *
- * Fixed point code
- * Copyright (c) 2013
- * MIPS Technologies, Inc., California.
- *
- * 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
- * AAC Spectral Band Replication decoding functions
- * @author Robert Swain ( rob opendot cl )
- * @author Stanislav Ocovaj ( stanislav.ocovaj at imgtec.com )
- * @author Zoran Basaric ( zoran.basaric at imgtec.com )
- */
-
-av_cold void AAC_RENAME(ff_aac_sbr_init)(void)
-{
- static const struct {
- const void *sbr_codes, *sbr_bits;
- const unsigned int table_size, elem_size;
- } sbr_tmp[] = {
- SBR_VLC_ROW(t_huffman_env_1_5dB),
- SBR_VLC_ROW(f_huffman_env_1_5dB),
- SBR_VLC_ROW(t_huffman_env_bal_1_5dB),
- SBR_VLC_ROW(f_huffman_env_bal_1_5dB),
- SBR_VLC_ROW(t_huffman_env_3_0dB),
- SBR_VLC_ROW(f_huffman_env_3_0dB),
- SBR_VLC_ROW(t_huffman_env_bal_3_0dB),
- SBR_VLC_ROW(f_huffman_env_bal_3_0dB),
- SBR_VLC_ROW(t_huffman_noise_3_0dB),
- SBR_VLC_ROW(t_huffman_noise_bal_3_0dB),
- };
-
- // SBR VLC table initialization
- SBR_INIT_VLC_STATIC(0, 1098);
- SBR_INIT_VLC_STATIC(1, 1092);
- SBR_INIT_VLC_STATIC(2, 768);
- SBR_INIT_VLC_STATIC(3, 1026);
- SBR_INIT_VLC_STATIC(4, 1058);
- SBR_INIT_VLC_STATIC(5, 1052);
- SBR_INIT_VLC_STATIC(6, 544);
- SBR_INIT_VLC_STATIC(7, 544);
- SBR_INIT_VLC_STATIC(8, 592);
- SBR_INIT_VLC_STATIC(9, 512);
-
- aacsbr_tableinit();
-
- AAC_RENAME(ff_ps_init)();
-}
-
-/** Places SBR in pure upsampling mode. */
-static void sbr_turnoff(SpectralBandReplication *sbr) {
- sbr->start = 0;
- sbr->ready_for_dequant = 0;
- // Init defults used in pure upsampling mode
- sbr->kx[1] = 32; //Typo in spec, kx' inits to 32
- sbr->m[1] = 0;
- // Reset values for first SBR header
- sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1;
- memset(&sbr->spectrum_params, -1, sizeof(SpectrumParameters));
-}
-
-av_cold void AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr)
-{
- if(sbr->mdct.mdct_bits)
- return;
- sbr->kx[0] = sbr->kx[1];
- sbr_turnoff(sbr);
- sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128);
- sbr->data[1].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128);
- /* SBR requires samples to be scaled to +/-32768.0 to work correctly.
- * mdct scale factors are adjusted to scale up from +/-1.0 at analysis
- * and scale back down at synthesis. */
- AAC_RENAME_32(ff_mdct_init)(&sbr->mdct, 7, 1, 1.0 / (64 * 32768.0));
- AAC_RENAME_32(ff_mdct_init)(&sbr->mdct_ana, 7, 1, -2.0 * 32768.0);
- AAC_RENAME(ff_ps_ctx_init)(&sbr->ps);
- AAC_RENAME(ff_sbrdsp_init)(&sbr->dsp);
- aacsbr_func_ptr_init(&sbr->c);
-}
-
-av_cold void AAC_RENAME(ff_aac_sbr_ctx_close)(SpectralBandReplication *sbr)
-{
- AAC_RENAME_32(ff_mdct_end)(&sbr->mdct);
- AAC_RENAME_32(ff_mdct_end)(&sbr->mdct_ana);
-}
-
-static int qsort_comparison_function_int16(const void *a, const void *b)
-{
- return *(const int16_t *)a - *(const int16_t *)b;
-}
-
-static inline int in_table_int16(const int16_t *table, int last_el, int16_t needle)
-{
- int i;
- for (i = 0; i <= last_el; i++)
- if (table[i] == needle)
- return 1;
- return 0;
-}
-
-/// Limiter Frequency Band Table (14496-3 sp04 p198)
-static void sbr_make_f_tablelim(SpectralBandReplication *sbr)
-{
- int k;
- if (sbr->bs_limiter_bands > 0) {
- static const INTFLOAT bands_warped[3] = { Q23(1.32715174233856803909f), //2^(0.49/1.2)
- Q23(1.18509277094158210129f), //2^(0.49/2)
- Q23(1.11987160404675912501f) }; //2^(0.49/3)
- const INTFLOAT lim_bands_per_octave_warped = bands_warped[sbr->bs_limiter_bands - 1];
- int16_t patch_borders[7];
- uint16_t *in = sbr->f_tablelim + 1, *out = sbr->f_tablelim;
-
- patch_borders[0] = sbr->kx[1];
- for (k = 1; k <= sbr->num_patches; k++)
- patch_borders[k] = patch_borders[k-1] + sbr->patch_num_subbands[k-1];
-
- memcpy(sbr->f_tablelim, sbr->f_tablelow,
- (sbr->n[0] + 1) * sizeof(sbr->f_tablelow[0]));
- if (sbr->num_patches > 1)
- memcpy(sbr->f_tablelim + sbr->n[0] + 1, patch_borders + 1,
- (sbr->num_patches - 1) * sizeof(patch_borders[0]));
-
- qsort(sbr->f_tablelim, sbr->num_patches + sbr->n[0],
- sizeof(sbr->f_tablelim[0]),
- qsort_comparison_function_int16);
-
- sbr->n_lim = sbr->n[0] + sbr->num_patches - 1;
- while (out < sbr->f_tablelim + sbr->n_lim) {
-#if USE_FIXED
- if ((*in << 23) >= *out * lim_bands_per_octave_warped) {
-#else
- if (*in >= *out * lim_bands_per_octave_warped) {
-#endif /* USE_FIXED */
- *++out = *in++;
- } else if (*in == *out ||
- !in_table_int16(patch_borders, sbr->num_patches, *in)) {
- in++;
- sbr->n_lim--;
- } else if (!in_table_int16(patch_borders, sbr->num_patches, *out)) {
- *out = *in++;
- sbr->n_lim--;
- } else {
- *++out = *in++;
- }
- }
- } else {
- sbr->f_tablelim[0] = sbr->f_tablelow[0];
- sbr->f_tablelim[1] = sbr->f_tablelow[sbr->n[0]];
- sbr->n_lim = 1;
- }
-}
-
-static unsigned int read_sbr_header(SpectralBandReplication *sbr, GetBitContext *gb)
-{
- unsigned int cnt = get_bits_count(gb);
- uint8_t bs_header_extra_1;
- uint8_t bs_header_extra_2;
- int old_bs_limiter_bands = sbr->bs_limiter_bands;
- SpectrumParameters old_spectrum_params;
-
- sbr->start = 1;
- sbr->ready_for_dequant = 0;
-
- // Save last spectrum parameters variables to compare to new ones
- memcpy(&old_spectrum_params, &sbr->spectrum_params, sizeof(SpectrumParameters));
-
- sbr->bs_amp_res_header = get_bits1(gb);
- sbr->spectrum_params.bs_start_freq = get_bits(gb, 4);
- sbr->spectrum_params.bs_stop_freq = get_bits(gb, 4);
- sbr->spectrum_params.bs_xover_band = get_bits(gb, 3);
- skip_bits(gb, 2); // bs_reserved
-
- bs_header_extra_1 = get_bits1(gb);
- bs_header_extra_2 = get_bits1(gb);
-
- if (bs_header_extra_1) {
- sbr->spectrum_params.bs_freq_scale = get_bits(gb, 2);
- sbr->spectrum_params.bs_alter_scale = get_bits1(gb);
- sbr->spectrum_params.bs_noise_bands = get_bits(gb, 2);
- } else {
- sbr->spectrum_params.bs_freq_scale = 2;
- sbr->spectrum_params.bs_alter_scale = 1;
- sbr->spectrum_params.bs_noise_bands = 2;
- }
-
- // Check if spectrum parameters changed
- if (memcmp(&old_spectrum_params, &sbr->spectrum_params, sizeof(SpectrumParameters)))
- sbr->reset = 1;
-
- if (bs_header_extra_2) {
- sbr->bs_limiter_bands = get_bits(gb, 2);
- sbr->bs_limiter_gains = get_bits(gb, 2);
- sbr->bs_interpol_freq = get_bits1(gb);
- sbr->bs_smoothing_mode = get_bits1(gb);
- } else {
- sbr->bs_limiter_bands = 2;
- sbr->bs_limiter_gains = 2;
- sbr->bs_interpol_freq = 1;
- sbr->bs_smoothing_mode = 1;
- }
-
- if (sbr->bs_limiter_bands != old_bs_limiter_bands && !sbr->reset)
- sbr_make_f_tablelim(sbr);
-
- return get_bits_count(gb) - cnt;
-}
-
-static int array_min_int16(const int16_t *array, int nel)
-{
- int i, min = array[0];
- for (i = 1; i < nel; i++)
- min = FFMIN(array[i], min);
- return min;
-}
-
-static int check_n_master(AVCodecContext *avctx, int n_master, int bs_xover_band)
-{
- // Requirements (14496-3 sp04 p205)
- if (n_master <= 0) {
- av_log(avctx, AV_LOG_ERROR, "Invalid n_master: %d\n", n_master);
- return -1;
- }
- if (bs_xover_band >= n_master) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid bitstream, crossover band index beyond array bounds: %d\n",
- bs_xover_band);
- return -1;
- }
- return 0;
-}
-
-/// Master Frequency Band Table (14496-3 sp04 p194)
-static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr,
- SpectrumParameters *spectrum)
-{
- unsigned int temp, max_qmf_subbands = 0;
- unsigned int start_min, stop_min;
- int k;
- const int8_t *sbr_offset_ptr;
- int16_t stop_dk[13];
-
- if (sbr->sample_rate < 32000) {
- temp = 3000;
- } else if (sbr->sample_rate < 64000) {
- temp = 4000;
- } else
- temp = 5000;
-
- switch (sbr->sample_rate) {
- case 16000:
- sbr_offset_ptr = sbr_offset[0];
- break;
- case 22050:
- sbr_offset_ptr = sbr_offset[1];
- break;
- case 24000:
- sbr_offset_ptr = sbr_offset[2];
- break;
- case 32000:
- sbr_offset_ptr = sbr_offset[3];
- break;
- case 44100: case 48000: case 64000:
- sbr_offset_ptr = sbr_offset[4];
- break;
- case 88200: case 96000: case 128000: case 176400: case 192000:
- sbr_offset_ptr = sbr_offset[5];
- break;
- default:
- av_log(ac->avctx, AV_LOG_ERROR,
- "Unsupported sample rate for SBR: %d\n", sbr->sample_rate);
- return -1;
- }
-
- start_min = ((temp << 7) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
- stop_min = ((temp << 8) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
-
- sbr->k[0] = start_min + sbr_offset_ptr[spectrum->bs_start_freq];
-
- if (spectrum->bs_stop_freq < 14) {
- sbr->k[2] = stop_min;
- make_bands(stop_dk, stop_min, 64, 13);
- qsort(stop_dk, 13, sizeof(stop_dk[0]), qsort_comparison_function_int16);
- for (k = 0; k < spectrum->bs_stop_freq; k++)
- sbr->k[2] += stop_dk[k];
- } else if (spectrum->bs_stop_freq == 14) {
- sbr->k[2] = 2*sbr->k[0];
- } else if (spectrum->bs_stop_freq == 15) {
- sbr->k[2] = 3*sbr->k[0];
- } else {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Invalid bs_stop_freq: %d\n", spectrum->bs_stop_freq);
- return -1;
- }
- sbr->k[2] = FFMIN(64, sbr->k[2]);
-
- // Requirements (14496-3 sp04 p205)
- if (sbr->sample_rate <= 32000) {
- max_qmf_subbands = 48;
- } else if (sbr->sample_rate == 44100) {
- max_qmf_subbands = 35;
- } else if (sbr->sample_rate >= 48000)
- max_qmf_subbands = 32;
- else
- av_assert0(0);
-
- if (sbr->k[2] - sbr->k[0] > max_qmf_subbands) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Invalid bitstream, too many QMF subbands: %d\n", sbr->k[2] - sbr->k[0]);
- return -1;
- }
-
- if (!spectrum->bs_freq_scale) {
- int dk, k2diff;
-
- dk = spectrum->bs_alter_scale + 1;
- sbr->n_master = ((sbr->k[2] - sbr->k[0] + (dk&2)) >> dk) << 1;
- if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))
- return -1;
-
- for (k = 1; k <= sbr->n_master; k++)
- sbr->f_master[k] = dk;
-
- k2diff = sbr->k[2] - sbr->k[0] - sbr->n_master * dk;
- if (k2diff < 0) {
- sbr->f_master[1]--;
- sbr->f_master[2]-= (k2diff < -1);
- } else if (k2diff) {
- sbr->f_master[sbr->n_master]++;
- }
-
- sbr->f_master[0] = sbr->k[0];
- for (k = 1; k <= sbr->n_master; k++)
- sbr->f_master[k] += sbr->f_master[k - 1];
-
- } else {
- int half_bands = 7 - spectrum->bs_freq_scale; // bs_freq_scale = {1,2,3}
- int two_regions, num_bands_0;
- int vdk0_max, vdk1_min;
- int16_t vk0[49];
-#if USE_FIXED
- int tmp, nz = 0;
-#endif /* USE_FIXED */
-
- if (49 * sbr->k[2] > 110 * sbr->k[0]) {
- two_regions = 1;
- sbr->k[1] = 2 * sbr->k[0];
- } else {
- two_regions = 0;
- sbr->k[1] = sbr->k[2];
- }
-
-#if USE_FIXED
- tmp = (sbr->k[1] << 23) / sbr->k[0];
- while (tmp < 0x40000000) {
- tmp <<= 1;
- nz++;
- }
- tmp = fixed_log(tmp - 0x80000000);
- tmp = (int)(((int64_t)tmp * CONST_RECIP_LN2 + 0x20000000) >> 30);
- tmp = (((tmp + 0x80) >> 8) + ((8 - nz) << 23)) * half_bands;
- num_bands_0 = ((tmp + 0x400000) >> 23) * 2;
-#else
- num_bands_0 = lrintf(half_bands * log2f(sbr->k[1] / (float)sbr->k[0])) * 2;
-#endif /* USE_FIXED */
-
- if (num_bands_0 <= 0) { // Requirements (14496-3 sp04 p205)
- av_log(ac->avctx, AV_LOG_ERROR, "Invalid num_bands_0: %d\n", num_bands_0);
- return -1;
- }
-
- vk0[0] = 0;
-
- make_bands(vk0+1, sbr->k[0], sbr->k[1], num_bands_0);
-
- qsort(vk0 + 1, num_bands_0, sizeof(vk0[1]), qsort_comparison_function_int16);
- vdk0_max = vk0[num_bands_0];
-
- vk0[0] = sbr->k[0];
- for (k = 1; k <= num_bands_0; k++) {
- if (vk0[k] <= 0) { // Requirements (14496-3 sp04 p205)
- av_log(ac->avctx, AV_LOG_ERROR, "Invalid vDk0[%d]: %d\n", k, vk0[k]);
- return -1;
- }
- vk0[k] += vk0[k-1];
- }
-
- if (two_regions) {
- int16_t vk1[49];
-#if USE_FIXED
- int num_bands_1;
-
- tmp = (sbr->k[2] << 23) / sbr->k[1];
- nz = 0;
- while (tmp < 0x40000000) {
- tmp <<= 1;
- nz++;
- }
- tmp = fixed_log(tmp - 0x80000000);
- tmp = (int)(((int64_t)tmp * CONST_RECIP_LN2 + 0x20000000) >> 30);
- tmp = (((tmp + 0x80) >> 8) + ((8 - nz) << 23)) * half_bands;
- if (spectrum->bs_alter_scale)
- tmp = (int)(((int64_t)tmp * CONST_076923 + 0x40000000) >> 31);
- num_bands_1 = ((tmp + 0x400000) >> 23) * 2;
-#else
- float invwarp = spectrum->bs_alter_scale ? 0.76923076923076923077f
- : 1.0f; // bs_alter_scale = {0,1}
- int num_bands_1 = lrintf(half_bands * invwarp *
- log2f(sbr->k[2] / (float)sbr->k[1])) * 2;
-#endif /* USE_FIXED */
- make_bands(vk1+1, sbr->k[1], sbr->k[2], num_bands_1);
-
- vdk1_min = array_min_int16(vk1 + 1, num_bands_1);
-
- if (vdk1_min < vdk0_max) {
- int change;
- qsort(vk1 + 1, num_bands_1, sizeof(vk1[1]), qsort_comparison_function_int16);
- change = FFMIN(vdk0_max - vk1[1], (vk1[num_bands_1] - vk1[1]) >> 1);
- vk1[1] += change;
- vk1[num_bands_1] -= change;
- }
-
- qsort(vk1 + 1, num_bands_1, sizeof(vk1[1]), qsort_comparison_function_int16);
-
- vk1[0] = sbr->k[1];
- for (k = 1; k <= num_bands_1; k++) {
- if (vk1[k] <= 0) { // Requirements (14496-3 sp04 p205)
- av_log(ac->avctx, AV_LOG_ERROR, "Invalid vDk1[%d]: %d\n", k, vk1[k]);
- return -1;
- }
- vk1[k] += vk1[k-1];
- }
-
- sbr->n_master = num_bands_0 + num_bands_1;
- if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))
- return -1;
- memcpy(&sbr->f_master[0], vk0,
- (num_bands_0 + 1) * sizeof(sbr->f_master[0]));
- memcpy(&sbr->f_master[num_bands_0 + 1], vk1 + 1,
- num_bands_1 * sizeof(sbr->f_master[0]));
-
- } else {
- sbr->n_master = num_bands_0;
- if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))
- return -1;
- memcpy(sbr->f_master, vk0, (num_bands_0 + 1) * sizeof(sbr->f_master[0]));
- }
- }
-
- return 0;
-}
-
-/// High Frequency Generation - Patch Construction (14496-3 sp04 p216 fig. 4.46)
-static int sbr_hf_calc_npatches(AACContext *ac, SpectralBandReplication *sbr)
-{
- int i, k, last_k = -1, last_msb = -1, sb = 0;
- int msb = sbr->k[0];
- int usb = sbr->kx[1];
- int goal_sb = ((1000 << 11) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
-
- sbr->num_patches = 0;
-
- if (goal_sb < sbr->kx[1] + sbr->m[1]) {
- for (k = 0; sbr->f_master[k] < goal_sb; k++) ;
- } else
- k = sbr->n_master;
-
- do {
- int odd = 0;
- if (k == last_k && msb == last_msb) {
- av_log(ac->avctx, AV_LOG_ERROR, "patch construction failed\n");
- return AVERROR_INVALIDDATA;
- }
- last_k = k;
- last_msb = msb;
- for (i = k; i == k || sb > (sbr->k[0] - 1 + msb - odd); i--) {
- sb = sbr->f_master[i];
- odd = (sb + sbr->k[0]) & 1;
- }
-
- // Requirements (14496-3 sp04 p205) sets the maximum number of patches to 5.
- // After this check the final number of patches can still be six which is
- // illegal however the Coding Technologies decoder check stream has a final
- // count of 6 patches
- if (sbr->num_patches > 5) {
- av_log(ac->avctx, AV_LOG_ERROR, "Too many patches: %d\n", sbr->num_patches);
- return -1;
- }
-
- sbr->patch_num_subbands[sbr->num_patches] = FFMAX(sb - usb, 0);
- sbr->patch_start_subband[sbr->num_patches] = sbr->k[0] - odd - sbr->patch_num_subbands[sbr->num_patches];
-
- if (sbr->patch_num_subbands[sbr->num_patches] > 0) {
- usb = sb;
- msb = sb;
- sbr->num_patches++;
- } else
- msb = sbr->kx[1];
-
- if (sbr->f_master[k] - sb < 3)
- k = sbr->n_master;
- } while (sb != sbr->kx[1] + sbr->m[1]);
-
- if (sbr->num_patches > 1 &&
- sbr->patch_num_subbands[sbr->num_patches - 1] < 3)
- sbr->num_patches--;
-
- return 0;
-}
-
-/// Derived Frequency Band Tables (14496-3 sp04 p197)
-static int sbr_make_f_derived(AACContext *ac, SpectralBandReplication *sbr)
-{
- int k, temp;
-#if USE_FIXED
- int nz = 0;
-#endif /* USE_FIXED */
-
- sbr->n[1] = sbr->n_master - sbr->spectrum_params.bs_xover_band;
- sbr->n[0] = (sbr->n[1] + 1) >> 1;
-
- memcpy(sbr->f_tablehigh, &sbr->f_master[sbr->spectrum_params.bs_xover_band],
- (sbr->n[1] + 1) * sizeof(sbr->f_master[0]));
- sbr->m[1] = sbr->f_tablehigh[sbr->n[1]] - sbr->f_tablehigh[0];
- sbr->kx[1] = sbr->f_tablehigh[0];
-
- // Requirements (14496-3 sp04 p205)
- if (sbr->kx[1] + sbr->m[1] > 64) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Stop frequency border too high: %d\n", sbr->kx[1] + sbr->m[1]);
- return -1;
- }
- if (sbr->kx[1] > 32) {
- av_log(ac->avctx, AV_LOG_ERROR, "Start frequency border too high: %d\n", sbr->kx[1]);
- return -1;
- }
-
- sbr->f_tablelow[0] = sbr->f_tablehigh[0];
- temp = sbr->n[1] & 1;
- for (k = 1; k <= sbr->n[0]; k++)
- sbr->f_tablelow[k] = sbr->f_tablehigh[2 * k - temp];
-#if USE_FIXED
- temp = (sbr->k[2] << 23) / sbr->kx[1];
- while (temp < 0x40000000) {
- temp <<= 1;
- nz++;
- }
- temp = fixed_log(temp - 0x80000000);
- temp = (int)(((int64_t)temp * CONST_RECIP_LN2 + 0x20000000) >> 30);
- temp = (((temp + 0x80) >> 8) + ((8 - nz) << 23)) * sbr->spectrum_params.bs_noise_bands;
-
- sbr->n_q = (temp + 0x400000) >> 23;
- if (sbr->n_q < 1)
- sbr->n_q = 1;
-#else
- sbr->n_q = FFMAX(1, lrintf(sbr->spectrum_params.bs_noise_bands *
- log2f(sbr->k[2] / (float)sbr->kx[1]))); // 0 <= bs_noise_bands <= 3
-#endif /* USE_FIXED */
-
- if (sbr->n_q > 5) {
- av_log(ac->avctx, AV_LOG_ERROR, "Too many noise floor scale factors: %d\n", sbr->n_q);
- return -1;
- }
-
- sbr->f_tablenoise[0] = sbr->f_tablelow[0];
- temp = 0;
- for (k = 1; k <= sbr->n_q; k++) {
- temp += (sbr->n[0] - temp) / (sbr->n_q + 1 - k);
- sbr->f_tablenoise[k] = sbr->f_tablelow[temp];
- }
-
- if (sbr_hf_calc_npatches(ac, sbr) < 0)
- return -1;
-
- sbr_make_f_tablelim(sbr);
-
- sbr->data[0].f_indexnoise = 0;
- sbr->data[1].f_indexnoise = 0;
-
- return 0;
-}
-
-static av_always_inline void get_bits1_vector(GetBitContext *gb, uint8_t *vec,
- int elements)
-{
- int i;
- for (i = 0; i < elements; i++) {
- vec[i] = get_bits1(gb);
- }
-}
-
-/** ceil(log2(index+1)) */
-static const int8_t ceil_log2[] = {
- 0, 1, 2, 2, 3, 3,
-};
-
-static int read_sbr_grid(AACContext *ac, SpectralBandReplication *sbr,
- GetBitContext *gb, SBRData *ch_data)
-{
- int i;
- int bs_pointer = 0;
- // frameLengthFlag ? 15 : 16; 960 sample length frames unsupported; this value is numTimeSlots
- int abs_bord_trail = 16;
- int num_rel_lead, num_rel_trail;
- unsigned bs_num_env_old = ch_data->bs_num_env;
-
- ch_data->bs_freq_res[0] = ch_data->bs_freq_res[ch_data->bs_num_env];
- ch_data->bs_amp_res = sbr->bs_amp_res_header;
- ch_data->t_env_num_env_old = ch_data->t_env[bs_num_env_old];
-
- switch (ch_data->bs_frame_class = get_bits(gb, 2)) {
- case FIXFIX:
- ch_data->bs_num_env = 1 << get_bits(gb, 2);
- num_rel_lead = ch_data->bs_num_env - 1;
- if (ch_data->bs_num_env == 1)
- ch_data->bs_amp_res = 0;
-
- if (ch_data->bs_num_env > 4) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Invalid bitstream, too many SBR envelopes in FIXFIX type SBR frame: %d\n",
- ch_data->bs_num_env);
- return -1;
- }
-
- ch_data->t_env[0] = 0;
- ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
-
- abs_bord_trail = (abs_bord_trail + (ch_data->bs_num_env >> 1)) /
- ch_data->bs_num_env;
- for (i = 0; i < num_rel_lead; i++)
- ch_data->t_env[i + 1] = ch_data->t_env[i] + abs_bord_trail;
-
- ch_data->bs_freq_res[1] = get_bits1(gb);
- for (i = 1; i < ch_data->bs_num_env; i++)
- ch_data->bs_freq_res[i + 1] = ch_data->bs_freq_res[1];
- break;
- case FIXVAR:
- abs_bord_trail += get_bits(gb, 2);
- num_rel_trail = get_bits(gb, 2);
- ch_data->bs_num_env = num_rel_trail + 1;
- ch_data->t_env[0] = 0;
- ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
-
- for (i = 0; i < num_rel_trail; i++)
- ch_data->t_env[ch_data->bs_num_env - 1 - i] =
- ch_data->t_env[ch_data->bs_num_env - i] - 2 * get_bits(gb, 2) - 2;
-
- bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]);
-
- for (i = 0; i < ch_data->bs_num_env; i++)
- ch_data->bs_freq_res[ch_data->bs_num_env - i] = get_bits1(gb);
- break;
- case VARFIX:
- ch_data->t_env[0] = get_bits(gb, 2);
- num_rel_lead = get_bits(gb, 2);
- ch_data->bs_num_env = num_rel_lead + 1;
- ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
-
- for (i = 0; i < num_rel_lead; i++)
- ch_data->t_env[i + 1] = ch_data->t_env[i] + 2 * get_bits(gb, 2) + 2;
-
- bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]);
-
- get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env);
- break;
- case VARVAR:
- ch_data->t_env[0] = get_bits(gb, 2);
- abs_bord_trail += get_bits(gb, 2);
- num_rel_lead = get_bits(gb, 2);
- num_rel_trail = get_bits(gb, 2);
- ch_data->bs_num_env = num_rel_lead + num_rel_trail + 1;
-
- if (ch_data->bs_num_env > 5) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Invalid bitstream, too many SBR envelopes in VARVAR type SBR frame: %d\n",
- ch_data->bs_num_env);
- return -1;
- }
-
- ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
-
- for (i = 0; i < num_rel_lead; i++)
- ch_data->t_env[i + 1] = ch_data->t_env[i] + 2 * get_bits(gb, 2) + 2;
- for (i = 0; i < num_rel_trail; i++)
- ch_data->t_env[ch_data->bs_num_env - 1 - i] =
- ch_data->t_env[ch_data->bs_num_env - i] - 2 * get_bits(gb, 2) - 2;
-
- bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]);
-
- get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env);
- break;
- }
-
- av_assert0(bs_pointer >= 0);
- if (bs_pointer > ch_data->bs_num_env + 1) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Invalid bitstream, bs_pointer points to a middle noise border outside the time borders table: %d\n",
- bs_pointer);
- return -1;
- }
-
- for (i = 1; i <= ch_data->bs_num_env; i++) {
- if (ch_data->t_env[i-1] >= ch_data->t_env[i]) {
- av_log(ac->avctx, AV_LOG_ERROR, "Not strictly monotone time borders\n");
- return -1;
- }
- }
-
- ch_data->bs_num_noise = (ch_data->bs_num_env > 1) + 1;
-
- ch_data->t_q[0] = ch_data->t_env[0];
- ch_data->t_q[ch_data->bs_num_noise] = ch_data->t_env[ch_data->bs_num_env];
- if (ch_data->bs_num_noise > 1) {
- int idx;
- if (ch_data->bs_frame_class == FIXFIX) {
- idx = ch_data->bs_num_env >> 1;
- } else if (ch_data->bs_frame_class & 1) { // FIXVAR or VARVAR
- idx = ch_data->bs_num_env - FFMAX(bs_pointer - 1, 1);
- } else { // VARFIX
- if (!bs_pointer)
- idx = 1;
- else if (bs_pointer == 1)
- idx = ch_data->bs_num_env - 1;
- else // bs_pointer > 1
- idx = bs_pointer - 1;
- }
- ch_data->t_q[1] = ch_data->t_env[idx];
- }
-
- ch_data->e_a[0] = -(ch_data->e_a[1] != bs_num_env_old); // l_APrev
- ch_data->e_a[1] = -1;
- if ((ch_data->bs_frame_class & 1) && bs_pointer) { // FIXVAR or VARVAR and bs_pointer != 0
- ch_data->e_a[1] = ch_data->bs_num_env + 1 - bs_pointer;
- } else if ((ch_data->bs_frame_class == 2) && (bs_pointer > 1)) // VARFIX and bs_pointer > 1
- ch_data->e_a[1] = bs_pointer - 1;
-
- return 0;
-}
-
-static void copy_sbr_grid(SBRData *dst, const SBRData *src) {
- //These variables are saved from the previous frame rather than copied
- dst->bs_freq_res[0] = dst->bs_freq_res[dst->bs_num_env];
- dst->t_env_num_env_old = dst->t_env[dst->bs_num_env];
- dst->e_a[0] = -(dst->e_a[1] != dst->bs_num_env);
-
- //These variables are read from the bitstream and therefore copied
- memcpy(dst->bs_freq_res+1, src->bs_freq_res+1, sizeof(dst->bs_freq_res)-sizeof(*dst->bs_freq_res));
- memcpy(dst->t_env, src->t_env, sizeof(dst->t_env));
- memcpy(dst->t_q, src->t_q, sizeof(dst->t_q));
- dst->bs_num_env = src->bs_num_env;
- dst->bs_amp_res = src->bs_amp_res;
- dst->bs_num_noise = src->bs_num_noise;
- dst->bs_frame_class = src->bs_frame_class;
- dst->e_a[1] = src->e_a[1];
-}
-
-/// Read how the envelope and noise floor data is delta coded
-static void read_sbr_dtdf(SpectralBandReplication *sbr, GetBitContext *gb,
- SBRData *ch_data)
-{
- get_bits1_vector(gb, ch_data->bs_df_env, ch_data->bs_num_env);
- get_bits1_vector(gb, ch_data->bs_df_noise, ch_data->bs_num_noise);
-}
-
-/// Read inverse filtering data
-static void read_sbr_invf(SpectralBandReplication *sbr, GetBitContext *gb,
- SBRData *ch_data)
-{
- int i;
-
- memcpy(ch_data->bs_invf_mode[1], ch_data->bs_invf_mode[0], 5 * sizeof(uint8_t));
- for (i = 0; i < sbr->n_q; i++)
- ch_data->bs_invf_mode[0][i] = get_bits(gb, 2);
-}
-
-static void read_sbr_envelope(SpectralBandReplication *sbr, GetBitContext *gb,
- SBRData *ch_data, int ch)
-{
- int bits;
- int i, j, k;
- VLC_TYPE (*t_huff)[2], (*f_huff)[2];
- int t_lav, f_lav;
- const int delta = (ch == 1 && sbr->bs_coupling == 1) + 1;
- const int odd = sbr->n[1] & 1;
-
- if (sbr->bs_coupling && ch) {
- if (ch_data->bs_amp_res) {
- bits = 5;
- t_huff = vlc_sbr[T_HUFFMAN_ENV_BAL_3_0DB].table;
- t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_BAL_3_0DB];
- f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_3_0DB].table;
- f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_3_0DB];
- } else {
- bits = 6;
- t_huff = vlc_sbr[T_HUFFMAN_ENV_BAL_1_5DB].table;
- t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_BAL_1_5DB];
- f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_1_5DB].table;
- f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_1_5DB];
- }
- } else {
- if (ch_data->bs_amp_res) {
- bits = 6;
- t_huff = vlc_sbr[T_HUFFMAN_ENV_3_0DB].table;
- t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_3_0DB];
- f_huff = vlc_sbr[F_HUFFMAN_ENV_3_0DB].table;
- f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_3_0DB];
- } else {
- bits = 7;
- t_huff = vlc_sbr[T_HUFFMAN_ENV_1_5DB].table;
- t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_1_5DB];
- f_huff = vlc_sbr[F_HUFFMAN_ENV_1_5DB].table;
- f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_1_5DB];
- }
- }
-
-#if USE_FIXED
- for (i = 0; i < ch_data->bs_num_env; i++) {
- if (ch_data->bs_df_env[i]) {
- // bs_freq_res[0] == bs_freq_res[bs_num_env] from prev frame
- if (ch_data->bs_freq_res[i + 1] == ch_data->bs_freq_res[i]) {
- for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++)
- ch_data->env_facs[i + 1][j].mant = ch_data->env_facs[i][j].mant + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
- } else if (ch_data->bs_freq_res[i + 1]) {
- for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) {
- k = (j + odd) >> 1; // find k such that f_tablelow[k] <= f_tablehigh[j] < f_tablelow[k + 1]
- ch_data->env_facs[i + 1][j].mant = ch_data->env_facs[i][k].mant + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
- }
- } else {
- for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) {
- k = j ? 2*j - odd : 0; // find k such that f_tablehigh[k] == f_tablelow[j]
- ch_data->env_facs[i + 1][j].mant = ch_data->env_facs[i][k].mant + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
- }
- }
- } else {
- ch_data->env_facs[i + 1][0].mant = delta * get_bits(gb, bits); // bs_env_start_value_balance
- for (j = 1; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++)
- ch_data->env_facs[i + 1][j].mant = ch_data->env_facs[i + 1][j - 1].mant + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav);
- }
- }
-#else
- for (i = 0; i < ch_data->bs_num_env; i++) {
- if (ch_data->bs_df_env[i]) {
- // bs_freq_res[0] == bs_freq_res[bs_num_env] from prev frame
- if (ch_data->bs_freq_res[i + 1] == ch_data->bs_freq_res[i]) {
- for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++)
- ch_data->env_facs[i + 1][j] = ch_data->env_facs[i][j] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
- } else if (ch_data->bs_freq_res[i + 1]) {
- for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) {
- k = (j + odd) >> 1; // find k such that f_tablelow[k] <= f_tablehigh[j] < f_tablelow[k + 1]
- ch_data->env_facs[i + 1][j] = ch_data->env_facs[i][k] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
- }
- } else {
- for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) {
- k = j ? 2*j - odd : 0; // find k such that f_tablehigh[k] == f_tablelow[j]
- ch_data->env_facs[i + 1][j] = ch_data->env_facs[i][k] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
- }
- }
- } else {
- ch_data->env_facs[i + 1][0] = delta * get_bits(gb, bits); // bs_env_start_value_balance
- for (j = 1; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++)
- ch_data->env_facs[i + 1][j] = ch_data->env_facs[i + 1][j - 1] + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav);
- }
- }
-#endif /* USE_FIXED */
-
- //assign 0th elements of env_facs from last elements
- memcpy(ch_data->env_facs[0], ch_data->env_facs[ch_data->bs_num_env],
- sizeof(ch_data->env_facs[0]));
-}
-
-static void read_sbr_noise(SpectralBandReplication *sbr, GetBitContext *gb,
- SBRData *ch_data, int ch)
-{
- int i, j;
- VLC_TYPE (*t_huff)[2], (*f_huff)[2];
- int t_lav, f_lav;
- int delta = (ch == 1 && sbr->bs_coupling == 1) + 1;
-
- if (sbr->bs_coupling && ch) {
- t_huff = vlc_sbr[T_HUFFMAN_NOISE_BAL_3_0DB].table;
- t_lav = vlc_sbr_lav[T_HUFFMAN_NOISE_BAL_3_0DB];
- f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_3_0DB].table;
- f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_3_0DB];
- } else {
- t_huff = vlc_sbr[T_HUFFMAN_NOISE_3_0DB].table;
- t_lav = vlc_sbr_lav[T_HUFFMAN_NOISE_3_0DB];
- f_huff = vlc_sbr[F_HUFFMAN_ENV_3_0DB].table;
- f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_3_0DB];
- }
-
-#if USE_FIXED
- for (i = 0; i < ch_data->bs_num_noise; i++) {
- if (ch_data->bs_df_noise[i]) {
- for (j = 0; j < sbr->n_q; j++)
- ch_data->noise_facs[i + 1][j].mant = ch_data->noise_facs[i][j].mant + delta * (get_vlc2(gb, t_huff, 9, 2) - t_lav);
- } else {
- ch_data->noise_facs[i + 1][0].mant = delta * get_bits(gb, 5); // bs_noise_start_value_balance or bs_noise_start_value_level
- for (j = 1; j < sbr->n_q; j++)
- ch_data->noise_facs[i + 1][j].mant = ch_data->noise_facs[i + 1][j - 1].mant + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav);
- }
- }
-#else
- for (i = 0; i < ch_data->bs_num_noise; i++) {
- if (ch_data->bs_df_noise[i]) {
- for (j = 0; j < sbr->n_q; j++)
- ch_data->noise_facs[i + 1][j] = ch_data->noise_facs[i][j] + delta * (get_vlc2(gb, t_huff, 9, 2) - t_lav);
- } else {
- ch_data->noise_facs[i + 1][0] = delta * get_bits(gb, 5); // bs_noise_start_value_balance or bs_noise_start_value_level
- for (j = 1; j < sbr->n_q; j++)
- ch_data->noise_facs[i + 1][j] = ch_data->noise_facs[i + 1][j - 1] + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav);
- }
- }
-#endif /* USE_FIXED */
-
- //assign 0th elements of noise_facs from last elements
- memcpy(ch_data->noise_facs[0], ch_data->noise_facs[ch_data->bs_num_noise],
- sizeof(ch_data->noise_facs[0]));
-}
-
-static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
- GetBitContext *gb,
- int bs_extension_id, int *num_bits_left)
-{
- switch (bs_extension_id) {
- case EXTENSION_ID_PS:
- if (!ac->oc[1].m4ac.ps) {
- av_log(ac->avctx, AV_LOG_ERROR, "Parametric Stereo signaled to be not-present but was found in the bitstream.\n");
- skip_bits_long(gb, *num_bits_left); // bs_fill_bits
- *num_bits_left = 0;
- } else {
-#if 1
- *num_bits_left -= AAC_RENAME(ff_ps_read_data)(ac->avctx, gb, &sbr->ps, *num_bits_left);
- ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
-#else
- avpriv_report_missing_feature(ac->avctx, "Parametric Stereo");
- skip_bits_long(gb, *num_bits_left); // bs_fill_bits
- *num_bits_left = 0;
-#endif
- }
- break;
- default:
- // some files contain 0-padding
- if (bs_extension_id || *num_bits_left > 16 || show_bits(gb, *num_bits_left))
- avpriv_request_sample(ac->avctx, "Reserved SBR extensions");
- skip_bits_long(gb, *num_bits_left); // bs_fill_bits
- *num_bits_left = 0;
- break;
- }
-}
-
-static int read_sbr_single_channel_element(AACContext *ac,
- SpectralBandReplication *sbr,
- GetBitContext *gb)
-{
- if (get_bits1(gb)) // bs_data_extra
- skip_bits(gb, 4); // bs_reserved
-
- if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]))
- return -1;
- read_sbr_dtdf(sbr, gb, &sbr->data[0]);
- read_sbr_invf(sbr, gb, &sbr->data[0]);
- read_sbr_envelope(sbr, gb, &sbr->data[0], 0);
- read_sbr_noise(sbr, gb, &sbr->data[0], 0);
-
- if ((sbr->data[0].bs_add_harmonic_flag = get_bits1(gb)))
- get_bits1_vector(gb, sbr->data[0].bs_add_harmonic, sbr->n[1]);
-
- return 0;
-}
-
-static int read_sbr_channel_pair_element(AACContext *ac,
- SpectralBandReplication *sbr,
- GetBitContext *gb)
-{
- if (get_bits1(gb)) // bs_data_extra
- skip_bits(gb, 8); // bs_reserved
-
- if ((sbr->bs_coupling = get_bits1(gb))) {
- if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]))
- return -1;
- copy_sbr_grid(&sbr->data[1], &sbr->data[0]);
- read_sbr_dtdf(sbr, gb, &sbr->data[0]);
- read_sbr_dtdf(sbr, gb, &sbr->data[1]);
- read_sbr_invf(sbr, gb, &sbr->data[0]);
- memcpy(sbr->data[1].bs_invf_mode[1], sbr->data[1].bs_invf_mode[0], sizeof(sbr->data[1].bs_invf_mode[0]));
- memcpy(sbr->data[1].bs_invf_mode[0], sbr->data[0].bs_invf_mode[0], sizeof(sbr->data[1].bs_invf_mode[0]));
- read_sbr_envelope(sbr, gb, &sbr->data[0], 0);
- read_sbr_noise(sbr, gb, &sbr->data[0], 0);
- read_sbr_envelope(sbr, gb, &sbr->data[1], 1);
- read_sbr_noise(sbr, gb, &sbr->data[1], 1);
- } else {
- if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]) ||
- read_sbr_grid(ac, sbr, gb, &sbr->data[1]))
- return -1;
- read_sbr_dtdf(sbr, gb, &sbr->data[0]);
- read_sbr_dtdf(sbr, gb, &sbr->data[1]);
- read_sbr_invf(sbr, gb, &sbr->data[0]);
- read_sbr_invf(sbr, gb, &sbr->data[1]);
- read_sbr_envelope(sbr, gb, &sbr->data[0], 0);
- read_sbr_envelope(sbr, gb, &sbr->data[1], 1);
- read_sbr_noise(sbr, gb, &sbr->data[0], 0);
- read_sbr_noise(sbr, gb, &sbr->data[1], 1);
- }
-
- if ((sbr->data[0].bs_add_harmonic_flag = get_bits1(gb)))
- get_bits1_vector(gb, sbr->data[0].bs_add_harmonic, sbr->n[1]);
- if ((sbr->data[1].bs_add_harmonic_flag = get_bits1(gb)))
- get_bits1_vector(gb, sbr->data[1].bs_add_harmonic, sbr->n[1]);
-
- return 0;
-}
-
-static unsigned int read_sbr_data(AACContext *ac, SpectralBandReplication *sbr,
- GetBitContext *gb, int id_aac)
-{
- unsigned int cnt = get_bits_count(gb);
-
- sbr->id_aac = id_aac;
- sbr->ready_for_dequant = 1;
-
- if (id_aac == TYPE_SCE || id_aac == TYPE_CCE) {
- if (read_sbr_single_channel_element(ac, sbr, gb)) {
- sbr_turnoff(sbr);
- return get_bits_count(gb) - cnt;
- }
- } else if (id_aac == TYPE_CPE) {
- if (read_sbr_channel_pair_element(ac, sbr, gb)) {
- sbr_turnoff(sbr);
- return get_bits_count(gb) - cnt;
- }
- } else {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Invalid bitstream - cannot apply SBR to element type %d\n", id_aac);
- sbr_turnoff(sbr);
- return get_bits_count(gb) - cnt;
- }
- if (get_bits1(gb)) { // bs_extended_data
- int num_bits_left = get_bits(gb, 4); // bs_extension_size
- if (num_bits_left == 15)
- num_bits_left += get_bits(gb, 8); // bs_esc_count
-
- num_bits_left <<= 3;
- while (num_bits_left > 7) {
- num_bits_left -= 2;
- read_sbr_extension(ac, sbr, gb, get_bits(gb, 2), &num_bits_left); // bs_extension_id
- }
- if (num_bits_left < 0) {
- av_log(ac->avctx, AV_LOG_ERROR, "SBR Extension over read.\n");
- }
- if (num_bits_left > 0)
- skip_bits(gb, num_bits_left);
- }
-
- return get_bits_count(gb) - cnt;
-}
-
-static void sbr_reset(AACContext *ac, SpectralBandReplication *sbr)
-{
- int err;
- err = sbr_make_f_master(ac, sbr, &sbr->spectrum_params);
- if (err >= 0)
- err = sbr_make_f_derived(ac, sbr);
- if (err < 0) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "SBR reset failed. Switching SBR to pure upsampling mode.\n");
- sbr_turnoff(sbr);
- }
-}
-
-/**
- * Decode Spectral Band Replication extension data; reference: table 4.55.
- *
- * @param crc flag indicating the presence of CRC checksum
- * @param cnt length of TYPE_FIL syntactic element in bytes
- *
- * @return Returns number of bytes consumed from the TYPE_FIL element.
- */
-int AAC_RENAME(ff_decode_sbr_extension)(AACContext *ac, SpectralBandReplication *sbr,
- GetBitContext *gb_host, int crc, int cnt, int id_aac)
-{
- unsigned int num_sbr_bits = 0, num_align_bits;
- unsigned bytes_read;
- GetBitContext gbc = *gb_host, *gb = &gbc;
- skip_bits_long(gb_host, cnt*8 - 4);
-
- sbr->reset = 0;
-
- if (!sbr->sample_rate)
- sbr->sample_rate = 2 * ac->oc[1].m4ac.sample_rate; //TODO use the nominal sample rate for arbitrary sample rate support
- if (!ac->oc[1].m4ac.ext_sample_rate)
- ac->oc[1].m4ac.ext_sample_rate = 2 * ac->oc[1].m4ac.sample_rate;
-
- if (crc) {
- skip_bits(gb, 10); // bs_sbr_crc_bits; TODO - implement CRC check
- num_sbr_bits += 10;
- }
-
- //Save some state from the previous frame.
- sbr->kx[0] = sbr->kx[1];
- sbr->m[0] = sbr->m[1];
- sbr->kx_and_m_pushed = 1;
-
- num_sbr_bits++;
- if (get_bits1(gb)) // bs_header_flag
- num_sbr_bits += read_sbr_header(sbr, gb);
-
- if (sbr->reset)
- sbr_reset(ac, sbr);
-
- if (sbr->start)
- num_sbr_bits += read_sbr_data(ac, sbr, gb, id_aac);
-
- num_align_bits = ((cnt << 3) - 4 - num_sbr_bits) & 7;
- bytes_read = ((num_sbr_bits + num_align_bits + 4) >> 3);
-
- if (bytes_read > cnt) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "Expected to read %d SBR bytes actually read %d.\n", cnt, bytes_read);
- }
- return cnt;
-}
-
-/**
- * Analysis QMF Bank (14496-3 sp04 p206)
- *
- * @param x pointer to the beginning of the first sample window
- * @param W array of complex-valued samples split into subbands
- */
-#ifndef sbr_qmf_analysis
-#if USE_FIXED
-static void sbr_qmf_analysis(AVFixedDSPContext *dsp, FFTContext *mdct,
-#else
-static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
-#endif /* USE_FIXED */
- SBRDSPContext *sbrdsp, const INTFLOAT *in, INTFLOAT *x,
- INTFLOAT z[320], INTFLOAT W[2][32][32][2], int buf_idx)
-{
- int i;
-#if USE_FIXED
- int j;
-#endif
- memcpy(x , x+1024, (320-32)*sizeof(x[0]));
- memcpy(x+288, in, 1024*sizeof(x[0]));
- for (i = 0; i < 32; i++) { // numTimeSlots*RATE = 16*2 as 960 sample frames
- // are not supported
- dsp->vector_fmul_reverse(z, sbr_qmf_window_ds, x, 320);
- sbrdsp->sum64x5(z);
- sbrdsp->qmf_pre_shuffle(z);
-#if USE_FIXED
- for (j = 64; j < 128; j++) {
- if (z[j] > 1<<24) {
- av_log(NULL, AV_LOG_WARNING,
- "sbr_qmf_analysis: value %09d too large, setting to %09d\n",
- z[j], 1<<24);
- z[j] = 1<<24;
- } else if (z[j] < -(1<<24)) {
- av_log(NULL, AV_LOG_WARNING,
- "sbr_qmf_analysis: value %09d too small, setting to %09d\n",
- z[j], -(1<<24));
- z[j] = -(1<<24);
- }
- }
-#endif
- mdct->imdct_half(mdct, z, z+64);
- sbrdsp->qmf_post_shuffle(W[buf_idx][i], z);
- x += 32;
- }
-}
-#endif
-
-/**
- * Synthesis QMF Bank (14496-3 sp04 p206) and Downsampled Synthesis QMF Bank
- * (14496-3 sp04 p206)
- */
-#ifndef sbr_qmf_synthesis
-static void sbr_qmf_synthesis(FFTContext *mdct,
-#if USE_FIXED
- SBRDSPContext *sbrdsp, AVFixedDSPContext *dsp,
-#else
- SBRDSPContext *sbrdsp, AVFloatDSPContext *dsp,
-#endif /* USE_FIXED */
- INTFLOAT *out, INTFLOAT X[2][38][64],
- INTFLOAT mdct_buf[2][64],
- INTFLOAT *v0, int *v_off, const unsigned int div)
-{
- int i, n;
- const INTFLOAT *sbr_qmf_window = div ? sbr_qmf_window_ds : sbr_qmf_window_us;
- const int step = 128 >> div;
- INTFLOAT *v;
- for (i = 0; i < 32; i++) {
- if (*v_off < step) {
- int saved_samples = (1280 - 128) >> div;
- memcpy(&v0[SBR_SYNTHESIS_BUF_SIZE - saved_samples], v0, saved_samples * sizeof(INTFLOAT));
- *v_off = SBR_SYNTHESIS_BUF_SIZE - saved_samples - step;
- } else {
- *v_off -= step;
- }
- v = v0 + *v_off;
- if (div) {
- for (n = 0; n < 32; n++) {
- X[0][i][ n] = -X[0][i][n];
- X[0][i][32+n] = X[1][i][31-n];
- }
- mdct->imdct_half(mdct, mdct_buf[0], X[0][i]);
- sbrdsp->qmf_deint_neg(v, mdct_buf[0]);
- } else {
- sbrdsp->neg_odd_64(X[1][i]);
- mdct->imdct_half(mdct, mdct_buf[0], X[0][i]);
- mdct->imdct_half(mdct, mdct_buf[1], X[1][i]);
- sbrdsp->qmf_deint_bfly(v, mdct_buf[1], mdct_buf[0]);
- }
- dsp->vector_fmul (out, v , sbr_qmf_window , 64 >> div);
- dsp->vector_fmul_add(out, v + ( 192 >> div), sbr_qmf_window + ( 64 >> div), out , 64 >> div);
- dsp->vector_fmul_add(out, v + ( 256 >> div), sbr_qmf_window + (128 >> div), out , 64 >> div);
- dsp->vector_fmul_add(out, v + ( 448 >> div), sbr_qmf_window + (192 >> div), out , 64 >> div);
- dsp->vector_fmul_add(out, v + ( 512 >> div), sbr_qmf_window + (256 >> div), out , 64 >> div);
- dsp->vector_fmul_add(out, v + ( 704 >> div), sbr_qmf_window + (320 >> div), out , 64 >> div);
- dsp->vector_fmul_add(out, v + ( 768 >> div), sbr_qmf_window + (384 >> div), out , 64 >> div);
- dsp->vector_fmul_add(out, v + ( 960 >> div), sbr_qmf_window + (448 >> div), out , 64 >> div);
- dsp->vector_fmul_add(out, v + (1024 >> div), sbr_qmf_window + (512 >> div), out , 64 >> div);
- dsp->vector_fmul_add(out, v + (1216 >> div), sbr_qmf_window + (576 >> div), out , 64 >> div);
- out += 64 >> div;
- }
-}
-#endif
-
-/// Generate the subband filtered lowband
-static int sbr_lf_gen(AACContext *ac, SpectralBandReplication *sbr,
- INTFLOAT X_low[32][40][2], const INTFLOAT W[2][32][32][2],
- int buf_idx)
-{
- int i, k;
- const int t_HFGen = 8;
- const int i_f = 32;
- memset(X_low, 0, 32*sizeof(*X_low));
- for (k = 0; k < sbr->kx[1]; k++) {
- for (i = t_HFGen; i < i_f + t_HFGen; i++) {
- X_low[k][i][0] = W[buf_idx][i - t_HFGen][k][0];
- X_low[k][i][1] = W[buf_idx][i - t_HFGen][k][1];
- }
- }
- buf_idx = 1-buf_idx;
- for (k = 0; k < sbr->kx[0]; k++) {
- for (i = 0; i < t_HFGen; i++) {
- X_low[k][i][0] = W[buf_idx][i + i_f - t_HFGen][k][0];
- X_low[k][i][1] = W[buf_idx][i + i_f - t_HFGen][k][1];
- }
- }
- return 0;
-}
-
-/// High Frequency Generator (14496-3 sp04 p215)
-static int sbr_hf_gen(AACContext *ac, SpectralBandReplication *sbr,
- INTFLOAT X_high[64][40][2], const INTFLOAT X_low[32][40][2],
- const INTFLOAT (*alpha0)[2], const INTFLOAT (*alpha1)[2],
- const INTFLOAT bw_array[5], const uint8_t *t_env,
- int bs_num_env)
-{
- int j, x;
- int g = 0;
- int k = sbr->kx[1];
- for (j = 0; j < sbr->num_patches; j++) {
- for (x = 0; x < sbr->patch_num_subbands[j]; x++, k++) {
- const int p = sbr->patch_start_subband[j] + x;
- while (g <= sbr->n_q && k >= sbr->f_tablenoise[g])
- g++;
- g--;
-
- if (g < 0) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "ERROR : no subband found for frequency %d\n", k);
- return -1;
- }
-
- sbr->dsp.hf_gen(X_high[k] + ENVELOPE_ADJUSTMENT_OFFSET,
- X_low[p] + ENVELOPE_ADJUSTMENT_OFFSET,
- alpha0[p], alpha1[p], bw_array[g],
- 2 * t_env[0], 2 * t_env[bs_num_env]);
- }
- }
- if (k < sbr->m[1] + sbr->kx[1])
- memset(X_high + k, 0, (sbr->m[1] + sbr->kx[1] - k) * sizeof(*X_high));
-
- return 0;
-}
-
-/// Generate the subband filtered lowband
-static int sbr_x_gen(SpectralBandReplication *sbr, INTFLOAT X[2][38][64],
- const INTFLOAT Y0[38][64][2], const INTFLOAT Y1[38][64][2],
- const INTFLOAT X_low[32][40][2], int ch)
-{
- int k, i;
- const int i_f = 32;
- const int i_Temp = FFMAX(2*sbr->data[ch].t_env_num_env_old - i_f, 0);
- memset(X, 0, 2*sizeof(*X));
- for (k = 0; k < sbr->kx[0]; k++) {
- for (i = 0; i < i_Temp; i++) {
- X[0][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][0];
- X[1][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][1];
- }
- }
- for (; k < sbr->kx[0] + sbr->m[0]; k++) {
- for (i = 0; i < i_Temp; i++) {
- X[0][i][k] = Y0[i + i_f][k][0];
- X[1][i][k] = Y0[i + i_f][k][1];
- }
- }
-
- for (k = 0; k < sbr->kx[1]; k++) {
- for (i = i_Temp; i < 38; i++) {
- X[0][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][0];
- X[1][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][1];
- }
- }
- for (; k < sbr->kx[1] + sbr->m[1]; k++) {
- for (i = i_Temp; i < i_f; i++) {
- X[0][i][k] = Y1[i][k][0];
- X[1][i][k] = Y1[i][k][1];
- }
- }
- return 0;
-}
-
-/** High Frequency Adjustment (14496-3 sp04 p217) and Mapping
- * (14496-3 sp04 p217)
- */
-static int sbr_mapping(AACContext *ac, SpectralBandReplication *sbr,
- SBRData *ch_data, int e_a[2])
-{
- int e, i, m;
-
- memset(ch_data->s_indexmapped[1], 0, 7*sizeof(ch_data->s_indexmapped[1]));
- for (e = 0; e < ch_data->bs_num_env; e++) {
- const unsigned int ilim = sbr->n[ch_data->bs_freq_res[e + 1]];
- uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow;
- int k;
-
- if (sbr->kx[1] != table[0]) {
- av_log(ac->avctx, AV_LOG_ERROR, "kx != f_table{high,low}[0]. "
- "Derived frequency tables were not regenerated.\n");
- sbr_turnoff(sbr);
- return AVERROR_BUG;
- }
- for (i = 0; i < ilim; i++)
- for (m = table[i]; m < table[i + 1]; m++)
- sbr->e_origmapped[e][m - sbr->kx[1]] = ch_data->env_facs[e+1][i];
-
- // ch_data->bs_num_noise > 1 => 2 noise floors
- k = (ch_data->bs_num_noise > 1) && (ch_data->t_env[e] >= ch_data->t_q[1]);
- for (i = 0; i < sbr->n_q; i++)
- for (m = sbr->f_tablenoise[i]; m < sbr->f_tablenoise[i + 1]; m++)
- sbr->q_mapped[e][m - sbr->kx[1]] = ch_data->noise_facs[k+1][i];
-
- for (i = 0; i < sbr->n[1]; i++) {
- if (ch_data->bs_add_harmonic_flag) {
- const unsigned int m_midpoint =
- (sbr->f_tablehigh[i] + sbr->f_tablehigh[i + 1]) >> 1;
-
- ch_data->s_indexmapped[e + 1][m_midpoint - sbr->kx[1]] = ch_data->bs_add_harmonic[i] *
- (e >= e_a[1] || (ch_data->s_indexmapped[0][m_midpoint - sbr->kx[1]] == 1));
- }
- }
-
- for (i = 0; i < ilim; i++) {
- int additional_sinusoid_present = 0;
- for (m = table[i]; m < table[i + 1]; m++) {
- if (ch_data->s_indexmapped[e + 1][m - sbr->kx[1]]) {
- additional_sinusoid_present = 1;
- break;
- }
- }
- memset(&sbr->s_mapped[e][table[i] - sbr->kx[1]], additional_sinusoid_present,
- (table[i + 1] - table[i]) * sizeof(sbr->s_mapped[e][0]));
- }
- }
-
- memcpy(ch_data->s_indexmapped[0], ch_data->s_indexmapped[ch_data->bs_num_env], sizeof(ch_data->s_indexmapped[0]));
- return 0;
-}
-
-/// Estimation of current envelope (14496-3 sp04 p218)
-static void sbr_env_estimate(AAC_FLOAT (*e_curr)[48], INTFLOAT X_high[64][40][2],
- SpectralBandReplication *sbr, SBRData *ch_data)
-{
- int e, m;
- int kx1 = sbr->kx[1];
-
- if (sbr->bs_interpol_freq) {
- for (e = 0; e < ch_data->bs_num_env; e++) {
-#if USE_FIXED
- const SoftFloat recip_env_size = av_int2sf(0x20000000 / (ch_data->t_env[e + 1] - ch_data->t_env[e]), 30);
-#else
- const float recip_env_size = 0.5f / (ch_data->t_env[e + 1] - ch_data->t_env[e]);
-#endif /* USE_FIXED */
- int ilb = ch_data->t_env[e] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;
- int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;
-
- for (m = 0; m < sbr->m[1]; m++) {
- AAC_FLOAT sum = sbr->dsp.sum_square(X_high[m+kx1] + ilb, iub - ilb);
-#if USE_FIXED
- e_curr[e][m] = av_mul_sf(sum, recip_env_size);
-#else
- e_curr[e][m] = sum * recip_env_size;
-#endif /* USE_FIXED */
- }
- }
- } else {
- int k, p;
-
- for (e = 0; e < ch_data->bs_num_env; e++) {
- const int env_size = 2 * (ch_data->t_env[e + 1] - ch_data->t_env[e]);
- int ilb = ch_data->t_env[e] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;
- int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;
- const uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow;
-
- for (p = 0; p < sbr->n[ch_data->bs_freq_res[e + 1]]; p++) {
-#if USE_FIXED
- SoftFloat sum = FLOAT_0;
- const SoftFloat den = av_int2sf(0x20000000 / (env_size * (table[p + 1] - table[p])), 29);
- for (k = table[p]; k < table[p + 1]; k++) {
- sum = av_add_sf(sum, sbr->dsp.sum_square(X_high[k] + ilb, iub - ilb));
- }
- sum = av_mul_sf(sum, den);
-#else
- float sum = 0.0f;
- const int den = env_size * (table[p + 1] - table[p]);
-
- for (k = table[p]; k < table[p + 1]; k++) {
- sum += sbr->dsp.sum_square(X_high[k] + ilb, iub - ilb);
- }
- sum /= den;
-#endif /* USE_FIXED */
- for (k = table[p]; k < table[p + 1]; k++) {
- e_curr[e][k - kx1] = sum;
- }
- }
- }
- }
-}
-
-void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
- INTFLOAT* L, INTFLOAT* R)
-{
- int downsampled = ac->oc[1].m4ac.ext_sample_rate < sbr->sample_rate;
- int ch;
- int nch = (id_aac == TYPE_CPE) ? 2 : 1;
- int err;
-
- if (id_aac != sbr->id_aac) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "element type mismatch %d != %d\n", id_aac, sbr->id_aac);
- sbr_turnoff(sbr);
- }
-
- if (sbr->start && !sbr->ready_for_dequant) {
- av_log(ac->avctx, AV_LOG_ERROR,
- "No quantized data read for sbr_dequant.\n");
- sbr_turnoff(sbr);
- }
-
- if (!sbr->kx_and_m_pushed) {
- sbr->kx[0] = sbr->kx[1];
- sbr->m[0] = sbr->m[1];
- } else {
- sbr->kx_and_m_pushed = 0;
- }
-
- if (sbr->start) {
- sbr_dequant(sbr, id_aac);
- sbr->ready_for_dequant = 0;
- }
- for (ch = 0; ch < nch; ch++) {
- /* decode channel */
- sbr_qmf_analysis(ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
- (INTFLOAT*)sbr->qmf_filter_scratch,
- sbr->data[ch].W, sbr->data[ch].Ypos);
- sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low,
- (const INTFLOAT (*)[32][32][2]) sbr->data[ch].W,
- sbr->data[ch].Ypos);
- sbr->data[ch].Ypos ^= 1;
- if (sbr->start) {
- sbr->c.sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1,
- (const INTFLOAT (*)[40][2]) sbr->X_low, sbr->k[0]);
- sbr_chirp(sbr, &sbr->data[ch]);
- av_assert0(sbr->data[ch].bs_num_env > 0);
- sbr_hf_gen(ac, sbr, sbr->X_high,
- (const INTFLOAT (*)[40][2]) sbr->X_low,
- (const INTFLOAT (*)[2]) sbr->alpha0,
- (const INTFLOAT (*)[2]) sbr->alpha1,
- sbr->data[ch].bw_array, sbr->data[ch].t_env,
- sbr->data[ch].bs_num_env);
-
- // hf_adj
- err = sbr_mapping(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
- if (!err) {
- sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]);
- sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
- sbr->c.sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos],
- (const INTFLOAT (*)[40][2]) sbr->X_high,
- sbr, &sbr->data[ch],
- sbr->data[ch].e_a);
- }
- }
-
- /* synthesis */
- sbr->c.sbr_x_gen(sbr, sbr->X[ch],
- (const INTFLOAT (*)[64][2]) sbr->data[ch].Y[1-sbr->data[ch].Ypos],
- (const INTFLOAT (*)[64][2]) sbr->data[ch].Y[ sbr->data[ch].Ypos],
- (const INTFLOAT (*)[40][2]) sbr->X_low, ch);
- }
-
- if (ac->oc[1].m4ac.ps == 1) {
- if (sbr->ps.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]));
- }
- nch = 2;
- }
-
- sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, ac->fdsp,
- L, sbr->X[0], sbr->qmf_filter_scratch,
- sbr->data[0].synthesis_filterbank_samples,
- &sbr->data[0].synthesis_filterbank_samples_offset,
- downsampled);
- if (nch == 2)
- sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, ac->fdsp,
- R, sbr->X[1], sbr->qmf_filter_scratch,
- sbr->data[1].synthesis_filterbank_samples,
- &sbr->data[1].synthesis_filterbank_samples_offset,
- downsampled);
-}
-
-static void aacsbr_func_ptr_init(AACSBRContext *c)
-{
- c->sbr_lf_gen = sbr_lf_gen;
- c->sbr_hf_assemble = sbr_hf_assemble;
- c->sbr_x_gen = sbr_x_gen;
- c->sbr_hf_inverse_filter = sbr_hf_inverse_filter;
-
-#if !USE_FIXED
- if(ARCH_MIPS)
- ff_aacsbr_func_ptr_init_mips(c);
-#endif
-}
diff --git a/ffmpeg-2-8-11/libavcodec/ac3dec.c b/ffmpeg-2-8-11/libavcodec/ac3dec.c
deleted file mode 100644
index 4ad99ce..0000000
--- a/ffmpeg-2-8-11/libavcodec/ac3dec.c
+++ /dev/null
@@ -1,1644 +0,0 @@
-/*
- * AC-3 Audio Decoder
- * This code was developed as part of Google Summer of Code 2006.
- * E-AC-3 support was added as part of Google Summer of Code 2007.
- *
- * Copyright (c) 2006 Kartikey Mahendra BHATT (bhattkm at gmail dot com)
- * Copyright (c) 2007-2008 Bartlomiej Wolowiec <bartek.wolowiec at gmail.com>
- * Copyright (c) 2007 Justin Ruggles <justin.ruggles at gmail.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 <stdio.h>
-#include <stddef.h>
-#include <math.h>
-#include <string.h>
-
-#include "libavutil/channel_layout.h"
-#include "libavutil/crc.h"
-#include "libavutil/downmix_info.h"
-#include "libavutil/opt.h"
-#include "bswapdsp.h"
-#include "internal.h"
-#include "aac_ac3_parser.h"
-#include "ac3_parser.h"
-#include "ac3dec.h"
-#include "ac3dec_data.h"
-#include "kbdwin.h"
-
-/**
- * table for ungrouping 3 values in 7 bits.
- * used for exponents and bap=2 mantissas
- */
-static uint8_t ungroup_3_in_7_bits_tab[128][3];
-
-/** tables for ungrouping mantissas */
-static int b1_mantissas[32][3];
-static int b2_mantissas[128][3];
-static int b3_mantissas[8];
-static int b4_mantissas[128][2];
-static int b5_mantissas[16];
-
-/**
- * Quantization table: levels for symmetric. bits for asymmetric.
- * reference: Table 7.18 Mapping of bap to Quantizer
- */
-static const uint8_t quantization_tab[16] = {
- 0, 3, 5, 7, 11, 15,
- 5, 6, 7, 8, 9, 10, 11, 12, 14, 16
-};
-
-/** dynamic range table. converts codes to scale factors. */
-static float dynamic_range_tab[256];
-static float heavy_dynamic_range_tab[256];
-
-/** Adjustments in dB gain */
-static const float gain_levels[9] = {
- LEVEL_PLUS_3DB,
- LEVEL_PLUS_1POINT5DB,
- LEVEL_ONE,
- LEVEL_MINUS_1POINT5DB,
- LEVEL_MINUS_3DB,
- LEVEL_MINUS_4POINT5DB,
- LEVEL_MINUS_6DB,
- LEVEL_ZERO,
- LEVEL_MINUS_9DB
-};
-
-/** Adjustments in dB gain (LFE, +10 to -21 dB) */
-static const float gain_levels_lfe[32] = {
- 3.162275, 2.818382, 2.511886, 2.238719, 1.995261, 1.778278, 1.584893,
- 1.412536, 1.258924, 1.122018, 1.000000, 0.891251, 0.794328, 0.707946,
- 0.630957, 0.562341, 0.501187, 0.446683, 0.398107, 0.354813, 0.316227,
- 0.281838, 0.251188, 0.223872, 0.199526, 0.177828, 0.158489, 0.141253,
- 0.125892, 0.112201, 0.100000, 0.089125
-};
-
-/**
- * Table for default stereo downmixing coefficients
- * reference: Section 7.8.2 Downmixing Into Two Channels
- */
-static const uint8_t ac3_default_coeffs[8][5][2] = {
- { { 2, 7 }, { 7, 2 }, },
- { { 4, 4 }, },
- { { 2, 7 }, { 7, 2 }, },
- { { 2, 7 }, { 5, 5 }, { 7, 2 }, },
- { { 2, 7 }, { 7, 2 }, { 6, 6 }, },
- { { 2, 7 }, { 5, 5 }, { 7, 2 }, { 8, 8 }, },
- { { 2, 7 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, },
- { { 2, 7 }, { 5, 5 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, },
-};
-
-/**
- * Symmetrical Dequantization
- * reference: Section 7.3.3 Expansion of Mantissas for Symmetrical Quantization
- * Tables 7.19 to 7.23
- */
-static inline int
-symmetric_dequant(int code, int levels)
-{
- return ((code - (levels >> 1)) * (1 << 24)) / levels;
-}
-
-/*
- * Initialize tables at runtime.
- */
-static av_cold void ac3_tables_init(void)
-{
- int i;
-
- /* generate table for ungrouping 3 values in 7 bits
- reference: Section 7.1.3 Exponent Decoding */
- for (i = 0; i < 128; i++) {
- ungroup_3_in_7_bits_tab[i][0] = i / 25;
- ungroup_3_in_7_bits_tab[i][1] = (i % 25) / 5;
- ungroup_3_in_7_bits_tab[i][2] = (i % 25) % 5;
- }
-
- /* generate grouped mantissa tables
- reference: Section 7.3.5 Ungrouping of Mantissas */
- for (i = 0; i < 32; i++) {
- /* bap=1 mantissas */
- b1_mantissas[i][0] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][0], 3);
- b1_mantissas[i][1] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][1], 3);
- b1_mantissas[i][2] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][2], 3);
- }
- for (i = 0; i < 128; i++) {
- /* bap=2 mantissas */
- b2_mantissas[i][0] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][0], 5);
- b2_mantissas[i][1] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][1], 5);
- b2_mantissas[i][2] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][2], 5);
-
- /* bap=4 mantissas */
- b4_mantissas[i][0] = symmetric_dequant(i / 11, 11);
- b4_mantissas[i][1] = symmetric_dequant(i % 11, 11);
- }
- /* generate ungrouped mantissa tables
- reference: Tables 7.21 and 7.23 */
- for (i = 0; i < 7; i++) {
- /* bap=3 mantissas */
- b3_mantissas[i] = symmetric_dequant(i, 7);
- }
- for (i = 0; i < 15; i++) {
- /* bap=5 mantissas */
- b5_mantissas[i] = symmetric_dequant(i, 15);
- }
-
- /* generate dynamic range table
- reference: Section 7.7.1 Dynamic Range Control */
- for (i = 0; i < 256; i++) {
- int v = (i >> 5) - ((i >> 7) << 3) - 5;
- dynamic_range_tab[i] = powf(2.0f, v) * ((i & 0x1F) | 0x20);
- }
-
- /* generate compr dynamic range table
- reference: Section 7.7.2 Heavy Compression */
- for (i = 0; i < 256; i++) {
- int v = (i >> 4) - ((i >> 7) << 4) - 4;
- heavy_dynamic_range_tab[i] = powf(2.0f, v) * ((i & 0xF) | 0x10);
- }
-
-}
-
-/**
- * AVCodec initialization
- */
-static av_cold int ac3_decode_init(AVCodecContext *avctx)
-{
- AC3DecodeContext *s = avctx->priv_data;
- int i;
-
- s->avctx = avctx;
-
- ff_ac3_common_init();
- ac3_tables_init();
- ff_mdct_init(&s->imdct_256, 8, 1, 1.0);
- ff_mdct_init(&s->imdct_512, 9, 1, 1.0);
- 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);
-#endif
-
- ff_ac3dsp_init(&s->ac3dsp, avctx->flags & AV_CODEC_FLAG_BITEXACT);
- av_lfg_init(&s->dith_state, 0);
-
- if (USE_FIXED)
- avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
- else
- avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
-
- /* allow downmixing to stereo or mono */
-#if FF_API_REQUEST_CHANNELS
-FF_DISABLE_DEPRECATION_WARNINGS
- if (avctx->request_channels == 1)
- avctx->request_channel_layout = AV_CH_LAYOUT_MONO;
- else if (avctx->request_channels == 2)
- avctx->request_channel_layout = AV_CH_LAYOUT_STEREO;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- if (avctx->channels > 1 &&
- avctx->request_channel_layout == AV_CH_LAYOUT_MONO)
- avctx->channels = 1;
- else if (avctx->channels > 2 &&
- avctx->request_channel_layout == AV_CH_LAYOUT_STEREO)
- avctx->channels = 2;
- s->downmixed = 1;
-
- for (i = 0; i < AC3_MAX_CHANNELS; i++) {
- s->xcfptr[i] = s->transform_coeffs[i];
- s->dlyptr[i] = s->delay[i];
- }
-
- return 0;
-}
-
-/**
- * Parse the 'sync info' and 'bit stream info' from the AC-3 bitstream.
- * GetBitContext within AC3DecodeContext must point to
- * the start of the synchronized AC-3 bitstream.
- */
-static int ac3_parse_header(AC3DecodeContext *s)
-{
- GetBitContext *gbc = &s->gbc;
- int i;
-
- /* read the rest of the bsi. read twice for dual mono mode. */
- i = !s->channel_mode;
- do {
- s->dialog_normalization[(!s->channel_mode)-i] = -get_bits(gbc, 5);
- if (s->dialog_normalization[(!s->channel_mode)-i] == 0) {
- s->dialog_normalization[(!s->channel_mode)-i] = -31;
- }
- if (s->target_level != 0) {
- s->level_gain[(!s->channel_mode)-i] = powf(2.0f,
- (float)(s->target_level -
- s->dialog_normalization[(!s->channel_mode)-i])/6.0f);
- }
- if (s->compression_exists[(!s->channel_mode)-i] = get_bits1(gbc)) {
- s->heavy_dynamic_range[(!s->channel_mode)-i] =
- AC3_HEAVY_RANGE(get_bits(gbc, 8));
- }
- if (get_bits1(gbc))
- skip_bits(gbc, 8); //skip language code
- if (get_bits1(gbc))
- skip_bits(gbc, 7); //skip audio production information
- } while (i--);
-
- skip_bits(gbc, 2); //skip copyright bit and original bitstream bit
-
- /* skip the timecodes or parse the Alternate Bit Stream Syntax */
- if (s->bitstream_id != 6) {
- if (get_bits1(gbc))
- skip_bits(gbc, 14); //skip timecode1
- if (get_bits1(gbc))
- skip_bits(gbc, 14); //skip timecode2
- } else {
- if (get_bits1(gbc)) {
- s->preferred_downmix = get_bits(gbc, 2);
- s->center_mix_level_ltrt = get_bits(gbc, 3);
- s->surround_mix_level_ltrt = av_clip(get_bits(gbc, 3), 3, 7);
- s->center_mix_level = get_bits(gbc, 3);
- s->surround_mix_level = av_clip(get_bits(gbc, 3), 3, 7);
- }
- if (get_bits1(gbc)) {
- s->dolby_surround_ex_mode = get_bits(gbc, 2);
- s->dolby_headphone_mode = get_bits(gbc, 2);
- skip_bits(gbc, 10); // skip adconvtyp (1), xbsi2 (8), encinfo (1)
- }
- }
-
- /* skip additional bitstream info */
- if (get_bits1(gbc)) {
- i = get_bits(gbc, 6);
- do {
- skip_bits(gbc, 8);
- } while (i--);
- }
-
- return 0;
-}
-
-/**
- * Common function to parse AC-3 or E-AC-3 frame header
- */
-static int parse_frame_header(AC3DecodeContext *s)
-{
- AC3HeaderInfo hdr, *phdr=&hdr;
- int err;
-
- err = avpriv_ac3_parse_header2(&s->gbc, &phdr);
- if (err)
- return err;
-
- /* get decoding parameters from header info */
- s->bit_alloc_params.sr_code = hdr.sr_code;
- s->bitstream_id = hdr.bitstream_id;
- s->bitstream_mode = hdr.bitstream_mode;
- s->channel_mode = hdr.channel_mode;
- s->lfe_on = hdr.lfe_on;
- s->bit_alloc_params.sr_shift = hdr.sr_shift;
- s->sample_rate = hdr.sample_rate;
- s->bit_rate = hdr.bit_rate;
- s->channels = hdr.channels;
- s->fbw_channels = s->channels - s->lfe_on;
- s->lfe_ch = s->fbw_channels + 1;
- s->frame_size = hdr.frame_size;
- s->preferred_downmix = AC3_DMIXMOD_NOTINDICATED;
- s->center_mix_level = hdr.center_mix_level;
- s->center_mix_level_ltrt = 4; // -3.0dB
- s->surround_mix_level = hdr.surround_mix_level;
- s->surround_mix_level_ltrt = 4; // -3.0dB
- s->lfe_mix_level_exists = 0;
- s->num_blocks = hdr.num_blocks;
- s->frame_type = hdr.frame_type;
- s->substreamid = hdr.substreamid;
- s->dolby_surround_mode = hdr.dolby_surround_mode;
- s->dolby_surround_ex_mode = AC3_DSUREXMOD_NOTINDICATED;
- s->dolby_headphone_mode = AC3_DHEADPHONMOD_NOTINDICATED;
-
- if (s->lfe_on) {
- s->start_freq[s->lfe_ch] = 0;
- s->end_freq[s->lfe_ch] = 7;
- s->num_exp_groups[s->lfe_ch] = 2;
- s->channel_in_cpl[s->lfe_ch] = 0;
- }
-
- if (s->bitstream_id <= 10) {
- s->eac3 = 0;
- s->snr_offset_strategy = 2;
- s->block_switch_syntax = 1;
- s->dither_flag_syntax = 1;
- s->bit_allocation_syntax = 1;
- s->fast_gain_syntax = 0;
- s->first_cpl_leak = 0;
- s->dba_syntax = 1;
- s->skip_syntax = 1;
- memset(s->channel_uses_aht, 0, sizeof(s->channel_uses_aht));
- return ac3_parse_header(s);
- } else if (CONFIG_EAC3_DECODER) {
- s->eac3 = 1;
- return ff_eac3_parse_header(s);
- } else {
- av_log(s->avctx, AV_LOG_ERROR, "E-AC-3 support not compiled in\n");
- return AVERROR(ENOSYS);
- }
-}
-
-/**
- * Set stereo downmixing coefficients based on frame header info.
- * reference: Section 7.8.2 Downmixing Into Two Channels
- */
-static void set_downmix_coeffs(AC3DecodeContext *s)
-{
- int i;
- float cmix = gain_levels[s-> center_mix_level];
- float smix = gain_levels[s->surround_mix_level];
- float norm0, norm1;
- float downmix_coeffs[AC3_MAX_CHANNELS][2];
-
- for (i = 0; i < s->fbw_channels; i++) {
- downmix_coeffs[i][0] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]];
- downmix_coeffs[i][1] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]];
- }
- if (s->channel_mode > 1 && s->channel_mode & 1) {
- downmix_coeffs[1][0] = downmix_coeffs[1][1] = cmix;
- }
- if (s->channel_mode == AC3_CHMODE_2F1R || s->channel_mode == AC3_CHMODE_3F1R) {
- int nf = s->channel_mode - 2;
- downmix_coeffs[nf][0] = downmix_coeffs[nf][1] = smix * LEVEL_MINUS_3DB;
- }
- if (s->channel_mode == AC3_CHMODE_2F2R || s->channel_mode == AC3_CHMODE_3F2R) {
- int nf = s->channel_mode - 4;
- downmix_coeffs[nf][0] = downmix_coeffs[nf+1][1] = smix;
- }
-
- /* renormalize */
- norm0 = norm1 = 0.0;
- for (i = 0; i < s->fbw_channels; i++) {
- norm0 += downmix_coeffs[i][0];
- norm1 += downmix_coeffs[i][1];
- }
- norm0 = 1.0f / norm0;
- norm1 = 1.0f / norm1;
- for (i = 0; i < s->fbw_channels; i++) {
- downmix_coeffs[i][0] *= norm0;
- downmix_coeffs[i][1] *= norm1;
- }
-
- if (s->output_mode == AC3_CHMODE_MONO) {
- for (i = 0; i < s->fbw_channels; i++)
- downmix_coeffs[i][0] = (downmix_coeffs[i][0] +
- downmix_coeffs[i][1]) * LEVEL_MINUS_3DB;
- }
- for (i = 0; i < s->fbw_channels; i++) {
- s->downmix_coeffs[i][0] = FIXR12(downmix_coeffs[i][0]);
- s->downmix_coeffs[i][1] = FIXR12(downmix_coeffs[i][1]);
- }
-}
-
-/**
- * Decode the grouped exponents according to exponent strategy.
- * reference: Section 7.1.3 Exponent Decoding
- */
-static int decode_exponents(GetBitContext *gbc, int exp_strategy, int ngrps,
- uint8_t absexp, int8_t *dexps)
-{
- int i, j, grp, group_size;
- int dexp[256];
- int expacc, prevexp;
-
- /* unpack groups */
- group_size = exp_strategy + (exp_strategy == EXP_D45);
- for (grp = 0, i = 0; grp < ngrps; grp++) {
- expacc = get_bits(gbc, 7);
- dexp[i++] = ungroup_3_in_7_bits_tab[expacc][0];
- dexp[i++] = ungroup_3_in_7_bits_tab[expacc][1];
- dexp[i++] = ungroup_3_in_7_bits_tab[expacc][2];
- }
-
- /* convert to absolute exps and expand groups */
- prevexp = absexp;
- for (i = 0, j = 0; i < ngrps * 3; i++) {
- prevexp += dexp[i] - 2;
- if (prevexp > 24U)
- return -1;
- switch (group_size) {
- case 4: dexps[j++] = prevexp;
- dexps[j++] = prevexp;
- case 2: dexps[j++] = prevexp;
- case 1: dexps[j++] = prevexp;
- }
- }
- return 0;
-}
-
-/**
- * Generate transform coefficients for each coupled channel in the coupling
- * range using the coupling coefficients and coupling coordinates.
- * reference: Section 7.4.3 Coupling Coordinate Format
- */
-static void calc_transform_coeffs_cpl(AC3DecodeContext *s)
-{
- int bin, band, ch;
-
- bin = s->start_freq[CPL_CH];
- for (band = 0; band < s->num_cpl_bands; band++) {
- int band_start = bin;
- int band_end = bin + s->cpl_band_sizes[band];
- for (ch = 1; ch <= s->fbw_channels; ch++) {
- if (s->channel_in_cpl[ch]) {
- int cpl_coord = s->cpl_coords[ch][band] << 5;
- for (bin = band_start; bin < band_end; bin++) {
- s->fixed_coeffs[ch][bin] =
- MULH(s->fixed_coeffs[CPL_CH][bin] * (1 << 4), cpl_coord);
- }
- if (ch == 2 && s->phase_flags[band]) {
- for (bin = band_start; bin < band_end; bin++)
- s->fixed_coeffs[2][bin] = -s->fixed_coeffs[2][bin];
- }
- }
- }
- bin = band_end;
- }
-}
-
-/**
- * Grouped mantissas for 3-level 5-level and 11-level quantization
- */
-typedef struct mant_groups {
- int b1_mant[2];
- int b2_mant[2];
- int b4_mant;
- int b1;
- int b2;
- int b4;
-} mant_groups;
-
-/**
- * Decode the transform coefficients for a particular channel
- * reference: Section 7.3 Quantization and Decoding of Mantissas
- */
-static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, mant_groups *m)
-{
- int start_freq = s->start_freq[ch_index];
- int end_freq = s->end_freq[ch_index];
- uint8_t *baps = s->bap[ch_index];
- int8_t *exps = s->dexps[ch_index];
- int32_t *coeffs = s->fixed_coeffs[ch_index];
- int dither = (ch_index == CPL_CH) || s->dither_flag[ch_index];
- GetBitContext *gbc = &s->gbc;
- int freq;
-
- for (freq = start_freq; freq < end_freq; freq++) {
- int bap = baps[freq];
- int mantissa;
- switch (bap) {
- case 0:
- /* random noise with approximate range of -0.707 to 0.707 */
- if (dither)
- mantissa = (((av_lfg_get(&s->dith_state)>>8)*181)>>8) - 5931008;
- else
- mantissa = 0;
- break;
- case 1:
- if (m->b1) {
- m->b1--;
- mantissa = m->b1_mant[m->b1];
- } else {
- int bits = get_bits(gbc, 5);
- mantissa = b1_mantissas[bits][0];
- m->b1_mant[1] = b1_mantissas[bits][1];
- m->b1_mant[0] = b1_mantissas[bits][2];
- m->b1 = 2;
- }
- break;
- case 2:
- if (m->b2) {
- m->b2--;
- mantissa = m->b2_mant[m->b2];
- } else {
- int bits = get_bits(gbc, 7);
- mantissa = b2_mantissas[bits][0];
- m->b2_mant[1] = b2_mantissas[bits][1];
- m->b2_mant[0] = b2_mantissas[bits][2];
- m->b2 = 2;
- }
- break;
- case 3:
- mantissa = b3_mantissas[get_bits(gbc, 3)];
- break;
- case 4:
- if (m->b4) {
- m->b4 = 0;
- mantissa = m->b4_mant;
- } else {
- int bits = get_bits(gbc, 7);
- mantissa = b4_mantissas[bits][0];
- m->b4_mant = b4_mantissas[bits][1];
- m->b4 = 1;
- }
- break;
- case 5:
- mantissa = b5_mantissas[get_bits(gbc, 4)];
- break;
- default: /* 6 to 15 */
- /* Shift mantissa and sign-extend it. */
- if (bap > 15) {
- av_log(s->avctx, AV_LOG_ERROR, "bap %d is invalid in plain AC-3\n", bap);
- bap = 15;
- }
- mantissa = (unsigned)get_sbits(gbc, quantization_tab[bap]) << (24 - quantization_tab[bap]);
- break;
- }
- coeffs[freq] = mantissa >> exps[freq];
- }
-}
-
-/**
- * Remove random dithering from coupling range coefficients with zero-bit
- * mantissas for coupled channels which do not use dithering.
- * reference: Section 7.3.4 Dither for Zero Bit Mantissas (bap=0)
- */
-static void remove_dithering(AC3DecodeContext *s) {
- int ch, i;
-
- for (ch = 1; ch <= s->fbw_channels; ch++) {
- if (!s->dither_flag[ch] && s->channel_in_cpl[ch]) {
- for (i = s->start_freq[CPL_CH]; i < s->end_freq[CPL_CH]; i++) {
- if (!s->bap[CPL_CH][i])
- s->fixed_coeffs[ch][i] = 0;
- }
- }
- }
-}
-
-static void decode_transform_coeffs_ch(AC3DecodeContext *s, int blk, int ch,
- mant_groups *m)
-{
- if (!s->channel_uses_aht[ch]) {
- ac3_decode_transform_coeffs_ch(s, ch, m);
- } else {
- /* if AHT is used, mantissas for all blocks are encoded in the first
- block of the frame. */
- int bin;
- if (CONFIG_EAC3_DECODER && !blk)
- ff_eac3_decode_transform_coeffs_aht_ch(s, ch);
- for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
- s->fixed_coeffs[ch][bin] = s->pre_mantissa[ch][bin][blk] >> s->dexps[ch][bin];
- }
- }
-}
-
-/**
- * Decode the transform coefficients.
- */
-static void decode_transform_coeffs(AC3DecodeContext *s, int blk)
-{
- int ch, end;
- int got_cplchan = 0;
- mant_groups m;
-
- m.b1 = m.b2 = m.b4 = 0;
-
- for (ch = 1; ch <= s->channels; ch++) {
- /* transform coefficients for full-bandwidth channel */
- decode_transform_coeffs_ch(s, blk, ch, &m);
- /* transform coefficients for coupling channel come right after the
- coefficients for the first coupled channel*/
- if (s->channel_in_cpl[ch]) {
- if (!got_cplchan) {
- decode_transform_coeffs_ch(s, blk, CPL_CH, &m);
- calc_transform_coeffs_cpl(s);
- got_cplchan = 1;
- }
- end = s->end_freq[CPL_CH];
- } else {
- end = s->end_freq[ch];
- }
- do
- s->fixed_coeffs[ch][end] = 0;
- while (++end < 256);
- }
-
- /* zero the dithered coefficients for appropriate channels */
- remove_dithering(s);
-}
-
-/**
- * Stereo rematrixing.
- * reference: Section 7.5.4 Rematrixing : Decoding Technique
- */
-static void do_rematrixing(AC3DecodeContext *s)
-{
- int bnd, i;
- int end, bndend;
-
- end = FFMIN(s->end_freq[1], s->end_freq[2]);
-
- for (bnd = 0; bnd < s->num_rematrixing_bands; bnd++) {
- if (s->rematrixing_flags[bnd]) {
- bndend = FFMIN(end, ff_ac3_rematrix_band_tab[bnd + 1]);
- for (i = ff_ac3_rematrix_band_tab[bnd]; i < bndend; i++) {
- int tmp0 = s->fixed_coeffs[1][i];
- s->fixed_coeffs[1][i] += s->fixed_coeffs[2][i];
- s->fixed_coeffs[2][i] = tmp0 - s->fixed_coeffs[2][i];
- }
- }
- }
-}
-
-/**
- * Inverse MDCT Transform.
- * Convert frequency domain coefficients to time-domain audio samples.
- * reference: Section 7.9.4 Transformation Equations
- */
-static inline void do_imdct(AC3DecodeContext *s, int channels)
-{
- int ch;
-
- for (ch = 1; ch <= channels; ch++) {
- if (s->block_switch[ch]) {
- int i;
- FFTSample *x = s->tmp_output + 128;
- for (i = 0; i < 128; i++)
- x[i] = s->transform_coeffs[ch][2 * i];
- s->imdct_256.imdct_half(&s->imdct_256, s->tmp_output, x);
-#if USE_FIXED
- s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1],
- s->tmp_output, s->window, 128, 8);
-#else
- s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
- s->tmp_output, s->window, 128);
-#endif
- for (i = 0; i < 128; i++)
- x[i] = s->transform_coeffs[ch][2 * i + 1];
- s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch - 1], x);
- } else {
- s->imdct_512.imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]);
-#if USE_FIXED
- s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1],
- s->tmp_output, s->window, 128, 8);
-#else
- s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
- s->tmp_output, s->window, 128);
-#endif
- memcpy(s->delay[ch - 1], s->tmp_output + 128, 128 * sizeof(FFTSample));
- }
- }
-}
-
-/**
- * Upmix delay samples from stereo to original channel layout.
- */
-static void ac3_upmix_delay(AC3DecodeContext *s)
-{
- int channel_data_size = sizeof(s->delay[0]);
- switch (s->channel_mode) {
- case AC3_CHMODE_DUALMONO:
- case AC3_CHMODE_STEREO:
- /* upmix mono to stereo */
- memcpy(s->delay[1], s->delay[0], channel_data_size);
- break;
- case AC3_CHMODE_2F2R:
- memset(s->delay[3], 0, channel_data_size);
- case AC3_CHMODE_2F1R:
- memset(s->delay[2], 0, channel_data_size);
- break;
- case AC3_CHMODE_3F2R:
- memset(s->delay[4], 0, channel_data_size);
- case AC3_CHMODE_3F1R:
- memset(s->delay[3], 0, channel_data_size);
- case AC3_CHMODE_3F:
- memcpy(s->delay[2], s->delay[1], channel_data_size);
- memset(s->delay[1], 0, channel_data_size);
- break;
- }
-}
-
-/**
- * Decode band structure for coupling, spectral extension, or enhanced coupling.
- * The band structure defines how many subbands are in each band. For each
- * subband in the range, 1 means it is combined with the previous band, and 0
- * means that it starts a new band.
- *
- * @param[in] gbc bit reader context
- * @param[in] blk block number
- * @param[in] eac3 flag to indicate E-AC-3
- * @param[in] ecpl flag to indicate enhanced coupling
- * @param[in] start_subband subband number for start of range
- * @param[in] end_subband subband number for end of range
- * @param[in] default_band_struct default band structure table
- * @param[out] num_bands number of bands (optionally NULL)
- * @param[out] band_sizes array containing the number of bins in each band (optionally NULL)
- */
-static void decode_band_structure(GetBitContext *gbc, int blk, int eac3,
- int ecpl, int start_subband, int end_subband,
- const uint8_t *default_band_struct,
- int *num_bands, uint8_t *band_sizes)
-{
- int subbnd, bnd, n_subbands, n_bands=0;
- uint8_t bnd_sz[22];
- uint8_t coded_band_struct[22];
- const uint8_t *band_struct;
-
- n_subbands = end_subband - start_subband;
-
- /* decode band structure from bitstream or use default */
- if (!eac3 || get_bits1(gbc)) {
- for (subbnd = 0; subbnd < n_subbands - 1; subbnd++) {
- coded_band_struct[subbnd] = get_bits1(gbc);
- }
- band_struct = coded_band_struct;
- } else if (!blk) {
- band_struct = &default_band_struct[start_subband+1];
- } else {
- /* no change in band structure */
- return;
- }
-
- /* calculate number of bands and band sizes based on band structure.
- note that the first 4 subbands in enhanced coupling span only 6 bins
- instead of 12. */
- if (num_bands || band_sizes ) {
- n_bands = n_subbands;
- bnd_sz[0] = ecpl ? 6 : 12;
- for (bnd = 0, subbnd = 1; subbnd < n_subbands; subbnd++) {
- int subbnd_size = (ecpl && subbnd < 4) ? 6 : 12;
- if (band_struct[subbnd - 1]) {
- n_bands--;
- bnd_sz[bnd] += subbnd_size;
- } else {
- bnd_sz[++bnd] = subbnd_size;
- }
- }
- }
-
- /* set optional output params */
- if (num_bands)
- *num_bands = n_bands;
- if (band_sizes)
- memcpy(band_sizes, bnd_sz, n_bands);
-}
-
-/**
- * Decode a single audio block from the AC-3 bitstream.
- */
-static int decode_audio_block(AC3DecodeContext *s, int blk)
-{
- int fbw_channels = s->fbw_channels;
- int channel_mode = s->channel_mode;
- int i, bnd, seg, ch;
- int different_transforms;
- int downmix_output;
- int cpl_in_use;
- GetBitContext *gbc = &s->gbc;
- uint8_t bit_alloc_stages[AC3_MAX_CHANNELS] = { 0 };
-
- /* block switch flags */
- different_transforms = 0;
- if (s->block_switch_syntax) {
- for (ch = 1; ch <= fbw_channels; ch++) {
- s->block_switch[ch] = get_bits1(gbc);
- if (ch > 1 && s->block_switch[ch] != s->block_switch[1])
- different_transforms = 1;
- }
- }
-
- /* dithering flags */
- if (s->dither_flag_syntax) {
- for (ch = 1; ch <= fbw_channels; ch++) {
- s->dither_flag[ch] = get_bits1(gbc);
- }
- }
-
- /* dynamic range */
- i = !s->channel_mode;
- do {
- if (get_bits1(gbc)) {
- /* Allow asymmetric application of DRC when drc_scale > 1.
- Amplification of quiet sounds is enhanced */
- int range_bits = get_bits(gbc, 8);
- INTFLOAT range = AC3_RANGE(range_bits);
- if (range_bits <= 127 || s->drc_scale <= 1.0)
- s->dynamic_range[i] = AC3_DYNAMIC_RANGE(range);
- else
- s->dynamic_range[i] = range;
- } else if (blk == 0) {
- s->dynamic_range[i] = AC3_DYNAMIC_RANGE1;
- }
- } while (i--);
-
- /* spectral extension strategy */
- if (s->eac3 && (!blk || get_bits1(gbc))) {
- s->spx_in_use = get_bits1(gbc);
- if (s->spx_in_use) {
- int dst_start_freq, dst_end_freq, src_start_freq,
- start_subband, end_subband;
-
- /* determine which channels use spx */
- if (s->channel_mode == AC3_CHMODE_MONO) {
- s->channel_uses_spx[1] = 1;
- } else {
- for (ch = 1; ch <= fbw_channels; ch++)
- s->channel_uses_spx[ch] = get_bits1(gbc);
- }
-
- /* get the frequency bins of the spx copy region and the spx start
- and end subbands */
- dst_start_freq = get_bits(gbc, 2);
- start_subband = get_bits(gbc, 3) + 2;
- if (start_subband > 7)
- start_subband += start_subband - 7;
- end_subband = get_bits(gbc, 3) + 5;
-#if USE_FIXED
- s->spx_dst_end_freq = end_freq_inv_tab[end_subband-5];
-#endif
- if (end_subband > 7)
- end_subband += end_subband - 7;
- dst_start_freq = dst_start_freq * 12 + 25;
- src_start_freq = start_subband * 12 + 25;
- dst_end_freq = end_subband * 12 + 25;
-
- /* check validity of spx ranges */
- if (start_subband >= end_subband) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension "
- "range (%d >= %d)\n", start_subband, end_subband);
- return AVERROR_INVALIDDATA;
- }
- if (dst_start_freq >= src_start_freq) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension "
- "copy start bin (%d >= %d)\n", dst_start_freq, src_start_freq);
- return AVERROR_INVALIDDATA;
- }
-
- s->spx_dst_start_freq = dst_start_freq;
- s->spx_src_start_freq = src_start_freq;
- if (!USE_FIXED)
- s->spx_dst_end_freq = dst_end_freq;
-
- decode_band_structure(gbc, blk, s->eac3, 0,
- start_subband, end_subband,
- ff_eac3_default_spx_band_struct,
- &s->num_spx_bands,
- s->spx_band_sizes);
- }
- }
- if (!s->eac3 || !s->spx_in_use) {
- s->spx_in_use = 0;
- for (ch = 1; ch <= fbw_channels; ch++) {
- s->channel_uses_spx[ch] = 0;
- s->first_spx_coords[ch] = 1;
- }
- }
-
- /* spectral extension coordinates */
- if (s->spx_in_use) {
- for (ch = 1; ch <= fbw_channels; ch++) {
- if (s->channel_uses_spx[ch]) {
- if (s->first_spx_coords[ch] || get_bits1(gbc)) {
- INTFLOAT spx_blend;
- int bin, master_spx_coord;
-
- s->first_spx_coords[ch] = 0;
- spx_blend = AC3_SPX_BLEND(get_bits(gbc, 5));
- master_spx_coord = get_bits(gbc, 2) * 3;
-
- bin = s->spx_src_start_freq;
- for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
- int bandsize = s->spx_band_sizes[bnd];
- int spx_coord_exp, spx_coord_mant;
- INTFLOAT nratio, sblend, nblend;
-#if USE_FIXED
- /* calculate blending factors */
- int64_t accu = ((bin << 23) + (bandsize << 22))
- * (int64_t)s->spx_dst_end_freq;
- nratio = (int)(accu >> 32);
- nratio -= spx_blend << 18;
-
- if (nratio < 0) {
- nblend = 0;
- sblend = 0x800000;
- } else if (nratio > 0x7fffff) {
- nblend = 14529495; // sqrt(3) in FP.23
- sblend = 0;
- } else {
- nblend = fixed_sqrt(nratio, 23);
- accu = (int64_t)nblend * 1859775393;
- nblend = (int)((accu + (1<<29)) >> 30);
- sblend = fixed_sqrt(0x800000 - nratio, 23);
- }
-#else
- float spx_coord;
-
- /* calculate blending factors */
- nratio = ((float)((bin + (bandsize >> 1))) / s->spx_dst_end_freq) - spx_blend;
- nratio = av_clipf(nratio, 0.0f, 1.0f);
- nblend = sqrtf(3.0f * nratio); // noise is scaled by sqrt(3)
- // to give unity variance
- sblend = sqrtf(1.0f - nratio);
-#endif
- bin += bandsize;
-
- /* decode spx coordinates */
- spx_coord_exp = get_bits(gbc, 4);
- spx_coord_mant = get_bits(gbc, 2);
- if (spx_coord_exp == 15) spx_coord_mant <<= 1;
- else spx_coord_mant += 4;
- spx_coord_mant <<= (25 - spx_coord_exp - master_spx_coord);
-
- /* multiply noise and signal blending factors by spx coordinate */
-#if USE_FIXED
- accu = (int64_t)nblend * spx_coord_mant;
- s->spx_noise_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23);
- accu = (int64_t)sblend * spx_coord_mant;
- s->spx_signal_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23);
-#else
- spx_coord = spx_coord_mant * (1.0f / (1 << 23));
- s->spx_noise_blend [ch][bnd] = nblend * spx_coord;
- s->spx_signal_blend[ch][bnd] = sblend * spx_coord;
-#endif
- }
- }
- } else {
- s->first_spx_coords[ch] = 1;
- }
- }
- }
-
- /* coupling strategy */
- if (s->eac3 ? s->cpl_strategy_exists[blk] : get_bits1(gbc)) {
- memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS);
- if (!s->eac3)
- s->cpl_in_use[blk] = get_bits1(gbc);
- if (s->cpl_in_use[blk]) {
- /* coupling in use */
- int cpl_start_subband, cpl_end_subband;
-
- if (channel_mode < AC3_CHMODE_STEREO) {
- av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n");
- return AVERROR_INVALIDDATA;
- }
-
- /* check for enhanced coupling */
- if (s->eac3 && get_bits1(gbc)) {
- /* TODO: parse enhanced coupling strategy info */
- avpriv_request_sample(s->avctx, "Enhanced coupling");
- return AVERROR_PATCHWELCOME;
- }
-
- /* determine which channels are coupled */
- if (s->eac3 && s->channel_mode == AC3_CHMODE_STEREO) {
- s->channel_in_cpl[1] = 1;
- s->channel_in_cpl[2] = 1;
- } else {
- for (ch = 1; ch <= fbw_channels; ch++)
- s->channel_in_cpl[ch] = get_bits1(gbc);
- }
-
- /* phase flags in use */
- if (channel_mode == AC3_CHMODE_STEREO)
- s->phase_flags_in_use = get_bits1(gbc);
-
- /* coupling frequency range */
- cpl_start_subband = get_bits(gbc, 4);
- cpl_end_subband = s->spx_in_use ? (s->spx_src_start_freq - 37) / 12 :
- get_bits(gbc, 4) + 3;
- if (cpl_start_subband >= cpl_end_subband) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d >= %d)\n",
- cpl_start_subband, cpl_end_subband);
- return AVERROR_INVALIDDATA;
- }
- s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37;
- s->end_freq[CPL_CH] = cpl_end_subband * 12 + 37;
-
- decode_band_structure(gbc, blk, s->eac3, 0, cpl_start_subband,
- cpl_end_subband,
- ff_eac3_default_cpl_band_struct,
- &s->num_cpl_bands, s->cpl_band_sizes);
- } else {
- /* coupling not in use */
- for (ch = 1; ch <= fbw_channels; ch++) {
- s->channel_in_cpl[ch] = 0;
- s->first_cpl_coords[ch] = 1;
- }
- s->first_cpl_leak = s->eac3;
- s->phase_flags_in_use = 0;
- }
- } else if (!s->eac3) {
- if (!blk) {
- av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must "
- "be present in block 0\n");
- return AVERROR_INVALIDDATA;
- } else {
- s->cpl_in_use[blk] = s->cpl_in_use[blk-1];
- }
- }
- cpl_in_use = s->cpl_in_use[blk];
-
- /* coupling coordinates */
- if (cpl_in_use) {
- int cpl_coords_exist = 0;
-
- for (ch = 1; ch <= fbw_channels; ch++) {
- if (s->channel_in_cpl[ch]) {
- if ((s->eac3 && s->first_cpl_coords[ch]) || get_bits1(gbc)) {
- int master_cpl_coord, cpl_coord_exp, cpl_coord_mant;
- s->first_cpl_coords[ch] = 0;
- cpl_coords_exist = 1;
- master_cpl_coord = 3 * get_bits(gbc, 2);
- for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
- cpl_coord_exp = get_bits(gbc, 4);
- cpl_coord_mant = get_bits(gbc, 4);
- if (cpl_coord_exp == 15)
- s->cpl_coords[ch][bnd] = cpl_coord_mant << 22;
- else
- s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16) << 21;
- s->cpl_coords[ch][bnd] >>= (cpl_coord_exp + master_cpl_coord);
- }
- } else if (!blk) {
- av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must "
- "be present in block 0\n");
- return AVERROR_INVALIDDATA;
- }
- } else {
- /* channel not in coupling */
- s->first_cpl_coords[ch] = 1;
- }
- }
- /* phase flags */
- if (channel_mode == AC3_CHMODE_STEREO && cpl_coords_exist) {
- for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
- s->phase_flags[bnd] = s->phase_flags_in_use? get_bits1(gbc) : 0;
- }
- }
- }
-
- /* stereo rematrixing strategy and band structure */
- if (channel_mode == AC3_CHMODE_STEREO) {
- if ((s->eac3 && !blk) || get_bits1(gbc)) {
- s->num_rematrixing_bands = 4;
- if (cpl_in_use && s->start_freq[CPL_CH] <= 61) {
- s->num_rematrixing_bands -= 1 + (s->start_freq[CPL_CH] == 37);
- } else if (s->spx_in_use && s->spx_src_start_freq <= 61) {
- s->num_rematrixing_bands--;
- }
- for (bnd = 0; bnd < s->num_rematrixing_bands; bnd++)
- s->rematrixing_flags[bnd] = get_bits1(gbc);
- } else if (!blk) {
- av_log(s->avctx, AV_LOG_WARNING, "Warning: "
- "new rematrixing strategy not present in block 0\n");
- s->num_rematrixing_bands = 0;
- }
- }
-
- /* exponent strategies for each channel */
- for (ch = !cpl_in_use; ch <= s->channels; ch++) {
- if (!s->eac3)
- s->exp_strategy[blk][ch] = get_bits(gbc, 2 - (ch == s->lfe_ch));
- if (s->exp_strategy[blk][ch] != EXP_REUSE)
- bit_alloc_stages[ch] = 3;
- }
-
- /* channel bandwidth */
- for (ch = 1; ch <= fbw_channels; ch++) {
- s->start_freq[ch] = 0;
- if (s->exp_strategy[blk][ch] != EXP_REUSE) {
- int group_size;
- int prev = s->end_freq[ch];
- if (s->channel_in_cpl[ch])
- s->end_freq[ch] = s->start_freq[CPL_CH];
- else if (s->channel_uses_spx[ch])
- s->end_freq[ch] = s->spx_src_start_freq;
- else {
- int bandwidth_code = get_bits(gbc, 6);
- if (bandwidth_code > 60) {
- av_log(s->avctx, AV_LOG_ERROR, "bandwidth code = %d > 60\n", bandwidth_code);
- return AVERROR_INVALIDDATA;
- }
- s->end_freq[ch] = bandwidth_code * 3 + 73;
- }
- group_size = 3 << (s->exp_strategy[blk][ch] - 1);
- s->num_exp_groups[ch] = (s->end_freq[ch] + group_size-4) / group_size;
- if (blk > 0 && s->end_freq[ch] != prev)
- memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS);
- }
- }
- if (cpl_in_use && s->exp_strategy[blk][CPL_CH] != EXP_REUSE) {
- s->num_exp_groups[CPL_CH] = (s->end_freq[CPL_CH] - s->start_freq[CPL_CH]) /
- (3 << (s->exp_strategy[blk][CPL_CH] - 1));
- }
-
- /* decode exponents for each channel */
- for (ch = !cpl_in_use; ch <= s->channels; ch++) {
- if (s->exp_strategy[blk][ch] != EXP_REUSE) {
- s->dexps[ch][0] = get_bits(gbc, 4) << !ch;
- if (decode_exponents(gbc, s->exp_strategy[blk][ch],
- s->num_exp_groups[ch], s->dexps[ch][0],
- &s->dexps[ch][s->start_freq[ch]+!!ch])) {
- av_log(s->avctx, AV_LOG_ERROR, "exponent out-of-range\n");
- return AVERROR_INVALIDDATA;
- }
- if (ch != CPL_CH && ch != s->lfe_ch)
- skip_bits(gbc, 2); /* skip gainrng */
- }
- }
-
- /* bit allocation information */
- if (s->bit_allocation_syntax) {
- if (get_bits1(gbc)) {
- s->bit_alloc_params.slow_decay = ff_ac3_slow_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift;
- s->bit_alloc_params.fast_decay = ff_ac3_fast_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift;
- s->bit_alloc_params.slow_gain = ff_ac3_slow_gain_tab[get_bits(gbc, 2)];
- s->bit_alloc_params.db_per_bit = ff_ac3_db_per_bit_tab[get_bits(gbc, 2)];
- s->bit_alloc_params.floor = ff_ac3_floor_tab[get_bits(gbc, 3)];
- for (ch = !cpl_in_use; ch <= s->channels; ch++)
- bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
- } else if (!blk) {
- av_log(s->avctx, AV_LOG_ERROR, "new bit allocation info must "
- "be present in block 0\n");
- return AVERROR_INVALIDDATA;
- }
- }
-
- /* signal-to-noise ratio offsets and fast gains (signal-to-mask ratios) */
- if (!s->eac3 || !blk) {
- if (s->snr_offset_strategy && get_bits1(gbc)) {
- int snr = 0;
- int csnr;
- csnr = (get_bits(gbc, 6) - 15) << 4;
- for (i = ch = !cpl_in_use; ch <= s->channels; ch++) {
- /* snr offset */
- if (ch == i || s->snr_offset_strategy == 2)
- snr = (csnr + get_bits(gbc, 4)) << 2;
- /* run at least last bit allocation stage if snr offset changes */
- if (blk && s->snr_offset[ch] != snr) {
- bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 1);
- }
- s->snr_offset[ch] = snr;
-
- /* fast gain (normal AC-3 only) */
- if (!s->eac3) {
- int prev = s->fast_gain[ch];
- s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)];
- /* run last 2 bit allocation stages if fast gain changes */
- if (blk && prev != s->fast_gain[ch])
- bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
- }
- }
- } else if (!s->eac3 && !blk) {
- av_log(s->avctx, AV_LOG_ERROR, "new snr offsets must be present in block 0\n");
- return AVERROR_INVALIDDATA;
- }
- }
-
- /* fast gain (E-AC-3 only) */
- if (s->fast_gain_syntax && get_bits1(gbc)) {
- for (ch = !cpl_in_use; ch <= s->channels; ch++) {
- int prev = s->fast_gain[ch];
- s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)];
- /* run last 2 bit allocation stages if fast gain changes */
- if (blk && prev != s->fast_gain[ch])
- bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
- }
- } else if (s->eac3 && !blk) {
- for (ch = !cpl_in_use; ch <= s->channels; ch++)
- s->fast_gain[ch] = ff_ac3_fast_gain_tab[4];
- }
-
- /* E-AC-3 to AC-3 converter SNR offset */
- if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT && get_bits1(gbc)) {
- skip_bits(gbc, 10); // skip converter snr offset
- }
-
- /* coupling leak information */
- if (cpl_in_use) {
- if (s->first_cpl_leak || get_bits1(gbc)) {
- int fl = get_bits(gbc, 3);
- int sl = get_bits(gbc, 3);
- /* run last 2 bit allocation stages for coupling channel if
- coupling leak changes */
- if (blk && (fl != s->bit_alloc_params.cpl_fast_leak ||
- sl != s->bit_alloc_params.cpl_slow_leak)) {
- bit_alloc_stages[CPL_CH] = FFMAX(bit_alloc_stages[CPL_CH], 2);
- }
- s->bit_alloc_params.cpl_fast_leak = fl;
- s->bit_alloc_params.cpl_slow_leak = sl;
- } else if (!s->eac3 && !blk) {
- av_log(s->avctx, AV_LOG_ERROR, "new coupling leak info must "
- "be present in block 0\n");
- return AVERROR_INVALIDDATA;
- }
- s->first_cpl_leak = 0;
- }
-
- /* delta bit allocation information */
- if (s->dba_syntax && get_bits1(gbc)) {
- /* delta bit allocation exists (strategy) */
- for (ch = !cpl_in_use; ch <= fbw_channels; ch++) {
- s->dba_mode[ch] = get_bits(gbc, 2);
- if (s->dba_mode[ch] == DBA_RESERVED) {
- av_log(s->avctx, AV_LOG_ERROR, "delta bit allocation strategy reserved\n");
- return AVERROR_INVALIDDATA;
- }
- bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
- }
- /* channel delta offset, len and bit allocation */
- for (ch = !cpl_in_use; ch <= fbw_channels; ch++) {
- if (s->dba_mode[ch] == DBA_NEW) {
- s->dba_nsegs[ch] = get_bits(gbc, 3) + 1;
- for (seg = 0; seg < s->dba_nsegs[ch]; seg++) {
- s->dba_offsets[ch][seg] = get_bits(gbc, 5);
- s->dba_lengths[ch][seg] = get_bits(gbc, 4);
- s->dba_values[ch][seg] = get_bits(gbc, 3);
- }
- /* run last 2 bit allocation stages if new dba values */
- bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
- }
- }
- } else if (blk == 0) {
- for (ch = 0; ch <= s->channels; ch++) {
- s->dba_mode[ch] = DBA_NONE;
- }
- }
-
- /* Bit allocation */
- for (ch = !cpl_in_use; ch <= s->channels; ch++) {
- if (bit_alloc_stages[ch] > 2) {
- /* Exponent mapping into PSD and PSD integration */
- ff_ac3_bit_alloc_calc_psd(s->dexps[ch],
- s->start_freq[ch], s->end_freq[ch],
- s->psd[ch], s->band_psd[ch]);
- }
- if (bit_alloc_stages[ch] > 1) {
- /* Compute excitation function, Compute masking curve, and
- Apply delta bit allocation */
- if (ff_ac3_bit_alloc_calc_mask(&s->bit_alloc_params, s->band_psd[ch],
- s->start_freq[ch], s->end_freq[ch],
- s->fast_gain[ch], (ch == s->lfe_ch),
- s->dba_mode[ch], s->dba_nsegs[ch],
- s->dba_offsets[ch], s->dba_lengths[ch],
- s->dba_values[ch], s->mask[ch])) {
- av_log(s->avctx, AV_LOG_ERROR, "error in bit allocation\n");
- return AVERROR_INVALIDDATA;
- }
- }
- if (bit_alloc_stages[ch] > 0) {
- /* Compute bit allocation */
- const uint8_t *bap_tab = s->channel_uses_aht[ch] ?
- ff_eac3_hebap_tab : ff_ac3_bap_tab;
- s->ac3dsp.bit_alloc_calc_bap(s->mask[ch], s->psd[ch],
- s->start_freq[ch], s->end_freq[ch],
- s->snr_offset[ch],
- s->bit_alloc_params.floor,
- bap_tab, s->bap[ch]);
- }
- }
-
- /* unused dummy data */
- if (s->skip_syntax && get_bits1(gbc)) {
- int skipl = get_bits(gbc, 9);
- while (skipl--)
- skip_bits(gbc, 8);
- }
-
- /* unpack the transform coefficients
- this also uncouples channels if coupling is in use. */
- decode_transform_coeffs(s, blk);
-
- /* TODO: generate enhanced coupling coordinates and uncouple */
-
- /* recover coefficients if rematrixing is in use */
- if (s->channel_mode == AC3_CHMODE_STEREO)
- do_rematrixing(s);
-
- /* apply scaling to coefficients (headroom, dynrng) */
- for (ch = 1; ch <= s->channels; ch++) {
- int audio_channel = 0;
- INTFLOAT gain;
- if (s->channel_mode == AC3_CHMODE_DUALMONO)
- audio_channel = 2-ch;
- if (s->heavy_compression && s->compression_exists[audio_channel])
- gain = s->heavy_dynamic_range[audio_channel];
- else
- gain = s->dynamic_range[audio_channel];
-
-#if USE_FIXED
- scale_coefs(s->transform_coeffs[ch], s->fixed_coeffs[ch], gain, 256);
-#else
- if (s->target_level != 0)
- gain = gain * s->level_gain[audio_channel];
- gain *= 1.0 / 4194304.0f;
- s->fmt_conv.int32_to_float_fmul_scalar(s->transform_coeffs[ch],
- s->fixed_coeffs[ch], gain, 256);
-#endif
- }
-
- /* apply spectral extension to high frequency bins */
- if (CONFIG_EAC3_DECODER && s->spx_in_use) {
- ff_eac3_apply_spectral_extension(s);
- }
-
- /* downmix and MDCT. order depends on whether block switching is used for
- any channel in this block. this is because coefficients for the long
- and short transforms cannot be mixed. */
- downmix_output = s->channels != s->out_channels &&
- !((s->output_mode & AC3_OUTPUT_LFEON) &&
- s->fbw_channels == s->out_channels);
- if (different_transforms) {
- /* the delay samples have already been downmixed, so we upmix the delay
- samples in order to reconstruct all channels before downmixing. */
- if (s->downmixed) {
- s->downmixed = 0;
- ac3_upmix_delay(s);
- }
-
- do_imdct(s, s->channels);
-
- if (downmix_output) {
-#if USE_FIXED
- ac3_downmix_c_fixed16(s->outptr, s->downmix_coeffs,
- s->out_channels, s->fbw_channels, 256);
-#else
- s->ac3dsp.downmix(s->outptr, s->downmix_coeffs,
- s->out_channels, s->fbw_channels, 256);
-#endif
- }
- } else {
- if (downmix_output) {
- s->ac3dsp.AC3_RENAME(downmix)(s->xcfptr + 1, s->downmix_coeffs,
- s->out_channels, s->fbw_channels, 256);
- }
-
- if (downmix_output && !s->downmixed) {
- s->downmixed = 1;
- s->ac3dsp.AC3_RENAME(downmix)(s->dlyptr, s->downmix_coeffs,
- s->out_channels, s->fbw_channels, 128);
- }
-
- do_imdct(s, s->out_channels);
- }
-
- return 0;
-}
-
-/**
- * Decode a single AC-3 frame.
- */
-static int ac3_decode_frame(AVCodecContext * avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- AVFrame *frame = data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- AC3DecodeContext *s = avctx->priv_data;
- int blk, ch, err, ret;
- const uint8_t *channel_map;
- const SHORTFLOAT *output[AC3_MAX_CHANNELS];
- enum AVMatrixEncoding matrix_encoding;
- AVDownmixInfo *downmix_info;
-
- /* copy input buffer to decoder context to avoid reading past the end
- of the buffer, which can be caused by a damaged input stream. */
- if (buf_size >= 2 && AV_RB16(buf) == 0x770B) {
- // seems to be byte-swapped AC-3
- int cnt = FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE) >> 1;
- s->bdsp.bswap16_buf((uint16_t *) s->input_buffer,
- (const uint16_t *) buf, cnt);
- } else
- memcpy(s->input_buffer, buf, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE));
- buf = s->input_buffer;
- /* initialize the GetBitContext with the start of valid AC-3 Frame */
- if ((ret = init_get_bits8(&s->gbc, buf, buf_size)) < 0)
- return ret;
-
- /* parse the syncinfo */
- err = parse_frame_header(s);
-
- if (err) {
- switch (err) {
- case AAC_AC3_PARSE_ERROR_SYNC:
- av_log(avctx, AV_LOG_ERROR, "frame sync error\n");
- return AVERROR_INVALIDDATA;
- case AAC_AC3_PARSE_ERROR_BSID:
- av_log(avctx, AV_LOG_ERROR, "invalid bitstream id\n");
- break;
- case AAC_AC3_PARSE_ERROR_SAMPLE_RATE:
- av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n");
- break;
- case AAC_AC3_PARSE_ERROR_FRAME_SIZE:
- av_log(avctx, AV_LOG_ERROR, "invalid frame size\n");
- break;
- case AAC_AC3_PARSE_ERROR_FRAME_TYPE:
- /* skip frame if CRC is ok. otherwise use error concealment. */
- /* TODO: add support for substreams and dependent frames */
- if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT || s->substreamid) {
- av_log(avctx, AV_LOG_WARNING, "unsupported frame type : "
- "skipping frame\n");
- *got_frame_ptr = 0;
- return buf_size;
- } else {
- av_log(avctx, AV_LOG_ERROR, "invalid frame type\n");
- }
- break;
- case AAC_AC3_PARSE_ERROR_CRC:
- case AAC_AC3_PARSE_ERROR_CHANNEL_CFG:
- break;
- default: // Normal AVERROR do not try to recover.
- *got_frame_ptr = 0;
- return err;
- }
- } else {
- /* check that reported frame size fits in input buffer */
- if (s->frame_size > buf_size) {
- av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
- err = AAC_AC3_PARSE_ERROR_FRAME_SIZE;
- } else if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) {
- /* check for crc mismatch */
- if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2],
- s->frame_size - 2)) {
- av_log(avctx, AV_LOG_ERROR, "frame CRC mismatch\n");
- if (avctx->err_recognition & AV_EF_EXPLODE)
- return AVERROR_INVALIDDATA;
- err = AAC_AC3_PARSE_ERROR_CRC;
- }
- }
- }
-
- /* if frame is ok, set audio parameters */
- if (!err) {
- avctx->sample_rate = s->sample_rate;
- avctx->bit_rate = s->bit_rate;
- }
-
- /* channel config */
- if (!err || (s->channels && s->out_channels != s->channels)) {
- s->out_channels = s->channels;
- s->output_mode = s->channel_mode;
- if (s->lfe_on)
- s->output_mode |= AC3_OUTPUT_LFEON;
- if (s->channels > 1 &&
- avctx->request_channel_layout == AV_CH_LAYOUT_MONO) {
- s->out_channels = 1;
- s->output_mode = AC3_CHMODE_MONO;
- } else if (s->channels > 2 &&
- avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
- s->out_channels = 2;
- s->output_mode = AC3_CHMODE_STEREO;
- }
-
- s->loro_center_mix_level = gain_levels[s-> center_mix_level];
- s->loro_surround_mix_level = gain_levels[s->surround_mix_level];
- s->ltrt_center_mix_level = LEVEL_MINUS_3DB;
- s->ltrt_surround_mix_level = LEVEL_MINUS_3DB;
- /* set downmixing coefficients if needed */
- if (s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) &&
- s->fbw_channels == s->out_channels)) {
- set_downmix_coeffs(s);
- }
- } else if (!s->channels) {
- av_log(avctx, AV_LOG_ERROR, "unable to determine channel mode\n");
- return AVERROR_INVALIDDATA;
- }
- avctx->channels = s->out_channels;
- avctx->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode & ~AC3_OUTPUT_LFEON];
- if (s->output_mode & AC3_OUTPUT_LFEON)
- avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
-
- /* set audio service type based on bitstream mode for AC-3 */
- avctx->audio_service_type = s->bitstream_mode;
- if (s->bitstream_mode == 0x7 && s->channels > 1)
- avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
-
- /* get output buffer */
- frame->nb_samples = s->num_blocks * AC3_BLOCK_SIZE;
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
-
- /* decode the audio blocks */
- channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on];
- for (ch = 0; ch < AC3_MAX_CHANNELS; ch++) {
- output[ch] = s->output[ch];
- s->outptr[ch] = s->output[ch];
- }
- for (ch = 0; ch < s->channels; ch++) {
- if (ch < s->out_channels)
- s->outptr[channel_map[ch]] = (SHORTFLOAT *)frame->data[ch];
- }
- for (blk = 0; blk < s->num_blocks; blk++) {
- if (!err && decode_audio_block(s, blk)) {
- av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n");
- err = 1;
- }
- if (err)
- for (ch = 0; ch < s->out_channels; ch++)
- memcpy(((SHORTFLOAT*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT));
- for (ch = 0; ch < s->out_channels; ch++)
- output[ch] = s->outptr[channel_map[ch]];
- for (ch = 0; ch < s->out_channels; ch++) {
- if (!ch || channel_map[ch])
- s->outptr[channel_map[ch]] += AC3_BLOCK_SIZE;
- }
- }
-
- av_frame_set_decode_error_flags(frame, err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0);
-
- /* keep last block for error concealment in next frame */
- for (ch = 0; ch < s->out_channels; ch++)
- memcpy(s->output[ch], output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT));
-
- /*
- * AVMatrixEncoding
- *
- * Check whether the input layout is compatible, and make sure we're not
- * downmixing (else the matrix encoding is no longer applicable).
- */
- matrix_encoding = AV_MATRIX_ENCODING_NONE;
- if (s->channel_mode == AC3_CHMODE_STEREO &&
- s->channel_mode == (s->output_mode & ~AC3_OUTPUT_LFEON)) {
- if (s->dolby_surround_mode == AC3_DSURMOD_ON)
- matrix_encoding = AV_MATRIX_ENCODING_DOLBY;
- else if (s->dolby_headphone_mode == AC3_DHEADPHONMOD_ON)
- matrix_encoding = AV_MATRIX_ENCODING_DOLBYHEADPHONE;
- } else if (s->channel_mode >= AC3_CHMODE_2F2R &&
- s->channel_mode == (s->output_mode & ~AC3_OUTPUT_LFEON)) {
- switch (s->dolby_surround_ex_mode) {
- case AC3_DSUREXMOD_ON: // EX or PLIIx
- matrix_encoding = AV_MATRIX_ENCODING_DOLBYEX;
- break;
- case AC3_DSUREXMOD_PLIIZ:
- matrix_encoding = AV_MATRIX_ENCODING_DPLIIZ;
- break;
- default: // not indicated or off
- break;
- }
- }
- if ((ret = ff_side_data_update_matrix_encoding(frame, matrix_encoding)) < 0)
- return ret;
-
- /* AVDownmixInfo */
- if ((downmix_info = av_downmix_info_update_side_data(frame))) {
- switch (s->preferred_downmix) {
- case AC3_DMIXMOD_LTRT:
- downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_LTRT;
- break;
- case AC3_DMIXMOD_LORO:
- downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_LORO;
- break;
- case AC3_DMIXMOD_DPLII:
- downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_DPLII;
- break;
- default:
- downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_UNKNOWN;
- break;
- }
- downmix_info->center_mix_level = gain_levels[s-> center_mix_level];
- downmix_info->center_mix_level_ltrt = gain_levels[s-> center_mix_level_ltrt];
- downmix_info->surround_mix_level = gain_levels[s-> surround_mix_level];
- downmix_info->surround_mix_level_ltrt = gain_levels[s->surround_mix_level_ltrt];
- if (s->lfe_mix_level_exists)
- downmix_info->lfe_mix_level = gain_levels_lfe[s->lfe_mix_level];
- else
- downmix_info->lfe_mix_level = 0.0; // -inf dB
- } else
- return AVERROR(ENOMEM);
-
- *got_frame_ptr = 1;
-
- return FFMIN(buf_size, s->frame_size);
-}
-
-/**
- * Uninitialize the AC-3 decoder.
- */
-static av_cold int ac3_decode_end(AVCodecContext *avctx)
-{
- AC3DecodeContext *s = avctx->priv_data;
- ff_mdct_end(&s->imdct_512);
- ff_mdct_end(&s->imdct_256);
- av_freep(&s->fdsp);
-
- return 0;
-}
-
-#define OFFSET(x) offsetof(AC3DecodeContext, x)
-#define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM)
diff --git a/ffmpeg-2-8-11/libavcodec/ac3dec.h b/ffmpeg-2-8-11/libavcodec/ac3dec.h
deleted file mode 100644
index b3498fe..0000000
--- a/ffmpeg-2-8-11/libavcodec/ac3dec.h
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Common code between the AC-3 and E-AC-3 decoders
- * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec at gmail.com>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * Common code between the AC-3 and E-AC-3 decoders.
- *
- * Summary of MDCT Coefficient Grouping:
- * The individual MDCT coefficient indices are often referred to in the
- * (E-)AC-3 specification as frequency bins. These bins are grouped together
- * into subbands of 12 coefficients each. The subbands are grouped together
- * into bands as defined in the bitstream by the band structures, which
- * determine the number of bands and the size of each band. The full spectrum
- * of 256 frequency bins is divided into 1 DC bin + 21 subbands = 253 bins.
- * This system of grouping coefficients is used for channel bandwidth, stereo
- * rematrixing, channel coupling, enhanced coupling, and spectral extension.
- *
- * +-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-+
- * |1| |12| | [12|12|12|12] | | | | | | | | | | | | |3|
- * +-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-+
- * ~~~ ~~~~ ~~~~~~~~~~~~~ ~~~
- * | | | |
- * | | | 3 unused frequency bins--+
- * | | |
- * | | +--1 band containing 4 subbands
- * | |
- * | +--1 subband of 12 frequency bins
- * |
- * +--DC frequency bin
- */
-
-#ifndef AVCODEC_AC3DEC_H
-#define AVCODEC_AC3DEC_H
-
-#include "libavutil/float_dsp.h"
-#include "libavutil/fixed_dsp.h"
-#include "libavutil/lfg.h"
-#include "ac3.h"
-#include "ac3dsp.h"
-#include "bswapdsp.h"
-#include "get_bits.h"
-#include "fft.h"
-#include "fmtconvert.h"
-
-#define AC3_OUTPUT_LFEON 8
-
-#define SPX_MAX_BANDS 17
-
-/** Large enough for maximum possible frame size when the specification limit is ignored */
-#define AC3_FRAME_BUFFER_SIZE 32768
-
-typedef struct AC3DecodeContext {
- AVClass *class; ///< class for AVOptions
- AVCodecContext *avctx; ///< parent context
- GetBitContext gbc; ///< bitstream reader
-
-///@name Bit stream information
-///@{
- int frame_type; ///< frame type (strmtyp)
- int substreamid; ///< substream identification
- int frame_size; ///< current frame size, in bytes
- int bit_rate; ///< stream bit rate, in bits-per-second
- int sample_rate; ///< sample frequency, in Hz
- int num_blocks; ///< number of audio blocks
- int bitstream_id; ///< bitstream id (bsid)
- int bitstream_mode; ///< bitstream mode (bsmod)
- int channel_mode; ///< channel mode (acmod)
- int lfe_on; ///< lfe channel in use
- int dialog_normalization[2]; ///< dialog level in dBFS (dialnorm)
- int compression_exists[2]; ///< compression field is valid for frame (compre)
- int compression_gain[2]; ///< gain to apply for heavy compression (compr)
- int channel_map; ///< custom channel map
- int preferred_downmix; ///< Preferred 2-channel downmix mode (dmixmod)
- int center_mix_level; ///< Center mix level index
- int center_mix_level_ltrt; ///< Center mix level index for Lt/Rt (ltrtcmixlev)
- int surround_mix_level; ///< Surround mix level index
- int surround_mix_level_ltrt; ///< Surround mix level index for Lt/Rt (ltrtsurmixlev)
- int lfe_mix_level_exists; ///< indicates if lfemixlevcod is specified (lfemixlevcode)
- int lfe_mix_level; ///< LFE mix level index (lfemixlevcod)
- int eac3; ///< indicates if current frame is E-AC-3
- int dolby_surround_mode; ///< dolby surround mode (dsurmod)
- int dolby_surround_ex_mode; ///< dolby surround ex mode (dsurexmod)
- int dolby_headphone_mode; ///< dolby headphone mode (dheadphonmod)
-///@}
-
- int preferred_stereo_downmix;
- float ltrt_center_mix_level;
- float ltrt_surround_mix_level;
- float loro_center_mix_level;
- float loro_surround_mix_level;
- int target_level; ///< target level in dBFS
- float level_gain[2];
-
-///@name Frame syntax parameters
- int snr_offset_strategy; ///< SNR offset strategy (snroffststr)
- int block_switch_syntax; ///< block switch syntax enabled (blkswe)
- int dither_flag_syntax; ///< dither flag syntax enabled (dithflage)
- int bit_allocation_syntax; ///< bit allocation model syntax enabled (bamode)
- int fast_gain_syntax; ///< fast gain codes enabled (frmfgaincode)
- int dba_syntax; ///< delta bit allocation syntax enabled (dbaflde)
- int skip_syntax; ///< skip field syntax enabled (skipflde)
- ///@}
-
-///@name Standard coupling
- int cpl_in_use[AC3_MAX_BLOCKS]; ///< coupling in use (cplinu)
- int cpl_strategy_exists[AC3_MAX_BLOCKS];///< coupling strategy exists (cplstre)
- int channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl)
- int phase_flags_in_use; ///< phase flags in use (phsflginu)
- int phase_flags[AC3_MAX_CPL_BANDS]; ///< phase flags (phsflg)
- int num_cpl_bands; ///< number of coupling bands (ncplbnd)
- uint8_t cpl_band_sizes[AC3_MAX_CPL_BANDS]; ///< number of coeffs in each coupling band
- int firstchincpl; ///< first channel in coupling
- int first_cpl_coords[AC3_MAX_CHANNELS]; ///< first coupling coordinates states (firstcplcos)
- int cpl_coords[AC3_MAX_CHANNELS][AC3_MAX_CPL_BANDS]; ///< coupling coordinates (cplco)
-///@}
-
-///@name Spectral extension
-///@{
- int spx_in_use; ///< spectral extension in use (spxinu)
- uint8_t channel_uses_spx[AC3_MAX_CHANNELS]; ///< channel uses spectral extension (chinspx)
- int8_t spx_atten_code[AC3_MAX_CHANNELS]; ///< spx attenuation code (spxattencod)
- int spx_src_start_freq; ///< spx start frequency bin
- int spx_dst_end_freq; ///< spx end frequency bin
- int spx_dst_start_freq; ///< spx starting frequency bin for copying (copystartmant)
- ///< the copy region ends at the start of the spx region.
- int num_spx_bands; ///< number of spx bands (nspxbnds)
- uint8_t spx_band_sizes[SPX_MAX_BANDS]; ///< number of bins in each spx band
- uint8_t first_spx_coords[AC3_MAX_CHANNELS]; ///< first spx coordinates states (firstspxcos)
- INTFLOAT spx_noise_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS]; ///< spx noise blending factor (nblendfact)
- INTFLOAT spx_signal_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS];///< spx signal blending factor (sblendfact)
-///@}
-
-///@name Adaptive hybrid transform
- int channel_uses_aht[AC3_MAX_CHANNELS]; ///< channel AHT in use (chahtinu)
- int pre_mantissa[AC3_MAX_CHANNELS][AC3_MAX_COEFS][AC3_MAX_BLOCKS]; ///< pre-IDCT mantissas
-///@}
-
-///@name Channel
- int fbw_channels; ///< number of full-bandwidth channels
- int channels; ///< number of total channels
- int lfe_ch; ///< index of LFE channel
- SHORTFLOAT downmix_coeffs[AC3_MAX_CHANNELS][2]; ///< stereo downmix coefficients
- int downmixed; ///< indicates if coeffs are currently downmixed
- int output_mode; ///< output channel configuration
- int out_channels; ///< number of output channels
-///@}
-
-///@name Dynamic range
- INTFLOAT dynamic_range[2]; ///< dynamic range
- INTFLOAT drc_scale; ///< percentage of dynamic range compression to be applied
- int heavy_compression; ///< apply heavy compression
- INTFLOAT heavy_dynamic_range[2]; ///< heavy dynamic range compression
-///@}
-
-///@name Bandwidth
- int start_freq[AC3_MAX_CHANNELS]; ///< start frequency bin (strtmant)
- int end_freq[AC3_MAX_CHANNELS]; ///< end frequency bin (endmant)
-///@}
-
-///@name Rematrixing
- int num_rematrixing_bands; ///< number of rematrixing bands (nrematbnd)
- int rematrixing_flags[4]; ///< rematrixing flags (rematflg)
-///@}
-
-///@name Exponents
- int num_exp_groups[AC3_MAX_CHANNELS]; ///< Number of exponent groups (nexpgrp)
- int8_t dexps[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< decoded exponents
- int exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS]; ///< exponent strategies (expstr)
-///@}
-
-///@name Bit allocation
- AC3BitAllocParameters bit_alloc_params; ///< bit allocation parameters
- int first_cpl_leak; ///< first coupling leak state (firstcplleak)
- int snr_offset[AC3_MAX_CHANNELS]; ///< signal-to-noise ratio offsets (snroffst)
- int fast_gain[AC3_MAX_CHANNELS]; ///< fast gain values/SMR's (fgain)
- uint8_t bap[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< bit allocation pointers
- int16_t psd[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< scaled exponents
- int16_t band_psd[AC3_MAX_CHANNELS][AC3_CRITICAL_BANDS]; ///< interpolated exponents
- int16_t mask[AC3_MAX_CHANNELS][AC3_CRITICAL_BANDS]; ///< masking curve values
- int dba_mode[AC3_MAX_CHANNELS]; ///< delta bit allocation mode
- int dba_nsegs[AC3_MAX_CHANNELS]; ///< number of delta segments
- uint8_t dba_offsets[AC3_MAX_CHANNELS][8]; ///< delta segment offsets
- uint8_t dba_lengths[AC3_MAX_CHANNELS][8]; ///< delta segment lengths
- uint8_t dba_values[AC3_MAX_CHANNELS][8]; ///< delta values for each segment
-///@}
-
-///@name Zero-mantissa dithering
- int dither_flag[AC3_MAX_CHANNELS]; ///< dither flags (dithflg)
- AVLFG dith_state; ///< for dither generation
-///@}
-
-///@name IMDCT
- int block_switch[AC3_MAX_CHANNELS]; ///< block switch flags (blksw)
- FFTContext imdct_512; ///< for 512 sample IMDCT
- FFTContext imdct_256; ///< for 256 sample IMDCT
-///@}
-
-///@name Optimization
- BswapDSPContext bdsp;
-#if USE_FIXED
- AVFixedDSPContext *fdsp;
-#else
- AVFloatDSPContext *fdsp;
-#endif
- AC3DSPContext ac3dsp;
- FmtConvertContext fmt_conv; ///< optimized conversion functions
-///@}
-
- SHORTFLOAT *outptr[AC3_MAX_CHANNELS];
- INTFLOAT *xcfptr[AC3_MAX_CHANNELS];
- INTFLOAT *dlyptr[AC3_MAX_CHANNELS];
-
-///@name Aligned arrays
- DECLARE_ALIGNED(16, int, fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< fixed-point transform coefficients
- DECLARE_ALIGNED(32, INTFLOAT, transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< transform coefficients
- DECLARE_ALIGNED(32, INTFLOAT, delay)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< delay - added to the next block
- DECLARE_ALIGNED(32, INTFLOAT, window)[AC3_BLOCK_SIZE]; ///< window coefficients
- DECLARE_ALIGNED(32, INTFLOAT, tmp_output)[AC3_BLOCK_SIZE]; ///< temporary storage for output before windowing
- DECLARE_ALIGNED(32, SHORTFLOAT, output)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< output after imdct transform and windowing
- DECLARE_ALIGNED(32, uint8_t, input_buffer)[AC3_FRAME_BUFFER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; ///< temp buffer to prevent overread
-///@}
-} AC3DecodeContext;
-
-/**
- * Parse the E-AC-3 frame header.
- * This parses both the bit stream info and audio frame header.
- */
-static int ff_eac3_parse_header(AC3DecodeContext *s);
-
-/**
- * Decode mantissas in a single channel for the entire frame.
- * This is used when AHT mode is enabled.
- */
-static void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch);
-
-/**
- * Apply spectral extension to each channel by copying lower frequency
- * coefficients to higher frequency bins and applying side information to
- * approximate the original high frequency signal.
- */
-static void ff_eac3_apply_spectral_extension(AC3DecodeContext *s);
-
-#endif /* AVCODEC_AC3DEC_H */
diff --git a/ffmpeg-2-8-11/libavcodec/ac3dec_fixed.c b/ffmpeg-2-8-11/libavcodec/ac3dec_fixed.c
deleted file mode 100644
index 21756ea..0000000
--- a/ffmpeg-2-8-11/libavcodec/ac3dec_fixed.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (c) 2012
- * MIPS Technologies, Inc., California.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * Author: Stanislav Ocovaj (socovaj at mips.com)
- *
- * AC3 fixed-point decoder for MIPS platforms
- *
- * 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
- */
-
-#define FFT_FLOAT 0
-#define USE_FIXED 1
-#define FFT_FIXED_32 1
-#include "ac3dec.h"
-
-
-static const int end_freq_inv_tab[8] =
-{
- 50529027, 44278013, 39403370, 32292987, 27356480, 23729101, 20951060, 18755316
-};
-
-static void scale_coefs (
- int32_t *dst,
- const int32_t *src,
- int dynrng,
- int len)
-{
- int i, shift, round;
- int16_t mul;
- int temp, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
-
- mul = (dynrng & 0x1f) + 0x20;
- shift = 4 - ((dynrng << 23) >> 28);
- if (shift > 0 ) {
- round = 1 << (shift-1);
- for (i=0; i<len; i+=8) {
-
- temp = src[i] * mul;
- temp1 = src[i+1] * mul;
- temp = temp + round;
- temp2 = src[i+2] * mul;
-
- temp1 = temp1 + round;
- dst[i] = temp >> shift;
- temp3 = src[i+3] * mul;
- temp2 = temp2 + round;
-
- dst[i+1] = temp1 >> shift;
- temp4 = src[i + 4] * mul;
- temp3 = temp3 + round;
- dst[i+2] = temp2 >> shift;
-
- temp5 = src[i+5] * mul;
- temp4 = temp4 + round;
- dst[i+3] = temp3 >> shift;
- temp6 = src[i+6] * mul;
-
- dst[i+4] = temp4 >> shift;
- temp5 = temp5 + round;
- temp7 = src[i+7] * mul;
- temp6 = temp6 + round;
-
- dst[i+5] = temp5 >> shift;
- temp7 = temp7 + round;
- dst[i+6] = temp6 >> shift;
- dst[i+7] = temp7 >> shift;
-
- }
- } else {
- shift = -shift;
- for (i=0; i<len; i+=8) {
-
- temp = src[i] * mul;
- temp1 = src[i+1] * mul;
- temp2 = src[i+2] * mul;
-
- dst[i] = temp << shift;
- temp3 = src[i+3] * mul;
-
- dst[i+1] = temp1 << shift;
- temp4 = src[i + 4] * mul;
- dst[i+2] = temp2 << shift;
-
- temp5 = src[i+5] * mul;
- dst[i+3] = temp3 << shift;
- temp6 = src[i+6] * mul;
-
- dst[i+4] = temp4 << shift;
- temp7 = src[i+7] * mul;
-
- dst[i+5] = temp5 << shift;
- dst[i+6] = temp6 << shift;
- dst[i+7] = temp7 << shift;
-
- }
- }
-}
-
-/**
- * Downmix samples from original signal to stereo or mono (this is for 16-bit samples
- * and fixed point decoder - original (for 32-bit samples) is in ac3dsp.c).
- */
-static void ac3_downmix_c_fixed16(int16_t **samples, int16_t (*matrix)[2],
- int out_ch, int in_ch, int len)
-{
- int i, j;
- int v0, v1;
- if (out_ch == 2) {
- for (i = 0; i < len; i++) {
- v0 = v1 = 0;
- for (j = 0; j < in_ch; j++) {
- v0 += samples[j][i] * matrix[j][0];
- v1 += samples[j][i] * matrix[j][1];
- }
- samples[0][i] = (v0+2048)>>12;
- samples[1][i] = (v1+2048)>>12;
- }
- } else if (out_ch == 1) {
- for (i = 0; i < len; i++) {
- v0 = 0;
- for (j = 0; j < in_ch; j++)
- v0 += samples[j][i] * matrix[j][0];
- samples[0][i] = (v0+2048)>>12;
- }
- }
-}
-
-#include "eac3dec.c"
-#include "ac3dec.c"
-
-static const AVOption options[] = {
- { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 6.0, PAR },
- { "heavy_compr", "heavy dynamic range compression enabled", OFFSET(heavy_compression), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, PAR },
- { NULL},
-};
-
-static const AVClass ac3_decoder_class = {
- .class_name = "Fixed-Point AC-3 Decoder",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-AVCodec ff_ac3_fixed_decoder = {
- .name = "ac3_fixed",
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_AC3,
- .priv_data_size = sizeof (AC3DecodeContext),
- .init = ac3_decode_init,
- .close = ac3_decode_end,
- .decode = ac3_decode_frame,
- .capabilities = 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,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/acelp_pitch_delay.c b/ffmpeg-2-8-11/libavcodec/acelp_pitch_delay.c
deleted file mode 100644
index 3ecec01..0000000
--- a/ffmpeg-2-8-11/libavcodec/acelp_pitch_delay.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * gain code, gain pitch and pitch delay decoding
- *
- * Copyright (c) 2008 Vladimir Voroshilov
- *
- * 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/float_dsp.h"
-#include "libavutil/libm.h"
-#include "libavutil/mathematics.h"
-#include "avcodec.h"
-#include "acelp_pitch_delay.h"
-#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,
- int log2_ma_pred_order,
- int erasure)
-{
- int i;
- int avg_gain=quant_energy[(1 << log2_ma_pred_order) - 1]; // (5.10)
-
- for(i=(1 << log2_ma_pred_order) - 1; i>0; i--)
- {
- avg_gain += quant_energy[i-1];
- quant_energy[i] = quant_energy[i-1];
- }
-
- if(erasure)
- quant_energy[0] = FFMAX(avg_gain >> log2_ma_pred_order, -10240) - 4096; // -10 and -4 in (5.10)
- else
- quant_energy[0] = (6165 * ((ff_log2_q15(gain_corr_factor) >> 2) - (13 << 13))) >> 13;
-}
-
-int16_t ff_acelp_decode_gain_code(
- AudioDSPContext *adsp,
- int gain_corr_factor,
- const int16_t* fc_v,
- int mr_energy,
- const int16_t* quant_energy,
- const int16_t* ma_prediction_coeff,
- int subframe_size,
- int ma_pred_order)
-{
- int i;
-
- mr_energy <<= 10;
-
- for(i=0; i<ma_pred_order; i++)
- mr_energy += quant_energy[i] * ma_prediction_coeff[i];
-
-#ifdef G729_BITEXACT
- mr_energy += (((-6165LL * ff_log2(dsp->scalarproduct_int16(fc_v, fc_v, subframe_size, 0))) >> 3) & ~0x3ff);
-
- mr_energy = (5439 * (mr_energy >> 15)) >> 8; // (0.15) = (0.15) * (7.23)
-
- return bidir_sal(
- ((ff_exp2(mr_energy & 0x7fff) + 16) >> 5) * (gain_corr_factor >> 1),
- (mr_energy >> 15) - 25
- );
-#else
- mr_energy = gain_corr_factor * exp(M_LN10 / (20 << 23) * mr_energy) /
- sqrt(adsp->scalarproduct_int16(fc_v, fc_v, subframe_size));
- return mr_energy >> 12;
-#endif
-}
-
-float ff_amr_set_fixed_gain(float fixed_gain_factor, float fixed_mean_energy,
- float *prediction_error, float energy_mean,
- const float *pred_table)
-{
- // Equations 66-69:
- // ^g_c = ^gamma_gc * 100.05 (predicted dB + mean dB - dB of fixed vector)
- // Note 10^(0.05 * -10log(average x2)) = 1/sqrt((average x2)).
- float val = fixed_gain_factor *
- exp2f(M_LOG2_10 * 0.05 *
- (avpriv_scalarproduct_float_c(pred_table, prediction_error, 4) +
- energy_mean)) /
- sqrtf(fixed_mean_energy);
-
- // update quantified prediction error energy history
- memmove(&prediction_error[0], &prediction_error[1],
- 3 * sizeof(prediction_error[0]));
- prediction_error[3] = 20.0 * log10f(fixed_gain_factor);
-
- return val;
-}
-
-void ff_decode_pitch_lag(int *lag_int, int *lag_frac, int pitch_index,
- const int prev_lag_int, const int subframe,
- int third_as_first, int resolution)
-{
- /* Note n * 10923 >> 15 is floor(x/3) for 0 <= n <= 32767 */
- if (subframe == 0 || (subframe == 2 && third_as_first)) {
-
- if (pitch_index < 197)
- pitch_index += 59;
- else
- pitch_index = 3 * pitch_index - 335;
-
- } else {
- if (resolution == 4) {
- int search_range_min = av_clip(prev_lag_int - 5, PITCH_DELAY_MIN,
- PITCH_DELAY_MAX - 9);
-
- // decoding with 4-bit resolution
- if (pitch_index < 4) {
- // integer only precision for [search_range_min, search_range_min+3]
- pitch_index = 3 * (pitch_index + search_range_min) + 1;
- } else if (pitch_index < 12) {
- // 1/3 fractional precision for [search_range_min+3 1/3, search_range_min+5 2/3]
- pitch_index += 3 * search_range_min + 7;
- } else {
- // integer only precision for [search_range_min+6, search_range_min+9]
- pitch_index = 3 * (pitch_index + search_range_min - 6) + 1;
- }
- } else {
- // decoding with 5 or 6 bit resolution, 1/3 fractional precision
- pitch_index--;
-
- if (resolution == 5) {
- pitch_index += 3 * av_clip(prev_lag_int - 10, PITCH_DELAY_MIN,
- PITCH_DELAY_MAX - 19);
- } else
- pitch_index += 3 * av_clip(prev_lag_int - 5, PITCH_DELAY_MIN,
- PITCH_DELAY_MAX - 9);
- }
- }
- *lag_int = pitch_index * 10923 >> 15;
- *lag_frac = pitch_index - 3 * *lag_int - 1;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/adxdec.c b/ffmpeg-2-8-11/libavcodec/adxdec.c
deleted file mode 100644
index 32cc0f0..0000000
--- a/ffmpeg-2-8-11/libavcodec/adxdec.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * ADX ADPCM codecs
- * Copyright (c) 2001,2003 BERO
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "libavutil/intreadwrite.h"
-#include "avcodec.h"
-#include "adx.h"
-#include "get_bits.h"
-#include "internal.h"
-
-/**
- * @file
- * SEGA CRI adx codecs.
- *
- * Reference documents:
- * http://ku-www.ss.titech.ac.jp/~yatsushi/adx.html
- * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/
- */
-
-static av_cold int adx_decode_init(AVCodecContext *avctx)
-{
- ADXContext *c = avctx->priv_data;
- int ret, header_size;
-
- if (avctx->extradata_size >= 24) {
- if ((ret = ff_adx_decode_header(avctx, avctx->extradata,
- avctx->extradata_size, &header_size,
- c->coeff)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n");
- return AVERROR_INVALIDDATA;
- }
- c->channels = avctx->channels;
- c->header_parsed = 1;
- }
-
- avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
-
- return 0;
-}
-
-/**
- * Decode 32 samples from 18 bytes.
- *
- * A 16-bit scalar value is applied to 32 residuals, which then have a
- * 2nd-order LPC filter applied to it to form the output signal for a single
- * channel.
- */
-static int adx_decode(ADXContext *c, int16_t *out, int offset,
- const uint8_t *in, int ch)
-{
- ADXChannelState *prev = &c->prev[ch];
- GetBitContext gb;
- int scale = AV_RB16(in);
- int i;
- int s0, s1, s2, d;
-
- /* check if this is an EOF packet */
- if (scale & 0x8000)
- return -1;
-
- init_get_bits(&gb, in + 2, (BLOCK_SIZE - 2) * 8);
- out += offset;
- s1 = prev->s1;
- s2 = prev->s2;
- for (i = 0; i < BLOCK_SAMPLES; i++) {
- d = get_sbits(&gb, 4);
- s0 = ((d << COEFF_BITS) * scale + c->coeff[0] * s1 + c->coeff[1] * s2) >> COEFF_BITS;
- s2 = s1;
- s1 = av_clip_int16(s0);
- *out++ = s1;
- }
- prev->s1 = s1;
- prev->s2 = s2;
-
- return 0;
-}
-
-static int adx_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- AVFrame *frame = data;
- int buf_size = avpkt->size;
- ADXContext *c = avctx->priv_data;
- int16_t **samples;
- int samples_offset;
- const uint8_t *buf = avpkt->data;
- const uint8_t *buf_end = buf + avpkt->size;
- int num_blocks, ch, ret;
-
- if (c->eof) {
- *got_frame_ptr = 0;
- return buf_size;
- }
-
- if (!c->header_parsed && buf_size >= 2 && AV_RB16(buf) == 0x8000) {
- int header_size;
- if ((ret = ff_adx_decode_header(avctx, buf, buf_size, &header_size,
- c->coeff)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n");
- return AVERROR_INVALIDDATA;
- }
- c->channels = avctx->channels;
- c->header_parsed = 1;
- if (buf_size < header_size)
- return AVERROR_INVALIDDATA;
- buf += header_size;
- buf_size -= header_size;
- }
- if (!c->header_parsed)
- return AVERROR_INVALIDDATA;
-
- /* calculate number of blocks in the packet */
- num_blocks = buf_size / (BLOCK_SIZE * c->channels);
-
- /* if the packet is not an even multiple of BLOCK_SIZE, check for an EOF
- packet */
- if (!num_blocks || buf_size % (BLOCK_SIZE * avctx->channels)) {
- if (buf_size >= 4 && (AV_RB16(buf) & 0x8000)) {
- c->eof = 1;
- *got_frame_ptr = 0;
- return avpkt->size;
- }
- return AVERROR_INVALIDDATA;
- }
-
- /* get output buffer */
- frame->nb_samples = num_blocks * BLOCK_SAMPLES;
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
- samples = (int16_t **)frame->extended_data;
- samples_offset = 0;
-
- while (num_blocks--) {
- for (ch = 0; ch < c->channels; ch++) {
- if (buf_end - buf < BLOCK_SIZE || adx_decode(c, samples[ch], samples_offset, buf, ch)) {
- c->eof = 1;
- buf = avpkt->data + avpkt->size;
- break;
- }
- buf_size -= BLOCK_SIZE;
- buf += BLOCK_SIZE;
- }
- if (!c->eof)
- samples_offset += BLOCK_SAMPLES;
- }
-
- frame->nb_samples = samples_offset;
- *got_frame_ptr = 1;
-
- return buf - avpkt->data;
-}
-
-static void adx_decode_flush(AVCodecContext *avctx)
-{
- ADXContext *c = avctx->priv_data;
- memset(c->prev, 0, sizeof(c->prev));
- c->eof = 0;
-}
-
-AVCodec ff_adpcm_adx_decoder = {
- .name = "adpcm_adx",
- .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_ADPCM_ADX,
- .priv_data_size = sizeof(ADXContext),
- .init = adx_decode_init,
- .decode = adx_decode_frame,
- .flush = adx_decode_flush,
- .capabilities = AV_CODEC_CAP_DR1,
- .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
- AV_SAMPLE_FMT_NONE },
-};
diff --git a/ffmpeg-2-8-11/libavcodec/amrwbdec.c b/ffmpeg-2-8-11/libavcodec/amrwbdec.c
deleted file mode 100644
index b73b700..0000000
--- a/ffmpeg-2-8-11/libavcodec/amrwbdec.c
+++ /dev/null
@@ -1,1279 +0,0 @@
-/*
- * AMR wideband decoder
- * Copyright (c) 2010 Marcelo Galvao Povoa
- *
- * 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
- * AMR wideband decoder
- */
-
-#include "libavutil/channel_layout.h"
-#include "libavutil/common.h"
-#include "libavutil/float_dsp.h"
-#include "libavutil/lfg.h"
-
-#include "avcodec.h"
-#include "lsp.h"
-#include "celp_filters.h"
-#include "celp_math.h"
-#include "acelp_filters.h"
-#include "acelp_vectors.h"
-#include "acelp_pitch_delay.h"
-#include "internal.h"
-
-#define AMR_USE_16BIT_TABLES
-#include "amr.h"
-
-#include "amrwbdata.h"
-#include "mips/amrwbdec_mips.h"
-
-typedef struct AMRWBContext {
- AMRWBFrame frame; ///< AMRWB parameters decoded from bitstream
- enum Mode fr_cur_mode; ///< mode index of current frame
- uint8_t fr_quality; ///< frame quality index (FQI)
- float isf_cur[LP_ORDER]; ///< working ISF vector from current frame
- float isf_q_past[LP_ORDER]; ///< quantized ISF vector of the previous frame
- float isf_past_final[LP_ORDER]; ///< final processed ISF vector of the previous frame
- double isp[4][LP_ORDER]; ///< ISP vectors from current frame
- double isp_sub4_past[LP_ORDER]; ///< ISP vector for the 4th subframe of the previous frame
-
- float lp_coef[4][LP_ORDER]; ///< Linear Prediction Coefficients from ISP vector
-
- uint8_t base_pitch_lag; ///< integer part of pitch lag for the next relative subframe
- uint8_t pitch_lag_int; ///< integer part of pitch lag of the previous subframe
-
- float excitation_buf[AMRWB_P_DELAY_MAX + LP_ORDER + 2 + AMRWB_SFR_SIZE]; ///< current excitation and all necessary excitation history
- float *excitation; ///< points to current excitation in excitation_buf[]
-
- float pitch_vector[AMRWB_SFR_SIZE]; ///< adaptive codebook (pitch) vector for current subframe
- float fixed_vector[AMRWB_SFR_SIZE]; ///< algebraic codebook (fixed) vector for current subframe
-
- float prediction_error[4]; ///< quantified prediction errors {20log10(^gamma_gc)} for previous four subframes
- float pitch_gain[6]; ///< quantified pitch gains for the current and previous five subframes
- float fixed_gain[2]; ///< quantified fixed gains for the current and previous subframes
-
- float tilt_coef; ///< {beta_1} related to the voicing of the previous subframe
-
- float prev_sparse_fixed_gain; ///< previous fixed gain; used by anti-sparseness to determine "onset"
- uint8_t prev_ir_filter_nr; ///< previous impulse response filter "impNr": 0 - strong, 1 - medium, 2 - none
- float prev_tr_gain; ///< previous initial gain used by noise enhancer for threshold
-
- float samples_az[LP_ORDER + AMRWB_SFR_SIZE]; ///< low-band samples and memory from synthesis at 12.8kHz
- float samples_up[UPS_MEM_SIZE + AMRWB_SFR_SIZE]; ///< low-band samples and memory processed for upsampling
- float samples_hb[LP_ORDER_16k + AMRWB_SFR_SIZE_16k]; ///< high-band samples and memory from synthesis at 16kHz
-
- float hpf_31_mem[2], hpf_400_mem[2]; ///< previous values in the high pass filters
- float demph_mem[1]; ///< previous value in the de-emphasis filter
- float bpf_6_7_mem[HB_FIR_SIZE]; ///< previous values in the high-band band pass filter
- float lpf_7_mem[HB_FIR_SIZE]; ///< previous values in the high-band low pass filter
-
- AVLFG prng; ///< random number generator for white noise excitation
- uint8_t first_frame; ///< flag active during decoding of the first frame
- ACELPFContext acelpf_ctx; ///< context for filters for ACELP-based codecs
- ACELPVContext acelpv_ctx; ///< context for vector operations for ACELP-based codecs
- CELPFContext celpf_ctx; ///< context for filters for CELP-based codecs
- CELPMContext celpm_ctx; ///< context for fixed point math operations
-
-} AMRWBContext;
-
-static av_cold int amrwb_decode_init(AVCodecContext *avctx)
-{
- AMRWBContext *ctx = avctx->priv_data;
- int i;
-
- if (avctx->channels > 1) {
- avpriv_report_missing_feature(avctx, "multi-channel AMR");
- return AVERROR_PATCHWELCOME;
- }
-
- avctx->channels = 1;
- avctx->channel_layout = AV_CH_LAYOUT_MONO;
- if (!avctx->sample_rate)
- avctx->sample_rate = 16000;
- avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
-
- av_lfg_init(&ctx->prng, 1);
-
- ctx->excitation = &ctx->excitation_buf[AMRWB_P_DELAY_MAX + LP_ORDER + 1];
- ctx->first_frame = 1;
-
- for (i = 0; i < LP_ORDER; i++)
- ctx->isf_past_final[i] = isf_init[i] * (1.0f / (1 << 15));
-
- for (i = 0; i < 4; i++)
- ctx->prediction_error[i] = MIN_ENERGY;
-
- ff_acelp_filter_init(&ctx->acelpf_ctx);
- ff_acelp_vectors_init(&ctx->acelpv_ctx);
- ff_celp_filter_init(&ctx->celpf_ctx);
- ff_celp_math_init(&ctx->celpm_ctx);
-
- return 0;
-}
-
-/**
- * Decode the frame header in the "MIME/storage" format. This format
- * is simpler and does not carry the auxiliary frame information.
- *
- * @param[in] ctx The Context
- * @param[in] buf Pointer to the input buffer
- *
- * @return The decoded header length in bytes
- */
-static int decode_mime_header(AMRWBContext *ctx, const uint8_t *buf)
-{
- /* Decode frame header (1st octet) */
- ctx->fr_cur_mode = buf[0] >> 3 & 0x0F;
- ctx->fr_quality = (buf[0] & 0x4) == 0x4;
-
- return 1;
-}
-
-/**
- * Decode quantized ISF vectors using 36-bit indexes (6K60 mode only).
- *
- * @param[in] ind Array of 5 indexes
- * @param[out] isf_q Buffer for isf_q[LP_ORDER]
- *
- */
-static void decode_isf_indices_36b(uint16_t *ind, float *isf_q)
-{
- int i;
-
- for (i = 0; i < 9; i++)
- isf_q[i] = dico1_isf[ind[0]][i] * (1.0f / (1 << 15));
-
- for (i = 0; i < 7; i++)
- isf_q[i + 9] = dico2_isf[ind[1]][i] * (1.0f / (1 << 15));
-
- for (i = 0; i < 5; i++)
- isf_q[i] += dico21_isf_36b[ind[2]][i] * (1.0f / (1 << 15));
-
- for (i = 0; i < 4; i++)
- isf_q[i + 5] += dico22_isf_36b[ind[3]][i] * (1.0f / (1 << 15));
-
- for (i = 0; i < 7; i++)
- isf_q[i + 9] += dico23_isf_36b[ind[4]][i] * (1.0f / (1 << 15));
-}
-
-/**
- * Decode quantized ISF vectors using 46-bit indexes (except 6K60 mode).
- *
- * @param[in] ind Array of 7 indexes
- * @param[out] isf_q Buffer for isf_q[LP_ORDER]
- *
- */
-static void decode_isf_indices_46b(uint16_t *ind, float *isf_q)
-{
- int i;
-
- for (i = 0; i < 9; i++)
- isf_q[i] = dico1_isf[ind[0]][i] * (1.0f / (1 << 15));
-
- for (i = 0; i < 7; i++)
- isf_q[i + 9] = dico2_isf[ind[1]][i] * (1.0f / (1 << 15));
-
- for (i = 0; i < 3; i++)
- isf_q[i] += dico21_isf[ind[2]][i] * (1.0f / (1 << 15));
-
- for (i = 0; i < 3; i++)
- isf_q[i + 3] += dico22_isf[ind[3]][i] * (1.0f / (1 << 15));
-
- for (i = 0; i < 3; i++)
- isf_q[i + 6] += dico23_isf[ind[4]][i] * (1.0f / (1 << 15));
-
- for (i = 0; i < 3; i++)
- isf_q[i + 9] += dico24_isf[ind[5]][i] * (1.0f / (1 << 15));
-
- for (i = 0; i < 4; i++)
- isf_q[i + 12] += dico25_isf[ind[6]][i] * (1.0f / (1 << 15));
-}
-
-/**
- * Apply mean and past ISF values using the prediction factor.
- * Updates past ISF vector.
- *
- * @param[in,out] isf_q Current quantized ISF
- * @param[in,out] isf_past Past quantized ISF
- *
- */
-static void isf_add_mean_and_past(float *isf_q, float *isf_past)
-{
- int i;
- float tmp;
-
- for (i = 0; i < LP_ORDER; i++) {
- tmp = isf_q[i];
- isf_q[i] += isf_mean[i] * (1.0f / (1 << 15));
- isf_q[i] += PRED_FACTOR * isf_past[i];
- isf_past[i] = tmp;
- }
-}
-
-/**
- * Interpolate the fourth ISP vector from current and past frames
- * to obtain an ISP vector for each subframe.
- *
- * @param[in,out] isp_q ISPs for each subframe
- * @param[in] isp4_past Past ISP for subframe 4
- */
-static void interpolate_isp(double isp_q[4][LP_ORDER], const double *isp4_past)
-{
- int i, k;
-
- for (k = 0; k < 3; k++) {
- float c = isfp_inter[k];
- for (i = 0; i < LP_ORDER; i++)
- isp_q[k][i] = (1.0 - c) * isp4_past[i] + c * isp_q[3][i];
- }
-}
-
-/**
- * Decode an adaptive codebook index into pitch lag (except 6k60, 8k85 modes).
- * Calculate integer lag and fractional lag always using 1/4 resolution.
- * In 1st and 3rd subframes the index is relative to last subframe integer lag.
- *
- * @param[out] lag_int Decoded integer pitch lag
- * @param[out] lag_frac Decoded fractional pitch lag
- * @param[in] pitch_index Adaptive codebook pitch index
- * @param[in,out] base_lag_int Base integer lag used in relative subframes
- * @param[in] subframe Current subframe index (0 to 3)
- */
-static void decode_pitch_lag_high(int *lag_int, int *lag_frac, int pitch_index,
- uint8_t *base_lag_int, int subframe)
-{
- if (subframe == 0 || subframe == 2) {
- if (pitch_index < 376) {
- *lag_int = (pitch_index + 137) >> 2;
- *lag_frac = pitch_index - (*lag_int << 2) + 136;
- } else if (pitch_index < 440) {
- *lag_int = (pitch_index + 257 - 376) >> 1;
- *lag_frac = (pitch_index - (*lag_int << 1) + 256 - 376) << 1;
- /* the actual resolution is 1/2 but expressed as 1/4 */
- } else {
- *lag_int = pitch_index - 280;
- *lag_frac = 0;
- }
- /* minimum lag for next subframe */
- *base_lag_int = av_clip(*lag_int - 8 - (*lag_frac < 0),
- AMRWB_P_DELAY_MIN, AMRWB_P_DELAY_MAX - 15);
- // XXX: the spec states clearly that *base_lag_int should be
- // the nearest integer to *lag_int (minus 8), but the ref code
- // actually always uses its floor, I'm following the latter
- } else {
- *lag_int = (pitch_index + 1) >> 2;
- *lag_frac = pitch_index - (*lag_int << 2);
- *lag_int += *base_lag_int;
- }
-}
-
-/**
- * Decode an adaptive codebook index into pitch lag for 8k85 and 6k60 modes.
- * The description is analogous to decode_pitch_lag_high, but in 6k60 the
- * relative index is used for all subframes except the first.
- */
-static void decode_pitch_lag_low(int *lag_int, int *lag_frac, int pitch_index,
- uint8_t *base_lag_int, int subframe, enum Mode mode)
-{
- if (subframe == 0 || (subframe == 2 && mode != MODE_6k60)) {
- if (pitch_index < 116) {
- *lag_int = (pitch_index + 69) >> 1;
- *lag_frac = (pitch_index - (*lag_int << 1) + 68) << 1;
- } else {
- *lag_int = pitch_index - 24;
- *lag_frac = 0;
- }
- // XXX: same problem as before
- *base_lag_int = av_clip(*lag_int - 8 - (*lag_frac < 0),
- AMRWB_P_DELAY_MIN, AMRWB_P_DELAY_MAX - 15);
- } else {
- *lag_int = (pitch_index + 1) >> 1;
- *lag_frac = (pitch_index - (*lag_int << 1)) << 1;
- *lag_int += *base_lag_int;
- }
-}
-
-/**
- * Find the pitch vector by interpolating the past excitation at the
- * pitch delay, which is obtained in this function.
- *
- * @param[in,out] ctx The context
- * @param[in] amr_subframe Current subframe data
- * @param[in] subframe Current subframe index (0 to 3)
- */
-static void decode_pitch_vector(AMRWBContext *ctx,
- const AMRWBSubFrame *amr_subframe,
- const int subframe)
-{
- int pitch_lag_int, pitch_lag_frac;
- int i;
- float *exc = ctx->excitation;
- enum Mode mode = ctx->fr_cur_mode;
-
- if (mode <= MODE_8k85) {
- decode_pitch_lag_low(&pitch_lag_int, &pitch_lag_frac, amr_subframe->adap,
- &ctx->base_pitch_lag, subframe, mode);
- } else
- decode_pitch_lag_high(&pitch_lag_int, &pitch_lag_frac, amr_subframe->adap,
- &ctx->base_pitch_lag, subframe);
-
- ctx->pitch_lag_int = pitch_lag_int;
- pitch_lag_int += pitch_lag_frac > 0;
-
- /* Calculate the pitch vector by interpolating the past excitation at the
- pitch lag using a hamming windowed sinc function */
- ctx->acelpf_ctx.acelp_interpolatef(exc,
- exc + 1 - pitch_lag_int,
- ac_inter, 4,
- pitch_lag_frac + (pitch_lag_frac > 0 ? 0 : 4),
- LP_ORDER, AMRWB_SFR_SIZE + 1);
-
- /* Check which pitch signal path should be used
- * 6k60 and 8k85 modes have the ltp flag set to 0 */
- if (amr_subframe->ltp) {
- memcpy(ctx->pitch_vector, exc, AMRWB_SFR_SIZE * sizeof(float));
- } else {
- for (i = 0; i < AMRWB_SFR_SIZE; i++)
- ctx->pitch_vector[i] = 0.18 * exc[i - 1] + 0.64 * exc[i] +
- 0.18 * exc[i + 1];
- memcpy(exc, ctx->pitch_vector, AMRWB_SFR_SIZE * sizeof(float));
- }
-}
-
-/** Get x bits in the index interval [lsb,lsb+len-1] inclusive */
-#define BIT_STR(x,lsb,len) (((x) >> (lsb)) & ((1 << (len)) - 1))
-
-/** Get the bit at specified position */
-#define BIT_POS(x, p) (((x) >> (p)) & 1)
-
-/**
- * The next six functions decode_[i]p_track decode exactly i pulses
- * positions and amplitudes (-1 or 1) in a subframe track using
- * an encoded pulse indexing (TS 26.190 section 5.8.2).
- *
- * The results are given in out[], in which a negative number means
- * amplitude -1 and vice versa (i.e., ampl(x) = x / abs(x) ).
- *
- * @param[out] out Output buffer (writes i elements)
- * @param[in] code Pulse index (no. of bits varies, see below)
- * @param[in] m (log2) Number of potential positions
- * @param[in] off Offset for decoded positions
- */
-static inline void decode_1p_track(int *out, int code, int m, int off)
-{
- int pos = BIT_STR(code, 0, m) + off; ///code: m+1 bits
-
- out[0] = BIT_POS(code, m) ? -pos : pos;
-}
-
-static inline void decode_2p_track(int *out, int code, int m, int off) ///code: 2m+1 bits
-{
- int pos0 = BIT_STR(code, m, m) + off;
- int pos1 = BIT_STR(code, 0, m) + off;
-
- out[0] = BIT_POS(code, 2*m) ? -pos0 : pos0;
- out[1] = BIT_POS(code, 2*m) ? -pos1 : pos1;
- out[1] = pos0 > pos1 ? -out[1] : out[1];
-}
-
-static void decode_3p_track(int *out, int code, int m, int off) ///code: 3m+1 bits
-{
- int half_2p = BIT_POS(code, 2*m - 1) << (m - 1);
-
- decode_2p_track(out, BIT_STR(code, 0, 2*m - 1),
- m - 1, off + half_2p);
- decode_1p_track(out + 2, BIT_STR(code, 2*m, m + 1), m, off);
-}
-
-static void decode_4p_track(int *out, int code, int m, int off) ///code: 4m bits
-{
- int half_4p, subhalf_2p;
- int b_offset = 1 << (m - 1);
-
- switch (BIT_STR(code, 4*m - 2, 2)) { /* case ID (2 bits) */
- case 0: /* 0 pulses in A, 4 pulses in B or vice versa */
- half_4p = BIT_POS(code, 4*m - 3) << (m - 1); // which has 4 pulses
- subhalf_2p = BIT_POS(code, 2*m - 3) << (m - 2);
-
- decode_2p_track(out, BIT_STR(code, 0, 2*m - 3),
- m - 2, off + half_4p + subhalf_2p);
- decode_2p_track(out + 2, BIT_STR(code, 2*m - 2, 2*m - 1),
- m - 1, off + half_4p);
- break;
- case 1: /* 1 pulse in A, 3 pulses in B */
- decode_1p_track(out, BIT_STR(code, 3*m - 2, m),
- m - 1, off);
- decode_3p_track(out + 1, BIT_STR(code, 0, 3*m - 2),
- m - 1, off + b_offset);
- break;
- case 2: /* 2 pulses in each half */
- decode_2p_track(out, BIT_STR(code, 2*m - 1, 2*m - 1),
- m - 1, off);
- decode_2p_track(out + 2, BIT_STR(code, 0, 2*m - 1),
- m - 1, off + b_offset);
- break;
- case 3: /* 3 pulses in A, 1 pulse in B */
- decode_3p_track(out, BIT_STR(code, m, 3*m - 2),
- m - 1, off);
- decode_1p_track(out + 3, BIT_STR(code, 0, m),
- m - 1, off + b_offset);
- break;
- }
-}
-
-static void decode_5p_track(int *out, int code, int m, int off) ///code: 5m bits
-{
- int half_3p = BIT_POS(code, 5*m - 1) << (m - 1);
-
- decode_3p_track(out, BIT_STR(code, 2*m + 1, 3*m - 2),
- m - 1, off + half_3p);
-
- decode_2p_track(out + 3, BIT_STR(code, 0, 2*m + 1), m, off);
-}
-
-static void decode_6p_track(int *out, int code, int m, int off) ///code: 6m-2 bits
-{
- int b_offset = 1 << (m - 1);
- /* which half has more pulses in cases 0 to 2 */
- int half_more = BIT_POS(code, 6*m - 5) << (m - 1);
- int half_other = b_offset - half_more;
-
- switch (BIT_STR(code, 6*m - 4, 2)) { /* case ID (2 bits) */
- case 0: /* 0 pulses in A, 6 pulses in B or vice versa */
- decode_1p_track(out, BIT_STR(code, 0, m),
- m - 1, off + half_more);
- decode_5p_track(out + 1, BIT_STR(code, m, 5*m - 5),
- m - 1, off + half_more);
- break;
- case 1: /* 1 pulse in A, 5 pulses in B or vice versa */
- decode_1p_track(out, BIT_STR(code, 0, m),
- m - 1, off + half_other);
- decode_5p_track(out + 1, BIT_STR(code, m, 5*m - 5),
- m - 1, off + half_more);
- break;
- case 2: /* 2 pulses in A, 4 pulses in B or vice versa */
- decode_2p_track(out, BIT_STR(code, 0, 2*m - 1),
- m - 1, off + half_other);
- decode_4p_track(out + 2, BIT_STR(code, 2*m - 1, 4*m - 4),
- m - 1, off + half_more);
- break;
- case 3: /* 3 pulses in A, 3 pulses in B */
- decode_3p_track(out, BIT_STR(code, 3*m - 2, 3*m - 2),
- m - 1, off);
- decode_3p_track(out + 3, BIT_STR(code, 0, 3*m - 2),
- m - 1, off + b_offset);
- break;
- }
-}
-
-/**
- * Decode the algebraic codebook index to pulse positions and signs,
- * then construct the algebraic codebook vector.
- *
- * @param[out] fixed_vector Buffer for the fixed codebook excitation
- * @param[in] pulse_hi MSBs part of the pulse index array (higher modes only)
- * @param[in] pulse_lo LSBs part of the pulse index array
- * @param[in] mode Mode of the current frame
- */
-static void decode_fixed_vector(float *fixed_vector, const uint16_t *pulse_hi,
- const uint16_t *pulse_lo, const enum Mode mode)
-{
- /* sig_pos stores for each track the decoded pulse position indexes
- * (1-based) multiplied by its corresponding amplitude (+1 or -1) */
- int sig_pos[4][6];
- int spacing = (mode == MODE_6k60) ? 2 : 4;
- int i, j;
-
- switch (mode) {
- case MODE_6k60:
- for (i = 0; i < 2; i++)
- decode_1p_track(sig_pos[i], pulse_lo[i], 5, 1);
- break;
- case MODE_8k85:
- for (i = 0; i < 4; i++)
- decode_1p_track(sig_pos[i], pulse_lo[i], 4, 1);
- break;
- case MODE_12k65:
- for (i = 0; i < 4; i++)
- decode_2p_track(sig_pos[i], pulse_lo[i], 4, 1);
- break;
- case MODE_14k25:
- for (i = 0; i < 2; i++)
- decode_3p_track(sig_pos[i], pulse_lo[i], 4, 1);
- for (i = 2; i < 4; i++)
- decode_2p_track(sig_pos[i], pulse_lo[i], 4, 1);
- break;
- case MODE_15k85:
- for (i = 0; i < 4; i++)
- decode_3p_track(sig_pos[i], pulse_lo[i], 4, 1);
- break;
- case MODE_18k25:
- for (i = 0; i < 4; i++)
- decode_4p_track(sig_pos[i], (int) pulse_lo[i] +
- ((int) pulse_hi[i] << 14), 4, 1);
- break;
- case MODE_19k85:
- for (i = 0; i < 2; i++)
- decode_5p_track(sig_pos[i], (int) pulse_lo[i] +
- ((int) pulse_hi[i] << 10), 4, 1);
- for (i = 2; i < 4; i++)
- decode_4p_track(sig_pos[i], (int) pulse_lo[i] +
- ((int) pulse_hi[i] << 14), 4, 1);
- break;
- case MODE_23k05:
- case MODE_23k85:
- for (i = 0; i < 4; i++)
- decode_6p_track(sig_pos[i], (int) pulse_lo[i] +
- ((int) pulse_hi[i] << 11), 4, 1);
- break;
- }
-
- memset(fixed_vector, 0, sizeof(float) * AMRWB_SFR_SIZE);
-
- for (i = 0; i < 4; i++)
- for (j = 0; j < pulses_nb_per_mode_tr[mode][i]; j++) {
- int pos = (FFABS(sig_pos[i][j]) - 1) * spacing + i;
-
- fixed_vector[pos] += sig_pos[i][j] < 0 ? -1.0 : 1.0;
- }
-}
-
-/**
- * Decode pitch gain and fixed gain correction factor.
- *
- * @param[in] vq_gain Vector-quantized index for gains
- * @param[in] mode Mode of the current frame
- * @param[out] fixed_gain_factor Decoded fixed gain correction factor
- * @param[out] pitch_gain Decoded pitch gain
- */
-static void decode_gains(const uint8_t vq_gain, const enum Mode mode,
- float *fixed_gain_factor, float *pitch_gain)
-{
- const int16_t *gains = (mode <= MODE_8k85 ? qua_gain_6b[vq_gain] :
- qua_gain_7b[vq_gain]);
-
- *pitch_gain = gains[0] * (1.0f / (1 << 14));
- *fixed_gain_factor = gains[1] * (1.0f / (1 << 11));
-}
-
-/**
- * Apply pitch sharpening filters to the fixed codebook vector.
- *
- * @param[in] ctx The context
- * @param[in,out] fixed_vector Fixed codebook excitation
- */
-// XXX: Spec states this procedure should be applied when the pitch
-// lag is less than 64, but this checking seems absent in reference and AMR-NB
-static void pitch_sharpening(AMRWBContext *ctx, float *fixed_vector)
-{
- int i;
-
- /* Tilt part */
- for (i = AMRWB_SFR_SIZE - 1; i != 0; i--)
- fixed_vector[i] -= fixed_vector[i - 1] * ctx->tilt_coef;
-
- /* Periodicity enhancement part */
- for (i = ctx->pitch_lag_int; i < AMRWB_SFR_SIZE; i++)
- fixed_vector[i] += fixed_vector[i - ctx->pitch_lag_int] * 0.85;
-}
-
-/**
- * Calculate the voicing factor (-1.0 = unvoiced to 1.0 = voiced).
- *
- * @param[in] p_vector, f_vector Pitch and fixed excitation vectors
- * @param[in] p_gain, f_gain Pitch and fixed gains
- * @param[in] ctx The context
- */
-// XXX: There is something wrong with the precision here! The magnitudes
-// of the energies are not correct. Please check the reference code carefully
-static float voice_factor(float *p_vector, float p_gain,
- float *f_vector, float f_gain,
- CELPMContext *ctx)
-{
- double p_ener = (double) ctx->dot_productf(p_vector, p_vector,
- AMRWB_SFR_SIZE) *
- p_gain * p_gain;
- double f_ener = (double) ctx->dot_productf(f_vector, f_vector,
- AMRWB_SFR_SIZE) *
- f_gain * f_gain;
-
- return (p_ener - f_ener) / (p_ener + f_ener);
-}
-
-/**
- * Reduce fixed vector sparseness by smoothing with one of three IR filters,
- * also known as "adaptive phase dispersion".
- *
- * @param[in] ctx The context
- * @param[in,out] fixed_vector Unfiltered fixed vector
- * @param[out] buf Space for modified vector if necessary
- *
- * @return The potentially overwritten filtered fixed vector address
- */
-static float *anti_sparseness(AMRWBContext *ctx,
- float *fixed_vector, float *buf)
-{
- int ir_filter_nr;
-
- if (ctx->fr_cur_mode > MODE_8k85) // no filtering in higher modes
- return fixed_vector;
-
- if (ctx->pitch_gain[0] < 0.6) {
- ir_filter_nr = 0; // strong filtering
- } else if (ctx->pitch_gain[0] < 0.9) {
- ir_filter_nr = 1; // medium filtering
- } else
- ir_filter_nr = 2; // no filtering
-
- /* detect 'onset' */
- if (ctx->fixed_gain[0] > 3.0 * ctx->fixed_gain[1]) {
- if (ir_filter_nr < 2)
- ir_filter_nr++;
- } else {
- int i, count = 0;
-
- for (i = 0; i < 6; i++)
- if (ctx->pitch_gain[i] < 0.6)
- count++;
-
- if (count > 2)
- ir_filter_nr = 0;
-
- if (ir_filter_nr > ctx->prev_ir_filter_nr + 1)
- ir_filter_nr--;
- }
-
- /* update ir filter strength history */
- ctx->prev_ir_filter_nr = ir_filter_nr;
-
- ir_filter_nr += (ctx->fr_cur_mode == MODE_8k85);
-
- if (ir_filter_nr < 2) {
- int i;
- const float *coef = ir_filters_lookup[ir_filter_nr];
-
- /* Circular convolution code in the reference
- * decoder was modified to avoid using one
- * extra array. The filtered vector is given by:
- *
- * c2(n) = sum(i,0,len-1){ c(i) * coef( (n - i + len) % len ) }
- */
-
- memset(buf, 0, sizeof(float) * AMRWB_SFR_SIZE);
- for (i = 0; i < AMRWB_SFR_SIZE; i++)
- if (fixed_vector[i])
- ff_celp_circ_addf(buf, buf, coef, i, fixed_vector[i],
- AMRWB_SFR_SIZE);
- fixed_vector = buf;
- }
-
- return fixed_vector;
-}
-
-/**
- * Calculate a stability factor {teta} based on distance between
- * current and past isf. A value of 1 shows maximum signal stability.
- */
-static float stability_factor(const float *isf, const float *isf_past)
-{
- int i;
- float acc = 0.0;
-
- for (i = 0; i < LP_ORDER - 1; i++)
- acc += (isf[i] - isf_past[i]) * (isf[i] - isf_past[i]);
-
- // XXX: This part is not so clear from the reference code
- // the result is more accurate changing the "/ 256" to "* 512"
- return FFMAX(0.0, 1.25 - acc * 0.8 * 512);
-}
-
-/**
- * Apply a non-linear fixed gain smoothing in order to reduce
- * fluctuation in the energy of excitation.
- *
- * @param[in] fixed_gain Unsmoothed fixed gain
- * @param[in,out] prev_tr_gain Previous threshold gain (updated)
- * @param[in] voice_fac Frame voicing factor
- * @param[in] stab_fac Frame stability factor
- *
- * @return The smoothed gain
- */
-static float noise_enhancer(float fixed_gain, float *prev_tr_gain,
- float voice_fac, float stab_fac)
-{
- float sm_fac = 0.5 * (1 - voice_fac) * stab_fac;
- float g0;
-
- // XXX: the following fixed-point constants used to in(de)crement
- // gain by 1.5dB were taken from the reference code, maybe it could
- // be simpler
- if (fixed_gain < *prev_tr_gain) {
- g0 = FFMIN(*prev_tr_gain, fixed_gain + fixed_gain *
- (6226 * (1.0f / (1 << 15)))); // +1.5 dB
- } else
- g0 = FFMAX(*prev_tr_gain, fixed_gain *
- (27536 * (1.0f / (1 << 15)))); // -1.5 dB
-
- *prev_tr_gain = g0; // update next frame threshold
-
- return sm_fac * g0 + (1 - sm_fac) * fixed_gain;
-}
-
-/**
- * Filter the fixed_vector to emphasize the higher frequencies.
- *
- * @param[in,out] fixed_vector Fixed codebook vector
- * @param[in] voice_fac Frame voicing factor
- */
-static void pitch_enhancer(float *fixed_vector, float voice_fac)
-{
- int i;
- float cpe = 0.125 * (1 + voice_fac);
- float last = fixed_vector[0]; // holds c(i - 1)
-
- fixed_vector[0] -= cpe * fixed_vector[1];
-
- for (i = 1; i < AMRWB_SFR_SIZE - 1; i++) {
- float cur = fixed_vector[i];
-
- fixed_vector[i] -= cpe * (last + fixed_vector[i + 1]);
- last = cur;
- }
-
- fixed_vector[AMRWB_SFR_SIZE - 1] -= cpe * last;
-}
-
-/**
- * Conduct 16th order linear predictive coding synthesis from excitation.
- *
- * @param[in] ctx Pointer to the AMRWBContext
- * @param[in] lpc Pointer to the LPC coefficients
- * @param[out] excitation Buffer for synthesis final excitation
- * @param[in] fixed_gain Fixed codebook gain for synthesis
- * @param[in] fixed_vector Algebraic codebook vector
- * @param[in,out] samples Pointer to the output samples and memory
- */
-static void synthesis(AMRWBContext *ctx, float *lpc, float *excitation,
- float fixed_gain, const float *fixed_vector,
- float *samples)
-{
- ctx->acelpv_ctx.weighted_vector_sumf(excitation, ctx->pitch_vector, fixed_vector,
- ctx->pitch_gain[0], fixed_gain, AMRWB_SFR_SIZE);
-
- /* emphasize pitch vector contribution in low bitrate modes */
- if (ctx->pitch_gain[0] > 0.5 && ctx->fr_cur_mode <= MODE_8k85) {
- int i;
- float energy = ctx->celpm_ctx.dot_productf(excitation, excitation,
- AMRWB_SFR_SIZE);
-
- // XXX: Weird part in both ref code and spec. A unknown parameter
- // {beta} seems to be identical to the current pitch gain
- float pitch_factor = 0.25 * ctx->pitch_gain[0] * ctx->pitch_gain[0];
-
- for (i = 0; i < AMRWB_SFR_SIZE; i++)
- excitation[i] += pitch_factor * ctx->pitch_vector[i];
-
- ff_scale_vector_to_given_sum_of_squares(excitation, excitation,
- energy, AMRWB_SFR_SIZE);
- }
-
- ctx->celpf_ctx.celp_lp_synthesis_filterf(samples, lpc, excitation,
- AMRWB_SFR_SIZE, LP_ORDER);
-}
-
-/**
- * Apply to synthesis a de-emphasis filter of the form:
- * H(z) = 1 / (1 - m * z^-1)
- *
- * @param[out] out Output buffer
- * @param[in] in Input samples array with in[-1]
- * @param[in] m Filter coefficient
- * @param[in,out] mem State from last filtering
- */
-static void de_emphasis(float *out, float *in, float m, float mem[1])
-{
- int i;
-
- out[0] = in[0] + m * mem[0];
-
- for (i = 1; i < AMRWB_SFR_SIZE; i++)
- out[i] = in[i] + out[i - 1] * m;
-
- mem[0] = out[AMRWB_SFR_SIZE - 1];
-}
-
-/**
- * Upsample a signal by 5/4 ratio (from 12.8kHz to 16kHz) using
- * a FIR interpolation filter. Uses past data from before *in address.
- *
- * @param[out] out Buffer for interpolated signal
- * @param[in] in Current signal data (length 0.8*o_size)
- * @param[in] o_size Output signal length
- * @param[in] ctx The context
- */
-static void upsample_5_4(float *out, const float *in, int o_size, CELPMContext *ctx)
-{
- const float *in0 = in - UPS_FIR_SIZE + 1;
- int i, j, k;
- int int_part = 0, frac_part;
-
- i = 0;
- for (j = 0; j < o_size / 5; j++) {
- out[i] = in[int_part];
- frac_part = 4;
- i++;
-
- for (k = 1; k < 5; k++) {
- out[i] = ctx->dot_productf(in0 + int_part,
- upsample_fir[4 - frac_part],
- UPS_MEM_SIZE);
- int_part++;
- frac_part--;
- i++;
- }
- }
-}
-
-/**
- * Calculate the high-band gain based on encoded index (23k85 mode) or
- * on the low-band speech signal and the Voice Activity Detection flag.
- *
- * @param[in] ctx The context
- * @param[in] synth LB speech synthesis at 12.8k
- * @param[in] hb_idx Gain index for mode 23k85 only
- * @param[in] vad VAD flag for the frame
- */
-static float find_hb_gain(AMRWBContext *ctx, const float *synth,
- uint16_t hb_idx, uint8_t vad)
-{
- int wsp = (vad > 0);
- float tilt;
-
- if (ctx->fr_cur_mode == MODE_23k85)
- return qua_hb_gain[hb_idx] * (1.0f / (1 << 14));
-
- tilt = ctx->celpm_ctx.dot_productf(synth, synth + 1, AMRWB_SFR_SIZE - 1) /
- ctx->celpm_ctx.dot_productf(synth, synth, AMRWB_SFR_SIZE);
-
- /* return gain bounded by [0.1, 1.0] */
- return av_clipf((1.0 - FFMAX(0.0, tilt)) * (1.25 - 0.25 * wsp), 0.1, 1.0);
-}
-
-/**
- * Generate the high-band excitation with the same energy from the lower
- * one and scaled by the given gain.
- *
- * @param[in] ctx The context
- * @param[out] hb_exc Buffer for the excitation
- * @param[in] synth_exc Low-band excitation used for synthesis
- * @param[in] hb_gain Wanted excitation gain
- */
-static void scaled_hb_excitation(AMRWBContext *ctx, float *hb_exc,
- const float *synth_exc, float hb_gain)
-{
- int i;
- float energy = ctx->celpm_ctx.dot_productf(synth_exc, synth_exc,
- AMRWB_SFR_SIZE);
-
- /* Generate a white-noise excitation */
- for (i = 0; i < AMRWB_SFR_SIZE_16k; i++)
- hb_exc[i] = 32768.0 - (uint16_t) av_lfg_get(&ctx->prng);
-
- ff_scale_vector_to_given_sum_of_squares(hb_exc, hb_exc,
- energy * hb_gain * hb_gain,
- AMRWB_SFR_SIZE_16k);
-}
-
-/**
- * Calculate the auto-correlation for the ISF difference vector.
- */
-static float auto_correlation(float *diff_isf, float mean, int lag)
-{
- int i;
- float sum = 0.0;
-
- for (i = 7; i < LP_ORDER - 2; i++) {
- float prod = (diff_isf[i] - mean) * (diff_isf[i - lag] - mean);
- sum += prod * prod;
- }
- return sum;
-}
-
-/**
- * Extrapolate a ISF vector to the 16kHz range (20th order LP)
- * used at mode 6k60 LP filter for the high frequency band.
- *
- * @param[out] isf Buffer for extrapolated isf; contains LP_ORDER
- * values on input
- */
-static void extrapolate_isf(float isf[LP_ORDER_16k])
-{
- float diff_isf[LP_ORDER - 2], diff_mean;
- float corr_lag[3];
- float est, scale;
- int i, j, i_max_corr;
-
- isf[LP_ORDER_16k - 1] = isf[LP_ORDER - 1];
-
- /* Calculate the difference vector */
- for (i = 0; i < LP_ORDER - 2; i++)
- diff_isf[i] = isf[i + 1] - isf[i];
-
- diff_mean = 0.0;
- for (i = 2; i < LP_ORDER - 2; i++)
- diff_mean += diff_isf[i] * (1.0f / (LP_ORDER - 4));
-
- /* Find which is the maximum autocorrelation */
- i_max_corr = 0;
- for (i = 0; i < 3; i++) {
- corr_lag[i] = auto_correlation(diff_isf, diff_mean, i + 2);
-
- if (corr_lag[i] > corr_lag[i_max_corr])
- i_max_corr = i;
- }
- i_max_corr++;
-
- for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++)
- isf[i] = isf[i - 1] + isf[i - 1 - i_max_corr]
- - isf[i - 2 - i_max_corr];
-
- /* Calculate an estimate for ISF(18) and scale ISF based on the error */
- est = 7965 + (isf[2] - isf[3] - isf[4]) / 6.0;
- scale = 0.5 * (FFMIN(est, 7600) - isf[LP_ORDER - 2]) /
- (isf[LP_ORDER_16k - 2] - isf[LP_ORDER - 2]);
-
- for (i = LP_ORDER - 1, j = 0; i < LP_ORDER_16k - 1; i++, j++)
- diff_isf[j] = scale * (isf[i] - isf[i - 1]);
-
- /* Stability insurance */
- for (i = 1; i < LP_ORDER_16k - LP_ORDER; i++)
- if (diff_isf[i] + diff_isf[i - 1] < 5.0) {
- if (diff_isf[i] > diff_isf[i - 1]) {
- diff_isf[i - 1] = 5.0 - diff_isf[i];
- } else
- diff_isf[i] = 5.0 - diff_isf[i - 1];
- }
-
- for (i = LP_ORDER - 1, j = 0; i < LP_ORDER_16k - 1; i++, j++)
- isf[i] = isf[i - 1] + diff_isf[j] * (1.0f / (1 << 15));
-
- /* Scale the ISF vector for 16000 Hz */
- for (i = 0; i < LP_ORDER_16k - 1; i++)
- isf[i] *= 0.8;
-}
-
-/**
- * Spectral expand the LP coefficients using the equation:
- * y[i] = x[i] * (gamma ** i)
- *
- * @param[out] out Output buffer (may use input array)
- * @param[in] lpc LP coefficients array
- * @param[in] gamma Weighting factor
- * @param[in] size LP array size
- */
-static void lpc_weighting(float *out, const float *lpc, float gamma, int size)
-{
- int i;
- float fac = gamma;
-
- for (i = 0; i < size; i++) {
- out[i] = lpc[i] * fac;
- fac *= gamma;
- }
-}
-
-/**
- * Conduct 20th order linear predictive coding synthesis for the high
- * frequency band excitation at 16kHz.
- *
- * @param[in] ctx The context
- * @param[in] subframe Current subframe index (0 to 3)
- * @param[in,out] samples Pointer to the output speech samples
- * @param[in] exc Generated white-noise scaled excitation
- * @param[in] isf Current frame isf vector
- * @param[in] isf_past Past frame final isf vector
- */
-static void hb_synthesis(AMRWBContext *ctx, int subframe, float *samples,
- const float *exc, const float *isf, const float *isf_past)
-{
- float hb_lpc[LP_ORDER_16k];
- enum Mode mode = ctx->fr_cur_mode;
-
- if (mode == MODE_6k60) {
- float e_isf[LP_ORDER_16k]; // ISF vector for extrapolation
- double e_isp[LP_ORDER_16k];
-
- ctx->acelpv_ctx.weighted_vector_sumf(e_isf, isf_past, isf, isfp_inter[subframe],
- 1.0 - isfp_inter[subframe], LP_ORDER);
-
- extrapolate_isf(e_isf);
-
- e_isf[LP_ORDER_16k - 1] *= 2.0;
- ff_acelp_lsf2lspd(e_isp, e_isf, LP_ORDER_16k);
- ff_amrwb_lsp2lpc(e_isp, hb_lpc, LP_ORDER_16k);
-
- lpc_weighting(hb_lpc, hb_lpc, 0.9, LP_ORDER_16k);
- } else {
- lpc_weighting(hb_lpc, ctx->lp_coef[subframe], 0.6, LP_ORDER);
- }
-
- ctx->celpf_ctx.celp_lp_synthesis_filterf(samples, hb_lpc, exc, AMRWB_SFR_SIZE_16k,
- (mode == MODE_6k60) ? LP_ORDER_16k : LP_ORDER);
-}
-
-/**
- * Apply a 15th order filter to high-band samples.
- * The filter characteristic depends on the given coefficients.
- *
- * @param[out] out Buffer for filtered output
- * @param[in] fir_coef Filter coefficients
- * @param[in,out] mem State from last filtering (updated)
- * @param[in] in Input speech data (high-band)
- *
- * @remark It is safe to pass the same array in in and out parameters
- */
-
-#ifndef hb_fir_filter
-static void hb_fir_filter(float *out, const float fir_coef[HB_FIR_SIZE + 1],
- float mem[HB_FIR_SIZE], const float *in)
-{
- int i, j;
- float data[AMRWB_SFR_SIZE_16k + HB_FIR_SIZE]; // past and current samples
-
- memcpy(data, mem, HB_FIR_SIZE * sizeof(float));
- memcpy(data + HB_FIR_SIZE, in, AMRWB_SFR_SIZE_16k * sizeof(float));
-
- for (i = 0; i < AMRWB_SFR_SIZE_16k; i++) {
- out[i] = 0.0;
- for (j = 0; j <= HB_FIR_SIZE; j++)
- out[i] += data[i + j] * fir_coef[j];
- }
-
- memcpy(mem, data + AMRWB_SFR_SIZE_16k, HB_FIR_SIZE * sizeof(float));
-}
-#endif /* hb_fir_filter */
-
-/**
- * Update context state before the next subframe.
- */
-static void update_sub_state(AMRWBContext *ctx)
-{
- memmove(&ctx->excitation_buf[0], &ctx->excitation_buf[AMRWB_SFR_SIZE],
- (AMRWB_P_DELAY_MAX + LP_ORDER + 1) * sizeof(float));
-
- memmove(&ctx->pitch_gain[1], &ctx->pitch_gain[0], 5 * sizeof(float));
- memmove(&ctx->fixed_gain[1], &ctx->fixed_gain[0], 1 * sizeof(float));
-
- memmove(&ctx->samples_az[0], &ctx->samples_az[AMRWB_SFR_SIZE],
- LP_ORDER * sizeof(float));
- memmove(&ctx->samples_up[0], &ctx->samples_up[AMRWB_SFR_SIZE],
- UPS_MEM_SIZE * sizeof(float));
- memmove(&ctx->samples_hb[0], &ctx->samples_hb[AMRWB_SFR_SIZE_16k],
- LP_ORDER_16k * sizeof(float));
-}
-
-static int amrwb_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- AMRWBContext *ctx = avctx->priv_data;
- AVFrame *frame = data;
- AMRWBFrame *cf = &ctx->frame;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- int expected_fr_size, header_size;
- float *buf_out;
- float spare_vector[AMRWB_SFR_SIZE]; // extra stack space to hold result from anti-sparseness processing
- float fixed_gain_factor; // fixed gain correction factor (gamma)
- float *synth_fixed_vector; // pointer to the fixed vector that synthesis should use
- float synth_fixed_gain; // the fixed gain that synthesis should use
- float voice_fac, stab_fac; // parameters used for gain smoothing
- float synth_exc[AMRWB_SFR_SIZE]; // post-processed excitation for synthesis
- float hb_exc[AMRWB_SFR_SIZE_16k]; // excitation for the high frequency band
- float hb_samples[AMRWB_SFR_SIZE_16k]; // filtered high-band samples from synthesis
- float hb_gain;
- int sub, i, ret;
-
- /* get output buffer */
- frame->nb_samples = 4 * AMRWB_SFR_SIZE_16k;
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
- buf_out = (float *)frame->data[0];
-
- header_size = decode_mime_header(ctx, buf);
- if (ctx->fr_cur_mode > MODE_SID) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid mode %d\n", ctx->fr_cur_mode);
- return AVERROR_INVALIDDATA;
- }
- expected_fr_size = ((cf_sizes_wb[ctx->fr_cur_mode] + 7) >> 3) + 1;
-
- if (buf_size < expected_fr_size) {
- av_log(avctx, AV_LOG_ERROR,
- "Frame too small (%d bytes). Truncated file?\n", buf_size);
- *got_frame_ptr = 0;
- return AVERROR_INVALIDDATA;
- }
-
- if (!ctx->fr_quality || ctx->fr_cur_mode > MODE_SID)
- av_log(avctx, AV_LOG_ERROR, "Encountered a bad or corrupted frame\n");
-
- if (ctx->fr_cur_mode == MODE_SID) { /* Comfort noise frame */
- avpriv_request_sample(avctx, "SID mode");
- return AVERROR_PATCHWELCOME;
- }
-
- ff_amr_bit_reorder((uint16_t *) &ctx->frame, sizeof(AMRWBFrame),
- buf + header_size, amr_bit_orderings_by_mode[ctx->fr_cur_mode]);
-
- /* Decode the quantized ISF vector */
- if (ctx->fr_cur_mode == MODE_6k60) {
- decode_isf_indices_36b(cf->isp_id, ctx->isf_cur);
- } else {
- decode_isf_indices_46b(cf->isp_id, ctx->isf_cur);
- }
-
- isf_add_mean_and_past(ctx->isf_cur, ctx->isf_q_past);
- ff_set_min_dist_lsf(ctx->isf_cur, MIN_ISF_SPACING, LP_ORDER - 1);
-
- stab_fac = stability_factor(ctx->isf_cur, ctx->isf_past_final);
-
- ctx->isf_cur[LP_ORDER - 1] *= 2.0;
- ff_acelp_lsf2lspd(ctx->isp[3], ctx->isf_cur, LP_ORDER);
-
- /* Generate a ISP vector for each subframe */
- if (ctx->first_frame) {
- ctx->first_frame = 0;
- memcpy(ctx->isp_sub4_past, ctx->isp[3], LP_ORDER * sizeof(double));
- }
- interpolate_isp(ctx->isp, ctx->isp_sub4_past);
-
- for (sub = 0; sub < 4; sub++)
- ff_amrwb_lsp2lpc(ctx->isp[sub], ctx->lp_coef[sub], LP_ORDER);
-
- for (sub = 0; sub < 4; sub++) {
- const AMRWBSubFrame *cur_subframe = &cf->subframe[sub];
- float *sub_buf = buf_out + sub * AMRWB_SFR_SIZE_16k;
-
- /* Decode adaptive codebook (pitch vector) */
- decode_pitch_vector(ctx, cur_subframe, sub);
- /* Decode innovative codebook (fixed vector) */
- decode_fixed_vector(ctx->fixed_vector, cur_subframe->pul_ih,
- cur_subframe->pul_il, ctx->fr_cur_mode);
-
- pitch_sharpening(ctx, ctx->fixed_vector);
-
- decode_gains(cur_subframe->vq_gain, ctx->fr_cur_mode,
- &fixed_gain_factor, &ctx->pitch_gain[0]);
-
- ctx->fixed_gain[0] =
- ff_amr_set_fixed_gain(fixed_gain_factor,
- ctx->celpm_ctx.dot_productf(ctx->fixed_vector,
- ctx->fixed_vector,
- AMRWB_SFR_SIZE) /
- AMRWB_SFR_SIZE,
- ctx->prediction_error,
- ENERGY_MEAN, energy_pred_fac);
-
- /* Calculate voice factor and store tilt for next subframe */
- voice_fac = voice_factor(ctx->pitch_vector, ctx->pitch_gain[0],
- ctx->fixed_vector, ctx->fixed_gain[0],
- &ctx->celpm_ctx);
- ctx->tilt_coef = voice_fac * 0.25 + 0.25;
-
- /* Construct current excitation */
- for (i = 0; i < AMRWB_SFR_SIZE; i++) {
- ctx->excitation[i] *= ctx->pitch_gain[0];
- ctx->excitation[i] += ctx->fixed_gain[0] * ctx->fixed_vector[i];
- ctx->excitation[i] = truncf(ctx->excitation[i]);
- }
-
- /* Post-processing of excitation elements */
- synth_fixed_gain = noise_enhancer(ctx->fixed_gain[0], &ctx->prev_tr_gain,
- voice_fac, stab_fac);
-
- synth_fixed_vector = anti_sparseness(ctx, ctx->fixed_vector,
- spare_vector);
-
- pitch_enhancer(synth_fixed_vector, voice_fac);
-
- synthesis(ctx, ctx->lp_coef[sub], synth_exc, synth_fixed_gain,
- synth_fixed_vector, &ctx->samples_az[LP_ORDER]);
-
- /* Synthesis speech post-processing */
- de_emphasis(&ctx->samples_up[UPS_MEM_SIZE],
- &ctx->samples_az[LP_ORDER], PREEMPH_FAC, ctx->demph_mem);
-
- ctx->acelpf_ctx.acelp_apply_order_2_transfer_function(&ctx->samples_up[UPS_MEM_SIZE],
- &ctx->samples_up[UPS_MEM_SIZE], hpf_zeros, hpf_31_poles,
- hpf_31_gain, ctx->hpf_31_mem, AMRWB_SFR_SIZE);
-
- upsample_5_4(sub_buf, &ctx->samples_up[UPS_FIR_SIZE],
- AMRWB_SFR_SIZE_16k, &ctx->celpm_ctx);
-
- /* High frequency band (6.4 - 7.0 kHz) generation part */
- ctx->acelpf_ctx.acelp_apply_order_2_transfer_function(hb_samples,
- &ctx->samples_up[UPS_MEM_SIZE], hpf_zeros, hpf_400_poles,
- hpf_400_gain, ctx->hpf_400_mem, AMRWB_SFR_SIZE);
-
- hb_gain = find_hb_gain(ctx, hb_samples,
- cur_subframe->hb_gain, cf->vad);
-
- scaled_hb_excitation(ctx, hb_exc, synth_exc, hb_gain);
-
- hb_synthesis(ctx, sub, &ctx->samples_hb[LP_ORDER_16k],
- hb_exc, ctx->isf_cur, ctx->isf_past_final);
-
- /* High-band post-processing filters */
- hb_fir_filter(hb_samples, bpf_6_7_coef, ctx->bpf_6_7_mem,
- &ctx->samples_hb[LP_ORDER_16k]);
-
- if (ctx->fr_cur_mode == MODE_23k85)
- hb_fir_filter(hb_samples, lpf_7_coef, ctx->lpf_7_mem,
- hb_samples);
-
- /* Add the low and high frequency bands */
- for (i = 0; i < AMRWB_SFR_SIZE_16k; i++)
- sub_buf[i] = (sub_buf[i] + hb_samples[i]) * (1.0f / (1 << 15));
-
- /* Update buffers and history */
- update_sub_state(ctx);
- }
-
- /* update state for next frame */
- memcpy(ctx->isp_sub4_past, ctx->isp[3], LP_ORDER * sizeof(ctx->isp[3][0]));
- memcpy(ctx->isf_past_final, ctx->isf_cur, LP_ORDER * sizeof(float));
-
- *got_frame_ptr = 1;
-
- return expected_fr_size;
-}
-
-AVCodec ff_amrwb_decoder = {
- .name = "amrwb",
- .long_name = NULL_IF_CONFIG_SMALL("AMR-WB (Adaptive Multi-Rate WideBand)"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_AMR_WB,
- .priv_data_size = sizeof(AMRWBContext),
- .init = amrwb_decode_init,
- .decode = amrwb_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
- .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
- AV_SAMPLE_FMT_NONE },
-};
diff --git a/ffmpeg-2-8-11/libavcodec/ansi.c b/ffmpeg-2-8-11/libavcodec/ansi.c
deleted file mode 100644
index 98ea9e3..0000000
--- a/ffmpeg-2-8-11/libavcodec/ansi.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * ASCII/ANSI art decoder
- * Copyright (c) 2010 Peter Ross <pross at 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
- * ASCII/ANSI art decoder
- */
-
-#include "libavutil/common.h"
-#include "libavutil/frame.h"
-#include "libavutil/lfg.h"
-#include "libavutil/xga_font_data.h"
-#include "avcodec.h"
-#include "cga_data.h"
-#include "internal.h"
-
-#define ATTR_BOLD 0x01 /**< Bold/Bright-foreground (mode 1) */
-#define ATTR_FAINT 0x02 /**< Faint (mode 2) */
-#define ATTR_UNDERLINE 0x08 /**< Underline (mode 4) */
-#define ATTR_BLINK 0x10 /**< Blink/Bright-background (mode 5) */
-#define ATTR_REVERSE 0x40 /**< Reverse (mode 7) */
-#define ATTR_CONCEALED 0x80 /**< Concealed (mode 8) */
-
-#define DEFAULT_FG_COLOR 7 /**< CGA color index */
-#define DEFAULT_BG_COLOR 0
-#define DEFAULT_SCREEN_MODE 3 /**< 80x25 */
-
-#define FONT_WIDTH 8 /**< Font width */
-
-/** map ansi color index to cga palette index */
-static const uint8_t ansi_to_cga[16] = {
- 0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15
-};
-
-typedef struct AnsiContext {
- AVFrame *frame;
- int x; /**< x cursor position (pixels) */
- int y; /**< y cursor position (pixels) */
- int sx; /**< saved x cursor position (pixels) */
- int sy; /**< saved y cursor position (pixels) */
- const uint8_t* font; /**< font */
- int font_height; /**< font height */
- int attributes; /**< attribute flags */
- int fg; /**< foreground color */
- int bg; /**< background color */
- int first_frame;
-
- /* ansi parser state machine */
- enum {
- STATE_NORMAL = 0,
- STATE_ESCAPE,
- STATE_CODE,
- STATE_MUSIC_PREAMBLE
- } state;
-#define MAX_NB_ARGS 4
- int args[MAX_NB_ARGS];
- int nb_args; /**< number of arguments (may exceed MAX_NB_ARGS) */
-} AnsiContext;
-
-static av_cold int decode_init(AVCodecContext *avctx)
-{
- AnsiContext *s = avctx->priv_data;
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
-
- s->frame = av_frame_alloc();
- if (!s->frame)
- return AVERROR(ENOMEM);
-
- /* defaults */
- s->font = avpriv_vga16_font;
- s->font_height = 16;
- s->fg = DEFAULT_FG_COLOR;
- s->bg = DEFAULT_BG_COLOR;
-
- if (!avctx->width || !avctx->height) {
- int ret = ff_set_dimensions(avctx, 80 << 3, 25 << 4);
- if (ret < 0)
- return ret;
- } else if (avctx->width % FONT_WIDTH || avctx->height % s->font_height) {
- av_log(avctx, AV_LOG_ERROR, "Invalid dimensions %d %d\n", avctx->width, avctx->height);
- return AVERROR(EINVAL);
- }
- return 0;
-}
-
-static void set_palette(uint32_t *pal)
-{
- int r, g, b;
- memcpy(pal, ff_cga_palette, 16 * 4);
- pal += 16;
-#define COLOR(x) ((x) * 40 + 55)
- for (r = 0; r < 6; r++)
- for (g = 0; g < 6; g++)
- for (b = 0; b < 6; b++)
- *pal++ = 0xFF000000 | (COLOR(r) << 16) | (COLOR(g) << 8) | COLOR(b);
-#define GRAY(x) ((x) * 10 + 8)
- for (g = 0; g < 24; g++)
- *pal++ = 0xFF000000 | (GRAY(g) << 16) | (GRAY(g) << 8) | GRAY(g);
-}
-
-static void hscroll(AVCodecContext *avctx)
-{
- AnsiContext *s = avctx->priv_data;
- int i;
-
- if (s->y <= avctx->height - 2*s->font_height) {
- s->y += s->font_height;
- return;
- }
-
- i = 0;
- for (; i < avctx->height - s->font_height; i++)
- memcpy(s->frame->data[0] + i * s->frame->linesize[0],
- s->frame->data[0] + (i + s->font_height) * s->frame->linesize[0],
- avctx->width);
- for (; i < avctx->height; i++)
- memset(s->frame->data[0] + i * s->frame->linesize[0],
- DEFAULT_BG_COLOR, avctx->width);
-}
-
-static void erase_line(AVCodecContext * avctx, int xoffset, int xlength)
-{
- AnsiContext *s = avctx->priv_data;
- int i;
- for (i = 0; i < s->font_height; i++)
- memset(s->frame->data[0] + (s->y + i)*s->frame->linesize[0] + xoffset,
- DEFAULT_BG_COLOR, xlength);
-}
-
-static void erase_screen(AVCodecContext *avctx)
-{
- AnsiContext *s = avctx->priv_data;
- int i;
- for (i = 0; i < avctx->height; i++)
- memset(s->frame->data[0] + i * s->frame->linesize[0], DEFAULT_BG_COLOR, avctx->width);
- s->x = s->y = 0;
-}
-
-/**
- * Draw character to screen
- */
-static void draw_char(AVCodecContext *avctx, int c)
-{
- AnsiContext *s = avctx->priv_data;
- int fg = s->fg;
- int bg = s->bg;
-
- if ((s->attributes & ATTR_BOLD))
- fg += 8;
- if ((s->attributes & ATTR_BLINK))
- bg += 8;
- if ((s->attributes & ATTR_REVERSE))
- FFSWAP(int, fg, bg);
- if ((s->attributes & ATTR_CONCEALED))
- fg = bg;
- ff_draw_pc_font(s->frame->data[0] + s->y * s->frame->linesize[0] + s->x,
- s->frame->linesize[0], s->font, s->font_height, c, fg, bg);
- s->x += FONT_WIDTH;
- if (s->x > avctx->width - FONT_WIDTH) {
- s->x = 0;
- hscroll(avctx);
- }
-}
-
-/**
- * Execute ANSI escape code
- * @return 0 on success, negative on error
- */
-static int execute_code(AVCodecContext * avctx, int c)
-{
- AnsiContext *s = avctx->priv_data;
- int ret, i;
- int width = avctx->width;
- int height = avctx->height;
-
- switch(c) {
- case 'A': //Cursor Up
- s->y = FFMAX(s->y - (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), 0);
- break;
- case 'B': //Cursor Down
- s->y = FFMIN(s->y + (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), avctx->height - s->font_height);
- break;
- case 'C': //Cursor Right
- s->x = FFMIN(s->x + (s->nb_args > 0 ? s->args[0]*FONT_WIDTH : FONT_WIDTH), avctx->width - FONT_WIDTH);
- break;
- case 'D': //Cursor Left
- s->x = FFMAX(s->x - (s->nb_args > 0 ? s->args[0]*FONT_WIDTH : FONT_WIDTH), 0);
- break;
- case 'H': //Cursor Position
- case 'f': //Horizontal and Vertical Position
- s->y = s->nb_args > 0 ? av_clip((s->args[0] - 1)*s->font_height, 0, avctx->height - s->font_height) : 0;
- s->x = s->nb_args > 1 ? av_clip((s->args[1] - 1)*FONT_WIDTH, 0, avctx->width - FONT_WIDTH) : 0;
- break;
- case 'h': //set creen mode
- case 'l': //reset screen mode
- if (s->nb_args < 2)
- s->args[0] = DEFAULT_SCREEN_MODE;
- switch(s->args[0]) {
- case 0: case 1: case 4: case 5: case 13: case 19: //320x200 (25 rows)
- s->font = avpriv_cga_font;
- s->font_height = 8;
- width = 40<<3;
- height = 25<<3;
- break;
- case 2: case 3: //640x400 (25 rows)
- s->font = avpriv_vga16_font;
- s->font_height = 16;
- width = 80<<3;
- height = 25<<4;
- break;
- case 6: case 14: //640x200 (25 rows)
- s->font = avpriv_cga_font;
- s->font_height = 8;
- width = 80<<3;
- height = 25<<3;
- break;
- case 7: //set line wrapping
- break;
- case 15: case 16: //640x350 (43 rows)
- s->font = avpriv_cga_font;
- s->font_height = 8;
- width = 80<<3;
- height = 43<<3;
- break;
- case 17: case 18: //640x480 (60 rows)
- s->font = avpriv_cga_font;
- s->font_height = 8;
- width = 80<<3;
- height = 60<<4;
- break;
- default:
- avpriv_request_sample(avctx, "Unsupported screen mode");
- }
- s->x = av_clip(s->x, 0, width - FONT_WIDTH);
- s->y = av_clip(s->y, 0, height - s->font_height);
- if (width != avctx->width || height != avctx->height) {
- av_frame_unref(s->frame);
- ret = ff_set_dimensions(avctx, width, height);
- if (ret < 0)
- return ret;
- if ((ret = ff_get_buffer(avctx, s->frame,
- AV_GET_BUFFER_FLAG_REF)) < 0)
- return ret;
- s->frame->pict_type = AV_PICTURE_TYPE_I;
- s->frame->palette_has_changed = 1;
- set_palette((uint32_t *)s->frame->data[1]);
- erase_screen(avctx);
- } else if (c == 'l') {
- erase_screen(avctx);
- }
- break;
- case 'J': //Erase in Page
- switch (s->args[0]) {
- case 0:
- erase_line(avctx, s->x, avctx->width - s->x);
- if (s->y < avctx->height - s->font_height)
- memset(s->frame->data[0] + (s->y + s->font_height)*s->frame->linesize[0],
- DEFAULT_BG_COLOR, (avctx->height - s->y - s->font_height)*s->frame->linesize[0]);
- break;
- case 1:
- erase_line(avctx, 0, s->x);
- if (s->y > 0)
- memset(s->frame->data[0], DEFAULT_BG_COLOR, s->y * s->frame->linesize[0]);
- break;
- case 2:
- erase_screen(avctx);
- }
- break;
- case 'K': //Erase in Line
- switch(s->args[0]) {
- case 0:
- erase_line(avctx, s->x, avctx->width - s->x);
- break;
- case 1:
- erase_line(avctx, 0, s->x);
- break;
- case 2:
- erase_line(avctx, 0, avctx->width);
- }
- break;
- case 'm': //Select Graphics Rendition
- if (s->nb_args == 0) {
- s->nb_args = 1;
- s->args[0] = 0;
- }
- for (i = 0; i < FFMIN(s->nb_args, MAX_NB_ARGS); i++) {
- int m = s->args[i];
- if (m == 0) {
- s->attributes = 0;
- s->fg = DEFAULT_FG_COLOR;
- s->bg = DEFAULT_BG_COLOR;
- } else if (m == 1 || m == 2 || m == 4 || m == 5 || m == 7 || m == 8) {
- s->attributes |= 1 << (m - 1);
- } else if (m >= 30 && m <= 37) {
- s->fg = ansi_to_cga[m - 30];
- } else if (m == 38 && i + 2 < FFMIN(s->nb_args, MAX_NB_ARGS) && s->args[i + 1] == 5 && s->args[i + 2] < 256) {
- int index = s->args[i + 2];
- s->fg = index < 16 ? ansi_to_cga[index] : index;
- i += 2;
- } else if (m == 39) {
- s->fg = ansi_to_cga[DEFAULT_FG_COLOR];
- } else if (m >= 40 && m <= 47) {
- s->bg = ansi_to_cga[m - 40];
- } else if (m == 48 && i + 2 < FFMIN(s->nb_args, MAX_NB_ARGS) && s->args[i + 1] == 5 && s->args[i + 2] < 256) {
- int index = s->args[i + 2];
- s->bg = index < 16 ? ansi_to_cga[index] : index;
- i += 2;
- } else if (m == 49) {
- s->fg = ansi_to_cga[DEFAULT_BG_COLOR];
- } else {
- avpriv_request_sample(avctx, "Unsupported rendition parameter");
- }
- }
- break;
- case 'n': //Device Status Report
- case 'R': //report current line and column
- /* ignore */
- break;
- case 's': //Save Cursor Position
- s->sx = s->x;
- s->sy = s->y;
- break;
- case 'u': //Restore Cursor Position
- s->x = av_clip(s->sx, 0, avctx->width - FONT_WIDTH);
- s->y = av_clip(s->sy, 0, avctx->height - s->font_height);
- break;
- default:
- avpriv_request_sample(avctx, "Unknown escape code");
- break;
- }
- s->x = av_clip(s->x, 0, avctx->width - FONT_WIDTH);
- s->y = av_clip(s->y, 0, avctx->height - s->font_height);
- return 0;
-}
-
-static int decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- AnsiContext *s = avctx->priv_data;
- uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- const uint8_t *buf_end = buf+buf_size;
- int ret, i, count;
-
- if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
- return ret;
- if (!avctx->frame_number) {
- for (i=0; i<avctx->height; i++)
- memset(s->frame->data[0]+ i*s->frame->linesize[0], 0, avctx->width);
- memset(s->frame->data[1], 0, AVPALETTE_SIZE);
- }
-
- s->frame->pict_type = AV_PICTURE_TYPE_I;
- s->frame->palette_has_changed = 1;
- set_palette((uint32_t *)s->frame->data[1]);
- if (!s->first_frame) {
- erase_screen(avctx);
- s->first_frame = 1;
- }
-
- while(buf < buf_end) {
- switch(s->state) {
- case STATE_NORMAL:
- switch (buf[0]) {
- case 0x00: //NUL
- case 0x07: //BEL
- case 0x1A: //SUB
- /* ignore */
- break;
- case 0x08: //BS
- s->x = FFMAX(s->x - 1, 0);
- break;
- case 0x09: //HT
- i = s->x / FONT_WIDTH;
- count = ((i + 8) & ~7) - i;
- for (i = 0; i < count; i++)
- draw_char(avctx, ' ');
- break;
- case 0x0A: //LF
- hscroll(avctx);
- case 0x0D: //CR
- s->x = 0;
- break;
- case 0x0C: //FF
- erase_screen(avctx);
- break;
- case 0x1B: //ESC
- s->state = STATE_ESCAPE;
- break;
- default:
- draw_char(avctx, buf[0]);
- }
- break;
- case STATE_ESCAPE:
- if (buf[0] == '[') {
- s->state = STATE_CODE;
- s->nb_args = 0;
- s->args[0] = -1;
- } else {
- s->state = STATE_NORMAL;
- draw_char(avctx, 0x1B);
- continue;
- }
- break;
- case STATE_CODE:
- switch(buf[0]) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- if (s->nb_args < MAX_NB_ARGS && s->args[s->nb_args] < 6553)
- s->args[s->nb_args] = FFMAX(s->args[s->nb_args], 0) * 10 + buf[0] - '0';
- break;
- case ';':
- s->nb_args++;
- if (s->nb_args < MAX_NB_ARGS)
- s->args[s->nb_args] = 0;
- break;
- case 'M':
- s->state = STATE_MUSIC_PREAMBLE;
- break;
- case '=': case '?':
- /* ignore */
- break;
- default:
- if (s->nb_args > MAX_NB_ARGS)
- av_log(avctx, AV_LOG_WARNING, "args overflow (%i)\n", s->nb_args);
- if (s->nb_args < MAX_NB_ARGS && s->args[s->nb_args] >= 0)
- s->nb_args++;
- if ((ret = execute_code(avctx, buf[0])) < 0)
- return ret;
- s->state = STATE_NORMAL;
- }
- break;
- case STATE_MUSIC_PREAMBLE:
- if (buf[0] == 0x0E || buf[0] == 0x1B)
- s->state = STATE_NORMAL;
- /* ignore music data */
- break;
- }
- buf++;
- }
-
- *got_frame = 1;
- if ((ret = av_frame_ref(data, s->frame)) < 0)
- return ret;
- return buf_size;
-}
-
-static av_cold int decode_close(AVCodecContext *avctx)
-{
- AnsiContext *s = avctx->priv_data;
-
- av_frame_free(&s->frame);
- return 0;
-}
-
-AVCodec ff_ansi_decoder = {
- .name = "ansi",
- .long_name = NULL_IF_CONFIG_SMALL("ASCII/ANSI art"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_ANSI,
- .priv_data_size = sizeof(AnsiContext),
- .init = decode_init,
- .close = decode_close,
- .decode = decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/avcodec.h b/ffmpeg-2-8-11/libavcodec/avcodec.h
deleted file mode 100644
index 9d38b59..0000000
--- a/ffmpeg-2-8-11/libavcodec/avcodec.h
+++ /dev/null
@@ -1,5613 +0,0 @@
-/*
- * copyright (c) 2001 Fabrice Bellard
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVCODEC_AVCODEC_H
-#define AVCODEC_AVCODEC_H
-
-/**
- * @file
- * @ingroup libavc
- * Libavcodec external API header
- */
-
-#include <errno.h>
-#include "libavutil/samplefmt.h"
-#include "libavutil/attributes.h"
-#include "libavutil/avutil.h"
-#include "libavutil/buffer.h"
-#include "libavutil/cpu.h"
-#include "libavutil/channel_layout.h"
-#include "libavutil/dict.h"
-#include "libavutil/frame.h"
-#include "libavutil/log.h"
-#include "libavutil/pixfmt.h"
-#include "libavutil/rational.h"
-
-#include "version.h"
-
-/**
- * @defgroup libavc Encoding/Decoding Library
- * @{
- *
- * @defgroup lavc_decoding Decoding
- * @{
- * @}
- *
- * @defgroup lavc_encoding Encoding
- * @{
- * @}
- *
- * @defgroup lavc_codec Codecs
- * @{
- * @defgroup lavc_codec_native Native Codecs
- * @{
- * @}
- * @defgroup lavc_codec_wrappers External library wrappers
- * @{
- * @}
- * @defgroup lavc_codec_hwaccel Hardware Accelerators bridge
- * @{
- * @}
- * @}
- * @defgroup lavc_internal Internal
- * @{
- * @}
- * @}
- *
- */
-
-/**
- * @defgroup lavc_core Core functions/structures.
- * @ingroup libavc
- *
- * Basic definitions, functions for querying libavcodec capabilities,
- * allocating core structures, etc.
- * @{
- */
-
-
-/**
- * Identify the syntax and semantics of the bitstream.
- * The principle is roughly:
- * Two decoders with the same ID can decode the same streams.
- * Two encoders with the same ID can encode compatible streams.
- * There may be slight deviations from the principle due to implementation
- * details.
- *
- * If you add a codec ID to this list, add it so that
- * 1. no value of a existing codec ID changes (that would break ABI),
- * 2. Give it a value which when taken as ASCII is recognized uniquely by a human as this specific codec.
- * This ensures that 2 forks can independently add AVCodecIDs without producing conflicts.
- *
- * After adding new codec IDs, do not forget to add an entry to the codec
- * descriptor list and bump libavcodec minor version.
- */
-enum AVCodecID {
- AV_CODEC_ID_NONE,
-
- /* video codecs */
- AV_CODEC_ID_MPEG1VIDEO,
- AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
-#if FF_API_XVMC
- AV_CODEC_ID_MPEG2VIDEO_XVMC,
-#endif /* FF_API_XVMC */
- AV_CODEC_ID_H261,
- AV_CODEC_ID_H263,
- AV_CODEC_ID_RV10,
- AV_CODEC_ID_RV20,
- AV_CODEC_ID_MJPEG,
- AV_CODEC_ID_MJPEGB,
- AV_CODEC_ID_LJPEG,
- AV_CODEC_ID_SP5X,
- AV_CODEC_ID_JPEGLS,
- AV_CODEC_ID_MPEG4,
- AV_CODEC_ID_RAWVIDEO,
- AV_CODEC_ID_MSMPEG4V1,
- AV_CODEC_ID_MSMPEG4V2,
- AV_CODEC_ID_MSMPEG4V3,
- AV_CODEC_ID_WMV1,
- AV_CODEC_ID_WMV2,
- AV_CODEC_ID_H263P,
- AV_CODEC_ID_H263I,
- AV_CODEC_ID_FLV1,
- AV_CODEC_ID_SVQ1,
- AV_CODEC_ID_SVQ3,
- AV_CODEC_ID_DVVIDEO,
- AV_CODEC_ID_HUFFYUV,
- AV_CODEC_ID_CYUV,
- AV_CODEC_ID_H264,
- AV_CODEC_ID_INDEO3,
- AV_CODEC_ID_VP3,
- AV_CODEC_ID_THEORA,
- AV_CODEC_ID_ASV1,
- AV_CODEC_ID_ASV2,
- AV_CODEC_ID_FFV1,
- AV_CODEC_ID_4XM,
- AV_CODEC_ID_VCR1,
- AV_CODEC_ID_CLJR,
- AV_CODEC_ID_MDEC,
- AV_CODEC_ID_ROQ,
- AV_CODEC_ID_INTERPLAY_VIDEO,
- AV_CODEC_ID_XAN_WC3,
- AV_CODEC_ID_XAN_WC4,
- AV_CODEC_ID_RPZA,
- AV_CODEC_ID_CINEPAK,
- AV_CODEC_ID_WS_VQA,
- AV_CODEC_ID_MSRLE,
- AV_CODEC_ID_MSVIDEO1,
- AV_CODEC_ID_IDCIN,
- AV_CODEC_ID_8BPS,
- AV_CODEC_ID_SMC,
- AV_CODEC_ID_FLIC,
- AV_CODEC_ID_TRUEMOTION1,
- AV_CODEC_ID_VMDVIDEO,
- AV_CODEC_ID_MSZH,
- AV_CODEC_ID_ZLIB,
- AV_CODEC_ID_QTRLE,
- AV_CODEC_ID_TSCC,
- AV_CODEC_ID_ULTI,
- AV_CODEC_ID_QDRAW,
- AV_CODEC_ID_VIXL,
- AV_CODEC_ID_QPEG,
- AV_CODEC_ID_PNG,
- AV_CODEC_ID_PPM,
- AV_CODEC_ID_PBM,
- AV_CODEC_ID_PGM,
- AV_CODEC_ID_PGMYUV,
- AV_CODEC_ID_PAM,
- AV_CODEC_ID_FFVHUFF,
- AV_CODEC_ID_RV30,
- AV_CODEC_ID_RV40,
- AV_CODEC_ID_VC1,
- AV_CODEC_ID_WMV3,
- AV_CODEC_ID_LOCO,
- AV_CODEC_ID_WNV1,
- AV_CODEC_ID_AASC,
- AV_CODEC_ID_INDEO2,
- AV_CODEC_ID_FRAPS,
- AV_CODEC_ID_TRUEMOTION2,
- AV_CODEC_ID_BMP,
- AV_CODEC_ID_CSCD,
- AV_CODEC_ID_MMVIDEO,
- AV_CODEC_ID_ZMBV,
- AV_CODEC_ID_AVS,
- AV_CODEC_ID_SMACKVIDEO,
- AV_CODEC_ID_NUV,
- AV_CODEC_ID_KMVC,
- AV_CODEC_ID_FLASHSV,
- AV_CODEC_ID_CAVS,
- AV_CODEC_ID_JPEG2000,
- AV_CODEC_ID_VMNC,
- AV_CODEC_ID_VP5,
- AV_CODEC_ID_VP6,
- AV_CODEC_ID_VP6F,
- AV_CODEC_ID_TARGA,
- AV_CODEC_ID_DSICINVIDEO,
- AV_CODEC_ID_TIERTEXSEQVIDEO,
- AV_CODEC_ID_TIFF,
- AV_CODEC_ID_GIF,
- AV_CODEC_ID_DXA,
- AV_CODEC_ID_DNXHD,
- AV_CODEC_ID_THP,
- AV_CODEC_ID_SGI,
- AV_CODEC_ID_C93,
- AV_CODEC_ID_BETHSOFTVID,
- AV_CODEC_ID_PTX,
- AV_CODEC_ID_TXD,
- AV_CODEC_ID_VP6A,
- AV_CODEC_ID_AMV,
- AV_CODEC_ID_VB,
- AV_CODEC_ID_PCX,
- AV_CODEC_ID_SUNRAST,
- AV_CODEC_ID_INDEO4,
- AV_CODEC_ID_INDEO5,
- AV_CODEC_ID_MIMIC,
- AV_CODEC_ID_RL2,
- AV_CODEC_ID_ESCAPE124,
- AV_CODEC_ID_DIRAC,
- AV_CODEC_ID_BFI,
- AV_CODEC_ID_CMV,
- AV_CODEC_ID_MOTIONPIXELS,
- AV_CODEC_ID_TGV,
- AV_CODEC_ID_TGQ,
- AV_CODEC_ID_TQI,
- AV_CODEC_ID_AURA,
- AV_CODEC_ID_AURA2,
- AV_CODEC_ID_V210X,
- AV_CODEC_ID_TMV,
- AV_CODEC_ID_V210,
- AV_CODEC_ID_DPX,
- AV_CODEC_ID_MAD,
- AV_CODEC_ID_FRWU,
- AV_CODEC_ID_FLASHSV2,
- AV_CODEC_ID_CDGRAPHICS,
- AV_CODEC_ID_R210,
- AV_CODEC_ID_ANM,
- AV_CODEC_ID_BINKVIDEO,
- AV_CODEC_ID_IFF_ILBM,
- AV_CODEC_ID_IFF_BYTERUN1,
- AV_CODEC_ID_KGV1,
- AV_CODEC_ID_YOP,
- AV_CODEC_ID_VP8,
- AV_CODEC_ID_PICTOR,
- AV_CODEC_ID_ANSI,
- AV_CODEC_ID_A64_MULTI,
- AV_CODEC_ID_A64_MULTI5,
- AV_CODEC_ID_R10K,
- AV_CODEC_ID_MXPEG,
- AV_CODEC_ID_LAGARITH,
- AV_CODEC_ID_PRORES,
- AV_CODEC_ID_JV,
- AV_CODEC_ID_DFA,
- AV_CODEC_ID_WMV3IMAGE,
- AV_CODEC_ID_VC1IMAGE,
- AV_CODEC_ID_UTVIDEO,
- AV_CODEC_ID_BMV_VIDEO,
- AV_CODEC_ID_VBLE,
- AV_CODEC_ID_DXTORY,
- AV_CODEC_ID_V410,
- AV_CODEC_ID_XWD,
- AV_CODEC_ID_CDXL,
- AV_CODEC_ID_XBM,
- AV_CODEC_ID_ZEROCODEC,
- AV_CODEC_ID_MSS1,
- AV_CODEC_ID_MSA1,
- AV_CODEC_ID_TSCC2,
- AV_CODEC_ID_MTS2,
- AV_CODEC_ID_CLLC,
- AV_CODEC_ID_MSS2,
- AV_CODEC_ID_VP9,
- AV_CODEC_ID_AIC,
- AV_CODEC_ID_ESCAPE130_DEPRECATED,
- AV_CODEC_ID_G2M_DEPRECATED,
- AV_CODEC_ID_WEBP_DEPRECATED,
- AV_CODEC_ID_HNM4_VIDEO,
- AV_CODEC_ID_HEVC_DEPRECATED,
- AV_CODEC_ID_FIC,
- AV_CODEC_ID_ALIAS_PIX,
- AV_CODEC_ID_BRENDER_PIX_DEPRECATED,
- AV_CODEC_ID_PAF_VIDEO_DEPRECATED,
- AV_CODEC_ID_EXR_DEPRECATED,
- AV_CODEC_ID_VP7_DEPRECATED,
- AV_CODEC_ID_SANM_DEPRECATED,
- AV_CODEC_ID_SGIRLE_DEPRECATED,
- AV_CODEC_ID_MVC1_DEPRECATED,
- AV_CODEC_ID_MVC2_DEPRECATED,
- AV_CODEC_ID_HQX,
- AV_CODEC_ID_TDSC,
- AV_CODEC_ID_HQ_HQA,
- AV_CODEC_ID_HAP,
- AV_CODEC_ID_DDS,
-
- AV_CODEC_ID_BRENDER_PIX= MKBETAG('B','P','I','X'),
- AV_CODEC_ID_Y41P = MKBETAG('Y','4','1','P'),
- AV_CODEC_ID_ESCAPE130 = MKBETAG('E','1','3','0'),
- AV_CODEC_ID_EXR = MKBETAG('0','E','X','R'),
- AV_CODEC_ID_AVRP = MKBETAG('A','V','R','P'),
-
- AV_CODEC_ID_012V = MKBETAG('0','1','2','V'),
- AV_CODEC_ID_G2M = MKBETAG( 0 ,'G','2','M'),
- AV_CODEC_ID_AVUI = MKBETAG('A','V','U','I'),
- AV_CODEC_ID_AYUV = MKBETAG('A','Y','U','V'),
- AV_CODEC_ID_TARGA_Y216 = MKBETAG('T','2','1','6'),
- AV_CODEC_ID_V308 = MKBETAG('V','3','0','8'),
- AV_CODEC_ID_V408 = MKBETAG('V','4','0','8'),
- AV_CODEC_ID_YUV4 = MKBETAG('Y','U','V','4'),
- AV_CODEC_ID_SANM = MKBETAG('S','A','N','M'),
- AV_CODEC_ID_PAF_VIDEO = MKBETAG('P','A','F','V'),
- AV_CODEC_ID_AVRN = MKBETAG('A','V','R','n'),
- AV_CODEC_ID_CPIA = MKBETAG('C','P','I','A'),
- AV_CODEC_ID_XFACE = MKBETAG('X','F','A','C'),
- AV_CODEC_ID_SGIRLE = MKBETAG('S','G','I','R'),
- AV_CODEC_ID_MVC1 = MKBETAG('M','V','C','1'),
- AV_CODEC_ID_MVC2 = MKBETAG('M','V','C','2'),
- AV_CODEC_ID_SNOW = MKBETAG('S','N','O','W'),
- AV_CODEC_ID_WEBP = MKBETAG('W','E','B','P'),
- AV_CODEC_ID_SMVJPEG = MKBETAG('S','M','V','J'),
- AV_CODEC_ID_HEVC = MKBETAG('H','2','6','5'),
-#define AV_CODEC_ID_H265 AV_CODEC_ID_HEVC
- AV_CODEC_ID_VP7 = MKBETAG('V','P','7','0'),
- AV_CODEC_ID_APNG = MKBETAG('A','P','N','G'),
-
- /* various PCM "codecs" */
- AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
- AV_CODEC_ID_PCM_S16LE = 0x10000,
- AV_CODEC_ID_PCM_S16BE,
- AV_CODEC_ID_PCM_U16LE,
- AV_CODEC_ID_PCM_U16BE,
- AV_CODEC_ID_PCM_S8,
- AV_CODEC_ID_PCM_U8,
- AV_CODEC_ID_PCM_MULAW,
- AV_CODEC_ID_PCM_ALAW,
- AV_CODEC_ID_PCM_S32LE,
- AV_CODEC_ID_PCM_S32BE,
- AV_CODEC_ID_PCM_U32LE,
- AV_CODEC_ID_PCM_U32BE,
- AV_CODEC_ID_PCM_S24LE,
- AV_CODEC_ID_PCM_S24BE,
- AV_CODEC_ID_PCM_U24LE,
- AV_CODEC_ID_PCM_U24BE,
- AV_CODEC_ID_PCM_S24DAUD,
- AV_CODEC_ID_PCM_ZORK,
- AV_CODEC_ID_PCM_S16LE_PLANAR,
- AV_CODEC_ID_PCM_DVD,
- AV_CODEC_ID_PCM_F32BE,
- AV_CODEC_ID_PCM_F32LE,
- AV_CODEC_ID_PCM_F64BE,
- AV_CODEC_ID_PCM_F64LE,
- AV_CODEC_ID_PCM_BLURAY,
- AV_CODEC_ID_PCM_LXF,
- AV_CODEC_ID_S302M,
- AV_CODEC_ID_PCM_S8_PLANAR,
- AV_CODEC_ID_PCM_S24LE_PLANAR_DEPRECATED,
- AV_CODEC_ID_PCM_S32LE_PLANAR_DEPRECATED,
- AV_CODEC_ID_PCM_S16BE_PLANAR_DEPRECATED,
- AV_CODEC_ID_PCM_S24LE_PLANAR = MKBETAG(24,'P','S','P'),
- AV_CODEC_ID_PCM_S32LE_PLANAR = MKBETAG(32,'P','S','P'),
- AV_CODEC_ID_PCM_S16BE_PLANAR = MKBETAG('P','S','P',16),
-
- /* various ADPCM codecs */
- AV_CODEC_ID_ADPCM_IMA_QT = 0x11000,
- AV_CODEC_ID_ADPCM_IMA_WAV,
- AV_CODEC_ID_ADPCM_IMA_DK3,
- AV_CODEC_ID_ADPCM_IMA_DK4,
- AV_CODEC_ID_ADPCM_IMA_WS,
- AV_CODEC_ID_ADPCM_IMA_SMJPEG,
- AV_CODEC_ID_ADPCM_MS,
- AV_CODEC_ID_ADPCM_4XM,
- AV_CODEC_ID_ADPCM_XA,
- AV_CODEC_ID_ADPCM_ADX,
- AV_CODEC_ID_ADPCM_EA,
- AV_CODEC_ID_ADPCM_G726,
- AV_CODEC_ID_ADPCM_CT,
- AV_CODEC_ID_ADPCM_SWF,
- AV_CODEC_ID_ADPCM_YAMAHA,
- AV_CODEC_ID_ADPCM_SBPRO_4,
- AV_CODEC_ID_ADPCM_SBPRO_3,
- AV_CODEC_ID_ADPCM_SBPRO_2,
- AV_CODEC_ID_ADPCM_THP,
- AV_CODEC_ID_ADPCM_IMA_AMV,
- AV_CODEC_ID_ADPCM_EA_R1,
- AV_CODEC_ID_ADPCM_EA_R3,
- AV_CODEC_ID_ADPCM_EA_R2,
- AV_CODEC_ID_ADPCM_IMA_EA_SEAD,
- AV_CODEC_ID_ADPCM_IMA_EA_EACS,
- AV_CODEC_ID_ADPCM_EA_XAS,
- AV_CODEC_ID_ADPCM_EA_MAXIS_XA,
- AV_CODEC_ID_ADPCM_IMA_ISS,
- AV_CODEC_ID_ADPCM_G722,
- AV_CODEC_ID_ADPCM_IMA_APC,
- AV_CODEC_ID_ADPCM_VIMA_DEPRECATED,
- AV_CODEC_ID_ADPCM_VIMA = MKBETAG('V','I','M','A'),
-#if FF_API_VIMA_DECODER
- AV_CODEC_ID_VIMA = MKBETAG('V','I','M','A'),
-#endif
- AV_CODEC_ID_ADPCM_AFC = MKBETAG('A','F','C',' '),
- AV_CODEC_ID_ADPCM_IMA_OKI = MKBETAG('O','K','I',' '),
- AV_CODEC_ID_ADPCM_DTK = MKBETAG('D','T','K',' '),
- AV_CODEC_ID_ADPCM_IMA_RAD = MKBETAG('R','A','D',' '),
- AV_CODEC_ID_ADPCM_G726LE = MKBETAG('6','2','7','G'),
- AV_CODEC_ID_ADPCM_THP_LE = MKBETAG('T','H','P','L'),
-
- /* AMR */
- AV_CODEC_ID_AMR_NB = 0x12000,
- AV_CODEC_ID_AMR_WB,
-
- /* RealAudio codecs*/
- AV_CODEC_ID_RA_144 = 0x13000,
- AV_CODEC_ID_RA_288,
-
- /* various DPCM codecs */
- AV_CODEC_ID_ROQ_DPCM = 0x14000,
- AV_CODEC_ID_INTERPLAY_DPCM,
- AV_CODEC_ID_XAN_DPCM,
- AV_CODEC_ID_SOL_DPCM,
-
- /* audio codecs */
- AV_CODEC_ID_MP2 = 0x15000,
- AV_CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3
- AV_CODEC_ID_AAC,
- AV_CODEC_ID_AC3,
- AV_CODEC_ID_DTS,
- AV_CODEC_ID_VORBIS,
- AV_CODEC_ID_DVAUDIO,
- AV_CODEC_ID_WMAV1,
- AV_CODEC_ID_WMAV2,
- AV_CODEC_ID_MACE3,
- AV_CODEC_ID_MACE6,
- AV_CODEC_ID_VMDAUDIO,
- AV_CODEC_ID_FLAC,
- AV_CODEC_ID_MP3ADU,
- AV_CODEC_ID_MP3ON4,
- AV_CODEC_ID_SHORTEN,
- AV_CODEC_ID_ALAC,
- AV_CODEC_ID_WESTWOOD_SND1,
- AV_CODEC_ID_GSM, ///< as in Berlin toast format
- AV_CODEC_ID_QDM2,
- AV_CODEC_ID_COOK,
- AV_CODEC_ID_TRUESPEECH,
- AV_CODEC_ID_TTA,
- AV_CODEC_ID_SMACKAUDIO,
- AV_CODEC_ID_QCELP,
- AV_CODEC_ID_WAVPACK,
- AV_CODEC_ID_DSICINAUDIO,
- AV_CODEC_ID_IMC,
- AV_CODEC_ID_MUSEPACK7,
- AV_CODEC_ID_MLP,
- AV_CODEC_ID_GSM_MS, /* as found in WAV */
- AV_CODEC_ID_ATRAC3,
-#if FF_API_VOXWARE
- AV_CODEC_ID_VOXWARE,
-#endif
- AV_CODEC_ID_APE,
- AV_CODEC_ID_NELLYMOSER,
- AV_CODEC_ID_MUSEPACK8,
- AV_CODEC_ID_SPEEX,
- AV_CODEC_ID_WMAVOICE,
- AV_CODEC_ID_WMAPRO,
- AV_CODEC_ID_WMALOSSLESS,
- AV_CODEC_ID_ATRAC3P,
- AV_CODEC_ID_EAC3,
- AV_CODEC_ID_SIPR,
- AV_CODEC_ID_MP1,
- AV_CODEC_ID_TWINVQ,
- AV_CODEC_ID_TRUEHD,
- AV_CODEC_ID_MP4ALS,
- AV_CODEC_ID_ATRAC1,
- AV_CODEC_ID_BINKAUDIO_RDFT,
- AV_CODEC_ID_BINKAUDIO_DCT,
- AV_CODEC_ID_AAC_LATM,
- AV_CODEC_ID_QDMC,
- AV_CODEC_ID_CELT,
- AV_CODEC_ID_G723_1,
- AV_CODEC_ID_G729,
- AV_CODEC_ID_8SVX_EXP,
- AV_CODEC_ID_8SVX_FIB,
- AV_CODEC_ID_BMV_AUDIO,
- AV_CODEC_ID_RALF,
- AV_CODEC_ID_IAC,
- AV_CODEC_ID_ILBC,
- AV_CODEC_ID_OPUS_DEPRECATED,
- AV_CODEC_ID_COMFORT_NOISE,
- AV_CODEC_ID_TAK_DEPRECATED,
- AV_CODEC_ID_METASOUND,
- AV_CODEC_ID_PAF_AUDIO_DEPRECATED,
- AV_CODEC_ID_ON2AVC,
- AV_CODEC_ID_DSS_SP,
- AV_CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'),
- AV_CODEC_ID_SONIC = MKBETAG('S','O','N','C'),
- AV_CODEC_ID_SONIC_LS = MKBETAG('S','O','N','L'),
- AV_CODEC_ID_PAF_AUDIO = MKBETAG('P','A','F','A'),
- AV_CODEC_ID_OPUS = MKBETAG('O','P','U','S'),
- AV_CODEC_ID_TAK = MKBETAG('t','B','a','K'),
- AV_CODEC_ID_EVRC = MKBETAG('s','e','v','c'),
- AV_CODEC_ID_SMV = MKBETAG('s','s','m','v'),
- AV_CODEC_ID_DSD_LSBF = MKBETAG('D','S','D','L'),
- AV_CODEC_ID_DSD_MSBF = MKBETAG('D','S','D','M'),
- AV_CODEC_ID_DSD_LSBF_PLANAR = MKBETAG('D','S','D','1'),
- AV_CODEC_ID_DSD_MSBF_PLANAR = MKBETAG('D','S','D','8'),
- AV_CODEC_ID_4GV = MKBETAG('s','4','g','v'),
-
- /* subtitle codecs */
- AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs.
- AV_CODEC_ID_DVD_SUBTITLE = 0x17000,
- AV_CODEC_ID_DVB_SUBTITLE,
- AV_CODEC_ID_TEXT, ///< raw UTF-8 text
- AV_CODEC_ID_XSUB,
- AV_CODEC_ID_SSA,
- AV_CODEC_ID_MOV_TEXT,
- AV_CODEC_ID_HDMV_PGS_SUBTITLE,
- AV_CODEC_ID_DVB_TELETEXT,
- AV_CODEC_ID_SRT,
- AV_CODEC_ID_MICRODVD = MKBETAG('m','D','V','D'),
- AV_CODEC_ID_EIA_608 = MKBETAG('c','6','0','8'),
- AV_CODEC_ID_JACOSUB = MKBETAG('J','S','U','B'),
- AV_CODEC_ID_SAMI = MKBETAG('S','A','M','I'),
- AV_CODEC_ID_REALTEXT = MKBETAG('R','T','X','T'),
- AV_CODEC_ID_STL = MKBETAG('S','p','T','L'),
- AV_CODEC_ID_SUBVIEWER1 = MKBETAG('S','b','V','1'),
- AV_CODEC_ID_SUBVIEWER = MKBETAG('S','u','b','V'),
- AV_CODEC_ID_SUBRIP = MKBETAG('S','R','i','p'),
- AV_CODEC_ID_WEBVTT = MKBETAG('W','V','T','T'),
- AV_CODEC_ID_MPL2 = MKBETAG('M','P','L','2'),
- AV_CODEC_ID_VPLAYER = MKBETAG('V','P','l','r'),
- AV_CODEC_ID_PJS = MKBETAG('P','h','J','S'),
- AV_CODEC_ID_ASS = MKBETAG('A','S','S',' '), ///< ASS as defined in Matroska
- AV_CODEC_ID_HDMV_TEXT_SUBTITLE = MKBETAG('B','D','T','X'),
-
- /* other specific kind of codecs (generally used for attachments) */
- AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs.
- AV_CODEC_ID_TTF = 0x18000,
- AV_CODEC_ID_BINTEXT = MKBETAG('B','T','X','T'),
- AV_CODEC_ID_XBIN = MKBETAG('X','B','I','N'),
- AV_CODEC_ID_IDF = MKBETAG( 0 ,'I','D','F'),
- AV_CODEC_ID_OTF = MKBETAG( 0 ,'O','T','F'),
- AV_CODEC_ID_SMPTE_KLV = MKBETAG('K','L','V','A'),
- AV_CODEC_ID_DVD_NAV = MKBETAG('D','N','A','V'),
- AV_CODEC_ID_TIMED_ID3 = MKBETAG('T','I','D','3'),
- AV_CODEC_ID_BIN_DATA = MKBETAG('D','A','T','A'),
-
-
- AV_CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it
-
- AV_CODEC_ID_MPEG2TS = 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS
- * stream (only used by libavformat) */
- AV_CODEC_ID_MPEG4SYSTEMS = 0x20001, /**< _FAKE_ codec to indicate a MPEG-4 Systems
- * stream (only used by libavformat) */
- AV_CODEC_ID_FFMETADATA = 0x21000, ///< Dummy codec for streams containing only metadata information.
-
-#if FF_API_CODEC_ID
-#include "old_codec_ids.h"
-#endif
-};
-
-/**
- * This struct describes the properties of a single codec described by an
- * AVCodecID.
- * @see avcodec_descriptor_get()
- */
-typedef struct AVCodecDescriptor {
- enum AVCodecID id;
- enum AVMediaType type;
- /**
- * Name of the codec described by this descriptor. It is non-empty and
- * unique for each codec descriptor. It should contain alphanumeric
- * characters and '_' only.
- */
- const char *name;
- /**
- * A more descriptive name for this codec. May be NULL.
- */
- const char *long_name;
- /**
- * Codec properties, a combination of AV_CODEC_PROP_* flags.
- */
- int props;
-
- /**
- * MIME type(s) associated with the codec.
- * May be NULL; if not, a NULL-terminated array of MIME types.
- * The first item is always non-NULL and is the preferred MIME type.
- */
- const char *const *mime_types;
-} AVCodecDescriptor;
-
-/**
- * Codec uses only intra compression.
- * Video codecs only.
- */
-#define AV_CODEC_PROP_INTRA_ONLY (1 << 0)
-/**
- * Codec supports lossy compression. Audio and video codecs only.
- * @note a codec may support both lossy and lossless
- * compression modes
- */
-#define AV_CODEC_PROP_LOSSY (1 << 1)
-/**
- * Codec supports lossless compression. Audio and video codecs only.
- */
-#define AV_CODEC_PROP_LOSSLESS (1 << 2)
-/**
- * Codec supports frame reordering. That is, the coded order (the order in which
- * the encoded packets are output by the encoders / stored / input to the
- * decoders) may be different from the presentation order of the corresponding
- * frames.
- *
- * For codecs that do not have this property set, PTS and DTS should always be
- * equal.
- */
-#define AV_CODEC_PROP_REORDER (1 << 3)
-/**
- * Subtitle codec is bitmap based
- * Decoded AVSubtitle data can be read from the AVSubtitleRect->pict field.
- */
-#define AV_CODEC_PROP_BITMAP_SUB (1 << 16)
-/**
- * Subtitle codec is text based.
- * Decoded AVSubtitle data can be read from the AVSubtitleRect->ass field.
- */
-#define AV_CODEC_PROP_TEXT_SUB (1 << 17)
-
-/**
- * @ingroup lavc_decoding
- * Required number of additionally allocated bytes at the end of the input bitstream for decoding.
- * This is mainly needed because some optimized bitstream readers read
- * 32 or 64 bit at once and could read over the end.<br>
- * Note: If the first 23 bits of the additional bytes are not 0, then damaged
- * MPEG bitstreams could cause overread and segfault.
- */
-#define AV_INPUT_BUFFER_PADDING_SIZE 32
-
-/**
- * @ingroup lavc_encoding
- * minimum encoding buffer size
- * Used to avoid some checks during header writing.
- */
-#define AV_INPUT_BUFFER_MIN_SIZE 16384
-
-#if FF_API_WITHOUT_PREFIX
-/**
- * @deprecated use AV_INPUT_BUFFER_PADDING_SIZE instead
- */
-#define FF_INPUT_BUFFER_PADDING_SIZE 32
-
-/**
- * @deprecated use AV_INPUT_BUFFER_MIN_SIZE instead
- */
-#define FF_MIN_BUFFER_SIZE 16384
-#endif /* FF_API_WITHOUT_PREFIX */
-
-/**
- * @ingroup lavc_encoding
- * motion estimation type.
- * @deprecated use codec private option instead
- */
-#if FF_API_MOTION_EST
-enum Motion_Est_ID {
- ME_ZERO = 1, ///< no search, that is use 0,0 vector whenever one is needed
- ME_FULL,
- ME_LOG,
- ME_PHODS,
- ME_EPZS, ///< enhanced predictive zonal search
- ME_X1, ///< reserved for experiments
- ME_HEX, ///< hexagon based search
- ME_UMH, ///< uneven multi-hexagon search
- ME_TESA, ///< transformed exhaustive search algorithm
- ME_ITER=50, ///< iterative search
-};
-#endif
-
-/**
- * @ingroup lavc_decoding
- */
-enum AVDiscard{
- /* We leave some space between them for extensions (drop some
- * keyframes for intra-only or drop just some bidir frames). */
- AVDISCARD_NONE =-16, ///< discard nothing
- AVDISCARD_DEFAULT = 0, ///< discard useless packets like 0 size packets in avi
- AVDISCARD_NONREF = 8, ///< discard all non reference
- AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames
- AVDISCARD_NONINTRA= 24, ///< discard all non intra frames
- AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes
- AVDISCARD_ALL = 48, ///< discard all
-};
-
-enum AVAudioServiceType {
- AV_AUDIO_SERVICE_TYPE_MAIN = 0,
- AV_AUDIO_SERVICE_TYPE_EFFECTS = 1,
- AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED = 2,
- AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED = 3,
- AV_AUDIO_SERVICE_TYPE_DIALOGUE = 4,
- AV_AUDIO_SERVICE_TYPE_COMMENTARY = 5,
- AV_AUDIO_SERVICE_TYPE_EMERGENCY = 6,
- AV_AUDIO_SERVICE_TYPE_VOICE_OVER = 7,
- AV_AUDIO_SERVICE_TYPE_KARAOKE = 8,
- AV_AUDIO_SERVICE_TYPE_NB , ///< Not part of ABI
-};
-
-/**
- * @ingroup lavc_encoding
- */
-typedef struct RcOverride{
- int start_frame;
- int end_frame;
- int qscale; // If this is 0 then quality_factor will be used instead.
- float quality_factor;
-} RcOverride;
-
-#if FF_API_MAX_BFRAMES
-/**
- * @deprecated there is no libavcodec-wide limit on the number of B-frames
- */
-#define FF_MAX_B_FRAMES 16
-#endif
-
-/* encoding support
- These flags can be passed in AVCodecContext.flags before initialization.
- Note: Not everything is supported yet.
-*/
-
-/**
- * Allow decoders to produce frames with data planes that are not aligned
- * to CPU requirements (e.g. due to cropping).
- */
-#define AV_CODEC_FLAG_UNALIGNED (1 << 0)
-/**
- * Use fixed qscale.
- */
-#define AV_CODEC_FLAG_QSCALE (1 << 1)
-/**
- * 4 MV per MB allowed / advanced prediction for H.263.
- */
-#define AV_CODEC_FLAG_4MV (1 << 2)
-/**
- * Output even those frames that might be corrupted.
- */
-#define AV_CODEC_FLAG_OUTPUT_CORRUPT (1 << 3)
-/**
- * Use qpel MC.
- */
-#define AV_CODEC_FLAG_QPEL (1 << 4)
-/**
- * Use internal 2pass ratecontrol in first pass mode.
- */
-#define AV_CODEC_FLAG_PASS1 (1 << 9)
-/**
- * Use internal 2pass ratecontrol in second pass mode.
- */
-#define AV_CODEC_FLAG_PASS2 (1 << 10)
-/**
- * loop filter.
- */
-#define AV_CODEC_FLAG_LOOP_FILTER (1 << 11)
-/**
- * Only decode/encode grayscale.
- */
-#define AV_CODEC_FLAG_GRAY (1 << 13)
-/**
- * error[?] variables will be set during encoding.
- */
-#define AV_CODEC_FLAG_PSNR (1 << 15)
-/**
- * Input bitstream might be truncated at a random location
- * instead of only at frame boundaries.
- */
-#define AV_CODEC_FLAG_TRUNCATED (1 << 16)
-/**
- * Use interlaced DCT.
- */
-#define AV_CODEC_FLAG_INTERLACED_DCT (1 << 18)
-/**
- * Force low delay.
- */
-#define AV_CODEC_FLAG_LOW_DELAY (1 << 19)
-/**
- * Place global headers in extradata instead of every keyframe.
- */
-#define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22)
-/**
- * Use only bitexact stuff (except (I)DCT).
- */
-#define AV_CODEC_FLAG_BITEXACT (1 << 23)
-/* Fx : Flag for h263+ extra options */
-/**
- * H.263 advanced intra coding / MPEG-4 AC prediction
- */
-#define AV_CODEC_FLAG_AC_PRED (1 << 24)
-/**
- * interlaced motion estimation
- */
-#define AV_CODEC_FLAG_INTERLACED_ME (1 << 29)
-/**
- * Allow non spec compliant speedup tricks.
- */
-#define AV_CODEC_FLAG_CLOSED_GOP (1U << 31)
-
-#define AV_CODEC_FLAG2_FAST (1 << 0)
-/**
- * Skip bitstream encoding.
- */
-#define AV_CODEC_FLAG2_NO_OUTPUT (1 << 2)
-/**
- * Place global headers at every keyframe instead of in extradata.
- */
-#define AV_CODEC_FLAG2_LOCAL_HEADER (1 << 3)
-
-/**
- * timecode is in drop frame format. DEPRECATED!!!!
- */
-#define AV_CODEC_FLAG2_DROP_FRAME_TIMECODE (1 << 13)
-
-/**
- * Input bitstream might be truncated at a packet boundaries
- * instead of only at frame boundaries.
- */
-#define AV_CODEC_FLAG2_CHUNKS (1 << 15)
-/**
- * Discard cropping information from SPS.
- */
-#define AV_CODEC_FLAG2_IGNORE_CROP (1 << 16)
-
-/**
- * Show all frames before the first keyframe
- */
-#define AV_CODEC_FLAG2_SHOW_ALL (1 << 22)
-/**
- * Export motion vectors through frame side data
- */
-#define AV_CODEC_FLAG2_EXPORT_MVS (1 << 28)
-/**
- * Do not skip samples and export skip information as frame side data
- */
-#define AV_CODEC_FLAG2_SKIP_MANUAL (1 << 29)
-
-/* Unsupported options :
- * Syntax Arithmetic coding (SAC)
- * Reference Picture Selection
- * Independent Segment Decoding */
-/* /Fx */
-/* codec capabilities */
-
-/**
- * Decoder can use draw_horiz_band callback.
- */
-#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.
- */
-#define AV_CODEC_CAP_DR1 (1 << 1)
-#define AV_CODEC_CAP_TRUNCATED (1 << 3)
-/**
- * Encoder or decoder requires flushing with NULL input at the end in order to
- * give the complete and correct output.
- *
- * NOTE: If this flag is not set, the codec is guaranteed to never be fed with
- * with NULL data. The user can still send NULL data to the public encode
- * or decode function, but libavcodec will not pass it along to the codec
- * unless this flag is set.
- *
- * Decoders:
- * The decoder has a non-zero delay and needs to be fed with avpkt->data=NULL,
- * avpkt->size=0 at the end to get the delayed data until the decoder no longer
- * returns frames.
- *
- * Encoders:
- * The encoder needs to be fed with NULL data at the end of encoding until the
- * encoder no longer returns data.
- *
- * NOTE: For encoders implementing the AVCodec.encode2() function, setting this
- * flag also means that the encoder must set the pts and duration for
- * each output packet. If this flag is not set, the pts and duration will
- * be determined by libavcodec from the input frame.
- */
-#define AV_CODEC_CAP_DELAY (1 << 5)
-/**
- * Codec can be fed a final frame with a smaller size.
- * This can be used to prevent truncation of the last audio samples.
- */
-#define AV_CODEC_CAP_SMALL_LAST_FRAME (1 << 6)
-
-#if FF_API_CAP_VDPAU
-/**
- * Codec can export data for HW decoding (VDPAU).
- */
-#define AV_CODEC_CAP_HWACCEL_VDPAU (1 << 7)
-#endif
-
-/**
- * Codec can output multiple frames per AVPacket
- * Normally demuxers return one frame at a time, demuxers which do not do
- * are connected to a parser to split what they return into proper frames.
- * This flag is reserved to the very rare category of codecs which have a
- * bitstream that cannot be split into frames without timeconsuming
- * operations like full decoding. Demuxers carring such bitstreams thus
- * may return multiple frames in a packet. This has many disadvantages like
- * prohibiting stream copy in many cases thus it should only be considered
- * as a last resort.
- */
-#define AV_CODEC_CAP_SUBFRAMES (1 << 8)
-/**
- * Codec is experimental and is thus avoided in favor of non experimental
- * encoders
- */
-#define AV_CODEC_CAP_EXPERIMENTAL (1 << 9)
-/**
- * Codec should fill in channel configuration and samplerate instead of container
- */
-#define AV_CODEC_CAP_CHANNEL_CONF (1 << 10)
-/**
- * Codec supports frame-level multithreading.
- */
-#define AV_CODEC_CAP_FRAME_THREADS (1 << 12)
-/**
- * Codec supports slice-based (or partition-based) multithreading.
- */
-#define AV_CODEC_CAP_SLICE_THREADS (1 << 13)
-/**
- * Codec supports changed parameters at any point.
- */
-#define AV_CODEC_CAP_PARAM_CHANGE (1 << 14)
-/**
- * Codec supports avctx->thread_count == 0 (auto).
- */
-#define AV_CODEC_CAP_AUTO_THREADS (1 << 15)
-/**
- * Audio encoder supports receiving a different number of samples in each call.
- */
-#define AV_CODEC_CAP_VARIABLE_FRAME_SIZE (1 << 16)
-/**
- * Codec is intra only.
- */
-#define AV_CODEC_CAP_INTRA_ONLY 0x40000000
-/**
- * Codec is lossless.
- */
-#define AV_CODEC_CAP_LOSSLESS 0x80000000
-
-
-#if FF_API_WITHOUT_PREFIX
-/**
- * Allow decoders to produce frames with data planes that are not aligned
- * to CPU requirements (e.g. due to cropping).
- */
-#define CODEC_FLAG_UNALIGNED AV_CODEC_FLAG_UNALIGNED
-#define CODEC_FLAG_QSCALE AV_CODEC_FLAG_QSCALE
-#define CODEC_FLAG_4MV AV_CODEC_FLAG_4MV
-#define CODEC_FLAG_OUTPUT_CORRUPT AV_CODEC_FLAG_OUTPUT_CORRUPT
-#define CODEC_FLAG_QPEL AV_CODEC_FLAG_QPEL
-#if FF_API_GMC
-/**
- * @deprecated use the "gmc" private option of the libxvid encoder
- */
-#define CODEC_FLAG_GMC 0x0020 ///< Use GMC.
-#endif
-#if FF_API_MV0
-/**
- * @deprecated use the flag "mv0" in the "mpv_flags" private option of the
- * mpegvideo encoders
- */
-#define CODEC_FLAG_MV0 0x0040
-#endif
-#if FF_API_INPUT_PRESERVED
-/**
- * @deprecated passing reference-counted frames to the encoders replaces this
- * flag
- */
-#define CODEC_FLAG_INPUT_PRESERVED 0x0100
-#endif
-#define CODEC_FLAG_PASS1 AV_CODEC_FLAG_PASS1
-#define CODEC_FLAG_PASS2 AV_CODEC_FLAG_PASS2
-#define CODEC_FLAG_GRAY AV_CODEC_FLAG_GRAY
-#if FF_API_EMU_EDGE
-/**
- * @deprecated edges are not used/required anymore. I.e. this flag is now always
- * set.
- */
-#define CODEC_FLAG_EMU_EDGE 0x4000
-#endif
-#define CODEC_FLAG_PSNR AV_CODEC_FLAG_PSNR
-#define CODEC_FLAG_TRUNCATED AV_CODEC_FLAG_TRUNCATED
-
-#if FF_API_NORMALIZE_AQP
-/**
- * @deprecated use the flag "naq" in the "mpv_flags" private option of the
- * mpegvideo encoders
- */
-#define CODEC_FLAG_NORMALIZE_AQP 0x00020000
-#endif
-#define CODEC_FLAG_INTERLACED_DCT AV_CODEC_FLAG_INTERLACED_DCT
-#define CODEC_FLAG_LOW_DELAY AV_CODEC_FLAG_LOW_DELAY
-#define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER
-#define CODEC_FLAG_BITEXACT AV_CODEC_FLAG_BITEXACT
-#define CODEC_FLAG_AC_PRED AV_CODEC_FLAG_AC_PRED
-#define CODEC_FLAG_LOOP_FILTER AV_CODEC_FLAG_LOOP_FILTER
-#define CODEC_FLAG_INTERLACED_ME AV_CODEC_FLAG_INTERLACED_ME
-#define CODEC_FLAG_CLOSED_GOP AV_CODEC_FLAG_CLOSED_GOP
-#define CODEC_FLAG2_FAST AV_CODEC_FLAG2_FAST
-#define CODEC_FLAG2_NO_OUTPUT AV_CODEC_FLAG2_NO_OUTPUT
-#define CODEC_FLAG2_LOCAL_HEADER AV_CODEC_FLAG2_LOCAL_HEADER
-#define CODEC_FLAG2_DROP_FRAME_TIMECODE AV_CODEC_FLAG2_DROP_FRAME_TIMECODE
-#define CODEC_FLAG2_IGNORE_CROP AV_CODEC_FLAG2_IGNORE_CROP
-
-#define CODEC_FLAG2_CHUNKS AV_CODEC_FLAG2_CHUNKS
-#define CODEC_FLAG2_SHOW_ALL AV_CODEC_FLAG2_SHOW_ALL
-#define CODEC_FLAG2_EXPORT_MVS AV_CODEC_FLAG2_EXPORT_MVS
-#define CODEC_FLAG2_SKIP_MANUAL AV_CODEC_FLAG2_SKIP_MANUAL
-
-/* Unsupported options :
- * Syntax Arithmetic coding (SAC)
- * Reference Picture Selection
- * Independent Segment Decoding */
-/* /Fx */
-/* codec capabilities */
-
-#define CODEC_CAP_DRAW_HORIZ_BAND AV_CODEC_CAP_DRAW_HORIZ_BAND ///< Decoder can use draw_horiz_band callback.
-/**
- * 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.
- */
-#define CODEC_CAP_DR1 AV_CODEC_CAP_DR1
-#define CODEC_CAP_TRUNCATED AV_CODEC_CAP_TRUNCATED
-#if FF_API_XVMC
-/* Codec can export data for HW decoding. This flag indicates that
- * the codec would call get_format() with list that might contain HW accelerated
- * pixel formats (XvMC, VDPAU, VAAPI, etc). The application can pick any of them
- * including raw image format.
- * The application can use the passed context to determine bitstream version,
- * chroma format, resolution etc.
- */
-#define CODEC_CAP_HWACCEL 0x0010
-#endif /* FF_API_XVMC */
-/**
- * Encoder or decoder requires flushing with NULL input at the end in order to
- * give the complete and correct output.
- *
- * NOTE: If this flag is not set, the codec is guaranteed to never be fed with
- * with NULL data. The user can still send NULL data to the public encode
- * or decode function, but libavcodec will not pass it along to the codec
- * unless this flag is set.
- *
- * Decoders:
- * The decoder has a non-zero delay and needs to be fed with avpkt->data=NULL,
- * avpkt->size=0 at the end to get the delayed data until the decoder no longer
- * returns frames.
- *
- * Encoders:
- * The encoder needs to be fed with NULL data at the end of encoding until the
- * encoder no longer returns data.
- *
- * NOTE: For encoders implementing the AVCodec.encode2() function, setting this
- * flag also means that the encoder must set the pts and duration for
- * each output packet. If this flag is not set, the pts and duration will
- * be determined by libavcodec from the input frame.
- */
-#define CODEC_CAP_DELAY AV_CODEC_CAP_DELAY
-/**
- * Codec can be fed a final frame with a smaller size.
- * This can be used to prevent truncation of the last audio samples.
- */
-#define CODEC_CAP_SMALL_LAST_FRAME AV_CODEC_CAP_SMALL_LAST_FRAME
-#if FF_API_CAP_VDPAU
-/**
- * Codec can export data for HW decoding (VDPAU).
- */
-#define CODEC_CAP_HWACCEL_VDPAU AV_CODEC_CAP_HWACCEL_VDPAU
-#endif
-/**
- * Codec can output multiple frames per AVPacket
- * Normally demuxers return one frame at a time, demuxers which do not do
- * are connected to a parser to split what they return into proper frames.
- * This flag is reserved to the very rare category of codecs which have a
- * bitstream that cannot be split into frames without timeconsuming
- * operations like full decoding. Demuxers carring such bitstreams thus
- * may return multiple frames in a packet. This has many disadvantages like
- * prohibiting stream copy in many cases thus it should only be considered
- * as a last resort.
- */
-#define CODEC_CAP_SUBFRAMES AV_CODEC_CAP_SUBFRAMES
-/**
- * Codec is experimental and is thus avoided in favor of non experimental
- * encoders
- */
-#define CODEC_CAP_EXPERIMENTAL AV_CODEC_CAP_EXPERIMENTAL
-/**
- * Codec should fill in channel configuration and samplerate instead of container
- */
-#define CODEC_CAP_CHANNEL_CONF AV_CODEC_CAP_CHANNEL_CONF
-#if FF_API_NEG_LINESIZES
-/**
- * @deprecated no codecs use this capability
- */
-#define CODEC_CAP_NEG_LINESIZES 0x0800
-#endif
-/**
- * Codec supports frame-level multithreading.
- */
-#define CODEC_CAP_FRAME_THREADS AV_CODEC_CAP_FRAME_THREADS
-/**
- * Codec supports slice-based (or partition-based) multithreading.
- */
-#define CODEC_CAP_SLICE_THREADS AV_CODEC_CAP_SLICE_THREADS
-/**
- * Codec supports changed parameters at any point.
- */
-#define CODEC_CAP_PARAM_CHANGE AV_CODEC_CAP_PARAM_CHANGE
-/**
- * Codec supports avctx->thread_count == 0 (auto).
- */
-#define CODEC_CAP_AUTO_THREADS AV_CODEC_CAP_AUTO_THREADS
-/**
- * Audio encoder supports receiving a different number of samples in each call.
- */
-#define CODEC_CAP_VARIABLE_FRAME_SIZE AV_CODEC_CAP_VARIABLE_FRAME_SIZE
-/**
- * Codec is intra only.
- */
-#define CODEC_CAP_INTRA_ONLY AV_CODEC_CAP_INTRA_ONLY
-/**
- * Codec is lossless.
- */
-#define CODEC_CAP_LOSSLESS AV_CODEC_CAP_LOSSLESS
-
-/**
- * HWAccel is experimental and is thus avoided in favor of non experimental
- * codecs
- */
-#define HWACCEL_CODEC_CAP_EXPERIMENTAL 0x0200
-#endif /* FF_API_WITHOUT_PREFIX */
-
-#if FF_API_MB_TYPE
-//The following defines may change, don't expect compatibility if you use them.
-#define MB_TYPE_INTRA4x4 0x0001
-#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific
-#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific
-#define MB_TYPE_16x16 0x0008
-#define MB_TYPE_16x8 0x0010
-#define MB_TYPE_8x16 0x0020
-#define MB_TYPE_8x8 0x0040
-#define MB_TYPE_INTERLACED 0x0080
-#define MB_TYPE_DIRECT2 0x0100 //FIXME
-#define MB_TYPE_ACPRED 0x0200
-#define MB_TYPE_GMC 0x0400
-#define MB_TYPE_SKIP 0x0800
-#define MB_TYPE_P0L0 0x1000
-#define MB_TYPE_P1L0 0x2000
-#define MB_TYPE_P0L1 0x4000
-#define MB_TYPE_P1L1 0x8000
-#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0)
-#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1)
-#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1)
-#define MB_TYPE_QUANT 0x00010000
-#define MB_TYPE_CBP 0x00020000
-//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...)
-#endif
-
-/**
- * Pan Scan area.
- * This specifies the area which should be displayed.
- * Note there may be multiple such areas for one frame.
- */
-typedef struct AVPanScan{
- /**
- * id
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- int id;
-
- /**
- * width and height in 1/16 pel
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- int width;
- int height;
-
- /**
- * position of the top left corner in 1/16 pel for up to 3 fields/frames
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- int16_t position[3][2];
-}AVPanScan;
-
-#if FF_API_QSCALE_TYPE
-#define FF_QSCALE_TYPE_MPEG1 0
-#define FF_QSCALE_TYPE_MPEG2 1
-#define FF_QSCALE_TYPE_H264 2
-#define FF_QSCALE_TYPE_VP56 3
-#endif
-
-#if FF_API_GET_BUFFER
-#define FF_BUFFER_TYPE_INTERNAL 1
-#define FF_BUFFER_TYPE_USER 2 ///< direct rendering buffers (image is (de)allocated by user)
-#define FF_BUFFER_TYPE_SHARED 4 ///< Buffer from somewhere else; don't deallocate image (data/base), all other tables are not shared.
-#define FF_BUFFER_TYPE_COPY 8 ///< Just a (modified) copy of some other buffer, don't deallocate anything.
-
-#define FF_BUFFER_HINTS_VALID 0x01 // Buffer hints value is meaningful (if 0 ignore).
-#define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer.
-#define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content.
-#define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update).
-#endif
-
-/**
- * The decoder will keep a reference to the frame and may reuse it later.
- */
-#define AV_GET_BUFFER_FLAG_REF (1 << 0)
-
-/**
- * @defgroup lavc_packet AVPacket
- *
- * Types and functions for working with AVPacket.
- * @{
- */
-enum AVPacketSideDataType {
- AV_PKT_DATA_PALETTE,
- AV_PKT_DATA_NEW_EXTRADATA,
-
- /**
- * An AV_PKT_DATA_PARAM_CHANGE side data packet is laid out as follows:
- * @code
- * u32le param_flags
- * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT)
- * s32le channel_count
- * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT)
- * u64le channel_layout
- * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE)
- * s32le sample_rate
- * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS)
- * s32le width
- * s32le height
- * @endcode
- */
- AV_PKT_DATA_PARAM_CHANGE,
-
- /**
- * An AV_PKT_DATA_H263_MB_INFO side data packet contains a number of
- * structures with info about macroblocks relevant to splitting the
- * packet into smaller packets on macroblock edges (e.g. as for RFC 2190).
- * That is, it does not necessarily contain info about all macroblocks,
- * as long as the distance between macroblocks in the info is smaller
- * than the target payload size.
- * Each MB info structure is 12 bytes, and is laid out as follows:
- * @code
- * u32le bit offset from the start of the packet
- * u8 current quantizer at the start of the macroblock
- * u8 GOB number
- * u16le macroblock address within the GOB
- * u8 horizontal MV predictor
- * u8 vertical MV predictor
- * u8 horizontal MV predictor for block number 3
- * u8 vertical MV predictor for block number 3
- * @endcode
- */
- AV_PKT_DATA_H263_MB_INFO,
-
- /**
- * This side data should be associated with an audio stream and contains
- * ReplayGain information in form of the AVReplayGain struct.
- */
- AV_PKT_DATA_REPLAYGAIN,
-
- /**
- * This side data contains a 3x3 transformation matrix describing an affine
- * transformation that needs to be applied to the decoded video frames for
- * correct presentation.
- *
- * See libavutil/display.h for a detailed description of the data.
- */
- AV_PKT_DATA_DISPLAYMATRIX,
-
- /**
- * This side data should be associated with a video stream and contains
- * Stereoscopic 3D information in form of the AVStereo3D struct.
- */
- AV_PKT_DATA_STEREO3D,
-
- /**
- * This side data should be associated with an audio stream and corresponds
- * to enum AVAudioServiceType.
- */
- AV_PKT_DATA_AUDIO_SERVICE_TYPE,
-
- /**
- * This side data contains quality related information from the encoder.
- * @code
- * u32le quality factor of the compressed frame. Allowed range is between 1 (good) and FF_LAMBDA_MAX (bad).
- * u8 picture type
- * u8 error count
- * u16 reserved
- * u64le[error count] sum of squared differences between encoder in and output
- * @endcode
- */
- AV_PKT_DATA_QUALITY_STATS,
-
- /**
- * Recommmends skipping the specified number of samples
- * @code
- * u32le number of samples to skip from start of this packet
- * u32le number of samples to skip from end of this packet
- * u8 reason for start skip
- * u8 reason for end skip (0=padding silence, 1=convergence)
- * @endcode
- */
- AV_PKT_DATA_SKIP_SAMPLES=70,
-
- /**
- * An AV_PKT_DATA_JP_DUALMONO side data packet indicates that
- * the packet may contain "dual mono" audio specific to Japanese DTV
- * and if it is true, recommends only the selected channel to be used.
- * @code
- * u8 selected channels (0=mail/left, 1=sub/right, 2=both)
- * @endcode
- */
- AV_PKT_DATA_JP_DUALMONO,
-
- /**
- * A list of zero terminated key/value strings. There is no end marker for
- * the list, so it is required to rely on the side data size to stop.
- */
- AV_PKT_DATA_STRINGS_METADATA,
-
- /**
- * Subtitle event position
- * @code
- * u32le x1
- * u32le y1
- * u32le x2
- * u32le y2
- * @endcode
- */
- AV_PKT_DATA_SUBTITLE_POSITION,
-
- /**
- * Data found in BlockAdditional element of matroska container. There is
- * no end marker for the data, so it is required to rely on the side data
- * size to recognize the end. 8 byte id (as found in BlockAddId) followed
- * by data.
- */
- AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
-
- /**
- * The optional first identifier line of a WebVTT cue.
- */
- AV_PKT_DATA_WEBVTT_IDENTIFIER,
-
- /**
- * The optional settings (rendering instructions) that immediately
- * follow the timestamp specifier of a WebVTT cue.
- */
- AV_PKT_DATA_WEBVTT_SETTINGS,
-
- /**
- * A list of zero terminated key/value strings. There is no end marker for
- * the list, so it is required to rely on the side data size to stop. This
- * side data includes updated metadata which appeared in the stream.
- */
- AV_PKT_DATA_METADATA_UPDATE,
-};
-
-#define AV_PKT_DATA_QUALITY_FACTOR AV_PKT_DATA_QUALITY_STATS //DEPRECATED
-
-typedef struct AVPacketSideData {
- uint8_t *data;
- int size;
- enum AVPacketSideDataType type;
-} AVPacketSideData;
-
-/**
- * This structure stores compressed data. It is typically exported by demuxers
- * and then passed as input to decoders, or received as output from encoders and
- * then passed to muxers.
- *
- * For video, it should typically contain one compressed frame. For audio it may
- * contain several compressed frames.
- *
- * 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 or destruct (deprecated)
- * fields. If either is set, the packet data is dynamically allocated and is
- * valid indefinitely until av_free_packet() is called (which in turn calls
- * av_buffer_unref()/the destruct callback to free the data). If neither is set,
- * the packet data is typically backed by some static buffer somewhere and is
- * only valid for a limited time (e.g. until the next read call when demuxing).
- *
- * The side data is always allocated with av_malloc() and is freed in
- * av_free_packet().
- */
-typedef struct AVPacket {
- /**
- * A reference to the reference-counted buffer where the packet data is
- * stored.
- * May be NULL, then the packet data is not reference-counted.
- */
- AVBufferRef *buf;
- /**
- * Presentation timestamp in AVStream->time_base units; the time at which
- * the decompressed packet will be presented to the user.
- * Can be AV_NOPTS_VALUE if it is not stored in the file.
- * pts MUST be larger or equal to dts as presentation cannot happen before
- * decompression, unless one wants to view hex dumps. Some formats misuse
- * the terms dts and pts/cts to mean something different. Such timestamps
- * must be converted to true pts/dts before they are stored in AVPacket.
- */
- int64_t pts;
- /**
- * Decompression timestamp in AVStream->time_base units; the time at which
- * the packet is decompressed.
- * Can be AV_NOPTS_VALUE if it is not stored in the file.
- */
- int64_t dts;
- uint8_t *data;
- int size;
- int stream_index;
- /**
- * A combination of AV_PKT_FLAG values
- */
- int flags;
- /**
- * Additional packet data that can be provided by the container.
- * Packet can contain several types of side information.
- */
- AVPacketSideData *side_data;
- int side_data_elems;
-
- /**
- * Duration of this packet in AVStream->time_base units, 0 if unknown.
- * Equals next_pts - this_pts in presentation order.
- */
- int duration;
-#if FF_API_DESTRUCT_PACKET
- attribute_deprecated
- void (*destruct)(struct AVPacket *);
- attribute_deprecated
- void *priv;
-#endif
- int64_t pos; ///< byte position in stream, -1 if unknown
-
- /**
- * Time difference in AVStream->time_base units from the pts of this
- * packet to the point at which the output from the decoder has converged
- * independent from the availability of previous frames. That is, the
- * frames are virtually identical no matter if decoding started from
- * the very first frame or from this keyframe.
- * Is AV_NOPTS_VALUE if unknown.
- * This field is not the display duration of the current packet.
- * This field has no meaning if the packet does not have AV_PKT_FLAG_KEY
- * set.
- *
- * The purpose of this field is to allow seeking in streams that have no
- * keyframes in the conventional sense. It corresponds to the
- * recovery point SEI in H.264 and match_time_delta in NUT. It is also
- * essential for some types of subtitle streams to ensure that all
- * subtitles are correctly displayed after seeking.
- */
- int64_t convergence_duration;
-} AVPacket;
-#define AV_PKT_FLAG_KEY 0x0001 ///< The packet contains a keyframe
-#define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted
-
-enum AVSideDataParamChangeFlags {
- AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001,
- AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 0x0002,
- AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE = 0x0004,
- AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS = 0x0008,
-};
-/**
- * @}
- */
-
-struct AVCodecInternal;
-
-enum AVFieldOrder {
- AV_FIELD_UNKNOWN,
- AV_FIELD_PROGRESSIVE,
- AV_FIELD_TT, //< Top coded_first, top displayed first
- AV_FIELD_BB, //< Bottom coded first, bottom displayed first
- AV_FIELD_TB, //< Top coded first, bottom displayed first
- AV_FIELD_BT, //< Bottom coded first, top displayed first
-};
-
-/**
- * main external API structure.
- * New fields can be added to the end with minor version bumps.
- * Removal, reordering and changes to existing fields require a major
- * version bump.
- * Please use AVOptions (av_opt* / av_set/get*()) to access these fields from user
- * applications.
- * sizeof(AVCodecContext) must not be used outside libav*.
- */
-typedef struct AVCodecContext {
- /**
- * information on struct for av_log
- * - set by avcodec_alloc_context3
- */
- const AVClass *av_class;
- int log_level_offset;
-
- enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
- const struct AVCodec *codec;
-#if FF_API_CODEC_NAME
- /**
- * @deprecated this field is not used for anything in libavcodec
- */
- attribute_deprecated
- char codec_name[32];
-#endif
- enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */
-
- /**
- * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
- * This is used to work around some encoder bugs.
- * A demuxer should set this to what is stored in the field used to identify the codec.
- * If there are multiple such fields in a container then the demuxer should choose the one
- * which maximizes the information about the used codec.
- * If the codec tag field in a container is larger than 32 bits then the demuxer should
- * remap the longer ID to 32 bits with a table or other structure. Alternatively a new
- * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated
- * first.
- * - encoding: Set by user, if not then the default based on codec_id will be used.
- * - decoding: Set by user, will be converted to uppercase by libavcodec during init.
- */
- unsigned int codec_tag;
-
-#if FF_API_STREAM_CODEC_TAG
- /**
- * @deprecated this field is unused
- */
- attribute_deprecated
- unsigned int stream_codec_tag;
-#endif
-
- void *priv_data;
-
- /**
- * Private context used for internal data.
- *
- * Unlike priv_data, this is not codec-specific. It is used in general
- * libavcodec functions.
- */
- struct AVCodecInternal *internal;
-
- /**
- * Private data of the user, can be used to carry app specific stuff.
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- void *opaque;
-
- /**
- * the average bitrate
- * - encoding: Set by user; unused for constant quantizer encoding.
- * - decoding: Set by user, may be overwritten by libavcodec
- * if this info is available in the stream
- */
- int bit_rate;
-
- /**
- * number of bits the bitstream is allowed to diverge from the reference.
- * the reference can be CBR (for CBR pass1) or VBR (for pass2)
- * - encoding: Set by user; unused for constant quantizer encoding.
- * - decoding: unused
- */
- int bit_rate_tolerance;
-
- /**
- * Global quality for codecs which cannot change it per frame.
- * This should be proportional to MPEG-1/2/4 qscale.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int global_quality;
-
- /**
- * - encoding: Set by user.
- * - decoding: unused
- */
- int compression_level;
-#define FF_COMPRESSION_DEFAULT -1
-
- /**
- * AV_CODEC_FLAG_*.
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- int flags;
-
- /**
- * AV_CODEC_FLAG2_*
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- int flags2;
-
- /**
- * some codecs need / can use extradata like Huffman tables.
- * mjpeg: Huffman tables
- * rv10: additional flags
- * mpeg4: global headers (they can be in the bitstream or here)
- * The allocated memory should be AV_INPUT_BUFFER_PADDING_SIZE bytes larger
- * than extradata_size to avoid problems if it is read with the bitstream reader.
- * The bytewise contents of extradata must not depend on the architecture or CPU endianness.
- * - encoding: Set/allocated/freed by libavcodec.
- * - decoding: Set/allocated/freed by user.
- */
- uint8_t *extradata;
- int extradata_size;
-
- /**
- * This is the fundamental unit of time (in seconds) in terms
- * of which frame timestamps are represented. For fixed-fps content,
- * timebase should be 1/framerate and timestamp increments should be
- * identically 1.
- * This often, but not always is the inverse of the frame rate or field rate
- * for video.
- * - encoding: MUST be set by user.
- * - decoding: the use of this field for decoding is deprecated.
- * Use framerate instead.
- */
- AVRational time_base;
-
- /**
- * For some codecs, the time base is closer to the field rate than the frame rate.
- * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration
- * if no telecine is used ...
- *
- * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2.
- */
- int ticks_per_frame;
-
- /**
- * Codec delay.
- *
- * Encoding: Number of frames delay there will be from the encoder input to
- * the decoder output. (we assume the decoder matches the spec)
- * Decoding: Number of frames delay in addition to what a standard decoder
- * as specified in the spec would produce.
- *
- * Video:
- * Number of frames the decoded output will be delayed relative to the
- * encoded input.
- *
- * Audio:
- * For encoding, this field is unused (see initial_padding).
- *
- * For decoding, this is the number of samples the decoder needs to
- * output before the decoder's output is valid. When seeking, you should
- * start decoding this many samples prior to your desired seek point.
- *
- * - encoding: Set by libavcodec.
- * - decoding: Set by libavcodec.
- */
- int delay;
-
-
- /* video only */
- /**
- * picture width / height.
- *
- * @note Those fields may not match the values of the last
- * AVFrame outputted by avcodec_decode_video2 due frame
- * reordering.
- *
- * - encoding: MUST be set by user.
- * - decoding: May be set by the user before opening the decoder if known e.g.
- * from the container. Some decoders will require the dimensions
- * to be set by the caller. During decoding, the decoder may
- * overwrite those values as required while parsing the data.
- */
- int width, height;
-
- /**
- * Bitstream width / height, may be different from width/height e.g. when
- * the decoded frame is cropped before being output or lowres is enabled.
- *
- * @note Those field may not match the value of the last
- * AVFrame outputted by avcodec_decode_video2 due frame
- * reordering.
- *
- * - encoding: unused
- * - decoding: May be set by the user before opening the decoder if known
- * e.g. from the container. During decoding, the decoder may
- * overwrite those values as required while parsing the data.
- */
- int coded_width, coded_height;
-
-#if FF_API_ASPECT_EXTENDED
-#define FF_ASPECT_EXTENDED 15
-#endif
-
- /**
- * the number of pictures in a group of pictures, or 0 for intra_only
- * - encoding: Set by user.
- * - decoding: unused
- */
- int gop_size;
-
- /**
- * Pixel format, see AV_PIX_FMT_xxx.
- * May be set by the demuxer if known from headers.
- * May be overridden by the decoder if it knows better.
- *
- * @note This field may not match the value of the last
- * AVFrame outputted by avcodec_decode_video2 due frame
- * reordering.
- *
- * - encoding: Set by user.
- * - decoding: Set by user if known, overridden by libavcodec while
- * parsing the data.
- */
- enum AVPixelFormat pix_fmt;
-
-#if FF_API_MOTION_EST
- /**
- * This option does nothing
- * @deprecated use codec private options instead
- */
- attribute_deprecated int me_method;
-#endif
-
- /**
- * If non NULL, 'draw_horiz_band' is called by the libavcodec
- * decoder to draw a horizontal band. It improves cache usage. Not
- * all codecs can do that. You must check the codec capabilities
- * beforehand.
- * When multithreading is used, it may be called from multiple threads
- * at the same time; threads might draw different parts of the same AVFrame,
- * or multiple AVFrames, and there is no guarantee that slices will be drawn
- * in order.
- * The function is also used by hardware acceleration APIs.
- * It is called at least once during frame decoding to pass
- * the data needed for hardware render.
- * In that mode instead of pixel data, AVFrame points to
- * a structure specific to the acceleration API. The application
- * reads the structure and can change some fields to indicate progress
- * or mark state.
- * - encoding: unused
- * - decoding: Set by user.
- * @param height the height of the slice
- * @param y the y position of the slice
- * @param type 1->top field, 2->bottom field, 3->frame
- * @param offset offset into the AVFrame.data from which the slice should be read
- */
- void (*draw_horiz_band)(struct AVCodecContext *s,
- const AVFrame *src, int offset[AV_NUM_DATA_POINTERS],
- int y, int type, int height);
-
- /**
- * callback to negotiate the pixelFormat
- * @param fmt is the list of formats which are supported by the codec,
- * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality.
- * The first is always the native one.
- * @note The callback may be called again immediately if initialization for
- * the selected (hardware-accelerated) pixel format failed.
- * @warning Behavior is undefined if the callback returns a value not
- * in the fmt list of formats.
- * @return the chosen format
- * - encoding: unused
- * - decoding: Set by user, if not set the native format will be chosen.
- */
- enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt);
-
- /**
- * maximum number of B-frames between non-B-frames
- * Note: The output will be delayed by max_b_frames+1 relative to the input.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int max_b_frames;
-
- /**
- * qscale factor between IP and B-frames
- * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset).
- * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
- * - encoding: Set by user.
- * - decoding: unused
- */
- float b_quant_factor;
-
-#if FF_API_RC_STRATEGY
- /** @deprecated use codec private option instead */
- attribute_deprecated int rc_strategy;
-#define FF_RC_STRATEGY_XVID 1
-#endif
-
- int b_frame_strategy;
-
- /**
- * qscale offset between IP and B-frames
- * - encoding: Set by user.
- * - decoding: unused
- */
- float b_quant_offset;
-
- /**
- * Size of the frame reordering buffer in the decoder.
- * For MPEG-2 it is 1 IPB or 0 low delay IP.
- * - encoding: Set by libavcodec.
- * - decoding: Set by libavcodec.
- */
- int has_b_frames;
-
- /**
- * 0-> h263 quant 1-> mpeg quant
- * - encoding: Set by user.
- * - decoding: unused
- */
- int mpeg_quant;
-
- /**
- * qscale factor between P and I-frames
- * If > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset).
- * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
- * - encoding: Set by user.
- * - decoding: unused
- */
- float i_quant_factor;
-
- /**
- * qscale offset between P and I-frames
- * - encoding: Set by user.
- * - decoding: unused
- */
- float i_quant_offset;
-
- /**
- * luminance masking (0-> disabled)
- * - encoding: Set by user.
- * - decoding: unused
- */
- float lumi_masking;
-
- /**
- * temporary complexity masking (0-> disabled)
- * - encoding: Set by user.
- * - decoding: unused
- */
- float temporal_cplx_masking;
-
- /**
- * spatial complexity masking (0-> disabled)
- * - encoding: Set by user.
- * - decoding: unused
- */
- float spatial_cplx_masking;
-
- /**
- * p block masking (0-> disabled)
- * - encoding: Set by user.
- * - decoding: unused
- */
- float p_masking;
-
- /**
- * darkness masking (0-> disabled)
- * - encoding: Set by user.
- * - decoding: unused
- */
- float dark_masking;
-
- /**
- * slice count
- * - encoding: Set by libavcodec.
- * - decoding: Set by user (or 0).
- */
- int slice_count;
- /**
- * prediction method (needed for huffyuv)
- * - encoding: Set by user.
- * - decoding: unused
- */
- int prediction_method;
-#define FF_PRED_LEFT 0
-#define FF_PRED_PLANE 1
-#define FF_PRED_MEDIAN 2
-
- /**
- * slice offsets in the frame in bytes
- * - encoding: Set/allocated by libavcodec.
- * - decoding: Set/allocated by user (or NULL).
- */
- int *slice_offset;
-
- /**
- * sample aspect ratio (0 if unknown)
- * That is the width of a pixel divided by the height of the pixel.
- * Numerator and denominator must be relatively prime and smaller than 256 for some video standards.
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- AVRational sample_aspect_ratio;
-
- /**
- * motion estimation comparison function
- * - encoding: Set by user.
- * - decoding: unused
- */
- int me_cmp;
- /**
- * subpixel motion estimation comparison function
- * - encoding: Set by user.
- * - decoding: unused
- */
- int me_sub_cmp;
- /**
- * macroblock comparison function (not supported yet)
- * - encoding: Set by user.
- * - decoding: unused
- */
- int mb_cmp;
- /**
- * interlaced DCT comparison function
- * - encoding: Set by user.
- * - decoding: unused
- */
- int ildct_cmp;
-#define FF_CMP_SAD 0
-#define FF_CMP_SSE 1
-#define FF_CMP_SATD 2
-#define FF_CMP_DCT 3
-#define FF_CMP_PSNR 4
-#define FF_CMP_BIT 5
-#define FF_CMP_RD 6
-#define FF_CMP_ZERO 7
-#define FF_CMP_VSAD 8
-#define FF_CMP_VSSE 9
-#define FF_CMP_NSSE 10
-#define FF_CMP_W53 11
-#define FF_CMP_W97 12
-#define FF_CMP_DCTMAX 13
-#define FF_CMP_DCT264 14
-#define FF_CMP_CHROMA 256
-
- /**
- * ME diamond size & shape
- * - encoding: Set by user.
- * - decoding: unused
- */
- int dia_size;
-
- /**
- * amount of previous MV predictors (2a+1 x 2a+1 square)
- * - encoding: Set by user.
- * - decoding: unused
- */
- int last_predictor_count;
-
- /**
- * prepass for motion estimation
- * - encoding: Set by user.
- * - decoding: unused
- */
- int pre_me;
-
- /**
- * motion estimation prepass comparison function
- * - encoding: Set by user.
- * - decoding: unused
- */
- int me_pre_cmp;
-
- /**
- * ME prepass diamond size & shape
- * - encoding: Set by user.
- * - decoding: unused
- */
- int pre_dia_size;
-
- /**
- * subpel ME quality
- * - encoding: Set by user.
- * - decoding: unused
- */
- int me_subpel_quality;
-
-#if FF_API_AFD
- /**
- * DTG active format information (additional aspect ratio
- * information only used in DVB MPEG-2 transport streams)
- * 0 if not set.
- *
- * - encoding: unused
- * - decoding: Set by decoder.
- * @deprecated Deprecated in favor of AVSideData
- */
- attribute_deprecated int dtg_active_format;
-#define FF_DTG_AFD_SAME 8
-#define FF_DTG_AFD_4_3 9
-#define FF_DTG_AFD_16_9 10
-#define FF_DTG_AFD_14_9 11
-#define FF_DTG_AFD_4_3_SP_14_9 13
-#define FF_DTG_AFD_16_9_SP_14_9 14
-#define FF_DTG_AFD_SP_4_3 15
-#endif /* FF_API_AFD */
-
- /**
- * maximum motion estimation search range in subpel units
- * If 0 then no limit.
- *
- * - encoding: Set by user.
- * - decoding: unused
- */
- int me_range;
-
-#if FF_API_QUANT_BIAS
- /**
- * @deprecated use encoder private option instead
- */
- attribute_deprecated int intra_quant_bias;
-#define FF_DEFAULT_QUANT_BIAS 999999
-
- /**
- * @deprecated use encoder private option instead
- */
- attribute_deprecated int inter_quant_bias;
-#endif
-
- /**
- * slice flags
- * - encoding: unused
- * - decoding: Set by user.
- */
- int slice_flags;
-#define SLICE_FLAG_CODED_ORDER 0x0001 ///< draw_horiz_band() is called in coded order instead of display
-#define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG2 field pics)
-#define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1)
-
-#if FF_API_XVMC
- /**
- * XVideo Motion Acceleration
- * - encoding: forbidden
- * - decoding: set by decoder
- * @deprecated XvMC doesn't need it anymore.
- */
- attribute_deprecated int xvmc_acceleration;
-#endif /* FF_API_XVMC */
-
- /**
- * macroblock decision mode
- * - encoding: Set by user.
- * - decoding: unused
- */
- int mb_decision;
-#define FF_MB_DECISION_SIMPLE 0 ///< uses mb_cmp
-#define FF_MB_DECISION_BITS 1 ///< chooses the one which needs the fewest bits
-#define FF_MB_DECISION_RD 2 ///< rate distortion
-
- /**
- * custom intra quantization matrix
- * - encoding: Set by user, can be NULL.
- * - decoding: Set by libavcodec.
- */
- uint16_t *intra_matrix;
-
- /**
- * custom inter quantization matrix
- * - encoding: Set by user, can be NULL.
- * - decoding: Set by libavcodec.
- */
- uint16_t *inter_matrix;
-
- /**
- * scene change detection threshold
- * 0 is default, larger means fewer detected scene changes.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int scenechange_threshold;
-
- /**
- * noise reduction strength
- * - encoding: Set by user.
- * - decoding: unused
- */
- int noise_reduction;
-
-#if FF_API_MPV_OPT
- /**
- * @deprecated this field is unused
- */
- attribute_deprecated
- int me_threshold;
-
- /**
- * @deprecated this field is unused
- */
- attribute_deprecated
- int mb_threshold;
-#endif
-
- /**
- * precision of the intra DC coefficient - 8
- * - encoding: Set by user.
- * - decoding: Set by libavcodec
- */
- int intra_dc_precision;
-
- /**
- * Number of macroblock rows at the top which are skipped.
- * - encoding: unused
- * - decoding: Set by user.
- */
- int skip_top;
-
- /**
- * Number of macroblock rows at the bottom which are skipped.
- * - encoding: unused
- * - decoding: Set by user.
- */
- int skip_bottom;
-
-#if FF_API_MPV_OPT
- /**
- * @deprecated use encoder private options instead
- */
- attribute_deprecated
- float border_masking;
-#endif
-
- /**
- * minimum MB lagrange multipler
- * - encoding: Set by user.
- * - decoding: unused
- */
- int mb_lmin;
-
- /**
- * maximum MB lagrange multipler
- * - encoding: Set by user.
- * - decoding: unused
- */
- int mb_lmax;
-
- /**
- *
- * - encoding: Set by user.
- * - decoding: unused
- */
- int me_penalty_compensation;
-
- /**
- *
- * - encoding: Set by user.
- * - decoding: unused
- */
- int bidir_refine;
-
- /**
- *
- * - encoding: Set by user.
- * - decoding: unused
- */
- int brd_scale;
-
- /**
- * minimum GOP size
- * - encoding: Set by user.
- * - decoding: unused
- */
- int keyint_min;
-
- /**
- * number of reference frames
- * - encoding: Set by user.
- * - decoding: Set by lavc.
- */
- int refs;
-
- /**
- * chroma qp offset from luma
- * - encoding: Set by user.
- * - decoding: unused
- */
- int chromaoffset;
-
-#if FF_API_UNUSED_MEMBERS
- /**
- * Multiplied by qscale for each frame and added to scene_change_score.
- * - encoding: Set by user.
- * - decoding: unused
- */
- attribute_deprecated int scenechange_factor;
-#endif
-
- /**
- *
- * Note: Value depends upon the compare function used for fullpel ME.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int mv0_threshold;
-
- /**
- * Adjust sensitivity of b_frame_strategy 1.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int b_sensitivity;
-
- /**
- * Chromaticity coordinates of the source primaries.
- * - encoding: Set by user
- * - decoding: Set by libavcodec
- */
- enum AVColorPrimaries color_primaries;
-
- /**
- * Color Transfer Characteristic.
- * - encoding: Set by user
- * - decoding: Set by libavcodec
- */
- enum AVColorTransferCharacteristic color_trc;
-
- /**
- * YUV colorspace type.
- * - encoding: Set by user
- * - decoding: Set by libavcodec
- */
- enum AVColorSpace colorspace;
-
- /**
- * MPEG vs JPEG YUV range.
- * - encoding: Set by user
- * - decoding: Set by libavcodec
- */
- enum AVColorRange color_range;
-
- /**
- * This defines the location of chroma samples.
- * - encoding: Set by user
- * - decoding: Set by libavcodec
- */
- enum AVChromaLocation chroma_sample_location;
-
- /**
- * Number of slices.
- * Indicates number of picture subdivisions. Used for parallelized
- * decoding.
- * - encoding: Set by user
- * - decoding: unused
- */
- int slices;
-
- /** Field order
- * - encoding: set by libavcodec
- * - decoding: Set by user.
- */
- enum AVFieldOrder field_order;
-
- /* audio only */
- int sample_rate; ///< samples per second
- int channels; ///< number of audio channels
-
- /**
- * audio sample format
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- enum AVSampleFormat sample_fmt; ///< sample format
-
- /* The following data should not be initialized. */
- /**
- * Number of samples per channel in an audio frame.
- *
- * - encoding: set by libavcodec in avcodec_open2(). Each submitted frame
- * except the last must contain exactly frame_size samples per channel.
- * May be 0 when the codec has AV_CODEC_CAP_VARIABLE_FRAME_SIZE set, then the
- * frame size is not restricted.
- * - decoding: may be set by some decoders to indicate constant frame size
- */
- int frame_size;
-
- /**
- * Frame counter, set by libavcodec.
- *
- * - decoding: total number of frames returned from the decoder so far.
- * - encoding: total number of frames passed to the encoder so far.
- *
- * @note the counter is not incremented if encoding/decoding resulted in
- * an error.
- */
- int frame_number;
-
- /**
- * number of bytes per packet if constant and known or 0
- * Used by some WAV based audio codecs.
- */
- int block_align;
-
- /**
- * Audio cutoff bandwidth (0 means "automatic")
- * - encoding: Set by user.
- * - decoding: unused
- */
- int cutoff;
-
-#if FF_API_REQUEST_CHANNELS
- /**
- * Decoder should decode to this many channels if it can (0 for default)
- * - encoding: unused
- * - decoding: Set by user.
- * @deprecated Deprecated in favor of request_channel_layout.
- */
- attribute_deprecated int request_channels;
-#endif
-
- /**
- * Audio channel layout.
- * - encoding: set by user.
- * - decoding: set by user, may be overwritten by libavcodec.
- */
- uint64_t channel_layout;
-
- /**
- * Request decoder to use this channel layout if it can (0 for default)
- * - encoding: unused
- * - decoding: Set by user.
- */
- uint64_t request_channel_layout;
-
- /**
- * Type of service that the audio stream conveys.
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- enum AVAudioServiceType audio_service_type;
-
- /**
- * desired sample format
- * - encoding: Not used.
- * - decoding: Set by user.
- * Decoder will decode to this format if it can.
- */
- enum AVSampleFormat request_sample_fmt;
-
-#if FF_API_GET_BUFFER
- /**
- * Called at the beginning of each frame to get a buffer for it.
- *
- * The function will set AVFrame.data[], AVFrame.linesize[].
- * AVFrame.extended_data[] must also be set, but it should be the same as
- * AVFrame.data[] except for planar audio with more channels than can fit
- * in AVFrame.data[]. In that case, AVFrame.data[] shall still contain as
- * many data pointers as it can hold.
- *
- * if CODEC_CAP_DR1 is not set then get_buffer() must call
- * avcodec_default_get_buffer() instead of providing buffers allocated by
- * some other means.
- *
- * AVFrame.data[] should be 32- or 16-byte-aligned unless the CPU doesn't
- * need it. avcodec_default_get_buffer() aligns the output buffer properly,
- * but if get_buffer() is overridden then alignment considerations should
- * be taken into account.
- *
- * @see avcodec_default_get_buffer()
- *
- * Video:
- *
- * If pic.reference is set then the frame will be read later by libavcodec.
- * avcodec_align_dimensions2() should be used to find the required width and
- * height, as they normally need to be rounded up to the next multiple of 16.
- *
- * If frame multithreading is used and thread_safe_callbacks is set,
- * it may be called from a different thread, but not from more than one at
- * once. Does not need to be reentrant.
- *
- * @see release_buffer(), reget_buffer()
- * @see avcodec_align_dimensions2()
- *
- * Audio:
- *
- * Decoders request a buffer of a particular size by setting
- * AVFrame.nb_samples prior to calling get_buffer(). The decoder may,
- * however, utilize only part of the buffer by setting AVFrame.nb_samples
- * to a smaller value in the output frame.
- *
- * Decoders cannot use the buffer after returning from
- * avcodec_decode_audio4(), so they will not call release_buffer(), as it
- * is assumed to be released immediately upon return. In some rare cases,
- * a decoder may need to call get_buffer() more than once in a single
- * call to avcodec_decode_audio4(). In that case, when get_buffer() is
- * called again after it has already been called once, the previously
- * acquired buffer is assumed to be released at that time and may not be
- * reused by the decoder.
- *
- * As a convenience, av_samples_get_buffer_size() and
- * av_samples_fill_arrays() in libavutil may be used by custom get_buffer()
- * functions to find the required data size and to fill data pointers and
- * linesize. In AVFrame.linesize, only linesize[0] may be set for audio
- * since all planes must be the same size.
- *
- * @see av_samples_get_buffer_size(), av_samples_fill_arrays()
- *
- * - encoding: unused
- * - decoding: Set by libavcodec, user can override.
- *
- * @deprecated use get_buffer2()
- */
- attribute_deprecated
- int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic);
-
- /**
- * Called to release buffers which were allocated with get_buffer.
- * A released buffer can be reused in get_buffer().
- * pic.data[*] must be set to NULL.
- * May be called from a different thread if frame multithreading is used,
- * but not by more than one thread at once, so does not need to be reentrant.
- * - encoding: unused
- * - decoding: Set by libavcodec, user can override.
- *
- * @deprecated custom freeing callbacks should be set from get_buffer2()
- */
- attribute_deprecated
- void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic);
-
- /**
- * Called at the beginning of a frame to get cr buffer for it.
- * Buffer type (size, hints) must be the same. libavcodec won't check it.
- * libavcodec will pass previous buffer in pic, function should return
- * same buffer or new buffer with old frame "painted" into it.
- * If pic.data[0] == NULL must behave like get_buffer().
- * if CODEC_CAP_DR1 is not set then reget_buffer() must call
- * avcodec_default_reget_buffer() instead of providing buffers allocated by
- * some other means.
- * - encoding: unused
- * - decoding: Set by libavcodec, user can override.
- */
- attribute_deprecated
- int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic);
-#endif
-
- /**
- * This callback is called at the beginning of each frame to get data
- * buffer(s) for it. There may be one contiguous buffer for all the data or
- * there may be a buffer per each data plane or anything in between. What
- * this means is, you may set however many entries in buf[] you feel necessary.
- * Each buffer must be reference-counted using the AVBuffer API (see description
- * of buf[] below).
- *
- * The following fields will be set in the frame before this callback is
- * called:
- * - format
- * - width, height (video only)
- * - sample_rate, channel_layout, nb_samples (audio only)
- * Their values may differ from the corresponding values in
- * AVCodecContext. This callback must use the frame values, not the codec
- * context values, to calculate the required buffer size.
- *
- * This callback must fill the following fields in the frame:
- * - data[]
- * - linesize[]
- * - extended_data:
- * * if the data is planar audio with more than 8 channels, then this
- * callback must allocate and fill extended_data to contain all pointers
- * to all data planes. data[] must hold as many pointers as it can.
- * extended_data must be allocated with av_malloc() and will be freed in
- * av_frame_unref().
- * * otherwise exended_data must point to data
- * - buf[] must contain one or more pointers to AVBufferRef structures. Each of
- * the frame's data and extended_data pointers must be contained in these. That
- * is, one AVBufferRef for each allocated chunk of memory, not necessarily one
- * AVBufferRef per data[] entry. See: av_buffer_create(), av_buffer_alloc(),
- * and av_buffer_ref().
- * - extended_buf and nb_extended_buf must be allocated with av_malloc() by
- * this callback and filled with the extra buffers if there are more
- * buffers than buf[] can hold. extended_buf will be freed in
- * av_frame_unref().
- *
- * If AV_CODEC_CAP_DR1 is not set then get_buffer2() must call
- * avcodec_default_get_buffer2() instead of providing buffers allocated by
- * some other means.
- *
- * Each data plane must be aligned to the maximum required by the target
- * CPU.
- *
- * @see avcodec_default_get_buffer2()
- *
- * Video:
- *
- * If AV_GET_BUFFER_FLAG_REF is set in flags then the frame may be reused
- * (read and/or written to if it is writable) later by libavcodec.
- *
- * avcodec_align_dimensions2() should be used to find the required width and
- * height, as they normally need to be rounded up to the next multiple of 16.
- *
- * 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.
- *
- * @see avcodec_align_dimensions2()
- *
- * Audio:
- *
- * Decoders request a buffer of a particular size by setting
- * AVFrame.nb_samples prior to calling get_buffer2(). The decoder may,
- * however, utilize only part of the buffer by setting AVFrame.nb_samples
- * to a smaller value in the output frame.
- *
- * As a convenience, av_samples_get_buffer_size() and
- * av_samples_fill_arrays() in libavutil may be used by custom get_buffer2()
- * functions to find the required data size and to fill data pointers and
- * linesize. In AVFrame.linesize, only linesize[0] may be set for audio
- * since all planes must be the same size.
- *
- * @see av_samples_get_buffer_size(), av_samples_fill_arrays()
- *
- * - encoding: unused
- * - decoding: Set by libavcodec, user can override.
- */
- int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags);
-
- /**
- * If non-zero, the decoded audio and video frames returned from
- * avcodec_decode_video2() and avcodec_decode_audio4() are reference-counted
- * and are valid indefinitely. The caller must free them with
- * av_frame_unref() when they are not needed anymore.
- * Otherwise, the decoded frames must not be freed by the caller and are
- * only valid until the next decode call.
- *
- * - encoding: unused
- * - decoding: set by the caller before avcodec_open2().
- */
- int refcounted_frames;
-
- /* - encoding parameters */
- float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0)
- float qblur; ///< amount of qscale smoothing over time (0.0-1.0)
-
- /**
- * minimum quantizer
- * - encoding: Set by user.
- * - decoding: unused
- */
- int qmin;
-
- /**
- * maximum quantizer
- * - encoding: Set by user.
- * - decoding: unused
- */
- int qmax;
-
- /**
- * maximum quantizer difference between frames
- * - encoding: Set by user.
- * - decoding: unused
- */
- int max_qdiff;
-
-#if FF_API_MPV_OPT
- /**
- * @deprecated use encoder private options instead
- */
- attribute_deprecated
- float rc_qsquish;
-
- attribute_deprecated
- float rc_qmod_amp;
- attribute_deprecated
- int rc_qmod_freq;
-#endif
-
- /**
- * decoder bitstream buffer size
- * - encoding: Set by user.
- * - decoding: unused
- */
- int rc_buffer_size;
-
- /**
- * ratecontrol override, see RcOverride
- * - encoding: Allocated/set/freed by user.
- * - decoding: unused
- */
- int rc_override_count;
- RcOverride *rc_override;
-
-#if FF_API_MPV_OPT
- /**
- * @deprecated use encoder private options instead
- */
- attribute_deprecated
- const char *rc_eq;
-#endif
-
- /**
- * maximum bitrate
- * - encoding: Set by user.
- * - decoding: Set by user, may be overwritten by libavcodec.
- */
- int rc_max_rate;
-
- /**
- * minimum bitrate
- * - encoding: Set by user.
- * - decoding: unused
- */
- int rc_min_rate;
-
-#if FF_API_MPV_OPT
- /**
- * @deprecated use encoder private options instead
- */
- attribute_deprecated
- float rc_buffer_aggressivity;
-
- attribute_deprecated
- float rc_initial_cplx;
-#endif
-
- /**
- * Ratecontrol attempt to use, at maximum, <value> of what can be used without an underflow.
- * - encoding: Set by user.
- * - decoding: unused.
- */
- float rc_max_available_vbv_use;
-
- /**
- * Ratecontrol attempt to use, at least, <value> times the amount needed to prevent a vbv overflow.
- * - encoding: Set by user.
- * - decoding: unused.
- */
- float rc_min_vbv_overflow_use;
-
- /**
- * Number of bits which should be loaded into the rc buffer before decoding starts.
- * - encoding: Set by user.
- * - decoding: unused
- */
- int rc_initial_buffer_occupancy;
-
-#define FF_CODER_TYPE_VLC 0
-#define FF_CODER_TYPE_AC 1
-#define FF_CODER_TYPE_RAW 2
-#define FF_CODER_TYPE_RLE 3
-#if FF_API_UNUSED_MEMBERS
-#define FF_CODER_TYPE_DEFLATE 4
-#endif /* FF_API_UNUSED_MEMBERS */
- /**
- * coder type
- * - encoding: Set by user.
- * - decoding: unused
- */
- int coder_type;
-
- /**
- * context model
- * - encoding: Set by user.
- * - decoding: unused
- */
- int context_model;
-
-#if FF_API_MPV_OPT
- /**
- * @deprecated use encoder private options instead
- */
- attribute_deprecated
- int lmin;
-
- /**
- * @deprecated use encoder private options instead
- */
- attribute_deprecated
- int lmax;
-#endif
-
- /**
- * frame skip threshold
- * - encoding: Set by user.
- * - decoding: unused
- */
- int frame_skip_threshold;
-
- /**
- * frame skip factor
- * - encoding: Set by user.
- * - decoding: unused
- */
- int frame_skip_factor;
-
- /**
- * frame skip exponent
- * - encoding: Set by user.
- * - decoding: unused
- */
- int frame_skip_exp;
-
- /**
- * frame skip comparison function
- * - encoding: Set by user.
- * - decoding: unused
- */
- int frame_skip_cmp;
-
- /**
- * trellis RD quantization
- * - encoding: Set by user.
- * - decoding: unused
- */
- int trellis;
-
- /**
- * - encoding: Set by user.
- * - decoding: unused
- */
- int min_prediction_order;
-
- /**
- * - encoding: Set by user.
- * - decoding: unused
- */
- int max_prediction_order;
-
- /**
- * GOP timecode frame start number
- * - encoding: Set by user, in non drop frame format
- * - decoding: Set by libavcodec (timecode in the 25 bits format, -1 if unset)
- */
- int64_t timecode_frame_start;
-
- /* The RTP callback: This function is called */
- /* every time the encoder has a packet to send. */
- /* It depends on the encoder if the data starts */
- /* with a Start Code (it should). H.263 does. */
- /* mb_nb contains the number of macroblocks */
- /* encoded in the RTP payload. */
- void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb);
-
- int rtp_payload_size; /* The size of the RTP payload: the coder will */
- /* do its best to deliver a chunk with size */
- /* below rtp_payload_size, the chunk will start */
- /* with a start code on some codecs like H.263. */
- /* This doesn't take account of any particular */
- /* headers inside the transmitted RTP payload. */
-
- /* statistics, used for 2-pass encoding */
- int mv_bits;
- int header_bits;
- int i_tex_bits;
- int p_tex_bits;
- int i_count;
- int p_count;
- int skip_count;
- int misc_bits;
-
- /**
- * number of bits used for the previously encoded frame
- * - encoding: Set by libavcodec.
- * - decoding: unused
- */
- int frame_bits;
-
- /**
- * pass1 encoding statistics output buffer
- * - encoding: Set by libavcodec.
- * - decoding: unused
- */
- char *stats_out;
-
- /**
- * pass2 encoding statistics input buffer
- * Concatenated stuff from stats_out of pass1 should be placed here.
- * - encoding: Allocated/set/freed by user.
- * - decoding: unused
- */
- char *stats_in;
-
- /**
- * Work around bugs in encoders which sometimes cannot be detected automatically.
- * - encoding: Set by user
- * - decoding: Set by user
- */
- int workaround_bugs;
-#define FF_BUG_AUTODETECT 1 ///< autodetection
-#if FF_API_OLD_MSMPEG4
-#define FF_BUG_OLD_MSMPEG4 2
-#endif
-#define FF_BUG_XVID_ILACE 4
-#define FF_BUG_UMP4 8
-#define FF_BUG_NO_PADDING 16
-#define FF_BUG_AMV 32
-#if FF_API_AC_VLC
-#define FF_BUG_AC_VLC 0 ///< Will be removed, libavcodec can now handle these non-compliant files by default.
-#endif
-#define FF_BUG_QPEL_CHROMA 64
-#define FF_BUG_STD_QPEL 128
-#define FF_BUG_QPEL_CHROMA2 256
-#define FF_BUG_DIRECT_BLOCKSIZE 512
-#define FF_BUG_EDGE 1024
-#define FF_BUG_HPEL_CHROMA 2048
-#define FF_BUG_DC_CLIP 4096
-#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders.
-#define FF_BUG_TRUNCATED 16384
-
- /**
- * strictly follow the standard (MPEG4, ...).
- * - encoding: Set by user.
- * - decoding: Set by user.
- * Setting this to STRICT or higher means the encoder and decoder will
- * generally do stupid things, whereas setting it to unofficial or lower
- * will mean the encoder might produce output that is not supported by all
- * spec-compliant decoders. Decoders don't differentiate between normal,
- * unofficial and experimental (that is, they always try to decode things
- * when they can) unless they are explicitly asked to behave stupidly
- * (=strictly conform to the specs)
- */
- int strict_std_compliance;
-#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to an older more strict version of the spec or reference software.
-#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences.
-#define FF_COMPLIANCE_NORMAL 0
-#define FF_COMPLIANCE_UNOFFICIAL -1 ///< Allow unofficial extensions
-#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things.
-
- /**
- * error concealment flags
- * - encoding: unused
- * - decoding: Set by user.
- */
- int error_concealment;
-#define FF_EC_GUESS_MVS 1
-#define FF_EC_DEBLOCK 2
-#define FF_EC_FAVOR_INTER 256
-
- /**
- * debug
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- int debug;
-#define FF_DEBUG_PICT_INFO 1
-#define FF_DEBUG_RC 2
-#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
-#if FF_API_UNUSED_MEMBERS
-#define FF_DEBUG_PTS 0x00000200
-#endif /* FF_API_UNUSED_MEMBERS */
-#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 ///< only access through AVOptions from outside libavcodec
-#define FF_DEBUG_VIS_MB_TYPE 0x00004000 ///< only access through AVOptions from outside libavcodec
-#endif
-#define FF_DEBUG_BUFFERS 0x00008000
-#define FF_DEBUG_THREADS 0x00010000
-#define FF_DEBUG_GREEN_MD 0x00800000
-#define FF_DEBUG_NOMC 0x01000000
-
-#if FF_API_DEBUG_MV
- /**
- * debug
- * Code outside libavcodec should access this field using AVOptions
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- int debug_mv;
-#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames
-#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames
-#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames
-#endif
-
- /**
- * Error recognition; may misdetect some more or less valid parts as errors.
- * - encoding: unused
- * - decoding: Set by user.
- */
- int err_recognition;
-
-/**
- * Verify checksums embedded in the bitstream (could be of either encoded or
- * decoded data, depending on the codec) and print an error message on mismatch.
- * If AV_EF_EXPLODE is also set, a mismatching checksum will result in the
- * decoder returning an error.
- */
-#define AV_EF_CRCCHECK (1<<0)
-#define AV_EF_BITSTREAM (1<<1) ///< detect bitstream specification deviations
-#define AV_EF_BUFFER (1<<2) ///< detect improper bitstream length
-#define AV_EF_EXPLODE (1<<3) ///< abort decoding on minor error detection
-
-#define AV_EF_IGNORE_ERR (1<<15) ///< ignore errors and continue
-#define AV_EF_CAREFUL (1<<16) ///< consider things that violate the spec, are fast to calculate and have not been seen in the wild as errors
-#define AV_EF_COMPLIANT (1<<17) ///< consider all spec non compliances as errors
-#define AV_EF_AGGRESSIVE (1<<18) ///< consider things that a sane encoder should not do as an error
-
-
- /**
- * opaque 64bit number (generally a PTS) that will be reordered and
- * output in AVFrame.reordered_opaque
- * - encoding: unused
- * - decoding: Set by user.
- */
- int64_t reordered_opaque;
-
- /**
- * Hardware accelerator in use
- * - encoding: unused.
- * - decoding: Set by libavcodec
- */
- struct AVHWAccel *hwaccel;
-
- /**
- * Hardware accelerator context.
- * For some hardware accelerators, a global context needs to be
- * provided by the user. In that case, this holds display-dependent
- * data FFmpeg cannot instantiate itself. Please refer to the
- * FFmpeg HW accelerator documentation to know how to fill this
- * is. e.g. for VA API, this is a struct vaapi_context.
- * - encoding: unused
- * - decoding: Set by user
- */
- void *hwaccel_context;
-
- /**
- * error
- * - encoding: Set by libavcodec if flags & AV_CODEC_FLAG_PSNR.
- * - decoding: unused
- */
- uint64_t error[AV_NUM_DATA_POINTERS];
-
- /**
- * DCT algorithm, see FF_DCT_* below
- * - encoding: Set by user.
- * - decoding: unused
- */
- int dct_algo;
-#define FF_DCT_AUTO 0
-#define FF_DCT_FASTINT 1
-#define FF_DCT_INT 2
-#define FF_DCT_MMX 3
-#define FF_DCT_ALTIVEC 5
-#define FF_DCT_FAAN 6
-
- /**
- * IDCT algorithm, see FF_IDCT_* below.
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- int idct_algo;
-#define FF_IDCT_AUTO 0
-#define FF_IDCT_INT 1
-#define FF_IDCT_SIMPLE 2
-#define FF_IDCT_SIMPLEMMX 3
-#define FF_IDCT_ARM 7
-#define FF_IDCT_ALTIVEC 8
-#if FF_API_ARCH_SH4
-#define FF_IDCT_SH4 9
-#endif
-#define FF_IDCT_SIMPLEARM 10
-#if FF_API_UNUSED_MEMBERS
-#define FF_IDCT_IPP 13
-#endif /* FF_API_UNUSED_MEMBERS */
-#define FF_IDCT_XVID 14
-#if FF_API_IDCT_XVIDMMX
-#define FF_IDCT_XVIDMMX 14
-#endif /* FF_API_IDCT_XVIDMMX */
-#define FF_IDCT_SIMPLEARMV5TE 16
-#define FF_IDCT_SIMPLEARMV6 17
-#if FF_API_ARCH_SPARC
-#define FF_IDCT_SIMPLEVIS 18
-#endif
-#define FF_IDCT_FAAN 20
-#define FF_IDCT_SIMPLENEON 22
-#if FF_API_ARCH_ALPHA
-#define FF_IDCT_SIMPLEALPHA 23
-#endif
-#define FF_IDCT_SIMPLEAUTO 128
-
- /**
- * bits per sample/pixel from the demuxer (needed for huffyuv).
- * - encoding: Set by libavcodec.
- * - decoding: Set by user.
- */
- int bits_per_coded_sample;
-
- /**
- * Bits per sample/pixel of internal libavcodec pixel/sample format.
- * - encoding: set by user.
- * - decoding: set by libavcodec.
- */
- int bits_per_raw_sample;
-
-#if FF_API_LOWRES
- /**
- * low resolution decoding, 1-> 1/2 size, 2->1/4 size
- * - encoding: unused
- * - decoding: Set by user.
- * Code outside libavcodec should access this field using:
- * av_codec_{get,set}_lowres(avctx)
- */
- int lowres;
-#endif
-
-#if FF_API_CODED_FRAME
- /**
- * the picture in the bitstream
- * - encoding: Set by libavcodec.
- * - decoding: unused
- *
- * @deprecated use the quality factor packet side data instead
- */
- attribute_deprecated AVFrame *coded_frame;
-#endif
-
- /**
- * thread count
- * is used to decide how many independent tasks should be passed to execute()
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- int thread_count;
-
- /**
- * Which multithreading methods to use.
- * Use of FF_THREAD_FRAME will increase decoding delay by one frame per thread,
- * so clients which cannot provide future frames should not use it.
- *
- * - encoding: Set by user, otherwise the default is used.
- * - decoding: Set by user, otherwise the default is used.
- */
- int thread_type;
-#define FF_THREAD_FRAME 1 ///< Decode more than one frame at once
-#define FF_THREAD_SLICE 2 ///< Decode more than one part of a single frame at once
-
- /**
- * Which multithreading methods are in use by the codec.
- * - encoding: Set by libavcodec.
- * - decoding: Set by libavcodec.
- */
- int active_thread_type;
-
- /**
- * Set by the client if its custom get_buffer() callback can be called
- * synchronously from another thread, which allows faster multithreaded decoding.
- * draw_horiz_band() will be called from other threads regardless of this setting.
- * Ignored if the default get_buffer() is used.
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- int thread_safe_callbacks;
-
- /**
- * The codec may call this to execute several independent things.
- * It will return only after finishing all tasks.
- * The user may replace this with some multithreaded implementation,
- * the default implementation will execute the parts serially.
- * @param count the number of things to execute
- * - encoding: Set by libavcodec, user can override.
- * - decoding: Set by libavcodec, user can override.
- */
- int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size);
-
- /**
- * The codec may call this to execute several independent things.
- * It will return only after finishing all tasks.
- * The user may replace this with some multithreaded implementation,
- * the default implementation will execute the parts serially.
- * Also see avcodec_thread_init and e.g. the --enable-pthread configure option.
- * @param c context passed also to func
- * @param count the number of things to execute
- * @param arg2 argument passed unchanged to func
- * @param ret return values of executed functions, must have space for "count" values. May be NULL.
- * @param func function that will be called count times, with jobnr from 0 to count-1.
- * threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS and so that no
- * two instances of func executing at the same time will have the same threadnr.
- * @return always 0 currently, but code should handle a future improvement where when any call to func
- * returns < 0 no further calls to func may be done and < 0 is returned.
- * - encoding: Set by libavcodec, user can override.
- * - decoding: Set by libavcodec, user can override.
- */
- int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);
-
-#if FF_API_THREAD_OPAQUE
- /**
- * @deprecated this field should not be used from outside of lavc
- */
- attribute_deprecated
- void *thread_opaque;
-#endif
-
- /**
- * noise vs. sse weight for the nsse comparison function
- * - encoding: Set by user.
- * - decoding: unused
- */
- int nsse_weight;
-
- /**
- * profile
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- int profile;
-#define FF_PROFILE_UNKNOWN -99
-#define FF_PROFILE_RESERVED -100
-
-#define FF_PROFILE_AAC_MAIN 0
-#define FF_PROFILE_AAC_LOW 1
-#define FF_PROFILE_AAC_SSR 2
-#define FF_PROFILE_AAC_LTP 3
-#define FF_PROFILE_AAC_HE 4
-#define FF_PROFILE_AAC_HE_V2 28
-#define FF_PROFILE_AAC_LD 22
-#define FF_PROFILE_AAC_ELD 38
-#define FF_PROFILE_MPEG2_AAC_LOW 128
-#define FF_PROFILE_MPEG2_AAC_HE 131
-
-#define FF_PROFILE_DTS 20
-#define FF_PROFILE_DTS_ES 30
-#define FF_PROFILE_DTS_96_24 40
-#define FF_PROFILE_DTS_HD_HRA 50
-#define FF_PROFILE_DTS_HD_MA 60
-#define FF_PROFILE_DTS_EXPRESS 70
-
-#define FF_PROFILE_MPEG2_422 0
-#define FF_PROFILE_MPEG2_HIGH 1
-#define FF_PROFILE_MPEG2_SS 2
-#define FF_PROFILE_MPEG2_SNR_SCALABLE 3
-#define FF_PROFILE_MPEG2_MAIN 4
-#define FF_PROFILE_MPEG2_SIMPLE 5
-
-#define FF_PROFILE_H264_CONSTRAINED (1<<9) // 8+1; constraint_set1_flag
-#define FF_PROFILE_H264_INTRA (1<<11) // 8+3; constraint_set3_flag
-
-#define FF_PROFILE_H264_BASELINE 66
-#define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED)
-#define FF_PROFILE_H264_MAIN 77
-#define FF_PROFILE_H264_EXTENDED 88
-#define FF_PROFILE_H264_HIGH 100
-#define FF_PROFILE_H264_HIGH_10 110
-#define FF_PROFILE_H264_HIGH_10_INTRA (110|FF_PROFILE_H264_INTRA)
-#define FF_PROFILE_H264_HIGH_422 122
-#define FF_PROFILE_H264_HIGH_422_INTRA (122|FF_PROFILE_H264_INTRA)
-#define FF_PROFILE_H264_HIGH_444 144
-#define FF_PROFILE_H264_HIGH_444_PREDICTIVE 244
-#define FF_PROFILE_H264_HIGH_444_INTRA (244|FF_PROFILE_H264_INTRA)
-#define FF_PROFILE_H264_CAVLC_444 44
-
-#define FF_PROFILE_VC1_SIMPLE 0
-#define FF_PROFILE_VC1_MAIN 1
-#define FF_PROFILE_VC1_COMPLEX 2
-#define FF_PROFILE_VC1_ADVANCED 3
-
-#define FF_PROFILE_MPEG4_SIMPLE 0
-#define FF_PROFILE_MPEG4_SIMPLE_SCALABLE 1
-#define FF_PROFILE_MPEG4_CORE 2
-#define FF_PROFILE_MPEG4_MAIN 3
-#define FF_PROFILE_MPEG4_N_BIT 4
-#define FF_PROFILE_MPEG4_SCALABLE_TEXTURE 5
-#define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION 6
-#define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE 7
-#define FF_PROFILE_MPEG4_HYBRID 8
-#define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME 9
-#define FF_PROFILE_MPEG4_CORE_SCALABLE 10
-#define FF_PROFILE_MPEG4_ADVANCED_CODING 11
-#define FF_PROFILE_MPEG4_ADVANCED_CORE 12
-#define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13
-#define FF_PROFILE_MPEG4_SIMPLE_STUDIO 14
-#define FF_PROFILE_MPEG4_ADVANCED_SIMPLE 15
-
-#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0 0
-#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1 1
-#define FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION 2
-#define FF_PROFILE_JPEG2000_DCINEMA_2K 3
-#define FF_PROFILE_JPEG2000_DCINEMA_4K 4
-
-#define FF_PROFILE_VP9_0 0
-#define FF_PROFILE_VP9_1 1
-#define FF_PROFILE_VP9_2 2
-#define FF_PROFILE_VP9_3 3
-
-#define FF_PROFILE_HEVC_MAIN 1
-#define FF_PROFILE_HEVC_MAIN_10 2
-#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3
-#define FF_PROFILE_HEVC_REXT 4
-
- /**
- * level
- * - encoding: Set by user.
- * - decoding: Set by libavcodec.
- */
- int level;
-#define FF_LEVEL_UNKNOWN -99
-
- /**
- * Skip loop filtering for selected frames.
- * - encoding: unused
- * - decoding: Set by user.
- */
- enum AVDiscard skip_loop_filter;
-
- /**
- * Skip IDCT/dequantization for selected frames.
- * - encoding: unused
- * - decoding: Set by user.
- */
- enum AVDiscard skip_idct;
-
- /**
- * Skip decoding for selected frames.
- * - encoding: unused
- * - decoding: Set by user.
- */
- enum AVDiscard skip_frame;
-
- /**
- * Header containing style information for text subtitles.
- * For SUBTITLE_ASS subtitle type, it should contain the whole ASS
- * [Script Info] and [V4+ Styles] section, plus the [Events] line and
- * the Format line following. It shouldn't include any Dialogue line.
- * - encoding: Set/allocated/freed by user (before avcodec_open2())
- * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2())
- */
- uint8_t *subtitle_header;
- int subtitle_header_size;
-
-#if FF_API_ERROR_RATE
- /**
- * @deprecated use the 'error_rate' private AVOption of the mpegvideo
- * encoders
- */
- attribute_deprecated
- int error_rate;
-#endif
-
-#if FF_API_CODEC_PKT
- /**
- * @deprecated this field is not supposed to be accessed from outside lavc
- */
- attribute_deprecated
- AVPacket *pkt;
-#endif
-
- /**
- * VBV delay coded in the last frame (in periods of a 27 MHz clock).
- * Used for compliant TS muxing.
- * - encoding: Set by libavcodec.
- * - decoding: unused.
- */
- uint64_t vbv_delay;
-
- /**
- * Encoding only. Allow encoders to output packets that do not contain any
- * encoded data, only side data.
- *
- * Some encoders need to output such packets, e.g. to update some stream
- * parameters at the end of encoding.
- *
- * All callers are strongly recommended to set this option to 1 and update
- * their code to deal with such packets, since this behaviour may become
- * always enabled in the future (then this option will be deprecated and
- * later removed). To avoid ABI issues when this happens, the callers should
- * use AVOptions to set this field.
- */
- int side_data_only_packets;
-
- /**
- * Audio only. The number of "priming" samples (padding) inserted by the
- * encoder at the beginning of the audio. I.e. this number of leading
- * decoded samples must be discarded by the caller to get the original audio
- * without leading padding.
- *
- * - decoding: unused
- * - encoding: Set by libavcodec. The timestamps on the output packets are
- * adjusted by the encoder so that they always refer to the
- * first sample of the data actually contained in the packet,
- * including any added padding. E.g. if the timebase is
- * 1/samplerate and the timestamp of the first input sample is
- * 0, the timestamp of the first output packet will be
- * -initial_padding.
- */
- int initial_padding;
-
- /**
- * - decoding: For codecs that store a framerate value in the compressed
- * bitstream, the decoder may export it here. { 0, 1} when
- * unknown.
- * - encoding: unused
- */
- AVRational framerate;
-
- /**
- * Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
- * - encoding: unused.
- * - decoding: Set by libavcodec before calling get_format()
- */
- enum AVPixelFormat sw_pix_fmt;
-
- /**
- * Timebase in which pkt_dts/pts and AVPacket.dts/pts are.
- * Code outside libavcodec should access this field using:
- * av_codec_{get,set}_pkt_timebase(avctx)
- * - encoding unused.
- * - decoding set by user.
- */
- AVRational pkt_timebase;
-
- /**
- * AVCodecDescriptor
- * Code outside libavcodec should access this field using:
- * av_codec_{get,set}_codec_descriptor(avctx)
- * - encoding: unused.
- * - decoding: set by libavcodec.
- */
- const AVCodecDescriptor *codec_descriptor;
-
-#if !FF_API_LOWRES
- /**
- * low resolution decoding, 1-> 1/2 size, 2->1/4 size
- * - encoding: unused
- * - decoding: Set by user.
- * Code outside libavcodec should access this field using:
- * av_codec_{get,set}_lowres(avctx)
- */
- int lowres;
-#endif
-
- /**
- * Current statistics for PTS correction.
- * - decoding: maintained and used by libavcodec, not intended to be used by user apps
- * - encoding: unused
- */
- int64_t pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far
- int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far
- int64_t pts_correction_last_pts; /// PTS of the last frame
- int64_t pts_correction_last_dts; /// DTS of the last frame
-
- /**
- * Character encoding of the input subtitles file.
- * - decoding: set by user
- * - encoding: unused
- */
- char *sub_charenc;
-
- /**
- * Subtitles character encoding mode. Formats or codecs might be adjusting
- * this setting (if they are doing the conversion themselves for instance).
- * - decoding: set by libavcodec
- * - encoding: unused
- */
- int sub_charenc_mode;
-#define FF_SUB_CHARENC_MODE_DO_NOTHING -1 ///< do nothing (demuxer outputs a stream supposed to be already in UTF-8, or the codec is bitmap for instance)
-#define FF_SUB_CHARENC_MODE_AUTOMATIC 0 ///< libavcodec will select the mode itself
-#define FF_SUB_CHARENC_MODE_PRE_DECODER 1 ///< the AVPacket data needs to be recoded to UTF-8 before being fed to the decoder, requires iconv
-
- /**
- * Skip processing alpha if supported by codec.
- * Note that if the format uses pre-multiplied alpha (common with VP6,
- * and recommended due to better video quality/compression)
- * the image will look as if alpha-blended onto a black background.
- * However for formats that do not use pre-multiplied alpha
- * there might be serious artefacts (though e.g. libswscale currently
- * assumes pre-multiplied alpha anyway).
- * Code outside libavcodec should access this field using AVOptions
- *
- * - decoding: set by user
- * - encoding: unused
- */
- int skip_alpha;
-
- /**
- * Number of samples to skip after a discontinuity
- * - decoding: unused
- * - encoding: set by libavcodec
- */
- int seek_preroll;
-
-#if !FF_API_DEBUG_MV
- /**
- * debug motion vectors
- * Code outside libavcodec should access this field using AVOptions
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- int debug_mv;
-#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames
-#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames
-#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames
-#endif
-
- /**
- * custom intra quantization matrix
- * Code outside libavcodec should access this field using av_codec_g/set_chroma_intra_matrix()
- * - encoding: Set by user, can be NULL.
- * - decoding: unused.
- */
- uint16_t *chroma_intra_matrix;
-
- /**
- * dump format separator.
- * can be ", " or "\n " or anything else
- * Code outside libavcodec should access this field using AVOptions
- * (NO direct access).
- * - encoding: Set by user.
- * - decoding: Set by user.
- */
- uint8_t *dump_separator;
-
- /**
- * ',' separated list of allowed decoders.
- * If NULL then all are allowed
- * - encoding: unused
- * - decoding: set by user through AVOPtions (NO direct access)
- */
- char *codec_whitelist;
-
- /*
- * Properties of the stream that gets decoded
- * To be accessed through av_codec_get_properties() (NO direct access)
- * - encoding: unused
- * - decoding: set by libavcodec
- */
- unsigned properties;
-#define FF_CODEC_PROPERTY_LOSSLESS 0x00000001
-#define FF_CODEC_PROPERTY_CLOSED_CAPTIONS 0x00000002
-} AVCodecContext;
-
-AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx);
-void av_codec_set_pkt_timebase (AVCodecContext *avctx, AVRational val);
-
-const AVCodecDescriptor *av_codec_get_codec_descriptor(const AVCodecContext *avctx);
-void av_codec_set_codec_descriptor(AVCodecContext *avctx, const AVCodecDescriptor *desc);
-
-unsigned av_codec_get_codec_properties(const AVCodecContext *avctx);
-
-int av_codec_get_lowres(const AVCodecContext *avctx);
-void av_codec_set_lowres(AVCodecContext *avctx, int val);
-
-int av_codec_get_seek_preroll(const AVCodecContext *avctx);
-void av_codec_set_seek_preroll(AVCodecContext *avctx, int val);
-
-uint16_t *av_codec_get_chroma_intra_matrix(const AVCodecContext *avctx);
-void av_codec_set_chroma_intra_matrix(AVCodecContext *avctx, uint16_t *val);
-
-/**
- * AVProfile.
- */
-typedef struct AVProfile {
- int profile;
- const char *name; ///< short name for the profile
-} AVProfile;
-
-typedef struct AVCodecDefault AVCodecDefault;
-
-struct AVSubtitle;
-
-/**
- * AVCodec.
- */
-typedef struct AVCodec {
- /**
- * Name of the codec implementation.
- * The name is globally unique among encoders and among decoders (but an
- * encoder and a decoder can share the same name).
- * This is the primary way to find a codec from the user perspective.
- */
- const char *name;
- /**
- * Descriptive name for the codec, meant to be more human readable than name.
- * You should use the NULL_IF_CONFIG_SMALL() macro to define it.
- */
- const char *long_name;
- enum AVMediaType type;
- enum AVCodecID id;
- /**
- * Codec capabilities.
- * see AV_CODEC_CAP_*
- */
- int capabilities;
- const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0}
- const enum AVPixelFormat *pix_fmts; ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1
- const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
- const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
- const uint64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
- uint8_t max_lowres; ///< maximum value for lowres supported by the decoder, no direct access, use av_codec_get_max_lowres()
- const AVClass *priv_class; ///< AVClass for the private context
- const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN}
-
- /*****************************************************************
- * No fields below this line are part of the public API. They
- * may not be used outside of libavcodec and can be changed and
- * removed at will.
- * New public fields should be added right above.
- *****************************************************************
- */
- int priv_data_size;
- struct AVCodec *next;
- /**
- * @name Frame-level threading support functions
- * @{
- */
- /**
- * If defined, called on thread contexts when they are created.
- * If the codec allocates writable tables in init(), re-allocate them here.
- * priv_data will be set to a copy of the original.
- */
- int (*init_thread_copy)(AVCodecContext *);
- /**
- * Copy necessary context variables from a previous thread context to the current one.
- * If not defined, the next thread will start automatically; otherwise, the codec
- * must call ff_thread_finish_setup().
- *
- * dst and src will (rarely) point to the same context, in which case memcpy should be skipped.
- */
- int (*update_thread_context)(AVCodecContext *dst, const AVCodecContext *src);
- /** @} */
-
- /**
- * Private codec-specific defaults.
- */
- const AVCodecDefault *defaults;
-
- /**
- * Initialize codec static data, called from avcodec_register().
- */
- void (*init_static_data)(struct AVCodec *codec);
-
- int (*init)(AVCodecContext *);
- int (*encode_sub)(AVCodecContext *, uint8_t *buf, int buf_size,
- const struct AVSubtitle *sub);
- /**
- * Encode data to an AVPacket.
- *
- * @param avctx codec context
- * @param avpkt output AVPacket (may contain a user-provided buffer)
- * @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.
- * @return 0 on success, negative error code on failure
- */
- int (*encode2)(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame,
- int *got_packet_ptr);
- int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt);
- int (*close)(AVCodecContext *);
- /**
- * Flush buffers.
- * Will be called when seeking
- */
- void (*flush)(AVCodecContext *);
- /**
- * Internal codec capabilities.
- * See FF_CODEC_CAP_* in internal.h
- */
- int caps_internal;
-} AVCodec;
-
-int av_codec_get_max_lowres(const AVCodec *codec);
-
-struct MpegEncContext;
-
-/**
- * @defgroup lavc_hwaccel AVHWAccel
- * @{
- */
-typedef struct AVHWAccel {
- /**
- * Name of the hardware accelerated codec.
- * The name is globally unique among encoders and among decoders (but an
- * encoder and a decoder can share the same name).
- */
- const char *name;
-
- /**
- * Type of codec implemented by the hardware accelerator.
- *
- * See AVMEDIA_TYPE_xxx
- */
- enum AVMediaType type;
-
- /**
- * Codec implemented by the hardware accelerator.
- *
- * See AV_CODEC_ID_xxx
- */
- enum AVCodecID id;
-
- /**
- * Supported pixel format.
- *
- * Only hardware accelerated formats are supported here.
- */
- enum AVPixelFormat pix_fmt;
-
- /**
- * Hardware accelerated codec capabilities.
- * see HWACCEL_CODEC_CAP_*
- */
- int capabilities;
-
- /*****************************************************************
- * No fields below this line are part of the public API. They
- * may not be used outside of libavcodec and can be changed and
- * removed at will.
- * New public fields should be added right above.
- *****************************************************************
- */
- struct AVHWAccel *next;
-
- /**
- * Allocate a custom buffer
- */
- int (*alloc_frame)(AVCodecContext *avctx, AVFrame *frame);
-
- /**
- * Called at the beginning of each frame or field picture.
- *
- * Meaningful frame information (codec specific) is guaranteed to
- * be parsed at this point. This function is mandatory.
- *
- * Note that buf can be NULL along with buf_size set to 0.
- * Otherwise, this means the whole frame is available at this point.
- *
- * @param avctx the codec context
- * @param buf the frame data buffer base
- * @param buf_size the size of the frame in bytes
- * @return zero if successful, a negative value otherwise
- */
- int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size);
-
- /**
- * Callback for each slice.
- *
- * Meaningful slice information (codec specific) is guaranteed to
- * be parsed at this point. This function is mandatory.
- * The only exception is XvMC, that works on MB level.
- *
- * @param avctx the codec context
- * @param buf the slice data buffer base
- * @param buf_size the size of the slice in bytes
- * @return zero if successful, a negative value otherwise
- */
- int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size);
-
- /**
- * Called at the end of each frame or field picture.
- *
- * The whole picture is parsed at this point and can now be sent
- * to the hardware accelerator. This function is mandatory.
- *
- * @param avctx the codec context
- * @return zero if successful, a negative value otherwise
- */
- int (*end_frame)(AVCodecContext *avctx);
-
- /**
- * Size of per-frame hardware accelerator private data.
- *
- * Private data is allocated with av_mallocz() before
- * AVCodecContext.get_buffer() and deallocated after
- * AVCodecContext.release_buffer().
- */
- int frame_priv_data_size;
-
- /**
- * Called for every Macroblock in a slice.
- *
- * XvMC uses it to replace the ff_mpv_decode_mb().
- * Instead of decoding to raw picture, MB parameters are
- * stored in an array provided by the video driver.
- *
- * @param s the mpeg context
- */
- void (*decode_mb)(struct MpegEncContext *s);
-
- /**
- * Initialize the hwaccel private data.
- *
- * This will be called from ff_get_format(), after hwaccel and
- * hwaccel_context are set and the hwaccel private data in AVCodecInternal
- * is allocated.
- */
- int (*init)(AVCodecContext *avctx);
-
- /**
- * Uninitialize the hwaccel private data.
- *
- * This will be called from get_format() or avcodec_close(), after hwaccel
- * and hwaccel_context are already uninitialized.
- */
- int (*uninit)(AVCodecContext *avctx);
-
- /**
- * Size of the private data to allocate in
- * AVCodecInternal.hwaccel_priv_data.
- */
- int priv_data_size;
-} AVHWAccel;
-
-/**
- * Hardware acceleration should be used for decoding even if the codec level
- * used is unknown or higher than the maximum supported level reported by the
- * hardware driver.
- *
- * It's generally a good idea to pass this flag unless you have a specific
- * reason not to, as hardware tends to under-report supported levels.
- */
-#define AV_HWACCEL_FLAG_IGNORE_LEVEL (1 << 0)
-
-/**
- * Hardware acceleration can output YUV pixel formats with a different chroma
- * sampling than 4:2:0 and/or other than 8 bits per component.
- */
-#define AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH (1 << 1)
-
-/**
- * @}
- */
-
-/**
- * @defgroup lavc_picture AVPicture
- *
- * Functions for working with AVPicture
- * @{
- */
-
-/**
- * Picture data structure.
- *
- * Up to four components can be stored into it, the last component is
- * alpha.
- */
-typedef struct AVPicture {
- uint8_t *data[AV_NUM_DATA_POINTERS]; ///< pointers to the image data planes
- int linesize[AV_NUM_DATA_POINTERS]; ///< number of bytes per line
-} AVPicture;
-
-/**
- * @}
- */
-
-enum AVSubtitleType {
- SUBTITLE_NONE,
-
- SUBTITLE_BITMAP, ///< A bitmap, pict will be set
-
- /**
- * Plain text, the text field must be set by the decoder and is
- * authoritative. ass and pict fields may contain approximations.
- */
- SUBTITLE_TEXT,
-
- /**
- * Formatted text, the ass field must be set by the decoder and is
- * authoritative. pict and text fields may contain approximations.
- */
- SUBTITLE_ASS,
-};
-
-#define AV_SUBTITLE_FLAG_FORCED 0x00000001
-
-typedef struct AVSubtitleRect {
- int x; ///< top left corner of pict, undefined when pict is not set
- int y; ///< top left corner of pict, undefined when pict is not set
- int w; ///< width of pict, undefined when pict is not set
- int h; ///< height of pict, undefined when pict is not set
- int nb_colors; ///< number of colors in pict, undefined when pict is not set
-
- /**
- * data+linesize for the bitmap of this subtitle.
- * can be set for text/ass as well once they are rendered
- */
- AVPicture pict;
- enum AVSubtitleType type;
-
- char *text; ///< 0 terminated plain UTF-8 text
-
- /**
- * 0 terminated ASS/SSA compatible event line.
- * The presentation of this is unaffected by the other values in this
- * struct.
- */
- char *ass;
-
- int flags;
-} AVSubtitleRect;
-
-typedef struct AVSubtitle {
- uint16_t format; /* 0 = graphics */
- uint32_t start_display_time; /* relative to packet pts, in ms */
- uint32_t end_display_time; /* relative to packet pts, in ms */
- unsigned num_rects;
- AVSubtitleRect **rects;
- int64_t pts; ///< Same as packet pts, in AV_TIME_BASE
-} AVSubtitle;
-
-/**
- * If c is NULL, returns the first registered codec,
- * if c is non-NULL, returns the next registered codec after c,
- * or NULL if c is the last one.
- */
-AVCodec *av_codec_next(const AVCodec *c);
-
-/**
- * Return the LIBAVCODEC_VERSION_INT constant.
- */
-unsigned avcodec_version(void);
-
-/**
- * Return the libavcodec build-time configuration.
- */
-const char *avcodec_configuration(void);
-
-/**
- * Return the libavcodec license.
- */
-const char *avcodec_license(void);
-
-/**
- * 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()
- */
-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
- */
-void avcodec_register_all(void);
-
-/**
- * Allocate an AVCodecContext and set its fields to default values. The
- * resulting struct should be freed with avcodec_free_context().
- *
- * @param codec if non-NULL, allocate private data and initialize defaults
- * for the given codec. It is illegal to then call avcodec_open2()
- * with a different codec.
- * If NULL, then the codec-specific defaults won't be initialized,
- * which may result in suboptimal default settings (this is
- * important mainly for encoders, e.g. libx264).
- *
- * @return An AVCodecContext filled with default values or NULL on failure.
- * @see avcodec_get_context_defaults
- */
-AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
-
-/**
- * Free the codec context and everything associated with it and write NULL to
- * the provided pointer.
- */
-void avcodec_free_context(AVCodecContext **avctx);
-
-/**
- * Set the fields of the given AVCodecContext to default values corresponding
- * to the given codec (defaults may be codec-dependent).
- *
- * Do not call this function if a non-NULL codec has been passed
- * to avcodec_alloc_context3() that allocated this AVCodecContext.
- * If codec is non-NULL, it is illegal to call avcodec_open2() with a
- * different codec on this AVCodecContext.
- */
-int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec);
-
-/**
- * Get the AVClass for AVCodecContext. It can be used in combination with
- * AV_OPT_SEARCH_FAKE_OBJ for examining options.
- *
- * @see av_opt_find().
- */
-const AVClass *avcodec_get_class(void);
-
-/**
- * Get the AVClass for AVFrame. It can be used in combination with
- * AV_OPT_SEARCH_FAKE_OBJ for examining options.
- *
- * @see av_opt_find().
- */
-const AVClass *avcodec_get_frame_class(void);
-
-/**
- * Get the AVClass for AVSubtitleRect. It can be used in combination with
- * AV_OPT_SEARCH_FAKE_OBJ for examining options.
- *
- * @see av_opt_find().
- */
-const AVClass *avcodec_get_subtitle_rect_class(void);
-
-/**
- * Copy the settings of the source AVCodecContext into the destination
- * AVCodecContext. The resulting destination codec context will be
- * unopened, i.e. you are required to call avcodec_open2() before you
- * can use this AVCodecContext to decode/encode video/audio data.
- *
- * @param dest target codec context, should be initialized with
- * avcodec_alloc_context3(NULL), but otherwise uninitialized
- * @param src source codec context
- * @return AVERROR() on error (e.g. memory allocation error), 0 on success
- */
-int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src);
-
-#if FF_API_AVFRAME_LAVC
-/**
- * @deprecated use av_frame_alloc()
- */
-attribute_deprecated
-AVFrame *avcodec_alloc_frame(void);
-
-/**
- * Set the fields of the given AVFrame to default values.
- *
- * @param frame The AVFrame of which the fields should be set to default values.
- *
- * @deprecated use av_frame_unref()
- */
-attribute_deprecated
-void avcodec_get_frame_defaults(AVFrame *frame);
-
-/**
- * Free the frame and any dynamically allocated objects in it,
- * e.g. extended_data.
- *
- * @param frame frame to be freed. The pointer will be set to NULL.
- *
- * @warning this function does NOT free the data buffers themselves
- * (it does not know how, since they might have been allocated with
- * a custom get_buffer()).
- *
- * @deprecated use av_frame_free()
- */
-attribute_deprecated
-void avcodec_free_frame(AVFrame **frame);
-#endif
-
-/**
- * Initialize the AVCodecContext to use the given AVCodec. Prior to using this
- * function the context has to be allocated with avcodec_alloc_context3().
- *
- * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(),
- * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for
- * retrieving a codec.
- *
- * @warning This function is not thread safe!
- *
- * @note Always call this function before using decoding routines (such as
- * @ref avcodec_decode_video2()).
- *
- * @code
- * avcodec_register_all();
- * av_dict_set(&opts, "b", "2.5M", 0);
- * codec = avcodec_find_decoder(AV_CODEC_ID_H264);
- * if (!codec)
- * exit(1);
- *
- * context = avcodec_alloc_context3(codec);
- *
- * if (avcodec_open2(context, codec, opts) < 0)
- * exit(1);
- * @endcode
- *
- * @param avctx The context to initialize.
- * @param codec The codec to open this context for. If a non-NULL codec has been
- * previously passed to avcodec_alloc_context3() or
- * avcodec_get_context_defaults3() for this context, then this
- * parameter MUST be either NULL or equal to the previously passed
- * codec.
- * @param options A dictionary filled with AVCodecContext and codec-private options.
- * On return this object will be filled with options that were not found.
- *
- * @return zero on success, a negative value on error
- * @see avcodec_alloc_context3(), avcodec_find_decoder(), avcodec_find_encoder(),
- * av_dict_set(), av_opt_find().
- */
-int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
-
-/**
- * Close a given AVCodecContext and free all the data associated with it
- * (but not the AVCodecContext itself).
- *
- * Calling this function on an AVCodecContext that hasn't been opened will free
- * the codec-specific data allocated in avcodec_alloc_context3() /
- * avcodec_get_context_defaults3() with a non-NULL codec. Subsequent calls will
- * do nothing.
- */
-int avcodec_close(AVCodecContext *avctx);
-
-/**
- * Free all allocated data in the given subtitle struct.
- *
- * @param sub AVSubtitle to free.
- */
-void avsubtitle_free(AVSubtitle *sub);
-
-/**
- * @}
- */
-
-/**
- * @addtogroup lavc_packet
- * @{
- */
-
-#if FF_API_DESTRUCT_PACKET
-/**
- * Default packet destructor.
- * @deprecated use the AVBuffer API instead
- */
-attribute_deprecated
-void av_destruct_packet(AVPacket *pkt);
-#endif
-
-/**
- * Initialize optional fields of a packet with default values.
- *
- * Note, this does not touch the data and size members, which have to be
- * initialized separately.
- *
- * @param pkt packet
- */
-void av_init_packet(AVPacket *pkt);
-
-/**
- * Allocate the payload of a packet and initialize its fields with
- * default values.
- *
- * @param pkt packet
- * @param size wanted payload size
- * @return 0 if OK, AVERROR_xxx otherwise
- */
-int av_new_packet(AVPacket *pkt, int size);
-
-/**
- * Reduce packet size, correctly zeroing padding
- *
- * @param pkt packet
- * @param size new size
- */
-void av_shrink_packet(AVPacket *pkt, int size);
-
-/**
- * Increase packet size, correctly zeroing padding
- *
- * @param pkt packet
- * @param grow_by number of bytes by which to increase the size of the packet
- */
-int av_grow_packet(AVPacket *pkt, int grow_by);
-
-/**
- * Initialize a reference-counted packet from av_malloc()ed data.
- *
- * @param pkt packet to be initialized. This function will set the data, size,
- * buf and destruct fields, all others are left untouched.
- * @param data Data allocated by av_malloc() to be used as packet data. If this
- * function returns successfully, the data is owned by the underlying AVBuffer.
- * The caller may not access the data through other means.
- * @param size size of data in bytes, without the padding. I.e. the full buffer
- * size is assumed to be size + AV_INPUT_BUFFER_PADDING_SIZE.
- *
- * @return 0 on success, a negative AVERROR on error
- */
-int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size);
-
-/**
- * @warning This is a hack - the packet memory allocation stuff is broken. The
- * packet is allocated if it was not really allocated.
- */
-int av_dup_packet(AVPacket *pkt);
-
-/**
- * Copy packet, including contents
- *
- * @return 0 on success, negative AVERROR on fail
- */
-int av_copy_packet(AVPacket *dst, const AVPacket *src);
-
-/**
- * Copy packet side data
- *
- * @return 0 on success, negative AVERROR on fail
- */
-int av_copy_packet_side_data(AVPacket *dst, const AVPacket *src);
-
-/**
- * Free a packet.
- *
- * @param pkt packet to free
- */
-void av_free_packet(AVPacket *pkt);
-
-/**
- * Allocate new information of a packet.
- *
- * @param pkt packet
- * @param type side information type
- * @param size side information size
- * @return pointer to fresh allocated data or NULL otherwise
- */
-uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
- int size);
-
-/**
- * Shrink the already allocated side data buffer
- *
- * @param pkt packet
- * @param type side information type
- * @param size new side information size
- * @return 0 on success, < 0 on failure
- */
-int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
- int size);
-
-/**
- * Get side information from packet.
- *
- * @param pkt packet
- * @param type desired side information type
- * @param size pointer for side information size to store (optional)
- * @return pointer to data if present or NULL otherwise
- */
-uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
- int *size);
-
-int av_packet_merge_side_data(AVPacket *pkt);
-
-int av_packet_split_side_data(AVPacket *pkt);
-
-const char *av_packet_side_data_name(enum AVPacketSideDataType type);
-
-/**
- * Pack a dictionary for use in side_data.
- *
- * @param dict The dictionary to pack.
- * @param size pointer to store the size of the returned data
- * @return pointer to data if successful, NULL otherwise
- */
-uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size);
-/**
- * Unpack a dictionary from side_data.
- *
- * @param data data from side_data
- * @param size size of the data
- * @param dict the metadata storage dictionary
- * @return 0 on success, < 0 on failure
- */
-int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict);
-
-
-/**
- * Convenience function to free all the side data stored.
- * All the other fields stay untouched.
- *
- * @param pkt packet
- */
-void av_packet_free_side_data(AVPacket *pkt);
-
-/**
- * Setup a new reference to the data described by a given packet
- *
- * If src is reference-counted, setup dst as a new reference to the
- * buffer in src. Otherwise allocate a new buffer in dst and copy the
- * data from src into it.
- *
- * All the other fields are copied from src.
- *
- * @see av_packet_unref
- *
- * @param dst Destination packet
- * @param src Source packet
- *
- * @return 0 on success, a negative AVERROR on error.
- */
-int av_packet_ref(AVPacket *dst, const AVPacket *src);
-
-/**
- * Wipe the packet.
- *
- * Unreference the buffer referenced by the packet and reset the
- * remaining packet fields to their default values.
- *
- * @param pkt The packet to be unreferenced.
- */
-void av_packet_unref(AVPacket *pkt);
-
-/**
- * Move every field in src to dst and reset src.
- *
- * @see av_packet_unref
- *
- * @param src Source packet, will be reset
- * @param dst Destination packet
- */
-void av_packet_move_ref(AVPacket *dst, AVPacket *src);
-
-/**
- * Copy only "properties" fields from src to dst.
- *
- * Properties for the purpose of this function are all the fields
- * beside those related to the packet data (buf, data, size)
- *
- * @param dst Destination packet
- * @param src Source packet
- *
- * @return 0 on success AVERROR on failure.
- *
- */
-int av_packet_copy_props(AVPacket *dst, const AVPacket *src);
-
-/**
- * Convert valid timing fields (timestamps / durations) in a packet from one
- * timebase to another. Timestamps with unknown values (AV_NOPTS_VALUE) will be
- * ignored.
- *
- * @param pkt packet on which the conversion will be performed
- * @param tb_src source timebase, in which the timing fields in pkt are
- * expressed
- * @param tb_dst destination timebase, to which the timing fields will be
- * converted
- */
-void av_packet_rescale_ts(AVPacket *pkt, AVRational tb_src, AVRational tb_dst);
-
-/**
- * @}
- */
-
-/**
- * @addtogroup lavc_decoding
- * @{
- */
-
-/**
- * Find a registered decoder with a matching codec ID.
- *
- * @param id AVCodecID of the requested decoder
- * @return A decoder if one was found, NULL otherwise.
- */
-AVCodec *avcodec_find_decoder(enum AVCodecID id);
-
-/**
- * Find a registered decoder with the specified name.
- *
- * @param name name of the requested decoder
- * @return A decoder if one was found, NULL otherwise.
- */
-AVCodec *avcodec_find_decoder_by_name(const char *name);
-
-#if FF_API_GET_BUFFER
-attribute_deprecated int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
-attribute_deprecated void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
-attribute_deprecated int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic);
-#endif
-
-/**
- * The default callback for AVCodecContext.get_buffer2(). It is made public so
- * it can be called by custom get_buffer2() implementations for decoders without
- * AV_CODEC_CAP_DR1 set.
- */
-int avcodec_default_get_buffer2(AVCodecContext *s, AVFrame *frame, int flags);
-
-#if FF_API_EMU_EDGE
-/**
- * Return the amount of padding in pixels which the get_buffer callback must
- * provide around the edge of the image for codecs which do not have the
- * CODEC_FLAG_EMU_EDGE flag.
- *
- * @return Required padding in pixels.
- *
- * @deprecated CODEC_FLAG_EMU_EDGE is deprecated, so this function is no longer
- * needed
- */
-attribute_deprecated
-unsigned avcodec_get_edge_width(void);
-#endif
-
-/**
- * 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
- * padding.
- *
- * May only be used if a codec with AV_CODEC_CAP_DR1 has been opened.
- */
-void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height);
-
-/**
- * Modify width and height values so that they will result in a memory
- * buffer that is acceptable for the codec if you also ensure that all
- * line sizes are a multiple of the respective linesize_align[i].
- *
- * May only be used if a codec with AV_CODEC_CAP_DR1 has been opened.
- */
-void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
- int linesize_align[AV_NUM_DATA_POINTERS]);
-
-/**
- * Converts AVChromaLocation to swscale x/y chroma position.
- *
- * The positions represent the chroma (0,0) position in a coordinates system
- * with luma (0,0) representing the origin and luma(1,1) representing 256,256
- *
- * @param xpos horizontal chroma sample position
- * @param ypos vertical chroma sample position
- */
-int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos);
-
-/**
- * Converts swscale x/y chroma position to AVChromaLocation.
- *
- * The positions represent the chroma (0,0) position in a coordinates system
- * with luma (0,0) representing the origin and luma(1,1) representing 256,256
- *
- * @param xpos horizontal chroma sample position
- * @param ypos vertical chroma sample position
- */
-enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos);
-
-#if FF_API_OLD_DECODE_AUDIO
-/**
- * Wrapper function which calls avcodec_decode_audio4.
- *
- * @deprecated Use avcodec_decode_audio4 instead.
- *
- * Decode the audio frame of size avpkt->size from avpkt->data into samples.
- * Some decoders may support multiple frames in a single AVPacket, such
- * decoders would then just decode the first frame. In this case,
- * avcodec_decode_audio3 has to be called again with an AVPacket that contains
- * the remaining data in order to decode the second frame etc.
- * If no frame
- * could be outputted, frame_size_ptr is zero. Otherwise, it is the
- * decompressed frame size in bytes.
- *
- * @warning You must set frame_size_ptr to the allocated size of the
- * output buffer before calling avcodec_decode_audio3().
- *
- * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than
- * the actual read bytes because some optimized bitstream readers read 32 or 64
- * bits at once and could read over the end.
- *
- * @warning The end of the input buffer avpkt->data should be set to 0 to ensure that
- * no overreading happens for damaged MPEG streams.
- *
- * @warning You must not provide a custom get_buffer() when using
- * avcodec_decode_audio3(). Doing so will override it with
- * avcodec_default_get_buffer. Use avcodec_decode_audio4() instead,
- * which does allow the application to provide a custom get_buffer().
- *
- * @note You might have to align the input buffer avpkt->data and output buffer
- * samples. The alignment requirements depend on the CPU: On some CPUs it isn't
- * necessary at all, on others it won't work at all if not aligned and on others
- * it will work but it will have an impact on performance.
- *
- * In practice, avpkt->data should have 4 byte alignment at minimum and
- * samples should be 16 byte aligned unless the CPU doesn't need it
- * (AltiVec and SSE do).
- *
- * @note Codecs which have the CODEC_CAP_DELAY capability set have a delay
- * between input and output, these need to be fed with avpkt->data=NULL,
- * avpkt->size=0 at the end to return the remaining frames.
- *
- * @param avctx the codec context
- * @param[out] samples the output buffer, sample type in avctx->sample_fmt
- * If the sample format is planar, each channel plane will
- * be the same size, with no padding between channels.
- * @param[in,out] frame_size_ptr the output buffer size in bytes
- * @param[in] avpkt The input AVPacket containing the input buffer.
- * You can create such packet with av_init_packet() and by then setting
- * data and size, some decoders might in addition need other fields.
- * All decoders are designed to use the least fields possible though.
- * @return On error a negative value is returned, otherwise the number of bytes
- * used or zero if no frame data was decompressed (used) from the input AVPacket.
- */
-attribute_deprecated int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
- int *frame_size_ptr,
- AVPacket *avpkt);
-#endif
-
-/**
- * Decode the audio frame of size avpkt->size from avpkt->data into frame.
- *
- * Some decoders may support multiple frames in a single AVPacket. Such
- * decoders would then just decode the first frame and the return value would be
- * less than the packet size. In this case, avcodec_decode_audio4 has to be
- * called again with an AVPacket containing the remaining data in order to
- * decode the second frame, etc... Even if no frames are returned, the packet
- * needs to be fed to the decoder with remaining data until it is completely
- * consumed or an error occurs.
- *
- * Some decoders (those marked with AV_CODEC_CAP_DELAY) have a delay between input
- * and output. This means that for some packets they will not immediately
- * produce decoded output and need to be flushed at the end of decoding to get
- * all the decoded data. Flushing is done by calling this function with packets
- * with avpkt->data set to NULL and avpkt->size set to 0 until it stops
- * returning samples. It is safe to flush even those decoders that are not
- * marked with AV_CODEC_CAP_DELAY, then no samples will be returned.
- *
- * @warning The input buffer, avpkt->data must be AV_INPUT_BUFFER_PADDING_SIZE
- * larger than the actual read bytes because some optimized bitstream
- * readers read 32 or 64 bits at once and could read over the end.
- *
- * @note The AVCodecContext MUST have been opened with @ref avcodec_open2()
- * before packets may be fed to the decoder.
- *
- * @param avctx the codec context
- * @param[out] frame The AVFrame in which to store decoded audio samples.
- * The decoder will allocate a buffer for the decoded frame by
- * calling the AVCodecContext.get_buffer2() callback.
- * When AVCodecContext.refcounted_frames is set to 1, the frame is
- * reference counted and the returned reference belongs to the
- * caller. The caller must release the frame using av_frame_unref()
- * when the frame is no longer needed. The caller may safely write
- * to the frame if av_frame_is_writable() returns 1.
- * When AVCodecContext.refcounted_frames is set to 0, the returned
- * reference belongs to the decoder and is valid only until the
- * next call to this function or until closing or flushing the
- * decoder. The caller may not write to it.
- * @param[out] got_frame_ptr Zero if no frame could be decoded, otherwise it is
- * non-zero. Note that this field being set to zero
- * does not mean that an error has occurred. For
- * decoders with AV_CODEC_CAP_DELAY set, no given decode
- * call is guaranteed to produce a frame.
- * @param[in] avpkt The input AVPacket containing the input buffer.
- * At least avpkt->data and avpkt->size should be set. Some
- * decoders might also require additional fields to be set.
- * @return A negative error code is returned if an error occurred during
- * decoding, otherwise the number of bytes consumed from the input
- * AVPacket is returned.
- */
-int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame,
- int *got_frame_ptr, const AVPacket *avpkt);
-
-/**
- * Decode the video frame of size avpkt->size from avpkt->data into picture.
- * Some decoders may support multiple frames in a single AVPacket, such
- * decoders would then just decode the first frame.
- *
- * @warning The input buffer must be AV_INPUT_BUFFER_PADDING_SIZE larger than
- * the actual read bytes because some optimized bitstream readers read 32 or 64
- * bits at once and could read over the end.
- *
- * @warning The end of the input buffer buf should be set to 0 to ensure that
- * no overreading happens for damaged MPEG streams.
- *
- * @note Codecs which have the AV_CODEC_CAP_DELAY capability set have a delay
- * between input and output, these need to be fed with avpkt->data=NULL,
- * avpkt->size=0 at the end to return the remaining frames.
- *
- * @note The AVCodecContext MUST have been opened with @ref avcodec_open2()
- * before packets may be fed to the decoder.
- *
- * @param avctx the codec context
- * @param[out] picture The AVFrame in which the decoded video frame will be stored.
- * Use av_frame_alloc() to get an AVFrame. The codec will
- * allocate memory for the actual bitmap by calling the
- * AVCodecContext.get_buffer2() callback.
- * When AVCodecContext.refcounted_frames is set to 1, the frame is
- * reference counted and the returned reference belongs to the
- * caller. The caller must release the frame using av_frame_unref()
- * when the frame is no longer needed. The caller may safely write
- * to the frame if av_frame_is_writable() returns 1.
- * When AVCodecContext.refcounted_frames is set to 0, the returned
- * reference belongs to the decoder and is valid only until the
- * next call to this function or until closing or flushing the
- * decoder. The caller may not write to it.
- *
- * @param[in] avpkt The input AVPacket containing the input buffer.
- * You can create such packet with av_init_packet() and by then setting
- * data and size, some decoders might in addition need other fields like
- * flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least
- * fields possible.
- * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero.
- * @return On error a negative value is returned, otherwise the number of bytes
- * used or zero if no frame could be decompressed.
- */
-int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
- int *got_picture_ptr,
- const AVPacket *avpkt);
-
-/**
- * Decode a subtitle message.
- * Return a negative value on error, otherwise return the number of bytes used.
- * If no subtitle could be decompressed, got_sub_ptr is zero.
- * Otherwise, the subtitle is stored in *sub.
- * Note that AV_CODEC_CAP_DR1 is not available for subtitle codecs. This is for
- * simplicity, because the performance difference is expect to be negligible
- * and reusing a get_buffer written for video codecs would probably perform badly
- * due to a potentially very different allocation pattern.
- *
- * Some decoders (those marked with CODEC_CAP_DELAY) have a delay between input
- * and output. This means that for some packets they will not immediately
- * produce decoded output and need to be flushed at the end of decoding to get
- * all the decoded data. Flushing is done by calling this function with packets
- * with avpkt->data set to NULL and avpkt->size set to 0 until it stops
- * returning subtitles. It is safe to flush even those decoders that are not
- * marked with CODEC_CAP_DELAY, then no subtitles will be returned.
- *
- * @note The AVCodecContext MUST have been opened with @ref avcodec_open2()
- * before packets may be fed to the decoder.
- *
- * @param avctx the codec context
- * @param[out] sub The Preallocated AVSubtitle in which the decoded subtitle will be stored,
- * must be freed with avsubtitle_free if *got_sub_ptr is set.
- * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, otherwise, it is nonzero.
- * @param[in] avpkt The input AVPacket containing the input buffer.
- */
-int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
- int *got_sub_ptr,
- AVPacket *avpkt);
-
-/**
- * @defgroup lavc_parsing Frame parsing
- * @{
- */
-
-enum AVPictureStructure {
- AV_PICTURE_STRUCTURE_UNKNOWN, //< unknown
- AV_PICTURE_STRUCTURE_TOP_FIELD, //< coded as top field
- AV_PICTURE_STRUCTURE_BOTTOM_FIELD, //< coded as bottom field
- AV_PICTURE_STRUCTURE_FRAME, //< coded as frame
-};
-
-typedef struct AVCodecParserContext {
- void *priv_data;
- struct AVCodecParser *parser;
- int64_t frame_offset; /* offset of the current frame */
- int64_t cur_offset; /* current offset
- (incremented by each av_parser_parse()) */
- int64_t next_frame_offset; /* offset of the next frame */
- /* video info */
- int pict_type; /* XXX: Put it back in AVCodecContext. */
- /**
- * This field is used for proper frame duration computation in lavf.
- * It signals, how much longer the frame duration of the current frame
- * is compared to normal frame duration.
- *
- * frame_duration = (1 + repeat_pict) * time_base
- *
- * It is used by codecs like H.264 to display telecined material.
- */
- int repeat_pict; /* XXX: Put it back in AVCodecContext. */
- int64_t pts; /* pts of the current frame */
- int64_t dts; /* dts of the current frame */
-
- /* private data */
- int64_t last_pts;
- int64_t last_dts;
- int fetch_timestamp;
-
-#define AV_PARSER_PTS_NB 4
- int cur_frame_start_index;
- int64_t cur_frame_offset[AV_PARSER_PTS_NB];
- int64_t cur_frame_pts[AV_PARSER_PTS_NB];
- int64_t cur_frame_dts[AV_PARSER_PTS_NB];
-
- int flags;
-#define PARSER_FLAG_COMPLETE_FRAMES 0x0001
-#define PARSER_FLAG_ONCE 0x0002
-/// Set if the parser has a valid file offset
-#define PARSER_FLAG_FETCHED_OFFSET 0x0004
-#define PARSER_FLAG_USE_CODEC_TS 0x1000
-
- int64_t offset; ///< byte offset from starting packet start
- int64_t cur_frame_end[AV_PARSER_PTS_NB];
-
- /**
- * Set by parser to 1 for key frames and 0 for non-key frames.
- * It is initialized to -1, so if the parser doesn't set this flag,
- * old-style fallback using AV_PICTURE_TYPE_I picture type as key frames
- * will be used.
- */
- int key_frame;
-
- /**
- * Time difference in stream time base units from the pts of this
- * packet to the point at which the output from the decoder has converged
- * independent from the availability of previous frames. That is, the
- * frames are virtually identical no matter if decoding started from
- * the very first frame or from this keyframe.
- * Is AV_NOPTS_VALUE if unknown.
- * This field is not the display duration of the current frame.
- * This field has no meaning if the packet does not have AV_PKT_FLAG_KEY
- * set.
- *
- * The purpose of this field is to allow seeking in streams that have no
- * keyframes in the conventional sense. It corresponds to the
- * recovery point SEI in H.264 and match_time_delta in NUT. It is also
- * essential for some types of subtitle streams to ensure that all
- * subtitles are correctly displayed after seeking.
- */
- int64_t convergence_duration;
-
- // Timestamp generation support:
- /**
- * Synchronization point for start of timestamp generation.
- *
- * Set to >0 for sync point, 0 for no sync point and <0 for undefined
- * (default).
- *
- * For example, this corresponds to presence of H.264 buffering period
- * SEI message.
- */
- int dts_sync_point;
-
- /**
- * Offset of the current timestamp against last timestamp sync point in
- * units of AVCodecContext.time_base.
- *
- * Set to INT_MIN when dts_sync_point unused. Otherwise, it must
- * contain a valid timestamp offset.
- *
- * Note that the timestamp of sync point has usually a nonzero
- * dts_ref_dts_delta, which refers to the previous sync point. Offset of
- * the next frame after timestamp sync point will be usually 1.
- *
- * For example, this corresponds to H.264 cpb_removal_delay.
- */
- int dts_ref_dts_delta;
-
- /**
- * Presentation delay of current frame in units of AVCodecContext.time_base.
- *
- * Set to INT_MIN when dts_sync_point unused. Otherwise, it must
- * contain valid non-negative timestamp delta (presentation time of a frame
- * must not lie in the past).
- *
- * This delay represents the difference between decoding and presentation
- * time of the frame.
- *
- * For example, this corresponds to H.264 dpb_output_delay.
- */
- int pts_dts_delta;
-
- /**
- * Position of the packet in file.
- *
- * Analogous to cur_frame_pts/dts
- */
- int64_t cur_frame_pos[AV_PARSER_PTS_NB];
-
- /**
- * Byte position of currently parsed frame in stream.
- */
- int64_t pos;
-
- /**
- * Previous frame byte position.
- */
- int64_t last_pos;
-
- /**
- * Duration of the current frame.
- * For audio, this is in units of 1 / AVCodecContext.sample_rate.
- * For all other types, this is in units of AVCodecContext.time_base.
- */
- int duration;
-
- enum AVFieldOrder field_order;
-
- /**
- * Indicate whether a picture is coded as a frame, top field or bottom field.
- *
- * For example, H.264 field_pic_flag equal to 0 corresponds to
- * AV_PICTURE_STRUCTURE_FRAME. An H.264 picture with field_pic_flag
- * equal to 1 and bottom_field_flag equal to 0 corresponds to
- * AV_PICTURE_STRUCTURE_TOP_FIELD.
- */
- enum AVPictureStructure picture_structure;
-
- /**
- * Picture number incremented in presentation or output order.
- * This field may be reinitialized at the first picture of a new sequence.
- *
- * For example, this corresponds to H.264 PicOrderCnt.
- */
- int output_picture_number;
-
- /**
- * Dimensions of the decoded video intended for presentation.
- */
- int width;
- int height;
-
- /**
- * Dimensions of the coded video.
- */
- int coded_width;
- int coded_height;
-
- /**
- * The format of the coded data, corresponds to enum AVPixelFormat for video
- * and for enum AVSampleFormat for audio.
- *
- * Note that a decoder can have considerable freedom in how exactly it
- * decodes the data, so the format reported here might be different from the
- * one returned by a decoder.
- */
- int format;
-} AVCodecParserContext;
-
-typedef struct AVCodecParser {
- int codec_ids[5]; /* several codec IDs are permitted */
- int priv_data_size;
- int (*parser_init)(AVCodecParserContext *s);
- /* This callback never returns an error, a negative value means that
- * the frame start was in a previous packet. */
- int (*parser_parse)(AVCodecParserContext *s,
- AVCodecContext *avctx,
- const uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *buf, int buf_size);
- void (*parser_close)(AVCodecParserContext *s);
- int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size);
- struct AVCodecParser *next;
-} AVCodecParser;
-
-AVCodecParser *av_parser_next(const AVCodecParser *c);
-
-void av_register_codec_parser(AVCodecParser *parser);
-AVCodecParserContext *av_parser_init(int codec_id);
-
-/**
- * Parse a packet.
- *
- * @param s parser context.
- * @param avctx codec context.
- * @param poutbuf set to pointer to parsed buffer or NULL if not yet finished.
- * @param poutbuf_size set to size of parsed buffer or zero if not yet finished.
- * @param buf input buffer.
- * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output).
- * @param pts input presentation timestamp.
- * @param dts input decoding timestamp.
- * @param pos input byte position in stream.
- * @return the number of bytes of the input bitstream used.
- *
- * Example:
- * @code
- * while(in_len){
- * len = av_parser_parse2(myparser, AVCodecContext, &data, &size,
- * in_data, in_len,
- * pts, dts, pos);
- * in_data += len;
- * in_len -= len;
- *
- * if(size)
- * decode_frame(data, size);
- * }
- * @endcode
- */
-int av_parser_parse2(AVCodecParserContext *s,
- AVCodecContext *avctx,
- uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *buf, int buf_size,
- int64_t pts, int64_t dts,
- int64_t pos);
-
-/**
- * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed
- * @deprecated use AVBitStreamFilter
- */
-int av_parser_change(AVCodecParserContext *s,
- AVCodecContext *avctx,
- uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *buf, int buf_size, int keyframe);
-void av_parser_close(AVCodecParserContext *s);
-
-/**
- * @}
- * @}
- */
-
-/**
- * @addtogroup lavc_encoding
- * @{
- */
-
-/**
- * Find a registered encoder with a matching codec ID.
- *
- * @param id AVCodecID of the requested encoder
- * @return An encoder if one was found, NULL otherwise.
- */
-AVCodec *avcodec_find_encoder(enum AVCodecID id);
-
-/**
- * Find a registered encoder with the specified name.
- *
- * @param name name of the requested encoder
- * @return An encoder if one was found, NULL otherwise.
- */
-AVCodec *avcodec_find_encoder_by_name(const char *name);
-
-#if FF_API_OLD_ENCODE_AUDIO
-/**
- * Encode an audio frame from samples into buf.
- *
- * @deprecated Use avcodec_encode_audio2 instead.
- *
- * @note The output buffer should be at least FF_MIN_BUFFER_SIZE bytes large.
- * However, for codecs with avctx->frame_size equal to 0 (e.g. PCM) the user
- * will know how much space is needed because it depends on the value passed
- * in buf_size as described below. In that case a lower value can be used.
- *
- * @param avctx the codec context
- * @param[out] buf the output buffer
- * @param[in] buf_size the output buffer size
- * @param[in] samples the input buffer containing the samples
- * The number of samples read from this buffer is frame_size*channels,
- * both of which are defined in avctx.
- * For codecs which have avctx->frame_size equal to 0 (e.g. PCM) the number of
- * samples read from samples is equal to:
- * buf_size * 8 / (avctx->channels * av_get_bits_per_sample(avctx->codec_id))
- * This also implies that av_get_bits_per_sample() must not return 0 for these
- * codecs.
- * @return On error a negative value is returned, on success zero or the number
- * of bytes used to encode the data read from the input buffer.
- */
-int attribute_deprecated avcodec_encode_audio(AVCodecContext *avctx,
- uint8_t *buf, int buf_size,
- const short *samples);
-#endif
-
-/**
- * Encode a frame of audio.
- *
- * Takes input samples from frame and writes the next output packet, if
- * available, to avpkt. The output packet does not necessarily contain data for
- * the most recent frame, as encoders can delay, split, and combine input frames
- * internally as needed.
- *
- * @param avctx codec context
- * @param avpkt output AVPacket.
- * The user can supply an output buffer by setting
- * avpkt->data and avpkt->size prior to calling the
- * function, but if the size of the user-provided data is not
- * large enough, encoding will fail. If avpkt->data and
- * avpkt->size are set, avpkt->destruct must also be set. All
- * other AVPacket fields will be reset by the encoder using
- * av_init_packet(). If avpkt->data is NULL, the encoder will
- * allocate it. The encoder will set avpkt->size to the size
- * of the output packet.
- *
- * If this function fails or produces no output, avpkt will be
- * freed using av_free_packet() (i.e. avpkt->destruct will be
- * called to free the user supplied buffer).
- * @param[in] frame AVFrame containing the raw audio data to be encoded.
- * May be NULL when flushing an encoder that has the
- * AV_CODEC_CAP_DELAY capability set.
- * If AV_CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame
- * can have any number of samples.
- * If it is not set, frame->nb_samples must be equal to
- * avctx->frame_size for all frames except the last.
- * The final frame may be smaller than avctx->frame_size.
- * @param[out] got_packet_ptr This field is set to 1 by libavcodec if the
- * output packet is non-empty, and to 0 if it is
- * empty. If the function returns an error, the
- * packet can be assumed to be invalid, and the
- * value of got_packet_ptr is undefined and should
- * not be used.
- * @return 0 on success, negative error code on failure
- */
-int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt,
- const AVFrame *frame, int *got_packet_ptr);
-
-#if FF_API_OLD_ENCODE_VIDEO
-/**
- * @deprecated use avcodec_encode_video2() instead.
- *
- * Encode a video frame from pict into buf.
- * The input picture should be
- * stored using a specific format, namely avctx.pix_fmt.
- *
- * @param avctx the codec context
- * @param[out] buf the output buffer for the bitstream of encoded frame
- * @param[in] buf_size the size of the output buffer in bytes
- * @param[in] pict the input picture to encode
- * @return On error a negative value is returned, on success zero or the number
- * of bytes used from the output buffer.
- */
-attribute_deprecated
-int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size,
- const AVFrame *pict);
-#endif
-
-/**
- * Encode a frame of video.
- *
- * Takes input raw video data from frame and writes the next output packet, if
- * available, to avpkt. The output packet does not necessarily contain data for
- * the most recent frame, as encoders can delay and reorder input frames
- * internally as needed.
- *
- * @param avctx codec context
- * @param avpkt output AVPacket.
- * The user can supply an output buffer by setting
- * avpkt->data and avpkt->size prior to calling the
- * function, but if the size of the user-provided data is not
- * large enough, encoding will fail. All other AVPacket fields
- * will be reset by the encoder using av_init_packet(). If
- * avpkt->data is NULL, the encoder will allocate it.
- * The encoder will set avpkt->size to the size of the
- * output packet. The returned data (if any) belongs to the
- * caller, he is responsible for freeing it.
- *
- * If this function fails or produces no output, avpkt will be
- * freed using av_free_packet() (i.e. avpkt->destruct will be
- * called to free the user supplied buffer).
- * @param[in] frame AVFrame containing the raw video data to be encoded.
- * May be NULL when flushing an encoder that has the
- * AV_CODEC_CAP_DELAY capability set.
- * @param[out] got_packet_ptr This field is set to 1 by libavcodec if the
- * output packet is non-empty, and to 0 if it is
- * empty. If the function returns an error, the
- * packet can be assumed to be invalid, and the
- * value of got_packet_ptr is undefined and should
- * not be used.
- * @return 0 on success, negative error code on failure
- */
-int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt,
- const AVFrame *frame, int *got_packet_ptr);
-
-int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
- const AVSubtitle *sub);
-
-
-/**
- * @}
- */
-
-#if FF_API_AVCODEC_RESAMPLE
-/**
- * @defgroup lavc_resample Audio resampling
- * @ingroup libavc
- * @deprecated use libswresample instead
- *
- * @{
- */
-struct ReSampleContext;
-struct AVResampleContext;
-
-typedef struct ReSampleContext ReSampleContext;
-
-/**
- * Initialize audio resampling context.
- *
- * @param output_channels number of output channels
- * @param input_channels number of input channels
- * @param output_rate output sample rate
- * @param input_rate input sample rate
- * @param sample_fmt_out requested output sample format
- * @param sample_fmt_in input sample format
- * @param filter_length length of each FIR filter in the filterbank relative to the cutoff frequency
- * @param log2_phase_count log2 of the number of entries in the polyphase filterbank
- * @param linear if 1 then the used FIR filter will be linearly interpolated
- between the 2 closest, if 0 the closest will be used
- * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate
- * @return allocated ReSampleContext, NULL if error occurred
- */
-attribute_deprecated
-ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
- int output_rate, int input_rate,
- enum AVSampleFormat sample_fmt_out,
- enum AVSampleFormat sample_fmt_in,
- int filter_length, int log2_phase_count,
- int linear, double cutoff);
-
-attribute_deprecated
-int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples);
-
-/**
- * Free resample context.
- *
- * @param s a non-NULL pointer to a resample context previously
- * created with av_audio_resample_init()
- */
-attribute_deprecated
-void audio_resample_close(ReSampleContext *s);
-
-
-/**
- * Initialize an audio resampler.
- * Note, if either rate is not an integer then simply scale both rates up so they are.
- * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq
- * @param log2_phase_count log2 of the number of entries in the polyphase filterbank
- * @param linear If 1 then the used FIR filter will be linearly interpolated
- between the 2 closest, if 0 the closest will be used
- * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate
- */
-attribute_deprecated
-struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff);
-
-/**
- * Resample an array of samples using a previously configured context.
- * @param src an array of unconsumed samples
- * @param consumed the number of samples of src which have been consumed are returned here
- * @param src_size the number of unconsumed samples available
- * @param dst_size the amount of space in samples available in dst
- * @param update_ctx If this is 0 then the context will not be modified, that way several channels can be resampled with the same context.
- * @return the number of samples written in dst or -1 if an error occurred
- */
-attribute_deprecated
-int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx);
-
-
-/**
- * Compensate samplerate/timestamp drift. The compensation is done by changing
- * the resampler parameters, so no audible clicks or similar distortions occur
- * @param compensation_distance distance in output samples over which the compensation should be performed
- * @param sample_delta number of output samples which should be output less
- *
- * example: av_resample_compensate(c, 10, 500)
- * here instead of 510 samples only 500 samples would be output
- *
- * note, due to rounding the actual compensation might be slightly different,
- * especially if the compensation_distance is large and the in_rate used during init is small
- */
-attribute_deprecated
-void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance);
-attribute_deprecated
-void av_resample_close(struct AVResampleContext *c);
-
-/**
- * @}
- */
-#endif
-
-/**
- * @addtogroup lavc_picture
- * @{
- */
-
-/**
- * Allocate memory for the pixels of a picture and setup the AVPicture
- * fields for it.
- *
- * Call avpicture_free() to free it.
- *
- * @param picture the picture structure to be filled in
- * @param pix_fmt the pixel format of the picture
- * @param width the width of the picture
- * @param height the height of the picture
- * @return zero if successful, a negative error code otherwise
- *
- * @see av_image_alloc(), avpicture_fill()
- */
-int avpicture_alloc(AVPicture *picture, enum AVPixelFormat pix_fmt, int width, int height);
-
-/**
- * Free a picture previously allocated by avpicture_alloc().
- * The data buffer used by the AVPicture is freed, but the AVPicture structure
- * itself is not.
- *
- * @param picture the AVPicture to be freed
- */
-void avpicture_free(AVPicture *picture);
-
-/**
- * Setup the picture fields based on the specified image parameters
- * and the provided image data buffer.
- *
- * The picture fields are filled in by using the image data buffer
- * pointed to by ptr.
- *
- * If ptr is NULL, the function will fill only the picture linesize
- * array and return the required size for the image buffer.
- *
- * To allocate an image buffer and fill the picture data in one call,
- * use avpicture_alloc().
- *
- * @param picture the picture to be filled in
- * @param ptr buffer where the image data is stored, or NULL
- * @param pix_fmt the pixel format of the image
- * @param width the width of the image in pixels
- * @param height the height of the image in pixels
- * @return the size in bytes required for src, a negative error code
- * in case of failure
- *
- * @see av_image_fill_arrays()
- */
-int avpicture_fill(AVPicture *picture, const uint8_t *ptr,
- enum AVPixelFormat pix_fmt, int width, int height);
-
-/**
- * Copy pixel data from an AVPicture into a buffer.
- *
- * avpicture_get_size() can be used to compute the required size for
- * the buffer to fill.
- *
- * @param src source picture with filled data
- * @param pix_fmt picture pixel format
- * @param width picture width
- * @param height picture height
- * @param dest destination buffer
- * @param dest_size destination buffer size in bytes
- * @return the number of bytes written to dest, or a negative value
- * (error code) on error, for example if the destination buffer is not
- * big enough
- *
- * @see av_image_copy_to_buffer()
- */
-int avpicture_layout(const AVPicture *src, enum AVPixelFormat pix_fmt,
- int width, int height,
- unsigned char *dest, int dest_size);
-
-/**
- * Calculate the size in bytes that a picture of the given width and height
- * would occupy if stored in the given picture format.
- *
- * @param pix_fmt picture pixel format
- * @param width picture width
- * @param height picture height
- * @return the computed picture buffer size or a negative error code
- * in case of error
- *
- * @see av_image_get_buffer_size().
- */
-int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height);
-
-#if FF_API_DEINTERLACE
-/**
- * deinterlace - if not supported return -1
- *
- * @deprecated - use yadif (in libavfilter) instead
- */
-attribute_deprecated
-int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
- enum AVPixelFormat pix_fmt, int width, int height);
-#endif
-/**
- * Copy image src to dst. Wraps av_image_copy().
- */
-void av_picture_copy(AVPicture *dst, const AVPicture *src,
- enum AVPixelFormat pix_fmt, int width, int height);
-
-/**
- * Crop image top and left side.
- */
-int av_picture_crop(AVPicture *dst, const AVPicture *src,
- enum AVPixelFormat pix_fmt, int top_band, int left_band);
-
-/**
- * Pad image.
- */
-int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, enum AVPixelFormat pix_fmt,
- int padtop, int padbottom, int padleft, int padright, int *color);
-
-/**
- * @}
- */
-
-/**
- * @defgroup lavc_misc Utility functions
- * @ingroup libavc
- *
- * Miscellaneous utility functions related to both encoding and decoding
- * (or neither).
- * @{
- */
-
-/**
- * @defgroup lavc_misc_pixfmt Pixel formats
- *
- * Functions for working with pixel formats.
- * @{
- */
-
-/**
- * Utility function to access log2_chroma_w log2_chroma_h from
- * the pixel format AVPixFmtDescriptor.
- *
- * This function asserts that pix_fmt is valid. See av_pix_fmt_get_chroma_sub_sample
- * for one that returns a failure code and continues in case of invalid
- * pix_fmts.
- *
- * @param[in] pix_fmt the pixel format
- * @param[out] h_shift store log2_chroma_w
- * @param[out] v_shift store log2_chroma_h
- *
- * @see av_pix_fmt_get_chroma_sub_sample
- */
-
-void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift);
-
-/**
- * Return a value representing the fourCC code associated to the
- * pixel format pix_fmt, or 0 if no associated fourCC code can be
- * found.
- */
-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
- * may occur. For example, when converting from RGB24 to GRAY, the color
- * information will be lost. Similarly, other losses occur when converting from
- * some formats to other formats. avcodec_find_best_pix_fmt_of_2() searches which of
- * the given pixel formats should be used to suffer the least amount of loss.
- * The pixel formats from which it chooses one, are determined by the
- * pix_fmt_list parameter.
- *
- *
- * @param[in] pix_fmt_list AV_PIX_FMT_NONE terminated array of pixel formats to choose from
- * @param[in] src_pix_fmt source pixel format
- * @param[in] has_alpha Whether the source pixel format alpha channel is used.
- * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur.
- * @return The best pixel format to convert to or -1 if none was found.
- */
-enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *pix_fmt_list,
- enum AVPixelFormat src_pix_fmt,
- int has_alpha, int *loss_ptr);
-
-/**
- * @deprecated see av_find_best_pix_fmt_of_2()
- */
-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
-#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI
-enum AVPixelFormat avcodec_find_best_pix_fmt2(const enum AVPixelFormat *pix_fmt_list,
- enum AVPixelFormat src_pix_fmt,
- int has_alpha, int *loss_ptr);
-#else
-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);
-
-/**
- * @}
- */
-
-#if FF_API_SET_DIMENSIONS
-/**
- * @deprecated this function is not supposed to be used from outside of lavc
- */
-attribute_deprecated
-void avcodec_set_dimensions(AVCodecContext *s, int width, int height);
-#endif
-
-/**
- * Put a string representing the codec tag codec_tag in buf.
- *
- * @param buf buffer to place codec tag in
- * @param buf_size size in bytes of buf
- * @param codec_tag codec tag to assign
- * @return the length of the string that would have been generated if
- * enough space had been available, excluding the trailing null
- */
-size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag);
-
-void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode);
-
-/**
- * Return a name for the specified profile, if available.
- *
- * @param codec the codec that is searched for the given profile
- * @param profile the profile value for which a name is requested
- * @return A name for the profile if found, NULL otherwise.
- */
-const char *av_get_profile_name(const AVCodec *codec, int profile);
-
-int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size);
-int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count);
-//FIXME func typedef
-
-/**
- * Fill AVFrame audio data and linesize pointers.
- *
- * The buffer buf must be a preallocated buffer with a size big enough
- * to contain the specified samples amount. The filled AVFrame data
- * pointers will point to this buffer.
- *
- * AVFrame extended_data channel pointers are allocated if necessary for
- * planar audio.
- *
- * @param frame the AVFrame
- * frame->nb_samples must be set prior to calling the
- * function. This function fills in frame->data,
- * frame->extended_data, frame->linesize[0].
- * @param nb_channels channel count
- * @param sample_fmt sample format
- * @param buf buffer to use for frame data
- * @param buf_size size of buffer
- * @param align plane size sample alignment (0 = default)
- * @return >=0 on success, negative error code on failure
- * @todo return the size in bytes required to store the samples in
- * case of success, at the next libavutil bump
- */
-int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
- enum AVSampleFormat sample_fmt, const uint8_t *buf,
- int buf_size, int align);
-
-/**
- * Reset the internal decoder state / flush internal buffers. Should be called
- * e.g. when seeking or when switching to a different stream.
- *
- * @note when refcounted frames are not used (i.e. avctx->refcounted_frames is 0),
- * this invalidates the frames previously returned from the decoder. When
- * refcounted frames are used, the decoder just releases any references it might
- * keep internally, but the caller's reference remains valid.
- */
-void avcodec_flush_buffers(AVCodecContext *avctx);
-
-/**
- * Return codec bits per sample.
- *
- * @param[in] codec_id the codec
- * @return Number of bits per sample or zero if unknown for the given codec.
- */
-int av_get_bits_per_sample(enum AVCodecID codec_id);
-
-/**
- * Return the PCM codec associated with a sample format.
- * @param be endianness, 0 for little, 1 for big,
- * -1 (or anything else) for native
- * @return AV_CODEC_ID_PCM_* or AV_CODEC_ID_NONE
- */
-enum AVCodecID av_get_pcm_codec(enum AVSampleFormat fmt, int be);
-
-/**
- * Return codec bits per sample.
- * Only return non-zero if the bits per sample is exactly correct, not an
- * approximation.
- *
- * @param[in] codec_id the codec
- * @return Number of bits per sample or zero if unknown for the given codec.
- */
-int av_get_exact_bits_per_sample(enum AVCodecID codec_id);
-
-/**
- * Return audio frame duration.
- *
- * @param avctx codec context
- * @param frame_bytes size of the frame, or 0 if unknown
- * @return frame duration, in samples, if known. 0 if not able to
- * determine.
- */
-int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes);
-
-
-typedef struct AVBitStreamFilterContext {
- void *priv_data;
- struct AVBitStreamFilter *filter;
- AVCodecParserContext *parser;
- struct AVBitStreamFilterContext *next;
-} AVBitStreamFilterContext;
-
-
-typedef struct AVBitStreamFilter {
- const char *name;
- int priv_data_size;
- int (*filter)(AVBitStreamFilterContext *bsfc,
- AVCodecContext *avctx, const char *args,
- uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *buf, int buf_size, int keyframe);
- void (*close)(AVBitStreamFilterContext *bsfc);
- struct AVBitStreamFilter *next;
-} AVBitStreamFilter;
-
-/**
- * Register a bitstream filter.
- *
- * The filter will be accessible to the application code through
- * av_bitstream_filter_next() or can be directly initialized with
- * av_bitstream_filter_init().
- *
- * @see avcodec_register_all()
- */
-void av_register_bitstream_filter(AVBitStreamFilter *bsf);
-
-/**
- * Create and initialize a bitstream filter context given a bitstream
- * filter name.
- *
- * The returned context must be freed with av_bitstream_filter_close().
- *
- * @param name the name of the bitstream filter
- * @return a bitstream filter context if a matching filter was found
- * and successfully initialized, NULL otherwise
- */
-AVBitStreamFilterContext *av_bitstream_filter_init(const char *name);
-
-/**
- * Filter bitstream.
- *
- * This function filters the buffer buf with size buf_size, and places the
- * filtered buffer in the buffer pointed to by poutbuf.
- *
- * The output buffer must be freed by the caller.
- *
- * @param bsfc bitstream filter context created by av_bitstream_filter_init()
- * @param avctx AVCodecContext accessed by the filter, may be NULL.
- * If specified, this must point to the encoder context of the
- * output stream the packet is sent to.
- * @param args arguments which specify the filter configuration, may be NULL
- * @param poutbuf pointer which is updated to point to the filtered buffer
- * @param poutbuf_size pointer which is updated to the filtered buffer size in bytes
- * @param buf buffer containing the data to filter
- * @param buf_size size in bytes of buf
- * @param keyframe set to non-zero if the buffer to filter corresponds to a key-frame packet data
- * @return >= 0 in case of success, or a negative error code in case of failure
- *
- * If the return value is positive, an output buffer is allocated and
- * is available in *poutbuf, and is distinct from the input buffer.
- *
- * If the return value is 0, the output buffer is not allocated and
- * should be considered identical to the input buffer, or in case
- * *poutbuf was set it points to the input buffer (not necessarily to
- * its starting address).
- */
-int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
- AVCodecContext *avctx, const char *args,
- uint8_t **poutbuf, int *poutbuf_size,
- const uint8_t *buf, int buf_size, int keyframe);
-
-/**
- * Release bitstream filter context.
- *
- * @param bsf the bitstream filter context created with
- * av_bitstream_filter_init(), can be NULL
- */
-void av_bitstream_filter_close(AVBitStreamFilterContext *bsf);
-
-/**
- * If f is NULL, return the first registered bitstream filter,
- * if f is non-NULL, return the next registered bitstream filter
- * after f, or NULL if f is the last one.
- *
- * This function can be used to iterate over all registered bitstream
- * filters.
- */
-AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f);
-
-/* memory */
-
-/**
- * Same behaviour av_fast_malloc but the buffer has additional
- * AV_INPUT_BUFFER_PADDING_SIZE at the end which will always be 0.
- *
- * In addition the whole buffer will initially and after resizes
- * be 0-initialized so that no uninitialized data will ever appear.
- */
-void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size);
-
-/**
- * Same behaviour av_fast_padded_malloc except that buffer will always
- * be 0-initialized after call.
- */
-void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size);
-
-/**
- * Encode extradata length to a buffer. Used by xiph codecs.
- *
- * @param s buffer to write to; must be at least (v/255+1) bytes long
- * @param v size of extradata in bytes
- * @return number of bytes written to the buffer.
- */
-unsigned int av_xiphlacing(unsigned char *s, unsigned int v);
-
-#if FF_API_MISSING_SAMPLE
-/**
- * Log a generic warning message about a missing feature. This function is
- * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.)
- * only, and would normally not be used by applications.
- * @param[in] avc a pointer to an arbitrary struct of which the first field is
- * a pointer to an AVClass struct
- * @param[in] feature string containing the name of the missing feature
- * @param[in] want_sample indicates if samples are wanted which exhibit this feature.
- * If want_sample is non-zero, additional verbage will be added to the log
- * message which tells the user how to report samples to the development
- * mailing list.
- * @deprecated Use avpriv_report_missing_feature() instead.
- */
-attribute_deprecated
-void av_log_missing_feature(void *avc, const char *feature, int want_sample);
-
-/**
- * Log a generic warning message asking for a sample. This function is
- * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.)
- * only, and would normally not be used by applications.
- * @param[in] avc a pointer to an arbitrary struct of which the first field is
- * a pointer to an AVClass struct
- * @param[in] msg string containing an optional message, or NULL if no message
- * @deprecated Use avpriv_request_sample() instead.
- */
-attribute_deprecated
-void av_log_ask_for_sample(void *avc, const char *msg, ...) av_printf_format(2, 3);
-#endif /* FF_API_MISSING_SAMPLE */
-
-/**
- * Register the hardware accelerator hwaccel.
- */
-void av_register_hwaccel(AVHWAccel *hwaccel);
-
-/**
- * If hwaccel is NULL, returns the first registered hardware accelerator,
- * if hwaccel is non-NULL, returns the next registered hardware accelerator
- * after hwaccel, or NULL if hwaccel is the last one.
- */
-AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel);
-
-
-/**
- * Lock operation used by lockmgr
- */
-enum AVLockOp {
- AV_LOCK_CREATE, ///< Create a mutex
- AV_LOCK_OBTAIN, ///< Lock the mutex
- AV_LOCK_RELEASE, ///< Unlock the mutex
- AV_LOCK_DESTROY, ///< Free mutex resources
-};
-
-/**
- * Register a user provided lock manager supporting the operations
- * specified by AVLockOp. The "mutex" argument to the function points
- * to a (void *) where the lockmgr should store/get a pointer to a user
- * allocated mutex. It is NULL upon AV_LOCK_CREATE and equal to the
- * value left by the last call for all other ops. If the lock manager is
- * unable to perform the op then it should leave the mutex in the same
- * state as when it was called and return a non-zero value. However,
- * when called with AV_LOCK_DESTROY the mutex will always be assumed to
- * have been successfully destroyed. If av_lockmgr_register succeeds
- * it will return a non-negative value, if it fails it will return a
- * negative value and destroy all mutex and unregister all callbacks.
- * av_lockmgr_register is not thread-safe, it must be called from a
- * single thread before any calls which make use of locking are used.
- *
- * @param cb User defined callback. av_lockmgr_register invokes calls
- * to this callback and the previously registered callback.
- * The callback will be used to create more than one mutex
- * each of which must be backed by its own underlying locking
- * mechanism (i.e. do not use a single static object to
- * implement your lock manager). If cb is set to NULL the
- * lockmgr will be unregistered.
- */
-int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op));
-
-/**
- * Get the type of the given codec.
- */
-enum AVMediaType avcodec_get_type(enum AVCodecID codec_id);
-
-/**
- * Get the name of a codec.
- * @return a static string identifying the codec; never NULL
- */
-const char *avcodec_get_name(enum AVCodecID id);
-
-/**
- * @return a positive value if s is open (i.e. avcodec_open2() was called on it
- * with no corresponding avcodec_close()), 0 otherwise.
- */
-int avcodec_is_open(AVCodecContext *s);
-
-/**
- * @return a non-zero number if codec is an encoder, zero otherwise
- */
-int av_codec_is_encoder(const AVCodec *codec);
-
-/**
- * @return a non-zero number if codec is a decoder, zero otherwise
- */
-int av_codec_is_decoder(const AVCodec *codec);
-
-/**
- * @return descriptor for given codec ID or NULL if no descriptor exists.
- */
-const AVCodecDescriptor *avcodec_descriptor_get(enum AVCodecID id);
-
-/**
- * Iterate over all codec descriptors known to libavcodec.
- *
- * @param prev previous descriptor. NULL to get the first descriptor.
- *
- * @return next descriptor or NULL after the last descriptor
- */
-const AVCodecDescriptor *avcodec_descriptor_next(const AVCodecDescriptor *prev);
-
-/**
- * @return codec descriptor with the given name or NULL if no such descriptor
- * exists.
- */
-const AVCodecDescriptor *avcodec_descriptor_get_by_name(const char *name);
-
-/**
- * @}
- */
-
-#endif /* AVCODEC_AVCODEC_H */
diff --git a/ffmpeg-2-8-11/libavcodec/avpacket.c b/ffmpeg-2-8-11/libavcodec/avpacket.c
deleted file mode 100644
index bf168be..0000000
--- a/ffmpeg-2-8-11/libavcodec/avpacket.c
+++ /dev/null
@@ -1,635 +0,0 @@
-/*
- * AVPacket functions for libavcodec
- * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <string.h>
-
-#include "libavutil/avassert.h"
-#include "libavutil/common.h"
-#include "libavutil/internal.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/mem.h"
-#include "avcodec.h"
-#include "bytestream.h"
-#include "internal.h"
-
-#if FF_API_DESTRUCT_PACKET
-
-void av_destruct_packet(AVPacket *pkt)
-{
- av_freep(&pkt->data);
- pkt->size = 0;
-}
-
-/* a dummy destruct callback for the callers that assume AVPacket.destruct ==
- * NULL => static data */
-static void dummy_destruct_packet(AVPacket *pkt)
-{
- av_assert0(0);
-}
-#endif
-
-void av_init_packet(AVPacket *pkt)
-{
- pkt->pts = AV_NOPTS_VALUE;
- pkt->dts = AV_NOPTS_VALUE;
- pkt->pos = -1;
- pkt->duration = 0;
- pkt->convergence_duration = 0;
- pkt->flags = 0;
- pkt->stream_index = 0;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = NULL;
- pkt->priv = NULL;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- pkt->buf = NULL;
- pkt->side_data = NULL;
- pkt->side_data_elems = 0;
-}
-
-static int packet_alloc(AVBufferRef **buf, int size)
-{
- int ret;
- if ((unsigned)size >= (unsigned)size + AV_INPUT_BUFFER_PADDING_SIZE)
- return AVERROR(EINVAL);
-
- ret = av_buffer_realloc(buf, size + AV_INPUT_BUFFER_PADDING_SIZE);
- if (ret < 0)
- return ret;
-
- memset((*buf)->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
-
- return 0;
-}
-
-int av_new_packet(AVPacket *pkt, int size)
-{
- AVBufferRef *buf = NULL;
- int ret = packet_alloc(&buf, size);
- if (ret < 0)
- return ret;
-
- av_init_packet(pkt);
- pkt->buf = buf;
- pkt->data = buf->data;
- pkt->size = size;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = dummy_destruct_packet;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
- return 0;
-}
-
-void av_shrink_packet(AVPacket *pkt, int size)
-{
- if (pkt->size <= size)
- return;
- pkt->size = size;
- memset(pkt->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
-}
-
-int av_grow_packet(AVPacket *pkt, int grow_by)
-{
- int new_size;
- av_assert0((unsigned)pkt->size <= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE);
- if (!pkt->size)
- return av_new_packet(pkt, grow_by);
- if ((unsigned)grow_by >
- INT_MAX - (pkt->size + AV_INPUT_BUFFER_PADDING_SIZE))
- return -1;
-
- new_size = pkt->size + grow_by + AV_INPUT_BUFFER_PADDING_SIZE;
- if (pkt->buf) {
- int ret = av_buffer_realloc(&pkt->buf, new_size);
- if (ret < 0)
- return ret;
- } else {
- pkt->buf = av_buffer_alloc(new_size);
- if (!pkt->buf)
- return AVERROR(ENOMEM);
- memcpy(pkt->buf->data, pkt->data, FFMIN(pkt->size, pkt->size + grow_by));
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = dummy_destruct_packet;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- }
- pkt->data = pkt->buf->data;
- pkt->size += grow_by;
- memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
-
- return 0;
-}
-
-int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size)
-{
- if (size >= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
- return AVERROR(EINVAL);
-
- pkt->buf = av_buffer_create(data, size + AV_INPUT_BUFFER_PADDING_SIZE,
- av_buffer_default_free, NULL, 0);
- if (!pkt->buf)
- return AVERROR(ENOMEM);
-
- pkt->data = data;
- pkt->size = size;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = dummy_destruct_packet;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
- return 0;
-}
-
-#define ALLOC_MALLOC(data, size) data = av_malloc(size)
-#define ALLOC_BUF(data, size) \
-do { \
- av_buffer_realloc(&pkt->buf, size); \
- data = pkt->buf ? pkt->buf->data : NULL; \
-} while (0)
-
-#define DUP_DATA(dst, src, size, padding, ALLOC) \
- do { \
- void *data; \
- if (padding) { \
- if ((unsigned)(size) > \
- (unsigned)(size) + AV_INPUT_BUFFER_PADDING_SIZE) \
- goto failed_alloc; \
- ALLOC(data, size + AV_INPUT_BUFFER_PADDING_SIZE); \
- } else { \
- ALLOC(data, size); \
- } \
- if (!data) \
- goto failed_alloc; \
- memcpy(data, src, size); \
- if (padding) \
- memset((uint8_t *)data + size, 0, \
- AV_INPUT_BUFFER_PADDING_SIZE); \
- dst = data; \
- } while (0)
-
-/* Makes duplicates of data, side_data, but does not copy any other fields */
-static int copy_packet_data(AVPacket *pkt, const AVPacket *src, int dup)
-{
- pkt->data = NULL;
- pkt->side_data = NULL;
- pkt->side_data_elems = 0;
- if (pkt->buf) {
- AVBufferRef *ref = av_buffer_ref(src->buf);
- if (!ref)
- return AVERROR(ENOMEM);
- pkt->buf = ref;
- pkt->data = ref->data;
- } else {
- DUP_DATA(pkt->data, src->data, pkt->size, 1, ALLOC_BUF);
- }
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = dummy_destruct_packet;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- if (src->side_data_elems && dup) {
- pkt->side_data = src->side_data;
- pkt->side_data_elems = src->side_data_elems;
- }
- if (src->side_data_elems && !dup) {
- return av_copy_packet_side_data(pkt, src);
- }
- return 0;
-
-failed_alloc:
- av_free_packet(pkt);
- return AVERROR(ENOMEM);
-}
-
-int av_copy_packet_side_data(AVPacket *pkt, const AVPacket *src)
-{
- if (src->side_data_elems) {
- int i;
- DUP_DATA(pkt->side_data, src->side_data,
- src->side_data_elems * sizeof(*src->side_data), 0, ALLOC_MALLOC);
- if (src != pkt) {
- memset(pkt->side_data, 0,
- src->side_data_elems * sizeof(*src->side_data));
- }
- for (i = 0; i < src->side_data_elems; i++) {
- DUP_DATA(pkt->side_data[i].data, src->side_data[i].data,
- src->side_data[i].size, 1, ALLOC_MALLOC);
- pkt->side_data[i].size = src->side_data[i].size;
- pkt->side_data[i].type = src->side_data[i].type;
- }
- }
- pkt->side_data_elems = src->side_data_elems;
- return 0;
-
-failed_alloc:
- av_free_packet(pkt);
- return AVERROR(ENOMEM);
-}
-
-int av_dup_packet(AVPacket *pkt)
-{
- AVPacket tmp_pkt;
-
-FF_DISABLE_DEPRECATION_WARNINGS
- if (!pkt->buf && pkt->data
-#if FF_API_DESTRUCT_PACKET
- && !pkt->destruct
-#endif
- ) {
-FF_ENABLE_DEPRECATION_WARNINGS
- tmp_pkt = *pkt;
- return copy_packet_data(pkt, &tmp_pkt, 1);
- }
- return 0;
-}
-
-int av_copy_packet(AVPacket *dst, const AVPacket *src)
-{
- *dst = *src;
- return copy_packet_data(dst, src, 0);
-}
-
-void av_packet_free_side_data(AVPacket *pkt)
-{
- int i;
- for (i = 0; i < pkt->side_data_elems; i++)
- av_freep(&pkt->side_data[i].data);
- av_freep(&pkt->side_data);
- pkt->side_data_elems = 0;
-}
-
-void av_free_packet(AVPacket *pkt)
-{
- if (pkt) {
-FF_DISABLE_DEPRECATION_WARNINGS
- if (pkt->buf)
- av_buffer_unref(&pkt->buf);
-#if FF_API_DESTRUCT_PACKET
- else if (pkt->destruct)
- pkt->destruct(pkt);
- pkt->destruct = NULL;
-#endif
-FF_ENABLE_DEPRECATION_WARNINGS
- pkt->data = NULL;
- pkt->size = 0;
-
- av_packet_free_side_data(pkt);
- }
-}
-
-uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
- int size)
-{
- int elems = pkt->side_data_elems;
-
- if ((unsigned)elems + 1 > INT_MAX / sizeof(*pkt->side_data))
- return NULL;
- if ((unsigned)size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
- return NULL;
-
- pkt->side_data = av_realloc(pkt->side_data,
- (elems + 1) * sizeof(*pkt->side_data));
- if (!pkt->side_data)
- return NULL;
-
- pkt->side_data[elems].data = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!pkt->side_data[elems].data)
- return NULL;
- pkt->side_data[elems].size = size;
- pkt->side_data[elems].type = type;
- pkt->side_data_elems++;
-
- return pkt->side_data[elems].data;
-}
-
-uint8_t *av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
- int *size)
-{
- int i;
-
- for (i = 0; i < pkt->side_data_elems; i++) {
- if (pkt->side_data[i].type == type) {
- if (size)
- *size = pkt->side_data[i].size;
- return pkt->side_data[i].data;
- }
- }
- return NULL;
-}
-
-const char *av_packet_side_data_name(enum AVPacketSideDataType type)
-{
- switch(type) {
- case AV_PKT_DATA_PALETTE: return "Palette";
- case AV_PKT_DATA_NEW_EXTRADATA: return "New Extradata";
- case AV_PKT_DATA_PARAM_CHANGE: return "Param Change";
- case AV_PKT_DATA_H263_MB_INFO: return "H263 MB Info";
- case AV_PKT_DATA_REPLAYGAIN: return "Replay Gain";
- case AV_PKT_DATA_DISPLAYMATRIX: return "Display Matrix";
- case AV_PKT_DATA_STEREO3D: return "Stereo 3D";
- case AV_PKT_DATA_AUDIO_SERVICE_TYPE: return "Audio Service Type";
- case AV_PKT_DATA_SKIP_SAMPLES: return "Skip Samples";
- case AV_PKT_DATA_JP_DUALMONO: return "JP Dual Mono";
- case AV_PKT_DATA_STRINGS_METADATA: return "Strings Metadata";
- case AV_PKT_DATA_SUBTITLE_POSITION: return "Subtitle Position";
- case AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL: return "Matroska BlockAdditional";
- case AV_PKT_DATA_WEBVTT_IDENTIFIER: return "WebVTT ID";
- case AV_PKT_DATA_WEBVTT_SETTINGS: return "WebVTT Settings";
- case AV_PKT_DATA_METADATA_UPDATE: return "Metadata Update";
- }
- return NULL;
-}
-
-#define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL
-
-int av_packet_merge_side_data(AVPacket *pkt){
- if(pkt->side_data_elems){
- AVBufferRef *buf;
- int i;
- uint8_t *p;
- uint64_t size= pkt->size + 8LL + AV_INPUT_BUFFER_PADDING_SIZE;
- AVPacket old= *pkt;
- for (i=0; i<old.side_data_elems; i++) {
- size += old.side_data[i].size + 5LL;
- }
- if (size > INT_MAX)
- return AVERROR(EINVAL);
- buf = av_buffer_alloc(size);
- if (!buf)
- return AVERROR(ENOMEM);
- pkt->buf = buf;
- pkt->data = p = buf->data;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = dummy_destruct_packet;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- pkt->size = size - AV_INPUT_BUFFER_PADDING_SIZE;
- bytestream_put_buffer(&p, old.data, old.size);
- for (i=old.side_data_elems-1; i>=0; i--) {
- bytestream_put_buffer(&p, old.side_data[i].data, old.side_data[i].size);
- bytestream_put_be32(&p, old.side_data[i].size);
- *p++ = old.side_data[i].type | ((i==old.side_data_elems-1)*128);
- }
- bytestream_put_be64(&p, FF_MERGE_MARKER);
- av_assert0(p-pkt->data == pkt->size);
- memset(p, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- av_free_packet(&old);
- pkt->side_data_elems = 0;
- pkt->side_data = NULL;
- return 1;
- }
- return 0;
-}
-
-int av_packet_split_side_data(AVPacket *pkt){
- if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){
- int i;
- unsigned int size;
- uint8_t *p;
-
- p = pkt->data + pkt->size - 8 - 5;
- for (i=1; ; i++){
- size = AV_RB32(p);
- if (size>INT_MAX - 5 || p - pkt->data < size)
- return 0;
- if (p[4]&128)
- break;
- if (p - pkt->data < size + 5)
- return 0;
- p-= size+5;
- }
-
- pkt->side_data = av_malloc_array(i, sizeof(*pkt->side_data));
- if (!pkt->side_data)
- return AVERROR(ENOMEM);
-
- p= pkt->data + pkt->size - 8 - 5;
- for (i=0; ; i++){
- size= AV_RB32(p);
- av_assert0(size<=INT_MAX - 5 && p - pkt->data >= size);
- pkt->side_data[i].data = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
- pkt->side_data[i].size = size;
- pkt->side_data[i].type = p[4]&127;
- if (!pkt->side_data[i].data)
- return AVERROR(ENOMEM);
- memcpy(pkt->side_data[i].data, p-size, size);
- pkt->size -= size + 5;
- if(p[4]&128)
- break;
- p-= size+5;
- }
- pkt->size -= 8;
- pkt->side_data_elems = i+1;
- return 1;
- }
- return 0;
-}
-
-uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size)
-{
- AVDictionaryEntry *t = NULL;
- uint8_t *data = NULL;
- *size = 0;
-
- if (!dict)
- return NULL;
-
- while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) {
- const size_t keylen = strlen(t->key);
- const size_t valuelen = strlen(t->value);
- const size_t new_size = *size + keylen + 1 + valuelen + 1;
- uint8_t *const new_data = av_realloc(data, new_size);
-
- if (!new_data)
- goto fail;
- data = new_data;
- if (new_size > INT_MAX)
- goto fail;
-
- memcpy(data + *size, t->key, keylen + 1);
- memcpy(data + *size + keylen + 1, t->value, valuelen + 1);
-
- *size = new_size;
- }
-
- return data;
-
-fail:
- av_freep(&data);
- *size = 0;
- return NULL;
-}
-
-int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict)
-{
- const uint8_t *end = data + size;
- int ret = 0;
-
- if (!dict || !data || !size)
- return ret;
- if (size && end[-1])
- return AVERROR_INVALIDDATA;
- while (data < end) {
- const uint8_t *key = data;
- const uint8_t *val = data + strlen(key) + 1;
-
- if (val >= end)
- return AVERROR_INVALIDDATA;
-
- ret = av_dict_set(dict, key, val, 0);
- if (ret < 0)
- break;
- data = val + strlen(val) + 1;
- }
-
- return ret;
-}
-
-int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
- int size)
-{
- int i;
-
- for (i = 0; i < pkt->side_data_elems; i++) {
- if (pkt->side_data[i].type == type) {
- if (size > pkt->side_data[i].size)
- return AVERROR(ENOMEM);
- pkt->side_data[i].size = size;
- return 0;
- }
- }
- return AVERROR(ENOENT);
-}
-
-int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
-{
- int i;
-
- dst->pts = src->pts;
- dst->dts = src->dts;
- dst->pos = src->pos;
- dst->duration = src->duration;
- dst->convergence_duration = src->convergence_duration;
- dst->flags = src->flags;
- dst->stream_index = src->stream_index;
-
- for (i = 0; i < src->side_data_elems; i++) {
- enum AVPacketSideDataType type = src->side_data[i].type;
- int size = src->side_data[i].size;
- uint8_t *src_data = src->side_data[i].data;
- uint8_t *dst_data = av_packet_new_side_data(dst, type, size);
-
- if (!dst_data) {
- av_packet_free_side_data(dst);
- return AVERROR(ENOMEM);
- }
- memcpy(dst_data, src_data, size);
- }
-
- return 0;
-}
-
-void av_packet_unref(AVPacket *pkt)
-{
- av_packet_free_side_data(pkt);
- av_buffer_unref(&pkt->buf);
- av_init_packet(pkt);
- pkt->data = NULL;
- pkt->size = 0;
-}
-
-int av_packet_ref(AVPacket *dst, const AVPacket *src)
-{
- int ret;
-
- ret = av_packet_copy_props(dst, src);
- if (ret < 0)
- return ret;
-
- if (!src->buf) {
- ret = packet_alloc(&dst->buf, src->size);
- if (ret < 0)
- goto fail;
- memcpy(dst->buf->data, src->data, src->size);
- } else {
- dst->buf = av_buffer_ref(src->buf);
- if (!dst->buf) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- }
-
- dst->size = src->size;
- dst->data = dst->buf->data;
- return 0;
-fail:
- av_packet_free_side_data(dst);
- return ret;
-}
-
-void av_packet_move_ref(AVPacket *dst, AVPacket *src)
-{
- *dst = *src;
- av_init_packet(src);
-}
-
-void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb)
-{
- if (pkt->pts != AV_NOPTS_VALUE)
- pkt->pts = av_rescale_q(pkt->pts, src_tb, dst_tb);
- if (pkt->dts != AV_NOPTS_VALUE)
- pkt->dts = av_rescale_q(pkt->dts, src_tb, dst_tb);
- if (pkt->duration > 0)
- pkt->duration = av_rescale_q(pkt->duration, src_tb, dst_tb);
- if (pkt->convergence_duration > 0)
- pkt->convergence_duration = av_rescale_q(pkt->convergence_duration, src_tb, dst_tb);
-}
-
-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;
- int i;
-
- side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, &side_data_size);
- if (!side_data) {
- side_data_size = 4+4+8*error_count;
- side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,
- side_data_size);
- }
-
- if (!side_data || side_data_size < 4+4+8*error_count)
- return AVERROR(ENOMEM);
-
- AV_WL32(side_data , quality );
- side_data[4] = pict_type;
- side_data[5] = error_count;
- for (i = 0; i<error_count; i++)
- AV_WL64(side_data+8 + 8*i , error[i]);
-
- return 0;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/bmvvideo.c b/ffmpeg-2-8-11/libavcodec/bmvvideo.c
deleted file mode 100644
index 97f850d..0000000
--- a/ffmpeg-2-8-11/libavcodec/bmvvideo.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Discworld II BMV video decoder
- * Copyright (c) 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 "libavutil/avassert.h"
-#include "libavutil/common.h"
-
-#include "avcodec.h"
-#include "bytestream.h"
-#include "internal.h"
-
-enum BMVFlags{
- BMV_NOP = 0,
- BMV_END,
- BMV_DELTA,
- BMV_INTRA,
-
- BMV_SCROLL = 0x04,
- BMV_PALETTE = 0x08,
- BMV_COMMAND = 0x10,
- BMV_AUDIO = 0x20,
- BMV_EXT = 0x40,
- BMV_PRINT = 0x80
-};
-
-#define SCREEN_WIDE 640
-#define SCREEN_HIGH 429
-
-typedef struct BMVDecContext {
- AVCodecContext *avctx;
-
- uint8_t *frame, frame_base[SCREEN_WIDE * (SCREEN_HIGH + 1)];
- uint32_t pal[256];
- const uint8_t *stream;
-} BMVDecContext;
-
-#define NEXT_BYTE(v) (v) = forward ? (v) + 1 : (v) - 1;
-
-static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, int frame_off)
-{
- unsigned val, saved_val = 0;
- int tmplen = src_len;
- const uint8_t *src, *source_end = source + src_len;
- uint8_t *frame_end = frame + SCREEN_WIDE * SCREEN_HIGH;
- uint8_t *dst, *dst_end;
- int len, mask;
- int forward = (frame_off <= -SCREEN_WIDE) || (frame_off >= 0);
- int read_two_nibbles, flag;
- int advance_mode;
- int mode = 0;
- int i;
-
- if (src_len <= 0)
- return AVERROR_INVALIDDATA;
-
- if (forward) {
- src = source;
- dst = frame;
- dst_end = frame_end;
- } else {
- src = source + src_len - 1;
- dst = frame_end - 1;
- dst_end = frame - 1;
- }
- for (;;) {
- int shift = 0;
- flag = 0;
-
- /* The mode/len decoding is a bit strange:
- * values are coded as variable-length codes with nibble units,
- * code end is signalled by two top bits in the nibble being nonzero.
- * And since data is bytepacked and we read two nibbles at a time,
- * we may get a nibble belonging to the next code.
- * Hence this convoluted loop.
- */
- if (!mode || (tmplen == 4)) {
- if (src < source || src >= source_end)
- return AVERROR_INVALIDDATA;
- val = *src;
- read_two_nibbles = 1;
- } else {
- val = saved_val;
- read_two_nibbles = 0;
- }
- if (!(val & 0xC)) {
- for (;;) {
- if(shift>22)
- return -1;
- if (!read_two_nibbles) {
- if (src < source || src >= source_end)
- return AVERROR_INVALIDDATA;
- shift += 2;
- val |= *src << shift;
- if (*src & 0xC)
- break;
- }
- // two upper bits of the nibble is zero,
- // so shift top nibble value down into their place
- read_two_nibbles = 0;
- shift += 2;
- mask = (1 << shift) - 1;
- val = ((val >> 2) & ~mask) | (val & mask);
- NEXT_BYTE(src);
- if ((val & (0xC << shift))) {
- flag = 1;
- break;
- }
- }
- } else if (mode) {
- flag = tmplen != 4;
- }
- if (flag) {
- tmplen = 4;
- } else {
- saved_val = val >> (4 + shift);
- tmplen = 0;
- val &= (1 << (shift + 4)) - 1;
- NEXT_BYTE(src);
- }
- advance_mode = val & 1;
- len = (val >> 1) - 1;
- av_assert0(len>0);
- mode += 1 + advance_mode;
- if (mode >= 4)
- mode -= 3;
- if (len <= 0 || FFABS(dst_end - dst) < len)
- return AVERROR_INVALIDDATA;
- switch (mode) {
- case 1:
- if (forward) {
- if (dst - frame + SCREEN_WIDE < frame_off ||
- dst - frame + SCREEN_WIDE + frame_off < 0 ||
- frame_end - dst < frame_off + len ||
- frame_end - dst < len)
- return AVERROR_INVALIDDATA;
- for (i = 0; i < len; i++)
- dst[i] = dst[frame_off + i];
- dst += len;
- } else {
- dst -= len;
- if (dst - frame + SCREEN_WIDE < frame_off ||
- dst - frame + SCREEN_WIDE + frame_off < 0 ||
- frame_end - dst < frame_off + len ||
- frame_end - dst < len)
- return AVERROR_INVALIDDATA;
- for (i = len - 1; i >= 0; i--)
- dst[i] = dst[frame_off + i];
- }
- break;
- case 2:
- if (forward) {
- if (source + src_len - src < len)
- return AVERROR_INVALIDDATA;
- memcpy(dst, src, len);
- dst += len;
- src += len;
- } else {
- if (src - source < len)
- return AVERROR_INVALIDDATA;
- dst -= len;
- src -= len;
- memcpy(dst, src, len);
- }
- break;
- case 3:
- val = forward ? dst[-1] : dst[1];
- if (forward) {
- memset(dst, val, len);
- dst += len;
- } else {
- dst -= len;
- memset(dst, val, len);
- }
- break;
- }
- if (dst == dst_end)
- return 0;
- }
- return 0;
-}
-
-static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *pkt)
-{
- BMVDecContext * const c = avctx->priv_data;
- AVFrame *frame = data;
- int type, scr_off;
- int i, ret;
- uint8_t *srcptr, *outptr;
-
- c->stream = pkt->data;
- type = bytestream_get_byte(&c->stream);
- if (type & BMV_AUDIO) {
- int blobs = bytestream_get_byte(&c->stream);
- if (pkt->size < blobs * 65 + 2) {
- av_log(avctx, AV_LOG_ERROR, "Audio data doesn't fit in frame\n");
- return AVERROR_INVALIDDATA;
- }
- c->stream += blobs * 65;
- }
- if (type & BMV_COMMAND) {
- int command_size = (type & BMV_PRINT) ? 8 : 10;
- if (c->stream - pkt->data + command_size > pkt->size) {
- av_log(avctx, AV_LOG_ERROR, "Command data doesn't fit in frame\n");
- return AVERROR_INVALIDDATA;
- }
- c->stream += command_size;
- }
- if (type & BMV_PALETTE) {
- if (c->stream - pkt->data > pkt->size - 768) {
- av_log(avctx, AV_LOG_ERROR, "Palette data doesn't fit in frame\n");
- return AVERROR_INVALIDDATA;
- }
- for (i = 0; i < 256; i++)
- c->pal[i] = 0xFFU << 24 | bytestream_get_be24(&c->stream);
- }
- if (type & BMV_SCROLL) {
- if (c->stream - pkt->data > pkt->size - 2) {
- av_log(avctx, AV_LOG_ERROR, "Screen offset data doesn't fit in frame\n");
- return AVERROR_INVALIDDATA;
- }
- scr_off = (int16_t)bytestream_get_le16(&c->stream);
- } else if ((type & BMV_INTRA) == BMV_INTRA) {
- scr_off = -640;
- } else {
- scr_off = 0;
- }
-
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
-
- if (decode_bmv_frame(c->stream, pkt->size - (c->stream - pkt->data), c->frame, scr_off)) {
- av_log(avctx, AV_LOG_ERROR, "Error decoding frame data\n");
- return AVERROR_INVALIDDATA;
- }
-
- memcpy(frame->data[1], c->pal, AVPALETTE_SIZE);
- frame->palette_has_changed = type & BMV_PALETTE;
-
- outptr = frame->data[0];
- srcptr = c->frame;
-
- for (i = 0; i < avctx->height; i++) {
- memcpy(outptr, srcptr, avctx->width);
- srcptr += avctx->width;
- outptr += frame->linesize[0];
- }
-
- *got_frame = 1;
-
- /* always report that the buffer was completely consumed */
- return pkt->size;
-}
-
-static av_cold int decode_init(AVCodecContext *avctx)
-{
- BMVDecContext * const c = avctx->priv_data;
-
- c->avctx = avctx;
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
-
- if (avctx->width != SCREEN_WIDE || avctx->height != SCREEN_HIGH) {
- av_log(avctx, AV_LOG_ERROR, "Invalid dimension %dx%d\n", avctx->width, avctx->height);
- return AVERROR_INVALIDDATA;
- }
-
- c->frame = c->frame_base + 640;
-
- return 0;
-}
-
-AVCodec ff_bmv_video_decoder = {
- .name = "bmv_video",
- .long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV video"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_BMV_VIDEO,
- .priv_data_size = sizeof(BMVDecContext),
- .init = decode_init,
- .decode = decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/cavs.c b/ffmpeg-2-8-11/libavcodec/cavs.c
deleted file mode 100644
index 10a25d8..0000000
--- a/ffmpeg-2-8-11/libavcodec/cavs.c
+++ /dev/null
@@ -1,855 +0,0 @@
-/*
- * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
- * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer at gmx.de>
- *
- * 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
- * Chinese AVS video (AVS1-P2, JiZhun profile) decoder
- * @author Stefan Gehrer <stefan.gehrer at gmx.de>
- */
-
-#include "avcodec.h"
-#include "get_bits.h"
-#include "golomb.h"
-#include "h264chroma.h"
-#include "idctdsp.h"
-#include "internal.h"
-#include "mathops.h"
-#include "qpeldsp.h"
-#include "cavs.h"
-
-static const uint8_t alpha_tab[64] = {
- 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3,
- 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 20,
- 22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44,
- 46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
-};
-
-static const uint8_t beta_tab[64] = {
- 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
- 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6,
- 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27
-};
-
-static const uint8_t tc_tab[64] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
- 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
- 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9
-};
-
-/** mark block as unavailable, i.e. out of picture
- * or not yet decoded */
-static const cavs_vector un_mv = { 0, 0, 1, NOT_AVAIL };
-
-static const int8_t left_modifier_l[8] = { 0, -1, 6, -1, -1, 7, 6, 7 };
-static const int8_t top_modifier_l[8] = { -1, 1, 5, -1, -1, 5, 7, 7 };
-static const int8_t left_modifier_c[7] = { 5, -1, 2, -1, 6, 5, 6 };
-static const int8_t top_modifier_c[7] = { 4, 1, -1, -1, 4, 6, 6 };
-
-/*****************************************************************************
- *
- * in-loop deblocking filter
- *
- ****************************************************************************/
-
-static inline int get_bs(cavs_vector *mvP, cavs_vector *mvQ, int b)
-{
- if ((mvP->ref == REF_INTRA) || (mvQ->ref == REF_INTRA))
- return 2;
- if((abs(mvP->x - mvQ->x) >= 4) ||
- (abs(mvP->y - mvQ->y) >= 4) ||
- (mvP->ref != mvQ->ref))
- return 1;
- if (b) {
- mvP += MV_BWD_OFFS;
- mvQ += MV_BWD_OFFS;
- if((abs(mvP->x - mvQ->x) >= 4) ||
- (abs(mvP->y - mvQ->y) >= 4) ||
- (mvP->ref != mvQ->ref))
- return 1;
- }
- return 0;
-}
-
-#define SET_PARAMS \
- alpha = alpha_tab[av_clip_uintp2(qp_avg + h->alpha_offset, 6)]; \
- beta = beta_tab[av_clip_uintp2(qp_avg + h->beta_offset, 6)]; \
- tc = tc_tab[av_clip_uintp2(qp_avg + h->alpha_offset, 6)];
-
-/**
- * in-loop deblocking filter for a single macroblock
- *
- * boundary strength (bs) mapping:
- *
- * --4---5--
- * 0 2 |
- * | 6 | 7 |
- * 1 3 |
- * ---------
- *
- */
-void ff_cavs_filter(AVSContext *h, enum cavs_mb mb_type)
-{
- uint8_t bs[8];
- int qp_avg, alpha, beta, tc;
- int i;
-
- /* save un-deblocked lines */
- h->topleft_border_y = h->top_border_y[h->mbx * 16 + 15];
- h->topleft_border_u = h->top_border_u[h->mbx * 10 + 8];
- h->topleft_border_v = h->top_border_v[h->mbx * 10 + 8];
- memcpy(&h->top_border_y[h->mbx * 16], h->cy + 15 * h->l_stride, 16);
- memcpy(&h->top_border_u[h->mbx * 10 + 1], h->cu + 7 * h->c_stride, 8);
- memcpy(&h->top_border_v[h->mbx * 10 + 1], h->cv + 7 * h->c_stride, 8);
- for (i = 0; i < 8; i++) {
- h->left_border_y[i * 2 + 1] = *(h->cy + 15 + (i * 2 + 0) * h->l_stride);
- h->left_border_y[i * 2 + 2] = *(h->cy + 15 + (i * 2 + 1) * h->l_stride);
- h->left_border_u[i + 1] = *(h->cu + 7 + i * h->c_stride);
- h->left_border_v[i + 1] = *(h->cv + 7 + i * h->c_stride);
- }
- if (!h->loop_filter_disable) {
- /* determine bs */
- if (mb_type == I_8X8)
- memset(bs, 2, 8);
- else {
- memset(bs, 0, 8);
- if (ff_cavs_partition_flags[mb_type] & SPLITV) {
- bs[2] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X1], mb_type > P_8X8);
- bs[3] = get_bs(&h->mv[MV_FWD_X2], &h->mv[MV_FWD_X3], mb_type > P_8X8);
- }
- if (ff_cavs_partition_flags[mb_type] & SPLITH) {
- bs[6] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X2], mb_type > P_8X8);
- bs[7] = get_bs(&h->mv[MV_FWD_X1], &h->mv[MV_FWD_X3], mb_type > P_8X8);
- }
- bs[0] = get_bs(&h->mv[MV_FWD_A1], &h->mv[MV_FWD_X0], mb_type > P_8X8);
- bs[1] = get_bs(&h->mv[MV_FWD_A3], &h->mv[MV_FWD_X2], mb_type > P_8X8);
- bs[4] = get_bs(&h->mv[MV_FWD_B2], &h->mv[MV_FWD_X0], mb_type > P_8X8);
- bs[5] = get_bs(&h->mv[MV_FWD_B3], &h->mv[MV_FWD_X1], mb_type > P_8X8);
- }
- if (AV_RN64(bs)) {
- if (h->flags & A_AVAIL) {
- qp_avg = (h->qp + h->left_qp + 1) >> 1;
- SET_PARAMS;
- h->cdsp.cavs_filter_lv(h->cy, h->l_stride, alpha, beta, tc, bs[0], bs[1]);
- qp_avg = (ff_cavs_chroma_qp[h->qp] + ff_cavs_chroma_qp[h->left_qp] + 1) >> 1;
- SET_PARAMS;
- h->cdsp.cavs_filter_cv(h->cu, h->c_stride, alpha, beta, tc, bs[0], bs[1]);
- h->cdsp.cavs_filter_cv(h->cv, h->c_stride, alpha, beta, tc, bs[0], bs[1]);
- }
- qp_avg = h->qp;
- SET_PARAMS;
- h->cdsp.cavs_filter_lv(h->cy + 8, h->l_stride, alpha, beta, tc, bs[2], bs[3]);
- h->cdsp.cavs_filter_lh(h->cy + 8 * h->l_stride, h->l_stride, alpha, beta, tc, bs[6], bs[7]);
-
- if (h->flags & B_AVAIL) {
- qp_avg = (h->qp + h->top_qp[h->mbx] + 1) >> 1;
- SET_PARAMS;
- h->cdsp.cavs_filter_lh(h->cy, h->l_stride, alpha, beta, tc, bs[4], bs[5]);
- qp_avg = (ff_cavs_chroma_qp[h->qp] + ff_cavs_chroma_qp[h->top_qp[h->mbx]] + 1) >> 1;
- SET_PARAMS;
- h->cdsp.cavs_filter_ch(h->cu, h->c_stride, alpha, beta, tc, bs[4], bs[5]);
- h->cdsp.cavs_filter_ch(h->cv, h->c_stride, alpha, beta, tc, bs[4], bs[5]);
- }
- }
- }
- h->left_qp = h->qp;
- h->top_qp[h->mbx] = h->qp;
-}
-
-#undef SET_PARAMS
-
-/*****************************************************************************
- *
- * spatial intra prediction
- *
- ****************************************************************************/
-
-void ff_cavs_load_intra_pred_luma(AVSContext *h, uint8_t *top,
- uint8_t **left, int block)
-{
- int i;
-
- switch (block) {
- case 0:
- *left = h->left_border_y;
- h->left_border_y[0] = h->left_border_y[1];
- memset(&h->left_border_y[17], h->left_border_y[16], 9);
- memcpy(&top[1], &h->top_border_y[h->mbx * 16], 16);
- top[17] = top[16];
- top[0] = top[1];
- if ((h->flags & A_AVAIL) && (h->flags & B_AVAIL))
- h->left_border_y[0] = top[0] = h->topleft_border_y;
- break;
- case 1:
- *left = h->intern_border_y;
- for (i = 0; i < 8; i++)
- h->intern_border_y[i + 1] = *(h->cy + 7 + i * h->l_stride);
- memset(&h->intern_border_y[9], h->intern_border_y[8], 9);
- h->intern_border_y[0] = h->intern_border_y[1];
- memcpy(&top[1], &h->top_border_y[h->mbx * 16 + 8], 8);
- if (h->flags & C_AVAIL)
- memcpy(&top[9], &h->top_border_y[(h->mbx + 1) * 16], 8);
- else
- memset(&top[9], top[8], 9);
- top[17] = top[16];
- top[0] = top[1];
- if (h->flags & B_AVAIL)
- h->intern_border_y[0] = top[0] = h->top_border_y[h->mbx * 16 + 7];
- break;
- case 2:
- *left = &h->left_border_y[8];
- memcpy(&top[1], h->cy + 7 * h->l_stride, 16);
- top[17] = top[16];
- top[0] = top[1];
- if (h->flags & A_AVAIL)
- top[0] = h->left_border_y[8];
- break;
- case 3:
- *left = &h->intern_border_y[8];
- for (i = 0; i < 8; i++)
- h->intern_border_y[i + 9] = *(h->cy + 7 + (i + 8) * h->l_stride);
- memset(&h->intern_border_y[17], h->intern_border_y[16], 9);
- memcpy(&top[0], h->cy + 7 + 7 * h->l_stride, 9);
- memset(&top[9], top[8], 9);
- break;
- }
-}
-
-void ff_cavs_load_intra_pred_chroma(AVSContext *h)
-{
- /* extend borders by one pixel */
- h->left_border_u[9] = h->left_border_u[8];
- h->left_border_v[9] = h->left_border_v[8];
- if(h->flags & C_AVAIL) {
- h->top_border_u[h->mbx*10 + 9] = h->top_border_u[h->mbx*10 + 11];
- h->top_border_v[h->mbx*10 + 9] = h->top_border_v[h->mbx*10 + 11];
- } else {
- h->top_border_u[h->mbx * 10 + 9] = h->top_border_u[h->mbx * 10 + 8];
- h->top_border_v[h->mbx * 10 + 9] = h->top_border_v[h->mbx * 10 + 8];
- }
- if((h->flags & A_AVAIL) && (h->flags & B_AVAIL)) {
- h->top_border_u[h->mbx * 10] = h->left_border_u[0] = h->topleft_border_u;
- h->top_border_v[h->mbx * 10] = h->left_border_v[0] = h->topleft_border_v;
- } else {
- h->left_border_u[0] = h->left_border_u[1];
- h->left_border_v[0] = h->left_border_v[1];
- h->top_border_u[h->mbx * 10] = h->top_border_u[h->mbx * 10 + 1];
- h->top_border_v[h->mbx * 10] = h->top_border_v[h->mbx * 10 + 1];
- }
-}
-
-static void intra_pred_vert(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
-{
- int y;
- uint64_t a = AV_RN64(&top[1]);
- for (y = 0; y < 8; y++)
- *((uint64_t *)(d + y * stride)) = a;
-}
-
-static void intra_pred_horiz(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
-{
- int y;
- uint64_t a;
- for (y = 0; y < 8; y++) {
- a = left[y + 1] * 0x0101010101010101ULL;
- *((uint64_t *)(d + y * stride)) = a;
- }
-}
-
-static void intra_pred_dc_128(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
-{
- int y;
- uint64_t a = 0x8080808080808080ULL;
- for (y = 0; y < 8; y++)
- *((uint64_t *)(d + y * stride)) = a;
-}
-
-static void intra_pred_plane(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
-{
- int x, y, ia;
- int ih = 0;
- int iv = 0;
- const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
-
- for (x = 0; x < 4; x++) {
- ih += (x + 1) * (top[5 + x] - top[3 - x]);
- iv += (x + 1) * (left[5 + x] - left[3 - x]);
- }
- ia = (top[8] + left[8]) << 4;
- ih = (17 * ih + 16) >> 5;
- iv = (17 * iv + 16) >> 5;
- for (y = 0; y < 8; y++)
- for (x = 0; x < 8; x++)
- d[y * stride + x] = cm[(ia + (x - 3) * ih + (y - 3) * iv + 16) >> 5];
-}
-
-#define LOWPASS(ARRAY, INDEX) \
- ((ARRAY[(INDEX) - 1] + 2 * ARRAY[(INDEX)] + ARRAY[(INDEX) + 1] + 2) >> 2)
-
-static void intra_pred_lp(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
-{
- int x, y;
- for (y = 0; y < 8; y++)
- for (x = 0; x < 8; x++)
- d[y * stride + x] = (LOWPASS(top, x + 1) + LOWPASS(left, y + 1)) >> 1;
-}
-
-static void intra_pred_down_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
-{
- int x, y;
- for (y = 0; y < 8; y++)
- for (x = 0; x < 8; x++)
- d[y * stride + x] = (LOWPASS(top, x + y + 2) + LOWPASS(left, x + y + 2)) >> 1;
-}
-
-static void intra_pred_down_right(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
-{
- int x, y;
- for (y = 0; y < 8; y++)
- for (x = 0; x < 8; x++)
- if (x == y)
- d[y * stride + x] = (left[1] + 2 * top[0] + top[1] + 2) >> 2;
- else if (x > y)
- d[y * stride + x] = LOWPASS(top, x - y);
- else
- d[y * stride + x] = LOWPASS(left, y - x);
-}
-
-static void intra_pred_lp_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
-{
- int x, y;
- for (y = 0; y < 8; y++)
- for (x = 0; x < 8; x++)
- d[y * stride + x] = LOWPASS(left, y + 1);
-}
-
-static void intra_pred_lp_top(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
-{
- int x, y;
- for (y = 0; y < 8; y++)
- for (x = 0; x < 8; x++)
- d[y * stride + x] = LOWPASS(top, x + 1);
-}
-
-#undef LOWPASS
-
-static inline void modify_pred(const int8_t *mod_table, int *mode)
-{
- *mode = mod_table[*mode];
- if (*mode < 0) {
- av_log(NULL, AV_LOG_ERROR, "Illegal intra prediction mode\n");
- *mode = 0;
- }
-}
-
-void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv)
-{
- /* save pred modes before they get modified */
- h->pred_mode_Y[3] = h->pred_mode_Y[5];
- h->pred_mode_Y[6] = h->pred_mode_Y[8];
- h->top_pred_Y[h->mbx * 2 + 0] = h->pred_mode_Y[7];
- h->top_pred_Y[h->mbx * 2 + 1] = h->pred_mode_Y[8];
-
- /* modify pred modes according to availability of neighbour samples */
- if (!(h->flags & A_AVAIL)) {
- modify_pred(left_modifier_l, &h->pred_mode_Y[4]);
- modify_pred(left_modifier_l, &h->pred_mode_Y[7]);
- modify_pred(left_modifier_c, pred_mode_uv);
- }
- if (!(h->flags & B_AVAIL)) {
- modify_pred(top_modifier_l, &h->pred_mode_Y[4]);
- modify_pred(top_modifier_l, &h->pred_mode_Y[5]);
- modify_pred(top_modifier_c, pred_mode_uv);
- }
-}
-
-/*****************************************************************************
- *
- * motion compensation
- *
- ****************************************************************************/
-
-static inline void mc_dir_part(AVSContext *h, AVFrame *pic, int chroma_height,
- int delta, int list, uint8_t *dest_y,
- uint8_t *dest_cb, uint8_t *dest_cr,
- int src_x_offset, int src_y_offset,
- qpel_mc_func *qpix_op,
- h264_chroma_mc_func chroma_op, cavs_vector *mv)
-{
- const int mx = mv->x + src_x_offset * 8;
- const int my = mv->y + src_y_offset * 8;
- const int luma_xy = (mx & 3) + ((my & 3) << 2);
- uint8_t *src_y = pic->data[0] + (mx >> 2) + (my >> 2) * h->l_stride;
- uint8_t *src_cb = pic->data[1] + (mx >> 3) + (my >> 3) * h->c_stride;
- uint8_t *src_cr = pic->data[2] + (mx >> 3) + (my >> 3) * h->c_stride;
- int extra_width = 0;
- int extra_height = extra_width;
- const int full_mx = mx >> 2;
- const int full_my = my >> 2;
- const int pic_width = 16 * h->mb_width;
- const int pic_height = 16 * h->mb_height;
- int emu = 0;
-
- if (!pic->data[0])
- return;
- if (mx & 7)
- extra_width -= 3;
- if (my & 7)
- extra_height -= 3;
-
- if (full_mx < 0 - extra_width ||
- full_my < 0 - extra_height ||
- full_mx + 16 /* FIXME */ > pic_width + extra_width ||
- full_my + 16 /* FIXME */ > pic_height + extra_height) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
- src_y - 2 - 2 * h->l_stride,
- h->l_stride, h->l_stride,
- 16 + 5, 16 + 5 /* FIXME */,
- full_mx - 2, full_my - 2,
- pic_width, pic_height);
- src_y = h->edge_emu_buffer + 2 + 2 * h->l_stride;
- emu = 1;
- }
-
- // FIXME try variable height perhaps?
- qpix_op[luma_xy](dest_y, src_y, h->l_stride);
-
- if (emu) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb,
- h->c_stride, h->c_stride,
- 9, 9 /* FIXME */,
- mx >> 3, my >> 3,
- pic_width >> 1, pic_height >> 1);
- src_cb = h->edge_emu_buffer;
- }
- chroma_op(dest_cb, src_cb, h->c_stride, chroma_height, mx & 7, my & 7);
-
- if (emu) {
- h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr,
- h->c_stride, h->c_stride,
- 9, 9 /* FIXME */,
- mx >> 3, my >> 3,
- pic_width >> 1, pic_height >> 1);
- src_cr = h->edge_emu_buffer;
- }
- chroma_op(dest_cr, src_cr, h->c_stride, chroma_height, mx & 7, my & 7);
-}
-
-static inline void mc_part_std(AVSContext *h, int chroma_height, int delta,
- uint8_t *dest_y,
- uint8_t *dest_cb,
- uint8_t *dest_cr,
- int x_offset, int y_offset,
- qpel_mc_func *qpix_put,
- h264_chroma_mc_func chroma_put,
- qpel_mc_func *qpix_avg,
- h264_chroma_mc_func chroma_avg,
- cavs_vector *mv)
-{
- qpel_mc_func *qpix_op = qpix_put;
- h264_chroma_mc_func chroma_op = chroma_put;
-
- dest_y += x_offset * 2 + y_offset * h->l_stride * 2;
- dest_cb += x_offset + y_offset * h->c_stride;
- dest_cr += x_offset + y_offset * h->c_stride;
- x_offset += 8 * h->mbx;
- y_offset += 8 * h->mby;
-
- if (mv->ref >= 0) {
- AVFrame *ref = h->DPB[mv->ref].f;
- mc_dir_part(h, ref, chroma_height, delta, 0,
- dest_y, dest_cb, dest_cr, x_offset, y_offset,
- qpix_op, chroma_op, mv);
-
- qpix_op = qpix_avg;
- chroma_op = chroma_avg;
- }
-
- if ((mv + MV_BWD_OFFS)->ref >= 0) {
- AVFrame *ref = h->DPB[0].f;
- mc_dir_part(h, ref, chroma_height, delta, 1,
- dest_y, dest_cb, dest_cr, x_offset, y_offset,
- qpix_op, chroma_op, mv + MV_BWD_OFFS);
- }
-}
-
-void ff_cavs_inter(AVSContext *h, enum cavs_mb mb_type)
-{
- if (ff_cavs_partition_flags[mb_type] == 0) { // 16x16
- mc_part_std(h, 8, 0, h->cy, h->cu, h->cv, 0, 0,
- h->cdsp.put_cavs_qpel_pixels_tab[0],
- h->h264chroma.put_h264_chroma_pixels_tab[0],
- h->cdsp.avg_cavs_qpel_pixels_tab[0],
- h->h264chroma.avg_h264_chroma_pixels_tab[0],
- &h->mv[MV_FWD_X0]);
- } else {
- mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 0,
- h->cdsp.put_cavs_qpel_pixels_tab[1],
- h->h264chroma.put_h264_chroma_pixels_tab[1],
- h->cdsp.avg_cavs_qpel_pixels_tab[1],
- h->h264chroma.avg_h264_chroma_pixels_tab[1],
- &h->mv[MV_FWD_X0]);
- mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 0,
- h->cdsp.put_cavs_qpel_pixels_tab[1],
- h->h264chroma.put_h264_chroma_pixels_tab[1],
- h->cdsp.avg_cavs_qpel_pixels_tab[1],
- h->h264chroma.avg_h264_chroma_pixels_tab[1],
- &h->mv[MV_FWD_X1]);
- mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 4,
- h->cdsp.put_cavs_qpel_pixels_tab[1],
- h->h264chroma.put_h264_chroma_pixels_tab[1],
- h->cdsp.avg_cavs_qpel_pixels_tab[1],
- h->h264chroma.avg_h264_chroma_pixels_tab[1],
- &h->mv[MV_FWD_X2]);
- mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 4,
- h->cdsp.put_cavs_qpel_pixels_tab[1],
- h->h264chroma.put_h264_chroma_pixels_tab[1],
- h->cdsp.avg_cavs_qpel_pixels_tab[1],
- h->h264chroma.avg_h264_chroma_pixels_tab[1],
- &h->mv[MV_FWD_X3]);
- }
-}
-
-/*****************************************************************************
- *
- * motion vector prediction
- *
- ****************************************************************************/
-
-static inline void scale_mv(AVSContext *h, int *d_x, int *d_y,
- cavs_vector *src, int distp)
-{
- int den = h->scale_den[FFMAX(src->ref, 0)];
-
- *d_x = (src->x * distp * den + 256 + FF_SIGNBIT(src->x)) >> 9;
- *d_y = (src->y * distp * den + 256 + FF_SIGNBIT(src->y)) >> 9;
-}
-
-static inline void mv_pred_median(AVSContext *h,
- cavs_vector *mvP,
- cavs_vector *mvA,
- cavs_vector *mvB,
- cavs_vector *mvC)
-{
- int ax, ay, bx, by, cx, cy;
- int len_ab, len_bc, len_ca, len_mid;
-
- /* scale candidates according to their temporal span */
- scale_mv(h, &ax, &ay, mvA, mvP->dist);
- scale_mv(h, &bx, &by, mvB, mvP->dist);
- scale_mv(h, &cx, &cy, mvC, mvP->dist);
- /* find the geometrical median of the three candidates */
- len_ab = abs(ax - bx) + abs(ay - by);
- len_bc = abs(bx - cx) + abs(by - cy);
- len_ca = abs(cx - ax) + abs(cy - ay);
- len_mid = mid_pred(len_ab, len_bc, len_ca);
- if (len_mid == len_ab) {
- mvP->x = cx;
- mvP->y = cy;
- } else if (len_mid == len_bc) {
- mvP->x = ax;
- mvP->y = ay;
- } else {
- mvP->x = bx;
- mvP->y = by;
- }
-}
-
-void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC,
- enum cavs_mv_pred mode, enum cavs_block size, int ref)
-{
- cavs_vector *mvP = &h->mv[nP];
- cavs_vector *mvA = &h->mv[nP-1];
- cavs_vector *mvB = &h->mv[nP-4];
- cavs_vector *mvC = &h->mv[nC];
- const cavs_vector *mvP2 = NULL;
-
- mvP->ref = ref;
- mvP->dist = h->dist[mvP->ref];
- if (mvC->ref == NOT_AVAIL || (nP == MV_FWD_X3) || (nP == MV_BWD_X3 ))
- mvC = &h->mv[nP - 5]; // set to top-left (mvD)
- if (mode == MV_PRED_PSKIP &&
- (mvA->ref == NOT_AVAIL ||
- mvB->ref == NOT_AVAIL ||
- (mvA->x | mvA->y | mvA->ref) == 0 ||
- (mvB->x | mvB->y | mvB->ref) == 0)) {
- mvP2 = &un_mv;
- /* if there is only one suitable candidate, take it */
- } else if (mvA->ref >= 0 && mvB->ref < 0 && mvC->ref < 0) {
- mvP2 = mvA;
- } else if (mvA->ref < 0 && mvB->ref >= 0 && mvC->ref < 0) {
- mvP2 = mvB;
- } else if (mvA->ref < 0 && mvB->ref < 0 && mvC->ref >= 0) {
- mvP2 = mvC;
- } else if (mode == MV_PRED_LEFT && mvA->ref == ref) {
- mvP2 = mvA;
- } else if (mode == MV_PRED_TOP && mvB->ref == ref) {
- mvP2 = mvB;
- } else if (mode == MV_PRED_TOPRIGHT && mvC->ref == ref) {
- mvP2 = mvC;
- }
- if (mvP2) {
- mvP->x = mvP2->x;
- mvP->y = mvP2->y;
- } else
- mv_pred_median(h, mvP, mvA, mvB, mvC);
-
- if (mode < MV_PRED_PSKIP) {
- mvP->x += get_se_golomb(&h->gb);
- mvP->y += get_se_golomb(&h->gb);
- }
- set_mvs(mvP, size);
-}
-
-/*****************************************************************************
- *
- * macroblock level
- *
- ****************************************************************************/
-
-/**
- * initialise predictors for motion vectors and intra prediction
- */
-void ff_cavs_init_mb(AVSContext *h)
-{
- int i;
-
- /* copy predictors from top line (MB B and C) into cache */
- for (i = 0; i < 3; i++) {
- h->mv[MV_FWD_B2 + i] = h->top_mv[0][h->mbx * 2 + i];
- h->mv[MV_BWD_B2 + i] = h->top_mv[1][h->mbx * 2 + i];
- }
- h->pred_mode_Y[1] = h->top_pred_Y[h->mbx * 2 + 0];
- h->pred_mode_Y[2] = h->top_pred_Y[h->mbx * 2 + 1];
- /* clear top predictors if MB B is not available */
- if (!(h->flags & B_AVAIL)) {
- h->mv[MV_FWD_B2] = un_mv;
- h->mv[MV_FWD_B3] = un_mv;
- h->mv[MV_BWD_B2] = un_mv;
- h->mv[MV_BWD_B3] = un_mv;
- h->pred_mode_Y[1] = h->pred_mode_Y[2] = NOT_AVAIL;
- h->flags &= ~(C_AVAIL | D_AVAIL);
- } else if (h->mbx) {
- h->flags |= D_AVAIL;
- }
- if (h->mbx == h->mb_width - 1) // MB C not available
- h->flags &= ~C_AVAIL;
- /* clear top-right predictors if MB C is not available */
- if (!(h->flags & C_AVAIL)) {
- h->mv[MV_FWD_C2] = un_mv;
- h->mv[MV_BWD_C2] = un_mv;
- }
- /* clear top-left predictors if MB D is not available */
- if (!(h->flags & D_AVAIL)) {
- h->mv[MV_FWD_D3] = un_mv;
- h->mv[MV_BWD_D3] = un_mv;
- }
-}
-
-/**
- * save predictors for later macroblocks and increase
- * macroblock address
- * @return 0 if end of frame is reached, 1 otherwise
- */
-int ff_cavs_next_mb(AVSContext *h)
-{
- int i;
-
- h->flags |= A_AVAIL;
- h->cy += 16;
- h->cu += 8;
- h->cv += 8;
- /* copy mvs as predictors to the left */
- for (i = 0; i <= 20; i += 4)
- h->mv[i] = h->mv[i + 2];
- /* copy bottom mvs from cache to top line */
- h->top_mv[0][h->mbx * 2 + 0] = h->mv[MV_FWD_X2];
- h->top_mv[0][h->mbx * 2 + 1] = h->mv[MV_FWD_X3];
- h->top_mv[1][h->mbx * 2 + 0] = h->mv[MV_BWD_X2];
- h->top_mv[1][h->mbx * 2 + 1] = h->mv[MV_BWD_X3];
- /* next MB address */
- h->mbidx++;
- h->mbx++;
- if (h->mbx == h->mb_width) { // New mb line
- h->flags = B_AVAIL | C_AVAIL;
- /* clear left pred_modes */
- h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
- /* clear left mv predictors */
- for (i = 0; i <= 20; i += 4)
- h->mv[i] = un_mv;
- h->mbx = 0;
- h->mby++;
- /* re-calculate sample pointers */
- h->cy = h->cur.f->data[0] + h->mby * 16 * h->l_stride;
- h->cu = h->cur.f->data[1] + h->mby * 8 * h->c_stride;
- h->cv = h->cur.f->data[2] + h->mby * 8 * h->c_stride;
- if (h->mby == h->mb_height) { // Frame end
- return 0;
- }
- }
- return 1;
-}
-
-/*****************************************************************************
- *
- * frame level
- *
- ****************************************************************************/
-
-int ff_cavs_init_pic(AVSContext *h)
-{
- int i;
-
- /* clear some predictors */
- for (i = 0; i <= 20; i += 4)
- h->mv[i] = un_mv;
- h->mv[MV_BWD_X0] = ff_cavs_dir_mv;
- set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
- h->mv[MV_FWD_X0] = ff_cavs_dir_mv;
- set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
- h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
- h->cy = h->cur.f->data[0];
- h->cu = h->cur.f->data[1];
- h->cv = h->cur.f->data[2];
- h->l_stride = h->cur.f->linesize[0];
- h->c_stride = h->cur.f->linesize[1];
- h->luma_scan[2] = 8 * h->l_stride;
- h->luma_scan[3] = 8 * h->l_stride + 8;
- h->mbx = h->mby = h->mbidx = 0;
- h->flags = 0;
-
- return 0;
-}
-
-/*****************************************************************************
- *
- * headers and interface
- *
- ****************************************************************************/
-
-/**
- * some predictions require data from the top-neighbouring macroblock.
- * this data has to be stored for one complete row of macroblocks
- * and this storage space is allocated here
- */
-int ff_cavs_init_top_lines(AVSContext *h)
-{
- /* alloc top line of predictors */
- h->top_qp = av_mallocz(h->mb_width);
- h->top_mv[0] = av_mallocz_array(h->mb_width * 2 + 1, sizeof(cavs_vector));
- h->top_mv[1] = av_mallocz_array(h->mb_width * 2 + 1, sizeof(cavs_vector));
- h->top_pred_Y = av_mallocz_array(h->mb_width * 2, sizeof(*h->top_pred_Y));
- h->top_border_y = av_mallocz_array(h->mb_width + 1, 16);
- h->top_border_u = av_mallocz_array(h->mb_width, 10);
- h->top_border_v = av_mallocz_array(h->mb_width, 10);
-
- /* alloc space for co-located MVs and types */
- h->col_mv = av_mallocz_array(h->mb_width * h->mb_height,
- 4 * sizeof(cavs_vector));
- h->col_type_base = av_mallocz(h->mb_width * h->mb_height);
- h->block = av_mallocz(64 * sizeof(int16_t));
-
- if (!h->top_qp || !h->top_mv[0] || !h->top_mv[1] || !h->top_pred_Y ||
- !h->top_border_y || !h->top_border_u || !h->top_border_v ||
- !h->col_mv || !h->col_type_base || !h->block) {
- av_freep(&h->top_qp);
- av_freep(&h->top_mv[0]);
- av_freep(&h->top_mv[1]);
- av_freep(&h->top_pred_Y);
- av_freep(&h->top_border_y);
- av_freep(&h->top_border_u);
- av_freep(&h->top_border_v);
- av_freep(&h->col_mv);
- av_freep(&h->col_type_base);
- av_freep(&h->block);
- return AVERROR(ENOMEM);
- }
- return 0;
-}
-
-av_cold int ff_cavs_init(AVCodecContext *avctx)
-{
- AVSContext *h = avctx->priv_data;
-
- ff_blockdsp_init(&h->bdsp, avctx);
- ff_h264chroma_init(&h->h264chroma, 8);
- ff_idctdsp_init(&h->idsp, avctx);
- ff_videodsp_init(&h->vdsp, 8);
- ff_cavsdsp_init(&h->cdsp, avctx);
- ff_init_scantable_permutation(h->idsp.idct_permutation,
- h->cdsp.idct_perm);
- ff_init_scantable(h->idsp.idct_permutation, &h->scantable, ff_zigzag_direct);
-
- h->avctx = avctx;
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
-
- h->cur.f = av_frame_alloc();
- h->DPB[0].f = av_frame_alloc();
- h->DPB[1].f = av_frame_alloc();
- if (!h->cur.f || !h->DPB[0].f || !h->DPB[1].f) {
- ff_cavs_end(avctx);
- return AVERROR(ENOMEM);
- }
-
- h->luma_scan[0] = 0;
- h->luma_scan[1] = 8;
- h->intra_pred_l[INTRA_L_VERT] = intra_pred_vert;
- h->intra_pred_l[INTRA_L_HORIZ] = intra_pred_horiz;
- h->intra_pred_l[INTRA_L_LP] = intra_pred_lp;
- h->intra_pred_l[INTRA_L_DOWN_LEFT] = intra_pred_down_left;
- h->intra_pred_l[INTRA_L_DOWN_RIGHT] = intra_pred_down_right;
- h->intra_pred_l[INTRA_L_LP_LEFT] = intra_pred_lp_left;
- h->intra_pred_l[INTRA_L_LP_TOP] = intra_pred_lp_top;
- h->intra_pred_l[INTRA_L_DC_128] = intra_pred_dc_128;
- h->intra_pred_c[INTRA_C_LP] = intra_pred_lp;
- h->intra_pred_c[INTRA_C_HORIZ] = intra_pred_horiz;
- h->intra_pred_c[INTRA_C_VERT] = intra_pred_vert;
- h->intra_pred_c[INTRA_C_PLANE] = intra_pred_plane;
- h->intra_pred_c[INTRA_C_LP_LEFT] = intra_pred_lp_left;
- h->intra_pred_c[INTRA_C_LP_TOP] = intra_pred_lp_top;
- h->intra_pred_c[INTRA_C_DC_128] = intra_pred_dc_128;
- h->mv[7] = un_mv;
- h->mv[19] = un_mv;
- return 0;
-}
-
-av_cold int ff_cavs_end(AVCodecContext *avctx)
-{
- AVSContext *h = avctx->priv_data;
-
- av_frame_free(&h->cur.f);
- av_frame_free(&h->DPB[0].f);
- av_frame_free(&h->DPB[1].f);
-
- av_freep(&h->top_qp);
- av_freep(&h->top_mv[0]);
- av_freep(&h->top_mv[1]);
- av_freep(&h->top_pred_Y);
- av_freep(&h->top_border_y);
- av_freep(&h->top_border_u);
- av_freep(&h->top_border_v);
- av_freep(&h->col_mv);
- av_freep(&h->col_type_base);
- av_freep(&h->block);
- av_freep(&h->edge_emu_buffer);
- return 0;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/cavsdec.c b/ffmpeg-2-8-11/libavcodec/cavsdec.c
deleted file mode 100644
index d267faa..0000000
--- a/ffmpeg-2-8-11/libavcodec/cavsdec.c
+++ /dev/null
@@ -1,1269 +0,0 @@
-/*
- * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
- * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer at gmx.de>
- *
- * 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
- * Chinese AVS video (AVS1-P2, JiZhun profile) decoder
- * @author Stefan Gehrer <stefan.gehrer at gmx.de>
- */
-
-#include "libavutil/avassert.h"
-#include "avcodec.h"
-#include "get_bits.h"
-#include "golomb.h"
-#include "cavs.h"
-#include "internal.h"
-#include "mpeg12data.h"
-#include "mpegvideo.h"
-
-static const uint8_t mv_scan[4] = {
- MV_FWD_X0, MV_FWD_X1,
- MV_FWD_X2, MV_FWD_X3
-};
-
-static const uint8_t cbp_tab[64][2] = {
- { 63, 0 }, { 15, 15 }, { 31, 63 }, { 47, 31 }, { 0, 16 }, { 14, 32 }, { 13, 47 }, { 11, 13 },
- { 7, 14 }, { 5, 11 }, { 10, 12 }, { 8, 5 }, { 12, 10 }, { 61, 7 }, { 4, 48 }, { 55, 3 },
- { 1, 2 }, { 2, 8 }, { 59, 4 }, { 3, 1 }, { 62, 61 }, { 9, 55 }, { 6, 59 }, { 29, 62 },
- { 45, 29 }, { 51, 27 }, { 23, 23 }, { 39, 19 }, { 27, 30 }, { 46, 28 }, { 53, 9 }, { 30, 6 },
- { 43, 60 }, { 37, 21 }, { 60, 44 }, { 16, 26 }, { 21, 51 }, { 28, 35 }, { 19, 18 }, { 35, 20 },
- { 42, 24 }, { 26, 53 }, { 44, 17 }, { 32, 37 }, { 58, 39 }, { 24, 45 }, { 20, 58 }, { 17, 43 },
- { 18, 42 }, { 48, 46 }, { 22, 36 }, { 33, 33 }, { 25, 34 }, { 49, 40 }, { 40, 52 }, { 36, 49 },
- { 34, 50 }, { 50, 56 }, { 52, 25 }, { 54, 22 }, { 41, 54 }, { 56, 57 }, { 38, 41 }, { 57, 38 }
-};
-
-static const uint8_t scan3x3[4] = { 4, 5, 7, 8 };
-
-static const uint8_t dequant_shift[64] = {
- 14, 14, 14, 14, 14, 14, 14, 14,
- 13, 13, 13, 13, 13, 13, 13, 13,
- 13, 12, 12, 12, 12, 12, 12, 12,
- 11, 11, 11, 11, 11, 11, 11, 11,
- 11, 10, 10, 10, 10, 10, 10, 10,
- 10, 9, 9, 9, 9, 9, 9, 9,
- 9, 8, 8, 8, 8, 8, 8, 8,
- 7, 7, 7, 7, 7, 7, 7, 7
-};
-
-static const uint16_t dequant_mul[64] = {
- 32768, 36061, 38968, 42495, 46341, 50535, 55437, 60424,
- 32932, 35734, 38968, 42495, 46177, 50535, 55109, 59933,
- 65535, 35734, 38968, 42577, 46341, 50617, 55027, 60097,
- 32809, 35734, 38968, 42454, 46382, 50576, 55109, 60056,
- 65535, 35734, 38968, 42495, 46320, 50515, 55109, 60076,
- 65535, 35744, 38968, 42495, 46341, 50535, 55099, 60087,
- 65535, 35734, 38973, 42500, 46341, 50535, 55109, 60097,
- 32771, 35734, 38965, 42497, 46341, 50535, 55109, 60099
-};
-
-#define EOB 0, 0, 0
-
-static const struct dec_2dvlc intra_dec[7] = {
- {
- { //level / run / table_inc
- { 1, 1, 1 }, { -1, 1, 1 }, { 1, 2, 1 }, { -1, 2, 1 }, { 1, 3, 1 }, { -1, 3, 1 },
- { 1, 4, 1 }, { -1, 4, 1 }, { 1, 5, 1 }, { -1, 5, 1 }, { 1, 6, 1 }, { -1, 6, 1 },
- { 1, 7, 1 }, { -1, 7, 1 }, { 1, 8, 1 }, { -1, 8, 1 }, { 1, 9, 1 }, { -1, 9, 1 },
- { 1, 10, 1 }, { -1, 10, 1 }, { 1, 11, 1 }, { -1, 11, 1 }, { 2, 1, 2 }, { -2, 1, 2 },
- { 1, 12, 1 }, { -1, 12, 1 }, { 1, 13, 1 }, { -1, 13, 1 }, { 1, 14, 1 }, { -1, 14, 1 },
- { 1, 15, 1 }, { -1, 15, 1 }, { 2, 2, 2 }, { -2, 2, 2 }, { 1, 16, 1 }, { -1, 16, 1 },
- { 1, 17, 1 }, { -1, 17, 1 }, { 3, 1, 3 }, { -3, 1, 3 }, { 1, 18, 1 }, { -1, 18, 1 },
- { 1, 19, 1 }, { -1, 19, 1 }, { 2, 3, 2 }, { -2, 3, 2 }, { 1, 20, 1 }, { -1, 20, 1 },
- { 1, 21, 1 }, { -1, 21, 1 }, { 2, 4, 2 }, { -2, 4, 2 }, { 1, 22, 1 }, { -1, 22, 1 },
- { 2, 5, 2 }, { -2, 5, 2 }, { 1, 23, 1 }, { -1, 23, 1 }, { EOB }
- },
- //level_add
- { 0, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1 },
- 2, //golomb_order
- 0, //inc_limit
- 23, //max_run
- },
- {
- { //level / run
- { 1, 1, 0 }, { -1, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 2, 1, 1 }, { -2, 1, 1 },
- { 1, 3, 0 }, { -1, 3, 0 }, { EOB }, { 1, 4, 0 }, { -1, 4, 0 }, { 1, 5, 0 },
- { -1, 5, 0 }, { 1, 6, 0 }, { -1, 6, 0 }, { 3, 1, 2 }, { -3, 1, 2 }, { 2, 2, 1 },
- { -2, 2, 1 }, { 1, 7, 0 }, { -1, 7, 0 }, { 1, 8, 0 }, { -1, 8, 0 }, { 1, 9, 0 },
- { -1, 9, 0 }, { 2, 3, 1 }, { -2, 3, 1 }, { 4, 1, 2 }, { -4, 1, 2 }, { 1, 10, 0 },
- { -1, 10, 0 }, { 1, 11, 0 }, { -1, 11, 0 }, { 2, 4, 1 }, { -2, 4, 1 }, { 3, 2, 2 },
- { -3, 2, 2 }, { 1, 12, 0 }, { -1, 12, 0 }, { 2, 5, 1 }, { -2, 5, 1 }, { 5, 1, 3 },
- { -5, 1, 3 }, { 1, 13, 0 }, { -1, 13, 0 }, { 2, 6, 1 }, { -2, 6, 1 }, { 1, 14, 0 },
- { -1, 14, 0 }, { 2, 7, 1 }, { -2, 7, 1 }, { 2, 8, 1 }, { -2, 8, 1 }, { 3, 3, 2 },
- { -3, 3, 2 }, { 6, 1, 3 }, { -6, 1, 3 }, { 1, 15, 0 }, { -1, 15, 0 }
- },
- //level_add
- { 0, 7, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- 2, //golomb_order
- 1, //inc_limit
- 15, //max_run
- },
- {
- { //level / run
- { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 },
- { 3, 1, 1 }, { -3, 1, 1 }, { EOB }, { 1, 3, 0 }, { -1, 3, 0 }, { 2, 2, 0 },
- { -2, 2, 0 }, { 4, 1, 1 }, { -4, 1, 1 }, { 1, 4, 0 }, { -1, 4, 0 }, { 5, 1, 2 },
- { -5, 1, 2 }, { 1, 5, 0 }, { -1, 5, 0 }, { 3, 2, 1 }, { -3, 2, 1 }, { 2, 3, 0 },
- { -2, 3, 0 }, { 1, 6, 0 }, { -1, 6, 0 }, { 6, 1, 2 }, { -6, 1, 2 }, { 2, 4, 0 },
- { -2, 4, 0 }, { 1, 7, 0 }, { -1, 7, 0 }, { 4, 2, 1 }, { -4, 2, 1 }, { 7, 1, 2 },
- { -7, 1, 2 }, { 3, 3, 1 }, { -3, 3, 1 }, { 2, 5, 0 }, { -2, 5, 0 }, { 1, 8, 0 },
- { -1, 8, 0 }, { 2, 6, 0 }, { -2, 6, 0 }, { 8, 1, 3 }, { -8, 1, 3 }, { 1, 9, 0 },
- { -1, 9, 0 }, { 5, 2, 2 }, { -5, 2, 2 }, { 3, 4, 1 }, { -3, 4, 1 }, { 2, 7, 0 },
- { -2, 7, 0 }, { 9, 1, 3 }, { -9, 1, 3 }, { 1, 10, 0 }, { -1, 10, 0 }
- },
- //level_add
- { 0, 10, 6, 4, 4, 3, 3, 3, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- 2, //golomb_order
- 2, //inc_limit
- 10, //max_run
- },
- {
- { //level / run
- { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 }, { -3, 1, 0 },
- { 1, 2, 0 }, { -1, 2, 0 }, { EOB }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 1 },
- { -5, 1, 1 }, { 2, 2, 0 }, { -2, 2, 0 }, { 1, 3, 0 }, { -1, 3, 0 }, { 6, 1, 1 },
- { -6, 1, 1 }, { 3, 2, 0 }, { -3, 2, 0 }, { 7, 1, 1 }, { -7, 1, 1 }, { 1, 4, 0 },
- { -1, 4, 0 }, { 8, 1, 2 }, { -8, 1, 2 }, { 2, 3, 0 }, { -2, 3, 0 }, { 4, 2, 0 },
- { -4, 2, 0 }, { 1, 5, 0 }, { -1, 5, 0 }, { 9, 1, 2 }, { -9, 1, 2 }, { 5, 2, 1 },
- { -5, 2, 1 }, { 2, 4, 0 }, { -2, 4, 0 }, { 10, 1, 2 }, {-10, 1, 2 }, { 3, 3, 0 },
- { -3, 3, 0 }, { 1, 6, 0 }, { -1, 6, 0 }, { 11, 1, 3 }, {-11, 1, 3 }, { 6, 2, 1 },
- { -6, 2, 1 }, { 1, 7, 0 }, { -1, 7, 0 }, { 2, 5, 0 }, { -2, 5, 0 }, { 3, 4, 0 },
- { -3, 4, 0 }, { 12, 1, 3 }, {-12, 1, 3 }, { 4, 3, 0 }, { -4, 3, 0 }
- },
- //level_add
- { 0, 13, 7, 5, 4, 3, 2, 2, -1, -1, -1 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- 2, //golomb_order
- 4, //inc_limit
- 7, //max_run
- },
- {
- { //level / run
- { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 }, { -3, 1, 0 },
- { EOB }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 0 }, { -5, 1, 0 }, { 6, 1, 0 },
- { -6, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 7, 1, 0 }, { -7, 1, 0 }, { 8, 1, 1 },
- { -8, 1, 1 }, { 2, 2, 0 }, { -2, 2, 0 }, { 9, 1, 1 }, { -9, 1, 1 }, { 10, 1, 1 },
- {-10, 1, 1 }, { 1, 3, 0 }, { -1, 3, 0 }, { 3, 2, 0 }, { -3, 2, 0 }, { 11, 1, 2 },
- {-11, 1, 2 }, { 4, 2, 0 }, { -4, 2, 0 }, { 12, 1, 2 }, {-12, 1, 2 }, { 13, 1, 2 },
- {-13, 1, 2 }, { 5, 2, 0 }, { -5, 2, 0 }, { 1, 4, 0 }, { -1, 4, 0 }, { 2, 3, 0 },
- { -2, 3, 0 }, { 14, 1, 2 }, {-14, 1, 2 }, { 6, 2, 0 }, { -6, 2, 0 }, { 15, 1, 2 },
- {-15, 1, 2 }, { 16, 1, 2 }, {-16, 1, 2 }, { 3, 3, 0 }, { -3, 3, 0 }, { 1, 5, 0 },
- { -1, 5, 0 }, { 7, 2, 0 }, { -7, 2, 0 }, { 17, 1, 2 }, {-17, 1, 2 }
- },
- //level_add
- { 0,18, 8, 4, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- 2, //golomb_order
- 7, //inc_limit
- 5, //max_run
- },
- {
- { //level / run
- { EOB }, { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 },
- { -3, 1, 0 }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 0 }, { -5, 1, 0 }, { 6, 1, 0 },
- { -6, 1, 0 }, { 7, 1, 0 }, { -7, 1, 0 }, { 8, 1, 0 }, { -8, 1, 0 }, { 9, 1, 0 },
- { -9, 1, 0 }, { 10, 1, 0 }, {-10, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 11, 1, 1 },
- {-11, 1, 1 }, { 12, 1, 1 }, {-12, 1, 1 }, { 13, 1, 1 }, {-13, 1, 1 }, { 2, 2, 0 },
- { -2, 2, 0 }, { 14, 1, 1 }, {-14, 1, 1 }, { 15, 1, 1 }, {-15, 1, 1 }, { 3, 2, 0 },
- { -3, 2, 0 }, { 16, 1, 1 }, {-16, 1, 1 }, { 1, 3, 0 }, { -1, 3, 0 }, { 17, 1, 1 },
- {-17, 1, 1 }, { 4, 2, 0 }, { -4, 2, 0 }, { 18, 1, 1 }, {-18, 1, 1 }, { 5, 2, 0 },
- { -5, 2, 0 }, { 19, 1, 1 }, {-19, 1, 1 }, { 20, 1, 1 }, {-20, 1, 1 }, { 6, 2, 0 },
- { -6, 2, 0 }, { 21, 1, 1 }, {-21, 1, 1 }, { 2, 3, 0 }, { -2, 3, 0 }
- },
- //level_add
- { 0, 22, 7, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- 2, //golomb_order
- 10, //inc_limit
- 3, //max_run
- },
- {
- { //level / run
- { EOB }, { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 },
- { -3, 1, 0 }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 0 }, { -5, 1, 0 }, { 6, 1, 0 },
- { -6, 1, 0 }, { 7, 1, 0 }, { -7, 1, 0 }, { 8, 1, 0 }, { -8, 1, 0 }, { 9, 1, 0 },
- { -9, 1, 0 }, { 10, 1, 0 }, {-10, 1, 0 }, { 11, 1, 0 }, {-11, 1, 0 }, { 12, 1, 0 },
- {-12, 1, 0 }, { 13, 1, 0 }, {-13, 1, 0 }, { 14, 1, 0 }, {-14, 1, 0 }, { 15, 1, 0 },
- {-15, 1, 0 }, { 16, 1, 0 }, {-16, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 17, 1, 0 },
- {-17, 1, 0 }, { 18, 1, 0 }, {-18, 1, 0 }, { 19, 1, 0 }, {-19, 1, 0 }, { 20, 1, 0 },
- {-20, 1, 0 }, { 21, 1, 0 }, {-21, 1, 0 }, { 2, 2, 0 }, { -2, 2, 0 }, { 22, 1, 0 },
- {-22, 1, 0 }, { 23, 1, 0 }, {-23, 1, 0 }, { 24, 1, 0 }, {-24, 1, 0 }, { 25, 1, 0 },
- {-25, 1, 0 }, { 3, 2, 0 }, { -3, 2, 0 }, { 26, 1, 0 }, {-26, 1, 0 }
- },
- //level_add
- { 0, 27, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- 2, //golomb_order
- INT_MAX, //inc_limit
- 2, //max_run
- }
-};
-
-static const struct dec_2dvlc inter_dec[7] = {
- {
- { //level / run
- { 1, 1, 1 }, { -1, 1, 1 }, { 1, 2, 1 }, { -1, 2, 1 }, { 1, 3, 1 }, { -1, 3, 1 },
- { 1, 4, 1 }, { -1, 4, 1 }, { 1, 5, 1 }, { -1, 5, 1 }, { 1, 6, 1 }, { -1, 6, 1 },
- { 1, 7, 1 }, { -1, 7, 1 }, { 1, 8, 1 }, { -1, 8, 1 }, { 1, 9, 1 }, { -1, 9, 1 },
- { 1, 10, 1 }, { -1, 10, 1 }, { 1, 11, 1 }, { -1, 11, 1 }, { 1, 12, 1 }, { -1, 12, 1 },
- { 1, 13, 1 }, { -1, 13, 1 }, { 2, 1, 2 }, { -2, 1, 2 }, { 1, 14, 1 }, { -1, 14, 1 },
- { 1, 15, 1 }, { -1, 15, 1 }, { 1, 16, 1 }, { -1, 16, 1 }, { 1, 17, 1 }, { -1, 17, 1 },
- { 1, 18, 1 }, { -1, 18, 1 }, { 1, 19, 1 }, { -1, 19, 1 }, { 3, 1, 3 }, { -3, 1, 3 },
- { 1, 20, 1 }, { -1, 20, 1 }, { 1, 21, 1 }, { -1, 21, 1 }, { 2, 2, 2 }, { -2, 2, 2 },
- { 1, 22, 1 }, { -1, 22, 1 }, { 1, 23, 1 }, { -1, 23, 1 }, { 1, 24, 1 }, { -1, 24, 1 },
- { 1, 25, 1 }, { -1, 25, 1 }, { 1, 26, 1 }, { -1, 26, 1 }, { EOB }
- },
- //level_add
- { 0, 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
- 3, //golomb_order
- 0, //inc_limit
- 26 //max_run
- },
- {
- { //level / run
- { 1, 1, 0 }, { -1, 1, 0 }, { EOB }, { 1, 2, 0 }, { -1, 2, 0 }, { 1, 3, 0 },
- { -1, 3, 0 }, { 1, 4, 0 }, { -1, 4, 0 }, { 1, 5, 0 }, { -1, 5, 0 }, { 1, 6, 0 },
- { -1, 6, 0 }, { 2, 1, 1 }, { -2, 1, 1 }, { 1, 7, 0 }, { -1, 7, 0 }, { 1, 8, 0 },
- { -1, 8, 0 }, { 1, 9, 0 }, { -1, 9, 0 }, { 1, 10, 0 }, { -1, 10, 0 }, { 2, 2, 1 },
- { -2, 2, 1 }, { 1, 11, 0 }, { -1, 11, 0 }, { 1, 12, 0 }, { -1, 12, 0 }, { 3, 1, 2 },
- { -3, 1, 2 }, { 1, 13, 0 }, { -1, 13, 0 }, { 1, 14, 0 }, { -1, 14, 0 }, { 2, 3, 1 },
- { -2, 3, 1 }, { 1, 15, 0 }, { -1, 15, 0 }, { 2, 4, 1 }, { -2, 4, 1 }, { 1, 16, 0 },
- { -1, 16, 0 }, { 2, 5, 1 }, { -2, 5, 1 }, { 1, 17, 0 }, { -1, 17, 0 }, { 4, 1, 3 },
- { -4, 1, 3 }, { 2, 6, 1 }, { -2, 6, 1 }, { 1, 18, 0 }, { -1, 18, 0 }, { 1, 19, 0 },
- { -1, 19, 0 }, { 2, 7, 1 }, { -2, 7, 1 }, { 3, 2, 2 }, { -3, 2, 2 }
- },
- //level_add
- { 0, 5, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1 },
- 2, //golomb_order
- 1, //inc_limit
- 19 //max_run
- },
- {
- { //level / run
- { 1, 1, 0 }, { -1, 1, 0 }, { EOB }, { 1, 2, 0 }, { -1, 2, 0 }, { 2, 1, 0 },
- { -2, 1, 0 }, { 1, 3, 0 }, { -1, 3, 0 }, { 1, 4, 0 }, { -1, 4, 0 }, { 3, 1, 1 },
- { -3, 1, 1 }, { 2, 2, 0 }, { -2, 2, 0 }, { 1, 5, 0 }, { -1, 5, 0 }, { 1, 6, 0 },
- { -1, 6, 0 }, { 1, 7, 0 }, { -1, 7, 0 }, { 2, 3, 0 }, { -2, 3, 0 }, { 4, 1, 2 },
- { -4, 1, 2 }, { 1, 8, 0 }, { -1, 8, 0 }, { 3, 2, 1 }, { -3, 2, 1 }, { 2, 4, 0 },
- { -2, 4, 0 }, { 1, 9, 0 }, { -1, 9, 0 }, { 1, 10, 0 }, { -1, 10, 0 }, { 5, 1, 2 },
- { -5, 1, 2 }, { 2, 5, 0 }, { -2, 5, 0 }, { 1, 11, 0 }, { -1, 11, 0 }, { 2, 6, 0 },
- { -2, 6, 0 }, { 1, 12, 0 }, { -1, 12, 0 }, { 3, 3, 1 }, { -3, 3, 1 }, { 6, 1, 2 },
- { -6, 1, 2 }, { 4, 2, 2 }, { -4, 2, 2 }, { 1, 13, 0 }, { -1, 13, 0 }, { 2, 7, 0 },
- { -2, 7, 0 }, { 3, 4, 1 }, { -3, 4, 1 }, { 1, 14, 0 }, { -1, 14, 0 }
- },
- //level_add
- { 0, 7, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- 2, //golomb_order
- 2, //inc_limit
- 14 //max_run
- },
- {
- { //level / run
- { 1, 1, 0 }, { -1, 1, 0 }, { EOB }, { 2, 1, 0 }, { -2, 1, 0 }, { 1, 2, 0 },
- { -1, 2, 0 }, { 3, 1, 0 }, { -3, 1, 0 }, { 1, 3, 0 }, { -1, 3, 0 }, { 2, 2, 0 },
- { -2, 2, 0 }, { 4, 1, 1 }, { -4, 1, 1 }, { 1, 4, 0 }, { -1, 4, 0 }, { 5, 1, 1 },
- { -5, 1, 1 }, { 1, 5, 0 }, { -1, 5, 0 }, { 3, 2, 0 }, { -3, 2, 0 }, { 2, 3, 0 },
- { -2, 3, 0 }, { 1, 6, 0 }, { -1, 6, 0 }, { 6, 1, 1 }, { -6, 1, 1 }, { 2, 4, 0 },
- { -2, 4, 0 }, { 1, 7, 0 }, { -1, 7, 0 }, { 4, 2, 1 }, { -4, 2, 1 }, { 7, 1, 2 },
- { -7, 1, 2 }, { 3, 3, 0 }, { -3, 3, 0 }, { 1, 8, 0 }, { -1, 8, 0 }, { 2, 5, 0 },
- { -2, 5, 0 }, { 8, 1, 2 }, { -8, 1, 2 }, { 1, 9, 0 }, { -1, 9, 0 }, { 3, 4, 0 },
- { -3, 4, 0 }, { 2, 6, 0 }, { -2, 6, 0 }, { 5, 2, 1 }, { -5, 2, 1 }, { 1, 10, 0 },
- { -1, 10, 0 }, { 9, 1, 2 }, { -9, 1, 2 }, { 4, 3, 1 }, { -4, 3, 1 }
- },
- //level_add
- { 0,10, 6, 5, 4, 3, 3, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- 2, //golomb_order
- 3, //inc_limit
- 10 //max_run
- },
- {
- { //level / run
- { 1, 1, 0 }, { -1, 1, 0 }, { EOB }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 },
- { -3, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 0 },
- { -5, 1, 0 }, { 2, 2, 0 }, { -2, 2, 0 }, { 1, 3, 0 }, { -1, 3, 0 }, { 6, 1, 0 },
- { -6, 1, 0 }, { 3, 2, 0 }, { -3, 2, 0 }, { 7, 1, 1 }, { -7, 1, 1 }, { 1, 4, 0 },
- { -1, 4, 0 }, { 8, 1, 1 }, { -8, 1, 1 }, { 2, 3, 0 }, { -2, 3, 0 }, { 4, 2, 0 },
- { -4, 2, 0 }, { 1, 5, 0 }, { -1, 5, 0 }, { 9, 1, 1 }, { -9, 1, 1 }, { 5, 2, 0 },
- { -5, 2, 0 }, { 2, 4, 0 }, { -2, 4, 0 }, { 1, 6, 0 }, { -1, 6, 0 }, { 10, 1, 2 },
- {-10, 1, 2 }, { 3, 3, 0 }, { -3, 3, 0 }, { 11, 1, 2 }, {-11, 1, 2 }, { 1, 7, 0 },
- { -1, 7, 0 }, { 6, 2, 0 }, { -6, 2, 0 }, { 3, 4, 0 }, { -3, 4, 0 }, { 2, 5, 0 },
- { -2, 5, 0 }, { 12, 1, 2 }, {-12, 1, 2 }, { 4, 3, 0 }, { -4, 3, 0 }
- },
- //level_add
- { 0, 13, 7, 5, 4, 3, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- 2, //golomb_order
- 6, //inc_limit
- 7 //max_run
- },
- {
- { //level / run
- { EOB }, { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 },
- { -3, 1, 0 }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 0 }, { -5, 1, 0 }, { 1, 2, 0 },
- { -1, 2, 0 }, { 6, 1, 0 }, { -6, 1, 0 }, { 7, 1, 0 }, { -7, 1, 0 }, { 8, 1, 0 },
- { -8, 1, 0 }, { 2, 2, 0 }, { -2, 2, 0 }, { 9, 1, 0 }, { -9, 1, 0 }, { 1, 3, 0 },
- { -1, 3, 0 }, { 10, 1, 1 }, { -10, 1, 1 }, { 3, 2, 0 }, { -3, 2, 0 }, { 11, 1, 1 },
- { -11, 1, 1 }, { 4, 2, 0 }, { -4, 2, 0 }, { 12, 1, 1 }, { -12, 1, 1 }, { 1, 4, 0 },
- { -1, 4, 0 }, { 2, 3, 0 }, { -2, 3, 0 }, { 13, 1, 1 }, { -13, 1, 1 }, { 5, 2, 0 },
- { -5, 2, 0 }, { 14, 1, 1 }, { -14, 1, 1 }, { 6, 2, 0 }, { -6, 2, 0 }, { 1, 5, 0 },
- { -1, 5, 0 }, { 15, 1, 1 }, { -15, 1, 1 }, { 3, 3, 0 }, { -3, 3, 0 }, { 16, 1, 1 },
- { -16, 1, 1 }, { 2, 4, 0 }, { -2, 4, 0 }, { 7, 2, 0 }, { -7, 2, 0 }
- },
- //level_add
- { 0, 17, 8, 4, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- 2, //golomb_order
- 9, //inc_limit
- 5 //max_run
- },
- {
- { //level / run
- { EOB }, { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 },
- { -3, 1, 0 }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 0 }, { -5, 1, 0 }, { 6, 1, 0 },
- { -6, 1, 0 }, { 7, 1, 0 }, { -7, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 8, 1, 0 },
- { -8, 1, 0 }, { 9, 1, 0 }, { -9, 1, 0 }, { 10, 1, 0 }, { -10, 1, 0 }, { 11, 1, 0 },
- { -11, 1, 0 }, { 12, 1, 0 }, { -12, 1, 0 }, { 2, 2, 0 }, { -2, 2, 0 }, { 13, 1, 0 },
- { -13, 1, 0 }, { 1, 3, 0 }, { -1, 3, 0 }, { 14, 1, 0 }, { -14, 1, 0 }, { 15, 1, 0 },
- { -15, 1, 0 }, { 3, 2, 0 }, { -3, 2, 0 }, { 16, 1, 0 }, { -16, 1, 0 }, { 17, 1, 0 },
- { -17, 1, 0 }, { 18, 1, 0 }, { -18, 1, 0 }, { 4, 2, 0 }, { -4, 2, 0 }, { 19, 1, 0 },
- { -19, 1, 0 }, { 20, 1, 0 }, { -20, 1, 0 }, { 2, 3, 0 }, { -2, 3, 0 }, { 1, 4, 0 },
- { -1, 4, 0 }, { 5, 2, 0 }, { -5, 2, 0 }, { 21, 1, 0 }, { -21, 1, 0 }
- },
- //level_add
- { 0, 22, 6, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- 2, //golomb_order
- INT_MAX, //inc_limit
- 4 //max_run
- }
-};
-
-static const struct dec_2dvlc chroma_dec[5] = {
- {
- { //level / run
- { 1, 1, 1 }, { -1, 1, 1 }, { 1, 2, 1 }, { -1, 2, 1 }, { 1, 3, 1 }, { -1, 3, 1 },
- { 1, 4, 1 }, { -1, 4, 1 }, { 1, 5, 1 }, { -1, 5, 1 }, { 1, 6, 1 }, { -1, 6, 1 },
- { 1, 7, 1 }, { -1, 7, 1 }, { 2, 1, 2 }, { -2, 1, 2 }, { 1, 8, 1 }, { -1, 8, 1 },
- { 1, 9, 1 }, { -1, 9, 1 }, { 1, 10, 1 }, { -1, 10, 1 }, { 1, 11, 1 }, { -1, 11, 1 },
- { 1, 12, 1 }, { -1, 12, 1 }, { 1, 13, 1 }, { -1, 13, 1 }, { 1, 14, 1 }, { -1, 14, 1 },
- { 1, 15, 1 }, { -1, 15, 1 }, { 3, 1, 3 }, { -3, 1, 3 }, { 1, 16, 1 }, { -1, 16, 1 },
- { 1, 17, 1 }, { -1, 17, 1 }, { 1, 18, 1 }, { -1, 18, 1 }, { 1, 19, 1 }, { -1, 19, 1 },
- { 1, 20, 1 }, { -1, 20, 1 }, { 1, 21, 1 }, { -1, 21, 1 }, { 1, 22, 1 }, { -1, 22, 1 },
- { 2, 2, 2 }, { -2, 2, 2 }, { 1, 23, 1 }, { -1, 23, 1 }, { 1, 24, 1 }, { -1, 24, 1 },
- { 1, 25, 1 }, { -1, 25, 1 }, { 4, 1, 3 }, { -4, 1, 3 }, { EOB }
- },
- //level_add
- { 0, 5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1 },
- 2, //golomb_order
- 0, //inc_limit
- 25 //max_run
- },
- {
- { //level / run
- { EOB }, { 1, 1, 0 }, { -1, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 2, 1, 1 },
- { -2, 1, 1 }, { 1, 3, 0 }, { -1, 3, 0 }, { 1, 4, 0 }, { -1, 4, 0 }, { 1, 5, 0 },
- { -1, 5, 0 }, { 1, 6, 0 }, { -1, 6, 0 }, { 3, 1, 2 }, { -3, 1, 2 }, { 1, 7, 0 },
- { -1, 7, 0 }, { 1, 8, 0 }, { -1, 8, 0 }, { 2, 2, 1 }, { -2, 2, 1 }, { 1, 9, 0 },
- { -1, 9, 0 }, { 1, 10, 0 }, { -1, 10, 0 }, { 1, 11, 0 }, { -1, 11, 0 }, { 4, 1, 2 },
- { -4, 1, 2 }, { 1, 12, 0 }, { -1, 12, 0 }, { 1, 13, 0 }, { -1, 13, 0 }, { 1, 14, 0 },
- { -1, 14, 0 }, { 2, 3, 1 }, { -2, 3, 1 }, { 1, 15, 0 }, { -1, 15, 0 }, { 2, 4, 1 },
- { -2, 4, 1 }, { 5, 1, 3 }, { -5, 1, 3 }, { 3, 2, 2 }, { -3, 2, 2 }, { 1, 16, 0 },
- { -1, 16, 0 }, { 1, 17, 0 }, { -1, 17, 0 }, { 1, 18, 0 }, { -1, 18, 0 }, { 2, 5, 1 },
- { -2, 5, 1 }, { 1, 19, 0 }, { -1, 19, 0 }, { 1, 20, 0 }, { -1, 20, 0 }
- },
- //level_add
- { 0, 6, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1 },
- 0, //golomb_order
- 1, //inc_limit
- 20 //max_run
- },
- {
- { //level / run
- { 1, 1, 0 }, { -1, 1, 0 }, { EOB }, { 2, 1, 0 }, { -2, 1, 0 }, { 1, 2, 0 },
- { -1, 2, 0 }, { 3, 1, 1 }, { -3, 1, 1 }, { 1, 3, 0 }, { -1, 3, 0 }, { 4, 1, 1 },
- { -4, 1, 1 }, { 2, 2, 0 }, { -2, 2, 0 }, { 1, 4, 0 }, { -1, 4, 0 }, { 5, 1, 2 },
- { -5, 1, 2 }, { 1, 5, 0 }, { -1, 5, 0 }, { 3, 2, 1 }, { -3, 2, 1 }, { 2, 3, 0 },
- { -2, 3, 0 }, { 1, 6, 0 }, { -1, 6, 0 }, { 6, 1, 2 }, { -6, 1, 2 }, { 1, 7, 0 },
- { -1, 7, 0 }, { 2, 4, 0 }, { -2, 4, 0 }, { 7, 1, 2 }, { -7, 1, 2 }, { 1, 8, 0 },
- { -1, 8, 0 }, { 4, 2, 1 }, { -4, 2, 1 }, { 1, 9, 0 }, { -1, 9, 0 }, { 3, 3, 1 },
- { -3, 3, 1 }, { 2, 5, 0 }, { -2, 5, 0 }, { 2, 6, 0 }, { -2, 6, 0 }, { 8, 1, 2 },
- { -8, 1, 2 }, { 1, 10, 0 }, { -1, 10, 0 }, { 1, 11, 0 }, { -1, 11, 0 }, { 9, 1, 2 },
- { -9, 1, 2 }, { 5, 2, 2 }, { -5, 2, 2 }, { 3, 4, 1 }, { -3, 4, 1 },
- },
- //level_add
- { 0,10, 6, 4, 4, 3, 3, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- 1, //golomb_order
- 2, //inc_limit
- 11 //max_run
- },
- {
- { //level / run
- { EOB }, { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 },
- { -3, 1, 0 }, { 4, 1, 0 }, { -4, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 5, 1, 1 },
- { -5, 1, 1 }, { 2, 2, 0 }, { -2, 2, 0 }, { 6, 1, 1 }, { -6, 1, 1 }, { 1, 3, 0 },
- { -1, 3, 0 }, { 7, 1, 1 }, { -7, 1, 1 }, { 3, 2, 0 }, { -3, 2, 0 }, { 8, 1, 1 },
- { -8, 1, 1 }, { 1, 4, 0 }, { -1, 4, 0 }, { 2, 3, 0 }, { -2, 3, 0 }, { 9, 1, 1 },
- { -9, 1, 1 }, { 4, 2, 0 }, { -4, 2, 0 }, { 1, 5, 0 }, { -1, 5, 0 }, { 10, 1, 1 },
- {-10, 1, 1 }, { 3, 3, 0 }, { -3, 3, 0 }, { 5, 2, 1 }, { -5, 2, 1 }, { 2, 4, 0 },
- { -2, 4, 0 }, { 11, 1, 1 }, {-11, 1, 1 }, { 1, 6, 0 }, { -1, 6, 0 }, { 12, 1, 1 },
- {-12, 1, 1 }, { 1, 7, 0 }, { -1, 7, 0 }, { 6, 2, 1 }, { -6, 2, 1 }, { 13, 1, 1 },
- {-13, 1, 1 }, { 2, 5, 0 }, { -2, 5, 0 }, { 1, 8, 0 }, { -1, 8, 0 },
- },
- //level_add
- { 0, 14, 7, 4, 3, 3, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
- 1, //golomb_order
- 4, //inc_limit
- 8 //max_run
- },
- {
- { //level / run
- { EOB }, { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 },
- { -3, 1, 0 }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 0 }, { -5, 1, 0 }, { 6, 1, 0 },
- { -6, 1, 0 }, { 7, 1, 0 }, { -7, 1, 0 }, { 8, 1, 0 }, { -8, 1, 0 }, { 1, 2, 0 },
- { -1, 2, 0 }, { 9, 1, 0 }, { -9, 1, 0 }, { 10, 1, 0 }, { -10, 1, 0 }, { 11, 1, 0 },
- { -11, 1, 0 }, { 2, 2, 0 }, { -2, 2, 0 }, { 12, 1, 0 }, { -12, 1, 0 }, { 13, 1, 0 },
- { -13, 1, 0 }, { 3, 2, 0 }, { -3, 2, 0 }, { 14, 1, 0 }, { -14, 1, 0 }, { 1, 3, 0 },
- { -1, 3, 0 }, { 15, 1, 0 }, { -15, 1, 0 }, { 4, 2, 0 }, { -4, 2, 0 }, { 16, 1, 0 },
- { -16, 1, 0 }, { 17, 1, 0 }, { -17, 1, 0 }, { 5, 2, 0 }, { -5, 2, 0 }, { 1, 4, 0 },
- { -1, 4, 0 }, { 2, 3, 0 }, { -2, 3, 0 }, { 18, 1, 0 }, { -18, 1, 0 }, { 6, 2, 0 },
- { -6, 2, 0 }, { 19, 1, 0 }, { -19, 1, 0 }, { 1, 5, 0 }, { -1, 5, 0 },
- },
- //level_add
- { 0, 20, 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 },
- 0, //golomb_order
- INT_MAX, //inc_limit
- 5, //max_run
- }
-};
-
-#undef EOB
-
-/*****************************************************************************
- *
- * motion vector prediction
- *
- ****************************************************************************/
-
-static inline void store_mvs(AVSContext *h)
-{
- h->col_mv[h->mbidx * 4 + 0] = h->mv[MV_FWD_X0];
- h->col_mv[h->mbidx * 4 + 1] = h->mv[MV_FWD_X1];
- h->col_mv[h->mbidx * 4 + 2] = h->mv[MV_FWD_X2];
- h->col_mv[h->mbidx * 4 + 3] = h->mv[MV_FWD_X3];
-}
-
-static inline void mv_pred_direct(AVSContext *h, cavs_vector *pmv_fw,
- cavs_vector *col_mv)
-{
- cavs_vector *pmv_bw = pmv_fw + MV_BWD_OFFS;
- int den = h->direct_den[col_mv->ref];
- int m = FF_SIGNBIT(col_mv->x);
-
- pmv_fw->dist = h->dist[1];
- pmv_bw->dist = h->dist[0];
- pmv_fw->ref = 1;
- pmv_bw->ref = 0;
- /* scale the co-located motion vector according to its temporal span */
- pmv_fw->x = (((den + (den * col_mv->x * pmv_fw->dist ^ m) - m - 1) >> 14) ^ m) - m;
- pmv_bw->x = m - (((den + (den * col_mv->x * pmv_bw->dist ^ m) - m - 1) >> 14) ^ m);
- m = FF_SIGNBIT(col_mv->y);
- pmv_fw->y = (((den + (den * col_mv->y * pmv_fw->dist ^ m) - m - 1) >> 14) ^ m) - m;
- pmv_bw->y = m - (((den + (den * col_mv->y * pmv_bw->dist ^ m) - m - 1) >> 14) ^ m);
-}
-
-static inline void mv_pred_sym(AVSContext *h, cavs_vector *src,
- enum cavs_block size)
-{
- cavs_vector *dst = src + MV_BWD_OFFS;
-
- /* backward mv is the scaled and negated forward mv */
- dst->x = -((src->x * h->sym_factor + 256) >> 9);
- dst->y = -((src->y * h->sym_factor + 256) >> 9);
- dst->ref = 0;
- dst->dist = h->dist[0];
- set_mvs(dst, size);
-}
-
-/*****************************************************************************
- *
- * residual data decoding
- *
- ****************************************************************************/
-
-/** kth-order exponential golomb code */
-static inline int get_ue_code(GetBitContext *gb, int order)
-{
- unsigned ret = get_ue_golomb(gb);
- if (ret >= ((1U<<31)>>order)) {
- av_log(NULL, AV_LOG_ERROR, "get_ue_code: value too larger\n");
- return AVERROR_INVALIDDATA;
- }
- if (order) {
- return (ret<<order) + get_bits(gb, order);
- }
- return ret;
-}
-
-static inline int dequant(AVSContext *h, int16_t *level_buf, uint8_t *run_buf,
- int16_t *dst, int mul, int shift, int coeff_num)
-{
- int round = 1 << (shift - 1);
- int pos = -1;
- const uint8_t *scantab = h->scantable.permutated;
-
- /* inverse scan and dequantization */
- while (--coeff_num >= 0) {
- pos += run_buf[coeff_num];
- if (pos > 63) {
- av_log(h->avctx, AV_LOG_ERROR,
- "position out of block bounds at pic %d MB(%d,%d)\n",
- h->cur.poc, h->mbx, h->mby);
- return AVERROR_INVALIDDATA;
- }
- dst[scantab[pos]] = (level_buf[coeff_num] * mul + round) >> shift;
- }
- return 0;
-}
-
-/**
- * decode coefficients from one 8x8 block, dequantize, inverse transform
- * and add them to sample block
- * @param r pointer to 2D VLC table
- * @param esc_golomb_order escape codes are k-golomb with this order k
- * @param qp quantizer
- * @param dst location of sample block
- * @param stride line stride in frame buffer
- */
-static int decode_residual_block(AVSContext *h, GetBitContext *gb,
- const struct dec_2dvlc *r, int esc_golomb_order,
- int qp, uint8_t *dst, int stride)
-{
- int i, esc_code, level, mask, ret;
- unsigned int level_code, run;
- int16_t level_buf[65];
- uint8_t run_buf[65];
- int16_t *block = h->block;
-
- for (i = 0; i < 65; i++) {
- level_code = get_ue_code(gb, r->golomb_order);
- if (level_code >= ESCAPE_CODE) {
- run = ((level_code - ESCAPE_CODE) >> 1) + 1;
- if(run > 64) {
- av_log(h->avctx, AV_LOG_ERROR, "run %d is too large\n", run);
- return AVERROR_INVALIDDATA;
- }
- esc_code = get_ue_code(gb, esc_golomb_order);
- if (esc_code < 0 || esc_code > 32767) {
- av_log(h->avctx, AV_LOG_ERROR, "esc_code invalid\n");
- return AVERROR_INVALIDDATA;
- }
-
- level = esc_code + (run > r->max_run ? 1 : r->level_add[run]);
- while (level > r->inc_limit)
- r++;
- mask = -(level_code & 1);
- level = (level ^ mask) - mask;
- } else {
- level = r->rltab[level_code][0];
- if (!level) //end of block signal
- break;
- run = r->rltab[level_code][1];
- r += r->rltab[level_code][2];
- }
- level_buf[i] = level;
- run_buf[i] = run;
- }
- if ((ret = dequant(h, level_buf, run_buf, block, dequant_mul[qp],
- dequant_shift[qp], i)) < 0)
- return ret;
- h->cdsp.cavs_idct8_add(dst, block, stride);
- h->bdsp.clear_block(block);
- return 0;
-}
-
-
-static inline void decode_residual_chroma(AVSContext *h)
-{
- if (h->cbp & (1 << 4))
- decode_residual_block(h, &h->gb, chroma_dec, 0,
- ff_cavs_chroma_qp[h->qp], h->cu, h->c_stride);
- if (h->cbp & (1 << 5))
- decode_residual_block(h, &h->gb, chroma_dec, 0,
- ff_cavs_chroma_qp[h->qp], h->cv, h->c_stride);
-}
-
-static inline int decode_residual_inter(AVSContext *h)
-{
- int block;
-
- /* get coded block pattern */
- int cbp = get_ue_golomb(&h->gb);
- if (cbp > 63U) {
- av_log(h->avctx, AV_LOG_ERROR, "illegal inter cbp %d\n", cbp);
- return AVERROR_INVALIDDATA;
- }
- h->cbp = cbp_tab[cbp][1];
-
- /* get quantizer */
- if (h->cbp && !h->qp_fixed)
- h->qp = (h->qp + get_se_golomb(&h->gb)) & 63;
- for (block = 0; block < 4; block++)
- if (h->cbp & (1 << block))
- decode_residual_block(h, &h->gb, inter_dec, 0, h->qp,
- h->cy + h->luma_scan[block], h->l_stride);
- decode_residual_chroma(h);
-
- return 0;
-}
-
-/*****************************************************************************
- *
- * macroblock level
- *
- ****************************************************************************/
-
-static inline void set_mv_intra(AVSContext *h)
-{
- h->mv[MV_FWD_X0] = ff_cavs_intra_mv;
- set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
- h->mv[MV_BWD_X0] = ff_cavs_intra_mv;
- set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
- if (h->cur.f->pict_type != AV_PICTURE_TYPE_B)
- h->col_type_base[h->mbidx] = I_8X8;
-}
-
-static int decode_mb_i(AVSContext *h, int cbp_code)
-{
- GetBitContext *gb = &h->gb;
- unsigned pred_mode_uv;
- int block;
- uint8_t top[18];
- uint8_t *left = NULL;
- uint8_t *d;
-
- ff_cavs_init_mb(h);
-
- /* get intra prediction modes from stream */
- for (block = 0; block < 4; block++) {
- int nA, nB, predpred;
- int pos = scan3x3[block];
-
- nA = h->pred_mode_Y[pos - 1];
- nB = h->pred_mode_Y[pos - 3];
- predpred = FFMIN(nA, nB);
- if (predpred == NOT_AVAIL) // if either is not available
- predpred = INTRA_L_LP;
- if (!get_bits1(gb)) {
- int rem_mode = get_bits(gb, 2);
- predpred = rem_mode + (rem_mode >= predpred);
- }
- h->pred_mode_Y[pos] = predpred;
- }
- pred_mode_uv = get_ue_golomb(gb);
- if (pred_mode_uv > 6) {
- av_log(h->avctx, AV_LOG_ERROR, "illegal intra chroma pred mode\n");
- return AVERROR_INVALIDDATA;
- }
- ff_cavs_modify_mb_i(h, &pred_mode_uv);
-
- /* get coded block pattern */
- if (h->cur.f->pict_type == AV_PICTURE_TYPE_I)
- cbp_code = get_ue_golomb(gb);
- if (cbp_code > 63U) {
- av_log(h->avctx, AV_LOG_ERROR, "illegal intra cbp\n");
- return AVERROR_INVALIDDATA;
- }
- h->cbp = cbp_tab[cbp_code][0];
- if (h->cbp && !h->qp_fixed)
- h->qp = (h->qp + get_se_golomb(gb)) & 63; //qp_delta
-
- /* luma intra prediction interleaved with residual decode/transform/add */
- for (block = 0; block < 4; block++) {
- d = h->cy + h->luma_scan[block];
- ff_cavs_load_intra_pred_luma(h, top, &left, block);
- h->intra_pred_l[h->pred_mode_Y[scan3x3[block]]]
- (d, top, left, h->l_stride);
- if (h->cbp & (1<<block))
- decode_residual_block(h, gb, intra_dec, 1, h->qp, d, h->l_stride);
- }
-
- /* chroma intra prediction */
- ff_cavs_load_intra_pred_chroma(h);
- h->intra_pred_c[pred_mode_uv](h->cu, &h->top_border_u[h->mbx * 10],
- h->left_border_u, h->c_stride);
- h->intra_pred_c[pred_mode_uv](h->cv, &h->top_border_v[h->mbx * 10],
- h->left_border_v, h->c_stride);
-
- decode_residual_chroma(h);
- ff_cavs_filter(h, I_8X8);
- set_mv_intra(h);
- return 0;
-}
-
-static inline void set_intra_mode_default(AVSContext *h)
-{
- if (h->stream_revision > 0) {
- h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
- h->top_pred_Y[h->mbx * 2 + 0] = h->top_pred_Y[h->mbx * 2 + 1] = NOT_AVAIL;
- } else {
- h->pred_mode_Y[3] = h->pred_mode_Y[6] = INTRA_L_LP;
- h->top_pred_Y[h->mbx * 2 + 0] = h->top_pred_Y[h->mbx * 2 + 1] = INTRA_L_LP;
- }
-}
-
-static void decode_mb_p(AVSContext *h, enum cavs_mb mb_type)
-{
- GetBitContext *gb = &h->gb;
- int ref[4];
-
- ff_cavs_init_mb(h);
- switch (mb_type) {
- case P_SKIP:
- ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_PSKIP, BLK_16X16, 0);
- break;
- case P_16X16:
- ref[0] = h->ref_flag ? 0 : get_bits1(gb);
- ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, ref[0]);
- break;
- case P_16X8:
- ref[0] = h->ref_flag ? 0 : get_bits1(gb);
- ref[2] = h->ref_flag ? 0 : get_bits1(gb);
- ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_TOP, BLK_16X8, ref[0]);
- ff_cavs_mv(h, MV_FWD_X2, MV_FWD_A1, MV_PRED_LEFT, BLK_16X8, ref[2]);
- break;
- case P_8X16:
- ref[0] = h->ref_flag ? 0 : get_bits1(gb);
- ref[1] = h->ref_flag ? 0 : get_bits1(gb);
- ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT, BLK_8X16, ref[0]);
- ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_TOPRIGHT, BLK_8X16, ref[1]);
- break;
- case P_8X8:
- ref[0] = h->ref_flag ? 0 : get_bits1(gb);
- ref[1] = h->ref_flag ? 0 : get_bits1(gb);
- ref[2] = h->ref_flag ? 0 : get_bits1(gb);
- ref[3] = h->ref_flag ? 0 : get_bits1(gb);
- ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_MEDIAN, BLK_8X8, ref[0]);
- ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_MEDIAN, BLK_8X8, ref[1]);
- ff_cavs_mv(h, MV_FWD_X2, MV_FWD_X1, MV_PRED_MEDIAN, BLK_8X8, ref[2]);
- ff_cavs_mv(h, MV_FWD_X3, MV_FWD_X0, MV_PRED_MEDIAN, BLK_8X8, ref[3]);
- }
- ff_cavs_inter(h, mb_type);
- set_intra_mode_default(h);
- store_mvs(h);
- if (mb_type != P_SKIP)
- decode_residual_inter(h);
- ff_cavs_filter(h, mb_type);
- h->col_type_base[h->mbidx] = mb_type;
-}
-
-static int decode_mb_b(AVSContext *h, enum cavs_mb mb_type)
-{
- int block;
- enum cavs_sub_mb sub_type[4];
- int flags;
-
- ff_cavs_init_mb(h);
-
- /* reset all MVs */
- h->mv[MV_FWD_X0] = ff_cavs_dir_mv;
- set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
- h->mv[MV_BWD_X0] = ff_cavs_dir_mv;
- set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
- switch (mb_type) {
- case B_SKIP:
- case B_DIRECT:
- if (!h->col_type_base[h->mbidx]) {
- /* intra MB at co-location, do in-plane prediction */
- ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_BSKIP, BLK_16X16, 1);
- ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_BSKIP, BLK_16X16, 0);
- } else
- /* direct prediction from co-located P MB, block-wise */
- for (block = 0; block < 4; block++)
- mv_pred_direct(h, &h->mv[mv_scan[block]],
- &h->col_mv[h->mbidx * 4 + block]);
- break;
- case B_FWD_16X16:
- ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, 1);
- break;
- case B_SYM_16X16:
- ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, 1);
- mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_16X16);
- break;
- case B_BWD_16X16:
- ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_MEDIAN, BLK_16X16, 0);
- break;
- case B_8X8:
-#define TMP_UNUSED_INX 7
- flags = 0;
- for (block = 0; block < 4; block++)
- sub_type[block] = get_bits(&h->gb, 2);
- for (block = 0; block < 4; block++) {
- switch (sub_type[block]) {
- case B_SUB_DIRECT:
- if (!h->col_type_base[h->mbidx]) {
- /* intra MB at co-location, do in-plane prediction */
- if(flags==0) {
- // if col-MB is a Intra MB, current Block size is 16x16.
- // AVS standard section 9.9.1
- if(block>0){
- h->mv[TMP_UNUSED_INX ] = h->mv[MV_FWD_X0 ];
- h->mv[TMP_UNUSED_INX + MV_BWD_OFFS] = h->mv[MV_FWD_X0 + MV_BWD_OFFS];
- }
- ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2,
- MV_PRED_BSKIP, BLK_8X8, 1);
- ff_cavs_mv(h, MV_FWD_X0+MV_BWD_OFFS,
- MV_FWD_C2+MV_BWD_OFFS,
- MV_PRED_BSKIP, BLK_8X8, 0);
- if(block>0) {
- flags = mv_scan[block];
- h->mv[flags ] = h->mv[MV_FWD_X0 ];
- h->mv[flags + MV_BWD_OFFS] = h->mv[MV_FWD_X0 + MV_BWD_OFFS];
- h->mv[MV_FWD_X0 ] = h->mv[TMP_UNUSED_INX ];
- h->mv[MV_FWD_X0 + MV_BWD_OFFS] = h->mv[TMP_UNUSED_INX + MV_BWD_OFFS];
- } else
- flags = MV_FWD_X0;
- } else {
- h->mv[mv_scan[block] ] = h->mv[flags ];
- h->mv[mv_scan[block] + MV_BWD_OFFS] = h->mv[flags + MV_BWD_OFFS];
- }
- } else
- mv_pred_direct(h, &h->mv[mv_scan[block]],
- &h->col_mv[h->mbidx * 4 + block]);
- break;
- case B_SUB_FWD:
- ff_cavs_mv(h, mv_scan[block], mv_scan[block] - 3,
- MV_PRED_MEDIAN, BLK_8X8, 1);
- break;
- case B_SUB_SYM:
- ff_cavs_mv(h, mv_scan[block], mv_scan[block] - 3,
- MV_PRED_MEDIAN, BLK_8X8, 1);
- mv_pred_sym(h, &h->mv[mv_scan[block]], BLK_8X8);
- break;
- }
- }
-#undef TMP_UNUSED_INX
- for (block = 0; block < 4; block++) {
- if (sub_type[block] == B_SUB_BWD)
- ff_cavs_mv(h, mv_scan[block] + MV_BWD_OFFS,
- mv_scan[block] + MV_BWD_OFFS - 3,
- MV_PRED_MEDIAN, BLK_8X8, 0);
- }
- break;
- default:
- if (mb_type <= B_SYM_16X16) {
- av_log(h->avctx, AV_LOG_ERROR, "Invalid mb_type %d in B frame\n", mb_type);
- return AVERROR_INVALIDDATA;
- }
- av_assert2(mb_type < B_8X8);
- flags = ff_cavs_partition_flags[mb_type];
- if (mb_type & 1) { /* 16x8 macroblock types */
- if (flags & FWD0)
- ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_TOP, BLK_16X8, 1);
- if (flags & SYM0)
- mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_16X8);
- if (flags & FWD1)
- ff_cavs_mv(h, MV_FWD_X2, MV_FWD_A1, MV_PRED_LEFT, BLK_16X8, 1);
- if (flags & SYM1)
- mv_pred_sym(h, &h->mv[MV_FWD_X2], BLK_16X8);
- if (flags & BWD0)
- ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_TOP, BLK_16X8, 0);
- if (flags & BWD1)
- ff_cavs_mv(h, MV_BWD_X2, MV_BWD_A1, MV_PRED_LEFT, BLK_16X8, 0);
- } else { /* 8x16 macroblock types */
- if (flags & FWD0)
- ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT, BLK_8X16, 1);
- if (flags & SYM0)
- mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_8X16);
- if (flags & FWD1)
- ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_TOPRIGHT, BLK_8X16, 1);
- if (flags & SYM1)
- mv_pred_sym(h, &h->mv[MV_FWD_X1], BLK_8X16);
- if (flags & BWD0)
- ff_cavs_mv(h, MV_BWD_X0, MV_BWD_B3, MV_PRED_LEFT, BLK_8X16, 0);
- if (flags & BWD1)
- ff_cavs_mv(h, MV_BWD_X1, MV_BWD_C2, MV_PRED_TOPRIGHT, BLK_8X16, 0);
- }
- }
- ff_cavs_inter(h, mb_type);
- set_intra_mode_default(h);
- if (mb_type != B_SKIP)
- decode_residual_inter(h);
- ff_cavs_filter(h, mb_type);
-
- return 0;
-}
-
-/*****************************************************************************
- *
- * slice level
- *
- ****************************************************************************/
-
-static inline int decode_slice_header(AVSContext *h, GetBitContext *gb)
-{
- if (h->stc > 0xAF)
- av_log(h->avctx, AV_LOG_ERROR, "unexpected start code 0x%02x\n", h->stc);
-
- if (h->stc >= h->mb_height) {
- av_log(h->avctx, AV_LOG_ERROR, "stc 0x%02x is too large\n", h->stc);
- return AVERROR_INVALIDDATA;
- }
-
- h->mby = h->stc;
- h->mbidx = h->mby * h->mb_width;
-
- /* mark top macroblocks as unavailable */
- h->flags &= ~(B_AVAIL | C_AVAIL);
- if (!h->pic_qp_fixed) {
- h->qp_fixed = get_bits1(gb);
- h->qp = get_bits(gb, 6);
- }
- /* inter frame or second slice can have weighting params */
- if ((h->cur.f->pict_type != AV_PICTURE_TYPE_I) ||
- (!h->pic_structure && h->mby >= h->mb_width / 2))
- if (get_bits1(gb)) { //slice_weighting_flag
- av_log(h->avctx, AV_LOG_ERROR,
- "weighted prediction not yet supported\n");
- }
- return 0;
-}
-
-static inline int check_for_slice(AVSContext *h)
-{
- GetBitContext *gb = &h->gb;
- int align;
-
- if (h->mbx)
- return 0;
- align = (-get_bits_count(gb)) & 7;
- /* check for stuffing byte */
- if (!align && (show_bits(gb, 8) == 0x80))
- align = 8;
- if ((show_bits_long(gb, 24 + align) & 0xFFFFFF) == 0x000001) {
- skip_bits_long(gb, 24 + align);
- h->stc = get_bits(gb, 8);
- if (h->stc >= h->mb_height)
- return 0;
- decode_slice_header(h, gb);
- return 1;
- }
- return 0;
-}
-
-/*****************************************************************************
- *
- * frame level
- *
- ****************************************************************************/
-
-static int decode_pic(AVSContext *h)
-{
- int ret;
- int skip_count = -1;
- enum cavs_mb mb_type;
-
- if (!h->top_qp) {
- av_log(h->avctx, AV_LOG_ERROR, "No sequence header decoded yet\n");
- return AVERROR_INVALIDDATA;
- }
-
- av_frame_unref(h->cur.f);
-
- skip_bits(&h->gb, 16);//bbv_dwlay
- if (h->stc == PIC_PB_START_CODE) {
- h->cur.f->pict_type = get_bits(&h->gb, 2) + AV_PICTURE_TYPE_I;
- if (h->cur.f->pict_type > AV_PICTURE_TYPE_B) {
- av_log(h->avctx, AV_LOG_ERROR, "illegal picture type\n");
- return AVERROR_INVALIDDATA;
- }
- /* make sure we have the reference frames we need */
- if (!h->DPB[0].f->data[0] ||
- (!h->DPB[1].f->data[0] && h->cur.f->pict_type == AV_PICTURE_TYPE_B))
- return AVERROR_INVALIDDATA;
- } else {
- h->cur.f->pict_type = AV_PICTURE_TYPE_I;
- if (get_bits1(&h->gb))
- skip_bits(&h->gb, 24);//time_code
- /* old sample clips were all progressive and no low_delay,
- bump stream revision if detected otherwise */
- if (h->low_delay || !(show_bits(&h->gb, 9) & 1))
- h->stream_revision = 1;
- /* similarly test top_field_first and repeat_first_field */
- else if (show_bits(&h->gb, 11) & 3)
- h->stream_revision = 1;
- if (h->stream_revision > 0)
- skip_bits(&h->gb, 1); //marker_bit
- }
-
- ret = ff_get_buffer(h->avctx, h->cur.f, h->cur.f->pict_type == AV_PICTURE_TYPE_B ?
- 0 : AV_GET_BUFFER_FLAG_REF);
- if (ret < 0)
- return ret;
-
- if (!h->edge_emu_buffer) {
- int alloc_size = FFALIGN(FFABS(h->cur.f->linesize[0]) + 32, 32);
- h->edge_emu_buffer = av_mallocz(alloc_size * 2 * 24);
- if (!h->edge_emu_buffer)
- return AVERROR(ENOMEM);
- }
-
- if ((ret = ff_cavs_init_pic(h)) < 0)
- return ret;
- h->cur.poc = get_bits(&h->gb, 8) * 2;
-
- /* get temporal distances and MV scaling factors */
- if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
- h->dist[0] = (h->cur.poc - h->DPB[0].poc) & 511;
- } else {
- h->dist[0] = (h->DPB[0].poc - h->cur.poc) & 511;
- }
- h->dist[1] = (h->cur.poc - h->DPB[1].poc) & 511;
- h->scale_den[0] = h->dist[0] ? 512/h->dist[0] : 0;
- h->scale_den[1] = h->dist[1] ? 512/h->dist[1] : 0;
- if (h->cur.f->pict_type == AV_PICTURE_TYPE_B) {
- h->sym_factor = h->dist[0] * h->scale_den[1];
- } else {
- h->direct_den[0] = h->dist[0] ? 16384 / h->dist[0] : 0;
- h->direct_den[1] = h->dist[1] ? 16384 / h->dist[1] : 0;
- }
-
- if (h->low_delay)
- get_ue_golomb(&h->gb); //bbv_check_times
- h->progressive = get_bits1(&h->gb);
- h->pic_structure = 1;
- if (!h->progressive)
- h->pic_structure = get_bits1(&h->gb);
- if (!h->pic_structure && h->stc == PIC_PB_START_CODE)
- skip_bits1(&h->gb); //advanced_pred_mode_disable
- skip_bits1(&h->gb); //top_field_first
- skip_bits1(&h->gb); //repeat_first_field
- h->pic_qp_fixed =
- h->qp_fixed = get_bits1(&h->gb);
- h->qp = get_bits(&h->gb, 6);
- if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) {
- if (!h->progressive && !h->pic_structure)
- skip_bits1(&h->gb);//what is this?
- skip_bits(&h->gb, 4); //reserved bits
- } else {
- if (!(h->cur.f->pict_type == AV_PICTURE_TYPE_B && h->pic_structure == 1))
- h->ref_flag = get_bits1(&h->gb);
- skip_bits(&h->gb, 4); //reserved bits
- h->skip_mode_flag = get_bits1(&h->gb);
- }
- h->loop_filter_disable = get_bits1(&h->gb);
- if (!h->loop_filter_disable && get_bits1(&h->gb)) {
- h->alpha_offset = get_se_golomb(&h->gb);
- h->beta_offset = get_se_golomb(&h->gb);
- } else {
- h->alpha_offset = h->beta_offset = 0;
- }
- if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) {
- do {
- check_for_slice(h);
- decode_mb_i(h, 0);
- } while (ff_cavs_next_mb(h));
- } else if (h->cur.f->pict_type == AV_PICTURE_TYPE_P) {
- do {
- if (check_for_slice(h))
- skip_count = -1;
- if (h->skip_mode_flag && (skip_count < 0))
- skip_count = get_ue_golomb(&h->gb);
- if (h->skip_mode_flag && skip_count--) {
- decode_mb_p(h, P_SKIP);
- } else {
- mb_type = get_ue_golomb(&h->gb) + P_SKIP + h->skip_mode_flag;
- if (mb_type > P_8X8)
- decode_mb_i(h, mb_type - P_8X8 - 1);
- else
- decode_mb_p(h, mb_type);
- }
- } while (ff_cavs_next_mb(h));
- } else { /* AV_PICTURE_TYPE_B */
- do {
- if (check_for_slice(h))
- skip_count = -1;
- if (h->skip_mode_flag && (skip_count < 0))
- skip_count = get_ue_golomb(&h->gb);
- if (h->skip_mode_flag && skip_count--) {
- decode_mb_b(h, B_SKIP);
- } else {
- mb_type = get_ue_golomb(&h->gb) + B_SKIP + h->skip_mode_flag;
- if (mb_type > B_8X8)
- decode_mb_i(h, mb_type - B_8X8 - 1);
- else
- decode_mb_b(h, mb_type);
- }
- } while (ff_cavs_next_mb(h));
- }
- if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
- av_frame_unref(h->DPB[1].f);
- FFSWAP(AVSFrame, h->cur, h->DPB[1]);
- FFSWAP(AVSFrame, h->DPB[0], h->DPB[1]);
- }
- return 0;
-}
-
-/*****************************************************************************
- *
- * headers and interface
- *
- ****************************************************************************/
-
-static int decode_seq_header(AVSContext *h)
-{
- int frame_rate_code;
- int width, height;
- int ret;
-
- h->profile = get_bits(&h->gb, 8);
- h->level = get_bits(&h->gb, 8);
- skip_bits1(&h->gb); //progressive sequence
-
- width = get_bits(&h->gb, 14);
- height = get_bits(&h->gb, 14);
- if ((h->width || h->height) && (h->width != width || h->height != height)) {
- avpriv_report_missing_feature(h->avctx,
- "Width/height changing in CAVS");
- return AVERROR_PATCHWELCOME;
- }
- if (width <= 0 || height <= 0) {
- av_log(h->avctx, AV_LOG_ERROR, "Dimensions invalid\n");
- return AVERROR_INVALIDDATA;
- }
- skip_bits(&h->gb, 2); //chroma format
- skip_bits(&h->gb, 3); //sample_precision
- h->aspect_ratio = get_bits(&h->gb, 4);
- frame_rate_code = get_bits(&h->gb, 4);
- if (frame_rate_code == 0 || frame_rate_code > 13) {
- av_log(h->avctx, AV_LOG_WARNING,
- "frame_rate_code %d is invalid\n", frame_rate_code);
- frame_rate_code = 1;
- }
-
- skip_bits(&h->gb, 18); //bit_rate_lower
- skip_bits1(&h->gb); //marker_bit
- skip_bits(&h->gb, 12); //bit_rate_upper
- h->low_delay = get_bits1(&h->gb);
-
- ret = ff_set_dimensions(h->avctx, width, height);
- if (ret < 0)
- return ret;
-
- h->width = width;
- h->height = height;
- h->mb_width = (h->width + 15) >> 4;
- h->mb_height = (h->height + 15) >> 4;
- h->avctx->framerate = ff_mpeg12_frame_rate_tab[frame_rate_code];
- if (!h->top_qp)
- return ff_cavs_init_top_lines(h);
- return 0;
-}
-
-static void cavs_flush(AVCodecContext * avctx)
-{
- AVSContext *h = avctx->priv_data;
- h->got_keyframe = 0;
-}
-
-static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *avpkt)
-{
- AVSContext *h = avctx->priv_data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- uint32_t stc = -1;
- int input_size, ret;
- const uint8_t *buf_end;
- const uint8_t *buf_ptr;
-
- if (buf_size == 0) {
- if (!h->low_delay && h->DPB[0].f->data[0]) {
- *got_frame = 1;
- av_frame_move_ref(data, h->DPB[0].f);
- }
- return 0;
- }
-
- h->stc = 0;
-
- buf_ptr = buf;
- buf_end = buf + buf_size;
- for(;;) {
- buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &stc);
- if ((stc & 0xFFFFFE00) || buf_ptr == buf_end) {
- if (!h->stc)
- av_log(h->avctx, AV_LOG_WARNING, "no frame decoded\n");
- return FFMAX(0, buf_ptr - buf);
- }
- input_size = (buf_end - buf_ptr) * 8;
- switch (stc) {
- case CAVS_START_CODE:
- init_get_bits(&h->gb, buf_ptr, input_size);
- decode_seq_header(h);
- break;
- case PIC_I_START_CODE:
- if (!h->got_keyframe) {
- av_frame_unref(h->DPB[0].f);
- av_frame_unref(h->DPB[1].f);
- h->got_keyframe = 1;
- }
- case PIC_PB_START_CODE:
- if (*got_frame)
- av_frame_unref(data);
- *got_frame = 0;
- if (!h->got_keyframe)
- break;
- init_get_bits(&h->gb, buf_ptr, input_size);
- h->stc = stc;
- if (decode_pic(h))
- break;
- *got_frame = 1;
- if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
- if (h->DPB[!h->low_delay].f->data[0]) {
- if ((ret = av_frame_ref(data, h->DPB[!h->low_delay].f)) < 0)
- return ret;
- } else {
- *got_frame = 0;
- }
- } else {
- av_frame_move_ref(data, h->cur.f);
- }
- break;
- case EXT_START_CODE:
- //mpeg_decode_extension(avctx, buf_ptr, input_size);
- break;
- case USER_START_CODE:
- //mpeg_decode_user_data(avctx, buf_ptr, input_size);
- break;
- default:
- if (stc <= SLICE_MAX_START_CODE) {
- init_get_bits(&h->gb, buf_ptr, input_size);
- decode_slice_header(h, &h->gb);
- }
- break;
- }
- }
-}
-
-AVCodec ff_cavs_decoder = {
- .name = "cavs",
- .long_name = NULL_IF_CONFIG_SMALL("Chinese AVS (Audio Video Standard) (AVS1-P2, JiZhun profile)"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_CAVS,
- .priv_data_size = sizeof(AVSContext),
- .init = ff_cavs_init,
- .close = ff_cavs_end,
- .decode = cavs_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
- .flush = cavs_flush,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/cdxl.c b/ffmpeg-2-8-11/libavcodec/cdxl.c
deleted file mode 100644
index 50d514b..0000000
--- a/ffmpeg-2-8-11/libavcodec/cdxl.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * CDXL video decoder
- * Copyright (c) 2011-2012 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
- * Commodore CDXL video decoder
- * @author Paul B Mahol
- */
-
-#define UNCHECKED_BITSTREAM_READER 1
-
-#include "libavutil/intreadwrite.h"
-#include "libavutil/imgutils.h"
-#include "avcodec.h"
-#include "get_bits.h"
-#include "internal.h"
-
-#define BIT_PLANAR 0x00
-#define CHUNKY 0x20
-#define BYTE_PLANAR 0x40
-#define BIT_LINE 0x80
-#define BYTE_LINE 0xC0
-
-typedef struct CDXLVideoContext {
- AVCodecContext *avctx;
- int bpp;
- int format;
- int padded_bits;
- const uint8_t *palette;
- int palette_size;
- const uint8_t *video;
- int video_size;
- uint8_t *new_video;
- int new_video_size;
-} CDXLVideoContext;
-
-static av_cold int cdxl_decode_init(AVCodecContext *avctx)
-{
- CDXLVideoContext *c = avctx->priv_data;
-
- c->new_video_size = 0;
- c->avctx = avctx;
-
- return 0;
-}
-
-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);
- }
-}
-
-static void bitplanar2chunky(CDXLVideoContext *c, int linesize, uint8_t *out)
-{
- GetBitContext gb;
- int x, y, plane;
-
- if (init_get_bits8(&gb, c->video, c->video_size) < 0)
- return;
- for (plane = 0; plane < c->bpp; plane++) {
- for (y = 0; y < c->avctx->height; y++) {
- for (x = 0; x < c->avctx->width; x++)
- out[linesize * y + x] |= get_bits1(&gb) << plane;
- skip_bits(&gb, c->padded_bits);
- }
- }
-}
-
-static void bitline2chunky(CDXLVideoContext *c, int linesize, uint8_t *out)
-{
- GetBitContext gb;
- int x, y, plane;
-
- if (init_get_bits8(&gb, c->video, c->video_size) < 0)
- return;
- for (y = 0; y < c->avctx->height; y++) {
- for (plane = 0; plane < c->bpp; plane++) {
- for (x = 0; x < c->avctx->width; x++)
- out[linesize * y + x] |= get_bits1(&gb) << plane;
- skip_bits(&gb, c->padded_bits);
- }
- }
-}
-
-static void import_format(CDXLVideoContext *c, int linesize, uint8_t *out)
-{
- memset(out, 0, linesize * c->avctx->height);
-
- switch (c->format) {
- case BIT_PLANAR:
- bitplanar2chunky(c, linesize, out);
- break;
- case BIT_LINE:
- bitline2chunky(c, linesize, out);
- break;
- }
-}
-
-static void cdxl_decode_rgb(CDXLVideoContext *c, AVFrame *frame)
-{
- uint32_t *new_palette = (uint32_t *)frame->data[1];
-
- memset(frame->data[1], 0, AVPALETTE_SIZE);
- import_palette(c, new_palette);
- import_format(c, frame->linesize[0], frame->data[0]);
-}
-
-static void cdxl_decode_ham6(CDXLVideoContext *c, AVFrame *frame)
-{
- AVCodecContext *avctx = c->avctx;
- uint32_t new_palette[16], r, g, b;
- uint8_t *ptr, *out, index, op;
- int x, y;
-
- ptr = c->new_video;
- out = frame->data[0];
-
- import_palette(c, new_palette);
- import_format(c, avctx->width, c->new_video);
-
- for (y = 0; y < avctx->height; y++) {
- r = new_palette[0] & 0xFF0000;
- g = new_palette[0] & 0xFF00;
- b = new_palette[0] & 0xFF;
- for (x = 0; x < avctx->width; x++) {
- index = *ptr++;
- op = index >> 4;
- index &= 15;
- switch (op) {
- case 0:
- r = new_palette[index] & 0xFF0000;
- g = new_palette[index] & 0xFF00;
- b = new_palette[index] & 0xFF;
- break;
- case 1:
- b = index * 0x11;
- break;
- case 2:
- r = index * 0x11 << 16;
- break;
- case 3:
- g = index * 0x11 << 8;
- break;
- }
- AV_WL24(out + x * 3, r | g | b);
- }
- out += frame->linesize[0];
- }
-}
-
-static void cdxl_decode_ham8(CDXLVideoContext *c, AVFrame *frame)
-{
- AVCodecContext *avctx = c->avctx;
- uint32_t new_palette[64], r, g, b;
- uint8_t *ptr, *out, index, op;
- int x, y;
-
- ptr = c->new_video;
- out = frame->data[0];
-
- import_palette(c, new_palette);
- import_format(c, avctx->width, c->new_video);
-
- for (y = 0; y < avctx->height; y++) {
- r = new_palette[0] & 0xFF0000;
- g = new_palette[0] & 0xFF00;
- b = new_palette[0] & 0xFF;
- for (x = 0; x < avctx->width; x++) {
- index = *ptr++;
- op = index >> 6;
- index &= 63;
- switch (op) {
- case 0:
- r = new_palette[index] & 0xFF0000;
- g = new_palette[index] & 0xFF00;
- b = new_palette[index] & 0xFF;
- break;
- case 1:
- b = (index << 2) | (b & 3);
- break;
- case 2:
- r = (index << 18) | (r & (3 << 16));
- break;
- case 3:
- g = (index << 10) | (g & (3 << 8));
- break;
- }
- AV_WL24(out + x * 3, r | g | b);
- }
- out += frame->linesize[0];
- }
-}
-
-static int cdxl_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame, AVPacket *pkt)
-{
- CDXLVideoContext *c = avctx->priv_data;
- AVFrame * const p = data;
- int ret, w, h, encoding, aligned_width, buf_size = pkt->size;
- const uint8_t *buf = pkt->data;
-
- if (buf_size < 32)
- return AVERROR_INVALIDDATA;
- encoding = buf[1] & 7;
- c->format = buf[1] & 0xE0;
- w = AV_RB16(&buf[14]);
- h = AV_RB16(&buf[16]);
- c->bpp = buf[19];
- c->palette_size = AV_RB16(&buf[20]);
- c->palette = buf + 32;
- c->video = c->palette + c->palette_size;
- c->video_size = buf_size - c->palette_size - 32;
-
- if (c->palette_size > 512)
- return AVERROR_INVALIDDATA;
- if (buf_size < c->palette_size + 32)
- return AVERROR_INVALIDDATA;
- if (c->bpp < 1)
- return AVERROR_INVALIDDATA;
- if (c->format != BIT_PLANAR && c->format != BIT_LINE) {
- avpriv_request_sample(avctx, "Pixel format 0x%0x", c->format);
- return AVERROR_PATCHWELCOME;
- }
-
- if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
- return ret;
-
- aligned_width = FFALIGN(c->avctx->width, 16);
- c->padded_bits = aligned_width - c->avctx->width;
- if (c->video_size < aligned_width * avctx->height * c->bpp / 8)
- return AVERROR_INVALIDDATA;
- if (!encoding && c->palette_size && c->bpp <= 8) {
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
- } else if (encoding == 1 && (c->bpp == 6 || c->bpp == 8)) {
- if (c->palette_size != (1 << (c->bpp - 1)))
- return AVERROR_INVALIDDATA;
- avctx->pix_fmt = AV_PIX_FMT_BGR24;
- } else {
- avpriv_request_sample(avctx, "Encoding %d and bpp %d",
- encoding, c->bpp);
- return AVERROR_PATCHWELCOME;
- }
-
- if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
- return ret;
- p->pict_type = AV_PICTURE_TYPE_I;
-
- if (encoding) {
- av_fast_padded_malloc(&c->new_video, &c->new_video_size,
- h * w + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!c->new_video)
- return AVERROR(ENOMEM);
- if (c->bpp == 8)
- cdxl_decode_ham8(c, p);
- else
- cdxl_decode_ham6(c, p);
- } else {
- cdxl_decode_rgb(c, p);
- }
- *got_frame = 1;
-
- return buf_size;
-}
-
-static av_cold int cdxl_decode_end(AVCodecContext *avctx)
-{
- CDXLVideoContext *c = avctx->priv_data;
-
- av_freep(&c->new_video);
-
- return 0;
-}
-
-AVCodec ff_cdxl_decoder = {
- .name = "cdxl",
- .long_name = NULL_IF_CONFIG_SMALL("Commodore CDXL video"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_CDXL,
- .priv_data_size = sizeof(CDXLVideoContext),
- .init = cdxl_decode_init,
- .close = cdxl_decode_end,
- .decode = cdxl_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/cinepak.c b/ffmpeg-2-8-11/libavcodec/cinepak.c
deleted file mode 100644
index 58c26dc..0000000
--- a/ffmpeg-2-8-11/libavcodec/cinepak.c
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * Cinepak Video Decoder
- * Copyright (c) 2003 The FFmpeg Project
- *
- * 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
- * Cinepak video decoder
- * @author Ewald Snel <ewald at rambo.its.tudelft.nl>
- *
- * @see For more information on the Cinepak algorithm, visit:
- * http://www.csse.monash.edu.au/~timf/
- * @see For more information on the quirky data inside Sega FILM/CPK files, visit:
- * http://wiki.multimedia.cx/index.php?title=Sega_FILM
- *
- * Cinepak colorspace support (c) 2013 Rl, Aetey Global Technologies AB
- * @author Cinepak colorspace, Rl, Aetey Global Technologies AB
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "libavutil/common.h"
-#include "libavutil/intreadwrite.h"
-#include "avcodec.h"
-#include "internal.h"
-
-
-typedef uint8_t cvid_codebook[12];
-
-#define MAX_STRIPS 32
-
-typedef struct cvid_strip {
- uint16_t id;
- uint16_t x1, y1;
- uint16_t x2, y2;
- cvid_codebook v4_codebook[256];
- cvid_codebook v1_codebook[256];
-} cvid_strip;
-
-typedef struct CinepakContext {
-
- AVCodecContext *avctx;
- AVFrame *frame;
-
- const unsigned char *data;
- int size;
-
- int width, height;
-
- int palette_video;
- cvid_strip strips[MAX_STRIPS];
-
- int sega_film_skip_bytes;
-
- uint32_t pal[256];
-} CinepakContext;
-
-static void cinepak_decode_codebook (cvid_codebook *codebook,
- int chunk_id, int size, const uint8_t *data)
-{
- const uint8_t *eod = (data + size);
- uint32_t flag, mask;
- int i, n;
- uint8_t *p;
-
- /* check if this chunk contains 4- or 6-element vectors */
- n = (chunk_id & 0x04) ? 4 : 6;
- flag = 0;
- mask = 0;
-
- p = codebook[0];
- for (i=0; i < 256; i++) {
- if ((chunk_id & 0x01) && !(mask >>= 1)) {
- if ((data + 4) > eod)
- break;
-
- flag = AV_RB32 (data);
- data += 4;
- mask = 0x80000000;
- }
-
- if (!(chunk_id & 0x01) || (flag & mask)) {
- int k, kk;
-
- if ((data + n) > eod)
- break;
-
- for (k = 0; k < 4; ++k) {
- int r = *data++;
- for (kk = 0; kk < 3; ++kk)
- *p++ = r;
- }
- if (n == 6) {
- int r, g, b, u, v;
- u = *(int8_t *)data++;
- v = *(int8_t *)data++;
- p -= 12;
- for(k=0; k<4; ++k) {
- r = *p++ + v*2;
- g = *p++ - (u/2) - v;
- b = *p + u*2;
- p -= 2;
- *p++ = av_clip_uint8(r);
- *p++ = av_clip_uint8(g);
- *p++ = av_clip_uint8(b);
- }
- }
- } else {
- p += 12;
- }
- }
-}
-
-static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
- int chunk_id, int size, const uint8_t *data)
-{
- const uint8_t *eod = (data + size);
- uint32_t flag, mask;
- uint8_t *cb0, *cb1, *cb2, *cb3;
- int x, y;
- char *ip0, *ip1, *ip2, *ip3;
-
- flag = 0;
- mask = 0;
-
- for (y=strip->y1; y < strip->y2; y+=4) {
-
-/* take care of y dimension not being multiple of 4, such streams exist */
- ip0 = ip1 = ip2 = ip3 = s->frame->data[0] +
- (s->palette_video?strip->x1:strip->x1*3) + (y * s->frame->linesize[0]);
- if(s->avctx->height - y > 1) {
- ip1 = ip0 + s->frame->linesize[0];
- if(s->avctx->height - y > 2) {
- ip2 = ip1 + s->frame->linesize[0];
- if(s->avctx->height - y > 3) {
- ip3 = ip2 + s->frame->linesize[0];
- }
- }
- }
-/* to get the correct picture for not-multiple-of-4 cases let us fill
- * each block from the bottom up, thus possibly overwriting the top line
- * more than once but ending with the correct data in place
- * (instead of in-loop checking) */
-
- for (x=strip->x1; x < strip->x2; x+=4) {
- if ((chunk_id & 0x01) && !(mask >>= 1)) {
- if ((data + 4) > eod)
- return AVERROR_INVALIDDATA;
-
- flag = AV_RB32 (data);
- data += 4;
- mask = 0x80000000;
- }
-
- if (!(chunk_id & 0x01) || (flag & mask)) {
- if (!(chunk_id & 0x02) && !(mask >>= 1)) {
- if ((data + 4) > eod)
- return AVERROR_INVALIDDATA;
-
- flag = AV_RB32 (data);
- data += 4;
- mask = 0x80000000;
- }
-
- if ((chunk_id & 0x02) || (~flag & mask)) {
- uint8_t *p;
- if (data >= eod)
- return AVERROR_INVALIDDATA;
-
- p = strip->v1_codebook[*data++];
- if (s->palette_video) {
- ip3[0] = ip3[1] = ip2[0] = ip2[1] = p[6];
- ip3[2] = ip3[3] = ip2[2] = ip2[3] = p[9];
- ip1[0] = ip1[1] = ip0[0] = ip0[1] = p[0];
- ip1[2] = ip1[3] = ip0[2] = ip0[3] = p[3];
- } else {
- p += 6;
- memcpy(ip3 + 0, p, 3); memcpy(ip3 + 3, p, 3);
- memcpy(ip2 + 0, p, 3); memcpy(ip2 + 3, p, 3);
- p += 3; /* ... + 9 */
- memcpy(ip3 + 6, p, 3); memcpy(ip3 + 9, p, 3);
- memcpy(ip2 + 6, p, 3); memcpy(ip2 + 9, p, 3);
- p -= 9; /* ... + 0 */
- memcpy(ip1 + 0, p, 3); memcpy(ip1 + 3, p, 3);
- memcpy(ip0 + 0, p, 3); memcpy(ip0 + 3, p, 3);
- p += 3; /* ... + 3 */
- memcpy(ip1 + 6, p, 3); memcpy(ip1 + 9, p, 3);
- memcpy(ip0 + 6, p, 3); memcpy(ip0 + 9, p, 3);
- }
-
- } else if (flag & mask) {
- if ((data + 4) > eod)
- return AVERROR_INVALIDDATA;
-
- cb0 = strip->v4_codebook[*data++];
- cb1 = strip->v4_codebook[*data++];
- cb2 = strip->v4_codebook[*data++];
- cb3 = strip->v4_codebook[*data++];
- if (s->palette_video) {
- uint8_t *p;
- p = ip3;
- *p++ = cb2[6];
- *p++ = cb2[9];
- *p++ = cb3[6];
- *p = cb3[9];
- p = ip2;
- *p++ = cb2[0];
- *p++ = cb2[3];
- *p++ = cb3[0];
- *p = cb3[3];
- p = ip1;
- *p++ = cb0[6];
- *p++ = cb0[9];
- *p++ = cb1[6];
- *p = cb1[9];
- p = ip0;
- *p++ = cb0[0];
- *p++ = cb0[3];
- *p++ = cb1[0];
- *p = cb1[3];
- } else {
- memcpy(ip3 + 0, cb2 + 6, 6);
- memcpy(ip3 + 6, cb3 + 6, 6);
- memcpy(ip2 + 0, cb2 + 0, 6);
- memcpy(ip2 + 6, cb3 + 0, 6);
- memcpy(ip1 + 0, cb0 + 6, 6);
- memcpy(ip1 + 6, cb1 + 6, 6);
- memcpy(ip0 + 0, cb0 + 0, 6);
- memcpy(ip0 + 6, cb1 + 0, 6);
- }
-
- }
- }
-
- if (s->palette_video) {
- ip0 += 4; ip1 += 4;
- ip2 += 4; ip3 += 4;
- } else {
- ip0 += 12; ip1 += 12;
- ip2 += 12; ip3 += 12;
- }
- }
- }
-
- return 0;
-}
-
-static int cinepak_decode_strip (CinepakContext *s,
- cvid_strip *strip, const uint8_t *data, int size)
-{
- const uint8_t *eod = (data + size);
- int chunk_id, chunk_size;
-
- /* coordinate sanity checks */
- if (strip->x2 > s->width ||
- strip->y2 > s->height ||
- strip->x1 >= strip->x2 || strip->y1 >= strip->y2)
- return AVERROR_INVALIDDATA;
-
- while ((data + 4) <= eod) {
- chunk_id = data[0];
- chunk_size = AV_RB24 (&data[1]) - 4;
- if(chunk_size < 0)
- return AVERROR_INVALIDDATA;
-
- data += 4;
- chunk_size = ((data + chunk_size) > eod) ? (eod - data) : chunk_size;
-
- switch (chunk_id) {
-
- case 0x20:
- case 0x21:
- case 0x24:
- case 0x25:
- cinepak_decode_codebook (strip->v4_codebook, chunk_id,
- chunk_size, data);
- break;
-
- case 0x22:
- case 0x23:
- case 0x26:
- case 0x27:
- cinepak_decode_codebook (strip->v1_codebook, chunk_id,
- chunk_size, data);
- break;
-
- case 0x30:
- case 0x31:
- case 0x32:
- return cinepak_decode_vectors (s, strip, chunk_id,
- chunk_size, data);
- }
-
- data += chunk_size;
- }
-
- return AVERROR_INVALIDDATA;
-}
-
-static int cinepak_decode (CinepakContext *s)
-{
- const uint8_t *eod = (s->data + s->size);
- int i, result, strip_size, frame_flags, num_strips;
- int y0 = 0;
- int encoded_buf_size;
-
- if (s->size < 10)
- return AVERROR_INVALIDDATA;
-
- frame_flags = s->data[0];
- num_strips = AV_RB16 (&s->data[8]);
- encoded_buf_size = AV_RB24(&s->data[1]);
-
- /* if this is the first frame, check for deviant Sega FILM data */
- if (s->sega_film_skip_bytes == -1) {
- if (!encoded_buf_size) {
- avpriv_request_sample(s->avctx, "encoded_buf_size 0");
- return AVERROR_PATCHWELCOME;
- }
- if (encoded_buf_size != s->size && (s->size % encoded_buf_size) != 0) {
- /* If the encoded frame size differs from the frame size as indicated
- * by the container file, this data likely comes from a Sega FILM/CPK file.
- * If the frame header is followed by the bytes FE 00 00 06 00 00 then
- * this is probably one of the two known files that have 6 extra bytes
- * after the frame header. Else, assume 2 extra bytes. The container
- * size also cannot be a multiple of the encoded size. */
- if (s->size >= 16 &&
- (s->data[10] == 0xFE) &&
- (s->data[11] == 0x00) &&
- (s->data[12] == 0x00) &&
- (s->data[13] == 0x06) &&
- (s->data[14] == 0x00) &&
- (s->data[15] == 0x00))
- s->sega_film_skip_bytes = 6;
- else
- s->sega_film_skip_bytes = 2;
- } else
- s->sega_film_skip_bytes = 0;
- }
-
- s->data += 10 + s->sega_film_skip_bytes;
-
- num_strips = FFMIN(num_strips, MAX_STRIPS);
-
- s->frame->key_frame = 0;
-
- for (i=0; i < num_strips; i++) {
- if ((s->data + 12) > eod)
- return AVERROR_INVALIDDATA;
-
- s->strips[i].id = s->data[0];
-/* zero y1 means "relative to the previous stripe" */
- if (!(s->strips[i].y1 = AV_RB16 (&s->data[4])))
- s->strips[i].y2 = (s->strips[i].y1 = y0) + AV_RB16 (&s->data[8]);
- else
- s->strips[i].y2 = AV_RB16 (&s->data[8]);
- s->strips[i].x1 = AV_RB16 (&s->data[6]);
- s->strips[i].x2 = AV_RB16 (&s->data[10]);
-
- if (s->strips[i].id == 0x10)
- s->frame->key_frame = 1;
-
- strip_size = AV_RB24 (&s->data[1]) - 12;
- if (strip_size < 0)
- return AVERROR_INVALIDDATA;
- s->data += 12;
- strip_size = ((s->data + strip_size) > eod) ? (eod - s->data) : strip_size;
-
- if ((i > 0) && !(frame_flags & 0x01)) {
- memcpy (s->strips[i].v4_codebook, s->strips[i-1].v4_codebook,
- sizeof(s->strips[i].v4_codebook));
- memcpy (s->strips[i].v1_codebook, s->strips[i-1].v1_codebook,
- sizeof(s->strips[i].v1_codebook));
- }
-
- result = cinepak_decode_strip (s, &s->strips[i], s->data, strip_size);
-
- if (result != 0)
- return result;
-
- s->data += strip_size;
- y0 = s->strips[i].y2;
- }
- return 0;
-}
-
-static av_cold int cinepak_decode_init(AVCodecContext *avctx)
-{
- CinepakContext *s = avctx->priv_data;
-
- s->avctx = avctx;
- s->width = (avctx->width + 3) & ~3;
- s->height = (avctx->height + 3) & ~3;
-
- s->sega_film_skip_bytes = -1; /* uninitialized state */
-
- // check for paletted data
- if (avctx->bits_per_coded_sample != 8) {
- s->palette_video = 0;
- avctx->pix_fmt = AV_PIX_FMT_RGB24;
- } else {
- s->palette_video = 1;
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
- }
-
- s->frame = av_frame_alloc();
- if (!s->frame)
- return AVERROR(ENOMEM);
-
- return 0;
-}
-
-static int cinepak_decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int ret = 0, buf_size = avpkt->size;
- CinepakContext *s = avctx->priv_data;
-
- s->data = buf;
- s->size = buf_size;
-
- if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
- return ret;
-
- if (s->palette_video) {
- int 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;
- memcpy(s->pal, pal, AVPALETTE_SIZE);
- } else if (pal) {
- av_log(avctx, AV_LOG_ERROR, "Palette size %d is wrong\n", size);
- }
- }
-
- if ((ret = cinepak_decode(s)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "cinepak_decode failed\n");
- }
-
- if (s->palette_video)
- memcpy (s->frame->data[1], s->pal, AVPALETTE_SIZE);
-
- if ((ret = av_frame_ref(data, s->frame)) < 0)
- return ret;
-
- *got_frame = 1;
-
- /* report that the buffer was completely consumed */
- return buf_size;
-}
-
-static av_cold int cinepak_decode_end(AVCodecContext *avctx)
-{
- CinepakContext *s = avctx->priv_data;
-
- av_frame_free(&s->frame);
-
- return 0;
-}
-
-AVCodec ff_cinepak_decoder = {
- .name = "cinepak",
- .long_name = NULL_IF_CONFIG_SMALL("Cinepak"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_CINEPAK,
- .priv_data_size = sizeof(CinepakContext),
- .init = cinepak_decode_init,
- .close = cinepak_decode_end,
- .decode = cinepak_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/cllc.c b/ffmpeg-2-8-11/libavcodec/cllc.c
deleted file mode 100644
index 1c6902a..0000000
--- a/ffmpeg-2-8-11/libavcodec/cllc.c
+++ /dev/null
@@ -1,499 +0,0 @@
-/*
- * Canopus Lossless Codec decoder
- *
- * Copyright (c) 2012-2013 Derek Buitenhuis
- *
- * 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 <inttypes.h>
-
-#include "libavutil/intreadwrite.h"
-#include "bswapdsp.h"
-#include "canopus.h"
-#include "get_bits.h"
-#include "avcodec.h"
-#include "internal.h"
-
-typedef struct CLLCContext {
- AVCodecContext *avctx;
- BswapDSPContext bdsp;
-
- uint8_t *swapped_buf;
- int swapped_buf_size;
-} CLLCContext;
-
-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 i, j, count;
-
- prefix = 0;
- count = 0;
- num_codes_sum = 0;
-
- num_lens = get_bits(gb, 5);
-
- for (i = 0; i < num_lens; i++) {
- num_codes = get_bits(gb, 9);
- 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;
- }
-
- for (j = 0; j < num_codes; j++) {
- symbols[count] = get_bits(gb, 8);
- bits[count] = i + 1;
- codes[count] = prefix++;
-
- count++;
- }
-
- prefix <<= 1;
- }
-
- return ff_init_vlc_sparse(vlc, 7, count, bits, 1, 1,
- codes, 2, 2, symbols, 1, 1, 0);
-}
-
-/*
- * Unlike the RGB24 read/restore, which reads in a component at a time,
- * ARGB read/restore reads in ARGB quads.
- */
-static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left,
- VLC *vlc, uint8_t *outbuf)
-{
- uint8_t *dst;
- int pred[4];
- int code;
- int i;
-
- OPEN_READER(bits, gb);
-
- dst = outbuf;
- pred[0] = top_left[0];
- pred[1] = top_left[1];
- pred[2] = top_left[2];
- pred[3] = top_left[3];
-
- for (i = 0; i < ctx->avctx->width; i++) {
- /* Always get the alpha component */
- UPDATE_CACHE(bits, gb);
- GET_VLC(code, bits, gb, vlc[0].table, 7, 2);
-
- pred[0] += code;
- dst[0] = pred[0];
-
- /* Skip the components if they are entirely transparent */
- if (dst[0]) {
- /* Red */
- UPDATE_CACHE(bits, gb);
- GET_VLC(code, bits, gb, vlc[1].table, 7, 2);
-
- pred[1] += code;
- dst[1] = pred[1];
-
- /* Green */
- UPDATE_CACHE(bits, gb);
- GET_VLC(code, bits, gb, vlc[2].table, 7, 2);
-
- pred[2] += code;
- dst[2] = pred[2];
-
- /* Blue */
- UPDATE_CACHE(bits, gb);
- GET_VLC(code, bits, gb, vlc[3].table, 7, 2);
-
- pred[3] += code;
- dst[3] = pred[3];
- } else {
- dst[1] = 0;
- dst[2] = 0;
- dst[3] = 0;
- }
-
- dst += 4;
- }
-
- CLOSE_READER(bits, gb);
-
- top_left[0] = outbuf[0];
-
- /* Only stash components if they are not transparent */
- if (top_left[0]) {
- top_left[1] = outbuf[1];
- top_left[2] = outbuf[2];
- top_left[3] = outbuf[3];
- }
-
- return 0;
-}
-
-static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb,
- int *top_left, VLC *vlc, uint8_t *outbuf)
-{
- uint8_t *dst;
- int pred, code;
- int i;
-
- OPEN_READER(bits, gb);
-
- dst = outbuf;
- pred = *top_left;
-
- /* Simultaneously read and restore the line */
- for (i = 0; i < ctx->avctx->width; i++) {
- UPDATE_CACHE(bits, gb);
- GET_VLC(code, bits, gb, vlc->table, 7, 2);
-
- pred += code;
- dst[0] = pred;
- dst += 3;
- }
-
- CLOSE_READER(bits, gb);
-
- /* Stash the first pixel */
- *top_left = outbuf[0];
-
- return 0;
-}
-
-static int read_yuv_component_line(CLLCContext *ctx, GetBitContext *gb,
- int *top_left, VLC *vlc, uint8_t *outbuf,
- int is_chroma)
-{
- int pred, code;
- int i;
-
- OPEN_READER(bits, gb);
-
- pred = *top_left;
-
- /* Simultaneously read and restore the line */
- for (i = 0; i < ctx->avctx->width >> is_chroma; i++) {
- UPDATE_CACHE(bits, gb);
- GET_VLC(code, bits, gb, vlc->table, 7, 2);
-
- pred += code;
- outbuf[i] = pred;
- }
-
- CLOSE_READER(bits, gb);
-
- /* Stash the first pixel */
- *top_left = outbuf[0];
-
- return 0;
-}
-
-static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
-{
- AVCodecContext *avctx = ctx->avctx;
- uint8_t *dst;
- int pred[4];
- int ret;
- int i, j;
- VLC vlc[4];
-
- pred[0] = 0;
- pred[1] = 0x80;
- pred[2] = 0x80;
- pred[3] = 0x80;
-
- dst = pic->data[0];
-
- skip_bits(gb, 16);
-
- /* Read in code table for each plane */
- for (i = 0; i < 4; i++) {
- ret = read_code_table(ctx, gb, &vlc[i]);
- if (ret < 0) {
- for (j = 0; j <= i; j++)
- ff_free_vlc(&vlc[j]);
-
- av_log(ctx->avctx, AV_LOG_ERROR,
- "Could not read code table %d.\n", i);
- return ret;
- }
- }
-
- /* Read in and restore every line */
- for (i = 0; i < avctx->height; i++) {
- read_argb_line(ctx, gb, pred, vlc, dst);
-
- dst += pic->linesize[0];
- }
-
- for (i = 0; i < 4; i++)
- ff_free_vlc(&vlc[i]);
-
- return 0;
-}
-
-static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
-{
- AVCodecContext *avctx = ctx->avctx;
- uint8_t *dst;
- int pred[3];
- int ret;
- int i, j;
- VLC vlc[3];
-
- pred[0] = 0x80;
- pred[1] = 0x80;
- pred[2] = 0x80;
-
- dst = pic->data[0];
-
- skip_bits(gb, 16);
-
- /* Read in code table for each plane */
- for (i = 0; i < 3; i++) {
- ret = read_code_table(ctx, gb, &vlc[i]);
- if (ret < 0) {
- for (j = 0; j <= i; j++)
- ff_free_vlc(&vlc[j]);
-
- av_log(ctx->avctx, AV_LOG_ERROR,
- "Could not read code table %d.\n", i);
- return ret;
- }
- }
-
- /* Read in and restore every line */
- for (i = 0; i < avctx->height; i++) {
- for (j = 0; j < 3; j++)
- read_rgb24_component_line(ctx, gb, &pred[j], &vlc[j], &dst[j]);
-
- dst += pic->linesize[0];
- }
-
- for (i = 0; i < 3; i++)
- ff_free_vlc(&vlc[i]);
-
- return 0;
-}
-
-static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
-{
- AVCodecContext *avctx = ctx->avctx;
- uint8_t block;
- uint8_t *dst[3];
- int pred[3];
- int ret;
- int i, j;
- VLC vlc[2];
-
- pred[0] = 0x80;
- pred[1] = 0x80;
- pred[2] = 0x80;
-
- dst[0] = pic->data[0];
- dst[1] = pic->data[1];
- dst[2] = pic->data[2];
-
- skip_bits(gb, 8);
-
- block = get_bits(gb, 8);
- if (block) {
- avpriv_request_sample(ctx->avctx, "Blocked YUV");
- return AVERROR_PATCHWELCOME;
- }
-
- /* Read in code table for luma and chroma */
- for (i = 0; i < 2; i++) {
- ret = read_code_table(ctx, gb, &vlc[i]);
- if (ret < 0) {
- for (j = 0; j <= i; j++)
- ff_free_vlc(&vlc[j]);
-
- av_log(ctx->avctx, AV_LOG_ERROR,
- "Could not read code table %d.\n", i);
- return ret;
- }
- }
-
- /* Read in and restore every line */
- for (i = 0; i < avctx->height; i++) {
- read_yuv_component_line(ctx, gb, &pred[0], &vlc[0], dst[0], 0); /* Y */
- read_yuv_component_line(ctx, gb, &pred[1], &vlc[1], dst[1], 1); /* U */
- read_yuv_component_line(ctx, gb, &pred[2], &vlc[1], dst[2], 1); /* V */
-
- for (j = 0; j < 3; j++)
- dst[j] += pic->linesize[j];
- }
-
- for (i = 0; i < 2; i++)
- ff_free_vlc(&vlc[i]);
-
- return 0;
-}
-
-static int cllc_decode_frame(AVCodecContext *avctx, void *data,
- int *got_picture_ptr, AVPacket *avpkt)
-{
- CLLCContext *ctx = avctx->priv_data;
- AVFrame *pic = data;
- uint8_t *src = avpkt->data;
- uint32_t info_tag, info_offset;
- int data_size;
- GetBitContext gb;
- int coding_type, ret;
-
- if (avpkt->size < 4 + 4) {
- av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size);
- return AVERROR_INVALIDDATA;
- }
-
- info_offset = 0;
- info_tag = AV_RL32(src);
- if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
- info_offset = AV_RL32(src + 4);
- if (info_offset > UINT32_MAX - 8 || info_offset + 8 > avpkt->size) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n",
- info_offset);
- return AVERROR_INVALIDDATA;
- }
- ff_canopus_parse_info_tag(avctx, src + 8, info_offset);
-
- info_offset += 8;
- src += info_offset;
- }
-
- data_size = (avpkt->size - info_offset) & ~1;
-
- /* Make sure our bswap16'd buffer is big enough */
- av_fast_padded_malloc(&ctx->swapped_buf,
- &ctx->swapped_buf_size, data_size);
- if (!ctx->swapped_buf) {
- av_log(avctx, AV_LOG_ERROR, "Could not allocate swapped buffer.\n");
- return AVERROR(ENOMEM);
- }
-
- /* bswap16 the buffer since CLLC's bitreader works in 16-bit words */
- ctx->bdsp.bswap16_buf((uint16_t *) ctx->swapped_buf, (uint16_t *) src,
- data_size / 2);
-
- if ((ret = init_get_bits8(&gb, ctx->swapped_buf, data_size)) < 0)
- return ret;
-
- /*
- * Read in coding type. The types are as follows:
- *
- * 0 - YUY2
- * 1 - BGR24 (Triples)
- * 2 - BGR24 (Quads)
- * 3 - BGRA
- */
- coding_type = (AV_RL32(src) >> 8) & 0xFF;
- av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type);
-
- switch (coding_type) {
- case 0:
- avctx->pix_fmt = AV_PIX_FMT_YUV422P;
- avctx->bits_per_raw_sample = 8;
-
- if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
- return ret;
-
- ret = decode_yuv_frame(ctx, &gb, pic);
- if (ret < 0)
- return ret;
-
- break;
- case 1:
- case 2:
- avctx->pix_fmt = AV_PIX_FMT_RGB24;
- avctx->bits_per_raw_sample = 8;
-
- if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
- return ret;
-
- ret = decode_rgb24_frame(ctx, &gb, pic);
- if (ret < 0)
- return ret;
-
- break;
- case 3:
- avctx->pix_fmt = AV_PIX_FMT_ARGB;
- avctx->bits_per_raw_sample = 8;
-
- if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
- return ret;
-
- ret = decode_argb_frame(ctx, &gb, pic);
- if (ret < 0)
- return ret;
-
- break;
- default:
- av_log(avctx, AV_LOG_ERROR, "Unknown coding type: %d.\n", coding_type);
- return AVERROR_INVALIDDATA;
- }
-
- pic->key_frame = 1;
- pic->pict_type = AV_PICTURE_TYPE_I;
-
- *got_picture_ptr = 1;
-
- return avpkt->size;
-}
-
-static av_cold int cllc_decode_close(AVCodecContext *avctx)
-{
- CLLCContext *ctx = avctx->priv_data;
-
- av_freep(&ctx->swapped_buf);
-
- return 0;
-}
-
-static av_cold int cllc_decode_init(AVCodecContext *avctx)
-{
- CLLCContext *ctx = avctx->priv_data;
-
- /* Initialize various context values */
- ctx->avctx = avctx;
- ctx->swapped_buf = NULL;
- ctx->swapped_buf_size = 0;
-
- ff_bswapdsp_init(&ctx->bdsp);
-
- return 0;
-}
-
-AVCodec ff_cllc_decoder = {
- .name = "cllc",
- .long_name = NULL_IF_CONFIG_SMALL("Canopus Lossless Codec"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_CLLC,
- .priv_data_size = sizeof(CLLCContext),
- .init = cllc_decode_init,
- .decode = cllc_decode_frame,
- .close = cllc_decode_close,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/dds.c b/ffmpeg-2-8-11/libavcodec/dds.c
deleted file mode 100644
index 9e29ada..0000000
--- a/ffmpeg-2-8-11/libavcodec/dds.c
+++ /dev/null
@@ -1,720 +0,0 @@
-/*
- * DirectDraw Surface image decoder
- * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara at gmail.com>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * DDS decoder
- *
- * https://msdn.microsoft.com/en-us/library/bb943982%28v=vs.85%29.aspx
- */
-
-#include <stdint.h>
-
-#include "libavutil/imgutils.h"
-
-#include "avcodec.h"
-#include "bytestream.h"
-#include "internal.h"
-#include "texturedsp.h"
-#include "thread.h"
-
-#define DDPF_FOURCC (1 << 2)
-#define DDPF_PALETTE (1 << 5)
-#define DDPF_NORMALMAP (1 << 31)
-
-enum DDSPostProc {
- DDS_NONE = 0,
- DDS_ALPHA_EXP,
- DDS_NORMAL_MAP,
- DDS_RAW_YCOCG,
- DDS_SWAP_ALPHA,
- DDS_SWIZZLE_A2XY,
- DDS_SWIZZLE_RBXG,
- DDS_SWIZZLE_RGXB,
- DDS_SWIZZLE_RXBG,
- DDS_SWIZZLE_RXGB,
- DDS_SWIZZLE_XGBR,
- DDS_SWIZZLE_XRBG,
- DDS_SWIZZLE_XGXR,
-};
-
-enum DDSDXGIFormat {
- DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
- DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
- DXGI_FORMAT_R16G16B16A16_UNORM = 11,
- DXGI_FORMAT_R16G16B16A16_UINT = 12,
- DXGI_FORMAT_R16G16B16A16_SNORM = 13,
- DXGI_FORMAT_R16G16B16A16_SINT = 14,
-
- DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
- DXGI_FORMAT_R8G8B8A8_UNORM = 28,
- DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
- DXGI_FORMAT_R8G8B8A8_UINT = 30,
- DXGI_FORMAT_R8G8B8A8_SNORM = 31,
- DXGI_FORMAT_R8G8B8A8_SINT = 32,
-
- DXGI_FORMAT_BC1_TYPELESS = 70,
- DXGI_FORMAT_BC1_UNORM = 71,
- DXGI_FORMAT_BC1_UNORM_SRGB = 72,
- DXGI_FORMAT_BC2_TYPELESS = 73,
- DXGI_FORMAT_BC2_UNORM = 74,
- DXGI_FORMAT_BC2_UNORM_SRGB = 75,
- DXGI_FORMAT_BC3_TYPELESS = 76,
- DXGI_FORMAT_BC3_UNORM = 77,
- DXGI_FORMAT_BC3_UNORM_SRGB = 78,
- DXGI_FORMAT_BC4_TYPELESS = 79,
- DXGI_FORMAT_BC4_UNORM = 80,
- DXGI_FORMAT_BC4_SNORM = 81,
- DXGI_FORMAT_BC5_TYPELESS = 82,
- DXGI_FORMAT_BC5_UNORM = 83,
- DXGI_FORMAT_BC5_SNORM = 84,
- DXGI_FORMAT_B5G6R5_UNORM = 85,
- DXGI_FORMAT_B8G8R8A8_UNORM = 87,
- DXGI_FORMAT_B8G8R8X8_UNORM = 88,
- DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
- DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
- DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
- DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
-};
-
-typedef struct DDSContext {
- TextureDSPContext texdsp;
- GetByteContext gbc;
-
- int compressed;
- int paletted;
- enum DDSPostProc postproc;
-
- const uint8_t *tex_data; // Compressed texture
- int tex_ratio; // Compression ratio
- int slice_count; // Number of slices for threaded operations
-
- /* Pointer to the selected compress or decompress function. */
- int (*tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block);
-} DDSContext;
-
-static int parse_pixel_format(AVCodecContext *avctx)
-{
- DDSContext *ctx = avctx->priv_data;
- GetByteContext *gbc = &ctx->gbc;
- char buf[32];
- uint32_t flags, fourcc, gimp_tag;
- enum DDSDXGIFormat dxgi;
- int size, bpp, r, g, b, a;
- int alpha_exponent, ycocg_classic, ycocg_scaled, normal_map, array;
-
- /* Alternative DDS implementations use reserved1 as custom header. */
- bytestream2_skip(gbc, 4 * 3);
- gimp_tag = bytestream2_get_le32(gbc);
- alpha_exponent = gimp_tag == MKTAG('A', 'E', 'X', 'P');
- ycocg_classic = gimp_tag == MKTAG('Y', 'C', 'G', '1');
- ycocg_scaled = gimp_tag == MKTAG('Y', 'C', 'G', '2');
- bytestream2_skip(gbc, 4 * 7);
-
- /* Now the real DDPF starts. */
- size = bytestream2_get_le32(gbc);
- if (size != 32) {
- av_log(avctx, AV_LOG_ERROR, "Invalid pixel format header %d.\n", size);
- return AVERROR_INVALIDDATA;
- }
- flags = bytestream2_get_le32(gbc);
- ctx->compressed = flags & DDPF_FOURCC;
- ctx->paletted = flags & DDPF_PALETTE;
- normal_map = flags & DDPF_NORMALMAP;
- fourcc = bytestream2_get_le32(gbc);
-
- if (ctx->compressed && ctx->paletted) {
- av_log(avctx, AV_LOG_WARNING,
- "Disabling invalid palette flag for compressed dds.\n");
- ctx->paletted = 0;
- }
-
- bpp = bytestream2_get_le32(gbc); // rgbbitcount
- r = bytestream2_get_le32(gbc); // rbitmask
- g = bytestream2_get_le32(gbc); // gbitmask
- b = bytestream2_get_le32(gbc); // bbitmask
- a = bytestream2_get_le32(gbc); // abitmask
-
- bytestream2_skip(gbc, 4); // caps
- bytestream2_skip(gbc, 4); // caps2
- bytestream2_skip(gbc, 4); // caps3
- bytestream2_skip(gbc, 4); // caps4
- bytestream2_skip(gbc, 4); // reserved2
-
- av_get_codec_tag_string(buf, sizeof(buf), fourcc);
- av_log(avctx, AV_LOG_VERBOSE, "fourcc %s bpp %d "
- "r 0x%x g 0x%x b 0x%x a 0x%x\n", buf, bpp, r, g, b, a);
- if (gimp_tag) {
- av_get_codec_tag_string(buf, sizeof(buf), gimp_tag);
- av_log(avctx, AV_LOG_VERBOSE, "and GIMP-DDS tag %s\n", buf);
- }
-
- if (ctx->compressed)
- avctx->pix_fmt = AV_PIX_FMT_RGBA;
-
- if (ctx->compressed) {
- switch (fourcc) {
- case MKTAG('D', 'X', 'T', '1'):
- ctx->tex_ratio = 8;
- ctx->tex_funct = ctx->texdsp.dxt1a_block;
- break;
- case MKTAG('D', 'X', 'T', '2'):
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.dxt2_block;
- break;
- case MKTAG('D', 'X', 'T', '3'):
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.dxt3_block;
- break;
- case MKTAG('D', 'X', 'T', '4'):
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.dxt4_block;
- break;
- case MKTAG('D', 'X', 'T', '5'):
- ctx->tex_ratio = 16;
- if (ycocg_scaled)
- ctx->tex_funct = ctx->texdsp.dxt5ys_block;
- else if (ycocg_classic)
- ctx->tex_funct = ctx->texdsp.dxt5y_block;
- else
- ctx->tex_funct = ctx->texdsp.dxt5_block;
- break;
- case MKTAG('R', 'X', 'G', 'B'):
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.dxt5_block;
- /* This format may be considered as a normal map,
- * but it is handled differently in a separate postproc. */
- ctx->postproc = DDS_SWIZZLE_RXGB;
- normal_map = 0;
- break;
- case MKTAG('A', 'T', 'I', '1'):
- case MKTAG('B', 'C', '4', 'U'):
- ctx->tex_ratio = 8;
- ctx->tex_funct = ctx->texdsp.rgtc1u_block;
- break;
- case MKTAG('B', 'C', '4', 'S'):
- ctx->tex_ratio = 8;
- ctx->tex_funct = ctx->texdsp.rgtc1s_block;
- break;
- case MKTAG('A', 'T', 'I', '2'):
- /* RGT2 variant with swapped R and G (3Dc)*/
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.dxn3dc_block;
- break;
- case MKTAG('B', 'C', '5', 'U'):
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.rgtc2u_block;
- break;
- case MKTAG('B', 'C', '5', 'S'):
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.rgtc2s_block;
- break;
- case MKTAG('U', 'Y', 'V', 'Y'):
- ctx->compressed = 0;
- avctx->pix_fmt = AV_PIX_FMT_UYVY422;
- break;
- case MKTAG('Y', 'U', 'Y', '2'):
- ctx->compressed = 0;
- avctx->pix_fmt = AV_PIX_FMT_YUYV422;
- break;
- case MKTAG('P', '8', ' ', ' '):
- /* ATI Palette8, same as normal palette */
- ctx->compressed = 0;
- ctx->paletted = 1;
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
- break;
- case MKTAG('D', 'X', '1', '0'):
- /* DirectX 10 extra header */
- dxgi = bytestream2_get_le32(gbc);
- bytestream2_skip(gbc, 4); // resourceDimension
- bytestream2_skip(gbc, 4); // miscFlag
- array = bytestream2_get_le32(gbc);
- bytestream2_skip(gbc, 4); // miscFlag2
-
- if (array != 0)
- av_log(avctx, AV_LOG_VERBOSE,
- "Found array of size %d (ignored).\n", array);
-
- /* Only BC[1-5] are actually compressed. */
- ctx->compressed = (dxgi >= 70) && (dxgi <= 84);
-
- av_log(avctx, AV_LOG_VERBOSE, "DXGI format %d.\n", dxgi);
- switch (dxgi) {
- /* RGB types. */
- case DXGI_FORMAT_R16G16B16A16_TYPELESS:
- case DXGI_FORMAT_R16G16B16A16_FLOAT:
- case DXGI_FORMAT_R16G16B16A16_UNORM:
- case DXGI_FORMAT_R16G16B16A16_UINT:
- case DXGI_FORMAT_R16G16B16A16_SNORM:
- case DXGI_FORMAT_R16G16B16A16_SINT:
- avctx->pix_fmt = AV_PIX_FMT_BGRA64;
- break;
- case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
- avctx->colorspace = AVCOL_SPC_RGB;
- case DXGI_FORMAT_R8G8B8A8_TYPELESS:
- case DXGI_FORMAT_R8G8B8A8_UNORM:
- case DXGI_FORMAT_R8G8B8A8_UINT:
- case DXGI_FORMAT_R8G8B8A8_SNORM:
- case DXGI_FORMAT_R8G8B8A8_SINT:
- avctx->pix_fmt = AV_PIX_FMT_BGRA;
- break;
- case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
- avctx->colorspace = AVCOL_SPC_RGB;
- case DXGI_FORMAT_B8G8R8A8_TYPELESS:
- case DXGI_FORMAT_B8G8R8A8_UNORM:
- avctx->pix_fmt = AV_PIX_FMT_RGBA;
- break;
- case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
- avctx->colorspace = AVCOL_SPC_RGB;
- case DXGI_FORMAT_B8G8R8X8_TYPELESS:
- case DXGI_FORMAT_B8G8R8X8_UNORM:
- avctx->pix_fmt = AV_PIX_FMT_RGBA; // opaque
- break;
- case DXGI_FORMAT_B5G6R5_UNORM:
- avctx->pix_fmt = AV_PIX_FMT_RGB565LE;
- break;
- /* Texture types. */
- case DXGI_FORMAT_BC1_UNORM_SRGB:
- avctx->colorspace = AVCOL_SPC_RGB;
- case DXGI_FORMAT_BC1_TYPELESS:
- case DXGI_FORMAT_BC1_UNORM:
- ctx->tex_ratio = 8;
- ctx->tex_funct = ctx->texdsp.dxt1a_block;
- break;
- case DXGI_FORMAT_BC2_UNORM_SRGB:
- avctx->colorspace = AVCOL_SPC_RGB;
- case DXGI_FORMAT_BC2_TYPELESS:
- case DXGI_FORMAT_BC2_UNORM:
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.dxt3_block;
- break;
- case DXGI_FORMAT_BC3_UNORM_SRGB:
- avctx->colorspace = AVCOL_SPC_RGB;
- case DXGI_FORMAT_BC3_TYPELESS:
- case DXGI_FORMAT_BC3_UNORM:
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.dxt5_block;
- break;
- case DXGI_FORMAT_BC4_TYPELESS:
- case DXGI_FORMAT_BC4_UNORM:
- ctx->tex_ratio = 8;
- ctx->tex_funct = ctx->texdsp.rgtc1u_block;
- break;
- case DXGI_FORMAT_BC4_SNORM:
- ctx->tex_ratio = 8;
- ctx->tex_funct = ctx->texdsp.rgtc1s_block;
- break;
- case DXGI_FORMAT_BC5_TYPELESS:
- case DXGI_FORMAT_BC5_UNORM:
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.rgtc2u_block;
- break;
- case DXGI_FORMAT_BC5_SNORM:
- ctx->tex_ratio = 16;
- ctx->tex_funct = ctx->texdsp.rgtc2s_block;
- break;
- default:
- av_log(avctx, AV_LOG_ERROR,
- "Unsupported DXGI format %d.\n", dxgi);
- return AVERROR_INVALIDDATA;
- }
- break;
- default:
- av_log(avctx, AV_LOG_ERROR, "Unsupported %s fourcc.\n", buf);
- return AVERROR_INVALIDDATA;
- }
- } else if (ctx->paletted) {
- if (bpp == 8) {
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
- } else {
- av_log(avctx, AV_LOG_ERROR, "Unsupported palette bpp %d.\n", bpp);
- return AVERROR_INVALIDDATA;
- }
- } else {
- /* 8 bpp */
- if (bpp == 8 && r == 0xff && g == 0 && b == 0 && a == 0)
- avctx->pix_fmt = AV_PIX_FMT_GRAY8;
- /* 16 bpp */
- else if (bpp == 16 && r == 0xff && g == 0 && b == 0 && a == 0xff00)
- avctx->pix_fmt = AV_PIX_FMT_YA8;
- else if (bpp == 16 && r == 0xffff && g == 0 && b == 0 && a == 0)
- avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
- else if (bpp == 16 && r == 0xf800 && g == 0x7e0 && b == 0x1f && a == 0)
- avctx->pix_fmt = AV_PIX_FMT_RGB565LE;
- /* 24 bpp */
- else if (bpp == 24 && r == 0xff0000 && g == 0xff00 && b == 0xff && a == 0)
- avctx->pix_fmt = AV_PIX_FMT_BGR24;
- /* 32 bpp */
- else if (bpp == 32 && r == 0xff0000 && g == 0xff00 && b == 0xff && a == 0)
- avctx->pix_fmt = AV_PIX_FMT_BGR0; // opaque
- else if (bpp == 32 && r == 0xff && g == 0xff00 && b == 0xff0000 && a == 0)
- avctx->pix_fmt = AV_PIX_FMT_RGB0; // opaque
- else if (bpp == 32 && r == 0xff0000 && g == 0xff00 && b == 0xff && a == 0xff000000)
- avctx->pix_fmt = AV_PIX_FMT_BGRA;
- else if (bpp == 32 && r == 0xff && g == 0xff00 && b == 0xff0000 && a == 0xff000000)
- avctx->pix_fmt = AV_PIX_FMT_RGBA;
- /* give up */
- else {
- av_log(avctx, AV_LOG_ERROR, "Unknown pixel format "
- "[bpp %d r 0x%x g 0x%x b 0x%x a 0x%x].\n", bpp, r, g, b, a);
- return AVERROR_INVALIDDATA;
- }
- }
-
- /* Set any remaining post-proc that should happen before frame is ready. */
- if (alpha_exponent)
- ctx->postproc = DDS_ALPHA_EXP;
- else if (normal_map)
- ctx->postproc = DDS_NORMAL_MAP;
- else if (ycocg_classic && !ctx->compressed)
- ctx->postproc = DDS_RAW_YCOCG;
- else if (avctx->pix_fmt == AV_PIX_FMT_YA8)
- ctx->postproc = DDS_SWAP_ALPHA;
-
- /* ATI/NVidia variants sometimes add swizzling in bpp. */
- switch (bpp) {
- case MKTAG('A', '2', 'X', 'Y'):
- ctx->postproc = DDS_SWIZZLE_A2XY;
- break;
- case MKTAG('x', 'G', 'B', 'R'):
- ctx->postproc = DDS_SWIZZLE_XGBR;
- break;
- case MKTAG('x', 'R', 'B', 'G'):
- ctx->postproc = DDS_SWIZZLE_XRBG;
- break;
- case MKTAG('R', 'B', 'x', 'G'):
- ctx->postproc = DDS_SWIZZLE_RBXG;
- break;
- case MKTAG('R', 'G', 'x', 'B'):
- ctx->postproc = DDS_SWIZZLE_RGXB;
- break;
- case MKTAG('R', 'x', 'B', 'G'):
- ctx->postproc = DDS_SWIZZLE_RXBG;
- break;
- case MKTAG('x', 'G', 'x', 'R'):
- ctx->postproc = DDS_SWIZZLE_XGXR;
- break;
- case MKTAG('A', '2', 'D', '5'):
- ctx->postproc = DDS_NORMAL_MAP;
- break;
- }
-
- return 0;
-}
-
-static int decompress_texture_thread(AVCodecContext *avctx, void *arg,
- int slice, int thread_nb)
-{
- DDSContext *ctx = avctx->priv_data;
- AVFrame *frame = arg;
- const uint8_t *d = ctx->tex_data;
- int w_block = avctx->coded_width / TEXTURE_BLOCK_W;
- int h_block = avctx->coded_height / TEXTURE_BLOCK_H;
- int x, y;
- int start_slice, end_slice;
- int base_blocks_per_slice = h_block / ctx->slice_count;
- int remainder_blocks = h_block % ctx->slice_count;
-
- /* When the frame height (in blocks) doesn't divide evenly between the
- * number of slices, spread the remaining blocks evenly between the first
- * operations */
- start_slice = slice * base_blocks_per_slice;
- /* Add any extra blocks (one per slice) that have been added before this slice */
- start_slice += FFMIN(slice, remainder_blocks);
-
- end_slice = start_slice + base_blocks_per_slice;
- /* Add an extra block if there are still remainder blocks to be accounted for */
- if (slice < remainder_blocks)
- end_slice++;
-
- for (y = start_slice; y < end_slice; y++) {
- uint8_t *p = frame->data[0] + y * frame->linesize[0] * TEXTURE_BLOCK_H;
- int off = y * w_block;
- for (x = 0; x < w_block; x++) {
- ctx->tex_funct(p + x * 16, frame->linesize[0],
- d + (off + x) * ctx->tex_ratio);
- }
- }
-
- return 0;
-}
-
-static void do_swizzle(AVFrame *frame, int x, int y)
-{
- int i;
- for (i = 0; i < frame->linesize[0] * frame->height; i += 4) {
- uint8_t *src = frame->data[0] + i;
- FFSWAP(uint8_t, src[x], src[y]);
- }
-}
-
-static void run_postproc(AVCodecContext *avctx, AVFrame *frame)
-{
- DDSContext *ctx = avctx->priv_data;
- int i, x_off;
-
- switch (ctx->postproc) {
- case DDS_ALPHA_EXP:
- /* Alpha-exponential mode divides each channel by the maximum
- * R, G or B value, and stores the multiplying factor in the
- * alpha channel. */
- av_log(avctx, AV_LOG_DEBUG, "Post-processing alpha exponent.\n");
-
- for (i = 0; i < frame->linesize[0] * frame->height; i += 4) {
- uint8_t *src = frame->data[0] + i;
- int r = src[0];
- int g = src[1];
- int b = src[2];
- int a = src[3];
-
- src[0] = r * a / 255;
- src[1] = g * a / 255;
- src[2] = b * a / 255;
- src[3] = 255;
- }
- break;
- case DDS_NORMAL_MAP:
- /* Normal maps work in the XYZ color space and they encode
- * X in R or in A, depending on the texture type, Y in G and
- * derive Z with a square root of the distance.
- *
- * http://www.realtimecollisiondetection.net/blog/?p=28 */
- av_log(avctx, AV_LOG_DEBUG, "Post-processing normal map.\n");
-
- x_off = ctx->tex_ratio == 8 ? 0 : 3;
- for (i = 0; i < frame->linesize[0] * frame->height; i += 4) {
- uint8_t *src = frame->data[0] + i;
- int x = src[x_off];
- int y = src[1];
- int z = 127;
-
- int d = (255 * 255 - x * x - y * y) / 2;
- if (d > 0)
- z = rint(sqrtf(d));
-
- src[0] = x;
- src[1] = y;
- src[2] = z;
- src[3] = 255;
- }
- break;
- case DDS_RAW_YCOCG:
- /* Data is Y-Co-Cg-A and not RGBA, but they are represented
- * with the same masks in the DDPF header. */
- av_log(avctx, AV_LOG_DEBUG, "Post-processing raw YCoCg.\n");
-
- for (i = 0; i < frame->linesize[0] * frame->height; i += 4) {
- uint8_t *src = frame->data[0] + i;
- int a = src[0];
- int cg = src[1] - 128;
- int co = src[2] - 128;
- int y = src[3];
-
- src[0] = av_clip_uint8(y + co - cg);
- src[1] = av_clip_uint8(y + cg);
- src[2] = av_clip_uint8(y - co - cg);
- src[3] = a;
- }
- break;
- case DDS_SWAP_ALPHA:
- /* Alpha and Luma are stored swapped. */
- av_log(avctx, AV_LOG_DEBUG, "Post-processing swapped Luma/Alpha.\n");
-
- for (i = 0; i < frame->linesize[0] * frame->height; i += 2) {
- uint8_t *src = frame->data[0] + i;
- FFSWAP(uint8_t, src[0], src[1]);
- }
- break;
- case DDS_SWIZZLE_A2XY:
- /* Swap R and G, often used to restore a standard RGTC2. */
- av_log(avctx, AV_LOG_DEBUG, "Post-processing A2XY swizzle.\n");
- do_swizzle(frame, 0, 1);
- break;
- case DDS_SWIZZLE_RBXG:
- /* Swap G and A, then B and new A (G). */
- av_log(avctx, AV_LOG_DEBUG, "Post-processing RBXG swizzle.\n");
- do_swizzle(frame, 1, 3);
- do_swizzle(frame, 2, 3);
- break;
- case DDS_SWIZZLE_RGXB:
- /* Swap B and A. */
- av_log(avctx, AV_LOG_DEBUG, "Post-processing RGXB swizzle.\n");
- do_swizzle(frame, 2, 3);
- break;
- case DDS_SWIZZLE_RXBG:
- /* Swap G and A. */
- av_log(avctx, AV_LOG_DEBUG, "Post-processing RXBG swizzle.\n");
- do_swizzle(frame, 1, 3);
- break;
- case DDS_SWIZZLE_RXGB:
- /* Swap R and A (misleading name). */
- av_log(avctx, AV_LOG_DEBUG, "Post-processing RXGB swizzle.\n");
- do_swizzle(frame, 0, 3);
- break;
- case DDS_SWIZZLE_XGBR:
- /* Swap B and A, then R and new A (B). */
- av_log(avctx, AV_LOG_DEBUG, "Post-processing XGBR swizzle.\n");
- do_swizzle(frame, 2, 3);
- do_swizzle(frame, 0, 3);
- break;
- case DDS_SWIZZLE_XGXR:
- /* Swap G and A, then R and new A (G), then new R (G) and new G (A).
- * This variant does not store any B component. */
- av_log(avctx, AV_LOG_DEBUG, "Post-processing XGXR swizzle.\n");
- do_swizzle(frame, 1, 3);
- do_swizzle(frame, 0, 3);
- do_swizzle(frame, 0, 1);
- break;
- case DDS_SWIZZLE_XRBG:
- /* Swap G and A, then R and new A (G). */
- av_log(avctx, AV_LOG_DEBUG, "Post-processing XRBG swizzle.\n");
- do_swizzle(frame, 1, 3);
- do_swizzle(frame, 0, 3);
- break;
- }
-}
-
-static int dds_decode(AVCodecContext *avctx, void *data,
- int *got_frame, AVPacket *avpkt)
-{
- DDSContext *ctx = avctx->priv_data;
- GetByteContext *gbc = &ctx->gbc;
- AVFrame *frame = data;
- int mipmap;
- int ret;
-
- ff_texturedsp_init(&ctx->texdsp);
- bytestream2_init(gbc, avpkt->data, avpkt->size);
-
- if (bytestream2_get_bytes_left(gbc) < 128) {
- av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).",
- bytestream2_get_bytes_left(gbc));
- return AVERROR_INVALIDDATA;
- }
-
- if (bytestream2_get_le32(gbc) != MKTAG('D', 'D', 'S', ' ') ||
- bytestream2_get_le32(gbc) != 124) { // header size
- av_log(avctx, AV_LOG_ERROR, "Invalid DDS header.");
- return AVERROR_INVALIDDATA;
- }
-
- bytestream2_skip(gbc, 4); // flags
-
- avctx->height = bytestream2_get_le32(gbc);
- avctx->width = bytestream2_get_le32(gbc);
- ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n",
- avctx->width, avctx->height);
- return ret;
- }
-
- /* Since codec is based on 4x4 blocks, size is aligned to 4. */
- avctx->coded_width = FFALIGN(avctx->width, TEXTURE_BLOCK_W);
- avctx->coded_height = FFALIGN(avctx->height, TEXTURE_BLOCK_H);
-
- bytestream2_skip(gbc, 4); // pitch
- bytestream2_skip(gbc, 4); // depth
- mipmap = bytestream2_get_le32(gbc);
- if (mipmap != 0)
- av_log(avctx, AV_LOG_VERBOSE, "Found %d mipmaps (ignored).\n", mipmap);
-
- /* Extract pixel format information, considering additional elements
- * in reserved1 and reserved2. */
- ret = parse_pixel_format(avctx);
- if (ret < 0)
- return ret;
-
- ret = ff_get_buffer(avctx, frame, 0);
- if (ret < 0)
- return ret;
-
- if (ctx->compressed) {
- int size = (avctx->coded_height / TEXTURE_BLOCK_H) *
- (avctx->coded_width / TEXTURE_BLOCK_W) * ctx->tex_ratio;
- ctx->slice_count = av_clip(avctx->thread_count, 1,
- avctx->coded_height / TEXTURE_BLOCK_H);
-
- if (bytestream2_get_bytes_left(gbc) < size) {
- av_log(avctx, AV_LOG_ERROR,
- "Compressed Buffer is too small (%d < %d).\n",
- bytestream2_get_bytes_left(gbc), size);
- return AVERROR_INVALIDDATA;
- }
-
- /* Use the decompress function on the texture, one block per thread. */
- ctx->tex_data = gbc->buffer;
- avctx->execute2(avctx, decompress_texture_thread, frame, NULL, ctx->slice_count);
- } else {
- int linesize = av_image_get_linesize(avctx->pix_fmt, frame->width, 0);
-
- if (ctx->paletted) {
- int i;
- /* Use the first 1024 bytes as palette, then copy the rest. */
- bytestream2_get_buffer(gbc, frame->data[1], 256 * 4);
- for (i = 0; i < 256; i++)
- AV_WN32(frame->data[1] + i*4,
- (frame->data[1][2+i*4]<<0)+
- (frame->data[1][1+i*4]<<8)+
- (frame->data[1][0+i*4]<<16)+
- (frame->data[1][3+i*4]<<24)
- );
-
- frame->palette_has_changed = 1;
- }
-
- if (bytestream2_get_bytes_left(gbc) < frame->height * linesize) {
- av_log(avctx, AV_LOG_ERROR, "Buffer is too small (%d < %d).\n",
- bytestream2_get_bytes_left(gbc), frame->height * linesize);
- return AVERROR_INVALIDDATA;
- }
-
- av_image_copy_plane(frame->data[0], frame->linesize[0],
- gbc->buffer, linesize,
- linesize, frame->height);
- }
-
- /* Run any post processing here if needed. */
- if (avctx->pix_fmt == AV_PIX_FMT_BGRA ||
- avctx->pix_fmt == AV_PIX_FMT_RGBA ||
- avctx->pix_fmt == AV_PIX_FMT_RGB0 ||
- avctx->pix_fmt == AV_PIX_FMT_BGR0 ||
- avctx->pix_fmt == AV_PIX_FMT_YA8)
- run_postproc(avctx, frame);
-
- /* Frame is ready to be output. */
- frame->pict_type = AV_PICTURE_TYPE_I;
- frame->key_frame = 1;
- *got_frame = 1;
-
- return avpkt->size;
-}
-
-AVCodec ff_dds_decoder = {
- .name = "dds",
- .long_name = NULL_IF_CONFIG_SMALL("DirectDraw Surface image decoder"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_DDS,
- .decode = dds_decode,
- .priv_data_size = sizeof(DDSContext),
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE
-};
diff --git a/ffmpeg-2-8-11/libavcodec/dfa.c b/ffmpeg-2-8-11/libavcodec/dfa.c
deleted file mode 100644
index f45d019..0000000
--- a/ffmpeg-2-8-11/libavcodec/dfa.c
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Chronomaster DFA Video Decoder
- * Copyright (c) 2011 Konstantin Shishkov
- * based on work by Vladimir "VAG" Gneushev
- *
- * 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 <inttypes.h>
-
-#include "avcodec.h"
-#include "bytestream.h"
-#include "internal.h"
-
-#include "libavutil/avassert.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/mem.h"
-
-typedef struct DfaContext {
- uint32_t pal[256];
- uint8_t *frame_buf;
-} DfaContext;
-
-static av_cold int dfa_decode_init(AVCodecContext *avctx)
-{
- DfaContext *s = avctx->priv_data;
-
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
-
- if (!avctx->width || !avctx->height)
- return AVERROR_INVALIDDATA;
-
- av_assert0(av_image_check_size(avctx->width, avctx->height, 0, avctx) >= 0);
-
- s->frame_buf = av_mallocz(avctx->width * avctx->height);
- if (!s->frame_buf)
- return AVERROR(ENOMEM);
-
- return 0;
-}
-
-static int decode_copy(GetByteContext *gb, uint8_t *frame, int width, int height)
-{
- const int size = width * height;
-
- if (bytestream2_get_buffer(gb, frame, size) != size)
- return AVERROR_INVALIDDATA;
- return 0;
-}
-
-static int decode_tsw1(GetByteContext *gb, uint8_t *frame, int width, int height)
-{
- const uint8_t *frame_start = frame;
- const uint8_t *frame_end = frame + width * height;
- int mask = 0x10000, bitbuf = 0;
- int v, count, segments;
- unsigned offset;
-
- segments = bytestream2_get_le32(gb);
- offset = bytestream2_get_le32(gb);
- if (segments == 0 && offset == frame_end - frame)
- return 0; // skip frame
- if (frame_end - frame <= offset)
- return AVERROR_INVALIDDATA;
- frame += offset;
- while (segments--) {
- if (bytestream2_get_bytes_left(gb) < 2)
- return AVERROR_INVALIDDATA;
- if (mask == 0x10000) {
- bitbuf = bytestream2_get_le16u(gb);
- mask = 1;
- }
- if (frame_end - frame < 2)
- return AVERROR_INVALIDDATA;
- if (bitbuf & mask) {
- v = bytestream2_get_le16(gb);
- offset = (v & 0x1FFF) << 1;
- count = ((v >> 13) + 2) << 1;
- if (frame - frame_start < offset || frame_end - frame < count)
- return AVERROR_INVALIDDATA;
- av_memcpy_backptr(frame, offset, count);
- frame += count;
- } else {
- *frame++ = bytestream2_get_byte(gb);
- *frame++ = bytestream2_get_byte(gb);
- }
- mask <<= 1;
- }
-
- return 0;
-}
-
-static int decode_dsw1(GetByteContext *gb, uint8_t *frame, int width, int height)
-{
- const uint8_t *frame_start = frame;
- const uint8_t *frame_end = frame + width * height;
- int mask = 0x10000, bitbuf = 0;
- int v, offset, count, segments;
-
- segments = bytestream2_get_le16(gb);
- while (segments--) {
- if (bytestream2_get_bytes_left(gb) < 2)
- return AVERROR_INVALIDDATA;
- if (mask == 0x10000) {
- bitbuf = bytestream2_get_le16u(gb);
- mask = 1;
- }
- if (frame_end - frame < 2)
- return AVERROR_INVALIDDATA;
- if (bitbuf & mask) {
- v = bytestream2_get_le16(gb);
- offset = (v & 0x1FFF) << 1;
- count = ((v >> 13) + 2) << 1;
- if (frame - frame_start < offset || frame_end - frame < count)
- return AVERROR_INVALIDDATA;
- av_memcpy_backptr(frame, offset, count);
- frame += count;
- } else if (bitbuf & (mask << 1)) {
- frame += bytestream2_get_le16(gb);
- } else {
- *frame++ = bytestream2_get_byte(gb);
- *frame++ = bytestream2_get_byte(gb);
- }
- mask <<= 2;
- }
-
- return 0;
-}
-
-static int decode_dds1(GetByteContext *gb, uint8_t *frame, int width, int height)
-{
- const uint8_t *frame_start = frame;
- const uint8_t *frame_end = frame + width * height;
- int mask = 0x10000, bitbuf = 0;
- int i, v, offset, count, segments;
-
- segments = bytestream2_get_le16(gb);
- while (segments--) {
- if (bytestream2_get_bytes_left(gb) < 2)
- return AVERROR_INVALIDDATA;
- if (mask == 0x10000) {
- bitbuf = bytestream2_get_le16u(gb);
- mask = 1;
- }
-
- if (bitbuf & mask) {
- v = bytestream2_get_le16(gb);
- offset = (v & 0x1FFF) << 2;
- count = ((v >> 13) + 2) << 1;
- if (frame - frame_start < offset || frame_end - frame < count*2 + width)
- return AVERROR_INVALIDDATA;
- for (i = 0; i < count; i++) {
- frame[0] = frame[1] =
- frame[width] = frame[width + 1] = frame[-offset];
-
- frame += 2;
- }
- } else if (bitbuf & (mask << 1)) {
- v = bytestream2_get_le16(gb)*2;
- if (frame - frame_end < v)
- return AVERROR_INVALIDDATA;
- frame += v;
- } else {
- if (frame_end - frame < width + 3)
- return AVERROR_INVALIDDATA;
- frame[0] = frame[1] =
- frame[width] = frame[width + 1] = bytestream2_get_byte(gb);
- frame += 2;
- frame[0] = frame[1] =
- frame[width] = frame[width + 1] = bytestream2_get_byte(gb);
- frame += 2;
- }
- mask <<= 2;
- }
-
- return 0;
-}
-
-static int decode_bdlt(GetByteContext *gb, uint8_t *frame, int width, int height)
-{
- uint8_t *line_ptr;
- int count, lines, segments;
-
- count = bytestream2_get_le16(gb);
- if (count >= height)
- return AVERROR_INVALIDDATA;
- frame += width * count;
- lines = bytestream2_get_le16(gb);
- if (count + lines > height)
- return AVERROR_INVALIDDATA;
-
- while (lines--) {
- if (bytestream2_get_bytes_left(gb) < 1)
- return AVERROR_INVALIDDATA;
- line_ptr = frame;
- frame += width;
- segments = bytestream2_get_byteu(gb);
- while (segments--) {
- if (frame - line_ptr <= bytestream2_peek_byte(gb))
- return AVERROR_INVALIDDATA;
- line_ptr += bytestream2_get_byte(gb);
- count = (int8_t)bytestream2_get_byte(gb);
- if (count >= 0) {
- if (frame - line_ptr < count)
- return AVERROR_INVALIDDATA;
- if (bytestream2_get_buffer(gb, line_ptr, count) != count)
- return AVERROR_INVALIDDATA;
- } else {
- count = -count;
- if (frame - line_ptr < count)
- return AVERROR_INVALIDDATA;
- memset(line_ptr, bytestream2_get_byte(gb), count);
- }
- line_ptr += count;
- }
- }
-
- return 0;
-}
-
-static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height)
-{
- const uint8_t *frame_end = frame + width * height;
- uint8_t *line_ptr;
- int count, i, v, lines, segments;
- int y = 0;
-
- lines = bytestream2_get_le16(gb);
- if (lines > height)
- return AVERROR_INVALIDDATA;
-
- while (lines--) {
- if (bytestream2_get_bytes_left(gb) < 2)
- return AVERROR_INVALIDDATA;
- segments = bytestream2_get_le16u(gb);
- while ((segments & 0xC000) == 0xC000) {
- unsigned skip_lines = -(int16_t)segments;
- unsigned delta = -((int16_t)segments * width);
- if (frame_end - frame <= delta || y + lines + skip_lines > height)
- return AVERROR_INVALIDDATA;
- frame += delta;
- y += skip_lines;
- segments = bytestream2_get_le16(gb);
- }
-
- if (frame_end <= frame)
- return AVERROR_INVALIDDATA;
- if (segments & 0x8000) {
- frame[width - 1] = segments & 0xFF;
- segments = bytestream2_get_le16(gb);
- }
- line_ptr = frame;
- if (frame_end - frame < width)
- return AVERROR_INVALIDDATA;
- frame += width;
- y++;
- while (segments--) {
- if (frame - line_ptr <= bytestream2_peek_byte(gb))
- return AVERROR_INVALIDDATA;
- line_ptr += bytestream2_get_byte(gb);
- count = (int8_t)bytestream2_get_byte(gb);
- if (count >= 0) {
- if (frame - line_ptr < count * 2)
- return AVERROR_INVALIDDATA;
- if (bytestream2_get_buffer(gb, line_ptr, count * 2) != count * 2)
- return AVERROR_INVALIDDATA;
- line_ptr += count * 2;
- } else {
- count = -count;
- if (frame - line_ptr < count * 2)
- return AVERROR_INVALIDDATA;
- v = bytestream2_get_le16(gb);
- for (i = 0; i < count; i++)
- bytestream_put_le16(&line_ptr, v);
- }
- }
- }
-
- return 0;
-}
-
-static int decode_tdlt(GetByteContext *gb, uint8_t *frame, int width, int height)
-{
- const uint8_t *frame_end = frame + width * height;
- uint32_t segments = bytestream2_get_le32(gb);
- int skip, copy;
-
- while (segments--) {
- if (bytestream2_get_bytes_left(gb) < 2)
- return AVERROR_INVALIDDATA;
- copy = bytestream2_get_byteu(gb) * 2;
- skip = bytestream2_get_byteu(gb) * 2;
- if (frame_end - frame < copy + skip ||
- bytestream2_get_bytes_left(gb) < copy)
- return AVERROR_INVALIDDATA;
- frame += skip;
- bytestream2_get_buffer(gb, frame, copy);
- frame += copy;
- }
-
- return 0;
-}
-
-static int decode_blck(GetByteContext *gb, uint8_t *frame, int width, int height)
-{
- memset(frame, 0, width * height);
- return 0;
-}
-
-
-typedef int (*chunk_decoder)(GetByteContext *gb, uint8_t *frame, int width, int height);
-
-static const chunk_decoder decoder[8] = {
- decode_copy, decode_tsw1, decode_bdlt, decode_wdlt,
- decode_tdlt, decode_dsw1, decode_blck, decode_dds1,
-};
-
-static const char* chunk_name[8] = {
- "COPY", "TSW1", "BDLT", "WDLT", "TDLT", "DSW1", "BLCK", "DDS1"
-};
-
-static int dfa_decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- AVFrame *frame = data;
- DfaContext *s = avctx->priv_data;
- GetByteContext gb;
- const uint8_t *buf = avpkt->data;
- uint32_t chunk_type, chunk_size;
- uint8_t *dst;
- int ret;
- int i, pal_elems;
- int version = avctx->extradata_size==2 ? AV_RL16(avctx->extradata) : 0;
-
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
-
- bytestream2_init(&gb, avpkt->data, avpkt->size);
- while (bytestream2_get_bytes_left(&gb) > 0) {
- bytestream2_skip(&gb, 4);
- chunk_size = bytestream2_get_le32(&gb);
- chunk_type = bytestream2_get_le32(&gb);
- if (!chunk_type)
- break;
- if (chunk_type == 1) {
- pal_elems = FFMIN(chunk_size / 3, 256);
- for (i = 0; i < pal_elems; i++) {
- s->pal[i] = bytestream2_get_be24(&gb) << 2;
- s->pal[i] |= 0xFFU << 24 | (s->pal[i] >> 6) & 0x30303;
- }
- frame->palette_has_changed = 1;
- } else if (chunk_type <= 9) {
- if (decoder[chunk_type - 2](&gb, s->frame_buf, avctx->width, avctx->height)) {
- av_log(avctx, AV_LOG_ERROR, "Error decoding %s chunk\n",
- chunk_name[chunk_type - 2]);
- return AVERROR_INVALIDDATA;
- }
- } else {
- av_log(avctx, AV_LOG_WARNING,
- "Ignoring unknown chunk type %"PRIu32"\n",
- chunk_type);
- }
- buf += chunk_size;
- }
-
- buf = s->frame_buf;
- dst = frame->data[0];
- for (i = 0; i < avctx->height; i++) {
- if(version == 0x100) {
- int j;
- for(j = 0; j < avctx->width; j++) {
- dst[j] = buf[ (i&3)*(avctx->width /4) + (j/4) +
- ((j&3)*(avctx->height/4) + (i/4))*avctx->width];
- }
- } else {
- memcpy(dst, buf, avctx->width);
- buf += avctx->width;
- }
- dst += frame->linesize[0];
- }
- memcpy(frame->data[1], s->pal, sizeof(s->pal));
-
- *got_frame = 1;
-
- return avpkt->size;
-}
-
-static av_cold int dfa_decode_end(AVCodecContext *avctx)
-{
- DfaContext *s = avctx->priv_data;
-
- av_freep(&s->frame_buf);
-
- return 0;
-}
-
-AVCodec ff_dfa_decoder = {
- .name = "dfa",
- .long_name = NULL_IF_CONFIG_SMALL("Chronomaster DFA"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_DFA,
- .priv_data_size = sizeof(DfaContext),
- .init = dfa_decode_init,
- .close = dfa_decode_end,
- .decode = dfa_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/diracdec.c b/ffmpeg-2-8-11/libavcodec/diracdec.c
deleted file mode 100644
index 670cc49..0000000
--- a/ffmpeg-2-8-11/libavcodec/diracdec.c
+++ /dev/null
@@ -1,2055 +0,0 @@
-/*
- * Copyright (C) 2007 Marco Gerards <marco at gnu.org>
- * Copyright (C) 2009 David Conrad
- * Copyright (C) 2011 Jordi Ortiz
- *
- * 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
- * Dirac Decoder
- * @author Marco Gerards <marco at gnu.org>, David Conrad, Jordi Ortiz <nenjordi at gmail.com>
- */
-
-#include "avcodec.h"
-#include "get_bits.h"
-#include "bytestream.h"
-#include "internal.h"
-#include "golomb.h"
-#include "dirac_arith.h"
-#include "mpeg12data.h"
-#include "libavcodec/mpegvideo.h"
-#include "mpegvideoencdsp.h"
-#include "dirac_dwt.h"
-#include "dirac.h"
-#include "diracdsp.h"
-#include "videodsp.h"
-
-/**
- * The spec limits the number of wavelet decompositions to 4 for both
- * level 1 (VC-2) and 128 (long-gop default).
- * 5 decompositions is the maximum before >16-bit buffers are needed.
- * Schroedinger allows this for DD 9,7 and 13,7 wavelets only, limiting
- * the others to 4 decompositions (or 3 for the fidelity filter).
- *
- * We use this instead of MAX_DECOMPOSITIONS to save some memory.
- */
-#define MAX_DWT_LEVELS 5
-
-/**
- * The spec limits this to 3 for frame coding, but in practice can be as high as 6
- */
-#define MAX_REFERENCE_FRAMES 8
-#define MAX_DELAY 5 /* limit for main profile for frame coding (TODO: field coding) */
-#define MAX_FRAMES (MAX_REFERENCE_FRAMES + MAX_DELAY + 1)
-#define MAX_QUANT 68 /* max quant for VC-2 */
-#define MAX_BLOCKSIZE 32 /* maximum xblen/yblen we support */
-
-/**
- * DiracBlock->ref flags, if set then the block does MC from the given ref
- */
-#define DIRAC_REF_MASK_REF1 1
-#define DIRAC_REF_MASK_REF2 2
-#define DIRAC_REF_MASK_GLOBAL 4
-
-/**
- * Value of Picture.reference when Picture is not a reference picture, but
- * is held for delayed output.
- */
-#define DELAYED_PIC_REF 4
-
-#define CALC_PADDING(size, depth) \
- (((size + (1 << depth) - 1) >> depth) << depth)
-
-#define DIVRNDUP(a, b) (((a) + (b) - 1) / (b))
-
-typedef struct {
- AVFrame *avframe;
- int interpolated[3]; /* 1 if hpel[] is valid */
- uint8_t *hpel[3][4];
- uint8_t *hpel_base[3][4];
- int reference;
-} DiracFrame;
-
-typedef struct {
- union {
- int16_t mv[2][2];
- int16_t dc[3];
- } u; /* anonymous unions aren't in C99 :( */
- uint8_t ref;
-} DiracBlock;
-
-typedef struct SubBand {
- int level;
- int orientation;
- int stride;
- int width;
- int height;
- int quant;
- IDWTELEM *ibuf;
- struct SubBand *parent;
-
- /* for low delay */
- unsigned length;
- const uint8_t *coeff_data;
-} SubBand;
-
-typedef struct Plane {
- int width;
- int height;
- ptrdiff_t stride;
-
- int idwt_width;
- int idwt_height;
- int idwt_stride;
- IDWTELEM *idwt_buf;
- IDWTELEM *idwt_buf_base;
- IDWTELEM *idwt_tmp;
-
- /* block length */
- uint8_t xblen;
- uint8_t yblen;
- /* block separation (block n+1 starts after this many pixels in block n) */
- uint8_t xbsep;
- uint8_t ybsep;
- /* amount of overspill on each edge (half of the overlap between blocks) */
- uint8_t xoffset;
- uint8_t yoffset;
-
- SubBand band[MAX_DWT_LEVELS][4];
-} Plane;
-
-typedef struct DiracContext {
- AVCodecContext *avctx;
- MpegvideoEncDSPContext mpvencdsp;
- VideoDSPContext vdsp;
- DiracDSPContext diracdsp;
- GetBitContext gb;
- dirac_source_params source;
- int seen_sequence_header;
- int frame_number; /* number of the next frame to display */
- Plane plane[3];
- int chroma_x_shift;
- int chroma_y_shift;
-
- int zero_res; /* zero residue flag */
- int is_arith; /* whether coeffs use arith or golomb coding */
- int low_delay; /* use the low delay syntax */
- int globalmc_flag; /* use global motion compensation */
- int num_refs; /* number of reference pictures */
-
- /* wavelet decoding */
- unsigned wavelet_depth; /* depth of the IDWT */
- unsigned wavelet_idx;
-
- /**
- * schroedinger older than 1.0.8 doesn't store
- * quant delta if only one codebook exists in a band
- */
- unsigned old_delta_quant;
- unsigned codeblock_mode;
-
- struct {
- unsigned width;
- unsigned height;
- } codeblock[MAX_DWT_LEVELS+1];
-
- struct {
- unsigned num_x; /* number of horizontal slices */
- unsigned num_y; /* number of vertical slices */
- AVRational bytes; /* average bytes per slice */
- uint8_t quant[MAX_DWT_LEVELS][4]; /* [DIRAC_STD] E.1 */
- } lowdelay;
-
- struct {
- int pan_tilt[2]; /* pan/tilt vector */
- int zrs[2][2]; /* zoom/rotate/shear matrix */
- int perspective[2]; /* perspective vector */
- unsigned zrs_exp;
- unsigned perspective_exp;
- } globalmc[2];
-
- /* motion compensation */
- uint8_t mv_precision; /* [DIRAC_STD] REFS_WT_PRECISION */
- int16_t weight[2]; /* [DIRAC_STD] REF1_WT and REF2_WT */
- unsigned weight_log2denom; /* [DIRAC_STD] REFS_WT_PRECISION */
-
- int blwidth; /* number of blocks (horizontally) */
- int blheight; /* number of blocks (vertically) */
- int sbwidth; /* number of superblocks (horizontally) */
- int sbheight; /* number of superblocks (vertically) */
-
- uint8_t *sbsplit;
- DiracBlock *blmotion;
-
- uint8_t *edge_emu_buffer[4];
- uint8_t *edge_emu_buffer_base;
-
- uint16_t *mctmp; /* buffer holding the MC data multiplied by OBMC weights */
- uint8_t *mcscratch;
- int buffer_stride;
-
- DECLARE_ALIGNED(16, uint8_t, obmc_weight)[3][MAX_BLOCKSIZE*MAX_BLOCKSIZE];
-
- void (*put_pixels_tab[4])(uint8_t *dst, const uint8_t *src[5], int stride, int h);
- void (*avg_pixels_tab[4])(uint8_t *dst, const uint8_t *src[5], int stride, int h);
- void (*add_obmc)(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen);
- dirac_weight_func weight_func;
- dirac_biweight_func biweight_func;
-
- DiracFrame *current_picture;
- DiracFrame *ref_pics[2];
-
- DiracFrame *ref_frames[MAX_REFERENCE_FRAMES+1];
- DiracFrame *delay_frames[MAX_DELAY+1];
- DiracFrame all_frames[MAX_FRAMES];
-} DiracContext;
-
-/**
- * Dirac Specification ->
- * Parse code values. 9.6.1 Table 9.1
- */
-enum dirac_parse_code {
- pc_seq_header = 0x00,
- pc_eos = 0x10,
- pc_aux_data = 0x20,
- pc_padding = 0x30,
-};
-
-enum dirac_subband {
- subband_ll = 0,
- subband_hl = 1,
- subband_lh = 2,
- subband_hh = 3,
- subband_nb,
-};
-
-static const uint8_t default_qmat[][4][4] = {
- { { 5, 3, 3, 0}, { 0, 4, 4, 1}, { 0, 5, 5, 2}, { 0, 6, 6, 3} },
- { { 4, 2, 2, 0}, { 0, 4, 4, 2}, { 0, 5, 5, 3}, { 0, 7, 7, 5} },
- { { 5, 3, 3, 0}, { 0, 4, 4, 1}, { 0, 5, 5, 2}, { 0, 6, 6, 3} },
- { { 8, 4, 4, 0}, { 0, 4, 4, 0}, { 0, 4, 4, 0}, { 0, 4, 4, 0} },
- { { 8, 4, 4, 0}, { 0, 4, 4, 0}, { 0, 4, 4, 0}, { 0, 4, 4, 0} },
- { { 0, 4, 4, 8}, { 0, 8, 8, 12}, { 0, 13, 13, 17}, { 0, 17, 17, 21} },
- { { 3, 1, 1, 0}, { 0, 4, 4, 2}, { 0, 6, 6, 5}, { 0, 9, 9, 7} },
-};
-
-static const int qscale_tab[MAX_QUANT+1] = {
- 4, 5, 6, 7, 8, 10, 11, 13,
- 16, 19, 23, 27, 32, 38, 45, 54,
- 64, 76, 91, 108, 128, 152, 181, 215,
- 256, 304, 362, 431, 512, 609, 724, 861,
- 1024, 1218, 1448, 1722, 2048, 2435, 2896, 3444,
- 4096, 4871, 5793, 6889, 8192, 9742, 11585, 13777,
- 16384, 19484, 23170, 27554, 32768, 38968, 46341, 55109,
- 65536, 77936
-};
-
-static const int qoffset_intra_tab[MAX_QUANT+1] = {
- 1, 2, 3, 4, 4, 5, 6, 7,
- 8, 10, 12, 14, 16, 19, 23, 27,
- 32, 38, 46, 54, 64, 76, 91, 108,
- 128, 152, 181, 216, 256, 305, 362, 431,
- 512, 609, 724, 861, 1024, 1218, 1448, 1722,
- 2048, 2436, 2897, 3445, 4096, 4871, 5793, 6889,
- 8192, 9742, 11585, 13777, 16384, 19484, 23171, 27555,
- 32768, 38968
-};
-
-static const int qoffset_inter_tab[MAX_QUANT+1] = {
- 1, 2, 2, 3, 3, 4, 4, 5,
- 6, 7, 9, 10, 12, 14, 17, 20,
- 24, 29, 34, 41, 48, 57, 68, 81,
- 96, 114, 136, 162, 192, 228, 272, 323,
- 384, 457, 543, 646, 768, 913, 1086, 1292,
- 1536, 1827, 2172, 2583, 3072, 3653, 4344, 5166,
- 6144, 7307, 8689, 10333, 12288, 14613, 17378, 20666,
- 24576, 29226
-};
-
-/* magic number division by 3 from schroedinger */
-static inline int divide3(int x)
-{
- return ((x+1)*21845 + 10922) >> 16;
-}
-
-static DiracFrame *remove_frame(DiracFrame *framelist[], int picnum)
-{
- DiracFrame *remove_pic = NULL;
- int i, remove_idx = -1;
-
- for (i = 0; framelist[i]; i++)
- if (framelist[i]->avframe->display_picture_number == picnum) {
- remove_pic = framelist[i];
- remove_idx = i;
- }
-
- if (remove_pic)
- for (i = remove_idx; framelist[i]; i++)
- framelist[i] = framelist[i+1];
-
- return remove_pic;
-}
-
-static int add_frame(DiracFrame *framelist[], int maxframes, DiracFrame *frame)
-{
- int i;
- for (i = 0; i < maxframes; i++)
- if (!framelist[i]) {
- framelist[i] = frame;
- return 0;
- }
- return -1;
-}
-
-static int alloc_sequence_buffers(DiracContext *s)
-{
- int sbwidth = DIVRNDUP(s->source.width, 4);
- int sbheight = DIVRNDUP(s->source.height, 4);
- int i, w, h, top_padding;
-
- /* todo: think more about this / use or set Plane here */
- for (i = 0; i < 3; i++) {
- int max_xblen = MAX_BLOCKSIZE >> (i ? s->chroma_x_shift : 0);
- int max_yblen = MAX_BLOCKSIZE >> (i ? s->chroma_y_shift : 0);
- w = s->source.width >> (i ? s->chroma_x_shift : 0);
- h = s->source.height >> (i ? s->chroma_y_shift : 0);
-
- /* we allocate the max we support here since num decompositions can
- * change from frame to frame. Stride is aligned to 16 for SIMD, and
- * 1<<MAX_DWT_LEVELS top padding to avoid if(y>0) in arith decoding
- * MAX_BLOCKSIZE padding for MC: blocks can spill up to half of that
- * on each side */
- top_padding = FFMAX(1<<MAX_DWT_LEVELS, max_yblen/2);
- w = FFALIGN(CALC_PADDING(w, MAX_DWT_LEVELS), 8); /* FIXME: Should this be 16 for SSE??? */
- h = top_padding + CALC_PADDING(h, MAX_DWT_LEVELS) + max_yblen/2;
-
- s->plane[i].idwt_buf_base = av_mallocz_array((w+max_xblen), h * sizeof(IDWTELEM));
- s->plane[i].idwt_tmp = av_malloc_array((w+16), sizeof(IDWTELEM));
- s->plane[i].idwt_buf = s->plane[i].idwt_buf_base + top_padding*w;
- if (!s->plane[i].idwt_buf_base || !s->plane[i].idwt_tmp)
- return AVERROR(ENOMEM);
- }
-
- /* fixme: allocate using real stride here */
- s->sbsplit = av_malloc_array(sbwidth, sbheight);
- s->blmotion = av_malloc_array(sbwidth, sbheight * 16 * sizeof(*s->blmotion));
-
- if (!s->sbsplit || !s->blmotion)
- return AVERROR(ENOMEM);
- return 0;
-}
-
-static int alloc_buffers(DiracContext *s, int stride)
-{
- int w = s->source.width;
- int h = s->source.height;
-
- av_assert0(stride >= w);
- stride += 64;
-
- if (s->buffer_stride >= stride)
- return 0;
- s->buffer_stride = 0;
-
- av_freep(&s->edge_emu_buffer_base);
- memset(s->edge_emu_buffer, 0, sizeof(s->edge_emu_buffer));
- av_freep(&s->mctmp);
- av_freep(&s->mcscratch);
-
- s->edge_emu_buffer_base = av_malloc_array(stride, MAX_BLOCKSIZE);
-
- s->mctmp = av_malloc_array((stride+MAX_BLOCKSIZE), (h+MAX_BLOCKSIZE) * sizeof(*s->mctmp));
- s->mcscratch = av_malloc_array(stride, MAX_BLOCKSIZE);
-
- if (!s->edge_emu_buffer_base || !s->mctmp || !s->mcscratch)
- return AVERROR(ENOMEM);
-
- s->buffer_stride = stride;
- return 0;
-}
-
-static void free_sequence_buffers(DiracContext *s)
-{
- int i, j, k;
-
- for (i = 0; i < MAX_FRAMES; i++) {
- if (s->all_frames[i].avframe->data[0]) {
- av_frame_unref(s->all_frames[i].avframe);
- memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated));
- }
-
- for (j = 0; j < 3; j++)
- for (k = 1; k < 4; k++)
- av_freep(&s->all_frames[i].hpel_base[j][k]);
- }
-
- memset(s->ref_frames, 0, sizeof(s->ref_frames));
- memset(s->delay_frames, 0, sizeof(s->delay_frames));
-
- for (i = 0; i < 3; i++) {
- av_freep(&s->plane[i].idwt_buf_base);
- av_freep(&s->plane[i].idwt_tmp);
- }
-
- s->buffer_stride = 0;
- av_freep(&s->sbsplit);
- av_freep(&s->blmotion);
- av_freep(&s->edge_emu_buffer_base);
-
- av_freep(&s->mctmp);
- av_freep(&s->mcscratch);
-}
-
-static av_cold int dirac_decode_init(AVCodecContext *avctx)
-{
- DiracContext *s = avctx->priv_data;
- int i;
-
- s->avctx = avctx;
- s->frame_number = -1;
-
- ff_diracdsp_init(&s->diracdsp);
- ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx);
- ff_videodsp_init(&s->vdsp, 8);
-
- for (i = 0; i < MAX_FRAMES; i++) {
- s->all_frames[i].avframe = av_frame_alloc();
- if (!s->all_frames[i].avframe) {
- while (i > 0)
- av_frame_free(&s->all_frames[--i].avframe);
- return AVERROR(ENOMEM);
- }
- }
-
- return 0;
-}
-
-static void dirac_decode_flush(AVCodecContext *avctx)
-{
- DiracContext *s = avctx->priv_data;
- free_sequence_buffers(s);
- s->seen_sequence_header = 0;
- s->frame_number = -1;
-}
-
-static av_cold int dirac_decode_end(AVCodecContext *avctx)
-{
- DiracContext *s = avctx->priv_data;
- int i;
-
- dirac_decode_flush(avctx);
- for (i = 0; i < MAX_FRAMES; i++)
- av_frame_free(&s->all_frames[i].avframe);
-
- return 0;
-}
-
-#define SIGN_CTX(x) (CTX_SIGN_ZERO + ((x) > 0) - ((x) < 0))
-
-static inline void coeff_unpack_arith(DiracArith *c, int qfactor, int qoffset,
- SubBand *b, IDWTELEM *buf, int x, int y)
-{
- int coeff, sign;
- int sign_pred = 0;
- int pred_ctx = CTX_ZPZN_F1;
-
- /* Check if the parent subband has a 0 in the corresponding position */
- if (b->parent)
- pred_ctx += !!b->parent->ibuf[b->parent->stride * (y>>1) + (x>>1)] << 1;
-
- if (b->orientation == subband_hl)
- sign_pred = buf[-b->stride];
-
- /* Determine if the pixel has only zeros in its neighbourhood */
- if (x) {
- pred_ctx += !(buf[-1] | buf[-b->stride] | buf[-1-b->stride]);
- if (b->orientation == subband_lh)
- sign_pred = buf[-1];
- } else {
- pred_ctx += !buf[-b->stride];
- }
-
- coeff = dirac_get_arith_uint(c, pred_ctx, CTX_COEFF_DATA);
- if (coeff) {
- coeff = (coeff * qfactor + qoffset + 2) >> 2;
- sign = dirac_get_arith_bit(c, SIGN_CTX(sign_pred));
- coeff = (coeff ^ -sign) + sign;
- }
- *buf = coeff;
-}
-
-static inline int coeff_unpack_golomb(GetBitContext *gb, int qfactor, int qoffset)
-{
- int sign, coeff;
-
- coeff = svq3_get_ue_golomb(gb);
- if (coeff) {
- coeff = (coeff * qfactor + qoffset + 2) >> 2;
- sign = get_bits1(gb);
- coeff = (coeff ^ -sign) + sign;
- }
- return coeff;
-}
-
-/**
- * Decode the coeffs in the rectangle defined by left, right, top, bottom
- * [DIRAC_STD] 13.4.3.2 Codeblock unpacking loop. codeblock()
- */
-static inline void codeblock(DiracContext *s, SubBand *b,
- GetBitContext *gb, DiracArith *c,
- int left, int right, int top, int bottom,
- int blockcnt_one, int is_arith)
-{
- int x, y, zero_block;
- int qoffset, qfactor;
- IDWTELEM *buf;
-
- /* check for any coded coefficients in this codeblock */
- if (!blockcnt_one) {
- if (is_arith)
- zero_block = dirac_get_arith_bit(c, CTX_ZERO_BLOCK);
- else
- zero_block = get_bits1(gb);
-
- if (zero_block)
- return;
- }
-
- if (s->codeblock_mode && !(s->old_delta_quant && blockcnt_one)) {
- int quant = b->quant;
- if (is_arith)
- quant += dirac_get_arith_int(c, CTX_DELTA_Q_F, CTX_DELTA_Q_DATA);
- else
- quant += dirac_get_se_golomb(gb);
- if (quant < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid quant\n");
- return;
- }
- b->quant = quant;
- }
-
- b->quant = FFMIN(b->quant, MAX_QUANT);
-
- qfactor = qscale_tab[b->quant];
- /* TODO: context pointer? */
- if (!s->num_refs)
- qoffset = qoffset_intra_tab[b->quant];
- else
- qoffset = qoffset_inter_tab[b->quant];
-
- buf = b->ibuf + top * b->stride;
- for (y = top; y < bottom; y++) {
- for (x = left; x < right; x++) {
- /* [DIRAC_STD] 13.4.4 Subband coefficients. coeff_unpack() */
- if (is_arith)
- coeff_unpack_arith(c, qfactor, qoffset, b, buf+x, x, y);
- else
- buf[x] = coeff_unpack_golomb(gb, qfactor, qoffset);
- }
- buf += b->stride;
- }
-}
-
-/**
- * Dirac Specification ->
- * 13.3 intra_dc_prediction(band)
- */
-static inline void intra_dc_prediction(SubBand *b)
-{
- IDWTELEM *buf = b->ibuf;
- int x, y;
-
- for (x = 1; x < b->width; x++)
- buf[x] += buf[x-1];
- buf += b->stride;
-
- for (y = 1; y < b->height; y++) {
- buf[0] += buf[-b->stride];
-
- for (x = 1; x < b->width; x++) {
- int pred = buf[x - 1] + buf[x - b->stride] + buf[x - b->stride-1];
- buf[x] += divide3(pred);
- }
- buf += b->stride;
- }
-}
-
-/**
- * Dirac Specification ->
- * 13.4.2 Non-skipped subbands. subband_coeffs()
- */
-static av_always_inline void decode_subband_internal(DiracContext *s, SubBand *b, int is_arith)
-{
- int cb_x, cb_y, left, right, top, bottom;
- DiracArith c;
- GetBitContext gb;
- int cb_width = s->codeblock[b->level + (b->orientation != subband_ll)].width;
- int cb_height = s->codeblock[b->level + (b->orientation != subband_ll)].height;
- int blockcnt_one = (cb_width + cb_height) == 2;
-
- if (!b->length)
- return;
-
- init_get_bits8(&gb, b->coeff_data, b->length);
-
- if (is_arith)
- ff_dirac_init_arith_decoder(&c, &gb, b->length);
-
- top = 0;
- for (cb_y = 0; cb_y < cb_height; cb_y++) {
- bottom = (b->height * (cb_y+1LL)) / cb_height;
- left = 0;
- for (cb_x = 0; cb_x < cb_width; cb_x++) {
- right = (b->width * (cb_x+1LL)) / cb_width;
- codeblock(s, b, &gb, &c, left, right, top, bottom, blockcnt_one, is_arith);
- left = right;
- }
- top = bottom;
- }
-
- if (b->orientation == subband_ll && s->num_refs == 0)
- intra_dc_prediction(b);
-}
-
-static int decode_subband_arith(AVCodecContext *avctx, void *b)
-{
- DiracContext *s = avctx->priv_data;
- decode_subband_internal(s, b, 1);
- return 0;
-}
-
-static int decode_subband_golomb(AVCodecContext *avctx, void *arg)
-{
- DiracContext *s = avctx->priv_data;
- SubBand **b = arg;
- decode_subband_internal(s, *b, 0);
- return 0;
-}
-
-/**
- * Dirac Specification ->
- * [DIRAC_STD] 13.4.1 core_transform_data()
- */
-static void decode_component(DiracContext *s, int comp)
-{
- AVCodecContext *avctx = s->avctx;
- SubBand *bands[3*MAX_DWT_LEVELS+1];
- enum dirac_subband orientation;
- int level, num_bands = 0;
-
- /* Unpack all subbands at all levels. */
- for (level = 0; level < s->wavelet_depth; level++) {
- for (orientation = !!level; orientation < 4; orientation++) {
- SubBand *b = &s->plane[comp].band[level][orientation];
- bands[num_bands++] = b;
-
- align_get_bits(&s->gb);
- /* [DIRAC_STD] 13.4.2 subband() */
- b->length = svq3_get_ue_golomb(&s->gb);
- if (b->length) {
- b->quant = svq3_get_ue_golomb(&s->gb);
- align_get_bits(&s->gb);
- b->coeff_data = s->gb.buffer + get_bits_count(&s->gb)/8;
- b->length = FFMIN(b->length, FFMAX(get_bits_left(&s->gb)/8, 0));
- skip_bits_long(&s->gb, b->length*8);
- }
- }
- /* arithmetic coding has inter-level dependencies, so we can only execute one level at a time */
- if (s->is_arith)
- avctx->execute(avctx, decode_subband_arith, &s->plane[comp].band[level][!!level],
- NULL, 4-!!level, sizeof(SubBand));
- }
- /* golomb coding has no inter-level dependencies, so we can execute all subbands in parallel */
- if (!s->is_arith)
- avctx->execute(avctx, decode_subband_golomb, bands, NULL, num_bands, sizeof(SubBand*));
-}
-
-/* [DIRAC_STD] 13.5.5.2 Luma slice subband data. luma_slice_band(level,orient,sx,sy) --> if b2 == NULL */
-/* [DIRAC_STD] 13.5.5.3 Chroma slice subband data. chroma_slice_band(level,orient,sx,sy) --> if b2 != NULL */
-static void lowdelay_subband(DiracContext *s, GetBitContext *gb, int quant,
- int slice_x, int slice_y, int bits_end,
- SubBand *b1, SubBand *b2)
-{
- int left = b1->width * slice_x / s->lowdelay.num_x;
- int right = b1->width *(slice_x+1) / s->lowdelay.num_x;
- int top = b1->height * slice_y / s->lowdelay.num_y;
- int bottom = b1->height *(slice_y+1) / s->lowdelay.num_y;
-
- int qfactor = qscale_tab[FFMIN(quant, MAX_QUANT)];
- int qoffset = qoffset_intra_tab[FFMIN(quant, MAX_QUANT)];
-
- IDWTELEM *buf1 = b1->ibuf + top * b1->stride;
- IDWTELEM *buf2 = b2 ? b2->ibuf + top * b2->stride : NULL;
- int x, y;
- /* we have to constantly check for overread since the spec explicitly
- requires this, with the meaning that all remaining coeffs are set to 0 */
- if (get_bits_count(gb) >= bits_end)
- return;
-
- for (y = top; y < bottom; y++) {
- for (x = left; x < right; x++) {
- buf1[x] = coeff_unpack_golomb(gb, qfactor, qoffset);
- if (get_bits_count(gb) >= bits_end)
- return;
- if (buf2) {
- buf2[x] = coeff_unpack_golomb(gb, qfactor, qoffset);
- if (get_bits_count(gb) >= bits_end)
- return;
- }
- }
- buf1 += b1->stride;
- if (buf2)
- buf2 += b2->stride;
- }
-}
-
-struct lowdelay_slice {
- GetBitContext gb;
- int slice_x;
- int slice_y;
- int bytes;
-};
-
-
-/**
- * Dirac Specification ->
- * 13.5.2 Slices. slice(sx,sy)
- */
-static int decode_lowdelay_slice(AVCodecContext *avctx, void *arg)
-{
- DiracContext *s = avctx->priv_data;
- struct lowdelay_slice *slice = arg;
- GetBitContext *gb = &slice->gb;
- enum dirac_subband orientation;
- int level, quant, chroma_bits, chroma_end;
-
- int quant_base = get_bits(gb, 7); /*[DIRAC_STD] qindex */
- int length_bits = av_log2(8 * slice->bytes)+1;
- int luma_bits = get_bits_long(gb, length_bits);
- int luma_end = get_bits_count(gb) + FFMIN(luma_bits, get_bits_left(gb));
-
- /* [DIRAC_STD] 13.5.5.2 luma_slice_band */
- for (level = 0; level < s->wavelet_depth; level++)
- for (orientation = !!level; orientation < 4; orientation++) {
- quant = FFMAX(quant_base - s->lowdelay.quant[level][orientation], 0);
- lowdelay_subband(s, gb, quant, slice->slice_x, slice->slice_y, luma_end,
- &s->plane[0].band[level][orientation], NULL);
- }
-
- /* consume any unused bits from luma */
- skip_bits_long(gb, get_bits_count(gb) - luma_end);
-
- chroma_bits = 8*slice->bytes - 7 - length_bits - luma_bits;
- chroma_end = get_bits_count(gb) + FFMIN(chroma_bits, get_bits_left(gb));
- /* [DIRAC_STD] 13.5.5.3 chroma_slice_band */
- for (level = 0; level < s->wavelet_depth; level++)
- for (orientation = !!level; orientation < 4; orientation++) {
- quant = FFMAX(quant_base - s->lowdelay.quant[level][orientation], 0);
- lowdelay_subband(s, gb, quant, slice->slice_x, slice->slice_y, chroma_end,
- &s->plane[1].band[level][orientation],
- &s->plane[2].band[level][orientation]);
- }
-
- return 0;
-}
-
-/**
- * Dirac Specification ->
- * 13.5.1 low_delay_transform_data()
- */
-static int decode_lowdelay(DiracContext *s)
-{
- AVCodecContext *avctx = s->avctx;
- int slice_x, slice_y, bytes, bufsize;
- const uint8_t *buf;
- struct lowdelay_slice *slices;
- int slice_num = 0;
-
- slices = av_mallocz_array(s->lowdelay.num_x, s->lowdelay.num_y * sizeof(struct lowdelay_slice));
- if (!slices)
- return AVERROR(ENOMEM);
-
- align_get_bits(&s->gb);
- /*[DIRAC_STD] 13.5.2 Slices. slice(sx,sy) */
- buf = s->gb.buffer + get_bits_count(&s->gb)/8;
- bufsize = get_bits_left(&s->gb);
-
- for (slice_y = 0; bufsize > 0 && slice_y < s->lowdelay.num_y; slice_y++)
- for (slice_x = 0; bufsize > 0 && slice_x < s->lowdelay.num_x; slice_x++) {
- bytes = (slice_num+1) * s->lowdelay.bytes.num / s->lowdelay.bytes.den
- - slice_num * s->lowdelay.bytes.num / s->lowdelay.bytes.den;
-
- slices[slice_num].bytes = bytes;
- slices[slice_num].slice_x = slice_x;
- slices[slice_num].slice_y = slice_y;
- init_get_bits(&slices[slice_num].gb, buf, bufsize);
- slice_num++;
-
- buf += bytes;
- if (bufsize/8 >= bytes)
- bufsize -= bytes*8;
- else
- bufsize = 0;
- }
-
- avctx->execute(avctx, decode_lowdelay_slice, slices, NULL, slice_num,
- sizeof(struct lowdelay_slice)); /* [DIRAC_STD] 13.5.2 Slices */
- intra_dc_prediction(&s->plane[0].band[0][0]); /* [DIRAC_STD] 13.3 intra_dc_prediction() */
- intra_dc_prediction(&s->plane[1].band[0][0]); /* [DIRAC_STD] 13.3 intra_dc_prediction() */
- intra_dc_prediction(&s->plane[2].band[0][0]); /* [DIRAC_STD] 13.3 intra_dc_prediction() */
- av_free(slices);
- return 0;
-}
-
-static void init_planes(DiracContext *s)
-{
- int i, w, h, level, orientation;
-
- for (i = 0; i < 3; i++) {
- Plane *p = &s->plane[i];
-
- p->width = s->source.width >> (i ? s->chroma_x_shift : 0);
- p->height = s->source.height >> (i ? s->chroma_y_shift : 0);
- p->idwt_width = w = CALC_PADDING(p->width , s->wavelet_depth);
- p->idwt_height = h = CALC_PADDING(p->height, s->wavelet_depth);
- p->idwt_stride = FFALIGN(p->idwt_width, 8);
-
- for (level = s->wavelet_depth-1; level >= 0; level--) {
- w = w>>1;
- h = h>>1;
- for (orientation = !!level; orientation < 4; orientation++) {
- SubBand *b = &p->band[level][orientation];
-
- b->ibuf = p->idwt_buf;
- b->level = level;
- b->stride = p->idwt_stride << (s->wavelet_depth - level);
- b->width = w;
- b->height = h;
- b->orientation = orientation;
-
- if (orientation & 1)
- b->ibuf += w;
- if (orientation > 1)
- b->ibuf += b->stride>>1;
-
- if (level)
- b->parent = &p->band[level-1][orientation];
- }
- }
-
- if (i > 0) {
- p->xblen = s->plane[0].xblen >> s->chroma_x_shift;
- p->yblen = s->plane[0].yblen >> s->chroma_y_shift;
- p->xbsep = s->plane[0].xbsep >> s->chroma_x_shift;
- p->ybsep = s->plane[0].ybsep >> s->chroma_y_shift;
- }
-
- p->xoffset = (p->xblen - p->xbsep)/2;
- p->yoffset = (p->yblen - p->ybsep)/2;
- }
-}
-
-/**
- * Unpack the motion compensation parameters
- * Dirac Specification ->
- * 11.2 Picture prediction data. picture_prediction()
- */
-static int dirac_unpack_prediction_parameters(DiracContext *s)
-{
- static const uint8_t default_blen[] = { 4, 12, 16, 24 };
-
- GetBitContext *gb = &s->gb;
- unsigned idx, ref;
-
- align_get_bits(gb);
- /* [DIRAC_STD] 11.2.2 Block parameters. block_parameters() */
- /* Luma and Chroma are equal. 11.2.3 */
- idx = svq3_get_ue_golomb(gb); /* [DIRAC_STD] index */
-
- if (idx > 4) {
- av_log(s->avctx, AV_LOG_ERROR, "Block prediction index too high\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (idx == 0) {
- s->plane[0].xblen = svq3_get_ue_golomb(gb);
- s->plane[0].yblen = svq3_get_ue_golomb(gb);
- s->plane[0].xbsep = svq3_get_ue_golomb(gb);
- s->plane[0].ybsep = svq3_get_ue_golomb(gb);
- } else {
- /*[DIRAC_STD] preset_block_params(index). Table 11.1 */
- s->plane[0].xblen = default_blen[idx-1];
- s->plane[0].yblen = default_blen[idx-1];
- s->plane[0].xbsep = 4 * idx;
- s->plane[0].ybsep = 4 * idx;
- }
- /*[DIRAC_STD] 11.2.4 motion_data_dimensions()
- Calculated in function dirac_unpack_block_motion_data */
-
- if (s->plane[0].xblen % (1 << s->chroma_x_shift) != 0 ||
- s->plane[0].yblen % (1 << s->chroma_y_shift) != 0 ||
- !s->plane[0].xblen || !s->plane[0].yblen) {
- av_log(s->avctx, AV_LOG_ERROR,
- "invalid x/y block length (%d/%d) for x/y chroma shift (%d/%d)\n",
- s->plane[0].xblen, s->plane[0].yblen, s->chroma_x_shift, s->chroma_y_shift);
- return AVERROR_INVALIDDATA;
- }
- if (!s->plane[0].xbsep || !s->plane[0].ybsep || s->plane[0].xbsep < s->plane[0].xblen/2 || s->plane[0].ybsep < s->plane[0].yblen/2) {
- av_log(s->avctx, AV_LOG_ERROR, "Block separation too small\n");
- return AVERROR_INVALIDDATA;
- }
- if (s->plane[0].xbsep > s->plane[0].xblen || s->plane[0].ybsep > s->plane[0].yblen) {
- av_log(s->avctx, AV_LOG_ERROR, "Block separation greater than size\n");
- return AVERROR_INVALIDDATA;
- }
- if (FFMAX(s->plane[0].xblen, s->plane[0].yblen) > MAX_BLOCKSIZE) {
- av_log(s->avctx, AV_LOG_ERROR, "Unsupported large block size\n");
- return AVERROR_PATCHWELCOME;
- }
-
- /*[DIRAC_STD] 11.2.5 Motion vector precision. motion_vector_precision()
- Read motion vector precision */
- s->mv_precision = svq3_get_ue_golomb(gb);
- if (s->mv_precision > 3) {
- av_log(s->avctx, AV_LOG_ERROR, "MV precision finer than eighth-pel\n");
- return AVERROR_INVALIDDATA;
- }
-
- /*[DIRAC_STD] 11.2.6 Global motion. global_motion()
- Read the global motion compensation parameters */
- s->globalmc_flag = get_bits1(gb);
- if (s->globalmc_flag) {
- memset(s->globalmc, 0, sizeof(s->globalmc));
- /* [DIRAC_STD] pan_tilt(gparams) */
- for (ref = 0; ref < s->num_refs; ref++) {
- if (get_bits1(gb)) {
- s->globalmc[ref].pan_tilt[0] = dirac_get_se_golomb(gb);
- s->globalmc[ref].pan_tilt[1] = dirac_get_se_golomb(gb);
- }
- /* [DIRAC_STD] zoom_rotate_shear(gparams)
- zoom/rotation/shear parameters */
- if (get_bits1(gb)) {
- s->globalmc[ref].zrs_exp = svq3_get_ue_golomb(gb);
- s->globalmc[ref].zrs[0][0] = dirac_get_se_golomb(gb);
- s->globalmc[ref].zrs[0][1] = dirac_get_se_golomb(gb);
- s->globalmc[ref].zrs[1][0] = dirac_get_se_golomb(gb);
- s->globalmc[ref].zrs[1][1] = dirac_get_se_golomb(gb);
- } else {
- s->globalmc[ref].zrs[0][0] = 1;
- s->globalmc[ref].zrs[1][1] = 1;
- }
- /* [DIRAC_STD] perspective(gparams) */
- if (get_bits1(gb)) {
- s->globalmc[ref].perspective_exp = svq3_get_ue_golomb(gb);
- s->globalmc[ref].perspective[0] = dirac_get_se_golomb(gb);
- s->globalmc[ref].perspective[1] = dirac_get_se_golomb(gb);
- }
- }
- }
-
- /*[DIRAC_STD] 11.2.7 Picture prediction mode. prediction_mode()
- Picture prediction mode, not currently used. */
- if (svq3_get_ue_golomb(gb)) {
- av_log(s->avctx, AV_LOG_ERROR, "Unknown picture prediction mode\n");
- return AVERROR_INVALIDDATA;
- }
-
- /* [DIRAC_STD] 11.2.8 Reference picture weight. reference_picture_weights()
- just data read, weight calculation will be done later on. */
- s->weight_log2denom = 1;
- s->weight[0] = 1;
- s->weight[1] = 1;
-
- if (get_bits1(gb)) {
- s->weight_log2denom = svq3_get_ue_golomb(gb);
- s->weight[0] = dirac_get_se_golomb(gb);
- if (s->num_refs == 2)
- s->weight[1] = dirac_get_se_golomb(gb);
- }
- return 0;
-}
-
-/**
- * Dirac Specification ->
- * 11.3 Wavelet transform data. wavelet_transform()
- */
-static int dirac_unpack_idwt_params(DiracContext *s)
-{
- GetBitContext *gb = &s->gb;
- int i, level;
- unsigned tmp;
-
-#define CHECKEDREAD(dst, cond, errmsg) \
- tmp = svq3_get_ue_golomb(gb); \
- if (cond) { \
- av_log(s->avctx, AV_LOG_ERROR, errmsg); \
- return AVERROR_INVALIDDATA; \
- }\
- dst = tmp;
-
- align_get_bits(gb);
-
- s->zero_res = s->num_refs ? get_bits1(gb) : 0;
- if (s->zero_res)
- return 0;
-
- /*[DIRAC_STD] 11.3.1 Transform parameters. transform_parameters() */
- CHECKEDREAD(s->wavelet_idx, tmp > 6, "wavelet_idx is too big\n")
-
- CHECKEDREAD(s->wavelet_depth, tmp > MAX_DWT_LEVELS || tmp < 1, "invalid number of DWT decompositions\n")
-
- if (!s->low_delay) {
- /* Codeblock parameters (core syntax only) */
- if (get_bits1(gb)) {
- for (i = 0; i <= s->wavelet_depth; i++) {
- CHECKEDREAD(s->codeblock[i].width , tmp < 1 || tmp > (s->avctx->width >>s->wavelet_depth-i), "codeblock width invalid\n")
- CHECKEDREAD(s->codeblock[i].height, tmp < 1 || tmp > (s->avctx->height>>s->wavelet_depth-i), "codeblock height invalid\n")
- }
-
- CHECKEDREAD(s->codeblock_mode, tmp > 1, "unknown codeblock mode\n")
- } else
- for (i = 0; i <= s->wavelet_depth; i++)
- s->codeblock[i].width = s->codeblock[i].height = 1;
- } else {
- /* Slice parameters + quantization matrix*/
- /*[DIRAC_STD] 11.3.4 Slice coding Parameters (low delay syntax only). slice_parameters() */
- s->lowdelay.num_x = svq3_get_ue_golomb(gb);
- s->lowdelay.num_y = svq3_get_ue_golomb(gb);
- if (s->lowdelay.num_x * s->lowdelay.num_y == 0 ||
- s->lowdelay.num_x * (uint64_t)s->lowdelay.num_y > INT_MAX) {
- av_log(s->avctx,AV_LOG_ERROR,"Invalid numx/y\n");
- s->lowdelay.num_x = s->lowdelay.num_y = 0;
- return AVERROR_INVALIDDATA;
- }
-
- s->lowdelay.bytes.num = svq3_get_ue_golomb(gb);
- s->lowdelay.bytes.den = svq3_get_ue_golomb(gb);
-
- if (s->lowdelay.bytes.den <= 0) {
- av_log(s->avctx,AV_LOG_ERROR,"Invalid lowdelay.bytes.den\n");
- return AVERROR_INVALIDDATA;
- }
-
- /* [DIRAC_STD] 11.3.5 Quantisation matrices (low-delay syntax). quant_matrix() */
- if (get_bits1(gb)) {
- av_log(s->avctx,AV_LOG_DEBUG,"Low Delay: Has Custom Quantization Matrix!\n");
- /* custom quantization matrix */
- s->lowdelay.quant[0][0] = svq3_get_ue_golomb(gb);
- for (level = 0; level < s->wavelet_depth; level++) {
- s->lowdelay.quant[level][1] = svq3_get_ue_golomb(gb);
- s->lowdelay.quant[level][2] = svq3_get_ue_golomb(gb);
- s->lowdelay.quant[level][3] = svq3_get_ue_golomb(gb);
- }
- } else {
- if (s->wavelet_depth > 4) {
- av_log(s->avctx,AV_LOG_ERROR,"Mandatory custom low delay matrix missing for depth %d\n", s->wavelet_depth);
- return AVERROR_INVALIDDATA;
- }
- /* default quantization matrix */
- for (level = 0; level < s->wavelet_depth; level++)
- for (i = 0; i < 4; i++) {
- s->lowdelay.quant[level][i] = default_qmat[s->wavelet_idx][level][i];
- /* haar with no shift differs for different depths */
- if (s->wavelet_idx == 3)
- s->lowdelay.quant[level][i] += 4*(s->wavelet_depth-1 - level);
- }
- }
- }
- return 0;
-}
-
-static inline int pred_sbsplit(uint8_t *sbsplit, int stride, int x, int y)
-{
- static const uint8_t avgsplit[7] = { 0, 0, 1, 1, 1, 2, 2 };
-
- if (!(x|y))
- return 0;
- else if (!y)
- return sbsplit[-1];
- else if (!x)
- return sbsplit[-stride];
-
- return avgsplit[sbsplit[-1] + sbsplit[-stride] + sbsplit[-stride-1]];
-}
-
-static inline int pred_block_mode(DiracBlock *block, int stride, int x, int y, int refmask)
-{
- int pred;
-
- if (!(x|y))
- return 0;
- else if (!y)
- return block[-1].ref & refmask;
- else if (!x)
- return block[-stride].ref & refmask;
-
- /* return the majority */
- pred = (block[-1].ref & refmask) + (block[-stride].ref & refmask) + (block[-stride-1].ref & refmask);
- return (pred >> 1) & refmask;
-}
-
-static inline void pred_block_dc(DiracBlock *block, int stride, int x, int y)
-{
- int i, n = 0;
-
- memset(block->u.dc, 0, sizeof(block->u.dc));
-
- if (x && !(block[-1].ref & 3)) {
- for (i = 0; i < 3; i++)
- block->u.dc[i] += block[-1].u.dc[i];
- n++;
- }
-
- if (y && !(block[-stride].ref & 3)) {
- for (i = 0; i < 3; i++)
- block->u.dc[i] += block[-stride].u.dc[i];
- n++;
- }
-
- if (x && y && !(block[-1-stride].ref & 3)) {
- for (i = 0; i < 3; i++)
- block->u.dc[i] += block[-1-stride].u.dc[i];
- n++;
- }
-
- if (n == 2) {
- for (i = 0; i < 3; i++)
- block->u.dc[i] = (block->u.dc[i]+1)>>1;
- } else if (n == 3) {
- for (i = 0; i < 3; i++)
- block->u.dc[i] = divide3(block->u.dc[i]);
- }
-}
-
-static inline void pred_mv(DiracBlock *block, int stride, int x, int y, int ref)
-{
- int16_t *pred[3];
- int refmask = ref+1;
- int mask = refmask | DIRAC_REF_MASK_GLOBAL; /* exclude gmc blocks */
- int n = 0;
-
- if (x && (block[-1].ref & mask) == refmask)
- pred[n++] = block[-1].u.mv[ref];
-
- if (y && (block[-stride].ref & mask) == refmask)
- pred[n++] = block[-stride].u.mv[ref];
-
- if (x && y && (block[-stride-1].ref & mask) == refmask)
- pred[n++] = block[-stride-1].u.mv[ref];
-
- switch (n) {
- case 0:
- block->u.mv[ref][0] = 0;
- block->u.mv[ref][1] = 0;
- break;
- case 1:
- block->u.mv[ref][0] = pred[0][0];
- block->u.mv[ref][1] = pred[0][1];
- break;
- case 2:
- block->u.mv[ref][0] = (pred[0][0] + pred[1][0] + 1) >> 1;
- block->u.mv[ref][1] = (pred[0][1] + pred[1][1] + 1) >> 1;
- break;
- case 3:
- block->u.mv[ref][0] = mid_pred(pred[0][0], pred[1][0], pred[2][0]);
- block->u.mv[ref][1] = mid_pred(pred[0][1], pred[1][1], pred[2][1]);
- break;
- }
-}
-
-static void global_mv(DiracContext *s, DiracBlock *block, int x, int y, int ref)
-{
- int ez = s->globalmc[ref].zrs_exp;
- int ep = s->globalmc[ref].perspective_exp;
- int (*A)[2] = s->globalmc[ref].zrs;
- int *b = s->globalmc[ref].pan_tilt;
- int *c = s->globalmc[ref].perspective;
-
- int m = (1<<ep) - (c[0]*x + c[1]*y);
- int mx = m * ((A[0][0] * x + A[0][1]*y) + (1<<ez) * b[0]);
- int my = m * ((A[1][0] * x + A[1][1]*y) + (1<<ez) * b[1]);
-
- block->u.mv[ref][0] = (mx + (1<<(ez+ep))) >> (ez+ep);
- block->u.mv[ref][1] = (my + (1<<(ez+ep))) >> (ez+ep);
-}
-
-static void decode_block_params(DiracContext *s, DiracArith arith[8], DiracBlock *block,
- int stride, int x, int y)
-{
- int i;
-
- block->ref = pred_block_mode(block, stride, x, y, DIRAC_REF_MASK_REF1);
- block->ref ^= dirac_get_arith_bit(arith, CTX_PMODE_REF1);
-
- if (s->num_refs == 2) {
- block->ref |= pred_block_mode(block, stride, x, y, DIRAC_REF_MASK_REF2);
- block->ref ^= dirac_get_arith_bit(arith, CTX_PMODE_REF2) << 1;
- }
-
- if (!block->ref) {
- pred_block_dc(block, stride, x, y);
- for (i = 0; i < 3; i++)
- block->u.dc[i] += dirac_get_arith_int(arith+1+i, CTX_DC_F1, CTX_DC_DATA);
- return;
- }
-
- if (s->globalmc_flag) {
- block->ref |= pred_block_mode(block, stride, x, y, DIRAC_REF_MASK_GLOBAL);
- block->ref ^= dirac_get_arith_bit(arith, CTX_GLOBAL_BLOCK) << 2;
- }
-
- for (i = 0; i < s->num_refs; i++)
- if (block->ref & (i+1)) {
- if (block->ref & DIRAC_REF_MASK_GLOBAL) {
- global_mv(s, block, x, y, i);
- } else {
- pred_mv(block, stride, x, y, i);
- block->u.mv[i][0] += dirac_get_arith_int(arith + 4 + 2 * i, CTX_MV_F1, CTX_MV_DATA);
- block->u.mv[i][1] += dirac_get_arith_int(arith + 5 + 2 * i, CTX_MV_F1, CTX_MV_DATA);
- }
- }
-}
-
-/**
- * Copies the current block to the other blocks covered by the current superblock split mode
- */
-static void propagate_block_data(DiracBlock *block, int stride, int size)
-{
- int x, y;
- DiracBlock *dst = block;
-
- for (x = 1; x < size; x++)
- dst[x] = *block;
-
- for (y = 1; y < size; y++) {
- dst += stride;
- for (x = 0; x < size; x++)
- dst[x] = *block;
- }
-}
-
-/**
- * Dirac Specification ->
- * 12. Block motion data syntax
- */
-static int dirac_unpack_block_motion_data(DiracContext *s)
-{
- GetBitContext *gb = &s->gb;
- uint8_t *sbsplit = s->sbsplit;
- int i, x, y, q, p;
- DiracArith arith[8];
-
- align_get_bits(gb);
-
- /* [DIRAC_STD] 11.2.4 and 12.2.1 Number of blocks and superblocks */
- s->sbwidth = DIVRNDUP(s->source.width, 4*s->plane[0].xbsep);
- s->sbheight = DIVRNDUP(s->source.height, 4*s->plane[0].ybsep);
- s->blwidth = 4 * s->sbwidth;
- s->blheight = 4 * s->sbheight;
-
- /* [DIRAC_STD] 12.3.1 Superblock splitting modes. superblock_split_modes()
- decode superblock split modes */
- ff_dirac_init_arith_decoder(arith, gb, svq3_get_ue_golomb(gb)); /* svq3_get_ue_golomb(gb) is the length */
- for (y = 0; y < s->sbheight; y++) {
- for (x = 0; x < s->sbwidth; x++) {
- unsigned int split = dirac_get_arith_uint(arith, CTX_SB_F1, CTX_SB_DATA);
- if (split > 2)
- return AVERROR_INVALIDDATA;
- sbsplit[x] = (split + pred_sbsplit(sbsplit+x, s->sbwidth, x, y)) % 3;
- }
- sbsplit += s->sbwidth;
- }
-
- /* setup arith decoding */
- ff_dirac_init_arith_decoder(arith, gb, svq3_get_ue_golomb(gb));
- for (i = 0; i < s->num_refs; i++) {
- ff_dirac_init_arith_decoder(arith + 4 + 2 * i, gb, svq3_get_ue_golomb(gb));
- ff_dirac_init_arith_decoder(arith + 5 + 2 * i, gb, svq3_get_ue_golomb(gb));
- }
- for (i = 0; i < 3; i++)
- ff_dirac_init_arith_decoder(arith+1+i, gb, svq3_get_ue_golomb(gb));
-
- for (y = 0; y < s->sbheight; y++)
- for (x = 0; x < s->sbwidth; x++) {
- int blkcnt = 1 << s->sbsplit[y * s->sbwidth + x];
- int step = 4 >> s->sbsplit[y * s->sbwidth + x];
-
- for (q = 0; q < blkcnt; q++)
- for (p = 0; p < blkcnt; p++) {
- int bx = 4 * x + p*step;
- int by = 4 * y + q*step;
- DiracBlock *block = &s->blmotion[by*s->blwidth + bx];
- decode_block_params(s, arith, block, s->blwidth, bx, by);
- propagate_block_data(block, s->blwidth, step);
- }
- }
-
- return 0;
-}
-
-static int weight(int i, int blen, int offset)
-{
-#define ROLLOFF(i) offset == 1 ? ((i) ? 5 : 3) : \
- (1 + (6*(i) + offset - 1) / (2*offset - 1))
-
- if (i < 2*offset)
- return ROLLOFF(i);
- else if (i > blen-1 - 2*offset)
- return ROLLOFF(blen-1 - i);
- return 8;
-}
-
-static void init_obmc_weight_row(Plane *p, uint8_t *obmc_weight, int stride,
- int left, int right, int wy)
-{
- int x;
- for (x = 0; left && x < p->xblen >> 1; x++)
- obmc_weight[x] = wy*8;
- for (; x < p->xblen >> right; x++)
- obmc_weight[x] = wy*weight(x, p->xblen, p->xoffset);
- for (; x < p->xblen; x++)
- obmc_weight[x] = wy*8;
- for (; x < stride; x++)
- obmc_weight[x] = 0;
-}
-
-static void init_obmc_weight(Plane *p, uint8_t *obmc_weight, int stride,
- int left, int right, int top, int bottom)
-{
- int y;
- for (y = 0; top && y < p->yblen >> 1; y++) {
- init_obmc_weight_row(p, obmc_weight, stride, left, right, 8);
- obmc_weight += stride;
- }
- for (; y < p->yblen >> bottom; y++) {
- int wy = weight(y, p->yblen, p->yoffset);
- init_obmc_weight_row(p, obmc_weight, stride, left, right, wy);
- obmc_weight += stride;
- }
- for (; y < p->yblen; y++) {
- init_obmc_weight_row(p, obmc_weight, stride, left, right, 8);
- obmc_weight += stride;
- }
-}
-
-static void init_obmc_weights(DiracContext *s, Plane *p, int by)
-{
- int top = !by;
- int bottom = by == s->blheight-1;
-
- /* don't bother re-initing for rows 2 to blheight-2, the weights don't change */
- if (top || bottom || by == 1) {
- init_obmc_weight(p, s->obmc_weight[0], MAX_BLOCKSIZE, 1, 0, top, bottom);
- init_obmc_weight(p, s->obmc_weight[1], MAX_BLOCKSIZE, 0, 0, top, bottom);
- init_obmc_weight(p, s->obmc_weight[2], MAX_BLOCKSIZE, 0, 1, top, bottom);
- }
-}
-
-static const uint8_t epel_weights[4][4][4] = {
- {{ 16, 0, 0, 0 },
- { 12, 4, 0, 0 },
- { 8, 8, 0, 0 },
- { 4, 12, 0, 0 }},
- {{ 12, 0, 4, 0 },
- { 9, 3, 3, 1 },
- { 6, 6, 2, 2 },
- { 3, 9, 1, 3 }},
- {{ 8, 0, 8, 0 },
- { 6, 2, 6, 2 },
- { 4, 4, 4, 4 },
- { 2, 6, 2, 6 }},
- {{ 4, 0, 12, 0 },
- { 3, 1, 9, 3 },
- { 2, 2, 6, 6 },
- { 1, 3, 3, 9 }}
-};
-
-/**
- * For block x,y, determine which of the hpel planes to do bilinear
- * interpolation from and set src[] to the location in each hpel plane
- * to MC from.
- *
- * @return the index of the put_dirac_pixels_tab function to use
- * 0 for 1 plane (fpel,hpel), 1 for 2 planes (qpel), 2 for 4 planes (qpel), and 3 for epel
- */
-static int mc_subpel(DiracContext *s, DiracBlock *block, const uint8_t *src[5],
- int x, int y, int ref, int plane)
-{
- Plane *p = &s->plane[plane];
- uint8_t **ref_hpel = s->ref_pics[ref]->hpel[plane];
- int motion_x = block->u.mv[ref][0];
- int motion_y = block->u.mv[ref][1];
- int mx, my, i, epel, nplanes = 0;
-
- if (plane) {
- motion_x >>= s->chroma_x_shift;
- motion_y >>= s->chroma_y_shift;
- }
-
- mx = motion_x & ~(-1U << s->mv_precision);
- my = motion_y & ~(-1U << s->mv_precision);
- motion_x >>= s->mv_precision;
- motion_y >>= s->mv_precision;
- /* normalize subpel coordinates to epel */
- /* TODO: template this function? */
- mx <<= 3 - s->mv_precision;
- my <<= 3 - s->mv_precision;
-
- x += motion_x;
- y += motion_y;
- epel = (mx|my)&1;
-
- /* hpel position */
- if (!((mx|my)&3)) {
- nplanes = 1;
- src[0] = ref_hpel[(my>>1)+(mx>>2)] + y*p->stride + x;
- } else {
- /* qpel or epel */
- nplanes = 4;
- for (i = 0; i < 4; i++)
- src[i] = ref_hpel[i] + y*p->stride + x;
-
- /* if we're interpolating in the right/bottom halves, adjust the planes as needed
- we increment x/y because the edge changes for half of the pixels */
- if (mx > 4) {
- src[0] += 1;
- src[2] += 1;
- x++;
- }
- if (my > 4) {
- src[0] += p->stride;
- src[1] += p->stride;
- y++;
- }
-
- /* hpel planes are:
- [0]: F [1]: H
- [2]: V [3]: C */
- if (!epel) {
- /* check if we really only need 2 planes since either mx or my is
- a hpel position. (epel weights of 0 handle this there) */
- if (!(mx&3)) {
- /* mx == 0: average [0] and [2]
- mx == 4: average [1] and [3] */
- src[!mx] = src[2 + !!mx];
- nplanes = 2;
- } else if (!(my&3)) {
- src[0] = src[(my>>1) ];
- src[1] = src[(my>>1)+1];
- nplanes = 2;
- }
- } else {
- /* adjust the ordering if needed so the weights work */
- if (mx > 4) {
- FFSWAP(const uint8_t *, src[0], src[1]);
- FFSWAP(const uint8_t *, src[2], src[3]);
- }
- if (my > 4) {
- FFSWAP(const uint8_t *, src[0], src[2]);
- FFSWAP(const uint8_t *, src[1], src[3]);
- }
- src[4] = epel_weights[my&3][mx&3];
- }
- }
-
- /* fixme: v/h _edge_pos */
- if (x + p->xblen > p->width +EDGE_WIDTH/2 ||
- y + p->yblen > p->height+EDGE_WIDTH/2 ||
- x < 0 || y < 0) {
- for (i = 0; i < nplanes; i++) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer[i], src[i],
- p->stride, p->stride,
- p->xblen, p->yblen, x, y,
- p->width+EDGE_WIDTH/2, p->height+EDGE_WIDTH/2);
- src[i] = s->edge_emu_buffer[i];
- }
- }
- return (nplanes>>1) + epel;
-}
-
-static void add_dc(uint16_t *dst, int dc, int stride,
- uint8_t *obmc_weight, int xblen, int yblen)
-{
- int x, y;
- dc += 128;
-
- for (y = 0; y < yblen; y++) {
- for (x = 0; x < xblen; x += 2) {
- dst[x ] += dc * obmc_weight[x ];
- dst[x+1] += dc * obmc_weight[x+1];
- }
- dst += stride;
- obmc_weight += MAX_BLOCKSIZE;
- }
-}
-
-static void block_mc(DiracContext *s, DiracBlock *block,
- uint16_t *mctmp, uint8_t *obmc_weight,
- int plane, int dstx, int dsty)
-{
- Plane *p = &s->plane[plane];
- const uint8_t *src[5];
- int idx;
-
- switch (block->ref&3) {
- case 0: /* DC */
- add_dc(mctmp, block->u.dc[plane], p->stride, obmc_weight, p->xblen, p->yblen);
- return;
- case 1:
- case 2:
- idx = mc_subpel(s, block, src, dstx, dsty, (block->ref&3)-1, plane);
- s->put_pixels_tab[idx](s->mcscratch, src, p->stride, p->yblen);
- if (s->weight_func)
- s->weight_func(s->mcscratch, p->stride, s->weight_log2denom,
- s->weight[0] + s->weight[1], p->yblen);
- break;
- case 3:
- idx = mc_subpel(s, block, src, dstx, dsty, 0, plane);
- s->put_pixels_tab[idx](s->mcscratch, src, p->stride, p->yblen);
- idx = mc_subpel(s, block, src, dstx, dsty, 1, plane);
- if (s->biweight_func) {
- /* fixme: +32 is a quick hack */
- s->put_pixels_tab[idx](s->mcscratch + 32, src, p->stride, p->yblen);
- s->biweight_func(s->mcscratch, s->mcscratch+32, p->stride, s->weight_log2denom,
- s->weight[0], s->weight[1], p->yblen);
- } else
- s->avg_pixels_tab[idx](s->mcscratch, src, p->stride, p->yblen);
- break;
- }
- s->add_obmc(mctmp, s->mcscratch, p->stride, obmc_weight, p->yblen);
-}
-
-static void mc_row(DiracContext *s, DiracBlock *block, uint16_t *mctmp, int plane, int dsty)
-{
- Plane *p = &s->plane[plane];
- int x, dstx = p->xbsep - p->xoffset;
-
- block_mc(s, block, mctmp, s->obmc_weight[0], plane, -p->xoffset, dsty);
- mctmp += p->xbsep;
-
- for (x = 1; x < s->blwidth-1; x++) {
- block_mc(s, block+x, mctmp, s->obmc_weight[1], plane, dstx, dsty);
- dstx += p->xbsep;
- mctmp += p->xbsep;
- }
- block_mc(s, block+x, mctmp, s->obmc_weight[2], plane, dstx, dsty);
-}
-
-static void select_dsp_funcs(DiracContext *s, int width, int height, int xblen, int yblen)
-{
- int idx = 0;
- if (xblen > 8)
- idx = 1;
- if (xblen > 16)
- idx = 2;
-
- memcpy(s->put_pixels_tab, s->diracdsp.put_dirac_pixels_tab[idx], sizeof(s->put_pixels_tab));
- memcpy(s->avg_pixels_tab, s->diracdsp.avg_dirac_pixels_tab[idx], sizeof(s->avg_pixels_tab));
- s->add_obmc = s->diracdsp.add_dirac_obmc[idx];
- if (s->weight_log2denom > 1 || s->weight[0] != 1 || s->weight[1] != 1) {
- s->weight_func = s->diracdsp.weight_dirac_pixels_tab[idx];
- s->biweight_func = s->diracdsp.biweight_dirac_pixels_tab[idx];
- } else {
- s->weight_func = NULL;
- s->biweight_func = NULL;
- }
-}
-
-static int interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, int width, int height)
-{
- /* chroma allocates an edge of 8 when subsampled
- which for 4:2:2 means an h edge of 16 and v edge of 8
- just use 8 for everything for the moment */
- int i, edge = EDGE_WIDTH/2;
-
- ref->hpel[plane][0] = ref->avframe->data[plane];
- s->mpvencdsp.draw_edges(ref->hpel[plane][0], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */
-
- /* no need for hpel if we only have fpel vectors */
- if (!s->mv_precision)
- return 0;
-
- for (i = 1; i < 4; i++) {
- if (!ref->hpel_base[plane][i])
- ref->hpel_base[plane][i] = av_malloc((height+2*edge) * ref->avframe->linesize[plane] + 32);
- if (!ref->hpel_base[plane][i]) {
- return AVERROR(ENOMEM);
- }
- /* we need to be 16-byte aligned even for chroma */
- ref->hpel[plane][i] = ref->hpel_base[plane][i] + edge*ref->avframe->linesize[plane] + 16;
- }
-
- if (!ref->interpolated[plane]) {
- s->diracdsp.dirac_hpel_filter(ref->hpel[plane][1], ref->hpel[plane][2],
- ref->hpel[plane][3], ref->hpel[plane][0],
- ref->avframe->linesize[plane], width, height);
- s->mpvencdsp.draw_edges(ref->hpel[plane][1], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
- s->mpvencdsp.draw_edges(ref->hpel[plane][2], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
- s->mpvencdsp.draw_edges(ref->hpel[plane][3], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
- }
- ref->interpolated[plane] = 1;
-
- return 0;
-}
-
-/**
- * Dirac Specification ->
- * 13.0 Transform data syntax. transform_data()
- */
-static int dirac_decode_frame_internal(DiracContext *s)
-{
- DWTContext d;
- int y, i, comp, dsty;
- int ret;
-
- if (s->low_delay) {
- /* [DIRAC_STD] 13.5.1 low_delay_transform_data() */
- for (comp = 0; comp < 3; comp++) {
- Plane *p = &s->plane[comp];
- memset(p->idwt_buf, 0, p->idwt_stride * p->idwt_height * sizeof(IDWTELEM));
- }
- if (!s->zero_res) {
- if ((ret = decode_lowdelay(s)) < 0)
- return ret;
- }
- }
-
- for (comp = 0; comp < 3; comp++) {
- Plane *p = &s->plane[comp];
- uint8_t *frame = s->current_picture->avframe->data[comp];
-
- /* FIXME: small resolutions */
- for (i = 0; i < 4; i++)
- s->edge_emu_buffer[i] = s->edge_emu_buffer_base + i*FFALIGN(p->width, 16);
-
- if (!s->zero_res && !s->low_delay)
- {
- memset(p->idwt_buf, 0, p->idwt_stride * p->idwt_height * sizeof(IDWTELEM));
- decode_component(s, comp); /* [DIRAC_STD] 13.4.1 core_transform_data() */
- }
- ret = ff_spatial_idwt_init2(&d, p->idwt_buf, p->idwt_width, p->idwt_height, p->idwt_stride,
- s->wavelet_idx+2, s->wavelet_depth, p->idwt_tmp);
- if (ret < 0)
- return ret;
-
- if (!s->num_refs) { /* intra */
- for (y = 0; y < p->height; y += 16) {
- ff_spatial_idwt_slice2(&d, y+16); /* decode */
- s->diracdsp.put_signed_rect_clamped(frame + y*p->stride, p->stride,
- p->idwt_buf + y*p->idwt_stride, p->idwt_stride, p->width, 16);
- }
- } else { /* inter */
- int rowheight = p->ybsep*p->stride;
-
- select_dsp_funcs(s, p->width, p->height, p->xblen, p->yblen);
-
- for (i = 0; i < s->num_refs; i++) {
- int ret = interpolate_refplane(s, s->ref_pics[i], comp, p->width, p->height);
- if (ret < 0)
- return ret;
- }
-
- memset(s->mctmp, 0, 4*p->yoffset*p->stride);
-
- dsty = -p->yoffset;
- for (y = 0; y < s->blheight; y++) {
- int h = 0,
- start = FFMAX(dsty, 0);
- uint16_t *mctmp = s->mctmp + y*rowheight;
- DiracBlock *blocks = s->blmotion + y*s->blwidth;
-
- init_obmc_weights(s, p, y);
-
- if (y == s->blheight-1 || start+p->ybsep > p->height)
- h = p->height - start;
- else
- h = p->ybsep - (start - dsty);
- if (h < 0)
- break;
-
- memset(mctmp+2*p->yoffset*p->stride, 0, 2*rowheight);
- mc_row(s, blocks, mctmp, comp, dsty);
-
- mctmp += (start - dsty)*p->stride + p->xoffset;
- ff_spatial_idwt_slice2(&d, start + h); /* decode */
- s->diracdsp.add_rect_clamped(frame + start*p->stride, mctmp, p->stride,
- p->idwt_buf + start*p->idwt_stride, p->idwt_stride, p->width, h);
-
- dsty += p->ybsep;
- }
- }
- }
-
-
- return 0;
-}
-
-static int get_buffer_with_edge(AVCodecContext *avctx, AVFrame *f, int flags)
-{
- int ret, i;
- int chroma_x_shift, chroma_y_shift;
- avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_x_shift, &chroma_y_shift);
-
- f->width = avctx->width + 2 * EDGE_WIDTH;
- f->height = avctx->height + 2 * EDGE_WIDTH + 2;
- ret = ff_get_buffer(avctx, f, flags);
- if (ret < 0)
- return ret;
-
- for (i = 0; f->data[i]; i++) {
- int offset = (EDGE_WIDTH >> (i && i<3 ? chroma_y_shift : 0)) *
- f->linesize[i] + 32;
- f->data[i] += offset;
- }
- f->width = avctx->width;
- f->height = avctx->height;
-
- return 0;
-}
-
-/**
- * Dirac Specification ->
- * 11.1.1 Picture Header. picture_header()
- */
-static int dirac_decode_picture_header(DiracContext *s)
-{
- unsigned retire, picnum;
- int i, j, ret;
- int64_t refdist, refnum;
- GetBitContext *gb = &s->gb;
-
- /* [DIRAC_STD] 11.1.1 Picture Header. picture_header() PICTURE_NUM */
- picnum = s->current_picture->avframe->display_picture_number = get_bits_long(gb, 32);
-
-
- av_log(s->avctx,AV_LOG_DEBUG,"PICTURE_NUM: %d\n",picnum);
-
- /* if this is the first keyframe after a sequence header, start our
- reordering from here */
- if (s->frame_number < 0)
- s->frame_number = picnum;
-
- s->ref_pics[0] = s->ref_pics[1] = NULL;
- for (i = 0; i < s->num_refs; i++) {
- refnum = (picnum + dirac_get_se_golomb(gb)) & 0xFFFFFFFF;
- refdist = INT64_MAX;
-
- /* find the closest reference to the one we want */
- /* Jordi: this is needed if the referenced picture hasn't yet arrived */
- for (j = 0; j < MAX_REFERENCE_FRAMES && refdist; j++)
- if (s->ref_frames[j]
- && FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum) < refdist) {
- s->ref_pics[i] = s->ref_frames[j];
- refdist = FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum);
- }
-
- if (!s->ref_pics[i] || refdist)
- av_log(s->avctx, AV_LOG_DEBUG, "Reference not found\n");
-
- /* if there were no references at all, allocate one */
- if (!s->ref_pics[i])
- for (j = 0; j < MAX_FRAMES; j++)
- if (!s->all_frames[j].avframe->data[0]) {
- s->ref_pics[i] = &s->all_frames[j];
- ret = get_buffer_with_edge(s->avctx, s->ref_pics[i]->avframe, AV_GET_BUFFER_FLAG_REF);
- if (ret < 0)
- return ret;
- break;
- }
-
- if (!s->ref_pics[i]) {
- av_log(s->avctx, AV_LOG_ERROR, "Reference could not be allocated\n");
- return AVERROR_INVALIDDATA;
- }
-
- }
-
- /* retire the reference frames that are not used anymore */
- if (s->current_picture->reference) {
- retire = (picnum + dirac_get_se_golomb(gb)) & 0xFFFFFFFF;
- if (retire != picnum) {
- DiracFrame *retire_pic = remove_frame(s->ref_frames, retire);
-
- if (retire_pic)
- retire_pic->reference &= DELAYED_PIC_REF;
- else
- av_log(s->avctx, AV_LOG_DEBUG, "Frame to retire not found\n");
- }
-
- /* if reference array is full, remove the oldest as per the spec */
- while (add_frame(s->ref_frames, MAX_REFERENCE_FRAMES, s->current_picture)) {
- av_log(s->avctx, AV_LOG_ERROR, "Reference frame overflow\n");
- remove_frame(s->ref_frames, s->ref_frames[0]->avframe->display_picture_number)->reference &= DELAYED_PIC_REF;
- }
- }
-
- if (s->num_refs) {
- ret = dirac_unpack_prediction_parameters(s); /* [DIRAC_STD] 11.2 Picture Prediction Data. picture_prediction() */
- if (ret < 0)
- return ret;
- ret = dirac_unpack_block_motion_data(s); /* [DIRAC_STD] 12. Block motion data syntax */
- if (ret < 0)
- return ret;
- }
- ret = dirac_unpack_idwt_params(s); /* [DIRAC_STD] 11.3 Wavelet transform data */
- if (ret < 0)
- return ret;
-
- init_planes(s);
- return 0;
-}
-
-static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame)
-{
- DiracFrame *out = s->delay_frames[0];
- int i, out_idx = 0;
- int ret;
-
- /* find frame with lowest picture number */
- for (i = 1; s->delay_frames[i]; i++)
- if (s->delay_frames[i]->avframe->display_picture_number < out->avframe->display_picture_number) {
- out = s->delay_frames[i];
- out_idx = i;
- }
-
- for (i = out_idx; s->delay_frames[i]; i++)
- s->delay_frames[i] = s->delay_frames[i+1];
-
- if (out) {
- out->reference ^= DELAYED_PIC_REF;
- *got_frame = 1;
- if((ret = av_frame_ref(picture, out->avframe)) < 0)
- return ret;
- }
-
- return 0;
-}
-
-/**
- * Dirac Specification ->
- * 9.6 Parse Info Header Syntax. parse_info()
- * 4 byte start code + byte parse code + 4 byte size + 4 byte previous size
- */
-#define DATA_UNIT_HEADER_SIZE 13
-
-/* [DIRAC_STD] dirac_decode_data_unit makes reference to the while defined in 9.3
- inside the function parse_sequence() */
-static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int size)
-{
- DiracContext *s = avctx->priv_data;
- DiracFrame *pic = NULL;
- int ret, i, parse_code;
- unsigned tmp;
-
- if (size < DATA_UNIT_HEADER_SIZE)
- return AVERROR_INVALIDDATA;
-
- parse_code = buf[4];
-
- init_get_bits(&s->gb, &buf[13], 8*(size - DATA_UNIT_HEADER_SIZE));
-
- if (parse_code == pc_seq_header) {
- if (s->seen_sequence_header)
- return 0;
-
- /* [DIRAC_STD] 10. Sequence header */
- ret = avpriv_dirac_parse_sequence_header(avctx, &s->gb, &s->source);
- if (ret < 0)
- return ret;
-
- avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift);
-
- ret = alloc_sequence_buffers(s);
- if (ret < 0)
- return ret;
-
- s->seen_sequence_header = 1;
- } else if (parse_code == pc_eos) { /* [DIRAC_STD] End of Sequence */
- free_sequence_buffers(s);
- s->seen_sequence_header = 0;
- } else if (parse_code == pc_aux_data) {
- if (buf[13] == 1) { /* encoder implementation/version */
- int ver[3];
- /* versions older than 1.0.8 don't store quant delta for
- subbands with only one codeblock */
- if (sscanf(buf+14, "Schroedinger %d.%d.%d", ver, ver+1, ver+2) == 3)
- if (ver[0] == 1 && ver[1] == 0 && ver[2] <= 7)
- s->old_delta_quant = 1;
- }
- } else if (parse_code & 0x8) { /* picture data unit */
- if (!s->seen_sequence_header) {
- av_log(avctx, AV_LOG_DEBUG, "Dropping frame without sequence header\n");
- return AVERROR_INVALIDDATA;
- }
-
- /* find an unused frame */
- for (i = 0; i < MAX_FRAMES; i++)
- if (s->all_frames[i].avframe->data[0] == NULL)
- pic = &s->all_frames[i];
- if (!pic) {
- av_log(avctx, AV_LOG_ERROR, "framelist full\n");
- return AVERROR_INVALIDDATA;
- }
-
- av_frame_unref(pic->avframe);
-
- /* [DIRAC_STD] Defined in 9.6.1 ... */
- tmp = parse_code & 0x03; /* [DIRAC_STD] num_refs() */
- if (tmp > 2) {
- av_log(avctx, AV_LOG_ERROR, "num_refs of 3\n");
- return AVERROR_INVALIDDATA;
- }
- s->num_refs = tmp;
- s->is_arith = (parse_code & 0x48) == 0x08; /* [DIRAC_STD] using_ac() */
- s->low_delay = (parse_code & 0x88) == 0x88; /* [DIRAC_STD] is_low_delay() */
- pic->reference = (parse_code & 0x0C) == 0x0C; /* [DIRAC_STD] is_reference() */
- pic->avframe->key_frame = s->num_refs == 0; /* [DIRAC_STD] is_intra() */
- pic->avframe->pict_type = s->num_refs + 1; /* Definition of AVPictureType in avutil.h */
-
- if ((ret = get_buffer_with_edge(avctx, pic->avframe, (parse_code & 0x0C) == 0x0C ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
- return ret;
- s->current_picture = pic;
- s->plane[0].stride = pic->avframe->linesize[0];
- s->plane[1].stride = pic->avframe->linesize[1];
- s->plane[2].stride = pic->avframe->linesize[2];
-
- if (alloc_buffers(s, FFMAX3(FFABS(s->plane[0].stride), FFABS(s->plane[1].stride), FFABS(s->plane[2].stride))) < 0)
- return AVERROR(ENOMEM);
-
- /* [DIRAC_STD] 11.1 Picture parse. picture_parse() */
- ret = dirac_decode_picture_header(s);
- if (ret < 0)
- return ret;
-
- /* [DIRAC_STD] 13.0 Transform data syntax. transform_data() */
- ret = dirac_decode_frame_internal(s);
- if (ret < 0)
- return ret;
- }
- return 0;
-}
-
-static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt)
-{
- DiracContext *s = avctx->priv_data;
- AVFrame *picture = data;
- uint8_t *buf = pkt->data;
- int buf_size = pkt->size;
- int i, buf_idx = 0;
- int ret;
- unsigned data_unit_size;
-
- /* release unused frames */
- for (i = 0; i < MAX_FRAMES; i++)
- if (s->all_frames[i].avframe->data[0] && !s->all_frames[i].reference) {
- av_frame_unref(s->all_frames[i].avframe);
- memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated));
- }
-
- s->current_picture = NULL;
- *got_frame = 0;
-
- /* end of stream, so flush delayed pics */
- if (buf_size == 0)
- return get_delayed_pic(s, (AVFrame *)data, got_frame);
-
- for (;;) {
- /*[DIRAC_STD] Here starts the code from parse_info() defined in 9.6
- [DIRAC_STD] PARSE_INFO_PREFIX = "BBCD" as defined in ISO/IEC 646
- BBCD start code search */
- for (; buf_idx + DATA_UNIT_HEADER_SIZE < buf_size; buf_idx++) {
- if (buf[buf_idx ] == 'B' && buf[buf_idx+1] == 'B' &&
- buf[buf_idx+2] == 'C' && buf[buf_idx+3] == 'D')
- break;
- }
- /* BBCD found or end of data */
- if (buf_idx + DATA_UNIT_HEADER_SIZE >= buf_size)
- break;
-
- data_unit_size = AV_RB32(buf+buf_idx+5);
- if (data_unit_size > buf_size - buf_idx || !data_unit_size) {
- if(data_unit_size > buf_size - buf_idx)
- av_log(s->avctx, AV_LOG_ERROR,
- "Data unit with size %d is larger than input buffer, discarding\n",
- data_unit_size);
- buf_idx += 4;
- continue;
- }
- /* [DIRAC_STD] dirac_decode_data_unit makes reference to the while defined in 9.3 inside the function parse_sequence() */
- ret = dirac_decode_data_unit(avctx, buf+buf_idx, data_unit_size);
- if (ret < 0)
- {
- av_log(s->avctx, AV_LOG_ERROR,"Error in dirac_decode_data_unit\n");
- return ret;
- }
- buf_idx += data_unit_size;
- }
-
- if (!s->current_picture)
- return buf_size;
-
- if (s->current_picture->avframe->display_picture_number > s->frame_number) {
- DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number);
-
- s->current_picture->reference |= DELAYED_PIC_REF;
-
- if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) {
- int min_num = s->delay_frames[0]->avframe->display_picture_number;
- /* Too many delayed frames, so we display the frame with the lowest pts */
- av_log(avctx, AV_LOG_ERROR, "Delay frame overflow\n");
-
- for (i = 1; s->delay_frames[i]; i++)
- if (s->delay_frames[i]->avframe->display_picture_number < min_num)
- min_num = s->delay_frames[i]->avframe->display_picture_number;
-
- delayed_frame = remove_frame(s->delay_frames, min_num);
- add_frame(s->delay_frames, MAX_DELAY, s->current_picture);
- }
-
- if (delayed_frame) {
- delayed_frame->reference ^= DELAYED_PIC_REF;
- if((ret=av_frame_ref(data, delayed_frame->avframe)) < 0)
- return ret;
- *got_frame = 1;
- }
- } else if (s->current_picture->avframe->display_picture_number == s->frame_number) {
- /* The right frame at the right time :-) */
- if((ret=av_frame_ref(data, s->current_picture->avframe)) < 0)
- return ret;
- *got_frame = 1;
- }
-
- if (*got_frame)
- s->frame_number = picture->display_picture_number + 1;
-
- return buf_idx;
-}
-
-AVCodec ff_dirac_decoder = {
- .name = "dirac",
- .long_name = NULL_IF_CONFIG_SMALL("BBC Dirac VC-2"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_DIRAC,
- .priv_data_size = sizeof(DiracContext),
- .init = dirac_decode_init,
- .close = dirac_decode_end,
- .decode = dirac_decode_frame,
- .capabilities = AV_CODEC_CAP_DELAY,
- .flush = dirac_decode_flush,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/dss_sp.c b/ffmpeg-2-8-11/libavcodec/dss_sp.c
deleted file mode 100644
index 7cf8489..0000000
--- a/ffmpeg-2-8-11/libavcodec/dss_sp.c
+++ /dev/null
@@ -1,787 +0,0 @@
-/*
- * Digital Speech Standard - Standard Play mode (DSS SP) audio decoder.
- * Copyright (C) 2014 Oleksij Rempel <linux at rempel-privat.de>
- *
- * 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/common.h"
-#include "libavutil/mem.h"
-#include "libavutil/opt.h"
-
-#include "avcodec.h"
-#include "get_bits.h"
-#include "internal.h"
-
-#define SUBFRAMES 4
-#define PULSE_MAX 8
-
-#define DSS_SP_FRAME_SIZE 42
-#define DSS_SP_SAMPLE_COUNT (66 * SUBFRAMES)
-#define DSS_SP_FORMULA(a, b, c) (((((a) << 15) + (b) * (c)) + 0x4000) >> 15)
-
-typedef struct DssSpSubframe {
- int16_t gain;
- int32_t combined_pulse_pos;
- int16_t pulse_pos[7];
- int16_t pulse_val[7];
-} DssSpSubframe;
-
-typedef struct DssSpFrame {
- int16_t filter_idx[14];
- int16_t sf_adaptive_gain[SUBFRAMES];
- int16_t pitch_lag[SUBFRAMES];
- struct DssSpSubframe sf[SUBFRAMES];
-} DssSpFrame;
-
-typedef struct DssSpContext {
- AVCodecContext *avctx;
- int32_t excitation[288 + 6];
- int32_t history[187];
- DssSpFrame fparam;
- int32_t working_buffer[SUBFRAMES][72];
- int32_t audio_buf[15];
- int32_t err_buf1[15];
- int32_t lpc_filter[14];
- int32_t filter[15];
- int32_t vector_buf[72];
- int noise_state;
- int32_t err_buf2[15];
-
- int pulse_dec_mode;
-
- DECLARE_ALIGNED(16, uint8_t, bits)[DSS_SP_FRAME_SIZE +
- AV_INPUT_BUFFER_PADDING_SIZE];
-} DssSpContext;
-
-/*
- * Used for the coding/decoding of the pulse positions for the MP-MLQ codebook.
- */
-static const uint32_t dss_sp_combinatorial_table[PULSE_MAX][72] = {
- { 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0 },
- { 0, 1, 2, 3, 4, 5,
- 6, 7, 8, 9, 10, 11,
- 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35,
- 36, 37, 38, 39, 40, 41,
- 42, 43, 44, 45, 46, 47,
- 48, 49, 50, 51, 52, 53,
- 54, 55, 56, 57, 58, 59,
- 60, 61, 62, 63, 64, 65,
- 66, 67, 68, 69, 70, 71 },
- { 0, 0, 1, 3, 6, 10,
- 15, 21, 28, 36, 45, 55,
- 66, 78, 91, 105, 120, 136,
- 153, 171, 190, 210, 231, 253,
- 276, 300, 325, 351, 378, 406,
- 435, 465, 496, 528, 561, 595,
- 630, 666, 703, 741, 780, 820,
- 861, 903, 946, 990, 1035, 1081,
- 1128, 1176, 1225, 1275, 1326, 1378,
- 1431, 1485, 1540, 1596, 1653, 1711,
- 1770, 1830, 1891, 1953, 2016, 2080,
- 2145, 2211, 2278, 2346, 2415, 2485 },
- { 0, 0, 0, 1, 4, 10,
- 20, 35, 56, 84, 120, 165,
- 220, 286, 364, 455, 560, 680,
- 816, 969, 1140, 1330, 1540, 1771,
- 2024, 2300, 2600, 2925, 3276, 3654,
- 4060, 4495, 4960, 5456, 5984, 6545,
- 7140, 7770, 8436, 9139, 9880, 10660,
- 11480, 12341, 13244, 14190, 15180, 16215,
- 17296, 18424, 19600, 20825, 22100, 23426,
- 24804, 26235, 27720, 29260, 30856, 32509,
- 34220, 35990, 37820, 39711, 41664, 43680,
- 45760, 47905, 50116, 52394, 54740, 57155 },
- { 0, 0, 0, 0, 1, 5,
- 15, 35, 70, 126, 210, 330,
- 495, 715, 1001, 1365, 1820, 2380,
- 3060, 3876, 4845, 5985, 7315, 8855,
- 10626, 12650, 14950, 17550, 20475, 23751,
- 27405, 31465, 35960, 40920, 46376, 52360,
- 58905, 66045, 73815, 82251, 91390, 101270,
- 111930, 123410, 135751, 148995, 163185, 178365,
- 194580, 211876, 230300, 249900, 270725, 292825,
- 316251, 341055, 367290, 395010, 424270, 455126,
- 487635, 521855, 557845, 595665, 635376, 677040,
- 720720, 766480, 814385, 864501, 916895, 971635 },
- { 0, 0, 0, 0, 0, 1,
- 6, 21, 56, 126, 252, 462,
- 792, 1287, 2002, 3003, 4368, 6188,
- 8568, 11628, 15504, 20349, 26334, 33649,
- 42504, 53130, 65780, 80730, 98280, 118755,
- 142506, 169911, 201376, 237336, 278256, 324632,
- 376992, 435897, 501942, 575757, 658008, 749398,
- 850668, 962598, 1086008, 1221759, 1370754, 1533939,
- 1712304, 1906884, 2118760, 2349060, 2598960, 2869685,
- 3162510, 3478761, 3819816, 4187106, 4582116, 5006386,
- 5461512, 5949147, 6471002, 7028847, 7624512, 8259888,
- 8936928, 9657648, 10424128, 11238513, 12103014, 13019909 },
- { 0, 0, 0, 0, 0, 0,
- 1, 7, 28, 84, 210, 462,
- 924, 1716, 3003, 5005, 8008, 12376,
- 18564, 27132, 38760, 54264, 74613, 100947,
- 134596, 177100, 230230, 296010, 376740, 475020,
- 593775, 736281, 906192, 1107568, 1344904, 1623160,
- 1947792, 2324784, 2760681, 3262623, 3838380, 4496388,
- 5245786, 6096454, 7059052, 8145060, 9366819, 10737573,
- 12271512, 13983816, 15890700, 18009460, 20358520, 22957480,
- 25827165, 28989675, 32468436, 36288252, 40475358, 45057474,
- 50063860, 55525372, 61474519, 67945521, 74974368, 82598880,
- 90858768, 99795696, 109453344, 119877472, 131115985, 143218999 },
- { 0, 0, 0, 0, 0, 0,
- 0, 1, 8, 36, 120, 330,
- 792, 1716, 3432, 6435, 11440, 19448,
- 31824, 50388, 77520, 116280, 170544, 245157,
- 346104, 480700, 657800, 888030, 1184040, 1560780,
- 2035800, 2629575, 3365856, 4272048, 5379616, 6724520,
- 8347680, 10295472, 12620256, 15380937, 18643560, 22481940,
- 26978328, 32224114, 38320568, 45379620, 53524680, 62891499,
- 73629072, 85900584, 99884400, 115775100, 133784560, 154143080,
- 177100560, 202927725, 231917400, 264385836, 300674088, 341149446,
- 386206920, 436270780, 491796152, 553270671, 621216192, 696190560,
- 778789440, 869648208, 969443904, 1078897248, 1198774720, 1329890705 },
-};
-
-static const int16_t dss_sp_filter_cb[14][32] = {
- { -32653, -32587, -32515, -32438, -32341, -32216, -32062, -31881,
- -31665, -31398, -31080, -30724, -30299, -29813, -29248, -28572,
- -27674, -26439, -24666, -22466, -19433, -16133, -12218, -7783,
- -2834, 1819, 6544, 11260, 16050, 20220, 24774, 28120 },
-
- { -27503, -24509, -20644, -17496, -14187, -11277, -8420, -5595,
- -3013, -624, 1711, 3880, 5844, 7774, 9739, 11592,
- 13364, 14903, 16426, 17900, 19250, 20586, 21803, 23006,
- 24142, 25249, 26275, 27300, 28359, 29249, 30118, 31183 },
-
- { -27827, -24208, -20943, -17781, -14843, -11848, -9066, -6297,
- -3660, -910, 1918, 5025, 8223, 11649, 15086, 18423,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 },
-
- { -17128, -11975, -8270, -5123, -2296, 183, 2503, 4707,
- 6798, 8945, 11045, 13239, 15528, 18248, 21115, 24785,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 },
-
- { -21557, -17280, -14286, -11644, -9268, -7087, -4939, -2831,
- -691, 1407, 3536, 5721, 8125, 10677, 13721, 17731,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 },
-
- { -15030, -10377, -7034, -4327, -1900, 364, 2458, 4450,
- 6422, 8374, 10374, 12486, 14714, 16997, 19626, 22954,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 },
-
- { -16155, -12362, -9698, -7460, -5258, -3359, -1547, 219,
- 1916, 3599, 5299, 6994, 8963, 11226, 13716, 16982,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 },
-
- { -14742, -9848, -6921, -4648, -2769, -1065, 499, 2083,
- 3633, 5219, 6857, 8580, 10410, 12672, 15561, 20101,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 },
-
- { -11099, -7014, -3855, -1025, 1680, 4544, 7807, 11932,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 },
-
- { -9060, -4570, -1381, 1419, 4034, 6728, 9865, 14149,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 },
-
- { -12450, -7985, -4596, -1734, 961, 3629, 6865, 11142,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 },
-
- { -11831, -7404, -4010, -1096, 1606, 4291, 7386, 11482,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 },
-
- { -13404, -9250, -5995, -3312, -890, 1594, 4464, 8198,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 },
-
- { -11239, -7220, -4040, -1406, 971, 3321, 6006, 9697,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 },
-};
-
-static const uint16_t dss_sp_fixed_cb_gain[64] = {
- 0, 4, 8, 13, 17, 22, 26, 31,
- 35, 40, 44, 48, 53, 58, 63, 69,
- 76, 83, 91, 99, 109, 119, 130, 142,
- 155, 170, 185, 203, 222, 242, 265, 290,
- 317, 346, 378, 414, 452, 494, 540, 591,
- 646, 706, 771, 843, 922, 1007, 1101, 1204,
- 1316, 1438, 1572, 1719, 1879, 2053, 2244, 2453,
- 2682, 2931, 3204, 3502, 3828, 4184, 4574, 5000,
-};
-
-static const int16_t dss_sp_pulse_val[8] = {
- -31182, -22273, -13364, -4455, 4455, 13364, 22273, 31182
-};
-
-static const uint16_t binary_decreasing_array[] = {
- 32767, 16384, 8192, 4096, 2048, 1024, 512, 256,
- 128, 64, 32, 16, 8, 4, 2,
-};
-
-static const uint16_t dss_sp_unc_decreasing_array[] = {
- 32767, 26214, 20972, 16777, 13422, 10737, 8590, 6872,
- 5498, 4398, 3518, 2815, 2252, 1801, 1441,
-};
-
-static const uint16_t dss_sp_adaptive_gain[] = {
- 102, 231, 360, 488, 617, 746, 875, 1004,
- 1133, 1261, 1390, 1519, 1648, 1777, 1905, 2034,
- 2163, 2292, 2421, 2550, 2678, 2807, 2936, 3065,
- 3194, 3323, 3451, 3580, 3709, 3838, 3967, 4096,
-};
-
-static const int32_t dss_sp_sinc[67] = {
- 262, 293, 323, 348, 356, 336, 269, 139,
- -67, -358, -733, -1178, -1668, -2162, -2607, -2940,
- -3090, -2986, -2562, -1760, -541, 1110, 3187, 5651,
- 8435, 11446, 14568, 17670, 20611, 23251, 25460, 27125,
- 28160, 28512, 28160,
- 27125, 25460, 23251, 20611, 17670, 14568, 11446, 8435,
- 5651, 3187, 1110, -541, -1760, -2562, -2986, -3090,
- -2940, -2607, -2162, -1668, -1178, -733, -358, -67,
- 139, 269, 336, 356, 348, 323, 293, 262,
-};
-
-static av_cold int dss_sp_decode_init(AVCodecContext *avctx)
-{
- DssSpContext *p = avctx->priv_data;
- avctx->channel_layout = AV_CH_LAYOUT_MONO;
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
- avctx->channels = 1;
- avctx->sample_rate = 11025;
-
- memset(p->history, 0, sizeof(p->history));
- p->pulse_dec_mode = 1;
- p->avctx = avctx;
-
- return 0;
-}
-
-static void dss_sp_unpack_coeffs(DssSpContext *p, const uint8_t *src)
-{
- GetBitContext gb;
- DssSpFrame *fparam = &p->fparam;
- int i;
- int subframe_idx;
- uint32_t combined_pitch;
- uint32_t tmp;
- uint32_t pitch_lag;
-
- for (i = 0; i < DSS_SP_FRAME_SIZE; i += 2) {
- p->bits[i] = src[i + 1];
- p->bits[i + 1] = src[i];
- }
-
- init_get_bits(&gb, p->bits, DSS_SP_FRAME_SIZE * 8);
-
- for (i = 0; i < 2; i++)
- fparam->filter_idx[i] = get_bits(&gb, 5);
- for (; i < 8; i++)
- fparam->filter_idx[i] = get_bits(&gb, 4);
- for (; i < 14; i++)
- fparam->filter_idx[i] = get_bits(&gb, 3);
-
- for (subframe_idx = 0; subframe_idx < 4; subframe_idx++) {
- fparam->sf_adaptive_gain[subframe_idx] = get_bits(&gb, 5);
-
- fparam->sf[subframe_idx].combined_pulse_pos = get_bits_long(&gb, 31);
-
- fparam->sf[subframe_idx].gain = get_bits(&gb, 6);
-
- for (i = 0; i < 7; i++)
- fparam->sf[subframe_idx].pulse_val[i] = get_bits(&gb, 3);
- }
-
- for (subframe_idx = 0; subframe_idx < 4; subframe_idx++) {
- unsigned int C72_binomials[PULSE_MAX] = {
- 72, 2556, 59640, 1028790, 13991544, 156238908, 1473109704,
- 3379081753
- };
- unsigned int combined_pulse_pos =
- fparam->sf[subframe_idx].combined_pulse_pos;
- int index = 6;
-
- if (combined_pulse_pos < C72_binomials[PULSE_MAX - 1]) {
- if (p->pulse_dec_mode) {
- int pulse, pulse_idx;
- pulse = PULSE_MAX - 1;
- pulse_idx = 71;
- combined_pulse_pos =
- fparam->sf[subframe_idx].combined_pulse_pos;
-
- /* this part seems to be close to g723.1 gen_fcb_excitation()
- * RATE_6300 */
-
- /* TODO: what is 7? size of subframe? */
- for (i = 0; i < 7; i++) {
- for (;
- combined_pulse_pos <
- dss_sp_combinatorial_table[pulse][pulse_idx];
- --pulse_idx)
- ;
- combined_pulse_pos -=
- dss_sp_combinatorial_table[pulse][pulse_idx];
- pulse--;
- fparam->sf[subframe_idx].pulse_pos[i] = pulse_idx;
- }
- }
- } else {
- p->pulse_dec_mode = 0;
-
- /* why do we need this? */
- fparam->sf[subframe_idx].pulse_pos[6] = 0;
-
- for (i = 71; i >= 0; i--) {
- if (C72_binomials[index] <= combined_pulse_pos) {
- combined_pulse_pos -= C72_binomials[index];
-
- fparam->sf[subframe_idx].pulse_pos[6 - index] = i;
-
- if (!index)
- break;
- --index;
- }
- --C72_binomials[0];
- if (index) {
- int a;
- for (a = 0; a < index; a++)
- C72_binomials[a + 1] -= C72_binomials[a];
- }
- }
- }
- }
-
- combined_pitch = get_bits(&gb, 24);
-
- fparam->pitch_lag[0] = (combined_pitch % 151) + 36;
-
- combined_pitch /= 151;
-
- for (i = 1; i < SUBFRAMES - 1; i++) {
- fparam->pitch_lag[i] = combined_pitch % 48;
- combined_pitch /= 48;
- }
- if (combined_pitch > 47) {
- av_log (p->avctx, AV_LOG_WARNING, "combined_pitch was too large\n");
- combined_pitch = 0;
- }
- fparam->pitch_lag[i] = combined_pitch;
-
- pitch_lag = fparam->pitch_lag[0];
- for (i = 1; i < SUBFRAMES; i++) {
- if (pitch_lag > 162) {
- fparam->pitch_lag[i] += 162 - 23;
- } else {
- tmp = pitch_lag - 23;
- if (tmp < 36)
- tmp = 36;
- fparam->pitch_lag[i] += tmp;
- }
- pitch_lag = fparam->pitch_lag[i];
- }
-}
-
-static void dss_sp_unpack_filter(DssSpContext *p)
-{
- int i;
-
- for (i = 0; i < 14; i++)
- p->lpc_filter[i] = dss_sp_filter_cb[i][p->fparam.filter_idx[i]];
-}
-
-static void dss_sp_convert_coeffs(int32_t *lpc_filter, int32_t *coeffs)
-{
- int a, a_plus, i;
-
- coeffs[0] = 0x2000;
- for (a = 0; a < 14; a++) {
- a_plus = a + 1;
- coeffs[a_plus] = lpc_filter[a] >> 2;
- if (a_plus / 2 >= 1) {
- for (i = 1; i <= a_plus / 2; i++) {
- int coeff_1, coeff_2, tmp;
-
- coeff_1 = coeffs[i];
- coeff_2 = coeffs[a_plus - i];
-
- tmp = DSS_SP_FORMULA(coeff_1, lpc_filter[a], coeff_2);
- coeffs[i] = av_clip_int16(tmp);
-
- tmp = DSS_SP_FORMULA(coeff_2, lpc_filter[a], coeff_1);
- coeffs[a_plus - i] = av_clip_int16(tmp);
- }
- }
- }
-}
-
-static void dss_sp_add_pulses(int32_t *vector_buf,
- const struct DssSpSubframe *sf)
-{
- int i;
-
- for (i = 0; i < 7; i++)
- vector_buf[sf->pulse_pos[i]] += (dss_sp_fixed_cb_gain[sf->gain] *
- dss_sp_pulse_val[sf->pulse_val[i]] +
- 0x4000) >> 15;
-}
-
-static void dss_sp_gen_exc(int32_t *vector, int32_t *prev_exc,
- int pitch_lag, int gain)
-{
- int i;
-
- /* do we actually need this check? we can use just [a3 - i % a3]
- * for both cases */
- if (pitch_lag < 72)
- for (i = 0; i < 72; i++)
- vector[i] = prev_exc[pitch_lag - i % pitch_lag];
- else
- for (i = 0; i < 72; i++)
- vector[i] = prev_exc[pitch_lag - i];
-
- for (i = 0; i < 72; i++) {
- int tmp = gain * vector[i] >> 11;
- vector[i] = av_clip_int16(tmp);
- }
-}
-
-static void dss_sp_scale_vector(int32_t *vec, int bits, int size)
-{
- int i;
-
- if (bits < 0)
- for (i = 0; i < size; i++)
- vec[i] = vec[i] >> -bits;
- else
- for (i = 0; i < size; i++)
- vec[i] = vec[i] << bits;
-}
-
-static void dss_sp_update_buf(int32_t *hist, int32_t *vector)
-{
- int i;
-
- for (i = 114; i > 0; i--)
- vector[i + 72] = vector[i];
-
- for (i = 0; i < 72; i++)
- vector[72 - i] = hist[i];
-}
-
-static void dss_sp_shift_sq_sub(const int32_t *filter_buf,
- int32_t *error_buf, int32_t *dst)
-{
- int a;
-
- for (a = 0; a < 72; a++) {
- int i, tmp;
-
- tmp = dst[a] * filter_buf[0];
-
- for (i = 14; i > 0; i--)
- tmp -= error_buf[i] * filter_buf[i];
-
- for (i = 14; i > 0; i--)
- error_buf[i] = error_buf[i - 1];
-
- tmp = (tmp + 4096) >> 13;
-
- error_buf[1] = tmp;
-
- dst[a] = av_clip_int16(tmp);
- }
-}
-
-static void dss_sp_shift_sq_add(const int32_t *filter_buf, int32_t *audio_buf,
- int32_t *dst)
-{
- int a;
-
- for (a = 0; a < 72; a++) {
- int i, tmp = 0;
-
- audio_buf[0] = dst[a];
-
- for (i = 14; i >= 0; i--)
- tmp += audio_buf[i] * filter_buf[i];
-
- for (i = 14; i > 0; i--)
- audio_buf[i] = audio_buf[i - 1];
-
- tmp = (tmp + 4096) >> 13;
-
- dst[a] = av_clip_int16(tmp);
- }
-}
-
-static void dss_sp_vec_mult(const int32_t *src, int32_t *dst,
- const int16_t *mult)
-{
- int i;
-
- dst[0] = src[0];
-
- for (i = 1; i < 15; i++)
- dst[i] = (src[i] * mult[i] + 0x4000) >> 15;
-}
-
-static int dss_sp_get_normalize_bits(int32_t *vector_buf, int16_t size)
-{
- unsigned int val;
- int max_val;
- int i;
-
- val = 1;
- for (i = 0; i < size; i++)
- val |= FFABS(vector_buf[i]);
-
- for (max_val = 0; val <= 0x4000; ++max_val)
- val *= 2;
- return max_val;
-}
-
-static int dss_sp_vector_sum(DssSpContext *p, int size)
-{
- int i, sum = 0;
- for (i = 0; i < size; i++)
- sum += FFABS(p->vector_buf[i]);
- return sum;
-}
-
-static void dss_sp_sf_synthesis(DssSpContext *p, int32_t lpc_filter,
- int32_t *dst, int size)
-{
- int32_t tmp_buf[15];
- int32_t noise[72];
- int bias, vsum_2 = 0, vsum_1 = 0, v36, normalize_bits;
- int i, tmp;
-
- if (size > 0) {
- vsum_1 = dss_sp_vector_sum(p, size);
-
- if (vsum_1 > 0xFFFFF)
- vsum_1 = 0xFFFFF;
- }
-
- normalize_bits = dss_sp_get_normalize_bits(p->vector_buf, size);
-
- dss_sp_scale_vector(p->vector_buf, normalize_bits - 3, size);
- dss_sp_scale_vector(p->audio_buf, normalize_bits, 15);
- dss_sp_scale_vector(p->err_buf1, normalize_bits, 15);
-
- v36 = p->err_buf1[1];
-
- dss_sp_vec_mult(p->filter, tmp_buf, binary_decreasing_array);
- dss_sp_shift_sq_add(tmp_buf, p->audio_buf, p->vector_buf);
-
- dss_sp_vec_mult(p->filter, tmp_buf, dss_sp_unc_decreasing_array);
- dss_sp_shift_sq_sub(tmp_buf, p->err_buf1, p->vector_buf);
-
- /* lpc_filter can be negative */
- lpc_filter = lpc_filter >> 1;
- if (lpc_filter >= 0)
- lpc_filter = 0;
-
- if (size > 1) {
- for (i = size - 1; i > 0; i--) {
- tmp = DSS_SP_FORMULA(p->vector_buf[i], lpc_filter,
- p->vector_buf[i - 1]);
- p->vector_buf[i] = av_clip_int16(tmp);
- }
- }
-
- tmp = DSS_SP_FORMULA(p->vector_buf[0], lpc_filter, v36);
- p->vector_buf[0] = av_clip_int16(tmp);
-
- dss_sp_scale_vector(p->vector_buf, -normalize_bits, size);
- dss_sp_scale_vector(p->audio_buf, -normalize_bits, 15);
- dss_sp_scale_vector(p->err_buf1, -normalize_bits, 15);
-
- if (size > 0)
- vsum_2 = dss_sp_vector_sum(p, size);
-
- if (vsum_2 >= 0x40)
- tmp = (vsum_1 << 11) / vsum_2;
- else
- tmp = 1;
-
- bias = 409 * tmp >> 15 << 15;
- tmp = (bias + 32358 * p->noise_state) >> 15;
- noise[0] = av_clip_int16(tmp);
-
- for (i = 1; i < size; i++) {
- tmp = (bias + 32358 * noise[i - 1]) >> 15;
- noise[i] = av_clip_int16(tmp);
- }
-
- p->noise_state = noise[size - 1];
- for (i = 0; i < size; i++) {
- tmp = (p->vector_buf[i] * noise[i]) >> 11;
- dst[i] = av_clip_int16(tmp);
- }
-}
-
-static void dss_sp_update_state(DssSpContext *p, int32_t *dst)
-{
- int i, offset = 6, counter = 0, a = 0;
-
- for (i = 0; i < 6; i++)
- p->excitation[i] = p->excitation[288 + i];
-
- for (i = 0; i < 72 * SUBFRAMES; i++)
- p->excitation[6 + i] = dst[i];
-
- do {
- int tmp = 0;
-
- for (i = 0; i < 6; i++)
- tmp += p->excitation[offset--] * dss_sp_sinc[a + i * 11];
-
- offset += 7;
-
- tmp >>= 15;
- dst[counter] = av_clip_int16(tmp);
-
- counter++;
-
- a = (a + 1) % 11;
- if (!a)
- offset++;
- } while (offset < FF_ARRAY_ELEMS(p->excitation));
-}
-
-static void dss_sp_32to16bit(int16_t *dst, int32_t *src, int size)
-{
- int i;
-
- for (i = 0; i < size; i++)
- dst[i] = av_clip_int16(src[i]);
-}
-
-static int dss_sp_decode_one_frame(DssSpContext *p,
- int16_t *abuf_dst, const uint8_t *abuf_src)
-{
- int i, j;
-
- dss_sp_unpack_coeffs(p, abuf_src);
-
- dss_sp_unpack_filter(p);
-
- dss_sp_convert_coeffs(p->lpc_filter, p->filter);
-
- for (j = 0; j < SUBFRAMES; j++) {
- dss_sp_gen_exc(p->vector_buf, p->history,
- p->fparam.pitch_lag[j],
- dss_sp_adaptive_gain[p->fparam.sf_adaptive_gain[j]]);
-
- dss_sp_add_pulses(p->vector_buf, &p->fparam.sf[j]);
-
- dss_sp_update_buf(p->vector_buf, p->history);
-
- for (i = 0; i < 72; i++)
- p->vector_buf[i] = p->history[72 - i];
-
- dss_sp_shift_sq_sub(p->filter,
- p->err_buf2, p->vector_buf);
-
- dss_sp_sf_synthesis(p, p->lpc_filter[0],
- &p->working_buffer[j][0], 72);
- }
-
- dss_sp_update_state(p, &p->working_buffer[0][0]);
-
- dss_sp_32to16bit(abuf_dst,
- &p->working_buffer[0][0], 264);
- return 0;
-}
-
-static int dss_sp_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- DssSpContext *p = avctx->priv_data;
- AVFrame *frame = data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
-
- int16_t *out;
- int ret;
-
- if (buf_size < DSS_SP_FRAME_SIZE) {
- if (buf_size)
- av_log(avctx, AV_LOG_WARNING,
- "Expected %d bytes, got %d - skipping packet.\n",
- DSS_SP_FRAME_SIZE, buf_size);
- *got_frame_ptr = 0;
- return AVERROR_INVALIDDATA;
- }
-
- frame->nb_samples = DSS_SP_SAMPLE_COUNT;
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "get_buffer() failed.\n");
- return ret;
- }
-
- out = (int16_t *)frame->data[0];
-
- dss_sp_decode_one_frame(p, out, buf);
-
- *got_frame_ptr = 1;
-
- return DSS_SP_FRAME_SIZE;
-}
-
-AVCodec ff_dss_sp_decoder = {
- .name = "dss_sp",
- .long_name = NULL_IF_CONFIG_SMALL("Digital Speech Standard - Standard Play mode (DSS SP)"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_DSS_SP,
- .priv_data_size = sizeof(DssSpContext),
- .init = dss_sp_decode_init,
- .decode = dss_sp_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/dvbsubdec.c b/ffmpeg-2-8-11/libavcodec/dvbsubdec.c
deleted file mode 100644
index ff670c4..0000000
--- a/ffmpeg-2-8-11/libavcodec/dvbsubdec.c
+++ /dev/null
@@ -1,1743 +0,0 @@
-/*
- * DVB subtitle decoding
- * Copyright (c) 2005 Ian Caulfield
- *
- * 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 "get_bits.h"
-#include "bytestream.h"
-#include "internal.h"
-#include "libavutil/colorspace.h"
-#include "libavutil/opt.h"
-
-#define DVBSUB_PAGE_SEGMENT 0x10
-#define DVBSUB_REGION_SEGMENT 0x11
-#define DVBSUB_CLUT_SEGMENT 0x12
-#define DVBSUB_OBJECT_SEGMENT 0x13
-#define DVBSUB_DISPLAYDEFINITION_SEGMENT 0x14
-#define DVBSUB_DISPLAY_SEGMENT 0x80
-
-#define cm (ff_crop_tab + MAX_NEG_CROP)
-
-#ifdef DEBUG
-#if 0
-static void png_save(const char *filename, uint8_t *bitmap, int w, int h,
- uint32_t *rgba_palette)
-{
- int x, y, v;
- FILE *f;
- char fname[40], fname2[40];
- char command[1024];
-
- snprintf(fname, 40, "%s.ppm", filename);
-
- f = fopen(fname, "w");
- if (!f) {
- perror(fname);
- return;
- }
- fprintf(f, "P6\n"
- "%d %d\n"
- "%d\n",
- w, h, 255);
- for(y = 0; y < h; y++) {
- for(x = 0; x < w; x++) {
- v = rgba_palette[bitmap[y * w + x]];
- putc((v >> 16) & 0xff, f);
- putc((v >> 8) & 0xff, f);
- putc((v >> 0) & 0xff, f);
- }
- }
- fclose(f);
-
-
- snprintf(fname2, 40, "%s-a.pgm", filename);
-
- f = fopen(fname2, "w");
- if (!f) {
- perror(fname2);
- return;
- }
- fprintf(f, "P5\n"
- "%d %d\n"
- "%d\n",
- w, h, 255);
- for(y = 0; y < h; y++) {
- for(x = 0; x < w; x++) {
- v = rgba_palette[bitmap[y * w + x]];
- putc((v >> 24) & 0xff, f);
- }
- }
- fclose(f);
-
- snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);
- system(command);
-
- snprintf(command, 1024, "rm %s %s", fname, fname2);
- system(command);
-}
-#endif
-
-static void png_save2(const char *filename, uint32_t *bitmap, int w, int h)
-{
- int x, y, v;
- FILE *f;
- char fname[40], fname2[40];
- char command[1024];
-
- snprintf(fname, sizeof(fname), "%s.ppm", filename);
-
- f = fopen(fname, "w");
- if (!f) {
- perror(fname);
- return;
- }
- fprintf(f, "P6\n"
- "%d %d\n"
- "%d\n",
- w, h, 255);
- for(y = 0; y < h; y++) {
- for(x = 0; x < w; x++) {
- v = bitmap[y * w + x];
- putc((v >> 16) & 0xff, f);
- putc((v >> 8) & 0xff, f);
- putc((v >> 0) & 0xff, f);
- }
- }
- fclose(f);
-
-
- snprintf(fname2, sizeof(fname2), "%s-a.pgm", filename);
-
- f = fopen(fname2, "w");
- if (!f) {
- perror(fname2);
- return;
- }
- fprintf(f, "P5\n"
- "%d %d\n"
- "%d\n",
- w, h, 255);
- for(y = 0; y < h; y++) {
- for(x = 0; x < w; x++) {
- v = bitmap[y * w + x];
- putc((v >> 24) & 0xff, f);
- }
- }
- fclose(f);
-
- snprintf(command, sizeof(command), "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);
- system(command);
-
- snprintf(command, sizeof(command), "rm %s %s", fname, fname2);
- system(command);
-}
-#endif
-
-#define RGBA(r,g,b,a) (((unsigned)(a) << 24) | ((r) << 16) | ((g) << 8) | (b))
-
-typedef struct DVBSubCLUT {
- int id;
- int version;
-
- uint32_t clut4[4];
- uint32_t clut16[16];
- uint32_t clut256[256];
-
- struct DVBSubCLUT *next;
-} DVBSubCLUT;
-
-static DVBSubCLUT default_clut;
-
-typedef struct DVBSubObjectDisplay {
- int object_id;
- int region_id;
-
- int x_pos;
- int y_pos;
-
- int fgcolor;
- int bgcolor;
-
- struct DVBSubObjectDisplay *region_list_next;
- struct DVBSubObjectDisplay *object_list_next;
-} DVBSubObjectDisplay;
-
-typedef struct DVBSubObject {
- int id;
- int version;
-
- int type;
-
- DVBSubObjectDisplay *display_list;
-
- struct DVBSubObject *next;
-} DVBSubObject;
-
-typedef struct DVBSubRegionDisplay {
- int region_id;
-
- int x_pos;
- int y_pos;
-
- struct DVBSubRegionDisplay *next;
-} DVBSubRegionDisplay;
-
-typedef struct DVBSubRegion {
- int id;
- int version;
-
- int width;
- int height;
- int depth;
-
- int clut;
- int bgcolor;
-
- uint8_t *pbuf;
- int buf_size;
- int dirty;
-
- DVBSubObjectDisplay *display_list;
-
- struct DVBSubRegion *next;
-} DVBSubRegion;
-
-typedef struct DVBSubDisplayDefinition {
- int version;
-
- int x;
- int y;
- int width;
- int height;
-} DVBSubDisplayDefinition;
-
-typedef struct DVBSubContext {
- AVClass *class;
- int composition_id;
- int ancillary_id;
-
- int version;
- int time_out;
- int compute_edt; /**< if 1 end display time calculated using pts
- if 0 (Default) calculated using time out */
- int compute_clut;
- int substream;
- int64_t prev_start;
- DVBSubRegion *region_list;
- DVBSubCLUT *clut_list;
- DVBSubObject *object_list;
-
- DVBSubRegionDisplay *display_list;
- DVBSubDisplayDefinition *display_definition;
-} DVBSubContext;
-
-
-static DVBSubObject* get_object(DVBSubContext *ctx, int object_id)
-{
- DVBSubObject *ptr = ctx->object_list;
-
- while (ptr && ptr->id != object_id) {
- ptr = ptr->next;
- }
-
- return ptr;
-}
-
-static DVBSubCLUT* get_clut(DVBSubContext *ctx, int clut_id)
-{
- DVBSubCLUT *ptr = ctx->clut_list;
-
- while (ptr && ptr->id != clut_id) {
- ptr = ptr->next;
- }
-
- return ptr;
-}
-
-static DVBSubRegion* get_region(DVBSubContext *ctx, int region_id)
-{
- DVBSubRegion *ptr = ctx->region_list;
-
- while (ptr && ptr->id != region_id) {
- ptr = ptr->next;
- }
-
- return ptr;
-}
-
-static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region)
-{
- DVBSubObject *object, *obj2, **obj2_ptr;
- DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr;
-
- while (region->display_list) {
- display = region->display_list;
-
- object = get_object(ctx, display->object_id);
-
- if (object) {
- obj_disp_ptr = &object->display_list;
- obj_disp = *obj_disp_ptr;
-
- while (obj_disp && obj_disp != display) {
- obj_disp_ptr = &obj_disp->object_list_next;
- obj_disp = *obj_disp_ptr;
- }
-
- if (obj_disp) {
- *obj_disp_ptr = obj_disp->object_list_next;
-
- if (!object->display_list) {
- obj2_ptr = &ctx->object_list;
- obj2 = *obj2_ptr;
-
- while (obj2 != object) {
- av_assert0(obj2);
- obj2_ptr = &obj2->next;
- obj2 = *obj2_ptr;
- }
-
- *obj2_ptr = obj2->next;
-
- av_freep(&obj2);
- }
- }
- }
-
- region->display_list = display->region_list_next;
-
- av_freep(&display);
- }
-
-}
-
-static void delete_cluts(DVBSubContext *ctx)
-{
- while (ctx->clut_list) {
- DVBSubCLUT *clut = ctx->clut_list;
-
- ctx->clut_list = clut->next;
-
- av_freep(&clut);
- }
-}
-
-static void delete_objects(DVBSubContext *ctx)
-{
- while (ctx->object_list) {
- DVBSubObject *object = ctx->object_list;
-
- ctx->object_list = object->next;
-
- av_freep(&object);
- }
-}
-
-static void delete_regions(DVBSubContext *ctx)
-{
- while (ctx->region_list) {
- DVBSubRegion *region = ctx->region_list;
-
- ctx->region_list = region->next;
-
- delete_region_display_list(ctx, region);
-
- av_freep(®ion->pbuf);
- av_freep(®ion);
- }
-}
-
-static av_cold int dvbsub_init_decoder(AVCodecContext *avctx)
-{
- int i, r, g, b, a = 0;
- DVBSubContext *ctx = avctx->priv_data;
-
- if (ctx->substream < 0) {
- ctx->composition_id = -1;
- ctx->ancillary_id = -1;
- } else if (!avctx->extradata || (avctx->extradata_size < 4) || ((avctx->extradata_size % 5 != 0) && (avctx->extradata_size != 4))) {
- av_log(avctx, AV_LOG_WARNING, "Invalid DVB subtitles stream extradata!\n");
- ctx->composition_id = -1;
- ctx->ancillary_id = -1;
- } else {
- if (avctx->extradata_size > 5*ctx->substream + 2) {
- ctx->composition_id = AV_RB16(avctx->extradata + 5*ctx->substream);
- ctx->ancillary_id = AV_RB16(avctx->extradata + 5*ctx->substream + 2);
- } else {
- av_log(avctx, AV_LOG_WARNING, "Selected DVB subtitles sub-stream %d is not available\n", ctx->substream);
- ctx->composition_id = AV_RB16(avctx->extradata);
- ctx->ancillary_id = AV_RB16(avctx->extradata + 2);
- }
- }
-
- ctx->version = -1;
- ctx->prev_start = AV_NOPTS_VALUE;
-
- default_clut.id = -1;
- default_clut.next = NULL;
-
- default_clut.clut4[0] = RGBA( 0, 0, 0, 0);
- default_clut.clut4[1] = RGBA(255, 255, 255, 255);
- default_clut.clut4[2] = RGBA( 0, 0, 0, 255);
- default_clut.clut4[3] = RGBA(127, 127, 127, 255);
-
- default_clut.clut16[0] = RGBA( 0, 0, 0, 0);
- for (i = 1; i < 16; i++) {
- if (i < 8) {
- r = (i & 1) ? 255 : 0;
- g = (i & 2) ? 255 : 0;
- b = (i & 4) ? 255 : 0;
- } else {
- r = (i & 1) ? 127 : 0;
- g = (i & 2) ? 127 : 0;
- b = (i & 4) ? 127 : 0;
- }
- default_clut.clut16[i] = RGBA(r, g, b, 255);
- }
-
- default_clut.clut256[0] = RGBA( 0, 0, 0, 0);
- for (i = 1; i < 256; i++) {
- if (i < 8) {
- r = (i & 1) ? 255 : 0;
- g = (i & 2) ? 255 : 0;
- b = (i & 4) ? 255 : 0;
- a = 63;
- } else {
- switch (i & 0x88) {
- case 0x00:
- r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
- g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
- b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
- a = 255;
- break;
- case 0x08:
- r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
- g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
- b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
- a = 127;
- break;
- case 0x80:
- r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
- g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
- b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
- a = 255;
- break;
- case 0x88:
- r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
- g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
- b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
- a = 255;
- break;
- }
- }
- default_clut.clut256[i] = RGBA(r, g, b, a);
- }
-
- return 0;
-}
-
-static av_cold int dvbsub_close_decoder(AVCodecContext *avctx)
-{
- DVBSubContext *ctx = avctx->priv_data;
- DVBSubRegionDisplay *display;
-
- delete_regions(ctx);
-
- delete_objects(ctx);
-
- delete_cluts(ctx);
-
- av_freep(&ctx->display_definition);
-
- while (ctx->display_list) {
- display = ctx->display_list;
- ctx->display_list = display->next;
-
- av_freep(&display);
- }
-
- return 0;
-}
-
-static int dvbsub_read_2bit_string(AVCodecContext *avctx,
- uint8_t *destbuf, int dbuf_len,
- const uint8_t **srcbuf, int buf_size,
- int non_mod, uint8_t *map_table, int x_pos)
-{
- GetBitContext gb;
-
- int bits;
- int run_length;
- int pixels_read = x_pos;
-
- init_get_bits(&gb, *srcbuf, buf_size << 3);
-
- destbuf += x_pos;
-
- while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
- bits = get_bits(&gb, 2);
-
- if (bits) {
- if (non_mod != 1 || bits != 1) {
- if (map_table)
- *destbuf++ = map_table[bits];
- else
- *destbuf++ = bits;
- }
- pixels_read++;
- } else {
- bits = get_bits1(&gb);
- if (bits == 1) {
- run_length = get_bits(&gb, 3) + 3;
- bits = get_bits(&gb, 2);
-
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
- else {
- if (map_table)
- bits = map_table[bits];
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- } else {
- bits = get_bits1(&gb);
- if (bits == 0) {
- bits = get_bits(&gb, 2);
- if (bits == 2) {
- run_length = get_bits(&gb, 4) + 12;
- bits = get_bits(&gb, 2);
-
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
- else {
- if (map_table)
- bits = map_table[bits];
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- } else if (bits == 3) {
- run_length = get_bits(&gb, 8) + 29;
- bits = get_bits(&gb, 2);
-
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
- else {
- if (map_table)
- bits = map_table[bits];
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- } else if (bits == 1) {
- if (map_table)
- bits = map_table[0];
- else
- bits = 0;
- run_length = 2;
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- } else {
- (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
- return pixels_read;
- }
- } else {
- if (map_table)
- bits = map_table[0];
- else
- bits = 0;
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- }
- }
-
- if (get_bits(&gb, 6))
- av_log(avctx, AV_LOG_ERROR, "line overflow\n");
-
- (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
-
- return pixels_read;
-}
-
-static int dvbsub_read_4bit_string(AVCodecContext *avctx, uint8_t *destbuf, int dbuf_len,
- const uint8_t **srcbuf, int buf_size,
- int non_mod, uint8_t *map_table, int x_pos)
-{
- GetBitContext gb;
-
- int bits;
- int run_length;
- int pixels_read = x_pos;
-
- init_get_bits(&gb, *srcbuf, buf_size << 3);
-
- destbuf += x_pos;
-
- while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
- bits = get_bits(&gb, 4);
-
- if (bits) {
- if (non_mod != 1 || bits != 1) {
- if (map_table)
- *destbuf++ = map_table[bits];
- else
- *destbuf++ = bits;
- }
- pixels_read++;
- } else {
- bits = get_bits1(&gb);
- if (bits == 0) {
- run_length = get_bits(&gb, 3);
-
- if (run_length == 0) {
- (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
- return pixels_read;
- }
-
- run_length += 2;
-
- if (map_table)
- bits = map_table[0];
- else
- bits = 0;
-
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- } else {
- bits = get_bits1(&gb);
- if (bits == 0) {
- run_length = get_bits(&gb, 2) + 4;
- bits = get_bits(&gb, 4);
-
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
- else {
- if (map_table)
- bits = map_table[bits];
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- } else {
- bits = get_bits(&gb, 2);
- if (bits == 2) {
- run_length = get_bits(&gb, 4) + 9;
- bits = get_bits(&gb, 4);
-
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
- else {
- if (map_table)
- bits = map_table[bits];
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- } else if (bits == 3) {
- run_length = get_bits(&gb, 8) + 25;
- bits = get_bits(&gb, 4);
-
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
- else {
- if (map_table)
- bits = map_table[bits];
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- } else if (bits == 1) {
- if (map_table)
- bits = map_table[0];
- else
- bits = 0;
- run_length = 2;
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- } else {
- if (map_table)
- bits = map_table[0];
- else
- bits = 0;
- *destbuf++ = bits;
- pixels_read ++;
- }
- }
- }
- }
- }
-
- if (get_bits(&gb, 8))
- av_log(avctx, AV_LOG_ERROR, "line overflow\n");
-
- (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
-
- return pixels_read;
-}
-
-static int dvbsub_read_8bit_string(AVCodecContext *avctx,
- uint8_t *destbuf, int dbuf_len,
- const uint8_t **srcbuf, int buf_size,
- int non_mod, uint8_t *map_table, int x_pos)
-{
- const uint8_t *sbuf_end = (*srcbuf) + buf_size;
- int bits;
- int run_length;
- int pixels_read = x_pos;
-
- destbuf += x_pos;
-
- while (*srcbuf < sbuf_end && pixels_read < dbuf_len) {
- bits = *(*srcbuf)++;
-
- if (bits) {
- if (non_mod != 1 || bits != 1) {
- if (map_table)
- *destbuf++ = map_table[bits];
- else
- *destbuf++ = bits;
- }
- pixels_read++;
- } else {
- bits = *(*srcbuf)++;
- run_length = bits & 0x7f;
- if ((bits & 0x80) == 0) {
- if (run_length == 0) {
- return pixels_read;
- }
-
- bits = 0;
- } else {
- bits = *(*srcbuf)++;
- }
- if (non_mod == 1 && bits == 1)
- pixels_read += run_length;
- else {
- if (map_table)
- bits = map_table[bits];
- while (run_length-- > 0 && pixels_read < dbuf_len) {
- *destbuf++ = bits;
- pixels_read++;
- }
- }
- }
- }
-
- if (*(*srcbuf)++)
- av_log(avctx, AV_LOG_ERROR, "line overflow\n");
-
- return pixels_read;
-}
-
-static void compute_default_clut(AVPicture *frame, int w, int h)
-{
- uint8_t list[256] = {0};
- uint8_t list_inv[256];
- int counttab[256] = {0};
- int count, i, x, y;
-
-#define V(x,y) frame->data[0][(x) + (y)*frame->linesize[0]]
- for (y = 0; y<h; y++) {
- for (x = 0; x<w; x++) {
- int v = V(x,y) + 1;
- int vl = x ? V(x-1,y) + 1 : 0;
- int vr = x+1<w ? V(x+1,y) + 1 : 0;
- int vt = y ? V(x,y-1) + 1 : 0;
- int vb = y+1<h ? V(x,y+1) + 1 : 0;
- counttab[v-1] += !!((v!=vl) + (v!=vr) + (v!=vt) + (v!=vb));
- }
- }
-#define L(x,y) list[ frame->data[0][(x) + (y)*frame->linesize[0]] ]
-
- for (i = 0; i<256; i++) {
- int scoretab[256] = {0};
- int bestscore = 0;
- int bestv = 0;
- for (y = 0; y<h; y++) {
- for (x = 0; x<w; x++) {
- int v = frame->data[0][x + y*frame->linesize[0]];
- int l_m = list[v];
- int l_l = x ? L(x-1, y) : 1;
- int l_r = x+1<w ? L(x+1, y) : 1;
- int l_t = y ? L(x, y-1) : 1;
- int l_b = y+1<h ? L(x, y+1) : 1;
- int score;
- if (l_m)
- continue;
- scoretab[v] += l_l + l_r + l_t + l_b;
- score = 1024LL*scoretab[v] / counttab[v];
- if (score > bestscore) {
- bestscore = score;
- bestv = v;
- }
- }
- }
- if (!bestscore)
- break;
- list [ bestv ] = 1;
- list_inv[ i ] = bestv;
- }
-
- count = FFMAX(i - 1, 1);
- for (i--; i>=0; i--) {
- int v = i*255/count;
- AV_WN32(frame->data[1] + 4*list_inv[i], RGBA(v/2,v,v/2,v));
- }
-}
-
-
-static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output)
-{
- DVBSubContext *ctx = avctx->priv_data;
- DVBSubRegionDisplay *display;
- DVBSubDisplayDefinition *display_def = ctx->display_definition;
- DVBSubRegion *region;
- AVSubtitleRect *rect;
- DVBSubCLUT *clut;
- uint32_t *clut_table;
- int i;
- int offset_x=0, offset_y=0;
- int ret = 0;
-
-
- if (display_def) {
- offset_x = display_def->x;
- offset_y = display_def->y;
- }
-
- /* Not touching AVSubtitles again*/
- if(sub->num_rects) {
- avpriv_request_sample(ctx, "Different Version of Segment asked Twice");
- return AVERROR_PATCHWELCOME;
- }
- for (display = ctx->display_list; display; display = display->next) {
- region = get_region(ctx, display->region_id);
- if (region && region->dirty)
- sub->num_rects++;
- }
-
- if(ctx->compute_edt == 0) {
- sub->end_display_time = ctx->time_out * 1000;
- *got_output = 1;
- } else if (ctx->prev_start != AV_NOPTS_VALUE) {
- sub->end_display_time = av_rescale_q((sub->pts - ctx->prev_start ), AV_TIME_BASE_Q, (AVRational){ 1, 1000 }) - 1;
- *got_output = 1;
- }
- if (sub->num_rects > 0) {
-
- sub->rects = av_mallocz_array(sizeof(*sub->rects), sub->num_rects);
- if (!sub->rects) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
-
- for(i=0; i<sub->num_rects; i++)
- sub->rects[i] = av_mallocz(sizeof(*sub->rects[i]));
-
- i = 0;
-
- for (display = ctx->display_list; display; display = display->next) {
- region = get_region(ctx, display->region_id);
-
- if (!region)
- continue;
-
- if (!region->dirty)
- continue;
-
- rect = sub->rects[i];
- rect->x = display->x_pos + offset_x;
- rect->y = display->y_pos + offset_y;
- rect->w = region->width;
- rect->h = region->height;
- rect->nb_colors = (1 << region->depth);
- rect->type = SUBTITLE_BITMAP;
- rect->pict.linesize[0] = region->width;
-
- clut = get_clut(ctx, region->clut);
-
- if (!clut)
- clut = &default_clut;
-
- switch (region->depth) {
- case 2:
- clut_table = clut->clut4;
- break;
- case 8:
- clut_table = clut->clut256;
- break;
- case 4:
- default:
- clut_table = clut->clut16;
- break;
- }
-
- rect->pict.data[1] = av_mallocz(AVPALETTE_SIZE);
- if (!rect->pict.data[1]) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- memcpy(rect->pict.data[1], clut_table, (1 << region->depth) * sizeof(uint32_t));
-
- rect->pict.data[0] = av_malloc(region->buf_size);
- if (!rect->pict.data[0]) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
-
- memcpy(rect->pict.data[0], region->pbuf, region->buf_size);
-
- if ((clut == &default_clut && ctx->compute_clut == -1) || ctx->compute_clut == 1)
- compute_default_clut(&rect->pict, rect->w, rect->h);
-
- i++;
- }
- }
-
- return 0;
-fail:
- if (sub->rects) {
- for(i=0; i<sub->num_rects; i++) {
- rect = sub->rects[i];
- if (rect) {
- av_freep(&rect->pict.data[0]);
- av_freep(&rect->pict.data[1]);
- }
- av_freep(&sub->rects[i]);
- }
- av_freep(&sub->rects);
- }
- sub->num_rects = 0;
- return ret;
-}
-
-static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display,
- const uint8_t *buf, int buf_size, int top_bottom, int non_mod)
-{
- DVBSubContext *ctx = avctx->priv_data;
-
- DVBSubRegion *region = get_region(ctx, display->region_id);
- const uint8_t *buf_end = buf + buf_size;
- uint8_t *pbuf;
- int x_pos, y_pos;
- int i;
-
- uint8_t map2to4[] = { 0x0, 0x7, 0x8, 0xf};
- uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff};
- uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
- 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
- uint8_t *map_table;
-
-#if 0
- ff_dlog(avctx, "DVB pixel block size %d, %s field:\n", buf_size,
- top_bottom ? "bottom" : "top");
-
- for (i = 0; i < buf_size; i++) {
- if (i % 16 == 0)
- ff_dlog(avctx, "0x%8p: ", buf+i);
-
- ff_dlog(avctx, "%02x ", buf[i]);
- if (i % 16 == 15)
- ff_dlog(avctx, "\n");
- }
-
- if (i % 16)
- ff_dlog(avctx, "\n");
-#endif
-
- if (!region)
- return;
-
- pbuf = region->pbuf;
- region->dirty = 1;
-
- x_pos = display->x_pos;
- y_pos = display->y_pos;
-
- y_pos += top_bottom;
-
- while (buf < buf_end) {
- if ((*buf!=0xf0 && x_pos >= region->width) || y_pos >= region->height) {
- av_log(avctx, AV_LOG_ERROR, "Invalid object location! %d-%d %d-%d %02x\n", x_pos, region->width, y_pos, region->height, *buf);
- return;
- }
-
- switch (*buf++) {
- case 0x10:
- if (region->depth == 8)
- map_table = map2to8;
- else if (region->depth == 4)
- map_table = map2to4;
- else
- map_table = NULL;
-
- x_pos = dvbsub_read_2bit_string(avctx, pbuf + (y_pos * region->width),
- region->width, &buf, buf_end - buf,
- non_mod, map_table, x_pos);
- break;
- case 0x11:
- if (region->depth < 4) {
- av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth);
- return;
- }
-
- if (region->depth == 8)
- map_table = map4to8;
- else
- map_table = NULL;
-
- x_pos = dvbsub_read_4bit_string(avctx, pbuf + (y_pos * region->width),
- region->width, &buf, buf_end - buf,
- non_mod, map_table, x_pos);
- break;
- case 0x12:
- if (region->depth < 8) {
- av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth);
- return;
- }
-
- x_pos = dvbsub_read_8bit_string(avctx, pbuf + (y_pos * region->width),
- region->width, &buf, buf_end - buf,
- non_mod, NULL, x_pos);
- break;
-
- case 0x20:
- map2to4[0] = (*buf) >> 4;
- map2to4[1] = (*buf++) & 0xf;
- map2to4[2] = (*buf) >> 4;
- map2to4[3] = (*buf++) & 0xf;
- break;
- case 0x21:
- for (i = 0; i < 4; i++)
- map2to8[i] = *buf++;
- break;
- case 0x22:
- for (i = 0; i < 16; i++)
- map4to8[i] = *buf++;
- break;
-
- case 0xf0:
- x_pos = display->x_pos;
- y_pos += 2;
- break;
- default:
- av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1));
- }
- }
-
-}
-
-static int dvbsub_parse_object_segment(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size)
-{
- DVBSubContext *ctx = avctx->priv_data;
-
- const uint8_t *buf_end = buf + buf_size;
- int object_id;
- DVBSubObject *object;
- DVBSubObjectDisplay *display;
- int top_field_len, bottom_field_len;
-
- int coding_method, non_modifying_color;
-
- object_id = AV_RB16(buf);
- buf += 2;
-
- object = get_object(ctx, object_id);
-
- if (!object)
- return AVERROR_INVALIDDATA;
-
- coding_method = ((*buf) >> 2) & 3;
- non_modifying_color = ((*buf++) >> 1) & 1;
-
- if (coding_method == 0) {
- top_field_len = AV_RB16(buf);
- buf += 2;
- bottom_field_len = AV_RB16(buf);
- buf += 2;
-
- if (buf + top_field_len + bottom_field_len > buf_end) {
- av_log(avctx, AV_LOG_ERROR, "Field data size %d+%d too large\n", top_field_len, bottom_field_len);
- return AVERROR_INVALIDDATA;
- }
-
- for (display = object->display_list; display; display = display->object_list_next) {
- const uint8_t *block = buf;
- int bfl = bottom_field_len;
-
- dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0,
- non_modifying_color);
-
- if (bottom_field_len > 0)
- block = buf + top_field_len;
- else
- bfl = top_field_len;
-
- dvbsub_parse_pixel_data_block(avctx, display, block, bfl, 1,
- non_modifying_color);
- }
-
-/* } else if (coding_method == 1) {*/
-
- } else {
- av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method);
- }
-
- return 0;
-}
-
-static int dvbsub_parse_clut_segment(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size)
-{
- DVBSubContext *ctx = avctx->priv_data;
-
- const uint8_t *buf_end = buf + buf_size;
- int i, clut_id;
- int version;
- DVBSubCLUT *clut;
- int entry_id, depth , full_range;
- int y, cr, cb, alpha;
- int r, g, b, r_add, g_add, b_add;
-
- ff_dlog(avctx, "DVB clut packet:\n");
-
- for (i=0; i < buf_size; i++) {
- ff_dlog(avctx, "%02x ", buf[i]);
- if (i % 16 == 15)
- ff_dlog(avctx, "\n");
- }
-
- if (i % 16)
- ff_dlog(avctx, "\n");
-
- clut_id = *buf++;
- version = ((*buf)>>4)&15;
- buf += 1;
-
- clut = get_clut(ctx, clut_id);
-
- if (!clut) {
- clut = av_malloc(sizeof(DVBSubCLUT));
- if (!clut)
- return AVERROR(ENOMEM);
-
- memcpy(clut, &default_clut, sizeof(DVBSubCLUT));
-
- clut->id = clut_id;
- clut->version = -1;
-
- clut->next = ctx->clut_list;
- ctx->clut_list = clut;
- }
-
- if (clut->version != version) {
-
- clut->version = version;
-
- while (buf + 4 < buf_end) {
- entry_id = *buf++;
-
- depth = (*buf) & 0xe0;
-
- 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)
- clut->clut4[entry_id] = RGBA(r,g,b,255 - alpha);
- else if (depth & 0x40)
- 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;
-}
-
-
-static int dvbsub_parse_region_segment(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size)
-{
- DVBSubContext *ctx = avctx->priv_data;
-
- const uint8_t *buf_end = buf + buf_size;
- int region_id, object_id;
- int av_unused version;
- DVBSubRegion *region;
- DVBSubObject *object;
- DVBSubObjectDisplay *display;
- int fill;
-
- if (buf_size < 10)
- return AVERROR_INVALIDDATA;
-
- region_id = *buf++;
-
- region = get_region(ctx, region_id);
-
- if (!region) {
- region = av_mallocz(sizeof(DVBSubRegion));
- if (!region)
- return AVERROR(ENOMEM);
-
- region->id = region_id;
- region->version = -1;
-
- region->next = ctx->region_list;
- ctx->region_list = region;
- }
-
- version = ((*buf)>>4) & 15;
- fill = ((*buf++) >> 3) & 1;
-
- region->width = AV_RB16(buf);
- buf += 2;
- region->height = AV_RB16(buf);
- buf += 2;
-
- if (region->width * region->height != region->buf_size) {
- av_free(region->pbuf);
-
- region->buf_size = region->width * region->height;
-
- region->pbuf = av_malloc(region->buf_size);
- if (!region->pbuf) {
- region->buf_size =
- region->width =
- region->height = 0;
- return AVERROR(ENOMEM);
- }
-
- fill = 1;
- region->dirty = 0;
- }
-
- region->depth = 1 << (((*buf++) >> 2) & 7);
- if(region->depth<2 || region->depth>8){
- av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth);
- region->depth= 4;
- }
- region->clut = *buf++;
-
- if (region->depth == 8) {
- region->bgcolor = *buf++;
- buf += 1;
- } else {
- buf += 1;
-
- if (region->depth == 4)
- region->bgcolor = (((*buf++) >> 4) & 15);
- else
- region->bgcolor = (((*buf++) >> 2) & 3);
- }
-
- ff_dlog(avctx, "Region %d, (%dx%d)\n", region_id, region->width, region->height);
-
- if (fill) {
- memset(region->pbuf, region->bgcolor, region->buf_size);
- ff_dlog(avctx, "Fill region (%d)\n", region->bgcolor);
- }
-
- delete_region_display_list(ctx, region);
-
- while (buf + 5 < buf_end) {
- object_id = AV_RB16(buf);
- buf += 2;
-
- object = get_object(ctx, object_id);
-
- if (!object) {
- object = av_mallocz(sizeof(DVBSubObject));
- if (!object)
- return AVERROR(ENOMEM);
-
- object->id = object_id;
- object->next = ctx->object_list;
- ctx->object_list = object;
- }
-
- object->type = (*buf) >> 6;
-
- display = av_mallocz(sizeof(DVBSubObjectDisplay));
- if (!display)
- return AVERROR(ENOMEM);
-
- display->object_id = object_id;
- display->region_id = region_id;
-
- display->x_pos = AV_RB16(buf) & 0xfff;
- buf += 2;
- display->y_pos = AV_RB16(buf) & 0xfff;
- buf += 2;
-
- if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {
- display->fgcolor = *buf++;
- display->bgcolor = *buf++;
- }
-
- display->region_list_next = region->display_list;
- region->display_list = display;
-
- display->object_list_next = object->display_list;
- object->display_list = display;
- }
-
- return 0;
-}
-
-static int dvbsub_parse_page_segment(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size, AVSubtitle *sub, int *got_output)
-{
- DVBSubContext *ctx = avctx->priv_data;
- DVBSubRegionDisplay *display;
- DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
-
- const uint8_t *buf_end = buf + buf_size;
- int region_id;
- int page_state;
- int timeout;
- int version;
-
- if (buf_size < 1)
- return AVERROR_INVALIDDATA;
-
- timeout = *buf++;
- version = ((*buf)>>4) & 15;
- page_state = ((*buf++) >> 2) & 3;
-
- if (ctx->version == version) {
- return 0;
- }
-
- ctx->time_out = timeout;
- ctx->version = version;
-
- ff_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state);
-
- if(ctx->compute_edt == 1)
- save_subtitle_set(avctx, sub, got_output);
-
- if (page_state == 1 || page_state == 2) {
- delete_regions(ctx);
- delete_objects(ctx);
- delete_cluts(ctx);
- }
-
- tmp_display_list = ctx->display_list;
- ctx->display_list = NULL;
-
- while (buf + 5 < buf_end) {
- region_id = *buf++;
- buf += 1;
-
- display = tmp_display_list;
- tmp_ptr = &tmp_display_list;
-
- while (display && display->region_id != region_id) {
- tmp_ptr = &display->next;
- display = display->next;
- }
-
- if (!display) {
- display = av_mallocz(sizeof(DVBSubRegionDisplay));
- if (!display)
- return AVERROR(ENOMEM);
- }
-
- display->region_id = region_id;
-
- display->x_pos = AV_RB16(buf);
- buf += 2;
- display->y_pos = AV_RB16(buf);
- buf += 2;
-
- *tmp_ptr = display->next;
-
- display->next = ctx->display_list;
- ctx->display_list = display;
-
- ff_dlog(avctx, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos);
- }
-
- while (tmp_display_list) {
- display = tmp_display_list;
-
- tmp_display_list = display->next;
-
- av_freep(&display);
- }
-
- return 0;
-}
-
-
-#ifdef DEBUG
-static void save_display_set(DVBSubContext *ctx)
-{
- DVBSubRegion *region;
- DVBSubRegionDisplay *display;
- DVBSubCLUT *clut;
- uint32_t *clut_table;
- int x_pos, y_pos, width, height;
- int x, y, y_off, x_off;
- uint32_t *pbuf;
- char filename[32];
- static int fileno_index = 0;
-
- x_pos = -1;
- y_pos = -1;
- width = 0;
- height = 0;
-
- for (display = ctx->display_list; display; display = display->next) {
- region = get_region(ctx, display->region_id);
-
- if (!region)
- return;
-
- if (x_pos == -1) {
- x_pos = display->x_pos;
- y_pos = display->y_pos;
- width = region->width;
- height = region->height;
- } else {
- if (display->x_pos < x_pos) {
- width += (x_pos - display->x_pos);
- x_pos = display->x_pos;
- }
-
- if (display->y_pos < y_pos) {
- height += (y_pos - display->y_pos);
- y_pos = display->y_pos;
- }
-
- if (display->x_pos + region->width > x_pos + width) {
- width = display->x_pos + region->width - x_pos;
- }
-
- if (display->y_pos + region->height > y_pos + height) {
- height = display->y_pos + region->height - y_pos;
- }
- }
- }
-
- if (x_pos >= 0) {
-
- pbuf = av_malloc(width * height * 4);
- if (!pbuf)
- return;
-
- for (display = ctx->display_list; display; display = display->next) {
- region = get_region(ctx, display->region_id);
-
- if (!region)
- return;
-
- x_off = display->x_pos - x_pos;
- y_off = display->y_pos - y_pos;
-
- clut = get_clut(ctx, region->clut);
-
- if (!clut)
- clut = &default_clut;
-
- switch (region->depth) {
- case 2:
- clut_table = clut->clut4;
- break;
- case 8:
- clut_table = clut->clut256;
- break;
- case 4:
- default:
- clut_table = clut->clut16;
- break;
- }
-
- for (y = 0; y < region->height; y++) {
- for (x = 0; x < region->width; x++) {
- pbuf[((y + y_off) * width) + x_off + x] =
- clut_table[region->pbuf[y * region->width + x]];
- }
- }
-
- }
-
- snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index);
-
- png_save2(filename, pbuf, width, height);
-
- av_freep(&pbuf);
- }
-
- fileno_index++;
-}
-#endif
-
-static int dvbsub_parse_display_definition_segment(AVCodecContext *avctx,
- const uint8_t *buf,
- int buf_size)
-{
- DVBSubContext *ctx = avctx->priv_data;
- DVBSubDisplayDefinition *display_def = ctx->display_definition;
- int dds_version, info_byte;
-
- if (buf_size < 5)
- return AVERROR_INVALIDDATA;
-
- info_byte = bytestream_get_byte(&buf);
- dds_version = info_byte >> 4;
- if (display_def && display_def->version == dds_version)
- return 0; // already have this display definition version
-
- if (!display_def) {
- display_def = av_mallocz(sizeof(*display_def));
- if (!display_def)
- return AVERROR(ENOMEM);
- ctx->display_definition = display_def;
- }
-
- display_def->version = dds_version;
- display_def->x = 0;
- display_def->y = 0;
- display_def->width = bytestream_get_be16(&buf) + 1;
- display_def->height = bytestream_get_be16(&buf) + 1;
- if (!avctx->width || !avctx->height) {
- avctx->width = display_def->width;
- avctx->height = display_def->height;
- }
-
- if (info_byte & 1<<3) { // display_window_flag
- if (buf_size < 13)
- return AVERROR_INVALIDDATA;
-
- display_def->x = bytestream_get_be16(&buf);
- display_def->width = bytestream_get_be16(&buf) - display_def->x + 1;
- display_def->y = bytestream_get_be16(&buf);
- display_def->height = bytestream_get_be16(&buf) - display_def->y + 1;
- }
-
- return 0;
-}
-
-static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
- int buf_size, AVSubtitle *sub,int *got_output)
-{
- DVBSubContext *ctx = avctx->priv_data;
-
- if(ctx->compute_edt == 0)
- save_subtitle_set(avctx, sub, got_output);
-#ifdef DEBUG
- save_display_set(ctx);
-#endif
- return 0;
-}
-
-static int dvbsub_decode(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- DVBSubContext *ctx = avctx->priv_data;
- AVSubtitle *sub = data;
- const uint8_t *p, *p_end;
- int segment_type;
- int page_id;
- int segment_length;
- int i;
- int ret = 0;
- int got_segment = 0;
- int got_dds = 0;
-
- ff_dlog(avctx, "DVB sub packet:\n");
-
- for (i=0; i < buf_size; i++) {
- ff_dlog(avctx, "%02x ", buf[i]);
- if (i % 16 == 15)
- ff_dlog(avctx, "\n");
- }
-
- if (i % 16)
- ff_dlog(avctx, "\n");
-
- if (buf_size <= 6 || *buf != 0x0f) {
- ff_dlog(avctx, "incomplete or broken packet");
- return AVERROR_INVALIDDATA;
- }
-
- p = buf;
- p_end = buf + buf_size;
-
- while (p_end - p >= 6 && *p == 0x0f) {
- p += 1;
- segment_type = *p++;
- page_id = AV_RB16(p);
- p += 2;
- segment_length = AV_RB16(p);
- p += 2;
-
- if (avctx->debug & FF_DEBUG_STARTCODE) {
- av_log(avctx, AV_LOG_DEBUG, "segment_type:%d page_id:%d segment_length:%d\n", segment_type, page_id, segment_length);
- }
-
- if (p_end - p < segment_length) {
- ff_dlog(avctx, "incomplete or broken packet");
- ret = -1;
- goto end;
- }
-
- if (page_id == ctx->composition_id || page_id == ctx->ancillary_id ||
- ctx->composition_id == -1 || ctx->ancillary_id == -1) {
- int ret = 0;
- switch (segment_type) {
- case DVBSUB_PAGE_SEGMENT:
- ret = dvbsub_parse_page_segment(avctx, p, segment_length, sub, data_size);
- got_segment |= 1;
- break;
- case DVBSUB_REGION_SEGMENT:
- ret = dvbsub_parse_region_segment(avctx, p, segment_length);
- got_segment |= 2;
- break;
- case DVBSUB_CLUT_SEGMENT:
- ret = dvbsub_parse_clut_segment(avctx, p, segment_length);
- if (ret < 0) goto end;
- got_segment |= 4;
- break;
- case DVBSUB_OBJECT_SEGMENT:
- ret = dvbsub_parse_object_segment(avctx, p, segment_length);
- got_segment |= 8;
- break;
- case DVBSUB_DISPLAYDEFINITION_SEGMENT:
- ret = dvbsub_parse_display_definition_segment(avctx, p,
- segment_length);
- got_dds = 1;
- break;
- case DVBSUB_DISPLAY_SEGMENT:
- ret = dvbsub_display_end_segment(avctx, p, segment_length, sub, data_size);
- if (got_segment == 15 && !got_dds && !avctx->width && !avctx->height) {
- // Default from ETSI EN 300 743 V1.3.1 (7.2.1)
- avctx->width = 720;
- avctx->height = 576;
- }
- got_segment |= 16;
- break;
- default:
- ff_dlog(avctx, "Subtitling segment type 0x%x, page id %d, length %d\n",
- segment_type, page_id, segment_length);
- break;
- }
- if (ret < 0)
- goto end;
- }
-
- p += segment_length;
- }
- // Some streams do not send a display segment but if we have all the other
- // segments then we need no further data.
- if (got_segment == 15) {
- av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, emulating\n");
- dvbsub_display_end_segment(avctx, p, 0, sub, data_size);
- }
-
-end:
- if(ret < 0) {
- *data_size = 0;
- avsubtitle_free(sub);
- return ret;
- } else {
- if(ctx->compute_edt == 1 )
- FFSWAP(int64_t, ctx->prev_start, sub->pts);
- }
-
- return p - buf;
-}
-
-#define DS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
-static const AVOption options[] = {
- {"compute_edt", "compute end of time using pts or timeout", offsetof(DVBSubContext, compute_edt), AV_OPT_TYPE_INT, {.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_INT, {.i64 = -1}, -1, 1, DS},
- {"dvb_substream", "", offsetof(DVBSubContext, substream), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, DS},
- {NULL}
-};
-static const AVClass dvbsubdec_class = {
- .class_name = "DVB Sub Decoder",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-AVCodec ff_dvbsub_decoder = {
- .name = "dvbsub",
- .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
- .type = AVMEDIA_TYPE_SUBTITLE,
- .id = AV_CODEC_ID_DVB_SUBTITLE,
- .priv_data_size = sizeof(DVBSubContext),
- .init = dvbsub_init_decoder,
- .close = dvbsub_close_decoder,
- .decode = dvbsub_decode,
- .priv_class = &dvbsubdec_class,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/dvdsubdec.c b/ffmpeg-2-8-11/libavcodec/dvdsubdec.c
deleted file mode 100644
index 42ee50a..0000000
--- a/ffmpeg-2-8-11/libavcodec/dvdsubdec.c
+++ /dev/null
@@ -1,761 +0,0 @@
-/*
- * DVD subtitle decoding
- * 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 "get_bits.h"
-#include "internal.h"
-
-#include "libavutil/attributes.h"
-#include "libavutil/colorspace.h"
-#include "libavutil/opt.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/avstring.h"
-#include "libavutil/bswap.h"
-
-typedef struct DVDSubContext
-{
- AVClass *class;
- uint32_t palette[16];
- char *palette_str;
- char *ifo_str;
- int has_palette;
- uint8_t colormap[4];
- uint8_t alpha[256];
- uint8_t buf[0x10000];
- int buf_size;
- int forced_subs_only;
-#ifdef DEBUG
- int sub_id;
-#endif
-} DVDSubContext;
-
-static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values)
-{
- const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
- uint8_t r, g, b;
- int i, y, cb, cr;
- int r_add, g_add, b_add;
-
- for (i = num_values; i > 0; i--) {
- y = *ycbcr++;
- cr = *ycbcr++;
- cb = *ycbcr++;
- YUV_TO_RGB1_CCIR(cb, cr);
- YUV_TO_RGB2_CCIR(r, g, b, y);
- *rgba++ = (*alpha++ << 24) | (r << 16) | (g << 8) | b;
- }
-}
-
-static int decode_run_2bit(GetBitContext *gb, int *color)
-{
- unsigned int v, t;
-
- v = 0;
- for (t = 1; v < t && t <= 0x40; t <<= 2)
- v = (v << 4) | get_bits(gb, 4);
- *color = v & 3;
- if (v < 4) { /* Code for fill rest of line */
- return INT_MAX;
- }
- return v >> 2;
-}
-
-static int decode_run_8bit(GetBitContext *gb, int *color)
-{
- int len;
- int has_run = get_bits1(gb);
- if (get_bits1(gb))
- *color = get_bits(gb, 8);
- else
- *color = get_bits(gb, 2);
- if (has_run) {
- if (get_bits1(gb)) {
- len = get_bits(gb, 7);
- if (len == 0)
- len = INT_MAX;
- else
- len += 9;
- } else
- len = get_bits(gb, 3) + 2;
- } else
- len = 1;
- return len;
-}
-
-static int decode_rle(uint8_t *bitmap, int linesize, int w, int h,
- const uint8_t *buf, int start, int buf_size, int is_8bit)
-{
- GetBitContext gb;
- int bit_len;
- int x, y, len, color;
- uint8_t *d;
-
- if (start >= buf_size)
- return -1;
-
- if (w <= 0 || h <= 0)
- return -1;
-
- bit_len = (buf_size - start) * 8;
- init_get_bits(&gb, buf + start, bit_len);
-
- x = 0;
- y = 0;
- d = bitmap;
- for(;;) {
- if (get_bits_count(&gb) > bit_len)
- return -1;
- if (is_8bit)
- len = decode_run_8bit(&gb, &color);
- else
- len = decode_run_2bit(&gb, &color);
- len = FFMIN(len, w - x);
- memset(d + x, color, len);
- x += len;
- if (x >= w) {
- y++;
- if (y >= h)
- break;
- d += linesize;
- x = 0;
- /* byte align */
- align_get_bits(&gb);
- }
- }
- return 0;
-}
-
-static void guess_palette(DVDSubContext* ctx,
- uint32_t *rgba_palette,
- uint32_t subtitle_color)
-{
- static const uint8_t level_map[4][4] = {
- // this configuration (full range, lowest to highest) in tests
- // seemed most common, so assume this
- {0xff},
- {0x00, 0xff},
- {0x00, 0x80, 0xff},
- {0x00, 0x55, 0xaa, 0xff},
- };
- uint8_t color_used[16] = { 0 };
- int nb_opaque_colors, i, level, j, r, g, b;
- uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha;
-
- if(ctx->has_palette) {
- for(i = 0; i < 4; i++)
- rgba_palette[i] = (ctx->palette[colormap[i]] & 0x00ffffff)
- | ((alpha[i] * 17U) << 24);
- return;
- }
-
- for(i = 0; i < 4; i++)
- rgba_palette[i] = 0;
-
- nb_opaque_colors = 0;
- for(i = 0; i < 4; i++) {
- if (alpha[i] != 0 && !color_used[colormap[i]]) {
- color_used[colormap[i]] = 1;
- nb_opaque_colors++;
- }
- }
-
- if (nb_opaque_colors == 0)
- return;
-
- j = 0;
- memset(color_used, 0, 16);
- for(i = 0; i < 4; i++) {
- if (alpha[i] != 0) {
- if (!color_used[colormap[i]]) {
- level = level_map[nb_opaque_colors - 1][j];
- r = (((subtitle_color >> 16) & 0xff) * level) >> 8;
- g = (((subtitle_color >> 8) & 0xff) * level) >> 8;
- b = (((subtitle_color >> 0) & 0xff) * level) >> 8;
- rgba_palette[i] = b | (g << 8) | (r << 16) | ((alpha[i] * 17) << 24);
- color_used[colormap[i]] = (i + 1);
- j++;
- } else {
- rgba_palette[i] = (rgba_palette[color_used[colormap[i]] - 1] & 0x00ffffff) |
- ((alpha[i] * 17) << 24);
- }
- }
- }
-}
-
-static void reset_rects(AVSubtitle *sub_header)
-{
- int i;
-
- if (sub_header->rects) {
- for (i = 0; i < sub_header->num_rects; i++) {
- av_freep(&sub_header->rects[i]->pict.data[0]);
- av_freep(&sub_header->rects[i]->pict.data[1]);
- av_freep(&sub_header->rects[i]);
- }
- av_freep(&sub_header->rects);
- sub_header->num_rects = 0;
- }
-}
-
-#define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a))
-
-static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header,
- const uint8_t *buf, int buf_size)
-{
- int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos;
- int big_offsets, offset_size, is_8bit = 0;
- const uint8_t *yuv_palette = NULL;
- uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha;
- int date;
- int i;
- int is_menu = 0;
-
- if (buf_size < 10)
- return -1;
-
- if (AV_RB16(buf) == 0) { /* HD subpicture with 4-byte offsets */
- big_offsets = 1;
- offset_size = 4;
- cmd_pos = 6;
- } else {
- big_offsets = 0;
- offset_size = 2;
- cmd_pos = 2;
- }
-
- cmd_pos = READ_OFFSET(buf + cmd_pos);
-
- if (cmd_pos < 0 || cmd_pos > buf_size - 2 - offset_size)
- return AVERROR(EAGAIN);
-
- while (cmd_pos > 0 && cmd_pos < buf_size - 2 - offset_size) {
- date = AV_RB16(buf + cmd_pos);
- next_cmd_pos = READ_OFFSET(buf + cmd_pos + 2);
- ff_dlog(NULL, "cmd_pos=0x%04x next=0x%04x date=%d\n",
- cmd_pos, next_cmd_pos, date);
- pos = cmd_pos + 2 + offset_size;
- offset1 = -1;
- offset2 = -1;
- x1 = y1 = x2 = y2 = 0;
- while (pos < buf_size) {
- cmd = buf[pos++];
- ff_dlog(NULL, "cmd=%02x\n", cmd);
- switch(cmd) {
- case 0x00:
- /* menu subpicture */
- is_menu = 1;
- break;
- case 0x01:
- /* set start date */
- sub_header->start_display_time = (date << 10) / 90;
- break;
- case 0x02:
- /* set end date */
- sub_header->end_display_time = (date << 10) / 90;
- break;
- case 0x03:
- /* set colormap */
- if ((buf_size - pos) < 2)
- goto fail;
- colormap[3] = buf[pos] >> 4;
- colormap[2] = buf[pos] & 0x0f;
- colormap[1] = buf[pos + 1] >> 4;
- colormap[0] = buf[pos + 1] & 0x0f;
- pos += 2;
- break;
- case 0x04:
- /* set alpha */
- if ((buf_size - pos) < 2)
- goto fail;
- alpha[3] = buf[pos] >> 4;
- alpha[2] = buf[pos] & 0x0f;
- alpha[1] = buf[pos + 1] >> 4;
- alpha[0] = buf[pos + 1] & 0x0f;
- pos += 2;
- ff_dlog(NULL, "alpha=%x%x%x%x\n", alpha[0],alpha[1],alpha[2],alpha[3]);
- break;
- case 0x05:
- case 0x85:
- if ((buf_size - pos) < 6)
- goto fail;
- x1 = (buf[pos] << 4) | (buf[pos + 1] >> 4);
- x2 = ((buf[pos + 1] & 0x0f) << 8) | buf[pos + 2];
- y1 = (buf[pos + 3] << 4) | (buf[pos + 4] >> 4);
- y2 = ((buf[pos + 4] & 0x0f) << 8) | buf[pos + 5];
- if (cmd & 0x80)
- is_8bit = 1;
- ff_dlog(NULL, "x1=%d x2=%d y1=%d y2=%d\n", x1, x2, y1, y2);
- pos += 6;
- break;
- case 0x06:
- if ((buf_size - pos) < 4)
- goto fail;
- offset1 = AV_RB16(buf + pos);
- offset2 = AV_RB16(buf + pos + 2);
- ff_dlog(NULL, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2);
- pos += 4;
- break;
- case 0x86:
- if ((buf_size - pos) < 8)
- goto fail;
- offset1 = AV_RB32(buf + pos);
- offset2 = AV_RB32(buf + pos + 4);
- ff_dlog(NULL, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2);
- pos += 8;
- break;
-
- case 0x83:
- /* HD set palette */
- if ((buf_size - pos) < 768)
- goto fail;
- yuv_palette = buf + pos;
- pos += 768;
- break;
- case 0x84:
- /* HD set contrast (alpha) */
- if ((buf_size - pos) < 256)
- goto fail;
- for (i = 0; i < 256; i++)
- alpha[i] = 0xFF - buf[pos+i];
- pos += 256;
- break;
-
- case 0xff:
- goto the_end;
- default:
- ff_dlog(NULL, "unrecognised subpicture command 0x%x\n", cmd);
- goto the_end;
- }
- }
- the_end:
- if (offset1 >= 0 && offset2 >= 0) {
- int w, h;
- uint8_t *bitmap;
-
- /* decode the bitmap */
- w = x2 - x1 + 1;
- if (w < 0)
- w = 0;
- h = y2 - y1 + 1;
- if (h < 0)
- h = 0;
- if (w > 0 && h > 0) {
- reset_rects(sub_header);
-
- sub_header->rects = av_mallocz(sizeof(*sub_header->rects));
- if (!sub_header->rects)
- goto fail;
- sub_header->rects[0] = av_mallocz(sizeof(AVSubtitleRect));
- if (!sub_header->rects[0])
- goto fail;
- sub_header->num_rects = 1;
- bitmap = sub_header->rects[0]->pict.data[0] = av_malloc(w * h);
- if (!bitmap)
- goto fail;
- if (decode_rle(bitmap, w * 2, w, (h + 1) / 2,
- buf, offset1, buf_size, is_8bit) < 0)
- goto fail;
- if (decode_rle(bitmap + w, w * 2, w, h / 2,
- buf, offset2, buf_size, is_8bit) < 0)
- goto fail;
- sub_header->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE);
- if (!sub_header->rects[0]->pict.data[1])
- goto fail;
- if (is_8bit) {
- if (!yuv_palette)
- goto fail;
- sub_header->rects[0]->nb_colors = 256;
- yuv_a_to_rgba(yuv_palette, alpha, (uint32_t*)sub_header->rects[0]->pict.data[1], 256);
- } else {
- sub_header->rects[0]->nb_colors = 4;
- guess_palette(ctx, (uint32_t*)sub_header->rects[0]->pict.data[1],
- 0xffff00);
- }
- sub_header->rects[0]->x = x1;
- sub_header->rects[0]->y = y1;
- sub_header->rects[0]->w = w;
- sub_header->rects[0]->h = h;
- sub_header->rects[0]->type = SUBTITLE_BITMAP;
- sub_header->rects[0]->pict.linesize[0] = w;
- sub_header->rects[0]->flags = is_menu ? AV_SUBTITLE_FLAG_FORCED : 0;
- }
- }
- if (next_cmd_pos < cmd_pos) {
- av_log(NULL, AV_LOG_ERROR, "Invalid command offset\n");
- break;
- }
- if (next_cmd_pos == cmd_pos)
- break;
- cmd_pos = next_cmd_pos;
- }
- if (sub_header->num_rects > 0)
- return is_menu;
- fail:
- reset_rects(sub_header);
- return -1;
-}
-
-static int is_transp(const uint8_t *buf, int pitch, int n,
- const uint8_t *transp_color)
-{
- int i;
- for(i = 0; i < n; i++) {
- if (!transp_color[*buf])
- return 0;
- buf += pitch;
- }
- return 1;
-}
-
-/* return 0 if empty rectangle, 1 if non empty */
-static int find_smallest_bounding_rectangle(AVSubtitle *s)
-{
- uint8_t transp_color[256] = { 0 };
- int y1, y2, x1, x2, y, w, h, i;
- uint8_t *bitmap;
-
- if (s->num_rects == 0 || !s->rects || s->rects[0]->w <= 0 || s->rects[0]->h <= 0)
- return 0;
-
- for(i = 0; i < s->rects[0]->nb_colors; i++) {
- if ((((uint32_t*)s->rects[0]->pict.data[1])[i] >> 24) == 0)
- transp_color[i] = 1;
- }
- y1 = 0;
- while (y1 < s->rects[0]->h && is_transp(s->rects[0]->pict.data[0] + y1 * s->rects[0]->pict.linesize[0],
- 1, s->rects[0]->w, transp_color))
- y1++;
- if (y1 == s->rects[0]->h) {
- av_freep(&s->rects[0]->pict.data[0]);
- s->rects[0]->w = s->rects[0]->h = 0;
- return 0;
- }
-
- y2 = s->rects[0]->h - 1;
- while (y2 > 0 && is_transp(s->rects[0]->pict.data[0] + y2 * s->rects[0]->pict.linesize[0], 1,
- s->rects[0]->w, transp_color))
- y2--;
- x1 = 0;
- while (x1 < (s->rects[0]->w - 1) && is_transp(s->rects[0]->pict.data[0] + x1, s->rects[0]->pict.linesize[0],
- s->rects[0]->h, transp_color))
- x1++;
- x2 = s->rects[0]->w - 1;
- while (x2 > 0 && is_transp(s->rects[0]->pict.data[0] + x2, s->rects[0]->pict.linesize[0], s->rects[0]->h,
- transp_color))
- x2--;
- w = x2 - x1 + 1;
- h = y2 - y1 + 1;
- bitmap = av_malloc(w * h);
- if (!bitmap)
- return 1;
- for(y = 0; y < h; y++) {
- memcpy(bitmap + w * y, s->rects[0]->pict.data[0] + x1 + (y1 + y) * s->rects[0]->pict.linesize[0], w);
- }
- av_freep(&s->rects[0]->pict.data[0]);
- s->rects[0]->pict.data[0] = bitmap;
- s->rects[0]->pict.linesize[0] = w;
- s->rects[0]->w = w;
- s->rects[0]->h = h;
- s->rects[0]->x += x1;
- s->rects[0]->y += y1;
- return 1;
-}
-
-#ifdef DEBUG
-#define ALPHA_MIX(A,BACK,FORE) (((255-(A)) * (BACK) + (A) * (FORE)) / 255)
-static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h,
- uint32_t *rgba_palette)
-{
- int x, y, alpha;
- uint32_t v;
- int back[3] = {0, 255, 0}; /* green background */
- FILE *f;
-
- f = fopen(filename, "w");
- if (!f) {
- perror(filename);
- return;
- }
- fprintf(f, "P6\n"
- "%d %d\n"
- "%d\n",
- w, h, 255);
- for(y = 0; y < h; y++) {
- for(x = 0; x < w; x++) {
- v = rgba_palette[bitmap[y * w + x]];
- alpha = v >> 24;
- putc(ALPHA_MIX(alpha, back[0], (v >> 16) & 0xff), f);
- putc(ALPHA_MIX(alpha, back[1], (v >> 8) & 0xff), f);
- putc(ALPHA_MIX(alpha, back[2], (v >> 0) & 0xff), f);
- }
- }
- fclose(f);
-}
-#endif
-
-static int append_to_cached_buf(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size)
-{
- DVDSubContext *ctx = avctx->priv_data;
-
- av_assert0(buf_size >= 0 && ctx->buf_size <= sizeof(ctx->buf));
- if (buf_size >= sizeof(ctx->buf) - ctx->buf_size) {
- av_log(avctx, AV_LOG_WARNING, "Attempt to reconstruct "
- "too large SPU packets aborted.\n");
- ctx->buf_size = 0;
- return AVERROR_INVALIDDATA;
- }
- memcpy(ctx->buf + ctx->buf_size, buf, buf_size);
- ctx->buf_size += buf_size;
- return 0;
-}
-
-static int dvdsub_decode(AVCodecContext *avctx,
- void *data, int *data_size,
- AVPacket *avpkt)
-{
- DVDSubContext *ctx = avctx->priv_data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- AVSubtitle *sub = data;
- int is_menu;
-
- if (ctx->buf_size) {
- int ret = append_to_cached_buf(avctx, buf, buf_size);
- if (ret < 0) {
- *data_size = 0;
- return ret;
- }
- buf = ctx->buf;
- buf_size = ctx->buf_size;
- }
-
- is_menu = decode_dvd_subtitles(ctx, sub, buf, buf_size);
- if (is_menu == AVERROR(EAGAIN)) {
- *data_size = 0;
- return append_to_cached_buf(avctx, buf, buf_size);
- }
-
- if (is_menu < 0) {
- no_subtitle:
- reset_rects(sub);
- *data_size = 0;
-
- return buf_size;
- }
- if (!is_menu && find_smallest_bounding_rectangle(sub) == 0)
- goto no_subtitle;
-
- if (ctx->forced_subs_only && !(sub->rects[0]->flags & AV_SUBTITLE_FLAG_FORCED))
- goto no_subtitle;
-
-#if defined(DEBUG)
- {
- char ppm_name[32];
-
- snprintf(ppm_name, sizeof(ppm_name), "/tmp/%05d.ppm", ctx->sub_id++);
- ff_dlog(NULL, "start=%d ms end =%d ms\n",
- sub->start_display_time,
- sub->end_display_time);
- ppm_save(ppm_name, sub->rects[0]->pict.data[0],
- sub->rects[0]->w, sub->rects[0]->h, (uint32_t*) sub->rects[0]->pict.data[1]);
- }
-#endif
-
- ctx->buf_size = 0;
- *data_size = 1;
- return buf_size;
-}
-
-static void parse_palette(DVDSubContext *ctx, char *p)
-{
- int i;
-
- ctx->has_palette = 1;
- for(i=0;i<16;i++) {
- ctx->palette[i] = strtoul(p, &p, 16);
- while(*p == ',' || av_isspace(*p))
- p++;
- }
-}
-
-static int parse_ifo_palette(DVDSubContext *ctx, char *p)
-{
- FILE *ifo;
- char ifostr[12];
- uint32_t sp_pgci, pgci, off_pgc, pgc;
- uint8_t r, g, b, yuv[65], *buf;
- int i, y, cb, cr, r_add, g_add, b_add;
- int ret = 0;
- const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
-
- ctx->has_palette = 0;
- if ((ifo = fopen(p, "r")) == NULL) {
- av_log(ctx, AV_LOG_WARNING, "Unable to open IFO file \"%s\": %s\n", p, av_err2str(AVERROR(errno)));
- return AVERROR_EOF;
- }
- if (fread(ifostr, 12, 1, ifo) != 1 || memcmp(ifostr, "DVDVIDEO-VTS", 12)) {
- av_log(ctx, AV_LOG_WARNING, "\"%s\" is not a proper IFO file\n", p);
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- if (fseek(ifo, 0xCC, SEEK_SET) == -1) {
- ret = AVERROR(errno);
- goto end;
- }
- if (fread(&sp_pgci, 4, 1, ifo) == 1) {
- pgci = av_be2ne32(sp_pgci) * 2048;
- if (fseek(ifo, pgci + 0x0C, SEEK_SET) == -1) {
- ret = AVERROR(errno);
- goto end;
- }
- if (fread(&off_pgc, 4, 1, ifo) == 1) {
- pgc = pgci + av_be2ne32(off_pgc);
- if (fseek(ifo, pgc + 0xA4, SEEK_SET) == -1) {
- ret = AVERROR(errno);
- goto end;
- }
- if (fread(yuv, 64, 1, ifo) == 1) {
- buf = yuv;
- for(i=0; i<16; i++) {
- y = *++buf;
- cr = *++buf;
- cb = *++buf;
- YUV_TO_RGB1_CCIR(cb, cr);
- YUV_TO_RGB2_CCIR(r, g, b, y);
- ctx->palette[i] = (r << 16) + (g << 8) + b;
- buf++;
- }
- ctx->has_palette = 1;
- }
- }
- }
- if (ctx->has_palette == 0) {
- av_log(ctx, AV_LOG_WARNING, "Failed to read palette from IFO file \"%s\"\n", p);
- ret = AVERROR_INVALIDDATA;
- }
-end:
- fclose(ifo);
- return ret;
-}
-
-static int dvdsub_parse_extradata(AVCodecContext *avctx)
-{
- DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data;
- char *dataorig, *data;
- int ret = 1;
-
- if (!avctx->extradata || !avctx->extradata_size)
- return 1;
-
- dataorig = data = av_malloc(avctx->extradata_size+1);
- if (!data)
- return AVERROR(ENOMEM);
- memcpy(data, avctx->extradata, avctx->extradata_size);
- data[avctx->extradata_size] = '\0';
-
- for(;;) {
- int pos = strcspn(data, "\n\r");
- if (pos==0 && *data==0)
- break;
-
- if (strncmp("palette:", data, 8) == 0) {
- parse_palette(ctx, data + 8);
- } else if (strncmp("size:", data, 5) == 0) {
- int w, h;
- if (sscanf(data + 5, "%dx%d", &w, &h) == 2) {
- ret = ff_set_dimensions(avctx, w, h);
- if (ret < 0)
- goto fail;
- }
- }
-
- data += pos;
- data += strspn(data, "\n\r");
- }
-
-fail:
- av_free(dataorig);
- return ret;
-}
-
-static av_cold int dvdsub_init(AVCodecContext *avctx)
-{
- DVDSubContext *ctx = avctx->priv_data;
- int ret;
-
- if ((ret = dvdsub_parse_extradata(avctx)) < 0)
- return ret;
-
- if (ctx->ifo_str)
- parse_ifo_palette(ctx, ctx->ifo_str);
- if (ctx->palette_str)
- parse_palette(ctx, ctx->palette_str);
- if (ctx->has_palette) {
- int i;
- av_log(avctx, AV_LOG_DEBUG, "palette:");
- for(i=0;i<16;i++)
- av_log(avctx, AV_LOG_DEBUG, " 0x%06x", ctx->palette[i]);
- av_log(avctx, AV_LOG_DEBUG, "\n");
- }
-
- return 1;
-}
-
-static void dvdsub_flush(AVCodecContext *avctx)
-{
- DVDSubContext *ctx = avctx->priv_data;
- ctx->buf_size = 0;
-}
-
-static av_cold int dvdsub_close(AVCodecContext *avctx)
-{
- dvdsub_flush(avctx);
- return 0;
-}
-
-#define OFFSET(field) offsetof(DVDSubContext, field)
-#define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
-static const AVOption options[] = {
- { "palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD },
- { "ifo_palette", "obtain the global palette from .IFO file", OFFSET(ifo_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD },
- { "forced_subs_only", "Only show forced subtitles", OFFSET(forced_subs_only), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD},
- { NULL }
-};
-static const AVClass dvdsub_class = {
- .class_name = "dvdsubdec",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-AVCodec ff_dvdsub_decoder = {
- .name = "dvdsub",
- .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
- .type = AVMEDIA_TYPE_SUBTITLE,
- .id = AV_CODEC_ID_DVD_SUBTITLE,
- .priv_data_size = sizeof(DVDSubContext),
- .init = dvdsub_init,
- .decode = dvdsub_decode,
- .flush = dvdsub_flush,
- .close = dvdsub_close,
- .priv_class = &dvdsub_class,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/eac3dec.c b/ffmpeg-2-8-11/libavcodec/eac3dec.c
deleted file mode 100644
index ef815af..0000000
--- a/ffmpeg-2-8-11/libavcodec/eac3dec.c
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * E-AC-3 decoder
- * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec at gmail.com>
- * Copyright (c) 2008 Justin Ruggles
- *
- * 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
- */
-
-/*
- * There are several features of E-AC-3 that this decoder does not yet support.
- *
- * Enhanced Coupling
- * No known samples exist. If any ever surface, this feature should not be
- * too difficult to implement.
- *
- * Reduced Sample Rates
- * No known samples exist. The spec also does not give clear information
- * on how this is to be implemented.
- *
- * Dependent Streams
- * Only the independent stream is currently decoded. Any dependent
- * streams are skipped. We have only come across two examples of this, and
- * they are both just test streams, one for HD-DVD and the other for
- * Blu-ray.
- *
- * Transient Pre-noise Processing
- * This is side information which a decoder should use to reduce artifacts
- * caused by transients. There are samples which are known to have this
- * information, but this decoder currently ignores it.
- */
-
-
-#include "avcodec.h"
-#include "internal.h"
-#include "aac_ac3_parser.h"
-#include "ac3.h"
-#include "ac3_parser.h"
-#include "ac3dec.h"
-#include "ac3dec_data.h"
-#include "eac3_data.h"
-
-/** gain adaptive quantization mode */
-typedef enum {
- EAC3_GAQ_NO =0,
- EAC3_GAQ_12,
- EAC3_GAQ_14,
- EAC3_GAQ_124
-} EAC3GaqMode;
-
-#define EAC3_SR_CODE_REDUCED 3
-
-static void ff_eac3_apply_spectral_extension(AC3DecodeContext *s)
-{
- int bin, bnd, ch, i;
- uint8_t wrapflag[SPX_MAX_BANDS]={1,0,}, num_copy_sections, copy_sizes[SPX_MAX_BANDS];
- float rms_energy[SPX_MAX_BANDS];
-
- /* Set copy index mapping table. Set wrap flags to apply a notch filter at
- wrap points later on. */
- bin = s->spx_dst_start_freq;
- num_copy_sections = 0;
- for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
- int copysize;
- int bandsize = s->spx_band_sizes[bnd];
- if (bin + bandsize > s->spx_src_start_freq) {
- copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq;
- bin = s->spx_dst_start_freq;
- wrapflag[bnd] = 1;
- }
- for (i = 0; i < bandsize; i += copysize) {
- if (bin == s->spx_src_start_freq) {
- copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq;
- bin = s->spx_dst_start_freq;
- }
- copysize = FFMIN(bandsize - i, s->spx_src_start_freq - bin);
- bin += copysize;
- }
- }
- copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq;
-
- for (ch = 1; ch <= s->fbw_channels; ch++) {
- if (!s->channel_uses_spx[ch])
- continue;
-
- /* Copy coeffs from normal bands to extension bands */
- bin = s->spx_src_start_freq;
- for (i = 0; i < num_copy_sections; i++) {
- memcpy(&s->transform_coeffs[ch][bin],
- &s->transform_coeffs[ch][s->spx_dst_start_freq],
- copy_sizes[i]*sizeof(INTFLOAT));
- bin += copy_sizes[i];
- }
-
- /* Calculate RMS energy for each SPX band. */
- bin = s->spx_src_start_freq;
- for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
- int bandsize = s->spx_band_sizes[bnd];
- float accum = 0.0f;
- for (i = 0; i < bandsize; i++) {
- float coeff = s->transform_coeffs[ch][bin++];
- accum += coeff * coeff;
- }
- rms_energy[bnd] = sqrtf(accum / bandsize);
- }
-
- /* Apply a notch filter at transitions between normal and extension
- bands and at all wrap points. */
- if (s->spx_atten_code[ch] >= 0) {
- const float *atten_tab = ff_eac3_spx_atten_tab[s->spx_atten_code[ch]];
- bin = s->spx_src_start_freq - 2;
- for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
- if (wrapflag[bnd]) {
- INTFLOAT *coeffs = &s->transform_coeffs[ch][bin];
- coeffs[0] *= atten_tab[0];
- coeffs[1] *= atten_tab[1];
- coeffs[2] *= atten_tab[2];
- coeffs[3] *= atten_tab[1];
- coeffs[4] *= atten_tab[0];
- }
- bin += s->spx_band_sizes[bnd];
- }
- }
-
- /* Apply noise-blended coefficient scaling based on previously
- calculated RMS energy, blending factors, and SPX coordinates for
- each band. */
- bin = s->spx_src_start_freq;
- for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
- float nscale = s->spx_noise_blend[ch][bnd] * rms_energy[bnd] * (1.0f / INT32_MIN);
- float sscale = s->spx_signal_blend[ch][bnd];
-#if USE_FIXED
- // spx_noise_blend and spx_signal_blend are both FP.23
- nscale *= 1.0 / (1<<23);
- sscale *= 1.0 / (1<<23);
-#endif
- for (i = 0; i < s->spx_band_sizes[bnd]; i++) {
- float noise = nscale * (int32_t)av_lfg_get(&s->dith_state);
- s->transform_coeffs[ch][bin] *= sscale;
- s->transform_coeffs[ch][bin++] += noise;
- }
- }
- }
-}
-
-
-/** lrint(M_SQRT2*cos(2*M_PI/12)*(1<<23)) */
-#define COEFF_0 10273905LL
-
-/** lrint(M_SQRT2*cos(0*M_PI/12)*(1<<23)) = lrint(M_SQRT2*(1<<23)) */
-#define COEFF_1 11863283LL
-
-/** lrint(M_SQRT2*cos(5*M_PI/12)*(1<<23)) */
-#define COEFF_2 3070444LL
-
-/**
- * Calculate 6-point IDCT of the pre-mantissas.
- * All calculations are 24-bit fixed-point.
- */
-static void idct6(int pre_mant[6])
-{
- int tmp;
- int even0, even1, even2, odd0, odd1, odd2;
-
- odd1 = pre_mant[1] - pre_mant[3] - pre_mant[5];
-
- even2 = ( pre_mant[2] * COEFF_0) >> 23;
- tmp = ( pre_mant[4] * COEFF_1) >> 23;
- odd0 = ((pre_mant[1] + pre_mant[5]) * COEFF_2) >> 23;
-
- even0 = pre_mant[0] + (tmp >> 1);
- even1 = pre_mant[0] - tmp;
-
- tmp = even0;
- even0 = tmp + even2;
- even2 = tmp - even2;
-
- tmp = odd0;
- odd0 = tmp + pre_mant[1] + pre_mant[3];
- odd2 = tmp + pre_mant[5] - pre_mant[3];
-
- pre_mant[0] = even0 + odd0;
- pre_mant[1] = even1 + odd1;
- pre_mant[2] = even2 + odd2;
- pre_mant[3] = even2 - odd2;
- pre_mant[4] = even1 - odd1;
- pre_mant[5] = even0 - odd0;
-}
-
-static void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch)
-{
- int bin, blk, gs;
- int end_bap, gaq_mode;
- GetBitContext *gbc = &s->gbc;
- int gaq_gain[AC3_MAX_COEFS];
-
- gaq_mode = get_bits(gbc, 2);
- end_bap = (gaq_mode < 2) ? 12 : 17;
-
- /* if GAQ gain is used, decode gain codes for bins with hebap between
- 8 and end_bap */
- gs = 0;
- if (gaq_mode == EAC3_GAQ_12 || gaq_mode == EAC3_GAQ_14) {
- /* read 1-bit GAQ gain codes */
- for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
- if (s->bap[ch][bin] > 7 && s->bap[ch][bin] < end_bap)
- gaq_gain[gs++] = get_bits1(gbc) << (gaq_mode-1);
- }
- } else if (gaq_mode == EAC3_GAQ_124) {
- /* read 1.67-bit GAQ gain codes (3 codes in 5 bits) */
- int gc = 2;
- for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
- if (s->bap[ch][bin] > 7 && s->bap[ch][bin] < 17) {
- if (gc++ == 2) {
- int group_code = get_bits(gbc, 5);
- if (group_code > 26) {
- av_log(s->avctx, AV_LOG_WARNING, "GAQ gain group code out-of-range\n");
- group_code = 26;
- }
- gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][0];
- gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][1];
- gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][2];
- gc = 0;
- }
- }
- }
- }
-
- gs=0;
- for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
- int hebap = s->bap[ch][bin];
- int bits = ff_eac3_bits_vs_hebap[hebap];
- if (!hebap) {
- /* zero-mantissa dithering */
- for (blk = 0; blk < 6; blk++) {
- s->pre_mantissa[ch][bin][blk] = (av_lfg_get(&s->dith_state) & 0x7FFFFF) - 0x400000;
- }
- } else if (hebap < 8) {
- /* Vector Quantization */
- int v = get_bits(gbc, bits);
- for (blk = 0; blk < 6; blk++) {
- s->pre_mantissa[ch][bin][blk] = ff_eac3_mantissa_vq[hebap][v][blk] << 8;
- }
- } else {
- /* Gain Adaptive Quantization */
- int gbits, log_gain;
- if (gaq_mode != EAC3_GAQ_NO && hebap < end_bap) {
- log_gain = gaq_gain[gs++];
- } else {
- log_gain = 0;
- }
- gbits = bits - log_gain;
-
- for (blk = 0; blk < 6; blk++) {
- int mant = get_sbits(gbc, gbits);
- if (log_gain && mant == -(1 << (gbits-1))) {
- /* large mantissa */
- int b;
- int mbits = bits - (2 - log_gain);
- mant = get_sbits(gbc, mbits);
- mant <<= (23 - (mbits - 1));
- /* remap mantissa value to correct for asymmetric quantization */
- if (mant >= 0)
- b = 1 << (23 - log_gain);
- else
- b = ff_eac3_gaq_remap_2_4_b[hebap-8][log_gain-1] << 8;
- mant += ((ff_eac3_gaq_remap_2_4_a[hebap-8][log_gain-1] * (int64_t)mant) >> 15) + b;
- } else {
- /* small mantissa, no GAQ, or Gk=1 */
- mant <<= 24 - bits;
- if (!log_gain) {
- /* remap mantissa value for no GAQ or Gk=1 */
- mant += (ff_eac3_gaq_remap_1[hebap-8] * (int64_t)mant) >> 15;
- }
- }
- s->pre_mantissa[ch][bin][blk] = mant;
- }
- }
- idct6(s->pre_mantissa[ch][bin]);
- }
-}
-
-static int ff_eac3_parse_header(AC3DecodeContext *s)
-{
- int i, blk, ch;
- int ac3_exponent_strategy, parse_aht_info, parse_spx_atten_data;
- int parse_transient_proc_info;
- int num_cpl_blocks;
- GetBitContext *gbc = &s->gbc;
-
- /* An E-AC-3 stream can have multiple independent streams which the
- application can select from. each independent stream can also contain
- dependent streams which are used to add or replace channels. */
- if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) {
- avpriv_request_sample(s->avctx, "Dependent substream decoding");
- return AAC_AC3_PARSE_ERROR_FRAME_TYPE;
- } else if (s->frame_type == EAC3_FRAME_TYPE_RESERVED) {
- av_log(s->avctx, AV_LOG_ERROR, "Reserved frame type\n");
- return AAC_AC3_PARSE_ERROR_FRAME_TYPE;
- }
-
- /* The substream id indicates which substream this frame belongs to. each
- independent stream has its own substream id, and the dependent streams
- associated to an independent stream have matching substream id's. */
- if (s->substreamid) {
- /* only decode substream with id=0. skip any additional substreams. */
- avpriv_request_sample(s->avctx, "Additional substreams");
- return AAC_AC3_PARSE_ERROR_FRAME_TYPE;
- }
-
- if (s->bit_alloc_params.sr_code == EAC3_SR_CODE_REDUCED) {
- /* The E-AC-3 specification does not tell how to handle reduced sample
- rates in bit allocation. The best assumption would be that it is
- handled like AC-3 DolbyNet, but we cannot be sure until we have a
- sample which utilizes this feature. */
- avpriv_request_sample(s->avctx, "Reduced sampling rate");
- return AVERROR_PATCHWELCOME;
- }
- skip_bits(gbc, 5); // skip bitstream id
-
- /* volume control params */
- for (i = 0; i < (s->channel_mode ? 1 : 2); i++) {
- skip_bits(gbc, 5); // skip dialog normalization
- if (get_bits1(gbc)) {
- skip_bits(gbc, 8); // skip compression gain word
- }
- }
-
- /* dependent stream channel map */
- if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) {
- if (get_bits1(gbc)) {
- skip_bits(gbc, 16); // skip custom channel map
- }
- }
-
- /* mixing metadata */
- if (get_bits1(gbc)) {
- /* center and surround mix levels */
- if (s->channel_mode > AC3_CHMODE_STEREO) {
- s->preferred_downmix = get_bits(gbc, 2);
- if (s->channel_mode & 1) {
- /* if three front channels exist */
- s->center_mix_level_ltrt = get_bits(gbc, 3);
- s->center_mix_level = get_bits(gbc, 3);
- }
- if (s->channel_mode & 4) {
- /* if a surround channel exists */
- s->surround_mix_level_ltrt = av_clip(get_bits(gbc, 3), 3, 7);
- s->surround_mix_level = av_clip(get_bits(gbc, 3), 3, 7);
- }
- }
-
- /* lfe mix level */
- if (s->lfe_on && (s->lfe_mix_level_exists = get_bits1(gbc))) {
- s->lfe_mix_level = get_bits(gbc, 5);
- }
-
- /* info for mixing with other streams and substreams */
- if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT) {
- for (i = 0; i < (s->channel_mode ? 1 : 2); i++) {
- // TODO: apply program scale factor
- if (get_bits1(gbc)) {
- skip_bits(gbc, 6); // skip program scale factor
- }
- }
- if (get_bits1(gbc)) {
- skip_bits(gbc, 6); // skip external program scale factor
- }
- /* skip mixing parameter data */
- switch(get_bits(gbc, 2)) {
- case 1: skip_bits(gbc, 5); break;
- case 2: skip_bits(gbc, 12); break;
- case 3: {
- int mix_data_size = (get_bits(gbc, 5) + 2) << 3;
- skip_bits_long(gbc, mix_data_size);
- break;
- }
- }
- /* skip pan information for mono or dual mono source */
- if (s->channel_mode < AC3_CHMODE_STEREO) {
- for (i = 0; i < (s->channel_mode ? 1 : 2); i++) {
- if (get_bits1(gbc)) {
- /* note: this is not in the ATSC A/52B specification
- reference: ETSI TS 102 366 V1.1.1
- section: E.1.3.1.25 */
- skip_bits(gbc, 8); // skip pan mean direction index
- skip_bits(gbc, 6); // skip reserved paninfo bits
- }
- }
- }
- /* skip mixing configuration information */
- if (get_bits1(gbc)) {
- for (blk = 0; blk < s->num_blocks; blk++) {
- if (s->num_blocks == 1 || get_bits1(gbc)) {
- skip_bits(gbc, 5);
- }
- }
- }
- }
- }
-
- /* informational metadata */
- if (get_bits1(gbc)) {
- s->bitstream_mode = get_bits(gbc, 3);
- skip_bits(gbc, 2); // skip copyright bit and original bitstream bit
- if (s->channel_mode == AC3_CHMODE_STEREO) {
- s->dolby_surround_mode = get_bits(gbc, 2);
- s->dolby_headphone_mode = get_bits(gbc, 2);
- }
- if (s->channel_mode >= AC3_CHMODE_2F2R) {
- s->dolby_surround_ex_mode = get_bits(gbc, 2);
- }
- for (i = 0; i < (s->channel_mode ? 1 : 2); i++) {
- if (get_bits1(gbc)) {
- skip_bits(gbc, 8); // skip mix level, room type, and A/D converter type
- }
- }
- if (s->bit_alloc_params.sr_code != EAC3_SR_CODE_REDUCED) {
- skip_bits1(gbc); // skip source sample rate code
- }
- }
-
- /* converter synchronization flag
- If frames are less than six blocks, this bit should be turned on
- once every 6 blocks to indicate the start of a frame set.
- reference: RFC 4598, Section 2.1.3 Frame Sets */
- if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT && s->num_blocks != 6) {
- skip_bits1(gbc); // skip converter synchronization flag
- }
-
- /* original frame size code if this stream was converted from AC-3 */
- if (s->frame_type == EAC3_FRAME_TYPE_AC3_CONVERT &&
- (s->num_blocks == 6 || get_bits1(gbc))) {
- skip_bits(gbc, 6); // skip frame size code
- }
-
- /* additional bitstream info */
- if (get_bits1(gbc)) {
- int addbsil = get_bits(gbc, 6);
- for (i = 0; i < addbsil + 1; i++) {
- skip_bits(gbc, 8); // skip additional bit stream info
- }
- }
-
- /* audio frame syntax flags, strategy data, and per-frame data */
-
- if (s->num_blocks == 6) {
- ac3_exponent_strategy = get_bits1(gbc);
- parse_aht_info = get_bits1(gbc);
- } else {
- /* less than 6 blocks, so use AC-3-style exponent strategy syntax, and
- do not use AHT */
- ac3_exponent_strategy = 1;
- parse_aht_info = 0;
- }
-
- s->snr_offset_strategy = get_bits(gbc, 2);
- parse_transient_proc_info = get_bits1(gbc);
-
- s->block_switch_syntax = get_bits1(gbc);
- if (!s->block_switch_syntax)
- memset(s->block_switch, 0, sizeof(s->block_switch));
-
- s->dither_flag_syntax = get_bits1(gbc);
- if (!s->dither_flag_syntax) {
- for (ch = 1; ch <= s->fbw_channels; ch++)
- s->dither_flag[ch] = 1;
- }
- s->dither_flag[CPL_CH] = s->dither_flag[s->lfe_ch] = 0;
-
- s->bit_allocation_syntax = get_bits1(gbc);
- if (!s->bit_allocation_syntax) {
- /* set default bit allocation parameters */
- s->bit_alloc_params.slow_decay = ff_ac3_slow_decay_tab[2];
- s->bit_alloc_params.fast_decay = ff_ac3_fast_decay_tab[1];
- s->bit_alloc_params.slow_gain = ff_ac3_slow_gain_tab [1];
- s->bit_alloc_params.db_per_bit = ff_ac3_db_per_bit_tab[2];
- s->bit_alloc_params.floor = ff_ac3_floor_tab [7];
- }
-
- s->fast_gain_syntax = get_bits1(gbc);
- s->dba_syntax = get_bits1(gbc);
- s->skip_syntax = get_bits1(gbc);
- parse_spx_atten_data = get_bits1(gbc);
-
- /* coupling strategy occurrence and coupling use per block */
- num_cpl_blocks = 0;
- if (s->channel_mode > 1) {
- for (blk = 0; blk < s->num_blocks; blk++) {
- s->cpl_strategy_exists[blk] = (!blk || get_bits1(gbc));
- if (s->cpl_strategy_exists[blk]) {
- s->cpl_in_use[blk] = get_bits1(gbc);
- } else {
- s->cpl_in_use[blk] = s->cpl_in_use[blk-1];
- }
- num_cpl_blocks += s->cpl_in_use[blk];
- }
- } else {
- memset(s->cpl_in_use, 0, sizeof(s->cpl_in_use));
- }
-
- /* exponent strategy data */
- if (ac3_exponent_strategy) {
- /* AC-3-style exponent strategy syntax */
- for (blk = 0; blk < s->num_blocks; blk++) {
- for (ch = !s->cpl_in_use[blk]; ch <= s->fbw_channels; ch++) {
- s->exp_strategy[blk][ch] = get_bits(gbc, 2);
- }
- }
- } else {
- /* LUT-based exponent strategy syntax */
- for (ch = !((s->channel_mode > 1) && num_cpl_blocks); ch <= s->fbw_channels; ch++) {
- int frmchexpstr = get_bits(gbc, 5);
- for (blk = 0; blk < 6; blk++) {
- s->exp_strategy[blk][ch] = ff_eac3_frm_expstr[frmchexpstr][blk];
- }
- }
- }
- /* LFE exponent strategy */
- if (s->lfe_on) {
- for (blk = 0; blk < s->num_blocks; blk++) {
- s->exp_strategy[blk][s->lfe_ch] = get_bits1(gbc);
- }
- }
- /* original exponent strategies if this stream was converted from AC-3 */
- if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT &&
- (s->num_blocks == 6 || get_bits1(gbc))) {
- skip_bits(gbc, 5 * s->fbw_channels); // skip converter channel exponent strategy
- }
-
- /* determine which channels use AHT */
- if (parse_aht_info) {
- /* For AHT to be used, all non-zero blocks must reuse exponents from
- the first block. Furthermore, for AHT to be used in the coupling
- channel, all blocks must use coupling and use the same coupling
- strategy. */
- s->channel_uses_aht[CPL_CH]=0;
- for (ch = (num_cpl_blocks != 6); ch <= s->channels; ch++) {
- int use_aht = 1;
- for (blk = 1; blk < 6; blk++) {
- if ((s->exp_strategy[blk][ch] != EXP_REUSE) ||
- (!ch && s->cpl_strategy_exists[blk])) {
- use_aht = 0;
- break;
- }
- }
- s->channel_uses_aht[ch] = use_aht && get_bits1(gbc);
- }
- } else {
- memset(s->channel_uses_aht, 0, sizeof(s->channel_uses_aht));
- }
-
- /* per-frame SNR offset */
- if (!s->snr_offset_strategy) {
- int csnroffst = (get_bits(gbc, 6) - 15) << 4;
- int snroffst = (csnroffst + get_bits(gbc, 4)) << 2;
- for (ch = 0; ch <= s->channels; ch++)
- s->snr_offset[ch] = snroffst;
- }
-
- /* transient pre-noise processing data */
- if (parse_transient_proc_info) {
- for (ch = 1; ch <= s->fbw_channels; ch++) {
- if (get_bits1(gbc)) { // channel in transient processing
- skip_bits(gbc, 10); // skip transient processing location
- skip_bits(gbc, 8); // skip transient processing length
- }
- }
- }
-
- /* spectral extension attenuation data */
- for (ch = 1; ch <= s->fbw_channels; ch++) {
- if (parse_spx_atten_data && get_bits1(gbc)) {
- s->spx_atten_code[ch] = get_bits(gbc, 5);
- } else {
- s->spx_atten_code[ch] = -1;
- }
- }
-
- /* block start information */
- if (s->num_blocks > 1 && get_bits1(gbc)) {
- /* reference: Section E2.3.2.27
- nblkstrtbits = (numblks - 1) * (4 + ceiling(log2(words_per_frame)))
- The spec does not say what this data is or what it's used for.
- It is likely the offset of each block within the frame. */
- int block_start_bits = (s->num_blocks-1) * (4 + av_log2(s->frame_size-2));
- skip_bits_long(gbc, block_start_bits);
- avpriv_request_sample(s->avctx, "Block start info");
- }
-
- /* syntax state initialization */
- for (ch = 1; ch <= s->fbw_channels; ch++) {
- s->first_spx_coords[ch] = 1;
- s->first_cpl_coords[ch] = 1;
- }
- s->first_cpl_leak = 1;
-
- return 0;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/eamad.c b/ffmpeg-2-8-11/libavcodec/eamad.c
deleted file mode 100644
index 4e202f9..0000000
--- a/ffmpeg-2-8-11/libavcodec/eamad.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Electronic Arts Madcow Video Decoder
- * Copyright (c) 2007-2009 Peter Ross
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * Electronic Arts Madcow Video Decoder
- * @author Peter Ross <pross at xvid.org>
- *
- * @see technical details at
- * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_MAD
- */
-
-#include "avcodec.h"
-#include "blockdsp.h"
-#include "bytestream.h"
-#include "bswapdsp.h"
-#include "get_bits.h"
-#include "aandcttab.h"
-#include "eaidct.h"
-#include "idctdsp.h"
-#include "internal.h"
-#include "mpeg12data.h"
-#include "mpeg12vlc.h"
-
-#define EA_PREAMBLE_SIZE 8
-#define MADk_TAG MKTAG('M', 'A', 'D', 'k') /* MAD i-frame */
-#define MADm_TAG MKTAG('M', 'A', 'D', 'm') /* MAD p-frame */
-#define MADe_TAG MKTAG('M', 'A', 'D', 'e') /* MAD lqp-frame */
-
-typedef struct MadContext {
- AVCodecContext *avctx;
- BlockDSPContext bdsp;
- BswapDSPContext bbdsp;
- IDCTDSPContext idsp;
- AVFrame *last_frame;
- GetBitContext gb;
- void *bitstream_buf;
- unsigned int bitstream_buf_size;
- DECLARE_ALIGNED(16, int16_t, block)[64];
- ScanTable scantable;
- uint16_t quant_matrix[64];
- int mb_x;
- int mb_y;
-} MadContext;
-
-static av_cold int decode_init(AVCodecContext *avctx)
-{
- MadContext *s = avctx->priv_data;
- s->avctx = avctx;
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- ff_blockdsp_init(&s->bdsp, avctx);
- ff_bswapdsp_init(&s->bbdsp);
- ff_idctdsp_init(&s->idsp, avctx);
- ff_init_scantable_permutation(s->idsp.idct_permutation, FF_IDCT_PERM_NONE);
- ff_init_scantable(s->idsp.idct_permutation, &s->scantable, ff_zigzag_direct);
- ff_mpeg12_init_vlcs();
-
- s->last_frame = av_frame_alloc();
- if (!s->last_frame)
- return AVERROR(ENOMEM);
-
- return 0;
-}
-
-static inline void comp(unsigned char *dst, int dst_stride,
- unsigned char *src, int src_stride, int add)
-{
- int j, i;
- for (j=0; j<8; j++)
- for (i=0; i<8; i++)
- dst[j*dst_stride + i] = av_clip_uint8(src[j*src_stride + i] + add);
-}
-
-static inline void comp_block(MadContext *t, AVFrame *frame,
- int mb_x, int mb_y,
- int j, int mv_x, int mv_y, int add)
-{
- if (j < 4) {
- unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame->linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x;
- if (offset >= (t->avctx->height - 7) * t->last_frame->linesize[0] - 7)
- return;
- comp(frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3),
- frame->linesize[0],
- t->last_frame->data[0] + offset,
- t->last_frame->linesize[0], add);
- } else if (!(t->avctx->flags & AV_CODEC_FLAG_GRAY)) {
- int index = j - 3;
- unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame->linesize[index] + mb_x * 8 + (mv_x/2);
- if (offset >= (t->avctx->height/2 - 7) * t->last_frame->linesize[index] - 7)
- return;
- comp(frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x * 8,
- frame->linesize[index],
- t->last_frame->data[index] + offset,
- t->last_frame->linesize[index], add);
- }
-}
-
-static inline void idct_put(MadContext *t, AVFrame *frame, int16_t *block,
- int mb_x, int mb_y, int j)
-{
- if (j < 4) {
- ff_ea_idct_put_c(
- frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3),
- frame->linesize[0], block);
- } else if (!(t->avctx->flags & AV_CODEC_FLAG_GRAY)) {
- int index = j - 3;
- ff_ea_idct_put_c(
- frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x*8,
- frame->linesize[index], block);
- }
-}
-
-static inline int decode_block_intra(MadContext *s, int16_t * block)
-{
- int level, i, j, run;
- RLTable *rl = &ff_rl_mpeg1;
- const uint8_t *scantable = s->scantable.permutated;
- int16_t *quant_matrix = s->quant_matrix;
-
- block[0] = (128 + get_sbits(&s->gb, 8)) * quant_matrix[0];
-
- /* The RL decoder is derived from mpeg1_decode_block_intra;
- Escaped level and run values a decoded differently */
- i = 0;
- {
- OPEN_READER(re, &s->gb);
- /* now quantify & encode AC coefficients */
- for (;;) {
- UPDATE_CACHE(re, &s->gb);
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-
- if (level == 127) {
- break;
- } else if (level != 0) {
- i += run;
- if (i > 63) {
- av_log(s->avctx, AV_LOG_ERROR,
- "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- j = scantable[i];
- level = (level*quant_matrix[j]) >> 4;
- level = (level-1)|1;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
- } else {
- /* escape */
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 10); SKIP_BITS(re, &s->gb, 10);
-
- UPDATE_CACHE(re, &s->gb);
- run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);
-
- i += run;
- if (i > 63) {
- av_log(s->avctx, AV_LOG_ERROR,
- "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- j = scantable[i];
- if (level < 0) {
- level = -level;
- level = (level*quant_matrix[j]) >> 4;
- level = (level-1)|1;
- level = -level;
- } else {
- level = (level*quant_matrix[j]) >> 4;
- level = (level-1)|1;
- }
- }
-
- block[j] = level;
- }
- CLOSE_READER(re, &s->gb);
- }
- return 0;
-}
-
-static int decode_motion(GetBitContext *gb)
-{
- int value = 0;
- if (get_bits1(gb)) {
- if (get_bits1(gb))
- value = -17;
- value += get_bits(gb, 4) + 1;
- }
- return value;
-}
-
-static int decode_mb(MadContext *s, AVFrame *frame, int inter)
-{
- int mv_map = 0;
- int av_uninit(mv_x), av_uninit(mv_y);
- int j;
-
- if (inter) {
- int v = decode210(&s->gb);
- if (v < 2) {
- mv_map = v ? get_bits(&s->gb, 6) : 63;
- mv_x = decode_motion(&s->gb);
- mv_y = decode_motion(&s->gb);
- }
- }
-
- for (j=0; j<6; j++) {
- if (mv_map & (1<<j)) { // mv_x and mv_y are guarded by mv_map
- int add = 2*decode_motion(&s->gb);
- if (s->last_frame->data[0])
- comp_block(s, frame, s->mb_x, s->mb_y, j, mv_x, mv_y, add);
- } else {
- s->bdsp.clear_block(s->block);
- if(decode_block_intra(s, s->block) < 0)
- return -1;
- idct_put(s, frame, s->block, s->mb_x, s->mb_y, j);
- }
- }
- return 0;
-}
-
-static void calc_quant_matrix(MadContext *s, int qscale)
-{
- int i;
-
- s->quant_matrix[0] = (ff_inv_aanscales[0]*ff_mpeg1_default_intra_matrix[0]) >> 11;
- for (i=1; i<64; i++)
- s->quant_matrix[i] = (ff_inv_aanscales[i]*ff_mpeg1_default_intra_matrix[i]*qscale + 32) >> 10;
-}
-
-static int decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- MadContext *s = avctx->priv_data;
- AVFrame *frame = data;
- GetByteContext gb;
- int width, height;
- int chunk_type;
- int inter, ret;
-
- bytestream2_init(&gb, buf, buf_size);
-
- chunk_type = bytestream2_get_le32(&gb);
- inter = (chunk_type == MADm_TAG || chunk_type == MADe_TAG);
- bytestream2_skip(&gb, 10);
-
- av_reduce(&avctx->framerate.den, &avctx->framerate.num,
- bytestream2_get_le16(&gb), 1000, 1<<30);
-
- width = bytestream2_get_le16(&gb);
- height = bytestream2_get_le16(&gb);
- bytestream2_skip(&gb, 1);
- calc_quant_matrix(s, bytestream2_get_byte(&gb));
- bytestream2_skip(&gb, 2);
-
- if (bytestream2_get_bytes_left(&gb) < 2) {
- av_log(avctx, AV_LOG_ERROR, "Input data too small\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (width < 16 || height < 16) {
- av_log(avctx, AV_LOG_ERROR, "Dimensions too small\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (avctx->width != width || avctx->height != height) {
- av_frame_unref(s->last_frame);
- if((width * height)/2048*7 > bytestream2_get_bytes_left(&gb))
- return AVERROR_INVALIDDATA;
- if ((ret = ff_set_dimensions(avctx, width, height)) < 0)
- return ret;
- }
-
- if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
- return ret;
-
- if (inter && !s->last_frame->data[0]) {
- av_log(avctx, AV_LOG_WARNING, "Missing reference frame.\n");
- ret = ff_get_buffer(avctx, s->last_frame, AV_GET_BUFFER_FLAG_REF);
- if (ret < 0)
- return ret;
- memset(s->last_frame->data[0], 0, s->last_frame->height *
- s->last_frame->linesize[0]);
- memset(s->last_frame->data[1], 0x80, s->last_frame->height / 2 *
- s->last_frame->linesize[1]);
- memset(s->last_frame->data[2], 0x80, s->last_frame->height / 2 *
- s->last_frame->linesize[2]);
- }
-
- av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size,
- bytestream2_get_bytes_left(&gb));
- if (!s->bitstream_buf)
- return AVERROR(ENOMEM);
- s->bbdsp.bswap16_buf(s->bitstream_buf, (const uint16_t *)(buf + bytestream2_tell(&gb)),
- bytestream2_get_bytes_left(&gb) / 2);
- memset((uint8_t*)s->bitstream_buf + bytestream2_get_bytes_left(&gb), 0, AV_INPUT_BUFFER_PADDING_SIZE);
- init_get_bits(&s->gb, s->bitstream_buf, 8*(bytestream2_get_bytes_left(&gb)));
-
- for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++)
- for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++)
- if(decode_mb(s, frame, inter) < 0)
- return AVERROR_INVALIDDATA;
-
- *got_frame = 1;
-
- if (chunk_type != MADe_TAG) {
- av_frame_unref(s->last_frame);
- if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
- return ret;
- }
-
- return buf_size;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx)
-{
- MadContext *t = avctx->priv_data;
- av_frame_free(&t->last_frame);
- av_freep(&t->bitstream_buf);
- return 0;
-}
-
-AVCodec ff_eamad_decoder = {
- .name = "eamad",
- .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Madcow Video"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MAD,
- .priv_data_size = sizeof(MadContext),
- .init = decode_init,
- .close = decode_end,
- .decode = decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/eatqi.c b/ffmpeg-2-8-11/libavcodec/eatqi.c
deleted file mode 100644
index 2423e21..0000000
--- a/ffmpeg-2-8-11/libavcodec/eatqi.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Electronic Arts TQI Video Decoder
- * Copyright (c) 2007-2009 Peter Ross <pross at 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * Electronic Arts TQI Video Decoder
- * @author Peter Ross <pross at xvid.org>
- * @see http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TQI
- */
-
-#include "avcodec.h"
-#include "blockdsp.h"
-#include "bswapdsp.h"
-#include "get_bits.h"
-#include "aandcttab.h"
-#include "eaidct.h"
-#include "idctdsp.h"
-#include "internal.h"
-#include "mpeg12.h"
-#include "mpegvideo.h"
-
-typedef struct TqiContext {
- MpegEncContext s;
- BswapDSPContext bsdsp;
- void *bitstream_buf;
- unsigned int bitstream_buf_size;
- DECLARE_ALIGNED(16, int16_t, block)[6][64];
-} TqiContext;
-
-static av_cold int tqi_decode_init(AVCodecContext *avctx)
-{
- TqiContext *t = avctx->priv_data;
- MpegEncContext *s = &t->s;
- s->avctx = avctx;
- ff_blockdsp_init(&s->bdsp, avctx);
- ff_bswapdsp_init(&t->bsdsp);
- ff_idctdsp_init(&s->idsp, avctx);
- ff_init_scantable_permutation(s->idsp.idct_permutation, FF_IDCT_PERM_NONE);
- ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
- s->qscale = 1;
- avctx->framerate = (AVRational){ 15, 1 };
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- ff_mpeg12_init_vlcs();
- return 0;
-}
-
-static int tqi_decode_mb(MpegEncContext *s, int16_t (*block)[64])
-{
- int n;
- s->bdsp.clear_blocks(block[0]);
- for (n=0; n<6; n++)
- if (ff_mpeg1_decode_block_intra(s, block[n], n) < 0)
- return -1;
-
- return 0;
-}
-
-static inline void tqi_idct_put(TqiContext *t, AVFrame *frame, int16_t (*block)[64])
-{
- MpegEncContext *s = &t->s;
- int linesize = frame->linesize[0];
- uint8_t *dest_y = frame->data[0] + (s->mb_y * 16* linesize ) + s->mb_x * 16;
- uint8_t *dest_cb = frame->data[1] + (s->mb_y * 8 * frame->linesize[1]) + s->mb_x * 8;
- uint8_t *dest_cr = frame->data[2] + (s->mb_y * 8 * frame->linesize[2]) + s->mb_x * 8;
-
- ff_ea_idct_put_c(dest_y , linesize, block[0]);
- ff_ea_idct_put_c(dest_y + 8, linesize, block[1]);
- ff_ea_idct_put_c(dest_y + 8*linesize , linesize, block[2]);
- ff_ea_idct_put_c(dest_y + 8*linesize + 8, linesize, block[3]);
- if(!(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
- ff_ea_idct_put_c(dest_cb, frame->linesize[1], block[4]);
- ff_ea_idct_put_c(dest_cr, frame->linesize[2], block[5]);
- }
-}
-
-static void tqi_calculate_qtable(MpegEncContext *s, int quant)
-{
- const int qscale = (215 - 2*quant)*5;
- int i;
- s->intra_matrix[0] = (ff_inv_aanscales[0]*ff_mpeg1_default_intra_matrix[0])>>11;
- for(i=1; i<64; i++)
- s->intra_matrix[i] = (ff_inv_aanscales[i]*ff_mpeg1_default_intra_matrix[i]*qscale + 32)>>14;
-}
-
-static int tqi_decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- const uint8_t *buf_end = buf+buf_size;
- TqiContext *t = avctx->priv_data;
- MpegEncContext *s = &t->s;
- AVFrame *frame = data;
- int ret;
-
- s->width = AV_RL16(&buf[0]);
- s->height = AV_RL16(&buf[2]);
- tqi_calculate_qtable(s, buf[4]);
- buf += 8;
-
- ret = ff_set_dimensions(s->avctx, s->width, s->height);
- if (ret < 0)
- return ret;
-
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
-
- av_fast_padded_malloc(&t->bitstream_buf, &t->bitstream_buf_size,
- buf_end - buf);
- if (!t->bitstream_buf)
- return AVERROR(ENOMEM);
- t->bsdsp.bswap_buf(t->bitstream_buf, (const uint32_t *) buf,
- (buf_end - buf) / 4);
- init_get_bits(&s->gb, t->bitstream_buf, 8*(buf_end-buf));
-
- s->last_dc[0] = s->last_dc[1] = s->last_dc[2] = 0;
- for (s->mb_y=0; s->mb_y<(avctx->height+15)/16; s->mb_y++)
- for (s->mb_x=0; s->mb_x<(avctx->width+15)/16; s->mb_x++)
- {
- if (tqi_decode_mb(s, t->block) < 0)
- goto end;
- tqi_idct_put(t, frame, t->block);
- }
- end:
-
- *got_frame = 1;
- return buf_size;
-}
-
-static av_cold int tqi_decode_end(AVCodecContext *avctx)
-{
- TqiContext *t = avctx->priv_data;
- av_freep(&t->bitstream_buf);
- return 0;
-}
-
-AVCodec ff_eatqi_decoder = {
- .name = "eatqi",
- .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TQI Video"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_TQI,
- .priv_data_size = sizeof(TqiContext),
- .init = tqi_decode_init,
- .close = tqi_decode_end,
- .decode = tqi_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/exr.c b/ffmpeg-2-8-11/libavcodec/exr.c
deleted file mode 100644
index 8feb9bd..0000000
--- a/ffmpeg-2-8-11/libavcodec/exr.c
+++ /dev/null
@@ -1,1453 +0,0 @@
-/*
- * OpenEXR (.exr) image decoder
- * Copyright (c) 2009 Jimmy Christensen
- *
- * 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 decoder
- * @author Jimmy Christensen
- *
- * For more information on the OpenEXR format, visit:
- * http://openexr.com/
- *
- * exr_flt2uint() and exr_halflt2uint() is credited to Reimar Döffinger.
- * exr_half2float() is credited to Aaftab Munshi, Dan Ginsburg, Dave Shreiner.
- */
-
-#include <float.h>
-#include <zlib.h>
-
-#include "libavutil/imgutils.h"
-#include "libavutil/intfloat.h"
-#include "libavutil/opt.h"
-
-#include "avcodec.h"
-#include "bytestream.h"
-#include "get_bits.h"
-#include "internal.h"
-#include "mathops.h"
-#include "thread.h"
-
-enum ExrCompr {
- EXR_RAW,
- EXR_RLE,
- EXR_ZIP1,
- EXR_ZIP16,
- EXR_PIZ,
- EXR_PXR24,
- EXR_B44,
- EXR_B44A,
- EXR_UNKN,
-};
-
-enum ExrPixelType {
- EXR_UINT,
- EXR_HALF,
- EXR_FLOAT,
- EXR_UNKNOWN,
-};
-
-typedef struct EXRChannel {
- int xsub, ysub;
- enum ExrPixelType pixel_type;
-} EXRChannel;
-
-typedef struct EXRThreadData {
- uint8_t *uncompressed_data;
- int uncompressed_size;
-
- uint8_t *tmp;
- int tmp_size;
-
- uint8_t *bitmap;
- uint16_t *lut;
-} EXRThreadData;
-
-typedef struct EXRContext {
- AVClass *class;
- AVFrame *picture;
- AVCodecContext *avctx;
-
- enum ExrCompr compression;
- enum ExrPixelType pixel_type;
- int channel_offsets[4]; // 0 = red, 1 = green, 2 = blue and 3 = alpha
- const AVPixFmtDescriptor *desc;
-
- int w, h;
- uint32_t xmax, xmin;
- uint32_t ymax, ymin;
- uint32_t xdelta, ydelta;
- int ysize;
-
- uint64_t scan_line_size;
- int scan_lines_per_block;
-
- GetByteContext gb;
- const uint8_t *buf;
- int buf_size;
-
- EXRChannel *channels;
- int nb_channels;
-
- EXRThreadData *thread_data;
-
- const char *layer;
-
- float gamma;
- uint16_t gamma_table[65536];
-} 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;
-}
-
-
-/**
- * Convert from 32-bit float as uint32_t to uint16_t.
- *
- * @param v 32-bit float
- *
- * @return normalized 16-bit unsigned int
- */
-static inline uint16_t exr_flt2uint(uint32_t v)
-{
- unsigned int exp = v >> 23;
- // "HACK": negative values result in exp< 0, so clipping them to 0
- // is also handled by this condition, avoids explicit check for sign bit.
- if (exp <= 127 + 7 - 24) // we would shift out all bits anyway
- return 0;
- if (exp >= 127)
- return 0xffff;
- v &= 0x007fffff;
- return (v + (1 << 23)) >> (127 + 7 - exp);
-}
-
-/**
- * Convert from 16-bit float as uint16_t to uint16_t.
- *
- * @param v 16-bit float
- *
- * @return normalized 16-bit unsigned int
- */
-static inline uint16_t exr_halflt2uint(uint16_t v)
-{
- unsigned exp = 14 - (v >> 10);
- if (exp >= 14) {
- if (exp == 14)
- return (v >> 9) & 1;
- else
- return (v & 0x8000) ? 0 : 0xffff;
- }
- v <<= 6;
- return (v + (1 << 16)) >> (exp + 1);
-}
-
-static void predictor(uint8_t *src, int size)
-{
- uint8_t *t = src + 1;
- uint8_t *stop = src + size;
-
- while (t < stop) {
- int d = (int) t[-1] + (int) t[0] - 128;
- t[0] = d;
- ++t;
- }
-}
-
-static void reorder_pixels(uint8_t *src, uint8_t *dst, int size)
-{
- const int8_t *t1 = src;
- const int8_t *t2 = src + (size + 1) / 2;
- int8_t *s = dst;
- int8_t *stop = s + size;
-
- while (1) {
- if (s < stop)
- *(s++) = *(t1++);
- else
- break;
-
- if (s < stop)
- *(s++) = *(t2++);
- else
- break;
- }
-}
-
-static int zip_uncompress(const uint8_t *src, int compressed_size,
- int uncompressed_size, EXRThreadData *td)
-{
- unsigned long dest_len = uncompressed_size;
-
- if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK ||
- dest_len != uncompressed_size)
- return AVERROR_INVALIDDATA;
-
- predictor(td->tmp, uncompressed_size);
- reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size);
-
- return 0;
-}
-
-static int rle_uncompress(const uint8_t *src, int compressed_size,
- int uncompressed_size, EXRThreadData *td)
-{
- uint8_t *d = td->tmp;
- const int8_t *s = src;
- int ssize = compressed_size;
- int dsize = uncompressed_size;
- uint8_t *dend = d + dsize;
- int count;
-
- while (ssize > 0) {
- count = *s++;
-
- if (count < 0) {
- count = -count;
-
- if ((dsize -= count) < 0 ||
- (ssize -= count + 1) < 0)
- return AVERROR_INVALIDDATA;
-
- while (count--)
- *d++ = *s++;
- } else {
- count++;
-
- if ((dsize -= count) < 0 ||
- (ssize -= 2) < 0)
- return AVERROR_INVALIDDATA;
-
- while (count--)
- *d++ = *s;
-
- s++;
- }
- }
-
- if (dend != d)
- return AVERROR_INVALIDDATA;
-
- predictor(td->tmp, uncompressed_size);
- reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size);
-
- return 0;
-}
-
-#define USHORT_RANGE (1 << 16)
-#define BITMAP_SIZE (1 << 13)
-
-static uint16_t reverse_lut(const uint8_t *bitmap, uint16_t *lut)
-{
- int i, k = 0;
-
- for (i = 0; i < USHORT_RANGE; i++)
- if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7))))
- lut[k++] = i;
-
- i = k - 1;
-
- memset(lut + k, 0, (USHORT_RANGE - k) * 2);
-
- return i;
-}
-
-static void apply_lut(const uint16_t *lut, uint16_t *dst, int dsize)
-{
- int i;
-
- for (i = 0; i < dsize; ++i)
- dst[i] = lut[dst[i]];
-}
-
-#define HUF_ENCBITS 16 // literal (value) bit length
-#define HUF_DECBITS 14 // decoding bit size (>= 8)
-
-#define HUF_ENCSIZE ((1 << HUF_ENCBITS) + 1) // encoding table size
-#define HUF_DECSIZE (1 << HUF_DECBITS) // decoding table size
-#define HUF_DECMASK (HUF_DECSIZE - 1)
-
-typedef struct HufDec {
- int len;
- int lit;
- int *p;
-} HufDec;
-
-static void huf_canonical_code_table(uint64_t *hcode)
-{
- uint64_t c, n[59] = { 0 };
- int i;
-
- for (i = 0; i < HUF_ENCSIZE; ++i)
- n[hcode[i]] += 1;
-
- c = 0;
- for (i = 58; i > 0; --i) {
- uint64_t nc = ((c + n[i]) >> 1);
- n[i] = c;
- c = nc;
- }
-
- for (i = 0; i < HUF_ENCSIZE; ++i) {
- int l = hcode[i];
-
- if (l > 0)
- hcode[i] = l | (n[l]++ << 6);
- }
-}
-
-#define SHORT_ZEROCODE_RUN 59
-#define LONG_ZEROCODE_RUN 63
-#define SHORTEST_LONG_RUN (2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN)
-#define LONGEST_LONG_RUN (255 + SHORTEST_LONG_RUN)
-
-static int huf_unpack_enc_table(GetByteContext *gb,
- int32_t im, int32_t iM, uint64_t *hcode)
-{
- GetBitContext gbit;
- int ret = init_get_bits8(&gbit, gb->buffer, bytestream2_get_bytes_left(gb));
- if (ret < 0)
- return ret;
-
- for (; im <= iM; im++) {
- uint64_t l = hcode[im] = get_bits(&gbit, 6);
-
- if (l == LONG_ZEROCODE_RUN) {
- int zerun = get_bits(&gbit, 8) + SHORTEST_LONG_RUN;
-
- if (im + zerun > iM + 1)
- return AVERROR_INVALIDDATA;
-
- while (zerun--)
- hcode[im++] = 0;
-
- im--;
- } else if (l >= SHORT_ZEROCODE_RUN) {
- int zerun = l - SHORT_ZEROCODE_RUN + 2;
-
- if (im + zerun > iM + 1)
- return AVERROR_INVALIDDATA;
-
- while (zerun--)
- hcode[im++] = 0;
-
- im--;
- }
- }
-
- bytestream2_skip(gb, (get_bits_count(&gbit) + 7) / 8);
- huf_canonical_code_table(hcode);
-
- return 0;
-}
-
-static int huf_build_dec_table(const uint64_t *hcode, int im,
- int iM, HufDec *hdecod)
-{
- for (; im <= iM; im++) {
- uint64_t c = hcode[im] >> 6;
- int i, l = hcode[im] & 63;
-
- if (c >> l)
- return AVERROR_INVALIDDATA;
-
- if (l > HUF_DECBITS) {
- HufDec *pl = hdecod + (c >> (l - HUF_DECBITS));
- if (pl->len)
- return AVERROR_INVALIDDATA;
-
- pl->lit++;
-
- pl->p = av_realloc(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, 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;
- get_code(pl.lit, rlc, c, lc, gb, out, oe, outb);
- } else {
- return AVERROR_INVALIDDATA;
- }
- }
-
- if (out - outb != no)
- return AVERROR_INVALIDDATA;
- return 0;
-}
-
-static int huf_uncompress(GetByteContext *gb,
- uint16_t *dst, int dst_size)
-{
- int32_t src_size, im, iM;
- uint32_t nBits;
- uint64_t *freq;
- HufDec *hdec;
- int ret, i;
-
- src_size = bytestream2_get_le32(gb);
- im = bytestream2_get_le32(gb);
- iM = bytestream2_get_le32(gb);
- bytestream2_skip(gb, 4);
- nBits = bytestream2_get_le32(gb);
- if (im < 0 || im >= HUF_ENCSIZE ||
- iM < 0 || iM >= HUF_ENCSIZE ||
- src_size < 0)
- return AVERROR_INVALIDDATA;
-
- bytestream2_skip(gb, 4);
-
- freq = av_mallocz_array(HUF_ENCSIZE, sizeof(*freq));
- hdec = av_mallocz_array(HUF_DECSIZE, sizeof(*hdec));
- if (!freq || !hdec) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
-
- if ((ret = huf_unpack_enc_table(gb, im, iM, freq)) < 0)
- goto fail;
-
- if (nBits > 8 * bytestream2_get_bytes_left(gb)) {
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
-
- if ((ret = huf_build_dec_table(freq, im, iM, hdec)) < 0)
- goto fail;
- ret = huf_decode(freq, hdec, gb, nBits, iM, dst_size, dst);
-
-fail:
- for (i = 0; i < HUF_DECSIZE; i++)
- if (hdec)
- av_freep(&hdec[i].p);
-
- av_free(freq);
- av_free(hdec);
-
- return ret;
-}
-
-static inline void wdec14(uint16_t l, uint16_t h, uint16_t *a, uint16_t *b)
-{
- int16_t ls = l;
- int16_t hs = h;
- int hi = hs;
- int ai = ls + (hi & 1) + (hi >> 1);
- int16_t as = ai;
- int16_t bs = ai - hi;
-
- *a = as;
- *b = bs;
-}
-
-#define NBITS 16
-#define A_OFFSET (1 << (NBITS - 1))
-#define MOD_MASK ((1 << NBITS) - 1)
-
-static inline void wdec16(uint16_t l, uint16_t h, uint16_t *a, uint16_t *b)
-{
- int m = l;
- int d = h;
- int bb = (m - (d >> 1)) & MOD_MASK;
- int aa = (d + bb - A_OFFSET) & MOD_MASK;
- *b = bb;
- *a = aa;
-}
-
-static void wav_decode(uint16_t *in, int nx, int ox,
- int ny, int oy, uint16_t mx)
-{
- int w14 = (mx < (1 << 14));
- int n = (nx > ny) ? ny : nx;
- int p = 1;
- int p2;
-
- while (p <= n)
- p <<= 1;
-
- p >>= 1;
- p2 = p;
- p >>= 1;
-
- while (p >= 1) {
- uint16_t *py = in;
- uint16_t *ey = in + oy * (ny - p2);
- uint16_t i00, i01, i10, i11;
- int oy1 = oy * p;
- int oy2 = oy * p2;
- int ox1 = ox * p;
- int ox2 = ox * p2;
-
- for (; py <= ey; py += oy2) {
- uint16_t *px = py;
- uint16_t *ex = py + ox * (nx - p2);
-
- for (; px <= ex; px += ox2) {
- uint16_t *p01 = px + ox1;
- uint16_t *p10 = px + oy1;
- uint16_t *p11 = p10 + ox1;
-
- if (w14) {
- wdec14(*px, *p10, &i00, &i10);
- wdec14(*p01, *p11, &i01, &i11);
- wdec14(i00, i01, px, p01);
- wdec14(i10, i11, p10, p11);
- } else {
- wdec16(*px, *p10, &i00, &i10);
- wdec16(*p01, *p11, &i01, &i11);
- wdec16(i00, i01, px, p01);
- wdec16(i10, i11, p10, p11);
- }
- }
-
- if (nx & p) {
- uint16_t *p10 = px + oy1;
-
- if (w14)
- wdec14(*px, *p10, &i00, p10);
- else
- wdec16(*px, *p10, &i00, p10);
-
- *px = i00;
- }
- }
-
- if (ny & p) {
- uint16_t *px = py;
- uint16_t *ex = py + ox * (nx - p2);
-
- for (; px <= ex; px += ox2) {
- uint16_t *p01 = px + ox1;
-
- if (w14)
- wdec14(*px, *p01, &i00, p01);
- else
- wdec16(*px, *p01, &i00, p01);
-
- *px = i00;
- }
- }
-
- p2 = p;
- p >>= 1;
- }
-}
-
-static int piz_uncompress(EXRContext *s, const uint8_t *src, int ssize,
- int dsize, EXRThreadData *td)
-{
- GetByteContext gb;
- uint16_t maxval, min_non_zero, max_non_zero;
- uint16_t *ptr;
- uint16_t *tmp = (uint16_t *)td->tmp;
- uint8_t *out;
- int ret, i, j;
-
- if (!td->bitmap)
- td->bitmap = av_malloc(BITMAP_SIZE);
- if (!td->lut)
- td->lut = av_malloc(1 << 17);
- if (!td->bitmap || !td->lut) {
- av_freep(&td->bitmap);
- av_freep(&td->lut);
- return AVERROR(ENOMEM);
- }
-
- bytestream2_init(&gb, src, ssize);
- min_non_zero = bytestream2_get_le16(&gb);
- max_non_zero = bytestream2_get_le16(&gb);
-
- if (max_non_zero >= BITMAP_SIZE)
- return AVERROR_INVALIDDATA;
-
- memset(td->bitmap, 0, FFMIN(min_non_zero, BITMAP_SIZE));
- if (min_non_zero <= max_non_zero)
- bytestream2_get_buffer(&gb, td->bitmap + min_non_zero,
- max_non_zero - min_non_zero + 1);
- memset(td->bitmap + max_non_zero, 0, BITMAP_SIZE - max_non_zero);
-
- maxval = reverse_lut(td->bitmap, td->lut);
-
- ret = huf_uncompress(&gb, tmp, dsize / sizeof(uint16_t));
- if (ret)
- return ret;
-
- ptr = tmp;
- for (i = 0; i < s->nb_channels; i++) {
- EXRChannel *channel = &s->channels[i];
- int size = channel->pixel_type;
-
- for (j = 0; j < size; j++)
- wav_decode(ptr + j, s->xdelta, size, s->ysize,
- s->xdelta * size, maxval);
- ptr += s->xdelta * s->ysize * size;
- }
-
- apply_lut(td->lut, tmp, dsize / sizeof(uint16_t));
-
- out = td->uncompressed_data;
- for (i = 0; i < s->ysize; i++)
- for (j = 0; j < s->nb_channels; j++) {
- uint16_t *in = tmp + j * s->xdelta * s->ysize + i * s->xdelta;
- memcpy(out, in, s->xdelta * 2);
- out += s->xdelta * 2;
- }
-
- return 0;
-}
-
-static int pxr24_uncompress(EXRContext *s, const uint8_t *src,
- int compressed_size, int uncompressed_size,
- EXRThreadData *td)
-{
- unsigned long dest_len = uncompressed_size;
- const uint8_t *in = td->tmp;
- uint8_t *out;
- int c, i, j;
-
- if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK ||
- dest_len != uncompressed_size)
- return AVERROR_INVALIDDATA;
-
- out = td->uncompressed_data;
- for (i = 0; i < s->ysize; i++)
- for (c = 0; c < s->nb_channels; c++) {
- EXRChannel *channel = &s->channels[c];
- const uint8_t *ptr[4];
- uint32_t pixel = 0;
-
- switch (channel->pixel_type) {
- case EXR_FLOAT:
- ptr[0] = in;
- ptr[1] = ptr[0] + s->xdelta;
- ptr[2] = ptr[1] + s->xdelta;
- in = ptr[2] + s->xdelta;
-
- for (j = 0; j < s->xdelta; ++j) {
- uint32_t diff = (*(ptr[0]++) << 24) |
- (*(ptr[1]++) << 16) |
- (*(ptr[2]++) << 8);
- pixel += diff;
- bytestream_put_le32(&out, pixel);
- }
- break;
- case EXR_HALF:
- ptr[0] = in;
- ptr[1] = ptr[0] + s->xdelta;
- in = ptr[1] + s->xdelta;
- for (j = 0; j < s->xdelta; j++) {
- uint32_t diff = (*(ptr[0]++) << 8) | *(ptr[1]++);
-
- pixel += diff;
- bytestream_put_le16(&out, pixel);
- }
- break;
- default:
- return AVERROR_INVALIDDATA;
- }
- }
-
- return 0;
-}
-
-static int decode_block(AVCodecContext *avctx, void *tdata,
- int jobnr, int threadnr)
-{
- EXRContext *s = avctx->priv_data;
- AVFrame *const p = s->picture;
- EXRThreadData *td = &s->thread_data[threadnr];
- const uint8_t *channel_buffer[4] = { 0 };
- const uint8_t *buf = s->buf;
- uint64_t line_offset, uncompressed_size;
- uint32_t xdelta = s->xdelta;
- uint16_t *ptr_x;
- uint8_t *ptr;
- uint32_t data_size, line;
- const uint8_t *src;
- int axmax = (avctx->width - (s->xmax + 1)) * 2 * s->desc->nb_components;
- int bxmin = s->xmin * 2 * s->desc->nb_components;
- int i, x, buf_size = s->buf_size;
- float one_gamma = 1.0f / s->gamma;
- int ret;
-
- line_offset = AV_RL64(s->gb.buffer + jobnr * 8);
- // Check if the buffer has the required bytes needed from the offset
- if (line_offset > buf_size - 8)
- return AVERROR_INVALIDDATA;
-
- src = buf + line_offset + 8;
- line = AV_RL32(src - 8);
- if (line < s->ymin || line > s->ymax)
- return AVERROR_INVALIDDATA;
-
- data_size = AV_RL32(src - 4);
- if (data_size <= 0 || data_size > buf_size)
- return AVERROR_INVALIDDATA;
-
- s->ysize = FFMIN(s->scan_lines_per_block, s->ymax - line + 1);
- uncompressed_size = s->scan_line_size * s->ysize;
- if ((s->compression == EXR_RAW && (data_size != uncompressed_size ||
- line_offset > buf_size - uncompressed_size)) ||
- (s->compression != EXR_RAW && (data_size > uncompressed_size ||
- line_offset > buf_size - data_size))) {
- return AVERROR_INVALIDDATA;
- }
-
- if (data_size < uncompressed_size) {
- av_fast_padded_malloc(&td->uncompressed_data,
- &td->uncompressed_size, uncompressed_size);
- av_fast_padded_malloc(&td->tmp, &td->tmp_size, uncompressed_size);
- if (!td->uncompressed_data || !td->tmp)
- return AVERROR(ENOMEM);
-
- ret = AVERROR_INVALIDDATA;
- switch (s->compression) {
- case EXR_ZIP1:
- case EXR_ZIP16:
- ret = zip_uncompress(src, data_size, uncompressed_size, td);
- break;
- case EXR_PIZ:
- ret = piz_uncompress(s, src, data_size, uncompressed_size, td);
- break;
- case EXR_PXR24:
- ret = pxr24_uncompress(s, src, data_size, uncompressed_size, td);
- break;
- case EXR_RLE:
- ret = rle_uncompress(src, data_size, uncompressed_size, td);
- }
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "decode_block() failed.\n");
- return ret;
- }
- src = td->uncompressed_data;
- }
-
- channel_buffer[0] = src + xdelta * s->channel_offsets[0];
- channel_buffer[1] = src + xdelta * s->channel_offsets[1];
- channel_buffer[2] = src + xdelta * s->channel_offsets[2];
- if (s->channel_offsets[3] >= 0)
- channel_buffer[3] = src + xdelta * s->channel_offsets[3];
-
- ptr = p->data[0] + line * p->linesize[0];
- for (i = 0;
- i < s->scan_lines_per_block && line + i <= s->ymax;
- i++, ptr += p->linesize[0]) {
- const uint8_t *r, *g, *b, *a;
-
- r = channel_buffer[0];
- g = channel_buffer[1];
- b = channel_buffer[2];
- if (channel_buffer[3])
- a = channel_buffer[3];
-
- ptr_x = (uint16_t *) ptr;
-
- // Zero out the start if xmin is not 0
- memset(ptr_x, 0, bxmin);
- ptr_x += s->xmin * s->desc->nb_components;
- if (s->pixel_type == EXR_FLOAT) {
- // 32-bit
- for (x = 0; x < xdelta; x++) {
- union av_intfloat32 t;
- t.i = bytestream_get_le32(&r);
- if (t.f > 0.0f) /* avoid negative values */
- t.f = powf(t.f, one_gamma);
- *ptr_x++ = exr_flt2uint(t.i);
-
- t.i = bytestream_get_le32(&g);
- if (t.f > 0.0f)
- t.f = powf(t.f, one_gamma);
- *ptr_x++ = exr_flt2uint(t.i);
-
- t.i = bytestream_get_le32(&b);
- if (t.f > 0.0f)
- t.f = powf(t.f, one_gamma);
- *ptr_x++ = exr_flt2uint(t.i);
- if (channel_buffer[3])
- *ptr_x++ = exr_flt2uint(bytestream_get_le32(&a));
- }
- } else {
- // 16-bit
- for (x = 0; x < xdelta; x++) {
- *ptr_x++ = s->gamma_table[bytestream_get_le16(&r)];
- *ptr_x++ = s->gamma_table[bytestream_get_le16(&g)];
- *ptr_x++ = s->gamma_table[bytestream_get_le16(&b)];
- if (channel_buffer[3])
- *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&a));
- }
- }
-
- // Zero out the end if xmax+1 is not w
- memset(ptr_x, 0, axmax);
-
- channel_buffer[0] += s->scan_line_size;
- channel_buffer[1] += s->scan_line_size;
- channel_buffer[2] += s->scan_line_size;
- if (channel_buffer[3])
- channel_buffer[3] += s->scan_line_size;
- }
-
- return 0;
-}
-
-/**
- * Check if the variable name corresponds to its data type.
- *
- * @param s the EXRContext
- * @param value_name name of the variable to check
- * @param value_type type of the variable to check
- * @param minimum_length minimum length of the variable data
- *
- * @return bytes to read containing variable data
- * -1 if variable is not found
- * 0 if buffer ended prematurely
- */
-static int check_header_variable(EXRContext *s,
- const char *value_name,
- const char *value_type,
- unsigned int minimum_length)
-{
- int var_size = -1;
-
- if (bytestream2_get_bytes_left(&s->gb) >= minimum_length &&
- !strcmp(s->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);
- // don't go read past boundaries
- if (var_size > bytestream2_get_bytes_left(&s->gb))
- var_size = 0;
- } else {
- // value_type not found, reset the buffer
- s->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);
- }
- }
-
- return var_size;
-}
-
-static int decode_header(EXRContext *s)
-{
- int current_channel_offset = 0;
- int magic_number, version, flags, i;
-
- s->xmin = ~0;
- s->xmax = ~0;
- s->ymin = ~0;
- s->ymax = ~0;
- s->xdelta = ~0;
- s->ydelta = ~0;
- s->channel_offsets[0] = -1;
- s->channel_offsets[1] = -1;
- s->channel_offsets[2] = -1;
- s->channel_offsets[3] = -1;
- s->pixel_type = EXR_UNKNOWN;
- s->compression = EXR_UNKN;
- s->nb_channels = 0;
- s->w = 0;
- s->h = 0;
-
- if (bytestream2_get_bytes_left(&s->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);
- if (magic_number != 20000630) {
- /* As per documentation of OpenEXR, it is supposed to be
- * int 20000630 little-endian */
- av_log(s->avctx, AV_LOG_ERROR, "Wrong magic number %d.\n", magic_number);
- return AVERROR_INVALIDDATA;
- }
-
- version = bytestream2_get_byte(&s->gb);
- if (version != 2) {
- avpriv_report_missing_feature(s->avctx, "Version %d", version);
- return AVERROR_PATCHWELCOME;
- }
-
- flags = bytestream2_get_le24(&s->gb);
- if (flags & 0x02) {
- avpriv_report_missing_feature(s->avctx, "Tile support");
- return AVERROR_PATCHWELCOME;
- }
-
- // Parse the header
- while (bytestream2_get_bytes_left(&s->gb) > 0 && *s->gb.buffer) {
- int var_size;
- if ((var_size = check_header_variable(s, "channels",
- "chlist", 38)) >= 0) {
- GetByteContext ch_gb;
- if (!var_size)
- return AVERROR_INVALIDDATA;
-
- bytestream2_init(&ch_gb, s->gb.buffer, var_size);
-
- while (bytestream2_get_bytes_left(&ch_gb) >= 19) {
- EXRChannel *channel;
- enum ExrPixelType current_pixel_type;
- int channel_index = -1;
- int xsub, ysub;
-
- if (strcmp(s->layer, "") != 0) {
- if (strncmp(ch_gb.buffer, s->layer, strlen(s->layer)) == 0) {
- ch_gb.buffer += strlen(s->layer);
- if (*ch_gb.buffer == '.')
- ch_gb.buffer++; /* skip dot if not given */
- av_log(s->avctx, AV_LOG_INFO,
- "Layer %s.%s matched.\n", s->layer, ch_gb.buffer);
- }
- }
-
- if (!strcmp(ch_gb.buffer, "R") ||
- !strcmp(ch_gb.buffer, "X") ||
- !strcmp(ch_gb.buffer, "U"))
- channel_index = 0;
- else if (!strcmp(ch_gb.buffer, "G") ||
- !strcmp(ch_gb.buffer, "Y") ||
- !strcmp(ch_gb.buffer, "V"))
- channel_index = 1;
- else if (!strcmp(ch_gb.buffer, "B") ||
- !strcmp(ch_gb.buffer, "Z") ||
- !strcmp(ch_gb.buffer, "W"))
- channel_index = 2;
- else if (!strcmp(ch_gb.buffer, "A"))
- channel_index = 3;
- else
- av_log(s->avctx, AV_LOG_WARNING,
- "Unsupported channel %.256s.\n", ch_gb.buffer);
-
- /* skip until you get a 0 */
- while (bytestream2_get_bytes_left(&ch_gb) > 0 &&
- bytestream2_get_byte(&ch_gb))
- continue;
-
- if (bytestream2_get_bytes_left(&ch_gb) < 4) {
- av_log(s->avctx, AV_LOG_ERROR, "Incomplete header.\n");
- return AVERROR_INVALIDDATA;
- }
-
- current_pixel_type = bytestream2_get_le32(&ch_gb);
- if (current_pixel_type >= EXR_UNKNOWN) {
- avpriv_report_missing_feature(s->avctx,
- "Pixel type %d.\n",
- current_pixel_type);
- return AVERROR_PATCHWELCOME;
- }
-
- bytestream2_skip(&ch_gb, 4);
- xsub = bytestream2_get_le32(&ch_gb);
- ysub = bytestream2_get_le32(&ch_gb);
- if (xsub != 1 || ysub != 1) {
- avpriv_report_missing_feature(s->avctx,
- "Subsampling %dx%d",
- xsub, ysub);
- return AVERROR_PATCHWELCOME;
- }
-
- if (channel_index >= 0) {
- if (s->pixel_type != EXR_UNKNOWN &&
- s->pixel_type != current_pixel_type) {
- av_log(s->avctx, AV_LOG_ERROR,
- "RGB channels not of the same depth.\n");
- return AVERROR_INVALIDDATA;
- }
- s->pixel_type = current_pixel_type;
- s->channel_offsets[channel_index] = current_channel_offset;
- }
-
- s->channels = av_realloc(s->channels,
- ++s->nb_channels * sizeof(EXRChannel));
- if (!s->channels)
- return AVERROR(ENOMEM);
- channel = &s->channels[s->nb_channels - 1];
- channel->pixel_type = current_pixel_type;
- channel->xsub = xsub;
- channel->ysub = ysub;
-
- current_channel_offset += 1 << current_pixel_type;
- }
-
- /* Check if all channels are set with an offset or if the channels
- * are causing an overflow */
- if (FFMIN3(s->channel_offsets[0],
- s->channel_offsets[1],
- s->channel_offsets[2]) < 0) {
- if (s->channel_offsets[0] < 0)
- av_log(s->avctx, AV_LOG_ERROR, "Missing red channel.\n");
- if (s->channel_offsets[1] < 0)
- av_log(s->avctx, AV_LOG_ERROR, "Missing green channel.\n");
- if (s->channel_offsets[2] < 0)
- av_log(s->avctx, AV_LOG_ERROR, "Missing blue channel.\n");
- return AVERROR_INVALIDDATA;
- }
-
- // skip one last byte and update main gb
- s->gb.buffer = ch_gb.buffer + 1;
- continue;
- } else if ((var_size = check_header_variable(s, "dataWindow", "box2i",
- 31)) >= 0) {
- if (!var_size)
- return AVERROR_INVALIDDATA;
-
- s->xmin = bytestream2_get_le32(&s->gb);
- s->ymin = bytestream2_get_le32(&s->gb);
- s->xmax = bytestream2_get_le32(&s->gb);
- s->ymax = bytestream2_get_le32(&s->gb);
- s->xdelta = (s->xmax - s->xmin) + 1;
- s->ydelta = (s->ymax - s->ymin) + 1;
-
- continue;
- } else if ((var_size = check_header_variable(s, "displayWindow",
- "box2i", 34)) >= 0) {
- if (!var_size)
- return AVERROR_INVALIDDATA;
-
- bytestream2_skip(&s->gb, 8);
- s->w = bytestream2_get_le32(&s->gb) + 1;
- s->h = bytestream2_get_le32(&s->gb) + 1;
-
- continue;
- } else if ((var_size = check_header_variable(s, "lineOrder",
- "lineOrder", 25)) >= 0) {
- int line_order;
- if (!var_size)
- return AVERROR_INVALIDDATA;
-
- line_order = bytestream2_get_byte(&s->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");
- return AVERROR_INVALIDDATA;
- }
-
- continue;
- } else if ((var_size = check_header_variable(s, "pixelAspectRatio",
- "float", 31)) >= 0) {
- if (!var_size)
- return AVERROR_INVALIDDATA;
-
- ff_set_sar(s->avctx,
- av_d2q(av_int2float(bytestream2_get_le32(&s->gb)), 255));
-
- continue;
- } else if ((var_size = check_header_variable(s, "compression",
- "compression", 29)) >= 0) {
- if (!var_size)
- return AVERROR_INVALIDDATA;
-
- if (s->compression == EXR_UNKN)
- s->compression = bytestream2_get_byte(&s->gb);
- else
- av_log(s->avctx, AV_LOG_WARNING,
- "Found more than one compression attribute.\n");
-
- continue;
- }
-
- // Check if there are enough bytes for a header
- if (bytestream2_get_bytes_left(&s->gb) <= 9) {
- av_log(s->avctx, AV_LOG_ERROR, "Incomplete header\n");
- return AVERROR_INVALIDDATA;
- }
-
- // Process unknown variables
- for (i = 0; i < 2; i++) // value_name and value_type
- while (bytestream2_get_byte(&s->gb) != 0);
-
- // Skip variable length
- bytestream2_skip(&s->gb, bytestream2_get_le32(&s->gb));
- }
-
- if (s->compression == EXR_UNKN) {
- av_log(s->avctx, AV_LOG_ERROR, "Missing compression attribute.\n");
- return AVERROR_INVALIDDATA;
- }
- s->scan_line_size = s->xdelta * current_channel_offset;
-
- if (bytestream2_get_bytes_left(&s->gb) <= 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Incomplete frame.\n");
- return AVERROR_INVALIDDATA;
- }
-
- // aaand we are done
- bytestream2_skip(&s->gb, 1);
- return 0;
-}
-
-static int decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame, AVPacket *avpkt)
-{
- EXRContext *s = avctx->priv_data;
- ThreadFrame frame = { .f = data };
- AVFrame *picture = data;
- uint8_t *ptr;
-
- int y, ret;
- int out_line_size;
- int scan_line_blocks;
-
- bytestream2_init(&s->gb, avpkt->data, avpkt->size);
-
- if ((ret = decode_header(s)) < 0)
- return ret;
-
- switch (s->pixel_type) {
- case EXR_FLOAT:
- case EXR_HALF:
- if (s->channel_offsets[3] >= 0)
- avctx->pix_fmt = AV_PIX_FMT_RGBA64;
- else
- avctx->pix_fmt = AV_PIX_FMT_RGB48;
- break;
- case EXR_UINT:
- avpriv_request_sample(avctx, "32-bit unsigned int");
- return AVERROR_PATCHWELCOME;
- default:
- av_log(avctx, AV_LOG_ERROR, "Missing channel list.\n");
- return AVERROR_INVALIDDATA;
- }
-
- switch (s->compression) {
- case EXR_RAW:
- case EXR_RLE:
- case EXR_ZIP1:
- s->scan_lines_per_block = 1;
- break;
- case EXR_PXR24:
- case EXR_ZIP16:
- s->scan_lines_per_block = 16;
- break;
- case EXR_PIZ:
- s->scan_lines_per_block = 32;
- 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) {
- av_log(avctx, AV_LOG_ERROR, "Wrong or missing size information.\n");
- return AVERROR_INVALIDDATA;
- }
-
- if ((ret = ff_set_dimensions(avctx, s->w, s->h)) < 0)
- return ret;
-
- s->desc = av_pix_fmt_desc_get(avctx->pix_fmt);
- if (!s->desc)
- return AVERROR_INVALIDDATA;
- out_line_size = avctx->width * 2 * s->desc->nb_components;
- scan_line_blocks = (s->ydelta + s->scan_lines_per_block - 1) /
- s->scan_lines_per_block;
-
- if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
- return ret;
-
- if (bytestream2_get_bytes_left(&s->gb) < scan_line_blocks * 8)
- return AVERROR_INVALIDDATA;
-
- // save pointer we are going to use in decode_block
- s->buf = avpkt->data;
- s->buf_size = avpkt->size;
- ptr = picture->data[0];
-
- // Zero out the start if ymin is not 0
- for (y = 0; y < s->ymin; y++) {
- memset(ptr, 0, out_line_size);
- ptr += picture->linesize[0];
- }
-
- s->picture = picture;
- avctx->execute2(avctx, decode_block, s->thread_data, NULL, scan_line_blocks);
-
- // Zero out the end if ymax+1 is not h
- for (y = s->ymax + 1; y < avctx->height; y++) {
- memset(ptr, 0, out_line_size);
- ptr += picture->linesize[0];
- }
-
- picture->pict_type = AV_PICTURE_TYPE_I;
- *got_frame = 1;
-
- return avpkt->size;
-}
-
-static av_cold int decode_init(AVCodecContext *avctx)
-{
- EXRContext *s = avctx->priv_data;
- uint32_t i;
- union av_intfloat32 t;
- float one_gamma = 1.0f / s->gamma;
-
- s->avctx = avctx;
-
- if (one_gamma > 0.9999f && one_gamma < 1.0001f) {
- for (i = 0; i < 65536; ++i)
- s->gamma_table[i] = exr_halflt2uint(i);
- } else {
- for (i = 0; i < 65536; ++i) {
- t = exr_half2float(i);
- /* If negative value we reuse half value */
- if (t.f <= 0.0f) {
- s->gamma_table[i] = exr_halflt2uint(i);
- } else {
- t.f = powf(t.f, one_gamma);
- s->gamma_table[i] = exr_flt2uint(t.i);
- }
- }
- }
-
- // allocate thread data, used for non EXR_RAW compreesion types
- s->thread_data = av_mallocz_array(avctx->thread_count, sizeof(EXRThreadData));
- if (!s->thread_data)
- return AVERROR_INVALIDDATA;
-
- return 0;
-}
-
-static int decode_init_thread_copy(AVCodecContext *avctx)
-{ EXRContext *s = avctx->priv_data;
-
- // allocate thread data, used for non EXR_RAW compreesion types
- s->thread_data = av_mallocz_array(avctx->thread_count, sizeof(EXRThreadData));
- if (!s->thread_data)
- return AVERROR_INVALIDDATA;
-
- return 0;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx)
-{
- EXRContext *s = avctx->priv_data;
- int i;
- for (i = 0; i < avctx->thread_count; i++) {
- EXRThreadData *td = &s->thread_data[i];
- av_freep(&td->uncompressed_data);
- av_freep(&td->tmp);
- av_freep(&td->bitmap);
- av_freep(&td->lut);
- }
-
- av_freep(&s->thread_data);
- av_freep(&s->channels);
-
- return 0;
-}
-
-#define OFFSET(x) offsetof(EXRContext, x)
-#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
-static const AVOption options[] = {
- { "layer", "Set the decoding layer", OFFSET(layer),
- AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VD },
- { "gamma", "Set the float gamma value when decoding", OFFSET(gamma),
- AV_OPT_TYPE_FLOAT, { .dbl = 1.0f }, 0.001, FLT_MAX, VD },
- { NULL },
-};
-
-static const AVClass exr_class = {
- .class_name = "EXR",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-AVCodec ff_exr_decoder = {
- .name = "exr",
- .long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_EXR,
- .priv_data_size = sizeof(EXRContext),
- .init = decode_init,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
- .close = decode_end,
- .decode = decode_frame,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
- AV_CODEC_CAP_SLICE_THREADS,
- .priv_class = &exr_class,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/ffv1dec.c b/ffmpeg-2-8-11/libavcodec/ffv1dec.c
deleted file mode 100644
index 9c941fa..0000000
--- a/ffmpeg-2-8-11/libavcodec/ffv1dec.c
+++ /dev/null
@@ -1,1134 +0,0 @@
-/*
- * FFV1 decoder
- *
- * Copyright (c) 2003-2013 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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
- * FF Video Codec 1 (a lossless codec) decoder
- */
-
-#include "libavutil/avassert.h"
-#include "libavutil/crc.h"
-#include "libavutil/opt.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/timer.h"
-#include "avcodec.h"
-#include "internal.h"
-#include "get_bits.h"
-#include "rangecoder.h"
-#include "golomb.h"
-#include "mathops.h"
-#include "ffv1.h"
-
-static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state,
- int is_signed)
-{
- if (get_rac(c, state + 0))
- return 0;
- else {
- int i, e, a;
- e = 0;
- while (get_rac(c, state + 1 + FFMIN(e, 9))) { // 1..10
- e++;
- if (e > 31)
- return AVERROR_INVALIDDATA;
- }
-
- a = 1;
- for (i = e - 1; i >= 0; i--)
- a += a + get_rac(c, state + 22 + FFMIN(i, 9)); // 22..31
-
- e = -(is_signed && get_rac(c, state + 11 + FFMIN(e, 10))); // 11..21
- return (a ^ e) - e;
- }
-}
-
-static av_noinline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed)
-{
- return get_symbol_inline(c, state, is_signed);
-}
-
-static inline int get_vlc_symbol(GetBitContext *gb, VlcState *const state,
- int bits)
-{
- int k, i, v, ret;
-
- i = state->count;
- k = 0;
- while (i < state->error_sum) { // FIXME: optimize
- k++;
- i += i;
- }
-
- v = get_sr_golomb(gb, k, 12, bits);
- ff_dlog(NULL, "v:%d bias:%d error:%d drift:%d count:%d k:%d",
- v, state->bias, state->error_sum, state->drift, state->count, k);
-
-#if 0 // JPEG LS
- if (k == 0 && 2 * state->drift <= -state->count)
- v ^= (-1);
-#else
- v ^= ((2 * state->drift + state->count) >> 31);
-#endif
-
- ret = fold(v + state->bias, bits);
-
- update_vlc_state(state, v);
-
- return ret;
-}
-
-static av_always_inline void decode_line(FFV1Context *s, int w,
- int16_t *sample[2],
- int plane_index, int bits)
-{
- PlaneContext *const p = &s->plane[plane_index];
- RangeCoder *const c = &s->c;
- int x;
- int run_count = 0;
- int run_mode = 0;
- int run_index = s->run_index;
-
- if (s->slice_coding_mode == 1) {
- int i;
- for (x = 0; x < w; x++) {
- int v = 0;
- for (i=0; i<bits; i++) {
- uint8_t state = 128;
- v += v + get_rac(c, &state);
- }
- sample[1][x] = v;
- }
- return;
- }
-
- for (x = 0; x < w; x++) {
- int diff, context, sign;
-
- context = get_context(p, sample[1] + x, sample[0] + x, sample[1] + x);
- if (context < 0) {
- context = -context;
- sign = 1;
- } else
- sign = 0;
-
- av_assert2(context < p->context_count);
-
- if (s->ac) {
- diff = get_symbol_inline(c, p->state[context], 1);
- } else {
- if (context == 0 && run_mode == 0)
- run_mode = 1;
-
- if (run_mode) {
- if (run_count == 0 && run_mode == 1) {
- if (get_bits1(&s->gb)) {
- run_count = 1 << ff_log2_run[run_index];
- if (x + run_count <= w)
- run_index++;
- } else {
- if (ff_log2_run[run_index])
- run_count = get_bits(&s->gb, ff_log2_run[run_index]);
- else
- run_count = 0;
- if (run_index)
- run_index--;
- run_mode = 2;
- }
- }
- run_count--;
- if (run_count < 0) {
- run_mode = 0;
- run_count = 0;
- diff = get_vlc_symbol(&s->gb, &p->vlc_state[context],
- bits);
- if (diff >= 0)
- diff++;
- } else
- diff = 0;
- } else
- diff = get_vlc_symbol(&s->gb, &p->vlc_state[context], bits);
-
- ff_dlog(s->avctx, "count:%d index:%d, mode:%d, x:%d pos:%d\n",
- run_count, run_index, run_mode, x, get_bits_count(&s->gb));
- }
-
- if (sign)
- diff = -diff;
-
- sample[1][x] = av_mod_uintp2(predict(sample[1] + x, sample[0] + x) + diff, bits);
- }
- s->run_index = run_index;
-}
-
-static void decode_plane(FFV1Context *s, uint8_t *src,
- int w, int h, int stride, int plane_index)
-{
- int x, y;
- int16_t *sample[2];
- sample[0] = s->sample_buffer + 3;
- sample[1] = s->sample_buffer + w + 6 + 3;
-
- s->run_index = 0;
-
- memset(s->sample_buffer, 0, 2 * (w + 6) * sizeof(*s->sample_buffer));
-
- for (y = 0; y < h; y++) {
- int16_t *temp = sample[0]; // FIXME: try a normal buffer
-
- sample[0] = sample[1];
- sample[1] = temp;
-
- sample[1][-1] = sample[0][0];
- sample[0][w] = sample[0][w - 1];
-
-// { START_TIMER
- if (s->avctx->bits_per_raw_sample <= 8) {
- decode_line(s, w, sample, plane_index, 8);
- for (x = 0; x < w; x++)
- src[x + stride * y] = sample[1][x];
- } else {
- decode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample);
- if (s->packed_at_lsb) {
- for (x = 0; x < w; x++) {
- ((uint16_t*)(src + stride*y))[x] = sample[1][x];
- }
- } else {
- for (x = 0; x < w; x++) {
- ((uint16_t*)(src + stride*y))[x] = sample[1][x] << (16 - s->avctx->bits_per_raw_sample);
- }
- }
- }
-// STOP_TIMER("decode-line") }
- }
-}
-
-static void decode_rgb_frame(FFV1Context *s, uint8_t *src[3], int w, int h, int stride[3])
-{
- int x, y, p;
- int16_t *sample[4][2];
- int lbd = s->avctx->bits_per_raw_sample <= 8;
- int bits = s->avctx->bits_per_raw_sample > 0 ? s->avctx->bits_per_raw_sample : 8;
- int offset = 1 << bits;
-
- for (x = 0; x < 4; x++) {
- sample[x][0] = s->sample_buffer + x * 2 * (w + 6) + 3;
- sample[x][1] = s->sample_buffer + (x * 2 + 1) * (w + 6) + 3;
- }
-
- s->run_index = 0;
-
- memset(s->sample_buffer, 0, 8 * (w + 6) * sizeof(*s->sample_buffer));
-
- for (y = 0; y < h; y++) {
- for (p = 0; p < 3 + s->transparency; p++) {
- int16_t *temp = sample[p][0]; // FIXME: try a normal buffer
-
- sample[p][0] = sample[p][1];
- sample[p][1] = temp;
-
- sample[p][1][-1]= sample[p][0][0 ];
- sample[p][0][ w]= sample[p][0][w-1];
- if (lbd && s->slice_coding_mode == 0)
- decode_line(s, w, sample[p], (p + 1)/2, 9);
- else
- decode_line(s, w, sample[p], (p + 1)/2, bits + (s->slice_coding_mode != 1));
- }
- for (x = 0; x < w; x++) {
- int g = sample[0][1][x];
- int b = sample[1][1][x];
- int r = sample[2][1][x];
- int a = sample[3][1][x];
-
- if (s->slice_coding_mode != 1) {
- b -= offset;
- r -= offset;
- g -= (b * s->slice_rct_by_coef + r * s->slice_rct_ry_coef) >> 2;
- b += g;
- r += g;
- }
-
- if (lbd)
- *((uint32_t*)(src[0] + x*4 + stride[0]*y)) = b + (g<<8) + (r<<16) + (a<<24);
- else {
- *((uint16_t*)(src[0] + x*2 + stride[0]*y)) = b;
- *((uint16_t*)(src[1] + x*2 + stride[1]*y)) = g;
- *((uint16_t*)(src[2] + x*2 + stride[2]*y)) = r;
- }
- }
- }
-}
-
-static int decode_slice_header(FFV1Context *f, FFV1Context *fs)
-{
- RangeCoder *c = &fs->c;
- uint8_t state[CONTEXT_SIZE];
- unsigned ps, i, context_count;
- memset(state, 128, sizeof(state));
-
- av_assert0(f->version > 2);
-
- fs->slice_x = get_symbol(c, state, 0) * f->width ;
- fs->slice_y = get_symbol(c, state, 0) * f->height;
- fs->slice_width = (get_symbol(c, state, 0) + 1) * f->width + fs->slice_x;
- fs->slice_height = (get_symbol(c, state, 0) + 1) * f->height + fs->slice_y;
-
- fs->slice_x /= f->num_h_slices;
- fs->slice_y /= f->num_v_slices;
- fs->slice_width = fs->slice_width /f->num_h_slices - fs->slice_x;
- fs->slice_height = fs->slice_height/f->num_v_slices - fs->slice_y;
- if ((unsigned)fs->slice_width > f->width || (unsigned)fs->slice_height > f->height)
- return -1;
- if ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width > f->width
- || (unsigned)fs->slice_y + (uint64_t)fs->slice_height > f->height)
- return -1;
-
- for (i = 0; i < f->plane_count; i++) {
- PlaneContext * const p = &fs->plane[i];
- int idx = get_symbol(c, state, 0);
- if (idx >= (unsigned)f->quant_table_count) {
- av_log(f->avctx, AV_LOG_ERROR, "quant_table_index out of range\n");
- return -1;
- }
- p->quant_table_index = idx;
- memcpy(p->quant_table, f->quant_tables[idx], sizeof(p->quant_table));
- context_count = f->context_count[idx];
-
- if (p->context_count < context_count) {
- av_freep(&p->state);
- av_freep(&p->vlc_state);
- }
- p->context_count = context_count;
- }
-
- ps = get_symbol(c, state, 0);
- if (ps == 1) {
- f->cur->interlaced_frame = 1;
- f->cur->top_field_first = 1;
- } else if (ps == 2) {
- f->cur->interlaced_frame = 1;
- f->cur->top_field_first = 0;
- } else if (ps == 3) {
- f->cur->interlaced_frame = 0;
- }
- f->cur->sample_aspect_ratio.num = get_symbol(c, state, 0);
- f->cur->sample_aspect_ratio.den = get_symbol(c, state, 0);
-
- if (av_image_check_sar(f->width, f->height,
- f->cur->sample_aspect_ratio) < 0) {
- av_log(f->avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n",
- f->cur->sample_aspect_ratio.num,
- f->cur->sample_aspect_ratio.den);
- f->cur->sample_aspect_ratio = (AVRational){ 0, 1 };
- }
-
- if (fs->version > 3) {
- fs->slice_reset_contexts = get_rac(c, state);
- fs->slice_coding_mode = get_symbol(c, state, 0);
- if (fs->slice_coding_mode != 1) {
- fs->slice_rct_by_coef = get_symbol(c, state, 0);
- fs->slice_rct_ry_coef = get_symbol(c, state, 0);
- if ((uint64_t)fs->slice_rct_by_coef + (uint64_t)fs->slice_rct_ry_coef > 4) {
- av_log(f->avctx, AV_LOG_ERROR, "slice_rct_y_coef out of range\n");
- return AVERROR_INVALIDDATA;
- }
- }
- }
-
- return 0;
-}
-
-static int decode_slice(AVCodecContext *c, void *arg)
-{
- FFV1Context *fs = *(void **)arg;
- FFV1Context *f = fs->avctx->priv_data;
- int width, height, x, y, ret;
- const int ps = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step_minus1 + 1;
- AVFrame * const p = f->cur;
- int i, si;
-
- for( si=0; fs != f->slice_context[si]; si ++)
- ;
-
- if(f->fsrc && !p->key_frame)
- ff_thread_await_progress(&f->last_picture, si, 0);
-
- if(f->fsrc && !p->key_frame) {
- FFV1Context *fssrc = f->fsrc->slice_context[si];
- FFV1Context *fsdst = f->slice_context[si];
- av_assert1(fsdst->plane_count == fssrc->plane_count);
- av_assert1(fsdst == fs);
-
- if (!p->key_frame)
- fsdst->slice_damaged |= fssrc->slice_damaged;
-
- for (i = 0; i < f->plane_count; i++) {
- PlaneContext *psrc = &fssrc->plane[i];
- PlaneContext *pdst = &fsdst->plane[i];
-
- av_free(pdst->state);
- av_free(pdst->vlc_state);
- memcpy(pdst, psrc, sizeof(*pdst));
- pdst->state = NULL;
- pdst->vlc_state = NULL;
-
- if (fssrc->ac) {
- pdst->state = av_malloc_array(CONTEXT_SIZE, psrc->context_count);
- memcpy(pdst->state, psrc->state, CONTEXT_SIZE * psrc->context_count);
- } else {
- pdst->vlc_state = av_malloc_array(sizeof(*pdst->vlc_state), psrc->context_count);
- memcpy(pdst->vlc_state, psrc->vlc_state, sizeof(*pdst->vlc_state) * psrc->context_count);
- }
- }
- }
-
- fs->slice_rct_by_coef = 1;
- fs->slice_rct_ry_coef = 1;
-
- if (f->version > 2) {
- if (ff_ffv1_init_slice_state(f, fs) < 0)
- return AVERROR(ENOMEM);
- if (decode_slice_header(f, fs) < 0) {
- fs->slice_x = fs->slice_y = fs->slice_height = fs->slice_width = 0;
- fs->slice_damaged = 1;
- return AVERROR_INVALIDDATA;
- }
- }
- if ((ret = ff_ffv1_init_slice_state(f, fs)) < 0)
- return ret;
- if (f->cur->key_frame || fs->slice_reset_contexts)
- ff_ffv1_clear_slice_state(f, fs);
-
- width = fs->slice_width;
- height = fs->slice_height;
- x = fs->slice_x;
- y = fs->slice_y;
-
- if (!fs->ac) {
- if (f->version == 3 && f->micro_version > 1 || f->version > 3)
- get_rac(&fs->c, (uint8_t[]) { 129 });
- fs->ac_byte_count = f->version > 2 || (!x && !y) ? fs->c.bytestream - fs->c.bytestream_start - 1 : 0;
- init_get_bits(&fs->gb,
- fs->c.bytestream_start + fs->ac_byte_count,
- (fs->c.bytestream_end - fs->c.bytestream_start - fs->ac_byte_count) * 8);
- }
-
- av_assert1(width && height);
- if (f->colorspace == 0) {
- const int chroma_width = FF_CEIL_RSHIFT(width, f->chroma_h_shift);
- const int chroma_height = FF_CEIL_RSHIFT(height, f->chroma_v_shift);
- const int cx = x >> f->chroma_h_shift;
- const int cy = y >> f->chroma_v_shift;
- decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0);
-
- if (f->chroma_planes) {
- decode_plane(fs, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1);
- decode_plane(fs, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1);
- }
- if (fs->transparency)
- decode_plane(fs, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], (f->version >= 4 && !f->chroma_planes) ? 1 : 2);
- } else {
- uint8_t *planes[3] = { p->data[0] + ps * x + y * p->linesize[0],
- p->data[1] + ps * x + y * p->linesize[1],
- p->data[2] + ps * x + y * p->linesize[2] };
- decode_rgb_frame(fs, planes, width, height, p->linesize);
- }
- if (fs->ac && f->version > 2) {
- int v;
- get_rac(&fs->c, (uint8_t[]) { 129 });
- v = fs->c.bytestream_end - fs->c.bytestream - 2 - 5*f->ec;
- if (v) {
- av_log(f->avctx, AV_LOG_ERROR, "bytestream end mismatching by %d\n", v);
- fs->slice_damaged = 1;
- }
- }
-
- emms_c();
-
- ff_thread_report_progress(&f->picture, si, 0);
-
- return 0;
-}
-
-static int read_quant_table(RangeCoder *c, int16_t *quant_table, int scale)
-{
- int v;
- int i = 0;
- uint8_t state[CONTEXT_SIZE];
-
- memset(state, 128, sizeof(state));
-
- for (v = 0; i < 128; v++) {
- unsigned len = get_symbol(c, state, 0) + 1;
-
- if (len > 128 - i || !len)
- return AVERROR_INVALIDDATA;
-
- while (len--) {
- quant_table[i] = scale * v;
- i++;
- }
- }
-
- for (i = 1; i < 128; i++)
- quant_table[256 - i] = -quant_table[i];
- quant_table[128] = -quant_table[127];
-
- return 2 * v - 1;
-}
-
-static int read_quant_tables(RangeCoder *c,
- int16_t quant_table[MAX_CONTEXT_INPUTS][256])
-{
- int i;
- int context_count = 1;
-
- for (i = 0; i < 5; i++) {
- int ret = read_quant_table(c, quant_table[i], context_count);
- if (ret < 0)
- return ret;
- context_count *= ret;
- if (context_count > 32768U) {
- return AVERROR_INVALIDDATA;
- }
- }
- return (context_count + 1) / 2;
-}
-
-static int read_extra_header(FFV1Context *f)
-{
- RangeCoder *const c = &f->c;
- uint8_t state[CONTEXT_SIZE];
- int i, j, k, ret;
- uint8_t state2[32][CONTEXT_SIZE];
- unsigned crc = 0;
-
- memset(state2, 128, sizeof(state2));
- memset(state, 128, sizeof(state));
-
- ff_init_range_decoder(c, f->avctx->extradata, f->avctx->extradata_size);
- ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
-
- f->version = get_symbol(c, state, 0);
- if (f->version < 2) {
- av_log(f->avctx, AV_LOG_ERROR, "Invalid version in global header\n");
- return AVERROR_INVALIDDATA;
- }
- if (f->version > 2) {
- c->bytestream_end -= 4;
- f->micro_version = get_symbol(c, state, 0);
- if (f->micro_version < 0)
- return AVERROR_INVALIDDATA;
- }
- f->ac = f->avctx->coder_type = get_symbol(c, state, 0);
- if (f->ac > 1) {
- for (i = 1; i < 256; i++)
- f->state_transition[i] = get_symbol(c, state, 1) + c->one_state[i];
- }
-
- f->colorspace = get_symbol(c, state, 0); //YUV cs type
- f->avctx->bits_per_raw_sample = get_symbol(c, state, 0);
- f->chroma_planes = get_rac(c, state);
- f->chroma_h_shift = get_symbol(c, state, 0);
- f->chroma_v_shift = get_symbol(c, state, 0);
- f->transparency = get_rac(c, state);
- f->plane_count = 1 + (f->chroma_planes || f->version<4) + f->transparency;
- f->num_h_slices = 1 + get_symbol(c, state, 0);
- f->num_v_slices = 1 + get_symbol(c, state, 0);
-
- if (f->chroma_h_shift > 4U || f->chroma_v_shift > 4U) {
- av_log(f->avctx, AV_LOG_ERROR, "chroma shift parameters %d %d are invalid\n",
- f->chroma_h_shift, f->chroma_v_shift);
- return AVERROR_INVALIDDATA;
- }
-
- if (f->num_h_slices > (unsigned)f->width || !f->num_h_slices ||
- f->num_v_slices > (unsigned)f->height || !f->num_v_slices
- ) {
- av_log(f->avctx, AV_LOG_ERROR, "slice count invalid\n");
- return AVERROR_INVALIDDATA;
- }
-
- f->quant_table_count = get_symbol(c, state, 0);
- if (f->quant_table_count > (unsigned)MAX_QUANT_TABLES || !f->quant_table_count) {
- av_log(f->avctx, AV_LOG_ERROR, "quant table count %d is invalid\n", f->quant_table_count);
- f->quant_table_count = 0;
- return AVERROR_INVALIDDATA;
- }
-
- for (i = 0; i < f->quant_table_count; i++) {
- f->context_count[i] = read_quant_tables(c, f->quant_tables[i]);
- if (f->context_count[i] < 0) {
- av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n");
- return AVERROR_INVALIDDATA;
- }
- }
- if ((ret = ff_ffv1_allocate_initial_states(f)) < 0)
- return ret;
-
- for (i = 0; i < f->quant_table_count; i++)
- if (get_rac(c, state)) {
- for (j = 0; j < f->context_count[i]; j++)
- for (k = 0; k < CONTEXT_SIZE; k++) {
- int pred = j ? f->initial_states[i][j - 1][k] : 128;
- f->initial_states[i][j][k] =
- (pred + get_symbol(c, state2[k], 1)) & 0xFF;
- }
- }
-
- if (f->version > 2) {
- f->ec = get_symbol(c, state, 0);
- if (f->micro_version > 2)
- f->intra = get_symbol(c, state, 0);
- }
-
- if (f->version > 2) {
- unsigned v;
- v = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0,
- f->avctx->extradata, f->avctx->extradata_size);
- if (v || f->avctx->extradata_size < 4) {
- av_log(f->avctx, AV_LOG_ERROR, "CRC mismatch %X!\n", v);
- return AVERROR_INVALIDDATA;
- }
- crc = AV_RB32(f->avctx->extradata + f->avctx->extradata_size - 4);
- }
-
- if (f->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(f->avctx, AV_LOG_DEBUG,
- "global: ver:%d.%d, coder:%d, colorspace: %d bpr:%d chroma:%d(%d:%d), alpha:%d slices:%dx%d qtabs:%d ec:%d intra:%d CRC:0x%08X\n",
- f->version, f->micro_version,
- f->ac,
- f->colorspace,
- f->avctx->bits_per_raw_sample,
- f->chroma_planes, f->chroma_h_shift, f->chroma_v_shift,
- f->transparency,
- f->num_h_slices, f->num_v_slices,
- f->quant_table_count,
- f->ec,
- f->intra,
- crc
- );
- return 0;
-}
-
-static int read_header(FFV1Context *f)
-{
- uint8_t state[CONTEXT_SIZE];
- int i, j, context_count = -1; //-1 to avoid warning
- RangeCoder *const c = &f->slice_context[0]->c;
-
- memset(state, 128, sizeof(state));
-
- if (f->version < 2) {
- int chroma_planes, chroma_h_shift, chroma_v_shift, transparency, colorspace, bits_per_raw_sample;
- unsigned v= get_symbol(c, state, 0);
- if (v >= 2) {
- av_log(f->avctx, AV_LOG_ERROR, "invalid version %d in ver01 header\n", v);
- return AVERROR_INVALIDDATA;
- }
- f->version = v;
- f->ac = f->avctx->coder_type = get_symbol(c, state, 0);
- if (f->ac > 1) {
- for (i = 1; i < 256; i++)
- f->state_transition[i] = get_symbol(c, state, 1) + c->one_state[i];
- }
-
- colorspace = get_symbol(c, state, 0); //YUV cs type
- bits_per_raw_sample = f->version > 0 ? get_symbol(c, state, 0) : f->avctx->bits_per_raw_sample;
- chroma_planes = get_rac(c, state);
- chroma_h_shift = get_symbol(c, state, 0);
- chroma_v_shift = get_symbol(c, state, 0);
- transparency = get_rac(c, state);
- if (colorspace == 0 && f->avctx->skip_alpha)
- transparency = 0;
-
- if (f->plane_count) {
- if (colorspace != f->colorspace ||
- bits_per_raw_sample != f->avctx->bits_per_raw_sample ||
- chroma_planes != f->chroma_planes ||
- chroma_h_shift != f->chroma_h_shift ||
- chroma_v_shift != f->chroma_v_shift ||
- transparency != f->transparency) {
- av_log(f->avctx, AV_LOG_ERROR, "Invalid change of global parameters\n");
- return AVERROR_INVALIDDATA;
- }
- }
-
- if (chroma_h_shift > 4U || chroma_v_shift > 4U) {
- av_log(f->avctx, AV_LOG_ERROR, "chroma shift parameters %d %d are invalid\n",
- chroma_h_shift, chroma_v_shift);
- return AVERROR_INVALIDDATA;
- }
-
- f->colorspace = colorspace;
- f->avctx->bits_per_raw_sample = bits_per_raw_sample;
- f->chroma_planes = chroma_planes;
- f->chroma_h_shift = chroma_h_shift;
- f->chroma_v_shift = chroma_v_shift;
- f->transparency = transparency;
-
- f->plane_count = 2 + f->transparency;
- }
-
- if (f->colorspace == 0) {
- if (!f->transparency && !f->chroma_planes) {
- if (f->avctx->bits_per_raw_sample <= 8)
- f->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
- else
- f->avctx->pix_fmt = AV_PIX_FMT_GRAY16;
- } else if (f->avctx->bits_per_raw_sample<=8 && !f->transparency) {
- switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
- case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P; break;
- case 0x01: f->avctx->pix_fmt = AV_PIX_FMT_YUV440P; break;
- case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P; break;
- case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P; break;
- case 0x20: f->avctx->pix_fmt = AV_PIX_FMT_YUV411P; break;
- case 0x22: f->avctx->pix_fmt = AV_PIX_FMT_YUV410P; break;
- }
- } else if (f->avctx->bits_per_raw_sample <= 8 && f->transparency) {
- switch(16*f->chroma_h_shift + f->chroma_v_shift) {
- case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUVA444P; break;
- case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUVA422P; break;
- case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUVA420P; break;
- }
- } else if (f->avctx->bits_per_raw_sample == 9 && !f->transparency) {
- f->packed_at_lsb = 1;
- switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
- case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P9; break;
- case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P9; break;
- case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P9; break;
- }
- } else if (f->avctx->bits_per_raw_sample == 9 && f->transparency) {
- f->packed_at_lsb = 1;
- switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
- case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUVA444P9; break;
- case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUVA422P9; break;
- case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUVA420P9; break;
- }
- } else if (f->avctx->bits_per_raw_sample == 10 && !f->transparency) {
- f->packed_at_lsb = 1;
- switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
- case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P10; break;
- case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P10; break;
- case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P10; break;
- }
- } else if (f->avctx->bits_per_raw_sample == 10 && f->transparency) {
- f->packed_at_lsb = 1;
- switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
- case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUVA444P10; break;
- case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUVA422P10; break;
- case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUVA420P10; break;
- }
- } else if (f->avctx->bits_per_raw_sample == 16 && !f->transparency){
- switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
- case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P16; break;
- case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P16; break;
- case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P16; break;
- }
- } else if (f->avctx->bits_per_raw_sample == 16 && f->transparency){
- switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
- case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUVA444P16; break;
- case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUVA422P16; break;
- case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUVA420P16; break;
- }
- }
- } else if (f->colorspace == 1) {
- if (f->chroma_h_shift || f->chroma_v_shift) {
- av_log(f->avctx, AV_LOG_ERROR,
- "chroma subsampling not supported in this colorspace\n");
- return AVERROR(ENOSYS);
- }
- if ( f->avctx->bits_per_raw_sample == 9)
- f->avctx->pix_fmt = AV_PIX_FMT_GBRP9;
- else if (f->avctx->bits_per_raw_sample == 10)
- f->avctx->pix_fmt = AV_PIX_FMT_GBRP10;
- else if (f->avctx->bits_per_raw_sample == 12)
- f->avctx->pix_fmt = AV_PIX_FMT_GBRP12;
- else if (f->avctx->bits_per_raw_sample == 14)
- f->avctx->pix_fmt = AV_PIX_FMT_GBRP14;
- else
- if (f->transparency) f->avctx->pix_fmt = AV_PIX_FMT_RGB32;
- else f->avctx->pix_fmt = AV_PIX_FMT_0RGB32;
- } else {
- av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n");
- return AVERROR(ENOSYS);
- }
- if (f->avctx->pix_fmt == AV_PIX_FMT_NONE) {
- av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
- return AVERROR(ENOSYS);
- }
-
- ff_dlog(f->avctx, "%d %d %d\n",
- f->chroma_h_shift, f->chroma_v_shift, f->avctx->pix_fmt);
- if (f->version < 2) {
- context_count = read_quant_tables(c, f->quant_table);
- if (context_count < 0) {
- av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n");
- return AVERROR_INVALIDDATA;
- }
- f->slice_count = f->max_slice_count;
- } else if (f->version < 3) {
- f->slice_count = get_symbol(c, state, 0);
- } else {
- const uint8_t *p = c->bytestream_end;
- for (f->slice_count = 0;
- f->slice_count < MAX_SLICES && 3 < p - c->bytestream_start;
- f->slice_count++) {
- int trailer = 3 + 5*!!f->ec;
- int size = AV_RB24(p-trailer);
- if (size + trailer > p - c->bytestream_start)
- break;
- p -= size + trailer;
- }
- }
- if (f->slice_count > (unsigned)MAX_SLICES || f->slice_count <= 0 || f->slice_count > f->max_slice_count) {
- av_log(f->avctx, AV_LOG_ERROR, "slice count %d is invalid (max=%d)\n", f->slice_count, f->max_slice_count);
- return AVERROR_INVALIDDATA;
- }
-
- for (j = 0; j < f->slice_count; j++) {
- FFV1Context *fs = f->slice_context[j];
- fs->ac = f->ac;
- fs->packed_at_lsb = f->packed_at_lsb;
-
- fs->slice_damaged = 0;
-
- if (f->version == 2) {
- fs->slice_x = get_symbol(c, state, 0) * f->width ;
- fs->slice_y = get_symbol(c, state, 0) * f->height;
- fs->slice_width = (get_symbol(c, state, 0) + 1) * f->width + fs->slice_x;
- fs->slice_height = (get_symbol(c, state, 0) + 1) * f->height + fs->slice_y;
-
- fs->slice_x /= f->num_h_slices;
- fs->slice_y /= f->num_v_slices;
- fs->slice_width = fs->slice_width / f->num_h_slices - fs->slice_x;
- fs->slice_height = fs->slice_height / f->num_v_slices - fs->slice_y;
- if ((unsigned)fs->slice_width > f->width ||
- (unsigned)fs->slice_height > f->height)
- return AVERROR_INVALIDDATA;
- if ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width > f->width
- || (unsigned)fs->slice_y + (uint64_t)fs->slice_height > f->height)
- return AVERROR_INVALIDDATA;
- }
-
- for (i = 0; i < f->plane_count; i++) {
- PlaneContext *const p = &fs->plane[i];
-
- if (f->version == 2) {
- int idx = get_symbol(c, state, 0);
- if (idx > (unsigned)f->quant_table_count) {
- av_log(f->avctx, AV_LOG_ERROR,
- "quant_table_index out of range\n");
- return AVERROR_INVALIDDATA;
- }
- p->quant_table_index = idx;
- memcpy(p->quant_table, f->quant_tables[idx],
- sizeof(p->quant_table));
- context_count = f->context_count[idx];
- } else {
- memcpy(p->quant_table, f->quant_table, sizeof(p->quant_table));
- }
-
- if (f->version <= 2) {
- av_assert0(context_count >= 0);
- if (p->context_count < context_count) {
- av_freep(&p->state);
- av_freep(&p->vlc_state);
- }
- p->context_count = context_count;
- }
- }
- }
- return 0;
-}
-
-static av_cold int decode_init(AVCodecContext *avctx)
-{
- FFV1Context *f = avctx->priv_data;
- int ret;
-
- if ((ret = ff_ffv1_common_init(avctx)) < 0)
- return ret;
-
- if (avctx->extradata && (ret = read_extra_header(f)) < 0)
- return ret;
-
- if ((ret = ff_ffv1_init_slice_contexts(f)) < 0)
- return ret;
-
- avctx->internal->allocate_progress = 1;
-
- return 0;
-}
-
-static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
-{
- uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- FFV1Context *f = avctx->priv_data;
- RangeCoder *const c = &f->slice_context[0]->c;
- int i, ret;
- uint8_t keystate = 128;
- uint8_t *buf_p;
- AVFrame *p;
-
- if (f->last_picture.f)
- ff_thread_release_buffer(avctx, &f->last_picture);
- FFSWAP(ThreadFrame, f->picture, f->last_picture);
-
- f->cur = p = f->picture.f;
-
- if (f->version < 3 && avctx->field_order > AV_FIELD_PROGRESSIVE) {
- /* we have interlaced material flagged in container */
- p->interlaced_frame = 1;
- if (avctx->field_order == AV_FIELD_TT || avctx->field_order == AV_FIELD_TB)
- p->top_field_first = 1;
- }
-
- f->avctx = avctx;
- ff_init_range_decoder(c, buf, buf_size);
- ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
-
- p->pict_type = AV_PICTURE_TYPE_I; //FIXME I vs. P
- if (get_rac(c, &keystate)) {
- p->key_frame = 1;
- f->key_frame_ok = 0;
- if ((ret = read_header(f)) < 0)
- return ret;
- f->key_frame_ok = 1;
- } else {
- if (!f->key_frame_ok) {
- av_log(avctx, AV_LOG_ERROR,
- "Cannot decode non-keyframe without valid keyframe\n");
- return AVERROR_INVALIDDATA;
- }
- p->key_frame = 0;
- }
-
- if ((ret = ff_thread_get_buffer(avctx, &f->picture, AV_GET_BUFFER_FLAG_REF)) < 0)
- return ret;
-
- if (avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d slices:%d bps:%d\n",
- f->version, p->key_frame, f->ac, f->ec, f->slice_count, f->avctx->bits_per_raw_sample);
-
- ff_thread_finish_setup(avctx);
-
- buf_p = buf + buf_size;
- for (i = f->slice_count - 1; i >= 0; i--) {
- FFV1Context *fs = f->slice_context[i];
- 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 (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);
- return AVERROR_INVALIDDATA;
- }
- buf_p -= v;
-
- if (f->ec) {
- unsigned crc = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0, buf_p, v);
- if (crc) {
- int64_t ts = avpkt->pts != AV_NOPTS_VALUE ? avpkt->pts : avpkt->dts;
- av_log(f->avctx, AV_LOG_ERROR, "CRC mismatch %X!", crc);
- if (ts != AV_NOPTS_VALUE && avctx->pkt_timebase.num) {
- av_log(f->avctx, AV_LOG_ERROR, "at %f seconds\n", ts*av_q2d(avctx->pkt_timebase));
- } else if (ts != AV_NOPTS_VALUE) {
- av_log(f->avctx, AV_LOG_ERROR, "at %"PRId64"\n", ts);
- } else {
- av_log(f->avctx, AV_LOG_ERROR, "\n");
- }
- fs->slice_damaged = 1;
- }
- if (avctx->debug & FF_DEBUG_PICT_INFO) {
- av_log(avctx, AV_LOG_DEBUG, "slice %d, CRC: 0x%08X\n", i, AV_RB32(buf_p + v - 4));
- }
- }
-
- if (i) {
- ff_init_range_decoder(&fs->c, buf_p, v);
- } else
- fs->c.bytestream_end = buf_p + v;
-
- fs->avctx = avctx;
- fs->cur = p;
- }
-
- avctx->execute(avctx,
- decode_slice,
- &f->slice_context[0],
- NULL,
- f->slice_count,
- sizeof(void*));
-
- for (i = f->slice_count - 1; i >= 0; i--) {
- FFV1Context *fs = f->slice_context[i];
- int j;
- if (fs->slice_damaged && f->last_picture.f->data[0]) {
- const uint8_t *src[4];
- uint8_t *dst[4];
- ff_thread_await_progress(&f->last_picture, INT_MAX, 0);
- for (j = 0; j < 4; j++) {
- int sh = (j == 1 || j == 2) ? f->chroma_h_shift : 0;
- int sv = (j == 1 || j == 2) ? f->chroma_v_shift : 0;
- dst[j] = p->data[j] + p->linesize[j] *
- (fs->slice_y >> sv) + (fs->slice_x >> sh);
- src[j] = f->last_picture.f->data[j] + f->last_picture.f->linesize[j] *
- (fs->slice_y >> sv) + (fs->slice_x >> sh);
- }
- av_image_copy(dst, p->linesize, src,
- f->last_picture.f->linesize,
- avctx->pix_fmt,
- fs->slice_width,
- fs->slice_height);
- }
- }
- ff_thread_report_progress(&f->picture, INT_MAX, 0);
-
- f->picture_number++;
-
- if (f->last_picture.f)
- ff_thread_release_buffer(avctx, &f->last_picture);
- f->cur = NULL;
- if ((ret = av_frame_ref(data, f->picture.f)) < 0)
- return ret;
-
- *got_frame = 1;
-
- return buf_size;
-}
-
-static int init_thread_copy(AVCodecContext *avctx)
-{
- FFV1Context *f = avctx->priv_data;
- int i, ret;
-
- f->picture.f = NULL;
- f->last_picture.f = NULL;
- f->sample_buffer = NULL;
- f->max_slice_count = 0;
- f->slice_count = 0;
-
- for (i = 0; i < f->quant_table_count; i++) {
- av_assert0(f->version > 1);
- f->initial_states[i] = av_memdup(f->initial_states[i],
- f->context_count[i] * sizeof(*f->initial_states[i]));
- }
-
- f->picture.f = av_frame_alloc();
- f->last_picture.f = av_frame_alloc();
-
- if ((ret = ff_ffv1_init_slice_contexts(f)) < 0)
- return ret;
-
- return 0;
-}
-
-static void copy_fields(FFV1Context *fsdst, FFV1Context *fssrc, FFV1Context *fsrc)
-{
- fsdst->version = fsrc->version;
- fsdst->micro_version = fsrc->micro_version;
- fsdst->chroma_planes = fsrc->chroma_planes;
- fsdst->chroma_h_shift = fsrc->chroma_h_shift;
- fsdst->chroma_v_shift = fsrc->chroma_v_shift;
- fsdst->transparency = fsrc->transparency;
- fsdst->plane_count = fsrc->plane_count;
- fsdst->ac = fsrc->ac;
- fsdst->colorspace = fsrc->colorspace;
-
- fsdst->ec = fsrc->ec;
- fsdst->intra = fsrc->intra;
- fsdst->slice_damaged = fssrc->slice_damaged;
- fsdst->key_frame_ok = fsrc->key_frame_ok;
-
- fsdst->bits_per_raw_sample = fsrc->bits_per_raw_sample;
- fsdst->packed_at_lsb = fsrc->packed_at_lsb;
- fsdst->slice_count = fsrc->slice_count;
- if (fsrc->version<3){
- fsdst->slice_x = fssrc->slice_x;
- fsdst->slice_y = fssrc->slice_y;
- fsdst->slice_width = fssrc->slice_width;
- fsdst->slice_height = fssrc->slice_height;
- }
-}
-
-static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
-{
- FFV1Context *fsrc = src->priv_data;
- FFV1Context *fdst = dst->priv_data;
- int i, ret;
-
- if (dst == src)
- return 0;
-
- {
- ThreadFrame picture = fdst->picture, last_picture = fdst->last_picture;
- uint8_t (*initial_states[MAX_QUANT_TABLES])[32];
- struct FFV1Context *slice_context[MAX_SLICES];
- memcpy(initial_states, fdst->initial_states, sizeof(fdst->initial_states));
- memcpy(slice_context, fdst->slice_context , sizeof(fdst->slice_context));
-
- memcpy(fdst, fsrc, sizeof(*fdst));
- memcpy(fdst->initial_states, initial_states, sizeof(fdst->initial_states));
- memcpy(fdst->slice_context, slice_context , sizeof(fdst->slice_context));
- fdst->picture = picture;
- fdst->last_picture = last_picture;
- for (i = 0; i<fdst->num_h_slices * fdst->num_v_slices; i++) {
- FFV1Context *fssrc = fsrc->slice_context[i];
- FFV1Context *fsdst = fdst->slice_context[i];
- copy_fields(fsdst, fssrc, fsrc);
- }
- av_assert0(!fdst->plane[0].state);
- av_assert0(!fdst->sample_buffer);
- }
-
- av_assert1(fdst->max_slice_count == fsrc->max_slice_count);
-
-
- ff_thread_release_buffer(dst, &fdst->picture);
- if (fsrc->picture.f->data[0]) {
- if ((ret = ff_thread_ref_frame(&fdst->picture, &fsrc->picture)) < 0)
- return ret;
- }
-
- fdst->fsrc = fsrc;
-
- return 0;
-}
-
-AVCodec ff_ffv1_decoder = {
- .name = "ffv1",
- .long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_FFV1,
- .priv_data_size = sizeof(FFV1Context),
- .init = decode_init,
- .close = ff_ffv1_close,
- .decode = decode_frame,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
- .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
- .capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/ |
- AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/fic.c b/ffmpeg-2-8-11/libavcodec/fic.c
deleted file mode 100644
index b58b017..0000000
--- a/ffmpeg-2-8-11/libavcodec/fic.c
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * Mirillis FIC decoder
- *
- * Copyright (c) 2014 Konstantin Shishkov
- * Copyright (c) 2014 Derek Buitenhuis
- *
- * 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/opt.h"
-#include "avcodec.h"
-#include "internal.h"
-#include "get_bits.h"
-#include "golomb.h"
-
-typedef struct FICThreadContext {
- DECLARE_ALIGNED(16, int16_t, block)[64];
- uint8_t *src;
- int slice_h;
- int src_size;
- int y_off;
-} FICThreadContext;
-
-typedef struct FICContext {
- AVClass *class;
- AVCodecContext *avctx;
- AVFrame *frame;
- AVFrame *final_frame;
-
- FICThreadContext *slice_data;
- int slice_data_size;
-
- const uint8_t *qmat;
-
- enum AVPictureType cur_frame_type;
-
- int aligned_width, aligned_height;
- int num_slices, slice_h;
-
- uint8_t cursor_buf[4096];
- int skip_cursor;
-} FICContext;
-
-static const uint8_t fic_qmat_hq[64] = {
- 1, 2, 2, 2, 3, 3, 3, 4,
- 2, 2, 2, 3, 3, 3, 4, 4,
- 2, 2, 3, 3, 3, 4, 4, 4,
- 2, 2, 3, 3, 3, 4, 4, 5,
- 2, 3, 3, 3, 4, 4, 5, 6,
- 3, 3, 3, 4, 4, 5, 6, 7,
- 3, 3, 3, 4, 4, 5, 7, 7,
- 3, 3, 4, 4, 5, 7, 7, 7,
-};
-
-static const uint8_t fic_qmat_lq[64] = {
- 1, 5, 6, 7, 8, 9, 9, 11,
- 5, 5, 7, 8, 9, 9, 11, 12,
- 6, 7, 8, 9, 9, 11, 11, 12,
- 7, 7, 8, 9, 9, 11, 12, 13,
- 7, 8, 9, 9, 10, 11, 13, 16,
- 8, 9, 9, 10, 11, 13, 16, 19,
- 8, 9, 9, 11, 12, 15, 18, 23,
- 9, 9, 11, 12, 15, 18, 23, 27
-};
-
-static const uint8_t fic_header[7] = { 0, 0, 1, 'F', 'I', 'C', 'V' };
-
-#define FIC_HEADER_SIZE 27
-
-static av_always_inline void fic_idct(int16_t *blk, int step, int shift, int rnd)
-{
- const int t0 = 27246 * blk[3 * step] + 18405 * blk[5 * step];
- const int t1 = 27246 * blk[5 * step] - 18405 * blk[3 * step];
- const int t2 = 6393 * blk[7 * step] + 32139 * blk[1 * step];
- const int t3 = 6393 * blk[1 * step] - 32139 * blk[7 * step];
- const int t4 = 5793 * (t2 + t0 + 0x800 >> 12);
- const int t5 = 5793 * (t3 + t1 + 0x800 >> 12);
- const int t6 = t2 - t0;
- const int t7 = t3 - t1;
- const int t8 = 17734 * blk[2 * step] - 42813 * blk[6 * step];
- const int t9 = 17734 * blk[6 * step] + 42814 * blk[2 * step];
- const int tA = (blk[0 * step] - blk[4 * step] << 15) + rnd;
- const int tB = (blk[0 * step] + blk[4 * step] << 15) + rnd;
- blk[0 * step] = ( t4 + t9 + tB) >> shift;
- blk[1 * step] = ( t6 + t7 + t8 + tA) >> shift;
- blk[2 * step] = ( t6 - t7 - t8 + tA) >> shift;
- blk[3 * step] = ( t5 - t9 + tB) >> shift;
- blk[4 * step] = ( -t5 - t9 + tB) >> shift;
- blk[5 * step] = (-(t6 - t7) - t8 + tA) >> shift;
- blk[6 * step] = (-(t6 + t7) + t8 + tA) >> shift;
- blk[7 * step] = ( -t4 + t9 + tB) >> shift;
-}
-
-static void fic_idct_put(uint8_t *dst, int stride, int16_t *block)
-{
- int i, j;
- int16_t *ptr;
-
- ptr = block;
- fic_idct(ptr++, 8, 13, (1 << 12) + (1 << 17));
- for (i = 1; i < 8; i++) {
- fic_idct(ptr, 8, 13, 1 << 12);
- ptr++;
- }
-
- ptr = block;
- for (i = 0; i < 8; i++) {
- fic_idct(ptr, 1, 20, 0);
- ptr += 8;
- }
-
- ptr = block;
- for (j = 0; j < 8; j++) {
- for (i = 0; i < 8; i++)
- dst[i] = av_clip_uint8(ptr[i]);
- dst += stride;
- ptr += 8;
- }
-}
-static int fic_decode_block(FICContext *ctx, GetBitContext *gb,
- uint8_t *dst, int stride, int16_t *block)
-{
- int i, num_coeff;
-
- /* Is it a skip block? */
- if (get_bits1(gb)) {
- /* This is a P-frame. */
- ctx->frame->key_frame = 0;
- ctx->frame->pict_type = AV_PICTURE_TYPE_P;
-
- return 0;
- }
-
- memset(block, 0, sizeof(*block) * 64);
-
- num_coeff = get_bits(gb, 7);
- if (num_coeff > 64)
- return AVERROR_INVALIDDATA;
-
- for (i = 0; i < num_coeff; i++)
- block[ff_zigzag_direct[i]] = get_se_golomb(gb) *
- ctx->qmat[ff_zigzag_direct[i]];
-
- fic_idct_put(dst, stride, block);
-
- return 0;
-}
-
-static int fic_decode_slice(AVCodecContext *avctx, void *tdata)
-{
- FICContext *ctx = avctx->priv_data;
- FICThreadContext *tctx = tdata;
- GetBitContext gb;
- uint8_t *src = tctx->src;
- int slice_h = tctx->slice_h;
- int src_size = tctx->src_size;
- int y_off = tctx->y_off;
- int x, y, p;
-
- init_get_bits(&gb, src, src_size * 8);
-
- for (p = 0; p < 3; p++) {
- int stride = ctx->frame->linesize[p];
- uint8_t* dst = ctx->frame->data[p] + (y_off >> !!p) * stride;
-
- for (y = 0; y < (slice_h >> !!p); y += 8) {
- for (x = 0; x < (ctx->aligned_width >> !!p); x += 8) {
- int ret;
-
- if ((ret = fic_decode_block(ctx, &gb, dst + x, stride, tctx->block)) != 0)
- return ret;
- }
-
- dst += 8 * stride;
- }
- }
-
- return 0;
-}
-
-static av_always_inline void fic_alpha_blend(uint8_t *dst, uint8_t *src,
- int size, uint8_t *alpha)
-{
- int i;
-
- for (i = 0; i < size; i++)
- dst[i] += ((src[i] - dst[i]) * alpha[i]) >> 8;
-}
-
-static void fic_draw_cursor(AVCodecContext *avctx, int cur_x, int cur_y)
-{
- FICContext *ctx = avctx->priv_data;
- uint8_t *ptr = ctx->cursor_buf;
- uint8_t *dstptr[3];
- uint8_t planes[4][1024];
- uint8_t chroma[3][256];
- int i, j, p;
-
- /* Convert to YUVA444. */
- for (i = 0; i < 1024; i++) {
- planes[0][i] = (( 25 * ptr[0] + 129 * ptr[1] + 66 * ptr[2]) / 255) + 16;
- planes[1][i] = ((-38 * ptr[0] + 112 * ptr[1] + -74 * ptr[2]) / 255) + 128;
- planes[2][i] = ((-18 * ptr[0] + 112 * ptr[1] + -94 * ptr[2]) / 255) + 128;
- planes[3][i] = ptr[3];
-
- ptr += 4;
- }
-
- /* Subsample chroma. */
- for (i = 0; i < 32; i += 2)
- for (j = 0; j < 32; j += 2)
- for (p = 0; p < 3; p++)
- chroma[p][16 * (i / 2) + j / 2] = (planes[p + 1][32 * i + j ] +
- planes[p + 1][32 * i + j + 1] +
- planes[p + 1][32 * (i + 1) + j ] +
- planes[p + 1][32 * (i + 1) + j + 1]) / 4;
-
- /* Seek to x/y pos of cursor. */
- for (i = 0; i < 3; i++)
- dstptr[i] = ctx->final_frame->data[i] +
- (ctx->final_frame->linesize[i] * (cur_y >> !!i)) +
- (cur_x >> !!i) + !!i;
-
- /* Copy. */
- for (i = 0; i < FFMIN(32, avctx->height - cur_y) - 1; i += 2) {
- int lsize = FFMIN(32, avctx->width - cur_x);
- int csize = lsize / 2;
-
- fic_alpha_blend(dstptr[0],
- planes[0] + i * 32, lsize, planes[3] + i * 32);
- fic_alpha_blend(dstptr[0] + ctx->final_frame->linesize[0],
- planes[0] + (i + 1) * 32, lsize, planes[3] + (i + 1) * 32);
- fic_alpha_blend(dstptr[1],
- chroma[0] + (i / 2) * 16, csize, chroma[2] + (i / 2) * 16);
- fic_alpha_blend(dstptr[2],
- chroma[1] + (i / 2) * 16, csize, chroma[2] + (i / 2) * 16);
-
- dstptr[0] += ctx->final_frame->linesize[0] * 2;
- dstptr[1] += ctx->final_frame->linesize[1];
- dstptr[2] += ctx->final_frame->linesize[2];
- }
-}
-
-static int fic_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame, AVPacket *avpkt)
-{
- FICContext *ctx = avctx->priv_data;
- uint8_t *src = avpkt->data;
- int ret;
- int slice, nslices;
- int msize;
- int tsize;
- int cur_x, cur_y;
- int skip_cursor = ctx->skip_cursor;
- uint8_t *sdata;
-
- if ((ret = ff_reget_buffer(avctx, ctx->frame)) < 0)
- return ret;
-
- /* Header + at least one slice (4) */
- if (avpkt->size < FIC_HEADER_SIZE + 4) {
- av_log(avctx, AV_LOG_ERROR, "Frame data is too small.\n");
- return AVERROR_INVALIDDATA;
- }
-
- /* Check for header. */
- if (memcmp(src, fic_header, 7))
- av_log(avctx, AV_LOG_WARNING, "Invalid FIC Header.\n");
-
- /* Is it a skip frame? */
- if (src[17]) {
- if (!ctx->final_frame) {
- av_log(avctx, AV_LOG_WARNING, "Initial frame is skipped\n");
- return AVERROR_INVALIDDATA;
- }
- goto skip;
- }
-
- nslices = src[13];
- if (!nslices) {
- av_log(avctx, AV_LOG_ERROR, "Zero slices found.\n");
- return AVERROR_INVALIDDATA;
- }
-
- /* High or Low Quality Matrix? */
- ctx->qmat = src[23] ? fic_qmat_hq : fic_qmat_lq;
-
- /* Skip cursor data. */
- tsize = AV_RB24(src + 24);
- if (tsize > avpkt->size - FIC_HEADER_SIZE) {
- av_log(avctx, AV_LOG_ERROR,
- "Packet is too small to contain cursor (%d vs %d bytes).\n",
- tsize, avpkt->size - FIC_HEADER_SIZE);
- return AVERROR_INVALIDDATA;
- }
-
- if (!tsize)
- skip_cursor = 1;
-
- if (!skip_cursor && tsize < 32) {
- av_log(avctx, AV_LOG_WARNING,
- "Cursor data too small. Skipping cursor.\n");
- skip_cursor = 1;
- }
-
- /* Cursor position. */
- cur_x = AV_RL16(src + 33);
- cur_y = AV_RL16(src + 35);
- if (!skip_cursor && (cur_x > avctx->width || cur_y > avctx->height)) {
- av_log(avctx, AV_LOG_WARNING,
- "Invalid cursor position: (%d,%d). Skipping cusor.\n",
- cur_x, cur_y);
- skip_cursor = 1;
- }
-
- if (!skip_cursor && (AV_RL16(src + 37) != 32 || AV_RL16(src + 39) != 32)) {
- av_log(avctx, AV_LOG_WARNING,
- "Invalid cursor size. Skipping cursor.\n");
- skip_cursor = 1;
- }
-
- /* Slice height for all but the last slice. */
- ctx->slice_h = 16 * (ctx->aligned_height >> 4) / nslices;
- if (ctx->slice_h % 16)
- ctx->slice_h = FFALIGN(ctx->slice_h - 16, 16);
-
- /* First slice offset and remaining data. */
- sdata = src + tsize + FIC_HEADER_SIZE + 4 * nslices;
- msize = avpkt->size - nslices * 4 - tsize - FIC_HEADER_SIZE;
-
- if (msize <= 0) {
- av_log(avctx, AV_LOG_ERROR, "Not enough frame data to decode.\n");
- return AVERROR_INVALIDDATA;
- }
-
- /*
- * Set the frametype to I initially. It will be set to P if the frame
- * has any dependencies (skip blocks). There will be a race condition
- * inside the slice decode function to set these, but we do not care.
- * since they will only ever be set to 0/P.
- */
- ctx->frame->key_frame = 1;
- ctx->frame->pict_type = AV_PICTURE_TYPE_I;
-
- /* Allocate slice data. */
- av_fast_malloc(&ctx->slice_data, &ctx->slice_data_size,
- nslices * sizeof(ctx->slice_data[0]));
- if (!ctx->slice_data_size) {
- av_log(avctx, AV_LOG_ERROR, "Could not allocate slice data.\n");
- return AVERROR(ENOMEM);
- }
- memset(ctx->slice_data, 0, nslices * sizeof(ctx->slice_data[0]));
-
- for (slice = 0; slice < nslices; slice++) {
- unsigned slice_off = AV_RB32(src + tsize + FIC_HEADER_SIZE + slice * 4);
- unsigned slice_size;
- int y_off = ctx->slice_h * slice;
- int slice_h = ctx->slice_h;
-
- /*
- * Either read the slice size, or consume all data left.
- * Also, special case the last slight height.
- */
- if (slice == nslices - 1) {
- slice_size = msize;
- slice_h = FFALIGN(avctx->height - ctx->slice_h * (nslices - 1), 16);
- } else {
- slice_size = AV_RB32(src + tsize + FIC_HEADER_SIZE + slice * 4 + 4);
- }
-
- if (slice_size < slice_off || slice_size > msize)
- continue;
-
- slice_size -= slice_off;
-
- ctx->slice_data[slice].src = sdata + slice_off;
- ctx->slice_data[slice].src_size = slice_size;
- ctx->slice_data[slice].slice_h = slice_h;
- ctx->slice_data[slice].y_off = y_off;
- }
-
- if ((ret = avctx->execute(avctx, fic_decode_slice, ctx->slice_data,
- NULL, nslices, sizeof(ctx->slice_data[0]))) < 0)
- return ret;
-
- av_frame_free(&ctx->final_frame);
- ctx->final_frame = av_frame_clone(ctx->frame);
- if (!ctx->final_frame) {
- av_log(avctx, AV_LOG_ERROR, "Could not clone frame buffer.\n");
- return AVERROR(ENOMEM);
- }
-
- /* Make sure we use a user-supplied buffer. */
- if ((ret = ff_reget_buffer(avctx, ctx->final_frame)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "Could not make frame writable.\n");
- return ret;
- }
-
- /* Draw cursor. */
- if (!skip_cursor) {
- memcpy(ctx->cursor_buf, src + 59, 32 * 32 * 4);
- fic_draw_cursor(avctx, cur_x, cur_y);
- }
-
-skip:
- *got_frame = 1;
- if ((ret = av_frame_ref(data, ctx->final_frame)) < 0)
- return ret;
-
- return avpkt->size;
-}
-
-static av_cold int fic_decode_close(AVCodecContext *avctx)
-{
- FICContext *ctx = avctx->priv_data;
-
- av_freep(&ctx->slice_data);
- av_frame_free(&ctx->final_frame);
- av_frame_free(&ctx->frame);
-
- return 0;
-}
-
-static av_cold int fic_decode_init(AVCodecContext *avctx)
-{
- FICContext *ctx = avctx->priv_data;
-
- /* Initialize various context values */
- ctx->avctx = avctx;
- ctx->aligned_width = FFALIGN(avctx->width, 16);
- ctx->aligned_height = FFALIGN(avctx->height, 16);
-
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- avctx->bits_per_raw_sample = 8;
-
- ctx->frame = av_frame_alloc();
- if (!ctx->frame)
- return AVERROR(ENOMEM);
-
- return 0;
-}
-
-static const AVOption options[] = {
-{ "skip_cursor", "skip the cursor", offsetof(FICContext, skip_cursor), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM },
-{ NULL },
-};
-
-static const AVClass fic_decoder_class = {
- .class_name = "FIC encoder",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-AVCodec ff_fic_decoder = {
- .name = "fic",
- .long_name = NULL_IF_CONFIG_SMALL("Mirillis FIC"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_FIC,
- .priv_data_size = sizeof(FICContext),
- .init = fic_decode_init,
- .decode = fic_decode_frame,
- .close = fic_decode_close,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
- .priv_class = &fic_decoder_class,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/flacdec.c b/ffmpeg-2-8-11/libavcodec/flacdec.c
deleted file mode 100644
index 65edac2..0000000
--- a/ffmpeg-2-8-11/libavcodec/flacdec.c
+++ /dev/null
@@ -1,676 +0,0 @@
-/*
- * FLAC (Free Lossless Audio Codec) decoder
- * Copyright (c) 2003 Alex Beregszaszi
- *
- * 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
- * FLAC (Free Lossless Audio Codec) decoder
- * @author Alex Beregszaszi
- * @see http://flac.sourceforge.net/
- *
- * This decoder can be used in 1 of 2 ways: Either raw FLAC data can be fed
- * through, starting from the initial 'fLaC' signature; or by passing the
- * 34-byte streaminfo structure through avctx->extradata[_size] followed
- * by data starting with the 0xFFF8 marker.
- */
-
-#include <limits.h>
-
-#include "libavutil/avassert.h"
-#include "libavutil/crc.h"
-#include "libavutil/opt.h"
-#include "avcodec.h"
-#include "internal.h"
-#include "get_bits.h"
-#include "bytestream.h"
-#include "golomb.h"
-#include "flac.h"
-#include "flacdata.h"
-#include "flacdsp.h"
-#include "thread.h"
-#include "unary.h"
-
-
-typedef struct FLACContext {
- AVClass *class;
- struct FLACStreaminfo flac_stream_info;
-
- AVCodecContext *avctx; ///< parent AVCodecContext
- GetBitContext gb; ///< GetBitContext initialized to start at the current frame
-
- int blocksize; ///< number of samples in the current frame
- int sample_shift; ///< shift required to make output samples 16-bit or 32-bit
- int ch_mode; ///< channel decorrelation type in the current frame
- int got_streaminfo; ///< indicates if the STREAMINFO has been read
-
- int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples
- uint8_t *decoded_buffer;
- unsigned int decoded_buffer_size;
- int buggy_lpc; ///< use workaround for old lavc encoded files
-
- FLACDSPContext dsp;
-} FLACContext;
-
-static int allocate_buffers(FLACContext *s);
-
-static void flac_set_bps(FLACContext *s)
-{
- enum AVSampleFormat req = s->avctx->request_sample_fmt;
- int need32 = s->flac_stream_info.bps > 16;
- int want32 = av_get_bytes_per_sample(req) > 2;
- int planar = av_sample_fmt_is_planar(req);
-
- if (need32 || want32) {
- if (planar)
- s->avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
- else
- s->avctx->sample_fmt = AV_SAMPLE_FMT_S32;
- s->sample_shift = 32 - s->flac_stream_info.bps;
- } else {
- if (planar)
- s->avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
- else
- s->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
- s->sample_shift = 16 - s->flac_stream_info.bps;
- }
-}
-
-static av_cold int flac_decode_init(AVCodecContext *avctx)
-{
- enum FLACExtradataFormat format;
- uint8_t *streaminfo;
- int ret;
- FLACContext *s = avctx->priv_data;
- s->avctx = avctx;
-
- /* for now, the raw FLAC header is allowed to be passed to the decoder as
- frame data instead of extradata. */
- if (!avctx->extradata)
- return 0;
-
- if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo))
- return AVERROR_INVALIDDATA;
-
- /* initialize based on the demuxer-supplied streamdata header */
- ff_flac_parse_streaminfo(avctx, &s->flac_stream_info, streaminfo);
- ret = allocate_buffers(s);
- if (ret < 0)
- return ret;
- flac_set_bps(s);
- ff_flacdsp_init(&s->dsp, avctx->sample_fmt,
- s->flac_stream_info.channels, s->flac_stream_info.bps);
- s->got_streaminfo = 1;
-
- return 0;
-}
-
-static void dump_headers(AVCodecContext *avctx, FLACStreaminfo *s)
-{
- av_log(avctx, AV_LOG_DEBUG, " Max Blocksize: %d\n", s->max_blocksize);
- av_log(avctx, AV_LOG_DEBUG, " Max Framesize: %d\n", s->max_framesize);
- av_log(avctx, AV_LOG_DEBUG, " Samplerate: %d\n", s->samplerate);
- av_log(avctx, AV_LOG_DEBUG, " Channels: %d\n", s->channels);
- av_log(avctx, AV_LOG_DEBUG, " Bits: %d\n", s->bps);
-}
-
-static int allocate_buffers(FLACContext *s)
-{
- int buf_size;
- int ret;
-
- av_assert0(s->flac_stream_info.max_blocksize);
-
- buf_size = av_samples_get_buffer_size(NULL, s->flac_stream_info.channels,
- s->flac_stream_info.max_blocksize,
- AV_SAMPLE_FMT_S32P, 0);
- if (buf_size < 0)
- return buf_size;
-
- av_fast_malloc(&s->decoded_buffer, &s->decoded_buffer_size, buf_size);
- if (!s->decoded_buffer)
- return AVERROR(ENOMEM);
-
- ret = av_samples_fill_arrays((uint8_t **)s->decoded, NULL,
- s->decoded_buffer,
- s->flac_stream_info.channels,
- s->flac_stream_info.max_blocksize,
- AV_SAMPLE_FMT_S32P, 0);
- return ret < 0 ? ret : 0;
-}
-
-/**
- * Parse the STREAMINFO from an inline header.
- * @param s the flac decoding context
- * @param buf input buffer, starting with the "fLaC" marker
- * @param buf_size buffer size
- * @return non-zero if metadata is invalid
- */
-static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size)
-{
- int metadata_type, metadata_size, ret;
-
- if (buf_size < FLAC_STREAMINFO_SIZE+8) {
- /* need more data */
- return 0;
- }
- flac_parse_block_header(&buf[4], NULL, &metadata_type, &metadata_size);
- if (metadata_type != FLAC_METADATA_TYPE_STREAMINFO ||
- metadata_size != FLAC_STREAMINFO_SIZE) {
- return AVERROR_INVALIDDATA;
- }
- ff_flac_parse_streaminfo(s->avctx, &s->flac_stream_info, &buf[8]);
- ret = allocate_buffers(s);
- if (ret < 0)
- return ret;
- flac_set_bps(s);
- ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt,
- s->flac_stream_info.channels, s->flac_stream_info.bps);
- s->got_streaminfo = 1;
-
- return 0;
-}
-
-/**
- * Determine the size of an inline header.
- * @param buf input buffer, starting with the "fLaC" marker
- * @param buf_size buffer size
- * @return number of bytes in the header, or 0 if more data is needed
- */
-static int get_metadata_size(const uint8_t *buf, int buf_size)
-{
- int metadata_last, metadata_size;
- const uint8_t *buf_end = buf + buf_size;
-
- buf += 4;
- do {
- if (buf_end - buf < 4)
- return 0;
- flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size);
- buf += 4;
- if (buf_end - buf < metadata_size) {
- /* need more data in order to read the complete header */
- return 0;
- }
- buf += metadata_size;
- } while (!metadata_last);
-
- return buf_size - (buf_end - buf);
-}
-
-static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order)
-{
- int i, tmp, partition, method_type, rice_order;
- int rice_bits, rice_esc;
- int samples;
-
- method_type = get_bits(&s->gb, 2);
- if (method_type > 1) {
- av_log(s->avctx, AV_LOG_ERROR, "illegal residual coding method %d\n",
- method_type);
- return AVERROR_INVALIDDATA;
- }
-
- rice_order = get_bits(&s->gb, 4);
-
- samples= s->blocksize >> rice_order;
- if (samples << rice_order != s->blocksize) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid rice order: %i blocksize %i\n",
- rice_order, s->blocksize);
- return AVERROR_INVALIDDATA;
- }
-
- if (pred_order > samples) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid predictor order: %i > %i\n",
- pred_order, samples);
- return AVERROR_INVALIDDATA;
- }
-
- rice_bits = 4 + method_type;
- rice_esc = (1 << rice_bits) - 1;
-
- decoded += pred_order;
- i= pred_order;
- for (partition = 0; partition < (1 << rice_order); partition++) {
- tmp = get_bits(&s->gb, rice_bits);
- if (tmp == rice_esc) {
- tmp = get_bits(&s->gb, 5);
- for (; i < samples; i++)
- *decoded++ = get_sbits_long(&s->gb, tmp);
- } else {
- for (; i < samples; i++) {
- *decoded++ = get_sr_golomb_flac(&s->gb, tmp, INT_MAX, 0);
- }
- }
- i= 0;
- }
-
- return 0;
-}
-
-static int decode_subframe_fixed(FLACContext *s, int32_t *decoded,
- int pred_order, int bps)
-{
- const int blocksize = s->blocksize;
- unsigned av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d);
- int i;
- int ret;
-
- /* warm up samples */
- for (i = 0; i < pred_order; i++) {
- decoded[i] = get_sbits_long(&s->gb, bps);
- }
-
- if ((ret = decode_residuals(s, decoded, pred_order)) < 0)
- return ret;
-
- if (pred_order > 0)
- a = decoded[pred_order-1];
- if (pred_order > 1)
- b = a - decoded[pred_order-2];
- if (pred_order > 2)
- c = b - decoded[pred_order-2] + decoded[pred_order-3];
- if (pred_order > 3)
- d = c - decoded[pred_order-2] + 2*decoded[pred_order-3] - decoded[pred_order-4];
-
- switch (pred_order) {
- case 0:
- break;
- case 1:
- for (i = pred_order; i < blocksize; i++)
- decoded[i] = a += decoded[i];
- break;
- case 2:
- for (i = pred_order; i < blocksize; i++)
- decoded[i] = a += b += decoded[i];
- break;
- case 3:
- for (i = pred_order; i < blocksize; i++)
- decoded[i] = a += b += c += decoded[i];
- break;
- case 4:
- for (i = pred_order; i < blocksize; i++)
- decoded[i] = a += b += c += d += decoded[i];
- break;
- default:
- av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order);
- return AVERROR_INVALIDDATA;
- }
-
- return 0;
-}
-
-static void lpc_analyze_remodulate(int32_t *decoded, const int coeffs[32],
- int order, int qlevel, int len, int bps)
-{
- int i, j;
- int ebps = 1 << (bps-1);
- unsigned sigma = 0;
-
- for (i = order; i < len; i++)
- sigma |= decoded[i] + ebps;
-
- if (sigma < 2*ebps)
- return;
-
- for (i = len - 1; i >= order; i--) {
- int64_t p = 0;
- for (j = 0; j < order; j++)
- p += coeffs[j] * (int64_t)decoded[i-order+j];
- decoded[i] -= p >> qlevel;
- }
- for (i = order; i < len; i++, decoded++) {
- int32_t p = 0;
- for (j = 0; j < order; j++)
- p += coeffs[j] * (uint32_t)decoded[j];
- decoded[j] += p >> qlevel;
- }
-}
-
-static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order,
- int bps)
-{
- int i, ret;
- int coeff_prec, qlevel;
- int coeffs[32];
-
- /* warm up samples */
- for (i = 0; i < pred_order; i++) {
- decoded[i] = get_sbits_long(&s->gb, bps);
- }
-
- coeff_prec = get_bits(&s->gb, 4) + 1;
- if (coeff_prec == 16) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid coeff precision\n");
- return AVERROR_INVALIDDATA;
- }
- qlevel = get_sbits(&s->gb, 5);
- if (qlevel < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "qlevel %d not supported, maybe buggy stream\n",
- qlevel);
- return AVERROR_INVALIDDATA;
- }
-
- for (i = 0; i < pred_order; i++) {
- coeffs[pred_order - i - 1] = get_sbits(&s->gb, coeff_prec);
- }
-
- if ((ret = decode_residuals(s, decoded, pred_order)) < 0)
- return ret;
-
- if ( ( s->buggy_lpc && s->flac_stream_info.bps <= 16)
- || ( !s->buggy_lpc && bps <= 16
- && bps + coeff_prec + av_log2(pred_order) <= 32)) {
- s->dsp.lpc16(decoded, coeffs, pred_order, qlevel, s->blocksize);
- } else {
- s->dsp.lpc32(decoded, coeffs, pred_order, qlevel, s->blocksize);
- if (s->flac_stream_info.bps <= 16)
- lpc_analyze_remodulate(decoded, coeffs, pred_order, qlevel, s->blocksize, bps);
- }
-
- return 0;
-}
-
-static inline int decode_subframe(FLACContext *s, int channel)
-{
- int32_t *decoded = s->decoded[channel];
- int type, wasted = 0;
- int bps = s->flac_stream_info.bps;
- int i, tmp, ret;
-
- if (channel == 0) {
- if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE)
- bps++;
- } else {
- if (s->ch_mode == FLAC_CHMODE_LEFT_SIDE || s->ch_mode == FLAC_CHMODE_MID_SIDE)
- bps++;
- }
-
- if (get_bits1(&s->gb)) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid subframe padding\n");
- return AVERROR_INVALIDDATA;
- }
- type = get_bits(&s->gb, 6);
-
- if (get_bits1(&s->gb)) {
- int left = get_bits_left(&s->gb);
- if ( left <= 0 ||
- (left < bps && !show_bits_long(&s->gb, left)) ||
- !show_bits_long(&s->gb, bps)) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Invalid number of wasted bits > available bits (%d) - left=%d\n",
- bps, left);
- return AVERROR_INVALIDDATA;
- }
- wasted = 1 + get_unary(&s->gb, 1, get_bits_left(&s->gb));
- bps -= wasted;
- }
- if (bps > 32) {
- avpriv_report_missing_feature(s->avctx, "Decorrelated bit depth > 32");
- return AVERROR_PATCHWELCOME;
- }
-
-//FIXME use av_log2 for types
- if (type == 0) {
- tmp = get_sbits_long(&s->gb, bps);
- for (i = 0; i < s->blocksize; i++)
- decoded[i] = tmp;
- } else if (type == 1) {
- for (i = 0; i < s->blocksize; i++)
- decoded[i] = get_sbits_long(&s->gb, bps);
- } else if ((type >= 8) && (type <= 12)) {
- if ((ret = decode_subframe_fixed(s, decoded, type & ~0x8, bps)) < 0)
- return ret;
- } else if (type >= 32) {
- if ((ret = decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps)) < 0)
- return ret;
- } else {
- av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (wasted) {
- int i;
- for (i = 0; i < s->blocksize; i++)
- decoded[i] = (unsigned)decoded[i] << wasted;
- }
-
- return 0;
-}
-
-static int decode_frame(FLACContext *s)
-{
- int i, ret;
- GetBitContext *gb = &s->gb;
- FLACFrameInfo fi;
-
- if ((ret = ff_flac_decode_frame_header(s->avctx, gb, &fi, 0)) < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid frame header\n");
- return ret;
- }
-
- if ( s->flac_stream_info.channels
- && fi.channels != s->flac_stream_info.channels
- && s->got_streaminfo) {
- s->flac_stream_info.channels = s->avctx->channels = fi.channels;
- ff_flac_set_channel_layout(s->avctx);
- ret = allocate_buffers(s);
- if (ret < 0)
- return ret;
- }
- s->flac_stream_info.channels = s->avctx->channels = fi.channels;
- if (!s->avctx->channel_layout)
- ff_flac_set_channel_layout(s->avctx);
- s->ch_mode = fi.ch_mode;
-
- if (!s->flac_stream_info.bps && !fi.bps) {
- av_log(s->avctx, AV_LOG_ERROR, "bps not found in STREAMINFO or frame header\n");
- return AVERROR_INVALIDDATA;
- }
- if (!fi.bps) {
- fi.bps = s->flac_stream_info.bps;
- } else if (s->flac_stream_info.bps && fi.bps != s->flac_stream_info.bps) {
- av_log(s->avctx, AV_LOG_ERROR, "switching bps mid-stream is not "
- "supported\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (!s->flac_stream_info.bps) {
- s->flac_stream_info.bps = s->avctx->bits_per_raw_sample = fi.bps;
- flac_set_bps(s);
- }
-
- if (!s->flac_stream_info.max_blocksize)
- s->flac_stream_info.max_blocksize = FLAC_MAX_BLOCKSIZE;
- if (fi.blocksize > s->flac_stream_info.max_blocksize) {
- av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", fi.blocksize,
- s->flac_stream_info.max_blocksize);
- return AVERROR_INVALIDDATA;
- }
- s->blocksize = fi.blocksize;
-
- if (!s->flac_stream_info.samplerate && !fi.samplerate) {
- av_log(s->avctx, AV_LOG_ERROR, "sample rate not found in STREAMINFO"
- " or frame header\n");
- return AVERROR_INVALIDDATA;
- }
- if (fi.samplerate == 0)
- fi.samplerate = s->flac_stream_info.samplerate;
- s->flac_stream_info.samplerate = s->avctx->sample_rate = fi.samplerate;
-
- if (!s->got_streaminfo) {
- ret = allocate_buffers(s);
- if (ret < 0)
- return ret;
- s->got_streaminfo = 1;
- dump_headers(s->avctx, &s->flac_stream_info);
- }
- ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt,
- s->flac_stream_info.channels, s->flac_stream_info.bps);
-
-// dump_headers(s->avctx, &s->flac_stream_info);
-
- /* subframes */
- for (i = 0; i < s->flac_stream_info.channels; i++) {
- if ((ret = decode_subframe(s, i)) < 0)
- return ret;
- }
-
- align_get_bits(gb);
-
- /* frame footer */
- skip_bits(gb, 16); /* data crc */
-
- return 0;
-}
-
-static int flac_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- AVFrame *frame = data;
- ThreadFrame tframe = { .f = data };
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- FLACContext *s = avctx->priv_data;
- int bytes_read = 0;
- int ret;
-
- *got_frame_ptr = 0;
-
- if (s->flac_stream_info.max_framesize == 0) {
- s->flac_stream_info.max_framesize =
- ff_flac_get_max_frame_size(s->flac_stream_info.max_blocksize ? s->flac_stream_info.max_blocksize : FLAC_MAX_BLOCKSIZE,
- FLAC_MAX_CHANNELS, 32);
- }
-
- if (buf_size > 5 && !memcmp(buf, "\177FLAC", 5)) {
- av_log(s->avctx, AV_LOG_DEBUG, "skipping flac header packet 1\n");
- return buf_size;
- }
-
- if (buf_size > 0 && (*buf & 0x7F) == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
- av_log(s->avctx, AV_LOG_DEBUG, "skipping vorbis comment\n");
- return buf_size;
- }
-
- /* check that there is at least the smallest decodable amount of data.
- this amount corresponds to the smallest valid FLAC frame possible.
- FF F8 69 02 00 00 9A 00 00 34 46 */
- if (buf_size < FLAC_MIN_FRAME_SIZE)
- return buf_size;
-
- /* check for inline header */
- if (AV_RB32(buf) == MKBETAG('f','L','a','C')) {
- if (!s->got_streaminfo && (ret = parse_streaminfo(s, buf, buf_size))) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid header\n");
- return ret;
- }
- return get_metadata_size(buf, buf_size);
- }
-
- /* decode frame */
- if ((ret = init_get_bits8(&s->gb, buf, buf_size)) < 0)
- return ret;
- if ((ret = decode_frame(s)) < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n");
- return ret;
- }
- bytes_read = get_bits_count(&s->gb)/8;
-
- if ((s->avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_COMPLIANT)) &&
- av_crc(av_crc_get_table(AV_CRC_16_ANSI),
- 0, buf, bytes_read)) {
- av_log(s->avctx, AV_LOG_ERROR, "CRC error at PTS %"PRId64"\n", avpkt->pts);
- if (s->avctx->err_recognition & AV_EF_EXPLODE)
- return AVERROR_INVALIDDATA;
- }
-
- /* get output buffer */
- frame->nb_samples = s->blocksize;
- if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
- return ret;
-
- s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded,
- s->flac_stream_info.channels,
- s->blocksize, s->sample_shift);
-
- if (bytes_read > buf_size) {
- av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size);
- return AVERROR_INVALIDDATA;
- }
- if (bytes_read < buf_size) {
- av_log(s->avctx, AV_LOG_DEBUG, "underread: %d orig size: %d\n",
- buf_size - bytes_read, buf_size);
- }
-
- *got_frame_ptr = 1;
-
- return bytes_read;
-}
-
-static int init_thread_copy(AVCodecContext *avctx)
-{
- FLACContext *s = avctx->priv_data;
- s->decoded_buffer = NULL;
- s->decoded_buffer_size = 0;
- s->avctx = avctx;
- if (s->flac_stream_info.max_blocksize)
- return allocate_buffers(s);
- return 0;
-}
-
-static av_cold int flac_decode_close(AVCodecContext *avctx)
-{
- FLACContext *s = avctx->priv_data;
-
- av_freep(&s->decoded_buffer);
-
- return 0;
-}
-
-static const AVOption options[] = {
-{ "use_buggy_lpc", "emulate old buggy lavc behavior", offsetof(FLACContext, buggy_lpc), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM },
-{ NULL },
-};
-
-static const AVClass flac_decoder_class = {
- "FLAC decoder",
- av_default_item_name,
- options,
- LIBAVUTIL_VERSION_INT,
-};
-
-AVCodec ff_flac_decoder = {
- .name = "flac",
- .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_FLAC,
- .priv_data_size = sizeof(FLACContext),
- .init = flac_decode_init,
- .close = flac_decode_close,
- .decode = flac_decode_frame,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
- .capabilities = 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,
- AV_SAMPLE_FMT_S32P,
- AV_SAMPLE_FMT_NONE },
- .priv_class = &flac_decoder_class,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/flicvideo.c b/ffmpeg-2-8-11/libavcodec/flicvideo.c
deleted file mode 100644
index 3e0573a..0000000
--- a/ffmpeg-2-8-11/libavcodec/flicvideo.c
+++ /dev/null
@@ -1,818 +0,0 @@
-/*
- * FLI/FLC Animation Video Decoder
- * Copyright (c) 2003, 2004 The FFmpeg Project
- *
- * 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
- * Autodesk Animator FLI/FLC Video Decoder
- * by Mike Melanson (melanson at pcisys.net)
- * for more information on the .fli/.flc file format and all of its many
- * variations, visit:
- * http://www.compuphase.com/flic.htm
- *
- * This decoder outputs PAL8/RGB555/RGB565 and maybe one day RGB24
- * colorspace data, depending on the FLC. To use this decoder, be
- * sure that your demuxer sends the FLI file header to the decoder via
- * the extradata chunk in AVCodecContext. The chunk should be 128 bytes
- * large. The only exception is for FLI files from the game "Magic Carpet",
- * in which the header is only 12 bytes.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "libavutil/intreadwrite.h"
-#include "avcodec.h"
-#include "bytestream.h"
-#include "internal.h"
-#include "mathops.h"
-
-#define FLI_256_COLOR 4
-#define FLI_DELTA 7
-#define FLI_COLOR 11
-#define FLI_LC 12
-#define FLI_BLACK 13
-#define FLI_BRUN 15
-#define FLI_COPY 16
-#define FLI_MINI 18
-#define FLI_DTA_BRUN 25
-#define FLI_DTA_COPY 26
-#define FLI_DTA_LC 27
-
-#define FLI_TYPE_CODE (0xAF11)
-#define FLC_FLX_TYPE_CODE (0xAF12)
-#define FLC_DTA_TYPE_CODE (0xAF44) /* Marks an "Extended FLC" comes from Dave's Targa Animator (DTA) */
-#define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE (0xAF13)
-
-#define CHECK_PIXEL_PTR(n) \
- if (pixel_ptr + n > pixel_limit) { \
- av_log (s->avctx, AV_LOG_ERROR, "Invalid pixel_ptr = %d > pixel_limit = %d\n", \
- pixel_ptr + n, pixel_limit); \
- return AVERROR_INVALIDDATA; \
- } \
-
-typedef struct FlicDecodeContext {
- AVCodecContext *avctx;
- AVFrame *frame;
-
- unsigned int palette[256];
- int new_palette;
- int fli_type; /* either 0xAF11 or 0xAF12, affects palette resolution */
-} FlicDecodeContext;
-
-static av_cold int flic_decode_init(AVCodecContext *avctx)
-{
- FlicDecodeContext *s = avctx->priv_data;
- unsigned char *fli_header = (unsigned char *)avctx->extradata;
- int depth;
-
- if (avctx->extradata_size != 0 &&
- avctx->extradata_size != 12 &&
- avctx->extradata_size != 128 &&
- avctx->extradata_size != 256 &&
- avctx->extradata_size != 904 &&
- avctx->extradata_size != 1024) {
- av_log(avctx, AV_LOG_ERROR, "Unexpected extradata size %d\n", avctx->extradata_size);
- return AVERROR_INVALIDDATA;
- }
-
- s->avctx = avctx;
-
- if (s->avctx->extradata_size == 12) {
- /* special case for magic carpet FLIs */
- s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE;
- depth = 8;
- } else if (avctx->extradata_size == 1024) {
- uint8_t *ptr = avctx->extradata;
- int i;
-
- for (i = 0; i < 256; i++) {
- s->palette[i] = AV_RL32(ptr);
- ptr += 4;
- }
- depth = 8;
- /* FLI in MOV, see e.g. FFmpeg trac issue #626 */
- } else if (avctx->extradata_size == 0 ||
- avctx->extradata_size == 256 ||
- /* see FFmpeg ticket #1234 */
- avctx->extradata_size == 904) {
- s->fli_type = FLI_TYPE_CODE;
- depth = 8;
- } else {
- s->fli_type = AV_RL16(&fli_header[4]);
- depth = AV_RL16(&fli_header[12]);
- }
-
- if (depth == 0) {
- depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */
- }
-
- if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) {
- depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */
- }
-
- switch (depth) {
- case 8 : avctx->pix_fmt = AV_PIX_FMT_PAL8; break;
- case 15 : avctx->pix_fmt = AV_PIX_FMT_RGB555; break;
- case 16 : avctx->pix_fmt = AV_PIX_FMT_RGB565; break;
- case 24 : avctx->pix_fmt = AV_PIX_FMT_BGR24; /* Supposedly BGR, but havent any files to test with */
- avpriv_request_sample(avctx, "24Bpp FLC/FLX");
- return AVERROR_PATCHWELCOME;
- default :
- av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
- return AVERROR_INVALIDDATA;
- }
-
- s->frame = av_frame_alloc();
- if (!s->frame)
- return AVERROR(ENOMEM);
-
- s->new_palette = 0;
-
- return 0;
-}
-
-static int flic_decode_frame_8BPP(AVCodecContext *avctx,
- void *data, int *got_frame,
- const uint8_t *buf, int buf_size)
-{
- FlicDecodeContext *s = avctx->priv_data;
-
- GetByteContext g2;
- int pixel_ptr;
- int palette_ptr;
- unsigned char palette_idx1;
- unsigned char palette_idx2;
-
- unsigned int frame_size;
- int num_chunks;
-
- unsigned int chunk_size;
- int chunk_type;
-
- int i, j, ret;
-
- int color_packets;
- int color_changes;
- int color_shift;
- unsigned char r, g, b;
-
- int lines;
- int compressed_lines;
- int starting_line;
- signed short line_packets;
- int y_ptr;
- int byte_run;
- int pixel_skip;
- int pixel_countdown;
- unsigned char *pixels;
- unsigned int pixel_limit;
-
- bytestream2_init(&g2, buf, buf_size);
-
- if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
- return ret;
-
- pixels = s->frame->data[0];
- pixel_limit = s->avctx->height * s->frame->linesize[0];
- if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + AV_INPUT_BUFFER_PADDING_SIZE))
- return AVERROR_INVALIDDATA;
- frame_size = bytestream2_get_le32(&g2);
- if (frame_size > buf_size)
- frame_size = buf_size;
- bytestream2_skip(&g2, 2); /* skip the magic number */
- num_chunks = bytestream2_get_le16(&g2);
- bytestream2_skip(&g2, 8); /* skip padding */
-
- frame_size -= 16;
-
- /* iterate through the chunks */
- while ((frame_size >= 6) && (num_chunks > 0) &&
- bytestream2_get_bytes_left(&g2) >= 4) {
- int stream_ptr_after_chunk;
- chunk_size = bytestream2_get_le32(&g2);
- if (chunk_size > frame_size) {
- av_log(avctx, AV_LOG_WARNING,
- "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
- chunk_size = frame_size;
- }
- stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
-
- chunk_type = bytestream2_get_le16(&g2);
-
- switch (chunk_type) {
- case FLI_256_COLOR:
- case FLI_COLOR:
- /* check special case: If this file is from the Magic Carpet
- * game and uses 6-bit colors even though it reports 256-color
- * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
- * initialization) */
- if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE))
- color_shift = 0;
- else
- color_shift = 2;
- /* set up the palette */
- color_packets = bytestream2_get_le16(&g2);
- palette_ptr = 0;
- for (i = 0; i < color_packets; i++) {
- /* first byte is how many colors to skip */
- palette_ptr += bytestream2_get_byte(&g2);
-
- /* next byte indicates how many entries to change */
- color_changes = bytestream2_get_byte(&g2);
-
- /* if there are 0 color changes, there are actually 256 */
- if (color_changes == 0)
- color_changes = 256;
-
- if (bytestream2_tell(&g2) + color_changes * 3 > stream_ptr_after_chunk)
- break;
-
- for (j = 0; j < color_changes; j++) {
- unsigned int entry;
-
- /* wrap around, for good measure */
- if ((unsigned)palette_ptr >= 256)
- palette_ptr = 0;
-
- r = bytestream2_get_byte(&g2) << color_shift;
- g = bytestream2_get_byte(&g2) << color_shift;
- b = bytestream2_get_byte(&g2) << color_shift;
- entry = 0xFFU << 24 | r << 16 | g << 8 | b;
- if (color_shift == 2)
- entry |= entry >> 6 & 0x30303;
- if (s->palette[palette_ptr] != entry)
- s->new_palette = 1;
- s->palette[palette_ptr++] = entry;
- }
- }
- break;
-
- case FLI_DELTA:
- y_ptr = 0;
- compressed_lines = bytestream2_get_le16(&g2);
- while (compressed_lines > 0) {
- if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
- break;
- line_packets = bytestream2_get_le16(&g2);
- if ((line_packets & 0xC000) == 0xC000) {
- // line skip opcode
- line_packets = -line_packets;
- y_ptr += line_packets * s->frame->linesize[0];
- } else if ((line_packets & 0xC000) == 0x4000) {
- av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets);
- } else if ((line_packets & 0xC000) == 0x8000) {
- // "last byte" opcode
- pixel_ptr= y_ptr + s->frame->linesize[0] - 1;
- CHECK_PIXEL_PTR(0);
- pixels[pixel_ptr] = line_packets & 0xff;
- } else {
- compressed_lines--;
- pixel_ptr = y_ptr;
- CHECK_PIXEL_PTR(0);
- pixel_countdown = s->avctx->width;
- for (i = 0; i < line_packets; i++) {
- if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
- break;
- /* account for the skip bytes */
- pixel_skip = bytestream2_get_byte(&g2);
- pixel_ptr += pixel_skip;
- pixel_countdown -= pixel_skip;
- byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
- if (byte_run < 0) {
- byte_run = -byte_run;
- palette_idx1 = bytestream2_get_byte(&g2);
- palette_idx2 = bytestream2_get_byte(&g2);
- CHECK_PIXEL_PTR(byte_run * 2);
- for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
- pixels[pixel_ptr++] = palette_idx1;
- pixels[pixel_ptr++] = palette_idx2;
- }
- } else {
- CHECK_PIXEL_PTR(byte_run * 2);
- if (bytestream2_tell(&g2) + byte_run * 2 > stream_ptr_after_chunk)
- break;
- for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
- pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
- }
- }
- }
-
- y_ptr += s->frame->linesize[0];
- }
- }
- break;
-
- case FLI_LC:
- /* line compressed */
- starting_line = bytestream2_get_le16(&g2);
- y_ptr = 0;
- y_ptr += starting_line * s->frame->linesize[0];
-
- compressed_lines = bytestream2_get_le16(&g2);
- while (compressed_lines > 0) {
- pixel_ptr = y_ptr;
- CHECK_PIXEL_PTR(0);
- pixel_countdown = s->avctx->width;
- if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
- break;
- line_packets = bytestream2_get_byte(&g2);
- if (line_packets > 0) {
- for (i = 0; i < line_packets; i++) {
- /* account for the skip bytes */
- if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
- break;
- pixel_skip = bytestream2_get_byte(&g2);
- pixel_ptr += pixel_skip;
- pixel_countdown -= pixel_skip;
- byte_run = sign_extend(bytestream2_get_byte(&g2),8);
- if (byte_run > 0) {
- CHECK_PIXEL_PTR(byte_run);
- if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
- break;
- for (j = 0; j < byte_run; j++, pixel_countdown--) {
- pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
- }
- } else if (byte_run < 0) {
- byte_run = -byte_run;
- palette_idx1 = bytestream2_get_byte(&g2);
- CHECK_PIXEL_PTR(byte_run);
- for (j = 0; j < byte_run; j++, pixel_countdown--) {
- pixels[pixel_ptr++] = palette_idx1;
- }
- }
- }
- }
-
- y_ptr += s->frame->linesize[0];
- compressed_lines--;
- }
- break;
-
- case FLI_BLACK:
- /* set the whole frame to color 0 (which is usually black) */
- memset(pixels, 0,
- s->frame->linesize[0] * s->avctx->height);
- break;
-
- case FLI_BRUN:
- /* Byte run compression: This chunk type only occurs in the first
- * FLI frame and it will update the entire frame. */
- y_ptr = 0;
- for (lines = 0; lines < s->avctx->height; lines++) {
- pixel_ptr = y_ptr;
- /* disregard the line packets; instead, iterate through all
- * pixels on a row */
- bytestream2_skip(&g2, 1);
- pixel_countdown = s->avctx->width;
- while (pixel_countdown > 0) {
- if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
- break;
- byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
- if (!byte_run) {
- av_log(avctx, AV_LOG_ERROR, "Invalid byte run value.\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (byte_run > 0) {
- palette_idx1 = bytestream2_get_byte(&g2);
- CHECK_PIXEL_PTR(byte_run);
- for (j = 0; j < byte_run; j++) {
- pixels[pixel_ptr++] = palette_idx1;
- pixel_countdown--;
- if (pixel_countdown < 0)
- av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
- pixel_countdown, lines);
- }
- } else { /* copy bytes if byte_run < 0 */
- byte_run = -byte_run;
- CHECK_PIXEL_PTR(byte_run);
- if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
- break;
- for (j = 0; j < byte_run; j++) {
- pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
- pixel_countdown--;
- if (pixel_countdown < 0)
- av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
- pixel_countdown, lines);
- }
- }
- }
-
- y_ptr += s->frame->linesize[0];
- }
- break;
-
- case FLI_COPY:
- /* copy the chunk (uncompressed frame) */
- if (chunk_size - 6 != s->avctx->width * s->avctx->height) {
- av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
- "has incorrect size, skipping chunk\n", chunk_size - 6);
- bytestream2_skip(&g2, chunk_size - 6);
- } else {
- for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
- y_ptr += s->frame->linesize[0]) {
- bytestream2_get_buffer(&g2, &pixels[y_ptr],
- s->avctx->width);
- }
- }
- break;
-
- case FLI_MINI:
- /* some sort of a thumbnail? disregard this chunk... */
- break;
-
- default:
- av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
- break;
- }
-
- if (stream_ptr_after_chunk - bytestream2_tell(&g2) > 0)
- bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
-
- frame_size -= chunk_size;
- num_chunks--;
- }
-
- /* by the end of the chunk, the stream ptr should equal the frame
- * size (minus 1 or 2, possibly); if it doesn't, issue a warning */
- if (bytestream2_get_bytes_left(&g2) > 2)
- av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
- "and final chunk ptr = %d\n", buf_size,
- buf_size - bytestream2_get_bytes_left(&g2));
-
- /* make the palette available on the way out */
- memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
- if (s->new_palette) {
- s->frame->palette_has_changed = 1;
- s->new_palette = 0;
- }
-
- if ((ret = av_frame_ref(data, s->frame)) < 0)
- return ret;
-
- *got_frame = 1;
-
- return buf_size;
-}
-
-static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
- void *data, int *got_frame,
- const uint8_t *buf, int buf_size)
-{
- /* Note, the only difference between the 15Bpp and 16Bpp */
- /* Format is the pixel format, the packets are processed the same. */
- FlicDecodeContext *s = avctx->priv_data;
-
- GetByteContext g2;
- int pixel_ptr;
- unsigned char palette_idx1;
-
- unsigned int frame_size;
- int num_chunks;
-
- unsigned int chunk_size;
- int chunk_type;
-
- int i, j, ret;
-
- int lines;
- int compressed_lines;
- signed short line_packets;
- int y_ptr;
- int byte_run;
- int pixel_skip;
- int pixel_countdown;
- unsigned char *pixels;
- int pixel;
- unsigned int pixel_limit;
-
- bytestream2_init(&g2, buf, buf_size);
-
- if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
- return ret;
-
- pixels = s->frame->data[0];
- pixel_limit = s->avctx->height * s->frame->linesize[0];
-
- frame_size = bytestream2_get_le32(&g2);
- bytestream2_skip(&g2, 2); /* skip the magic number */
- num_chunks = bytestream2_get_le16(&g2);
- bytestream2_skip(&g2, 8); /* skip padding */
- if (frame_size > buf_size)
- frame_size = buf_size;
-
- frame_size -= 16;
-
- /* iterate through the chunks */
- while ((frame_size > 0) && (num_chunks > 0) &&
- bytestream2_get_bytes_left(&g2) >= 4) {
- int stream_ptr_after_chunk;
- chunk_size = bytestream2_get_le32(&g2);
- if (chunk_size > frame_size) {
- av_log(avctx, AV_LOG_WARNING,
- "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
- chunk_size = frame_size;
- }
- stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
-
- chunk_type = bytestream2_get_le16(&g2);
-
-
- switch (chunk_type) {
- case FLI_256_COLOR:
- case FLI_COLOR:
- /* For some reason, it seems that non-palettized flics do
- * include one of these chunks in their first frame.
- * Why I do not know, it seems rather extraneous. */
- ff_dlog(avctx,
- "Unexpected Palette chunk %d in non-palettized FLC\n",
- chunk_type);
- bytestream2_skip(&g2, chunk_size - 6);
- break;
-
- case FLI_DELTA:
- case FLI_DTA_LC:
- y_ptr = 0;
- compressed_lines = bytestream2_get_le16(&g2);
- while (compressed_lines > 0) {
- if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
- break;
- line_packets = bytestream2_get_le16(&g2);
- if (line_packets < 0) {
- line_packets = -line_packets;
- y_ptr += line_packets * s->frame->linesize[0];
- } else {
- compressed_lines--;
- pixel_ptr = y_ptr;
- CHECK_PIXEL_PTR(0);
- pixel_countdown = s->avctx->width;
- for (i = 0; i < line_packets; i++) {
- /* account for the skip bytes */
- if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
- break;
- pixel_skip = bytestream2_get_byte(&g2);
- pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
- pixel_countdown -= pixel_skip;
- byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
- if (byte_run < 0) {
- byte_run = -byte_run;
- pixel = bytestream2_get_le16(&g2);
- CHECK_PIXEL_PTR(2 * byte_run);
- for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
- *((signed short*)(&pixels[pixel_ptr])) = pixel;
- pixel_ptr += 2;
- }
- } else {
- if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
- break;
- CHECK_PIXEL_PTR(2 * byte_run);
- for (j = 0; j < byte_run; j++, pixel_countdown--) {
- *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
- pixel_ptr += 2;
- }
- }
- }
-
- y_ptr += s->frame->linesize[0];
- }
- }
- break;
-
- case FLI_LC:
- av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
- bytestream2_skip(&g2, chunk_size - 6);
- break;
-
- case FLI_BLACK:
- /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */
- memset(pixels, 0x0000,
- s->frame->linesize[0] * s->avctx->height);
- break;
-
- case FLI_BRUN:
- y_ptr = 0;
- for (lines = 0; lines < s->avctx->height; lines++) {
- pixel_ptr = y_ptr;
- /* disregard the line packets; instead, iterate through all
- * pixels on a row */
- bytestream2_skip(&g2, 1);
- pixel_countdown = (s->avctx->width * 2);
-
- while (pixel_countdown > 0) {
- if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
- break;
- byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
- if (byte_run > 0) {
- palette_idx1 = bytestream2_get_byte(&g2);
- CHECK_PIXEL_PTR(byte_run);
- for (j = 0; j < byte_run; j++) {
- pixels[pixel_ptr++] = palette_idx1;
- pixel_countdown--;
- if (pixel_countdown < 0)
- av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
- pixel_countdown, lines);
- }
- } else { /* copy bytes if byte_run < 0 */
- byte_run = -byte_run;
- if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
- break;
- CHECK_PIXEL_PTR(byte_run);
- for (j = 0; j < byte_run; j++) {
- palette_idx1 = bytestream2_get_byte(&g2);
- pixels[pixel_ptr++] = palette_idx1;
- pixel_countdown--;
- if (pixel_countdown < 0)
- av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
- pixel_countdown, lines);
- }
- }
- }
-
- /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed.
- * This does not give us any good opportunity to perform word endian conversion
- * during decompression. So if it is required (i.e., this is not a LE target, we do
- * a second pass over the line here, swapping the bytes.
- */
-#if HAVE_BIGENDIAN
- pixel_ptr = y_ptr;
- pixel_countdown = s->avctx->width;
- while (pixel_countdown > 0) {
- *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]);
- pixel_ptr += 2;
- }
-#endif
- y_ptr += s->frame->linesize[0];
- }
- break;
-
- case FLI_DTA_BRUN:
- y_ptr = 0;
- for (lines = 0; lines < s->avctx->height; lines++) {
- pixel_ptr = y_ptr;
- /* disregard the line packets; instead, iterate through all
- * pixels on a row */
- bytestream2_skip(&g2, 1);
- pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
-
- while (pixel_countdown > 0) {
- if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
- break;
- byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
- if (byte_run > 0) {
- pixel = bytestream2_get_le16(&g2);
- CHECK_PIXEL_PTR(2 * byte_run);
- for (j = 0; j < byte_run; j++) {
- *((signed short*)(&pixels[pixel_ptr])) = pixel;
- pixel_ptr += 2;
- pixel_countdown--;
- if (pixel_countdown < 0)
- av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
- pixel_countdown);
- }
- } else { /* copy pixels if byte_run < 0 */
- byte_run = -byte_run;
- if (bytestream2_tell(&g2) + 2 * byte_run > stream_ptr_after_chunk)
- break;
- CHECK_PIXEL_PTR(2 * byte_run);
- for (j = 0; j < byte_run; j++) {
- *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
- pixel_ptr += 2;
- pixel_countdown--;
- if (pixel_countdown < 0)
- av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
- pixel_countdown);
- }
- }
- }
-
- y_ptr += s->frame->linesize[0];
- }
- break;
-
- case FLI_COPY:
- case FLI_DTA_COPY:
- /* copy the chunk (uncompressed frame) */
- if (chunk_size - 6 > (unsigned int)(s->avctx->width * s->avctx->height)*2) {
- av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
- "bigger than image, skipping chunk\n", chunk_size - 6);
- bytestream2_skip(&g2, chunk_size - 6);
- } else {
-
- for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
- y_ptr += s->frame->linesize[0]) {
-
- pixel_countdown = s->avctx->width;
- pixel_ptr = 0;
- while (pixel_countdown > 0) {
- *((signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
- pixel_ptr += 2;
- pixel_countdown--;
- }
- }
- }
- break;
-
- case FLI_MINI:
- /* some sort of a thumbnail? disregard this chunk... */
- bytestream2_skip(&g2, chunk_size - 6);
- break;
-
- default:
- av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
- break;
- }
-
- frame_size -= chunk_size;
- num_chunks--;
- }
-
- /* by the end of the chunk, the stream ptr should equal the frame
- * size (minus 1, possibly); if it doesn't, issue a warning */
- if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
- av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
- "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
-
- if ((ret = av_frame_ref(data, s->frame)) < 0)
- return ret;
-
- *got_frame = 1;
-
- return buf_size;
-}
-
-static int flic_decode_frame_24BPP(AVCodecContext *avctx,
- void *data, int *got_frame,
- const uint8_t *buf, int buf_size)
-{
- av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n");
- return AVERROR_PATCHWELCOME;
-}
-
-static int flic_decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
- return flic_decode_frame_8BPP(avctx, data, got_frame,
- buf, buf_size);
- }
- else if ((avctx->pix_fmt == AV_PIX_FMT_RGB555) ||
- (avctx->pix_fmt == AV_PIX_FMT_RGB565)) {
- return flic_decode_frame_15_16BPP(avctx, data, got_frame,
- buf, buf_size);
- }
- else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
- return flic_decode_frame_24BPP(avctx, data, got_frame,
- buf, buf_size);
- }
-
- /* Should not get here, ever as the pix_fmt is processed */
- /* in flic_decode_init and the above if should deal with */
- /* the finite set of possibilites allowable by here. */
- /* But in case we do, just error out. */
- av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
- return AVERROR_BUG;
-}
-
-
-static av_cold int flic_decode_end(AVCodecContext *avctx)
-{
- FlicDecodeContext *s = avctx->priv_data;
-
- av_frame_free(&s->frame);
-
- return 0;
-}
-
-AVCodec ff_flic_decoder = {
- .name = "flic",
- .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_FLIC,
- .priv_data_size = sizeof(FlicDecodeContext),
- .init = flic_decode_init,
- .close = flic_decode_end,
- .decode = flic_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/g722.c b/ffmpeg-2-8-11/libavcodec/g722.c
deleted file mode 100644
index ee3b85f..0000000
--- a/ffmpeg-2-8-11/libavcodec/g722.c
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * G.722 ADPCM audio encoder/decoder
- *
- * Copyright (c) CMU 1993 Computer Science, Speech Group
- * Chengxiang Lu and Alex Hauptmann
- * Copyright (c) 2005 Steve Underwood <steveu at coppice.org>
- * Copyright (c) 2009 Kenan Gillet
- * Copyright (c) 2010 Martin Storsjo
- *
- * 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
- * G.722 ADPCM audio codec
- *
- * This G.722 decoder is a bit-exact implementation of the ITU G.722
- * specification for all three specified bitrates - 64000bps, 56000bps
- * and 48000bps. It passes the ITU tests.
- *
- * @note For the 56000bps and 48000bps bitrates, the lowest 1 or 2 bits
- * respectively of each byte are ignored.
- */
-
-#include "mathops.h"
-#include "g722.h"
-
-static const int8_t sign_lookup[2] = { -1, 1 };
-
-static const int16_t inv_log2_table[32] = {
- 2048, 2093, 2139, 2186, 2233, 2282, 2332, 2383,
- 2435, 2489, 2543, 2599, 2656, 2714, 2774, 2834,
- 2896, 2960, 3025, 3091, 3158, 3228, 3298, 3371,
- 3444, 3520, 3597, 3676, 3756, 3838, 3922, 4008
-};
-static const int16_t high_log_factor_step[2] = { 798, -214 };
-const int16_t ff_g722_high_inv_quant[4] = { -926, -202, 926, 202 };
-/**
- * low_log_factor_step[index] == wl[rl42[index]]
- */
-static const int16_t low_log_factor_step[16] = {
- -60, 3042, 1198, 538, 334, 172, 58, -30,
- 3042, 1198, 538, 334, 172, 58, -30, -60
-};
-const int16_t ff_g722_low_inv_quant4[16] = {
- 0, -2557, -1612, -1121, -786, -530, -323, -150,
- 2557, 1612, 1121, 786, 530, 323, 150, 0
-};
-const int16_t ff_g722_low_inv_quant6[64] = {
- -17, -17, -17, -17, -3101, -2738, -2376, -2088,
- -1873, -1689, -1535, -1399, -1279, -1170, -1072, -982,
- -899, -822, -750, -682, -618, -558, -501, -447,
- -396, -347, -300, -254, -211, -170, -130, -91,
- 3101, 2738, 2376, 2088, 1873, 1689, 1535, 1399,
- 1279, 1170, 1072, 982, 899, 822, 750, 682,
- 618, 558, 501, 447, 396, 347, 300, 254,
- 211, 170, 130, 91, 54, 17, -54, -17
-};
-
-static inline void s_zero(int cur_diff, struct G722Band *band)
-{
- int s_zero = 0;
-
- #define ACCUM(k, x, d) do { \
- int tmp = x; \
- band->zero_mem[k] = ((band->zero_mem[k] * 255) >> 8) + \
- d*((band->diff_mem[k]^cur_diff) < 0 ? -128 : 128); \
- band->diff_mem[k] = tmp; \
- s_zero += (tmp * band->zero_mem[k]) >> 15; \
- } while (0)
- if (cur_diff) {
- ACCUM(5, band->diff_mem[4], 1);
- ACCUM(4, band->diff_mem[3], 1);
- ACCUM(3, band->diff_mem[2], 1);
- ACCUM(2, band->diff_mem[1], 1);
- ACCUM(1, band->diff_mem[0], 1);
- ACCUM(0, cur_diff << 1, 1);
- } else {
- ACCUM(5, band->diff_mem[4], 0);
- ACCUM(4, band->diff_mem[3], 0);
- ACCUM(3, band->diff_mem[2], 0);
- ACCUM(2, band->diff_mem[1], 0);
- ACCUM(1, band->diff_mem[0], 0);
- ACCUM(0, cur_diff << 1, 0);
- }
- #undef ACCUM
- band->s_zero = s_zero;
-}
-
-/**
- * adaptive predictor
- *
- * @param cur_diff the dequantized and scaled delta calculated from the
- * current codeword
- */
-static void do_adaptive_prediction(struct G722Band *band, const int cur_diff)
-{
- int sg[2], limit, cur_qtzd_reconst;
-
- const int cur_part_reconst = band->s_zero + cur_diff < 0;
-
- sg[0] = sign_lookup[cur_part_reconst != band->part_reconst_mem[0]];
- sg[1] = sign_lookup[cur_part_reconst == band->part_reconst_mem[1]];
- band->part_reconst_mem[1] = band->part_reconst_mem[0];
- band->part_reconst_mem[0] = cur_part_reconst;
-
- band->pole_mem[1] = av_clip((sg[0] * av_clip(band->pole_mem[0], -8191, 8191) >> 5) +
- (sg[1] << 7) + (band->pole_mem[1] * 127 >> 7), -12288, 12288);
-
- limit = 15360 - band->pole_mem[1];
- band->pole_mem[0] = av_clip(-192 * sg[0] + (band->pole_mem[0] * 255 >> 8), -limit, limit);
-
- s_zero(cur_diff, band);
-
- cur_qtzd_reconst = av_clip_int16((band->s_predictor + cur_diff) << 1);
- band->s_predictor = av_clip_int16(band->s_zero +
- (band->pole_mem[0] * cur_qtzd_reconst >> 15) +
- (band->pole_mem[1] * band->prev_qtzd_reconst >> 15));
- band->prev_qtzd_reconst = cur_qtzd_reconst;
-}
-
-static inline int linear_scale_factor(const int log_factor)
-{
- const int wd1 = inv_log2_table[(log_factor >> 6) & 31];
- const int shift = log_factor >> 11;
- return shift < 0 ? wd1 >> -shift : wd1 << shift;
-}
-
-void ff_g722_update_low_predictor(struct G722Band *band, const int ilow)
-{
- do_adaptive_prediction(band,
- band->scale_factor * ff_g722_low_inv_quant4[ilow] >> 10);
-
- // quantizer adaptation
- band->log_factor = av_clip((band->log_factor * 127 >> 7) +
- low_log_factor_step[ilow], 0, 18432);
- band->scale_factor = linear_scale_factor(band->log_factor - (8 << 11));
-}
-
-void ff_g722_update_high_predictor(struct G722Band *band, const int dhigh,
- const int ihigh)
-{
- do_adaptive_prediction(band, dhigh);
-
- // quantizer adaptation
- band->log_factor = av_clip((band->log_factor * 127 >> 7) +
- high_log_factor_step[ihigh&1], 0, 22528);
- band->scale_factor = linear_scale_factor(band->log_factor - (10 << 11));
-}
diff --git a/ffmpeg-2-8-11/libavcodec/g726.c b/ffmpeg-2-8-11/libavcodec/g726.c
deleted file mode 100644
index f3de9e7..0000000
--- a/ffmpeg-2-8-11/libavcodec/g726.c
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * G.726 ADPCM audio codec
- * Copyright (c) 2004 Roman Shaposhnik
- *
- * This is a very straightforward rendition of the G.726
- * Section 4 "Computational Details".
- *
- * 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 <limits.h>
-
-#include "libavutil/channel_layout.h"
-#include "libavutil/opt.h"
-#include "avcodec.h"
-#include "internal.h"
-#include "get_bits.h"
-#include "put_bits.h"
-
-/**
- * G.726 11bit float.
- * G.726 Standard uses rather odd 11bit floating point arithmetic for
- * numerous occasions. It's a mystery to me why they did it this way
- * instead of simply using 32bit integer arithmetic.
- */
-typedef struct Float11 {
- uint8_t sign; /**< 1bit sign */
- uint8_t exp; /**< 4bit exponent */
- uint8_t mant; /**< 6bit mantissa */
-} Float11;
-
-static inline Float11* i2f(int i, Float11* f)
-{
- f->sign = (i < 0);
- if (f->sign)
- i = -i;
- f->exp = av_log2_16bit(i) + !!i;
- f->mant = i? (i<<6) >> f->exp : 1<<5;
- return f;
-}
-
-static inline int16_t mult(Float11* f1, Float11* f2)
-{
- int res, exp;
-
- exp = f1->exp + f2->exp;
- res = (((f1->mant * f2->mant) + 0x30) >> 4);
- res = exp > 19 ? res << (exp - 19) : res >> (19 - exp);
- return (f1->sign ^ f2->sign) ? -res : res;
-}
-
-static inline int sgn(int value)
-{
- return (value < 0) ? -1 : 1;
-}
-
-typedef struct G726Tables {
- const int* quant; /**< quantization table */
- const int16_t* iquant; /**< inverse quantization table */
- const int16_t* W; /**< special table #1 ;-) */
- const uint8_t* F; /**< special table #2 */
-} G726Tables;
-
-typedef struct G726Context {
- AVClass *class;
- G726Tables tbls; /**< static tables needed for computation */
-
- Float11 sr[2]; /**< prev. reconstructed samples */
- Float11 dq[6]; /**< prev. difference */
- int a[2]; /**< second order predictor coeffs */
- int b[6]; /**< sixth order predictor coeffs */
- int pk[2]; /**< signs of prev. 2 sez + dq */
-
- int ap; /**< scale factor control */
- int yu; /**< fast scale factor */
- int yl; /**< slow scale factor */
- int dms; /**< short average magnitude of F[i] */
- int dml; /**< long average magnitude of F[i] */
- int td; /**< tone detect */
-
- int se; /**< estimated signal for the next iteration */
- int sez; /**< estimated second order prediction */
- int y; /**< quantizer scaling factor for the next iteration */
- int code_size;
- int little_endian; /**< little-endian bitstream as used in aiff and Sun AU */
-} G726Context;
-
-static const int quant_tbl16[] = /**< 16kbit/s 2bits per sample */
- { 260, INT_MAX };
-static const int16_t iquant_tbl16[] =
- { 116, 365, 365, 116 };
-static const int16_t W_tbl16[] =
- { -22, 439, 439, -22 };
-static const uint8_t F_tbl16[] =
- { 0, 7, 7, 0 };
-
-static const int quant_tbl24[] = /**< 24kbit/s 3bits per sample */
- { 7, 217, 330, INT_MAX };
-static const int16_t iquant_tbl24[] =
- { INT16_MIN, 135, 273, 373, 373, 273, 135, INT16_MIN };
-static const int16_t W_tbl24[] =
- { -4, 30, 137, 582, 582, 137, 30, -4 };
-static const uint8_t F_tbl24[] =
- { 0, 1, 2, 7, 7, 2, 1, 0 };
-
-static const int quant_tbl32[] = /**< 32kbit/s 4bits per sample */
- { -125, 79, 177, 245, 299, 348, 399, INT_MAX };
-static const int16_t iquant_tbl32[] =
- { INT16_MIN, 4, 135, 213, 273, 323, 373, 425,
- 425, 373, 323, 273, 213, 135, 4, INT16_MIN };
-static const int16_t W_tbl32[] =
- { -12, 18, 41, 64, 112, 198, 355, 1122,
- 1122, 355, 198, 112, 64, 41, 18, -12};
-static const uint8_t F_tbl32[] =
- { 0, 0, 0, 1, 1, 1, 3, 7, 7, 3, 1, 1, 1, 0, 0, 0 };
-
-static const int quant_tbl40[] = /**< 40kbit/s 5bits per sample */
- { -122, -16, 67, 138, 197, 249, 297, 338,
- 377, 412, 444, 474, 501, 527, 552, INT_MAX };
-static const int16_t iquant_tbl40[] =
- { INT16_MIN, -66, 28, 104, 169, 224, 274, 318,
- 358, 395, 429, 459, 488, 514, 539, 566,
- 566, 539, 514, 488, 459, 429, 395, 358,
- 318, 274, 224, 169, 104, 28, -66, INT16_MIN };
-static const int16_t W_tbl40[] =
- { 14, 14, 24, 39, 40, 41, 58, 100,
- 141, 179, 219, 280, 358, 440, 529, 696,
- 696, 529, 440, 358, 280, 219, 179, 141,
- 100, 58, 41, 40, 39, 24, 14, 14 };
-static const uint8_t F_tbl40[] =
- { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 6,
- 6, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
-
-static const G726Tables G726Tables_pool[] =
- {{ quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 },
- { quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 },
- { quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 },
- { quant_tbl40, iquant_tbl40, W_tbl40, F_tbl40 }};
-
-
-/**
- * Para 4.2.2 page 18: Adaptive quantizer.
- */
-static inline uint8_t quant(G726Context* c, int d)
-{
- int sign, exp, i, dln;
-
- sign = i = 0;
- if (d < 0) {
- sign = 1;
- d = -d;
- }
- exp = av_log2_16bit(d);
- dln = ((exp<<7) + (((d<<7)>>exp)&0x7f)) - (c->y>>2);
-
- while (c->tbls.quant[i] < INT_MAX && c->tbls.quant[i] < dln)
- ++i;
-
- if (sign)
- i = ~i;
- if (c->code_size != 2 && i == 0) /* I'm not sure this is a good idea */
- i = 0xff;
-
- return i;
-}
-
-/**
- * Para 4.2.3 page 22: Inverse adaptive quantizer.
- */
-static inline int16_t inverse_quant(G726Context* c, int i)
-{
- int dql, dex, dqt;
-
- dql = c->tbls.iquant[i] + (c->y >> 2);
- dex = (dql>>7) & 0xf; /* 4bit exponent */
- dqt = (1<<7) + (dql & 0x7f); /* log2 -> linear */
- return (dql < 0) ? 0 : ((dqt<<dex) >> 7);
-}
-
-static int16_t g726_decode(G726Context* c, int I)
-{
- int dq, re_signal, pk0, fa1, i, tr, ylint, ylfrac, thr2, al, dq0;
- Float11 f;
- int I_sig= I >> (c->code_size - 1);
-
- dq = inverse_quant(c, I);
-
- /* Transition detect */
- ylint = (c->yl >> 15);
- ylfrac = (c->yl >> 10) & 0x1f;
- thr2 = (ylint > 9) ? 0x1f << 10 : (0x20 + ylfrac) << ylint;
- tr= (c->td == 1 && dq > ((3*thr2)>>2));
-
- if (I_sig) /* get the sign */
- dq = -dq;
- re_signal = (int16_t)(c->se + dq);
-
- /* Update second order predictor coefficient A2 and A1 */
- pk0 = (c->sez + dq) ? sgn(c->sez + dq) : 0;
- dq0 = dq ? sgn(dq) : 0;
- if (tr) {
- c->a[0] = 0;
- c->a[1] = 0;
- for (i=0; i<6; i++)
- c->b[i] = 0;
- } else {
- /* This is a bit crazy, but it really is +255 not +256 */
- fa1 = av_clip_intp2((-c->a[0]*c->pk[0]*pk0)>>5, 8);
-
- c->a[1] += 128*pk0*c->pk[1] + fa1 - (c->a[1]>>7);
- c->a[1] = av_clip(c->a[1], -12288, 12288);
- c->a[0] += 64*3*pk0*c->pk[0] - (c->a[0] >> 8);
- c->a[0] = av_clip(c->a[0], -(15360 - c->a[1]), 15360 - c->a[1]);
-
- for (i=0; i<6; i++)
- c->b[i] += 128*dq0*sgn(-c->dq[i].sign) - (c->b[i]>>8);
- }
-
- /* Update Dq and Sr and Pk */
- c->pk[1] = c->pk[0];
- c->pk[0] = pk0 ? pk0 : 1;
- c->sr[1] = c->sr[0];
- i2f(re_signal, &c->sr[0]);
- for (i=5; i>0; i--)
- c->dq[i] = c->dq[i-1];
- i2f(dq, &c->dq[0]);
- c->dq[0].sign = I_sig; /* Isn't it crazy ?!?! */
-
- c->td = c->a[1] < -11776;
-
- /* Update Ap */
- c->dms += (c->tbls.F[I]<<4) + ((- c->dms) >> 5);
- c->dml += (c->tbls.F[I]<<4) + ((- c->dml) >> 7);
- if (tr)
- c->ap = 256;
- else {
- c->ap += (-c->ap) >> 4;
- if (c->y <= 1535 || c->td || abs((c->dms << 2) - c->dml) >= (c->dml >> 3))
- c->ap += 0x20;
- }
-
- /* Update Yu and Yl */
- c->yu = av_clip(c->y + c->tbls.W[I] + ((-c->y)>>5), 544, 5120);
- c->yl += c->yu + ((-c->yl)>>6);
-
- /* Next iteration for Y */
- al = (c->ap >= 256) ? 1<<6 : c->ap >> 2;
- c->y = (c->yl + (c->yu - (c->yl>>6))*al) >> 6;
-
- /* Next iteration for SE and SEZ */
- c->se = 0;
- for (i=0; i<6; i++)
- c->se += mult(i2f(c->b[i] >> 2, &f), &c->dq[i]);
- c->sez = c->se >> 1;
- for (i=0; i<2; i++)
- c->se += mult(i2f(c->a[i] >> 2, &f), &c->sr[i]);
- c->se >>= 1;
-
- return av_clip(re_signal << 2, -0xffff, 0xffff);
-}
-
-static av_cold int g726_reset(G726Context *c)
-{
- int i;
-
- c->tbls = G726Tables_pool[c->code_size - 2];
- for (i=0; i<2; i++) {
- c->sr[i].mant = 1<<5;
- c->pk[i] = 1;
- }
- for (i=0; i<6; i++) {
- c->dq[i].mant = 1<<5;
- }
- c->yu = 544;
- c->yl = 34816;
-
- c->y = 544;
-
- return 0;
-}
-
-#if CONFIG_ADPCM_G726_ENCODER
-static int16_t g726_encode(G726Context* c, int16_t sig)
-{
- uint8_t i;
-
- i = av_mod_uintp2(quant(c, sig/4 - c->se), c->code_size);
- g726_decode(c, i);
- return i;
-}
-
-/* Interfacing to the libavcodec */
-
-static av_cold int g726_encode_init(AVCodecContext *avctx)
-{
- G726Context* c = avctx->priv_data;
-
- if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL &&
- avctx->sample_rate != 8000) {
- av_log(avctx, AV_LOG_ERROR, "Sample rates other than 8kHz are not "
- "allowed when the compliance level is higher than unofficial. "
- "Resample or reduce the compliance level.\n");
- return AVERROR(EINVAL);
- }
- if (avctx->sample_rate <= 0) {
- av_log(avctx, AV_LOG_ERROR, "Invalid sample rate %d\n",
- avctx->sample_rate);
- return AVERROR(EINVAL);
- }
-
- if(avctx->channels != 1){
- av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n");
- return AVERROR(EINVAL);
- }
-
- if (avctx->bit_rate)
- c->code_size = (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate;
-
- c->code_size = av_clip(c->code_size, 2, 5);
- avctx->bit_rate = c->code_size * avctx->sample_rate;
- avctx->bits_per_coded_sample = c->code_size;
-
- g726_reset(c);
-
- /* select a frame size that will end on a byte boundary and have a size of
- approximately 1024 bytes */
- avctx->frame_size = ((int[]){ 4096, 2736, 2048, 1640 })[c->code_size - 2];
-
- return 0;
-}
-
-static int g726_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
- const AVFrame *frame, int *got_packet_ptr)
-{
- G726Context *c = avctx->priv_data;
- const int16_t *samples = (const int16_t *)frame->data[0];
- PutBitContext pb;
- int i, ret, out_size;
-
- out_size = (frame->nb_samples * c->code_size + 7) / 8;
- if ((ret = ff_alloc_packet2(avctx, avpkt, out_size, 0)) < 0)
- return ret;
- init_put_bits(&pb, avpkt->data, avpkt->size);
-
- for (i = 0; i < frame->nb_samples; i++)
- put_bits(&pb, c->code_size, g726_encode(c, *samples++));
-
- flush_put_bits(&pb);
-
- avpkt->size = out_size;
- *got_packet_ptr = 1;
- return 0;
-}
-
-#define OFFSET(x) offsetof(G726Context, x)
-#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
-static const AVOption options[] = {
- { "code_size", "Bits per code", OFFSET(code_size), AV_OPT_TYPE_INT, { .i64 = 4 }, 2, 5, AE },
- { NULL },
-};
-
-static const AVClass g726_class = {
- .class_name = "g726",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-static const AVCodecDefault defaults[] = {
- { "b", "0" },
- { NULL },
-};
-
-AVCodec ff_adpcm_g726_encoder = {
- .name = "g726",
- .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_ADPCM_G726,
- .priv_data_size = sizeof(G726Context),
- .init = g726_encode_init,
- .encode2 = g726_encode_frame,
- .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME,
- .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
- AV_SAMPLE_FMT_NONE },
- .priv_class = &g726_class,
- .defaults = defaults,
-};
-#endif
-
-#if CONFIG_ADPCM_G726_DECODER || CONFIG_ADPCM_G726LE_DECODER
-static av_cold int g726_decode_init(AVCodecContext *avctx)
-{
- G726Context* c = avctx->priv_data;
-
- if(avctx->channels > 1){
- avpriv_request_sample(avctx, "Decoding more than one channel");
- return AVERROR_PATCHWELCOME;
- }
- avctx->channels = 1;
- avctx->channel_layout = AV_CH_LAYOUT_MONO;
-
- c->little_endian = !strcmp(avctx->codec->name, "g726le");
-
- c->code_size = avctx->bits_per_coded_sample;
- if (c->code_size < 2 || c->code_size > 5) {
- av_log(avctx, AV_LOG_ERROR, "Invalid number of bits %d\n", c->code_size);
- return AVERROR(EINVAL);
- }
- g726_reset(c);
-
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-
- return 0;
-}
-
-static int g726_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- AVFrame *frame = data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- G726Context *c = avctx->priv_data;
- int16_t *samples;
- GetBitContext gb;
- int out_samples, ret;
-
- out_samples = buf_size * 8 / c->code_size;
-
- /* get output buffer */
- frame->nb_samples = out_samples;
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
- samples = (int16_t *)frame->data[0];
-
- init_get_bits(&gb, buf, buf_size * 8);
-
- while (out_samples--)
- *samples++ = g726_decode(c, c->little_endian ?
- get_bits_le(&gb, c->code_size) :
- get_bits(&gb, c->code_size));
-
- if (get_bits_left(&gb) > 0)
- av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n");
-
- *got_frame_ptr = 1;
-
- return buf_size;
-}
-
-static void g726_decode_flush(AVCodecContext *avctx)
-{
- G726Context *c = avctx->priv_data;
- g726_reset(c);
-}
-#endif
-
-#if CONFIG_ADPCM_G726_DECODER
-AVCodec ff_adpcm_g726_decoder = {
- .name = "g726",
- .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_ADPCM_G726,
- .priv_data_size = sizeof(G726Context),
- .init = g726_decode_init,
- .decode = g726_decode_frame,
- .flush = g726_decode_flush,
- .capabilities = AV_CODEC_CAP_DR1,
-};
-#endif
-
-#if CONFIG_ADPCM_G726LE_DECODER
-AVCodec ff_adpcm_g726le_decoder = {
- .name = "g726le",
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_ADPCM_G726LE,
- .priv_data_size = sizeof(G726Context),
- .init = g726_decode_init,
- .decode = g726_decode_frame,
- .flush = g726_decode_flush,
- .capabilities = AV_CODEC_CAP_DR1,
- .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM little-endian"),
-};
-#endif
diff --git a/ffmpeg-2-8-11/libavcodec/h264_cabac.c b/ffmpeg-2-8-11/libavcodec/h264_cabac.c
deleted file mode 100644
index 04d412b..0000000
--- a/ffmpeg-2-8-11/libavcodec/h264_cabac.c
+++ /dev/null
@@ -1,2465 +0,0 @@
-/*
- * H.26L/H.264/AVC/JVT/14496-10/... cabac decoding
- * Copyright (c) 2003 Michael Niedermayer <michaelni at gmx.at>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * H.264 / AVC / MPEG4 part10 cabac decoding.
- * @author Michael Niedermayer <michaelni at gmx.at>
- */
-
-#define CABAC(h) 1
-#define UNCHECKED_BITSTREAM_READER 1
-#define INT_BIT (CHAR_BIT * sizeof(int))
-
-#include "libavutil/attributes.h"
-#include "libavutil/avassert.h"
-#include "libavutil/timer.h"
-#include "config.h"
-#include "cabac.h"
-#include "cabac_functions.h"
-#include "internal.h"
-#include "avcodec.h"
-#include "h264.h"
-#include "h264data.h"
-#include "h264_mvpred.h"
-#include "golomb.h"
-#include "mpegutils.h"
-
-#if ARCH_X86
-#include "x86/h264_i386.h"
-#endif
-
-/* Cabac pre state table */
-
-static const int8_t cabac_context_init_I[1024][2] =
-{
- /* 0 - 10 */
- { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 },
- { 2, 54 }, { 3, 74 }, { -28,127 }, { -23, 104 },
- { -6, 53 }, { -1, 54 }, { 7, 51 },
-
- /* 11 - 23 unsused for I */
- { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
- { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
- { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
- { 0, 0 },
-
- /* 24- 39 */
- { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
- { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
- { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
- { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
-
- /* 40 - 53 */
- { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
- { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
- { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
- { 0, 0 }, { 0, 0 },
-
- /* 54 - 59 */
- { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
- { 0, 0 }, { 0, 0 },
-
- /* 60 - 69 */
- { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 },
- { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 },
- { 13, 41 }, { 3, 62 },
-
- /* 70 -> 87 */
- { 0, 11 }, { 1, 55 }, { 0, 69 }, { -17, 127 },
- { -13, 102 },{ 0, 82 }, { -7, 74 }, { -21, 107 },
- { -27, 127 },{ -31, 127 },{ -24, 127 }, { -18, 95 },
- { -27, 127 },{ -21, 114 },{ -30, 127 }, { -17, 123 },
- { -12, 115 },{ -16, 122 },
-
- /* 88 -> 104 */
- { -11, 115 },{ -12, 63 }, { -2, 68 }, { -15, 84 },
- { -13, 104 },{ -3, 70 }, { -8, 93 }, { -10, 90 },
- { -30, 127 },{ -1, 74 }, { -6, 97 }, { -7, 91 },
- { -20, 127 },{ -4, 56 }, { -5, 82 }, { -7, 76 },
- { -22, 125 },
-
- /* 105 -> 135 */
- { -7, 93 }, { -11, 87 }, { -3, 77 }, { -5, 71 },
- { -4, 63 }, { -4, 68 }, { -12, 84 }, { -7, 62 },
- { -7, 65 }, { 8, 61 }, { 5, 56 }, { -2, 66 },
- { 1, 64 }, { 0, 61 }, { -2, 78 }, { 1, 50 },
- { 7, 52 }, { 10, 35 }, { 0, 44 }, { 11, 38 },
- { 1, 45 }, { 0, 46 }, { 5, 44 }, { 31, 17 },
- { 1, 51 }, { 7, 50 }, { 28, 19 }, { 16, 33 },
- { 14, 62 }, { -13, 108 },{ -15, 100 },
-
- /* 136 -> 165 */
- { -13, 101 },{ -13, 91 }, { -12, 94 }, { -10, 88 },
- { -16, 84 }, { -10, 86 }, { -7, 83 }, { -13, 87 },
- { -19, 94 }, { 1, 70 }, { 0, 72 }, { -5, 74 },
- { 18, 59 }, { -8, 102 }, { -15, 100 }, { 0, 95 },
- { -4, 75 }, { 2, 72 }, { -11, 75 }, { -3, 71 },
- { 15, 46 }, { -13, 69 }, { 0, 62 }, { 0, 65 },
- { 21, 37 }, { -15, 72 }, { 9, 57 }, { 16, 54 },
- { 0, 62 }, { 12, 72 },
-
- /* 166 -> 196 */
- { 24, 0 }, { 15, 9 }, { 8, 25 }, { 13, 18 },
- { 15, 9 }, { 13, 19 }, { 10, 37 }, { 12, 18 },
- { 6, 29 }, { 20, 33 }, { 15, 30 }, { 4, 45 },
- { 1, 58 }, { 0, 62 }, { 7, 61 }, { 12, 38 },
- { 11, 45 }, { 15, 39 }, { 11, 42 }, { 13, 44 },
- { 16, 45 }, { 12, 41 }, { 10, 49 }, { 30, 34 },
- { 18, 42 }, { 10, 55 }, { 17, 51 }, { 17, 46 },
- { 0, 89 }, { 26, -19 }, { 22, -17 },
-
- /* 197 -> 226 */
- { 26, -17 }, { 30, -25 }, { 28, -20 }, { 33, -23 },
- { 37, -27 }, { 33, -23 }, { 40, -28 }, { 38, -17 },
- { 33, -11 }, { 40, -15 }, { 41, -6 }, { 38, 1 },
- { 41, 17 }, { 30, -6 }, { 27, 3 }, { 26, 22 },
- { 37, -16 }, { 35, -4 }, { 38, -8 }, { 38, -3 },
- { 37, 3 }, { 38, 5 }, { 42, 0 }, { 35, 16 },
- { 39, 22 }, { 14, 48 }, { 27, 37 }, { 21, 60 },
- { 12, 68 }, { 2, 97 },
-
- /* 227 -> 251 */
- { -3, 71 }, { -6, 42 }, { -5, 50 }, { -3, 54 },
- { -2, 62 }, { 0, 58 }, { 1, 63 }, { -2, 72 },
- { -1, 74 }, { -9, 91 }, { -5, 67 }, { -5, 27 },
- { -3, 39 }, { -2, 44 }, { 0, 46 }, { -16, 64 },
- { -8, 68 }, { -10, 78 }, { -6, 77 }, { -10, 86 },
- { -12, 92 }, { -15, 55 }, { -10, 60 }, { -6, 62 },
- { -4, 65 },
-
- /* 252 -> 275 */
- { -12, 73 }, { -8, 76 }, { -7, 80 }, { -9, 88 },
- { -17, 110 },{ -11, 97 }, { -20, 84 }, { -11, 79 },
- { -6, 73 }, { -4, 74 }, { -13, 86 }, { -13, 96 },
- { -11, 97 }, { -19, 117 },{ -8, 78 }, { -5, 33 },
- { -4, 48 }, { -2, 53 }, { -3, 62 }, { -13, 71 },
- { -10, 79 }, { -12, 86 }, { -13, 90 }, { -14, 97 },
-
- /* 276 a bit special (not used, bypass is used instead) */
- { 0, 0 },
-
- /* 277 -> 307 */
- { -6, 93 }, { -6, 84 }, { -8, 79 }, { 0, 66 },
- { -1, 71 }, { 0, 62 }, { -2, 60 }, { -2, 59 },
- { -5, 75 }, { -3, 62 }, { -4, 58 }, { -9, 66 },
- { -1, 79 }, { 0, 71 }, { 3, 68 }, { 10, 44 },
- { -7, 62 }, { 15, 36 }, { 14, 40 }, { 16, 27 },
- { 12, 29 }, { 1, 44 }, { 20, 36 }, { 18, 32 },
- { 5, 42 }, { 1, 48 }, { 10, 62 }, { 17, 46 },
- { 9, 64 }, { -12, 104 },{ -11, 97 },
-
- /* 308 -> 337 */
- { -16, 96 }, { -7, 88 }, { -8, 85 }, { -7, 85 },
- { -9, 85 }, { -13, 88 }, { 4, 66 }, { -3, 77 },
- { -3, 76 }, { -6, 76 }, { 10, 58 }, { -1, 76 },
- { -1, 83 }, { -7, 99 }, { -14, 95 }, { 2, 95 },
- { 0, 76 }, { -5, 74 }, { 0, 70 }, { -11, 75 },
- { 1, 68 }, { 0, 65 }, { -14, 73 }, { 3, 62 },
- { 4, 62 }, { -1, 68 }, { -13, 75 }, { 11, 55 },
- { 5, 64 }, { 12, 70 },
-
- /* 338 -> 368 */
- { 15, 6 }, { 6, 19 }, { 7, 16 }, { 12, 14 },
- { 18, 13 }, { 13, 11 }, { 13, 15 }, { 15, 16 },
- { 12, 23 }, { 13, 23 }, { 15, 20 }, { 14, 26 },
- { 14, 44 }, { 17, 40 }, { 17, 47 }, { 24, 17 },
- { 21, 21 }, { 25, 22 }, { 31, 27 }, { 22, 29 },
- { 19, 35 }, { 14, 50 }, { 10, 57 }, { 7, 63 },
- { -2, 77 }, { -4, 82 }, { -3, 94 }, { 9, 69 },
- { -12, 109 },{ 36, -35 }, { 36, -34 },
-
- /* 369 -> 398 */
- { 32, -26 }, { 37, -30 }, { 44, -32 }, { 34, -18 },
- { 34, -15 }, { 40, -15 }, { 33, -7 }, { 35, -5 },
- { 33, 0 }, { 38, 2 }, { 33, 13 }, { 23, 35 },
- { 13, 58 }, { 29, -3 }, { 26, 0 }, { 22, 30 },
- { 31, -7 }, { 35, -15 }, { 34, -3 }, { 34, 3 },
- { 36, -1 }, { 34, 5 }, { 32, 11 }, { 35, 5 },
- { 34, 12 }, { 39, 11 }, { 30, 29 }, { 34, 26 },
- { 29, 39 }, { 19, 66 },
-
- /* 399 -> 435 */
- { 31, 21 }, { 31, 31 }, { 25, 50 },
- { -17, 120 }, { -20, 112 }, { -18, 114 }, { -11, 85 },
- { -15, 92 }, { -14, 89 }, { -26, 71 }, { -15, 81 },
- { -14, 80 }, { 0, 68 }, { -14, 70 }, { -24, 56 },
- { -23, 68 }, { -24, 50 }, { -11, 74 }, { 23, -13 },
- { 26, -13 }, { 40, -15 }, { 49, -14 }, { 44, 3 },
- { 45, 6 }, { 44, 34 }, { 33, 54 }, { 19, 82 },
- { -3, 75 }, { -1, 23 }, { 1, 34 }, { 1, 43 },
- { 0, 54 }, { -2, 55 }, { 0, 61 }, { 1, 64 },
- { 0, 68 }, { -9, 92 },
-
- /* 436 -> 459 */
- { -14, 106 }, { -13, 97 }, { -15, 90 }, { -12, 90 },
- { -18, 88 }, { -10, 73 }, { -9, 79 }, { -14, 86 },
- { -10, 73 }, { -10, 70 }, { -10, 69 }, { -5, 66 },
- { -9, 64 }, { -5, 58 }, { 2, 59 }, { 21, -10 },
- { 24, -11 }, { 28, -8 }, { 28, -1 }, { 29, 3 },
- { 29, 9 }, { 35, 20 }, { 29, 36 }, { 14, 67 },
-
- /* 460 -> 1024 */
- { -17, 123 }, { -12, 115 }, { -16, 122 }, { -11, 115 },
- { -12, 63 }, { -2, 68 }, { -15, 84 }, { -13, 104 },
- { -3, 70 }, { -8, 93 }, { -10, 90 }, { -30, 127 },
- { -17, 123 }, { -12, 115 }, { -16, 122 }, { -11, 115 },
- { -12, 63 }, { -2, 68 }, { -15, 84 }, { -13, 104 },
- { -3, 70 }, { -8, 93 }, { -10, 90 }, { -30, 127 },
- { -7, 93 }, { -11, 87 }, { -3, 77 }, { -5, 71 },
- { -4, 63 }, { -4, 68 }, { -12, 84 }, { -7, 62 },
- { -7, 65 }, { 8, 61 }, { 5, 56 }, { -2, 66 },
- { 1, 64 }, { 0, 61 }, { -2, 78 }, { 1, 50 },
- { 7, 52 }, { 10, 35 }, { 0, 44 }, { 11, 38 },
- { 1, 45 }, { 0, 46 }, { 5, 44 }, { 31, 17 },
- { 1, 51 }, { 7, 50 }, { 28, 19 }, { 16, 33 },
- { 14, 62 }, { -13, 108 }, { -15, 100 }, { -13, 101 },
- { -13, 91 }, { -12, 94 }, { -10, 88 }, { -16, 84 },
- { -10, 86 }, { -7, 83 }, { -13, 87 }, { -19, 94 },
- { 1, 70 }, { 0, 72 }, { -5, 74 }, { 18, 59 },
- { -7, 93 }, { -11, 87 }, { -3, 77 }, { -5, 71 },
- { -4, 63 }, { -4, 68 }, { -12, 84 }, { -7, 62 },
- { -7, 65 }, { 8, 61 }, { 5, 56 }, { -2, 66 },
- { 1, 64 }, { 0, 61 }, { -2, 78 }, { 1, 50 },
- { 7, 52 }, { 10, 35 }, { 0, 44 }, { 11, 38 },
- { 1, 45 }, { 0, 46 }, { 5, 44 }, { 31, 17 },
- { 1, 51 }, { 7, 50 }, { 28, 19 }, { 16, 33 },
- { 14, 62 }, { -13, 108 }, { -15, 100 }, { -13, 101 },
- { -13, 91 }, { -12, 94 }, { -10, 88 }, { -16, 84 },
- { -10, 86 }, { -7, 83 }, { -13, 87 }, { -19, 94 },
- { 1, 70 }, { 0, 72 }, { -5, 74 }, { 18, 59 },
- { 24, 0 }, { 15, 9 }, { 8, 25 }, { 13, 18 },
- { 15, 9 }, { 13, 19 }, { 10, 37 }, { 12, 18 },
- { 6, 29 }, { 20, 33 }, { 15, 30 }, { 4, 45 },
- { 1, 58 }, { 0, 62 }, { 7, 61 }, { 12, 38 },
- { 11, 45 }, { 15, 39 }, { 11, 42 }, { 13, 44 },
- { 16, 45 }, { 12, 41 }, { 10, 49 }, { 30, 34 },
- { 18, 42 }, { 10, 55 }, { 17, 51 }, { 17, 46 },
- { 0, 89 }, { 26, -19 }, { 22, -17 }, { 26, -17 },
- { 30, -25 }, { 28, -20 }, { 33, -23 }, { 37, -27 },
- { 33, -23 }, { 40, -28 }, { 38, -17 }, { 33, -11 },
- { 40, -15 }, { 41, -6 }, { 38, 1 }, { 41, 17 },
- { 24, 0 }, { 15, 9 }, { 8, 25 }, { 13, 18 },
- { 15, 9 }, { 13, 19 }, { 10, 37 }, { 12, 18 },
- { 6, 29 }, { 20, 33 }, { 15, 30 }, { 4, 45 },
- { 1, 58 }, { 0, 62 }, { 7, 61 }, { 12, 38 },
- { 11, 45 }, { 15, 39 }, { 11, 42 }, { 13, 44 },
- { 16, 45 }, { 12, 41 }, { 10, 49 }, { 30, 34 },
- { 18, 42 }, { 10, 55 }, { 17, 51 }, { 17, 46 },
- { 0, 89 }, { 26, -19 }, { 22, -17 }, { 26, -17 },
- { 30, -25 }, { 28, -20 }, { 33, -23 }, { 37, -27 },
- { 33, -23 }, { 40, -28 }, { 38, -17 }, { 33, -11 },
- { 40, -15 }, { 41, -6 }, { 38, 1 }, { 41, 17 },
- { -17, 120 }, { -20, 112 }, { -18, 114 }, { -11, 85 },
- { -15, 92 }, { -14, 89 }, { -26, 71 }, { -15, 81 },
- { -14, 80 }, { 0, 68 }, { -14, 70 }, { -24, 56 },
- { -23, 68 }, { -24, 50 }, { -11, 74 }, { -14, 106 },
- { -13, 97 }, { -15, 90 }, { -12, 90 }, { -18, 88 },
- { -10, 73 }, { -9, 79 }, { -14, 86 }, { -10, 73 },
- { -10, 70 }, { -10, 69 }, { -5, 66 }, { -9, 64 },
- { -5, 58 }, { 2, 59 }, { 23, -13 }, { 26, -13 },
- { 40, -15 }, { 49, -14 }, { 44, 3 }, { 45, 6 },
- { 44, 34 }, { 33, 54 }, { 19, 82 }, { 21, -10 },
- { 24, -11 }, { 28, -8 }, { 28, -1 }, { 29, 3 },
- { 29, 9 }, { 35, 20 }, { 29, 36 }, { 14, 67 },
- { -3, 75 }, { -1, 23 }, { 1, 34 }, { 1, 43 },
- { 0, 54 }, { -2, 55 }, { 0, 61 }, { 1, 64 },
- { 0, 68 }, { -9, 92 }, { -17, 120 }, { -20, 112 },
- { -18, 114 }, { -11, 85 }, { -15, 92 }, { -14, 89 },
- { -26, 71 }, { -15, 81 }, { -14, 80 }, { 0, 68 },
- { -14, 70 }, { -24, 56 }, { -23, 68 }, { -24, 50 },
- { -11, 74 }, { -14, 106 }, { -13, 97 }, { -15, 90 },
- { -12, 90 }, { -18, 88 }, { -10, 73 }, { -9, 79 },
- { -14, 86 }, { -10, 73 }, { -10, 70 }, { -10, 69 },
- { -5, 66 }, { -9, 64 }, { -5, 58 }, { 2, 59 },
- { 23, -13 }, { 26, -13 }, { 40, -15 }, { 49, -14 },
- { 44, 3 }, { 45, 6 }, { 44, 34 }, { 33, 54 },
- { 19, 82 }, { 21, -10 }, { 24, -11 }, { 28, -8 },
- { 28, -1 }, { 29, 3 }, { 29, 9 }, { 35, 20 },
- { 29, 36 }, { 14, 67 }, { -3, 75 }, { -1, 23 },
- { 1, 34 }, { 1, 43 }, { 0, 54 }, { -2, 55 },
- { 0, 61 }, { 1, 64 }, { 0, 68 }, { -9, 92 },
- { -6, 93 }, { -6, 84 }, { -8, 79 }, { 0, 66 },
- { -1, 71 }, { 0, 62 }, { -2, 60 }, { -2, 59 },
- { -5, 75 }, { -3, 62 }, { -4, 58 }, { -9, 66 },
- { -1, 79 }, { 0, 71 }, { 3, 68 }, { 10, 44 },
- { -7, 62 }, { 15, 36 }, { 14, 40 }, { 16, 27 },
- { 12, 29 }, { 1, 44 }, { 20, 36 }, { 18, 32 },
- { 5, 42 }, { 1, 48 }, { 10, 62 }, { 17, 46 },
- { 9, 64 }, { -12, 104 }, { -11, 97 }, { -16, 96 },
- { -7, 88 }, { -8, 85 }, { -7, 85 }, { -9, 85 },
- { -13, 88 }, { 4, 66 }, { -3, 77 }, { -3, 76 },
- { -6, 76 }, { 10, 58 }, { -1, 76 }, { -1, 83 },
- { -6, 93 }, { -6, 84 }, { -8, 79 }, { 0, 66 },
- { -1, 71 }, { 0, 62 }, { -2, 60 }, { -2, 59 },
- { -5, 75 }, { -3, 62 }, { -4, 58 }, { -9, 66 },
- { -1, 79 }, { 0, 71 }, { 3, 68 }, { 10, 44 },
- { -7, 62 }, { 15, 36 }, { 14, 40 }, { 16, 27 },
- { 12, 29 }, { 1, 44 }, { 20, 36 }, { 18, 32 },
- { 5, 42 }, { 1, 48 }, { 10, 62 }, { 17, 46 },
- { 9, 64 }, { -12, 104 }, { -11, 97 }, { -16, 96 },
- { -7, 88 }, { -8, 85 }, { -7, 85 }, { -9, 85 },
- { -13, 88 }, { 4, 66 }, { -3, 77 }, { -3, 76 },
- { -6, 76 }, { 10, 58 }, { -1, 76 }, { -1, 83 },
- { 15, 6 }, { 6, 19 }, { 7, 16 }, { 12, 14 },
- { 18, 13 }, { 13, 11 }, { 13, 15 }, { 15, 16 },
- { 12, 23 }, { 13, 23 }, { 15, 20 }, { 14, 26 },
- { 14, 44 }, { 17, 40 }, { 17, 47 }, { 24, 17 },
- { 21, 21 }, { 25, 22 }, { 31, 27 }, { 22, 29 },
- { 19, 35 }, { 14, 50 }, { 10, 57 }, { 7, 63 },
- { -2, 77 }, { -4, 82 }, { -3, 94 }, { 9, 69 },
- { -12, 109 }, { 36, -35 }, { 36, -34 }, { 32, -26 },
- { 37, -30 }, { 44, -32 }, { 34, -18 }, { 34, -15 },
- { 40, -15 }, { 33, -7 }, { 35, -5 }, { 33, 0 },
- { 38, 2 }, { 33, 13 }, { 23, 35 }, { 13, 58 },
- { 15, 6 }, { 6, 19 }, { 7, 16 }, { 12, 14 },
- { 18, 13 }, { 13, 11 }, { 13, 15 }, { 15, 16 },
- { 12, 23 }, { 13, 23 }, { 15, 20 }, { 14, 26 },
- { 14, 44 }, { 17, 40 }, { 17, 47 }, { 24, 17 },
- { 21, 21 }, { 25, 22 }, { 31, 27 }, { 22, 29 },
- { 19, 35 }, { 14, 50 }, { 10, 57 }, { 7, 63 },
- { -2, 77 }, { -4, 82 }, { -3, 94 }, { 9, 69 },
- { -12, 109 }, { 36, -35 }, { 36, -34 }, { 32, -26 },
- { 37, -30 }, { 44, -32 }, { 34, -18 }, { 34, -15 },
- { 40, -15 }, { 33, -7 }, { 35, -5 }, { 33, 0 },
- { 38, 2 }, { 33, 13 }, { 23, 35 }, { 13, 58 },
- { -3, 71 }, { -6, 42 }, { -5, 50 }, { -3, 54 },
- { -2, 62 }, { 0, 58 }, { 1, 63 }, { -2, 72 },
- { -1, 74 }, { -9, 91 }, { -5, 67 }, { -5, 27 },
- { -3, 39 }, { -2, 44 }, { 0, 46 }, { -16, 64 },
- { -8, 68 }, { -10, 78 }, { -6, 77 }, { -10, 86 },
- { -12, 92 }, { -15, 55 }, { -10, 60 }, { -6, 62 },
- { -4, 65 }, { -12, 73 }, { -8, 76 }, { -7, 80 },
- { -9, 88 }, { -17, 110 }, { -3, 71 }, { -6, 42 },
- { -5, 50 }, { -3, 54 }, { -2, 62 }, { 0, 58 },
- { 1, 63 }, { -2, 72 }, { -1, 74 }, { -9, 91 },
- { -5, 67 }, { -5, 27 }, { -3, 39 }, { -2, 44 },
- { 0, 46 }, { -16, 64 }, { -8, 68 }, { -10, 78 },
- { -6, 77 }, { -10, 86 }, { -12, 92 }, { -15, 55 },
- { -10, 60 }, { -6, 62 }, { -4, 65 }, { -12, 73 },
- { -8, 76 }, { -7, 80 }, { -9, 88 }, { -17, 110 },
- { -3, 70 }, { -8, 93 }, { -10, 90 }, { -30, 127 },
- { -3, 70 }, { -8, 93 }, { -10, 90 }, { -30, 127 },
- { -3, 70 }, { -8, 93 }, { -10, 90 }, { -30, 127 }
-};
-
-static const int8_t cabac_context_init_PB[3][1024][2] =
-{
- /* i_cabac_init_idc == 0 */
- {
- /* 0 - 10 */
- { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 },
- { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 },
- { -6, 53 }, { -1, 54 }, { 7, 51 },
-
- /* 11 - 23 */
- { 23, 33 }, { 23, 2 }, { 21, 0 }, { 1, 9 },
- { 0, 49 }, { -37, 118 }, { 5, 57 }, { -13, 78 },
- { -11, 65 }, { 1, 62 }, { 12, 49 }, { -4, 73 },
- { 17, 50 },
-
- /* 24 - 39 */
- { 18, 64 }, { 9, 43 }, { 29, 0 }, { 26, 67 },
- { 16, 90 }, { 9, 104 }, { -46, 127 }, { -20, 104 },
- { 1, 67 }, { -13, 78 }, { -11, 65 }, { 1, 62 },
- { -6, 86 }, { -17, 95 }, { -6, 61 }, { 9, 45 },
-
- /* 40 - 53 */
- { -3, 69 }, { -6, 81 }, { -11, 96 }, { 6, 55 },
- { 7, 67 }, { -5, 86 }, { 2, 88 }, { 0, 58 },
- { -3, 76 }, { -10, 94 }, { 5, 54 }, { 4, 69 },
- { -3, 81 }, { 0, 88 },
-
- /* 54 - 59 */
- { -7, 67 }, { -5, 74 }, { -4, 74 }, { -5, 80 },
- { -7, 72 }, { 1, 58 },
-
- /* 60 - 69 */
- { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 },
- { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 },
- { 13, 41 }, { 3, 62 },
-
- /* 70 - 87 */
- { 0, 45 }, { -4, 78 }, { -3, 96 }, { -27, 126 },
- { -28, 98 }, { -25, 101 }, { -23, 67 }, { -28, 82 },
- { -20, 94 }, { -16, 83 }, { -22, 110 }, { -21, 91 },
- { -18, 102 }, { -13, 93 }, { -29, 127 }, { -7, 92 },
- { -5, 89 }, { -7, 96 }, { -13, 108 }, { -3, 46 },
- { -1, 65 }, { -1, 57 }, { -9, 93 }, { -3, 74 },
- { -9, 92 }, { -8, 87 }, { -23, 126 }, { 5, 54 },
- { 6, 60 }, { 6, 59 }, { 6, 69 }, { -1, 48 },
- { 0, 68 }, { -4, 69 }, { -8, 88 },
-
- /* 105 -> 165 */
- { -2, 85 }, { -6, 78 }, { -1, 75 }, { -7, 77 },
- { 2, 54 }, { 5, 50 }, { -3, 68 }, { 1, 50 },
- { 6, 42 }, { -4, 81 }, { 1, 63 }, { -4, 70 },
- { 0, 67 }, { 2, 57 }, { -2, 76 }, { 11, 35 },
- { 4, 64 }, { 1, 61 }, { 11, 35 }, { 18, 25 },
- { 12, 24 }, { 13, 29 }, { 13, 36 }, { -10, 93 },
- { -7, 73 }, { -2, 73 }, { 13, 46 }, { 9, 49 },
- { -7, 100 }, { 9, 53 }, { 2, 53 }, { 5, 53 },
- { -2, 61 }, { 0, 56 }, { 0, 56 }, { -13, 63 },
- { -5, 60 }, { -1, 62 }, { 4, 57 }, { -6, 69 },
- { 4, 57 }, { 14, 39 }, { 4, 51 }, { 13, 68 },
- { 3, 64 }, { 1, 61 }, { 9, 63 }, { 7, 50 },
- { 16, 39 }, { 5, 44 }, { 4, 52 }, { 11, 48 },
- { -5, 60 }, { -1, 59 }, { 0, 59 }, { 22, 33 },
- { 5, 44 }, { 14, 43 }, { -1, 78 }, { 0, 60 },
- { 9, 69 },
-
- /* 166 - 226 */
- { 11, 28 }, { 2, 40 }, { 3, 44 }, { 0, 49 },
- { 0, 46 }, { 2, 44 }, { 2, 51 }, { 0, 47 },
- { 4, 39 }, { 2, 62 }, { 6, 46 }, { 0, 54 },
- { 3, 54 }, { 2, 58 }, { 4, 63 }, { 6, 51 },
- { 6, 57 }, { 7, 53 }, { 6, 52 }, { 6, 55 },
- { 11, 45 }, { 14, 36 }, { 8, 53 }, { -1, 82 },
- { 7, 55 }, { -3, 78 }, { 15, 46 }, { 22, 31 },
- { -1, 84 }, { 25, 7 }, { 30, -7 }, { 28, 3 },
- { 28, 4 }, { 32, 0 }, { 34, -1 }, { 30, 6 },
- { 30, 6 }, { 32, 9 }, { 31, 19 }, { 26, 27 },
- { 26, 30 }, { 37, 20 }, { 28, 34 }, { 17, 70 },
- { 1, 67 }, { 5, 59 }, { 9, 67 }, { 16, 30 },
- { 18, 32 }, { 18, 35 }, { 22, 29 }, { 24, 31 },
- { 23, 38 }, { 18, 43 }, { 20, 41 }, { 11, 63 },
- { 9, 59 }, { 9, 64 }, { -1, 94 }, { -2, 89 },
- { -9, 108 },
-
- /* 227 - 275 */
- { -6, 76 }, { -2, 44 }, { 0, 45 }, { 0, 52 },
- { -3, 64 }, { -2, 59 }, { -4, 70 }, { -4, 75 },
- { -8, 82 }, { -17, 102 }, { -9, 77 }, { 3, 24 },
- { 0, 42 }, { 0, 48 }, { 0, 55 }, { -6, 59 },
- { -7, 71 }, { -12, 83 }, { -11, 87 }, { -30, 119 },
- { 1, 58 }, { -3, 29 }, { -1, 36 }, { 1, 38 },
- { 2, 43 }, { -6, 55 }, { 0, 58 }, { 0, 64 },
- { -3, 74 }, { -10, 90 }, { 0, 70 }, { -4, 29 },
- { 5, 31 }, { 7, 42 }, { 1, 59 }, { -2, 58 },
- { -3, 72 }, { -3, 81 }, { -11, 97 }, { 0, 58 },
- { 8, 5 }, { 10, 14 }, { 14, 18 }, { 13, 27 },
- { 2, 40 }, { 0, 58 }, { -3, 70 }, { -6, 79 },
- { -8, 85 },
-
- /* 276 a bit special (not used, bypass is used instead) */
- { 0, 0 },
-
- /* 277 - 337 */
- { -13, 106 }, { -16, 106 }, { -10, 87 }, { -21, 114 },
- { -18, 110 }, { -14, 98 }, { -22, 110 }, { -21, 106 },
- { -18, 103 }, { -21, 107 }, { -23, 108 }, { -26, 112 },
- { -10, 96 }, { -12, 95 }, { -5, 91 }, { -9, 93 },
- { -22, 94 }, { -5, 86 }, { 9, 67 }, { -4, 80 },
- { -10, 85 }, { -1, 70 }, { 7, 60 }, { 9, 58 },
- { 5, 61 }, { 12, 50 }, { 15, 50 }, { 18, 49 },
- { 17, 54 }, { 10, 41 }, { 7, 46 }, { -1, 51 },
- { 7, 49 }, { 8, 52 }, { 9, 41 }, { 6, 47 },
- { 2, 55 }, { 13, 41 }, { 10, 44 }, { 6, 50 },
- { 5, 53 }, { 13, 49 }, { 4, 63 }, { 6, 64 },
- { -2, 69 }, { -2, 59 }, { 6, 70 }, { 10, 44 },
- { 9, 31 }, { 12, 43 }, { 3, 53 }, { 14, 34 },
- { 10, 38 }, { -3, 52 }, { 13, 40 }, { 17, 32 },
- { 7, 44 }, { 7, 38 }, { 13, 50 }, { 10, 57 },
- { 26, 43 },
-
- /* 338 - 398 */
- { 14, 11 }, { 11, 14 }, { 9, 11 }, { 18, 11 },
- { 21, 9 }, { 23, -2 }, { 32, -15 }, { 32, -15 },
- { 34, -21 }, { 39, -23 }, { 42, -33 }, { 41, -31 },
- { 46, -28 }, { 38, -12 }, { 21, 29 }, { 45, -24 },
- { 53, -45 }, { 48, -26 }, { 65, -43 }, { 43, -19 },
- { 39, -10 }, { 30, 9 }, { 18, 26 }, { 20, 27 },
- { 0, 57 }, { -14, 82 }, { -5, 75 }, { -19, 97 },
- { -35, 125 }, { 27, 0 }, { 28, 0 }, { 31, -4 },
- { 27, 6 }, { 34, 8 }, { 30, 10 }, { 24, 22 },
- { 33, 19 }, { 22, 32 }, { 26, 31 }, { 21, 41 },
- { 26, 44 }, { 23, 47 }, { 16, 65 }, { 14, 71 },
- { 8, 60 }, { 6, 63 }, { 17, 65 }, { 21, 24 },
- { 23, 20 }, { 26, 23 }, { 27, 32 }, { 28, 23 },
- { 28, 24 }, { 23, 40 }, { 24, 32 }, { 28, 29 },
- { 23, 42 }, { 19, 57 }, { 22, 53 }, { 22, 61 },
- { 11, 86 },
-
- /* 399 - 435 */
- { 12, 40 }, { 11, 51 }, { 14, 59 },
- { -4, 79 }, { -7, 71 }, { -5, 69 }, { -9, 70 },
- { -8, 66 }, { -10, 68 }, { -19, 73 }, { -12, 69 },
- { -16, 70 }, { -15, 67 }, { -20, 62 }, { -19, 70 },
- { -16, 66 }, { -22, 65 }, { -20, 63 }, { 9, -2 },
- { 26, -9 }, { 33, -9 }, { 39, -7 }, { 41, -2 },
- { 45, 3 }, { 49, 9 }, { 45, 27 }, { 36, 59 },
- { -6, 66 }, { -7, 35 }, { -7, 42 }, { -8, 45 },
- { -5, 48 }, { -12, 56 }, { -6, 60 }, { -5, 62 },
- { -8, 66 }, { -8, 76 },
-
- /* 436 - 459 */
- { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 },
- { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 },
- { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 },
- { -14, 66 }, { 0, 59 }, { 2, 59 }, { 21, -13 },
- { 33, -14 }, { 39, -7 }, { 46, -2 }, { 51, 2 },
- { 60, 6 }, { 61, 17 }, { 55, 34 }, { 42, 62 },
-
- /* 460 - 1024 */
- { -7, 92 }, { -5, 89 }, { -7, 96 }, { -13, 108 },
- { -3, 46 }, { -1, 65 }, { -1, 57 }, { -9, 93 },
- { -3, 74 }, { -9, 92 }, { -8, 87 }, { -23, 126 },
- { -7, 92 }, { -5, 89 }, { -7, 96 }, { -13, 108 },
- { -3, 46 }, { -1, 65 }, { -1, 57 }, { -9, 93 },
- { -3, 74 }, { -9, 92 }, { -8, 87 }, { -23, 126 },
- { -2, 85 }, { -6, 78 }, { -1, 75 }, { -7, 77 },
- { 2, 54 }, { 5, 50 }, { -3, 68 }, { 1, 50 },
- { 6, 42 }, { -4, 81 }, { 1, 63 }, { -4, 70 },
- { 0, 67 }, { 2, 57 }, { -2, 76 }, { 11, 35 },
- { 4, 64 }, { 1, 61 }, { 11, 35 }, { 18, 25 },
- { 12, 24 }, { 13, 29 }, { 13, 36 }, { -10, 93 },
- { -7, 73 }, { -2, 73 }, { 13, 46 }, { 9, 49 },
- { -7, 100 }, { 9, 53 }, { 2, 53 }, { 5, 53 },
- { -2, 61 }, { 0, 56 }, { 0, 56 }, { -13, 63 },
- { -5, 60 }, { -1, 62 }, { 4, 57 }, { -6, 69 },
- { 4, 57 }, { 14, 39 }, { 4, 51 }, { 13, 68 },
- { -2, 85 }, { -6, 78 }, { -1, 75 }, { -7, 77 },
- { 2, 54 }, { 5, 50 }, { -3, 68 }, { 1, 50 },
- { 6, 42 }, { -4, 81 }, { 1, 63 }, { -4, 70 },
- { 0, 67 }, { 2, 57 }, { -2, 76 }, { 11, 35 },
- { 4, 64 }, { 1, 61 }, { 11, 35 }, { 18, 25 },
- { 12, 24 }, { 13, 29 }, { 13, 36 }, { -10, 93 },
- { -7, 73 }, { -2, 73 }, { 13, 46 }, { 9, 49 },
- { -7, 100 }, { 9, 53 }, { 2, 53 }, { 5, 53 },
- { -2, 61 }, { 0, 56 }, { 0, 56 }, { -13, 63 },
- { -5, 60 }, { -1, 62 }, { 4, 57 }, { -6, 69 },
- { 4, 57 }, { 14, 39 }, { 4, 51 }, { 13, 68 },
- { 11, 28 }, { 2, 40 }, { 3, 44 }, { 0, 49 },
- { 0, 46 }, { 2, 44 }, { 2, 51 }, { 0, 47 },
- { 4, 39 }, { 2, 62 }, { 6, 46 }, { 0, 54 },
- { 3, 54 }, { 2, 58 }, { 4, 63 }, { 6, 51 },
- { 6, 57 }, { 7, 53 }, { 6, 52 }, { 6, 55 },
- { 11, 45 }, { 14, 36 }, { 8, 53 }, { -1, 82 },
- { 7, 55 }, { -3, 78 }, { 15, 46 }, { 22, 31 },
- { -1, 84 }, { 25, 7 }, { 30, -7 }, { 28, 3 },
- { 28, 4 }, { 32, 0 }, { 34, -1 }, { 30, 6 },
- { 30, 6 }, { 32, 9 }, { 31, 19 }, { 26, 27 },
- { 26, 30 }, { 37, 20 }, { 28, 34 }, { 17, 70 },
- { 11, 28 }, { 2, 40 }, { 3, 44 }, { 0, 49 },
- { 0, 46 }, { 2, 44 }, { 2, 51 }, { 0, 47 },
- { 4, 39 }, { 2, 62 }, { 6, 46 }, { 0, 54 },
- { 3, 54 }, { 2, 58 }, { 4, 63 }, { 6, 51 },
- { 6, 57 }, { 7, 53 }, { 6, 52 }, { 6, 55 },
- { 11, 45 }, { 14, 36 }, { 8, 53 }, { -1, 82 },
- { 7, 55 }, { -3, 78 }, { 15, 46 }, { 22, 31 },
- { -1, 84 }, { 25, 7 }, { 30, -7 }, { 28, 3 },
- { 28, 4 }, { 32, 0 }, { 34, -1 }, { 30, 6 },
- { 30, 6 }, { 32, 9 }, { 31, 19 }, { 26, 27 },
- { 26, 30 }, { 37, 20 }, { 28, 34 }, { 17, 70 },
- { -4, 79 }, { -7, 71 }, { -5, 69 }, { -9, 70 },
- { -8, 66 }, { -10, 68 }, { -19, 73 }, { -12, 69 },
- { -16, 70 }, { -15, 67 }, { -20, 62 }, { -19, 70 },
- { -16, 66 }, { -22, 65 }, { -20, 63 }, { -5, 85 },
- { -6, 81 }, { -10, 77 }, { -7, 81 }, { -17, 80 },
- { -18, 73 }, { -4, 74 }, { -10, 83 }, { -9, 71 },
- { -9, 67 }, { -1, 61 }, { -8, 66 }, { -14, 66 },
- { 0, 59 }, { 2, 59 }, { 9, -2 }, { 26, -9 },
- { 33, -9 }, { 39, -7 }, { 41, -2 }, { 45, 3 },
- { 49, 9 }, { 45, 27 }, { 36, 59 }, { 21, -13 },
- { 33, -14 }, { 39, -7 }, { 46, -2 }, { 51, 2 },
- { 60, 6 }, { 61, 17 }, { 55, 34 }, { 42, 62 },
- { -6, 66 }, { -7, 35 }, { -7, 42 }, { -8, 45 },
- { -5, 48 }, { -12, 56 }, { -6, 60 }, { -5, 62 },
- { -8, 66 }, { -8, 76 }, { -4, 79 }, { -7, 71 },
- { -5, 69 }, { -9, 70 }, { -8, 66 }, { -10, 68 },
- { -19, 73 }, { -12, 69 }, { -16, 70 }, { -15, 67 },
- { -20, 62 }, { -19, 70 }, { -16, 66 }, { -22, 65 },
- { -20, 63 }, { -5, 85 }, { -6, 81 }, { -10, 77 },
- { -7, 81 }, { -17, 80 }, { -18, 73 }, { -4, 74 },
- { -10, 83 }, { -9, 71 }, { -9, 67 }, { -1, 61 },
- { -8, 66 }, { -14, 66 }, { 0, 59 }, { 2, 59 },
- { 9, -2 }, { 26, -9 }, { 33, -9 }, { 39, -7 },
- { 41, -2 }, { 45, 3 }, { 49, 9 }, { 45, 27 },
- { 36, 59 }, { 21, -13 }, { 33, -14 }, { 39, -7 },
- { 46, -2 }, { 51, 2 }, { 60, 6 }, { 61, 17 },
- { 55, 34 }, { 42, 62 }, { -6, 66 }, { -7, 35 },
- { -7, 42 }, { -8, 45 }, { -5, 48 }, { -12, 56 },
- { -6, 60 }, { -5, 62 }, { -8, 66 }, { -8, 76 },
- { -13, 106 }, { -16, 106 }, { -10, 87 }, { -21, 114 },
- { -18, 110 }, { -14, 98 }, { -22, 110 }, { -21, 106 },
- { -18, 103 }, { -21, 107 }, { -23, 108 }, { -26, 112 },
- { -10, 96 }, { -12, 95 }, { -5, 91 }, { -9, 93 },
- { -22, 94 }, { -5, 86 }, { 9, 67 }, { -4, 80 },
- { -10, 85 }, { -1, 70 }, { 7, 60 }, { 9, 58 },
- { 5, 61 }, { 12, 50 }, { 15, 50 }, { 18, 49 },
- { 17, 54 }, { 10, 41 }, { 7, 46 }, { -1, 51 },
- { 7, 49 }, { 8, 52 }, { 9, 41 }, { 6, 47 },
- { 2, 55 }, { 13, 41 }, { 10, 44 }, { 6, 50 },
- { 5, 53 }, { 13, 49 }, { 4, 63 }, { 6, 64 },
- { -13, 106 }, { -16, 106 }, { -10, 87 }, { -21, 114 },
- { -18, 110 }, { -14, 98 }, { -22, 110 }, { -21, 106 },
- { -18, 103 }, { -21, 107 }, { -23, 108 }, { -26, 112 },
- { -10, 96 }, { -12, 95 }, { -5, 91 }, { -9, 93 },
- { -22, 94 }, { -5, 86 }, { 9, 67 }, { -4, 80 },
- { -10, 85 }, { -1, 70 }, { 7, 60 }, { 9, 58 },
- { 5, 61 }, { 12, 50 }, { 15, 50 }, { 18, 49 },
- { 17, 54 }, { 10, 41 }, { 7, 46 }, { -1, 51 },
- { 7, 49 }, { 8, 52 }, { 9, 41 }, { 6, 47 },
- { 2, 55 }, { 13, 41 }, { 10, 44 }, { 6, 50 },
- { 5, 53 }, { 13, 49 }, { 4, 63 }, { 6, 64 },
- { 14, 11 }, { 11, 14 }, { 9, 11 }, { 18, 11 },
- { 21, 9 }, { 23, -2 }, { 32, -15 }, { 32, -15 },
- { 34, -21 }, { 39, -23 }, { 42, -33 }, { 41, -31 },
- { 46, -28 }, { 38, -12 }, { 21, 29 }, { 45, -24 },
- { 53, -45 }, { 48, -26 }, { 65, -43 }, { 43, -19 },
- { 39, -10 }, { 30, 9 }, { 18, 26 }, { 20, 27 },
- { 0, 57 }, { -14, 82 }, { -5, 75 }, { -19, 97 },
- { -35, 125 }, { 27, 0 }, { 28, 0 }, { 31, -4 },
- { 27, 6 }, { 34, 8 }, { 30, 10 }, { 24, 22 },
- { 33, 19 }, { 22, 32 }, { 26, 31 }, { 21, 41 },
- { 26, 44 }, { 23, 47 }, { 16, 65 }, { 14, 71 },
- { 14, 11 }, { 11, 14 }, { 9, 11 }, { 18, 11 },
- { 21, 9 }, { 23, -2 }, { 32, -15 }, { 32, -15 },
- { 34, -21 }, { 39, -23 }, { 42, -33 }, { 41, -31 },
- { 46, -28 }, { 38, -12 }, { 21, 29 }, { 45, -24 },
- { 53, -45 }, { 48, -26 }, { 65, -43 }, { 43, -19 },
- { 39, -10 }, { 30, 9 }, { 18, 26 }, { 20, 27 },
- { 0, 57 }, { -14, 82 }, { -5, 75 }, { -19, 97 },
- { -35, 125 }, { 27, 0 }, { 28, 0 }, { 31, -4 },
- { 27, 6 }, { 34, 8 }, { 30, 10 }, { 24, 22 },
- { 33, 19 }, { 22, 32 }, { 26, 31 }, { 21, 41 },
- { 26, 44 }, { 23, 47 }, { 16, 65 }, { 14, 71 },
- { -6, 76 }, { -2, 44 }, { 0, 45 }, { 0, 52 },
- { -3, 64 }, { -2, 59 }, { -4, 70 }, { -4, 75 },
- { -8, 82 }, { -17, 102 }, { -9, 77 }, { 3, 24 },
- { 0, 42 }, { 0, 48 }, { 0, 55 }, { -6, 59 },
- { -7, 71 }, { -12, 83 }, { -11, 87 }, { -30, 119 },
- { 1, 58 }, { -3, 29 }, { -1, 36 }, { 1, 38 },
- { 2, 43 }, { -6, 55 }, { 0, 58 }, { 0, 64 },
- { -3, 74 }, { -10, 90 }, { -6, 76 }, { -2, 44 },
- { 0, 45 }, { 0, 52 }, { -3, 64 }, { -2, 59 },
- { -4, 70 }, { -4, 75 }, { -8, 82 }, { -17, 102 },
- { -9, 77 }, { 3, 24 }, { 0, 42 }, { 0, 48 },
- { 0, 55 }, { -6, 59 }, { -7, 71 }, { -12, 83 },
- { -11, 87 }, { -30, 119 }, { 1, 58 }, { -3, 29 },
- { -1, 36 }, { 1, 38 }, { 2, 43 }, { -6, 55 },
- { 0, 58 }, { 0, 64 }, { -3, 74 }, { -10, 90 },
- { -3, 74 }, { -9, 92 }, { -8, 87 }, { -23, 126 },
- { -3, 74 }, { -9, 92 }, { -8, 87 }, { -23, 126 },
- { -3, 74 }, { -9, 92 }, { -8, 87 }, { -23, 126 }
- },
-
- /* i_cabac_init_idc == 1 */
- {
- /* 0 - 10 */
- { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 },
- { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 },
- { -6, 53 }, { -1, 54 }, { 7, 51 },
-
- /* 11 - 23 */
- { 22, 25 }, { 34, 0 }, { 16, 0 }, { -2, 9 },
- { 4, 41 }, { -29, 118 }, { 2, 65 }, { -6, 71 },
- { -13, 79 }, { 5, 52 }, { 9, 50 }, { -3, 70 },
- { 10, 54 },
-
- /* 24 - 39 */
- { 26, 34 }, { 19, 22 }, { 40, 0 }, { 57, 2 },
- { 41, 36 }, { 26, 69 }, { -45, 127 }, { -15, 101 },
- { -4, 76 }, { -6, 71 }, { -13, 79 }, { 5, 52 },
- { 6, 69 }, { -13, 90 }, { 0, 52 }, { 8, 43 },
-
- /* 40 - 53 */
- { -2, 69 },{ -5, 82 },{ -10, 96 },{ 2, 59 },
- { 2, 75 },{ -3, 87 },{ -3, 100 },{ 1, 56 },
- { -3, 74 },{ -6, 85 },{ 0, 59 },{ -3, 81 },
- { -7, 86 },{ -5, 95 },
-
- /* 54 - 59 */
- { -1, 66 },{ -1, 77 },{ 1, 70 },{ -2, 86 },
- { -5, 72 },{ 0, 61 },
-
- /* 60 - 69 */
- { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 },
- { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 },
- { 13, 41 }, { 3, 62 },
-
- /* 70 - 104 */
- { 13, 15 }, { 7, 51 }, { 2, 80 }, { -39, 127 },
- { -18, 91 }, { -17, 96 }, { -26, 81 }, { -35, 98 },
- { -24, 102 }, { -23, 97 }, { -27, 119 }, { -24, 99 },
- { -21, 110 }, { -18, 102 }, { -36, 127 }, { 0, 80 },
- { -5, 89 }, { -7, 94 }, { -4, 92 }, { 0, 39 },
- { 0, 65 }, { -15, 84 }, { -35, 127 }, { -2, 73 },
- { -12, 104 }, { -9, 91 }, { -31, 127 }, { 3, 55 },
- { 7, 56 }, { 7, 55 }, { 8, 61 }, { -3, 53 },
- { 0, 68 }, { -7, 74 }, { -9, 88 },
-
- /* 105 -> 165 */
- { -13, 103 }, { -13, 91 }, { -9, 89 }, { -14, 92 },
- { -8, 76 }, { -12, 87 }, { -23, 110 }, { -24, 105 },
- { -10, 78 }, { -20, 112 }, { -17, 99 }, { -78, 127 },
- { -70, 127 }, { -50, 127 }, { -46, 127 }, { -4, 66 },
- { -5, 78 }, { -4, 71 }, { -8, 72 }, { 2, 59 },
- { -1, 55 }, { -7, 70 }, { -6, 75 }, { -8, 89 },
- { -34, 119 }, { -3, 75 }, { 32, 20 }, { 30, 22 },
- { -44, 127 }, { 0, 54 }, { -5, 61 }, { 0, 58 },
- { -1, 60 }, { -3, 61 }, { -8, 67 }, { -25, 84 },
- { -14, 74 }, { -5, 65 }, { 5, 52 }, { 2, 57 },
- { 0, 61 }, { -9, 69 }, { -11, 70 }, { 18, 55 },
- { -4, 71 }, { 0, 58 }, { 7, 61 }, { 9, 41 },
- { 18, 25 }, { 9, 32 }, { 5, 43 }, { 9, 47 },
- { 0, 44 }, { 0, 51 }, { 2, 46 }, { 19, 38 },
- { -4, 66 }, { 15, 38 }, { 12, 42 }, { 9, 34 },
- { 0, 89 },
-
- /* 166 - 226 */
- { 4, 45 }, { 10, 28 }, { 10, 31 }, { 33, -11 },
- { 52, -43 }, { 18, 15 }, { 28, 0 }, { 35, -22 },
- { 38, -25 }, { 34, 0 }, { 39, -18 }, { 32, -12 },
- { 102, -94 }, { 0, 0 }, { 56, -15 }, { 33, -4 },
- { 29, 10 }, { 37, -5 }, { 51, -29 }, { 39, -9 },
- { 52, -34 }, { 69, -58 }, { 67, -63 }, { 44, -5 },
- { 32, 7 }, { 55, -29 }, { 32, 1 }, { 0, 0 },
- { 27, 36 }, { 33, -25 }, { 34, -30 }, { 36, -28 },
- { 38, -28 }, { 38, -27 }, { 34, -18 }, { 35, -16 },
- { 34, -14 }, { 32, -8 }, { 37, -6 }, { 35, 0 },
- { 30, 10 }, { 28, 18 }, { 26, 25 }, { 29, 41 },
- { 0, 75 }, { 2, 72 }, { 8, 77 }, { 14, 35 },
- { 18, 31 }, { 17, 35 }, { 21, 30 }, { 17, 45 },
- { 20, 42 }, { 18, 45 }, { 27, 26 }, { 16, 54 },
- { 7, 66 }, { 16, 56 }, { 11, 73 }, { 10, 67 },
- { -10, 116 },
-
- /* 227 - 275 */
- { -23, 112 }, { -15, 71 }, { -7, 61 }, { 0, 53 },
- { -5, 66 }, { -11, 77 }, { -9, 80 }, { -9, 84 },
- { -10, 87 }, { -34, 127 }, { -21, 101 }, { -3, 39 },
- { -5, 53 }, { -7, 61 }, { -11, 75 }, { -15, 77 },
- { -17, 91 }, { -25, 107 }, { -25, 111 }, { -28, 122 },
- { -11, 76 }, { -10, 44 }, { -10, 52 }, { -10, 57 },
- { -9, 58 }, { -16, 72 }, { -7, 69 }, { -4, 69 },
- { -5, 74 }, { -9, 86 }, { 2, 66 }, { -9, 34 },
- { 1, 32 }, { 11, 31 }, { 5, 52 }, { -2, 55 },
- { -2, 67 }, { 0, 73 }, { -8, 89 }, { 3, 52 },
- { 7, 4 }, { 10, 8 }, { 17, 8 }, { 16, 19 },
- { 3, 37 }, { -1, 61 }, { -5, 73 }, { -1, 70 },
- { -4, 78 },
-
- /* 276 a bit special (not used, bypass is used instead) */
- { 0, 0 },
-
- /* 277 - 337 */
- { -21, 126 }, { -23, 124 }, { -20, 110 }, { -26, 126 },
- { -25, 124 }, { -17, 105 }, { -27, 121 }, { -27, 117 },
- { -17, 102 }, { -26, 117 }, { -27, 116 }, { -33, 122 },
- { -10, 95 }, { -14, 100 }, { -8, 95 }, { -17, 111 },
- { -28, 114 }, { -6, 89 }, { -2, 80 }, { -4, 82 },
- { -9, 85 }, { -8, 81 }, { -1, 72 }, { 5, 64 },
- { 1, 67 }, { 9, 56 }, { 0, 69 }, { 1, 69 },
- { 7, 69 }, { -7, 69 }, { -6, 67 }, { -16, 77 },
- { -2, 64 }, { 2, 61 }, { -6, 67 }, { -3, 64 },
- { 2, 57 }, { -3, 65 }, { -3, 66 }, { 0, 62 },
- { 9, 51 }, { -1, 66 }, { -2, 71 }, { -2, 75 },
- { -1, 70 }, { -9, 72 }, { 14, 60 }, { 16, 37 },
- { 0, 47 }, { 18, 35 }, { 11, 37 }, { 12, 41 },
- { 10, 41 }, { 2, 48 }, { 12, 41 }, { 13, 41 },
- { 0, 59 }, { 3, 50 }, { 19, 40 }, { 3, 66 },
- { 18, 50 },
-
- /* 338 - 398 */
- { 19, -6 }, { 18, -6 }, { 14, 0 }, { 26, -12 },
- { 31, -16 }, { 33, -25 }, { 33, -22 }, { 37, -28 },
- { 39, -30 }, { 42, -30 }, { 47, -42 }, { 45, -36 },
- { 49, -34 }, { 41, -17 }, { 32, 9 }, { 69, -71 },
- { 63, -63 }, { 66, -64 }, { 77, -74 }, { 54, -39 },
- { 52, -35 }, { 41, -10 }, { 36, 0 }, { 40, -1 },
- { 30, 14 }, { 28, 26 }, { 23, 37 }, { 12, 55 },
- { 11, 65 }, { 37, -33 }, { 39, -36 }, { 40, -37 },
- { 38, -30 }, { 46, -33 }, { 42, -30 }, { 40, -24 },
- { 49, -29 }, { 38, -12 }, { 40, -10 }, { 38, -3 },
- { 46, -5 }, { 31, 20 }, { 29, 30 }, { 25, 44 },
- { 12, 48 }, { 11, 49 }, { 26, 45 }, { 22, 22 },
- { 23, 22 }, { 27, 21 }, { 33, 20 }, { 26, 28 },
- { 30, 24 }, { 27, 34 }, { 18, 42 }, { 25, 39 },
- { 18, 50 }, { 12, 70 }, { 21, 54 }, { 14, 71 },
- { 11, 83 },
-
- /* 399 - 435 */
- { 25, 32 }, { 21, 49 }, { 21, 54 },
- { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 },
- { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 },
- { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 },
- { -14, 66 }, { 0, 59 }, { 2, 59 }, { 17, -10 },
- { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 },
- { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 },
- { -5, 71 }, { 0, 24 }, { -1, 36 }, { -2, 42 },
- { -2, 52 }, { -9, 57 }, { -6, 63 }, { -4, 65 },
- { -4, 67 }, { -7, 82 },
-
- /* 436 - 459 */
- { -3, 81 }, { -3, 76 }, { -7, 72 }, { -6, 78 },
- { -12, 72 }, { -14, 68 }, { -3, 70 }, { -6, 76 },
- { -5, 66 }, { -5, 62 }, { 0, 57 }, { -4, 61 },
- { -9, 60 }, { 1, 54 }, { 2, 58 }, { 17, -10 },
- { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 },
- { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 },
-
- /* 460 - 1024 */
- { 0, 80 }, { -5, 89 }, { -7, 94 }, { -4, 92 },
- { 0, 39 }, { 0, 65 }, { -15, 84 }, { -35, 127 },
- { -2, 73 }, { -12, 104 }, { -9, 91 }, { -31, 127 },
- { 0, 80 }, { -5, 89 }, { -7, 94 }, { -4, 92 },
- { 0, 39 }, { 0, 65 }, { -15, 84 }, { -35, 127 },
- { -2, 73 }, { -12, 104 }, { -9, 91 }, { -31, 127 },
- { -13, 103 }, { -13, 91 }, { -9, 89 }, { -14, 92 },
- { -8, 76 }, { -12, 87 }, { -23, 110 }, { -24, 105 },
- { -10, 78 }, { -20, 112 }, { -17, 99 }, { -78, 127 },
- { -70, 127 }, { -50, 127 }, { -46, 127 }, { -4, 66 },
- { -5, 78 }, { -4, 71 }, { -8, 72 }, { 2, 59 },
- { -1, 55 }, { -7, 70 }, { -6, 75 }, { -8, 89 },
- { -34, 119 }, { -3, 75 }, { 32, 20 }, { 30, 22 },
- { -44, 127 }, { 0, 54 }, { -5, 61 }, { 0, 58 },
- { -1, 60 }, { -3, 61 }, { -8, 67 }, { -25, 84 },
- { -14, 74 }, { -5, 65 }, { 5, 52 }, { 2, 57 },
- { 0, 61 }, { -9, 69 }, { -11, 70 }, { 18, 55 },
- { -13, 103 }, { -13, 91 }, { -9, 89 }, { -14, 92 },
- { -8, 76 }, { -12, 87 }, { -23, 110 }, { -24, 105 },
- { -10, 78 }, { -20, 112 }, { -17, 99 }, { -78, 127 },
- { -70, 127 }, { -50, 127 }, { -46, 127 }, { -4, 66 },
- { -5, 78 }, { -4, 71 }, { -8, 72 }, { 2, 59 },
- { -1, 55 }, { -7, 70 }, { -6, 75 }, { -8, 89 },
- { -34, 119 }, { -3, 75 }, { 32, 20 }, { 30, 22 },
- { -44, 127 }, { 0, 54 }, { -5, 61 }, { 0, 58 },
- { -1, 60 }, { -3, 61 }, { -8, 67 }, { -25, 84 },
- { -14, 74 }, { -5, 65 }, { 5, 52 }, { 2, 57 },
- { 0, 61 }, { -9, 69 }, { -11, 70 }, { 18, 55 },
- { 4, 45 }, { 10, 28 }, { 10, 31 }, { 33, -11 },
- { 52, -43 }, { 18, 15 }, { 28, 0 }, { 35, -22 },
- { 38, -25 }, { 34, 0 }, { 39, -18 }, { 32, -12 },
- { 102, -94 }, { 0, 0 }, { 56, -15 }, { 33, -4 },
- { 29, 10 }, { 37, -5 }, { 51, -29 }, { 39, -9 },
- { 52, -34 }, { 69, -58 }, { 67, -63 }, { 44, -5 },
- { 32, 7 }, { 55, -29 }, { 32, 1 }, { 0, 0 },
- { 27, 36 }, { 33, -25 }, { 34, -30 }, { 36, -28 },
- { 38, -28 }, { 38, -27 }, { 34, -18 }, { 35, -16 },
- { 34, -14 }, { 32, -8 }, { 37, -6 }, { 35, 0 },
- { 30, 10 }, { 28, 18 }, { 26, 25 }, { 29, 41 },
- { 4, 45 }, { 10, 28 }, { 10, 31 }, { 33, -11 },
- { 52, -43 }, { 18, 15 }, { 28, 0 }, { 35, -22 },
- { 38, -25 }, { 34, 0 }, { 39, -18 }, { 32, -12 },
- { 102, -94 }, { 0, 0 }, { 56, -15 }, { 33, -4 },
- { 29, 10 }, { 37, -5 }, { 51, -29 }, { 39, -9 },
- { 52, -34 }, { 69, -58 }, { 67, -63 }, { 44, -5 },
- { 32, 7 }, { 55, -29 }, { 32, 1 }, { 0, 0 },
- { 27, 36 }, { 33, -25 }, { 34, -30 }, { 36, -28 },
- { 38, -28 }, { 38, -27 }, { 34, -18 }, { 35, -16 },
- { 34, -14 }, { 32, -8 }, { 37, -6 }, { 35, 0 },
- { 30, 10 }, { 28, 18 }, { 26, 25 }, { 29, 41 },
- { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 },
- { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 },
- { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 },
- { -14, 66 }, { 0, 59 }, { 2, 59 }, { -3, 81 },
- { -3, 76 }, { -7, 72 }, { -6, 78 }, { -12, 72 },
- { -14, 68 }, { -3, 70 }, { -6, 76 }, { -5, 66 },
- { -5, 62 }, { 0, 57 }, { -4, 61 }, { -9, 60 },
- { 1, 54 }, { 2, 58 }, { 17, -10 }, { 32, -13 },
- { 42, -9 }, { 49, -5 }, { 53, 0 }, { 64, 3 },
- { 68, 10 }, { 66, 27 }, { 47, 57 }, { 17, -10 },
- { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 },
- { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 },
- { -5, 71 }, { 0, 24 }, { -1, 36 }, { -2, 42 },
- { -2, 52 }, { -9, 57 }, { -6, 63 }, { -4, 65 },
- { -4, 67 }, { -7, 82 }, { -5, 85 }, { -6, 81 },
- { -10, 77 }, { -7, 81 }, { -17, 80 }, { -18, 73 },
- { -4, 74 }, { -10, 83 }, { -9, 71 }, { -9, 67 },
- { -1, 61 }, { -8, 66 }, { -14, 66 }, { 0, 59 },
- { 2, 59 }, { -3, 81 }, { -3, 76 }, { -7, 72 },
- { -6, 78 }, { -12, 72 }, { -14, 68 }, { -3, 70 },
- { -6, 76 }, { -5, 66 }, { -5, 62 }, { 0, 57 },
- { -4, 61 }, { -9, 60 }, { 1, 54 }, { 2, 58 },
- { 17, -10 }, { 32, -13 }, { 42, -9 }, { 49, -5 },
- { 53, 0 }, { 64, 3 }, { 68, 10 }, { 66, 27 },
- { 47, 57 }, { 17, -10 }, { 32, -13 }, { 42, -9 },
- { 49, -5 }, { 53, 0 }, { 64, 3 }, { 68, 10 },
- { 66, 27 }, { 47, 57 }, { -5, 71 }, { 0, 24 },
- { -1, 36 }, { -2, 42 }, { -2, 52 }, { -9, 57 },
- { -6, 63 }, { -4, 65 }, { -4, 67 }, { -7, 82 },
- { -21, 126 }, { -23, 124 }, { -20, 110 }, { -26, 126 },
- { -25, 124 }, { -17, 105 }, { -27, 121 }, { -27, 117 },
- { -17, 102 }, { -26, 117 }, { -27, 116 }, { -33, 122 },
- { -10, 95 }, { -14, 100 }, { -8, 95 }, { -17, 111 },
- { -28, 114 }, { -6, 89 }, { -2, 80 }, { -4, 82 },
- { -9, 85 }, { -8, 81 }, { -1, 72 }, { 5, 64 },
- { 1, 67 }, { 9, 56 }, { 0, 69 }, { 1, 69 },
- { 7, 69 }, { -7, 69 }, { -6, 67 }, { -16, 77 },
- { -2, 64 }, { 2, 61 }, { -6, 67 }, { -3, 64 },
- { 2, 57 }, { -3, 65 }, { -3, 66 }, { 0, 62 },
- { 9, 51 }, { -1, 66 }, { -2, 71 }, { -2, 75 },
- { -21, 126 }, { -23, 124 }, { -20, 110 }, { -26, 126 },
- { -25, 124 }, { -17, 105 }, { -27, 121 }, { -27, 117 },
- { -17, 102 }, { -26, 117 }, { -27, 116 }, { -33, 122 },
- { -10, 95 }, { -14, 100 }, { -8, 95 }, { -17, 111 },
- { -28, 114 }, { -6, 89 }, { -2, 80 }, { -4, 82 },
- { -9, 85 }, { -8, 81 }, { -1, 72 }, { 5, 64 },
- { 1, 67 }, { 9, 56 }, { 0, 69 }, { 1, 69 },
- { 7, 69 }, { -7, 69 }, { -6, 67 }, { -16, 77 },
- { -2, 64 }, { 2, 61 }, { -6, 67 }, { -3, 64 },
- { 2, 57 }, { -3, 65 }, { -3, 66 }, { 0, 62 },
- { 9, 51 }, { -1, 66 }, { -2, 71 }, { -2, 75 },
- { 19, -6 }, { 18, -6 }, { 14, 0 }, { 26, -12 },
- { 31, -16 }, { 33, -25 }, { 33, -22 }, { 37, -28 },
- { 39, -30 }, { 42, -30 }, { 47, -42 }, { 45, -36 },
- { 49, -34 }, { 41, -17 }, { 32, 9 }, { 69, -71 },
- { 63, -63 }, { 66, -64 }, { 77, -74 }, { 54, -39 },
- { 52, -35 }, { 41, -10 }, { 36, 0 }, { 40, -1 },
- { 30, 14 }, { 28, 26 }, { 23, 37 }, { 12, 55 },
- { 11, 65 }, { 37, -33 }, { 39, -36 }, { 40, -37 },
- { 38, -30 }, { 46, -33 }, { 42, -30 }, { 40, -24 },
- { 49, -29 }, { 38, -12 }, { 40, -10 }, { 38, -3 },
- { 46, -5 }, { 31, 20 }, { 29, 30 }, { 25, 44 },
- { 19, -6 }, { 18, -6 }, { 14, 0 }, { 26, -12 },
- { 31, -16 }, { 33, -25 }, { 33, -22 }, { 37, -28 },
- { 39, -30 }, { 42, -30 }, { 47, -42 }, { 45, -36 },
- { 49, -34 }, { 41, -17 }, { 32, 9 }, { 69, -71 },
- { 63, -63 }, { 66, -64 }, { 77, -74 }, { 54, -39 },
- { 52, -35 }, { 41, -10 }, { 36, 0 }, { 40, -1 },
- { 30, 14 }, { 28, 26 }, { 23, 37 }, { 12, 55 },
- { 11, 65 }, { 37, -33 }, { 39, -36 }, { 40, -37 },
- { 38, -30 }, { 46, -33 }, { 42, -30 }, { 40, -24 },
- { 49, -29 }, { 38, -12 }, { 40, -10 }, { 38, -3 },
- { 46, -5 }, { 31, 20 }, { 29, 30 }, { 25, 44 },
- { -23, 112 }, { -15, 71 }, { -7, 61 }, { 0, 53 },
- { -5, 66 }, { -11, 77 }, { -9, 80 }, { -9, 84 },
- { -10, 87 }, { -34, 127 }, { -21, 101 }, { -3, 39 },
- { -5, 53 }, { -7, 61 }, { -11, 75 }, { -15, 77 },
- { -17, 91 }, { -25, 107 }, { -25, 111 }, { -28, 122 },
- { -11, 76 }, { -10, 44 }, { -10, 52 }, { -10, 57 },
- { -9, 58 }, { -16, 72 }, { -7, 69 }, { -4, 69 },
- { -5, 74 }, { -9, 86 }, { -23, 112 }, { -15, 71 },
- { -7, 61 }, { 0, 53 }, { -5, 66 }, { -11, 77 },
- { -9, 80 }, { -9, 84 }, { -10, 87 }, { -34, 127 },
- { -21, 101 }, { -3, 39 }, { -5, 53 }, { -7, 61 },
- { -11, 75 }, { -15, 77 }, { -17, 91 }, { -25, 107 },
- { -25, 111 }, { -28, 122 }, { -11, 76 }, { -10, 44 },
- { -10, 52 }, { -10, 57 }, { -9, 58 }, { -16, 72 },
- { -7, 69 }, { -4, 69 }, { -5, 74 }, { -9, 86 },
- { -2, 73 }, { -12, 104 }, { -9, 91 }, { -31, 127 },
- { -2, 73 }, { -12, 104 }, { -9, 91 }, { -31, 127 },
- { -2, 73 }, { -12, 104 }, { -9, 91 }, { -31, 127 }
- },
-
- /* i_cabac_init_idc == 2 */
- {
- /* 0 - 10 */
- { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 },
- { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 },
- { -6, 53 }, { -1, 54 }, { 7, 51 },
-
- /* 11 - 23 */
- { 29, 16 }, { 25, 0 }, { 14, 0 }, { -10, 51 },
- { -3, 62 }, { -27, 99 }, { 26, 16 }, { -4, 85 },
- { -24, 102 }, { 5, 57 }, { 6, 57 }, { -17, 73 },
- { 14, 57 },
-
- /* 24 - 39 */
- { 20, 40 }, { 20, 10 }, { 29, 0 }, { 54, 0 },
- { 37, 42 }, { 12, 97 }, { -32, 127 }, { -22, 117 },
- { -2, 74 }, { -4, 85 }, { -24, 102 }, { 5, 57 },
- { -6, 93 }, { -14, 88 }, { -6, 44 }, { 4, 55 },
-
- /* 40 - 53 */
- { -11, 89 },{ -15, 103 },{ -21, 116 },{ 19, 57 },
- { 20, 58 },{ 4, 84 },{ 6, 96 },{ 1, 63 },
- { -5, 85 },{ -13, 106 },{ 5, 63 },{ 6, 75 },
- { -3, 90 },{ -1, 101 },
-
- /* 54 - 59 */
- { 3, 55 },{ -4, 79 },{ -2, 75 },{ -12, 97 },
- { -7, 50 },{ 1, 60 },
-
- /* 60 - 69 */
- { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 },
- { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 },
- { 13, 41 }, { 3, 62 },
-
- /* 70 - 104 */
- { 7, 34 }, { -9, 88 }, { -20, 127 }, { -36, 127 },
- { -17, 91 }, { -14, 95 }, { -25, 84 }, { -25, 86 },
- { -12, 89 }, { -17, 91 }, { -31, 127 }, { -14, 76 },
- { -18, 103 }, { -13, 90 }, { -37, 127 }, { 11, 80 },
- { 5, 76 }, { 2, 84 }, { 5, 78 }, { -6, 55 },
- { 4, 61 }, { -14, 83 }, { -37, 127 }, { -5, 79 },
- { -11, 104 }, { -11, 91 }, { -30, 127 }, { 0, 65 },
- { -2, 79 }, { 0, 72 }, { -4, 92 }, { -6, 56 },
- { 3, 68 }, { -8, 71 }, { -13, 98 },
-
- /* 105 -> 165 */
- { -4, 86 }, { -12, 88 }, { -5, 82 }, { -3, 72 },
- { -4, 67 }, { -8, 72 }, { -16, 89 }, { -9, 69 },
- { -1, 59 }, { 5, 66 }, { 4, 57 }, { -4, 71 },
- { -2, 71 }, { 2, 58 }, { -1, 74 }, { -4, 44 },
- { -1, 69 }, { 0, 62 }, { -7, 51 }, { -4, 47 },
- { -6, 42 }, { -3, 41 }, { -6, 53 }, { 8, 76 },
- { -9, 78 }, { -11, 83 }, { 9, 52 }, { 0, 67 },
- { -5, 90 }, { 1, 67 }, { -15, 72 }, { -5, 75 },
- { -8, 80 }, { -21, 83 }, { -21, 64 }, { -13, 31 },
- { -25, 64 }, { -29, 94 }, { 9, 75 }, { 17, 63 },
- { -8, 74 }, { -5, 35 }, { -2, 27 }, { 13, 91 },
- { 3, 65 }, { -7, 69 }, { 8, 77 }, { -10, 66 },
- { 3, 62 }, { -3, 68 }, { -20, 81 }, { 0, 30 },
- { 1, 7 }, { -3, 23 }, { -21, 74 }, { 16, 66 },
- { -23, 124 }, { 17, 37 }, { 44, -18 }, { 50, -34 },
- { -22, 127 },
-
- /* 166 - 226 */
- { 4, 39 }, { 0, 42 }, { 7, 34 }, { 11, 29 },
- { 8, 31 }, { 6, 37 }, { 7, 42 }, { 3, 40 },
- { 8, 33 }, { 13, 43 }, { 13, 36 }, { 4, 47 },
- { 3, 55 }, { 2, 58 }, { 6, 60 }, { 8, 44 },
- { 11, 44 }, { 14, 42 }, { 7, 48 }, { 4, 56 },
- { 4, 52 }, { 13, 37 }, { 9, 49 }, { 19, 58 },
- { 10, 48 }, { 12, 45 }, { 0, 69 }, { 20, 33 },
- { 8, 63 }, { 35, -18 }, { 33, -25 }, { 28, -3 },
- { 24, 10 }, { 27, 0 }, { 34, -14 }, { 52, -44 },
- { 39, -24 }, { 19, 17 }, { 31, 25 }, { 36, 29 },
- { 24, 33 }, { 34, 15 }, { 30, 20 }, { 22, 73 },
- { 20, 34 }, { 19, 31 }, { 27, 44 }, { 19, 16 },
- { 15, 36 }, { 15, 36 }, { 21, 28 }, { 25, 21 },
- { 30, 20 }, { 31, 12 }, { 27, 16 }, { 24, 42 },
- { 0, 93 }, { 14, 56 }, { 15, 57 }, { 26, 38 },
- { -24, 127 },
-
- /* 227 - 275 */
- { -24, 115 }, { -22, 82 }, { -9, 62 }, { 0, 53 },
- { 0, 59 }, { -14, 85 }, { -13, 89 }, { -13, 94 },
- { -11, 92 }, { -29, 127 }, { -21, 100 }, { -14, 57 },
- { -12, 67 }, { -11, 71 }, { -10, 77 }, { -21, 85 },
- { -16, 88 }, { -23, 104 }, { -15, 98 }, { -37, 127 },
- { -10, 82 }, { -8, 48 }, { -8, 61 }, { -8, 66 },
- { -7, 70 }, { -14, 75 }, { -10, 79 }, { -9, 83 },
- { -12, 92 }, { -18, 108 }, { -4, 79 }, { -22, 69 },
- { -16, 75 }, { -2, 58 }, { 1, 58 }, { -13, 78 },
- { -9, 83 }, { -4, 81 }, { -13, 99 }, { -13, 81 },
- { -6, 38 }, { -13, 62 }, { -6, 58 }, { -2, 59 },
- { -16, 73 }, { -10, 76 }, { -13, 86 }, { -9, 83 },
- { -10, 87 },
-
- /* 276 a bit special (not used, bypass is used instead) */
- { 0, 0 },
-
- /* 277 - 337 */
- { -22, 127 }, { -25, 127 }, { -25, 120 }, { -27, 127 },
- { -19, 114 }, { -23, 117 }, { -25, 118 }, { -26, 117 },
- { -24, 113 }, { -28, 118 }, { -31, 120 }, { -37, 124 },
- { -10, 94 }, { -15, 102 }, { -10, 99 }, { -13, 106 },
- { -50, 127 }, { -5, 92 }, { 17, 57 }, { -5, 86 },
- { -13, 94 }, { -12, 91 }, { -2, 77 }, { 0, 71 },
- { -1, 73 }, { 4, 64 }, { -7, 81 }, { 5, 64 },
- { 15, 57 }, { 1, 67 }, { 0, 68 }, { -10, 67 },
- { 1, 68 }, { 0, 77 }, { 2, 64 }, { 0, 68 },
- { -5, 78 }, { 7, 55 }, { 5, 59 }, { 2, 65 },
- { 14, 54 }, { 15, 44 }, { 5, 60 }, { 2, 70 },
- { -2, 76 }, { -18, 86 }, { 12, 70 }, { 5, 64 },
- { -12, 70 }, { 11, 55 }, { 5, 56 }, { 0, 69 },
- { 2, 65 }, { -6, 74 }, { 5, 54 }, { 7, 54 },
- { -6, 76 }, { -11, 82 }, { -2, 77 }, { -2, 77 },
- { 25, 42 },
-
- /* 338 - 398 */
- { 17, -13 }, { 16, -9 }, { 17, -12 }, { 27, -21 },
- { 37, -30 }, { 41, -40 }, { 42, -41 }, { 48, -47 },
- { 39, -32 }, { 46, -40 }, { 52, -51 }, { 46, -41 },
- { 52, -39 }, { 43, -19 }, { 32, 11 }, { 61, -55 },
- { 56, -46 }, { 62, -50 }, { 81, -67 }, { 45, -20 },
- { 35, -2 }, { 28, 15 }, { 34, 1 }, { 39, 1 },
- { 30, 17 }, { 20, 38 }, { 18, 45 }, { 15, 54 },
- { 0, 79 }, { 36, -16 }, { 37, -14 }, { 37, -17 },
- { 32, 1 }, { 34, 15 }, { 29, 15 }, { 24, 25 },
- { 34, 22 }, { 31, 16 }, { 35, 18 }, { 31, 28 },
- { 33, 41 }, { 36, 28 }, { 27, 47 }, { 21, 62 },
- { 18, 31 }, { 19, 26 }, { 36, 24 }, { 24, 23 },
- { 27, 16 }, { 24, 30 }, { 31, 29 }, { 22, 41 },
- { 22, 42 }, { 16, 60 }, { 15, 52 }, { 14, 60 },
- { 3, 78 }, { -16, 123 }, { 21, 53 }, { 22, 56 },
- { 25, 61 },
-
- /* 399 - 435 */
- { 21, 33 }, { 19, 50 }, { 17, 61 },
- { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 },
- { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 },
- { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 },
- { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 },
- { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 },
- { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 },
- { -9, 71 }, { -7, 37 }, { -8, 44 }, { -11, 49 },
- { -10, 56 }, { -12, 59 }, { -8, 63 }, { -9, 67 },
- { -6, 68 }, { -10, 79 },
-
- /* 436 - 459 */
- { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 },
- { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 },
- { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 },
- { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 },
- { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 },
- { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 },
-
- /* 460 - 1024 */
- { 11, 80 }, { 5, 76 }, { 2, 84 }, { 5, 78 },
- { -6, 55 }, { 4, 61 }, { -14, 83 }, { -37, 127 },
- { -5, 79 }, { -11, 104 }, { -11, 91 }, { -30, 127 },
- { 11, 80 }, { 5, 76 }, { 2, 84 }, { 5, 78 },
- { -6, 55 }, { 4, 61 }, { -14, 83 }, { -37, 127 },
- { -5, 79 }, { -11, 104 }, { -11, 91 }, { -30, 127 },
- { -4, 86 }, { -12, 88 }, { -5, 82 }, { -3, 72 },
- { -4, 67 }, { -8, 72 }, { -16, 89 }, { -9, 69 },
- { -1, 59 }, { 5, 66 }, { 4, 57 }, { -4, 71 },
- { -2, 71 }, { 2, 58 }, { -1, 74 }, { -4, 44 },
- { -1, 69 }, { 0, 62 }, { -7, 51 }, { -4, 47 },
- { -6, 42 }, { -3, 41 }, { -6, 53 }, { 8, 76 },
- { -9, 78 }, { -11, 83 }, { 9, 52 }, { 0, 67 },
- { -5, 90 }, { 1, 67 }, { -15, 72 }, { -5, 75 },
- { -8, 80 }, { -21, 83 }, { -21, 64 }, { -13, 31 },
- { -25, 64 }, { -29, 94 }, { 9, 75 }, { 17, 63 },
- { -8, 74 }, { -5, 35 }, { -2, 27 }, { 13, 91 },
- { -4, 86 }, { -12, 88 }, { -5, 82 }, { -3, 72 },
- { -4, 67 }, { -8, 72 }, { -16, 89 }, { -9, 69 },
- { -1, 59 }, { 5, 66 }, { 4, 57 }, { -4, 71 },
- { -2, 71 }, { 2, 58 }, { -1, 74 }, { -4, 44 },
- { -1, 69 }, { 0, 62 }, { -7, 51 }, { -4, 47 },
- { -6, 42 }, { -3, 41 }, { -6, 53 }, { 8, 76 },
- { -9, 78 }, { -11, 83 }, { 9, 52 }, { 0, 67 },
- { -5, 90 }, { 1, 67 }, { -15, 72 }, { -5, 75 },
- { -8, 80 }, { -21, 83 }, { -21, 64 }, { -13, 31 },
- { -25, 64 }, { -29, 94 }, { 9, 75 }, { 17, 63 },
- { -8, 74 }, { -5, 35 }, { -2, 27 }, { 13, 91 },
- { 4, 39 }, { 0, 42 }, { 7, 34 }, { 11, 29 },
- { 8, 31 }, { 6, 37 }, { 7, 42 }, { 3, 40 },
- { 8, 33 }, { 13, 43 }, { 13, 36 }, { 4, 47 },
- { 3, 55 }, { 2, 58 }, { 6, 60 }, { 8, 44 },
- { 11, 44 }, { 14, 42 }, { 7, 48 }, { 4, 56 },
- { 4, 52 }, { 13, 37 }, { 9, 49 }, { 19, 58 },
- { 10, 48 }, { 12, 45 }, { 0, 69 }, { 20, 33 },
- { 8, 63 }, { 35, -18 }, { 33, -25 }, { 28, -3 },
- { 24, 10 }, { 27, 0 }, { 34, -14 }, { 52, -44 },
- { 39, -24 }, { 19, 17 }, { 31, 25 }, { 36, 29 },
- { 24, 33 }, { 34, 15 }, { 30, 20 }, { 22, 73 },
- { 4, 39 }, { 0, 42 }, { 7, 34 }, { 11, 29 },
- { 8, 31 }, { 6, 37 }, { 7, 42 }, { 3, 40 },
- { 8, 33 }, { 13, 43 }, { 13, 36 }, { 4, 47 },
- { 3, 55 }, { 2, 58 }, { 6, 60 }, { 8, 44 },
- { 11, 44 }, { 14, 42 }, { 7, 48 }, { 4, 56 },
- { 4, 52 }, { 13, 37 }, { 9, 49 }, { 19, 58 },
- { 10, 48 }, { 12, 45 }, { 0, 69 }, { 20, 33 },
- { 8, 63 }, { 35, -18 }, { 33, -25 }, { 28, -3 },
- { 24, 10 }, { 27, 0 }, { 34, -14 }, { 52, -44 },
- { 39, -24 }, { 19, 17 }, { 31, 25 }, { 36, 29 },
- { 24, 33 }, { 34, 15 }, { 30, 20 }, { 22, 73 },
- { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 },
- { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 },
- { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 },
- { -14, 59 }, { -9, 52 }, { -11, 68 }, { -3, 78 },
- { -8, 74 }, { -9, 72 }, { -10, 72 }, { -18, 75 },
- { -12, 71 }, { -11, 63 }, { -5, 70 }, { -17, 75 },
- { -14, 72 }, { -16, 67 }, { -8, 53 }, { -14, 59 },
- { -9, 52 }, { -11, 68 }, { 9, -2 }, { 30, -10 },
- { 31, -4 }, { 33, -1 }, { 33, 7 }, { 31, 12 },
- { 37, 23 }, { 31, 38 }, { 20, 64 }, { 9, -2 },
- { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 },
- { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 },
- { -9, 71 }, { -7, 37 }, { -8, 44 }, { -11, 49 },
- { -10, 56 }, { -12, 59 }, { -8, 63 }, { -9, 67 },
- { -6, 68 }, { -10, 79 }, { -3, 78 }, { -8, 74 },
- { -9, 72 }, { -10, 72 }, { -18, 75 }, { -12, 71 },
- { -11, 63 }, { -5, 70 }, { -17, 75 }, { -14, 72 },
- { -16, 67 }, { -8, 53 }, { -14, 59 }, { -9, 52 },
- { -11, 68 }, { -3, 78 }, { -8, 74 }, { -9, 72 },
- { -10, 72 }, { -18, 75 }, { -12, 71 }, { -11, 63 },
- { -5, 70 }, { -17, 75 }, { -14, 72 }, { -16, 67 },
- { -8, 53 }, { -14, 59 }, { -9, 52 }, { -11, 68 },
- { 9, -2 }, { 30, -10 }, { 31, -4 }, { 33, -1 },
- { 33, 7 }, { 31, 12 }, { 37, 23 }, { 31, 38 },
- { 20, 64 }, { 9, -2 }, { 30, -10 }, { 31, -4 },
- { 33, -1 }, { 33, 7 }, { 31, 12 }, { 37, 23 },
- { 31, 38 }, { 20, 64 }, { -9, 71 }, { -7, 37 },
- { -8, 44 }, { -11, 49 }, { -10, 56 }, { -12, 59 },
- { -8, 63 }, { -9, 67 }, { -6, 68 }, { -10, 79 },
- { -22, 127 }, { -25, 127 }, { -25, 120 }, { -27, 127 },
- { -19, 114 }, { -23, 117 }, { -25, 118 }, { -26, 117 },
- { -24, 113 }, { -28, 118 }, { -31, 120 }, { -37, 124 },
- { -10, 94 }, { -15, 102 }, { -10, 99 }, { -13, 106 },
- { -50, 127 }, { -5, 92 }, { 17, 57 }, { -5, 86 },
- { -13, 94 }, { -12, 91 }, { -2, 77 }, { 0, 71 },
- { -1, 73 }, { 4, 64 }, { -7, 81 }, { 5, 64 },
- { 15, 57 }, { 1, 67 }, { 0, 68 }, { -10, 67 },
- { 1, 68 }, { 0, 77 }, { 2, 64 }, { 0, 68 },
- { -5, 78 }, { 7, 55 }, { 5, 59 }, { 2, 65 },
- { 14, 54 }, { 15, 44 }, { 5, 60 }, { 2, 70 },
- { -22, 127 }, { -25, 127 }, { -25, 120 }, { -27, 127 },
- { -19, 114 }, { -23, 117 }, { -25, 118 }, { -26, 117 },
- { -24, 113 }, { -28, 118 }, { -31, 120 }, { -37, 124 },
- { -10, 94 }, { -15, 102 }, { -10, 99 }, { -13, 106 },
- { -50, 127 }, { -5, 92 }, { 17, 57 }, { -5, 86 },
- { -13, 94 }, { -12, 91 }, { -2, 77 }, { 0, 71 },
- { -1, 73 }, { 4, 64 }, { -7, 81 }, { 5, 64 },
- { 15, 57 }, { 1, 67 }, { 0, 68 }, { -10, 67 },
- { 1, 68 }, { 0, 77 }, { 2, 64 }, { 0, 68 },
- { -5, 78 }, { 7, 55 }, { 5, 59 }, { 2, 65 },
- { 14, 54 }, { 15, 44 }, { 5, 60 }, { 2, 70 },
- { 17, -13 }, { 16, -9 }, { 17, -12 }, { 27, -21 },
- { 37, -30 }, { 41, -40 }, { 42, -41 }, { 48, -47 },
- { 39, -32 }, { 46, -40 }, { 52, -51 }, { 46, -41 },
- { 52, -39 }, { 43, -19 }, { 32, 11 }, { 61, -55 },
- { 56, -46 }, { 62, -50 }, { 81, -67 }, { 45, -20 },
- { 35, -2 }, { 28, 15 }, { 34, 1 }, { 39, 1 },
- { 30, 17 }, { 20, 38 }, { 18, 45 }, { 15, 54 },
- { 0, 79 }, { 36, -16 }, { 37, -14 }, { 37, -17 },
- { 32, 1 }, { 34, 15 }, { 29, 15 }, { 24, 25 },
- { 34, 22 }, { 31, 16 }, { 35, 18 }, { 31, 28 },
- { 33, 41 }, { 36, 28 }, { 27, 47 }, { 21, 62 },
- { 17, -13 }, { 16, -9 }, { 17, -12 }, { 27, -21 },
- { 37, -30 }, { 41, -40 }, { 42, -41 }, { 48, -47 },
- { 39, -32 }, { 46, -40 }, { 52, -51 }, { 46, -41 },
- { 52, -39 }, { 43, -19 }, { 32, 11 }, { 61, -55 },
- { 56, -46 }, { 62, -50 }, { 81, -67 }, { 45, -20 },
- { 35, -2 }, { 28, 15 }, { 34, 1 }, { 39, 1 },
- { 30, 17 }, { 20, 38 }, { 18, 45 }, { 15, 54 },
- { 0, 79 }, { 36, -16 }, { 37, -14 }, { 37, -17 },
- { 32, 1 }, { 34, 15 }, { 29, 15 }, { 24, 25 },
- { 34, 22 }, { 31, 16 }, { 35, 18 }, { 31, 28 },
- { 33, 41 }, { 36, 28 }, { 27, 47 }, { 21, 62 },
- { -24, 115 }, { -22, 82 }, { -9, 62 }, { 0, 53 },
- { 0, 59 }, { -14, 85 }, { -13, 89 }, { -13, 94 },
- { -11, 92 }, { -29, 127 }, { -21, 100 }, { -14, 57 },
- { -12, 67 }, { -11, 71 }, { -10, 77 }, { -21, 85 },
- { -16, 88 }, { -23, 104 }, { -15, 98 }, { -37, 127 },
- { -10, 82 }, { -8, 48 }, { -8, 61 }, { -8, 66 },
- { -7, 70 }, { -14, 75 }, { -10, 79 }, { -9, 83 },
- { -12, 92 }, { -18, 108 }, { -24, 115 }, { -22, 82 },
- { -9, 62 }, { 0, 53 }, { 0, 59 }, { -14, 85 },
- { -13, 89 }, { -13, 94 }, { -11, 92 }, { -29, 127 },
- { -21, 100 }, { -14, 57 }, { -12, 67 }, { -11, 71 },
- { -10, 77 }, { -21, 85 }, { -16, 88 }, { -23, 104 },
- { -15, 98 }, { -37, 127 }, { -10, 82 }, { -8, 48 },
- { -8, 61 }, { -8, 66 }, { -7, 70 }, { -14, 75 },
- { -10, 79 }, { -9, 83 }, { -12, 92 }, { -18, 108 },
- { -5, 79 }, { -11, 104 }, { -11, 91 }, { -30, 127 },
- { -5, 79 }, { -11, 104 }, { -11, 91 }, { -30, 127 },
- { -5, 79 }, { -11, 104 }, { -11, 91 }, { -30, 127 }
- }
-};
-
-void ff_h264_init_cabac_states(const H264Context *h, H264SliceContext *sl)
-{
- int i;
- const int8_t (*tab)[2];
- const int slice_qp = av_clip(sl->qscale - 6*(h->sps.bit_depth_luma-8), 0, 51);
-
- if (sl->slice_type_nos == AV_PICTURE_TYPE_I) tab = cabac_context_init_I;
- else tab = cabac_context_init_PB[sl->cabac_init_idc];
-
- /* calculate pre-state */
- for( i= 0; i < 1024; i++ ) {
- int pre = 2*(((tab[i][0] * slice_qp) >>4 ) + tab[i][1]) - 127;
-
- pre^= pre>>31;
- if(pre > 124)
- pre= 124 + (pre&1);
-
- sl->cabac_state[i] = pre;
- }
-}
-
-static int decode_cabac_field_decoding_flag(const H264Context *h, H264SliceContext *sl)
-{
- const int mbb_xy = sl->mb_xy - 2*h->mb_stride;
-
- unsigned long ctx = 0;
-
- ctx += sl->mb_field_decoding_flag & !!sl->mb_x; //for FMO:(s->current_picture.mb_type[mba_xy] >> 7) & (h->slice_table[mba_xy] == h->slice_num);
- ctx += (h->cur_pic.mb_type[mbb_xy] >> 7) & (h->slice_table[mbb_xy] == sl->slice_num);
-
- return get_cabac_noinline( &sl->cabac, &(sl->cabac_state+70)[ctx] );
-}
-
-static int decode_cabac_intra_mb_type(H264SliceContext *sl,
- int ctx_base, int intra_slice)
-{
- uint8_t *state= &sl->cabac_state[ctx_base];
- int mb_type;
-
- if(intra_slice){
- int ctx=0;
- if (sl->left_type[LTOP] & (MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM))
- ctx++;
- if (sl->top_type & (MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM))
- ctx++;
- if( get_cabac_noinline( &sl->cabac, &state[ctx] ) == 0 )
- return 0; /* I4x4 */
- state += 2;
- }else{
- if( get_cabac_noinline( &sl->cabac, state ) == 0 )
- return 0; /* I4x4 */
- }
-
- if( get_cabac_terminate( &sl->cabac ) )
- return 25; /* PCM */
-
- mb_type = 1; /* I16x16 */
- mb_type += 12 * get_cabac_noinline( &sl->cabac, &state[1] ); /* cbp_luma != 0 */
- if( get_cabac_noinline( &sl->cabac, &state[2] ) ) /* cbp_chroma */
- mb_type += 4 + 4 * get_cabac_noinline( &sl->cabac, &state[2+intra_slice] );
- mb_type += 2 * get_cabac_noinline( &sl->cabac, &state[3+intra_slice] );
- mb_type += 1 * get_cabac_noinline( &sl->cabac, &state[3+2*intra_slice] );
- return mb_type;
-}
-
-static int decode_cabac_mb_skip(const H264Context *h, H264SliceContext *sl,
- int mb_x, int mb_y)
-{
- int mba_xy, mbb_xy;
- int ctx = 0;
-
- if (FRAME_MBAFF(h)) { //FIXME merge with the stuff in fill_caches?
- int mb_xy = mb_x + (mb_y&~1)*h->mb_stride;
- mba_xy = mb_xy - 1;
- if( (mb_y&1)
- && h->slice_table[mba_xy] == sl->slice_num
- && MB_FIELD(sl) == !!IS_INTERLACED( h->cur_pic.mb_type[mba_xy] ) )
- mba_xy += h->mb_stride;
- if (MB_FIELD(sl)) {
- mbb_xy = mb_xy - h->mb_stride;
- if( !(mb_y&1)
- && h->slice_table[mbb_xy] == sl->slice_num
- && IS_INTERLACED( h->cur_pic.mb_type[mbb_xy] ) )
- mbb_xy -= h->mb_stride;
- }else
- mbb_xy = mb_x + (mb_y-1)*h->mb_stride;
- }else{
- int mb_xy = sl->mb_xy;
- mba_xy = mb_xy - 1;
- mbb_xy = mb_xy - (h->mb_stride << FIELD_PICTURE(h));
- }
-
- if( h->slice_table[mba_xy] == sl->slice_num && !IS_SKIP(h->cur_pic.mb_type[mba_xy] ))
- ctx++;
- if( h->slice_table[mbb_xy] == sl->slice_num && !IS_SKIP(h->cur_pic.mb_type[mbb_xy] ))
- ctx++;
-
- if (sl->slice_type_nos == AV_PICTURE_TYPE_B)
- ctx += 13;
- return get_cabac_noinline( &sl->cabac, &sl->cabac_state[11+ctx] );
-}
-
-static int decode_cabac_mb_intra4x4_pred_mode(H264SliceContext *sl, int pred_mode)
-{
- int mode = 0;
-
- if( get_cabac( &sl->cabac, &sl->cabac_state[68] ) )
- return pred_mode;
-
- mode += 1 * get_cabac( &sl->cabac, &sl->cabac_state[69] );
- mode += 2 * get_cabac( &sl->cabac, &sl->cabac_state[69] );
- mode += 4 * get_cabac( &sl->cabac, &sl->cabac_state[69] );
-
- return mode + ( mode >= pred_mode );
-}
-
-static int decode_cabac_mb_chroma_pre_mode(const H264Context *h, H264SliceContext *sl)
-{
- const int mba_xy = sl->left_mb_xy[0];
- const int mbb_xy = sl->top_mb_xy;
-
- int ctx = 0;
-
- /* No need to test for IS_INTRA4x4 and IS_INTRA16x16, as we set chroma_pred_mode_table to 0 */
- if (sl->left_type[LTOP] && h->chroma_pred_mode_table[mba_xy] != 0)
- ctx++;
-
- if (sl->top_type && h->chroma_pred_mode_table[mbb_xy] != 0)
- ctx++;
-
- if( get_cabac_noinline( &sl->cabac, &sl->cabac_state[64+ctx] ) == 0 )
- return 0;
-
- if( get_cabac_noinline( &sl->cabac, &sl->cabac_state[64+3] ) == 0 )
- return 1;
- if( get_cabac_noinline( &sl->cabac, &sl->cabac_state[64+3] ) == 0 )
- return 2;
- else
- return 3;
-}
-
-static int decode_cabac_mb_cbp_luma(H264SliceContext *sl)
-{
- int cbp_b, cbp_a, ctx, cbp = 0;
-
- cbp_a = sl->left_cbp;
- cbp_b = sl->top_cbp;
-
- ctx = !(cbp_a & 0x02) + 2 * !(cbp_b & 0x04);
- cbp += get_cabac_noinline(&sl->cabac, &sl->cabac_state[73 + ctx]);
- ctx = !(cbp & 0x01) + 2 * !(cbp_b & 0x08);
- cbp += get_cabac_noinline(&sl->cabac, &sl->cabac_state[73 + ctx]) << 1;
- ctx = !(cbp_a & 0x08) + 2 * !(cbp & 0x01);
- cbp += get_cabac_noinline(&sl->cabac, &sl->cabac_state[73 + ctx]) << 2;
- ctx = !(cbp & 0x04) + 2 * !(cbp & 0x02);
- cbp += get_cabac_noinline(&sl->cabac, &sl->cabac_state[73 + ctx]) << 3;
- return cbp;
-}
-static int decode_cabac_mb_cbp_chroma(H264SliceContext *sl)
-{
- int ctx;
- int cbp_a, cbp_b;
-
- cbp_a = (sl->left_cbp>>4)&0x03;
- cbp_b = (sl-> top_cbp>>4)&0x03;
-
- ctx = 0;
- if( cbp_a > 0 ) ctx++;
- if( cbp_b > 0 ) ctx += 2;
- if( get_cabac_noinline( &sl->cabac, &sl->cabac_state[77 + ctx] ) == 0 )
- return 0;
-
- ctx = 4;
- if( cbp_a == 2 ) ctx++;
- if( cbp_b == 2 ) ctx += 2;
- return 1 + get_cabac_noinline( &sl->cabac, &sl->cabac_state[77 + ctx] );
-}
-
-static int decode_cabac_p_mb_sub_type(H264SliceContext *sl)
-{
- if( get_cabac( &sl->cabac, &sl->cabac_state[21] ) )
- return 0; /* 8x8 */
- if( !get_cabac( &sl->cabac, &sl->cabac_state[22] ) )
- return 1; /* 8x4 */
- if( get_cabac( &sl->cabac, &sl->cabac_state[23] ) )
- return 2; /* 4x8 */
- return 3; /* 4x4 */
-}
-static int decode_cabac_b_mb_sub_type(H264SliceContext *sl)
-{
- int type;
- if( !get_cabac( &sl->cabac, &sl->cabac_state[36] ) )
- return 0; /* B_Direct_8x8 */
- if( !get_cabac( &sl->cabac, &sl->cabac_state[37] ) )
- return 1 + get_cabac( &sl->cabac, &sl->cabac_state[39] ); /* B_L0_8x8, B_L1_8x8 */
- type = 3;
- if( get_cabac( &sl->cabac, &sl->cabac_state[38] ) ) {
- if( get_cabac( &sl->cabac, &sl->cabac_state[39] ) )
- return 11 + get_cabac( &sl->cabac, &sl->cabac_state[39] ); /* B_L1_4x4, B_Bi_4x4 */
- type += 4;
- }
- type += 2*get_cabac( &sl->cabac, &sl->cabac_state[39] );
- type += get_cabac( &sl->cabac, &sl->cabac_state[39] );
- return type;
-}
-
-static int decode_cabac_mb_ref(H264SliceContext *sl, int list, int n)
-{
- int refa = sl->ref_cache[list][scan8[n] - 1];
- int refb = sl->ref_cache[list][scan8[n] - 8];
- int ref = 0;
- int ctx = 0;
-
- if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
- if( refa > 0 && !(sl->direct_cache[scan8[n] - 1]&(MB_TYPE_DIRECT2>>1)) )
- ctx++;
- if( refb > 0 && !(sl->direct_cache[scan8[n] - 8]&(MB_TYPE_DIRECT2>>1)) )
- ctx += 2;
- } else {
- if( refa > 0 )
- ctx++;
- if( refb > 0 )
- ctx += 2;
- }
-
- while( get_cabac( &sl->cabac, &sl->cabac_state[54+ctx] ) ) {
- ref++;
- ctx = (ctx>>2)+4;
- if(ref >= 32 /*h->ref_list[list]*/){
- return -1;
- }
- }
- return ref;
-}
-
-static int decode_cabac_mb_mvd(H264SliceContext *sl, int ctxbase, int amvd, int *mvda)
-{
- int mvd;
-
- if(!get_cabac(&sl->cabac, &sl->cabac_state[ctxbase+((amvd-3)>>(INT_BIT-1))+((amvd-33)>>(INT_BIT-1))+2])){
-// if(!get_cabac(&sl->cabac, &sl->cabac_state[ctxbase+(amvd>2)+(amvd>32)])){
- *mvda= 0;
- return 0;
- }
-
- mvd= 1;
- ctxbase+= 3;
- while( mvd < 9 && get_cabac( &sl->cabac, &sl->cabac_state[ctxbase] ) ) {
- if( mvd < 4 )
- ctxbase++;
- mvd++;
- }
-
- if( mvd >= 9 ) {
- int k = 3;
- while( get_cabac_bypass( &sl->cabac ) ) {
- mvd += 1 << k;
- k++;
- if(k>24){
- av_log(sl->h264->avctx, AV_LOG_ERROR, "overflow in decode_cabac_mb_mvd\n");
- return INT_MIN;
- }
- }
- while( k-- ) {
- mvd += get_cabac_bypass( &sl->cabac )<<k;
- }
- *mvda=mvd < 70 ? mvd : 70;
- }else
- *mvda=mvd;
- return get_cabac_bypass_sign( &sl->cabac, -mvd );
-}
-
-#define DECODE_CABAC_MB_MVD(sl, list, n )\
-{\
- int amvd0 = sl->mvd_cache[list][scan8[n] - 1][0] +\
- sl->mvd_cache[list][scan8[n] - 8][0];\
- int amvd1 = sl->mvd_cache[list][scan8[n] - 1][1] +\
- sl->mvd_cache[list][scan8[n] - 8][1];\
-\
- mx += decode_cabac_mb_mvd(sl, 40, amvd0, &mpx);\
- my += decode_cabac_mb_mvd(sl, 47, amvd1, &mpy);\
-}
-
-static av_always_inline int get_cabac_cbf_ctx(H264SliceContext *sl,
- int cat, int idx, int max_coeff,
- int is_dc)
-{
- int nza, nzb;
- int ctx = 0;
- static const uint16_t base_ctx[14] = {85,89,93,97,101,1012,460,464,468,1016,472,476,480,1020};
-
- if( is_dc ) {
- if( cat == 3 ) {
- idx -= CHROMA_DC_BLOCK_INDEX;
- nza = (sl->left_cbp>>(6+idx))&0x01;
- nzb = (sl-> top_cbp>>(6+idx))&0x01;
- } else {
- idx -= LUMA_DC_BLOCK_INDEX;
- nza = sl->left_cbp&(0x100<<idx);
- nzb = sl-> top_cbp&(0x100<<idx);
- }
- } else {
- nza = sl->non_zero_count_cache[scan8[idx] - 1];
- nzb = sl->non_zero_count_cache[scan8[idx] - 8];
- }
-
- if( nza > 0 )
- ctx++;
-
- if( nzb > 0 )
- ctx += 2;
-
- return base_ctx[cat] + ctx;
-}
-
-static av_always_inline void
-decode_cabac_residual_internal(const H264Context *h, H264SliceContext *sl,
- int16_t *block,
- int cat, int n, const uint8_t *scantable,
- const uint32_t *qmul, int max_coeff,
- int is_dc, int chroma422)
-{
- static const int significant_coeff_flag_offset[2][14] = {
- { 105+0, 105+15, 105+29, 105+44, 105+47, 402, 484+0, 484+15, 484+29, 660, 528+0, 528+15, 528+29, 718 },
- { 277+0, 277+15, 277+29, 277+44, 277+47, 436, 776+0, 776+15, 776+29, 675, 820+0, 820+15, 820+29, 733 }
- };
- static const int last_coeff_flag_offset[2][14] = {
- { 166+0, 166+15, 166+29, 166+44, 166+47, 417, 572+0, 572+15, 572+29, 690, 616+0, 616+15, 616+29, 748 },
- { 338+0, 338+15, 338+29, 338+44, 338+47, 451, 864+0, 864+15, 864+29, 699, 908+0, 908+15, 908+29, 757 }
- };
- static const int coeff_abs_level_m1_offset[14] = {
- 227+0, 227+10, 227+20, 227+30, 227+39, 426, 952+0, 952+10, 952+20, 708, 982+0, 982+10, 982+20, 766
- };
- static const uint8_t significant_coeff_flag_offset_8x8[2][63] = {
- { 0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5,
- 4, 4, 4, 4, 3, 3, 6, 7, 7, 7, 8, 9,10, 9, 8, 7,
- 7, 6,11,12,13,11, 6, 7, 8, 9,14,10, 9, 8, 6,11,
- 12,13,11, 6, 9,14,10, 9,11,12,13,11,14,10,12 },
- { 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 7, 8, 4, 5,
- 6, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,11,12,11,
- 9, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,13,13, 9,
- 9,10,10, 8,13,13, 9, 9,10,10,14,14,14,14,14 }
- };
- static const uint8_t sig_coeff_offset_dc[7] = { 0, 0, 1, 1, 2, 2, 2 };
- /* node ctx: 0..3: abslevel1 (with abslevelgt1 == 0).
- * 4..7: abslevelgt1 + 3 (and abslevel1 doesn't matter).
- * map node ctx => cabac ctx for level=1 */
- static const uint8_t coeff_abs_level1_ctx[8] = { 1, 2, 3, 4, 0, 0, 0, 0 };
- /* map node ctx => cabac ctx for level>1 */
- static const uint8_t coeff_abs_levelgt1_ctx[2][8] = {
- { 5, 5, 5, 5, 6, 7, 8, 9 },
- { 5, 5, 5, 5, 6, 7, 8, 8 }, // 422/dc case
- };
- static const uint8_t coeff_abs_level_transition[2][8] = {
- /* update node ctx after decoding a level=1 */
- { 1, 2, 3, 3, 4, 5, 6, 7 },
- /* update node ctx after decoding a level>1 */
- { 4, 4, 4, 4, 5, 6, 7, 7 }
- };
-
- int index[64];
-
- int last;
- int coeff_count = 0;
- int node_ctx = 0;
-
- uint8_t *significant_coeff_ctx_base;
- uint8_t *last_coeff_ctx_base;
- uint8_t *abs_level_m1_ctx_base;
-
-#if !ARCH_X86
-#define CABAC_ON_STACK
-#endif
-#ifdef CABAC_ON_STACK
-#define CC &cc
- CABACContext cc;
- cc.range = sl->cabac.range;
- cc.low = sl->cabac.low;
- cc.bytestream= sl->cabac.bytestream;
-#if !UNCHECKED_BITSTREAM_READER || ARCH_AARCH64
- cc.bytestream_end = sl->cabac.bytestream_end;
-#endif
-#else
-#define CC &sl->cabac
-#endif
-
- significant_coeff_ctx_base = sl->cabac_state
- + significant_coeff_flag_offset[MB_FIELD(sl)][cat];
- last_coeff_ctx_base = sl->cabac_state
- + last_coeff_flag_offset[MB_FIELD(sl)][cat];
- abs_level_m1_ctx_base = sl->cabac_state
- + coeff_abs_level_m1_offset[cat];
-
- if( !is_dc && max_coeff == 64 ) {
-#define DECODE_SIGNIFICANCE( coefs, sig_off, last_off ) \
- for(last= 0; last < coefs; last++) { \
- uint8_t *sig_ctx = significant_coeff_ctx_base + sig_off; \
- if( get_cabac( CC, sig_ctx )) { \
- uint8_t *last_ctx = last_coeff_ctx_base + last_off; \
- index[coeff_count++] = last; \
- if( get_cabac( CC, last_ctx ) ) { \
- last= max_coeff; \
- break; \
- } \
- } \
- }\
- if( last == max_coeff -1 ) {\
- index[coeff_count++] = last;\
- }
- const uint8_t *sig_off = significant_coeff_flag_offset_8x8[MB_FIELD(sl)];
-#ifdef decode_significance
- coeff_count = decode_significance_8x8(CC, significant_coeff_ctx_base, index,
- last_coeff_ctx_base, sig_off);
- } else {
- if (is_dc && chroma422) { // dc 422
- DECODE_SIGNIFICANCE(7, sig_coeff_offset_dc[last], sig_coeff_offset_dc[last]);
- } else {
- coeff_count = decode_significance(CC, max_coeff, significant_coeff_ctx_base, index,
- last_coeff_ctx_base-significant_coeff_ctx_base);
- }
-#else
- DECODE_SIGNIFICANCE( 63, sig_off[last], ff_h264_last_coeff_flag_offset_8x8[last] );
- } else {
- if (is_dc && chroma422) { // dc 422
- DECODE_SIGNIFICANCE(7, sig_coeff_offset_dc[last], sig_coeff_offset_dc[last]);
- } else {
- DECODE_SIGNIFICANCE(max_coeff - 1, last, last);
- }
-#endif
- }
- av_assert2(coeff_count > 0);
-
- if( is_dc ) {
- if( cat == 3 )
- h->cbp_table[sl->mb_xy] |= 0x40 << (n - CHROMA_DC_BLOCK_INDEX);
- else
- h->cbp_table[sl->mb_xy] |= 0x100 << (n - LUMA_DC_BLOCK_INDEX);
- sl->non_zero_count_cache[scan8[n]] = coeff_count;
- } else {
- if( max_coeff == 64 )
- fill_rectangle(&sl->non_zero_count_cache[scan8[n]], 2, 2, 8, coeff_count, 1);
- else {
- av_assert2( cat == 1 || cat == 2 || cat == 4 || cat == 7 || cat == 8 || cat == 11 || cat == 12 );
- sl->non_zero_count_cache[scan8[n]] = coeff_count;
- }
- }
-
-#define STORE_BLOCK(type) \
- do { \
- uint8_t *ctx = coeff_abs_level1_ctx[node_ctx] + abs_level_m1_ctx_base; \
- \
- int j= scantable[index[--coeff_count]]; \
- \
- if( get_cabac( CC, ctx ) == 0 ) { \
- node_ctx = coeff_abs_level_transition[0][node_ctx]; \
- if( is_dc ) { \
- ((type*)block)[j] = get_cabac_bypass_sign( CC, -1); \
- }else{ \
- ((type*)block)[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6; \
- } \
- } else { \
- int coeff_abs = 2; \
- ctx = coeff_abs_levelgt1_ctx[is_dc && chroma422][node_ctx] + abs_level_m1_ctx_base; \
- node_ctx = coeff_abs_level_transition[1][node_ctx]; \
-\
- while( coeff_abs < 15 && get_cabac( CC, ctx ) ) { \
- coeff_abs++; \
- } \
-\
- if( coeff_abs >= 15 ) { \
- int j = 0; \
- while (get_cabac_bypass(CC) && j < 30) { \
- j++; \
- } \
-\
- coeff_abs=1; \
- while( j-- ) { \
- coeff_abs += coeff_abs + get_cabac_bypass( CC ); \
- } \
- coeff_abs+= 14; \
- } \
-\
- if( is_dc ) { \
- ((type*)block)[j] = get_cabac_bypass_sign( CC, -coeff_abs ); \
- }else{ \
- ((type*)block)[j] = ((int)(get_cabac_bypass_sign( CC, -coeff_abs ) * qmul[j] + 32)) >> 6; \
- } \
- } \
- } while ( coeff_count );
-
- if (h->pixel_shift) {
- STORE_BLOCK(int32_t)
- } else {
- STORE_BLOCK(int16_t)
- }
-#ifdef CABAC_ON_STACK
- sl->cabac.range = cc.range ;
- sl->cabac.low = cc.low ;
- sl->cabac.bytestream= cc.bytestream;
-#endif
-
-}
-
-static av_noinline void decode_cabac_residual_dc_internal(const H264Context *h,
- H264SliceContext *sl,
- int16_t *block,
- int cat, int n,
- const uint8_t *scantable,
- int max_coeff)
-{
- decode_cabac_residual_internal(h, sl, block, cat, n, scantable, NULL, max_coeff, 1, 0);
-}
-
-static av_noinline void decode_cabac_residual_dc_internal_422(const H264Context *h,
- H264SliceContext *sl,
- int16_t *block,
- int cat, int n,
- const uint8_t *scantable,
- int max_coeff)
-{
- decode_cabac_residual_internal(h, sl, block, cat, n, scantable, NULL, max_coeff, 1, 1);
-}
-
-static av_noinline void decode_cabac_residual_nondc_internal(const H264Context *h,
- H264SliceContext *sl,
- int16_t *block,
- int cat, int n,
- const uint8_t *scantable,
- const uint32_t *qmul,
- int max_coeff)
-{
- decode_cabac_residual_internal(h, sl, block, cat, n, scantable, qmul, max_coeff, 0, 0);
-}
-
-/* cat: 0-> DC 16x16 n = 0
- * 1-> AC 16x16 n = luma4x4idx
- * 2-> Luma4x4 n = luma4x4idx
- * 3-> DC Chroma n = iCbCr
- * 4-> AC Chroma n = 16 + 4 * iCbCr + chroma4x4idx
- * 5-> Luma8x8 n = 4 * luma8x8idx */
-
-/* Partially inline the CABAC residual decode: inline the coded block flag.
- * This has very little impact on binary size and improves performance
- * because it allows improved constant propagation into get_cabac_cbf_ctx,
- * as well as because most blocks have zero CBFs. */
-
-static av_always_inline void decode_cabac_residual_dc(const H264Context *h,
- H264SliceContext *sl,
- int16_t *block,
- int cat, int n,
- const uint8_t *scantable,
- int max_coeff)
-{
- /* read coded block flag */
- if( get_cabac( &sl->cabac, &sl->cabac_state[get_cabac_cbf_ctx(sl, cat, n, max_coeff, 1)]) == 0 ) {
- sl->non_zero_count_cache[scan8[n]] = 0;
- return;
- }
- decode_cabac_residual_dc_internal(h, sl, block, cat, n, scantable, max_coeff);
-}
-
-static av_always_inline void
-decode_cabac_residual_dc_422(const H264Context *h, H264SliceContext *sl,
- int16_t *block,
- int cat, int n, const uint8_t *scantable,
- int max_coeff)
-{
- /* read coded block flag */
- if (get_cabac(&sl->cabac, &sl->cabac_state[get_cabac_cbf_ctx(sl, cat, n, max_coeff, 1)]) == 0) {
- sl->non_zero_count_cache[scan8[n]] = 0;
- return;
- }
- decode_cabac_residual_dc_internal_422(h, sl, block, cat, n, scantable, max_coeff);
-}
-
-static av_always_inline void decode_cabac_residual_nondc(const H264Context *h,
- H264SliceContext *sl,
- int16_t *block,
- int cat, int n,
- const uint8_t *scantable,
- const uint32_t *qmul,
- int max_coeff)
-{
- /* read coded block flag */
- if( (cat != 5 || CHROMA444(h)) && get_cabac( &sl->cabac, &sl->cabac_state[get_cabac_cbf_ctx(sl, cat, n, max_coeff, 0)]) == 0) {
- if( max_coeff == 64 ) {
- fill_rectangle(&sl->non_zero_count_cache[scan8[n]], 2, 2, 8, 0, 1);
- } else {
- sl->non_zero_count_cache[scan8[n]] = 0;
- }
- return;
- }
- decode_cabac_residual_nondc_internal(h, sl, block, cat, n, scantable, qmul, max_coeff);
-}
-
-static av_always_inline void decode_cabac_luma_residual(const H264Context *h, H264SliceContext *sl,
- const uint8_t *scan, const uint8_t *scan8x8,
- int pixel_shift, int mb_type, int cbp, int p)
-{
- static const uint8_t ctx_cat[4][3] = {{0,6,10},{1,7,11},{2,8,12},{5,9,13}};
- const uint32_t *qmul;
- int i8x8, i4x4;
- int qscale = p == 0 ? sl->qscale : sl->chroma_qp[p - 1];
- if( IS_INTRA16x16( mb_type ) ) {
- AV_ZERO128(sl->mb_luma_dc[p]+0);
- AV_ZERO128(sl->mb_luma_dc[p]+8);
- AV_ZERO128(sl->mb_luma_dc[p]+16);
- AV_ZERO128(sl->mb_luma_dc[p]+24);
- decode_cabac_residual_dc(h, sl, sl->mb_luma_dc[p], ctx_cat[0][p], LUMA_DC_BLOCK_INDEX+p, scan, 16);
-
- if( cbp&15 ) {
- qmul = h->dequant4_coeff[p][qscale];
- for( i4x4 = 0; i4x4 < 16; i4x4++ ) {
- const int index = 16*p + i4x4;
- decode_cabac_residual_nondc(h, sl, sl->mb + (16*index << pixel_shift), ctx_cat[1][p], index, scan + 1, qmul, 15);
- }
- } else {
- fill_rectangle(&sl->non_zero_count_cache[scan8[16*p]], 4, 4, 8, 0, 1);
- }
- } else {
- int cqm = (IS_INTRA( mb_type ) ? 0:3) + p;
- for( i8x8 = 0; i8x8 < 4; i8x8++ ) {
- if( cbp & (1<<i8x8) ) {
- if( IS_8x8DCT(mb_type) ) {
- const int index = 16*p + 4*i8x8;
- decode_cabac_residual_nondc(h, sl, sl->mb + (16*index << pixel_shift), ctx_cat[3][p], index,
- scan8x8, h->dequant8_coeff[cqm][qscale], 64);
- } else {
- qmul = h->dequant4_coeff[cqm][qscale];
- for( i4x4 = 0; i4x4 < 4; i4x4++ ) {
- const int index = 16*p + 4*i8x8 + i4x4;
-//START_TIMER
- decode_cabac_residual_nondc(h, sl, sl->mb + (16*index << pixel_shift), ctx_cat[2][p], index, scan, qmul, 16);
-//STOP_TIMER("decode_residual")
- }
- }
- } else {
- fill_rectangle(&sl->non_zero_count_cache[scan8[4*i8x8+16*p]], 2, 2, 8, 0, 1);
- }
- }
- }
-}
-
-/**
- * Decode a macroblock.
- * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR if an error is noticed
- */
-int ff_h264_decode_mb_cabac(const H264Context *h, H264SliceContext *sl)
-{
- int mb_xy;
- int mb_type, partition_count, cbp = 0;
- int dct8x8_allowed= h->pps.transform_8x8_mode;
- int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;
- const int pixel_shift = h->pixel_shift;
-
- mb_xy = sl->mb_xy = sl->mb_x + sl->mb_y*h->mb_stride;
-
- ff_tlog(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, sl->mb_x, sl->mb_y);
- if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {
- int skip;
- /* a skipped mb needs the aff flag from the following mb */
- if (FRAME_MBAFF(h) && (sl->mb_y & 1) == 1 && sl->prev_mb_skipped)
- skip = sl->next_mb_skipped;
- else
- skip = decode_cabac_mb_skip(h, sl, sl->mb_x, sl->mb_y );
- /* read skip flags */
- if( skip ) {
- if (FRAME_MBAFF(h) && (sl->mb_y & 1) == 0) {
- h->cur_pic.mb_type[mb_xy] = MB_TYPE_SKIP;
- sl->next_mb_skipped = decode_cabac_mb_skip(h, sl, sl->mb_x, sl->mb_y+1 );
- if(!sl->next_mb_skipped)
- sl->mb_mbaff = sl->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h, sl);
- }
-
- decode_mb_skip(h, sl);
-
- h->cbp_table[mb_xy] = 0;
- h->chroma_pred_mode_table[mb_xy] = 0;
- sl->last_qscale_diff = 0;
-
- return 0;
-
- }
- }
- if (FRAME_MBAFF(h)) {
- if ((sl->mb_y & 1) == 0)
- sl->mb_mbaff =
- sl->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h, sl);
- }
-
- sl->prev_mb_skipped = 0;
-
- fill_decode_neighbors(h, sl, -(MB_FIELD(sl)));
-
- if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
- int ctx = 0;
- av_assert2(sl->slice_type_nos == AV_PICTURE_TYPE_B);
-
- if (!IS_DIRECT(sl->left_type[LTOP] - 1))
- ctx++;
- if (!IS_DIRECT(sl->top_type - 1))
- ctx++;
-
- if( !get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+ctx] ) ){
- mb_type= 0; /* B_Direct_16x16 */
- }else if( !get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+3] ) ) {
- mb_type= 1 + get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] ); /* B_L[01]_16x16 */
- }else{
- int bits;
- bits = get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+4] ) << 3;
- bits+= get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] ) << 2;
- bits+= get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] ) << 1;
- bits+= get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] );
- if( bits < 8 ){
- mb_type= bits + 3; /* B_Bi_16x16 through B_L1_L0_16x8 */
- }else if( bits == 13 ){
- mb_type = decode_cabac_intra_mb_type(sl, 32, 0);
- goto decode_intra_mb;
- }else if( bits == 14 ){
- mb_type= 11; /* B_L1_L0_8x16 */
- }else if( bits == 15 ){
- mb_type= 22; /* B_8x8 */
- }else{
- bits= ( bits<<1 ) + get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] );
- mb_type= bits - 4; /* B_L0_Bi_* through B_Bi_Bi_* */
- }
- }
- partition_count= b_mb_type_info[mb_type].partition_count;
- mb_type= b_mb_type_info[mb_type].type;
- } else if (sl->slice_type_nos == AV_PICTURE_TYPE_P) {
- if( get_cabac_noinline( &sl->cabac, &sl->cabac_state[14] ) == 0 ) {
- /* P-type */
- if( get_cabac_noinline( &sl->cabac, &sl->cabac_state[15] ) == 0 ) {
- /* P_L0_D16x16, P_8x8 */
- mb_type= 3 * get_cabac_noinline( &sl->cabac, &sl->cabac_state[16] );
- } else {
- /* P_L0_D8x16, P_L0_D16x8 */
- mb_type= 2 - get_cabac_noinline( &sl->cabac, &sl->cabac_state[17] );
- }
- partition_count= p_mb_type_info[mb_type].partition_count;
- mb_type= p_mb_type_info[mb_type].type;
- } else {
- mb_type = decode_cabac_intra_mb_type(sl, 17, 0);
- goto decode_intra_mb;
- }
- } else {
- mb_type = decode_cabac_intra_mb_type(sl, 3, 1);
- if (sl->slice_type == AV_PICTURE_TYPE_SI && mb_type)
- mb_type--;
- av_assert2(sl->slice_type_nos == AV_PICTURE_TYPE_I);
-decode_intra_mb:
- partition_count = 0;
- cbp= i_mb_type_info[mb_type].cbp;
- sl->intra16x16_pred_mode = i_mb_type_info[mb_type].pred_mode;
- mb_type= i_mb_type_info[mb_type].type;
- }
- if (MB_FIELD(sl))
- mb_type |= MB_TYPE_INTERLACED;
-
- h->slice_table[mb_xy] = sl->slice_num;
-
- if(IS_INTRA_PCM(mb_type)) {
- const int mb_size = ff_h264_mb_sizes[h->sps.chroma_format_idc] *
- h->sps.bit_depth_luma >> 3;
- const uint8_t *ptr;
- int ret;
-
- // We assume these blocks are very rare so we do not optimize it.
- // FIXME The two following lines get the bitstream position in the cabac
- // decode, I think it should be done by a function in cabac.h (or cabac.c).
- ptr= sl->cabac.bytestream;
- if(sl->cabac.low&0x1) ptr--;
- if(CABAC_BITS==16){
- if(sl->cabac.low&0x1FF) ptr--;
- }
-
- // The pixels are stored in the same order as levels in h->mb array.
- if ((int) (sl->cabac.bytestream_end - ptr) < mb_size)
- return -1;
- sl->intra_pcm_ptr = ptr;
- ptr += mb_size;
-
- ret = ff_init_cabac_decoder(&sl->cabac, ptr, sl->cabac.bytestream_end - ptr);
- if (ret < 0)
- return ret;
-
- // All blocks are present
- h->cbp_table[mb_xy] = 0xf7ef;
- h->chroma_pred_mode_table[mb_xy] = 0;
- // In deblocking, the quantizer is 0
- h->cur_pic.qscale_table[mb_xy] = 0;
- // All coeffs are present
- memset(h->non_zero_count[mb_xy], 16, 48);
- h->cur_pic.mb_type[mb_xy] = mb_type;
- sl->last_qscale_diff = 0;
- return 0;
- }
-
- fill_decode_caches(h, sl, mb_type);
-
- if( IS_INTRA( mb_type ) ) {
- int i, pred_mode;
- if( IS_INTRA4x4( mb_type ) ) {
- if (dct8x8_allowed && get_cabac_noinline(&sl->cabac, &sl->cabac_state[399 + sl->neighbor_transform_size])) {
- mb_type |= MB_TYPE_8x8DCT;
- for( i = 0; i < 16; i+=4 ) {
- int pred = pred_intra_mode(h, sl, i);
- int mode = decode_cabac_mb_intra4x4_pred_mode(sl, pred);
- fill_rectangle(&sl->intra4x4_pred_mode_cache[scan8[i]], 2, 2, 8, mode, 1);
- }
- } else {
- for( i = 0; i < 16; i++ ) {
- int pred = pred_intra_mode(h, sl, i);
- sl->intra4x4_pred_mode_cache[scan8[i]] = decode_cabac_mb_intra4x4_pred_mode(sl, pred);
-
- ff_tlog(h->avctx, "i4x4 pred=%d mode=%d\n", pred,
- sl->intra4x4_pred_mode_cache[scan8[i]]);
- }
- }
- write_back_intra_pred_mode(h, sl);
- if (ff_h264_check_intra4x4_pred_mode(h, sl) < 0 ) return -1;
- } else {
- sl->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, sl, sl->intra16x16_pred_mode, 0);
- if (sl->intra16x16_pred_mode < 0) return -1;
- }
- if(decode_chroma){
- h->chroma_pred_mode_table[mb_xy] =
- pred_mode = decode_cabac_mb_chroma_pre_mode(h, sl);
-
- pred_mode= ff_h264_check_intra_pred_mode(h, sl, pred_mode, 1 );
- if( pred_mode < 0 ) return -1;
- sl->chroma_pred_mode = pred_mode;
- } else {
- sl->chroma_pred_mode = DC_128_PRED8x8;
- }
- } else if( partition_count == 4 ) {
- int i, j, sub_partition_count[4], list, ref[2][4];
-
- if (sl->slice_type_nos == AV_PICTURE_TYPE_B ) {
- for( i = 0; i < 4; i++ ) {
- sl->sub_mb_type[i] = decode_cabac_b_mb_sub_type(sl);
- sub_partition_count[i] = b_sub_mb_type_info[sl->sub_mb_type[i]].partition_count;
- sl->sub_mb_type[i] = b_sub_mb_type_info[sl->sub_mb_type[i]].type;
- }
- if (IS_DIRECT(sl->sub_mb_type[0] | sl->sub_mb_type[1] |
- sl->sub_mb_type[2] | sl->sub_mb_type[3])) {
- ff_h264_pred_direct_motion(h, sl, &mb_type);
- sl->ref_cache[0][scan8[4]] =
- sl->ref_cache[1][scan8[4]] =
- sl->ref_cache[0][scan8[12]] =
- sl->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;
- for( i = 0; i < 4; i++ )
- fill_rectangle(&sl->direct_cache[scan8[4*i]], 2, 2, 8, (sl->sub_mb_type[i] >> 1) & 0xFF, 1);
- }
- } else {
- for( i = 0; i < 4; i++ ) {
- sl->sub_mb_type[i] = decode_cabac_p_mb_sub_type(sl);
- sub_partition_count[i] = p_sub_mb_type_info[sl->sub_mb_type[i]].partition_count;
- sl->sub_mb_type[i] = p_sub_mb_type_info[sl->sub_mb_type[i]].type;
- }
- }
-
- for( list = 0; list < sl->list_count; list++ ) {
- for( i = 0; i < 4; i++ ) {
- if(IS_DIRECT(sl->sub_mb_type[i])) continue;
- if(IS_DIR(sl->sub_mb_type[i], 0, list)){
- unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
- if (rc > 1) {
- ref[list][i] = decode_cabac_mb_ref(sl, list, 4 * i);
- if (ref[list][i] >= rc) {
- av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], rc);
- return -1;
- }
- }else
- ref[list][i] = 0;
- } else {
- ref[list][i] = -1;
- }
- sl->ref_cache[list][scan8[4 * i] + 1] =
- sl->ref_cache[list][scan8[4 * i] + 8] = sl->ref_cache[list][scan8[4 * i] + 9] = ref[list][i];
- }
- }
-
- if(dct8x8_allowed)
- dct8x8_allowed = get_dct8x8_allowed(h, sl);
-
- for (list = 0; list < sl->list_count; list++) {
- for(i=0; i<4; i++){
- sl->ref_cache[list][scan8[4 * i]] = sl->ref_cache[list][scan8[4 * i] + 1];
- if(IS_DIRECT(sl->sub_mb_type[i])){
- fill_rectangle(sl->mvd_cache[list][scan8[4*i]], 2, 2, 8, 0, 2);
- continue;
- }
-
- if(IS_DIR(sl->sub_mb_type[i], 0, list) && !IS_DIRECT(sl->sub_mb_type[i])){
- const int sub_mb_type= sl->sub_mb_type[i];
- const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1;
- for(j=0; j<sub_partition_count[i]; j++){
- int mpx, mpy;
- int mx, my;
- const int index= 4*i + block_width*j;
- int16_t (* mv_cache)[2] = &sl->mv_cache[list][ scan8[index] ];
- uint8_t (* mvd_cache)[2]= &sl->mvd_cache[list][ scan8[index] ];
- pred_motion(h, sl, index, block_width, list, sl->ref_cache[list][ scan8[index] ], &mx, &my);
- DECODE_CABAC_MB_MVD(sl, list, index)
- ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
-
- if(IS_SUB_8X8(sub_mb_type)){
- mv_cache[ 1 ][0]=
- mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx;
- mv_cache[ 1 ][1]=
- mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my;
-
- mvd_cache[ 1 ][0]=
- mvd_cache[ 8 ][0]= mvd_cache[ 9 ][0]= mpx;
- mvd_cache[ 1 ][1]=
- mvd_cache[ 8 ][1]= mvd_cache[ 9 ][1]= mpy;
- }else if(IS_SUB_8X4(sub_mb_type)){
- mv_cache[ 1 ][0]= mx;
- mv_cache[ 1 ][1]= my;
-
- mvd_cache[ 1 ][0]= mpx;
- mvd_cache[ 1 ][1]= mpy;
- }else if(IS_SUB_4X8(sub_mb_type)){
- mv_cache[ 8 ][0]= mx;
- mv_cache[ 8 ][1]= my;
-
- mvd_cache[ 8 ][0]= mpx;
- mvd_cache[ 8 ][1]= mpy;
- }
- mv_cache[ 0 ][0]= mx;
- mv_cache[ 0 ][1]= my;
-
- mvd_cache[ 0 ][0]= mpx;
- mvd_cache[ 0 ][1]= mpy;
- }
- }else{
- fill_rectangle(sl->mv_cache [list][ scan8[4*i] ], 2, 2, 8, 0, 4);
- fill_rectangle(sl->mvd_cache[list][ scan8[4*i] ], 2, 2, 8, 0, 2);
- }
- }
- }
- } else if( IS_DIRECT(mb_type) ) {
- ff_h264_pred_direct_motion(h, sl, &mb_type);
- fill_rectangle(sl->mvd_cache[0][scan8[0]], 4, 4, 8, 0, 2);
- fill_rectangle(sl->mvd_cache[1][scan8[0]], 4, 4, 8, 0, 2);
- dct8x8_allowed &= h->sps.direct_8x8_inference_flag;
- } else {
- int list, i;
- if(IS_16X16(mb_type)){
- for (list = 0; list < sl->list_count; list++) {
- if(IS_DIR(mb_type, 0, list)){
- int ref;
- unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
- if (rc > 1) {
- ref= decode_cabac_mb_ref(sl, list, 0);
- if (ref >= rc) {
- av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
- return -1;
- }
- }else
- ref=0;
- fill_rectangle(&sl->ref_cache[list][ scan8[0] ], 4, 4, 8, ref, 1);
- }
- }
- for (list = 0; list < sl->list_count; list++) {
- if(IS_DIR(mb_type, 0, list)){
- int mx,my,mpx,mpy;
- pred_motion(h, sl, 0, 4, list, sl->ref_cache[list][ scan8[0] ], &mx, &my);
- DECODE_CABAC_MB_MVD(sl, list, 0)
- ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
-
- fill_rectangle(sl->mvd_cache[list][ scan8[0] ], 4, 4, 8, pack8to16(mpx,mpy), 2);
- fill_rectangle(sl->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
- }
- }
- }
- else if(IS_16X8(mb_type)){
- for (list = 0; list < sl->list_count; list++) {
- for(i=0; i<2; i++){
- if(IS_DIR(mb_type, i, list)){
- int ref;
- unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
- if (rc > 1) {
- ref= decode_cabac_mb_ref(sl, list, 8 * i);
- if (ref >= rc) {
- av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
- return -1;
- }
- }else
- ref=0;
- fill_rectangle(&sl->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, ref, 1);
- }else
- fill_rectangle(&sl->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, (LIST_NOT_USED&0xFF), 1);
- }
- }
- for (list = 0; list < sl->list_count; list++) {
- for(i=0; i<2; i++){
- if(IS_DIR(mb_type, i, list)){
- int mx,my,mpx,mpy;
- pred_16x8_motion(h, sl, 8*i, list, sl->ref_cache[list][scan8[0] + 16*i], &mx, &my);
- DECODE_CABAC_MB_MVD(sl, list, 8*i)
- ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
-
- fill_rectangle(sl->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack8to16(mpx,mpy), 2);
- fill_rectangle(sl->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4);
- }else{
- fill_rectangle(sl->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 2);
- fill_rectangle(sl->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4);
- }
- }
- }
- }else{
- av_assert2(IS_8X16(mb_type));
- for (list = 0; list < sl->list_count; list++) {
- for(i=0; i<2; i++){
- if(IS_DIR(mb_type, i, list)){ //FIXME optimize
- int ref;
- unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
- if (rc > 1) {
- ref = decode_cabac_mb_ref(sl, list, 4 * i);
- if (ref >= rc) {
- av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
- return -1;
- }
- }else
- ref=0;
- fill_rectangle(&sl->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, ref, 1);
- }else
- fill_rectangle(&sl->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, (LIST_NOT_USED&0xFF), 1);
- }
- }
- for (list = 0; list < sl->list_count; list++) {
- for(i=0; i<2; i++){
- if(IS_DIR(mb_type, i, list)){
- int mx,my,mpx,mpy;
- pred_8x16_motion(h, sl, i*4, list, sl->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);
- DECODE_CABAC_MB_MVD(sl, list, 4*i)
-
- ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
- fill_rectangle(sl->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack8to16(mpx,mpy), 2);
- fill_rectangle(sl->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4);
- }else{
- fill_rectangle(sl->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 2);
- fill_rectangle(sl->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4);
- }
- }
- }
- }
- }
-
- if( IS_INTER( mb_type ) ) {
- h->chroma_pred_mode_table[mb_xy] = 0;
- write_back_motion(h, sl, mb_type);
- }
-
- if( !IS_INTRA16x16( mb_type ) ) {
- cbp = decode_cabac_mb_cbp_luma(sl);
- if(decode_chroma)
- cbp |= decode_cabac_mb_cbp_chroma(sl) << 4;
- } else {
- if (!decode_chroma && cbp>15) {
- av_log(h->avctx, AV_LOG_ERROR, "gray chroma\n");
- return AVERROR_INVALIDDATA;
- }
- }
-
- h->cbp_table[mb_xy] = sl->cbp = cbp;
-
- if( dct8x8_allowed && (cbp&15) && !IS_INTRA( mb_type ) ) {
- mb_type |= MB_TYPE_8x8DCT * get_cabac_noinline(&sl->cabac, &sl->cabac_state[399 + sl->neighbor_transform_size]);
- }
-
- /* It would be better to do this in fill_decode_caches, but we don't know
- * the transform mode of the current macroblock there. */
- if (CHROMA444(h) && IS_8x8DCT(mb_type)){
- int i;
- uint8_t *nnz_cache = sl->non_zero_count_cache;
- for (i = 0; i < 2; i++){
- if (sl->left_type[LEFT(i)] && !IS_8x8DCT(sl->left_type[LEFT(i)])) {
- nnz_cache[3+8* 1 + 2*8*i]=
- nnz_cache[3+8* 2 + 2*8*i]=
- nnz_cache[3+8* 6 + 2*8*i]=
- nnz_cache[3+8* 7 + 2*8*i]=
- nnz_cache[3+8*11 + 2*8*i]=
- nnz_cache[3+8*12 + 2*8*i]= IS_INTRA(mb_type) ? 64 : 0;
- }
- }
- if (sl->top_type && !IS_8x8DCT(sl->top_type)){
- uint32_t top_empty = CABAC(h) && !IS_INTRA(mb_type) ? 0 : 0x40404040;
- AV_WN32A(&nnz_cache[4+8* 0], top_empty);
- AV_WN32A(&nnz_cache[4+8* 5], top_empty);
- AV_WN32A(&nnz_cache[4+8*10], top_empty);
- }
- }
- h->cur_pic.mb_type[mb_xy] = mb_type;
-
- if( cbp || IS_INTRA16x16( mb_type ) ) {
- const uint8_t *scan, *scan8x8;
- const uint32_t *qmul;
-
- if(IS_INTERLACED(mb_type)){
- scan8x8 = sl->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;
- scan = sl->qscale ? h->field_scan : h->field_scan_q0;
- }else{
- scan8x8 = sl->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;
- scan = sl->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
- }
-
- // decode_cabac_mb_dqp
- if(get_cabac_noinline( &sl->cabac, &sl->cabac_state[60 + (sl->last_qscale_diff != 0)])){
- int val = 1;
- int ctx= 2;
- const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
-
- while( get_cabac_noinline( &sl->cabac, &sl->cabac_state[60 + ctx] ) ) {
- ctx= 3;
- val++;
- if(val > 2*max_qp){ //prevent infinite loop
- av_log(h->avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", sl->mb_x, sl->mb_y);
- return -1;
- }
- }
-
- if( val&0x01 )
- val= (val + 1)>>1 ;
- else
- val= -((val + 1)>>1);
- sl->last_qscale_diff = val;
- sl->qscale += val;
- if (((unsigned)sl->qscale) > max_qp){
- if (sl->qscale < 0) sl->qscale += max_qp + 1;
- else sl->qscale -= max_qp + 1;
- }
- sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale);
- sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale);
- }else
- sl->last_qscale_diff=0;
-
- decode_cabac_luma_residual(h, sl, scan, scan8x8, pixel_shift, mb_type, cbp, 0);
- if (CHROMA444(h)) {
- decode_cabac_luma_residual(h, sl, scan, scan8x8, pixel_shift, mb_type, cbp, 1);
- decode_cabac_luma_residual(h, sl, scan, scan8x8, pixel_shift, mb_type, cbp, 2);
- } else if (CHROMA422(h)) {
- if( cbp&0x30 ){
- int c;
- for (c = 0; c < 2; c++)
- decode_cabac_residual_dc_422(h, sl, sl->mb + ((256 + 16*16*c) << pixel_shift), 3,
- CHROMA_DC_BLOCK_INDEX + c,
- chroma422_dc_scan, 8);
- }
-
- if( cbp&0x20 ) {
- int c, i, i8x8;
- for( c = 0; c < 2; c++ ) {
- int16_t *mb = sl->mb + (16*(16 + 16*c) << pixel_shift);
- qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][sl->chroma_qp[c]];
- for (i8x8 = 0; i8x8 < 2; i8x8++) {
- for (i = 0; i < 4; i++) {
- const int index = 16 + 16 * c + 8*i8x8 + i;
- decode_cabac_residual_nondc(h, sl, mb, 4, index, scan + 1, qmul, 15);
- mb += 16<<pixel_shift;
- }
- }
- }
- } else {
- fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
- fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
- }
- } else /* yuv420 */ {
- if( cbp&0x30 ){
- int c;
- for (c = 0; c < 2; c++)
- decode_cabac_residual_dc(h, sl, sl->mb + ((256 + 16*16*c) << pixel_shift), 3, CHROMA_DC_BLOCK_INDEX+c, chroma_dc_scan, 4);
- }
-
- if( cbp&0x20 ) {
- int c, i;
- for( c = 0; c < 2; c++ ) {
- qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][sl->chroma_qp[c]];
- for( i = 0; i < 4; i++ ) {
- const int index = 16 + 16 * c + i;
- decode_cabac_residual_nondc(h, sl, sl->mb + (16*index << pixel_shift), 4, index, scan + 1, qmul, 15);
- }
- }
- } else {
- fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
- fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
- }
- }
- } else {
- fill_rectangle(&sl->non_zero_count_cache[scan8[ 0]], 4, 4, 8, 0, 1);
- fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
- fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
- sl->last_qscale_diff = 0;
- }
-
- h->cur_pic.qscale_table[mb_xy] = sl->qscale;
- write_back_non_zero_count(h, sl);
-
- return 0;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/h264_cavlc.c b/ffmpeg-2-8-11/libavcodec/h264_cavlc.c
deleted file mode 100644
index b0251f4..0000000
--- a/ffmpeg-2-8-11/libavcodec/h264_cavlc.c
+++ /dev/null
@@ -1,1182 +0,0 @@
-/*
- * H.26L/H.264/AVC/JVT/14496-10/... cavlc bitstream decoding
- * Copyright (c) 2003 Michael Niedermayer <michaelni at gmx.at>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * H.264 / AVC / MPEG4 part10 cavlc bitstream decoding.
- * @author Michael Niedermayer <michaelni at gmx.at>
- */
-
-#define CABAC(h) 0
-#define UNCHECKED_BITSTREAM_READER 1
-
-#include "internal.h"
-#include "avcodec.h"
-#include "h264.h"
-#include "h264data.h" // FIXME FIXME FIXME
-#include "h264_mvpred.h"
-#include "golomb.h"
-#include "mpegutils.h"
-#include "libavutil/avassert.h"
-
-
-static const uint8_t golomb_to_inter_cbp_gray[16]={
- 0, 1, 2, 4, 8, 3, 5,10,12,15, 7,11,13,14, 6, 9,
-};
-
-static const uint8_t golomb_to_intra4x4_cbp_gray[16]={
-15, 0, 7,11,13,14, 3, 5,10,12, 1, 2, 4, 8, 6, 9,
-};
-
-static const uint8_t chroma_dc_coeff_token_len[4*5]={
- 2, 0, 0, 0,
- 6, 1, 0, 0,
- 6, 6, 3, 0,
- 6, 7, 7, 6,
- 6, 8, 8, 7,
-};
-
-static const uint8_t chroma_dc_coeff_token_bits[4*5]={
- 1, 0, 0, 0,
- 7, 1, 0, 0,
- 4, 6, 1, 0,
- 3, 3, 2, 5,
- 2, 3, 2, 0,
-};
-
-static const uint8_t chroma422_dc_coeff_token_len[4*9]={
- 1, 0, 0, 0,
- 7, 2, 0, 0,
- 7, 7, 3, 0,
- 9, 7, 7, 5,
- 9, 9, 7, 6,
- 10, 10, 9, 7,
- 11, 11, 10, 7,
- 12, 12, 11, 10,
- 13, 12, 12, 11,
-};
-
-static const uint8_t chroma422_dc_coeff_token_bits[4*9]={
- 1, 0, 0, 0,
- 15, 1, 0, 0,
- 14, 13, 1, 0,
- 7, 12, 11, 1,
- 6, 5, 10, 1,
- 7, 6, 4, 9,
- 7, 6, 5, 8,
- 7, 6, 5, 4,
- 7, 5, 4, 4,
-};
-
-static const uint8_t coeff_token_len[4][4*17]={
-{
- 1, 0, 0, 0,
- 6, 2, 0, 0, 8, 6, 3, 0, 9, 8, 7, 5, 10, 9, 8, 6,
- 11,10, 9, 7, 13,11,10, 8, 13,13,11, 9, 13,13,13,10,
- 14,14,13,11, 14,14,14,13, 15,15,14,14, 15,15,15,14,
- 16,15,15,15, 16,16,16,15, 16,16,16,16, 16,16,16,16,
-},
-{
- 2, 0, 0, 0,
- 6, 2, 0, 0, 6, 5, 3, 0, 7, 6, 6, 4, 8, 6, 6, 4,
- 8, 7, 7, 5, 9, 8, 8, 6, 11, 9, 9, 6, 11,11,11, 7,
- 12,11,11, 9, 12,12,12,11, 12,12,12,11, 13,13,13,12,
- 13,13,13,13, 13,14,13,13, 14,14,14,13, 14,14,14,14,
-},
-{
- 4, 0, 0, 0,
- 6, 4, 0, 0, 6, 5, 4, 0, 6, 5, 5, 4, 7, 5, 5, 4,
- 7, 5, 5, 4, 7, 6, 6, 4, 7, 6, 6, 4, 8, 7, 7, 5,
- 8, 8, 7, 6, 9, 8, 8, 7, 9, 9, 8, 8, 9, 9, 9, 8,
- 10, 9, 9, 9, 10,10,10,10, 10,10,10,10, 10,10,10,10,
-},
-{
- 6, 0, 0, 0,
- 6, 6, 0, 0, 6, 6, 6, 0, 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, 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, 6, 6, 6, 6, 6, 6,
-}
-};
-
-static const uint8_t coeff_token_bits[4][4*17]={
-{
- 1, 0, 0, 0,
- 5, 1, 0, 0, 7, 4, 1, 0, 7, 6, 5, 3, 7, 6, 5, 3,
- 7, 6, 5, 4, 15, 6, 5, 4, 11,14, 5, 4, 8,10,13, 4,
- 15,14, 9, 4, 11,10,13,12, 15,14, 9,12, 11,10,13, 8,
- 15, 1, 9,12, 11,14,13, 8, 7,10, 9,12, 4, 6, 5, 8,
-},
-{
- 3, 0, 0, 0,
- 11, 2, 0, 0, 7, 7, 3, 0, 7,10, 9, 5, 7, 6, 5, 4,
- 4, 6, 5, 6, 7, 6, 5, 8, 15, 6, 5, 4, 11,14,13, 4,
- 15,10, 9, 4, 11,14,13,12, 8,10, 9, 8, 15,14,13,12,
- 11,10, 9,12, 7,11, 6, 8, 9, 8,10, 1, 7, 6, 5, 4,
-},
-{
- 15, 0, 0, 0,
- 15,14, 0, 0, 11,15,13, 0, 8,12,14,12, 15,10,11,11,
- 11, 8, 9,10, 9,14,13, 9, 8,10, 9, 8, 15,14,13,13,
- 11,14,10,12, 15,10,13,12, 11,14, 9,12, 8,10,13, 8,
- 13, 7, 9,12, 9,12,11,10, 5, 8, 7, 6, 1, 4, 3, 2,
-},
-{
- 3, 0, 0, 0,
- 0, 1, 0, 0, 4, 5, 6, 0, 8, 9,10,11, 12,13,14,15,
- 16,17,18,19, 20,21,22,23, 24,25,26,27, 28,29,30,31,
- 32,33,34,35, 36,37,38,39, 40,41,42,43, 44,45,46,47,
- 48,49,50,51, 52,53,54,55, 56,57,58,59, 60,61,62,63,
-}
-};
-
-static const uint8_t total_zeros_len[16][16]= {
- {1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9},
- {3,3,3,3,3,4,4,4,4,5,5,6,6,6,6},
- {4,3,3,3,4,4,3,3,4,5,5,6,5,6},
- {5,3,4,4,3,3,3,4,3,4,5,5,5},
- {4,4,4,3,3,3,3,3,4,5,4,5},
- {6,5,3,3,3,3,3,3,4,3,6},
- {6,5,3,3,3,2,3,4,3,6},
- {6,4,5,3,2,2,3,3,6},
- {6,6,4,2,2,3,2,5},
- {5,5,3,2,2,2,4},
- {4,4,3,3,1,3},
- {4,4,2,1,3},
- {3,3,1,2},
- {2,2,1},
- {1,1},
-};
-
-static const uint8_t total_zeros_bits[16][16]= {
- {1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1},
- {7,6,5,4,3,5,4,3,2,3,2,3,2,1,0},
- {5,7,6,5,4,3,4,3,2,3,2,1,1,0},
- {3,7,5,4,6,5,4,3,3,2,2,1,0},
- {5,4,3,7,6,5,4,3,2,1,1,0},
- {1,1,7,6,5,4,3,2,1,1,0},
- {1,1,5,4,3,3,2,1,1,0},
- {1,1,1,3,3,2,2,1,0},
- {1,0,1,3,2,1,1,1},
- {1,0,1,3,2,1,1},
- {0,1,1,2,1,3},
- {0,1,1,1,1},
- {0,1,1,1},
- {0,1,1},
- {0,1},
-};
-
-static const uint8_t chroma_dc_total_zeros_len[3][4]= {
- { 1, 2, 3, 3,},
- { 1, 2, 2, 0,},
- { 1, 1, 0, 0,},
-};
-
-static const uint8_t chroma_dc_total_zeros_bits[3][4]= {
- { 1, 1, 1, 0,},
- { 1, 1, 0, 0,},
- { 1, 0, 0, 0,},
-};
-
-static const uint8_t chroma422_dc_total_zeros_len[7][8]= {
- { 1, 3, 3, 4, 4, 4, 5, 5 },
- { 3, 2, 3, 3, 3, 3, 3 },
- { 3, 3, 2, 2, 3, 3 },
- { 3, 2, 2, 2, 3 },
- { 2, 2, 2, 2 },
- { 2, 2, 1 },
- { 1, 1 },
-};
-
-static const uint8_t chroma422_dc_total_zeros_bits[7][8]= {
- { 1, 2, 3, 2, 3, 1, 1, 0 },
- { 0, 1, 1, 4, 5, 6, 7 },
- { 0, 1, 1, 2, 6, 7 },
- { 6, 0, 1, 2, 7 },
- { 0, 1, 2, 3 },
- { 0, 1, 1 },
- { 0, 1 },
-};
-
-static const uint8_t run_len[7][16]={
- {1,1},
- {1,2,2},
- {2,2,2,2},
- {2,2,2,3,3},
- {2,2,3,3,3,3},
- {2,3,3,3,3,3,3},
- {3,3,3,3,3,3,3,4,5,6,7,8,9,10,11},
-};
-
-static const uint8_t run_bits[7][16]={
- {1,0},
- {1,1,0},
- {3,2,1,0},
- {3,2,1,1,0},
- {3,2,3,2,1,0},
- {3,0,1,3,2,5,4},
- {7,6,5,4,3,2,1,1,1,1,1,1,1,1,1},
-};
-
-static VLC coeff_token_vlc[4];
-static VLC_TYPE coeff_token_vlc_tables[520+332+280+256][2];
-static const int coeff_token_vlc_tables_size[4]={520,332,280,256};
-
-static VLC chroma_dc_coeff_token_vlc;
-static VLC_TYPE chroma_dc_coeff_token_vlc_table[256][2];
-static const int chroma_dc_coeff_token_vlc_table_size = 256;
-
-static VLC chroma422_dc_coeff_token_vlc;
-static VLC_TYPE chroma422_dc_coeff_token_vlc_table[8192][2];
-static const int chroma422_dc_coeff_token_vlc_table_size = 8192;
-
-static VLC total_zeros_vlc[15];
-static VLC_TYPE total_zeros_vlc_tables[15][512][2];
-static const int total_zeros_vlc_tables_size = 512;
-
-static VLC chroma_dc_total_zeros_vlc[3];
-static VLC_TYPE chroma_dc_total_zeros_vlc_tables[3][8][2];
-static const int chroma_dc_total_zeros_vlc_tables_size = 8;
-
-static VLC chroma422_dc_total_zeros_vlc[7];
-static VLC_TYPE chroma422_dc_total_zeros_vlc_tables[7][32][2];
-static const int chroma422_dc_total_zeros_vlc_tables_size = 32;
-
-static VLC run_vlc[6];
-static VLC_TYPE run_vlc_tables[6][8][2];
-static const int run_vlc_tables_size = 8;
-
-static VLC run7_vlc;
-static VLC_TYPE run7_vlc_table[96][2];
-static const int run7_vlc_table_size = 96;
-
-#define LEVEL_TAB_BITS 8
-static int8_t cavlc_level_tab[7][1<<LEVEL_TAB_BITS][2];
-
-#define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8
-#define CHROMA422_DC_COEFF_TOKEN_VLC_BITS 13
-#define COEFF_TOKEN_VLC_BITS 8
-#define TOTAL_ZEROS_VLC_BITS 9
-#define CHROMA_DC_TOTAL_ZEROS_VLC_BITS 3
-#define CHROMA422_DC_TOTAL_ZEROS_VLC_BITS 5
-#define RUN_VLC_BITS 3
-#define RUN7_VLC_BITS 6
-
-/**
- * Get the predicted number of non-zero coefficients.
- * @param n block index
- */
-static inline int pred_non_zero_count(const H264Context *h, H264SliceContext *sl, int n)
-{
- const int index8= scan8[n];
- const int left = sl->non_zero_count_cache[index8 - 1];
- const int top = sl->non_zero_count_cache[index8 - 8];
- int i= left + top;
-
- if(i<64) i= (i+1)>>1;
-
- ff_tlog(h->avctx, "pred_nnz L%X T%X n%d s%d P%X\n", left, top, n, scan8[n], i&31);
-
- return i&31;
-}
-
-static av_cold void init_cavlc_level_tab(void){
- int suffix_length;
- unsigned int i;
-
- for(suffix_length=0; suffix_length<7; suffix_length++){
- for(i=0; i<(1<<LEVEL_TAB_BITS); i++){
- int prefix= LEVEL_TAB_BITS - av_log2(2*i);
-
- if(prefix + 1 + suffix_length <= LEVEL_TAB_BITS){
- int level_code = (prefix << suffix_length) +
- (i >> (av_log2(i) - suffix_length)) - (1 << suffix_length);
- int mask = -(level_code&1);
- level_code = (((2 + level_code) >> 1) ^ mask) - mask;
- cavlc_level_tab[suffix_length][i][0]= level_code;
- cavlc_level_tab[suffix_length][i][1]= prefix + 1 + suffix_length;
- }else if(prefix + 1 <= LEVEL_TAB_BITS){
- cavlc_level_tab[suffix_length][i][0]= prefix+100;
- cavlc_level_tab[suffix_length][i][1]= prefix + 1;
- }else{
- cavlc_level_tab[suffix_length][i][0]= LEVEL_TAB_BITS+100;
- cavlc_level_tab[suffix_length][i][1]= LEVEL_TAB_BITS;
- }
- }
- }
-}
-
-av_cold void ff_h264_decode_init_vlc(void){
- static int done = 0;
-
- 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);
-
- 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].table = chroma_dc_total_zeros_vlc_tables[i];
- chroma_dc_total_zeros_vlc[i].table_allocated = chroma_dc_total_zeros_vlc_tables_size;
- init_vlc(&chroma_dc_total_zeros_vlc[i],
- 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].table = chroma422_dc_total_zeros_vlc_tables[i];
- chroma422_dc_total_zeros_vlc[i].table_allocated = chroma422_dc_total_zeros_vlc_tables_size;
- init_vlc(&chroma422_dc_total_zeros_vlc[i],
- 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].table = total_zeros_vlc_tables[i];
- total_zeros_vlc[i].table_allocated = total_zeros_vlc_tables_size;
- init_vlc(&total_zeros_vlc[i],
- 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].table = run_vlc_tables[i];
- run_vlc[i].table_allocated = run_vlc_tables_size;
- init_vlc(&run_vlc[i],
- 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){
- unsigned int buf;
- int log;
-
- OPEN_READER(re, gb);
- UPDATE_CACHE(re, gb);
- buf=GET_CACHE(re, gb);
-
- log= 32 - av_log2(buf);
-#ifdef TRACE
- print_bin(buf>>(32-log), log);
- av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d lpr @%5d in %s get_level_prefix\n", buf>>(32-log), log, log-1, get_bits_count(gb), __FILE__);
-#endif
-
- LAST_SKIP_BITS(re, gb, log);
- CLOSE_READER(re, gb);
-
- return log-1;
-}
-
-/**
- * Decode a residual block.
- * @param n block index
- * @param scantable scantable
- * @param max_coeff number of coefficients in the block
- * @return <0 if an error occurred
- */
-static int decode_residual(const H264Context *h, H264SliceContext *sl,
- GetBitContext *gb, int16_t *block, int n,
- const uint8_t *scantable, const uint32_t *qmul,
- int max_coeff)
-{
- static const int coeff_token_table_index[17]= {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3};
- int level[16];
- int zeros_left, coeff_token, total_coeff, i, trailing_ones, run_before;
-
- //FIXME put trailing_onex into the context
-
- if(max_coeff <= 8){
- if (max_coeff == 4)
- coeff_token = get_vlc2(gb, chroma_dc_coeff_token_vlc.table, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1);
- else
- coeff_token = get_vlc2(gb, chroma422_dc_coeff_token_vlc.table, CHROMA422_DC_COEFF_TOKEN_VLC_BITS, 1);
- total_coeff= coeff_token>>2;
- }else{
- if(n >= LUMA_DC_BLOCK_INDEX){
- total_coeff= pred_non_zero_count(h, sl, (n - LUMA_DC_BLOCK_INDEX)*16);
- coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2);
- total_coeff= coeff_token>>2;
- }else{
- total_coeff= pred_non_zero_count(h, sl, n);
- coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2);
- total_coeff= coeff_token>>2;
- }
- }
- sl->non_zero_count_cache[scan8[n]] = total_coeff;
-
- //FIXME set last_non_zero?
-
- if(total_coeff==0)
- return 0;
- if(total_coeff > (unsigned)max_coeff) {
- av_log(h->avctx, AV_LOG_ERROR, "corrupted macroblock %d %d (total_coeff=%d)\n", sl->mb_x, sl->mb_y, total_coeff);
- return -1;
- }
-
- trailing_ones= coeff_token&3;
- ff_tlog(h->avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
- av_assert2(total_coeff<=16);
-
- i = show_bits(gb, 3);
- skip_bits(gb, trailing_ones);
- level[0] = 1-((i&4)>>1);
- level[1] = 1-((i&2) );
- level[2] = 1-((i&1)<<1);
-
- if(trailing_ones<total_coeff) {
- int mask, prefix;
- int suffix_length = total_coeff > 10 & trailing_ones < 3;
- int bitsi= show_bits(gb, LEVEL_TAB_BITS);
- int level_code= cavlc_level_tab[suffix_length][bitsi][0];
-
- skip_bits(gb, cavlc_level_tab[suffix_length][bitsi][1]);
- if(level_code >= 100){
- prefix= level_code - 100;
- if(prefix == LEVEL_TAB_BITS)
- prefix += get_level_prefix(gb);
-
- //first coefficient has suffix_length equal to 0 or 1
- if(prefix<14){ //FIXME try to build a large unified VLC table for all this
- if(suffix_length)
- level_code= (prefix<<1) + get_bits1(gb); //part
- else
- level_code= prefix; //part
- }else if(prefix==14){
- if(suffix_length)
- level_code= (prefix<<1) + get_bits1(gb); //part
- else
- level_code= prefix + get_bits(gb, 4); //part
- }else{
- level_code= 30;
- if(prefix>=16){
- if(prefix > 25+3){
- av_log(h->avctx, AV_LOG_ERROR, "Invalid level prefix\n");
- return -1;
- }
- level_code += (1<<(prefix-3))-4096;
- }
- level_code += get_bits(gb, prefix-3); //part
- }
-
- if(trailing_ones < 3) level_code += 2;
-
- suffix_length = 2;
- mask= -(level_code&1);
- level[trailing_ones]= (((2+level_code)>>1) ^ mask) - mask;
- }else{
- level_code += ((level_code>>31)|1) & -(trailing_ones < 3);
-
- suffix_length = 1 + (level_code + 3U > 6U);
- level[trailing_ones]= level_code;
- }
-
- //remaining coefficients have suffix_length > 0
- for(i=trailing_ones+1;i<total_coeff;i++) {
- static const unsigned int suffix_limit[7] = {0,3,6,12,24,48,INT_MAX };
- int bitsi= show_bits(gb, LEVEL_TAB_BITS);
- level_code= cavlc_level_tab[suffix_length][bitsi][0];
-
- skip_bits(gb, cavlc_level_tab[suffix_length][bitsi][1]);
- if(level_code >= 100){
- prefix= level_code - 100;
- if(prefix == LEVEL_TAB_BITS){
- prefix += get_level_prefix(gb);
- }
- if(prefix<15){
- level_code = (prefix<<suffix_length) + get_bits(gb, suffix_length);
- }else{
- level_code = 15<<suffix_length;
- if (prefix>=16) {
- if(prefix > 25+3){
- av_log(h->avctx, AV_LOG_ERROR, "Invalid level prefix\n");
- return AVERROR_INVALIDDATA;
- }
- level_code += (1<<(prefix-3))-4096;
- }
- level_code += get_bits(gb, prefix-3);
- }
- mask= -(level_code&1);
- level_code= (((2+level_code)>>1) ^ mask) - mask;
- }
- level[i]= level_code;
- suffix_length+= suffix_limit[suffix_length] + level_code > 2U*suffix_limit[suffix_length];
- }
- }
-
- if(total_coeff == max_coeff)
- zeros_left=0;
- else{
- if (max_coeff <= 8) {
- if (max_coeff == 4)
- zeros_left = get_vlc2(gb, (chroma_dc_total_zeros_vlc-1)[total_coeff].table,
- CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1);
- else
- zeros_left = get_vlc2(gb, (chroma422_dc_total_zeros_vlc-1)[total_coeff].table,
- CHROMA422_DC_TOTAL_ZEROS_VLC_BITS, 1);
- } else {
- zeros_left= get_vlc2(gb, (total_zeros_vlc-1)[ total_coeff ].table, TOTAL_ZEROS_VLC_BITS, 1);
- }
- }
-
-#define STORE_BLOCK(type) \
- scantable += zeros_left + total_coeff - 1; \
- if(n >= LUMA_DC_BLOCK_INDEX){ \
- ((type*)block)[*scantable] = level[0]; \
- for(i=1;i<total_coeff && zeros_left > 0;i++) { \
- if(zeros_left < 7) \
- run_before= get_vlc2(gb, (run_vlc-1)[zeros_left].table, RUN_VLC_BITS, 1); \
- else \
- run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2); \
- zeros_left -= run_before; \
- scantable -= 1 + run_before; \
- ((type*)block)[*scantable]= level[i]; \
- } \
- for(;i<total_coeff;i++) { \
- scantable--; \
- ((type*)block)[*scantable]= level[i]; \
- } \
- }else{ \
- ((type*)block)[*scantable] = ((int)(level[0] * qmul[*scantable] + 32))>>6; \
- for(i=1;i<total_coeff && zeros_left > 0;i++) { \
- if(zeros_left < 7) \
- run_before= get_vlc2(gb, (run_vlc-1)[zeros_left].table, RUN_VLC_BITS, 1); \
- else \
- run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2); \
- zeros_left -= run_before; \
- scantable -= 1 + run_before; \
- ((type*)block)[*scantable]= ((int)(level[i] * qmul[*scantable] + 32))>>6; \
- } \
- for(;i<total_coeff;i++) { \
- scantable--; \
- ((type*)block)[*scantable]= ((int)(level[i] * qmul[*scantable] + 32))>>6; \
- } \
- }
-
- if (h->pixel_shift) {
- STORE_BLOCK(int32_t)
- } else {
- STORE_BLOCK(int16_t)
- }
-
- if(zeros_left<0){
- av_log(h->avctx, AV_LOG_ERROR, "negative number of zero coeffs at %d %d\n", sl->mb_x, sl->mb_y);
- return -1;
- }
-
- return 0;
-}
-
-static av_always_inline
-int decode_luma_residual(const H264Context *h, H264SliceContext *sl,
- GetBitContext *gb, const uint8_t *scan,
- const uint8_t *scan8x8, int pixel_shift,
- int mb_type, int cbp, int p)
-{
- int i4x4, i8x8;
- int qscale = p == 0 ? sl->qscale : sl->chroma_qp[p - 1];
- if(IS_INTRA16x16(mb_type)){
- AV_ZERO128(sl->mb_luma_dc[p]+0);
- AV_ZERO128(sl->mb_luma_dc[p]+8);
- AV_ZERO128(sl->mb_luma_dc[p]+16);
- AV_ZERO128(sl->mb_luma_dc[p]+24);
- if (decode_residual(h, sl, gb, sl->mb_luma_dc[p], LUMA_DC_BLOCK_INDEX + p, scan, NULL, 16) < 0) {
- return -1; //FIXME continue if partitioned and other return -1 too
- }
-
- av_assert2((cbp&15) == 0 || (cbp&15) == 15);
-
- if(cbp&15){
- for(i8x8=0; i8x8<4; i8x8++){
- for(i4x4=0; i4x4<4; i4x4++){
- const int index= i4x4 + 4*i8x8 + p*16;
- if( decode_residual(h, sl, gb, sl->mb + (16*index << pixel_shift),
- index, scan + 1, h->dequant4_coeff[p][qscale], 15) < 0 ){
- return -1;
- }
- }
- }
- return 0xf;
- }else{
- fill_rectangle(&sl->non_zero_count_cache[scan8[p*16]], 4, 4, 8, 0, 1);
- return 0;
- }
- }else{
- int cqm = (IS_INTRA( mb_type ) ? 0:3)+p;
- /* For CAVLC 4:4:4, we need to keep track of the luma 8x8 CBP for deblocking nnz purposes. */
- int new_cbp = 0;
- for(i8x8=0; i8x8<4; i8x8++){
- if(cbp & (1<<i8x8)){
- if(IS_8x8DCT(mb_type)){
- int16_t *buf = &sl->mb[64*i8x8+256*p << pixel_shift];
- uint8_t *nnz;
- for(i4x4=0; i4x4<4; i4x4++){
- const int index= i4x4 + 4*i8x8 + p*16;
- if( decode_residual(h, sl, gb, buf, index, scan8x8+16*i4x4,
- h->dequant8_coeff[cqm][qscale], 16) < 0 )
- return -1;
- }
- nnz = &sl->non_zero_count_cache[scan8[4 * i8x8 + p * 16]];
- nnz[0] += nnz[1] + nnz[8] + nnz[9];
- new_cbp |= !!nnz[0] << i8x8;
- }else{
- for(i4x4=0; i4x4<4; i4x4++){
- const int index= i4x4 + 4*i8x8 + p*16;
- if( decode_residual(h, sl, gb, sl->mb + (16*index << pixel_shift), index,
- scan, h->dequant4_coeff[cqm][qscale], 16) < 0 ){
- return -1;
- }
- new_cbp |= sl->non_zero_count_cache[scan8[index]] << i8x8;
- }
- }
- }else{
- uint8_t * const nnz = &sl->non_zero_count_cache[scan8[4 * i8x8 + p * 16]];
- nnz[0] = nnz[1] = nnz[8] = nnz[9] = 0;
- }
- }
- return new_cbp;
- }
-}
-
-int ff_h264_decode_mb_cavlc(const H264Context *h, H264SliceContext *sl)
-{
- int mb_xy;
- int partition_count;
- unsigned int mb_type, cbp;
- int dct8x8_allowed= h->pps.transform_8x8_mode;
- int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;
- const int pixel_shift = h->pixel_shift;
-
- mb_xy = sl->mb_xy = sl->mb_x + sl->mb_y*h->mb_stride;
-
- ff_tlog(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, sl->mb_x, sl->mb_y);
- cbp = 0; /* avoid warning. FIXME: find a solution without slowing
- down the code */
- if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {
- if (sl->mb_skip_run == -1)
- sl->mb_skip_run = get_ue_golomb_long(&sl->gb);
-
- if (sl->mb_skip_run--) {
- if (FRAME_MBAFF(h) && (sl->mb_y & 1) == 0) {
- if (sl->mb_skip_run == 0)
- sl->mb_mbaff = sl->mb_field_decoding_flag = get_bits1(&sl->gb);
- }
- decode_mb_skip(h, sl);
- return 0;
- }
- }
- if (FRAME_MBAFF(h)) {
- if ((sl->mb_y & 1) == 0)
- sl->mb_mbaff = sl->mb_field_decoding_flag = get_bits1(&sl->gb);
- }
-
- sl->prev_mb_skipped = 0;
-
- mb_type= get_ue_golomb(&sl->gb);
- if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
- if(mb_type < 23){
- partition_count= b_mb_type_info[mb_type].partition_count;
- mb_type= b_mb_type_info[mb_type].type;
- }else{
- mb_type -= 23;
- goto decode_intra_mb;
- }
- } else if (sl->slice_type_nos == AV_PICTURE_TYPE_P) {
- if(mb_type < 5){
- partition_count= p_mb_type_info[mb_type].partition_count;
- mb_type= p_mb_type_info[mb_type].type;
- }else{
- mb_type -= 5;
- goto decode_intra_mb;
- }
- }else{
- av_assert2(sl->slice_type_nos == AV_PICTURE_TYPE_I);
- if (sl->slice_type == AV_PICTURE_TYPE_SI && mb_type)
- mb_type--;
-decode_intra_mb:
- if(mb_type > 25){
- av_log(h->avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_picture_type_char(sl->slice_type), sl->mb_x, sl->mb_y);
- return -1;
- }
- partition_count=0;
- cbp= i_mb_type_info[mb_type].cbp;
- sl->intra16x16_pred_mode = i_mb_type_info[mb_type].pred_mode;
- mb_type= i_mb_type_info[mb_type].type;
- }
-
- if (MB_FIELD(sl))
- mb_type |= MB_TYPE_INTERLACED;
-
- h->slice_table[mb_xy] = sl->slice_num;
-
- if(IS_INTRA_PCM(mb_type)){
- const int mb_size = ff_h264_mb_sizes[h->sps.chroma_format_idc] *
- h->sps.bit_depth_luma;
-
- // We assume these blocks are very rare so we do not optimize it.
- sl->intra_pcm_ptr = align_get_bits(&sl->gb);
- if (get_bits_left(&sl->gb) < mb_size) {
- av_log(h->avctx, AV_LOG_ERROR, "Not enough data for an intra PCM block.\n");
- return AVERROR_INVALIDDATA;
- }
- skip_bits_long(&sl->gb, mb_size);
-
- // In deblocking, the quantizer is 0
- h->cur_pic.qscale_table[mb_xy] = 0;
- // All coeffs are present
- memset(h->non_zero_count[mb_xy], 16, 48);
-
- h->cur_pic.mb_type[mb_xy] = mb_type;
- return 0;
- }
-
- fill_decode_neighbors(h, sl, mb_type);
- fill_decode_caches(h, sl, mb_type);
-
- //mb_pred
- if(IS_INTRA(mb_type)){
- int pred_mode;
-// init_top_left_availability(h);
- if(IS_INTRA4x4(mb_type)){
- int i;
- int di = 1;
- if(dct8x8_allowed && get_bits1(&sl->gb)){
- mb_type |= MB_TYPE_8x8DCT;
- di = 4;
- }
-
-// fill_intra4x4_pred_table(h);
- for(i=0; i<16; i+=di){
- int mode = pred_intra_mode(h, sl, i);
-
- if(!get_bits1(&sl->gb)){
- const int rem_mode= get_bits(&sl->gb, 3);
- mode = rem_mode + (rem_mode >= mode);
- }
-
- if(di==4)
- fill_rectangle(&sl->intra4x4_pred_mode_cache[ scan8[i] ], 2, 2, 8, mode, 1);
- else
- sl->intra4x4_pred_mode_cache[scan8[i]] = mode;
- }
- write_back_intra_pred_mode(h, sl);
- if (ff_h264_check_intra4x4_pred_mode(h, sl) < 0)
- return -1;
- }else{
- sl->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, sl, sl->intra16x16_pred_mode, 0);
- if (sl->intra16x16_pred_mode < 0)
- return -1;
- }
- if(decode_chroma){
- pred_mode= ff_h264_check_intra_pred_mode(h, sl, get_ue_golomb_31(&sl->gb), 1);
- if(pred_mode < 0)
- return -1;
- sl->chroma_pred_mode = pred_mode;
- } else {
- sl->chroma_pred_mode = DC_128_PRED8x8;
- }
- }else if(partition_count==4){
- int i, j, sub_partition_count[4], list, ref[2][4];
-
- if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
- for(i=0; i<4; i++){
- sl->sub_mb_type[i]= get_ue_golomb_31(&sl->gb);
- if(sl->sub_mb_type[i] >=13){
- av_log(h->avctx, AV_LOG_ERROR, "B sub_mb_type %u out of range at %d %d\n", sl->sub_mb_type[i], sl->mb_x, sl->mb_y);
- return -1;
- }
- sub_partition_count[i]= b_sub_mb_type_info[ sl->sub_mb_type[i] ].partition_count;
- sl->sub_mb_type[i]= b_sub_mb_type_info[ sl->sub_mb_type[i] ].type;
- }
- if( IS_DIRECT(sl->sub_mb_type[0]|sl->sub_mb_type[1]|sl->sub_mb_type[2]|sl->sub_mb_type[3])) {
- ff_h264_pred_direct_motion(h, sl, &mb_type);
- sl->ref_cache[0][scan8[4]] =
- sl->ref_cache[1][scan8[4]] =
- sl->ref_cache[0][scan8[12]] =
- sl->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;
- }
- }else{
- av_assert2(sl->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?
- for(i=0; i<4; i++){
- sl->sub_mb_type[i]= get_ue_golomb_31(&sl->gb);
- if(sl->sub_mb_type[i] >=4){
- av_log(h->avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", sl->sub_mb_type[i], sl->mb_x, sl->mb_y);
- return -1;
- }
- sub_partition_count[i]= p_sub_mb_type_info[ sl->sub_mb_type[i] ].partition_count;
- sl->sub_mb_type[i]= p_sub_mb_type_info[ sl->sub_mb_type[i] ].type;
- }
- }
-
- for (list = 0; list < sl->list_count; list++) {
- int ref_count = IS_REF0(mb_type) ? 1 : sl->ref_count[list] << MB_MBAFF(sl);
- for(i=0; i<4; i++){
- if(IS_DIRECT(sl->sub_mb_type[i])) continue;
- if(IS_DIR(sl->sub_mb_type[i], 0, list)){
- unsigned int tmp;
- if(ref_count == 1){
- tmp= 0;
- }else if(ref_count == 2){
- tmp= get_bits1(&sl->gb)^1;
- }else{
- tmp= get_ue_golomb_31(&sl->gb);
- if(tmp>=ref_count){
- av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp);
- return -1;
- }
- }
- ref[list][i]= tmp;
- }else{
- //FIXME
- ref[list][i] = -1;
- }
- }
- }
-
- if(dct8x8_allowed)
- dct8x8_allowed = get_dct8x8_allowed(h, sl);
-
- for (list = 0; list < sl->list_count; list++) {
- for(i=0; i<4; i++){
- if(IS_DIRECT(sl->sub_mb_type[i])) {
- sl->ref_cache[list][ scan8[4*i] ] = sl->ref_cache[list][ scan8[4*i]+1 ];
- continue;
- }
- sl->ref_cache[list][ scan8[4*i] ]=sl->ref_cache[list][ scan8[4*i]+1 ]=
- sl->ref_cache[list][ scan8[4*i]+8 ]=sl->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i];
-
- if(IS_DIR(sl->sub_mb_type[i], 0, list)){
- const int sub_mb_type= sl->sub_mb_type[i];
- const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1;
- for(j=0; j<sub_partition_count[i]; j++){
- int mx, my;
- const int index= 4*i + block_width*j;
- int16_t (* mv_cache)[2]= &sl->mv_cache[list][ scan8[index] ];
- pred_motion(h, sl, index, block_width, list, sl->ref_cache[list][ scan8[index] ], &mx, &my);
- mx += get_se_golomb(&sl->gb);
- my += get_se_golomb(&sl->gb);
- ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
-
- if(IS_SUB_8X8(sub_mb_type)){
- mv_cache[ 1 ][0]=
- mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx;
- mv_cache[ 1 ][1]=
- mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my;
- }else if(IS_SUB_8X4(sub_mb_type)){
- mv_cache[ 1 ][0]= mx;
- mv_cache[ 1 ][1]= my;
- }else if(IS_SUB_4X8(sub_mb_type)){
- mv_cache[ 8 ][0]= mx;
- mv_cache[ 8 ][1]= my;
- }
- mv_cache[ 0 ][0]= mx;
- mv_cache[ 0 ][1]= my;
- }
- }else{
- uint32_t *p= (uint32_t *)&sl->mv_cache[list][ scan8[4*i] ][0];
- p[0] = p[1]=
- p[8] = p[9]= 0;
- }
- }
- }
- }else if(IS_DIRECT(mb_type)){
- ff_h264_pred_direct_motion(h, sl, &mb_type);
- dct8x8_allowed &= h->sps.direct_8x8_inference_flag;
- }else{
- int list, mx, my, i;
- //FIXME we should set ref_idx_l? to 0 if we use that later ...
- if(IS_16X16(mb_type)){
- for (list = 0; list < sl->list_count; list++) {
- unsigned int val;
- if(IS_DIR(mb_type, 0, list)){
- unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
- if (rc == 1) {
- val= 0;
- } else if (rc == 2) {
- val= get_bits1(&sl->gb)^1;
- }else{
- val= get_ue_golomb_31(&sl->gb);
- if (val >= rc) {
- av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
- return -1;
- }
- }
- fill_rectangle(&sl->ref_cache[list][ scan8[0] ], 4, 4, 8, val, 1);
- }
- }
- for (list = 0; list < sl->list_count; list++) {
- if(IS_DIR(mb_type, 0, list)){
- pred_motion(h, sl, 0, 4, list, sl->ref_cache[list][ scan8[0] ], &mx, &my);
- mx += get_se_golomb(&sl->gb);
- my += get_se_golomb(&sl->gb);
- ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
-
- fill_rectangle(sl->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
- }
- }
- }
- else if(IS_16X8(mb_type)){
- for (list = 0; list < sl->list_count; list++) {
- for(i=0; i<2; i++){
- unsigned int val;
- if(IS_DIR(mb_type, i, list)){
- unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
- if (rc == 1) {
- val= 0;
- } else if (rc == 2) {
- val= get_bits1(&sl->gb)^1;
- }else{
- val= get_ue_golomb_31(&sl->gb);
- if (val >= rc) {
- av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
- return -1;
- }
- }
- }else
- val= LIST_NOT_USED&0xFF;
- fill_rectangle(&sl->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 1);
- }
- }
- for (list = 0; list < sl->list_count; list++) {
- for(i=0; i<2; i++){
- unsigned int val;
- if(IS_DIR(mb_type, i, list)){
- pred_16x8_motion(h, sl, 8*i, list, sl->ref_cache[list][scan8[0] + 16*i], &mx, &my);
- mx += get_se_golomb(&sl->gb);
- my += get_se_golomb(&sl->gb);
- ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
-
- val= pack16to32(mx,my);
- }else
- val=0;
- fill_rectangle(sl->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 4);
- }
- }
- }else{
- av_assert2(IS_8X16(mb_type));
- for (list = 0; list < sl->list_count; list++) {
- for(i=0; i<2; i++){
- unsigned int val;
- if(IS_DIR(mb_type, i, list)){ //FIXME optimize
- unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
- if (rc == 1) {
- val= 0;
- } else if (rc == 2) {
- val= get_bits1(&sl->gb)^1;
- }else{
- val= get_ue_golomb_31(&sl->gb);
- if (val >= rc) {
- av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
- return -1;
- }
- }
- }else
- val= LIST_NOT_USED&0xFF;
- fill_rectangle(&sl->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 1);
- }
- }
- for (list = 0; list < sl->list_count; list++) {
- for(i=0; i<2; i++){
- unsigned int val;
- if(IS_DIR(mb_type, i, list)){
- pred_8x16_motion(h, sl, i*4, list, sl->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);
- mx += get_se_golomb(&sl->gb);
- my += get_se_golomb(&sl->gb);
- ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
-
- val= pack16to32(mx,my);
- }else
- val=0;
- fill_rectangle(sl->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 4);
- }
- }
- }
- }
-
- if(IS_INTER(mb_type))
- write_back_motion(h, sl, mb_type);
-
- if(!IS_INTRA16x16(mb_type)){
- cbp= get_ue_golomb(&sl->gb);
-
- if(decode_chroma){
- if(cbp > 47){
- av_log(h->avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, sl->mb_x, sl->mb_y);
- return -1;
- }
- if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp[cbp];
- else cbp= golomb_to_inter_cbp [cbp];
- }else{
- if(cbp > 15){
- av_log(h->avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, sl->mb_x, sl->mb_y);
- return -1;
- }
- if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp];
- else cbp= golomb_to_inter_cbp_gray[cbp];
- }
- } else {
- if (!decode_chroma && cbp>15) {
- av_log(h->avctx, AV_LOG_ERROR, "gray chroma\n");
- return AVERROR_INVALIDDATA;
- }
- }
-
- if(dct8x8_allowed && (cbp&15) && !IS_INTRA(mb_type)){
- mb_type |= MB_TYPE_8x8DCT*get_bits1(&sl->gb);
- }
- sl->cbp=
- h->cbp_table[mb_xy]= cbp;
- h->cur_pic.mb_type[mb_xy] = mb_type;
-
- if(cbp || IS_INTRA16x16(mb_type)){
- int i4x4, i8x8, chroma_idx;
- int dquant;
- int ret;
- GetBitContext *gb = &sl->gb;
- const uint8_t *scan, *scan8x8;
- const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
-
- if(IS_INTERLACED(mb_type)){
- scan8x8 = sl->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;
- scan = sl->qscale ? h->field_scan : h->field_scan_q0;
- }else{
- scan8x8 = sl->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0;
- scan = sl->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
- }
-
- dquant= get_se_golomb(&sl->gb);
-
- sl->qscale += dquant;
-
- if (((unsigned)sl->qscale) > max_qp){
- if (sl->qscale < 0) sl->qscale += max_qp + 1;
- else sl->qscale -= max_qp+1;
- if (((unsigned)sl->qscale) > max_qp){
- av_log(h->avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, sl->mb_x, sl->mb_y);
- return -1;
- }
- }
-
- sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale);
- sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale);
-
- if ((ret = decode_luma_residual(h, sl, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 0)) < 0 ) {
- return -1;
- }
- h->cbp_table[mb_xy] |= ret << 12;
- if (CHROMA444(h)) {
- if (decode_luma_residual(h, sl, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 1) < 0 ) {
- return -1;
- }
- if (decode_luma_residual(h, sl, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 2) < 0 ) {
- return -1;
- }
- } else {
- const int num_c8x8 = h->sps.chroma_format_idc;
-
- if(cbp&0x30){
- for(chroma_idx=0; chroma_idx<2; chroma_idx++)
- if (decode_residual(h, sl, gb, sl->mb + ((256 + 16*16*chroma_idx) << pixel_shift),
- CHROMA_DC_BLOCK_INDEX+chroma_idx,
- CHROMA422(h) ? chroma422_dc_scan : chroma_dc_scan,
- NULL, 4*num_c8x8) < 0) {
- return -1;
- }
- }
-
- if(cbp&0x20){
- for(chroma_idx=0; chroma_idx<2; chroma_idx++){
- const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][sl->chroma_qp[chroma_idx]];
- int16_t *mb = sl->mb + (16*(16 + 16*chroma_idx) << pixel_shift);
- for (i8x8 = 0; i8x8<num_c8x8; i8x8++) {
- for (i4x4 = 0; i4x4 < 4; i4x4++) {
- const int index = 16 + 16*chroma_idx + 8*i8x8 + i4x4;
- if (decode_residual(h, sl, gb, mb, index, scan + 1, qmul, 15) < 0)
- return -1;
- mb += 16 << pixel_shift;
- }
- }
- }
- }else{
- fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
- fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
- }
- }
- }else{
- fill_rectangle(&sl->non_zero_count_cache[scan8[ 0]], 4, 4, 8, 0, 1);
- fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
- fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
- }
- h->cur_pic.qscale_table[mb_xy] = sl->qscale;
- write_back_non_zero_count(h, sl);
-
- return 0;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/h264_direct.c b/ffmpeg-2-8-11/libavcodec/h264_direct.c
deleted file mode 100644
index 5756a7b..0000000
--- a/ffmpeg-2-8-11/libavcodec/h264_direct.c
+++ /dev/null
@@ -1,709 +0,0 @@
-/*
- * H.26L/H.264/AVC/JVT/14496-10/... direct mb/block decoding
- * Copyright (c) 2003 Michael Niedermayer <michaelni at gmx.at>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * H.264 / AVC / MPEG4 part10 direct mb/block decoding.
- * @author Michael Niedermayer <michaelni at gmx.at>
- */
-
-#include "internal.h"
-#include "avcodec.h"
-#include "h264.h"
-#include "mpegutils.h"
-#include "rectangle.h"
-#include "thread.h"
-
-#include <assert.h>
-
-static int get_scale_factor(H264SliceContext *sl,
- int poc, int poc1, int i)
-{
- int poc0 = sl->ref_list[0][i].poc;
- int td = av_clip_int8(poc1 - poc0);
- if (td == 0 || sl->ref_list[0][i].parent->long_ref) {
- return 256;
- } else {
- int tb = av_clip_int8(poc - poc0);
- int tx = (16384 + (FFABS(td) >> 1)) / td;
- return av_clip_intp2((tb * tx + 32) >> 6, 10);
- }
-}
-
-void ff_h264_direct_dist_scale_factor(const H264Context *const h,
- H264SliceContext *sl)
-{
- const int poc = FIELD_PICTURE(h) ? h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD]
- : h->cur_pic_ptr->poc;
- const int poc1 = sl->ref_list[1][0].poc;
- int i, field;
-
- if (FRAME_MBAFF(h))
- for (field = 0; field < 2; field++) {
- const int poc = h->cur_pic_ptr->field_poc[field];
- const int poc1 = sl->ref_list[1][0].parent->field_poc[field];
- for (i = 0; i < 2 * sl->ref_count[0]; i++)
- sl->dist_scale_factor_field[field][i ^ field] =
- get_scale_factor(sl, poc, poc1, i + 16);
- }
-
- for (i = 0; i < sl->ref_count[0]; i++)
- sl->dist_scale_factor[i] = get_scale_factor(sl, poc, poc1, i);
-}
-
-static void fill_colmap(const H264Context *h, H264SliceContext *sl,
- int map[2][16 + 32], int list,
- int field, int colfield, int mbafi)
-{
- H264Picture *const ref1 = sl->ref_list[1][0].parent;
- int j, old_ref, rfield;
- int start = mbafi ? 16 : 0;
- int end = mbafi ? 16 + 2 * sl->ref_count[0] : sl->ref_count[0];
- int interl = mbafi || h->picture_structure != PICT_FRAME;
-
- /* bogus; fills in for missing frames */
- memset(map[list], 0, sizeof(map[list]));
-
- for (rfield = 0; rfield < 2; rfield++) {
- for (old_ref = 0; old_ref < ref1->ref_count[colfield][list]; old_ref++) {
- int poc = ref1->ref_poc[colfield][list][old_ref];
-
- if (!interl)
- poc |= 3;
- // FIXME: store all MBAFF references so this is not needed
- else if (interl && (poc & 3) == 3)
- poc = (poc & ~3) + rfield + 1;
-
- for (j = start; j < end; j++) {
- if (4 * sl->ref_list[0][j].parent->frame_num +
- (sl->ref_list[0][j].reference & 3) == poc) {
- int cur_ref = mbafi ? (j - 16) ^ field : j;
- if (ref1->mbaff)
- map[list][2 * old_ref + (rfield ^ field) + 16] = cur_ref;
- if (rfield == field || !interl)
- map[list][old_ref] = cur_ref;
- break;
- }
- }
- }
- }
-}
-
-void ff_h264_direct_ref_list_init(const H264Context *const h, H264SliceContext *sl)
-{
- H264Ref *const ref1 = &sl->ref_list[1][0];
- H264Picture *const cur = h->cur_pic_ptr;
- int list, j, field;
- int sidx = (h->picture_structure & 1) ^ 1;
- int ref1sidx = (ref1->reference & 1) ^ 1;
-
- for (list = 0; list < sl->list_count; list++) {
- cur->ref_count[sidx][list] = sl->ref_count[list];
- for (j = 0; j < sl->ref_count[list]; j++)
- cur->ref_poc[sidx][list][j] = 4 * sl->ref_list[list][j].parent->frame_num +
- (sl->ref_list[list][j].reference & 3);
- }
-
- if (h->picture_structure == PICT_FRAME) {
- memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0]));
- memcpy(cur->ref_poc[1], cur->ref_poc[0], sizeof(cur->ref_poc[0]));
- }
-
- cur->mbaff = FRAME_MBAFF(h);
-
- sl->col_fieldoff = 0;
-
- if (sl->list_count != 2 || !sl->ref_count[1])
- return;
-
- if (h->picture_structure == PICT_FRAME) {
- int cur_poc = h->cur_pic_ptr->poc;
- int *col_poc = sl->ref_list[1][0].parent->field_poc;
- sl->col_parity = (FFABS(col_poc[0] - cur_poc) >=
- FFABS(col_poc[1] - cur_poc));
- ref1sidx =
- sidx = sl->col_parity;
- // FL -> FL & differ parity
- } else if (!(h->picture_structure & sl->ref_list[1][0].reference) &&
- !sl->ref_list[1][0].parent->mbaff) {
- sl->col_fieldoff = 2 * sl->ref_list[1][0].reference - 3;
- }
-
- if (sl->slice_type_nos != AV_PICTURE_TYPE_B || sl->direct_spatial_mv_pred)
- return;
-
- for (list = 0; list < 2; list++) {
- fill_colmap(h, sl, sl->map_col_to_list0, list, sidx, ref1sidx, 0);
- if (FRAME_MBAFF(h))
- for (field = 0; field < 2; field++)
- fill_colmap(h, sl, sl->map_col_to_list0_field[field], list, field,
- field, 1);
- }
-}
-
-static void await_reference_mb_row(const H264Context *const h, H264Ref *ref,
- int mb_y)
-{
- int ref_field = ref->reference - 1;
- int ref_field_picture = ref->parent->field_picture;
- int ref_height = 16 * h->mb_height >> ref_field_picture;
-
- if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_FRAME))
- return;
-
- /* FIXME: It can be safe to access mb stuff
- * even if pixels aren't deblocked yet. */
-
- ff_thread_await_progress(&ref->parent->tf,
- FFMIN(16 * mb_y >> ref_field_picture,
- ref_height - 1),
- ref_field_picture && ref_field);
-}
-
-static void pred_spatial_direct_motion(const H264Context *const h, H264SliceContext *sl,
- int *mb_type)
-{
- int b8_stride = 2;
- int b4_stride = h->b_stride;
- int mb_xy = sl->mb_xy, mb_y = sl->mb_y;
- int mb_type_col[2];
- const int16_t (*l1mv0)[2], (*l1mv1)[2];
- const int8_t *l1ref0, *l1ref1;
- const int is_b8x8 = IS_8X8(*mb_type);
- unsigned int sub_mb_type = MB_TYPE_L0L1;
- int i8, i4;
- int ref[2];
- int mv[2];
- int list;
-
- assert(sl->ref_list[1][0].reference & 3);
-
- await_reference_mb_row(h, &sl->ref_list[1][0],
- sl->mb_y + !!IS_INTERLACED(*mb_type));
-
-#define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16 | MB_TYPE_INTRA4x4 | \
- MB_TYPE_INTRA16x16 | MB_TYPE_INTRA_PCM)
-
- /* ref = min(neighbors) */
- for (list = 0; list < 2; list++) {
- int left_ref = sl->ref_cache[list][scan8[0] - 1];
- int top_ref = sl->ref_cache[list][scan8[0] - 8];
- int refc = sl->ref_cache[list][scan8[0] - 8 + 4];
- const int16_t *C = sl->mv_cache[list][scan8[0] - 8 + 4];
- if (refc == PART_NOT_AVAILABLE) {
- refc = sl->ref_cache[list][scan8[0] - 8 - 1];
- C = sl->mv_cache[list][scan8[0] - 8 - 1];
- }
- ref[list] = FFMIN3((unsigned)left_ref,
- (unsigned)top_ref,
- (unsigned)refc);
- if (ref[list] >= 0) {
- /* This is just pred_motion() but with the cases removed that
- * cannot happen for direct blocks. */
- const int16_t *const A = sl->mv_cache[list][scan8[0] - 1];
- const int16_t *const B = sl->mv_cache[list][scan8[0] - 8];
-
- int match_count = (left_ref == ref[list]) +
- (top_ref == ref[list]) +
- (refc == ref[list]);
-
- if (match_count > 1) { // most common
- mv[list] = pack16to32(mid_pred(A[0], B[0], C[0]),
- mid_pred(A[1], B[1], C[1]));
- } else {
- assert(match_count == 1);
- if (left_ref == ref[list])
- mv[list] = AV_RN32A(A);
- else if (top_ref == ref[list])
- mv[list] = AV_RN32A(B);
- else
- mv[list] = AV_RN32A(C);
- }
- av_assert2(ref[list] < (sl->ref_count[list] << !!FRAME_MBAFF(h)));
- } else {
- int mask = ~(MB_TYPE_L0 << (2 * list));
- mv[list] = 0;
- ref[list] = -1;
- if (!is_b8x8)
- *mb_type &= mask;
- sub_mb_type &= mask;
- }
- }
- if (ref[0] < 0 && ref[1] < 0) {
- ref[0] = ref[1] = 0;
- if (!is_b8x8)
- *mb_type |= MB_TYPE_L0L1;
- sub_mb_type |= MB_TYPE_L0L1;
- }
-
- if (!(is_b8x8 | mv[0] | mv[1])) {
- fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1);
- fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1);
- fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4);
- fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, 0, 4);
- *mb_type = (*mb_type & ~(MB_TYPE_8x8 | MB_TYPE_16x8 | MB_TYPE_8x16 |
- MB_TYPE_P1L0 | MB_TYPE_P1L1)) |
- MB_TYPE_16x16 | MB_TYPE_DIRECT2;
- return;
- }
-
- if (IS_INTERLACED(sl->ref_list[1][0].parent->mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
- if (!IS_INTERLACED(*mb_type)) { // AFR/FR -> AFL/FL
- mb_y = (sl->mb_y & ~1) + sl->col_parity;
- mb_xy = sl->mb_x +
- ((sl->mb_y & ~1) + sl->col_parity) * h->mb_stride;
- b8_stride = 0;
- } else {
- mb_y += sl->col_fieldoff;
- mb_xy += h->mb_stride * sl->col_fieldoff; // non-zero for FL -> FL & differ parity
- }
- goto single_col;
- } else { // AFL/AFR/FR/FL -> AFR/FR
- if (IS_INTERLACED(*mb_type)) { // AFL /FL -> AFR/FR
- mb_y = sl->mb_y & ~1;
- mb_xy = (sl->mb_y & ~1) * h->mb_stride + sl->mb_x;
- mb_type_col[0] = sl->ref_list[1][0].parent->mb_type[mb_xy];
- mb_type_col[1] = sl->ref_list[1][0].parent->mb_type[mb_xy + h->mb_stride];
- b8_stride = 2 + 4 * h->mb_stride;
- b4_stride *= 6;
- if (IS_INTERLACED(mb_type_col[0]) !=
- IS_INTERLACED(mb_type_col[1])) {
- mb_type_col[0] &= ~MB_TYPE_INTERLACED;
- mb_type_col[1] &= ~MB_TYPE_INTERLACED;
- }
-
- sub_mb_type |= MB_TYPE_16x16 | MB_TYPE_DIRECT2; /* B_SUB_8x8 */
- if ((mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) &&
- (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) &&
- !is_b8x8) {
- *mb_type |= MB_TYPE_16x8 | MB_TYPE_DIRECT2; /* B_16x8 */
- } else {
- *mb_type |= MB_TYPE_8x8;
- }
- } else { // AFR/FR -> AFR/FR
-single_col:
- mb_type_col[0] =
- mb_type_col[1] = sl->ref_list[1][0].parent->mb_type[mb_xy];
-
- sub_mb_type |= MB_TYPE_16x16 | MB_TYPE_DIRECT2; /* B_SUB_8x8 */
- if (!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)) {
- *mb_type |= MB_TYPE_16x16 | MB_TYPE_DIRECT2; /* B_16x16 */
- } else if (!is_b8x8 &&
- (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16))) {
- *mb_type |= MB_TYPE_DIRECT2 |
- (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16));
- } else {
- if (!h->sps.direct_8x8_inference_flag) {
- /* FIXME: Save sub mb types from previous frames (or derive
- * from MVs) so we know exactly what block size to use. */
- sub_mb_type += (MB_TYPE_8x8 - MB_TYPE_16x16); /* B_SUB_4x4 */
- }
- *mb_type |= MB_TYPE_8x8;
- }
- }
- }
-
- await_reference_mb_row(h, &sl->ref_list[1][0], mb_y);
-
- l1mv0 = (void*)&sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]];
- l1mv1 = (void*)&sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]];
- l1ref0 = &sl->ref_list[1][0].parent->ref_index[0][4 * mb_xy];
- l1ref1 = &sl->ref_list[1][0].parent->ref_index[1][4 * mb_xy];
- if (!b8_stride) {
- if (sl->mb_y & 1) {
- l1ref0 += 2;
- l1ref1 += 2;
- l1mv0 += 2 * b4_stride;
- l1mv1 += 2 * b4_stride;
- }
- }
-
- if (IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])) {
- int n = 0;
- for (i8 = 0; i8 < 4; i8++) {
- int x8 = i8 & 1;
- int y8 = i8 >> 1;
- int xy8 = x8 + y8 * b8_stride;
- int xy4 = x8 * 3 + y8 * b4_stride;
- int a, b;
-
- if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
- continue;
- sl->sub_mb_type[i8] = sub_mb_type;
-
- fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
- (uint8_t)ref[0], 1);
- fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8,
- (uint8_t)ref[1], 1);
- if (!IS_INTRA(mb_type_col[y8]) && !sl->ref_list[1][0].parent->long_ref &&
- ((l1ref0[xy8] == 0 &&
- FFABS(l1mv0[xy4][0]) <= 1 &&
- FFABS(l1mv0[xy4][1]) <= 1) ||
- (l1ref0[xy8] < 0 &&
- l1ref1[xy8] == 0 &&
- FFABS(l1mv1[xy4][0]) <= 1 &&
- FFABS(l1mv1[xy4][1]) <= 1))) {
- a =
- b = 0;
- if (ref[0] > 0)
- a = mv[0];
- if (ref[1] > 0)
- b = mv[1];
- n++;
- } else {
- a = mv[0];
- b = mv[1];
- }
- fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, a, 4);
- fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, b, 4);
- }
- if (!is_b8x8 && !(n & 3))
- *mb_type = (*mb_type & ~(MB_TYPE_8x8 | MB_TYPE_16x8 | MB_TYPE_8x16 |
- MB_TYPE_P1L0 | MB_TYPE_P1L1)) |
- MB_TYPE_16x16 | MB_TYPE_DIRECT2;
- } else if (IS_16X16(*mb_type)) {
- int a, b;
-
- fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1);
- fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1);
- if (!IS_INTRA(mb_type_col[0]) && !sl->ref_list[1][0].parent->long_ref &&
- ((l1ref0[0] == 0 &&
- FFABS(l1mv0[0][0]) <= 1 &&
- FFABS(l1mv0[0][1]) <= 1) ||
- (l1ref0[0] < 0 && !l1ref1[0] &&
- FFABS(l1mv1[0][0]) <= 1 &&
- FFABS(l1mv1[0][1]) <= 1 &&
- h->x264_build > 33U))) {
- a = b = 0;
- if (ref[0] > 0)
- a = mv[0];
- if (ref[1] > 0)
- b = mv[1];
- } else {
- a = mv[0];
- b = mv[1];
- }
- fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, a, 4);
- fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, b, 4);
- } else {
- int n = 0;
- for (i8 = 0; i8 < 4; i8++) {
- const int x8 = i8 & 1;
- const int y8 = i8 >> 1;
-
- if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
- continue;
- sl->sub_mb_type[i8] = sub_mb_type;
-
- fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, mv[0], 4);
- fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, mv[1], 4);
- fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
- (uint8_t)ref[0], 1);
- fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8,
- (uint8_t)ref[1], 1);
-
- assert(b8_stride == 2);
- /* col_zero_flag */
- if (!IS_INTRA(mb_type_col[0]) && !sl->ref_list[1][0].parent->long_ref &&
- (l1ref0[i8] == 0 ||
- (l1ref0[i8] < 0 &&
- l1ref1[i8] == 0 &&
- h->x264_build > 33U))) {
- const int16_t (*l1mv)[2] = l1ref0[i8] == 0 ? l1mv0 : l1mv1;
- if (IS_SUB_8X8(sub_mb_type)) {
- const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride];
- if (FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1) {
- if (ref[0] == 0)
- fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2,
- 8, 0, 4);
- if (ref[1] == 0)
- fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2,
- 8, 0, 4);
- n += 4;
- }
- } else {
- int m = 0;
- for (i4 = 0; i4 < 4; i4++) {
- const int16_t *mv_col = l1mv[x8 * 2 + (i4 & 1) +
- (y8 * 2 + (i4 >> 1)) * b4_stride];
- if (FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1) {
- if (ref[0] == 0)
- AV_ZERO32(sl->mv_cache[0][scan8[i8 * 4 + i4]]);
- if (ref[1] == 0)
- AV_ZERO32(sl->mv_cache[1][scan8[i8 * 4 + i4]]);
- m++;
- }
- }
- if (!(m & 3))
- sl->sub_mb_type[i8] += MB_TYPE_16x16 - MB_TYPE_8x8;
- n += m;
- }
- }
- }
- if (!is_b8x8 && !(n & 15))
- *mb_type = (*mb_type & ~(MB_TYPE_8x8 | MB_TYPE_16x8 | MB_TYPE_8x16 |
- MB_TYPE_P1L0 | MB_TYPE_P1L1)) |
- MB_TYPE_16x16 | MB_TYPE_DIRECT2;
- }
-}
-
-static void pred_temp_direct_motion(const H264Context *const h, H264SliceContext *sl,
- int *mb_type)
-{
- int b8_stride = 2;
- int b4_stride = h->b_stride;
- int mb_xy = sl->mb_xy, mb_y = sl->mb_y;
- int mb_type_col[2];
- const int16_t (*l1mv0)[2], (*l1mv1)[2];
- const int8_t *l1ref0, *l1ref1;
- const int is_b8x8 = IS_8X8(*mb_type);
- unsigned int sub_mb_type;
- int i8, i4;
-
- assert(sl->ref_list[1][0].reference & 3);
-
- await_reference_mb_row(h, &sl->ref_list[1][0],
- sl->mb_y + !!IS_INTERLACED(*mb_type));
-
- if (IS_INTERLACED(sl->ref_list[1][0].parent->mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
- if (!IS_INTERLACED(*mb_type)) { // AFR/FR -> AFL/FL
- mb_y = (sl->mb_y & ~1) + sl->col_parity;
- mb_xy = sl->mb_x +
- ((sl->mb_y & ~1) + sl->col_parity) * h->mb_stride;
- b8_stride = 0;
- } else {
- mb_y += sl->col_fieldoff;
- mb_xy += h->mb_stride * sl->col_fieldoff; // non-zero for FL -> FL & differ parity
- }
- goto single_col;
- } else { // AFL/AFR/FR/FL -> AFR/FR
- if (IS_INTERLACED(*mb_type)) { // AFL /FL -> AFR/FR
- mb_y = sl->mb_y & ~1;
- mb_xy = sl->mb_x + (sl->mb_y & ~1) * h->mb_stride;
- mb_type_col[0] = sl->ref_list[1][0].parent->mb_type[mb_xy];
- mb_type_col[1] = sl->ref_list[1][0].parent->mb_type[mb_xy + h->mb_stride];
- b8_stride = 2 + 4 * h->mb_stride;
- b4_stride *= 6;
- if (IS_INTERLACED(mb_type_col[0]) !=
- IS_INTERLACED(mb_type_col[1])) {
- mb_type_col[0] &= ~MB_TYPE_INTERLACED;
- mb_type_col[1] &= ~MB_TYPE_INTERLACED;
- }
-
- sub_mb_type = MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
- MB_TYPE_DIRECT2; /* B_SUB_8x8 */
-
- if ((mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) &&
- (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) &&
- !is_b8x8) {
- *mb_type |= MB_TYPE_16x8 | MB_TYPE_L0L1 |
- MB_TYPE_DIRECT2; /* B_16x8 */
- } else {
- *mb_type |= MB_TYPE_8x8 | MB_TYPE_L0L1;
- }
- } else { // AFR/FR -> AFR/FR
-single_col:
- mb_type_col[0] =
- mb_type_col[1] = sl->ref_list[1][0].parent->mb_type[mb_xy];
-
- sub_mb_type = MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
- MB_TYPE_DIRECT2; /* B_SUB_8x8 */
- if (!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)) {
- *mb_type |= MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
- MB_TYPE_DIRECT2; /* B_16x16 */
- } else if (!is_b8x8 &&
- (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16))) {
- *mb_type |= MB_TYPE_L0L1 | MB_TYPE_DIRECT2 |
- (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16));
- } else {
- if (!h->sps.direct_8x8_inference_flag) {
- /* FIXME: save sub mb types from previous frames (or derive
- * from MVs) so we know exactly what block size to use */
- sub_mb_type = MB_TYPE_8x8 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
- MB_TYPE_DIRECT2; /* B_SUB_4x4 */
- }
- *mb_type |= MB_TYPE_8x8 | MB_TYPE_L0L1;
- }
- }
- }
-
- await_reference_mb_row(h, &sl->ref_list[1][0], mb_y);
-
- l1mv0 = (void*)&sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]];
- l1mv1 = (void*)&sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]];
- l1ref0 = &sl->ref_list[1][0].parent->ref_index[0][4 * mb_xy];
- l1ref1 = &sl->ref_list[1][0].parent->ref_index[1][4 * mb_xy];
- if (!b8_stride) {
- if (sl->mb_y & 1) {
- l1ref0 += 2;
- l1ref1 += 2;
- l1mv0 += 2 * b4_stride;
- l1mv1 += 2 * b4_stride;
- }
- }
-
- {
- const int *map_col_to_list0[2] = { sl->map_col_to_list0[0],
- sl->map_col_to_list0[1] };
- const int *dist_scale_factor = sl->dist_scale_factor;
- int ref_offset;
-
- if (FRAME_MBAFF(h) && IS_INTERLACED(*mb_type)) {
- map_col_to_list0[0] = sl->map_col_to_list0_field[sl->mb_y & 1][0];
- map_col_to_list0[1] = sl->map_col_to_list0_field[sl->mb_y & 1][1];
- dist_scale_factor = sl->dist_scale_factor_field[sl->mb_y & 1];
- }
- ref_offset = (sl->ref_list[1][0].parent->mbaff << 4) & (mb_type_col[0] >> 3);
-
- if (IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])) {
- int y_shift = 2 * !IS_INTERLACED(*mb_type);
- assert(h->sps.direct_8x8_inference_flag);
-
- for (i8 = 0; i8 < 4; i8++) {
- const int x8 = i8 & 1;
- const int y8 = i8 >> 1;
- int ref0, scale;
- const int16_t (*l1mv)[2] = l1mv0;
-
- if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
- continue;
- sl->sub_mb_type[i8] = sub_mb_type;
-
- fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 1);
- if (IS_INTRA(mb_type_col[y8])) {
- fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 1);
- fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4);
- fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4);
- continue;
- }
-
- ref0 = l1ref0[x8 + y8 * b8_stride];
- if (ref0 >= 0)
- ref0 = map_col_to_list0[0][ref0 + ref_offset];
- else {
- ref0 = map_col_to_list0[1][l1ref1[x8 + y8 * b8_stride] +
- ref_offset];
- l1mv = l1mv1;
- }
- scale = dist_scale_factor[ref0];
- fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
- ref0, 1);
-
- {
- const int16_t *mv_col = l1mv[x8 * 3 + y8 * b4_stride];
- int my_col = (mv_col[1] << y_shift) / 2;
- int mx = (scale * mv_col[0] + 128) >> 8;
- int my = (scale * my_col + 128) >> 8;
- fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8,
- pack16to32(mx, my), 4);
- fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8,
- pack16to32(mx - mv_col[0], my - my_col), 4);
- }
- }
- return;
- }
-
- /* one-to-one mv scaling */
-
- if (IS_16X16(*mb_type)) {
- int ref, mv0, mv1;
-
- fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1);
- if (IS_INTRA(mb_type_col[0])) {
- ref = mv0 = mv1 = 0;
- } else {
- const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0] + ref_offset]
- : map_col_to_list0[1][l1ref1[0] + ref_offset];
- const int scale = dist_scale_factor[ref0];
- const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0];
- int mv_l0[2];
- mv_l0[0] = (scale * mv_col[0] + 128) >> 8;
- mv_l0[1] = (scale * mv_col[1] + 128) >> 8;
- ref = ref0;
- mv0 = pack16to32(mv_l0[0], mv_l0[1]);
- mv1 = pack16to32(mv_l0[0] - mv_col[0], mv_l0[1] - mv_col[1]);
- }
- fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
- fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, mv0, 4);
- fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, mv1, 4);
- } else {
- for (i8 = 0; i8 < 4; i8++) {
- const int x8 = i8 & 1;
- const int y8 = i8 >> 1;
- int ref0, scale;
- const int16_t (*l1mv)[2] = l1mv0;
-
- if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
- continue;
- sl->sub_mb_type[i8] = sub_mb_type;
- fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 1);
- if (IS_INTRA(mb_type_col[0])) {
- fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 1);
- fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4);
- fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4);
- continue;
- }
-
- assert(b8_stride == 2);
- ref0 = l1ref0[i8];
- if (ref0 >= 0)
- ref0 = map_col_to_list0[0][ref0 + ref_offset];
- else {
- ref0 = map_col_to_list0[1][l1ref1[i8] + ref_offset];
- l1mv = l1mv1;
- }
- scale = dist_scale_factor[ref0];
-
- fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
- ref0, 1);
- if (IS_SUB_8X8(sub_mb_type)) {
- const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride];
- int mx = (scale * mv_col[0] + 128) >> 8;
- int my = (scale * mv_col[1] + 128) >> 8;
- fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8,
- pack16to32(mx, my), 4);
- fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8,
- pack16to32(mx - mv_col[0], my - mv_col[1]), 4);
- } else {
- for (i4 = 0; i4 < 4; i4++) {
- const int16_t *mv_col = l1mv[x8 * 2 + (i4 & 1) +
- (y8 * 2 + (i4 >> 1)) * b4_stride];
- int16_t *mv_l0 = sl->mv_cache[0][scan8[i8 * 4 + i4]];
- mv_l0[0] = (scale * mv_col[0] + 128) >> 8;
- mv_l0[1] = (scale * mv_col[1] + 128) >> 8;
- AV_WN32A(sl->mv_cache[1][scan8[i8 * 4 + i4]],
- pack16to32(mv_l0[0] - mv_col[0],
- mv_l0[1] - mv_col[1]));
- }
- }
- }
- }
- }
-}
-
-void ff_h264_pred_direct_motion(const H264Context *const h, H264SliceContext *sl,
- int *mb_type)
-{
- if (sl->direct_spatial_mv_pred)
- pred_spatial_direct_motion(h, sl, mb_type);
- else
- pred_temp_direct_motion(h, sl, mb_type);
-}
diff --git a/ffmpeg-2-8-11/libavcodec/h264_mvpred.h b/ffmpeg-2-8-11/libavcodec/h264_mvpred.h
deleted file mode 100644
index 763746c..0000000
--- a/ffmpeg-2-8-11/libavcodec/h264_mvpred.h
+++ /dev/null
@@ -1,836 +0,0 @@
-/*
- * H.26L/H.264/AVC/JVT/14496-10/... motion vector predicion
- * Copyright (c) 2003 Michael Niedermayer <michaelni at gmx.at>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * H.264 / AVC / MPEG4 part10 motion vector predicion.
- * @author Michael Niedermayer <michaelni at gmx.at>
- */
-
-#ifndef AVCODEC_H264_MVPRED_H
-#define AVCODEC_H264_MVPRED_H
-
-#include "internal.h"
-#include "avcodec.h"
-#include "h264.h"
-#include "mpegutils.h"
-#include "libavutil/avassert.h"
-
-
-static av_always_inline int fetch_diagonal_mv(const H264Context *h, H264SliceContext *sl,
- const int16_t **C,
- int i, int list, int part_width)
-{
- const int topright_ref = sl->ref_cache[list][i - 8 + part_width];
-
- /* there is no consistent mapping of mvs to neighboring locations that will
- * make mbaff happy, so we can't move all this logic to fill_caches */
- if (FRAME_MBAFF(h)) {
-#define SET_DIAG_MV(MV_OP, REF_OP, XY, Y4) \
- const int xy = XY, y4 = Y4; \
- const int mb_type = mb_types[xy + (y4 >> 2) * h->mb_stride]; \
- if (!USES_LIST(mb_type, list)) \
- return LIST_NOT_USED; \
- mv = h->cur_pic_ptr->motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \
- sl->mv_cache[list][scan8[0] - 2][0] = mv[0]; \
- sl->mv_cache[list][scan8[0] - 2][1] = mv[1] MV_OP; \
- return h->cur_pic_ptr->ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP;
-
- if (topright_ref == PART_NOT_AVAILABLE
- && i >= scan8[0] + 8 && (i & 7) == 4
- && sl->ref_cache[list][scan8[0] - 1] != PART_NOT_AVAILABLE) {
- const uint32_t *mb_types = h->cur_pic_ptr->mb_type;
- const int16_t *mv;
- AV_ZERO32(sl->mv_cache[list][scan8[0] - 2]);
- *C = sl->mv_cache[list][scan8[0] - 2];
-
- if (!MB_FIELD(sl) && IS_INTERLACED(sl->left_type[0])) {
- SET_DIAG_MV(* 2, >> 1, sl->left_mb_xy[0] + h->mb_stride,
- (sl->mb_y & 1) * 2 + (i >> 5));
- }
- if (MB_FIELD(sl) && !IS_INTERLACED(sl->left_type[0])) {
- // left shift will turn LIST_NOT_USED into PART_NOT_AVAILABLE, but that's OK.
- SET_DIAG_MV(/ 2, << 1, sl->left_mb_xy[i >= 36], ((i >> 2)) & 3);
- }
- }
-#undef SET_DIAG_MV
- }
-
- if (topright_ref != PART_NOT_AVAILABLE) {
- *C = sl->mv_cache[list][i - 8 + part_width];
- return topright_ref;
- } else {
- ff_tlog(h->avctx, "topright MV not available\n");
-
- *C = sl->mv_cache[list][i - 8 - 1];
- return sl->ref_cache[list][i - 8 - 1];
- }
-}
-
-/**
- * Get the predicted MV.
- * @param n the block index
- * @param part_width the width of the partition (4, 8,16) -> (1, 2, 4)
- * @param mx the x component of the predicted motion vector
- * @param my the y component of the predicted motion vector
- */
-static av_always_inline void pred_motion(const H264Context *const h,
- H264SliceContext *sl,
- int n,
- int part_width, int list, int ref,
- int *const mx, int *const my)
-{
- const int index8 = scan8[n];
- const int top_ref = sl->ref_cache[list][index8 - 8];
- const int left_ref = sl->ref_cache[list][index8 - 1];
- const int16_t *const A = sl->mv_cache[list][index8 - 1];
- const int16_t *const B = sl->mv_cache[list][index8 - 8];
- const int16_t *C;
- int diagonal_ref, match_count;
-
- av_assert2(part_width == 1 || part_width == 2 || part_width == 4);
-
-/* mv_cache
- * B . . A T T T T
- * U . . L . . , .
- * U . . L . . . .
- * U . . L . . , .
- * . . . L . . . .
- */
-
- diagonal_ref = fetch_diagonal_mv(h, sl, &C, index8, list, part_width);
- match_count = (diagonal_ref == ref) + (top_ref == ref) + (left_ref == ref);
- ff_tlog(h->avctx, "pred_motion match_count=%d\n", match_count);
- if (match_count > 1) { //most common
- *mx = mid_pred(A[0], B[0], C[0]);
- *my = mid_pred(A[1], B[1], C[1]);
- } else if (match_count == 1) {
- if (left_ref == ref) {
- *mx = A[0];
- *my = A[1];
- } else if (top_ref == ref) {
- *mx = B[0];
- *my = B[1];
- } else {
- *mx = C[0];
- *my = C[1];
- }
- } else {
- if (top_ref == PART_NOT_AVAILABLE &&
- diagonal_ref == PART_NOT_AVAILABLE &&
- left_ref != PART_NOT_AVAILABLE) {
- *mx = A[0];
- *my = A[1];
- } else {
- *mx = mid_pred(A[0], B[0], C[0]);
- *my = mid_pred(A[1], B[1], C[1]);
- }
- }
-
- ff_tlog(h->avctx,
- "pred_motion (%2d %2d %2d) (%2d %2d %2d) (%2d %2d %2d) -> (%2d %2d %2d) at %2d %2d %d list %d\n",
- top_ref, B[0], B[1], diagonal_ref, C[0], C[1], left_ref,
- A[0], A[1], ref, *mx, *my, sl->mb_x, sl->mb_y, n, list);
-}
-
-/**
- * Get the directionally predicted 16x8 MV.
- * @param n the block index
- * @param mx the x component of the predicted motion vector
- * @param my the y component of the predicted motion vector
- */
-static av_always_inline void pred_16x8_motion(const H264Context *const h,
- H264SliceContext *sl,
- int n, int list, int ref,
- int *const mx, int *const my)
-{
- if (n == 0) {
- const int top_ref = sl->ref_cache[list][scan8[0] - 8];
- const int16_t *const B = sl->mv_cache[list][scan8[0] - 8];
-
- ff_tlog(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
- top_ref, B[0], B[1], sl->mb_x, sl->mb_y, n, list);
-
- if (top_ref == ref) {
- *mx = B[0];
- *my = B[1];
- return;
- }
- } else {
- const int left_ref = sl->ref_cache[list][scan8[8] - 1];
- const int16_t *const A = sl->mv_cache[list][scan8[8] - 1];
-
- ff_tlog(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
- left_ref, A[0], A[1], sl->mb_x, sl->mb_y, n, list);
-
- if (left_ref == ref) {
- *mx = A[0];
- *my = A[1];
- return;
- }
- }
-
- //RARE
- pred_motion(h, sl, n, 4, list, ref, mx, my);
-}
-
-/**
- * Get the directionally predicted 8x16 MV.
- * @param n the block index
- * @param mx the x component of the predicted motion vector
- * @param my the y component of the predicted motion vector
- */
-static av_always_inline void pred_8x16_motion(const H264Context *const h,
- H264SliceContext *sl,
- int n, int list, int ref,
- int *const mx, int *const my)
-{
- if (n == 0) {
- const int left_ref = sl->ref_cache[list][scan8[0] - 1];
- const int16_t *const A = sl->mv_cache[list][scan8[0] - 1];
-
- ff_tlog(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
- left_ref, A[0], A[1], sl->mb_x, sl->mb_y, n, list);
-
- if (left_ref == ref) {
- *mx = A[0];
- *my = A[1];
- return;
- }
- } else {
- const int16_t *C;
- int diagonal_ref;
-
- diagonal_ref = fetch_diagonal_mv(h, sl, &C, scan8[4], list, 2);
-
- ff_tlog(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
- diagonal_ref, C[0], C[1], sl->mb_x, sl->mb_y, n, list);
-
- if (diagonal_ref == ref) {
- *mx = C[0];
- *my = C[1];
- return;
- }
- }
-
- //RARE
- pred_motion(h, sl, n, 2, list, ref, mx, my);
-}
-
-#define FIX_MV_MBAFF(type, refn, mvn, idx) \
- if (FRAME_MBAFF(h)) { \
- if (MB_FIELD(sl)) { \
- if (!IS_INTERLACED(type)) { \
- refn <<= 1; \
- AV_COPY32(mvbuf[idx], mvn); \
- mvbuf[idx][1] /= 2; \
- mvn = mvbuf[idx]; \
- } \
- } else { \
- if (IS_INTERLACED(type)) { \
- refn >>= 1; \
- AV_COPY32(mvbuf[idx], mvn); \
- mvbuf[idx][1] <<= 1; \
- mvn = mvbuf[idx]; \
- } \
- } \
- }
-
-static av_always_inline void pred_pskip_motion(const H264Context *const h,
- H264SliceContext *sl)
-{
- DECLARE_ALIGNED(4, static const int16_t, zeromv)[2] = { 0 };
- DECLARE_ALIGNED(4, int16_t, mvbuf)[3][2];
- int8_t *ref = h->cur_pic.ref_index[0];
- int16_t(*mv)[2] = h->cur_pic.motion_val[0];
- int top_ref, left_ref, diagonal_ref, match_count, mx, my;
- const int16_t *A, *B, *C;
- int b_stride = h->b_stride;
-
- fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1);
-
- /* To avoid doing an entire fill_decode_caches, we inline the relevant
- * parts here.
- * FIXME: this is a partial duplicate of the logic in fill_decode_caches,
- * but it's faster this way. Is there a way to avoid this duplication?
- */
- if (USES_LIST(sl->left_type[LTOP], 0)) {
- left_ref = ref[4 * sl->left_mb_xy[LTOP] + 1 + (sl->left_block[0] & ~1)];
- A = mv[h->mb2b_xy[sl->left_mb_xy[LTOP]] + 3 + b_stride * sl->left_block[0]];
- FIX_MV_MBAFF(sl->left_type[LTOP], left_ref, A, 0);
- if (!(left_ref | AV_RN32A(A)))
- goto zeromv;
- } else if (sl->left_type[LTOP]) {
- left_ref = LIST_NOT_USED;
- A = zeromv;
- } else {
- goto zeromv;
- }
-
- if (USES_LIST(sl->top_type, 0)) {
- top_ref = ref[4 * sl->top_mb_xy + 2];
- B = mv[h->mb2b_xy[sl->top_mb_xy] + 3 * b_stride];
- FIX_MV_MBAFF(sl->top_type, top_ref, B, 1);
- if (!(top_ref | AV_RN32A(B)))
- goto zeromv;
- } else if (sl->top_type) {
- top_ref = LIST_NOT_USED;
- B = zeromv;
- } else {
- goto zeromv;
- }
-
- ff_tlog(h->avctx, "pred_pskip: (%d) (%d) at %2d %2d\n",
- top_ref, left_ref, sl->mb_x, sl->mb_y);
-
- if (USES_LIST(sl->topright_type, 0)) {
- diagonal_ref = ref[4 * sl->topright_mb_xy + 2];
- C = mv[h->mb2b_xy[sl->topright_mb_xy] + 3 * b_stride];
- FIX_MV_MBAFF(sl->topright_type, diagonal_ref, C, 2);
- } else if (sl->topright_type) {
- diagonal_ref = LIST_NOT_USED;
- C = zeromv;
- } else {
- if (USES_LIST(sl->topleft_type, 0)) {
- diagonal_ref = ref[4 * sl->topleft_mb_xy + 1 +
- (sl->topleft_partition & 2)];
- C = mv[h->mb2b_xy[sl->topleft_mb_xy] + 3 + b_stride +
- (sl->topleft_partition & 2 * b_stride)];
- FIX_MV_MBAFF(sl->topleft_type, diagonal_ref, C, 2);
- } else if (sl->topleft_type) {
- diagonal_ref = LIST_NOT_USED;
- C = zeromv;
- } else {
- diagonal_ref = PART_NOT_AVAILABLE;
- C = zeromv;
- }
- }
-
- match_count = !diagonal_ref + !top_ref + !left_ref;
- ff_tlog(h->avctx, "pred_pskip_motion match_count=%d\n", match_count);
- if (match_count > 1) {
- mx = mid_pred(A[0], B[0], C[0]);
- my = mid_pred(A[1], B[1], C[1]);
- } else if (match_count == 1) {
- if (!left_ref) {
- mx = A[0];
- my = A[1];
- } else if (!top_ref) {
- mx = B[0];
- my = B[1];
- } else {
- mx = C[0];
- my = C[1];
- }
- } else {
- mx = mid_pred(A[0], B[0], C[0]);
- my = mid_pred(A[1], B[1], C[1]);
- }
-
- fill_rectangle(sl->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx, my), 4);
- return;
-
-zeromv:
- fill_rectangle(sl->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4);
- return;
-}
-
-static void fill_decode_neighbors(const H264Context *h, H264SliceContext *sl, int mb_type)
-{
- const int mb_xy = sl->mb_xy;
- int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS];
- static const uint8_t left_block_options[4][32] = {
- { 0, 1, 2, 3, 7, 10, 8, 11, 3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4, 3 + 3 * 4, 1 + 4 * 4, 1 + 8 * 4, 1 + 5 * 4, 1 + 9 * 4 },
- { 2, 2, 3, 3, 8, 11, 8, 11, 3 + 2 * 4, 3 + 2 * 4, 3 + 3 * 4, 3 + 3 * 4, 1 + 5 * 4, 1 + 9 * 4, 1 + 5 * 4, 1 + 9 * 4 },
- { 0, 0, 1, 1, 7, 10, 7, 10, 3 + 0 * 4, 3 + 0 * 4, 3 + 1 * 4, 3 + 1 * 4, 1 + 4 * 4, 1 + 8 * 4, 1 + 4 * 4, 1 + 8 * 4 },
- { 0, 2, 0, 2, 7, 10, 7, 10, 3 + 0 * 4, 3 + 2 * 4, 3 + 0 * 4, 3 + 2 * 4, 1 + 4 * 4, 1 + 8 * 4, 1 + 4 * 4, 1 + 8 * 4 }
- };
-
- sl->topleft_partition = -1;
-
- top_xy = mb_xy - (h->mb_stride << MB_FIELD(sl));
-
- /* Wow, what a mess, why didn't they simplify the interlacing & intra
- * stuff, I can't imagine that these complex rules are worth it. */
-
- topleft_xy = top_xy - 1;
- topright_xy = top_xy + 1;
- left_xy[LBOT] = left_xy[LTOP] = mb_xy - 1;
- sl->left_block = left_block_options[0];
- if (FRAME_MBAFF(h)) {
- const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.mb_type[mb_xy - 1]);
- const int curr_mb_field_flag = IS_INTERLACED(mb_type);
- if (sl->mb_y & 1) {
- if (left_mb_field_flag != curr_mb_field_flag) {
- left_xy[LBOT] = left_xy[LTOP] = mb_xy - h->mb_stride - 1;
- if (curr_mb_field_flag) {
- left_xy[LBOT] += h->mb_stride;
- sl->left_block = left_block_options[3];
- } else {
- topleft_xy += h->mb_stride;
- /* take top left mv from the middle of the mb, as opposed
- * to all other modes which use the bottom right partition */
- sl->topleft_partition = 0;
- sl->left_block = left_block_options[1];
- }
- }
- } else {
- if (curr_mb_field_flag) {
- topleft_xy += h->mb_stride & (((h->cur_pic.mb_type[top_xy - 1] >> 7) & 1) - 1);
- topright_xy += h->mb_stride & (((h->cur_pic.mb_type[top_xy + 1] >> 7) & 1) - 1);
- top_xy += h->mb_stride & (((h->cur_pic.mb_type[top_xy] >> 7) & 1) - 1);
- }
- if (left_mb_field_flag != curr_mb_field_flag) {
- if (curr_mb_field_flag) {
- left_xy[LBOT] += h->mb_stride;
- sl->left_block = left_block_options[3];
- } else {
- sl->left_block = left_block_options[2];
- }
- }
- }
- }
-
- sl->topleft_mb_xy = topleft_xy;
- sl->top_mb_xy = top_xy;
- sl->topright_mb_xy = topright_xy;
- sl->left_mb_xy[LTOP] = left_xy[LTOP];
- sl->left_mb_xy[LBOT] = left_xy[LBOT];
- //FIXME do we need all in the context?
-
- sl->topleft_type = h->cur_pic.mb_type[topleft_xy];
- sl->top_type = h->cur_pic.mb_type[top_xy];
- sl->topright_type = h->cur_pic.mb_type[topright_xy];
- sl->left_type[LTOP] = h->cur_pic.mb_type[left_xy[LTOP]];
- sl->left_type[LBOT] = h->cur_pic.mb_type[left_xy[LBOT]];
-
- if (FMO) {
- if (h->slice_table[topleft_xy] != sl->slice_num)
- sl->topleft_type = 0;
- if (h->slice_table[top_xy] != sl->slice_num)
- sl->top_type = 0;
- if (h->slice_table[left_xy[LTOP]] != sl->slice_num)
- sl->left_type[LTOP] = sl->left_type[LBOT] = 0;
- } else {
- if (h->slice_table[topleft_xy] != sl->slice_num) {
- sl->topleft_type = 0;
- if (h->slice_table[top_xy] != sl->slice_num)
- sl->top_type = 0;
- if (h->slice_table[left_xy[LTOP]] != sl->slice_num)
- sl->left_type[LTOP] = sl->left_type[LBOT] = 0;
- }
- }
- if (h->slice_table[topright_xy] != sl->slice_num)
- sl->topright_type = 0;
-}
-
-static void fill_decode_caches(const H264Context *h, H264SliceContext *sl, int mb_type)
-{
- int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS];
- int topleft_type, top_type, topright_type, left_type[LEFT_MBS];
- const uint8_t *left_block = sl->left_block;
- int i;
- uint8_t *nnz;
- uint8_t *nnz_cache;
-
- topleft_xy = sl->topleft_mb_xy;
- top_xy = sl->top_mb_xy;
- topright_xy = sl->topright_mb_xy;
- left_xy[LTOP] = sl->left_mb_xy[LTOP];
- left_xy[LBOT] = sl->left_mb_xy[LBOT];
- topleft_type = sl->topleft_type;
- top_type = sl->top_type;
- topright_type = sl->topright_type;
- left_type[LTOP] = sl->left_type[LTOP];
- left_type[LBOT] = sl->left_type[LBOT];
-
- if (!IS_SKIP(mb_type)) {
- if (IS_INTRA(mb_type)) {
- int type_mask = h->pps.constrained_intra_pred ? IS_INTRA(-1) : -1;
- sl->topleft_samples_available =
- sl->top_samples_available =
- sl->left_samples_available = 0xFFFF;
- sl->topright_samples_available = 0xEEEA;
-
- if (!(top_type & type_mask)) {
- sl->topleft_samples_available = 0xB3FF;
- sl->top_samples_available = 0x33FF;
- sl->topright_samples_available = 0x26EA;
- }
- if (IS_INTERLACED(mb_type) != IS_INTERLACED(left_type[LTOP])) {
- if (IS_INTERLACED(mb_type)) {
- if (!(left_type[LTOP] & type_mask)) {
- sl->topleft_samples_available &= 0xDFFF;
- sl->left_samples_available &= 0x5FFF;
- }
- if (!(left_type[LBOT] & type_mask)) {
- sl->topleft_samples_available &= 0xFF5F;
- sl->left_samples_available &= 0xFF5F;
- }
- } else {
- int left_typei = h->cur_pic.mb_type[left_xy[LTOP] + h->mb_stride];
-
- av_assert2(left_xy[LTOP] == left_xy[LBOT]);
- if (!((left_typei & type_mask) && (left_type[LTOP] & type_mask))) {
- sl->topleft_samples_available &= 0xDF5F;
- sl->left_samples_available &= 0x5F5F;
- }
- }
- } else {
- if (!(left_type[LTOP] & type_mask)) {
- sl->topleft_samples_available &= 0xDF5F;
- sl->left_samples_available &= 0x5F5F;
- }
- }
-
- if (!(topleft_type & type_mask))
- sl->topleft_samples_available &= 0x7FFF;
-
- if (!(topright_type & type_mask))
- sl->topright_samples_available &= 0xFBFF;
-
- if (IS_INTRA4x4(mb_type)) {
- if (IS_INTRA4x4(top_type)) {
- AV_COPY32(sl->intra4x4_pred_mode_cache + 4 + 8 * 0, sl->intra4x4_pred_mode + h->mb2br_xy[top_xy]);
- } else {
- sl->intra4x4_pred_mode_cache[4 + 8 * 0] =
- sl->intra4x4_pred_mode_cache[5 + 8 * 0] =
- sl->intra4x4_pred_mode_cache[6 + 8 * 0] =
- sl->intra4x4_pred_mode_cache[7 + 8 * 0] = 2 - 3 * !(top_type & type_mask);
- }
- for (i = 0; i < 2; i++) {
- if (IS_INTRA4x4(left_type[LEFT(i)])) {
- int8_t *mode = sl->intra4x4_pred_mode + h->mb2br_xy[left_xy[LEFT(i)]];
- sl->intra4x4_pred_mode_cache[3 + 8 * 1 + 2 * 8 * i] = mode[6 - left_block[0 + 2 * i]];
- sl->intra4x4_pred_mode_cache[3 + 8 * 2 + 2 * 8 * i] = mode[6 - left_block[1 + 2 * i]];
- } else {
- sl->intra4x4_pred_mode_cache[3 + 8 * 1 + 2 * 8 * i] =
- sl->intra4x4_pred_mode_cache[3 + 8 * 2 + 2 * 8 * i] = 2 - 3 * !(left_type[LEFT(i)] & type_mask);
- }
- }
- }
- }
-
- /*
- * 0 . T T. T T T T
- * 1 L . .L . . . .
- * 2 L . .L . . . .
- * 3 . T TL . . . .
- * 4 L . .L . . . .
- * 5 L . .. . . . .
- */
- /* FIXME: constraint_intra_pred & partitioning & nnz
- * (let us hope this is just a typo in the spec) */
- nnz_cache = sl->non_zero_count_cache;
- if (top_type) {
- nnz = h->non_zero_count[top_xy];
- AV_COPY32(&nnz_cache[4 + 8 * 0], &nnz[4 * 3]);
- if (!h->chroma_y_shift) {
- AV_COPY32(&nnz_cache[4 + 8 * 5], &nnz[4 * 7]);
- AV_COPY32(&nnz_cache[4 + 8 * 10], &nnz[4 * 11]);
- } else {
- AV_COPY32(&nnz_cache[4 + 8 * 5], &nnz[4 * 5]);
- AV_COPY32(&nnz_cache[4 + 8 * 10], &nnz[4 * 9]);
- }
- } else {
- uint32_t top_empty = CABAC(h) && !IS_INTRA(mb_type) ? 0 : 0x40404040;
- AV_WN32A(&nnz_cache[4 + 8 * 0], top_empty);
- AV_WN32A(&nnz_cache[4 + 8 * 5], top_empty);
- AV_WN32A(&nnz_cache[4 + 8 * 10], top_empty);
- }
-
- for (i = 0; i < 2; i++) {
- if (left_type[LEFT(i)]) {
- nnz = h->non_zero_count[left_xy[LEFT(i)]];
- nnz_cache[3 + 8 * 1 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i]];
- nnz_cache[3 + 8 * 2 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i]];
- if (CHROMA444(h)) {
- nnz_cache[3 + 8 * 6 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] + 4 * 4];
- nnz_cache[3 + 8 * 7 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] + 4 * 4];
- nnz_cache[3 + 8 * 11 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] + 8 * 4];
- nnz_cache[3 + 8 * 12 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] + 8 * 4];
- } else if (CHROMA422(h)) {
- nnz_cache[3 + 8 * 6 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] - 2 + 4 * 4];
- nnz_cache[3 + 8 * 7 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] - 2 + 4 * 4];
- nnz_cache[3 + 8 * 11 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] - 2 + 8 * 4];
- nnz_cache[3 + 8 * 12 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] - 2 + 8 * 4];
- } else {
- nnz_cache[3 + 8 * 6 + 8 * i] = nnz[left_block[8 + 4 + 2 * i]];
- nnz_cache[3 + 8 * 11 + 8 * i] = nnz[left_block[8 + 5 + 2 * i]];
- }
- } else {
- nnz_cache[3 + 8 * 1 + 2 * 8 * i] =
- nnz_cache[3 + 8 * 2 + 2 * 8 * i] =
- nnz_cache[3 + 8 * 6 + 2 * 8 * i] =
- nnz_cache[3 + 8 * 7 + 2 * 8 * i] =
- nnz_cache[3 + 8 * 11 + 2 * 8 * i] =
- nnz_cache[3 + 8 * 12 + 2 * 8 * i] = CABAC(h) && !IS_INTRA(mb_type) ? 0 : 64;
- }
- }
-
- if (CABAC(h)) {
- // top_cbp
- if (top_type)
- sl->top_cbp = h->cbp_table[top_xy];
- else
- sl->top_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F;
- // left_cbp
- if (left_type[LTOP]) {
- sl->left_cbp = (h->cbp_table[left_xy[LTOP]] & 0x7F0) |
- ((h->cbp_table[left_xy[LTOP]] >> (left_block[0] & (~1))) & 2) |
- (((h->cbp_table[left_xy[LBOT]] >> (left_block[2] & (~1))) & 2) << 2);
- } else {
- sl->left_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F;
- }
- }
- }
-
- if (IS_INTER(mb_type) || (IS_DIRECT(mb_type) && sl->direct_spatial_mv_pred)) {
- int list;
- int b_stride = h->b_stride;
- for (list = 0; list < sl->list_count; list++) {
- int8_t *ref_cache = &sl->ref_cache[list][scan8[0]];
- int8_t *ref = h->cur_pic.ref_index[list];
- int16_t(*mv_cache)[2] = &sl->mv_cache[list][scan8[0]];
- int16_t(*mv)[2] = h->cur_pic.motion_val[list];
- if (!USES_LIST(mb_type, list))
- continue;
- av_assert2(!(IS_DIRECT(mb_type) && !sl->direct_spatial_mv_pred));
-
- if (USES_LIST(top_type, list)) {
- const int b_xy = h->mb2b_xy[top_xy] + 3 * b_stride;
- AV_COPY128(mv_cache[0 - 1 * 8], mv[b_xy + 0]);
- ref_cache[0 - 1 * 8] =
- ref_cache[1 - 1 * 8] = ref[4 * top_xy + 2];
- ref_cache[2 - 1 * 8] =
- ref_cache[3 - 1 * 8] = ref[4 * top_xy + 3];
- } else {
- AV_ZERO128(mv_cache[0 - 1 * 8]);
- AV_WN32A(&ref_cache[0 - 1 * 8],
- ((top_type ? LIST_NOT_USED : PART_NOT_AVAILABLE) & 0xFF) * 0x01010101u);
- }
-
- if (mb_type & (MB_TYPE_16x8 | MB_TYPE_8x8)) {
- for (i = 0; i < 2; i++) {
- int cache_idx = -1 + i * 2 * 8;
- if (USES_LIST(left_type[LEFT(i)], list)) {
- const int b_xy = h->mb2b_xy[left_xy[LEFT(i)]] + 3;
- const int b8_xy = 4 * left_xy[LEFT(i)] + 1;
- AV_COPY32(mv_cache[cache_idx],
- mv[b_xy + b_stride * left_block[0 + i * 2]]);
- AV_COPY32(mv_cache[cache_idx + 8],
- mv[b_xy + b_stride * left_block[1 + i * 2]]);
- ref_cache[cache_idx] = ref[b8_xy + (left_block[0 + i * 2] & ~1)];
- ref_cache[cache_idx + 8] = ref[b8_xy + (left_block[1 + i * 2] & ~1)];
- } else {
- AV_ZERO32(mv_cache[cache_idx]);
- AV_ZERO32(mv_cache[cache_idx + 8]);
- ref_cache[cache_idx] =
- ref_cache[cache_idx + 8] = (left_type[LEFT(i)]) ? LIST_NOT_USED
- : PART_NOT_AVAILABLE;
- }
- }
- } else {
- if (USES_LIST(left_type[LTOP], list)) {
- const int b_xy = h->mb2b_xy[left_xy[LTOP]] + 3;
- const int b8_xy = 4 * left_xy[LTOP] + 1;
- AV_COPY32(mv_cache[-1], mv[b_xy + b_stride * left_block[0]]);
- ref_cache[-1] = ref[b8_xy + (left_block[0] & ~1)];
- } else {
- AV_ZERO32(mv_cache[-1]);
- ref_cache[-1] = left_type[LTOP] ? LIST_NOT_USED
- : PART_NOT_AVAILABLE;
- }
- }
-
- if (USES_LIST(topright_type, list)) {
- const int b_xy = h->mb2b_xy[topright_xy] + 3 * b_stride;
- AV_COPY32(mv_cache[4 - 1 * 8], mv[b_xy]);
- ref_cache[4 - 1 * 8] = ref[4 * topright_xy + 2];
- } else {
- AV_ZERO32(mv_cache[4 - 1 * 8]);
- ref_cache[4 - 1 * 8] = topright_type ? LIST_NOT_USED
- : PART_NOT_AVAILABLE;
- }
- if(ref_cache[2 - 1*8] < 0 || ref_cache[4 - 1 * 8] < 0) {
- if (USES_LIST(topleft_type, list)) {
- const int b_xy = h->mb2b_xy[topleft_xy] + 3 + b_stride +
- (sl->topleft_partition & 2 * b_stride);
- const int b8_xy = 4 * topleft_xy + 1 + (sl->topleft_partition & 2);
- AV_COPY32(mv_cache[-1 - 1 * 8], mv[b_xy]);
- ref_cache[-1 - 1 * 8] = ref[b8_xy];
- } else {
- AV_ZERO32(mv_cache[-1 - 1 * 8]);
- ref_cache[-1 - 1 * 8] = topleft_type ? LIST_NOT_USED
- : PART_NOT_AVAILABLE;
- }
- }
-
- if ((mb_type & (MB_TYPE_SKIP | MB_TYPE_DIRECT2)) && !FRAME_MBAFF(h))
- continue;
-
- if (!(mb_type & (MB_TYPE_SKIP | MB_TYPE_DIRECT2))) {
- uint8_t(*mvd_cache)[2] = &sl->mvd_cache[list][scan8[0]];
- uint8_t(*mvd)[2] = sl->mvd_table[list];
- ref_cache[2 + 8 * 0] =
- ref_cache[2 + 8 * 2] = PART_NOT_AVAILABLE;
- AV_ZERO32(mv_cache[2 + 8 * 0]);
- AV_ZERO32(mv_cache[2 + 8 * 2]);
-
- if (CABAC(h)) {
- if (USES_LIST(top_type, list)) {
- const int b_xy = h->mb2br_xy[top_xy];
- AV_COPY64(mvd_cache[0 - 1 * 8], mvd[b_xy + 0]);
- } else {
- AV_ZERO64(mvd_cache[0 - 1 * 8]);
- }
- if (USES_LIST(left_type[LTOP], list)) {
- const int b_xy = h->mb2br_xy[left_xy[LTOP]] + 6;
- AV_COPY16(mvd_cache[-1 + 0 * 8], mvd[b_xy - left_block[0]]);
- AV_COPY16(mvd_cache[-1 + 1 * 8], mvd[b_xy - left_block[1]]);
- } else {
- AV_ZERO16(mvd_cache[-1 + 0 * 8]);
- AV_ZERO16(mvd_cache[-1 + 1 * 8]);
- }
- if (USES_LIST(left_type[LBOT], list)) {
- const int b_xy = h->mb2br_xy[left_xy[LBOT]] + 6;
- AV_COPY16(mvd_cache[-1 + 2 * 8], mvd[b_xy - left_block[2]]);
- AV_COPY16(mvd_cache[-1 + 3 * 8], mvd[b_xy - left_block[3]]);
- } else {
- AV_ZERO16(mvd_cache[-1 + 2 * 8]);
- AV_ZERO16(mvd_cache[-1 + 3 * 8]);
- }
- AV_ZERO16(mvd_cache[2 + 8 * 0]);
- AV_ZERO16(mvd_cache[2 + 8 * 2]);
- if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
- uint8_t *direct_cache = &sl->direct_cache[scan8[0]];
- uint8_t *direct_table = h->direct_table;
- fill_rectangle(direct_cache, 4, 4, 8, MB_TYPE_16x16 >> 1, 1);
-
- if (IS_DIRECT(top_type)) {
- AV_WN32A(&direct_cache[-1 * 8],
- 0x01010101u * (MB_TYPE_DIRECT2 >> 1));
- } else if (IS_8X8(top_type)) {
- int b8_xy = 4 * top_xy;
- direct_cache[0 - 1 * 8] = direct_table[b8_xy + 2];
- direct_cache[2 - 1 * 8] = direct_table[b8_xy + 3];
- } else {
- AV_WN32A(&direct_cache[-1 * 8],
- 0x01010101 * (MB_TYPE_16x16 >> 1));
- }
-
- if (IS_DIRECT(left_type[LTOP]))
- direct_cache[-1 + 0 * 8] = MB_TYPE_DIRECT2 >> 1;
- else if (IS_8X8(left_type[LTOP]))
- direct_cache[-1 + 0 * 8] = direct_table[4 * left_xy[LTOP] + 1 + (left_block[0] & ~1)];
- else
- direct_cache[-1 + 0 * 8] = MB_TYPE_16x16 >> 1;
-
- if (IS_DIRECT(left_type[LBOT]))
- direct_cache[-1 + 2 * 8] = MB_TYPE_DIRECT2 >> 1;
- else if (IS_8X8(left_type[LBOT]))
- direct_cache[-1 + 2 * 8] = direct_table[4 * left_xy[LBOT] + 1 + (left_block[2] & ~1)];
- else
- direct_cache[-1 + 2 * 8] = MB_TYPE_16x16 >> 1;
- }
- }
- }
-
-#define MAP_MVS \
- MAP_F2F(scan8[0] - 1 - 1 * 8, topleft_type) \
- MAP_F2F(scan8[0] + 0 - 1 * 8, top_type) \
- MAP_F2F(scan8[0] + 1 - 1 * 8, top_type) \
- MAP_F2F(scan8[0] + 2 - 1 * 8, top_type) \
- MAP_F2F(scan8[0] + 3 - 1 * 8, top_type) \
- MAP_F2F(scan8[0] + 4 - 1 * 8, topright_type) \
- MAP_F2F(scan8[0] - 1 + 0 * 8, left_type[LTOP]) \
- MAP_F2F(scan8[0] - 1 + 1 * 8, left_type[LTOP]) \
- MAP_F2F(scan8[0] - 1 + 2 * 8, left_type[LBOT]) \
- MAP_F2F(scan8[0] - 1 + 3 * 8, left_type[LBOT])
-
- if (FRAME_MBAFF(h)) {
- if (MB_FIELD(sl)) {
-
-#define MAP_F2F(idx, mb_type) \
- if (!IS_INTERLACED(mb_type) && sl->ref_cache[list][idx] >= 0) { \
- sl->ref_cache[list][idx] *= 2; \
- sl->mv_cache[list][idx][1] /= 2; \
- sl->mvd_cache[list][idx][1] >>= 1; \
- }
-
- MAP_MVS
- } else {
-
-#undef MAP_F2F
-#define MAP_F2F(idx, mb_type) \
- if (IS_INTERLACED(mb_type) && sl->ref_cache[list][idx] >= 0) { \
- sl->ref_cache[list][idx] >>= 1; \
- sl->mv_cache[list][idx][1] *= 2; \
- sl->mvd_cache[list][idx][1] <<= 1; \
- }
-
- MAP_MVS
-#undef MAP_F2F
- }
- }
- }
- }
-
- sl->neighbor_transform_size = !!IS_8x8DCT(top_type) + !!IS_8x8DCT(left_type[LTOP]);
-}
-
-/**
- * decodes a P_SKIP or B_SKIP macroblock
- */
-static void av_unused decode_mb_skip(const H264Context *h, H264SliceContext *sl)
-{
- const int mb_xy = sl->mb_xy;
- int mb_type = 0;
-
- memset(h->non_zero_count[mb_xy], 0, 48);
-
- if (MB_FIELD(sl))
- mb_type |= MB_TYPE_INTERLACED;
-
- if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
- // just for fill_caches. pred_direct_motion will set the real mb_type
- mb_type |= MB_TYPE_L0L1 | MB_TYPE_DIRECT2 | MB_TYPE_SKIP;
- if (sl->direct_spatial_mv_pred) {
- fill_decode_neighbors(h, sl, mb_type);
- fill_decode_caches(h, sl, mb_type); //FIXME check what is needed and what not ...
- }
- ff_h264_pred_direct_motion(h, sl, &mb_type);
- mb_type |= MB_TYPE_SKIP;
- } else {
- mb_type |= MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P1L0 | MB_TYPE_SKIP;
-
- fill_decode_neighbors(h, sl, mb_type);
- pred_pskip_motion(h, sl);
- }
-
- write_back_motion(h, sl, mb_type);
- h->cur_pic.mb_type[mb_xy] = mb_type;
- h->cur_pic.qscale_table[mb_xy] = sl->qscale;
- h->slice_table[mb_xy] = sl->slice_num;
- sl->prev_mb_skipped = 1;
-}
-
-#endif /* AVCODEC_H264_MVPRED_H */
diff --git a/ffmpeg-2-8-11/libavcodec/hevc_ps.c b/ffmpeg-2-8-11/libavcodec/hevc_ps.c
deleted file mode 100644
index 14f908e..0000000
--- a/ffmpeg-2-8-11/libavcodec/hevc_ps.c
+++ /dev/null
@@ -1,1612 +0,0 @@
-/*
- * HEVC Parameter Set decoding
- *
- * Copyright (C) 2012 - 2103 Guillaume Martres
- * Copyright (C) 2012 - 2103 Mickael Raulet
- * Copyright (C) 2012 - 2013 Gildas Cocherel
- * Copyright (C) 2013 Vittorio Giovara
- *
- * 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 "golomb.h"
-#include "hevc.h"
-
-static const uint8_t default_scaling_list_intra[] = {
- 16, 16, 16, 16, 17, 18, 21, 24,
- 16, 16, 16, 16, 17, 19, 22, 25,
- 16, 16, 17, 18, 20, 22, 25, 29,
- 16, 16, 18, 21, 24, 27, 31, 36,
- 17, 17, 20, 24, 30, 35, 41, 47,
- 18, 19, 22, 27, 35, 44, 54, 65,
- 21, 22, 25, 31, 41, 54, 70, 88,
- 24, 25, 29, 36, 47, 65, 88, 115
-};
-
-static const uint8_t default_scaling_list_inter[] = {
- 16, 16, 16, 16, 17, 18, 20, 24,
- 16, 16, 16, 17, 18, 20, 24, 25,
- 16, 16, 17, 18, 20, 24, 25, 28,
- 16, 17, 18, 20, 24, 25, 28, 33,
- 17, 18, 20, 24, 25, 28, 33, 41,
- 18, 20, 24, 25, 28, 33, 41, 54,
- 20, 24, 25, 28, 33, 41, 54, 71,
- 24, 25, 28, 33, 41, 54, 71, 91
-};
-
-static const AVRational vui_sar[] = {
- { 0, 1 },
- { 1, 1 },
- { 12, 11 },
- { 10, 11 },
- { 16, 11 },
- { 40, 33 },
- { 24, 11 },
- { 20, 11 },
- { 32, 11 },
- { 80, 33 },
- { 18, 11 },
- { 15, 11 },
- { 64, 33 },
- { 160, 99 },
- { 4, 3 },
- { 3, 2 },
- { 2, 1 },
-};
-
-static void remove_pps(HEVCParamSets *s, int id)
-{
- if (s->pps_list[id] && s->pps == (const HEVCPPS*)s->pps_list[id]->data)
- s->pps = NULL;
- av_buffer_unref(&s->pps_list[id]);
-}
-
-static void remove_sps(HEVCParamSets *s, int id)
-{
- int i;
- if (s->sps_list[id]) {
- if (s->sps == (const HEVCSPS*)s->sps_list[id]->data)
- s->sps = NULL;
-
- /* drop all PPS that depend on this SPS */
- for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++)
- if (s->pps_list[i] && ((HEVCPPS*)s->pps_list[i]->data)->sps_id == id)
- remove_pps(s, i);
-
- av_assert0(!(s->sps_list[id] && s->sps == (HEVCSPS*)s->sps_list[id]->data));
- }
- av_buffer_unref(&s->sps_list[id]);
-}
-
-static void remove_vps(HEVCParamSets *s, int id)
-{
- int i;
- if (s->vps_list[id]) {
- if (s->vps == (const HEVCVPS*)s->vps_list[id]->data)
- s->vps = NULL;
-
- for (i = 0; i < FF_ARRAY_ELEMS(s->sps_list); i++)
- if (s->sps_list[i] && ((HEVCSPS*)s->sps_list[i]->data)->vps_id == id)
- remove_sps(s, i);
- }
- av_buffer_unref(&s->vps_list[id]);
-}
-
-int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx,
- ShortTermRPS *rps, const HEVCSPS *sps, int is_slice_header)
-{
- uint8_t rps_predict = 0;
- int delta_poc;
- int k0 = 0;
- int k1 = 0;
- int k = 0;
- int i;
-
- if (rps != sps->st_rps && sps->nb_st_rps)
- rps_predict = get_bits1(gb);
-
- if (rps_predict) {
- const ShortTermRPS *rps_ridx;
- int delta_rps;
- unsigned abs_delta_rps;
- uint8_t use_delta_flag = 0;
- uint8_t delta_rps_sign;
-
- if (is_slice_header) {
- unsigned int delta_idx = get_ue_golomb_long(gb) + 1;
- if (delta_idx > sps->nb_st_rps) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid value of delta_idx in slice header RPS: %d > %d.\n",
- delta_idx, sps->nb_st_rps);
- return AVERROR_INVALIDDATA;
- }
- rps_ridx = &sps->st_rps[sps->nb_st_rps - delta_idx];
- rps->rps_idx_num_delta_pocs = rps_ridx->num_delta_pocs;
- } else
- rps_ridx = &sps->st_rps[rps - sps->st_rps - 1];
-
- delta_rps_sign = get_bits1(gb);
- abs_delta_rps = get_ue_golomb_long(gb) + 1;
- if (abs_delta_rps < 1 || abs_delta_rps > 32768) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid value of abs_delta_rps: %d\n",
- abs_delta_rps);
- return AVERROR_INVALIDDATA;
- }
- delta_rps = (1 - (delta_rps_sign << 1)) * abs_delta_rps;
- for (i = 0; i <= rps_ridx->num_delta_pocs; i++) {
- int used = rps->used[k] = get_bits1(gb);
-
- if (!used)
- use_delta_flag = get_bits1(gb);
-
- if (used || use_delta_flag) {
- if (i < rps_ridx->num_delta_pocs)
- delta_poc = delta_rps + rps_ridx->delta_poc[i];
- else
- delta_poc = delta_rps;
- rps->delta_poc[k] = delta_poc;
- if (delta_poc < 0)
- k0++;
- else
- k1++;
- k++;
- }
- }
-
- rps->num_delta_pocs = k;
- rps->num_negative_pics = k0;
- // sort in increasing order (smallest first)
- if (rps->num_delta_pocs != 0) {
- int used, tmp;
- for (i = 1; i < rps->num_delta_pocs; i++) {
- delta_poc = rps->delta_poc[i];
- used = rps->used[i];
- for (k = i - 1; k >= 0; k--) {
- tmp = rps->delta_poc[k];
- if (delta_poc < tmp) {
- rps->delta_poc[k + 1] = tmp;
- rps->used[k + 1] = rps->used[k];
- rps->delta_poc[k] = delta_poc;
- rps->used[k] = used;
- }
- }
- }
- }
- if ((rps->num_negative_pics >> 1) != 0) {
- int used;
- k = rps->num_negative_pics - 1;
- // flip the negative values to largest first
- for (i = 0; i < rps->num_negative_pics >> 1; i++) {
- delta_poc = rps->delta_poc[i];
- used = rps->used[i];
- rps->delta_poc[i] = rps->delta_poc[k];
- rps->used[i] = rps->used[k];
- rps->delta_poc[k] = delta_poc;
- rps->used[k] = used;
- k--;
- }
- }
- } else {
- unsigned int prev, nb_positive_pics;
- rps->num_negative_pics = get_ue_golomb_long(gb);
- nb_positive_pics = get_ue_golomb_long(gb);
-
- if (rps->num_negative_pics >= MAX_REFS ||
- nb_positive_pics >= MAX_REFS) {
- av_log(avctx, AV_LOG_ERROR, "Too many refs in a short term RPS.\n");
- return AVERROR_INVALIDDATA;
- }
-
- rps->num_delta_pocs = rps->num_negative_pics + nb_positive_pics;
- if (rps->num_delta_pocs) {
- prev = 0;
- for (i = 0; i < rps->num_negative_pics; i++) {
- delta_poc = get_ue_golomb_long(gb) + 1;
- prev -= delta_poc;
- rps->delta_poc[i] = prev;
- rps->used[i] = get_bits1(gb);
- }
- prev = 0;
- for (i = 0; i < nb_positive_pics; i++) {
- delta_poc = get_ue_golomb_long(gb) + 1;
- prev += delta_poc;
- rps->delta_poc[rps->num_negative_pics + i] = prev;
- rps->used[rps->num_negative_pics + i] = get_bits1(gb);
- }
- }
- }
- return 0;
-}
-
-
-static int decode_profile_tier_level(GetBitContext *gb, AVCodecContext *avctx,
- PTLCommon *ptl)
-{
- int i;
-
- if (get_bits_left(gb) < 2+1+5 + 32 + 4 + 16 + 16 + 12)
- return -1;
-
- ptl->profile_space = get_bits(gb, 2);
- ptl->tier_flag = get_bits1(gb);
- ptl->profile_idc = get_bits(gb, 5);
- if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN)
- av_log(avctx, AV_LOG_DEBUG, "Main profile bitstream\n");
- else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_10)
- av_log(avctx, AV_LOG_DEBUG, "Main 10 profile bitstream\n");
- else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_STILL_PICTURE)
- av_log(avctx, AV_LOG_DEBUG, "Main Still Picture profile bitstream\n");
- else if (ptl->profile_idc == FF_PROFILE_HEVC_REXT)
- av_log(avctx, AV_LOG_DEBUG, "Range Extension profile bitstream\n");
- else
- av_log(avctx, AV_LOG_WARNING, "Unknown HEVC profile: %d\n", ptl->profile_idc);
-
- for (i = 0; i < 32; i++)
- ptl->profile_compatibility_flag[i] = get_bits1(gb);
- ptl->progressive_source_flag = get_bits1(gb);
- ptl->interlaced_source_flag = get_bits1(gb);
- ptl->non_packed_constraint_flag = get_bits1(gb);
- ptl->frame_only_constraint_flag = get_bits1(gb);
-
- skip_bits(gb, 16); // XXX_reserved_zero_44bits[0..15]
- skip_bits(gb, 16); // XXX_reserved_zero_44bits[16..31]
- skip_bits(gb, 12); // XXX_reserved_zero_44bits[32..43]
-
- return 0;
-}
-
-static int parse_ptl(GetBitContext *gb, AVCodecContext *avctx,
- PTL *ptl, int max_num_sub_layers)
-{
- int i;
- if (decode_profile_tier_level(gb, avctx, &ptl->general_ptl) < 0 ||
- get_bits_left(gb) < 8 + 8*2) {
- av_log(avctx, AV_LOG_ERROR, "PTL information too short\n");
- return -1;
- }
-
- ptl->general_ptl.level_idc = get_bits(gb, 8);
-
- for (i = 0; i < max_num_sub_layers - 1; i++) {
- ptl->sub_layer_profile_present_flag[i] = get_bits1(gb);
- ptl->sub_layer_level_present_flag[i] = get_bits1(gb);
- }
-
- if (max_num_sub_layers - 1> 0)
- for (i = max_num_sub_layers - 1; i < 8; i++)
- skip_bits(gb, 2); // reserved_zero_2bits[i]
- for (i = 0; i < max_num_sub_layers - 1; i++) {
- if (ptl->sub_layer_profile_present_flag[i] &&
- decode_profile_tier_level(gb, avctx, &ptl->sub_layer_ptl[i]) < 0) {
- av_log(avctx, AV_LOG_ERROR,
- "PTL information for sublayer %i too short\n", i);
- return -1;
- }
- if (ptl->sub_layer_level_present_flag[i]) {
- if (get_bits_left(gb) < 8) {
- av_log(avctx, AV_LOG_ERROR,
- "Not enough data for sublayer %i level_idc\n", i);
- return -1;
- } else
- ptl->sub_layer_ptl[i].level_idc = get_bits(gb, 8);
- }
- }
-
- return 0;
-}
-
-static void decode_sublayer_hrd(GetBitContext *gb, unsigned int nb_cpb,
- int subpic_params_present)
-{
- int i;
-
- for (i = 0; i < nb_cpb; i++) {
- get_ue_golomb_long(gb); // bit_rate_value_minus1
- get_ue_golomb_long(gb); // cpb_size_value_minus1
-
- if (subpic_params_present) {
- get_ue_golomb_long(gb); // cpb_size_du_value_minus1
- get_ue_golomb_long(gb); // bit_rate_du_value_minus1
- }
- skip_bits1(gb); // cbr_flag
- }
-}
-
-static int decode_hrd(GetBitContext *gb, int common_inf_present,
- int max_sublayers)
-{
- int nal_params_present = 0, vcl_params_present = 0;
- int subpic_params_present = 0;
- int i;
-
- if (common_inf_present) {
- nal_params_present = get_bits1(gb);
- vcl_params_present = get_bits1(gb);
-
- if (nal_params_present || vcl_params_present) {
- subpic_params_present = get_bits1(gb);
-
- if (subpic_params_present) {
- skip_bits(gb, 8); // tick_divisor_minus2
- skip_bits(gb, 5); // du_cpb_removal_delay_increment_length_minus1
- skip_bits(gb, 1); // sub_pic_cpb_params_in_pic_timing_sei_flag
- skip_bits(gb, 5); // dpb_output_delay_du_length_minus1
- }
-
- skip_bits(gb, 4); // bit_rate_scale
- skip_bits(gb, 4); // cpb_size_scale
-
- if (subpic_params_present)
- skip_bits(gb, 4); // cpb_size_du_scale
-
- skip_bits(gb, 5); // initial_cpb_removal_delay_length_minus1
- skip_bits(gb, 5); // au_cpb_removal_delay_length_minus1
- skip_bits(gb, 5); // dpb_output_delay_length_minus1
- }
- }
-
- for (i = 0; i < max_sublayers; i++) {
- int low_delay = 0;
- unsigned int nb_cpb = 1;
- int fixed_rate = get_bits1(gb);
-
- if (!fixed_rate)
- fixed_rate = get_bits1(gb);
-
- if (fixed_rate)
- get_ue_golomb_long(gb); // elemental_duration_in_tc_minus1
- else
- low_delay = get_bits1(gb);
-
- if (!low_delay) {
- nb_cpb = get_ue_golomb_long(gb) + 1;
- if (nb_cpb < 1 || nb_cpb > 32) {
- av_log(NULL, AV_LOG_ERROR, "nb_cpb %d invalid\n", nb_cpb);
- return AVERROR_INVALIDDATA;
- }
- }
-
- if (nal_params_present)
- decode_sublayer_hrd(gb, nb_cpb, subpic_params_present);
- if (vcl_params_present)
- decode_sublayer_hrd(gb, nb_cpb, subpic_params_present);
- }
- return 0;
-}
-
-int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx,
- HEVCParamSets *ps)
-{
- int i,j;
- int vps_id = 0;
- HEVCVPS *vps;
- AVBufferRef *vps_buf = av_buffer_allocz(sizeof(*vps));
-
- if (!vps_buf)
- return AVERROR(ENOMEM);
- vps = (HEVCVPS*)vps_buf->data;
-
- av_log(avctx, AV_LOG_DEBUG, "Decoding VPS\n");
-
- vps_id = get_bits(gb, 4);
- if (vps_id >= MAX_VPS_COUNT) {
- av_log(avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", vps_id);
- goto err;
- }
-
- if (get_bits(gb, 2) != 3) { // vps_reserved_three_2bits
- av_log(avctx, AV_LOG_ERROR, "vps_reserved_three_2bits is not three\n");
- goto err;
- }
-
- vps->vps_max_layers = get_bits(gb, 6) + 1;
- vps->vps_max_sub_layers = get_bits(gb, 3) + 1;
- vps->vps_temporal_id_nesting_flag = get_bits1(gb);
-
- if (get_bits(gb, 16) != 0xffff) { // vps_reserved_ffff_16bits
- av_log(avctx, AV_LOG_ERROR, "vps_reserved_ffff_16bits is not 0xffff\n");
- goto err;
- }
-
- if (vps->vps_max_sub_layers > MAX_SUB_LAYERS) {
- av_log(avctx, AV_LOG_ERROR, "vps_max_sub_layers out of range: %d\n",
- vps->vps_max_sub_layers);
- goto err;
- }
-
- if (parse_ptl(gb, avctx, &vps->ptl, vps->vps_max_sub_layers) < 0)
- goto err;
-
- vps->vps_sub_layer_ordering_info_present_flag = get_bits1(gb);
-
- i = vps->vps_sub_layer_ordering_info_present_flag ? 0 : vps->vps_max_sub_layers - 1;
- for (; i < vps->vps_max_sub_layers; i++) {
- vps->vps_max_dec_pic_buffering[i] = get_ue_golomb_long(gb) + 1;
- vps->vps_num_reorder_pics[i] = get_ue_golomb_long(gb);
- vps->vps_max_latency_increase[i] = get_ue_golomb_long(gb) - 1;
-
- if (vps->vps_max_dec_pic_buffering[i] > MAX_DPB_SIZE || !vps->vps_max_dec_pic_buffering[i]) {
- av_log(avctx, AV_LOG_ERROR, "vps_max_dec_pic_buffering_minus1 out of range: %d\n",
- vps->vps_max_dec_pic_buffering[i] - 1);
- goto err;
- }
- if (vps->vps_num_reorder_pics[i] > vps->vps_max_dec_pic_buffering[i] - 1) {
- av_log(avctx, AV_LOG_WARNING, "vps_max_num_reorder_pics out of range: %d\n",
- vps->vps_num_reorder_pics[i]);
- if (avctx->err_recognition & AV_EF_EXPLODE)
- goto err;
- }
- }
-
- vps->vps_max_layer_id = get_bits(gb, 6);
- vps->vps_num_layer_sets = get_ue_golomb_long(gb) + 1;
- if (vps->vps_num_layer_sets < 1 || vps->vps_num_layer_sets > 1024 ||
- (vps->vps_num_layer_sets - 1LL) * (vps->vps_max_layer_id + 1LL) > get_bits_left(gb)) {
- av_log(avctx, AV_LOG_ERROR, "too many layer_id_included_flags\n");
- goto err;
- }
-
- for (i = 1; i < vps->vps_num_layer_sets; i++)
- for (j = 0; j <= vps->vps_max_layer_id; j++)
- skip_bits(gb, 1); // layer_id_included_flag[i][j]
-
- vps->vps_timing_info_present_flag = get_bits1(gb);
- if (vps->vps_timing_info_present_flag) {
- vps->vps_num_units_in_tick = get_bits_long(gb, 32);
- vps->vps_time_scale = get_bits_long(gb, 32);
- vps->vps_poc_proportional_to_timing_flag = get_bits1(gb);
- if (vps->vps_poc_proportional_to_timing_flag)
- vps->vps_num_ticks_poc_diff_one = get_ue_golomb_long(gb) + 1;
- vps->vps_num_hrd_parameters = get_ue_golomb_long(gb);
- if (vps->vps_num_hrd_parameters > (unsigned)vps->vps_num_layer_sets) {
- av_log(avctx, AV_LOG_ERROR,
- "vps_num_hrd_parameters %d is invalid\n", vps->vps_num_hrd_parameters);
- goto err;
- }
- for (i = 0; i < vps->vps_num_hrd_parameters; i++) {
- int common_inf_present = 1;
-
- get_ue_golomb_long(gb); // hrd_layer_set_idx
- if (i)
- common_inf_present = get_bits1(gb);
- decode_hrd(gb, common_inf_present, vps->vps_max_sub_layers);
- }
- }
- get_bits1(gb); /* vps_extension_flag */
-
- if (get_bits_left(gb) < 0) {
- av_log(avctx, AV_LOG_ERROR,
- "Overread VPS by %d bits\n", -get_bits_left(gb));
- if (ps->vps_list[vps_id])
- goto err;
- }
-
- if (ps->vps_list[vps_id] &&
- !memcmp(ps->vps_list[vps_id]->data, vps_buf->data, vps_buf->size)) {
- av_buffer_unref(&vps_buf);
- } else {
- remove_vps(ps, vps_id);
- ps->vps_list[vps_id] = vps_buf;
- }
-
- return 0;
-
-err:
- av_buffer_unref(&vps_buf);
- return AVERROR_INVALIDDATA;
-}
-
-static void decode_vui(GetBitContext *gb, AVCodecContext *avctx,
- int apply_defdispwin, HEVCSPS *sps)
-{
- VUI *vui = &sps->vui;
- GetBitContext backup;
- int sar_present, alt = 0;
-
- av_log(avctx, AV_LOG_DEBUG, "Decoding VUI\n");
-
- sar_present = get_bits1(gb);
- if (sar_present) {
- uint8_t sar_idx = get_bits(gb, 8);
- if (sar_idx < FF_ARRAY_ELEMS(vui_sar))
- vui->sar = vui_sar[sar_idx];
- else if (sar_idx == 255) {
- vui->sar.num = get_bits(gb, 16);
- vui->sar.den = get_bits(gb, 16);
- } else
- av_log(avctx, AV_LOG_WARNING,
- "Unknown SAR index: %u.\n", sar_idx);
- }
-
- vui->overscan_info_present_flag = get_bits1(gb);
- if (vui->overscan_info_present_flag)
- vui->overscan_appropriate_flag = get_bits1(gb);
-
- vui->video_signal_type_present_flag = get_bits1(gb);
- if (vui->video_signal_type_present_flag) {
- vui->video_format = get_bits(gb, 3);
- vui->video_full_range_flag = get_bits1(gb);
- vui->colour_description_present_flag = get_bits1(gb);
- if (vui->video_full_range_flag && sps->pix_fmt == AV_PIX_FMT_YUV420P)
- sps->pix_fmt = AV_PIX_FMT_YUVJ420P;
- if (vui->colour_description_present_flag) {
- vui->colour_primaries = get_bits(gb, 8);
- vui->transfer_characteristic = get_bits(gb, 8);
- vui->matrix_coeffs = get_bits(gb, 8);
-
- // Set invalid values to "unspecified"
- if (vui->colour_primaries >= AVCOL_PRI_NB)
- vui->colour_primaries = AVCOL_PRI_UNSPECIFIED;
- if (vui->transfer_characteristic >= AVCOL_TRC_NB)
- vui->transfer_characteristic = AVCOL_TRC_UNSPECIFIED;
- if (vui->matrix_coeffs >= AVCOL_SPC_NB)
- vui->matrix_coeffs = AVCOL_SPC_UNSPECIFIED;
- }
- }
-
- vui->chroma_loc_info_present_flag = get_bits1(gb);
- if (vui->chroma_loc_info_present_flag) {
- vui->chroma_sample_loc_type_top_field = get_ue_golomb_long(gb);
- vui->chroma_sample_loc_type_bottom_field = get_ue_golomb_long(gb);
- }
-
- vui->neutra_chroma_indication_flag = get_bits1(gb);
- vui->field_seq_flag = get_bits1(gb);
- vui->frame_field_info_present_flag = get_bits1(gb);
-
- if (get_bits_left(gb) >= 68 && show_bits_long(gb, 21) == 0x100000) {
- vui->default_display_window_flag = 0;
- av_log(avctx, AV_LOG_WARNING, "Invalid default display window\n");
- } else
- vui->default_display_window_flag = get_bits1(gb);
- // Backup context in case an alternate header is detected
- memcpy(&backup, gb, sizeof(backup));
-
- if (vui->default_display_window_flag) {
- //TODO: * 2 is only valid for 420
- vui->def_disp_win.left_offset = get_ue_golomb_long(gb) * 2;
- vui->def_disp_win.right_offset = get_ue_golomb_long(gb) * 2;
- vui->def_disp_win.top_offset = get_ue_golomb_long(gb) * 2;
- vui->def_disp_win.bottom_offset = get_ue_golomb_long(gb) * 2;
-
- if (apply_defdispwin &&
- avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) {
- av_log(avctx, AV_LOG_DEBUG,
- "discarding vui default display window, "
- "original values are l:%u r:%u t:%u b:%u\n",
- vui->def_disp_win.left_offset,
- vui->def_disp_win.right_offset,
- vui->def_disp_win.top_offset,
- vui->def_disp_win.bottom_offset);
-
- vui->def_disp_win.left_offset =
- vui->def_disp_win.right_offset =
- vui->def_disp_win.top_offset =
- vui->def_disp_win.bottom_offset = 0;
- }
- }
-
- vui->vui_timing_info_present_flag = get_bits1(gb);
-
- if (vui->vui_timing_info_present_flag) {
- if( get_bits_left(gb) < 66) {
- // The alternate syntax seem to have timing info located
- // at where def_disp_win is normally located
- av_log(avctx, AV_LOG_WARNING,
- "Strange VUI timing information, retrying...\n");
- vui->default_display_window_flag = 0;
- memset(&vui->def_disp_win, 0, sizeof(vui->def_disp_win));
- memcpy(gb, &backup, sizeof(backup));
- alt = 1;
- }
- vui->vui_num_units_in_tick = get_bits_long(gb, 32);
- vui->vui_time_scale = get_bits_long(gb, 32);
- if (alt) {
- av_log(avctx, AV_LOG_INFO, "Retry got %i/%i fps\n",
- vui->vui_time_scale, vui->vui_num_units_in_tick);
- }
- vui->vui_poc_proportional_to_timing_flag = get_bits1(gb);
- if (vui->vui_poc_proportional_to_timing_flag)
- vui->vui_num_ticks_poc_diff_one_minus1 = get_ue_golomb_long(gb);
- vui->vui_hrd_parameters_present_flag = get_bits1(gb);
- if (vui->vui_hrd_parameters_present_flag)
- decode_hrd(gb, 1, sps->max_sub_layers);
- }
-
- vui->bitstream_restriction_flag = get_bits1(gb);
- if (vui->bitstream_restriction_flag) {
- vui->tiles_fixed_structure_flag = get_bits1(gb);
- vui->motion_vectors_over_pic_boundaries_flag = get_bits1(gb);
- vui->restricted_ref_pic_lists_flag = get_bits1(gb);
- vui->min_spatial_segmentation_idc = get_ue_golomb_long(gb);
- vui->max_bytes_per_pic_denom = get_ue_golomb_long(gb);
- vui->max_bits_per_min_cu_denom = get_ue_golomb_long(gb);
- vui->log2_max_mv_length_horizontal = get_ue_golomb_long(gb);
- vui->log2_max_mv_length_vertical = get_ue_golomb_long(gb);
- }
-}
-
-static void set_default_scaling_list_data(ScalingList *sl)
-{
- int matrixId;
-
- for (matrixId = 0; matrixId < 6; matrixId++) {
- // 4x4 default is 16
- memset(sl->sl[0][matrixId], 16, 16);
- sl->sl_dc[0][matrixId] = 16; // default for 16x16
- sl->sl_dc[1][matrixId] = 16; // default for 32x32
- }
- memcpy(sl->sl[1][0], default_scaling_list_intra, 64);
- memcpy(sl->sl[1][1], default_scaling_list_intra, 64);
- memcpy(sl->sl[1][2], default_scaling_list_intra, 64);
- memcpy(sl->sl[1][3], default_scaling_list_inter, 64);
- memcpy(sl->sl[1][4], default_scaling_list_inter, 64);
- memcpy(sl->sl[1][5], default_scaling_list_inter, 64);
- memcpy(sl->sl[2][0], default_scaling_list_intra, 64);
- memcpy(sl->sl[2][1], default_scaling_list_intra, 64);
- memcpy(sl->sl[2][2], default_scaling_list_intra, 64);
- memcpy(sl->sl[2][3], default_scaling_list_inter, 64);
- memcpy(sl->sl[2][4], default_scaling_list_inter, 64);
- memcpy(sl->sl[2][5], default_scaling_list_inter, 64);
- memcpy(sl->sl[3][0], default_scaling_list_intra, 64);
- memcpy(sl->sl[3][1], default_scaling_list_intra, 64);
- memcpy(sl->sl[3][2], default_scaling_list_intra, 64);
- memcpy(sl->sl[3][3], default_scaling_list_inter, 64);
- memcpy(sl->sl[3][4], default_scaling_list_inter, 64);
- memcpy(sl->sl[3][5], default_scaling_list_inter, 64);
-}
-
-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];
- int size_id, matrix_id, pos;
- int i;
-
- for (size_id = 0; size_id < 4; size_id++)
- for (matrix_id = 0; matrix_id < 6; matrix_id += ((size_id == 3) ? 3 : 1)) {
- scaling_list_pred_mode_flag = get_bits1(gb);
- if (!scaling_list_pred_mode_flag) {
- unsigned int delta = get_ue_golomb_long(gb);
- /* Only need to handle non-zero delta. Zero means default,
- * which should already be in the arrays. */
- if (delta) {
- // Copy from previous array.
- if (matrix_id < delta) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid delta in scaling list data: %d.\n", delta);
- return AVERROR_INVALIDDATA;
- }
-
- memcpy(sl->sl[size_id][matrix_id],
- sl->sl[size_id][matrix_id - delta],
- size_id > 0 ? 64 : 16);
- if (size_id > 1)
- sl->sl_dc[size_id - 2][matrix_id] = sl->sl_dc[size_id - 2][matrix_id - delta];
- }
- } else {
- int next_coef, coef_num;
- int32_t scaling_list_delta_coef;
-
- next_coef = 8;
- coef_num = FFMIN(64, 1 << (4 + (size_id << 1)));
- if (size_id > 1) {
- scaling_list_dc_coef[size_id - 2][matrix_id] = get_se_golomb(gb) + 8;
- next_coef = scaling_list_dc_coef[size_id - 2][matrix_id];
- sl->sl_dc[size_id - 2][matrix_id] = next_coef;
- }
- for (i = 0; i < coef_num; i++) {
- if (size_id == 0)
- pos = 4 * ff_hevc_diag_scan4x4_y[i] +
- ff_hevc_diag_scan4x4_x[i];
- else
- pos = 8 * ff_hevc_diag_scan8x8_y[i] +
- ff_hevc_diag_scan8x8_x[i];
-
- scaling_list_delta_coef = get_se_golomb(gb);
- next_coef = (next_coef + scaling_list_delta_coef + 256) % 256;
- sl->sl[size_id][matrix_id][pos] = next_coef;
- }
- }
- }
-
- if (sps->chroma_format_idc == 3) {
- for (i = 0; i < 64; i++) {
- sl->sl[3][1][i] = sl->sl[2][1][i];
- sl->sl[3][2][i] = sl->sl[2][2][i];
- sl->sl[3][4][i] = sl->sl[2][4][i];
- sl->sl[3][5][i] = sl->sl[2][5][i];
- }
- sl->sl_dc[1][1] = sl->sl_dc[0][1];
- sl->sl_dc[1][2] = sl->sl_dc[0][2];
- sl->sl_dc[1][4] = sl->sl_dc[0][4];
- sl->sl_dc[1][5] = sl->sl_dc[0][5];
- }
-
-
- return 0;
-}
-
-static int map_pixel_format(AVCodecContext *avctx, HEVCSPS *sps)
-{
- const AVPixFmtDescriptor *desc;
- switch (sps->bit_depth) {
- case 8:
- if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY8;
- if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P;
- if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P;
- if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P;
- break;
- case 9:
- if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;
- if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P9;
- if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P9;
- if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P9;
- break;
- case 10:
- if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;
- if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P10;
- if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P10;
- if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P10;
- break;
- case 12:
- if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;
- if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P12;
- if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P12;
- if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P12;
- break;
- default:
- av_log(avctx, AV_LOG_ERROR,
- "4:2:0, 4:2:2, 4:4:4 supports are currently specified for 8, 10 and 12 bits.\n");
- av_log(avctx, AV_LOG_ERROR,
- "chroma_format_idc is %d, depth is %d",
- sps->chroma_format_idc, sps->bit_depth);
- return AVERROR_INVALIDDATA;
- }
-
- desc = av_pix_fmt_desc_get(sps->pix_fmt);
- if (!desc)
- return AVERROR(EINVAL);
-
- sps->hshift[0] = sps->vshift[0] = 0;
- sps->hshift[2] = sps->hshift[1] = desc->log2_chroma_w;
- sps->vshift[2] = sps->vshift[1] = desc->log2_chroma_h;
-
- sps->pixel_shift = sps->bit_depth > 8;
-
- return 0;
-}
-
-int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
- int apply_defdispwin, AVBufferRef **vps_list, AVCodecContext *avctx)
-{
- int ret = 0;
- int log2_diff_max_min_transform_block_size;
- int bit_depth_chroma, start, vui_present, sublayer_ordering_info;
- int i;
-
- // Coded parameters
-
- sps->vps_id = get_bits(gb, 4);
- if (sps->vps_id >= MAX_VPS_COUNT) {
- av_log(avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", sps->vps_id);
- return AVERROR_INVALIDDATA;
- }
-
- if (vps_list && !vps_list[sps->vps_id]) {
- av_log(avctx, AV_LOG_ERROR, "VPS %d does not exist\n",
- sps->vps_id);
- return AVERROR_INVALIDDATA;
- }
-
- sps->max_sub_layers = get_bits(gb, 3) + 1;
- if (sps->max_sub_layers > MAX_SUB_LAYERS) {
- av_log(avctx, AV_LOG_ERROR, "sps_max_sub_layers out of range: %d\n",
- sps->max_sub_layers);
- return AVERROR_INVALIDDATA;
- }
-
- skip_bits1(gb); // temporal_id_nesting_flag
-
- if ((ret = parse_ptl(gb, avctx, &sps->ptl, sps->max_sub_layers)) < 0)
- return ret;
-
- *sps_id = get_ue_golomb_long(gb);
- if (*sps_id >= MAX_SPS_COUNT) {
- av_log(avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", *sps_id);
- return AVERROR_INVALIDDATA;
- }
-
- sps->chroma_format_idc = get_ue_golomb_long(gb);
- if (sps->chroma_format_idc > 3U) {
- av_log(avctx, AV_LOG_ERROR, "chroma_format_idc %d is invalid\n", sps->chroma_format_idc);
- return AVERROR_INVALIDDATA;
- }
-
- if (sps->chroma_format_idc == 3)
- sps->separate_colour_plane_flag = get_bits1(gb);
-
- if (sps->separate_colour_plane_flag)
- sps->chroma_format_idc = 0;
-
- sps->width = get_ue_golomb_long(gb);
- sps->height = get_ue_golomb_long(gb);
- if ((ret = av_image_check_size(sps->width,
- sps->height, 0, avctx)) < 0)
- return ret;
-
- if (get_bits1(gb)) { // pic_conformance_flag
- //TODO: * 2 is only valid for 420
- sps->pic_conf_win.left_offset = get_ue_golomb_long(gb) * 2;
- sps->pic_conf_win.right_offset = get_ue_golomb_long(gb) * 2;
- sps->pic_conf_win.top_offset = get_ue_golomb_long(gb) * 2;
- sps->pic_conf_win.bottom_offset = get_ue_golomb_long(gb) * 2;
-
- if (avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) {
- av_log(avctx, AV_LOG_DEBUG,
- "discarding sps conformance window, "
- "original values are l:%u r:%u t:%u b:%u\n",
- sps->pic_conf_win.left_offset,
- sps->pic_conf_win.right_offset,
- sps->pic_conf_win.top_offset,
- sps->pic_conf_win.bottom_offset);
-
- sps->pic_conf_win.left_offset =
- sps->pic_conf_win.right_offset =
- sps->pic_conf_win.top_offset =
- sps->pic_conf_win.bottom_offset = 0;
- }
- sps->output_window = sps->pic_conf_win;
- }
-
- sps->bit_depth = get_ue_golomb_long(gb) + 8;
- bit_depth_chroma = get_ue_golomb_long(gb) + 8;
- if (sps->chroma_format_idc && bit_depth_chroma != sps->bit_depth) {
- av_log(avctx, AV_LOG_ERROR,
- "Luma bit depth (%d) is different from chroma bit depth (%d), "
- "this is unsupported.\n",
- sps->bit_depth, bit_depth_chroma);
- return AVERROR_INVALIDDATA;
- }
-
- ret = map_pixel_format(avctx, sps);
- if (ret < 0)
- return ret;
-
- sps->log2_max_poc_lsb = get_ue_golomb_long(gb) + 4;
- if (sps->log2_max_poc_lsb > 16) {
- av_log(avctx, AV_LOG_ERROR, "log2_max_pic_order_cnt_lsb_minus4 out range: %d\n",
- sps->log2_max_poc_lsb - 4);
- return AVERROR_INVALIDDATA;
- }
-
- sublayer_ordering_info = get_bits1(gb);
- start = sublayer_ordering_info ? 0 : sps->max_sub_layers - 1;
- for (i = start; i < sps->max_sub_layers; i++) {
- sps->temporal_layer[i].max_dec_pic_buffering = get_ue_golomb_long(gb) + 1;
- sps->temporal_layer[i].num_reorder_pics = get_ue_golomb_long(gb);
- sps->temporal_layer[i].max_latency_increase = get_ue_golomb_long(gb) - 1;
- if (sps->temporal_layer[i].max_dec_pic_buffering > MAX_DPB_SIZE) {
- av_log(avctx, AV_LOG_ERROR, "sps_max_dec_pic_buffering_minus1 out of range: %d\n",
- sps->temporal_layer[i].max_dec_pic_buffering - 1);
- return AVERROR_INVALIDDATA;
- }
- if (sps->temporal_layer[i].num_reorder_pics > sps->temporal_layer[i].max_dec_pic_buffering - 1) {
- av_log(avctx, AV_LOG_WARNING, "sps_max_num_reorder_pics out of range: %d\n",
- sps->temporal_layer[i].num_reorder_pics);
- if (avctx->err_recognition & AV_EF_EXPLODE ||
- sps->temporal_layer[i].num_reorder_pics > MAX_DPB_SIZE - 1) {
- return AVERROR_INVALIDDATA;
- }
- sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[i].num_reorder_pics + 1;
- }
- }
-
- if (!sublayer_ordering_info) {
- for (i = 0; i < start; i++) {
- sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[start].max_dec_pic_buffering;
- sps->temporal_layer[i].num_reorder_pics = sps->temporal_layer[start].num_reorder_pics;
- sps->temporal_layer[i].max_latency_increase = sps->temporal_layer[start].max_latency_increase;
- }
- }
-
- sps->log2_min_cb_size = get_ue_golomb_long(gb) + 3;
- sps->log2_diff_max_min_coding_block_size = get_ue_golomb_long(gb);
- sps->log2_min_tb_size = get_ue_golomb_long(gb) + 2;
- log2_diff_max_min_transform_block_size = get_ue_golomb_long(gb);
- sps->log2_max_trafo_size = log2_diff_max_min_transform_block_size +
- sps->log2_min_tb_size;
-
- if (sps->log2_min_cb_size < 3 || sps->log2_min_cb_size > 30) {
- av_log(avctx, AV_LOG_ERROR, "Invalid value %d for log2_min_cb_size", sps->log2_min_cb_size);
- return AVERROR_INVALIDDATA;
- }
-
- if (sps->log2_diff_max_min_coding_block_size > 30) {
- av_log(avctx, AV_LOG_ERROR, "Invalid value %d for log2_diff_max_min_coding_block_size", sps->log2_diff_max_min_coding_block_size);
- return AVERROR_INVALIDDATA;
- }
-
- if (sps->log2_min_tb_size >= sps->log2_min_cb_size || sps->log2_min_tb_size < 2) {
- av_log(avctx, AV_LOG_ERROR, "Invalid value for log2_min_tb_size");
- return AVERROR_INVALIDDATA;
- }
-
- if (log2_diff_max_min_transform_block_size < 0 || log2_diff_max_min_transform_block_size > 30) {
- av_log(avctx, AV_LOG_ERROR, "Invalid value %d for log2_diff_max_min_transform_block_size", log2_diff_max_min_transform_block_size);
- return AVERROR_INVALIDDATA;
- }
-
- sps->max_transform_hierarchy_depth_inter = get_ue_golomb_long(gb);
- sps->max_transform_hierarchy_depth_intra = get_ue_golomb_long(gb);
-
- sps->scaling_list_enable_flag = get_bits1(gb);
- if (sps->scaling_list_enable_flag) {
- set_default_scaling_list_data(&sps->scaling_list);
-
- if (get_bits1(gb)) {
- ret = scaling_list_data(gb, avctx, &sps->scaling_list, sps);
- if (ret < 0)
- return ret;
- }
- }
-
- sps->amp_enabled_flag = get_bits1(gb);
- sps->sao_enabled = get_bits1(gb);
-
- sps->pcm_enabled_flag = get_bits1(gb);
- if (sps->pcm_enabled_flag) {
- sps->pcm.bit_depth = get_bits(gb, 4) + 1;
- sps->pcm.bit_depth_chroma = get_bits(gb, 4) + 1;
- sps->pcm.log2_min_pcm_cb_size = get_ue_golomb_long(gb) + 3;
- sps->pcm.log2_max_pcm_cb_size = sps->pcm.log2_min_pcm_cb_size +
- get_ue_golomb_long(gb);
- if (sps->pcm.bit_depth > sps->bit_depth) {
- av_log(avctx, AV_LOG_ERROR,
- "PCM bit depth (%d) is greater than normal bit depth (%d)\n",
- sps->pcm.bit_depth, sps->bit_depth);
- return AVERROR_INVALIDDATA;
- }
-
- sps->pcm.loop_filter_disable_flag = get_bits1(gb);
- }
-
- sps->nb_st_rps = get_ue_golomb_long(gb);
- if (sps->nb_st_rps > MAX_SHORT_TERM_RPS_COUNT) {
- av_log(avctx, AV_LOG_ERROR, "Too many short term RPS: %d.\n",
- sps->nb_st_rps);
- return AVERROR_INVALIDDATA;
- }
- for (i = 0; i < sps->nb_st_rps; i++) {
- if ((ret = ff_hevc_decode_short_term_rps(gb, avctx, &sps->st_rps[i],
- sps, 0)) < 0)
- return ret;
- }
-
- sps->long_term_ref_pics_present_flag = get_bits1(gb);
- if (sps->long_term_ref_pics_present_flag) {
- sps->num_long_term_ref_pics_sps = get_ue_golomb_long(gb);
- if (sps->num_long_term_ref_pics_sps > 31U) {
- av_log(avctx, AV_LOG_ERROR, "num_long_term_ref_pics_sps %d is out of range.\n",
- sps->num_long_term_ref_pics_sps);
- return AVERROR_INVALIDDATA;
- }
- for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
- sps->lt_ref_pic_poc_lsb_sps[i] = get_bits(gb, sps->log2_max_poc_lsb);
- sps->used_by_curr_pic_lt_sps_flag[i] = get_bits1(gb);
- }
- }
-
- sps->sps_temporal_mvp_enabled_flag = get_bits1(gb);
- sps->sps_strong_intra_smoothing_enable_flag = get_bits1(gb);
- sps->vui.sar = (AVRational){0, 1};
- vui_present = get_bits1(gb);
- if (vui_present)
- decode_vui(gb, avctx, apply_defdispwin, sps);
-
- if (get_bits1(gb)) { // sps_extension_flag
- int sps_extension_flag[1];
- for (i = 0; i < 1; i++)
- sps_extension_flag[i] = get_bits1(gb);
- skip_bits(gb, 7); //sps_extension_7bits = get_bits(gb, 7);
- if (sps_extension_flag[0]) {
- int extended_precision_processing_flag;
- int high_precision_offsets_enabled_flag;
- int cabac_bypass_alignment_enabled_flag;
-
- sps->transform_skip_rotation_enabled_flag = get_bits1(gb);
- sps->transform_skip_context_enabled_flag = get_bits1(gb);
- sps->implicit_rdpcm_enabled_flag = get_bits1(gb);
-
- sps->explicit_rdpcm_enabled_flag = get_bits1(gb);
-
- extended_precision_processing_flag = get_bits1(gb);
- if (extended_precision_processing_flag)
- av_log(avctx, AV_LOG_WARNING,
- "extended_precision_processing_flag not yet implemented\n");
-
- sps->intra_smoothing_disabled_flag = get_bits1(gb);
- high_precision_offsets_enabled_flag = get_bits1(gb);
- if (high_precision_offsets_enabled_flag)
- av_log(avctx, AV_LOG_WARNING,
- "high_precision_offsets_enabled_flag not yet implemented\n");
-
- sps->persistent_rice_adaptation_enabled_flag = get_bits1(gb);
-
- cabac_bypass_alignment_enabled_flag = get_bits1(gb);
- if (cabac_bypass_alignment_enabled_flag)
- av_log(avctx, AV_LOG_WARNING,
- "cabac_bypass_alignment_enabled_flag not yet implemented\n");
- }
- }
- if (apply_defdispwin) {
- sps->output_window.left_offset += sps->vui.def_disp_win.left_offset;
- sps->output_window.right_offset += sps->vui.def_disp_win.right_offset;
- sps->output_window.top_offset += sps->vui.def_disp_win.top_offset;
- sps->output_window.bottom_offset += sps->vui.def_disp_win.bottom_offset;
- }
- if (sps->output_window.left_offset & (0x1F >> (sps->pixel_shift)) &&
- !(avctx->flags & AV_CODEC_FLAG_UNALIGNED)) {
- sps->output_window.left_offset &= ~(0x1F >> (sps->pixel_shift));
- av_log(avctx, AV_LOG_WARNING, "Reducing left output window to %d "
- "chroma samples to preserve alignment.\n",
- sps->output_window.left_offset);
- }
- sps->output_width = sps->width -
- (sps->output_window.left_offset + sps->output_window.right_offset);
- sps->output_height = sps->height -
- (sps->output_window.top_offset + sps->output_window.bottom_offset);
- if (sps->width <= sps->output_window.left_offset + (int64_t)sps->output_window.right_offset ||
- sps->height <= sps->output_window.top_offset + (int64_t)sps->output_window.bottom_offset) {
- av_log(avctx, AV_LOG_WARNING, "Invalid visible frame dimensions: %dx%d.\n",
- sps->output_width, sps->output_height);
- if (avctx->err_recognition & AV_EF_EXPLODE) {
- return AVERROR_INVALIDDATA;
- }
- av_log(avctx, AV_LOG_WARNING,
- "Displaying the whole video surface.\n");
- memset(&sps->pic_conf_win, 0, sizeof(sps->pic_conf_win));
- memset(&sps->output_window, 0, sizeof(sps->output_window));
- sps->output_width = sps->width;
- sps->output_height = sps->height;
- }
-
- // Inferred parameters
- sps->log2_ctb_size = sps->log2_min_cb_size +
- sps->log2_diff_max_min_coding_block_size;
- sps->log2_min_pu_size = sps->log2_min_cb_size - 1;
-
- if (sps->log2_ctb_size > MAX_LOG2_CTB_SIZE) {
- av_log(avctx, AV_LOG_ERROR, "CTB size out of range: 2^%d\n", sps->log2_ctb_size);
- return AVERROR_INVALIDDATA;
- }
- if (sps->log2_ctb_size < 4) {
- av_log(avctx,
- AV_LOG_ERROR,
- "log2_ctb_size %d differs from the bounds of any known profile\n",
- sps->log2_ctb_size);
- avpriv_request_sample(avctx, "log2_ctb_size %d", sps->log2_ctb_size);
- return AVERROR_INVALIDDATA;
- }
-
- sps->ctb_width = (sps->width + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;
- sps->ctb_height = (sps->height + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;
- sps->ctb_size = sps->ctb_width * sps->ctb_height;
-
- sps->min_cb_width = sps->width >> sps->log2_min_cb_size;
- sps->min_cb_height = sps->height >> sps->log2_min_cb_size;
- sps->min_tb_width = sps->width >> sps->log2_min_tb_size;
- sps->min_tb_height = sps->height >> sps->log2_min_tb_size;
- sps->min_pu_width = sps->width >> sps->log2_min_pu_size;
- sps->min_pu_height = sps->height >> sps->log2_min_pu_size;
- sps->tb_mask = (1 << (sps->log2_ctb_size - sps->log2_min_tb_size)) - 1;
-
- sps->qp_bd_offset = 6 * (sps->bit_depth - 8);
-
- if (av_mod_uintp2(sps->width, sps->log2_min_cb_size) ||
- av_mod_uintp2(sps->height, sps->log2_min_cb_size)) {
- av_log(avctx, AV_LOG_ERROR, "Invalid coded frame dimensions.\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (sps->max_transform_hierarchy_depth_inter > sps->log2_ctb_size - sps->log2_min_tb_size) {
- av_log(avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_inter out of range: %d\n",
- sps->max_transform_hierarchy_depth_inter);
- return AVERROR_INVALIDDATA;
- }
- if (sps->max_transform_hierarchy_depth_intra > sps->log2_ctb_size - sps->log2_min_tb_size) {
- av_log(avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_intra out of range: %d\n",
- sps->max_transform_hierarchy_depth_intra);
- return AVERROR_INVALIDDATA;
- }
- if (sps->log2_max_trafo_size > FFMIN(sps->log2_ctb_size, 5)) {
- av_log(avctx, AV_LOG_ERROR,
- "max transform block size out of range: %d\n",
- sps->log2_max_trafo_size);
- return AVERROR_INVALIDDATA;
- }
-
- if (get_bits_left(gb) < 0) {
- av_log(avctx, AV_LOG_ERROR,
- "Overread SPS by %d bits\n", -get_bits_left(gb));
- return AVERROR_INVALIDDATA;
- }
-
- return 0;
-}
-
-int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx,
- HEVCParamSets *ps, int apply_defdispwin)
-{
- HEVCSPS *sps;
- AVBufferRef *sps_buf = av_buffer_allocz(sizeof(*sps));
- unsigned int sps_id;
- int ret;
-
- if (!sps_buf)
- return AVERROR(ENOMEM);
- sps = (HEVCSPS*)sps_buf->data;
-
- av_log(avctx, AV_LOG_DEBUG, "Decoding SPS\n");
-
- ret = ff_hevc_parse_sps(sps, gb, &sps_id,
- apply_defdispwin,
- ps->vps_list, avctx);
- if (ret < 0) {
- av_buffer_unref(&sps_buf);
- return ret;
- }
-
- if (avctx->debug & FF_DEBUG_BITSTREAM) {
- av_log(avctx, AV_LOG_DEBUG,
- "Parsed SPS: id %d; coded wxh: %dx%d; "
- "cropped wxh: %dx%d; pix_fmt: %s.\n",
- sps_id, sps->width, sps->height,
- sps->output_width, sps->output_height,
- av_get_pix_fmt_name(sps->pix_fmt));
- }
-
- /* check if this is a repeat of an already parsed SPS, then keep the
- * original one.
- * otherwise drop all PPSes that depend on it */
- if (ps->sps_list[sps_id] &&
- !memcmp(ps->sps_list[sps_id]->data, sps_buf->data, sps_buf->size)) {
- av_buffer_unref(&sps_buf);
- } else {
- remove_sps(ps, sps_id);
- ps->sps_list[sps_id] = sps_buf;
- }
-
- return 0;
-}
-
-static void hevc_pps_free(void *opaque, uint8_t *data)
-{
- HEVCPPS *pps = (HEVCPPS*)data;
-
- av_freep(&pps->column_width);
- av_freep(&pps->row_height);
- av_freep(&pps->col_bd);
- av_freep(&pps->row_bd);
- av_freep(&pps->col_idxX);
- av_freep(&pps->ctb_addr_rs_to_ts);
- av_freep(&pps->ctb_addr_ts_to_rs);
- av_freep(&pps->tile_pos_rs);
- av_freep(&pps->tile_id);
- av_freep(&pps->min_tb_addr_zs_tab);
-
- av_freep(&pps);
-}
-
-static int pps_range_extensions(GetBitContext *gb, AVCodecContext *avctx,
- HEVCPPS *pps, HEVCSPS *sps) {
- int i;
-
- if (pps->transform_skip_enabled_flag) {
- pps->log2_max_transform_skip_block_size = get_ue_golomb_long(gb) + 2;
- }
- pps->cross_component_prediction_enabled_flag = get_bits1(gb);
- pps->chroma_qp_offset_list_enabled_flag = get_bits1(gb);
- if (pps->chroma_qp_offset_list_enabled_flag) {
- pps->diff_cu_chroma_qp_offset_depth = get_ue_golomb_long(gb);
- pps->chroma_qp_offset_list_len_minus1 = get_ue_golomb_long(gb);
- if (pps->chroma_qp_offset_list_len_minus1 && pps->chroma_qp_offset_list_len_minus1 >= 5) {
- av_log(avctx, AV_LOG_ERROR,
- "chroma_qp_offset_list_len_minus1 shall be in the range [0, 5].\n");
- return AVERROR_INVALIDDATA;
- }
- for (i = 0; i <= pps->chroma_qp_offset_list_len_minus1; i++) {
- pps->cb_qp_offset_list[i] = get_se_golomb_long(gb);
- if (pps->cb_qp_offset_list[i]) {
- av_log(avctx, AV_LOG_WARNING,
- "cb_qp_offset_list not tested yet.\n");
- }
- pps->cr_qp_offset_list[i] = get_se_golomb_long(gb);
- if (pps->cr_qp_offset_list[i]) {
- av_log(avctx, AV_LOG_WARNING,
- "cb_qp_offset_list not tested yet.\n");
- }
- }
- }
- pps->log2_sao_offset_scale_luma = get_ue_golomb_long(gb);
- pps->log2_sao_offset_scale_chroma = get_ue_golomb_long(gb);
-
- return(0);
-}
-
-static inline int setup_pps(AVCodecContext *avctx, GetBitContext *gb,
- HEVCPPS *pps, HEVCSPS *sps)
-{
- int log2_diff;
- int pic_area_in_ctbs;
- int i, j, x, y, ctb_addr_rs, tile_id;
-
- // Inferred parameters
- pps->col_bd = av_malloc_array(pps->num_tile_columns + 1, sizeof(*pps->col_bd));
- pps->row_bd = av_malloc_array(pps->num_tile_rows + 1, sizeof(*pps->row_bd));
- pps->col_idxX = av_malloc_array(sps->ctb_width, sizeof(*pps->col_idxX));
- if (!pps->col_bd || !pps->row_bd || !pps->col_idxX)
- return AVERROR(ENOMEM);
-
- if (pps->uniform_spacing_flag) {
- if (!pps->column_width) {
- pps->column_width = av_malloc_array(pps->num_tile_columns, sizeof(*pps->column_width));
- pps->row_height = av_malloc_array(pps->num_tile_rows, sizeof(*pps->row_height));
- }
- if (!pps->column_width || !pps->row_height)
- return AVERROR(ENOMEM);
-
- for (i = 0; i < pps->num_tile_columns; i++) {
- pps->column_width[i] = ((i + 1) * sps->ctb_width) / pps->num_tile_columns -
- (i * sps->ctb_width) / pps->num_tile_columns;
- }
-
- for (i = 0; i < pps->num_tile_rows; i++) {
- pps->row_height[i] = ((i + 1) * sps->ctb_height) / pps->num_tile_rows -
- (i * sps->ctb_height) / pps->num_tile_rows;
- }
- }
-
- pps->col_bd[0] = 0;
- for (i = 0; i < pps->num_tile_columns; i++)
- pps->col_bd[i + 1] = pps->col_bd[i] + pps->column_width[i];
-
- pps->row_bd[0] = 0;
- for (i = 0; i < pps->num_tile_rows; i++)
- pps->row_bd[i + 1] = pps->row_bd[i] + pps->row_height[i];
-
- for (i = 0, j = 0; i < sps->ctb_width; i++) {
- if (i > pps->col_bd[j])
- j++;
- pps->col_idxX[i] = j;
- }
-
- /**
- * 6.5
- */
- pic_area_in_ctbs = sps->ctb_width * sps->ctb_height;
-
- pps->ctb_addr_rs_to_ts = av_malloc_array(pic_area_in_ctbs, sizeof(*pps->ctb_addr_rs_to_ts));
- pps->ctb_addr_ts_to_rs = av_malloc_array(pic_area_in_ctbs, sizeof(*pps->ctb_addr_ts_to_rs));
- pps->tile_id = av_malloc_array(pic_area_in_ctbs, sizeof(*pps->tile_id));
- pps->min_tb_addr_zs_tab = av_malloc_array((sps->tb_mask+2) * (sps->tb_mask+2), sizeof(*pps->min_tb_addr_zs_tab));
- if (!pps->ctb_addr_rs_to_ts || !pps->ctb_addr_ts_to_rs ||
- !pps->tile_id || !pps->min_tb_addr_zs_tab) {
- return AVERROR(ENOMEM);
- }
-
- for (ctb_addr_rs = 0; ctb_addr_rs < pic_area_in_ctbs; ctb_addr_rs++) {
- int tb_x = ctb_addr_rs % sps->ctb_width;
- int tb_y = ctb_addr_rs / sps->ctb_width;
- int tile_x = 0;
- int tile_y = 0;
- int val = 0;
-
- for (i = 0; i < pps->num_tile_columns; i++) {
- if (tb_x < pps->col_bd[i + 1]) {
- tile_x = i;
- break;
- }
- }
-
- for (i = 0; i < pps->num_tile_rows; i++) {
- if (tb_y < pps->row_bd[i + 1]) {
- tile_y = i;
- break;
- }
- }
-
- for (i = 0; i < tile_x; i++)
- val += pps->row_height[tile_y] * pps->column_width[i];
- for (i = 0; i < tile_y; i++)
- val += sps->ctb_width * pps->row_height[i];
-
- val += (tb_y - pps->row_bd[tile_y]) * pps->column_width[tile_x] +
- tb_x - pps->col_bd[tile_x];
-
- pps->ctb_addr_rs_to_ts[ctb_addr_rs] = val;
- pps->ctb_addr_ts_to_rs[val] = ctb_addr_rs;
- }
-
- for (j = 0, tile_id = 0; j < pps->num_tile_rows; j++)
- for (i = 0; i < pps->num_tile_columns; i++, tile_id++)
- for (y = pps->row_bd[j]; y < pps->row_bd[j + 1]; y++)
- for (x = pps->col_bd[i]; x < pps->col_bd[i + 1]; x++)
- pps->tile_id[pps->ctb_addr_rs_to_ts[y * sps->ctb_width + x]] = tile_id;
-
- pps->tile_pos_rs = av_malloc_array(tile_id, sizeof(*pps->tile_pos_rs));
- if (!pps->tile_pos_rs)
- return AVERROR(ENOMEM);
-
- for (j = 0; j < pps->num_tile_rows; j++)
- for (i = 0; i < pps->num_tile_columns; i++)
- pps->tile_pos_rs[j * pps->num_tile_columns + i] =
- pps->row_bd[j] * sps->ctb_width + pps->col_bd[i];
-
- log2_diff = sps->log2_ctb_size - sps->log2_min_tb_size;
- pps->min_tb_addr_zs = &pps->min_tb_addr_zs_tab[1*(sps->tb_mask+2)+1];
- for (y = 0; y < sps->tb_mask+2; y++) {
- pps->min_tb_addr_zs_tab[y*(sps->tb_mask+2)] = -1;
- pps->min_tb_addr_zs_tab[y] = -1;
- }
- for (y = 0; y < sps->tb_mask+1; y++) {
- for (x = 0; x < sps->tb_mask+1; x++) {
- int tb_x = x >> log2_diff;
- int tb_y = y >> log2_diff;
- int rs = sps->ctb_width * tb_y + tb_x;
- int val = pps->ctb_addr_rs_to_ts[rs] << (log2_diff * 2);
- for (i = 0; i < log2_diff; i++) {
- int m = 1 << i;
- val += (m & x ? m * m : 0) + (m & y ? 2 * m * m : 0);
- }
- pps->min_tb_addr_zs[y * (sps->tb_mask+2) + x] = val;
- }
- }
-
- return 0;
-}
-
-int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx,
- HEVCParamSets *ps)
-{
- HEVCSPS *sps = NULL;
- int i, ret = 0;
- unsigned int pps_id = 0;
-
- AVBufferRef *pps_buf;
- HEVCPPS *pps = av_mallocz(sizeof(*pps));
-
- if (!pps)
- return AVERROR(ENOMEM);
-
- pps_buf = av_buffer_create((uint8_t *)pps, sizeof(*pps),
- hevc_pps_free, NULL, 0);
- if (!pps_buf) {
- av_freep(&pps);
- return AVERROR(ENOMEM);
- }
-
- av_log(avctx, AV_LOG_DEBUG, "Decoding PPS\n");
-
- // Default values
- pps->loop_filter_across_tiles_enabled_flag = 1;
- pps->num_tile_columns = 1;
- pps->num_tile_rows = 1;
- pps->uniform_spacing_flag = 1;
- pps->disable_dbf = 0;
- pps->beta_offset = 0;
- pps->tc_offset = 0;
- pps->log2_max_transform_skip_block_size = 2;
-
- // Coded parameters
- pps_id = get_ue_golomb_long(gb);
- if (pps_id >= MAX_PPS_COUNT) {
- av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id);
- ret = AVERROR_INVALIDDATA;
- goto err;
- }
- pps->sps_id = get_ue_golomb_long(gb);
- if (pps->sps_id >= MAX_SPS_COUNT) {
- av_log(avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", pps->sps_id);
- ret = AVERROR_INVALIDDATA;
- goto err;
- }
- if (!ps->sps_list[pps->sps_id]) {
- av_log(avctx, AV_LOG_ERROR, "SPS %u does not exist.\n", pps->sps_id);
- ret = AVERROR_INVALIDDATA;
- goto err;
- }
- sps = (HEVCSPS *)ps->sps_list[pps->sps_id]->data;
-
- pps->dependent_slice_segments_enabled_flag = get_bits1(gb);
- pps->output_flag_present_flag = get_bits1(gb);
- pps->num_extra_slice_header_bits = get_bits(gb, 3);
-
- pps->sign_data_hiding_flag = get_bits1(gb);
-
- pps->cabac_init_present_flag = get_bits1(gb);
-
- pps->num_ref_idx_l0_default_active = get_ue_golomb_long(gb) + 1;
- pps->num_ref_idx_l1_default_active = get_ue_golomb_long(gb) + 1;
-
- pps->pic_init_qp_minus26 = get_se_golomb(gb);
-
- pps->constrained_intra_pred_flag = get_bits1(gb);
- pps->transform_skip_enabled_flag = get_bits1(gb);
-
- pps->cu_qp_delta_enabled_flag = get_bits1(gb);
- pps->diff_cu_qp_delta_depth = 0;
- if (pps->cu_qp_delta_enabled_flag)
- pps->diff_cu_qp_delta_depth = get_ue_golomb_long(gb);
-
- if (pps->diff_cu_qp_delta_depth < 0 ||
- pps->diff_cu_qp_delta_depth > sps->log2_diff_max_min_coding_block_size) {
- av_log(avctx, AV_LOG_ERROR, "diff_cu_qp_delta_depth %d is invalid\n",
- pps->diff_cu_qp_delta_depth);
- ret = AVERROR_INVALIDDATA;
- goto err;
- }
-
- pps->cb_qp_offset = get_se_golomb(gb);
- if (pps->cb_qp_offset < -12 || pps->cb_qp_offset > 12) {
- av_log(avctx, AV_LOG_ERROR, "pps_cb_qp_offset out of range: %d\n",
- pps->cb_qp_offset);
- ret = AVERROR_INVALIDDATA;
- goto err;
- }
- pps->cr_qp_offset = get_se_golomb(gb);
- if (pps->cr_qp_offset < -12 || pps->cr_qp_offset > 12) {
- av_log(avctx, AV_LOG_ERROR, "pps_cr_qp_offset out of range: %d\n",
- pps->cr_qp_offset);
- ret = AVERROR_INVALIDDATA;
- goto err;
- }
- pps->pic_slice_level_chroma_qp_offsets_present_flag = get_bits1(gb);
-
- pps->weighted_pred_flag = get_bits1(gb);
- pps->weighted_bipred_flag = get_bits1(gb);
-
- pps->transquant_bypass_enable_flag = get_bits1(gb);
- pps->tiles_enabled_flag = get_bits1(gb);
- pps->entropy_coding_sync_enabled_flag = get_bits1(gb);
-
- if (pps->tiles_enabled_flag) {
- pps->num_tile_columns = get_ue_golomb_long(gb) + 1;
- pps->num_tile_rows = get_ue_golomb_long(gb) + 1;
- if (pps->num_tile_columns <= 0 ||
- pps->num_tile_columns >= sps->width) {
- av_log(avctx, AV_LOG_ERROR, "num_tile_columns_minus1 out of range: %d\n",
- pps->num_tile_columns - 1);
- ret = AVERROR_INVALIDDATA;
- goto err;
- }
- if (pps->num_tile_rows <= 0 ||
- pps->num_tile_rows >= sps->height) {
- av_log(avctx, AV_LOG_ERROR, "num_tile_rows_minus1 out of range: %d\n",
- pps->num_tile_rows - 1);
- ret = AVERROR_INVALIDDATA;
- goto err;
- }
-
- pps->column_width = av_malloc_array(pps->num_tile_columns, sizeof(*pps->column_width));
- pps->row_height = av_malloc_array(pps->num_tile_rows, sizeof(*pps->row_height));
- if (!pps->column_width || !pps->row_height) {
- ret = AVERROR(ENOMEM);
- goto err;
- }
-
- pps->uniform_spacing_flag = get_bits1(gb);
- if (!pps->uniform_spacing_flag) {
- uint64_t sum = 0;
- for (i = 0; i < pps->num_tile_columns - 1; i++) {
- pps->column_width[i] = get_ue_golomb_long(gb) + 1;
- sum += pps->column_width[i];
- }
- if (sum >= sps->ctb_width) {
- av_log(avctx, AV_LOG_ERROR, "Invalid tile widths.\n");
- ret = AVERROR_INVALIDDATA;
- goto err;
- }
- pps->column_width[pps->num_tile_columns - 1] = sps->ctb_width - sum;
-
- sum = 0;
- for (i = 0; i < pps->num_tile_rows - 1; i++) {
- pps->row_height[i] = get_ue_golomb_long(gb) + 1;
- sum += pps->row_height[i];
- }
- if (sum >= sps->ctb_height) {
- av_log(avctx, AV_LOG_ERROR, "Invalid tile heights.\n");
- ret = AVERROR_INVALIDDATA;
- goto err;
- }
- pps->row_height[pps->num_tile_rows - 1] = sps->ctb_height - sum;
- }
- pps->loop_filter_across_tiles_enabled_flag = get_bits1(gb);
- }
-
- pps->seq_loop_filter_across_slices_enabled_flag = get_bits1(gb);
-
- pps->deblocking_filter_control_present_flag = get_bits1(gb);
- if (pps->deblocking_filter_control_present_flag) {
- pps->deblocking_filter_override_enabled_flag = get_bits1(gb);
- pps->disable_dbf = get_bits1(gb);
- if (!pps->disable_dbf) {
- pps->beta_offset = get_se_golomb(gb) * 2;
- pps->tc_offset = get_se_golomb(gb) * 2;
- if (pps->beta_offset/2 < -6 || pps->beta_offset/2 > 6) {
- av_log(avctx, AV_LOG_ERROR, "pps_beta_offset_div2 out of range: %d\n",
- pps->beta_offset/2);
- ret = AVERROR_INVALIDDATA;
- goto err;
- }
- if (pps->tc_offset/2 < -6 || pps->tc_offset/2 > 6) {
- av_log(avctx, AV_LOG_ERROR, "pps_tc_offset_div2 out of range: %d\n",
- pps->tc_offset/2);
- ret = AVERROR_INVALIDDATA;
- goto err;
- }
- }
- }
-
- pps->scaling_list_data_present_flag = get_bits1(gb);
- if (pps->scaling_list_data_present_flag) {
- set_default_scaling_list_data(&pps->scaling_list);
- ret = scaling_list_data(gb, avctx, &pps->scaling_list, sps);
- if (ret < 0)
- goto err;
- }
- pps->lists_modification_present_flag = get_bits1(gb);
- pps->log2_parallel_merge_level = get_ue_golomb_long(gb) + 2;
- if (pps->log2_parallel_merge_level > sps->log2_ctb_size) {
- av_log(avctx, AV_LOG_ERROR, "log2_parallel_merge_level_minus2 out of range: %d\n",
- pps->log2_parallel_merge_level - 2);
- ret = AVERROR_INVALIDDATA;
- goto err;
- }
-
- pps->slice_header_extension_present_flag = get_bits1(gb);
-
- if (get_bits1(gb)) { // pps_extension_present_flag
- int pps_range_extensions_flag = get_bits1(gb);
- /* int pps_extension_7bits = */ get_bits(gb, 7);
- if (sps->ptl.general_ptl.profile_idc == FF_PROFILE_HEVC_REXT && pps_range_extensions_flag) {
- if ((ret = pps_range_extensions(gb, avctx, pps, sps)) < 0)
- goto err;
- }
- }
-
- ret = setup_pps(avctx, gb, pps, sps);
- if (ret < 0)
- goto err;
-
- if (get_bits_left(gb) < 0) {
- av_log(avctx, AV_LOG_ERROR,
- "Overread PPS by %d bits\n", -get_bits_left(gb));
- goto err;
- }
-
- remove_pps(ps, pps_id);
- ps->pps_list[pps_id] = pps_buf;
-
- return 0;
-
-err:
- av_buffer_unref(&pps_buf);
- return ret;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/hevc_sei.c b/ffmpeg-2-8-11/libavcodec/hevc_sei.c
deleted file mode 100644
index 179b045..0000000
--- a/ffmpeg-2-8-11/libavcodec/hevc_sei.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * HEVC Supplementary Enhancement Information messages
- *
- * Copyright (C) 2012 - 2013 Guillaume Martres
- * Copyright (C) 2012 - 2013 Gildas Cocherel
- * Copyright (C) 2013 Vittorio Giovara
- *
- * 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 "golomb.h"
-#include "hevc.h"
-
-enum HEVC_SEI_TYPE {
- SEI_TYPE_BUFFERING_PERIOD = 0,
- SEI_TYPE_PICTURE_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_SCENE_INFO = 9,
- SEI_TYPE_FULL_FRAME_SNAPSHOT = 15,
- SEI_TYPE_PROGRESSIVE_REFINEMENT_SEGMENT_START = 16,
- SEI_TYPE_PROGRESSIVE_REFINEMENT_SEGMENT_END = 17,
- SEI_TYPE_FILM_GRAIN_CHARACTERISTICS = 19,
- SEI_TYPE_POST_FILTER_HINT = 22,
- SEI_TYPE_TONE_MAPPING_INFO = 23,
- SEI_TYPE_FRAME_PACKING = 45,
- SEI_TYPE_DISPLAY_ORIENTATION = 47,
- SEI_TYPE_SOP_DESCRIPTION = 128,
- SEI_TYPE_ACTIVE_PARAMETER_SETS = 129,
- SEI_TYPE_DECODING_UNIT_INFO = 130,
- SEI_TYPE_TEMPORAL_LEVEL0_INDEX = 131,
- SEI_TYPE_DECODED_PICTURE_HASH = 132,
- SEI_TYPE_SCALABLE_NESTING = 133,
- SEI_TYPE_REGION_REFRESH_INFO = 134,
- SEI_TYPE_MASTERING_DISPLAY_INFO = 137,
- SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO = 144,
-};
-
-static int decode_nal_sei_decoded_picture_hash(HEVCContext *s)
-{
- int cIdx, i;
- uint8_t hash_type;
- //uint16_t picture_crc;
- //uint32_t picture_checksum;
- GetBitContext *gb = &s->HEVClc->gb;
- hash_type = get_bits(gb, 8);
-
- for (cIdx = 0; cIdx < 3/*((s->sps->chroma_format_idc == 0) ? 1 : 3)*/; cIdx++) {
- if (hash_type == 0) {
- s->is_md5 = 1;
- for (i = 0; i < 16; i++)
- s->md5[cIdx][i] = get_bits(gb, 8);
- } else if (hash_type == 1) {
- // picture_crc = get_bits(gb, 16);
- skip_bits(gb, 16);
- } else if (hash_type == 2) {
- // picture_checksum = get_bits_long(gb, 32);
- skip_bits(gb, 32);
- }
- }
- return 0;
-}
-
-static int decode_nal_sei_frame_packing_arrangement(HEVCContext *s)
-{
- GetBitContext *gb = &s->HEVClc->gb;
-
- get_ue_golomb(gb); // frame_packing_arrangement_id
- s->sei_frame_packing_present = !get_bits1(gb);
-
- if (s->sei_frame_packing_present) {
- s->frame_packing_arrangement_type = get_bits(gb, 7);
- s->quincunx_subsampling = get_bits1(gb);
- s->content_interpretation_type = get_bits(gb, 6);
-
- // the following skips spatial_flipping_flag frame0_flipped_flag
- // field_views_flag current_frame_is_frame0_flag
- // frame0_self_contained_flag frame1_self_contained_flag
- skip_bits(gb, 6);
-
- if (!s->quincunx_subsampling && s->frame_packing_arrangement_type != 5)
- skip_bits(gb, 16); // frame[01]_grid_position_[xy]
- skip_bits(gb, 8); // frame_packing_arrangement_reserved_byte
- skip_bits1(gb); // frame_packing_arrangement_persistance_flag
- }
- skip_bits1(gb); // upsampled_aspect_ratio_flag
- return 0;
-}
-
-static int decode_nal_sei_display_orientation(HEVCContext *s)
-{
- GetBitContext *gb = &s->HEVClc->gb;
-
- s->sei_display_orientation_present = !get_bits1(gb);
-
- if (s->sei_display_orientation_present) {
- s->sei_hflip = get_bits1(gb); // hor_flip
- s->sei_vflip = get_bits1(gb); // ver_flip
-
- s->sei_anticlockwise_rotation = get_bits(gb, 16);
- skip_bits1(gb); // display_orientation_persistence_flag
- }
-
- return 0;
-}
-
-static int decode_pic_timing(HEVCContext *s)
-{
- GetBitContext *gb = &s->HEVClc->gb;
- HEVCSPS *sps;
-
- if (!s->ps.sps_list[s->active_seq_parameter_set_id])
- return(AVERROR(ENOMEM));
- sps = (HEVCSPS*)s->ps.sps_list[s->active_seq_parameter_set_id]->data;
-
- if (sps->vui.frame_field_info_present_flag) {
- int pic_struct = get_bits(gb, 4);
- s->picture_struct = AV_PICTURE_STRUCTURE_UNKNOWN;
- if (pic_struct == 2) {
- av_log(s->avctx, AV_LOG_DEBUG, "BOTTOM Field\n");
- s->picture_struct = AV_PICTURE_STRUCTURE_BOTTOM_FIELD;
- } else if (pic_struct == 1) {
- av_log(s->avctx, AV_LOG_DEBUG, "TOP Field\n");
- s->picture_struct = AV_PICTURE_STRUCTURE_TOP_FIELD;
- }
- get_bits(gb, 2); // source_scan_type
- get_bits(gb, 1); // duplicate_flag
- }
- return 1;
-}
-
-static int active_parameter_sets(HEVCContext *s)
-{
- GetBitContext *gb = &s->HEVClc->gb;
- int num_sps_ids_minus1;
- int i;
- unsigned active_seq_parameter_set_id;
-
- get_bits(gb, 4); // active_video_parameter_set_id
- get_bits(gb, 1); // self_contained_cvs_flag
- get_bits(gb, 1); // num_sps_ids_minus1
- num_sps_ids_minus1 = get_ue_golomb_long(gb); // num_sps_ids_minus1
-
- if (num_sps_ids_minus1 < 0 || num_sps_ids_minus1 > 15) {
- av_log(s->avctx, AV_LOG_ERROR, "num_sps_ids_minus1 %d invalid\n", num_sps_ids_minus1);
- return AVERROR_INVALIDDATA;
- }
-
- active_seq_parameter_set_id = get_ue_golomb_long(gb);
- if (active_seq_parameter_set_id >= MAX_SPS_COUNT) {
- av_log(s->avctx, AV_LOG_ERROR, "active_parameter_set_id %d invalid\n", active_seq_parameter_set_id);
- return AVERROR_INVALIDDATA;
- }
- s->active_seq_parameter_set_id = active_seq_parameter_set_id;
-
- for (i = 1; i <= num_sps_ids_minus1; i++)
- get_ue_golomb_long(gb); // active_seq_parameter_set_id[i]
-
- return 0;
-}
-
-static int decode_nal_sei_prefix(HEVCContext *s, int type, int size)
-{
- GetBitContext *gb = &s->HEVClc->gb;
-
- switch (type) {
- case 256: // Mismatched value from HM 8.1
- return decode_nal_sei_decoded_picture_hash(s);
- case SEI_TYPE_FRAME_PACKING:
- return decode_nal_sei_frame_packing_arrangement(s);
- case SEI_TYPE_DISPLAY_ORIENTATION:
- return decode_nal_sei_display_orientation(s);
- case SEI_TYPE_PICTURE_TIMING:
- {
- int ret = decode_pic_timing(s);
- av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
- skip_bits(gb, 8 * size);
- return ret;
- }
- case SEI_TYPE_ACTIVE_PARAMETER_SETS:
- active_parameter_sets(s);
- av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
- return 0;
- default:
- av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
- skip_bits_long(gb, 8 * size);
- return 0;
- }
-}
-
-static int decode_nal_sei_suffix(HEVCContext *s, int type, int size)
-{
- GetBitContext *gb = &s->HEVClc->gb;
-
- switch (type) {
- case SEI_TYPE_DECODED_PICTURE_HASH:
- return decode_nal_sei_decoded_picture_hash(s);
- default:
- av_log(s->avctx, AV_LOG_DEBUG, "Skipped SUFFIX SEI %d\n", type);
- skip_bits_long(gb, 8 * size);
- return 0;
- }
-}
-
-static int decode_nal_sei_message(HEVCContext *s)
-{
- GetBitContext *gb = &s->HEVClc->gb;
-
- int payload_type = 0;
- int payload_size = 0;
- int byte = 0xFF;
- av_log(s->avctx, AV_LOG_DEBUG, "Decoding SEI\n");
-
- while (byte == 0xFF) {
- byte = get_bits(gb, 8);
- payload_type += byte;
- }
- byte = 0xFF;
- while (byte == 0xFF) {
- byte = get_bits(gb, 8);
- payload_size += byte;
- }
- if (s->nal_unit_type == NAL_SEI_PREFIX) {
- return decode_nal_sei_prefix(s, payload_type, payload_size);
- } else { /* nal_unit_type == NAL_SEI_SUFFIX */
- return decode_nal_sei_suffix(s, payload_type, payload_size);
- }
- return 1;
-}
-
-static int more_rbsp_data(GetBitContext *gb)
-{
- return get_bits_left(gb) > 0 && show_bits(gb, 8) != 0x80;
-}
-
-int ff_hevc_decode_nal_sei(HEVCContext *s)
-{
- int ret;
-
- do {
- ret = decode_nal_sei_message(s);
- if (ret < 0)
- return(AVERROR(ENOMEM));
- } while (more_rbsp_data(&s->HEVClc->gb));
- return 1;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/hq_hqa.c b/ffmpeg-2-8-11/libavcodec/hq_hqa.c
deleted file mode 100644
index 3ef83d4..0000000
--- a/ffmpeg-2-8-11/libavcodec/hq_hqa.c
+++ /dev/null
@@ -1,387 +0,0 @@
-/*
- * Canopus HQ/HQA 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 <stdint.h>
-
-#include "libavutil/attributes.h"
-#include "libavutil/intreadwrite.h"
-
-#include "avcodec.h"
-#include "canopus.h"
-#include "internal.h"
-
-#include "hq_hqa.h"
-#include "hq_hqadsp.h"
-
-/* HQ/HQA slices are a set of macroblocks belonging to a frame, and
- * they usually form a pseudorandom pattern (probably because it is
- * nicer to display on partial decode).
- *
- * For HQA it just happens that each slice is on every 8th macroblock,
- * but they can be on any frame width like
- * X.......X.
- * ......X...
- * ....X.....
- * ..X.......
- * etc.
- *
- * The original decoder has special handling for edge macroblocks,
- * while lavc simply aligns coded_width and coded_height.
- */
-
-static inline void put_blocks(HQContext *c, AVFrame *pic,
- int plane, int x, int y, int ilace,
- int16_t *block0, int16_t *block1)
-{
- uint8_t *p = pic->data[plane] + x;
-
- c->hqhqadsp.idct_put(p + y * pic->linesize[plane],
- pic->linesize[plane] << ilace, block0);
- c->hqhqadsp.idct_put(p + (y + (ilace ? 1 : 8)) * pic->linesize[plane],
- pic->linesize[plane] << ilace, block1);
-}
-
-static int hq_decode_block(HQContext *c, GetBitContext *gb, int16_t block[64],
- int qsel, int is_chroma, int is_hqa)
-{
- const int32_t *q;
- int val, pos = 1;
-
- memset(block, 0, 64 * sizeof(*block));
-
- if (!is_hqa) {
- block[0] = get_sbits(gb, 9) << 6;
- q = ff_hq_quants[qsel][is_chroma][get_bits(gb, 2)];
- } else {
- q = ff_hq_quants[qsel][is_chroma][get_bits(gb, 2)];
- block[0] = get_sbits(gb, 9) << 6;
- }
-
- for (;;) {
- val = get_vlc2(gb, c->hq_ac_vlc.table, 9, 2);
- if (val < 0)
- return AVERROR_INVALIDDATA;
-
- pos += ff_hq_ac_skips[val];
- if (pos >= 64)
- break;
- block[ff_zigzag_direct[pos]] = (ff_hq_ac_syms[val] * q[pos]) >> 12;
- pos++;
- }
-
- return 0;
-}
-
-static int hq_decode_mb(HQContext *c, AVFrame *pic,
- GetBitContext *gb, int x, int y)
-{
- int qgroup, flag;
- int i, ret;
-
- qgroup = get_bits(gb, 4);
- flag = get_bits1(gb);
-
- for (i = 0; i < 8; i++) {
- ret = hq_decode_block(c, gb, c->block[i], qgroup, i >= 4, 0);
- if (ret < 0)
- return ret;
- }
-
- put_blocks(c, pic, 0, x, y, flag, c->block[0], c->block[2]);
- put_blocks(c, pic, 0, x + 8, y, flag, c->block[1], c->block[3]);
- put_blocks(c, pic, 2, x >> 1, y, flag, c->block[4], c->block[5]);
- put_blocks(c, pic, 1, x >> 1, y, flag, c->block[6], c->block[7]);
-
- return 0;
-}
-
-static int hq_decode_frame(HQContext *ctx, AVFrame *pic,
- int prof_num, size_t data_size)
-{
- const HQProfile *profile;
- GetBitContext gb;
- const uint8_t *perm, *src = ctx->gbc.buffer;
- uint32_t slice_off[21];
- int slice, start_off, next_off, i, ret;
-
- if ((unsigned)prof_num >= NUM_HQ_PROFILES) {
- profile = &ff_hq_profile[0];
- avpriv_request_sample(ctx->avctx, "HQ Profile %d", prof_num);
- } else {
- profile = &ff_hq_profile[prof_num];
- av_log(ctx->avctx, AV_LOG_VERBOSE, "HQ Profile %d\n", prof_num);
- }
-
- ctx->avctx->coded_width = FFALIGN(profile->width, 16);
- ctx->avctx->coded_height = FFALIGN(profile->height, 16);
- ctx->avctx->width = profile->width;
- ctx->avctx->height = profile->height;
- ctx->avctx->bits_per_raw_sample = 8;
- ctx->avctx->pix_fmt = AV_PIX_FMT_YUV422P;
-
- ret = ff_get_buffer(ctx->avctx, pic, 0);
- if (ret < 0)
- return ret;
-
- /* Offsets are stored from CUV position, so adjust them accordingly. */
- for (i = 0; i < profile->num_slices + 1; i++)
- slice_off[i] = bytestream2_get_be24(&ctx->gbc) - 4;
-
- next_off = 0;
- for (slice = 0; slice < profile->num_slices; slice++) {
- start_off = next_off;
- next_off = profile->tab_h * (slice + 1) / profile->num_slices;
- perm = profile->perm_tab + start_off * profile->tab_w * 2;
-
- if (slice_off[slice] < (profile->num_slices + 1) * 3 ||
- slice_off[slice] >= slice_off[slice + 1] ||
- slice_off[slice + 1] > data_size) {
- av_log(ctx->avctx, AV_LOG_ERROR,
- "Invalid slice size %zu.\n", data_size);
- break;
- }
- init_get_bits(&gb, src + slice_off[slice],
- (slice_off[slice + 1] - slice_off[slice]) * 8);
-
- for (i = 0; i < (next_off - start_off) * profile->tab_w; i++) {
- ret = hq_decode_mb(ctx, pic, &gb, perm[0] * 16, perm[1] * 16);
- if (ret < 0) {
- av_log(ctx->avctx, AV_LOG_ERROR,
- "Error decoding macroblock %d at slice %d.\n", i, slice);
- return ret;
- }
- perm += 2;
- }
- }
-
- return 0;
-}
-
-static int hqa_decode_mb(HQContext *c, AVFrame *pic, int qgroup,
- GetBitContext *gb, int x, int y)
-{
- int flag = 0;
- int i, ret, cbp;
-
- cbp = get_vlc2(gb, c->hqa_cbp_vlc.table, 5, 1);
-
- for (i = 0; i < 12; i++)
- memset(c->block[i], 0, sizeof(*c->block));
- for (i = 0; i < 12; i++)
- c->block[i][0] = -128 * (1 << 6);
-
- if (cbp) {
- flag = get_bits1(gb);
-
- cbp |= cbp << 4;
- if (cbp & 0x3)
- cbp |= 0x500;
- if (cbp & 0xC)
- cbp |= 0xA00;
- for (i = 0; i < 12; i++) {
- if (!(cbp & (1 << i)))
- continue;
- ret = hq_decode_block(c, gb, c->block[i], qgroup, i >= 8, 1);
- if (ret < 0)
- return ret;
- }
- }
-
- put_blocks(c, pic, 3, x, y, flag, c->block[ 0], c->block[ 2]);
- put_blocks(c, pic, 3, x + 8, y, flag, c->block[ 1], c->block[ 3]);
- put_blocks(c, pic, 0, x, y, flag, c->block[ 4], c->block[ 6]);
- put_blocks(c, pic, 0, x + 8, y, flag, c->block[ 5], c->block[ 7]);
- put_blocks(c, pic, 2, x >> 1, y, flag, c->block[ 8], c->block[ 9]);
- put_blocks(c, pic, 1, x >> 1, y, flag, c->block[10], c->block[11]);
-
- return 0;
-}
-
-static int hqa_decode_slice(HQContext *ctx, AVFrame *pic, GetBitContext *gb,
- int quant, int slice_no, int w, int h)
-{
- int i, j, off;
- int ret;
-
- for (i = 0; i < h; i += 16) {
- off = (slice_no * 16 + i * 3) & 0x70;
- for (j = off; j < w; j += 128) {
- ret = hqa_decode_mb(ctx, pic, quant, gb, j, i);
- if (ret < 0) {
- av_log(ctx->avctx, AV_LOG_ERROR,
- "Error decoding macroblock at %dx%d.\n", i, j);
- return ret;
- }
- }
- }
-
- return 0;
-}
-
-static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, size_t data_size)
-{
- GetBitContext gb;
- const int num_slices = 8;
- uint32_t slice_off[9];
- int i, slice, ret;
- int width, height, quant;
- const uint8_t *src = ctx->gbc.buffer;
-
- width = bytestream2_get_be16(&ctx->gbc);
- height = bytestream2_get_be16(&ctx->gbc);
-
- ctx->avctx->coded_width = FFALIGN(width, 16);
- ctx->avctx->coded_height = FFALIGN(height, 16);
- ctx->avctx->width = width;
- ctx->avctx->height = height;
- ctx->avctx->bits_per_raw_sample = 8;
- ctx->avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
-
- av_log(ctx->avctx, AV_LOG_VERBOSE, "HQA Profile\n");
-
- quant = bytestream2_get_byte(&ctx->gbc);
- bytestream2_skip(&ctx->gbc, 3);
- if (quant >= NUM_HQ_QUANTS) {
- av_log(ctx->avctx, AV_LOG_ERROR,
- "Invalid quantization matrix %d.\n", quant);
- return AVERROR_INVALIDDATA;
- }
-
- ret = ff_get_buffer(ctx->avctx, pic, 0);
- if (ret < 0)
- return ret;
-
- /* Offsets are stored from HQA1 position, so adjust them accordingly. */
- for (i = 0; i < num_slices + 1; i++)
- slice_off[i] = bytestream2_get_be32(&ctx->gbc) - 4;
-
- for (slice = 0; slice < num_slices; slice++) {
- if (slice_off[slice] < (num_slices + 1) * 3 ||
- slice_off[slice] >= slice_off[slice + 1] ||
- slice_off[slice + 1] > data_size) {
- av_log(ctx->avctx, AV_LOG_ERROR,
- "Invalid slice size %zu.\n", data_size);
- break;
- }
- init_get_bits(&gb, src + slice_off[slice],
- (slice_off[slice + 1] - slice_off[slice]) * 8);
-
- ret = hqa_decode_slice(ctx, pic, &gb, quant, slice, width, height);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
-static int hq_hqa_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame, AVPacket *avpkt)
-{
- HQContext *ctx = avctx->priv_data;
- AVFrame *pic = data;
- uint32_t info_tag;
- unsigned int data_size;
- int ret;
- unsigned tag;
-
- bytestream2_init(&ctx->gbc, avpkt->data, avpkt->size);
- if (bytestream2_get_bytes_left(&ctx->gbc) < 4 + 4) {
- av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", avpkt->size);
- return AVERROR_INVALIDDATA;
- }
-
- info_tag = bytestream2_peek_le32(&ctx->gbc);
- if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
- int info_size;
- bytestream2_skip(&ctx->gbc, 4);
- info_size = bytestream2_get_le32(&ctx->gbc);
- if (bytestream2_get_bytes_left(&ctx->gbc) < info_size) {
- av_log(avctx, AV_LOG_ERROR, "Invalid INFO size (%d).\n", info_size);
- return AVERROR_INVALIDDATA;
- }
- ff_canopus_parse_info_tag(avctx, ctx->gbc.buffer, info_size);
-
- bytestream2_skip(&ctx->gbc, info_size);
- }
-
- data_size = bytestream2_get_bytes_left(&ctx->gbc);
- if (data_size < 4) {
- av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", data_size);
- return AVERROR_INVALIDDATA;
- }
-
- /* HQ defines dimensions and number of slices, and thus slice traversal
- * order. HQA has no size constraint and a fixed number of slices, so it
- * needs a separate scheme for it. */
- tag = bytestream2_get_le32(&ctx->gbc);
- if ((tag & 0x00FFFFFF) == (MKTAG('U', 'V', 'C', ' ') & 0x00FFFFFF)) {
- ret = hq_decode_frame(ctx, pic, tag >> 24, data_size);
- } else if (tag == MKTAG('H', 'Q', 'A', '1')) {
- ret = hqa_decode_frame(ctx, pic, data_size);
- } else {
- av_log(avctx, AV_LOG_ERROR, "Not a HQ/HQA frame.\n");
- return AVERROR_INVALIDDATA;
- }
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "Error decoding frame.\n");
- return ret;
- }
-
- pic->key_frame = 1;
- pic->pict_type = AV_PICTURE_TYPE_I;
-
- *got_frame = 1;
-
- return avpkt->size;
-}
-
-static av_cold int hq_hqa_decode_init(AVCodecContext *avctx)
-{
- HQContext *ctx = avctx->priv_data;
- ctx->avctx = avctx;
-
- ff_hqdsp_init(&ctx->hqhqadsp);
-
- return ff_hq_init_vlcs(ctx);
-}
-
-static av_cold int hq_hqa_decode_close(AVCodecContext *avctx)
-{
- HQContext *ctx = avctx->priv_data;
-
- ff_free_vlc(&ctx->hq_ac_vlc);
- ff_free_vlc(&ctx->hqa_cbp_vlc);
-
- return 0;
-}
-
-AVCodec ff_hq_hqa_decoder = {
- .name = "hq_hqa",
- .long_name = NULL_IF_CONFIG_SMALL("Canopus HQ/HQA"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_HQ_HQA,
- .priv_data_size = sizeof(HQContext),
- .init = hq_hqa_decode_init,
- .decode = hq_hqa_decode_frame,
- .close = hq_hqa_decode_close,
- .capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/hqxdsp.c b/ffmpeg-2-8-11/libavcodec/hqxdsp.c
deleted file mode 100644
index feff9c0..0000000
--- a/ffmpeg-2-8-11/libavcodec/hqxdsp.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * HQX DSP routines
- *
- * 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 <stdint.h>
-
-#include "libavutil/common.h"
-
-#include "hqxdsp.h"
-
-static inline void idct_col(int16_t *blk, const uint8_t *quant)
-{
- int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, tA, tB, tC, tD, tE, tF;
- int t10, t11, t12, t13;
- int s0, s1, s2, s3, s4, s5, s6, s7;
-
- s0 = (int) blk[0 * 8] * quant[0 * 8];
- s1 = (int) blk[1 * 8] * quant[1 * 8];
- s2 = (int) blk[2 * 8] * quant[2 * 8];
- s3 = (int) blk[3 * 8] * quant[3 * 8];
- s4 = (int) blk[4 * 8] * quant[4 * 8];
- s5 = (int) blk[5 * 8] * quant[5 * 8];
- s6 = (int) blk[6 * 8] * quant[6 * 8];
- s7 = (int) blk[7 * 8] * quant[7 * 8];
-
- t0 = (s3 * 19266 + s5 * 12873) >> 15;
- t1 = (s5 * 19266 - s3 * 12873) >> 15;
- t2 = ((s7 * 4520 + s1 * 22725) >> 15) - t0;
- t3 = ((s1 * 4520 - s7 * 22725) >> 15) - t1;
- t4 = t0 * 2 + t2;
- t5 = t1 * 2 + t3;
- t6 = t2 - t3;
- t7 = t3 * 2 + t6;
- t8 = (t6 * 11585) >> 14;
- t9 = (t7 * 11585) >> 14;
- tA = (s2 * 8867 - s6 * 21407) >> 14;
- tB = (s6 * 8867 + s2 * 21407) >> 14;
- tC = (s0 >> 1) - (s4 >> 1);
- tD = (s4 >> 1) * 2 + tC;
- tE = tC - (tA >> 1);
- tF = tD - (tB >> 1);
- t10 = tF - t5;
- t11 = tE - t8;
- t12 = tE + (tA >> 1) * 2 - t9;
- t13 = tF + (tB >> 1) * 2 - t4;
-
- blk[0 * 8] = t13 + t4 * 2;
- blk[1 * 8] = t12 + t9 * 2;
- blk[2 * 8] = t11 + t8 * 2;
- blk[3 * 8] = t10 + t5 * 2;
- blk[4 * 8] = t10;
- blk[5 * 8] = t11;
- blk[6 * 8] = t12;
- blk[7 * 8] = t13;
-}
-
-static inline void idct_row(int16_t *blk)
-{
- int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, tA, tB, tC, tD, tE, tF;
- int t10, t11, t12, t13;
-
- t0 = (blk[3] * 19266 + blk[5] * 12873) >> 14;
- t1 = (blk[5] * 19266 - blk[3] * 12873) >> 14;
- t2 = ((blk[7] * 4520 + blk[1] * 22725) >> 14) - t0;
- t3 = ((blk[1] * 4520 - blk[7] * 22725) >> 14) - t1;
- t4 = t0 * 2 + t2;
- t5 = t1 * 2 + t3;
- t6 = t2 - t3;
- t7 = t3 * 2 + t6;
- t8 = (t6 * 11585) >> 14;
- t9 = (t7 * 11585) >> 14;
- tA = (blk[2] * 8867 - blk[6] * 21407) >> 14;
- tB = (blk[6] * 8867 + blk[2] * 21407) >> 14;
- tC = blk[0] - blk[4];
- tD = blk[4] * 2 + tC;
- tE = tC - tA;
- tF = tD - tB;
- t10 = tF - t5;
- t11 = tE - t8;
- t12 = tE + tA * 2 - t9;
- t13 = tF + tB * 2 - t4;
-
- blk[0] = (t13 + t4 * 2 + 4) >> 3;
- blk[1] = (t12 + t9 * 2 + 4) >> 3;
- blk[2] = (t11 + t8 * 2 + 4) >> 3;
- blk[3] = (t10 + t5 * 2 + 4) >> 3;
- blk[4] = (t10 + 4) >> 3;
- blk[5] = (t11 + 4) >> 3;
- blk[6] = (t12 + 4) >> 3;
- blk[7] = (t13 + 4) >> 3;
-}
-
-static void hqx_idct_put(uint16_t *dst, ptrdiff_t stride,
- int16_t *block, const uint8_t *quant)
-{
- int i, j;
-
- for (i = 0; i < 8; i++)
- idct_col(block + i, quant + i);
- for (i = 0; i < 8; i++)
- idct_row(block + i * 8);
-
- for (i = 0; i < 8; i++) {
- for (j = 0; j < 8; j++) {
- int v = av_clip_uintp2(block[j + i * 8] + 0x800, 12);
- dst[j] = (v << 4) | (v >> 8);
- }
- dst += stride >> 1;
- }
-}
-
-av_cold void ff_hqxdsp_init(HQXDSPContext *c)
-{
- c->idct_put = hqx_idct_put;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/indeo2.c b/ffmpeg-2-8-11/libavcodec/indeo2.c
deleted file mode 100644
index 5bf33aa..0000000
--- a/ffmpeg-2-8-11/libavcodec/indeo2.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Intel Indeo 2 codec
- * Copyright (c) 2005 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
- */
-
-/**
- * @file
- * Intel Indeo 2 decoder.
- */
-
-#define BITSTREAM_READER_LE
-#include "libavutil/attributes.h"
-#include "avcodec.h"
-#include "get_bits.h"
-#include "indeo2data.h"
-#include "internal.h"
-#include "mathops.h"
-
-typedef struct Ir2Context{
- AVCodecContext *avctx;
- AVFrame *picture;
- GetBitContext gb;
- int decode_delta;
-} Ir2Context;
-
-#define CODE_VLC_BITS 14
-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;
-}
-
-static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst,
- int pitch, const uint8_t *table)
-{
- int i;
- int j;
- int out = 0;
-
- if (width & 1)
- return AVERROR_INVALIDDATA;
-
- /* first line contain absolute values, other lines contain deltas */
- while (out < width) {
- int c = ir2_get_code(&ctx->gb);
- if (c >= 0x80) { /* we have a run */
- c -= 0x7F;
- if (out + c*2 > width)
- return AVERROR_INVALIDDATA;
- for (i = 0; i < c * 2; i++)
- dst[out++] = 0x80;
- } else { /* copy two values from table */
- dst[out++] = table[c * 2];
- dst[out++] = table[(c * 2) + 1];
- }
- }
- dst += pitch;
-
- for (j = 1; j < height; j++) {
- out = 0;
- while (out < width) {
- int c = ir2_get_code(&ctx->gb);
- if (c >= 0x80) { /* we have a skip */
- c -= 0x7F;
- if (out + c*2 > width)
- return AVERROR_INVALIDDATA;
- for (i = 0; i < c * 2; i++) {
- dst[out] = dst[out - pitch];
- out++;
- }
- } else { /* add two deltas from table */
- int t = dst[out - pitch] + (table[c * 2] - 128);
- t = av_clip_uint8(t);
- dst[out] = t;
- out++;
- t = dst[out - pitch] + (table[(c * 2) + 1] - 128);
- t = av_clip_uint8(t);
- dst[out] = t;
- out++;
- }
- }
- dst += pitch;
- }
- return 0;
-}
-
-static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst,
- int pitch, const uint8_t *table)
-{
- int j;
- int out = 0;
- int c;
- int t;
-
- if (width & 1)
- return AVERROR_INVALIDDATA;
-
- for (j = 0; j < height; j++) {
- out = 0;
- while (out < width) {
- c = ir2_get_code(&ctx->gb);
- if (c >= 0x80) { /* we have a skip */
- c -= 0x7F;
- out += c * 2;
- } else { /* add two deltas from table */
- t = dst[out] + (((table[c * 2] - 128)*3) >> 2);
- t = av_clip_uint8(t);
- dst[out] = t;
- out++;
- t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2);
- t = av_clip_uint8(t);
- dst[out] = t;
- out++;
- }
- }
- dst += pitch;
- }
- return 0;
-}
-
-static int ir2_decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- Ir2Context * const s = avctx->priv_data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- AVFrame *picture = data;
- AVFrame * const p = s->picture;
- int start, ret;
- int ltab, ctab;
-
- if ((ret = ff_reget_buffer(avctx, p)) < 0)
- return ret;
-
- start = 48; /* hardcoded for now */
-
- if (start >= buf_size) {
- av_log(s->avctx, AV_LOG_ERROR, "input buffer size too small (%d)\n", buf_size);
- return AVERROR_INVALIDDATA;
- }
-
- 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
-
- init_get_bits(&s->gb, buf + start, (buf_size - start) * 8);
-
- ltab = buf[0x22] & 3;
- ctab = buf[0x22] >> 2;
-
- if (ctab > 3) {
- av_log(avctx, AV_LOG_ERROR, "ctab %d is invalid\n", ctab);
- return AVERROR_INVALIDDATA;
- }
-
- if (s->decode_delta) { /* intraframe */
- if ((ret = ir2_decode_plane(s, avctx->width, avctx->height,
- p->data[0], p->linesize[0],
- ir2_delta_table[ltab])) < 0)
- return ret;
-
- /* swapped U and V */
- if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
- p->data[2], p->linesize[2],
- ir2_delta_table[ctab])) < 0)
- return ret;
- if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
- p->data[1], p->linesize[1],
- ir2_delta_table[ctab])) < 0)
- return ret;
- } else { /* interframe */
- if ((ret = ir2_decode_plane_inter(s, avctx->width, avctx->height,
- p->data[0], p->linesize[0],
- ir2_delta_table[ltab])) < 0)
- return ret;
- /* swapped U and V */
- if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
- p->data[2], p->linesize[2],
- ir2_delta_table[ctab])) < 0)
- return ret;
- if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
- p->data[1], p->linesize[1],
- ir2_delta_table[ctab])) < 0)
- return ret;
- }
-
- if ((ret = av_frame_ref(picture, p)) < 0)
- return ret;
-
- *got_frame = 1;
-
- return buf_size;
-}
-
-static av_cold int ir2_decode_init(AVCodecContext *avctx)
-{
- Ir2Context * const ic = avctx->priv_data;
- static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2];
-
- ic->avctx = avctx;
-
- avctx->pix_fmt= AV_PIX_FMT_YUV410P;
-
- ic->picture = av_frame_alloc();
- 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
-
- return 0;
-}
-
-static av_cold int ir2_decode_end(AVCodecContext *avctx)
-{
- Ir2Context * const ic = avctx->priv_data;
-
- av_frame_free(&ic->picture);
-
- return 0;
-}
-
-AVCodec ff_indeo2_decoder = {
- .name = "indeo2",
- .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_INDEO2,
- .priv_data_size = sizeof(Ir2Context),
- .init = ir2_decode_init,
- .close = ir2_decode_end,
- .decode = ir2_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/ituh263dec.c b/ffmpeg-2-8-11/libavcodec/ituh263dec.c
deleted file mode 100644
index 42ec1f6..0000000
--- a/ffmpeg-2-8-11/libavcodec/ituh263dec.c
+++ /dev/null
@@ -1,1161 +0,0 @@
-/*
- * ITU H263 bitstream decoder
- * Copyright (c) 2000,2001 Fabrice Bellard
- * H263+ support.
- * Copyright (c) 2001 Juan J. Sierralta P
- * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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
- * h263 decoder.
- */
-
-#define UNCHECKED_BITSTREAM_READER 1
-#include <limits.h>
-
-#include "libavutil/attributes.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/internal.h"
-#include "libavutil/mathematics.h"
-#include "avcodec.h"
-#include "mpegvideo.h"
-#include "h263.h"
-#include "h263data.h"
-#include "internal.h"
-#include "mathops.h"
-#include "mpegutils.h"
-#include "unary.h"
-#include "flv.h"
-#include "rv10.h"
-#include "mpeg4video.h"
-#include "mpegvideodata.h"
-
-// The defines below define the number of bits that are read at once for
-// reading vlc values. Changing these may improve speed and data cache needs
-// be aware though that decreasing them may need the number of stages that is
-// passed to get_vlc* to be increased.
-#define MV_VLC_BITS 9
-#define H263_MBTYPE_B_VLC_BITS 6
-#define CBPC_B_VLC_BITS 3
-
-static const int h263_mb_type_b_map[15]= {
- MB_TYPE_DIRECT2 | MB_TYPE_L0L1,
- MB_TYPE_DIRECT2 | MB_TYPE_L0L1 | MB_TYPE_CBP,
- MB_TYPE_DIRECT2 | MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_QUANT,
- MB_TYPE_L0 | MB_TYPE_16x16,
- MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_16x16,
- MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_QUANT | MB_TYPE_16x16,
- MB_TYPE_L1 | MB_TYPE_16x16,
- MB_TYPE_L1 | MB_TYPE_CBP | MB_TYPE_16x16,
- MB_TYPE_L1 | MB_TYPE_CBP | MB_TYPE_QUANT | MB_TYPE_16x16,
- MB_TYPE_L0L1 | MB_TYPE_16x16,
- MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_16x16,
- MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_QUANT | MB_TYPE_16x16,
- 0, //stuffing
- MB_TYPE_INTRA4x4 | MB_TYPE_CBP,
- MB_TYPE_INTRA4x4 | MB_TYPE_CBP | MB_TYPE_QUANT,
-};
-
-void ff_h263_show_pict_info(MpegEncContext *s){
- if(s->avctx->debug&FF_DEBUG_PICT_INFO){
- av_log(s->avctx, AV_LOG_DEBUG, "qp:%d %c size:%d rnd:%d%s%s%s%s%s%s%s%s%s %d/%d\n",
- s->qscale, av_get_picture_type_char(s->pict_type),
- s->gb.size_in_bits, 1-s->no_rounding,
- s->obmc ? " AP" : "",
- s->umvplus ? " UMV" : "",
- s->h263_long_vectors ? " LONG" : "",
- s->h263_plus ? " +" : "",
- s->h263_aic ? " AIC" : "",
- s->alt_inter_vlc ? " AIV" : "",
- s->modified_quant ? " MQ" : "",
- s->loop_filter ? " LOOP" : "",
- s->h263_slice_structured ? " SS" : "",
- s->avctx->framerate.num, s->avctx->framerate.den
- );
- }
-}
-
-/***********************************************/
-/* decoding */
-
-VLC ff_h263_intra_MCBPC_vlc;
-VLC ff_h263_inter_MCBPC_vlc;
-VLC ff_h263_cbpy_vlc;
-static VLC mv_vlc;
-static VLC h263_mbtype_b_vlc;
-static VLC cbpc_b_vlc;
-
-/* init vlcs */
-
-/* XXX: find a better solution to handle static init */
-av_cold void ff_h263_decode_init_vlc(void)
-{
- static volatile int done = 0;
-
- if (!done) {
- INIT_VLC_STATIC(&ff_h263_intra_MCBPC_vlc, INTRA_MCBPC_VLC_BITS, 9,
- ff_h263_intra_MCBPC_bits, 1, 1,
- ff_h263_intra_MCBPC_code, 1, 1, 72);
- INIT_VLC_STATIC(&ff_h263_inter_MCBPC_vlc, INTER_MCBPC_VLC_BITS, 28,
- ff_h263_inter_MCBPC_bits, 1, 1,
- ff_h263_inter_MCBPC_code, 1, 1, 198);
- 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,
- &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]);
- INIT_VLC_RL(ff_h263_rl_inter, 554);
- INIT_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);
- INIT_VLC_STATIC(&cbpc_b_vlc, CBPC_B_VLC_BITS, 4,
- &ff_cbpc_b_tab[0][1], 2, 1,
- &ff_cbpc_b_tab[0][0], 2, 1, 8);
- done = 1;
- }
-}
-
-int ff_h263_decode_mba(MpegEncContext *s)
-{
- int i, mb_pos;
-
- for (i = 0; i < 6; i++)
- if (s->mb_num - 1 <= ff_mba_max[i])
- break;
- mb_pos = get_bits(&s->gb, ff_mba_length[i]);
- s->mb_x = mb_pos % s->mb_width;
- s->mb_y = mb_pos / s->mb_width;
-
- return mb_pos;
-}
-
-/**
- * Decode the group of blocks header or slice header.
- * @return <0 if an error occurred
- */
-static int h263_decode_gob_header(MpegEncContext *s)
-{
- unsigned int val, gob_number;
- int left;
-
- /* Check for GOB Start Code */
- val = show_bits(&s->gb, 16);
- if(val)
- return -1;
-
- /* We have a GBSC probably with GSTUFF */
- skip_bits(&s->gb, 16); /* Drop the zeros */
- left= get_bits_left(&s->gb);
- left = FFMIN(left, 32);
- //MN: we must check the bits left or we might end in a infinite loop (or segfault)
- for(;left>13; left--){
- if(get_bits1(&s->gb)) break; /* Seek the '1' bit */
- }
- if(left<=13)
- return -1;
-
- if(s->h263_slice_structured){
- if(check_marker(&s->gb, "before MBA")==0)
- return -1;
-
- ff_h263_decode_mba(s);
-
- if(s->mb_num > 1583)
- if(check_marker(&s->gb, "after MBA")==0)
- return -1;
-
- s->qscale = get_bits(&s->gb, 5); /* SQUANT */
- if(check_marker(&s->gb, "after SQUANT")==0)
- return -1;
- skip_bits(&s->gb, 2); /* GFID */
- }else{
- gob_number = get_bits(&s->gb, 5); /* GN */
- s->mb_x= 0;
- s->mb_y= s->gob_index* gob_number;
- skip_bits(&s->gb, 2); /* GFID */
- s->qscale = get_bits(&s->gb, 5); /* GQUANT */
- }
-
- if(s->mb_y >= s->mb_height)
- return -1;
-
- if(s->qscale==0)
- return -1;
-
- return 0;
-}
-
-/**
- * Decode the group of blocks / video packet header.
- * @return bit position of the resync_marker, or <0 if none was found
- */
-int ff_h263_resync(MpegEncContext *s){
- int left, pos, ret;
-
- if(s->codec_id==AV_CODEC_ID_MPEG4){
- skip_bits1(&s->gb);
- align_get_bits(&s->gb);
- }
-
- if(show_bits(&s->gb, 16)==0){
- pos= get_bits_count(&s->gb);
- if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4)
- ret= ff_mpeg4_decode_video_packet_header(s->avctx->priv_data);
- else
- ret= h263_decode_gob_header(s);
- if(ret>=0)
- return pos;
- }
- //OK, it's not where it is supposed to be ...
- s->gb= s->last_resync_gb;
- align_get_bits(&s->gb);
- left= get_bits_left(&s->gb);
-
- for(;left>16+1+5+5; left-=8){
- if(show_bits(&s->gb, 16)==0){
- GetBitContext bak= s->gb;
-
- pos= get_bits_count(&s->gb);
- if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4)
- ret= ff_mpeg4_decode_video_packet_header(s->avctx->priv_data);
- else
- ret= h263_decode_gob_header(s);
- if(ret>=0)
- return pos;
-
- s->gb= bak;
- }
- skip_bits(&s->gb, 8);
- }
-
- return -1;
-}
-
-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);
-
- if (code == 0)
- return pred;
- if (code < 0)
- return 0xffff;
-
- sign = get_bits1(&s->gb);
- shift = f_code - 1;
- val = code;
- if (shift) {
- val = (val - 1) << shift;
- val |= get_bits(&s->gb, shift);
- val++;
- }
- if (sign)
- val = -val;
- val += pred;
-
- /* modulo decoding */
- if (!s->h263_long_vectors) {
- val = sign_extend(val, 5 + f_code);
- } else {
- /* horrible h263 long vector mode */
- if (pred < -31 && val < -63)
- val += 64;
- if (pred > 32 && val > 63)
- val -= 64;
-
- }
- return val;
-}
-
-
-/* Decode RVLC of H.263+ UMV */
-static int h263p_decode_umotion(MpegEncContext * s, int pred)
-{
- int code = 0, sign;
-
- if (get_bits1(&s->gb)) /* Motion difference = 0 */
- return pred;
-
- code = 2 + get_bits1(&s->gb);
-
- while (get_bits1(&s->gb))
- {
- code <<= 1;
- code += get_bits1(&s->gb);
- }
- sign = code & 1;
- code >>= 1;
-
- code = (sign) ? (pred - code) : (pred + code);
- ff_tlog(s->avctx,"H.263+ UMV Motion = %d\n", code);
- return code;
-
-}
-
-/**
- * read the next MVs for OBMC. yes this is a ugly hack, feel free to send a patch :)
- */
-static void preview_obmc(MpegEncContext *s){
- GetBitContext gb= s->gb;
-
- int cbpc, i, pred_x, pred_y, mx, my;
- int16_t *mot_val;
- const int xy= s->mb_x + 1 + s->mb_y * s->mb_stride;
- const int stride= s->b8_stride*2;
-
- for(i=0; i<4; i++)
- s->block_index[i]+= 2;
- for(i=4; i<6; i++)
- s->block_index[i]+= 1;
- s->mb_x++;
-
- av_assert2(s->pict_type == AV_PICTURE_TYPE_P);
-
- do{
- if (get_bits1(&s->gb)) {
- /* skip mb */
- mot_val = s->current_picture.motion_val[0][s->block_index[0]];
- mot_val[0 ]= mot_val[2 ]=
- mot_val[0+stride]= mot_val[2+stride]= 0;
- mot_val[1 ]= mot_val[3 ]=
- mot_val[1+stride]= mot_val[3+stride]= 0;
-
- s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
- goto end;
- }
- cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
- }while(cbpc == 20);
-
- if(cbpc & 4){
- s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
- }else{
- get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
- if (cbpc & 8) {
- if(s->modified_quant){
- if(get_bits1(&s->gb)) skip_bits(&s->gb, 1);
- else skip_bits(&s->gb, 5);
- }else
- skip_bits(&s->gb, 2);
- }
-
- if ((cbpc & 16) == 0) {
- s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
- /* 16x16 motion prediction */
- mot_val= ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
- if (s->umvplus)
- mx = h263p_decode_umotion(s, pred_x);
- else
- mx = ff_h263_decode_motion(s, pred_x, 1);
-
- if (s->umvplus)
- my = h263p_decode_umotion(s, pred_y);
- else
- my = ff_h263_decode_motion(s, pred_y, 1);
-
- mot_val[0 ]= mot_val[2 ]=
- mot_val[0+stride]= mot_val[2+stride]= mx;
- mot_val[1 ]= mot_val[3 ]=
- mot_val[1+stride]= mot_val[3+stride]= my;
- } else {
- s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
- for(i=0;i<4;i++) {
- mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
- if (s->umvplus)
- mx = h263p_decode_umotion(s, pred_x);
- else
- mx = ff_h263_decode_motion(s, pred_x, 1);
-
- if (s->umvplus)
- my = h263p_decode_umotion(s, pred_y);
- else
- my = ff_h263_decode_motion(s, pred_y, 1);
- if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1)
- skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */
- mot_val[0] = mx;
- mot_val[1] = my;
- }
- }
- }
-end:
-
- for(i=0; i<4; i++)
- s->block_index[i]-= 2;
- for(i=4; i<6; i++)
- s->block_index[i]-= 1;
- s->mb_x--;
-
- s->gb= gb;
-}
-
-static void h263_decode_dquant(MpegEncContext *s){
- static const int8_t quant_tab[4] = { -1, -2, 1, 2 };
-
- if(s->modified_quant){
- if(get_bits1(&s->gb))
- s->qscale= ff_modified_quant_tab[get_bits1(&s->gb)][ s->qscale ];
- else
- s->qscale= get_bits(&s->gb, 5);
- }else
- s->qscale += quant_tab[get_bits(&s->gb, 2)];
- ff_set_qscale(s, s->qscale);
-}
-
-static int h263_decode_block(MpegEncContext * s, int16_t * block,
- int n, int coded)
-{
- int level, i, j, run;
- RLTable *rl = &ff_h263_rl_inter;
- const uint8_t *scan_table;
- GetBitContext gb= s->gb;
-
- scan_table = s->intra_scantable.permutated;
- if (s->h263_aic && s->mb_intra) {
- rl = &ff_rl_intra_aic;
- i = 0;
- if (s->ac_pred) {
- if (s->h263_aic_dir)
- scan_table = s->intra_v_scantable.permutated; /* left */
- else
- scan_table = s->intra_h_scantable.permutated; /* top */
- }
- } else if (s->mb_intra) {
- /* DC coef */
- if (CONFIG_RV10_DECODER && s->codec_id == AV_CODEC_ID_RV10) {
- if (s->rv10_version == 3 && s->pict_type == AV_PICTURE_TYPE_I) {
- int component, diff;
- component = (n <= 3 ? 0 : n - 4 + 1);
- level = s->last_dc[component];
- if (s->rv10_first_dc_coded[component]) {
- diff = ff_rv_decode_dc(s, n);
- if (diff == 0xffff)
- return -1;
- level += diff;
- level = level & 0xff; /* handle wrap round */
- s->last_dc[component] = level;
- } else {
- s->rv10_first_dc_coded[component] = 1;
- }
- } else {
- level = get_bits(&s->gb, 8);
- if (level == 255)
- level = 128;
- }
- }else{
- level = get_bits(&s->gb, 8);
- if((level&0x7F) == 0){
- av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", level, s->mb_x, s->mb_y);
- if (s->avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))
- return -1;
- }
- if (level == 255)
- level = 128;
- }
- block[0] = level;
- i = 1;
- } else {
- i = 0;
- }
- if (!coded) {
- if (s->mb_intra && s->h263_aic)
- goto not_coded;
- s->block_last_index[n] = i - 1;
- return 0;
- }
-retry:
- {
- OPEN_READER(re, &s->gb);
- i--; // offset by -1 to allow direct indexing of scan_table
- for(;;) {
- UPDATE_CACHE(re, &s->gb);
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
- if (run == 66) {
- if (level){
- CLOSE_READER(re, &s->gb);
- av_log(s->avctx, AV_LOG_ERROR, "illegal ac vlc code at %dx%d\n", s->mb_x, s->mb_y);
- return -1;
- }
- /* escape */
- if (CONFIG_FLV_DECODER && s->h263_flv > 1) {
- int is11 = SHOW_UBITS(re, &s->gb, 1);
- SKIP_CACHE(re, &s->gb, 1);
- run = SHOW_UBITS(re, &s->gb, 7) + 1;
- if (is11) {
- SKIP_COUNTER(re, &s->gb, 1 + 7);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 11);
- SKIP_COUNTER(re, &s->gb, 11);
- } else {
- SKIP_CACHE(re, &s->gb, 7);
- level = SHOW_SBITS(re, &s->gb, 7);
- SKIP_COUNTER(re, &s->gb, 1 + 7 + 7);
- }
- } else {
- run = SHOW_UBITS(re, &s->gb, 7) + 1;
- SKIP_CACHE(re, &s->gb, 7);
- level = (int8_t)SHOW_UBITS(re, &s->gb, 8);
- SKIP_COUNTER(re, &s->gb, 7 + 8);
- if(level == -128){
- UPDATE_CACHE(re, &s->gb);
- if (s->codec_id == AV_CODEC_ID_RV10) {
- /* XXX: should patch encoder too */
- level = SHOW_SBITS(re, &s->gb, 12);
- SKIP_COUNTER(re, &s->gb, 12);
- }else{
- level = SHOW_UBITS(re, &s->gb, 5);
- SKIP_CACHE(re, &s->gb, 5);
- level |= SHOW_SBITS(re, &s->gb, 6)<<5;
- SKIP_COUNTER(re, &s->gb, 5 + 6);
- }
- }
- }
- } else {
- if (SHOW_UBITS(re, &s->gb, 1))
- level = -level;
- SKIP_COUNTER(re, &s->gb, 1);
- }
- i += run;
- if (i >= 64){
- CLOSE_READER(re, &s->gb);
- // redo update without last flag, revert -1 offset
- i = i - run + ((run-1)&63) + 1;
- if (i < 64) {
- // only last marker, no overrun
- block[scan_table[i]] = level;
- break;
- }
- if(s->alt_inter_vlc && rl == &ff_h263_rl_inter && !s->mb_intra){
- //Looks like a hack but no, it's the way it is supposed to work ...
- rl = &ff_rl_intra_aic;
- i = 0;
- s->gb= gb;
- s->bdsp.clear_block(block);
- goto retry;
- }
- av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d i:%d\n", s->mb_x, s->mb_y, s->mb_intra);
- return -1;
- }
- j = scan_table[i];
- block[j] = level;
- }
- }
-not_coded:
- if (s->mb_intra && s->h263_aic) {
- ff_h263_pred_acdc(s, block, n);
- i = 63;
- }
- s->block_last_index[n] = i;
- return 0;
-}
-
-static int h263_skip_b_part(MpegEncContext *s, int cbp)
-{
- LOCAL_ALIGNED_16(int16_t, dblock, [64]);
- int i, mbi;
- int bli[6];
-
- /* we have to set s->mb_intra to zero to decode B-part of PB-frame correctly
- * but real value should be restored in order to be used later (in OBMC condition)
- */
- mbi = s->mb_intra;
- memcpy(bli, s->block_last_index, sizeof(bli));
- s->mb_intra = 0;
- for (i = 0; i < 6; i++) {
- if (h263_decode_block(s, dblock, i, cbp&32) < 0)
- return -1;
- cbp+=cbp;
- }
- s->mb_intra = mbi;
- memcpy(s->block_last_index, bli, sizeof(bli));
- return 0;
-}
-
-static int h263_get_modb(GetBitContext *gb, int pb_frame, int *cbpb)
-{
- int c, mv = 1;
-
- if (pb_frame < 3) { // h.263 Annex G and i263 PB-frame
- c = get_bits1(gb);
- if (pb_frame == 2 && c)
- mv = !get_bits1(gb);
- } else { // h.263 Annex M improved PB-frame
- mv = get_unary(gb, 0, 4) + 1;
- c = mv & 1;
- mv = !!(mv & 2);
- }
- if(c)
- *cbpb = get_bits(gb, 6);
- return mv;
-}
-
-int ff_h263_decode_mb(MpegEncContext *s,
- int16_t block[6][64])
-{
- int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
- int16_t *mot_val;
- const int xy= s->mb_x + s->mb_y * s->mb_stride;
- int cbpb = 0, pb_mv_count = 0;
-
- av_assert2(!s->h263_pred);
-
- if (s->pict_type == AV_PICTURE_TYPE_P) {
- do{
- if (get_bits1(&s->gb)) {
- /* skip mb */
- s->mb_intra = 0;
- for(i=0;i<6;i++)
- s->block_last_index[i] = -1;
- s->mv_dir = MV_DIR_FORWARD;
- s->mv_type = MV_TYPE_16X16;
- s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
- s->mv[0][0][0] = 0;
- s->mv[0][0][1] = 0;
- s->mb_skipped = !(s->obmc | s->loop_filter);
- goto end;
- }
- cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
- if (cbpc < 0){
- av_log(s->avctx, AV_LOG_ERROR, "cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- }while(cbpc == 20);
-
- s->bdsp.clear_blocks(s->block[0]);
-
- dquant = cbpc & 8;
- s->mb_intra = ((cbpc & 4) != 0);
- if (s->mb_intra) goto intra;
-
- if(s->pb_frame && get_bits1(&s->gb))
- pb_mv_count = h263_get_modb(&s->gb, s->pb_frame, &cbpb);
- cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
-
- if(s->alt_inter_vlc==0 || (cbpc & 3)!=3)
- cbpy ^= 0xF;
-
- cbp = (cbpc & 3) | (cbpy << 2);
- if (dquant) {
- h263_decode_dquant(s);
- }
-
- s->mv_dir = MV_DIR_FORWARD;
- if ((cbpc & 16) == 0) {
- s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
- /* 16x16 motion prediction */
- s->mv_type = MV_TYPE_16X16;
- ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
- if (s->umvplus)
- mx = h263p_decode_umotion(s, pred_x);
- else
- mx = ff_h263_decode_motion(s, pred_x, 1);
-
- if (mx >= 0xffff)
- return -1;
-
- if (s->umvplus)
- my = h263p_decode_umotion(s, pred_y);
- else
- my = ff_h263_decode_motion(s, pred_y, 1);
-
- if (my >= 0xffff)
- return -1;
- s->mv[0][0][0] = mx;
- s->mv[0][0][1] = my;
-
- if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1)
- skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */
- } else {
- s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
- s->mv_type = MV_TYPE_8X8;
- for(i=0;i<4;i++) {
- mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
- if (s->umvplus)
- mx = h263p_decode_umotion(s, pred_x);
- else
- mx = ff_h263_decode_motion(s, pred_x, 1);
- if (mx >= 0xffff)
- return -1;
-
- if (s->umvplus)
- my = h263p_decode_umotion(s, pred_y);
- else
- my = ff_h263_decode_motion(s, pred_y, 1);
- if (my >= 0xffff)
- return -1;
- s->mv[0][i][0] = mx;
- s->mv[0][i][1] = my;
- if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1)
- skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */
- mot_val[0] = mx;
- mot_val[1] = my;
- }
- }
- } else if(s->pict_type==AV_PICTURE_TYPE_B) {
- int mb_type;
- const int stride= s->b8_stride;
- int16_t *mot_val0 = s->current_picture.motion_val[0][2 * (s->mb_x + s->mb_y * stride)];
- int16_t *mot_val1 = s->current_picture.motion_val[1][2 * (s->mb_x + s->mb_y * stride)];
-// const int mv_xy= s->mb_x + 1 + s->mb_y * s->mb_stride;
-
- //FIXME ugly
- mot_val0[0 ]= mot_val0[2 ]= mot_val0[0+2*stride]= mot_val0[2+2*stride]=
- mot_val0[1 ]= mot_val0[3 ]= mot_val0[1+2*stride]= mot_val0[3+2*stride]=
- mot_val1[0 ]= mot_val1[2 ]= mot_val1[0+2*stride]= mot_val1[2+2*stride]=
- mot_val1[1 ]= mot_val1[3 ]= mot_val1[1+2*stride]= mot_val1[3+2*stride]= 0;
-
- do{
- mb_type= get_vlc2(&s->gb, h263_mbtype_b_vlc.table, H263_MBTYPE_B_VLC_BITS, 2);
- if (mb_type < 0){
- av_log(s->avctx, AV_LOG_ERROR, "b mb_type damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
-
- mb_type= h263_mb_type_b_map[ mb_type ];
- }while(!mb_type);
-
- s->mb_intra = IS_INTRA(mb_type);
- if(HAS_CBP(mb_type)){
- s->bdsp.clear_blocks(s->block[0]);
- cbpc = get_vlc2(&s->gb, cbpc_b_vlc.table, CBPC_B_VLC_BITS, 1);
- if(s->mb_intra){
- dquant = IS_QUANT(mb_type);
- goto intra;
- }
-
- cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
-
- if (cbpy < 0){
- av_log(s->avctx, AV_LOG_ERROR, "b cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
-
- if(s->alt_inter_vlc==0 || (cbpc & 3)!=3)
- cbpy ^= 0xF;
-
- cbp = (cbpc & 3) | (cbpy << 2);
- }else
- cbp=0;
-
- av_assert2(!s->mb_intra);
-
- if(IS_QUANT(mb_type)){
- h263_decode_dquant(s);
- }
-
- if(IS_DIRECT(mb_type)){
- s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
- mb_type |= ff_mpeg4_set_direct_mv(s, 0, 0);
- }else{
- s->mv_dir = 0;
- s->mv_type= MV_TYPE_16X16;
-//FIXME UMV
-
- if(USES_LIST(mb_type, 0)){
- int16_t *mot_val= ff_h263_pred_motion(s, 0, 0, &mx, &my);
- s->mv_dir = MV_DIR_FORWARD;
-
- mx = ff_h263_decode_motion(s, mx, 1);
- my = ff_h263_decode_motion(s, my, 1);
-
- s->mv[0][0][0] = mx;
- s->mv[0][0][1] = my;
- mot_val[0 ]= mot_val[2 ]= mot_val[0+2*stride]= mot_val[2+2*stride]= mx;
- mot_val[1 ]= mot_val[3 ]= mot_val[1+2*stride]= mot_val[3+2*stride]= my;
- }
-
- if(USES_LIST(mb_type, 1)){
- int16_t *mot_val= ff_h263_pred_motion(s, 0, 1, &mx, &my);
- s->mv_dir |= MV_DIR_BACKWARD;
-
- mx = ff_h263_decode_motion(s, mx, 1);
- my = ff_h263_decode_motion(s, my, 1);
-
- s->mv[1][0][0] = mx;
- s->mv[1][0][1] = my;
- mot_val[0 ]= mot_val[2 ]= mot_val[0+2*stride]= mot_val[2+2*stride]= mx;
- mot_val[1 ]= mot_val[3 ]= mot_val[1+2*stride]= mot_val[3+2*stride]= my;
- }
- }
-
- s->current_picture.mb_type[xy] = mb_type;
- } else { /* I-Frame */
- do{
- cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
- if (cbpc < 0){
- av_log(s->avctx, AV_LOG_ERROR, "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- }while(cbpc == 8);
-
- s->bdsp.clear_blocks(s->block[0]);
-
- dquant = cbpc & 4;
- s->mb_intra = 1;
-intra:
- s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
- if (s->h263_aic) {
- s->ac_pred = get_bits1(&s->gb);
- if(s->ac_pred){
- s->current_picture.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
-
- s->h263_aic_dir = get_bits1(&s->gb);
- }
- }else
- s->ac_pred = 0;
-
- if(s->pb_frame && get_bits1(&s->gb))
- pb_mv_count = h263_get_modb(&s->gb, s->pb_frame, &cbpb);
- cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
- if(cbpy<0){
- av_log(s->avctx, AV_LOG_ERROR, "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- cbp = (cbpc & 3) | (cbpy << 2);
- if (dquant) {
- h263_decode_dquant(s);
- }
-
- pb_mv_count += !!s->pb_frame;
- }
-
- while(pb_mv_count--){
- ff_h263_decode_motion(s, 0, 1);
- ff_h263_decode_motion(s, 0, 1);
- }
-
- /* decode each block */
- for (i = 0; i < 6; i++) {
- if (h263_decode_block(s, block[i], i, cbp&32) < 0)
- return -1;
- cbp+=cbp;
- }
-
- if(s->pb_frame && h263_skip_b_part(s, cbpb) < 0)
- return -1;
- if(s->obmc && !s->mb_intra){
- if(s->pict_type == AV_PICTURE_TYPE_P && s->mb_x+1<s->mb_width && s->mb_num_left != 1)
- preview_obmc(s);
- }
-end:
-
- /* per-MB end of slice check */
- {
- int v= show_bits(&s->gb, 16);
-
- if (get_bits_left(&s->gb) < 16) {
- v >>= 16 - get_bits_left(&s->gb);
- }
-
- if(v==0)
- return SLICE_END;
- }
-
- return SLICE_OK;
-}
-
-/* most is hardcoded. should extend to handle all h263 streams */
-int ff_h263_decode_picture_header(MpegEncContext *s)
-{
- int format, width, height, i, ret;
- uint32_t startcode;
-
- align_get_bits(&s->gb);
-
- if (show_bits(&s->gb, 2) == 2 && s->avctx->frame_number == 0) {
- av_log(s->avctx, AV_LOG_WARNING, "Header looks like RTP instead of H.263\n");
- }
-
- startcode= get_bits(&s->gb, 22-8);
-
- for(i= get_bits_left(&s->gb); i>24; i-=8) {
- startcode = ((startcode << 8) | get_bits(&s->gb, 8)) & 0x003FFFFF;
-
- if(startcode == 0x20)
- break;
- }
-
- if (startcode != 0x20) {
- av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n");
- return -1;
- }
- /* temporal reference */
- i = get_bits(&s->gb, 8); /* picture timestamp */
- if( (s->picture_number&~0xFF)+i < s->picture_number)
- i+= 256;
- s->picture_number= (s->picture_number&~0xFF) + i;
-
- /* PTYPE starts here */
- if (check_marker(&s->gb, "in PTYPE") != 1) {
- return -1;
- }
- if (get_bits1(&s->gb) != 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Bad H263 id\n");
- return -1; /* h263 id */
- }
- skip_bits1(&s->gb); /* split screen off */
- skip_bits1(&s->gb); /* camera off */
- skip_bits1(&s->gb); /* freeze picture release off */
-
- format = get_bits(&s->gb, 3);
- /*
- 0 forbidden
- 1 sub-QCIF
- 10 QCIF
- 7 extended PTYPE (PLUSPTYPE)
- */
-
- if (format != 7 && format != 6) {
- s->h263_plus = 0;
- /* H.263v1 */
- width = ff_h263_format[format][0];
- height = ff_h263_format[format][1];
- if (!width)
- return -1;
-
- s->pict_type = AV_PICTURE_TYPE_I + get_bits1(&s->gb);
-
- s->h263_long_vectors = get_bits1(&s->gb);
-
- if (get_bits1(&s->gb) != 0) {
- av_log(s->avctx, AV_LOG_ERROR, "H263 SAC not supported\n");
- return -1; /* SAC: off */
- }
- s->obmc= get_bits1(&s->gb); /* Advanced prediction mode */
- s->unrestricted_mv = s->h263_long_vectors || s->obmc;
-
- s->pb_frame = get_bits1(&s->gb);
- s->chroma_qscale= s->qscale = get_bits(&s->gb, 5);
- skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */
-
- s->width = width;
- s->height = height;
- s->avctx->sample_aspect_ratio= (AVRational){12,11};
- s->avctx->framerate = (AVRational){ 30000, 1001 };
- } else {
- int ufep;
-
- /* H.263v2 */
- s->h263_plus = 1;
- ufep = get_bits(&s->gb, 3); /* Update Full Extended PTYPE */
-
- /* ufep other than 0 and 1 are reserved */
- if (ufep == 1) {
- /* OPPTYPE */
- format = get_bits(&s->gb, 3);
- ff_dlog(s->avctx, "ufep=1, format: %d\n", format);
- s->custom_pcf= get_bits1(&s->gb);
- s->umvplus = get_bits1(&s->gb); /* Unrestricted Motion Vector */
- if (get_bits1(&s->gb) != 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Syntax-based Arithmetic Coding (SAC) not supported\n");
- }
- s->obmc= get_bits1(&s->gb); /* Advanced prediction mode */
- s->h263_aic = get_bits1(&s->gb); /* Advanced Intra Coding (AIC) */
- s->loop_filter= get_bits1(&s->gb);
- s->unrestricted_mv = s->umvplus || s->obmc || s->loop_filter;
- if(s->avctx->lowres)
- s->loop_filter = 0;
-
- s->h263_slice_structured= get_bits1(&s->gb);
- if (get_bits1(&s->gb) != 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Reference Picture Selection not supported\n");
- }
- if (get_bits1(&s->gb) != 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Independent Segment Decoding not supported\n");
- }
- s->alt_inter_vlc= get_bits1(&s->gb);
- s->modified_quant= get_bits1(&s->gb);
- if(s->modified_quant)
- s->chroma_qscale_table= ff_h263_chroma_qscale_table;
-
- skip_bits(&s->gb, 1); /* Prevent start code emulation */
-
- skip_bits(&s->gb, 3); /* Reserved */
- } else if (ufep != 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Bad UFEP type (%d)\n", ufep);
- return -1;
- }
-
- /* MPPTYPE */
- s->pict_type = get_bits(&s->gb, 3);
- switch(s->pict_type){
- case 0: s->pict_type= AV_PICTURE_TYPE_I;break;
- case 1: s->pict_type= AV_PICTURE_TYPE_P;break;
- case 2: s->pict_type= AV_PICTURE_TYPE_P;s->pb_frame = 3;break;
- case 3: s->pict_type= AV_PICTURE_TYPE_B;break;
- case 7: s->pict_type= AV_PICTURE_TYPE_I;break; //ZYGO
- default:
- return -1;
- }
- skip_bits(&s->gb, 2);
- s->no_rounding = get_bits1(&s->gb);
- skip_bits(&s->gb, 4);
-
- /* Get the picture dimensions */
- if (ufep) {
- if (format == 6) {
- /* Custom Picture Format (CPFMT) */
- s->aspect_ratio_info = get_bits(&s->gb, 4);
- ff_dlog(s->avctx, "aspect: %d\n", s->aspect_ratio_info);
- /* aspect ratios:
- 0 - forbidden
- 1 - 1:1
- 2 - 12:11 (CIF 4:3)
- 3 - 10:11 (525-type 4:3)
- 4 - 16:11 (CIF 16:9)
- 5 - 40:33 (525-type 16:9)
- 6-14 - reserved
- */
- width = (get_bits(&s->gb, 9) + 1) * 4;
- check_marker(&s->gb, "in dimensions");
- height = get_bits(&s->gb, 9) * 4;
- ff_dlog(s->avctx, "\nH.263+ Custom picture: %dx%d\n",width,height);
- if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) {
- /* aspected dimensions */
- s->avctx->sample_aspect_ratio.num= get_bits(&s->gb, 8);
- s->avctx->sample_aspect_ratio.den= get_bits(&s->gb, 8);
- }else{
- s->avctx->sample_aspect_ratio= ff_h263_pixel_aspect[s->aspect_ratio_info];
- }
- } else {
- width = ff_h263_format[format][0];
- height = ff_h263_format[format][1];
- s->avctx->sample_aspect_ratio= (AVRational){12,11};
- }
- s->avctx->sample_aspect_ratio.den <<= s->ehc_mode;
- if ((width == 0) || (height == 0))
- return -1;
- s->width = width;
- s->height = height;
-
- if(s->custom_pcf){
- int gcd;
- s->avctx->framerate.num = 1800000;
- s->avctx->framerate.den = 1000 + get_bits1(&s->gb);
- s->avctx->framerate.den *= get_bits(&s->gb, 7);
- if(s->avctx->framerate.den == 0){
- av_log(s, AV_LOG_ERROR, "zero framerate\n");
- return -1;
- }
- gcd= av_gcd(s->avctx->framerate.den, s->avctx->framerate.num);
- s->avctx->framerate.den /= gcd;
- s->avctx->framerate.num /= gcd;
- }else{
- s->avctx->framerate = (AVRational){ 30000, 1001 };
- }
- }
-
- if(s->custom_pcf){
- skip_bits(&s->gb, 2); //extended Temporal reference
- }
-
- if (ufep) {
- if (s->umvplus) {
- if(get_bits1(&s->gb)==0) /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */
- skip_bits1(&s->gb);
- }
- if(s->h263_slice_structured){
- if (get_bits1(&s->gb) != 0) {
- av_log(s->avctx, AV_LOG_ERROR, "rectangular slices not supported\n");
- }
- if (get_bits1(&s->gb) != 0) {
- av_log(s->avctx, AV_LOG_ERROR, "unordered slices not supported\n");
- }
- }
- }
-
- s->qscale = get_bits(&s->gb, 5);
- }
-
- if ((ret = av_image_check_size(s->width, s->height, 0, s)) < 0)
- return ret;
-
- s->mb_width = (s->width + 15) / 16;
- s->mb_height = (s->height + 15) / 16;
- s->mb_num = s->mb_width * s->mb_height;
-
- if (s->pb_frame) {
- skip_bits(&s->gb, 3); /* Temporal reference for B-pictures */
- if (s->custom_pcf)
- skip_bits(&s->gb, 2); //extended Temporal reference
- skip_bits(&s->gb, 2); /* Quantization information for B-pictures */
- }
-
- if (s->pict_type!=AV_PICTURE_TYPE_B) {
- s->time = s->picture_number;
- s->pp_time = s->time - s->last_non_b_time;
- s->last_non_b_time = s->time;
- }else{
- s->time = s->picture_number;
- s->pb_time = s->pp_time - (s->last_non_b_time - s->time);
- if (s->pp_time <=s->pb_time ||
- s->pp_time <= s->pp_time - s->pb_time ||
- s->pp_time <= 0){
- s->pp_time = 2;
- s->pb_time = 1;
- }
- ff_mpeg4_init_direct_mv(s);
- }
-
- /* PEI */
- if (skip_1stop_8data_bits(&s->gb) < 0)
- return AVERROR_INVALIDDATA;
-
- if(s->h263_slice_structured){
- if (check_marker(&s->gb, "SEPB1") != 1) {
- return -1;
- }
-
- ff_h263_decode_mba(s);
-
- if (check_marker(&s->gb, "SEPB2") != 1) {
- return -1;
- }
- }
- s->f_code = 1;
-
- if(s->h263_aic){
- s->y_dc_scale_table=
- s->c_dc_scale_table= ff_aic_dc_scale_table;
- }else{
- s->y_dc_scale_table=
- s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
- }
-
- ff_h263_show_pict_info(s);
- if (s->pict_type == AV_PICTURE_TYPE_I && s->codec_tag == AV_RL32("ZYGO") && get_bits_left(&s->gb) >= 85 + 13*3*16 + 50){
- int i,j;
- for(i=0; i<85; i++) av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&s->gb));
- av_log(s->avctx, AV_LOG_DEBUG, "\n");
- for(i=0; i<13; i++){
- for(j=0; j<3; j++){
- int v= get_bits(&s->gb, 8);
- v |= get_sbits(&s->gb, 8)<<8;
- av_log(s->avctx, AV_LOG_DEBUG, " %5d", v);
- }
- av_log(s->avctx, AV_LOG_DEBUG, "\n");
- }
- for(i=0; i<50; i++) av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&s->gb));
- }
-
- return 0;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/ivi_dsp.c b/ffmpeg-2-8-11/libavcodec/ivi_dsp.c
deleted file mode 100644
index 4b97399..0000000
--- a/ffmpeg-2-8-11/libavcodec/ivi_dsp.c
+++ /dev/null
@@ -1,846 +0,0 @@
-/*
- * DSP functions for Indeo Video Interactive codecs (Indeo4 and Indeo5)
- *
- * Copyright (c) 2009-2011 Maxim Poliakovski
- *
- * 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
- * DSP functions (inverse transforms, motion compensation, wavelet recompostions)
- * for Indeo Video Interactive codecs.
- */
-
-#include "avcodec.h"
-#include "ivi.h"
-#include "ivi_dsp.h"
-
-void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst,
- const int dst_pitch)
-{
- int x, y, indx;
- int32_t p0, p1, p2, p3, tmp0, tmp1, tmp2;
- int32_t b0_1, b0_2, b1_1, b1_2, b1_3, b2_1, b2_2, b2_3, b2_4, b2_5, b2_6;
- int32_t b3_1, b3_2, b3_3, b3_4, b3_5, b3_6, b3_7, b3_8, b3_9;
- int32_t pitch, back_pitch;
- const short *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
- const int num_bands = 4;
-
- /* all bands should have the same pitch */
- pitch = plane->bands[0].pitch;
-
- /* pixels at the position "y-1" will be set to pixels at the "y" for the 1st iteration */
- back_pitch = 0;
-
- /* get pointers to the wavelet bands */
- b0_ptr = plane->bands[0].buf;
- b1_ptr = plane->bands[1].buf;
- b2_ptr = plane->bands[2].buf;
- b3_ptr = plane->bands[3].buf;
-
- for (y = 0; y < plane->height; y += 2) {
-
- if (y+2 >= plane->height)
- pitch= 0;
- /* load storage variables with values */
- if (num_bands > 0) {
- b0_1 = b0_ptr[0];
- b0_2 = b0_ptr[pitch];
- }
-
- if (num_bands > 1) {
- b1_1 = b1_ptr[back_pitch];
- b1_2 = b1_ptr[0];
- b1_3 = b1_1 - b1_2*6 + b1_ptr[pitch];
- }
-
- if (num_bands > 2) {
- b2_2 = b2_ptr[0]; // b2[x, y ]
- b2_3 = b2_2; // b2[x+1,y ] = b2[x,y]
- b2_5 = b2_ptr[pitch]; // b2[x ,y+1]
- b2_6 = b2_5; // b2[x+1,y+1] = b2[x,y+1]
- }
-
- if (num_bands > 3) {
- b3_2 = b3_ptr[back_pitch]; // b3[x ,y-1]
- b3_3 = b3_2; // b3[x+1,y-1] = b3[x ,y-1]
- b3_5 = b3_ptr[0]; // b3[x ,y ]
- b3_6 = b3_5; // b3[x+1,y ] = b3[x ,y ]
- b3_8 = b3_2 - b3_5*6 + b3_ptr[pitch];
- b3_9 = b3_8;
- }
-
- for (x = 0, indx = 0; x < plane->width; x+=2, indx++) {
- if (x+2 >= plane->width) {
- b0_ptr --;
- b1_ptr --;
- b2_ptr --;
- b3_ptr --;
- }
-
- /* some values calculated in the previous iterations can */
- /* be reused in the next ones, so do appropriate copying */
- b2_1 = b2_2; // b2[x-1,y ] = b2[x, y ]
- b2_2 = b2_3; // b2[x ,y ] = b2[x+1,y ]
- b2_4 = b2_5; // b2[x-1,y+1] = b2[x ,y+1]
- b2_5 = b2_6; // b2[x ,y+1] = b2[x+1,y+1]
- b3_1 = b3_2; // b3[x-1,y-1] = b3[x ,y-1]
- b3_2 = b3_3; // b3[x ,y-1] = b3[x+1,y-1]
- b3_4 = b3_5; // b3[x-1,y ] = b3[x ,y ]
- b3_5 = b3_6; // b3[x ,y ] = b3[x+1,y ]
- b3_7 = b3_8; // vert_HPF(x-1)
- b3_8 = b3_9; // vert_HPF(x )
-
- p0 = p1 = p2 = p3 = 0;
-
- /* process the LL-band by applying LPF both vertically and horizontally */
- if (num_bands > 0) {
- tmp0 = b0_1;
- tmp2 = b0_2;
- b0_1 = b0_ptr[indx+1];
- b0_2 = b0_ptr[pitch+indx+1];
- tmp1 = tmp0 + b0_1;
-
- p0 = tmp0 << 4;
- p1 = tmp1 << 3;
- p2 = (tmp0 + tmp2) << 3;
- p3 = (tmp1 + tmp2 + b0_2) << 2;
- }
-
- /* process the HL-band by applying HPF vertically and LPF horizontally */
- if (num_bands > 1) {
- tmp0 = b1_2;
- tmp1 = b1_1;
- b1_2 = b1_ptr[indx+1];
- b1_1 = b1_ptr[back_pitch+indx+1];
-
- tmp2 = tmp1 - tmp0*6 + b1_3;
- b1_3 = b1_1 - b1_2*6 + b1_ptr[pitch+indx+1];
-
- p0 += (tmp0 + tmp1) << 3;
- p1 += (tmp0 + tmp1 + b1_1 + b1_2) << 2;
- p2 += tmp2 << 2;
- p3 += (tmp2 + b1_3) << 1;
- }
-
- /* process the LH-band by applying LPF vertically and HPF horizontally */
- if (num_bands > 2) {
- b2_3 = b2_ptr[indx+1];
- b2_6 = b2_ptr[pitch+indx+1];
-
- tmp0 = b2_1 + b2_2;
- tmp1 = b2_1 - b2_2*6 + b2_3;
-
- p0 += tmp0 << 3;
- p1 += tmp1 << 2;
- p2 += (tmp0 + b2_4 + b2_5) << 2;
- p3 += (tmp1 + b2_4 - b2_5*6 + b2_6) << 1;
- }
-
- /* process the HH-band by applying HPF both vertically and horizontally */
- if (num_bands > 3) {
- b3_6 = b3_ptr[indx+1]; // b3[x+1,y ]
- b3_3 = b3_ptr[back_pitch+indx+1]; // b3[x+1,y-1]
-
- tmp0 = b3_1 + b3_4;
- tmp1 = b3_2 + b3_5;
- tmp2 = b3_3 + b3_6;
-
- b3_9 = b3_3 - b3_6*6 + b3_ptr[pitch+indx+1];
-
- p0 += (tmp0 + tmp1) << 2;
- p1 += (tmp0 - tmp1*6 + tmp2) << 1;
- p2 += (b3_7 + b3_8) << 1;
- p3 += b3_7 - b3_8*6 + b3_9;
- }
-
- /* output four pixels */
- dst[x] = av_clip_uint8((p0 >> 6) + 128);
- dst[x+1] = av_clip_uint8((p1 >> 6) + 128);
- dst[dst_pitch+x] = av_clip_uint8((p2 >> 6) + 128);
- dst[dst_pitch+x+1] = av_clip_uint8((p3 >> 6) + 128);
- }// for x
-
- dst += dst_pitch << 1;
-
- back_pitch = -pitch;
-
- b0_ptr += pitch + 1;
- b1_ptr += pitch + 1;
- b2_ptr += pitch + 1;
- b3_ptr += pitch + 1;
- }
-}
-
-void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst,
- const int dst_pitch)
-{
- int x, y, indx, b0, b1, b2, b3, p0, p1, p2, p3;
- const short *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
- int32_t pitch;
-
- /* all bands should have the same pitch */
- pitch = plane->bands[0].pitch;
-
- /* get pointers to the wavelet bands */
- b0_ptr = plane->bands[0].buf;
- b1_ptr = plane->bands[1].buf;
- b2_ptr = plane->bands[2].buf;
- b3_ptr = plane->bands[3].buf;
-
- for (y = 0; y < plane->height; y += 2) {
- for (x = 0, indx = 0; x < plane->width; x += 2, indx++) {
- /* load coefficients */
- b0 = b0_ptr[indx]; //should be: b0 = (num_bands > 0) ? b0_ptr[indx] : 0;
- b1 = b1_ptr[indx]; //should be: b1 = (num_bands > 1) ? b1_ptr[indx] : 0;
- b2 = b2_ptr[indx]; //should be: b2 = (num_bands > 2) ? b2_ptr[indx] : 0;
- b3 = b3_ptr[indx]; //should be: b3 = (num_bands > 3) ? b3_ptr[indx] : 0;
-
- /* haar wavelet recomposition */
- p0 = (b0 + b1 + b2 + b3 + 2) >> 2;
- p1 = (b0 + b1 - b2 - b3 + 2) >> 2;
- p2 = (b0 - b1 + b2 - b3 + 2) >> 2;
- p3 = (b0 - b1 - b2 + b3 + 2) >> 2;
-
- /* bias, convert and output four pixels */
- dst[x] = av_clip_uint8(p0 + 128);
- dst[x + 1] = av_clip_uint8(p1 + 128);
- dst[dst_pitch + x] = av_clip_uint8(p2 + 128);
- dst[dst_pitch + x + 1] = av_clip_uint8(p3 + 128);
- }// for x
-
- dst += dst_pitch << 1;
-
- b0_ptr += pitch;
- b1_ptr += pitch;
- b2_ptr += pitch;
- b3_ptr += pitch;
- }// for y
-}
-
-/** butterfly operation for the inverse Haar transform */
-#define IVI_HAAR_BFLY(s1, s2, o1, o2, t) \
- t = ((s1) - (s2)) >> 1;\
- o1 = ((s1) + (s2)) >> 1;\
- o2 = (t);\
-
-/** inverse 8-point Haar transform */
-#define INV_HAAR8(s1, s5, s3, s7, s2, s4, s6, s8,\
- d1, d2, d3, d4, d5, d6, d7, d8,\
- t0, t1, t2, t3, t4, t5, t6, t7, t8) {\
- t1 = (s1) << 1; t5 = (s5) << 1;\
- IVI_HAAR_BFLY(t1, t5, t1, t5, t0); IVI_HAAR_BFLY(t1, s3, t1, t3, t0);\
- IVI_HAAR_BFLY(t5, s7, t5, t7, t0); IVI_HAAR_BFLY(t1, s2, t1, t2, t0);\
- IVI_HAAR_BFLY(t3, s4, t3, t4, t0); IVI_HAAR_BFLY(t5, s6, t5, t6, t0);\
- IVI_HAAR_BFLY(t7, s8, t7, t8, t0);\
- d1 = COMPENSATE(t1);\
- d2 = COMPENSATE(t2);\
- d3 = COMPENSATE(t3);\
- d4 = COMPENSATE(t4);\
- d5 = COMPENSATE(t5);\
- d6 = COMPENSATE(t6);\
- d7 = COMPENSATE(t7);\
- d8 = COMPENSATE(t8); }
-
-/** inverse 4-point Haar transform */
-#define INV_HAAR4(s1, s3, s5, s7, d1, d2, d3, d4, t0, t1, t2, t3, t4) {\
- IVI_HAAR_BFLY(s1, s3, t0, t1, t4);\
- IVI_HAAR_BFLY(t0, s5, t2, t3, t4);\
- d1 = COMPENSATE(t2);\
- d2 = COMPENSATE(t3);\
- IVI_HAAR_BFLY(t1, s7, t2, t3, t4);\
- d3 = COMPENSATE(t2);\
- d4 = COMPENSATE(t3); }
-
-void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
- const uint8_t *flags)
-{
- int i, shift, sp1, sp2, sp3, sp4;
- const int32_t *src;
- int32_t *dst;
- int tmp[64];
- int t0, t1, t2, t3, t4, t5, t6, t7, t8;
-
- /* apply the InvHaar8 to all columns */
-#define COMPENSATE(x) (x)
- src = in;
- dst = tmp;
- for (i = 0; i < 8; i++) {
- if (flags[i]) {
- /* pre-scaling */
- shift = !(i & 4);
- sp1 = src[ 0] << shift;
- sp2 = src[ 8] << shift;
- sp3 = src[16] << shift;
- sp4 = src[24] << shift;
- INV_HAAR8( sp1, sp2, sp3, sp4,
- src[32], src[40], src[48], src[56],
- dst[ 0], dst[ 8], dst[16], dst[24],
- dst[32], dst[40], dst[48], dst[56],
- t0, t1, t2, t3, t4, t5, t6, t7, t8);
- } else
- dst[ 0] = dst[ 8] = dst[16] = dst[24] =
- dst[32] = dst[40] = dst[48] = dst[56] = 0;
-
- src++;
- dst++;
- }
-#undef COMPENSATE
-
- /* apply the InvHaar8 to all rows */
-#define COMPENSATE(x) (x)
- src = tmp;
- for (i = 0; i < 8; i++) {
- if ( !src[0] && !src[1] && !src[2] && !src[3]
- && !src[4] && !src[5] && !src[6] && !src[7]) {
- memset(out, 0, 8 * sizeof(out[0]));
- } else {
- INV_HAAR8(src[0], src[1], src[2], src[3],
- src[4], src[5], src[6], src[7],
- out[0], out[1], out[2], out[3],
- out[4], out[5], out[6], out[7],
- t0, t1, t2, t3, t4, t5, t6, t7, t8);
- }
- src += 8;
- out += pitch;
- }
-#undef COMPENSATE
-}
-
-void ff_ivi_row_haar8(const int32_t *in, int16_t *out, uint32_t pitch,
- const uint8_t *flags)
-{
- int i;
- int t0, t1, t2, t3, t4, t5, t6, t7, t8;
-
- /* apply the InvHaar8 to all rows */
-#define COMPENSATE(x) (x)
- for (i = 0; i < 8; i++) {
- if ( !in[0] && !in[1] && !in[2] && !in[3]
- && !in[4] && !in[5] && !in[6] && !in[7]) {
- memset(out, 0, 8 * sizeof(out[0]));
- } else {
- INV_HAAR8(in[0], in[1], in[2], in[3],
- in[4], in[5], in[6], in[7],
- out[0], out[1], out[2], out[3],
- out[4], out[5], out[6], out[7],
- t0, t1, t2, t3, t4, t5, t6, t7, t8);
- }
- in += 8;
- out += pitch;
- }
-#undef COMPENSATE
-}
-
-void ff_ivi_col_haar8(const int32_t *in, int16_t *out, uint32_t pitch,
- const uint8_t *flags)
-{
- int i;
- int t0, t1, t2, t3, t4, t5, t6, t7, t8;
-
- /* apply the InvHaar8 to all columns */
-#define COMPENSATE(x) (x)
- for (i = 0; i < 8; i++) {
- if (flags[i]) {
- INV_HAAR8(in[ 0], in[ 8], in[16], in[24],
- in[32], in[40], in[48], in[56],
- out[0 * pitch], out[1 * pitch],
- out[2 * pitch], out[3 * pitch],
- out[4 * pitch], out[5 * pitch],
- out[6 * pitch], out[7 * pitch],
- t0, t1, t2, t3, t4, t5, t6, t7, t8);
- } else
- out[0 * pitch] = out[1 * pitch] =
- out[2 * pitch] = out[3 * pitch] =
- out[4 * pitch] = out[5 * pitch] =
- out[6 * pitch] = out[7 * pitch] = 0;
-
- in++;
- out++;
- }
-#undef COMPENSATE
-}
-
-void ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, uint32_t pitch,
- const uint8_t *flags)
-{
- int i, shift, sp1, sp2;
- const int32_t *src;
- int32_t *dst;
- int tmp[16];
- int t0, t1, t2, t3, t4;
-
- /* apply the InvHaar4 to all columns */
-#define COMPENSATE(x) (x)
- src = in;
- dst = tmp;
- for (i = 0; i < 4; i++) {
- if (flags[i]) {
- /* pre-scaling */
- shift = !(i & 2);
- sp1 = src[0] << shift;
- sp2 = src[4] << shift;
- INV_HAAR4( sp1, sp2, src[8], src[12],
- dst[0], dst[4], dst[8], dst[12],
- t0, t1, t2, t3, t4);
- } else
- dst[0] = dst[4] = dst[8] = dst[12] = 0;
-
- src++;
- dst++;
- }
-#undef COMPENSATE
-
- /* apply the InvHaar8 to all rows */
-#define COMPENSATE(x) (x)
- src = tmp;
- for (i = 0; i < 4; i++) {
- if (!src[0] && !src[1] && !src[2] && !src[3]) {
- memset(out, 0, 4 * sizeof(out[0]));
- } else {
- INV_HAAR4(src[0], src[1], src[2], src[3],
- out[0], out[1], out[2], out[3],
- t0, t1, t2, t3, t4);
- }
- src += 4;
- out += pitch;
- }
-#undef COMPENSATE
-}
-
-void ff_ivi_row_haar4(const int32_t *in, int16_t *out, uint32_t pitch,
- const uint8_t *flags)
-{
- int i;
- int t0, t1, t2, t3, t4;
-
- /* apply the InvHaar4 to all rows */
-#define COMPENSATE(x) (x)
- for (i = 0; i < 4; i++) {
- if (!in[0] && !in[1] && !in[2] && !in[3]) {
- memset(out, 0, 4 * sizeof(out[0]));
- } else {
- INV_HAAR4(in[0], in[1], in[2], in[3],
- out[0], out[1], out[2], out[3],
- t0, t1, t2, t3, t4);
- }
- in += 4;
- out += pitch;
- }
-#undef COMPENSATE
-}
-
-void ff_ivi_col_haar4(const int32_t *in, int16_t *out, uint32_t pitch,
- const uint8_t *flags)
-{
- int i;
- int t0, t1, t2, t3, t4;
-
- /* apply the InvHaar8 to all columns */
-#define COMPENSATE(x) (x)
- for (i = 0; i < 4; i++) {
- if (flags[i]) {
- INV_HAAR4(in[0], in[4], in[8], in[12],
- out[0 * pitch], out[1 * pitch],
- out[2 * pitch], out[3 * pitch],
- t0, t1, t2, t3, t4);
- } else
- out[0 * pitch] = out[1 * pitch] =
- out[2 * pitch] = out[3 * pitch] = 0;
-
- in++;
- out++;
- }
-#undef COMPENSATE
-}
-
-void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch,
- int blk_size)
-{
- int x, y;
- int16_t dc_coeff;
-
- dc_coeff = (*in + 0) >> 3;
-
- for (y = 0; y < blk_size; out += pitch, y++) {
- for (x = 0; x < blk_size; x++)
- out[x] = dc_coeff;
- }
-}
-
-/** butterfly operation for the inverse slant transform */
-#define IVI_SLANT_BFLY(s1, s2, o1, o2, t) \
- t = (s1) - (s2);\
- o1 = (s1) + (s2);\
- o2 = (t);\
-
-/** This is a reflection a,b = 1/2, 5/4 for the inverse slant transform */
-#define IVI_IREFLECT(s1, s2, o1, o2, t) \
- t = (((s1) + (s2)*2 + 2) >> 2) + (s1);\
- o2 = (((s1)*2 - (s2) + 2) >> 2) - (s2);\
- o1 = (t);\
-
-/** This is a reflection a,b = 1/2, 7/8 for the inverse slant transform */
-#define IVI_SLANT_PART4(s1, s2, o1, o2, t) \
- t = (s2) + (((s1)*4 - (s2) + 4) >> 3);\
- o2 = (s1) + ((-(s1) - (s2)*4 + 4) >> 3);\
- o1 = (t);\
-
-/** inverse slant8 transform */
-#define IVI_INV_SLANT8(s1, s4, s8, s5, s2, s6, s3, s7,\
- d1, d2, d3, d4, d5, d6, d7, d8,\
- t0, t1, t2, t3, t4, t5, t6, t7, t8) {\
- IVI_SLANT_PART4(s4, s5, t4, t5, t0);\
-\
- IVI_SLANT_BFLY(s1, t5, t1, t5, t0); IVI_SLANT_BFLY(s2, s6, t2, t6, t0);\
- IVI_SLANT_BFLY(s7, s3, t7, t3, t0); IVI_SLANT_BFLY(t4, s8, t4, t8, t0);\
-\
- IVI_SLANT_BFLY(t1, t2, t1, t2, t0); IVI_IREFLECT (t4, t3, t4, t3, t0);\
- IVI_SLANT_BFLY(t5, t6, t5, t6, t0); IVI_IREFLECT (t8, t7, t8, t7, t0);\
- IVI_SLANT_BFLY(t1, t4, t1, t4, t0); IVI_SLANT_BFLY(t2, t3, t2, t3, t0);\
- IVI_SLANT_BFLY(t5, t8, t5, t8, t0); IVI_SLANT_BFLY(t6, t7, t6, t7, t0);\
- d1 = COMPENSATE(t1);\
- d2 = COMPENSATE(t2);\
- d3 = COMPENSATE(t3);\
- d4 = COMPENSATE(t4);\
- d5 = COMPENSATE(t5);\
- d6 = COMPENSATE(t6);\
- d7 = COMPENSATE(t7);\
- d8 = COMPENSATE(t8);}
-
-/** inverse slant4 transform */
-#define IVI_INV_SLANT4(s1, s4, s2, s3, d1, d2, d3, d4, t0, t1, t2, t3, t4) {\
- IVI_SLANT_BFLY(s1, s2, t1, t2, t0); IVI_IREFLECT (s4, s3, t4, t3, t0);\
-\
- IVI_SLANT_BFLY(t1, t4, t1, t4, t0); IVI_SLANT_BFLY(t2, t3, t2, t3, t0);\
- d1 = COMPENSATE(t1);\
- d2 = COMPENSATE(t2);\
- d3 = COMPENSATE(t3);\
- d4 = COMPENSATE(t4);}
-
-void ff_ivi_inverse_slant_8x8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
-{
- int i;
- const int32_t *src;
- int32_t *dst;
- int tmp[64];
- int t0, t1, t2, t3, t4, t5, t6, t7, t8;
-
-#define COMPENSATE(x) (x)
- src = in;
- dst = tmp;
- for (i = 0; i < 8; i++) {
- if (flags[i]) {
- IVI_INV_SLANT8(src[0], src[8], src[16], src[24], src[32], src[40], src[48], src[56],
- dst[0], dst[8], dst[16], dst[24], dst[32], dst[40], dst[48], dst[56],
- t0, t1, t2, t3, t4, t5, t6, t7, t8);
- } else
- dst[0] = dst[8] = dst[16] = dst[24] = dst[32] = dst[40] = dst[48] = dst[56] = 0;
-
- src++;
- dst++;
- }
-#undef COMPENSATE
-
-#define COMPENSATE(x) (((x) + 1)>>1)
- src = tmp;
- for (i = 0; i < 8; i++) {
- if (!src[0] && !src[1] && !src[2] && !src[3] && !src[4] && !src[5] && !src[6] && !src[7]) {
- memset(out, 0, 8*sizeof(out[0]));
- } else {
- IVI_INV_SLANT8(src[0], src[1], src[2], src[3], src[4], src[5], src[6], src[7],
- out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
- t0, t1, t2, t3, t4, t5, t6, t7, t8);
- }
- src += 8;
- out += pitch;
- }
-#undef COMPENSATE
-}
-
-void ff_ivi_inverse_slant_4x4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
-{
- int i;
- const int32_t *src;
- int32_t *dst;
- int tmp[16];
- int t0, t1, t2, t3, t4;
-
-#define COMPENSATE(x) (x)
- src = in;
- dst = tmp;
- for (i = 0; i < 4; i++) {
- if (flags[i]) {
- IVI_INV_SLANT4(src[0], src[4], src[8], src[12],
- dst[0], dst[4], dst[8], dst[12],
- t0, t1, t2, t3, t4);
- } else
- dst[0] = dst[4] = dst[8] = dst[12] = 0;
-
- src++;
- dst++;
- }
-#undef COMPENSATE
-
-#define COMPENSATE(x) (((x) + 1)>>1)
- src = tmp;
- for (i = 0; i < 4; i++) {
- if (!src[0] && !src[1] && !src[2] && !src[3]) {
- out[0] = out[1] = out[2] = out[3] = 0;
- } else {
- IVI_INV_SLANT4(src[0], src[1], src[2], src[3],
- out[0], out[1], out[2], out[3],
- t0, t1, t2, t3, t4);
- }
- src += 4;
- out += pitch;
- }
-#undef COMPENSATE
-}
-
-void ff_ivi_dc_slant_2d(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size)
-{
- int x, y;
- int16_t dc_coeff;
-
- dc_coeff = (*in + 1) >> 1;
-
- for (y = 0; y < blk_size; out += pitch, y++) {
- for (x = 0; x < blk_size; x++)
- out[x] = dc_coeff;
- }
-}
-
-void ff_ivi_row_slant8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
-{
- int i;
- int t0, t1, t2, t3, t4, t5, t6, t7, t8;
-
-#define COMPENSATE(x) (((x) + 1)>>1)
- for (i = 0; i < 8; i++) {
- if (!in[0] && !in[1] && !in[2] && !in[3] && !in[4] && !in[5] && !in[6] && !in[7]) {
- memset(out, 0, 8*sizeof(out[0]));
- } else {
- IVI_INV_SLANT8( in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7],
- out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
- t0, t1, t2, t3, t4, t5, t6, t7, t8);
- }
- in += 8;
- out += pitch;
- }
-#undef COMPENSATE
-}
-
-void ff_ivi_dc_row_slant(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size)
-{
- int x, y;
- int16_t dc_coeff;
-
- dc_coeff = (*in + 1) >> 1;
-
- for (x = 0; x < blk_size; x++)
- out[x] = dc_coeff;
-
- out += pitch;
-
- for (y = 1; y < blk_size; out += pitch, y++) {
- for (x = 0; x < blk_size; x++)
- out[x] = 0;
- }
-}
-
-void ff_ivi_col_slant8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
-{
- int i, row2, row4, row8;
- int t0, t1, t2, t3, t4, t5, t6, t7, t8;
-
- row2 = pitch << 1;
- row4 = pitch << 2;
- row8 = pitch << 3;
-
-#define COMPENSATE(x) (((x) + 1)>>1)
- for (i = 0; i < 8; i++) {
- if (flags[i]) {
- IVI_INV_SLANT8(in[0], in[8], in[16], in[24], in[32], in[40], in[48], in[56],
- out[0], out[pitch], out[row2], out[row2 + pitch], out[row4],
- out[row4 + pitch], out[row4 + row2], out[row8 - pitch],
- t0, t1, t2, t3, t4, t5, t6, t7, t8);
- } else {
- out[0] = out[pitch] = out[row2] = out[row2 + pitch] = out[row4] =
- out[row4 + pitch] = out[row4 + row2] = out[row8 - pitch] = 0;
- }
-
- in++;
- out++;
- }
-#undef COMPENSATE
-}
-
-void ff_ivi_dc_col_slant(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size)
-{
- int x, y;
- int16_t dc_coeff;
-
- dc_coeff = (*in + 1) >> 1;
-
- for (y = 0; y < blk_size; out += pitch, y++) {
- out[0] = dc_coeff;
- for (x = 1; x < blk_size; x++)
- out[x] = 0;
- }
-}
-
-void ff_ivi_row_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
-{
- int i;
- int t0, t1, t2, t3, t4;
-
-#define COMPENSATE(x) (((x) + 1)>>1)
- for (i = 0; i < 4; i++) {
- if (!in[0] && !in[1] && !in[2] && !in[3]) {
- memset(out, 0, 4*sizeof(out[0]));
- } else {
- IVI_INV_SLANT4( in[0], in[1], in[2], in[3],
- out[0], out[1], out[2], out[3],
- t0, t1, t2, t3, t4);
- }
- in += 4;
- out += pitch;
- }
-#undef COMPENSATE
-}
-
-void ff_ivi_col_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
-{
- int i, row2;
- int t0, t1, t2, t3, t4;
-
- row2 = pitch << 1;
-
-#define COMPENSATE(x) (((x) + 1)>>1)
- for (i = 0; i < 4; i++) {
- if (flags[i]) {
- IVI_INV_SLANT4(in[0], in[4], in[8], in[12],
- out[0], out[pitch], out[row2], out[row2 + pitch],
- t0, t1, t2, t3, t4);
- } else {
- out[0] = out[pitch] = out[row2] = out[row2 + pitch] = 0;
- }
-
- in++;
- out++;
- }
-#undef COMPENSATE
-}
-
-void ff_ivi_put_pixels_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
- const uint8_t *flags)
-{
- int x, y;
-
- for (y = 0; y < 8; out += pitch, in += 8, y++)
- for (x = 0; x < 8; x++)
- out[x] = in[x];
-}
-
-void ff_ivi_put_dc_pixel_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
- int blk_size)
-{
- int y;
-
- out[0] = in[0];
- memset(out + 1, 0, 7*sizeof(out[0]));
- out += pitch;
-
- for (y = 1; y < 8; out += pitch, y++)
- memset(out, 0, 8*sizeof(out[0]));
-}
-
-#define IVI_MC_TEMPLATE(size, suffix, OP) \
-static void ivi_mc_ ## size ##x## size ## suffix(int16_t *buf, \
- uint32_t dpitch, \
- const int16_t *ref_buf, \
- uint32_t pitch, int mc_type) \
-{ \
- int i, j; \
- const int16_t *wptr; \
-\
- switch (mc_type) { \
- case 0: /* fullpel (no interpolation) */ \
- for (i = 0; i < size; i++, buf += dpitch, ref_buf += pitch) { \
- for (j = 0; j < size; j++) {\
- OP(buf[j], ref_buf[j]); \
- } \
- } \
- break; \
- case 1: /* horizontal halfpel interpolation */ \
- for (i = 0; i < size; i++, buf += dpitch, ref_buf += pitch) \
- for (j = 0; j < size; j++) \
- OP(buf[j], (ref_buf[j] + ref_buf[j+1]) >> 1); \
- break; \
- case 2: /* vertical halfpel interpolation */ \
- wptr = ref_buf + pitch; \
- for (i = 0; i < size; i++, buf += dpitch, wptr += pitch, ref_buf += pitch) \
- for (j = 0; j < size; j++) \
- OP(buf[j], (ref_buf[j] + wptr[j]) >> 1); \
- break; \
- case 3: /* vertical and horizontal halfpel interpolation */ \
- wptr = ref_buf + pitch; \
- for (i = 0; i < size; i++, buf += dpitch, wptr += pitch, ref_buf += pitch) \
- for (j = 0; j < size; j++) \
- OP(buf[j], (ref_buf[j] + ref_buf[j+1] + wptr[j] + wptr[j+1]) >> 2); \
- break; \
- } \
-} \
-\
-void ff_ivi_mc_ ## size ##x## size ## suffix(int16_t *buf, const int16_t *ref_buf, \
- uint32_t pitch, int mc_type) \
-{ \
- ivi_mc_ ## size ##x## size ## suffix(buf, pitch, ref_buf, pitch, mc_type); \
-} \
-
-#define IVI_MC_AVG_TEMPLATE(size, suffix, OP) \
-void ff_ivi_mc_avg_ ## size ##x## size ## suffix(int16_t *buf, \
- const int16_t *ref_buf, \
- const int16_t *ref_buf2, \
- uint32_t pitch, \
- int mc_type, int mc_type2) \
-{ \
- int16_t tmp[size * size]; \
- int i, j; \
-\
- ivi_mc_ ## size ##x## size ## _no_delta(tmp, size, ref_buf, pitch, mc_type); \
- ivi_mc_ ## size ##x## size ## _delta(tmp, size, ref_buf2, pitch, mc_type2); \
- for (i = 0; i < size; i++, buf += pitch) { \
- for (j = 0; j < size; j++) {\
- OP(buf[j], tmp[i * size + j] >> 1); \
- } \
- } \
-} \
-
-#define OP_PUT(a, b) (a) = (b)
-#define OP_ADD(a, b) (a) += (b)
-
-IVI_MC_TEMPLATE(8, _no_delta, OP_PUT)
-IVI_MC_TEMPLATE(8, _delta, OP_ADD)
-IVI_MC_TEMPLATE(4, _no_delta, OP_PUT)
-IVI_MC_TEMPLATE(4, _delta, OP_ADD)
-IVI_MC_AVG_TEMPLATE(8, _no_delta, OP_PUT)
-IVI_MC_AVG_TEMPLATE(8, _delta, OP_ADD)
-IVI_MC_AVG_TEMPLATE(4, _no_delta, OP_PUT)
-IVI_MC_AVG_TEMPLATE(4, _delta, OP_ADD)
diff --git a/ffmpeg-2-8-11/libavcodec/jpeg2000.h b/ffmpeg-2-8-11/libavcodec/jpeg2000.h
deleted file mode 100644
index ed3b421..0000000
--- a/ffmpeg-2-8-11/libavcodec/jpeg2000.h
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * JPEG 2000 common defines, structures and functions
- * Copyright (c) 2007 Kamil Nowosad
- * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu at gmail.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 AVCODEC_JPEG2000_H
-#define AVCODEC_JPEG2000_H
-
-/**
- * @file
- * JPEG 2000 structures and defines common
- * to encoder and decoder
- */
-
-#include <stdint.h>
-
-#include "avcodec.h"
-#include "mqc.h"
-#include "jpeg2000dwt.h"
-
-enum Jpeg2000Markers {
- JPEG2000_SOC = 0xff4f, // start of codestream
- JPEG2000_SIZ = 0xff51, // image and tile size
- JPEG2000_COD, // coding style default
- JPEG2000_COC, // coding style component
- JPEG2000_TLM = 0xff55, // packed packet headers, tile-part header
- JPEG2000_PLM = 0xff57, // tile-part lengths
- JPEG2000_PLT, // packet length, main header
- JPEG2000_QCD = 0xff5c, // quantization default
- JPEG2000_QCC, // quantization component
- JPEG2000_RGN, // region of interest
- JPEG2000_POC, // progression order change
- JPEG2000_PPM, // packet length, tile-part header
- JPEG2000_PPT, // packed packet headers, main header
- JPEG2000_CRG = 0xff63, // component registration
- JPEG2000_COM, // comment
- JPEG2000_SOT = 0xff90, // start of tile-part
- JPEG2000_SOP, // start of packet
- JPEG2000_EPH, // end of packet header
- JPEG2000_SOD, // start of data
- JPEG2000_EOC = 0xffd9, // end of codestream
-};
-
-#define JPEG2000_SOP_FIXED_BYTES 0xFF910004
-#define JPEG2000_SOP_BYTE_LENGTH 6
-
-enum Jpeg2000Quantsty { // quantization style
- JPEG2000_QSTY_NONE, // no quantization
- JPEG2000_QSTY_SI, // scalar derived
- JPEG2000_QSTY_SE // scalar expounded
-};
-
-#define JPEG2000_MAX_DECLEVELS 33
-#define JPEG2000_MAX_RESLEVELS (JPEG2000_MAX_DECLEVELS + 1)
-
-#define JPEG2000_MAX_PASSES 100
-
-// T1 flags
-// flags determining significance of neighbor coefficients
-#define JPEG2000_T1_SIG_N 0x0001
-#define JPEG2000_T1_SIG_E 0x0002
-#define JPEG2000_T1_SIG_W 0x0004
-#define JPEG2000_T1_SIG_S 0x0008
-#define JPEG2000_T1_SIG_NE 0x0010
-#define JPEG2000_T1_SIG_NW 0x0020
-#define JPEG2000_T1_SIG_SE 0x0040
-#define JPEG2000_T1_SIG_SW 0x0080
-#define JPEG2000_T1_SIG_NB (JPEG2000_T1_SIG_N | JPEG2000_T1_SIG_E | \
- JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_W | \
- JPEG2000_T1_SIG_NE | JPEG2000_T1_SIG_NW | \
- JPEG2000_T1_SIG_SE | JPEG2000_T1_SIG_SW)
-// flags determining sign bit of neighbor coefficients
-#define JPEG2000_T1_SGN_N 0x0100
-#define JPEG2000_T1_SGN_S 0x0200
-#define JPEG2000_T1_SGN_W 0x0400
-#define JPEG2000_T1_SGN_E 0x0800
-
-#define JPEG2000_T1_VIS 0x1000
-#define JPEG2000_T1_SIG 0x2000
-#define JPEG2000_T1_REF 0x4000
-
-#define JPEG2000_T1_SGN 0x8000
-
-// Codeblock coding styles
-#define JPEG2000_CBLK_BYPASS 0x01 // Selective arithmetic coding bypass
-#define JPEG2000_CBLK_RESET 0x02 // Reset context probabilities
-#define JPEG2000_CBLK_TERMALL 0x04 // Terminate after each coding pass
-#define JPEG2000_CBLK_VSC 0x08 // Vertical stripe causal context formation
-#define JPEG2000_CBLK_PREDTERM 0x10 // Predictable termination
-#define JPEG2000_CBLK_SEGSYM 0x20 // Segmentation symbols present
-
-// Coding styles
-#define JPEG2000_CSTY_PREC 0x01 // Precincts defined in coding style
-#define JPEG2000_CSTY_SOP 0x02 // SOP marker present
-#define JPEG2000_CSTY_EPH 0x04 // EPH marker present
-
-// Progression orders
-#define JPEG2000_PGOD_LRCP 0x00 // Layer-resolution level-component-position progression
-#define JPEG2000_PGOD_RLCP 0x01 // Resolution level-layer-component-position progression
-#define JPEG2000_PGOD_RPCL 0x02 // Resolution level-position-component-layer progression
-#define JPEG2000_PGOD_PCRL 0x03 // Position-component-resolution level-layer progression
-#define JPEG2000_PGOD_CPRL 0x04 // Component-position-resolution level-layer progression
-
-typedef struct Jpeg2000T1Context {
- int data[6144];
- uint16_t flags[6156];
- MqcState mqc;
- int stride;
-} Jpeg2000T1Context;
-
-typedef struct Jpeg2000TgtNode {
- uint8_t val;
- uint8_t vis;
- struct Jpeg2000TgtNode *parent;
-} Jpeg2000TgtNode;
-
-typedef struct Jpeg2000CodingStyle {
- int nreslevels; // number of resolution levels
- int nreslevels2decode; // number of resolution levels to decode
- uint8_t log2_cblk_width,
- log2_cblk_height; // exponent of codeblock size
- uint8_t transform; // DWT type
- uint8_t csty; // coding style
- uint8_t nlayers; // number of layers
- uint8_t mct; // multiple component transformation
- uint8_t cblk_style; // codeblock coding style
- 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?
-} Jpeg2000CodingStyle;
-
-typedef struct Jpeg2000QuantStyle {
- uint8_t expn[JPEG2000_MAX_DECLEVELS * 3]; // quantization exponent
- uint16_t mant[JPEG2000_MAX_DECLEVELS * 3]; // quantization mantissa
- uint8_t quantsty; // quantization style
- uint8_t nguardbits; // number of guard bits
-} Jpeg2000QuantStyle;
-
-typedef struct Jpeg2000Pass {
- uint16_t rate;
- int64_t disto;
- uint8_t flushed[4];
- int flushed_len;
-} Jpeg2000Pass;
-
-typedef struct Jpeg2000Cblk {
- uint8_t npasses;
- uint8_t ninclpasses; // number coding of passes included in codestream
- uint8_t nonzerobits;
- uint16_t length;
- uint16_t lengthinc[JPEG2000_MAX_PASSES];
- uint8_t nb_lengthinc;
- uint8_t lblock;
- uint8_t zero;
- uint8_t data[8192];
- int nb_terminations;
- int nb_terminationsinc;
- int data_start[JPEG2000_MAX_PASSES];
- Jpeg2000Pass passes[JPEG2000_MAX_PASSES];
- int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
-} Jpeg2000Cblk; // code block
-
-typedef struct Jpeg2000Prec {
- int nb_codeblocks_width;
- int nb_codeblocks_height;
- Jpeg2000TgtNode *zerobits;
- Jpeg2000TgtNode *cblkincl;
- Jpeg2000Cblk *cblk;
- int decoded_layers;
- int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
-} Jpeg2000Prec; // precinct
-
-typedef struct Jpeg2000Band {
- int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
- uint16_t log2_cblk_width, log2_cblk_height;
- int i_stepsize; // quantization stepsize
- float f_stepsize; // quantization stepsize
- Jpeg2000Prec *prec;
-} Jpeg2000Band; // subband
-
-typedef struct Jpeg2000ResLevel {
- uint8_t nbands;
- int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
- int num_precincts_x, num_precincts_y; // number of precincts in x/y direction
- uint8_t log2_prec_width, log2_prec_height; // exponent of precinct size
- Jpeg2000Band *band;
-} Jpeg2000ResLevel; // resolution level
-
-typedef struct Jpeg2000Component {
- Jpeg2000ResLevel *reslevel;
- DWTContext dwt;
- float *f_data;
- int *i_data;
- int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}} -- can be reduced with lowres option
- int coord_o[2][2]; // border coordinates {{x0, x1}, {y0, y1}} -- original values from jpeg2000 headers
-} Jpeg2000Component;
-
-/* misc tools */
-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)
-{
- return (a + b - 1) / b;
-}
-
-/* TIER-1 routines */
-
-/* Set up lookup tables used in TIER-1. */
-void ff_jpeg2000_init_tier1_luts(void);
-
-/* Update significance of a coefficient at current position (x,y) and
- * for neighbors. */
-void ff_jpeg2000_set_significance(Jpeg2000T1Context *t1,
- int x, int y, int negative);
-
-extern uint8_t ff_jpeg2000_sigctxno_lut[256][4];
-
-/* Get context label (number in range[0..8]) of a coefficient for significance
- * propagation and cleanup coding passes. */
-static inline int ff_jpeg2000_getsigctxno(int flag, int bandno)
-{
- return ff_jpeg2000_sigctxno_lut[flag & 255][bandno];
-}
-
-static const uint8_t refctxno_lut[2][2] = { { 14, 15 }, { 16, 16 } };
-
-/* Get context label (number in range[14..16]) of a coefficient for magnitude
- * refinement pass. */
-static inline int ff_jpeg2000_getrefctxno(int flag)
-{
- return refctxno_lut[(flag >> 14) & 1][(flag & 255) != 0];
-}
-
-extern uint8_t ff_jpeg2000_sgnctxno_lut[16][16];
-extern uint8_t ff_jpeg2000_xorbit_lut[16][16];
-
-/* Get context label (number in range[9..13]) for sign decoding. */
-static inline int ff_jpeg2000_getsgnctxno(int flag, int *xorbit)
-{
- *xorbit = ff_jpeg2000_xorbit_lut[flag & 15][(flag >> 8) & 15];
- return ff_jpeg2000_sgnctxno_lut[flag & 15][(flag >> 8) & 15];
-}
-
-int ff_jpeg2000_init_component(Jpeg2000Component *comp,
- Jpeg2000CodingStyle *codsty,
- Jpeg2000QuantStyle *qntsty,
- int cbps, int dx, int dy,
- AVCodecContext *ctx);
-
-void ff_jpeg2000_reinit(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty);
-
-void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty);
-
-static inline int needs_termination(int style, int passno) {
- if (style & JPEG2000_CBLK_BYPASS) {
- int type = passno % 3;
- passno /= 3;
- if (type == 0 && passno > 2)
- return 2;
- if (type == 2 && passno > 2)
- return 1;
- if (style & JPEG2000_CBLK_TERMALL) {
- return passno > 2 ? 2 : 1;
- }
- }
- if (style & JPEG2000_CBLK_TERMALL)
- return 1;
- return 0;
-}
-
-#endif /* AVCODEC_JPEG2000_H */
diff --git a/ffmpeg-2-8-11/libavcodec/jpeg2000dec.c b/ffmpeg-2-8-11/libavcodec/jpeg2000dec.c
deleted file mode 100644
index c4705cf..0000000
--- a/ffmpeg-2-8-11/libavcodec/jpeg2000dec.c
+++ /dev/null
@@ -1,2191 +0,0 @@
-/*
- * JPEG 2000 image decoder
- * Copyright (c) 2007 Kamil Nowosad
- * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu at gmail.com>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * JPEG 2000 image decoder
- */
-
-#include <inttypes.h>
-
-#include "libavutil/attributes.h"
-#include "libavutil/avassert.h"
-#include "libavutil/common.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/opt.h"
-#include "libavutil/pixdesc.h"
-#include "avcodec.h"
-#include "bytestream.h"
-#include "internal.h"
-#include "thread.h"
-#include "jpeg2000.h"
-#include "jpeg2000dsp.h"
-
-#define JP2_SIG_TYPE 0x6A502020
-#define JP2_SIG_VALUE 0x0D0A870A
-#define JP2_CODESTREAM 0x6A703263
-#define JP2_HEADER 0x6A703268
-
-#define HAD_COC 0x01
-#define HAD_QCC 0x02
-
-#define MAX_POCS 32
-
-typedef struct Jpeg2000POCEntry {
- uint16_t LYEpoc;
- uint16_t CSpoc;
- uint16_t CEpoc;
- uint8_t RSpoc;
- uint8_t REpoc;
- uint8_t Ppoc;
-} Jpeg2000POCEntry;
-
-typedef struct Jpeg2000POC {
- Jpeg2000POCEntry poc[MAX_POCS];
- int nb_poc;
- int is_default;
-} Jpeg2000POC;
-
-typedef struct Jpeg2000TilePart {
- uint8_t tile_index; // Tile index who refers the tile-part
- const uint8_t *tp_end;
- GetByteContext tpg; // bit stream in tile-part
-} Jpeg2000TilePart;
-
-/* RMK: For JPEG2000 DCINEMA 3 tile-parts in a tile
- * one per component, so tile_part elements have a size of 3 */
-typedef struct Jpeg2000Tile {
- Jpeg2000Component *comp;
- uint8_t properties[4];
- Jpeg2000CodingStyle codsty[4];
- Jpeg2000QuantStyle qntsty[4];
- Jpeg2000POC poc;
- Jpeg2000TilePart tile_part[256];
- uint16_t tp_idx; // Tile-part index
- int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
-} Jpeg2000Tile;
-
-typedef struct Jpeg2000DecoderContext {
- AVClass *class;
- AVCodecContext *avctx;
- GetByteContext g;
-
- int width, height;
- int image_offset_x, image_offset_y;
- int tile_offset_x, tile_offset_y;
- uint8_t cbps[4]; // bits per sample in particular components
- uint8_t sgnd[4]; // if a component is signed
- uint8_t properties[4];
- int cdx[4], cdy[4];
- int precision;
- int ncomponents;
- int colour_space;
- uint32_t palette[256];
- int8_t pal8;
- int cdef[4];
- int tile_width, tile_height;
- unsigned numXtiles, numYtiles;
- int maxtilelen;
-
- Jpeg2000CodingStyle codsty[4];
- Jpeg2000QuantStyle qntsty[4];
- Jpeg2000POC poc;
-
- int bit_index;
-
- int curtileno;
-
- Jpeg2000Tile *tile;
- Jpeg2000DSPContext dsp;
-
- /*options parameters*/
- int reduction_factor;
-} Jpeg2000DecoderContext;
-
-/* get_bits functions for JPEG2000 packet bitstream
- * It is a get_bit function with a bit-stuffing routine. If the value of the
- * byte is 0xFF, the next byte includes an extra zero bit stuffed into the MSB.
- * cf. ISO-15444-1:2002 / B.10.1 Bit-stuffing routine */
-static int get_bits(Jpeg2000DecoderContext *s, int n)
-{
- int res = 0;
-
- while (--n >= 0) {
- res <<= 1;
- if (s->bit_index == 0) {
- s->bit_index = 7 + (bytestream2_get_byte(&s->g) != 0xFFu);
- }
- s->bit_index--;
- res |= (bytestream2_peek_byte(&s->g) >> s->bit_index) & 1;
- }
- return res;
-}
-
-static void jpeg2000_flush(Jpeg2000DecoderContext *s)
-{
- if (bytestream2_get_byte(&s->g) == 0xff)
- bytestream2_skip(&s->g, 1);
- s->bit_index = 8;
-}
-
-/* decode the value stored in node */
-static int tag_tree_decode(Jpeg2000DecoderContext *s, Jpeg2000TgtNode *node,
- int threshold)
-{
- Jpeg2000TgtNode *stack[30];
- int sp = -1, curval = 0;
-
- if (!node) {
- av_log(s->avctx, AV_LOG_ERROR, "missing node\n");
- return AVERROR_INVALIDDATA;
- }
-
- while (node && !node->vis) {
- stack[++sp] = node;
- node = node->parent;
- }
-
- if (node)
- curval = node->val;
- else
- curval = stack[sp]->val;
-
- while (curval < threshold && sp >= 0) {
- if (curval < stack[sp]->val)
- curval = stack[sp]->val;
- while (curval < threshold) {
- int ret;
- if ((ret = get_bits(s, 1)) > 0) {
- stack[sp]->vis++;
- break;
- } else if (!ret)
- curval++;
- else
- return ret;
- }
- stack[sp]->val = curval;
- sp--;
- }
- return curval;
-}
-
-static int pix_fmt_match(enum AVPixelFormat pix_fmt, int components,
- int bpc, uint32_t log2_chroma_wh, int pal8)
-{
- int match = 1;
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
-
- av_assert2(desc);
-
- if (desc->nb_components != components) {
- return 0;
- }
-
- switch (components) {
- case 4:
- match = match && desc->comp[3].depth_minus1 + 1 >= bpc &&
- (log2_chroma_wh >> 14 & 3) == 0 &&
- (log2_chroma_wh >> 12 & 3) == 0;
- case 3:
- match = match && desc->comp[2].depth_minus1 + 1 >= bpc &&
- (log2_chroma_wh >> 10 & 3) == desc->log2_chroma_w &&
- (log2_chroma_wh >> 8 & 3) == desc->log2_chroma_h;
- case 2:
- match = match && desc->comp[1].depth_minus1 + 1 >= bpc &&
- (log2_chroma_wh >> 6 & 3) == desc->log2_chroma_w &&
- (log2_chroma_wh >> 4 & 3) == desc->log2_chroma_h;
-
- case 1:
- match = match && desc->comp[0].depth_minus1 + 1 >= bpc &&
- (log2_chroma_wh >> 2 & 3) == 0 &&
- (log2_chroma_wh & 3) == 0 &&
- (desc->flags & AV_PIX_FMT_FLAG_PAL) == pal8 * AV_PIX_FMT_FLAG_PAL;
- }
- return match;
-}
-
-// pix_fmts with lower bpp have to be listed before
-// similar pix_fmts with higher bpp.
-#define RGB_PIXEL_FORMATS AV_PIX_FMT_PAL8,AV_PIX_FMT_RGB24,AV_PIX_FMT_RGBA,AV_PIX_FMT_RGB48,AV_PIX_FMT_RGBA64
-#define GRAY_PIXEL_FORMATS AV_PIX_FMT_GRAY8,AV_PIX_FMT_GRAY8A,AV_PIX_FMT_GRAY16,AV_PIX_FMT_YA16
-#define YUV_PIXEL_FORMATS AV_PIX_FMT_YUV410P,AV_PIX_FMT_YUV411P,AV_PIX_FMT_YUVA420P, \
- AV_PIX_FMT_YUV420P,AV_PIX_FMT_YUV422P,AV_PIX_FMT_YUVA422P, \
- AV_PIX_FMT_YUV440P,AV_PIX_FMT_YUV444P,AV_PIX_FMT_YUVA444P, \
- AV_PIX_FMT_YUV420P9,AV_PIX_FMT_YUV422P9,AV_PIX_FMT_YUV444P9, \
- AV_PIX_FMT_YUVA420P9,AV_PIX_FMT_YUVA422P9,AV_PIX_FMT_YUVA444P9, \
- AV_PIX_FMT_YUV420P10,AV_PIX_FMT_YUV422P10,AV_PIX_FMT_YUV444P10, \
- AV_PIX_FMT_YUVA420P10,AV_PIX_FMT_YUVA422P10,AV_PIX_FMT_YUVA444P10, \
- 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_YUV420P16,AV_PIX_FMT_YUV422P16,AV_PIX_FMT_YUV444P16, \
- AV_PIX_FMT_YUVA420P16,AV_PIX_FMT_YUVA422P16,AV_PIX_FMT_YUVA444P16
-#define XYZ_PIXEL_FORMATS AV_PIX_FMT_XYZ12
-
-static const enum AVPixelFormat rgb_pix_fmts[] = {RGB_PIXEL_FORMATS};
-static const enum AVPixelFormat gray_pix_fmts[] = {GRAY_PIXEL_FORMATS};
-static const enum AVPixelFormat yuv_pix_fmts[] = {YUV_PIXEL_FORMATS};
-static const enum AVPixelFormat xyz_pix_fmts[] = {XYZ_PIXEL_FORMATS,
- YUV_PIXEL_FORMATS};
-static const enum AVPixelFormat all_pix_fmts[] = {RGB_PIXEL_FORMATS,
- GRAY_PIXEL_FORMATS,
- YUV_PIXEL_FORMATS,
- XYZ_PIXEL_FORMATS};
-
-/* marker segments */
-/* get sizes and offsets of image, tiles; number of components */
-static int get_siz(Jpeg2000DecoderContext *s)
-{
- int i;
- int ncomponents;
- uint32_t log2_chroma_wh = 0;
- const enum AVPixelFormat *possible_fmts = NULL;
- int possible_fmts_nb = 0;
-
- if (bytestream2_get_bytes_left(&s->g) < 36) {
- av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for SIZ\n");
- return AVERROR_INVALIDDATA;
- }
-
- s->avctx->profile = bytestream2_get_be16u(&s->g); // Rsiz
- s->width = bytestream2_get_be32u(&s->g); // Width
- s->height = bytestream2_get_be32u(&s->g); // Height
- s->image_offset_x = bytestream2_get_be32u(&s->g); // X0Siz
- s->image_offset_y = bytestream2_get_be32u(&s->g); // Y0Siz
- s->tile_width = bytestream2_get_be32u(&s->g); // XTSiz
- s->tile_height = bytestream2_get_be32u(&s->g); // YTSiz
- s->tile_offset_x = bytestream2_get_be32u(&s->g); // XT0Siz
- s->tile_offset_y = bytestream2_get_be32u(&s->g); // YT0Siz
- 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_size(s->width, s->height, 0, s->avctx)) {
- avpriv_request_sample(s->avctx, "Large Dimensions");
- return AVERROR_PATCHWELCOME;
- }
-
- if (ncomponents <= 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid number of components: %d\n",
- s->ncomponents);
- return AVERROR_INVALIDDATA;
- }
-
- if (ncomponents > 4) {
- avpriv_request_sample(s->avctx, "Support for %d components",
- ncomponents);
- return AVERROR_PATCHWELCOME;
- }
-
- s->ncomponents = ncomponents;
-
- if (s->tile_width <= 0 || s->tile_height <= 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid tile dimension %dx%d.\n",
- s->tile_width, s->tile_height);
- return AVERROR_INVALIDDATA;
- }
-
- if (bytestream2_get_bytes_left(&s->g) < 3 * s->ncomponents) {
- av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for %d components in SIZ\n", s->ncomponents);
- return AVERROR_INVALIDDATA;
- }
-
- for (i = 0; i < s->ncomponents; i++) { // Ssiz_i XRsiz_i, YRsiz_i
- uint8_t x = bytestream2_get_byteu(&s->g);
- s->cbps[i] = (x & 0x7f) + 1;
- s->precision = FFMAX(s->cbps[i], s->precision);
- s->sgnd[i] = !!(x & 0x80);
- s->cdx[i] = bytestream2_get_byteu(&s->g);
- s->cdy[i] = bytestream2_get_byteu(&s->g);
- if ( !s->cdx[i] || s->cdx[i] == 3 || s->cdx[i] > 4
- || !s->cdy[i] || s->cdy[i] == 3 || s->cdy[i] > 4) {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid sample separation %d/%d\n", s->cdx[i], s->cdy[i]);
- return AVERROR_INVALIDDATA;
- }
- log2_chroma_wh |= s->cdy[i] >> 1 << i * 4 | s->cdx[i] >> 1 << i * 4 + 2;
- }
-
- s->numXtiles = ff_jpeg2000_ceildiv(s->width - s->tile_offset_x, s->tile_width);
- s->numYtiles = ff_jpeg2000_ceildiv(s->height - s->tile_offset_y, s->tile_height);
-
- if (s->numXtiles * (uint64_t)s->numYtiles > INT_MAX/sizeof(*s->tile)) {
- s->numXtiles = s->numYtiles = 0;
- return AVERROR(EINVAL);
- }
-
- s->tile = av_mallocz_array(s->numXtiles * s->numYtiles, sizeof(*s->tile));
- if (!s->tile) {
- s->numXtiles = s->numYtiles = 0;
- return AVERROR(ENOMEM);
- }
-
- for (i = 0; i < s->numXtiles * s->numYtiles; i++) {
- Jpeg2000Tile *tile = s->tile + i;
-
- tile->comp = av_mallocz(s->ncomponents * sizeof(*tile->comp));
- if (!tile->comp)
- return AVERROR(ENOMEM);
- }
-
- /* compute image size with reduction factor */
- s->avctx->width = ff_jpeg2000_ceildivpow2(s->width - s->image_offset_x,
- s->reduction_factor);
- s->avctx->height = ff_jpeg2000_ceildivpow2(s->height - s->image_offset_y,
- s->reduction_factor);
-
- if (s->avctx->profile == FF_PROFILE_JPEG2000_DCINEMA_2K ||
- s->avctx->profile == FF_PROFILE_JPEG2000_DCINEMA_4K) {
- possible_fmts = xyz_pix_fmts;
- possible_fmts_nb = FF_ARRAY_ELEMS(xyz_pix_fmts);
- } else {
- switch (s->colour_space) {
- case 16:
- possible_fmts = rgb_pix_fmts;
- possible_fmts_nb = FF_ARRAY_ELEMS(rgb_pix_fmts);
- break;
- case 17:
- possible_fmts = gray_pix_fmts;
- possible_fmts_nb = FF_ARRAY_ELEMS(gray_pix_fmts);
- break;
- case 18:
- possible_fmts = yuv_pix_fmts;
- possible_fmts_nb = FF_ARRAY_ELEMS(yuv_pix_fmts);
- break;
- default:
- possible_fmts = all_pix_fmts;
- possible_fmts_nb = FF_ARRAY_ELEMS(all_pix_fmts);
- break;
- }
- }
- for (i = 0; i < possible_fmts_nb; ++i) {
- if (pix_fmt_match(possible_fmts[i], ncomponents, s->precision, log2_chroma_wh, s->pal8)) {
- s->avctx->pix_fmt = possible_fmts[i];
- break;
- }
- }
-
- if (i == possible_fmts_nb) {
- if (ncomponents == 4 &&
- s->cdy[0] == 1 && s->cdx[0] == 1 &&
- s->cdy[1] == 1 && s->cdx[1] == 1 &&
- s->cdy[2] == s->cdy[3] && s->cdx[2] == s->cdx[3]) {
- if (s->precision == 8 && s->cdy[2] == 2 && s->cdx[2] == 2 && !s->pal8) {
- s->avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
- s->cdef[0] = 0;
- s->cdef[1] = 1;
- s->cdef[2] = 2;
- s->cdef[3] = 3;
- i = 0;
- }
- }
- }
-
-
- if (i == possible_fmts_nb) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Unknown pix_fmt, profile: %d, colour_space: %d, "
- "components: %d, precision: %d\n"
- "cdx[0]: %d, cdy[0]: %d\n"
- "cdx[1]: %d, cdy[1]: %d\n"
- "cdx[2]: %d, cdy[2]: %d\n"
- "cdx[3]: %d, cdy[3]: %d\n",
- s->avctx->profile, s->colour_space, ncomponents, s->precision,
- s->cdx[0],
- s->cdy[0],
- ncomponents > 1 ? s->cdx[1] : 0,
- ncomponents > 1 ? s->cdy[1] : 0,
- ncomponents > 2 ? s->cdx[2] : 0,
- ncomponents > 2 ? s->cdy[2] : 0,
- ncomponents > 3 ? s->cdx[3] : 0,
- ncomponents > 3 ? s->cdy[3] : 0);
- return AVERROR_PATCHWELCOME;
- }
- s->avctx->bits_per_raw_sample = s->precision;
- return 0;
-}
-
-/* get common part for COD and COC segments */
-static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c)
-{
- uint8_t byte;
-
- if (bytestream2_get_bytes_left(&s->g) < 5) {
- av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for COX\n");
- return AVERROR_INVALIDDATA;
- }
-
- /* nreslevels = number of resolution levels
- = number of decomposition level +1 */
- c->nreslevels = bytestream2_get_byteu(&s->g) + 1;
- if (c->nreslevels >= JPEG2000_MAX_RESLEVELS) {
- av_log(s->avctx, AV_LOG_ERROR, "nreslevels %d is invalid\n", c->nreslevels);
- return AVERROR_INVALIDDATA;
- }
-
- if (c->nreslevels <= s->reduction_factor) {
- /* we are forced to update reduction_factor as its requested value is
- not compatible with this bitstream, and as we might have used it
- already in setup earlier we have to fail this frame until
- reinitialization is implemented */
- av_log(s->avctx, AV_LOG_ERROR, "reduction_factor too large for this bitstream, max is %d\n", c->nreslevels - 1);
- s->reduction_factor = c->nreslevels - 1;
- return AVERROR(EINVAL);
- }
-
- /* compute number of resolution levels to decode */
- c->nreslevels2decode = c->nreslevels - s->reduction_factor;
-
- c->log2_cblk_width = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk width
- c->log2_cblk_height = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk height
-
- if (c->log2_cblk_width > 10 || c->log2_cblk_height > 10 ||
- c->log2_cblk_width + c->log2_cblk_height > 12) {
- av_log(s->avctx, AV_LOG_ERROR, "cblk size invalid\n");
- return AVERROR_INVALIDDATA;
- }
-
- c->cblk_style = bytestream2_get_byteu(&s->g);
- if (c->cblk_style != 0) { // cblk style
- av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style);
- if (c->cblk_style & JPEG2000_CBLK_BYPASS)
- av_log(s->avctx, AV_LOG_WARNING, "Selective arithmetic coding bypass\n");
- }
- c->transform = bytestream2_get_byteu(&s->g); // DWT transformation type
- /* set integer 9/7 DWT in case of BITEXACT flag */
- if ((s->avctx->flags & AV_CODEC_FLAG_BITEXACT) && (c->transform == FF_DWT97))
- c->transform = FF_DWT97_INT;
- else if (c->transform == FF_DWT53) {
- s->avctx->properties |= FF_CODEC_PROPERTY_LOSSLESS;
- }
-
- if (c->csty & JPEG2000_CSTY_PREC) {
- int i;
- for (i = 0; i < c->nreslevels; i++) {
- byte = bytestream2_get_byte(&s->g);
- c->log2_prec_widths[i] = byte & 0x0F; // precinct PPx
- c->log2_prec_heights[i] = (byte >> 4) & 0x0F; // precinct PPy
- if (i)
- if (c->log2_prec_widths[i] == 0 || c->log2_prec_heights[i] == 0) {
- av_log(s->avctx, AV_LOG_ERROR, "PPx %d PPy %d invalid\n",
- c->log2_prec_widths[i], c->log2_prec_heights[i]);
- c->log2_prec_widths[i] = c->log2_prec_heights[i] = 1;
- return AVERROR_INVALIDDATA;
- }
- }
- } else {
- memset(c->log2_prec_widths , 15, sizeof(c->log2_prec_widths ));
- memset(c->log2_prec_heights, 15, sizeof(c->log2_prec_heights));
- }
- return 0;
-}
-
-/* get coding parameters for a particular tile or whole image*/
-static int get_cod(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c,
- uint8_t *properties)
-{
- Jpeg2000CodingStyle tmp;
- int compno, ret;
-
- if (bytestream2_get_bytes_left(&s->g) < 5) {
- av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for COD\n");
- return AVERROR_INVALIDDATA;
- }
-
- tmp.csty = bytestream2_get_byteu(&s->g);
-
- // get progression order
- tmp.prog_order = bytestream2_get_byteu(&s->g);
-
- tmp.nlayers = bytestream2_get_be16u(&s->g);
- tmp.mct = bytestream2_get_byteu(&s->g); // multiple component transformation
-
- if (tmp.mct && s->ncomponents < 3) {
- av_log(s->avctx, AV_LOG_ERROR,
- "MCT %"PRIu8" with too few components (%d)\n",
- tmp.mct, s->ncomponents);
- return AVERROR_INVALIDDATA;
- }
-
- if ((ret = get_cox(s, &tmp)) < 0)
- return ret;
-
- for (compno = 0; compno < s->ncomponents; compno++)
- if (!(properties[compno] & HAD_COC))
- memcpy(c + compno, &tmp, sizeof(tmp));
- return 0;
-}
-
-/* Get coding parameters for a component in the whole image or a
- * particular tile. */
-static int get_coc(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c,
- uint8_t *properties)
-{
- int compno, ret;
-
- if (bytestream2_get_bytes_left(&s->g) < 2) {
- av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for COC\n");
- return AVERROR_INVALIDDATA;
- }
-
- compno = bytestream2_get_byteu(&s->g);
-
- if (compno >= s->ncomponents) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Invalid compno %d. There are %d components in the image.\n",
- compno, s->ncomponents);
- return AVERROR_INVALIDDATA;
- }
-
- c += compno;
- c->csty = bytestream2_get_byteu(&s->g);
-
- if ((ret = get_cox(s, c)) < 0)
- return ret;
-
- properties[compno] |= HAD_COC;
- return 0;
-}
-
-/* Get common part for QCD and QCC segments. */
-static int get_qcx(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q)
-{
- int i, x;
-
- if (bytestream2_get_bytes_left(&s->g) < 1)
- return AVERROR_INVALIDDATA;
-
- x = bytestream2_get_byteu(&s->g); // Sqcd
-
- q->nguardbits = x >> 5;
- q->quantsty = x & 0x1f;
-
- if (q->quantsty == JPEG2000_QSTY_NONE) {
- n -= 3;
- if (bytestream2_get_bytes_left(&s->g) < n ||
- n > JPEG2000_MAX_DECLEVELS*3)
- return AVERROR_INVALIDDATA;
- for (i = 0; i < n; i++)
- q->expn[i] = bytestream2_get_byteu(&s->g) >> 3;
- } else if (q->quantsty == JPEG2000_QSTY_SI) {
- if (bytestream2_get_bytes_left(&s->g) < 2)
- return AVERROR_INVALIDDATA;
- x = bytestream2_get_be16u(&s->g);
- q->expn[0] = x >> 11;
- q->mant[0] = x & 0x7ff;
- for (i = 1; i < JPEG2000_MAX_DECLEVELS * 3; i++) {
- int curexpn = FFMAX(0, q->expn[0] - (i - 1) / 3);
- q->expn[i] = curexpn;
- q->mant[i] = q->mant[0];
- }
- } else {
- n = (n - 3) >> 1;
- if (bytestream2_get_bytes_left(&s->g) < 2 * n ||
- n > JPEG2000_MAX_DECLEVELS*3)
- return AVERROR_INVALIDDATA;
- for (i = 0; i < n; i++) {
- x = bytestream2_get_be16u(&s->g);
- q->expn[i] = x >> 11;
- q->mant[i] = x & 0x7ff;
- }
- }
- return 0;
-}
-
-/* Get quantization parameters for a particular tile or a whole image. */
-static int get_qcd(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q,
- uint8_t *properties)
-{
- Jpeg2000QuantStyle tmp;
- int compno, ret;
-
- memset(&tmp, 0, sizeof(tmp));
-
- if ((ret = get_qcx(s, n, &tmp)) < 0)
- return ret;
- for (compno = 0; compno < s->ncomponents; compno++)
- if (!(properties[compno] & HAD_QCC))
- memcpy(q + compno, &tmp, sizeof(tmp));
- return 0;
-}
-
-/* Get quantization parameters for a component in the whole image
- * on in a particular tile. */
-static int get_qcc(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q,
- uint8_t *properties)
-{
- int compno;
-
- if (bytestream2_get_bytes_left(&s->g) < 1)
- return AVERROR_INVALIDDATA;
-
- compno = bytestream2_get_byteu(&s->g);
-
- if (compno >= s->ncomponents) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Invalid compno %d. There are %d components in the image.\n",
- compno, s->ncomponents);
- return AVERROR_INVALIDDATA;
- }
-
- properties[compno] |= HAD_QCC;
- return get_qcx(s, n - 1, q + compno);
-}
-
-static int get_poc(Jpeg2000DecoderContext *s, int size, Jpeg2000POC *p)
-{
- int i;
- int elem_size = s->ncomponents <= 257 ? 7 : 9;
- Jpeg2000POC tmp = {{{0}}};
-
- if (bytestream2_get_bytes_left(&s->g) < 5 || size < 2 + elem_size) {
- av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for POC\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (elem_size > 7) {
- avpriv_request_sample(s->avctx, "Fat POC not supported");
- return AVERROR_PATCHWELCOME;
- }
-
- tmp.nb_poc = (size - 2) / elem_size;
- if (tmp.nb_poc > MAX_POCS) {
- avpriv_request_sample(s->avctx, "Too many POCs (%d)", tmp.nb_poc);
- return AVERROR_PATCHWELCOME;
- }
-
- for (i = 0; i<tmp.nb_poc; i++) {
- Jpeg2000POCEntry *e = &tmp.poc[i];
- e->RSpoc = bytestream2_get_byteu(&s->g);
- e->CSpoc = bytestream2_get_byteu(&s->g);
- e->LYEpoc = bytestream2_get_be16u(&s->g);
- e->REpoc = bytestream2_get_byteu(&s->g);
- e->CEpoc = bytestream2_get_byteu(&s->g);
- e->Ppoc = bytestream2_get_byteu(&s->g);
- if (!e->CEpoc)
- e->CEpoc = 256;
- if (e->CEpoc > s->ncomponents)
- e->CEpoc = s->ncomponents;
- if ( e->RSpoc >= e->REpoc || e->REpoc > 33
- || e->CSpoc >= e->CEpoc || e->CEpoc > s->ncomponents
- || !e->LYEpoc) {
- av_log(s->avctx, AV_LOG_ERROR, "POC Entry %d is invalid (%d, %d, %d, %d, %d, %d)\n", i,
- e->RSpoc, e->CSpoc, e->LYEpoc, e->REpoc, e->CEpoc, e->Ppoc
- );
- return AVERROR_INVALIDDATA;
- }
- }
-
- if (!p->nb_poc || p->is_default) {
- *p = tmp;
- } else {
- if (p->nb_poc + tmp.nb_poc > MAX_POCS) {
- av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for POC\n");
- return AVERROR_INVALIDDATA;
- }
- memcpy(p->poc + p->nb_poc, tmp.poc, tmp.nb_poc * sizeof(tmp.poc[0]));
- p->nb_poc += tmp.nb_poc;
- }
-
- p->is_default = 0;
-
- return 0;
-}
-
-
-/* Get start of tile segment. */
-static int get_sot(Jpeg2000DecoderContext *s, int n)
-{
- Jpeg2000TilePart *tp;
- uint16_t Isot;
- uint32_t Psot;
- unsigned TPsot;
-
- if (bytestream2_get_bytes_left(&s->g) < 8)
- return AVERROR_INVALIDDATA;
-
- s->curtileno = 0;
- Isot = bytestream2_get_be16u(&s->g); // Isot
- if (Isot >= s->numXtiles * s->numYtiles)
- return AVERROR_INVALIDDATA;
-
- s->curtileno = Isot;
- Psot = bytestream2_get_be32u(&s->g); // Psot
- TPsot = bytestream2_get_byteu(&s->g); // TPsot
-
- /* Read TNSot but not used */
- bytestream2_get_byteu(&s->g); // TNsot
-
- if (!Psot)
- Psot = bytestream2_get_bytes_left(&s->g) + n + 2;
-
- if (Psot > bytestream2_get_bytes_left(&s->g) + n + 2) {
- av_log(s->avctx, AV_LOG_ERROR, "Psot %"PRIu32" too big\n", Psot);
- return AVERROR_INVALIDDATA;
- }
-
- av_assert0(TPsot < FF_ARRAY_ELEMS(s->tile[Isot].tile_part));
-
- s->tile[Isot].tp_idx = TPsot;
- tp = s->tile[Isot].tile_part + TPsot;
- tp->tile_index = Isot;
- tp->tp_end = s->g.buffer + Psot - n - 2;
-
- if (!TPsot) {
- Jpeg2000Tile *tile = s->tile + s->curtileno;
-
- /* copy defaults */
- memcpy(tile->codsty, s->codsty, s->ncomponents * sizeof(Jpeg2000CodingStyle));
- memcpy(tile->qntsty, s->qntsty, s->ncomponents * sizeof(Jpeg2000QuantStyle));
- memcpy(&tile->poc , &s->poc , sizeof(tile->poc));
- tile->poc.is_default = 1;
- }
-
- return 0;
-}
-
-/* Tile-part lengths: see ISO 15444-1:2002, section A.7.1
- * Used to know the number of tile parts and lengths.
- * There may be multiple TLMs in the header.
- * TODO: The function is not used for tile-parts management, nor anywhere else.
- * It can be useful to allocate memory for tile parts, before managing the SOT
- * markers. Parsing the TLM header is needed to increment the input header
- * buffer.
- * This marker is mandatory for DCI. */
-static uint8_t get_tlm(Jpeg2000DecoderContext *s, int n)
-{
- uint8_t Stlm, ST, SP, tile_tlm, i;
- bytestream2_get_byte(&s->g); /* Ztlm: skipped */
- Stlm = bytestream2_get_byte(&s->g);
-
- // too complex ? ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
- ST = (Stlm >> 4) & 0x03;
- // TODO: Manage case of ST = 0b11 --> raise error
- SP = (Stlm >> 6) & 0x01;
- tile_tlm = (n - 4) / ((SP + 1) * 2 + ST);
- for (i = 0; i < tile_tlm; i++) {
- switch (ST) {
- case 0:
- break;
- case 1:
- bytestream2_get_byte(&s->g);
- break;
- case 2:
- bytestream2_get_be16(&s->g);
- break;
- case 3:
- bytestream2_get_be32(&s->g);
- break;
- }
- if (SP == 0) {
- bytestream2_get_be16(&s->g);
- } else {
- bytestream2_get_be32(&s->g);
- }
- }
- return 0;
-}
-
-static uint8_t get_plt(Jpeg2000DecoderContext *s, int n)
-{
- int i;
-
- av_log(s->avctx, AV_LOG_DEBUG,
- "PLT marker at pos 0x%X\n", bytestream2_tell(&s->g) - 4);
-
- /*Zplt =*/ bytestream2_get_byte(&s->g);
-
- for (i = 0; i < n - 3; i++) {
- bytestream2_get_byte(&s->g);
- }
-
- return 0;
-}
-
-static int init_tile(Jpeg2000DecoderContext *s, int tileno)
-{
- int compno;
- int tilex = tileno % s->numXtiles;
- int tiley = tileno / s->numXtiles;
- Jpeg2000Tile *tile = s->tile + tileno;
-
- if (!tile->comp)
- return AVERROR(ENOMEM);
-
- tile->coord[0][0] = av_clip(tilex * (int64_t)s->tile_width + s->tile_offset_x, s->image_offset_x, s->width);
- tile->coord[0][1] = av_clip((tilex + 1) * (int64_t)s->tile_width + s->tile_offset_x, s->image_offset_x, s->width);
- tile->coord[1][0] = av_clip(tiley * (int64_t)s->tile_height + s->tile_offset_y, s->image_offset_y, s->height);
- tile->coord[1][1] = av_clip((tiley + 1) * (int64_t)s->tile_height + s->tile_offset_y, s->image_offset_y, s->height);
-
- for (compno = 0; compno < s->ncomponents; compno++) {
- Jpeg2000Component *comp = tile->comp + compno;
- Jpeg2000CodingStyle *codsty = tile->codsty + compno;
- Jpeg2000QuantStyle *qntsty = tile->qntsty + compno;
- int ret; // global bandno
-
- comp->coord_o[0][0] = tile->coord[0][0];
- 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[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);
- comp->coord[1][0] = ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], s->reduction_factor);
- comp->coord[1][1] = ff_jpeg2000_ceildivpow2(comp->coord_o[1][1], s->reduction_factor);
-
- if (ret = ff_jpeg2000_init_component(comp, codsty, qntsty,
- s->cbps[compno], s->cdx[compno],
- s->cdy[compno], s->avctx))
- return ret;
- }
- return 0;
-}
-
-/* Read the number of coding passes. */
-static int getnpasses(Jpeg2000DecoderContext *s)
-{
- int num;
- if (!get_bits(s, 1))
- return 1;
- if (!get_bits(s, 1))
- return 2;
- if ((num = get_bits(s, 2)) != 3)
- return num < 0 ? num : 3 + num;
- if ((num = get_bits(s, 5)) != 31)
- return num < 0 ? num : 6 + num;
- num = get_bits(s, 7);
- return num < 0 ? num : 37 + num;
-}
-
-static int getlblockinc(Jpeg2000DecoderContext *s)
-{
- int res = 0, ret;
- while (ret = get_bits(s, 1)) {
- if (ret < 0)
- return ret;
- res++;
- }
- return res;
-}
-
-static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, int *tp_index,
- Jpeg2000CodingStyle *codsty,
- Jpeg2000ResLevel *rlevel, int precno,
- int layno, uint8_t *expn, int numgbits)
-{
- int bandno, cblkno, ret, nb_code_blocks;
- int cwsno;
-
- if (layno < rlevel->band[0].prec[precno].decoded_layers)
- return 0;
- rlevel->band[0].prec[precno].decoded_layers = layno + 1;
-
- 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;
- }
- }
-
- if (bytestream2_peek_be32(&s->g) == JPEG2000_SOP_FIXED_BYTES)
- bytestream2_skip(&s->g, JPEG2000_SOP_BYTE_LENGTH);
-
- if (!(ret = get_bits(s, 1))) {
- jpeg2000_flush(s);
- return 0;
- } else if (ret < 0)
- return ret;
-
- for (bandno = 0; bandno < rlevel->nbands; bandno++) {
- Jpeg2000Band *band = rlevel->band + bandno;
- Jpeg2000Prec *prec = band->prec + precno;
-
- if (band->coord[0][0] == band->coord[0][1] ||
- band->coord[1][0] == band->coord[1][1])
- continue;
- nb_code_blocks = prec->nb_codeblocks_height *
- prec->nb_codeblocks_width;
- for (cblkno = 0; cblkno < nb_code_blocks; cblkno++) {
- Jpeg2000Cblk *cblk = prec->cblk + cblkno;
- int incl, newpasses, llen;
-
- if (cblk->npasses)
- incl = get_bits(s, 1);
- else
- incl = tag_tree_decode(s, prec->cblkincl + cblkno, layno + 1) == layno;
- if (!incl)
- continue;
- else if (incl < 0)
- return incl;
-
- if (!cblk->npasses) {
- int v = expn[bandno] + numgbits - 1 -
- tag_tree_decode(s, prec->zerobits + cblkno, 100);
- if (v < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "nonzerobits %d invalid\n", v);
- return AVERROR_INVALIDDATA;
- }
- cblk->nonzerobits = v;
- }
- if ((newpasses = getnpasses(s)) < 0)
- return newpasses;
- av_assert2(newpasses > 0);
- if (cblk->npasses + newpasses >= JPEG2000_MAX_PASSES) {
- avpriv_request_sample(s->avctx, "Too many passes");
- return AVERROR_PATCHWELCOME;
- }
- if ((llen = getlblockinc(s)) < 0)
- return llen;
- if (cblk->lblock + llen + av_log2(newpasses) > 16) {
- avpriv_request_sample(s->avctx,
- "Block with length beyond 16 bits");
- return AVERROR_PATCHWELCOME;
- }
-
- cblk->lblock += llen;
-
- cblk->nb_lengthinc = 0;
- cblk->nb_terminationsinc = 0;
- do {
- int newpasses1 = 0;
-
- while (newpasses1 < newpasses) {
- newpasses1 ++;
- if (needs_termination(codsty->cblk_style, cblk->npasses + newpasses1 - 1)) {
- cblk->nb_terminationsinc ++;
- break;
- }
- }
-
- if ((ret = get_bits(s, av_log2(newpasses1) + cblk->lblock)) < 0)
- return ret;
- if (ret > sizeof(cblk->data)) {
- avpriv_request_sample(s->avctx,
- "Block with lengthinc greater than %"SIZE_SPECIFIER"",
- sizeof(cblk->data));
- return AVERROR_PATCHWELCOME;
- }
- cblk->lengthinc[cblk->nb_lengthinc++] = ret;
- cblk->npasses += newpasses1;
- newpasses -= newpasses1;
- } while(newpasses);
- }
- }
- jpeg2000_flush(s);
-
- 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));
- }
-
- for (bandno = 0; bandno < rlevel->nbands; bandno++) {
- Jpeg2000Band *band = rlevel->band + bandno;
- Jpeg2000Prec *prec = band->prec + precno;
-
- nb_code_blocks = prec->nb_codeblocks_height * prec->nb_codeblocks_width;
- for (cblkno = 0; cblkno < nb_code_blocks; cblkno++) {
- Jpeg2000Cblk *cblk = prec->cblk + cblkno;
- for (cwsno = 0; cwsno < cblk->nb_lengthinc; cwsno ++) {
- if ( bytestream2_get_bytes_left(&s->g) < cblk->lengthinc[cwsno]
- || sizeof(cblk->data) < cblk->length + cblk->lengthinc[cwsno] + 4
- ) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Block length %"PRIu16" or lengthinc %d is too large, left %d\n",
- cblk->length, cblk->lengthinc[cwsno], bytestream2_get_bytes_left(&s->g));
- return AVERROR_INVALIDDATA;
- }
-
- bytestream2_get_bufferu(&s->g, cblk->data + cblk->length, cblk->lengthinc[cwsno]);
- cblk->length += cblk->lengthinc[cwsno];
- cblk->lengthinc[cwsno] = 0;
- if (cblk->nb_terminationsinc) {
- cblk->nb_terminationsinc--;
- cblk->nb_terminations++;
- cblk->data[cblk->length++] = 0xFF;
- cblk->data[cblk->length++] = 0xFF;
- cblk->data_start[cblk->nb_terminations] = cblk->length;
- }
- }
- }
- }
- return 0;
-}
-
-static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
- int RSpoc, int CSpoc,
- int LYEpoc, int REpoc, int CEpoc,
- int Ppoc, int *tp_index)
-{
- int ret = 0;
- int layno, reslevelno, compno, precno, ok_reslevel;
- int x, y;
- int step_x, step_y;
-
- switch (Ppoc) {
- case JPEG2000_PGOD_RLCP:
- av_log(s->avctx, AV_LOG_DEBUG, "Progression order RLCP\n");
- ok_reslevel = 1;
- for (reslevelno = RSpoc; ok_reslevel && reslevelno < REpoc; reslevelno++) {
- ok_reslevel = 0;
- for (layno = 0; layno < LYEpoc; layno++) {
- for (compno = CSpoc; compno < CEpoc; compno++) {
- Jpeg2000CodingStyle *codsty = tile->codsty + compno;
- Jpeg2000QuantStyle *qntsty = tile->qntsty + compno;
- if (reslevelno < codsty->nreslevels) {
- Jpeg2000ResLevel *rlevel = tile->comp[compno].reslevel +
- reslevelno;
- ok_reslevel = 1;
- for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++)
- if ((ret = jpeg2000_decode_packet(s, tile, tp_index,
- codsty, rlevel,
- precno, layno,
- qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
- qntsty->nguardbits)) < 0)
- return ret;
- }
- }
- }
- }
- break;
-
- case JPEG2000_PGOD_LRCP:
- av_log(s->avctx, AV_LOG_DEBUG, "Progression order LRCP\n");
- for (layno = 0; layno < LYEpoc; layno++) {
- ok_reslevel = 1;
- for (reslevelno = RSpoc; ok_reslevel && reslevelno < REpoc; reslevelno++) {
- ok_reslevel = 0;
- for (compno = CSpoc; compno < CEpoc; compno++) {
- Jpeg2000CodingStyle *codsty = tile->codsty + compno;
- Jpeg2000QuantStyle *qntsty = tile->qntsty + compno;
- if (reslevelno < codsty->nreslevels) {
- Jpeg2000ResLevel *rlevel = tile->comp[compno].reslevel +
- reslevelno;
- ok_reslevel = 1;
- for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++)
- if ((ret = jpeg2000_decode_packet(s, tile, tp_index,
- codsty, rlevel,
- precno, layno,
- qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
- qntsty->nguardbits)) < 0)
- return ret;
- }
- }
- }
- }
- break;
-
- case JPEG2000_PGOD_CPRL:
- av_log(s->avctx, AV_LOG_DEBUG, "Progression order CPRL\n");
- for (compno = CSpoc; compno < CEpoc; compno++) {
- Jpeg2000Component *comp = tile->comp + compno;
- Jpeg2000CodingStyle *codsty = tile->codsty + compno;
- Jpeg2000QuantStyle *qntsty = tile->qntsty + compno;
- step_x = 32;
- step_y = 32;
-
- for (reslevelno = RSpoc; reslevelno < FFMIN(codsty->nreslevels, REpoc); 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);
- }
- av_assert0(step_x < 32 && step_y < 32);
- step_x = 1<<step_x;
- step_y = 1<<step_y;
-
- for (y = tile->coord[1][0]; y < tile->coord[1][1]; y = (y/step_y + 1)*step_y) {
- for (x = tile->coord[0][0]; x < tile->coord[0][1]; x = (x/step_x + 1)*step_x) {
- 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 xc = x / s->cdx[compno];
- int yc = y / s->cdy[compno];
-
- if (yc % (1 << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check
- continue;
-
- if (xc % (1 << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check
- 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_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;
-
- precno = prcx + rlevel->num_precincts_x * prcy;
-
- if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y) {
- av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n",
- prcx, prcy, rlevel->num_precincts_x, rlevel->num_precincts_y);
- continue;
- }
-
- for (layno = 0; layno < LYEpoc; layno++) {
- if ((ret = jpeg2000_decode_packet(s, tile, tp_index, codsty, rlevel,
- precno, layno,
- qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
- qntsty->nguardbits)) < 0)
- return ret;
- }
- }
- }
- }
- }
- break;
-
- case JPEG2000_PGOD_RPCL:
- av_log(s->avctx, AV_LOG_WARNING, "Progression order RPCL\n");
- ok_reslevel = 1;
- for (reslevelno = RSpoc; ok_reslevel && reslevelno < REpoc; reslevelno++) {
- ok_reslevel = 0;
- step_x = 30;
- step_y = 30;
- for (compno = CSpoc; compno < CEpoc; compno++) {
- Jpeg2000Component *comp = tile->comp + compno;
- Jpeg2000CodingStyle *codsty = tile->codsty + 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<<step_x;
- step_y = 1<<step_y;
-
- for (y = tile->coord[1][0]; y < tile->coord[1][1]; y = (y/step_y + 1)*step_y) {
- for (x = tile->coord[0][0]; x < tile->coord[0][1]; x = (x/step_x + 1)*step_x) {
- for (compno = CSpoc; compno < CEpoc; compno++) {
- Jpeg2000Component *comp = tile->comp + compno;
- Jpeg2000CodingStyle *codsty = tile->codsty + compno;
- Jpeg2000QuantStyle *qntsty = tile->qntsty + compno;
- uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r
- Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;
- unsigned prcx, prcy;
-
- int xc = x / s->cdx[compno];
- int yc = y / s->cdy[compno];
-
- if (reslevelno >= codsty->nreslevels)
- continue;
-
- if (yc % (1 << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check
- continue;
-
- if (xc % (1 << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check
- 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_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;
-
- precno = prcx + rlevel->num_precincts_x * prcy;
-
- ok_reslevel = 1;
- if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y) {
- av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n",
- prcx, prcy, rlevel->num_precincts_x, rlevel->num_precincts_y);
- continue;
- }
-
- for (layno = 0; layno < LYEpoc; layno++) {
- if ((ret = jpeg2000_decode_packet(s, tile, tp_index,
- codsty, rlevel,
- precno, layno,
- qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
- qntsty->nguardbits)) < 0)
- return ret;
- }
- }
- }
- }
- }
- break;
-
- case JPEG2000_PGOD_PCRL:
- av_log(s->avctx, AV_LOG_WARNING, "Progression order PCRL\n");
- step_x = 32;
- step_y = 32;
- for (compno = CSpoc; compno < CEpoc; compno++) {
- Jpeg2000Component *comp = tile->comp + compno;
- Jpeg2000CodingStyle *codsty = tile->codsty + compno;
-
- for (reslevelno = RSpoc; reslevelno < FFMIN(codsty->nreslevels, REpoc); 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);
- }
- }
- step_x = 1<<step_x;
- step_y = 1<<step_y;
-
- for (y = tile->coord[1][0]; y < tile->coord[1][1]; y = (y/step_y + 1)*step_y) {
- for (x = tile->coord[0][0]; x < tile->coord[0][1]; x = (x/step_x + 1)*step_x) {
- for (compno = CSpoc; compno < CEpoc; compno++) {
- 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];
-
- 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;
-
- if (yc % (1 << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check
- continue;
-
- if (xc % (1 << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check
- 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_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;
-
- precno = prcx + rlevel->num_precincts_x * prcy;
-
- if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y) {
- av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n",
- prcx, prcy, rlevel->num_precincts_x, rlevel->num_precincts_y);
- continue;
- }
-
- for (layno = 0; layno < LYEpoc; layno++) {
- if ((ret = jpeg2000_decode_packet(s, tile, tp_index, codsty, rlevel,
- precno, layno,
- qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
- qntsty->nguardbits)) < 0)
- return ret;
- }
- }
- }
- }
- }
- break;
-
- default:
- break;
- }
-
- return ret;
-}
-
-static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
-{
- int ret = AVERROR_BUG;
- int i;
- int tp_index = 0;
-
- s->bit_index = 8;
- if (tile->poc.nb_poc) {
- for (i=0; i<tile->poc.nb_poc; i++) {
- Jpeg2000POCEntry *e = &tile->poc.poc[i];
- ret = jpeg2000_decode_packets_po_iteration(s, tile,
- e->RSpoc, e->CSpoc,
- FFMIN(e->LYEpoc, tile->codsty[0].nlayers),
- e->REpoc,
- FFMIN(e->CEpoc, s->ncomponents),
- e->Ppoc, &tp_index
- );
- if (ret < 0)
- return ret;
- }
- } else {
- ret = jpeg2000_decode_packets_po_iteration(s, tile,
- 0, 0,
- tile->codsty[0].nlayers,
- 33,
- s->ncomponents,
- tile->codsty[0].prog_order,
- &tp_index
- );
- }
- /* EOC marker reached */
- bytestream2_skip(&s->g, 2);
-
- return ret;
-}
-
-/* TIER-1 routines */
-static void decode_sigpass(Jpeg2000T1Context *t1, int width, int height,
- int bpno, int bandno,
- int vert_causal_ctx_csty_symbol)
-{
- int mask = 3 << (bpno - 1), y0, x, y;
-
- for (y0 = 0; y0 < height; y0 += 4)
- for (x = 0; x < width; x++)
- for (y = y0; y < height && y < y0 + 4; y++) {
- int flags_mask = -1;
- if (vert_causal_ctx_csty_symbol && y == y0 + 3)
- flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S);
- if ((t1->flags[(y+1) * t1->stride + x+1] & JPEG2000_T1_SIG_NB & flags_mask)
- && !(t1->flags[(y+1) * t1->stride + x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {
- if (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[(y+1) * t1->stride + x+1] & flags_mask, bandno))) {
- int xorbit, ctxno = ff_jpeg2000_getsgnctxno(t1->flags[(y+1) * t1->stride + x+1] & flags_mask, &xorbit);
- if (t1->mqc.raw)
- t1->data[(y) * t1->stride + x] = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? -mask : mask;
- else
- t1->data[(y) * t1->stride + x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ xorbit) ?
- -mask : mask;
-
- ff_jpeg2000_set_significance(t1, x, y,
- t1->data[(y) * t1->stride + x] < 0);
- }
- t1->flags[(y + 1) * t1->stride + x + 1] |= JPEG2000_T1_VIS;
- }
- }
-}
-
-static void decode_refpass(Jpeg2000T1Context *t1, int width, int height,
- int bpno, int vert_causal_ctx_csty_symbol)
-{
- int phalf, nhalf;
- int y0, x, y;
-
- phalf = 1 << (bpno - 1);
- nhalf = -phalf;
-
- for (y0 = 0; y0 < height; y0 += 4)
- for (x = 0; x < width; x++)
- for (y = y0; y < height && y < y0 + 4; y++)
- if ((t1->flags[(y + 1) * t1->stride + x + 1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS)) == JPEG2000_T1_SIG) {
- int flags_mask = (vert_causal_ctx_csty_symbol && y == y0 + 3) ?
- ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S) : -1;
- int ctxno = ff_jpeg2000_getrefctxno(t1->flags[(y + 1) * t1->stride + x + 1] & flags_mask);
- int r = ff_mqc_decode(&t1->mqc,
- t1->mqc.cx_states + ctxno)
- ? phalf : nhalf;
- t1->data[(y) * t1->stride + x] += t1->data[(y) * t1->stride + x] < 0 ? -r : r;
- t1->flags[(y + 1) * t1->stride + x + 1] |= JPEG2000_T1_REF;
- }
-}
-
-static void decode_clnpass(Jpeg2000DecoderContext *s, Jpeg2000T1Context *t1,
- int width, int height, int bpno, int bandno,
- int seg_symbols, int vert_causal_ctx_csty_symbol)
-{
- int mask = 3 << (bpno - 1), y0, x, y, runlen, dec;
-
- for (y0 = 0; y0 < height; y0 += 4) {
- for (x = 0; x < width; x++) {
- int flags_mask = -1;
- if (vert_causal_ctx_csty_symbol)
- flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S);
- if (y0 + 3 < height &&
- !((t1->flags[(y0 + 1) * t1->stride + x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
- (t1->flags[(y0 + 2) * t1->stride + x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
- (t1->flags[(y0 + 3) * t1->stride + x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
- (t1->flags[(y0 + 4) * t1->stride + x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG) & flags_mask))) {
- if (!ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_RL))
- continue;
- runlen = ff_mqc_decode(&t1->mqc,
- t1->mqc.cx_states + MQC_CX_UNI);
- runlen = (runlen << 1) | ff_mqc_decode(&t1->mqc,
- t1->mqc.cx_states +
- MQC_CX_UNI);
- dec = 1;
- } else {
- runlen = 0;
- dec = 0;
- }
-
- for (y = y0 + runlen; y < y0 + 4 && y < height; y++) {
- int flags_mask = -1;
- if (vert_causal_ctx_csty_symbol && y == y0 + 3)
- flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S);
- if (!dec) {
- if (!(t1->flags[(y+1) * t1->stride + x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {
- dec = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[(y+1) * t1->stride + x+1] & flags_mask,
- bandno));
- }
- }
- if (dec) {
- int xorbit;
- int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[(y + 1) * t1->stride + x + 1] & flags_mask,
- &xorbit);
- t1->data[(y) * t1->stride + x] = (ff_mqc_decode(&t1->mqc,
- t1->mqc.cx_states + ctxno) ^
- xorbit)
- ? -mask : mask;
- ff_jpeg2000_set_significance(t1, x, y, t1->data[(y) * t1->stride + x] < 0);
- }
- dec = 0;
- t1->flags[(y + 1) * t1->stride + x + 1] &= ~JPEG2000_T1_VIS;
- }
- }
- }
- if (seg_symbols) {
- int val;
- val = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
- val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
- val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
- val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
- if (val != 0xa)
- av_log(s->avctx, AV_LOG_ERROR,
- "Segmentation symbol value incorrect\n");
- }
-}
-
-static int decode_cblk(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty,
- Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk,
- int width, int height, int bandpos)
-{
- int passno = cblk->npasses, pass_t = 2, bpno = cblk->nonzerobits - 1;
- int pass_cnt = 0;
- int vert_causal_ctx_csty_symbol = codsty->cblk_style & JPEG2000_CBLK_VSC;
- int term_cnt = 0;
- int coder_type;
-
- av_assert0(width <= 1024U && height <= 1024U);
- av_assert0(width*height <= 4096);
-
- memset(t1->data, 0, t1->stride * height * sizeof(*t1->data));
-
- /* If code-block contains no compressed data: nothing to do. */
- if (!cblk->length)
- return 0;
-
- memset(t1->flags, 0, t1->stride * (height + 2) * sizeof(*t1->flags));
-
- cblk->data[cblk->length] = 0xff;
- cblk->data[cblk->length+1] = 0xff;
- ff_mqc_initdec(&t1->mqc, cblk->data, 0, 1);
-
- while (passno--) {
- if (bpno < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "bpno became negative\n");
- return AVERROR_INVALIDDATA;
- }
- switch(pass_t) {
- case 0:
- decode_sigpass(t1, width, height, bpno + 1, bandpos,
- vert_causal_ctx_csty_symbol);
- break;
- case 1:
- decode_refpass(t1, width, height, bpno + 1, vert_causal_ctx_csty_symbol);
- break;
- case 2:
- av_assert2(!t1->mqc.raw);
- decode_clnpass(s, t1, width, height, bpno + 1, bandpos,
- codsty->cblk_style & JPEG2000_CBLK_SEGSYM,
- vert_causal_ctx_csty_symbol);
- break;
- }
- if (codsty->cblk_style & JPEG2000_CBLK_RESET) // XXX no testcase for just this
- ff_mqc_init_contexts(&t1->mqc);
-
- if (passno && (coder_type = needs_termination(codsty->cblk_style, pass_cnt))) {
- if (term_cnt >= cblk->nb_terminations) {
- av_log(s->avctx, AV_LOG_ERROR, "Missing needed termination \n");
- return AVERROR_INVALIDDATA;
- }
- if (FFABS(cblk->data + cblk->data_start[term_cnt + 1] - 2 - t1->mqc.bp) > 0) {
- av_log(s->avctx, AV_LOG_WARNING, "Mid mismatch %"PTRDIFF_SPECIFIER" in pass %d of %d\n",
- cblk->data + cblk->data_start[term_cnt + 1] - 2 - t1->mqc.bp,
- pass_cnt, cblk->npasses);
- }
-
- ff_mqc_initdec(&t1->mqc, cblk->data + cblk->data_start[++term_cnt], coder_type == 2, 0);
- }
-
- pass_t++;
- if (pass_t == 3) {
- bpno--;
- pass_t = 0;
- }
- pass_cnt ++;
- }
-
- if (cblk->data + cblk->length - 2*(term_cnt < cblk->nb_terminations) != 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);
- }
-
- return 0;
-}
-
-/* TODO: Verify dequantization for lossless case
- * comp->data can be float or int
- * band->stepsize can be float or int
- * depending on the type of DWT transformation.
- * see ISO/IEC 15444-1:2002 A.6.1 */
-
-/* Float dequantization of a codeblock.*/
-static void dequantization_float(int x, int y, Jpeg2000Cblk *cblk,
- Jpeg2000Component *comp,
- Jpeg2000T1Context *t1, Jpeg2000Band *band)
-{
- int i, j;
- int w = cblk->coord[0][1] - cblk->coord[0][0];
- for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j) {
- float *datap = &comp->f_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];
- int *src = t1->data + j*t1->stride;
- for (i = 0; i < w; ++i)
- datap[i] = src[i] * band->f_stepsize;
- }
-}
-
-/* Integer dequantization of a codeblock.*/
-static void dequantization_int(int x, int y, Jpeg2000Cblk *cblk,
- Jpeg2000Component *comp,
- Jpeg2000T1Context *t1, Jpeg2000Band *band)
-{
- int i, j;
- int w = cblk->coord[0][1] - cblk->coord[0][0];
- for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j) {
- int32_t *datap = &comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];
- int *src = t1->data + j*t1->stride;
- if (band->i_stepsize == 32768) {
- for (i = 0; i < w; ++i)
- datap[i] = src[i] / 2;
- } else {
- // This should be VERY uncommon
- for (i = 0; i < w; ++i)
- datap[i] = (src[i] * (int64_t)band->i_stepsize) / 65536;
- }
- }
-}
-
-static void dequantization_int_97(int x, int y, Jpeg2000Cblk *cblk,
- Jpeg2000Component *comp,
- Jpeg2000T1Context *t1, Jpeg2000Band *band)
-{
- int i, j;
- int w = cblk->coord[0][1] - cblk->coord[0][0];
- for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j) {
- int32_t *datap = &comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];
- int *src = t1->data + j*t1->stride;
- for (i = 0; i < w; ++i)
- datap[i] = (src[i] * (int64_t)band->i_stepsize + (1<<15)) >> 16;
- }
-}
-
-static inline void mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
-{
- int i, csize = 1;
- void *src[3];
-
- for (i = 1; i < 3; i++) {
- if (tile->codsty[0].transform != tile->codsty[i].transform) {
- av_log(s->avctx, AV_LOG_ERROR, "Transforms mismatch, MCT not supported\n");
- return;
- }
- if (memcmp(tile->comp[0].coord, tile->comp[i].coord, sizeof(tile->comp[0].coord))) {
- av_log(s->avctx, AV_LOG_ERROR, "Coords mismatch, MCT not supported\n");
- return;
- }
- }
-
- for (i = 0; i < 3; i++)
- if (tile->codsty[0].transform == FF_DWT97)
- src[i] = tile->comp[i].f_data;
- else
- src[i] = tile->comp[i].i_data;
-
- for (i = 0; i < 2; i++)
- csize *= tile->comp[0].coord[i][1] - tile->comp[0].coord[i][0];
-
- s->dsp.mct_decode[tile->codsty[0].transform](src[0], src[1], src[2], csize);
-}
-
-static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
- AVFrame *picture)
-{
- const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
- int compno, reslevelno, bandno;
- int x, y;
- int planar = !!(pixdesc->flags & AV_PIX_FMT_FLAG_PLANAR);
- int pixelsize = planar ? 1 : pixdesc->nb_components;
-
- uint8_t *line;
- Jpeg2000T1Context t1;
-
- /* Loop on tile components */
- for (compno = 0; compno < s->ncomponents; compno++) {
- Jpeg2000Component *comp = tile->comp + compno;
- Jpeg2000CodingStyle *codsty = tile->codsty + compno;
-
- t1.stride = (1<<codsty->log2_cblk_width) + 2;
-
- /* Loop on resolution levels */
- for (reslevelno = 0; reslevelno < codsty->nreslevels2decode; reslevelno++) {
- Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;
- /* Loop on bands */
- for (bandno = 0; bandno < rlevel->nbands; bandno++) {
- int nb_precincts, precno;
- Jpeg2000Band *band = rlevel->band + bandno;
- int cblkno = 0, bandpos;
-
- bandpos = bandno + (reslevelno > 0);
-
- if (band->coord[0][0] == band->coord[0][1] ||
- band->coord[1][0] == band->coord[1][1])
- continue;
-
- nb_precincts = rlevel->num_precincts_x * rlevel->num_precincts_y;
- /* Loop on precincts */
- for (precno = 0; precno < nb_precincts; precno++) {
- Jpeg2000Prec *prec = band->prec + precno;
-
- /* Loop on codeblocks */
- for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) {
- int x, y;
- Jpeg2000Cblk *cblk = prec->cblk + cblkno;
- decode_cblk(s, codsty, &t1, cblk,
- cblk->coord[0][1] - cblk->coord[0][0],
- cblk->coord[1][1] - cblk->coord[1][0],
- bandpos);
-
- x = cblk->coord[0][0] - band->coord[0][0];
- y = cblk->coord[1][0] - band->coord[1][0];
-
- if (codsty->transform == FF_DWT97)
- dequantization_float(x, y, cblk, comp, &t1, band);
- else if (codsty->transform == FF_DWT97_INT)
- dequantization_int_97(x, y, cblk, comp, &t1, band);
- else
- dequantization_int(x, y, cblk, comp, &t1, band);
- } /* end cblk */
- } /*end prec */
- } /* end band */
- } /* end reslevel */
-
- /* inverse DWT */
- ff_dwt_decode(&comp->dwt, codsty->transform == FF_DWT97 ? (void*)comp->f_data : (void*)comp->i_data);
- } /*end comp */
-
- /* inverse MCT transformation */
- if (tile->codsty[0].mct)
- mct_decode(s, tile);
-
- for (x = 0; x < s->ncomponents; x++) {
- if (s->cdef[x] < 0) {
- for (x = 0; x < s->ncomponents; x++) {
- s->cdef[x] = x + 1;
- }
- if ((s->ncomponents & 1) == 0)
- s->cdef[s->ncomponents-1] = 0;
- break;
- }
- }
-
- if (s->precision <= 8) {
- for (compno = 0; compno < s->ncomponents; compno++) {
- Jpeg2000Component *comp = tile->comp + compno;
- Jpeg2000CodingStyle *codsty = tile->codsty + compno;
- 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 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];
- line = picture->data[plane] + y * picture->linesize[plane];
- for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y ++) {
- uint8_t *dst;
-
- x = tile->comp[compno].coord[0][0] - s->image_offset_x / s->cdx[compno];
- dst = line + x * pixelsize + compno*!planar;
-
- if (codsty->transform == FF_DWT97) {
- for (; x < w; x ++) {
- int val = lrintf(*datap) + (1 << (cbps - 1));
- /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
- val = av_clip(val, 0, (1 << cbps) - 1);
- *dst = val << (8 - cbps);
- datap++;
- dst += pixelsize;
- }
- } else {
- for (; x < w; x ++) {
- int val = *i_datap + (1 << (cbps - 1));
- /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
- val = av_clip(val, 0, (1 << cbps) - 1);
- *dst = val << (8 - cbps);
- i_datap++;
- dst += pixelsize;
- }
- }
- line += picture->linesize[plane];
- }
- }
- } else {
- int precision = picture->format == AV_PIX_FMT_XYZ12 ||
- picture->format == AV_PIX_FMT_RGB48 ||
- picture->format == AV_PIX_FMT_RGBA64 ||
- picture->format == AV_PIX_FMT_GRAY16 ? 16 : s->precision;
-
- for (compno = 0; compno < s->ncomponents; compno++) {
- Jpeg2000Component *comp = tile->comp + compno;
- Jpeg2000CodingStyle *codsty = tile->codsty + compno;
- float *datap = comp->f_data;
- int32_t *i_datap = comp->i_data;
- uint16_t *linel;
- int cbps = s->cbps[compno];
- int w = tile->comp[compno].coord[0][1] - s->image_offset_x;
- 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];
- linel = (uint16_t *)picture->data[plane] + y * (picture->linesize[plane] >> 1);
- for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y ++) {
- uint16_t *dst;
-
- x = tile->comp[compno].coord[0][0] - s->image_offset_x / s->cdx[compno];
- dst = linel + (x * pixelsize + compno*!planar);
- if (codsty->transform == FF_DWT97) {
- for (; x < w; x ++) {
- int val = lrintf(*datap) + (1 << (cbps - 1));
- /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
- val = av_clip(val, 0, (1 << cbps) - 1);
- /* align 12 bit values in little-endian mode */
- *dst = val << (precision - cbps);
- datap++;
- dst += pixelsize;
- }
- } else {
- for (; x < w; x ++) {
- int val = *i_datap + (1 << (cbps - 1));
- /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
- val = av_clip(val, 0, (1 << cbps) - 1);
- /* align 12 bit values in little-endian mode */
- *dst = val << (precision - cbps);
- i_datap++;
- dst += pixelsize;
- }
- }
- linel += picture->linesize[plane] >> 1;
- }
- }
- }
-
- return 0;
-}
-
-static void jpeg2000_dec_cleanup(Jpeg2000DecoderContext *s)
-{
- int tileno, compno;
- for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++) {
- if (s->tile[tileno].comp) {
- for (compno = 0; compno < s->ncomponents; compno++) {
- Jpeg2000Component *comp = s->tile[tileno].comp + compno;
- Jpeg2000CodingStyle *codsty = s->tile[tileno].codsty + compno;
-
- ff_jpeg2000_cleanup(comp, codsty);
- }
- av_freep(&s->tile[tileno].comp);
- }
- }
- av_freep(&s->tile);
- memset(s->codsty, 0, sizeof(s->codsty));
- memset(s->qntsty, 0, sizeof(s->qntsty));
- memset(s->properties, 0, sizeof(s->properties));
- memset(&s->poc , 0, sizeof(s->poc));
- s->numXtiles = s->numYtiles = 0;
- s->ncomponents = 0;
-}
-
-static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
-{
- Jpeg2000CodingStyle *codsty = s->codsty;
- Jpeg2000QuantStyle *qntsty = s->qntsty;
- Jpeg2000POC *poc = &s->poc;
- uint8_t *properties = s->properties;
-
- for (;;) {
- int len, ret = 0;
- uint16_t marker;
- int oldpos;
-
- if (bytestream2_get_bytes_left(&s->g) < 2) {
- av_log(s->avctx, AV_LOG_ERROR, "Missing EOC\n");
- break;
- }
-
- marker = bytestream2_get_be16u(&s->g);
- oldpos = bytestream2_tell(&s->g);
-
- if (marker == JPEG2000_SOD) {
- Jpeg2000Tile *tile;
- Jpeg2000TilePart *tp;
-
- if (!s->tile) {
- av_log(s->avctx, AV_LOG_ERROR, "Missing SIZ\n");
- return AVERROR_INVALIDDATA;
- }
- if (s->curtileno < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Missing SOT\n");
- return AVERROR_INVALIDDATA;
- }
-
- tile = s->tile + s->curtileno;
- tp = tile->tile_part + tile->tp_idx;
- if (tp->tp_end < s->g.buffer) {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid tpend\n");
- return AVERROR_INVALIDDATA;
- }
- bytestream2_init(&tp->tpg, s->g.buffer, tp->tp_end - s->g.buffer);
- bytestream2_skip(&s->g, tp->tp_end - s->g.buffer);
-
- continue;
- }
- if (marker == JPEG2000_EOC)
- break;
-
- len = bytestream2_get_be16(&s->g);
- if (len < 2 || bytestream2_get_bytes_left(&s->g) < len - 2) {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid len %d left=%d\n", len, bytestream2_get_bytes_left(&s->g));
- return AVERROR_INVALIDDATA;
- }
-
- switch (marker) {
- case JPEG2000_SIZ:
- if (s->ncomponents) {
- av_log(s->avctx, AV_LOG_ERROR, "Duplicate SIZ\n");
- return AVERROR_INVALIDDATA;
- }
- ret = get_siz(s);
- if (!s->tile)
- s->numXtiles = s->numYtiles = 0;
- break;
- case JPEG2000_COC:
- ret = get_coc(s, codsty, properties);
- break;
- case JPEG2000_COD:
- ret = get_cod(s, codsty, properties);
- break;
- case JPEG2000_QCC:
- ret = get_qcc(s, len, qntsty, properties);
- break;
- case JPEG2000_QCD:
- ret = get_qcd(s, len, qntsty, properties);
- break;
- case JPEG2000_POC:
- ret = get_poc(s, len, poc);
- break;
- case JPEG2000_SOT:
- if (!(ret = get_sot(s, len))) {
- av_assert1(s->curtileno >= 0);
- codsty = s->tile[s->curtileno].codsty;
- qntsty = s->tile[s->curtileno].qntsty;
- poc = &s->tile[s->curtileno].poc;
- properties = s->tile[s->curtileno].properties;
- }
- break;
- case JPEG2000_COM:
- // the comment is ignored
- bytestream2_skip(&s->g, len - 2);
- break;
- case JPEG2000_TLM:
- // Tile-part lengths
- ret = get_tlm(s, len);
- break;
- case JPEG2000_PLT:
- // Packet length, tile-part header
- ret = get_plt(s, len);
- break;
- default:
- av_log(s->avctx, AV_LOG_ERROR,
- "unsupported marker 0x%.4"PRIX16" at pos 0x%X\n",
- marker, bytestream2_tell(&s->g) - 4);
- bytestream2_skip(&s->g, len - 2);
- break;
- }
- if (bytestream2_tell(&s->g) - oldpos != len || ret) {
- av_log(s->avctx, AV_LOG_ERROR,
- "error during processing marker segment %.4"PRIx16"\n",
- marker);
- return ret ? ret : -1;
- }
- }
- return 0;
-}
-
-/* Read bit stream packets --> T2 operation. */
-static int jpeg2000_read_bitstream_packets(Jpeg2000DecoderContext *s)
-{
- int ret = 0;
- int tileno;
-
- for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++) {
- Jpeg2000Tile *tile = s->tile + tileno;
-
- if ((ret = init_tile(s, tileno)) < 0)
- return ret;
-
- s->g = tile->tile_part[0].tpg;
- if ((ret = jpeg2000_decode_packets(s, tile)) < 0)
- return ret;
- }
-
- return 0;
-}
-
-static int jp2_find_codestream(Jpeg2000DecoderContext *s)
-{
- uint32_t atom_size, atom, atom_end;
- int search_range = 10;
-
- while (search_range
- &&
- bytestream2_get_bytes_left(&s->g) >= 8) {
- atom_size = bytestream2_get_be32u(&s->g);
- atom = bytestream2_get_be32u(&s->g);
- atom_end = bytestream2_tell(&s->g) + atom_size - 8;
-
- if (atom == JP2_CODESTREAM)
- return 1;
-
- if (bytestream2_get_bytes_left(&s->g) < atom_size || atom_end < atom_size)
- return 0;
-
- if (atom == JP2_HEADER &&
- atom_size >= 16) {
- uint32_t atom2_size, atom2, atom2_end;
- do {
- atom2_size = bytestream2_get_be32u(&s->g);
- atom2 = bytestream2_get_be32u(&s->g);
- atom2_end = bytestream2_tell(&s->g) + atom2_size - 8;
- if (atom2_size < 8 || atom2_end > atom_end || atom2_end < atom2_size)
- break;
- if (atom2 == JP2_CODESTREAM) {
- return 1;
- } else if (atom2 == MKBETAG('c','o','l','r') && atom2_size >= 7) {
- int method = bytestream2_get_byteu(&s->g);
- bytestream2_skipu(&s->g, 2);
- if (method == 1) {
- s->colour_space = bytestream2_get_be32u(&s->g);
- }
- } else if (atom2 == MKBETAG('p','c','l','r') && atom2_size >= 6) {
- int i, size, colour_count, colour_channels, colour_depth[3];
- uint32_t r, g, b;
- colour_count = bytestream2_get_be16u(&s->g);
- colour_channels = bytestream2_get_byteu(&s->g);
- // FIXME: Do not ignore channel_sign
- colour_depth[0] = (bytestream2_get_byteu(&s->g) & 0x7f) + 1;
- colour_depth[1] = (bytestream2_get_byteu(&s->g) & 0x7f) + 1;
- colour_depth[2] = (bytestream2_get_byteu(&s->g) & 0x7f) + 1;
- size = (colour_depth[0] + 7 >> 3) * colour_count +
- (colour_depth[1] + 7 >> 3) * colour_count +
- (colour_depth[2] + 7 >> 3) * colour_count;
- if (colour_count > 256 ||
- colour_channels != 3 ||
- colour_depth[0] > 16 ||
- colour_depth[1] > 16 ||
- colour_depth[2] > 16 ||
- atom2_size < size) {
- avpriv_request_sample(s->avctx, "Unknown palette");
- bytestream2_seek(&s->g, atom2_end, SEEK_SET);
- continue;
- }
- s->pal8 = 1;
- for (i = 0; i < colour_count; i++) {
- if (colour_depth[0] <= 8) {
- r = bytestream2_get_byteu(&s->g) << 8 - colour_depth[0];
- r |= r >> colour_depth[0];
- } else {
- r = bytestream2_get_be16u(&s->g) >> colour_depth[0] - 8;
- }
- if (colour_depth[1] <= 8) {
- g = bytestream2_get_byteu(&s->g) << 8 - colour_depth[1];
- r |= r >> colour_depth[1];
- } else {
- g = bytestream2_get_be16u(&s->g) >> colour_depth[1] - 8;
- }
- if (colour_depth[2] <= 8) {
- b = bytestream2_get_byteu(&s->g) << 8 - colour_depth[2];
- r |= r >> colour_depth[2];
- } else {
- b = bytestream2_get_be16u(&s->g) >> colour_depth[2] - 8;
- }
- s->palette[i] = 0xffu << 24 | r << 16 | g << 8 | b;
- }
- } else if (atom2 == MKBETAG('c','d','e','f') && atom2_size >= 2) {
- int n = bytestream2_get_be16u(&s->g);
- for (; n>0; n--) {
- int cn = bytestream2_get_be16(&s->g);
- int av_unused typ = bytestream2_get_be16(&s->g);
- int asoc = bytestream2_get_be16(&s->g);
- if (cn < 4 && asoc < 4)
- s->cdef[cn] = asoc;
- }
- }
- bytestream2_seek(&s->g, atom2_end, SEEK_SET);
- } while (atom_end - atom2_end >= 8);
- } else {
- search_range--;
- }
- bytestream2_seek(&s->g, atom_end, SEEK_SET);
- }
-
- return 0;
-}
-
-static av_cold int jpeg2000_decode_init(AVCodecContext *avctx)
-{
- Jpeg2000DecoderContext *s = avctx->priv_data;
-
- ff_jpeg2000dsp_init(&s->dsp);
-
- return 0;
-}
-
-static int jpeg2000_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame, AVPacket *avpkt)
-{
- Jpeg2000DecoderContext *s = avctx->priv_data;
- ThreadFrame frame = { .f = data };
- AVFrame *picture = data;
- int tileno, ret;
-
- s->avctx = avctx;
- bytestream2_init(&s->g, avpkt->data, avpkt->size);
- s->curtileno = -1;
- memset(s->cdef, -1, sizeof(s->cdef));
-
- if (bytestream2_get_bytes_left(&s->g) < 2) {
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
-
- // check if the image is in jp2 format
- if (bytestream2_get_bytes_left(&s->g) >= 12 &&
- (bytestream2_get_be32u(&s->g) == 12) &&
- (bytestream2_get_be32u(&s->g) == JP2_SIG_TYPE) &&
- (bytestream2_get_be32u(&s->g) == JP2_SIG_VALUE)) {
- if (!jp2_find_codestream(s)) {
- av_log(avctx, AV_LOG_ERROR,
- "Could not find Jpeg2000 codestream atom.\n");
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- } else {
- bytestream2_seek(&s->g, 0, SEEK_SET);
- }
-
- while (bytestream2_get_bytes_left(&s->g) >= 3 && bytestream2_peek_be16(&s->g) != JPEG2000_SOC)
- bytestream2_skip(&s->g, 1);
-
- if (bytestream2_get_be16u(&s->g) != JPEG2000_SOC) {
- av_log(avctx, AV_LOG_ERROR, "SOC marker not present\n");
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- if (ret = jpeg2000_read_main_headers(s))
- goto end;
-
- /* get picture buffer */
- if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
- goto end;
- picture->pict_type = AV_PICTURE_TYPE_I;
- picture->key_frame = 1;
-
- if (ret = jpeg2000_read_bitstream_packets(s))
- goto end;
-
- for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++)
- if (ret = jpeg2000_decode_tile(s, s->tile + tileno, picture))
- goto end;
-
- jpeg2000_dec_cleanup(s);
-
- *got_frame = 1;
-
- if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
- memcpy(picture->data[1], s->palette, 256 * sizeof(uint32_t));
-
- return bytestream2_tell(&s->g);
-
-end:
- jpeg2000_dec_cleanup(s);
- return ret;
-}
-
-static av_cold void jpeg2000_init_static_data(AVCodec *codec)
-{
- ff_jpeg2000_init_tier1_luts();
- ff_mqc_init_context_tables();
-}
-
-#define OFFSET(x) offsetof(Jpeg2000DecoderContext, 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(reduction_factor), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, JPEG2000_MAX_RESLEVELS - 1, VD },
- { NULL },
-};
-
-static const AVProfile profiles[] = {
- { FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0, "JPEG 2000 codestream restriction 0" },
- { FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1, "JPEG 2000 codestream restriction 1" },
- { FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION, "JPEG 2000 no codestream restrictions" },
- { FF_PROFILE_JPEG2000_DCINEMA_2K, "JPEG 2000 digital cinema 2K" },
- { FF_PROFILE_JPEG2000_DCINEMA_4K, "JPEG 2000 digital cinema 4K" },
- { FF_PROFILE_UNKNOWN },
-};
-
-static const AVClass jpeg2000_class = {
- .class_name = "jpeg2000",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-AVCodec ff_jpeg2000_decoder = {
- .name = "jpeg2000",
- .long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_JPEG2000,
- .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_DR1,
- .priv_data_size = sizeof(Jpeg2000DecoderContext),
- .init_static_data = jpeg2000_init_static_data,
- .init = jpeg2000_decode_init,
- .decode = jpeg2000_decode_frame,
- .priv_class = &jpeg2000_class,
- .max_lowres = 5,
- .profiles = NULL_IF_CONFIG_SMALL(profiles)
-};
diff --git a/ffmpeg-2-8-11/libavcodec/jpeglsdec.c b/ffmpeg-2-8-11/libavcodec/jpeglsdec.c
deleted file mode 100644
index 68151cb..0000000
--- a/ffmpeg-2-8-11/libavcodec/jpeglsdec.c
+++ /dev/null
@@ -1,528 +0,0 @@
-/*
- * JPEG-LS decoder
- * Copyright (c) 2003 Michael Niedermayer
- * Copyright (c) 2006 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
- */
-
-/**
- * @file
- * JPEG-LS decoder.
- */
-
-#include "avcodec.h"
-#include "get_bits.h"
-#include "golomb.h"
-#include "internal.h"
-#include "mathops.h"
-#include "mjpeg.h"
-#include "mjpegdec.h"
-#include "jpegls.h"
-#include "jpeglsdec.h"
-
-/*
- * Uncomment this to significantly speed up decoding of broken JPEG-LS
- * (or test broken JPEG-LS decoder) and slow down ordinary decoding a bit.
- *
- * There is no Golomb code with length >= 32 bits possible, so check and
- * avoid situation of 32 zeros, FFmpeg Golomb decoder is painfully slow
- * on this errors.
- */
-//#define JLS_BROKEN
-
-/**
- * Decode LSE block with initialization parameters
- */
-int ff_jpegls_decode_lse(MJpegDecodeContext *s)
-{
- int id;
- int tid, wt, maxtab, i, j;
-
- int len = get_bits(&s->gb, 16);
- id = get_bits(&s->gb, 8);
-
- switch (id) {
- case 1:
- if (len < 13)
- return AVERROR_INVALIDDATA;
-
- s->maxval = get_bits(&s->gb, 16);
- s->t1 = get_bits(&s->gb, 16);
- s->t2 = get_bits(&s->gb, 16);
- s->t3 = get_bits(&s->gb, 16);
- s->reset = get_bits(&s->gb, 16);
-
- if(s->avctx->debug & FF_DEBUG_PICT_INFO) {
- av_log(s->avctx, AV_LOG_DEBUG, "Coding parameters maxval:%d T1:%d T2:%d T3:%d reset:%d\n",
- s->maxval, s->t1, s->t2, s->t3, s->reset);
- }
-
-// ff_jpegls_reset_coding_parameters(s, 0);
- //FIXME quant table?
- break;
- case 2:
- s->palette_index = 0;
- case 3:
- tid= get_bits(&s->gb, 8);
- wt = get_bits(&s->gb, 8);
-
- if (len < 5)
- return AVERROR_INVALIDDATA;
-
- if (wt < 1 || wt > MAX_COMPONENTS) {
- avpriv_request_sample(s->avctx, "wt %d", wt);
- return AVERROR_PATCHWELCOME;
- }
-
- if (!s->maxval)
- maxtab = 255;
- else if ((5 + wt*(s->maxval+1)) < 65535)
- maxtab = s->maxval;
- else
- maxtab = 65530/wt - 1;
-
- if(s->avctx->debug & FF_DEBUG_PICT_INFO) {
- av_log(s->avctx, AV_LOG_DEBUG, "LSE palette %d tid:%d wt:%d maxtab:%d\n", id, tid, wt, maxtab);
- }
- if (maxtab >= 256) {
- avpriv_request_sample(s->avctx, ">8bit palette");
- return AVERROR_PATCHWELCOME;
- }
- maxtab = FFMIN(maxtab, (len - 5) / wt + s->palette_index);
-
- if (s->palette_index > maxtab)
- return AVERROR_INVALIDDATA;
-
- if ((s->avctx->pix_fmt == AV_PIX_FMT_GRAY8 || s->avctx->pix_fmt == AV_PIX_FMT_PAL8) &&
- (s->picture_ptr->format == AV_PIX_FMT_GRAY8 || s->picture_ptr->format == AV_PIX_FMT_PAL8)) {
- uint32_t *pal = (uint32_t *)s->picture_ptr->data[1];
- int shift = 0;
-
- if (s->avctx->bits_per_raw_sample > 0 && s->avctx->bits_per_raw_sample < 8) {
- maxtab = FFMIN(maxtab, (1<<s->avctx->bits_per_raw_sample)-1);
- shift = 8 - s->avctx->bits_per_raw_sample;
- }
-
- s->picture_ptr->format =
- s->avctx->pix_fmt = AV_PIX_FMT_PAL8;
- for (i=s->palette_index; i<=maxtab; i++) {
- uint8_t k = i << shift;
- pal[k] = 0;
- for (j=0; j<wt; j++) {
- pal[k] |= get_bits(&s->gb, 8) << (8*(wt-j-1));
- }
- }
- s->palette_index = i;
- }
- break;
- case 4:
- avpriv_request_sample(s->avctx, "oversize image");
- return AVERROR(ENOSYS);
- default:
- av_log(s->avctx, AV_LOG_ERROR, "invalid id %d\n", id);
- return AVERROR_INVALIDDATA;
- }
- ff_dlog(s->avctx, "ID=%i, T=%i,%i,%i\n", id, s->t1, s->t2, s->t3);
-
- return 0;
-}
-
-/**
- * Get context-dependent Golomb code, decode it and update context
- */
-static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q)
-{
- int k, ret;
-
- for (k = 0; (state->N[Q] << k) < state->A[Q]; k++)
- ;
-
-#ifdef JLS_BROKEN
- if (!show_bits_long(gb, 32))
- return -1;
-#endif
- ret = get_ur_golomb_jpegls(gb, k, state->limit, state->qbpp);
-
- /* decode mapped error */
- if (ret & 1)
- ret = -(ret + 1 >> 1);
- else
- ret >>= 1;
-
- /* for NEAR=0, k=0 and 2*B[Q] <= - N[Q] mapping is reversed */
- if (!state->near && !k && (2 * state->B[Q] <= -state->N[Q]))
- ret = -(ret + 1);
-
- ret = ff_jpegls_update_state_regular(state, Q, ret);
-
- return ret;
-}
-
-/**
- * Get Golomb code, decode it and update state for run termination
- */
-static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state,
- int RItype, int limit_add)
-{
- int k, ret, temp, map;
- int Q = 365 + RItype;
-
- temp = state->A[Q];
- if (RItype)
- temp += state->N[Q] >> 1;
-
- for (k = 0; (state->N[Q] << k) < temp; k++)
- ;
-
-#ifdef JLS_BROKEN
- if (!show_bits_long(gb, 32))
- return -1;
-#endif
- ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1,
- state->qbpp);
-
- /* decode mapped error */
- map = 0;
- if (!k && (RItype || ret) && (2 * state->B[Q] < state->N[Q]))
- map = 1;
- ret += RItype + map;
-
- if (ret & 1) {
- ret = map - (ret + 1 >> 1);
- state->B[Q]++;
- } else {
- ret = ret >> 1;
- }
-
- if(FFABS(ret) > 0xFFFF)
- return -0x10000;
- /* update state */
- state->A[Q] += FFABS(ret) - RItype;
- ret *= state->twonear;
- ff_jpegls_downscale_state(state, Q);
-
- return ret;
-}
-
-/**
- * Decode one line of image
- */
-static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s,
- void *last, void *dst, int last2, int w,
- int stride, int comp, int bits)
-{
- int i, x = 0;
- int Ra, Rb, Rc, Rd;
- int D0, D1, D2;
-
- while (x < w) {
- int err, pred;
-
- /* compute gradients */
- Ra = x ? R(dst, 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);
- D0 = Rd - Rb;
- D1 = Rb - Rc;
- D2 = Rc - Ra;
- /* run mode */
- if ((FFABS(D0) <= state->near) &&
- (FFABS(D1) <= state->near) &&
- (FFABS(D2) <= state->near)) {
- int r;
- int RItype;
-
- /* decode full runs while available */
- while (get_bits1(&s->gb)) {
- int r;
- r = 1 << ff_log2_run[state->run_index[comp]];
- if (x + r * stride > w)
- r = (w - x) / stride;
- for (i = 0; i < r; i++) {
- W(dst, x, Ra);
- x += stride;
- }
- /* if EOL reached, we stop decoding */
- if (r != 1 << ff_log2_run[state->run_index[comp]])
- return;
- if (state->run_index[comp] < 31)
- state->run_index[comp]++;
- if (x + stride > w)
- return;
- }
- /* decode aborted run */
- r = ff_log2_run[state->run_index[comp]];
- if (r)
- r = get_bits_long(&s->gb, r);
- if (x + r * stride > w) {
- r = (w - x) / stride;
- }
- for (i = 0; i < r; i++) {
- W(dst, x, Ra);
- x += stride;
- }
-
- if (x >= w) {
- av_log(NULL, AV_LOG_ERROR, "run overflow\n");
- av_assert0(x <= w);
- return;
- }
-
- /* decode run termination value */
- Rb = R(last, x);
- RItype = (FFABS(Ra - Rb) <= state->near) ? 1 : 0;
- err = ls_get_code_runterm(&s->gb, state, RItype,
- ff_log2_run[state->run_index[comp]]);
- if (state->run_index[comp])
- state->run_index[comp]--;
-
- if (state->near && RItype) {
- pred = Ra + err;
- } else {
- if (Rb < Ra)
- pred = Rb - err;
- else
- pred = Rb + err;
- }
- } else { /* regular mode */
- int context, sign;
-
- context = ff_jpegls_quantize(state, D0) * 81 +
- ff_jpegls_quantize(state, D1) * 9 +
- ff_jpegls_quantize(state, D2);
- pred = mid_pred(Ra, Ra + Rb - Rc, Rb);
-
- if (context < 0) {
- context = -context;
- sign = 1;
- } else {
- sign = 0;
- }
-
- if (sign) {
- pred = av_clip(pred - state->C[context], 0, state->maxval);
- err = -ls_get_code_regular(&s->gb, state, context);
- } else {
- pred = av_clip(pred + state->C[context], 0, state->maxval);
- err = ls_get_code_regular(&s->gb, state, context);
- }
-
- /* we have to do something more for near-lossless coding */
- pred += err;
- }
- if (state->near) {
- if (pred < -state->near)
- pred += state->range * state->twonear;
- else if (pred > state->maxval + state->near)
- pred -= state->range * state->twonear;
- pred = av_clip(pred, 0, state->maxval);
- }
-
- pred &= state->maxval;
- W(dst, x, pred);
- x += stride;
- }
-}
-
-int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near,
- int point_transform, int ilv)
-{
- int i, t = 0;
- uint8_t *zero, *last, *cur;
- JLSState *state;
- int off = 0, stride = 1, width, shift, ret = 0;
-
- zero = av_mallocz(s->picture_ptr->linesize[0]);
- if (!zero)
- return AVERROR(ENOMEM);
- last = zero;
- cur = s->picture_ptr->data[0];
-
- state = av_mallocz(sizeof(JLSState));
- if (!state) {
- av_free(zero);
- return AVERROR(ENOMEM);
- }
- /* initialize JPEG-LS state from JPEG parameters */
- state->near = near;
- state->bpp = (s->bits < 2) ? 2 : s->bits;
- state->maxval = s->maxval;
- state->T1 = s->t1;
- state->T2 = s->t2;
- state->T3 = s->t3;
- state->reset = s->reset;
- ff_jpegls_reset_coding_parameters(state, 0);
- ff_jpegls_init_state(state);
-
- if (s->bits <= 8)
- shift = point_transform + (8 - s->bits);
- else
- shift = point_transform + (16 - s->bits);
-
- if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
- av_log(s->avctx, AV_LOG_DEBUG,
- "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) "
- "RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n",
- s->width, s->height, state->near, state->maxval,
- state->T1, state->T2, state->T3,
- state->reset, state->limit, state->qbpp, state->range);
- av_log(s->avctx, AV_LOG_DEBUG, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n",
- ilv, point_transform, s->bits, s->cur_scan);
- }
- if (ilv == 0) { /* separate planes */
- if (s->cur_scan > s->nb_components) {
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- stride = (s->nb_components > 1) ? 3 : 1;
- off = av_clip(s->cur_scan - 1, 0, stride - 1);
- width = s->width * stride;
- cur += off;
- for (i = 0; i < s->height; i++) {
- if (s->bits <= 8) {
- ls_decode_line(state, s, last, cur, t, width, stride, off, 8);
- t = last[0];
- } else {
- ls_decode_line(state, s, last, cur, t, width, stride, off, 16);
- t = *((uint16_t *)last);
- }
- last = cur;
- cur += s->picture_ptr->linesize[0];
-
- if (s->restart_interval && !--s->restart_count) {
- align_get_bits(&s->gb);
- skip_bits(&s->gb, 16); /* skip RSTn */
- }
- }
- } else if (ilv == 1) { /* line interleaving */
- int j;
- int Rc[3] = { 0, 0, 0 };
- stride = (s->nb_components > 1) ? 3 : 1;
- memset(cur, 0, s->picture_ptr->linesize[0]);
- width = s->width * stride;
- for (i = 0; i < s->height; i++) {
- for (j = 0; j < stride; j++) {
- ls_decode_line(state, s, last + j, cur + j,
- Rc[j], width, stride, j, 8);
- Rc[j] = last[j];
-
- if (s->restart_interval && !--s->restart_count) {
- align_get_bits(&s->gb);
- skip_bits(&s->gb, 16); /* skip RSTn */
- }
- }
- last = cur;
- cur += s->picture_ptr->linesize[0];
- }
- } else if (ilv == 2) { /* sample interleaving */
- avpriv_report_missing_feature(s->avctx, "Sample interleaved images");
- ret = AVERROR_PATCHWELCOME;
- goto end;
- }
-
- if (s->xfrm && s->nb_components == 3) {
- int x, w;
-
- w = s->width * s->nb_components;
-
- if (s->bits <= 8) {
- uint8_t *src = s->picture_ptr->data[0];
-
- for (i = 0; i < s->height; i++) {
- switch(s->xfrm) {
- case 1:
- for (x = off; x < w; x += 3) {
- src[x ] += src[x+1] + 128;
- src[x+2] += src[x+1] + 128;
- }
- break;
- case 2:
- for (x = off; x < w; x += 3) {
- src[x ] += src[x+1] + 128;
- src[x+2] += ((src[x ] + src[x+1])>>1) + 128;
- }
- break;
- case 3:
- for (x = off; x < w; x += 3) {
- int g = src[x+0] - ((src[x+2]+src[x+1])>>2) + 64;
- src[x+0] = src[x+2] + g + 128;
- src[x+2] = src[x+1] + g + 128;
- src[x+1] = g;
- }
- break;
- case 4:
- for (x = off; x < w; x += 3) {
- int r = src[x+0] - (( 359 * (src[x+2]-128) + 490) >> 8);
- int g = src[x+0] - (( 88 * (src[x+1]-128) - 183 * (src[x+2]-128) + 30) >> 8);
- int b = src[x+0] + ((454 * (src[x+1]-128) + 574) >> 8);
- src[x+0] = av_clip_uint8(r);
- src[x+1] = av_clip_uint8(g);
- src[x+2] = av_clip_uint8(b);
- }
- break;
- }
- src += s->picture_ptr->linesize[0];
- }
- }else
- avpriv_report_missing_feature(s->avctx, "16bit xfrm");
- }
-
- if (shift) { /* we need to do point transform or normalize samples */
- int x, w;
-
- w = s->width * s->nb_components;
-
- if (s->bits <= 8) {
- uint8_t *src = s->picture_ptr->data[0];
-
- for (i = 0; i < s->height; i++) {
- for (x = off; x < w; x += stride)
- src[x] <<= shift;
- src += s->picture_ptr->linesize[0];
- }
- } else {
- uint16_t *src = (uint16_t *)s->picture_ptr->data[0];
-
- for (i = 0; i < s->height; i++) {
- for (x = 0; x < w; x++)
- src[x] <<= shift;
- src += s->picture_ptr->linesize[0] / 2;
- }
- }
- }
-
-end:
- av_free(state);
- av_free(zero);
-
- return ret;
-}
-
-AVCodec ff_jpegls_decoder = {
- .name = "jpegls",
- .long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_JPEGLS,
- .priv_data_size = sizeof(MJpegDecodeContext),
- .init = ff_mjpeg_decode_init,
- .close = ff_mjpeg_decode_end,
- .decode = ff_mjpeg_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/lagarith.c b/ffmpeg-2-8-11/libavcodec/lagarith.c
deleted file mode 100644
index 94d723d..0000000
--- a/ffmpeg-2-8-11/libavcodec/lagarith.c
+++ /dev/null
@@ -1,752 +0,0 @@
-/*
- * Lagarith lossless decoder
- * Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * Lagarith lossless decoder
- * @author Nathan Caldwell
- */
-
-#include <inttypes.h>
-
-#include "avcodec.h"
-#include "get_bits.h"
-#include "mathops.h"
-#include "huffyuvdsp.h"
-#include "lagarithrac.h"
-#include "thread.h"
-
-enum LagarithFrameType {
- FRAME_RAW = 1, /**< uncompressed */
- FRAME_U_RGB24 = 2, /**< unaligned RGB24 */
- FRAME_ARITH_YUY2 = 3, /**< arithmetic coded YUY2 */
- FRAME_ARITH_RGB24 = 4, /**< arithmetic coded RGB24 */
- FRAME_SOLID_GRAY = 5, /**< solid grayscale color frame */
- FRAME_SOLID_COLOR = 6, /**< solid non-grayscale color frame */
- FRAME_OLD_ARITH_RGB = 7, /**< obsolete arithmetic coded RGB (no longer encoded by upstream since version 1.1.0) */
- FRAME_ARITH_RGBA = 8, /**< arithmetic coded RGBA */
- FRAME_SOLID_RGBA = 9, /**< solid RGBA color frame */
- FRAME_ARITH_YV12 = 10, /**< arithmetic coded YV12 */
- FRAME_REDUCED_RES = 11, /**< reduced resolution YV12 frame */
-};
-
-typedef struct LagarithContext {
- AVCodecContext *avctx;
- HuffYUVDSPContext hdsp;
- int zeros; /**< number of consecutive zero bytes encountered */
- int zeros_rem; /**< number of zero bytes remaining to output */
- uint8_t *rgb_planes;
- int rgb_planes_allocated;
- int rgb_stride;
-} LagarithContext;
-
-/**
- * Compute the 52bit mantissa of 1/(double)denom.
- * This crazy format uses floats in an entropy coder and we have to match x86
- * rounding exactly, thus ordinary floats aren't portable enough.
- * @param denom denominator
- * @return 52bit mantissa
- * @see softfloat_mul
- */
-static uint64_t softfloat_reciprocal(uint32_t denom)
-{
- int shift = av_log2(denom - 1) + 1;
- uint64_t ret = (1ULL << 52) / denom;
- uint64_t err = (1ULL << 52) - ret * denom;
- ret <<= shift;
- err <<= shift;
- err += denom / 2;
- return ret + err / denom;
-}
-
-/**
- * (uint32_t)(x*f), where f has the given mantissa, and exponent 0
- * Used in combination with softfloat_reciprocal computes x/(double)denom.
- * @param x 32bit integer factor
- * @param mantissa mantissa of f with exponent 0
- * @return 32bit integer value (x*f)
- * @see softfloat_reciprocal
- */
-static uint32_t softfloat_mul(uint32_t x, uint64_t mantissa)
-{
- uint64_t l = x * (mantissa & 0xffffffff);
- uint64_t h = x * (mantissa >> 32);
- h += l >> 32;
- l &= 0xffffffff;
- l += 1 << av_log2(h >> 21);
- h += l >> 32;
- return h >> 20;
-}
-
-static uint8_t lag_calc_zero_run(int8_t x)
-{
- return (x << 1) ^ (x >> 7);
-}
-
-static int lag_decode_prob(GetBitContext *gb, uint32_t *value)
-{
- static const uint8_t series[] = { 1, 2, 3, 5, 8, 13, 21 };
- int i;
- int bit = 0;
- int bits = 0;
- int prevbit = 0;
- unsigned val;
-
- for (i = 0; i < 7; i++) {
- if (prevbit && bit)
- break;
- prevbit = bit;
- bit = get_bits1(gb);
- if (bit && !prevbit)
- bits += series[i];
- }
- bits--;
- if (bits < 0 || bits > 31) {
- *value = 0;
- return -1;
- } else if (bits == 0) {
- *value = 0;
- return 0;
- }
-
- val = get_bits_long(gb, bits);
- val |= 1U << bits;
-
- *value = val - 1;
-
- return 0;
-}
-
-static int lag_read_prob_header(lag_rac *rac, GetBitContext *gb)
-{
- int i, j, scale_factor;
- unsigned prob, cumulative_target;
- unsigned cumul_prob = 0;
- unsigned scaled_cumul_prob = 0;
-
- rac->prob[0] = 0;
- rac->prob[257] = UINT_MAX;
- /* Read probabilities from bitstream */
- for (i = 1; i < 257; i++) {
- if (lag_decode_prob(gb, &rac->prob[i]) < 0) {
- av_log(rac->avctx, AV_LOG_ERROR, "Invalid probability encountered.\n");
- return -1;
- }
- if ((uint64_t)cumul_prob + rac->prob[i] > UINT_MAX) {
- av_log(rac->avctx, AV_LOG_ERROR, "Integer overflow encountered in cumulative probability calculation.\n");
- return -1;
- }
- cumul_prob += rac->prob[i];
- if (!rac->prob[i]) {
- if (lag_decode_prob(gb, &prob)) {
- av_log(rac->avctx, AV_LOG_ERROR, "Invalid probability run encountered.\n");
- return -1;
- }
- if (prob > 256 - i)
- prob = 256 - i;
- for (j = 0; j < prob; j++)
- rac->prob[++i] = 0;
- }
- }
-
- if (!cumul_prob) {
- av_log(rac->avctx, AV_LOG_ERROR, "All probabilities are 0!\n");
- return -1;
- }
-
- /* Scale probabilities so cumulative probability is an even power of 2. */
- scale_factor = av_log2(cumul_prob);
-
- if (cumul_prob & (cumul_prob - 1)) {
- uint64_t mul = softfloat_reciprocal(cumul_prob);
- for (i = 1; i <= 128; i++) {
- rac->prob[i] = softfloat_mul(rac->prob[i], mul);
- scaled_cumul_prob += rac->prob[i];
- }
- if (scaled_cumul_prob <= 0) {
- av_log(rac->avctx, AV_LOG_ERROR, "Scaled probabilities invalid\n");
- return AVERROR_INVALIDDATA;
- }
- for (; i < 257; i++) {
- rac->prob[i] = softfloat_mul(rac->prob[i], mul);
- scaled_cumul_prob += rac->prob[i];
- }
-
- scale_factor++;
- cumulative_target = 1 << scale_factor;
-
- if (scaled_cumul_prob > cumulative_target) {
- av_log(rac->avctx, AV_LOG_ERROR,
- "Scaled probabilities are larger than target!\n");
- return -1;
- }
-
- scaled_cumul_prob = cumulative_target - scaled_cumul_prob;
-
- for (i = 1; scaled_cumul_prob; i = (i & 0x7f) + 1) {
- if (rac->prob[i]) {
- rac->prob[i]++;
- scaled_cumul_prob--;
- }
- /* Comment from reference source:
- * if (b & 0x80 == 0) { // order of operations is 'wrong'; it has been left this way
- * // since the compression change is negligible and fixing it
- * // breaks backwards compatibility
- * b =- (signed int)b;
- * b &= 0xFF;
- * } else {
- * b++;
- * b &= 0x7f;
- * }
- */
- }
- }
-
- rac->scale = scale_factor;
-
- /* Fill probability array with cumulative probability for each symbol. */
- for (i = 1; i < 257; i++)
- rac->prob[i] += rac->prob[i - 1];
-
- return 0;
-}
-
-static void add_lag_median_prediction(uint8_t *dst, uint8_t *src1,
- uint8_t *diff, int w, int *left,
- int *left_top)
-{
- /* This is almost identical to add_hfyu_median_pred in huffyuvdsp.h.
- * However the &0xFF on the gradient predictor yealds incorrect output
- * for lagarith.
- */
- int i;
- uint8_t l, lt;
-
- l = *left;
- lt = *left_top;
-
- for (i = 0; i < w; i++) {
- l = mid_pred(l, src1[i], l + src1[i] - lt) + diff[i];
- lt = src1[i];
- dst[i] = l;
- }
-
- *left = l;
- *left_top = lt;
-}
-
-static void lag_pred_line(LagarithContext *l, uint8_t *buf,
- int width, int stride, int line)
-{
- int L, TL;
-
- if (!line) {
- /* Left prediction only for first line */
- L = l->hdsp.add_hfyu_left_pred(buf, buf, width, 0);
- } else {
- /* Left pixel is actually prev_row[width] */
- L = buf[width - stride - 1];
-
- if (line == 1) {
- /* Second line, left predict first pixel, the rest of the line is median predicted
- * NOTE: In the case of RGB this pixel is top predicted */
- TL = l->avctx->pix_fmt == AV_PIX_FMT_YUV420P ? buf[-stride] : L;
- } else {
- /* Top left is 2 rows back, last pixel */
- TL = buf[width - (2 * stride) - 1];
- }
-
- add_lag_median_prediction(buf, buf - stride, buf,
- width, &L, &TL);
- }
-}
-
-static void lag_pred_line_yuy2(LagarithContext *l, uint8_t *buf,
- int width, int stride, int line,
- int is_luma)
-{
- int L, TL;
-
- if (!line) {
- L= buf[0];
- if (is_luma)
- buf[0] = 0;
- l->hdsp.add_hfyu_left_pred(buf, buf, width, 0);
- if (is_luma)
- buf[0] = L;
- return;
- }
- if (line == 1) {
- const int HEAD = is_luma ? 4 : 2;
- int i;
-
- L = buf[width - stride - 1];
- TL = buf[HEAD - stride - 1];
- for (i = 0; i < HEAD; i++) {
- L += buf[i];
- buf[i] = L;
- }
- for (; i < width; i++) {
- L = mid_pred(L & 0xFF, buf[i - stride], (L + buf[i - stride] - TL) & 0xFF) + buf[i];
- TL = buf[i - stride];
- buf[i] = L;
- }
- } else {
- TL = buf[width - (2 * stride) - 1];
- L = buf[width - stride - 1];
- l->hdsp.add_hfyu_median_pred(buf, buf - stride, buf, width, &L, &TL);
- }
-}
-
-static int lag_decode_line(LagarithContext *l, lag_rac *rac,
- uint8_t *dst, int width, int stride,
- int esc_count)
-{
- int i = 0;
- int ret = 0;
-
- if (!esc_count)
- esc_count = -1;
-
- /* Output any zeros remaining from the previous run */
-handle_zeros:
- if (l->zeros_rem) {
- int count = FFMIN(l->zeros_rem, width - i);
- memset(dst + i, 0, count);
- i += count;
- l->zeros_rem -= count;
- }
-
- while (i < width) {
- dst[i] = lag_get_rac(rac);
- ret++;
-
- if (dst[i])
- l->zeros = 0;
- else
- l->zeros++;
-
- i++;
- if (l->zeros == esc_count) {
- int index = lag_get_rac(rac);
- ret++;
-
- l->zeros = 0;
-
- l->zeros_rem = lag_calc_zero_run(index);
- goto handle_zeros;
- }
- }
- return ret;
-}
-
-static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst,
- const uint8_t *src, const uint8_t *src_end,
- int width, int esc_count)
-{
- int i = 0;
- int count;
- uint8_t zero_run = 0;
- const uint8_t *src_start = src;
- uint8_t mask1 = -(esc_count < 2);
- uint8_t mask2 = -(esc_count < 3);
- uint8_t *end = dst + (width - 2);
-
- avpriv_request_sample(l->avctx, "zero_run_line");
-
- memset(dst, 0, width);
-
-output_zeros:
- if (l->zeros_rem) {
- count = FFMIN(l->zeros_rem, width - i);
- if (end - dst < count) {
- av_log(l->avctx, AV_LOG_ERROR, "Too many zeros remaining.\n");
- return AVERROR_INVALIDDATA;
- }
-
- memset(dst, 0, count);
- l->zeros_rem -= count;
- dst += count;
- }
-
- while (dst < end) {
- i = 0;
- while (!zero_run && dst + i < end) {
- i++;
- if (i+2 >= src_end - src)
- return AVERROR_INVALIDDATA;
- zero_run =
- !(src[i] | (src[i + 1] & mask1) | (src[i + 2] & mask2));
- }
- if (zero_run) {
- zero_run = 0;
- i += esc_count;
- memcpy(dst, src, i);
- dst += i;
- l->zeros_rem = lag_calc_zero_run(src[i]);
-
- src += i + 1;
- goto output_zeros;
- } else {
- memcpy(dst, src, i);
- src += i;
- dst += i;
- }
- }
- return src - src_start;
-}
-
-
-
-static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst,
- int width, int height, int stride,
- const uint8_t *src, int src_size)
-{
- int i = 0;
- int read = 0;
- uint32_t length;
- uint32_t offset = 1;
- int esc_count;
- GetBitContext gb;
- lag_rac rac;
- const uint8_t *src_end = src + src_size;
- int ret;
-
- rac.avctx = l->avctx;
- l->zeros = 0;
-
- if(src_size < 2)
- return AVERROR_INVALIDDATA;
-
- esc_count = src[0];
- if (esc_count < 4) {
- length = width * height;
- if(src_size < 5)
- return AVERROR_INVALIDDATA;
- if (esc_count && AV_RL32(src + 1) < length) {
- length = AV_RL32(src + 1);
- offset += 4;
- }
-
- if ((ret = init_get_bits8(&gb, src + offset, src_size - offset)) < 0)
- return ret;
-
- if (lag_read_prob_header(&rac, &gb) < 0)
- return -1;
-
- ff_lag_rac_init(&rac, &gb, length - stride);
-
- for (i = 0; i < height; i++)
- read += lag_decode_line(l, &rac, dst + (i * stride), width,
- stride, esc_count);
-
- if (read > length)
- av_log(l->avctx, AV_LOG_WARNING,
- "Output more bytes than length (%d of %"PRIu32")\n", read,
- length);
- } else if (esc_count < 8) {
- esc_count -= 4;
- src ++;
- src_size --;
- if (esc_count > 0) {
- /* Zero run coding only, no range coding. */
- for (i = 0; i < height; i++) {
- int res = lag_decode_zero_run_line(l, dst + (i * stride), src,
- src_end, width, esc_count);
- if (res < 0)
- return res;
- src += res;
- }
- } else {
- if (src_size < width * height)
- return AVERROR_INVALIDDATA; // buffer not big enough
- /* Plane is stored uncompressed */
- for (i = 0; i < height; i++) {
- memcpy(dst + (i * stride), src, width);
- src += width;
- }
- }
- } else if (esc_count == 0xff) {
- /* Plane is a solid run of given value */
- for (i = 0; i < height; i++)
- memset(dst + i * stride, src[1], width);
- /* Do not apply prediction.
- Note: memset to 0 above, setting first value to src[1]
- and applying prediction gives the same result. */
- return 0;
- } else {
- av_log(l->avctx, AV_LOG_ERROR,
- "Invalid zero run escape code! (%#x)\n", esc_count);
- return -1;
- }
-
- if (l->avctx->pix_fmt != AV_PIX_FMT_YUV422P) {
- for (i = 0; i < height; i++) {
- lag_pred_line(l, dst, width, stride, i);
- dst += stride;
- }
- } else {
- for (i = 0; i < height; i++) {
- lag_pred_line_yuy2(l, dst, width, stride, i,
- width == l->avctx->width);
- dst += stride;
- }
- }
-
- return 0;
-}
-
-/**
- * Decode a frame.
- * @param avctx codec context
- * @param data output AVFrame
- * @param data_size size of output data or 0 if no picture is returned
- * @param avpkt input packet
- * @return number of consumed bytes on success or negative if decode fails
- */
-static int lag_decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame, AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- unsigned int buf_size = avpkt->size;
- LagarithContext *l = avctx->priv_data;
- ThreadFrame frame = { .f = data };
- AVFrame *const p = data;
- uint8_t frametype = 0;
- uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
- uint32_t offs[4];
- uint8_t *srcs[4], *dst;
- int i, j, planes = 3;
- int ret;
-
- p->key_frame = 1;
-
- frametype = buf[0];
-
- offset_gu = AV_RL32(buf + 1);
- offset_bv = AV_RL32(buf + 5);
-
- switch (frametype) {
- case FRAME_SOLID_RGBA:
- avctx->pix_fmt = AV_PIX_FMT_RGB32;
- case FRAME_SOLID_GRAY:
- if (frametype == FRAME_SOLID_GRAY)
- if (avctx->bits_per_coded_sample == 24) {
- avctx->pix_fmt = AV_PIX_FMT_RGB24;
- } else {
- avctx->pix_fmt = AV_PIX_FMT_0RGB32;
- planes = 4;
- }
-
- if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
- return ret;
-
- dst = p->data[0];
- if (frametype == FRAME_SOLID_RGBA) {
- for (j = 0; j < avctx->height; j++) {
- for (i = 0; i < avctx->width; i++)
- AV_WN32(dst + i * 4, offset_gu);
- dst += p->linesize[0];
- }
- } else {
- for (j = 0; j < avctx->height; j++) {
- memset(dst, buf[1], avctx->width * planes);
- dst += p->linesize[0];
- }
- }
- break;
- case FRAME_SOLID_COLOR:
- if (avctx->bits_per_coded_sample == 24) {
- avctx->pix_fmt = AV_PIX_FMT_RGB24;
- } else {
- avctx->pix_fmt = AV_PIX_FMT_RGB32;
- offset_gu |= 0xFFU << 24;
- }
-
- if ((ret = ff_thread_get_buffer(avctx, &frame,0)) < 0)
- return ret;
-
- dst = p->data[0];
- for (j = 0; j < avctx->height; j++) {
- for (i = 0; i < avctx->width; i++)
- if (avctx->bits_per_coded_sample == 24) {
- AV_WB24(dst + i * 3, offset_gu);
- } else {
- AV_WN32(dst + i * 4, offset_gu);
- }
- dst += p->linesize[0];
- }
- break;
- case FRAME_ARITH_RGBA:
- avctx->pix_fmt = AV_PIX_FMT_RGB32;
- planes = 4;
- offset_ry += 4;
- offs[3] = AV_RL32(buf + 9);
- case FRAME_ARITH_RGB24:
- case FRAME_U_RGB24:
- if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24)
- avctx->pix_fmt = AV_PIX_FMT_RGB24;
-
- if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
- return ret;
-
- offs[0] = offset_bv;
- offs[1] = offset_gu;
- offs[2] = offset_ry;
-
- l->rgb_stride = FFALIGN(avctx->width, 16);
- av_fast_malloc(&l->rgb_planes, &l->rgb_planes_allocated,
- l->rgb_stride * avctx->height * planes + 1);
- if (!l->rgb_planes) {
- av_log(avctx, AV_LOG_ERROR, "cannot allocate temporary buffer\n");
- return AVERROR(ENOMEM);
- }
- for (i = 0; i < planes; i++)
- srcs[i] = l->rgb_planes + (i + 1) * l->rgb_stride * avctx->height - l->rgb_stride;
- for (i = 0; i < planes; i++)
- if (buf_size <= offs[i]) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid frame offsets\n");
- return AVERROR_INVALIDDATA;
- }
-
- for (i = 0; i < planes; i++)
- lag_decode_arith_plane(l, srcs[i],
- avctx->width, avctx->height,
- -l->rgb_stride, buf + offs[i],
- buf_size - offs[i]);
- dst = p->data[0];
- for (i = 0; i < planes; i++)
- srcs[i] = l->rgb_planes + i * l->rgb_stride * avctx->height;
- for (j = 0; j < avctx->height; j++) {
- for (i = 0; i < avctx->width; i++) {
- uint8_t r, g, b, a;
- r = srcs[0][i];
- g = srcs[1][i];
- b = srcs[2][i];
- r += g;
- b += g;
- if (frametype == FRAME_ARITH_RGBA) {
- a = srcs[3][i];
- AV_WN32(dst + i * 4, MKBETAG(a, r, g, b));
- } else {
- dst[i * 3 + 0] = r;
- dst[i * 3 + 1] = g;
- dst[i * 3 + 2] = b;
- }
- }
- dst += p->linesize[0];
- for (i = 0; i < planes; i++)
- srcs[i] += l->rgb_stride;
- }
- break;
- case FRAME_ARITH_YUY2:
- avctx->pix_fmt = AV_PIX_FMT_YUV422P;
-
- if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
- return ret;
-
- if (offset_ry >= buf_size ||
- offset_gu >= buf_size ||
- offset_bv >= buf_size) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid frame offsets\n");
- return AVERROR_INVALIDDATA;
- }
-
- lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
- p->linesize[0], buf + offset_ry,
- buf_size - offset_ry);
- lag_decode_arith_plane(l, p->data[1], (avctx->width + 1) / 2,
- avctx->height, p->linesize[1],
- buf + offset_gu, buf_size - offset_gu);
- lag_decode_arith_plane(l, p->data[2], (avctx->width + 1) / 2,
- avctx->height, p->linesize[2],
- buf + offset_bv, buf_size - offset_bv);
- break;
- case FRAME_ARITH_YV12:
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
-
- if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
- return ret;
- if (buf_size <= offset_ry || buf_size <= offset_gu || buf_size <= offset_bv) {
- return AVERROR_INVALIDDATA;
- }
-
- if (offset_ry >= buf_size ||
- offset_gu >= buf_size ||
- offset_bv >= buf_size) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid frame offsets\n");
- return AVERROR_INVALIDDATA;
- }
-
- lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
- p->linesize[0], buf + offset_ry,
- buf_size - offset_ry);
- lag_decode_arith_plane(l, p->data[2], (avctx->width + 1) / 2,
- (avctx->height + 1) / 2, p->linesize[2],
- buf + offset_gu, buf_size - offset_gu);
- lag_decode_arith_plane(l, p->data[1], (avctx->width + 1) / 2,
- (avctx->height + 1) / 2, p->linesize[1],
- buf + offset_bv, buf_size - offset_bv);
- break;
- default:
- av_log(avctx, AV_LOG_ERROR,
- "Unsupported Lagarith frame type: %#"PRIx8"\n", frametype);
- return AVERROR_PATCHWELCOME;
- }
-
- *got_frame = 1;
-
- return buf_size;
-}
-
-static av_cold int lag_decode_init(AVCodecContext *avctx)
-{
- LagarithContext *l = avctx->priv_data;
- l->avctx = avctx;
-
- ff_huffyuvdsp_init(&l->hdsp);
-
- return 0;
-}
-
-static av_cold int lag_decode_end(AVCodecContext *avctx)
-{
- LagarithContext *l = avctx->priv_data;
-
- av_freep(&l->rgb_planes);
-
- return 0;
-}
-
-AVCodec ff_lagarith_decoder = {
- .name = "lagarith",
- .long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_LAGARITH,
- .priv_data_size = sizeof(LagarithContext),
- .init = lag_decode_init,
- .close = lag_decode_end,
- .decode = lag_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/libfdk-aacdec.c b/ffmpeg-2-8-11/libavcodec/libfdk-aacdec.c
deleted file mode 100644
index e5f7c4e..0000000
--- a/ffmpeg-2-8-11/libavcodec/libfdk-aacdec.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- * AAC decoder wrapper
- * Copyright (c) 2012 Martin Storsjo
- *
- * This file is part of FFmpeg.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <fdk-aac/aacdecoder_lib.h>
-
-#include "libavutil/channel_layout.h"
-#include "libavutil/common.h"
-#include "libavutil/opt.h"
-#include "avcodec.h"
-#include "internal.h"
-
-/* The version macro is introduced the same time as the setting enum was
- * changed, so this check should suffice. */
-#ifndef AACDECODER_LIB_VL0
-#define AAC_PCM_MAX_OUTPUT_CHANNELS AAC_PCM_OUTPUT_CHANNELS
-#endif
-
-enum ConcealMethod {
- CONCEAL_METHOD_SPECTRAL_MUTING = 0,
- CONCEAL_METHOD_NOISE_SUBSTITUTION = 1,
- CONCEAL_METHOD_ENERGY_INTERPOLATION = 2,
- CONCEAL_METHOD_NB,
-};
-
-typedef struct FDKAACDecContext {
- const AVClass *class;
- HANDLE_AACDECODER handle;
- uint8_t *decoder_buffer;
- int decoder_buffer_size;
- uint8_t *anc_buffer;
- int conceal_method;
- int drc_level;
- int drc_boost;
- int drc_heavy;
- int drc_cut;
- int level_limit;
-} FDKAACDecContext;
-
-
-#define DMX_ANC_BUFFSIZE 128
-#define DECODER_MAX_CHANNELS 8
-#define DECODER_BUFFSIZE 2048 * sizeof(INT_PCM)
-
-#define OFFSET(x) offsetof(FDKAACDecContext, x)
-#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
-static const AVOption fdk_aac_dec_options[] = {
- { "conceal", "Error concealment method", OFFSET(conceal_method), AV_OPT_TYPE_INT, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION }, CONCEAL_METHOD_SPECTRAL_MUTING, CONCEAL_METHOD_NB - 1, AD, "conceal" },
- { "spectral", "Spectral muting", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_SPECTRAL_MUTING }, INT_MIN, INT_MAX, AD, "conceal" },
- { "noise", "Noise Substitution", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION }, INT_MIN, INT_MAX, AD, "conceal" },
- { "energy", "Energy Interpolation", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_ENERGY_INTERPOLATION }, INT_MIN, INT_MAX, AD, "conceal" },
- { "drc_boost", "Dynamic Range Control: boost, where [0] is none and [127] is max boost",
- OFFSET(drc_boost), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 127, AD, NULL },
- { "drc_cut", "Dynamic Range Control: attenuation factor, where [0] is none and [127] is max compression",
- OFFSET(drc_cut), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 127, AD, NULL },
- { "drc_level", "Dynamic Range Control: reference level, quantized to 0.25dB steps where [0] is 0dB and [127] is -31.75dB",
- OFFSET(drc_level), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 127, AD, NULL },
- { "drc_heavy", "Dynamic Range Control: heavy compression, where [1] is on (RF mode) and [0] is off",
- OFFSET(drc_heavy), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 1, AD, NULL },
-#ifdef AACDECODER_LIB_VL0
- { "level_limit", "Signal level limiting", OFFSET(level_limit), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, 1, AD },
-#endif
- { NULL }
-};
-
-static const AVClass fdk_aac_dec_class = {
- "libfdk-aac decoder", av_default_item_name, fdk_aac_dec_options, LIBAVUTIL_VERSION_INT
-};
-
-static int get_stream_info(AVCodecContext *avctx)
-{
- FDKAACDecContext *s = avctx->priv_data;
- CStreamInfo *info = aacDecoder_GetStreamInfo(s->handle);
- int channel_counts[0x24] = { 0 };
- int i, ch_error = 0;
- uint64_t ch_layout = 0;
-
- if (!info) {
- av_log(avctx, AV_LOG_ERROR, "Unable to get stream info\n");
- return AVERROR_UNKNOWN;
- }
-
- if (info->sampleRate <= 0) {
- av_log(avctx, AV_LOG_ERROR, "Stream info not initialized\n");
- return AVERROR_UNKNOWN;
- }
- avctx->sample_rate = info->sampleRate;
- avctx->frame_size = info->frameSize;
-
- for (i = 0; i < info->numChannels; i++) {
- AUDIO_CHANNEL_TYPE ctype = info->pChannelType[i];
- if (ctype <= ACT_NONE || ctype >= FF_ARRAY_ELEMS(channel_counts)) {
- av_log(avctx, AV_LOG_WARNING, "unknown channel type\n");
- break;
- }
- channel_counts[ctype]++;
- }
- av_log(avctx, AV_LOG_DEBUG,
- "%d channels - front:%d side:%d back:%d lfe:%d top:%d\n",
- info->numChannels,
- channel_counts[ACT_FRONT], channel_counts[ACT_SIDE],
- channel_counts[ACT_BACK], channel_counts[ACT_LFE],
- channel_counts[ACT_FRONT_TOP] + channel_counts[ACT_SIDE_TOP] +
- channel_counts[ACT_BACK_TOP] + channel_counts[ACT_TOP]);
-
- switch (channel_counts[ACT_FRONT]) {
- case 4:
- ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_LEFT_OF_CENTER |
- AV_CH_FRONT_RIGHT_OF_CENTER;
- break;
- case 3:
- ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER;
- break;
- case 2:
- ch_layout |= AV_CH_LAYOUT_STEREO;
- break;
- case 1:
- ch_layout |= AV_CH_FRONT_CENTER;
- break;
- default:
- av_log(avctx, AV_LOG_WARNING,
- "unsupported number of front channels: %d\n",
- channel_counts[ACT_FRONT]);
- ch_error = 1;
- break;
- }
- if (channel_counts[ACT_SIDE] > 0) {
- if (channel_counts[ACT_SIDE] == 2) {
- ch_layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT;
- } else {
- av_log(avctx, AV_LOG_WARNING,
- "unsupported number of side channels: %d\n",
- channel_counts[ACT_SIDE]);
- ch_error = 1;
- }
- }
- if (channel_counts[ACT_BACK] > 0) {
- switch (channel_counts[ACT_BACK]) {
- case 3:
- ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_BACK_CENTER;
- break;
- case 2:
- ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT;
- break;
- case 1:
- ch_layout |= AV_CH_BACK_CENTER;
- break;
- default:
- av_log(avctx, AV_LOG_WARNING,
- "unsupported number of back channels: %d\n",
- channel_counts[ACT_BACK]);
- ch_error = 1;
- break;
- }
- }
- if (channel_counts[ACT_LFE] > 0) {
- if (channel_counts[ACT_LFE] == 1) {
- ch_layout |= AV_CH_LOW_FREQUENCY;
- } else {
- av_log(avctx, AV_LOG_WARNING,
- "unsupported number of LFE channels: %d\n",
- channel_counts[ACT_LFE]);
- ch_error = 1;
- }
- }
- if (!ch_error &&
- av_get_channel_layout_nb_channels(ch_layout) != info->numChannels) {
- av_log(avctx, AV_LOG_WARNING, "unsupported channel configuration\n");
- ch_error = 1;
- }
- if (ch_error)
- avctx->channel_layout = 0;
- else
- avctx->channel_layout = ch_layout;
-
- avctx->channels = info->numChannels;
-
- return 0;
-}
-
-static av_cold int fdk_aac_decode_close(AVCodecContext *avctx)
-{
- FDKAACDecContext *s = avctx->priv_data;
-
- if (s->handle)
- aacDecoder_Close(s->handle);
- av_freep(&s->decoder_buffer);
- av_freep(&s->anc_buffer);
-
- return 0;
-}
-
-static av_cold int fdk_aac_decode_init(AVCodecContext *avctx)
-{
- FDKAACDecContext *s = avctx->priv_data;
- AAC_DECODER_ERROR err;
-
- s->handle = aacDecoder_Open(avctx->extradata_size ? TT_MP4_RAW : TT_MP4_ADTS, 1);
- if (!s->handle) {
- av_log(avctx, AV_LOG_ERROR, "Error opening decoder\n");
- return AVERROR_UNKNOWN;
- }
-
- if (avctx->extradata_size) {
- if ((err = aacDecoder_ConfigRaw(s->handle, &avctx->extradata,
- &avctx->extradata_size)) != AAC_DEC_OK) {
- av_log(avctx, AV_LOG_ERROR, "Unable to set extradata\n");
- return AVERROR_INVALIDDATA;
- }
- }
-
- if ((err = aacDecoder_SetParam(s->handle, AAC_CONCEAL_METHOD,
- s->conceal_method)) != AAC_DEC_OK) {
- av_log(avctx, AV_LOG_ERROR, "Unable to set error concealment method\n");
- return AVERROR_UNKNOWN;
- }
-
- if (avctx->request_channel_layout > 0 &&
- avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE) {
- int downmix_channels = -1;
-
- switch (avctx->request_channel_layout) {
- case AV_CH_LAYOUT_STEREO:
- case AV_CH_LAYOUT_STEREO_DOWNMIX:
- downmix_channels = 2;
- break;
- case AV_CH_LAYOUT_MONO:
- downmix_channels = 1;
- break;
- default:
- av_log(avctx, AV_LOG_WARNING, "Invalid request_channel_layout\n");
- break;
- }
-
- if (downmix_channels != -1) {
- if (aacDecoder_SetParam(s->handle, AAC_PCM_MAX_OUTPUT_CHANNELS,
- downmix_channels) != AAC_DEC_OK) {
- av_log(avctx, AV_LOG_WARNING, "Unable to set output channels in the decoder\n");
- } else {
- s->anc_buffer = av_malloc(DMX_ANC_BUFFSIZE);
- if (!s->anc_buffer) {
- av_log(avctx, AV_LOG_ERROR, "Unable to allocate ancillary buffer for the decoder\n");
- return AVERROR(ENOMEM);
- }
- if (aacDecoder_AncDataInit(s->handle, s->anc_buffer, DMX_ANC_BUFFSIZE)) {
- av_log(avctx, AV_LOG_ERROR, "Unable to register downmix ancillary buffer in the decoder\n");
- return AVERROR_UNKNOWN;
- }
- }
- }
- }
-
- if (s->drc_boost != -1) {
- if (aacDecoder_SetParam(s->handle, AAC_DRC_BOOST_FACTOR, s->drc_boost) != AAC_DEC_OK) {
- av_log(avctx, AV_LOG_ERROR, "Unable to set DRC boost factor in the decoder\n");
- return AVERROR_UNKNOWN;
- }
- }
-
- if (s->drc_cut != -1) {
- if (aacDecoder_SetParam(s->handle, AAC_DRC_ATTENUATION_FACTOR, s->drc_cut) != AAC_DEC_OK) {
- av_log(avctx, AV_LOG_ERROR, "Unable to set DRC attenuation factor in the decoder\n");
- return AVERROR_UNKNOWN;
- }
- }
-
- if (s->drc_level != -1) {
- if (aacDecoder_SetParam(s->handle, AAC_DRC_REFERENCE_LEVEL, s->drc_level) != AAC_DEC_OK) {
- av_log(avctx, AV_LOG_ERROR, "Unable to set DRC reference level in the decoder\n");
- return AVERROR_UNKNOWN;
- }
- }
-
- if (s->drc_heavy != -1) {
- if (aacDecoder_SetParam(s->handle, AAC_DRC_HEAVY_COMPRESSION, s->drc_heavy) != AAC_DEC_OK) {
- av_log(avctx, AV_LOG_ERROR, "Unable to set DRC heavy compression in the decoder\n");
- return AVERROR_UNKNOWN;
- }
- }
-
-#ifdef AACDECODER_LIB_VL0
- if (aacDecoder_SetParam(s->handle, AAC_PCM_LIMITER_ENABLE, s->level_limit) != AAC_DEC_OK) {
- av_log(avctx, AV_LOG_ERROR, "Unable to set in signal level limiting in the decoder\n");
- return AVERROR_UNKNOWN;
- }
-#endif
-
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-
- s->decoder_buffer_size = DECODER_BUFFSIZE * DECODER_MAX_CHANNELS;
- s->decoder_buffer = av_malloc(s->decoder_buffer_size);
- if (!s->decoder_buffer)
- return AVERROR(ENOMEM);
-
- return 0;
-}
-
-static int fdk_aac_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- FDKAACDecContext *s = avctx->priv_data;
- AVFrame *frame = data;
- int ret;
- AAC_DECODER_ERROR err;
- UINT valid = avpkt->size;
-
- err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid);
- if (err != AAC_DEC_OK) {
- av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err);
- return AVERROR_INVALIDDATA;
- }
-
- err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) s->decoder_buffer, s->decoder_buffer_size, 0);
- if (err == AAC_DEC_NOT_ENOUGH_BITS) {
- ret = avpkt->size - valid;
- goto end;
- }
- if (err != AAC_DEC_OK) {
- av_log(avctx, AV_LOG_ERROR,
- "aacDecoder_DecodeFrame() failed: %x\n", err);
- ret = AVERROR_UNKNOWN;
- goto end;
- }
-
- if ((ret = get_stream_info(avctx)) < 0)
- goto end;
- frame->nb_samples = avctx->frame_size;
-
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- goto end;
-
- memcpy(frame->extended_data[0], s->decoder_buffer,
- avctx->channels * avctx->frame_size *
- av_get_bytes_per_sample(avctx->sample_fmt));
-
- *got_frame_ptr = 1;
- ret = avpkt->size - valid;
-
-end:
- return ret;
-}
-
-static av_cold void fdk_aac_decode_flush(AVCodecContext *avctx)
-{
- FDKAACDecContext *s = avctx->priv_data;
- AAC_DECODER_ERROR err;
-
- if (!s->handle)
- return;
-
- if ((err = aacDecoder_SetParam(s->handle,
- AAC_TPDEC_CLEAR_BUFFER, 1)) != AAC_DEC_OK)
- av_log(avctx, AV_LOG_WARNING, "failed to clear buffer when flushing\n");
-}
-
-AVCodec ff_libfdk_aac_decoder = {
- .name = "libfdk_aac",
- .long_name = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_AAC,
- .priv_data_size = sizeof(FDKAACDecContext),
- .init = fdk_aac_decode_init,
- .decode = fdk_aac_decode_frame,
- .close = fdk_aac_decode_close,
- .flush = fdk_aac_decode_flush,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
- .priv_class = &fdk_aac_dec_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/mdec.c b/ffmpeg-2-8-11/libavcodec/mdec.c
deleted file mode 100644
index ee96614..0000000
--- a/ffmpeg-2-8-11/libavcodec/mdec.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Sony PlayStation MDEC (Motion DECoder)
- * Copyright (c) 2003 Michael Niedermayer
- *
- * based upon code from Sebastian Jedruszkiewicz <elf at frogger.rules.pl>
- *
- * 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
- * Sony PlayStation MDEC (Motion DECoder)
- * This is very similar to intra-only MPEG-1.
- */
-
-#include "avcodec.h"
-#include "blockdsp.h"
-#include "bswapdsp.h"
-#include "idctdsp.h"
-#include "mpegvideo.h"
-#include "mpeg12.h"
-#include "thread.h"
-
-typedef struct MDECContext {
- AVCodecContext *avctx;
- BlockDSPContext bdsp;
- BswapDSPContext bbdsp;
- IDCTDSPContext idsp;
- ThreadFrame frame;
- GetBitContext gb;
- ScanTable scantable;
- int version;
- int qscale;
- int last_dc[3];
- int mb_width;
- int mb_height;
- int mb_x, mb_y;
- DECLARE_ALIGNED(16, int16_t, block)[6][64];
- uint8_t *bitstream_buffer;
- unsigned int bitstream_buffer_size;
- int block_last_index[6];
-} MDECContext;
-
-//very similar to MPEG-1
-static inline int mdec_decode_block_intra(MDECContext *a, int16_t *block, int n)
-{
- int level, diff, i, j, run;
- int component;
- RLTable *rl = &ff_rl_mpeg1;
- uint8_t * const scantable = a->scantable.permutated;
- const uint16_t *quant_matrix = ff_mpeg1_default_intra_matrix;
- const int qscale = a->qscale;
-
- /* DC coefficient */
- if (a->version == 2) {
- block[0] = 2 * get_sbits(&a->gb, 10) + 1024;
- } 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] << 3;
- }
-
- i = 0;
- {
- OPEN_READER(re, &a->gb);
- /* now quantify & encode AC coefficients */
- for (;;) {
- UPDATE_CACHE(re, &a->gb);
- GET_RL_VLC(level, run, re, &a->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-
- if (level == 127) {
- break;
- } else if (level != 0) {
- i += run;
- if (i > 63) {
- av_log(a->avctx, AV_LOG_ERROR,
- "ac-tex damaged at %d %d\n", a->mb_x, a->mb_y);
- return AVERROR_INVALIDDATA;
- }
- j = scantable[i];
- level = (level * qscale * quant_matrix[j]) >> 3;
- level = (level ^ SHOW_SBITS(re, &a->gb, 1)) - SHOW_SBITS(re, &a->gb, 1);
- LAST_SKIP_BITS(re, &a->gb, 1);
- } else {
- /* escape */
- run = SHOW_UBITS(re, &a->gb, 6)+1; LAST_SKIP_BITS(re, &a->gb, 6);
- UPDATE_CACHE(re, &a->gb);
- level = SHOW_SBITS(re, &a->gb, 10); SKIP_BITS(re, &a->gb, 10);
- i += run;
- if (i > 63) {
- av_log(a->avctx, AV_LOG_ERROR,
- "ac-tex damaged at %d %d\n", a->mb_x, a->mb_y);
- return AVERROR_INVALIDDATA;
- }
- j = scantable[i];
- if (level < 0) {
- level = -level;
- level = (level * qscale * quant_matrix[j]) >> 3;
- level = (level - 1) | 1;
- level = -level;
- } else {
- level = (level * qscale * quant_matrix[j]) >> 3;
- level = (level - 1) | 1;
- }
- }
-
- block[j] = level;
- }
- CLOSE_READER(re, &a->gb);
- }
- a->block_last_index[n] = i;
- return 0;
-}
-
-static inline int decode_mb(MDECContext *a, int16_t block[6][64])
-{
- int i, ret;
- static const int block_index[6] = { 5, 4, 0, 1, 2, 3 };
-
- a->bdsp.clear_blocks(block[0]);
-
- for (i = 0; i < 6; i++) {
- if ((ret = mdec_decode_block_intra(a, block[block_index[i]],
- block_index[i])) < 0)
- return ret;
- if (get_bits_left(&a->gb) < 0)
- return AVERROR_INVALIDDATA;
- }
- return 0;
-}
-
-static inline void idct_put(MDECContext *a, AVFrame *frame, int mb_x, int mb_y)
-{
- int16_t (*block)[64] = a->block;
- int linesize = frame->linesize[0];
-
- uint8_t *dest_y = frame->data[0] + (mb_y * 16* linesize ) + mb_x * 16;
- uint8_t *dest_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8;
- uint8_t *dest_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8;
-
- a->idsp.idct_put(dest_y, linesize, block[0]);
- a->idsp.idct_put(dest_y + 8, linesize, block[1]);
- a->idsp.idct_put(dest_y + 8 * linesize, linesize, block[2]);
- a->idsp.idct_put(dest_y + 8 * linesize + 8, linesize, block[3]);
-
- if (!(a->avctx->flags & AV_CODEC_FLAG_GRAY)) {
- a->idsp.idct_put(dest_cb, frame->linesize[1], block[4]);
- a->idsp.idct_put(dest_cr, frame->linesize[2], block[5]);
- }
-}
-
-static int decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- MDECContext * const a = avctx->priv_data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- ThreadFrame frame = { .f = data };
- int ret;
-
- if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
- return ret;
- frame.f->pict_type = AV_PICTURE_TYPE_I;
- frame.f->key_frame = 1;
-
- av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size);
- if (!a->bitstream_buffer)
- return AVERROR(ENOMEM);
- a->bbdsp.bswap16_buf((uint16_t *)a->bitstream_buffer, (uint16_t *)buf, (buf_size + 1) / 2);
- if ((ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size)) < 0)
- return ret;
-
- /* skip over 4 preamble bytes in stream (typically 0xXX 0xXX 0x00 0x38) */
- skip_bits(&a->gb, 32);
-
- a->qscale = get_bits(&a->gb, 16);
- a->version = get_bits(&a->gb, 16);
-
- a->last_dc[0] = a->last_dc[1] = a->last_dc[2] = 128;
-
- for (a->mb_x = 0; a->mb_x < a->mb_width; a->mb_x++) {
- for (a->mb_y = 0; a->mb_y < a->mb_height; a->mb_y++) {
- if ((ret = decode_mb(a, a->block)) < 0)
- return ret;
-
- idct_put(a, frame.f, a->mb_x, a->mb_y);
- }
- }
-
- *got_frame = 1;
-
- return (get_bits_count(&a->gb) + 31) / 32 * 4;
-}
-
-static av_cold int decode_init(AVCodecContext *avctx)
-{
- MDECContext * const a = avctx->priv_data;
-
- a->mb_width = (avctx->coded_width + 15) / 16;
- a->mb_height = (avctx->coded_height + 15) / 16;
-
- a->avctx = avctx;
-
- ff_blockdsp_init(&a->bdsp, avctx);
- ff_bswapdsp_init(&a->bbdsp);
- ff_idctdsp_init(&a->idsp, avctx);
- ff_mpeg12_init_vlcs();
- ff_init_scantable(a->idsp.idct_permutation, &a->scantable,
- ff_zigzag_direct);
-
- if (avctx->idct_algo == FF_IDCT_AUTO)
- avctx->idct_algo = FF_IDCT_SIMPLE;
- avctx->pix_fmt = AV_PIX_FMT_YUVJ420P;
- avctx->color_range = AVCOL_RANGE_JPEG;
-
- return 0;
-}
-
-static av_cold int decode_init_thread_copy(AVCodecContext *avctx)
-{
- MDECContext * const a = avctx->priv_data;
-
- a->avctx = avctx;
-
- return 0;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx)
-{
- MDECContext * const a = avctx->priv_data;
-
- av_freep(&a->bitstream_buffer);
- a->bitstream_buffer_size = 0;
-
- return 0;
-}
-
-AVCodec ff_mdec_decoder = {
- .name = "mdec",
- .long_name = NULL_IF_CONFIG_SMALL("Sony PlayStation MDEC (Motion DECoder)"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MDEC,
- .priv_data_size = sizeof(MDECContext),
- .init = decode_init,
- .close = decode_end,
- .decode = decode_frame,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy)
-};
diff --git a/ffmpeg-2-8-11/libavcodec/mimic.c b/ffmpeg-2-8-11/libavcodec/mimic.c
deleted file mode 100644
index f5853b5..0000000
--- a/ffmpeg-2-8-11/libavcodec/mimic.c
+++ /dev/null
@@ -1,485 +0,0 @@
-/*
- * Copyright (C) 2005 Ole André Vadla Ravnås <oleavr at gmail.com>
- * Copyright (C) 2008 Ramiro Polla
- *
- * 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 <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-
-#include "avcodec.h"
-#include "blockdsp.h"
-#include "internal.h"
-#include "get_bits.h"
-#include "bytestream.h"
-#include "bswapdsp.h"
-#include "hpeldsp.h"
-#include "idctdsp.h"
-#include "thread.h"
-
-#define MIMIC_HEADER_SIZE 20
-
-typedef struct MimicContext {
- AVCodecContext *avctx;
-
- int num_vblocks[3];
- int num_hblocks[3];
-
- void *swap_buf;
- int swap_buf_size;
-
- int cur_index;
- int prev_index;
-
- ThreadFrame frames [16];
- AVPicture flipped_ptrs[16];
-
- DECLARE_ALIGNED(16, int16_t, dct_block)[64];
-
- GetBitContext gb;
- ScanTable scantable;
- BlockDSPContext bdsp;
- 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 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,
-};
-
-static const uint8_t col_zag[64] = {
- 0, 8, 1, 2, 9, 16, 24, 17,
- 10, 3, 4, 11, 18, 25, 32, 40,
- 33, 26, 19, 12, 5, 6, 13, 20,
- 27, 34, 41, 48, 56, 49, 42, 35,
- 28, 21, 14, 7, 15, 22, 29, 36,
- 43, 50, 57, 58, 51, 44, 37, 30,
- 23, 31, 38, 45, 52, 59, 39, 46,
- 53, 60, 61, 54, 47, 55, 62, 63,
-};
-
-static av_cold int mimic_decode_end(AVCodecContext *avctx)
-{
- MimicContext *ctx = avctx->priv_data;
- int i;
-
- av_freep(&ctx->swap_buf);
- ctx->swap_buf_size = 0;
-
- for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
- if (ctx->frames[i].f)
- ff_thread_release_buffer(avctx, &ctx->frames[i]);
- av_frame_free(&ctx->frames[i].f);
- }
-
- if (!avctx->internal->is_copy)
- ff_free_vlc(&ctx->vlc);
-
- return 0;
-}
-
-static av_cold int mimic_decode_init(AVCodecContext *avctx)
-{
- MimicContext *ctx = avctx->priv_data;
- int ret, i;
-
- avctx->internal->allocate_progress = 1;
-
- 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);
- ff_idctdsp_init(&ctx->idsp, avctx);
- ff_init_scantable(ctx->idsp.idct_permutation, &ctx->scantable, col_zag);
-
- 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);
- return AVERROR(ENOMEM);
- }
- }
-
- return 0;
-}
-
-static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
-{
- MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
- int i, ret;
-
- if (avctx == avctx_from)
- return 0;
-
- dst->cur_index = src->next_cur_index;
- dst->prev_index = src->next_prev_index;
-
- memcpy(dst->flipped_ptrs, src->flipped_ptrs, sizeof(src->flipped_ptrs));
-
- for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
- ff_thread_release_buffer(avctx, &dst->frames[i]);
- if (i != src->next_cur_index && src->frames[i].f->data[0]) {
- ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
- if (ret < 0)
- return ret;
- }
- }
-
- return 0;
-}
-
-static const int8_t vlcdec_lookup[9][64] = {
- { 0, },
- { -1, 1, },
- { -3, 3, -2, 2, },
- { -7, 7, -6, 6, -5, 5, -4, 4, },
- { -15, 15, -14, 14, -13, 13, -12, 12,
- -11, 11, -10, 10, -9, 9, -8, 8, },
- { -31, 31, -30, 30, -29, 29, -28, 28,
- -27, 27, -26, 26, -25, 25, -24, 24,
- -23, 23, -22, 22, -21, 21, -20, 20,
- -19, 19, -18, 18, -17, 17, -16, 16, },
- { -63, 63, -62, 62, -61, 61, -60, 60,
- -59, 59, -58, 58, -57, 57, -56, 56,
- -55, 55, -54, 54, -53, 53, -52, 52,
- -51, 51, -50, 50, -49, 49, -48, 48,
- -47, 47, -46, 46, -45, 45, -44, 44,
- -43, 43, -42, 42, -41, 41, -40, 40,
- -39, 39, -38, 38, -37, 37, -36, 36,
- -35, 35, -34, 34, -33, 33, -32, 32, },
- { -127, 127, -126, 126, -125, 125, -124, 124,
- -123, 123, -122, 122, -121, 121, -120, 120,
- -119, 119, -118, 118, -117, 117, -116, 116,
- -115, 115, -114, 114, -113, 113, -112, 112,
- -111, 111, -110, 110, -109, 109, -108, 108,
- -107, 107, -106, 106, -105, 105, -104, 104,
- -103, 103, -102, 102, -101, 101, -100, 100,
- -99, 99, -98, 98, -97, 97, -96, 96, },
- { -95, 95, -94, 94, -93, 93, -92, 92,
- -91, 91, -90, 90, -89, 89, -88, 88,
- -87, 87, -86, 86, -85, 85, -84, 84,
- -83, 83, -82, 82, -81, 81, -80, 80,
- -79, 79, -78, 78, -77, 77, -76, 76,
- -75, 75, -74, 74, -73, 73, -72, 72,
- -71, 71, -70, 70, -69, 69, -68, 68,
- -67, 67, -66, 66, -65, 65, -64, 64, },
-};
-
-static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
-{
- int16_t *block = ctx->dct_block;
- unsigned int pos;
-
- ctx->bdsp.clear_block(block);
-
- block[0] = get_bits(&ctx->gb, 8) << 3;
-
- for (pos = 1; pos < num_coeffs; pos++) {
- uint32_t vlc, num_bits;
- int value;
- int coeff;
-
- vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
- if (!vlc) /* end-of-block code */
- return 0;
- if (vlc == -1)
- return AVERROR_INVALIDDATA;
-
- /* pos_add and num_bits are coded in the vlc code */
- pos += vlc & 15; // pos_add
- num_bits = vlc >> 4; // num_bits
-
- if (pos >= 64)
- return AVERROR_INVALIDDATA;
-
- value = get_bits(&ctx->gb, num_bits);
-
- /* FFmpeg's IDCT behaves somewhat different from the original code, so
- * a factor of 4 was added to the input */
-
- coeff = vlcdec_lookup[num_bits][value];
- if (pos < 3)
- coeff <<= 4;
- else /* TODO Use >> 10 instead of / 1001 */
- coeff = (coeff * qscale) / 1001;
-
- block[ctx->scantable.permutated[pos]] = coeff;
- }
-
- return 0;
-}
-
-static int decode(MimicContext *ctx, int quality, int num_coeffs,
- int is_iframe)
-{
- int ret, y, x, plane, cur_row = 0;
-
- for (plane = 0; plane < 3; plane++) {
- const int is_chroma = !!plane;
- const int qscale = av_clip(10000 - quality, is_chroma ? 1000 : 2000,
- 10000) << 2;
- const int stride = ctx->flipped_ptrs[ctx->cur_index ].linesize[plane];
- const uint8_t *src = ctx->flipped_ptrs[ctx->prev_index].data[plane];
- uint8_t *dst = ctx->flipped_ptrs[ctx->cur_index ].data[plane];
-
- for (y = 0; y < ctx->num_vblocks[plane]; y++) {
- for (x = 0; x < ctx->num_hblocks[plane]; x++) {
- /* Check for a change condition in the current block.
- * - iframes always change.
- * - Luma plane changes on get_bits1 == 0
- * - Chroma planes change on get_bits1 == 1 */
- if (is_iframe || get_bits1(&ctx->gb) == is_chroma) {
- /* Luma planes may use a backreference from the 15 last
- * frames preceding the previous. (get_bits1 == 1)
- * Chroma planes don't use backreferences. */
- if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
- if ((ret = vlc_decode_block(ctx, num_coeffs,
- qscale)) < 0) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding "
- "block.\n");
- return ret;
- }
- ctx->idsp.idct_put(dst, stride, ctx->dct_block);
- } else {
- unsigned int backref = get_bits(&ctx->gb, 4);
- int index = (ctx->cur_index + backref) & 15;
- uint8_t *p = ctx->flipped_ptrs[index].data[0];
-
- if (index != ctx->cur_index && p) {
- ff_thread_await_progress(&ctx->frames[index],
- cur_row, 0);
- p += src -
- ctx->flipped_ptrs[ctx->prev_index].data[plane];
- ctx->hdsp.put_pixels_tab[1][0](dst, p, stride, 8);
- } else {
- av_log(ctx->avctx, AV_LOG_ERROR,
- "No such backreference! Buggy sample.\n");
- }
- }
- } else {
- ff_thread_await_progress(&ctx->frames[ctx->prev_index],
- cur_row, 0);
- ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8);
- }
- src += 8;
- dst += 8;
- }
- src += (stride - ctx->num_hblocks[plane]) << 3;
- dst += (stride - ctx->num_hblocks[plane]) << 3;
-
- ff_thread_report_progress(&ctx->frames[ctx->cur_index],
- cur_row++, 0);
- }
- }
-
- return 0;
-}
-
-/**
- * Flip the buffer upside-down and put it in the YVU order to match the
- * way Mimic encodes frames.
- */
-static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVFrame *src)
-{
- int i;
- dst->data[0] = src->data[0] + ( ctx->avctx->height - 1) * src->linesize[0];
- dst->data[1] = src->data[2] + ((ctx->avctx->height >> 1) - 1) * src->linesize[2];
- dst->data[2] = src->data[1] + ((ctx->avctx->height >> 1) - 1) * src->linesize[1];
- for (i = 0; i < 3; i++)
- dst->linesize[i] = -src->linesize[i];
-}
-
-static int mimic_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame, AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
- MimicContext *ctx = avctx->priv_data;
- GetByteContext gb;
- int is_pframe;
- int width, height;
- int quality, num_coeffs;
- int res;
-
- if (buf_size <= MIMIC_HEADER_SIZE) {
- av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
- return AVERROR_INVALIDDATA;
- }
-
- bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);
- bytestream2_skip(&gb, 2); /* some constant (always 256) */
- quality = bytestream2_get_le16u(&gb);
- width = bytestream2_get_le16u(&gb);
- height = bytestream2_get_le16u(&gb);
- bytestream2_skip(&gb, 4); /* some constant */
- is_pframe = bytestream2_get_le32u(&gb);
- num_coeffs = bytestream2_get_byteu(&gb);
- bytestream2_skip(&gb, 3); /* some constant */
-
- if (!ctx->avctx) {
- int i;
-
- if (!(width == 160 && height == 120) &&
- !(width == 320 && height == 240)) {
- av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
- return AVERROR_INVALIDDATA;
- }
-
- ctx->avctx = avctx;
- avctx->width = width;
- avctx->height = height;
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- for (i = 0; i < 3; i++) {
- ctx->num_vblocks[i] = FF_CEIL_RSHIFT(height, 3 + !!i);
- ctx->num_hblocks[i] = width >> (3 + !!i);
- }
- } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
- avpriv_request_sample(avctx, "Resolution changing");
- return AVERROR_PATCHWELCOME;
- }
-
- if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {
- av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
- return AVERROR_INVALIDDATA;
- }
-
- ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
- ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
- AV_PICTURE_TYPE_I;
- if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],
- AV_GET_BUFFER_FLAG_REF)) < 0)
- return res;
-
- ctx->next_prev_index = ctx->cur_index;
- ctx->next_cur_index = (ctx->cur_index - 1) & 15;
-
- prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
- ctx->frames[ctx->cur_index].f);
-
- ff_thread_finish_setup(avctx);
-
- av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
- if (!ctx->swap_buf)
- return AVERROR(ENOMEM);
-
- ctx->bbdsp.bswap_buf(ctx->swap_buf,
- (const uint32_t *) (buf + MIMIC_HEADER_SIZE),
- swap_buf_size >> 2);
- init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
-
- res = decode(ctx, quality, num_coeffs, !is_pframe);
- ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
- if (res < 0) {
- if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
- ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
- return res;
- }
- }
-
- if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0)
- return res;
- *got_frame = 1;
-
- ctx->prev_index = ctx->next_prev_index;
- ctx->cur_index = ctx->next_cur_index;
-
- /* Only release frames that aren't used for backreferences anymore */
- ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
-
- return buf_size;
-}
-
-static av_cold int mimic_init_thread_copy(AVCodecContext *avctx)
-{
- MimicContext *ctx = avctx->priv_data;
- int i;
-
- 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);
- return AVERROR(ENOMEM);
- }
- }
-
- return 0;
-}
-
-AVCodec ff_mimic_decoder = {
- .name = "mimic",
- .long_name = NULL_IF_CONFIG_SMALL("Mimic"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MIMIC,
- .priv_data_size = sizeof(MimicContext),
- .init = mimic_decode_init,
- .close = mimic_decode_end,
- .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),
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy),
-};
diff --git a/ffmpeg-2-8-11/libavcodec/mjpegdec.c b/ffmpeg-2-8-11/libavcodec/mjpegdec.c
deleted file mode 100644
index d9d18e2..0000000
--- a/ffmpeg-2-8-11/libavcodec/mjpegdec.c
+++ /dev/null
@@ -1,2489 +0,0 @@
-/*
- * MJPEG decoder
- * Copyright (c) 2000, 2001 Fabrice Bellard
- * Copyright (c) 2003 Alex Beregszaszi
- * Copyright (c) 2003-2004 Michael Niedermayer
- *
- * Support for external huffman table, various fixes (AVID workaround),
- * aspecting, new decode_frame mechanism and apple mjpeg-b support
- * by Alex Beregszaszi
- *
- * 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
- * MJPEG decoder.
- */
-
-#include "libavutil/imgutils.h"
-#include "libavutil/avassert.h"
-#include "libavutil/opt.h"
-#include "avcodec.h"
-#include "blockdsp.h"
-#include "copy_block.h"
-#include "idctdsp.h"
-#include "internal.h"
-#include "jpegtables.h"
-#include "mjpeg.h"
-#include "mjpegdec.h"
-#include "jpeglsdec.h"
-#include "put_bits.h"
-#include "tiff.h"
-#include "exif.h"
-#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 void build_basic_mjpeg_vlc(MJpegDecodeContext *s)
-{
- build_vlc(&s->vlcs[0][0], avpriv_mjpeg_bits_dc_luminance,
- avpriv_mjpeg_val_dc, 12, 0, 0);
- build_vlc(&s->vlcs[0][1], avpriv_mjpeg_bits_dc_chrominance,
- avpriv_mjpeg_val_dc, 12, 0, 0);
- build_vlc(&s->vlcs[1][0], avpriv_mjpeg_bits_ac_luminance,
- avpriv_mjpeg_val_ac_luminance, 251, 0, 1);
- build_vlc(&s->vlcs[1][1], avpriv_mjpeg_bits_ac_chrominance,
- avpriv_mjpeg_val_ac_chrominance, 251, 0, 1);
- build_vlc(&s->vlcs[2][0], avpriv_mjpeg_bits_ac_luminance,
- avpriv_mjpeg_val_ac_luminance, 251, 0, 0);
- build_vlc(&s->vlcs[2][1], avpriv_mjpeg_bits_ac_chrominance,
- avpriv_mjpeg_val_ac_chrominance, 251, 0, 0);
-}
-
-static void parse_avid(MJpegDecodeContext *s, uint8_t *buf, int len)
-{
- s->buggy_avid = 1;
- if (len > 14 && buf[12] == 1) /* 1 - NTSC */
- s->interlace_polarity = 1;
- if (len > 14 && buf[12] == 2) /* 2 - PAL */
- s->interlace_polarity = 0;
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_INFO, "AVID: len:%d %d\n", len, len > 14 ? buf[12] : -1);
-}
-
-static void init_idct(AVCodecContext *avctx)
-{
- MJpegDecodeContext *s = avctx->priv_data;
-
- ff_idctdsp_init(&s->idsp, avctx);
- ff_init_scantable(s->idsp.idct_permutation, &s->scantable,
- ff_zigzag_direct);
-}
-
-av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx)
-{
- MJpegDecodeContext *s = avctx->priv_data;
-
- if (!s->picture_ptr) {
- s->picture = av_frame_alloc();
- if (!s->picture)
- return AVERROR(ENOMEM);
- s->picture_ptr = s->picture;
- }
-
- s->avctx = avctx;
- ff_blockdsp_init(&s->bdsp, avctx);
- ff_hpeldsp_init(&s->hdsp, avctx->flags);
- init_idct(avctx);
- s->buffer_size = 0;
- s->buffer = NULL;
- s->start_code = -1;
- s->first_picture = 1;
- s->got_picture = 0;
- s->org_height = avctx->coded_height;
- avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
- avctx->colorspace = AVCOL_SPC_BT470BG;
-
- build_basic_mjpeg_vlc(s);
-
- if (s->extern_huff) {
- av_log(avctx, AV_LOG_INFO, "using external huffman table\n");
- init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size * 8);
- if (ff_mjpeg_decode_dht(s)) {
- av_log(avctx, AV_LOG_ERROR,
- "error using external huffman table, switching back to internal\n");
- build_basic_mjpeg_vlc(s);
- }
- }
- if (avctx->field_order == AV_FIELD_BB) { /* quicktime icefloe 019 */
- s->interlace_polarity = 1; /* bottom field first */
- av_log(avctx, AV_LOG_DEBUG, "bottom field first\n");
- } else if (avctx->field_order == AV_FIELD_UNKNOWN) {
- if (avctx->codec_tag == AV_RL32("MJPG"))
- s->interlace_polarity = 1;
- }
-
- if ( avctx->extradata_size > 8
- && AV_RL32(avctx->extradata) == 0x2C
- && AV_RL32(avctx->extradata+4) == 0x18) {
- parse_avid(s, avctx->extradata, avctx->extradata_size);
- }
-
- if (avctx->codec->id == AV_CODEC_ID_AMV)
- s->flipped = 1;
-
- return 0;
-}
-
-
-/* quantize tables */
-int ff_mjpeg_decode_dqt(MJpegDecodeContext *s)
-{
- int len, index, i, j;
-
- len = get_bits(&s->gb, 16) - 2;
-
- if (8*len > get_bits_left(&s->gb)) {
- av_log(s->avctx, AV_LOG_ERROR, "dqt: len %d is too large\n", len);
- return AVERROR_INVALIDDATA;
- }
-
- while (len >= 65) {
- int pr = get_bits(&s->gb, 4);
- if (pr > 1) {
- av_log(s->avctx, AV_LOG_ERROR, "dqt: invalid precision\n");
- return AVERROR_INVALIDDATA;
- }
- index = get_bits(&s->gb, 4);
- if (index >= 4)
- return -1;
- av_log(s->avctx, AV_LOG_DEBUG, "index=%d\n", index);
- /* read quant table */
- for (i = 0; i < 64; i++) {
- j = s->scantable.permutated[i];
- s->quant_matrixes[index][j] = get_bits(&s->gb, pr ? 16 : 8);
- }
-
- // XXX FIXME finetune, and perhaps add dc too
- s->qscale[index] = FFMAX(s->quant_matrixes[index][s->scantable.permutated[1]],
- s->quant_matrixes[index][s->scantable.permutated[8]]) >> 1;
- av_log(s->avctx, AV_LOG_DEBUG, "qscale[%d]: %d\n",
- index, s->qscale[index]);
- len -= 1 + 64 * (1+pr);
- }
- return 0;
-}
-
-/* decode huffman tables and build VLC decoders */
-int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
-{
- int len, index, i, class, n, v, code_max;
- uint8_t bits_table[17];
- uint8_t val_table[256];
- int ret = 0;
-
- len = get_bits(&s->gb, 16) - 2;
-
- if (8*len > get_bits_left(&s->gb)) {
- av_log(s->avctx, AV_LOG_ERROR, "dht: len %d is too large\n", len);
- return AVERROR_INVALIDDATA;
- }
-
- while (len > 0) {
- if (len < 17)
- return AVERROR_INVALIDDATA;
- class = get_bits(&s->gb, 4);
- if (class >= 2)
- return AVERROR_INVALIDDATA;
- index = get_bits(&s->gb, 4);
- if (index >= 4)
- return AVERROR_INVALIDDATA;
- n = 0;
- for (i = 1; i <= 16; i++) {
- bits_table[i] = get_bits(&s->gb, 8);
- n += bits_table[i];
- }
- len -= 17;
- 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;
-
- /* 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)
- 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)
- return ret;
- }
- }
- return 0;
-}
-
-int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
-{
- int len, nb_components, i, width, height, bits, ret;
- unsigned pix_fmt_id;
- int h_count[MAX_COMPONENTS] = { 0 };
- int v_count[MAX_COMPONENTS] = { 0 };
-
- s->cur_scan = 0;
- memset(s->upscale_h, 0, sizeof(s->upscale_h));
- memset(s->upscale_v, 0, sizeof(s->upscale_v));
-
- /* XXX: verify len field validity */
- len = get_bits(&s->gb, 16);
- bits = get_bits(&s->gb, 8);
-
- if (bits > 16 || bits < 1) {
- av_log(s->avctx, AV_LOG_ERROR, "bits %d is invalid\n", bits);
- return AVERROR_INVALIDDATA;
- }
-
- if (s->avctx->bits_per_raw_sample != bits) {
- av_log(s->avctx, AV_LOG_INFO, "Changeing bps to %d\n", bits);
- s->avctx->bits_per_raw_sample = bits;
- init_idct(s->avctx);
- }
- if (s->pegasus_rct)
- bits = 9;
- if (bits == 9 && !s->pegasus_rct)
- s->rct = 1; // FIXME ugly
-
- if(s->lossless && s->avctx->lowres){
- av_log(s->avctx, AV_LOG_ERROR, "lowres is not possible with lossless jpeg\n");
- return -1;
- }
-
- height = get_bits(&s->gb, 16);
- width = get_bits(&s->gb, 16);
-
- // HACK for odd_height.mov
- if (s->interlaced && s->width == width && s->height == height + 1)
- height= s->height;
-
- av_log(s->avctx, AV_LOG_DEBUG, "sof0: picture: %dx%d\n", width, height);
- if (av_image_check_size(width, height, 0, s->avctx))
- return AVERROR_INVALIDDATA;
-
- nb_components = get_bits(&s->gb, 8);
- if (nb_components <= 0 ||
- nb_components > MAX_COMPONENTS)
- return -1;
- if (s->interlaced && (s->bottom_field == !s->interlace_polarity)) {
- if (nb_components != s->nb_components) {
- av_log(s->avctx, AV_LOG_ERROR,
- "nb_components changing in interlaced picture\n");
- return AVERROR_INVALIDDATA;
- }
- }
- if (s->ls && !(bits <= 8 || nb_components == 1)) {
- avpriv_report_missing_feature(s->avctx,
- "JPEG-LS that is not <= 8 "
- "bits/component or 16-bit gray");
- return AVERROR_PATCHWELCOME;
- }
- s->nb_components = nb_components;
- s->h_max = 1;
- s->v_max = 1;
- for (i = 0; i < nb_components; i++) {
- /* component id */
- s->component_id[i] = get_bits(&s->gb, 8) - 1;
- h_count[i] = get_bits(&s->gb, 4);
- v_count[i] = get_bits(&s->gb, 4);
- /* compute hmax and vmax (only used in interleaved case) */
- if (h_count[i] > s->h_max)
- s->h_max = h_count[i];
- if (v_count[i] > s->v_max)
- s->v_max = v_count[i];
- s->quant_index[i] = get_bits(&s->gb, 8);
- if (s->quant_index[i] >= 4) {
- av_log(s->avctx, AV_LOG_ERROR, "quant_index is invalid\n");
- return AVERROR_INVALIDDATA;
- }
- if (!h_count[i] || !v_count[i]) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Invalid sampling factor in component %d %d:%d\n",
- i, h_count[i], v_count[i]);
- return AVERROR_INVALIDDATA;
- }
-
- av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n",
- i, h_count[i], v_count[i],
- s->component_id[i], s->quant_index[i]);
- }
- if ( nb_components == 4
- && s->component_id[0] == 'C' - 1
- && s->component_id[1] == 'M' - 1
- && s->component_id[2] == 'Y' - 1
- && s->component_id[3] == 'K' - 1)
- s->adobe_transform = 0;
-
- if (s->ls && (s->h_max > 1 || s->v_max > 1)) {
- avpriv_report_missing_feature(s->avctx, "Subsampling in JPEG-LS");
- return AVERROR_PATCHWELCOME;
- }
-
-
- /* if different size, realloc/alloc picture */
- if (width != s->width || height != s->height || bits != s->bits ||
- memcmp(s->h_count, h_count, sizeof(h_count)) ||
- memcmp(s->v_count, v_count, sizeof(v_count))) {
-
- s->width = width;
- s->height = height;
- s->bits = bits;
- memcpy(s->h_count, h_count, sizeof(h_count));
- memcpy(s->v_count, v_count, sizeof(v_count));
- s->interlaced = 0;
- s->got_picture = 0;
-
- /* 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->interlaced = 1;
- s->bottom_field = s->interlace_polarity;
- s->picture_ptr->interlaced_frame = 1;
- s->picture_ptr->top_field_first = !s->interlace_polarity;
- height *= 2;
- }
-
- ret = ff_set_dimensions(s->avctx, width, height);
- if (ret < 0)
- return ret;
-
- s->first_picture = 0;
- }
-
- if (s->got_picture && s->interlaced && (s->bottom_field == !s->interlace_polarity)) {
- if (s->progressive) {
- avpriv_request_sample(s->avctx, "progressively coded interlaced picture");
- return AVERROR_INVALIDDATA;
- }
- } else{
- if (s->v_max == 1 && s->h_max == 1 && s->lossless==1 && (nb_components==3 || nb_components==4))
- s->rgb = 1;
- else if (!s->lossless)
- s->rgb = 0;
- /* XXX: not complete test ! */
- pix_fmt_id = ((unsigned)s->h_count[0] << 28) | (s->v_count[0] << 24) |
- (s->h_count[1] << 20) | (s->v_count[1] << 16) |
- (s->h_count[2] << 12) | (s->v_count[2] << 8) |
- (s->h_count[3] << 4) | s->v_count[3];
- av_log(s->avctx, AV_LOG_DEBUG, "pix fmt id %x\n", pix_fmt_id);
- /* NOTE we do not allocate pictures large enough for the possible
- * padding of h/v_count being 4 */
- if (!(pix_fmt_id & 0xD0D0D0D0))
- pix_fmt_id -= (pix_fmt_id & 0xF0F0F0F0) >> 1;
- if (!(pix_fmt_id & 0x0D0D0D0D))
- pix_fmt_id -= (pix_fmt_id & 0x0F0F0F0F) >> 1;
-
- for (i = 0; i < 8; i++) {
- int j = 6 + (i&1) - (i&6);
- int is = (pix_fmt_id >> (4*i)) & 0xF;
- int js = (pix_fmt_id >> (4*j)) & 0xF;
-
- if (is == 1 && js != 2 && (i < 2 || i > 5))
- js = (pix_fmt_id >> ( 8 + 4*(i&1))) & 0xF;
- if (is == 1 && js != 2 && (i < 2 || i > 5))
- js = (pix_fmt_id >> (16 + 4*(i&1))) & 0xF;
-
- if (is == 1 && js == 2) {
- if (i & 1) s->upscale_h[j/2] = 1;
- else s->upscale_v[j/2] = 1;
- }
- }
-
- switch (pix_fmt_id) {
- case 0x11111100:
- if (s->rgb)
- s->avctx->pix_fmt = s->bits <= 9 ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_BGR48;
- else {
- if (s->component_id[0] == 'Q' && s->component_id[1] == 'F' && s->component_id[2] == 'A') {
- s->avctx->pix_fmt = s->bits <= 8 ? AV_PIX_FMT_GBRP : AV_PIX_FMT_GBRP16;
- } else {
- if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
- else s->avctx->pix_fmt = AV_PIX_FMT_YUV444P16;
- s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- }
- }
- av_assert0(s->nb_components == 3);
- break;
- case 0x11111111:
- if (s->rgb)
- s->avctx->pix_fmt = s->bits <= 9 ? AV_PIX_FMT_ABGR : AV_PIX_FMT_RGBA64;
- else {
- if (s->adobe_transform == 0 && s->bits <= 8) {
- s->avctx->pix_fmt = AV_PIX_FMT_GBRAP;
- } else {
- s->avctx->pix_fmt = s->bits <= 8 ? AV_PIX_FMT_YUVA444P : AV_PIX_FMT_YUVA444P16;
- s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- }
- }
- av_assert0(s->nb_components == 4);
- break;
- case 0x22111122:
- case 0x22111111:
- if (s->adobe_transform == 0 && s->bits <= 8) {
- s->avctx->pix_fmt = AV_PIX_FMT_GBRAP;
- s->upscale_v[1] = s->upscale_v[2] = 1;
- s->upscale_h[1] = s->upscale_h[2] = 1;
- } else if (s->adobe_transform == 2 && s->bits <= 8) {
- s->avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
- s->upscale_v[1] = s->upscale_v[2] = 1;
- s->upscale_h[1] = s->upscale_h[2] = 1;
- s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- } else {
- if (s->bits <= 8) s->avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
- else s->avctx->pix_fmt = AV_PIX_FMT_YUVA420P16;
- s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- }
- av_assert0(s->nb_components == 4);
- break;
- case 0x12121100:
- case 0x22122100:
- case 0x21211100:
- case 0x22211200:
- if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
- else
- goto unk_pixfmt;
- s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- break;
- case 0x22221100:
- case 0x22112200:
- case 0x11222200:
- if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
- else
- goto unk_pixfmt;
- s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- break;
- case 0x11000000:
- case 0x13000000:
- case 0x14000000:
- case 0x31000000:
- case 0x33000000:
- case 0x34000000:
- case 0x41000000:
- case 0x43000000:
- case 0x44000000:
- if(s->bits <= 8)
- s->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
- else
- s->avctx->pix_fmt = AV_PIX_FMT_GRAY16;
- break;
- case 0x12111100:
- case 0x14121200:
- case 0x14111100:
- case 0x22211100:
- case 0x22112100:
- if (s->component_id[0] == 'Q' && s->component_id[1] == 'F' && s->component_id[2] == 'A') {
- if (s->bits <= 8) s->avctx->pix_fmt = AV_PIX_FMT_GBRP;
- else
- goto unk_pixfmt;
- s->upscale_v[0] = s->upscale_v[1] = 1;
- } else {
- if (pix_fmt_id == 0x14111100)
- s->upscale_v[1] = s->upscale_v[2] = 1;
- if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV440P : AV_PIX_FMT_YUVJ440P;
- else
- goto unk_pixfmt;
- s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- }
- break;
- case 0x21111100:
- if (s->component_id[0] == 'Q' && s->component_id[1] == 'F' && s->component_id[2] == 'A') {
- if (s->bits <= 8) s->avctx->pix_fmt = AV_PIX_FMT_GBRP;
- else
- goto unk_pixfmt;
- s->upscale_h[0] = s->upscale_h[1] = 1;
- } else {
- if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P;
- else s->avctx->pix_fmt = AV_PIX_FMT_YUV422P16;
- s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- }
- break;
- case 0x31111100:
- if (s->bits > 8)
- goto unk_pixfmt;
- s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
- s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- s->upscale_h[1] = s->upscale_h[2] = 2;
- break;
- case 0x22121100:
- case 0x22111200:
- if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P;
- else
- goto unk_pixfmt;
- s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- break;
- case 0x22111100:
- case 0x42111100:
- case 0x24111100:
- if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUVJ420P;
- else s->avctx->pix_fmt = AV_PIX_FMT_YUV420P16;
- s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- if (pix_fmt_id == 0x42111100) {
- if (s->bits > 8)
- goto unk_pixfmt;
- s->upscale_h[1] = s->upscale_h[2] = 1;
- } else if (pix_fmt_id == 0x24111100) {
- if (s->bits > 8)
- goto unk_pixfmt;
- s->upscale_v[1] = s->upscale_v[2] = 1;
- }
- break;
- case 0x41111100:
- if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV411P : AV_PIX_FMT_YUVJ411P;
- else
- goto unk_pixfmt;
- s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
- break;
- default:
-unk_pixfmt:
- av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x bits:%d\n", pix_fmt_id, s->bits);
- memset(s->upscale_h, 0, sizeof(s->upscale_h));
- memset(s->upscale_v, 0, sizeof(s->upscale_v));
- return AVERROR_PATCHWELCOME;
- }
- if ((AV_RB32(s->upscale_h) || AV_RB32(s->upscale_v)) && s->avctx->lowres) {
- av_log(s->avctx, AV_LOG_ERROR, "lowres not supported for weird subsampling\n");
- return AVERROR_PATCHWELCOME;
- }
- if (s->ls) {
- memset(s->upscale_h, 0, sizeof(s->upscale_h));
- memset(s->upscale_v, 0, sizeof(s->upscale_v));
- if (s->nb_components == 3) {
- s->avctx->pix_fmt = AV_PIX_FMT_RGB24;
- } else if (s->nb_components != 1) {
- av_log(s->avctx, AV_LOG_ERROR, "Unsupported number of components %d\n", s->nb_components);
- return AVERROR_PATCHWELCOME;
- } else if (s->palette_index && s->bits <= 8)
- s->avctx->pix_fmt = AV_PIX_FMT_PAL8;
- else if (s->bits <= 8)
- s->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
- else
- s->avctx->pix_fmt = AV_PIX_FMT_GRAY16;
- }
-
- s->pix_desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
- if (!s->pix_desc) {
- av_log(s->avctx, AV_LOG_ERROR, "Could not get a pixel format descriptor.\n");
- return AVERROR_BUG;
- }
-
- av_frame_unref(s->picture_ptr);
- if (ff_get_buffer(s->avctx, s->picture_ptr, AV_GET_BUFFER_FLAG_REF) < 0)
- return -1;
- s->picture_ptr->pict_type = AV_PICTURE_TYPE_I;
- s->picture_ptr->key_frame = 1;
- s->got_picture = 1;
-
- for (i = 0; i < 4; i++)
- s->linesize[i] = s->picture_ptr->linesize[i] << s->interlaced;
-
- ff_dlog(s->avctx, "%d %d %d %d %d %d\n",
- s->width, s->height, s->linesize[0], s->linesize[1],
- s->interlaced, s->avctx->height);
-
- if (len != (8 + (3 * nb_components)))
- av_log(s->avctx, AV_LOG_DEBUG, "decode_sof0: error, len(%d) mismatch\n", len);
- }
-
- if ((s->rgb && !s->lossless && !s->ls) ||
- (!s->rgb && s->ls && s->nb_components > 1)) {
- av_log(s->avctx, AV_LOG_ERROR, "Unsupported coding and pixel format combination\n");
- return AVERROR_PATCHWELCOME;
- }
-
- /* totally blank picture as progressive JPEG will only add details to it */
- if (s->progressive) {
- int bw = (width + s->h_max * 8 - 1) / (s->h_max * 8);
- int bh = (height + s->v_max * 8 - 1) / (s->v_max * 8);
- for (i = 0; i < s->nb_components; i++) {
- int size = bw * bh * s->h_count[i] * s->v_count[i];
- av_freep(&s->blocks[i]);
- av_freep(&s->last_nnz[i]);
- s->blocks[i] = av_mallocz_array(size, sizeof(**s->blocks));
- s->last_nnz[i] = av_mallocz_array(size, sizeof(**s->last_nnz));
- if (!s->blocks[i] || !s->last_nnz[i])
- return AVERROR(ENOMEM);
- s->block_stride[i] = bw * s->h_count[i];
- }
- memset(s->coefs_finished, 0, sizeof(s->coefs_finished));
- }
- return 0;
-}
-
-static inline int mjpeg_decode_dc(MJpegDecodeContext *s, int dc_index)
-{
- int code;
- code = get_vlc2(&s->gb, s->vlcs[0][dc_index].table, 9, 2);
- if (code < 0 || code > 16) {
- av_log(s->avctx, AV_LOG_WARNING,
- "mjpeg_decode_dc: bad vlc: %d:%d (%p)\n",
- 0, dc_index, &s->vlcs[0][dc_index]);
- return 0xfffff;
- }
-
- if (code)
- return get_xbits(&s->gb, code);
- else
- return 0;
-}
-
-/* decode block and dequantize */
-static int decode_block(MJpegDecodeContext *s, int16_t *block, int component,
- int dc_index, int ac_index, int16_t *quant_matrix)
-{
- int code, i, j, level, val;
-
- /* DC coef */
- val = mjpeg_decode_dc(s, dc_index);
- if (val == 0xfffff) {
- av_log(s->avctx, AV_LOG_ERROR, "error dc\n");
- return AVERROR_INVALIDDATA;
- }
- val = val * quant_matrix[0] + s->last_dc[component];
- val = FFMIN(val, 32767);
- s->last_dc[component] = val;
- block[0] = val;
- /* AC coefs */
- i = 0;
- {OPEN_READER(re, &s->gb);
- do {
- UPDATE_CACHE(re, &s->gb);
- GET_VLC(code, re, &s->gb, s->vlcs[1][ac_index].table, 9, 2);
-
- i += ((unsigned)code) >> 4;
- code &= 0xf;
- if (code) {
- if (code > MIN_CACHE_BITS - 16)
- UPDATE_CACHE(re, &s->gb);
-
- {
- int cache = GET_CACHE(re, &s->gb);
- int sign = (~cache) >> 31;
- level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign;
- }
-
- LAST_SKIP_BITS(re, &s->gb, code);
-
- if (i > 63) {
- av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i);
- return AVERROR_INVALIDDATA;
- }
- j = s->scantable.permutated[i];
- block[j] = level * quant_matrix[j];
- }
- } while (i < 63);
- CLOSE_READER(re, &s->gb);}
-
- return 0;
-}
-
-static int decode_dc_progressive(MJpegDecodeContext *s, int16_t *block,
- int component, int dc_index,
- int16_t *quant_matrix, int Al)
-{
- int val;
- s->bdsp.clear_block(block);
- val = mjpeg_decode_dc(s, dc_index);
- if (val == 0xfffff) {
- av_log(s->avctx, AV_LOG_ERROR, "error dc\n");
- return AVERROR_INVALIDDATA;
- }
- val = (val * (quant_matrix[0] << Al)) + s->last_dc[component];
- s->last_dc[component] = val;
- block[0] = val;
- return 0;
-}
-
-/* decode block and dequantize - progressive JPEG version */
-static int decode_block_progressive(MJpegDecodeContext *s, int16_t *block,
- uint8_t *last_nnz, int ac_index,
- int16_t *quant_matrix,
- int ss, int se, int Al, int *EOBRUN)
-{
- int code, i, j, level, val, run;
-
- if (*EOBRUN) {
- (*EOBRUN)--;
- return 0;
- }
-
- {
- OPEN_READER(re, &s->gb);
- for (i = ss; ; i++) {
- UPDATE_CACHE(re, &s->gb);
- GET_VLC(code, re, &s->gb, s->vlcs[2][ac_index].table, 9, 2);
-
- run = ((unsigned) code) >> 4;
- code &= 0xF;
- if (code) {
- i += run;
- if (code > MIN_CACHE_BITS - 16)
- UPDATE_CACHE(re, &s->gb);
-
- {
- int cache = GET_CACHE(re, &s->gb);
- int sign = (~cache) >> 31;
- level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign;
- }
-
- LAST_SKIP_BITS(re, &s->gb, code);
-
- if (i >= se) {
- if (i == se) {
- j = s->scantable.permutated[se];
- block[j] = level * (quant_matrix[j] << Al);
- break;
- }
- av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i);
- return AVERROR_INVALIDDATA;
- }
- j = s->scantable.permutated[i];
- block[j] = level * (quant_matrix[j] << Al);
- } else {
- if (run == 0xF) {// ZRL - skip 15 coefficients
- i += 15;
- if (i >= se) {
- av_log(s->avctx, AV_LOG_ERROR, "ZRL overflow: %d\n", i);
- return AVERROR_INVALIDDATA;
- }
- } else {
- val = (1 << run);
- if (run) {
- UPDATE_CACHE(re, &s->gb);
- val += NEG_USR32(GET_CACHE(re, &s->gb), run);
- LAST_SKIP_BITS(re, &s->gb, run);
- }
- *EOBRUN = val - 1;
- break;
- }
- }
- }
- CLOSE_READER(re, &s->gb);
- }
-
- if (i > *last_nnz)
- *last_nnz = i;
-
- return 0;
-}
-
-#define REFINE_BIT(j) { \
- UPDATE_CACHE(re, &s->gb); \
- sign = block[j] >> 15; \
- block[j] += SHOW_UBITS(re, &s->gb, 1) * \
- ((quant_matrix[j] ^ sign) - sign) << Al; \
- LAST_SKIP_BITS(re, &s->gb, 1); \
-}
-
-#define ZERO_RUN \
-for (; ; i++) { \
- if (i > last) { \
- i += run; \
- if (i > se) { \
- av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i); \
- return -1; \
- } \
- break; \
- } \
- j = s->scantable.permutated[i]; \
- if (block[j]) \
- REFINE_BIT(j) \
- else if (run-- == 0) \
- break; \
-}
-
-/* decode block and dequantize - progressive JPEG refinement pass */
-static int decode_block_refinement(MJpegDecodeContext *s, int16_t *block,
- uint8_t *last_nnz,
- int ac_index, int16_t *quant_matrix,
- int ss, int se, int Al, int *EOBRUN)
-{
- int code, i = ss, j, sign, val, run;
- int last = FFMIN(se, *last_nnz);
-
- OPEN_READER(re, &s->gb);
- if (*EOBRUN) {
- (*EOBRUN)--;
- } else {
- for (; ; i++) {
- UPDATE_CACHE(re, &s->gb);
- GET_VLC(code, re, &s->gb, s->vlcs[2][ac_index].table, 9, 2);
-
- if (code & 0xF) {
- run = ((unsigned) code) >> 4;
- UPDATE_CACHE(re, &s->gb);
- val = SHOW_UBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
- ZERO_RUN;
- j = s->scantable.permutated[i];
- val--;
- block[j] = ((quant_matrix[j] << Al) ^ val) - val;
- if (i == se) {
- if (i > *last_nnz)
- *last_nnz = i;
- CLOSE_READER(re, &s->gb);
- return 0;
- }
- } else {
- run = ((unsigned) code) >> 4;
- if (run == 0xF) {
- ZERO_RUN;
- } else {
- val = run;
- run = (1 << run);
- if (val) {
- UPDATE_CACHE(re, &s->gb);
- run += SHOW_UBITS(re, &s->gb, val);
- LAST_SKIP_BITS(re, &s->gb, val);
- }
- *EOBRUN = run - 1;
- break;
- }
- }
- }
-
- if (i > *last_nnz)
- *last_nnz = i;
- }
-
- for (; i <= last; i++) {
- j = s->scantable.permutated[i];
- if (block[j])
- REFINE_BIT(j)
- }
- CLOSE_READER(re, &s->gb);
-
- return 0;
-}
-#undef REFINE_BIT
-#undef ZERO_RUN
-
-static int handle_rstn(MJpegDecodeContext *s, int nb_components)
-{
- int i;
- int reset = 0;
-
- if (s->restart_interval) {
- s->restart_count--;
- if(s->restart_count == 0 && s->avctx->codec_id == AV_CODEC_ID_THP){
- align_get_bits(&s->gb);
- for (i = 0; i < nb_components; i++) /* reset dc */
- s->last_dc[i] = (4 << s->bits);
- }
-
- i = 8 + ((-get_bits_count(&s->gb)) & 7);
- /* skip RSTn */
- if (s->restart_count == 0) {
- if( show_bits(&s->gb, i) == (1 << i) - 1
- || show_bits(&s->gb, i) == 0xFF) {
- int pos = get_bits_count(&s->gb);
- align_get_bits(&s->gb);
- while (get_bits_left(&s->gb) >= 8 && show_bits(&s->gb, 8) == 0xFF)
- skip_bits(&s->gb, 8);
- if (get_bits_left(&s->gb) >= 8 && (get_bits(&s->gb, 8) & 0xF8) == 0xD0) {
- for (i = 0; i < nb_components; i++) /* reset dc */
- s->last_dc[i] = (4 << s->bits);
- reset = 1;
- } else
- skip_bits_long(&s->gb, pos - get_bits_count(&s->gb));
- }
- }
- }
- return reset;
-}
-
-static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int predictor, int point_transform)
-{
- int i, mb_x, mb_y;
- uint16_t (*buffer)[4];
- int left[4], top[4], topleft[4];
- const int linesize = s->linesize[0];
- const int mask = ((1 << s->bits) - 1) << point_transform;
- int resync_mb_y = 0;
- int resync_mb_x = 0;
-
- if (s->nb_components != 3 && s->nb_components != 4)
- return AVERROR_INVALIDDATA;
- if (s->v_max != 1 || s->h_max != 1 || !s->lossless)
- return AVERROR_INVALIDDATA;
-
-
- s->restart_count = s->restart_interval;
-
- av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size,
- (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0]));
- buffer = s->ljpeg_buffer;
-
- for (i = 0; i < 4; i++)
- buffer[0][i] = 1 << (s->bits - 1);
-
- for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
- uint8_t *ptr = s->picture_ptr->data[0] + (linesize * mb_y);
-
- if (s->interlaced && s->bottom_field)
- ptr += linesize >> 1;
-
- for (i = 0; i < 4; i++)
- top[i] = left[i] = topleft[i] = buffer[0][i];
-
- for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
- int modified_predictor = predictor;
-
- if (s->restart_interval && !s->restart_count){
- s->restart_count = s->restart_interval;
- resync_mb_x = mb_x;
- resync_mb_y = mb_y;
- for(i=0; i<4; i++)
- top[i] = left[i]= topleft[i]= 1 << (s->bits - 1);
- }
- if (mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x || !mb_x)
- modified_predictor = 1;
-
- for (i=0;i<nb_components;i++) {
- int pred, dc;
-
- topleft[i] = top[i];
- top[i] = buffer[mb_x][i];
-
- PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
-
- dc = mjpeg_decode_dc(s, s->dc_index[i]);
- if(dc == 0xFFFFF)
- return -1;
-
- left[i] = buffer[mb_x][i] =
- mask & (pred + (dc * (1 << point_transform)));
- }
-
- if (s->restart_interval && !--s->restart_count) {
- align_get_bits(&s->gb);
- skip_bits(&s->gb, 16); /* skip RSTn */
- }
- }
- if (s->rct && s->nb_components == 4) {
- for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
- ptr[4*mb_x + 2] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200) >> 2);
- ptr[4*mb_x + 1] = buffer[mb_x][1] + ptr[4*mb_x + 2];
- ptr[4*mb_x + 3] = buffer[mb_x][2] + ptr[4*mb_x + 2];
- ptr[4*mb_x + 0] = buffer[mb_x][3];
- }
- } else if (s->nb_components == 4) {
- for(i=0; i<nb_components; i++) {
- int c= s->comp_index[i];
- if (s->bits <= 8) {
- for(mb_x = 0; mb_x < s->mb_width; mb_x++) {
- ptr[4*mb_x+3-c] = buffer[mb_x][i];
- }
- } else if(s->bits == 9) {
- return AVERROR_PATCHWELCOME;
- } else {
- for(mb_x = 0; mb_x < s->mb_width; mb_x++) {
- ((uint16_t*)ptr)[4*mb_x+c] = buffer[mb_x][i];
- }
- }
- }
- } else if (s->rct) {
- for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
- ptr[3*mb_x + 1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200) >> 2);
- ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1];
- ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*mb_x + 1];
- }
- } else if (s->pegasus_rct) {
- for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
- ptr[3*mb_x + 1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2]) >> 2);
- ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1];
- ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*mb_x + 1];
- }
- } else {
- for(i=0; i<nb_components; i++) {
- int c= s->comp_index[i];
- if (s->bits <= 8) {
- for(mb_x = 0; mb_x < s->mb_width; mb_x++) {
- ptr[3*mb_x+2-c] = buffer[mb_x][i];
- }
- } else if(s->bits == 9) {
- return AVERROR_PATCHWELCOME;
- } else {
- for(mb_x = 0; mb_x < s->mb_width; mb_x++) {
- ((uint16_t*)ptr)[3*mb_x+2-c] = buffer[mb_x][i];
- }
- }
- }
- }
- }
- return 0;
-}
-
-static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor,
- int point_transform, int nb_components)
-{
- int i, mb_x, mb_y, mask;
- int bits= (s->bits+7)&~7;
- int resync_mb_y = 0;
- int resync_mb_x = 0;
-
- point_transform += bits - s->bits;
- mask = ((1 << s->bits) - 1) << point_transform;
-
- av_assert0(nb_components>=1 && nb_components<=4);
-
- for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
- for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
- if (get_bits_left(&s->gb) < 1) {
- av_log(s->avctx, AV_LOG_ERROR, "bitstream end in yuv_scan\n");
- return AVERROR_INVALIDDATA;
- }
- if (s->restart_interval && !s->restart_count){
- s->restart_count = s->restart_interval;
- resync_mb_x = mb_x;
- resync_mb_y = mb_y;
- }
-
- if(!mb_x || mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x || s->interlaced){
- int toprow = mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x;
- int leftcol = !mb_x || mb_y == resync_mb_y && mb_x == resync_mb_x;
- for (i = 0; i < nb_components; i++) {
- uint8_t *ptr;
- uint16_t *ptr16;
- int n, h, v, x, y, c, j, linesize;
- n = s->nb_blocks[i];
- c = s->comp_index[i];
- h = s->h_scount[i];
- v = s->v_scount[i];
- x = 0;
- y = 0;
- linesize= s->linesize[c];
-
- if(bits>8) linesize /= 2;
-
- for(j=0; j<n; j++) {
- int pred, dc;
-
- dc = mjpeg_decode_dc(s, s->dc_index[i]);
- if(dc == 0xFFFFF)
- return -1;
- if ( h * mb_x + x >= s->width
- || v * mb_y + y >= s->height) {
- // Nothing to do
- } else if (bits<=8) {
- ptr = s->picture_ptr->data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
- if(y==0 && toprow){
- if(x==0 && leftcol){
- pred= 1 << (bits - 1);
- }else{
- pred= ptr[-1];
- }
- }else{
- if(x==0 && leftcol){
- pred= ptr[-linesize];
- }else{
- PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
- }
- }
-
- if (s->interlaced && s->bottom_field)
- ptr += linesize >> 1;
- pred &= mask;
- *ptr= pred + (dc << point_transform);
- }else{
- ptr16 = (uint16_t*)(s->picture_ptr->data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap
- if(y==0 && toprow){
- if(x==0 && leftcol){
- pred= 1 << (bits - 1);
- }else{
- pred= ptr16[-1];
- }
- }else{
- if(x==0 && leftcol){
- pred= ptr16[-linesize];
- }else{
- PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor);
- }
- }
-
- if (s->interlaced && s->bottom_field)
- ptr16 += linesize >> 1;
- pred &= mask;
- *ptr16= pred + (dc << point_transform);
- }
- if (++x == h) {
- x = 0;
- y++;
- }
- }
- }
- } else {
- for (i = 0; i < nb_components; i++) {
- uint8_t *ptr;
- uint16_t *ptr16;
- int n, h, v, x, y, c, j, linesize, dc;
- n = s->nb_blocks[i];
- c = s->comp_index[i];
- h = s->h_scount[i];
- v = s->v_scount[i];
- x = 0;
- y = 0;
- linesize = s->linesize[c];
-
- if(bits>8) linesize /= 2;
-
- for (j = 0; j < n; j++) {
- int pred;
-
- dc = mjpeg_decode_dc(s, s->dc_index[i]);
- if(dc == 0xFFFFF)
- return -1;
- if ( h * mb_x + x >= s->width
- || v * mb_y + y >= s->height) {
- // Nothing to do
- } else if (bits<=8) {
- ptr = s->picture_ptr->data[c] +
- (linesize * (v * mb_y + y)) +
- (h * mb_x + x); //FIXME optimize this crap
- PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
-
- pred &= mask;
- *ptr = pred + (dc << point_transform);
- }else{
- ptr16 = (uint16_t*)(s->picture_ptr->data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap
- PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor);
-
- pred &= mask;
- *ptr16= pred + (dc << point_transform);
- }
-
- if (++x == h) {
- x = 0;
- y++;
- }
- }
- }
- }
- if (s->restart_interval && !--s->restart_count) {
- align_get_bits(&s->gb);
- skip_bits(&s->gb, 16); /* skip RSTn */
- }
- }
- }
- return 0;
-}
-
-static av_always_inline void mjpeg_copy_block(MJpegDecodeContext *s,
- uint8_t *dst, const uint8_t *src,
- int linesize, int lowres)
-{
- switch (lowres) {
- case 0: s->hdsp.put_pixels_tab[1][0](dst, src, linesize, 8);
- break;
- case 1: copy_block4(dst, src, linesize, linesize, 4);
- break;
- case 2: copy_block2(dst, src, linesize, linesize, 2);
- break;
- case 3: *dst = *src;
- break;
- }
-}
-
-static void shift_output(MJpegDecodeContext *s, uint8_t *ptr, int linesize)
-{
- int block_x, block_y;
- int size = 8 >> s->avctx->lowres;
- if (s->bits > 8) {
- for (block_y=0; block_y<size; block_y++)
- for (block_x=0; block_x<size; block_x++)
- *(uint16_t*)(ptr + 2*block_x + block_y*linesize) <<= 16 - s->bits;
- } else {
- for (block_y=0; block_y<size; block_y++)
- for (block_x=0; block_x<size; block_x++)
- *(ptr + block_x + block_y*linesize) <<= 8 - s->bits;
- }
-}
-
-static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
- int Al, const uint8_t *mb_bitmask,
- int mb_bitmask_size,
- const AVFrame *reference)
-{
- int i, mb_x, mb_y, chroma_h_shift, chroma_v_shift, chroma_width, chroma_height;
- uint8_t *data[MAX_COMPONENTS];
- const uint8_t *reference_data[MAX_COMPONENTS];
- int linesize[MAX_COMPONENTS];
- GetBitContext mb_bitmask_gb = {0}; // initialize to silence gcc warning
- int bytes_per_pixel = 1 + (s->bits > 8);
-
- if (mb_bitmask) {
- if (mb_bitmask_size != (s->mb_width * s->mb_height + 7)>>3) {
- av_log(s->avctx, AV_LOG_ERROR, "mb_bitmask_size mismatches\n");
- return AVERROR_INVALIDDATA;
- }
- init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height);
- }
-
- s->restart_count = 0;
-
- av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt, &chroma_h_shift,
- &chroma_v_shift);
- chroma_width = FF_CEIL_RSHIFT(s->width, chroma_h_shift);
- chroma_height = FF_CEIL_RSHIFT(s->height, chroma_v_shift);
-
- for (i = 0; i < nb_components; i++) {
- int c = s->comp_index[i];
- data[c] = s->picture_ptr->data[c];
- reference_data[c] = reference ? reference->data[c] : NULL;
- linesize[c] = s->linesize[c];
- s->coefs_finished[c] |= 1;
- }
-
- for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
- for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
- const int copy_mb = mb_bitmask && !get_bits1(&mb_bitmask_gb);
-
- if (s->restart_interval && !s->restart_count)
- s->restart_count = s->restart_interval;
-
- if (get_bits_left(&s->gb) < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "overread %d\n",
- -get_bits_left(&s->gb));
- return AVERROR_INVALIDDATA;
- }
- for (i = 0; i < nb_components; i++) {
- uint8_t *ptr;
- int n, h, v, x, y, c, j;
- int block_offset;
- n = s->nb_blocks[i];
- c = s->comp_index[i];
- h = s->h_scount[i];
- v = s->v_scount[i];
- x = 0;
- y = 0;
- for (j = 0; j < n; j++) {
- block_offset = (((linesize[c] * (v * mb_y + y) * 8) +
- (h * mb_x + x) * 8 * bytes_per_pixel) >> s->avctx->lowres);
-
- if (s->interlaced && s->bottom_field)
- block_offset += linesize[c] >> 1;
- if ( 8*(h * mb_x + x) < ((c == 1) || (c == 2) ? chroma_width : s->width)
- && 8*(v * mb_y + y) < ((c == 1) || (c == 2) ? chroma_height : s->height)) {
- ptr = data[c] + block_offset;
- } else
- ptr = NULL;
- if (!s->progressive) {
- if (copy_mb) {
- if (ptr)
- mjpeg_copy_block(s, ptr, reference_data[c] + block_offset,
- linesize[c], s->avctx->lowres);
-
- } else {
- s->bdsp.clear_block(s->block);
- if (decode_block(s, s->block, i,
- s->dc_index[i], s->ac_index[i],
- s->quant_matrixes[s->quant_sindex[i]]) < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "error y=%d x=%d\n", mb_y, mb_x);
- return AVERROR_INVALIDDATA;
- }
- if (ptr) {
- s->idsp.idct_put(ptr, linesize[c], s->block);
- if (s->bits & 7)
- shift_output(s, ptr, linesize[c]);
- }
- }
- } else {
- int block_idx = s->block_stride[c] * (v * mb_y + y) +
- (h * mb_x + x);
- int16_t *block = s->blocks[c][block_idx];
- if (Ah)
- block[0] += get_bits1(&s->gb) *
- s->quant_matrixes[s->quant_sindex[i]][0] << Al;
- else if (decode_dc_progressive(s, block, i, s->dc_index[i],
- s->quant_matrixes[s->quant_sindex[i]],
- Al) < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "error y=%d x=%d\n", mb_y, mb_x);
- return AVERROR_INVALIDDATA;
- }
- }
- ff_dlog(s->avctx, "mb: %d %d processed\n", mb_y, mb_x);
- ff_dlog(s->avctx, "%d %d %d %d %d %d %d %d \n",
- mb_x, mb_y, x, y, c, s->bottom_field,
- (v * mb_y + y) * 8, (h * mb_x + x) * 8);
- if (++x == h) {
- x = 0;
- y++;
- }
- }
- }
-
- handle_rstn(s, nb_components);
- }
- }
- return 0;
-}
-
-static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss,
- int se, int Ah, int Al)
-{
- int mb_x, mb_y;
- int EOBRUN = 0;
- int c = s->comp_index[0];
- int16_t *quant_matrix = s->quant_matrixes[s->quant_sindex[0]];
-
- av_assert0(ss>=0 && Ah>=0 && Al>=0);
- if (se < ss || se > 63) {
- av_log(s->avctx, AV_LOG_ERROR, "SS/SE %d/%d is invalid\n", ss, se);
- return AVERROR_INVALIDDATA;
- }
-
- // s->coefs_finished is a bitmask for coefficients coded
- // ss and se are parameters telling start and end coefficients
- s->coefs_finished[c] |= (2ULL << se) - (1ULL << ss);
-
- s->restart_count = 0;
-
- for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
- int block_idx = mb_y * s->block_stride[c];
- int16_t (*block)[64] = &s->blocks[c][block_idx];
- uint8_t *last_nnz = &s->last_nnz[c][block_idx];
- if (get_bits_left(&s->gb) <= 0) {
- av_log(s->avctx, AV_LOG_ERROR, "bitstream truncated in mjpeg_decode_scan_progressive_ac\n");
- return AVERROR_INVALIDDATA;
- }
- for (mb_x = 0; mb_x < s->mb_width; mb_x++, block++, last_nnz++) {
- int ret;
- if (s->restart_interval && !s->restart_count)
- s->restart_count = s->restart_interval;
-
- if (Ah)
- ret = decode_block_refinement(s, *block, last_nnz, s->ac_index[0],
- quant_matrix, ss, se, Al, &EOBRUN);
- else
- ret = decode_block_progressive(s, *block, last_nnz, s->ac_index[0],
- quant_matrix, ss, se, Al, &EOBRUN);
- if (ret < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "error y=%d x=%d\n", mb_y, mb_x);
- return AVERROR_INVALIDDATA;
- }
-
- if (handle_rstn(s, 0))
- EOBRUN = 0;
- }
- }
- return 0;
-}
-
-static void mjpeg_idct_scan_progressive_ac(MJpegDecodeContext *s)
-{
- int mb_x, mb_y;
- int c;
- const int bytes_per_pixel = 1 + (s->bits > 8);
- const int block_size = s->lossless ? 1 : 8;
-
- for (c = 0; c < s->nb_components; c++) {
- uint8_t *data = s->picture_ptr->data[c];
- int linesize = s->linesize[c];
- int h = s->h_max / s->h_count[c];
- int v = s->v_max / s->v_count[c];
- int mb_width = (s->width + h * block_size - 1) / (h * block_size);
- int mb_height = (s->height + v * block_size - 1) / (v * block_size);
-
- if (~s->coefs_finished[c])
- av_log(s->avctx, AV_LOG_WARNING, "component %d is incomplete\n", c);
-
- if (s->interlaced && s->bottom_field)
- data += linesize >> 1;
-
- for (mb_y = 0; mb_y < mb_height; mb_y++) {
- uint8_t *ptr = data + (mb_y * linesize * 8 >> s->avctx->lowres);
- int block_idx = mb_y * s->block_stride[c];
- int16_t (*block)[64] = &s->blocks[c][block_idx];
- for (mb_x = 0; mb_x < mb_width; mb_x++, block++) {
- s->idsp.idct_put(ptr, linesize, *block);
- if (s->bits & 7)
- shift_output(s, ptr, linesize);
- ptr += bytes_per_pixel*8 >> s->avctx->lowres;
- }
- }
- }
-}
-
-int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask,
- int mb_bitmask_size, const AVFrame *reference)
-{
- int len, nb_components, i, h, v, predictor, point_transform;
- int index, id, ret;
- const int block_size = s->lossless ? 1 : 8;
- int ilv, prev_shift;
-
- if (!s->got_picture) {
- av_log(s->avctx, AV_LOG_WARNING,
- "Can not process SOS before SOF, skipping\n");
- return -1;
- }
-
- av_assert0(s->picture_ptr->data[0]);
- /* XXX: verify len field validity */
- len = get_bits(&s->gb, 16);
- nb_components = get_bits(&s->gb, 8);
- if (nb_components == 0 || nb_components > MAX_COMPONENTS) {
- av_log(s->avctx, AV_LOG_ERROR,
- "decode_sos: nb_components (%d) unsupported\n", nb_components);
- return AVERROR_PATCHWELCOME;
- }
- if (len != 6 + 2 * nb_components) {
- av_log(s->avctx, AV_LOG_ERROR, "decode_sos: invalid len (%d)\n", len);
- return AVERROR_INVALIDDATA;
- }
- for (i = 0; i < nb_components; i++) {
- id = get_bits(&s->gb, 8) - 1;
- av_log(s->avctx, AV_LOG_DEBUG, "component: %d\n", id);
- /* find component index */
- for (index = 0; index < s->nb_components; index++)
- if (id == s->component_id[index])
- break;
- if (index == s->nb_components) {
- av_log(s->avctx, AV_LOG_ERROR,
- "decode_sos: index(%d) out of components\n", index);
- return AVERROR_INVALIDDATA;
- }
- /* Metasoft MJPEG codec has Cb and Cr swapped */
- if (s->avctx->codec_tag == MKTAG('M', 'T', 'S', 'J')
- && nb_components == 3 && s->nb_components == 3 && i)
- index = 3 - i;
-
- s->quant_sindex[i] = s->quant_index[index];
- s->nb_blocks[i] = s->h_count[index] * s->v_count[index];
- s->h_scount[i] = s->h_count[index];
- s->v_scount[i] = s->v_count[index];
-
- if(nb_components == 3 && s->nb_components == 3 && s->avctx->pix_fmt == AV_PIX_FMT_GBR24P)
- index = (i+2)%3;
- if(nb_components == 1 && s->nb_components == 3 && s->avctx->pix_fmt == AV_PIX_FMT_GBR24P)
- index = (index+2)%3;
-
- s->comp_index[i] = index;
-
- s->dc_index[i] = get_bits(&s->gb, 4);
- s->ac_index[i] = get_bits(&s->gb, 4);
-
- if (s->dc_index[i] < 0 || s->ac_index[i] < 0 ||
- s->dc_index[i] >= 4 || s->ac_index[i] >= 4)
- goto out_of_range;
- if (!s->vlcs[0][s->dc_index[i]].table || !(s->progressive ? s->vlcs[2][s->ac_index[0]].table : s->vlcs[1][s->ac_index[i]].table))
- goto out_of_range;
- }
-
- predictor = get_bits(&s->gb, 8); /* JPEG Ss / lossless JPEG predictor /JPEG-LS NEAR */
- ilv = get_bits(&s->gb, 8); /* JPEG Se / JPEG-LS ILV */
- if(s->avctx->codec_tag != AV_RL32("CJPG")){
- prev_shift = get_bits(&s->gb, 4); /* Ah */
- point_transform = get_bits(&s->gb, 4); /* Al */
- }else
- prev_shift = point_transform = 0;
-
- if (nb_components > 1) {
- /* interleaved stream */
- s->mb_width = (s->width + s->h_max * block_size - 1) / (s->h_max * block_size);
- s->mb_height = (s->height + s->v_max * block_size - 1) / (s->v_max * block_size);
- } else if (!s->ls) { /* skip this for JPEG-LS */
- h = s->h_max / s->h_scount[0];
- v = s->v_max / s->v_scount[0];
- s->mb_width = (s->width + h * block_size - 1) / (h * block_size);
- s->mb_height = (s->height + v * block_size - 1) / (v * block_size);
- s->nb_blocks[0] = 1;
- s->h_scount[0] = 1;
- s->v_scount[0] = 1;
- }
-
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_DEBUG, "%s %s p:%d >>:%d ilv:%d bits:%d skip:%d %s comp:%d\n",
- s->lossless ? "lossless" : "sequential DCT", s->rgb ? "RGB" : "",
- predictor, point_transform, ilv, s->bits, s->mjpb_skiptosod,
- s->pegasus_rct ? "PRCT" : (s->rct ? "RCT" : ""), nb_components);
-
-
- /* mjpeg-b can have padding bytes between sos and image data, skip them */
- for (i = s->mjpb_skiptosod; i > 0; i--)
- skip_bits(&s->gb, 8);
-
-next_field:
- for (i = 0; i < nb_components; i++)
- s->last_dc[i] = (4 << s->bits);
-
- if (s->lossless) {
- av_assert0(s->picture_ptr == s->picture);
- if (CONFIG_JPEGLS_DECODER && s->ls) {
-// for () {
-// reset_ls_coding_parameters(s, 0);
-
- if ((ret = ff_jpegls_decode_picture(s, predictor,
- point_transform, ilv)) < 0)
- return ret;
- } else {
- if (s->rgb) {
- if ((ret = ljpeg_decode_rgb_scan(s, nb_components, predictor, point_transform)) < 0)
- return ret;
- } else {
- if ((ret = ljpeg_decode_yuv_scan(s, predictor,
- point_transform,
- nb_components)) < 0)
- return ret;
- }
- }
- } else {
- if (s->progressive && predictor) {
- av_assert0(s->picture_ptr == s->picture);
- if ((ret = mjpeg_decode_scan_progressive_ac(s, predictor,
- ilv, prev_shift,
- point_transform)) < 0)
- return ret;
- } else {
- if ((ret = mjpeg_decode_scan(s, nb_components,
- prev_shift, point_transform,
- mb_bitmask, mb_bitmask_size, reference)) < 0)
- return ret;
- }
- }
-
- if (s->interlaced &&
- get_bits_left(&s->gb) > 32 &&
- show_bits(&s->gb, 8) == 0xFF) {
- GetBitContext bak = s->gb;
- align_get_bits(&bak);
- if (show_bits(&bak, 16) == 0xFFD1) {
- av_log(s->avctx, AV_LOG_DEBUG, "AVRn interlaced picture marker found\n");
- s->gb = bak;
- skip_bits(&s->gb, 16);
- s->bottom_field ^= 1;
-
- goto next_field;
- }
- }
-
- emms_c();
- return 0;
- out_of_range:
- av_log(s->avctx, AV_LOG_ERROR, "decode_sos: ac/dc index out of range\n");
- return AVERROR_INVALIDDATA;
-}
-
-static int mjpeg_decode_dri(MJpegDecodeContext *s)
-{
- if (get_bits(&s->gb, 16) != 4)
- return AVERROR_INVALIDDATA;
- s->restart_interval = get_bits(&s->gb, 16);
- s->restart_count = 0;
- av_log(s->avctx, AV_LOG_DEBUG, "restart interval: %d\n",
- s->restart_interval);
-
- return 0;
-}
-
-static int mjpeg_decode_app(MJpegDecodeContext *s)
-{
- int len, id, i;
-
- len = get_bits(&s->gb, 16);
- if (len < 6)
- return AVERROR_INVALIDDATA;
- if (8 * len > get_bits_left(&s->gb))
- return AVERROR_INVALIDDATA;
-
- id = get_bits_long(&s->gb, 32);
- len -= 6;
-
- if (s->avctx->debug & FF_DEBUG_STARTCODE) {
- char id_str[32];
- av_get_codec_tag_string(id_str, sizeof(id_str), av_bswap32(id));
- av_log(s->avctx, AV_LOG_DEBUG, "APPx (%s / %8X) len=%d\n", id_str, id, len);
- }
-
- /* Buggy AVID, it puts EOI only at every 10th frame. */
- /* Also, this fourcc is used by non-avid files too, it holds some
- information, but it's always present in AVID-created files. */
- if (id == AV_RB32("AVI1")) {
- /* structure:
- 4bytes AVI1
- 1bytes polarity
- 1bytes always zero
- 4bytes field_size
- 4bytes field_size_less_padding
- */
- s->buggy_avid = 1;
- i = get_bits(&s->gb, 8); len--;
- av_log(s->avctx, AV_LOG_DEBUG, "polarity %d\n", i);
-#if 0
- skip_bits(&s->gb, 8);
- skip_bits(&s->gb, 32);
- skip_bits(&s->gb, 32);
- len -= 10;
-#endif
- goto out;
- }
-
-// len -= 2;
-
- if (id == AV_RB32("JFIF")) {
- int t_w, t_h, v1, v2;
- skip_bits(&s->gb, 8); /* the trailing zero-byte */
- v1 = get_bits(&s->gb, 8);
- v2 = get_bits(&s->gb, 8);
- skip_bits(&s->gb, 8);
-
- s->avctx->sample_aspect_ratio.num = get_bits(&s->gb, 16);
- s->avctx->sample_aspect_ratio.den = get_bits(&s->gb, 16);
- ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio);
-
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_INFO,
- "mjpeg: JFIF header found (version: %x.%x) SAR=%d/%d\n",
- v1, v2,
- s->avctx->sample_aspect_ratio.num,
- s->avctx->sample_aspect_ratio.den);
-
- t_w = get_bits(&s->gb, 8);
- t_h = get_bits(&s->gb, 8);
- if (t_w && t_h) {
- /* skip thumbnail */
- if (len -10 - (t_w * t_h * 3) > 0)
- len -= t_w * t_h * 3;
- }
- len -= 10;
- goto out;
- }
-
- if (id == AV_RB32("Adob") && (get_bits(&s->gb, 8) == 'e')) {
- skip_bits(&s->gb, 16); /* version */
- skip_bits(&s->gb, 16); /* flags0 */
- skip_bits(&s->gb, 16); /* flags1 */
- s->adobe_transform = get_bits(&s->gb, 8);
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_INFO, "mjpeg: Adobe header found, transform=%d\n", s->adobe_transform);
- len -= 7;
- goto out;
- }
-
- if (id == AV_RB32("LJIF")) {
- int rgb = s->rgb;
- int pegasus_rct = s->pegasus_rct;
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_INFO,
- "Pegasus lossless jpeg header found\n");
- skip_bits(&s->gb, 16); /* version ? */
- skip_bits(&s->gb, 16); /* unknown always 0? */
- skip_bits(&s->gb, 16); /* unknown always 0? */
- skip_bits(&s->gb, 16); /* unknown always 0? */
- switch (i=get_bits(&s->gb, 8)) {
- case 1:
- rgb = 1;
- pegasus_rct = 0;
- break;
- case 2:
- rgb = 1;
- pegasus_rct = 1;
- break;
- default:
- av_log(s->avctx, AV_LOG_ERROR, "unknown colorspace %d\n", i);
- }
-
- len -= 9;
- if (s->got_picture)
- if (rgb != s->rgb || pegasus_rct != s->pegasus_rct) {
- av_log(s->avctx, AV_LOG_WARNING, "Mismatching LJIF tag\n");
- goto out;
- }
-
- s->rgb = rgb;
- s->pegasus_rct = pegasus_rct;
-
- goto out;
- }
- if (id == AV_RL32("colr") && len > 0) {
- s->colr = get_bits(&s->gb, 8);
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_INFO, "COLR %d\n", s->colr);
- len --;
- goto out;
- }
- if (id == AV_RL32("xfrm") && len > 0) {
- s->xfrm = get_bits(&s->gb, 8);
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_INFO, "XFRM %d\n", s->xfrm);
- len --;
- goto out;
- }
-
- /* JPS extension by VRex */
- if (s->start_code == APP3 && id == AV_RB32("_JPS") && len >= 10) {
- int flags, layout, type;
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_INFO, "_JPSJPS_\n");
-
- skip_bits(&s->gb, 32); len -= 4; /* JPS_ */
- skip_bits(&s->gb, 16); len -= 2; /* block length */
- skip_bits(&s->gb, 8); /* reserved */
- flags = get_bits(&s->gb, 8);
- layout = get_bits(&s->gb, 8);
- type = get_bits(&s->gb, 8);
- len -= 4;
-
- s->stereo3d = av_stereo3d_alloc();
- if (!s->stereo3d) {
- goto out;
- }
- if (type == 0) {
- s->stereo3d->type = AV_STEREO3D_2D;
- } else if (type == 1) {
- switch (layout) {
- case 0x01:
- s->stereo3d->type = AV_STEREO3D_LINES;
- break;
- case 0x02:
- s->stereo3d->type = AV_STEREO3D_SIDEBYSIDE;
- break;
- case 0x03:
- s->stereo3d->type = AV_STEREO3D_TOPBOTTOM;
- break;
- }
- if (!(flags & 0x04)) {
- s->stereo3d->flags = AV_STEREO3D_FLAG_INVERT;
- }
- }
- goto out;
- }
-
- /* EXIF metadata */
- if (s->start_code == APP1 && id == AV_RB32("Exif") && len >= 2) {
- GetByteContext gbytes;
- int ret, le, ifd_offset, bytes_read;
- const uint8_t *aligned;
-
- skip_bits(&s->gb, 16); // skip padding
- len -= 2;
-
- // init byte wise reading
- aligned = align_get_bits(&s->gb);
- bytestream2_init(&gbytes, aligned, len);
-
- // read TIFF header
- ret = ff_tdecode_header(&gbytes, &le, &ifd_offset);
- if (ret) {
- av_log(s->avctx, AV_LOG_ERROR, "mjpeg: invalid TIFF header in EXIF data\n");
- } else {
- bytestream2_seek(&gbytes, ifd_offset, SEEK_SET);
-
- // read 0th IFD and store the metadata
- // (return values > 0 indicate the presence of subimage metadata)
- ret = avpriv_exif_decode_ifd(s->avctx, &gbytes, le, 0, &s->exif_metadata);
- if (ret < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "mjpeg: error decoding EXIF data\n");
- }
- }
-
- bytes_read = bytestream2_tell(&gbytes);
- skip_bits(&s->gb, bytes_read << 3);
- len -= bytes_read;
-
- goto out;
- }
-
- /* Apple MJPEG-A */
- if ((s->start_code == APP1) && (len > (0x28 - 8))) {
- id = get_bits_long(&s->gb, 32);
- len -= 4;
- /* Apple MJPEG-A */
- if (id == AV_RB32("mjpg")) {
-#if 0
- skip_bits(&s->gb, 32); /* field size */
- skip_bits(&s->gb, 32); /* pad field size */
- skip_bits(&s->gb, 32); /* next off */
- skip_bits(&s->gb, 32); /* quant off */
- skip_bits(&s->gb, 32); /* huff off */
- skip_bits(&s->gb, 32); /* image off */
- skip_bits(&s->gb, 32); /* scan off */
- skip_bits(&s->gb, 32); /* data off */
-#endif
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_INFO, "mjpeg: Apple MJPEG-A header found\n");
- }
- }
-
-out:
- /* slow but needed for extreme adobe jpegs */
- if (len < 0)
- av_log(s->avctx, AV_LOG_ERROR,
- "mjpeg: error, decode_app parser read over the end\n");
- while (--len > 0)
- skip_bits(&s->gb, 8);
-
- return 0;
-}
-
-static int mjpeg_decode_com(MJpegDecodeContext *s)
-{
- int len = get_bits(&s->gb, 16);
- if (len >= 2 && 8 * len - 16 <= get_bits_left(&s->gb)) {
- char *cbuf = av_malloc(len - 1);
- if (cbuf) {
- int i;
- for (i = 0; i < len - 2; i++)
- cbuf[i] = get_bits(&s->gb, 8);
- if (i > 0 && cbuf[i - 1] == '\n')
- cbuf[i - 1] = 0;
- else
- cbuf[i] = 0;
-
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_INFO, "comment: '%s'\n", cbuf);
-
- /* buggy avid, it puts EOI only at every 10th frame */
- if (!strncmp(cbuf, "AVID", 4)) {
- parse_avid(s, cbuf, len);
- } else if (!strcmp(cbuf, "CS=ITU601"))
- s->cs_itu601 = 1;
- else if ((!strncmp(cbuf, "Intel(R) JPEG Library, version 1", 32) && s->avctx->codec_tag) ||
- (!strncmp(cbuf, "Metasoft MJPEG Codec", 20)))
- s->flipped = 1;
- else if (!strcmp(cbuf, "MULTISCOPE II"))
- s->multiscope = 2;
-
- av_free(cbuf);
- }
- }
-
- return 0;
-}
-
-/* return the 8 bit start code value and update the search
- state. Return -1 if no start code found */
-static int find_marker(const uint8_t **pbuf_ptr, const uint8_t *buf_end)
-{
- const uint8_t *buf_ptr;
- unsigned int v, v2;
- int val;
- int skipped = 0;
-
- buf_ptr = *pbuf_ptr;
- while (buf_end - buf_ptr > 1) {
- v = *buf_ptr++;
- v2 = *buf_ptr;
- if ((v == 0xff) && (v2 >= 0xc0) && (v2 <= 0xfe) && buf_ptr < buf_end) {
- val = *buf_ptr++;
- goto found;
- }
- skipped++;
- }
- buf_ptr = buf_end;
- val = -1;
-found:
- ff_dlog(NULL, "find_marker skipped %d bytes\n", skipped);
- *pbuf_ptr = buf_ptr;
- return val;
-}
-
-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 start_code;
- start_code = find_marker(buf_ptr, buf_end);
-
- av_fast_padded_malloc(&s->buffer, &s->buffer_size, buf_end - *buf_ptr);
- if (!s->buffer)
- return AVERROR(ENOMEM);
-
- /* unescape buffer of SOS, use special treatment for JPEG-LS */
- if (start_code == SOS && !s->ls) {
- const uint8_t *src = *buf_ptr;
- uint8_t *dst = s->buffer;
-
- while (src < buf_end) {
- uint8_t x = *(src++);
-
- *(dst++) = x;
- if (s->avctx->codec_id != AV_CODEC_ID_THP) {
- if (x == 0xff) {
- while (src < buf_end && x == 0xff)
- x = *(src++);
-
- if (x >= 0xd0 && x <= 0xd7)
- *(dst++) = x;
- else if (x)
- break;
- }
- }
- }
- *unescaped_buf_ptr = s->buffer;
- *unescaped_buf_size = dst - s->buffer;
- memset(s->buffer + *unescaped_buf_size, 0,
- AV_INPUT_BUFFER_PADDING_SIZE);
-
- av_log(s->avctx, AV_LOG_DEBUG, "escaping removed %"PTRDIFF_SPECIFIER" bytes\n",
- (buf_end - *buf_ptr) - (dst - s->buffer));
- } else if (start_code == SOS && s->ls) {
- const uint8_t *src = *buf_ptr;
- uint8_t *dst = s->buffer;
- int bit_count = 0;
- int t = 0, b = 0;
- PutBitContext pb;
-
- /* find marker */
- while (src + t < buf_end) {
- uint8_t x = src[t++];
- if (x == 0xff) {
- while ((src + t < buf_end) && x == 0xff)
- x = src[t++];
- if (x & 0x80) {
- t -= FFMIN(2, t);
- break;
- }
- }
- }
- bit_count = t * 8;
- init_put_bits(&pb, dst, t);
-
- /* unescape bitstream */
- while (b < t) {
- uint8_t x = src[b++];
- put_bits(&pb, 8, x);
- if (x == 0xFF && b < t) {
- x = src[b++];
- if (x & 0x80) {
- av_log(s->avctx, AV_LOG_WARNING, "Invalid escape sequence\n");
- x &= 0x7f;
- }
- put_bits(&pb, 7, x);
- bit_count--;
- }
- }
- flush_put_bits(&pb);
-
- *unescaped_buf_ptr = dst;
- *unescaped_buf_size = (bit_count + 7) >> 3;
- memset(s->buffer + *unescaped_buf_size, 0,
- AV_INPUT_BUFFER_PADDING_SIZE);
- } else {
- *unescaped_buf_ptr = *buf_ptr;
- *unescaped_buf_size = buf_end - *buf_ptr;
- }
-
- return start_code;
-}
-
-int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *avpkt)
-{
- 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;
- int hshift, vshift;
- int unescaped_buf_size;
- int start_code;
- int i, index;
- int ret = 0;
- int is16bit;
-
- av_dict_free(&s->exif_metadata);
- av_freep(&s->stereo3d);
- s->adobe_transform = -1;
-
- buf_ptr = buf;
- buf_end = buf + buf_size;
- while (buf_ptr < buf_end) {
- /* find start next marker */
- start_code = ff_mjpeg_find_marker(s, &buf_ptr, buf_end,
- &unescaped_buf_ptr,
- &unescaped_buf_size);
- /* EOF */
- if (start_code < 0) {
- break;
- } else if (unescaped_buf_size > INT_MAX / 8) {
- av_log(avctx, AV_LOG_ERROR,
- "MJPEG packet 0x%x too big (%d/%d), corrupt data?\n",
- start_code, unescaped_buf_size, buf_size);
- return AVERROR_INVALIDDATA;
- }
- av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%"PTRDIFF_SPECIFIER"\n",
- start_code, buf_end - buf_ptr);
-
- ret = init_get_bits8(&s->gb, unescaped_buf_ptr, unescaped_buf_size);
-
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "invalid buffer\n");
- goto fail;
- }
-
- s->start_code = start_code;
- if (s->avctx->debug & FF_DEBUG_STARTCODE)
- av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code);
-
- /* process markers */
- if (start_code >= 0xd0 && start_code <= 0xd7)
- av_log(avctx, AV_LOG_DEBUG,
- "restart marker: %d\n", start_code & 0x0f);
- /* APP fields */
- else if (start_code >= APP0 && start_code <= APP15)
- mjpeg_decode_app(s);
- /* Comment */
- else if (start_code == COM)
- mjpeg_decode_com(s);
-
- ret = -1;
-
- if (!CONFIG_JPEGLS_DECODER &&
- (start_code == SOF48 || start_code == LSE)) {
- av_log(avctx, AV_LOG_ERROR, "JPEG-LS support not enabled.\n");
- return AVERROR(ENOSYS);
- }
-
- switch (start_code) {
- case SOI:
- s->restart_interval = 0;
- s->restart_count = 0;
- /* nothing to do on SOI */
- break;
- case DQT:
- ff_mjpeg_decode_dqt(s);
- break;
- case DHT:
- if ((ret = ff_mjpeg_decode_dht(s)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n");
- goto fail;
- }
- break;
- case SOF0:
- case SOF1:
- s->lossless = 0;
- s->ls = 0;
- s->progressive = 0;
- if ((ret = ff_mjpeg_decode_sof(s)) < 0)
- goto fail;
- break;
- case SOF2:
- s->lossless = 0;
- s->ls = 0;
- s->progressive = 1;
- if ((ret = ff_mjpeg_decode_sof(s)) < 0)
- goto fail;
- break;
- case SOF3:
- s->avctx->properties |= FF_CODEC_PROPERTY_LOSSLESS;
- s->lossless = 1;
- s->ls = 0;
- s->progressive = 0;
- if ((ret = ff_mjpeg_decode_sof(s)) < 0)
- goto fail;
- break;
- case SOF48:
- s->avctx->properties |= FF_CODEC_PROPERTY_LOSSLESS;
- s->lossless = 1;
- s->ls = 1;
- s->progressive = 0;
- if ((ret = ff_mjpeg_decode_sof(s)) < 0)
- goto fail;
- break;
- case LSE:
- if (!CONFIG_JPEGLS_DECODER ||
- (ret = ff_jpegls_decode_lse(s)) < 0)
- goto fail;
- break;
- case EOI:
-eoi_parser:
- if (avctx->skip_frame != AVDISCARD_ALL && s->progressive && s->cur_scan && s->got_picture)
- mjpeg_idct_scan_progressive_ac(s);
- s->cur_scan = 0;
- if (!s->got_picture) {
- av_log(avctx, AV_LOG_WARNING,
- "Found EOI before any SOF, ignoring\n");
- break;
- }
- if (s->interlaced) {
- s->bottom_field ^= 1;
- /* if not bottom field, do not output image yet */
- if (s->bottom_field == !s->interlace_polarity)
- break;
- }
- if ((ret = av_frame_ref(frame, s->picture_ptr)) < 0)
- return ret;
- *got_frame = 1;
- s->got_picture = 0;
-
- if (!s->lossless) {
- int qp = FFMAX3(s->qscale[0],
- s->qscale[1],
- s->qscale[2]);
- int qpw = (s->width + 15) / 16;
- AVBufferRef *qp_table_buf = av_buffer_alloc(qpw);
- if (qp_table_buf) {
- memset(qp_table_buf->data, qp, qpw);
- av_frame_set_qp_table(data, qp_table_buf, 0, FF_QSCALE_TYPE_MPEG1);
- }
-
- if(avctx->debug & FF_DEBUG_QP)
- av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", qp);
- }
-
- goto the_end;
- case SOS:
- s->cur_scan++;
- if ((ret = ff_mjpeg_decode_sos(s, NULL, 0, NULL)) < 0 &&
- (avctx->err_recognition & AV_EF_EXPLODE))
- goto fail;
- break;
- case DRI:
- mjpeg_decode_dri(s);
- break;
- case SOF5:
- case SOF6:
- case SOF7:
- case SOF9:
- case SOF10:
- case SOF11:
- case SOF13:
- case SOF14:
- case SOF15:
- case JPG:
- av_log(avctx, AV_LOG_ERROR,
- "mjpeg: unsupported coding type (%x)\n", start_code);
- break;
- }
-
- /* eof process start code */
- buf_ptr += (get_bits_count(&s->gb) + 7) / 8;
- av_log(avctx, AV_LOG_DEBUG,
- "marker parser used %d bytes (%d bits)\n",
- (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb));
- }
- if (s->got_picture && s->cur_scan) {
- av_log(avctx, AV_LOG_WARNING, "EOI missing, emulating\n");
- goto eoi_parser;
- }
- av_log(avctx, AV_LOG_FATAL, "No JPEG data found in image\n");
- return AVERROR_INVALIDDATA;
-fail:
- s->got_picture = 0;
- return ret;
-the_end:
-
- is16bit = av_pix_fmt_desc_get(s->avctx->pix_fmt)->comp[0].step_minus1;
-
- if (AV_RB32(s->upscale_h)) {
- int p;
- av_assert0(avctx->pix_fmt == AV_PIX_FMT_YUVJ444P ||
- avctx->pix_fmt == AV_PIX_FMT_YUV444P ||
- avctx->pix_fmt == AV_PIX_FMT_YUVJ440P ||
- avctx->pix_fmt == AV_PIX_FMT_YUV440P ||
- avctx->pix_fmt == AV_PIX_FMT_YUVA444P ||
- avctx->pix_fmt == AV_PIX_FMT_YUVJ420P ||
- avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
- avctx->pix_fmt == AV_PIX_FMT_YUV420P16||
- avctx->pix_fmt == AV_PIX_FMT_YUVA420P ||
- avctx->pix_fmt == AV_PIX_FMT_YUVA420P16||
- avctx->pix_fmt == AV_PIX_FMT_GBRP ||
- avctx->pix_fmt == AV_PIX_FMT_GBRAP
- );
- avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift);
- for (p = 0; p<4; p++) {
- uint8_t *line = s->picture_ptr->data[p];
- int w = s->width;
- int h = s->height;
- if (!s->upscale_h[p])
- continue;
- if (p==1 || p==2) {
- w = FF_CEIL_RSHIFT(w, hshift);
- h = FF_CEIL_RSHIFT(h, vshift);
- }
- if (s->upscale_v[p])
- h = (h+1)>>1;
- av_assert0(w > 0);
- for (i = 0; i < h; i++) {
- if (s->upscale_h[p] == 1) {
- if (is16bit) ((uint16_t*)line)[w - 1] = ((uint16_t*)line)[(w - 1) / 2];
- else line[w - 1] = line[(w - 1) / 2];
- for (index = w - 2; index > 0; index--) {
- if (is16bit)
- ((uint16_t*)line)[index] = (((uint16_t*)line)[index / 2] + ((uint16_t*)line)[(index + 1) / 2]) >> 1;
- else
- line[index] = (line[index / 2] + line[(index + 1) / 2]) >> 1;
- }
- } else if (s->upscale_h[p] == 2) {
- if (is16bit) {
- ((uint16_t*)line)[w - 1] = ((uint16_t*)line)[(w - 1) / 3];
- if (w > 1)
- ((uint16_t*)line)[w - 2] = ((uint16_t*)line)[w - 1];
- } else {
- line[w - 1] = line[(w - 1) / 3];
- if (w > 1)
- line[w - 2] = line[w - 1];
- }
- for (index = w - 3; index > 0; index--) {
- line[index] = (line[index / 3] + line[(index + 1) / 3] + line[(index + 2) / 3] + 1) / 3;
- }
- }
- line += s->linesize[p];
- }
- }
- }
- if (AV_RB32(s->upscale_v)) {
- int p;
- av_assert0(avctx->pix_fmt == AV_PIX_FMT_YUVJ444P ||
- avctx->pix_fmt == AV_PIX_FMT_YUV444P ||
- avctx->pix_fmt == AV_PIX_FMT_YUVJ422P ||
- avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
- avctx->pix_fmt == AV_PIX_FMT_YUVJ420P ||
- avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
- avctx->pix_fmt == AV_PIX_FMT_YUV440P ||
- avctx->pix_fmt == AV_PIX_FMT_YUVJ440P ||
- avctx->pix_fmt == AV_PIX_FMT_YUVA444P ||
- avctx->pix_fmt == AV_PIX_FMT_YUVA420P ||
- avctx->pix_fmt == AV_PIX_FMT_YUVA420P16||
- avctx->pix_fmt == AV_PIX_FMT_GBRP ||
- avctx->pix_fmt == AV_PIX_FMT_GBRAP
- );
- avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift);
- for (p = 0; p < 4; p++) {
- uint8_t *dst;
- int w = s->width;
- int h = s->height;
- if (!s->upscale_v[p])
- continue;
- if (p==1 || p==2) {
- w = FF_CEIL_RSHIFT(w, hshift);
- h = FF_CEIL_RSHIFT(h, vshift);
- }
- dst = &((uint8_t *)s->picture_ptr->data[p])[(h - 1) * s->linesize[p]];
- for (i = h - 1; i; i--) {
- uint8_t *src1 = &((uint8_t *)s->picture_ptr->data[p])[i / 2 * s->linesize[p]];
- uint8_t *src2 = &((uint8_t *)s->picture_ptr->data[p])[(i + 1) / 2 * s->linesize[p]];
- if (src1 == src2 || i == h - 1) {
- memcpy(dst, src1, w);
- } else {
- for (index = 0; index < w; index++)
- dst[index] = (src1[index] + src2[index]) >> 1;
- }
- dst -= s->linesize[p];
- }
- }
- }
- if (s->flipped && !s->rgb) {
- int j;
- avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift);
- for (index=0; index<4; index++) {
- uint8_t *dst = s->picture_ptr->data[index];
- int w = s->picture_ptr->width;
- int h = s->picture_ptr->height;
- if(index && index<3){
- w = FF_CEIL_RSHIFT(w, hshift);
- h = FF_CEIL_RSHIFT(h, vshift);
- }
- if(dst){
- uint8_t *dst2 = dst + s->picture_ptr->linesize[index]*(h-1);
- for (i=0; i<h/2; i++) {
- for (j=0; j<w; j++)
- FFSWAP(int, dst[j], dst2[j]);
- dst += s->picture_ptr->linesize[index];
- dst2 -= s->picture_ptr->linesize[index];
- }
- }
- }
- }
- if (s->adobe_transform == 0 && s->avctx->pix_fmt == AV_PIX_FMT_GBRAP) {
- int w = s->picture_ptr->width;
- int h = s->picture_ptr->height;
- for (i=0; i<h; i++) {
- int j;
- uint8_t *dst[4];
- for (index=0; index<4; index++) {
- dst[index] = s->picture_ptr->data[index]
- + s->picture_ptr->linesize[index]*i;
- }
- for (j=0; j<w; j++) {
- int k = dst[3][j];
- int r = dst[0][j] * k;
- int g = dst[1][j] * k;
- int b = dst[2][j] * k;
- dst[0][j] = g*257 >> 16;
- dst[1][j] = b*257 >> 16;
- dst[2][j] = r*257 >> 16;
- dst[3][j] = 255;
- }
- }
- }
- if (s->adobe_transform == 2 && s->avctx->pix_fmt == AV_PIX_FMT_YUVA444P) {
- int w = s->picture_ptr->width;
- int h = s->picture_ptr->height;
- for (i=0; i<h; i++) {
- int j;
- uint8_t *dst[4];
- for (index=0; index<4; index++) {
- dst[index] = s->picture_ptr->data[index]
- + s->picture_ptr->linesize[index]*i;
- }
- for (j=0; j<w; j++) {
- int k = dst[3][j];
- int r = (255 - dst[0][j]) * k;
- int g = (128 - dst[1][j]) * k;
- int b = (128 - dst[2][j]) * k;
- dst[0][j] = r*257 >> 16;
- dst[1][j] = (g*257 >> 16) + 128;
- dst[2][j] = (b*257 >> 16) + 128;
- dst[3][j] = 255;
- }
- }
- }
-
- if (s->stereo3d) {
- AVStereo3D *stereo = av_stereo3d_create_side_data(data);
- if (stereo) {
- stereo->type = s->stereo3d->type;
- stereo->flags = s->stereo3d->flags;
- }
- av_freep(&s->stereo3d);
- }
-
- av_dict_copy(avpriv_frame_get_metadatap(data), s->exif_metadata, 0);
- av_dict_free(&s->exif_metadata);
-
- av_log(avctx, AV_LOG_DEBUG, "decode frame unused %"PTRDIFF_SPECIFIER" bytes\n",
- buf_end - buf_ptr);
-// return buf_end - buf_ptr;
- return buf_ptr - buf;
-}
-
-av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx)
-{
- MJpegDecodeContext *s = avctx->priv_data;
- int i, j;
-
- if (s->interlaced && s->bottom_field == !s->interlace_polarity && s->got_picture && !avctx->frame_number) {
- av_log(avctx, AV_LOG_INFO, "Single field\n");
- }
-
- if (s->picture) {
- av_frame_free(&s->picture);
- s->picture_ptr = NULL;
- } else if (s->picture_ptr)
- av_frame_unref(s->picture_ptr);
-
- av_freep(&s->buffer);
- av_freep(&s->stereo3d);
- av_freep(&s->ljpeg_buffer);
- s->ljpeg_buffer_size = 0;
-
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 4; j++)
- ff_free_vlc(&s->vlcs[i][j]);
- }
- for (i = 0; i < MAX_COMPONENTS; i++) {
- av_freep(&s->blocks[i]);
- av_freep(&s->last_nnz[i]);
- }
- av_dict_free(&s->exif_metadata);
- return 0;
-}
-
-static void decode_flush(AVCodecContext *avctx)
-{
- MJpegDecodeContext *s = avctx->priv_data;
- s->got_picture = 0;
-}
-
-#if CONFIG_MJPEG_DECODER
-#define OFFSET(x) offsetof(MJpegDecodeContext, x)
-#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
-static const AVOption options[] = {
- { "extern_huff", "Use external huffman table.",
- OFFSET(extern_huff), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VD },
- { NULL },
-};
-
-static const AVClass mjpegdec_class = {
- .class_name = "MJPEG decoder",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-AVCodec ff_mjpeg_decoder = {
- .name = "mjpeg",
- .long_name = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MJPEG,
- .priv_data_size = sizeof(MJpegDecodeContext),
- .init = ff_mjpeg_decode_init,
- .close = ff_mjpeg_decode_end,
- .decode = ff_mjpeg_decode_frame,
- .flush = decode_flush,
- .capabilities = AV_CODEC_CAP_DR1,
- .max_lowres = 3,
- .priv_class = &mjpegdec_class,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
-};
-#endif
-#if CONFIG_THP_DECODER
-AVCodec ff_thp_decoder = {
- .name = "thp",
- .long_name = NULL_IF_CONFIG_SMALL("Nintendo Gamecube THP video"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_THP,
- .priv_data_size = sizeof(MJpegDecodeContext),
- .init = ff_mjpeg_decode_init,
- .close = ff_mjpeg_decode_end,
- .decode = ff_mjpeg_decode_frame,
- .flush = decode_flush,
- .capabilities = AV_CODEC_CAP_DR1,
- .max_lowres = 3,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
-};
-#endif
diff --git a/ffmpeg-2-8-11/libavcodec/mlpdec.c b/ffmpeg-2-8-11/libavcodec/mlpdec.c
deleted file mode 100644
index 1687ce8..0000000
--- a/ffmpeg-2-8-11/libavcodec/mlpdec.c
+++ /dev/null
@@ -1,1331 +0,0 @@
-/*
- * MLP decoder
- * Copyright (c) 2007-2008 Ian Caulfield
- *
- * 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
- * MLP decoder
- */
-
-#include <stdint.h>
-
-#include "avcodec.h"
-#include "libavutil/internal.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/channel_layout.h"
-#include "get_bits.h"
-#include "internal.h"
-#include "libavutil/crc.h"
-#include "parser.h"
-#include "mlp_parser.h"
-#include "mlpdsp.h"
-#include "mlp.h"
-#include "config.h"
-
-/** number of bits used for VLC lookup - longest Huffman code is 9 */
-#if ARCH_ARM
-#define VLC_BITS 5
-#define VLC_STATIC_SIZE 64
-#else
-#define VLC_BITS 9
-#define VLC_STATIC_SIZE 512
-#endif
-
-typedef struct SubStream {
- /// Set if a valid restart header has been read. Otherwise the substream cannot be decoded.
- uint8_t restart_seen;
-
- //@{
- /** restart header data */
- /// The type of noise to be used in the rematrix stage.
- uint16_t noise_type;
-
- /// The index of the first channel coded in this substream.
- uint8_t min_channel;
- /// The index of the last channel coded in this substream.
- uint8_t max_channel;
- /// The number of channels input into the rematrix stage.
- uint8_t max_matrix_channel;
- /// For each channel output by the matrix, the output channel to map it to
- uint8_t ch_assign[MAX_CHANNELS];
- /// The channel layout for this substream
- uint64_t ch_layout;
- /// The matrix encoding mode for this substream
- enum AVMatrixEncoding matrix_encoding;
-
- /// Channel coding parameters for channels in the substream
- ChannelParams channel_params[MAX_CHANNELS];
-
- /// The left shift applied to random noise in 0x31ea substreams.
- uint8_t noise_shift;
- /// The current seed value for the pseudorandom noise generator(s).
- uint32_t noisegen_seed;
-
- /// Set if the substream contains extra info to check the size of VLC blocks.
- uint8_t data_check_present;
-
- /// Bitmask of which parameter sets are conveyed in a decoding parameter block.
- uint8_t param_presence_flags;
-#define PARAM_BLOCKSIZE (1 << 7)
-#define PARAM_MATRIX (1 << 6)
-#define PARAM_OUTSHIFT (1 << 5)
-#define PARAM_QUANTSTEP (1 << 4)
-#define PARAM_FIR (1 << 3)
-#define PARAM_IIR (1 << 2)
-#define PARAM_HUFFOFFSET (1 << 1)
-#define PARAM_PRESENCE (1 << 0)
- //@}
-
- //@{
- /** matrix data */
-
- /// Number of matrices to be applied.
- uint8_t num_primitive_matrices;
-
- /// matrix output channel
- uint8_t matrix_out_ch[MAX_MATRICES];
-
- /// Whether the LSBs of the matrix output are encoded in the bitstream.
- uint8_t lsb_bypass[MAX_MATRICES];
- /// Matrix coefficients, stored as 2.14 fixed point.
- DECLARE_ALIGNED(32, int32_t, matrix_coeff)[MAX_MATRICES][MAX_CHANNELS];
- /// Left shift to apply to noise values in 0x31eb substreams.
- uint8_t matrix_noise_shift[MAX_MATRICES];
- //@}
-
- /// Left shift to apply to Huffman-decoded residuals.
- uint8_t quant_step_size[MAX_CHANNELS];
-
- /// number of PCM samples in current audio block
- uint16_t blocksize;
- /// Number of PCM samples decoded so far in this frame.
- uint16_t blockpos;
-
- /// Left shift to apply to decoded PCM values to get final 24-bit output.
- int8_t output_shift[MAX_CHANNELS];
-
- /// Running XOR of all output samples.
- int32_t lossless_check_data;
-
-} SubStream;
-
-typedef struct MLPDecodeContext {
- AVCodecContext *avctx;
-
- /// Current access unit being read has a major sync.
- int is_major_sync_unit;
-
- /// Size of the major sync unit, in bytes
- int major_sync_header_size;
-
- /// Set if a valid major sync block has been read. Otherwise no decoding is possible.
- uint8_t params_valid;
-
- /// Number of substreams contained within this stream.
- uint8_t num_substreams;
-
- /// Index of the last substream to decode - further substreams are skipped.
- uint8_t max_decoded_substream;
-
- /// Stream needs channel reordering to comply with FFmpeg's channel order
- uint8_t needs_reordering;
-
- /// number of PCM samples contained in each frame
- int access_unit_size;
- /// next power of two above the number of samples in each frame
- int access_unit_size_pow2;
-
- SubStream substream[MAX_SUBSTREAMS];
-
- int matrix_changed;
- int filter_changed[MAX_CHANNELS][NUM_FILTERS];
-
- int8_t noise_buffer[MAX_BLOCKSIZE_POW2];
- int8_t bypassed_lsbs[MAX_BLOCKSIZE][MAX_CHANNELS];
- DECLARE_ALIGNED(32, int32_t, sample_buffer)[MAX_BLOCKSIZE][MAX_CHANNELS];
-
- MLPDSPContext dsp;
-} MLPDecodeContext;
-
-static const uint64_t thd_channel_order[] = {
- AV_CH_FRONT_LEFT, AV_CH_FRONT_RIGHT, // LR
- AV_CH_FRONT_CENTER, // C
- AV_CH_LOW_FREQUENCY, // LFE
- AV_CH_SIDE_LEFT, AV_CH_SIDE_RIGHT, // LRs
- AV_CH_TOP_FRONT_LEFT, AV_CH_TOP_FRONT_RIGHT, // LRvh
- AV_CH_FRONT_LEFT_OF_CENTER, AV_CH_FRONT_RIGHT_OF_CENTER, // LRc
- AV_CH_BACK_LEFT, AV_CH_BACK_RIGHT, // LRrs
- AV_CH_BACK_CENTER, // Cs
- AV_CH_TOP_CENTER, // Ts
- AV_CH_SURROUND_DIRECT_LEFT, AV_CH_SURROUND_DIRECT_RIGHT, // LRsd
- AV_CH_WIDE_LEFT, AV_CH_WIDE_RIGHT, // LRw
- AV_CH_TOP_FRONT_CENTER, // Cvh
- AV_CH_LOW_FREQUENCY_2, // LFE2
-};
-
-static uint64_t thd_channel_layout_extract_channel(uint64_t channel_layout,
- int index)
-{
- int i;
-
- if (av_get_channel_layout_nb_channels(channel_layout) <= index)
- return 0;
-
- for (i = 0; i < FF_ARRAY_ELEMS(thd_channel_order); i++)
- if (channel_layout & thd_channel_order[i] && !index--)
- return thd_channel_order[i];
- return 0;
-}
-
-static VLC huff_vlc[3];
-
-/** Initialize static data, constant between all invocations of the codec. */
-
-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);
- }
-
- ff_mlp_init_crc();
-}
-
-static inline int32_t calculate_sign_huff(MLPDecodeContext *m,
- unsigned int substr, unsigned int ch)
-{
- SubStream *s = &m->substream[substr];
- ChannelParams *cp = &s->channel_params[ch];
- int lsb_bits = cp->huff_lsbs - s->quant_step_size[ch];
- int sign_shift = lsb_bits + (cp->codebook ? 2 - cp->codebook : -1);
- int32_t sign_huff_offset = cp->huff_offset;
-
- if (cp->codebook > 0)
- sign_huff_offset -= 7 << lsb_bits;
-
- if (sign_shift >= 0)
- sign_huff_offset -= 1 << sign_shift;
-
- return sign_huff_offset;
-}
-
-/** Read a sample, consisting of either, both or neither of entropy-coded MSBs
- * and plain LSBs. */
-
-static inline int read_huff_channels(MLPDecodeContext *m, GetBitContext *gbp,
- unsigned int substr, unsigned int pos)
-{
- SubStream *s = &m->substream[substr];
- unsigned int mat, channel;
-
- for (mat = 0; mat < s->num_primitive_matrices; mat++)
- if (s->lsb_bypass[mat])
- m->bypassed_lsbs[pos + s->blockpos][mat] = get_bits1(gbp);
-
- for (channel = s->min_channel; channel <= s->max_channel; channel++) {
- ChannelParams *cp = &s->channel_params[channel];
- int codebook = cp->codebook;
- int quant_step_size = s->quant_step_size[channel];
- int lsb_bits = cp->huff_lsbs - quant_step_size;
- int result = 0;
-
- if (codebook > 0)
- result = get_vlc2(gbp, huff_vlc[codebook-1].table,
- VLC_BITS, (9 + VLC_BITS - 1) / VLC_BITS);
-
- if (result < 0)
- return AVERROR_INVALIDDATA;
-
- if (lsb_bits > 0)
- result = (result << lsb_bits) + get_bits(gbp, lsb_bits);
-
- result += cp->sign_huff_offset;
- result <<= quant_step_size;
-
- m->sample_buffer[pos + s->blockpos][channel] = result;
- }
-
- return 0;
-}
-
-static av_cold int mlp_decode_init(AVCodecContext *avctx)
-{
- 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);
-
- return 0;
-}
-
-/** Read a major sync info header - contains high level information about
- * the stream - sample rate, channel arrangement etc. Most of this
- * information is not actually necessary for decoding, only for playback.
- */
-
-static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb)
-{
- MLPHeaderInfo mh;
- int substr, ret;
-
- if ((ret = ff_mlp_read_major_sync(m->avctx, &mh, gb)) != 0)
- return ret;
-
- if (mh.group1_bits == 0) {
- av_log(m->avctx, AV_LOG_ERROR, "invalid/unknown bits per sample\n");
- return AVERROR_INVALIDDATA;
- }
- if (mh.group2_bits > mh.group1_bits) {
- av_log(m->avctx, AV_LOG_ERROR,
- "Channel group 2 cannot have more bits per sample than group 1.\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (mh.group2_samplerate && mh.group2_samplerate != mh.group1_samplerate) {
- av_log(m->avctx, AV_LOG_ERROR,
- "Channel groups with differing sample rates are not currently supported.\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (mh.group1_samplerate == 0) {
- av_log(m->avctx, AV_LOG_ERROR, "invalid/unknown sampling rate\n");
- return AVERROR_INVALIDDATA;
- }
- if (mh.group1_samplerate > MAX_SAMPLERATE) {
- av_log(m->avctx, AV_LOG_ERROR,
- "Sampling rate %d is greater than the supported maximum (%d).\n",
- mh.group1_samplerate, MAX_SAMPLERATE);
- return AVERROR_INVALIDDATA;
- }
- if (mh.access_unit_size > MAX_BLOCKSIZE) {
- av_log(m->avctx, AV_LOG_ERROR,
- "Block size %d is greater than the supported maximum (%d).\n",
- mh.access_unit_size, MAX_BLOCKSIZE);
- return AVERROR_INVALIDDATA;
- }
- if (mh.access_unit_size_pow2 > MAX_BLOCKSIZE_POW2) {
- av_log(m->avctx, AV_LOG_ERROR,
- "Block size pow2 %d is greater than the supported maximum (%d).\n",
- mh.access_unit_size_pow2, MAX_BLOCKSIZE_POW2);
- return AVERROR_INVALIDDATA;
- }
-
- if (mh.num_substreams == 0)
- return AVERROR_INVALIDDATA;
- if (m->avctx->codec_id == AV_CODEC_ID_MLP && mh.num_substreams > 2) {
- av_log(m->avctx, AV_LOG_ERROR, "MLP only supports up to 2 substreams.\n");
- return AVERROR_INVALIDDATA;
- }
- if (mh.num_substreams > MAX_SUBSTREAMS) {
- avpriv_request_sample(m->avctx,
- "%d substreams (more than the "
- "maximum supported by the decoder)",
- mh.num_substreams);
- return AVERROR_PATCHWELCOME;
- }
-
- m->major_sync_header_size = mh.header_size;
-
- m->access_unit_size = mh.access_unit_size;
- m->access_unit_size_pow2 = mh.access_unit_size_pow2;
-
- m->num_substreams = mh.num_substreams;
-
- /* limit to decoding 3 substreams, as the 4th is used by Dolby Atmos for non-audio data */
- m->max_decoded_substream = FFMIN(m->num_substreams - 1, 2);
-
- m->avctx->sample_rate = mh.group1_samplerate;
- m->avctx->frame_size = mh.access_unit_size;
-
- m->avctx->bits_per_raw_sample = mh.group1_bits;
- if (mh.group1_bits > 16)
- m->avctx->sample_fmt = AV_SAMPLE_FMT_S32;
- else
- m->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
- m->dsp.mlp_pack_output = m->dsp.mlp_select_pack_output(m->substream[m->max_decoded_substream].ch_assign,
- m->substream[m->max_decoded_substream].output_shift,
- m->substream[m->max_decoded_substream].max_matrix_channel,
- m->avctx->sample_fmt == AV_SAMPLE_FMT_S32);
-
- m->params_valid = 1;
- for (substr = 0; substr < MAX_SUBSTREAMS; substr++)
- m->substream[substr].restart_seen = 0;
-
- /* Set the layout for each substream. When there's more than one, the first
- * substream is Stereo. Subsequent substreams' layouts are indicated in the
- * major sync. */
- if (m->avctx->codec_id == AV_CODEC_ID_MLP) {
- if (mh.stream_type != 0xbb) {
- avpriv_request_sample(m->avctx,
- "unexpected stream_type %X in MLP",
- mh.stream_type);
- return AVERROR_PATCHWELCOME;
- }
- if ((substr = (mh.num_substreams > 1)))
- m->substream[0].ch_layout = AV_CH_LAYOUT_STEREO;
- m->substream[substr].ch_layout = mh.channel_layout_mlp;
- } else {
- if (mh.stream_type != 0xba) {
- avpriv_request_sample(m->avctx,
- "unexpected stream_type %X in !MLP",
- mh.stream_type);
- return AVERROR_PATCHWELCOME;
- }
- if ((substr = (mh.num_substreams > 1)))
- m->substream[0].ch_layout = AV_CH_LAYOUT_STEREO;
- if (mh.num_substreams > 2)
- if (mh.channel_layout_thd_stream2)
- m->substream[2].ch_layout = mh.channel_layout_thd_stream2;
- else
- m->substream[2].ch_layout = mh.channel_layout_thd_stream1;
- m->substream[substr].ch_layout = mh.channel_layout_thd_stream1;
-
- if (m->avctx->channels<=2 && m->substream[substr].ch_layout == AV_CH_LAYOUT_MONO && m->max_decoded_substream == 1) {
- av_log(m->avctx, AV_LOG_DEBUG, "Mono stream with 2 substreams, ignoring 2nd\n");
- m->max_decoded_substream = 0;
- if (m->avctx->channels==2)
- m->avctx->channel_layout = AV_CH_LAYOUT_STEREO;
- }
- }
-
- m->needs_reordering = mh.channel_arrangement >= 18 && mh.channel_arrangement <= 20;
-
- /* Parse the TrueHD decoder channel modifiers and set each substream's
- * AVMatrixEncoding accordingly.
- *
- * The meaning of the modifiers depends on the channel layout:
- *
- * - THD_CH_MODIFIER_LTRT, THD_CH_MODIFIER_LBINRBIN only apply to 2-channel
- *
- * - THD_CH_MODIFIER_MONO applies to 1-channel or 2-channel (dual mono)
- *
- * - THD_CH_MODIFIER_SURROUNDEX, THD_CH_MODIFIER_NOTSURROUNDEX only apply to
- * layouts with an Ls/Rs channel pair
- */
- for (substr = 0; substr < MAX_SUBSTREAMS; substr++)
- m->substream[substr].matrix_encoding = AV_MATRIX_ENCODING_NONE;
- if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD) {
- if (mh.num_substreams > 2 &&
- mh.channel_layout_thd_stream2 & AV_CH_SIDE_LEFT &&
- mh.channel_layout_thd_stream2 & AV_CH_SIDE_RIGHT &&
- mh.channel_modifier_thd_stream2 == THD_CH_MODIFIER_SURROUNDEX)
- m->substream[2].matrix_encoding = AV_MATRIX_ENCODING_DOLBYEX;
-
- if (mh.num_substreams > 1 &&
- mh.channel_layout_thd_stream1 & AV_CH_SIDE_LEFT &&
- mh.channel_layout_thd_stream1 & AV_CH_SIDE_RIGHT &&
- mh.channel_modifier_thd_stream1 == THD_CH_MODIFIER_SURROUNDEX)
- m->substream[1].matrix_encoding = AV_MATRIX_ENCODING_DOLBYEX;
-
- if (mh.num_substreams > 0)
- switch (mh.channel_modifier_thd_stream0) {
- case THD_CH_MODIFIER_LTRT:
- m->substream[0].matrix_encoding = AV_MATRIX_ENCODING_DOLBY;
- break;
- case THD_CH_MODIFIER_LBINRBIN:
- m->substream[0].matrix_encoding = AV_MATRIX_ENCODING_DOLBYHEADPHONE;
- break;
- default:
- break;
- }
- }
-
- return 0;
-}
-
-/** Read a restart header from a block in a substream. This contains parameters
- * required to decode the audio that do not change very often. Generally
- * (always) present only in blocks following a major sync. */
-
-static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp,
- const uint8_t *buf, unsigned int substr)
-{
- SubStream *s = &m->substream[substr];
- unsigned int ch;
- int sync_word, tmp;
- uint8_t checksum;
- uint8_t lossless_check;
- int start_count = get_bits_count(gbp);
- int min_channel, max_channel, max_matrix_channel;
- const int std_max_matrix_channel = m->avctx->codec_id == AV_CODEC_ID_MLP
- ? MAX_MATRIX_CHANNEL_MLP
- : MAX_MATRIX_CHANNEL_TRUEHD;
-
- sync_word = get_bits(gbp, 13);
-
- if (sync_word != 0x31ea >> 1) {
- av_log(m->avctx, AV_LOG_ERROR,
- "restart header sync incorrect (got 0x%04x)\n", sync_word);
- return AVERROR_INVALIDDATA;
- }
-
- s->noise_type = get_bits1(gbp);
-
- if (m->avctx->codec_id == AV_CODEC_ID_MLP && s->noise_type) {
- av_log(m->avctx, AV_LOG_ERROR, "MLP must have 0x31ea sync word.\n");
- return AVERROR_INVALIDDATA;
- }
-
- skip_bits(gbp, 16); /* Output timestamp */
-
- min_channel = get_bits(gbp, 4);
- max_channel = get_bits(gbp, 4);
- max_matrix_channel = get_bits(gbp, 4);
-
- if (max_matrix_channel > std_max_matrix_channel) {
- av_log(m->avctx, AV_LOG_ERROR,
- "Max matrix channel cannot be greater than %d.\n",
- std_max_matrix_channel);
- return AVERROR_INVALIDDATA;
- }
-
- if (max_channel != max_matrix_channel) {
- av_log(m->avctx, AV_LOG_ERROR,
- "Max channel must be equal max matrix channel.\n");
- return AVERROR_INVALIDDATA;
- }
-
- /* This should happen for TrueHD streams with >6 channels and MLP's noise
- * type. It is not yet known if this is allowed. */
- if (max_channel > MAX_MATRIX_CHANNEL_MLP && !s->noise_type) {
- avpriv_request_sample(m->avctx,
- "%d channels (more than the "
- "maximum supported by the decoder)",
- max_channel + 2);
- return AVERROR_PATCHWELCOME;
- }
-
- if (min_channel > max_channel) {
- av_log(m->avctx, AV_LOG_ERROR,
- "Substream min channel cannot be greater than max channel.\n");
- return AVERROR_INVALIDDATA;
- }
-
- s->min_channel = min_channel;
- s->max_channel = max_channel;
- s->max_matrix_channel = max_matrix_channel;
-
-#if FF_API_REQUEST_CHANNELS
-FF_DISABLE_DEPRECATION_WARNINGS
- if (m->avctx->request_channels > 0 &&
- m->avctx->request_channels <= s->max_channel + 1 &&
- m->max_decoded_substream > substr) {
- av_log(m->avctx, AV_LOG_DEBUG,
- "Extracting %d-channel downmix from substream %d. "
- "Further substreams will be skipped.\n",
- s->max_channel + 1, substr);
- m->max_decoded_substream = substr;
-FF_ENABLE_DEPRECATION_WARNINGS
- } else
-#endif
- if (m->avctx->request_channel_layout && (s->ch_layout & m->avctx->request_channel_layout) ==
- m->avctx->request_channel_layout && m->max_decoded_substream > substr) {
- av_log(m->avctx, AV_LOG_DEBUG,
- "Extracting %d-channel downmix (0x%"PRIx64") from substream %d. "
- "Further substreams will be skipped.\n",
- s->max_channel + 1, s->ch_layout, substr);
- m->max_decoded_substream = substr;
- }
-
- s->noise_shift = get_bits(gbp, 4);
- s->noisegen_seed = get_bits(gbp, 23);
-
- skip_bits(gbp, 19);
-
- s->data_check_present = get_bits1(gbp);
- lossless_check = get_bits(gbp, 8);
- if (substr == m->max_decoded_substream
- && s->lossless_check_data != 0xffffffff) {
- tmp = xor_32_to_8(s->lossless_check_data);
- if (tmp != lossless_check)
- av_log(m->avctx, AV_LOG_WARNING,
- "Lossless check failed - expected %02x, calculated %02x.\n",
- lossless_check, tmp);
- }
-
- skip_bits(gbp, 16);
-
- memset(s->ch_assign, 0, sizeof(s->ch_assign));
-
- for (ch = 0; ch <= s->max_matrix_channel; ch++) {
- int ch_assign = get_bits(gbp, 6);
- if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD) {
- uint64_t channel = thd_channel_layout_extract_channel(s->ch_layout,
- ch_assign);
- ch_assign = av_get_channel_layout_channel_index(s->ch_layout,
- channel);
- }
- if (ch_assign < 0 || ch_assign > s->max_matrix_channel) {
- avpriv_request_sample(m->avctx,
- "Assignment of matrix channel %d to invalid output channel %d",
- ch, ch_assign);
- return AVERROR_PATCHWELCOME;
- }
- s->ch_assign[ch_assign] = ch;
- }
-
- checksum = ff_mlp_restart_checksum(buf, get_bits_count(gbp) - start_count);
-
- if (checksum != get_bits(gbp, 8))
- av_log(m->avctx, AV_LOG_ERROR, "restart header checksum error\n");
-
- /* Set default decoding parameters. */
- s->param_presence_flags = 0xff;
- s->num_primitive_matrices = 0;
- s->blocksize = 8;
- s->lossless_check_data = 0;
-
- memset(s->output_shift , 0, sizeof(s->output_shift ));
- memset(s->quant_step_size, 0, sizeof(s->quant_step_size));
-
- for (ch = s->min_channel; ch <= s->max_channel; ch++) {
- ChannelParams *cp = &s->channel_params[ch];
- cp->filter_params[FIR].order = 0;
- cp->filter_params[IIR].order = 0;
- cp->filter_params[FIR].shift = 0;
- cp->filter_params[IIR].shift = 0;
-
- /* Default audio coding is 24-bit raw PCM. */
- cp->huff_offset = 0;
- cp->sign_huff_offset = (-1) << 23;
- cp->codebook = 0;
- cp->huff_lsbs = 24;
- }
-
- if (substr == m->max_decoded_substream) {
- m->avctx->channels = s->max_matrix_channel + 1;
- m->avctx->channel_layout = s->ch_layout;
- m->dsp.mlp_pack_output = m->dsp.mlp_select_pack_output(s->ch_assign,
- s->output_shift,
- s->max_matrix_channel,
- m->avctx->sample_fmt == AV_SAMPLE_FMT_S32);
-
- if (m->avctx->codec_id == AV_CODEC_ID_MLP && m->needs_reordering) {
- if (m->avctx->channel_layout == (AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY) ||
- m->avctx->channel_layout == AV_CH_LAYOUT_5POINT0_BACK) {
- int i = s->ch_assign[4];
- s->ch_assign[4] = s->ch_assign[3];
- s->ch_assign[3] = s->ch_assign[2];
- s->ch_assign[2] = i;
- } else if (m->avctx->channel_layout == AV_CH_LAYOUT_5POINT1_BACK) {
- FFSWAP(int, s->ch_assign[2], s->ch_assign[4]);
- FFSWAP(int, s->ch_assign[3], s->ch_assign[5]);
- }
- }
-
- }
-
- return 0;
-}
-
-/** Read parameters for one of the prediction filters. */
-
-static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp,
- unsigned int substr, unsigned int channel,
- unsigned int filter)
-{
- SubStream *s = &m->substream[substr];
- FilterParams *fp = &s->channel_params[channel].filter_params[filter];
- const int max_order = filter ? MAX_IIR_ORDER : MAX_FIR_ORDER;
- const char fchar = filter ? 'I' : 'F';
- int i, order;
-
- // Filter is 0 for FIR, 1 for IIR.
- av_assert0(filter < 2);
-
- if (m->filter_changed[channel][filter]++ > 1) {
- av_log(m->avctx, AV_LOG_ERROR, "Filters may change only once per access unit.\n");
- return AVERROR_INVALIDDATA;
- }
-
- order = get_bits(gbp, 4);
- if (order > max_order) {
- av_log(m->avctx, AV_LOG_ERROR,
- "%cIR filter order %d is greater than maximum %d.\n",
- fchar, order, max_order);
- return AVERROR_INVALIDDATA;
- }
- fp->order = order;
-
- if (order > 0) {
- int32_t *fcoeff = s->channel_params[channel].coeff[filter];
- int coeff_bits, coeff_shift;
-
- fp->shift = get_bits(gbp, 4);
-
- coeff_bits = get_bits(gbp, 5);
- coeff_shift = get_bits(gbp, 3);
- if (coeff_bits < 1 || coeff_bits > 16) {
- av_log(m->avctx, AV_LOG_ERROR,
- "%cIR filter coeff_bits must be between 1 and 16.\n",
- fchar);
- return AVERROR_INVALIDDATA;
- }
- if (coeff_bits + coeff_shift > 16) {
- av_log(m->avctx, AV_LOG_ERROR,
- "Sum of coeff_bits and coeff_shift for %cIR filter must be 16 or less.\n",
- fchar);
- return AVERROR_INVALIDDATA;
- }
-
- for (i = 0; i < order; i++)
- fcoeff[i] = get_sbits(gbp, coeff_bits) << coeff_shift;
-
- if (get_bits1(gbp)) {
- int state_bits, state_shift;
-
- if (filter == FIR) {
- av_log(m->avctx, AV_LOG_ERROR,
- "FIR filter has state data specified.\n");
- return AVERROR_INVALIDDATA;
- }
-
- state_bits = get_bits(gbp, 4);
- state_shift = get_bits(gbp, 4);
-
- /* TODO: Check validity of state data. */
-
- for (i = 0; i < order; i++)
- fp->state[i] = state_bits ? get_sbits(gbp, state_bits) << state_shift : 0;
- }
- }
-
- return 0;
-}
-
-/** Read parameters for primitive matrices. */
-
-static int read_matrix_params(MLPDecodeContext *m, unsigned int substr, GetBitContext *gbp)
-{
- SubStream *s = &m->substream[substr];
- unsigned int mat, ch;
- const int max_primitive_matrices = m->avctx->codec_id == AV_CODEC_ID_MLP
- ? MAX_MATRICES_MLP
- : MAX_MATRICES_TRUEHD;
-
- if (m->matrix_changed++ > 1) {
- av_log(m->avctx, AV_LOG_ERROR, "Matrices may change only once per access unit.\n");
- return AVERROR_INVALIDDATA;
- }
-
- s->num_primitive_matrices = get_bits(gbp, 4);
-
- if (s->num_primitive_matrices > max_primitive_matrices) {
- av_log(m->avctx, AV_LOG_ERROR,
- "Number of primitive matrices cannot be greater than %d.\n",
- max_primitive_matrices);
- return AVERROR_INVALIDDATA;
- }
-
- for (mat = 0; mat < s->num_primitive_matrices; mat++) {
- int frac_bits, max_chan;
- s->matrix_out_ch[mat] = get_bits(gbp, 4);
- frac_bits = get_bits(gbp, 4);
- s->lsb_bypass [mat] = get_bits1(gbp);
-
- if (s->matrix_out_ch[mat] > s->max_matrix_channel) {
- av_log(m->avctx, AV_LOG_ERROR,
- "Invalid channel %d specified as output from matrix.\n",
- s->matrix_out_ch[mat]);
- return AVERROR_INVALIDDATA;
- }
- if (frac_bits > 14) {
- av_log(m->avctx, AV_LOG_ERROR,
- "Too many fractional bits specified.\n");
- return AVERROR_INVALIDDATA;
- }
-
- max_chan = s->max_matrix_channel;
- if (!s->noise_type)
- max_chan+=2;
-
- for (ch = 0; ch <= max_chan; ch++) {
- int coeff_val = 0;
- if (get_bits1(gbp))
- coeff_val = get_sbits(gbp, frac_bits + 2);
-
- s->matrix_coeff[mat][ch] = coeff_val << (14 - frac_bits);
- }
-
- if (s->noise_type)
- s->matrix_noise_shift[mat] = get_bits(gbp, 4);
- else
- s->matrix_noise_shift[mat] = 0;
- }
-
- return 0;
-}
-
-/** Read channel parameters. */
-
-static int read_channel_params(MLPDecodeContext *m, unsigned int substr,
- GetBitContext *gbp, unsigned int ch)
-{
- SubStream *s = &m->substream[substr];
- ChannelParams *cp = &s->channel_params[ch];
- FilterParams *fir = &cp->filter_params[FIR];
- FilterParams *iir = &cp->filter_params[IIR];
- int ret;
-
- if (s->param_presence_flags & PARAM_FIR)
- if (get_bits1(gbp))
- if ((ret = read_filter_params(m, gbp, substr, ch, FIR)) < 0)
- return ret;
-
- if (s->param_presence_flags & PARAM_IIR)
- if (get_bits1(gbp))
- if ((ret = read_filter_params(m, gbp, substr, ch, IIR)) < 0)
- return ret;
-
- if (fir->order + iir->order > 8) {
- av_log(m->avctx, AV_LOG_ERROR, "Total filter orders too high.\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (fir->order && iir->order &&
- fir->shift != iir->shift) {
- av_log(m->avctx, AV_LOG_ERROR,
- "FIR and IIR filters must use the same precision.\n");
- return AVERROR_INVALIDDATA;
- }
- /* The FIR and IIR filters must have the same precision.
- * To simplify the filtering code, only the precision of the
- * FIR filter is considered. If only the IIR filter is employed,
- * the FIR filter precision is set to that of the IIR filter, so
- * that the filtering code can use it. */
- if (!fir->order && iir->order)
- fir->shift = iir->shift;
-
- if (s->param_presence_flags & PARAM_HUFFOFFSET)
- if (get_bits1(gbp))
- cp->huff_offset = get_sbits(gbp, 15);
-
- cp->codebook = get_bits(gbp, 2);
- cp->huff_lsbs = get_bits(gbp, 5);
-
- if (cp->huff_lsbs > 24) {
- av_log(m->avctx, AV_LOG_ERROR, "Invalid huff_lsbs.\n");
- cp->huff_lsbs = 0;
- return AVERROR_INVALIDDATA;
- }
-
- cp->sign_huff_offset = calculate_sign_huff(m, substr, ch);
-
- return 0;
-}
-
-/** Read decoding parameters that change more often than those in the restart
- * header. */
-
-static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp,
- unsigned int substr)
-{
- SubStream *s = &m->substream[substr];
- unsigned int ch;
- int ret;
-
- if (s->param_presence_flags & PARAM_PRESENCE)
- if (get_bits1(gbp))
- s->param_presence_flags = get_bits(gbp, 8);
-
- if (s->param_presence_flags & PARAM_BLOCKSIZE)
- if (get_bits1(gbp)) {
- s->blocksize = get_bits(gbp, 9);
- if (s->blocksize < 8 || s->blocksize > m->access_unit_size) {
- av_log(m->avctx, AV_LOG_ERROR, "Invalid blocksize.\n");
- s->blocksize = 0;
- return AVERROR_INVALIDDATA;
- }
- }
-
- if (s->param_presence_flags & PARAM_MATRIX)
- if (get_bits1(gbp))
- if ((ret = read_matrix_params(m, substr, gbp)) < 0)
- return ret;
-
- if (s->param_presence_flags & PARAM_OUTSHIFT)
- if (get_bits1(gbp)) {
- for (ch = 0; ch <= s->max_matrix_channel; ch++)
- s->output_shift[ch] = get_sbits(gbp, 4);
- if (substr == m->max_decoded_substream)
- m->dsp.mlp_pack_output = m->dsp.mlp_select_pack_output(s->ch_assign,
- s->output_shift,
- s->max_matrix_channel,
- m->avctx->sample_fmt == AV_SAMPLE_FMT_S32);
- }
-
- if (s->param_presence_flags & PARAM_QUANTSTEP)
- if (get_bits1(gbp))
- for (ch = 0; ch <= s->max_channel; ch++) {
- ChannelParams *cp = &s->channel_params[ch];
-
- s->quant_step_size[ch] = get_bits(gbp, 4);
-
- cp->sign_huff_offset = calculate_sign_huff(m, substr, ch);
- }
-
- for (ch = s->min_channel; ch <= s->max_channel; ch++)
- if (get_bits1(gbp))
- if ((ret = read_channel_params(m, substr, gbp, ch)) < 0)
- return ret;
-
- return 0;
-}
-
-#define MSB_MASK(bits) (-1u << (bits))
-
-/** Generate PCM samples using the prediction filters and residual values
- * read from the data stream, and update the filter state. */
-
-static void filter_channel(MLPDecodeContext *m, unsigned int substr,
- unsigned int channel)
-{
- SubStream *s = &m->substream[substr];
- const int32_t *fircoeff = s->channel_params[channel].coeff[FIR];
- int32_t state_buffer[NUM_FILTERS][MAX_BLOCKSIZE + MAX_FIR_ORDER];
- int32_t *firbuf = state_buffer[FIR] + MAX_BLOCKSIZE;
- int32_t *iirbuf = state_buffer[IIR] + MAX_BLOCKSIZE;
- FilterParams *fir = &s->channel_params[channel].filter_params[FIR];
- FilterParams *iir = &s->channel_params[channel].filter_params[IIR];
- unsigned int filter_shift = fir->shift;
- int32_t mask = MSB_MASK(s->quant_step_size[channel]);
-
- memcpy(firbuf, fir->state, MAX_FIR_ORDER * sizeof(int32_t));
- memcpy(iirbuf, iir->state, MAX_IIR_ORDER * sizeof(int32_t));
-
- m->dsp.mlp_filter_channel(firbuf, fircoeff,
- fir->order, iir->order,
- filter_shift, mask, s->blocksize,
- &m->sample_buffer[s->blockpos][channel]);
-
- memcpy(fir->state, firbuf - s->blocksize, MAX_FIR_ORDER * sizeof(int32_t));
- memcpy(iir->state, iirbuf - s->blocksize, MAX_IIR_ORDER * sizeof(int32_t));
-}
-
-/** Read a block of PCM residual data (or actual if no filtering active). */
-
-static int read_block_data(MLPDecodeContext *m, GetBitContext *gbp,
- unsigned int substr)
-{
- SubStream *s = &m->substream[substr];
- unsigned int i, ch, expected_stream_pos = 0;
- int ret;
-
- if (s->data_check_present) {
- expected_stream_pos = get_bits_count(gbp);
- expected_stream_pos += get_bits(gbp, 16);
- avpriv_request_sample(m->avctx,
- "Substreams with VLC block size check info");
- }
-
- if (s->blockpos + s->blocksize > m->access_unit_size) {
- av_log(m->avctx, AV_LOG_ERROR, "too many audio samples in frame\n");
- return AVERROR_INVALIDDATA;
- }
-
- memset(&m->bypassed_lsbs[s->blockpos][0], 0,
- s->blocksize * sizeof(m->bypassed_lsbs[0]));
-
- for (i = 0; i < s->blocksize; i++)
- if ((ret = read_huff_channels(m, gbp, substr, i)) < 0)
- return ret;
-
- for (ch = s->min_channel; ch <= s->max_channel; ch++)
- filter_channel(m, substr, ch);
-
- s->blockpos += s->blocksize;
-
- if (s->data_check_present) {
- if (get_bits_count(gbp) != expected_stream_pos)
- av_log(m->avctx, AV_LOG_ERROR, "block data length mismatch\n");
- skip_bits(gbp, 8);
- }
-
- return 0;
-}
-
-/** Data table used for TrueHD noise generation function. */
-
-static const int8_t noise_table[256] = {
- 30, 51, 22, 54, 3, 7, -4, 38, 14, 55, 46, 81, 22, 58, -3, 2,
- 52, 31, -7, 51, 15, 44, 74, 30, 85, -17, 10, 33, 18, 80, 28, 62,
- 10, 32, 23, 69, 72, 26, 35, 17, 73, 60, 8, 56, 2, 6, -2, -5,
- 51, 4, 11, 50, 66, 76, 21, 44, 33, 47, 1, 26, 64, 48, 57, 40,
- 38, 16, -10, -28, 92, 22, -18, 29, -10, 5, -13, 49, 19, 24, 70, 34,
- 61, 48, 30, 14, -6, 25, 58, 33, 42, 60, 67, 17, 54, 17, 22, 30,
- 67, 44, -9, 50, -11, 43, 40, 32, 59, 82, 13, 49, -14, 55, 60, 36,
- 48, 49, 31, 47, 15, 12, 4, 65, 1, 23, 29, 39, 45, -2, 84, 69,
- 0, 72, 37, 57, 27, 41, -15, -16, 35, 31, 14, 61, 24, 0, 27, 24,
- 16, 41, 55, 34, 53, 9, 56, 12, 25, 29, 53, 5, 20, -20, -8, 20,
- 13, 28, -3, 78, 38, 16, 11, 62, 46, 29, 21, 24, 46, 65, 43, -23,
- 89, 18, 74, 21, 38, -12, 19, 12, -19, 8, 15, 33, 4, 57, 9, -8,
- 36, 35, 26, 28, 7, 83, 63, 79, 75, 11, 3, 87, 37, 47, 34, 40,
- 39, 19, 20, 42, 27, 34, 39, 77, 13, 42, 59, 64, 45, -1, 32, 37,
- 45, -5, 53, -6, 7, 36, 50, 23, 6, 32, 9, -21, 18, 71, 27, 52,
- -25, 31, 35, 42, -1, 68, 63, 52, 26, 43, 66, 37, 41, 25, 40, 70,
-};
-
-/** Noise generation functions.
- * I'm not sure what these are for - they seem to be some kind of pseudorandom
- * sequence generators, used to generate noise data which is used when the
- * channels are rematrixed. I'm not sure if they provide a practical benefit
- * to compression, or just obfuscate the decoder. Are they for some kind of
- * dithering? */
-
-/** Generate two channels of noise, used in the matrix when
- * restart sync word == 0x31ea. */
-
-static void generate_2_noise_channels(MLPDecodeContext *m, unsigned int substr)
-{
- SubStream *s = &m->substream[substr];
- unsigned int i;
- uint32_t seed = s->noisegen_seed;
- unsigned int maxchan = s->max_matrix_channel;
-
- for (i = 0; i < s->blockpos; i++) {
- uint16_t seed_shr7 = seed >> 7;
- m->sample_buffer[i][maxchan+1] = ((int8_t)(seed >> 15)) << s->noise_shift;
- m->sample_buffer[i][maxchan+2] = ((int8_t) seed_shr7) << s->noise_shift;
-
- seed = (seed << 16) ^ seed_shr7 ^ (seed_shr7 << 5);
- }
-
- s->noisegen_seed = seed;
-}
-
-/** Generate a block of noise, used when restart sync word == 0x31eb. */
-
-static void fill_noise_buffer(MLPDecodeContext *m, unsigned int substr)
-{
- SubStream *s = &m->substream[substr];
- unsigned int i;
- uint32_t seed = s->noisegen_seed;
-
- for (i = 0; i < m->access_unit_size_pow2; i++) {
- uint8_t seed_shr15 = seed >> 15;
- m->noise_buffer[i] = noise_table[seed_shr15];
- seed = (seed << 8) ^ seed_shr15 ^ (seed_shr15 << 5);
- }
-
- s->noisegen_seed = seed;
-}
-
-/** Write the audio data into the output buffer. */
-
-static int output_data(MLPDecodeContext *m, unsigned int substr,
- AVFrame *frame, int *got_frame_ptr)
-{
- AVCodecContext *avctx = m->avctx;
- SubStream *s = &m->substream[substr];
- unsigned int mat;
- unsigned int maxchan;
- int ret;
- int is32 = (m->avctx->sample_fmt == AV_SAMPLE_FMT_S32);
-
- if (m->avctx->channels != s->max_matrix_channel + 1) {
- av_log(m->avctx, AV_LOG_ERROR, "channel count mismatch\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (!s->blockpos) {
- av_log(avctx, AV_LOG_ERROR, "No samples to output.\n");
- return AVERROR_INVALIDDATA;
- }
-
- maxchan = s->max_matrix_channel;
- if (!s->noise_type) {
- generate_2_noise_channels(m, substr);
- maxchan += 2;
- } else {
- fill_noise_buffer(m, substr);
- }
-
- /* Apply the channel matrices in turn to reconstruct the original audio
- * samples. */
- for (mat = 0; mat < s->num_primitive_matrices; mat++) {
- unsigned int dest_ch = s->matrix_out_ch[mat];
- m->dsp.mlp_rematrix_channel(&m->sample_buffer[0][0],
- s->matrix_coeff[mat],
- &m->bypassed_lsbs[0][mat],
- m->noise_buffer,
- s->num_primitive_matrices - mat,
- dest_ch,
- s->blockpos,
- maxchan,
- s->matrix_noise_shift[mat],
- m->access_unit_size_pow2,
- MSB_MASK(s->quant_step_size[dest_ch]));
- }
-
- /* get output buffer */
- frame->nb_samples = s->blockpos;
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
- s->lossless_check_data = m->dsp.mlp_pack_output(s->lossless_check_data,
- s->blockpos,
- m->sample_buffer,
- frame->data[0],
- s->ch_assign,
- s->output_shift,
- s->max_matrix_channel,
- is32);
-
- /* Update matrix encoding side data */
- if ((ret = ff_side_data_update_matrix_encoding(frame, s->matrix_encoding)) < 0)
- return ret;
-
- *got_frame_ptr = 1;
-
- return 0;
-}
-
-/** Read an access unit from the stream.
- * @return negative on error, 0 if not enough data is present in the input stream,
- * otherwise the number of bytes consumed. */
-
-static int read_access_unit(AVCodecContext *avctx, void* data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- MLPDecodeContext *m = avctx->priv_data;
- GetBitContext gb;
- unsigned int length, substr;
- unsigned int substream_start;
- unsigned int header_size = 4;
- unsigned int substr_header_size = 0;
- uint8_t substream_parity_present[MAX_SUBSTREAMS];
- uint16_t substream_data_len[MAX_SUBSTREAMS];
- uint8_t parity_bits;
- int ret;
-
- if (buf_size < 4)
- return AVERROR_INVALIDDATA;
-
- length = (AV_RB16(buf) & 0xfff) * 2;
-
- if (length < 4 || length > buf_size)
- return AVERROR_INVALIDDATA;
-
- init_get_bits(&gb, (buf + 4), (length - 4) * 8);
-
- m->is_major_sync_unit = 0;
- if (show_bits_long(&gb, 31) == (0xf8726fba >> 1)) {
- if (read_major_sync(m, &gb) < 0)
- goto error;
- m->is_major_sync_unit = 1;
- header_size += m->major_sync_header_size;
- }
-
- if (!m->params_valid) {
- av_log(m->avctx, AV_LOG_WARNING,
- "Stream parameters not seen; skipping frame.\n");
- *got_frame_ptr = 0;
- return length;
- }
-
- substream_start = 0;
-
- for (substr = 0; substr < m->num_substreams; substr++) {
- int extraword_present, checkdata_present, end, nonrestart_substr;
-
- extraword_present = get_bits1(&gb);
- nonrestart_substr = get_bits1(&gb);
- checkdata_present = get_bits1(&gb);
- skip_bits1(&gb);
-
- end = get_bits(&gb, 12) * 2;
-
- substr_header_size += 2;
-
- if (extraword_present) {
- if (m->avctx->codec_id == AV_CODEC_ID_MLP) {
- av_log(m->avctx, AV_LOG_ERROR, "There must be no extraword for MLP.\n");
- goto error;
- }
- skip_bits(&gb, 16);
- substr_header_size += 2;
- }
-
- if (!(nonrestart_substr ^ m->is_major_sync_unit)) {
- av_log(m->avctx, AV_LOG_ERROR, "Invalid nonrestart_substr.\n");
- goto error;
- }
-
- if (end + header_size + substr_header_size > length) {
- av_log(m->avctx, AV_LOG_ERROR,
- "Indicated length of substream %d data goes off end of "
- "packet.\n", substr);
- end = length - header_size - substr_header_size;
- }
-
- if (end < substream_start) {
- av_log(avctx, AV_LOG_ERROR,
- "Indicated end offset of substream %d data "
- "is smaller than calculated start offset.\n",
- substr);
- goto error;
- }
-
- if (substr > m->max_decoded_substream)
- continue;
-
- substream_parity_present[substr] = checkdata_present;
- substream_data_len[substr] = end - substream_start;
- substream_start = end;
- }
-
- parity_bits = ff_mlp_calculate_parity(buf, 4);
- parity_bits ^= ff_mlp_calculate_parity(buf + header_size, substr_header_size);
-
- if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) {
- av_log(avctx, AV_LOG_ERROR, "Parity check failed.\n");
- goto error;
- }
-
- buf += header_size + substr_header_size;
-
- for (substr = 0; substr <= m->max_decoded_substream; substr++) {
- SubStream *s = &m->substream[substr];
- init_get_bits(&gb, buf, substream_data_len[substr] * 8);
-
- m->matrix_changed = 0;
- memset(m->filter_changed, 0, sizeof(m->filter_changed));
-
- s->blockpos = 0;
- do {
- if (get_bits1(&gb)) {
- if (get_bits1(&gb)) {
- /* A restart header should be present. */
- if (read_restart_header(m, &gb, buf, substr) < 0)
- goto next_substr;
- s->restart_seen = 1;
- }
-
- if (!s->restart_seen)
- goto next_substr;
- if (read_decoding_params(m, &gb, substr) < 0)
- goto next_substr;
- }
-
- if (!s->restart_seen)
- goto next_substr;
-
- if ((ret = read_block_data(m, &gb, substr)) < 0)
- return ret;
-
- if (get_bits_count(&gb) >= substream_data_len[substr] * 8)
- goto substream_length_mismatch;
-
- } while (!get_bits1(&gb));
-
- skip_bits(&gb, (-get_bits_count(&gb)) & 15);
-
- if (substream_data_len[substr] * 8 - get_bits_count(&gb) >= 32) {
- int shorten_by;
-
- if (get_bits(&gb, 16) != 0xD234)
- return AVERROR_INVALIDDATA;
-
- shorten_by = get_bits(&gb, 16);
- if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD && shorten_by & 0x2000)
- s->blockpos -= FFMIN(shorten_by & 0x1FFF, s->blockpos);
- else if (m->avctx->codec_id == AV_CODEC_ID_MLP && shorten_by != 0xD234)
- return AVERROR_INVALIDDATA;
-
- if (substr == m->max_decoded_substream)
- av_log(m->avctx, AV_LOG_INFO, "End of stream indicated.\n");
- }
-
- if (substream_parity_present[substr]) {
- uint8_t parity, checksum;
-
- if (substream_data_len[substr] * 8 - get_bits_count(&gb) != 16)
- goto substream_length_mismatch;
-
- parity = ff_mlp_calculate_parity(buf, substream_data_len[substr] - 2);
- checksum = ff_mlp_checksum8 (buf, substream_data_len[substr] - 2);
-
- if ((get_bits(&gb, 8) ^ parity) != 0xa9 )
- av_log(m->avctx, AV_LOG_ERROR, "Substream %d parity check failed.\n", substr);
- if ( get_bits(&gb, 8) != checksum)
- av_log(m->avctx, AV_LOG_ERROR, "Substream %d checksum failed.\n" , substr);
- }
-
- if (substream_data_len[substr] * 8 != get_bits_count(&gb))
- goto substream_length_mismatch;
-
-next_substr:
- if (!s->restart_seen)
- av_log(m->avctx, AV_LOG_ERROR,
- "No restart header present in substream %d.\n", substr);
-
- buf += substream_data_len[substr];
- }
-
- if ((ret = output_data(m, m->max_decoded_substream, data, got_frame_ptr)) < 0)
- return ret;
-
- return length;
-
-substream_length_mismatch:
- av_log(m->avctx, AV_LOG_ERROR, "substream %d length mismatch\n", substr);
- return AVERROR_INVALIDDATA;
-
-error:
- m->params_valid = 0;
- return AVERROR_INVALIDDATA;
-}
-
-#if CONFIG_MLP_DECODER
-AVCodec ff_mlp_decoder = {
- .name = "mlp",
- .long_name = NULL_IF_CONFIG_SMALL("MLP (Meridian Lossless Packing)"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_MLP,
- .priv_data_size = sizeof(MLPDecodeContext),
- .init = mlp_decode_init,
- .decode = read_access_unit,
- .capabilities = AV_CODEC_CAP_DR1,
-};
-#endif
-#if CONFIG_TRUEHD_DECODER
-AVCodec ff_truehd_decoder = {
- .name = "truehd",
- .long_name = NULL_IF_CONFIG_SMALL("TrueHD"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_TRUEHD,
- .priv_data_size = sizeof(MLPDecodeContext),
- .init = mlp_decode_init,
- .decode = read_access_unit,
- .capabilities = AV_CODEC_CAP_DR1,
-};
-#endif /* CONFIG_TRUEHD_DECODER */
diff --git a/ffmpeg-2-8-11/libavcodec/mlpdsp.c b/ffmpeg-2-8-11/libavcodec/mlpdsp.c
deleted file mode 100644
index 3ae8c37..0000000
--- a/ffmpeg-2-8-11/libavcodec/mlpdsp.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2007-2008 Ian Caulfield
- * 2009 Ramiro Polla
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-#include "libavutil/attributes.h"
-#include "mlpdsp.h"
-#include "mlp.h"
-
-static void mlp_filter_channel(int32_t *state, const int32_t *coeff,
- int firorder, int iirorder,
- unsigned int filter_shift, int32_t mask,
- int blocksize, int32_t *sample_buffer)
-{
- int32_t *firbuf = state;
- int32_t *iirbuf = state + MAX_BLOCKSIZE + MAX_FIR_ORDER;
- const int32_t *fircoeff = coeff;
- const int32_t *iircoeff = coeff + MAX_FIR_ORDER;
- int i;
-
- for (i = 0; i < blocksize; i++) {
- int32_t residual = *sample_buffer;
- unsigned int order;
- int64_t accum = 0;
- int32_t result;
-
- for (order = 0; order < firorder; order++)
- accum += (int64_t) firbuf[order] * fircoeff[order];
- for (order = 0; order < iirorder; order++)
- accum += (int64_t) iirbuf[order] * iircoeff[order];
-
- accum = accum >> filter_shift;
- result = (accum + residual) & mask;
-
- *--firbuf = result;
- *--iirbuf = result - accum;
-
- *sample_buffer = result;
- sample_buffer += MAX_CHANNELS;
- }
-}
-
-void ff_mlp_rematrix_channel(int32_t *samples,
- const int32_t *coeffs,
- const uint8_t *bypassed_lsbs,
- const int8_t *noise_buffer,
- int index,
- unsigned int dest_ch,
- uint16_t blockpos,
- unsigned int maxchan,
- int matrix_noise_shift,
- int access_unit_size_pow2,
- int32_t mask)
-{
- unsigned int src_ch, i;
- int index2 = 2 * index + 1;
- for (i = 0; i < blockpos; i++) {
- int64_t accum = 0;
-
- for (src_ch = 0; src_ch <= maxchan; src_ch++)
- accum += (int64_t) samples[src_ch] * coeffs[src_ch];
-
- if (matrix_noise_shift) {
- index &= access_unit_size_pow2 - 1;
- accum += noise_buffer[index] << (matrix_noise_shift + 7);
- index += index2;
- }
-
- samples[dest_ch] = ((accum >> 14) & mask) + *bypassed_lsbs;
- bypassed_lsbs += MAX_CHANNELS;
- samples += MAX_CHANNELS;
- }
-}
-
-static int32_t (*mlp_select_pack_output(uint8_t *ch_assign,
- int8_t *output_shift,
- uint8_t max_matrix_channel,
- int is32))(int32_t, uint16_t, int32_t (*)[], void *, uint8_t*, int8_t *, uint8_t, int)
-{
- return ff_mlp_pack_output;
-}
-
-int32_t ff_mlp_pack_output(int32_t lossless_check_data,
- uint16_t blockpos,
- int32_t (*sample_buffer)[MAX_CHANNELS],
- void *data,
- uint8_t *ch_assign,
- int8_t *output_shift,
- uint8_t max_matrix_channel,
- int is32)
-{
- unsigned int i, out_ch = 0;
- int32_t *data_32 = data;
- int16_t *data_16 = data;
-
- for (i = 0; i < blockpos; i++) {
- for (out_ch = 0; out_ch <= max_matrix_channel; out_ch++) {
- int mat_ch = ch_assign[out_ch];
- int32_t sample = sample_buffer[i][mat_ch]
- << output_shift[mat_ch];
- lossless_check_data ^= (sample & 0xffffff) << mat_ch;
- if (is32)
- *data_32++ = sample << 8;
- else
- *data_16++ = sample >> 8;
- }
- }
- return lossless_check_data;
-}
-
-av_cold void ff_mlpdsp_init(MLPDSPContext *c)
-{
- c->mlp_filter_channel = mlp_filter_channel;
- c->mlp_rematrix_channel = ff_mlp_rematrix_channel;
- c->mlp_select_pack_output = mlp_select_pack_output;
- c->mlp_pack_output = ff_mlp_pack_output;
- if (ARCH_ARM)
- ff_mlpdsp_init_arm(c);
- if (ARCH_X86)
- ff_mlpdsp_init_x86(c);
-}
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg12dec.c b/ffmpeg-2-8-11/libavcodec/mpeg12dec.c
deleted file mode 100644
index c457ec8..0000000
--- a/ffmpeg-2-8-11/libavcodec/mpeg12dec.c
+++ /dev/null
@@ -1,2992 +0,0 @@
-/*
- * MPEG-1/2 decoder
- * Copyright (c) 2000, 2001 Fabrice Bellard
- * Copyright (c) 2002-2013 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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-1/2 decoder
- */
-
-#define UNCHECKED_BITSTREAM_READER 1
-#include <inttypes.h>
-
-#include "libavutil/attributes.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/internal.h"
-#include "libavutil/stereo3d.h"
-
-#include "avcodec.h"
-#include "bytestream.h"
-#include "error_resilience.h"
-#include "idctdsp.h"
-#include "internal.h"
-#include "mpeg_er.h"
-#include "mpeg12.h"
-#include "mpeg12data.h"
-#include "mpegutils.h"
-#include "mpegvideo.h"
-#include "mpegvideodata.h"
-#include "thread.h"
-#include "version.h"
-#include "vdpau_compat.h"
-#include "xvmc_internal.h"
-
-typedef struct Mpeg1Context {
- MpegEncContext mpeg_enc_ctx;
- int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
- int repeat_field; /* true if we must repeat the field */
- AVPanScan pan_scan; /* some temporary storage for the panscan */
- AVStereo3D stereo3d;
- int has_stereo3d;
- uint8_t *a53_caption;
- int a53_caption_size;
- uint8_t afd;
- int has_afd;
- int slice_count;
- AVRational save_aspect;
- int save_width, save_height, save_progressive_seq;
- AVRational frame_rate_ext; /* MPEG-2 specific framerate modificator */
- int sync; /* Did we reach a sync point like a GOP/SEQ/KEYFrame? */
- int tmpgexs;
- int first_slice;
- int extradata_decoded;
-} Mpeg1Context;
-
-#define MB_TYPE_ZERO_MV 0x20000000
-
-static const uint32_t ptype2mb_type[7] = {
- MB_TYPE_INTRA,
- MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
- MB_TYPE_L0,
- MB_TYPE_L0 | MB_TYPE_CBP,
- MB_TYPE_QUANT | MB_TYPE_INTRA,
- MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
- MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP,
-};
-
-static const uint32_t btype2mb_type[11] = {
- MB_TYPE_INTRA,
- MB_TYPE_L1,
- MB_TYPE_L1 | MB_TYPE_CBP,
- MB_TYPE_L0,
- MB_TYPE_L0 | MB_TYPE_CBP,
- MB_TYPE_L0L1,
- MB_TYPE_L0L1 | MB_TYPE_CBP,
- MB_TYPE_QUANT | MB_TYPE_INTRA,
- MB_TYPE_QUANT | MB_TYPE_L1 | MB_TYPE_CBP,
- MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP,
- MB_TYPE_QUANT | MB_TYPE_L0L1 | MB_TYPE_CBP,
-};
-
-static const uint8_t non_linear_qscale[32] = {
- 0, 1, 2, 3, 4, 5, 6, 7,
- 8, 10, 12, 14, 16, 18, 20, 22,
- 24, 28, 32, 36, 40, 44, 48, 52,
- 56, 64, 72, 80, 88, 96, 104, 112,
-};
-
-/* as H.263, but only 17 codes */
-static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred)
-{
- int code, sign, val, shift;
-
- code = get_vlc2(&s->gb, ff_mv_vlc.table, MV_VLC_BITS, 2);
- if (code == 0)
- return pred;
- if (code < 0)
- return 0xffff;
-
- sign = get_bits1(&s->gb);
- shift = fcode - 1;
- val = code;
- if (shift) {
- val = (val - 1) << shift;
- val |= get_bits(&s->gb, shift);
- val++;
- }
- if (sign)
- val = -val;
- val += pred;
-
- /* modulo decoding */
- return sign_extend(val, 5 + shift);
-}
-
-#define check_scantable_index(ctx, x) \
- do { \
- if ((x) > 63) { \
- av_log(ctx->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", \
- ctx->mb_x, ctx->mb_y); \
- return AVERROR_INVALIDDATA; \
- } \
- } while (0)
-
-static inline int mpeg1_decode_block_intra(MpegEncContext *s,
- int16_t *block, int n)
-{
- int level, dc, diff, i, j, run;
- int component;
- RLTable *rl = &ff_rl_mpeg1;
- uint8_t *const scantable = s->intra_scantable.permutated;
- const uint16_t *quant_matrix = s->intra_matrix;
- const int qscale = s->qscale;
-
- /* DC coefficient */
- component = (n <= 3 ? 0 : n - 4 + 1);
- diff = decode_dc(&s->gb, component);
- if (diff >= 0xffff)
- return AVERROR_INVALIDDATA;
- dc = s->last_dc[component];
- dc += diff;
- s->last_dc[component] = dc;
- block[0] = dc * quant_matrix[0];
- ff_tlog(s->avctx, "dc=%d diff=%d\n", dc, diff);
- i = 0;
- {
- OPEN_READER(re, &s->gb);
- UPDATE_CACHE(re, &s->gb);
- if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
- goto end;
-
- /* now quantify & encode AC coefficients */
- for (;;) {
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0],
- TEX_VLC_BITS, 2, 0);
-
- if (level != 0) {
- i += run;
- check_scantable_index(s, i);
- j = scantable[i];
- level = (level * qscale * quant_matrix[j]) >> 4;
- level = (level - 1) | 1;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
- SHOW_SBITS(re, &s->gb, 1);
- SKIP_BITS(re, &s->gb, 1);
- } else {
- /* escape */
- run = SHOW_UBITS(re, &s->gb, 6) + 1;
- LAST_SKIP_BITS(re, &s->gb, 6);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 8);
- SKIP_BITS(re, &s->gb, 8);
- if (level == -128) {
- level = SHOW_UBITS(re, &s->gb, 8) - 256;
- SKIP_BITS(re, &s->gb, 8);
- } else if (level == 0) {
- level = SHOW_UBITS(re, &s->gb, 8);
- SKIP_BITS(re, &s->gb, 8);
- }
- i += run;
- check_scantable_index(s, i);
- j = scantable[i];
- if (level < 0) {
- level = -level;
- level = (level * qscale * quant_matrix[j]) >> 4;
- level = (level - 1) | 1;
- level = -level;
- } else {
- level = (level * qscale * quant_matrix[j]) >> 4;
- level = (level - 1) | 1;
- }
- }
-
- block[j] = level;
- if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
- break;
-
- UPDATE_CACHE(re, &s->gb);
- }
-end:
- LAST_SKIP_BITS(re, &s->gb, 2);
- CLOSE_READER(re, &s->gb);
- }
- s->block_last_index[n] = i;
- return 0;
-}
-
-int ff_mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
-{
- return mpeg1_decode_block_intra(s, block, n);
-}
-
-static inline int mpeg1_decode_block_inter(MpegEncContext *s,
- int16_t *block, int n)
-{
- int level, i, j, run;
- RLTable *rl = &ff_rl_mpeg1;
- uint8_t *const scantable = s->intra_scantable.permutated;
- const uint16_t *quant_matrix = s->inter_matrix;
- const int qscale = s->qscale;
-
- {
- OPEN_READER(re, &s->gb);
- i = -1;
- // special case for first coefficient, no need to add second VLC table
- UPDATE_CACHE(re, &s->gb);
- if (((int32_t) GET_CACHE(re, &s->gb)) < 0) {
- level = (3 * qscale * quant_matrix[0]) >> 5;
- level = (level - 1) | 1;
- if (GET_CACHE(re, &s->gb) & 0x40000000)
- level = -level;
- block[0] = level;
- i++;
- SKIP_BITS(re, &s->gb, 2);
- if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF)
- goto end;
- }
- /* now quantify & encode AC coefficients */
- for (;;) {
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0],
- TEX_VLC_BITS, 2, 0);
-
- if (level != 0) {
- i += run;
- check_scantable_index(s, i);
- j = scantable[i];
- level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
- level = (level - 1) | 1;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
- SHOW_SBITS(re, &s->gb, 1);
- SKIP_BITS(re, &s->gb, 1);
- } else {
- /* escape */
- run = SHOW_UBITS(re, &s->gb, 6) + 1;
- LAST_SKIP_BITS(re, &s->gb, 6);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 8);
- SKIP_BITS(re, &s->gb, 8);
- if (level == -128) {
- level = SHOW_UBITS(re, &s->gb, 8) - 256;
- SKIP_BITS(re, &s->gb, 8);
- } else if (level == 0) {
- level = SHOW_UBITS(re, &s->gb, 8);
- SKIP_BITS(re, &s->gb, 8);
- }
- i += run;
- check_scantable_index(s, i);
- j = scantable[i];
- if (level < 0) {
- level = -level;
- level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
- level = (level - 1) | 1;
- level = -level;
- } else {
- level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
- level = (level - 1) | 1;
- }
- }
-
- block[j] = level;
- if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF)
- break;
- UPDATE_CACHE(re, &s->gb);
- }
-end:
- LAST_SKIP_BITS(re, &s->gb, 2);
- CLOSE_READER(re, &s->gb);
- }
- s->block_last_index[n] = i;
- return 0;
-}
-
-/**
- * Note: this function can read out of range and crash for corrupt streams.
- * Changing this would eat up any speed benefits it has.
- * Do not use "fast" flag if you need the code to be robust.
- */
-static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s,
- int16_t *block, int n)
-{
- int level, i, j, run;
- RLTable *rl = &ff_rl_mpeg1;
- uint8_t *const scantable = s->intra_scantable.permutated;
- const int qscale = s->qscale;
-
- {
- OPEN_READER(re, &s->gb);
- i = -1;
- // Special case for first coefficient, no need to add second VLC table.
- UPDATE_CACHE(re, &s->gb);
- if (((int32_t) GET_CACHE(re, &s->gb)) < 0) {
- level = (3 * qscale) >> 1;
- level = (level - 1) | 1;
- if (GET_CACHE(re, &s->gb) & 0x40000000)
- level = -level;
- block[0] = level;
- i++;
- SKIP_BITS(re, &s->gb, 2);
- if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF)
- goto end;
- }
-
- /* now quantify & encode AC coefficients */
- for (;;) {
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0],
- TEX_VLC_BITS, 2, 0);
-
- if (level != 0) {
- i += run;
- check_scantable_index(s, i);
- j = scantable[i];
- level = ((level * 2 + 1) * qscale) >> 1;
- level = (level - 1) | 1;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
- SHOW_SBITS(re, &s->gb, 1);
- SKIP_BITS(re, &s->gb, 1);
- } else {
- /* escape */
- run = SHOW_UBITS(re, &s->gb, 6) + 1;
- LAST_SKIP_BITS(re, &s->gb, 6);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 8);
- SKIP_BITS(re, &s->gb, 8);
- if (level == -128) {
- level = SHOW_UBITS(re, &s->gb, 8) - 256;
- SKIP_BITS(re, &s->gb, 8);
- } else if (level == 0) {
- level = SHOW_UBITS(re, &s->gb, 8);
- SKIP_BITS(re, &s->gb, 8);
- }
- i += run;
- check_scantable_index(s, i);
- j = scantable[i];
- if (level < 0) {
- level = -level;
- level = ((level * 2 + 1) * qscale) >> 1;
- level = (level - 1) | 1;
- level = -level;
- } else {
- level = ((level * 2 + 1) * qscale) >> 1;
- level = (level - 1) | 1;
- }
- }
-
- block[j] = level;
- if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF)
- break;
- UPDATE_CACHE(re, &s->gb);
- }
-end:
- LAST_SKIP_BITS(re, &s->gb, 2);
- CLOSE_READER(re, &s->gb);
- }
- s->block_last_index[n] = i;
- return 0;
-}
-
-static inline int mpeg2_decode_block_non_intra(MpegEncContext *s,
- int16_t *block, int n)
-{
- int level, i, j, run;
- RLTable *rl = &ff_rl_mpeg1;
- uint8_t *const scantable = s->intra_scantable.permutated;
- const uint16_t *quant_matrix;
- const int qscale = s->qscale;
- int mismatch;
-
- mismatch = 1;
-
- {
- OPEN_READER(re, &s->gb);
- i = -1;
- if (n < 4)
- quant_matrix = s->inter_matrix;
- else
- quant_matrix = s->chroma_inter_matrix;
-
- // Special case for first coefficient, no need to add second VLC table.
- UPDATE_CACHE(re, &s->gb);
- if (((int32_t) GET_CACHE(re, &s->gb)) < 0) {
- level = (3 * qscale * quant_matrix[0]) >> 5;
- if (GET_CACHE(re, &s->gb) & 0x40000000)
- level = -level;
- block[0] = level;
- mismatch ^= level;
- i++;
- SKIP_BITS(re, &s->gb, 2);
- if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF)
- goto end;
- }
-
- /* now quantify & encode AC coefficients */
- for (;;) {
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0],
- TEX_VLC_BITS, 2, 0);
-
- if (level != 0) {
- i += run;
- check_scantable_index(s, i);
- j = scantable[i];
- level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
- SHOW_SBITS(re, &s->gb, 1);
- SKIP_BITS(re, &s->gb, 1);
- } else {
- /* escape */
- run = SHOW_UBITS(re, &s->gb, 6) + 1;
- LAST_SKIP_BITS(re, &s->gb, 6);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 12);
- SKIP_BITS(re, &s->gb, 12);
-
- i += run;
- check_scantable_index(s, i);
- j = scantable[i];
- if (level < 0) {
- level = ((-level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
- level = -level;
- } else {
- level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
- }
- }
-
- mismatch ^= level;
- block[j] = level;
- if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF)
- break;
- UPDATE_CACHE(re, &s->gb);
- }
-end:
- LAST_SKIP_BITS(re, &s->gb, 2);
- CLOSE_READER(re, &s->gb);
- }
- block[63] ^= (mismatch & 1);
-
- s->block_last_index[n] = i;
- return 0;
-}
-
-/**
- * Note: this function can read out of range and crash for corrupt streams.
- * Changing this would eat up any speed benefits it has.
- * Do not use "fast" flag if you need the code to be robust.
- */
-static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s,
- int16_t *block, int n)
-{
- int level, i, j, run;
- RLTable *rl = &ff_rl_mpeg1;
- uint8_t *const scantable = s->intra_scantable.permutated;
- const int qscale = s->qscale;
- OPEN_READER(re, &s->gb);
- i = -1;
-
- // special case for first coefficient, no need to add second VLC table
- UPDATE_CACHE(re, &s->gb);
- if (((int32_t) GET_CACHE(re, &s->gb)) < 0) {
- level = (3 * qscale) >> 1;
- if (GET_CACHE(re, &s->gb) & 0x40000000)
- level = -level;
- block[0] = level;
- i++;
- SKIP_BITS(re, &s->gb, 2);
- if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF)
- goto end;
- }
-
- /* now quantify & encode AC coefficients */
- for (;;) {
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
-
- if (level != 0) {
- i += run;
- j = scantable[i];
- level = ((level * 2 + 1) * qscale) >> 1;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
- SHOW_SBITS(re, &s->gb, 1);
- SKIP_BITS(re, &s->gb, 1);
- } else {
- /* escape */
- run = SHOW_UBITS(re, &s->gb, 6) + 1;
- LAST_SKIP_BITS(re, &s->gb, 6);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 12);
- SKIP_BITS(re, &s->gb, 12);
-
- i += run;
- j = scantable[i];
- if (level < 0) {
- level = ((-level * 2 + 1) * qscale) >> 1;
- level = -level;
- } else {
- level = ((level * 2 + 1) * qscale) >> 1;
- }
- }
-
- block[j] = level;
- if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF || i > 63)
- break;
-
- UPDATE_CACHE(re, &s->gb);
- }
-end:
- LAST_SKIP_BITS(re, &s->gb, 2);
- CLOSE_READER(re, &s->gb);
- s->block_last_index[n] = i;
- return 0;
-}
-
-static inline int mpeg2_decode_block_intra(MpegEncContext *s,
- int16_t *block, int n)
-{
- int level, dc, diff, i, j, run;
- int component;
- RLTable *rl;
- uint8_t *const scantable = s->intra_scantable.permutated;
- const uint16_t *quant_matrix;
- const int qscale = s->qscale;
- int mismatch;
-
- /* DC coefficient */
- if (n < 4) {
- quant_matrix = s->intra_matrix;
- component = 0;
- } else {
- quant_matrix = s->chroma_intra_matrix;
- component = (n & 1) + 1;
- }
- diff = decode_dc(&s->gb, component);
- if (diff >= 0xffff)
- return AVERROR_INVALIDDATA;
- dc = s->last_dc[component];
- dc += diff;
- s->last_dc[component] = dc;
- block[0] = dc << (3 - s->intra_dc_precision);
- ff_tlog(s->avctx, "dc=%d\n", block[0]);
- mismatch = block[0] ^ 1;
- i = 0;
- if (s->intra_vlc_format)
- rl = &ff_rl_mpeg2;
- else
- rl = &ff_rl_mpeg1;
-
- {
- OPEN_READER(re, &s->gb);
- /* now quantify & encode AC coefficients */
- for (;;) {
- UPDATE_CACHE(re, &s->gb);
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0],
- TEX_VLC_BITS, 2, 0);
-
- if (level == 127) {
- break;
- } else if (level != 0) {
- i += run;
- check_scantable_index(s, i);
- j = scantable[i];
- level = (level * qscale * quant_matrix[j]) >> 4;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
- SHOW_SBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
- } else {
- /* escape */
- run = SHOW_UBITS(re, &s->gb, 6) + 1;
- LAST_SKIP_BITS(re, &s->gb, 6);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 12);
- SKIP_BITS(re, &s->gb, 12);
- i += run;
- check_scantable_index(s, i);
- j = scantable[i];
- if (level < 0) {
- level = (-level * qscale * quant_matrix[j]) >> 4;
- level = -level;
- } else {
- level = (level * qscale * quant_matrix[j]) >> 4;
- }
- }
-
- mismatch ^= level;
- block[j] = level;
- }
- CLOSE_READER(re, &s->gb);
- }
- block[63] ^= mismatch & 1;
-
- s->block_last_index[n] = i;
- return 0;
-}
-
-/**
- * Note: this function can read out of range and crash for corrupt streams.
- * Changing this would eat up any speed benefits it has.
- * Do not use "fast" flag if you need the code to be robust.
- */
-static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s,
- int16_t *block, int n)
-{
- int level, dc, diff, i, j, run;
- int component;
- RLTable *rl;
- uint8_t *const scantable = s->intra_scantable.permutated;
- const uint16_t *quant_matrix;
- const int qscale = s->qscale;
-
- /* DC coefficient */
- if (n < 4) {
- quant_matrix = s->intra_matrix;
- component = 0;
- } else {
- quant_matrix = s->chroma_intra_matrix;
- component = (n & 1) + 1;
- }
- diff = decode_dc(&s->gb, component);
- if (diff >= 0xffff)
- return AVERROR_INVALIDDATA;
- dc = s->last_dc[component];
- dc += diff;
- s->last_dc[component] = dc;
- block[0] = dc << (3 - s->intra_dc_precision);
- i = 0;
- if (s->intra_vlc_format)
- rl = &ff_rl_mpeg2;
- else
- rl = &ff_rl_mpeg1;
-
- {
- OPEN_READER(re, &s->gb);
- /* now quantify & encode AC coefficients */
- for (;;) {
- UPDATE_CACHE(re, &s->gb);
- GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0],
- TEX_VLC_BITS, 2, 0);
-
- if (level >= 64 || i > 63) {
- break;
- } else if (level != 0) {
- i += run;
- j = scantable[i];
- level = (level * qscale * quant_matrix[j]) >> 4;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
- SHOW_SBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
- } else {
- /* escape */
- run = SHOW_UBITS(re, &s->gb, 6) + 1;
- LAST_SKIP_BITS(re, &s->gb, 6);
- UPDATE_CACHE(re, &s->gb);
- level = SHOW_SBITS(re, &s->gb, 12);
- SKIP_BITS(re, &s->gb, 12);
- i += run;
- j = scantable[i];
- if (level < 0) {
- level = (-level * qscale * quant_matrix[j]) >> 4;
- level = -level;
- } else {
- level = (level * qscale * quant_matrix[j]) >> 4;
- }
- }
-
- block[j] = level;
- }
- CLOSE_READER(re, &s->gb);
- }
-
- s->block_last_index[n] = i;
- return 0;
-}
-
-/******************************************/
-/* decoding */
-
-static inline int get_dmv(MpegEncContext *s)
-{
- if (get_bits1(&s->gb))
- return 1 - (get_bits1(&s->gb) << 1);
- else
- return 0;
-}
-
-static inline int get_qscale(MpegEncContext *s)
-{
- int qscale = get_bits(&s->gb, 5);
- if (s->q_scale_type)
- return non_linear_qscale[qscale];
- else
- return qscale << 1;
-}
-
-
-/* motion type (for MPEG-2) */
-#define MT_FIELD 1
-#define MT_FRAME 2
-#define MT_16X8 2
-#define MT_DMV 3
-
-static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
-{
- int i, j, k, cbp, val, mb_type, motion_type;
- const int mb_block_count = 4 + (1 << s->chroma_format);
- int ret;
-
- ff_tlog(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);
-
- av_assert2(s->mb_skipped == 0);
-
- if (s->mb_skip_run-- != 0) {
- if (s->pict_type == AV_PICTURE_TYPE_P) {
- s->mb_skipped = 1;
- s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] =
- MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
- } else {
- int mb_type;
-
- if (s->mb_x)
- mb_type = s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1];
- else
- // FIXME not sure if this is allowed in MPEG at all
- mb_type = s->current_picture.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1];
- if (IS_INTRA(mb_type)) {
- av_log(s->avctx, AV_LOG_ERROR, "skip with previntra\n");
- return AVERROR_INVALIDDATA;
- }
- s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] =
- mb_type | MB_TYPE_SKIP;
-
- if ((s->mv[0][0][0] | s->mv[0][0][1] | s->mv[1][0][0] | s->mv[1][0][1]) == 0)
- s->mb_skipped = 1;
- }
-
- return 0;
- }
-
- switch (s->pict_type) {
- default:
- case AV_PICTURE_TYPE_I:
- if (get_bits1(&s->gb) == 0) {
- if (get_bits1(&s->gb) == 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "invalid mb type in I Frame at %d %d\n",
- s->mb_x, s->mb_y);
- return AVERROR_INVALIDDATA;
- }
- mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA;
- } else {
- mb_type = MB_TYPE_INTRA;
- }
- break;
- case AV_PICTURE_TYPE_P:
- mb_type = get_vlc2(&s->gb, ff_mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1);
- if (mb_type < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y);
- return AVERROR_INVALIDDATA;
- }
- mb_type = ptype2mb_type[mb_type];
- break;
- case AV_PICTURE_TYPE_B:
- mb_type = get_vlc2(&s->gb, ff_mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1);
- if (mb_type < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y);
- return AVERROR_INVALIDDATA;
- }
- mb_type = btype2mb_type[mb_type];
- break;
- }
- ff_tlog(s->avctx, "mb_type=%x\n", mb_type);
-// motion_type = 0; /* avoid warning */
- if (IS_INTRA(mb_type)) {
- s->bdsp.clear_blocks(s->block[0]);
-
- if (!s->chroma_y_shift)
- s->bdsp.clear_blocks(s->block[6]);
-
- /* compute DCT type */
- // FIXME: add an interlaced_dct coded var?
- if (s->picture_structure == PICT_FRAME &&
- !s->frame_pred_frame_dct)
- s->interlaced_dct = get_bits1(&s->gb);
-
- if (IS_QUANT(mb_type))
- s->qscale = get_qscale(s);
-
- if (s->concealment_motion_vectors) {
- /* just parse them */
- if (s->picture_structure != PICT_FRAME)
- skip_bits1(&s->gb); /* field select */
-
- s->mv[0][0][0] =
- s->last_mv[0][0][0] =
- s->last_mv[0][1][0] = mpeg_decode_motion(s, s->mpeg_f_code[0][0],
- s->last_mv[0][0][0]);
- s->mv[0][0][1] =
- s->last_mv[0][0][1] =
- s->last_mv[0][1][1] = mpeg_decode_motion(s, s->mpeg_f_code[0][1],
- s->last_mv[0][0][1]);
-
- check_marker(&s->gb, "after concealment_motion_vectors");
- } else {
- /* reset mv prediction */
- memset(s->last_mv, 0, sizeof(s->last_mv));
- }
- s->mb_intra = 1;
- // if 1, we memcpy blocks in xvmcvideo
- if ((CONFIG_MPEG1_XVMC_HWACCEL || CONFIG_MPEG2_XVMC_HWACCEL) && s->pack_pblocks)
- ff_xvmc_pack_pblocks(s, -1); // inter are always full blocks
-
- if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
- if (s->avctx->flags2 & AV_CODEC_FLAG2_FAST) {
- for (i = 0; i < 6; i++)
- mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i);
- } else {
- for (i = 0; i < mb_block_count; i++)
- if ((ret = mpeg2_decode_block_intra(s, *s->pblocks[i], i)) < 0)
- return ret;
- }
- } else {
- for (i = 0; i < 6; i++)
- if ((ret = mpeg1_decode_block_intra(s, *s->pblocks[i], i)) < 0)
- return ret;
- }
- } else {
- if (mb_type & MB_TYPE_ZERO_MV) {
- av_assert2(mb_type & MB_TYPE_CBP);
-
- s->mv_dir = MV_DIR_FORWARD;
- if (s->picture_structure == PICT_FRAME) {
- if (s->picture_structure == PICT_FRAME
- && !s->frame_pred_frame_dct)
- s->interlaced_dct = get_bits1(&s->gb);
- s->mv_type = MV_TYPE_16X16;
- } else {
- s->mv_type = MV_TYPE_FIELD;
- mb_type |= MB_TYPE_INTERLACED;
- s->field_select[0][0] = s->picture_structure - 1;
- }
-
- if (IS_QUANT(mb_type))
- s->qscale = get_qscale(s);
-
- s->last_mv[0][0][0] = 0;
- s->last_mv[0][0][1] = 0;
- s->last_mv[0][1][0] = 0;
- s->last_mv[0][1][1] = 0;
- s->mv[0][0][0] = 0;
- s->mv[0][0][1] = 0;
- } else {
- av_assert2(mb_type & MB_TYPE_L0L1);
- // FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED
- /* get additional motion vector type */
- if (s->picture_structure == PICT_FRAME && s->frame_pred_frame_dct) {
- motion_type = MT_FRAME;
- } else {
- motion_type = get_bits(&s->gb, 2);
- if (s->picture_structure == PICT_FRAME && HAS_CBP(mb_type))
- s->interlaced_dct = get_bits1(&s->gb);
- }
-
- if (IS_QUANT(mb_type))
- s->qscale = get_qscale(s);
-
- /* motion vectors */
- s->mv_dir = (mb_type >> 13) & 3;
- ff_tlog(s->avctx, "motion_type=%d\n", motion_type);
- switch (motion_type) {
- case MT_FRAME: /* or MT_16X8 */
- if (s->picture_structure == PICT_FRAME) {
- mb_type |= MB_TYPE_16x16;
- s->mv_type = MV_TYPE_16X16;
- for (i = 0; i < 2; i++) {
- if (USES_LIST(mb_type, i)) {
- /* MT_FRAME */
- s->mv[i][0][0] =
- s->last_mv[i][0][0] =
- s->last_mv[i][1][0] =
- mpeg_decode_motion(s, s->mpeg_f_code[i][0],
- s->last_mv[i][0][0]);
- s->mv[i][0][1] =
- s->last_mv[i][0][1] =
- s->last_mv[i][1][1] =
- mpeg_decode_motion(s, s->mpeg_f_code[i][1],
- s->last_mv[i][0][1]);
- /* full_pel: only for MPEG-1 */
- if (s->full_pel[i]) {
- s->mv[i][0][0] <<= 1;
- s->mv[i][0][1] <<= 1;
- }
- }
- }
- } else {
- mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
- s->mv_type = MV_TYPE_16X8;
- for (i = 0; i < 2; i++) {
- if (USES_LIST(mb_type, i)) {
- /* MT_16X8 */
- for (j = 0; j < 2; j++) {
- s->field_select[i][j] = get_bits1(&s->gb);
- for (k = 0; k < 2; k++) {
- val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
- s->last_mv[i][j][k]);
- s->last_mv[i][j][k] = val;
- s->mv[i][j][k] = val;
- }
- }
- }
- }
- }
- break;
- case MT_FIELD:
- s->mv_type = MV_TYPE_FIELD;
- if (s->picture_structure == PICT_FRAME) {
- mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
- for (i = 0; i < 2; i++) {
- if (USES_LIST(mb_type, i)) {
- for (j = 0; j < 2; j++) {
- s->field_select[i][j] = get_bits1(&s->gb);
- val = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
- s->last_mv[i][j][0]);
- s->last_mv[i][j][0] = val;
- s->mv[i][j][0] = val;
- ff_tlog(s->avctx, "fmx=%d\n", val);
- val = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
- s->last_mv[i][j][1] >> 1);
- s->last_mv[i][j][1] = 2 * val;
- s->mv[i][j][1] = val;
- ff_tlog(s->avctx, "fmy=%d\n", val);
- }
- }
- }
- } else {
- av_assert0(!s->progressive_sequence);
- mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
- for (i = 0; i < 2; i++) {
- if (USES_LIST(mb_type, i)) {
- s->field_select[i][0] = get_bits1(&s->gb);
- for (k = 0; k < 2; k++) {
- val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
- s->last_mv[i][0][k]);
- s->last_mv[i][0][k] = val;
- s->last_mv[i][1][k] = val;
- s->mv[i][0][k] = val;
- }
- }
- }
- }
- break;
- case MT_DMV:
- if (s->progressive_sequence){
- av_log(s->avctx, AV_LOG_ERROR, "MT_DMV in progressive_sequence\n");
- return AVERROR_INVALIDDATA;
- }
- s->mv_type = MV_TYPE_DMV;
- for (i = 0; i < 2; i++) {
- if (USES_LIST(mb_type, i)) {
- int dmx, dmy, mx, my, m;
- const int my_shift = s->picture_structure == PICT_FRAME;
-
- mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
- s->last_mv[i][0][0]);
- s->last_mv[i][0][0] = mx;
- s->last_mv[i][1][0] = mx;
- dmx = get_dmv(s);
- my = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
- s->last_mv[i][0][1] >> my_shift);
- dmy = get_dmv(s);
-
-
- s->last_mv[i][0][1] = my << my_shift;
- s->last_mv[i][1][1] = my << my_shift;
-
- s->mv[i][0][0] = mx;
- s->mv[i][0][1] = my;
- s->mv[i][1][0] = mx; // not used
- s->mv[i][1][1] = my; // not used
-
- if (s->picture_structure == PICT_FRAME) {
- mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
-
- // m = 1 + 2 * s->top_field_first;
- m = s->top_field_first ? 1 : 3;
-
- /* top -> top pred */
- s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
- s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1;
- m = 4 - m;
- s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
- s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1;
- } else {
- mb_type |= MB_TYPE_16x16;
-
- s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx;
- s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy;
- if (s->picture_structure == PICT_TOP_FIELD)
- s->mv[i][2][1]--;
- else
- s->mv[i][2][1]++;
- }
- }
- }
- break;
- default:
- av_log(s->avctx, AV_LOG_ERROR,
- "00 motion_type at %d %d\n", s->mb_x, s->mb_y);
- return AVERROR_INVALIDDATA;
- }
- }
-
- s->mb_intra = 0;
- if (HAS_CBP(mb_type)) {
- s->bdsp.clear_blocks(s->block[0]);
-
- cbp = get_vlc2(&s->gb, ff_mb_pat_vlc.table, MB_PAT_VLC_BITS, 1);
- if (mb_block_count > 6) {
- cbp <<= mb_block_count - 6;
- cbp |= get_bits(&s->gb, mb_block_count - 6);
- s->bdsp.clear_blocks(s->block[6]);
- }
- if (cbp <= 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "invalid cbp %d at %d %d\n", cbp, s->mb_x, s->mb_y);
- return AVERROR_INVALIDDATA;
- }
-
- // if 1, we memcpy blocks in xvmcvideo
- if ((CONFIG_MPEG1_XVMC_HWACCEL || CONFIG_MPEG2_XVMC_HWACCEL) && s->pack_pblocks)
- ff_xvmc_pack_pblocks(s, cbp);
-
- if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
- if (s->avctx->flags2 & AV_CODEC_FLAG2_FAST) {
- for (i = 0; i < 6; i++) {
- if (cbp & 32)
- mpeg2_fast_decode_block_non_intra(s, *s->pblocks[i], i);
- else
- s->block_last_index[i] = -1;
- cbp += cbp;
- }
- } else {
- cbp <<= 12 - mb_block_count;
-
- for (i = 0; i < mb_block_count; i++) {
- if (cbp & (1 << 11)) {
- if ((ret = mpeg2_decode_block_non_intra(s, *s->pblocks[i], i)) < 0)
- return ret;
- } else {
- s->block_last_index[i] = -1;
- }
- cbp += cbp;
- }
- }
- } else {
- if (s->avctx->flags2 & AV_CODEC_FLAG2_FAST) {
- for (i = 0; i < 6; i++) {
- if (cbp & 32)
- mpeg1_fast_decode_block_inter(s, *s->pblocks[i], i);
- else
- s->block_last_index[i] = -1;
- cbp += cbp;
- }
- } else {
- for (i = 0; i < 6; i++) {
- if (cbp & 32) {
- if ((ret = mpeg1_decode_block_inter(s, *s->pblocks[i], i)) < 0)
- return ret;
- } else {
- s->block_last_index[i] = -1;
- }
- cbp += cbp;
- }
- }
- }
- } else {
- for (i = 0; i < 12; i++)
- s->block_last_index[i] = -1;
- }
- }
-
- s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] = mb_type;
-
- return 0;
-}
-
-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);
- ff_mpeg12_common_init(&s->mpeg_enc_ctx);
- ff_mpeg12_init_vlcs();
-
- s->mpeg_enc_ctx_allocated = 0;
- s->mpeg_enc_ctx.picture_number = 0;
- s->repeat_field = 0;
- s->mpeg_enc_ctx.codec_id = avctx->codec->id;
- avctx->color_range = AVCOL_RANGE_MPEG;
- return 0;
-}
-
-static int mpeg_decode_update_thread_context(AVCodecContext *avctx,
- const AVCodecContext *avctx_from)
-{
- Mpeg1Context *ctx = avctx->priv_data, *ctx_from = avctx_from->priv_data;
- MpegEncContext *s = &ctx->mpeg_enc_ctx, *s1 = &ctx_from->mpeg_enc_ctx;
- int err;
-
- if (avctx == avctx_from ||
- !ctx_from->mpeg_enc_ctx_allocated ||
- !s1->context_initialized)
- return 0;
-
- err = ff_mpeg_update_thread_context(avctx, avctx_from);
- if (err)
- return err;
-
- if (!ctx->mpeg_enc_ctx_allocated)
- memcpy(s + 1, s1 + 1, sizeof(Mpeg1Context) - sizeof(MpegEncContext));
-
- if (!(s->pict_type == AV_PICTURE_TYPE_B || s->low_delay))
- s->picture_number++;
-
- return 0;
-}
-
-static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm,
- const uint8_t *new_perm)
-{
- uint16_t temp_matrix[64];
- int i;
-
- memcpy(temp_matrix, matrix, 64 * sizeof(uint16_t));
-
- for (i = 0; i < 64; i++)
- matrix[new_perm[i]] = temp_matrix[old_perm[i]];
-}
-
-static const enum AVPixelFormat mpeg1_hwaccel_pixfmt_list_420[] = {
-#if CONFIG_MPEG1_XVMC_HWACCEL
- AV_PIX_FMT_XVMC,
-#endif
-#if CONFIG_MPEG1_VDPAU_DECODER && FF_API_VDPAU
- AV_PIX_FMT_VDPAU_MPEG1,
-#endif
-#if CONFIG_MPEG1_VDPAU_HWACCEL
- AV_PIX_FMT_VDPAU,
-#endif
- AV_PIX_FMT_YUV420P,
- AV_PIX_FMT_NONE
-};
-
-static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = {
-#if CONFIG_MPEG2_XVMC_HWACCEL
- AV_PIX_FMT_XVMC,
-#endif
-#if CONFIG_MPEG_VDPAU_DECODER && FF_API_VDPAU
- AV_PIX_FMT_VDPAU_MPEG2,
-#endif
-#if CONFIG_MPEG2_VDPAU_HWACCEL
- AV_PIX_FMT_VDPAU,
-#endif
-#if CONFIG_MPEG2_DXVA2_HWACCEL
- AV_PIX_FMT_DXVA2_VLD,
-#endif
-#if CONFIG_MPEG2_D3D11VA_HWACCEL
- AV_PIX_FMT_D3D11VA_VLD,
-#endif
-#if CONFIG_MPEG2_VAAPI_HWACCEL
- AV_PIX_FMT_VAAPI,
-#endif
-#if CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL
- AV_PIX_FMT_VIDEOTOOLBOX,
-#endif
- AV_PIX_FMT_YUV420P,
- AV_PIX_FMT_NONE
-};
-
-static const enum AVPixelFormat mpeg12_pixfmt_list_422[] = {
- AV_PIX_FMT_YUV422P,
- AV_PIX_FMT_NONE
-};
-
-static const enum AVPixelFormat mpeg12_pixfmt_list_444[] = {
- AV_PIX_FMT_YUV444P,
- AV_PIX_FMT_NONE
-};
-
-#if FF_API_VDPAU
-static inline int uses_vdpau(AVCodecContext *avctx) {
- return avctx->pix_fmt == AV_PIX_FMT_VDPAU_MPEG1 || avctx->pix_fmt == AV_PIX_FMT_VDPAU_MPEG2;
-}
-#endif
-
-static enum AVPixelFormat mpeg_get_pixelformat(AVCodecContext *avctx)
-{
- Mpeg1Context *s1 = avctx->priv_data;
- MpegEncContext *s = &s1->mpeg_enc_ctx;
- const enum AVPixelFormat *pix_fmts;
-
- if (CONFIG_GRAY && (avctx->flags & AV_CODEC_FLAG_GRAY))
- return AV_PIX_FMT_GRAY8;
-
- if (s->chroma_format < 2)
- pix_fmts = avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO ?
- mpeg1_hwaccel_pixfmt_list_420 :
- mpeg2_hwaccel_pixfmt_list_420;
- else if (s->chroma_format == 2)
- pix_fmts = mpeg12_pixfmt_list_422;
- else
- pix_fmts = mpeg12_pixfmt_list_444;
-
- return ff_thread_get_format(avctx, pix_fmts);
-}
-
-static void setup_hwaccel_for_pixfmt(AVCodecContext *avctx)
-{
- // until then pix_fmt may be changed right after codec init
- if (avctx->hwaccel
-#if FF_API_VDPAU
- || uses_vdpau(avctx)
-#endif
- )
- if (avctx->idct_algo == FF_IDCT_AUTO)
- avctx->idct_algo = FF_IDCT_SIMPLE;
-
- if (avctx->hwaccel && avctx->pix_fmt == AV_PIX_FMT_XVMC) {
- Mpeg1Context *s1 = avctx->priv_data;
- MpegEncContext *s = &s1->mpeg_enc_ctx;
-
- s->pack_pblocks = 1;
-#if FF_API_XVMC
-FF_DISABLE_DEPRECATION_WARNINGS
- avctx->xvmc_acceleration = 2;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif /* FF_API_XVMC */
- }
-}
-
-/* Call this function when we know all parameters.
- * It may be called in different places for MPEG-1 and MPEG-2. */
-static int mpeg_decode_postinit(AVCodecContext *avctx)
-{
- Mpeg1Context *s1 = avctx->priv_data;
- MpegEncContext *s = &s1->mpeg_enc_ctx;
- uint8_t old_permutation[64];
- int ret;
-
- if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
- // MPEG-1 aspect
- avctx->sample_aspect_ratio = av_d2q(1.0 / ff_mpeg1_aspect[s->aspect_ratio_info], 255);
- } else { // MPEG-2
- // MPEG-2 aspect
- if (s->aspect_ratio_info > 1) {
- AVRational dar =
- av_mul_q(av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
- (AVRational) { s1->pan_scan.width,
- s1->pan_scan.height }),
- (AVRational) { s->width, s->height });
-
- /* We ignore the spec here and guess a bit as reality does not
- * match the spec, see for example res_change_ffmpeg_aspect.ts
- * and sequence-display-aspect.mpg.
- * issue1613, 621, 562 */
- if ((s1->pan_scan.width == 0) || (s1->pan_scan.height == 0) ||
- (av_cmp_q(dar, (AVRational) { 4, 3 }) &&
- av_cmp_q(dar, (AVRational) { 16, 9 }))) {
- s->avctx->sample_aspect_ratio =
- av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
- (AVRational) { s->width, s->height });
- } else {
- s->avctx->sample_aspect_ratio =
- av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
- (AVRational) { s1->pan_scan.width, s1->pan_scan.height });
-// issue1613 4/3 16/9 -> 16/9
-// res_change_ffmpeg_aspect.ts 4/3 225/44 ->4/3
-// widescreen-issue562.mpg 4/3 16/9 -> 16/9
-// s->avctx->sample_aspect_ratio = av_mul_q(s->avctx->sample_aspect_ratio, (AVRational) {s->width, s->height});
- ff_dlog(avctx, "aspect A %d/%d\n",
- ff_mpeg2_aspect[s->aspect_ratio_info].num,
- ff_mpeg2_aspect[s->aspect_ratio_info].den);
- ff_dlog(avctx, "aspect B %d/%d\n", s->avctx->sample_aspect_ratio.num,
- s->avctx->sample_aspect_ratio.den);
- }
- } else {
- s->avctx->sample_aspect_ratio =
- ff_mpeg2_aspect[s->aspect_ratio_info];
- }
- } // MPEG-2
-
- if (av_image_check_sar(s->width, s->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 ((s1->mpeg_enc_ctx_allocated == 0) ||
- avctx->coded_width != s->width ||
- avctx->coded_height != s->height ||
- s1->save_width != s->width ||
- s1->save_height != s->height ||
- av_cmp_q(s1->save_aspect, s->avctx->sample_aspect_ratio) ||
- (s1->save_progressive_seq != s->progressive_sequence && FFALIGN(s->height, 16) != FFALIGN(s->height, 32)) ||
- 0) {
- if (s1->mpeg_enc_ctx_allocated) {
- ParseContext pc = s->parse_context;
- s->parse_context.buffer = 0;
- ff_mpv_common_end(s);
- s->parse_context = pc;
- s1->mpeg_enc_ctx_allocated = 0;
- }
-
- ret = ff_set_dimensions(avctx, s->width, s->height);
- if (ret < 0)
- return ret;
-
- if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->bit_rate) {
- avctx->rc_max_rate = s->bit_rate;
- } else if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && s->bit_rate &&
- (s->bit_rate != 0x3FFFF*400 || s->vbv_delay != 0xFFFF)) {
- avctx->bit_rate = s->bit_rate;
- }
- s1->save_aspect = s->avctx->sample_aspect_ratio;
- s1->save_width = s->width;
- s1->save_height = s->height;
- s1->save_progressive_seq = s->progressive_sequence;
-
- /* low_delay may be forced, in this case we will have B-frames
- * that behave like P-frames. */
- avctx->has_b_frames = !s->low_delay;
-
- if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
- // MPEG-1 fps
- avctx->framerate = ff_mpeg12_frame_rate_tab[s->frame_rate_index];
- avctx->ticks_per_frame = 1;
-
- avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
- } else { // MPEG-2
- // MPEG-2 fps
- av_reduce(&s->avctx->framerate.num,
- &s->avctx->framerate.den,
- ff_mpeg12_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num,
- ff_mpeg12_frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den,
- 1 << 30);
- avctx->ticks_per_frame = 2;
-
- switch (s->chroma_format) {
- case 1: avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; break;
- case 2:
- case 3: avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; break;
- default: av_assert0(0);
- }
- } // MPEG-2
-
- avctx->pix_fmt = mpeg_get_pixelformat(avctx);
- setup_hwaccel_for_pixfmt(avctx);
-
- /* Quantization matrices may need reordering
- * if DCT permutation is changed. */
- memcpy(old_permutation, s->idsp.idct_permutation, 64 * sizeof(uint8_t));
-
- ff_mpv_idct_init(s);
- if ((ret = ff_mpv_common_init(s)) < 0)
- return ret;
-
- quant_matrix_rebuild(s->intra_matrix, old_permutation, s->idsp.idct_permutation);
- quant_matrix_rebuild(s->inter_matrix, old_permutation, s->idsp.idct_permutation);
- quant_matrix_rebuild(s->chroma_intra_matrix, old_permutation, s->idsp.idct_permutation);
- quant_matrix_rebuild(s->chroma_inter_matrix, old_permutation, s->idsp.idct_permutation);
-
- s1->mpeg_enc_ctx_allocated = 1;
- }
- return 0;
-}
-
-static int mpeg1_decode_picture(AVCodecContext *avctx, const uint8_t *buf,
- int buf_size)
-{
- Mpeg1Context *s1 = avctx->priv_data;
- MpegEncContext *s = &s1->mpeg_enc_ctx;
- int ref, f_code, vbv_delay;
-
- init_get_bits(&s->gb, buf, buf_size * 8);
-
- ref = get_bits(&s->gb, 10); /* temporal ref */
- s->pict_type = get_bits(&s->gb, 3);
- if (s->pict_type == 0 || s->pict_type > 3)
- return AVERROR_INVALIDDATA;
-
- vbv_delay = get_bits(&s->gb, 16);
- s->vbv_delay = vbv_delay;
- if (s->pict_type == AV_PICTURE_TYPE_P ||
- s->pict_type == AV_PICTURE_TYPE_B) {
- s->full_pel[0] = get_bits1(&s->gb);
- f_code = get_bits(&s->gb, 3);
- if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)))
- return AVERROR_INVALIDDATA;
- f_code += !f_code;
- s->mpeg_f_code[0][0] = f_code;
- s->mpeg_f_code[0][1] = f_code;
- }
- if (s->pict_type == AV_PICTURE_TYPE_B) {
- s->full_pel[1] = get_bits1(&s->gb);
- f_code = get_bits(&s->gb, 3);
- if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)))
- return AVERROR_INVALIDDATA;
- f_code += !f_code;
- s->mpeg_f_code[1][0] = f_code;
- s->mpeg_f_code[1][1] = f_code;
- }
- s->current_picture.f->pict_type = s->pict_type;
- s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I;
-
- if (avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(avctx, AV_LOG_DEBUG,
- "vbv_delay %d, ref %d type:%d\n", vbv_delay, ref, s->pict_type);
-
- s->y_dc_scale = 8;
- s->c_dc_scale = 8;
- return 0;
-}
-
-static void mpeg_decode_sequence_extension(Mpeg1Context *s1)
-{
- MpegEncContext *s = &s1->mpeg_enc_ctx;
- int horiz_size_ext, vert_size_ext;
- int bit_rate_ext;
-
- skip_bits(&s->gb, 1); /* profile and level esc*/
- s->avctx->profile = get_bits(&s->gb, 3);
- s->avctx->level = get_bits(&s->gb, 4);
- s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */
- s->chroma_format = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */
-
- if (!s->chroma_format) {
- s->chroma_format = 1;
- av_log(s->avctx, AV_LOG_WARNING, "Chroma format invalid\n");
- }
-
- horiz_size_ext = get_bits(&s->gb, 2);
- vert_size_ext = get_bits(&s->gb, 2);
- s->width |= (horiz_size_ext << 12);
- s->height |= (vert_size_ext << 12);
- bit_rate_ext = get_bits(&s->gb, 12); /* XXX: handle it */
- s->bit_rate += (bit_rate_ext << 18) * 400LL;
- check_marker(&s->gb, "after bit rate extension");
- s->avctx->rc_buffer_size += get_bits(&s->gb, 8) * 1024 * 16 << 10;
-
- s->low_delay = get_bits1(&s->gb);
- if (s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY)
- s->low_delay = 1;
-
- s1->frame_rate_ext.num = get_bits(&s->gb, 2) + 1;
- s1->frame_rate_ext.den = get_bits(&s->gb, 5) + 1;
-
- ff_dlog(s->avctx, "sequence extension\n");
- s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
-
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_DEBUG,
- "profile: %d, level: %d ps: %d cf:%d vbv buffer: %d, bitrate:%"PRId64"\n",
- s->avctx->profile, s->avctx->level, s->progressive_sequence, s->chroma_format,
- s->avctx->rc_buffer_size, s->bit_rate);
-}
-
-static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1)
-{
- MpegEncContext *s = &s1->mpeg_enc_ctx;
- int color_description, w, h;
-
- skip_bits(&s->gb, 3); /* video format */
- color_description = get_bits1(&s->gb);
- if (color_description) {
- s->avctx->color_primaries = get_bits(&s->gb, 8);
- s->avctx->color_trc = get_bits(&s->gb, 8);
- s->avctx->colorspace = get_bits(&s->gb, 8);
- }
- w = get_bits(&s->gb, 14);
- skip_bits(&s->gb, 1); // marker
- h = get_bits(&s->gb, 14);
- // remaining 3 bits are zero padding
-
- s1->pan_scan.width = 16 * w;
- s1->pan_scan.height = 16 * h;
-
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_DEBUG, "sde w:%d, h:%d\n", w, h);
-}
-
-static void mpeg_decode_picture_display_extension(Mpeg1Context *s1)
-{
- MpegEncContext *s = &s1->mpeg_enc_ctx;
- int i, nofco;
-
- nofco = 1;
- if (s->progressive_sequence) {
- if (s->repeat_first_field) {
- nofco++;
- if (s->top_field_first)
- nofco++;
- }
- } else {
- if (s->picture_structure == PICT_FRAME) {
- nofco++;
- if (s->repeat_first_field)
- nofco++;
- }
- }
- for (i = 0; i < nofco; i++) {
- s1->pan_scan.position[i][0] = get_sbits(&s->gb, 16);
- skip_bits(&s->gb, 1); // marker
- s1->pan_scan.position[i][1] = get_sbits(&s->gb, 16);
- skip_bits(&s->gb, 1); // marker
- }
-
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_DEBUG,
- "pde (%"PRId16",%"PRId16") (%"PRId16",%"PRId16") (%"PRId16",%"PRId16")\n",
- s1->pan_scan.position[0][0], s1->pan_scan.position[0][1],
- s1->pan_scan.position[1][0], s1->pan_scan.position[1][1],
- s1->pan_scan.position[2][0], s1->pan_scan.position[2][1]);
-}
-
-static int load_matrix(MpegEncContext *s, uint16_t matrix0[64],
- uint16_t matrix1[64], int intra)
-{
- int i;
-
- for (i = 0; i < 64; i++) {
- int j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
- int v = get_bits(&s->gb, 8);
- if (v == 0) {
- av_log(s->avctx, AV_LOG_ERROR, "matrix damaged\n");
- return AVERROR_INVALIDDATA;
- }
- if (intra && i == 0 && v != 8) {
- av_log(s->avctx, AV_LOG_DEBUG, "intra matrix specifies invalid DC quantizer %d, ignoring\n", v);
- v = 8; // needed by pink.mpg / issue1046
- }
- matrix0[j] = v;
- if (matrix1)
- matrix1[j] = v;
- }
- return 0;
-}
-
-static void mpeg_decode_quant_matrix_extension(MpegEncContext *s)
-{
- ff_dlog(s->avctx, "matrix extension\n");
-
- if (get_bits1(&s->gb))
- load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1);
- if (get_bits1(&s->gb))
- load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0);
- if (get_bits1(&s->gb))
- load_matrix(s, s->chroma_intra_matrix, NULL, 1);
- if (get_bits1(&s->gb))
- load_matrix(s, s->chroma_inter_matrix, NULL, 0);
-}
-
-static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1)
-{
- MpegEncContext *s = &s1->mpeg_enc_ctx;
-
- s->full_pel[0] = s->full_pel[1] = 0;
- s->mpeg_f_code[0][0] = get_bits(&s->gb, 4);
- s->mpeg_f_code[0][1] = get_bits(&s->gb, 4);
- s->mpeg_f_code[1][0] = get_bits(&s->gb, 4);
- s->mpeg_f_code[1][1] = get_bits(&s->gb, 4);
- if (!s->pict_type && s1->mpeg_enc_ctx_allocated) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Missing picture start code, guessing missing values\n");
- if (s->mpeg_f_code[1][0] == 15 && s->mpeg_f_code[1][1] == 15) {
- if (s->mpeg_f_code[0][0] == 15 && s->mpeg_f_code[0][1] == 15)
- s->pict_type = AV_PICTURE_TYPE_I;
- else
- s->pict_type = AV_PICTURE_TYPE_P;
- } else
- s->pict_type = AV_PICTURE_TYPE_B;
- s->current_picture.f->pict_type = s->pict_type;
- s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I;
- }
- s->mpeg_f_code[0][0] += !s->mpeg_f_code[0][0];
- s->mpeg_f_code[0][1] += !s->mpeg_f_code[0][1];
- s->mpeg_f_code[1][0] += !s->mpeg_f_code[1][0];
- s->mpeg_f_code[1][1] += !s->mpeg_f_code[1][1];
-
- s->intra_dc_precision = get_bits(&s->gb, 2);
- s->picture_structure = get_bits(&s->gb, 2);
- s->top_field_first = get_bits1(&s->gb);
- s->frame_pred_frame_dct = get_bits1(&s->gb);
- s->concealment_motion_vectors = get_bits1(&s->gb);
- s->q_scale_type = get_bits1(&s->gb);
- s->intra_vlc_format = get_bits1(&s->gb);
- s->alternate_scan = get_bits1(&s->gb);
- s->repeat_first_field = get_bits1(&s->gb);
- s->chroma_420_type = get_bits1(&s->gb);
- s->progressive_frame = get_bits1(&s->gb);
-
- if (s->alternate_scan) {
- ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan);
- ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan);
- } else {
- ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct);
- ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
- }
-
- /* composite display not parsed */
- ff_dlog(s->avctx, "intra_dc_precision=%d\n", s->intra_dc_precision);
- ff_dlog(s->avctx, "picture_structure=%d\n", s->picture_structure);
- ff_dlog(s->avctx, "top field first=%d\n", s->top_field_first);
- ff_dlog(s->avctx, "repeat first field=%d\n", s->repeat_first_field);
- ff_dlog(s->avctx, "conceal=%d\n", s->concealment_motion_vectors);
- ff_dlog(s->avctx, "intra_vlc_format=%d\n", s->intra_vlc_format);
- ff_dlog(s->avctx, "alternate_scan=%d\n", s->alternate_scan);
- ff_dlog(s->avctx, "frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct);
- ff_dlog(s->avctx, "progressive_frame=%d\n", s->progressive_frame);
-}
-
-static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
-{
- AVCodecContext *avctx = s->avctx;
- Mpeg1Context *s1 = (Mpeg1Context *) s;
- int ret;
-
- /* start frame decoding */
- if (s->first_field || s->picture_structure == PICT_FRAME) {
- AVFrameSideData *pan_scan;
-
- if ((ret = ff_mpv_frame_start(s, avctx)) < 0)
- return ret;
-
- ff_mpeg_er_frame_start(s);
-
- /* first check if we must repeat the frame */
- s->current_picture_ptr->f->repeat_pict = 0;
- if (s->repeat_first_field) {
- if (s->progressive_sequence) {
- if (s->top_field_first)
- s->current_picture_ptr->f->repeat_pict = 4;
- else
- s->current_picture_ptr->f->repeat_pict = 2;
- } else if (s->progressive_frame) {
- s->current_picture_ptr->f->repeat_pict = 1;
- }
- }
-
- pan_scan = av_frame_new_side_data(s->current_picture_ptr->f,
- AV_FRAME_DATA_PANSCAN,
- sizeof(s1->pan_scan));
- if (!pan_scan)
- return AVERROR(ENOMEM);
- memcpy(pan_scan->data, &s1->pan_scan, sizeof(s1->pan_scan));
-
- if (s1->a53_caption) {
- AVFrameSideData *sd = av_frame_new_side_data(
- 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);
- avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
- }
-
- if (s1->has_stereo3d) {
- AVStereo3D *stereo = av_stereo3d_create_side_data(s->current_picture_ptr->f);
- if (!stereo)
- return AVERROR(ENOMEM);
-
- *stereo = s1->stereo3d;
- s1->has_stereo3d = 0;
- }
-
- if (s1->has_afd) {
- AVFrameSideData *sd =
- av_frame_new_side_data(s->current_picture_ptr->f,
- AV_FRAME_DATA_AFD, 1);
- if (!sd)
- return AVERROR(ENOMEM);
-
- *sd->data = s1->afd;
- s1->has_afd = 0;
- }
-
- if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME))
- ff_thread_finish_setup(avctx);
- } else { // second field
- int i;
-
- if (!s->current_picture_ptr) {
- av_log(s->avctx, AV_LOG_ERROR, "first field missing\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (s->avctx->hwaccel &&
- (s->avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) {
- if ((ret = s->avctx->hwaccel->end_frame(s->avctx)) < 0) {
- av_log(avctx, AV_LOG_ERROR,
- "hardware accelerator failed to decode first field\n");
- return ret;
- }
- }
-
- for (i = 0; i < 4; i++) {
- s->current_picture.f->data[i] = s->current_picture_ptr->f->data[i];
- if (s->picture_structure == PICT_BOTTOM_FIELD)
- s->current_picture.f->data[i] +=
- s->current_picture_ptr->f->linesize[i];
- }
- }
-
- if (avctx->hwaccel) {
- if ((ret = avctx->hwaccel->start_frame(avctx, buf, buf_size)) < 0)
- return ret;
- }
-
- return 0;
-}
-
-#define DECODE_SLICE_ERROR -1
-#define DECODE_SLICE_OK 0
-
-/**
- * Decode a slice.
- * MpegEncContext.mb_y must be set to the MB row from the startcode.
- * @return DECODE_SLICE_ERROR if the slice is damaged,
- * DECODE_SLICE_OK if this slice is OK
- */
-static int mpeg_decode_slice(MpegEncContext *s, int mb_y,
- const uint8_t **buf, int buf_size)
-{
- AVCodecContext *avctx = s->avctx;
- const int lowres = s->avctx->lowres;
- const int field_pic = s->picture_structure != PICT_FRAME;
- int ret;
-
- s->resync_mb_x =
- s->resync_mb_y = -1;
-
- av_assert0(mb_y < s->mb_height);
-
- init_get_bits(&s->gb, *buf, buf_size * 8);
- if (s->codec_id != AV_CODEC_ID_MPEG1VIDEO && s->mb_height > 2800/16)
- skip_bits(&s->gb, 3);
-
- ff_mpeg1_clean_buffers(s);
- s->interlaced_dct = 0;
-
- s->qscale = get_qscale(s);
-
- if (s->qscale == 0) {
- av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n");
- return AVERROR_INVALIDDATA;
- }
-
- /* extra slice info */
- if (skip_1stop_8data_bits(&s->gb) < 0)
- return AVERROR_INVALIDDATA;
-
- s->mb_x = 0;
-
- if (mb_y == 0 && s->codec_tag == AV_RL32("SLIF")) {
- skip_bits1(&s->gb);
- } else {
- while (get_bits_left(&s->gb) > 0) {
- int code = get_vlc2(&s->gb, ff_mbincr_vlc.table,
- MBINCR_VLC_BITS, 2);
- if (code < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n");
- return AVERROR_INVALIDDATA;
- }
- if (code >= 33) {
- if (code == 33)
- s->mb_x += 33;
- /* otherwise, stuffing, nothing to do */
- } else {
- s->mb_x += code;
- break;
- }
- }
- }
-
- if (s->mb_x >= (unsigned) s->mb_width) {
- av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (avctx->hwaccel && avctx->hwaccel->decode_slice) {
- const uint8_t *buf_end, *buf_start = *buf - 4; /* include start_code */
- int start_code = -1;
- buf_end = avpriv_find_start_code(buf_start + 2, *buf + buf_size, &start_code);
- if (buf_end < *buf + buf_size)
- buf_end -= 4;
- s->mb_y = mb_y;
- if (avctx->hwaccel->decode_slice(avctx, buf_start, buf_end - buf_start) < 0)
- return DECODE_SLICE_ERROR;
- *buf = buf_end;
- return DECODE_SLICE_OK;
- }
-
- s->resync_mb_x = s->mb_x;
- s->resync_mb_y = s->mb_y = mb_y;
- s->mb_skip_run = 0;
- ff_init_block_index(s);
-
- if (s->mb_y == 0 && s->mb_x == 0 && (s->first_field || s->picture_structure == PICT_FRAME)) {
- if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
- av_log(s->avctx, AV_LOG_DEBUG,
- "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n",
- s->qscale,
- s->mpeg_f_code[0][0], s->mpeg_f_code[0][1],
- s->mpeg_f_code[1][0], s->mpeg_f_code[1][1],
- s->pict_type == AV_PICTURE_TYPE_I ? "I" :
- (s->pict_type == AV_PICTURE_TYPE_P ? "P" :
- (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")),
- s->progressive_sequence ? "ps" : "",
- s->progressive_frame ? "pf" : "",
- s->alternate_scan ? "alt" : "",
- s->top_field_first ? "top" : "",
- s->intra_dc_precision, s->picture_structure,
- s->frame_pred_frame_dct, s->concealment_motion_vectors,
- s->q_scale_type, s->intra_vlc_format,
- s->repeat_first_field, s->chroma_420_type ? "420" : "");
- }
- }
-
- for (;;) {
- // If 1, we memcpy blocks in xvmcvideo.
- if ((CONFIG_MPEG1_XVMC_HWACCEL || CONFIG_MPEG2_XVMC_HWACCEL) && s->pack_pblocks)
- ff_xvmc_init_block(s); // set s->block
-
- if ((ret = mpeg_decode_mb(s, s->block)) < 0)
- return ret;
-
- // Note motion_val is normally NULL unless we want to extract the MVs.
- if (s->current_picture.motion_val[0] && !s->encoding) {
- const int wrap = s->b8_stride;
- int xy = s->mb_x * 2 + s->mb_y * 2 * wrap;
- int b8_xy = 4 * (s->mb_x + s->mb_y * s->mb_stride);
- int motion_x, motion_y, dir, i;
-
- for (i = 0; i < 2; i++) {
- for (dir = 0; dir < 2; dir++) {
- if (s->mb_intra ||
- (dir == 1 && s->pict_type != AV_PICTURE_TYPE_B)) {
- motion_x = motion_y = 0;
- } else if (s->mv_type == MV_TYPE_16X16 ||
- (s->mv_type == MV_TYPE_FIELD && field_pic)) {
- motion_x = s->mv[dir][0][0];
- motion_y = s->mv[dir][0][1];
- } else { /* if ((s->mv_type == MV_TYPE_FIELD) || (s->mv_type == MV_TYPE_16X8)) */
- motion_x = s->mv[dir][i][0];
- motion_y = s->mv[dir][i][1];
- }
-
- s->current_picture.motion_val[dir][xy][0] = motion_x;
- s->current_picture.motion_val[dir][xy][1] = motion_y;
- s->current_picture.motion_val[dir][xy + 1][0] = motion_x;
- s->current_picture.motion_val[dir][xy + 1][1] = motion_y;
- s->current_picture.ref_index [dir][b8_xy] =
- s->current_picture.ref_index [dir][b8_xy + 1] = s->field_select[dir][i];
- av_assert2(s->field_select[dir][i] == 0 ||
- s->field_select[dir][i] == 1);
- }
- xy += wrap;
- b8_xy += 2;
- }
- }
-
- s->dest[0] += 16 >> lowres;
- s->dest[1] +=(16 >> lowres) >> s->chroma_x_shift;
- s->dest[2] +=(16 >> lowres) >> s->chroma_x_shift;
-
- ff_mpv_decode_mb(s, s->block);
-
- if (++s->mb_x >= s->mb_width) {
- const int mb_size = 16 >> s->avctx->lowres;
-
- ff_mpeg_draw_horiz_band(s, mb_size * (s->mb_y >> field_pic), mb_size);
- ff_mpv_report_decode_progress(s);
-
- s->mb_x = 0;
- s->mb_y += 1 << field_pic;
-
- if (s->mb_y >= s->mb_height) {
- int left = get_bits_left(&s->gb);
- int is_d10 = s->chroma_format == 2 &&
- s->pict_type == AV_PICTURE_TYPE_I &&
- avctx->profile == 0 && avctx->level == 5 &&
- s->intra_dc_precision == 2 &&
- s->q_scale_type == 1 && s->alternate_scan == 0 &&
- s->progressive_frame == 0
- /* vbv_delay == 0xBBB || 0xE10 */;
-
- if (left >= 32 && !is_d10) {
- GetBitContext gb = s->gb;
- align_get_bits(&gb);
- if (show_bits(&gb, 24) == 0x060E2B) {
- av_log(avctx, AV_LOG_DEBUG, "Invalid MXF data found in video stream\n");
- is_d10 = 1;
- }
- }
-
- if (left < 0 ||
- (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10) ||
- ((avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_AGGRESSIVE)) && left > 8)) {
- av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n",
- left, left>0 ? show_bits(&s->gb, FFMIN(left, 23)) : 0);
- return AVERROR_INVALIDDATA;
- } else
- goto eos;
- }
- // There are some files out there which are missing the last slice
- // in cases where the slice is completely outside the visible
- // area, we detect this here instead of running into the end expecting
- // more data
- if (s->mb_y >= ((s->height + 15) >> 4) &&
- !s->progressive_sequence &&
- get_bits_left(&s->gb) <= 8 &&
- get_bits_left(&s->gb) >= 0 &&
- s->mb_skip_run == -1 &&
- show_bits(&s->gb, 8) == 0)
- goto eos;
-
- ff_init_block_index(s);
- }
-
- /* skip mb handling */
- if (s->mb_skip_run == -1) {
- /* read increment again */
- s->mb_skip_run = 0;
- for (;;) {
- int code = get_vlc2(&s->gb, ff_mbincr_vlc.table,
- MBINCR_VLC_BITS, 2);
- if (code < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "mb incr damaged\n");
- return AVERROR_INVALIDDATA;
- }
- if (code >= 33) {
- if (code == 33) {
- s->mb_skip_run += 33;
- } else if (code == 35) {
- if (s->mb_skip_run != 0 || show_bits(&s->gb, 15) != 0) {
- av_log(s->avctx, AV_LOG_ERROR, "slice mismatch\n");
- return AVERROR_INVALIDDATA;
- }
- goto eos; /* end of slice */
- }
- /* otherwise, stuffing, nothing to do */
- } else {
- s->mb_skip_run += code;
- break;
- }
- }
- if (s->mb_skip_run) {
- int i;
- if (s->pict_type == AV_PICTURE_TYPE_I) {
- av_log(s->avctx, AV_LOG_ERROR,
- "skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y);
- return AVERROR_INVALIDDATA;
- }
-
- /* skip mb */
- s->mb_intra = 0;
- for (i = 0; i < 12; i++)
- s->block_last_index[i] = -1;
- if (s->picture_structure == PICT_FRAME)
- s->mv_type = MV_TYPE_16X16;
- else
- s->mv_type = MV_TYPE_FIELD;
- if (s->pict_type == AV_PICTURE_TYPE_P) {
- /* if P type, zero motion vector is implied */
- s->mv_dir = MV_DIR_FORWARD;
- s->mv[0][0][0] = s->mv[0][0][1] = 0;
- s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0;
- s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0;
- s->field_select[0][0] = (s->picture_structure - 1) & 1;
- } else {
- /* if B type, reuse previous vectors and directions */
- s->mv[0][0][0] = s->last_mv[0][0][0];
- s->mv[0][0][1] = s->last_mv[0][0][1];
- s->mv[1][0][0] = s->last_mv[1][0][0];
- s->mv[1][0][1] = s->last_mv[1][0][1];
- }
- }
- }
- }
-eos: // end of slice
- if (get_bits_left(&s->gb) < 0) {
- av_log(s, AV_LOG_ERROR, "overread %d\n", -get_bits_left(&s->gb));
- return AVERROR_INVALIDDATA;
- }
- *buf += (get_bits_count(&s->gb) - 1) / 8;
- ff_dlog(s, "Slice start:%d %d end:%d %d\n", s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y);
- return 0;
-}
-
-static int slice_decode_thread(AVCodecContext *c, void *arg)
-{
- MpegEncContext *s = *(void **) arg;
- const uint8_t *buf = s->gb.buffer;
- int mb_y = s->start_mb_y;
- const int field_pic = s->picture_structure != PICT_FRAME;
-
- s->er.error_count = (3 * (s->end_mb_y - s->start_mb_y) * s->mb_width) >> field_pic;
-
- for (;;) {
- uint32_t start_code;
- int ret;
-
- ret = mpeg_decode_slice(s, mb_y, &buf, s->gb.buffer_end - buf);
- emms_c();
- ff_dlog(c, "ret:%d resync:%d/%d mb:%d/%d ts:%d/%d ec:%d\n",
- ret, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y,
- s->start_mb_y, s->end_mb_y, s->er.error_count);
- if (ret < 0) {
- if (c->err_recognition & AV_EF_EXPLODE)
- return ret;
- if (s->resync_mb_x >= 0 && s->resync_mb_y >= 0)
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
- s->mb_x, s->mb_y,
- ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
- } else {
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
- s->mb_x - 1, s->mb_y,
- ER_AC_END | ER_DC_END | ER_MV_END);
- }
-
- if (s->mb_y == s->end_mb_y)
- return 0;
-
- start_code = -1;
- buf = avpriv_find_start_code(buf, s->gb.buffer_end, &start_code);
- mb_y = start_code - SLICE_MIN_START_CODE;
- if (s->codec_id != AV_CODEC_ID_MPEG1VIDEO && s->mb_height > 2800/16)
- mb_y += (*buf&0xE0)<<2;
- mb_y <<= field_pic;
- if (s->picture_structure == PICT_BOTTOM_FIELD)
- mb_y++;
- if (mb_y < 0 || mb_y >= s->end_mb_y)
- return AVERROR_INVALIDDATA;
- }
-}
-
-/**
- * Handle slice ends.
- * @return 1 if it seems to be the last slice
- */
-static int slice_end(AVCodecContext *avctx, AVFrame *pict)
-{
- Mpeg1Context *s1 = avctx->priv_data;
- MpegEncContext *s = &s1->mpeg_enc_ctx;
-
- if (!s1->mpeg_enc_ctx_allocated || !s->current_picture_ptr)
- return 0;
-
- if (s->avctx->hwaccel) {
- int ret = s->avctx->hwaccel->end_frame(s->avctx);
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR,
- "hardware accelerator failed to decode picture\n");
- return ret;
- }
- }
-
- /* end of slice reached */
- if (/* s->mb_y << field_pic == s->mb_height && */ !s->first_field && !s1->first_slice) {
- /* end of image */
-
- ff_er_frame_end(&s->er);
-
- ff_mpv_frame_end(s);
-
- if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
- int ret = av_frame_ref(pict, s->current_picture_ptr->f);
- if (ret < 0)
- return ret;
- ff_print_debug_info(s, s->current_picture_ptr, pict);
- ff_mpv_export_qp_table(s, pict, s->current_picture_ptr, FF_QSCALE_TYPE_MPEG2);
- } else {
- if (avctx->active_thread_type & FF_THREAD_FRAME)
- s->picture_number++;
- /* latency of 1 frame for I- and P-frames */
- /* XXX: use another variable than picture_number */
- if (s->last_picture_ptr) {
- int ret = av_frame_ref(pict, s->last_picture_ptr->f);
- if (ret < 0)
- return ret;
- ff_print_debug_info(s, s->last_picture_ptr, pict);
- ff_mpv_export_qp_table(s, pict, s->last_picture_ptr, FF_QSCALE_TYPE_MPEG2);
- }
- }
-
- return 1;
- } else {
- return 0;
- }
-}
-
-static int mpeg1_decode_sequence(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size)
-{
- Mpeg1Context *s1 = avctx->priv_data;
- MpegEncContext *s = &s1->mpeg_enc_ctx;
- int width, height;
- int i, v, j;
-
- init_get_bits(&s->gb, buf, buf_size * 8);
-
- width = get_bits(&s->gb, 12);
- height = get_bits(&s->gb, 12);
- if (width == 0 || height == 0) {
- av_log(avctx, AV_LOG_WARNING,
- "Invalid horizontal or vertical size value.\n");
- if (avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT))
- return AVERROR_INVALIDDATA;
- }
- s->aspect_ratio_info = get_bits(&s->gb, 4);
- if (s->aspect_ratio_info == 0) {
- av_log(avctx, AV_LOG_ERROR, "aspect ratio has forbidden 0 value\n");
- if (avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT))
- return AVERROR_INVALIDDATA;
- }
- s->frame_rate_index = get_bits(&s->gb, 4);
- if (s->frame_rate_index == 0 || s->frame_rate_index > 13) {
- av_log(avctx, AV_LOG_WARNING,
- "frame_rate_index %d is invalid\n", s->frame_rate_index);
- s->frame_rate_index = 1;
- }
- s->bit_rate = get_bits(&s->gb, 18) * 400LL;
- if (check_marker(&s->gb, "in sequence header") == 0) {
- return AVERROR_INVALIDDATA;
- }
-
- s->avctx->rc_buffer_size = get_bits(&s->gb, 10) * 1024 * 16;
- skip_bits(&s->gb, 1);
-
- /* get matrix */
- if (get_bits1(&s->gb)) {
- load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1);
- } else {
- for (i = 0; i < 64; i++) {
- j = s->idsp.idct_permutation[i];
- v = ff_mpeg1_default_intra_matrix[i];
- s->intra_matrix[j] = v;
- s->chroma_intra_matrix[j] = v;
- }
- }
- if (get_bits1(&s->gb)) {
- load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0);
- } else {
- for (i = 0; i < 64; i++) {
- int j = s->idsp.idct_permutation[i];
- v = ff_mpeg1_default_non_intra_matrix[i];
- s->inter_matrix[j] = v;
- s->chroma_inter_matrix[j] = v;
- }
- }
-
- if (show_bits(&s->gb, 23) != 0) {
- av_log(s->avctx, AV_LOG_ERROR, "sequence header damaged\n");
- return AVERROR_INVALIDDATA;
- }
-
- s->width = width;
- s->height = height;
-
- /* We set MPEG-2 parameters so that it emulates MPEG-1. */
- s->progressive_sequence = 1;
- s->progressive_frame = 1;
- s->picture_structure = PICT_FRAME;
- s->first_field = 0;
- s->frame_pred_frame_dct = 1;
- s->chroma_format = 1;
- s->codec_id =
- s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO;
- s->out_format = FMT_MPEG1;
- s->swap_uv = 0; // AFAIK VCR2 does not have SEQ_HEADER
- if (s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY)
- s->low_delay = 1;
-
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_DEBUG, "vbv buffer: %d, bitrate:%"PRId64", aspect_ratio_info: %d \n",
- s->avctx->rc_buffer_size, s->bit_rate, s->aspect_ratio_info);
-
- return 0;
-}
-
-static int vcr2_init_sequence(AVCodecContext *avctx)
-{
- Mpeg1Context *s1 = avctx->priv_data;
- MpegEncContext *s = &s1->mpeg_enc_ctx;
- int i, v, ret;
-
- /* start new MPEG-1 context decoding */
- s->out_format = FMT_MPEG1;
- if (s1->mpeg_enc_ctx_allocated) {
- ff_mpv_common_end(s);
- s1->mpeg_enc_ctx_allocated = 0;
- }
- s->width = avctx->coded_width;
- s->height = avctx->coded_height;
- avctx->has_b_frames = 0; // true?
- s->low_delay = 1;
-
- avctx->pix_fmt = mpeg_get_pixelformat(avctx);
- setup_hwaccel_for_pixfmt(avctx);
-
- ff_mpv_idct_init(s);
- if ((ret = ff_mpv_common_init(s)) < 0)
- return ret;
- s1->mpeg_enc_ctx_allocated = 1;
-
- for (i = 0; i < 64; i++) {
- int j = s->idsp.idct_permutation[i];
- v = ff_mpeg1_default_intra_matrix[i];
- s->intra_matrix[j] = v;
- s->chroma_intra_matrix[j] = v;
-
- v = ff_mpeg1_default_non_intra_matrix[i];
- s->inter_matrix[j] = v;
- s->chroma_inter_matrix[j] = v;
- }
-
- s->progressive_sequence = 1;
- s->progressive_frame = 1;
- s->picture_structure = PICT_FRAME;
- s->first_field = 0;
- s->frame_pred_frame_dct = 1;
- s->chroma_format = 1;
- if (s->codec_tag == AV_RL32("BW10")) {
- s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO;
- } else {
- s->swap_uv = 1; // in case of xvmc we need to swap uv for each MB
- s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
- }
- s1->save_width = s->width;
- s1->save_height = s->height;
- s1->save_progressive_seq = s->progressive_sequence;
- return 0;
-}
-
-static int mpeg_decode_a53_cc(AVCodecContext *avctx,
- const uint8_t *p, int buf_size)
-{
- Mpeg1Context *s1 = avctx->priv_data;
-
- if (buf_size >= 6 &&
- p[0] == 'G' && p[1] == 'A' && p[2] == '9' && p[3] == '4' &&
- p[4] == 3 && (p[5] & 0x40)) {
- /* 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)
- memcpy(s1->a53_caption, p + 7, s1->a53_caption_size);
- }
- return 1;
- } else if (buf_size >= 11 &&
- p[0] == 'C' && p[1] == 'C' && p[2] == 0x01 && p[3] == 0xf8) {
- /* extract DVD CC data */
- int cc_count = 0;
- int i;
- // There is a caption count field in the data, but it is often
- // incorect. 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) {
- uint8_t field1 = !!(p[4] & 0x80);
- uint8_t *cap = s1->a53_caption;
- p += 5;
- for (i = 0; i < cc_count; i++) {
- cap[0] = (p[0] == 0xff && field1) ? 0xfc : 0xfd;
- cap[1] = p[1];
- cap[2] = p[2];
- cap[3] = (p[3] == 0xff && !field1) ? 0xfc : 0xfd;
- cap[4] = p[4];
- cap[5] = p[5];
- cap += 6;
- p += 6;
- }
- }
- }
- return 1;
- }
- return 0;
-}
-
-static void mpeg_decode_user_data(AVCodecContext *avctx,
- const uint8_t *p, int buf_size)
-{
- Mpeg1Context *s = avctx->priv_data;
- const uint8_t *buf_end = p + buf_size;
- Mpeg1Context *s1 = avctx->priv_data;
-
-#if 0
- int i;
- for(i=0; !(!p[i-2] && !p[i-1] && p[i]==1) && i<buf_size; i++){
- av_log(avctx, AV_LOG_ERROR, "%c", p[i]);
- }
- av_log(avctx, AV_LOG_ERROR, "\n");
-#endif
-
- if (buf_size > 29){
- int i;
- for(i=0; i<20; i++)
- if (!memcmp(p+i, "\0TMPGEXS\0", 9)){
- s->tmpgexs= 1;
- }
- }
- /* we parse the DTG active format information */
- if (buf_end - p >= 5 &&
- p[0] == 'D' && p[1] == 'T' && p[2] == 'G' && p[3] == '1') {
- int flags = p[4];
- p += 5;
- if (flags & 0x80) {
- /* skip event id */
- p += 2;
- }
- if (flags & 0x40) {
- if (buf_end - p < 1)
- return;
-#if FF_API_AFD
-FF_DISABLE_DEPRECATION_WARNINGS
- avctx->dtg_active_format = p[0] & 0x0f;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif /* FF_API_AFD */
- s1->has_afd = 1;
- s1->afd = p[0] & 0x0f;
- }
- } else if (buf_end - p >= 6 &&
- p[0] == 'J' && p[1] == 'P' && p[2] == '3' && p[3] == 'D' &&
- p[4] == 0x03) { // S3D_video_format_length
- // the 0x7F mask ignores the reserved_bit value
- const uint8_t S3D_video_format_type = p[5] & 0x7F;
-
- if (S3D_video_format_type == 0x03 ||
- S3D_video_format_type == 0x04 ||
- S3D_video_format_type == 0x08 ||
- S3D_video_format_type == 0x23) {
-
- s1->has_stereo3d = 1;
-
- switch (S3D_video_format_type) {
- case 0x03:
- s1->stereo3d.type = AV_STEREO3D_SIDEBYSIDE;
- break;
- case 0x04:
- s1->stereo3d.type = AV_STEREO3D_TOPBOTTOM;
- break;
- case 0x08:
- s1->stereo3d.type = AV_STEREO3D_2D;
- break;
- case 0x23:
- s1->stereo3d.type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
- break;
- }
- }
- } else if (mpeg_decode_a53_cc(avctx, p, buf_size)) {
- return;
- }
-}
-
-static void mpeg_decode_gop(AVCodecContext *avctx,
- const uint8_t *buf, int buf_size)
-{
- Mpeg1Context *s1 = avctx->priv_data;
- MpegEncContext *s = &s1->mpeg_enc_ctx;
- int broken_link;
- int64_t tc;
-
- init_get_bits(&s->gb, buf, buf_size * 8);
-
- tc = avctx->timecode_frame_start = get_bits(&s->gb, 25);
-
- s->closed_gop = get_bits1(&s->gb);
- /* broken_link indicates that after editing the
- * reference frames of the first B-Frames after GOP I-Frame
- * are missing (open gop) */
- broken_link = get_bits1(&s->gb);
-
- if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
- char tcbuf[AV_TIMECODE_STR_SIZE];
- av_timecode_make_mpeg_tc_string(tcbuf, tc);
- av_log(s->avctx, AV_LOG_DEBUG,
- "GOP (%s) closed_gop=%d broken_link=%d\n",
- tcbuf, s->closed_gop, broken_link);
- }
-}
-
-static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
- int *got_output, const uint8_t *buf, int buf_size)
-{
- Mpeg1Context *s = avctx->priv_data;
- MpegEncContext *s2 = &s->mpeg_enc_ctx;
- const uint8_t *buf_ptr = buf;
- const uint8_t *buf_end = buf + buf_size;
- int ret, input_size;
- int last_code = 0, skip_frame = 0;
- int picture_start_code_seen = 0;
-
- for (;;) {
- /* find next start code */
- uint32_t start_code = -1;
- buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &start_code);
- if (start_code > 0x1ff) {
- if (!skip_frame) {
- if (HAVE_THREADS &&
- (avctx->active_thread_type & FF_THREAD_SLICE) &&
- !avctx->hwaccel) {
- int i;
- av_assert0(avctx->thread_count > 1);
-
- avctx->execute(avctx, slice_decode_thread,
- &s2->thread_context[0], NULL,
- s->slice_count, sizeof(void *));
- for (i = 0; i < s->slice_count; i++)
- s2->er.error_count += s2->thread_context[i]->er.error_count;
- }
-
-#if FF_API_VDPAU
- if ((CONFIG_MPEG_VDPAU_DECODER || CONFIG_MPEG1_VDPAU_DECODER)
- && uses_vdpau(avctx))
- ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count);
-#endif
-
- ret = slice_end(avctx, picture);
- if (ret < 0)
- return ret;
- else if (ret) {
- // FIXME: merge with the stuff in mpeg_decode_slice
- if (s2->last_picture_ptr || s2->low_delay)
- *got_output = 1;
- }
- }
- s2->pict_type = 0;
-
- if (avctx->err_recognition & AV_EF_EXPLODE && s2->er.error_count)
- return AVERROR_INVALIDDATA;
-
- return FFMAX(0, buf_ptr - buf - s2->parse_context.last_index);
- }
-
- input_size = buf_end - buf_ptr;
-
- if (avctx->debug & FF_DEBUG_STARTCODE)
- av_log(avctx, AV_LOG_DEBUG, "%3"PRIX32" at %"PTRDIFF_SPECIFIER" left %d\n",
- start_code, buf_ptr - buf, input_size);
-
- /* prepare data for next start code */
- switch (start_code) {
- case SEQ_START_CODE:
- if (last_code == 0) {
- mpeg1_decode_sequence(avctx, buf_ptr, input_size);
- if (buf != avctx->extradata)
- s->sync = 1;
- } else {
- av_log(avctx, AV_LOG_ERROR,
- "ignoring SEQ_START_CODE after %X\n", last_code);
- if (avctx->err_recognition & AV_EF_EXPLODE)
- return AVERROR_INVALIDDATA;
- }
- break;
-
- case PICTURE_START_CODE:
- if (picture_start_code_seen && s2->picture_structure == PICT_FRAME) {
- /* If it's a frame picture, there can't be more than one picture header.
- Yet, it does happen and we need to handle it. */
- av_log(avctx, AV_LOG_WARNING, "ignoring extra picture following a frame-picture\n");
- break;
- }
- picture_start_code_seen = 1;
-
- if (s2->width <= 0 || s2->height <= 0) {
- av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d.\n",
- s2->width, s2->height);
- return AVERROR_INVALIDDATA;
- }
-
- if (s->tmpgexs){
- s2->intra_dc_precision= 3;
- s2->intra_matrix[0]= 1;
- }
- if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) &&
- !avctx->hwaccel && s->slice_count) {
- int i;
-
- avctx->execute(avctx, slice_decode_thread,
- s2->thread_context, NULL,
- s->slice_count, sizeof(void *));
- for (i = 0; i < s->slice_count; i++)
- s2->er.error_count += s2->thread_context[i]->er.error_count;
- s->slice_count = 0;
- }
- if (last_code == 0 || last_code == SLICE_MIN_START_CODE) {
- ret = mpeg_decode_postinit(avctx);
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR,
- "mpeg_decode_postinit() failure\n");
- return ret;
- }
-
- /* We have a complete image: we try to decompress it. */
- if (mpeg1_decode_picture(avctx, buf_ptr, input_size) < 0)
- s2->pict_type = 0;
- s->first_slice = 1;
- last_code = PICTURE_START_CODE;
- } else {
- av_log(avctx, AV_LOG_ERROR,
- "ignoring pic after %X\n", last_code);
- if (avctx->err_recognition & AV_EF_EXPLODE)
- return AVERROR_INVALIDDATA;
- }
- break;
- case EXT_START_CODE:
- init_get_bits(&s2->gb, buf_ptr, input_size * 8);
-
- switch (get_bits(&s2->gb, 4)) {
- case 0x1:
- if (last_code == 0) {
- mpeg_decode_sequence_extension(s);
- } else {
- av_log(avctx, AV_LOG_ERROR,
- "ignoring seq ext after %X\n", last_code);
- if (avctx->err_recognition & AV_EF_EXPLODE)
- return AVERROR_INVALIDDATA;
- }
- break;
- case 0x2:
- mpeg_decode_sequence_display_extension(s);
- break;
- case 0x3:
- mpeg_decode_quant_matrix_extension(s2);
- break;
- case 0x7:
- mpeg_decode_picture_display_extension(s);
- break;
- case 0x8:
- if (last_code == PICTURE_START_CODE) {
- mpeg_decode_picture_coding_extension(s);
- } else {
- av_log(avctx, AV_LOG_ERROR,
- "ignoring pic cod ext after %X\n", last_code);
- if (avctx->err_recognition & AV_EF_EXPLODE)
- return AVERROR_INVALIDDATA;
- }
- break;
- }
- break;
- case USER_START_CODE:
- mpeg_decode_user_data(avctx, buf_ptr, input_size);
- break;
- case GOP_START_CODE:
- if (last_code == 0) {
- s2->first_field = 0;
- mpeg_decode_gop(avctx, buf_ptr, input_size);
- s->sync = 1;
- } else {
- av_log(avctx, AV_LOG_ERROR,
- "ignoring GOP_START_CODE after %X\n", last_code);
- if (avctx->err_recognition & AV_EF_EXPLODE)
- return AVERROR_INVALIDDATA;
- }
- break;
- default:
- if (start_code >= SLICE_MIN_START_CODE &&
- start_code <= SLICE_MAX_START_CODE && last_code == PICTURE_START_CODE) {
- if (s2->progressive_sequence && !s2->progressive_frame) {
- s2->progressive_frame = 1;
- av_log(s2->avctx, AV_LOG_ERROR,
- "interlaced frame in progressive sequence, ignoring\n");
- }
-
- if (s2->picture_structure == 0 ||
- (s2->progressive_frame && s2->picture_structure != PICT_FRAME)) {
- av_log(s2->avctx, AV_LOG_ERROR,
- "picture_structure %d invalid, ignoring\n",
- s2->picture_structure);
- s2->picture_structure = PICT_FRAME;
- }
-
- if (s2->progressive_sequence && !s2->frame_pred_frame_dct)
- av_log(s2->avctx, AV_LOG_WARNING, "invalid frame_pred_frame_dct\n");
-
- if (s2->picture_structure == PICT_FRAME) {
- s2->first_field = 0;
- s2->v_edge_pos = 16 * s2->mb_height;
- } else {
- s2->first_field ^= 1;
- s2->v_edge_pos = 8 * s2->mb_height;
- memset(s2->mbskip_table, 0, s2->mb_stride * s2->mb_height);
- }
- }
- if (start_code >= SLICE_MIN_START_CODE &&
- start_code <= SLICE_MAX_START_CODE && last_code != 0) {
- const int field_pic = s2->picture_structure != PICT_FRAME;
- int mb_y = start_code - SLICE_MIN_START_CODE;
- last_code = SLICE_MIN_START_CODE;
- if (s2->codec_id != AV_CODEC_ID_MPEG1VIDEO && s2->mb_height > 2800/16)
- mb_y += (*buf_ptr&0xE0)<<2;
-
- mb_y <<= field_pic;
- if (s2->picture_structure == PICT_BOTTOM_FIELD)
- mb_y++;
-
- if (buf_end - buf_ptr < 2) {
- av_log(s2->avctx, AV_LOG_ERROR, "slice too small\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (mb_y >= s2->mb_height) {
- av_log(s2->avctx, AV_LOG_ERROR,
- "slice below image (%d >= %d)\n", mb_y, s2->mb_height);
- return AVERROR_INVALIDDATA;
- }
-
- if (!s2->last_picture_ptr) {
- /* Skip B-frames if we do not have reference frames and
- * GOP is not closed. */
- if (s2->pict_type == AV_PICTURE_TYPE_B) {
- if (!s2->closed_gop) {
- skip_frame = 1;
- break;
- }
- }
- }
- if (s2->pict_type == AV_PICTURE_TYPE_I || (s2->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL))
- s->sync = 1;
- if (!s2->next_picture_ptr) {
- /* Skip P-frames if we do not have a reference frame or
- * we have an invalid header. */
- if (s2->pict_type == AV_PICTURE_TYPE_P && !s->sync) {
- skip_frame = 1;
- break;
- }
- }
- if ((avctx->skip_frame >= AVDISCARD_NONREF &&
- s2->pict_type == AV_PICTURE_TYPE_B) ||
- (avctx->skip_frame >= AVDISCARD_NONKEY &&
- s2->pict_type != AV_PICTURE_TYPE_I) ||
- avctx->skip_frame >= AVDISCARD_ALL) {
- skip_frame = 1;
- break;
- }
-
- if (!s->mpeg_enc_ctx_allocated)
- break;
-
- if (s2->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
- if (mb_y < avctx->skip_top ||
- mb_y >= s2->mb_height - avctx->skip_bottom)
- break;
- }
-
- if (!s2->pict_type) {
- av_log(avctx, AV_LOG_ERROR, "Missing picture start code\n");
- if (avctx->err_recognition & AV_EF_EXPLODE)
- return AVERROR_INVALIDDATA;
- break;
- }
-
- if (s->first_slice) {
- skip_frame = 0;
- s->first_slice = 0;
- if ((ret = mpeg_field_start(s2, buf, buf_size)) < 0)
- return ret;
- }
- if (!s2->current_picture_ptr) {
- av_log(avctx, AV_LOG_ERROR,
- "current_picture not initialized\n");
- return AVERROR_INVALIDDATA;
- }
-
-#if FF_API_VDPAU
- if (uses_vdpau(avctx)) {
- s->slice_count++;
- break;
- }
-#endif
-
- if (HAVE_THREADS &&
- (avctx->active_thread_type & FF_THREAD_SLICE) &&
- !avctx->hwaccel) {
- int threshold = (s2->mb_height * s->slice_count +
- s2->slice_context_count / 2) /
- s2->slice_context_count;
- av_assert0(avctx->thread_count > 1);
- if (threshold <= mb_y) {
- MpegEncContext *thread_context = s2->thread_context[s->slice_count];
-
- thread_context->start_mb_y = mb_y;
- thread_context->end_mb_y = s2->mb_height;
- if (s->slice_count) {
- s2->thread_context[s->slice_count - 1]->end_mb_y = mb_y;
- ret = ff_update_duplicate_context(thread_context, s2);
- if (ret < 0)
- return ret;
- }
- init_get_bits(&thread_context->gb, buf_ptr, input_size * 8);
- s->slice_count++;
- }
- buf_ptr += 2; // FIXME add minimum number of bytes per slice
- } else {
- ret = mpeg_decode_slice(s2, mb_y, &buf_ptr, input_size);
- emms_c();
-
- if (ret < 0) {
- if (avctx->err_recognition & AV_EF_EXPLODE)
- return ret;
- if (s2->resync_mb_x >= 0 && s2->resync_mb_y >= 0)
- ff_er_add_slice(&s2->er, s2->resync_mb_x,
- s2->resync_mb_y, s2->mb_x, s2->mb_y,
- ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
- } else {
- ff_er_add_slice(&s2->er, s2->resync_mb_x,
- s2->resync_mb_y, s2->mb_x - 1, s2->mb_y,
- ER_AC_END | ER_DC_END | ER_MV_END);
- }
- }
- }
- break;
- }
- }
-}
-
-static int mpeg_decode_frame(AVCodecContext *avctx, void *data,
- int *got_output, AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int ret;
- int buf_size = avpkt->size;
- Mpeg1Context *s = avctx->priv_data;
- AVFrame *picture = data;
- MpegEncContext *s2 = &s->mpeg_enc_ctx;
-
- if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) {
- /* special case for last picture */
- if (s2->low_delay == 0 && s2->next_picture_ptr) {
- int ret = av_frame_ref(picture, s2->next_picture_ptr->f);
- if (ret < 0)
- return ret;
-
- s2->next_picture_ptr = NULL;
-
- *got_output = 1;
- }
- return buf_size;
- }
-
- if (s2->avctx->flags & AV_CODEC_FLAG_TRUNCATED) {
- int next = ff_mpeg1_find_frame_end(&s2->parse_context, buf,
- buf_size, NULL);
-
- if (ff_combine_frame(&s2->parse_context, next,
- (const uint8_t **) &buf, &buf_size) < 0)
- return buf_size;
- }
-
- s2->codec_tag = avpriv_toupper4(avctx->codec_tag);
- if (s->mpeg_enc_ctx_allocated == 0 && ( s2->codec_tag == AV_RL32("VCR2")
- || s2->codec_tag == AV_RL32("BW10")
- ))
- vcr2_init_sequence(avctx);
-
- s->slice_count = 0;
-
- if (avctx->extradata && !s->extradata_decoded) {
- ret = decode_chunks(avctx, picture, got_output,
- avctx->extradata, avctx->extradata_size);
- if (*got_output) {
- av_log(avctx, AV_LOG_ERROR, "picture in extradata\n");
- av_frame_unref(picture);
- *got_output = 0;
- }
- s->extradata_decoded = 1;
- if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) {
- s2->current_picture_ptr = NULL;
- return ret;
- }
- }
-
- ret = decode_chunks(avctx, picture, got_output, buf, buf_size);
- if (ret<0 || *got_output)
- s2->current_picture_ptr = NULL;
-
- return ret;
-}
-
-static void flush(AVCodecContext *avctx)
-{
- Mpeg1Context *s = avctx->priv_data;
-
- s->sync = 0;
-
- ff_mpeg_flush(avctx);
-}
-
-static av_cold int mpeg_decode_end(AVCodecContext *avctx)
-{
- Mpeg1Context *s = avctx->priv_data;
-
- if (s->mpeg_enc_ctx_allocated)
- ff_mpv_common_end(&s->mpeg_enc_ctx);
- av_freep(&s->a53_caption);
- return 0;
-}
-
-static const AVProfile mpeg2_video_profiles[] = {
- { FF_PROFILE_MPEG2_422, "4:2:2" },
- { FF_PROFILE_MPEG2_HIGH, "High" },
- { FF_PROFILE_MPEG2_SS, "Spatially Scalable" },
- { FF_PROFILE_MPEG2_SNR_SCALABLE, "SNR Scalable" },
- { FF_PROFILE_MPEG2_MAIN, "Main" },
- { FF_PROFILE_MPEG2_SIMPLE, "Simple" },
- { FF_PROFILE_RESERVED, "Reserved" },
- { FF_PROFILE_RESERVED, "Reserved" },
- { FF_PROFILE_UNKNOWN },
-};
-
-AVCodec ff_mpeg1video_decoder = {
- .name = "mpeg1video",
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MPEG1VIDEO,
- .priv_data_size = sizeof(Mpeg1Context),
- .init = mpeg_decode_init,
- .close = mpeg_decode_end,
- .decode = mpeg_decode_frame,
- .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
- AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
- AV_CODEC_CAP_SLICE_THREADS,
- .flush = flush,
- .max_lowres = 3,
- .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context)
-};
-
-AVCodec ff_mpeg2video_decoder = {
- .name = "mpeg2video",
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MPEG2VIDEO,
- .priv_data_size = sizeof(Mpeg1Context),
- .init = mpeg_decode_init,
- .close = mpeg_decode_end,
- .decode = mpeg_decode_frame,
- .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
- AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
- AV_CODEC_CAP_SLICE_THREADS,
- .flush = flush,
- .max_lowres = 3,
- .profiles = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles),
-};
-
-//legacy decoder
-AVCodec ff_mpegvideo_decoder = {
- .name = "mpegvideo",
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MPEG2VIDEO,
- .priv_data_size = sizeof(Mpeg1Context),
- .init = mpeg_decode_init,
- .close = mpeg_decode_end,
- .decode = mpeg_decode_frame,
- .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
- .flush = flush,
- .max_lowres = 3,
-};
-
-#if FF_API_XVMC
-#if CONFIG_MPEG_XVMC_DECODER
-FF_DISABLE_DEPRECATION_WARNINGS
-static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx)
-{
- if (avctx->active_thread_type & FF_THREAD_SLICE)
- return -1;
- if (!(avctx->slice_flags & SLICE_FLAG_CODED_ORDER))
- return -1;
- if (!(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) {
- ff_dlog(avctx, "mpeg12.c: XvMC decoder will work better if SLICE_FLAG_ALLOW_FIELD is set\n");
- }
- mpeg_decode_init(avctx);
-
- avctx->pix_fmt = AV_PIX_FMT_XVMC_MPEG2_IDCT;
- avctx->xvmc_acceleration = 2; // 2 - the blocks are packed!
-
- return 0;
-}
-
-AVCodec ff_mpeg_xvmc_decoder = {
- .name = "mpegvideo_xvmc",
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MPEG2VIDEO_XVMC,
- .priv_data_size = sizeof(Mpeg1Context),
- .init = mpeg_mc_decode_init,
- .close = mpeg_decode_end,
- .decode = mpeg_decode_frame,
- .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
- AV_CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL |
- AV_CODEC_CAP_DELAY,
- .flush = flush,
-};
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-#endif /* FF_API_XVMC */
-
-#if CONFIG_MPEG_VDPAU_DECODER && FF_API_VDPAU
-AVCodec ff_mpeg_vdpau_decoder = {
- .name = "mpegvideo_vdpau",
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video (VDPAU acceleration)"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MPEG2VIDEO,
- .priv_data_size = sizeof(Mpeg1Context),
- .init = mpeg_decode_init,
- .close = mpeg_decode_end,
- .decode = mpeg_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED |
- AV_CODEC_CAP_HWACCEL_VDPAU | AV_CODEC_CAP_DELAY,
- .flush = flush,
-};
-#endif
-
-#if CONFIG_MPEG1_VDPAU_DECODER && FF_API_VDPAU
-AVCodec ff_mpeg1_vdpau_decoder = {
- .name = "mpeg1video_vdpau",
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video (VDPAU acceleration)"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MPEG1VIDEO,
- .priv_data_size = sizeof(Mpeg1Context),
- .init = mpeg_decode_init,
- .close = mpeg_decode_end,
- .decode = mpeg_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED |
- AV_CODEC_CAP_HWACCEL_VDPAU | AV_CODEC_CAP_DELAY,
- .flush = flush,
-};
-#endif
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg4videodec.c b/ffmpeg-2-8-11/libavcodec/mpeg4videodec.c
deleted file mode 100644
index 8d015ef..0000000
--- a/ffmpeg-2-8-11/libavcodec/mpeg4videodec.c
+++ /dev/null
@@ -1,2823 +0,0 @@
-/*
- * MPEG4 decoder.
- * Copyright (c) 2000,2001 Fabrice Bellard
- * Copyright (c) 2002-2010 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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
- */
-
-#define UNCHECKED_BITSTREAM_READER 1
-
-#include "libavutil/internal.h"
-#include "libavutil/opt.h"
-#include "error_resilience.h"
-#include "idctdsp.h"
-#include "internal.h"
-#include "mpegutils.h"
-#include "mpegvideo.h"
-#include "mpegvideodata.h"
-#include "mpeg4video.h"
-#include "h263.h"
-#include "thread.h"
-#include "xvididct.h"
-
-/* The defines below define the number of bits that are read at once for
- * reading vlc values. Changing these may improve speed and data cache needs
- * be aware though that decreasing them may need the number of stages that is
- * passed to get_vlc* to be increased. */
-#define SPRITE_TRAJ_VLC_BITS 6
-#define DC_VLC_BITS 9
-#define MB_TYPE_B_VLC_BITS 4
-
-static VLC dc_lum, dc_chrom;
-static VLC sprite_trajectory;
-static VLC mb_type_b_vlc;
-
-static const int mb_type_b_map[4] = {
- MB_TYPE_DIRECT2 | MB_TYPE_L0L1,
- MB_TYPE_L0L1 | MB_TYPE_16x16,
- MB_TYPE_L1 | MB_TYPE_16x16,
- MB_TYPE_L0 | MB_TYPE_16x16,
-};
-
-/**
- * Predict the ac.
- * @param n block index (0-3 are luma, 4-5 are chroma)
- * @param dir the ac prediction direction
- */
-void ff_mpeg4_pred_ac(MpegEncContext *s, int16_t *block, int n, int dir)
-{
- int i;
- int16_t *ac_val, *ac_val1;
- int8_t *const qscale_table = s->current_picture.qscale_table;
-
- /* find prediction */
- ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
- ac_val1 = ac_val;
- if (s->ac_pred) {
- if (dir == 0) {
- const int xy = s->mb_x - 1 + s->mb_y * s->mb_stride;
- /* left prediction */
- ac_val -= 16;
-
- if (s->mb_x == 0 || s->qscale == qscale_table[xy] ||
- n == 1 || n == 3) {
- /* same qscale */
- for (i = 1; i < 8; i++)
- block[s->idsp.idct_permutation[i << 3]] += ac_val[i];
- } else {
- /* different qscale, we must rescale */
- for (i = 1; i < 8; i++)
- block[s->idsp.idct_permutation[i << 3]] += ROUNDED_DIV(ac_val[i] * qscale_table[xy], s->qscale);
- }
- } else {
- const int xy = s->mb_x + s->mb_y * s->mb_stride - s->mb_stride;
- /* top prediction */
- ac_val -= 16 * s->block_wrap[n];
-
- if (s->mb_y == 0 || s->qscale == qscale_table[xy] ||
- n == 2 || n == 3) {
- /* same qscale */
- for (i = 1; i < 8; i++)
- block[s->idsp.idct_permutation[i]] += ac_val[i + 8];
- } else {
- /* different qscale, we must rescale */
- for (i = 1; i < 8; i++)
- block[s->idsp.idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8] * qscale_table[xy], s->qscale);
- }
- }
- }
- /* left copy */
- for (i = 1; i < 8; i++)
- ac_val1[i] = block[s->idsp.idct_permutation[i << 3]];
-
- /* top copy */
- for (i = 1; i < 8; i++)
- ac_val1[8 + i] = block[s->idsp.idct_permutation[i]];
-}
-
-/**
- * check if the next stuff is a resync marker or the end.
- * @return 0 if not
- */
-static inline int mpeg4_is_resync(Mpeg4DecContext *ctx)
-{
- MpegEncContext *s = &ctx->m;
- int bits_count = get_bits_count(&s->gb);
- int v = show_bits(&s->gb, 16);
-
- if (s->workaround_bugs & FF_BUG_NO_PADDING && !ctx->resync_marker)
- return 0;
-
- while (v <= 0xFF) {
- if (s->pict_type == AV_PICTURE_TYPE_B ||
- (v >> (8 - s->pict_type) != 1) || s->partitioned_frame)
- break;
- skip_bits(&s->gb, 8 + s->pict_type);
- bits_count += 8 + s->pict_type;
- v = show_bits(&s->gb, 16);
- }
-
- if (bits_count + 8 >= s->gb.size_in_bits) {
- v >>= 8;
- v |= 0x7F >> (7 - (bits_count & 7));
-
- if (v == 0x7F)
- return s->mb_num;
- } else {
- if (v == ff_mpeg4_resync_prefix[bits_count & 7]) {
- int len, mb_num;
- int mb_num_bits = av_log2(s->mb_num - 1) + 1;
- GetBitContext gb = s->gb;
-
- skip_bits(&s->gb, 1);
- align_get_bits(&s->gb);
-
- for (len = 0; len < 32; len++)
- if (get_bits1(&s->gb))
- break;
-
- mb_num = get_bits(&s->gb, mb_num_bits);
- if (!mb_num || mb_num > s->mb_num || get_bits_count(&s->gb)+6 > s->gb.size_in_bits)
- mb_num= -1;
-
- s->gb = gb;
-
- if (len >= ff_mpeg4_get_video_packet_prefix_length(s))
- return mb_num;
- }
- }
- return 0;
-}
-
-static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *gb)
-{
- MpegEncContext *s = &ctx->m;
- int a = 2 << s->sprite_warping_accuracy;
- int rho = 3 - s->sprite_warping_accuracy;
- int r = 16 / a;
- int alpha = 0;
- int beta = 0;
- int w = s->width;
- int h = s->height;
- int min_ab, i, w2, h2, w3, h3;
- int sprite_ref[4][2];
- int virtual_ref[2][2];
-
- // only true for rectangle shapes
- const int vop_ref[4][2] = { { 0, 0 }, { s->width, 0 },
- { 0, s->height }, { s->width, s->height } };
- int d[4][2] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
-
- if (w <= 0 || h <= 0)
- return AVERROR_INVALIDDATA;
-
- for (i = 0; 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);
- if (length > 0)
- x = get_xbits(gb, length);
-
- if (!(ctx->divx_version == 500 && ctx->divx_build == 413))
- check_marker(gb, "before sprite_trajectory");
-
- length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3);
- if (length > 0)
- y = get_xbits(gb, length);
-
- check_marker(gb, "after sprite_trajectory");
- ctx->sprite_traj[i][0] = d[i][0] = x;
- ctx->sprite_traj[i][1] = d[i][1] = y;
- }
- for (; i < 4; i++)
- ctx->sprite_traj[i][0] = ctx->sprite_traj[i][1] = 0;
-
- while ((1 << alpha) < w)
- alpha++;
- while ((1 << beta) < h)
- beta++; /* typo in the mpeg4 std for the definition of w' and h' */
- w2 = 1 << alpha;
- h2 = 1 << beta;
-
- // Note, the 4th point isn't used for GMC
- if (ctx->divx_version == 500 && ctx->divx_build == 413) {
- sprite_ref[0][0] = a * vop_ref[0][0] + d[0][0];
- sprite_ref[0][1] = a * vop_ref[0][1] + d[0][1];
- sprite_ref[1][0] = a * vop_ref[1][0] + d[0][0] + d[1][0];
- sprite_ref[1][1] = a * vop_ref[1][1] + d[0][1] + d[1][1];
- sprite_ref[2][0] = a * vop_ref[2][0] + d[0][0] + d[2][0];
- sprite_ref[2][1] = a * vop_ref[2][1] + d[0][1] + d[2][1];
- } else {
- sprite_ref[0][0] = (a >> 1) * (2 * vop_ref[0][0] + d[0][0]);
- sprite_ref[0][1] = (a >> 1) * (2 * vop_ref[0][1] + d[0][1]);
- sprite_ref[1][0] = (a >> 1) * (2 * vop_ref[1][0] + d[0][0] + d[1][0]);
- sprite_ref[1][1] = (a >> 1) * (2 * vop_ref[1][1] + d[0][1] + d[1][1]);
- sprite_ref[2][0] = (a >> 1) * (2 * vop_ref[2][0] + d[0][0] + d[2][0]);
- sprite_ref[2][1] = (a >> 1) * (2 * vop_ref[2][1] + d[0][1] + d[2][1]);
- }
- /* sprite_ref[3][0] = (a >> 1) * (2 * vop_ref[3][0] + d[0][0] + d[1][0] + d[2][0] + d[3][0]);
- * sprite_ref[3][1] = (a >> 1) * (2 * vop_ref[3][1] + d[0][1] + d[1][1] + d[2][1] + d[3][1]); */
-
- /* this is mostly identical to the mpeg4 std (and is totally unreadable
- * because of that...). Perhaps it should be reordered to be more readable.
- * The idea behind this virtual_ref mess is to be able to use shifts later
- * per pixel instead of divides so the distance between points is converted
- * from w&h based to w2&h2 based which are of the 2^x form. */
- virtual_ref[0][0] = 16 * (vop_ref[0][0] + w2) +
- ROUNDED_DIV(((w - w2) *
- (r * sprite_ref[0][0] - 16 * vop_ref[0][0]) +
- w2 * (r * sprite_ref[1][0] - 16 * vop_ref[1][0])), w);
- virtual_ref[0][1] = 16 * vop_ref[0][1] +
- ROUNDED_DIV(((w - w2) *
- (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) +
- w2 * (r * sprite_ref[1][1] - 16 * vop_ref[1][1])), w);
- virtual_ref[1][0] = 16 * vop_ref[0][0] +
- ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][0] - 16 * vop_ref[0][0]) +
- h2 * (r * sprite_ref[2][0] - 16 * vop_ref[2][0])), h);
- virtual_ref[1][1] = 16 * (vop_ref[0][1] + h2) +
- ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) +
- h2 * (r * sprite_ref[2][1] - 16 * vop_ref[2][1])), h);
-
- switch (ctx->num_sprite_warping_points) {
- case 0:
- s->sprite_offset[0][0] =
- s->sprite_offset[0][1] =
- s->sprite_offset[1][0] =
- s->sprite_offset[1][1] = 0;
- s->sprite_delta[0][0] = a;
- s->sprite_delta[0][1] =
- s->sprite_delta[1][0] = 0;
- s->sprite_delta[1][1] = a;
- ctx->sprite_shift[0] =
- ctx->sprite_shift[1] = 0;
- break;
- case 1: // GMC only
- s->sprite_offset[0][0] = sprite_ref[0][0] - a * vop_ref[0][0];
- s->sprite_offset[0][1] = sprite_ref[0][1] - a * vop_ref[0][1];
- s->sprite_offset[1][0] = ((sprite_ref[0][0] >> 1) | (sprite_ref[0][0] & 1)) -
- a * (vop_ref[0][0] / 2);
- s->sprite_offset[1][1] = ((sprite_ref[0][1] >> 1) | (sprite_ref[0][1] & 1)) -
- a * (vop_ref[0][1] / 2);
- s->sprite_delta[0][0] = a;
- s->sprite_delta[0][1] =
- s->sprite_delta[1][0] = 0;
- s->sprite_delta[1][1] = a;
- ctx->sprite_shift[0] =
- ctx->sprite_shift[1] = 0;
- break;
- case 2:
- s->sprite_offset[0][0] = (sprite_ref[0][0] << (alpha + rho)) +
- (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
- (-vop_ref[0][0]) +
- (r * sprite_ref[0][1] - virtual_ref[0][1]) *
- (-vop_ref[0][1]) + (1 << (alpha + rho - 1));
- s->sprite_offset[0][1] = (sprite_ref[0][1] << (alpha + rho)) +
- (-r * sprite_ref[0][1] + virtual_ref[0][1]) *
- (-vop_ref[0][0]) +
- (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
- (-vop_ref[0][1]) + (1 << (alpha + rho - 1));
- s->sprite_offset[1][0] = ((-r * sprite_ref[0][0] + virtual_ref[0][0]) *
- (-2 * vop_ref[0][0] + 1) +
- (r * sprite_ref[0][1] - virtual_ref[0][1]) *
- (-2 * vop_ref[0][1] + 1) + 2 * w2 * r *
- sprite_ref[0][0] - 16 * w2 + (1 << (alpha + rho + 1)));
- s->sprite_offset[1][1] = ((-r * sprite_ref[0][1] + virtual_ref[0][1]) *
- (-2 * vop_ref[0][0] + 1) +
- (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
- (-2 * vop_ref[0][1] + 1) + 2 * w2 * r *
- sprite_ref[0][1] - 16 * w2 + (1 << (alpha + rho + 1)));
- s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]);
- s->sprite_delta[0][1] = (+r * sprite_ref[0][1] - virtual_ref[0][1]);
- s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]);
- s->sprite_delta[1][1] = (-r * sprite_ref[0][0] + virtual_ref[0][0]);
-
- ctx->sprite_shift[0] = alpha + rho;
- ctx->sprite_shift[1] = alpha + rho + 2;
- break;
- case 3:
- min_ab = FFMIN(alpha, beta);
- w3 = w2 >> min_ab;
- h3 = h2 >> min_ab;
- s->sprite_offset[0][0] = (sprite_ref[0][0] * (1<<(alpha + beta + rho - min_ab))) +
- (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
- h3 * (-vop_ref[0][0]) +
- (-r * sprite_ref[0][0] + virtual_ref[1][0]) *
- w3 * (-vop_ref[0][1]) +
- (1 << (alpha + beta + rho - min_ab - 1));
- s->sprite_offset[0][1] = (sprite_ref[0][1] * (1 << (alpha + beta + rho - min_ab))) +
- (-r * sprite_ref[0][1] + virtual_ref[0][1]) *
- h3 * (-vop_ref[0][0]) +
- (-r * sprite_ref[0][1] + virtual_ref[1][1]) *
- w3 * (-vop_ref[0][1]) +
- (1 << (alpha + beta + rho - min_ab - 1));
- s->sprite_offset[1][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
- h3 * (-2 * vop_ref[0][0] + 1) +
- (-r * sprite_ref[0][0] + virtual_ref[1][0]) *
- w3 * (-2 * vop_ref[0][1] + 1) + 2 * w2 * h3 *
- r * sprite_ref[0][0] - 16 * w2 * h3 +
- (1 << (alpha + beta + rho - min_ab + 1));
- s->sprite_offset[1][1] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) *
- h3 * (-2 * vop_ref[0][0] + 1) +
- (-r * sprite_ref[0][1] + virtual_ref[1][1]) *
- w3 * (-2 * vop_ref[0][1] + 1) + 2 * w2 * h3 *
- r * sprite_ref[0][1] - 16 * w2 * h3 +
- (1 << (alpha + beta + rho - min_ab + 1));
- s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]) * h3;
- s->sprite_delta[0][1] = (-r * sprite_ref[0][0] + virtual_ref[1][0]) * w3;
- s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3;
- s->sprite_delta[1][1] = (-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3;
-
- ctx->sprite_shift[0] = alpha + beta + rho - min_ab;
- ctx->sprite_shift[1] = alpha + beta + rho - min_ab + 2;
- break;
- }
- /* try to simplify the situation */
- if (s->sprite_delta[0][0] == a << ctx->sprite_shift[0] &&
- s->sprite_delta[0][1] == 0 &&
- s->sprite_delta[1][0] == 0 &&
- s->sprite_delta[1][1] == a << ctx->sprite_shift[0]) {
- s->sprite_offset[0][0] >>= ctx->sprite_shift[0];
- s->sprite_offset[0][1] >>= ctx->sprite_shift[0];
- s->sprite_offset[1][0] >>= ctx->sprite_shift[1];
- s->sprite_offset[1][1] >>= ctx->sprite_shift[1];
- s->sprite_delta[0][0] = a;
- s->sprite_delta[0][1] = 0;
- s->sprite_delta[1][0] = 0;
- s->sprite_delta[1][1] = a;
- ctx->sprite_shift[0] = 0;
- ctx->sprite_shift[1] = 0;
- s->real_sprite_warping_points = 1;
- } else {
- int shift_y = 16 - ctx->sprite_shift[0];
- int shift_c = 16 - ctx->sprite_shift[1];
- for (i = 0; i < 2; i++) {
- s->sprite_offset[0][i] *= 1 << shift_y;
- s->sprite_offset[1][i] *= 1 << shift_c;
- s->sprite_delta[0][i] *= 1 << shift_y;
- s->sprite_delta[1][i] *= 1 << shift_y;
- ctx->sprite_shift[i] = 16;
- }
- s->real_sprite_warping_points = ctx->num_sprite_warping_points;
- }
-
- return 0;
-}
-
-static int decode_new_pred(Mpeg4DecContext *ctx, GetBitContext *gb) {
- int len = FFMIN(ctx->time_increment_bits + 3, 15);
-
- get_bits(gb, len);
- if (get_bits1(gb))
- get_bits(gb, len);
- check_marker(gb, "after new_pred");
-
- return 0;
-}
-
-/**
- * Decode the next video packet.
- * @return <0 if something went wrong
- */
-int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx)
-{
- MpegEncContext *s = &ctx->m;
-
- int mb_num_bits = av_log2(s->mb_num - 1) + 1;
- int header_extension = 0, mb_num, len;
-
- /* is there enough space left for a video packet + header */
- if (get_bits_count(&s->gb) > s->gb.size_in_bits - 20)
- return -1;
-
- for (len = 0; len < 32; len++)
- if (get_bits1(&s->gb))
- break;
-
- if (len != ff_mpeg4_get_video_packet_prefix_length(s)) {
- av_log(s->avctx, AV_LOG_ERROR, "marker does not match f_code\n");
- return -1;
- }
-
- if (ctx->shape != RECT_SHAPE) {
- header_extension = get_bits1(&s->gb);
- // FIXME more stuff here
- }
-
- mb_num = get_bits(&s->gb, mb_num_bits);
- if (mb_num >= s->mb_num) {
- av_log(s->avctx, AV_LOG_ERROR,
- "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num);
- return -1;
- }
-
- s->mb_x = mb_num % s->mb_width;
- s->mb_y = mb_num / s->mb_width;
-
- if (ctx->shape != BIN_ONLY_SHAPE) {
- int qscale = get_bits(&s->gb, s->quant_precision);
- if (qscale)
- s->chroma_qscale = s->qscale = qscale;
- }
-
- if (ctx->shape == RECT_SHAPE)
- header_extension = get_bits1(&s->gb);
-
- if (header_extension) {
- int time_incr = 0;
-
- while (get_bits1(&s->gb) != 0)
- time_incr++;
-
- check_marker(&s->gb, "before time_increment in video packed header");
- skip_bits(&s->gb, ctx->time_increment_bits); /* time_increment */
- check_marker(&s->gb, "before vop_coding_type in video packed header");
-
- skip_bits(&s->gb, 2); /* vop coding type */
- // FIXME not rect stuff here
-
- if (ctx->shape != BIN_ONLY_SHAPE) {
- skip_bits(&s->gb, 3); /* intra dc vlc threshold */
- // FIXME don't just ignore everything
- if (s->pict_type == AV_PICTURE_TYPE_S &&
- ctx->vol_sprite_usage == GMC_SPRITE) {
- if (mpeg4_decode_sprite_trajectory(ctx, &s->gb) < 0)
- return AVERROR_INVALIDDATA;
- av_log(s->avctx, AV_LOG_ERROR, "untested\n");
- }
-
- // FIXME reduced res stuff here
-
- if (s->pict_type != AV_PICTURE_TYPE_I) {
- int f_code = get_bits(&s->gb, 3); /* fcode_for */
- if (f_code == 0)
- av_log(s->avctx, AV_LOG_ERROR,
- "Error, video packet header damaged (f_code=0)\n");
- }
- if (s->pict_type == AV_PICTURE_TYPE_B) {
- int b_code = get_bits(&s->gb, 3);
- if (b_code == 0)
- av_log(s->avctx, AV_LOG_ERROR,
- "Error, video packet header damaged (b_code=0)\n");
- }
- }
- }
- if (ctx->new_pred)
- decode_new_pred(ctx, &s->gb);
-
- return 0;
-}
-
-/**
- * Get the average motion vector for a GMC MB.
- * @param n either 0 for the x component or 1 for y
- * @return the average MV for a GMC MB
- */
-static inline int get_amv(Mpeg4DecContext *ctx, int n)
-{
- MpegEncContext *s = &ctx->m;
- int x, y, mb_v, sum, dx, dy, shift;
- int len = 1 << (s->f_code + 4);
- const int a = s->sprite_warping_accuracy;
-
- if (s->workaround_bugs & FF_BUG_AMV)
- len >>= s->quarter_sample;
-
- if (s->real_sprite_warping_points == 1) {
- if (ctx->divx_version == 500 && ctx->divx_build == 413)
- sum = s->sprite_offset[0][n] / (1 << (a - s->quarter_sample));
- else
- sum = RSHIFT(s->sprite_offset[0][n] << s->quarter_sample, a);
- } else {
- dx = s->sprite_delta[n][0];
- dy = s->sprite_delta[n][1];
- shift = ctx->sprite_shift[0];
- if (n)
- dy -= 1 << (shift + a + 1);
- else
- dx -= 1 << (shift + a + 1);
- mb_v = s->sprite_offset[0][n] + dx * s->mb_x * 16 + dy * s->mb_y * 16;
-
- sum = 0;
- for (y = 0; y < 16; y++) {
- int v;
-
- v = mb_v + dy * y;
- // FIXME optimize
- for (x = 0; x < 16; x++) {
- sum += v >> shift;
- v += dx;
- }
- }
- sum = RSHIFT(sum, a + 8 - s->quarter_sample);
- }
-
- if (sum < -len)
- sum = -len;
- else if (sum >= len)
- sum = len - 1;
-
- return sum;
-}
-
-/**
- * Decode the dc value.
- * @param n block index (0-3 are luma, 4-5 are chroma)
- * @param dir_ptr the prediction direction will be stored here
- * @return the quantized dc
- */
-static inline int mpeg4_decode_dc(MpegEncContext *s, int n, int *dir_ptr)
-{
- int level, code;
-
- if (n < 4)
- code = get_vlc2(&s->gb, dc_lum.table, DC_VLC_BITS, 1);
- else
- code = get_vlc2(&s->gb, dc_chrom.table, DC_VLC_BITS, 1);
-
- if (code < 0 || code > 9 /* && s->nbit < 9 */) {
- av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n");
- return -1;
- }
-
- if (code == 0) {
- level = 0;
- } else {
- if (IS_3IV1) {
- if (code == 1)
- level = 2 * get_bits1(&s->gb) - 1;
- else {
- if (get_bits1(&s->gb))
- level = get_bits(&s->gb, code - 1) + (1 << (code - 1));
- else
- level = -get_bits(&s->gb, code - 1) - (1 << (code - 1));
- }
- } else {
- level = get_xbits(&s->gb, code);
- }
-
- if (code > 8) {
- if (get_bits1(&s->gb) == 0) { /* marker */
- if (s->avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)) {
- av_log(s->avctx, AV_LOG_ERROR, "dc marker bit missing\n");
- return -1;
- }
- }
- }
- }
-
- return ff_mpeg4_pred_dc(s, n, level, dir_ptr, 0);
-}
-
-/**
- * Decode first partition.
- * @return number of MBs decoded or <0 if an error occurred
- */
-static int mpeg4_decode_partition_a(Mpeg4DecContext *ctx)
-{
- MpegEncContext *s = &ctx->m;
- int mb_num = 0;
- static const int8_t quant_tab[4] = { -1, -2, 1, 2 };
-
- /* decode first partition */
- s->first_slice_line = 1;
- for (; s->mb_y < s->mb_height; s->mb_y++) {
- ff_init_block_index(s);
- for (; s->mb_x < s->mb_width; s->mb_x++) {
- const int xy = s->mb_x + s->mb_y * s->mb_stride;
- int cbpc;
- int dir = 0;
-
- mb_num++;
- ff_update_block_index(s);
- if (s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y + 1)
- s->first_slice_line = 0;
-
- if (s->pict_type == AV_PICTURE_TYPE_I) {
- int i;
-
- do {
- if (show_bits_long(&s->gb, 19) == DC_MARKER)
- return mb_num - 1;
-
- cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
- if (cbpc < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "mcbpc corrupted at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- } while (cbpc == 8);
-
- s->cbp_table[xy] = cbpc & 3;
- s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
- s->mb_intra = 1;
-
- if (cbpc & 4)
- ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
-
- s->current_picture.qscale_table[xy] = s->qscale;
-
- s->mbintra_table[xy] = 1;
- for (i = 0; i < 6; i++) {
- int dc_pred_dir;
- int dc = mpeg4_decode_dc(s, i, &dc_pred_dir);
- if (dc < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "DC corrupted at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- dir <<= 1;
- if (dc_pred_dir)
- dir |= 1;
- }
- s->pred_dir_table[xy] = dir;
- } else { /* P/S_TYPE */
- int mx, my, pred_x, pred_y, bits;
- int16_t *const mot_val = s->current_picture.motion_val[0][s->block_index[0]];
- const int stride = s->b8_stride * 2;
-
-try_again:
- bits = show_bits(&s->gb, 17);
- if (bits == MOTION_MARKER)
- return mb_num - 1;
-
- skip_bits1(&s->gb);
- if (bits & 0x10000) {
- /* skip mb */
- if (s->pict_type == AV_PICTURE_TYPE_S &&
- ctx->vol_sprite_usage == GMC_SPRITE) {
- s->current_picture.mb_type[xy] = MB_TYPE_SKIP |
- MB_TYPE_16x16 |
- MB_TYPE_GMC |
- MB_TYPE_L0;
- mx = get_amv(ctx, 0);
- my = get_amv(ctx, 1);
- } else {
- s->current_picture.mb_type[xy] = MB_TYPE_SKIP |
- MB_TYPE_16x16 |
- MB_TYPE_L0;
- mx = my = 0;
- }
- mot_val[0] =
- mot_val[2] =
- mot_val[0 + stride] =
- mot_val[2 + stride] = mx;
- mot_val[1] =
- mot_val[3] =
- mot_val[1 + stride] =
- mot_val[3 + stride] = my;
-
- if (s->mbintra_table[xy])
- ff_clean_intra_table_entries(s);
- continue;
- }
-
- cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
- if (cbpc < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "mcbpc corrupted at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- if (cbpc == 20)
- goto try_again;
-
- s->cbp_table[xy] = cbpc & (8 + 3); // 8 is dquant
-
- s->mb_intra = ((cbpc & 4) != 0);
-
- if (s->mb_intra) {
- s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
- s->mbintra_table[xy] = 1;
- mot_val[0] =
- mot_val[2] =
- mot_val[0 + stride] =
- mot_val[2 + stride] = 0;
- mot_val[1] =
- mot_val[3] =
- mot_val[1 + stride] =
- mot_val[3 + stride] = 0;
- } else {
- if (s->mbintra_table[xy])
- ff_clean_intra_table_entries(s);
-
- if (s->pict_type == AV_PICTURE_TYPE_S &&
- ctx->vol_sprite_usage == GMC_SPRITE &&
- (cbpc & 16) == 0)
- s->mcsel = get_bits1(&s->gb);
- else
- s->mcsel = 0;
-
- if ((cbpc & 16) == 0) {
- /* 16x16 motion prediction */
-
- ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
- if (!s->mcsel) {
- mx = ff_h263_decode_motion(s, pred_x, s->f_code);
- if (mx >= 0xffff)
- return -1;
-
- my = ff_h263_decode_motion(s, pred_y, s->f_code);
- if (my >= 0xffff)
- return -1;
- s->current_picture.mb_type[xy] = MB_TYPE_16x16 |
- MB_TYPE_L0;
- } else {
- mx = get_amv(ctx, 0);
- my = get_amv(ctx, 1);
- s->current_picture.mb_type[xy] = MB_TYPE_16x16 |
- MB_TYPE_GMC |
- MB_TYPE_L0;
- }
-
- mot_val[0] =
- mot_val[2] =
- mot_val[0 + stride] =
- mot_val[2 + stride] = mx;
- mot_val[1] =
- mot_val[3] =
- mot_val[1 + stride] =
- mot_val[3 + stride] = my;
- } else {
- int i;
- s->current_picture.mb_type[xy] = MB_TYPE_8x8 |
- MB_TYPE_L0;
- for (i = 0; i < 4; i++) {
- int16_t *mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
- mx = ff_h263_decode_motion(s, pred_x, s->f_code);
- if (mx >= 0xffff)
- return -1;
-
- my = ff_h263_decode_motion(s, pred_y, s->f_code);
- if (my >= 0xffff)
- return -1;
- mot_val[0] = mx;
- mot_val[1] = my;
- }
- }
- }
- }
- }
- s->mb_x = 0;
- }
-
- return mb_num;
-}
-
-/**
- * decode second partition.
- * @return <0 if an error occurred
- */
-static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count)
-{
- int mb_num = 0;
- static const int8_t quant_tab[4] = { -1, -2, 1, 2 };
-
- s->mb_x = s->resync_mb_x;
- s->first_slice_line = 1;
- for (s->mb_y = s->resync_mb_y; mb_num < mb_count; s->mb_y++) {
- ff_init_block_index(s);
- for (; mb_num < mb_count && s->mb_x < s->mb_width; s->mb_x++) {
- const int xy = s->mb_x + s->mb_y * s->mb_stride;
-
- mb_num++;
- ff_update_block_index(s);
- if (s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y + 1)
- s->first_slice_line = 0;
-
- if (s->pict_type == AV_PICTURE_TYPE_I) {
- int ac_pred = get_bits1(&s->gb);
- int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
- if (cbpy < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
-
- s->cbp_table[xy] |= cbpy << 2;
- s->current_picture.mb_type[xy] |= ac_pred * MB_TYPE_ACPRED;
- } else { /* P || S_TYPE */
- if (IS_INTRA(s->current_picture.mb_type[xy])) {
- int i;
- int dir = 0;
- int ac_pred = get_bits1(&s->gb);
- int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
-
- if (cbpy < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "I cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
-
- if (s->cbp_table[xy] & 8)
- ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
- s->current_picture.qscale_table[xy] = s->qscale;
-
- for (i = 0; i < 6; i++) {
- int dc_pred_dir;
- int dc = mpeg4_decode_dc(s, i, &dc_pred_dir);
- if (dc < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "DC corrupted at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- dir <<= 1;
- if (dc_pred_dir)
- dir |= 1;
- }
- s->cbp_table[xy] &= 3; // remove dquant
- s->cbp_table[xy] |= cbpy << 2;
- s->current_picture.mb_type[xy] |= ac_pred * MB_TYPE_ACPRED;
- s->pred_dir_table[xy] = dir;
- } else if (IS_SKIP(s->current_picture.mb_type[xy])) {
- s->current_picture.qscale_table[xy] = s->qscale;
- s->cbp_table[xy] = 0;
- } else {
- int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
-
- if (cbpy < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "P cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
-
- if (s->cbp_table[xy] & 8)
- ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
- s->current_picture.qscale_table[xy] = s->qscale;
-
- s->cbp_table[xy] &= 3; // remove dquant
- s->cbp_table[xy] |= (cbpy ^ 0xf) << 2;
- }
- }
- }
- if (mb_num >= mb_count)
- return 0;
- s->mb_x = 0;
- }
- return 0;
-}
-
-/**
- * Decode the first and second partition.
- * @return <0 if error (and sets error type in the error_status_table)
- */
-int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx)
-{
- MpegEncContext *s = &ctx->m;
- int mb_num;
- const int part_a_error = s->pict_type == AV_PICTURE_TYPE_I ? (ER_DC_ERROR | ER_MV_ERROR) : ER_MV_ERROR;
- const int part_a_end = s->pict_type == AV_PICTURE_TYPE_I ? (ER_DC_END | ER_MV_END) : ER_MV_END;
-
- mb_num = mpeg4_decode_partition_a(ctx);
- if (mb_num <= 0) {
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
- s->mb_x, s->mb_y, part_a_error);
- return -1;
- }
-
- if (s->resync_mb_x + s->resync_mb_y * s->mb_width + mb_num > s->mb_num) {
- av_log(s->avctx, AV_LOG_ERROR, "slice below monitor ...\n");
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
- s->mb_x, s->mb_y, part_a_error);
- return -1;
- }
-
- s->mb_num_left = mb_num;
-
- if (s->pict_type == AV_PICTURE_TYPE_I) {
- while (show_bits(&s->gb, 9) == 1)
- skip_bits(&s->gb, 9);
- if (get_bits_long(&s->gb, 19) != DC_MARKER) {
- av_log(s->avctx, AV_LOG_ERROR,
- "marker missing after first I partition at %d %d\n",
- s->mb_x, s->mb_y);
- return -1;
- }
- } else {
- while (show_bits(&s->gb, 10) == 1)
- skip_bits(&s->gb, 10);
- if (get_bits(&s->gb, 17) != MOTION_MARKER) {
- av_log(s->avctx, AV_LOG_ERROR,
- "marker missing after first P partition at %d %d\n",
- s->mb_x, s->mb_y);
- return -1;
- }
- }
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
- s->mb_x - 1, s->mb_y, part_a_end);
-
- if (mpeg4_decode_partition_b(s, mb_num) < 0) {
- if (s->pict_type == AV_PICTURE_TYPE_P)
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
- s->mb_x, s->mb_y, ER_DC_ERROR);
- return -1;
- } else {
- if (s->pict_type == AV_PICTURE_TYPE_P)
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
- s->mb_x - 1, s->mb_y, ER_DC_END);
- }
-
- return 0;
-}
-
-/**
- * Decode a block.
- * @return <0 if an error occurred
- */
-static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block,
- int n, int coded, int intra, int rvlc)
-{
- MpegEncContext *s = &ctx->m;
- int level, i, last, run, qmul, qadd;
- int av_uninit(dc_pred_dir);
- RLTable *rl;
- RL_VLC_ELEM *rl_vlc;
- const uint8_t *scan_table;
-
- // Note intra & rvlc should be optimized away if this is inlined
-
- if (intra) {
- if (ctx->use_intra_dc_vlc) {
- /* DC coef */
- if (s->partitioned_frame) {
- level = s->dc_val[0][s->block_index[n]];
- if (n < 4)
- level = FASTDIV((level + (s->y_dc_scale >> 1)), s->y_dc_scale);
- else
- level = FASTDIV((level + (s->c_dc_scale >> 1)), s->c_dc_scale);
- dc_pred_dir = (s->pred_dir_table[s->mb_x + s->mb_y * s->mb_stride] << n) & 32;
- } else {
- level = mpeg4_decode_dc(s, n, &dc_pred_dir);
- if (level < 0)
- return -1;
- }
- block[0] = level;
- i = 0;
- } else {
- i = -1;
- ff_mpeg4_pred_dc(s, n, 0, &dc_pred_dir, 0);
- }
- if (!coded)
- goto not_coded;
-
- if (rvlc) {
- rl = &ff_rvlc_rl_intra;
- rl_vlc = ff_rvlc_rl_intra.rl_vlc[0];
- } else {
- rl = &ff_mpeg4_rl_intra;
- rl_vlc = ff_mpeg4_rl_intra.rl_vlc[0];
- }
- if (s->ac_pred) {
- if (dc_pred_dir == 0)
- scan_table = s->intra_v_scantable.permutated; /* left */
- else
- scan_table = s->intra_h_scantable.permutated; /* top */
- } else {
- scan_table = s->intra_scantable.permutated;
- }
- qmul = 1;
- qadd = 0;
- } else {
- i = -1;
- if (!coded) {
- s->block_last_index[n] = i;
- return 0;
- }
- if (rvlc)
- rl = &ff_rvlc_rl_inter;
- else
- rl = &ff_h263_rl_inter;
-
- scan_table = s->intra_scantable.permutated;
-
- if (s->mpeg_quant) {
- qmul = 1;
- qadd = 0;
- if (rvlc)
- rl_vlc = ff_rvlc_rl_inter.rl_vlc[0];
- else
- rl_vlc = ff_h263_rl_inter.rl_vlc[0];
- } else {
- qmul = s->qscale << 1;
- qadd = (s->qscale - 1) | 1;
- if (rvlc)
- rl_vlc = ff_rvlc_rl_inter.rl_vlc[s->qscale];
- else
- rl_vlc = ff_h263_rl_inter.rl_vlc[s->qscale];
- }
- }
- {
- OPEN_READER(re, &s->gb);
- for (;;) {
- UPDATE_CACHE(re, &s->gb);
- GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0);
- if (level == 0) {
- /* escape */
- if (rvlc) {
- if (SHOW_UBITS(re, &s->gb, 1) == 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "1. marker bit missing in rvlc esc\n");
- return -1;
- }
- SKIP_CACHE(re, &s->gb, 1);
-
- last = SHOW_UBITS(re, &s->gb, 1);
- SKIP_CACHE(re, &s->gb, 1);
- run = SHOW_UBITS(re, &s->gb, 6);
- SKIP_COUNTER(re, &s->gb, 1 + 1 + 6);
- UPDATE_CACHE(re, &s->gb);
-
- if (SHOW_UBITS(re, &s->gb, 1) == 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "2. marker bit missing in rvlc esc\n");
- return -1;
- }
- SKIP_CACHE(re, &s->gb, 1);
-
- level = SHOW_UBITS(re, &s->gb, 11);
- SKIP_CACHE(re, &s->gb, 11);
-
- if (SHOW_UBITS(re, &s->gb, 5) != 0x10) {
- av_log(s->avctx, AV_LOG_ERROR, "reverse esc missing\n");
- return -1;
- }
- SKIP_CACHE(re, &s->gb, 5);
-
- level = level * qmul + qadd;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- SKIP_COUNTER(re, &s->gb, 1 + 11 + 5 + 1);
-
- i += run + 1;
- if (last)
- i += 192;
- } else {
- int cache;
- cache = GET_CACHE(re, &s->gb);
-
- if (IS_3IV1)
- cache ^= 0xC0000000;
-
- if (cache & 0x80000000) {
- if (cache & 0x40000000) {
- /* third escape */
- SKIP_CACHE(re, &s->gb, 2);
- last = SHOW_UBITS(re, &s->gb, 1);
- SKIP_CACHE(re, &s->gb, 1);
- run = SHOW_UBITS(re, &s->gb, 6);
- SKIP_COUNTER(re, &s->gb, 2 + 1 + 6);
- UPDATE_CACHE(re, &s->gb);
-
- if (IS_3IV1) {
- level = SHOW_SBITS(re, &s->gb, 12);
- LAST_SKIP_BITS(re, &s->gb, 12);
- } else {
- if (SHOW_UBITS(re, &s->gb, 1) == 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "1. marker bit missing in 3. esc\n");
- if (!(s->avctx->err_recognition & AV_EF_IGNORE_ERR))
- return -1;
- }
- SKIP_CACHE(re, &s->gb, 1);
-
- level = SHOW_SBITS(re, &s->gb, 12);
- SKIP_CACHE(re, &s->gb, 12);
-
- if (SHOW_UBITS(re, &s->gb, 1) == 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "2. marker bit missing in 3. esc\n");
- if (!(s->avctx->err_recognition & AV_EF_IGNORE_ERR))
- return -1;
- }
-
- SKIP_COUNTER(re, &s->gb, 1 + 12 + 1);
- }
-
-#if 0
- if (s->error_recognition >= FF_ER_COMPLIANT) {
- const int abs_level= FFABS(level);
- if (abs_level<=MAX_LEVEL && run<=MAX_RUN) {
- const int run1= run - rl->max_run[last][abs_level] - 1;
- if (abs_level <= rl->max_level[last][run]) {
- av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n");
- return -1;
- }
- if (s->error_recognition > FF_ER_COMPLIANT) {
- if (abs_level <= rl->max_level[last][run]*2) {
- av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n");
- return -1;
- }
- if (run1 >= 0 && abs_level <= rl->max_level[last][run1]) {
- av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 2 encoding possible\n");
- return -1;
- }
- }
- }
- }
-#endif
- if (level > 0)
- level = level * qmul + qadd;
- else
- level = level * qmul - qadd;
-
- if ((unsigned)(level + 2048) > 4095) {
- if (s->avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_AGGRESSIVE)) {
- if (level > 2560 || level < -2560) {
- av_log(s->avctx, AV_LOG_ERROR,
- "|level| overflow in 3. esc, qp=%d\n",
- s->qscale);
- return -1;
- }
- }
- level = level < 0 ? -2048 : 2047;
- }
-
- i += run + 1;
- if (last)
- i += 192;
- } else {
- /* second escape */
- SKIP_BITS(re, &s->gb, 2);
- GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
- i += run + rl->max_run[run >> 7][level / qmul] + 1; // FIXME opt indexing
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
- }
- } else {
- /* first escape */
- SKIP_BITS(re, &s->gb, 1);
- GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
- i += run;
- level = level + rl->max_level[run >> 7][(run - 1) & 63] * qmul; // FIXME opt indexing
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
- }
- }
- } else {
- i += run;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
- }
- ff_tlog(s->avctx, "dct[%d][%d] = %- 4d end?:%d\n", scan_table[i&63]&7, scan_table[i&63] >> 3, level, i>62);
- if (i > 62) {
- i -= 192;
- if (i & (~63)) {
- av_log(s->avctx, AV_LOG_ERROR,
- "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
-
- block[scan_table[i]] = level;
- break;
- }
-
- block[scan_table[i]] = level;
- }
- CLOSE_READER(re, &s->gb);
- }
-
-not_coded:
- if (intra) {
- if (!ctx->use_intra_dc_vlc) {
- block[0] = ff_mpeg4_pred_dc(s, n, block[0], &dc_pred_dir, 0);
-
- i -= i >> 31; // if (i == -1) i = 0;
- }
-
- ff_mpeg4_pred_ac(s, block, n, dc_pred_dir);
- if (s->ac_pred)
- i = 63; // FIXME not optimal
- }
- s->block_last_index[n] = i;
- return 0;
-}
-
-/**
- * decode partition C of one MB.
- * @return <0 if an error occurred
- */
-static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64])
-{
- Mpeg4DecContext *ctx = (Mpeg4DecContext *)s;
- int cbp, mb_type;
- const int xy = s->mb_x + s->mb_y * s->mb_stride;
-
- mb_type = s->current_picture.mb_type[xy];
- cbp = s->cbp_table[xy];
-
- ctx->use_intra_dc_vlc = s->qscale < ctx->intra_dc_threshold;
-
- if (s->current_picture.qscale_table[xy] != s->qscale)
- ff_set_qscale(s, s->current_picture.qscale_table[xy]);
-
- if (s->pict_type == AV_PICTURE_TYPE_P ||
- s->pict_type == AV_PICTURE_TYPE_S) {
- int i;
- for (i = 0; i < 4; i++) {
- s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];
- s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];
- }
- s->mb_intra = IS_INTRA(mb_type);
-
- if (IS_SKIP(mb_type)) {
- /* skip mb */
- for (i = 0; i < 6; i++)
- s->block_last_index[i] = -1;
- s->mv_dir = MV_DIR_FORWARD;
- s->mv_type = MV_TYPE_16X16;
- if (s->pict_type == AV_PICTURE_TYPE_S
- && ctx->vol_sprite_usage == GMC_SPRITE) {
- s->mcsel = 1;
- s->mb_skipped = 0;
- } else {
- s->mcsel = 0;
- s->mb_skipped = 1;
- }
- } else if (s->mb_intra) {
- s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]);
- } else if (!s->mb_intra) {
- // s->mcsel = 0; // FIXME do we need to init that?
-
- s->mv_dir = MV_DIR_FORWARD;
- if (IS_8X8(mb_type)) {
- s->mv_type = MV_TYPE_8X8;
- } else {
- s->mv_type = MV_TYPE_16X16;
- }
- }
- } else { /* I-Frame */
- s->mb_intra = 1;
- s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]);
- }
-
- if (!IS_SKIP(mb_type)) {
- int i;
- s->bdsp.clear_blocks(s->block[0]);
- /* decode each block */
- for (i = 0; i < 6; i++) {
- if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, s->mb_intra, ctx->rvlc) < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "texture corrupted at %d %d %d\n",
- s->mb_x, s->mb_y, s->mb_intra);
- return -1;
- }
- cbp += cbp;
- }
- }
-
- /* per-MB end of slice check */
- if (--s->mb_num_left <= 0) {
- if (mpeg4_is_resync(ctx))
- return SLICE_END;
- else
- return SLICE_NOEND;
- } else {
- if (mpeg4_is_resync(ctx)) {
- const int delta = s->mb_x + 1 == s->mb_width ? 2 : 1;
- if (s->cbp_table[xy + delta])
- return SLICE_END;
- }
- return SLICE_OK;
- }
-}
-
-static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64])
-{
- Mpeg4DecContext *ctx = (Mpeg4DecContext *)s;
- int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
- int16_t *mot_val;
- static const int8_t quant_tab[4] = { -1, -2, 1, 2 };
- const int xy = s->mb_x + s->mb_y * s->mb_stride;
-
- av_assert2(s->h263_pred);
-
- if (s->pict_type == AV_PICTURE_TYPE_P ||
- s->pict_type == AV_PICTURE_TYPE_S) {
- do {
- if (get_bits1(&s->gb)) {
- /* skip mb */
- s->mb_intra = 0;
- for (i = 0; i < 6; i++)
- s->block_last_index[i] = -1;
- s->mv_dir = MV_DIR_FORWARD;
- s->mv_type = MV_TYPE_16X16;
- if (s->pict_type == AV_PICTURE_TYPE_S &&
- ctx->vol_sprite_usage == GMC_SPRITE) {
- s->current_picture.mb_type[xy] = MB_TYPE_SKIP |
- MB_TYPE_GMC |
- MB_TYPE_16x16 |
- MB_TYPE_L0;
- s->mcsel = 1;
- s->mv[0][0][0] = get_amv(ctx, 0);
- s->mv[0][0][1] = get_amv(ctx, 1);
- s->mb_skipped = 0;
- } else {
- s->current_picture.mb_type[xy] = MB_TYPE_SKIP |
- MB_TYPE_16x16 |
- MB_TYPE_L0;
- s->mcsel = 0;
- s->mv[0][0][0] = 0;
- s->mv[0][0][1] = 0;
- s->mb_skipped = 1;
- }
- goto end;
- }
- cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
- if (cbpc < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "mcbpc damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- } while (cbpc == 20);
-
- s->bdsp.clear_blocks(s->block[0]);
- dquant = cbpc & 8;
- s->mb_intra = ((cbpc & 4) != 0);
- if (s->mb_intra)
- goto intra;
-
- if (s->pict_type == AV_PICTURE_TYPE_S &&
- ctx->vol_sprite_usage == GMC_SPRITE && (cbpc & 16) == 0)
- s->mcsel = get_bits1(&s->gb);
- else
- s->mcsel = 0;
- cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1) ^ 0x0F;
- if (cbpy < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "P cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
- return AVERROR_INVALIDDATA;
- }
-
- cbp = (cbpc & 3) | (cbpy << 2);
- if (dquant)
- ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
- if ((!s->progressive_sequence) &&
- (cbp || (s->workaround_bugs & FF_BUG_XVID_ILACE)))
- s->interlaced_dct = get_bits1(&s->gb);
-
- s->mv_dir = MV_DIR_FORWARD;
- if ((cbpc & 16) == 0) {
- if (s->mcsel) {
- s->current_picture.mb_type[xy] = MB_TYPE_GMC |
- MB_TYPE_16x16 |
- MB_TYPE_L0;
- /* 16x16 global motion prediction */
- s->mv_type = MV_TYPE_16X16;
- mx = get_amv(ctx, 0);
- my = get_amv(ctx, 1);
- s->mv[0][0][0] = mx;
- s->mv[0][0][1] = my;
- } else if ((!s->progressive_sequence) && get_bits1(&s->gb)) {
- s->current_picture.mb_type[xy] = MB_TYPE_16x8 |
- MB_TYPE_L0 |
- MB_TYPE_INTERLACED;
- /* 16x8 field motion prediction */
- s->mv_type = MV_TYPE_FIELD;
-
- s->field_select[0][0] = get_bits1(&s->gb);
- s->field_select[0][1] = get_bits1(&s->gb);
-
- ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
-
- for (i = 0; i < 2; i++) {
- mx = ff_h263_decode_motion(s, pred_x, s->f_code);
- if (mx >= 0xffff)
- return -1;
-
- my = ff_h263_decode_motion(s, pred_y / 2, s->f_code);
- if (my >= 0xffff)
- return -1;
-
- s->mv[0][i][0] = mx;
- s->mv[0][i][1] = my;
- }
- } else {
- s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
- /* 16x16 motion prediction */
- s->mv_type = MV_TYPE_16X16;
- ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
- mx = ff_h263_decode_motion(s, pred_x, s->f_code);
-
- if (mx >= 0xffff)
- return -1;
-
- my = ff_h263_decode_motion(s, pred_y, s->f_code);
-
- if (my >= 0xffff)
- return -1;
- s->mv[0][0][0] = mx;
- s->mv[0][0][1] = my;
- }
- } else {
- s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
- s->mv_type = MV_TYPE_8X8;
- for (i = 0; i < 4; i++) {
- mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
- mx = ff_h263_decode_motion(s, pred_x, s->f_code);
- if (mx >= 0xffff)
- return -1;
-
- my = ff_h263_decode_motion(s, pred_y, s->f_code);
- if (my >= 0xffff)
- return -1;
- s->mv[0][i][0] = mx;
- s->mv[0][i][1] = my;
- mot_val[0] = mx;
- mot_val[1] = my;
- }
- }
- } else if (s->pict_type == AV_PICTURE_TYPE_B) {
- int modb1; // first bit of modb
- int modb2; // second bit of modb
- int mb_type;
-
- s->mb_intra = 0; // B-frames never contain intra blocks
- s->mcsel = 0; // ... true gmc blocks
-
- if (s->mb_x == 0) {
- for (i = 0; i < 2; i++) {
- s->last_mv[i][0][0] =
- s->last_mv[i][0][1] =
- s->last_mv[i][1][0] =
- s->last_mv[i][1][1] = 0;
- }
-
- ff_thread_await_progress(&s->next_picture_ptr->tf, s->mb_y, 0);
- }
-
- /* if we skipped it in the future P Frame than skip it now too */
- s->mb_skipped = s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC
-
- if (s->mb_skipped) {
- /* skip mb */
- for (i = 0; i < 6; i++)
- s->block_last_index[i] = -1;
-
- s->mv_dir = MV_DIR_FORWARD;
- s->mv_type = MV_TYPE_16X16;
- s->mv[0][0][0] =
- s->mv[0][0][1] =
- s->mv[1][0][0] =
- s->mv[1][0][1] = 0;
- s->current_picture.mb_type[xy] = MB_TYPE_SKIP |
- MB_TYPE_16x16 |
- MB_TYPE_L0;
- goto end;
- }
-
- modb1 = get_bits1(&s->gb);
- if (modb1) {
- // like MB_TYPE_B_DIRECT but no vectors coded
- mb_type = MB_TYPE_DIRECT2 | MB_TYPE_SKIP | MB_TYPE_L0L1;
- cbp = 0;
- } else {
- modb2 = get_bits1(&s->gb);
- mb_type = get_vlc2(&s->gb, mb_type_b_vlc.table, MB_TYPE_B_VLC_BITS, 1);
- if (mb_type < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "illegal MB_type\n");
- return -1;
- }
- mb_type = mb_type_b_map[mb_type];
- if (modb2) {
- cbp = 0;
- } else {
- s->bdsp.clear_blocks(s->block[0]);
- cbp = get_bits(&s->gb, 6);
- }
-
- if ((!IS_DIRECT(mb_type)) && cbp) {
- if (get_bits1(&s->gb))
- ff_set_qscale(s, s->qscale + get_bits1(&s->gb) * 4 - 2);
- }
-
- if (!s->progressive_sequence) {
- if (cbp)
- s->interlaced_dct = get_bits1(&s->gb);
-
- if (!IS_DIRECT(mb_type) && get_bits1(&s->gb)) {
- mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
- mb_type &= ~MB_TYPE_16x16;
-
- if (USES_LIST(mb_type, 0)) {
- s->field_select[0][0] = get_bits1(&s->gb);
- s->field_select[0][1] = get_bits1(&s->gb);
- }
- if (USES_LIST(mb_type, 1)) {
- s->field_select[1][0] = get_bits1(&s->gb);
- s->field_select[1][1] = get_bits1(&s->gb);
- }
- }
- }
-
- s->mv_dir = 0;
- if ((mb_type & (MB_TYPE_DIRECT2 | MB_TYPE_INTERLACED)) == 0) {
- s->mv_type = MV_TYPE_16X16;
-
- if (USES_LIST(mb_type, 0)) {
- s->mv_dir = MV_DIR_FORWARD;
-
- mx = ff_h263_decode_motion(s, s->last_mv[0][0][0], s->f_code);
- my = ff_h263_decode_motion(s, s->last_mv[0][0][1], s->f_code);
- s->last_mv[0][1][0] =
- s->last_mv[0][0][0] =
- s->mv[0][0][0] = mx;
- s->last_mv[0][1][1] =
- s->last_mv[0][0][1] =
- s->mv[0][0][1] = my;
- }
-
- if (USES_LIST(mb_type, 1)) {
- s->mv_dir |= MV_DIR_BACKWARD;
-
- mx = ff_h263_decode_motion(s, s->last_mv[1][0][0], s->b_code);
- my = ff_h263_decode_motion(s, s->last_mv[1][0][1], s->b_code);
- s->last_mv[1][1][0] =
- s->last_mv[1][0][0] =
- s->mv[1][0][0] = mx;
- s->last_mv[1][1][1] =
- s->last_mv[1][0][1] =
- s->mv[1][0][1] = my;
- }
- } else if (!IS_DIRECT(mb_type)) {
- s->mv_type = MV_TYPE_FIELD;
-
- if (USES_LIST(mb_type, 0)) {
- s->mv_dir = MV_DIR_FORWARD;
-
- for (i = 0; i < 2; i++) {
- mx = ff_h263_decode_motion(s, s->last_mv[0][i][0], s->f_code);
- my = ff_h263_decode_motion(s, s->last_mv[0][i][1] / 2, s->f_code);
- s->last_mv[0][i][0] =
- s->mv[0][i][0] = mx;
- s->last_mv[0][i][1] = (s->mv[0][i][1] = my) * 2;
- }
- }
-
- if (USES_LIST(mb_type, 1)) {
- s->mv_dir |= MV_DIR_BACKWARD;
-
- for (i = 0; i < 2; i++) {
- mx = ff_h263_decode_motion(s, s->last_mv[1][i][0], s->b_code);
- my = ff_h263_decode_motion(s, s->last_mv[1][i][1] / 2, s->b_code);
- s->last_mv[1][i][0] =
- s->mv[1][i][0] = mx;
- s->last_mv[1][i][1] = (s->mv[1][i][1] = my) * 2;
- }
- }
- }
- }
-
- if (IS_DIRECT(mb_type)) {
- if (IS_SKIP(mb_type)) {
- mx =
- my = 0;
- } else {
- mx = ff_h263_decode_motion(s, 0, 1);
- my = ff_h263_decode_motion(s, 0, 1);
- }
-
- s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
- mb_type |= ff_mpeg4_set_direct_mv(s, mx, my);
- }
- s->current_picture.mb_type[xy] = mb_type;
- } else { /* I-Frame */
- do {
- cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
- if (cbpc < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- } while (cbpc == 8);
-
- dquant = cbpc & 4;
- s->mb_intra = 1;
-
-intra:
- s->ac_pred = get_bits1(&s->gb);
- if (s->ac_pred)
- s->current_picture.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
- else
- s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
-
- cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
- if (cbpy < 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- cbp = (cbpc & 3) | (cbpy << 2);
-
- ctx->use_intra_dc_vlc = s->qscale < ctx->intra_dc_threshold;
-
- if (dquant)
- ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
-
- if (!s->progressive_sequence)
- s->interlaced_dct = get_bits1(&s->gb);
-
- s->bdsp.clear_blocks(s->block[0]);
- /* decode each block */
- for (i = 0; i < 6; i++) {
- if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, 1, 0) < 0)
- return -1;
- cbp += cbp;
- }
- goto end;
- }
-
- /* decode each block */
- for (i = 0; i < 6; i++) {
- if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, 0, 0) < 0)
- return -1;
- cbp += cbp;
- }
-
-end:
- /* per-MB end of slice check */
- if (s->codec_id == AV_CODEC_ID_MPEG4) {
- int next = mpeg4_is_resync(ctx);
- if (next) {
- if (s->mb_x + s->mb_y*s->mb_width + 1 > next && (s->avctx->err_recognition & AV_EF_AGGRESSIVE)) {
- return -1;
- } else if (s->mb_x + s->mb_y*s->mb_width + 1 >= next)
- return SLICE_END;
-
- if (s->pict_type == AV_PICTURE_TYPE_B) {
- const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1;
- ff_thread_await_progress(&s->next_picture_ptr->tf,
- (s->mb_x + delta >= s->mb_width)
- ? FFMIN(s->mb_y + 1, s->mb_height - 1)
- : s->mb_y, 0);
- if (s->next_picture.mbskip_table[xy + delta])
- return SLICE_OK;
- }
-
- return SLICE_END;
- }
- }
-
- return SLICE_OK;
-}
-
-static int mpeg4_decode_gop_header(MpegEncContext *s, GetBitContext *gb)
-{
- int hours, minutes, seconds;
-
- if (!show_bits(gb, 23)) {
- av_log(s->avctx, AV_LOG_WARNING, "GOP header invalid\n");
- return -1;
- }
-
- hours = get_bits(gb, 5);
- minutes = get_bits(gb, 6);
- check_marker(gb, "in gop_header");
- seconds = get_bits(gb, 6);
-
- s->time_base = seconds + 60*(minutes + 60*hours);
-
- skip_bits1(gb);
- skip_bits1(gb);
-
- return 0;
-}
-
-static int mpeg4_decode_profile_level(MpegEncContext *s, GetBitContext *gb)
-{
-
- s->avctx->profile = get_bits(gb, 4);
- s->avctx->level = get_bits(gb, 4);
-
- // for Simple profile, level 0
- if (s->avctx->profile == 0 && s->avctx->level == 8) {
- s->avctx->level = 0;
- }
-
- return 0;
-}
-
-static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb)
-{
- MpegEncContext *s = &ctx->m;
- int width, height, vo_ver_id;
-
- /* vol header */
- skip_bits(gb, 1); /* random access */
- s->vo_type = get_bits(gb, 8);
- if (get_bits1(gb) != 0) { /* is_ol_id */
- vo_ver_id = get_bits(gb, 4); /* vo_ver_id */
- skip_bits(gb, 3); /* vo_priority */
- } else {
- vo_ver_id = 1;
- }
- s->aspect_ratio_info = get_bits(gb, 4);
- if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) {
- s->avctx->sample_aspect_ratio.num = get_bits(gb, 8); // par_width
- s->avctx->sample_aspect_ratio.den = get_bits(gb, 8); // par_height
- } else {
- s->avctx->sample_aspect_ratio = ff_h263_pixel_aspect[s->aspect_ratio_info];
- }
-
- if ((ctx->vol_control_parameters = get_bits1(gb))) { /* vol control parameter */
- int chroma_format = get_bits(gb, 2);
- if (chroma_format != CHROMA_420)
- av_log(s->avctx, AV_LOG_ERROR, "illegal chroma format\n");
-
- s->low_delay = get_bits1(gb);
- if (get_bits1(gb)) { /* vbv parameters */
- get_bits(gb, 15); /* first_half_bitrate */
- check_marker(gb, "after first_half_bitrate");
- get_bits(gb, 15); /* latter_half_bitrate */
- check_marker(gb, "after latter_half_bitrate");
- get_bits(gb, 15); /* first_half_vbv_buffer_size */
- check_marker(gb, "after first_half_vbv_buffer_size");
- get_bits(gb, 3); /* latter_half_vbv_buffer_size */
- get_bits(gb, 11); /* first_half_vbv_occupancy */
- check_marker(gb, "after first_half_vbv_occupancy");
- get_bits(gb, 15); /* latter_half_vbv_occupancy */
- check_marker(gb, "after latter_half_vbv_occupancy");
- }
- } else {
- /* is setting low delay flag only once the smartest thing to do?
- * low delay detection won't be overridden. */
- if (s->picture_number == 0)
- s->low_delay = 0;
- }
-
- ctx->shape = get_bits(gb, 2); /* vol shape */
- if (ctx->shape != RECT_SHAPE)
- av_log(s->avctx, AV_LOG_ERROR, "only rectangular vol supported\n");
- if (ctx->shape == GRAY_SHAPE && vo_ver_id != 1) {
- av_log(s->avctx, AV_LOG_ERROR, "Gray shape not supported\n");
- skip_bits(gb, 4); /* video_object_layer_shape_extension */
- }
-
- check_marker(gb, "before time_increment_resolution");
-
- s->avctx->framerate.num = get_bits(gb, 16);
- if (!s->avctx->framerate.num) {
- av_log(s->avctx, AV_LOG_ERROR, "framerate==0\n");
- return AVERROR_INVALIDDATA;
- }
-
- ctx->time_increment_bits = av_log2(s->avctx->framerate.num - 1) + 1;
- if (ctx->time_increment_bits < 1)
- ctx->time_increment_bits = 1;
-
- check_marker(gb, "before fixed_vop_rate");
-
- if (get_bits1(gb) != 0) /* fixed_vop_rate */
- s->avctx->framerate.den = get_bits(gb, ctx->time_increment_bits);
- else
- s->avctx->framerate.den = 1;
-
- s->avctx->time_base = av_inv_q(av_mul_q(s->avctx->framerate, (AVRational){s->avctx->ticks_per_frame, 1}));
-
- ctx->t_frame = 0;
-
- if (ctx->shape != BIN_ONLY_SHAPE) {
- if (ctx->shape == RECT_SHAPE) {
- check_marker(gb, "before width");
- width = get_bits(gb, 13);
- check_marker(gb, "before height");
- height = get_bits(gb, 13);
- check_marker(gb, "after height");
- if (width && height && /* they should be non zero but who knows */
- !(s->width && s->codec_tag == AV_RL32("MP4S"))) {
- if (s->width && s->height &&
- (s->width != width || s->height != height))
- s->context_reinit = 1;
- s->width = width;
- s->height = height;
- }
- }
-
- s->progressive_sequence =
- s->progressive_frame = get_bits1(gb) ^ 1;
- s->interlaced_dct = 0;
- if (!get_bits1(gb) && (s->avctx->debug & FF_DEBUG_PICT_INFO))
- av_log(s->avctx, AV_LOG_INFO, /* OBMC Disable */
- "MPEG4 OBMC not supported (very likely buggy encoder)\n");
- if (vo_ver_id == 1)
- ctx->vol_sprite_usage = get_bits1(gb); /* vol_sprite_usage */
- else
- ctx->vol_sprite_usage = get_bits(gb, 2); /* vol_sprite_usage */
-
- if (ctx->vol_sprite_usage == STATIC_SPRITE)
- av_log(s->avctx, AV_LOG_ERROR, "Static Sprites not supported\n");
- if (ctx->vol_sprite_usage == STATIC_SPRITE ||
- ctx->vol_sprite_usage == GMC_SPRITE) {
- if (ctx->vol_sprite_usage == STATIC_SPRITE) {
- skip_bits(gb, 13); // sprite_width
- check_marker(gb, "after sprite_width");
- skip_bits(gb, 13); // sprite_height
- check_marker(gb, "after sprite_height");
- skip_bits(gb, 13); // sprite_left
- check_marker(gb, "after sprite_left");
- skip_bits(gb, 13); // sprite_top
- check_marker(gb, "after sprite_top");
- }
- ctx->num_sprite_warping_points = get_bits(gb, 6);
- if (ctx->num_sprite_warping_points > 3) {
- av_log(s->avctx, AV_LOG_ERROR,
- "%d sprite_warping_points\n",
- ctx->num_sprite_warping_points);
- ctx->num_sprite_warping_points = 0;
- return AVERROR_INVALIDDATA;
- }
- s->sprite_warping_accuracy = get_bits(gb, 2);
- ctx->sprite_brightness_change = get_bits1(gb);
- if (ctx->vol_sprite_usage == STATIC_SPRITE)
- skip_bits1(gb); // low_latency_sprite
- }
- // FIXME sadct disable bit if verid!=1 && shape not rect
-
- if (get_bits1(gb) == 1) { /* not_8_bit */
- s->quant_precision = get_bits(gb, 4); /* quant_precision */
- if (get_bits(gb, 4) != 8) /* bits_per_pixel */
- av_log(s->avctx, AV_LOG_ERROR, "N-bit not supported\n");
- if (s->quant_precision != 5)
- av_log(s->avctx, AV_LOG_ERROR,
- "quant precision %d\n", s->quant_precision);
- if (s->quant_precision<3 || s->quant_precision>9) {
- s->quant_precision = 5;
- }
- } else {
- s->quant_precision = 5;
- }
-
- // FIXME a bunch of grayscale shape things
-
- if ((s->mpeg_quant = get_bits1(gb))) { /* vol_quant_type */
- int i, v;
-
- /* load default matrixes */
- for (i = 0; i < 64; i++) {
- int j = s->idsp.idct_permutation[i];
- v = ff_mpeg4_default_intra_matrix[i];
- s->intra_matrix[j] = v;
- s->chroma_intra_matrix[j] = v;
-
- v = ff_mpeg4_default_non_intra_matrix[i];
- s->inter_matrix[j] = v;
- s->chroma_inter_matrix[j] = v;
- }
-
- /* load custom intra matrix */
- if (get_bits1(gb)) {
- int last = 0;
- for (i = 0; i < 64; i++) {
- int j;
- if (get_bits_left(gb) < 8) {
- av_log(s->avctx, AV_LOG_ERROR, "insufficient data for custom matrix\n");
- return AVERROR_INVALIDDATA;
- }
- v = get_bits(gb, 8);
- if (v == 0)
- break;
-
- last = v;
- j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
- s->intra_matrix[j] = last;
- s->chroma_intra_matrix[j] = last;
- }
-
- /* replicate last value */
- for (; i < 64; i++) {
- int j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
- s->intra_matrix[j] = last;
- s->chroma_intra_matrix[j] = last;
- }
- }
-
- /* load custom non intra matrix */
- if (get_bits1(gb)) {
- int last = 0;
- for (i = 0; i < 64; i++) {
- int j;
- if (get_bits_left(gb) < 8) {
- av_log(s->avctx, AV_LOG_ERROR, "insufficient data for custom matrix\n");
- return AVERROR_INVALIDDATA;
- }
- v = get_bits(gb, 8);
- if (v == 0)
- break;
-
- last = v;
- j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
- s->inter_matrix[j] = v;
- s->chroma_inter_matrix[j] = v;
- }
-
- /* replicate last value */
- for (; i < 64; i++) {
- int j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
- s->inter_matrix[j] = last;
- s->chroma_inter_matrix[j] = last;
- }
- }
-
- // FIXME a bunch of grayscale shape things
- }
-
- if (vo_ver_id != 1)
- s->quarter_sample = get_bits1(gb);
- else
- s->quarter_sample = 0;
-
- if (get_bits_left(gb) < 4) {
- av_log(s->avctx, AV_LOG_ERROR, "VOL Header truncated\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (!get_bits1(gb)) {
- int pos = get_bits_count(gb);
- int estimation_method = get_bits(gb, 2);
- if (estimation_method < 2) {
- if (!get_bits1(gb)) {
- ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* opaque */
- ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* transparent */
- ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* intra_cae */
- ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* inter_cae */
- ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* no_update */
- ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* upampling */
- }
- if (!get_bits1(gb)) {
- ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* intra_blocks */
- ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* inter_blocks */
- ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* inter4v_blocks */
- ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* not coded blocks */
- }
- if (!check_marker(gb, "in complexity estimation part 1")) {
- skip_bits_long(gb, pos - get_bits_count(gb));
- goto no_cplx_est;
- }
- if (!get_bits1(gb)) {
- ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* dct_coeffs */
- ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* dct_lines */
- ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* vlc_syms */
- ctx->cplx_estimation_trash_i += 4 * get_bits1(gb); /* vlc_bits */
- }
- if (!get_bits1(gb)) {
- ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* apm */
- ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* npm */
- ctx->cplx_estimation_trash_b += 8 * get_bits1(gb); /* interpolate_mc_q */
- ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* forwback_mc_q */
- ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* halfpel2 */
- ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* halfpel4 */
- }
- if (!check_marker(gb, "in complexity estimation part 2")) {
- skip_bits_long(gb, pos - get_bits_count(gb));
- goto no_cplx_est;
- }
- if (estimation_method == 1) {
- ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* sadct */
- ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* qpel */
- }
- } else
- av_log(s->avctx, AV_LOG_ERROR,
- "Invalid Complexity estimation method %d\n",
- estimation_method);
- } else {
-
-no_cplx_est:
- ctx->cplx_estimation_trash_i =
- ctx->cplx_estimation_trash_p =
- ctx->cplx_estimation_trash_b = 0;
- }
-
- ctx->resync_marker = !get_bits1(gb); /* resync_marker_disabled */
-
- s->data_partitioning = get_bits1(gb);
- if (s->data_partitioning)
- ctx->rvlc = get_bits1(gb);
-
- if (vo_ver_id != 1) {
- ctx->new_pred = get_bits1(gb);
- if (ctx->new_pred) {
- av_log(s->avctx, AV_LOG_ERROR, "new pred not supported\n");
- skip_bits(gb, 2); /* requested upstream message type */
- skip_bits1(gb); /* newpred segment type */
- }
- if (get_bits1(gb)) // reduced_res_vop
- av_log(s->avctx, AV_LOG_ERROR,
- "reduced resolution VOP not supported\n");
- } else {
- ctx->new_pred = 0;
- }
-
- ctx->scalability = get_bits1(gb);
-
- if (ctx->scalability) {
- GetBitContext bak = *gb;
- int h_sampling_factor_n;
- int h_sampling_factor_m;
- int v_sampling_factor_n;
- int v_sampling_factor_m;
-
- skip_bits1(gb); // hierarchy_type
- skip_bits(gb, 4); /* ref_layer_id */
- skip_bits1(gb); /* ref_layer_sampling_dir */
- h_sampling_factor_n = get_bits(gb, 5);
- h_sampling_factor_m = get_bits(gb, 5);
- v_sampling_factor_n = get_bits(gb, 5);
- v_sampling_factor_m = get_bits(gb, 5);
- ctx->enhancement_type = get_bits1(gb);
-
- if (h_sampling_factor_n == 0 || h_sampling_factor_m == 0 ||
- v_sampling_factor_n == 0 || v_sampling_factor_m == 0) {
- /* illegal scalability header (VERY broken encoder),
- * trying to workaround */
- ctx->scalability = 0;
- *gb = bak;
- } else
- av_log(s->avctx, AV_LOG_ERROR, "scalability not supported\n");
-
- // bin shape stuff FIXME
- }
- }
-
- if (s->avctx->debug&FF_DEBUG_PICT_INFO) {
- av_log(s->avctx, AV_LOG_DEBUG, "tb %d/%d, tincrbits:%d, qp_prec:%d, ps:%d, %s%s%s%s\n",
- s->avctx->framerate.den, s->avctx->framerate.num,
- ctx->time_increment_bits,
- s->quant_precision,
- s->progressive_sequence,
- ctx->scalability ? "scalability " :"" , s->quarter_sample ? "qpel " : "",
- s->data_partitioning ? "partition " : "", ctx->rvlc ? "rvlc " : ""
- );
- }
-
- return 0;
-}
-
-/**
- * Decode the user data stuff in the header.
- * Also initializes divx/xvid/lavc_version/build.
- */
-static int decode_user_data(Mpeg4DecContext *ctx, GetBitContext *gb)
-{
- MpegEncContext *s = &ctx->m;
- char buf[256];
- int i;
- int e;
- int ver = 0, build = 0, ver2 = 0, ver3 = 0;
- char last;
-
- for (i = 0; i < 255 && get_bits_count(gb) < gb->size_in_bits; i++) {
- if (show_bits(gb, 23) == 0)
- break;
- buf[i] = get_bits(gb, 8);
- }
- buf[i] = 0;
-
- /* divx detection */
- e = sscanf(buf, "DivX%dBuild%d%c", &ver, &build, &last);
- if (e < 2)
- e = sscanf(buf, "DivX%db%d%c", &ver, &build, &last);
- if (e >= 2) {
- ctx->divx_version = ver;
- ctx->divx_build = build;
- s->divx_packed = e == 3 && last == 'p';
- }
-
- /* libavcodec detection */
- e = sscanf(buf, "FFmpe%*[^b]b%d", &build) + 3;
- if (e != 4)
- e = sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build);
- if (e != 4) {
- e = sscanf(buf, "Lavc%d.%d.%d", &ver, &ver2, &ver3) + 1;
- if (e > 1)
- build = (ver << 16) + (ver2 << 8) + ver3;
- }
- if (e != 4) {
- if (strcmp(buf, "ffmpeg") == 0)
- ctx->lavc_build = 4600;
- }
- if (e == 4)
- ctx->lavc_build = build;
-
- /* Xvid detection */
- e = sscanf(buf, "XviD%d", &build);
- if (e == 1)
- ctx->xvid_build = build;
-
- return 0;
-}
-
-int ff_mpeg4_workaround_bugs(AVCodecContext *avctx)
-{
- Mpeg4DecContext *ctx = avctx->priv_data;
- MpegEncContext *s = &ctx->m;
-
- if (ctx->xvid_build == -1 && ctx->divx_version == -1 && ctx->lavc_build == -1) {
- if (s->codec_tag == AV_RL32("XVID") ||
- s->codec_tag == AV_RL32("XVIX") ||
- s->codec_tag == AV_RL32("RMP4") ||
- s->codec_tag == AV_RL32("ZMP4") ||
- s->codec_tag == AV_RL32("SIPP"))
- ctx->xvid_build = 0;
- }
-
- if (ctx->xvid_build == -1 && ctx->divx_version == -1 && ctx->lavc_build == -1)
- if (s->codec_tag == AV_RL32("DIVX") && s->vo_type == 0 &&
- ctx->vol_control_parameters == 0)
- ctx->divx_version = 400; // divx 4
-
- if (ctx->xvid_build >= 0 && ctx->divx_version >= 0) {
- ctx->divx_version =
- ctx->divx_build = -1;
- }
-
- if (s->workaround_bugs & FF_BUG_AUTODETECT) {
- if (s->codec_tag == AV_RL32("XVIX"))
- s->workaround_bugs |= FF_BUG_XVID_ILACE;
-
- if (s->codec_tag == AV_RL32("UMP4"))
- s->workaround_bugs |= FF_BUG_UMP4;
-
- if (ctx->divx_version >= 500 && ctx->divx_build < 1814)
- s->workaround_bugs |= FF_BUG_QPEL_CHROMA;
-
- if (ctx->divx_version > 502 && ctx->divx_build < 1814)
- s->workaround_bugs |= FF_BUG_QPEL_CHROMA2;
-
- if (ctx->xvid_build <= 3U)
- s->padding_bug_score = 256 * 256 * 256 * 64;
-
- if (ctx->xvid_build <= 1U)
- s->workaround_bugs |= FF_BUG_QPEL_CHROMA;
-
- if (ctx->xvid_build <= 12U)
- s->workaround_bugs |= FF_BUG_EDGE;
-
- if (ctx->xvid_build <= 32U)
- s->workaround_bugs |= FF_BUG_DC_CLIP;
-
-#define SET_QPEL_FUNC(postfix1, postfix2) \
- s->qdsp.put_ ## postfix1 = ff_put_ ## postfix2; \
- s->qdsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2; \
- s->qdsp.avg_ ## postfix1 = ff_avg_ ## postfix2;
-
- if (ctx->lavc_build < 4653U)
- s->workaround_bugs |= FF_BUG_STD_QPEL;
-
- if (ctx->lavc_build < 4655U)
- s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE;
-
- if (ctx->lavc_build < 4670U)
- s->workaround_bugs |= FF_BUG_EDGE;
-
- if (ctx->lavc_build <= 4712U)
- s->workaround_bugs |= FF_BUG_DC_CLIP;
-
- if (ctx->divx_version >= 0)
- s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE;
- if (ctx->divx_version == 501 && ctx->divx_build == 20020416)
- s->padding_bug_score = 256 * 256 * 256 * 64;
-
- if (ctx->divx_version < 500U)
- s->workaround_bugs |= FF_BUG_EDGE;
-
- if (ctx->divx_version >= 0)
- s->workaround_bugs |= FF_BUG_HPEL_CHROMA;
- }
-
- if (s->workaround_bugs & FF_BUG_STD_QPEL) {
- SET_QPEL_FUNC(qpel_pixels_tab[0][5], qpel16_mc11_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[0][7], qpel16_mc31_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[0][9], qpel16_mc12_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_old_c)
-
- SET_QPEL_FUNC(qpel_pixels_tab[1][5], qpel8_mc11_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[1][7], qpel8_mc31_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[1][9], qpel8_mc12_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_old_c)
- SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_old_c)
- }
-
- if (avctx->debug & FF_DEBUG_BUGS)
- av_log(s->avctx, AV_LOG_DEBUG,
- "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n",
- s->workaround_bugs, ctx->lavc_build, ctx->xvid_build,
- ctx->divx_version, ctx->divx_build, s->divx_packed ? "p" : "");
-
- if (CONFIG_MPEG4_DECODER && ctx->xvid_build >= 0 &&
- s->codec_id == AV_CODEC_ID_MPEG4 &&
- avctx->idct_algo == FF_IDCT_AUTO) {
- avctx->idct_algo = FF_IDCT_XVID;
- ff_mpv_idct_init(s);
- return 1;
- }
-
- return 0;
-}
-
-static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb)
-{
- MpegEncContext *s = &ctx->m;
- int time_incr, time_increment;
- int64_t pts;
-
- s->pict_type = get_bits(gb, 2) + AV_PICTURE_TYPE_I; /* pict type: I = 0 , P = 1 */
- if (s->pict_type == AV_PICTURE_TYPE_B && s->low_delay &&
- ctx->vol_control_parameters == 0 && !(s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY)) {
- av_log(s->avctx, AV_LOG_ERROR, "low_delay flag set incorrectly, clearing it\n");
- s->low_delay = 0;
- }
-
- s->partitioned_frame = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B;
- if (s->partitioned_frame)
- s->decode_mb = mpeg4_decode_partitioned_mb;
- else
- s->decode_mb = mpeg4_decode_mb;
-
- time_incr = 0;
- while (get_bits1(gb) != 0)
- time_incr++;
-
- check_marker(gb, "before time_increment");
-
- if (ctx->time_increment_bits == 0 ||
- !(show_bits(gb, ctx->time_increment_bits + 1) & 1)) {
- av_log(s->avctx, AV_LOG_WARNING,
- "time_increment_bits %d is invalid in relation to the current bitstream, this is likely caused by a missing VOL header\n", ctx->time_increment_bits);
-
- for (ctx->time_increment_bits = 1;
- ctx->time_increment_bits < 16;
- ctx->time_increment_bits++) {
- if (s->pict_type == AV_PICTURE_TYPE_P ||
- (s->pict_type == AV_PICTURE_TYPE_S &&
- ctx->vol_sprite_usage == GMC_SPRITE)) {
- if ((show_bits(gb, ctx->time_increment_bits + 6) & 0x37) == 0x30)
- break;
- } else if ((show_bits(gb, ctx->time_increment_bits + 5) & 0x1F) == 0x18)
- break;
- }
-
- av_log(s->avctx, AV_LOG_WARNING,
- "time_increment_bits set to %d bits, based on bitstream analysis\n", ctx->time_increment_bits);
- if (s->avctx->framerate.num && 4*s->avctx->framerate.num < 1<<ctx->time_increment_bits) {
- s->avctx->framerate.num = 1<<ctx->time_increment_bits;
- s->avctx->time_base = av_inv_q(av_mul_q(s->avctx->framerate, (AVRational){s->avctx->ticks_per_frame, 1}));
- }
- }
-
- if (IS_3IV1)
- time_increment = get_bits1(gb); // FIXME investigate further
- else
- time_increment = get_bits(gb, ctx->time_increment_bits);
-
- if (s->pict_type != AV_PICTURE_TYPE_B) {
- s->last_time_base = s->time_base;
- s->time_base += time_incr;
- s->time = s->time_base * s->avctx->framerate.num + time_increment;
- if (s->workaround_bugs & FF_BUG_UMP4) {
- if (s->time < s->last_non_b_time) {
- /* header is not mpeg-4-compatible, broken encoder,
- * trying to workaround */
- s->time_base++;
- s->time += s->avctx->framerate.num;
- }
- }
- s->pp_time = s->time - s->last_non_b_time;
- s->last_non_b_time = s->time;
- } else {
- s->time = (s->last_time_base + time_incr) * s->avctx->framerate.num + time_increment;
- s->pb_time = s->pp_time - (s->last_non_b_time - s->time);
- if (s->pp_time <= s->pb_time ||
- s->pp_time <= s->pp_time - s->pb_time ||
- s->pp_time <= 0) {
- /* messed up order, maybe after seeking? skipping current b-frame */
- return FRAME_SKIPPED;
- }
- ff_mpeg4_init_direct_mv(s);
-
- if (ctx->t_frame == 0)
- ctx->t_frame = s->pb_time;
- if (ctx->t_frame == 0)
- ctx->t_frame = 1; // 1/0 protection
- s->pp_field_time = (ROUNDED_DIV(s->last_non_b_time, ctx->t_frame) -
- ROUNDED_DIV(s->last_non_b_time - s->pp_time, ctx->t_frame)) * 2;
- s->pb_field_time = (ROUNDED_DIV(s->time, ctx->t_frame) -
- ROUNDED_DIV(s->last_non_b_time - s->pp_time, ctx->t_frame)) * 2;
- if (s->pp_field_time <= s->pb_field_time || s->pb_field_time <= 1) {
- s->pb_field_time = 2;
- s->pp_field_time = 4;
- if (!s->progressive_sequence)
- return FRAME_SKIPPED;
- }
- }
-
- if (s->avctx->framerate.den)
- pts = ROUNDED_DIV(s->time, s->avctx->framerate.den);
- else
- pts = AV_NOPTS_VALUE;
- ff_dlog(s->avctx, "MPEG4 PTS: %"PRId64"\n", pts);
-
- check_marker(gb, "before vop_coded");
-
- /* vop coded */
- if (get_bits1(gb) != 1) {
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_ERROR, "vop not coded\n");
- return FRAME_SKIPPED;
- }
- if (ctx->new_pred)
- decode_new_pred(ctx, gb);
-
- if (ctx->shape != BIN_ONLY_SHAPE &&
- (s->pict_type == AV_PICTURE_TYPE_P ||
- (s->pict_type == AV_PICTURE_TYPE_S &&
- ctx->vol_sprite_usage == GMC_SPRITE))) {
- /* rounding type for motion estimation */
- s->no_rounding = get_bits1(gb);
- } else {
- s->no_rounding = 0;
- }
- // FIXME reduced res stuff
-
- if (ctx->shape != RECT_SHAPE) {
- if (ctx->vol_sprite_usage != 1 || s->pict_type != AV_PICTURE_TYPE_I) {
- skip_bits(gb, 13); /* width */
- check_marker(gb, "after width");
- skip_bits(gb, 13); /* height */
- check_marker(gb, "after height");
- skip_bits(gb, 13); /* hor_spat_ref */
- check_marker(gb, "after hor_spat_ref");
- skip_bits(gb, 13); /* ver_spat_ref */
- }
- skip_bits1(gb); /* change_CR_disable */
-
- if (get_bits1(gb) != 0)
- skip_bits(gb, 8); /* constant_alpha_value */
- }
-
- // FIXME complexity estimation stuff
-
- if (ctx->shape != BIN_ONLY_SHAPE) {
- skip_bits_long(gb, ctx->cplx_estimation_trash_i);
- if (s->pict_type != AV_PICTURE_TYPE_I)
- skip_bits_long(gb, ctx->cplx_estimation_trash_p);
- if (s->pict_type == AV_PICTURE_TYPE_B)
- skip_bits_long(gb, ctx->cplx_estimation_trash_b);
-
- if (get_bits_left(gb) < 3) {
- av_log(s->avctx, AV_LOG_ERROR, "Header truncated\n");
- return AVERROR_INVALIDDATA;
- }
- ctx->intra_dc_threshold = ff_mpeg4_dc_threshold[get_bits(gb, 3)];
- if (!s->progressive_sequence) {
- s->top_field_first = get_bits1(gb);
- s->alternate_scan = get_bits1(gb);
- } else
- s->alternate_scan = 0;
- }
-
- if (s->alternate_scan) {
- ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan);
- ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan);
- ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan);
- ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
- } else {
- ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct);
- ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
- ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
- ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
- }
-
- if (s->pict_type == AV_PICTURE_TYPE_S &&
- (ctx->vol_sprite_usage == STATIC_SPRITE ||
- ctx->vol_sprite_usage == GMC_SPRITE)) {
- if (mpeg4_decode_sprite_trajectory(ctx, gb) < 0)
- return AVERROR_INVALIDDATA;
- if (ctx->sprite_brightness_change)
- av_log(s->avctx, AV_LOG_ERROR,
- "sprite_brightness_change not supported\n");
- if (ctx->vol_sprite_usage == STATIC_SPRITE)
- av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n");
- }
-
- if (ctx->shape != BIN_ONLY_SHAPE) {
- s->chroma_qscale = s->qscale = get_bits(gb, s->quant_precision);
- if (s->qscale == 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Error, header damaged or not MPEG4 header (qscale=0)\n");
- return AVERROR_INVALIDDATA; // makes no sense to continue, as there is nothing left from the image then
- }
-
- if (s->pict_type != AV_PICTURE_TYPE_I) {
- s->f_code = get_bits(gb, 3); /* fcode_for */
- if (s->f_code == 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Error, header damaged or not MPEG4 header (f_code=0)\n");
- s->f_code = 1;
- return AVERROR_INVALIDDATA; // makes no sense to continue, as there is nothing left from the image then
- }
- } else
- s->f_code = 1;
-
- if (s->pict_type == AV_PICTURE_TYPE_B) {
- s->b_code = get_bits(gb, 3);
- if (s->b_code == 0) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Error, header damaged or not MPEG4 header (b_code=0)\n");
- s->b_code=1;
- return AVERROR_INVALIDDATA; // makes no sense to continue, as the MV decoding will break very quickly
- }
- } else
- s->b_code = 1;
-
- if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
- av_log(s->avctx, AV_LOG_DEBUG,
- "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d ce:%d/%d/%d time:%"PRId64" tincr:%d\n",
- s->qscale, s->f_code, s->b_code,
- s->pict_type == AV_PICTURE_TYPE_I ? "I" : (s->pict_type == AV_PICTURE_TYPE_P ? "P" : (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")),
- gb->size_in_bits,s->progressive_sequence, s->alternate_scan,
- s->top_field_first, s->quarter_sample ? "q" : "h",
- s->data_partitioning, ctx->resync_marker,
- ctx->num_sprite_warping_points, s->sprite_warping_accuracy,
- 1 - s->no_rounding, s->vo_type,
- ctx->vol_control_parameters ? " VOLC" : " ", ctx->intra_dc_threshold,
- ctx->cplx_estimation_trash_i, ctx->cplx_estimation_trash_p,
- ctx->cplx_estimation_trash_b,
- s->time,
- time_increment
- );
- }
-
- if (!ctx->scalability) {
- if (ctx->shape != RECT_SHAPE && s->pict_type != AV_PICTURE_TYPE_I)
- skip_bits1(gb); // vop shape coding type
- } else {
- if (ctx->enhancement_type) {
- int load_backward_shape = get_bits1(gb);
- if (load_backward_shape)
- av_log(s->avctx, AV_LOG_ERROR,
- "load backward shape isn't supported\n");
- }
- skip_bits(gb, 2); // ref_select_code
- }
- }
- /* detect buggy encoders which don't set the low_delay flag
- * (divx4/xvid/opendivx). Note we cannot detect divx5 without b-frames
- * easily (although it's buggy too) */
- if (s->vo_type == 0 && ctx->vol_control_parameters == 0 &&
- ctx->divx_version == -1 && s->picture_number == 0) {
- av_log(s->avctx, AV_LOG_WARNING,
- "looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag\n");
- s->low_delay = 1;
- }
-
- s->picture_number++; // better than pic number==0 always ;)
-
- // FIXME add short header support
- s->y_dc_scale_table = ff_mpeg4_y_dc_scale_table;
- s->c_dc_scale_table = ff_mpeg4_c_dc_scale_table;
-
- if (s->workaround_bugs & FF_BUG_EDGE) {
- s->h_edge_pos = s->width;
- s->v_edge_pos = s->height;
- }
- return 0;
-}
-
-/**
- * Decode mpeg4 headers.
- * @return <0 if no VOP found (or a damaged one)
- * FRAME_SKIPPED if a not coded VOP is found
- * 0 if a VOP is found
- */
-int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb)
-{
- MpegEncContext *s = &ctx->m;
- unsigned startcode, v;
- int ret;
-
- /* search next start code */
- align_get_bits(gb);
-
- if (s->codec_tag == AV_RL32("WV1F") && show_bits(gb, 24) == 0x575630) {
- skip_bits(gb, 24);
- if (get_bits(gb, 8) == 0xF0)
- goto end;
- }
-
- startcode = 0xff;
- for (;;) {
- if (get_bits_count(gb) >= gb->size_in_bits) {
- if (gb->size_in_bits == 8 &&
- (ctx->divx_version >= 0 || ctx->xvid_build >= 0) || s->codec_tag == AV_RL32("QMP4")) {
- av_log(s->avctx, AV_LOG_VERBOSE, "frame skip %d\n", gb->size_in_bits);
- return FRAME_SKIPPED; // divx bug
- } else
- return -1; // end of stream
- }
-
- /* use the bits after the test */
- v = get_bits(gb, 8);
- startcode = ((startcode << 8) | v) & 0xffffffff;
-
- if ((startcode & 0xFFFFFF00) != 0x100)
- continue; // no startcode
-
- if (s->avctx->debug & FF_DEBUG_STARTCODE) {
- av_log(s->avctx, AV_LOG_DEBUG, "startcode: %3X ", startcode);
- if (startcode <= 0x11F)
- av_log(s->avctx, AV_LOG_DEBUG, "Video Object Start");
- else if (startcode <= 0x12F)
- av_log(s->avctx, AV_LOG_DEBUG, "Video Object Layer Start");
- else if (startcode <= 0x13F)
- av_log(s->avctx, AV_LOG_DEBUG, "Reserved");
- else if (startcode <= 0x15F)
- av_log(s->avctx, AV_LOG_DEBUG, "FGS bp start");
- else if (startcode <= 0x1AF)
- av_log(s->avctx, AV_LOG_DEBUG, "Reserved");
- else if (startcode == 0x1B0)
- av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq Start");
- else if (startcode == 0x1B1)
- av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq End");
- else if (startcode == 0x1B2)
- av_log(s->avctx, AV_LOG_DEBUG, "User Data");
- else if (startcode == 0x1B3)
- av_log(s->avctx, AV_LOG_DEBUG, "Group of VOP start");
- else if (startcode == 0x1B4)
- av_log(s->avctx, AV_LOG_DEBUG, "Video Session Error");
- else if (startcode == 0x1B5)
- av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Start");
- else if (startcode == 0x1B6)
- av_log(s->avctx, AV_LOG_DEBUG, "Video Object Plane start");
- else if (startcode == 0x1B7)
- av_log(s->avctx, AV_LOG_DEBUG, "slice start");
- else if (startcode == 0x1B8)
- av_log(s->avctx, AV_LOG_DEBUG, "extension start");
- else if (startcode == 0x1B9)
- av_log(s->avctx, AV_LOG_DEBUG, "fgs start");
- else if (startcode == 0x1BA)
- av_log(s->avctx, AV_LOG_DEBUG, "FBA Object start");
- else if (startcode == 0x1BB)
- av_log(s->avctx, AV_LOG_DEBUG, "FBA Object Plane start");
- else if (startcode == 0x1BC)
- av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object start");
- else if (startcode == 0x1BD)
- av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object Plane start");
- else if (startcode == 0x1BE)
- av_log(s->avctx, AV_LOG_DEBUG, "Still Texture Object start");
- else if (startcode == 0x1BF)
- av_log(s->avctx, AV_LOG_DEBUG, "Texture Spatial Layer start");
- else if (startcode == 0x1C0)
- av_log(s->avctx, AV_LOG_DEBUG, "Texture SNR Layer start");
- else if (startcode == 0x1C1)
- av_log(s->avctx, AV_LOG_DEBUG, "Texture Tile start");
- else if (startcode == 0x1C2)
- av_log(s->avctx, AV_LOG_DEBUG, "Texture Shape Layer start");
- else if (startcode == 0x1C3)
- av_log(s->avctx, AV_LOG_DEBUG, "stuffing start");
- else if (startcode <= 0x1C5)
- av_log(s->avctx, AV_LOG_DEBUG, "reserved");
- else if (startcode <= 0x1FF)
- av_log(s->avctx, AV_LOG_DEBUG, "System start");
- av_log(s->avctx, AV_LOG_DEBUG, " at %d\n", get_bits_count(gb));
- }
-
- if (startcode >= 0x120 && startcode <= 0x12F) {
- if ((ret = decode_vol_header(ctx, gb)) < 0)
- return ret;
- } else if (startcode == USER_DATA_STARTCODE) {
- decode_user_data(ctx, gb);
- } else if (startcode == GOP_STARTCODE) {
- mpeg4_decode_gop_header(s, gb);
- } else if (startcode == VOS_STARTCODE) {
- mpeg4_decode_profile_level(s, gb);
- } else if (startcode == VOP_STARTCODE) {
- break;
- }
-
- align_get_bits(gb);
- startcode = 0xff;
- }
-
-end:
- if (s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY)
- s->low_delay = 1;
- s->avctx->has_b_frames = !s->low_delay;
-
- return decode_vop_header(ctx, gb);
-}
-
-av_cold void ff_mpeg4videodec_static_init(void) {
- static int done = 0;
-
- if (!done) {
- 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_VLC_RL(ff_rvlc_rl_inter, 1072);
- INIT_VLC_RL(ff_rvlc_rl_intra, 1072);
- INIT_VLC_STATIC(&dc_lum, DC_VLC_BITS, 10 /* 13 */,
- &ff_mpeg4_DCtab_lum[0][1], 2, 1,
- &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512);
- 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(&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);
- done = 1;
- }
-}
-
-int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
-{
- Mpeg4DecContext *ctx = avctx->priv_data;
- MpegEncContext *s = &ctx->m;
-
- /* divx 5.01+ bitstream reorder stuff */
- /* Since this clobbers the input buffer and hwaccel codecs still need the
- * data during hwaccel->end_frame we should not do this any earlier */
- if (s->divx_packed) {
- int current_pos = s->gb.buffer == s->bitstream_buffer ? 0 : (get_bits_count(&s->gb) >> 3);
- int startcode_found = 0;
-
- if (buf_size - current_pos > 7) {
-
- int i;
- for (i = current_pos; i < buf_size - 4; i++)
-
- if (buf[i] == 0 &&
- buf[i + 1] == 0 &&
- buf[i + 2] == 1 &&
- buf[i + 3] == 0xB6) {
- startcode_found = !(buf[i + 4] & 0x40);
- break;
- }
- }
-
- if (startcode_found) {
- if (!ctx->showed_packed_warning) {
- av_log(s->avctx, AV_LOG_INFO, "Video uses a non-standard and "
- "wasteful way to store B-frames ('packed B-frames'). "
- "Consider using the mpeg4_unpack_bframes bitstream filter without encoding but stream copy to fix it.\n");
- ctx->showed_packed_warning = 1;
- }
- av_fast_padded_malloc(&s->bitstream_buffer,
- &s->allocated_bitstream_buffer_size,
- buf_size - current_pos);
- if (!s->bitstream_buffer) {
- s->bitstream_buffer_size = 0;
- return AVERROR(ENOMEM);
- }
- memcpy(s->bitstream_buffer, buf + current_pos,
- buf_size - current_pos);
- s->bitstream_buffer_size = buf_size - current_pos;
- }
- }
-
- return 0;
-}
-
-static int mpeg4_update_thread_context(AVCodecContext *dst,
- const AVCodecContext *src)
-{
- Mpeg4DecContext *s = dst->priv_data;
- const Mpeg4DecContext *s1 = src->priv_data;
- int init = s->m.context_initialized;
-
- int ret = ff_mpeg_update_thread_context(dst, src);
-
- if (ret < 0)
- return ret;
-
- memcpy(((uint8_t*)s) + sizeof(MpegEncContext), ((uint8_t*)s1) + sizeof(MpegEncContext), sizeof(Mpeg4DecContext) - sizeof(MpegEncContext));
-
- if (CONFIG_MPEG4_DECODER && !init && s1->xvid_build >= 0)
- ff_xvid_idct_init(&s->m.idsp, dst);
-
- return 0;
-}
-
-static av_cold int decode_init(AVCodecContext *avctx)
-{
- Mpeg4DecContext *ctx = avctx->priv_data;
- MpegEncContext *s = &ctx->m;
- int ret;
-
- ctx->divx_version =
- ctx->divx_build =
- ctx->xvid_build =
- ctx->lavc_build = -1;
-
- if ((ret = ff_h263_decode_init(avctx)) < 0)
- return ret;
-
- ff_mpeg4videodec_static_init();
-
- s->h263_pred = 1;
- s->low_delay = 0; /* default, might be overridden in the vol header during header parsing */
- s->decode_mb = mpeg4_decode_mb;
- ctx->time_increment_bits = 4; /* default value for broken headers */
-
- avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
- avctx->internal->allocate_progress = 1;
-
- return 0;
-}
-
-static const AVProfile mpeg4_video_profiles[] = {
- { FF_PROFILE_MPEG4_SIMPLE, "Simple Profile" },
- { FF_PROFILE_MPEG4_SIMPLE_SCALABLE, "Simple Scalable Profile" },
- { FF_PROFILE_MPEG4_CORE, "Core Profile" },
- { FF_PROFILE_MPEG4_MAIN, "Main Profile" },
- { FF_PROFILE_MPEG4_N_BIT, "N-bit Profile" },
- { FF_PROFILE_MPEG4_SCALABLE_TEXTURE, "Scalable Texture Profile" },
- { FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION, "Simple Face Animation Profile" },
- { FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE, "Basic Animated Texture Profile" },
- { FF_PROFILE_MPEG4_HYBRID, "Hybrid Profile" },
- { FF_PROFILE_MPEG4_ADVANCED_REAL_TIME, "Advanced Real Time Simple Profile" },
- { FF_PROFILE_MPEG4_CORE_SCALABLE, "Code Scalable Profile" },
- { FF_PROFILE_MPEG4_ADVANCED_CODING, "Advanced Coding Profile" },
- { FF_PROFILE_MPEG4_ADVANCED_CORE, "Advanced Core Profile" },
- { FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE, "Advanced Scalable Texture Profile" },
- { FF_PROFILE_MPEG4_SIMPLE_STUDIO, "Simple Studio Profile" },
- { FF_PROFILE_MPEG4_ADVANCED_SIMPLE, "Advanced Simple Profile" },
- { FF_PROFILE_UNKNOWN },
-};
-
-static const AVOption mpeg4_options[] = {
- {"quarter_sample", "1/4 subpel MC", offsetof(MpegEncContext, quarter_sample), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, 0},
- {"divx_packed", "divx style packed b frames", offsetof(MpegEncContext, divx_packed), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, 0},
- {NULL}
-};
-
-static const AVClass mpeg4_class = {
- "MPEG4 Video Decoder",
- av_default_item_name,
- mpeg4_options,
- LIBAVUTIL_VERSION_INT,
-};
-
-AVCodec ff_mpeg4_decoder = {
- .name = "mpeg4",
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MPEG4,
- .priv_data_size = sizeof(Mpeg4DecContext),
- .init = decode_init,
- .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 |
- AV_CODEC_CAP_FRAME_THREADS,
- .flush = ff_mpeg_flush,
- .max_lowres = 3,
- .pix_fmts = ff_h263_hwaccel_pixfmt_list_420,
- .profiles = NULL_IF_CONFIG_SMALL(mpeg4_video_profiles),
- .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg4_update_thread_context),
- .priv_class = &mpeg4_class,
-};
-
-
-#if CONFIG_MPEG4_VDPAU_DECODER && FF_API_VDPAU
-static const AVClass mpeg4_vdpau_class = {
- "MPEG4 Video VDPAU Decoder",
- av_default_item_name,
- mpeg4_options,
- LIBAVUTIL_VERSION_INT,
-};
-
-AVCodec ff_mpeg4_vdpau_decoder = {
- .name = "mpeg4_vdpau",
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 (VDPAU)"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MPEG4,
- .priv_data_size = sizeof(Mpeg4DecContext),
- .init = decode_init,
- .close = ff_h263_decode_end,
- .decode = ff_h263_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
- AV_CODEC_CAP_HWACCEL_VDPAU,
- .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_VDPAU_MPEG4,
- AV_PIX_FMT_NONE },
- .priv_class = &mpeg4_vdpau_class,
-};
-#endif
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiodec_template.c b/ffmpeg-2-8-11/libavcodec/mpegaudiodec_template.c
deleted file mode 100644
index 0f32ac7..0000000
--- a/ffmpeg-2-8-11/libavcodec/mpegaudiodec_template.c
+++ /dev/null
@@ -1,2003 +0,0 @@
-/*
- * MPEG Audio decoder
- * Copyright (c) 2001, 2002 Fabrice Bellard
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * MPEG Audio decoder
- */
-
-#include "libavutil/attributes.h"
-#include "libavutil/avassert.h"
-#include "libavutil/channel_layout.h"
-#include "libavutil/float_dsp.h"
-#include "libavutil/libm.h"
-#include "avcodec.h"
-#include "get_bits.h"
-#include "internal.h"
-#include "mathops.h"
-#include "mpegaudiodsp.h"
-
-/*
- * TODO:
- * - test lsf / mpeg25 extensively.
- */
-
-#include "mpegaudio.h"
-#include "mpegaudiodecheader.h"
-
-#define BACKSTEP_SIZE 512
-#define EXTRABYTES 24
-#define LAST_BUF_SIZE 2 * BACKSTEP_SIZE + EXTRABYTES
-
-/* layer 3 "granule" */
-typedef struct GranuleDef {
- uint8_t scfsi;
- int part2_3_length;
- int big_values;
- int global_gain;
- int scalefac_compress;
- uint8_t block_type;
- uint8_t switch_point;
- int table_select[3];
- int subblock_gain[3];
- uint8_t scalefac_scale;
- uint8_t count1table_select;
- int region_size[3]; /* number of huffman codes in each region */
- int preflag;
- int short_start, long_end; /* long/short band indexes */
- uint8_t scale_factors[40];
- DECLARE_ALIGNED(16, INTFLOAT, sb_hybrid)[SBLIMIT * 18]; /* 576 samples */
-} GranuleDef;
-
-typedef struct MPADecodeContext {
- MPA_DECODE_HEADER
- uint8_t last_buf[LAST_BUF_SIZE];
- int last_buf_size;
- /* next header (used in free format parsing) */
- uint32_t free_format_next_header;
- GetBitContext gb;
- GetBitContext in_gb;
- DECLARE_ALIGNED(32, MPA_INT, synth_buf)[MPA_MAX_CHANNELS][512 * 2];
- int synth_buf_offset[MPA_MAX_CHANNELS];
- DECLARE_ALIGNED(32, INTFLOAT, sb_samples)[MPA_MAX_CHANNELS][36][SBLIMIT];
- INTFLOAT mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */
- GranuleDef granules[2][2]; /* Used in Layer 3 */
- int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3
- int dither_state;
- int err_recognition;
- AVCodecContext* avctx;
- MPADSPContext mpadsp;
- AVFloatDSPContext *fdsp;
- AVFrame *frame;
-} MPADecodeContext;
-
-#define HEADER_SIZE 4
-
-#include "mpegaudiodata.h"
-#include "mpegaudiodectab.h"
-
-/* vlc structure for decoding layer 3 huffman tables */
-static VLC huff_vlc[16];
-static VLC_TYPE huff_vlc_tables[
- 0 + 128 + 128 + 128 + 130 + 128 + 154 + 166 +
- 142 + 204 + 190 + 170 + 542 + 460 + 662 + 414
- ][2];
-static const int huff_vlc_tables_sizes[16] = {
- 0, 128, 128, 128, 130, 128, 154, 166,
- 142, 204, 190, 170, 542, 460, 662, 414
-};
-static VLC huff_quad_vlc[2];
-static VLC_TYPE huff_quad_vlc_tables[128+16][2];
-static const int huff_quad_vlc_tables_sizes[2] = { 128, 16 };
-/* computed from band_size_long */
-static uint16_t band_index_long[9][23];
-#include "mpegaudio_tablegen.h"
-/* intensity stereo coef table */
-static INTFLOAT is_table[2][16];
-static INTFLOAT is_table_lsf[2][2][16];
-static INTFLOAT csa_table[8][4];
-
-static int16_t division_tab3[1<<6 ];
-static int16_t division_tab5[1<<8 ];
-static int16_t division_tab9[1<<11];
-
-static int16_t * const division_tabs[4] = {
- division_tab3, division_tab5, NULL, division_tab9
-};
-
-/* lower 2 bits: modulo 3, higher bits: shift */
-static uint16_t scale_factor_modshift[64];
-/* [i][j]: 2^(-j/3) * FRAC_ONE * 2^(i+2) / (2^(i+2) - 1) */
-static int32_t scale_factor_mult[15][3];
-/* mult table for layer 2 group quantization */
-
-#define SCALE_GEN(v) \
-{ FIXR_OLD(1.0 * (v)), FIXR_OLD(0.7937005259 * (v)), FIXR_OLD(0.6299605249 * (v)) }
-
-static const int32_t scale_factor_mult2[3][3] = {
- SCALE_GEN(4.0 / 3.0), /* 3 steps */
- SCALE_GEN(4.0 / 5.0), /* 5 steps */
- SCALE_GEN(4.0 / 9.0), /* 9 steps */
-};
-
-/**
- * Convert region offsets to region sizes and truncate
- * size to big_values.
- */
-static void region_offset2size(GranuleDef *g)
-{
- int i, k, j = 0;
- g->region_size[2] = 576 / 2;
- for (i = 0; i < 3; i++) {
- k = FFMIN(g->region_size[i], g->big_values);
- g->region_size[i] = k - j;
- j = k;
- }
-}
-
-static void init_short_region(MPADecodeContext *s, GranuleDef *g)
-{
- if (g->block_type == 2) {
- if (s->sample_rate_index != 8)
- g->region_size[0] = (36 / 2);
- else
- g->region_size[0] = (72 / 2);
- } else {
- if (s->sample_rate_index <= 2)
- g->region_size[0] = (36 / 2);
- else if (s->sample_rate_index != 8)
- g->region_size[0] = (54 / 2);
- else
- g->region_size[0] = (108 / 2);
- }
- g->region_size[1] = (576 / 2);
-}
-
-static void init_long_region(MPADecodeContext *s, GranuleDef *g,
- int ra1, int ra2)
-{
- int l;
- g->region_size[0] = band_index_long[s->sample_rate_index][ra1 + 1] >> 1;
- /* should not overflow */
- l = FFMIN(ra1 + ra2 + 2, 22);
- g->region_size[1] = band_index_long[s->sample_rate_index][ l] >> 1;
-}
-
-static void compute_band_indexes(MPADecodeContext *s, GranuleDef *g)
-{
- if (g->block_type == 2) {
- if (g->switch_point) {
- if(s->sample_rate_index == 8)
- avpriv_request_sample(s->avctx, "switch point in 8khz");
- /* if switched mode, we handle the 36 first samples as
- long blocks. For 8000Hz, we handle the 72 first
- exponents as long blocks */
- if (s->sample_rate_index <= 2)
- g->long_end = 8;
- else
- g->long_end = 6;
-
- g->short_start = 3;
- } else {
- g->long_end = 0;
- g->short_start = 0;
- }
- } else {
- g->short_start = 13;
- g->long_end = 22;
- }
-}
-
-/* layer 1 unscaling */
-/* n = number of bits of the mantissa minus 1 */
-static inline int l1_unscale(int n, int mant, int scale_factor)
-{
- int shift, mod;
- int64_t val;
-
- shift = scale_factor_modshift[scale_factor];
- mod = shift & 3;
- shift >>= 2;
- val = MUL64((int)(mant + (-1U << n) + 1), scale_factor_mult[n-1][mod]);
- shift += n;
- /* NOTE: at this point, 1 <= shift >= 21 + 15 */
- return (int)((val + (1LL << (shift - 1))) >> shift);
-}
-
-static inline int l2_unscale_group(int steps, int mant, int scale_factor)
-{
- int shift, mod, val;
-
- shift = scale_factor_modshift[scale_factor];
- mod = shift & 3;
- shift >>= 2;
-
- val = (mant - (steps >> 1)) * scale_factor_mult2[steps >> 2][mod];
- /* NOTE: at this point, 0 <= shift <= 21 */
- if (shift > 0)
- val = (val + (1 << (shift - 1))) >> shift;
- return val;
-}
-
-/* compute value^(4/3) * 2^(exponent/4). It normalized to FRAC_BITS */
-static inline int l3_unscale(int value, int exponent)
-{
- unsigned int m;
- int e;
-
- e = table_4_3_exp [4 * value + (exponent & 3)];
- m = table_4_3_value[4 * value + (exponent & 3)];
- e -= exponent >> 2;
-#ifdef DEBUG
- if(e < 1)
- av_log(NULL, AV_LOG_WARNING, "l3_unscale: e is %d\n", e);
-#endif
- if (e > 31)
- return 0;
- m = (m + (1 << (e - 1))) >> e;
-
- return m;
-}
-
-static av_cold void decode_init_static(void)
-{
- int i, j, k;
- int offset;
-
- /* scale factors table for layer 1/2 */
- for (i = 0; i < 64; i++) {
- int shift, mod;
- /* 1.0 (i = 3) is normalized to 2 ^ FRAC_BITS */
- shift = i / 3;
- mod = i % 3;
- scale_factor_modshift[i] = mod | (shift << 2);
- }
-
- /* scale factor multiply for layer 1 */
- for (i = 0; i < 15; i++) {
- int n, norm;
- n = i + 2;
- norm = ((INT64_C(1) << n) * FRAC_ONE) / ((1 << n) - 1);
- scale_factor_mult[i][0] = MULLx(norm, FIXR(1.0 * 2.0), FRAC_BITS);
- scale_factor_mult[i][1] = MULLx(norm, FIXR(0.7937005259 * 2.0), FRAC_BITS);
- scale_factor_mult[i][2] = MULLx(norm, FIXR(0.6299605249 * 2.0), FRAC_BITS);
- ff_dlog(NULL, "%d: norm=%x s=%x %x %x\n", i, norm,
- scale_factor_mult[i][0],
- scale_factor_mult[i][1],
- scale_factor_mult[i][2]);
- }
-
- RENAME(ff_mpa_synth_init)(RENAME(ff_mpa_synth_window));
-
- /* huffman decode tables */
- offset = 0;
- for (i = 1; i < 16; i++) {
- const HuffTable *h = &mpa_huff_tables[i];
- int xsize, x, y;
- uint8_t tmp_bits [512] = { 0 };
- uint16_t tmp_codes[512] = { 0 };
-
- xsize = h->xsize;
-
- j = 0;
- for (x = 0; x < xsize; x++) {
- for (y = 0; y < xsize; y++) {
- tmp_bits [(x << 5) | y | ((x&&y)<<4)]= h->bits [j ];
- tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++];
- }
- }
-
- /* XXX: fail test */
- huff_vlc[i].table = huff_vlc_tables+offset;
- huff_vlc[i].table_allocated = huff_vlc_tables_sizes[i];
- init_vlc(&huff_vlc[i], 7, 512,
- tmp_bits, 1, 1, tmp_codes, 2, 2,
- INIT_VLC_USE_NEW_STATIC);
- offset += huff_vlc_tables_sizes[i];
- }
- av_assert0(offset == FF_ARRAY_ELEMS(huff_vlc_tables));
-
- offset = 0;
- for (i = 0; i < 2; i++) {
- huff_quad_vlc[i].table = huff_quad_vlc_tables+offset;
- huff_quad_vlc[i].table_allocated = huff_quad_vlc_tables_sizes[i];
- init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16,
- mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1,
- INIT_VLC_USE_NEW_STATIC);
- offset += huff_quad_vlc_tables_sizes[i];
- }
- av_assert0(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables));
-
- for (i = 0; i < 9; i++) {
- k = 0;
- for (j = 0; j < 22; j++) {
- band_index_long[i][j] = k;
- k += band_size_long[i][j];
- }
- band_index_long[i][22] = k;
- }
-
- /* compute n ^ (4/3) and store it in mantissa/exp format */
-
- mpegaudio_tableinit();
-
- for (i = 0; i < 4; i++) {
- if (ff_mpa_quant_bits[i] < 0) {
- for (j = 0; j < (1 << (-ff_mpa_quant_bits[i]+1)); j++) {
- int val1, val2, val3, steps;
- int val = j;
- steps = ff_mpa_quant_steps[i];
- val1 = val % steps;
- val /= steps;
- val2 = val % steps;
- val3 = val / steps;
- division_tabs[i][j] = val1 + (val2 << 4) + (val3 << 8);
- }
- }
- }
-
-
- for (i = 0; i < 7; i++) {
- float f;
- INTFLOAT v;
- if (i != 6) {
- f = tan((double)i * M_PI / 12.0);
- v = FIXR(f / (1.0 + f));
- } else {
- v = FIXR(1.0);
- }
- is_table[0][ i] = v;
- is_table[1][6 - i] = v;
- }
- /* invalid values */
- for (i = 7; i < 16; i++)
- is_table[0][i] = is_table[1][i] = 0.0;
-
- for (i = 0; i < 16; i++) {
- double f;
- int e, k;
-
- for (j = 0; j < 2; j++) {
- e = -(j + 1) * ((i + 1) >> 1);
- f = exp2(e / 4.0);
- k = i & 1;
- is_table_lsf[j][k ^ 1][i] = FIXR(f);
- is_table_lsf[j][k ][i] = FIXR(1.0);
- ff_dlog(NULL, "is_table_lsf %d %d: %f %f\n",
- i, j, (float) is_table_lsf[j][0][i],
- (float) is_table_lsf[j][1][i]);
- }
- }
-
- for (i = 0; i < 8; i++) {
- 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
- }
-}
-
-#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;
- 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);
-#endif
-
- ff_mpadsp_init(&s->mpadsp);
-
- if (avctx->request_sample_fmt == OUT_FMT &&
- avctx->codec_id != AV_CODEC_ID_MP3ON4)
- avctx->sample_fmt = OUT_FMT;
- else
- avctx->sample_fmt = OUT_FMT_P;
- s->err_recognition = avctx->err_recognition;
-
- if (avctx->codec_id == AV_CODEC_ID_MP3ADU)
- s->adu_mode = 1;
-
- return 0;
-}
-
-#define C3 FIXHR(0.86602540378443864676/2)
-#define C4 FIXHR(0.70710678118654752439/2) //0.5 / cos(pi*(9)/36)
-#define C5 FIXHR(0.51763809020504152469/2) //0.5 / cos(pi*(5)/36)
-#define C6 FIXHR(1.93185165257813657349/4) //0.5 / cos(pi*(15)/36)
-
-/* 12 points IMDCT. We compute it "by hand" by factorizing obvious
- cases. */
-static void imdct12(INTFLOAT *out, INTFLOAT *in)
-{
- INTFLOAT in0, in1, in2, in3, in4, in5, t1, t2;
-
- in0 = in[0*3];
- in1 = in[1*3] + in[0*3];
- in2 = in[2*3] + in[1*3];
- in3 = in[3*3] + in[2*3];
- in4 = in[4*3] + in[3*3];
- in5 = in[5*3] + in[4*3];
- in5 += in3;
- in3 += in1;
-
- in2 = MULH3(in2, C3, 2);
- in3 = MULH3(in3, C3, 4);
-
- t1 = in0 - in4;
- t2 = MULH3(in1 - in5, C4, 2);
-
- out[ 7] =
- out[10] = t1 + t2;
- out[ 1] =
- out[ 4] = t1 - t2;
-
- in0 += SHR(in4, 1);
- in4 = in0 + in2;
- in5 += 2*in1;
- in1 = MULH3(in5 + in3, C5, 1);
- out[ 8] =
- out[ 9] = in4 + in1;
- out[ 2] =
- out[ 3] = in4 - in1;
-
- in0 -= in2;
- in5 = MULH3(in5 - in3, C6, 2);
- out[ 0] =
- out[ 5] = in0 - in5;
- out[ 6] =
- out[11] = in0 + in5;
-}
-
-/* return the number of decoded frames */
-static int mp_decode_layer1(MPADecodeContext *s)
-{
- int bound, i, v, n, ch, j, mant;
- uint8_t allocation[MPA_MAX_CHANNELS][SBLIMIT];
- uint8_t scale_factors[MPA_MAX_CHANNELS][SBLIMIT];
-
- if (s->mode == MPA_JSTEREO)
- bound = (s->mode_ext + 1) * 4;
- else
- bound = SBLIMIT;
-
- /* allocation bits */
- for (i = 0; i < bound; i++) {
- for (ch = 0; ch < s->nb_channels; ch++) {
- allocation[ch][i] = get_bits(&s->gb, 4);
- }
- }
- for (i = bound; i < SBLIMIT; i++)
- allocation[0][i] = get_bits(&s->gb, 4);
-
- /* scale factors */
- for (i = 0; i < bound; i++) {
- for (ch = 0; ch < s->nb_channels; ch++) {
- if (allocation[ch][i])
- scale_factors[ch][i] = get_bits(&s->gb, 6);
- }
- }
- for (i = bound; i < SBLIMIT; i++) {
- if (allocation[0][i]) {
- scale_factors[0][i] = get_bits(&s->gb, 6);
- scale_factors[1][i] = get_bits(&s->gb, 6);
- }
- }
-
- /* compute samples */
- for (j = 0; j < 12; j++) {
- for (i = 0; i < bound; i++) {
- for (ch = 0; ch < s->nb_channels; ch++) {
- n = allocation[ch][i];
- if (n) {
- mant = get_bits(&s->gb, n + 1);
- v = l1_unscale(n, mant, scale_factors[ch][i]);
- } else {
- v = 0;
- }
- s->sb_samples[ch][j][i] = v;
- }
- }
- for (i = bound; i < SBLIMIT; i++) {
- n = allocation[0][i];
- if (n) {
- mant = get_bits(&s->gb, n + 1);
- v = l1_unscale(n, mant, scale_factors[0][i]);
- s->sb_samples[0][j][i] = v;
- v = l1_unscale(n, mant, scale_factors[1][i]);
- s->sb_samples[1][j][i] = v;
- } else {
- s->sb_samples[0][j][i] = 0;
- s->sb_samples[1][j][i] = 0;
- }
- }
- }
- return 12;
-}
-
-static int mp_decode_layer2(MPADecodeContext *s)
-{
- int sblimit; /* number of used subbands */
- const unsigned char *alloc_table;
- int table, bit_alloc_bits, i, j, ch, bound, v;
- unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT];
- unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT];
- unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3], *sf;
- int scale, qindex, bits, steps, k, l, m, b;
-
- /* select decoding table */
- table = ff_mpa_l2_select_table(s->bit_rate / 1000, s->nb_channels,
- s->sample_rate, s->lsf);
- sblimit = ff_mpa_sblimit_table[table];
- alloc_table = ff_mpa_alloc_tables[table];
-
- if (s->mode == MPA_JSTEREO)
- bound = (s->mode_ext + 1) * 4;
- else
- bound = sblimit;
-
- ff_dlog(s->avctx, "bound=%d sblimit=%d\n", bound, sblimit);
-
- /* sanity check */
- if (bound > sblimit)
- bound = sblimit;
-
- /* parse bit allocation */
- j = 0;
- for (i = 0; i < bound; i++) {
- bit_alloc_bits = alloc_table[j];
- for (ch = 0; ch < s->nb_channels; ch++)
- bit_alloc[ch][i] = get_bits(&s->gb, bit_alloc_bits);
- j += 1 << bit_alloc_bits;
- }
- for (i = bound; i < sblimit; i++) {
- bit_alloc_bits = alloc_table[j];
- v = get_bits(&s->gb, bit_alloc_bits);
- bit_alloc[0][i] = v;
- bit_alloc[1][i] = v;
- j += 1 << bit_alloc_bits;
- }
-
- /* scale codes */
- for (i = 0; i < sblimit; i++) {
- for (ch = 0; ch < s->nb_channels; ch++) {
- if (bit_alloc[ch][i])
- scale_code[ch][i] = get_bits(&s->gb, 2);
- }
- }
-
- /* scale factors */
- for (i = 0; i < sblimit; i++) {
- for (ch = 0; ch < s->nb_channels; ch++) {
- if (bit_alloc[ch][i]) {
- sf = scale_factors[ch][i];
- switch (scale_code[ch][i]) {
- default:
- case 0:
- sf[0] = get_bits(&s->gb, 6);
- sf[1] = get_bits(&s->gb, 6);
- sf[2] = get_bits(&s->gb, 6);
- break;
- case 2:
- sf[0] = get_bits(&s->gb, 6);
- sf[1] = sf[0];
- sf[2] = sf[0];
- break;
- case 1:
- sf[0] = get_bits(&s->gb, 6);
- sf[2] = get_bits(&s->gb, 6);
- sf[1] = sf[0];
- break;
- case 3:
- sf[0] = get_bits(&s->gb, 6);
- sf[2] = get_bits(&s->gb, 6);
- sf[1] = sf[2];
- break;
- }
- }
- }
- }
-
- /* samples */
- for (k = 0; k < 3; k++) {
- for (l = 0; l < 12; l += 3) {
- j = 0;
- for (i = 0; i < bound; i++) {
- bit_alloc_bits = alloc_table[j];
- for (ch = 0; ch < s->nb_channels; ch++) {
- b = bit_alloc[ch][i];
- if (b) {
- scale = scale_factors[ch][i][k];
- qindex = alloc_table[j+b];
- bits = ff_mpa_quant_bits[qindex];
- if (bits < 0) {
- int v2;
- /* 3 values at the same time */
- v = get_bits(&s->gb, -bits);
- v2 = division_tabs[qindex][v];
- steps = ff_mpa_quant_steps[qindex];
-
- s->sb_samples[ch][k * 12 + l + 0][i] =
- l2_unscale_group(steps, v2 & 15, scale);
- s->sb_samples[ch][k * 12 + l + 1][i] =
- l2_unscale_group(steps, (v2 >> 4) & 15, scale);
- s->sb_samples[ch][k * 12 + l + 2][i] =
- l2_unscale_group(steps, v2 >> 8 , scale);
- } else {
- for (m = 0; m < 3; m++) {
- v = get_bits(&s->gb, bits);
- v = l1_unscale(bits - 1, v, scale);
- s->sb_samples[ch][k * 12 + l + m][i] = v;
- }
- }
- } else {
- s->sb_samples[ch][k * 12 + l + 0][i] = 0;
- s->sb_samples[ch][k * 12 + l + 1][i] = 0;
- s->sb_samples[ch][k * 12 + l + 2][i] = 0;
- }
- }
- /* next subband in alloc table */
- j += 1 << bit_alloc_bits;
- }
- /* XXX: find a way to avoid this duplication of code */
- for (i = bound; i < sblimit; i++) {
- bit_alloc_bits = alloc_table[j];
- b = bit_alloc[0][i];
- if (b) {
- int mant, scale0, scale1;
- scale0 = scale_factors[0][i][k];
- scale1 = scale_factors[1][i][k];
- qindex = alloc_table[j+b];
- bits = ff_mpa_quant_bits[qindex];
- if (bits < 0) {
- /* 3 values at the same time */
- v = get_bits(&s->gb, -bits);
- steps = ff_mpa_quant_steps[qindex];
- mant = v % steps;
- v = v / steps;
- s->sb_samples[0][k * 12 + l + 0][i] =
- l2_unscale_group(steps, mant, scale0);
- s->sb_samples[1][k * 12 + l + 0][i] =
- l2_unscale_group(steps, mant, scale1);
- mant = v % steps;
- v = v / steps;
- s->sb_samples[0][k * 12 + l + 1][i] =
- l2_unscale_group(steps, mant, scale0);
- s->sb_samples[1][k * 12 + l + 1][i] =
- l2_unscale_group(steps, mant, scale1);
- s->sb_samples[0][k * 12 + l + 2][i] =
- l2_unscale_group(steps, v, scale0);
- s->sb_samples[1][k * 12 + l + 2][i] =
- l2_unscale_group(steps, v, scale1);
- } else {
- for (m = 0; m < 3; m++) {
- mant = get_bits(&s->gb, bits);
- s->sb_samples[0][k * 12 + l + m][i] =
- l1_unscale(bits - 1, mant, scale0);
- s->sb_samples[1][k * 12 + l + m][i] =
- l1_unscale(bits - 1, mant, scale1);
- }
- }
- } else {
- s->sb_samples[0][k * 12 + l + 0][i] = 0;
- s->sb_samples[0][k * 12 + l + 1][i] = 0;
- s->sb_samples[0][k * 12 + l + 2][i] = 0;
- s->sb_samples[1][k * 12 + l + 0][i] = 0;
- s->sb_samples[1][k * 12 + l + 1][i] = 0;
- s->sb_samples[1][k * 12 + l + 2][i] = 0;
- }
- /* next subband in alloc table */
- j += 1 << bit_alloc_bits;
- }
- /* fill remaining samples to zero */
- for (i = sblimit; i < SBLIMIT; i++) {
- for (ch = 0; ch < s->nb_channels; ch++) {
- s->sb_samples[ch][k * 12 + l + 0][i] = 0;
- s->sb_samples[ch][k * 12 + l + 1][i] = 0;
- s->sb_samples[ch][k * 12 + l + 2][i] = 0;
- }
- }
- }
- }
- return 3 * 12;
-}
-
-#define SPLIT(dst,sf,n) \
- if (n == 3) { \
- int m = (sf * 171) >> 9; \
- dst = sf - 3 * m; \
- sf = m; \
- } else if (n == 4) { \
- dst = sf & 3; \
- sf >>= 2; \
- } else if (n == 5) { \
- int m = (sf * 205) >> 10; \
- dst = sf - 5 * m; \
- sf = m; \
- } else if (n == 6) { \
- int m = (sf * 171) >> 10; \
- dst = sf - 6 * m; \
- sf = m; \
- } else { \
- dst = 0; \
- }
-
-static av_always_inline void lsf_sf_expand(int *slen, int sf, int n1, int n2,
- int n3)
-{
- SPLIT(slen[3], sf, n3)
- SPLIT(slen[2], sf, n2)
- SPLIT(slen[1], sf, n1)
- slen[0] = sf;
-}
-
-static void exponents_from_scale_factors(MPADecodeContext *s, GranuleDef *g,
- int16_t *exponents)
-{
- const uint8_t *bstab, *pretab;
- int len, i, j, k, l, v0, shift, gain, gains[3];
- int16_t *exp_ptr;
-
- exp_ptr = exponents;
- gain = g->global_gain - 210;
- shift = g->scalefac_scale + 1;
-
- bstab = band_size_long[s->sample_rate_index];
- pretab = mpa_pretab[g->preflag];
- for (i = 0; i < g->long_end; i++) {
- v0 = gain - ((g->scale_factors[i] + pretab[i]) << shift) + 400;
- len = bstab[i];
- for (j = len; j > 0; j--)
- *exp_ptr++ = v0;
- }
-
- if (g->short_start < 13) {
- bstab = band_size_short[s->sample_rate_index];
- gains[0] = gain - (g->subblock_gain[0] << 3);
- gains[1] = gain - (g->subblock_gain[1] << 3);
- gains[2] = gain - (g->subblock_gain[2] << 3);
- k = g->long_end;
- for (i = g->short_start; i < 13; i++) {
- len = bstab[i];
- for (l = 0; l < 3; l++) {
- v0 = gains[l] - (g->scale_factors[k++] << shift) + 400;
- for (j = len; j > 0; j--)
- *exp_ptr++ = v0;
- }
- }
- }
-}
-
-/* handle n = 0 too */
-static inline int get_bitsz(GetBitContext *s, int n)
-{
- return n ? get_bits(s, n) : 0;
-}
-
-
-static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos,
- int *end_pos2)
-{
- if (s->in_gb.buffer && *pos >= s->gb.size_in_bits) {
- s->gb = s->in_gb;
- s->in_gb.buffer = NULL;
- av_assert2((get_bits_count(&s->gb) & 7) == 0);
- skip_bits_long(&s->gb, *pos - *end_pos);
- *end_pos2 =
- *end_pos = *end_pos2 + get_bits_count(&s->gb) - *pos;
- *pos = get_bits_count(&s->gb);
- }
-}
-
-/* Following is a optimized code for
- INTFLOAT v = *src
- if(get_bits1(&s->gb))
- v = -v;
- *dst = v;
-*/
-#if USE_FLOATS
-#define READ_FLIP_SIGN(dst,src) \
- v = AV_RN32A(src) ^ (get_bits1(&s->gb) << 31); \
- AV_WN32A(dst, v);
-#else
-#define READ_FLIP_SIGN(dst,src) \
- v = -get_bits1(&s->gb); \
- *(dst) = (*(src) ^ v) - v;
-#endif
-
-static int huffman_decode(MPADecodeContext *s, GranuleDef *g,
- int16_t *exponents, int end_pos2)
-{
- int s_index;
- int i;
- int last_pos, bits_left;
- VLC *vlc;
- int end_pos = FFMIN(end_pos2, s->gb.size_in_bits);
-
- /* low frequencies (called big values) */
- s_index = 0;
- for (i = 0; i < 3; i++) {
- int j, k, l, linbits;
- j = g->region_size[i];
- if (j == 0)
- continue;
- /* select vlc table */
- k = g->table_select[i];
- l = mpa_huff_data[k][0];
- linbits = mpa_huff_data[k][1];
- vlc = &huff_vlc[l];
-
- if (!l) {
- memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * 2 * j);
- s_index += 2 * j;
- continue;
- }
-
- /* read huffcode and compute each couple */
- for (; j > 0; j--) {
- int exponent, x, y;
- int v;
- int pos = get_bits_count(&s->gb);
-
- if (pos >= end_pos){
- switch_buffer(s, &pos, &end_pos, &end_pos2);
- if (pos >= end_pos)
- break;
- }
- y = get_vlc2(&s->gb, vlc->table, 7, 3);
-
- if (!y) {
- g->sb_hybrid[s_index ] =
- g->sb_hybrid[s_index+1] = 0;
- s_index += 2;
- continue;
- }
-
- exponent= exponents[s_index];
-
- ff_dlog(s->avctx, "region=%d n=%d x=%d y=%d exp=%d\n",
- i, g->region_size[i] - j, x, y, exponent);
- if (y & 16) {
- x = y >> 5;
- y = y & 0x0f;
- if (x < 15) {
- READ_FLIP_SIGN(g->sb_hybrid + s_index, RENAME(expval_table)[exponent] + x)
- } else {
- x += get_bitsz(&s->gb, linbits);
- v = l3_unscale(x, exponent);
- if (get_bits1(&s->gb))
- v = -v;
- g->sb_hybrid[s_index] = v;
- }
- if (y < 15) {
- READ_FLIP_SIGN(g->sb_hybrid + s_index + 1, RENAME(expval_table)[exponent] + y)
- } else {
- y += get_bitsz(&s->gb, linbits);
- v = l3_unscale(y, exponent);
- if (get_bits1(&s->gb))
- v = -v;
- g->sb_hybrid[s_index+1] = v;
- }
- } else {
- x = y >> 5;
- y = y & 0x0f;
- x += y;
- if (x < 15) {
- READ_FLIP_SIGN(g->sb_hybrid + s_index + !!y, RENAME(expval_table)[exponent] + x)
- } else {
- x += get_bitsz(&s->gb, linbits);
- v = l3_unscale(x, exponent);
- if (get_bits1(&s->gb))
- v = -v;
- g->sb_hybrid[s_index+!!y] = v;
- }
- g->sb_hybrid[s_index + !y] = 0;
- }
- s_index += 2;
- }
- }
-
- /* high frequencies */
- vlc = &huff_quad_vlc[g->count1table_select];
- last_pos = 0;
- while (s_index <= 572) {
- int pos, code;
- pos = get_bits_count(&s->gb);
- if (pos >= end_pos) {
- if (pos > end_pos2 && last_pos) {
- /* some encoders generate an incorrect size for this
- part. We must go back into the data */
- s_index -= 4;
- skip_bits_long(&s->gb, last_pos - pos);
- av_log(s->avctx, AV_LOG_INFO, "overread, skip %d enddists: %d %d\n", last_pos - pos, end_pos-pos, end_pos2-pos);
- if(s->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))
- s_index=0;
- break;
- }
- switch_buffer(s, &pos, &end_pos, &end_pos2);
- if (pos >= end_pos)
- break;
- }
- last_pos = pos;
-
- code = get_vlc2(&s->gb, vlc->table, vlc->bits, 1);
- 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;
- while (code) {
- static const int idxtab[16] = { 3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0 };
- int v;
- int pos = s_index + idxtab[code];
- code ^= 8 >> idxtab[code];
- READ_FLIP_SIGN(g->sb_hybrid + pos, RENAME(exp_table)+exponents[pos])
- }
- s_index += 4;
- }
- /* skip extension bits */
- bits_left = end_pos2 - get_bits_count(&s->gb);
- if (bits_left < 0 && (s->err_recognition & (AV_EF_BUFFER|AV_EF_COMPLIANT))) {
- av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
- s_index=0;
- } else if (bits_left > 0 && (s->err_recognition & (AV_EF_BUFFER|AV_EF_AGGRESSIVE))) {
- av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
- s_index = 0;
- }
- memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * (576 - s_index));
- skip_bits_long(&s->gb, bits_left);
-
- i = get_bits_count(&s->gb);
- switch_buffer(s, &i, &end_pos, &end_pos2);
-
- return 0;
-}
-
-/* Reorder short blocks from bitstream order to interleaved order. It
- would be faster to do it in parsing, but the code would be far more
- complicated */
-static void reorder_block(MPADecodeContext *s, GranuleDef *g)
-{
- int i, j, len;
- INTFLOAT *ptr, *dst, *ptr1;
- INTFLOAT tmp[576];
-
- if (g->block_type != 2)
- return;
-
- if (g->switch_point) {
- if (s->sample_rate_index != 8)
- ptr = g->sb_hybrid + 36;
- else
- ptr = g->sb_hybrid + 72;
- } else {
- ptr = g->sb_hybrid;
- }
-
- for (i = g->short_start; i < 13; i++) {
- len = band_size_short[s->sample_rate_index][i];
- ptr1 = ptr;
- dst = tmp;
- for (j = len; j > 0; j--) {
- *dst++ = ptr[0*len];
- *dst++ = ptr[1*len];
- *dst++ = ptr[2*len];
- ptr++;
- }
- ptr += 2 * len;
- memcpy(ptr1, tmp, len * 3 * sizeof(*ptr1));
- }
-}
-
-#define ISQRT2 FIXR(0.70710678118654752440)
-
-static void compute_stereo(MPADecodeContext *s, GranuleDef *g0, GranuleDef *g1)
-{
- int i, j, k, l;
- int sf_max, sf, len, non_zero_found;
- INTFLOAT (*is_tab)[16], *tab0, *tab1, tmp0, tmp1, v1, v2;
- int non_zero_found_short[3];
-
- /* intensity stereo */
- if (s->mode_ext & MODE_EXT_I_STEREO) {
- if (!s->lsf) {
- is_tab = is_table;
- sf_max = 7;
- } else {
- is_tab = is_table_lsf[g1->scalefac_compress & 1];
- sf_max = 16;
- }
-
- tab0 = g0->sb_hybrid + 576;
- tab1 = g1->sb_hybrid + 576;
-
- non_zero_found_short[0] = 0;
- non_zero_found_short[1] = 0;
- non_zero_found_short[2] = 0;
- k = (13 - g1->short_start) * 3 + g1->long_end - 3;
- for (i = 12; i >= g1->short_start; i--) {
- /* for last band, use previous scale factor */
- if (i != 11)
- k -= 3;
- len = band_size_short[s->sample_rate_index][i];
- for (l = 2; l >= 0; l--) {
- tab0 -= len;
- tab1 -= len;
- if (!non_zero_found_short[l]) {
- /* test if non zero band. if so, stop doing i-stereo */
- for (j = 0; j < len; j++) {
- if (tab1[j] != 0) {
- non_zero_found_short[l] = 1;
- goto found1;
- }
- }
- sf = g1->scale_factors[k + l];
- if (sf >= sf_max)
- goto found1;
-
- v1 = is_tab[0][sf];
- v2 = is_tab[1][sf];
- for (j = 0; j < len; j++) {
- tmp0 = tab0[j];
- tab0[j] = MULLx(tmp0, v1, FRAC_BITS);
- tab1[j] = MULLx(tmp0, v2, FRAC_BITS);
- }
- } else {
-found1:
- if (s->mode_ext & MODE_EXT_MS_STEREO) {
- /* lower part of the spectrum : do ms stereo
- if enabled */
- for (j = 0; j < len; j++) {
- tmp0 = tab0[j];
- tmp1 = tab1[j];
- tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS);
- tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS);
- }
- }
- }
- }
- }
-
- non_zero_found = non_zero_found_short[0] |
- non_zero_found_short[1] |
- non_zero_found_short[2];
-
- for (i = g1->long_end - 1;i >= 0;i--) {
- len = band_size_long[s->sample_rate_index][i];
- tab0 -= len;
- tab1 -= len;
- /* test if non zero band. if so, stop doing i-stereo */
- if (!non_zero_found) {
- for (j = 0; j < len; j++) {
- if (tab1[j] != 0) {
- non_zero_found = 1;
- goto found2;
- }
- }
- /* for last band, use previous scale factor */
- k = (i == 21) ? 20 : i;
- sf = g1->scale_factors[k];
- if (sf >= sf_max)
- goto found2;
- v1 = is_tab[0][sf];
- v2 = is_tab[1][sf];
- for (j = 0; j < len; j++) {
- tmp0 = tab0[j];
- tab0[j] = MULLx(tmp0, v1, FRAC_BITS);
- tab1[j] = MULLx(tmp0, v2, FRAC_BITS);
- }
- } else {
-found2:
- if (s->mode_ext & MODE_EXT_MS_STEREO) {
- /* lower part of the spectrum : do ms stereo
- if enabled */
- for (j = 0; j < len; j++) {
- tmp0 = tab0[j];
- tmp1 = tab1[j];
- tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS);
- tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS);
- }
- }
- }
- }
- } else if (s->mode_ext & MODE_EXT_MS_STEREO) {
- /* ms stereo ONLY */
- /* NOTE: the 1/sqrt(2) normalization factor is included in the
- global gain */
-#if USE_FLOATS
- s->fdsp->butterflies_float(g0->sb_hybrid, g1->sb_hybrid, 576);
-#else
- tab0 = g0->sb_hybrid;
- tab1 = g1->sb_hybrid;
- for (i = 0; i < 576; i++) {
- tmp0 = tab0[i];
- tmp1 = tab1[i];
- tab0[i] = tmp0 + tmp1;
- tab1[i] = tmp0 - tmp1;
- }
-#endif
- }
-}
-
-#if USE_FLOATS
-#if HAVE_MIPSFPU
-# include "mips/compute_antialias_float.h"
-#endif /* HAVE_MIPSFPU */
-#else
-#if HAVE_MIPSDSPR1
-# include "mips/compute_antialias_fixed.h"
-#endif /* HAVE_MIPSDSPR1 */
-#endif /* USE_FLOATS */
-
-#ifndef compute_antialias
-#if USE_FLOATS
-#define AA(j) do { \
- float tmp0 = ptr[-1-j]; \
- float tmp1 = ptr[ j]; \
- ptr[-1-j] = tmp0 * csa_table[j][0] - tmp1 * csa_table[j][1]; \
- ptr[ j] = tmp0 * csa_table[j][1] + tmp1 * csa_table[j][0]; \
- } while (0)
-#else
-#define AA(j) do { \
- int tmp0 = ptr[-1-j]; \
- int tmp1 = ptr[ j]; \
- int tmp2 = MULH(tmp0 + tmp1, csa_table[j][0]); \
- ptr[-1-j] = 4 * (tmp2 - MULH(tmp1, csa_table[j][2])); \
- ptr[ j] = 4 * (tmp2 + MULH(tmp0, csa_table[j][3])); \
- } while (0)
-#endif
-
-static void compute_antialias(MPADecodeContext *s, GranuleDef *g)
-{
- INTFLOAT *ptr;
- int n, i;
-
- /* we antialias only "long" bands */
- if (g->block_type == 2) {
- if (!g->switch_point)
- return;
- /* XXX: check this for 8000Hz case */
- n = 1;
- } else {
- n = SBLIMIT - 1;
- }
-
- ptr = g->sb_hybrid + 18;
- for (i = n; i > 0; i--) {
- AA(0);
- AA(1);
- AA(2);
- AA(3);
- AA(4);
- AA(5);
- AA(6);
- AA(7);
-
- ptr += 18;
- }
-}
-#endif /* compute_antialias */
-
-static void compute_imdct(MPADecodeContext *s, GranuleDef *g,
- INTFLOAT *sb_samples, INTFLOAT *mdct_buf)
-{
- INTFLOAT *win, *out_ptr, *ptr, *buf, *ptr1;
- INTFLOAT out2[12];
- int i, j, mdct_long_end, sblimit;
-
- /* find last non zero block */
- ptr = g->sb_hybrid + 576;
- ptr1 = g->sb_hybrid + 2 * 18;
- while (ptr >= ptr1) {
- int32_t *p;
- ptr -= 6;
- p = (int32_t*)ptr;
- if (p[0] | p[1] | p[2] | p[3] | p[4] | p[5])
- break;
- }
- sblimit = ((ptr - g->sb_hybrid) / 18) + 1;
-
- if (g->block_type == 2) {
- /* XXX: check for 8000 Hz */
- if (g->switch_point)
- mdct_long_end = 2;
- else
- mdct_long_end = 0;
- } else {
- mdct_long_end = sblimit;
- }
-
- s->mpadsp.RENAME(imdct36_blocks)(sb_samples, mdct_buf, g->sb_hybrid,
- mdct_long_end, g->switch_point,
- g->block_type);
-
- buf = mdct_buf + 4*18*(mdct_long_end >> 2) + (mdct_long_end & 3);
- ptr = g->sb_hybrid + 18 * mdct_long_end;
-
- for (j = mdct_long_end; j < sblimit; j++) {
- /* select frequency inversion */
- win = RENAME(ff_mdct_win)[2 + (4 & -(j & 1))];
- out_ptr = sb_samples + j;
-
- for (i = 0; i < 6; i++) {
- *out_ptr = buf[4*i];
- out_ptr += SBLIMIT;
- }
- imdct12(out2, ptr + 0);
- for (i = 0; i < 6; i++) {
- *out_ptr = MULH3(out2[i ], win[i ], 1) + buf[4*(i + 6*1)];
- buf[4*(i + 6*2)] = MULH3(out2[i + 6], win[i + 6], 1);
- out_ptr += SBLIMIT;
- }
- imdct12(out2, ptr + 1);
- for (i = 0; i < 6; i++) {
- *out_ptr = MULH3(out2[i ], win[i ], 1) + buf[4*(i + 6*2)];
- buf[4*(i + 6*0)] = MULH3(out2[i + 6], win[i + 6], 1);
- out_ptr += SBLIMIT;
- }
- imdct12(out2, ptr + 2);
- for (i = 0; i < 6; i++) {
- buf[4*(i + 6*0)] = MULH3(out2[i ], win[i ], 1) + buf[4*(i + 6*0)];
- buf[4*(i + 6*1)] = MULH3(out2[i + 6], win[i + 6], 1);
- buf[4*(i + 6*2)] = 0;
- }
- ptr += 18;
- buf += (j&3) != 3 ? 1 : (4*18-3);
- }
- /* zero bands */
- for (j = sblimit; j < SBLIMIT; j++) {
- /* overlap */
- out_ptr = sb_samples + j;
- for (i = 0; i < 18; i++) {
- *out_ptr = buf[4*i];
- buf[4*i] = 0;
- out_ptr += SBLIMIT;
- }
- buf += (j&3) != 3 ? 1 : (4*18-3);
- }
-}
-
-/* main layer3 decoding function */
-static int mp_decode_layer3(MPADecodeContext *s)
-{
- int nb_granules, main_data_begin;
- int gr, ch, blocksplit_flag, i, j, k, n, bits_pos;
- GranuleDef *g;
- int16_t exponents[576]; //FIXME try INTFLOAT
-
- /* read side info */
- if (s->lsf) {
- main_data_begin = get_bits(&s->gb, 8);
- skip_bits(&s->gb, s->nb_channels);
- nb_granules = 1;
- } else {
- main_data_begin = get_bits(&s->gb, 9);
- if (s->nb_channels == 2)
- skip_bits(&s->gb, 3);
- else
- skip_bits(&s->gb, 5);
- nb_granules = 2;
- for (ch = 0; ch < s->nb_channels; ch++) {
- s->granules[ch][0].scfsi = 0;/* all scale factors are transmitted */
- s->granules[ch][1].scfsi = get_bits(&s->gb, 4);
- }
- }
-
- for (gr = 0; gr < nb_granules; gr++) {
- for (ch = 0; ch < s->nb_channels; ch++) {
- ff_dlog(s->avctx, "gr=%d ch=%d: side_info\n", gr, ch);
- g = &s->granules[ch][gr];
- g->part2_3_length = get_bits(&s->gb, 12);
- g->big_values = get_bits(&s->gb, 9);
- if (g->big_values > 288) {
- av_log(s->avctx, AV_LOG_ERROR, "big_values too big\n");
- return AVERROR_INVALIDDATA;
- }
-
- g->global_gain = get_bits(&s->gb, 8);
- /* if MS stereo only is selected, we precompute the
- 1/sqrt(2) renormalization factor */
- if ((s->mode_ext & (MODE_EXT_MS_STEREO | MODE_EXT_I_STEREO)) ==
- MODE_EXT_MS_STEREO)
- g->global_gain -= 2;
- if (s->lsf)
- g->scalefac_compress = get_bits(&s->gb, 9);
- else
- g->scalefac_compress = get_bits(&s->gb, 4);
- blocksplit_flag = get_bits1(&s->gb);
- if (blocksplit_flag) {
- g->block_type = get_bits(&s->gb, 2);
- if (g->block_type == 0) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid block type\n");
- return AVERROR_INVALIDDATA;
- }
- g->switch_point = get_bits1(&s->gb);
- for (i = 0; i < 2; i++)
- g->table_select[i] = get_bits(&s->gb, 5);
- for (i = 0; i < 3; i++)
- g->subblock_gain[i] = get_bits(&s->gb, 3);
- init_short_region(s, g);
- } else {
- int region_address1, region_address2;
- g->block_type = 0;
- g->switch_point = 0;
- for (i = 0; i < 3; i++)
- g->table_select[i] = get_bits(&s->gb, 5);
- /* compute huffman coded region sizes */
- region_address1 = get_bits(&s->gb, 4);
- region_address2 = get_bits(&s->gb, 3);
- ff_dlog(s->avctx, "region1=%d region2=%d\n",
- region_address1, region_address2);
- init_long_region(s, g, region_address1, region_address2);
- }
- region_offset2size(g);
- compute_band_indexes(s, g);
-
- g->preflag = 0;
- if (!s->lsf)
- g->preflag = get_bits1(&s->gb);
- g->scalefac_scale = get_bits1(&s->gb);
- g->count1table_select = get_bits1(&s->gb);
- ff_dlog(s->avctx, "block_type=%d switch_point=%d\n",
- g->block_type, g->switch_point);
- }
- }
-
- if (!s->adu_mode) {
- int skip;
- const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3);
- int extrasize = av_clip(get_bits_left(&s->gb) >> 3, 0, EXTRABYTES);
- av_assert1((get_bits_count(&s->gb) & 7) == 0);
- /* now we get bits from the main_data_begin offset */
- ff_dlog(s->avctx, "seekback:%d, lastbuf:%d\n",
- main_data_begin, s->last_buf_size);
-
- memcpy(s->last_buf + s->last_buf_size, ptr, extrasize);
- s->in_gb = s->gb;
- init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8);
-#if !UNCHECKED_BITSTREAM_READER
- s->gb.size_in_bits_plus8 += FFMAX(extrasize, LAST_BUF_SIZE - s->last_buf_size) * 8;
-#endif
- s->last_buf_size <<= 3;
- for (gr = 0; gr < nb_granules && (s->last_buf_size >> 3) < main_data_begin; gr++) {
- for (ch = 0; ch < s->nb_channels; ch++) {
- g = &s->granules[ch][gr];
- s->last_buf_size += g->part2_3_length;
- memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid));
- compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]);
- }
- }
- skip = s->last_buf_size - 8 * main_data_begin;
- if (skip >= s->gb.size_in_bits && s->in_gb.buffer) {
- skip_bits_long(&s->in_gb, skip - s->gb.size_in_bits);
- s->gb = s->in_gb;
- s->in_gb.buffer = NULL;
- } else {
- skip_bits_long(&s->gb, skip);
- }
- } else {
- gr = 0;
- }
-
- for (; gr < nb_granules; gr++) {
- for (ch = 0; ch < s->nb_channels; ch++) {
- g = &s->granules[ch][gr];
- bits_pos = get_bits_count(&s->gb);
-
- if (!s->lsf) {
- uint8_t *sc;
- int slen, slen1, slen2;
-
- /* MPEG1 scale factors */
- slen1 = slen_table[0][g->scalefac_compress];
- slen2 = slen_table[1][g->scalefac_compress];
- ff_dlog(s->avctx, "slen1=%d slen2=%d\n", slen1, slen2);
- if (g->block_type == 2) {
- n = g->switch_point ? 17 : 18;
- j = 0;
- if (slen1) {
- for (i = 0; i < n; i++)
- g->scale_factors[j++] = get_bits(&s->gb, slen1);
- } else {
- for (i = 0; i < n; i++)
- g->scale_factors[j++] = 0;
- }
- if (slen2) {
- for (i = 0; i < 18; i++)
- g->scale_factors[j++] = get_bits(&s->gb, slen2);
- for (i = 0; i < 3; i++)
- g->scale_factors[j++] = 0;
- } else {
- for (i = 0; i < 21; i++)
- g->scale_factors[j++] = 0;
- }
- } else {
- sc = s->granules[ch][0].scale_factors;
- j = 0;
- for (k = 0; k < 4; k++) {
- n = k == 0 ? 6 : 5;
- if ((g->scfsi & (0x8 >> k)) == 0) {
- slen = (k < 2) ? slen1 : slen2;
- if (slen) {
- for (i = 0; i < n; i++)
- g->scale_factors[j++] = get_bits(&s->gb, slen);
- } else {
- for (i = 0; i < n; i++)
- g->scale_factors[j++] = 0;
- }
- } else {
- /* simply copy from last granule */
- for (i = 0; i < n; i++) {
- g->scale_factors[j] = sc[j];
- j++;
- }
- }
- }
- g->scale_factors[j++] = 0;
- }
- } else {
- int tindex, tindex2, slen[4], sl, sf;
-
- /* LSF scale factors */
- if (g->block_type == 2)
- tindex = g->switch_point ? 2 : 1;
- else
- tindex = 0;
-
- sf = g->scalefac_compress;
- if ((s->mode_ext & MODE_EXT_I_STEREO) && ch == 1) {
- /* intensity stereo case */
- sf >>= 1;
- if (sf < 180) {
- lsf_sf_expand(slen, sf, 6, 6, 0);
- tindex2 = 3;
- } else if (sf < 244) {
- lsf_sf_expand(slen, sf - 180, 4, 4, 0);
- tindex2 = 4;
- } else {
- lsf_sf_expand(slen, sf - 244, 3, 0, 0);
- tindex2 = 5;
- }
- } else {
- /* normal case */
- if (sf < 400) {
- lsf_sf_expand(slen, sf, 5, 4, 4);
- tindex2 = 0;
- } else if (sf < 500) {
- lsf_sf_expand(slen, sf - 400, 5, 4, 0);
- tindex2 = 1;
- } else {
- lsf_sf_expand(slen, sf - 500, 3, 0, 0);
- tindex2 = 2;
- g->preflag = 1;
- }
- }
-
- j = 0;
- for (k = 0; k < 4; k++) {
- n = lsf_nsf_table[tindex2][tindex][k];
- sl = slen[k];
- if (sl) {
- for (i = 0; i < n; i++)
- g->scale_factors[j++] = get_bits(&s->gb, sl);
- } else {
- for (i = 0; i < n; i++)
- g->scale_factors[j++] = 0;
- }
- }
- /* XXX: should compute exact size */
- for (; j < 40; j++)
- g->scale_factors[j] = 0;
- }
-
- exponents_from_scale_factors(s, g, exponents);
-
- /* read Huffman coded residue */
- huffman_decode(s, g, exponents, bits_pos + g->part2_3_length);
- } /* ch */
-
- if (s->mode == MPA_JSTEREO)
- compute_stereo(s, &s->granules[0][gr], &s->granules[1][gr]);
-
- for (ch = 0; ch < s->nb_channels; ch++) {
- g = &s->granules[ch][gr];
-
- reorder_block(s, g);
- compute_antialias(s, g);
- compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]);
- }
- } /* gr */
- if (get_bits_count(&s->gb) < 0)
- skip_bits_long(&s->gb, -get_bits_count(&s->gb));
- return nb_granules * 18;
-}
-
-static int mp_decode_frame(MPADecodeContext *s, OUT_INT **samples,
- const uint8_t *buf, int buf_size)
-{
- int i, nb_frames, ch, ret;
- OUT_INT *samples_ptr;
-
- init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE) * 8);
-
- /* skip error protection field */
- if (s->error_protection)
- skip_bits(&s->gb, 16);
-
- switch(s->layer) {
- case 1:
- s->avctx->frame_size = 384;
- nb_frames = mp_decode_layer1(s);
- break;
- case 2:
- s->avctx->frame_size = 1152;
- nb_frames = mp_decode_layer2(s);
- break;
- case 3:
- s->avctx->frame_size = s->lsf ? 576 : 1152;
- default:
- nb_frames = mp_decode_layer3(s);
-
- s->last_buf_size=0;
- if (s->in_gb.buffer) {
- align_get_bits(&s->gb);
- i = get_bits_left(&s->gb)>>3;
- if (i >= 0 && i <= BACKSTEP_SIZE) {
- memmove(s->last_buf, s->gb.buffer + (get_bits_count(&s->gb)>>3), i);
- s->last_buf_size=i;
- } else
- av_log(s->avctx, AV_LOG_ERROR, "invalid old backstep %d\n", i);
- s->gb = s->in_gb;
- s->in_gb.buffer = NULL;
- }
-
- align_get_bits(&s->gb);
- av_assert1((get_bits_count(&s->gb) & 7) == 0);
- i = get_bits_left(&s->gb) >> 3;
-
- if (i < 0 || i > BACKSTEP_SIZE || nb_frames < 0) {
- if (i < 0)
- av_log(s->avctx, AV_LOG_ERROR, "invalid new backstep %d\n", i);
- i = FFMIN(BACKSTEP_SIZE, buf_size - HEADER_SIZE);
- }
- av_assert1(i <= buf_size - HEADER_SIZE && i >= 0);
- memcpy(s->last_buf + s->last_buf_size, s->gb.buffer + buf_size - HEADER_SIZE - i, i);
- s->last_buf_size += i;
- }
-
- if(nb_frames < 0)
- return nb_frames;
-
- /* get output buffer */
- if (!samples) {
- av_assert0(s->frame);
- s->frame->nb_samples = s->avctx->frame_size;
- if ((ret = ff_get_buffer(s->avctx, s->frame, 0)) < 0)
- return ret;
- samples = (OUT_INT **)s->frame->extended_data;
- }
-
- /* apply the synthesis filter */
- for (ch = 0; ch < s->nb_channels; ch++) {
- int sample_stride;
- if (s->avctx->sample_fmt == OUT_FMT_P) {
- samples_ptr = samples[ch];
- sample_stride = 1;
- } else {
- samples_ptr = samples[0] + ch;
- sample_stride = s->nb_channels;
- }
- for (i = 0; i < nb_frames; i++) {
- RENAME(ff_mpa_synth_filter)(&s->mpadsp, s->synth_buf[ch],
- &(s->synth_buf_offset[ch]),
- RENAME(ff_mpa_synth_window),
- &s->dither_state, samples_ptr,
- sample_stride, s->sb_samples[ch][i]);
- samples_ptr += 32 * sample_stride;
- }
- }
-
- return nb_frames * 32 * sizeof(OUT_INT) * s->nb_channels;
-}
-
-static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- MPADecodeContext *s = avctx->priv_data;
- uint32_t header;
- int ret;
-
- int skipped = 0;
- while(buf_size && !*buf){
- buf++;
- buf_size--;
- skipped++;
- }
-
- if (buf_size < HEADER_SIZE)
- return AVERROR_INVALIDDATA;
-
- header = AV_RB32(buf);
- if (header>>8 == AV_RB32("TAG")>>8) {
- av_log(avctx, AV_LOG_DEBUG, "discarding ID3 tag\n");
- return buf_size;
- }
- if (ff_mpa_check_header(header) < 0) {
- av_log(avctx, AV_LOG_ERROR, "Header missing\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header) == 1) {
- /* free format: prepare to compute frame size */
- s->frame_size = -1;
- return AVERROR_INVALIDDATA;
- }
- /* update codec info */
- avctx->channels = s->nb_channels;
- avctx->channel_layout = s->nb_channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
- if (!avctx->bit_rate)
- avctx->bit_rate = s->bit_rate;
-
- if (s->frame_size <= 0) {
- av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
- return AVERROR_INVALIDDATA;
- } else if (s->frame_size < buf_size) {
- av_log(avctx, AV_LOG_DEBUG, "incorrect frame size - multiple frames in buffer?\n");
- buf_size= s->frame_size;
- }
-
- s->frame = data;
-
- ret = mp_decode_frame(s, NULL, buf, buf_size);
- if (ret >= 0) {
- s->frame->nb_samples = avctx->frame_size;
- *got_frame_ptr = 1;
- avctx->sample_rate = s->sample_rate;
- //FIXME maybe move the other codec info stuff from above here too
- } else {
- av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n");
- /* Only return an error if the bad frame makes up the whole packet or
- * the error is related to buffer management.
- * If there is more data in the packet, just consume the bad frame
- * instead of returning an error, which would discard the whole
- * packet. */
- *got_frame_ptr = 0;
- if (buf_size == avpkt->size || ret != AVERROR_INVALIDDATA)
- return ret;
- }
- s->frame_size = 0;
- return buf_size + skipped;
-}
-
-static void mp_flush(MPADecodeContext *ctx)
-{
- memset(ctx->synth_buf, 0, sizeof(ctx->synth_buf));
- memset(ctx->mdct_buf, 0, sizeof(ctx->mdct_buf));
- ctx->last_buf_size = 0;
- ctx->dither_state = 0;
-}
-
-static void flush(AVCodecContext *avctx)
-{
- mp_flush(avctx->priv_data);
-}
-
-#if CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER
-static int decode_frame_adu(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- MPADecodeContext *s = avctx->priv_data;
- uint32_t header;
- int len, ret;
- int av_unused out_size;
-
- len = buf_size;
-
- // Discard too short frames
- if (buf_size < HEADER_SIZE) {
- av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
- return AVERROR_INVALIDDATA;
- }
-
-
- if (len > MPA_MAX_CODED_FRAME_SIZE)
- len = MPA_MAX_CODED_FRAME_SIZE;
-
- // Get header and restore sync word
- header = AV_RB32(buf) | 0xffe00000;
-
- if (ff_mpa_check_header(header) < 0) { // Bad header, discard frame
- av_log(avctx, AV_LOG_ERROR, "Invalid frame header\n");
- return AVERROR_INVALIDDATA;
- }
-
- avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header);
- /* update codec info */
- avctx->sample_rate = s->sample_rate;
- avctx->channels = s->nb_channels;
- avctx->channel_layout = s->nb_channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
- if (!avctx->bit_rate)
- avctx->bit_rate = s->bit_rate;
-
- s->frame_size = len;
-
- s->frame = data;
-
- ret = mp_decode_frame(s, NULL, buf, buf_size);
- if (ret < 0) {
- av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n");
- return ret;
- }
-
- *got_frame_ptr = 1;
-
- return buf_size;
-}
-#endif /* CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER */
-
-#if CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER
-
-/**
- * Context for MP3On4 decoder
- */
-typedef struct MP3On4DecodeContext {
- int frames; ///< number of mp3 frames per block (number of mp3 decoder instances)
- int syncword; ///< syncword patch
- const uint8_t *coff; ///< channel offsets in output buffer
- MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance
-} MP3On4DecodeContext;
-
-#include "mpeg4audio.h"
-
-/* Next 3 arrays are indexed by channel config number (passed via codecdata) */
-
-/* number of mp3 decoder instances */
-static const uint8_t mp3Frames[8] = { 0, 1, 1, 2, 3, 3, 4, 5 };
-
-/* offsets into output buffer, assume output order is FL FR C LFE BL BR SL SR */
-static const uint8_t chan_offset[8][5] = {
- { 0 },
- { 0 }, // C
- { 0 }, // FLR
- { 2, 0 }, // C FLR
- { 2, 0, 3 }, // C FLR BS
- { 2, 0, 3 }, // C FLR BLRS
- { 2, 0, 4, 3 }, // C FLR BLRS LFE
- { 2, 0, 6, 4, 3 }, // C FLR BLRS BLR LFE
-};
-
-/* mp3on4 channel layouts */
-static const int16_t chan_layout[8] = {
- 0,
- AV_CH_LAYOUT_MONO,
- AV_CH_LAYOUT_STEREO,
- AV_CH_LAYOUT_SURROUND,
- AV_CH_LAYOUT_4POINT0,
- AV_CH_LAYOUT_5POINT0,
- AV_CH_LAYOUT_5POINT1,
- AV_CH_LAYOUT_7POINT1
-};
-
-static av_cold int decode_close_mp3on4(AVCodecContext * avctx)
-{
- MP3On4DecodeContext *s = avctx->priv_data;
- int i;
-
- for (i = 0; i < s->frames; i++)
- av_freep(&s->mp3decctx[i]);
-
- return 0;
-}
-
-
-static av_cold int decode_init_mp3on4(AVCodecContext * avctx)
-{
- MP3On4DecodeContext *s = avctx->priv_data;
- MPEG4AudioConfig cfg;
- int i;
-
- if ((avctx->extradata_size < 2) || !avctx->extradata) {
- av_log(avctx, AV_LOG_ERROR, "Codec extradata missing or too short.\n");
- return AVERROR_INVALIDDATA;
- }
-
- avpriv_mpeg4audio_get_config(&cfg, avctx->extradata,
- avctx->extradata_size * 8, 1);
- if (!cfg.chan_config || cfg.chan_config > 7) {
- av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n");
- return AVERROR_INVALIDDATA;
- }
- s->frames = mp3Frames[cfg.chan_config];
- s->coff = chan_offset[cfg.chan_config];
- avctx->channels = ff_mpeg4audio_channels[cfg.chan_config];
- avctx->channel_layout = chan_layout[cfg.chan_config];
-
- if (cfg.sample_rate < 16000)
- s->syncword = 0xffe00000;
- else
- s->syncword = 0xfff00000;
-
- /* Init the first mp3 decoder in standard way, so that all tables get builded
- * We replace avctx->priv_data with the context of the first decoder so that
- * decode_init() does not have to be changed.
- * Other decoders will be initialized here copying data from the first context
- */
- // Allocate zeroed memory for the first decoder context
- s->mp3decctx[0] = av_mallocz(sizeof(MPADecodeContext));
- if (!s->mp3decctx[0])
- goto alloc_fail;
- // Put decoder context in place to make init_decode() happy
- avctx->priv_data = s->mp3decctx[0];
- decode_init(avctx);
- // Restore mp3on4 context pointer
- avctx->priv_data = s;
- s->mp3decctx[0]->adu_mode = 1; // Set adu mode
-
- /* Create a separate codec/context for each frame (first is already ok).
- * Each frame is 1 or 2 channels - up to 5 frames allowed
- */
- for (i = 1; i < s->frames; i++) {
- s->mp3decctx[i] = av_mallocz(sizeof(MPADecodeContext));
- if (!s->mp3decctx[i])
- goto alloc_fail;
- s->mp3decctx[i]->adu_mode = 1;
- s->mp3decctx[i]->avctx = avctx;
- s->mp3decctx[i]->mpadsp = s->mp3decctx[0]->mpadsp;
- s->mp3decctx[i]->fdsp = s->mp3decctx[0]->fdsp;
- }
-
- return 0;
-alloc_fail:
- decode_close_mp3on4(avctx);
- return AVERROR(ENOMEM);
-}
-
-
-static void flush_mp3on4(AVCodecContext *avctx)
-{
- int i;
- MP3On4DecodeContext *s = avctx->priv_data;
-
- for (i = 0; i < s->frames; i++)
- mp_flush(s->mp3decctx[i]);
-}
-
-
-static int decode_frame_mp3on4(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- AVFrame *frame = data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- MP3On4DecodeContext *s = avctx->priv_data;
- MPADecodeContext *m;
- int fsize, len = buf_size, out_size = 0;
- uint32_t header;
- OUT_INT **out_samples;
- OUT_INT *outptr[2];
- int fr, ch, ret;
-
- /* get output buffer */
- frame->nb_samples = MPA_FRAME_SIZE;
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
- out_samples = (OUT_INT **)frame->extended_data;
-
- // Discard too short frames
- if (buf_size < HEADER_SIZE)
- return AVERROR_INVALIDDATA;
-
- avctx->bit_rate = 0;
-
- ch = 0;
- for (fr = 0; fr < s->frames; fr++) {
- fsize = AV_RB16(buf) >> 4;
- fsize = FFMIN3(fsize, len, MPA_MAX_CODED_FRAME_SIZE);
- m = s->mp3decctx[fr];
- av_assert1(m);
-
- if (fsize < HEADER_SIZE) {
- av_log(avctx, AV_LOG_ERROR, "Frame size smaller than header size\n");
- return AVERROR_INVALIDDATA;
- }
- header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header
-
- if (ff_mpa_check_header(header) < 0) {
- av_log(avctx, AV_LOG_ERROR, "Bad header, discard block\n");
- return AVERROR_INVALIDDATA;
- }
-
- avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header);
-
- if (ch + m->nb_channels > avctx->channels ||
- s->coff[fr] + m->nb_channels > avctx->channels) {
- av_log(avctx, AV_LOG_ERROR, "frame channel count exceeds codec "
- "channel count\n");
- return AVERROR_INVALIDDATA;
- }
- ch += m->nb_channels;
-
- outptr[0] = out_samples[s->coff[fr]];
- if (m->nb_channels > 1)
- outptr[1] = out_samples[s->coff[fr] + 1];
-
- if ((ret = mp_decode_frame(m, outptr, buf, fsize)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "failed to decode channel %d\n", ch);
- memset(outptr[0], 0, MPA_FRAME_SIZE*sizeof(OUT_INT));
- if (m->nb_channels > 1)
- memset(outptr[1], 0, MPA_FRAME_SIZE*sizeof(OUT_INT));
- ret = m->nb_channels * MPA_FRAME_SIZE*sizeof(OUT_INT);
- }
-
- out_size += ret;
- buf += fsize;
- len -= fsize;
-
- avctx->bit_rate += m->bit_rate;
- }
- if (ch != avctx->channels) {
- av_log(avctx, AV_LOG_ERROR, "failed to decode all channels\n");
- return AVERROR_INVALIDDATA;
- }
-
- /* update codec info */
- avctx->sample_rate = s->mp3decctx[0]->sample_rate;
-
- frame->nb_samples = out_size / (avctx->channels * sizeof(OUT_INT));
- *got_frame_ptr = 1;
-
- return buf_size;
-}
-#endif /* CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER */
diff --git a/ffmpeg-2-8-11/libavcodec/mpegvideo_motion.c b/ffmpeg-2-8-11/libavcodec/mpegvideo_motion.c
deleted file mode 100644
index 51ba435..0000000
--- a/ffmpeg-2-8-11/libavcodec/mpegvideo_motion.c
+++ /dev/null
@@ -1,990 +0,0 @@
-/*
- * Copyright (c) 2000,2001 Fabrice Bellard
- * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni at gmx.at>
- *
- * 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 <string.h>
-
-#include "libavutil/avassert.h"
-#include "libavutil/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 <limits.h>
-
-static void gmc1_motion(MpegEncContext *s,
- uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
- uint8_t **ref_picture)
-{
- uint8_t *ptr;
- int src_x, src_y, motion_x, motion_y;
- ptrdiff_t offset, linesize, uvlinesize;
- int emu = 0;
-
- motion_x = s->sprite_offset[0][0];
- motion_y = s->sprite_offset[0][1];
- src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy + 1));
- src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy + 1));
- motion_x <<= (3 - s->sprite_warping_accuracy);
- motion_y <<= (3 - s->sprite_warping_accuracy);
- src_x = av_clip(src_x, -16, s->width);
- if (src_x == s->width)
- motion_x = 0;
- src_y = av_clip(src_y, -16, s->height);
- if (src_y == s->height)
- motion_y = 0;
-
- linesize = s->linesize;
- uvlinesize = s->uvlinesize;
-
- ptr = ref_picture[0] + src_y * linesize + src_x;
-
- if ((unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0) ||
- (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)) {
- s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
- linesize, linesize,
- 17, 17,
- src_x, src_y,
- s->h_edge_pos, s->v_edge_pos);
- ptr = s->sc.edge_emu_buffer;
- }
-
- if ((motion_x | motion_y) & 7) {
- s->mdsp.gmc1(dest_y, ptr, linesize, 16,
- motion_x & 15, motion_y & 15, 128 - s->no_rounding);
- s->mdsp.gmc1(dest_y + 8, ptr + 8, linesize, 16,
- motion_x & 15, motion_y & 15, 128 - s->no_rounding);
- } else {
- int dxy;
-
- dxy = ((motion_x >> 3) & 1) | ((motion_y >> 2) & 2);
- if (s->no_rounding) {
- s->hdsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
- } else {
- s->hdsp.put_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
- }
- }
-
- if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
- return;
-
- motion_x = s->sprite_offset[1][0];
- motion_y = s->sprite_offset[1][1];
- src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy + 1));
- src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy + 1));
- motion_x <<= (3 - s->sprite_warping_accuracy);
- motion_y <<= (3 - s->sprite_warping_accuracy);
- src_x = av_clip(src_x, -8, s->width >> 1);
- if (src_x == s->width >> 1)
- motion_x = 0;
- src_y = av_clip(src_y, -8, s->height >> 1);
- if (src_y == s->height >> 1)
- motion_y = 0;
-
- offset = (src_y * uvlinesize) + src_x;
- ptr = ref_picture[1] + offset;
- if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - 9, 0) ||
- (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - 9, 0)) {
- s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
- uvlinesize, uvlinesize,
- 9, 9,
- src_x, src_y,
- s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- ptr = s->sc.edge_emu_buffer;
- emu = 1;
- }
- s->mdsp.gmc1(dest_cb, ptr, uvlinesize, 8,
- motion_x & 15, motion_y & 15, 128 - s->no_rounding);
-
- ptr = ref_picture[2] + offset;
- if (emu) {
- s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
- uvlinesize, uvlinesize,
- 9, 9,
- src_x, src_y,
- s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- ptr = s->sc.edge_emu_buffer;
- }
- s->mdsp.gmc1(dest_cr, ptr, uvlinesize, 8,
- motion_x & 15, motion_y & 15, 128 - s->no_rounding);
-}
-
-static void gmc_motion(MpegEncContext *s,
- uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
- uint8_t **ref_picture)
-{
- uint8_t *ptr;
- int linesize, uvlinesize;
- const int a = s->sprite_warping_accuracy;
- int ox, oy;
-
- linesize = s->linesize;
- uvlinesize = s->uvlinesize;
-
- ptr = ref_picture[0];
-
- ox = s->sprite_offset[0][0] + s->sprite_delta[0][0] * s->mb_x * 16 +
- s->sprite_delta[0][1] * s->mb_y * 16;
- oy = s->sprite_offset[0][1] + s->sprite_delta[1][0] * s->mb_x * 16 +
- s->sprite_delta[1][1] * s->mb_y * 16;
-
- s->mdsp.gmc(dest_y, ptr, linesize, 16,
- ox, oy,
- s->sprite_delta[0][0], s->sprite_delta[0][1],
- s->sprite_delta[1][0], s->sprite_delta[1][1],
- a + 1, (1 << (2 * a + 1)) - s->no_rounding,
- s->h_edge_pos, s->v_edge_pos);
- s->mdsp.gmc(dest_y + 8, ptr, linesize, 16,
- ox + s->sprite_delta[0][0] * 8,
- oy + s->sprite_delta[1][0] * 8,
- s->sprite_delta[0][0], s->sprite_delta[0][1],
- s->sprite_delta[1][0], s->sprite_delta[1][1],
- a + 1, (1 << (2 * a + 1)) - s->no_rounding,
- s->h_edge_pos, s->v_edge_pos);
-
- if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
- return;
-
- ox = s->sprite_offset[1][0] + s->sprite_delta[0][0] * s->mb_x * 8 +
- s->sprite_delta[0][1] * s->mb_y * 8;
- oy = s->sprite_offset[1][1] + s->sprite_delta[1][0] * s->mb_x * 8 +
- s->sprite_delta[1][1] * s->mb_y * 8;
-
- ptr = ref_picture[1];
- s->mdsp.gmc(dest_cb, ptr, uvlinesize, 8,
- ox, oy,
- s->sprite_delta[0][0], s->sprite_delta[0][1],
- s->sprite_delta[1][0], s->sprite_delta[1][1],
- a + 1, (1 << (2 * a + 1)) - s->no_rounding,
- (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1);
-
- ptr = ref_picture[2];
- s->mdsp.gmc(dest_cr, ptr, uvlinesize, 8,
- ox, oy,
- s->sprite_delta[0][0], s->sprite_delta[0][1],
- s->sprite_delta[1][0], s->sprite_delta[1][1],
- a + 1, (1 << (2 * a + 1)) - s->no_rounding,
- (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1);
-}
-
-static inline int hpel_motion(MpegEncContext *s,
- uint8_t *dest, uint8_t *src,
- int src_x, int src_y,
- op_pixels_func *pix_op,
- int motion_x, int motion_y)
-{
- int dxy = 0;
- int emu = 0;
-
- src_x += motion_x >> 1;
- src_y += motion_y >> 1;
-
- /* WARNING: do no forget half pels */
- src_x = av_clip(src_x, -16, s->width); // FIXME unneeded for emu?
- if (src_x != s->width)
- dxy |= motion_x & 1;
- src_y = av_clip(src_y, -16, s->height);
- if (src_y != s->height)
- 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;
- }
- pix_op[dxy](dest, src, s->linesize, 8);
- return emu;
-}
-
-static av_always_inline
-void mpeg_motion_internal(MpegEncContext *s,
- uint8_t *dest_y,
- uint8_t *dest_cb,
- uint8_t *dest_cr,
- int field_based,
- int bottom_field,
- int field_select,
- uint8_t **ref_picture,
- op_pixels_func (*pix_op)[4],
- int motion_x,
- int motion_y,
- int h,
- int is_mpeg12,
- int mb_y)
-{
- uint8_t *ptr_y, *ptr_cb, *ptr_cr;
- int dxy, uvdxy, mx, my, src_x, src_y,
- uvsrc_x, uvsrc_y, v_edge_pos;
- ptrdiff_t uvlinesize, linesize;
-
-#if 0
- if (s->quarter_sample) {
- motion_x >>= 1;
- motion_y >>= 1;
- }
-#endif
-
- v_edge_pos = s->v_edge_pos >> field_based;
- linesize = s->current_picture.f->linesize[0] << field_based;
- uvlinesize = s->current_picture.f->linesize[1] << field_based;
-
- dxy = ((motion_y & 1) << 1) | (motion_x & 1);
- src_x = s->mb_x * 16 + (motion_x >> 1);
- src_y = (mb_y << (4 - field_based)) + (motion_y >> 1);
-
- if (!is_mpeg12 && s->out_format == FMT_H263) {
- if ((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based) {
- mx = (motion_x >> 1) | (motion_x & 1);
- my = motion_y >> 1;
- uvdxy = ((my & 1) << 1) | (mx & 1);
- uvsrc_x = s->mb_x * 8 + (mx >> 1);
- uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1);
- } else {
- uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1);
- uvsrc_x = src_x >> 1;
- uvsrc_y = src_y >> 1;
- }
- // Even chroma mv's are full pel in H261
- } else if (!is_mpeg12 && s->out_format == FMT_H261) {
- mx = motion_x / 4;
- my = motion_y / 4;
- uvdxy = 0;
- uvsrc_x = s->mb_x * 8 + mx;
- uvsrc_y = mb_y * 8 + my;
- } else {
- if (s->chroma_y_shift) {
- mx = motion_x / 2;
- my = motion_y / 2;
- uvdxy = ((my & 1) << 1) | (mx & 1);
- uvsrc_x = s->mb_x * 8 + (mx >> 1);
- uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1);
- } else {
- if (s->chroma_x_shift) {
- // Chroma422
- mx = motion_x / 2;
- uvdxy = ((motion_y & 1) << 1) | (mx & 1);
- uvsrc_x = s->mb_x * 8 + (mx >> 1);
- uvsrc_y = src_y;
- } else {
- // Chroma444
- uvdxy = dxy;
- uvsrc_x = src_x;
- uvsrc_y = src_y;
- }
- }
- }
-
- ptr_y = ref_picture[0] + src_y * linesize + src_x;
- ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
- ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
-
- if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 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) {
- av_log(s->avctx, AV_LOG_DEBUG,
- "MPEG motion vector out of boundary (%d %d)\n", src_x,
- src_y);
- return;
- }
- src_y = (unsigned)src_y << field_based;
- s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr_y,
- s->linesize, s->linesize,
- 17, 17 + field_based,
- src_x, src_y,
- s->h_edge_pos, s->v_edge_pos);
- ptr_y = s->sc.edge_emu_buffer;
- if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
- uint8_t *ubuf = s->sc.edge_emu_buffer + 18 * s->linesize;
- uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
- uvsrc_y = (unsigned)uvsrc_y << field_based;
- s->vdsp.emulated_edge_mc(ubuf, ptr_cb,
- s->uvlinesize, s->uvlinesize,
- 9, 9 + field_based,
- uvsrc_x, uvsrc_y,
- s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- s->vdsp.emulated_edge_mc(vbuf, ptr_cr,
- s->uvlinesize, s->uvlinesize,
- 9, 9 + field_based,
- uvsrc_x, uvsrc_y,
- s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- ptr_cb = ubuf;
- ptr_cr = vbuf;
- }
- }
-
- /* FIXME use this for field pix too instead of the obnoxious hack which
- * changes picture.data */
- if (bottom_field) {
- dest_y += s->linesize;
- dest_cb += s->uvlinesize;
- dest_cr += s->uvlinesize;
- }
-
- if (field_select) {
- ptr_y += s->linesize;
- ptr_cb += s->uvlinesize;
- ptr_cr += s->uvlinesize;
- }
-
- pix_op[0][dxy](dest_y, ptr_y, linesize, h);
-
- if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
- pix_op[s->chroma_x_shift][uvdxy]
- (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift);
- pix_op[s->chroma_x_shift][uvdxy]
- (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift);
- }
- if (!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) &&
- s->out_format == FMT_H261) {
- ff_h261_loop_filter(s);
- }
-}
-/* apply one mpeg motion vector to the three components */
-static void mpeg_motion(MpegEncContext *s,
- uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
- int field_select, uint8_t **ref_picture,
- op_pixels_func (*pix_op)[4],
- int motion_x, int motion_y, int h, int mb_y)
-{
-#if !CONFIG_SMALL
- if (s->out_format == FMT_MPEG1)
- mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0,
- field_select, ref_picture, pix_op,
- motion_x, motion_y, h, 1, mb_y);
- else
-#endif
- mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0,
- field_select, ref_picture, pix_op,
- motion_x, motion_y, h, 0, mb_y);
-}
-
-static void mpeg_motion_field(MpegEncContext *s, uint8_t *dest_y,
- uint8_t *dest_cb, uint8_t *dest_cr,
- int bottom_field, int field_select,
- uint8_t **ref_picture,
- op_pixels_func (*pix_op)[4],
- int motion_x, int motion_y, int h, int mb_y)
-{
-#if !CONFIG_SMALL
- if (s->out_format == FMT_MPEG1)
- mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1,
- bottom_field, field_select, ref_picture, pix_op,
- motion_x, motion_y, h, 1, mb_y);
- else
-#endif
- mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1,
- bottom_field, field_select, ref_picture, pix_op,
- motion_x, motion_y, h, 0, mb_y);
-}
-
-// FIXME: SIMDify, avg variant, 16x16 version
-static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride)
-{
- int x;
- uint8_t *const top = src[1];
- uint8_t *const left = src[2];
- uint8_t *const mid = src[0];
- uint8_t *const right = src[3];
- uint8_t *const bottom = src[4];
-#define OBMC_FILTER(x, t, l, m, r, b)\
- dst[x]= (t*top[x] + l*left[x] + m*mid[x] + r*right[x] + b*bottom[x] + 4)>>3
-#define OBMC_FILTER4(x, t, l, m, r, b)\
- OBMC_FILTER(x , t, l, m, r, b);\
- OBMC_FILTER(x+1 , t, l, m, r, b);\
- OBMC_FILTER(x +stride, t, l, m, r, b);\
- OBMC_FILTER(x+1+stride, t, l, m, r, b);
-
- x = 0;
- OBMC_FILTER (x , 2, 2, 4, 0, 0);
- OBMC_FILTER (x + 1, 2, 1, 5, 0, 0);
- OBMC_FILTER4(x + 2, 2, 1, 5, 0, 0);
- OBMC_FILTER4(x + 4, 2, 0, 5, 1, 0);
- OBMC_FILTER (x + 6, 2, 0, 5, 1, 0);
- OBMC_FILTER (x + 7, 2, 0, 4, 2, 0);
- x += stride;
- OBMC_FILTER (x , 1, 2, 5, 0, 0);
- OBMC_FILTER (x + 1, 1, 2, 5, 0, 0);
- OBMC_FILTER (x + 6, 1, 0, 5, 2, 0);
- OBMC_FILTER (x + 7, 1, 0, 5, 2, 0);
- x += stride;
- OBMC_FILTER4(x , 1, 2, 5, 0, 0);
- OBMC_FILTER4(x + 2, 1, 1, 6, 0, 0);
- OBMC_FILTER4(x + 4, 1, 0, 6, 1, 0);
- OBMC_FILTER4(x + 6, 1, 0, 5, 2, 0);
- x += 2 * stride;
- OBMC_FILTER4(x , 0, 2, 5, 0, 1);
- OBMC_FILTER4(x + 2, 0, 1, 6, 0, 1);
- OBMC_FILTER4(x + 4, 0, 0, 6, 1, 1);
- OBMC_FILTER4(x + 6, 0, 0, 5, 2, 1);
- x += 2*stride;
- OBMC_FILTER (x , 0, 2, 5, 0, 1);
- OBMC_FILTER (x + 1, 0, 2, 5, 0, 1);
- OBMC_FILTER4(x + 2, 0, 1, 5, 0, 2);
- OBMC_FILTER4(x + 4, 0, 0, 5, 1, 2);
- OBMC_FILTER (x + 6, 0, 0, 5, 2, 1);
- OBMC_FILTER (x + 7, 0, 0, 5, 2, 1);
- x += stride;
- OBMC_FILTER (x , 0, 2, 4, 0, 2);
- OBMC_FILTER (x + 1, 0, 1, 5, 0, 2);
- OBMC_FILTER (x + 6, 0, 0, 5, 1, 2);
- OBMC_FILTER (x + 7, 0, 0, 4, 2, 2);
-}
-
-/* obmc for 1 8x8 luma block */
-static inline void obmc_motion(MpegEncContext *s,
- uint8_t *dest, uint8_t *src,
- int src_x, int src_y,
- op_pixels_func *pix_op,
- int16_t mv[5][2] /* mid top left right bottom */)
-#define MID 0
-{
- int i;
- uint8_t *ptr[5];
-
- av_assert2(s->quarter_sample == 0);
-
- for (i = 0; i < 5; i++) {
- if (i && mv[i][0] == mv[MID][0] && mv[i][1] == mv[MID][1]) {
- ptr[i] = ptr[MID];
- } else {
- ptr[i] = s->sc.obmc_scratchpad + 8 * (i & 1) +
- s->linesize * 8 * (i >> 1);
- hpel_motion(s, ptr[i], src, src_x, src_y, pix_op,
- mv[i][0], mv[i][1]);
- }
- }
-
- put_obmc(dest, ptr, s->linesize);
-}
-
-static inline void qpel_motion(MpegEncContext *s,
- uint8_t *dest_y,
- uint8_t *dest_cb,
- uint8_t *dest_cr,
- int field_based, int bottom_field,
- int field_select, uint8_t **ref_picture,
- op_pixels_func (*pix_op)[4],
- qpel_mc_func (*qpix_op)[16],
- int motion_x, int motion_y, int h)
-{
- uint8_t *ptr_y, *ptr_cb, *ptr_cr;
- int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos;
- ptrdiff_t linesize, uvlinesize;
-
- dxy = ((motion_y & 3) << 2) | (motion_x & 3);
-
- src_x = s->mb_x * 16 + (motion_x >> 2);
- src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2);
-
- v_edge_pos = s->v_edge_pos >> field_based;
- linesize = s->linesize << field_based;
- uvlinesize = s->uvlinesize << field_based;
-
- if (field_based) {
- mx = motion_x / 2;
- my = motion_y >> 1;
- } else if (s->workaround_bugs & FF_BUG_QPEL_CHROMA2) {
- static const int rtab[8] = { 0, 0, 1, 1, 0, 0, 0, 1 };
- mx = (motion_x >> 1) + rtab[motion_x & 7];
- my = (motion_y >> 1) + rtab[motion_y & 7];
- } else if (s->workaround_bugs & FF_BUG_QPEL_CHROMA) {
- mx = (motion_x >> 1) | (motion_x & 1);
- my = (motion_y >> 1) | (motion_y & 1);
- } else {
- mx = motion_x / 2;
- my = motion_y / 2;
- }
- mx = (mx >> 1) | (mx & 1);
- my = (my >> 1) | (my & 1);
-
- uvdxy = (mx & 1) | ((my & 1) << 1);
- mx >>= 1;
- my >>= 1;
-
- uvsrc_x = s->mb_x * 8 + mx;
- uvsrc_y = s->mb_y * (8 >> field_based) + my;
-
- ptr_y = ref_picture[0] + src_y * linesize + src_x;
- ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
- ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
-
- if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 3) - 15 , 0) ||
- (unsigned)src_y >= FFMAX( v_edge_pos - (motion_y & 3) - h + 1, 0)) {
- s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr_y,
- s->linesize, s->linesize,
- 17, 17 + field_based,
- src_x, src_y << field_based,
- s->h_edge_pos, s->v_edge_pos);
- ptr_y = s->sc.edge_emu_buffer;
- if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
- uint8_t *ubuf = s->sc.edge_emu_buffer + 18 * s->linesize;
- uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
- s->vdsp.emulated_edge_mc(ubuf, ptr_cb,
- s->uvlinesize, s->uvlinesize,
- 9, 9 + field_based,
- uvsrc_x, uvsrc_y << field_based,
- s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- s->vdsp.emulated_edge_mc(vbuf, ptr_cr,
- s->uvlinesize, s->uvlinesize,
- 9, 9 + field_based,
- uvsrc_x, uvsrc_y << field_based,
- s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- ptr_cb = ubuf;
- ptr_cr = vbuf;
- }
- }
-
- if (!field_based)
- qpix_op[0][dxy](dest_y, ptr_y, linesize);
- else {
- if (bottom_field) {
- dest_y += s->linesize;
- dest_cb += s->uvlinesize;
- dest_cr += s->uvlinesize;
- }
-
- if (field_select) {
- ptr_y += s->linesize;
- ptr_cb += s->uvlinesize;
- ptr_cr += s->uvlinesize;
- }
- // damn interlaced mode
- // FIXME boundary mirroring is not exactly correct here
- qpix_op[1][dxy](dest_y, ptr_y, linesize);
- qpix_op[1][dxy](dest_y + 8, ptr_y + 8, linesize);
- }
- if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
- pix_op[1][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> 1);
- pix_op[1][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> 1);
- }
-}
-
-/**
- * h263 chroma 4mv motion compensation.
- */
-static void chroma_4mv_motion(MpegEncContext *s,
- uint8_t *dest_cb, uint8_t *dest_cr,
- uint8_t **ref_picture,
- op_pixels_func *pix_op,
- int mx, int my)
-{
- uint8_t *ptr;
- int src_x, src_y, dxy, emu = 0;
- ptrdiff_t offset;
-
- /* In case of 8X8, we construct a single chroma motion vector
- * with a special rounding */
- mx = ff_h263_round_chroma(mx);
- my = ff_h263_round_chroma(my);
-
- dxy = ((my & 1) << 1) | (mx & 1);
- mx >>= 1;
- my >>= 1;
-
- src_x = s->mb_x * 8 + mx;
- src_y = s->mb_y * 8 + my;
- src_x = av_clip(src_x, -8, (s->width >> 1));
- if (src_x == (s->width >> 1))
- dxy &= ~1;
- src_y = av_clip(src_y, -8, (s->height >> 1));
- if (src_y == (s->height >> 1))
- dxy &= ~2;
-
- offset = src_y * s->uvlinesize + src_x;
- ptr = ref_picture[1] + offset;
- if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - (dxy & 1) - 7, 0) ||
- (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - (dxy >> 1) - 7, 0)) {
- s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
- s->uvlinesize, s->uvlinesize,
- 9, 9, src_x, src_y,
- s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- ptr = s->sc.edge_emu_buffer;
- emu = 1;
- }
- pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8);
-
- ptr = ref_picture[2] + offset;
- if (emu) {
- s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
- s->uvlinesize, s->uvlinesize,
- 9, 9, src_x, src_y,
- s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- ptr = s->sc.edge_emu_buffer;
- }
- pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8);
-}
-
-static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir)
-{
- /* fetch pixels for estimated mv 4 macroblocks ahead
- * optimized for 64byte cache lines */
- const int shift = s->quarter_sample ? 2 : 1;
- const int mx = (s->mv[dir][0][0] >> shift) + 16 * s->mb_x + 8;
- const int my = (s->mv[dir][0][1] >> shift) + 16 * s->mb_y;
- int off = mx + (my + (s->mb_x & 3) * 4) * s->linesize + 64;
-
- s->vdsp.prefetch(pix[0] + off, s->linesize, 4);
- off = (mx >> 1) + ((my >> 1) + (s->mb_x & 7)) * s->uvlinesize + 64;
- s->vdsp.prefetch(pix[1] + off, pix[2] - pix[1], 2);
-}
-
-static inline void apply_obmc(MpegEncContext *s,
- uint8_t *dest_y,
- uint8_t *dest_cb,
- uint8_t *dest_cr,
- uint8_t **ref_picture,
- op_pixels_func (*pix_op)[4])
-{
- LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]);
- Picture *cur_frame = &s->current_picture;
- int mb_x = s->mb_x;
- int mb_y = s->mb_y;
- const int xy = mb_x + mb_y * s->mb_stride;
- const int mot_stride = s->b8_stride;
- const int mot_xy = mb_x * 2 + mb_y * 2 * mot_stride;
- int mx, my, i;
-
- av_assert2(!s->mb_skipped);
-
- AV_COPY32(mv_cache[1][1], cur_frame->motion_val[0][mot_xy]);
- AV_COPY32(mv_cache[1][2], cur_frame->motion_val[0][mot_xy + 1]);
-
- AV_COPY32(mv_cache[2][1],
- cur_frame->motion_val[0][mot_xy + mot_stride]);
- AV_COPY32(mv_cache[2][2],
- cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
-
- AV_COPY32(mv_cache[3][1],
- cur_frame->motion_val[0][mot_xy + mot_stride]);
- AV_COPY32(mv_cache[3][2],
- cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
-
- if (mb_y == 0 || IS_INTRA(cur_frame->mb_type[xy - s->mb_stride])) {
- AV_COPY32(mv_cache[0][1], mv_cache[1][1]);
- AV_COPY32(mv_cache[0][2], mv_cache[1][2]);
- } else {
- AV_COPY32(mv_cache[0][1],
- cur_frame->motion_val[0][mot_xy - mot_stride]);
- AV_COPY32(mv_cache[0][2],
- cur_frame->motion_val[0][mot_xy - mot_stride + 1]);
- }
-
- if (mb_x == 0 || IS_INTRA(cur_frame->mb_type[xy - 1])) {
- AV_COPY32(mv_cache[1][0], mv_cache[1][1]);
- AV_COPY32(mv_cache[2][0], mv_cache[2][1]);
- } else {
- AV_COPY32(mv_cache[1][0], cur_frame->motion_val[0][mot_xy - 1]);
- AV_COPY32(mv_cache[2][0],
- cur_frame->motion_val[0][mot_xy - 1 + mot_stride]);
- }
-
- if (mb_x + 1 >= s->mb_width || IS_INTRA(cur_frame->mb_type[xy + 1])) {
- AV_COPY32(mv_cache[1][3], mv_cache[1][2]);
- AV_COPY32(mv_cache[2][3], mv_cache[2][2]);
- } else {
- AV_COPY32(mv_cache[1][3], cur_frame->motion_val[0][mot_xy + 2]);
- AV_COPY32(mv_cache[2][3],
- cur_frame->motion_val[0][mot_xy + 2 + mot_stride]);
- }
-
- mx = 0;
- my = 0;
- for (i = 0; i < 4; i++) {
- const int x = (i & 1) + 1;
- const int y = (i >> 1) + 1;
- int16_t mv[5][2] = {
- { mv_cache[y][x][0], mv_cache[y][x][1] },
- { mv_cache[y - 1][x][0], mv_cache[y - 1][x][1] },
- { mv_cache[y][x - 1][0], mv_cache[y][x - 1][1] },
- { mv_cache[y][x + 1][0], mv_cache[y][x + 1][1] },
- { mv_cache[y + 1][x][0], mv_cache[y + 1][x][1] }
- };
- // FIXME cleanup
- obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
- ref_picture[0],
- mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >> 1) * 8,
- pix_op[1],
- mv);
-
- mx += mv[0][0];
- my += mv[0][1];
- }
- if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))
- chroma_4mv_motion(s, dest_cb, dest_cr,
- ref_picture, pix_op[1],
- mx, my);
-}
-
-static inline void apply_8x8(MpegEncContext *s,
- uint8_t *dest_y,
- uint8_t *dest_cb,
- uint8_t *dest_cr,
- int dir,
- uint8_t **ref_picture,
- qpel_mc_func (*qpix_op)[16],
- op_pixels_func (*pix_op)[4])
-{
- int dxy, mx, my, src_x, src_y;
- int i;
- int mb_x = s->mb_x;
- int mb_y = s->mb_y;
- uint8_t *ptr, *dest;
-
- mx = 0;
- my = 0;
- if (s->quarter_sample) {
- for (i = 0; i < 4; i++) {
- int motion_x = s->mv[dir][i][0];
- int motion_y = s->mv[dir][i][1];
-
- dxy = ((motion_y & 3) << 2) | (motion_x & 3);
- src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8;
- src_y = mb_y * 16 + (motion_y >> 2) + (i >> 1) * 8;
-
- /* WARNING: do no forget half pels */
- src_x = av_clip(src_x, -16, s->width);
- if (src_x == s->width)
- dxy &= ~3;
- src_y = av_clip(src_y, -16, s->height);
- if (src_y == s->height)
- dxy &= ~12;
-
- ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
- if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 3) - 7, 0) ||
- (unsigned)src_y >= FFMAX(s->v_edge_pos - (motion_y & 3) - 7, 0)) {
- s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
- s->linesize, s->linesize,
- 9, 9,
- src_x, src_y,
- s->h_edge_pos,
- s->v_edge_pos);
- ptr = s->sc.edge_emu_buffer;
- }
- dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
- qpix_op[1][dxy](dest, ptr, s->linesize);
-
- mx += s->mv[dir][i][0] / 2;
- my += s->mv[dir][i][1] / 2;
- }
- } else {
- for (i = 0; i < 4; i++) {
- hpel_motion(s,
- dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
- ref_picture[0],
- mb_x * 16 + (i & 1) * 8,
- mb_y * 16 + (i >> 1) * 8,
- pix_op[1],
- s->mv[dir][i][0],
- s->mv[dir][i][1]);
-
- mx += s->mv[dir][i][0];
- my += s->mv[dir][i][1];
- }
- }
-
- if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))
- chroma_4mv_motion(s, dest_cb, dest_cr,
- ref_picture, pix_op[1], mx, my);
-}
-
-/**
- * motion compensation of a single macroblock
- * @param s context
- * @param dest_y luma destination pointer
- * @param dest_cb chroma cb/u destination pointer
- * @param dest_cr chroma cr/v destination pointer
- * @param dir direction (0->forward, 1->backward)
- * @param ref_picture array[3] of pointers to the 3 planes of the reference picture
- * @param pix_op halfpel motion compensation function (average or put normally)
- * @param qpix_op qpel motion compensation function (average or put normally)
- * the motion vectors are taken from s->mv and the MV type from s->mv_type
- */
-static av_always_inline void mpv_motion_internal(MpegEncContext *s,
- uint8_t *dest_y,
- uint8_t *dest_cb,
- uint8_t *dest_cr,
- int dir,
- uint8_t **ref_picture,
- op_pixels_func (*pix_op)[4],
- qpel_mc_func (*qpix_op)[16],
- int is_mpeg12)
-{
- int i;
- int mb_y = s->mb_y;
-
- prefetch_motion(s, ref_picture, dir);
-
- if (!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B) {
- apply_obmc(s, dest_y, dest_cb, dest_cr, ref_picture, pix_op);
- return;
- }
-
- switch (s->mv_type) {
- case MV_TYPE_16X16:
- if (s->mcsel) {
- if (s->real_sprite_warping_points == 1) {
- gmc1_motion(s, dest_y, dest_cb, dest_cr,
- ref_picture);
- } else {
- gmc_motion(s, dest_y, dest_cb, dest_cr,
- ref_picture);
- }
- } else if (!is_mpeg12 && s->quarter_sample) {
- qpel_motion(s, dest_y, dest_cb, dest_cr,
- 0, 0, 0,
- ref_picture, pix_op, qpix_op,
- s->mv[dir][0][0], s->mv[dir][0][1], 16);
- } else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) &&
- s->mspel && s->codec_id == AV_CODEC_ID_WMV2) {
- ff_mspel_motion(s, dest_y, dest_cb, dest_cr,
- ref_picture, pix_op,
- s->mv[dir][0][0], s->mv[dir][0][1], 16);
- } else {
- mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,
- ref_picture, pix_op,
- s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y);
- }
- break;
- case MV_TYPE_8X8:
- if (!is_mpeg12)
- apply_8x8(s, dest_y, dest_cb, dest_cr,
- dir, ref_picture, qpix_op, pix_op);
- break;
- case MV_TYPE_FIELD:
- if (s->picture_structure == PICT_FRAME) {
- if (!is_mpeg12 && s->quarter_sample) {
- for (i = 0; i < 2; i++)
- qpel_motion(s, dest_y, dest_cb, dest_cr,
- 1, i, s->field_select[dir][i],
- ref_picture, pix_op, qpix_op,
- s->mv[dir][i][0], s->mv[dir][i][1], 8);
- } else {
- /* top field */
- mpeg_motion_field(s, dest_y, dest_cb, dest_cr,
- 0, s->field_select[dir][0],
- ref_picture, pix_op,
- s->mv[dir][0][0], s->mv[dir][0][1], 8, mb_y);
- /* bottom field */
- mpeg_motion_field(s, dest_y, dest_cb, dest_cr,
- 1, s->field_select[dir][1],
- ref_picture, pix_op,
- s->mv[dir][1][0], s->mv[dir][1][1], 8, mb_y);
- }
- } else {
- if ( s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != AV_PICTURE_TYPE_B && !s->first_field
- || !ref_picture[0]) {
- ref_picture = s->current_picture_ptr->f->data;
- }
-
- mpeg_motion(s, dest_y, dest_cb, dest_cr,
- s->field_select[dir][0],
- ref_picture, pix_op,
- s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y >> 1);
- }
- 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] + 16 * i,
- 8, mb_y >> 1);
-
- dest_y += 16 * s->linesize;
- dest_cb += (16 >> s->chroma_y_shift) * s->uvlinesize;
- dest_cr += (16 >> s->chroma_y_shift) * s->uvlinesize;
- }
- 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;
- }
- 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, 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;
- default: av_assert2(0);
- }
-}
-
-void ff_mpv_motion(MpegEncContext *s,
- uint8_t *dest_y, uint8_t *dest_cb,
- uint8_t *dest_cr, int dir,
- uint8_t **ref_picture,
- op_pixels_func (*pix_op)[4],
- qpel_mc_func (*qpix_op)[16])
-{
-#if !CONFIG_SMALL
- if (s->out_format == FMT_MPEG1)
- mpv_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
- ref_picture, pix_op, qpix_op, 1);
- else
-#endif
- mpv_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
- ref_picture, pix_op, qpix_op, 0);
-}
diff --git a/ffmpeg-2-8-11/libavcodec/msmpeg4dec.c b/ffmpeg-2-8-11/libavcodec/msmpeg4dec.c
deleted file mode 100644
index aaadd9c..0000000
--- a/ffmpeg-2-8-11/libavcodec/msmpeg4dec.c
+++ /dev/null
@@ -1,984 +0,0 @@
-/*
- * MSMPEG4 backend for encoder and decoder
- * Copyright (c) 2001 Fabrice Bellard
- * Copyright (c) 2002-2013 Michael Niedermayer <michaelni at gmx.at>
- *
- * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni at gmx.at>
- *
- * 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 "mpegutils.h"
-#include "mpegvideo.h"
-#include "msmpeg4.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/x86/asm.h"
-#include "h263.h"
-#include "mpeg4video.h"
-#include "msmpeg4data.h"
-#include "vc1data.h"
-#include "wmv2.h"
-
-#define DC_VLC_BITS 9
-#define V2_INTRA_CBPC_VLC_BITS 3
-#define V2_MB_TYPE_VLC_BITS 7
-#define MV_VLC_BITS 9
-#define V2_MV_VLC_BITS 9
-#define TEX_VLC_BITS 9
-
-#define DEFAULT_INTER_INDEX 3
-
-static inline int msmpeg4v1_pred_dc(MpegEncContext * s, int n,
- int32_t **dc_val_ptr)
-{
- int i;
-
- if (n < 4) {
- i= 0;
- } else {
- i= n-3;
- }
-
- *dc_val_ptr= &s->last_dc[i];
- return s->last_dc[i];
-}
-
-/****************************************/
-/* decoding stuff */
-
-VLC ff_mb_non_intra_vlc[4];
-static VLC v2_dc_lum_vlc;
-static VLC v2_dc_chroma_vlc;
-static VLC v2_intra_cbpc_vlc;
-static VLC v2_mb_type_vlc;
-static VLC v2_mv_vlc;
-VLC ff_inter_intra_vlc;
-
-/* This is identical to h263 except that its range is multiplied by 2. */
-static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code)
-{
- int code, val, sign, shift;
-
- code = get_vlc2(&s->gb, v2_mv_vlc.table, V2_MV_VLC_BITS, 2);
- 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;
-
- if (code == 0)
- return pred;
- sign = get_bits1(&s->gb);
- shift = f_code - 1;
- val = code;
- if (shift) {
- val = (val - 1) << shift;
- val |= get_bits(&s->gb, shift);
- val++;
- }
- if (sign)
- val = -val;
-
- val += pred;
- if (val <= -64)
- val += 64;
- else if (val >= 64)
- val -= 64;
-
- return val;
-}
-
-static int msmpeg4v12_decode_mb(MpegEncContext *s, int16_t block[6][64])
-{
- int cbp, code, i;
- uint32_t * const mb_type_ptr = &s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride];
-
- if (s->pict_type == AV_PICTURE_TYPE_P) {
- if (s->use_skip_mb_code) {
- if (get_bits1(&s->gb)) {
- /* skip mb */
- s->mb_intra = 0;
- for(i=0;i<6;i++)
- s->block_last_index[i] = -1;
- s->mv_dir = MV_DIR_FORWARD;
- s->mv_type = MV_TYPE_16X16;
- s->mv[0][0][0] = 0;
- s->mv[0][0][1] = 0;
- s->mb_skipped = 1;
- *mb_type_ptr = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
- return 0;
- }
- }
-
- if(s->msmpeg4_version==2)
- code = get_vlc2(&s->gb, v2_mb_type_vlc.table, V2_MB_TYPE_VLC_BITS, 1);
- else
- code = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
- if(code<0 || code>7){
- av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", code, s->mb_x, s->mb_y);
- return -1;
- }
-
- s->mb_intra = code >>2;
-
- cbp = code & 0x3;
- } else {
- s->mb_intra = 1;
- if(s->msmpeg4_version==2)
- cbp= get_vlc2(&s->gb, v2_intra_cbpc_vlc.table, V2_INTRA_CBPC_VLC_BITS, 1);
- else
- cbp= get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 1);
- if(cbp<0 || cbp>3){
- av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y);
- return -1;
- }
- }
-
- if (!s->mb_intra) {
- int mx, my, cbpy;
-
- cbpy= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
- if(cbpy<0){
- av_log(s->avctx, AV_LOG_ERROR, "cbpy %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y);
- return -1;
- }
-
- cbp|= cbpy<<2;
- if(s->msmpeg4_version==1 || (cbp&3) != 3) cbp^= 0x3C;
-
- ff_h263_pred_motion(s, 0, 0, &mx, &my);
- mx= msmpeg4v2_decode_motion(s, mx, 1);
- my= msmpeg4v2_decode_motion(s, my, 1);
-
- s->mv_dir = MV_DIR_FORWARD;
- s->mv_type = MV_TYPE_16X16;
- s->mv[0][0][0] = mx;
- s->mv[0][0][1] = my;
- *mb_type_ptr = MB_TYPE_L0 | MB_TYPE_16x16;
- } else {
- if(s->msmpeg4_version==2){
- s->ac_pred = get_bits1(&s->gb);
- cbp|= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors
- } else{
- s->ac_pred = 0;
- cbp|= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1)<<2; //FIXME check errors
- if(s->pict_type==AV_PICTURE_TYPE_P) cbp^=0x3C;
- }
- *mb_type_ptr = MB_TYPE_INTRA;
- }
-
- s->bdsp.clear_blocks(s->block[0]);
- for (i = 0; i < 6; i++) {
- if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
- {
- av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
- return -1;
- }
- }
- return 0;
-}
-
-static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64])
-{
- int cbp, code, i;
- uint8_t *coded_val;
- uint32_t * const mb_type_ptr = &s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride];
-
- if (s->pict_type == AV_PICTURE_TYPE_P) {
- if (s->use_skip_mb_code) {
- if (get_bits1(&s->gb)) {
- /* skip mb */
- s->mb_intra = 0;
- for(i=0;i<6;i++)
- s->block_last_index[i] = -1;
- s->mv_dir = MV_DIR_FORWARD;
- s->mv_type = MV_TYPE_16X16;
- s->mv[0][0][0] = 0;
- s->mv[0][0][1] = 0;
- s->mb_skipped = 1;
- *mb_type_ptr = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
-
- return 0;
- }
- }
-
- code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[DEFAULT_INTER_INDEX].table, MB_NON_INTRA_VLC_BITS, 3);
- if (code < 0)
- return -1;
- //s->mb_intra = (code & 0x40) ? 0 : 1;
- s->mb_intra = (~code & 0x40) >> 6;
-
- cbp = code & 0x3f;
- } else {
- s->mb_intra = 1;
- code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
- if (code < 0)
- return -1;
- /* predict coded block pattern */
- cbp = 0;
- for(i=0;i<6;i++) {
- int val = ((code >> (5 - i)) & 1);
- if (i < 4) {
- int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_val);
- val = val ^ pred;
- *coded_val = val;
- }
- cbp |= val << (5 - i);
- }
- }
-
- if (!s->mb_intra) {
- int mx, my;
- if(s->per_mb_rl_table && cbp){
- s->rl_table_index = decode012(&s->gb);
- s->rl_chroma_table_index = s->rl_table_index;
- }
- ff_h263_pred_motion(s, 0, 0, &mx, &my);
- if (ff_msmpeg4_decode_motion(s, &mx, &my) < 0)
- return -1;
- s->mv_dir = MV_DIR_FORWARD;
- s->mv_type = MV_TYPE_16X16;
- s->mv[0][0][0] = mx;
- s->mv[0][0][1] = my;
- *mb_type_ptr = MB_TYPE_L0 | MB_TYPE_16x16;
- } else {
- ff_dlog(s, "I at %d %d %d %06X\n", s->mb_x, s->mb_y,
- ((cbp & 3) ? 1 : 0) +((cbp & 0x3C)? 2 : 0),
- show_bits(&s->gb, 24));
- s->ac_pred = get_bits1(&s->gb);
- *mb_type_ptr = MB_TYPE_INTRA;
- if(s->inter_intra_pred){
- s->h263_aic_dir= get_vlc2(&s->gb, ff_inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1);
- ff_dlog(s, "%d%d %d %d/",
- s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y);
- }
- if(s->per_mb_rl_table && cbp){
- s->rl_table_index = decode012(&s->gb);
- s->rl_chroma_table_index = s->rl_table_index;
- }
- }
-
- s->bdsp.clear_blocks(s->block[0]);
- for (i = 0; i < 6; i++) {
- if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
- {
- av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
- return -1;
- }
- }
-
- return 0;
-}
-
-/* init all vlc decoding tables */
-av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx)
-{
- MpegEncContext *s = avctx->priv_data;
- static volatile int done = 0;
- int i, ret;
- MVTable *mv;
-
- if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
- return ret;
-
- if (ff_h263_decode_init(avctx) < 0)
- return -1;
-
- ff_msmpeg4_common_init(s);
-
- if (!done) {
- for(i=0;i<NB_RL_TABLES;i++) {
- ff_rl_init(&ff_rl_table[i], ff_static_rl_table_store[i]);
- }
- INIT_VLC_RL(ff_rl_table[0], 642);
- INIT_VLC_RL(ff_rl_table[1], 1104);
- INIT_VLC_RL(ff_rl_table[2], 554);
- INIT_VLC_RL(ff_rl_table[3], 940);
- INIT_VLC_RL(ff_rl_table[4], 962);
- INIT_VLC_RL(ff_rl_table[5], 554);
-
- mv = &ff_mv_tables[0];
- INIT_VLC_STATIC(&mv->vlc, MV_VLC_BITS, mv->n + 1,
- mv->table_mv_bits, 1, 1,
- mv->table_mv_code, 2, 2, 3714);
- mv = &ff_mv_tables[1];
- INIT_VLC_STATIC(&mv->vlc, MV_VLC_BITS, mv->n + 1,
- mv->table_mv_bits, 1, 1,
- mv->table_mv_code, 2, 2, 2694);
-
- INIT_VLC_STATIC(&ff_msmp4_dc_luma_vlc[0], DC_VLC_BITS, 120,
- &ff_table0_dc_lum[0][1], 8, 4,
- &ff_table0_dc_lum[0][0], 8, 4, 1158);
- INIT_VLC_STATIC(&ff_msmp4_dc_chroma_vlc[0], DC_VLC_BITS, 120,
- &ff_table0_dc_chroma[0][1], 8, 4,
- &ff_table0_dc_chroma[0][0], 8, 4, 1118);
- INIT_VLC_STATIC(&ff_msmp4_dc_luma_vlc[1], DC_VLC_BITS, 120,
- &ff_table1_dc_lum[0][1], 8, 4,
- &ff_table1_dc_lum[0][0], 8, 4, 1476);
- INIT_VLC_STATIC(&ff_msmp4_dc_chroma_vlc[1], DC_VLC_BITS, 120,
- &ff_table1_dc_chroma[0][1], 8, 4,
- &ff_table1_dc_chroma[0][0], 8, 4, 1216);
-
- INIT_VLC_STATIC(&v2_dc_lum_vlc, DC_VLC_BITS, 512,
- &ff_v2_dc_lum_table[0][1], 8, 4,
- &ff_v2_dc_lum_table[0][0], 8, 4, 1472);
- INIT_VLC_STATIC(&v2_dc_chroma_vlc, DC_VLC_BITS, 512,
- &ff_v2_dc_chroma_table[0][1], 8, 4,
- &ff_v2_dc_chroma_table[0][0], 8, 4, 1506);
-
- INIT_VLC_STATIC(&v2_intra_cbpc_vlc, V2_INTRA_CBPC_VLC_BITS, 4,
- &ff_v2_intra_cbpc[0][1], 2, 1,
- &ff_v2_intra_cbpc[0][0], 2, 1, 8);
- INIT_VLC_STATIC(&v2_mb_type_vlc, V2_MB_TYPE_VLC_BITS, 8,
- &ff_v2_mb_type[0][1], 2, 1,
- &ff_v2_mb_type[0][0], 2, 1, 128);
- INIT_VLC_STATIC(&v2_mv_vlc, V2_MV_VLC_BITS, 33,
- &ff_mvtab[0][1], 2, 1,
- &ff_mvtab[0][0], 2, 1, 538);
-
- INIT_VLC_STATIC(&ff_mb_non_intra_vlc[0], MB_NON_INTRA_VLC_BITS, 128,
- &ff_wmv2_inter_table[0][0][1], 8, 4,
- &ff_wmv2_inter_table[0][0][0], 8, 4, 1636);
- INIT_VLC_STATIC(&ff_mb_non_intra_vlc[1], MB_NON_INTRA_VLC_BITS, 128,
- &ff_wmv2_inter_table[1][0][1], 8, 4,
- &ff_wmv2_inter_table[1][0][0], 8, 4, 2648);
- INIT_VLC_STATIC(&ff_mb_non_intra_vlc[2], MB_NON_INTRA_VLC_BITS, 128,
- &ff_wmv2_inter_table[2][0][1], 8, 4,
- &ff_wmv2_inter_table[2][0][0], 8, 4, 1532);
- INIT_VLC_STATIC(&ff_mb_non_intra_vlc[3], MB_NON_INTRA_VLC_BITS, 128,
- &ff_wmv2_inter_table[3][0][1], 8, 4,
- &ff_wmv2_inter_table[3][0][0], 8, 4, 2488);
-
- INIT_VLC_STATIC(&ff_msmp4_mb_i_vlc, MB_INTRA_VLC_BITS, 64,
- &ff_msmp4_mb_i_table[0][1], 4, 2,
- &ff_msmp4_mb_i_table[0][0], 4, 2, 536);
-
- INIT_VLC_STATIC(&ff_inter_intra_vlc, INTER_INTRA_VLC_BITS, 4,
- &ff_table_inter_intra[0][1], 2, 1,
- &ff_table_inter_intra[0][0], 2, 1, 8);
- done = 1;
- }
-
- switch(s->msmpeg4_version){
- case 1:
- case 2:
- s->decode_mb= msmpeg4v12_decode_mb;
- break;
- case 3:
- case 4:
- s->decode_mb= msmpeg4v34_decode_mb;
- break;
- case 5:
- if (CONFIG_WMV2_DECODER)
- s->decode_mb= ff_wmv2_decode_mb;
- case 6:
- //FIXME + TODO VC1 decode mb
- break;
- }
-
- s->slice_height= s->mb_height; //to avoid 1/0 if the first frame is not a keyframe
-
- return 0;
-}
-
-int ff_msmpeg4_decode_picture_header(MpegEncContext * s)
-{
- int code;
-
- if(s->msmpeg4_version==1){
- int start_code = get_bits_long(&s->gb, 32);
- if(start_code!=0x00000100){
- av_log(s->avctx, AV_LOG_ERROR, "invalid startcode\n");
- return -1;
- }
-
- skip_bits(&s->gb, 5); // frame number */
- }
-
- s->pict_type = get_bits(&s->gb, 2) + 1;
- if (s->pict_type != AV_PICTURE_TYPE_I &&
- s->pict_type != AV_PICTURE_TYPE_P){
- av_log(s->avctx, AV_LOG_ERROR, "invalid picture type\n");
- return -1;
- }
-#if 0
-{
- static int had_i=0;
- if(s->pict_type == AV_PICTURE_TYPE_I) had_i=1;
- if(!had_i) return -1;
-}
-#endif
- s->chroma_qscale= s->qscale = get_bits(&s->gb, 5);
- if(s->qscale==0){
- av_log(s->avctx, AV_LOG_ERROR, "invalid qscale\n");
- return -1;
- }
-
- if (s->pict_type == AV_PICTURE_TYPE_I) {
- code = get_bits(&s->gb, 5);
- if(s->msmpeg4_version==1){
- if(code==0 || code>s->mb_height){
- av_log(s->avctx, AV_LOG_ERROR, "invalid slice height %d\n", code);
- return -1;
- }
-
- s->slice_height = code;
- }else{
- /* 0x17: one slice, 0x18: two slices, ... */
- if (code < 0x17){
- av_log(s->avctx, AV_LOG_ERROR, "error, slice code was %X\n", code);
- return -1;
- }
-
- s->slice_height = s->mb_height / (code - 0x16);
- }
-
- switch(s->msmpeg4_version){
- case 1:
- case 2:
- s->rl_chroma_table_index = 2;
- s->rl_table_index = 2;
-
- s->dc_table_index = 0; //not used
- break;
- case 3:
- s->rl_chroma_table_index = decode012(&s->gb);
- s->rl_table_index = decode012(&s->gb);
-
- s->dc_table_index = get_bits1(&s->gb);
- break;
- case 4:
- ff_msmpeg4_decode_ext_header(s, (2+5+5+17+7)/8);
-
- if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb);
- else s->per_mb_rl_table= 0;
-
- if(!s->per_mb_rl_table){
- s->rl_chroma_table_index = decode012(&s->gb);
- s->rl_table_index = decode012(&s->gb);
- }
-
- s->dc_table_index = get_bits1(&s->gb);
- s->inter_intra_pred= 0;
- break;
- }
- s->no_rounding = 1;
- if(s->avctx->debug&FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d slice:%d \n",
- s->qscale,
- s->rl_chroma_table_index,
- s->rl_table_index,
- s->dc_table_index,
- s->per_mb_rl_table,
- s->slice_height);
- } else {
- switch(s->msmpeg4_version){
- case 1:
- case 2:
- if(s->msmpeg4_version==1)
- s->use_skip_mb_code = 1;
- else
- s->use_skip_mb_code = get_bits1(&s->gb);
- s->rl_table_index = 2;
- s->rl_chroma_table_index = s->rl_table_index;
- s->dc_table_index = 0; //not used
- s->mv_table_index = 0;
- break;
- case 3:
- s->use_skip_mb_code = get_bits1(&s->gb);
- s->rl_table_index = decode012(&s->gb);
- s->rl_chroma_table_index = s->rl_table_index;
-
- s->dc_table_index = get_bits1(&s->gb);
-
- s->mv_table_index = get_bits1(&s->gb);
- break;
- case 4:
- s->use_skip_mb_code = get_bits1(&s->gb);
-
- if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb);
- else s->per_mb_rl_table= 0;
-
- if(!s->per_mb_rl_table){
- s->rl_table_index = decode012(&s->gb);
- s->rl_chroma_table_index = s->rl_table_index;
- }
-
- s->dc_table_index = get_bits1(&s->gb);
-
- s->mv_table_index = get_bits1(&s->gb);
- s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE);
- break;
- }
-
- if(s->avctx->debug&FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_DEBUG, "skip:%d rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d \n",
- s->use_skip_mb_code,
- s->rl_table_index,
- s->rl_chroma_table_index,
- s->dc_table_index,
- s->mv_table_index,
- s->per_mb_rl_table,
- s->qscale);
-
- if(s->flipflop_rounding){
- s->no_rounding ^= 1;
- }else{
- s->no_rounding = 0;
- }
- }
- ff_dlog(s->avctx, "%d %"PRId64" %d %d %d\n", s->pict_type, s->bit_rate,
- s->inter_intra_pred, s->width, s->height);
-
- s->esc3_level_length= 0;
- s->esc3_run_length= 0;
-
- return 0;
-}
-
-int ff_msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size)
-{
- int left= buf_size*8 - get_bits_count(&s->gb);
- int length= s->msmpeg4_version>=3 ? 17 : 16;
- /* the alt_bitstream reader could read over the end so we need to check it */
- if(left>=length && left<length+8)
- {
- skip_bits(&s->gb, 5); /* fps */
- s->bit_rate= get_bits(&s->gb, 11)*1024;
- if(s->msmpeg4_version>=3)
- s->flipflop_rounding= get_bits1(&s->gb);
- else
- s->flipflop_rounding= 0;
- }
- else if(left<length+8)
- {
- s->flipflop_rounding= 0;
- if(s->msmpeg4_version != 2)
- av_log(s->avctx, AV_LOG_ERROR, "ext header missing, %d left\n", left);
- }
- else
- {
- av_log(s->avctx, AV_LOG_ERROR, "I frame too long, ignoring ext header\n");
- }
-
- return 0;
-}
-
-static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
-{
- int level, pred;
-
- if(s->msmpeg4_version<=2){
- if (n < 4) {
- level = get_vlc2(&s->gb, v2_dc_lum_vlc.table, DC_VLC_BITS, 3);
- } else {
- level = get_vlc2(&s->gb, v2_dc_chroma_vlc.table, DC_VLC_BITS, 3);
- }
- if (level < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n");
- *dir_ptr = 0;
- return -1;
- }
- level-=256;
- }else{ //FIXME optimize use unified tables & index
- if (n < 4) {
- level = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
- } else {
- level = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
- }
- if (level < 0){
- av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n");
- *dir_ptr = 0;
- return -1;
- }
-
- if (level == DC_MAX) {
- level = get_bits(&s->gb, 8);
- if (get_bits1(&s->gb))
- level = -level;
- } else if (level != 0) {
- if (get_bits1(&s->gb))
- level = -level;
- }
- }
-
- if(s->msmpeg4_version==1){
- int32_t *dc_val;
- pred = msmpeg4v1_pred_dc(s, n, &dc_val);
- level += pred;
-
- /* update predictor */
- *dc_val= level;
- }else{
- int16_t *dc_val;
- pred = ff_msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
- level += pred;
-
- /* update predictor */
- if (n < 4) {
- *dc_val = level * s->y_dc_scale;
- } else {
- *dc_val = level * s->c_dc_scale;
- }
- }
-
- return level;
-}
-
-//#define ERROR_DETAILS
-int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block,
- int n, int coded, const uint8_t *scan_table)
-{
- int level, i, last, run, run_diff;
- int av_uninit(dc_pred_dir);
- RLTable *rl;
- RL_VLC_ELEM *rl_vlc;
- int qmul, qadd;
-
- if (s->mb_intra) {
- qmul=1;
- qadd=0;
-
- /* DC coef */
- level = msmpeg4_decode_dc(s, n, &dc_pred_dir);
-
- if (level < 0){
- av_log(s->avctx, AV_LOG_ERROR, "dc overflow- block: %d qscale: %d//\n", n, s->qscale);
- if(s->inter_intra_pred) level=0;
- }
- if (n < 4) {
- rl = &ff_rl_table[s->rl_table_index];
- if(level > 256*s->y_dc_scale){
- av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ L qscale: %d//\n", s->qscale);
- if(!s->inter_intra_pred) return -1;
- }
- } else {
- rl = &ff_rl_table[3 + s->rl_chroma_table_index];
- if(level > 256*s->c_dc_scale){
- av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ C qscale: %d//\n", s->qscale);
- if(!s->inter_intra_pred) return -1;
- }
- }
- block[0] = level;
-
- run_diff = s->msmpeg4_version >= 4;
- i = 0;
- if (!coded) {
- goto not_coded;
- }
- if (s->ac_pred) {
- if (dc_pred_dir == 0)
- scan_table = s->intra_v_scantable.permutated; /* left */
- else
- scan_table = s->intra_h_scantable.permutated; /* top */
- } else {
- scan_table = s->intra_scantable.permutated;
- }
- rl_vlc= rl->rl_vlc[0];
- } else {
- qmul = s->qscale << 1;
- qadd = (s->qscale - 1) | 1;
- i = -1;
- rl = &ff_rl_table[3 + s->rl_table_index];
-
- if(s->msmpeg4_version==2)
- run_diff = 0;
- else
- run_diff = 1;
-
- if (!coded) {
- s->block_last_index[n] = i;
- return 0;
- }
- if(!scan_table)
- scan_table = s->inter_scantable.permutated;
- rl_vlc= rl->rl_vlc[s->qscale];
- }
- {
- OPEN_READER(re, &s->gb);
- for(;;) {
- UPDATE_CACHE(re, &s->gb);
- GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0);
- if (level==0) {
- int cache;
- cache= GET_CACHE(re, &s->gb);
- /* escape */
- if (s->msmpeg4_version==1 || (cache&0x80000000)==0) {
- if (s->msmpeg4_version==1 || (cache&0x40000000)==0) {
- /* third escape */
- if(s->msmpeg4_version!=1) LAST_SKIP_BITS(re, &s->gb, 2);
- UPDATE_CACHE(re, &s->gb);
- if(s->msmpeg4_version<=3){
- last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);
- run= SHOW_UBITS(re, &s->gb, 6); SKIP_CACHE(re, &s->gb, 6);
- level= SHOW_SBITS(re, &s->gb, 8);
- SKIP_COUNTER(re, &s->gb, 1+6+8);
- }else{
- int sign;
- last= SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1);
- if(!s->esc3_level_length){
- int ll;
- ff_dlog(s->avctx, "ESC-3 %X at %d %d\n",
- show_bits(&s->gb, 24), s->mb_x, s->mb_y);
- if(s->qscale<8){
- ll= SHOW_UBITS(re, &s->gb, 3); SKIP_BITS(re, &s->gb, 3);
- if(ll==0){
- ll= 8+SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1);
- }
- }else{
- ll=2;
- while(ll<8 && SHOW_UBITS(re, &s->gb, 1)==0){
- ll++;
- SKIP_BITS(re, &s->gb, 1);
- }
- if(ll<8) SKIP_BITS(re, &s->gb, 1);
- }
-
- s->esc3_level_length= ll;
- s->esc3_run_length= SHOW_UBITS(re, &s->gb, 2) + 3; SKIP_BITS(re, &s->gb, 2);
- UPDATE_CACHE(re, &s->gb);
- }
- run= SHOW_UBITS(re, &s->gb, s->esc3_run_length);
- SKIP_BITS(re, &s->gb, s->esc3_run_length);
-
- sign= SHOW_UBITS(re, &s->gb, 1);
- SKIP_BITS(re, &s->gb, 1);
-
- level= SHOW_UBITS(re, &s->gb, s->esc3_level_length);
- SKIP_BITS(re, &s->gb, s->esc3_level_length);
- if(sign) level= -level;
- }
-
-#if 0 // waste of time / this will detect very few errors
- {
- const int abs_level= FFABS(level);
- const int run1= run - rl->max_run[last][abs_level] - run_diff;
- if(abs_level<=MAX_LEVEL && run<=MAX_RUN){
- if(abs_level <= rl->max_level[last][run]){
- av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n");
- return DECODING_AC_LOST;
- }
- if(abs_level <= rl->max_level[last][run]*2){
- av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n");
- return DECODING_AC_LOST;
- }
- if(run1>=0 && abs_level <= rl->max_level[last][run1]){
- av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 2 encoding possible\n");
- return DECODING_AC_LOST;
- }
- }
- }
-#endif
- //level = level * qmul + (level>0) * qadd - (level<=0) * qadd ;
- if (level>0) level= level * qmul + qadd;
- else level= level * qmul - qadd;
-#if 0 // waste of time too :(
- if(level>2048 || level<-2048){
- av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc\n");
- return DECODING_AC_LOST;
- }
-#endif
- i+= run + 1;
- if(last) i+=192;
-#ifdef ERROR_DETAILS
- if(run==66)
- av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC3 level=%d\n", level);
- else if((i>62 && i<192) || i>192+63)
- av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC3 i=%d run=%d level=%d\n", i, run, level);
-#endif
- } else {
- /* second escape */
- SKIP_BITS(re, &s->gb, 2);
- GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
- i+= run + rl->max_run[run>>7][level/qmul] + run_diff; //FIXME opt indexing
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
-#ifdef ERROR_DETAILS
- if(run==66)
- av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC2 level=%d\n", level);
- else if((i>62 && i<192) || i>192+63)
- av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC2 i=%d run=%d level=%d\n", i, run, level);
-#endif
- }
- } else {
- /* first escape */
- SKIP_BITS(re, &s->gb, 1);
- GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
- i+= run;
- level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
-#ifdef ERROR_DETAILS
- if(run==66)
- av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC1 level=%d\n", level);
- else if((i>62 && i<192) || i>192+63)
- av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC1 i=%d run=%d level=%d\n", i, run, level);
-#endif
- }
- } else {
- i+= run;
- level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
- LAST_SKIP_BITS(re, &s->gb, 1);
-#ifdef ERROR_DETAILS
- if(run==66)
- av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code level=%d\n", level);
- else if((i>62 && i<192) || i>192+63)
- av_log(s->avctx, AV_LOG_ERROR, "run overflow i=%d run=%d level=%d\n", i, run, level);
-#endif
- }
- if (i > 62){
- i-= 192;
- if(i&(~63)){
- const int left= get_bits_left(&s->gb);
- if (((i + 192 == 64 && level / qmul == -1) ||
- !(s->avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))) &&
- left >= 0) {
- av_log(s->avctx, AV_LOG_ERROR, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y);
- i = 63;
- break;
- }else{
- av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- }
-
- block[scan_table[i]] = level;
- break;
- }
-
- block[scan_table[i]] = level;
- }
- CLOSE_READER(re, &s->gb);
- }
- not_coded:
- if (s->mb_intra) {
- ff_mpeg4_pred_ac(s, block, n, dc_pred_dir);
- if (s->ac_pred) {
- i = 63; /* XXX: not optimal */
- }
- }
- if(s->msmpeg4_version>=4 && i>0) i=63; //FIXME/XXX optimize
- s->block_last_index[n] = i;
-
- return 0;
-}
-
-int ff_msmpeg4_decode_motion(MpegEncContext * s,
- int *mx_ptr, int *my_ptr)
-{
- MVTable *mv;
- int code, mx, my;
-
- mv = &ff_mv_tables[s->mv_table_index];
-
- code = get_vlc2(&s->gb, mv->vlc.table, MV_VLC_BITS, 2);
- if (code < 0){
- av_log(s->avctx, AV_LOG_ERROR, "illegal MV code at %d %d\n", s->mb_x, s->mb_y);
- return -1;
- }
- if (code == mv->n) {
- mx = get_bits(&s->gb, 6);
- my = get_bits(&s->gb, 6);
- } else {
- mx = mv->table_mvx[code];
- my = mv->table_mvy[code];
- }
-
- mx += *mx_ptr - 32;
- my += *my_ptr - 32;
- /* WARNING : they do not do exactly modulo encoding */
- if (mx <= -64)
- mx += 64;
- else if (mx >= 64)
- mx -= 64;
-
- if (my <= -64)
- my += 64;
- else if (my >= 64)
- my -= 64;
- *mx_ptr = mx;
- *my_ptr = my;
- return 0;
-}
-
-AVCodec ff_msmpeg4v1_decoder = {
- .name = "msmpeg4v1",
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MSMPEG4V1,
- .priv_data_size = sizeof(MpegEncContext),
- .init = ff_msmpeg4_decode_init,
- .close = ff_h263_decode_end,
- .decode = ff_h263_decode_frame,
- .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
- .max_lowres = 3,
- .pix_fmts = (const enum AVPixelFormat[]) {
- AV_PIX_FMT_YUV420P,
- AV_PIX_FMT_NONE
- },
-};
-
-AVCodec ff_msmpeg4v2_decoder = {
- .name = "msmpeg4v2",
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MSMPEG4V2,
- .priv_data_size = sizeof(MpegEncContext),
- .init = ff_msmpeg4_decode_init,
- .close = ff_h263_decode_end,
- .decode = ff_h263_decode_frame,
- .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
- .max_lowres = 3,
- .pix_fmts = (const enum AVPixelFormat[]) {
- AV_PIX_FMT_YUV420P,
- AV_PIX_FMT_NONE
- },
-};
-
-AVCodec ff_msmpeg4v3_decoder = {
- .name = "msmpeg4",
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MSMPEG4V3,
- .priv_data_size = sizeof(MpegEncContext),
- .init = ff_msmpeg4_decode_init,
- .close = ff_h263_decode_end,
- .decode = ff_h263_decode_frame,
- .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
- .max_lowres = 3,
- .pix_fmts = (const enum AVPixelFormat[]) {
- AV_PIX_FMT_YUV420P,
- AV_PIX_FMT_NONE
- },
-};
-
-AVCodec ff_wmv1_decoder = {
- .name = "wmv1",
- .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 7"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_WMV1,
- .priv_data_size = sizeof(MpegEncContext),
- .init = ff_msmpeg4_decode_init,
- .close = ff_h263_decode_end,
- .decode = ff_h263_decode_frame,
- .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
- .max_lowres = 3,
- .pix_fmts = (const enum AVPixelFormat[]) {
- AV_PIX_FMT_YUV420P,
- AV_PIX_FMT_NONE
- },
-};
diff --git a/ffmpeg-2-8-11/libavcodec/mss3.c b/ffmpeg-2-8-11/libavcodec/mss3.c
deleted file mode 100644
index 0194196..0000000
--- a/ffmpeg-2-8-11/libavcodec/mss3.c
+++ /dev/null
@@ -1,873 +0,0 @@
-/*
- * Microsoft Screen 3 (aka Microsoft ATC Screen) decoder
- * Copyright (c) 2012 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
- */
-
-/**
- * @file
- * Microsoft Screen 3 (aka Microsoft ATC Screen) decoder
- */
-
-#include "avcodec.h"
-#include "bytestream.h"
-#include "internal.h"
-#include "mathops.h"
-#include "mss34dsp.h"
-
-#define HEADER_SIZE 27
-
-#define MODEL2_SCALE 13
-#define MODEL_SCALE 15
-#define MODEL256_SEC_SCALE 9
-
-typedef struct Model2 {
- int upd_val, till_rescale;
- unsigned zero_freq, zero_weight;
- unsigned total_freq, total_weight;
-} Model2;
-
-typedef struct Model {
- int weights[16], freqs[16];
- int num_syms;
- int tot_weight;
- int upd_val, max_upd_val, till_rescale;
-} Model;
-
-typedef struct Model256 {
- int weights[256], freqs[256];
- int tot_weight;
- int secondary[68];
- int sec_size;
- int upd_val, max_upd_val, till_rescale;
-} Model256;
-
-#define RAC_BOTTOM 0x01000000
-typedef struct RangeCoder {
- const uint8_t *src, *src_end;
-
- uint32_t range, low;
- int got_error;
-} RangeCoder;
-
-enum BlockType {
- FILL_BLOCK = 0,
- IMAGE_BLOCK,
- DCT_BLOCK,
- HAAR_BLOCK,
- SKIP_BLOCK
-};
-
-typedef struct BlockTypeContext {
- int last_type;
- Model bt_model[5];
-} BlockTypeContext;
-
-typedef struct FillBlockCoder {
- int fill_val;
- Model coef_model;
-} FillBlockCoder;
-
-typedef struct ImageBlockCoder {
- Model256 esc_model, vec_entry_model;
- Model vec_size_model;
- Model vq_model[125];
-} ImageBlockCoder;
-
-typedef struct DCTBlockCoder {
- int *prev_dc;
- int prev_dc_stride;
- int prev_dc_height;
- int quality;
- uint16_t qmat[64];
- Model dc_model;
- Model2 sign_model;
- Model256 ac_model;
-} DCTBlockCoder;
-
-typedef struct HaarBlockCoder {
- int quality, scale;
- Model256 coef_model;
- Model coef_hi_model;
-} HaarBlockCoder;
-
-typedef struct MSS3Context {
- AVCodecContext *avctx;
- AVFrame *pic;
-
- int got_error;
- RangeCoder coder;
- BlockTypeContext btype[3];
- FillBlockCoder fill_coder[3];
- ImageBlockCoder image_coder[3];
- DCTBlockCoder dct_coder[3];
- HaarBlockCoder haar_coder[3];
-
- int dctblock[64];
- int hblock[16 * 16];
-} MSS3Context;
-
-
-static void model2_reset(Model2 *m)
-{
- m->zero_weight = 1;
- m->total_weight = 2;
- m->zero_freq = 0x1000;
- m->total_freq = 0x2000;
- m->upd_val = 4;
- m->till_rescale = 4;
-}
-
-static void model2_update(Model2 *m, int bit)
-{
- unsigned scale;
-
- if (!bit)
- m->zero_weight++;
- m->till_rescale--;
- if (m->till_rescale)
- return;
-
- m->total_weight += m->upd_val;
- if (m->total_weight > 0x2000) {
- m->total_weight = (m->total_weight + 1) >> 1;
- m->zero_weight = (m->zero_weight + 1) >> 1;
- if (m->total_weight == m->zero_weight)
- m->total_weight = m->zero_weight + 1;
- }
- m->upd_val = m->upd_val * 5 >> 2;
- if (m->upd_val > 64)
- m->upd_val = 64;
- scale = 0x80000000u / m->total_weight;
- m->zero_freq = m->zero_weight * scale >> 18;
- m->total_freq = m->total_weight * scale >> 18;
- m->till_rescale = m->upd_val;
-}
-
-static void model_update(Model *m, int val)
-{
- int i, sum = 0;
- unsigned scale;
-
- m->weights[val]++;
- m->till_rescale--;
- if (m->till_rescale)
- return;
- m->tot_weight += m->upd_val;
-
- if (m->tot_weight > 0x8000) {
- m->tot_weight = 0;
- for (i = 0; i < m->num_syms; i++) {
- m->weights[i] = (m->weights[i] + 1) >> 1;
- m->tot_weight += m->weights[i];
- }
- }
- scale = 0x80000000u / m->tot_weight;
- for (i = 0; i < m->num_syms; i++) {
- m->freqs[i] = sum * scale >> 16;
- sum += m->weights[i];
- }
-
- m->upd_val = m->upd_val * 5 >> 2;
- if (m->upd_val > m->max_upd_val)
- m->upd_val = m->max_upd_val;
- m->till_rescale = m->upd_val;
-}
-
-static void model_reset(Model *m)
-{
- int i;
-
- m->tot_weight = 0;
- for (i = 0; i < m->num_syms - 1; i++)
- m->weights[i] = 1;
- m->weights[m->num_syms - 1] = 0;
-
- m->upd_val = m->num_syms;
- m->till_rescale = 1;
- model_update(m, m->num_syms - 1);
- m->till_rescale =
- m->upd_val = (m->num_syms + 6) >> 1;
-}
-
-static av_cold void model_init(Model *m, int num_syms)
-{
- m->num_syms = num_syms;
- m->max_upd_val = 8 * num_syms + 48;
-
- model_reset(m);
-}
-
-static void model256_update(Model256 *m, int val)
-{
- int i, sum = 0;
- unsigned scale;
- int send, sidx = 1;
-
- m->weights[val]++;
- m->till_rescale--;
- if (m->till_rescale)
- return;
- m->tot_weight += m->upd_val;
-
- if (m->tot_weight > 0x8000) {
- m->tot_weight = 0;
- for (i = 0; i < 256; i++) {
- m->weights[i] = (m->weights[i] + 1) >> 1;
- m->tot_weight += m->weights[i];
- }
- }
- scale = 0x80000000u / m->tot_weight;
- m->secondary[0] = 0;
- for (i = 0; i < 256; i++) {
- m->freqs[i] = sum * scale >> 16;
- sum += m->weights[i];
- send = m->freqs[i] >> MODEL256_SEC_SCALE;
- while (sidx <= send)
- m->secondary[sidx++] = i - 1;
- }
- while (sidx < m->sec_size)
- m->secondary[sidx++] = 255;
-
- m->upd_val = m->upd_val * 5 >> 2;
- if (m->upd_val > m->max_upd_val)
- m->upd_val = m->max_upd_val;
- m->till_rescale = m->upd_val;
-}
-
-static void model256_reset(Model256 *m)
-{
- int i;
-
- for (i = 0; i < 255; i++)
- m->weights[i] = 1;
- m->weights[255] = 0;
-
- m->tot_weight = 0;
- m->upd_val = 256;
- m->till_rescale = 1;
- model256_update(m, 255);
- m->till_rescale =
- m->upd_val = (256 + 6) >> 1;
-}
-
-static av_cold void model256_init(Model256 *m)
-{
- m->max_upd_val = 8 * 256 + 48;
- m->sec_size = (1 << 6) + 2;
-
- model256_reset(m);
-}
-
-static void rac_init(RangeCoder *c, const uint8_t *src, int size)
-{
- int i;
-
- c->src = src;
- c->src_end = src + size;
- c->low = 0;
- for (i = 0; i < FFMIN(size, 4); i++)
- c->low = (c->low << 8) | *c->src++;
- c->range = 0xFFFFFFFF;
- c->got_error = 0;
-}
-
-static void rac_normalise(RangeCoder *c)
-{
- for (;;) {
- c->range <<= 8;
- c->low <<= 8;
- if (c->src < c->src_end) {
- c->low |= *c->src++;
- } else if (!c->low) {
- c->got_error = 1;
- c->low = 1;
- }
- if (c->range >= RAC_BOTTOM)
- return;
- }
-}
-
-static int rac_get_bit(RangeCoder *c)
-{
- int bit;
-
- c->range >>= 1;
-
- bit = (c->range <= c->low);
- if (bit)
- c->low -= c->range;
-
- if (c->range < RAC_BOTTOM)
- rac_normalise(c);
-
- return bit;
-}
-
-static int rac_get_bits(RangeCoder *c, int nbits)
-{
- int val;
-
- c->range >>= nbits;
- val = c->low / c->range;
- c->low -= c->range * val;
-
- if (c->range < RAC_BOTTOM)
- rac_normalise(c);
-
- return val;
-}
-
-static int rac_get_model2_sym(RangeCoder *c, Model2 *m)
-{
- int bit, helper;
-
- helper = m->zero_freq * (c->range >> MODEL2_SCALE);
- bit = (c->low >= helper);
- if (bit) {
- c->low -= helper;
- c->range -= helper;
- } else {
- c->range = helper;
- }
-
- if (c->range < RAC_BOTTOM)
- rac_normalise(c);
-
- model2_update(m, bit);
-
- return bit;
-}
-
-static int rac_get_model_sym(RangeCoder *c, Model *m)
-{
- int prob, prob2, helper, val;
- int end, end2;
-
- prob = 0;
- prob2 = c->range;
- c->range >>= MODEL_SCALE;
- val = 0;
- end = m->num_syms >> 1;
- end2 = m->num_syms;
- do {
- helper = m->freqs[end] * c->range;
- if (helper <= c->low) {
- val = end;
- prob = helper;
- } else {
- end2 = end;
- prob2 = helper;
- }
- end = (end2 + val) >> 1;
- } while (end != val);
- c->low -= prob;
- c->range = prob2 - prob;
- if (c->range < RAC_BOTTOM)
- rac_normalise(c);
-
- model_update(m, val);
-
- return val;
-}
-
-static int rac_get_model256_sym(RangeCoder *c, Model256 *m)
-{
- int prob, prob2, helper, val;
- int start, end;
- int ssym;
-
- prob2 = c->range;
- c->range >>= MODEL_SCALE;
-
- helper = c->low / c->range;
- ssym = helper >> MODEL256_SEC_SCALE;
- val = m->secondary[ssym];
-
- end = start = m->secondary[ssym + 1] + 1;
- while (end > val + 1) {
- ssym = (end + val) >> 1;
- if (m->freqs[ssym] <= helper) {
- end = start;
- val = ssym;
- } else {
- end = (end + val) >> 1;
- start = ssym;
- }
- }
- prob = m->freqs[val] * c->range;
- if (val != 255)
- prob2 = m->freqs[val + 1] * c->range;
-
- c->low -= prob;
- c->range = prob2 - prob;
- if (c->range < RAC_BOTTOM)
- rac_normalise(c);
-
- model256_update(m, val);
-
- return val;
-}
-
-static int decode_block_type(RangeCoder *c, BlockTypeContext *bt)
-{
- bt->last_type = rac_get_model_sym(c, &bt->bt_model[bt->last_type]);
-
- return bt->last_type;
-}
-
-static int decode_coeff(RangeCoder *c, Model *m)
-{
- int val, sign;
-
- val = rac_get_model_sym(c, m);
- if (val) {
- sign = rac_get_bit(c);
- if (val > 1) {
- val--;
- val = (1 << val) + rac_get_bits(c, val);
- }
- if (!sign)
- val = -val;
- }
-
- return val;
-}
-
-static void decode_fill_block(RangeCoder *c, FillBlockCoder *fc,
- uint8_t *dst, int stride, int block_size)
-{
- int i;
-
- fc->fill_val += decode_coeff(c, &fc->coef_model);
-
- for (i = 0; i < block_size; i++, dst += stride)
- memset(dst, fc->fill_val, block_size);
-}
-
-static void decode_image_block(RangeCoder *c, ImageBlockCoder *ic,
- uint8_t *dst, int stride, int block_size)
-{
- int i, j;
- int vec_size;
- int vec[4];
- int prev_line[16];
- int A, B, C;
-
- vec_size = rac_get_model_sym(c, &ic->vec_size_model) + 2;
- for (i = 0; i < vec_size; i++)
- vec[i] = rac_get_model256_sym(c, &ic->vec_entry_model);
- for (; i < 4; i++)
- vec[i] = 0;
- memset(prev_line, 0, sizeof(prev_line));
-
- for (j = 0; j < block_size; j++) {
- A = 0;
- B = 0;
- for (i = 0; i < block_size; i++) {
- C = B;
- B = prev_line[i];
- A = rac_get_model_sym(c, &ic->vq_model[A + B * 5 + C * 25]);
-
- prev_line[i] = A;
- if (A < 4)
- dst[i] = vec[A];
- else
- dst[i] = rac_get_model256_sym(c, &ic->esc_model);
- }
- dst += stride;
- }
-}
-
-static int decode_dct(RangeCoder *c, DCTBlockCoder *bc, int *block,
- int bx, int by)
-{
- int skip, val, sign, pos = 1, zz_pos, dc;
- int blk_pos = bx + by * bc->prev_dc_stride;
-
- memset(block, 0, sizeof(*block) * 64);
-
- dc = decode_coeff(c, &bc->dc_model);
- if (by) {
- if (bx) {
- int l, tl, t;
-
- l = bc->prev_dc[blk_pos - 1];
- tl = bc->prev_dc[blk_pos - 1 - bc->prev_dc_stride];
- t = bc->prev_dc[blk_pos - bc->prev_dc_stride];
-
- if (FFABS(t - tl) <= FFABS(l - tl))
- dc += l;
- else
- dc += t;
- } else {
- dc += bc->prev_dc[blk_pos - bc->prev_dc_stride];
- }
- } else if (bx) {
- dc += bc->prev_dc[bx - 1];
- }
- bc->prev_dc[blk_pos] = dc;
- block[0] = dc * bc->qmat[0];
-
- while (pos < 64) {
- val = rac_get_model256_sym(c, &bc->ac_model);
- if (!val)
- return 0;
- if (val == 0xF0) {
- pos += 16;
- continue;
- }
- skip = val >> 4;
- val = val & 0xF;
- if (!val)
- return -1;
- pos += skip;
- if (pos >= 64)
- return -1;
-
- sign = rac_get_model2_sym(c, &bc->sign_model);
- if (val > 1) {
- val--;
- val = (1 << val) + rac_get_bits(c, val);
- }
- if (!sign)
- val = -val;
-
- zz_pos = ff_zigzag_direct[pos];
- block[zz_pos] = val * bc->qmat[zz_pos];
- pos++;
- }
-
- return pos == 64 ? 0 : -1;
-}
-
-static void decode_dct_block(RangeCoder *c, DCTBlockCoder *bc,
- uint8_t *dst, int stride, int block_size,
- int *block, int mb_x, int mb_y)
-{
- int i, j;
- int bx, by;
- int nblocks = block_size >> 3;
-
- bx = mb_x * nblocks;
- by = mb_y * nblocks;
-
- for (j = 0; j < nblocks; j++) {
- for (i = 0; i < nblocks; i++) {
- if (decode_dct(c, bc, block, bx + i, by + j)) {
- c->got_error = 1;
- return;
- }
- ff_mss34_dct_put(dst + i * 8, stride, block);
- }
- dst += 8 * stride;
- }
-}
-
-static void decode_haar_block(RangeCoder *c, HaarBlockCoder *hc,
- uint8_t *dst, int stride, int block_size,
- int *block)
-{
- const int hsize = block_size >> 1;
- int A, B, C, D, t1, t2, t3, t4;
- int i, j;
-
- for (j = 0; j < block_size; j++) {
- for (i = 0; i < block_size; i++) {
- if (i < hsize && j < hsize)
- block[i] = rac_get_model256_sym(c, &hc->coef_model);
- else
- block[i] = decode_coeff(c, &hc->coef_hi_model);
- block[i] *= hc->scale;
- }
- block += block_size;
- }
- block -= block_size * block_size;
-
- for (j = 0; j < hsize; j++) {
- for (i = 0; i < hsize; i++) {
- A = block[i];
- B = block[i + hsize];
- C = block[i + hsize * block_size];
- D = block[i + hsize * block_size + hsize];
-
- t1 = A - B;
- t2 = C - D;
- t3 = A + B;
- t4 = C + D;
- dst[i * 2] = av_clip_uint8(t1 - t2);
- dst[i * 2 + stride] = av_clip_uint8(t1 + t2);
- dst[i * 2 + 1] = av_clip_uint8(t3 - t4);
- dst[i * 2 + 1 + stride] = av_clip_uint8(t3 + t4);
- }
- block += block_size;
- dst += stride * 2;
- }
-}
-
-static void reset_coders(MSS3Context *ctx, int quality)
-{
- int i, j;
-
- for (i = 0; i < 3; i++) {
- ctx->btype[i].last_type = SKIP_BLOCK;
- for (j = 0; j < 5; j++)
- model_reset(&ctx->btype[i].bt_model[j]);
- ctx->fill_coder[i].fill_val = 0;
- model_reset(&ctx->fill_coder[i].coef_model);
- model256_reset(&ctx->image_coder[i].esc_model);
- model256_reset(&ctx->image_coder[i].vec_entry_model);
- model_reset(&ctx->image_coder[i].vec_size_model);
- for (j = 0; j < 125; j++)
- model_reset(&ctx->image_coder[i].vq_model[j]);
- if (ctx->dct_coder[i].quality != quality) {
- ctx->dct_coder[i].quality = quality;
- ff_mss34_gen_quant_mat(ctx->dct_coder[i].qmat, quality, !i);
- }
- memset(ctx->dct_coder[i].prev_dc, 0,
- sizeof(*ctx->dct_coder[i].prev_dc) *
- ctx->dct_coder[i].prev_dc_stride *
- ctx->dct_coder[i].prev_dc_height);
- model_reset(&ctx->dct_coder[i].dc_model);
- model2_reset(&ctx->dct_coder[i].sign_model);
- model256_reset(&ctx->dct_coder[i].ac_model);
- if (ctx->haar_coder[i].quality != quality) {
- ctx->haar_coder[i].quality = quality;
- ctx->haar_coder[i].scale = 17 - 7 * quality / 50;
- }
- model_reset(&ctx->haar_coder[i].coef_hi_model);
- model256_reset(&ctx->haar_coder[i].coef_model);
- }
-}
-
-static av_cold void init_coders(MSS3Context *ctx)
-{
- int i, j;
-
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 5; j++)
- model_init(&ctx->btype[i].bt_model[j], 5);
- model_init(&ctx->fill_coder[i].coef_model, 12);
- model256_init(&ctx->image_coder[i].esc_model);
- model256_init(&ctx->image_coder[i].vec_entry_model);
- model_init(&ctx->image_coder[i].vec_size_model, 3);
- for (j = 0; j < 125; j++)
- model_init(&ctx->image_coder[i].vq_model[j], 5);
- model_init(&ctx->dct_coder[i].dc_model, 12);
- model256_init(&ctx->dct_coder[i].ac_model);
- model_init(&ctx->haar_coder[i].coef_hi_model, 12);
- model256_init(&ctx->haar_coder[i].coef_model);
- }
-}
-
-static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- MSS3Context *c = avctx->priv_data;
- RangeCoder *acoder = &c->coder;
- GetByteContext gb;
- uint8_t *dst[3];
- int dec_width, dec_height, dec_x, dec_y, quality, keyframe;
- int x, y, i, mb_width, mb_height, blk_size, btype;
- int ret;
-
- if (buf_size < HEADER_SIZE) {
- av_log(avctx, AV_LOG_ERROR,
- "Frame should have at least %d bytes, got %d instead\n",
- HEADER_SIZE, buf_size);
- return AVERROR_INVALIDDATA;
- }
-
- bytestream2_init(&gb, buf, buf_size);
- keyframe = bytestream2_get_be32(&gb);
- if (keyframe & ~0x301) {
- av_log(avctx, AV_LOG_ERROR, "Invalid frame type %X\n", keyframe);
- return AVERROR_INVALIDDATA;
- }
- keyframe = !(keyframe & 1);
- bytestream2_skip(&gb, 6);
- dec_x = bytestream2_get_be16(&gb);
- dec_y = bytestream2_get_be16(&gb);
- dec_width = bytestream2_get_be16(&gb);
- dec_height = bytestream2_get_be16(&gb);
-
- if (dec_x + dec_width > avctx->width ||
- dec_y + dec_height > avctx->height ||
- (dec_width | dec_height) & 0xF) {
- av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d +%d,%d\n",
- dec_width, dec_height, dec_x, dec_y);
- return AVERROR_INVALIDDATA;
- }
- bytestream2_skip(&gb, 4);
- quality = bytestream2_get_byte(&gb);
- if (quality < 1 || quality > 100) {
- av_log(avctx, AV_LOG_ERROR, "Invalid quality setting %d\n", quality);
- return AVERROR_INVALIDDATA;
- }
- bytestream2_skip(&gb, 4);
-
- if (keyframe && !bytestream2_get_bytes_left(&gb)) {
- av_log(avctx, AV_LOG_ERROR, "Keyframe without data found\n");
- return AVERROR_INVALIDDATA;
- }
- if (!keyframe && c->got_error)
- return buf_size;
- c->got_error = 0;
-
- if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)
- return ret;
- c->pic->key_frame = keyframe;
- c->pic->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
- if (!bytestream2_get_bytes_left(&gb)) {
- if ((ret = av_frame_ref(data, c->pic)) < 0)
- return ret;
- *got_frame = 1;
-
- return buf_size;
- }
-
- reset_coders(c, quality);
-
- rac_init(acoder, buf + HEADER_SIZE, buf_size - HEADER_SIZE);
-
- mb_width = dec_width >> 4;
- mb_height = dec_height >> 4;
- dst[0] = c->pic->data[0] + dec_x + dec_y * c->pic->linesize[0];
- dst[1] = c->pic->data[1] + dec_x / 2 + (dec_y / 2) * c->pic->linesize[1];
- dst[2] = c->pic->data[2] + dec_x / 2 + (dec_y / 2) * c->pic->linesize[2];
- for (y = 0; y < mb_height; y++) {
- for (x = 0; x < mb_width; x++) {
- for (i = 0; i < 3; i++) {
- blk_size = 8 << !i;
-
- btype = decode_block_type(acoder, c->btype + i);
- switch (btype) {
- case FILL_BLOCK:
- decode_fill_block(acoder, c->fill_coder + i,
- dst[i] + x * blk_size,
- c->pic->linesize[i], blk_size);
- break;
- case IMAGE_BLOCK:
- decode_image_block(acoder, c->image_coder + i,
- dst[i] + x * blk_size,
- c->pic->linesize[i], blk_size);
- break;
- case DCT_BLOCK:
- decode_dct_block(acoder, c->dct_coder + i,
- dst[i] + x * blk_size,
- c->pic->linesize[i], blk_size,
- c->dctblock, x, y);
- break;
- case HAAR_BLOCK:
- decode_haar_block(acoder, c->haar_coder + i,
- dst[i] + x * blk_size,
- c->pic->linesize[i], blk_size,
- c->hblock);
- break;
- }
- if (c->got_error || acoder->got_error) {
- av_log(avctx, AV_LOG_ERROR, "Error decoding block %d,%d\n",
- x, y);
- c->got_error = 1;
- return AVERROR_INVALIDDATA;
- }
- }
- }
- dst[0] += c->pic->linesize[0] * 16;
- dst[1] += c->pic->linesize[1] * 8;
- dst[2] += c->pic->linesize[2] * 8;
- }
-
- if ((ret = av_frame_ref(data, c->pic)) < 0)
- return ret;
-
- *got_frame = 1;
-
- return buf_size;
-}
-
-static av_cold int mss3_decode_end(AVCodecContext *avctx)
-{
- MSS3Context * const c = avctx->priv_data;
- int i;
-
- av_frame_free(&c->pic);
- for (i = 0; i < 3; i++)
- av_freep(&c->dct_coder[i].prev_dc);
-
- return 0;
-}
-
-static av_cold int mss3_decode_init(AVCodecContext *avctx)
-{
- MSS3Context * const c = avctx->priv_data;
- int i;
-
- c->avctx = avctx;
-
- if ((avctx->width & 0xF) || (avctx->height & 0xF)) {
- av_log(avctx, AV_LOG_ERROR,
- "Image dimensions should be a multiple of 16.\n");
- return AVERROR_INVALIDDATA;
- }
-
- c->got_error = 0;
- for (i = 0; i < 3; i++) {
- int b_width = avctx->width >> (2 + !!i);
- int b_height = avctx->height >> (2 + !!i);
- c->dct_coder[i].prev_dc_stride = b_width;
- c->dct_coder[i].prev_dc_height = b_height;
- c->dct_coder[i].prev_dc = av_malloc(sizeof(*c->dct_coder[i].prev_dc) *
- 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);
- return AVERROR(ENOMEM);
- }
-
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
-
- init_coders(c);
-
- return 0;
-}
-
-AVCodec ff_msa1_decoder = {
- .name = "msa1",
- .long_name = NULL_IF_CONFIG_SMALL("MS ATC Screen"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MSA1,
- .priv_data_size = sizeof(MSS3Context),
- .init = mss3_decode_init,
- .close = mss3_decode_end,
- .decode = mss3_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/mss34dsp.c b/ffmpeg-2-8-11/libavcodec/mss34dsp.c
deleted file mode 100644
index 0397add..0000000
--- a/ffmpeg-2-8-11/libavcodec/mss34dsp.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Common stuff for some Microsoft Screen codecs
- * Copyright (C) 2012 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 <stdint.h>
-#include "libavutil/common.h"
-#include "mss34dsp.h"
-
-static const uint8_t luma_quant[64] = {
- 16, 11, 10, 16, 24, 40, 51, 61,
- 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 56, 68, 109, 103, 77,
- 24, 35, 55, 64, 81, 104, 113, 92,
- 49, 64, 78, 87, 103, 121, 120, 101,
- 72, 92, 95, 98, 112, 100, 103, 99
-};
-
-static const uint8_t chroma_quant[64] = {
- 17, 18, 24, 47, 99, 99, 99, 99,
- 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 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
-};
-
-void ff_mss34_gen_quant_mat(uint16_t *qmat, int quality, int luma)
-{
- int i;
- const uint8_t *qsrc = luma ? luma_quant : chroma_quant;
-
- if (quality >= 50) {
- int scale = 200 - 2 * quality;
-
- for (i = 0; i < 64; i++)
- qmat[i] = (qsrc[i] * scale + 50) / 100;
- } else {
- for (i = 0; i < 64; i++)
- qmat[i] = (5000 * qsrc[i] / quality + 50) / 100;
- }
-}
-
-#define DCT_TEMPLATE(blk, step, SOP, shift) \
- const int t0 = -39409 * blk[7 * step] - 58980 * blk[1 * step]; \
- const int t1 = 39410 * blk[1 * step] - 58980 * blk[7 * step]; \
- const int t2 = -33410 * blk[5 * step] - 167963 * blk[3 * step]; \
- const int t3 = 33410 * blk[3 * step] - 167963 * blk[5 * step]; \
- const int t4 = blk[3 * step] + blk[7 * step]; \
- const int t5 = blk[1 * step] + blk[5 * step]; \
- const int t6 = 77062 * t4 + 51491 * t5; \
- const int t7 = 77062 * t5 - 51491 * t4; \
- const int t8 = 35470 * blk[2 * step] - 85623 * blk[6 * step]; \
- const int t9 = 35470 * blk[6 * step] + 85623 * blk[2 * step]; \
- const int tA = SOP(blk[0 * step] - blk[4 * step]); \
- const int tB = SOP(blk[0 * step] + blk[4 * step]); \
- \
- blk[0 * step] = ( t1 + t6 + t9 + tB) >> shift; \
- blk[1 * step] = ( t3 + t7 + t8 + tA) >> shift; \
- blk[2 * step] = ( t2 + t6 - t8 + tA) >> shift; \
- blk[3 * step] = ( t0 + t7 - t9 + tB) >> shift; \
- blk[4 * step] = (-(t0 + t7) - t9 + tB) >> shift; \
- blk[5 * step] = (-(t2 + t6) - t8 + tA) >> shift; \
- blk[6 * step] = (-(t3 + t7) + t8 + tA) >> shift; \
- blk[7 * step] = (-(t1 + t6) + t9 + tB) >> shift; \
-
-#define SOP_ROW(a) (((a) << 16) + 0x2000)
-#define SOP_COL(a) (((a) + 32) << 16)
-
-void ff_mss34_dct_put(uint8_t *dst, int stride, int *block)
-{
- int i, j;
- int *ptr;
-
- ptr = block;
- for (i = 0; i < 8; i++) {
- DCT_TEMPLATE(ptr, 1, SOP_ROW, 13);
- ptr += 8;
- }
-
- ptr = block;
- for (i = 0; i < 8; i++) {
- DCT_TEMPLATE(ptr, 8, SOP_COL, 22);
- ptr++;
- }
-
- ptr = block;
- for (j = 0; j < 8; j++) {
- for (i = 0; i < 8; i++)
- dst[i] = av_clip_uint8(ptr[i] + 128);
- dst += stride;
- ptr += 8;
- }
-}
diff --git a/ffmpeg-2-8-11/libavcodec/msvideo1.c b/ffmpeg-2-8-11/libavcodec/msvideo1.c
deleted file mode 100644
index 0526505..0000000
--- a/ffmpeg-2-8-11/libavcodec/msvideo1.c
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Microsoft Video-1 Decoder
- * Copyright (c) 2003 The FFmpeg Project
- *
- * 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 Video-1 Decoder by Mike Melanson (melanson at pcisys.net)
- * For more information about the MS Video-1 format, visit:
- * http://www.pcisys.net/~melanson/codecs/
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "libavutil/internal.h"
-#include "libavutil/intreadwrite.h"
-#include "avcodec.h"
-#include "internal.h"
-
-#define PALETTE_COUNT 256
-#define CHECK_STREAM_PTR(n) \
- if ((stream_ptr + n) > s->size ) { \
- av_log(s->avctx, AV_LOG_ERROR, " MS Video-1 warning: stream_ptr out of bounds (%d >= %d)\n", \
- stream_ptr + n, s->size); \
- return; \
- }
-
-typedef struct Msvideo1Context {
-
- AVCodecContext *avctx;
- AVFrame *frame;
-
- const unsigned char *buf;
- int size;
-
- int mode_8bit; /* if it's not 8-bit, it's 16-bit */
-
- uint32_t pal[256];
-} Msvideo1Context;
-
-static av_cold int msvideo1_decode_init(AVCodecContext *avctx)
-{
- Msvideo1Context *s = avctx->priv_data;
-
- s->avctx = avctx;
-
- /* figure out the colorspace based on the presence of a palette */
- if (s->avctx->bits_per_coded_sample == 8) {
- s->mode_8bit = 1;
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
- if (avctx->extradata_size >= AVPALETTE_SIZE)
- memcpy(s->pal, avctx->extradata, AVPALETTE_SIZE);
- } else {
- s->mode_8bit = 0;
- avctx->pix_fmt = AV_PIX_FMT_RGB555;
- }
-
- s->frame = av_frame_alloc();
- if (!s->frame)
- return AVERROR(ENOMEM);
-
- return 0;
-}
-
-static void msvideo1_decode_8bit(Msvideo1Context *s)
-{
- int block_ptr, pixel_ptr;
- int total_blocks;
- int pixel_x, pixel_y; /* pixel width and height iterators */
- int block_x, block_y; /* block width and height iterators */
- int blocks_wide, blocks_high; /* width and height in 4x4 blocks */
- int block_inc;
- int row_dec;
-
- /* decoding parameters */
- int stream_ptr;
- unsigned char byte_a, byte_b;
- unsigned short flags;
- int skip_blocks;
- unsigned char colors[8];
- unsigned char *pixels = s->frame->data[0];
- int stride = s->frame->linesize[0];
-
- stream_ptr = 0;
- skip_blocks = 0;
- blocks_wide = s->avctx->width / 4;
- blocks_high = s->avctx->height / 4;
- total_blocks = blocks_wide * blocks_high;
- block_inc = 4;
- row_dec = stride + 4;
-
- for (block_y = blocks_high; block_y > 0; block_y--) {
- block_ptr = ((block_y * 4) - 1) * stride;
- for (block_x = blocks_wide; block_x > 0; block_x--) {
- /* check if this block should be skipped */
- if (skip_blocks) {
- block_ptr += block_inc;
- skip_blocks--;
- total_blocks--;
- continue;
- }
-
- pixel_ptr = block_ptr;
-
- /* get the next two bytes in the encoded data stream */
- CHECK_STREAM_PTR(2);
- byte_a = s->buf[stream_ptr++];
- byte_b = s->buf[stream_ptr++];
-
- /* check if the decode is finished */
- if ((byte_a == 0) && (byte_b == 0) && (total_blocks == 0))
- return;
- else if ((byte_b & 0xFC) == 0x84) {
- /* skip code, but don't count the current block */
- skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1;
- } else if (byte_b < 0x80) {
- /* 2-color encoding */
- flags = (byte_b << 8) | byte_a;
-
- CHECK_STREAM_PTR(2);
- colors[0] = s->buf[stream_ptr++];
- colors[1] = s->buf[stream_ptr++];
-
- for (pixel_y = 0; pixel_y < 4; pixel_y++) {
- for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
- pixels[pixel_ptr++] = colors[(flags & 0x1) ^ 1];
- pixel_ptr -= row_dec;
- }
- } else if (byte_b >= 0x90) {
- /* 8-color encoding */
- flags = (byte_b << 8) | byte_a;
-
- CHECK_STREAM_PTR(8);
- memcpy(colors, &s->buf[stream_ptr], 8);
- stream_ptr += 8;
-
- for (pixel_y = 0; pixel_y < 4; pixel_y++) {
- for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
- pixels[pixel_ptr++] =
- colors[((pixel_y & 0x2) << 1) +
- (pixel_x & 0x2) + ((flags & 0x1) ^ 1)];
- pixel_ptr -= row_dec;
- }
- } else {
- /* 1-color encoding */
- colors[0] = byte_a;
-
- for (pixel_y = 0; pixel_y < 4; pixel_y++) {
- for (pixel_x = 0; pixel_x < 4; pixel_x++)
- pixels[pixel_ptr++] = colors[0];
- pixel_ptr -= row_dec;
- }
- }
-
- block_ptr += block_inc;
- total_blocks--;
- }
- }
-
- /* make the palette available on the way out */
- if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
- memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);
-}
-
-static void msvideo1_decode_16bit(Msvideo1Context *s)
-{
- int block_ptr, pixel_ptr;
- int total_blocks;
- int pixel_x, pixel_y; /* pixel width and height iterators */
- int block_x, block_y; /* block width and height iterators */
- int blocks_wide, blocks_high; /* width and height in 4x4 blocks */
- int block_inc;
- int row_dec;
-
- /* decoding parameters */
- int stream_ptr;
- unsigned char byte_a, byte_b;
- unsigned short flags;
- int skip_blocks;
- unsigned short colors[8];
- unsigned short *pixels = (unsigned short *)s->frame->data[0];
- int stride = s->frame->linesize[0] / 2;
-
- stream_ptr = 0;
- skip_blocks = 0;
- blocks_wide = s->avctx->width / 4;
- blocks_high = s->avctx->height / 4;
- total_blocks = blocks_wide * blocks_high;
- block_inc = 4;
- row_dec = stride + 4;
-
- for (block_y = blocks_high; block_y > 0; block_y--) {
- block_ptr = ((block_y * 4) - 1) * stride;
- for (block_x = blocks_wide; block_x > 0; block_x--) {
- /* check if this block should be skipped */
- if (skip_blocks) {
- block_ptr += block_inc;
- skip_blocks--;
- total_blocks--;
- continue;
- }
-
- pixel_ptr = block_ptr;
-
- /* get the next two bytes in the encoded data stream */
- CHECK_STREAM_PTR(2);
- byte_a = s->buf[stream_ptr++];
- byte_b = s->buf[stream_ptr++];
-
- /* check if the decode is finished */
- if ((byte_a == 0) && (byte_b == 0) && (total_blocks == 0)) {
- return;
- } else if ((byte_b & 0xFC) == 0x84) {
- /* skip code, but don't count the current block */
- skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1;
- } else if (byte_b < 0x80) {
- /* 2- or 8-color encoding modes */
- flags = (byte_b << 8) | byte_a;
-
- CHECK_STREAM_PTR(4);
- colors[0] = AV_RL16(&s->buf[stream_ptr]);
- stream_ptr += 2;
- colors[1] = AV_RL16(&s->buf[stream_ptr]);
- stream_ptr += 2;
-
- if (colors[0] & 0x8000) {
- /* 8-color encoding */
- CHECK_STREAM_PTR(12);
- colors[2] = AV_RL16(&s->buf[stream_ptr]);
- stream_ptr += 2;
- colors[3] = AV_RL16(&s->buf[stream_ptr]);
- stream_ptr += 2;
- colors[4] = AV_RL16(&s->buf[stream_ptr]);
- stream_ptr += 2;
- colors[5] = AV_RL16(&s->buf[stream_ptr]);
- stream_ptr += 2;
- colors[6] = AV_RL16(&s->buf[stream_ptr]);
- stream_ptr += 2;
- colors[7] = AV_RL16(&s->buf[stream_ptr]);
- stream_ptr += 2;
-
- for (pixel_y = 0; pixel_y < 4; pixel_y++) {
- for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
- pixels[pixel_ptr++] =
- colors[((pixel_y & 0x2) << 1) +
- (pixel_x & 0x2) + ((flags & 0x1) ^ 1)];
- pixel_ptr -= row_dec;
- }
- } else {
- /* 2-color encoding */
- for (pixel_y = 0; pixel_y < 4; pixel_y++) {
- for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
- pixels[pixel_ptr++] = colors[(flags & 0x1) ^ 1];
- pixel_ptr -= row_dec;
- }
- }
- } else {
- /* otherwise, it's a 1-color block */
- colors[0] = (byte_b << 8) | byte_a;
-
- for (pixel_y = 0; pixel_y < 4; pixel_y++) {
- for (pixel_x = 0; pixel_x < 4; pixel_x++)
- pixels[pixel_ptr++] = colors[0];
- pixel_ptr -= row_dec;
- }
- }
-
- block_ptr += block_inc;
- total_blocks--;
- }
- }
-}
-
-static int msvideo1_decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- Msvideo1Context *s = avctx->priv_data;
- int ret;
-
- s->buf = buf;
- s->size = buf_size;
-
- if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
- return ret;
-
- if (s->mode_8bit) {
- int size;
- const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size);
-
- if (pal && size == AVPALETTE_SIZE) {
- memcpy(s->pal, pal, AVPALETTE_SIZE);
- s->frame->palette_has_changed = 1;
- } else if (pal) {
- av_log(avctx, AV_LOG_ERROR, "Palette size %d is wrong\n", size);
- }
- }
-
- if (s->mode_8bit)
- msvideo1_decode_8bit(s);
- else
- msvideo1_decode_16bit(s);
-
- if ((ret = av_frame_ref(data, s->frame)) < 0)
- return ret;
-
- *got_frame = 1;
-
- /* report that the buffer was completely consumed */
- return buf_size;
-}
-
-static av_cold int msvideo1_decode_end(AVCodecContext *avctx)
-{
- Msvideo1Context *s = avctx->priv_data;
-
- av_frame_free(&s->frame);
-
- return 0;
-}
-
-AVCodec ff_msvideo1_decoder = {
- .name = "msvideo1",
- .long_name = NULL_IF_CONFIG_SMALL("Microsoft Video 1"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_MSVIDEO1,
- .priv_data_size = sizeof(Msvideo1Context),
- .init = msvideo1_decode_init,
- .close = msvideo1_decode_end,
- .decode = msvideo1_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/nellymoser.c b/ffmpeg-2-8-11/libavcodec/nellymoser.c
deleted file mode 100644
index 0740c75..0000000
--- a/ffmpeg-2-8-11/libavcodec/nellymoser.c
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Common code between Nellymoser encoder and decoder
- * Copyright (c) 2007 a840bda5870ba11f19698ff6eb9581dfb0f95fa5,
- * 539459aeb7d425140b62a3ec7dbf6dc8e408a306, and
- * 520e17cd55896441042b14df2566a6eb610ed444
- * Copyright (c) 2007 Loic Minier <lool at dooz.org>
- * Benjamin Larsson
- *
- * 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.
- */
-
-/**
- * @file
- * The 3 alphanumeric copyright notices are md5summed they are from the original
- * implementors. The original code is available from http://code.google.com/p/nelly2pcm/
- */
-
-#include "nellymoser.h"
-#include "avcodec.h"
-
-#define BITSTREAM_READER_LE
-#include "get_bits.h"
-
-const float ff_nelly_dequantization_table[127] = {
- 0.0000000000,
-
--0.8472560048, 0.7224709988,
-
--1.5247479677,-0.4531480074, 0.3753609955, 1.4717899561,
-
--1.9822579622,-1.1929379702,-0.5829370022,-0.0693780035, 0.3909569979, 0.9069200158, 1.4862740040, 2.2215409279,
-
--2.3887870312,-1.8067539930,-1.4105420113,-1.0773609877,-0.7995010018,-0.5558109879,-0.3334020078,-0.1324490011,
- 0.0568020009, 0.2548770010, 0.4773550034, 0.7386850119, 1.0443060398, 1.3954459429, 1.8098750114, 2.3918759823,
-
--2.3893830776,-1.9884680510,-1.7514040470,-1.5643119812,-1.3922129869,-1.2164649963,-1.0469499826,-0.8905100226,
--0.7645580173,-0.6454579830,-0.5259280205,-0.4059549868,-0.3029719889,-0.2096900046,-0.1239869967,-0.0479229987,
- 0.0257730000, 0.1001340002, 0.1737180054, 0.2585540116, 0.3522900045, 0.4569880068, 0.5767750144, 0.7003160119,
- 0.8425520062, 1.0093879700, 1.1821349859, 1.3534560204, 1.5320819616, 1.7332619429, 1.9722349644, 2.3978140354,
-
--2.5756309032,-2.0573320389,-1.8984919786,-1.7727810144,-1.6662600040,-1.5742180347,-1.4993319511,-1.4316639900,
--1.3652280569,-1.3000990152,-1.2280930281,-1.1588579416,-1.0921250582,-1.0135740042,-0.9202849865,-0.8287050128,
--0.7374889851,-0.6447759867,-0.5590940118,-0.4857139885,-0.4110319912,-0.3459700048,-0.2851159871,-0.2341620028,
--0.1870580018,-0.1442500055,-0.1107169986,-0.0739680007,-0.0365610011,-0.0073290002, 0.0203610007, 0.0479039997,
- 0.0751969963, 0.0980999991, 0.1220389977, 0.1458999962, 0.1694349945, 0.1970459968, 0.2252430022, 0.2556869984,
- 0.2870100141, 0.3197099864, 0.3525829911, 0.3889069855, 0.4334920049, 0.4769459963, 0.5204820037, 0.5644530058,
- 0.6122040153, 0.6685929894, 0.7341650128, 0.8032159805, 0.8784040213, 0.9566209912, 1.0397069454, 1.1293770075,
- 1.2211159468, 1.3080279827, 1.4024800062, 1.5056819916, 1.6227730513, 1.7724959850, 1.9430880547, 2.2903931141
-};
-
-const uint8_t ff_nelly_band_sizes_table[NELLY_BANDS] = {
-2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 12, 14, 15
-};
-
-const uint16_t ff_nelly_init_table[64] = {
-3134, 5342, 6870, 7792, 8569, 9185, 9744, 10191, 10631, 11061, 11434, 11770,
-12116, 12513, 12925, 13300, 13674, 14027, 14352, 14716, 15117, 15477, 15824,
-16157, 16513, 16804, 17090, 17401, 17679, 17948, 18238, 18520, 18764, 19078,
-19381, 19640, 19921, 20205, 20500, 20813, 21162, 21465, 21794, 22137, 22453,
-22756, 23067, 23350, 23636, 23926, 24227, 24521, 24819, 25107, 25414, 25730,
-26120, 26497, 26895, 27344, 27877, 28463, 29426, 31355
-};
-
-const int16_t ff_nelly_delta_table[32] = {
--11725, -9420, -7910, -6801, -5948, -5233, -4599, -4039, -3507, -3030, -2596,
--2170, -1774, -1383, -1016, -660, -329, -1, 337, 696, 1085, 1512, 1962, 2433,
-2968, 3569, 4314, 5279, 6622, 8154, 10076, 12975
-};
-
-static inline int signed_shift(int i, int shift) {
- if (shift > 0)
- return i << shift;
- return i >> -shift;
-}
-
-static int sum_bits(short *buf, short shift, short off)
-{
- int i, ret = 0;
-
- for (i = 0; i < NELLY_FILL_LEN; i++) {
- int b = buf[i]-off;
- b = ((b>>(shift-1))+1)>>1;
- ret += av_clip(b, 0, NELLY_BIT_CAP);
- }
-
- return ret;
-}
-
-static int headroom(int *la)
-{
- int l;
- if (*la == 0) {
- return 31;
- }
- l = 30 - av_log2(FFABS(*la));
- *la <<= l;
- return l;
-}
-
-
-void ff_nelly_get_sample_bits(const float *buf, int *bits)
-{
- int i, j;
- short sbuf[128];
- int bitsum = 0, last_bitsum, small_bitsum, big_bitsum;
- short shift, shift_saved;
- int max, sum, last_off, tmp;
- int big_off, small_off;
- int off;
-
- max = 0;
- for (i = 0; i < NELLY_FILL_LEN; i++) {
- max = FFMAX(max, buf[i]);
- }
- shift = -16;
- shift += headroom(&max);
-
- sum = 0;
- for (i = 0; i < NELLY_FILL_LEN; i++) {
- sbuf[i] = signed_shift(buf[i], shift);
- sbuf[i] = (3*sbuf[i])>>2;
- sum += sbuf[i];
- }
-
- shift += 11;
- shift_saved = shift;
- sum -= NELLY_DETAIL_BITS << shift;
- shift += headroom(&sum);
- small_off = (NELLY_BASE_OFF * (sum>>16)) >> 15;
- shift = shift_saved - (NELLY_BASE_SHIFT+shift-31);
-
- small_off = signed_shift(small_off, shift);
-
- bitsum = sum_bits(sbuf, shift_saved, small_off);
-
- if (bitsum != NELLY_DETAIL_BITS) {
- off = bitsum - NELLY_DETAIL_BITS;
-
- for(shift=0; FFABS(off) <= 16383; shift++)
- off *= 2;
-
- off = (off * NELLY_BASE_OFF) >> 15;
- shift = shift_saved-(NELLY_BASE_SHIFT+shift-15);
-
- off = signed_shift(off, shift);
-
- for (j = 1; j < 20; j++) {
- last_off = small_off;
- small_off += off;
- last_bitsum = bitsum;
-
- bitsum = sum_bits(sbuf, shift_saved, small_off);
-
- if ((bitsum-NELLY_DETAIL_BITS) * (last_bitsum-NELLY_DETAIL_BITS) <= 0)
- break;
- }
-
- if (bitsum > NELLY_DETAIL_BITS) {
- big_off = small_off;
- small_off = last_off;
- big_bitsum=bitsum;
- small_bitsum=last_bitsum;
- } else {
- big_off = last_off;
- big_bitsum=last_bitsum;
- small_bitsum=bitsum;
- }
-
- while (bitsum != NELLY_DETAIL_BITS && j <= 19) {
- off = (big_off+small_off)>>1;
- bitsum = sum_bits(sbuf, shift_saved, off);
- if (bitsum > NELLY_DETAIL_BITS) {
- big_off=off;
- big_bitsum=bitsum;
- } else {
- small_off = off;
- small_bitsum=bitsum;
- }
- j++;
- }
-
- if (abs(big_bitsum-NELLY_DETAIL_BITS) >=
- abs(small_bitsum-NELLY_DETAIL_BITS)) {
- bitsum = small_bitsum;
- } else {
- small_off = big_off;
- bitsum = big_bitsum;
- }
- }
-
- for (i = 0; i < NELLY_FILL_LEN; i++) {
- tmp = sbuf[i]-small_off;
- tmp = ((tmp>>(shift_saved-1))+1)>>1;
- bits[i] = av_clip(tmp, 0, NELLY_BIT_CAP);
- }
-
- if (bitsum > NELLY_DETAIL_BITS) {
- tmp = i = 0;
- while (tmp < NELLY_DETAIL_BITS) {
- tmp += bits[i];
- i++;
- }
-
- bits[i-1] -= tmp - NELLY_DETAIL_BITS;
- for(; i < NELLY_FILL_LEN; i++)
- bits[i] = 0;
- }
-}
diff --git a/ffmpeg-2-8-11/libavcodec/options.c b/ffmpeg-2-8-11/libavcodec/options.c
deleted file mode 100644
index ea2563b..0000000
--- a/ffmpeg-2-8-11/libavcodec/options.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * Copyright (c) 2001 Fabrice Bellard
- * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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
- * Options definition for AVCodecContext.
- */
-
-#include "avcodec.h"
-#include "internal.h"
-#include "libavutil/avassert.h"
-#include "libavutil/internal.h"
-#include "libavutil/mem.h"
-#include "libavutil/opt.h"
-#include <float.h> /* FLT_MIN, FLT_MAX */
-#include <string.h>
-
-FF_DISABLE_DEPRECATION_WARNINGS
-#include "options_table.h"
-FF_ENABLE_DEPRECATION_WARNINGS
-
-static const char* context_to_name(void* ptr) {
- AVCodecContext *avc= ptr;
-
- if(avc && avc->codec && avc->codec->name)
- return avc->codec->name;
- else
- return "NULL";
-}
-
-static void *codec_child_next(void *obj, void *prev)
-{
- AVCodecContext *s = obj;
- if (!prev && s->codec && s->codec->priv_class && s->priv_data)
- return s->priv_data;
- return NULL;
-}
-
-static const AVClass *codec_child_class_next(const AVClass *prev)
-{
- AVCodec *c = NULL;
-
- /* find the codec that corresponds to prev */
- while (prev && (c = av_codec_next(c)))
- if (c->priv_class == prev)
- break;
-
- /* find next codec with priv options */
- while (c = av_codec_next(c))
- if (c->priv_class)
- return c->priv_class;
- return NULL;
-}
-
-static AVClassCategory get_category(void *ptr)
-{
- AVCodecContext* avctx = ptr;
- if(avctx->codec && avctx->codec->decode) return AV_CLASS_CATEGORY_DECODER;
- else return AV_CLASS_CATEGORY_ENCODER;
-}
-
-static const AVClass av_codec_context_class = {
- .class_name = "AVCodecContext",
- .item_name = context_to_name,
- .option = avcodec_options,
- .version = LIBAVUTIL_VERSION_INT,
- .log_level_offset_offset = offsetof(AVCodecContext, log_level_offset),
- .child_next = codec_child_next,
- .child_class_next = codec_child_class_next,
- .category = AV_CLASS_CATEGORY_ENCODER,
- .get_category = get_category,
-};
-
-int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec)
-{
- int flags=0;
- memset(s, 0, sizeof(AVCodecContext));
-
- s->av_class = &av_codec_context_class;
-
- s->codec_type = codec ? codec->type : AVMEDIA_TYPE_UNKNOWN;
- if (codec) {
- s->codec = codec;
- s->codec_id = codec->id;
- }
-
- if(s->codec_type == AVMEDIA_TYPE_AUDIO)
- flags= AV_OPT_FLAG_AUDIO_PARAM;
- else if(s->codec_type == AVMEDIA_TYPE_VIDEO)
- flags= AV_OPT_FLAG_VIDEO_PARAM;
- else if(s->codec_type == AVMEDIA_TYPE_SUBTITLE)
- flags= AV_OPT_FLAG_SUBTITLE_PARAM;
- av_opt_set_defaults2(s, flags, flags);
-
- s->time_base = (AVRational){0,1};
- s->framerate = (AVRational){ 0, 1 };
- s->pkt_timebase = (AVRational){ 0, 1 };
- s->get_buffer2 = avcodec_default_get_buffer2;
- s->get_format = avcodec_default_get_format;
- s->execute = avcodec_default_execute;
- s->execute2 = avcodec_default_execute2;
- s->sample_aspect_ratio = (AVRational){0,1};
- s->pix_fmt = AV_PIX_FMT_NONE;
- s->sample_fmt = AV_SAMPLE_FMT_NONE;
-
- s->reordered_opaque = AV_NOPTS_VALUE;
- if(codec && codec->priv_data_size){
- if(!s->priv_data){
- s->priv_data= av_mallocz(codec->priv_data_size);
- if (!s->priv_data) {
- return AVERROR(ENOMEM);
- }
- }
- if(codec->priv_class){
- *(const AVClass**)s->priv_data = codec->priv_class;
- av_opt_set_defaults(s->priv_data);
- }
- }
- if (codec && codec->defaults) {
- int ret;
- const AVCodecDefault *d = codec->defaults;
- while (d->key) {
- ret = av_opt_set(s, d->key, d->value, 0);
- av_assert0(ret >= 0);
- d++;
- }
- }
- return 0;
-}
-
-AVCodecContext *avcodec_alloc_context3(const AVCodec *codec)
-{
- AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext));
-
- if (!avctx)
- return NULL;
-
- if(avcodec_get_context_defaults3(avctx, codec) < 0){
- av_free(avctx);
- return NULL;
- }
-
- return avctx;
-}
-
-void avcodec_free_context(AVCodecContext **pavctx)
-{
- AVCodecContext *avctx = *pavctx;
-
- if (!avctx)
- return;
-
- avcodec_close(avctx);
-
- av_freep(&avctx->extradata);
- av_freep(&avctx->subtitle_header);
- av_freep(&avctx->intra_matrix);
- av_freep(&avctx->inter_matrix);
- av_freep(&avctx->rc_override);
-
- av_freep(pavctx);
-}
-
-int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src)
-{
- const AVCodec *orig_codec = dest->codec;
- uint8_t *orig_priv_data = dest->priv_data;
-
- if (avcodec_is_open(dest)) { // check that the dest context is uninitialized
- av_log(dest, AV_LOG_ERROR,
- "Tried to copy AVCodecContext %p into already-initialized %p\n",
- src, dest);
- return AVERROR(EINVAL);
- }
-
- av_opt_free(dest);
- av_freep(&dest->rc_override);
- av_freep(&dest->intra_matrix);
- av_freep(&dest->inter_matrix);
- av_freep(&dest->extradata);
- av_freep(&dest->subtitle_header);
-
- memcpy(dest, src, sizeof(*dest));
- av_opt_copy(dest, src);
-
- dest->priv_data = orig_priv_data;
- dest->codec = orig_codec;
-
- if (orig_priv_data && src->codec && src->codec->priv_class &&
- dest->codec && dest->codec->priv_class)
- av_opt_copy(orig_priv_data, src->priv_data);
-
-
- /* set values specific to opened codecs back to their default state */
- dest->slice_offset = NULL;
- dest->hwaccel = NULL;
- dest->internal = NULL;
-#if FF_API_CODED_FRAME
-FF_DISABLE_DEPRECATION_WARNINGS
- dest->coded_frame = NULL;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
- /* reallocate values that should be allocated separately */
- dest->extradata = NULL;
- dest->intra_matrix = NULL;
- dest->inter_matrix = NULL;
- dest->rc_override = NULL;
- dest->subtitle_header = NULL;
-
-#define alloc_and_copy_or_fail(obj, size, pad) \
- if (src->obj && size > 0) { \
- dest->obj = av_malloc(size + pad); \
- if (!dest->obj) \
- goto fail; \
- memcpy(dest->obj, src->obj, size); \
- if (pad) \
- memset(((uint8_t *) dest->obj) + size, 0, pad); \
- }
- alloc_and_copy_or_fail(extradata, src->extradata_size,
- AV_INPUT_BUFFER_PADDING_SIZE);
- dest->extradata_size = src->extradata_size;
- alloc_and_copy_or_fail(intra_matrix, 64 * sizeof(int16_t), 0);
- alloc_and_copy_or_fail(inter_matrix, 64 * sizeof(int16_t), 0);
- alloc_and_copy_or_fail(rc_override, src->rc_override_count * sizeof(*src->rc_override), 0);
- alloc_and_copy_or_fail(subtitle_header, src->subtitle_header_size, 1);
- av_assert0(dest->subtitle_header_size == src->subtitle_header_size);
-#undef alloc_and_copy_or_fail
-
- return 0;
-
-fail:
- av_freep(&dest->rc_override);
- av_freep(&dest->intra_matrix);
- av_freep(&dest->inter_matrix);
- av_freep(&dest->extradata);
- av_freep(&dest->subtitle_header);
- dest->subtitle_header_size = 0;
- dest->extradata_size = 0;
- av_opt_free(dest);
- return AVERROR(ENOMEM);
-}
-
-const AVClass *avcodec_get_class(void)
-{
- return &av_codec_context_class;
-}
-
-#define FOFFSET(x) offsetof(AVFrame,x)
-
-static const AVOption frame_options[]={
-{"best_effort_timestamp", "", FOFFSET(best_effort_timestamp), AV_OPT_TYPE_INT64, {.i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, 0},
-{"pkt_pos", "", FOFFSET(pkt_pos), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0},
-{"pkt_size", "", FOFFSET(pkt_size), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0},
-{"sample_aspect_ratio", "", FOFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0},
-{"width", "", FOFFSET(width), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
-{"height", "", FOFFSET(height), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
-{"format", "", FOFFSET(format), AV_OPT_TYPE_INT, {.i64 = -1 }, 0, INT_MAX, 0},
-{"channel_layout", "", FOFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, 0},
-{"sample_rate", "", FOFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
-{NULL},
-};
-
-static const AVClass av_frame_class = {
- .class_name = "AVFrame",
- .item_name = NULL,
- .option = frame_options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-const AVClass *avcodec_get_frame_class(void)
-{
- return &av_frame_class;
-}
-
-#define SROFFSET(x) offsetof(AVSubtitleRect,x)
-
-static const AVOption subtitle_rect_options[]={
-{"x", "", SROFFSET(x), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
-{"y", "", SROFFSET(y), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
-{"w", "", SROFFSET(w), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
-{"h", "", SROFFSET(h), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
-{"type", "", SROFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
-{"flags", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0, "flags"},
-{"forced", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0},
-{NULL},
-};
-
-static const AVClass av_subtitle_rect_class = {
- .class_name = "AVSubtitleRect",
- .item_name = NULL,
- .option = subtitle_rect_options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-const AVClass *avcodec_get_subtitle_rect_class(void)
-{
- return &av_subtitle_rect_class;
-}
-
-#ifdef TEST
-static int dummy_init(AVCodecContext *ctx)
-{
- //TODO: this code should set every possible pointer that could be set by codec and is not an option;
- ctx->extradata_size = 8;
- ctx->extradata = av_malloc(ctx->extradata_size);
- return 0;
-}
-
-static int dummy_close(AVCodecContext *ctx)
-{
- av_freep(&ctx->extradata);
- ctx->extradata_size = 0;
- return 0;
-}
-
-static int dummy_encode(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
-{
- return AVERROR(ENOSYS);
-}
-
-typedef struct Dummy12Context {
- AVClass *av_class;
- int num;
- char* str;
-} Dummy12Context;
-
-typedef struct Dummy3Context {
- void *fake_av_class;
- int num;
- char* str;
-} Dummy3Context;
-
-#define OFFSET(x) offsetof(Dummy12Context, x)
-#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
-static const AVOption dummy_options[] = {
- { "str", "set str", OFFSET(str), AV_OPT_TYPE_STRING, { .str = "i'm src default value" }, 0, 0, VE},
- { "num", "set num", OFFSET(num), AV_OPT_TYPE_INT, { .i64 = 1500100900 }, 0, INT_MAX, VE},
- { NULL },
-};
-
-static const AVClass dummy_v1_class = {
- .class_name = "dummy_v1_class",
- .item_name = av_default_item_name,
- .option = dummy_options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-static const AVClass dummy_v2_class = {
- .class_name = "dummy_v2_class",
- .item_name = av_default_item_name,
- .option = dummy_options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-/* codec with options */
-static AVCodec dummy_v1_encoder = {
- .name = "dummy_v1_codec",
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_NONE - 1,
- .encode2 = dummy_encode,
- .init = dummy_init,
- .close = dummy_close,
- .priv_class = &dummy_v1_class,
- .priv_data_size = sizeof(Dummy12Context),
-};
-
-/* codec with options, different class */
-static AVCodec dummy_v2_encoder = {
- .name = "dummy_v2_codec",
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_NONE - 2,
- .encode2 = dummy_encode,
- .init = dummy_init,
- .close = dummy_close,
- .priv_class = &dummy_v2_class,
- .priv_data_size = sizeof(Dummy12Context),
-};
-
-/* codec with priv data, but no class */
-static AVCodec dummy_v3_encoder = {
- .name = "dummy_v3_codec",
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_NONE - 3,
- .encode2 = dummy_encode,
- .init = dummy_init,
- .close = dummy_close,
- .priv_data_size = sizeof(Dummy3Context),
-};
-
-/* codec without priv data */
-static AVCodec dummy_v4_encoder = {
- .name = "dummy_v4_codec",
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_NONE - 4,
- .encode2 = dummy_encode,
- .init = dummy_init,
- .close = dummy_close,
-};
-
-static void test_copy_print_codec(const AVCodecContext *ctx)
-{
- printf("%-14s: %dx%d prv: %s",
- ctx->codec ? ctx->codec->name : "NULL",
- ctx->width, ctx->height,
- ctx->priv_data ? "set" : "null");
- if (ctx->codec && ctx->codec->priv_class && ctx->codec->priv_data_size) {
- int64_t i64;
- char *str = NULL;
- av_opt_get_int(ctx->priv_data, "num", 0, &i64);
- av_opt_get(ctx->priv_data, "str", 0, (uint8_t**)&str);
- printf(" opts: %"PRId64" %s", i64, str);
- av_free(str);
- }
- printf("\n");
-}
-
-static void test_copy(const AVCodec *c1, const AVCodec *c2)
-{
- AVCodecContext *ctx1, *ctx2;
- printf("%s -> %s\nclosed:\n", c1 ? c1->name : "NULL", c2 ? c2->name : "NULL");
- ctx1 = avcodec_alloc_context3(c1);
- ctx2 = avcodec_alloc_context3(c2);
- ctx1->width = ctx1->height = 128;
- if (ctx2->codec && ctx2->codec->priv_class && ctx2->codec->priv_data_size) {
- av_opt_set(ctx2->priv_data, "num", "667", 0);
- av_opt_set(ctx2->priv_data, "str", "i'm dest value before copy", 0);
- }
- avcodec_copy_context(ctx2, ctx1);
- test_copy_print_codec(ctx1);
- test_copy_print_codec(ctx2);
- if (ctx1->codec) {
- printf("opened:\n");
- avcodec_open2(ctx1, ctx1->codec, NULL);
- if (ctx2->codec && ctx2->codec->priv_class && ctx2->codec->priv_data_size) {
- av_opt_set(ctx2->priv_data, "num", "667", 0);
- av_opt_set(ctx2->priv_data, "str", "i'm dest value before copy", 0);
- }
- avcodec_copy_context(ctx2, ctx1);
- test_copy_print_codec(ctx1);
- test_copy_print_codec(ctx2);
- avcodec_close(ctx1);
- }
- avcodec_free_context(&ctx1);
- avcodec_free_context(&ctx2);
-}
-
-int main(void)
-{
- AVCodec *dummy_codec[] = {
- &dummy_v1_encoder,
- &dummy_v2_encoder,
- &dummy_v3_encoder,
- &dummy_v4_encoder,
- NULL,
- };
- int i, j;
-
- for (i = 0; dummy_codec[i]; i++)
- avcodec_register(dummy_codec[i]);
-
- printf("testing avcodec_copy_context()\n");
- for (i = 0; i < FF_ARRAY_ELEMS(dummy_codec); i++)
- for (j = 0; j < FF_ARRAY_ELEMS(dummy_codec); j++)
- test_copy(dummy_codec[i], dummy_codec[j]);
- return 0;
-}
-#endif
diff --git a/ffmpeg-2-8-11/libavcodec/opus_silk.c b/ffmpeg-2-8-11/libavcodec/opus_silk.c
deleted file mode 100644
index 73526f9..0000000
--- a/ffmpeg-2-8-11/libavcodec/opus_silk.c
+++ /dev/null
@@ -1,1597 +0,0 @@
-/*
- * Copyright (c) 2012 Andrew D'Addesio
- * Copyright (c) 2013-2014 Mozilla 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 FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * Opus SILK decoder
- */
-
-#include <stdint.h>
-
-#include "opus.h"
-
-typedef struct SilkFrame {
- int coded;
- int log_gain;
- int16_t nlsf[16];
- float lpc[16];
-
- float output [2 * SILK_HISTORY];
- float lpc_history[2 * SILK_HISTORY];
- int primarylag;
-
- int prev_voiced;
-} SilkFrame;
-
-struct SilkContext {
- AVCodecContext *avctx;
- int output_channels;
-
- int midonly;
- int subframes;
- int sflength;
- int flength;
- int nlsf_interp_factor;
-
- enum OpusBandwidth bandwidth;
- int wb;
-
- SilkFrame frame[2];
- float prev_stereo_weights[2];
- float stereo_weights[2];
-
- int prev_coded_channels;
-};
-
-static const uint16_t silk_model_stereo_s1[] = {
- 256, 7, 9, 10, 11, 12, 22, 46, 54, 55, 56, 59, 82, 174, 197, 200,
- 201, 202, 210, 234, 244, 245, 246, 247, 249, 256
-};
-
-static const uint16_t silk_model_stereo_s2[] = {256, 85, 171, 256};
-
-static const uint16_t silk_model_stereo_s3[] = {256, 51, 102, 154, 205, 256};
-
-static const uint16_t silk_model_mid_only[] = {256, 192, 256};
-
-static const uint16_t silk_model_frame_type_inactive[] = {256, 26, 256};
-
-static const uint16_t silk_model_frame_type_active[] = {256, 24, 98, 246, 256};
-
-static const uint16_t silk_model_gain_highbits[3][9] = {
- {256, 32, 144, 212, 241, 253, 254, 255, 256},
- {256, 2, 19, 64, 124, 186, 233, 252, 256},
- {256, 1, 4, 30, 101, 195, 245, 254, 256}
-};
-
-static const uint16_t silk_model_gain_lowbits[] = {256, 32, 64, 96, 128, 160, 192, 224, 256};
-
-static const uint16_t silk_model_gain_delta[] = {
- 256, 6, 11, 22, 53, 185, 206, 214, 218, 221, 223, 225, 227, 228, 229, 230,
- 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
- 247, 248, 249, 250, 251, 252, 253, 254, 255, 256
-};
-static const uint16_t silk_model_lsf_s1[2][2][33] = {
- {
- { // NB or MB, unvoiced
- 256, 44, 78, 108, 127, 148, 160, 171, 174, 177, 179, 195, 197, 199, 200, 205,
- 207, 208, 211, 214, 215, 216, 218, 220, 222, 225, 226, 235, 244, 246, 253, 255, 256
- }, { // NB or MB, voiced
- 256, 1, 11, 12, 20, 23, 31, 39, 53, 66, 80, 81, 95, 107, 120, 131,
- 142, 154, 165, 175, 185, 196, 204, 213, 221, 228, 236, 237, 238, 244, 245, 251, 256
- }
- }, {
- { // WB, unvoiced
- 256, 31, 52, 55, 72, 73, 81, 98, 102, 103, 121, 137, 141, 143, 146, 147,
- 157, 158, 161, 177, 188, 204, 206, 208, 211, 213, 224, 225, 229, 238, 246, 253, 256
- }, { // WB, voiced
- 256, 1, 5, 21, 26, 44, 55, 60, 74, 89, 90, 93, 105, 118, 132, 146,
- 152, 166, 178, 180, 186, 187, 199, 211, 222, 232, 235, 245, 250, 251, 252, 253, 256
- }
- }
-};
-
-static const uint16_t silk_model_lsf_s2[32][10] = {
- // NB, MB
- { 256, 1, 2, 3, 18, 242, 253, 254, 255, 256 },
- { 256, 1, 2, 4, 38, 221, 253, 254, 255, 256 },
- { 256, 1, 2, 6, 48, 197, 252, 254, 255, 256 },
- { 256, 1, 2, 10, 62, 185, 246, 254, 255, 256 },
- { 256, 1, 4, 20, 73, 174, 248, 254, 255, 256 },
- { 256, 1, 4, 21, 76, 166, 239, 254, 255, 256 },
- { 256, 1, 8, 32, 85, 159, 226, 252, 255, 256 },
- { 256, 1, 2, 20, 83, 161, 219, 249, 255, 256 },
-
- // WB
- { 256, 1, 2, 3, 12, 244, 253, 254, 255, 256 },
- { 256, 1, 2, 4, 32, 218, 253, 254, 255, 256 },
- { 256, 1, 2, 5, 47, 199, 252, 254, 255, 256 },
- { 256, 1, 2, 12, 61, 187, 252, 254, 255, 256 },
- { 256, 1, 5, 24, 72, 172, 249, 254, 255, 256 },
- { 256, 1, 2, 16, 70, 170, 242, 254, 255, 256 },
- { 256, 1, 2, 17, 78, 165, 226, 251, 255, 256 },
- { 256, 1, 8, 29, 79, 156, 237, 254, 255, 256 }
-};
-
-static const uint16_t silk_model_lsf_s2_ext[] = { 256, 156, 216, 240, 249, 253, 255, 256 };
-
-static const uint16_t silk_model_lsf_interpolation_offset[] = { 256, 13, 35, 64, 75, 256 };
-
-static const uint16_t silk_model_pitch_highbits[] = {
- 256, 3, 6, 12, 23, 44, 74, 106, 125, 136, 146, 158, 171, 184, 196, 207,
- 216, 224, 231, 237, 241, 243, 245, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256
-};
-
-static const uint16_t silk_model_pitch_lowbits_nb[]= { 256, 64, 128, 192, 256 };
-
-static const uint16_t silk_model_pitch_lowbits_mb[]= { 256, 43, 85, 128, 171, 213, 256 };
-
-static const uint16_t silk_model_pitch_lowbits_wb[]= { 256, 32, 64, 96, 128, 160, 192, 224, 256 };
-
-static const uint16_t silk_model_pitch_delta[] = {
- 256, 46, 48, 50, 53, 57, 63, 73, 88, 114, 152, 182, 204, 219, 229, 236,
- 242, 246, 250, 252, 254, 256
-};
-
-static const uint16_t silk_model_pitch_contour_nb10ms[] = { 256, 143, 193, 256 };
-
-static const uint16_t silk_model_pitch_contour_nb20ms[] = {
- 256, 68, 80, 101, 118, 137, 159, 189, 213, 230, 246, 256
-};
-
-static const uint16_t silk_model_pitch_contour_mbwb10ms[] = {
- 256, 91, 137, 176, 195, 209, 221, 229, 236, 242, 247, 252, 256
-};
-
-static const uint16_t silk_model_pitch_contour_mbwb20ms[] = {
- 256, 33, 55, 73, 89, 104, 118, 132, 145, 158, 168, 177, 186, 194, 200, 206,
- 212, 217, 221, 225, 229, 232, 235, 238, 240, 242, 244, 246, 248, 250, 252, 253,
- 254, 255, 256
-};
-
-static const uint16_t silk_model_ltp_filter[] = { 256, 77, 157, 256 };
-
-static const uint16_t silk_model_ltp_filter0_sel[] = {
- 256, 185, 200, 213, 226, 235, 244, 250, 256
-};
-
-static const uint16_t silk_model_ltp_filter1_sel[] = {
- 256, 57, 91, 112, 132, 147, 160, 172, 185, 195, 205, 214, 224, 233, 241, 248, 256
-};
-
-static const uint16_t silk_model_ltp_filter2_sel[] = {
- 256, 15, 31, 45, 57, 69, 81, 92, 103, 114, 124, 133, 142, 151, 160, 168,
- 176, 184, 192, 199, 206, 212, 218, 223, 227, 232, 236, 240, 244, 247, 251, 254, 256
-};
-
-static const uint16_t silk_model_ltp_scale_index[] = { 256, 128, 192, 256 };
-
-static const uint16_t silk_model_lcg_seed[] = { 256, 64, 128, 192, 256 };
-
-static const uint16_t silk_model_exc_rate[2][10] = {
- { 256, 15, 66, 78, 124, 169, 182, 215, 242, 256 }, // unvoiced
- { 256, 33, 63, 99, 116, 150, 199, 217, 238, 256 } // voiced
-};
-
-static const uint16_t silk_model_pulse_count[11][19] = {
- { 256, 131, 205, 230, 238, 241, 244, 245, 246,
- 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 },
- { 256, 58, 151, 211, 234, 241, 244, 245, 246,
- 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 },
- { 256, 43, 94, 140, 173, 197, 213, 224, 232,
- 238, 241, 244, 247, 249, 250, 251, 253, 254, 256 },
- { 256, 17, 69, 140, 197, 228, 240, 245, 246,
- 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 },
- { 256, 6, 27, 68, 121, 170, 205, 226, 237,
- 243, 246, 248, 250, 251, 252, 253, 254, 255, 256 },
- { 256, 7, 21, 43, 71, 100, 128, 153, 173,
- 190, 203, 214, 223, 230, 235, 239, 243, 246, 256 },
- { 256, 2, 7, 21, 50, 92, 138, 179, 210,
- 229, 240, 246, 249, 251, 252, 253, 254, 255, 256 },
- { 256, 1, 3, 7, 17, 36, 65, 100, 137,
- 171, 199, 219, 233, 241, 246, 250, 252, 254, 256 },
- { 256, 1, 3, 5, 10, 19, 33, 53, 77,
- 104, 132, 158, 181, 201, 216, 227, 235, 241, 256 },
- { 256, 1, 2, 3, 9, 36, 94, 150, 189,
- 214, 228, 238, 244, 247, 250, 252, 253, 254, 256 },
- { 256, 2, 3, 9, 36, 94, 150, 189, 214,
- 228, 238, 244, 247, 250, 252, 253, 254, 256, 256 }
-};
-
-static const uint16_t silk_model_pulse_location[4][168] = {
- {
- 256, 126, 256,
- 256, 56, 198, 256,
- 256, 25, 126, 230, 256,
- 256, 12, 72, 180, 244, 256,
- 256, 7, 42, 126, 213, 250, 256,
- 256, 4, 24, 83, 169, 232, 253, 256,
- 256, 3, 15, 53, 125, 200, 242, 254, 256,
- 256, 2, 10, 35, 89, 162, 221, 248, 255, 256,
- 256, 2, 7, 24, 63, 126, 191, 233, 251, 255, 256,
- 256, 1, 5, 17, 45, 94, 157, 211, 241, 252, 255, 256,
- 256, 1, 5, 13, 33, 70, 125, 182, 223, 245, 253, 255, 256,
- 256, 1, 4, 11, 26, 54, 98, 151, 199, 232, 248, 254, 255, 256,
- 256, 1, 3, 9, 21, 42, 77, 124, 172, 212, 237, 249, 254, 255, 256,
- 256, 1, 2, 6, 16, 33, 60, 97, 144, 187, 220, 241, 250, 254, 255, 256,
- 256, 1, 2, 3, 11, 25, 47, 80, 120, 163, 201, 229, 245, 253, 254, 255, 256,
- 256, 1, 2, 3, 4, 17, 35, 62, 98, 139, 180, 214, 238, 252, 253, 254, 255, 256
- },{
- 256, 127, 256,
- 256, 53, 202, 256,
- 256, 22, 127, 233, 256,
- 256, 11, 72, 183, 246, 256,
- 256, 6, 41, 127, 215, 251, 256,
- 256, 4, 24, 83, 170, 232, 253, 256,
- 256, 3, 16, 56, 127, 200, 241, 254, 256,
- 256, 3, 12, 39, 92, 162, 218, 246, 255, 256,
- 256, 3, 11, 30, 67, 124, 185, 229, 249, 255, 256,
- 256, 3, 10, 25, 53, 97, 151, 200, 233, 250, 255, 256,
- 256, 1, 8, 21, 43, 77, 123, 171, 209, 237, 251, 255, 256,
- 256, 1, 2, 13, 35, 62, 97, 139, 186, 219, 244, 254, 255, 256,
- 256, 1, 2, 8, 22, 48, 85, 128, 171, 208, 234, 248, 254, 255, 256,
- 256, 1, 2, 6, 16, 36, 67, 107, 149, 189, 220, 240, 250, 254, 255, 256,
- 256, 1, 2, 5, 13, 29, 55, 90, 128, 166, 201, 227, 243, 251, 254, 255, 256,
- 256, 1, 2, 4, 10, 22, 43, 73, 109, 147, 183, 213, 234, 246, 252, 254, 255, 256
- },{
- 256, 127, 256,
- 256, 49, 206, 256,
- 256, 20, 127, 236, 256,
- 256, 11, 71, 184, 246, 256,
- 256, 7, 43, 127, 214, 250, 256,
- 256, 6, 30, 87, 169, 229, 252, 256,
- 256, 5, 23, 62, 126, 194, 236, 252, 256,
- 256, 6, 20, 49, 96, 157, 209, 239, 253, 256,
- 256, 1, 16, 39, 74, 125, 175, 215, 245, 255, 256,
- 256, 1, 2, 23, 55, 97, 149, 195, 236, 254, 255, 256,
- 256, 1, 7, 23, 50, 86, 128, 170, 206, 233, 249, 255, 256,
- 256, 1, 6, 18, 39, 70, 108, 148, 186, 217, 238, 250, 255, 256,
- 256, 1, 4, 13, 30, 56, 90, 128, 166, 200, 226, 243, 252, 255, 256,
- 256, 1, 4, 11, 25, 47, 76, 110, 146, 180, 209, 231, 245, 252, 255, 256,
- 256, 1, 3, 8, 19, 37, 62, 93, 128, 163, 194, 219, 237, 248, 253, 255, 256,
- 256, 1, 2, 6, 15, 30, 51, 79, 111, 145, 177, 205, 226, 241, 250, 254, 255, 256
- },{
- 256, 128, 256,
- 256, 42, 214, 256,
- 256, 21, 128, 235, 256,
- 256, 12, 72, 184, 245, 256,
- 256, 8, 42, 128, 214, 249, 256,
- 256, 8, 31, 86, 176, 231, 251, 256,
- 256, 5, 20, 58, 130, 202, 238, 253, 256,
- 256, 6, 18, 45, 97, 174, 221, 241, 251, 256,
- 256, 6, 25, 53, 88, 128, 168, 203, 231, 250, 256,
- 256, 4, 18, 40, 71, 108, 148, 185, 216, 238, 252, 256,
- 256, 3, 13, 31, 57, 90, 128, 166, 199, 225, 243, 253, 256,
- 256, 2, 10, 23, 44, 73, 109, 147, 183, 212, 233, 246, 254, 256,
- 256, 1, 6, 16, 33, 58, 90, 128, 166, 198, 223, 240, 250, 255, 256,
- 256, 1, 5, 12, 25, 46, 75, 110, 146, 181, 210, 231, 244, 251, 255, 256,
- 256, 1, 3, 8, 18, 35, 60, 92, 128, 164, 196, 221, 238, 248, 253, 255, 256,
- 256, 1, 3, 7, 14, 27, 48, 76, 110, 146, 180, 208, 229, 242, 249, 253, 255, 256
- }
-};
-
-static const uint16_t silk_model_excitation_lsb[] = {256, 136, 256};
-
-static const uint16_t silk_model_excitation_sign[3][2][7][3] = {
- { // Inactive
- { // Low offset
- {256, 2, 256},
- {256, 207, 256},
- {256, 189, 256},
- {256, 179, 256},
- {256, 174, 256},
- {256, 163, 256},
- {256, 157, 256}
- }, { // High offset
- {256, 58, 256},
- {256, 245, 256},
- {256, 238, 256},
- {256, 232, 256},
- {256, 225, 256},
- {256, 220, 256},
- {256, 211, 256}
- }
- }, { // Unvoiced
- { // Low offset
- {256, 1, 256},
- {256, 210, 256},
- {256, 190, 256},
- {256, 178, 256},
- {256, 169, 256},
- {256, 162, 256},
- {256, 152, 256}
- }, { // High offset
- {256, 48, 256},
- {256, 242, 256},
- {256, 235, 256},
- {256, 224, 256},
- {256, 214, 256},
- {256, 205, 256},
- {256, 190, 256}
- }
- }, { // Voiced
- { // Low offset
- {256, 1, 256},
- {256, 162, 256},
- {256, 152, 256},
- {256, 147, 256},
- {256, 144, 256},
- {256, 141, 256},
- {256, 138, 256}
- }, { // High offset
- {256, 8, 256},
- {256, 203, 256},
- {256, 187, 256},
- {256, 176, 256},
- {256, 168, 256},
- {256, 161, 256},
- {256, 154, 256}
- }
- }
-};
-
-static const int16_t silk_stereo_weights[] = {
- -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820,
- 820, 2950, 5000, 6500, 7526, 8266, 10050, 13732
-};
-
-static const uint8_t silk_lsf_s2_model_sel_nbmb[32][10] = {
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 1, 3, 1, 2, 2, 1, 2, 1, 1, 1 },
- { 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
- { 1, 2, 2, 2, 2, 1, 2, 1, 1, 1 },
- { 2, 3, 3, 3, 3, 2, 2, 2, 2, 2 },
- { 0, 5, 3, 3, 2, 2, 2, 2, 1, 1 },
- { 0, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
- { 2, 3, 6, 4, 4, 4, 5, 4, 5, 5 },
- { 2, 4, 5, 5, 4, 5, 4, 6, 4, 4 },
- { 2, 4, 4, 7, 4, 5, 4, 5, 5, 4 },
- { 4, 3, 3, 3, 2, 3, 2, 2, 2, 2 },
- { 1, 5, 5, 6, 4, 5, 4, 5, 5, 5 },
- { 2, 7, 4, 6, 5, 5, 5, 5, 5, 5 },
- { 2, 7, 5, 5, 5, 5, 5, 6, 5, 4 },
- { 3, 3, 5, 4, 4, 5, 4, 5, 4, 4 },
- { 2, 3, 3, 5, 5, 4, 4, 4, 4, 4 },
- { 2, 4, 4, 6, 4, 5, 4, 5, 5, 5 },
- { 2, 5, 4, 6, 5, 5, 5, 4, 5, 4 },
- { 2, 7, 4, 5, 4, 5, 4, 5, 5, 5 },
- { 2, 5, 4, 6, 7, 6, 5, 6, 5, 4 },
- { 3, 6, 7, 4, 6, 5, 5, 6, 4, 5 },
- { 2, 7, 6, 4, 4, 4, 5, 4, 5, 5 },
- { 4, 5, 5, 4, 6, 6, 5, 6, 5, 4 },
- { 2, 5, 5, 6, 5, 6, 4, 6, 4, 4 },
- { 4, 5, 5, 5, 3, 7, 4, 5, 5, 4 },
- { 2, 3, 4, 5, 5, 6, 4, 5, 5, 4 },
- { 2, 3, 2, 3, 3, 4, 2, 3, 3, 3 },
- { 1, 1, 2, 2, 2, 2, 2, 3, 2, 2 },
- { 4, 5, 5, 6, 6, 6, 5, 6, 4, 5 },
- { 3, 5, 5, 4, 4, 4, 4, 3, 3, 2 },
- { 2, 5, 3, 7, 5, 5, 4, 4, 5, 4 },
- { 4, 4, 5, 4, 5, 6, 5, 6, 5, 4 }
-};
-
-static const uint8_t silk_lsf_s2_model_sel_wb[32][16] = {
- { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 },
- { 10, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 8, 11 },
- { 10, 13, 13, 11, 15, 12, 12, 13, 10, 13, 12, 13, 13, 12, 11, 11 },
- { 8, 10, 9, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9 },
- { 8, 14, 13, 12, 14, 12, 15, 13, 12, 12, 12, 13, 13, 12, 12, 11 },
- { 8, 11, 13, 13, 12, 11, 11, 13, 11, 11, 11, 11, 11, 11, 10, 12 },
- { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 },
- { 8, 10, 14, 11, 15, 10, 13, 11, 12, 13, 13, 12, 11, 11, 10, 11 },
- { 8, 14, 10, 14, 14, 12, 13, 12, 14, 13, 12, 12, 13, 11, 11, 11 },
- { 10, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 },
- { 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9 },
- { 10, 10, 11, 12, 13, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 11 },
- { 10, 10, 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, 11, 10, 9, 11 },
- { 11, 12, 12, 12, 14, 12, 12, 13, 11, 13, 12, 12, 13, 12, 11, 12 },
- { 8, 14, 12, 13, 12, 15, 13, 10, 14, 13, 15, 12, 12, 11, 13, 11 },
- { 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 9, 8 },
- { 9, 14, 13, 15, 13, 12, 13, 11, 12, 13, 12, 12, 12, 11, 11, 12 },
- { 9, 11, 11, 12, 12, 11, 11, 13, 10, 11, 11, 13, 13, 13, 11, 12 },
- { 10, 11, 11, 10, 10, 10, 11, 10, 9, 10, 9, 10, 9, 9, 9, 12 },
- { 8, 10, 11, 13, 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 8 },
- { 11, 12, 11, 13, 11, 11, 10, 10, 9, 9, 9, 9, 9, 10, 10, 12 },
- { 10, 14, 11, 15, 15, 12, 13, 12, 13, 11, 13, 11, 11, 10, 11, 11 },
- { 10, 11, 13, 14, 14, 11, 13, 11, 12, 12, 11, 11, 11, 11, 10, 12 },
- { 9, 11, 11, 12, 12, 12, 12, 11, 13, 13, 13, 11, 9, 9, 9, 9 },
- { 10, 13, 11, 14, 14, 12, 15, 12, 12, 13, 11, 12, 12, 11, 11, 11 },
- { 8, 14, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 },
- { 8, 14, 14, 11, 13, 10, 13, 13, 11, 12, 12, 15, 15, 12, 12, 12 },
- { 11, 11, 15, 11, 13, 12, 11, 11, 11, 10, 10, 11, 11, 11, 10, 11 },
- { 8, 8, 9, 8, 8, 8, 10, 9, 10, 9, 9, 10, 10, 10, 9, 9 },
- { 8, 11, 10, 13, 11, 11, 10, 11, 10, 9, 8, 8, 9, 8, 8, 9 },
- { 11, 13, 13, 12, 15, 13, 11, 11, 10, 11, 10, 10, 9, 8, 9, 8 },
- { 10, 11, 13, 11, 12, 11, 11, 11, 10, 9, 10, 14, 12, 8, 8, 8 }
-};
-
-static const uint8_t silk_lsf_pred_weights_nbmb[2][9] = {
- {179, 138, 140, 148, 151, 149, 153, 151, 163},
- {116, 67, 82, 59, 92, 72, 100, 89, 92}
-};
-
-static const uint8_t silk_lsf_pred_weights_wb[2][15] = {
- {175, 148, 160, 176, 178, 173, 174, 164, 177, 174, 196, 182, 198, 192, 182},
- { 68, 62, 66, 60, 72, 117, 85, 90, 118, 136, 151, 142, 160, 142, 155}
-};
-
-static const uint8_t silk_lsf_weight_sel_nbmb[32][9] = {
- { 0, 1, 0, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 1, 1, 1, 0, 0, 0, 0, 1, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 1, 1, 0, 0, 0, 1, 0 },
- { 0, 1, 1, 0, 0, 1, 1, 0, 0 },
- { 0, 0, 1, 1, 0, 1, 0, 1, 1 },
- { 0, 0, 1, 1, 0, 0, 1, 1, 1 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 1, 1, 1, 1, 1, 0 },
- { 0, 1, 0, 1, 1, 1, 1, 1, 0 },
- { 0, 1, 1, 1, 1, 1, 1, 1, 0 },
- { 1, 0, 1, 1, 0, 1, 1, 1, 1 },
- { 0, 1, 1, 1, 1, 1, 0, 1, 0 },
- { 0, 0, 1, 1, 0, 1, 0, 1, 0 },
- { 0, 0, 1, 1, 1, 0, 1, 1, 1 },
- { 0, 1, 1, 0, 0, 1, 1, 1, 0 },
- { 0, 0, 0, 1, 1, 1, 0, 1, 0 },
- { 0, 1, 1, 0, 0, 1, 0, 1, 0 },
- { 0, 1, 1, 0, 0, 0, 1, 1, 0 },
- { 0, 0, 0, 0, 0, 1, 1, 1, 1 },
- { 0, 0, 1, 1, 0, 0, 0, 1, 1 },
- { 0, 0, 0, 1, 0, 1, 1, 1, 1 },
- { 0, 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, 1, 0, 1, 1, 0, 1, 0 },
- { 1, 0, 0, 1, 0, 0, 0, 0, 0 },
- { 0, 0, 0, 1, 1, 0, 1, 0, 1 },
- { 1, 0, 1, 1, 0, 1, 1, 1, 1 }
-};
-
-static const uint8_t silk_lsf_weight_sel_wb[32][15] = {
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
- { 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 },
- { 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1 },
- { 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
- { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0 },
- { 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
- { 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0 },
- { 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 },
- { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
- { 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0 },
- { 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
- { 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0 },
- { 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
- { 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0 },
- { 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
- { 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1 },
- { 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
- { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
- { 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0 }
-};
-
-static const uint8_t silk_lsf_codebook_nbmb[32][10] = {
- { 12, 35, 60, 83, 108, 132, 157, 180, 206, 228 },
- { 15, 32, 55, 77, 101, 125, 151, 175, 201, 225 },
- { 19, 42, 66, 89, 114, 137, 162, 184, 209, 230 },
- { 12, 25, 50, 72, 97, 120, 147, 172, 200, 223 },
- { 26, 44, 69, 90, 114, 135, 159, 180, 205, 225 },
- { 13, 22, 53, 80, 106, 130, 156, 180, 205, 228 },
- { 15, 25, 44, 64, 90, 115, 142, 168, 196, 222 },
- { 19, 24, 62, 82, 100, 120, 145, 168, 190, 214 },
- { 22, 31, 50, 79, 103, 120, 151, 170, 203, 227 },
- { 21, 29, 45, 65, 106, 124, 150, 171, 196, 224 },
- { 30, 49, 75, 97, 121, 142, 165, 186, 209, 229 },
- { 19, 25, 52, 70, 93, 116, 143, 166, 192, 219 },
- { 26, 34, 62, 75, 97, 118, 145, 167, 194, 217 },
- { 25, 33, 56, 70, 91, 113, 143, 165, 196, 223 },
- { 21, 34, 51, 72, 97, 117, 145, 171, 196, 222 },
- { 20, 29, 50, 67, 90, 117, 144, 168, 197, 221 },
- { 22, 31, 48, 66, 95, 117, 146, 168, 196, 222 },
- { 24, 33, 51, 77, 116, 134, 158, 180, 200, 224 },
- { 21, 28, 70, 87, 106, 124, 149, 170, 194, 217 },
- { 26, 33, 53, 64, 83, 117, 152, 173, 204, 225 },
- { 27, 34, 65, 95, 108, 129, 155, 174, 210, 225 },
- { 20, 26, 72, 99, 113, 131, 154, 176, 200, 219 },
- { 34, 43, 61, 78, 93, 114, 155, 177, 205, 229 },
- { 23, 29, 54, 97, 124, 138, 163, 179, 209, 229 },
- { 30, 38, 56, 89, 118, 129, 158, 178, 200, 231 },
- { 21, 29, 49, 63, 85, 111, 142, 163, 193, 222 },
- { 27, 48, 77, 103, 133, 158, 179, 196, 215, 232 },
- { 29, 47, 74, 99, 124, 151, 176, 198, 220, 237 },
- { 33, 42, 61, 76, 93, 121, 155, 174, 207, 225 },
- { 29, 53, 87, 112, 136, 154, 170, 188, 208, 227 },
- { 24, 30, 52, 84, 131, 150, 166, 186, 203, 229 },
- { 37, 48, 64, 84, 104, 118, 156, 177, 201, 230 }
-};
-
-static const uint8_t silk_lsf_codebook_wb[32][16] = {
- { 7, 23, 38, 54, 69, 85, 100, 116, 131, 147, 162, 178, 193, 208, 223, 239 },
- { 13, 25, 41, 55, 69, 83, 98, 112, 127, 142, 157, 171, 187, 203, 220, 236 },
- { 15, 21, 34, 51, 61, 78, 92, 106, 126, 136, 152, 167, 185, 205, 225, 240 },
- { 10, 21, 36, 50, 63, 79, 95, 110, 126, 141, 157, 173, 189, 205, 221, 237 },
- { 17, 20, 37, 51, 59, 78, 89, 107, 123, 134, 150, 164, 184, 205, 224, 240 },
- { 10, 15, 32, 51, 67, 81, 96, 112, 129, 142, 158, 173, 189, 204, 220, 236 },
- { 8, 21, 37, 51, 65, 79, 98, 113, 126, 138, 155, 168, 179, 192, 209, 218 },
- { 12, 15, 34, 55, 63, 78, 87, 108, 118, 131, 148, 167, 185, 203, 219, 236 },
- { 16, 19, 32, 36, 56, 79, 91, 108, 118, 136, 154, 171, 186, 204, 220, 237 },
- { 11, 28, 43, 58, 74, 89, 105, 120, 135, 150, 165, 180, 196, 211, 226, 241 },
- { 6, 16, 33, 46, 60, 75, 92, 107, 123, 137, 156, 169, 185, 199, 214, 225 },
- { 11, 19, 30, 44, 57, 74, 89, 105, 121, 135, 152, 169, 186, 202, 218, 234 },
- { 12, 19, 29, 46, 57, 71, 88, 100, 120, 132, 148, 165, 182, 199, 216, 233 },
- { 17, 23, 35, 46, 56, 77, 92, 106, 123, 134, 152, 167, 185, 204, 222, 237 },
- { 14, 17, 45, 53, 63, 75, 89, 107, 115, 132, 151, 171, 188, 206, 221, 240 },
- { 9, 16, 29, 40, 56, 71, 88, 103, 119, 137, 154, 171, 189, 205, 222, 237 },
- { 16, 19, 36, 48, 57, 76, 87, 105, 118, 132, 150, 167, 185, 202, 218, 236 },
- { 12, 17, 29, 54, 71, 81, 94, 104, 126, 136, 149, 164, 182, 201, 221, 237 },
- { 15, 28, 47, 62, 79, 97, 115, 129, 142, 155, 168, 180, 194, 208, 223, 238 },
- { 8, 14, 30, 45, 62, 78, 94, 111, 127, 143, 159, 175, 192, 207, 223, 239 },
- { 17, 30, 49, 62, 79, 92, 107, 119, 132, 145, 160, 174, 190, 204, 220, 235 },
- { 14, 19, 36, 45, 61, 76, 91, 108, 121, 138, 154, 172, 189, 205, 222, 238 },
- { 12, 18, 31, 45, 60, 76, 91, 107, 123, 138, 154, 171, 187, 204, 221, 236 },
- { 13, 17, 31, 43, 53, 70, 83, 103, 114, 131, 149, 167, 185, 203, 220, 237 },
- { 17, 22, 35, 42, 58, 78, 93, 110, 125, 139, 155, 170, 188, 206, 224, 240 },
- { 8, 15, 34, 50, 67, 83, 99, 115, 131, 146, 162, 178, 193, 209, 224, 239 },
- { 13, 16, 41, 66, 73, 86, 95, 111, 128, 137, 150, 163, 183, 206, 225, 241 },
- { 17, 25, 37, 52, 63, 75, 92, 102, 119, 132, 144, 160, 175, 191, 212, 231 },
- { 19, 31, 49, 65, 83, 100, 117, 133, 147, 161, 174, 187, 200, 213, 227, 242 },
- { 18, 31, 52, 68, 88, 103, 117, 126, 138, 149, 163, 177, 192, 207, 223, 239 },
- { 16, 29, 47, 61, 76, 90, 106, 119, 133, 147, 161, 176, 193, 209, 224, 240 },
- { 15, 21, 35, 50, 61, 73, 86, 97, 110, 119, 129, 141, 175, 198, 218, 237 }
-};
-
-static const uint16_t silk_lsf_min_spacing_nbmb[] = {
- 250, 3, 6, 3, 3, 3, 4, 3, 3, 3, 461
-};
-
-static const uint16_t silk_lsf_min_spacing_wb[] = {
- 100, 3, 40, 3, 3, 3, 5, 14, 14, 10, 11, 3, 8, 9, 7, 3, 347
-};
-
-static const uint8_t silk_lsf_ordering_nbmb[] = {
- 0, 9, 6, 3, 4, 5, 8, 1, 2, 7
-};
-
-static const uint8_t silk_lsf_ordering_wb[] = {
- 0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1
-};
-
-static const int16_t silk_cosine[] = { /* (0.12) */
- 4096, 4095, 4091, 4085,
- 4076, 4065, 4052, 4036,
- 4017, 3997, 3973, 3948,
- 3920, 3889, 3857, 3822,
- 3784, 3745, 3703, 3659,
- 3613, 3564, 3513, 3461,
- 3406, 3349, 3290, 3229,
- 3166, 3102, 3035, 2967,
- 2896, 2824, 2751, 2676,
- 2599, 2520, 2440, 2359,
- 2276, 2191, 2106, 2019,
- 1931, 1842, 1751, 1660,
- 1568, 1474, 1380, 1285,
- 1189, 1093, 995, 897,
- 799, 700, 601, 501,
- 401, 301, 201, 101,
- 0, -101, -201, -301,
- -401, -501, -601, -700,
- -799, -897, -995, -1093,
- -1189, -1285, -1380, -1474,
- -1568, -1660, -1751, -1842,
- -1931, -2019, -2106, -2191,
- -2276, -2359, -2440, -2520,
- -2599, -2676, -2751, -2824,
- -2896, -2967, -3035, -3102,
- -3166, -3229, -3290, -3349,
- -3406, -3461, -3513, -3564,
- -3613, -3659, -3703, -3745,
- -3784, -3822, -3857, -3889,
- -3920, -3948, -3973, -3997,
- -4017, -4036, -4052, -4065,
- -4076, -4085, -4091, -4095,
- -4096
-};
-
-static const uint16_t silk_pitch_scale[] = { 4, 6, 8};
-
-static const uint16_t silk_pitch_min_lag[] = { 16, 24, 32};
-
-static const uint16_t silk_pitch_max_lag[] = {144, 216, 288};
-
-static const int8_t silk_pitch_offset_nb10ms[3][2] = {
- { 0, 0},
- { 1, 0},
- { 0, 1}
-};
-
-static const int8_t silk_pitch_offset_nb20ms[11][4] = {
- { 0, 0, 0, 0},
- { 2, 1, 0, -1},
- {-1, 0, 1, 2},
- {-1, 0, 0, 1},
- {-1, 0, 0, 0},
- { 0, 0, 0, 1},
- { 0, 0, 1, 1},
- { 1, 1, 0, 0},
- { 1, 0, 0, 0},
- { 0, 0, 0, -1},
- { 1, 0, 0, -1}
-};
-
-static const int8_t silk_pitch_offset_mbwb10ms[12][2] = {
- { 0, 0},
- { 0, 1},
- { 1, 0},
- {-1, 1},
- { 1, -1},
- {-1, 2},
- { 2, -1},
- {-2, 2},
- { 2, -2},
- {-2, 3},
- { 3, -2},
- {-3, 3}
-};
-
-static const int8_t silk_pitch_offset_mbwb20ms[34][4] = {
- { 0, 0, 0, 0},
- { 0, 0, 1, 1},
- { 1, 1, 0, 0},
- {-1, 0, 0, 0},
- { 0, 0, 0, 1},
- { 1, 0, 0, 0},
- {-1, 0, 0, 1},
- { 0, 0, 0, -1},
- {-1, 0, 1, 2},
- { 1, 0, 0, -1},
- {-2, -1, 1, 2},
- { 2, 1, 0, -1},
- {-2, 0, 0, 2},
- {-2, 0, 1, 3},
- { 2, 1, -1, -2},
- {-3, -1, 1, 3},
- { 2, 0, 0, -2},
- { 3, 1, 0, -2},
- {-3, -1, 2, 4},
- {-4, -1, 1, 4},
- { 3, 1, -1, -3},
- {-4, -1, 2, 5},
- { 4, 2, -1, -3},
- { 4, 1, -1, -4},
- {-5, -1, 2, 6},
- { 5, 2, -1, -4},
- {-6, -2, 2, 6},
- {-5, -2, 2, 5},
- { 6, 2, -1, -5},
- {-7, -2, 3, 8},
- { 6, 2, -2, -6},
- { 5, 2, -2, -5},
- { 8, 3, -2, -7},
- {-9, -3, 3, 9}
-};
-
-static const int8_t silk_ltp_filter0_taps[8][5] = {
- { 4, 6, 24, 7, 5},
- { 0, 0, 2, 0, 0},
- { 12, 28, 41, 13, -4},
- { -9, 15, 42, 25, 14},
- { 1, -2, 62, 41, -9},
- {-10, 37, 65, -4, 3},
- { -6, 4, 66, 7, -8},
- { 16, 14, 38, -3, 33}
-};
-
-static const int8_t silk_ltp_filter1_taps[16][5] = {
- { 13, 22, 39, 23, 12},
- { -1, 36, 64, 27, -6},
- { -7, 10, 55, 43, 17},
- { 1, 1, 8, 1, 1},
- { 6, -11, 74, 53, -9},
- {-12, 55, 76, -12, 8},
- { -3, 3, 93, 27, -4},
- { 26, 39, 59, 3, -8},
- { 2, 0, 77, 11, 9},
- { -8, 22, 44, -6, 7},
- { 40, 9, 26, 3, 9},
- { -7, 20, 101, -7, 4},
- { 3, -8, 42, 26, 0},
- {-15, 33, 68, 2, 23},
- { -2, 55, 46, -2, 15},
- { 3, -1, 21, 16, 41}
-};
-
-static const int8_t silk_ltp_filter2_taps[32][5] = {
- { -6, 27, 61, 39, 5},
- {-11, 42, 88, 4, 1},
- { -2, 60, 65, 6, -4},
- { -1, -5, 73, 56, 1},
- { -9, 19, 94, 29, -9},
- { 0, 12, 99, 6, 4},
- { 8, -19, 102, 46, -13},
- { 3, 2, 13, 3, 2},
- { 9, -21, 84, 72, -18},
- {-11, 46, 104, -22, 8},
- { 18, 38, 48, 23, 0},
- {-16, 70, 83, -21, 11},
- { 5, -11, 117, 22, -8},
- { -6, 23, 117, -12, 3},
- { 3, -8, 95, 28, 4},
- {-10, 15, 77, 60, -15},
- { -1, 4, 124, 2, -4},
- { 3, 38, 84, 24, -25},
- { 2, 13, 42, 13, 31},
- { 21, -4, 56, 46, -1},
- { -1, 35, 79, -13, 19},
- { -7, 65, 88, -9, -14},
- { 20, 4, 81, 49, -29},
- { 20, 0, 75, 3, -17},
- { 5, -9, 44, 92, -8},
- { 1, -3, 22, 69, 31},
- { -6, 95, 41, -12, 5},
- { 39, 67, 16, -4, 1},
- { 0, -6, 120, 55, -36},
- {-13, 44, 122, 4, -24},
- { 81, 5, 11, 3, 7},
- { 2, 0, 9, 10, 88}
-};
-
-static const uint16_t silk_ltp_scale_factor[] = {15565, 12288, 8192};
-
-static const uint8_t silk_shell_blocks[3][2] = {
- { 5, 10}, // NB
- { 8, 15}, // MB
- {10, 20} // WB
-};
-
-static const uint8_t silk_quant_offset[2][2] = { /* (0.23) */
- {25, 60}, // Inactive or Unvoiced
- { 8, 25} // Voiced
-};
-
-static const int silk_stereo_interp_len[3] = {
- 64, 96, 128
-};
-
-static inline void silk_stabilize_lsf(int16_t nlsf[16], int order, const uint16_t min_delta[17])
-{
- int pass, i;
- for (pass = 0; pass < 20; pass++) {
- int k, min_diff = 0;
- for (i = 0; i < order+1; i++) {
- int low = i != 0 ? nlsf[i-1] : 0;
- int high = i != order ? nlsf[i] : 32768;
- int diff = (high - low) - (min_delta[i]);
-
- if (diff < min_diff) {
- min_diff = diff;
- k = i;
-
- if (pass == 20)
- break;
- }
- }
- if (min_diff == 0) /* no issues; stabilized */
- return;
-
- /* wiggle one or two LSFs */
- if (k == 0) {
- /* repel away from lower bound */
- nlsf[0] = min_delta[0];
- } else if (k == order) {
- /* repel away from higher bound */
- nlsf[order-1] = 32768 - min_delta[order];
- } else {
- /* repel away from current position */
- int min_center = 0, max_center = 32768, center_val;
-
- /* lower extent */
- for (i = 0; i < k; i++)
- min_center += min_delta[i];
- min_center += min_delta[k] >> 1;
-
- /* upper extent */
- for (i = order; i > k; i--)
- max_center -= min_delta[i];
- max_center -= min_delta[k] >> 1;
-
- /* move apart */
- center_val = nlsf[k - 1] + nlsf[k];
- center_val = (center_val >> 1) + (center_val & 1); // rounded divide by 2
- center_val = FFMIN(max_center, FFMAX(min_center, center_val));
-
- nlsf[k - 1] = center_val - (min_delta[k] >> 1);
- nlsf[k] = nlsf[k - 1] + min_delta[k];
- }
- }
-
- /* resort to the fall-back method, the standard method for LSF stabilization */
-
- /* sort; as the LSFs should be nearly sorted, use insertion sort */
- for (i = 1; i < order; i++) {
- int j, value = nlsf[i];
- for (j = i - 1; j >= 0 && nlsf[j] > value; j--)
- nlsf[j + 1] = nlsf[j];
- nlsf[j + 1] = value;
- }
-
- /* push forwards to increase distance */
- if (nlsf[0] < min_delta[0])
- nlsf[0] = min_delta[0];
- for (i = 1; i < order; i++)
- if (nlsf[i] < nlsf[i - 1] + min_delta[i])
- nlsf[i] = nlsf[i - 1] + min_delta[i];
-
- /* push backwards to increase distance */
- if (nlsf[order-1] > 32768 - min_delta[order])
- nlsf[order-1] = 32768 - min_delta[order];
- for (i = order-2; i >= 0; i--)
- if (nlsf[i] > nlsf[i + 1] - min_delta[i+1])
- nlsf[i] = nlsf[i + 1] - min_delta[i+1];
-
- return;
-}
-
-static inline int silk_is_lpc_stable(const int16_t lpc[16], int order)
-{
- int k, j, DC_resp = 0;
- int32_t lpc32[2][16]; // Q24
- int totalinvgain = 1 << 30; // 1.0 in Q30
- int32_t *row = lpc32[0], *prevrow;
-
- /* initialize the first row for the Levinson recursion */
- for (k = 0; k < order; k++) {
- DC_resp += lpc[k];
- row[k] = lpc[k] * 4096;
- }
-
- if (DC_resp >= 4096)
- return 0;
-
- /* check if prediction gain pushes any coefficients too far */
- for (k = order - 1; 1; k--) {
- int rc; // Q31; reflection coefficient
- int gaindiv; // Q30; inverse of the gain (the divisor)
- int gain; // gain for this reflection coefficient
- int fbits; // fractional bits used for the gain
- int error; // Q29; estimate of the error of our partial estimate of 1/gaindiv
-
- if (FFABS(row[k]) > 16773022)
- return 0;
-
- rc = -(row[k] * 128);
- gaindiv = (1 << 30) - MULH(rc, rc);
-
- totalinvgain = MULH(totalinvgain, gaindiv) << 2;
- if (k == 0)
- return (totalinvgain >= 107374);
-
- /* approximate 1.0/gaindiv */
- fbits = opus_ilog(gaindiv);
- gain = ((1 << 29) - 1) / (gaindiv >> (fbits + 1 - 16)); // Q<fbits-16>
- error = (1 << 29) - MULL(gaindiv << (15 + 16 - fbits), gain, 16);
- gain = ((gain << 16) + (error * gain >> 13));
-
- /* switch to the next row of the LPC coefficients */
- prevrow = row;
- row = lpc32[k & 1];
-
- for (j = 0; j < k; j++) {
- int x = prevrow[j] - ROUND_MULL(prevrow[k - j - 1], rc, 31);
- row[j] = ROUND_MULL(x, gain, fbits);
- }
- }
-}
-
-static void silk_lsp2poly(const int32_t lsp[16], int32_t pol[16], int half_order)
-{
- int i, j;
-
- pol[0] = 65536; // 1.0 in Q16
- pol[1] = -lsp[0];
-
- for (i = 1; i < half_order; i++) {
- pol[i + 1] = pol[i - 1] * 2 - ROUND_MULL(lsp[2 * i], pol[i], 16);
- for (j = i; j > 1; j--)
- pol[j] += pol[j - 2] - ROUND_MULL(lsp[2 * i], pol[j - 1], 16);
-
- pol[1] -= lsp[2 * i];
- }
-}
-
-static void silk_lsf2lpc(const int16_t nlsf[16], float lpcf[16], int order)
-{
- int i, k;
- int32_t lsp[16]; // Q17; 2*cos(LSF)
- int32_t p[9], q[9]; // Q16
- int32_t lpc32[16]; // Q17
- int16_t lpc[16]; // Q12
-
- /* convert the LSFs to LSPs, i.e. 2*cos(LSF) */
- for (k = 0; k < order; k++) {
- int index = nlsf[k] >> 8;
- int offset = nlsf[k] & 255;
- int k2 = (order == 10) ? silk_lsf_ordering_nbmb[k] : silk_lsf_ordering_wb[k];
-
- /* interpolate and round */
- lsp[k2] = silk_cosine[index] * 256;
- lsp[k2] += (silk_cosine[index + 1] - silk_cosine[index]) * offset;
- lsp[k2] = (lsp[k2] + 4) >> 3;
- }
-
- silk_lsp2poly(lsp , p, order >> 1);
- silk_lsp2poly(lsp + 1, q, order >> 1);
-
- /* reconstruct A(z) */
- for (k = 0; k < order>>1; k++) {
- lpc32[k] = -p[k + 1] - p[k] - q[k + 1] + q[k];
- lpc32[order-k-1] = -p[k + 1] - p[k] + q[k + 1] - q[k];
- }
-
- /* limit the range of the LPC coefficients to each fit within an int16_t */
- for (i = 0; i < 10; i++) {
- int j;
- unsigned int maxabs = 0;
- for (j = 0, k = 0; j < order; j++) {
- unsigned int x = FFABS(lpc32[k]);
- if (x > maxabs) {
- maxabs = x; // Q17
- k = j;
- }
- }
-
- maxabs = (maxabs + 16) >> 5; // convert to Q12
-
- if (maxabs > 32767) {
- /* perform bandwidth expansion */
- unsigned int chirp, chirp_base; // Q16
- maxabs = FFMIN(maxabs, 163838); // anything above this overflows chirp's numerator
- chirp_base = chirp = 65470 - ((maxabs - 32767) << 14) / ((maxabs * (k+1)) >> 2);
-
- for (k = 0; k < order; k++) {
- lpc32[k] = ROUND_MULL(lpc32[k], chirp, 16);
- chirp = (chirp_base * chirp + 32768) >> 16;
- }
- } else break;
- }
-
- if (i == 10) {
- /* time's up: just clamp */
- for (k = 0; k < order; k++) {
- int x = (lpc32[k] + 16) >> 5;
- lpc[k] = av_clip_int16(x);
- lpc32[k] = lpc[k] << 5; // shortcut mandated by the spec; drops lower 5 bits
- }
- } else {
- for (k = 0; k < order; k++)
- lpc[k] = (lpc32[k] + 16) >> 5;
- }
-
- /* if the prediction gain causes the LPC filter to become unstable,
- apply further bandwidth expansion on the Q17 coefficients */
- for (i = 1; i <= 16 && !silk_is_lpc_stable(lpc, order); i++) {
- unsigned int chirp, chirp_base;
- chirp_base = chirp = 65536 - (1 << i);
-
- for (k = 0; k < order; k++) {
- lpc32[k] = ROUND_MULL(lpc32[k], chirp, 16);
- lpc[k] = (lpc32[k] + 16) >> 5;
- chirp = (chirp_base * chirp + 32768) >> 16;
- }
- }
-
- for (i = 0; i < order; i++)
- lpcf[i] = lpc[i] / 4096.0f;
-}
-
-static inline void silk_decode_lpc(SilkContext *s, SilkFrame *frame,
- OpusRangeCoder *rc,
- float lpc_leadin[16], float lpc[16],
- int *lpc_order, int *has_lpc_leadin, int voiced)
-{
- int i;
- int order; // order of the LP polynomial; 10 for NB/MB and 16 for WB
- int8_t lsf_i1, lsf_i2[16]; // stage-1 and stage-2 codebook indices
- int16_t lsf_res[16]; // residual as a Q10 value
- int16_t nlsf[16]; // Q15
-
- *lpc_order = order = s->wb ? 16 : 10;
-
- /* obtain LSF stage-1 and stage-2 indices */
- lsf_i1 = opus_rc_getsymbol(rc, silk_model_lsf_s1[s->wb][voiced]);
- for (i = 0; i < order; i++) {
- int index = s->wb ? silk_lsf_s2_model_sel_wb [lsf_i1][i] :
- silk_lsf_s2_model_sel_nbmb[lsf_i1][i];
- lsf_i2[i] = opus_rc_getsymbol(rc, silk_model_lsf_s2[index]) - 4;
- if (lsf_i2[i] == -4)
- lsf_i2[i] -= opus_rc_getsymbol(rc, silk_model_lsf_s2_ext);
- else if (lsf_i2[i] == 4)
- lsf_i2[i] += opus_rc_getsymbol(rc, silk_model_lsf_s2_ext);
- }
-
- /* reverse the backwards-prediction step */
- for (i = order - 1; i >= 0; i--) {
- int qstep = s->wb ? 9830 : 11796;
-
- lsf_res[i] = lsf_i2[i] * 1024;
- if (lsf_i2[i] < 0) lsf_res[i] += 102;
- else if (lsf_i2[i] > 0) lsf_res[i] -= 102;
- lsf_res[i] = (lsf_res[i] * qstep) >> 16;
-
- if (i + 1 < order) {
- int weight = s->wb ? silk_lsf_pred_weights_wb [silk_lsf_weight_sel_wb [lsf_i1][i]][i] :
- silk_lsf_pred_weights_nbmb[silk_lsf_weight_sel_nbmb[lsf_i1][i]][i];
- lsf_res[i] += (lsf_res[i+1] * weight) >> 8;
- }
- }
-
- /* reconstruct the NLSF coefficients from the supplied indices */
- for (i = 0; i < order; i++) {
- const uint8_t * codebook = s->wb ? silk_lsf_codebook_wb [lsf_i1] :
- silk_lsf_codebook_nbmb[lsf_i1];
- int cur, prev, next, weight_sq, weight, ipart, fpart, y, value;
-
- /* find the weight of the residual */
- /* TODO: precompute */
- cur = codebook[i];
- prev = i ? codebook[i - 1] : 0;
- next = i + 1 < order ? codebook[i + 1] : 256;
- weight_sq = (1024 / (cur - prev) + 1024 / (next - cur)) << 16;
-
- /* approximate square-root with mandated fixed-point arithmetic */
- ipart = opus_ilog(weight_sq);
- fpart = (weight_sq >> (ipart-8)) & 127;
- y = ((ipart & 1) ? 32768 : 46214) >> ((32 - ipart)>>1);
- weight = y + ((213 * fpart * y) >> 16);
-
- value = cur * 128 + (lsf_res[i] * 16384) / weight;
- nlsf[i] = av_clip_uintp2(value, 15);
- }
-
- /* stabilize the NLSF coefficients */
- silk_stabilize_lsf(nlsf, order, s->wb ? silk_lsf_min_spacing_wb :
- silk_lsf_min_spacing_nbmb);
-
- /* produce an interpolation for the first 2 subframes, */
- /* and then convert both sets of NLSFs to LPC coefficients */
- *has_lpc_leadin = 0;
- if (s->subframes == 4) {
- int offset = opus_rc_getsymbol(rc, silk_model_lsf_interpolation_offset);
- if (offset != 4 && frame->coded) {
- *has_lpc_leadin = 1;
- if (offset != 0) {
- int16_t nlsf_leadin[16];
- for (i = 0; i < order; i++)
- nlsf_leadin[i] = frame->nlsf[i] +
- ((nlsf[i] - frame->nlsf[i]) * offset >> 2);
- silk_lsf2lpc(nlsf_leadin, lpc_leadin, order);
- } else /* avoid re-computation for a (roughly) 1-in-4 occurrence */
- memcpy(lpc_leadin, frame->lpc, 16 * sizeof(float));
- } else
- offset = 4;
- s->nlsf_interp_factor = offset;
-
- silk_lsf2lpc(nlsf, lpc, order);
- } else {
- s->nlsf_interp_factor = 4;
- silk_lsf2lpc(nlsf, lpc, order);
- }
-
- memcpy(frame->nlsf, nlsf, order * sizeof(nlsf[0]));
- memcpy(frame->lpc, lpc, order * sizeof(lpc[0]));
-}
-
-static inline void silk_count_children(OpusRangeCoder *rc, int model, int32_t total,
- int32_t child[2])
-{
- if (total != 0) {
- child[0] = opus_rc_getsymbol(rc,
- silk_model_pulse_location[model] + (((total - 1 + 5) * (total - 1)) >> 1));
- child[1] = total - child[0];
- } else {
- child[0] = 0;
- child[1] = 0;
- }
-}
-
-static inline void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc,
- float* excitationf,
- int qoffset_high, int active, int voiced)
-{
- int i;
- uint32_t seed;
- int shellblocks;
- int ratelevel;
- uint8_t pulsecount[20]; // total pulses in each shell block
- uint8_t lsbcount[20] = {0}; // raw lsbits defined for each pulse in each shell block
- int32_t excitation[320]; // Q23
-
- /* excitation parameters */
- seed = opus_rc_getsymbol(rc, silk_model_lcg_seed);
- shellblocks = silk_shell_blocks[s->bandwidth][s->subframes >> 2];
- ratelevel = opus_rc_getsymbol(rc, silk_model_exc_rate[voiced]);
-
- for (i = 0; i < shellblocks; i++) {
- pulsecount[i] = opus_rc_getsymbol(rc, silk_model_pulse_count[ratelevel]);
- if (pulsecount[i] == 17) {
- while (pulsecount[i] == 17 && ++lsbcount[i] != 10)
- pulsecount[i] = opus_rc_getsymbol(rc, silk_model_pulse_count[9]);
- if (lsbcount[i] == 10)
- pulsecount[i] = opus_rc_getsymbol(rc, silk_model_pulse_count[10]);
- }
- }
-
- /* decode pulse locations using PVQ */
- for (i = 0; i < shellblocks; i++) {
- if (pulsecount[i] != 0) {
- int a, b, c, d;
- int32_t * location = excitation + 16*i;
- int32_t branch[4][2];
- branch[0][0] = pulsecount[i];
-
- /* unrolled tail recursion */
- for (a = 0; a < 1; a++) {
- silk_count_children(rc, 0, branch[0][a], branch[1]);
- for (b = 0; b < 2; b++) {
- silk_count_children(rc, 1, branch[1][b], branch[2]);
- for (c = 0; c < 2; c++) {
- silk_count_children(rc, 2, branch[2][c], branch[3]);
- for (d = 0; d < 2; d++) {
- silk_count_children(rc, 3, branch[3][d], location);
- location += 2;
- }
- }
- }
- }
- } else
- memset(excitation + 16*i, 0, 16*sizeof(int32_t));
- }
-
- /* decode least significant bits */
- for (i = 0; i < shellblocks << 4; i++) {
- int bit;
- for (bit = 0; bit < lsbcount[i >> 4]; bit++)
- excitation[i] = (excitation[i] << 1) |
- opus_rc_getsymbol(rc, silk_model_excitation_lsb);
- }
-
- /* decode signs */
- for (i = 0; i < shellblocks << 4; i++) {
- if (excitation[i] != 0) {
- int sign = opus_rc_getsymbol(rc, silk_model_excitation_sign[active +
- voiced][qoffset_high][FFMIN(pulsecount[i >> 4], 6)]);
- if (sign == 0)
- excitation[i] *= -1;
- }
- }
-
- /* assemble the excitation */
- for (i = 0; i < shellblocks << 4; i++) {
- int value = excitation[i];
- excitation[i] = value * 256 | silk_quant_offset[voiced][qoffset_high];
- if (value < 0) excitation[i] += 20;
- else if (value > 0) excitation[i] -= 20;
-
- /* invert samples pseudorandomly */
- seed = 196314165 * seed + 907633515;
- if (seed & 0x80000000)
- excitation[i] *= -1;
- seed += value;
-
- excitationf[i] = excitation[i] / 8388608.0f;
- }
-}
-
-/** Maximum residual history according to 4.2.7.6.1 */
-#define SILK_MAX_LAG (288 + LTP_ORDER / 2)
-
-/** Order of the LTP filter */
-#define LTP_ORDER 5
-
-static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
- int frame_num, int channel, int coded_channels, int active, int active1)
-{
- /* per frame */
- int voiced; // combines with active to indicate inactive, active, or active+voiced
- int qoffset_high;
- int order; // order of the LPC coefficients
- float lpc_leadin[16], lpc_body[16], residual[SILK_MAX_LAG + SILK_HISTORY];
- int has_lpc_leadin;
- float ltpscale;
-
- /* per subframe */
- struct {
- float gain;
- int pitchlag;
- float ltptaps[5];
- } sf[4];
-
- SilkFrame * const frame = s->frame + channel;
-
- int i;
-
- /* obtain stereo weights */
- if (coded_channels == 2 && channel == 0) {
- int n, wi[2], ws[2], w[2];
- n = opus_rc_getsymbol(rc, silk_model_stereo_s1);
- wi[0] = opus_rc_getsymbol(rc, silk_model_stereo_s2) + 3 * (n / 5);
- ws[0] = opus_rc_getsymbol(rc, silk_model_stereo_s3);
- wi[1] = opus_rc_getsymbol(rc, silk_model_stereo_s2) + 3 * (n % 5);
- ws[1] = opus_rc_getsymbol(rc, silk_model_stereo_s3);
-
- for (i = 0; i < 2; i++)
- w[i] = silk_stereo_weights[wi[i]] +
- (((silk_stereo_weights[wi[i] + 1] - silk_stereo_weights[wi[i]]) * 6554) >> 16)
- * (ws[i]*2 + 1);
-
- s->stereo_weights[0] = (w[0] - w[1]) / 8192.0;
- s->stereo_weights[1] = w[1] / 8192.0;
-
- /* and read the mid-only flag */
- s->midonly = active1 ? 0 : opus_rc_getsymbol(rc, silk_model_mid_only);
- }
-
- /* obtain frame type */
- if (!active) {
- qoffset_high = opus_rc_getsymbol(rc, silk_model_frame_type_inactive);
- voiced = 0;
- } else {
- int type = opus_rc_getsymbol(rc, silk_model_frame_type_active);
- qoffset_high = type & 1;
- voiced = type >> 1;
- }
-
- /* obtain subframe quantization gains */
- for (i = 0; i < s->subframes; i++) {
- int log_gain; //Q7
- int ipart, fpart, lingain;
-
- if (i == 0 && (frame_num == 0 || !frame->coded)) {
- /* gain is coded absolute */
- int x = opus_rc_getsymbol(rc, silk_model_gain_highbits[active + voiced]);
- log_gain = (x<<3) | opus_rc_getsymbol(rc, silk_model_gain_lowbits);
-
- if (frame->coded)
- log_gain = FFMAX(log_gain, frame->log_gain - 16);
- } else {
- /* gain is coded relative */
- int delta_gain = opus_rc_getsymbol(rc, silk_model_gain_delta);
- log_gain = av_clip_uintp2(FFMAX((delta_gain<<1) - 16,
- frame->log_gain + delta_gain - 4), 6);
- }
-
- frame->log_gain = log_gain;
-
- /* approximate 2**(x/128) with a Q7 (i.e. non-integer) input */
- log_gain = (log_gain * 0x1D1C71 >> 16) + 2090;
- ipart = log_gain >> 7;
- fpart = log_gain & 127;
- lingain = (1 << ipart) + ((-174 * fpart * (128-fpart) >>16) + fpart) * ((1<<ipart) >> 7);
- sf[i].gain = lingain / 65536.0f;
- }
-
- /* obtain LPC filter coefficients */
- silk_decode_lpc(s, frame, rc, lpc_leadin, lpc_body, &order, &has_lpc_leadin, voiced);
-
- /* obtain pitch lags, if this is a voiced frame */
- if (voiced) {
- int lag_absolute = (!frame_num || !frame->prev_voiced);
- int primarylag; // primary pitch lag for the entire SILK frame
- int ltpfilter;
- const int8_t * offsets;
-
- if (!lag_absolute) {
- int delta = opus_rc_getsymbol(rc, silk_model_pitch_delta);
- if (delta)
- primarylag = frame->primarylag + delta - 9;
- else
- lag_absolute = 1;
- }
-
- if (lag_absolute) {
- /* primary lag is coded absolute */
- int highbits, lowbits;
- const uint16_t *model[] = {
- silk_model_pitch_lowbits_nb, silk_model_pitch_lowbits_mb,
- silk_model_pitch_lowbits_wb
- };
- highbits = opus_rc_getsymbol(rc, silk_model_pitch_highbits);
- lowbits = opus_rc_getsymbol(rc, model[s->bandwidth]);
-
- primarylag = silk_pitch_min_lag[s->bandwidth] +
- highbits*silk_pitch_scale[s->bandwidth] + lowbits;
- }
- frame->primarylag = primarylag;
-
- if (s->subframes == 2)
- offsets = (s->bandwidth == OPUS_BANDWIDTH_NARROWBAND)
- ? silk_pitch_offset_nb10ms[opus_rc_getsymbol(rc,
- silk_model_pitch_contour_nb10ms)]
- : silk_pitch_offset_mbwb10ms[opus_rc_getsymbol(rc,
- silk_model_pitch_contour_mbwb10ms)];
- else
- offsets = (s->bandwidth == OPUS_BANDWIDTH_NARROWBAND)
- ? silk_pitch_offset_nb20ms[opus_rc_getsymbol(rc,
- silk_model_pitch_contour_nb20ms)]
- : silk_pitch_offset_mbwb20ms[opus_rc_getsymbol(rc,
- silk_model_pitch_contour_mbwb20ms)];
-
- for (i = 0; i < s->subframes; i++)
- sf[i].pitchlag = av_clip(primarylag + offsets[i],
- silk_pitch_min_lag[s->bandwidth],
- silk_pitch_max_lag[s->bandwidth]);
-
- /* obtain LTP filter coefficients */
- ltpfilter = opus_rc_getsymbol(rc, silk_model_ltp_filter);
- for (i = 0; i < s->subframes; i++) {
- int index, j;
- const uint16_t *filter_sel[] = {
- silk_model_ltp_filter0_sel, silk_model_ltp_filter1_sel,
- silk_model_ltp_filter2_sel
- };
- const int8_t (*filter_taps[])[5] = {
- silk_ltp_filter0_taps, silk_ltp_filter1_taps, silk_ltp_filter2_taps
- };
- index = opus_rc_getsymbol(rc, filter_sel[ltpfilter]);
- for (j = 0; j < 5; j++)
- sf[i].ltptaps[j] = filter_taps[ltpfilter][index][j] / 128.0f;
- }
- }
-
- /* obtain LTP scale factor */
- if (voiced && frame_num == 0)
- ltpscale = silk_ltp_scale_factor[opus_rc_getsymbol(rc,
- silk_model_ltp_scale_index)] / 16384.0f;
- else ltpscale = 15565.0f/16384.0f;
-
- /* generate the excitation signal for the entire frame */
- silk_decode_excitation(s, rc, residual + SILK_MAX_LAG, qoffset_high,
- active, voiced);
-
- /* skip synthesising the side channel if we want mono-only */
- if (s->output_channels == channel)
- return;
-
- /* generate the output signal */
- for (i = 0; i < s->subframes; i++) {
- const float * lpc_coeff = (i < 2 && has_lpc_leadin) ? lpc_leadin : lpc_body;
- float *dst = frame->output + SILK_HISTORY + i * s->sflength;
- float *resptr = residual + SILK_MAX_LAG + i * s->sflength;
- float *lpc = frame->lpc_history + SILK_HISTORY + i * s->sflength;
- float sum;
- int j, k;
-
- if (voiced) {
- int out_end;
- float scale;
-
- if (i < 2 || s->nlsf_interp_factor == 4) {
- out_end = -i * s->sflength;
- scale = ltpscale;
- } else {
- out_end = -(i - 2) * s->sflength;
- scale = 1.0f;
- }
-
- /* when the LPC coefficients change, a re-whitening filter is used */
- /* to produce a residual that accounts for the change */
- for (j = - sf[i].pitchlag - LTP_ORDER/2; j < out_end; j++) {
- sum = dst[j];
- for (k = 0; k < order; k++)
- sum -= lpc_coeff[k] * dst[j - k - 1];
- resptr[j] = av_clipf(sum, -1.0f, 1.0f) * scale / sf[i].gain;
- }
-
- if (out_end) {
- float rescale = sf[i-1].gain / sf[i].gain;
- for (j = out_end; j < 0; j++)
- resptr[j] *= rescale;
- }
-
- /* LTP synthesis */
- for (j = 0; j < s->sflength; j++) {
- sum = resptr[j];
- for (k = 0; k < LTP_ORDER; k++)
- sum += sf[i].ltptaps[k] * resptr[j - sf[i].pitchlag + LTP_ORDER/2 - k];
- resptr[j] = sum;
- }
- }
-
- /* LPC synthesis */
- for (j = 0; j < s->sflength; j++) {
- sum = resptr[j] * sf[i].gain;
- for (k = 1; k <= order; k++)
- sum += lpc_coeff[k - 1] * lpc[j - k];
-
- lpc[j] = sum;
- dst[j] = av_clipf(sum, -1.0f, 1.0f);
- }
- }
-
- frame->prev_voiced = voiced;
- memmove(frame->lpc_history, frame->lpc_history + s->flength, SILK_HISTORY * sizeof(float));
- memmove(frame->output, frame->output + s->flength, SILK_HISTORY * sizeof(float));
-
- frame->coded = 1;
-}
-
-static void silk_unmix_ms(SilkContext *s, float *l, float *r)
-{
- float *mid = s->frame[0].output + SILK_HISTORY - s->flength;
- float *side = s->frame[1].output + SILK_HISTORY - s->flength;
- float w0_prev = s->prev_stereo_weights[0];
- float w1_prev = s->prev_stereo_weights[1];
- float w0 = s->stereo_weights[0];
- float w1 = s->stereo_weights[1];
- int n1 = silk_stereo_interp_len[s->bandwidth];
- int i;
-
- for (i = 0; i < n1; i++) {
- float interp0 = w0_prev + i * (w0 - w0_prev) / n1;
- float interp1 = w1_prev + i * (w1 - w1_prev) / n1;
- float p0 = 0.25 * (mid[i - 2] + 2 * mid[i - 1] + mid[i]);
-
- l[i] = av_clipf((1 + interp1) * mid[i - 1] + side[i - 1] + interp0 * p0, -1.0, 1.0);
- r[i] = av_clipf((1 - interp1) * mid[i - 1] - side[i - 1] - interp0 * p0, -1.0, 1.0);
- }
-
- for (; i < s->flength; i++) {
- float p0 = 0.25 * (mid[i - 2] + 2 * mid[i - 1] + mid[i]);
-
- l[i] = av_clipf((1 + w1) * mid[i - 1] + side[i - 1] + w0 * p0, -1.0, 1.0);
- r[i] = av_clipf((1 - w1) * mid[i - 1] - side[i - 1] - w0 * p0, -1.0, 1.0);
- }
-
- memcpy(s->prev_stereo_weights, s->stereo_weights, sizeof(s->stereo_weights));
-}
-
-static void silk_flush_frame(SilkFrame *frame)
-{
- if (!frame->coded)
- return;
-
- memset(frame->output, 0, sizeof(frame->output));
- memset(frame->lpc_history, 0, sizeof(frame->lpc_history));
-
- memset(frame->lpc, 0, sizeof(frame->lpc));
- memset(frame->nlsf, 0, sizeof(frame->nlsf));
-
- frame->log_gain = 0;
-
- frame->primarylag = 0;
- frame->prev_voiced = 0;
- frame->coded = 0;
-}
-
-int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc,
- float *output[2],
- enum OpusBandwidth bandwidth,
- int coded_channels,
- int duration_ms)
-{
- int active[2][6], redundancy[2];
- int nb_frames, i, j;
-
- if (bandwidth > OPUS_BANDWIDTH_WIDEBAND ||
- coded_channels > 2 || duration_ms > 60) {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid parameters passed "
- "to the SILK decoder.\n");
- return AVERROR(EINVAL);
- }
-
- nb_frames = 1 + (duration_ms > 20) + (duration_ms > 40);
- s->subframes = duration_ms / nb_frames / 5; // 5ms subframes
- s->sflength = 20 * (bandwidth + 2);
- s->flength = s->sflength * s->subframes;
- s->bandwidth = bandwidth;
- s->wb = bandwidth == OPUS_BANDWIDTH_WIDEBAND;
-
- /* make sure to flush the side channel when switching from mono to stereo */
- if (coded_channels > s->prev_coded_channels)
- silk_flush_frame(&s->frame[1]);
- s->prev_coded_channels = coded_channels;
-
- /* read the LP-layer header bits */
- for (i = 0; i < coded_channels; i++) {
- for (j = 0; j < nb_frames; j++)
- active[i][j] = opus_rc_p2model(rc, 1);
-
- redundancy[i] = opus_rc_p2model(rc, 1);
- if (redundancy[i]) {
- av_log(s->avctx, AV_LOG_ERROR, "LBRR frames present; this is unsupported\n");
- return AVERROR_PATCHWELCOME;
- }
- }
-
- for (i = 0; i < nb_frames; i++) {
- for (j = 0; j < coded_channels && !s->midonly; j++)
- silk_decode_frame(s, rc, i, j, coded_channels, active[j][i], active[1][i]);
-
- /* reset the side channel if it is not coded */
- if (s->midonly && s->frame[1].coded)
- silk_flush_frame(&s->frame[1]);
-
- if (coded_channels == 1 || s->output_channels == 1) {
- for (j = 0; j < s->output_channels; j++) {
- memcpy(output[j] + i * s->flength,
- s->frame[0].output + SILK_HISTORY - s->flength - 2,
- s->flength * sizeof(float));
- }
- } else {
- silk_unmix_ms(s, output[0] + i * s->flength, output[1] + i * s->flength);
- }
-
- s->midonly = 0;
- }
-
- return nb_frames * s->flength;
-}
-
-void ff_silk_free(SilkContext **ps)
-{
- av_freep(ps);
-}
-
-void ff_silk_flush(SilkContext *s)
-{
- silk_flush_frame(&s->frame[0]);
- silk_flush_frame(&s->frame[1]);
-
- memset(s->prev_stereo_weights, 0, sizeof(s->prev_stereo_weights));
-}
-
-int ff_silk_init(AVCodecContext *avctx, SilkContext **ps, int output_channels)
-{
- SilkContext *s;
-
- if (output_channels != 1 && output_channels != 2) {
- av_log(avctx, AV_LOG_ERROR, "Invalid number of output channels: %d\n",
- output_channels);
- return AVERROR(EINVAL);
- }
-
- s = av_mallocz(sizeof(*s));
- if (!s)
- return AVERROR(ENOMEM);
-
- s->avctx = avctx;
- s->output_channels = output_channels;
-
- ff_silk_flush(s);
-
- *ps = s;
-
- return 0;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/pafvideo.c b/ffmpeg-2-8-11/libavcodec/pafvideo.c
deleted file mode 100644
index cab3129..0000000
--- a/ffmpeg-2-8-11/libavcodec/pafvideo.c
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Packed Animation File video decoder
- * Copyright (c) 2012 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 "avcodec.h"
-#include "bytestream.h"
-#include "copy_block.h"
-#include "internal.h"
-
-
-static const uint8_t block_sequences[16][8] = {
- { 0, 0, 0, 0, 0, 0, 0, 0 },
- { 2, 0, 0, 0, 0, 0, 0, 0 },
- { 5, 7, 0, 0, 0, 0, 0, 0 },
- { 5, 0, 0, 0, 0, 0, 0, 0 },
- { 6, 0, 0, 0, 0, 0, 0, 0 },
- { 5, 7, 5, 7, 0, 0, 0, 0 },
- { 5, 7, 5, 0, 0, 0, 0, 0 },
- { 5, 7, 6, 0, 0, 0, 0, 0 },
- { 5, 5, 0, 0, 0, 0, 0, 0 },
- { 3, 0, 0, 0, 0, 0, 0, 0 },
- { 6, 6, 0, 0, 0, 0, 0, 0 },
- { 2, 4, 0, 0, 0, 0, 0, 0 },
- { 2, 4, 5, 7, 0, 0, 0, 0 },
- { 2, 4, 5, 0, 0, 0, 0, 0 },
- { 2, 4, 6, 0, 0, 0, 0, 0 },
- { 2, 4, 5, 7, 5, 7, 0, 0 },
-};
-
-typedef struct PAFVideoDecContext {
- AVFrame *pic;
- GetByteContext gb;
-
- int width;
- int height;
-
- int current_frame;
- uint8_t *frame[4];
- int frame_size;
- int video_size;
-
- uint8_t *opcodes;
-} PAFVideoDecContext;
-
-static av_cold int paf_video_close(AVCodecContext *avctx)
-{
- PAFVideoDecContext *c = avctx->priv_data;
- int i;
-
- av_frame_free(&c->pic);
-
- for (i = 0; i < 4; i++)
- av_freep(&c->frame[i]);
-
- return 0;
-}
-
-static av_cold int paf_video_init(AVCodecContext *avctx)
-{
- PAFVideoDecContext *c = avctx->priv_data;
- int i;
-
- c->width = avctx->width;
- c->height = avctx->height;
-
- if (avctx->height & 3 || avctx->width & 3) {
- av_log(avctx, AV_LOG_ERROR,
- "width %d and height %d must be multiplie of 4.\n",
- avctx->width, avctx->height);
- return AVERROR_INVALIDDATA;
- }
-
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
-
- c->pic = av_frame_alloc();
- if (!c->pic)
- return AVERROR(ENOMEM);
-
- c->frame_size = avctx->width * FFALIGN(avctx->height, 256);
- 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);
- return AVERROR(ENOMEM);
- }
- }
-
- return 0;
-}
-
-static void read4x4block(PAFVideoDecContext *c, uint8_t *dst, int width)
-{
- int i;
-
- for (i = 0; i < 4; i++) {
- bytestream2_get_buffer(&c->gb, dst, 4);
- dst += width;
- }
-}
-
-static void copy_color_mask(uint8_t *dst, int width, uint8_t mask, uint8_t color)
-{
- int i;
-
- for (i = 0; i < 4; i++) {
- if (mask & (1 << 7 - i))
- dst[i] = color;
- if (mask & (1 << 3 - i))
- dst[width + i] = color;
- }
-}
-
-static void copy_src_mask(uint8_t *dst, int width, uint8_t mask, const uint8_t *src)
-{
- int i;
-
- for (i = 0; i < 4; i++) {
- if (mask & (1 << 7 - i))
- dst[i] = src[i];
- if (mask & (1 << 3 - i))
- dst[width + i] = src[width + i];
- }
-}
-
-static void set_src_position(PAFVideoDecContext *c,
- const uint8_t **p,
- const uint8_t **pend)
-{
- int val = bytestream2_get_be16(&c->gb);
- int page = val >> 14;
- int x = (val & 0x7F);
- int y = ((val >> 7) & 0x7F);
-
- *p = c->frame[page] + x * 2 + y * 2 * c->width;
- *pend = c->frame[page] + c->frame_size;
-}
-
-static int decode_0(PAFVideoDecContext *c, uint8_t *pkt, uint8_t code)
-{
- uint32_t opcode_size, offset;
- uint8_t *dst, *dend, mask = 0, color = 0;
- const uint8_t *src, *send, *opcodes;
- int i, j, op = 0;
-
- i = bytestream2_get_byte(&c->gb);
- if (i) {
- if (code & 0x10) {
- int align;
-
- align = bytestream2_tell(&c->gb) & 3;
- if (align)
- bytestream2_skip(&c->gb, 4 - align);
- }
- do {
- int page, val, x, y;
- val = bytestream2_get_be16(&c->gb);
- page = val >> 14;
- x = (val & 0x7F) * 2;
- y = ((val >> 7) & 0x7F) * 2;
- dst = c->frame[page] + x + y * c->width;
- dend = c->frame[page] + c->frame_size;
- offset = (x & 0x7F) * 2;
- j = bytestream2_get_le16(&c->gb) + offset;
- do {
- offset++;
- if (dst + 3 * c->width + 4 > dend)
- return AVERROR_INVALIDDATA;
- read4x4block(c, dst, c->width);
- if ((offset & 0x3F) == 0)
- dst += c->width * 3;
- dst += 4;
- } while (offset < j);
- } while (--i);
- }
-
- dst = c->frame[c->current_frame];
- dend = c->frame[c->current_frame] + c->frame_size;
- do {
- set_src_position(c, &src, &send);
- if ((src + 3 * c->width + 4 > send) ||
- (dst + 3 * c->width + 4 > dend))
- return AVERROR_INVALIDDATA;
- copy_block4(dst, src, c->width, c->width, 4);
- i++;
- if ((i & 0x3F) == 0)
- dst += c->width * 3;
- dst += 4;
- } while (i < c->video_size / 16);
-
- opcode_size = bytestream2_get_le16(&c->gb);
- bytestream2_skip(&c->gb, 2);
-
- if (bytestream2_get_bytes_left(&c->gb) < opcode_size)
- return AVERROR_INVALIDDATA;
-
- opcodes = pkt + bytestream2_tell(&c->gb);
- bytestream2_skipu(&c->gb, opcode_size);
-
- dst = c->frame[c->current_frame];
-
- for (i = 0; i < c->height; i += 4, dst += c->width * 3)
- for (j = 0; j < c->width; j += 4, dst += 4) {
- int opcode, k = 0;
- if (op > opcode_size)
- return AVERROR_INVALIDDATA;
- if (j & 4) {
- opcode = opcodes[op] & 15;
- op++;
- } else {
- opcode = opcodes[op] >> 4;
- }
-
- while (block_sequences[opcode][k]) {
- offset = c->width * 2;
- code = block_sequences[opcode][k++];
-
- switch (code) {
- case 2:
- offset = 0;
- case 3:
- color = bytestream2_get_byte(&c->gb);
- case 4:
- mask = bytestream2_get_byte(&c->gb);
- copy_color_mask(dst + offset, c->width, mask, color);
- break;
- case 5:
- offset = 0;
- case 6:
- set_src_position(c, &src, &send);
- case 7:
- if (src + offset + c->width + 4 > send)
- return AVERROR_INVALIDDATA;
- mask = bytestream2_get_byte(&c->gb);
- copy_src_mask(dst + offset, c->width, mask, src + offset);
- break;
- }
- }
- }
-
- return 0;
-}
-
-static int paf_video_decode(AVCodecContext *avctx, void *data,
- int *got_frame, AVPacket *pkt)
-{
- PAFVideoDecContext *c = avctx->priv_data;
- uint8_t code, *dst, *end;
- int i, frame, ret;
-
- if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)
- return ret;
-
- bytestream2_init(&c->gb, pkt->data, pkt->size);
-
- code = bytestream2_get_byte(&c->gb);
- if (code & 0x20) { // frame is keyframe
- for (i = 0; i < 4; i++)
- memset(c->frame[i], 0, c->frame_size);
-
- memset(c->pic->data[1], 0, AVPALETTE_SIZE);
- c->current_frame = 0;
- c->pic->key_frame = 1;
- c->pic->pict_type = AV_PICTURE_TYPE_I;
- } else {
- c->pic->key_frame = 0;
- c->pic->pict_type = AV_PICTURE_TYPE_P;
- }
-
- if (code & 0x40) { // palette update
- uint32_t *out = (uint32_t *)c->pic->data[1];
- int index, count;
-
- index = bytestream2_get_byte(&c->gb);
- count = bytestream2_get_byte(&c->gb) + 1;
-
- if (index + count > 256)
- return AVERROR_INVALIDDATA;
- if (bytestream2_get_bytes_left(&c->gb) < 3 * count)
- return AVERROR_INVALIDDATA;
-
- out += index;
- for (i = 0; i < count; i++) {
- unsigned r, g, b;
-
- r = bytestream2_get_byteu(&c->gb);
- r = r << 2 | r >> 4;
- g = bytestream2_get_byteu(&c->gb);
- g = g << 2 | g >> 4;
- b = bytestream2_get_byteu(&c->gb);
- b = b << 2 | b >> 4;
- *out++ = (0xFFU << 24) | (r << 16) | (g << 8) | b;
- }
- c->pic->palette_has_changed = 1;
- }
-
- switch (code & 0x0F) {
- case 0:
- /* Block-based motion compensation using 4x4 blocks with either
- * horizontal or vertical vectors; might incorporate VQ as well. */
- if ((ret = decode_0(c, pkt->data, code)) < 0)
- return ret;
- break;
- case 1:
- /* Uncompressed data. This mode specifies that (width * height) bytes
- * should be copied directly from the encoded buffer into the output. */
- dst = c->frame[c->current_frame];
- // possibly chunk length data
- bytestream2_skip(&c->gb, 2);
- if (bytestream2_get_bytes_left(&c->gb) < c->video_size)
- return AVERROR_INVALIDDATA;
- bytestream2_get_bufferu(&c->gb, dst, c->video_size);
- break;
- case 2:
- /* Copy reference frame: Consume the next byte in the stream as the
- * reference frame (which should be 0, 1, 2, or 3, and should not be
- * the same as the current frame number). */
- frame = bytestream2_get_byte(&c->gb);
- if (frame > 3)
- return AVERROR_INVALIDDATA;
- if (frame != c->current_frame)
- memcpy(c->frame[c->current_frame], c->frame[frame], c->frame_size);
- break;
- case 4:
- /* Run length encoding.*/
- dst = c->frame[c->current_frame];
- end = dst + c->video_size;
-
- bytestream2_skip(&c->gb, 2);
-
- while (dst < end) {
- int8_t code;
- int count;
-
- if (bytestream2_get_bytes_left(&c->gb) < 2)
- return AVERROR_INVALIDDATA;
-
- code = bytestream2_get_byteu(&c->gb);
- count = FFABS(code) + 1;
-
- if (dst + count > end)
- return AVERROR_INVALIDDATA;
- if (code < 0)
- memset(dst, bytestream2_get_byteu(&c->gb), count);
- else
- bytestream2_get_buffer(&c->gb, dst, count);
- dst += count;
- }
- break;
- default:
- avpriv_request_sample(avctx, "unknown/invalid code");
- return AVERROR_INVALIDDATA;
- }
-
- av_image_copy_plane(c->pic->data[0], c->pic->linesize[0],
- c->frame[c->current_frame], c->width,
- c->width, c->height);
-
- c->current_frame = (c->current_frame + 1) & 3;
- if ((ret = av_frame_ref(data, c->pic)) < 0)
- return ret;
-
- *got_frame = 1;
-
- return pkt->size;
-}
-
-AVCodec ff_paf_video_decoder = {
- .name = "paf_video",
- .long_name = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Video"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_PAF_VIDEO,
- .priv_data_size = sizeof(PAFVideoDecContext),
- .init = paf_video_init,
- .close = paf_video_close,
- .decode = paf_video_decode,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/pictordec.c b/ffmpeg-2-8-11/libavcodec/pictordec.c
deleted file mode 100644
index 0cfc785..0000000
--- a/ffmpeg-2-8-11/libavcodec/pictordec.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Pictor/PC Paint decoder
- * Copyright (c) 2010 Peter Ross <pross at 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
- * Pictor/PC Paint decoder
- */
-
-#include "libavutil/imgutils.h"
-#include "avcodec.h"
-#include "bytestream.h"
-#include "cga_data.h"
-#include "internal.h"
-
-typedef struct PicContext {
- int width, height;
- int nb_planes;
- GetByteContext g;
-} PicContext;
-
-static void picmemset_8bpp(PicContext *s, AVFrame *frame, int value, int run,
- int *x, int *y)
-{
- while (run > 0) {
- uint8_t *d = frame->data[0] + *y * frame->linesize[0];
- if (*x + run >= s->width) {
- int n = s->width - *x;
- memset(d + *x, value, n);
- run -= n;
- *x = 0;
- *y -= 1;
- if (*y < 0)
- break;
- } else {
- memset(d + *x, value, run);
- *x += run;
- break;
- }
- }
-}
-
-static void picmemset(PicContext *s, AVFrame *frame, int value, int run,
- int *x, int *y, int *plane, int bits_per_plane)
-{
- uint8_t *d;
- int shift = *plane * bits_per_plane;
- int mask = ((1 << bits_per_plane) - 1) << shift;
- value <<= shift;
-
- while (run > 0) {
- int j;
- for (j = 8-bits_per_plane; j >= 0; j -= bits_per_plane) {
- d = frame->data[0] + *y * frame->linesize[0];
- d[*x] |= (value >> j) & mask;
- *x += 1;
- if (*x == s->width) {
- *y -= 1;
- *x = 0;
- if (*y < 0) {
- *y = s->height - 1;
- *plane += 1;
- value <<= bits_per_plane;
- mask <<= bits_per_plane;
- if (*plane >= s->nb_planes)
- break;
- }
- }
- }
- run--;
- }
-}
-
-static const uint8_t cga_mode45_index[6][4] = {
- [0] = { 0, 3, 5, 7 }, // mode4, palette#1, low intensity
- [1] = { 0, 2, 4, 6 }, // mode4, palette#2, low intensity
- [2] = { 0, 3, 4, 7 }, // mode5, low intensity
- [3] = { 0, 11, 13, 15 }, // mode4, palette#1, high intensity
- [4] = { 0, 10, 12, 14 }, // mode4, palette#2, high intensity
- [5] = { 0, 11, 12, 15 }, // mode5, high intensity
-};
-
-static int decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- PicContext *s = avctx->priv_data;
- AVFrame *frame = data;
- uint32_t *palette;
- int bits_per_plane, bpp, etype, esize, npal, pos_after_pal;
- int i, x, y, plane, tmp, ret, val;
-
- bytestream2_init(&s->g, avpkt->data, avpkt->size);
-
- if (bytestream2_get_bytes_left(&s->g) < 11)
- return AVERROR_INVALIDDATA;
-
- if (bytestream2_get_le16u(&s->g) != 0x1234)
- return AVERROR_INVALIDDATA;
-
- s->width = bytestream2_get_le16u(&s->g);
- s->height = bytestream2_get_le16u(&s->g);
- bytestream2_skip(&s->g, 4);
- tmp = bytestream2_get_byteu(&s->g);
- bits_per_plane = tmp & 0xF;
- s->nb_planes = (tmp >> 4) + 1;
- bpp = bits_per_plane * s->nb_planes;
- if (bits_per_plane > 8 || bpp < 1 || bpp > 32) {
- avpriv_request_sample(avctx, "Unsupported bit depth");
- return AVERROR_PATCHWELCOME;
- }
-
- if (bytestream2_peek_byte(&s->g) == 0xFF || bpp == 1 || bpp == 4 || bpp == 8) {
- bytestream2_skip(&s->g, 2);
- etype = bytestream2_get_le16(&s->g);
- esize = bytestream2_get_le16(&s->g);
- if (bytestream2_get_bytes_left(&s->g) < esize)
- return AVERROR_INVALIDDATA;
- } else {
- etype = -1;
- esize = 0;
- }
-
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
-
- if (av_image_check_size(s->width, s->height, 0, avctx) < 0)
- return -1;
- if (s->width != avctx->width || s->height != avctx->height) {
- ret = ff_set_dimensions(avctx, s->width, s->height);
- if (ret < 0)
- return ret;
- }
-
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
- memset(frame->data[0], 0, s->height * frame->linesize[0]);
- frame->pict_type = AV_PICTURE_TYPE_I;
- frame->palette_has_changed = 1;
-
- pos_after_pal = bytestream2_tell(&s->g) + esize;
- palette = (uint32_t*)frame->data[1];
- if (etype == 1 && esize > 1 && bytestream2_peek_byte(&s->g) < 6) {
- int idx = bytestream2_get_byte(&s->g);
- npal = 4;
- for (i = 0; i < npal; i++)
- palette[i] = ff_cga_palette[ cga_mode45_index[idx][i] ];
- } else if (etype == 2) {
- npal = FFMIN(esize, 16);
- for (i = 0; i < npal; i++) {
- int pal_idx = bytestream2_get_byte(&s->g);
- palette[i] = ff_cga_palette[FFMIN(pal_idx, 15)];
- }
- } else if (etype == 3) {
- npal = FFMIN(esize, 16);
- for (i = 0; i < npal; i++) {
- int pal_idx = bytestream2_get_byte(&s->g);
- palette[i] = ff_ega_palette[FFMIN(pal_idx, 63)];
- }
- } else if (etype == 4 || etype == 5) {
- npal = FFMIN(esize / 3, 256);
- for (i = 0; i < npal; i++) {
- palette[i] = bytestream2_get_be24(&s->g) << 2;
- palette[i] |= 0xFFU << 24 | palette[i] >> 6 & 0x30303;
- }
- } else {
- if (bpp == 1) {
- npal = 2;
- palette[0] = 0xFF000000;
- palette[1] = 0xFFFFFFFF;
- } else if (bpp == 2) {
- npal = 4;
- for (i = 0; i < npal; i++)
- palette[i] = ff_cga_palette[ cga_mode45_index[0][i] ];
- } else {
- npal = 16;
- memcpy(palette, ff_cga_palette, npal * 4);
- }
- }
- // fill remaining palette entries
- memset(palette + npal, 0, AVPALETTE_SIZE - npal * 4);
- // skip remaining palette bytes
- bytestream2_seek(&s->g, pos_after_pal, SEEK_SET);
-
- val = 0;
- y = s->height - 1;
- if (bytestream2_get_le16(&s->g)) {
- x = 0;
- plane = 0;
- while (bytestream2_get_bytes_left(&s->g) >= 6) {
- int stop_size, marker, t1, t2;
-
- t1 = bytestream2_get_bytes_left(&s->g);
- t2 = bytestream2_get_le16(&s->g);
- stop_size = t1 - FFMIN(t1, t2);
- // ignore uncompressed block size
- bytestream2_skip(&s->g, 2);
- marker = bytestream2_get_byte(&s->g);
-
- while (plane < s->nb_planes &&
- bytestream2_get_bytes_left(&s->g) > stop_size) {
- int run = 1;
- val = bytestream2_get_byte(&s->g);
- if (val == marker) {
- run = bytestream2_get_byte(&s->g);
- if (run == 0)
- run = bytestream2_get_le16(&s->g);
- val = bytestream2_get_byte(&s->g);
- }
- if (!bytestream2_get_bytes_left(&s->g))
- break;
-
- if (bits_per_plane == 8) {
- picmemset_8bpp(s, frame, val, run, &x, &y);
- if (y < 0)
- goto finish;
- } else {
- picmemset(s, frame, val, run, &x, &y, &plane, bits_per_plane);
- }
- }
- }
-
- if (x < avctx->width) {
- int run = (y + 1) * avctx->width - x;
- if (bits_per_plane == 8)
- picmemset_8bpp(s, frame, val, run, &x, &y);
- else
- picmemset(s, frame, val, run / (8 / bits_per_plane), &x, &y, &plane, bits_per_plane);
- }
- } else {
- while (y >= 0 && bytestream2_get_bytes_left(&s->g) > 0) {
- memcpy(frame->data[0] + y * frame->linesize[0], s->g.buffer, FFMIN(avctx->width, bytestream2_get_bytes_left(&s->g)));
- bytestream2_skip(&s->g, avctx->width);
- y--;
- }
- }
-finish:
-
- *got_frame = 1;
- return avpkt->size;
-}
-
-AVCodec ff_pictor_decoder = {
- .name = "pictor",
- .long_name = NULL_IF_CONFIG_SMALL("Pictor/PC Paint"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_PICTOR,
- .priv_data_size = sizeof(PicContext),
- .decode = decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/pngdec.c b/ffmpeg-2-8-11/libavcodec/pngdec.c
deleted file mode 100644
index 61c4ac8..0000000
--- a/ffmpeg-2-8-11/libavcodec/pngdec.c
+++ /dev/null
@@ -1,1487 +0,0 @@
-/*
- * PNG image format
- * Copyright (c) 2003 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
- */
-
-//#define DEBUG
-
-#include "libavutil/avassert.h"
-#include "libavutil/bprint.h"
-#include "libavutil/imgutils.h"
-#include "avcodec.h"
-#include "bytestream.h"
-#include "internal.h"
-#include "apng.h"
-#include "png.h"
-#include "pngdsp.h"
-#include "thread.h"
-
-#include <zlib.h>
-
-typedef struct PNGDecContext {
- PNGDSPContext dsp;
- AVCodecContext *avctx;
-
- GetByteContext gb;
- ThreadFrame previous_picture;
- ThreadFrame last_picture;
- ThreadFrame picture;
-
- int state;
- int width, height;
- int cur_w, cur_h;
- int last_w, last_h;
- int x_offset, y_offset;
- int last_x_offset, last_y_offset;
- uint8_t dispose_op, blend_op;
- uint8_t last_dispose_op;
- int bit_depth;
- int color_type;
- int compression_type;
- int interlace_type;
- int filter_type;
- int channels;
- int bits_per_pixel;
- int bpp;
- int has_trns;
- uint8_t transparent_color_be[6];
-
- uint8_t *image_buf;
- int image_linesize;
- uint32_t palette[256];
- uint8_t *crow_buf;
- uint8_t *last_row;
- unsigned int last_row_size;
- uint8_t *tmp_row;
- unsigned int tmp_row_size;
- uint8_t *buffer;
- int buffer_size;
- int pass;
- int crow_size; /* compressed row size (include filter type) */
- int row_size; /* decompressed row size */
- int pass_row_size; /* decompress row size of the current pass */
- int y;
- z_stream zstream;
-} PNGDecContext;
-
-/* Mask to determine which pixels are valid in a pass */
-static const uint8_t png_pass_mask[NB_PASSES] = {
- 0x01, 0x01, 0x11, 0x11, 0x55, 0x55, 0xff,
-};
-
-/* Mask to determine which y pixels can be written in a pass */
-static const uint8_t png_pass_dsp_ymask[NB_PASSES] = {
- 0xff, 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
-};
-
-/* Mask to determine which pixels to overwrite while displaying */
-static const uint8_t png_pass_dsp_mask[NB_PASSES] = {
- 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff
-};
-
-/* NOTE: we try to construct a good looking image at each pass. width
- * is the original image width. We also do pixel format conversion at
- * this stage */
-static void png_put_interlaced_row(uint8_t *dst, int width,
- int bits_per_pixel, int pass,
- int color_type, const uint8_t *src)
-{
- int x, mask, dsp_mask, j, src_x, b, bpp;
- uint8_t *d;
- const uint8_t *s;
-
- mask = png_pass_mask[pass];
- dsp_mask = png_pass_dsp_mask[pass];
-
- switch (bits_per_pixel) {
- case 1:
- src_x = 0;
- for (x = 0; x < width; x++) {
- j = (x & 7);
- if ((dsp_mask << j) & 0x80) {
- b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1;
- dst[x >> 3] &= 0xFF7F>>j;
- dst[x >> 3] |= b << (7 - j);
- }
- if ((mask << j) & 0x80)
- src_x++;
- }
- break;
- case 2:
- src_x = 0;
- for (x = 0; x < width; x++) {
- int j2 = 2 * (x & 3);
- j = (x & 7);
- if ((dsp_mask << j) & 0x80) {
- b = (src[src_x >> 2] >> (6 - 2*(src_x & 3))) & 3;
- dst[x >> 2] &= 0xFF3F>>j2;
- dst[x >> 2] |= b << (6 - j2);
- }
- if ((mask << j) & 0x80)
- src_x++;
- }
- break;
- case 4:
- src_x = 0;
- for (x = 0; x < width; x++) {
- int j2 = 4*(x&1);
- j = (x & 7);
- if ((dsp_mask << j) & 0x80) {
- b = (src[src_x >> 1] >> (4 - 4*(src_x & 1))) & 15;
- dst[x >> 1] &= 0xFF0F>>j2;
- dst[x >> 1] |= b << (4 - j2);
- }
- if ((mask << j) & 0x80)
- src_x++;
- }
- break;
- default:
- bpp = bits_per_pixel >> 3;
- d = dst;
- s = src;
- for (x = 0; x < width; x++) {
- j = x & 7;
- if ((dsp_mask << j) & 0x80) {
- memcpy(d, s, bpp);
- }
- d += bpp;
- if ((mask << j) & 0x80)
- s += bpp;
- }
- break;
- }
-}
-
-void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top,
- int w, int bpp)
-{
- int i;
- for (i = 0; i < w; i++) {
- int a, b, c, p, pa, pb, pc;
-
- a = dst[i - bpp];
- b = top[i];
- c = top[i - bpp];
-
- p = b - c;
- pc = a - c;
-
- pa = abs(p);
- pb = abs(pc);
- pc = abs(p + pc);
-
- if (pa <= pb && pa <= pc)
- p = a;
- else if (pb <= pc)
- p = b;
- else
- p = c;
- dst[i] = p + src[i];
- }
-}
-
-#define UNROLL1(bpp, op) \
- { \
- r = dst[0]; \
- if (bpp >= 2) \
- g = dst[1]; \
- if (bpp >= 3) \
- b = dst[2]; \
- if (bpp >= 4) \
- a = dst[3]; \
- for (; i <= size - bpp; i += bpp) { \
- dst[i + 0] = r = op(r, src[i + 0], last[i + 0]); \
- if (bpp == 1) \
- continue; \
- dst[i + 1] = g = op(g, src[i + 1], last[i + 1]); \
- if (bpp == 2) \
- continue; \
- dst[i + 2] = b = op(b, src[i + 2], last[i + 2]); \
- if (bpp == 3) \
- continue; \
- dst[i + 3] = a = op(a, src[i + 3], last[i + 3]); \
- } \
- }
-
-#define UNROLL_FILTER(op) \
- if (bpp == 1) { \
- UNROLL1(1, op) \
- } else if (bpp == 2) { \
- UNROLL1(2, op) \
- } else if (bpp == 3) { \
- UNROLL1(3, op) \
- } else if (bpp == 4) { \
- UNROLL1(4, op) \
- } \
- for (; i < size; i++) { \
- dst[i] = op(dst[i - bpp], src[i], last[i]); \
- }
-
-/* 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)
-{
- int i, p, r, g, b, a;
-
- switch (filter_type) {
- case PNG_FILTER_VALUE_NONE:
- memcpy(dst, src, size);
- break;
- case PNG_FILTER_VALUE_SUB:
- for (i = 0; i < bpp; i++)
- dst[i] = src[i];
- if (bpp == 4) {
- p = *(int *)dst;
- for (; i < size; i += bpp) {
- unsigned s = *(int *)(src + i);
- p = ((s & 0x7f7f7f7f) + (p & 0x7f7f7f7f)) ^ ((s ^ p) & 0x80808080);
- *(int *)(dst + i) = p;
- }
- } else {
-#define OP_SUB(x, s, l) ((x) + (s))
- UNROLL_FILTER(OP_SUB);
- }
- break;
- case PNG_FILTER_VALUE_UP:
- dsp->add_bytes_l2(dst, src, last, size);
- break;
- case PNG_FILTER_VALUE_AVG:
- for (i = 0; i < bpp; i++) {
- p = (last[i] >> 1);
- dst[i] = p + src[i];
- }
-#define OP_AVG(x, s, l) (((((x) + (l)) >> 1) + (s)) & 0xff)
- UNROLL_FILTER(OP_AVG);
- break;
- case PNG_FILTER_VALUE_PAETH:
- for (i = 0; i < bpp; i++) {
- p = last[i];
- dst[i] = p + src[i];
- }
- if (bpp > 2 && size > 4) {
- /* would write off the end of the array if we let it process
- * the last pixel with bpp=3 */
- int w = (bpp & 3) ? size - 3 : size;
-
- if (w > i) {
- dsp->add_paeth_prediction(dst + i, src + i, last + i, size - i, bpp);
- i = w;
- }
- }
- ff_add_png_paeth_prediction(dst + i, src + i, last + i, size - i, bpp);
- break;
- }
-}
-
-/* This used to be called "deloco" in FFmpeg
- * and is actually an inverse reversible colorspace transformation */
-#define YUV2RGB(NAME, TYPE) \
-static void deloco_ ## NAME(TYPE *dst, int size, int alpha) \
-{ \
- int i; \
- for (i = 0; i < size; i += 3 + alpha) { \
- int g = dst [i + 1]; \
- dst[i + 0] += g; \
- dst[i + 2] += g; \
- } \
-}
-
-YUV2RGB(rgb8, uint8_t)
-YUV2RGB(rgb16, uint16_t)
-
-/* process exactly one decompressed row */
-static void png_handle_row(PNGDecContext *s)
-{
- 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;
- if (s->y == 0)
- last_row = s->last_row;
- else
- last_row = ptr - s->image_linesize;
-
- 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,
- s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
- } else {
- deloco_rgb8(ptr - s->image_linesize, s->row_size,
- s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
- }
- }
- s->y++;
- if (s->y == s->cur_h) {
- s->state |= PNG_ALLIMAGE;
- if (s->filter_type == PNG_FILTER_TYPE_LOCO) {
- if (s->bit_depth == 16) {
- deloco_rgb16((uint16_t *)ptr, s->row_size / 2,
- s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
- } else {
- deloco_rgb8(ptr, s->row_size,
- s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
- }
- }
- }
- } else {
- got_line = 0;
- for (;;) {
- ptr = s->image_buf + s->image_linesize * (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);
- FFSWAP(uint8_t *, s->last_row, s->tmp_row);
- FFSWAP(unsigned int, s->last_row_size, s->tmp_row_size);
- got_line = 1;
- }
- if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) {
- png_put_interlaced_row(ptr, s->cur_w, s->bits_per_pixel, s->pass,
- s->color_type, s->last_row);
- }
- s->y++;
- if (s->y == s->cur_h) {
- memset(s->last_row, 0, s->row_size);
- for (;;) {
- if (s->pass == NB_PASSES - 1) {
- s->state |= PNG_ALLIMAGE;
- goto the_end;
- } else {
- s->pass++;
- s->y = 0;
- s->pass_row_size = ff_png_pass_row_size(s->pass,
- s->bits_per_pixel,
- s->cur_w);
- s->crow_size = s->pass_row_size + 1;
- if (s->pass_row_size != 0)
- break;
- /* skip pass if empty row */
- }
- }
- }
- }
-the_end:;
- }
-}
-
-static int png_decode_idat(PNGDecContext *s, int length)
-{
- int ret;
- s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb));
- s->zstream.next_in = (unsigned char *)s->gb.buffer;
- 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->state & PNG_ALLIMAGE)) {
- png_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(NULL, AV_LOG_WARNING,
- "%d undecompressed bytes left in buffer\n", s->zstream.avail_in);
- return 0;
- }
- }
- return 0;
-}
-
-static int decode_zbuf(AVBPrint *bp, const uint8_t *data,
- const uint8_t *data_end)
-{
- z_stream zstream;
- unsigned char *buf;
- unsigned buf_size;
- int ret;
-
- zstream.zalloc = ff_png_zalloc;
- zstream.zfree = ff_png_zfree;
- zstream.opaque = NULL;
- if (inflateInit(&zstream) != Z_OK)
- return AVERROR_EXTERNAL;
- zstream.next_in = (unsigned char *)data;
- zstream.avail_in = data_end - data;
- av_bprint_init(bp, 0, -1);
-
- while (zstream.avail_in > 0) {
- av_bprint_get_buffer(bp, 2, &buf, &buf_size);
- if (buf_size < 2) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- zstream.next_out = buf;
- zstream.avail_out = buf_size - 1;
- ret = inflate(&zstream, Z_PARTIAL_FLUSH);
- if (ret != Z_OK && ret != Z_STREAM_END) {
- ret = AVERROR_EXTERNAL;
- goto fail;
- }
- bp->len += zstream.next_out - buf;
- if (ret == Z_STREAM_END)
- break;
- }
- inflateEnd(&zstream);
- bp->str[bp->len] = 0;
- return 0;
-
-fail:
- inflateEnd(&zstream);
- av_bprint_finalize(bp, NULL);
- return ret;
-}
-
-static uint8_t *iso88591_to_utf8(const uint8_t *in, size_t size_in)
-{
- size_t extra = 0, i;
- uint8_t *out, *q;
-
- for (i = 0; i < size_in; i++)
- extra += in[i] >= 0x80;
- if (size_in == SIZE_MAX || extra > SIZE_MAX - size_in - 1)
- return NULL;
- q = out = av_malloc(size_in + extra + 1);
- if (!out)
- return NULL;
- for (i = 0; i < size_in; i++) {
- if (in[i] >= 0x80) {
- *(q++) = 0xC0 | (in[i] >> 6);
- *(q++) = 0x80 | (in[i] & 0x3F);
- } else {
- *(q++) = in[i];
- }
- }
- *(q++) = 0;
- return out;
-}
-
-static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed,
- AVDictionary **dict)
-{
- int ret, method;
- const uint8_t *data = s->gb.buffer;
- const uint8_t *data_end = data + length;
- const uint8_t *keyword = data;
- const uint8_t *keyword_end = memchr(keyword, 0, data_end - keyword);
- uint8_t *kw_utf8 = NULL, *text, *txt_utf8 = NULL;
- unsigned text_len;
- AVBPrint bp;
-
- if (!keyword_end)
- return AVERROR_INVALIDDATA;
- data = keyword_end + 1;
-
- if (compressed) {
- if (data == data_end)
- return AVERROR_INVALIDDATA;
- method = *(data++);
- if (method)
- return AVERROR_INVALIDDATA;
- if ((ret = decode_zbuf(&bp, data, data_end)) < 0)
- return ret;
- text_len = bp.len;
- av_bprint_finalize(&bp, (char **)&text);
- if (!text)
- return AVERROR(ENOMEM);
- } else {
- text = (uint8_t *)data;
- text_len = data_end - text;
- }
-
- kw_utf8 = iso88591_to_utf8(keyword, keyword_end - keyword);
- txt_utf8 = iso88591_to_utf8(text, text_len);
- if (text != data)
- av_free(text);
- if (!(kw_utf8 && txt_utf8)) {
- av_free(kw_utf8);
- av_free(txt_utf8);
- return AVERROR(ENOMEM);
- }
-
- av_dict_set(dict, kw_utf8, txt_utf8,
- AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
- return 0;
-}
-
-static int decode_ihdr_chunk(AVCodecContext *avctx, PNGDecContext *s,
- uint32_t length)
-{
- if (length != 13)
- return AVERROR_INVALIDDATA;
-
- if (s->state & PNG_IDAT) {
- av_log(avctx, AV_LOG_ERROR, "IHDR after IDAT\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (s->state & PNG_IHDR) {
- av_log(avctx, AV_LOG_ERROR, "Multiple IHDR\n");
- return AVERROR_INVALIDDATA;
- }
-
- s->width = s->cur_w = bytestream2_get_be32(&s->gb);
- s->height = s->cur_h = bytestream2_get_be32(&s->gb);
- if (av_image_check_size(s->width, s->height, 0, avctx)) {
- s->cur_w = s->cur_h = s->width = s->height = 0;
- av_log(avctx, AV_LOG_ERROR, "Invalid image size\n");
- return AVERROR_INVALIDDATA;
- }
- s->bit_depth = bytestream2_get_byte(&s->gb);
- s->color_type = bytestream2_get_byte(&s->gb);
- s->compression_type = bytestream2_get_byte(&s->gb);
- s->filter_type = bytestream2_get_byte(&s->gb);
- s->interlace_type = bytestream2_get_byte(&s->gb);
- bytestream2_skip(&s->gb, 4); /* crc */
- s->state |= PNG_IHDR;
- if (avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(avctx, AV_LOG_DEBUG, "width=%d height=%d depth=%d color_type=%d "
- "compression_type=%d filter_type=%d interlace_type=%d\n",
- s->width, s->height, s->bit_depth, s->color_type,
- s->compression_type, s->filter_type, s->interlace_type);
-
- return 0;
-}
-
-static int decode_phys_chunk(AVCodecContext *avctx, PNGDecContext *s)
-{
- if (s->state & PNG_IDAT) {
- av_log(avctx, AV_LOG_ERROR, "pHYs after IDAT\n");
- return AVERROR_INVALIDDATA;
- }
- avctx->sample_aspect_ratio.num = bytestream2_get_be32(&s->gb);
- avctx->sample_aspect_ratio.den = bytestream2_get_be32(&s->gb);
- if (avctx->sample_aspect_ratio.num < 0 || avctx->sample_aspect_ratio.den < 0)
- avctx->sample_aspect_ratio = (AVRational){ 0, 1 };
- bytestream2_skip(&s->gb, 1); /* unit specifier */
- bytestream2_skip(&s->gb, 4); /* crc */
-
- return 0;
-}
-
-static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s,
- uint32_t length, AVFrame *p)
-{
- int ret;
- size_t byte_depth = s->bit_depth > 8 ? 2 : 1;
-
- if (!(s->state & PNG_IHDR)) {
- av_log(avctx, AV_LOG_ERROR, "IDAT without IHDR\n");
- return AVERROR_INVALIDDATA;
- }
- if (!(s->state & PNG_IDAT)) {
- /* init image info */
- avctx->width = s->width;
- avctx->height = s->height;
-
- s->channels = ff_png_get_nb_channels(s->color_type);
- s->bits_per_pixel = s->bit_depth * s->channels;
- s->bpp = (s->bits_per_pixel + 7) >> 3;
- s->row_size = (s->cur_w * s->bits_per_pixel + 7) >> 3;
-
- if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
- s->color_type == PNG_COLOR_TYPE_RGB) {
- avctx->pix_fmt = AV_PIX_FMT_RGB24;
- } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
- s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
- avctx->pix_fmt = AV_PIX_FMT_RGBA;
- } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
- s->color_type == PNG_COLOR_TYPE_GRAY) {
- avctx->pix_fmt = AV_PIX_FMT_GRAY8;
- } else if (s->bit_depth == 16 &&
- s->color_type == PNG_COLOR_TYPE_GRAY) {
- avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
- } else if (s->bit_depth == 16 &&
- s->color_type == PNG_COLOR_TYPE_RGB) {
- avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
- } else if (s->bit_depth == 16 &&
- s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
- avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
- } else if ((s->bits_per_pixel == 1 || s->bits_per_pixel == 2 || s->bits_per_pixel == 4 || s->bits_per_pixel == 8) &&
- s->color_type == PNG_COLOR_TYPE_PALETTE) {
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
- } else if (s->bit_depth == 1 && s->bits_per_pixel == 1 && avctx->codec_id != AV_CODEC_ID_APNG) {
- avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
- } else if (s->bit_depth == 8 &&
- s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
- avctx->pix_fmt = AV_PIX_FMT_YA8;
- } else if (s->bit_depth == 16 &&
- s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
- avctx->pix_fmt = AV_PIX_FMT_YA16BE;
- } else {
- av_log(avctx, AV_LOG_ERROR, "unsupported bit depth %d "
- "and color type %d\n",
- s->bit_depth, s->color_type);
- return AVERROR_INVALIDDATA;
- }
-
- if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE) {
- switch (avctx->pix_fmt) {
- case AV_PIX_FMT_RGB24:
- avctx->pix_fmt = AV_PIX_FMT_RGBA;
- break;
-
- case AV_PIX_FMT_RGB48BE:
- avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
- break;
-
- case AV_PIX_FMT_GRAY8:
- avctx->pix_fmt = AV_PIX_FMT_YA8;
- break;
-
- case AV_PIX_FMT_GRAY16BE:
- avctx->pix_fmt = AV_PIX_FMT_YA16BE;
- break;
-
- default:
- avpriv_request_sample(avctx, "bit depth %d "
- "and color type %d with TRNS",
- s->bit_depth, s->color_type);
- return AVERROR_INVALIDDATA;
- }
-
- s->bpp += byte_depth;
- }
-
- 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;
- }
- ff_thread_finish_setup(avctx);
-
- p->pict_type = AV_PICTURE_TYPE_I;
- p->key_frame = 1;
- p->interlaced_frame = !!s->interlace_type;
-
- /* compute the compressed row size */
- if (!s->interlace_type) {
- s->crow_size = s->row_size + 1;
- } else {
- s->pass = 0;
- s->pass_row_size = ff_png_pass_row_size(s->pass,
- s->bits_per_pixel,
- s->cur_w);
- s->crow_size = s->pass_row_size + 1;
- }
- 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));
- /* empty row is used if differencing to the first row */
- av_fast_padded_mallocz(&s->last_row, &s->last_row_size, s->row_size);
- if (!s->last_row)
- return AVERROR_INVALIDDATA;
- if (s->interlace_type ||
- s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
- av_fast_padded_malloc(&s->tmp_row, &s->tmp_row_size, s->row_size);
- if (!s->tmp_row)
- return AVERROR_INVALIDDATA;
- }
- /* compressed row */
- av_fast_padded_malloc(&s->buffer, &s->buffer_size, s->row_size + 16);
- if (!s->buffer)
- return AVERROR(ENOMEM);
-
- /* we want crow_buf+1 to be 16-byte aligned */
- s->crow_buf = s->buffer + 15;
- s->zstream.avail_out = s->crow_size;
- s->zstream.next_out = s->crow_buf;
- }
-
- s->state |= PNG_IDAT;
-
- /* set image to non-transparent bpp while decompressing */
- if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE)
- s->bpp -= byte_depth;
-
- ret = png_decode_idat(s, length);
-
- if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE)
- s->bpp += byte_depth;
-
- if (ret < 0)
- return ret;
-
- bytestream2_skip(&s->gb, 4); /* crc */
-
- return 0;
-}
-
-static int decode_plte_chunk(AVCodecContext *avctx, PNGDecContext *s,
- uint32_t length)
-{
- int n, i, r, g, b;
-
- if ((length % 3) != 0 || length > 256 * 3)
- return AVERROR_INVALIDDATA;
- /* read the palette */
- n = length / 3;
- for (i = 0; i < n; i++) {
- r = bytestream2_get_byte(&s->gb);
- g = bytestream2_get_byte(&s->gb);
- b = bytestream2_get_byte(&s->gb);
- s->palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | b;
- }
- for (; i < 256; i++)
- s->palette[i] = (0xFFU << 24);
- s->state |= PNG_PLTE;
- bytestream2_skip(&s->gb, 4); /* crc */
-
- return 0;
-}
-
-static int decode_trns_chunk(AVCodecContext *avctx, PNGDecContext *s,
- uint32_t length)
-{
- int v, i;
-
- if (!(s->state & PNG_IHDR)) {
- av_log(avctx, AV_LOG_ERROR, "trns before IHDR\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (s->state & PNG_IDAT) {
- av_log(avctx, AV_LOG_ERROR, "trns after IDAT\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
- if (length > 256 || !(s->state & PNG_PLTE))
- return AVERROR_INVALIDDATA;
-
- for (i = 0; i < length; i++) {
- v = bytestream2_get_byte(&s->gb);
- s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
- }
- } else if (s->color_type == PNG_COLOR_TYPE_GRAY || s->color_type == PNG_COLOR_TYPE_RGB) {
- if ((s->color_type == PNG_COLOR_TYPE_GRAY && length != 2) ||
- (s->color_type == PNG_COLOR_TYPE_RGB && length != 6) ||
- s->bit_depth == 1)
- return AVERROR_INVALIDDATA;
-
- for (i = 0; i < length / 2; i++) {
- /* only use the least significant bits */
- v = bytestream2_get_be16(&s->gb) & ((1 << s->bit_depth) - 1);
-
- if (s->bit_depth > 8)
- AV_WB16(&s->transparent_color_be[2 * i], v);
- else
- s->transparent_color_be[i] = v;
- }
- } else {
- return AVERROR_INVALIDDATA;
- }
-
- bytestream2_skip(&s->gb, 4); /* crc */
- s->has_trns = 1;
-
- return 0;
-}
-
-static void handle_small_bpp(PNGDecContext *s, AVFrame *p)
-{
- if (s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE) {
- int i, j, k;
- uint8_t *pd = p->data[0];
- for (j = 0; j < s->height; j++) {
- i = s->width / 8;
- for (k = 7; k >= 1; k--)
- if ((s->width&7) >= k)
- pd[8*i + k - 1] = (pd[i]>>8-k) & 1;
- for (i--; i >= 0; i--) {
- pd[8*i + 7]= pd[i] & 1;
- pd[8*i + 6]= (pd[i]>>1) & 1;
- pd[8*i + 5]= (pd[i]>>2) & 1;
- pd[8*i + 4]= (pd[i]>>3) & 1;
- pd[8*i + 3]= (pd[i]>>4) & 1;
- pd[8*i + 2]= (pd[i]>>5) & 1;
- pd[8*i + 1]= (pd[i]>>6) & 1;
- pd[8*i + 0]= pd[i]>>7;
- }
- pd += s->image_linesize;
- }
- } else if (s->bits_per_pixel == 2) {
- int i, j;
- uint8_t *pd = p->data[0];
- for (j = 0; j < s->height; j++) {
- i = s->width / 4;
- if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
- if ((s->width&3) >= 3) pd[4*i + 2]= (pd[i] >> 2) & 3;
- if ((s->width&3) >= 2) pd[4*i + 1]= (pd[i] >> 4) & 3;
- if ((s->width&3) >= 1) pd[4*i + 0]= pd[i] >> 6;
- for (i--; i >= 0; i--) {
- pd[4*i + 3]= pd[i] & 3;
- pd[4*i + 2]= (pd[i]>>2) & 3;
- pd[4*i + 1]= (pd[i]>>4) & 3;
- pd[4*i + 0]= pd[i]>>6;
- }
- } else {
- if ((s->width&3) >= 3) pd[4*i + 2]= ((pd[i]>>2) & 3)*0x55;
- if ((s->width&3) >= 2) pd[4*i + 1]= ((pd[i]>>4) & 3)*0x55;
- if ((s->width&3) >= 1) pd[4*i + 0]= ( pd[i]>>6 )*0x55;
- for (i--; i >= 0; i--) {
- pd[4*i + 3]= ( pd[i] & 3)*0x55;
- pd[4*i + 2]= ((pd[i]>>2) & 3)*0x55;
- pd[4*i + 1]= ((pd[i]>>4) & 3)*0x55;
- pd[4*i + 0]= ( pd[i]>>6 )*0x55;
- }
- }
- pd += s->image_linesize;
- }
- } else if (s->bits_per_pixel == 4) {
- int i, j;
- uint8_t *pd = p->data[0];
- for (j = 0; j < s->height; j++) {
- i = s->width/2;
- if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
- if (s->width&1) pd[2*i+0]= pd[i]>>4;
- for (i--; i >= 0; i--) {
- pd[2*i + 1] = pd[i] & 15;
- pd[2*i + 0] = pd[i] >> 4;
- }
- } else {
- if (s->width & 1) pd[2*i + 0]= (pd[i] >> 4) * 0x11;
- for (i--; i >= 0; i--) {
- pd[2*i + 1] = (pd[i] & 15) * 0x11;
- pd[2*i + 0] = (pd[i] >> 4) * 0x11;
- }
- }
- pd += s->image_linesize;
- }
- }
-}
-
-static int decode_fctl_chunk(AVCodecContext *avctx, PNGDecContext *s,
- uint32_t length)
-{
- uint32_t sequence_number;
- int cur_w, cur_h, x_offset, y_offset, dispose_op, blend_op;
-
- if (length != 26)
- return AVERROR_INVALIDDATA;
-
- if (!(s->state & PNG_IHDR)) {
- av_log(avctx, AV_LOG_ERROR, "fctl before IHDR\n");
- return AVERROR_INVALIDDATA;
- }
-
- s->last_w = s->cur_w;
- s->last_h = s->cur_h;
- s->last_x_offset = s->x_offset;
- s->last_y_offset = s->y_offset;
- s->last_dispose_op = s->dispose_op;
-
- sequence_number = bytestream2_get_be32(&s->gb);
- cur_w = bytestream2_get_be32(&s->gb);
- cur_h = bytestream2_get_be32(&s->gb);
- x_offset = bytestream2_get_be32(&s->gb);
- y_offset = bytestream2_get_be32(&s->gb);
- bytestream2_skip(&s->gb, 4); /* delay_num (2), delay_den (2) */
- dispose_op = bytestream2_get_byte(&s->gb);
- blend_op = bytestream2_get_byte(&s->gb);
- bytestream2_skip(&s->gb, 4); /* crc */
-
- if (sequence_number == 0 &&
- (cur_w != s->width ||
- cur_h != s->height ||
- x_offset != 0 ||
- y_offset != 0) ||
- cur_w <= 0 || cur_h <= 0 ||
- x_offset < 0 || y_offset < 0 ||
- cur_w > s->width - x_offset|| cur_h > s->height - y_offset)
- return AVERROR_INVALIDDATA;
-
- if (blend_op != APNG_BLEND_OP_OVER && blend_op != APNG_BLEND_OP_SOURCE) {
- av_log(avctx, AV_LOG_ERROR, "Invalid blend_op %d\n", blend_op);
- return AVERROR_INVALIDDATA;
- }
-
- if (sequence_number == 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
- dispose_op = APNG_DISPOSE_OP_BACKGROUND;
- }
-
- if (blend_op == APNG_BLEND_OP_OVER && !s->has_trns && (
- avctx->pix_fmt == AV_PIX_FMT_RGB24 ||
- avctx->pix_fmt == AV_PIX_FMT_RGB48BE ||
- avctx->pix_fmt == AV_PIX_FMT_PAL8 ||
- avctx->pix_fmt == AV_PIX_FMT_GRAY8 ||
- avctx->pix_fmt == AV_PIX_FMT_GRAY16BE ||
- avctx->pix_fmt == AV_PIX_FMT_MONOBLACK
- )) {
- // APNG_BLEND_OP_OVER is the same as APNG_BLEND_OP_SOURCE when there is no alpha channel
- blend_op = APNG_BLEND_OP_SOURCE;
- }
-
- s->cur_w = cur_w;
- s->cur_h = cur_h;
- s->x_offset = x_offset;
- s->y_offset = y_offset;
- s->dispose_op = dispose_op;
- s->blend_op = blend_op;
-
- return 0;
-}
-
-static void handle_p_frame_png(PNGDecContext *s, AVFrame *p)
-{
- int i, j;
- uint8_t *pd = p->data[0];
- uint8_t *pd_last = s->last_picture.f->data[0];
- int ls = FFMIN(av_image_get_linesize(p->format, s->width, 0), s->width * s->bpp);
-
- ff_thread_await_progress(&s->last_picture, INT_MAX, 0);
- 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;
- }
-}
-
-// divide by 255 and round to nearest
-// apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16
-#define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
-
-static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s,
- AVFrame *p)
-{
- size_t x, y;
- uint8_t *buffer = av_malloc(s->image_linesize * s->height);
-
- if (!buffer)
- return AVERROR(ENOMEM);
-
- if (s->blend_op == APNG_BLEND_OP_OVER &&
- avctx->pix_fmt != AV_PIX_FMT_RGBA &&
- avctx->pix_fmt != AV_PIX_FMT_GRAY8A &&
- avctx->pix_fmt != AV_PIX_FMT_PAL8) {
- avpriv_request_sample(avctx, "Blending with pixel format %s",
- av_get_pix_fmt_name(avctx->pix_fmt));
- return AVERROR_PATCHWELCOME;
- }
-
- // 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);
-
- 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);
-
- 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);
- }
-
- // Perform blending
- if (s->blend_op == APNG_BLEND_OP_SOURCE) {
- 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;
- 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;
- uint8_t output[10];
-
- // Since we might be blending alpha onto alpha, we use the following equations:
- // output_alpha = foreground_alpha + (1 - foreground_alpha) * background_alpha
- // output = (foreground_alpha * foreground + (1 - foreground_alpha) * background_alpha * background) / output_alpha
-
- switch (avctx->pix_fmt) {
- case AV_PIX_FMT_RGBA:
- foreground_alpha = foreground[3];
- background_alpha = background[3];
- break;
-
- case AV_PIX_FMT_GRAY8A:
- foreground_alpha = foreground[1];
- background_alpha = background[1];
- break;
-
- case AV_PIX_FMT_PAL8:
- foreground_alpha = s->palette[foreground[0]] >> 24;
- background_alpha = s->palette[background[0]] >> 24;
- break;
- }
-
- if (foreground_alpha == 0)
- continue;
-
- if (foreground_alpha == 255) {
- memcpy(background, foreground, 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;
- }
-
- output_alpha = foreground_alpha + FAST_DIV255((255 - foreground_alpha) * background_alpha);
-
- av_assert0(s->bpp <= 10);
-
- for (b = 0; b < s->bpp - 1; ++b) {
- if (output_alpha == 0) {
- output[b] = 0;
- } else if (background_alpha == 255) {
- output[b] = FAST_DIV255(foreground_alpha * foreground[b] + (255 - foreground_alpha) * background[b]);
- } else {
- output[b] = (255 * foreground_alpha * foreground[b] + (255 - foreground_alpha) * background_alpha * background[b]) / (255 * output_alpha);
- }
- }
- output[b] = output_alpha;
- memcpy(background, 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)
-{
- AVDictionary *metadata = NULL;
- uint32_t tag, length;
- int decode_next_dat = 0;
- int ret;
-
- for (;;) {
- length = bytestream2_get_bytes_left(&s->gb);
- if (length <= 0) {
- if (CONFIG_APNG_DECODER && avctx->codec_id == AV_CODEC_ID_APNG && length == 0) {
- if (!(s->state & PNG_IDAT))
- return 0;
- else
- goto exit_loop;
- }
- av_log(avctx, AV_LOG_ERROR, "%d bytes left\n", length);
- if ( s->state & PNG_ALLIMAGE
- && avctx->strict_std_compliance <= FF_COMPLIANCE_NORMAL)
- goto exit_loop;
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
-
- length = bytestream2_get_be32(&s->gb);
- if (length > 0x7fffffff || length > bytestream2_get_bytes_left(&s->gb)) {
- av_log(avctx, AV_LOG_ERROR, "chunk too big\n");
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
- tag = bytestream2_get_le32(&s->gb);
- if (avctx->debug & FF_DEBUG_STARTCODE)
- av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n",
- (tag & 0xff),
- ((tag >> 8) & 0xff),
- ((tag >> 16) & 0xff),
- ((tag >> 24) & 0xff), length);
- switch (tag) {
- case MKTAG('I', 'H', 'D', 'R'):
- if ((ret = decode_ihdr_chunk(avctx, s, length)) < 0)
- goto fail;
- break;
- case MKTAG('p', 'H', 'Y', 's'):
- if ((ret = decode_phys_chunk(avctx, s)) < 0)
- goto fail;
- break;
- case MKTAG('f', 'c', 'T', 'L'):
- if (!CONFIG_APNG_DECODER || avctx->codec_id != AV_CODEC_ID_APNG)
- goto skip_tag;
- if ((ret = decode_fctl_chunk(avctx, s, length)) < 0)
- goto fail;
- decode_next_dat = 1;
- break;
- case MKTAG('f', 'd', 'A', 'T'):
- if (!CONFIG_APNG_DECODER || avctx->codec_id != AV_CODEC_ID_APNG)
- goto skip_tag;
- if (!decode_next_dat) {
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
- bytestream2_get_be32(&s->gb);
- length -= 4;
- /* fallthrough */
- case MKTAG('I', 'D', 'A', 'T'):
- if (CONFIG_APNG_DECODER && avctx->codec_id == AV_CODEC_ID_APNG && !decode_next_dat)
- goto skip_tag;
- if ((ret = decode_idat_chunk(avctx, s, length, p)) < 0)
- goto fail;
- break;
- case MKTAG('P', 'L', 'T', 'E'):
- if (decode_plte_chunk(avctx, s, length) < 0)
- goto skip_tag;
- break;
- case MKTAG('t', 'R', 'N', 'S'):
- if (decode_trns_chunk(avctx, s, length) < 0)
- goto skip_tag;
- break;
- case MKTAG('t', 'E', 'X', 't'):
- if (decode_text_chunk(s, length, 0, &metadata) < 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, &metadata) < 0)
- av_log(avctx, AV_LOG_WARNING, "Broken zTXt chunk\n");
- bytestream2_skip(&s->gb, length + 4);
- break;
- case MKTAG('I', 'E', 'N', 'D'):
- if (!(s->state & PNG_ALLIMAGE))
- av_log(avctx, AV_LOG_ERROR, "IEND without all image\n");
- if (!(s->state & (PNG_ALLIMAGE|PNG_IDAT))) {
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
- bytestream2_skip(&s->gb, 4); /* crc */
- goto exit_loop;
- default:
- /* skip tag */
-skip_tag:
- bytestream2_skip(&s->gb, length + 4);
- break;
- }
- }
-exit_loop:
-
- if (s->bits_per_pixel <= 4)
- handle_small_bpp(s, p);
-
- /* apply transparency if needed */
- if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE) {
- size_t byte_depth = s->bit_depth > 8 ? 2 : 1;
- size_t raw_bpp = s->bpp - byte_depth;
- unsigned x, y;
-
- av_assert0(s->bit_depth > 1);
-
- for (y = 0; y < s->height; ++y) {
- uint8_t *row = &s->image_buf[s->image_linesize * y];
-
- /* since we're updating in-place, we have to go from right to left */
- for (x = s->width; x > 0; --x) {
- uint8_t *pixel = &row[s->bpp * (x - 1)];
- memmove(pixel, &row[raw_bpp * (x - 1)], raw_bpp);
-
- if (!memcmp(pixel, s->transparent_color_be, raw_bpp)) {
- memset(&pixel[raw_bpp], 0, byte_depth);
- } else {
- memset(&pixel[raw_bpp], 0xff, byte_depth);
- }
- }
- }
- }
-
- /* handle p-frames only if a predecessor frame is available */
- if (s->last_picture.f->data[0]) {
- if ( !(avpkt->flags & AV_PKT_FLAG_KEY) && avctx->codec_tag != AV_RL32("MPNG")
- && s->last_picture.f->width == p->width
- && s->last_picture.f->height== p->height
- && s->last_picture.f->format== p->format
- ) {
- if (CONFIG_PNG_DECODER && avctx->codec_id != AV_CODEC_ID_APNG)
- handle_p_frame_png(s, p);
- else if (CONFIG_APNG_DECODER &&
- 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);
-
- av_frame_set_metadata(p, metadata);
- metadata = NULL;
- return 0;
-
-fail:
- av_dict_free(&metadata);
- ff_thread_report_progress(&s->picture, INT_MAX, 0);
- return ret;
-}
-
-#if CONFIG_PNG_DECODER
-static int decode_frame_png(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- PNGDecContext *const s = avctx->priv_data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- AVFrame *p;
- int64_t sig;
- int ret;
-
- ff_thread_release_buffer(avctx, &s->last_picture);
- FFSWAP(ThreadFrame, s->picture, s->last_picture);
- p = s->picture.f;
-
- bytestream2_init(&s->gb, buf, buf_size);
-
- /* check signature */
- sig = bytestream2_get_be64(&s->gb);
- if (sig != PNGSIG &&
- sig != MNGSIG) {
- av_log(avctx, AV_LOG_ERROR, "Invalid PNG signature 0x%08"PRIX64".\n", sig);
- return AVERROR_INVALIDDATA;
- }
-
- s->y = s->state = s->has_trns = 0;
-
- /* init the zlib */
- s->zstream.zalloc = ff_png_zalloc;
- s->zstream.zfree = ff_png_zfree;
- s->zstream.opaque = NULL;
- ret = inflateInit(&s->zstream);
- if (ret != Z_OK) {
- av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret);
- return AVERROR_EXTERNAL;
- }
-
- if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0)
- goto the_end;
-
- if ((ret = av_frame_ref(data, s->picture.f)) < 0)
- return ret;
-
- *got_frame = 1;
-
- ret = bytestream2_tell(&s->gb);
-the_end:
- inflateEnd(&s->zstream);
- s->crow_buf = NULL;
- return ret;
-}
-#endif
-
-#if CONFIG_APNG_DECODER
-static int decode_frame_apng(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- PNGDecContext *const s = avctx->priv_data;
- int ret;
- AVFrame *p;
-
- ff_thread_release_buffer(avctx, &s->last_picture);
- FFSWAP(ThreadFrame, s->picture, s->last_picture);
- p = s->picture.f;
-
- if (!(s->state & PNG_IHDR)) {
- if (!avctx->extradata_size)
- return AVERROR_INVALIDDATA;
-
- /* only init fields, there is no zlib use in extradata */
- s->zstream.zalloc = ff_png_zalloc;
- s->zstream.zfree = ff_png_zfree;
-
- bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size);
- if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0)
- goto end;
- }
-
- /* reset state for a new frame */
- if ((ret = inflateInit(&s->zstream)) != Z_OK) {
- av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret);
- ret = AVERROR_EXTERNAL;
- goto end;
- }
- s->y = 0;
- s->state &= ~(PNG_IDAT | PNG_ALLIMAGE);
- bytestream2_init(&s->gb, avpkt->data, avpkt->size);
- if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0)
- goto end;
-
- if (!(s->state & PNG_ALLIMAGE))
- av_log(avctx, AV_LOG_WARNING, "Frame did not contain a complete image\n");
- if (!(s->state & (PNG_ALLIMAGE|PNG_IDAT))) {
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- if ((ret = av_frame_ref(data, s->picture.f)) < 0)
- goto end;
-
- *got_frame = 1;
- ret = bytestream2_tell(&s->gb);
-
-end:
- inflateEnd(&s->zstream);
- return ret;
-}
-#endif
-
-static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
-{
- PNGDecContext *psrc = src->priv_data;
- PNGDecContext *pdst = dst->priv_data;
- 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;
- pdst->color_type = psrc->color_type;
- pdst->compression_type = psrc->compression_type;
- pdst->interlace_type = psrc->interlace_type;
- pdst->filter_type = psrc->filter_type;
- pdst->cur_w = psrc->cur_w;
- pdst->cur_h = psrc->cur_h;
- pdst->x_offset = psrc->x_offset;
- pdst->y_offset = psrc->y_offset;
- pdst->has_trns = psrc->has_trns;
- memcpy(pdst->transparent_color_be, psrc->transparent_color_be, sizeof(pdst->transparent_color_be));
-
- pdst->dispose_op = psrc->dispose_op;
-
- memcpy(pdst->palette, psrc->palette, sizeof(pdst->palette));
-
- pdst->state |= psrc->state & (PNG_IHDR | PNG_PLTE);
-
- 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;
-
- 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)
- return ret;
- }
-
- return 0;
-}
-
-static av_cold int png_dec_init(AVCodecContext *avctx)
-{
- PNGDecContext *s = avctx->priv_data;
-
- avctx->color_range = AVCOL_RANGE_JPEG;
-
- 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);
- av_frame_free(&s->last_picture.f);
- av_frame_free(&s->picture.f);
- return AVERROR(ENOMEM);
- }
-
- if (!avctx->internal->is_copy) {
- avctx->internal->allocate_progress = 1;
- ff_pngdsp_init(&s->dsp);
- }
-
- return 0;
-}
-
-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);
- av_frame_free(&s->picture.f);
- av_freep(&s->buffer);
- s->buffer_size = 0;
- av_freep(&s->last_row);
- s->last_row_size = 0;
- av_freep(&s->tmp_row);
- s->tmp_row_size = 0;
-
- return 0;
-}
-
-#if CONFIG_APNG_DECODER
-AVCodec ff_apng_decoder = {
- .name = "apng",
- .long_name = NULL_IF_CONFIG_SMALL("APNG (Animated Portable Network Graphics) image"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_APNG,
- .priv_data_size = sizeof(PNGDecContext),
- .init = png_dec_init,
- .close = png_dec_end,
- .decode = decode_frame_apng,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(png_dec_init),
- .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/,
-};
-#endif
-
-#if CONFIG_PNG_DECODER
-AVCodec ff_png_decoder = {
- .name = "png",
- .long_name = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_PNG,
- .priv_data_size = sizeof(PNGDecContext),
- .init = png_dec_init,
- .close = png_dec_end,
- .decode = decode_frame_png,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(png_dec_init),
- .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/,
-};
-#endif
diff --git a/ffmpeg-2-8-11/libavcodec/pnm.c b/ffmpeg-2-8-11/libavcodec/pnm.c
deleted file mode 100644
index 1675959..0000000
--- a/ffmpeg-2-8-11/libavcodec/pnm.c
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * PNM image format
- * Copyright (c) 2002, 2003 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 <stdlib.h>
-#include <string.h>
-
-#include "libavutil/imgutils.h"
-#include "avcodec.h"
-#include "pnm.h"
-
-static inline int pnm_space(int c)
-{
- return c == ' ' || c == '\n' || c == '\r' || c == '\t';
-}
-
-static void pnm_get(PNMContext *sc, char *str, int buf_size)
-{
- char *s;
- int c;
-
- /* skip spaces and comments */
- while (sc->bytestream < sc->bytestream_end) {
- c = *sc->bytestream++;
- if (c == '#') {
- while (c != '\n' && sc->bytestream < sc->bytestream_end) {
- c = *sc->bytestream++;
- }
- } else if (!pnm_space(c)) {
- break;
- }
- }
-
- s = str;
- while (sc->bytestream < sc->bytestream_end && !pnm_space(c)) {
- if ((s - str) < buf_size - 1)
- *s++ = c;
- c = *sc->bytestream++;
- }
- *s = '\0';
-}
-
-int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)
-{
- char buf1[32], tuple_type[32];
- int h, w, depth, maxval;
-
- pnm_get(s, buf1, sizeof(buf1));
- if(buf1[0] != 'P')
- return AVERROR_INVALIDDATA;
- s->type= buf1[1]-'0';
-
- if (s->type==1 || s->type==4) {
- avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
- } else if (s->type==2 || s->type==5) {
- if (avctx->codec_id == AV_CODEC_ID_PGMYUV)
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- else
- avctx->pix_fmt = AV_PIX_FMT_GRAY8;
- } else if (s->type==3 || s->type==6) {
- avctx->pix_fmt = AV_PIX_FMT_RGB24;
- } else if (s->type==7) {
- w = -1;
- h = -1;
- maxval = -1;
- depth = -1;
- tuple_type[0] = '\0';
- for (;;) {
- pnm_get(s, buf1, sizeof(buf1));
- if (!strcmp(buf1, "WIDTH")) {
- pnm_get(s, buf1, sizeof(buf1));
- w = strtol(buf1, NULL, 10);
- } else if (!strcmp(buf1, "HEIGHT")) {
- pnm_get(s, buf1, sizeof(buf1));
- h = strtol(buf1, NULL, 10);
- } else if (!strcmp(buf1, "DEPTH")) {
- pnm_get(s, buf1, sizeof(buf1));
- depth = strtol(buf1, NULL, 10);
- } else if (!strcmp(buf1, "MAXVAL")) {
- pnm_get(s, buf1, sizeof(buf1));
- maxval = strtol(buf1, NULL, 10);
- } else if (!strcmp(buf1, "TUPLTYPE") ||
- /* libavcodec used to write invalid files */
- !strcmp(buf1, "TUPLETYPE")) {
- pnm_get(s, tuple_type, sizeof(tuple_type));
- } else if (!strcmp(buf1, "ENDHDR")) {
- break;
- } else {
- return AVERROR_INVALIDDATA;
- }
- }
- /* check that all tags are present */
- if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || av_image_check_size(w, h, 0, avctx) || s->bytestream >= s->bytestream_end)
- return AVERROR_INVALIDDATA;
-
- avctx->width = w;
- avctx->height = h;
- s->maxval = maxval;
- if (depth == 1) {
- if (maxval == 1) {
- avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
- } else if (maxval < 256) {
- avctx->pix_fmt = AV_PIX_FMT_GRAY8;
- } else {
- avctx->pix_fmt = AV_PIX_FMT_GRAY16;
- }
- } else if (depth == 2) {
- if (maxval < 256) {
- avctx->pix_fmt = AV_PIX_FMT_GRAY8A;
- } else {
- avctx->pix_fmt = AV_PIX_FMT_YA16;
- }
- } else if (depth == 3) {
- if (maxval < 256) {
- avctx->pix_fmt = AV_PIX_FMT_RGB24;
- } else {
- avctx->pix_fmt = AV_PIX_FMT_RGB48;
- }
- } else if (depth == 4) {
- if (maxval < 256) {
- avctx->pix_fmt = AV_PIX_FMT_RGBA;
- } else {
- avctx->pix_fmt = AV_PIX_FMT_RGBA64;
- }
- } else {
- return AVERROR_INVALIDDATA;
- }
- return 0;
- } else {
- return AVERROR_INVALIDDATA;
- }
- pnm_get(s, buf1, sizeof(buf1));
- w = atoi(buf1);
- pnm_get(s, buf1, sizeof(buf1));
- h = atoi(buf1);
- if(w <= 0 || h <= 0 || av_image_check_size(w, h, 0, avctx) || s->bytestream >= s->bytestream_end)
- return AVERROR_INVALIDDATA;
-
- avctx->width = w;
- avctx->height = h;
-
- if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE && avctx->pix_fmt != AV_PIX_FMT_MONOBLACK) {
- pnm_get(s, buf1, sizeof(buf1));
- s->maxval = atoi(buf1);
- if (s->maxval <= 0) {
- av_log(avctx, AV_LOG_ERROR, "Invalid maxval: %d\n", s->maxval);
- s->maxval = 255;
- }
- if (s->maxval >= 256) {
- if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
- avctx->pix_fmt = AV_PIX_FMT_GRAY16;
- } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {
- avctx->pix_fmt = AV_PIX_FMT_RGB48;
- } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P && s->maxval < 65536) {
- if (s->maxval < 512)
- avctx->pix_fmt = AV_PIX_FMT_YUV420P9;
- else if (s->maxval < 1024)
- avctx->pix_fmt = AV_PIX_FMT_YUV420P10;
- else
- avctx->pix_fmt = AV_PIX_FMT_YUV420P16;
- } else {
- av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format\n");
- avctx->pix_fmt = AV_PIX_FMT_NONE;
- return AVERROR_INVALIDDATA;
- }
- }
- }else
- s->maxval=1;
- /* more check if YUV420 */
- if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_PLANAR) {
- if ((avctx->width & 1) != 0)
- return AVERROR_INVALIDDATA;
- h = (avctx->height * 2);
- if ((h % 3) != 0)
- return AVERROR_INVALIDDATA;
- h /= 3;
- avctx->height = h;
- }
- return 0;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/qdrw.c b/ffmpeg-2-8-11/libavcodec/qdrw.c
deleted file mode 100644
index 0a31b41..0000000
--- a/ffmpeg-2-8-11/libavcodec/qdrw.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * QuickDraw (qdrw) codec
- * Copyright (c) 2004 Konstantin Shishkov
- * Copyright (c) 2015 Vittorio Giovara
- *
- * 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
- * Apple QuickDraw codec.
- * https://developer.apple.com/legacy/library/documentation/mac/QuickDraw/QuickDraw-461.html
- */
-
-#include "libavutil/common.h"
-#include "libavutil/intreadwrite.h"
-#include "avcodec.h"
-#include "bytestream.h"
-#include "internal.h"
-
-enum QuickdrawOpcodes {
- PACKBITSRECT = 0x0098,
- PACKBITSRGN,
- DIRECTBITSRECT,
- DIRECTBITSRGN,
-
- EOP = 0x00FF,
-};
-
-static int parse_palette(AVCodecContext *avctx, GetByteContext *gbc,
- uint32_t *pal, int colors)
-{
- int i;
-
- for (i = 0; i <= colors; i++) {
- uint8_t r, g, b;
- unsigned int idx = bytestream2_get_be16(gbc); /* color index */
- if (idx > 255) {
- av_log(avctx, AV_LOG_WARNING,
- "Palette index out of range: %u\n", idx);
- bytestream2_skip(gbc, 6);
- continue;
- }
- r = bytestream2_get_byte(gbc);
- bytestream2_skip(gbc, 1);
- g = bytestream2_get_byte(gbc);
- bytestream2_skip(gbc, 1);
- b = bytestream2_get_byte(gbc);
- bytestream2_skip(gbc, 1);
- pal[idx] = (0xFFU << 24) | (r << 16) | (g << 8) | b;
- }
- return 0;
-}
-
-static int decode_rle(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc,
- int step)
-{
- int i, j;
- int offset = avctx->width * step;
- uint8_t *outdata = p->data[0];
-
- for (i = 0; i < avctx->height; i++) {
- int size, left, code, pix;
- uint8_t *out = outdata;
- int pos = 0;
-
- /* size of packed line */
- size = left = bytestream2_get_be16(gbc);
- if (bytestream2_get_bytes_left(gbc) < size)
- return AVERROR_INVALIDDATA;
-
- /* decode line */
- while (left > 0) {
- code = bytestream2_get_byte(gbc);
- if (code & 0x80 ) { /* run */
- pix = bytestream2_get_byte(gbc);
- for (j = 0; j < 257 - code; j++) {
- out[pos] = pix;
- pos += step;
- if (pos >= offset) {
- pos -= offset;
- pos++;
- }
- if (pos >= offset)
- return AVERROR_INVALIDDATA;
- }
- left -= 2;
- } else { /* copy */
- for (j = 0; j < code + 1; j++) {
- out[pos] = bytestream2_get_byte(gbc);
- pos += step;
- if (pos >= offset) {
- pos -= offset;
- pos++;
- }
- if (pos >= offset)
- return AVERROR_INVALIDDATA;
- }
- left -= 2 + code;
- }
- }
- outdata += p->linesize[0];
- }
- return 0;
-}
-
-static int check_header(const char *buf, int buf_size)
-{
- unsigned w, h, v0, v1;
-
- if (buf_size < 40)
- return 0;
-
- w = AV_RB16(buf+6);
- h = AV_RB16(buf+8);
- v0 = AV_RB16(buf+10);
- v1 = AV_RB16(buf+12);
-
- if (!w || !h)
- return 0;
-
- if (v0 == 0x1101)
- return 1;
- if (v0 == 0x0011 && v1 == 0x02FF)
- return 2;
- return 0;
-}
-
-
-static int decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- AVFrame * const p = data;
- GetByteContext gbc;
- int colors;
- int w, h, ret;
- int ver;
-
- bytestream2_init(&gbc, avpkt->data, avpkt->size);
- if ( bytestream2_get_bytes_left(&gbc) >= 552
- && check_header(gbc.buffer + 512, bytestream2_get_bytes_left(&gbc) - 512)
- )
- bytestream2_skip(&gbc, 512);
-
- ver = check_header(gbc.buffer, bytestream2_get_bytes_left(&gbc));
-
- /* smallest PICT header */
- if (bytestream2_get_bytes_left(&gbc) < 40) {
- av_log(avctx, AV_LOG_ERROR, "Frame is too small %d\n",
- bytestream2_get_bytes_left(&gbc));
- return AVERROR_INVALIDDATA;
- }
-
- bytestream2_skip(&gbc, 6);
- h = bytestream2_get_be16(&gbc);
- w = bytestream2_get_be16(&gbc);
-
- ret = ff_set_dimensions(avctx, w, h);
- if (ret < 0)
- return ret;
-
- /* version 1 is identified by 0x1101
- * it uses byte-aligned opcodes rather than word-aligned */
- if (ver == 1) {
- avpriv_request_sample(avctx, "QuickDraw version 1");
- return AVERROR_PATCHWELCOME;
- } else if (ver != 2) {
- avpriv_request_sample(avctx, "QuickDraw version unknown (%X)", bytestream2_get_be32(&gbc));
- return AVERROR_PATCHWELCOME;
- }
-
- bytestream2_skip(&gbc, 4+26);
-
- while (bytestream2_get_bytes_left(&gbc) >= 4) {
- int bppcnt, bpp;
- int rowbytes, pack_type;
- int opcode = bytestream2_get_be16(&gbc);
-
- switch(opcode) {
- case PACKBITSRECT:
- case PACKBITSRGN:
- av_log(avctx, AV_LOG_DEBUG, "Parsing Packbit opcode\n");
-
- bytestream2_skip(&gbc, 30);
- bppcnt = bytestream2_get_be16(&gbc); /* cmpCount */
- bpp = bytestream2_get_be16(&gbc); /* cmpSize */
-
- av_log(avctx, AV_LOG_DEBUG, "bppcount %d bpp %d\n", bppcnt, bpp);
- if (bppcnt == 1 && bpp == 8) {
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
- } else {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid pixel format (bppcnt %d bpp %d) in Packbit\n",
- bppcnt, bpp);
- return AVERROR_INVALIDDATA;
- }
-
- /* jump to palette */
- bytestream2_skip(&gbc, 18);
- colors = bytestream2_get_be16(&gbc);
-
- if (colors < 0 || colors > 256) {
- av_log(avctx, AV_LOG_ERROR,
- "Error color count - %i(0x%X)\n", colors, colors);
- return AVERROR_INVALIDDATA;
- }
- if (bytestream2_get_bytes_left(&gbc) < (colors + 1) * 8) {
- av_log(avctx, AV_LOG_ERROR, "Palette is too small %d\n",
- bytestream2_get_bytes_left(&gbc));
- return AVERROR_INVALIDDATA;
- }
- if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
- return ret;
-
- parse_palette(avctx, &gbc, (uint32_t *)p->data[1], colors);
- p->palette_has_changed = 1;
-
- /* jump to image data */
- bytestream2_skip(&gbc, 18);
-
- if (opcode == PACKBITSRGN) {
- bytestream2_skip(&gbc, 2 + 8); /* size + rect */
- avpriv_report_missing_feature(avctx, "Packbit mask region");
- }
-
- ret = decode_rle(avctx, p, &gbc, bppcnt);
- if (ret < 0)
- return ret;
- *got_frame = 1;
- break;
- case DIRECTBITSRECT:
- case DIRECTBITSRGN:
- av_log(avctx, AV_LOG_DEBUG, "Parsing Directbit opcode\n");
-
- bytestream2_skip(&gbc, 4);
- rowbytes = bytestream2_get_be16(&gbc) & 0x3FFF;
- if (rowbytes <= 250) {
- avpriv_report_missing_feature(avctx, "Short rowbytes");
- return AVERROR_PATCHWELCOME;
- }
-
- bytestream2_skip(&gbc, 10);
- pack_type = bytestream2_get_be16(&gbc);
-
- bytestream2_skip(&gbc, 16);
- bppcnt = bytestream2_get_be16(&gbc); /* cmpCount */
- bpp = bytestream2_get_be16(&gbc); /* cmpSize */
-
- av_log(avctx, AV_LOG_DEBUG, "bppcount %d bpp %d\n", bppcnt, bpp);
- if (bppcnt == 3 && bpp == 8) {
- avctx->pix_fmt = AV_PIX_FMT_RGB24;
- } else if (bppcnt == 4 && bpp == 8) {
- avctx->pix_fmt = AV_PIX_FMT_ARGB;
- } else {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid pixel format (bppcnt %d bpp %d) in Directbit\n",
- bppcnt, bpp);
- return AVERROR_INVALIDDATA;
- }
-
- /* set packing when default is selected */
- if (pack_type == 0)
- pack_type = bppcnt;
-
- if (pack_type != 3 && pack_type != 4) {
- avpriv_request_sample(avctx, "Pack type %d", pack_type);
- return AVERROR_PATCHWELCOME;
- }
- if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
- return ret;
- }
-
- /* jump to data */
- bytestream2_skip(&gbc, 30);
-
- if (opcode == DIRECTBITSRGN) {
- bytestream2_skip(&gbc, 2 + 8); /* size + rect */
- avpriv_report_missing_feature(avctx, "DirectBit mask region");
- }
-
- ret = decode_rle(avctx, p, &gbc, bppcnt);
- if (ret < 0)
- return ret;
- *got_frame = 1;
- break;
- default:
- av_log(avctx, AV_LOG_TRACE, "Unknown 0x%04X opcode\n", opcode);
- break;
- }
- /* exit the loop when a known pixel block has been found */
- if (*got_frame) {
- int eop, trail;
-
- /* re-align to a word */
- bytestream2_skip(&gbc, bytestream2_get_bytes_left(&gbc) % 2);
-
- eop = bytestream2_get_be16(&gbc);
- trail = bytestream2_get_bytes_left(&gbc);
- if (eop != EOP)
- av_log(avctx, AV_LOG_WARNING,
- "Missing end of picture opcode (found 0x%04X)\n", eop);
- if (trail)
- av_log(avctx, AV_LOG_WARNING, "Got %d trailing bytes\n", trail);
- break;
- }
- }
-
- if (*got_frame) {
- p->pict_type = AV_PICTURE_TYPE_I;
- p->key_frame = 1;
-
- return avpkt->size;
- } else {
- av_log(avctx, AV_LOG_ERROR, "Frame contained no usable data\n");
-
- return AVERROR_INVALIDDATA;
- }
-}
-
-AVCodec ff_qdraw_decoder = {
- .name = "qdraw",
- .long_name = NULL_IF_CONFIG_SMALL("Apple QuickDraw"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_QDRAW,
- .decode = decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/ra144.c b/ffmpeg-2-8-11/libavcodec/ra144.c
deleted file mode 100644
index 696a49e..0000000
--- a/ffmpeg-2-8-11/libavcodec/ra144.c
+++ /dev/null
@@ -1,1724 +0,0 @@
-/*
- * Real Audio 1.0 (14.4K)
- * Copyright (c) 2003 The FFmpeg Project
- *
- * 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 <stdint.h>
-#include "avcodec.h"
-#include "celp_filters.h"
-#include "mathops.h"
-#include "ra144.h"
-
-const int16_t ff_gain_val_tab[256][3] = {
- { 541, 956, 768}, { 877, 581, 568}, { 675,1574, 635}, {1248,1464, 668},
- {1246, 839, 1394}, {2560,1386, 991}, { 925, 687, 608}, {2208, 797, 1144},
- { 535, 832, 799}, { 762, 605, 1154}, { 832,1122, 1003}, {1180, 687, 1176},
- {1292, 901, 732}, {1656, 689, 896}, {1750,1248, 848}, {2284, 942, 1022},
- { 824,1472, 643}, { 517, 765, 512}, { 562,1816, 1522}, { 694,1826, 2700},
- { 704, 524, 672}, {1442, 757, 2232}, { 884, 551, 1266}, {2232,1007, 1692},
- { 932, 746, 777}, {1132, 822, 926}, {1226, 771, 611}, {2948,1342, 1008},
- {1302, 594, 1158}, {1602, 636, 1128}, {3408, 910, 1438}, {1996, 614, 575},
- { 665, 935, 628}, { 631,1192, 829}, { 644, 926, 1052}, { 879, 988, 1226},
- { 941,2768, 2772}, { 565,1344, 2304}, { 547, 628, 740}, { 639, 532, 1074},
- { 955,1208, 598}, {1124,1160, 900}, {1206, 899, 1242}, { 746, 533, 624},
- {1458,1028, 735}, {1706,1102, 692}, {1898,1018, 1004}, {2176, 988, 735},
- {1578, 782, 1642}, { 897, 516, 754}, {2068, 702, 1656}, {2344, 818, 1526},
- { 907, 652, 592}, {1056, 652, 642}, {2124,1416, 780}, {2664,1250, 727},
- {1894, 727, 1108}, {2196, 657, 981}, {4840, 920, 1704}, {4992,1238, 983},
- {2420, 909, 1094}, {2760, 935, 1032}, {2800, 612, 853}, {3068, 832, 574},
- { 523,1796, 923}, { 722,1916, 1382}, {1226,1542, 928}, { 758, 757, 584},
- { 512,1134, 577}, { 615,1276, 698}, { 574,2568, 2356}, { 993,2728, 3512},
- { 539, 890, 913}, { 694, 928, 1088}, { 805, 600, 1360}, {2160, 951, 3128},
- { 816, 950, 590}, { 955, 847, 811}, {1094, 883, 556}, {1304, 888, 604},
- { 863,1170, 855}, {1023, 997, 1032}, { 932,1228, 1280}, { 627, 564, 573},
- { 876, 900, 1448}, {1030, 857, 1792}, {1294, 953, 1758}, {1612, 854, 1714},
- {1090,1166, 631}, {1314,1202, 751}, {1480, 905, 795}, {1682,1016, 568},
- {1494,1178, 983}, { 878, 613, 526}, {1728,1446, 779}, {2136,1348, 774},
- { 950, 649, 939}, {1180, 703, 899}, {1236, 527, 1158}, {1450, 647, 972},
- {1282, 647, 707}, {1460, 663, 644}, {1614, 572, 578}, {3516,1222, 821},
- {2668, 729, 1682}, {3128, 585, 1502}, {3208, 733, 976}, {6800, 871, 1416},
- {3480, 743, 1408}, {3764, 899, 1170}, {3772, 632, 875}, {4092, 732, 638},
- {3112, 753, 2620}, {3372, 945, 1890}, {3768, 969, 2288}, {2016, 559, 854},
- {1736, 729, 787}, {1940, 686, 547}, {2140, 635, 674}, {4480,1272, 828},
- {3976, 592, 1666}, {4384, 621, 1388}, {4400, 801, 955}, {4656, 522, 646},
- {4848, 625, 1636}, {4984, 591, 874}, {5352, 535, 1001}, {11216,938, 1184},
- { 925,3280, 1476}, { 735,1580, 1088}, {1150,1576, 674}, { 655, 783, 528},
- { 527,2052, 1354}, { 782,1704, 1880}, { 578, 910, 1026}, { 692, 882, 1468},
- { 586, 683, 715}, { 739, 609, 717}, { 778, 773, 697}, { 922, 785, 813},
- { 766, 651, 984}, { 978, 596, 1030}, {1070, 757, 1080}, {1324, 687, 1178},
- {1108,2144, 979}, { 723, 982, 690}, { 936, 956, 527}, {1180,1002, 547},
- { 517,1306, 825}, { 832,1184, 974}, {1024, 957, 903}, {1262,1090, 906},
- {1028, 720, 649}, {1192, 679, 694}, {2468,1480, 979}, {2844,1370, 877},
- {1310, 835, 848}, {1508, 839, 698}, {1742,1030, 769}, {1910, 852, 573},
- {1280, 859, 1174}, {1584, 863, 1108}, {1686, 708, 1364}, {1942, 768, 1104},
- { 891, 536, 690}, {1016, 560, 663}, {2172, 870, 1348}, {2404, 999, 1170},
- {1890, 966, 889}, {2116, 912, 777}, {2296,1020, 714}, {4872,1844, 932},
- {2392, 778, 929}, {2604, 772, 744}, {2764, 957, 722}, {5832,1532, 984},
- {2188, 519, 1264}, {2332, 532, 922}, {5064, 995, 2412}, {2708, 571, 874},
- {2408, 545, 666}, {5016,1084, 875}, {5376, 983, 1196}, {5536, 979, 730},
- {5344, 634, 1744}, {5688, 706, 1348}, {5912, 977, 1190}, {6072, 905, 763},
- {6048, 582, 1526}, {11968,1013,1816}, {12864,937, 1900}, {12560,1086, 998},
- {1998, 684, 1884}, {2504, 633, 1992}, {1252, 567, 835}, {1478, 571, 973},
- {2620, 769, 1414}, {2808, 952, 1142}, {2908, 712, 1028}, {2976, 686, 741},
- {1462, 552, 714}, {3296, 991, 1452}, {1590, 615, 544}, {3480,1150, 824},
- {3212, 832, 923}, {3276, 839, 531}, {3548, 786, 852}, {3732, 764, 570},
- {5728, 906, 2616}, {6272, 804, 2252}, {3096, 535, 876}, {3228, 598, 649},
- {6536, 759, 1436}, {6648, 993, 846}, {6864, 567, 1210},{14016,1012, 1302},
- {3408, 548, 1098}, {7160,1008, 1742}, {7136,1000, 1182}, {7480,1032, 836},
- {7448, 612, 1552}, {7744, 614, 816}, {8384, 777, 1438}, {8784, 694, 786},
- { 882,1508, 1068}, { 597, 837, 766}, {1270, 954, 1408}, { 803, 550, 798},
- {1398,1308, 798}, {1848,1534, 738}, { 970, 675, 608}, {1264, 706, 684},
- {1716, 767, 1126}, {2108, 765, 1404}, {2236, 924, 1003}, {2472,1048, 611},
- { 999, 942, 963}, {1094, 857, 935}, {2936, 926, 1138}, {1934, 746, 551},
- {3336, 633, 1762}, {3764, 701, 1454}, {1890, 564, 636}, {4096,1126, 793},
- {3936, 556, 1140}, {3936, 540, 740}, {4216, 764, 874}, {8480,1328, 1014},
- {2184, 515, 1042}, {4432, 934, 1344}, {4784, 945, 1112}, {5016,1062, 733},
- {9216,1020, 2028}, {9968, 924, 1188}, {5424, 909, 1206}, {6512, 744, 1086}
-};
-
-const uint8_t ff_gain_exp_tab[256] = {
- 15, 15, 15, 15, 15, 16, 14, 15, 14, 14, 14, 14, 14, 14, 14, 14,
- 14, 13, 14, 14, 13, 14, 13, 14, 13, 13, 13, 14, 13, 13, 14, 13,
- 13, 13, 13, 13, 14, 13, 12, 12, 13, 13, 13, 12, 13, 13, 13, 13,
- 13, 12, 13, 13, 12, 12, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13,
- 13, 13, 13, 12, 12, 12, 13, 13, 12, 12, 12, 13, 12, 12, 12, 12,
- 12, 12, 12, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12,
- 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 13, 13, 13, 13,
- 13, 13, 13, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 14,
- 13, 12, 12, 11, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
- 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 11, 11, 11, 11,
- 12, 12, 12, 12, 11, 11, 12, 12, 12, 12, 12, 13, 12, 12, 12, 13,
- 12, 12, 13, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14,
- 12, 12, 11, 11, 12, 12, 12, 12, 11, 12, 11, 12, 12, 12, 12, 12,
- 13, 13, 12, 12, 13, 13, 13, 14, 12, 13, 13, 13, 13, 13, 13, 13,
- 11, 10, 11, 10, 11, 11, 10, 10, 11, 11, 11, 11, 10, 9, 11, 10,
- 12, 12, 11, 12, 12, 12, 12, 13, 11, 12, 12, 12, 13, 13, 12, 12
-};
-
-const int8_t ff_cb1_vects[128][40]={
- {
- 38, -4, 15, -4, 14, -13, 12, -11, -2, -6,
- -6, -11, -45, -16, -11, -13, -7, 6, -12, 4,
- -20, 3, -16, 12, -1, 12, 46, 24, 0, 33,
- -3, 9, -12, -12, -8, -7, 17, -6, 0, -2,
- }, {
- 60, -16, 3, -22, 10, -32, 0, -28, -17, -18,
- -3, -25, -37, -23, -10, 3, 2, 3, 0, 3,
- -14, 0, -14, -1, 0, 2, 32, 9, -1, 25,
- 7, 13, -5, 13, 8, 1, 2, 8, -10, 6,
- }, {
- 27, -12, 28, -2, 6, -7, 15, 9, -11, 1,
- -13, -11, -40, 4, -29, -14, -19, -5, -23, -8,
- -30, -13, -17, 0, -14, 12, 34, 20, -2, 25,
- 2, -16, -4, -12, 15, 16, 29, 7, 24, 10,
- }, {
- 49, -24, 16, -20, 2, -26, 2, -7, -25, -10,
- -11, -25, -32, -3, -27, 2, -8, -8, -11, -9,
- -24, -17, -16, -14, -13, 2, 20, 5, -4, 17,
- 14, -12, 3, 13, 33, 25, 14, 23, 15, 19,
- }, {
- 46, -6, 21, 8, -2, -16, -5, -8, -11, 4,
- 8, 15, -24, 4, -2, -26, -3, -16, -16, -14,
- -9, -2, -1, 4, 19, 7, 36, 17, 9, 13,
- 0, 31, -5, -12, 7, -8, 11, -15, -13, -4,
- }, {
- 68, -18, 9, -9, -6, -35, -18, -25, -26, -7,
- 10, 1, -16, -3, -1, -9, 6, -19, -4, -15,
- -4, -6, 0, -8, 20, -2, 23, 2, 7, 5,
- 12, 35, 1, 13, 24, 0, -3, 0, -22, 4,
- }, {
- 35, -14, 34, 10, -10, -10, -1, 12, -20, 12,
- 0, 15, -18, 24, -20, -27, -14, -28, -27, -27,
- -20, -19, -2, -8, 5, 7, 25, 13, 5, 5,
- 6, 5, 2, -12, 31, 15, 23, -1, 12, 8,
- }, {
- 57, -26, 22, -7, -14, -28, -14, -3, -35, 0,
- 3, 1, -11, 16, -18, -10, -4, -31, -15, -28,
- -14, -23, -1, -21, 7, -2, 11, -1, 3, -1,
- 18, 9, 10, 13, 49, 24, 8, 14, 2, 16,
- }, {
- 25, 15, 22, 11, 18, 4, 15, -22, 8, -2,
- -17, -9, -48, -20, -30, -17, -16, 11, -1, 16,
- 2, 10, -5, 26, -2, -4, 22, 0, 2, 10,
- -6, 13, -14, 10, -23, 0, 10, -2, 1, 0,
- }, {
- 47, 3, 11, -6, 15, -13, 2, -38, -6, -13,
- -15, -22, -40, -28, -28, 0, -5, 8, 10, 15,
- 7, 7, -4, 13, -1, -14, 9, -14, 0, 2,
- 4, 18, -7, 36, -6, 8, -3, 13, -7, 8,
- }, {
- 14, 7, 36, 13, 10, 10, 18, 0, 0, 5,
- -25, -8, -43, 0, -48, -18, -27, 0, -12, 3,
- -7, -6, -7, 13, -15, -5, 11, -3, 0, 2,
- 0, -12, -6, 10, 0, 23, 22, 11, 26, 12,
- }, {
- 36, -5, 24, -4, 7, -7, 6, -17, -14, -5,
- -22, -22, -35, -8, -46, -1, -17, -3, 0, 2,
- -2, -10, -5, 0, -14, -15, -2, -18, -2, -4,
- 11, -7, 1, 36, 18, 32, 7, 27, 17, 20,
- }, {
- 33, 13, 29, 24, 1, 1, -2, -18, 0, 9,
- -3, 17, -27, 0, -21, -30, -12, -11, -5, -2,
- 12, 4, 9, 19, 18, -9, 13, -6, 11, -8,
- -2, 35, -8, 10, -7, -1, 4, -11, -10, -2,
- }, {
- 55, 1, 17, 6, -1, -16, -15, -35, -15, -2,
- 0, 4, -19, -8, -20, -13, -1, -14, 7, -3,
- 18, 0, 10, 5, 19, -19, 0, -21, 8, -16,
- 9, 39, 0, 36, 10, 7, -9, 4, -20, 5,
- }, {
- 22, 5, 42, 26, -6, 8, 1, 2, -9, 17,
- -10, 18, -21, 19, -39, -31, -23, -23, -16, -15,
- 2, -12, 7, 6, 5, -9, 1, -10, 7, -16,
- 4, 9, 0, 10, 17, 22, 16, 2, 14, 9,
- }, {
- 44, -6, 30, 8, -9, -10, -11, -14, -23, 5,
- -8, 4, -14, 12, -37, -14, -12, -26, -4, -16,
- 8, -16, 9, -7, 6, -19, -12, -25, 5, -24,
- 15, 13, 8, 36, 34, 31, 1, 18, 4, 18,
- }, {
- -3, -5, -9, -7, 15, -1, 5, 13, 2, 12,
- 5, 2, -21, -23, -2, -16, 0, 5, -6, 13,
- -23, 3, -32, 10, -15, 8, 44, 28, 9, 37,
- -2, 13, -9, -15, -12, -27, -7, -12, 0, -11,
- }, {
- 18, -17, -21, -25, 11, -19, -6, -3, -11, 0,
- 7, -11, -13, -31, -1, 0, 9, 1, 5, 12,
- -18, 0, -31, -2, -13, -1, 30, 14, 7, 29,
- 9, 18, -1, 10, 4, -18, -22, 3, -10, -2,
- }, {
- -13, -13, 3, -5, 7, 4, 9, 34, -5, 20,
- -2, 3, -16, -3, -20, -17, -11, -7, -17, 0,
- -34, -13, -33, -2, -28, 8, 32, 24, 5, 29,
- 3, -12, 0, -15, 11, -3, 3, 2, 24, 1,
- }, {
- 8, -25, -8, -23, 3, -13, -3, 17, -20, 8,
- 0, -10, -8, -11, -18, 0, -1, -10, -5, 0,
- -28, -17, -32, -15, -26, -1, 19, 9, 3, 21,
- 15, -7, 6, 9, 29, 5, -10, 17, 15, 9,
- }, {
- 4, -6, -3, 5, -1, -4, -11, 16, -6, 23,
- 19, 29, 0, -3, 6, -30, 3, -17, -10, -5,
- -13, -2, -17, 3, 5, 3, 35, 21, 17, 17,
- 2, 35, -2, -15, 3, -28, -13, -21, -13, -13,
- }, {
- 26, -19, -15, -12, -5, -22, -24, 0, -21, 12,
- 21, 15, 8, -11, 7, -12, 14, -20, 2, -6,
- -7, -6, -16, -9, 6, -5, 21, 7, 15, 10,
- 13, 39, 5, 10, 20, -19, -28, -5, -22, -5,
- }, {
- -5, -15, 9, 7, -9, 2, -8, 37, -14, 31,
- 11, 29, 5, 16, -11, -30, -7, -29, -21, -18,
- -23, -19, -18, -9, -7, 3, 23, 17, 14, 9,
- 8, 9, 6, -15, 27, -4, -2, -6, 12, -1,
- }, {
- 16, -27, -2, -10, -13, -16, -20, 20, -29, 20,
- 14, 16, 13, 8, -9, -13, 2, -33, -9, -19,
- -17, -23, -17, -22, -6, -6, 9, 2, 12, 2,
- 20, 13, 13, 10, 45, 4, -16, 8, 2, 7,
- }, {
- -16, 14, -2, 8, 20, 17, 9, 2, 14, 16,
- -6, 5, -24, -28, -21, -20, -8, 9, 4, 25,
- -1, 11, -22, 24, -15, -8, 21, 5, 11, 14,
- -5, 18, -11, 7, -27, -20, -14, -7, 1, -9,
- }, {
- 6, 2, -14, -9, 16, -1, -3, -14, 0, 5,
- -3, -8, -16, -36, -19, -3, 1, 6, 17, 24,
- 4, 7, -21, 11, -14, -18, 7, -9, 9, 7,
- 6, 22, -3, 33, -10, -11, -28, 7, -7, 0,
- }, {
- -26, 6, 11, 10, 12, 23, 12, 23, 5, 24,
- -13, 5, -19, -8, -38, -21, -20, -2, -6, 12,
- -11, -5, -23, 11, -29, -9, 9, 0, 7, 6,
- 1, -7, -2, 7, -3, 3, -2, 6, 27, 3,
- }, {
- -4, -6, 0, -7, 8, 4, 0, 6, -9, 13,
- -11, -7, -11, -15, -37, -4, -9, -5, 5, 11,
- -5, -9, -22, -1, -27, -18, -4, -14, 5, 0,
- 12, -3, 4, 32, 14, 12, -17, 22, 17, 11,
- }, {
- -8, 12, 3, 21, 3, 14, -8, 5, 4, 28,
- 7, 32, -2, -8, -12, -34, -4, -12, 1, 6,
- 9, 4, -7, 17, 4, -13, 11, -1, 19, -4,
- 0, 39, -4, 7, -11, -21, -20, -16, -10, -11,
- }, {
- 13, 0, -8, 3, 0, -4, -21, -11, -9, 16,
- 10, 18, 5, -16, -10, -16, 5, -15, 13, 5,
- 15, 1, -6, 4, 6, -23, -2, -16, 17, -12,
- 10, 44, 3, 33, 6, -12, -34, -1, -20, -3,
- }, {
- -18, 4, 17, 23, -4, 20, -4, 26, -3, 36,
- 0, 32, 2, 12, -29, -34, -16, -24, -10, -6,
- 0, -12, -8, 4, -8, -13, 0, -6, 16, -12,
- 5, 13, 3, 7, 13, 3, -8, -2, 14, 0,
- }, {
- 3, -7, 5, 5, -8, 2, -17, 9, -18, 24,
- 2, 19, 10, 4, -28, -17, -5, -28, 2, -7,
- 4, -15, -7, -8, -6, -23, -13, -21, 14, -20,
- 17, 18, 11, 33, 30, 11, -23, 13, 5, 9,
- }, {
- 60, 10, 7, -1, 9, -8, 6, -13, 2, -15,
- -1, -10, -13, -11, 15, 0, 6, 9, -1, 0,
- -13, 1, -11, -3, -13, 21, 13, 26, -7, 31,
- -10, -7, -16, -33, -31, -10, 22, -8, 1, -2,
- }, {
- 82, -1, -4, -19, 6, -27, -6, -29, -12, -26,
- 1, -24, -5, -18, 17, 17, 17, 6, 10, 0,
- -7, -2, -9, -16, -12, 11, 0, 11, -9, 23,
- 0, -3, -8, -8, -13, -1, 8, 7, -7, 6,
- }, {
- 49, 2, 21, 0, 1, -2, 9, 8, -6, -6,
- -8, -10, -8, 9, -2, 0, -4, -2, -13, -12,
- -23, -15, -12, -16, -26, 21, 2, 21, -11, 23,
- -4, -33, -7, -33, -6, 13, 34, 5, 27, 10,
- }, {
- 71, -10, 9, -17, -1, -20, -3, -8, -21, -18,
- -6, -24, 0, 1, 0, 16, 6, -5, 0, -13,
- -17, -19, -11, -29, -25, 11, -11, 6, -13, 15,
- 7, -29, 0, -8, 11, 22, 20, 21, 17, 18,
- }, {
- 67, 8, 14, 11, -7, -11, -11, -9, -7, -3,
- 13, 16, 8, 9, 24, -12, 10, -13, -5, -17,
- -2, -4, 3, -10, 6, 17, 4, 19, 0, 11,
- -6, 13, -9, -33, -14, -10, 16, -17, -10, -4,
- }, {
- 90, -3, 2, -6, -10, -29, -24, -26, -21, -15,
- 15, 2, 16, 1, 25, 4, 21, -16, 6, -18,
- 3, -8, 5, -24, 8, 7, -9, 4, -1, 3,
- 5, 18, -1, -7, 2, -1, 2, -1, -19, 3,
- }, {
- 57, 0, 27, 13, -14, -5, -7, 11, -15, 4,
- 5, 16, 13, 29, 6, -13, 0, -25, -16, -31,
- -12, -22, 2, -23, -6, 16, -7, 14, -2, 3,
- 0, -12, 0, -33, 9, 13, 28, -3, 14, 7,
- }, {
- 79, -11, 15, -4, -18, -23, -20, -5, -30, -7,
- 7, 2, 21, 21, 8, 3, 10, -28, -4, -31,
- -6, -25, 3, -37, -4, 7, -20, 0, -4, -4,
- 11, -7, 6, -8, 27, 22, 14, 12, 5, 16,
- }, {
- 47, 30, 15, 14, 14, 9, 9, -23, 13, -10,
- -12, -7, -16, -15, -3, -3, -1, 14, 9, 12,
- 9, 8, 0, 10, -14, 4, -9, 2, -5, 8,
- -13, -3, -18, -10, -45, -3, 16, -4, 4, 0,
- }, {
- 69, 17, 3, -3, 10, -8, -3, -40, -1, -21,
- -10, -21, -8, -23, -1, 13, 8, 11, 21, 11,
- 15, 4, 0, -2, -13, -5, -23, -12, -7, 0,
- -1, 0, -10, 14, -28, 5, 1, 11, -5, 7,
- }, {
- 36, 21, 28, 16, 6, 16, 12, -2, 4, -2,
- -20, -7, -11, 4, -20, -4, -12, 2, -1, 0,
- 0, -8, -2, -2, -27, 4, -21, -2, -9, 0,
- -6, -29, -9, -10, -21, 21, 28, 10, 29, 11,
- }, {
- 58, 9, 16, -1, 2, -2, 0, -19, -10, -13,
- -17, -21, -3, -3, -19, 12, -2, 0, 10, -1,
- 5, -12, 0, -15, -26, -5, -34, -16, -11, -7,
- 4, -25, -2, 14, -3, 29, 13, 25, 20, 20,
- }, {
- 55, 28, 21, 27, -2, 7, -8, -20, 4, 1,
- 1, 18, 5, 4, 5, -16, 2, -8, 5, -5,
- 19, 2, 14, 3, 6, 0, -18, -4, 2, -11,
- -8, 18, -11, -10, -29, -3, 10, -13, -8, -3,
- }, {
- 77, 16, 9, 9, -6, -11, -21, -37, -10, -10,
- 4, 5, 13, -3, 7, 0, 13, -11, 17, -6,
- 25, -1, 15, -9, 7, -9, -32, -19, 0, -18,
- 2, 22, -3, 15, -12, 5, -4, 2, -17, 5,
- }, {
- 44, 20, 34, 29, -10, 13, -4, 0, -4, 9,
- -5, 19, 10, 24, -11, -17, -8, -20, -5, -19,
- 9, -14, 12, -9, -6, 0, -30, -9, 0, -19,
- -2, -7, -2, -10, -5, 20, 21, 1, 17, 9,
- }, {
- 66, 8, 23, 11, -14, -5, -17, -16, -19, -2,
- -3, 5, 18, 17, -10, 0, 1, -23, 6, -20,
- 15, -18, 14, -22, -5, -10, -44, -23, -2, -26,
- 9, -3, 4, 14, 12, 29, 7, 16, 7, 18,
- }, {
- 18, 9, -17, -4, 11, 3, 0, 11, 7, 4,
- 10, 3, 10, -18, 24, -3, 14, 7, 4, 10,
- -16, 1, -27, -4, -27, 17, 12, 30, 0, 35,
- -9, -3, -12, -36, -35, -30, -2, -13, 2, -11,
- }, {
- 40, -2, -29, -22, 7, -14, -12, -5, -7, -7,
- 12, -9, 18, -26, 26, 14, 24, 4, 16, 9,
- -10, -2, -26, -18, -26, 7, -1, 15, -1, 27,
- 2, 0, -4, -11, -17, -21, -16, 1, -7, -3,
- }, {
- 8, 1, -3, -2, 3, 10, 3, 32, -1, 12,
- 2, 4, 15, 1, 7, -3, 2, -4, -6, -3,
- -26, -15, -29, -17, -40, 17, 0, 26, -2, 27,
- -2, -29, -4, -36, -10, -6, 9, 0, 27, 0,
- }, {
- 30, -11, -15, -20, 0, -8, -9, 15, -15, 0,
- 5, -9, 23, -6, 8, 13, 13, -7, 5, -3,
- -20, -19, -27, -31, -39, 7, -13, 11, -4, 19,
- 8, -25, 3, -11, 7, 2, -4, 16, 18, 9,
- }, {
- 26, 7, -11, 8, -5, 1, -17, 14, -1, 15,
- 24, 30, 32, 1, 33, -16, 18, -14, 0, -8,
- -6, -4, -12, -12, -6, 13, 2, 23, 8, 15,
- -4, 17, -5, -36, -18, -30, -8, -22, -10, -14,
- }, {
- 48, -4, -23, -9, -9, -17, -30, -2, -16, 3,
- 26, 16, 40, -6, 35, 1, 28, -17, 12, -9,
- 0, -8, -11, -25, -5, 3, -10, 8, 6, 7,
- 6, 22, 1, -11, -1, -21, -22, -7, -19, -5,
- }, {
- 15, 0, 2, 10, -13, 7, -14, 35, -10, 23,
- 16, 31, 37, 21, 16, -17, 6, -26, -10, -21,
- -16, -21, -13, -25, -19, 13, -8, 19, 5, 7,
- 1, -8, 2, -36, 5, -6, 3, -8, 15, -1,
- }, {
- 37, -12, -9, -7, -17, -11, -26, 18, -25, 12,
- 19, 17, 45, 14, 17, 0, 17, -30, 1, -22,
- -10, -25, -12, -38, -18, 3, -22, 4, 3, 0,
- 13, -3, 10, -11, 23, 2, -10, 7, 5, 7,
- }, {
- 5, 29, -9, 11, 15, 22, 3, 0, 18, 8,
- -1, 6, 7, -23, 6, -6, 5, 12, 15, 21,
- 5, 8, -17, 9, -28, 0, -11, 6, 2, 12,
- -11, 0, -14, -13, -49, -22, -8, -9, 4, -9,
- }, {
- 27, 16, -21, -6, 12, 3, -9, -16, 3, -2,
- 1, -7, 15, -31, 7, 10, 16, 9, 27, 21,
- 11, 5, -16, -3, -26, -9, -24, -7, 0, 4,
- 0, 4, -6, 11, -32, -14, -23, 6, -5, -1,
- }, {
- -4, 20, 3, 13, 8, 28, 6, 21, 10, 16,
- -8, 7, 12, -3, -11, -7, -5, 0, 4, 8,
- -4, -8, -18, -3, -41, 0, -22, 2, 0, 4,
- -5, -25, -6, -14, -25, 1, 2, 4, 29, 2,
- }, {
- 17, 8, -8, -4, 4, 10, -6, 5, -4, 5,
- -6, -6, 20, -10, -9, 9, 4, -2, 16, 7,
- 1, -12, -17, -16, -39, -9, -36, -12, -2, -3,
- 6, -21, 1, 11, -7, 10, -11, 20, 20, 11,
- }, {
- 13, 27, -3, 24, -1, 19, -14, 3, 9, 20,
- 12, 33, 29, -3, 15, -20, 9, -9, 11, 3,
- 16, 2, -2, 2, -7, -3, -20, 0, 10, -7,
- -7, 22, -7, -13, -33, -23, -14, -18, -7, -12,
- }, {
- 35, 15, -15, 6, -4, 1, -27, -12, -5, 8,
- 15, 19, 37, -11, 16, -2, 20, -12, 23, 2,
- 22, -1, -1, -11, -5, -13, -34, -14, 8, -14,
- 4, 26, 0, 11, -16, -14, -29, -2, -17, -3,
- }, {
- 3, 19, 9, 26, -8, 26, -10, 24, 0, 28,
- 5, 33, 34, 17, -2, -20, -1, -22, 0, -10,
- 6, -14, -3, -10, -20, -4, -32, -4, 7, -15,
- 0, -3, 0, -13, -9, 0, -3, -4, 17, 0,
- }, {
- 25, 7, -2, 8, -12, 7, -23, 8, -13, 16,
- 7, 20, 42, 9, 0, -3, 9, -25, 12, -10,
- 12, -18, -2, -24, -19, -13, -46, -19, 5, -22,
- 10, 0, 8, 11, 8, 9, -17, 11, 7, 8,
- }, {
- -25, -7, 2, -8, 12, -7, 23, -8, 13, -16,
- -7, -20, -42, -9, 0, 3, -9, 25, -12, 10,
- -12, 18, 2, 24, 19, 13, 46, 19, -5, 22,
- -10, 0, -8, -11, -8, -9, 17, -11, -7, -8,
- }, {
- -3, -19, -9, -26, 8, -26, 10, -24, 0, -28,
- -5, -33, -34, -17, 2, 20, 1, 22, 0, 10,
- -6, 14, 3, 10, 20, 4, 32, 4, -7, 15,
- 0, 3, 0, 13, 9, 0, 3, 4, -17, 0,
- }, {
- -35, -15, 15, -6, 4, -1, 27, 12, 5, -8,
- -15, -19, -37, 11, -16, 2, -20, 12, -23, -2,
- -22, 1, 1, 11, 5, 13, 34, 14, -8, 14,
- -4, -26, 0, -11, 16, 14, 29, 2, 17, 3,
- }, {
- -13, -27, 3, -24, 1, -19, 14, -3, -9, -20,
- -12, -33, -29, 3, -15, 20, -9, 9, -11, -3,
- -16, -2, 2, -2, 7, 3, 20, 0, -10, 7,
- 7, -22, 7, 13, 33, 23, 14, 18, 7, 12,
- }, {
- -17, -8, 8, 4, -4, -10, 6, -5, 4, -5,
- 6, 6, -20, 10, 9, -9, -4, 2, -16, -7,
- -1, 12, 17, 16, 39, 9, 36, 12, 2, 3,
- -6, 21, -1, -11, 7, -10, 11, -20, -20, -11,
- }, {
- 4, -20, -3, -13, -8, -28, -6, -21, -10, -16,
- 8, -7, -12, 3, 11, 7, 5, 0, -4, -8,
- 4, 8, 18, 3, 41, 0, 22, -2, 0, -4,
- 5, 25, 6, 14, 25, -1, -2, -4, -29, -2,
- }, {
- -27, -16, 21, 6, -12, -3, 9, 16, -3, 2,
- -1, 7, -15, 31, -7, -10, -16, -9, -27, -21,
- -11, -5, 16, 3, 26, 9, 24, 7, 0, -4,
- 0, -4, 6, -11, 32, 14, 23, -6, 5, 1,
- }, {
- -5, -29, 9, -11, -15, -22, -3, 0, -18, -8,
- 1, -6, -7, 23, -6, 6, -5, -12, -15, -21,
- -5, -8, 17, -9, 28, 0, 11, -6, -2, -12,
- 11, 0, 14, 13, 49, 22, 8, 9, -4, 9,
- }, {
- -37, 12, 9, 7, 17, 11, 26, -18, 25, -12,
- -19, -17, -45, -14, -17, 0, -17, 30, -1, 22,
- 10, 25, 12, 38, 18, -3, 22, -4, -3, 0,
- -13, 3, -10, 11, -23, -2, 10, -7, -5, -7,
- }, {
- -15, 0, -2, -10, 13, -7, 14, -35, 10, -23,
- -16, -31, -37, -21, -16, 17, -6, 26, 10, 21,
- 16, 21, 13, 25, 19, -13, 8, -19, -5, -7,
- -1, 8, -2, 36, -5, 6, -3, 8, -15, 1,
- }, {
- -48, 4, 23, 9, 9, 17, 30, 2, 16, -3,
- -26, -16, -40, 6, -35, -1, -28, 17, -12, 9,
- 0, 8, 11, 25, 5, -3, 10, -8, -6, -7,
- -6, -22, -1, 11, 1, 21, 22, 7, 19, 5,
- }, {
- -26, -7, 11, -8, 5, -1, 17, -14, 1, -15,
- -24, -30, -32, -1, -33, 16, -18, 14, 0, 8,
- 6, 4, 12, 12, 6, -13, -2, -23, -8, -15,
- 4, -17, 5, 36, 18, 30, 8, 22, 10, 14,
- }, {
- -30, 11, 15, 20, 0, 8, 9, -15, 15, 0,
- -5, 9, -23, 6, -8, -13, -13, 7, -5, 3,
- 20, 19, 27, 31, 39, -7, 13, -11, 4, -19,
- -8, 25, -3, 11, -7, -2, 4, -16, -18, -9,
- }, {
- -8, -1, 3, 2, -3, -10, -3, -32, 1, -12,
- -2, -4, -15, -1, -7, 3, -2, 4, 6, 3,
- 26, 15, 29, 17, 40, -17, 0, -26, 2, -27,
- 2, 29, 4, 36, 10, 6, -9, 0, -27, 0,
- }, {
- -40, 2, 29, 22, -7, 14, 12, 5, 7, 7,
- -12, 9, -18, 26, -26, -14, -24, -4, -16, -9,
- 10, 2, 26, 18, 26, -7, 1, -15, 1, -27,
- -2, 0, 4, 11, 17, 21, 16, -1, 7, 3,
- }, {
- -18, -9, 17, 4, -11, -3, 0, -11, -7, -4,
- -10, -3, -10, 18, -24, 3, -14, -7, -4, -10,
- 16, -1, 27, 4, 27, -17, -12, -30, 0, -35,
- 9, 3, 12, 36, 35, 30, 2, 13, -2, 11,
- }, {
- -66, -8, -23, -11, 14, 5, 17, 16, 19, 2,
- 3, -5, -18, -17, 10, 0, -1, 23, -6, 20,
- -15, 18, -14, 22, 5, 10, 44, 23, 2, 26,
- -9, 3, -4, -14, -12, -29, -7, -16, -7, -18,
- }, {
- -44, -20, -34, -29, 10, -13, 4, 0, 4, -9,
- 5, -19, -10, -24, 11, 17, 8, 20, 5, 19,
- -9, 14, -12, 9, 6, 0, 30, 9, 0, 19,
- 2, 7, 2, 10, 5, -20, -21, -1, -17, -9,
- }, {
- -77, -16, -9, -9, 6, 11, 21, 37, 10, 10,
- -4, -5, -13, 3, -7, 0, -13, 11, -17, 6,
- -25, 1, -15, 9, -7, 9, 32, 19, 0, 18,
- -2, -22, 3, -15, 12, -5, 4, -2, 17, -5,
- }, {
- -55, -28, -21, -27, 2, -7, 8, 20, -4, -1,
- -1, -18, -5, -4, -5, 16, -2, 8, -5, 5,
- -19, -2, -14, -3, -6, 0, 18, 4, -2, 11,
- 8, -18, 11, 10, 29, 3, -10, 13, 8, 3,
- }, {
- -58, -9, -16, 1, -2, 2, 0, 19, 10, 13,
- 17, 21, 3, 3, 19, -12, 2, 0, -10, 1,
- -5, 12, 0, 15, 26, 5, 34, 16, 11, 7,
- -4, 25, 2, -14, 3, -29, -13, -25, -20, -20,
- }, {
- -36, -21, -28, -16, -6, -16, -12, 2, -4, 2,
- 20, 7, 11, -4, 20, 4, 12, -2, 1, 0,
- 0, 8, 2, 2, 27, -4, 21, 2, 9, 0,
- 6, 29, 9, 10, 21, -21, -28, -10, -29, -11,
- }, {
- -69, -17, -3, 3, -10, 8, 3, 40, 1, 21,
- 10, 21, 8, 23, 1, -13, -8, -11, -21, -11,
- -15, -4, 0, 2, 13, 5, 23, 12, 7, 0,
- 1, 0, 10, -14, 28, -5, -1, -11, 5, -7,
- }, {
- -47, -30, -15, -14, -14, -9, -9, 23, -13, 10,
- 12, 7, 16, 15, 3, 3, 1, -14, -9, -12,
- -9, -8, 0, -10, 14, -4, 9, -2, 5, -8,
- 13, 3, 18, 10, 45, 3, -16, 4, -4, 0,
- }, {
- -79, 11, -15, 4, 18, 23, 20, 5, 30, 7,
- -7, -2, -21, -21, -8, -3, -10, 28, 4, 31,
- 6, 25, -3, 37, 4, -7, 20, 0, 4, 4,
- -11, 7, -6, 8, -27, -22, -14, -12, -5, -16,
- }, {
- -57, 0, -27, -13, 14, 5, 7, -11, 15, -4,
- -5, -16, -13, -29, -6, 13, 0, 25, 16, 31,
- 12, 22, -2, 23, 6, -16, 7, -14, 2, -3,
- 0, 12, 0, 33, -9, -13, -28, 3, -14, -7,
- }, {
- -90, 3, -2, 6, 10, 29, 24, 26, 21, 15,
- -15, -2, -16, -1, -25, -4, -21, 16, -6, 18,
- -3, 8, -5, 24, -8, -7, 9, -4, 1, -3,
- -5, -18, 1, 7, -2, 1, -2, 1, 19, -3,
- }, {
- -67, -8, -14, -11, 7, 11, 11, 9, 7, 3,
- -13, -16, -8, -9, -24, 12, -10, 13, 5, 17,
- 2, 4, -3, 10, -6, -17, -4, -19, 0, -11,
- 6, -13, 9, 33, 14, 10, -16, 17, 10, 4,
- }, {
- -71, 10, -9, 17, 1, 20, 3, 8, 21, 18,
- 6, 24, 0, -1, 0, -16, -6, 5, 0, 13,
- 17, 19, 11, 29, 25, -11, 11, -6, 13, -15,
- -7, 29, 0, 8, -11, -22, -20, -21, -17, -18,
- }, {
- -49, -2, -21, 0, -1, 2, -9, -8, 6, 6,
- 8, 10, 8, -9, 2, 0, 4, 2, 13, 12,
- 23, 15, 12, 16, 26, -21, -2, -21, 11, -23,
- 4, 33, 7, 33, 6, -13, -34, -5, -27, -10,
- }, {
- -82, 1, 4, 19, -6, 27, 6, 29, 12, 26,
- -1, 24, 5, 18, -17, -17, -17, -6, -10, 0,
- 7, 2, 9, 16, 12, -11, 0, -11, 9, -23,
- 0, 3, 8, 8, 13, 1, -8, -7, 7, -6,
- }, {
- -60, -10, -7, 1, -9, 8, -6, 13, -2, 15,
- 1, 10, 13, 11, -15, 0, -6, -9, 1, 0,
- 13, -1, 11, 3, 13, -21, -13, -26, 7, -31,
- 10, 7, 16, 33, 31, 10, -22, 8, -1, 2,
- }, {
- -3, 7, -5, -5, 8, -2, 17, -9, 18, -24,
- -2, -19, -10, -4, 28, 17, 5, 28, -2, 7,
- -4, 15, 7, 8, 6, 23, 13, 21, -14, 20,
- -17, -18, -11, -33, -30, -11, 23, -13, -5, -9,
- }, {
- 18, -4, -17, -23, 4, -20, 4, -26, 3, -36,
- 0, -32, -2, -12, 29, 34, 16, 24, 10, 6,
- 0, 12, 8, -4, 8, 13, 0, 6, -16, 12,
- -5, -13, -3, -7, -13, -3, 8, 2, -14, 0,
- }, {
- -13, 0, 8, -3, 0, 4, 21, 11, 9, -16,
- -10, -18, -5, 16, 10, 16, -5, 15, -13, -5,
- -15, -1, 6, -4, -6, 23, 2, 16, -17, 12,
- -10, -44, -3, -33, -6, 12, 34, 1, 20, 3,
- }, {
- 8, -12, -3, -21, -3, -14, 8, -5, -4, -28,
- -7, -32, 2, 8, 12, 34, 4, 12, -1, -6,
- -9, -4, 7, -17, -4, 13, -11, 1, -19, 4,
- 0, -39, 4, -7, 11, 21, 20, 16, 10, 11,
- }, {
- 4, 6, 0, 7, -8, -4, 0, -6, 9, -13,
- 11, 7, 11, 15, 37, 4, 9, 5, -5, -11,
- 5, 9, 22, 1, 27, 18, 4, 14, -5, 0,
- -12, 3, -4, -32, -14, -12, 17, -22, -17, -11,
- }, {
- 26, -6, -11, -10, -12, -23, -12, -23, -5, -24,
- 13, -5, 19, 8, 38, 21, 20, 2, 6, -12,
- 11, 5, 23, -11, 29, 9, -9, 0, -7, -6,
- -1, 7, 2, -7, 3, -3, 2, -6, -27, -3,
- }, {
- -6, -2, 14, 9, -16, 1, 3, 14, 0, -5,
- 3, 8, 16, 36, 19, 3, -1, -6, -17, -24,
- -4, -7, 21, -11, 14, 18, -7, 9, -9, -7,
- -6, -22, 3, -33, 10, 11, 28, -7, 7, 0,
- }, {
- 16, -14, 2, -8, -20, -17, -9, -2, -14, -16,
- 6, -5, 24, 28, 21, 20, 8, -9, -4, -25,
- 1, -11, 22, -24, 15, 8, -21, -5, -11, -14,
- 5, -18, 11, -7, 27, 20, 14, 7, -1, 9,
- }, {
- -16, 27, 2, 10, 13, 16, 20, -20, 29, -20,
- -14, -16, -13, -8, 9, 13, -2, 33, 9, 19,
- 17, 23, 17, 22, 6, 6, -9, -2, -12, -2,
- -20, -13, -13, -10, -45, -4, 16, -8, -2, -7,
- }, {
- 5, 15, -9, -7, 9, -2, 8, -37, 14, -31,
- -11, -29, -5, -16, 11, 30, 7, 29, 21, 18,
- 23, 19, 18, 9, 7, -3, -23, -17, -14, -9,
- -8, -9, -6, 15, -27, 4, 2, 6, -12, 1,
- }, {
- -26, 19, 15, 12, 5, 22, 24, 0, 21, -12,
- -21, -15, -8, 11, -7, 12, -14, 20, -2, 6,
- 7, 6, 16, 9, -6, 5, -21, -7, -15, -10,
- -13, -39, -5, -10, -20, 19, 28, 5, 22, 5,
- }, {
- -4, 6, 3, -5, 1, 4, 11, -16, 6, -23,
- -19, -29, 0, 3, -6, 30, -3, 17, 10, 5,
- 13, 2, 17, -3, -5, -3, -35, -21, -17, -17,
- -2, -35, 2, 15, -3, 28, 13, 21, 13, 13,
- }, {
- -8, 25, 8, 23, -3, 13, 3, -17, 20, -8,
- 0, 10, 8, 11, 18, 0, 1, 10, 5, 0,
- 28, 17, 32, 15, 26, 1, -19, -9, -3, -21,
- -15, 7, -6, -9, -29, -5, 10, -17, -15, -9,
- }, {
- 13, 13, -3, 5, -7, -4, -9, -34, 5, -20,
- 2, -3, 16, 3, 20, 17, 11, 7, 17, 0,
- 34, 13, 33, 2, 28, -8, -32, -24, -5, -29,
- -3, 12, 0, 15, -11, 3, -3, -2, -24, -1,
- }, {
- -18, 17, 21, 25, -11, 19, 6, 3, 11, 0,
- -7, 11, 13, 31, 1, 0, -9, -1, -5, -12,
- 18, 0, 31, 2, 13, 1, -30, -14, -7, -29,
- -9, -18, 1, -10, -4, 18, 22, -3, 10, 2,
- }, {
- 3, 5, 9, 7, -15, 1, -5, -13, -2, -12,
- -5, -2, 21, 23, 2, 16, 0, -5, 6, -13,
- 23, -3, 32, -10, 15, -8, -44, -28, -9, -37,
- 2, -13, 9, 15, 12, 27, 7, 12, 0, 11,
- }, {
- -44, 6, -30, -8, 9, 10, 11, 14, 23, -5,
- 8, -4, 14, -12, 37, 14, 12, 26, 4, 16,
- -8, 16, -9, 7, -6, 19, 12, 25, -5, 24,
- -15, -13, -8, -36, -34, -31, -1, -18, -4, -18,
- }, {
- -22, -5, -42, -26, 6, -8, -1, -2, 9, -17,
- 10, -18, 21, -19, 39, 31, 23, 23, 16, 15,
- -2, 12, -7, -6, -5, 9, -1, 10, -7, 16,
- -4, -9, 0, -10, -17, -22, -16, -2, -14, -9,
- }, {
- -55, -1, -17, -6, 1, 16, 15, 35, 15, 2,
- 0, -4, 19, 8, 20, 13, 1, 14, -7, 3,
- -18, 0, -10, -5, -19, 19, 0, 21, -8, 16,
- -9, -39, 0, -36, -10, -7, 9, -4, 20, -5,
- }, {
- -33, -13, -29, -24, -1, -1, 2, 18, 0, -9,
- 3, -17, 27, 0, 21, 30, 12, 11, 5, 2,
- -12, -4, -9, -19, -18, 9, -13, 6, -11, 8,
- 2, -35, 8, -10, 7, 1, -4, 11, 10, 2,
- }, {
- -36, 5, -24, 4, -7, 7, -6, 17, 14, 5,
- 22, 22, 35, 8, 46, 1, 17, 3, 0, -2,
- 2, 10, 5, 0, 14, 15, 2, 18, 2, 4,
- -11, 7, -1, -36, -18, -32, -7, -27, -17, -20,
- }, {
- -14, -7, -36, -13, -10, -10, -18, 0, 0, -5,
- 25, 8, 43, 0, 48, 18, 27, 0, 12, -3,
- 7, 6, 7, -13, 15, 5, -11, 3, 0, -2,
- 0, 12, 6, -10, 0, -23, -22, -11, -26, -12,
- }, {
- -47, -3, -11, 6, -15, 13, -2, 38, 6, 13,
- 15, 22, 40, 28, 28, 0, 5, -8, -10, -15,
- -7, -7, 4, -13, 1, 14, -9, 14, 0, -2,
- -4, -18, 7, -36, 6, -8, 3, -13, 7, -8,
- }, {
- -25, -15, -22, -11, -18, -4, -15, 22, -8, 2,
- 17, 9, 48, 20, 30, 17, 16, -11, 1, -16,
- -2, -10, 5, -26, 2, 4, -22, 0, -2, -10,
- 6, -13, 14, -10, 23, 0, -10, 2, -1, 0,
- }, {
- -57, 26, -22, 7, 14, 28, 14, 3, 35, 0,
- -3, -1, 11, -16, 18, 10, 4, 31, 15, 28,
- 14, 23, 1, 21, -7, 2, -11, 1, -3, 1,
- -18, -9, -10, -13, -49, -24, -8, -14, -2, -16,
- }, {
- -35, 14, -34, -10, 10, 10, 1, -12, 20, -12,
- 0, -15, 18, -24, 20, 27, 14, 28, 27, 27,
- 20, 19, 2, 8, -5, -7, -25, -13, -5, -5,
- -6, -5, -2, 12, -31, -15, -23, 1, -12, -8,
- }, {
- -68, 18, -9, 9, 6, 35, 18, 25, 26, 7,
- -10, -1, 16, 3, 1, 9, -6, 19, 4, 15,
- 4, 6, 0, 8, -20, 2, -23, -2, -7, -5,
- -12, -35, -1, -13, -24, 0, 3, 0, 22, -4,
- }, {
- -46, 6, -21, -8, 2, 16, 5, 8, 11, -4,
- -8, -15, 24, -4, 2, 26, 3, 16, 16, 14,
- 9, 2, 1, -4, -19, -7, -36, -17, -9, -13,
- 0, -31, 5, 12, -7, 8, -11, 15, 13, 4,
- }, {
- -49, 24, -16, 20, -2, 26, -2, 7, 25, 10,
- 11, 25, 32, 3, 27, -2, 8, 8, 11, 9,
- 24, 17, 16, 14, 13, -2, -20, -5, 4, -17,
- -14, 12, -3, -13, -33, -25, -14, -23, -15, -19,
- }, {
- -27, 12, -28, 2, -6, 7, -15, -9, 11, -1,
- 13, 11, 40, -4, 29, 14, 19, 5, 23, 8,
- 30, 13, 17, 0, 14, -12, -34, -20, 2, -25,
- -2, 16, 4, 12, -15, -16, -29, -7, -24, -10,
- }, {
- -60, 16, -3, 22, -10, 32, 0, 28, 17, 18,
- 3, 25, 37, 23, 10, -3, -2, -3, 0, -3,
- 14, 0, 14, 1, 0, -2, -32, -9, 1, -25,
- -7, -13, 5, -13, -8, -1, -2, -8, 10, -6,
- }, {
- -38, 4, -15, 4, -14, 13, -12, 11, 2, 6,
- 6, 11, 45, 16, 11, 13, 7, -6, 12, -4,
- 20, -3, 16, -12, 1, -12, -46, -24, 0, -33,
- 3, -9, 12, 12, 8, 7, -17, 6, 0, 2
- }
-};
-
-const int8_t ff_cb2_vects[128][40]={
- {
- 73, -32, -60, -15, -26, 59, 2, -33, 30, -10,
- -3, -17, 8, 30, -1, -26, -4, -22, 10, 16,
- -36, -5, -11, 56, 37, 6, -10, -5, -13, -3,
- 6, -5, 11, 4, -19, -5, -16, 41, 24, 13,
- }, {
- 4, -11, -37, 23, -5, 46, -2, -29, -5, -39,
- -21, -9, 0, 49, 12, -9, -16, -26, 22, 15,
- -45, -20, -5, 40, 22, 17, -26, 31, -14, 2,
- -14, 10, 30, 20, -27, -9, -39, 39, 18, 5,
- }, {
- 34, -25, -48, -28, -11, 34, -2, -41, 9, -7,
- -17, 21, 20, 24, -17, -33, 0, -24, 10, 42,
- 3, -5, 10, 42, 11, 8, -3, 3, 16, 9,
- 22, -2, 0, -33, -10, 18, 7, 58, 10, 28,
- }, {
- -34, -4, -25, 10, 9, 21, -7, -36, -26, -36,
- -35, 28, 12, 42, -3, -16, -12, -28, 21, 42,
- -5, -21, 16, 26, -4, 19, -19, 39, 15, 15,
- 1, 13, 19, -17, -17, 14, -15, 55, 4, 19,
- }, {
- 28, -20, -51, -14, -6, 7, 0, -26, 27, -4,
- 18, -40, -6, 16, -1, -15, 0, -55, -5, -16,
- -19, 14, -3, 49, 14, 1, -22, -30, -12, 0,
- 24, 15, 9, -17, -45, -29, 4, 28, 51, 35,
- }, {
- -40, 0, -28, 24, 14, -5, -4, -21, -7, -33,
- 0, -32, -15, 35, 12, 1, -11, -58, 5, -16,
- -28, 0, 1, 33, 0, 11, -39, 5, -14, 6,
- 3, 31, 28, -1, -53, -33, -19, 25, 46, 26,
- }, {
- -11, -14, -39, -27, 9, -17, -4, -33, 6, 0,
- 4, -1, 5, 10, -17, -22, 5, -57, -5, 9,
- 20, 13, 18, 35, -11, 3, -16, -22, 17, 13,
- 40, 19, -1, -55, -35, -5, 27, 44, 37, 49,
- }, {
- -80, 6, -16, 11, 30, -30, -9, -28, -28, -29,
- -13, 6, -2, 28, -3, -5, -7, -60, 5, 9,
- 11, -1, 24, 19, -27, 13, -32, 13, 15, 19,
- 19, 35, 17, -39, -43, -9, 4, 42, 32, 41,
- }, {
- 78, -21, -43, 4, -38, 17, 17, -5, 55, 24,
- -15, -36, 14, 4, 24, -24, 12, 5, 17, 31,
- -54, -5, -2, 27, 43, -12, 2, 9, -9, -15,
- 22, -3, 28, 21, -20, 3, 20, 28, 9, -5,
- }, {
- 9, -1, -20, 43, -17, 3, 12, 0, 20, -4,
- -33, -29, 6, 22, 38, -7, 0, 1, 29, 30,
- -63, -21, 3, 11, 27, -1, -14, 45, -10, -9,
- 1, 12, 47, 37, -28, 0, -2, 26, 4, -13,
- }, {
- 39, -14, -30, -8, -22, -8, 12, -12, 34, 27,
- -29, 2, 26, -2, 8, -31, 16, 3, 17, 57,
- -14, -6, 19, 13, 16, -10, 8, 17, 20, -2,
- 38, 0, 17, -16, -11, 27, 44, 45, -4, 8,
- }, {
- -29, 5, -7, 30, -1, -21, 7, -7, 0, 0,
- -47, 9, 18, 15, 22, -14, 4, 0, 28, 57,
- -23, -21, 25, -2, 1, 0, -7, 53, 19, 3,
- 17, 15, 36, 0, -19, 24, 21, 43, -9, 0,
- }, {
- 33, -10, -34, 5, -17, -35, 15, 1, 53, 30,
- 6, -59, 0, -10, 24, -13, 17, -27, 1, -1,
- -37, 13, 4, 20, 20, -18, -10, -16, -8, -11,
- 39, 18, 26, 0, -46, -20, 41, 15, 37, 15,
- }, {
- -35, 10, -11, 44, 3, -48, 10, 6, 17, 2,
- -11, -51, -8, 8, 38, 3, 4, -31, 12, -2,
- -46, -1, 10, 4, 5, -7, -26, 19, -10, -5,
- 18, 34, 45, 15, -54, -24, 18, 13, 31, 7,
- }, {
- -5, -3, -21, -7, -2, -60, 10, -5, 32, 34,
- -7, -20, 11, -16, 8, -20, 21, -29, 1, 24,
- 2, 13, 27, 6, -5, -15, -3, -8, 21, 1,
- 55, 21, 15, -38, -37, 3, 65, 32, 23, 30,
- }, {
- -74, 17, 0, 31, 18, -73, 5, 0, -3, 5,
- -25, -12, 3, 1, 22, -3, 9, -33, 12, 24,
- -6, -2, 33, -9, -21, -5, -20, 27, 19, 7,
- 34, 37, 34, -22, -44, 0, 41, 29, 17, 21,
- }, {
- 76, -35, -31, -28, -49, 43, -40, 0, 29, -14,
- 8, 5, 10, 18, -26, -46, 0, 7, 6, 3,
- -25, -7, -2, 40, 28, 14, 18, -3, -27, -28,
- -8, -45, -13, 34, -13, -27, -15, 31, 12, 3,
- }, {
- 7, -15, -9, 9, -28, 29, -45, 5, -6, -43,
- -9, 12, 2, 36, -12, -30, -11, 3, 17, 3,
- -34, -22, 3, 24, 12, 24, 2, 32, -28, -22,
- -29, -29, 5, 50, -21, -31, -38, 29, 7, -5,
- }, {
- 36, -29, -19, -41, -34, 18, -45, -6, 8, -10,
- -5, 43, 23, 11, -42, -53, 5, 5, 6, 30,
- 14, -8, 20, 26, 1, 16, 25, 4, 3, -15,
- 7, -41, -23, -3, -4, -3, 8, 48, -1, 17,
- }, {
- -32, -8, 3, -2, -13, 4, -50, -1, -27, -39,
- -23, 51, 15, 30, -27, -37, -7, 1, 17, 29,
- 5, -23, 25, 10, -14, 26, 8, 41, 1, -9,
- -13, -26, -5, 12, -12, -7, -14, 45, -6, 9,
- }, {
- 31, -24, -23, -27, -29, -9, -43, 8, 26, -7,
- 30, -17, -4, 3, -26, -35, 5, -24, -10, -28,
- -9, 12, 5, 33, 5, 8, 5, -29, -26, -24,
- 9, -23, -14, 12, -39, -52, 5, 18, 39, 24,
- }, {
- -37, -3, 0, 10, -7, -22, -48, 12, -8, -36,
- 12, -9, -12, 22, -12, -19, -6, -28, 0, -29,
- -18, -3, 11, 17, -10, 18, -10, 7, -27, -18,
- -11, -7, 3, 28, -47, -55, -18, 15, 34, 16,
- }, {
- -8, -17, -10, -40, -13, -34, -47, 0, 5, -4,
- 16, 21, 8, -2, -42, -43, 10, -26, -10, -2,
- 31, 11, 27, 19, -21, 10, 12, -20, 3, -11,
- 25, -20, -25, -25, -29, -28, 28, 34, 25, 38,
- }, {
- -77, 2, 11, -1, 7, -47, -52, 5, -29, -33,
- -1, 28, 0, 15, -28, -26, -2, -30, 0, -2,
- 22, -4, 33, 3, -36, 21, -3, 15, 2, -5,
- 4, -4, -6, -9, -37, -31, 5, 32, 20, 30,
- }, {
- 81, -25, -14, -8, -61, 0, -25, 28, 54, 20,
- -3, -14, 17, -8, 0, -44, 16, 35, 13, 18,
- -43, -7, 6, 11, 33, -4, 30, 11, -22, -40,
- 6, -43, 3, 50, -14, -18, 22, 18, -1, -16,
- }, {
- 12, -4, 8, 29, -39, -12, -30, 33, 19, -8,
- -21, -6, 8, 9, 13, -28, 4, 31, 24, 18,
- -52, -23, 12, -4, 18, 5, 14, 47, -24, -34,
- -14, -27, 22, 66, -22, -22, -1, 16, -6, -24,
- }, {
- 41, -18, -2, -21, -45, -24, -30, 21, 33, 24,
- -17, 24, 29, -15, -16, -51, 21, 33, 13, 45,
- -3, -8, 28, -2, 7, -2, 37, 19, 7, -27,
- 22, -39, -7, 12, -5, 5, 45, 35, -15, -1,
- }, {
- -27, 1, 20, 17, -24, -38, -35, 26, -1, -4,
- -35, 32, 21, 3, -2, -35, 8, 29, 24, 44,
- -12, -24, 34, -18, -8, 7, 21, 55, 5, -21,
- 2, -23, 11, 28, -13, 1, 22, 33, -21, -10,
- }, {
- 36, -13, -5, -7, -40, -51, -28, 36, 52, 27,
- 18, -36, 2, -22, 0, -33, 21, 2, -3, -13,
- -26, 11, 14, 4, 10, -10, 18, -14, -22, -36,
- 24, -21, 1, 28, -40, -42, 42, 5, 25, 5,
- }, {
- -32, 6, 17, 31, -19, -65, -33, 41, 16, -1,
- 0, -29, -6, -4, 13, -17, 9, -1, 8, -14,
- -35, -3, 19, -11, -4, 0, 1, 21, -23, -30,
- 3, -5, 20, 44, -48, -46, 19, 3, 20, -3,
- }, {
- -3, -7, 6, -20, -25, -77, -32, 29, 31, 30,
- 4, 2, 14, -29, -16, -40, 26, 0, -3, 12,
- 13, 10, 36, -9, -15, -8, 24, -6, 7, -22,
- 40, -17, -8, -9, -31, -18, 66, 22, 11, 19,
- }, {
- -72, 13, 29, 18, -4, -90, -37, 34, -4, 1,
- -13, 9, 6, -11, -2, -24, 13, -3, 7, 11,
- 4, -4, 42, -25, -31, 1, 8, 29, 6, -17,
- 19, -2, 10, 6, -38, -22, 42, 19, 6, 11,
- }, {
- 116, -20, -68, -30, -28, 83, 28, -18, 32, -22,
- -13, -21, 5, 28, 5, -7, -24, -8, -22, 17,
- -23, 30, -25, 45, 15, -9, -11, -18, 22, -10,
- 4, -2, 19, -12, 23, 3, -43, 2, 12, -4,
- }, {
- 47, 0, -45, 7, -7, 69, 23, -13, -2, -51,
- -32, -14, -3, 47, 19, 8, -37, -11, -10, 16,
- -32, 15, -19, 29, 0, 1, -28, 18, 20, -4,
- -16, 13, 38, 3, 15, 0, -66, 0, 7, -13,
- }, {
- 77, -13, -56, -43, -13, 57, 23, -26, 11, -19,
- -27, 16, 17, 22, -10, -15, -19, -10, -22, 43,
- 16, 30, -2, 31, -11, -6, -5, -9, 52, 2,
- 20, 0, 8, -50, 33, 27, -19, 19, -1, 9,
- }, {
- 8, 6, -33, -4, 7, 44, 18, -21, -23, -48,
- -46, 24, 9, 40, 3, 1, -32, -13, -11, 43,
- 7, 14, 3, 15, -26, 3, -21, 26, 50, 8,
- 0, 16, 27, -34, 25, 23, -43, 17, -6, 1,
- }, {
- 71, -9, -59, -29, -8, 30, 26, -11, 30, -16,
- 8, -44, -9, 14, 5, 2, -19, -40, -38, -15,
- -7, 50, -17, 38, -7, -14, -24, -43, 22, -6,
- 22, 19, 17, -34, -2, -20, -23, -10, 39, 16,
- }, {
- 2, 11, -36, 9, 13, 17, 21, -6, -5, -45,
- -10, -36, -18, 33, 19, 19, -31, -44, -27, -15,
- -16, 34, -11, 22, -22, -4, -40, -7, 21, 0,
- 1, 35, 36, -18, -10, -24, -46, -12, 34, 8,
- }, {
- 32, -2, -47, -42, 7, 5, 21, -18, 9, -12,
- -5, -5, 2, 8, -10, -4, -14, -42, -38, 10,
- 33, 49, 5, 24, -33, -12, -17, -35, 52, 6,
- 38, 22, 7, -72, 7, 3, 0, 6, 25, 30,
- }, {
- -36, 18, -24, -3, 28, -7, 16, -13, -26, -41,
- -24, 1, -5, 26, 3, 12, -27, -46, -27, 10,
- 24, 34, 10, 8, -49, -2, -34, 0, 51, 12,
- 17, 38, 25, -56, 0, 0, -22, 3, 20, 22,
- }, {
- 121, -9, -50, -10, -40, 40, 43, 9, 58, 12,
- -25, -41, 11, 2, 31, -5, -8, 19, -15, 32,
- -41, 30, -16, 16, 20, -28, 0, -3, 26, -22,
- 19, 0, 36, 4, 22, 12, -6, -9, -1, -24,
- }, {
- 52, 10, -27, 27, -18, 26, 38, 14, 23, -16,
- -44, -33, 3, 20, 45, 10, -20, 15, -3, 31,
- -50, 14, -10, 0, 5, -17, -15, 32, 24, -16,
- -1, 15, 55, 20, 14, 8, -29, -12, -7, -32,
- }, {
- 82, -3, -38, -23, -24, 15, 38, 2, 37, 15,
- -39, -2, 23, -4, 15, -12, -3, 17, -15, 58,
- -1, 29, 6, 2, -5, -26, 7, 4, 56, -9,
- 35, 3, 25, -33, 32, 36, 17, 7, -15, -9,
- }, {
- 13, 17, -15, 15, -3, 1, 33, 7, 1, -12,
- -58, 5, 15, 13, 29, 3, -16, 13, -4, 57,
- -10, 13, 11, -13, -21, -15, -9, 40, 55, -3,
- 14, 19, 44, -17, 24, 32, -5, 4, -21, -18,
- }, {
- 76, 1, -41, -9, -19, -12, 41, 17, 55, 18,
- -3, -63, -3, -12, 30, 5, -3, -12, -31, 0,
- -24, 49, -8, 9, -1, -33, -12, -29, 27, -18,
- 37, 21, 34, -17, -3, -11, 14, -23, 25, -2,
- }, {
- 7, 22, -18, 29, 1, -25, 36, 21, 20, -9,
- -22, -56, -11, 6, 45, 21, -15, -16, -20, -1,
- -33, 34, -2, -6, -17, -23, -28, 6, 25, -12,
- 16, 37, 53, -1, -11, -15, -8, -25, 20, -11,
- }, {
- 37, 8, -29, -22, -4, -37, 36, 9, 34, 22,
- -17, -24, 8, -18, 15, -2, 1, -14, -31, 25,
- 15, 48, 13, -4, -28, -31, -5, -21, 57, -4,
- 53, 24, 23, -55, 6, 12, 37, -6, 11, 11,
- }, {
- -31, 28, -6, 16, 16, -50, 31, 14, 0, -6,
- -36, -17, 0, 0, 29, 14, -11, -18, -20, 25,
- 6, 33, 19, -20, -43, -21, -21, 14, 55, 0,
- 32, 40, 42, -39, -1, 8, 14, -8, 6, 3,
- }, {
- 119, -24, -39, -44, -51, 66, -14, 15, 31, -26,
- -1, 0, 7, 16, -19, -28, -19, 22, -26, 4,
- -13, 28, -16, 29, 5, -1, 16, -16, 8, -35,
- -10, -42, -4, 17, 29, -19, -42, -7, 0, -15,
- }, {
- 50, -3, -16, -5, -30, 53, -19, 20, -3, -55,
- -19, 8, 0, 34, -5, -11, -32, 18, -15, 4,
- -22, 13, -10, 13, -9, 8, 0, 19, 7, -29,
- -31, -26, 13, 33, 21, -22, -65, -9, -4, -23,
- }, {
- 79, -17, -27, -56, -36, 41, -19, 8, 10, -22,
- -15, 39, 20, 9, -35, -35, -15, 20, -26, 31,
- 26, 27, 6, 15, -20, 0, 23, -8, 38, -22,
- 5, -38, -15, -20, 39, 4, -18, 9, -13, -1,
- }, {
- 10, 3, -4, -18, -15, 27, -24, 13, -24, -51,
- -34, 47, 12, 28, -21, -19, -27, 16, -15, 30,
- 17, 12, 12, 0, -36, 10, 7, 27, 37, -16,
- -15, -22, 3, -4, 31, 1, -42, 7, -18, -9,
- }, {
- 74, -12, -30, -42, -30, 14, -16, 23, 29, -19,
- 20, -21, -7, 1, -19, -17, -14, -10, -43, -27,
- 3, 48, -8, 22, -16, -7, 4, -42, 9, -31,
- 6, -20, -6, -4, 3, -43, -22, -20, 28, 5,
- }, {
- 5, 7, -7, -4, -9, 0, -21, 28, -6, -48,
- 2, -14, -15, 20, -5, 0, -27, -14, -32, -28,
- -5, 32, -2, 6, -32, 3, -12, -5, 8, -25,
- -14, -4, 12, 11, -4, -47, -45, -22, 22, -2,
- }, {
- 34, -6, -18, -55, -15, -11, -21, 16, 8, -16,
- 6, 16, 5, -4, -35, -24, -10, -12, -43, -1,
- 43, 47, 14, 8, -43, -5, 10, -34, 39, -18,
- 22, -16, -17, -42, 13, -19, 1, -3, 14, 20,
- }, {
- -34, 14, 4, -17, 5, -24, -26, 20, -27, -45,
- -12, 24, -2, 13, -21, -8, -22, -16, -32, -2,
- 34, 31, 20, -7, -58, 5, -5, 2, 38, -12,
- 2, -1, 1, -26, 5, -23, -21, -6, 8, 11,
- }, {
- 124, -13, -21, -23, -62, 23, 0, 43, 57, 8,
- -13, -18, 14, -10, 6, -26, -3, 49, -19, 19,
- -31, 27, -7, 0, 11, -20, 29, -1, 12, -47,
- 4, -39, 11, 34, 28, -9, -5, -19, -13, -34,
- }, {
- 55, 6, 1, 14, -41, 10, -4, 48, 22, -20,
- -31, -10, 5, 7, 20, -9, -16, 45, -8, 19,
- -40, 12, -1, -15, -4, -10, 12, 34, 11, -41,
- -16, -24, 30, 49, 20, -13, -28, -22, -18, -43,
- }, {
- 84, -6, -9, -36, -47, -1, -4, 36, 36, 12,
- -27, 20, 26, -17, -9, -33, 1, 47, -19, 46,
- 9, 27, 15, -13, -15, -18, 35, 6, 42, -33,
- 20, -36, 1, -4, 38, 14, 18, -2, -27, -20,
- }, {
- 15, 13, 13, 1, -26, -14, -9, 41, 1, -16,
- -46, 27, 18, 1, 4, -16, -11, 43, -8, 45,
- 0, 11, 21, -29, -30, -8, 19, 42, 41, -28,
- 0, -20, 20, 11, 30, 10, -4, -5, -32, -28,
- }, {
- 79, -2, -12, -22, -42, -28, -1, 51, 54, 15,
- 8, -41, 0, -24, 6, -15, 1, 17, -36, -12,
- -14, 47, 0, -6, -11, -26, 16, -27, 13, -43,
- 22, -18, 10, 12, 2, -34, 15, -33, 13, -13,
- }, {
- 10, 18, 10, 15, -21, -41, -6, 56, 19, -13,
- -9, -33, -9, -6, 20, 1, -11, 13, -24, -13,
- -23, 32, 6, -22, -26, -15, 0, 8, 12, -37,
- 1, -2, 28, 27, -5, -37, -7, -35, 8, -21,
- }, {
- 39, 4, 0, -35, -27, -53, -6, 44, 33, 18,
- -5, -2, 11, -31, -9, -22, 6, 15, -36, 13,
- 25, 46, 23, -20, -37, -24, 23, -19, 43, -29,
- 38, -14, 0, -26, 12, -10, 38, -16, 0, 0,
- }, {
- -29, 25, 22, 2, -6, -67, -11, 49, -1, -10,
- -24, 5, 3, -13, 4, -5, -6, 11, -25, 12,
- 16, 31, 28, -36, -53, -13, 6, 16, 42, -24,
- 17, 1, 18, -10, 4, -13, 15, -18, -5, -7,
- }, {
- 29, -25, -22, -2, 6, 67, 11, -49, 1, 10,
- 24, -5, -3, 13, -4, 5, 6, -11, 25, -12,
- -16, -31, -28, 36, 53, 13, -6, -16, -42, 24,
- -17, -1, -18, 10, -4, 13, -15, 18, 5, 7,
- }, {
- -39, -4, 0, 35, 27, 53, 6, -44, -33, -18,
- 5, 2, -11, 31, 9, 22, -6, -15, 36, -13,
- -25, -46, -23, 20, 37, 24, -23, 19, -43, 29,
- -38, 14, 0, 26, -12, 10, -38, 16, 0, 0,
- }, {
- -10, -18, -10, -15, 21, 41, 6, -56, -19, 13,
- 9, 33, 9, 6, -20, -1, 11, -13, 24, 13,
- 23, -32, -6, 22, 26, 15, 0, -8, -12, 37,
- -1, 2, -28, -27, 5, 37, 7, 35, -8, 21,
- }, {
- -79, 2, 12, 22, 42, 28, 1, -51, -54, -15,
- -8, 41, 0, 24, -6, 15, -1, -17, 36, 12,
- 14, -47, 0, 6, 11, 26, -16, 27, -13, 43,
- -22, 18, -10, -12, -2, 34, -15, 33, -13, 13,
- }, {
- -15, -13, -13, -1, 26, 14, 9, -41, -1, 16,
- 46, -27, -18, -1, -4, 16, 11, -43, 8, -45,
- 0, -11, -21, 29, 30, 8, -19, -42, -41, 28,
- 0, 20, -20, -11, -30, -10, 4, 5, 32, 28,
- }, {
- -84, 6, 9, 36, 47, 1, 4, -36, -36, -12,
- 27, -20, -26, 17, 9, 33, -1, -47, 19, -46,
- -9, -27, -15, 13, 15, 18, -35, -6, -42, 33,
- -20, 36, -1, 4, -38, -14, -18, 2, 27, 20,
- }, {
- -55, -6, -1, -14, 41, -10, 4, -48, -22, 20,
- 31, 10, -5, -7, -20, 9, 16, -45, 8, -19,
- 40, -12, 1, 15, 4, 10, -12, -34, -11, 41,
- 16, 24, -30, -49, -20, 13, 28, 22, 18, 43,
- }, {
- -124, 13, 21, 23, 62, -23, 0, -43, -57, -8,
- 13, 18, -14, 10, -6, 26, 3, -49, 19, -19,
- 31, -27, 7, 0, -11, 20, -29, 1, -12, 47,
- -4, 39, -11, -34, -28, 9, 5, 19, 13, 34,
- }, {
- 34, -14, -4, 17, -5, 24, 26, -20, 27, 45,
- 12, -24, 2, -13, 21, 8, 22, 16, 32, 2,
- -34, -31, -20, 7, 58, -5, 5, -2, -38, 12,
- -2, 1, -1, 26, -5, 23, 21, 6, -8, -11,
- }, {
- -34, 6, 18, 55, 15, 11, 21, -16, -8, 16,
- -6, -16, -5, 4, 35, 24, 10, 12, 43, 1,
- -43, -47, -14, -8, 43, 5, -10, 34, -39, 18,
- -22, 16, 17, 42, -13, 19, -1, 3, -14, -20,
- }, {
- -5, -7, 7, 4, 9, 0, 21, -28, 6, 48,
- -2, 14, 15, -20, 5, 0, 27, 14, 32, 28,
- 5, -32, 2, -6, 32, -3, 12, 5, -8, 25,
- 14, 4, -12, -11, 4, 47, 45, 22, -22, 2,
- }, {
- -74, 12, 30, 42, 30, -14, 16, -23, -29, 19,
- -20, 21, 7, -1, 19, 17, 14, 10, 43, 27,
- -3, -48, 8, -22, 16, 7, -4, 42, -9, 31,
- -6, 20, 6, 4, -3, 43, 22, 20, -28, -5,
- }, {
- -10, -3, 4, 18, 15, -27, 24, -13, 24, 51,
- 34, -47, -12, -28, 21, 19, 27, -16, 15, -30,
- -17, -12, -12, 0, 36, -10, -7, -27, -37, 16,
- 15, 22, -3, 4, -31, -1, 42, -7, 18, 9,
- }, {
- -79, 17, 27, 56, 36, -41, 19, -8, -10, 22,
- 15, -39, -20, -9, 35, 35, 15, -20, 26, -31,
- -26, -27, -6, -15, 20, 0, -23, 8, -38, 22,
- -5, 38, 15, 20, -39, -4, 18, -9, 13, 1,
- }, {
- -50, 3, 16, 5, 30, -53, 19, -20, 3, 55,
- 19, -8, 0, -34, 5, 11, 32, -18, 15, -4,
- 22, -13, 10, -13, 9, -8, 0, -19, -7, 29,
- 31, 26, -13, -33, -21, 22, 65, 9, 4, 23,
- }, {
- -119, 24, 39, 44, 51, -66, 14, -15, -31, 26,
- 1, 0, -7, -16, 19, 28, 19, -22, 26, -4,
- 13, -28, 16, -29, -5, 1, -16, 16, -8, 35,
- 10, 42, 4, -17, -29, 19, 42, 7, 0, 15,
- }, {
- 31, -28, 6, -16, -16, 50, -31, -14, 0, 6,
- 36, 17, 0, 0, -29, -14, 11, 18, 20, -25,
- -6, -33, -19, 20, 43, 21, 21, -14, -55, 0,
- -32, -40, -42, 39, 1, -8, -14, 8, -6, -3,
- }, {
- -37, -8, 29, 22, 4, 37, -36, -9, -34, -22,
- 17, 24, -8, 18, -15, 2, -1, 14, 31, -25,
- -15, -48, -13, 4, 28, 31, 5, 21, -57, 4,
- -53, -24, -23, 55, -6, -12, -37, 6, -11, -11,
- }, {
- -7, -22, 18, -29, -1, 25, -36, -21, -20, 9,
- 22, 56, 11, -6, -45, -21, 15, 16, 20, 1,
- 33, -34, 2, 6, 17, 23, 28, -6, -25, 12,
- -16, -37, -53, 1, 11, 15, 8, 25, -20, 11,
- }, {
- -76, -1, 41, 9, 19, 12, -41, -17, -55, -18,
- 3, 63, 3, 12, -30, -5, 3, 12, 31, 0,
- 24, -49, 8, -9, 1, 33, 12, 29, -27, 18,
- -37, -21, -34, 17, 3, 11, -14, 23, -25, 2,
- }, {
- -13, -17, 15, -15, 3, -1, -33, -7, -1, 12,
- 58, -5, -15, -13, -29, -3, 16, -13, 4, -57,
- 10, -13, -11, 13, 21, 15, 9, -40, -55, 3,
- -14, -19, -44, 17, -24, -32, 5, -4, 21, 18,
- }, {
- -82, 3, 38, 23, 24, -15, -38, -2, -37, -15,
- 39, 2, -23, 4, -15, 12, 3, -17, 15, -58,
- 1, -29, -6, -2, 5, 26, -7, -4, -56, 9,
- -35, -3, -25, 33, -32, -36, -17, -7, 15, 9,
- }, {
- -52, -10, 27, -27, 18, -26, -38, -14, -23, 16,
- 44, 33, -3, -20, -45, -10, 20, -15, 3, -31,
- 50, -14, 10, 0, -5, 17, 15, -32, -24, 16,
- 1, -15, -55, -20, -14, -8, 29, 12, 7, 32,
- }, {
- -121, 9, 50, 10, 40, -40, -43, -9, -58, -12,
- 25, 41, -11, -2, -31, 5, 8, -19, 15, -32,
- 41, -30, 16, -16, -20, 28, 0, 3, -26, 22,
- -19, 0, -36, -4, -22, -12, 6, 9, 1, 24,
- }, {
- 36, -18, 24, 3, -28, 7, -16, 13, 26, 41,
- 24, -1, 5, -26, -3, -12, 27, 46, 27, -10,
- -24, -34, -10, -8, 49, 2, 34, 0, -51, -12,
- -17, -38, -25, 56, 0, 0, 22, -3, -20, -22,
- }, {
- -32, 2, 47, 42, -7, -5, -21, 18, -9, 12,
- 5, 5, -2, -8, 10, 4, 14, 42, 38, -10,
- -33, -49, -5, -24, 33, 12, 17, 35, -52, -6,
- -38, -22, -7, 72, -7, -3, 0, -6, -25, -30,
- }, {
- -2, -11, 36, -9, -13, -17, -21, 6, 5, 45,
- 10, 36, 18, -33, -19, -19, 31, 44, 27, 15,
- 16, -34, 11, -22, 22, 4, 40, 7, -21, 0,
- -1, -35, -36, 18, 10, 24, 46, 12, -34, -8,
- }, {
- -71, 9, 59, 29, 8, -30, -26, 11, -30, 16,
- -8, 44, 9, -14, -5, -2, 19, 40, 38, 15,
- 7, -50, 17, -38, 7, 14, 24, 43, -22, 6,
- -22, -19, -17, 34, 2, 20, 23, 10, -39, -16,
- }, {
- -8, -6, 33, 4, -7, -44, -18, 21, 23, 48,
- 46, -24, -9, -40, -3, -1, 32, 13, 11, -43,
- -7, -14, -3, -15, 26, -3, 21, -26, -50, -8,
- 0, -16, -27, 34, -25, -23, 43, -17, 6, -1,
- }, {
- -77, 13, 56, 43, 13, -57, -23, 26, -11, 19,
- 27, -16, -17, -22, 10, 15, 19, 10, 22, -43,
- -16, -30, 2, -31, 11, 6, 5, 9, -52, -2,
- -20, 0, -8, 50, -33, -27, 19, -19, 1, -9,
- }, {
- -47, 0, 45, -7, 7, -69, -23, 13, 2, 51,
- 32, 14, 3, -47, -19, -8, 37, 11, 10, -16,
- 32, -15, 19, -29, 0, -1, 28, -18, -20, 4,
- 16, -13, -38, -3, -15, 0, 66, 0, -7, 13,
- }, {
- -116, 20, 68, 30, 28, -83, -28, 18, -32, 22,
- 13, 21, -5, -28, -5, 7, 24, 8, 22, -17,
- 23, -30, 25, -45, -15, 9, 11, 18, -22, 10,
- -4, 2, -19, 12, -23, -3, 43, -2, -12, 4,
- }, {
- 72, -13, -29, -18, 4, 90, 37, -34, 4, -1,
- 13, -9, -6, 11, 2, 24, -13, 3, -7, -11,
- -4, 4, -42, 25, 31, -1, -8, -29, -6, 17,
- -19, 2, -10, -6, 38, 22, -42, -19, -6, -11,
- }, {
- 3, 7, -6, 20, 25, 77, 32, -29, -31, -30,
- -4, -2, -14, 29, 16, 40, -26, 0, 3, -12,
- -13, -10, -36, 9, 15, 8, -24, 6, -7, 22,
- -40, 17, 8, 9, 31, 18, -66, -22, -11, -19,
- }, {
- 32, -6, -17, -31, 19, 65, 33, -41, -16, 1,
- 0, 29, 6, 4, -13, 17, -9, 1, -8, 14,
- 35, 3, -19, 11, 4, 0, -1, -21, 23, 30,
- -3, 5, -20, -44, 48, 46, -19, -3, -20, 3,
- }, {
- -36, 13, 5, 7, 40, 51, 28, -36, -52, -27,
- -18, 36, -2, 22, 0, 33, -21, -2, 3, 13,
- 26, -11, -14, -4, -10, 10, -18, 14, 22, 36,
- -24, 21, -1, -28, 40, 42, -42, -5, -25, -5,
- }, {
- 27, -1, -20, -17, 24, 38, 35, -26, 1, 4,
- 35, -32, -21, -3, 2, 35, -8, -29, -24, -44,
- 12, 24, -34, 18, 8, -7, -21, -55, -5, 21,
- -2, 23, -11, -28, 13, -1, -22, -33, 21, 10,
- }, {
- -41, 18, 2, 21, 45, 24, 30, -21, -33, -24,
- 17, -24, -29, 15, 16, 51, -21, -33, -13, -45,
- 3, 8, -28, 2, -7, 2, -37, -19, -7, 27,
- -22, 39, 7, -12, 5, -5, -45, -35, 15, 1,
- }, {
- -12, 4, -8, -29, 39, 12, 30, -33, -19, 8,
- 21, 6, -8, -9, -13, 28, -4, -31, -24, -18,
- 52, 23, -12, 4, -18, -5, -14, -47, 24, 34,
- 14, 27, -22, -66, 22, 22, 1, -16, 6, 24,
- }, {
- -81, 25, 14, 8, 61, 0, 25, -28, -54, -20,
- 3, 14, -17, 8, 0, 44, -16, -35, -13, -18,
- 43, 7, -6, -11, -33, 4, -30, -11, 22, 40,
- -6, 43, -3, -50, 14, 18, -22, -18, 1, 16,
- }, {
- 77, -2, -11, 1, -7, 47, 52, -5, 29, 33,
- 1, -28, 0, -15, 28, 26, 2, 30, 0, 2,
- -22, 4, -33, -3, 36, -21, 3, -15, -2, 5,
- -4, 4, 6, 9, 37, 31, -5, -32, -20, -30,
- }, {
- 8, 17, 10, 40, 13, 34, 47, 0, -5, 4,
- -16, -21, -8, 2, 42, 43, -10, 26, 10, 2,
- -31, -11, -27, -19, 21, -10, -12, 20, -3, 11,
- -25, 20, 25, 25, 29, 28, -28, -34, -25, -38,
- }, {
- 37, 3, 0, -10, 7, 22, 48, -12, 8, 36,
- -12, 9, 12, -22, 12, 19, 6, 28, 0, 29,
- 18, 3, -11, -17, 10, -18, 10, -7, 27, 18,
- 11, 7, -3, -28, 47, 55, 18, -15, -34, -16,
- }, {
- -31, 24, 23, 27, 29, 9, 43, -8, -26, 7,
- -30, 17, 4, -3, 26, 35, -5, 24, 10, 28,
- 9, -12, -5, -33, -5, -8, -5, 29, 26, 24,
- -9, 23, 14, -12, 39, 52, -5, -18, -39, -24,
- }, {
- 32, 8, -3, 2, 13, -4, 50, 1, 27, 39,
- 23, -51, -15, -30, 27, 37, 7, -1, -17, -29,
- -5, 23, -25, -10, 14, -26, -8, -41, -1, 9,
- 13, 26, 5, -12, 12, 7, 14, -45, 6, -9,
- }, {
- -36, 29, 19, 41, 34, -18, 45, 6, -8, 10,
- 5, -43, -23, -11, 42, 53, -5, -5, -6, -30,
- -14, 8, -20, -26, -1, -16, -25, -4, -3, 15,
- -7, 41, 23, 3, 4, 3, -8, -48, 1, -17,
- }, {
- -7, 15, 9, -9, 28, -29, 45, -5, 6, 43,
- 9, -12, -2, -36, 12, 30, 11, -3, -17, -3,
- 34, 22, -3, -24, -12, -24, -2, -32, 28, 22,
- 29, 29, -5, -50, 21, 31, 38, -29, -7, 5,
- }, {
- -76, 35, 31, 28, 49, -43, 40, 0, -29, 14,
- -8, -5, -10, -18, 26, 46, 0, -7, -6, -3,
- 25, 7, 2, -40, -28, -14, -18, 3, 27, 28,
- 8, 45, 13, -34, 13, 27, 15, -31, -12, -3,
- }, {
- 74, -17, 0, -31, -18, 73, -5, 0, 3, -5,
- 25, 12, -3, -1, -22, 3, -9, 33, -12, -24,
- 6, 2, -33, 9, 21, 5, 20, -27, -19, -7,
- -34, -37, -34, 22, 44, 0, -41, -29, -17, -21,
- }, {
- 5, 3, 21, 7, 2, 60, -10, 5, -32, -34,
- 7, 20, -11, 16, -8, 20, -21, 29, -1, -24,
- -2, -13, -27, -6, 5, 15, 3, 8, -21, -1,
- -55, -21, -15, 38, 37, -3, -65, -32, -23, -30,
- }, {
- 35, -10, 11, -44, -3, 48, -10, -6, -17, -2,
- 11, 51, 8, -8, -38, -3, -4, 31, -12, 2,
- 46, 1, -10, -4, -5, 7, 26, -19, 10, 5,
- -18, -34, -45, -15, 54, 24, -18, -13, -31, -7,
- }, {
- -33, 10, 34, -5, 17, 35, -15, -1, -53, -30,
- -6, 59, 0, 10, -24, 13, -17, 27, -1, 1,
- 37, -13, -4, -20, -20, 18, 10, 16, 8, 11,
- -39, -18, -26, 0, 46, 20, -41, -15, -37, -15,
- }, {
- 29, -5, 7, -30, 1, 21, -7, 7, 0, 0,
- 47, -9, -18, -15, -22, 14, -4, 0, -28, -57,
- 23, 21, -25, 2, -1, 0, 7, -53, -19, -3,
- -17, -15, -36, 0, 19, -24, -21, -43, 9, 0,
- }, {
- -39, 14, 30, 8, 22, 8, -12, 12, -34, -27,
- 29, -2, -26, 2, -8, 31, -16, -3, -17, -57,
- 14, 6, -19, -13, -16, 10, -8, -17, -20, 2,
- -38, 0, -17, 16, 11, -27, -44, -45, 4, -8,
- }, {
- -9, 1, 20, -43, 17, -3, -12, 0, -20, 4,
- 33, 29, -6, -22, -38, 7, 0, -1, -29, -30,
- 63, 21, -3, -11, -27, 1, 14, -45, 10, 9,
- -1, -12, -47, -37, 28, 0, 2, -26, -4, 13,
- }, {
- -78, 21, 43, -4, 38, -17, -17, 5, -55, -24,
- 15, 36, -14, -4, -24, 24, -12, -5, -17, -31,
- 54, 5, 2, -27, -43, 12, -2, -9, 9, 15,
- -22, 3, -28, -21, 20, -3, -20, -28, -9, 5,
- }, {
- 80, -6, 16, -11, -30, 30, 9, 28, 28, 29,
- 13, -6, 2, -28, 3, 5, 7, 60, -5, -9,
- -11, 1, -24, -19, 27, -13, 32, -13, -15, -19,
- -19, -35, -17, 39, 43, 9, -4, -42, -32, -41,
- }, {
- 11, 14, 39, 27, -9, 17, 4, 33, -6, 0,
- -4, 1, -5, -10, 17, 22, -5, 57, 5, -9,
- -20, -13, -18, -35, 11, -3, 16, 22, -17, -13,
- -40, -19, 1, 55, 35, 5, -27, -44, -37, -49,
- }, {
- 40, 0, 28, -24, -14, 5, 4, 21, 7, 33,
- 0, 32, 15, -35, -12, -1, 11, 58, -5, 16,
- 28, 0, -1, -33, 0, -11, 39, -5, 14, -6,
- -3, -31, -28, 1, 53, 33, 19, -25, -46, -26,
- }, {
- -28, 20, 51, 14, 6, -7, 0, 26, -27, 4,
- -18, 40, 6, -16, 1, 15, 0, 55, 5, 16,
- 19, -14, 3, -49, -14, -1, 22, 30, 12, 0,
- -24, -15, -9, 17, 45, 29, -4, -28, -51, -35,
- }, {
- 34, 4, 25, -10, -9, -21, 7, 36, 26, 36,
- 35, -28, -12, -42, 3, 16, 12, 28, -21, -42,
- 5, 21, -16, -26, 4, -19, 19, -39, -15, -15,
- -1, -13, -19, 17, 17, -14, 15, -55, -4, -19,
- }, {
- -34, 25, 48, 28, 11, -34, 2, 41, -9, 7,
- 17, -21, -20, -24, 17, 33, 0, 24, -10, -42,
- -3, 5, -10, -42, -11, -8, 3, -3, -16, -9,
- -22, 2, 0, 33, 10, -18, -7, -58, -10, -28,
- }, {
- -4, 11, 37, -23, 5, -46, 2, 29, 5, 39,
- 21, 9, 0, -49, -12, 9, 16, 26, -22, -15,
- 45, 20, 5, -40, -22, -17, 26, -31, 14, -2,
- 14, -10, -30, -20, 27, 9, 39, -39, -18, -5,
- }, {
- -73, 32, 60, 15, 26, -59, -2, 33, -30, 10,
- 3, 17, -8, -30, 1, 26, 4, 22, -10, -16,
- 36, 5, 11, -56, -37, -6, 10, 5, 13, 3,
- -6, 5, -11, -4, 19, 5, 16, -41, -24, -13
- }
-};
-
-const uint16_t ff_cb1_base[128]={
- 19657, 18474, 18365, 17520, 21048, 18231, 18584, 16671,
- 20363, 19069, 19409, 18430, 21844, 18753, 19613, 17411,
- 20389, 21772, 20129, 21702, 20978, 20472, 19627, 19387,
- 21477, 23134, 21841, 23919, 22089, 21519, 21134, 20852,
- 19675, 17821, 19044, 17477, 19986, 16955, 18446, 16086,
- 21138, 18899, 20952, 18929, 21452, 17833, 20104, 17159,
- 19770, 20056, 20336, 20866, 19329, 18217, 18908, 18004,
- 21556, 21948, 23079, 23889, 20922, 19544, 20984, 19781,
- 19781, 20984, 19544, 20922, 23889, 23079, 21948, 21556,
- 18004, 18908, 18217, 19329, 20866, 20336, 20056, 19770,
- 17159, 20104, 17833, 21452, 18929, 20952, 18899, 21138,
- 16086, 18446, 16955, 19986, 17477, 19044, 17821, 19675,
- 20852, 21134, 21519, 22089, 23919, 21841, 23134, 21477,
- 19387, 19627, 20472, 20978, 21702, 20129, 21772, 20389,
- 17411, 19613, 18753, 21844, 18430, 19409, 19069, 20363,
- 16671, 18584, 18231, 21048, 17520, 18365, 18474, 19657,
-};
-
-const uint16_t ff_cb2_base[128]={
- 12174, 13380, 13879, 13832, 13170, 13227, 13204, 12053,
- 12410, 13988, 14348, 14631, 13100, 13415, 13224, 12268,
- 11982, 13825, 13499, 14210, 13877, 14788, 13811, 13109,
- 11449, 13275, 12833, 13717, 12728, 13696, 12759, 12405,
- 10230, 12185, 11628, 13161, 11762, 13458, 12312, 12818,
- 10443, 12773, 12011, 14020, 11818, 13825, 12453, 13226,
- 10446, 13162, 11881, 14300, 12859, 16288, 13490, 15053,
- 10155, 12820, 11519, 13973, 12041, 15081, 12635, 14198,
- 14198, 12635, 15081, 12041, 13973, 11519, 12820, 10155,
- 15053, 13490, 16288, 12859, 14300, 11881, 13162, 10446,
- 13226, 12453, 13825, 11818, 14020, 12011, 12773, 10443,
- 12818, 12312, 13458, 11762, 13161, 11628, 12185, 10230,
- 12405, 12759, 13696, 12728, 13717, 12833, 13275, 11449,
- 13109, 13811, 14788, 13877, 14210, 13499, 13825, 11982,
- 12268, 13224, 13415, 13100, 14631, 14348, 13988, 12410,
- 12053, 13204, 13227, 13170, 13832, 13879, 13380, 12174,
-};
-
-const int16_t ff_energy_tab[32]={
- 0, 16, 20, 25, 32, 41, 51, 65,
- 81, 103, 129, 163, 205, 259, 326, 410,
- 516, 650, 819, 1031, 1298, 1634, 2057, 2590,
- 3261, 4105, 5168, 6507, 8192, 10313, 12983, 16345
-};
-
-static const int16_t lpc_refl_cb1[64]={
- -4041, -4018, -3998, -3977, -3954, -3930, -3906, -3879,
- -3852, -3825, -3795, -3764, -3731, -3699, -3666, -3631,
- -3594, -3555, -3513, -3468, -3420, -3372, -3321, -3268,
- -3212, -3153, -3090, -3021, -2944, -2863, -2772, -2676,
- -2565, -2445, -2328, -2202, -2072, -1941, -1808, -1660,
- -1508, -1348, -1185, -994, -798, -600, -374, -110,
- 152, 447, 720, 982, 1229, 1456, 1682, 1916,
- 2130, 2353, 2595, 2853, 3118, 3363, 3588, 3814
-};
-
-static const int16_t lpc_refl_cb2[32]={
- -3091, -2386, -1871, -1425, -1021, -649, -316, -20,
- 267, 544, 810, 1065, 1305, 1534, 1756, 1970,
- 2171, 2359, 2536, 2700, 2854, 2996, 3133, 3263,
- 3386, 3499, 3603, 3701, 3789, 3870, 3947, 4020
-};
-
-static const int16_t lpc_refl_cb3[32]={
- -3525, -3295, -3081, -2890, -2696, -2511, -2328, -2149,
- -1979, -1817, -1658, -1498, -1341, -1188, -1032, -876,
- -721, -561, -394, -228, -54, 119, 296, 484,
- 683, 895, 1123, 1373, 1651, 1965, 2360, 2854
-};
-
-static const int16_t lpc_refl_cb4[16]={
- -1845, -1057, -522, -77, 301, 647, 975, 1285,
- 1582, 1873, 2163, 2452, 2735, 3017, 3299, 3569
-};
-
-static const int16_t lpc_refl_cb5[16]={
- -2691, -2187, -1788, -1435, -1118, -837, -571, -316,
- -59, 201, 470, 759, 1077, 1457, 1908, 2495
-};
-
-static const int16_t lpc_refl_cb6[8]={
- -1372, -474, 133, 632, 1100, 1571, 2075, 2672
-};
-
-static const int16_t lpc_refl_cb7[8]={
- -2389, -1787, -1231, -717, -239, 234, 770, 1474
-};
-
-static const int16_t lpc_refl_cb8[8]={
- -1569, -864, -296, 200, 670, 1151, 1709, 2385
-};
-
-static const int16_t lpc_refl_cb9[8]={
- -2200, -1608, -1062, -569, -120, 338, 863, 1621
-};
-
-static const int16_t lpc_refl_cb10[4]={
- -617, 190, 802, 1483
-};
-
-const int16_t * const ff_lpc_refl_cb[10]={
- lpc_refl_cb1, lpc_refl_cb2, lpc_refl_cb3, lpc_refl_cb4, lpc_refl_cb5,
- lpc_refl_cb6, lpc_refl_cb7, lpc_refl_cb8, lpc_refl_cb9, lpc_refl_cb10
-};
-
-static void add_wav(int16_t *dest, int n, int skip_first, int *m,
- const int16_t *s1, const int8_t *s2, const int8_t *s3)
-{
- int i;
- int v[3];
-
- v[0] = 0;
- for (i=!skip_first; i<3; i++)
- v[i] = (ff_gain_val_tab[n][i] * m[i]) >> ff_gain_exp_tab[n];
-
- if (v[0]) {
- for (i=0; i < BLOCKSIZE; i++)
- dest[i] = (s1[i]*v[0] + s2[i]*v[1] + s3[i]*v[2]) >> 12;
- } else {
- for (i=0; i < BLOCKSIZE; i++)
- dest[i] = ( s2[i]*v[1] + s3[i]*v[2]) >> 12;
- }
-}
-
-/**
- * Copy the last offset values of *source to *target. If those values are not
- * enough to fill the target buffer, fill it with another copy of those values.
- */
-void ff_copy_and_dup(int16_t *target, const int16_t *source, int offset)
-{
- source += BUFFERSIZE - offset;
-
- memcpy(target, source, FFMIN(BLOCKSIZE, offset)*sizeof(*target));
- if (offset < BLOCKSIZE)
- memcpy(target + offset, source, (BLOCKSIZE - offset)*sizeof(*target));
-}
-
-/**
- * Evaluate the reflection coefficients from the filter coefficients.
- *
- * @return 1 if one of the reflection coefficients is greater than
- * 4095, 0 if not.
- */
-int ff_eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx)
-{
- int b, i, j;
- int buffer1[LPC_ORDER];
- int buffer2[LPC_ORDER];
- int *bp1 = buffer1;
- int *bp2 = buffer2;
-
- for (i=0; i < LPC_ORDER; i++)
- buffer2[i] = coefs[i];
-
- refl[LPC_ORDER-1] = bp2[LPC_ORDER-1];
-
- if ((unsigned) bp2[LPC_ORDER-1] + 0x1000 > 0x1fff) {
- av_log(avctx, AV_LOG_ERROR, "Overflow. Broken sample?\n");
- return 1;
- }
-
- for (i = LPC_ORDER-2; i >= 0; i--) {
- b = 0x1000-((bp2[i+1] * bp2[i+1]) >> 12);
-
- if (!b)
- b = -2;
-
- b = 0x1000000 / b;
- for (j=0; j <= i; j++) {
-#if CONFIG_FTRAPV
- int a = bp2[j] - ((refl[i+1] * bp2[i-j]) >> 12);
- if((int)(a*(unsigned)b) != a*(int64_t)b)
- return 1;
-#endif
- bp1[j] = ((bp2[j] - ((refl[i+1] * bp2[i-j]) >> 12)) * b) >> 12;
- }
-
- if ((unsigned) bp1[i] + 0x1000 > 0x1fff)
- return 1;
-
- refl[i] = bp1[i];
-
- FFSWAP(int *, bp1, bp2);
- }
- return 0;
-}
-
-/**
- * Evaluate the LPC filter coefficients from the reflection coefficients.
- * Does the inverse of the ff_eval_refl() function.
- */
-void ff_eval_coefs(int *coefs, const int *refl)
-{
- int buffer[LPC_ORDER];
- int *b1 = buffer;
- int *b2 = coefs;
- int i, j;
-
- for (i=0; i < LPC_ORDER; i++) {
- b1[i] = refl[i] << 4;
-
- for (j=0; j < i; j++)
- b1[j] = ((refl[i] * b2[i-j-1]) >> 12) + b2[j];
-
- FFSWAP(int *, b1, b2);
- }
-
- for (i=0; i < LPC_ORDER; i++)
- coefs[i] >>= 4;
-}
-
-void ff_int_to_int16(int16_t *out, const int *inp)
-{
- int i;
-
- for (i = 0; i < LPC_ORDER; i++)
- *out++ = *inp++;
-}
-
-/**
- * Evaluate sqrt(x << 24). x must fit in 20 bits. This value is evaluated in an
- * odd way to make the output identical to the binary decoder.
- */
-int ff_t_sqrt(unsigned int x)
-{
- int s = 2;
- while (x > 0xfff) {
- s++;
- x >>= 2;
- }
-
- return ff_sqrt(x << 20) << s;
-}
-
-unsigned int ff_rms(const int *data)
-{
- int i;
- unsigned int res = 0x10000;
- int b = LPC_ORDER;
-
- for (i = 0; i < LPC_ORDER; i++) {
- res = (((0x1000000 - data[i]*data[i]) >> 12) * res) >> 12;
-
- if (res == 0)
- return 0;
-
- while (res <= 0x3fff) {
- b++;
- res <<= 2;
- }
- }
-
- return ff_t_sqrt(res) >> b;
-}
-
-int ff_interp(RA144Context *ractx, int16_t *out, int a, int copyold, int energy)
-{
- int work[LPC_ORDER];
- int b = NBLOCKS - a;
- int i;
-
- // Interpolate block coefficients from the this frame's forth block and
- // last frame's forth block.
- for (i = 0; i < LPC_ORDER; i++)
- out[i] = (a * ractx->lpc_coef[0][i] + b * ractx->lpc_coef[1][i])>> 2;
-
- if (ff_eval_refl(work, out, ractx->avctx)) {
- // The interpolated coefficients are unstable, copy either new or old
- // coefficients.
- ff_int_to_int16(out, ractx->lpc_coef[copyold]);
- return ff_rescale_rms(ractx->lpc_refl_rms[copyold], energy);
- } else {
- return ff_rescale_rms(ff_rms(work), energy);
- }
-}
-
-unsigned int ff_rescale_rms(unsigned int rms, unsigned int energy)
-{
- return (rms * energy) >> 10;
-}
-
-/** inverse root mean square */
-int ff_irms(AudioDSPContext *adsp, const int16_t *data)
-{
- unsigned int sum = adsp->scalarproduct_int16(data, data, BLOCKSIZE);
-
- if (sum == 0)
- return 0; /* OOPS - division by zero */
-
- return 0x20000000 / (ff_t_sqrt(sum) >> 8);
-}
-
-void ff_subblock_synthesis(RA144Context *ractx, const int16_t *lpc_coefs,
- int cba_idx, int cb1_idx, int cb2_idx,
- int gval, int gain)
-{
- int16_t *block;
- int m[3];
-
- if (cba_idx) {
- cba_idx += BLOCKSIZE/2 - 1;
- ff_copy_and_dup(ractx->buffer_a, ractx->adapt_cb, cba_idx);
- m[0] = (ff_irms(&ractx->adsp, ractx->buffer_a) * gval) >> 12;
- } else {
- m[0] = 0;
- }
- m[1] = (ff_cb1_base[cb1_idx] * gval) >> 8;
- m[2] = (ff_cb2_base[cb2_idx] * gval) >> 8;
- memmove(ractx->adapt_cb, ractx->adapt_cb + BLOCKSIZE,
- (BUFFERSIZE - BLOCKSIZE) * sizeof(*ractx->adapt_cb));
-
- block = ractx->adapt_cb + BUFFERSIZE - BLOCKSIZE;
-
- add_wav(block, gain, cba_idx, m, cba_idx? ractx->buffer_a: NULL,
- ff_cb1_vects[cb1_idx], ff_cb2_vects[cb2_idx]);
-
- memcpy(ractx->curr_sblock, ractx->curr_sblock + BLOCKSIZE,
- LPC_ORDER*sizeof(*ractx->curr_sblock));
-
- if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + LPC_ORDER, lpc_coefs,
- block, BLOCKSIZE, LPC_ORDER, 1, 0, 0xfff))
- memset(ractx->curr_sblock, 0, (LPC_ORDER+BLOCKSIZE)*sizeof(*ractx->curr_sblock));
-}
diff --git a/ffmpeg-2-8-11/libavcodec/ra144dec.c b/ffmpeg-2-8-11/libavcodec/ra144dec.c
deleted file mode 100644
index 3eed17c..0000000
--- a/ffmpeg-2-8-11/libavcodec/ra144dec.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Real Audio 1.0 (14.4K)
- *
- * Copyright (c) 2008 Vitor Sessak
- * Copyright (c) 2003 Nick Kurshev
- * Based on public domain decoder at http://www.honeypot.net/audio
- *
- * 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 "avcodec.h"
-#include "get_bits.h"
-#include "internal.h"
-#include "ra144.h"
-
-
-static av_cold int ra144_decode_init(AVCodecContext * avctx)
-{
- RA144Context *ractx = avctx->priv_data;
-
- ractx->avctx = avctx;
- ff_audiodsp_init(&ractx->adsp);
-
- ractx->lpc_coef[0] = ractx->lpc_tables[0];
- ractx->lpc_coef[1] = ractx->lpc_tables[1];
-
- avctx->channels = 1;
- avctx->channel_layout = AV_CH_LAYOUT_MONO;
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-
- return 0;
-}
-
-static void do_output_subblock(RA144Context *ractx, const int16_t *lpc_coefs,
- int gval, GetBitContext *gb)
-{
- int cba_idx = get_bits(gb, 7); // index of the adaptive CB, 0 if none
- int gain = get_bits(gb, 8);
- int cb1_idx = get_bits(gb, 7);
- int cb2_idx = get_bits(gb, 7);
-
- ff_subblock_synthesis(ractx, lpc_coefs, cba_idx, cb1_idx, cb2_idx, gval,
- gain);
-}
-
-/** Uncompress one block (20 bytes -> 160*2 bytes). */
-static int ra144_decode_frame(AVCodecContext * avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- AVFrame *frame = data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- static const uint8_t sizes[LPC_ORDER] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
- unsigned int refl_rms[NBLOCKS]; // RMS of the reflection coefficients
- int16_t block_coefs[NBLOCKS][LPC_ORDER]; // LPC coefficients of each sub-block
- unsigned int lpc_refl[LPC_ORDER]; // LPC reflection coefficients of the frame
- int i, j;
- int ret;
- int16_t *samples;
- unsigned int energy;
-
- RA144Context *ractx = avctx->priv_data;
- GetBitContext gb;
-
- if (buf_size < FRAME_SIZE) {
- av_log(avctx, AV_LOG_ERROR,
- "Frame too small (%d bytes). Truncated file?\n", buf_size);
- *got_frame_ptr = 0;
- return AVERROR_INVALIDDATA;
- }
-
- /* get output buffer */
- frame->nb_samples = NBLOCKS * BLOCKSIZE;
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
- samples = (int16_t *)frame->data[0];
-
- init_get_bits8(&gb, buf, FRAME_SIZE);
-
- for (i = 0; i < LPC_ORDER; i++)
- lpc_refl[i] = ff_lpc_refl_cb[i][get_bits(&gb, sizes[i])];
-
- ff_eval_coefs(ractx->lpc_coef[0], lpc_refl);
- ractx->lpc_refl_rms[0] = ff_rms(lpc_refl);
-
- energy = ff_energy_tab[get_bits(&gb, 5)];
-
- refl_rms[0] = ff_interp(ractx, block_coefs[0], 1, 1, ractx->old_energy);
- refl_rms[1] = ff_interp(ractx, block_coefs[1], 2,
- energy <= ractx->old_energy,
- ff_t_sqrt(energy*ractx->old_energy) >> 12);
- refl_rms[2] = ff_interp(ractx, block_coefs[2], 3, 0, energy);
- refl_rms[3] = ff_rescale_rms(ractx->lpc_refl_rms[0], energy);
-
- ff_int_to_int16(block_coefs[3], ractx->lpc_coef[0]);
-
- for (i=0; i < NBLOCKS; i++) {
- do_output_subblock(ractx, block_coefs[i], refl_rms[i], &gb);
-
- for (j=0; j < BLOCKSIZE; j++)
- *samples++ = av_clip_int16(ractx->curr_sblock[j + 10] << 2);
- }
-
- ractx->old_energy = energy;
- ractx->lpc_refl_rms[1] = ractx->lpc_refl_rms[0];
-
- FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]);
-
- *got_frame_ptr = 1;
-
- return FRAME_SIZE;
-}
-
-AVCodec ff_ra_144_decoder = {
- .name = "real_144",
- .long_name = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_RA_144,
- .priv_data_size = sizeof(RA144Context),
- .init = ra144_decode_init,
- .decode = ra144_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/rv34.c b/ffmpeg-2-8-11/libavcodec/rv34.c
deleted file mode 100644
index 51e0f40..0000000
--- a/ffmpeg-2-8-11/libavcodec/rv34.c
+++ /dev/null
@@ -1,1849 +0,0 @@
-/*
- * RV30/40 decoder common data
- * Copyright (c) 2007 Mike Melanson, 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
- */
-
-/**
- * @file
- * RV30/40 decoder common data
- */
-
-#include "libavutil/imgutils.h"
-#include "libavutil/internal.h"
-
-#include "avcodec.h"
-#include "error_resilience.h"
-#include "mpegutils.h"
-#include "mpegvideo.h"
-#include "golomb.h"
-#include "internal.h"
-#include "mathops.h"
-#include "mpeg_er.h"
-#include "qpeldsp.h"
-#include "rectangle.h"
-#include "thread.h"
-
-#include "rv34vlc.h"
-#include "rv34data.h"
-#include "rv34.h"
-
-static inline void ZERO8x2(void* dst, int stride)
-{
- fill_rectangle(dst, 1, 2, stride, 0, 4);
- fill_rectangle(((uint8_t*)(dst))+4, 1, 2, stride, 0, 4);
-}
-
-/** translation of RV30/40 macroblock types to lavc ones */
-static const int rv34_mb_type_to_lavc[12] = {
- MB_TYPE_INTRA,
- MB_TYPE_INTRA16x16 | MB_TYPE_SEPARATE_DC,
- MB_TYPE_16x16 | MB_TYPE_L0,
- MB_TYPE_8x8 | MB_TYPE_L0,
- MB_TYPE_16x16 | MB_TYPE_L0,
- MB_TYPE_16x16 | MB_TYPE_L1,
- MB_TYPE_SKIP,
- MB_TYPE_DIRECT2 | MB_TYPE_16x16,
- MB_TYPE_16x8 | MB_TYPE_L0,
- MB_TYPE_8x16 | MB_TYPE_L0,
- MB_TYPE_16x16 | MB_TYPE_L0L1,
- MB_TYPE_16x16 | MB_TYPE_L0 | MB_TYPE_SEPARATE_DC
-};
-
-
-static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES];
-
-static int rv34_decode_mv(RV34DecContext *r, int block_type);
-
-/**
- * @name RV30/40 VLC generating functions
- * @{
- */
-
-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];
-
-/**
- * Generate VLC from codeword lengths.
- * @param bits codeword lengths (zeroes are accepted)
- * @param size length of input data
- * @param vlc output VLC
- * @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)
-{
- 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;
-
- 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]]++;
- }
- }
-
- codes[0] = 0;
- for(i = 0; i < 16; i++)
- codes[i+1] = (codes[i] + counts[i]) << 1;
- for(i = 0; i < realsize; i++)
- cw[i] = codes[bits2[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,
- cw, 2, 2,
- syms, 2, 2, INIT_VLC_USE_NEW_STATIC);
-}
-
-/**
- * Initialize all tables.
- */
-static av_cold void rv34_init_tables(void)
-{
- int i, j, k;
-
- 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);
- 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);
- }
- }
- 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_intra_coeff[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient, NULL, 19*i + 18);
- }
-
- 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);
- 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);
- }
- 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_inter_coeff[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient, NULL, i*12 + 106);
- }
-}
-
-/** @} */ // vlc group
-
-/**
- * @name RV30/40 4x4 block decoding functions
- * @{
- */
-
-/**
- * Decode coded block pattern.
- */
-static int rv34_decode_cbp(GetBitContext *gb, RV34VLC *vlc, int table)
-{
- int pattern, code, cbp=0;
- int ones;
- static const int cbp_masks[3] = {0x100000, 0x010000, 0x110000};
- static const int shifts[4] = { 0, 2, 8, 10 };
- const int *curshift = shifts;
- int i, t, mask;
-
- code = get_vlc2(gb, vlc->cbppattern[table].table, 9, 2);
- pattern = code & 0xF;
- code >>= 4;
-
- ones = rv34_count_ones[pattern];
-
- for(mask = 8; mask; mask >>= 1, curshift++){
- if(pattern & mask)
- cbp |= get_vlc2(gb, vlc->cbp[table][ones].table, vlc->cbp[table][ones].bits, 1) << curshift[0];
- }
-
- for(i = 0; i < 4; i++){
- t = (modulo_three_table[code] >> (6 - 2*i)) & 3;
- if(t == 1)
- cbp |= cbp_masks[get_bits1(gb)] << i;
- if(t == 2)
- cbp |= cbp_masks[2] << i;
- }
- return cbp;
-}
-
-/**
- * Get one coefficient value from the bitstream and store it.
- */
-static inline void decode_coeff(int16_t *dst, int coef, int esc, GetBitContext *gb, VLC* vlc, int q)
-{
- if(coef){
- if(coef == esc){
- coef = get_vlc2(gb, vlc->table, 9, 2);
- if(coef > 23){
- coef -= 23;
- coef = 22 + ((1 << coef) | get_bits(gb, coef));
- }
- coef += esc;
- }
- if(get_bits1(gb))
- coef = -coef;
- *dst = (coef*q + 8) >> 4;
- }
-}
-
-/**
- * Decode 2x2 subblock of coefficients.
- */
-static inline void decode_subblock(int16_t *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc, int q)
-{
- int flags = modulo_three_table[code];
-
- decode_coeff( dst+0*4+0, (flags >> 6) , 3, gb, vlc, q);
- if(is_block2){
- decode_coeff(dst+1*4+0, (flags >> 4) & 3, 2, gb, vlc, q);
- decode_coeff(dst+0*4+1, (flags >> 2) & 3, 2, gb, vlc, q);
- }else{
- decode_coeff(dst+0*4+1, (flags >> 4) & 3, 2, gb, vlc, q);
- decode_coeff(dst+1*4+0, (flags >> 2) & 3, 2, gb, vlc, q);
- }
- decode_coeff( dst+1*4+1, (flags >> 0) & 3, 2, gb, vlc, q);
-}
-
-/**
- * Decode a single coefficient.
- */
-static inline void decode_subblock1(int16_t *dst, int code, GetBitContext *gb, VLC *vlc, int q)
-{
- int coeff = modulo_three_table[code] >> 6;
- decode_coeff(dst, coeff, 3, gb, vlc, q);
-}
-
-static inline void decode_subblock3(int16_t *dst, int code, GetBitContext *gb, VLC *vlc,
- int q_dc, int q_ac1, int q_ac2)
-{
- int flags = modulo_three_table[code];
-
- decode_coeff(dst+0*4+0, (flags >> 6) , 3, gb, vlc, q_dc);
- decode_coeff(dst+0*4+1, (flags >> 4) & 3, 2, gb, vlc, q_ac1);
- decode_coeff(dst+1*4+0, (flags >> 2) & 3, 2, gb, vlc, q_ac1);
- decode_coeff(dst+1*4+1, (flags >> 0) & 3, 2, gb, vlc, q_ac2);
-}
-
-/**
- * Decode coefficients for 4x4 block.
- *
- * This is done by filling 2x2 subblocks with decoded coefficients
- * in this order (the same for subblocks and subblock coefficients):
- * o--o
- * /
- * /
- * o--o
- */
-
-static int rv34_decode_block(int16_t *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc, int q_dc, int q_ac1, int q_ac2)
-{
- int code, pattern, has_ac = 1;
-
- code = get_vlc2(gb, rvlc->first_pattern[fc].table, 9, 2);
-
- pattern = code & 0x7;
-
- code >>= 3;
-
- if (modulo_three_table[code] & 0x3F) {
- decode_subblock3(dst, code, gb, &rvlc->coefficient, q_dc, q_ac1, q_ac2);
- } else {
- decode_subblock1(dst, code, gb, &rvlc->coefficient, q_dc);
- if (!pattern)
- return 0;
- has_ac = 0;
- }
-
- if(pattern & 4){
- code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
- decode_subblock(dst + 4*0+2, code, 0, gb, &rvlc->coefficient, q_ac2);
- }
- if(pattern & 2){ // Looks like coefficients 1 and 2 are swapped for this block
- code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
- decode_subblock(dst + 4*2+0, code, 1, gb, &rvlc->coefficient, q_ac2);
- }
- if(pattern & 1){
- code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2);
- decode_subblock(dst + 4*2+2, code, 0, gb, &rvlc->coefficient, q_ac2);
- }
- return has_ac | pattern;
-}
-
-/**
- * @name RV30/40 bitstream parsing
- * @{
- */
-
-/**
- * Decode starting slice position.
- * @todo Maybe replace with ff_h263_decode_mba() ?
- */
-int ff_rv34_get_start_offset(GetBitContext *gb, int mb_size)
-{
- int i;
- for(i = 0; i < 5; i++)
- if(rv34_mb_max_sizes[i] >= mb_size - 1)
- break;
- return rv34_mb_bits_sizes[i];
-}
-
-/**
- * Select VLC set for decoding from current quantizer, modifier and frame type.
- */
-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)]];
-}
-
-/**
- * Decode intra macroblock header and return CBP in case of success, -1 otherwise.
- */
-static int rv34_decode_intra_mb_header(RV34DecContext *r, int8_t *intra_types)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int t;
-
- r->is16 = get_bits1(gb);
- if(r->is16){
- s->current_picture_ptr->mb_type[mb_pos] = MB_TYPE_INTRA16x16;
- r->block_type = RV34_MB_TYPE_INTRA16x16;
- t = get_bits(gb, 2);
- fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
- r->luma_vlc = 2;
- }else{
- if(!r->rv30){
- if(!get_bits1(gb))
- av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n");
- }
- s->current_picture_ptr->mb_type[mb_pos] = MB_TYPE_INTRA;
- r->block_type = RV34_MB_TYPE_INTRA;
- if(r->decode_intra_types(r, gb, intra_types) < 0)
- return -1;
- r->luma_vlc = 1;
- }
-
- r->chroma_vlc = 0;
- r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
-
- return rv34_decode_cbp(gb, r->cur_vlcs, r->is16);
-}
-
-/**
- * Decode inter macroblock header and return CBP in case of success, -1 otherwise.
- */
-static int rv34_decode_inter_mb_header(RV34DecContext *r, int8_t *intra_types)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int i, t;
-
- r->block_type = r->decode_mb_info(r);
- if(r->block_type == -1)
- return -1;
- s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type];
- r->mb_type[mb_pos] = r->block_type;
- if(r->block_type == RV34_MB_SKIP){
- if(s->pict_type == AV_PICTURE_TYPE_P)
- r->mb_type[mb_pos] = RV34_MB_P_16x16;
- if(s->pict_type == AV_PICTURE_TYPE_B)
- r->mb_type[mb_pos] = RV34_MB_B_DIRECT;
- }
- r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]);
- rv34_decode_mv(r, r->block_type);
- if(r->block_type == RV34_MB_SKIP){
- fill_rectangle(intra_types, 4, 4, r->intra_types_stride, 0, sizeof(intra_types[0]));
- return 0;
- }
- r->chroma_vlc = 1;
- r->luma_vlc = 0;
-
- if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
- if(r->is16){
- t = get_bits(gb, 2);
- fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
- r->luma_vlc = 2;
- }else{
- if(r->decode_intra_types(r, gb, intra_types) < 0)
- return -1;
- r->luma_vlc = 1;
- }
- r->chroma_vlc = 0;
- r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
- }else{
- for(i = 0; i < 16; i++)
- intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 0;
- r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
- if(r->mb_type[mb_pos] == RV34_MB_P_MIX16x16){
- r->is16 = 1;
- r->chroma_vlc = 1;
- r->luma_vlc = 2;
- r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
- }
- }
-
- return rv34_decode_cbp(gb, r->cur_vlcs, r->is16);
-}
-
-/** @} */ //bitstream functions
-
-/**
- * @name motion vector related code (prediction, reconstruction, motion compensation)
- * @{
- */
-
-/** macroblock partition width in 8x8 blocks */
-static const uint8_t part_sizes_w[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2 };
-
-/** macroblock partition height in 8x8 blocks */
-static const uint8_t part_sizes_h[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2 };
-
-/** availability index for subblocks */
-static const uint8_t avail_indexes[4] = { 6, 7, 10, 11 };
-
-/**
- * motion vector prediction
- *
- * Motion prediction performed for the block by using median prediction of
- * motion vectors from the left, top and right top blocks but in corner cases
- * some other vectors may be used instead.
- */
-static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int dmv_no)
-{
- MpegEncContext *s = &r->s;
- int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
- int A[2] = {0}, B[2], C[2];
- int i, j;
- int mx, my;
- int* avail = r->avail_cache + avail_indexes[subblock_no];
- int c_off = part_sizes_w[block_type];
-
- mv_pos += (subblock_no & 1) + (subblock_no >> 1)*s->b8_stride;
- if(subblock_no == 3)
- c_off = -1;
-
- if(avail[-1]){
- A[0] = s->current_picture_ptr->motion_val[0][mv_pos-1][0];
- A[1] = s->current_picture_ptr->motion_val[0][mv_pos-1][1];
- }
- if(avail[-4]){
- B[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][0];
- B[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][1];
- }else{
- B[0] = A[0];
- B[1] = A[1];
- }
- if(!avail[c_off-4]){
- if(avail[-4] && (avail[-1] || r->rv30)){
- C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][0];
- C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][1];
- }else{
- C[0] = A[0];
- C[1] = A[1];
- }
- }else{
- C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][0];
- C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][1];
- }
- mx = mid_pred(A[0], B[0], C[0]);
- my = mid_pred(A[1], B[1], C[1]);
- mx += r->dmv[dmv_no][0];
- my += r->dmv[dmv_no][1];
- for(j = 0; j < part_sizes_h[block_type]; j++){
- for(i = 0; i < part_sizes_w[block_type]; i++){
- s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx;
- s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my;
- }
- }
-}
-
-#define GET_PTS_DIFF(a, b) (((a) - (b) + 8192) & 0x1FFF)
-
-/**
- * Calculate motion vector component that should be added for direct blocks.
- */
-static int calc_add_mv(RV34DecContext *r, int dir, int val)
-{
- int mul = dir ? -r->mv_weight2 : r->mv_weight1;
-
- return (val * mul + 0x2000) >> 14;
-}
-
-/**
- * Predict motion vector for B-frame macroblock.
- */
-static inline void rv34_pred_b_vector(int A[2], int B[2], int C[2],
- int A_avail, int B_avail, int C_avail,
- int *mx, int *my)
-{
- if(A_avail + B_avail + C_avail != 3){
- *mx = A[0] + B[0] + C[0];
- *my = A[1] + B[1] + C[1];
- if(A_avail + B_avail + C_avail == 2){
- *mx /= 2;
- *my /= 2;
- }
- }else{
- *mx = mid_pred(A[0], B[0], C[0]);
- *my = mid_pred(A[1], B[1], C[1]);
- }
-}
-
-/**
- * motion vector prediction for B-frames
- */
-static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
-{
- MpegEncContext *s = &r->s;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
- int A[2] = { 0 }, B[2] = { 0 }, C[2] = { 0 };
- int has_A = 0, has_B = 0, has_C = 0;
- int mx, my;
- int i, j;
- Picture *cur_pic = s->current_picture_ptr;
- const int mask = dir ? MB_TYPE_L1 : MB_TYPE_L0;
- int type = cur_pic->mb_type[mb_pos];
-
- if((r->avail_cache[6-1] & type) & mask){
- A[0] = cur_pic->motion_val[dir][mv_pos - 1][0];
- A[1] = cur_pic->motion_val[dir][mv_pos - 1][1];
- has_A = 1;
- }
- if((r->avail_cache[6-4] & type) & mask){
- B[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][0];
- B[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][1];
- has_B = 1;
- }
- if(r->avail_cache[6-4] && (r->avail_cache[6-2] & type) & mask){
- C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][0];
- C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][1];
- has_C = 1;
- }else if((s->mb_x+1) == s->mb_width && (r->avail_cache[6-5] & type) & mask){
- C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][0];
- C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][1];
- has_C = 1;
- }
-
- rv34_pred_b_vector(A, B, C, has_A, has_B, has_C, &mx, &my);
-
- mx += r->dmv[dir][0];
- my += r->dmv[dir][1];
-
- for(j = 0; j < 2; j++){
- for(i = 0; i < 2; i++){
- cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx;
- cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my;
- }
- }
- if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD){
- ZERO8x2(cur_pic->motion_val[!dir][mv_pos], s->b8_stride);
- }
-}
-
-/**
- * motion vector prediction - RV3 version
- */
-static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir)
-{
- MpegEncContext *s = &r->s;
- int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
- int A[2] = {0}, B[2], C[2];
- int i, j, k;
- int mx, my;
- int* avail = r->avail_cache + avail_indexes[0];
-
- if(avail[-1]){
- A[0] = s->current_picture_ptr->motion_val[0][mv_pos - 1][0];
- A[1] = s->current_picture_ptr->motion_val[0][mv_pos - 1][1];
- }
- if(avail[-4]){
- B[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][0];
- B[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][1];
- }else{
- B[0] = A[0];
- B[1] = A[1];
- }
- if(!avail[-4 + 2]){
- if(avail[-4] && (avail[-1])){
- C[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride - 1][0];
- C[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride - 1][1];
- }else{
- C[0] = A[0];
- C[1] = A[1];
- }
- }else{
- C[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride + 2][0];
- C[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride + 2][1];
- }
- mx = mid_pred(A[0], B[0], C[0]);
- my = mid_pred(A[1], B[1], C[1]);
- mx += r->dmv[0][0];
- my += r->dmv[0][1];
- for(j = 0; j < 2; j++){
- for(i = 0; i < 2; i++){
- for(k = 0; k < 2; k++){
- s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx;
- s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][1] = my;
- }
- }
- }
-}
-
-static const int chroma_coeffs[3] = { 0, 3, 5 };
-
-/**
- * generic motion compensation function
- *
- * @param r decoder context
- * @param block_type type of the current block
- * @param xoff horizontal offset from the start of the current block
- * @param yoff vertical offset from the start of the current block
- * @param mv_off offset to the motion vector information
- * @param width width of the current partition in 8x8 blocks
- * @param height height of the current partition in 8x8 blocks
- * @param dir motion compensation direction (i.e. from the last or the next reference frame)
- * @param thirdpel motion vectors are specified in 1/3 of pixel
- * @param qpel_mc a set of functions used to perform luma motion compensation
- * @param chroma_mc a set of functions used to perform chroma motion compensation
- */
-static inline void rv34_mc(RV34DecContext *r, const int block_type,
- const int xoff, const int yoff, int mv_off,
- const int width, const int height, int dir,
- const int thirdpel, int weighted,
- qpel_mc_func (*qpel_mc)[16],
- h264_chroma_mc_func (*chroma_mc))
-{
- MpegEncContext *s = &r->s;
- uint8_t *Y, *U, *V, *srcY, *srcU, *srcV;
- int dxy, mx, my, umx, umy, lx, ly, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
- int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride + mv_off;
- int is16x16 = 1;
- int emu = 0;
-
- if(thirdpel){
- int chroma_mx, chroma_my;
- mx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24);
- my = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24);
- lx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) % 3;
- ly = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) % 3;
- chroma_mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2;
- chroma_my = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2;
- umx = (chroma_mx + (3 << 24)) / 3 - (1 << 24);
- umy = (chroma_my + (3 << 24)) / 3 - (1 << 24);
- uvmx = chroma_coeffs[(chroma_mx + (3 << 24)) % 3];
- uvmy = chroma_coeffs[(chroma_my + (3 << 24)) % 3];
- }else{
- int cx, cy;
- mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] >> 2;
- my = s->current_picture_ptr->motion_val[dir][mv_pos][1] >> 2;
- lx = s->current_picture_ptr->motion_val[dir][mv_pos][0] & 3;
- ly = s->current_picture_ptr->motion_val[dir][mv_pos][1] & 3;
- cx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2;
- cy = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2;
- umx = cx >> 2;
- umy = cy >> 2;
- uvmx = (cx & 3) << 1;
- uvmy = (cy & 3) << 1;
- //due to some flaw RV40 uses the same MC compensation routine for H2V2 and H3V3
- if(uvmx == 6 && uvmy == 6)
- uvmx = uvmy = 4;
- }
-
- if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) {
- /* wait for the referenced mb row to be finished */
- int mb_row = s->mb_y + ((yoff + my + 5 + 8 * height) >> 4);
- ThreadFrame *f = dir ? &s->next_picture_ptr->tf : &s->last_picture_ptr->tf;
- ff_thread_await_progress(f, mb_row, 0);
- }
-
- dxy = ly*4 + lx;
- srcY = dir ? s->next_picture_ptr->f->data[0] : s->last_picture_ptr->f->data[0];
- srcU = dir ? s->next_picture_ptr->f->data[1] : s->last_picture_ptr->f->data[1];
- srcV = dir ? s->next_picture_ptr->f->data[2] : s->last_picture_ptr->f->data[2];
- src_x = s->mb_x * 16 + xoff + mx;
- src_y = s->mb_y * 16 + yoff + my;
- uvsrc_x = s->mb_x * 8 + (xoff >> 1) + umx;
- uvsrc_y = s->mb_y * 8 + (yoff >> 1) + umy;
- srcY += src_y * s->linesize + src_x;
- srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
- srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
- if(s->h_edge_pos - (width << 3) < 6 || s->v_edge_pos - (height << 3) < 6 ||
- (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4 ||
- (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4) {
- srcY -= 2 + 2*s->linesize;
- s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
- s->linesize, s->linesize,
- (width << 3) + 6, (height << 3) + 6,
- src_x - 2, src_y - 2,
- s->h_edge_pos, s->v_edge_pos);
- srcY = s->sc.edge_emu_buffer + 2 + 2*s->linesize;
- emu = 1;
- }
- if(!weighted){
- Y = s->dest[0] + xoff + yoff *s->linesize;
- U = s->dest[1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
- V = s->dest[2] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
- }else{
- Y = r->tmp_b_block_y [dir] + xoff + yoff *s->linesize;
- U = r->tmp_b_block_uv[dir*2] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
- V = r->tmp_b_block_uv[dir*2+1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
- }
-
- if(block_type == RV34_MB_P_16x8){
- qpel_mc[1][dxy](Y, srcY, s->linesize);
- Y += 8;
- srcY += 8;
- }else if(block_type == RV34_MB_P_8x16){
- qpel_mc[1][dxy](Y, srcY, s->linesize);
- Y += 8 * s->linesize;
- srcY += 8 * s->linesize;
- }
- is16x16 = (block_type != RV34_MB_P_8x8) && (block_type != RV34_MB_P_16x8) && (block_type != RV34_MB_P_8x16);
- qpel_mc[!is16x16][dxy](Y, srcY, s->linesize);
- if (emu) {
- uint8_t *uvbuf = s->sc.edge_emu_buffer;
-
- s->vdsp.emulated_edge_mc(uvbuf, srcU,
- s->uvlinesize, s->uvlinesize,
- (width << 2) + 1, (height << 2) + 1,
- uvsrc_x, uvsrc_y,
- s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- srcU = uvbuf;
- uvbuf += 9*s->uvlinesize;
-
- s->vdsp.emulated_edge_mc(uvbuf, srcV,
- s->uvlinesize, s->uvlinesize,
- (width << 2) + 1, (height << 2) + 1,
- uvsrc_x, uvsrc_y,
- s->h_edge_pos >> 1, s->v_edge_pos >> 1);
- srcV = uvbuf;
- }
- chroma_mc[2-width] (U, srcU, s->uvlinesize, height*4, uvmx, uvmy);
- chroma_mc[2-width] (V, srcV, s->uvlinesize, height*4, uvmx, uvmy);
-}
-
-static void rv34_mc_1mv(RV34DecContext *r, const int block_type,
- const int xoff, const int yoff, int mv_off,
- const int width, const int height, int dir)
-{
- rv34_mc(r, block_type, xoff, yoff, mv_off, width, height, dir, r->rv30, 0,
- r->rdsp.put_pixels_tab,
- r->rdsp.put_chroma_pixels_tab);
-}
-
-static void rv4_weight(RV34DecContext *r)
-{
- r->rdsp.rv40_weight_pixels_tab[r->scaled_weight][0](r->s.dest[0],
- r->tmp_b_block_y[0],
- r->tmp_b_block_y[1],
- r->weight1,
- r->weight2,
- r->s.linesize);
- r->rdsp.rv40_weight_pixels_tab[r->scaled_weight][1](r->s.dest[1],
- r->tmp_b_block_uv[0],
- r->tmp_b_block_uv[2],
- r->weight1,
- r->weight2,
- r->s.uvlinesize);
- r->rdsp.rv40_weight_pixels_tab[r->scaled_weight][1](r->s.dest[2],
- r->tmp_b_block_uv[1],
- r->tmp_b_block_uv[3],
- r->weight1,
- r->weight2,
- r->s.uvlinesize);
-}
-
-static void rv34_mc_2mv(RV34DecContext *r, const int block_type)
-{
- int weighted = !r->rv30 && block_type != RV34_MB_B_BIDIR && r->weight1 != 8192;
-
- rv34_mc(r, block_type, 0, 0, 0, 2, 2, 0, r->rv30, weighted,
- r->rdsp.put_pixels_tab,
- r->rdsp.put_chroma_pixels_tab);
- if(!weighted){
- rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, 0,
- r->rdsp.avg_pixels_tab,
- r->rdsp.avg_chroma_pixels_tab);
- }else{
- rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, 1,
- r->rdsp.put_pixels_tab,
- r->rdsp.put_chroma_pixels_tab);
- rv4_weight(r);
- }
-}
-
-static void rv34_mc_2mv_skip(RV34DecContext *r)
-{
- int i, j;
- int weighted = !r->rv30 && r->weight1 != 8192;
-
- for(j = 0; j < 2; j++)
- for(i = 0; i < 2; i++){
- rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 0, r->rv30,
- weighted,
- r->rdsp.put_pixels_tab,
- r->rdsp.put_chroma_pixels_tab);
- rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 1, r->rv30,
- weighted,
- weighted ? r->rdsp.put_pixels_tab : r->rdsp.avg_pixels_tab,
- weighted ? r->rdsp.put_chroma_pixels_tab : r->rdsp.avg_chroma_pixels_tab);
- }
- if(weighted)
- rv4_weight(r);
-}
-
-/** number of motion vectors in each macroblock type */
-static const int num_mvs[RV34_MB_TYPES] = { 0, 0, 1, 4, 1, 1, 0, 0, 2, 2, 2, 1 };
-
-/**
- * Decode motion vector differences
- * and perform motion vector reconstruction and motion compensation.
- */
-static int rv34_decode_mv(RV34DecContext *r, int block_type)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int i, j, k, l;
- int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
- int next_bt;
-
- memset(r->dmv, 0, sizeof(r->dmv));
- for(i = 0; i < num_mvs[block_type]; i++){
- r->dmv[i][0] = svq3_get_se_golomb(gb);
- r->dmv[i][1] = svq3_get_se_golomb(gb);
- }
- switch(block_type){
- case RV34_MB_TYPE_INTRA:
- case RV34_MB_TYPE_INTRA16x16:
- ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
- return 0;
- case RV34_MB_SKIP:
- if(s->pict_type == AV_PICTURE_TYPE_P){
- ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
- rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
- break;
- }
- case RV34_MB_B_DIRECT:
- //surprisingly, it uses motion scheme from next reference frame
- /* wait for the current mb row to be finished */
- if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
- ff_thread_await_progress(&s->next_picture_ptr->tf, FFMAX(0, s->mb_y-1), 0);
-
- next_bt = s->next_picture_ptr->mb_type[s->mb_x + s->mb_y * s->mb_stride];
- if(IS_INTRA(next_bt) || IS_SKIP(next_bt)){
- ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
- ZERO8x2(s->current_picture_ptr->motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
- }else
- for(j = 0; j < 2; j++)
- for(i = 0; i < 2; i++)
- for(k = 0; k < 2; k++)
- for(l = 0; l < 2; l++)
- s->current_picture_ptr->motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][k]);
- if(!(IS_16X8(next_bt) || IS_8X16(next_bt) || IS_8X8(next_bt))) //we can use whole macroblock MC
- rv34_mc_2mv(r, block_type);
- else
- rv34_mc_2mv_skip(r);
- ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
- break;
- case RV34_MB_P_16x16:
- case RV34_MB_P_MIX16x16:
- rv34_pred_mv(r, block_type, 0, 0);
- rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
- break;
- case RV34_MB_B_FORWARD:
- case RV34_MB_B_BACKWARD:
- r->dmv[1][0] = r->dmv[0][0];
- r->dmv[1][1] = r->dmv[0][1];
- if(r->rv30)
- rv34_pred_mv_rv3(r, block_type, block_type == RV34_MB_B_BACKWARD);
- else
- rv34_pred_mv_b (r, block_type, block_type == RV34_MB_B_BACKWARD);
- rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, block_type == RV34_MB_B_BACKWARD);
- break;
- case RV34_MB_P_16x8:
- case RV34_MB_P_8x16:
- rv34_pred_mv(r, block_type, 0, 0);
- rv34_pred_mv(r, block_type, 1 + (block_type == RV34_MB_P_16x8), 1);
- if(block_type == RV34_MB_P_16x8){
- rv34_mc_1mv(r, block_type, 0, 0, 0, 2, 1, 0);
- rv34_mc_1mv(r, block_type, 0, 8, s->b8_stride, 2, 1, 0);
- }
- if(block_type == RV34_MB_P_8x16){
- rv34_mc_1mv(r, block_type, 0, 0, 0, 1, 2, 0);
- rv34_mc_1mv(r, block_type, 8, 0, 1, 1, 2, 0);
- }
- break;
- case RV34_MB_B_BIDIR:
- rv34_pred_mv_b (r, block_type, 0);
- rv34_pred_mv_b (r, block_type, 1);
- rv34_mc_2mv (r, block_type);
- break;
- case RV34_MB_P_8x8:
- for(i=0;i< 4;i++){
- rv34_pred_mv(r, block_type, i, i);
- rv34_mc_1mv (r, block_type, (i&1)<<3, (i&2)<<2, (i&1)+(i>>1)*s->b8_stride, 1, 1, 0);
- }
- break;
- }
-
- return 0;
-}
-/** @} */ // mv group
-
-/**
- * @name Macroblock reconstruction functions
- * @{
- */
-/** mapping of RV30/40 intra prediction types to standard H.264 types */
-static const int ittrans[9] = {
- DC_PRED, VERT_PRED, HOR_PRED, DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_LEFT_PRED,
- VERT_RIGHT_PRED, VERT_LEFT_PRED, HOR_UP_PRED, HOR_DOWN_PRED,
-};
-
-/** mapping of RV30/40 intra 16x16 prediction types to standard H.264 types */
-static const int ittrans16[4] = {
- DC_PRED8x8, VERT_PRED8x8, HOR_PRED8x8, PLANE_PRED8x8,
-};
-
-/**
- * Perform 4x4 intra prediction.
- */
-static void rv34_pred_4x4_block(RV34DecContext *r, uint8_t *dst, int stride, int itype, int up, int left, int down, int right)
-{
- uint8_t *prev = dst - stride + 4;
- uint32_t topleft;
-
- if(!up && !left)
- itype = DC_128_PRED;
- else if(!up){
- if(itype == VERT_PRED) itype = HOR_PRED;
- if(itype == DC_PRED) itype = LEFT_DC_PRED;
- }else if(!left){
- if(itype == HOR_PRED) itype = VERT_PRED;
- if(itype == DC_PRED) itype = TOP_DC_PRED;
- if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN;
- }
- if(!down){
- if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN;
- if(itype == HOR_UP_PRED) itype = HOR_UP_PRED_RV40_NODOWN;
- if(itype == VERT_LEFT_PRED) itype = VERT_LEFT_PRED_RV40_NODOWN;
- }
- if(!right && up){
- topleft = dst[-stride + 3] * 0x01010101u;
- prev = (uint8_t*)&topleft;
- }
- r->h.pred4x4[itype](dst, prev, stride);
-}
-
-static inline int adjust_pred16(int itype, int up, int left)
-{
- if(!up && !left)
- itype = DC_128_PRED8x8;
- else if(!up){
- if(itype == PLANE_PRED8x8)itype = HOR_PRED8x8;
- if(itype == VERT_PRED8x8) itype = HOR_PRED8x8;
- if(itype == DC_PRED8x8) itype = LEFT_DC_PRED8x8;
- }else if(!left){
- if(itype == PLANE_PRED8x8)itype = VERT_PRED8x8;
- if(itype == HOR_PRED8x8) itype = VERT_PRED8x8;
- if(itype == DC_PRED8x8) itype = TOP_DC_PRED8x8;
- }
- return itype;
-}
-
-static inline void rv34_process_block(RV34DecContext *r,
- uint8_t *pdst, int stride,
- int fc, int sc, int q_dc, int q_ac)
-{
- MpegEncContext *s = &r->s;
- int16_t *ptr = s->block[0];
- int has_ac = rv34_decode_block(ptr, &s->gb, r->cur_vlcs,
- fc, sc, q_dc, q_ac, q_ac);
- if(has_ac){
- r->rdsp.rv34_idct_add(pdst, stride, ptr);
- }else{
- r->rdsp.rv34_idct_dc_add(pdst, stride, ptr[0]);
- ptr[0] = 0;
- }
-}
-
-static void rv34_output_i16x16(RV34DecContext *r, int8_t *intra_types, int cbp)
-{
- LOCAL_ALIGNED_16(int16_t, block16, [16]);
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int q_dc = rv34_qscale_tab[ r->luma_dc_quant_i[s->qscale] ],
- q_ac = rv34_qscale_tab[s->qscale];
- uint8_t *dst = s->dest[0];
- int16_t *ptr = s->block[0];
- int i, j, itype, has_ac;
-
- memset(block16, 0, 16 * sizeof(*block16));
-
- has_ac = rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0, q_dc, q_dc, q_ac);
- if(has_ac)
- r->rdsp.rv34_inv_transform(block16);
- else
- r->rdsp.rv34_inv_transform_dc(block16);
-
- itype = ittrans16[intra_types[0]];
- itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
- r->h.pred16x16[itype](dst, s->linesize);
-
- for(j = 0; j < 4; j++){
- for(i = 0; i < 4; i++, cbp >>= 1){
- int dc = block16[i + j*4];
-
- if(cbp & 1){
- has_ac = rv34_decode_block(ptr, gb, r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac);
- }else
- has_ac = 0;
-
- if(has_ac){
- ptr[0] = dc;
- r->rdsp.rv34_idct_add(dst+4*i, s->linesize, ptr);
- }else
- r->rdsp.rv34_idct_dc_add(dst+4*i, s->linesize, dc);
- }
-
- dst += 4*s->linesize;
- }
-
- itype = ittrans16[intra_types[0]];
- if(itype == PLANE_PRED8x8) itype = DC_PRED8x8;
- itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
-
- q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
- q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];
-
- for(j = 1; j < 3; j++){
- dst = s->dest[j];
- r->h.pred8x8[itype](dst, s->uvlinesize);
- for(i = 0; i < 4; i++, cbp >>= 1){
- uint8_t *pdst;
- if(!(cbp & 1)) continue;
- pdst = dst + (i&1)*4 + (i&2)*2*s->uvlinesize;
-
- rv34_process_block(r, pdst, s->uvlinesize,
- r->chroma_vlc, 1, q_dc, q_ac);
- }
- }
-}
-
-static void rv34_output_intra(RV34DecContext *r, int8_t *intra_types, int cbp)
-{
- MpegEncContext *s = &r->s;
- uint8_t *dst = s->dest[0];
- int avail[6*8] = {0};
- int i, j, k;
- int idx, q_ac, q_dc;
-
- // Set neighbour information.
- if(r->avail_cache[1])
- avail[0] = 1;
- if(r->avail_cache[2])
- avail[1] = avail[2] = 1;
- if(r->avail_cache[3])
- avail[3] = avail[4] = 1;
- if(r->avail_cache[4])
- avail[5] = 1;
- if(r->avail_cache[5])
- avail[8] = avail[16] = 1;
- if(r->avail_cache[9])
- avail[24] = avail[32] = 1;
-
- q_ac = rv34_qscale_tab[s->qscale];
- for(j = 0; j < 4; j++){
- idx = 9 + j*8;
- for(i = 0; i < 4; i++, cbp >>= 1, dst += 4, idx++){
- rv34_pred_4x4_block(r, dst, s->linesize, ittrans[intra_types[i]], avail[idx-8], avail[idx-1], avail[idx+7], avail[idx-7]);
- avail[idx] = 1;
- if(!(cbp & 1)) continue;
-
- rv34_process_block(r, dst, s->linesize,
- r->luma_vlc, 0, q_ac, q_ac);
- }
- dst += s->linesize * 4 - 4*4;
- intra_types += r->intra_types_stride;
- }
-
- intra_types -= r->intra_types_stride * 4;
-
- q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
- q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];
-
- for(k = 0; k < 2; k++){
- dst = s->dest[1+k];
- fill_rectangle(r->avail_cache + 6, 2, 2, 4, 0, 4);
-
- for(j = 0; j < 2; j++){
- int* acache = r->avail_cache + 6 + j*4;
- for(i = 0; i < 2; i++, cbp >>= 1, acache++){
- int itype = ittrans[intra_types[i*2+j*2*r->intra_types_stride]];
- rv34_pred_4x4_block(r, dst+4*i, s->uvlinesize, itype, acache[-4], acache[-1], !i && !j, acache[-3]);
- acache[0] = 1;
-
- if(!(cbp&1)) continue;
-
- rv34_process_block(r, dst + 4*i, s->uvlinesize,
- r->chroma_vlc, 1, q_dc, q_ac);
- }
-
- dst += 4*s->uvlinesize;
- }
- }
-}
-
-static int is_mv_diff_gt_3(int16_t (*motion_val)[2], int step)
-{
- int d;
- d = motion_val[0][0] - motion_val[-step][0];
- if(d < -3 || d > 3)
- return 1;
- d = motion_val[0][1] - motion_val[-step][1];
- if(d < -3 || d > 3)
- return 1;
- return 0;
-}
-
-static int rv34_set_deblock_coef(RV34DecContext *r)
-{
- MpegEncContext *s = &r->s;
- int hmvmask = 0, vmvmask = 0, i, j;
- int midx = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
- int16_t (*motion_val)[2] = &s->current_picture_ptr->motion_val[0][midx];
- for(j = 0; j < 16; j += 8){
- for(i = 0; i < 2; i++){
- if(is_mv_diff_gt_3(motion_val + i, 1))
- vmvmask |= 0x11 << (j + i*2);
- if((j || s->mb_y) && is_mv_diff_gt_3(motion_val + i, s->b8_stride))
- hmvmask |= 0x03 << (j + i*2);
- }
- motion_val += s->b8_stride;
- }
- if(s->first_slice_line)
- hmvmask &= ~0x000F;
- if(!s->mb_x)
- vmvmask &= ~0x1111;
- if(r->rv30){ //RV30 marks both subblocks on the edge for filtering
- vmvmask |= (vmvmask & 0x4444) >> 1;
- hmvmask |= (hmvmask & 0x0F00) >> 4;
- if(s->mb_x)
- r->deblock_coefs[s->mb_x - 1 + s->mb_y*s->mb_stride] |= (vmvmask & 0x1111) << 3;
- if(!s->first_slice_line)
- r->deblock_coefs[s->mb_x + (s->mb_y - 1)*s->mb_stride] |= (hmvmask & 0xF) << 12;
- }
- return hmvmask | vmvmask;
-}
-
-static int rv34_decode_inter_macroblock(RV34DecContext *r, int8_t *intra_types)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- uint8_t *dst = s->dest[0];
- int16_t *ptr = s->block[0];
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
- int cbp, cbp2;
- int q_dc, q_ac, has_ac;
- int i, j;
- int dist;
-
- // Calculate which neighbours are available. Maybe it's worth optimizing too.
- memset(r->avail_cache, 0, sizeof(r->avail_cache));
- fill_rectangle(r->avail_cache + 6, 2, 2, 4, 1, 4);
- dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
- if(s->mb_x && dist)
- r->avail_cache[5] =
- r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1];
- if(dist >= s->mb_width)
- r->avail_cache[2] =
- r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride];
- if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
- r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1];
- if(s->mb_x && dist > s->mb_width)
- r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1];
-
- s->qscale = r->si.quant;
- cbp = cbp2 = rv34_decode_inter_mb_header(r, intra_types);
- r->cbp_luma [mb_pos] = cbp;
- r->cbp_chroma[mb_pos] = cbp >> 16;
- r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r) | r->cbp_luma[mb_pos];
- s->current_picture_ptr->qscale_table[mb_pos] = s->qscale;
-
- if(cbp == -1)
- return -1;
-
- if (IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
- if(r->is16) rv34_output_i16x16(r, intra_types, cbp);
- else rv34_output_intra(r, intra_types, cbp);
- return 0;
- }
-
- if(r->is16){
- // Only for RV34_MB_P_MIX16x16
- LOCAL_ALIGNED_16(int16_t, block16, [16]);
- memset(block16, 0, 16 * sizeof(*block16));
- q_dc = rv34_qscale_tab[ r->luma_dc_quant_p[s->qscale] ];
- q_ac = rv34_qscale_tab[s->qscale];
- if (rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0, q_dc, q_dc, q_ac))
- r->rdsp.rv34_inv_transform(block16);
- else
- r->rdsp.rv34_inv_transform_dc(block16);
-
- q_ac = rv34_qscale_tab[s->qscale];
-
- for(j = 0; j < 4; j++){
- for(i = 0; i < 4; i++, cbp >>= 1){
- int dc = block16[i + j*4];
-
- if(cbp & 1){
- has_ac = rv34_decode_block(ptr, gb, r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac);
- }else
- has_ac = 0;
-
- if(has_ac){
- ptr[0] = dc;
- r->rdsp.rv34_idct_add(dst+4*i, s->linesize, ptr);
- }else
- r->rdsp.rv34_idct_dc_add(dst+4*i, s->linesize, dc);
- }
-
- dst += 4*s->linesize;
- }
-
- r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
- }else{
- q_ac = rv34_qscale_tab[s->qscale];
-
- for(j = 0; j < 4; j++){
- for(i = 0; i < 4; i++, cbp >>= 1){
- if(!(cbp & 1)) continue;
-
- rv34_process_block(r, dst + 4*i, s->linesize,
- r->luma_vlc, 0, q_ac, q_ac);
- }
- dst += 4*s->linesize;
- }
- }
-
- q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
- q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];
-
- for(j = 1; j < 3; j++){
- dst = s->dest[j];
- for(i = 0; i < 4; i++, cbp >>= 1){
- uint8_t *pdst;
- if(!(cbp & 1)) continue;
- pdst = dst + (i&1)*4 + (i&2)*2*s->uvlinesize;
-
- rv34_process_block(r, pdst, s->uvlinesize,
- r->chroma_vlc, 1, q_dc, q_ac);
- }
- }
-
- return 0;
-}
-
-static int rv34_decode_intra_macroblock(RV34DecContext *r, int8_t *intra_types)
-{
- MpegEncContext *s = &r->s;
- int cbp, dist;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
-
- // Calculate which neighbours are available. Maybe it's worth optimizing too.
- memset(r->avail_cache, 0, sizeof(r->avail_cache));
- fill_rectangle(r->avail_cache + 6, 2, 2, 4, 1, 4);
- dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
- if(s->mb_x && dist)
- r->avail_cache[5] =
- r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1];
- if(dist >= s->mb_width)
- r->avail_cache[2] =
- r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride];
- if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
- r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1];
- if(s->mb_x && dist > s->mb_width)
- r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1];
-
- s->qscale = r->si.quant;
- cbp = rv34_decode_intra_mb_header(r, intra_types);
- r->cbp_luma [mb_pos] = cbp;
- r->cbp_chroma[mb_pos] = cbp >> 16;
- r->deblock_coefs[mb_pos] = 0xFFFF;
- s->current_picture_ptr->qscale_table[mb_pos] = s->qscale;
-
- if(cbp == -1)
- return -1;
-
- if(r->is16){
- rv34_output_i16x16(r, intra_types, cbp);
- return 0;
- }
-
- rv34_output_intra(r, intra_types, cbp);
- return 0;
-}
-
-static int check_slice_end(RV34DecContext *r, MpegEncContext *s)
-{
- int bits;
- if(s->mb_y >= s->mb_height)
- return 1;
- if(!s->mb_num_left)
- return 1;
- if(r->s.mb_skip_run > 1)
- return 0;
- bits = get_bits_left(&s->gb);
- if(bits <= 0 || (bits < 8 && !show_bits(&s->gb, bits)))
- return 1;
- return 0;
-}
-
-
-static void rv34_decoder_free(RV34DecContext *r)
-{
- av_freep(&r->intra_types_hist);
- r->intra_types = NULL;
- av_freep(&r->tmp_b_block_base);
- av_freep(&r->mb_type);
- av_freep(&r->cbp_luma);
- av_freep(&r->cbp_chroma);
- av_freep(&r->deblock_coefs);
-}
-
-
-static int rv34_decoder_alloc(RV34DecContext *r)
-{
- r->intra_types_stride = r->s.mb_width * 4 + 4;
-
- r->cbp_chroma = av_mallocz(r->s.mb_stride * r->s.mb_height *
- sizeof(*r->cbp_chroma));
- r->cbp_luma = av_mallocz(r->s.mb_stride * r->s.mb_height *
- sizeof(*r->cbp_luma));
- r->deblock_coefs = av_mallocz(r->s.mb_stride * r->s.mb_height *
- sizeof(*r->deblock_coefs));
- r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 *
- sizeof(*r->intra_types_hist));
- r->mb_type = av_mallocz(r->s.mb_stride * r->s.mb_height *
- sizeof(*r->mb_type));
-
- if (!(r->cbp_chroma && r->cbp_luma && r->deblock_coefs &&
- r->intra_types_hist && r->mb_type)) {
- rv34_decoder_free(r);
- return AVERROR(ENOMEM);
- }
-
- r->intra_types = r->intra_types_hist + r->intra_types_stride * 4;
-
- return 0;
-}
-
-
-static int rv34_decoder_realloc(RV34DecContext *r)
-{
- rv34_decoder_free(r);
- return rv34_decoder_alloc(r);
-}
-
-
-static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int buf_size)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int mb_pos, slice_type;
- int res;
-
- init_get_bits(&r->s.gb, buf, buf_size*8);
- res = r->parse_slice_header(r, gb, &r->si);
- if(res < 0){
- av_log(s->avctx, AV_LOG_ERROR, "Incorrect or unknown slice header\n");
- return -1;
- }
-
- slice_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I;
- if (slice_type != s->pict_type) {
- av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
- return AVERROR_INVALIDDATA;
- }
- if (s->width != r->si.width || s->height != r->si.height) {
- av_log(s->avctx, AV_LOG_ERROR, "Size mismatch\n");
- return AVERROR_INVALIDDATA;
- }
-
- r->si.end = end;
- s->qscale = r->si.quant;
- s->mb_num_left = r->si.end - r->si.start;
- r->s.mb_skip_run = 0;
-
- mb_pos = s->mb_x + s->mb_y * s->mb_width;
- if(r->si.start != mb_pos){
- av_log(s->avctx, AV_LOG_ERROR, "Slice indicates MB offset %d, got %d\n", r->si.start, mb_pos);
- s->mb_x = r->si.start % s->mb_width;
- s->mb_y = r->si.start / s->mb_width;
- }
- memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
- s->first_slice_line = 1;
- s->resync_mb_x = s->mb_x;
- s->resync_mb_y = s->mb_y;
-
- ff_init_block_index(s);
- while(!check_slice_end(r, s)) {
- ff_update_block_index(s);
-
- if(r->si.type)
- res = rv34_decode_inter_macroblock(r, r->intra_types + s->mb_x * 4 + 4);
- else
- res = rv34_decode_intra_macroblock(r, r->intra_types + s->mb_x * 4 + 4);
- if(res < 0){
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_ERROR);
- return -1;
- }
- if (++s->mb_x == s->mb_width) {
- s->mb_x = 0;
- s->mb_y++;
- ff_init_block_index(s);
-
- memmove(r->intra_types_hist, r->intra_types, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist));
- memset(r->intra_types, -1, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist));
-
- if(r->loop_filter && s->mb_y >= 2)
- r->loop_filter(r, s->mb_y - 2);
-
- if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
- ff_thread_report_progress(&s->current_picture_ptr->tf,
- s->mb_y - 2, 0);
-
- }
- if(s->mb_x == s->resync_mb_x)
- s->first_slice_line=0;
- s->mb_num_left--;
- }
- ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
-
- return s->mb_y == s->mb_height;
-}
-
-/** @} */ // recons group end
-
-/**
- * Initialize decoder.
- */
-av_cold int ff_rv34_decode_init(AVCodecContext *avctx)
-{
- 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;
-
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- avctx->has_b_frames = 1;
- s->low_delay = 0;
-
- ff_mpv_idct_init(s);
- if ((ret = ff_mpv_common_init(s)) < 0)
- return ret;
-
- ff_h264_pred_init(&r->h, AV_CODEC_ID_RV40, 8, 1);
-
-#if CONFIG_RV30_DECODER
- if (avctx->codec_id == AV_CODEC_ID_RV30)
- ff_rv30dsp_init(&r->rdsp);
-#endif
-#if CONFIG_RV40_DECODER
- if (avctx->codec_id == AV_CODEC_ID_RV40)
- ff_rv40dsp_init(&r->rdsp);
-#endif
-
- if ((ret = rv34_decoder_alloc(r)) < 0) {
- ff_mpv_common_end(&r->s);
- return ret;
- }
-
- if(!intra_vlcs[0].cbppattern[0].bits)
- rv34_init_tables();
-
- avctx->internal->allocate_progress = 1;
-
- return 0;
-}
-
-int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx)
-{
- int err;
- RV34DecContext *r = avctx->priv_data;
-
- r->s.avctx = avctx;
-
- if (avctx->internal->is_copy) {
- r->tmp_b_block_base = NULL;
- r->cbp_chroma = NULL;
- r->cbp_luma = NULL;
- r->deblock_coefs = NULL;
- r->intra_types_hist = NULL;
- r->mb_type = NULL;
-
- ff_mpv_idct_init(&r->s);
-
- if ((err = ff_mpv_common_init(&r->s)) < 0)
- return err;
- if ((err = rv34_decoder_alloc(r)) < 0) {
- ff_mpv_common_end(&r->s);
- return err;
- }
- }
-
- return 0;
-}
-
-int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
-{
- RV34DecContext *r = dst->priv_data, *r1 = src->priv_data;
- MpegEncContext * const s = &r->s, * const s1 = &r1->s;
- int err;
-
- if (dst == src || !s1->context_initialized)
- return 0;
-
- if (s->height != s1->height || s->width != s1->width) {
- s->height = s1->height;
- s->width = s1->width;
- if ((err = ff_mpv_common_frame_size_change(s)) < 0)
- return err;
- if ((err = rv34_decoder_realloc(r)) < 0)
- return err;
- }
-
- r->cur_pts = r1->cur_pts;
- r->last_pts = r1->last_pts;
- r->next_pts = r1->next_pts;
-
- memset(&r->si, 0, sizeof(r->si));
-
- // Do no call ff_mpeg_update_thread_context on a partially initialized
- // decoder context.
- if (!s1->linesize)
- return 0;
-
- return ff_mpeg_update_thread_context(dst, src);
-}
-
-static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n)
-{
- if(avctx->slice_count) return avctx->slice_offset[n];
- else return AV_RL32(buf + n*8 - 4) == 1 ? AV_RL32(buf + n*8) : AV_RB32(buf + n*8);
-}
-
-static int finish_frame(AVCodecContext *avctx, AVFrame *pict)
-{
- RV34DecContext *r = avctx->priv_data;
- MpegEncContext *s = &r->s;
- int got_picture = 0, ret;
-
- ff_er_frame_end(&s->er);
- ff_mpv_frame_end(s);
- s->mb_num_left = 0;
-
- if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
- ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);
-
- if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
- if ((ret = av_frame_ref(pict, s->current_picture_ptr->f)) < 0)
- return ret;
- ff_print_debug_info(s, s->current_picture_ptr, pict);
- ff_mpv_export_qp_table(s, pict, s->current_picture_ptr, FF_QSCALE_TYPE_MPEG1);
- got_picture = 1;
- } else if (s->last_picture_ptr) {
- if ((ret = av_frame_ref(pict, s->last_picture_ptr->f)) < 0)
- return ret;
- ff_print_debug_info(s, s->last_picture_ptr, pict);
- ff_mpv_export_qp_table(s, pict, s->last_picture_ptr, FF_QSCALE_TYPE_MPEG1);
- got_picture = 1;
- }
-
- return got_picture;
-}
-
-static AVRational update_sar(int old_w, int old_h, AVRational sar, int new_w, int new_h)
-{
- // attempt to keep aspect during typical resolution switches
- if (!sar.num)
- sar = (AVRational){1, 1};
-
- sar = av_mul_q(sar, (AVRational){new_h * old_w, new_w * old_h});
- return sar;
-}
-
-int ff_rv34_decode_frame(AVCodecContext *avctx,
- void *data, int *got_picture_ptr,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- RV34DecContext *r = avctx->priv_data;
- MpegEncContext *s = &r->s;
- AVFrame *pict = data;
- SliceInfo si;
- int i, ret;
- int slice_count;
- const uint8_t *slices_hdr = NULL;
- int last = 0;
-
- /* no supplementary picture */
- if (buf_size == 0) {
- /* special case for last picture */
- if (s->low_delay==0 && s->next_picture_ptr) {
- if ((ret = av_frame_ref(pict, s->next_picture_ptr->f)) < 0)
- return ret;
- s->next_picture_ptr = NULL;
-
- *got_picture_ptr = 1;
- }
- return 0;
- }
-
- if(!avctx->slice_count){
- slice_count = (*buf++) + 1;
- slices_hdr = buf + 4;
- buf += 8 * slice_count;
- buf_size -= 1 + 8 * slice_count;
- }else
- slice_count = avctx->slice_count;
-
- //parse first slice header to check whether this frame can be decoded
- if(get_slice_offset(avctx, slices_hdr, 0) < 0 ||
- get_slice_offset(avctx, slices_hdr, 0) > buf_size){
- av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
- return AVERROR_INVALIDDATA;
- }
- init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, 0), (buf_size-get_slice_offset(avctx, slices_hdr, 0))*8);
- if(r->parse_slice_header(r, &r->s.gb, &si) < 0 || si.start){
- av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n");
- return AVERROR_INVALIDDATA;
- }
- if ((!s->last_picture_ptr || !s->last_picture_ptr->f->data[0]) &&
- si.type == AV_PICTURE_TYPE_B) {
- av_log(avctx, AV_LOG_ERROR, "Invalid decoder state: B-frame without "
- "reference data.\n");
- return AVERROR_INVALIDDATA;
- }
- if( (avctx->skip_frame >= AVDISCARD_NONREF && si.type==AV_PICTURE_TYPE_B)
- || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=AV_PICTURE_TYPE_I)
- || avctx->skip_frame >= AVDISCARD_ALL)
- return avpkt->size;
-
- /* first slice */
- if (si.start == 0) {
- 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);
- ff_mpv_frame_end(s);
- }
-
- if (s->width != si.width || s->height != si.height) {
- int err;
-
- av_log(s->avctx, AV_LOG_WARNING, "Changing dimensions to %dx%d\n",
- si.width, si.height);
-
- if (av_image_check_size(si.width, si.height, 0, s->avctx))
- return AVERROR_INVALIDDATA;
-
- s->avctx->sample_aspect_ratio = update_sar(
- s->width, s->height, s->avctx->sample_aspect_ratio,
- si.width, si.height);
- s->width = si.width;
- s->height = si.height;
-
- err = ff_set_dimensions(s->avctx, s->width, s->height);
- if (err < 0)
- return err;
-
- if ((err = ff_mpv_common_frame_size_change(s)) < 0)
- return err;
- if ((err = rv34_decoder_realloc(r)) < 0)
- return err;
- }
- s->pict_type = si.type ? si.type : AV_PICTURE_TYPE_I;
- if (ff_mpv_frame_start(s, s->avctx) < 0)
- return -1;
- ff_mpeg_er_frame_start(s);
- if (!r->tmp_b_block_base) {
- int i;
-
- r->tmp_b_block_base = av_malloc(s->linesize * 48);
- for (i = 0; i < 2; i++)
- r->tmp_b_block_y[i] = r->tmp_b_block_base
- + i * 16 * s->linesize;
- for (i = 0; i < 4; i++)
- r->tmp_b_block_uv[i] = r->tmp_b_block_base + 32 * s->linesize
- + (i >> 1) * 8 * s->uvlinesize
- + (i & 1) * 16;
- }
- r->cur_pts = si.pts;
- if (s->pict_type != AV_PICTURE_TYPE_B) {
- r->last_pts = r->next_pts;
- r->next_pts = r->cur_pts;
- } else {
- int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts);
- int dist0 = GET_PTS_DIFF(r->cur_pts, r->last_pts);
- int dist1 = GET_PTS_DIFF(r->next_pts, r->cur_pts);
-
- if(!refdist){
- r->mv_weight1 = r->mv_weight2 = r->weight1 = r->weight2 = 8192;
- r->scaled_weight = 0;
- }else{
- r->mv_weight1 = (dist0 << 14) / refdist;
- r->mv_weight2 = (dist1 << 14) / refdist;
- if((r->mv_weight1|r->mv_weight2) & 511){
- r->weight1 = r->mv_weight1;
- r->weight2 = r->mv_weight2;
- r->scaled_weight = 0;
- }else{
- r->weight1 = r->mv_weight1 >> 9;
- r->weight2 = r->mv_weight2 >> 9;
- r->scaled_weight = 1;
- }
- }
- }
- s->mb_x = s->mb_y = 0;
- ff_thread_finish_setup(s->avctx);
- } 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 "
- "multithreading mode (start MB is %d).\n", si.start);
- return AVERROR_INVALIDDATA;
- }
-
- for(i = 0; i < slice_count; i++){
- int offset = get_slice_offset(avctx, slices_hdr, i);
- int size;
- if(i+1 == slice_count)
- size = buf_size - offset;
- else
- size = get_slice_offset(avctx, slices_hdr, i+1) - offset;
-
- if(offset < 0 || offset > buf_size){
- av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
- break;
- }
-
- r->si.end = s->mb_width * s->mb_height;
- s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start;
-
- if(i+1 < slice_count){
- if (get_slice_offset(avctx, slices_hdr, i+1) < 0 ||
- get_slice_offset(avctx, slices_hdr, i+1) > buf_size) {
- av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
- break;
- }
- init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, i+1), (buf_size-get_slice_offset(avctx, slices_hdr, i+1))*8);
- if(r->parse_slice_header(r, &r->s.gb, &si) < 0){
- if(i+2 < slice_count)
- size = get_slice_offset(avctx, slices_hdr, i+2) - offset;
- else
- size = buf_size - offset;
- }else
- r->si.end = si.start;
- }
- if (size < 0 || size > buf_size - offset) {
- av_log(avctx, AV_LOG_ERROR, "Slice size is invalid\n");
- break;
- }
- last = rv34_decode_slice(r, r->si.end, buf + offset, size);
- if(last)
- break;
- }
-
- if (s->current_picture_ptr) {
- if (last) {
- if(r->loop_filter)
- r->loop_filter(r, s->mb_height - 1);
-
- ret = finish_frame(avctx, pict);
- if (ret < 0)
- return ret;
- *got_picture_ptr = ret;
- } else if (HAVE_THREADS &&
- (s->avctx->active_thread_type & FF_THREAD_FRAME)) {
- av_log(avctx, AV_LOG_INFO, "marking unfished frame as finished\n");
- /* always mark the current frame as finished, frame-mt supports
- * only complete frames */
- ff_er_frame_end(&s->er);
- ff_mpv_frame_end(s);
- s->mb_num_left = 0;
- ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);
- return AVERROR_INVALIDDATA;
- }
- }
-
- return avpkt->size;
-}
-
-av_cold int ff_rv34_decode_end(AVCodecContext *avctx)
-{
- RV34DecContext *r = avctx->priv_data;
-
- ff_mpv_common_end(&r->s);
- rv34_decoder_free(r);
-
- return 0;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/rv40.c b/ffmpeg-2-8-11/libavcodec/rv40.c
deleted file mode 100644
index c52e06d..0000000
--- a/ffmpeg-2-8-11/libavcodec/rv40.c
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- * RV40 decoder
- * Copyright (c) 2007 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
- */
-
-/**
- * @file
- * RV40 decoder
- */
-
-#include "libavutil/imgutils.h"
-
-#include "avcodec.h"
-#include "mpegutils.h"
-#include "mpegvideo.h"
-#include "golomb.h"
-
-#include "rv34.h"
-#include "rv40vlc2.h"
-#include "rv40data.h"
-
-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
-};
-
-/**
- * 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];
- 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);
- 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);
- }
- 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(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);
- }
- 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);
- }
-}
-
-/**
- * Get stored dimension from bitstream.
- *
- * If the width/height is the standard one then it's coded as a 3-bit index.
- * Otherwise it is coded as escaped 8-bit portions.
- */
-static int get_dimension(GetBitContext *gb, const int *dim)
-{
- int t = get_bits(gb, 3);
- int val = dim[t];
- if(val < 0)
- val = dim[get_bits1(gb) - val];
- if(!val){
- do{
- if (get_bits_left(gb) < 8)
- return AVERROR_INVALIDDATA;
- t = get_bits(gb, 8);
- val += t << 2;
- }while(t == 0xFF);
- }
- return val;
-}
-
-/**
- * Get encoded picture size - usually this is called from rv40_parse_slice_header.
- */
-static void rv40_parse_picture_size(GetBitContext *gb, int *w, int *h)
-{
- *w = get_dimension(gb, rv40_standard_widths);
- *h = get_dimension(gb, rv40_standard_heights);
-}
-
-static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si)
-{
- int mb_bits;
- int w = r->s.width, h = r->s.height;
- int mb_size;
- int ret;
-
- memset(si, 0, sizeof(SliceInfo));
- if(get_bits1(gb))
- return AVERROR_INVALIDDATA;
- si->type = get_bits(gb, 2);
- if(si->type == 1) si->type = 0;
- si->quant = get_bits(gb, 5);
- if(get_bits(gb, 2))
- return AVERROR_INVALIDDATA;
- si->vlc_set = get_bits(gb, 2);
- skip_bits1(gb);
- si->pts = get_bits(gb, 13);
- if(!si->type || !get_bits1(gb))
- rv40_parse_picture_size(gb, &w, &h);
- if ((ret = av_image_check_size(w, h, 0, r->s.avctx)) < 0)
- return ret;
- si->width = w;
- si->height = h;
- mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
- mb_bits = ff_rv34_get_start_offset(gb, mb_size);
- si->start = get_bits(gb, mb_bits);
-
- return 0;
-}
-
-/**
- * Decode 4x4 intra types array.
- */
-static int rv40_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t *dst)
-{
- MpegEncContext *s = &r->s;
- int i, j, k, v;
- int A, B, C;
- int pattern;
- int8_t *ptr;
-
- for(i = 0; i < 4; i++, dst += r->intra_types_stride){
- if(!i && s->first_slice_line){
- pattern = get_vlc2(gb, aic_top_vlc.table, AIC_TOP_BITS, 1);
- dst[0] = (pattern >> 2) & 2;
- dst[1] = (pattern >> 1) & 2;
- dst[2] = pattern & 2;
- dst[3] = (pattern << 1) & 2;
- continue;
- }
- ptr = dst;
- for(j = 0; j < 4; j++){
- /* Coefficients are read using VLC chosen by the prediction pattern
- * The first one (used for retrieving a pair of coefficients) is
- * constructed from the top, top right and left coefficients
- * The second one (used for retrieving only one coefficient) is
- * top + 10 * left.
- */
- A = ptr[-r->intra_types_stride + 1]; // it won't be used for the last coefficient in a row
- B = ptr[-r->intra_types_stride];
- C = ptr[-1];
- pattern = A + (B << 4) + (C << 8);
- for(k = 0; k < MODE2_PATTERNS_NUM; k++)
- 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;
- j++;
- }else{
- if(B != -1 && C != -1)
- v = get_vlc2(gb, aic_mode1_vlc[B + C*10].table, AIC_MODE1_BITS, 1);
- else{ // tricky decoding
- v = 0;
- switch(C){
- case -1: // code 0 -> 1, 1 -> 0
- if(B < 2)
- v = get_bits1(gb) ^ 1;
- break;
- case 0:
- case 2: // code 0 -> 2, 1 -> 0
- v = (get_bits1(gb) ^ 1) << 1;
- break;
- }
- }
- *ptr++ = v;
- }
- }
- }
- return 0;
-}
-
-/**
- * Decode macroblock information.
- */
-static int rv40_decode_mb_info(RV34DecContext *r)
-{
- MpegEncContext *s = &r->s;
- GetBitContext *gb = &s->gb;
- int q, i;
- int prev_type = 0;
- int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
-
- if(!r->s.mb_skip_run) {
- r->s.mb_skip_run = svq3_get_ue_golomb(gb) + 1;
- if(r->s.mb_skip_run > (unsigned)s->mb_num)
- return -1;
- }
-
- if(--r->s.mb_skip_run)
- return RV34_MB_SKIP;
-
- if(r->avail_cache[6-4]){
- int blocks[RV34_MB_TYPES] = {0};
- int count = 0;
- if(r->avail_cache[6-1])
- blocks[r->mb_type[mb_pos - 1]]++;
- blocks[r->mb_type[mb_pos - s->mb_stride]]++;
- if(r->avail_cache[6-2])
- blocks[r->mb_type[mb_pos - s->mb_stride + 1]]++;
- if(r->avail_cache[6-5])
- blocks[r->mb_type[mb_pos - s->mb_stride - 1]]++;
- for(i = 0; i < RV34_MB_TYPES; i++){
- if(blocks[i] > count){
- count = blocks[i];
- prev_type = i;
- if(count>1)
- break;
- }
- }
- } else if (r->avail_cache[6-1])
- prev_type = r->mb_type[mb_pos - 1];
-
- if(s->pict_type == AV_PICTURE_TYPE_P){
- prev_type = block_num_to_ptype_vlc_num[prev_type];
- q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1);
- if(q < PBTYPE_ESCAPE)
- return q;
- q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1);
- av_log(s->avctx, AV_LOG_ERROR, "Dquant for P-frame\n");
- }else{
- prev_type = block_num_to_btype_vlc_num[prev_type];
- q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1);
- if(q < PBTYPE_ESCAPE)
- return q;
- q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1);
- av_log(s->avctx, AV_LOG_ERROR, "Dquant for B-frame\n");
- }
- return 0;
-}
-
-enum RV40BlockPos{
- POS_CUR,
- POS_TOP,
- POS_LEFT,
- POS_BOTTOM,
-};
-
-#define MASK_CUR 0x0001
-#define MASK_RIGHT 0x0008
-#define MASK_BOTTOM 0x0010
-#define MASK_TOP 0x1000
-#define MASK_Y_TOP_ROW 0x000F
-#define MASK_Y_LAST_ROW 0xF000
-#define MASK_Y_LEFT_COL 0x1111
-#define MASK_Y_RIGHT_COL 0x8888
-#define MASK_C_TOP_ROW 0x0003
-#define MASK_C_LAST_ROW 0x000C
-#define MASK_C_LEFT_COL 0x0005
-#define MASK_C_RIGHT_COL 0x000A
-
-static const int neighbour_offs_x[4] = { 0, 0, -1, 0 };
-static const int neighbour_offs_y[4] = { 0, -1, 0, 1 };
-
-static void rv40_adaptive_loop_filter(RV34DSPContext *rdsp,
- uint8_t *src, int stride, int dmode,
- int lim_q1, int lim_p1,
- int alpha, int beta, int beta2,
- int chroma, int edge, int dir)
-{
- int filter_p1, filter_q1;
- int strong;
- int lims;
-
- strong = rdsp->rv40_loop_filter_strength[dir](src, stride, beta, beta2,
- edge, &filter_p1, &filter_q1);
-
- lims = filter_p1 + filter_q1 + ((lim_q1 + lim_p1) >> 1) + 1;
-
- if (strong) {
- rdsp->rv40_strong_loop_filter[dir](src, stride, alpha,
- lims, dmode, chroma);
- } else if (filter_p1 & filter_q1) {
- rdsp->rv40_weak_loop_filter[dir](src, stride, 1, 1, alpha, beta,
- lims, lim_q1, lim_p1);
- } else if (filter_p1 | filter_q1) {
- rdsp->rv40_weak_loop_filter[dir](src, stride, filter_p1, filter_q1,
- alpha, beta, lims >> 1, lim_q1 >> 1,
- lim_p1 >> 1);
- }
-}
-
-/**
- * RV40 loop filtering function
- */
-static void rv40_loop_filter(RV34DecContext *r, int row)
-{
- MpegEncContext *s = &r->s;
- int mb_pos, mb_x;
- int i, j, k;
- uint8_t *Y, *C;
- int alpha, beta, betaY, betaC;
- int q;
- int mbtype[4]; ///< current macroblock and its neighbours types
- /**
- * flags indicating that macroblock can be filtered with strong filter
- * it is set only for intra coded MB and MB with DCs coded separately
- */
- int mb_strong[4];
- int clip[4]; ///< MB filter clipping value calculated from filtering strength
- /**
- * coded block patterns for luma part of current macroblock and its neighbours
- * Format:
- * LSB corresponds to the top left block,
- * each nibble represents one row of subblocks.
- */
- int cbp[4];
- /**
- * coded block patterns for chroma part of current macroblock and its neighbours
- * Format is the same as for luma with two subblocks in a row.
- */
- int uvcbp[4][2];
- /**
- * This mask represents the pattern of luma subblocks that should be filtered
- * in addition to the coded ones because they lie at the edge of
- * 8x8 block with different enough motion vectors
- */
- unsigned mvmasks[4];
-
- mb_pos = row * s->mb_stride;
- for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
- int mbtype = s->current_picture_ptr->mb_type[mb_pos];
- if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype))
- r->cbp_luma [mb_pos] = r->deblock_coefs[mb_pos] = 0xFFFF;
- if(IS_INTRA(mbtype))
- r->cbp_chroma[mb_pos] = 0xFF;
- }
- mb_pos = row * s->mb_stride;
- for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
- int y_h_deblock, y_v_deblock;
- int c_v_deblock[2], c_h_deblock[2];
- int clip_left;
- int avail[4];
- unsigned y_to_deblock;
- int c_to_deblock[2];
-
- q = s->current_picture_ptr->qscale_table[mb_pos];
- alpha = rv40_alpha_tab[q];
- beta = rv40_beta_tab [q];
- betaY = betaC = beta * 3;
- if(s->width * s->height <= 176*144)
- betaY += beta;
-
- avail[0] = 1;
- avail[1] = row;
- avail[2] = mb_x;
- avail[3] = row < s->mb_height - 1;
- for(i = 0; i < 4; i++){
- if(avail[i]){
- int pos = mb_pos + neighbour_offs_x[i] + neighbour_offs_y[i]*s->mb_stride;
- mvmasks[i] = r->deblock_coefs[pos];
- mbtype [i] = s->current_picture_ptr->mb_type[pos];
- cbp [i] = r->cbp_luma[pos];
- uvcbp[i][0] = r->cbp_chroma[pos] & 0xF;
- uvcbp[i][1] = r->cbp_chroma[pos] >> 4;
- }else{
- mvmasks[i] = 0;
- mbtype [i] = mbtype[0];
- cbp [i] = 0;
- uvcbp[i][0] = uvcbp[i][1] = 0;
- }
- mb_strong[i] = IS_INTRA(mbtype[i]) || IS_SEPARATE_DC(mbtype[i]);
- clip[i] = rv40_filter_clip_tbl[mb_strong[i] + 1][q];
- }
- y_to_deblock = mvmasks[POS_CUR]
- | (mvmasks[POS_BOTTOM] << 16);
- /* This pattern contains bits signalling that horizontal edges of
- * the current block can be filtered.
- * That happens when either of adjacent subblocks is coded or lies on
- * the edge of 8x8 blocks with motion vectors differing by more than
- * 3/4 pel in any component (any edge orientation for some reason).
- */
- y_h_deblock = y_to_deblock
- | ((cbp[POS_CUR] << 4) & ~MASK_Y_TOP_ROW)
- | ((cbp[POS_TOP] & MASK_Y_LAST_ROW) >> 12);
- /* This pattern contains bits signalling that vertical edges of
- * the current block can be filtered.
- * That happens when either of adjacent subblocks is coded or lies on
- * the edge of 8x8 blocks with motion vectors differing by more than
- * 3/4 pel in any component (any edge orientation for some reason).
- */
- y_v_deblock = y_to_deblock
- | ((cbp[POS_CUR] << 1) & ~MASK_Y_LEFT_COL)
- | ((cbp[POS_LEFT] & MASK_Y_RIGHT_COL) >> 3);
- if(!mb_x)
- y_v_deblock &= ~MASK_Y_LEFT_COL;
- if(!row)
- y_h_deblock &= ~MASK_Y_TOP_ROW;
- if(row == s->mb_height - 1 || (mb_strong[POS_CUR] | mb_strong[POS_BOTTOM]))
- y_h_deblock &= ~(MASK_Y_TOP_ROW << 16);
- /* Calculating chroma patterns is similar and easier since there is
- * no motion vector pattern for them.
- */
- for(i = 0; i < 2; i++){
- c_to_deblock[i] = (uvcbp[POS_BOTTOM][i] << 4) | uvcbp[POS_CUR][i];
- c_v_deblock[i] = c_to_deblock[i]
- | ((uvcbp[POS_CUR] [i] << 1) & ~MASK_C_LEFT_COL)
- | ((uvcbp[POS_LEFT][i] & MASK_C_RIGHT_COL) >> 1);
- c_h_deblock[i] = c_to_deblock[i]
- | ((uvcbp[POS_TOP][i] & MASK_C_LAST_ROW) >> 2)
- | (uvcbp[POS_CUR][i] << 2);
- if(!mb_x)
- c_v_deblock[i] &= ~MASK_C_LEFT_COL;
- if(!row)
- c_h_deblock[i] &= ~MASK_C_TOP_ROW;
- if(row == s->mb_height - 1 || (mb_strong[POS_CUR] | mb_strong[POS_BOTTOM]))
- c_h_deblock[i] &= ~(MASK_C_TOP_ROW << 4);
- }
-
- for(j = 0; j < 16; j += 4){
- Y = s->current_picture_ptr->f->data[0] + mb_x*16 + (row*16 + j) * s->linesize;
- for(i = 0; i < 4; i++, Y += 4){
- int ij = i + j;
- int clip_cur = y_to_deblock & (MASK_CUR << ij) ? clip[POS_CUR] : 0;
- int dither = j ? ij : i*4;
-
- // if bottom block is coded then we can filter its top edge
- // (or bottom edge of this block, which is the same)
- if(y_h_deblock & (MASK_BOTTOM << ij)){
- rv40_adaptive_loop_filter(&r->rdsp, Y+4*s->linesize,
- s->linesize, dither,
- y_to_deblock & (MASK_BOTTOM << ij) ? clip[POS_CUR] : 0,
- clip_cur, alpha, beta, betaY,
- 0, 0, 0);
- }
- // filter left block edge in ordinary mode (with low filtering strength)
- if(y_v_deblock & (MASK_CUR << ij) && (i || !(mb_strong[POS_CUR] | mb_strong[POS_LEFT]))){
- if(!i)
- clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0;
- else
- clip_left = y_to_deblock & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0;
- rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither,
- clip_cur,
- clip_left,
- alpha, beta, betaY, 0, 0, 1);
- }
- // filter top edge of the current macroblock when filtering strength is high
- if(!j && y_h_deblock & (MASK_CUR << i) && (mb_strong[POS_CUR] | mb_strong[POS_TOP])){
- rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither,
- clip_cur,
- mvmasks[POS_TOP] & (MASK_TOP << i) ? clip[POS_TOP] : 0,
- alpha, beta, betaY, 0, 1, 0);
- }
- // filter left block edge in edge mode (with high filtering strength)
- if(y_v_deblock & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] | mb_strong[POS_LEFT])){
- clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0;
- rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither,
- clip_cur,
- clip_left,
- alpha, beta, betaY, 0, 1, 1);
- }
- }
- }
- for(k = 0; k < 2; k++){
- for(j = 0; j < 2; j++){
- C = s->current_picture_ptr->f->data[k + 1] + mb_x*8 + (row*8 + j*4) * s->uvlinesize;
- for(i = 0; i < 2; i++, C += 4){
- int ij = i + j*2;
- int clip_cur = c_to_deblock[k] & (MASK_CUR << ij) ? clip[POS_CUR] : 0;
- if(c_h_deblock[k] & (MASK_CUR << (ij+2))){
- int clip_bot = c_to_deblock[k] & (MASK_CUR << (ij+2)) ? clip[POS_CUR] : 0;
- rv40_adaptive_loop_filter(&r->rdsp, C+4*s->uvlinesize, s->uvlinesize, i*8,
- clip_bot,
- clip_cur,
- alpha, beta, betaC, 1, 0, 0);
- }
- if((c_v_deblock[k] & (MASK_CUR << ij)) && (i || !(mb_strong[POS_CUR] | mb_strong[POS_LEFT]))){
- if(!i)
- clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0;
- else
- clip_left = c_to_deblock[k] & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0;
- rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, j*8,
- clip_cur,
- clip_left,
- alpha, beta, betaC, 1, 0, 1);
- }
- if(!j && c_h_deblock[k] & (MASK_CUR << ij) && (mb_strong[POS_CUR] | mb_strong[POS_TOP])){
- int clip_top = uvcbp[POS_TOP][k] & (MASK_CUR << (ij+2)) ? clip[POS_TOP] : 0;
- rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, i*8,
- clip_cur,
- clip_top,
- alpha, beta, betaC, 1, 1, 0);
- }
- if(c_v_deblock[k] & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] | mb_strong[POS_LEFT])){
- clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0;
- rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, j*8,
- clip_cur,
- clip_left,
- alpha, beta, betaC, 1, 1, 1);
- }
- }
- }
- }
- }
-}
-
-/**
- * Initialize decoder.
- */
-static av_cold int rv40_decode_init(AVCodecContext *avctx)
-{
- RV34DecContext *r = avctx->priv_data;
- int ret;
-
- r->rv30 = 0;
- if ((ret = ff_rv34_decode_init(avctx)) < 0)
- return ret;
- if(!aic_top_vlc.bits)
- rv40_init_tables();
- r->parse_slice_header = rv40_parse_slice_header;
- r->decode_intra_types = rv40_decode_intra_types;
- r->decode_mb_info = rv40_decode_mb_info;
- r->loop_filter = rv40_loop_filter;
- r->luma_dc_quant_i = rv40_luma_dc_quant[0];
- r->luma_dc_quant_p = rv40_luma_dc_quant[1];
- return 0;
-}
-
-AVCodec ff_rv40_decoder = {
- .name = "rv40",
- .long_name = NULL_IF_CONFIG_SMALL("RealVideo 4.0"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_RV40,
- .priv_data_size = sizeof(RV34DecContext),
- .init = rv40_decode_init,
- .close = ff_rv34_decode_end,
- .decode = ff_rv34_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
- AV_CODEC_CAP_FRAME_THREADS,
- .flush = ff_mpeg_flush,
- .pix_fmts = (const enum AVPixelFormat[]) {
- AV_PIX_FMT_YUV420P,
- AV_PIX_FMT_NONE
- },
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_init_thread_copy),
- .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context),
-};
diff --git a/ffmpeg-2-8-11/libavcodec/rv40dsp.c b/ffmpeg-2-8-11/libavcodec/rv40dsp.c
deleted file mode 100644
index 19b0e93..0000000
--- a/ffmpeg-2-8-11/libavcodec/rv40dsp.c
+++ /dev/null
@@ -1,709 +0,0 @@
-/*
- * RV40 decoder motion compensation functions
- * Copyright (c) 2008 Konstantin Shishkov
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * RV40 decoder motion compensation functions
- */
-
-#include "libavutil/common.h"
-#include "libavutil/intreadwrite.h"
-#include "avcodec.h"
-#include "h264qpel.h"
-#include "mathops.h"
-#include "pixels.h"
-#include "rnd_avg.h"
-#include "rv34dsp.h"
-#include "libavutil/avassert.h"
-
-#define RV40_LOWPASS(OPNAME, OP) \
-static void OPNAME ## rv40_qpel8_h_lowpass(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride,\
- const int h, const int C1, const int C2, const int SHIFT){\
- const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;\
- int i;\
- for(i = 0; i < h; i++)\
- {\
- OP(dst[0], (src[-2] + src[ 3] - 5*(src[-1]+src[2]) + src[0]*C1 + src[1]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- OP(dst[1], (src[-1] + src[ 4] - 5*(src[ 0]+src[3]) + src[1]*C1 + src[2]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- OP(dst[2], (src[ 0] + src[ 5] - 5*(src[ 1]+src[4]) + src[2]*C1 + src[3]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- OP(dst[3], (src[ 1] + src[ 6] - 5*(src[ 2]+src[5]) + src[3]*C1 + src[4]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- OP(dst[4], (src[ 2] + src[ 7] - 5*(src[ 3]+src[6]) + src[4]*C1 + src[5]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- OP(dst[5], (src[ 3] + src[ 8] - 5*(src[ 4]+src[7]) + src[5]*C1 + src[6]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- OP(dst[6], (src[ 4] + src[ 9] - 5*(src[ 5]+src[8]) + src[6]*C1 + src[7]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- OP(dst[7], (src[ 5] + src[10] - 5*(src[ 6]+src[9]) + src[7]*C1 + src[8]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- dst += dstStride;\
- src += srcStride;\
- }\
-}\
-\
-static void OPNAME ## rv40_qpel8_v_lowpass(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride,\
- const int w, const int C1, const int C2, const int SHIFT){\
- const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;\
- int i;\
- for(i = 0; i < w; i++)\
- {\
- const int srcB = src[-2*srcStride];\
- const int srcA = src[-1*srcStride];\
- const int src0 = src[0 *srcStride];\
- const int src1 = src[1 *srcStride];\
- const int src2 = src[2 *srcStride];\
- const int src3 = src[3 *srcStride];\
- const int src4 = src[4 *srcStride];\
- const int src5 = src[5 *srcStride];\
- const int src6 = src[6 *srcStride];\
- const int src7 = src[7 *srcStride];\
- const int src8 = src[8 *srcStride];\
- const int src9 = src[9 *srcStride];\
- const int src10 = src[10*srcStride];\
- OP(dst[0*dstStride], (srcB + src3 - 5*(srcA+src2) + src0*C1 + src1*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- OP(dst[1*dstStride], (srcA + src4 - 5*(src0+src3) + src1*C1 + src2*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- OP(dst[2*dstStride], (src0 + src5 - 5*(src1+src4) + src2*C1 + src3*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- OP(dst[3*dstStride], (src1 + src6 - 5*(src2+src5) + src3*C1 + src4*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- OP(dst[4*dstStride], (src2 + src7 - 5*(src3+src6) + src4*C1 + src5*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- OP(dst[5*dstStride], (src3 + src8 - 5*(src4+src7) + src5*C1 + src6*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- OP(dst[6*dstStride], (src4 + src9 - 5*(src5+src8) + src6*C1 + src7*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- OP(dst[7*dstStride], (src5 + src10 - 5*(src6+src9) + src7*C1 + src8*C2 + (1<<(SHIFT-1))) >> SHIFT);\
- dst++;\
- src++;\
- }\
-}\
-\
-static void OPNAME ## rv40_qpel16_v_lowpass(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride,\
- const int w, const int C1, const int C2, const int SHIFT){\
- OPNAME ## rv40_qpel8_v_lowpass(dst , src , dstStride, srcStride, 8, C1, C2, SHIFT);\
- OPNAME ## rv40_qpel8_v_lowpass(dst+8, src+8, dstStride, srcStride, 8, C1, C2, SHIFT);\
- src += 8*srcStride;\
- dst += 8*dstStride;\
- OPNAME ## rv40_qpel8_v_lowpass(dst , src , dstStride, srcStride, w-8, C1, C2, SHIFT);\
- OPNAME ## rv40_qpel8_v_lowpass(dst+8, src+8, dstStride, srcStride, w-8, C1, C2, SHIFT);\
-}\
-\
-static void OPNAME ## rv40_qpel16_h_lowpass(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride,\
- const int h, const int C1, const int C2, const int SHIFT){\
- OPNAME ## rv40_qpel8_h_lowpass(dst , src , dstStride, srcStride, 8, C1, C2, SHIFT);\
- OPNAME ## rv40_qpel8_h_lowpass(dst+8, src+8, dstStride, srcStride, 8, C1, C2, SHIFT);\
- src += 8*srcStride;\
- dst += 8*dstStride;\
- OPNAME ## rv40_qpel8_h_lowpass(dst , src , dstStride, srcStride, h-8, C1, C2, SHIFT);\
- OPNAME ## rv40_qpel8_h_lowpass(dst+8, src+8, dstStride, srcStride, h-8, C1, C2, SHIFT);\
-}\
-\
-
-#define RV40_MC(OPNAME, SIZE) \
-static void OPNAME ## rv40_qpel ## SIZE ## _mc10_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
-{\
- OPNAME ## rv40_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride, SIZE, 52, 20, 6);\
-}\
-\
-static void OPNAME ## rv40_qpel ## SIZE ## _mc30_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
-{\
- OPNAME ## rv40_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride, SIZE, 20, 52, 6);\
-}\
-\
-static void OPNAME ## rv40_qpel ## SIZE ## _mc01_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
-{\
- OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, src, stride, stride, SIZE, 52, 20, 6);\
-}\
-\
-static void OPNAME ## rv40_qpel ## SIZE ## _mc11_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
-{\
- uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid = full + SIZE*2;\
- put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\
- OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\
-}\
-\
-static void OPNAME ## rv40_qpel ## SIZE ## _mc21_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
-{\
- uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid = full + SIZE*2;\
- put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\
- OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\
-}\
-\
-static void OPNAME ## rv40_qpel ## SIZE ## _mc31_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
-{\
- uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid = full + SIZE*2;\
- put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 52, 6);\
- OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\
-}\
-\
-static void OPNAME ## rv40_qpel ## SIZE ## _mc12_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
-{\
- uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid = full + SIZE*2;\
- put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\
- OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\
-}\
-\
-static void OPNAME ## rv40_qpel ## SIZE ## _mc22_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
-{\
- uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid = full + SIZE*2;\
- put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\
- OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\
-}\
-\
-static void OPNAME ## rv40_qpel ## SIZE ## _mc32_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
-{\
- uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid = full + SIZE*2;\
- put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 52, 6);\
- OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\
-}\
-\
-static void OPNAME ## rv40_qpel ## SIZE ## _mc03_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
-{\
- OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, src, stride, stride, SIZE, 20, 52, 6);\
-}\
-\
-static void OPNAME ## rv40_qpel ## SIZE ## _mc13_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
-{\
- uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid = full + SIZE*2;\
- put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\
- OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 52, 6);\
-}\
-\
-static void OPNAME ## rv40_qpel ## SIZE ## _mc23_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
-{\
- uint8_t full[SIZE*(SIZE+5)];\
- uint8_t * const full_mid = full + SIZE*2;\
- put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\
- OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 52, 6);\
-}\
-\
-
-#define op_avg(a, b) a = (((a)+cm[b]+1)>>1)
-#define op_put(a, b) a = cm[b]
-
-RV40_LOWPASS(put_ , op_put)
-RV40_LOWPASS(avg_ , op_avg)
-
-#undef op_avg
-#undef op_put
-
-RV40_MC(put_, 8)
-RV40_MC(put_, 16)
-RV40_MC(avg_, 8)
-RV40_MC(avg_, 16)
-
-#define PIXOP2(OPNAME, OP) \
-static inline void OPNAME ## _pixels8_xy2_8_c(uint8_t *block, \
- const uint8_t *pixels, \
- ptrdiff_t line_size, \
- int h) \
-{ \
- /* FIXME HIGH BIT DEPTH */ \
- int j; \
- \
- for (j = 0; j < 2; j++) { \
- int i; \
- const uint32_t a = AV_RN32(pixels); \
- const uint32_t b = AV_RN32(pixels + 1); \
- uint32_t l0 = (a & 0x03030303UL) + \
- (b & 0x03030303UL) + \
- 0x02020202UL; \
- uint32_t h0 = ((a & 0xFCFCFCFCUL) >> 2) + \
- ((b & 0xFCFCFCFCUL) >> 2); \
- uint32_t l1, h1; \
- \
- pixels += line_size; \
- for (i = 0; i < h; i += 2) { \
- uint32_t a = AV_RN32(pixels); \
- uint32_t b = AV_RN32(pixels + 1); \
- l1 = (a & 0x03030303UL) + \
- (b & 0x03030303UL); \
- h1 = ((a & 0xFCFCFCFCUL) >> 2) + \
- ((b & 0xFCFCFCFCUL) >> 2); \
- OP(*((uint32_t *) block), \
- h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL)); \
- pixels += line_size; \
- block += line_size; \
- a = AV_RN32(pixels); \
- b = AV_RN32(pixels + 1); \
- l0 = (a & 0x03030303UL) + \
- (b & 0x03030303UL) + \
- 0x02020202UL; \
- h0 = ((a & 0xFCFCFCFCUL) >> 2) + \
- ((b & 0xFCFCFCFCUL) >> 2); \
- OP(*((uint32_t *) block), \
- h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL)); \
- pixels += line_size; \
- block += line_size; \
- } \
- pixels += 4 - line_size * (h + 1); \
- block += 4 - line_size * h; \
- } \
-} \
- \
-CALL_2X_PIXELS(OPNAME ## _pixels16_xy2_8_c, \
- OPNAME ## _pixels8_xy2_8_c, \
- 8) \
-
-#define op_avg(a, b) a = rnd_avg32(a, b)
-#define op_put(a, b) a = b
-PIXOP2(avg, op_avg)
-PIXOP2(put, op_put)
-#undef op_avg
-#undef op_put
-
-static void put_rv40_qpel16_mc33_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
-{
- put_pixels16_xy2_8_c(dst, src, stride, 16);
-}
-static void avg_rv40_qpel16_mc33_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
-{
- avg_pixels16_xy2_8_c(dst, src, stride, 16);
-}
-static void put_rv40_qpel8_mc33_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
-{
- put_pixels8_xy2_8_c(dst, src, stride, 8);
-}
-static void avg_rv40_qpel8_mc33_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
-{
- avg_pixels8_xy2_8_c(dst, src, stride, 8);
-}
-
-static const int rv40_bias[4][4] = {
- { 0, 16, 32, 16 },
- { 32, 28, 32, 28 },
- { 0, 32, 16, 32 },
- { 32, 28, 32, 28 }
-};
-
-#define RV40_CHROMA_MC(OPNAME, OP)\
-static void OPNAME ## rv40_chroma_mc4_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\
- const int A = (8-x) * (8-y);\
- const int B = ( x) * (8-y);\
- const int C = (8-x) * ( y);\
- const int D = ( x) * ( y);\
- int i;\
- int bias = rv40_bias[y>>1][x>>1];\
- \
- av_assert2(x<8 && y<8 && x>=0 && y>=0);\
-\
- if(D){\
- for(i = 0; i < h; i++){\
- OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1] + bias));\
- OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + bias));\
- OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + bias));\
- OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + bias));\
- dst += stride;\
- src += stride;\
- }\
- }else{\
- const int E = B + C;\
- const int step = C ? stride : 1;\
- for(i = 0; i < h; i++){\
- OP(dst[0], (A*src[0] + E*src[step+0] + bias));\
- OP(dst[1], (A*src[1] + E*src[step+1] + bias));\
- OP(dst[2], (A*src[2] + E*src[step+2] + bias));\
- OP(dst[3], (A*src[3] + E*src[step+3] + bias));\
- dst += stride;\
- src += stride;\
- }\
- }\
-}\
-\
-static void OPNAME ## rv40_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\
- const int A = (8-x) * (8-y);\
- const int B = ( x) * (8-y);\
- const int C = (8-x) * ( y);\
- const int D = ( x) * ( y);\
- int i;\
- int bias = rv40_bias[y>>1][x>>1];\
- \
- av_assert2(x<8 && y<8 && x>=0 && y>=0);\
-\
- if(D){\
- for(i = 0; i < h; i++){\
- OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1] + bias));\
- OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + bias));\
- OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + bias));\
- OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + bias));\
- OP(dst[4], (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5] + bias));\
- OP(dst[5], (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6] + bias));\
- OP(dst[6], (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7] + bias));\
- OP(dst[7], (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8] + bias));\
- dst += stride;\
- src += stride;\
- }\
- }else{\
- const int E = B + C;\
- const int step = C ? stride : 1;\
- for(i = 0; i < h; i++){\
- OP(dst[0], (A*src[0] + E*src[step+0] + bias));\
- OP(dst[1], (A*src[1] + E*src[step+1] + bias));\
- OP(dst[2], (A*src[2] + E*src[step+2] + bias));\
- OP(dst[3], (A*src[3] + E*src[step+3] + bias));\
- OP(dst[4], (A*src[4] + E*src[step+4] + bias));\
- OP(dst[5], (A*src[5] + E*src[step+5] + bias));\
- OP(dst[6], (A*src[6] + E*src[step+6] + bias));\
- OP(dst[7], (A*src[7] + E*src[step+7] + bias));\
- dst += stride;\
- src += stride;\
- }\
- }\
-}
-
-#define op_avg(a, b) a = (((a)+((b)>>6)+1)>>1)
-#define op_put(a, b) a = ((b)>>6)
-
-RV40_CHROMA_MC(put_, op_put)
-RV40_CHROMA_MC(avg_, op_avg)
-
-#define RV40_WEIGHT_FUNC(size) \
-static void rv40_weight_func_rnd_ ## size (uint8_t *dst, uint8_t *src1, uint8_t *src2, int w1, int w2, ptrdiff_t stride)\
-{\
- int i, j;\
-\
- for (j = 0; j < size; j++) {\
- for (i = 0; i < size; i++)\
- dst[i] = (((w2 * src1[i]) >> 9) + ((w1 * src2[i]) >> 9) + 0x10) >> 5;\
- src1 += stride;\
- src2 += stride;\
- dst += stride;\
- }\
-}\
-static void rv40_weight_func_nornd_ ## size (uint8_t *dst, uint8_t *src1, uint8_t *src2, int w1, int w2, ptrdiff_t stride)\
-{\
- int i, j;\
-\
- for (j = 0; j < size; j++) {\
- for (i = 0; i < size; i++)\
- dst[i] = (w2 * src1[i] + w1 * src2[i] + 0x10) >> 5;\
- src1 += stride;\
- src2 += stride;\
- dst += stride;\
- }\
-}
-
-RV40_WEIGHT_FUNC(16)
-RV40_WEIGHT_FUNC(8)
-
-/**
- * dither values for deblocking filter - left/top values
- */
-static const uint8_t rv40_dither_l[16] = {
- 0x40, 0x50, 0x20, 0x60, 0x30, 0x50, 0x40, 0x30,
- 0x50, 0x40, 0x50, 0x30, 0x60, 0x20, 0x50, 0x40
-};
-
-/**
- * dither values for deblocking filter - right/bottom values
- */
-static const uint8_t rv40_dither_r[16] = {
- 0x40, 0x30, 0x60, 0x20, 0x50, 0x30, 0x30, 0x40,
- 0x40, 0x40, 0x50, 0x30, 0x20, 0x60, 0x30, 0x40
-};
-
-#define CLIP_SYMM(a, b) av_clip(a, -(b), b)
-/**
- * weaker deblocking very similar to the one described in 4.4.2 of JVT-A003r1
- */
-static av_always_inline void rv40_weak_loop_filter(uint8_t *src,
- const int step,
- const ptrdiff_t stride,
- const int filter_p1,
- const int filter_q1,
- const int alpha,
- const int beta,
- const int lim_p0q0,
- const int lim_q1,
- const int lim_p1)
-{
- const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
- int i, t, u, diff;
-
- for (i = 0; i < 4; i++, src += stride) {
- int diff_p1p0 = src[-2*step] - src[-1*step];
- int diff_q1q0 = src[ 1*step] - src[ 0*step];
- int diff_p1p2 = src[-2*step] - src[-3*step];
- int diff_q1q2 = src[ 1*step] - src[ 2*step];
-
- t = src[0*step] - src[-1*step];
- if (!t)
- continue;
-
- u = (alpha * FFABS(t)) >> 7;
- if (u > 3 - (filter_p1 && filter_q1))
- continue;
-
- t <<= 2;
- if (filter_p1 && filter_q1)
- t += src[-2*step] - src[1*step];
-
- diff = CLIP_SYMM((t + 4) >> 3, lim_p0q0);
- src[-1*step] = cm[src[-1*step] + diff];
- src[ 0*step] = cm[src[ 0*step] - diff];
-
- if (filter_p1 && FFABS(diff_p1p2) <= beta) {
- t = (diff_p1p0 + diff_p1p2 - diff) >> 1;
- src[-2*step] = cm[src[-2*step] - CLIP_SYMM(t, lim_p1)];
- }
-
- if (filter_q1 && FFABS(diff_q1q2) <= beta) {
- t = (diff_q1q0 + diff_q1q2 + diff) >> 1;
- src[ 1*step] = cm[src[ 1*step] - CLIP_SYMM(t, lim_q1)];
- }
- }
-}
-
-static void rv40_h_weak_loop_filter(uint8_t *src, const ptrdiff_t stride,
- const int filter_p1, const int filter_q1,
- const int alpha, const int beta,
- const int lim_p0q0, const int lim_q1,
- const int lim_p1)
-{
- rv40_weak_loop_filter(src, stride, 1, filter_p1, filter_q1,
- alpha, beta, lim_p0q0, lim_q1, lim_p1);
-}
-
-static void rv40_v_weak_loop_filter(uint8_t *src, const ptrdiff_t stride,
- const int filter_p1, const int filter_q1,
- const int alpha, const int beta,
- const int lim_p0q0, const int lim_q1,
- const int lim_p1)
-{
- rv40_weak_loop_filter(src, 1, stride, filter_p1, filter_q1,
- alpha, beta, lim_p0q0, lim_q1, lim_p1);
-}
-
-static av_always_inline void rv40_strong_loop_filter(uint8_t *src,
- const int step,
- const ptrdiff_t stride,
- const int alpha,
- const int lims,
- const int dmode,
- const int chroma)
-{
- int i;
-
- for(i = 0; i < 4; i++, src += stride){
- int sflag, p0, q0, p1, q1;
- int t = src[0*step] - src[-1*step];
-
- if (!t)
- continue;
-
- sflag = (alpha * FFABS(t)) >> 7;
- if (sflag > 1)
- continue;
-
- p0 = (25*src[-3*step] + 26*src[-2*step] + 26*src[-1*step] +
- 26*src[ 0*step] + 25*src[ 1*step] +
- rv40_dither_l[dmode + i]) >> 7;
-
- q0 = (25*src[-2*step] + 26*src[-1*step] + 26*src[ 0*step] +
- 26*src[ 1*step] + 25*src[ 2*step] +
- rv40_dither_r[dmode + i]) >> 7;
-
- if (sflag) {
- p0 = av_clip(p0, src[-1*step] - lims, src[-1*step] + lims);
- q0 = av_clip(q0, src[ 0*step] - lims, src[ 0*step] + lims);
- }
-
- p1 = (25*src[-4*step] + 26*src[-3*step] + 26*src[-2*step] + 26*p0 +
- 25*src[ 0*step] + rv40_dither_l[dmode + i]) >> 7;
- q1 = (25*src[-1*step] + 26*q0 + 26*src[ 1*step] + 26*src[ 2*step] +
- 25*src[ 3*step] + rv40_dither_r[dmode + i]) >> 7;
-
- if (sflag) {
- p1 = av_clip(p1, src[-2*step] - lims, src[-2*step] + lims);
- q1 = av_clip(q1, src[ 1*step] - lims, src[ 1*step] + lims);
- }
-
- src[-2*step] = p1;
- src[-1*step] = p0;
- src[ 0*step] = q0;
- src[ 1*step] = q1;
-
- if(!chroma){
- src[-3*step] = (25*src[-1*step] + 26*src[-2*step] +
- 51*src[-3*step] + 26*src[-4*step] + 64) >> 7;
- src[ 2*step] = (25*src[ 0*step] + 26*src[ 1*step] +
- 51*src[ 2*step] + 26*src[ 3*step] + 64) >> 7;
- }
- }
-}
-
-static void rv40_h_strong_loop_filter(uint8_t *src, const ptrdiff_t stride,
- const int alpha, const int lims,
- const int dmode, const int chroma)
-{
- rv40_strong_loop_filter(src, stride, 1, alpha, lims, dmode, chroma);
-}
-
-static void rv40_v_strong_loop_filter(uint8_t *src, const ptrdiff_t stride,
- const int alpha, const int lims,
- const int dmode, const int chroma)
-{
- rv40_strong_loop_filter(src, 1, stride, alpha, lims, dmode, chroma);
-}
-
-static av_always_inline int rv40_loop_filter_strength(uint8_t *src,
- int step, ptrdiff_t stride,
- int beta, int beta2,
- int edge,
- int *p1, int *q1)
-{
- int sum_p1p0 = 0, sum_q1q0 = 0, sum_p1p2 = 0, sum_q1q2 = 0;
- int strong0 = 0, strong1 = 0;
- uint8_t *ptr;
- int i;
-
- for (i = 0, ptr = src; i < 4; i++, ptr += stride) {
- sum_p1p0 += ptr[-2*step] - ptr[-1*step];
- sum_q1q0 += ptr[ 1*step] - ptr[ 0*step];
- }
-
- *p1 = FFABS(sum_p1p0) < (beta << 2);
- *q1 = FFABS(sum_q1q0) < (beta << 2);
-
- if(!*p1 && !*q1)
- return 0;
-
- if (!edge)
- return 0;
-
- for (i = 0, ptr = src; i < 4; i++, ptr += stride) {
- sum_p1p2 += ptr[-2*step] - ptr[-3*step];
- sum_q1q2 += ptr[ 1*step] - ptr[ 2*step];
- }
-
- strong0 = *p1 && (FFABS(sum_p1p2) < beta2);
- strong1 = *q1 && (FFABS(sum_q1q2) < beta2);
-
- return strong0 && strong1;
-}
-
-static int rv40_h_loop_filter_strength(uint8_t *src, ptrdiff_t stride,
- int beta, int beta2, int edge,
- int *p1, int *q1)
-{
- return rv40_loop_filter_strength(src, stride, 1, beta, beta2, edge, p1, q1);
-}
-
-static int rv40_v_loop_filter_strength(uint8_t *src, ptrdiff_t stride,
- int beta, int beta2, int edge,
- int *p1, int *q1)
-{
- return rv40_loop_filter_strength(src, 1, stride, beta, beta2, edge, p1, q1);
-}
-
-av_cold void ff_rv40dsp_init(RV34DSPContext *c)
-{
- H264QpelContext qpel;
-
- ff_rv34dsp_init(c);
- ff_h264qpel_init(&qpel, 8);
-
- c->put_pixels_tab[0][ 0] = qpel.put_h264_qpel_pixels_tab[0][0];
- c->put_pixels_tab[0][ 1] = put_rv40_qpel16_mc10_c;
- c->put_pixels_tab[0][ 2] = qpel.put_h264_qpel_pixels_tab[0][2];
- c->put_pixels_tab[0][ 3] = put_rv40_qpel16_mc30_c;
- c->put_pixels_tab[0][ 4] = put_rv40_qpel16_mc01_c;
- c->put_pixels_tab[0][ 5] = put_rv40_qpel16_mc11_c;
- c->put_pixels_tab[0][ 6] = put_rv40_qpel16_mc21_c;
- c->put_pixels_tab[0][ 7] = put_rv40_qpel16_mc31_c;
- c->put_pixels_tab[0][ 8] = qpel.put_h264_qpel_pixels_tab[0][8];
- c->put_pixels_tab[0][ 9] = put_rv40_qpel16_mc12_c;
- c->put_pixels_tab[0][10] = put_rv40_qpel16_mc22_c;
- c->put_pixels_tab[0][11] = put_rv40_qpel16_mc32_c;
- c->put_pixels_tab[0][12] = put_rv40_qpel16_mc03_c;
- c->put_pixels_tab[0][13] = put_rv40_qpel16_mc13_c;
- c->put_pixels_tab[0][14] = put_rv40_qpel16_mc23_c;
- c->put_pixels_tab[0][15] = put_rv40_qpel16_mc33_c;
- c->avg_pixels_tab[0][ 0] = qpel.avg_h264_qpel_pixels_tab[0][0];
- c->avg_pixels_tab[0][ 1] = avg_rv40_qpel16_mc10_c;
- c->avg_pixels_tab[0][ 2] = qpel.avg_h264_qpel_pixels_tab[0][2];
- c->avg_pixels_tab[0][ 3] = avg_rv40_qpel16_mc30_c;
- c->avg_pixels_tab[0][ 4] = avg_rv40_qpel16_mc01_c;
- c->avg_pixels_tab[0][ 5] = avg_rv40_qpel16_mc11_c;
- c->avg_pixels_tab[0][ 6] = avg_rv40_qpel16_mc21_c;
- c->avg_pixels_tab[0][ 7] = avg_rv40_qpel16_mc31_c;
- c->avg_pixels_tab[0][ 8] = qpel.avg_h264_qpel_pixels_tab[0][8];
- c->avg_pixels_tab[0][ 9] = avg_rv40_qpel16_mc12_c;
- c->avg_pixels_tab[0][10] = avg_rv40_qpel16_mc22_c;
- c->avg_pixels_tab[0][11] = avg_rv40_qpel16_mc32_c;
- c->avg_pixels_tab[0][12] = avg_rv40_qpel16_mc03_c;
- c->avg_pixels_tab[0][13] = avg_rv40_qpel16_mc13_c;
- c->avg_pixels_tab[0][14] = avg_rv40_qpel16_mc23_c;
- c->avg_pixels_tab[0][15] = avg_rv40_qpel16_mc33_c;
- c->put_pixels_tab[1][ 0] = qpel.put_h264_qpel_pixels_tab[1][0];
- c->put_pixels_tab[1][ 1] = put_rv40_qpel8_mc10_c;
- c->put_pixels_tab[1][ 2] = qpel.put_h264_qpel_pixels_tab[1][2];
- c->put_pixels_tab[1][ 3] = put_rv40_qpel8_mc30_c;
- c->put_pixels_tab[1][ 4] = put_rv40_qpel8_mc01_c;
- c->put_pixels_tab[1][ 5] = put_rv40_qpel8_mc11_c;
- c->put_pixels_tab[1][ 6] = put_rv40_qpel8_mc21_c;
- c->put_pixels_tab[1][ 7] = put_rv40_qpel8_mc31_c;
- c->put_pixels_tab[1][ 8] = qpel.put_h264_qpel_pixels_tab[1][8];
- c->put_pixels_tab[1][ 9] = put_rv40_qpel8_mc12_c;
- c->put_pixels_tab[1][10] = put_rv40_qpel8_mc22_c;
- c->put_pixels_tab[1][11] = put_rv40_qpel8_mc32_c;
- c->put_pixels_tab[1][12] = put_rv40_qpel8_mc03_c;
- c->put_pixels_tab[1][13] = put_rv40_qpel8_mc13_c;
- c->put_pixels_tab[1][14] = put_rv40_qpel8_mc23_c;
- c->put_pixels_tab[1][15] = put_rv40_qpel8_mc33_c;
- c->avg_pixels_tab[1][ 0] = qpel.avg_h264_qpel_pixels_tab[1][0];
- c->avg_pixels_tab[1][ 1] = avg_rv40_qpel8_mc10_c;
- c->avg_pixels_tab[1][ 2] = qpel.avg_h264_qpel_pixels_tab[1][2];
- c->avg_pixels_tab[1][ 3] = avg_rv40_qpel8_mc30_c;
- c->avg_pixels_tab[1][ 4] = avg_rv40_qpel8_mc01_c;
- c->avg_pixels_tab[1][ 5] = avg_rv40_qpel8_mc11_c;
- c->avg_pixels_tab[1][ 6] = avg_rv40_qpel8_mc21_c;
- c->avg_pixels_tab[1][ 7] = avg_rv40_qpel8_mc31_c;
- c->avg_pixels_tab[1][ 8] = qpel.avg_h264_qpel_pixels_tab[1][8];
- c->avg_pixels_tab[1][ 9] = avg_rv40_qpel8_mc12_c;
- c->avg_pixels_tab[1][10] = avg_rv40_qpel8_mc22_c;
- c->avg_pixels_tab[1][11] = avg_rv40_qpel8_mc32_c;
- c->avg_pixels_tab[1][12] = avg_rv40_qpel8_mc03_c;
- c->avg_pixels_tab[1][13] = avg_rv40_qpel8_mc13_c;
- c->avg_pixels_tab[1][14] = avg_rv40_qpel8_mc23_c;
- c->avg_pixels_tab[1][15] = avg_rv40_qpel8_mc33_c;
-
- c->put_chroma_pixels_tab[0] = put_rv40_chroma_mc8_c;
- c->put_chroma_pixels_tab[1] = put_rv40_chroma_mc4_c;
- c->avg_chroma_pixels_tab[0] = avg_rv40_chroma_mc8_c;
- c->avg_chroma_pixels_tab[1] = avg_rv40_chroma_mc4_c;
-
- c->rv40_weight_pixels_tab[0][0] = rv40_weight_func_rnd_16;
- c->rv40_weight_pixels_tab[0][1] = rv40_weight_func_rnd_8;
- c->rv40_weight_pixels_tab[1][0] = rv40_weight_func_nornd_16;
- c->rv40_weight_pixels_tab[1][1] = rv40_weight_func_nornd_8;
-
- c->rv40_weak_loop_filter[0] = rv40_h_weak_loop_filter;
- c->rv40_weak_loop_filter[1] = rv40_v_weak_loop_filter;
- c->rv40_strong_loop_filter[0] = rv40_h_strong_loop_filter;
- c->rv40_strong_loop_filter[1] = rv40_v_strong_loop_filter;
- c->rv40_loop_filter_strength[0] = rv40_h_loop_filter_strength;
- c->rv40_loop_filter_strength[1] = rv40_v_loop_filter_strength;
-
- if (ARCH_AARCH64)
- ff_rv40dsp_init_aarch64(c);
- if (ARCH_ARM)
- ff_rv40dsp_init_arm(c);
- if (ARCH_X86)
- ff_rv40dsp_init_x86(c);
-}
diff --git a/ffmpeg-2-8-11/libavcodec/s302m.c b/ffmpeg-2-8-11/libavcodec/s302m.c
deleted file mode 100644
index ccfb591..0000000
--- a/ffmpeg-2-8-11/libavcodec/s302m.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * SMPTE 302M decoder
- * Copyright (c) 2008 Laurent Aimar <fenrir at videolan.org>
- * Copyright (c) 2009 Baptiste Coudurier <baptiste.coudurier at gmail.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 "libavutil/intreadwrite.h"
-#include "libavutil/opt.h"
-#include "libavutil/log.h"
-#include "avcodec.h"
-#include "internal.h"
-#include "mathops.h"
-
-#define AES3_HEADER_LEN 4
-
-typedef struct S302Context {
- AVClass *class;
- int non_pcm_mode;
-} S302Context;
-
-static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
- int buf_size)
-{
- uint32_t h;
- int frame_size, channels, bits;
-
- if (buf_size <= AES3_HEADER_LEN) {
- av_log(avctx, AV_LOG_ERROR, "frame is too short\n");
- return AVERROR_INVALIDDATA;
- }
-
- /*
- * AES3 header :
- * size: 16
- * number channels 2
- * channel_id 8
- * bits per samples 2
- * alignments 4
- */
-
- h = AV_RB32(buf);
- frame_size = (h >> 16) & 0xffff;
- channels = ((h >> 14) & 0x0003) * 2 + 2;
- bits = ((h >> 4) & 0x0003) * 4 + 16;
-
- if (AES3_HEADER_LEN + frame_size != buf_size || bits > 24) {
- av_log(avctx, AV_LOG_ERROR, "frame has invalid header\n");
- return AVERROR_INVALIDDATA;
- }
-
- /* Set output properties */
- avctx->bits_per_raw_sample = bits;
- if (bits > 16)
- avctx->sample_fmt = AV_SAMPLE_FMT_S32;
- else
- avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-
- avctx->channels = channels;
- switch(channels) {
- case 2:
- avctx->channel_layout = AV_CH_LAYOUT_STEREO;
- break;
- case 4:
- avctx->channel_layout = AV_CH_LAYOUT_QUAD;
- break;
- case 6:
- avctx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK;
- break;
- case 8:
- avctx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX;
- }
-
- return frame_size;
-}
-
-static int s302m_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- S302Context *s = avctx->priv_data;
- AVFrame *frame = data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- int block_size, ret;
- int i;
- int non_pcm_data_type = -1;
-
- int frame_size = s302m_parse_frame_header(avctx, buf, buf_size);
- if (frame_size < 0)
- return frame_size;
-
- buf_size -= AES3_HEADER_LEN;
- buf += AES3_HEADER_LEN;
-
- /* get output buffer */
- block_size = (avctx->bits_per_raw_sample + 4) / 4;
- frame->nb_samples = 2 * (buf_size / block_size) / avctx->channels;
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
-
- avctx->bit_rate = 48000 * avctx->channels * (avctx->bits_per_raw_sample + 4) +
- 32 * 48000 / frame->nb_samples;
- buf_size = (frame->nb_samples * avctx->channels / 2) * block_size;
-
- if (avctx->bits_per_raw_sample == 24) {
- uint32_t *o = (uint32_t *)frame->data[0];
- for (; buf_size > 6; buf_size -= 7) {
- *o++ = (ff_reverse[buf[2]] << 24) |
- (ff_reverse[buf[1]] << 16) |
- (ff_reverse[buf[0]] << 8);
- *o++ = (ff_reverse[buf[6] & 0xf0] << 28) |
- (ff_reverse[buf[5]] << 20) |
- (ff_reverse[buf[4]] << 12) |
- (ff_reverse[buf[3] & 0x0f] << 4);
- buf += 7;
- }
- o = (uint32_t *)frame->data[0];
- if (avctx->channels == 2)
- for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
- if (o[i] || o[i+1] || o[i+2] || o[i+3])
- break;
- if (o[i+4] == 0x96F87200U && o[i+5] == 0xA54E1F00) {
- non_pcm_data_type = (o[i+6] >> 16) & 0x1F;
- break;
- }
- }
- } else if (avctx->bits_per_raw_sample == 20) {
- uint32_t *o = (uint32_t *)frame->data[0];
- for (; buf_size > 5; buf_size -= 6) {
- *o++ = (ff_reverse[buf[2] & 0xf0] << 28) |
- (ff_reverse[buf[1]] << 20) |
- (ff_reverse[buf[0]] << 12);
- *o++ = (ff_reverse[buf[5] & 0xf0] << 28) |
- (ff_reverse[buf[4]] << 20) |
- (ff_reverse[buf[3]] << 12);
- buf += 6;
- }
- o = (uint32_t *)frame->data[0];
- if (avctx->channels == 2)
- for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
- if (o[i] || o[i+1] || o[i+2] || o[i+3])
- break;
- if (o[i+4] == 0x6F872000U && o[i+5] == 0x54E1F000) {
- non_pcm_data_type = (o[i+6] >> 16) & 0x1F;
- break;
- }
- }
- } else {
- uint16_t *o = (uint16_t *)frame->data[0];
- for (; buf_size > 4; buf_size -= 5) {
- *o++ = (ff_reverse[buf[1]] << 8) |
- ff_reverse[buf[0]];
- *o++ = (ff_reverse[buf[4] & 0xf0] << 12) |
- (ff_reverse[buf[3]] << 4) |
- (ff_reverse[buf[2]] >> 4);
- buf += 5;
- }
- o = (uint16_t *)frame->data[0];
- if (avctx->channels == 2)
- for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
- if (o[i] || o[i+1] || o[i+2] || o[i+3])
- break;
- if (o[i+4] == 0xF872U && o[i+5] == 0x4E1F) {
- non_pcm_data_type = (o[i+6] & 0x1F);
- break;
- }
- }
- }
-
- if (non_pcm_data_type != -1) {
- if (s->non_pcm_mode == 3) {
- av_log(avctx, AV_LOG_ERROR,
- "S302 non PCM mode with data type %d not supported\n",
- non_pcm_data_type);
- return AVERROR_PATCHWELCOME;
- }
- if (s->non_pcm_mode & 1) {
- return avpkt->size;
- }
- }
-
- avctx->sample_rate = 48000;
-
- *got_frame_ptr = 1;
-
- return avpkt->size;
-}
-
-#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM
-static const AVOption s302m_options[] = {
- {"non_pcm_mode", "Chooses what to do with NON-PCM", offsetof(S302Context, non_pcm_mode), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 3, FLAGS, "non_pcm_mode"},
- {"copy" , "Pass NON-PCM through unchanged" , 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 3, FLAGS, "non_pcm_mode"},
- {"drop" , "Drop NON-PCM" , 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 3, FLAGS, "non_pcm_mode"},
- {"decode_copy" , "Decode if possible else passthrough", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 3, FLAGS, "non_pcm_mode"},
- {"decode_drop" , "Decode if possible else drop" , 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 3, FLAGS, "non_pcm_mode"},
- {NULL}
-};
-
-static const AVClass s302m_class = {
- "SMPTE 302M Decoder",
- av_default_item_name,
- s302m_options,
- LIBAVUTIL_VERSION_INT,
-};
-
-AVCodec ff_s302m_decoder = {
- .name = "s302m",
- .long_name = NULL_IF_CONFIG_SMALL("SMPTE 302M"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_S302M,
- .priv_data_size = sizeof(S302Context),
- .decode = s302m_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
- .priv_class = &s302m_class,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/sanm.c b/ffmpeg-2-8-11/libavcodec/sanm.c
deleted file mode 100644
index 1aa002b..0000000
--- a/ffmpeg-2-8-11/libavcodec/sanm.c
+++ /dev/null
@@ -1,1529 +0,0 @@
-/*
- * LucasArts Smush video decoder
- * Copyright (c) 2006 Cyril Zorin
- * Copyright (c) 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 "libavutil/avassert.h"
-#include "libavutil/bswap.h"
-#include "libavutil/imgutils.h"
-
-#include "avcodec.h"
-#include "bytestream.h"
-#include "copy_block.h"
-#include "internal.h"
-
-#define NGLYPHS 256
-#define GLYPH_COORD_VECT_SIZE 16
-#define PALETTE_SIZE 256
-#define PALETTE_DELTA 768
-
-static const int8_t glyph4_x[GLYPH_COORD_VECT_SIZE] = {
- 0, 1, 2, 3, 3, 3, 3, 2, 1, 0, 0, 0, 1, 2, 2, 1
-};
-
-static const int8_t glyph4_y[GLYPH_COORD_VECT_SIZE] = {
- 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 2, 1, 1, 1, 2, 2
-};
-
-static const int8_t glyph8_x[GLYPH_COORD_VECT_SIZE] = {
- 0, 2, 5, 7, 7, 7, 7, 7, 7, 5, 2, 0, 0, 0, 0, 0
-};
-
-static const int8_t glyph8_y[GLYPH_COORD_VECT_SIZE] = {
- 0, 0, 0, 0, 1, 3, 4, 6, 7, 7, 7, 7, 6, 4, 3, 1
-};
-
-static const int8_t motion_vectors[256][2] = {
- { 0, 0 }, { -1, -43 }, { 6, -43 }, { -9, -42 }, { 13, -41 },
- { -16, -40 }, { 19, -39 }, { -23, -36 }, { 26, -34 }, { -2, -33 },
- { 4, -33 }, { -29, -32 }, { -9, -32 }, { 11, -31 }, { -16, -29 },
- { 32, -29 }, { 18, -28 }, { -34, -26 }, { -22, -25 }, { -1, -25 },
- { 3, -25 }, { -7, -24 }, { 8, -24 }, { 24, -23 }, { 36, -23 },
- { -12, -22 }, { 13, -21 }, { -38, -20 }, { 0, -20 }, { -27, -19 },
- { -4, -19 }, { 4, -19 }, { -17, -18 }, { -8, -17 }, { 8, -17 },
- { 18, -17 }, { 28, -17 }, { 39, -17 }, { -12, -15 }, { 12, -15 },
- { -21, -14 }, { -1, -14 }, { 1, -14 }, { -41, -13 }, { -5, -13 },
- { 5, -13 }, { 21, -13 }, { -31, -12 }, { -15, -11 }, { -8, -11 },
- { 8, -11 }, { 15, -11 }, { -2, -10 }, { 1, -10 }, { 31, -10 },
- { -23, -9 }, { -11, -9 }, { -5, -9 }, { 4, -9 }, { 11, -9 },
- { 42, -9 }, { 6, -8 }, { 24, -8 }, { -18, -7 }, { -7, -7 },
- { -3, -7 }, { -1, -7 }, { 2, -7 }, { 18, -7 }, { -43, -6 },
- { -13, -6 }, { -4, -6 }, { 4, -6 }, { 8, -6 }, { -33, -5 },
- { -9, -5 }, { -2, -5 }, { 0, -5 }, { 2, -5 }, { 5, -5 },
- { 13, -5 }, { -25, -4 }, { -6, -4 }, { -3, -4 }, { 3, -4 },
- { 9, -4 }, { -19, -3 }, { -7, -3 }, { -4, -3 }, { -2, -3 },
- { -1, -3 }, { 0, -3 }, { 1, -3 }, { 2, -3 }, { 4, -3 },
- { 6, -3 }, { 33, -3 }, { -14, -2 }, { -10, -2 }, { -5, -2 },
- { -3, -2 }, { -2, -2 }, { -1, -2 }, { 0, -2 }, { 1, -2 },
- { 2, -2 }, { 3, -2 }, { 5, -2 }, { 7, -2 }, { 14, -2 },
- { 19, -2 }, { 25, -2 }, { 43, -2 }, { -7, -1 }, { -3, -1 },
- { -2, -1 }, { -1, -1 }, { 0, -1 }, { 1, -1 }, { 2, -1 },
- { 3, -1 }, { 10, -1 }, { -5, 0 }, { -3, 0 }, { -2, 0 },
- { -1, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 }, { 5, 0 },
- { 7, 0 }, { -10, 1 }, { -7, 1 }, { -3, 1 }, { -2, 1 },
- { -1, 1 }, { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 },
- { -43, 2 }, { -25, 2 }, { -19, 2 }, { -14, 2 }, { -5, 2 },
- { -3, 2 }, { -2, 2 }, { -1, 2 }, { 0, 2 }, { 1, 2 },
- { 2, 2 }, { 3, 2 }, { 5, 2 }, { 7, 2 }, { 10, 2 },
- { 14, 2 }, { -33, 3 }, { -6, 3 }, { -4, 3 }, { -2, 3 },
- { -1, 3 }, { 0, 3 }, { 1, 3 }, { 2, 3 }, { 4, 3 },
- { 19, 3 }, { -9, 4 }, { -3, 4 }, { 3, 4 }, { 7, 4 },
- { 25, 4 }, { -13, 5 }, { -5, 5 }, { -2, 5 }, { 0, 5 },
- { 2, 5 }, { 5, 5 }, { 9, 5 }, { 33, 5 }, { -8, 6 },
- { -4, 6 }, { 4, 6 }, { 13, 6 }, { 43, 6 }, { -18, 7 },
- { -2, 7 }, { 0, 7 }, { 2, 7 }, { 7, 7 }, { 18, 7 },
- { -24, 8 }, { -6, 8 }, { -42, 9 }, { -11, 9 }, { -4, 9 },
- { 5, 9 }, { 11, 9 }, { 23, 9 }, { -31, 10 }, { -1, 10 },
- { 2, 10 }, { -15, 11 }, { -8, 11 }, { 8, 11 }, { 15, 11 },
- { 31, 12 }, { -21, 13 }, { -5, 13 }, { 5, 13 }, { 41, 13 },
- { -1, 14 }, { 1, 14 }, { 21, 14 }, { -12, 15 }, { 12, 15 },
- { -39, 17 }, { -28, 17 }, { -18, 17 }, { -8, 17 }, { 8, 17 },
- { 17, 18 }, { -4, 19 }, { 0, 19 }, { 4, 19 }, { 27, 19 },
- { 38, 20 }, { -13, 21 }, { 12, 22 }, { -36, 23 }, { -24, 23 },
- { -8, 24 }, { 7, 24 }, { -3, 25 }, { 1, 25 }, { 22, 25 },
- { 34, 26 }, { -18, 28 }, { -32, 29 }, { 16, 29 }, { -11, 31 },
- { 9, 32 }, { 29, 32 }, { -4, 33 }, { 2, 33 }, { -26, 34 },
- { 23, 36 }, { -19, 39 }, { 16, 40 }, { -13, 41 }, { 9, 42 },
- { -6, 43 }, { 1, 43 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
-};
-
-static const int8_t c37_mv[] = {
- 0, 0, 1, 0, 2, 0, 3, 0, 5, 0,
- 8, 0, 13, 0, 21, 0, -1, 0, -2, 0,
- -3, 0, -5, 0, -8, 0, -13, 0, -17, 0,
- -21, 0, 0, 1, 1, 1, 2, 1, 3, 1,
- 5, 1, 8, 1, 13, 1, 21, 1, -1, 1,
- -2, 1, -3, 1, -5, 1, -8, 1, -13, 1,
- -17, 1, -21, 1, 0, 2, 1, 2, 2, 2,
- 3, 2, 5, 2, 8, 2, 13, 2, 21, 2,
- -1, 2, -2, 2, -3, 2, -5, 2, -8, 2,
- -13, 2, -17, 2, -21, 2, 0, 3, 1, 3,
- 2, 3, 3, 3, 5, 3, 8, 3, 13, 3,
- 21, 3, -1, 3, -2, 3, -3, 3, -5, 3,
- -8, 3, -13, 3, -17, 3, -21, 3, 0, 5,
- 1, 5, 2, 5, 3, 5, 5, 5, 8, 5,
- 13, 5, 21, 5, -1, 5, -2, 5, -3, 5,
- -5, 5, -8, 5, -13, 5, -17, 5, -21, 5,
- 0, 8, 1, 8, 2, 8, 3, 8, 5, 8,
- 8, 8, 13, 8, 21, 8, -1, 8, -2, 8,
- -3, 8, -5, 8, -8, 8, -13, 8, -17, 8,
- -21, 8, 0, 13, 1, 13, 2, 13, 3, 13,
- 5, 13, 8, 13, 13, 13, 21, 13, -1, 13,
- -2, 13, -3, 13, -5, 13, -8, 13, -13, 13,
- -17, 13, -21, 13, 0, 21, 1, 21, 2, 21,
- 3, 21, 5, 21, 8, 21, 13, 21, 21, 21,
- -1, 21, -2, 21, -3, 21, -5, 21, -8, 21,
- -13, 21, -17, 21, -21, 21, 0, -1, 1, -1,
- 2, -1, 3, -1, 5, -1, 8, -1, 13, -1,
- 21, -1, -1, -1, -2, -1, -3, -1, -5, -1,
- -8, -1, -13, -1, -17, -1, -21, -1, 0, -2,
- 1, -2, 2, -2, 3, -2, 5, -2, 8, -2,
- 13, -2, 21, -2, -1, -2, -2, -2, -3, -2,
- -5, -2, -8, -2, -13, -2, -17, -2, -21, -2,
- 0, -3, 1, -3, 2, -3, 3, -3, 5, -3,
- 8, -3, 13, -3, 21, -3, -1, -3, -2, -3,
- -3, -3, -5, -3, -8, -3, -13, -3, -17, -3,
- -21, -3, 0, -5, 1, -5, 2, -5, 3, -5,
- 5, -5, 8, -5, 13, -5, 21, -5, -1, -5,
- -2, -5, -3, -5, -5, -5, -8, -5, -13, -5,
- -17, -5, -21, -5, 0, -8, 1, -8, 2, -8,
- 3, -8, 5, -8, 8, -8, 13, -8, 21, -8,
- -1, -8, -2, -8, -3, -8, -5, -8, -8, -8,
- -13, -8, -17, -8, -21, -8, 0, -13, 1, -13,
- 2, -13, 3, -13, 5, -13, 8, -13, 13, -13,
- 21, -13, -1, -13, -2, -13, -3, -13, -5, -13,
- -8, -13, -13, -13, -17, -13, -21, -13, 0, -17,
- 1, -17, 2, -17, 3, -17, 5, -17, 8, -17,
- 13, -17, 21, -17, -1, -17, -2, -17, -3, -17,
- -5, -17, -8, -17, -13, -17, -17, -17, -21, -17,
- 0, -21, 1, -21, 2, -21, 3, -21, 5, -21,
- 8, -21, 13, -21, 21, -21, -1, -21, -2, -21,
- -3, -21, -5, -21, -8, -21, -13, -21, -17, -21,
- 0, 0, -8, -29, 8, -29, -18, -25, 17, -25,
- 0, -23, -6, -22, 6, -22, -13, -19, 12, -19,
- 0, -18, 25, -18, -25, -17, -5, -17, 5, -17,
- -10, -15, 10, -15, 0, -14, -4, -13, 4, -13,
- 19, -13, -19, -12, -8, -11, -2, -11, 0, -11,
- 2, -11, 8, -11, -15, -10, -4, -10, 4, -10,
- 15, -10, -6, -9, -1, -9, 1, -9, 6, -9,
- -29, -8, -11, -8, -8, -8, -3, -8, 3, -8,
- 8, -8, 11, -8, 29, -8, -5, -7, -2, -7,
- 0, -7, 2, -7, 5, -7, -22, -6, -9, -6,
- -6, -6, -3, -6, -1, -6, 1, -6, 3, -6,
- 6, -6, 9, -6, 22, -6, -17, -5, -7, -5,
- -4, -5, -2, -5, 0, -5, 2, -5, 4, -5,
- 7, -5, 17, -5, -13, -4, -10, -4, -5, -4,
- -3, -4, -1, -4, 0, -4, 1, -4, 3, -4,
- 5, -4, 10, -4, 13, -4, -8, -3, -6, -3,
- -4, -3, -3, -3, -2, -3, -1, -3, 0, -3,
- 1, -3, 2, -3, 4, -3, 6, -3, 8, -3,
- -11, -2, -7, -2, -5, -2, -3, -2, -2, -2,
- -1, -2, 0, -2, 1, -2, 2, -2, 3, -2,
- 5, -2, 7, -2, 11, -2, -9, -1, -6, -1,
- -4, -1, -3, -1, -2, -1, -1, -1, 0, -1,
- 1, -1, 2, -1, 3, -1, 4, -1, 6, -1,
- 9, -1, -31, 0, -23, 0, -18, 0, -14, 0,
- -11, 0, -7, 0, -5, 0, -4, 0, -3, 0,
- -2, 0, -1, 0, 0, -31, 1, 0, 2, 0,
- 3, 0, 4, 0, 5, 0, 7, 0, 11, 0,
- 14, 0, 18, 0, 23, 0, 31, 0, -9, 1,
- -6, 1, -4, 1, -3, 1, -2, 1, -1, 1,
- 0, 1, 1, 1, 2, 1, 3, 1, 4, 1,
- 6, 1, 9, 1, -11, 2, -7, 2, -5, 2,
- -3, 2, -2, 2, -1, 2, 0, 2, 1, 2,
- 2, 2, 3, 2, 5, 2, 7, 2, 11, 2,
- -8, 3, -6, 3, -4, 3, -2, 3, -1, 3,
- 0, 3, 1, 3, 2, 3, 3, 3, 4, 3,
- 6, 3, 8, 3, -13, 4, -10, 4, -5, 4,
- -3, 4, -1, 4, 0, 4, 1, 4, 3, 4,
- 5, 4, 10, 4, 13, 4, -17, 5, -7, 5,
- -4, 5, -2, 5, 0, 5, 2, 5, 4, 5,
- 7, 5, 17, 5, -22, 6, -9, 6, -6, 6,
- -3, 6, -1, 6, 1, 6, 3, 6, 6, 6,
- 9, 6, 22, 6, -5, 7, -2, 7, 0, 7,
- 2, 7, 5, 7, -29, 8, -11, 8, -8, 8,
- -3, 8, 3, 8, 8, 8, 11, 8, 29, 8,
- -6, 9, -1, 9, 1, 9, 6, 9, -15, 10,
- -4, 10, 4, 10, 15, 10, -8, 11, -2, 11,
- 0, 11, 2, 11, 8, 11, 19, 12, -19, 13,
- -4, 13, 4, 13, 0, 14, -10, 15, 10, 15,
- -5, 17, 5, 17, 25, 17, -25, 18, 0, 18,
- -12, 19, 13, 19, -6, 22, 6, 22, 0, 23,
- -17, 25, 18, 25, -8, 29, 8, 29, 0, 31,
- 0, 0, -6, -22, 6, -22, -13, -19, 12, -19,
- 0, -18, -5, -17, 5, -17, -10, -15, 10, -15,
- 0, -14, -4, -13, 4, -13, 19, -13, -19, -12,
- -8, -11, -2, -11, 0, -11, 2, -11, 8, -11,
- -15, -10, -4, -10, 4, -10, 15, -10, -6, -9,
- -1, -9, 1, -9, 6, -9, -11, -8, -8, -8,
- -3, -8, 0, -8, 3, -8, 8, -8, 11, -8,
- -5, -7, -2, -7, 0, -7, 2, -7, 5, -7,
- -22, -6, -9, -6, -6, -6, -3, -6, -1, -6,
- 1, -6, 3, -6, 6, -6, 9, -6, 22, -6,
- -17, -5, -7, -5, -4, -5, -2, -5, -1, -5,
- 0, -5, 1, -5, 2, -5, 4, -5, 7, -5,
- 17, -5, -13, -4, -10, -4, -5, -4, -3, -4,
- -2, -4, -1, -4, 0, -4, 1, -4, 2, -4,
- 3, -4, 5, -4, 10, -4, 13, -4, -8, -3,
- -6, -3, -4, -3, -3, -3, -2, -3, -1, -3,
- 0, -3, 1, -3, 2, -3, 3, -3, 4, -3,
- 6, -3, 8, -3, -11, -2, -7, -2, -5, -2,
- -4, -2, -3, -2, -2, -2, -1, -2, 0, -2,
- 1, -2, 2, -2, 3, -2, 4, -2, 5, -2,
- 7, -2, 11, -2, -9, -1, -6, -1, -5, -1,
- -4, -1, -3, -1, -2, -1, -1, -1, 0, -1,
- 1, -1, 2, -1, 3, -1, 4, -1, 5, -1,
- 6, -1, 9, -1, -23, 0, -18, 0, -14, 0,
- -11, 0, -7, 0, -5, 0, -4, 0, -3, 0,
- -2, 0, -1, 0, 0, -23, 1, 0, 2, 0,
- 3, 0, 4, 0, 5, 0, 7, 0, 11, 0,
- 14, 0, 18, 0, 23, 0, -9, 1, -6, 1,
- -5, 1, -4, 1, -3, 1, -2, 1, -1, 1,
- 0, 1, 1, 1, 2, 1, 3, 1, 4, 1,
- 5, 1, 6, 1, 9, 1, -11, 2, -7, 2,
- -5, 2, -4, 2, -3, 2, -2, 2, -1, 2,
- 0, 2, 1, 2, 2, 2, 3, 2, 4, 2,
- 5, 2, 7, 2, 11, 2, -8, 3, -6, 3,
- -4, 3, -3, 3, -2, 3, -1, 3, 0, 3,
- 1, 3, 2, 3, 3, 3, 4, 3, 6, 3,
- 8, 3, -13, 4, -10, 4, -5, 4, -3, 4,
- -2, 4, -1, 4, 0, 4, 1, 4, 2, 4,
- 3, 4, 5, 4, 10, 4, 13, 4, -17, 5,
- -7, 5, -4, 5, -2, 5, -1, 5, 0, 5,
- 1, 5, 2, 5, 4, 5, 7, 5, 17, 5,
- -22, 6, -9, 6, -6, 6, -3, 6, -1, 6,
- 1, 6, 3, 6, 6, 6, 9, 6, 22, 6,
- -5, 7, -2, 7, 0, 7, 2, 7, 5, 7,
- -11, 8, -8, 8, -3, 8, 0, 8, 3, 8,
- 8, 8, 11, 8, -6, 9, -1, 9, 1, 9,
- 6, 9, -15, 10, -4, 10, 4, 10, 15, 10,
- -8, 11, -2, 11, 0, 11, 2, 11, 8, 11,
- 19, 12, -19, 13, -4, 13, 4, 13, 0, 14,
- -10, 15, 10, 15, -5, 17, 5, 17, 0, 18,
- -12, 19, 13, 19, -6, 22, 6, 22, 0, 23,
-};
-
-typedef struct SANMVideoContext {
- AVCodecContext *avctx;
- GetByteContext gb;
-
- int version, subversion;
- uint32_t pal[PALETTE_SIZE];
- int16_t delta_pal[PALETTE_DELTA];
-
- int pitch;
- int width, height;
- int aligned_width, aligned_height;
- int prev_seq;
-
- AVFrame *frame;
- uint16_t *frm0, *frm1, *frm2;
- uint8_t *stored_frame;
- uint32_t frm0_size, frm1_size, frm2_size;
- uint32_t stored_frame_size;
-
- uint8_t *rle_buf;
- unsigned int rle_buf_size;
-
- int rotate_code;
-
- long npixels, buf_size;
-
- uint16_t codebook[256];
- uint16_t small_codebook[4];
-
- int8_t p4x4glyphs[NGLYPHS][16];
- int8_t p8x8glyphs[NGLYPHS][64];
-} SANMVideoContext;
-
-typedef struct SANMFrameHeader {
- int seq_num, codec, rotate_code, rle_output_size;
-
- uint16_t bg_color;
- uint32_t width, height;
-} SANMFrameHeader;
-
-enum GlyphEdge {
- LEFT_EDGE,
- TOP_EDGE,
- RIGHT_EDGE,
- BOTTOM_EDGE,
- NO_EDGE
-};
-
-enum GlyphDir {
- DIR_LEFT,
- DIR_UP,
- DIR_RIGHT,
- DIR_DOWN,
- NO_DIR
-};
-
-/**
- * Return enum GlyphEdge of box where point (x, y) lies.
- *
- * @param x x point coordinate
- * @param y y point coordinate
- * @param edge_size box width/height.
- */
-static enum GlyphEdge which_edge(int x, int y, int edge_size)
-{
- const int edge_max = edge_size - 1;
-
- if (!y)
- return BOTTOM_EDGE;
- else if (y == edge_max)
- return TOP_EDGE;
- else if (!x)
- return LEFT_EDGE;
- else if (x == edge_max)
- return RIGHT_EDGE;
- else
- return NO_EDGE;
-}
-
-static enum GlyphDir which_direction(enum GlyphEdge edge0, enum GlyphEdge edge1)
-{
- if ((edge0 == LEFT_EDGE && edge1 == RIGHT_EDGE) ||
- (edge1 == LEFT_EDGE && edge0 == RIGHT_EDGE) ||
- (edge0 == BOTTOM_EDGE && edge1 != TOP_EDGE) ||
- (edge1 == BOTTOM_EDGE && edge0 != TOP_EDGE))
- return DIR_UP;
- else if ((edge0 == TOP_EDGE && edge1 != BOTTOM_EDGE) ||
- (edge1 == TOP_EDGE && edge0 != BOTTOM_EDGE))
- return DIR_DOWN;
- else if ((edge0 == LEFT_EDGE && edge1 != RIGHT_EDGE) ||
- (edge1 == LEFT_EDGE && edge0 != RIGHT_EDGE))
- return DIR_LEFT;
- else if ((edge0 == TOP_EDGE && edge1 == BOTTOM_EDGE) ||
- (edge1 == TOP_EDGE && edge0 == BOTTOM_EDGE) ||
- (edge0 == RIGHT_EDGE && edge1 != LEFT_EDGE) ||
- (edge1 == RIGHT_EDGE && edge0 != LEFT_EDGE))
- return DIR_RIGHT;
-
- return NO_DIR;
-}
-
-/* Interpolate two points. */
-static void interp_point(int8_t *points, int x0, int y0, int x1, int y1,
- int pos, int npoints)
-{
- if (npoints) {
- points[0] = (x0 * pos + x1 * (npoints - pos) + (npoints >> 1)) / npoints;
- points[1] = (y0 * pos + y1 * (npoints - pos) + (npoints >> 1)) / npoints;
- } else {
- points[0] = x0;
- points[1] = y0;
- }
-}
-
-/**
- * Construct glyphs by iterating through vector coordinates.
- *
- * @param pglyphs pointer to table where glyphs are stored
- * @param xvec pointer to x component of vector coordinates
- * @param yvec pointer to y component of vector coordinates
- * @param side_length glyph width/height.
- */
-static void make_glyphs(int8_t *pglyphs, const int8_t *xvec, const int8_t *yvec,
- const int side_length)
-{
- const int glyph_size = side_length * side_length;
- int8_t *pglyph = pglyphs;
-
- int i, j;
- for (i = 0; i < GLYPH_COORD_VECT_SIZE; i++) {
- int x0 = xvec[i];
- int y0 = yvec[i];
- enum GlyphEdge edge0 = which_edge(x0, y0, side_length);
-
- for (j = 0; j < GLYPH_COORD_VECT_SIZE; j++, pglyph += glyph_size) {
- int x1 = xvec[j];
- int y1 = yvec[j];
- enum GlyphEdge edge1 = which_edge(x1, y1, side_length);
- enum GlyphDir dir = which_direction(edge0, edge1);
- int npoints = FFMAX(FFABS(x1 - x0), FFABS(y1 - y0));
- int ipoint;
-
- for (ipoint = 0; ipoint <= npoints; ipoint++) {
- int8_t point[2];
- int irow, icol;
-
- interp_point(point, x0, y0, x1, y1, ipoint, npoints);
-
- switch (dir) {
- case DIR_UP:
- for (irow = point[1]; irow >= 0; irow--)
- pglyph[point[0] + irow * side_length] = 1;
- break;
-
- case DIR_DOWN:
- for (irow = point[1]; irow < side_length; irow++)
- pglyph[point[0] + irow * side_length] = 1;
- break;
-
- case DIR_LEFT:
- for (icol = point[0]; icol >= 0; icol--)
- pglyph[icol + point[1] * side_length] = 1;
- break;
-
- case DIR_RIGHT:
- for (icol = point[0]; icol < side_length; icol++)
- pglyph[icol + point[1] * side_length] = 1;
- break;
- }
- }
- }
- }
-}
-
-static void init_sizes(SANMVideoContext *ctx, int width, int height)
-{
- ctx->width = width;
- ctx->height = height;
- ctx->npixels = width * height;
-
- ctx->aligned_width = FFALIGN(width, 8);
- ctx->aligned_height = FFALIGN(height, 8);
-
- ctx->buf_size = ctx->aligned_width * ctx->aligned_height * sizeof(ctx->frm0[0]);
- ctx->pitch = width;
-}
-
-static void destroy_buffers(SANMVideoContext *ctx)
-{
- av_freep(&ctx->frm0);
- av_freep(&ctx->frm1);
- av_freep(&ctx->frm2);
- av_freep(&ctx->stored_frame);
- av_freep(&ctx->rle_buf);
- ctx->frm0_size =
- ctx->frm1_size =
- ctx->frm2_size = 0;
- init_sizes(ctx, 0, 0);
-}
-
-static av_cold int init_buffers(SANMVideoContext *ctx)
-{
- av_fast_padded_malloc(&ctx->frm0, &ctx->frm0_size, ctx->buf_size);
- av_fast_padded_malloc(&ctx->frm1, &ctx->frm1_size, ctx->buf_size);
- av_fast_padded_malloc(&ctx->frm2, &ctx->frm2_size, ctx->buf_size);
- if (!ctx->version)
- av_fast_padded_malloc(&ctx->stored_frame,
- &ctx->stored_frame_size, ctx->buf_size);
-
- if (!ctx->frm0 || !ctx->frm1 || !ctx->frm2 ||
- (!ctx->stored_frame && !ctx->version)) {
- destroy_buffers(ctx);
- return AVERROR(ENOMEM);
- }
-
- return 0;
-}
-
-static void rotate_bufs(SANMVideoContext *ctx, int rotate_code)
-{
- if (rotate_code == 2)
- FFSWAP(uint16_t*, ctx->frm1, ctx->frm2);
- FFSWAP(uint16_t*, ctx->frm2, ctx->frm0);
-}
-
-static av_cold int decode_init(AVCodecContext *avctx)
-{
- SANMVideoContext *ctx = avctx->priv_data;
-
- ctx->avctx = avctx;
- ctx->version = !avctx->extradata_size;
-
- avctx->pix_fmt = ctx->version ? AV_PIX_FMT_RGB565 : AV_PIX_FMT_PAL8;
-
- init_sizes(ctx, avctx->width, avctx->height);
- if (init_buffers(ctx)) {
- av_log(avctx, AV_LOG_ERROR, "Error allocating buffers.\n");
- return AVERROR(ENOMEM);
- }
-
- make_glyphs(ctx->p4x4glyphs[0], glyph4_x, glyph4_y, 4);
- make_glyphs(ctx->p8x8glyphs[0], glyph8_x, glyph8_y, 8);
-
- if (!ctx->version) {
- int i;
-
- if (avctx->extradata_size < 1026) {
- av_log(avctx, AV_LOG_ERROR, "Not enough extradata.\n");
- return AVERROR_INVALIDDATA;
- }
-
- ctx->subversion = AV_RL16(avctx->extradata);
- for (i = 0; i < PALETTE_SIZE; i++)
- ctx->pal[i] = 0xFFU << 24 | AV_RL32(avctx->extradata + 2 + i * 4);
- }
-
- return 0;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx)
-{
- SANMVideoContext *ctx = avctx->priv_data;
-
- destroy_buffers(ctx);
-
- return 0;
-}
-
-static int rle_decode(SANMVideoContext *ctx, uint8_t *dst, const int out_size)
-{
- int opcode, color, run_len, left = out_size;
-
- while (left > 0) {
- opcode = bytestream2_get_byte(&ctx->gb);
- run_len = (opcode >> 1) + 1;
- if (run_len > left || bytestream2_get_bytes_left(&ctx->gb) <= 0)
- return AVERROR_INVALIDDATA;
-
- if (opcode & 1) {
- color = bytestream2_get_byte(&ctx->gb);
- memset(dst, color, run_len);
- } else {
- if (bytestream2_get_bytes_left(&ctx->gb) < run_len)
- return AVERROR_INVALIDDATA;
- bytestream2_get_bufferu(&ctx->gb, dst, run_len);
- }
-
- dst += run_len;
- left -= run_len;
- }
-
- return 0;
-}
-
-static int old_codec1(SANMVideoContext *ctx, int top,
- int left, int width, int height)
-{
- uint8_t *dst = ((uint8_t *)ctx->frm0) + left + top * ctx->pitch;
- int i, j, len, flag, code, val, pos, end;
-
- for (i = 0; i < height; i++) {
- pos = 0;
-
- if (bytestream2_get_bytes_left(&ctx->gb) < 2)
- return AVERROR_INVALIDDATA;
-
- len = bytestream2_get_le16u(&ctx->gb);
- end = bytestream2_tell(&ctx->gb) + len;
-
- while (bytestream2_tell(&ctx->gb) < end) {
- if (bytestream2_get_bytes_left(&ctx->gb) < 2)
- return AVERROR_INVALIDDATA;
-
- code = bytestream2_get_byteu(&ctx->gb);
- flag = code & 1;
- code = (code >> 1) + 1;
- if (pos + code > width)
- return AVERROR_INVALIDDATA;
- if (flag) {
- val = bytestream2_get_byteu(&ctx->gb);
- if (val)
- memset(dst + pos, val, code);
- pos += code;
- } else {
- if (bytestream2_get_bytes_left(&ctx->gb) < code)
- return AVERROR_INVALIDDATA;
- for (j = 0; j < code; j++) {
- val = bytestream2_get_byteu(&ctx->gb);
- if (val)
- dst[pos] = val;
- pos++;
- }
- }
- }
- dst += ctx->pitch;
- }
- ctx->rotate_code = 0;
-
- return 0;
-}
-
-static inline void codec37_mv(uint8_t *dst, const uint8_t *src,
- int height, int stride, int x, int y)
-{
- int pos, i, j;
-
- pos = x + y * stride;
- for (j = 0; j < 4; j++) {
- for (i = 0; i < 4; i++) {
- if ((pos + i) < 0 || (pos + i) >= height * stride)
- dst[i] = 0;
- else
- dst[i] = src[i];
- }
- dst += stride;
- src += stride;
- pos += stride;
- }
-}
-
-static int old_codec37(SANMVideoContext *ctx, int top,
- int left, int width, int height)
-{
- int stride = ctx->pitch;
- int i, j, k, t;
- uint8_t *dst, *prev;
- int skip_run = 0;
- int compr = bytestream2_get_byte(&ctx->gb);
- int mvoff = bytestream2_get_byte(&ctx->gb);
- int seq = bytestream2_get_le16(&ctx->gb);
- uint32_t decoded_size = bytestream2_get_le32(&ctx->gb);
- int flags;
-
- bytestream2_skip(&ctx->gb, 4);
- flags = bytestream2_get_byte(&ctx->gb);
- bytestream2_skip(&ctx->gb, 3);
-
- if (decoded_size > ctx->height * stride - left - top * stride) {
- decoded_size = ctx->height * stride - left - top * stride;
- av_log(ctx->avctx, AV_LOG_WARNING, "Decoded size is too large.\n");
- }
-
- ctx->rotate_code = 0;
-
- if (((seq & 1) || !(flags & 1)) && (compr && compr != 2))
- rotate_bufs(ctx, 1);
-
- dst = ((uint8_t*)ctx->frm0) + left + top * stride;
- prev = ((uint8_t*)ctx->frm2) + left + top * stride;
-
- if (mvoff > 2) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Invalid motion base value %d.\n", mvoff);
- return AVERROR_INVALIDDATA;
- }
-
- switch (compr) {
- case 0:
- for (i = 0; i < height; i++) {
- bytestream2_get_buffer(&ctx->gb, dst, width);
- dst += stride;
- }
- memset(ctx->frm1, 0, ctx->height * stride);
- memset(ctx->frm2, 0, ctx->height * stride);
- break;
- case 2:
- if (rle_decode(ctx, dst, decoded_size))
- return AVERROR_INVALIDDATA;
- memset(ctx->frm1, 0, ctx->frm1_size);
- memset(ctx->frm2, 0, ctx->frm2_size);
- break;
- case 3:
- case 4:
- if (flags & 4) {
- for (j = 0; j < height; j += 4) {
- for (i = 0; i < width; i += 4) {
- int code;
- if (skip_run) {
- skip_run--;
- copy_block4(dst + i, prev + i, stride, stride, 4);
- continue;
- }
- if (bytestream2_get_bytes_left(&ctx->gb) < 1)
- return AVERROR_INVALIDDATA;
- code = bytestream2_get_byteu(&ctx->gb);
- switch (code) {
- case 0xFF:
- if (bytestream2_get_bytes_left(&ctx->gb) < 16)
- return AVERROR_INVALIDDATA;
- for (k = 0; k < 4; k++)
- bytestream2_get_bufferu(&ctx->gb, dst + i + k * stride, 4);
- break;
- case 0xFE:
- if (bytestream2_get_bytes_left(&ctx->gb) < 4)
- return AVERROR_INVALIDDATA;
- for (k = 0; k < 4; k++)
- memset(dst + i + k * stride, bytestream2_get_byteu(&ctx->gb), 4);
- break;
- case 0xFD:
- if (bytestream2_get_bytes_left(&ctx->gb) < 1)
- return AVERROR_INVALIDDATA;
- t = bytestream2_get_byteu(&ctx->gb);
- for (k = 0; k < 4; k++)
- memset(dst + i + k * stride, t, 4);
- break;
- default:
- if (compr == 4 && !code) {
- if (bytestream2_get_bytes_left(&ctx->gb) < 1)
- return AVERROR_INVALIDDATA;
- skip_run = bytestream2_get_byteu(&ctx->gb) + 1;
- i -= 4;
- } else {
- int mx, my;
-
- mx = c37_mv[(mvoff * 255 + code) * 2];
- my = c37_mv[(mvoff * 255 + code) * 2 + 1];
- codec37_mv(dst + i, prev + i + mx + my * stride,
- ctx->height, stride, i + mx, j + my);
- }
- }
- }
- dst += stride * 4;
- prev += stride * 4;
- }
- } else {
- for (j = 0; j < height; j += 4) {
- for (i = 0; i < width; i += 4) {
- int code;
- if (skip_run) {
- skip_run--;
- copy_block4(dst + i, prev + i, stride, stride, 4);
- continue;
- }
- code = bytestream2_get_byte(&ctx->gb);
- if (code == 0xFF) {
- if (bytestream2_get_bytes_left(&ctx->gb) < 16)
- return AVERROR_INVALIDDATA;
- for (k = 0; k < 4; k++)
- bytestream2_get_bufferu(&ctx->gb, dst + i + k * stride, 4);
- } else if (compr == 4 && !code) {
- if (bytestream2_get_bytes_left(&ctx->gb) < 1)
- return AVERROR_INVALIDDATA;
- skip_run = bytestream2_get_byteu(&ctx->gb) + 1;
- i -= 4;
- } else {
- int mx, my;
-
- mx = c37_mv[(mvoff * 255 + code) * 2];
- my = c37_mv[(mvoff * 255 + code) * 2 + 1];
- codec37_mv(dst + i, prev + i + mx + my * stride,
- ctx->height, stride, i + mx, j + my);
- }
- }
- dst += stride * 4;
- prev += stride * 4;
- }
- }
- break;
- default:
- avpriv_report_missing_feature(ctx->avctx,
- "Subcodec 37 compression %d", compr);
- return AVERROR_PATCHWELCOME;
- }
-
- return 0;
-}
-
-static int process_block(SANMVideoContext *ctx, uint8_t *dst, uint8_t *prev1,
- uint8_t *prev2, int stride, int tbl, int size)
-{
- int code, k, t;
- uint8_t colors[2];
- int8_t *pglyph;
-
- if (bytestream2_get_bytes_left(&ctx->gb) < 1)
- return AVERROR_INVALIDDATA;
-
- code = bytestream2_get_byteu(&ctx->gb);
- if (code >= 0xF8) {
- switch (code) {
- case 0xFF:
- if (size == 2) {
- if (bytestream2_get_bytes_left(&ctx->gb) < 4)
- return AVERROR_INVALIDDATA;
- dst[0] = bytestream2_get_byteu(&ctx->gb);
- dst[1] = bytestream2_get_byteu(&ctx->gb);
- dst[0 + stride] = bytestream2_get_byteu(&ctx->gb);
- dst[1 + stride] = bytestream2_get_byteu(&ctx->gb);
- } else {
- size >>= 1;
- if (process_block(ctx, dst, prev1, prev2, stride, tbl, size))
- return AVERROR_INVALIDDATA;
- if (process_block(ctx, dst + size, prev1 + size, prev2 + size,
- stride, tbl, size))
- return AVERROR_INVALIDDATA;
- dst += size * stride;
- prev1 += size * stride;
- prev2 += size * stride;
- if (process_block(ctx, dst, prev1, prev2, stride, tbl, size))
- return AVERROR_INVALIDDATA;
- if (process_block(ctx, dst + size, prev1 + size, prev2 + size,
- stride, tbl, size))
- return AVERROR_INVALIDDATA;
- }
- break;
- case 0xFE:
- if (bytestream2_get_bytes_left(&ctx->gb) < 1)
- return AVERROR_INVALIDDATA;
-
- t = bytestream2_get_byteu(&ctx->gb);
- for (k = 0; k < size; k++)
- memset(dst + k * stride, t, size);
- break;
- case 0xFD:
- if (bytestream2_get_bytes_left(&ctx->gb) < 3)
- return AVERROR_INVALIDDATA;
-
- code = bytestream2_get_byteu(&ctx->gb);
- pglyph = (size == 8) ? ctx->p8x8glyphs[code] : ctx->p4x4glyphs[code];
- bytestream2_get_bufferu(&ctx->gb, colors, 2);
-
- for (k = 0; k < size; k++)
- for (t = 0; t < size; t++)
- dst[t + k * stride] = colors[!*pglyph++];
- break;
- case 0xFC:
- for (k = 0; k < size; k++)
- memcpy(dst + k * stride, prev1 + k * stride, size);
- break;
- default:
- k = bytestream2_tell(&ctx->gb);
- bytestream2_seek(&ctx->gb, tbl + (code & 7), SEEK_SET);
- t = bytestream2_get_byte(&ctx->gb);
- bytestream2_seek(&ctx->gb, k, SEEK_SET);
- for (k = 0; k < size; k++)
- memset(dst + k * stride, t, size);
- }
- } else {
- int mx = motion_vectors[code][0];
- int my = motion_vectors[code][1];
- int index = prev2 - (const uint8_t *)ctx->frm2;
-
- av_assert2(index >= 0 && index < (ctx->buf_size >> 1));
-
- if (index < -mx - my * stride ||
- (ctx->buf_size >> 1) - index < mx + size + (my + size - 1) * stride) {
- av_log(ctx->avctx, AV_LOG_ERROR, "MV is invalid.\n");
- return AVERROR_INVALIDDATA;
- }
-
- for (k = 0; k < size; k++)
- memcpy(dst + k * stride, prev2 + mx + (my + k) * stride, size);
- }
-
- return 0;
-}
-
-static int old_codec47(SANMVideoContext *ctx, int top,
- int left, int width, int height)
-{
- uint32_t decoded_size;
- int i, j;
- int stride = ctx->pitch;
- uint8_t *dst = (uint8_t *)ctx->frm0 + left + top * stride;
- uint8_t *prev1 = (uint8_t *)ctx->frm1;
- uint8_t *prev2 = (uint8_t *)ctx->frm2;
- int tbl_pos = bytestream2_tell(&ctx->gb);
- int seq = bytestream2_get_le16(&ctx->gb);
- int compr = bytestream2_get_byte(&ctx->gb);
- int new_rot = bytestream2_get_byte(&ctx->gb);
- int skip = bytestream2_get_byte(&ctx->gb);
-
- bytestream2_skip(&ctx->gb, 9);
- decoded_size = bytestream2_get_le32(&ctx->gb);
- bytestream2_skip(&ctx->gb, 8);
-
- if (decoded_size > ctx->height * stride - left - top * stride) {
- decoded_size = ctx->height * stride - left - top * stride;
- av_log(ctx->avctx, AV_LOG_WARNING, "Decoded size is too large.\n");
- }
-
- if (skip & 1)
- bytestream2_skip(&ctx->gb, 0x8080);
- if (!seq) {
- ctx->prev_seq = -1;
- memset(prev1, 0, ctx->height * stride);
- memset(prev2, 0, ctx->height * stride);
- }
-
- switch (compr) {
- case 0:
- if (bytestream2_get_bytes_left(&ctx->gb) < width * height)
- return AVERROR_INVALIDDATA;
- for (j = 0; j < height; j++) {
- bytestream2_get_bufferu(&ctx->gb, dst, width);
- dst += stride;
- }
- break;
- case 1:
- if (bytestream2_get_bytes_left(&ctx->gb) < ((width + 1) >> 1) * ((height + 1) >> 1))
- return AVERROR_INVALIDDATA;
- for (j = 0; j < height; j += 2) {
- for (i = 0; i < width; i += 2) {
- dst[i] =
- dst[i + 1] =
- dst[stride + i] =
- dst[stride + i + 1] = bytestream2_get_byteu(&ctx->gb);
- }
- dst += stride * 2;
- }
- break;
- case 2:
- if (seq == ctx->prev_seq + 1) {
- for (j = 0; j < height; j += 8) {
- for (i = 0; i < width; i += 8)
- if (process_block(ctx, dst + i, prev1 + i, prev2 + i, stride,
- tbl_pos + 8, 8))
- return AVERROR_INVALIDDATA;
- dst += stride * 8;
- prev1 += stride * 8;
- prev2 += stride * 8;
- }
- }
- break;
- case 3:
- memcpy(ctx->frm0, ctx->frm2, ctx->pitch * ctx->height);
- break;
- case 4:
- memcpy(ctx->frm0, ctx->frm1, ctx->pitch * ctx->height);
- break;
- case 5:
- if (rle_decode(ctx, dst, decoded_size))
- return AVERROR_INVALIDDATA;
- break;
- default:
- avpriv_report_missing_feature(ctx->avctx,
- "Subcodec 47 compression %d", compr);
- return AVERROR_PATCHWELCOME;
- }
- if (seq == ctx->prev_seq + 1)
- ctx->rotate_code = new_rot;
- else
- ctx->rotate_code = 0;
- ctx->prev_seq = seq;
-
- return 0;
-}
-
-static int process_frame_obj(SANMVideoContext *ctx)
-{
- uint16_t codec = bytestream2_get_le16u(&ctx->gb);
- uint16_t left = bytestream2_get_le16u(&ctx->gb);
- uint16_t top = bytestream2_get_le16u(&ctx->gb);
- uint16_t w = bytestream2_get_le16u(&ctx->gb);
- uint16_t h = bytestream2_get_le16u(&ctx->gb);
-
- if (!w || !h) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Dimensions are invalid.\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (ctx->width < left + w || ctx->height < top + h) {
- int ret = ff_set_dimensions(ctx->avctx, FFMAX(left + w, ctx->width),
- FFMAX(top + h, ctx->height));
- if (ret < 0)
- return ret;
- init_sizes(ctx, FFMAX(left + w, ctx->width),
- FFMAX(top + h, ctx->height));
- if (init_buffers(ctx)) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Error resizing buffers.\n");
- return AVERROR(ENOMEM);
- }
- }
- bytestream2_skip(&ctx->gb, 4);
-
- switch (codec) {
- case 1:
- case 3:
- return old_codec1(ctx, top, left, w, h);
- break;
- case 37:
- return old_codec37(ctx, top, left, w, h);
- break;
- case 47:
- return old_codec47(ctx, top, left, w, h);
- break;
- default:
- avpriv_request_sample(ctx->avctx, "Subcodec %d", codec);
- return AVERROR_PATCHWELCOME;
- }
-}
-
-static int decode_0(SANMVideoContext *ctx)
-{
- uint16_t *frm = ctx->frm0;
- int x, y;
-
- if (bytestream2_get_bytes_left(&ctx->gb) < ctx->width * ctx->height * 2) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Insufficient data for raw frame.\n");
- return AVERROR_INVALIDDATA;
- }
- for (y = 0; y < ctx->height; y++) {
- for (x = 0; x < ctx->width; x++)
- frm[x] = bytestream2_get_le16u(&ctx->gb);
- frm += ctx->pitch;
- }
- return 0;
-}
-
-static int decode_nop(SANMVideoContext *ctx)
-{
- avpriv_request_sample(ctx->avctx, "Unknown/unsupported compression type");
- return AVERROR_PATCHWELCOME;
-}
-
-static void copy_block(uint16_t *pdest, uint16_t *psrc, int block_size, int pitch)
-{
- uint8_t *dst = (uint8_t *)pdest;
- uint8_t *src = (uint8_t *)psrc;
- int stride = pitch * 2;
-
- switch (block_size) {
- case 2:
- copy_block4(dst, src, stride, stride, 2);
- break;
- case 4:
- copy_block8(dst, src, stride, stride, 4);
- break;
- case 8:
- copy_block16(dst, src, stride, stride, 8);
- break;
- }
-}
-
-static void fill_block(uint16_t *pdest, uint16_t color, int block_size, int pitch)
-{
- int x, y;
-
- pitch -= block_size;
- for (y = 0; y < block_size; y++, pdest += pitch)
- for (x = 0; x < block_size; x++)
- *pdest++ = color;
-}
-
-static int draw_glyph(SANMVideoContext *ctx, uint16_t *dst, int index,
- uint16_t fg_color, uint16_t bg_color, int block_size,
- int pitch)
-{
- int8_t *pglyph;
- uint16_t colors[2] = { fg_color, bg_color };
- int x, y;
-
- if (index >= NGLYPHS) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Ignoring nonexistent glyph #%u.\n", index);
- return AVERROR_INVALIDDATA;
- }
-
- pglyph = block_size == 8 ? ctx->p8x8glyphs[index] : ctx->p4x4glyphs[index];
- pitch -= block_size;
-
- for (y = 0; y < block_size; y++, dst += pitch)
- for (x = 0; x < block_size; x++)
- *dst++ = colors[*pglyph++];
- return 0;
-}
-
-static int opcode_0xf7(SANMVideoContext *ctx, int cx, int cy, int block_size, int pitch)
-{
- uint16_t *dst = ctx->frm0 + cx + cy * ctx->pitch;
-
- if (block_size == 2) {
- uint32_t indices;
-
- if (bytestream2_get_bytes_left(&ctx->gb) < 4)
- return AVERROR_INVALIDDATA;
-
- indices = bytestream2_get_le32u(&ctx->gb);
- dst[0] = ctx->codebook[indices & 0xFF];
- indices >>= 8;
- dst[1] = ctx->codebook[indices & 0xFF];
- indices >>= 8;
- dst[pitch] = ctx->codebook[indices & 0xFF];
- indices >>= 8;
- dst[pitch + 1] = ctx->codebook[indices & 0xFF];
- } else {
- uint16_t fgcolor, bgcolor;
- int glyph;
-
- if (bytestream2_get_bytes_left(&ctx->gb) < 3)
- return AVERROR_INVALIDDATA;
-
- glyph = bytestream2_get_byteu(&ctx->gb);
- bgcolor = ctx->codebook[bytestream2_get_byteu(&ctx->gb)];
- fgcolor = ctx->codebook[bytestream2_get_byteu(&ctx->gb)];
-
- draw_glyph(ctx, dst, glyph, fgcolor, bgcolor, block_size, pitch);
- }
- return 0;
-}
-
-static int opcode_0xf8(SANMVideoContext *ctx, int cx, int cy, int block_size, int pitch)
-{
- uint16_t *dst = ctx->frm0 + cx + cy * ctx->pitch;
-
- if (block_size == 2) {
- if (bytestream2_get_bytes_left(&ctx->gb) < 8)
- return AVERROR_INVALIDDATA;
-
- dst[0] = bytestream2_get_le16u(&ctx->gb);
- dst[1] = bytestream2_get_le16u(&ctx->gb);
- dst[pitch] = bytestream2_get_le16u(&ctx->gb);
- dst[pitch + 1] = bytestream2_get_le16u(&ctx->gb);
- } else {
- uint16_t fgcolor, bgcolor;
- int glyph;
-
- if (bytestream2_get_bytes_left(&ctx->gb) < 5)
- return AVERROR_INVALIDDATA;
-
- glyph = bytestream2_get_byteu(&ctx->gb);
- bgcolor = bytestream2_get_le16u(&ctx->gb);
- fgcolor = bytestream2_get_le16u(&ctx->gb);
-
- draw_glyph(ctx, dst, glyph, fgcolor, bgcolor, block_size, pitch);
- }
- return 0;
-}
-
-static int good_mvec(SANMVideoContext *ctx, int cx, int cy, int mx, int my,
- int block_size)
-{
- int start_pos = cx + mx + (cy + my) * ctx->pitch;
- int end_pos = start_pos + (block_size - 1) * (ctx->pitch + 1);
-
- int good = start_pos >= 0 && end_pos < (ctx->buf_size >> 1);
-
- if (!good)
- av_log(ctx->avctx, AV_LOG_ERROR,
- "Ignoring invalid motion vector (%i, %i)->(%u, %u), block size = %u\n",
- cx + mx, cy + my, cx, cy, block_size);
-
- return good;
-}
-
-static int codec2subblock(SANMVideoContext *ctx, int cx, int cy, int blk_size)
-{
- int16_t mx, my, index;
- int opcode;
-
- if (bytestream2_get_bytes_left(&ctx->gb) < 1)
- return AVERROR_INVALIDDATA;
-
- opcode = bytestream2_get_byteu(&ctx->gb);
-
- switch (opcode) {
- default:
- mx = motion_vectors[opcode][0];
- my = motion_vectors[opcode][1];
-
- if (good_mvec(ctx, cx, cy, mx, my, blk_size)) {
- copy_block(ctx->frm0 + cx + ctx->pitch * cy,
- ctx->frm2 + cx + mx + ctx->pitch * (cy + my),
- blk_size, ctx->pitch);
- }
- break;
- case 0xF5:
- if (bytestream2_get_bytes_left(&ctx->gb) < 2)
- return AVERROR_INVALIDDATA;
- index = bytestream2_get_le16u(&ctx->gb);
-
- mx = index % ctx->width;
- my = index / ctx->width;
-
- if (good_mvec(ctx, cx, cy, mx, my, blk_size)) {
- copy_block(ctx->frm0 + cx + ctx->pitch * cy,
- ctx->frm2 + cx + mx + ctx->pitch * (cy + my),
- blk_size, ctx->pitch);
- }
- break;
- case 0xF6:
- copy_block(ctx->frm0 + cx + ctx->pitch * cy,
- ctx->frm1 + cx + ctx->pitch * cy,
- blk_size, ctx->pitch);
- break;
- case 0xF7:
- opcode_0xf7(ctx, cx, cy, blk_size, ctx->pitch);
- break;
-
- case 0xF8:
- opcode_0xf8(ctx, cx, cy, blk_size, ctx->pitch);
- break;
- case 0xF9:
- case 0xFA:
- case 0xFB:
- case 0xFC:
- fill_block(ctx->frm0 + cx + cy * ctx->pitch,
- ctx->small_codebook[opcode - 0xf9], blk_size, ctx->pitch);
- break;
- case 0xFD:
- if (bytestream2_get_bytes_left(&ctx->gb) < 1)
- return AVERROR_INVALIDDATA;
- fill_block(ctx->frm0 + cx + cy * ctx->pitch,
- ctx->codebook[bytestream2_get_byteu(&ctx->gb)], blk_size, ctx->pitch);
- break;
- case 0xFE:
- if (bytestream2_get_bytes_left(&ctx->gb) < 2)
- return AVERROR_INVALIDDATA;
- fill_block(ctx->frm0 + cx + cy * ctx->pitch,
- bytestream2_get_le16u(&ctx->gb), blk_size, ctx->pitch);
- break;
- case 0xFF:
- if (blk_size == 2) {
- opcode_0xf8(ctx, cx, cy, blk_size, ctx->pitch);
- } else {
- blk_size >>= 1;
- if (codec2subblock(ctx, cx, cy, blk_size))
- return AVERROR_INVALIDDATA;
- if (codec2subblock(ctx, cx + blk_size, cy, blk_size))
- return AVERROR_INVALIDDATA;
- if (codec2subblock(ctx, cx, cy + blk_size, blk_size))
- return AVERROR_INVALIDDATA;
- if (codec2subblock(ctx, cx + blk_size, cy + blk_size, blk_size))
- return AVERROR_INVALIDDATA;
- }
- break;
- }
- return 0;
-}
-
-static int decode_2(SANMVideoContext *ctx)
-{
- int cx, cy, ret;
-
- for (cy = 0; cy < ctx->aligned_height; cy += 8)
- for (cx = 0; cx < ctx->aligned_width; cx += 8)
- if (ret = codec2subblock(ctx, cx, cy, 8))
- return ret;
-
- return 0;
-}
-
-static int decode_3(SANMVideoContext *ctx)
-{
- memcpy(ctx->frm0, ctx->frm2, ctx->frm2_size);
- return 0;
-}
-
-static int decode_4(SANMVideoContext *ctx)
-{
- memcpy(ctx->frm0, ctx->frm1, ctx->frm1_size);
- return 0;
-}
-
-static int decode_5(SANMVideoContext *ctx)
-{
-#if HAVE_BIGENDIAN
- uint16_t *frm;
- int npixels;
-#endif
- uint8_t *dst = (uint8_t*)ctx->frm0;
-
- if (rle_decode(ctx, dst, ctx->buf_size))
- return AVERROR_INVALIDDATA;
-
-#if HAVE_BIGENDIAN
- npixels = ctx->npixels;
- frm = ctx->frm0;
- while (npixels--) {
- *frm = av_bswap16(*frm);
- frm++;
- }
-#endif
-
- return 0;
-}
-
-static int decode_6(SANMVideoContext *ctx)
-{
- int npixels = ctx->npixels;
- uint16_t *frm = ctx->frm0;
-
- if (bytestream2_get_bytes_left(&ctx->gb) < npixels) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Insufficient data for frame.\n");
- return AVERROR_INVALIDDATA;
- }
- while (npixels--)
- *frm++ = ctx->codebook[bytestream2_get_byteu(&ctx->gb)];
-
- return 0;
-}
-
-static int decode_8(SANMVideoContext *ctx)
-{
- uint16_t *pdest = ctx->frm0;
- uint8_t *rsrc;
- long npixels = ctx->npixels;
-
- av_fast_malloc(&ctx->rle_buf, &ctx->rle_buf_size, npixels);
- if (!ctx->rle_buf) {
- av_log(ctx->avctx, AV_LOG_ERROR, "RLE buffer allocation failed.\n");
- return AVERROR(ENOMEM);
- }
- rsrc = ctx->rle_buf;
-
- if (rle_decode(ctx, rsrc, npixels))
- return AVERROR_INVALIDDATA;
-
- while (npixels--)
- *pdest++ = ctx->codebook[*rsrc++];
-
- return 0;
-}
-
-typedef int (*frm_decoder)(SANMVideoContext *ctx);
-
-static const frm_decoder v1_decoders[] = {
- decode_0, decode_nop, decode_2, decode_3, decode_4, decode_5,
- decode_6, decode_nop, decode_8
-};
-
-static int read_frame_header(SANMVideoContext *ctx, SANMFrameHeader *hdr)
-{
- int i, ret;
-
- if ((ret = bytestream2_get_bytes_left(&ctx->gb)) < 560) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Input frame too short (%d bytes).\n",
- ret);
- return AVERROR_INVALIDDATA;
- }
- bytestream2_skip(&ctx->gb, 8); // skip pad
-
- hdr->width = bytestream2_get_le32u(&ctx->gb);
- hdr->height = bytestream2_get_le32u(&ctx->gb);
-
- if (hdr->width != ctx->width || hdr->height != ctx->height) {
- avpriv_report_missing_feature(ctx->avctx, "Variable size frames");
- return AVERROR_PATCHWELCOME;
- }
-
- hdr->seq_num = bytestream2_get_le16u(&ctx->gb);
- hdr->codec = bytestream2_get_byteu(&ctx->gb);
- hdr->rotate_code = bytestream2_get_byteu(&ctx->gb);
-
- bytestream2_skip(&ctx->gb, 4); // skip pad
-
- for (i = 0; i < 4; i++)
- ctx->small_codebook[i] = bytestream2_get_le16u(&ctx->gb);
- hdr->bg_color = bytestream2_get_le16u(&ctx->gb);
-
- bytestream2_skip(&ctx->gb, 2); // skip pad
-
- hdr->rle_output_size = bytestream2_get_le32u(&ctx->gb);
- for (i = 0; i < 256; i++)
- ctx->codebook[i] = bytestream2_get_le16u(&ctx->gb);
-
- bytestream2_skip(&ctx->gb, 8); // skip pad
-
- return 0;
-}
-
-static void fill_frame(uint16_t *pbuf, int buf_size, uint16_t color)
-{
- while (buf_size--)
- *pbuf++ = color;
-}
-
-static int copy_output(SANMVideoContext *ctx, SANMFrameHeader *hdr)
-{
- uint8_t *dst;
- const uint8_t *src = (uint8_t*) ctx->frm0;
- int ret, dstpitch, height = ctx->height;
- int srcpitch = ctx->pitch * (hdr ? sizeof(ctx->frm0[0]) : 1);
-
- if ((ret = ff_get_buffer(ctx->avctx, ctx->frame, 0)) < 0)
- return ret;
-
- dst = ctx->frame->data[0];
- dstpitch = ctx->frame->linesize[0];
-
- while (height--) {
- memcpy(dst, src, srcpitch);
- src += srcpitch;
- dst += dstpitch;
- }
-
- return 0;
-}
-
-static int decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, AVPacket *pkt)
-{
- SANMVideoContext *ctx = avctx->priv_data;
- int i, ret;
-
- ctx->frame = data;
- bytestream2_init(&ctx->gb, pkt->data, pkt->size);
-
- if (!ctx->version) {
- int to_store = 0;
-
- while (bytestream2_get_bytes_left(&ctx->gb) >= 8) {
- uint32_t sig, size;
- int pos;
-
- sig = bytestream2_get_be32u(&ctx->gb);
- size = bytestream2_get_be32u(&ctx->gb);
- pos = bytestream2_tell(&ctx->gb);
-
- if (bytestream2_get_bytes_left(&ctx->gb) < size) {
- av_log(avctx, AV_LOG_ERROR, "Incorrect chunk size %"PRIu32".\n", size);
- break;
- }
- switch (sig) {
- case MKBETAG('N', 'P', 'A', 'L'):
- if (size != PALETTE_SIZE * 3) {
- av_log(avctx, AV_LOG_ERROR,
- "Incorrect palette block size %"PRIu32".\n", size);
- return AVERROR_INVALIDDATA;
- }
- for (i = 0; i < PALETTE_SIZE; i++)
- ctx->pal[i] = 0xFFU << 24 | bytestream2_get_be24u(&ctx->gb);
- break;
- case MKBETAG('F', 'O', 'B', 'J'):
- if (size < 16)
- return AVERROR_INVALIDDATA;
- if (ret = process_frame_obj(ctx))
- return ret;
- break;
- case MKBETAG('X', 'P', 'A', 'L'):
- if (size == 6 || size == 4) {
- uint8_t tmp[3];
- int j;
-
- for (i = 0; i < PALETTE_SIZE; i++) {
- for (j = 0; j < 3; j++) {
- int t = (ctx->pal[i] >> (16 - j * 8)) & 0xFF;
- tmp[j] = av_clip_uint8((t * 129 + ctx->delta_pal[i * 3 + j]) >> 7);
- }
- ctx->pal[i] = 0xFFU << 24 | AV_RB24(tmp);
- }
- } else {
- if (size < PALETTE_DELTA * 2 + 4) {
- av_log(avctx, AV_LOG_ERROR,
- "Incorrect palette change block size %"PRIu32".\n",
- size);
- return AVERROR_INVALIDDATA;
- }
- bytestream2_skipu(&ctx->gb, 4);
- for (i = 0; i < PALETTE_DELTA; i++)
- ctx->delta_pal[i] = bytestream2_get_le16u(&ctx->gb);
- if (size >= PALETTE_DELTA * 5 + 4) {
- for (i = 0; i < PALETTE_SIZE; i++)
- ctx->pal[i] = 0xFFU << 24 | bytestream2_get_be24u(&ctx->gb);
- } else {
- memset(ctx->pal, 0, sizeof(ctx->pal));
- }
- }
- break;
- case MKBETAG('S', 'T', 'O', 'R'):
- to_store = 1;
- break;
- case MKBETAG('F', 'T', 'C', 'H'):
- memcpy(ctx->frm0, ctx->stored_frame, ctx->buf_size);
- break;
- default:
- bytestream2_skip(&ctx->gb, size);
- av_log(avctx, AV_LOG_DEBUG,
- "Unknown/unsupported chunk %"PRIx32".\n", sig);
- break;
- }
-
- bytestream2_seek(&ctx->gb, pos + size, SEEK_SET);
- if (size & 1)
- bytestream2_skip(&ctx->gb, 1);
- }
- if (to_store)
- memcpy(ctx->stored_frame, ctx->frm0, ctx->buf_size);
- if ((ret = copy_output(ctx, NULL)))
- return ret;
- memcpy(ctx->frame->data[1], ctx->pal, 1024);
- } else {
- SANMFrameHeader header;
-
- if ((ret = read_frame_header(ctx, &header)))
- return ret;
-
- ctx->rotate_code = header.rotate_code;
- if ((ctx->frame->key_frame = !header.seq_num)) {
- ctx->frame->pict_type = AV_PICTURE_TYPE_I;
- fill_frame(ctx->frm1, ctx->npixels, header.bg_color);
- fill_frame(ctx->frm2, ctx->npixels, header.bg_color);
- } else {
- ctx->frame->pict_type = AV_PICTURE_TYPE_P;
- }
-
- if (header.codec < FF_ARRAY_ELEMS(v1_decoders)) {
- if ((ret = v1_decoders[header.codec](ctx))) {
- av_log(avctx, AV_LOG_ERROR,
- "Subcodec %d: error decoding frame.\n", header.codec);
- return ret;
- }
- } else {
- avpriv_request_sample(avctx, "Subcodec %d", header.codec);
- return AVERROR_PATCHWELCOME;
- }
-
- if ((ret = copy_output(ctx, &header)))
- return ret;
- }
- if (ctx->rotate_code)
- rotate_bufs(ctx, ctx->rotate_code);
-
- *got_frame_ptr = 1;
-
- return pkt->size;
-}
-
-AVCodec ff_sanm_decoder = {
- .name = "sanm",
- .long_name = NULL_IF_CONFIG_SMALL("LucasArts SANM/Smush video"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_SANM,
- .priv_data_size = sizeof(SANMVideoContext),
- .init = decode_init,
- .close = decode_end,
- .decode = decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/sbrdsp_fixed.c b/ffmpeg-2-8-11/libavcodec/sbrdsp_fixed.c
deleted file mode 100644
index f4e3de0..0000000
--- a/ffmpeg-2-8-11/libavcodec/sbrdsp_fixed.c
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * AAC Spectral Band Replication decoding functions
- * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
- * Copyright (c) 2009-2010 Alex Converse <alex.converse at gmail.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
- *
- * Note: Rounding-to-nearest used unless otherwise stated
- *
- */
-
-#define USE_FIXED 1
-
-#include "aac.h"
-#include "config.h"
-#include "libavutil/attributes.h"
-#include "libavutil/intfloat.h"
-#include "sbrdsp.h"
-
-static SoftFloat sbr_sum_square_c(int (*x)[2], int n)
-{
- SoftFloat ret;
- int64_t accu = 0;
- int i, nz, round;
-
- for (i = 0; i < n; i += 2) {
- // Larger values are inavlid and could cause overflows of accu.
- av_assert2(FFABS(x[i + 0][0]) >> 29 == 0);
- accu += (int64_t)x[i + 0][0] * x[i + 0][0];
- av_assert2(FFABS(x[i + 0][1]) >> 29 == 0);
- accu += (int64_t)x[i + 0][1] * x[i + 0][1];
- av_assert2(FFABS(x[i + 1][0]) >> 29 == 0);
- accu += (int64_t)x[i + 1][0] * x[i + 1][0];
- av_assert2(FFABS(x[i + 1][1]) >> 29 == 0);
- accu += (int64_t)x[i + 1][1] * x[i + 1][1];
- }
-
- i = (int)(accu >> 32);
- if (i == 0) {
- nz = 1;
- } else {
- nz = 0;
- while (FFABS(i) < 0x40000000) {
- i <<= 1;
- nz++;
- }
- nz = 32 - nz;
- }
-
- round = 1 << (nz-1);
- i = (int)((accu + round) >> nz);
- i >>= 1;
- ret = av_int2sf(i, 15 - nz);
-
- return ret;
-}
-
-static void sbr_neg_odd_64_c(int *x)
-{
- int i;
- for (i = 1; i < 64; i += 2)
- x[i] = -x[i];
-}
-
-static void sbr_qmf_pre_shuffle_c(int *z)
-{
- int k;
- z[64] = z[0];
- z[65] = z[1];
- for (k = 1; k < 32; k++) {
- z[64+2*k ] = -z[64 - k];
- z[64+2*k+1] = z[ k + 1];
- }
-}
-
-static void sbr_qmf_post_shuffle_c(int W[32][2], const int *z)
-{
- int k;
- for (k = 0; k < 32; k++) {
- W[k][0] = -z[63-k];
- W[k][1] = z[k];
- }
-}
-
-static void sbr_qmf_deint_neg_c(int *v, const int *src)
-{
- int i;
- for (i = 0; i < 32; i++) {
- v[ i] = ( src[63 - 2*i ] + 0x10) >> 5;
- v[63 - i] = (-src[63 - 2*i - 1] + 0x10) >> 5;
- }
-}
-
-static av_always_inline SoftFloat autocorr_calc(int64_t accu)
-{
- int nz, mant, expo, round;
- int i = (int)(accu >> 32);
- if (i == 0) {
- nz = 1;
- } else {
- nz = 0;
- while (FFABS(i) < 0x40000000) {
- i <<= 1;
- nz++;
- }
- nz = 32-nz;
- }
-
- round = 1 << (nz-1);
- mant = (int)((accu + round) >> nz);
- mant = (mant + 0x40)>>7;
- mant <<= 6;
- expo = nz + 15;
- return av_int2sf(mant, 30 - expo);
-}
-
-static av_always_inline void autocorrelate(const int x[40][2], SoftFloat phi[3][2][2], int lag)
-{
- int i;
- int64_t real_sum, imag_sum;
- int64_t accu_re = 0, accu_im = 0;
-
- if (lag) {
- for (i = 1; i < 38; i++) {
- accu_re += (int64_t)x[i][0] * x[i+lag][0];
- accu_re += (int64_t)x[i][1] * x[i+lag][1];
- accu_im += (int64_t)x[i][0] * x[i+lag][1];
- accu_im -= (int64_t)x[i][1] * x[i+lag][0];
- }
-
- real_sum = accu_re;
- imag_sum = accu_im;
-
- accu_re += (int64_t)x[ 0][0] * x[lag][0];
- accu_re += (int64_t)x[ 0][1] * x[lag][1];
- accu_im += (int64_t)x[ 0][0] * x[lag][1];
- accu_im -= (int64_t)x[ 0][1] * x[lag][0];
-
- phi[2-lag][1][0] = autocorr_calc(accu_re);
- phi[2-lag][1][1] = autocorr_calc(accu_im);
-
- if (lag == 1) {
- accu_re = real_sum;
- accu_im = imag_sum;
- accu_re += (int64_t)x[38][0] * x[39][0];
- accu_re += (int64_t)x[38][1] * x[39][1];
- accu_im += (int64_t)x[38][0] * x[39][1];
- accu_im -= (int64_t)x[38][1] * x[39][0];
-
- phi[0][0][0] = autocorr_calc(accu_re);
- phi[0][0][1] = autocorr_calc(accu_im);
- }
- } else {
- for (i = 1; i < 38; i++) {
- accu_re += (int64_t)x[i][0] * x[i][0];
- accu_re += (int64_t)x[i][1] * x[i][1];
- }
- real_sum = accu_re;
- accu_re += (int64_t)x[ 0][0] * x[ 0][0];
- accu_re += (int64_t)x[ 0][1] * x[ 0][1];
-
- phi[2][1][0] = autocorr_calc(accu_re);
-
- accu_re = real_sum;
- accu_re += (int64_t)x[38][0] * x[38][0];
- accu_re += (int64_t)x[38][1] * x[38][1];
-
- phi[1][0][0] = autocorr_calc(accu_re);
- }
-}
-
-static void sbr_autocorrelate_c(const int x[40][2], SoftFloat phi[3][2][2])
-{
- autocorrelate(x, phi, 0);
- autocorrelate(x, phi, 1);
- autocorrelate(x, phi, 2);
-}
-
-static void sbr_hf_gen_c(int (*X_high)[2], const int (*X_low)[2],
- const int alpha0[2], const int alpha1[2],
- int bw, int start, int end)
-{
- int alpha[4];
- int i;
- int64_t accu;
-
- accu = (int64_t)alpha0[0] * bw;
- alpha[2] = (int)((accu + 0x40000000) >> 31);
- accu = (int64_t)alpha0[1] * bw;
- alpha[3] = (int)((accu + 0x40000000) >> 31);
- accu = (int64_t)bw * bw;
- bw = (int)((accu + 0x40000000) >> 31);
- accu = (int64_t)alpha1[0] * bw;
- alpha[0] = (int)((accu + 0x40000000) >> 31);
- accu = (int64_t)alpha1[1] * bw;
- alpha[1] = (int)((accu + 0x40000000) >> 31);
-
- for (i = start; i < end; i++) {
- accu = (int64_t)X_low[i][0] * 0x20000000;
- accu += (int64_t)X_low[i - 2][0] * alpha[0];
- accu -= (int64_t)X_low[i - 2][1] * alpha[1];
- accu += (int64_t)X_low[i - 1][0] * alpha[2];
- accu -= (int64_t)X_low[i - 1][1] * alpha[3];
- X_high[i][0] = (int)((accu + 0x10000000) >> 29);
-
- accu = (int64_t)X_low[i][1] * 0x20000000;
- accu += (int64_t)X_low[i - 2][1] * alpha[0];
- accu += (int64_t)X_low[i - 2][0] * alpha[1];
- accu += (int64_t)X_low[i - 1][1] * alpha[2];
- accu += (int64_t)X_low[i - 1][0] * alpha[3];
- X_high[i][1] = (int)((accu + 0x10000000) >> 29);
- }
-}
-
-static void sbr_hf_g_filt_c(int (*Y)[2], const int (*X_high)[40][2],
- const SoftFloat *g_filt, int m_max, intptr_t ixh)
-{
- int m, r;
- int64_t accu;
-
- for (m = 0; m < m_max; m++) {
- r = 1 << (22-g_filt[m].exp);
- accu = (int64_t)X_high[m][ixh][0] * ((g_filt[m].mant + 0x40)>>7);
- Y[m][0] = (int)((accu + r) >> (23-g_filt[m].exp));
-
- accu = (int64_t)X_high[m][ixh][1] * ((g_filt[m].mant + 0x40)>>7);
- Y[m][1] = (int)((accu + r) >> (23-g_filt[m].exp));
- }
-}
-
-static av_always_inline void sbr_hf_apply_noise(int (*Y)[2],
- const SoftFloat *s_m,
- const SoftFloat *q_filt,
- int noise,
- int phi_sign0,
- int phi_sign1,
- int m_max)
-{
- int m;
-
- for (m = 0; m < m_max; m++) {
- int y0 = Y[m][0];
- int y1 = Y[m][1];
- noise = (noise + 1) & 0x1ff;
- if (s_m[m].mant) {
- int shift, round;
-
- shift = 22 - s_m[m].exp;
- if (shift < 30) {
- round = 1 << (shift-1);
- y0 += (s_m[m].mant * phi_sign0 + round) >> shift;
- y1 += (s_m[m].mant * phi_sign1 + round) >> shift;
- }
- } else {
- int shift, round, tmp;
- int64_t accu;
-
- shift = 22 - q_filt[m].exp;
- if (shift < 30) {
- round = 1 << (shift-1);
-
- accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][0];
- tmp = (int)((accu + 0x40000000) >> 31);
- y0 += (tmp + round) >> shift;
-
- accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][1];
- tmp = (int)((accu + 0x40000000) >> 31);
- y1 += (tmp + round) >> shift;
- }
- }
- Y[m][0] = y0;
- Y[m][1] = y1;
- phi_sign1 = -phi_sign1;
- }
-}
-
-#include "sbrdsp_template.c"
diff --git a/ffmpeg-2-8-11/libavcodec/sbrdsp_template.c b/ffmpeg-2-8-11/libavcodec/sbrdsp_template.c
deleted file mode 100644
index b649dfd..0000000
--- a/ffmpeg-2-8-11/libavcodec/sbrdsp_template.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * AAC Spectral Band Replication decoding functions
- * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
- * Copyright (c) 2009-2010 Alex Converse <alex.converse at gmail.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
- */
-
-static void sbr_sum64x5_c(INTFLOAT *z)
-{
- int k;
- for (k = 0; k < 64; k++) {
- INTFLOAT f = z[k] + z[k + 64] + z[k + 128] + z[k + 192] + z[k + 256];
- z[k] = f;
- }
-}
-
-static void sbr_qmf_deint_bfly_c(INTFLOAT *v, const INTFLOAT *src0, const INTFLOAT *src1)
-{
- int i;
- for (i = 0; i < 64; i++) {
- v[ i] = AAC_SRA_R((src0[i] - src1[63 - i]), 5);
- v[127 - i] = AAC_SRA_R((src0[i] + src1[63 - i]), 5);
- }
-}
-
-static void sbr_hf_apply_noise_0(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m,
- const AAC_FLOAT *q_filt, int noise,
- int kx, int m_max)
-{
- sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)1.0, (INTFLOAT)0.0, m_max);
-}
-
-static void sbr_hf_apply_noise_1(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m,
- const AAC_FLOAT *q_filt, int noise,
- int kx, int m_max)
-{
- INTFLOAT phi_sign = 1 - 2 * (kx & 1);
- sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)0.0, phi_sign, m_max);
-}
-
-static void sbr_hf_apply_noise_2(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m,
- const AAC_FLOAT *q_filt, int noise,
- int kx, int m_max)
-{
- sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)-1.0, (INTFLOAT)0.0, m_max);
-}
-
-static void sbr_hf_apply_noise_3(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m,
- const AAC_FLOAT *q_filt, int noise,
- int kx, int m_max)
-{
- INTFLOAT phi_sign = 1 - 2 * (kx & 1);
- sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)0.0, -phi_sign, m_max);
-}
-
-av_cold void AAC_RENAME(ff_sbrdsp_init)(SBRDSPContext *s)
-{
- s->sum64x5 = sbr_sum64x5_c;
- s->sum_square = sbr_sum_square_c;
- s->neg_odd_64 = sbr_neg_odd_64_c;
- s->qmf_pre_shuffle = sbr_qmf_pre_shuffle_c;
- s->qmf_post_shuffle = sbr_qmf_post_shuffle_c;
- s->qmf_deint_neg = sbr_qmf_deint_neg_c;
- s->qmf_deint_bfly = sbr_qmf_deint_bfly_c;
- s->autocorrelate = sbr_autocorrelate_c;
- s->hf_gen = sbr_hf_gen_c;
- s->hf_g_filt = sbr_hf_g_filt_c;
-
- s->hf_apply_noise[0] = sbr_hf_apply_noise_0;
- s->hf_apply_noise[1] = sbr_hf_apply_noise_1;
- s->hf_apply_noise[2] = sbr_hf_apply_noise_2;
- s->hf_apply_noise[3] = sbr_hf_apply_noise_3;
-
-#if !USE_FIXED
- if (ARCH_ARM)
- ff_sbrdsp_init_arm(s);
- if (ARCH_X86)
- ff_sbrdsp_init_x86(s);
- if (ARCH_MIPS)
- ff_sbrdsp_init_mips(s);
-#endif /* !USE_FIXED */
-}
diff --git a/ffmpeg-2-8-11/libavcodec/shorten.c b/ffmpeg-2-8-11/libavcodec/shorten.c
deleted file mode 100644
index 0f5be96..0000000
--- a/ffmpeg-2-8-11/libavcodec/shorten.c
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
- * Shorten decoder
- * Copyright (c) 2005 Jeff Muizelaar
- *
- * 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
- * Shorten decoder
- * @author Jeff Muizelaar
- *
- */
-
-#include <limits.h>
-#include "avcodec.h"
-#include "bytestream.h"
-#include "get_bits.h"
-#include "golomb.h"
-#include "internal.h"
-
-#define MAX_CHANNELS 8
-#define MAX_BLOCKSIZE 65535
-
-#define OUT_BUFFER_SIZE 16384
-
-#define ULONGSIZE 2
-
-#define WAVE_FORMAT_PCM 0x0001
-
-#define DEFAULT_BLOCK_SIZE 256
-
-#define TYPESIZE 4
-#define CHANSIZE 0
-#define LPCQSIZE 2
-#define ENERGYSIZE 3
-#define BITSHIFTSIZE 2
-
-#define TYPE_S8 1
-#define TYPE_U8 2
-#define TYPE_S16HL 3
-#define TYPE_U16HL 4
-#define TYPE_S16LH 5
-#define TYPE_U16LH 6
-
-#define NWRAP 3
-#define NSKIPSIZE 1
-
-#define LPCQUANT 5
-#define V2LPCQOFFSET (1 << LPCQUANT)
-
-#define FNSIZE 2
-#define FN_DIFF0 0
-#define FN_DIFF1 1
-#define FN_DIFF2 2
-#define FN_DIFF3 3
-#define FN_QUIT 4
-#define FN_BLOCKSIZE 5
-#define FN_BITSHIFT 6
-#define FN_QLPC 7
-#define FN_ZERO 8
-#define FN_VERBATIM 9
-
-/** indicates if the FN_* command is audio or non-audio */
-static const uint8_t is_audio_command[10] = { 1, 1, 1, 1, 0, 0, 0, 1, 1, 0 };
-
-#define VERBATIM_CKSIZE_SIZE 5
-#define VERBATIM_BYTE_SIZE 8
-#define CANONICAL_HEADER_SIZE 44
-
-typedef struct ShortenContext {
- AVCodecContext *avctx;
- GetBitContext gb;
-
- int min_framesize, max_framesize;
- unsigned channels;
-
- int32_t *decoded[MAX_CHANNELS];
- int32_t *decoded_base[MAX_CHANNELS];
- int32_t *offset[MAX_CHANNELS];
- int *coeffs;
- uint8_t *bitstream;
- int bitstream_size;
- int bitstream_index;
- unsigned int allocated_bitstream_size;
- int header_size;
- uint8_t header[OUT_BUFFER_SIZE];
- int version;
- int cur_chan;
- int bitshift;
- int nmean;
- int internal_ftype;
- int nwrap;
- int blocksize;
- int bitindex;
- int32_t lpcqoffset;
- int got_header;
- int got_quit_command;
-} ShortenContext;
-
-static av_cold int shorten_decode_init(AVCodecContext *avctx)
-{
- ShortenContext *s = avctx->priv_data;
- s->avctx = avctx;
-
- return 0;
-}
-
-static int allocate_buffers(ShortenContext *s)
-{
- int i, chan, err;
-
- for (chan = 0; chan < s->channels; chan++) {
- if (FFMAX(1, s->nmean) >= UINT_MAX / sizeof(int32_t)) {
- av_log(s->avctx, AV_LOG_ERROR, "nmean too large\n");
- return AVERROR_INVALIDDATA;
- }
- if (s->blocksize + (uint64_t)s->nwrap >= UINT_MAX / sizeof(int32_t)) {
- av_log(s->avctx, AV_LOG_ERROR,
- "s->blocksize + s->nwrap too large\n");
- return AVERROR_INVALIDDATA;
- }
-
- if ((err = av_reallocp_array(&s->offset[chan],
- sizeof(int32_t),
- FFMAX(1, s->nmean))) < 0)
- return err;
-
- if ((err = av_reallocp_array(&s->decoded_base[chan], (s->blocksize + s->nwrap),
- sizeof(s->decoded_base[0][0]))) < 0)
- return err;
- for (i = 0; i < s->nwrap; i++)
- s->decoded_base[chan][i] = 0;
- s->decoded[chan] = s->decoded_base[chan] + s->nwrap;
- }
-
- if ((err = av_reallocp_array(&s->coeffs, s->nwrap, sizeof(*s->coeffs))) < 0)
- return err;
-
- return 0;
-}
-
-static inline unsigned int get_uint(ShortenContext *s, int k)
-{
- if (s->version != 0)
- k = get_ur_golomb_shorten(&s->gb, ULONGSIZE);
- return get_ur_golomb_shorten(&s->gb, k);
-}
-
-static void fix_bitshift(ShortenContext *s, int32_t *buffer)
-{
- int i;
-
- if (s->bitshift != 0)
- for (i = 0; i < s->blocksize; i++)
- buffer[i] <<= s->bitshift;
-}
-
-static int init_offset(ShortenContext *s)
-{
- int32_t mean = 0;
- int chan, i;
- int nblock = FFMAX(1, s->nmean);
- /* initialise offset */
- switch (s->internal_ftype) {
- case TYPE_U8:
- s->avctx->sample_fmt = AV_SAMPLE_FMT_U8P;
- mean = 0x80;
- break;
- case TYPE_S16HL:
- case TYPE_S16LH:
- s->avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
- break;
- default:
- av_log(s->avctx, AV_LOG_ERROR, "unknown audio type\n");
- return AVERROR_PATCHWELCOME;
- }
-
- for (chan = 0; chan < s->channels; chan++)
- for (i = 0; i < nblock; i++)
- s->offset[chan][i] = mean;
- return 0;
-}
-
-static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header,
- int header_size)
-{
- int len, bps;
- short wave_format;
- GetByteContext gb;
-
- bytestream2_init(&gb, header, header_size);
-
- if (bytestream2_get_le32(&gb) != MKTAG('R', 'I', 'F', 'F')) {
- av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n");
- return AVERROR_INVALIDDATA;
- }
-
- bytestream2_skip(&gb, 4); /* chunk size */
-
- if (bytestream2_get_le32(&gb) != MKTAG('W', 'A', 'V', 'E')) {
- av_log(avctx, AV_LOG_ERROR, "missing WAVE tag\n");
- return AVERROR_INVALIDDATA;
- }
-
- while (bytestream2_get_le32(&gb) != MKTAG('f', 'm', 't', ' ')) {
- len = bytestream2_get_le32(&gb);
- bytestream2_skip(&gb, len);
- if (len < 0 || bytestream2_get_bytes_left(&gb) < 16) {
- av_log(avctx, AV_LOG_ERROR, "no fmt chunk found\n");
- return AVERROR_INVALIDDATA;
- }
- }
- len = bytestream2_get_le32(&gb);
-
- if (len < 16) {
- av_log(avctx, AV_LOG_ERROR, "fmt chunk was too short\n");
- return AVERROR_INVALIDDATA;
- }
-
- wave_format = bytestream2_get_le16(&gb);
-
- switch (wave_format) {
- case WAVE_FORMAT_PCM:
- break;
- default:
- av_log(avctx, AV_LOG_ERROR, "unsupported wave format\n");
- return AVERROR(ENOSYS);
- }
-
- bytestream2_skip(&gb, 2); // skip channels (already got from shorten header)
- avctx->sample_rate = bytestream2_get_le32(&gb);
- bytestream2_skip(&gb, 4); // skip bit rate (represents original uncompressed bit rate)
- bytestream2_skip(&gb, 2); // skip block align (not needed)
- bps = bytestream2_get_le16(&gb);
- avctx->bits_per_coded_sample = bps;
-
- if (bps != 16 && bps != 8) {
- av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample: %d\n", bps);
- return AVERROR(ENOSYS);
- }
-
- len -= 16;
- if (len > 0)
- av_log(avctx, AV_LOG_INFO, "%d header bytes unparsed\n", len);
-
- return 0;
-}
-
-static const int fixed_coeffs[][3] = {
- { 0, 0, 0 },
- { 1, 0, 0 },
- { 2, -1, 0 },
- { 3, -3, 1 }
-};
-
-static int decode_subframe_lpc(ShortenContext *s, int command, int channel,
- int residual_size, int32_t coffset)
-{
- int pred_order, sum, qshift, init_sum, i, j;
- const int *coeffs;
-
- if (command == FN_QLPC) {
- /* read/validate prediction order */
- pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE);
- if ((unsigned)pred_order > s->nwrap) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n",
- pred_order);
- return AVERROR(EINVAL);
- }
- /* read LPC coefficients */
- for (i = 0; i < pred_order; i++)
- s->coeffs[i] = get_sr_golomb_shorten(&s->gb, LPCQUANT);
- coeffs = s->coeffs;
-
- qshift = LPCQUANT;
- } else {
- /* fixed LPC coeffs */
- pred_order = command;
- if (pred_order >= FF_ARRAY_ELEMS(fixed_coeffs)) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n",
- pred_order);
- return AVERROR_INVALIDDATA;
- }
- coeffs = fixed_coeffs[pred_order];
- qshift = 0;
- }
-
- /* subtract offset from previous samples to use in prediction */
- if (command == FN_QLPC && coffset)
- for (i = -pred_order; i < 0; i++)
- s->decoded[channel][i] -= coffset;
-
- /* decode residual and do LPC prediction */
- init_sum = pred_order ? (command == FN_QLPC ? s->lpcqoffset : 0) : coffset;
- for (i = 0; i < s->blocksize; i++) {
- sum = init_sum;
- for (j = 0; j < pred_order; j++)
- sum += coeffs[j] * s->decoded[channel][i - j - 1];
- s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) +
- (sum >> qshift);
- }
-
- /* add offset to current samples */
- if (command == FN_QLPC && coffset)
- for (i = 0; i < s->blocksize; i++)
- s->decoded[channel][i] += coffset;
-
- return 0;
-}
-
-static int read_header(ShortenContext *s)
-{
- int i, ret;
- int maxnlpc = 0;
- /* shorten signature */
- if (get_bits_long(&s->gb, 32) != AV_RB32("ajkg")) {
- av_log(s->avctx, AV_LOG_ERROR, "missing shorten magic 'ajkg'\n");
- return AVERROR_INVALIDDATA;
- }
-
- s->lpcqoffset = 0;
- s->blocksize = DEFAULT_BLOCK_SIZE;
- s->nmean = -1;
- s->version = get_bits(&s->gb, 8);
- s->internal_ftype = get_uint(s, TYPESIZE);
-
- s->channels = get_uint(s, CHANSIZE);
- if (!s->channels) {
- av_log(s->avctx, AV_LOG_ERROR, "No channels reported\n");
- return AVERROR_INVALIDDATA;
- }
- if (s->channels > MAX_CHANNELS) {
- av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels);
- s->channels = 0;
- return AVERROR_INVALIDDATA;
- }
- s->avctx->channels = s->channels;
-
- /* get blocksize if version > 0 */
- if (s->version > 0) {
- int skip_bytes;
- unsigned blocksize;
-
- blocksize = get_uint(s, av_log2(DEFAULT_BLOCK_SIZE));
- if (!blocksize || blocksize > MAX_BLOCKSIZE) {
- av_log(s->avctx, AV_LOG_ERROR,
- "invalid or unsupported block size: %d\n",
- blocksize);
- return AVERROR(EINVAL);
- }
- s->blocksize = blocksize;
-
- maxnlpc = get_uint(s, LPCQSIZE);
- s->nmean = get_uint(s, 0);
-
- skip_bytes = get_uint(s, NSKIPSIZE);
- if ((unsigned)skip_bytes > get_bits_left(&s->gb)/8) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid skip_bytes: %d\n", skip_bytes);
- return AVERROR_INVALIDDATA;
- }
-
- for (i = 0; i < skip_bytes; i++)
- skip_bits(&s->gb, 8);
- }
- s->nwrap = FFMAX(NWRAP, maxnlpc);
-
- if ((ret = allocate_buffers(s)) < 0)
- return ret;
-
- if ((ret = init_offset(s)) < 0)
- return ret;
-
- if (s->version > 1)
- s->lpcqoffset = V2LPCQOFFSET;
-
- if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) {
- av_log(s->avctx, AV_LOG_ERROR,
- "missing verbatim section at beginning of stream\n");
- return AVERROR_INVALIDDATA;
- }
-
- s->header_size = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
- if (s->header_size >= OUT_BUFFER_SIZE ||
- s->header_size < CANONICAL_HEADER_SIZE) {
- av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n",
- s->header_size);
- return AVERROR_INVALIDDATA;
- }
-
- for (i = 0; i < s->header_size; i++)
- s->header[i] = (char)get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
-
- if ((ret = decode_wave_header(s->avctx, s->header, s->header_size)) < 0)
- return ret;
-
- s->cur_chan = 0;
- s->bitshift = 0;
-
- s->got_header = 1;
-
- return 0;
-}
-
-static int shorten_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- AVFrame *frame = data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- ShortenContext *s = avctx->priv_data;
- int i, input_buf_size = 0;
- int ret;
-
- /* allocate internal bitstream buffer */
- if (s->max_framesize == 0) {
- void *tmp_ptr;
- s->max_framesize = 8192; // should hopefully be enough for the first header
- tmp_ptr = av_fast_realloc(s->bitstream, &s->allocated_bitstream_size,
- s->max_framesize + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!tmp_ptr) {
- av_log(avctx, AV_LOG_ERROR, "error allocating bitstream buffer\n");
- return AVERROR(ENOMEM);
- }
- memset(tmp_ptr, 0, s->allocated_bitstream_size);
- s->bitstream = tmp_ptr;
- }
-
- /* append current packet data to bitstream buffer */
- if (1 && s->max_framesize) { //FIXME truncated
- buf_size = FFMIN(buf_size, s->max_framesize - s->bitstream_size);
- input_buf_size = buf_size;
-
- if (s->bitstream_index + s->bitstream_size + buf_size + AV_INPUT_BUFFER_PADDING_SIZE >
- s->allocated_bitstream_size) {
- memmove(s->bitstream, &s->bitstream[s->bitstream_index],
- s->bitstream_size);
- s->bitstream_index = 0;
- }
- if (buf)
- memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf,
- buf_size);
- buf = &s->bitstream[s->bitstream_index];
- buf_size += s->bitstream_size;
- s->bitstream_size = buf_size;
-
- /* do not decode until buffer has at least max_framesize bytes or
- * the end of the file has been reached */
- if (buf_size < s->max_framesize && avpkt->data) {
- *got_frame_ptr = 0;
- return input_buf_size;
- }
- }
- /* init and position bitstream reader */
- if ((ret = init_get_bits8(&s->gb, buf, buf_size)) < 0)
- return ret;
- skip_bits(&s->gb, s->bitindex);
-
- /* process header or next subblock */
- if (!s->got_header) {
- if ((ret = read_header(s)) < 0)
- return ret;
- *got_frame_ptr = 0;
- goto finish_frame;
- }
-
- /* if quit command was read previously, don't decode anything */
- if (s->got_quit_command) {
- *got_frame_ptr = 0;
- return avpkt->size;
- }
-
- s->cur_chan = 0;
- while (s->cur_chan < s->channels) {
- unsigned cmd;
- int len;
-
- if (get_bits_left(&s->gb) < 3 + FNSIZE) {
- *got_frame_ptr = 0;
- break;
- }
-
- cmd = get_ur_golomb_shorten(&s->gb, FNSIZE);
-
- if (cmd > FN_VERBATIM) {
- av_log(avctx, AV_LOG_ERROR, "unknown shorten function %d\n", cmd);
- *got_frame_ptr = 0;
- break;
- }
-
- if (!is_audio_command[cmd]) {
- /* process non-audio command */
- switch (cmd) {
- case FN_VERBATIM:
- len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
- while (len--)
- get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
- break;
- case FN_BITSHIFT: {
- unsigned bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE);
- if (bitshift > 31) {
- av_log(avctx, AV_LOG_ERROR, "bitshift %d is invalid\n",
- bitshift);
- return AVERROR_INVALIDDATA;
- }
- s->bitshift = bitshift;
- break;
- }
- case FN_BLOCKSIZE: {
- unsigned blocksize = get_uint(s, av_log2(s->blocksize));
- if (blocksize > s->blocksize) {
- av_log(avctx, AV_LOG_ERROR,
- "Increasing block size is not supported\n");
- return AVERROR_PATCHWELCOME;
- }
- if (!blocksize || blocksize > MAX_BLOCKSIZE) {
- av_log(avctx, AV_LOG_ERROR, "invalid or unsupported "
- "block size: %d\n", blocksize);
- return AVERROR(EINVAL);
- }
- s->blocksize = blocksize;
- break;
- }
- case FN_QUIT:
- s->got_quit_command = 1;
- break;
- }
- if (cmd == FN_BLOCKSIZE || cmd == FN_QUIT) {
- *got_frame_ptr = 0;
- break;
- }
- } else {
- /* process audio command */
- int residual_size = 0;
- int channel = s->cur_chan;
- int32_t coffset;
-
- /* get Rice code for residual decoding */
- if (cmd != FN_ZERO) {
- residual_size = get_ur_golomb_shorten(&s->gb, ENERGYSIZE);
- /* This is a hack as version 0 differed in the definition
- * of get_sr_golomb_shorten(). */
- if (s->version == 0)
- residual_size--;
- }
-
- /* calculate sample offset using means from previous blocks */
- if (s->nmean == 0)
- coffset = s->offset[channel][0];
- else {
- int32_t sum = (s->version < 2) ? 0 : s->nmean / 2;
- for (i = 0; i < s->nmean; i++)
- sum += s->offset[channel][i];
- coffset = sum / s->nmean;
- if (s->version >= 2)
- coffset = s->bitshift == 0 ? coffset : coffset >> s->bitshift - 1 >> 1;
- }
-
- /* decode samples for this channel */
- if (cmd == FN_ZERO) {
- for (i = 0; i < s->blocksize; i++)
- s->decoded[channel][i] = 0;
- } else {
- if ((ret = decode_subframe_lpc(s, cmd, channel,
- residual_size, coffset)) < 0)
- return ret;
- }
-
- /* update means with info from the current block */
- if (s->nmean > 0) {
- int32_t sum = (s->version < 2) ? 0 : s->blocksize / 2;
- for (i = 0; i < s->blocksize; i++)
- sum += s->decoded[channel][i];
-
- for (i = 1; i < s->nmean; i++)
- s->offset[channel][i - 1] = s->offset[channel][i];
-
- if (s->version < 2)
- s->offset[channel][s->nmean - 1] = sum / s->blocksize;
- else
- s->offset[channel][s->nmean - 1] = (sum / s->blocksize) << s->bitshift;
- }
-
- /* copy wrap samples for use with next block */
- for (i = -s->nwrap; i < 0; i++)
- s->decoded[channel][i] = s->decoded[channel][i + s->blocksize];
-
- /* shift samples to add in unused zero bits which were removed
- * during encoding */
- fix_bitshift(s, s->decoded[channel]);
-
- /* if this is the last channel in the block, output the samples */
- s->cur_chan++;
- if (s->cur_chan == s->channels) {
- uint8_t *samples_u8;
- int16_t *samples_s16;
- int chan;
-
- /* get output buffer */
- frame->nb_samples = s->blocksize;
- if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
- return ret;
-
- for (chan = 0; chan < s->channels; chan++) {
- samples_u8 = ((uint8_t **)frame->extended_data)[chan];
- samples_s16 = ((int16_t **)frame->extended_data)[chan];
- for (i = 0; i < s->blocksize; i++) {
- switch (s->internal_ftype) {
- case TYPE_U8:
- *samples_u8++ = av_clip_uint8(s->decoded[chan][i]);
- break;
- case TYPE_S16HL:
- case TYPE_S16LH:
- *samples_s16++ = av_clip_int16(s->decoded[chan][i]);
- break;
- }
- }
- }
-
- *got_frame_ptr = 1;
- }
- }
- }
- if (s->cur_chan < s->channels)
- *got_frame_ptr = 0;
-
-finish_frame:
- s->bitindex = get_bits_count(&s->gb) - 8 * (get_bits_count(&s->gb) / 8);
- i = get_bits_count(&s->gb) / 8;
- if (i > buf_size) {
- av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size);
- s->bitstream_size = 0;
- s->bitstream_index = 0;
- return AVERROR_INVALIDDATA;
- }
- if (s->bitstream_size) {
- s->bitstream_index += i;
- s->bitstream_size -= i;
- return input_buf_size;
- } else
- return i;
-}
-
-static av_cold int shorten_decode_close(AVCodecContext *avctx)
-{
- ShortenContext *s = avctx->priv_data;
- int i;
-
- for (i = 0; i < s->channels; i++) {
- s->decoded[i] = NULL;
- av_freep(&s->decoded_base[i]);
- av_freep(&s->offset[i]);
- }
- av_freep(&s->bitstream);
- av_freep(&s->coeffs);
-
- return 0;
-}
-
-AVCodec ff_shorten_decoder = {
- .name = "shorten",
- .long_name = NULL_IF_CONFIG_SMALL("Shorten"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_SHORTEN,
- .priv_data_size = sizeof(ShortenContext),
- .init = shorten_decode_init,
- .close = shorten_decode_close,
- .decode = shorten_decode_frame,
- .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
- .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
- AV_SAMPLE_FMT_U8P,
- AV_SAMPLE_FMT_NONE },
-};
diff --git a/ffmpeg-2-8-11/libavcodec/smc.c b/ffmpeg-2-8-11/libavcodec/smc.c
deleted file mode 100644
index a423c45..0000000
--- a/ffmpeg-2-8-11/libavcodec/smc.c
+++ /dev/null
@@ -1,476 +0,0 @@
-/*
- * Quicktime Graphics (SMC) Video Decoder
- * Copyright (c) 2003 The FFmpeg Project
- *
- * 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
- * QT SMC Video Decoder by Mike Melanson (melanson at pcisys.net)
- * For more information about the SMC format, visit:
- * http://www.pcisys.net/~melanson/codecs/
- *
- * The SMC decoder outputs PAL8 colorspace data.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "libavutil/intreadwrite.h"
-#include "avcodec.h"
-#include "bytestream.h"
-#include "internal.h"
-
-#define CPAIR 2
-#define CQUAD 4
-#define COCTET 8
-
-#define COLORS_PER_TABLE 256
-
-typedef struct SmcContext {
-
- AVCodecContext *avctx;
- AVFrame *frame;
-
- GetByteContext gb;
-
- /* SMC color tables */
- unsigned char color_pairs[COLORS_PER_TABLE * CPAIR];
- unsigned char color_quads[COLORS_PER_TABLE * CQUAD];
- unsigned char color_octets[COLORS_PER_TABLE * COCTET];
-
- uint32_t pal[256];
-} SmcContext;
-
-#define GET_BLOCK_COUNT() \
- (opcode & 0x10) ? (1 + bytestream2_get_byte(&s->gb)) : 1 + (opcode & 0x0F);
-
-#define ADVANCE_BLOCK() \
-{ \
- pixel_ptr += 4; \
- if (pixel_ptr >= width) \
- { \
- pixel_ptr = 0; \
- row_ptr += stride * 4; \
- } \
- total_blocks--; \
- if (total_blocks < !!n_blocks) \
- { \
- av_log(s->avctx, AV_LOG_INFO, "warning: block counter just went negative (this should not happen)\n"); \
- return; \
- } \
-}
-
-static void smc_decode_stream(SmcContext *s)
-{
- int width = s->avctx->width;
- int height = s->avctx->height;
- int stride = s->frame->linesize[0];
- int i;
- int chunk_size;
- int buf_size = bytestream2_size(&s->gb);
- unsigned char opcode;
- int n_blocks;
- unsigned int color_flags;
- unsigned int color_flags_a;
- unsigned int color_flags_b;
- unsigned int flag_mask;
-
- unsigned char *pixels = s->frame->data[0];
-
- int image_size = height * s->frame->linesize[0];
- int row_ptr = 0;
- int pixel_ptr = 0;
- int pixel_x, pixel_y;
- int row_inc = stride - 4;
- int block_ptr;
- int prev_block_ptr;
- int prev_block_ptr1, prev_block_ptr2;
- int prev_block_flag;
- int total_blocks;
- int color_table_index; /* indexes to color pair, quad, or octet tables */
- int pixel;
-
- int color_pair_index = 0;
- int color_quad_index = 0;
- int color_octet_index = 0;
-
- /* make the palette available */
- memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);
-
- bytestream2_skip(&s->gb, 1);
- chunk_size = bytestream2_get_be24(&s->gb);
- if (chunk_size != buf_size)
- av_log(s->avctx, AV_LOG_INFO, "warning: MOV chunk size != encoded chunk size (%d != %d); using MOV chunk size\n",
- chunk_size, buf_size);
-
- chunk_size = buf_size;
- total_blocks = ((s->avctx->width + 3) / 4) * ((s->avctx->height + 3) / 4);
-
- /* traverse through the blocks */
- while (total_blocks) {
- /* sanity checks */
- /* make sure the row pointer hasn't gone wild */
- if (row_ptr >= image_size) {
- av_log(s->avctx, AV_LOG_INFO, "SMC decoder just went out of bounds (row ptr = %d, height = %d)\n",
- row_ptr, image_size);
- return;
- }
-
- opcode = bytestream2_get_byte(&s->gb);
- switch (opcode & 0xF0) {
- /* skip n blocks */
- case 0x00:
- case 0x10:
- n_blocks = GET_BLOCK_COUNT();
- while (n_blocks--) {
- ADVANCE_BLOCK();
- }
- break;
-
- /* repeat last block n times */
- case 0x20:
- case 0x30:
- n_blocks = GET_BLOCK_COUNT();
-
- /* sanity check */
- if ((row_ptr == 0) && (pixel_ptr == 0)) {
- av_log(s->avctx, AV_LOG_INFO, "encountered repeat block opcode (%02X) but no blocks rendered yet\n",
- opcode & 0xF0);
- return;
- }
-
- /* figure out where the previous block started */
- if (pixel_ptr == 0)
- prev_block_ptr1 =
- (row_ptr - s->avctx->width * 4) + s->avctx->width - 4;
- else
- prev_block_ptr1 = row_ptr + pixel_ptr - 4;
-
- while (n_blocks--) {
- block_ptr = row_ptr + pixel_ptr;
- prev_block_ptr = prev_block_ptr1;
- for (pixel_y = 0; pixel_y < 4; pixel_y++) {
- for (pixel_x = 0; pixel_x < 4; pixel_x++) {
- pixels[block_ptr++] = pixels[prev_block_ptr++];
- }
- block_ptr += row_inc;
- prev_block_ptr += row_inc;
- }
- ADVANCE_BLOCK();
- }
- break;
-
- /* repeat previous pair of blocks n times */
- case 0x40:
- case 0x50:
- n_blocks = GET_BLOCK_COUNT();
- n_blocks *= 2;
-
- /* sanity check */
- if ((row_ptr == 0) && (pixel_ptr < 2 * 4)) {
- av_log(s->avctx, AV_LOG_INFO, "encountered repeat block opcode (%02X) but not enough blocks rendered yet\n",
- opcode & 0xF0);
- return;
- }
-
- /* figure out where the previous 2 blocks started */
- if (pixel_ptr == 0)
- prev_block_ptr1 = (row_ptr - s->avctx->width * 4) +
- s->avctx->width - 4 * 2;
- else if (pixel_ptr == 4)
- prev_block_ptr1 = (row_ptr - s->avctx->width * 4) + row_inc;
- else
- prev_block_ptr1 = row_ptr + pixel_ptr - 4 * 2;
-
- if (pixel_ptr == 0)
- prev_block_ptr2 = (row_ptr - s->avctx->width * 4) + row_inc;
- else
- prev_block_ptr2 = row_ptr + pixel_ptr - 4;
-
- prev_block_flag = 0;
- while (n_blocks--) {
- block_ptr = row_ptr + pixel_ptr;
- if (prev_block_flag)
- prev_block_ptr = prev_block_ptr2;
- else
- prev_block_ptr = prev_block_ptr1;
- prev_block_flag = !prev_block_flag;
-
- for (pixel_y = 0; pixel_y < 4; pixel_y++) {
- for (pixel_x = 0; pixel_x < 4; pixel_x++) {
- pixels[block_ptr++] = pixels[prev_block_ptr++];
- }
- block_ptr += row_inc;
- prev_block_ptr += row_inc;
- }
- ADVANCE_BLOCK();
- }
- break;
-
- /* 1-color block encoding */
- case 0x60:
- case 0x70:
- n_blocks = GET_BLOCK_COUNT();
- pixel = bytestream2_get_byte(&s->gb);
-
- while (n_blocks--) {
- block_ptr = row_ptr + pixel_ptr;
- for (pixel_y = 0; pixel_y < 4; pixel_y++) {
- for (pixel_x = 0; pixel_x < 4; pixel_x++) {
- pixels[block_ptr++] = pixel;
- }
- block_ptr += row_inc;
- }
- ADVANCE_BLOCK();
- }
- break;
-
- /* 2-color block encoding */
- case 0x80:
- case 0x90:
- n_blocks = (opcode & 0x0F) + 1;
-
- /* figure out which color pair to use to paint the 2-color block */
- if ((opcode & 0xF0) == 0x80) {
- /* fetch the next 2 colors from bytestream and store in next
- * available entry in the color pair table */
- for (i = 0; i < CPAIR; i++) {
- pixel = bytestream2_get_byte(&s->gb);
- color_table_index = CPAIR * color_pair_index + i;
- s->color_pairs[color_table_index] = pixel;
- }
- /* this is the base index to use for this block */
- color_table_index = CPAIR * color_pair_index;
- color_pair_index++;
- /* wraparound */
- if (color_pair_index == COLORS_PER_TABLE)
- color_pair_index = 0;
- } else
- color_table_index = CPAIR * bytestream2_get_byte(&s->gb);
-
- while (n_blocks--) {
- color_flags = bytestream2_get_be16(&s->gb);
- flag_mask = 0x8000;
- block_ptr = row_ptr + pixel_ptr;
- for (pixel_y = 0; pixel_y < 4; pixel_y++) {
- for (pixel_x = 0; pixel_x < 4; pixel_x++) {
- if (color_flags & flag_mask)
- pixel = color_table_index + 1;
- else
- pixel = color_table_index;
- flag_mask >>= 1;
- pixels[block_ptr++] = s->color_pairs[pixel];
- }
- block_ptr += row_inc;
- }
- ADVANCE_BLOCK();
- }
- break;
-
- /* 4-color block encoding */
- case 0xA0:
- case 0xB0:
- n_blocks = (opcode & 0x0F) + 1;
-
- /* figure out which color quad to use to paint the 4-color block */
- if ((opcode & 0xF0) == 0xA0) {
- /* fetch the next 4 colors from bytestream and store in next
- * available entry in the color quad table */
- for (i = 0; i < CQUAD; i++) {
- pixel = bytestream2_get_byte(&s->gb);
- color_table_index = CQUAD * color_quad_index + i;
- s->color_quads[color_table_index] = pixel;
- }
- /* this is the base index to use for this block */
- color_table_index = CQUAD * color_quad_index;
- color_quad_index++;
- /* wraparound */
- if (color_quad_index == COLORS_PER_TABLE)
- color_quad_index = 0;
- } else
- color_table_index = CQUAD * bytestream2_get_byte(&s->gb);
-
- while (n_blocks--) {
- color_flags = bytestream2_get_be32(&s->gb);
- /* flag mask actually acts as a bit shift count here */
- flag_mask = 30;
- block_ptr = row_ptr + pixel_ptr;
- for (pixel_y = 0; pixel_y < 4; pixel_y++) {
- for (pixel_x = 0; pixel_x < 4; pixel_x++) {
- pixel = color_table_index +
- ((color_flags >> flag_mask) & 0x03);
- flag_mask -= 2;
- pixels[block_ptr++] = s->color_quads[pixel];
- }
- block_ptr += row_inc;
- }
- ADVANCE_BLOCK();
- }
- break;
-
- /* 8-color block encoding */
- case 0xC0:
- case 0xD0:
- n_blocks = (opcode & 0x0F) + 1;
-
- /* figure out which color octet to use to paint the 8-color block */
- if ((opcode & 0xF0) == 0xC0) {
- /* fetch the next 8 colors from bytestream and store in next
- * available entry in the color octet table */
- for (i = 0; i < COCTET; i++) {
- pixel = bytestream2_get_byte(&s->gb);
- color_table_index = COCTET * color_octet_index + i;
- s->color_octets[color_table_index] = pixel;
- }
- /* this is the base index to use for this block */
- color_table_index = COCTET * color_octet_index;
- color_octet_index++;
- /* wraparound */
- if (color_octet_index == COLORS_PER_TABLE)
- color_octet_index = 0;
- } else
- color_table_index = COCTET * bytestream2_get_byte(&s->gb);
-
- while (n_blocks--) {
- /*
- For this input of 6 hex bytes:
- 01 23 45 67 89 AB
- Mangle it to this output:
- flags_a = xx012456, flags_b = xx89A37B
- */
- /* build the color flags */
- int val1 = bytestream2_get_be16(&s->gb);
- int val2 = bytestream2_get_be16(&s->gb);
- int val3 = bytestream2_get_be16(&s->gb);
- color_flags_a = ((val1 & 0xFFF0) << 8) | (val2 >> 4);
- color_flags_b = ((val3 & 0xFFF0) << 8) |
- ((val1 & 0x0F) << 8) | ((val2 & 0x0F) << 4) | (val3 & 0x0F);
-
- color_flags = color_flags_a;
- /* flag mask actually acts as a bit shift count here */
- flag_mask = 21;
- block_ptr = row_ptr + pixel_ptr;
- for (pixel_y = 0; pixel_y < 4; pixel_y++) {
- /* reload flags at third row (iteration pixel_y == 2) */
- if (pixel_y == 2) {
- color_flags = color_flags_b;
- flag_mask = 21;
- }
- for (pixel_x = 0; pixel_x < 4; pixel_x++) {
- pixel = color_table_index +
- ((color_flags >> flag_mask) & 0x07);
- flag_mask -= 3;
- pixels[block_ptr++] = s->color_octets[pixel];
- }
- block_ptr += row_inc;
- }
- ADVANCE_BLOCK();
- }
- break;
-
- /* 16-color block encoding (every pixel is a different color) */
- case 0xE0:
- n_blocks = (opcode & 0x0F) + 1;
-
- while (n_blocks--) {
- block_ptr = row_ptr + pixel_ptr;
- for (pixel_y = 0; pixel_y < 4; pixel_y++) {
- for (pixel_x = 0; pixel_x < 4; pixel_x++) {
- pixels[block_ptr++] = bytestream2_get_byte(&s->gb);
- }
- block_ptr += row_inc;
- }
- ADVANCE_BLOCK();
- }
- break;
-
- case 0xF0:
- avpriv_request_sample(s->avctx, "0xF0 opcode");
- break;
- }
- }
-
- return;
-}
-
-static av_cold int smc_decode_init(AVCodecContext *avctx)
-{
- SmcContext *s = avctx->priv_data;
-
- s->avctx = avctx;
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
-
- s->frame = av_frame_alloc();
- if (!s->frame)
- return AVERROR(ENOMEM);
-
- return 0;
-}
-
-static int smc_decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- SmcContext *s = avctx->priv_data;
- const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
- int ret;
-
- bytestream2_init(&s->gb, buf, buf_size);
-
- if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
- return ret;
-
- if (pal) {
- s->frame->palette_has_changed = 1;
- memcpy(s->pal, pal, AVPALETTE_SIZE);
- }
-
- smc_decode_stream(s);
-
- *got_frame = 1;
- if ((ret = av_frame_ref(data, s->frame)) < 0)
- return ret;
-
- /* always report that the buffer was completely consumed */
- return buf_size;
-}
-
-static av_cold int smc_decode_end(AVCodecContext *avctx)
-{
- SmcContext *s = avctx->priv_data;
-
- av_frame_free(&s->frame);
-
- return 0;
-}
-
-AVCodec ff_smc_decoder = {
- .name = "smc",
- .long_name = NULL_IF_CONFIG_SMALL("QuickTime Graphics (SMC)"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_SMC,
- .priv_data_size = sizeof(SmcContext),
- .init = smc_decode_init,
- .close = smc_decode_end,
- .decode = smc_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/snow.h b/ffmpeg-2-8-11/libavcodec/snow.h
deleted file mode 100644
index fd58f72..0000000
--- a/ffmpeg-2-8-11/libavcodec/snow.h
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- * Copyright (C) 2004 Michael Niedermayer <michaelni at gmx.at>
- * Copyright (C) 2006 Robert Edele <yartrebo at earthlink.net>
- *
- * 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_SNOW_H
-#define AVCODEC_SNOW_H
-
-#include "libavutil/motion_vector.h"
-
-#include "hpeldsp.h"
-#include "me_cmp.h"
-#include "qpeldsp.h"
-#include "snow_dwt.h"
-
-#include "rangecoder.h"
-#include "mathops.h"
-
-#define FF_MPV_OFFSET(x) (offsetof(MpegEncContext, x) + offsetof(SnowContext, m))
-#include "mpegvideo.h"
-#include "h264qpel.h"
-
-#define MID_STATE 128
-
-#define MAX_PLANES 4
-#define QSHIFT 5
-#define QROOT (1<<QSHIFT)
-#define LOSSLESS_QLOG -128
-#define FRAC_BITS 4
-#define MAX_REF_FRAMES 8
-
-#define LOG2_OBMC_MAX 8
-#define OBMC_MAX (1<<(LOG2_OBMC_MAX))
-typedef struct BlockNode{
- int16_t mx;
- int16_t my;
- uint8_t ref;
- uint8_t color[3];
- uint8_t type;
-//#define TYPE_SPLIT 1
-#define BLOCK_INTRA 1
-#define BLOCK_OPT 2
-//#define TYPE_NOCOLOR 4
- uint8_t level; //FIXME merge into type?
-}BlockNode;
-
-static const BlockNode null_block= { //FIXME add border maybe
- .color= {128,128,128},
- .mx= 0,
- .my= 0,
- .ref= 0,
- .type= 0,
- .level= 0,
-};
-
-#define LOG2_MB_SIZE 4
-#define MB_SIZE (1<<LOG2_MB_SIZE)
-#define ENCODER_EXTRA_BITS 4
-#define HTAPS_MAX 8
-
-typedef struct x_and_coeff{
- int16_t x;
- uint16_t coeff;
-} x_and_coeff;
-
-typedef struct SubBand{
- int level;
- int stride;
- int width;
- int height;
- int qlog; ///< log(qscale)/log[2^(1/6)]
- DWTELEM *buf;
- IDWTELEM *ibuf;
- int buf_x_offset;
- int buf_y_offset;
- int stride_line; ///< Stride measured in lines, not pixels.
- x_and_coeff * x_coeff;
- struct SubBand *parent;
- uint8_t state[/*7*2*/ 7 + 512][32];
-}SubBand;
-
-typedef struct Plane{
- int width;
- int height;
- SubBand band[MAX_DECOMPOSITIONS][4];
-
- int htaps;
- int8_t hcoeff[HTAPS_MAX/2];
- int diag_mc;
- int fast_mc;
-
- int last_htaps;
- int8_t last_hcoeff[HTAPS_MAX/2];
- int last_diag_mc;
-}Plane;
-
-typedef struct SnowContext{
- AVClass *class;
- AVCodecContext *avctx;
- RangeCoder c;
- MECmpContext mecc;
- HpelDSPContext hdsp;
- QpelDSPContext qdsp;
- VideoDSPContext vdsp;
- H264QpelContext h264qpel;
- MpegvideoEncDSPContext mpvencdsp;
- SnowDWTContext dwt;
- const AVFrame *new_picture;
- AVFrame *input_picture; ///< new_picture with the internal linesizes
- AVFrame *current_picture;
- AVFrame *last_picture[MAX_REF_FRAMES];
- uint8_t *halfpel_plane[MAX_REF_FRAMES][4][4];
- AVFrame *mconly_picture;
-// uint8_t q_context[16];
- uint8_t header_state[32];
- uint8_t block_state[128 + 32*128];
- int keyframe;
- int always_reset;
- int version;
- int spatial_decomposition_type;
- int last_spatial_decomposition_type;
- int temporal_decomposition_type;
- int spatial_decomposition_count;
- int last_spatial_decomposition_count;
- int temporal_decomposition_count;
- int max_ref_frames;
- int ref_frames;
- int16_t (*ref_mvs[MAX_REF_FRAMES])[2];
- uint32_t *ref_scores[MAX_REF_FRAMES];
- DWTELEM *spatial_dwt_buffer;
- DWTELEM *temp_dwt_buffer;
- IDWTELEM *spatial_idwt_buffer;
- IDWTELEM *temp_idwt_buffer;
- int *run_buffer;
- int colorspace_type;
- int chroma_h_shift;
- int chroma_v_shift;
- int spatial_scalability;
- int qlog;
- int last_qlog;
- int lambda;
- int lambda2;
- int pass1_rc;
- int mv_scale;
- int last_mv_scale;
- int qbias;
- int last_qbias;
-#define QBIAS_SHIFT 3
- int b_width;
- int b_height;
- int block_max_depth;
- int last_block_max_depth;
- int nb_planes;
- Plane plane[MAX_PLANES];
- BlockNode *block;
-#define ME_CACHE_SIZE 1024
- unsigned me_cache[ME_CACHE_SIZE];
- unsigned me_cache_generation;
- slice_buffer sb;
- int memc_only;
- int no_bitstream;
- int intra_penalty;
- int motion_est;
- int iterative_dia_size;
-
- MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX)
-
- uint8_t *scratchbuf;
- uint8_t *emu_edge_buffer;
-
- AVMotionVector *avmv;
- int avmv_index;
-}SnowContext;
-
-/* Tables */
-extern const uint8_t * const ff_obmc_tab[4];
-extern uint8_t ff_qexp[QROOT];
-extern int ff_scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES];
-
-/* C bits used by mmx/sse2/altivec */
-
-static av_always_inline void snow_interleave_line_header(int * i, int width, IDWTELEM * low, IDWTELEM * high){
- (*i) = (width) - 2;
-
- if (width & 1){
- low[(*i)+1] = low[((*i)+1)>>1];
- (*i)--;
- }
-}
-
-static av_always_inline void snow_interleave_line_footer(int * i, IDWTELEM * low, IDWTELEM * high){
- for (; (*i)>=0; (*i)-=2){
- low[(*i)+1] = high[(*i)>>1];
- low[*i] = low[(*i)>>1];
- }
-}
-
-static av_always_inline void snow_horizontal_compose_lift_lead_out(int i, IDWTELEM * dst, IDWTELEM * src, IDWTELEM * ref, int width, int w, int lift_high, int mul, int add, int shift){
- for(; i<w; i++){
- dst[i] = src[i] - ((mul * (ref[i] + ref[i + 1]) + add) >> shift);
- }
-
- if((width^lift_high)&1){
- dst[w] = src[w] - ((mul * 2 * ref[w] + add) >> shift);
- }
-}
-
-static av_always_inline void snow_horizontal_compose_liftS_lead_out(int i, IDWTELEM * dst, IDWTELEM * src, IDWTELEM * ref, int width, int w){
- for(; i<w; i++){
- dst[i] = src[i] + ((ref[i] + ref[(i+1)]+W_BO + 4 * src[i]) >> W_BS);
- }
-
- if(width&1){
- dst[w] = src[w] + ((2 * ref[w] + W_BO + 4 * src[w]) >> W_BS);
- }
-}
-
-/* common code */
-
-int ff_snow_common_init(AVCodecContext *avctx);
-int ff_snow_common_init_after_header(AVCodecContext *avctx);
-void ff_snow_common_end(SnowContext *s);
-void ff_snow_release_buffer(AVCodecContext *avctx);
-void ff_snow_reset_contexts(SnowContext *s);
-int ff_snow_alloc_blocks(SnowContext *s);
-int ff_snow_frame_start(SnowContext *s);
-void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, ptrdiff_t stride,
- int sx, int sy, int b_w, int b_h, const BlockNode *block,
- int plane_index, int w, int h);
-int ff_snow_get_buffer(SnowContext *s, AVFrame *frame);
-/* common inline functions */
-//XXX doublecheck all of them should stay inlined
-
-static inline void snow_set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){
- const int w= s->b_width << s->block_max_depth;
- const int rem_depth= s->block_max_depth - level;
- const int index= (x + y*w) << rem_depth;
- const int block_w= 1<<rem_depth;
- BlockNode block;
- int i,j;
-
- block.color[0]= l;
- block.color[1]= cb;
- block.color[2]= cr;
- block.mx= mx;
- block.my= my;
- block.ref= ref;
- block.type= type;
- block.level= level;
-
- for(j=0; j<block_w; j++){
- for(i=0; i<block_w; i++){
- s->block[index + i + j*w]= block;
- }
- }
-}
-
-static inline void pred_mv(SnowContext *s, int *mx, int *my, int ref,
- const BlockNode *left, const BlockNode *top, const BlockNode *tr){
- if(s->ref_frames == 1){
- *mx = mid_pred(left->mx, top->mx, tr->mx);
- *my = mid_pred(left->my, top->my, tr->my);
- }else{
- const int *scale = ff_scale_mv_ref[ref];
- *mx = mid_pred((left->mx * scale[left->ref] + 128) >>8,
- (top ->mx * scale[top ->ref] + 128) >>8,
- (tr ->mx * scale[tr ->ref] + 128) >>8);
- *my = mid_pred((left->my * scale[left->ref] + 128) >>8,
- (top ->my * scale[top ->ref] + 128) >>8,
- (tr ->my * scale[tr ->ref] + 128) >>8);
- }
-}
-
-static av_always_inline int same_block(BlockNode *a, BlockNode *b){
- if((a->type&BLOCK_INTRA) && (b->type&BLOCK_INTRA)){
- return !((a->color[0] - b->color[0]) | (a->color[1] - b->color[1]) | (a->color[2] - b->color[2]));
- }else{
- return !((a->mx - b->mx) | (a->my - b->my) | (a->ref - b->ref) | ((a->type ^ b->type)&BLOCK_INTRA));
- }
-}
-
-//FIXME name cleanup (b_w, block_w, b_width stuff)
-//XXX should we really inline it?
-static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer *sb, IDWTELEM *dst, uint8_t *dst8, const uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int offset_dst, int plane_index){
- const int b_width = s->b_width << s->block_max_depth;
- const int b_height= s->b_height << s->block_max_depth;
- const int b_stride= b_width;
- BlockNode *lt= &s->block[b_x + b_y*b_stride];
- BlockNode *rt= lt+1;
- BlockNode *lb= lt+b_stride;
- BlockNode *rb= lb+1;
- uint8_t *block[4];
- // When src_stride is large enough, it is possible to interleave the blocks.
- // Otherwise the blocks are written sequentially in the tmp buffer.
- int tmp_step= src_stride >= 7*MB_SIZE ? MB_SIZE : MB_SIZE*src_stride;
- uint8_t *tmp = s->scratchbuf;
- uint8_t *ptmp;
- int x,y;
-
- if(b_x<0){
- lt= rt;
- lb= rb;
- }else if(b_x + 1 >= b_width){
- rt= lt;
- rb= lb;
- }
- if(b_y<0){
- lt= lb;
- rt= rb;
- }else if(b_y + 1 >= b_height){
- lb= lt;
- rb= rt;
- }
-
- if(src_x<0){ //FIXME merge with prev & always round internal width up to *16
- obmc -= src_x;
- b_w += src_x;
- if(!sliced && !offset_dst)
- dst -= src_x;
- src_x=0;
- }
- if(src_x + b_w > w){
- b_w = w - src_x;
- }
- if(src_y<0){
- obmc -= src_y*obmc_stride;
- b_h += src_y;
- if(!sliced && !offset_dst)
- dst -= src_y*dst_stride;
- src_y=0;
- }
- if(src_y + b_h> h){
- b_h = h - src_y;
- }
-
- if(b_w<=0 || b_h<=0) return;
-
- if(!sliced && offset_dst)
- dst += src_x + src_y*dst_stride;
- dst8+= src_x + src_y*src_stride;
-// src += src_x + src_y*src_stride;
-
- ptmp= tmp + 3*tmp_step;
- block[0]= ptmp;
- ptmp+=tmp_step;
- ff_snow_pred_block(s, block[0], tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h);
-
- if(same_block(lt, rt)){
- block[1]= block[0];
- }else{
- block[1]= ptmp;
- ptmp+=tmp_step;
- ff_snow_pred_block(s, block[1], tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h);
- }
-
- if(same_block(lt, lb)){
- block[2]= block[0];
- }else if(same_block(rt, lb)){
- block[2]= block[1];
- }else{
- block[2]= ptmp;
- ptmp+=tmp_step;
- ff_snow_pred_block(s, block[2], tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h);
- }
-
- if(same_block(lt, rb) ){
- block[3]= block[0];
- }else if(same_block(rt, rb)){
- block[3]= block[1];
- }else if(same_block(lb, rb)){
- block[3]= block[2];
- }else{
- block[3]= ptmp;
- ff_snow_pred_block(s, block[3], tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h);
- }
- if(sliced){
- s->dwt.inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
- }else{
- for(y=0; y<b_h; y++){
- //FIXME ugly misuse of obmc_stride
- const uint8_t *obmc1= obmc + y*obmc_stride;
- const uint8_t *obmc2= obmc1+ (obmc_stride>>1);
- const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1);
- const uint8_t *obmc4= obmc3+ (obmc_stride>>1);
- for(x=0; x<b_w; x++){
- int v= obmc1[x] * block[3][x + y*src_stride]
- +obmc2[x] * block[2][x + y*src_stride]
- +obmc3[x] * block[1][x + y*src_stride]
- +obmc4[x] * block[0][x + y*src_stride];
-
- v <<= 8 - LOG2_OBMC_MAX;
- if(FRAC_BITS != 8){
- v >>= 8 - FRAC_BITS;
- }
- if(add){
- v += dst[x + y*dst_stride];
- v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS;
- if(v&(~255)) v= ~(v>>31);
- dst8[x + y*src_stride] = v;
- }else{
- dst[x + y*dst_stride] -= v;
- }
- }
- }
- }
-}
-
-static av_always_inline void predict_slice(SnowContext *s, IDWTELEM *buf, int plane_index, int add, int mb_y){
- Plane *p= &s->plane[plane_index];
- const int mb_w= s->b_width << s->block_max_depth;
- const int mb_h= s->b_height << s->block_max_depth;
- int x, y, mb_x;
- int block_size = MB_SIZE >> s->block_max_depth;
- int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size;
- int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size;
- const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth];
- const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
- int ref_stride= s->current_picture->linesize[plane_index];
- uint8_t *dst8= s->current_picture->data[plane_index];
- int w= p->width;
- int h= p->height;
- av_assert2(s->chroma_h_shift == s->chroma_v_shift); // obmc params assume squares
- if(s->keyframe || (s->avctx->debug&512)){
- if(mb_y==mb_h)
- return;
-
- if(add){
- for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
- for(x=0; x<w; x++){
- int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
- v >>= FRAC_BITS;
- if(v&(~255)) v= ~(v>>31);
- dst8[x + y*ref_stride]= v;
- }
- }
- }else{
- for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
- for(x=0; x<w; x++){
- buf[x + y*w]-= 128<<FRAC_BITS;
- }
- }
- }
-
- return;
- }
-
- for(mb_x=0; mb_x<=mb_w; mb_x++){
- add_yblock(s, 0, NULL, buf, dst8, obmc,
- block_w*mb_x - block_w/2,
- block_h*mb_y - block_h/2,
- block_w, block_h,
- w, h,
- w, ref_stride, obmc_stride,
- mb_x - 1, mb_y - 1,
- add, 1, plane_index);
- }
-}
-
-static av_always_inline void predict_plane(SnowContext *s, IDWTELEM *buf, int plane_index, int add){
- const int mb_h= s->b_height << s->block_max_depth;
- int mb_y;
- for(mb_y=0; mb_y<=mb_h; mb_y++)
- predict_slice(s, buf, plane_index, add, mb_y);
-}
-
-static inline void set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){
- const int w= s->b_width << s->block_max_depth;
- const int rem_depth= s->block_max_depth - level;
- const int index= (x + y*w) << rem_depth;
- const int block_w= 1<<rem_depth;
- const int block_h= 1<<rem_depth; //FIXME "w!=h"
- BlockNode block;
- int i,j;
-
- block.color[0]= l;
- block.color[1]= cb;
- block.color[2]= cr;
- block.mx= mx;
- block.my= my;
- block.ref= ref;
- block.type= type;
- block.level= level;
-
- for(j=0; j<block_h; j++){
- for(i=0; i<block_w; i++){
- s->block[index + i + j*w]= block;
- }
- }
-}
-
-static inline void init_ref(MotionEstContext *c, uint8_t *src[3], uint8_t *ref[3], uint8_t *ref2[3], int x, int y, int ref_index){
- SnowContext *s = c->avctx->priv_data;
- const int offset[3]= {
- y*c-> stride + x,
- ((y*c->uvstride + x)>>s->chroma_h_shift),
- ((y*c->uvstride + x)>>s->chroma_h_shift),
- };
- int i;
- for(i=0; i<3; i++){
- c->src[0][i]= src [i];
- c->ref[0][i]= ref [i] + offset[i];
- }
- av_assert2(!ref_index);
-}
-
-
-/* bitstream functions */
-
-extern const int8_t ff_quant3bA[256];
-
-#define QEXPSHIFT (7-FRAC_BITS+8) //FIXME try to change this to 0
-
-static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){
- int i;
-
- if(v){
- const int a= FFABS(v);
- const int e= av_log2(a);
- const int el= FFMIN(e, 10);
- put_rac(c, state+0, 0);
-
- for(i=0; i<el; i++){
- put_rac(c, state+1+i, 1); //1..10
- }
- for(; i<e; i++){
- put_rac(c, state+1+9, 1); //1..10
- }
- put_rac(c, state+1+FFMIN(i,9), 0);
-
- for(i=e-1; i>=el; i--){
- put_rac(c, state+22+9, (a>>i)&1); //22..31
- }
- for(; i>=0; i--){
- put_rac(c, state+22+i, (a>>i)&1); //22..31
- }
-
- if(is_signed)
- put_rac(c, state+11 + el, v < 0); //11..21
- }else{
- put_rac(c, state+0, 1);
- }
-}
-
-static inline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){
- if(get_rac(c, state+0))
- return 0;
- else{
- int i, e, a;
- e= 0;
- while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10
- e++;
- if (e > 31)
- return AVERROR_INVALIDDATA;
- }
-
- a= 1;
- for(i=e-1; i>=0; i--){
- a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31
- }
-
- e= -(is_signed && get_rac(c, state+11 + FFMIN(e,10))); //11..21
- return (a^e)-e;
- }
-}
-
-static inline void put_symbol2(RangeCoder *c, uint8_t *state, int v, int log2){
- int i;
- int r= log2>=0 ? 1<<log2 : 1;
-
- av_assert2(v>=0);
- av_assert2(log2>=-4);
-
- while(v >= r){
- put_rac(c, state+4+log2, 1);
- v -= r;
- log2++;
- if(log2>0) r+=r;
- }
- put_rac(c, state+4+log2, 0);
-
- for(i=log2-1; i>=0; i--){
- put_rac(c, state+31-i, (v>>i)&1);
- }
-}
-
-static inline int get_symbol2(RangeCoder *c, uint8_t *state, int log2){
- int i;
- int r= log2>=0 ? 1<<log2 : 1;
- int v=0;
-
- av_assert2(log2>=-4);
-
- while(log2<28 && get_rac(c, state+4+log2)){
- v+= r;
- log2++;
- if(log2>0) r+=r;
- }
-
- for(i=log2-1; i>=0; i--){
- v+= get_rac(c, state+31-i)<<i;
- }
-
- return v;
-}
-
-static inline void unpack_coeffs(SnowContext *s, SubBand *b, SubBand * parent, int orientation){
- const int w= b->width;
- const int h= b->height;
- int x,y;
-
- int run, runs;
- x_and_coeff *xc= b->x_coeff;
- x_and_coeff *prev_xc= NULL;
- x_and_coeff *prev2_xc= xc;
- x_and_coeff *parent_xc= parent ? parent->x_coeff : NULL;
- x_and_coeff *prev_parent_xc= parent_xc;
-
- runs= get_symbol2(&s->c, b->state[30], 0);
- if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3);
- else run= INT_MAX;
-
- for(y=0; y<h; y++){
- int v=0;
- int lt=0, t=0, rt=0;
-
- if(y && prev_xc->x == 0){
- rt= prev_xc->coeff;
- }
- for(x=0; x<w; x++){
- int p=0;
- const int l= v;
-
- lt= t; t= rt;
-
- if(y){
- if(prev_xc->x <= x)
- prev_xc++;
- if(prev_xc->x == x + 1)
- rt= prev_xc->coeff;
- else
- rt=0;
- }
- if(parent_xc){
- if(x>>1 > parent_xc->x){
- parent_xc++;
- }
- if(x>>1 == parent_xc->x){
- p= parent_xc->coeff;
- }
- }
- if(/*ll|*/l|lt|t|rt|p){
- int context= av_log2(/*FFABS(ll) + */3*(l>>1) + (lt>>1) + (t&~1) + (rt>>1) + (p>>1));
-
- v=get_rac(&s->c, &b->state[0][context]);
- if(v){
- v= 2*(get_symbol2(&s->c, b->state[context + 2], context-4) + 1);
- v+=get_rac(&s->c, &b->state[0][16 + 1 + 3 + ff_quant3bA[l&0xFF] + 3*ff_quant3bA[t&0xFF]]);
- if ((uint16_t)v != v) {
- av_log(s->avctx, AV_LOG_ERROR, "Coefficient damaged\n");
- v = 1;
- }
- xc->x=x;
- (xc++)->coeff= v;
- }
- }else{
- if(!run){
- if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3);
- else run= INT_MAX;
- v= 2*(get_symbol2(&s->c, b->state[0 + 2], 0-4) + 1);
- v+=get_rac(&s->c, &b->state[0][16 + 1 + 3]);
- if ((uint16_t)v != v) {
- av_log(s->avctx, AV_LOG_ERROR, "Coefficient damaged\n");
- v = 1;
- }
-
- xc->x=x;
- (xc++)->coeff= v;
- }else{
- int max_run;
- run--;
- v=0;
- av_assert2(run >= 0);
- if(y) max_run= FFMIN(run, prev_xc->x - x - 2);
- else max_run= FFMIN(run, w-x-1);
- if(parent_xc)
- max_run= FFMIN(max_run, 2*parent_xc->x - x - 1);
- av_assert2(max_run >= 0 && max_run <= run);
-
- x+= max_run;
- run-= max_run;
- }
- }
- }
- (xc++)->x= w+1; //end marker
- prev_xc= prev2_xc;
- prev2_xc= xc;
-
- if(parent_xc){
- if(y&1){
- while(parent_xc->x != parent->width+1)
- parent_xc++;
- parent_xc++;
- prev_parent_xc= parent_xc;
- }else{
- parent_xc= prev_parent_xc;
- }
- }
- }
-
- (xc++)->x= w+1; //end marker
-}
-
-#endif /* AVCODEC_SNOW_H */
diff --git a/ffmpeg-2-8-11/libavcodec/snowdec.c b/ffmpeg-2-8-11/libavcodec/snowdec.c
deleted file mode 100644
index 1b288dd..0000000
--- a/ffmpeg-2-8-11/libavcodec/snowdec.c
+++ /dev/null
@@ -1,648 +0,0 @@
-/*
- * Copyright (C) 2004 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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/intmath.h"
-#include "libavutil/log.h"
-#include "libavutil/opt.h"
-#include "avcodec.h"
-#include "snow_dwt.h"
-#include "internal.h"
-#include "snow.h"
-
-#include "rangecoder.h"
-#include "mathops.h"
-
-#include "mpegvideo.h"
-#include "h263.h"
-
-static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer * sb, IDWTELEM * old_buffer, int plane_index, int add, int mb_y){
- Plane *p= &s->plane[plane_index];
- const int mb_w= s->b_width << s->block_max_depth;
- const int mb_h= s->b_height << s->block_max_depth;
- int x, y, mb_x;
- int block_size = MB_SIZE >> s->block_max_depth;
- int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size;
- int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size;
- const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth];
- int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
- int ref_stride= s->current_picture->linesize[plane_index];
- uint8_t *dst8= s->current_picture->data[plane_index];
- int w= p->width;
- int h= p->height;
-
- if(s->keyframe || (s->avctx->debug&512)){
- if(mb_y==mb_h)
- return;
-
- if(add){
- for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
-// DWTELEM * line = slice_buffer_get_line(sb, y);
- IDWTELEM * line = sb->line[y];
- for(x=0; x<w; x++){
-// int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
- int v= line[x] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
- v >>= FRAC_BITS;
- if(v&(~255)) v= ~(v>>31);
- dst8[x + y*ref_stride]= v;
- }
- }
- }else{
- for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
-// DWTELEM * line = slice_buffer_get_line(sb, y);
- IDWTELEM * line = sb->line[y];
- for(x=0; x<w; x++){
- line[x] -= 128 << FRAC_BITS;
-// buf[x + y*w]-= 128<<FRAC_BITS;
- }
- }
- }
-
- return;
- }
-
- for(mb_x=0; mb_x<=mb_w; mb_x++){
- add_yblock(s, 1, sb, old_buffer, dst8, obmc,
- block_w*mb_x - block_w/2,
- block_h*mb_y - block_h/2,
- block_w, block_h,
- w, h,
- w, ref_stride, obmc_stride,
- mb_x - 1, mb_y - 1,
- add, 0, plane_index);
- }
-
- if(s->avmv && mb_y < mb_h && plane_index == 0)
- for(mb_x=0; mb_x<mb_w; mb_x++){
- AVMotionVector *avmv = s->avmv + s->avmv_index;
- const int b_width = s->b_width << s->block_max_depth;
- const int b_stride= b_width;
- BlockNode *bn= &s->block[mb_x + mb_y*b_stride];
-
- if (bn->type)
- continue;
-
- s->avmv_index++;
-
- avmv->w = block_w;
- avmv->h = block_h;
- avmv->dst_x = block_w*mb_x - block_w/2;
- avmv->dst_y = block_h*mb_y - block_h/2;
- avmv->src_x = avmv->dst_x + (bn->mx * s->mv_scale)/8;
- avmv->src_y = avmv->dst_y + (bn->my * s->mv_scale)/8;
- avmv->source= -1 - bn->ref;
- avmv->flags = 0;
- }
-}
-
-static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, slice_buffer * sb, int start_y, int h, int save_state[1]){
- const int w= b->width;
- int y;
- const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
- int qmul= ff_qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
- int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
- int new_index = 0;
-
- if(b->ibuf == s->spatial_idwt_buffer || s->qlog == LOSSLESS_QLOG){
- qadd= 0;
- qmul= 1<<QEXPSHIFT;
- }
-
- /* If we are on the second or later slice, restore our index. */
- if (start_y != 0)
- new_index = save_state[0];
-
-
- for(y=start_y; y<h; y++){
- int x = 0;
- int v;
- IDWTELEM * line = slice_buffer_get_line(sb, y * b->stride_line + b->buf_y_offset) + b->buf_x_offset;
- memset(line, 0, b->width*sizeof(IDWTELEM));
- v = b->x_coeff[new_index].coeff;
- x = b->x_coeff[new_index++].x;
- while(x < w){
- register int t= ( (v>>1)*qmul + qadd)>>QEXPSHIFT;
- register int u= -(v&1);
- line[x] = (t^u) - u;
-
- v = b->x_coeff[new_index].coeff;
- x = b->x_coeff[new_index++].x;
- }
- }
-
- /* Save our variables for the next slice. */
- save_state[0] = new_index;
-
- return;
-}
-
-static int decode_q_branch(SnowContext *s, int level, int x, int y){
- const int w= s->b_width << s->block_max_depth;
- const int rem_depth= s->block_max_depth - level;
- const int index= (x + y*w) << rem_depth;
- int trx= (x+1)<<rem_depth;
- const BlockNode *left = x ? &s->block[index-1] : &null_block;
- const BlockNode *top = y ? &s->block[index-w] : &null_block;
- const BlockNode *tl = y && x ? &s->block[index-w-1] : left;
- const BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
- int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
- int res;
-
- if(s->keyframe){
- set_blocks(s, level, x, y, null_block.color[0], null_block.color[1], null_block.color[2], null_block.mx, null_block.my, null_block.ref, BLOCK_INTRA);
- return 0;
- }
-
- if(level==s->block_max_depth || get_rac(&s->c, &s->block_state[4 + s_context])){
- int type, mx, my;
- int l = left->color[0];
- int cb= left->color[1];
- int cr= left->color[2];
- unsigned ref = 0;
- int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
- int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 0*av_log2(2*FFABS(tr->mx - top->mx));
- int my_context= av_log2(2*FFABS(left->my - top->my)) + 0*av_log2(2*FFABS(tr->my - top->my));
-
- type= get_rac(&s->c, &s->block_state[1 + left->type + top->type]) ? BLOCK_INTRA : 0;
-
- if(type){
- pred_mv(s, &mx, &my, 0, left, top, tr);
- l += get_symbol(&s->c, &s->block_state[32], 1);
- if (s->nb_planes > 2) {
- cb+= get_symbol(&s->c, &s->block_state[64], 1);
- cr+= get_symbol(&s->c, &s->block_state[96], 1);
- }
- }else{
- if(s->ref_frames > 1)
- ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0);
- if (ref >= s->ref_frames) {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid ref\n");
- return AVERROR_INVALIDDATA;
- }
- pred_mv(s, &mx, &my, ref, left, top, tr);
- mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1);
- my+= get_symbol(&s->c, &s->block_state[128 + 32*(my_context + 16*!!ref)], 1);
- }
- set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type);
- }else{
- if ((res = decode_q_branch(s, level+1, 2*x+0, 2*y+0)) < 0 ||
- (res = decode_q_branch(s, level+1, 2*x+1, 2*y+0)) < 0 ||
- (res = decode_q_branch(s, level+1, 2*x+0, 2*y+1)) < 0 ||
- (res = decode_q_branch(s, level+1, 2*x+1, 2*y+1)) < 0)
- return res;
- }
- return 0;
-}
-
-static void dequantize_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int start_y, int end_y){
- const int w= b->width;
- const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
- const int qmul= ff_qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
- const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
- int x,y;
-
- if(s->qlog == LOSSLESS_QLOG) return;
-
- for(y=start_y; y<end_y; y++){
-// DWTELEM * line = slice_buffer_get_line_from_address(sb, src + (y * stride));
- IDWTELEM * line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
- for(x=0; x<w; x++){
- int i= line[x];
- if(i<0){
- line[x]= -((-i*qmul + qadd)>>(QEXPSHIFT)); //FIXME try different bias
- }else if(i>0){
- line[x]= (( i*qmul + qadd)>>(QEXPSHIFT));
- }
- }
- }
-}
-
-static void correlate_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median, int start_y, int end_y){
- const int w= b->width;
- int x,y;
-
- IDWTELEM * line=0; // silence silly "could be used without having been initialized" warning
- IDWTELEM * prev;
-
- if (start_y != 0)
- line = slice_buffer_get_line(sb, ((start_y - 1) * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
-
- for(y=start_y; y<end_y; y++){
- prev = line;
-// line = slice_buffer_get_line_from_address(sb, src + (y * stride));
- line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
- for(x=0; x<w; x++){
- if(x){
- if(use_median){
- if(y && x+1<w) line[x] += mid_pred(line[x - 1], prev[x], prev[x + 1]);
- else line[x] += line[x - 1];
- }else{
- if(y) line[x] += mid_pred(line[x - 1], prev[x], line[x - 1] + prev[x] - prev[x - 1]);
- else line[x] += line[x - 1];
- }
- }else{
- if(y) line[x] += prev[x];
- }
- }
- }
-}
-
-static void decode_qlogs(SnowContext *s){
- int plane_index, level, orientation;
-
- for(plane_index=0; plane_index < s->nb_planes; plane_index++){
- for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1:0; orientation<4; orientation++){
- int q;
- if (plane_index==2) q= s->plane[1].band[level][orientation].qlog;
- else if(orientation==2) q= s->plane[plane_index].band[level][1].qlog;
- else q= get_symbol(&s->c, s->header_state, 1);
- s->plane[plane_index].band[level][orientation].qlog= q;
- }
- }
- }
-}
-
-#define GET_S(dst, check) \
- tmp= get_symbol(&s->c, s->header_state, 0);\
- if(!(check)){\
- av_log(s->avctx, AV_LOG_ERROR, "Error " #dst " is %d\n", tmp);\
- return AVERROR_INVALIDDATA;\
- }\
- dst= tmp;
-
-static int decode_header(SnowContext *s){
- int plane_index, tmp;
- uint8_t kstate[32];
-
- memset(kstate, MID_STATE, sizeof(kstate));
-
- s->keyframe= get_rac(&s->c, kstate);
- if(s->keyframe || s->always_reset){
- ff_snow_reset_contexts(s);
- s->spatial_decomposition_type=
- s->qlog=
- s->qbias=
- s->mv_scale=
- s->block_max_depth= 0;
- }
- if(s->keyframe){
- GET_S(s->version, tmp <= 0U)
- s->always_reset= get_rac(&s->c, s->header_state);
- s->temporal_decomposition_type= get_symbol(&s->c, s->header_state, 0);
- s->temporal_decomposition_count= get_symbol(&s->c, s->header_state, 0);
- GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS)
- s->colorspace_type= get_symbol(&s->c, s->header_state, 0);
- if (s->colorspace_type == 1) {
- s->avctx->pix_fmt= AV_PIX_FMT_GRAY8;
- s->nb_planes = 1;
- } else if(s->colorspace_type == 0) {
- s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0);
- s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0);
-
- if(s->chroma_h_shift == 1 && s->chroma_v_shift==1){
- s->avctx->pix_fmt= AV_PIX_FMT_YUV420P;
- }else if(s->chroma_h_shift == 0 && s->chroma_v_shift==0){
- s->avctx->pix_fmt= AV_PIX_FMT_YUV444P;
- }else if(s->chroma_h_shift == 2 && s->chroma_v_shift==2){
- s->avctx->pix_fmt= AV_PIX_FMT_YUV410P;
- } else {
- av_log(s, AV_LOG_ERROR, "unsupported color subsample mode %d %d\n", s->chroma_h_shift, s->chroma_v_shift);
- s->chroma_h_shift = s->chroma_v_shift = 1;
- s->avctx->pix_fmt= AV_PIX_FMT_YUV420P;
- return AVERROR_INVALIDDATA;
- }
- s->nb_planes = 3;
- } else {
- av_log(s, AV_LOG_ERROR, "unsupported color space\n");
- s->chroma_h_shift = s->chroma_v_shift = 1;
- s->avctx->pix_fmt= AV_PIX_FMT_YUV420P;
- return AVERROR_INVALIDDATA;
- }
-
-
- s->spatial_scalability= get_rac(&s->c, s->header_state);
-// s->rate_scalability= get_rac(&s->c, s->header_state);
- GET_S(s->max_ref_frames, tmp < (unsigned)MAX_REF_FRAMES)
- s->max_ref_frames++;
-
- decode_qlogs(s);
- }
-
- if(!s->keyframe){
- if(get_rac(&s->c, s->header_state)){
- for(plane_index=0; plane_index<FFMIN(s->nb_planes, 2); plane_index++){
- int htaps, i, sum=0;
- Plane *p= &s->plane[plane_index];
- p->diag_mc= get_rac(&s->c, s->header_state);
- htaps= get_symbol(&s->c, s->header_state, 0)*2 + 2;
- if((unsigned)htaps > HTAPS_MAX || htaps==0)
- return AVERROR_INVALIDDATA;
- p->htaps= htaps;
- for(i= htaps/2; i; i--){
- p->hcoeff[i]= get_symbol(&s->c, s->header_state, 0) * (1-2*(i&1));
- sum += p->hcoeff[i];
- }
- p->hcoeff[0]= 32-sum;
- }
- s->plane[2].diag_mc= s->plane[1].diag_mc;
- s->plane[2].htaps = s->plane[1].htaps;
- memcpy(s->plane[2].hcoeff, s->plane[1].hcoeff, sizeof(s->plane[1].hcoeff));
- }
- if(get_rac(&s->c, s->header_state)){
- GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS)
- decode_qlogs(s);
- }
- }
-
- s->spatial_decomposition_type+= get_symbol(&s->c, s->header_state, 1);
- if(s->spatial_decomposition_type > 1U){
- av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_type %d not supported\n", s->spatial_decomposition_type);
- return AVERROR_INVALIDDATA;
- }
- if(FFMIN(s->avctx-> width>>s->chroma_h_shift,
- s->avctx->height>>s->chroma_v_shift) >> (s->spatial_decomposition_count-1) <= 1){
- av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_count %d too large for size\n", s->spatial_decomposition_count);
- return AVERROR_INVALIDDATA;
- }
-
-
- s->qlog += get_symbol(&s->c, s->header_state, 1);
- s->mv_scale += get_symbol(&s->c, s->header_state, 1);
- s->qbias += get_symbol(&s->c, s->header_state, 1);
- s->block_max_depth+= get_symbol(&s->c, s->header_state, 1);
- if(s->block_max_depth > 1 || s->block_max_depth < 0){
- av_log(s->avctx, AV_LOG_ERROR, "block_max_depth= %d is too large\n", s->block_max_depth);
- s->block_max_depth= 0;
- return AVERROR_INVALIDDATA;
- }
-
- 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;
- int h= s->b_height;
- int res;
-
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- if ((res = decode_q_branch(s, 0, x, y)) < 0)
- return res;
- }
- }
- return 0;
-}
-
-static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- SnowContext *s = avctx->priv_data;
- RangeCoder * const c= &s->c;
- int bytes_read;
- AVFrame *picture = data;
- int level, orientation, plane_index;
- int res;
-
- ff_init_range_decoder(c, buf, buf_size);
- ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
-
- s->current_picture->pict_type= AV_PICTURE_TYPE_I; //FIXME I vs. P
- if ((res = decode_header(s)) < 0)
- return res;
- if ((res=ff_snow_common_init_after_header(avctx)) < 0)
- return res;
-
- // realloc slice buffer for the case that spatial_decomposition_count changed
- ff_slice_buffer_destroy(&s->sb);
- if ((res = ff_slice_buffer_init(&s->sb, s->plane[0].height,
- (MB_SIZE >> s->block_max_depth) +
- s->spatial_decomposition_count * 11 + 1,
- s->plane[0].width,
- s->spatial_idwt_buffer)) < 0)
- return res;
-
- for(plane_index=0; plane_index < s->nb_planes; plane_index++){
- Plane *p= &s->plane[plane_index];
- p->fast_mc= p->diag_mc && p->htaps==6 && p->hcoeff[0]==40
- && p->hcoeff[1]==-10
- && p->hcoeff[2]==2;
- }
-
- ff_snow_alloc_blocks(s);
-
- if((res = ff_snow_frame_start(s)) < 0)
- return res;
-
- s->current_picture->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
-
- //keyframe flag duplication mess FIXME
- if(avctx->debug&FF_DEBUG_PICT_INFO)
- av_log(avctx, AV_LOG_ERROR,
- "keyframe:%d qlog:%d qbias: %d mvscale: %d "
- "decomposition_type:%d decomposition_count:%d\n",
- s->keyframe, s->qlog, s->qbias, s->mv_scale,
- s->spatial_decomposition_type,
- s->spatial_decomposition_count
- );
-
- av_assert0(!s->avmv);
- if (s->avctx->flags2 & AV_CODEC_FLAG2_EXPORT_MVS) {
- s->avmv = av_malloc_array(s->b_width * s->b_height, sizeof(AVMotionVector) << (s->block_max_depth*2));
- }
- s->avmv_index = 0;
-
- if ((res = decode_blocks(s)) < 0)
- return res;
-
- for(plane_index=0; plane_index < s->nb_planes; plane_index++){
- Plane *p= &s->plane[plane_index];
- int w= p->width;
- int h= p->height;
- int x, y;
- int decode_state[MAX_DECOMPOSITIONS][4][1]; /* Stored state info for unpack_coeffs. 1 variable per instance. */
-
- if(s->avctx->debug&2048){
- memset(s->spatial_dwt_buffer, 0, sizeof(DWTELEM)*w*h);
- predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
-
- for(y=0; y<h; y++){
- for(x=0; x<w; x++){
- int v= s->current_picture->data[plane_index][y*s->current_picture->linesize[plane_index] + x];
- s->mconly_picture->data[plane_index][y*s->mconly_picture->linesize[plane_index] + x]= v;
- }
- }
- }
-
- {
- for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1 : 0; orientation<4; orientation++){
- SubBand *b= &p->band[level][orientation];
- unpack_coeffs(s, b, b->parent, orientation);
- }
- }
- }
-
- {
- const int mb_h= s->b_height << s->block_max_depth;
- const int block_size = MB_SIZE >> s->block_max_depth;
- const int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size;
- int mb_y;
- DWTCompose cs[MAX_DECOMPOSITIONS];
- int yd=0, yq=0;
- int y;
- int end_y;
-
- ff_spatial_idwt_buffered_init(cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count);
- for(mb_y=0; mb_y<=mb_h; mb_y++){
-
- int slice_starty = block_h*mb_y;
- int slice_h = block_h*(mb_y+1);
-
- if (!(s->keyframe || s->avctx->debug&512)){
- slice_starty = FFMAX(0, slice_starty - (block_h >> 1));
- slice_h -= (block_h >> 1);
- }
-
- for(level=0; level<s->spatial_decomposition_count; level++){
- for(orientation=level ? 1 : 0; orientation<4; orientation++){
- SubBand *b= &p->band[level][orientation];
- int start_y;
- int end_y;
- int our_mb_start = mb_y;
- int our_mb_end = (mb_y + 1);
- const int extra= 3;
- start_y = (mb_y ? ((block_h * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0);
- end_y = (((block_h * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra);
- if (!(s->keyframe || s->avctx->debug&512)){
- start_y = FFMAX(0, start_y - (block_h >> (1+s->spatial_decomposition_count - level)));
- end_y = FFMAX(0, end_y - (block_h >> (1+s->spatial_decomposition_count - level)));
- }
- start_y = FFMIN(b->height, start_y);
- end_y = FFMIN(b->height, end_y);
-
- if (start_y != end_y){
- if (orientation == 0){
- SubBand * correlate_band = &p->band[0][0];
- int correlate_end_y = FFMIN(b->height, end_y + 1);
- int correlate_start_y = FFMIN(b->height, (start_y ? start_y + 1 : 0));
- decode_subband_slice_buffered(s, correlate_band, &s->sb, correlate_start_y, correlate_end_y, decode_state[0][0]);
- correlate_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, 1, 0, correlate_start_y, correlate_end_y);
- dequantize_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, start_y, end_y);
- }
- else
- decode_subband_slice_buffered(s, b, &s->sb, start_y, end_y, decode_state[level][orientation]);
- }
- }
- }
-
- for(; yd<slice_h; yd+=4){
- ff_spatial_idwt_buffered_slice(&s->dwt, cs, &s->sb, s->temp_idwt_buffer, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count, yd);
- }
-
- if(s->qlog == LOSSLESS_QLOG){
- for(; yq<slice_h && yq<h; yq++){
- IDWTELEM * line = slice_buffer_get_line(&s->sb, yq);
- for(x=0; x<w; x++){
- line[x] <<= FRAC_BITS;
- }
- }
- }
-
- predict_slice_buffered(s, &s->sb, s->spatial_idwt_buffer, plane_index, 1, mb_y);
-
- y = FFMIN(p->height, slice_starty);
- end_y = FFMIN(p->height, slice_h);
- while(y < end_y)
- ff_slice_buffer_release(&s->sb, y++);
- }
-
- ff_slice_buffer_flush(&s->sb);
- }
-
- }
-
- emms_c();
-
- ff_snow_release_buffer(avctx);
-
- if(!(s->avctx->debug&2048))
- res = av_frame_ref(picture, s->current_picture);
- else
- res = av_frame_ref(picture, s->mconly_picture);
- if (res >= 0 && s->avmv_index) {
- AVFrameSideData *sd;
-
- sd = av_frame_new_side_data(picture, AV_FRAME_DATA_MOTION_VECTORS, s->avmv_index * sizeof(AVMotionVector));
- if (!sd)
- return AVERROR(ENOMEM);
- memcpy(sd->data, s->avmv, s->avmv_index * sizeof(AVMotionVector));
- }
-
- av_freep(&s->avmv);
-
- if (res < 0)
- return res;
-
- *got_frame = 1;
-
- bytes_read= c->bytestream - c->bytestream_start;
- if(bytes_read ==0) av_log(s->avctx, AV_LOG_ERROR, "error at end of frame\n"); //FIXME
-
- return bytes_read;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx)
-{
- SnowContext *s = avctx->priv_data;
-
- ff_slice_buffer_destroy(&s->sb);
-
- ff_snow_common_end(s);
-
- return 0;
-}
-
-AVCodec ff_snow_decoder = {
- .name = "snow",
- .long_name = NULL_IF_CONFIG_SMALL("Snow"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_SNOW,
- .priv_data_size = sizeof(SnowContext),
- .init = decode_init,
- .close = decode_end,
- .decode = decode_frame,
- .capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/,
- .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
- FF_CODEC_CAP_INIT_CLEANUP,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/srtdec.c b/ffmpeg-2-8-11/libavcodec/srtdec.c
deleted file mode 100644
index ed3af95..0000000
--- a/ffmpeg-2-8-11/libavcodec/srtdec.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * SubRip subtitle decoder
- * Copyright (c) 2010 Aurelien Jacobs <aurel at gnuage.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
- */
-
-#include "libavutil/avstring.h"
-#include "libavutil/common.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/parseutils.h"
-#include "avcodec.h"
-#include "ass.h"
-
-static int html_color_parse(AVCodecContext *avctx, const char *str)
-{
- uint8_t rgba[4];
- if (av_parse_color(rgba, str, strcspn(str, "\" >"), avctx) < 0)
- return -1;
- return rgba[0] | rgba[1] << 8 | rgba[2] << 16;
-}
-
-enum {
- PARAM_UNKNOWN = -1,
- PARAM_SIZE,
- PARAM_COLOR,
- PARAM_FACE,
- PARAM_NUMBER
-};
-
-typedef struct SrtStack {
- char tag[128];
- char param[PARAM_NUMBER][128];
-} SrtStack;
-
-static void rstrip_spaces_buf(AVBPrint *buf)
-{
- while (buf->len > 0 && buf->str[buf->len - 1] == ' ')
- buf->str[--buf->len] = 0;
-}
-
-static void srt_to_ass(AVCodecContext *avctx, AVBPrint *dst,
- const char *in, int x1, int y1, int x2, int y2)
-{
- char *param, buffer[128], tmp[128];
- int len, tag_close, sptr = 1, line_start = 1, an = 0, end = 0;
- SrtStack stack[16];
-
- stack[0].tag[0] = 0;
- strcpy(stack[0].param[PARAM_SIZE], "{\\fs}");
- strcpy(stack[0].param[PARAM_COLOR], "{\\c}");
- strcpy(stack[0].param[PARAM_FACE], "{\\fn}");
-
- if (x1 >= 0 && y1 >= 0) {
- /* XXX: here we rescale coordinate assuming they are in DVD resolution
- * (720x480) since we don't have anything better */
-
- if (x2 >= 0 && y2 >= 0 && (x2 != x1 || y2 != y1) && x2 >= x1 && y2 >= y1) {
- /* text rectangle defined, write the text at the center of the rectangle */
- const int cx = x1 + (x2 - x1)/2;
- const int cy = y1 + (y2 - y1)/2;
- const int scaled_x = cx * ASS_DEFAULT_PLAYRESX / 720;
- const int scaled_y = cy * ASS_DEFAULT_PLAYRESY / 480;
- av_bprintf(dst, "{\\an5}{\\pos(%d,%d)}", scaled_x, scaled_y);
- } else {
- /* only the top left corner, assume the text starts in that corner */
- const int scaled_x = x1 * ASS_DEFAULT_PLAYRESX / 720;
- const int scaled_y = y1 * ASS_DEFAULT_PLAYRESY / 480;
- av_bprintf(dst, "{\\an1}{\\pos(%d,%d)}", scaled_x, scaled_y);
- }
- }
-
- for (; !end && *in; in++) {
- switch (*in) {
- case '\r':
- break;
- case '\n':
- if (line_start) {
- end = 1;
- break;
- }
- rstrip_spaces_buf(dst);
- av_bprintf(dst, "\\N");
- line_start = 1;
- break;
- case ' ':
- if (!line_start)
- av_bprint_chars(dst, *in, 1);
- break;
- case '{': /* skip all {\xxx} substrings except for {\an%d}
- and all microdvd like styles such as {Y:xxx} */
- len = 0;
- an += sscanf(in, "{\\an%*1u}%n", &len) >= 0 && len > 0;
- if ((an != 1 && (len = 0, sscanf(in, "{\\%*[^}]}%n", &len) >= 0 && len > 0)) ||
- (len = 0, sscanf(in, "{%*1[CcFfoPSsYy]:%*[^}]}%n", &len) >= 0 && len > 0)) {
- in += len - 1;
- } else
- av_bprint_chars(dst, *in, 1);
- break;
- case '<':
- tag_close = in[1] == '/';
- len = 0;
- if (sscanf(in+tag_close+1, "%127[^>]>%n", buffer, &len) >= 1 && len > 0) {
- if ((param = strchr(buffer, ' ')))
- *param++ = 0;
- if ((!tag_close && sptr < FF_ARRAY_ELEMS(stack)) ||
- ( tag_close && sptr > 0 && !strcmp(stack[sptr-1].tag, buffer))) {
- int i, j, unknown = 0;
- in += len + tag_close;
- if (!tag_close)
- memset(stack+sptr, 0, sizeof(*stack));
- if (!strcmp(buffer, "font")) {
- if (tag_close) {
- for (i=PARAM_NUMBER-1; i>=0; i--)
- if (stack[sptr-1].param[i][0])
- for (j=sptr-2; j>=0; j--)
- if (stack[j].param[i][0]) {
- av_bprintf(dst, "%s", stack[j].param[i]);
- break;
- }
- } else {
- while (param) {
- if (!strncmp(param, "size=", 5)) {
- unsigned font_size;
- param += 5 + (param[5] == '"');
- if (sscanf(param, "%u", &font_size) == 1) {
- snprintf(stack[sptr].param[PARAM_SIZE],
- sizeof(stack[0].param[PARAM_SIZE]),
- "{\\fs%u}", font_size);
- }
- } else if (!strncmp(param, "color=", 6)) {
- param += 6 + (param[6] == '"');
- snprintf(stack[sptr].param[PARAM_COLOR],
- sizeof(stack[0].param[PARAM_COLOR]),
- "{\\c&H%X&}",
- html_color_parse(avctx, param));
- } else if (!strncmp(param, "face=", 5)) {
- param += 5 + (param[5] == '"');
- len = strcspn(param,
- param[-1] == '"' ? "\"" :" ");
- av_strlcpy(tmp, param,
- FFMIN(sizeof(tmp), len+1));
- param += len;
- snprintf(stack[sptr].param[PARAM_FACE],
- sizeof(stack[0].param[PARAM_FACE]),
- "{\\fn%s}", tmp);
- }
- if ((param = strchr(param, ' ')))
- param++;
- }
- for (i=0; i<PARAM_NUMBER; i++)
- if (stack[sptr].param[i][0])
- av_bprintf(dst, "%s", stack[sptr].param[i]);
- }
- } else if (!buffer[1] && strspn(buffer, "bisu") == 1) {
- av_bprintf(dst, "{\\%c%d}", buffer[0], !tag_close);
- } else {
- unknown = 1;
- snprintf(tmp, sizeof(tmp), "</%s>", buffer);
- }
- if (tag_close) {
- sptr--;
- } else if (unknown && !strstr(in, tmp)) {
- in -= len + tag_close;
- av_bprint_chars(dst, *in, 1);
- } else
- av_strlcpy(stack[sptr++].tag, buffer,
- sizeof(stack[0].tag));
- break;
- }
- }
- default:
- av_bprint_chars(dst, *in, 1);
- break;
- }
- if (*in != ' ' && *in != '\r' && *in != '\n')
- line_start = 0;
- }
-
- while (dst->len >= 2 && !strncmp(&dst->str[dst->len - 2], "\\N", 2))
- dst->len -= 2;
- dst->str[dst->len] = 0;
- rstrip_spaces_buf(dst);
-}
-
-static int srt_decode_frame(AVCodecContext *avctx,
- void *data, int *got_sub_ptr, AVPacket *avpkt)
-{
- AVSubtitle *sub = data;
- AVBPrint buffer;
- int ts_start, ts_end, x1 = -1, y1 = -1, x2 = -1, y2 = -1;
- int size, ret;
- const uint8_t *p = av_packet_get_side_data(avpkt, AV_PKT_DATA_SUBTITLE_POSITION, &size);
-
- if (p && size == 16) {
- x1 = AV_RL32(p );
- y1 = AV_RL32(p + 4);
- x2 = AV_RL32(p + 8);
- y2 = AV_RL32(p + 12);
- }
-
- if (avpkt->size <= 0)
- return avpkt->size;
-
- av_bprint_init(&buffer, 0, AV_BPRINT_SIZE_UNLIMITED);
-
- // TODO: reindent
- // Do final divide-by-10 outside rescale to force rounding down.
- ts_start = av_rescale_q(avpkt->pts,
- avctx->time_base,
- (AVRational){1,100});
- ts_end = av_rescale_q(avpkt->pts + avpkt->duration,
- avctx->time_base,
- (AVRational){1,100});
-
- srt_to_ass(avctx, &buffer, avpkt->data, x1, y1, x2, y2);
- ret = ff_ass_add_rect_bprint(sub, &buffer, ts_start, ts_end-ts_start);
- av_bprint_finalize(&buffer, NULL);
- if (ret < 0)
- return ret;
-
- *got_sub_ptr = sub->num_rects > 0;
- return avpkt->size;
-}
-
-#if CONFIG_SRT_DECODER
-/* deprecated decoder */
-AVCodec ff_srt_decoder = {
- .name = "srt",
- .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
- .type = AVMEDIA_TYPE_SUBTITLE,
- .id = AV_CODEC_ID_SUBRIP,
- .init = ff_ass_subtitle_header_default,
- .decode = srt_decode_frame,
-};
-#endif
-
-#if CONFIG_SUBRIP_DECODER
-AVCodec ff_subrip_decoder = {
- .name = "subrip",
- .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
- .type = AVMEDIA_TYPE_SUBTITLE,
- .id = AV_CODEC_ID_SUBRIP,
- .init = ff_ass_subtitle_header_default,
- .decode = srt_decode_frame,
-};
-#endif
diff --git a/ffmpeg-2-8-11/libavcodec/svq3.c b/ffmpeg-2-8-11/libavcodec/svq3.c
deleted file mode 100644
index 57205c6..0000000
--- a/ffmpeg-2-8-11/libavcodec/svq3.c
+++ /dev/null
@@ -1,1422 +0,0 @@
-/*
- * Copyright (c) 2003 The FFmpeg Project
- *
- * 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
- */
-
-/*
- * How to use this decoder:
- * SVQ3 data is transported within Apple Quicktime files. Quicktime files
- * have stsd atoms to describe media trak properties. A stsd atom for a
- * video trak contains 1 or more ImageDescription atoms. These atoms begin
- * with the 4-byte length of the atom followed by the codec fourcc. Some
- * decoders need information in this atom to operate correctly. Such
- * is the case with SVQ3. In order to get the best use out of this decoder,
- * the calling app must make the SVQ3 ImageDescription atom available
- * via the AVCodecContext's extradata[_size] field:
- *
- * AVCodecContext.extradata = pointer to ImageDescription, first characters
- * are expected to be 'S', 'V', 'Q', and '3', NOT the 4-byte atom length
- * AVCodecContext.extradata_size = size of ImageDescription atom memory
- * buffer (which will be the same as the ImageDescription atom size field
- * from the QT file, minus 4 bytes since the length is missing)
- *
- * You will know you have these parameters passed correctly when the decoder
- * correctly decodes this file:
- * http://samples.mplayerhq.hu/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov
- */
-
-#include <inttypes.h>
-
-#include "libavutil/attributes.h"
-#include "internal.h"
-#include "avcodec.h"
-#include "mpegutils.h"
-#include "h264.h"
-
-#include "h264data.h" // FIXME FIXME FIXME
-
-#include "h264_mvpred.h"
-#include "golomb.h"
-#include "hpeldsp.h"
-#include "rectangle.h"
-#include "tpeldsp.h"
-#include "vdpau_internal.h"
-
-#if CONFIG_ZLIB
-#include <zlib.h>
-#endif
-
-#include "svq1.h"
-#include "svq3.h"
-
-/**
- * @file
- * svq3 decoder.
- */
-
-typedef struct SVQ3Context {
- H264Context h;
- HpelDSPContext hdsp;
- TpelDSPContext tdsp;
- H264Picture *cur_pic;
- H264Picture *next_pic;
- H264Picture *last_pic;
- int halfpel_flag;
- int thirdpel_flag;
- int has_watermark;
- int next_slice_index;
- uint32_t watermark_key;
- uint8_t *buf;
- int buf_size;
- int adaptive_quant;
- int next_p_frame_damaged;
- int h_edge_pos;
- int v_edge_pos;
- int last_frame_output;
-} SVQ3Context;
-
-#define FULLPEL_MODE 1
-#define HALFPEL_MODE 2
-#define THIRDPEL_MODE 3
-#define PREDICT_MODE 4
-
-/* dual scan (from some older h264 draft)
- * o-->o-->o o
- * | /|
- * o o o / o
- * | / | |/ |
- * o o o o
- * /
- * o-->o-->o-->o
- */
-static const uint8_t svq3_scan[16] = {
- 0 + 0 * 4, 1 + 0 * 4, 2 + 0 * 4, 2 + 1 * 4,
- 2 + 2 * 4, 3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4,
- 0 + 1 * 4, 0 + 2 * 4, 1 + 1 * 4, 1 + 2 * 4,
- 0 + 3 * 4, 1 + 3 * 4, 2 + 3 * 4, 3 + 3 * 4,
-};
-
-static const uint8_t luma_dc_zigzag_scan[16] = {
- 0 * 16 + 0 * 64, 1 * 16 + 0 * 64, 2 * 16 + 0 * 64, 0 * 16 + 2 * 64,
- 3 * 16 + 0 * 64, 0 * 16 + 1 * 64, 1 * 16 + 1 * 64, 2 * 16 + 1 * 64,
- 1 * 16 + 2 * 64, 2 * 16 + 2 * 64, 3 * 16 + 2 * 64, 0 * 16 + 3 * 64,
- 3 * 16 + 1 * 64, 1 * 16 + 3 * 64, 2 * 16 + 3 * 64, 3 * 16 + 3 * 64,
-};
-
-static const uint8_t svq3_pred_0[25][2] = {
- { 0, 0 },
- { 1, 0 }, { 0, 1 },
- { 0, 2 }, { 1, 1 }, { 2, 0 },
- { 3, 0 }, { 2, 1 }, { 1, 2 }, { 0, 3 },
- { 0, 4 }, { 1, 3 }, { 2, 2 }, { 3, 1 }, { 4, 0 },
- { 4, 1 }, { 3, 2 }, { 2, 3 }, { 1, 4 },
- { 2, 4 }, { 3, 3 }, { 4, 2 },
- { 4, 3 }, { 3, 4 },
- { 4, 4 }
-};
-
-static const int8_t svq3_pred_1[6][6][5] = {
- { { 2, -1, -1, -1, -1 }, { 2, 1, -1, -1, -1 }, { 1, 2, -1, -1, -1 },
- { 2, 1, -1, -1, -1 }, { 1, 2, -1, -1, -1 }, { 1, 2, -1, -1, -1 } },
- { { 0, 2, -1, -1, -1 }, { 0, 2, 1, 4, 3 }, { 0, 1, 2, 4, 3 },
- { 0, 2, 1, 4, 3 }, { 2, 0, 1, 3, 4 }, { 0, 4, 2, 1, 3 } },
- { { 2, 0, -1, -1, -1 }, { 2, 1, 0, 4, 3 }, { 1, 2, 4, 0, 3 },
- { 2, 1, 0, 4, 3 }, { 2, 1, 4, 3, 0 }, { 1, 2, 4, 0, 3 } },
- { { 2, 0, -1, -1, -1 }, { 2, 0, 1, 4, 3 }, { 1, 2, 0, 4, 3 },
- { 2, 1, 0, 4, 3 }, { 2, 1, 3, 4, 0 }, { 2, 4, 1, 0, 3 } },
- { { 0, 2, -1, -1, -1 }, { 0, 2, 1, 3, 4 }, { 1, 2, 3, 0, 4 },
- { 2, 0, 1, 3, 4 }, { 2, 1, 3, 0, 4 }, { 2, 0, 4, 3, 1 } },
- { { 0, 2, -1, -1, -1 }, { 0, 2, 4, 1, 3 }, { 1, 4, 2, 0, 3 },
- { 4, 2, 0, 1, 3 }, { 2, 0, 1, 4, 3 }, { 4, 2, 1, 0, 3 } },
-};
-
-static const struct {
- uint8_t run;
- uint8_t level;
-} svq3_dct_tables[2][16] = {
- { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 2, 1 }, { 0, 2 }, { 3, 1 }, { 4, 1 }, { 5, 1 },
- { 0, 3 }, { 1, 2 }, { 2, 2 }, { 6, 1 }, { 7, 1 }, { 8, 1 }, { 9, 1 }, { 0, 4 } },
- { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 0, 2 }, { 2, 1 }, { 0, 3 }, { 0, 4 }, { 0, 5 },
- { 3, 1 }, { 4, 1 }, { 1, 2 }, { 1, 3 }, { 0, 6 }, { 0, 7 }, { 0, 8 }, { 0, 9 } }
-};
-
-static const uint32_t svq3_dequant_coeff[32] = {
- 3881, 4351, 4890, 5481, 6154, 6914, 7761, 8718,
- 9781, 10987, 12339, 13828, 15523, 17435, 19561, 21873,
- 24552, 27656, 30847, 34870, 38807, 43747, 49103, 54683,
- 61694, 68745, 77615, 89113, 100253, 109366, 126635, 141533
-};
-
-static int svq3_decode_end(AVCodecContext *avctx);
-
-void ff_svq3_luma_dc_dequant_idct_c(int16_t *output, int16_t *input, int qp)
-{
- const int qmul = svq3_dequant_coeff[qp];
-#define stride 16
- int i;
- int temp[16];
- static const uint8_t x_offset[4] = { 0, 1 * stride, 4 * stride, 5 * stride };
-
- for (i = 0; i < 4; i++) {
- const int z0 = 13 * (input[4 * i + 0] + input[4 * i + 2]);
- const int z1 = 13 * (input[4 * i + 0] - input[4 * i + 2]);
- const int z2 = 7 * input[4 * i + 1] - 17 * input[4 * i + 3];
- const int z3 = 17 * input[4 * i + 1] + 7 * input[4 * i + 3];
-
- temp[4 * i + 0] = z0 + z3;
- temp[4 * i + 1] = z1 + z2;
- temp[4 * i + 2] = z1 - z2;
- temp[4 * i + 3] = z0 - z3;
- }
-
- for (i = 0; i < 4; i++) {
- const int offset = x_offset[i];
- const int z0 = 13 * (temp[4 * 0 + i] + temp[4 * 2 + i]);
- const int z1 = 13 * (temp[4 * 0 + i] - temp[4 * 2 + i]);
- const int z2 = 7 * temp[4 * 1 + i] - 17 * temp[4 * 3 + i];
- const int z3 = 17 * temp[4 * 1 + i] + 7 * temp[4 * 3 + i];
-
- output[stride * 0 + offset] = (z0 + z3) * qmul + 0x80000 >> 20;
- output[stride * 2 + offset] = (z1 + z2) * qmul + 0x80000 >> 20;
- output[stride * 8 + offset] = (z1 - z2) * qmul + 0x80000 >> 20;
- output[stride * 10 + offset] = (z0 - z3) * qmul + 0x80000 >> 20;
- }
-}
-#undef stride
-
-void ff_svq3_add_idct_c(uint8_t *dst, int16_t *block,
- int stride, int qp, int dc)
-{
- const int qmul = svq3_dequant_coeff[qp];
- int i;
-
- if (dc) {
- dc = 13 * 13 * (dc == 1 ? 1538 * block[0]
- : qmul * (block[0] >> 3) / 2);
- block[0] = 0;
- }
-
- for (i = 0; i < 4; i++) {
- const int z0 = 13 * (block[0 + 4 * i] + block[2 + 4 * i]);
- const int z1 = 13 * (block[0 + 4 * i] - block[2 + 4 * i]);
- const int z2 = 7 * block[1 + 4 * i] - 17 * block[3 + 4 * i];
- const int z3 = 17 * block[1 + 4 * i] + 7 * block[3 + 4 * i];
-
- block[0 + 4 * i] = z0 + z3;
- block[1 + 4 * i] = z1 + z2;
- block[2 + 4 * i] = z1 - z2;
- block[3 + 4 * i] = z0 - z3;
- }
-
- for (i = 0; i < 4; i++) {
- const int z0 = 13 * (block[i + 4 * 0] + block[i + 4 * 2]);
- const int z1 = 13 * (block[i + 4 * 0] - block[i + 4 * 2]);
- const int z2 = 7 * block[i + 4 * 1] - 17 * block[i + 4 * 3];
- const int z3 = 17 * block[i + 4 * 1] + 7 * block[i + 4 * 3];
- const int rr = (dc + 0x80000);
-
- dst[i + stride * 0] = av_clip_uint8(dst[i + stride * 0] + ((z0 + z3) * qmul + rr >> 20));
- dst[i + stride * 1] = av_clip_uint8(dst[i + stride * 1] + ((z1 + z2) * qmul + rr >> 20));
- dst[i + stride * 2] = av_clip_uint8(dst[i + stride * 2] + ((z1 - z2) * qmul + rr >> 20));
- dst[i + stride * 3] = av_clip_uint8(dst[i + stride * 3] + ((z0 - z3) * qmul + rr >> 20));
- }
-
- memset(block, 0, 16 * sizeof(int16_t));
-}
-
-static inline int svq3_decode_block(GetBitContext *gb, int16_t *block,
- int index, const int type)
-{
- static const uint8_t *const scan_patterns[4] =
- { luma_dc_zigzag_scan, zigzag_scan, svq3_scan, chroma_dc_scan };
-
- int run, level, sign, limit;
- unsigned vlc;
- const int intra = 3 * type >> 2;
- const uint8_t *const scan = scan_patterns[type];
-
- for (limit = (16 >> intra); index < 16; index = limit, limit += 8) {
- for (; (vlc = svq3_get_ue_golomb(gb)) != 0; index++) {
- if ((int32_t)vlc < 0)
- return -1;
-
- sign = (vlc & 1) ? 0 : -1;
- vlc = vlc + 1 >> 1;
-
- if (type == 3) {
- if (vlc < 3) {
- run = 0;
- level = vlc;
- } else if (vlc < 4) {
- run = 1;
- level = 1;
- } else {
- run = vlc & 0x3;
- level = (vlc + 9 >> 2) - run;
- }
- } else {
- if (vlc < 16U) {
- run = svq3_dct_tables[intra][vlc].run;
- level = svq3_dct_tables[intra][vlc].level;
- } else if (intra) {
- run = vlc & 0x7;
- level = (vlc >> 3) + ((run == 0) ? 8 : ((run < 2) ? 2 : ((run < 5) ? 0 : -1)));
- } else {
- run = vlc & 0xF;
- level = (vlc >> 4) + ((run == 0) ? 4 : ((run < 3) ? 2 : ((run < 10) ? 1 : 0)));
- }
- }
-
-
- if ((index += run) >= limit)
- return -1;
-
- block[scan[index]] = (level ^ sign) - sign;
- }
-
- if (type != 2) {
- break;
- }
- }
-
- return 0;
-}
-
-static inline void svq3_mc_dir_part(SVQ3Context *s,
- int x, int y, int width, int height,
- int mx, int my, int dxy,
- int thirdpel, int dir, int avg)
-{
- H264Context *h = &s->h;
- H264SliceContext *sl = &h->slice_ctx[0];
- const H264Picture *pic = (dir == 0) ? s->last_pic : s->next_pic;
- uint8_t *src, *dest;
- int i, emu = 0;
- int blocksize = 2 - (width >> 3); // 16->0, 8->1, 4->2
-
- mx += x;
- my += y;
-
- if (mx < 0 || mx >= s->h_edge_pos - width - 1 ||
- my < 0 || my >= s->v_edge_pos - height - 1) {
- emu = 1;
- mx = av_clip(mx, -16, s->h_edge_pos - width + 15);
- my = av_clip(my, -16, s->v_edge_pos - height + 15);
- }
-
- /* form component predictions */
- dest = h->cur_pic.f->data[0] + x + y * sl->linesize;
- src = pic->f->data[0] + mx + my * sl->linesize;
-
- if (emu) {
- h->vdsp.emulated_edge_mc(sl->edge_emu_buffer, src,
- sl->linesize, sl->linesize,
- width + 1, height + 1,
- mx, my, s->h_edge_pos, s->v_edge_pos);
- src = sl->edge_emu_buffer;
- }
- if (thirdpel)
- (avg ? s->tdsp.avg_tpel_pixels_tab
- : s->tdsp.put_tpel_pixels_tab)[dxy](dest, src, sl->linesize,
- width, height);
- else
- (avg ? s->hdsp.avg_pixels_tab
- : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src, sl->linesize,
- height);
-
- if (!(h->flags & AV_CODEC_FLAG_GRAY)) {
- mx = mx + (mx < (int) x) >> 1;
- my = my + (my < (int) y) >> 1;
- width = width >> 1;
- height = height >> 1;
- blocksize++;
-
- for (i = 1; i < 3; i++) {
- dest = h->cur_pic.f->data[i] + (x >> 1) + (y >> 1) * sl->uvlinesize;
- src = pic->f->data[i] + mx + my * sl->uvlinesize;
-
- if (emu) {
- h->vdsp.emulated_edge_mc(sl->edge_emu_buffer, src,
- sl->uvlinesize, sl->uvlinesize,
- width + 1, height + 1,
- mx, my, (s->h_edge_pos >> 1),
- s->v_edge_pos >> 1);
- src = sl->edge_emu_buffer;
- }
- if (thirdpel)
- (avg ? s->tdsp.avg_tpel_pixels_tab
- : s->tdsp.put_tpel_pixels_tab)[dxy](dest, src,
- sl->uvlinesize,
- width, height);
- else
- (avg ? s->hdsp.avg_pixels_tab
- : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src,
- sl->uvlinesize,
- height);
- }
- }
-}
-
-static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode,
- int dir, int avg)
-{
- int i, j, k, mx, my, dx, dy, x, y;
- H264Context *h = &s->h;
- H264SliceContext *sl = &h->slice_ctx[0];
- const int part_width = ((size & 5) == 4) ? 4 : 16 >> (size & 1);
- const int part_height = 16 >> ((unsigned)(size + 1) / 3);
- const int extra_width = (mode == PREDICT_MODE) ? -16 * 6 : 0;
- const int h_edge_pos = 6 * (s->h_edge_pos - part_width) - extra_width;
- const int v_edge_pos = 6 * (s->v_edge_pos - part_height) - extra_width;
-
- for (i = 0; i < 16; i += part_height)
- for (j = 0; j < 16; j += part_width) {
- const int b_xy = (4 * sl->mb_x + (j >> 2)) +
- (4 * sl->mb_y + (i >> 2)) * h->b_stride;
- int dxy;
- x = 16 * sl->mb_x + j;
- y = 16 * sl->mb_y + i;
- k = (j >> 2 & 1) + (i >> 1 & 2) +
- (j >> 1 & 4) + (i & 8);
-
- if (mode != PREDICT_MODE) {
- pred_motion(h, sl, k, part_width >> 2, dir, 1, &mx, &my);
- } else {
- mx = s->next_pic->motion_val[0][b_xy][0] << 1;
- my = s->next_pic->motion_val[0][b_xy][1] << 1;
-
- if (dir == 0) {
- mx = mx * h->frame_num_offset /
- h->prev_frame_num_offset + 1 >> 1;
- my = my * h->frame_num_offset /
- h->prev_frame_num_offset + 1 >> 1;
- } else {
- mx = mx * (h->frame_num_offset - h->prev_frame_num_offset) /
- h->prev_frame_num_offset + 1 >> 1;
- my = my * (h->frame_num_offset - h->prev_frame_num_offset) /
- h->prev_frame_num_offset + 1 >> 1;
- }
- }
-
- /* clip motion vector prediction to frame border */
- mx = av_clip(mx, extra_width - 6 * x, h_edge_pos - 6 * x);
- my = av_clip(my, extra_width - 6 * y, v_edge_pos - 6 * y);
-
- /* get (optional) motion vector differential */
- if (mode == PREDICT_MODE) {
- dx = dy = 0;
- } else {
- dy = svq3_get_se_golomb(&h->gb);
- dx = svq3_get_se_golomb(&h->gb);
-
- if (dx == INVALID_VLC || dy == INVALID_VLC) {
- av_log(h->avctx, AV_LOG_ERROR, "invalid MV vlc\n");
- return -1;
- }
- }
-
- /* compute motion vector */
- if (mode == THIRDPEL_MODE) {
- int fx, fy;
- mx = (mx + 1 >> 1) + dx;
- my = (my + 1 >> 1) + dy;
- fx = (unsigned)(mx + 0x3000) / 3 - 0x1000;
- fy = (unsigned)(my + 0x3000) / 3 - 0x1000;
- dxy = (mx - 3 * fx) + 4 * (my - 3 * fy);
-
- svq3_mc_dir_part(s, x, y, part_width, part_height,
- fx, fy, dxy, 1, dir, avg);
- mx += mx;
- my += my;
- } else if (mode == HALFPEL_MODE || mode == PREDICT_MODE) {
- mx = (unsigned)(mx + 1 + 0x3000) / 3 + dx - 0x1000;
- my = (unsigned)(my + 1 + 0x3000) / 3 + dy - 0x1000;
- dxy = (mx & 1) + 2 * (my & 1);
-
- svq3_mc_dir_part(s, x, y, part_width, part_height,
- mx >> 1, my >> 1, dxy, 0, dir, avg);
- mx *= 3;
- my *= 3;
- } else {
- mx = (unsigned)(mx + 3 + 0x6000) / 6 + dx - 0x1000;
- my = (unsigned)(my + 3 + 0x6000) / 6 + dy - 0x1000;
-
- svq3_mc_dir_part(s, x, y, part_width, part_height,
- mx, my, 0, 0, dir, avg);
- mx *= 6;
- my *= 6;
- }
-
- /* update mv_cache */
- if (mode != PREDICT_MODE) {
- int32_t mv = pack16to32(mx, my);
-
- if (part_height == 8 && i < 8) {
- AV_WN32A(sl->mv_cache[dir][scan8[k] + 1 * 8], mv);
-
- if (part_width == 8 && j < 8)
- AV_WN32A(sl->mv_cache[dir][scan8[k] + 1 + 1 * 8], mv);
- }
- if (part_width == 8 && j < 8)
- AV_WN32A(sl->mv_cache[dir][scan8[k] + 1], mv);
- if (part_width == 4 || part_height == 4)
- AV_WN32A(sl->mv_cache[dir][scan8[k]], mv);
- }
-
- /* write back motion vectors */
- fill_rectangle(h->cur_pic.motion_val[dir][b_xy],
- part_width >> 2, part_height >> 2, h->b_stride,
- pack16to32(mx, my), 4);
- }
-
- return 0;
-}
-
-static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
-{
- H264Context *h = &s->h;
- H264SliceContext *sl = &h->slice_ctx[0];
- int i, j, k, m, dir, mode;
- int cbp = 0;
- uint32_t vlc;
- int8_t *top, *left;
- const int mb_xy = sl->mb_xy;
- const int b_xy = 4 * sl->mb_x + 4 * sl->mb_y * h->b_stride;
-
- sl->top_samples_available = (sl->mb_y == 0) ? 0x33FF : 0xFFFF;
- sl->left_samples_available = (sl->mb_x == 0) ? 0x5F5F : 0xFFFF;
- sl->topright_samples_available = 0xFFFF;
-
- if (mb_type == 0) { /* SKIP */
- if (h->pict_type == AV_PICTURE_TYPE_P ||
- s->next_pic->mb_type[mb_xy] == -1) {
- svq3_mc_dir_part(s, 16 * sl->mb_x, 16 * sl->mb_y, 16, 16,
- 0, 0, 0, 0, 0, 0);
-
- if (h->pict_type == AV_PICTURE_TYPE_B)
- svq3_mc_dir_part(s, 16 * sl->mb_x, 16 * sl->mb_y, 16, 16,
- 0, 0, 0, 0, 1, 1);
-
- mb_type = MB_TYPE_SKIP;
- } else {
- mb_type = FFMIN(s->next_pic->mb_type[mb_xy], 6);
- if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 0, 0) < 0)
- return -1;
- if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 1, 1) < 0)
- return -1;
-
- mb_type = MB_TYPE_16x16;
- }
- } else if (mb_type < 8) { /* INTER */
- if (s->thirdpel_flag && s->halfpel_flag == !get_bits1(&h->gb))
- mode = THIRDPEL_MODE;
- else if (s->halfpel_flag &&
- s->thirdpel_flag == !get_bits1(&h->gb))
- mode = HALFPEL_MODE;
- else
- mode = FULLPEL_MODE;
-
- /* fill caches */
- /* note ref_cache should contain here:
- * ????????
- * ???11111
- * N??11111
- * N??11111
- * N??11111
- */
-
- for (m = 0; m < 2; m++) {
- if (sl->mb_x > 0 && sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6] != -1) {
- for (i = 0; i < 4; i++)
- AV_COPY32(sl->mv_cache[m][scan8[0] - 1 + i * 8],
- h->cur_pic.motion_val[m][b_xy - 1 + i * h->b_stride]);
- } else {
- for (i = 0; i < 4; i++)
- AV_ZERO32(sl->mv_cache[m][scan8[0] - 1 + i * 8]);
- }
- if (sl->mb_y > 0) {
- memcpy(sl->mv_cache[m][scan8[0] - 1 * 8],
- h->cur_pic.motion_val[m][b_xy - h->b_stride],
- 4 * 2 * sizeof(int16_t));
- memset(&sl->ref_cache[m][scan8[0] - 1 * 8],
- (sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4);
-
- if (sl->mb_x < h->mb_width - 1) {
- AV_COPY32(sl->mv_cache[m][scan8[0] + 4 - 1 * 8],
- h->cur_pic.motion_val[m][b_xy - h->b_stride + 4]);
- sl->ref_cache[m][scan8[0] + 4 - 1 * 8] =
- (sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride + 1] + 6] == -1 ||
- sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1;
- } else
- sl->ref_cache[m][scan8[0] + 4 - 1 * 8] = PART_NOT_AVAILABLE;
- if (sl->mb_x > 0) {
- AV_COPY32(sl->mv_cache[m][scan8[0] - 1 - 1 * 8],
- h->cur_pic.motion_val[m][b_xy - h->b_stride - 1]);
- sl->ref_cache[m][scan8[0] - 1 - 1 * 8] =
- (sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] == -1) ? PART_NOT_AVAILABLE : 1;
- } else
- sl->ref_cache[m][scan8[0] - 1 - 1 * 8] = PART_NOT_AVAILABLE;
- } else
- memset(&sl->ref_cache[m][scan8[0] - 1 * 8 - 1],
- PART_NOT_AVAILABLE, 8);
-
- if (h->pict_type != AV_PICTURE_TYPE_B)
- break;
- }
-
- /* decode motion vector(s) and form prediction(s) */
- if (h->pict_type == AV_PICTURE_TYPE_P) {
- if (svq3_mc_dir(s, mb_type - 1, mode, 0, 0) < 0)
- return -1;
- } else { /* AV_PICTURE_TYPE_B */
- if (mb_type != 2) {
- if (svq3_mc_dir(s, 0, mode, 0, 0) < 0)
- return -1;
- } else {
- for (i = 0; i < 4; i++)
- memset(h->cur_pic.motion_val[0][b_xy + i * h->b_stride],
- 0, 4 * 2 * sizeof(int16_t));
- }
- if (mb_type != 1) {
- if (svq3_mc_dir(s, 0, mode, 1, mb_type == 3) < 0)
- return -1;
- } else {
- for (i = 0; i < 4; i++)
- memset(h->cur_pic.motion_val[1][b_xy + i * h->b_stride],
- 0, 4 * 2 * sizeof(int16_t));
- }
- }
-
- mb_type = MB_TYPE_16x16;
- } else if (mb_type == 8 || mb_type == 33) { /* INTRA4x4 */
- memset(sl->intra4x4_pred_mode_cache, -1, 8 * 5 * sizeof(int8_t));
-
- if (mb_type == 8) {
- if (sl->mb_x > 0) {
- for (i = 0; i < 4; i++)
- sl->intra4x4_pred_mode_cache[scan8[0] - 1 + i * 8] = sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6 - i];
- if (sl->intra4x4_pred_mode_cache[scan8[0] - 1] == -1)
- sl->left_samples_available = 0x5F5F;
- }
- if (sl->mb_y > 0) {
- sl->intra4x4_pred_mode_cache[4 + 8 * 0] = sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 0];
- sl->intra4x4_pred_mode_cache[5 + 8 * 0] = sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 1];
- sl->intra4x4_pred_mode_cache[6 + 8 * 0] = sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 2];
- sl->intra4x4_pred_mode_cache[7 + 8 * 0] = sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 3];
-
- if (sl->intra4x4_pred_mode_cache[4 + 8 * 0] == -1)
- sl->top_samples_available = 0x33FF;
- }
-
- /* decode prediction codes for luma blocks */
- for (i = 0; i < 16; i += 2) {
- vlc = svq3_get_ue_golomb(&h->gb);
-
- if (vlc >= 25U) {
- av_log(h->avctx, AV_LOG_ERROR,
- "luma prediction:%"PRIu32"\n", vlc);
- return -1;
- }
-
- left = &sl->intra4x4_pred_mode_cache[scan8[i] - 1];
- top = &sl->intra4x4_pred_mode_cache[scan8[i] - 8];
-
- left[1] = svq3_pred_1[top[0] + 1][left[0] + 1][svq3_pred_0[vlc][0]];
- left[2] = svq3_pred_1[top[1] + 1][left[1] + 1][svq3_pred_0[vlc][1]];
-
- if (left[1] == -1 || left[2] == -1) {
- av_log(h->avctx, AV_LOG_ERROR, "weird prediction\n");
- return -1;
- }
- }
- } else { /* mb_type == 33, DC_128_PRED block type */
- for (i = 0; i < 4; i++)
- memset(&sl->intra4x4_pred_mode_cache[scan8[0] + 8 * i], DC_PRED, 4);
- }
-
- write_back_intra_pred_mode(h, sl);
-
- if (mb_type == 8) {
- ff_h264_check_intra4x4_pred_mode(h, sl);
-
- sl->top_samples_available = (sl->mb_y == 0) ? 0x33FF : 0xFFFF;
- sl->left_samples_available = (sl->mb_x == 0) ? 0x5F5F : 0xFFFF;
- } else {
- for (i = 0; i < 4; i++)
- memset(&sl->intra4x4_pred_mode_cache[scan8[0] + 8 * i], DC_128_PRED, 4);
-
- sl->top_samples_available = 0x33FF;
- sl->left_samples_available = 0x5F5F;
- }
-
- mb_type = MB_TYPE_INTRA4x4;
- } else { /* INTRA16x16 */
- dir = i_mb_type_info[mb_type - 8].pred_mode;
- dir = (dir >> 1) ^ 3 * (dir & 1) ^ 1;
-
- if ((sl->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, sl, dir, 0)) < 0) {
- av_log(h->avctx, AV_LOG_ERROR, "ff_h264_check_intra_pred_mode < 0\n");
- return sl->intra16x16_pred_mode;
- }
-
- cbp = i_mb_type_info[mb_type - 8].cbp;
- mb_type = MB_TYPE_INTRA16x16;
- }
-
- if (!IS_INTER(mb_type) && h->pict_type != AV_PICTURE_TYPE_I) {
- for (i = 0; i < 4; i++)
- memset(h->cur_pic.motion_val[0][b_xy + i * h->b_stride],
- 0, 4 * 2 * sizeof(int16_t));
- if (h->pict_type == AV_PICTURE_TYPE_B) {
- for (i = 0; i < 4; i++)
- memset(h->cur_pic.motion_val[1][b_xy + i * h->b_stride],
- 0, 4 * 2 * sizeof(int16_t));
- }
- }
- if (!IS_INTRA4x4(mb_type)) {
- memset(sl->intra4x4_pred_mode + h->mb2br_xy[mb_xy], DC_PRED, 8);
- }
- if (!IS_SKIP(mb_type) || h->pict_type == AV_PICTURE_TYPE_B) {
- memset(sl->non_zero_count_cache + 8, 0, 14 * 8 * sizeof(uint8_t));
- }
-
- if (!IS_INTRA16x16(mb_type) &&
- (!IS_SKIP(mb_type) || h->pict_type == AV_PICTURE_TYPE_B)) {
- if ((vlc = svq3_get_ue_golomb(&h->gb)) >= 48U){
- av_log(h->avctx, AV_LOG_ERROR, "cbp_vlc=%"PRIu32"\n", vlc);
- return -1;
- }
-
- cbp = IS_INTRA(mb_type) ? golomb_to_intra4x4_cbp[vlc]
- : golomb_to_inter_cbp[vlc];
- }
- if (IS_INTRA16x16(mb_type) ||
- (h->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) {
- sl->qscale += svq3_get_se_golomb(&h->gb);
-
- if (sl->qscale > 31u) {
- av_log(h->avctx, AV_LOG_ERROR, "qscale:%d\n", sl->qscale);
- return -1;
- }
- }
- if (IS_INTRA16x16(mb_type)) {
- AV_ZERO128(sl->mb_luma_dc[0] + 0);
- AV_ZERO128(sl->mb_luma_dc[0] + 8);
- if (svq3_decode_block(&h->gb, sl->mb_luma_dc[0], 0, 1)) {
- av_log(h->avctx, AV_LOG_ERROR,
- "error while decoding intra luma dc\n");
- return -1;
- }
- }
-
- if (cbp) {
- const int index = IS_INTRA16x16(mb_type) ? 1 : 0;
- const int type = ((sl->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1);
-
- for (i = 0; i < 4; i++)
- if ((cbp & (1 << i))) {
- for (j = 0; j < 4; j++) {
- k = index ? (1 * (j & 1) + 2 * (i & 1) +
- 2 * (j & 2) + 4 * (i & 2))
- : (4 * i + j);
- sl->non_zero_count_cache[scan8[k]] = 1;
-
- if (svq3_decode_block(&h->gb, &sl->mb[16 * k], index, type)) {
- av_log(h->avctx, AV_LOG_ERROR,
- "error while decoding block\n");
- return -1;
- }
- }
- }
-
- if ((cbp & 0x30)) {
- for (i = 1; i < 3; ++i)
- if (svq3_decode_block(&h->gb, &sl->mb[16 * 16 * i], 0, 3)) {
- av_log(h->avctx, AV_LOG_ERROR,
- "error while decoding chroma dc block\n");
- return -1;
- }
-
- if ((cbp & 0x20)) {
- for (i = 1; i < 3; i++) {
- for (j = 0; j < 4; j++) {
- k = 16 * i + j;
- sl->non_zero_count_cache[scan8[k]] = 1;
-
- if (svq3_decode_block(&h->gb, &sl->mb[16 * k], 1, 1)) {
- av_log(h->avctx, AV_LOG_ERROR,
- "error while decoding chroma ac block\n");
- return -1;
- }
- }
- }
- }
- }
- }
-
- sl->cbp = cbp;
- h->cur_pic.mb_type[mb_xy] = mb_type;
-
- if (IS_INTRA(mb_type))
- sl->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, sl, DC_PRED8x8, 1);
-
- return 0;
-}
-
-static int svq3_decode_slice_header(AVCodecContext *avctx)
-{
- SVQ3Context *s = avctx->priv_data;
- H264Context *h = &s->h;
- H264SliceContext *sl = &h->slice_ctx[0];
- const int mb_xy = sl->mb_xy;
- int i, header;
- unsigned slice_id;
-
- header = get_bits(&h->gb, 8);
-
- if (((header & 0x9F) != 1 && (header & 0x9F) != 2) || (header & 0x60) == 0) {
- /* TODO: what? */
- av_log(avctx, AV_LOG_ERROR, "unsupported slice header (%02X)\n", header);
- return -1;
- } else {
- int length = header >> 5 & 3;
-
- s->next_slice_index = get_bits_count(&h->gb) +
- 8 * show_bits(&h->gb, 8 * length) +
- 8 * length;
-
- if (s->next_slice_index > h->gb.size_in_bits) {
- av_log(avctx, AV_LOG_ERROR, "slice after bitstream end\n");
- return -1;
- }
-
- h->gb.size_in_bits = s->next_slice_index - 8 * (length - 1);
- skip_bits(&h->gb, 8);
-
- if (s->watermark_key) {
- uint32_t header = AV_RL32(&h->gb.buffer[(get_bits_count(&h->gb) >> 3) + 1]);
- AV_WL32(&h->gb.buffer[(get_bits_count(&h->gb) >> 3) + 1],
- header ^ s->watermark_key);
- }
- if (length > 0) {
- memmove((uint8_t *) &h->gb.buffer[get_bits_count(&h->gb) >> 3],
- &h->gb.buffer[h->gb.size_in_bits >> 3], length - 1);
- }
- skip_bits_long(&h->gb, 0);
- }
-
- if ((slice_id = svq3_get_ue_golomb(&h->gb)) >= 3) {
- av_log(h->avctx, AV_LOG_ERROR, "illegal slice type %u \n", slice_id);
- return -1;
- }
-
- sl->slice_type = golomb_to_pict_type[slice_id];
-
- if ((header & 0x9F) == 2) {
- i = (h->mb_num < 64) ? 6 : (1 + av_log2(h->mb_num - 1));
- sl->mb_skip_run = get_bits(&h->gb, i) -
- (sl->mb_y * h->mb_width + sl->mb_x);
- } else {
- skip_bits1(&h->gb);
- sl->mb_skip_run = 0;
- }
-
- sl->slice_num = get_bits(&h->gb, 8);
- sl->qscale = get_bits(&h->gb, 5);
- s->adaptive_quant = get_bits1(&h->gb);
-
- /* unknown fields */
- skip_bits1(&h->gb);
-
- if (s->has_watermark)
- skip_bits1(&h->gb);
-
- skip_bits1(&h->gb);
- skip_bits(&h->gb, 2);
-
- if (skip_1stop_8data_bits(&h->gb) < 0)
- return AVERROR_INVALIDDATA;
-
- /* reset intra predictors and invalidate motion vector references */
- if (sl->mb_x > 0) {
- memset(sl->intra4x4_pred_mode + h->mb2br_xy[mb_xy - 1] + 3,
- -1, 4 * sizeof(int8_t));
- memset(sl->intra4x4_pred_mode + h->mb2br_xy[mb_xy - sl->mb_x],
- -1, 8 * sizeof(int8_t) * sl->mb_x);
- }
- if (sl->mb_y > 0) {
- memset(sl->intra4x4_pred_mode + h->mb2br_xy[mb_xy - h->mb_stride],
- -1, 8 * sizeof(int8_t) * (h->mb_width - sl->mb_x));
-
- if (sl->mb_x > 0)
- sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] = -1;
- }
-
- return 0;
-}
-
-static av_cold int svq3_decode_init(AVCodecContext *avctx)
-{
- SVQ3Context *s = avctx->priv_data;
- H264Context *h = &s->h;
- H264SliceContext *sl;
- int m;
- unsigned char *extradata;
- unsigned char *extradata_end;
- unsigned int size;
- int marker_found = 0;
- int ret;
-
- s->cur_pic = av_mallocz(sizeof(*s->cur_pic));
- s->last_pic = av_mallocz(sizeof(*s->last_pic));
- s->next_pic = av_mallocz(sizeof(*s->next_pic));
- if (!s->next_pic || !s->last_pic || !s->cur_pic) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
-
- s->cur_pic->f = av_frame_alloc();
- s->last_pic->f = av_frame_alloc();
- s->next_pic->f = av_frame_alloc();
- if (!s->cur_pic->f || !s->last_pic->f || !s->next_pic->f)
- return AVERROR(ENOMEM);
-
- if ((ret = ff_h264_decode_init(avctx)) < 0)
- goto fail;
-
- // we will overwrite it later during decoding
- av_frame_free(&h->cur_pic.f);
-
- av_frame_free(&h->last_pic_for_ec.f);
-
- ff_h264dsp_init(&h->h264dsp, 8, 1);
- av_assert0(h->sps.bit_depth_chroma == 0);
- ff_h264_pred_init(&h->hpc, AV_CODEC_ID_SVQ3, 8, 1);
- ff_videodsp_init(&h->vdsp, 8);
-
- memset(h->pps.scaling_matrix4, 16, 6 * 16 * sizeof(uint8_t));
- memset(h->pps.scaling_matrix8, 16, 2 * 64 * sizeof(uint8_t));
-
- avctx->bits_per_raw_sample = 8;
- h->sps.bit_depth_luma = 8;
- h->chroma_format_idc = 1;
-
- ff_hpeldsp_init(&s->hdsp, avctx->flags);
- ff_tpeldsp_init(&s->tdsp);
-
- sl = h->slice_ctx;
-
- h->flags = avctx->flags;
- sl->is_complex = 1;
- h->sps.chroma_format_idc = 1;
- h->picture_structure = PICT_FRAME;
- avctx->pix_fmt = AV_PIX_FMT_YUVJ420P;
- avctx->color_range = AVCOL_RANGE_JPEG;
-
- h->slice_ctx[0].chroma_qp[0] = h->slice_ctx[0].chroma_qp[1] = 4;
- h->chroma_x_shift = h->chroma_y_shift = 1;
-
- s->halfpel_flag = 1;
- s->thirdpel_flag = 1;
- s->has_watermark = 0;
-
- /* prowl for the "SEQH" marker in the extradata */
- extradata = (unsigned char *)avctx->extradata;
- extradata_end = avctx->extradata + avctx->extradata_size;
- if (extradata) {
- for (m = 0; m + 8 < avctx->extradata_size; m++) {
- if (!memcmp(extradata, "SEQH", 4)) {
- marker_found = 1;
- break;
- }
- extradata++;
- }
- }
-
- /* if a match was found, parse the extra data */
- if (marker_found) {
- GetBitContext gb;
- int frame_size_code;
- int unk0, unk1, unk2, unk3, unk4;
-
- size = AV_RB32(&extradata[4]);
- if (size > extradata_end - extradata - 8) {
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
- init_get_bits(&gb, extradata + 8, size * 8);
-
- /* 'frame size code' and optional 'width, height' */
- frame_size_code = get_bits(&gb, 3);
- switch (frame_size_code) {
- case 0:
- avctx->width = 160;
- avctx->height = 120;
- break;
- case 1:
- avctx->width = 128;
- avctx->height = 96;
- break;
- case 2:
- avctx->width = 176;
- avctx->height = 144;
- break;
- case 3:
- avctx->width = 352;
- avctx->height = 288;
- break;
- case 4:
- avctx->width = 704;
- avctx->height = 576;
- break;
- case 5:
- avctx->width = 240;
- avctx->height = 180;
- break;
- case 6:
- avctx->width = 320;
- avctx->height = 240;
- break;
- case 7:
- avctx->width = get_bits(&gb, 12);
- avctx->height = get_bits(&gb, 12);
- break;
- }
-
- s->halfpel_flag = get_bits1(&gb);
- s->thirdpel_flag = get_bits1(&gb);
-
- /* unknown fields */
- unk0 = get_bits1(&gb);
- unk1 = get_bits1(&gb);
- unk2 = get_bits1(&gb);
- unk3 = get_bits1(&gb);
-
- h->low_delay = get_bits1(&gb);
-
- /* unknown field */
- unk4 = get_bits1(&gb);
-
- 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;
- }
-
- s->has_watermark = get_bits1(&gb);
- avctx->has_b_frames = !h->low_delay;
- if (s->has_watermark) {
-#if CONFIG_ZLIB
- unsigned watermark_width = svq3_get_ue_golomb(&gb);
- unsigned watermark_height = svq3_get_ue_golomb(&gb);
- int u1 = svq3_get_ue_golomb(&gb);
- int u2 = get_bits(&gb, 8);
- int u3 = get_bits(&gb, 2);
- int u4 = svq3_get_ue_golomb(&gb);
- unsigned long buf_len = watermark_width *
- watermark_height * 4;
- int offset = get_bits_count(&gb) + 7 >> 3;
- uint8_t *buf;
-
- if (watermark_height <= 0 ||
- (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height) {
- ret = -1;
- goto fail;
- }
-
- buf = av_malloc(buf_len);
- if (!buf) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- av_log(avctx, AV_LOG_DEBUG, "watermark size: %ux%u\n",
- watermark_width, watermark_height);
- av_log(avctx, AV_LOG_DEBUG,
- "u1: %x u2: %x u3: %x compressed data size: %d offset: %d\n",
- u1, u2, u3, u4, offset);
- if (uncompress(buf, &buf_len, extradata + 8 + offset,
- size - offset) != Z_OK) {
- av_log(avctx, AV_LOG_ERROR,
- "could not uncompress watermark logo\n");
- av_free(buf);
- ret = -1;
- goto fail;
- }
- s->watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0);
- s->watermark_key = s->watermark_key << 16 | s->watermark_key;
- av_log(avctx, AV_LOG_DEBUG,
- "watermark key %#"PRIx32"\n", s->watermark_key);
- av_free(buf);
-#else
- av_log(avctx, AV_LOG_ERROR,
- "this svq3 file contains watermark which need zlib support compiled in\n");
- ret = -1;
- goto fail;
-#endif
- }
- }
-
- h->width = avctx->width;
- h->height = avctx->height;
- h->mb_width = (h->width + 15) / 16;
- h->mb_height = (h->height + 15) / 16;
- h->mb_stride = h->mb_width + 1;
- h->mb_num = h->mb_width * h->mb_height;
- h->b_stride = 4 * h->mb_width;
- s->h_edge_pos = h->mb_width * 16;
- s->v_edge_pos = h->mb_height * 16;
-
- if ((ret = ff_h264_alloc_tables(h)) < 0) {
- av_log(avctx, AV_LOG_ERROR, "svq3 memory allocation failed\n");
- goto fail;
- }
-
- return 0;
-fail:
- svq3_decode_end(avctx);
- return ret;
-}
-
-static void free_picture(AVCodecContext *avctx, H264Picture *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_buffer_unref(&pic->mb_type_buf);
-
- av_frame_unref(pic->f);
-}
-
-static int get_buffer(AVCodecContext *avctx, H264Picture *pic)
-{
- SVQ3Context *s = avctx->priv_data;
- H264Context *h = &s->h;
- H264SliceContext *sl = &h->slice_ctx[0];
- const int big_mb_num = h->mb_stride * (h->mb_height + 1) + 1;
- const int mb_array_size = h->mb_stride * h->mb_height;
- const int b4_stride = h->mb_width * 4 + 1;
- const int b4_array_size = b4_stride * h->mb_height * 4;
- int ret;
-
- if (!pic->motion_val_buf[0]) {
- int i;
-
- pic->mb_type_buf = av_buffer_allocz((big_mb_num + h->mb_stride) * sizeof(uint32_t));
- if (!pic->mb_type_buf)
- return AVERROR(ENOMEM);
- pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * h->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]) {
- 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->reference = !(h->pict_type == AV_PICTURE_TYPE_B);
-
- ret = ff_get_buffer(avctx, pic->f,
- pic->reference ? AV_GET_BUFFER_FLAG_REF : 0);
- if (ret < 0)
- goto fail;
-
- if (!sl->edge_emu_buffer) {
- sl->edge_emu_buffer = av_mallocz_array(pic->f->linesize[0], 17);
- if (!sl->edge_emu_buffer)
- return AVERROR(ENOMEM);
- }
-
- sl->linesize = pic->f->linesize[0];
- sl->uvlinesize = pic->f->linesize[1];
-
- return 0;
-fail:
- free_picture(avctx, pic);
- return ret;
-}
-
-static int svq3_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame, AVPacket *avpkt)
-{
- SVQ3Context *s = avctx->priv_data;
- H264Context *h = &s->h;
- H264SliceContext *sl = &h->slice_ctx[0];
- int buf_size = avpkt->size;
- int left;
- uint8_t *buf;
- int ret, m, i;
-
- /* special case for last picture */
- if (buf_size == 0) {
- if (s->next_pic->f->data[0] && !h->low_delay && !s->last_frame_output) {
- ret = av_frame_ref(data, s->next_pic->f);
- if (ret < 0)
- return ret;
- s->last_frame_output = 1;
- *got_frame = 1;
- }
- return 0;
- }
-
- sl->mb_x = sl->mb_y = sl->mb_xy = 0;
-
- if (s->watermark_key) {
- av_fast_padded_malloc(&s->buf, &s->buf_size, buf_size);
- if (!s->buf)
- return AVERROR(ENOMEM);
- memcpy(s->buf, avpkt->data, buf_size);
- buf = s->buf;
- } else {
- buf = avpkt->data;
- }
-
- init_get_bits(&h->gb, buf, 8 * buf_size);
-
- if (svq3_decode_slice_header(avctx))
- return -1;
-
- h->pict_type = sl->slice_type;
-
- if (h->pict_type != AV_PICTURE_TYPE_B)
- FFSWAP(H264Picture*, s->next_pic, s->last_pic);
-
- av_frame_unref(s->cur_pic->f);
-
- /* for skipping the frame */
- s->cur_pic->f->pict_type = h->pict_type;
- s->cur_pic->f->key_frame = (h->pict_type == AV_PICTURE_TYPE_I);
-
- ret = get_buffer(avctx, s->cur_pic);
- if (ret < 0)
- return ret;
-
- h->cur_pic_ptr = s->cur_pic;
- h->cur_pic = *s->cur_pic;
-
- for (i = 0; i < 16; i++) {
- h->block_offset[i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * sl->linesize * ((scan8[i] - scan8[0]) >> 3);
- h->block_offset[48 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * sl->linesize * ((scan8[i] - scan8[0]) >> 3);
- }
- for (i = 0; i < 16; i++) {
- h->block_offset[16 + i] =
- h->block_offset[32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * sl->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
- h->block_offset[48 + 16 + i] =
- h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * sl->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
- }
-
- if (h->pict_type != AV_PICTURE_TYPE_I) {
- if (!s->last_pic->f->data[0]) {
- av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
- av_frame_unref(s->last_pic->f);
- ret = get_buffer(avctx, s->last_pic);
- if (ret < 0)
- return ret;
- memset(s->last_pic->f->data[0], 0, avctx->height * s->last_pic->f->linesize[0]);
- memset(s->last_pic->f->data[1], 0x80, (avctx->height / 2) *
- s->last_pic->f->linesize[1]);
- memset(s->last_pic->f->data[2], 0x80, (avctx->height / 2) *
- s->last_pic->f->linesize[2]);
- }
-
- if (h->pict_type == AV_PICTURE_TYPE_B && !s->next_pic->f->data[0]) {
- av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
- av_frame_unref(s->next_pic->f);
- ret = get_buffer(avctx, s->next_pic);
- if (ret < 0)
- return ret;
- memset(s->next_pic->f->data[0], 0, avctx->height * s->next_pic->f->linesize[0]);
- memset(s->next_pic->f->data[1], 0x80, (avctx->height / 2) *
- s->next_pic->f->linesize[1]);
- memset(s->next_pic->f->data[2], 0x80, (avctx->height / 2) *
- s->next_pic->f->linesize[2]);
- }
- }
-
- if (avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(h->avctx, AV_LOG_DEBUG,
- "%c hpel:%d, tpel:%d aqp:%d qp:%d, slice_num:%02X\n",
- av_get_picture_type_char(h->pict_type),
- s->halfpel_flag, s->thirdpel_flag,
- s->adaptive_quant, h->slice_ctx[0].qscale, sl->slice_num);
-
- if (avctx->skip_frame >= AVDISCARD_NONREF && h->pict_type == AV_PICTURE_TYPE_B ||
- avctx->skip_frame >= AVDISCARD_NONKEY && h->pict_type != AV_PICTURE_TYPE_I ||
- avctx->skip_frame >= AVDISCARD_ALL)
- return 0;
-
- if (s->next_p_frame_damaged) {
- if (h->pict_type == AV_PICTURE_TYPE_B)
- return 0;
- else
- s->next_p_frame_damaged = 0;
- }
-
- if (h->pict_type == AV_PICTURE_TYPE_B) {
- h->frame_num_offset = sl->slice_num - h->prev_frame_num;
-
- if (h->frame_num_offset < 0)
- h->frame_num_offset += 256;
- if (h->frame_num_offset == 0 ||
- h->frame_num_offset >= h->prev_frame_num_offset) {
- av_log(h->avctx, AV_LOG_ERROR, "error in B-frame picture id\n");
- return -1;
- }
- } else {
- h->prev_frame_num = h->frame_num;
- h->frame_num = sl->slice_num;
- h->prev_frame_num_offset = h->frame_num - h->prev_frame_num;
-
- if (h->prev_frame_num_offset < 0)
- h->prev_frame_num_offset += 256;
- }
-
- for (m = 0; m < 2; m++) {
- int i;
- for (i = 0; i < 4; i++) {
- int j;
- for (j = -1; j < 4; j++)
- sl->ref_cache[m][scan8[0] + 8 * i + j] = 1;
- if (i < 3)
- sl->ref_cache[m][scan8[0] + 8 * i + j] = PART_NOT_AVAILABLE;
- }
- }
-
- for (sl->mb_y = 0; sl->mb_y < h->mb_height; sl->mb_y++) {
- for (sl->mb_x = 0; sl->mb_x < h->mb_width; sl->mb_x++) {
- unsigned mb_type;
- sl->mb_xy = sl->mb_x + sl->mb_y * h->mb_stride;
-
- if ((get_bits_count(&h->gb) + 7) >= h->gb.size_in_bits &&
- ((get_bits_count(&h->gb) & 7) == 0 ||
- show_bits(&h->gb, -get_bits_count(&h->gb) & 7) == 0)) {
- skip_bits(&h->gb, s->next_slice_index - get_bits_count(&h->gb));
- h->gb.size_in_bits = 8 * buf_size;
-
- if (svq3_decode_slice_header(avctx))
- return -1;
-
- /* TODO: support s->mb_skip_run */
- }
-
- mb_type = svq3_get_ue_golomb(&h->gb);
-
- if (h->pict_type == AV_PICTURE_TYPE_I)
- mb_type += 8;
- else if (h->pict_type == AV_PICTURE_TYPE_B && mb_type >= 4)
- mb_type += 4;
- if (mb_type > 33 || svq3_decode_mb(s, mb_type)) {
- av_log(h->avctx, AV_LOG_ERROR,
- "error while decoding MB %d %d\n", sl->mb_x, sl->mb_y);
- return -1;
- }
-
- if (mb_type != 0 || sl->cbp)
- ff_h264_hl_decode_mb(h, &h->slice_ctx[0]);
-
- if (h->pict_type != AV_PICTURE_TYPE_B && !h->low_delay)
- h->cur_pic.mb_type[sl->mb_x + sl->mb_y * h->mb_stride] =
- (h->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1;
- }
-
- ff_draw_horiz_band(avctx, s->cur_pic->f,
- s->last_pic->f->data[0] ? s->last_pic->f : NULL,
- 16 * sl->mb_y, 16, h->picture_structure, 0,
- h->low_delay);
- }
-
- left = buf_size*8 - get_bits_count(&h->gb);
-
- if (sl->mb_y != h->mb_height || sl->mb_x != h->mb_width) {
- av_log(avctx, AV_LOG_INFO, "frame num %d incomplete pic x %d y %d left %d\n", avctx->frame_number, sl->mb_y, sl->mb_x, left);
- //av_hex_dump(stderr, buf+buf_size-8, 8);
- }
-
- if (left < 0) {
- av_log(avctx, AV_LOG_ERROR, "frame num %d left %d\n", avctx->frame_number, left);
- return -1;
- }
-
- if (h->pict_type == AV_PICTURE_TYPE_B || h->low_delay)
- ret = av_frame_ref(data, s->cur_pic->f);
- else if (s->last_pic->f->data[0])
- ret = av_frame_ref(data, s->last_pic->f);
- if (ret < 0)
- return ret;
-
- /* Do not output the last pic after seeking. */
- if (s->last_pic->f->data[0] || h->low_delay)
- *got_frame = 1;
-
- if (h->pict_type != AV_PICTURE_TYPE_B) {
- FFSWAP(H264Picture*, s->cur_pic, s->next_pic);
- } else {
- av_frame_unref(s->cur_pic->f);
- }
-
- return buf_size;
-}
-
-static av_cold int svq3_decode_end(AVCodecContext *avctx)
-{
- SVQ3Context *s = avctx->priv_data;
- H264Context *h = &s->h;
-
- free_picture(avctx, s->cur_pic);
- free_picture(avctx, s->next_pic);
- free_picture(avctx, s->last_pic);
- 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);
-
- memset(&h->cur_pic, 0, sizeof(h->cur_pic));
-
- ff_h264_free_context(h);
-
- av_freep(&s->buf);
- s->buf_size = 0;
-
- return 0;
-}
-
-AVCodec ff_svq3_decoder = {
- .name = "svq3",
- .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_SVQ3,
- .priv_data_size = sizeof(SVQ3Context),
- .init = svq3_decode_init,
- .close = svq3_decode_end,
- .decode = svq3_decode_frame,
- .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND |
- AV_CODEC_CAP_DR1 |
- AV_CODEC_CAP_DELAY,
- .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P,
- AV_PIX_FMT_NONE},
-};
diff --git a/ffmpeg-2-8-11/libavcodec/takdec.c b/ffmpeg-2-8-11/libavcodec/takdec.c
deleted file mode 100644
index bd5f5cb..0000000
--- a/ffmpeg-2-8-11/libavcodec/takdec.c
+++ /dev/null
@@ -1,956 +0,0 @@
-/*
- * TAK decoder
- * Copyright (c) 2012 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
- * TAK (Tom's lossless Audio Kompressor) decoder
- * @author Paul B Mahol
- */
-
-#include "libavutil/internal.h"
-#include "libavutil/samplefmt.h"
-#include "tak.h"
-#include "audiodsp.h"
-#include "thread.h"
-#include "avcodec.h"
-#include "internal.h"
-#include "unary.h"
-
-#define MAX_SUBFRAMES 8 ///< max number of subframes per channel
-#define MAX_PREDICTORS 256
-
-typedef struct MCDParam {
- int8_t present; ///< decorrelation parameter availability for this channel
- int8_t index; ///< index into array of decorrelation types
- int8_t chan1;
- int8_t chan2;
-} MCDParam;
-
-typedef struct TAKDecContext {
- AVCodecContext *avctx; ///< parent AVCodecContext
- AudioDSPContext adsp;
- TAKStreamInfo ti;
- GetBitContext gb; ///< bitstream reader initialized to start at the current frame
-
- int uval;
- int nb_samples; ///< number of samples in the current frame
- uint8_t *decode_buffer;
- unsigned int decode_buffer_size;
- int32_t *decoded[TAK_MAX_CHANNELS]; ///< decoded samples for each channel
-
- int8_t lpc_mode[TAK_MAX_CHANNELS];
- int8_t sample_shift[TAK_MAX_CHANNELS]; ///< shift applied to every sample in the channel
- int16_t predictors[MAX_PREDICTORS];
- int nb_subframes; ///< number of subframes in the current frame
- int16_t subframe_len[MAX_SUBFRAMES]; ///< subframe length in samples
- int subframe_scale;
-
- int8_t dmode; ///< channel decorrelation type in the current frame
-
- MCDParam mcdparams[TAK_MAX_CHANNELS]; ///< multichannel decorrelation parameters
-
- int8_t coding_mode[128];
- DECLARE_ALIGNED(16, int16_t, filter)[MAX_PREDICTORS];
- DECLARE_ALIGNED(16, int16_t, residues)[544];
-} TAKDecContext;
-
-static const int8_t mc_dmodes[] = { 1, 3, 4, 6, };
-
-static const uint16_t predictor_sizes[] = {
- 4, 8, 12, 16, 24, 32, 48, 64, 80, 96, 128, 160, 192, 224, 256, 0,
-};
-
-static const struct CParam {
- int init;
- int escape;
- int scale;
- int aescape;
- int bias;
-} xcodes[50] = {
- { 0x01, 0x0000001, 0x0000001, 0x0000003, 0x0000008 },
- { 0x02, 0x0000003, 0x0000001, 0x0000007, 0x0000006 },
- { 0x03, 0x0000005, 0x0000002, 0x000000E, 0x000000D },
- { 0x03, 0x0000003, 0x0000003, 0x000000D, 0x0000018 },
- { 0x04, 0x000000B, 0x0000004, 0x000001C, 0x0000019 },
- { 0x04, 0x0000006, 0x0000006, 0x000001A, 0x0000030 },
- { 0x05, 0x0000016, 0x0000008, 0x0000038, 0x0000032 },
- { 0x05, 0x000000C, 0x000000C, 0x0000034, 0x0000060 },
- { 0x06, 0x000002C, 0x0000010, 0x0000070, 0x0000064 },
- { 0x06, 0x0000018, 0x0000018, 0x0000068, 0x00000C0 },
- { 0x07, 0x0000058, 0x0000020, 0x00000E0, 0x00000C8 },
- { 0x07, 0x0000030, 0x0000030, 0x00000D0, 0x0000180 },
- { 0x08, 0x00000B0, 0x0000040, 0x00001C0, 0x0000190 },
- { 0x08, 0x0000060, 0x0000060, 0x00001A0, 0x0000300 },
- { 0x09, 0x0000160, 0x0000080, 0x0000380, 0x0000320 },
- { 0x09, 0x00000C0, 0x00000C0, 0x0000340, 0x0000600 },
- { 0x0A, 0x00002C0, 0x0000100, 0x0000700, 0x0000640 },
- { 0x0A, 0x0000180, 0x0000180, 0x0000680, 0x0000C00 },
- { 0x0B, 0x0000580, 0x0000200, 0x0000E00, 0x0000C80 },
- { 0x0B, 0x0000300, 0x0000300, 0x0000D00, 0x0001800 },
- { 0x0C, 0x0000B00, 0x0000400, 0x0001C00, 0x0001900 },
- { 0x0C, 0x0000600, 0x0000600, 0x0001A00, 0x0003000 },
- { 0x0D, 0x0001600, 0x0000800, 0x0003800, 0x0003200 },
- { 0x0D, 0x0000C00, 0x0000C00, 0x0003400, 0x0006000 },
- { 0x0E, 0x0002C00, 0x0001000, 0x0007000, 0x0006400 },
- { 0x0E, 0x0001800, 0x0001800, 0x0006800, 0x000C000 },
- { 0x0F, 0x0005800, 0x0002000, 0x000E000, 0x000C800 },
- { 0x0F, 0x0003000, 0x0003000, 0x000D000, 0x0018000 },
- { 0x10, 0x000B000, 0x0004000, 0x001C000, 0x0019000 },
- { 0x10, 0x0006000, 0x0006000, 0x001A000, 0x0030000 },
- { 0x11, 0x0016000, 0x0008000, 0x0038000, 0x0032000 },
- { 0x11, 0x000C000, 0x000C000, 0x0034000, 0x0060000 },
- { 0x12, 0x002C000, 0x0010000, 0x0070000, 0x0064000 },
- { 0x12, 0x0018000, 0x0018000, 0x0068000, 0x00C0000 },
- { 0x13, 0x0058000, 0x0020000, 0x00E0000, 0x00C8000 },
- { 0x13, 0x0030000, 0x0030000, 0x00D0000, 0x0180000 },
- { 0x14, 0x00B0000, 0x0040000, 0x01C0000, 0x0190000 },
- { 0x14, 0x0060000, 0x0060000, 0x01A0000, 0x0300000 },
- { 0x15, 0x0160000, 0x0080000, 0x0380000, 0x0320000 },
- { 0x15, 0x00C0000, 0x00C0000, 0x0340000, 0x0600000 },
- { 0x16, 0x02C0000, 0x0100000, 0x0700000, 0x0640000 },
- { 0x16, 0x0180000, 0x0180000, 0x0680000, 0x0C00000 },
- { 0x17, 0x0580000, 0x0200000, 0x0E00000, 0x0C80000 },
- { 0x17, 0x0300000, 0x0300000, 0x0D00000, 0x1800000 },
- { 0x18, 0x0B00000, 0x0400000, 0x1C00000, 0x1900000 },
- { 0x18, 0x0600000, 0x0600000, 0x1A00000, 0x3000000 },
- { 0x19, 0x1600000, 0x0800000, 0x3800000, 0x3200000 },
- { 0x19, 0x0C00000, 0x0C00000, 0x3400000, 0x6000000 },
- { 0x1A, 0x2C00000, 0x1000000, 0x7000000, 0x6400000 },
- { 0x1A, 0x1800000, 0x1800000, 0x6800000, 0xC000000 },
-};
-
-static int set_bps_params(AVCodecContext *avctx)
-{
- switch (avctx->bits_per_raw_sample) {
- case 8:
- avctx->sample_fmt = AV_SAMPLE_FMT_U8P;
- break;
- case 16:
- avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
- break;
- case 24:
- avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
- break;
- default:
- av_log(avctx, AV_LOG_ERROR, "invalid/unsupported bits per sample: %d\n",
- avctx->bits_per_raw_sample);
- return AVERROR_INVALIDDATA;
- }
-
- return 0;
-}
-
-static void set_sample_rate_params(AVCodecContext *avctx)
-{
- TAKDecContext *s = avctx->priv_data;
- int shift = 3 - (avctx->sample_rate / 11025);
- shift = FFMAX(0, shift);
- s->uval = FFALIGN(avctx->sample_rate + 511 >> 9, 4) << shift;
- s->subframe_scale = FFALIGN(avctx->sample_rate + 511 >> 9, 4) << 1;
-}
-
-static av_cold int tak_decode_init(AVCodecContext *avctx)
-{
- TAKDecContext *s = avctx->priv_data;
-
- ff_audiodsp_init(&s->adsp);
-
- s->avctx = avctx;
- avctx->bits_per_raw_sample = avctx->bits_per_coded_sample;
-
- set_sample_rate_params(avctx);
-
- return set_bps_params(avctx);
-}
-
-static void decode_lpc(int32_t *coeffs, int mode, int length)
-{
- int i;
-
- if (length < 2)
- return;
-
- if (mode == 1) {
- int a1 = *coeffs++;
- for (i = 0; i < length - 1 >> 1; i++) {
- *coeffs += a1;
- coeffs[1] += *coeffs;
- a1 = coeffs[1];
- coeffs += 2;
- }
- if (length - 1 & 1)
- *coeffs += a1;
- } else if (mode == 2) {
- int a1 = coeffs[1];
- int a2 = a1 + *coeffs;
- coeffs[1] = a2;
- if (length > 2) {
- coeffs += 2;
- for (i = 0; i < length - 2 >> 1; i++) {
- int a3 = *coeffs + a1;
- int a4 = a3 + a2;
- *coeffs = a4;
- a1 = coeffs[1] + a3;
- a2 = a1 + a4;
- coeffs[1] = a2;
- coeffs += 2;
- }
- if (length & 1)
- *coeffs += a1 + a2;
- }
- } else if (mode == 3) {
- int a1 = coeffs[1];
- int a2 = a1 + *coeffs;
- coeffs[1] = a2;
- if (length > 2) {
- int a3 = coeffs[2];
- int a4 = a3 + a1;
- int a5 = a4 + a2;
- coeffs[2] = a5;
- coeffs += 3;
- for (i = 0; i < length - 3; i++) {
- a3 += *coeffs;
- a4 += a3;
- a5 += a4;
- *coeffs = a5;
- coeffs++;
- }
- }
- }
-}
-
-static int decode_segment(TAKDecContext *s, int8_t mode, int32_t *decoded, int len)
-{
- struct CParam code;
- GetBitContext *gb = &s->gb;
- int i;
-
- if (!mode) {
- memset(decoded, 0, len * sizeof(*decoded));
- return 0;
- }
-
- if (mode > FF_ARRAY_ELEMS(xcodes))
- return AVERROR_INVALIDDATA;
- code = xcodes[mode - 1];
-
- for (i = 0; i < len; i++) {
- int x = get_bits_long(gb, code.init);
- if (x >= code.escape && get_bits1(gb)) {
- x |= 1 << code.init;
- if (x >= code.aescape) {
- int scale = get_unary(gb, 1, 9);
- if (scale == 9) {
- int scale_bits = get_bits(gb, 3);
- if (scale_bits > 0) {
- if (scale_bits == 7) {
- scale_bits += get_bits(gb, 5);
- if (scale_bits > 29)
- return AVERROR_INVALIDDATA;
- }
- scale = get_bits_long(gb, scale_bits) + 1;
- x += code.scale * scale;
- }
- x += code.bias;
- } else
- x += code.scale * scale - code.escape;
- } else
- x -= code.escape;
- }
- decoded[i] = (x >> 1) ^ -(x & 1);
- }
-
- return 0;
-}
-
-static int decode_residues(TAKDecContext *s, int32_t *decoded, int length)
-{
- GetBitContext *gb = &s->gb;
- int i, mode, ret;
-
- if (length > s->nb_samples)
- return AVERROR_INVALIDDATA;
-
- if (get_bits1(gb)) {
- int wlength, rval;
-
- wlength = length / s->uval;
-
- rval = length - (wlength * s->uval);
-
- if (rval < s->uval / 2)
- rval += s->uval;
- else
- wlength++;
-
- if (wlength <= 1 || wlength > 128)
- return AVERROR_INVALIDDATA;
-
- s->coding_mode[0] = mode = get_bits(gb, 6);
-
- for (i = 1; i < wlength; i++) {
- int c = get_unary(gb, 1, 6);
-
- switch (c) {
- case 6:
- mode = get_bits(gb, 6);
- break;
- case 5:
- case 4:
- case 3: {
- /* mode += sign ? (1 - c) : (c - 1) */
- int sign = get_bits1(gb);
- mode += (-sign ^ (c - 1)) + sign;
- break;
- }
- case 2:
- mode++;
- break;
- case 1:
- mode--;
- break;
- }
- s->coding_mode[i] = mode;
- }
-
- i = 0;
- while (i < wlength) {
- int len = 0;
-
- mode = s->coding_mode[i];
- do {
- if (i >= wlength - 1)
- len += rval;
- else
- len += s->uval;
- i++;
-
- if (i == wlength)
- break;
- } while (s->coding_mode[i] == mode);
-
- if ((ret = decode_segment(s, mode, decoded, len)) < 0)
- return ret;
- decoded += len;
- }
- } else {
- mode = get_bits(gb, 6);
- if ((ret = decode_segment(s, mode, decoded, length)) < 0)
- return ret;
- }
-
- return 0;
-}
-
-static int get_bits_esc4(GetBitContext *gb)
-{
- if (get_bits1(gb))
- return get_bits(gb, 4) + 1;
- else
- return 0;
-}
-
-static int decode_subframe(TAKDecContext *s, int32_t *decoded,
- int subframe_size, int prev_subframe_size)
-{
- GetBitContext *gb = &s->gb;
- int x, y, i, j, ret = 0;
- int dshift, size, filter_quant, filter_order;
- int tfilter[MAX_PREDICTORS];
-
- if (!get_bits1(gb))
- return decode_residues(s, decoded, subframe_size);
-
- filter_order = predictor_sizes[get_bits(gb, 4)];
-
- if (prev_subframe_size > 0 && get_bits1(gb)) {
- if (filter_order > prev_subframe_size)
- return AVERROR_INVALIDDATA;
-
- decoded -= filter_order;
- subframe_size += filter_order;
-
- if (filter_order > subframe_size)
- return AVERROR_INVALIDDATA;
- } else {
- int lpc_mode;
-
- if (filter_order > subframe_size)
- return AVERROR_INVALIDDATA;
-
- lpc_mode = get_bits(gb, 2);
- if (lpc_mode > 2)
- return AVERROR_INVALIDDATA;
-
- if ((ret = decode_residues(s, decoded, filter_order)) < 0)
- return ret;
-
- if (lpc_mode)
- decode_lpc(decoded, lpc_mode, filter_order);
- }
-
- dshift = get_bits_esc4(gb);
- size = get_bits1(gb) + 6;
-
- filter_quant = 10;
- if (get_bits1(gb)) {
- filter_quant -= get_bits(gb, 3) + 1;
- if (filter_quant < 3)
- return AVERROR_INVALIDDATA;
- }
-
- s->predictors[0] = get_sbits(gb, 10);
- s->predictors[1] = get_sbits(gb, 10);
- s->predictors[2] = get_sbits(gb, size) << (10 - size);
- s->predictors[3] = get_sbits(gb, size) << (10 - size);
- if (filter_order > 4) {
- int tmp = size - get_bits1(gb);
-
- for (i = 4; i < filter_order; i++) {
- if (!(i & 3))
- x = tmp - get_bits(gb, 2);
- s->predictors[i] = get_sbits(gb, x) << (10 - size);
- }
- }
-
- tfilter[0] = s->predictors[0] << 6;
- for (i = 1; i < filter_order; i++) {
- int32_t *p1 = &tfilter[0];
- int32_t *p2 = &tfilter[i - 1];
-
- for (j = 0; j < (i + 1) / 2; j++) {
- x = *p1 + (s->predictors[i] * *p2 + 256 >> 9);
- *p2 += s->predictors[i] * *p1 + 256 >> 9;
- *p1++ = x;
- p2--;
- }
-
- tfilter[i] = s->predictors[i] << 6;
- }
-
- x = 1 << (32 - (15 - filter_quant));
- y = 1 << ((15 - filter_quant) - 1);
- for (i = 0, j = filter_order - 1; i < filter_order / 2; i++, j--) {
- s->filter[j] = x - ((tfilter[i] + y) >> (15 - filter_quant));
- s->filter[i] = x - ((tfilter[j] + y) >> (15 - filter_quant));
- }
-
- if ((ret = decode_residues(s, &decoded[filter_order],
- subframe_size - filter_order)) < 0)
- return ret;
-
- for (i = 0; i < filter_order; i++)
- s->residues[i] = *decoded++ >> dshift;
-
- y = FF_ARRAY_ELEMS(s->residues) - filter_order;
- x = subframe_size - filter_order;
- while (x > 0) {
- int tmp = FFMIN(y, x);
-
- for (i = 0; i < tmp; i++) {
- int v = 1 << (filter_quant - 1);
-
- if (filter_order & -16)
- v += s->adsp.scalarproduct_int16(&s->residues[i], s->filter,
- filter_order & -16);
- for (j = filter_order & -16; j < filter_order; j += 4) {
- v += s->residues[i + j + 3] * s->filter[j + 3] +
- s->residues[i + j + 2] * s->filter[j + 2] +
- s->residues[i + j + 1] * s->filter[j + 1] +
- s->residues[i + j ] * s->filter[j ];
- }
- v = (av_clip_intp2(v >> filter_quant, 13) << dshift) - *decoded;
- *decoded++ = v;
- s->residues[filter_order + i] = v >> dshift;
- }
-
- x -= tmp;
- if (x > 0)
- memcpy(s->residues, &s->residues[y], 2 * filter_order);
- }
-
- emms_c();
-
- return 0;
-}
-
-static int decode_channel(TAKDecContext *s, int chan)
-{
- AVCodecContext *avctx = s->avctx;
- GetBitContext *gb = &s->gb;
- int32_t *decoded = s->decoded[chan];
- int left = s->nb_samples - 1;
- int i = 0, ret, prev = 0;
-
- s->sample_shift[chan] = get_bits_esc4(gb);
- if (s->sample_shift[chan] >= avctx->bits_per_raw_sample)
- return AVERROR_INVALIDDATA;
-
- *decoded++ = get_sbits(gb, avctx->bits_per_raw_sample - s->sample_shift[chan]);
- s->lpc_mode[chan] = get_bits(gb, 2);
- s->nb_subframes = get_bits(gb, 3) + 1;
-
- if (s->nb_subframes > 1) {
- if (get_bits_left(gb) < (s->nb_subframes - 1) * 6)
- return AVERROR_INVALIDDATA;
-
- for (; i < s->nb_subframes - 1; i++) {
- int v = get_bits(gb, 6);
-
- s->subframe_len[i] = (v - prev) * s->subframe_scale;
- if (s->subframe_len[i] <= 0)
- return AVERROR_INVALIDDATA;
-
- left -= s->subframe_len[i];
- prev = v;
- }
-
- if (left <= 0)
- return AVERROR_INVALIDDATA;
- }
- s->subframe_len[i] = left;
-
- prev = 0;
- for (i = 0; i < s->nb_subframes; i++) {
- if ((ret = decode_subframe(s, decoded, s->subframe_len[i], prev)) < 0)
- return ret;
- decoded += s->subframe_len[i];
- prev = s->subframe_len[i];
- }
-
- return 0;
-}
-
-static int decorrelate(TAKDecContext *s, int c1, int c2, int length)
-{
- GetBitContext *gb = &s->gb;
- int32_t *p1 = s->decoded[c1] + 1;
- int32_t *p2 = s->decoded[c2] + 1;
- int i;
- int dshift, dfactor;
-
- switch (s->dmode) {
- case 1: /* left/side */
- for (i = 0; i < length; i++) {
- int32_t a = p1[i];
- int32_t b = p2[i];
- p2[i] = a + b;
- }
- break;
- case 2: /* side/right */
- for (i = 0; i < length; i++) {
- int32_t a = p1[i];
- int32_t b = p2[i];
- p1[i] = b - a;
- }
- break;
- case 3: /* side/mid */
- for (i = 0; i < length; i++) {
- int32_t a = p1[i];
- int32_t b = p2[i];
- a -= b >> 1;
- p1[i] = a;
- p2[i] = a + b;
- }
- break;
- case 4: /* side/left with scale factor */
- FFSWAP(int32_t*, p1, p2);
- case 5: /* side/right with scale factor */
- dshift = get_bits_esc4(gb);
- dfactor = get_sbits(gb, 10);
- for (i = 0; i < length; i++) {
- int32_t a = p1[i];
- int32_t b = p2[i];
- b = dfactor * (b >> dshift) + 128 >> 8 << dshift;
- p1[i] = b - a;
- }
- break;
- case 6:
- FFSWAP(int32_t*, p1, p2);
- case 7: {
- int length2, order_half, filter_order, dval1, dval2;
- int tmp, x, code_size;
-
- if (length < 256)
- return AVERROR_INVALIDDATA;
-
- dshift = get_bits_esc4(gb);
- filter_order = 8 << get_bits1(gb);
- dval1 = get_bits1(gb);
- dval2 = get_bits1(gb);
-
- for (i = 0; i < filter_order; i++) {
- if (!(i & 3))
- code_size = 14 - get_bits(gb, 3);
- s->filter[i] = get_sbits(gb, code_size);
- }
-
- order_half = filter_order / 2;
- length2 = length - (filter_order - 1);
-
- /* decorrelate beginning samples */
- if (dval1) {
- for (i = 0; i < order_half; i++) {
- int32_t a = p1[i];
- int32_t b = p2[i];
- p1[i] = a + b;
- }
- }
-
- /* decorrelate ending samples */
- if (dval2) {
- for (i = length2 + order_half; i < length; i++) {
- int32_t a = p1[i];
- int32_t b = p2[i];
- p1[i] = a + b;
- }
- }
-
-
- for (i = 0; i < filter_order; i++)
- s->residues[i] = *p2++ >> dshift;
-
- p1 += order_half;
- x = FF_ARRAY_ELEMS(s->residues) - filter_order;
- for (; length2 > 0; length2 -= tmp) {
- tmp = FFMIN(length2, x);
-
- for (i = 0; i < tmp - (tmp == length2); i++)
- s->residues[filter_order + i] = *p2++ >> dshift;
-
- for (i = 0; i < tmp; i++) {
- int v = 1 << 9;
-
- if (filter_order == 16) {
- v += s->adsp.scalarproduct_int16(&s->residues[i], s->filter,
- filter_order);
- } else {
- v += s->residues[i + 7] * s->filter[7] +
- s->residues[i + 6] * s->filter[6] +
- s->residues[i + 5] * s->filter[5] +
- s->residues[i + 4] * s->filter[4] +
- s->residues[i + 3] * s->filter[3] +
- s->residues[i + 2] * s->filter[2] +
- s->residues[i + 1] * s->filter[1] +
- s->residues[i ] * s->filter[0];
- }
-
- v = (av_clip_intp2(v >> 10, 13) << dshift) - *p1;
- *p1++ = v;
- }
-
- memmove(s->residues, &s->residues[tmp], 2 * filter_order);
- }
-
- emms_c();
- break;
- }
- }
-
- return 0;
-}
-
-static int tak_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, AVPacket *pkt)
-{
- TAKDecContext *s = avctx->priv_data;
- AVFrame *frame = data;
- ThreadFrame tframe = { .f = data };
- GetBitContext *gb = &s->gb;
- int chan, i, ret, hsize;
-
- if (pkt->size < TAK_MIN_FRAME_HEADER_BYTES)
- return AVERROR_INVALIDDATA;
-
- if ((ret = init_get_bits8(gb, pkt->data, pkt->size)) < 0)
- return ret;
-
- if ((ret = ff_tak_decode_frame_header(avctx, gb, &s->ti, 0)) < 0)
- return ret;
-
- hsize = get_bits_count(gb) / 8;
- if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_COMPLIANT)) {
- if (ff_tak_check_crc(pkt->data, hsize)) {
- av_log(avctx, AV_LOG_ERROR, "CRC error\n");
- if (avctx->err_recognition & AV_EF_EXPLODE)
- return AVERROR_INVALIDDATA;
- }
- }
-
- if (s->ti.codec != TAK_CODEC_MONO_STEREO &&
- s->ti.codec != TAK_CODEC_MULTICHANNEL) {
- av_log(avctx, AV_LOG_ERROR, "unsupported codec: %d\n", s->ti.codec);
- return AVERROR_PATCHWELCOME;
- }
- if (s->ti.data_type) {
- av_log(avctx, AV_LOG_ERROR,
- "unsupported data type: %d\n", s->ti.data_type);
- return AVERROR_INVALIDDATA;
- }
- if (s->ti.codec == TAK_CODEC_MONO_STEREO && s->ti.channels > 2) {
- av_log(avctx, AV_LOG_ERROR,
- "invalid number of channels: %d\n", s->ti.channels);
- return AVERROR_INVALIDDATA;
- }
- if (s->ti.channels > 6) {
- av_log(avctx, AV_LOG_ERROR,
- "unsupported number of channels: %d\n", s->ti.channels);
- return AVERROR_INVALIDDATA;
- }
-
- if (s->ti.frame_samples <= 0) {
- av_log(avctx, AV_LOG_ERROR, "unsupported/invalid number of samples\n");
- return AVERROR_INVALIDDATA;
- }
-
- avctx->bits_per_raw_sample = s->ti.bps;
- if ((ret = set_bps_params(avctx)) < 0)
- return ret;
- if (s->ti.sample_rate != avctx->sample_rate) {
- avctx->sample_rate = s->ti.sample_rate;
- set_sample_rate_params(avctx);
- }
- if (s->ti.ch_layout)
- avctx->channel_layout = s->ti.ch_layout;
- avctx->channels = s->ti.channels;
-
- s->nb_samples = s->ti.last_frame_samples ? s->ti.last_frame_samples
- : s->ti.frame_samples;
-
- frame->nb_samples = s->nb_samples;
- if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
- return ret;
- ff_thread_finish_setup(avctx);
-
- if (avctx->bits_per_raw_sample <= 16) {
- int buf_size = av_samples_get_buffer_size(NULL, avctx->channels,
- s->nb_samples,
- AV_SAMPLE_FMT_S32P, 0);
- if (buf_size < 0)
- return buf_size;
- av_fast_malloc(&s->decode_buffer, &s->decode_buffer_size, buf_size);
- if (!s->decode_buffer)
- return AVERROR(ENOMEM);
- ret = av_samples_fill_arrays((uint8_t **)s->decoded, NULL,
- s->decode_buffer, avctx->channels,
- s->nb_samples, AV_SAMPLE_FMT_S32P, 0);
- if (ret < 0)
- return ret;
- } else {
- for (chan = 0; chan < avctx->channels; chan++)
- s->decoded[chan] = (int32_t *)frame->extended_data[chan];
- }
-
- if (s->nb_samples < 16) {
- for (chan = 0; chan < avctx->channels; chan++) {
- int32_t *decoded = s->decoded[chan];
- for (i = 0; i < s->nb_samples; i++)
- decoded[i] = get_sbits(gb, avctx->bits_per_raw_sample);
- }
- } else {
- if (s->ti.codec == TAK_CODEC_MONO_STEREO) {
- for (chan = 0; chan < avctx->channels; chan++)
- if (ret = decode_channel(s, chan))
- return ret;
-
- if (avctx->channels == 2) {
- s->nb_subframes = get_bits(gb, 1) + 1;
- if (s->nb_subframes > 1) {
- s->subframe_len[1] = get_bits(gb, 6);
- }
-
- s->dmode = get_bits(gb, 3);
- if (ret = decorrelate(s, 0, 1, s->nb_samples - 1))
- return ret;
- }
- } else if (s->ti.codec == TAK_CODEC_MULTICHANNEL) {
- if (get_bits1(gb)) {
- int ch_mask = 0;
-
- chan = get_bits(gb, 4) + 1;
- if (chan > avctx->channels)
- return AVERROR_INVALIDDATA;
-
- for (i = 0; i < chan; i++) {
- int nbit = get_bits(gb, 4);
-
- if (nbit >= avctx->channels)
- return AVERROR_INVALIDDATA;
-
- if (ch_mask & 1 << nbit)
- return AVERROR_INVALIDDATA;
-
- s->mcdparams[i].present = get_bits1(gb);
- if (s->mcdparams[i].present) {
- s->mcdparams[i].index = get_bits(gb, 2);
- s->mcdparams[i].chan2 = get_bits(gb, 4);
- if (s->mcdparams[i].chan2 >= avctx->channels) {
- av_log(avctx, AV_LOG_ERROR,
- "invalid channel 2 (%d) for %d channel(s)\n",
- s->mcdparams[i].chan2, avctx->channels);
- return AVERROR_INVALIDDATA;
- }
- if (s->mcdparams[i].index == 1) {
- if ((nbit == s->mcdparams[i].chan2) ||
- (ch_mask & 1 << s->mcdparams[i].chan2))
- return AVERROR_INVALIDDATA;
-
- ch_mask |= 1 << s->mcdparams[i].chan2;
- } else if (!(ch_mask & 1 << s->mcdparams[i].chan2)) {
- return AVERROR_INVALIDDATA;
- }
- }
- s->mcdparams[i].chan1 = nbit;
-
- ch_mask |= 1 << nbit;
- }
- } else {
- chan = avctx->channels;
- for (i = 0; i < chan; i++) {
- s->mcdparams[i].present = 0;
- s->mcdparams[i].chan1 = i;
- }
- }
-
- for (i = 0; i < chan; i++) {
- if (s->mcdparams[i].present && s->mcdparams[i].index == 1)
- if (ret = decode_channel(s, s->mcdparams[i].chan2))
- return ret;
-
- if (ret = decode_channel(s, s->mcdparams[i].chan1))
- return ret;
-
- if (s->mcdparams[i].present) {
- s->dmode = mc_dmodes[s->mcdparams[i].index];
- if (ret = decorrelate(s,
- s->mcdparams[i].chan2,
- s->mcdparams[i].chan1,
- s->nb_samples - 1))
- return ret;
- }
- }
- }
-
- for (chan = 0; chan < avctx->channels; chan++) {
- int32_t *decoded = s->decoded[chan];
-
- if (s->lpc_mode[chan])
- decode_lpc(decoded, s->lpc_mode[chan], s->nb_samples);
-
- if (s->sample_shift[chan] > 0)
- for (i = 0; i < s->nb_samples; i++)
- decoded[i] <<= s->sample_shift[chan];
- }
- }
-
- align_get_bits(gb);
- skip_bits(gb, 24);
- if (get_bits_left(gb) < 0)
- av_log(avctx, AV_LOG_DEBUG, "overread\n");
- else if (get_bits_left(gb) > 0)
- av_log(avctx, AV_LOG_DEBUG, "underread\n");
-
- if (avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_COMPLIANT)) {
- if (ff_tak_check_crc(pkt->data + hsize,
- get_bits_count(gb) / 8 - hsize)) {
- av_log(avctx, AV_LOG_ERROR, "CRC error\n");
- if (avctx->err_recognition & AV_EF_EXPLODE)
- return AVERROR_INVALIDDATA;
- }
- }
-
- /* convert to output buffer */
- switch (avctx->sample_fmt) {
- case AV_SAMPLE_FMT_U8P:
- for (chan = 0; chan < avctx->channels; chan++) {
- uint8_t *samples = (uint8_t *)frame->extended_data[chan];
- int32_t *decoded = s->decoded[chan];
- for (i = 0; i < s->nb_samples; i++)
- samples[i] = decoded[i] + 0x80;
- }
- break;
- case AV_SAMPLE_FMT_S16P:
- for (chan = 0; chan < avctx->channels; chan++) {
- int16_t *samples = (int16_t *)frame->extended_data[chan];
- int32_t *decoded = s->decoded[chan];
- for (i = 0; i < s->nb_samples; i++)
- samples[i] = decoded[i];
- }
- break;
- case AV_SAMPLE_FMT_S32P:
- for (chan = 0; chan < avctx->channels; chan++) {
- int32_t *samples = (int32_t *)frame->extended_data[chan];
- for (i = 0; i < s->nb_samples; i++)
- samples[i] <<= 8;
- }
- break;
- }
-
- *got_frame_ptr = 1;
-
- return pkt->size;
-}
-
-static int init_thread_copy(AVCodecContext *avctx)
-{
- TAKDecContext *s = avctx->priv_data;
- s->avctx = avctx;
- return 0;
-}
-
-static int update_thread_context(AVCodecContext *dst,
- const AVCodecContext *src)
-{
- TAKDecContext *tsrc = src->priv_data;
- TAKDecContext *tdst = dst->priv_data;
-
- if (dst == src)
- return 0;
- memcpy(&tdst->ti, &tsrc->ti, sizeof(TAKStreamInfo));
- return 0;
-}
-
-static av_cold int tak_decode_close(AVCodecContext *avctx)
-{
- TAKDecContext *s = avctx->priv_data;
-
- av_freep(&s->decode_buffer);
-
- return 0;
-}
-
-AVCodec ff_tak_decoder = {
- .name = "tak",
- .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_TAK,
- .priv_data_size = sizeof(TAKDecContext),
- .init = tak_decode_init,
- .close = tak_decode_close,
- .decode = tak_decode_frame,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
- .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
- .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
- AV_SAMPLE_FMT_S16P,
- AV_SAMPLE_FMT_S32P,
- AV_SAMPLE_FMT_NONE },
-};
diff --git a/ffmpeg-2-8-11/libavcodec/targa_y216dec.c b/ffmpeg-2-8-11/libavcodec/targa_y216dec.c
deleted file mode 100644
index 21b3d35..0000000
--- a/ffmpeg-2-8-11/libavcodec/targa_y216dec.c
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Pinnacle TARGA CineWave YUV16 decoder
- * Copyright (c) 2012 Carl Eugen Hoyos
- *
- * 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"
-
-static av_cold int y216_decode_init(AVCodecContext *avctx)
-{
- avctx->pix_fmt = AV_PIX_FMT_YUV422P16;
- avctx->bits_per_raw_sample = 14;
-
- return 0;
-}
-
-static int y216_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame, AVPacket *avpkt)
-{
- AVFrame *pic = data;
- const uint16_t *src = (uint16_t *)avpkt->data;
- uint16_t *y, *u, *v, aligned_width = FFALIGN(avctx->width, 4);
- int i, j, ret;
-
- if (avpkt->size < 4 * avctx->height * aligned_width) {
- av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
- return AVERROR(EINVAL);
- }
-
- if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
- return ret;
-
- pic->key_frame = 1;
- pic->pict_type = AV_PICTURE_TYPE_I;
-
- y = (uint16_t *)pic->data[0];
- u = (uint16_t *)pic->data[1];
- v = (uint16_t *)pic->data[2];
-
- for (i = 0; i < avctx->height; i++) {
- for (j = 0; j < avctx->width >> 1; j++) {
- u[ j ] = src[4 * j ] << 2 | src[4 * j ] >> 14;
- y[2 * j ] = src[4 * j + 1] << 2 | src[4 * j + 1] >> 14;
- v[ j ] = src[4 * j + 2] << 2 | src[4 * j + 2] >> 14;
- y[2 * j + 1] = src[4 * j + 3] << 2 | src[4 * j + 3] >> 14;
- }
-
- y += pic->linesize[0] >> 1;
- u += pic->linesize[1] >> 1;
- v += pic->linesize[2] >> 1;
- src += aligned_width << 1;
- }
-
- *got_frame = 1;
-
- return avpkt->size;
-}
-
-AVCodec ff_targa_y216_decoder = {
- .name = "targa_y216",
- .long_name = NULL_IF_CONFIG_SMALL("Pinnacle TARGA CineWave YUV16"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_TARGA_Y216,
- .init = y216_decode_init,
- .decode = y216_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/texturedsp.c b/ffmpeg-2-8-11/libavcodec/texturedsp.c
deleted file mode 100644
index 19aa353..0000000
--- a/ffmpeg-2-8-11/libavcodec/texturedsp.c
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
- * Texture block decompression
- * Copyright (C) 2009 Benjamin Dobell, Glass Echidna
- * Copyright (C) 2012 Matthäus G. "Anteru" Chajdas (http://anteru.net)
- * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara at gmail.com>
- *
- * 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 <stddef.h>
-#include <stdint.h>
-
-#include "libavutil/attributes.h"
-#include "libavutil/common.h"
-#include "libavutil/intreadwrite.h"
-
-#include "texturedsp.h"
-
-#define RGBA(r, g, b, a) ((r) | ((g) << 8) | ((b) << 16) | ((a) << 24))
-
-static av_always_inline void extract_color(uint32_t colors[4],
- uint16_t color0,
- uint16_t color1,
- int dxtn, int alpha)
-{
- int tmp;
- uint8_t r0, g0, b0, r1, g1, b1;
- uint8_t a = dxtn ? 0 : 255;
-
- tmp = (color0 >> 11) * 255 + 16;
- r0 = (uint8_t) ((tmp / 32 + tmp) / 32);
- tmp = ((color0 & 0x07E0) >> 5) * 255 + 32;
- g0 = (uint8_t) ((tmp / 64 + tmp) / 64);
- tmp = (color0 & 0x001F) * 255 + 16;
- b0 = (uint8_t) ((tmp / 32 + tmp) / 32);
-
- tmp = (color1 >> 11) * 255 + 16;
- r1 = (uint8_t) ((tmp / 32 + tmp) / 32);
- tmp = ((color1 & 0x07E0) >> 5) * 255 + 32;
- g1 = (uint8_t) ((tmp / 64 + tmp) / 64);
- tmp = (color1 & 0x001F) * 255 + 16;
- b1 = (uint8_t) ((tmp / 32 + tmp) / 32);
-
- if (dxtn || color0 > color1) {
- colors[0] = RGBA(r0, g0, b0, a);
- colors[1] = RGBA(r1, g1, b1, a);
- colors[2] = RGBA((2 * r0 + r1) / 3,
- (2 * g0 + g1) / 3,
- (2 * b0 + b1) / 3,
- a);
- colors[3] = RGBA((2 * r1 + r0) / 3,
- (2 * g1 + g0) / 3,
- (2 * b1 + b0) / 3,
- a);
- } else {
- colors[0] = RGBA(r0, g0, b0, a);
- colors[1] = RGBA(r1, g1, b1, a);
- colors[2] = RGBA((r0 + r1) / 2,
- (g0 + g1) / 2,
- (b0 + b1) / 2,
- a);
- colors[3] = RGBA(0, 0, 0, alpha);
- }
-}
-
-static inline void dxt1_block_internal(uint8_t *dst, ptrdiff_t stride,
- const uint8_t *block, uint8_t alpha)
-{
- int x, y;
- uint32_t colors[4];
- uint16_t color0 = AV_RL16(block + 0);
- uint16_t color1 = AV_RL16(block + 2);
- uint32_t code = AV_RL32(block + 4);
-
- extract_color(colors, color0, color1, 0, alpha);
-
- for (y = 0; y < 4; y++) {
- for (x = 0; x < 4; x++) {
- uint32_t pixel = colors[code & 3];
- code >>= 2;
- AV_WL32(dst + x * 4, pixel);
- }
- dst += stride;
- }
-}
-
-/**
- * Decompress one block of a DXT1 texture and store the resulting
- * RGBA pixels in 'dst'. Alpha component is fully opaque.
- *
- * @param dst output buffer.
- * @param stride scanline in bytes.
- * @param block block to decompress.
- * @return how much texture data has been consumed.
- */
-static int dxt1_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
-{
- dxt1_block_internal(dst, stride, block, 255);
-
- return 8;
-}
-
-/**
- * Decompress one block of a DXT1 with 1-bit alpha texture and store
- * the resulting RGBA pixels in 'dst'. Alpha is either fully opaque or
- * fully transparent.
- *
- * @param dst output buffer.
- * @param stride scanline in bytes.
- * @param block block to decompress.
- * @return how much texture data has been consumed.
- */
-static int dxt1a_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
-{
- dxt1_block_internal(dst, stride, block, 0);
-
- return 8;
-}
-
-static inline void dxt3_block_internal(uint8_t *dst, ptrdiff_t stride,
- const uint8_t *block)
-{
- int x, y;
- uint32_t colors[4];
- uint16_t color0 = AV_RL16(block + 8);
- uint16_t color1 = AV_RL16(block + 10);
- uint32_t code = AV_RL32(block + 12);
-
- extract_color(colors, color0, color1, 1, 0);
-
- for (y = 0; y < 4; y++) {
- const uint16_t alpha_code = AV_RL16(block + 2 * y);
- uint8_t alpha_values[4];
-
- alpha_values[0] = ((alpha_code >> 0) & 0x0F) * 17;
- alpha_values[1] = ((alpha_code >> 4) & 0x0F) * 17;
- alpha_values[2] = ((alpha_code >> 8) & 0x0F) * 17;
- alpha_values[3] = ((alpha_code >> 12) & 0x0F) * 17;
-
- for (x = 0; x < 4; x++) {
- uint8_t alpha = alpha_values[x];
- uint32_t pixel = colors[code & 3] | (alpha << 24);
- code >>= 2;
-
- AV_WL32(dst + x * 4, pixel);
- }
- dst += stride;
- }
-}
-
-/** Convert a premultiplied alpha pixel to a straigth alpha pixel. */
-static av_always_inline void premult2straight(uint8_t *src)
-{
- int r = src[0];
- int g = src[1];
- int b = src[2];
- int a = src[3]; /* unchanged */
-
- src[0] = (uint8_t) r * a / 255;
- src[1] = (uint8_t) g * a / 255;
- src[2] = (uint8_t) b * a / 255;
-}
-
-/**
- * Decompress one block of a DXT2 texture and store the resulting
- * RGBA pixels in 'dst'.
- *
- * @param dst output buffer.
- * @param stride scanline in bytes.
- * @param block block to decompress.
- * @return how much texture data has been consumed.
- */
-static int dxt2_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
-{
- int x, y;
-
- dxt3_block_internal(dst, stride, block);
-
- /* This format is DXT3, but returns premultiplied alpha. It needs to be
- * converted because it's what lavc outputs (and swscale expects). */
- for (y = 0; y < 4; y++)
- for (x = 0; x < 4; x++)
- premult2straight(dst + x * 4 + y * stride);
-
- return 16;
-}
-
-/**
- * Decompress one block of a DXT3 texture and store the resulting
- * RGBA pixels in 'dst'.
- *
- * @param dst output buffer.
- * @param stride scanline in bytes.
- * @param block block to decompress.
- * @return how much texture data has been consumed.
- */
-static int dxt3_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
-{
- dxt3_block_internal(dst, stride, block);
-
- return 16;
-}
-
-/**
- * Decompress a BC 16x3 index block stored as
- * h g f e
- * d c b a
- * p o n m
- * l k j i
- *
- * Bits packed as
- * | h | g | f | e | d | c | b | a | // Entry
- * |765 432 107 654 321 076 543 210| // Bit
- * |0000000000111111111112222222222| // Byte
- *
- * into 16 8-bit indices.
- */
-static void decompress_indices(uint8_t *dst, const uint8_t *src)
-{
- int block, i;
-
- for (block = 0; block < 2; block++) {
- int tmp = AV_RL24(src);
-
- /* Unpack 8x3 bit from last 3 byte block */
- for (i = 0; i < 8; i++)
- dst[i] = (tmp >> (i * 3)) & 0x7;
-
- src += 3;
- dst += 8;
- }
-}
-
-static inline void dxt5_block_internal(uint8_t *dst, ptrdiff_t stride,
- const uint8_t *block)
-{
- int x, y;
- uint32_t colors[4];
- uint8_t alpha_indices[16];
- uint16_t color0 = AV_RL16(block + 8);
- uint16_t color1 = AV_RL16(block + 10);
- uint32_t code = AV_RL32(block + 12);
- uint8_t alpha0 = *(block);
- uint8_t alpha1 = *(block + 1);
-
- decompress_indices(alpha_indices, block + 2);
-
- extract_color(colors, color0, color1, 1, 0);
-
- for (y = 0; y < 4; y++) {
- for (x = 0; x < 4; x++) {
- int alpha_code = alpha_indices[x + y * 4];
- uint32_t pixel;
- uint8_t alpha;
-
- if (alpha_code == 0) {
- alpha = alpha0;
- } else if (alpha_code == 1) {
- alpha = alpha1;
- } else {
- if (alpha0 > alpha1) {
- alpha = (uint8_t) (((8 - alpha_code) * alpha0 +
- (alpha_code - 1) * alpha1) / 7);
- } else {
- if (alpha_code == 6) {
- alpha = 0;
- } else if (alpha_code == 7) {
- alpha = 255;
- } else {
- alpha = (uint8_t) (((6 - alpha_code) * alpha0 +
- (alpha_code - 1) * alpha1) / 5);
- }
- }
- }
- pixel = colors[code & 3] | (alpha << 24);
- code >>= 2;
- AV_WL32(dst + x * 4, pixel);
- }
- dst += stride;
- }
-}
-
-/**
- * Decompress one block of a DXT4 texture and store the resulting
- * RGBA pixels in 'dst'.
- *
- * @param dst output buffer.
- * @param stride scanline in bytes.
- * @param block block to decompress.
- * @return how much texture data has been consumed.
- */
-static int dxt4_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
-{
- int x, y;
-
- dxt5_block_internal(dst, stride, block);
-
- /* This format is DXT5, but returns premultiplied alpha. It needs to be
- * converted because it's what lavc outputs (and swscale expects). */
- for (y = 0; y < 4; y++)
- for (x = 0; x < 4; x++)
- premult2straight(dst + x * 4 + y * stride);
-
- return 16;
-}
-
-/**
- * Decompress one block of a DXT5 texture and store the resulting
- * RGBA pixels in 'dst'.
- *
- * @param dst output buffer.
- * @param stride scanline in bytes.
- * @param block block to decompress.
- * @return how much texture data has been consumed.
- */
-static int dxt5_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
-{
- dxt5_block_internal(dst, stride, block);
-
- return 16;
-}
-
-/**
- * Convert a YCoCg buffer to RGBA.
- *
- * @param src input buffer.
- * @param scaled variant with scaled chroma components and opaque alpha.
- */
-static av_always_inline void ycocg2rgba(uint8_t *src, int scaled)
-{
- int r = src[0];
- int g = src[1];
- int b = src[2];
- int a = src[3];
-
- int s = scaled ? (b >> 3) + 1 : 1;
- int y = a;
- int co = (r - 128) / s;
- int cg = (g - 128) / s;
-
- src[0] = av_clip_uint8(y + co - cg);
- src[1] = av_clip_uint8(y + cg);
- src[2] = av_clip_uint8(y - co - cg);
- src[3] = scaled ? 255 : b;
-}
-
-/**
- * Decompress one block of a DXT5 texture with classic YCoCg and store
- * the resulting RGBA pixels in 'dst'. Alpha component is fully opaque.
- *
- * @param dst output buffer.
- * @param stride scanline in bytes.
- * @param block block to decompress.
- * @return how much texture data has been consumed.
- */
-static int dxt5y_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
-{
- int x, y;
-
- /* This format is basically DXT5, with luma stored in alpha.
- * Run a normal decompress and then reorder the components. */
- dxt5_block_internal(dst, stride, block);
-
- for (y = 0; y < 4; y++)
- for (x = 0; x < 4; x++)
- ycocg2rgba(dst + x * 4 + y * stride, 0);
-
- return 16;
-}
-
-/**
- * Decompress one block of a DXT5 texture with scaled YCoCg and store
- * the resulting RGBA pixels in 'dst'. Alpha component is fully opaque.
- *
- * @param dst output buffer.
- * @param stride scanline in bytes.
- * @param block block to decompress.
- * @return how much texture data has been consumed.
- */
-static int dxt5ys_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
-{
- int x, y;
-
- /* This format is basically DXT5, with luma stored in alpha.
- * Run a normal decompress and then reorder the components. */
- dxt5_block_internal(dst, stride, block);
-
- for (y = 0; y < 4; y++)
- for (x = 0; x < 4; x++)
- ycocg2rgba(dst + x * 4 + y * stride, 1);
-
- return 16;
-}
-
-static inline void rgtc_block_internal(uint8_t *dst, ptrdiff_t stride,
- const uint8_t *block,
- const int *color_tab)
-{
- uint8_t indices[16];
- int x, y;
-
- decompress_indices(indices, block + 2);
-
- /* Only one or two channels are stored at most, since it only used to
- * compress specular (black and white) or normal (red and green) maps.
- * Although the standard says to zero out unused components, many
- * implementations fill all of them with the same value. */
- for (y = 0; y < 4; y++) {
- for (x = 0; x < 4; x++) {
- int i = indices[x + y * 4];
- /* Interval expansion from [-1 1] or [0 1] to [0 255]. */
- int c = color_tab[i];
- uint32_t pixel = RGBA(c, c, c, 255U);
- AV_WL32(dst + x * 4 + y * stride, pixel);
- }
- }
-}
-
-static inline void rgtc1_block_internal(uint8_t *dst, ptrdiff_t stride,
- const uint8_t *block, int sign)
-{
- int color_table[8];
- int r0, r1;
-
- if (sign) {
- /* signed data is in [-128 127] so just offset it to unsigned
- * and it can be treated exactly the same */
- r0 = ((int8_t) block[0]) + 128;
- r1 = ((int8_t) block[1]) + 128;
- } else {
- r0 = block[0];
- r1 = block[1];
- }
-
- color_table[0] = r0;
- color_table[1] = r1;
-
- if (r0 > r1) {
- /* 6 interpolated color values */
- color_table[2] = (6 * r0 + 1 * r1) / 7; // bit code 010
- color_table[3] = (5 * r0 + 2 * r1) / 7; // bit code 011
- color_table[4] = (4 * r0 + 3 * r1) / 7; // bit code 100
- color_table[5] = (3 * r0 + 4 * r1) / 7; // bit code 101
- color_table[6] = (2 * r0 + 5 * r1) / 7; // bit code 110
- color_table[7] = (1 * r0 + 6 * r1) / 7; // bit code 111
- } else {
- /* 4 interpolated color values */
- color_table[2] = (4 * r0 + 1 * r1) / 5; // bit code 010
- color_table[3] = (3 * r0 + 2 * r1) / 5; // bit code 011
- color_table[4] = (2 * r0 + 3 * r1) / 5; // bit code 100
- color_table[5] = (1 * r0 + 4 * r1) / 5; // bit code 101
- color_table[6] = 0; /* min range */ // bit code 110
- color_table[7] = 255; /* max range */ // bit code 111
- }
-
- rgtc_block_internal(dst, stride, block, color_table);
-}
-
-/**
- * Decompress one block of a RGRC1 texture with signed components
- * and store the resulting RGBA pixels in 'dst'.
- *
- * @param dst output buffer.
- * @param stride scanline in bytes.
- * @param block block to decompress.
- * @return how much texture data has been consumed.
- */
-static int rgtc1s_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
-{
- rgtc1_block_internal(dst, stride, block, 1);
-
- return 8;
-}
-
-/**
- * Decompress one block of a RGRC1 texture with unsigned components
- * and store the resulting RGBA pixels in 'dst'.
- *
- * @param dst output buffer.
- * @param stride scanline in bytes.
- * @param block block to decompress.
- * @return how much texture data has been consumed.
- */
-static int rgtc1u_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
-{
- rgtc1_block_internal(dst, stride, block, 0);
-
- return 8;
-}
-
-static inline void rgtc2_block_internal(uint8_t *dst, ptrdiff_t stride,
- const uint8_t *block, int sign)
-{
- /* 4x4 block containing 4 component pixels. */
- uint8_t c0[4 * 4 * 4];
- uint8_t c1[4 * 4 * 4];
- int x, y;
-
- /* Decompress the two channels separately and interleave them afterwards. */
- rgtc1_block_internal(c0, 16, block, sign);
- rgtc1_block_internal(c1, 16, block + 8, sign);
-
- /* B is rebuilt exactly like a normal map. */
- for (y = 0; y < 4; y++) {
- for (x = 0; x < 4; x++) {
- uint8_t *p = dst + x * 4 + y * stride;
- int r = c0[x * 4 + y * 16];
- int g = c1[x * 4 + y * 16];
- int b = 127;
-
- int d = (255 * 255 - r * r - g * g) / 2;
- if (d > 0)
- b = rint(sqrtf(d));
-
- p[0] = r;
- p[1] = g;
- p[2] = b;
- p[3] = 255;
- }
- }
-}
-
-/**
- * Decompress one block of a RGRC2 texture with signed components
- * and store the resulting RGBA pixels in 'dst'. Alpha is fully opaque.
- *
- * @param dst output buffer.
- * @param stride scanline in bytes.
- * @param block block to decompress.
- * @return how much texture data has been consumed.
- */
-static int rgtc2s_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
-{
- rgtc2_block_internal(dst, stride, block, 1);
-
- return 16;
-}
-
-/**
- * Decompress one block of a RGRC2 texture with unsigned components
- * and store the resulting RGBA pixels in 'dst'. Alpha is fully opaque.
- *
- * @param dst output buffer.
- * @param stride scanline in bytes.
- * @param block block to decompress.
- * @return how much texture data has been consumed.
- */
-static int rgtc2u_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
-{
- rgtc2_block_internal(dst, stride, block, 0);
-
- return 16;
-}
-
-/**
- * Decompress one block of a 3Dc texture with unsigned components
- * and store the resulting RGBA pixels in 'dst'. Alpha is fully opaque.
- *
- * @param dst output buffer.
- * @param stride scanline in bytes.
- * @param block block to decompress.
- * @return how much texture data has been consumed.
- */
-static int dxn3dc_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
-{
- int x, y;
- rgtc2_block_internal(dst, stride, block, 0);
-
- /* This is the 3Dc variant of RGTC2, with swapped R and G. */
- for (y = 0; y < 4; y++) {
- for (x = 0; x < 4; x++) {
- uint8_t *p = dst + x * 4 + y * stride;
- FFSWAP(uint8_t, p[0], p[1]);
- }
- }
-
- return 16;
-}
-
-av_cold void ff_texturedsp_init(TextureDSPContext *c)
-{
- c->dxt1_block = dxt1_block;
- c->dxt1a_block = dxt1a_block;
- c->dxt2_block = dxt2_block;
- c->dxt3_block = dxt3_block;
- c->dxt4_block = dxt4_block;
- c->dxt5_block = dxt5_block;
- c->dxt5y_block = dxt5y_block;
- c->dxt5ys_block = dxt5ys_block;
- c->rgtc1s_block = rgtc1s_block;
- c->rgtc1u_block = rgtc1u_block;
- c->rgtc2s_block = rgtc2s_block;
- c->rgtc2u_block = rgtc2u_block;
- c->dxn3dc_block = dxn3dc_block;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/tiertexseqv.c b/ffmpeg-2-8-11/libavcodec/tiertexseqv.c
deleted file mode 100644
index df12ee3..0000000
--- a/ffmpeg-2-8-11/libavcodec/tiertexseqv.c
+++ /dev/null
@@ -1,269 +0,0 @@
-/*
- * Tiertex Limited SEQ Video Decoder
- * Copyright (c) 2006 Gregory Montoir (cyx at users.sourceforge.net)
- *
- * 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
- * Tiertex Limited SEQ video decoder
- */
-
-#include "avcodec.h"
-#define BITSTREAM_READER_LE
-#include "get_bits.h"
-#include "internal.h"
-
-
-typedef struct SeqVideoContext {
- AVCodecContext *avctx;
- AVFrame *frame;
-} SeqVideoContext;
-
-
-static const unsigned char *seq_unpack_rle_block(const unsigned char *src,
- const unsigned char *src_end,
- unsigned char *dst, int dst_size)
-{
- int i, len, sz;
- GetBitContext gb;
- int code_table[64];
-
- /* get the rle codes */
- init_get_bits(&gb, src, (src_end - src) * 8);
- for (i = 0, sz = 0; i < 64 && sz < dst_size; i++) {
- if (get_bits_left(&gb) < 4)
- return NULL;
- code_table[i] = get_sbits(&gb, 4);
- sz += FFABS(code_table[i]);
- }
- src += (get_bits_count(&gb) + 7) / 8;
-
- /* do the rle unpacking */
- for (i = 0; i < 64 && dst_size > 0; i++) {
- len = code_table[i];
- if (len < 0) {
- len = -len;
- if (src_end - src < 1)
- return NULL;
- memset(dst, *src++, FFMIN(len, dst_size));
- } else {
- if (src_end - src < len)
- return NULL;
- memcpy(dst, src, FFMIN(len, dst_size));
- src += len;
- }
- dst += len;
- dst_size -= len;
- }
- return src;
-}
-
-static const unsigned char *seq_decode_op1(SeqVideoContext *seq,
- const unsigned char *src,
- const unsigned char *src_end,
- unsigned char *dst)
-{
- const unsigned char *color_table;
- int b, i, len, bits;
- GetBitContext gb;
- unsigned char block[8 * 8];
-
- if (src_end - src < 1)
- return NULL;
- len = *src++;
- if (len & 0x80) {
- switch (len & 3) {
- case 1:
- src = seq_unpack_rle_block(src, src_end, block, sizeof(block));
- for (b = 0; b < 8; b++) {
- memcpy(dst, &block[b * 8], 8);
- dst += seq->frame->linesize[0];
- }
- break;
- case 2:
- src = seq_unpack_rle_block(src, src_end, block, sizeof(block));
- for (i = 0; i < 8; i++) {
- for (b = 0; b < 8; b++)
- dst[b * seq->frame->linesize[0]] = block[i * 8 + b];
- ++dst;
- }
- break;
- }
- } else {
- if (len <= 0)
- return NULL;
- bits = ff_log2_tab[len - 1] + 1;
- if (src_end - src < len + 8 * bits)
- return NULL;
- color_table = src;
- src += len;
- init_get_bits(&gb, src, bits * 8 * 8); src += bits * 8;
- for (b = 0; b < 8; b++) {
- for (i = 0; i < 8; i++)
- dst[i] = color_table[get_bits(&gb, bits)];
- dst += seq->frame->linesize[0];
- }
- }
-
- return src;
-}
-
-static const unsigned char *seq_decode_op2(SeqVideoContext *seq,
- const unsigned char *src,
- const unsigned char *src_end,
- unsigned char *dst)
-{
- int i;
-
- if (src_end - src < 8 * 8)
- return NULL;
-
- for (i = 0; i < 8; i++) {
- memcpy(dst, src, 8);
- src += 8;
- dst += seq->frame->linesize[0];
- }
-
- return src;
-}
-
-static const unsigned char *seq_decode_op3(SeqVideoContext *seq,
- const unsigned char *src,
- const unsigned char *src_end,
- unsigned char *dst)
-{
- int pos, offset;
-
- do {
- if (src_end - src < 2)
- return NULL;
- pos = *src++;
- offset = ((pos >> 3) & 7) * seq->frame->linesize[0] + (pos & 7);
- dst[offset] = *src++;
- } while (!(pos & 0x80));
-
- return src;
-}
-
-static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size)
-{
- const unsigned char *data_end = data + data_size;
- GetBitContext gb;
- int flags, i, j, x, y, op;
- unsigned char c[3];
- unsigned char *dst;
- uint32_t *palette;
-
- flags = *data++;
-
- if (flags & 1) {
- palette = (uint32_t *)seq->frame->data[1];
- if (data_end - data < 256 * 3)
- return AVERROR_INVALIDDATA;
- for (i = 0; i < 256; i++) {
- for (j = 0; j < 3; j++, data++)
- c[j] = (*data << 2) | (*data >> 4);
- palette[i] = 0xFFU << 24 | AV_RB24(c);
- }
- seq->frame->palette_has_changed = 1;
- }
-
- if (flags & 2) {
- if (data_end - data < 128)
- return AVERROR_INVALIDDATA;
- init_get_bits(&gb, data, 128 * 8); data += 128;
- for (y = 0; y < 128; y += 8)
- for (x = 0; x < 256; x += 8) {
- dst = &seq->frame->data[0][y * seq->frame->linesize[0] + x];
- op = get_bits(&gb, 2);
- switch (op) {
- case 1:
- data = seq_decode_op1(seq, data, data_end, dst);
- break;
- case 2:
- data = seq_decode_op2(seq, data, data_end, dst);
- break;
- case 3:
- data = seq_decode_op3(seq, data, data_end, dst);
- break;
- }
- if (!data)
- return AVERROR_INVALIDDATA;
- }
- }
- return 0;
-}
-
-static av_cold int seqvideo_decode_init(AVCodecContext *avctx)
-{
- SeqVideoContext *seq = avctx->priv_data;
-
- seq->avctx = avctx;
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
-
- seq->frame = av_frame_alloc();
- if (!seq->frame)
- return AVERROR(ENOMEM);
-
- return 0;
-}
-
-static int seqvideo_decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- int ret;
-
- SeqVideoContext *seq = avctx->priv_data;
-
- if ((ret = ff_reget_buffer(avctx, seq->frame)) < 0)
- return ret;
-
- if (seqvideo_decode(seq, buf, buf_size))
- return AVERROR_INVALIDDATA;
-
- if ((ret = av_frame_ref(data, seq->frame)) < 0)
- return ret;
- *got_frame = 1;
-
- return buf_size;
-}
-
-static av_cold int seqvideo_decode_end(AVCodecContext *avctx)
-{
- SeqVideoContext *seq = avctx->priv_data;
-
- av_frame_free(&seq->frame);
-
- return 0;
-}
-
-AVCodec ff_tiertexseqvideo_decoder = {
- .name = "tiertexseqvideo",
- .long_name = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ video"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_TIERTEXSEQVIDEO,
- .priv_data_size = sizeof(SeqVideoContext),
- .init = seqvideo_decode_init,
- .close = seqvideo_decode_end,
- .decode = seqvideo_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/tiff.c b/ffmpeg-2-8-11/libavcodec/tiff.c
deleted file mode 100644
index 4be587d..0000000
--- a/ffmpeg-2-8-11/libavcodec/tiff.c
+++ /dev/null
@@ -1,1393 +0,0 @@
-/*
- * Copyright (c) 2006 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
- */
-
-/**
- * @file
- * TIFF image decoder
- * @author Konstantin Shishkov
- */
-
-#include "config.h"
-#if CONFIG_ZLIB
-#include <zlib.h>
-#endif
-#if CONFIG_LZMA
-#define LZMA_API_STATIC
-#include <lzma.h>
-#endif
-
-#include "libavutil/attributes.h"
-#include "libavutil/avstring.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/imgutils.h"
-#include "avcodec.h"
-#include "bytestream.h"
-#include "faxcompr.h"
-#include "internal.h"
-#include "lzw.h"
-#include "mathops.h"
-#include "tiff.h"
-#include "tiff_data.h"
-#include "thread.h"
-
-typedef struct TiffContext {
- AVCodecContext *avctx;
- GetByteContext gb;
-
- int width, height;
- unsigned int bpp, bppcount;
- uint32_t palette[256];
- int palette_is_set;
- int le;
- enum TiffCompr compr;
- enum TiffPhotometric photometric;
- int planar;
- int subsampling[2];
- int fax_opts;
- int predictor;
- int fill_order;
- uint32_t res[4];
-
- int strips, rps, sstype;
- int sot;
- int stripsizesoff, stripsize, stripoff, strippos;
- LZWState *lzw;
-
- uint8_t *deinvert_buf;
- int deinvert_buf_size;
- uint8_t *yuv_line;
- unsigned int yuv_line_size;
-
- int geotag_count;
- TiffGeoTag *geotags;
-} TiffContext;
-
-static void free_geotags(TiffContext *const s)
-{
- int i;
- for (i = 0; i < s->geotag_count; i++) {
- if (s->geotags[i].val)
- av_freep(&s->geotags[i].val);
- }
- av_freep(&s->geotags);
- s->geotag_count = 0;
-}
-
-#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;
-
-static const char *get_geokey_name(int key)
-{
- RET_GEOKEY(VERT, vert, name);
- RET_GEOKEY(PROJ, proj, name);
- RET_GEOKEY(GEOG, geog, name);
- RET_GEOKEY(CONF, conf, name);
-
- return NULL;
-}
-
-static int get_geokey_type(int key)
-{
- RET_GEOKEY(VERT, vert, type);
- RET_GEOKEY(PROJ, proj, type);
- RET_GEOKEY(GEOG, geog, type);
- RET_GEOKEY(CONF, conf, type);
-
- return AVERROR_INVALIDDATA;
-}
-
-static int cmp_id_key(const void *id, const void *k)
-{
- return *(const int*)id - ((const TiffGeoTagKeyName*)k)->key;
-}
-
-static const char *search_keyval(const TiffGeoTagKeyName *keys, int n, int id)
-{
- TiffGeoTagKeyName *r = bsearch(&id, keys, n, sizeof(keys[0]), cmp_id_key);
- if(r)
- return r->name;
-
- return NULL;
-}
-
-static char *get_geokey_val(int key, int val)
-{
- char *ap;
-
- if (val == TIFF_GEO_KEY_UNDEFINED)
- return av_strdup("undefined");
- if (val == TIFF_GEO_KEY_USER_DEFINED)
- return av_strdup("User-Defined");
-
-#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]);
-
- switch (key) {
- case TIFF_GT_MODEL_TYPE_GEOKEY:
- RET_GEOKEY_VAL(GT_MODEL_TYPE, gt_model_type);
- break;
- case TIFF_GT_RASTER_TYPE_GEOKEY:
- RET_GEOKEY_VAL(GT_RASTER_TYPE, gt_raster_type);
- break;
- case TIFF_GEOG_LINEAR_UNITS_GEOKEY:
- case TIFF_PROJ_LINEAR_UNITS_GEOKEY:
- case TIFF_VERTICAL_UNITS_GEOKEY:
- RET_GEOKEY_VAL(LINEAR_UNIT, linear_unit);
- break;
- case TIFF_GEOG_ANGULAR_UNITS_GEOKEY:
- case TIFF_GEOG_AZIMUTH_UNITS_GEOKEY:
- RET_GEOKEY_VAL(ANGULAR_UNIT, angular_unit);
- break;
- case TIFF_GEOGRAPHIC_TYPE_GEOKEY:
- RET_GEOKEY_VAL(GCS_TYPE, gcs_type);
- RET_GEOKEY_VAL(GCSE_TYPE, gcse_type);
- break;
- case TIFF_GEOG_GEODETIC_DATUM_GEOKEY:
- RET_GEOKEY_VAL(GEODETIC_DATUM, geodetic_datum);
- RET_GEOKEY_VAL(GEODETIC_DATUM_E, geodetic_datum_e);
- break;
- case TIFF_GEOG_ELLIPSOID_GEOKEY:
- RET_GEOKEY_VAL(ELLIPSOID, ellipsoid);
- break;
- case TIFF_GEOG_PRIME_MERIDIAN_GEOKEY:
- 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));
- 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));
- if(ap) return ap;
- break;
- case TIFF_PROJ_COORD_TRANS_GEOKEY:
- RET_GEOKEY_VAL(COORD_TRANS, coord_trans);
- break;
- case TIFF_VERTICAL_CS_TYPE_GEOKEY:
- RET_GEOKEY_VAL(VERT_CS, vert_cs);
- RET_GEOKEY_VAL(ORTHO_VERT_CS, ortho_vert_cs);
- break;
-
- }
-
- ap = av_malloc(14);
- if (ap)
- snprintf(ap, 14, "Unknown-%d", val);
- return ap;
-}
-
-static char *doubles2str(double *dp, int count, const char *sep)
-{
- int i;
- char *ap, *ap0;
- uint64_t component_len;
- if (!sep) sep = ", ";
- component_len = 24LL + strlen(sep);
- if (count >= (INT_MAX - 1)/component_len)
- return NULL;
- ap = av_malloc(component_len * count + 1);
- if (!ap)
- return NULL;
- ap0 = ap;
- ap[0] = '\0';
- for (i = 0; i < count; i++) {
- unsigned l = snprintf(ap, component_len, "%.15g%s", dp[i], sep);
- if(l >= component_len) {
- av_free(ap0);
- return NULL;
- }
- ap += l;
- }
- ap0[strlen(ap0) - strlen(sep)] = '\0';
- return ap0;
-}
-
-static int add_metadata(int count, int type,
- const char *name, const char *sep, TiffContext *s, AVFrame *frame)
-{
- switch(type) {
- case TIFF_DOUBLE: return ff_tadd_doubles_metadata(count, name, sep, &s->gb, s->le, avpriv_frame_get_metadatap(frame));
- case TIFF_SHORT : return ff_tadd_shorts_metadata(count, name, sep, &s->gb, s->le, 0, avpriv_frame_get_metadatap(frame));
- case TIFF_STRING: return ff_tadd_string_metadata(count, name, &s->gb, s->le, avpriv_frame_get_metadatap(frame));
- default : return AVERROR_INVALIDDATA;
- };
-}
-
-static void av_always_inline horizontal_fill(unsigned int bpp, uint8_t* dst,
- int usePtr, const uint8_t *src,
- uint8_t c, int width, int offset)
-{
- switch (bpp) {
- case 1:
- while (--width >= 0) {
- dst[(width+offset)*8+7] = (usePtr ? src[width] : c) & 0x1;
- dst[(width+offset)*8+6] = (usePtr ? src[width] : c) >> 1 & 0x1;
- dst[(width+offset)*8+5] = (usePtr ? src[width] : c) >> 2 & 0x1;
- dst[(width+offset)*8+4] = (usePtr ? src[width] : c) >> 3 & 0x1;
- dst[(width+offset)*8+3] = (usePtr ? src[width] : c) >> 4 & 0x1;
- dst[(width+offset)*8+2] = (usePtr ? src[width] : c) >> 5 & 0x1;
- dst[(width+offset)*8+1] = (usePtr ? src[width] : c) >> 6 & 0x1;
- dst[(width+offset)*8+0] = (usePtr ? src[width] : c) >> 7;
- }
- break;
- case 2:
- while (--width >= 0) {
- dst[(width+offset)*4+3] = (usePtr ? src[width] : c) & 0x3;
- dst[(width+offset)*4+2] = (usePtr ? src[width] : c) >> 2 & 0x3;
- dst[(width+offset)*4+1] = (usePtr ? src[width] : c) >> 4 & 0x3;
- dst[(width+offset)*4+0] = (usePtr ? src[width] : c) >> 6;
- }
- break;
- case 4:
- while (--width >= 0) {
- dst[(width+offset)*2+1] = (usePtr ? src[width] : c) & 0xF;
- dst[(width+offset)*2+0] = (usePtr ? src[width] : c) >> 4;
- }
- break;
- default:
- if (usePtr) {
- memcpy(dst + offset, src, width);
- } else {
- memset(dst + offset, c, width);
- }
- }
-}
-
-static int deinvert_buffer(TiffContext *s, const uint8_t *src, int size)
-{
- int i;
-
- av_fast_padded_malloc(&s->deinvert_buf, &s->deinvert_buf_size, size);
- if (!s->deinvert_buf)
- return AVERROR(ENOMEM);
- for (i = 0; i < size; i++)
- s->deinvert_buf[i] = ff_reverse[src[i]];
-
- return 0;
-}
-
-static void unpack_yuv(TiffContext *s, AVFrame *p,
- const uint8_t *src, int lnum)
-{
- int i, j, k;
- int w = (s->width - 1) / s->subsampling[0] + 1;
- uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]];
- uint8_t *pv = &p->data[2][lnum / s->subsampling[1] * p->linesize[2]];
- if (s->width % s->subsampling[0] || s->height % s->subsampling[1]) {
- for (i = 0; i < w; i++) {
- for (j = 0; j < s->subsampling[1]; j++)
- for (k = 0; k < s->subsampling[0]; k++)
- p->data[0][FFMIN(lnum + j, s->height-1) * p->linesize[0] +
- FFMIN(i * s->subsampling[0] + k, s->width-1)] = *src++;
- *pu++ = *src++;
- *pv++ = *src++;
- }
- }else{
- for (i = 0; i < w; i++) {
- for (j = 0; j < s->subsampling[1]; j++)
- for (k = 0; k < s->subsampling[0]; k++)
- p->data[0][(lnum + j) * p->linesize[0] +
- i * s->subsampling[0] + k] = *src++;
- *pu++ = *src++;
- *pv++ = *src++;
- }
- }
-}
-
-#if CONFIG_ZLIB
-static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src,
- int size)
-{
- z_stream zstream = { 0 };
- int zret;
-
- zstream.next_in = (uint8_t *)src;
- zstream.avail_in = size;
- zstream.next_out = dst;
- zstream.avail_out = *len;
- zret = inflateInit(&zstream);
- if (zret != Z_OK) {
- av_log(NULL, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
- return zret;
- }
- zret = inflate(&zstream, Z_SYNC_FLUSH);
- inflateEnd(&zstream);
- *len = zstream.total_out;
- return zret == Z_STREAM_END ? Z_OK : zret;
-}
-
-static int tiff_unpack_zlib(TiffContext *s, AVFrame *p, uint8_t *dst, int stride,
- const uint8_t *src, int size, int width, int lines,
- int strip_start, int is_yuv)
-{
- uint8_t *zbuf;
- unsigned long outlen;
- int ret, line;
- outlen = width * lines;
- zbuf = av_malloc(outlen);
- if (!zbuf)
- return AVERROR(ENOMEM);
- if (s->fill_order) {
- if ((ret = deinvert_buffer(s, src, size)) < 0) {
- av_free(zbuf);
- return ret;
- }
- src = s->deinvert_buf;
- }
- ret = tiff_uncompress(zbuf, &outlen, src, size);
- if (ret != Z_OK) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Uncompressing failed (%lu of %lu) with error %d\n", outlen,
- (unsigned long)width * lines, ret);
- av_free(zbuf);
- return AVERROR_UNKNOWN;
- }
- src = zbuf;
- for (line = 0; line < lines; line++) {
- if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
- horizontal_fill(s->bpp, dst, 1, src, 0, width, 0);
- } else {
- memcpy(dst, src, width);
- }
- if (is_yuv) {
- unpack_yuv(s, p, dst, strip_start + line);
- line += s->subsampling[1] - 1;
- }
- dst += stride;
- src += width;
- }
- av_free(zbuf);
- return 0;
-}
-#endif
-
-#if CONFIG_LZMA
-static int tiff_uncompress_lzma(uint8_t *dst, uint64_t *len, const uint8_t *src,
- int size)
-{
- lzma_stream stream = LZMA_STREAM_INIT;
- lzma_ret ret;
-
- stream.next_in = (uint8_t *)src;
- stream.avail_in = size;
- stream.next_out = dst;
- stream.avail_out = *len;
- ret = lzma_stream_decoder(&stream, UINT64_MAX, 0);
- if (ret != LZMA_OK) {
- av_log(NULL, AV_LOG_ERROR, "LZMA init error: %d\n", ret);
- return ret;
- }
- ret = lzma_code(&stream, LZMA_RUN);
- lzma_end(&stream);
- *len = stream.total_out;
- return ret == LZMA_STREAM_END ? LZMA_OK : ret;
-}
-
-static int tiff_unpack_lzma(TiffContext *s, AVFrame *p, uint8_t *dst, int stride,
- const uint8_t *src, int size, int width, int lines,
- int strip_start, int is_yuv)
-{
- uint64_t outlen = width * lines;
- int ret, line;
- uint8_t *buf = av_malloc(outlen);
- if (!buf)
- return AVERROR(ENOMEM);
- if (s->fill_order) {
- if ((ret = deinvert_buffer(s, src, size)) < 0) {
- av_free(buf);
- return ret;
- }
- src = s->deinvert_buf;
- }
- ret = tiff_uncompress_lzma(buf, &outlen, src, size);
- if (ret != LZMA_OK) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Uncompressing failed (%"PRIu64" of %"PRIu64") with error %d\n", outlen,
- (uint64_t)width * lines, ret);
- av_free(buf);
- return AVERROR_UNKNOWN;
- }
- src = buf;
- for (line = 0; line < lines; line++) {
- if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
- horizontal_fill(s->bpp, dst, 1, src, 0, width, 0);
- } else {
- memcpy(dst, src, width);
- }
- if (is_yuv) {
- unpack_yuv(s, p, dst, strip_start + line);
- line += s->subsampling[1] - 1;
- }
- dst += stride;
- src += width;
- }
- av_free(buf);
- return 0;
-}
-#endif
-
-static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, int stride,
- const uint8_t *src, int size, int width, int lines)
-{
- int i, ret = 0;
- int line;
- uint8_t *src2 = av_malloc((unsigned)size +
- AV_INPUT_BUFFER_PADDING_SIZE);
-
- if (!src2) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Error allocating temporary buffer\n");
- return AVERROR(ENOMEM);
- }
-
- if (!s->fill_order) {
- memcpy(src2, src, size);
- } else {
- for (i = 0; i < size; i++)
- src2[i] = ff_reverse[src[i]];
- }
- memset(src2 + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride,
- s->compr, s->fax_opts);
- if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
- for (line = 0; line < lines; line++) {
- horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
- dst += stride;
- }
- av_free(src2);
- return ret;
-}
-
-static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int stride,
- const uint8_t *src, int size, int strip_start, int lines)
-{
- PutByteContext pb;
- int c, line, pixels, code, ret;
- const uint8_t *ssrc = src;
- int width = ((s->width * s->bpp) + 7) >> 3;
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(p->format);
- int is_yuv = !(desc->flags & AV_PIX_FMT_FLAG_RGB) &&
- (desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
- desc->nb_components >= 3;
-
- if (s->planar)
- width /= s->bppcount;
-
- if (size <= 0)
- return AVERROR_INVALIDDATA;
-
- if (is_yuv) {
- int bytes_per_row = (((s->width - 1) / s->subsampling[0] + 1) * s->bpp *
- s->subsampling[0] * s->subsampling[1] + 7) >> 3;
- av_fast_padded_malloc(&s->yuv_line, &s->yuv_line_size, bytes_per_row);
- if (s->yuv_line == NULL) {
- av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n");
- return AVERROR(ENOMEM);
- }
- dst = s->yuv_line;
- stride = 0;
-
- width = (s->width - 1) / s->subsampling[0] + 1;
- width = width * s->subsampling[0] * s->subsampling[1] + 2*width;
- av_assert0(width <= bytes_per_row);
- av_assert0(s->bpp == 24);
- }
-
- if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {
-#if CONFIG_ZLIB
- return tiff_unpack_zlib(s, p, dst, stride, src, size, width, lines,
- strip_start, is_yuv);
-#else
- av_log(s->avctx, AV_LOG_ERROR,
- "zlib support not enabled, "
- "deflate compression not supported\n");
- return AVERROR(ENOSYS);
-#endif
- }
- if (s->compr == TIFF_LZMA) {
-#if CONFIG_LZMA
- return tiff_unpack_lzma(s, p, dst, stride, src, size, width, lines,
- strip_start, is_yuv);
-#else
- av_log(s->avctx, AV_LOG_ERROR,
- "LZMA support not enabled\n");
- return AVERROR(ENOSYS);
-#endif
- }
- if (s->compr == TIFF_LZW) {
- if (s->fill_order) {
- if ((ret = deinvert_buffer(s, src, size)) < 0)
- return ret;
- ssrc = src = s->deinvert_buf;
- }
- if (size > 1 && !src[0] && (src[1]&1)) {
- av_log(s->avctx, AV_LOG_ERROR, "Old style LZW is unsupported\n");
- }
- if ((ret = ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF)) < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n");
- return ret;
- }
- for (line = 0; line < lines; line++) {
- pixels = ff_lzw_decode(s->lzw, dst, width);
- if (pixels < width) {
- av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n",
- pixels, width);
- return AVERROR_INVALIDDATA;
- }
- if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
- horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
- if (is_yuv) {
- unpack_yuv(s, p, dst, strip_start + line);
- line += s->subsampling[1] - 1;
- }
- dst += stride;
- }
- return 0;
- }
- if (s->compr == TIFF_CCITT_RLE ||
- s->compr == TIFF_G3 ||
- s->compr == TIFF_G4) {
- if (is_yuv)
- return AVERROR_INVALIDDATA;
-
- return tiff_unpack_fax(s, dst, stride, src, size, width, lines);
- }
-
- bytestream2_init(&s->gb, src, size);
- bytestream2_init_writer(&pb, dst, is_yuv ? s->yuv_line_size : (stride * lines));
-
- for (line = 0; line < lines; line++) {
- if (src - ssrc > size) {
- av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (bytestream2_get_bytes_left(&s->gb) == 0 || bytestream2_get_eof(&pb))
- break;
- bytestream2_seek_p(&pb, stride * line, SEEK_SET);
- switch (s->compr) {
- case TIFF_RAW:
- if (ssrc + size - src < width)
- return AVERROR_INVALIDDATA;
-
- if (!s->fill_order) {
- horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
- dst, 1, src, 0, width, 0);
- } else {
- int i;
- for (i = 0; i < width; i++)
- dst[i] = ff_reverse[src[i]];
- }
- src += width;
- break;
- case TIFF_PACKBITS:
- for (pixels = 0; pixels < width;) {
- if (ssrc + size - src < 2) {
- av_log(s->avctx, AV_LOG_ERROR, "Read went out of bounds\n");
- return AVERROR_INVALIDDATA;
- }
- code = s->fill_order ? (int8_t) ff_reverse[*src++]: (int8_t) *src++;
- if (code >= 0) {
- code++;
- if (pixels + code > width ||
- ssrc + size - src < code) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Copy went out of bounds\n");
- return AVERROR_INVALIDDATA;
- }
- horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
- dst, 1, src, 0, code, pixels);
- src += code;
- pixels += code;
- } else if (code != -128) { // -127..-1
- code = (-code) + 1;
- if (pixels + code > width) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Run went out of bounds\n");
- return AVERROR_INVALIDDATA;
- }
- c = *src++;
- horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
- dst, 0, NULL, c, code, pixels);
- pixels += code;
- }
- }
- if (s->fill_order) {
- int i;
- for (i = 0; i < width; i++)
- dst[i] = ff_reverse[dst[i]];
- }
- break;
- }
- if (is_yuv) {
- unpack_yuv(s, p, dst, strip_start + line);
- line += s->subsampling[1] - 1;
- }
- dst += stride;
- }
- return 0;
-}
-
-static int init_image(TiffContext *s, ThreadFrame *frame)
-{
- int ret;
- int create_gray_palette = 0;
-
- // make sure there is no aliasing in the following switch
- if (s->bpp >= 100 || s->bppcount >= 10) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Unsupported image parameters: bpp=%d, bppcount=%d\n",
- s->bpp, s->bppcount);
- return AVERROR_INVALIDDATA;
- }
-
- switch (s->planar * 1000 + s->bpp * 10 + s->bppcount) {
- case 11:
- if (!s->palette_is_set) {
- s->avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
- break;
- }
- case 21:
- case 41:
- s->avctx->pix_fmt = AV_PIX_FMT_PAL8;
- if (!s->palette_is_set) {
- create_gray_palette = 1;
- }
- break;
- case 81:
- s->avctx->pix_fmt = s->palette_is_set ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
- break;
- case 243:
- if (s->photometric == TIFF_PHOTOMETRIC_YCBCR) {
- if (s->subsampling[0] == 1 && s->subsampling[1] == 1) {
- s->avctx->pix_fmt = AV_PIX_FMT_YUV444P;
- } else if (s->subsampling[0] == 2 && s->subsampling[1] == 1) {
- s->avctx->pix_fmt = AV_PIX_FMT_YUV422P;
- } else if (s->subsampling[0] == 4 && s->subsampling[1] == 1) {
- s->avctx->pix_fmt = AV_PIX_FMT_YUV411P;
- } else if (s->subsampling[0] == 1 && s->subsampling[1] == 2) {
- s->avctx->pix_fmt = AV_PIX_FMT_YUV440P;
- } else if (s->subsampling[0] == 2 && s->subsampling[1] == 2) {
- s->avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- } else if (s->subsampling[0] == 4 && s->subsampling[1] == 4) {
- s->avctx->pix_fmt = AV_PIX_FMT_YUV410P;
- } else {
- av_log(s->avctx, AV_LOG_ERROR, "Unsupported YCbCr subsampling\n");
- return AVERROR_PATCHWELCOME;
- }
- } else
- s->avctx->pix_fmt = AV_PIX_FMT_RGB24;
- break;
- case 161:
- s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GRAY16LE : AV_PIX_FMT_GRAY16BE;
- break;
- case 162:
- s->avctx->pix_fmt = AV_PIX_FMT_YA8;
- break;
- case 322:
- s->avctx->pix_fmt = s->le ? AV_PIX_FMT_YA16LE : AV_PIX_FMT_YA16BE;
- break;
- case 324:
- s->avctx->pix_fmt = AV_PIX_FMT_RGBA;
- break;
- case 483:
- s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGB48LE : AV_PIX_FMT_RGB48BE;
- break;
- case 644:
- s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGBA64LE : AV_PIX_FMT_RGBA64BE;
- break;
- case 1243:
- s->avctx->pix_fmt = AV_PIX_FMT_GBRP;
- break;
- case 1324:
- s->avctx->pix_fmt = AV_PIX_FMT_GBRAP;
- break;
- case 1483:
- s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GBRP16LE : AV_PIX_FMT_GBRP16BE;
- break;
- case 1644:
- s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GBRAP16LE : AV_PIX_FMT_GBRAP16BE;
- break;
- default:
- av_log(s->avctx, AV_LOG_ERROR,
- "This format is not supported (bpp=%d, bppcount=%d)\n",
- s->bpp, s->bppcount);
- return AVERROR_INVALIDDATA;
- }
-
- if (s->photometric == TIFF_PHOTOMETRIC_YCBCR) {
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
- if((desc->flags & AV_PIX_FMT_FLAG_RGB) ||
- !(desc->flags & AV_PIX_FMT_FLAG_PLANAR) ||
- desc->nb_components < 3) {
- av_log(s->avctx, AV_LOG_ERROR, "Unsupported YCbCr variant\n");
- return AVERROR_INVALIDDATA;
- }
- }
-
- if (s->width != s->avctx->width || s->height != s->avctx->height) {
- ret = ff_set_dimensions(s->avctx, s->width, s->height);
- if (ret < 0)
- return ret;
- }
- if ((ret = ff_thread_get_buffer(s->avctx, frame, 0)) < 0)
- return ret;
- if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
- if (!create_gray_palette)
- memcpy(frame->f->data[1], s->palette, sizeof(s->palette));
- else {
- /* make default grayscale pal */
- int i;
- uint32_t *pal = (uint32_t *)frame->f->data[1];
- for (i = 0; i < 1<<s->bpp; i++)
- pal[i] = 0xFFU << 24 | i * 255 / ((1<<s->bpp) - 1) * 0x010101;
- }
- }
- return 0;
-}
-
-static void set_sar(TiffContext *s, unsigned tag, unsigned num, unsigned den)
-{
- int offset = tag == TIFF_YRES ? 2 : 0;
- s->res[offset++] = num;
- s->res[offset] = den;
- if (s->res[0] && s->res[1] && s->res[2] && s->res[3])
- av_reduce(&s->avctx->sample_aspect_ratio.num, &s->avctx->sample_aspect_ratio.den,
- s->res[2] * (uint64_t)s->res[1], s->res[0] * (uint64_t)s->res[3], INT32_MAX);
-}
-
-static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
-{
- unsigned tag, type, count, off, value = 0, value2 = 0;
- int i, start;
- int pos;
- int ret;
- double *dp;
-
- ret = ff_tread_tag(&s->gb, s->le, &tag, &type, &count, &start);
- if (ret < 0) {
- goto end;
- }
-
- off = bytestream2_tell(&s->gb);
- if (count == 1) {
- switch (type) {
- case TIFF_BYTE:
- case TIFF_SHORT:
- case TIFF_LONG:
- value = ff_tget(&s->gb, type, s->le);
- break;
- case TIFF_RATIONAL:
- value = ff_tget(&s->gb, TIFF_LONG, s->le);
- value2 = ff_tget(&s->gb, TIFF_LONG, s->le);
- break;
- case TIFF_STRING:
- if (count <= 4) {
- break;
- }
- default:
- value = UINT_MAX;
- }
- }
-
- switch (tag) {
- case TIFF_WIDTH:
- s->width = value;
- break;
- case TIFF_HEIGHT:
- s->height = value;
- break;
- case TIFF_BPP:
- if (count > 4U) {
- av_log(s->avctx, AV_LOG_ERROR,
- "This format is not supported (bpp=%d, %d components)\n",
- value, count);
- return AVERROR_INVALIDDATA;
- }
- s->bppcount = count;
- if (count == 1)
- s->bpp = value;
- else {
- switch (type) {
- case TIFF_BYTE:
- case TIFF_SHORT:
- case TIFF_LONG:
- s->bpp = 0;
- if (bytestream2_get_bytes_left(&s->gb) < type_sizes[type] * count)
- return AVERROR_INVALIDDATA;
- for (i = 0; i < count; i++)
- s->bpp += ff_tget(&s->gb, type, s->le);
- break;
- default:
- s->bpp = -1;
- }
- }
- break;
- case TIFF_SAMPLES_PER_PIXEL:
- if (count != 1) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Samples per pixel requires a single value, many provided\n");
- return AVERROR_INVALIDDATA;
- }
- if (value > 4U) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Samples per pixel %d is too large\n", value);
- return AVERROR_INVALIDDATA;
- }
- if (s->bppcount == 1)
- s->bpp *= value;
- s->bppcount = value;
- break;
- case TIFF_COMPR:
- s->compr = value;
- s->predictor = 0;
- switch (s->compr) {
- case TIFF_RAW:
- case TIFF_PACKBITS:
- case TIFF_LZW:
- case TIFF_CCITT_RLE:
- break;
- case TIFF_G3:
- case TIFF_G4:
- s->fax_opts = 0;
- break;
- case TIFF_DEFLATE:
- case TIFF_ADOBE_DEFLATE:
-#if CONFIG_ZLIB
- break;
-#else
- av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n");
- return AVERROR(ENOSYS);
-#endif
- case TIFF_JPEG:
- case TIFF_NEWJPEG:
- avpriv_report_missing_feature(s->avctx, "JPEG compression");
- return AVERROR_PATCHWELCOME;
- case TIFF_LZMA:
-#if CONFIG_LZMA
- break;
-#else
- av_log(s->avctx, AV_LOG_ERROR, "LZMA not compiled in\n");
- return AVERROR(ENOSYS);
-#endif
- default:
- av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n",
- s->compr);
- return AVERROR_INVALIDDATA;
- }
- break;
- case TIFF_ROWSPERSTRIP:
- if (!value || (type == TIFF_LONG && value == UINT_MAX))
- value = s->height;
- s->rps = FFMIN(value, s->height);
- break;
- case TIFF_STRIP_OFFS:
- if (count == 1) {
- s->strippos = 0;
- s->stripoff = value;
- } else
- s->strippos = off;
- s->strips = count;
- if (s->strips == 1)
- s->rps = s->height;
- s->sot = type;
- break;
- case TIFF_STRIP_SIZE:
- if (count == 1) {
- s->stripsizesoff = 0;
- s->stripsize = value;
- s->strips = 1;
- } else {
- s->stripsizesoff = off;
- }
- s->strips = count;
- s->sstype = type;
- break;
- case TIFF_XRES:
- case TIFF_YRES:
- set_sar(s, tag, value, value2);
- break;
- case TIFF_TILE_BYTE_COUNTS:
- case TIFF_TILE_LENGTH:
- case TIFF_TILE_OFFSETS:
- case TIFF_TILE_WIDTH:
- av_log(s->avctx, AV_LOG_ERROR, "Tiled images are not supported\n");
- return AVERROR_PATCHWELCOME;
- break;
- case TIFF_PREDICTOR:
- s->predictor = value;
- break;
- case TIFF_PHOTOMETRIC:
- switch (value) {
- case TIFF_PHOTOMETRIC_WHITE_IS_ZERO:
- case TIFF_PHOTOMETRIC_BLACK_IS_ZERO:
- case TIFF_PHOTOMETRIC_RGB:
- case TIFF_PHOTOMETRIC_PALETTE:
- case TIFF_PHOTOMETRIC_YCBCR:
- s->photometric = value;
- break;
- case TIFF_PHOTOMETRIC_ALPHA_MASK:
- case TIFF_PHOTOMETRIC_SEPARATED:
- case TIFF_PHOTOMETRIC_CIE_LAB:
- case TIFF_PHOTOMETRIC_ICC_LAB:
- case TIFF_PHOTOMETRIC_ITU_LAB:
- case TIFF_PHOTOMETRIC_CFA:
- case TIFF_PHOTOMETRIC_LOG_L:
- case TIFF_PHOTOMETRIC_LOG_LUV:
- case TIFF_PHOTOMETRIC_LINEAR_RAW:
- avpriv_report_missing_feature(s->avctx,
- "PhotometricInterpretation 0x%04X",
- value);
- return AVERROR_PATCHWELCOME;
- default:
- av_log(s->avctx, AV_LOG_ERROR, "PhotometricInterpretation %u is "
- "unknown\n", value);
- return AVERROR_INVALIDDATA;
- }
- break;
- case TIFF_FILL_ORDER:
- if (value < 1 || value > 2) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Unknown FillOrder value %d, trying default one\n", value);
- value = 1;
- }
- s->fill_order = value - 1;
- break;
- case TIFF_PAL: {
- GetByteContext pal_gb[3];
- off = type_sizes[type];
- if (count / 3 > 256 ||
- bytestream2_get_bytes_left(&s->gb) < count / 3 * off * 3)
- return AVERROR_INVALIDDATA;
-
- pal_gb[0] = pal_gb[1] = pal_gb[2] = s->gb;
- bytestream2_skip(&pal_gb[1], count / 3 * off);
- bytestream2_skip(&pal_gb[2], count / 3 * off * 2);
-
- off = (type_sizes[type] - 1) << 3;
- for (i = 0; i < count / 3; i++) {
- uint32_t p = 0xFF000000;
- p |= (ff_tget(&pal_gb[0], type, s->le) >> off) << 16;
- p |= (ff_tget(&pal_gb[1], type, s->le) >> off) << 8;
- p |= ff_tget(&pal_gb[2], type, s->le) >> off;
- s->palette[i] = p;
- }
- s->palette_is_set = 1;
- break;
- }
- case TIFF_PLANAR:
- s->planar = value == 2;
- break;
- case TIFF_YCBCR_SUBSAMPLING:
- if (count != 2) {
- av_log(s->avctx, AV_LOG_ERROR, "subsample count invalid\n");
- return AVERROR_INVALIDDATA;
- }
- for (i = 0; i < count; i++) {
- s->subsampling[i] = ff_tget(&s->gb, type, s->le);
- if (s->subsampling[i] <= 0) {
- av_log(s->avctx, AV_LOG_ERROR, "subsampling %d is invalid\n", s->subsampling[i]);
- return AVERROR_INVALIDDATA;
- }
- }
- break;
- case TIFF_T4OPTIONS:
- if (s->compr == TIFF_G3)
- s->fax_opts = value;
- break;
- case TIFF_T6OPTIONS:
- if (s->compr == TIFF_G4)
- s->fax_opts = value;
- break;
-#define ADD_METADATA(count, name, sep)\
- if ((ret = add_metadata(count, type, name, sep, s, frame)) < 0) {\
- av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");\
- goto end;\
- }
- case TIFF_MODEL_PIXEL_SCALE:
- ADD_METADATA(count, "ModelPixelScaleTag", NULL);
- break;
- case TIFF_MODEL_TRANSFORMATION:
- ADD_METADATA(count, "ModelTransformationTag", NULL);
- break;
- case TIFF_MODEL_TIEPOINT:
- ADD_METADATA(count, "ModelTiepointTag", NULL);
- break;
- case TIFF_GEO_KEY_DIRECTORY:
- ADD_METADATA(1, "GeoTIFF_Version", NULL);
- ADD_METADATA(2, "GeoTIFF_Key_Revision", ".");
- s->geotag_count = ff_tget_short(&s->gb, s->le);
- if (s->geotag_count > count / 4 - 1) {
- s->geotag_count = count / 4 - 1;
- av_log(s->avctx, AV_LOG_WARNING, "GeoTIFF key directory buffer shorter than specified\n");
- }
- if (bytestream2_get_bytes_left(&s->gb) < s->geotag_count * sizeof(int16_t) * 4) {
- s->geotag_count = 0;
- return -1;
- }
- s->geotags = av_mallocz_array(s->geotag_count, sizeof(TiffGeoTag));
- if (!s->geotags) {
- av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
- s->geotag_count = 0;
- goto end;
- }
- for (i = 0; i < s->geotag_count; i++) {
- s->geotags[i].key = ff_tget_short(&s->gb, s->le);
- s->geotags[i].type = ff_tget_short(&s->gb, s->le);
- s->geotags[i].count = ff_tget_short(&s->gb, s->le);
-
- if (!s->geotags[i].type)
- s->geotags[i].val = get_geokey_val(s->geotags[i].key, ff_tget_short(&s->gb, s->le));
- else
- s->geotags[i].offset = ff_tget_short(&s->gb, s->le);
- }
- break;
- case TIFF_GEO_DOUBLE_PARAMS:
- if (count >= INT_MAX / sizeof(int64_t))
- return AVERROR_INVALIDDATA;
- if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int64_t))
- return AVERROR_INVALIDDATA;
- dp = av_malloc_array(count, sizeof(double));
- if (!dp) {
- av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
- goto end;
- }
- for (i = 0; i < count; i++)
- dp[i] = ff_tget_double(&s->gb, s->le);
- for (i = 0; i < s->geotag_count; i++) {
- if (s->geotags[i].type == TIFF_GEO_DOUBLE_PARAMS) {
- if (s->geotags[i].count == 0
- || s->geotags[i].offset + s->geotags[i].count > count) {
- av_log(s->avctx, AV_LOG_WARNING, "Invalid GeoTIFF key %d\n", s->geotags[i].key);
- } else {
- char *ap = doubles2str(&dp[s->geotags[i].offset], s->geotags[i].count, ", ");
- if (!ap) {
- av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
- av_freep(&dp);
- return AVERROR(ENOMEM);
- }
- s->geotags[i].val = ap;
- }
- }
- }
- av_freep(&dp);
- break;
- case TIFF_GEO_ASCII_PARAMS:
- pos = bytestream2_tell(&s->gb);
- for (i = 0; i < s->geotag_count; i++) {
- if (s->geotags[i].type == TIFF_GEO_ASCII_PARAMS) {
- if (s->geotags[i].count == 0
- || s->geotags[i].offset + s->geotags[i].count > count) {
- av_log(s->avctx, AV_LOG_WARNING, "Invalid GeoTIFF key %d\n", s->geotags[i].key);
- } else {
- char *ap;
-
- bytestream2_seek(&s->gb, pos + s->geotags[i].offset, SEEK_SET);
- if (bytestream2_get_bytes_left(&s->gb) < s->geotags[i].count)
- return AVERROR_INVALIDDATA;
- ap = av_malloc(s->geotags[i].count);
- if (!ap) {
- av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
- return AVERROR(ENOMEM);
- }
- bytestream2_get_bufferu(&s->gb, ap, s->geotags[i].count);
- ap[s->geotags[i].count - 1] = '\0'; //replace the "|" delimiter with a 0 byte
- s->geotags[i].val = ap;
- }
- }
- }
- break;
- case TIFF_ARTIST:
- ADD_METADATA(count, "artist", NULL);
- break;
- case TIFF_COPYRIGHT:
- ADD_METADATA(count, "copyright", NULL);
- break;
- case TIFF_DATE:
- ADD_METADATA(count, "date", NULL);
- break;
- case TIFF_DOCUMENT_NAME:
- ADD_METADATA(count, "document_name", NULL);
- break;
- case TIFF_HOST_COMPUTER:
- ADD_METADATA(count, "computer", NULL);
- break;
- case TIFF_IMAGE_DESCRIPTION:
- ADD_METADATA(count, "description", NULL);
- break;
- case TIFF_MAKE:
- ADD_METADATA(count, "make", NULL);
- break;
- case TIFF_MODEL:
- ADD_METADATA(count, "model", NULL);
- break;
- case TIFF_PAGE_NAME:
- ADD_METADATA(count, "page_name", NULL);
- break;
- case TIFF_PAGE_NUMBER:
- ADD_METADATA(count, "page_number", " / ");
- break;
- case TIFF_SOFTWARE_NAME:
- ADD_METADATA(count, "software", NULL);
- break;
- default:
- if (s->avctx->err_recognition & AV_EF_EXPLODE) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Unknown or unsupported tag %d/0X%0X\n",
- tag, tag);
- return AVERROR_INVALIDDATA;
- }
- }
-end:
- if (s->bpp > 64U) {
- av_log(s->avctx, AV_LOG_ERROR,
- "This format is not supported (bpp=%d, %d components)\n",
- s->bpp, count);
- s->bpp = 0;
- return AVERROR_INVALIDDATA;
- }
- bytestream2_seek(&s->gb, start, SEEK_SET);
- return 0;
-}
-
-static int decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame, AVPacket *avpkt)
-{
- TiffContext *const s = avctx->priv_data;
- AVFrame *const p = data;
- ThreadFrame frame = { .f = data };
- unsigned off;
- int le, ret, plane, planes;
- int i, j, entries, stride;
- unsigned soff, ssize;
- uint8_t *dst;
- GetByteContext stripsizes;
- GetByteContext stripdata;
-
- bytestream2_init(&s->gb, avpkt->data, avpkt->size);
-
- // parse image header
- if ((ret = ff_tdecode_header(&s->gb, &le, &off))) {
- av_log(avctx, AV_LOG_ERROR, "Invalid TIFF header\n");
- return ret;
- } else if (off >= UINT_MAX - 14 || avpkt->size < off + 14) {
- av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
- return AVERROR_INVALIDDATA;
- }
- s->le = le;
- // TIFF_BPP is not a required tag and defaults to 1
- s->bppcount = s->bpp = 1;
- s->photometric = TIFF_PHOTOMETRIC_NONE;
- s->compr = TIFF_RAW;
- s->fill_order = 0;
- free_geotags(s);
-
- // Reset these offsets so we can tell if they were set this frame
- s->stripsizesoff = s->strippos = 0;
- /* parse image file directory */
- bytestream2_seek(&s->gb, off, SEEK_SET);
- entries = ff_tget_short(&s->gb, le);
- if (bytestream2_get_bytes_left(&s->gb) < entries * 12)
- return AVERROR_INVALIDDATA;
- for (i = 0; i < entries; i++) {
- if ((ret = tiff_decode_tag(s, p)) < 0)
- return ret;
- }
-
- for (i = 0; i<s->geotag_count; i++) {
- const char *keyname = get_geokey_name(s->geotags[i].key);
- if (!keyname) {
- av_log(avctx, AV_LOG_WARNING, "Unknown or unsupported GeoTIFF key %d\n", s->geotags[i].key);
- continue;
- }
- if (get_geokey_type(s->geotags[i].key) != s->geotags[i].type) {
- av_log(avctx, AV_LOG_WARNING, "Type of GeoTIFF key %d is wrong\n", s->geotags[i].key);
- continue;
- }
- ret = av_dict_set(avpriv_frame_get_metadatap(p), keyname, s->geotags[i].val, 0);
- if (ret<0) {
- av_log(avctx, AV_LOG_ERROR, "Writing metadata with key '%s' failed\n", keyname);
- return ret;
- }
- }
-
- if (!s->strippos && !s->stripoff) {
- av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
- return AVERROR_INVALIDDATA;
- }
- /* now we have the data and may start decoding */
- if ((ret = init_image(s, &frame)) < 0)
- return ret;
-
- if (s->strips == 1 && !s->stripsize) {
- av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
- s->stripsize = avpkt->size - s->stripoff;
- }
-
- if (s->stripsizesoff) {
- if (s->stripsizesoff >= (unsigned)avpkt->size)
- return AVERROR_INVALIDDATA;
- bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff,
- avpkt->size - s->stripsizesoff);
- }
- if (s->strippos) {
- if (s->strippos >= (unsigned)avpkt->size)
- return AVERROR_INVALIDDATA;
- bytestream2_init(&stripdata, avpkt->data + s->strippos,
- avpkt->size - s->strippos);
- }
-
- if (s->rps <= 0 || s->rps % s->subsampling[1]) {
- av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps);
- return AVERROR_INVALIDDATA;
- }
-
- planes = s->planar ? s->bppcount : 1;
- for (plane = 0; plane < planes; plane++) {
- stride = p->linesize[plane];
- dst = p->data[plane];
- for (i = 0; i < s->height; i += s->rps) {
- if (s->stripsizesoff)
- ssize = ff_tget(&stripsizes, s->sstype, le);
- else
- ssize = s->stripsize;
-
- if (s->strippos)
- soff = ff_tget(&stripdata, s->sot, le);
- else
- soff = s->stripoff;
-
- if (soff > avpkt->size || ssize > avpkt->size - soff) {
- av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n");
- return AVERROR_INVALIDDATA;
- }
- if ((ret = tiff_unpack_strip(s, p, dst, stride, avpkt->data + soff, ssize, i,
- FFMIN(s->rps, s->height - i))) < 0) {
- if (avctx->err_recognition & AV_EF_EXPLODE)
- return ret;
- break;
- }
- dst += s->rps * stride;
- }
- if (s->predictor == 2) {
- if (s->photometric == TIFF_PHOTOMETRIC_YCBCR) {
- av_log(s->avctx, AV_LOG_ERROR, "predictor == 2 with YUV is unsupported");
- return AVERROR_PATCHWELCOME;
- }
- dst = p->data[plane];
- soff = s->bpp >> 3;
- if (s->planar)
- soff = FFMAX(soff / s->bppcount, 1);
- ssize = s->width * soff;
- if (s->avctx->pix_fmt == AV_PIX_FMT_RGB48LE ||
- s->avctx->pix_fmt == AV_PIX_FMT_RGBA64LE ||
- s->avctx->pix_fmt == AV_PIX_FMT_GRAY16LE ||
- s->avctx->pix_fmt == AV_PIX_FMT_YA16LE ||
- s->avctx->pix_fmt == AV_PIX_FMT_GBRP16LE ||
- s->avctx->pix_fmt == AV_PIX_FMT_GBRAP16LE) {
- for (i = 0; i < s->height; i++) {
- for (j = soff; j < ssize; j += 2)
- AV_WL16(dst + j, AV_RL16(dst + j) + AV_RL16(dst + j - soff));
- dst += stride;
- }
- } else if (s->avctx->pix_fmt == AV_PIX_FMT_RGB48BE ||
- s->avctx->pix_fmt == AV_PIX_FMT_RGBA64BE ||
- s->avctx->pix_fmt == AV_PIX_FMT_GRAY16BE ||
- s->avctx->pix_fmt == AV_PIX_FMT_YA16BE ||
- s->avctx->pix_fmt == AV_PIX_FMT_GBRP16BE ||
- s->avctx->pix_fmt == AV_PIX_FMT_GBRAP16BE) {
- for (i = 0; i < s->height; i++) {
- for (j = soff; j < ssize; j += 2)
- AV_WB16(dst + j, AV_RB16(dst + j) + AV_RB16(dst + j - soff));
- dst += stride;
- }
- } else {
- for (i = 0; i < s->height; i++) {
- for (j = soff; j < ssize; j++)
- dst[j] += dst[j - soff];
- dst += stride;
- }
- }
- }
-
- if (s->photometric == TIFF_PHOTOMETRIC_WHITE_IS_ZERO) {
- dst = p->data[plane];
- for (i = 0; i < s->height; i++) {
- for (j = 0; j < stride; j++)
- dst[j] = (s->avctx->pix_fmt == AV_PIX_FMT_PAL8 ? (1<<s->bpp) - 1 : 255) - dst[j];
- dst += stride;
- }
- }
- }
-
- if (s->planar && s->bppcount > 2) {
- FFSWAP(uint8_t*, p->data[0], p->data[2]);
- FFSWAP(int, p->linesize[0], p->linesize[2]);
- FFSWAP(uint8_t*, p->data[0], p->data[1]);
- FFSWAP(int, p->linesize[0], p->linesize[1]);
- }
-
- *got_frame = 1;
-
- return avpkt->size;
-}
-
-static av_cold int tiff_init(AVCodecContext *avctx)
-{
- TiffContext *s = avctx->priv_data;
-
- s->width = 0;
- s->height = 0;
- s->subsampling[0] =
- s->subsampling[1] = 1;
- s->avctx = avctx;
- ff_lzw_decode_open(&s->lzw);
- ff_ccitt_unpack_init();
-
- return 0;
-}
-
-static av_cold int tiff_end(AVCodecContext *avctx)
-{
- TiffContext *const s = avctx->priv_data;
-
- free_geotags(s);
-
- ff_lzw_decode_close(&s->lzw);
- av_freep(&s->deinvert_buf);
- return 0;
-}
-
-AVCodec ff_tiff_decoder = {
- .name = "tiff",
- .long_name = NULL_IF_CONFIG_SMALL("TIFF image"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_TIFF,
- .priv_data_size = sizeof(TiffContext),
- .init = tiff_init,
- .close = tiff_end,
- .decode = decode_frame,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(tiff_init),
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/truemotion1.c b/ffmpeg-2-8-11/libavcodec/truemotion1.c
deleted file mode 100644
index 14c964d..0000000
--- a/ffmpeg-2-8-11/libavcodec/truemotion1.c
+++ /dev/null
@@ -1,920 +0,0 @@
-/*
- * Duck TrueMotion 1.0 Decoder
- * Copyright (C) 2003 Alex Beregszaszi & Mike Melanson
- *
- * 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
- * Duck TrueMotion v1 Video Decoder by
- * Alex Beregszaszi and
- * Mike Melanson (melanson at pcisys.net)
- *
- * The TrueMotion v1 decoder presently only decodes 16-bit TM1 data and
- * outputs RGB555 (or RGB565) data. 24-bit TM1 data is not supported yet.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "avcodec.h"
-#include "internal.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/internal.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/mem.h"
-
-#include "truemotion1data.h"
-
-typedef struct TrueMotion1Context {
- AVCodecContext *avctx;
- AVFrame *frame;
-
- const uint8_t *buf;
- int size;
-
- const uint8_t *mb_change_bits;
- int mb_change_bits_row_size;
- const uint8_t *index_stream;
- int index_stream_size;
-
- int flags;
- int x, y, w, h;
-
- uint32_t y_predictor_table[1024];
- uint32_t c_predictor_table[1024];
- uint32_t fat_y_predictor_table[1024];
- uint32_t fat_c_predictor_table[1024];
-
- int compression;
- int block_type;
- int block_width;
- int block_height;
-
- int16_t ydt[8];
- int16_t cdt[8];
- int16_t fat_ydt[8];
- int16_t fat_cdt[8];
-
- int last_deltaset, last_vectable;
-
- unsigned int *vert_pred;
- int vert_pred_size;
-
-} TrueMotion1Context;
-
-#define FLAG_SPRITE 32
-#define FLAG_KEYFRAME 16
-#define FLAG_INTERFRAME 8
-#define FLAG_INTERPOLATED 4
-
-struct frame_header {
- uint8_t header_size;
- uint8_t compression;
- uint8_t deltaset;
- uint8_t vectable;
- uint16_t ysize;
- uint16_t xsize;
- uint16_t checksum;
- uint8_t version;
- uint8_t header_type;
- uint8_t flags;
- uint8_t control;
- uint16_t xoffset;
- uint16_t yoffset;
- uint16_t width;
- uint16_t height;
-};
-
-#define ALGO_NOP 0
-#define ALGO_RGB16V 1
-#define ALGO_RGB16H 2
-#define ALGO_RGB24H 3
-
-/* these are the various block sizes that can occupy a 4x4 block */
-#define BLOCK_2x2 0
-#define BLOCK_2x4 1
-#define BLOCK_4x2 2
-#define BLOCK_4x4 3
-
-typedef struct comp_types {
- int algorithm;
- int block_width; // vres
- int block_height; // hres
- int block_type;
-} comp_types;
-
-/* { valid for metatype }, algorithm, num of deltas, vert res, horiz res */
-static const comp_types compression_types[17] = {
- { ALGO_NOP, 0, 0, 0 },
-
- { ALGO_RGB16V, 4, 4, BLOCK_4x4 },
- { ALGO_RGB16H, 4, 4, BLOCK_4x4 },
- { ALGO_RGB16V, 4, 2, BLOCK_4x2 },
- { ALGO_RGB16H, 4, 2, BLOCK_4x2 },
-
- { ALGO_RGB16V, 2, 4, BLOCK_2x4 },
- { ALGO_RGB16H, 2, 4, BLOCK_2x4 },
- { ALGO_RGB16V, 2, 2, BLOCK_2x2 },
- { ALGO_RGB16H, 2, 2, BLOCK_2x2 },
-
- { ALGO_NOP, 4, 4, BLOCK_4x4 },
- { ALGO_RGB24H, 4, 4, BLOCK_4x4 },
- { ALGO_NOP, 4, 2, BLOCK_4x2 },
- { ALGO_RGB24H, 4, 2, BLOCK_4x2 },
-
- { ALGO_NOP, 2, 4, BLOCK_2x4 },
- { ALGO_RGB24H, 2, 4, BLOCK_2x4 },
- { ALGO_NOP, 2, 2, BLOCK_2x2 },
- { ALGO_RGB24H, 2, 2, BLOCK_2x2 }
-};
-
-static void select_delta_tables(TrueMotion1Context *s, int delta_table_index)
-{
- int i;
-
- if (delta_table_index > 3)
- return;
-
- memcpy(s->ydt, ydts[delta_table_index], 8 * sizeof(int16_t));
- memcpy(s->cdt, cdts[delta_table_index], 8 * sizeof(int16_t));
- memcpy(s->fat_ydt, fat_ydts[delta_table_index], 8 * sizeof(int16_t));
- memcpy(s->fat_cdt, fat_cdts[delta_table_index], 8 * sizeof(int16_t));
-
- /* Y skinny deltas need to be halved for some reason; maybe the
- * skinny Y deltas should be modified */
- for (i = 0; i < 8; i++)
- {
- /* drop the lsb before dividing by 2-- net effect: round down
- * when dividing a negative number (e.g., -3/2 = -2, not -1) */
- s->ydt[i] &= 0xFFFE;
- s->ydt[i] /= 2;
- }
-}
-
-#if HAVE_BIGENDIAN
-static int make_ydt15_entry(int p2, int p1, int16_t *ydt)
-#else
-static int make_ydt15_entry(int p1, int p2, int16_t *ydt)
-#endif
-{
- int lo, hi;
-
- lo = ydt[p1];
- lo += (lo << 5) + (lo << 10);
- hi = ydt[p2];
- hi += (hi << 5) + (hi << 10);
- return (lo + (hi << 16)) << 1;
-}
-
-static int make_cdt15_entry(int p1, int p2, int16_t *cdt)
-{
- int r, b, lo;
-
- b = cdt[p2];
- r = cdt[p1] << 10;
- lo = b + r;
- return (lo + (lo << 16)) << 1;
-}
-
-#if HAVE_BIGENDIAN
-static int make_ydt16_entry(int p2, int p1, int16_t *ydt)
-#else
-static int make_ydt16_entry(int p1, int p2, int16_t *ydt)
-#endif
-{
- int lo, hi;
-
- lo = ydt[p1];
- lo += (lo << 6) + (lo << 11);
- hi = ydt[p2];
- hi += (hi << 6) + (hi << 11);
- return (lo + (hi << 16)) << 1;
-}
-
-static int make_cdt16_entry(int p1, int p2, int16_t *cdt)
-{
- int r, b, lo;
-
- b = cdt[p2];
- r = cdt[p1] << 11;
- lo = b + r;
- return (lo + (lo * (1 << 16))) * 2;
-}
-
-static int make_ydt24_entry(int p1, int p2, int16_t *ydt)
-{
- int lo, hi;
-
- lo = ydt[p1];
- hi = ydt[p2];
- return (lo + (hi * (1 << 8)) + (hi * (1 << 16))) * 2;
-}
-
-static int make_cdt24_entry(int p1, int p2, int16_t *cdt)
-{
- int r, b;
-
- b = cdt[p2];
- r = cdt[p1] * (1 << 16);
- return (b+r) * 2;
-}
-
-static void gen_vector_table15(TrueMotion1Context *s, const uint8_t *sel_vector_table)
-{
- int len, i, j;
- unsigned char delta_pair;
-
- for (i = 0; i < 1024; i += 4)
- {
- len = *sel_vector_table++ / 2;
- for (j = 0; j < len; j++)
- {
- delta_pair = *sel_vector_table++;
- s->y_predictor_table[i+j] = 0xfffffffe &
- make_ydt15_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
- s->c_predictor_table[i+j] = 0xfffffffe &
- make_cdt15_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
- }
- s->y_predictor_table[i+(j-1)] |= 1;
- s->c_predictor_table[i+(j-1)] |= 1;
- }
-}
-
-static void gen_vector_table16(TrueMotion1Context *s, const uint8_t *sel_vector_table)
-{
- int len, i, j;
- unsigned char delta_pair;
-
- for (i = 0; i < 1024; i += 4)
- {
- len = *sel_vector_table++ / 2;
- for (j = 0; j < len; j++)
- {
- delta_pair = *sel_vector_table++;
- s->y_predictor_table[i+j] = 0xfffffffe &
- make_ydt16_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
- s->c_predictor_table[i+j] = 0xfffffffe &
- make_cdt16_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
- }
- s->y_predictor_table[i+(j-1)] |= 1;
- s->c_predictor_table[i+(j-1)] |= 1;
- }
-}
-
-static void gen_vector_table24(TrueMotion1Context *s, const uint8_t *sel_vector_table)
-{
- int len, i, j;
- unsigned char delta_pair;
-
- for (i = 0; i < 1024; i += 4)
- {
- len = *sel_vector_table++ / 2;
- for (j = 0; j < len; j++)
- {
- delta_pair = *sel_vector_table++;
- s->y_predictor_table[i+j] = 0xfffffffe &
- make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
- s->c_predictor_table[i+j] = 0xfffffffe &
- make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
- s->fat_y_predictor_table[i+j] = 0xfffffffe &
- make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_ydt);
- s->fat_c_predictor_table[i+j] = 0xfffffffe &
- make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_cdt);
- }
- s->y_predictor_table[i+(j-1)] |= 1;
- s->c_predictor_table[i+(j-1)] |= 1;
- s->fat_y_predictor_table[i+(j-1)] |= 1;
- s->fat_c_predictor_table[i+(j-1)] |= 1;
- }
-}
-
-/* Returns the number of bytes consumed from the bytestream. Returns -1 if
- * there was an error while decoding the header */
-static int truemotion1_decode_header(TrueMotion1Context *s)
-{
- int i, ret;
- int width_shift = 0;
- int new_pix_fmt;
- struct frame_header header;
- uint8_t header_buffer[128] = { 0 }; /* logical maximum size of the header */
- const uint8_t *sel_vector_table;
-
- header.header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f;
- if (s->buf[0] < 0x10)
- {
- av_log(s->avctx, AV_LOG_ERROR, "invalid header size (%d)\n", s->buf[0]);
- return AVERROR_INVALIDDATA;
- }
-
- if (header.header_size + 1 > s->size) {
- av_log(s->avctx, AV_LOG_ERROR, "Input packet too small.\n");
- return AVERROR_INVALIDDATA;
- }
-
- /* unscramble the header bytes with a XOR operation */
- for (i = 1; i < header.header_size; i++)
- header_buffer[i - 1] = s->buf[i] ^ s->buf[i + 1];
-
- header.compression = header_buffer[0];
- header.deltaset = header_buffer[1];
- header.vectable = header_buffer[2];
- header.ysize = AV_RL16(&header_buffer[3]);
- header.xsize = AV_RL16(&header_buffer[5]);
- header.checksum = AV_RL16(&header_buffer[7]);
- header.version = header_buffer[9];
- header.header_type = header_buffer[10];
- header.flags = header_buffer[11];
- header.control = header_buffer[12];
-
- /* Version 2 */
- if (header.version >= 2)
- {
- if (header.header_type > 3)
- {
- av_log(s->avctx, AV_LOG_ERROR, "invalid header type (%d)\n", header.header_type);
- return AVERROR_INVALIDDATA;
- } else if ((header.header_type == 2) || (header.header_type == 3)) {
- s->flags = header.flags;
- if (!(s->flags & FLAG_INTERFRAME))
- s->flags |= FLAG_KEYFRAME;
- } else
- s->flags = FLAG_KEYFRAME;
- } else /* Version 1 */
- s->flags = FLAG_KEYFRAME;
-
- if (s->flags & FLAG_SPRITE) {
- avpriv_request_sample(s->avctx, "Frame with sprite");
- /* FIXME header.width, height, xoffset and yoffset aren't initialized */
- return AVERROR_PATCHWELCOME;
- } else {
- s->w = header.xsize;
- s->h = header.ysize;
- if (header.header_type < 2) {
- if ((s->w < 213) && (s->h >= 176))
- {
- s->flags |= FLAG_INTERPOLATED;
- avpriv_request_sample(s->avctx, "Interpolated frame");
- }
- }
- }
-
- if (header.compression >= 17) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid compression type (%d)\n", header.compression);
- return AVERROR_INVALIDDATA;
- }
-
- if ((header.deltaset != s->last_deltaset) ||
- (header.vectable != s->last_vectable))
- select_delta_tables(s, header.deltaset);
-
- if ((header.compression & 1) && header.header_type)
- sel_vector_table = pc_tbl2;
- else {
- if (header.vectable > 0 && header.vectable < 4)
- sel_vector_table = tables[header.vectable - 1];
- else {
- av_log(s->avctx, AV_LOG_ERROR, "invalid vector table id (%d)\n", header.vectable);
- return AVERROR_INVALIDDATA;
- }
- }
-
- if (compression_types[header.compression].algorithm == ALGO_RGB24H) {
- new_pix_fmt = AV_PIX_FMT_RGB32;
- width_shift = 1;
- } else
- new_pix_fmt = AV_PIX_FMT_RGB555; // RGB565 is supported as well
-
- s->w >>= width_shift;
- if (s->w & 1) {
- avpriv_request_sample(s->avctx, "Frame with odd width");
- return AVERROR_PATCHWELCOME;
- }
-
- if (s->w != s->avctx->width || s->h != s->avctx->height ||
- new_pix_fmt != s->avctx->pix_fmt) {
- av_frame_unref(s->frame);
- s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 };
- s->avctx->pix_fmt = new_pix_fmt;
-
- if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0)
- return ret;
-
- ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio);
-
- av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
- if (!s->vert_pred)
- return AVERROR(ENOMEM);
- }
-
- /* There is 1 change bit per 4 pixels, so each change byte represents
- * 32 pixels; divide width by 4 to obtain the number of change bits and
- * then round up to the nearest byte. */
- s->mb_change_bits_row_size = ((s->avctx->width >> (2 - width_shift)) + 7) >> 3;
-
- if ((header.deltaset != s->last_deltaset) || (header.vectable != s->last_vectable))
- {
- if (compression_types[header.compression].algorithm == ALGO_RGB24H)
- gen_vector_table24(s, sel_vector_table);
- else
- if (s->avctx->pix_fmt == AV_PIX_FMT_RGB555)
- gen_vector_table15(s, sel_vector_table);
- else
- gen_vector_table16(s, sel_vector_table);
- }
-
- /* set up pointers to the other key data chunks */
- s->mb_change_bits = s->buf + header.header_size;
- if (s->flags & FLAG_KEYFRAME) {
- /* no change bits specified for a keyframe; only index bytes */
- s->index_stream = s->mb_change_bits;
- } else {
- /* one change bit per 4x4 block */
- s->index_stream = s->mb_change_bits +
- (s->mb_change_bits_row_size * (s->avctx->height >> 2));
- }
- s->index_stream_size = s->size - (s->index_stream - s->buf);
-
- s->last_deltaset = header.deltaset;
- s->last_vectable = header.vectable;
- s->compression = header.compression;
- s->block_width = compression_types[header.compression].block_width;
- s->block_height = compression_types[header.compression].block_height;
- s->block_type = compression_types[header.compression].block_type;
-
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_INFO, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n",
- s->last_deltaset, s->last_vectable, s->compression, s->block_width,
- s->block_height, s->block_type,
- s->flags & FLAG_KEYFRAME ? " KEY" : "",
- s->flags & FLAG_INTERFRAME ? " INTER" : "",
- s->flags & FLAG_SPRITE ? " SPRITE" : "",
- s->flags & FLAG_INTERPOLATED ? " INTERPOL" : "");
-
- return header.header_size;
-}
-
-static av_cold int truemotion1_decode_init(AVCodecContext *avctx)
-{
- TrueMotion1Context *s = avctx->priv_data;
-
- s->avctx = avctx;
-
- // FIXME: it may change ?
-// if (avctx->bits_per_sample == 24)
-// avctx->pix_fmt = AV_PIX_FMT_RGB24;
-// else
-// avctx->pix_fmt = AV_PIX_FMT_RGB555;
-
- s->frame = av_frame_alloc();
- if (!s->frame)
- return AVERROR(ENOMEM);
-
- /* there is a vertical predictor for each pixel in a line; each vertical
- * predictor is 0 to start with */
- av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
- if (!s->vert_pred)
- return AVERROR(ENOMEM);
-
- return 0;
-}
-
-/*
-Block decoding order:
-
-dxi: Y-Y
-dxic: Y-C-Y
-dxic2: Y-C-Y-C
-
-hres,vres,i,i%vres (0 < i < 4)
-2x2 0: 0 dxic2
-2x2 1: 1 dxi
-2x2 2: 0 dxic2
-2x2 3: 1 dxi
-2x4 0: 0 dxic2
-2x4 1: 1 dxi
-2x4 2: 2 dxi
-2x4 3: 3 dxi
-4x2 0: 0 dxic
-4x2 1: 1 dxi
-4x2 2: 0 dxic
-4x2 3: 1 dxi
-4x4 0: 0 dxic
-4x4 1: 1 dxi
-4x4 2: 2 dxi
-4x4 3: 3 dxi
-*/
-
-#define GET_NEXT_INDEX() \
-{\
- if (index_stream_index >= s->index_stream_size) { \
- av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \
- return; \
- } \
- index = s->index_stream[index_stream_index++] * 4; \
-}
-
-#define INC_INDEX \
-do { \
- if (index >= 1023) { \
- av_log(s->avctx, AV_LOG_ERROR, "Invalid index value.\n"); \
- return; \
- } \
- index++; \
-} while (0)
-
-#define APPLY_C_PREDICTOR() \
- predictor_pair = s->c_predictor_table[index]; \
- horiz_pred += (predictor_pair >> 1); \
- if (predictor_pair & 1) { \
- GET_NEXT_INDEX() \
- if (!index) { \
- GET_NEXT_INDEX() \
- predictor_pair = s->c_predictor_table[index]; \
- horiz_pred += ((predictor_pair >> 1) * 5); \
- if (predictor_pair & 1) \
- GET_NEXT_INDEX() \
- else \
- INC_INDEX; \
- } \
- } else \
- INC_INDEX;
-
-#define APPLY_C_PREDICTOR_24() \
- predictor_pair = s->c_predictor_table[index]; \
- horiz_pred += (predictor_pair >> 1); \
- if (predictor_pair & 1) { \
- GET_NEXT_INDEX() \
- if (!index) { \
- GET_NEXT_INDEX() \
- predictor_pair = s->fat_c_predictor_table[index]; \
- horiz_pred += (predictor_pair >> 1); \
- if (predictor_pair & 1) \
- GET_NEXT_INDEX() \
- else \
- INC_INDEX; \
- } \
- } else \
- INC_INDEX;
-
-
-#define APPLY_Y_PREDICTOR() \
- predictor_pair = s->y_predictor_table[index]; \
- horiz_pred += (predictor_pair >> 1); \
- if (predictor_pair & 1) { \
- GET_NEXT_INDEX() \
- if (!index) { \
- GET_NEXT_INDEX() \
- predictor_pair = s->y_predictor_table[index]; \
- horiz_pred += ((predictor_pair >> 1) * 5); \
- if (predictor_pair & 1) \
- GET_NEXT_INDEX() \
- else \
- INC_INDEX; \
- } \
- } else \
- INC_INDEX;
-
-#define APPLY_Y_PREDICTOR_24() \
- predictor_pair = s->y_predictor_table[index]; \
- horiz_pred += (predictor_pair >> 1); \
- if (predictor_pair & 1) { \
- GET_NEXT_INDEX() \
- if (!index) { \
- GET_NEXT_INDEX() \
- predictor_pair = s->fat_y_predictor_table[index]; \
- horiz_pred += (predictor_pair >> 1); \
- if (predictor_pair & 1) \
- GET_NEXT_INDEX() \
- else \
- INC_INDEX; \
- } \
- } else \
- INC_INDEX;
-
-#define OUTPUT_PIXEL_PAIR() \
- *current_pixel_pair = *vert_pred + horiz_pred; \
- *vert_pred++ = *current_pixel_pair++;
-
-static void truemotion1_decode_16bit(TrueMotion1Context *s)
-{
- int y;
- int pixels_left; /* remaining pixels on this line */
- unsigned int predictor_pair;
- unsigned int horiz_pred;
- unsigned int *vert_pred;
- unsigned int *current_pixel_pair;
- unsigned char *current_line = s->frame->data[0];
- int keyframe = s->flags & FLAG_KEYFRAME;
-
- /* these variables are for managing the stream of macroblock change bits */
- const unsigned char *mb_change_bits = s->mb_change_bits;
- unsigned char mb_change_byte;
- unsigned char mb_change_byte_mask;
- int mb_change_index;
-
- /* these variables are for managing the main index stream */
- int index_stream_index = 0; /* yes, the index into the index stream */
- int index;
-
- /* clean out the line buffer */
- memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int));
-
- GET_NEXT_INDEX();
-
- for (y = 0; y < s->avctx->height; y++) {
-
- /* re-init variables for the next line iteration */
- horiz_pred = 0;
- current_pixel_pair = (unsigned int *)current_line;
- vert_pred = s->vert_pred;
- mb_change_index = 0;
- mb_change_byte = mb_change_bits[mb_change_index++];
- mb_change_byte_mask = 0x01;
- pixels_left = s->avctx->width;
-
- while (pixels_left > 0) {
-
- if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
-
- switch (y & 3) {
- case 0:
- /* if macroblock width is 2, apply C-Y-C-Y; else
- * apply C-Y-Y */
- if (s->block_width == 2) {
- APPLY_C_PREDICTOR();
- APPLY_Y_PREDICTOR();
- OUTPUT_PIXEL_PAIR();
- APPLY_C_PREDICTOR();
- APPLY_Y_PREDICTOR();
- OUTPUT_PIXEL_PAIR();
- } else {
- APPLY_C_PREDICTOR();
- APPLY_Y_PREDICTOR();
- OUTPUT_PIXEL_PAIR();
- APPLY_Y_PREDICTOR();
- OUTPUT_PIXEL_PAIR();
- }
- break;
-
- case 1:
- case 3:
- /* always apply 2 Y predictors on these iterations */
- APPLY_Y_PREDICTOR();
- OUTPUT_PIXEL_PAIR();
- APPLY_Y_PREDICTOR();
- OUTPUT_PIXEL_PAIR();
- break;
-
- case 2:
- /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
- * depending on the macroblock type */
- if (s->block_type == BLOCK_2x2) {
- APPLY_C_PREDICTOR();
- APPLY_Y_PREDICTOR();
- OUTPUT_PIXEL_PAIR();
- APPLY_C_PREDICTOR();
- APPLY_Y_PREDICTOR();
- OUTPUT_PIXEL_PAIR();
- } else if (s->block_type == BLOCK_4x2) {
- APPLY_C_PREDICTOR();
- APPLY_Y_PREDICTOR();
- OUTPUT_PIXEL_PAIR();
- APPLY_Y_PREDICTOR();
- OUTPUT_PIXEL_PAIR();
- } else {
- APPLY_Y_PREDICTOR();
- OUTPUT_PIXEL_PAIR();
- APPLY_Y_PREDICTOR();
- OUTPUT_PIXEL_PAIR();
- }
- break;
- }
-
- } else {
-
- /* skip (copy) four pixels, but reassign the horizontal
- * predictor */
- *vert_pred++ = *current_pixel_pair++;
- horiz_pred = *current_pixel_pair - *vert_pred;
- *vert_pred++ = *current_pixel_pair++;
-
- }
-
- if (!keyframe) {
- mb_change_byte_mask <<= 1;
-
- /* next byte */
- if (!mb_change_byte_mask) {
- mb_change_byte = mb_change_bits[mb_change_index++];
- mb_change_byte_mask = 0x01;
- }
- }
-
- pixels_left -= 4;
- }
-
- /* next change row */
- if (((y + 1) & 3) == 0)
- mb_change_bits += s->mb_change_bits_row_size;
-
- current_line += s->frame->linesize[0];
- }
-}
-
-static void truemotion1_decode_24bit(TrueMotion1Context *s)
-{
- int y;
- int pixels_left; /* remaining pixels on this line */
- unsigned int predictor_pair;
- unsigned int horiz_pred;
- unsigned int *vert_pred;
- unsigned int *current_pixel_pair;
- unsigned char *current_line = s->frame->data[0];
- int keyframe = s->flags & FLAG_KEYFRAME;
-
- /* these variables are for managing the stream of macroblock change bits */
- const unsigned char *mb_change_bits = s->mb_change_bits;
- unsigned char mb_change_byte;
- unsigned char mb_change_byte_mask;
- int mb_change_index;
-
- /* these variables are for managing the main index stream */
- int index_stream_index = 0; /* yes, the index into the index stream */
- int index;
-
- /* clean out the line buffer */
- memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int));
-
- GET_NEXT_INDEX();
-
- for (y = 0; y < s->avctx->height; y++) {
-
- /* re-init variables for the next line iteration */
- horiz_pred = 0;
- current_pixel_pair = (unsigned int *)current_line;
- vert_pred = s->vert_pred;
- mb_change_index = 0;
- mb_change_byte = mb_change_bits[mb_change_index++];
- mb_change_byte_mask = 0x01;
- pixels_left = s->avctx->width;
-
- while (pixels_left > 0) {
-
- if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
-
- switch (y & 3) {
- case 0:
- /* if macroblock width is 2, apply C-Y-C-Y; else
- * apply C-Y-Y */
- if (s->block_width == 2) {
- APPLY_C_PREDICTOR_24();
- APPLY_Y_PREDICTOR_24();
- OUTPUT_PIXEL_PAIR();
- APPLY_C_PREDICTOR_24();
- APPLY_Y_PREDICTOR_24();
- OUTPUT_PIXEL_PAIR();
- } else {
- APPLY_C_PREDICTOR_24();
- APPLY_Y_PREDICTOR_24();
- OUTPUT_PIXEL_PAIR();
- APPLY_Y_PREDICTOR_24();
- OUTPUT_PIXEL_PAIR();
- }
- break;
-
- case 1:
- case 3:
- /* always apply 2 Y predictors on these iterations */
- APPLY_Y_PREDICTOR_24();
- OUTPUT_PIXEL_PAIR();
- APPLY_Y_PREDICTOR_24();
- OUTPUT_PIXEL_PAIR();
- break;
-
- case 2:
- /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
- * depending on the macroblock type */
- if (s->block_type == BLOCK_2x2) {
- APPLY_C_PREDICTOR_24();
- APPLY_Y_PREDICTOR_24();
- OUTPUT_PIXEL_PAIR();
- APPLY_C_PREDICTOR_24();
- APPLY_Y_PREDICTOR_24();
- OUTPUT_PIXEL_PAIR();
- } else if (s->block_type == BLOCK_4x2) {
- APPLY_C_PREDICTOR_24();
- APPLY_Y_PREDICTOR_24();
- OUTPUT_PIXEL_PAIR();
- APPLY_Y_PREDICTOR_24();
- OUTPUT_PIXEL_PAIR();
- } else {
- APPLY_Y_PREDICTOR_24();
- OUTPUT_PIXEL_PAIR();
- APPLY_Y_PREDICTOR_24();
- OUTPUT_PIXEL_PAIR();
- }
- break;
- }
-
- } else {
-
- /* skip (copy) four pixels, but reassign the horizontal
- * predictor */
- *vert_pred++ = *current_pixel_pair++;
- horiz_pred = *current_pixel_pair - *vert_pred;
- *vert_pred++ = *current_pixel_pair++;
-
- }
-
- if (!keyframe) {
- mb_change_byte_mask <<= 1;
-
- /* next byte */
- if (!mb_change_byte_mask) {
- mb_change_byte = mb_change_bits[mb_change_index++];
- mb_change_byte_mask = 0x01;
- }
- }
-
- pixels_left -= 2;
- }
-
- /* next change row */
- if (((y + 1) & 3) == 0)
- mb_change_bits += s->mb_change_bits_row_size;
-
- current_line += s->frame->linesize[0];
- }
-}
-
-
-static int truemotion1_decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int ret, buf_size = avpkt->size;
- TrueMotion1Context *s = avctx->priv_data;
-
- s->buf = buf;
- s->size = buf_size;
-
- if ((ret = truemotion1_decode_header(s)) < 0)
- return ret;
-
- if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
- return ret;
-
- if (compression_types[s->compression].algorithm == ALGO_RGB24H) {
- truemotion1_decode_24bit(s);
- } else if (compression_types[s->compression].algorithm != ALGO_NOP) {
- truemotion1_decode_16bit(s);
- }
-
- if ((ret = av_frame_ref(data, s->frame)) < 0)
- return ret;
-
- *got_frame = 1;
-
- /* report that the buffer was completely consumed */
- return buf_size;
-}
-
-static av_cold int truemotion1_decode_end(AVCodecContext *avctx)
-{
- TrueMotion1Context *s = avctx->priv_data;
-
- av_frame_free(&s->frame);
- av_freep(&s->vert_pred);
-
- return 0;
-}
-
-AVCodec ff_truemotion1_decoder = {
- .name = "truemotion1",
- .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_TRUEMOTION1,
- .priv_data_size = sizeof(TrueMotion1Context),
- .init = truemotion1_decode_init,
- .close = truemotion1_decode_end,
- .decode = truemotion1_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/truemotion2.c b/ffmpeg-2-8-11/libavcodec/truemotion2.c
deleted file mode 100644
index 75373a0..0000000
--- a/ffmpeg-2-8-11/libavcodec/truemotion2.c
+++ /dev/null
@@ -1,1027 +0,0 @@
-/*
- * Duck/ON2 TrueMotion 2 Decoder
- * Copyright (c) 2005 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
- */
-
-/**
- * @file
- * Duck TrueMotion2 decoder.
- */
-
-#include <inttypes.h>
-
-#include "avcodec.h"
-#include "bswapdsp.h"
-#include "bytestream.h"
-#include "get_bits.h"
-#include "internal.h"
-
-#define TM2_ESCAPE 0x80000000
-#define TM2_DELTAS 64
-
-/* Huffman-coded streams of different types of blocks */
-enum TM2_STREAMS {
- TM2_C_HI = 0,
- TM2_C_LO,
- TM2_L_HI,
- TM2_L_LO,
- TM2_UPD,
- TM2_MOT,
- TM2_TYPE,
- TM2_NUM_STREAMS
-};
-
-/* Block types */
-enum TM2_BLOCKS {
- TM2_HI_RES = 0,
- TM2_MED_RES,
- TM2_LOW_RES,
- TM2_NULL_RES,
- TM2_UPDATE,
- TM2_STILL,
- TM2_MOTION
-};
-
-typedef struct TM2Context {
- AVCodecContext *avctx;
- AVFrame *pic;
-
- GetBitContext gb;
- BswapDSPContext bdsp;
-
- uint8_t *buffer;
- int buffer_size;
-
- /* TM2 streams */
- int *tokens[TM2_NUM_STREAMS];
- int tok_lens[TM2_NUM_STREAMS];
- int tok_ptrs[TM2_NUM_STREAMS];
- int deltas[TM2_NUM_STREAMS][TM2_DELTAS];
- /* for blocks decoding */
- int D[4];
- int CD[4];
- int *last;
- int *clast;
-
- /* data for current and previous frame */
- int *Y1_base, *U1_base, *V1_base, *Y2_base, *U2_base, *V2_base;
- int *Y1, *U1, *V1, *Y2, *U2, *V2;
- int y_stride, uv_stride;
- int cur;
-} TM2Context;
-
-/**
-* Huffman codes for each of streams
-*/
-typedef struct TM2Codes {
- VLC vlc; ///< table for FFmpeg bitstream reader
- int bits;
- int *recode; ///< table for converting from code indexes to values
- int length;
-} TM2Codes;
-
-/**
-* structure for gathering Huffman codes information
-*/
-typedef struct TM2Huff {
- int val_bits; ///< length of literal
- int max_bits; ///< maximum length of code
- int min_bits; ///< minimum length of code
- int nodes; ///< total number of nodes in tree
- int num; ///< current number filled
- int max_num; ///< total number of codes
- int *nums; ///< literals
- uint32_t *bits; ///< codes
- int *lens; ///< codelengths
-} TM2Huff;
-
-static int tm2_read_tree(TM2Context *ctx, uint32_t prefix, int length, TM2Huff *huff)
-{
- int ret;
- if (length > huff->max_bits) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Tree exceeded its given depth (%i)\n",
- huff->max_bits);
- return AVERROR_INVALIDDATA;
- }
-
- if (!get_bits1(&ctx->gb)) { /* literal */
- if (length == 0) {
- length = 1;
- }
- if (huff->num >= huff->max_num) {
- av_log(ctx->avctx, AV_LOG_DEBUG, "Too many literals\n");
- 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 0;
- } else { /* non-terminal node */
- if ((ret = tm2_read_tree(ctx, prefix << 1, length + 1, huff)) < 0)
- return ret;
- if ((ret = tm2_read_tree(ctx, (prefix << 1) | 1, length + 1, huff)) < 0)
- return ret;
- }
- return 0;
-}
-
-static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code)
-{
- TM2Huff huff;
- int res = 0;
-
- huff.val_bits = get_bits(&ctx->gb, 5);
- huff.max_bits = get_bits(&ctx->gb, 5);
- huff.min_bits = get_bits(&ctx->gb, 5);
- huff.nodes = get_bits_long(&ctx->gb, 17);
- huff.num = 0;
-
- /* check for correct codes parameters */
- if ((huff.val_bits < 1) || (huff.val_bits > 32) ||
- (huff.max_bits < 0) || (huff.max_bits > 25)) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect tree parameters - literal "
- "length: %i, max code length: %i\n", huff.val_bits, huff.max_bits);
- return AVERROR_INVALIDDATA;
- }
- if ((huff.nodes <= 0) || (huff.nodes > 0x10000)) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of Huffman tree "
- "nodes: %i\n", huff.nodes);
- return AVERROR_INVALIDDATA;
- }
- /* one-node tree */
- if (huff.max_bits == 0)
- huff.max_bits = 1;
-
- /* 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));
-
- if (!huff.nums || !huff.bits || !huff.lens) {
- res = AVERROR(ENOMEM);
- goto out;
- }
-
- res = tm2_read_tree(ctx, 0, 0, &huff);
-
- if (huff.num != huff.max_num) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Got less codes than expected: %i of %i\n",
- huff.num, huff.max_num);
- res = AVERROR_INVALIDDATA;
- }
-
- /* 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);
- 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];
- }
- }
-
-out:
- /* free allocated memory */
- av_free(huff.nums);
- av_free(huff.bits);
- av_free(huff.lens);
-
- return res;
-}
-
-static void tm2_free_codes(TM2Codes *code)
-{
- av_free(code->recode);
- if (code->vlc.table)
- ff_free_vlc(&code->vlc);
-}
-
-static inline int tm2_get_token(GetBitContext *gb, TM2Codes *code)
-{
- int val;
- val = get_vlc2(gb, code->vlc.table, code->bits, 1);
- if(val<0)
- return -1;
- return code->recode[val];
-}
-
-#define TM2_OLD_HEADER_MAGIC 0x00000100
-#define TM2_NEW_HEADER_MAGIC 0x00000101
-
-static inline int tm2_read_header(TM2Context *ctx, const uint8_t *buf)
-{
- uint32_t magic = AV_RL32(buf);
-
- switch (magic) {
- case TM2_OLD_HEADER_MAGIC:
- avpriv_request_sample(ctx->avctx, "Old TM2 header");
- return 0;
- case TM2_NEW_HEADER_MAGIC:
- return 0;
- default:
- av_log(ctx->avctx, AV_LOG_ERROR, "Not a TM2 header: 0x%08"PRIX32"\n",
- magic);
- return AVERROR_INVALIDDATA;
- }
-}
-
-static int tm2_read_deltas(TM2Context *ctx, int stream_id)
-{
- int d, mb;
- int i, v;
-
- d = get_bits(&ctx->gb, 9);
- mb = get_bits(&ctx->gb, 5);
-
- av_assert2(mb < 32);
- if ((d < 1) || (d > TM2_DELTAS) || (mb < 1)) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect delta table: %i deltas x %i bits\n", d, mb);
- return AVERROR_INVALIDDATA;
- }
-
- for (i = 0; i < d; i++) {
- v = get_bits_long(&ctx->gb, mb);
- if (v & (1 << (mb - 1)))
- ctx->deltas[stream_id][i] = v - (1 << mb);
- else
- ctx->deltas[stream_id][i] = v;
- }
- for (; i < TM2_DELTAS; i++)
- ctx->deltas[stream_id][i] = 0;
-
- return 0;
-}
-
-static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, int buf_size)
-{
- int i, ret;
- int skip = 0;
- int len, toks, pos;
- TM2Codes codes;
- GetByteContext gb;
-
- if (buf_size < 4) {
- av_log(ctx->avctx, AV_LOG_ERROR, "not enough space for len left\n");
- return AVERROR_INVALIDDATA;
- }
-
- /* get stream length in dwords */
- bytestream2_init(&gb, buf, buf_size);
- len = bytestream2_get_be32(&gb);
- skip = len * 4 + 4;
-
- if (len == 0)
- return 4;
-
- if (len >= INT_MAX/4-1 || len < 0 || skip > buf_size) {
- av_log(ctx->avctx, AV_LOG_ERROR, "invalid stream size\n");
- return AVERROR_INVALIDDATA;
- }
-
- toks = bytestream2_get_be32(&gb);
- if (toks & 1) {
- len = bytestream2_get_be32(&gb);
- if (len == TM2_ESCAPE) {
- len = bytestream2_get_be32(&gb);
- }
- if (len > 0) {
- pos = bytestream2_tell(&gb);
- if (skip <= pos)
- return AVERROR_INVALIDDATA;
- init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
- if ((ret = tm2_read_deltas(ctx, stream_id)) < 0)
- return ret;
- bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2);
- }
- }
- /* skip unused fields */
- len = bytestream2_get_be32(&gb);
- if (len == TM2_ESCAPE) { /* some unknown length - could be escaped too */
- bytestream2_skip(&gb, 8); /* unused by decoder */
- } else {
- bytestream2_skip(&gb, 4); /* unused by decoder */
- }
-
- pos = bytestream2_tell(&gb);
- if (skip <= pos)
- return AVERROR_INVALIDDATA;
- init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
- if ((ret = tm2_build_huff_table(ctx, &codes)) < 0)
- return ret;
- bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2);
-
- toks >>= 1;
- /* check if we have sane number of tokens */
- if ((toks < 0) || (toks > 0xFFFFFF)) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks);
- tm2_free_codes(&codes);
- return AVERROR_INVALIDDATA;
- }
- ret = av_reallocp_array(&ctx->tokens[stream_id], toks, sizeof(int));
- if (ret < 0) {
- ctx->tok_lens[stream_id] = 0;
- return ret;
- }
- ctx->tok_lens[stream_id] = toks;
- len = bytestream2_get_be32(&gb);
- if (len > 0) {
- pos = bytestream2_tell(&gb);
- if (skip <= pos)
- return AVERROR_INVALIDDATA;
- init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
- for (i = 0; i < toks; i++) {
- if (get_bits_left(&ctx->gb) <= 0) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks);
- return AVERROR_INVALIDDATA;
- }
- ctx->tokens[stream_id][i] = tm2_get_token(&ctx->gb, &codes);
- if (stream_id <= TM2_MOT && ctx->tokens[stream_id][i] >= TM2_DELTAS || ctx->tokens[stream_id][i]<0) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Invalid delta token index %d for type %d, n=%d\n",
- ctx->tokens[stream_id][i], stream_id, i);
- return AVERROR_INVALIDDATA;
- }
- }
- } else {
- for (i = 0; i < toks; i++) {
- ctx->tokens[stream_id][i] = codes.recode[0];
- if (stream_id <= TM2_MOT && ctx->tokens[stream_id][i] >= TM2_DELTAS) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Invalid delta token index %d for type %d, n=%d\n",
- ctx->tokens[stream_id][i], stream_id, i);
- return AVERROR_INVALIDDATA;
- }
- }
- }
- tm2_free_codes(&codes);
-
- return skip;
-}
-
-static inline int GET_TOK(TM2Context *ctx,int type)
-{
- if (ctx->tok_ptrs[type] >= ctx->tok_lens[type]) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Read token from stream %i out of bounds (%i>=%i)\n", type, ctx->tok_ptrs[type], ctx->tok_lens[type]);
- return 0;
- }
- if (type <= TM2_MOT) {
- if (ctx->tokens[type][ctx->tok_ptrs[type]] >= TM2_DELTAS) {
- av_log(ctx->avctx, AV_LOG_ERROR, "token %d is too large\n", ctx->tokens[type][ctx->tok_ptrs[type]]);
- return 0;
- }
- return ctx->deltas[type][ctx->tokens[type][ctx->tok_ptrs[type]++]];
- }
- return ctx->tokens[type][ctx->tok_ptrs[type]++];
-}
-
-/* blocks decoding routines */
-
-/* common Y, U, V pointers initialisation */
-#define TM2_INIT_POINTERS() \
- int *last, *clast; \
- int *Y, *U, *V;\
- int Ystride, Ustride, Vstride;\
-\
- Ystride = ctx->y_stride;\
- Vstride = ctx->uv_stride;\
- Ustride = ctx->uv_stride;\
- Y = (ctx->cur?ctx->Y2:ctx->Y1) + by * 4 * Ystride + bx * 4;\
- V = (ctx->cur?ctx->V2:ctx->V1) + by * 2 * Vstride + bx * 2;\
- U = (ctx->cur?ctx->U2:ctx->U1) + by * 2 * Ustride + bx * 2;\
- last = ctx->last + bx * 4;\
- clast = ctx->clast + bx * 4;
-
-#define TM2_INIT_POINTERS_2() \
- int *Yo, *Uo, *Vo;\
- int oYstride, oUstride, oVstride;\
-\
- TM2_INIT_POINTERS();\
- oYstride = Ystride;\
- oVstride = Vstride;\
- oUstride = Ustride;\
- Yo = (ctx->cur?ctx->Y1:ctx->Y2) + by * 4 * oYstride + bx * 4;\
- Vo = (ctx->cur?ctx->V1:ctx->V2) + by * 2 * oVstride + bx * 2;\
- Uo = (ctx->cur?ctx->U1:ctx->U2) + by * 2 * oUstride + bx * 2;
-
-/* recalculate last and delta values for next blocks */
-#define TM2_RECALC_BLOCK(CHR, stride, last, CD) {\
- CD[0] = CHR[1] - last[1];\
- CD[1] = (int)CHR[stride + 1] - (int)CHR[1];\
- last[0] = (int)CHR[stride + 0];\
- last[1] = (int)CHR[stride + 1];}
-
-/* common operations - add deltas to 4x4 block of luma or 2x2 blocks of chroma */
-static inline void tm2_apply_deltas(TM2Context *ctx, int* Y, int stride, int *deltas, int *last)
-{
- int ct, d;
- int i, j;
-
- for (j = 0; j < 4; j++){
- ct = ctx->D[j];
- for (i = 0; i < 4; i++){
- d = deltas[i + j * 4];
- ct += d;
- last[i] += ct;
- Y[i] = av_clip_uint8(last[i]);
- }
- Y += stride;
- ctx->D[j] = ct;
- }
-}
-
-static inline void tm2_high_chroma(int *data, int stride, int *last, int *CD, int *deltas)
-{
- int i, j;
- for (j = 0; j < 2; j++) {
- for (i = 0; i < 2; i++) {
- CD[j] += deltas[i + j * 2];
- last[i] += CD[j];
- data[i] = last[i];
- }
- data += stride;
- }
-}
-
-static inline void tm2_low_chroma(int *data, int stride, int *clast, int *CD, int *deltas, int bx)
-{
- int t;
- int l;
- int prev;
-
- if (bx > 0)
- prev = clast[-3];
- else
- prev = 0;
- t = (CD[0] + CD[1]) >> 1;
- l = (prev - CD[0] - CD[1] + clast[1]) >> 1;
- CD[1] = CD[0] + CD[1] - t;
- CD[0] = t;
- clast[0] = l;
-
- tm2_high_chroma(data, stride, clast, CD, deltas);
-}
-
-static inline void tm2_hi_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
-{
- int i;
- int deltas[16];
- TM2_INIT_POINTERS();
-
- /* hi-res chroma */
- for (i = 0; i < 4; i++) {
- deltas[i] = GET_TOK(ctx, TM2_C_HI);
- deltas[i + 4] = GET_TOK(ctx, TM2_C_HI);
- }
- tm2_high_chroma(U, Ustride, clast, ctx->CD, deltas);
- tm2_high_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas + 4);
-
- /* hi-res luma */
- for (i = 0; i < 16; i++)
- deltas[i] = GET_TOK(ctx, TM2_L_HI);
-
- tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
-}
-
-static inline void tm2_med_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
-{
- int i;
- int deltas[16];
- TM2_INIT_POINTERS();
-
- /* low-res chroma */
- deltas[0] = GET_TOK(ctx, TM2_C_LO);
- deltas[1] = deltas[2] = deltas[3] = 0;
- tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx);
-
- deltas[0] = GET_TOK(ctx, TM2_C_LO);
- deltas[1] = deltas[2] = deltas[3] = 0;
- tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
-
- /* hi-res luma */
- for (i = 0; i < 16; i++)
- deltas[i] = GET_TOK(ctx, TM2_L_HI);
-
- tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
-}
-
-static inline void tm2_low_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
-{
- int i;
- int t1, t2;
- int deltas[16];
- TM2_INIT_POINTERS();
-
- /* low-res chroma */
- deltas[0] = GET_TOK(ctx, TM2_C_LO);
- deltas[1] = deltas[2] = deltas[3] = 0;
- tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx);
-
- deltas[0] = GET_TOK(ctx, TM2_C_LO);
- deltas[1] = deltas[2] = deltas[3] = 0;
- tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
-
- /* low-res luma */
- for (i = 0; i < 16; i++)
- deltas[i] = 0;
-
- deltas[ 0] = GET_TOK(ctx, TM2_L_LO);
- deltas[ 2] = GET_TOK(ctx, TM2_L_LO);
- deltas[ 8] = GET_TOK(ctx, TM2_L_LO);
- deltas[10] = GET_TOK(ctx, TM2_L_LO);
-
- if (bx > 0)
- last[0] = (last[-1] - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3] + last[1]) >> 1;
- else
- last[0] = (last[1] - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3])>> 1;
- last[2] = (last[1] + last[3]) >> 1;
-
- t1 = ctx->D[0] + ctx->D[1];
- ctx->D[0] = t1 >> 1;
- ctx->D[1] = t1 - (t1 >> 1);
- t2 = ctx->D[2] + ctx->D[3];
- ctx->D[2] = t2 >> 1;
- ctx->D[3] = t2 - (t2 >> 1);
-
- tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
-}
-
-static inline void tm2_null_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
-{
- int i;
- int ct;
- int left, right, diff;
- int deltas[16];
- TM2_INIT_POINTERS();
-
- /* null chroma */
- deltas[0] = deltas[1] = deltas[2] = deltas[3] = 0;
- tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx);
-
- deltas[0] = deltas[1] = deltas[2] = deltas[3] = 0;
- tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
-
- /* null luma */
- for (i = 0; i < 16; i++)
- deltas[i] = 0;
-
- ct = ctx->D[0] + ctx->D[1] + ctx->D[2] + ctx->D[3];
-
- if (bx > 0)
- left = last[-1] - ct;
- else
- left = 0;
-
- right = last[3];
- diff = right - left;
- last[0] = left + (diff >> 2);
- last[1] = left + (diff >> 1);
- last[2] = right - (diff >> 2);
- last[3] = right;
- {
- int tp = left;
-
- ctx->D[0] = (tp + (ct >> 2)) - left;
- left += ctx->D[0];
- ctx->D[1] = (tp + (ct >> 1)) - left;
- left += ctx->D[1];
- ctx->D[2] = ((tp + ct) - (ct >> 2)) - left;
- left += ctx->D[2];
- ctx->D[3] = (tp + ct) - left;
- }
- tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
-}
-
-static inline void tm2_still_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
-{
- int i, j;
- TM2_INIT_POINTERS_2();
-
- /* update chroma */
- for (j = 0; j < 2; j++) {
- for (i = 0; i < 2; i++){
- U[i] = Uo[i];
- V[i] = Vo[i];
- }
- U += Ustride; V += Vstride;
- Uo += oUstride; Vo += oVstride;
- }
- U -= Ustride * 2;
- V -= Vstride * 2;
- TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD);
- TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2));
-
- /* update deltas */
- ctx->D[0] = Yo[3] - last[3];
- ctx->D[1] = Yo[3 + oYstride] - Yo[3];
- ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride];
- ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2];
-
- for (j = 0; j < 4; j++) {
- for (i = 0; i < 4; i++) {
- Y[i] = Yo[i];
- last[i] = Yo[i];
- }
- Y += Ystride;
- Yo += oYstride;
- }
-}
-
-static inline void tm2_update_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
-{
- int i, j;
- int d;
- TM2_INIT_POINTERS_2();
-
- /* update chroma */
- for (j = 0; j < 2; j++) {
- for (i = 0; i < 2; i++) {
- U[i] = Uo[i] + GET_TOK(ctx, TM2_UPD);
- V[i] = Vo[i] + GET_TOK(ctx, TM2_UPD);
- }
- U += Ustride;
- V += Vstride;
- Uo += oUstride;
- Vo += oVstride;
- }
- U -= Ustride * 2;
- V -= Vstride * 2;
- TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD);
- TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2));
-
- /* update deltas */
- ctx->D[0] = Yo[3] - last[3];
- ctx->D[1] = Yo[3 + oYstride] - Yo[3];
- ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride];
- ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2];
-
- for (j = 0; j < 4; j++) {
- d = last[3];
- for (i = 0; i < 4; i++) {
- Y[i] = Yo[i] + GET_TOK(ctx, TM2_UPD);
- last[i] = Y[i];
- }
- ctx->D[j] = last[3] - d;
- Y += Ystride;
- Yo += oYstride;
- }
-}
-
-static inline void tm2_motion_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
-{
- int i, j;
- int mx, my;
- TM2_INIT_POINTERS_2();
-
- mx = GET_TOK(ctx, TM2_MOT);
- my = GET_TOK(ctx, TM2_MOT);
- mx = av_clip(mx, -(bx * 4 + 4), ctx->avctx->width - bx * 4);
- my = av_clip(my, -(by * 4 + 4), ctx->avctx->height - by * 4);
-
- if (4*bx+mx<0 || 4*by+my<0 || 4*bx+mx+4 > ctx->avctx->width || 4*by+my+4 > ctx->avctx->height) {
- av_log(ctx->avctx, AV_LOG_ERROR, "MV out of picture\n");
- return;
- }
-
- Yo += my * oYstride + mx;
- Uo += (my >> 1) * oUstride + (mx >> 1);
- Vo += (my >> 1) * oVstride + (mx >> 1);
-
- /* copy chroma */
- for (j = 0; j < 2; j++) {
- for (i = 0; i < 2; i++) {
- U[i] = Uo[i];
- V[i] = Vo[i];
- }
- U += Ustride;
- V += Vstride;
- Uo += oUstride;
- Vo += oVstride;
- }
- U -= Ustride * 2;
- V -= Vstride * 2;
- TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD);
- TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2));
-
- /* copy luma */
- for (j = 0; j < 4; j++) {
- for (i = 0; i < 4; i++) {
- Y[i] = Yo[i];
- }
- Y += Ystride;
- Yo += oYstride;
- }
- /* calculate deltas */
- Y -= Ystride * 4;
- ctx->D[0] = Y[3] - last[3];
- ctx->D[1] = Y[3 + Ystride] - Y[3];
- ctx->D[2] = Y[3 + Ystride * 2] - Y[3 + Ystride];
- ctx->D[3] = Y[3 + Ystride * 3] - Y[3 + Ystride * 2];
- for (i = 0; i < 4; i++)
- last[i] = Y[i + Ystride * 3];
-}
-
-static int tm2_decode_blocks(TM2Context *ctx, AVFrame *p)
-{
- int i, j;
- int w = ctx->avctx->width, h = ctx->avctx->height, bw = w >> 2, bh = h >> 2, cw = w >> 1;
- int type;
- int keyframe = 1;
- int *Y, *U, *V;
- uint8_t *dst;
-
- for (i = 0; i < TM2_NUM_STREAMS; i++)
- ctx->tok_ptrs[i] = 0;
-
- if (ctx->tok_lens[TM2_TYPE]<bw*bh) {
- av_log(ctx->avctx,AV_LOG_ERROR,"Got %i tokens for %i blocks\n",ctx->tok_lens[TM2_TYPE],bw*bh);
- return AVERROR_INVALIDDATA;
- }
-
- memset(ctx->last, 0, 4 * bw * sizeof(int));
- memset(ctx->clast, 0, 4 * bw * sizeof(int));
-
- for (j = 0; j < bh; j++) {
- memset(ctx->D, 0, 4 * sizeof(int));
- memset(ctx->CD, 0, 4 * sizeof(int));
- for (i = 0; i < bw; i++) {
- type = GET_TOK(ctx, TM2_TYPE);
- switch(type) {
- case TM2_HI_RES:
- tm2_hi_res_block(ctx, p, i, j);
- break;
- case TM2_MED_RES:
- tm2_med_res_block(ctx, p, i, j);
- break;
- case TM2_LOW_RES:
- tm2_low_res_block(ctx, p, i, j);
- break;
- case TM2_NULL_RES:
- tm2_null_res_block(ctx, p, i, j);
- break;
- case TM2_UPDATE:
- tm2_update_block(ctx, p, i, j);
- keyframe = 0;
- break;
- case TM2_STILL:
- tm2_still_block(ctx, p, i, j);
- keyframe = 0;
- break;
- case TM2_MOTION:
- tm2_motion_block(ctx, p, i, j);
- keyframe = 0;
- break;
- default:
- av_log(ctx->avctx, AV_LOG_ERROR, "Skipping unknown block type %i\n", type);
- }
- }
- }
-
- /* copy data from our buffer to AVFrame */
- Y = (ctx->cur?ctx->Y2:ctx->Y1);
- U = (ctx->cur?ctx->U2:ctx->U1);
- V = (ctx->cur?ctx->V2:ctx->V1);
- dst = p->data[0];
- for (j = 0; j < h; j++) {
- for (i = 0; i < w; i++) {
- int y = Y[i], u = U[i >> 1], v = V[i >> 1];
- dst[3*i+0] = av_clip_uint8(y + v);
- dst[3*i+1] = av_clip_uint8(y);
- dst[3*i+2] = av_clip_uint8(y + u);
- }
-
- /* horizontal edge extension */
- Y[-4] = Y[-3] = Y[-2] = Y[-1] = Y[0];
- Y[w + 3] = Y[w + 2] = Y[w + 1] = Y[w] = Y[w - 1];
-
- /* vertical edge extension */
- if (j == 0) {
- memcpy(Y - 4 - 1 * ctx->y_stride, Y - 4, ctx->y_stride);
- memcpy(Y - 4 - 2 * ctx->y_stride, Y - 4, ctx->y_stride);
- memcpy(Y - 4 - 3 * ctx->y_stride, Y - 4, ctx->y_stride);
- memcpy(Y - 4 - 4 * ctx->y_stride, Y - 4, ctx->y_stride);
- } else if (j == h - 1) {
- memcpy(Y - 4 + 1 * ctx->y_stride, Y - 4, ctx->y_stride);
- memcpy(Y - 4 + 2 * ctx->y_stride, Y - 4, ctx->y_stride);
- memcpy(Y - 4 + 3 * ctx->y_stride, Y - 4, ctx->y_stride);
- memcpy(Y - 4 + 4 * ctx->y_stride, Y - 4, ctx->y_stride);
- }
-
- Y += ctx->y_stride;
- if (j & 1) {
- /* horizontal edge extension */
- U[-2] = U[-1] = U[0];
- V[-2] = V[-1] = V[0];
- U[cw + 1] = U[cw] = U[cw - 1];
- V[cw + 1] = V[cw] = V[cw - 1];
-
- /* vertical edge extension */
- if (j == 1) {
- memcpy(U - 2 - 1 * ctx->uv_stride, U - 2, ctx->uv_stride);
- memcpy(V - 2 - 1 * ctx->uv_stride, V - 2, ctx->uv_stride);
- memcpy(U - 2 - 2 * ctx->uv_stride, U - 2, ctx->uv_stride);
- memcpy(V - 2 - 2 * ctx->uv_stride, V - 2, ctx->uv_stride);
- } else if (j == h - 1) {
- memcpy(U - 2 + 1 * ctx->uv_stride, U - 2, ctx->uv_stride);
- memcpy(V - 2 + 1 * ctx->uv_stride, V - 2, ctx->uv_stride);
- memcpy(U - 2 + 2 * ctx->uv_stride, U - 2, ctx->uv_stride);
- memcpy(V - 2 + 2 * ctx->uv_stride, V - 2, ctx->uv_stride);
- }
-
- U += ctx->uv_stride;
- V += ctx->uv_stride;
- }
- dst += p->linesize[0];
- }
-
- return keyframe;
-}
-
-static const int tm2_stream_order[TM2_NUM_STREAMS] = {
- TM2_C_HI, TM2_C_LO, TM2_L_HI, TM2_L_LO, TM2_UPD, TM2_MOT, TM2_TYPE
-};
-
-#define TM2_HEADER_SIZE 40
-
-static int decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- TM2Context * const l = avctx->priv_data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size & ~3;
- AVFrame * const p = l->pic;
- int offset = TM2_HEADER_SIZE;
- int i, t, ret;
-
- av_fast_padded_malloc(&l->buffer, &l->buffer_size, buf_size);
- if (!l->buffer) {
- av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
- return AVERROR(ENOMEM);
- }
-
- if ((ret = ff_reget_buffer(avctx, p)) < 0)
- return ret;
-
- l->bdsp.bswap_buf((uint32_t *) l->buffer, (const uint32_t *) buf,
- buf_size >> 2);
-
- if ((ret = tm2_read_header(l, l->buffer)) < 0) {
- return ret;
- }
-
- for (i = 0; i < TM2_NUM_STREAMS; i++) {
- if (offset >= buf_size) {
- av_log(avctx, AV_LOG_ERROR, "no space for tm2_read_stream\n");
- return AVERROR_INVALIDDATA;
- }
-
- t = tm2_read_stream(l, l->buffer + offset, tm2_stream_order[i],
- buf_size - offset);
- if (t < 0) {
- int j = tm2_stream_order[i];
- memset(l->tokens[j], 0, sizeof(**l->tokens) * l->tok_lens[j]);
- return t;
- }
- offset += t;
- }
- p->key_frame = tm2_decode_blocks(l, p);
- if (p->key_frame)
- p->pict_type = AV_PICTURE_TYPE_I;
- else
- p->pict_type = AV_PICTURE_TYPE_P;
-
- l->cur = !l->cur;
- *got_frame = 1;
- ret = av_frame_ref(data, l->pic);
-
- return (ret < 0) ? ret : buf_size;
-}
-
-static av_cold int decode_init(AVCodecContext *avctx)
-{
- TM2Context * const l = avctx->priv_data;
- int i, 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");
- return AVERROR(EINVAL);
- }
-
- l->avctx = avctx;
- avctx->pix_fmt = AV_PIX_FMT_BGR24;
-
- l->pic = av_frame_alloc();
- if (!l->pic)
- return AVERROR(ENOMEM);
-
- 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;
- }
-
- 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_stride = w;
- 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);
- 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;
-
- return 0;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx)
-{
- TM2Context * const l = avctx->priv_data;
- int i;
-
- av_free(l->last);
- av_free(l->clast);
- 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->buffer);
- l->buffer_size = 0;
-
- av_frame_free(&l->pic);
-
- return 0;
-}
-
-AVCodec ff_truemotion2_decoder = {
- .name = "truemotion2",
- .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_TRUEMOTION2,
- .priv_data_size = sizeof(TM2Context),
- .init = decode_init,
- .close = decode_end,
- .decode = decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/vdpau_hevc.c b/ffmpeg-2-8-11/libavcodec/vdpau_hevc.c
deleted file mode 100644
index 3c1dc5f..0000000
--- a/ffmpeg-2-8-11/libavcodec/vdpau_hevc.c
+++ /dev/null
@@ -1,437 +0,0 @@
-/*
- * MPEG-H Part 2 / HEVC / H.265 HW decode acceleration through VDPAU
- *
- * Copyright (c) 2013 Philip Langdale
- *
- * 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 <vdpau/vdpau.h>
-
-#include "avcodec.h"
-#include "internal.h"
-#include "hevc.h"
-#include "vdpau.h"
-#include "vdpau_internal.h"
-
-static int vdpau_hevc_start_frame(AVCodecContext *avctx,
- const uint8_t *buffer, uint32_t size)
-{
- HEVCContext *h = avctx->priv_data;
- HEVCFrame *pic = h->ref;
- struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
-
- VdpPictureInfoHEVC *info = &pic_ctx->info.hevc;
-
- const HEVCSPS *sps = h->ps.sps;
- const HEVCPPS *pps = h->ps.pps;
- const SliceHeader *sh = &h->sh;
- const ScalingList *sl = pps->scaling_list_data_present_flag ?
- &pps->scaling_list : &sps->scaling_list;
-
- /* init VdpPictureInfoHEVC */
-
- /* SPS */
- info->chroma_format_idc = sps->chroma_format_idc;
- info->separate_colour_plane_flag = sps->separate_colour_plane_flag;
- info->pic_width_in_luma_samples = sps->width;
- info->pic_height_in_luma_samples = sps->height;
- info->bit_depth_luma_minus8 = sps->bit_depth - 8;
- info->bit_depth_chroma_minus8 = sps->bit_depth - 8;
- info->log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4;
- /** Provides the value corresponding to the nuh_temporal_id of the frame
- to be decoded. */
- info->sps_max_dec_pic_buffering_minus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering - 1;
- info->log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3;
- info->log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_coding_block_size;
- info->log2_min_transform_block_size_minus2 = sps->log2_min_tb_size - 2;
- info->log2_diff_max_min_transform_block_size = sps->log2_max_trafo_size - sps->log2_min_tb_size;
- info->max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter;
- info->max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra;
- info->scaling_list_enabled_flag = sps->scaling_list_enable_flag;
- /** Scaling lists, in diagonal order, to be used for this frame. */
- for (size_t i = 0; i < 6; i++) {
- for (size_t j = 0; j < 16; j++) {
- /** Scaling List for 4x4 quantization matrix,
- indexed as ScalingList4x4[matrixId][i]. */
- uint8_t pos = 4 * ff_hevc_diag_scan4x4_y[j] + ff_hevc_diag_scan4x4_x[j];
- info->ScalingList4x4[i][j] = sl->sl[0][i][pos];
- }
- for (size_t j = 0; j < 64; j++) {
- uint8_t pos = 8 * ff_hevc_diag_scan8x8_y[j] + ff_hevc_diag_scan8x8_x[j];
- /** Scaling List for 8x8 quantization matrix,
- indexed as ScalingList8x8[matrixId][i]. */
- info->ScalingList8x8[i][j] = sl->sl[1][i][pos];
- /** Scaling List for 16x16 quantization matrix,
- indexed as ScalingList16x16[matrixId][i]. */
- info->ScalingList16x16[i][j] = sl->sl[2][i][pos];
- if (i < 2) {
- /** Scaling List for 32x32 quantization matrix,
- indexed as ScalingList32x32[matrixId][i]. */
- info->ScalingList32x32[i][j] = sl->sl[3][i * 3][pos];
- }
- }
- /** Scaling List DC Coefficients for 16x16,
- indexed as ScalingListDCCoeff16x16[matrixId]. */
- info->ScalingListDCCoeff16x16[i] = sl->sl_dc[0][i];
- if (i < 2) {
- /** Scaling List DC Coefficients for 32x32,
- indexed as ScalingListDCCoeff32x32[matrixId]. */
- info->ScalingListDCCoeff32x32[i] = sl->sl_dc[1][i * 3];
- }
- }
- info->amp_enabled_flag = sps->amp_enabled_flag;
- info->sample_adaptive_offset_enabled_flag = sps->sao_enabled;
- info->pcm_enabled_flag = sps->pcm_enabled_flag;
- if (info->pcm_enabled_flag) {
- /** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
- info->pcm_sample_bit_depth_luma_minus1 = sps->pcm.bit_depth - 1;
- /** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
- info->pcm_sample_bit_depth_chroma_minus1 = sps->pcm.bit_depth_chroma - 1;
- /** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
- info->log2_min_pcm_luma_coding_block_size_minus3 = sps->pcm.log2_min_pcm_cb_size - 3;
- /** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
- info->log2_diff_max_min_pcm_luma_coding_block_size = sps->pcm.log2_max_pcm_cb_size - sps->pcm.log2_min_pcm_cb_size;
- /** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
- info->pcm_loop_filter_disabled_flag = sps->pcm.loop_filter_disable_flag;
- }
- /** Per spec, when zero, assume short_term_ref_pic_set_sps_flag
- is also zero. */
- info->num_short_term_ref_pic_sets = sps->nb_st_rps;
- info->long_term_ref_pics_present_flag = sps->long_term_ref_pics_present_flag;
- /** Only needed if long_term_ref_pics_present_flag is set. Ignored
- otherwise. */
- info->num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps;
- info->sps_temporal_mvp_enabled_flag = sps->sps_temporal_mvp_enabled_flag;
- info->strong_intra_smoothing_enabled_flag = sps->sps_strong_intra_smoothing_enable_flag;
- /** @} */
-
- /** \name HEVC Picture Parameter Set
- *
- * Copies of the HEVC Picture Parameter Set bitstream fields.
- * @{ */
- info->dependent_slice_segments_enabled_flag = pps->dependent_slice_segments_enabled_flag;
- info->output_flag_present_flag = pps->output_flag_present_flag;
- info->num_extra_slice_header_bits = pps->num_extra_slice_header_bits;
- info->sign_data_hiding_enabled_flag = pps->sign_data_hiding_flag;
- info->cabac_init_present_flag = pps->cabac_init_present_flag;
- info->num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active - 1;
- info->num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active - 1;
- info->init_qp_minus26 = pps->pic_init_qp_minus26;
- info->constrained_intra_pred_flag = pps->constrained_intra_pred_flag;
- info->transform_skip_enabled_flag = pps->transform_skip_enabled_flag;
- info->cu_qp_delta_enabled_flag = pps->cu_qp_delta_enabled_flag;
- /** Only needed if cu_qp_delta_enabled_flag is set. Ignored otherwise. */
- info->diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth;
- info->pps_cb_qp_offset = pps->cb_qp_offset;
- info->pps_cr_qp_offset = pps->cr_qp_offset;
- info->pps_slice_chroma_qp_offsets_present_flag = pps->pic_slice_level_chroma_qp_offsets_present_flag;
- info->weighted_pred_flag = pps->weighted_pred_flag;
- info->weighted_bipred_flag = pps->weighted_bipred_flag;
- info->transquant_bypass_enabled_flag = pps->transquant_bypass_enable_flag;
- info->tiles_enabled_flag = pps->tiles_enabled_flag;
- info->entropy_coding_sync_enabled_flag = pps->entropy_coding_sync_enabled_flag;
- if (info->tiles_enabled_flag) {
- /** Only valid if tiles_enabled_flag is set. Ignored otherwise. */
- info->num_tile_columns_minus1 = pps->num_tile_columns - 1;
- /** Only valid if tiles_enabled_flag is set. Ignored otherwise. */
- info->num_tile_rows_minus1 = pps->num_tile_rows - 1;
- /** Only valid if tiles_enabled_flag is set. Ignored otherwise. */
- info->uniform_spacing_flag = pps->uniform_spacing_flag;
- /** Only need to set 0..num_tile_columns_minus1. The struct
- definition reserves up to the maximum of 20. Invalid values are
- ignored. */
- for (ssize_t i = 0; i < pps->num_tile_columns; i++) {
- info->column_width_minus1[i] = pps->column_width[i] - 1;
- }
- /** Only need to set 0..num_tile_rows_minus1. The struct
- definition reserves up to the maximum of 22. Invalid values are
- ignored.*/
- for (ssize_t i = 0; i < pps->num_tile_rows; i++) {
- info->row_height_minus1[i] = pps->row_height[i] - 1;
- }
- /** Only needed if tiles_enabled_flag is set. Invalid values are
- ignored. */
- info->loop_filter_across_tiles_enabled_flag = pps->loop_filter_across_tiles_enabled_flag;
- }
- info->pps_loop_filter_across_slices_enabled_flag = pps->seq_loop_filter_across_slices_enabled_flag;
- info->deblocking_filter_control_present_flag = pps->deblocking_filter_control_present_flag;
- /** Only valid if deblocking_filter_control_present_flag is set. Ignored
- otherwise. */
- info->deblocking_filter_override_enabled_flag = pps->deblocking_filter_override_enabled_flag;
- /** Only valid if deblocking_filter_control_present_flag is set. Ignored
- otherwise. */
- info->pps_deblocking_filter_disabled_flag = pps->disable_dbf;
- /** Only valid if deblocking_filter_control_present_flag is set and
- pps_deblocking_filter_disabled_flag is not set. Ignored otherwise.*/
- info->pps_beta_offset_div2 = pps->beta_offset / 2;
- /** Only valid if deblocking_filter_control_present_flag is set and
- pps_deblocking_filter_disabled_flag is not set. Ignored otherwise. */
- info->pps_tc_offset_div2 = pps->tc_offset / 2;
- info->lists_modification_present_flag = pps->lists_modification_present_flag;
- info->log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level - 2;
- info->slice_segment_header_extension_present_flag = pps->slice_header_extension_present_flag;
-
- /** \name HEVC Slice Segment Header
- *
- * Copies of the HEVC Slice Segment Header bitstream fields and calculated
- * values detailed in the specification.
- * @{ */
- /** Set to 1 if nal_unit_type is equal to IDR_W_RADL or IDR_N_LP.
- Set to zero otherwise. */
- info->IDRPicFlag = IS_IDR(h);
- /** Set to 1 if nal_unit_type in the range of BLA_W_LP to
- RSV_IRAP_VCL23, inclusive. Set to zero otherwise.*/
- info->RAPPicFlag = IS_IRAP(h);
- /** See section 7.4.7.1 of the specification. */
- info->CurrRpsIdx = sps->nb_st_rps;
- if (sh->short_term_ref_pic_set_sps_flag == 1) {
- for (size_t i = 0; i < sps->nb_st_rps; i++) {
- if (sh->short_term_rps == &sps->st_rps[i]) {
- info->CurrRpsIdx = i;
- break;
- }
- }
- }
- /** See section 7.4.7.2 of the specification. */
- info->NumPocTotalCurr = ff_hevc_frame_nb_refs(h);
- if (sh->short_term_ref_pic_set_sps_flag == 0 && sh->short_term_rps) {
- /** Corresponds to specification field, NumDeltaPocs[RefRpsIdx].
- Only applicable when short_term_ref_pic_set_sps_flag == 0.
- Implementations will ignore this value in other cases. See 7.4.8. */
- info->NumDeltaPocsOfRefRpsIdx = sh->short_term_rps->rps_idx_num_delta_pocs;
- }
- /** Section 7.6.3.1 of the H.265/HEVC Specification defines the syntax of
- the slice_segment_header. This header contains information that
- some VDPAU implementations may choose to skip. The VDPAU API
- requires client applications to track the number of bits used in the
- slice header for structures associated with short term and long term
- reference pictures. First, VDPAU requires the number of bits used by
- the short_term_ref_pic_set array in the slice_segment_header. */
- info->NumShortTermPictureSliceHeaderBits = sh->short_term_ref_pic_set_size;
- /** Second, VDPAU requires the number of bits used for long term reference
- pictures in the slice_segment_header. This is equal to the number
- of bits used for the contents of the block beginning with
- "if(long_term_ref_pics_present_flag)". */
- info->NumLongTermPictureSliceHeaderBits = sh->long_term_ref_pic_set_size;
- /** @} */
-
- /** Slice Decoding Process - Picture Order Count */
- /** The value of PicOrderCntVal of the picture in the access unit
- containing the SEI message. The picture being decoded. */
- info->CurrPicOrderCntVal = h->poc;
-
- /** Slice Decoding Process - Reference Picture Sets */
- for (size_t i = 0; i < 16; i++) {
- info->RefPics[i] = VDP_INVALID_HANDLE;
- info->PicOrderCntVal[i] = 0;
- info->IsLongTerm[i] = 0;
- }
- for (size_t i = 0, j = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) {
- const HEVCFrame *frame = &h->DPB[i];
- if (frame != h->ref && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF |
- HEVC_FRAME_FLAG_SHORT_REF))) {
- if (j > 16) {
- av_log(avctx, AV_LOG_WARNING,
- "VDPAU only supports up to 16 references in the DPB. "
- "This frame may not be decoded correctly.\n");
- break;
- }
- /** Array of video reference surfaces.
- Set any unused positions to VDP_INVALID_HANDLE. */
- info->RefPics[j] = ff_vdpau_get_surface_id(frame->frame);
- /** Array of picture order counts. These correspond to positions
- in the RefPics array. */
- info->PicOrderCntVal[j] = frame->poc;
- /** Array used to specify whether a particular RefPic is
- a long term reference. A value of "1" indicates a long-term
- reference. */
- // XXX: Setting this caused glitches in the nvidia implementation
- // Always setting it to zero, produces correct results
- //info->IsLongTerm[j] = frame->flags & HEVC_FRAME_FLAG_LONG_REF;
- info->IsLongTerm[j] = 0;
- j++;
- }
- }
- /** Copy of specification field, see Section 8.3.2 of the
- H.265/HEVC Specification. */
- info->NumPocStCurrBefore = h->rps[ST_CURR_BEF].nb_refs;
- if (info->NumPocStCurrBefore > 8) {
- av_log(avctx, AV_LOG_WARNING,
- "VDPAU only supports up to 8 references in StCurrBefore. "
- "This frame may not be decoded correctly.\n");
- info->NumPocStCurrBefore = 8;
- }
- /** Copy of specification field, see Section 8.3.2 of the
- H.265/HEVC Specification. */
- info->NumPocStCurrAfter = h->rps[ST_CURR_AFT].nb_refs;
- if (info->NumPocStCurrAfter > 8) {
- av_log(avctx, AV_LOG_WARNING,
- "VDPAU only supports up to 8 references in StCurrAfter. "
- "This frame may not be decoded correctly.\n");
- info->NumPocStCurrAfter = 8;
- }
- /** Copy of specification field, see Section 8.3.2 of the
- H.265/HEVC Specification. */
- info->NumPocLtCurr = h->rps[LT_CURR].nb_refs;
- if (info->NumPocLtCurr > 8) {
- av_log(avctx, AV_LOG_WARNING,
- "VDPAU only supports up to 8 references in LtCurr. "
- "This frame may not be decoded correctly.\n");
- info->NumPocLtCurr = 8;
- }
- /** Reference Picture Set list, one of the short-term RPS. These
- correspond to positions in the RefPics array. */
- for (ssize_t i = 0, j = 0; i < h->rps[ST_CURR_BEF].nb_refs; i++) {
- HEVCFrame *frame = h->rps[ST_CURR_BEF].ref[i];
- if (frame) {
- uint8_t found = 0;
- uintptr_t id = ff_vdpau_get_surface_id(frame->frame);
- for (size_t k = 0; k < 16; k++) {
- if (id == info->RefPics[k]) {
- info->RefPicSetStCurrBefore[j] = k;
- j++;
- found = 1;
- break;
- }
- }
- if (!found) {
- av_log(avctx, AV_LOG_WARNING, "missing surface: %p\n",
- (void *)id);
- }
- } else {
- av_log(avctx, AV_LOG_WARNING, "missing STR Before frame: %zd\n", i);
- }
- }
- /** Reference Picture Set list, one of the short-term RPS. These
- correspond to positions in the RefPics array. */
- for (ssize_t i = 0, j = 0; i < h->rps[ST_CURR_AFT].nb_refs; i++) {
- HEVCFrame *frame = h->rps[ST_CURR_AFT].ref[i];
- if (frame) {
- uint8_t found = 0;
- uintptr_t id = ff_vdpau_get_surface_id(frame->frame);
- for (size_t k = 0; k < 16; k++) {
- if (id == info->RefPics[k]) {
- info->RefPicSetStCurrAfter[j] = k;
- j++;
- found = 1;
- break;
- }
- }
- if (!found) {
- av_log(avctx, AV_LOG_WARNING, "missing surface: %p\n",
- (void *)id);
- }
- } else {
- av_log(avctx, AV_LOG_WARNING, "missing STR After frame: %zd\n", i);
- }
- }
- /** Reference Picture Set list, one of the long-term RPS. These
- correspond to positions in the RefPics array. */
- for (ssize_t i = 0, j = 0; i < h->rps[LT_CURR].nb_refs; i++) {
- HEVCFrame *frame = h->rps[LT_CURR].ref[i];
- if (frame) {
- uint8_t found = 0;
- uintptr_t id = ff_vdpau_get_surface_id(frame->frame);
- for (size_t k = 0; k < 16; k++) {
- if (id == info->RefPics[k]) {
- info->RefPicSetLtCurr[j] = k;
- j++;
- found = 1;
- break;
- }
- }
- if (!found) {
- av_log(avctx, AV_LOG_WARNING, "missing surface: %p\n",
- (void *)id);
- }
- } else {
- av_log(avctx, AV_LOG_WARNING, "missing LTR frame: %zd\n", i);
- }
- }
-
- return ff_vdpau_common_start_frame(pic_ctx, buffer, size);
-}
-
-static const uint8_t start_code_prefix[3] = { 0x00, 0x00, 0x01 };
-
-static int vdpau_hevc_decode_slice(AVCodecContext *avctx,
- const uint8_t *buffer, uint32_t size)
-{
- HEVCContext *h = avctx->priv_data;
- struct vdpau_picture_context *pic_ctx = h->ref->hwaccel_picture_private;
- int val;
-
- val = ff_vdpau_add_buffer(pic_ctx, start_code_prefix, 3);
- if (val)
- return val;
-
- val = ff_vdpau_add_buffer(pic_ctx, buffer, size);
- if (val)
- return val;
-
- return 0;
-}
-
-static int vdpau_hevc_end_frame(AVCodecContext *avctx)
-{
- HEVCContext *h = avctx->priv_data;
- struct vdpau_picture_context *pic_ctx = h->ref->hwaccel_picture_private;
- int val;
-
- val = ff_vdpau_common_end_frame(avctx, h->ref->frame, pic_ctx);
- if (val < 0)
- return val;
-
- return 0;
-}
-
-static int vdpau_hevc_init(AVCodecContext *avctx)
-{
- VdpDecoderProfile profile;
- uint32_t level = avctx->level;
-
- switch (avctx->profile) {
- case FF_PROFILE_HEVC_MAIN:
- profile = VDP_DECODER_PROFILE_HEVC_MAIN;
- break;
- case FF_PROFILE_HEVC_MAIN_10:
- profile = VDP_DECODER_PROFILE_HEVC_MAIN_10;
- break;
- case FF_PROFILE_HEVC_MAIN_STILL_PICTURE:
- profile = VDP_DECODER_PROFILE_HEVC_MAIN_STILL;
- break;
- default:
- return AVERROR(ENOTSUP);
- }
-
- return ff_vdpau_common_init(avctx, profile, level);
-}
-
-AVHWAccel ff_hevc_vdpau_hwaccel = {
- .name = "hevc_vdpau",
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_HEVC,
- .pix_fmt = AV_PIX_FMT_VDPAU,
- .start_frame = vdpau_hevc_start_frame,
- .end_frame = vdpau_hevc_end_frame,
- .decode_slice = vdpau_hevc_decode_slice,
- .frame_priv_data_size = sizeof(struct vdpau_picture_context),
- .init = vdpau_hevc_init,
- .uninit = ff_vdpau_common_uninit,
- .priv_data_size = sizeof(VDPAUContext),
-};
diff --git a/ffmpeg-2-8-11/libavcodec/vmnc.c b/ffmpeg-2-8-11/libavcodec/vmnc.c
deleted file mode 100644
index 49abb77..0000000
--- a/ffmpeg-2-8-11/libavcodec/vmnc.c
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * VMware Screen Codec (VMnc) decoder
- * Copyright (c) 2006 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
- */
-
-/**
- * @file
- * VMware Screen Codec (VMnc) decoder
- * As Alex Beregszaszi discovered, this is effectively RFB data dump
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "libavutil/common.h"
-#include "libavutil/intreadwrite.h"
-#include "avcodec.h"
-#include "internal.h"
-#include "bytestream.h"
-
-enum EncTypes {
- MAGIC_WMVd = 0x574D5664,
- MAGIC_WMVe,
- MAGIC_WMVf,
- MAGIC_WMVg,
- MAGIC_WMVh,
- MAGIC_WMVi,
- MAGIC_WMVj
-};
-
-enum HexTile_Flags {
- HT_RAW = 1, // tile is raw
- HT_BKG = 2, // background color is present
- HT_FG = 4, // foreground color is present
- HT_SUB = 8, // subrects are present
- HT_CLR = 16 // each subrect has own color
-};
-
-/*
- * Decoder context
- */
-typedef struct VmncContext {
- AVCodecContext *avctx;
- AVFrame *pic;
-
- int bpp;
- int bpp2;
- int bigendian;
- uint8_t pal[768];
- int width, height;
- GetByteContext gb;
-
- /* cursor data */
- int cur_w, cur_h;
- int cur_x, cur_y;
- int cur_hx, cur_hy;
- uint8_t *curbits, *curmask;
- uint8_t *screendta;
-} VmncContext;
-
-/* read pixel value from stream */
-static av_always_inline int vmnc_get_pixel(GetByteContext *gb, int bpp, int be)
-{
- switch (bpp * 2 + be) {
- case 2:
- case 3:
- return bytestream2_get_byte(gb);
- case 4:
- return bytestream2_get_le16(gb);
- case 5:
- return bytestream2_get_be16(gb);
- case 8:
- return bytestream2_get_le32(gb);
- case 9:
- return bytestream2_get_be32(gb);
- default: return 0;
- }
-}
-
-static void load_cursor(VmncContext *c)
-{
- int i, j, p;
- const int bpp = c->bpp2;
- uint8_t *dst8 = c->curbits;
- uint16_t *dst16 = (uint16_t *)c->curbits;
- uint32_t *dst32 = (uint32_t *)c->curbits;
-
- for (j = 0; j < c->cur_h; j++) {
- for (i = 0; i < c->cur_w; i++) {
- p = vmnc_get_pixel(&c->gb, bpp, c->bigendian);
- if (bpp == 1)
- *dst8++ = p;
- if (bpp == 2)
- *dst16++ = p;
- if (bpp == 4)
- *dst32++ = p;
- }
- }
- dst8 = c->curmask;
- dst16 = (uint16_t*)c->curmask;
- dst32 = (uint32_t*)c->curmask;
- for (j = 0; j < c->cur_h; j++) {
- for (i = 0; i < c->cur_w; i++) {
- p = vmnc_get_pixel(&c->gb, bpp, c->bigendian);
- if (bpp == 1)
- *dst8++ = p;
- if (bpp == 2)
- *dst16++ = p;
- if (bpp == 4)
- *dst32++ = p;
- }
- }
-}
-
-static void put_cursor(uint8_t *dst, int stride, VmncContext *c, int dx, int dy)
-{
- int i, j;
- int w, h, x, y;
- w = c->cur_w;
- if (c->width < c->cur_x + c->cur_w)
- w = c->width - c->cur_x;
- h = c->cur_h;
- if (c->height < c->cur_y + c->cur_h)
- h = c->height - c->cur_y;
- x = c->cur_x;
- y = c->cur_y;
- if (x < 0) {
- w += x;
- x = 0;
- }
- if (y < 0) {
- h += y;
- y = 0;
- }
-
- if ((w < 1) || (h < 1))
- return;
- dst += x * c->bpp2 + y * stride;
-
- if (c->bpp2 == 1) {
- uint8_t *cd = c->curbits, *msk = c->curmask;
- for (j = 0; j < h; j++) {
- for (i = 0; i < w; i++)
- dst[i] = (dst[i] & cd[i]) ^ msk[i];
- msk += c->cur_w;
- cd += c->cur_w;
- dst += stride;
- }
- } else if (c->bpp2 == 2) {
- uint16_t *cd = (uint16_t*)c->curbits, *msk = (uint16_t*)c->curmask;
- uint16_t *dst2;
- for (j = 0; j < h; j++) {
- dst2 = (uint16_t*)dst;
- for (i = 0; i < w; i++)
- dst2[i] = (dst2[i] & cd[i]) ^ msk[i];
- msk += c->cur_w;
- cd += c->cur_w;
- dst += stride;
- }
- } else if (c->bpp2 == 4) {
- uint32_t *cd = (uint32_t*)c->curbits, *msk = (uint32_t*)c->curmask;
- uint32_t *dst2;
- for (j = 0; j < h; j++) {
- dst2 = (uint32_t*)dst;
- for (i = 0; i < w; i++)
- dst2[i] = (dst2[i] & cd[i]) ^ msk[i];
- msk += c->cur_w;
- cd += c->cur_w;
- dst += stride;
- }
- }
-}
-
-/* fill rectangle with given color */
-static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy,
- int w, int h, int color,
- int bpp, int stride)
-{
- int i, j;
- dst += dx * bpp + dy * stride;
- if (bpp == 1) {
- for (j = 0; j < h; j++) {
- memset(dst, color, w);
- dst += stride;
- }
- } else if (bpp == 2) {
- uint16_t *dst2;
- for (j = 0; j < h; j++) {
- dst2 = (uint16_t*)dst;
- for (i = 0; i < w; i++)
- *dst2++ = color;
- dst += stride;
- }
- } else if (bpp == 4) {
- uint32_t *dst2;
- for (j = 0; j < h; j++) {
- dst2 = (uint32_t*)dst;
- for (i = 0; i < w; i++)
- dst2[i] = color;
- dst += stride;
- }
- }
-}
-
-static av_always_inline void paint_raw(uint8_t *dst, int w, int h,
- GetByteContext *gb, int bpp,
- int be, int stride)
-{
- int i, j, p;
- for (j = 0; j < h; j++) {
- for (i = 0; i < w; i++) {
- p = vmnc_get_pixel(gb, bpp, be);
- switch (bpp) {
- case 1:
- dst[i] = p;
- break;
- case 2:
- ((uint16_t*)dst)[i] = p;
- break;
- case 4:
- ((uint32_t*)dst)[i] = p;
- break;
- }
- }
- dst += stride;
- }
-}
-
-static int decode_hextile(VmncContext *c, uint8_t* dst, GetByteContext *gb,
- int w, int h, int stride)
-{
- int i, j, k;
- int bg = 0, fg = 0, rects, color, flags, xy, wh;
- const int bpp = c->bpp2;
- uint8_t *dst2;
- int bw = 16, bh = 16;
-
- for (j = 0; j < h; j += 16) {
- dst2 = dst;
- bw = 16;
- if (j + 16 > h)
- bh = h - j;
- for (i = 0; i < w; i += 16, dst2 += 16 * bpp) {
- if (bytestream2_get_bytes_left(gb) <= 0) {
- av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
- return AVERROR_INVALIDDATA;
- }
- if (i + 16 > w)
- bw = w - i;
- flags = bytestream2_get_byte(gb);
- if (flags & HT_RAW) {
- if (bytestream2_get_bytes_left(gb) < bw * bh * bpp) {
- av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
- return AVERROR_INVALIDDATA;
- }
- paint_raw(dst2, bw, bh, gb, bpp, c->bigendian, stride);
- } else {
- if (flags & HT_BKG)
- bg = vmnc_get_pixel(gb, bpp, c->bigendian);
- if (flags & HT_FG)
- fg = vmnc_get_pixel(gb, bpp, c->bigendian);
- rects = 0;
- if (flags & HT_SUB)
- rects = bytestream2_get_byte(gb);
- color = !!(flags & HT_CLR);
-
- paint_rect(dst2, 0, 0, bw, bh, bg, bpp, stride);
-
- if (bytestream2_get_bytes_left(gb) < rects * (color * bpp + 2)) {
- av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
- return AVERROR_INVALIDDATA;
- }
- for (k = 0; k < rects; k++) {
- if (color)
- fg = vmnc_get_pixel(gb, bpp, c->bigendian);
- xy = bytestream2_get_byte(gb);
- wh = bytestream2_get_byte(gb);
- if ( (xy >> 4) + (wh >> 4) + 1 > w - i
- || (xy & 0xF) + (wh & 0xF)+1 > h - j) {
- av_log(c->avctx, AV_LOG_ERROR, "Rectangle outside picture\n");
- return AVERROR_INVALIDDATA;
- }
- paint_rect(dst2, xy >> 4, xy & 0xF,
- (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride);
- }
- }
- }
- dst += stride * 16;
- }
- return 0;
-}
-
-static void reset_buffers(VmncContext *c)
-{
- av_freep(&c->curbits);
- av_freep(&c->curmask);
- av_freep(&c->screendta);
- c->cur_w = c->cur_h = 0;
- c->cur_hx = c->cur_hy = 0;
-
-}
-
-static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- VmncContext * const c = avctx->priv_data;
- GetByteContext *gb = &c->gb;
- uint8_t *outptr;
- int dx, dy, w, h, depth, enc, chunks, res, size_left, ret;
-
- if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)
- return ret;
-
- bytestream2_init(gb, buf, buf_size);
-
- c->pic->key_frame = 0;
- c->pic->pict_type = AV_PICTURE_TYPE_P;
-
- // restore screen after cursor
- if (c->screendta) {
- int i;
- w = c->cur_w;
- if (c->width < c->cur_x + w)
- w = c->width - c->cur_x;
- h = c->cur_h;
- if (c->height < c->cur_y + h)
- h = c->height - c->cur_y;
- dx = c->cur_x;
- if (dx < 0) {
- w += dx;
- dx = 0;
- }
- dy = c->cur_y;
- if (dy < 0) {
- h += dy;
- dy = 0;
- }
- if ((w > 0) && (h > 0)) {
- outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
- for (i = 0; i < h; i++) {
- memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2,
- w * c->bpp2);
- outptr += c->pic->linesize[0];
- }
- }
- }
- bytestream2_skip(gb, 2);
- chunks = bytestream2_get_be16(gb);
- while (chunks--) {
- if (bytestream2_get_bytes_left(gb) < 12) {
- av_log(avctx, AV_LOG_ERROR, "Premature end of data!\n");
- return -1;
- }
- dx = bytestream2_get_be16(gb);
- dy = bytestream2_get_be16(gb);
- w = bytestream2_get_be16(gb);
- h = bytestream2_get_be16(gb);
- enc = bytestream2_get_be32(gb);
- outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
- size_left = bytestream2_get_bytes_left(gb);
- switch (enc) {
- case MAGIC_WMVd: // cursor
- if (w*(int64_t)h*c->bpp2 > INT_MAX/2 - 2) {
- av_log(avctx, AV_LOG_ERROR, "dimensions too large\n");
- return AVERROR_INVALIDDATA;
- }
- if (size_left < 2 + w * h * c->bpp2 * 2) {
- av_log(avctx, AV_LOG_ERROR,
- "Premature end of data! (need %i got %i)\n",
- 2 + w * h * c->bpp2 * 2, size_left);
- return AVERROR_INVALIDDATA;
- }
- bytestream2_skip(gb, 2);
- c->cur_w = w;
- c->cur_h = h;
- c->cur_hx = dx;
- c->cur_hy = dy;
- if ((c->cur_hx > c->cur_w) || (c->cur_hy > c->cur_h)) {
- av_log(avctx, AV_LOG_ERROR,
- "Cursor hot spot is not in image: "
- "%ix%i of %ix%i cursor size\n",
- c->cur_hx, c->cur_hy, c->cur_w, c->cur_h);
- c->cur_hx = c->cur_hy = 0;
- }
- if (c->cur_w * c->cur_h >= INT_MAX / c->bpp2) {
- reset_buffers(c);
- return AVERROR(EINVAL);
- } else {
- int screen_size = c->cur_w * c->cur_h * c->bpp2;
- if ((ret = av_reallocp(&c->curbits, screen_size)) < 0 ||
- (ret = av_reallocp(&c->curmask, screen_size)) < 0 ||
- (ret = av_reallocp(&c->screendta, screen_size)) < 0) {
- reset_buffers(c);
- return ret;
- }
- }
- load_cursor(c);
- break;
- case MAGIC_WMVe: // unknown
- bytestream2_skip(gb, 2);
- break;
- case MAGIC_WMVf: // update cursor position
- c->cur_x = dx - c->cur_hx;
- c->cur_y = dy - c->cur_hy;
- break;
- case MAGIC_WMVg: // unknown
- bytestream2_skip(gb, 10);
- break;
- case MAGIC_WMVh: // unknown
- bytestream2_skip(gb, 4);
- break;
- case MAGIC_WMVi: // ServerInitialization struct
- c->pic->key_frame = 1;
- c->pic->pict_type = AV_PICTURE_TYPE_I;
- depth = bytestream2_get_byte(gb);
- if (depth != c->bpp) {
- av_log(avctx, AV_LOG_INFO,
- "Depth mismatch. Container %i bpp, "
- "Frame data: %i bpp\n",
- c->bpp, depth);
- }
- bytestream2_skip(gb, 1);
- c->bigendian = bytestream2_get_byte(gb);
- if (c->bigendian & (~1)) {
- av_log(avctx, AV_LOG_INFO,
- "Invalid header: bigendian flag = %i\n", c->bigendian);
- return AVERROR_INVALIDDATA;
- }
- //skip the rest of pixel format data
- bytestream2_skip(gb, 13);
- break;
- case MAGIC_WMVj: // unknown
- bytestream2_skip(gb, 2);
- break;
- case 0x00000000: // raw rectangle data
- if ((dx + w > c->width) || (dy + h > c->height)) {
- av_log(avctx, AV_LOG_ERROR,
- "Incorrect frame size: %ix%i+%ix%i of %ix%i\n",
- w, h, dx, dy, c->width, c->height);
- return AVERROR_INVALIDDATA;
- }
- if (size_left < w * h * c->bpp2) {
- av_log(avctx, AV_LOG_ERROR,
- "Premature end of data! (need %i got %i)\n",
- w * h * c->bpp2, size_left);
- return AVERROR_INVALIDDATA;
- }
- paint_raw(outptr, w, h, gb, c->bpp2, c->bigendian,
- c->pic->linesize[0]);
- break;
- case 0x00000005: // HexTile encoded rectangle
- if ((dx + w > c->width) || (dy + h > c->height)) {
- av_log(avctx, AV_LOG_ERROR,
- "Incorrect frame size: %ix%i+%ix%i of %ix%i\n",
- w, h, dx, dy, c->width, c->height);
- return AVERROR_INVALIDDATA;
- }
- res = decode_hextile(c, outptr, gb, w, h, c->pic->linesize[0]);
- if (res < 0)
- return res;
- break;
- default:
- av_log(avctx, AV_LOG_ERROR, "Unsupported block type 0x%08X\n", enc);
- chunks = 0; // leave chunks decoding loop
- }
- }
- if (c->screendta) {
- int i;
- // save screen data before painting cursor
- w = c->cur_w;
- if (c->width < c->cur_x + w)
- w = c->width - c->cur_x;
- h = c->cur_h;
- if (c->height < c->cur_y + h)
- h = c->height - c->cur_y;
- dx = c->cur_x;
- if (dx < 0) {
- w += dx;
- dx = 0;
- }
- dy = c->cur_y;
- if (dy < 0) {
- h += dy;
- dy = 0;
- }
- if ((w > 0) && (h > 0)) {
- outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
- for (i = 0; i < h; i++) {
- memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr,
- w * c->bpp2);
- outptr += c->pic->linesize[0];
- }
- outptr = c->pic->data[0];
- put_cursor(outptr, c->pic->linesize[0], c, c->cur_x, c->cur_y);
- }
- }
- *got_frame = 1;
- if ((ret = av_frame_ref(data, c->pic)) < 0)
- return ret;
-
- /* always report that the buffer was completely consumed */
- return buf_size;
-}
-
-static av_cold int decode_init(AVCodecContext *avctx)
-{
- VmncContext * const c = avctx->priv_data;
-
- c->avctx = avctx;
- c->width = avctx->width;
- c->height = avctx->height;
- c->bpp = avctx->bits_per_coded_sample;
-
- switch (c->bpp) {
- case 8:
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
- break;
- case 16:
- avctx->pix_fmt = AV_PIX_FMT_RGB555;
- break;
- case 24:
- /* 24 bits is not technically supported, but some clients might
- * mistakenly set it, so let's assume they actually meant 32 bits */
- c->bpp = 32;
- case 32:
- avctx->pix_fmt = AV_PIX_FMT_0RGB32;
- break;
- default:
- av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", c->bpp);
- return AVERROR_INVALIDDATA;
- }
- c->bpp2 = c->bpp / 8;
-
- c->pic = av_frame_alloc();
- if (!c->pic)
- return AVERROR(ENOMEM);
-
- return 0;
-}
-
-static av_cold int decode_end(AVCodecContext *avctx)
-{
- VmncContext * const c = avctx->priv_data;
-
- av_frame_free(&c->pic);
-
- av_freep(&c->curbits);
- av_freep(&c->curmask);
- av_freep(&c->screendta);
- return 0;
-}
-
-AVCodec ff_vmnc_decoder = {
- .name = "vmnc",
- .long_name = NULL_IF_CONFIG_SMALL("VMware Screen Codec / VMware Video"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_VMNC,
- .priv_data_size = sizeof(VmncContext),
- .init = decode_init,
- .close = decode_end,
- .decode = decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/vp3.c b/ffmpeg-2-8-11/libavcodec/vp3.c
deleted file mode 100644
index 9bdbbb8..0000000
--- a/ffmpeg-2-8-11/libavcodec/vp3.c
+++ /dev/null
@@ -1,2580 +0,0 @@
-/*
- * Copyright (c) 2003-2004 The FFmpeg Project
- *
- * 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
- * On2 VP3 Video Decoder
- *
- * VP3 Video Decoder by Mike Melanson (mike at multimedia.cx)
- * For more information about the VP3 coding process, visit:
- * http://wiki.multimedia.cx/index.php?title=On2_VP3
- *
- * Theora decoder by Alex Beregszaszi
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "libavutil/imgutils.h"
-
-#include "avcodec.h"
-#include "get_bits.h"
-#include "hpeldsp.h"
-#include "internal.h"
-#include "mathops.h"
-#include "thread.h"
-#include "videodsp.h"
-#include "vp3data.h"
-#include "vp3dsp.h"
-#include "xiph.h"
-
-#define FRAGMENT_PIXELS 8
-
-// FIXME split things out into their own arrays
-typedef struct Vp3Fragment {
- int16_t dc;
- uint8_t coding_method;
- uint8_t qpi;
-} Vp3Fragment;
-
-#define SB_NOT_CODED 0
-#define SB_PARTIALLY_CODED 1
-#define SB_FULLY_CODED 2
-
-// This is the maximum length of a single long bit run that can be encoded
-// for superblock coding or block qps. Theora special-cases this to read a
-// bit instead of flipping the current bit to allow for runs longer than 4129.
-#define MAXIMUM_LONG_BIT_RUN 4129
-
-#define MODE_INTER_NO_MV 0
-#define MODE_INTRA 1
-#define MODE_INTER_PLUS_MV 2
-#define MODE_INTER_LAST_MV 3
-#define MODE_INTER_PRIOR_LAST 4
-#define MODE_USING_GOLDEN 5
-#define MODE_GOLDEN_MV 6
-#define MODE_INTER_FOURMV 7
-#define CODING_MODE_COUNT 8
-
-/* special internal mode */
-#define MODE_COPY 8
-
-static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb);
-static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb);
-
-
-/* There are 6 preset schemes, plus a free-form scheme */
-static const int ModeAlphabet[6][CODING_MODE_COUNT] = {
- /* scheme 1: Last motion vector dominates */
- { MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST,
- MODE_INTER_PLUS_MV, MODE_INTER_NO_MV,
- MODE_INTRA, MODE_USING_GOLDEN,
- MODE_GOLDEN_MV, MODE_INTER_FOURMV },
-
- /* scheme 2 */
- { MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST,
- MODE_INTER_NO_MV, MODE_INTER_PLUS_MV,
- MODE_INTRA, MODE_USING_GOLDEN,
- MODE_GOLDEN_MV, MODE_INTER_FOURMV },
-
- /* scheme 3 */
- { MODE_INTER_LAST_MV, MODE_INTER_PLUS_MV,
- MODE_INTER_PRIOR_LAST, MODE_INTER_NO_MV,
- MODE_INTRA, MODE_USING_GOLDEN,
- MODE_GOLDEN_MV, MODE_INTER_FOURMV },
-
- /* scheme 4 */
- { MODE_INTER_LAST_MV, MODE_INTER_PLUS_MV,
- MODE_INTER_NO_MV, MODE_INTER_PRIOR_LAST,
- MODE_INTRA, MODE_USING_GOLDEN,
- MODE_GOLDEN_MV, MODE_INTER_FOURMV },
-
- /* scheme 5: No motion vector dominates */
- { MODE_INTER_NO_MV, MODE_INTER_LAST_MV,
- MODE_INTER_PRIOR_LAST, MODE_INTER_PLUS_MV,
- MODE_INTRA, MODE_USING_GOLDEN,
- MODE_GOLDEN_MV, MODE_INTER_FOURMV },
-
- /* scheme 6 */
- { MODE_INTER_NO_MV, MODE_USING_GOLDEN,
- MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST,
- MODE_INTER_PLUS_MV, MODE_INTRA,
- MODE_GOLDEN_MV, MODE_INTER_FOURMV },
-};
-
-static const uint8_t hilbert_offset[16][2] = {
- { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 },
- { 0, 2 }, { 0, 3 }, { 1, 3 }, { 1, 2 },
- { 2, 2 }, { 2, 3 }, { 3, 3 }, { 3, 2 },
- { 3, 1 }, { 2, 1 }, { 2, 0 }, { 3, 0 }
-};
-
-#define MIN_DEQUANT_VAL 2
-
-typedef struct Vp3DecodeContext {
- AVCodecContext *avctx;
- int theora, theora_tables, theora_header;
- int version;
- int width, height;
- int chroma_x_shift, chroma_y_shift;
- ThreadFrame golden_frame;
- ThreadFrame last_frame;
- ThreadFrame current_frame;
- int keyframe;
- uint8_t idct_permutation[64];
- uint8_t idct_scantable[64];
- HpelDSPContext hdsp;
- VideoDSPContext vdsp;
- VP3DSPContext vp3dsp;
- DECLARE_ALIGNED(16, int16_t, block)[64];
- int flipped_image;
- int last_slice_end;
- int skip_loop_filter;
-
- int qps[3];
- int nqps;
- int last_qps[3];
-
- int superblock_count;
- int y_superblock_width;
- int y_superblock_height;
- int y_superblock_count;
- int c_superblock_width;
- int c_superblock_height;
- int c_superblock_count;
- int u_superblock_start;
- int v_superblock_start;
- unsigned char *superblock_coding;
-
- int macroblock_count;
- int macroblock_width;
- int macroblock_height;
-
- int fragment_count;
- int fragment_width[2];
- int fragment_height[2];
-
- Vp3Fragment *all_fragments;
- int fragment_start[3];
- int data_offset[3];
- uint8_t offset_x;
- uint8_t offset_y;
- int offset_x_warned;
-
- int8_t (*motion_val[2])[2];
-
- /* tables */
- uint16_t coded_dc_scale_factor[64];
- uint32_t coded_ac_scale_factor[64];
- uint8_t base_matrix[384][64];
- uint8_t qr_count[2][3];
- uint8_t qr_size[2][3][64];
- uint16_t qr_base[2][3][64];
-
- /**
- * This is a list of all tokens in bitstream order. Reordering takes place
- * by pulling from each level during IDCT. As a consequence, IDCT must be
- * in Hilbert order, making the minimum slice height 64 for 4:2:0 and 32
- * otherwise. The 32 different tokens with up to 12 bits of extradata are
- * collapsed into 3 types, packed as follows:
- * (from the low to high bits)
- *
- * 2 bits: type (0,1,2)
- * 0: EOB run, 14 bits for run length (12 needed)
- * 1: zero run, 7 bits for run length
- * 7 bits for the next coefficient (3 needed)
- * 2: coefficient, 14 bits (11 needed)
- *
- * Coefficients are signed, so are packed in the highest bits for automatic
- * sign extension.
- */
- int16_t *dct_tokens[3][64];
- int16_t *dct_tokens_base;
-#define TOKEN_EOB(eob_run) ((eob_run) << 2)
-#define TOKEN_ZERO_RUN(coeff, zero_run) (((coeff) * 512) + ((zero_run) << 2) + 1)
-#define TOKEN_COEFF(coeff) (((coeff) * 4) + 2)
-
- /**
- * number of blocks that contain DCT coefficients at
- * the given level or higher
- */
- int num_coded_frags[3][64];
- int total_num_coded_frags;
-
- /* this is a list of indexes into the all_fragments array indicating
- * which of the fragments are coded */
- int *coded_fragment_list[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];
-
- VLC superblock_run_length_vlc;
- VLC fragment_run_length_vlc;
- VLC mode_code_vlc;
- VLC motion_vector_vlc;
-
- /* these arrays need to be on 16-byte boundaries since SSE2 operations
- * index into them */
- DECLARE_ALIGNED(16, int16_t, qmat)[3][2][3][64]; ///< qmat[qpi][is_inter][plane]
-
- /* This table contains superblock_count * 16 entries. Each set of 16
- * numbers corresponds to the fragment indexes 0..15 of the superblock.
- * An entry will be -1 to indicate that no entry corresponds to that
- * index. */
- int *superblock_fragments;
-
- /* This is an array that indicates how a particular macroblock
- * is coded. */
- unsigned char *macroblock_coding;
-
- 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];
-
- uint8_t filter_limit_values[64];
- DECLARE_ALIGNED(8, int, bounding_values_array)[256 + 2];
-} Vp3DecodeContext;
-
-/************************************************************************
- * VP3 specific functions
- ************************************************************************/
-
-static av_cold void free_tables(AVCodecContext *avctx)
-{
- Vp3DecodeContext *s = avctx->priv_data;
-
- av_freep(&s->superblock_coding);
- av_freep(&s->all_fragments);
- av_freep(&s->coded_fragment_list[0]);
- av_freep(&s->dct_tokens_base);
- av_freep(&s->superblock_fragments);
- av_freep(&s->macroblock_coding);
- av_freep(&s->motion_val[0]);
- av_freep(&s->motion_val[1]);
-}
-
-static void vp3_decode_flush(AVCodecContext *avctx)
-{
- Vp3DecodeContext *s = avctx->priv_data;
-
- if (s->golden_frame.f)
- ff_thread_release_buffer(avctx, &s->golden_frame);
- if (s->last_frame.f)
- ff_thread_release_buffer(avctx, &s->last_frame);
- if (s->current_frame.f)
- ff_thread_release_buffer(avctx, &s->current_frame);
-}
-
-static av_cold int vp3_decode_end(AVCodecContext *avctx)
-{
- Vp3DecodeContext *s = avctx->priv_data;
- int i;
-
- free_tables(avctx);
- av_freep(&s->edge_emu_buffer);
-
- s->theora_tables = 0;
-
- /* release all frames */
- vp3_decode_flush(avctx);
- av_frame_free(&s->current_frame.f);
- av_frame_free(&s->last_frame.f);
- av_frame_free(&s->golden_frame.f);
-
- if (avctx->internal->is_copy)
- return 0;
-
- 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]);
- }
-
- ff_free_vlc(&s->superblock_run_length_vlc);
- ff_free_vlc(&s->fragment_run_length_vlc);
- ff_free_vlc(&s->mode_code_vlc);
- ff_free_vlc(&s->motion_vector_vlc);
-
- return 0;
-}
-
-/**
- * This function sets up all of the various blocks mappings:
- * superblocks <-> fragments, macroblocks <-> fragments,
- * superblocks <-> macroblocks
- *
- * @return 0 is successful; returns 1 if *anything* went wrong.
- */
-static int init_block_mapping(Vp3DecodeContext *s)
-{
- int sb_x, sb_y, plane;
- int x, y, i, j = 0;
-
- for (plane = 0; plane < 3; plane++) {
- int sb_width = plane ? s->c_superblock_width
- : s->y_superblock_width;
- int sb_height = plane ? s->c_superblock_height
- : s->y_superblock_height;
- int frag_width = s->fragment_width[!!plane];
- int frag_height = s->fragment_height[!!plane];
-
- for (sb_y = 0; sb_y < sb_height; sb_y++)
- for (sb_x = 0; sb_x < sb_width; sb_x++)
- for (i = 0; i < 16; i++) {
- x = 4 * sb_x + hilbert_offset[i][0];
- y = 4 * sb_y + hilbert_offset[i][1];
-
- if (x < frag_width && y < frag_height)
- s->superblock_fragments[j++] = s->fragment_start[plane] +
- y * frag_width + x;
- else
- s->superblock_fragments[j++] = -1;
- }
- }
-
- return 0; /* successful path out */
-}
-
-/*
- * This function sets up the dequantization tables used for a particular
- * frame.
- */
-static void init_dequantizer(Vp3DecodeContext *s, int qpi)
-{
- int ac_scale_factor = s->coded_ac_scale_factor[s->qps[qpi]];
- int dc_scale_factor = s->coded_dc_scale_factor[s->qps[qpi]];
- int i, plane, inter, qri, bmi, bmj, qistart;
-
- for (inter = 0; inter < 2; inter++) {
- for (plane = 0; plane < 3; plane++) {
- int sum = 0;
- for (qri = 0; qri < s->qr_count[inter][plane]; qri++) {
- sum += s->qr_size[inter][plane][qri];
- if (s->qps[qpi] <= sum)
- break;
- }
- qistart = sum - s->qr_size[inter][plane][qri];
- bmi = s->qr_base[inter][plane][qri];
- bmj = s->qr_base[inter][plane][qri + 1];
- for (i = 0; i < 64; i++) {
- int coeff = (2 * (sum - s->qps[qpi]) * s->base_matrix[bmi][i] -
- 2 * (qistart - s->qps[qpi]) * s->base_matrix[bmj][i] +
- s->qr_size[inter][plane][qri]) /
- (2 * s->qr_size[inter][plane][qri]);
-
- int qmin = 8 << (inter + !i);
- int qscale = i ? ac_scale_factor : dc_scale_factor;
-
- s->qmat[qpi][inter][plane][s->idct_permutation[i]] =
- av_clip((qscale * coeff) / 100 * 4, qmin, 4096);
- }
- /* all DC coefficients use the same quant so as not to interfere
- * with DC prediction */
- s->qmat[qpi][inter][plane][0] = s->qmat[0][inter][plane][0];
- }
- }
-}
-
-/*
- * This function initializes the loop filter boundary limits if the frame's
- * quality index is different from the previous frame's.
- *
- * The filter_limit_values may not be larger than 127.
- */
-static void init_loop_filter(Vp3DecodeContext *s)
-{
- int *bounding_values = s->bounding_values_array + 127;
- int filter_limit;
- int x;
- int value;
-
- filter_limit = s->filter_limit_values[s->qps[0]];
- av_assert0(filter_limit < 128U);
-
- /* set up the bounding values */
- memset(s->bounding_values_array, 0, 256 * sizeof(int));
- for (x = 0; x < filter_limit; x++) {
- bounding_values[-x] = -x;
- bounding_values[x] = x;
- }
- for (x = value = filter_limit; x < 128 && value; x++, value--) {
- bounding_values[ x] = value;
- bounding_values[-x] = -value;
- }
- if (value)
- bounding_values[128] = value;
- bounding_values[129] = bounding_values[130] = filter_limit * 0x02020202;
-}
-
-/*
- * This function unpacks all of the superblock/macroblock/fragment coding
- * information from the bitstream.
- */
-static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)
-{
- int superblock_starts[3] = {
- 0, s->u_superblock_start, s->v_superblock_start
- };
- int bit = 0;
- int current_superblock = 0;
- int current_run = 0;
- int num_partial_superblocks = 0;
-
- int i, j;
- int current_fragment;
- int plane;
-
- if (s->keyframe) {
- memset(s->superblock_coding, SB_FULLY_CODED, s->superblock_count);
- } else {
- /* unpack the list of partially-coded superblocks */
- bit = get_bits1(gb) ^ 1;
- current_run = 0;
-
- while (current_superblock < s->superblock_count && get_bits_left(gb) > 0) {
- if (s->theora && current_run == MAXIMUM_LONG_BIT_RUN)
- bit = get_bits1(gb);
- else
- bit ^= 1;
-
- current_run = get_vlc2(gb, s->superblock_run_length_vlc.table,
- 6, 2) + 1;
- if (current_run == 34)
- current_run += get_bits(gb, 12);
-
- if (current_run > s->superblock_count - current_superblock) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Invalid partially coded superblock run length\n");
- return -1;
- }
-
- memset(s->superblock_coding + current_superblock, bit, current_run);
-
- current_superblock += current_run;
- if (bit)
- num_partial_superblocks += current_run;
- }
-
- /* unpack the list of fully coded superblocks if any of the blocks were
- * not marked as partially coded in the previous step */
- if (num_partial_superblocks < s->superblock_count) {
- int superblocks_decoded = 0;
-
- current_superblock = 0;
- bit = get_bits1(gb) ^ 1;
- current_run = 0;
-
- while (superblocks_decoded < s->superblock_count - num_partial_superblocks &&
- get_bits_left(gb) > 0) {
- if (s->theora && current_run == MAXIMUM_LONG_BIT_RUN)
- bit = get_bits1(gb);
- else
- bit ^= 1;
-
- current_run = get_vlc2(gb, s->superblock_run_length_vlc.table,
- 6, 2) + 1;
- if (current_run == 34)
- current_run += get_bits(gb, 12);
-
- for (j = 0; j < current_run; current_superblock++) {
- if (current_superblock >= s->superblock_count) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Invalid fully coded superblock run length\n");
- return -1;
- }
-
- /* skip any superblocks already marked as partially coded */
- if (s->superblock_coding[current_superblock] == SB_NOT_CODED) {
- s->superblock_coding[current_superblock] = 2 * bit;
- j++;
- }
- }
- superblocks_decoded += current_run;
- }
- }
-
- /* if there were partial blocks, initialize bitstream for
- * unpacking fragment codings */
- if (num_partial_superblocks) {
- current_run = 0;
- bit = get_bits1(gb);
- /* toggle the bit because as soon as the first run length is
- * fetched the bit will be toggled again */
- bit ^= 1;
- }
- }
-
- /* figure out which fragments are coded; iterate through each
- * superblock (all planes) */
- s->total_num_coded_frags = 0;
- memset(s->macroblock_coding, MODE_COPY, s->macroblock_count);
-
- for (plane = 0; plane < 3; plane++) {
- int sb_start = superblock_starts[plane];
- int sb_end = sb_start + (plane ? s->c_superblock_count
- : s->y_superblock_count);
- int num_coded_frags = 0;
-
- for (i = sb_start; i < sb_end && get_bits_left(gb) > 0; i++) {
- /* iterate through all 16 fragments in a superblock */
- for (j = 0; j < 16; j++) {
- /* if the fragment is in bounds, check its coding status */
- current_fragment = s->superblock_fragments[i * 16 + j];
- if (current_fragment != -1) {
- int coded = s->superblock_coding[i];
-
- if (s->superblock_coding[i] == SB_PARTIALLY_CODED) {
- /* fragment may or may not be coded; this is the case
- * that cares about the fragment coding runs */
- if (current_run-- == 0) {
- bit ^= 1;
- current_run = get_vlc2(gb, s->fragment_run_length_vlc.table, 5, 2);
- }
- coded = bit;
- }
-
- if (coded) {
- /* default mode; actual mode will be decoded in
- * the next phase */
- s->all_fragments[current_fragment].coding_method =
- MODE_INTER_NO_MV;
- s->coded_fragment_list[plane][num_coded_frags++] =
- current_fragment;
- } else {
- /* not coded; copy this fragment from the prior frame */
- s->all_fragments[current_fragment].coding_method =
- MODE_COPY;
- }
- }
- }
- }
- s->total_num_coded_frags += num_coded_frags;
- for (i = 0; i < 64; i++)
- s->num_coded_frags[plane][i] = num_coded_frags;
- if (plane < 2)
- s->coded_fragment_list[plane + 1] = s->coded_fragment_list[plane] +
- num_coded_frags;
- }
- return 0;
-}
-
-/*
- * This function unpacks all the coding mode data for individual macroblocks
- * from the bitstream.
- */
-static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb)
-{
- int i, j, k, sb_x, sb_y;
- int scheme;
- int current_macroblock;
- int current_fragment;
- int coding_mode;
- int custom_mode_alphabet[CODING_MODE_COUNT];
- const int *alphabet;
- Vp3Fragment *frag;
-
- if (s->keyframe) {
- for (i = 0; i < s->fragment_count; i++)
- s->all_fragments[i].coding_method = MODE_INTRA;
- } else {
- /* fetch the mode coding scheme for this frame */
- scheme = get_bits(gb, 3);
-
- /* is it a custom coding scheme? */
- if (scheme == 0) {
- for (i = 0; i < 8; i++)
- custom_mode_alphabet[i] = MODE_INTER_NO_MV;
- for (i = 0; i < 8; i++)
- custom_mode_alphabet[get_bits(gb, 3)] = i;
- alphabet = custom_mode_alphabet;
- } else
- alphabet = ModeAlphabet[scheme - 1];
-
- /* iterate through all of the macroblocks that contain 1 or more
- * coded fragments */
- for (sb_y = 0; sb_y < s->y_superblock_height; sb_y++) {
- for (sb_x = 0; sb_x < s->y_superblock_width; sb_x++) {
- if (get_bits_left(gb) <= 0)
- return -1;
-
- for (j = 0; j < 4; j++) {
- int mb_x = 2 * sb_x + (j >> 1);
- int mb_y = 2 * sb_y + (((j >> 1) + j) & 1);
- current_macroblock = mb_y * s->macroblock_width + mb_x;
-
- if (mb_x >= s->macroblock_width ||
- mb_y >= s->macroblock_height)
- continue;
-
-#define BLOCK_X (2 * mb_x + (k & 1))
-#define BLOCK_Y (2 * mb_y + (k >> 1))
- /* coding modes are only stored if the macroblock has
- * at least one luma block coded, otherwise it must be
- * INTER_NO_MV */
- for (k = 0; k < 4; k++) {
- current_fragment = BLOCK_Y *
- s->fragment_width[0] + BLOCK_X;
- if (s->all_fragments[current_fragment].coding_method != MODE_COPY)
- break;
- }
- if (k == 4) {
- s->macroblock_coding[current_macroblock] = MODE_INTER_NO_MV;
- continue;
- }
-
- /* mode 7 means get 3 bits for each coding mode */
- if (scheme == 7)
- coding_mode = get_bits(gb, 3);
- else
- coding_mode = alphabet[get_vlc2(gb, s->mode_code_vlc.table, 3, 3)];
-
- s->macroblock_coding[current_macroblock] = coding_mode;
- for (k = 0; k < 4; k++) {
- frag = s->all_fragments + BLOCK_Y * s->fragment_width[0] + BLOCK_X;
- if (frag->coding_method != MODE_COPY)
- frag->coding_method = coding_mode;
- }
-
-#define SET_CHROMA_MODES \
- if (frag[s->fragment_start[1]].coding_method != MODE_COPY) \
- frag[s->fragment_start[1]].coding_method = coding_mode; \
- if (frag[s->fragment_start[2]].coding_method != MODE_COPY) \
- frag[s->fragment_start[2]].coding_method = coding_mode;
-
- if (s->chroma_y_shift) {
- frag = s->all_fragments + mb_y *
- s->fragment_width[1] + mb_x;
- SET_CHROMA_MODES
- } else if (s->chroma_x_shift) {
- frag = s->all_fragments +
- 2 * mb_y * s->fragment_width[1] + mb_x;
- for (k = 0; k < 2; k++) {
- SET_CHROMA_MODES
- frag += s->fragment_width[1];
- }
- } else {
- for (k = 0; k < 4; k++) {
- frag = s->all_fragments +
- BLOCK_Y * s->fragment_width[1] + BLOCK_X;
- SET_CHROMA_MODES
- }
- }
- }
- }
- }
- }
-
- return 0;
-}
-
-/*
- * This function unpacks all the motion vectors for the individual
- * macroblocks from the bitstream.
- */
-static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb)
-{
- int j, k, sb_x, sb_y;
- int coding_mode;
- int motion_x[4];
- int motion_y[4];
- int last_motion_x = 0;
- int last_motion_y = 0;
- int prior_last_motion_x = 0;
- int prior_last_motion_y = 0;
- int current_macroblock;
- int current_fragment;
- int frag;
-
- if (s->keyframe)
- return 0;
-
- /* coding mode 0 is the VLC scheme; 1 is the fixed code scheme */
- coding_mode = get_bits1(gb);
-
- /* iterate through all of the macroblocks that contain 1 or more
- * coded fragments */
- for (sb_y = 0; sb_y < s->y_superblock_height; sb_y++) {
- for (sb_x = 0; sb_x < s->y_superblock_width; sb_x++) {
- if (get_bits_left(gb) <= 0)
- return -1;
-
- for (j = 0; j < 4; j++) {
- int mb_x = 2 * sb_x + (j >> 1);
- int mb_y = 2 * sb_y + (((j >> 1) + j) & 1);
- current_macroblock = mb_y * s->macroblock_width + mb_x;
-
- if (mb_x >= s->macroblock_width ||
- mb_y >= s->macroblock_height ||
- s->macroblock_coding[current_macroblock] == MODE_COPY)
- continue;
-
- switch (s->macroblock_coding[current_macroblock]) {
- case MODE_INTER_PLUS_MV:
- case MODE_GOLDEN_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)];
- } else {
- motion_x[0] = fixed_motion_vector_table[get_bits(gb, 6)];
- motion_y[0] = fixed_motion_vector_table[get_bits(gb, 6)];
- }
-
- /* vector maintenance, only on MODE_INTER_PLUS_MV */
- if (s->macroblock_coding[current_macroblock] == MODE_INTER_PLUS_MV) {
- prior_last_motion_x = last_motion_x;
- prior_last_motion_y = last_motion_y;
- last_motion_x = motion_x[0];
- last_motion_y = motion_y[0];
- }
- break;
-
- case MODE_INTER_FOURMV:
- /* vector maintenance */
- prior_last_motion_x = last_motion_x;
- prior_last_motion_y = last_motion_y;
-
- /* fetch 4 vectors from the bitstream, one for each
- * Y fragment, then average for the C fragment vectors */
- for (k = 0; k < 4; k++) {
- 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)];
- } else {
- motion_x[k] = fixed_motion_vector_table[get_bits(gb, 6)];
- motion_y[k] = fixed_motion_vector_table[get_bits(gb, 6)];
- }
- last_motion_x = motion_x[k];
- last_motion_y = motion_y[k];
- } else {
- motion_x[k] = 0;
- motion_y[k] = 0;
- }
- }
- break;
-
- case MODE_INTER_LAST_MV:
- /* all 6 fragments use the last motion vector */
- motion_x[0] = last_motion_x;
- motion_y[0] = last_motion_y;
-
- /* no vector maintenance (last vector remains the
- * last vector) */
- break;
-
- case MODE_INTER_PRIOR_LAST:
- /* all 6 fragments use the motion vector prior to the
- * last motion vector */
- motion_x[0] = prior_last_motion_x;
- motion_y[0] = prior_last_motion_y;
-
- /* vector maintenance */
- prior_last_motion_x = last_motion_x;
- prior_last_motion_y = last_motion_y;
- last_motion_x = motion_x[0];
- last_motion_y = motion_y[0];
- break;
-
- default:
- /* covers intra, inter without MV, golden without MV */
- motion_x[0] = 0;
- motion_y[0] = 0;
-
- /* no vector maintenance */
- break;
- }
-
- /* assign the motion vectors to the correct fragments */
- for (k = 0; k < 4; k++) {
- current_fragment =
- BLOCK_Y * s->fragment_width[0] + BLOCK_X;
- if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {
- s->motion_val[0][current_fragment][0] = motion_x[k];
- s->motion_val[0][current_fragment][1] = motion_y[k];
- } else {
- s->motion_val[0][current_fragment][0] = motion_x[0];
- s->motion_val[0][current_fragment][1] = motion_y[0];
- }
- }
-
- if (s->chroma_y_shift) {
- if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {
- motion_x[0] = RSHIFT(motion_x[0] + motion_x[1] +
- motion_x[2] + motion_x[3], 2);
- motion_y[0] = RSHIFT(motion_y[0] + motion_y[1] +
- motion_y[2] + motion_y[3], 2);
- }
- motion_x[0] = (motion_x[0] >> 1) | (motion_x[0] & 1);
- motion_y[0] = (motion_y[0] >> 1) | (motion_y[0] & 1);
- frag = mb_y * s->fragment_width[1] + mb_x;
- s->motion_val[1][frag][0] = motion_x[0];
- s->motion_val[1][frag][1] = motion_y[0];
- } else if (s->chroma_x_shift) {
- if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {
- motion_x[0] = RSHIFT(motion_x[0] + motion_x[1], 1);
- motion_y[0] = RSHIFT(motion_y[0] + motion_y[1], 1);
- motion_x[1] = RSHIFT(motion_x[2] + motion_x[3], 1);
- motion_y[1] = RSHIFT(motion_y[2] + motion_y[3], 1);
- } else {
- motion_x[1] = motion_x[0];
- motion_y[1] = motion_y[0];
- }
- motion_x[0] = (motion_x[0] >> 1) | (motion_x[0] & 1);
- motion_x[1] = (motion_x[1] >> 1) | (motion_x[1] & 1);
-
- frag = 2 * mb_y * s->fragment_width[1] + mb_x;
- for (k = 0; k < 2; k++) {
- s->motion_val[1][frag][0] = motion_x[k];
- s->motion_val[1][frag][1] = motion_y[k];
- frag += s->fragment_width[1];
- }
- } else {
- for (k = 0; k < 4; k++) {
- frag = BLOCK_Y * s->fragment_width[1] + BLOCK_X;
- if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {
- s->motion_val[1][frag][0] = motion_x[k];
- s->motion_val[1][frag][1] = motion_y[k];
- } else {
- s->motion_val[1][frag][0] = motion_x[0];
- s->motion_val[1][frag][1] = motion_y[0];
- }
- }
- }
- }
- }
- }
-
- return 0;
-}
-
-static int unpack_block_qpis(Vp3DecodeContext *s, GetBitContext *gb)
-{
- int qpi, i, j, bit, run_length, blocks_decoded, num_blocks_at_qpi;
- int num_blocks = s->total_num_coded_frags;
-
- for (qpi = 0; qpi < s->nqps - 1 && num_blocks > 0; qpi++) {
- i = blocks_decoded = num_blocks_at_qpi = 0;
-
- bit = get_bits1(gb) ^ 1;
- run_length = 0;
-
- do {
- if (run_length == MAXIMUM_LONG_BIT_RUN)
- bit = get_bits1(gb);
- else
- bit ^= 1;
-
- run_length = get_vlc2(gb, s->superblock_run_length_vlc.table, 6, 2) + 1;
- if (run_length == 34)
- run_length += get_bits(gb, 12);
- blocks_decoded += run_length;
-
- if (!bit)
- num_blocks_at_qpi += run_length;
-
- for (j = 0; j < run_length; i++) {
- if (i >= s->total_num_coded_frags)
- return -1;
-
- if (s->all_fragments[s->coded_fragment_list[0][i]].qpi == qpi) {
- s->all_fragments[s->coded_fragment_list[0][i]].qpi += bit;
- j++;
- }
- }
- } while (blocks_decoded < num_blocks && get_bits_left(gb) > 0);
-
- num_blocks -= num_blocks_at_qpi;
- }
-
- return 0;
-}
-
-/*
- * This function is called by unpack_dct_coeffs() to extract the VLCs from
- * the bitstream. The VLCs encode tokens which are used to unpack DCT
- * data. This function unpacks all the VLCs for either the Y plane or both
- * C planes, and is called for DC coefficients or different AC coefficient
- * levels (since different coefficient types require different VLC tables.
- *
- * This function returns a residual eob run. E.g, if a particular token gave
- * instructions to EOB the next 5 fragments and there were only 2 fragments
- * left in the current fragment range, 3 would be returned so that it could
- * be passed into the next call to this same function.
- */
-static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
- VLC *table, int coeff_index,
- int plane,
- int eob_run)
-{
- int i, j = 0;
- int token;
- int zero_run = 0;
- int16_t coeff = 0;
- int bits_to_get;
- int blocks_ended;
- int coeff_i = 0;
- int num_coeffs = s->num_coded_frags[plane][coeff_index];
- int16_t *dct_tokens = s->dct_tokens[plane][coeff_index];
-
- /* local references to structure members to avoid repeated deferences */
- int *coded_fragment_list = s->coded_fragment_list[plane];
- Vp3Fragment *all_fragments = s->all_fragments;
- VLC_TYPE(*vlc_table)[2] = table->table;
-
- if (num_coeffs < 0)
- av_log(s->avctx, AV_LOG_ERROR,
- "Invalid number of coefficents at level %d\n", coeff_index);
-
- if (eob_run > num_coeffs) {
- coeff_i =
- blocks_ended = num_coeffs;
- eob_run -= num_coeffs;
- } else {
- coeff_i =
- blocks_ended = eob_run;
- eob_run = 0;
- }
-
- // insert fake EOB token to cover the split between planes or zzi
- if (blocks_ended)
- dct_tokens[j++] = blocks_ended << 2;
-
- while (coeff_i < num_coeffs && get_bits_left(gb) > 0) {
- /* decode a VLC into a token */
- token = get_vlc2(gb, vlc_table, 11, 3);
- /* use the token to get a zero run, a coefficient, and an eob run */
- if ((unsigned) token <= 6U) {
- eob_run = eob_run_base[token];
- if (eob_run_get_bits[token])
- eob_run += get_bits(gb, eob_run_get_bits[token]);
-
- // record only the number of blocks ended in this plane,
- // any spill will be recorded in the next plane.
- if (eob_run > num_coeffs - coeff_i) {
- dct_tokens[j++] = TOKEN_EOB(num_coeffs - coeff_i);
- blocks_ended += num_coeffs - coeff_i;
- eob_run -= num_coeffs - coeff_i;
- coeff_i = num_coeffs;
- } else {
- dct_tokens[j++] = TOKEN_EOB(eob_run);
- blocks_ended += eob_run;
- coeff_i += eob_run;
- eob_run = 0;
- }
- } else if (token >= 0) {
- bits_to_get = coeff_get_bits[token];
- if (bits_to_get)
- bits_to_get = get_bits(gb, bits_to_get);
- coeff = coeff_tables[token][bits_to_get];
-
- zero_run = zero_run_base[token];
- if (zero_run_get_bits[token])
- zero_run += get_bits(gb, zero_run_get_bits[token]);
-
- if (zero_run) {
- dct_tokens[j++] = TOKEN_ZERO_RUN(coeff, zero_run);
- } else {
- // Save DC into the fragment structure. DC prediction is
- // done in raster order, so the actual DC can't be in with
- // other tokens. We still need the token in dct_tokens[]
- // however, or else the structure collapses on itself.
- if (!coeff_index)
- all_fragments[coded_fragment_list[coeff_i]].dc = coeff;
-
- dct_tokens[j++] = TOKEN_COEFF(coeff);
- }
-
- if (coeff_index + zero_run > 64) {
- av_log(s->avctx, AV_LOG_DEBUG,
- "Invalid zero run of %d with %d coeffs left\n",
- zero_run, 64 - coeff_index);
- zero_run = 64 - coeff_index;
- }
-
- // zero runs code multiple coefficients,
- // so don't try to decode coeffs for those higher levels
- for (i = coeff_index + 1; i <= coeff_index + zero_run; i++)
- s->num_coded_frags[plane][i]--;
- coeff_i++;
- } else {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid token %d\n", token);
- return -1;
- }
- }
-
- if (blocks_ended > s->num_coded_frags[plane][coeff_index])
- av_log(s->avctx, AV_LOG_ERROR, "More blocks ended than coded!\n");
-
- // decrement the number of blocks that have higher coefficients for each
- // EOB run at this level
- if (blocks_ended)
- for (i = coeff_index + 1; i < 64; i++)
- s->num_coded_frags[plane][i] -= blocks_ended;
-
- // setup the next buffer
- if (plane < 2)
- s->dct_tokens[plane + 1][coeff_index] = dct_tokens + j;
- else if (coeff_index < 63)
- s->dct_tokens[0][coeff_index + 1] = dct_tokens + j;
-
- return eob_run;
-}
-
-static void reverse_dc_prediction(Vp3DecodeContext *s,
- int first_fragment,
- int fragment_width,
- int fragment_height);
-/*
- * This function unpacks all of the DCT coefficient data from the
- * bitstream.
- */
-static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
-{
- int i;
- int dc_y_table;
- int dc_c_table;
- int ac_y_table;
- int ac_c_table;
- int residual_eob_run = 0;
- VLC *y_tables[64];
- VLC *c_tables[64];
-
- s->dct_tokens[0][0] = s->dct_tokens_base;
-
- /* fetch the DC table indexes */
- dc_y_table = get_bits(gb, 4);
- 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,
- 0, residual_eob_run);
- if (residual_eob_run < 0)
- return residual_eob_run;
-
- /* reverse prediction of the Y-plane DC coefficients */
- 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,
- 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,
- 2, residual_eob_run);
- if (residual_eob_run < 0)
- return residual_eob_run;
-
- /* reverse prediction of the C-plane DC coefficients */
- if (!(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
- reverse_dc_prediction(s, s->fragment_start[1],
- s->fragment_width[1], s->fragment_height[1]);
- reverse_dc_prediction(s, s->fragment_start[2],
- s->fragment_width[1], s->fragment_height[1]);
- }
-
- /* fetch the AC table indexes */
- ac_y_table = get_bits(gb, 4);
- ac_c_table = get_bits(gb, 4);
-
- /* 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];
- }
- 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];
- }
- 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];
- }
- 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];
- }
-
- /* decode all AC coefficents */
- for (i = 1; i <= 63; i++) {
- residual_eob_run = unpack_vlcs(s, gb, y_tables[i], i,
- 0, residual_eob_run);
- if (residual_eob_run < 0)
- return residual_eob_run;
-
- residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i,
- 1, residual_eob_run);
- if (residual_eob_run < 0)
- return residual_eob_run;
- residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i,
- 2, residual_eob_run);
- if (residual_eob_run < 0)
- return residual_eob_run;
- }
-
- return 0;
-}
-
-/*
- * This function reverses the DC prediction for each coded fragment in
- * the frame. Much of this function is adapted directly from the original
- * VP3 source code.
- */
-#define COMPATIBLE_FRAME(x) \
- (compatible_frame[s->all_fragments[x].coding_method] == current_frame_type)
-#define DC_COEFF(u) s->all_fragments[u].dc
-
-static void reverse_dc_prediction(Vp3DecodeContext *s,
- int first_fragment,
- int fragment_width,
- int fragment_height)
-{
-#define PUL 8
-#define PU 4
-#define PUR 2
-#define PL 1
-
- int x, y;
- int i = first_fragment;
-
- int predicted_dc;
-
- /* DC values for the left, up-left, up, and up-right fragments */
- int vl, vul, vu, vur;
-
- /* indexes for the left, up-left, up, and up-right fragments */
- int l, ul, u, ur;
-
- /*
- * The 6 fields mean:
- * 0: up-left multiplier
- * 1: up multiplier
- * 2: up-right multiplier
- * 3: left multiplier
- */
- static const int predictor_transform[16][4] = {
- { 0, 0, 0, 0 },
- { 0, 0, 0, 128 }, // PL
- { 0, 0, 128, 0 }, // PUR
- { 0, 0, 53, 75 }, // PUR|PL
- { 0, 128, 0, 0 }, // PU
- { 0, 64, 0, 64 }, // PU |PL
- { 0, 128, 0, 0 }, // PU |PUR
- { 0, 0, 53, 75 }, // PU |PUR|PL
- { 128, 0, 0, 0 }, // PUL
- { 0, 0, 0, 128 }, // PUL|PL
- { 64, 0, 64, 0 }, // PUL|PUR
- { 0, 0, 53, 75 }, // PUL|PUR|PL
- { 0, 128, 0, 0 }, // PUL|PU
- { -104, 116, 0, 116 }, // PUL|PU |PL
- { 24, 80, 24, 0 }, // PUL|PU |PUR
- { -104, 116, 0, 116 } // PUL|PU |PUR|PL
- };
-
- /* This table shows which types of blocks can use other blocks for
- * prediction. For example, INTRA is the only mode in this table to
- * have a frame number of 0. That means INTRA blocks can only predict
- * from other INTRA blocks. There are 2 golden frame coding types;
- * blocks encoding in these modes can only predict from other blocks
- * that were encoded with these 1 of these 2 modes. */
- static const unsigned char compatible_frame[9] = {
- 1, /* MODE_INTER_NO_MV */
- 0, /* MODE_INTRA */
- 1, /* MODE_INTER_PLUS_MV */
- 1, /* MODE_INTER_LAST_MV */
- 1, /* MODE_INTER_PRIOR_MV */
- 2, /* MODE_USING_GOLDEN */
- 2, /* MODE_GOLDEN_MV */
- 1, /* MODE_INTER_FOUR_MV */
- 3 /* MODE_COPY */
- };
- int current_frame_type;
-
- /* there is a last DC predictor for each of the 3 frame types */
- short last_dc[3];
-
- int transform = 0;
-
- vul =
- vu =
- vur =
- vl = 0;
- last_dc[0] =
- last_dc[1] =
- last_dc[2] = 0;
-
- /* for each fragment row... */
- for (y = 0; y < fragment_height; y++) {
- /* for each fragment in a row... */
- for (x = 0; x < fragment_width; x++, i++) {
-
- /* reverse prediction if this block was coded */
- if (s->all_fragments[i].coding_method != MODE_COPY) {
- current_frame_type =
- compatible_frame[s->all_fragments[i].coding_method];
-
- transform = 0;
- if (x) {
- l = i - 1;
- vl = DC_COEFF(l);
- if (COMPATIBLE_FRAME(l))
- transform |= PL;
- }
- if (y) {
- u = i - fragment_width;
- vu = DC_COEFF(u);
- if (COMPATIBLE_FRAME(u))
- transform |= PU;
- if (x) {
- ul = i - fragment_width - 1;
- vul = DC_COEFF(ul);
- if (COMPATIBLE_FRAME(ul))
- transform |= PUL;
- }
- if (x + 1 < fragment_width) {
- ur = i - fragment_width + 1;
- vur = DC_COEFF(ur);
- if (COMPATIBLE_FRAME(ur))
- transform |= PUR;
- }
- }
-
- if (transform == 0) {
- /* if there were no fragments to predict from, use last
- * DC saved */
- predicted_dc = last_dc[current_frame_type];
- } else {
- /* apply the appropriate predictor transform */
- predicted_dc =
- (predictor_transform[transform][0] * vul) +
- (predictor_transform[transform][1] * vu) +
- (predictor_transform[transform][2] * vur) +
- (predictor_transform[transform][3] * vl);
-
- predicted_dc /= 128;
-
- /* check for outranging on the [ul u l] and
- * [ul u ur l] predictors */
- if ((transform == 15) || (transform == 13)) {
- if (FFABS(predicted_dc - vu) > 128)
- predicted_dc = vu;
- else if (FFABS(predicted_dc - vl) > 128)
- predicted_dc = vl;
- else if (FFABS(predicted_dc - vul) > 128)
- predicted_dc = vul;
- }
- }
-
- /* at long last, apply the predictor */
- DC_COEFF(i) += predicted_dc;
- /* save the DC */
- last_dc[current_frame_type] = DC_COEFF(i);
- }
- }
- }
-}
-
-static void apply_loop_filter(Vp3DecodeContext *s, int plane,
- int ystart, int yend)
-{
- int x, y;
- int *bounding_values = s->bounding_values_array + 127;
-
- int width = s->fragment_width[!!plane];
- int height = s->fragment_height[!!plane];
- int fragment = s->fragment_start[plane] + ystart * width;
- ptrdiff_t stride = s->current_frame.f->linesize[plane];
- uint8_t *plane_data = s->current_frame.f->data[plane];
- if (!s->flipped_image)
- stride = -stride;
- plane_data += s->data_offset[plane] + 8 * ystart * stride;
-
- for (y = ystart; y < yend; y++) {
- for (x = 0; x < width; x++) {
- /* This code basically just deblocks on the edges of coded blocks.
- * However, it has to be much more complicated because of the
- * braindamaged deblock ordering used in VP3/Theora. Order matters
- * because some pixels get filtered twice. */
- if (s->all_fragments[fragment].coding_method != MODE_COPY) {
- /* do not perform left edge filter for left columns frags */
- if (x > 0) {
- s->vp3dsp.h_loop_filter(
- plane_data + 8 * x,
- stride, bounding_values);
- }
-
- /* do not perform top edge filter for top row fragments */
- if (y > 0) {
- s->vp3dsp.v_loop_filter(
- plane_data + 8 * x,
- stride, bounding_values);
- }
-
- /* do not perform right edge filter for right column
- * fragments or if right fragment neighbor is also coded
- * in this frame (it will be filtered in next iteration) */
- if ((x < width - 1) &&
- (s->all_fragments[fragment + 1].coding_method == MODE_COPY)) {
- s->vp3dsp.h_loop_filter(
- plane_data + 8 * x + 8,
- stride, bounding_values);
- }
-
- /* do not perform bottom edge filter for bottom row
- * fragments or if bottom fragment neighbor is also coded
- * in this frame (it will be filtered in the next row) */
- if ((y < height - 1) &&
- (s->all_fragments[fragment + width].coding_method == MODE_COPY)) {
- s->vp3dsp.v_loop_filter(
- plane_data + 8 * x + 8 * stride,
- stride, bounding_values);
- }
- }
-
- fragment++;
- }
- plane_data += 8 * stride;
- }
-}
-
-/**
- * Pull DCT tokens from the 64 levels to decode and dequant the coefficients
- * for the next block in coding order
- */
-static inline int vp3_dequant(Vp3DecodeContext *s, Vp3Fragment *frag,
- int plane, int inter, int16_t block[64])
-{
- int16_t *dequantizer = s->qmat[frag->qpi][inter][plane];
- uint8_t *perm = s->idct_scantable;
- int i = 0;
-
- do {
- int token = *s->dct_tokens[plane][i];
- switch (token & 3) {
- case 0: // EOB
- if (--token < 4) // 0-3 are token types so the EOB run must now be 0
- s->dct_tokens[plane][i]++;
- else
- *s->dct_tokens[plane][i] = token & ~3;
- goto end;
- case 1: // zero run
- s->dct_tokens[plane][i]++;
- i += (token >> 2) & 0x7f;
- if (i > 63) {
- av_log(s->avctx, AV_LOG_ERROR, "Coefficient index overflow\n");
- return i;
- }
- block[perm[i]] = (token >> 9) * dequantizer[perm[i]];
- i++;
- break;
- case 2: // coeff
- block[perm[i]] = (token >> 2) * dequantizer[perm[i]];
- s->dct_tokens[plane][i++]++;
- break;
- default: // shouldn't happen
- return i;
- }
- } while (i < 64);
- // return value is expected to be a valid level
- i--;
-end:
- // the actual DC+prediction is in the fragment structure
- block[0] = frag->dc * s->qmat[0][inter][plane][0];
- return i;
-}
-
-/**
- * called when all pixels up to row y are complete
- */
-static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
-{
- int h, cy, i;
- int offset[AV_NUM_DATA_POINTERS];
-
- if (HAVE_THREADS && s->avctx->active_thread_type & FF_THREAD_FRAME) {
- int y_flipped = s->flipped_image ? s->height - y : y;
-
- /* At the end of the frame, report INT_MAX instead of the height of
- * the frame. This makes the other threads' ff_thread_await_progress()
- * calls cheaper, because they don't have to clip their values. */
- ff_thread_report_progress(&s->current_frame,
- y_flipped == s->height ? INT_MAX
- : y_flipped - 1,
- 0);
- }
-
- if (!s->avctx->draw_horiz_band)
- return;
-
- h = y - s->last_slice_end;
- s->last_slice_end = y;
- y -= h;
-
- if (!s->flipped_image)
- y = s->height - y - h;
-
- cy = y >> s->chroma_y_shift;
- offset[0] = s->current_frame.f->linesize[0] * y;
- offset[1] = s->current_frame.f->linesize[1] * cy;
- offset[2] = s->current_frame.f->linesize[2] * cy;
- for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
- offset[i] = 0;
-
- emms_c();
- s->avctx->draw_horiz_band(s->avctx, s->current_frame.f, offset, y, 3, h);
-}
-
-/**
- * Wait for the reference frame of the current fragment.
- * The progress value is in luma pixel rows.
- */
-static void await_reference_row(Vp3DecodeContext *s, Vp3Fragment *fragment,
- int motion_y, int y)
-{
- ThreadFrame *ref_frame;
- int ref_row;
- int border = motion_y & 1;
-
- if (fragment->coding_method == MODE_USING_GOLDEN ||
- fragment->coding_method == MODE_GOLDEN_MV)
- ref_frame = &s->golden_frame;
- else
- ref_frame = &s->last_frame;
-
- ref_row = y + (motion_y >> 1);
- ref_row = FFMAX(FFABS(ref_row), ref_row + 8 + border);
-
- ff_thread_await_progress(ref_frame, ref_row, 0);
-}
-
-/*
- * Perform the final rendering for a particular slice of data.
- * The slice number ranges from 0..(c_superblock_height - 1).
- */
-static void render_slice(Vp3DecodeContext *s, int slice)
-{
- int x, y, i, j, fragment;
- int16_t *block = s->block;
- int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef;
- int motion_halfpel_index;
- uint8_t *motion_source;
- int plane, first_pixel;
-
- if (slice >= s->c_superblock_height)
- return;
-
- for (plane = 0; plane < 3; plane++) {
- uint8_t *output_plane = s->current_frame.f->data[plane] +
- s->data_offset[plane];
- uint8_t *last_plane = s->last_frame.f->data[plane] +
- s->data_offset[plane];
- uint8_t *golden_plane = s->golden_frame.f->data[plane] +
- s->data_offset[plane];
- ptrdiff_t stride = s->current_frame.f->linesize[plane];
- int plane_width = s->width >> (plane && s->chroma_x_shift);
- int plane_height = s->height >> (plane && s->chroma_y_shift);
- int8_t(*motion_val)[2] = s->motion_val[!!plane];
-
- int sb_x, sb_y = slice << (!plane && s->chroma_y_shift);
- int slice_height = sb_y + 1 + (!plane && s->chroma_y_shift);
- int slice_width = plane ? s->c_superblock_width
- : s->y_superblock_width;
-
- int fragment_width = s->fragment_width[!!plane];
- int fragment_height = s->fragment_height[!!plane];
- int fragment_start = s->fragment_start[plane];
-
- int do_await = !plane && HAVE_THREADS &&
- (s->avctx->active_thread_type & FF_THREAD_FRAME);
-
- if (!s->flipped_image)
- stride = -stride;
- if (CONFIG_GRAY && plane && (s->avctx->flags & AV_CODEC_FLAG_GRAY))
- continue;
-
- /* for each superblock row in the slice (both of them)... */
- for (; sb_y < slice_height; sb_y++) {
- /* for each superblock in a row... */
- for (sb_x = 0; sb_x < slice_width; sb_x++) {
- /* for each block in a superblock... */
- for (j = 0; j < 16; j++) {
- x = 4 * sb_x + hilbert_offset[j][0];
- y = 4 * sb_y + hilbert_offset[j][1];
- fragment = y * fragment_width + x;
-
- i = fragment_start + fragment;
-
- // bounds check
- if (x >= fragment_width || y >= fragment_height)
- continue;
-
- first_pixel = 8 * y * stride + 8 * x;
-
- if (do_await &&
- s->all_fragments[i].coding_method != MODE_INTRA)
- await_reference_row(s, &s->all_fragments[i],
- motion_val[fragment][1],
- (16 * y) >> s->chroma_y_shift);
-
- /* transform if this block was coded */
- if (s->all_fragments[i].coding_method != MODE_COPY) {
- if ((s->all_fragments[i].coding_method == MODE_USING_GOLDEN) ||
- (s->all_fragments[i].coding_method == MODE_GOLDEN_MV))
- motion_source = golden_plane;
- else
- motion_source = last_plane;
-
- motion_source += first_pixel;
- motion_halfpel_index = 0;
-
- /* sort out the motion vector if this fragment is coded
- * using a motion vector method */
- if ((s->all_fragments[i].coding_method > MODE_INTRA) &&
- (s->all_fragments[i].coding_method != MODE_USING_GOLDEN)) {
- int src_x, src_y;
- motion_x = motion_val[fragment][0];
- motion_y = motion_val[fragment][1];
-
- src_x = (motion_x >> 1) + 8 * x;
- src_y = (motion_y >> 1) + 8 * y;
-
- motion_halfpel_index = motion_x & 0x01;
- motion_source += (motion_x >> 1);
-
- motion_halfpel_index |= (motion_y & 0x01) << 1;
- motion_source += ((motion_y >> 1) * stride);
-
- if (src_x < 0 || src_y < 0 ||
- src_x + 9 >= plane_width ||
- src_y + 9 >= plane_height) {
- uint8_t *temp = s->edge_emu_buffer;
- if (stride < 0)
- temp -= 8 * stride;
-
- s->vdsp.emulated_edge_mc(temp, motion_source,
- stride, stride,
- 9, 9, src_x, src_y,
- plane_width,
- plane_height);
- motion_source = temp;
- }
- }
-
- /* first, take care of copying a block from either the
- * previous or the golden frame */
- if (s->all_fragments[i].coding_method != MODE_INTRA) {
- /* Note, it is possible to implement all MC cases
- * with put_no_rnd_pixels_l2 which would look more
- * like the VP3 source but this would be slower as
- * put_no_rnd_pixels_tab is better optimzed */
- if (motion_halfpel_index != 3) {
- s->hdsp.put_no_rnd_pixels_tab[1][motion_halfpel_index](
- output_plane + first_pixel,
- motion_source, stride, 8);
- } else {
- /* d is 0 if motion_x and _y have the same sign,
- * else -1 */
- int d = (motion_x ^ motion_y) >> 31;
- s->vp3dsp.put_no_rnd_pixels_l2(output_plane + first_pixel,
- motion_source - d,
- motion_source + stride + 1 + d,
- stride, 8);
- }
- }
-
- /* invert DCT and place (or add) in final output */
-
- if (s->all_fragments[i].coding_method == MODE_INTRA) {
- vp3_dequant(s, s->all_fragments + i,
- plane, 0, block);
- s->vp3dsp.idct_put(output_plane + first_pixel,
- stride,
- block);
- } else {
- if (vp3_dequant(s, s->all_fragments + i,
- plane, 1, block)) {
- s->vp3dsp.idct_add(output_plane + first_pixel,
- stride,
- block);
- } else {
- s->vp3dsp.idct_dc_add(output_plane + first_pixel,
- stride, block);
- }
- }
- } else {
- /* copy directly from the previous frame */
- s->hdsp.put_pixels_tab[1][0](
- output_plane + first_pixel,
- last_plane + first_pixel,
- stride, 8);
- }
- }
- }
-
- // Filter up to the last row in the superblock row
- if (!s->skip_loop_filter)
- apply_loop_filter(s, plane, 4 * sb_y - !!sb_y,
- FFMIN(4 * sb_y + 3, fragment_height - 1));
- }
- }
-
- /* this looks like a good place for slice dispatch... */
- /* algorithm:
- * if (slice == s->macroblock_height - 1)
- * dispatch (both last slice & 2nd-to-last slice);
- * else if (slice > 0)
- * dispatch (slice - 1);
- */
-
- vp3_draw_horiz_band(s, FFMIN((32 << s->chroma_y_shift) * (slice + 1) - 16,
- s->height - 16));
-}
-
-/// Allocate tables for per-frame data in Vp3DecodeContext
-static av_cold int allocate_tables(AVCodecContext *avctx)
-{
- Vp3DecodeContext *s = avctx->priv_data;
- int y_fragment_count, c_fragment_count;
-
- free_tables(avctx);
-
- y_fragment_count = s->fragment_width[0] * s->fragment_height[0];
- c_fragment_count = s->fragment_width[1] * s->fragment_height[1];
-
- s->superblock_coding = av_mallocz(s->superblock_count);
- s->all_fragments = av_mallocz_array(s->fragment_count, sizeof(Vp3Fragment));
-
- s->coded_fragment_list[0] = av_mallocz_array(s->fragment_count, sizeof(int));
-
- s->dct_tokens_base = av_mallocz_array(s->fragment_count,
- 64 * sizeof(*s->dct_tokens_base));
- s->motion_val[0] = av_mallocz_array(y_fragment_count, sizeof(*s->motion_val[0]));
- s->motion_val[1] = av_mallocz_array(c_fragment_count, sizeof(*s->motion_val[1]));
-
- /* work out the block mapping tables */
- s->superblock_fragments = av_mallocz_array(s->superblock_count, 16 * sizeof(int));
- s->macroblock_coding = av_mallocz(s->macroblock_count + 1);
-
- if (!s->superblock_coding || !s->all_fragments ||
- !s->dct_tokens_base || !s->coded_fragment_list[0] ||
- !s->superblock_fragments || !s->macroblock_coding ||
- !s->motion_val[0] || !s->motion_val[1]) {
- vp3_decode_end(avctx);
- return -1;
- }
-
- init_block_mapping(s);
-
- return 0;
-}
-
-static av_cold int init_frames(Vp3DecodeContext *s)
-{
- s->current_frame.f = av_frame_alloc();
- 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);
- return AVERROR(ENOMEM);
- }
-
- return 0;
-}
-
-static av_cold int vp3_decode_init(AVCodecContext *avctx)
-{
- Vp3DecodeContext *s = avctx->priv_data;
- int i, inter, plane, ret;
- int c_width;
- int c_height;
- int y_fragment_count, c_fragment_count;
-
- ret = init_frames(s);
- if (ret < 0)
- return ret;
-
- avctx->internal->allocate_progress = 1;
-
- if (avctx->codec_tag == MKTAG('V', 'P', '3', '0'))
- s->version = 0;
- else
- s->version = 1;
-
- s->avctx = avctx;
- s->width = FFALIGN(avctx->coded_width, 16);
- s->height = FFALIGN(avctx->coded_height, 16);
- if (avctx->codec_id != AV_CODEC_ID_THEORA)
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
- ff_hpeldsp_init(&s->hdsp, avctx->flags | AV_CODEC_FLAG_BITEXACT);
- ff_videodsp_init(&s->vdsp, 8);
- ff_vp3dsp_init(&s->vp3dsp, avctx->flags);
-
- for (i = 0; i < 64; i++) {
-#define TRANSPOSE(x) (((x) >> 3) | (((x) & 7) << 3))
- s->idct_permutation[i] = TRANSPOSE(i);
- s->idct_scantable[i] = TRANSPOSE(ff_zigzag_direct[i]);
-#undef TRANSPOSE
- }
-
- /* initialize to an impossible value which will force a recalculation
- * in the first frame decode */
- for (i = 0; i < 3; i++)
- s->qps[i] = -1;
-
- avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift);
-
- s->y_superblock_width = (s->width + 31) / 32;
- s->y_superblock_height = (s->height + 31) / 32;
- s->y_superblock_count = s->y_superblock_width * s->y_superblock_height;
-
- /* work out the dimensions for the C planes */
- c_width = s->width >> s->chroma_x_shift;
- c_height = s->height >> s->chroma_y_shift;
- s->c_superblock_width = (c_width + 31) / 32;
- s->c_superblock_height = (c_height + 31) / 32;
- s->c_superblock_count = s->c_superblock_width * s->c_superblock_height;
-
- s->superblock_count = s->y_superblock_count + (s->c_superblock_count * 2);
- s->u_superblock_start = s->y_superblock_count;
- s->v_superblock_start = s->u_superblock_start + s->c_superblock_count;
-
- s->macroblock_width = (s->width + 15) / 16;
- s->macroblock_height = (s->height + 15) / 16;
- s->macroblock_count = s->macroblock_width * s->macroblock_height;
-
- s->fragment_width[0] = s->width / FRAGMENT_PIXELS;
- s->fragment_height[0] = s->height / FRAGMENT_PIXELS;
- s->fragment_width[1] = s->fragment_width[0] >> s->chroma_x_shift;
- s->fragment_height[1] = s->fragment_height[0] >> s->chroma_y_shift;
-
- /* fragment count covers all 8x8 blocks for all 3 planes */
- y_fragment_count = s->fragment_width[0] * s->fragment_height[0];
- c_fragment_count = s->fragment_width[1] * s->fragment_height[1];
- s->fragment_count = y_fragment_count + 2 * c_fragment_count;
- s->fragment_start[1] = y_fragment_count;
- s->fragment_start[2] = y_fragment_count + c_fragment_count;
-
- if (!s->theora_tables) {
- for (i = 0; i < 64; i++) {
- s->coded_dc_scale_factor[i] = vp31_dc_scale_factor[i];
- s->coded_ac_scale_factor[i] = vp31_ac_scale_factor[i];
- s->base_matrix[0][i] = vp31_intra_y_dequant[i];
- s->base_matrix[1][i] = vp31_intra_c_dequant[i];
- s->base_matrix[2][i] = vp31_inter_dequant[i];
- s->filter_limit_values[i] = vp31_filter_limit_values[i];
- }
-
- for (inter = 0; inter < 2; inter++) {
- for (plane = 0; plane < 3; plane++) {
- s->qr_count[inter][plane] = 1;
- s->qr_size[inter][plane][0] = 63;
- s->qr_base[inter][plane][0] =
- s->qr_base[inter][plane][1] = 2 * inter + (!!plane) * !inter;
- }
- }
-
- /* init VLC tables */
- 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);
- }
- } 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;
-
- /* 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;
- }
- }
-
- 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);
-
- 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);
-
- 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);
-
- 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);
-
- 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
-static int update_frames(AVCodecContext *avctx)
-{
- Vp3DecodeContext *s = avctx->priv_data;
- int ret = 0;
-
- /* shuffle frames (last = current) */
- ff_thread_release_buffer(avctx, &s->last_frame);
- ret = ff_thread_ref_frame(&s->last_frame, &s->current_frame);
- if (ret < 0)
- goto fail;
-
- if (s->keyframe) {
- ff_thread_release_buffer(avctx, &s->golden_frame);
- ret = ff_thread_ref_frame(&s->golden_frame, &s->current_frame);
- }
-
-fail:
- ff_thread_release_buffer(avctx, &s->current_frame);
- return ret;
-}
-
-static int ref_frame(Vp3DecodeContext *s, ThreadFrame *dst, ThreadFrame *src)
-{
- ff_thread_release_buffer(s->avctx, dst);
- if (src->f->data[0])
- return ff_thread_ref_frame(dst, src);
- return 0;
-}
-
-static int ref_frames(Vp3DecodeContext *dst, Vp3DecodeContext *src)
-{
- int ret;
- if ((ret = ref_frame(dst, &dst->current_frame, &src->current_frame)) < 0 ||
- (ret = ref_frame(dst, &dst->golden_frame, &src->golden_frame)) < 0 ||
- (ret = ref_frame(dst, &dst->last_frame, &src->last_frame)) < 0)
- return ret;
- return 0;
-}
-
-static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
-{
- Vp3DecodeContext *s = dst->priv_data, *s1 = src->priv_data;
- int qps_changed = 0, i, err;
-
-#define copy_fields(to, from, start_field, end_field) \
- memcpy(&to->start_field, &from->start_field, \
- (char *) &to->end_field - (char *) &to->start_field)
-
- if (!s1->current_frame.f->data[0] ||
- s->width != s1->width || s->height != s1->height) {
- if (s != s1)
- ref_frames(s, s1);
- return -1;
- }
-
- if (s != s1) {
- if (!s->current_frame.f)
- return AVERROR(ENOMEM);
- // init tables if the first frame hasn't been decoded
- if (!s->current_frame.f->data[0]) {
- int y_fragment_count, c_fragment_count;
- s->avctx = dst;
- err = allocate_tables(dst);
- if (err)
- return err;
- y_fragment_count = s->fragment_width[0] * s->fragment_height[0];
- c_fragment_count = s->fragment_width[1] * s->fragment_height[1];
- memcpy(s->motion_val[0], s1->motion_val[0],
- y_fragment_count * sizeof(*s->motion_val[0]));
- memcpy(s->motion_val[1], s1->motion_val[1],
- c_fragment_count * sizeof(*s->motion_val[1]));
- }
-
- // copy previous frame data
- if ((err = ref_frames(s, s1)) < 0)
- return err;
-
- s->keyframe = s1->keyframe;
-
- // copy qscale data if necessary
- for (i = 0; i < 3; i++) {
- if (s->qps[i] != s1->qps[1]) {
- qps_changed = 1;
- memcpy(&s->qmat[i], &s1->qmat[i], sizeof(s->qmat[i]));
- }
- }
-
- if (s->qps[0] != s1->qps[0])
- memcpy(&s->bounding_values_array, &s1->bounding_values_array,
- sizeof(s->bounding_values_array));
-
- if (qps_changed)
- copy_fields(s, s1, qps, superblock_count);
-#undef copy_fields
- }
-
- return update_frames(dst);
-}
-
-static int vp3_decode_frame(AVCodecContext *avctx,
- void *data, int *got_frame,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- Vp3DecodeContext *s = avctx->priv_data;
- GetBitContext gb;
- int i, ret;
-
- if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0)
- return ret;
-
-#if CONFIG_THEORA_DECODER
- if (s->theora && get_bits1(&gb)) {
- int type = get_bits(&gb, 7);
- skip_bits_long(&gb, 6*8); /* "theora" */
-
- if (s->avctx->active_thread_type&FF_THREAD_FRAME) {
- av_log(avctx, AV_LOG_ERROR, "midstream reconfiguration with multithreading is unsupported, try -threads 1\n");
- return AVERROR_PATCHWELCOME;
- }
- if (type == 0) {
- vp3_decode_end(avctx);
- ret = theora_decode_header(avctx, &gb);
-
- if (ret >= 0)
- ret = vp3_decode_init(avctx);
- if (ret < 0) {
- vp3_decode_end(avctx);
- }
- return ret;
- } else if (type == 2) {
- ret = theora_decode_tables(avctx, &gb);
- if (ret >= 0)
- ret = vp3_decode_init(avctx);
- if (ret < 0) {
- vp3_decode_end(avctx);
- }
- return ret;
- }
-
- av_log(avctx, AV_LOG_ERROR,
- "Header packet passed to frame decoder, skipping\n");
- return -1;
- }
-#endif
-
- s->keyframe = !get_bits1(&gb);
- if (!s->all_fragments) {
- av_log(avctx, AV_LOG_ERROR, "Data packet without prior valid headers\n");
- return -1;
- }
- if (!s->theora)
- skip_bits(&gb, 1);
- for (i = 0; i < 3; i++)
- s->last_qps[i] = s->qps[i];
-
- s->nqps = 0;
- do {
- s->qps[s->nqps++] = get_bits(&gb, 6);
- } while (s->theora >= 0x030200 && s->nqps < 3 && get_bits1(&gb));
- for (i = s->nqps; i < 3; i++)
- s->qps[i] = -1;
-
- if (s->avctx->debug & FF_DEBUG_PICT_INFO)
- av_log(s->avctx, AV_LOG_INFO, " VP3 %sframe #%d: Q index = %d\n",
- s->keyframe ? "key" : "", avctx->frame_number + 1, s->qps[0]);
-
- s->skip_loop_filter = !s->filter_limit_values[s->qps[0]] ||
- avctx->skip_loop_filter >= (s->keyframe ? AVDISCARD_ALL
- : AVDISCARD_NONKEY);
-
- if (s->qps[0] != s->last_qps[0])
- init_loop_filter(s);
-
- for (i = 0; i < s->nqps; i++)
- // reinit all dequantizers if the first one changed, because
- // the DC of the first quantizer must be used for all matrices
- if (s->qps[i] != s->last_qps[i] || s->qps[0] != s->last_qps[0])
- init_dequantizer(s, i);
-
- if (avctx->skip_frame >= AVDISCARD_NONKEY && !s->keyframe)
- return buf_size;
-
- s->current_frame.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I
- : AV_PICTURE_TYPE_P;
- s->current_frame.f->key_frame = s->keyframe;
- if (ff_thread_get_buffer(avctx, &s->current_frame, AV_GET_BUFFER_FLAG_REF) < 0)
- goto error;
-
- if (!s->edge_emu_buffer)
- s->edge_emu_buffer = av_malloc(9 * FFABS(s->current_frame.f->linesize[0]));
-
- if (s->keyframe) {
- if (!s->theora) {
- skip_bits(&gb, 4); /* width code */
- skip_bits(&gb, 4); /* height code */
- if (s->version) {
- s->version = get_bits(&gb, 5);
- if (avctx->frame_number == 0)
- av_log(s->avctx, AV_LOG_DEBUG,
- "VP version: %d\n", s->version);
- }
- }
- if (s->version || s->theora) {
- if (get_bits1(&gb))
- av_log(s->avctx, AV_LOG_ERROR,
- "Warning, unsupported keyframe coding type?!\n");
- skip_bits(&gb, 2); /* reserved? */
- }
- } else {
- if (!s->golden_frame.f->data[0]) {
- av_log(s->avctx, AV_LOG_WARNING,
- "vp3: first frame not a keyframe\n");
-
- s->golden_frame.f->pict_type = AV_PICTURE_TYPE_I;
- if (ff_thread_get_buffer(avctx, &s->golden_frame,
- AV_GET_BUFFER_FLAG_REF) < 0)
- goto error;
- ff_thread_release_buffer(avctx, &s->last_frame);
- if ((ret = ff_thread_ref_frame(&s->last_frame,
- &s->golden_frame)) < 0)
- goto error;
- ff_thread_report_progress(&s->last_frame, INT_MAX, 0);
- }
- }
-
- memset(s->all_fragments, 0, s->fragment_count * sizeof(Vp3Fragment));
- ff_thread_finish_setup(avctx);
-
- if (unpack_superblocks(s, &gb)) {
- av_log(s->avctx, AV_LOG_ERROR, "error in unpack_superblocks\n");
- goto error;
- }
- if (unpack_modes(s, &gb)) {
- av_log(s->avctx, AV_LOG_ERROR, "error in unpack_modes\n");
- goto error;
- }
- if (unpack_vectors(s, &gb)) {
- av_log(s->avctx, AV_LOG_ERROR, "error in unpack_vectors\n");
- goto error;
- }
- if (unpack_block_qpis(s, &gb)) {
- av_log(s->avctx, AV_LOG_ERROR, "error in unpack_block_qpis\n");
- goto error;
- }
- if (unpack_dct_coeffs(s, &gb)) {
- av_log(s->avctx, AV_LOG_ERROR, "error in unpack_dct_coeffs\n");
- goto error;
- }
-
- for (i = 0; i < 3; i++) {
- int height = s->height >> (i && s->chroma_y_shift);
- if (s->flipped_image)
- s->data_offset[i] = 0;
- else
- s->data_offset[i] = (height - 1) * s->current_frame.f->linesize[i];
- }
-
- s->last_slice_end = 0;
- for (i = 0; i < s->c_superblock_height; i++)
- render_slice(s, i);
-
- // filter the last row
- for (i = 0; i < 3; i++) {
- int row = (s->height >> (3 + (i && s->chroma_y_shift))) - 1;
- apply_loop_filter(s, i, row, row + 1);
- }
- vp3_draw_horiz_band(s, s->height);
-
- /* output frame, offset as needed */
- if ((ret = av_frame_ref(data, s->current_frame.f)) < 0)
- return ret;
- for (i = 0; i < 3; i++) {
- AVFrame *dst = data;
- int off = (s->offset_x >> (i && s->chroma_y_shift)) +
- (s->offset_y >> (i && s->chroma_y_shift)) * dst->linesize[i];
- dst->data[i] += off;
- }
- *got_frame = 1;
-
- if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_FRAME)) {
- ret = update_frames(avctx);
- if (ret < 0)
- return ret;
- }
-
- return buf_size;
-
-error:
- ff_thread_report_progress(&s->current_frame, INT_MAX, 0);
-
- if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_FRAME))
- av_frame_unref(s->current_frame.f);
-
- return -1;
-}
-
-static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb)
-{
- Vp3DecodeContext *s = avctx->priv_data;
-
- if (get_bits1(gb)) {
- int token;
- if (s->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++;
- } else {
- if (s->huff_code_size >= 32) { /* 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))
- return -1;
- s->hbits |= 1;
- if (read_huffman_tree(avctx, gb))
- return -1;
- s->hbits >>= 1;
- s->huff_code_size--;
- }
- return 0;
-}
-
-static int vp3_init_thread_copy(AVCodecContext *avctx)
-{
- Vp3DecodeContext *s = avctx->priv_data;
-
- s->superblock_coding = NULL;
- s->all_fragments = NULL;
- s->coded_fragment_list[0] = NULL;
- s->dct_tokens_base = NULL;
- s->superblock_fragments = NULL;
- s->macroblock_coding = NULL;
- s->motion_val[0] = NULL;
- s->motion_val[1] = NULL;
- s->edge_emu_buffer = NULL;
-
- return init_frames(s);
-}
-
-#if CONFIG_THEORA_DECODER
-static const enum AVPixelFormat theora_pix_fmts[4] = {
- AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P
-};
-
-static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
-{
- Vp3DecodeContext *s = avctx->priv_data;
- int visible_width, visible_height, colorspace;
- uint8_t offset_x = 0, offset_y = 0;
- int ret;
- AVRational fps, aspect;
-
- s->theora_header = 0;
- s->theora = get_bits_long(gb, 24);
- av_log(avctx, AV_LOG_DEBUG, "Theora bitstream version %X\n", s->theora);
-
- /* 3.2.0 aka alpha3 has the same frame orientation as original vp3
- * but previous versions have the image flipped relative to vp3 */
- if (s->theora < 0x030200) {
- s->flipped_image = 1;
- av_log(avctx, AV_LOG_DEBUG,
- "Old (<alpha3) Theora bitstream, flipped image\n");
- }
-
- visible_width =
- s->width = get_bits(gb, 16) << 4;
- visible_height =
- s->height = get_bits(gb, 16) << 4;
-
- if (s->theora >= 0x030200) {
- visible_width = get_bits_long(gb, 24);
- visible_height = get_bits_long(gb, 24);
-
- offset_x = get_bits(gb, 8); /* offset x */
- offset_y = get_bits(gb, 8); /* offset y, from bottom */
- }
-
- /* sanity check */
- if (av_image_check_size(visible_width, visible_height, 0, avctx) < 0 ||
- visible_width + offset_x > s->width ||
- visible_height + offset_y > s->height) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid frame dimensions - w:%d h:%d x:%d y:%d (%dx%d).\n",
- visible_width, visible_height, offset_x, offset_y,
- s->width, s->height);
- return AVERROR_INVALIDDATA;
- }
-
- fps.num = get_bits_long(gb, 32);
- fps.den = get_bits_long(gb, 32);
- if (fps.num && fps.den) {
- if (fps.num < 0 || fps.den < 0) {
- av_log(avctx, AV_LOG_ERROR, "Invalid framerate\n");
- return AVERROR_INVALIDDATA;
- }
- av_reduce(&avctx->framerate.den, &avctx->framerate.num,
- fps.den, fps.num, 1 << 30);
- }
-
- aspect.num = get_bits_long(gb, 24);
- aspect.den = get_bits_long(gb, 24);
- if (aspect.num && aspect.den) {
- av_reduce(&avctx->sample_aspect_ratio.num,
- &avctx->sample_aspect_ratio.den,
- aspect.num, aspect.den, 1 << 30);
- ff_set_sar(avctx, avctx->sample_aspect_ratio);
- }
-
- if (s->theora < 0x030200)
- skip_bits(gb, 5); /* keyframe frequency force */
- colorspace = get_bits(gb, 8);
- skip_bits(gb, 24); /* bitrate */
-
- skip_bits(gb, 6); /* quality hint */
-
- if (s->theora >= 0x030200) {
- skip_bits(gb, 5); /* keyframe frequency force */
- avctx->pix_fmt = theora_pix_fmts[get_bits(gb, 2)];
- if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
- av_log(avctx, AV_LOG_ERROR, "Invalid pixel format\n");
- return AVERROR_INVALIDDATA;
- }
- skip_bits(gb, 3); /* reserved */
- } else
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
-
- ret = ff_set_dimensions(avctx, s->width, s->height);
- if (ret < 0)
- return ret;
- if (!(avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP)) {
- avctx->width = visible_width;
- avctx->height = visible_height;
- // translate offsets from theora axis ([0,0] lower left)
- // to normal axis ([0,0] upper left)
- s->offset_x = offset_x;
- s->offset_y = s->height - visible_height - offset_y;
-
- if ((s->offset_x & 0x1F) && !(avctx->flags & AV_CODEC_FLAG_UNALIGNED)) {
- s->offset_x &= ~0x1F;
- if (!s->offset_x_warned) {
- s->offset_x_warned = 1;
- av_log(avctx, AV_LOG_WARNING, "Reducing offset_x from %d to %d"
- "chroma samples to preserve alignment.\n",
- offset_x, s->offset_x);
- }
- }
- }
-
- if (colorspace == 1)
- avctx->color_primaries = AVCOL_PRI_BT470M;
- else if (colorspace == 2)
- avctx->color_primaries = AVCOL_PRI_BT470BG;
-
- if (colorspace == 1 || colorspace == 2) {
- avctx->colorspace = AVCOL_SPC_BT470BG;
- avctx->color_trc = AVCOL_TRC_BT709;
- }
-
- s->theora_header = 1;
- return 0;
-}
-
-static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb)
-{
- Vp3DecodeContext *s = avctx->priv_data;
- int i, n, matrices, inter, plane;
-
- if (!s->theora_header)
- return AVERROR_INVALIDDATA;
-
- if (s->theora >= 0x030200) {
- n = get_bits(gb, 3);
- /* loop filter limit values table */
- if (n)
- for (i = 0; i < 64; i++)
- s->filter_limit_values[i] = get_bits(gb, n);
- }
-
- if (s->theora >= 0x030200)
- n = get_bits(gb, 4) + 1;
- else
- n = 16;
- /* quality threshold table */
- for (i = 0; i < 64; i++)
- s->coded_ac_scale_factor[i] = get_bits(gb, n);
-
- if (s->theora >= 0x030200)
- n = get_bits(gb, 4) + 1;
- else
- n = 16;
- /* dc scale factor table */
- for (i = 0; i < 64; i++)
- s->coded_dc_scale_factor[i] = get_bits(gb, n);
-
- if (s->theora >= 0x030200)
- matrices = get_bits(gb, 9) + 1;
- else
- matrices = 3;
-
- if (matrices > 384) {
- av_log(avctx, AV_LOG_ERROR, "invalid number of base matrixes\n");
- return -1;
- }
-
- for (n = 0; n < matrices; n++)
- for (i = 0; i < 64; i++)
- s->base_matrix[n][i] = get_bits(gb, 8);
-
- for (inter = 0; inter <= 1; inter++) {
- for (plane = 0; plane <= 2; plane++) {
- int newqr = 1;
- if (inter || plane > 0)
- newqr = get_bits1(gb);
- if (!newqr) {
- int qtj, plj;
- if (inter && get_bits1(gb)) {
- qtj = 0;
- plj = plane;
- } else {
- qtj = (3 * inter + plane - 1) / 3;
- plj = (plane + 2) % 3;
- }
- s->qr_count[inter][plane] = s->qr_count[qtj][plj];
- memcpy(s->qr_size[inter][plane], s->qr_size[qtj][plj],
- sizeof(s->qr_size[0][0]));
- memcpy(s->qr_base[inter][plane], s->qr_base[qtj][plj],
- sizeof(s->qr_base[0][0]));
- } else {
- int qri = 0;
- int qi = 0;
-
- for (;;) {
- i = get_bits(gb, av_log2(matrices - 1) + 1);
- if (i >= matrices) {
- av_log(avctx, AV_LOG_ERROR,
- "invalid base matrix index\n");
- return -1;
- }
- s->qr_base[inter][plane][qri] = i;
- if (qi >= 63)
- break;
- i = get_bits(gb, av_log2(63 - qi) + 1) + 1;
- s->qr_size[inter][plane][qri++] = i;
- qi += i;
- }
-
- if (qi > 63) {
- av_log(avctx, AV_LOG_ERROR, "invalid qi %d > 63\n", qi);
- return -1;
- }
- s->qr_count[inter][plane] = qri;
- }
- }
- }
-
- /* 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;
- }
- }
-
- s->theora_tables = 1;
-
- return 0;
-}
-
-static av_cold int theora_decode_init(AVCodecContext *avctx)
-{
- Vp3DecodeContext *s = avctx->priv_data;
- GetBitContext gb;
- int ptype;
- const uint8_t *header_start[3];
- int header_len[3];
- int i;
- int ret;
-
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
-
- s->theora = 1;
-
- if (!avctx->extradata_size) {
- av_log(avctx, AV_LOG_ERROR, "Missing extradata!\n");
- return -1;
- }
-
- if (avpriv_split_xiph_headers(avctx->extradata, avctx->extradata_size,
- 42, header_start, header_len) < 0) {
- av_log(avctx, AV_LOG_ERROR, "Corrupt extradata\n");
- return -1;
- }
-
- for (i = 0; i < 3; i++) {
- if (header_len[i] <= 0)
- continue;
- ret = init_get_bits8(&gb, header_start[i], header_len[i]);
- if (ret < 0)
- return ret;
-
- ptype = get_bits(&gb, 8);
-
- if (!(ptype & 0x80)) {
- av_log(avctx, AV_LOG_ERROR, "Invalid extradata!\n");
-// return -1;
- }
-
- // FIXME: Check for this as well.
- skip_bits_long(&gb, 6 * 8); /* "theora" */
-
- switch (ptype) {
- case 0x80:
- if (theora_decode_header(avctx, &gb) < 0)
- return -1;
- break;
- case 0x81:
-// FIXME: is this needed? it breaks sometimes
-// theora_decode_comments(avctx, gb);
- break;
- case 0x82:
- if (theora_decode_tables(avctx, &gb))
- return -1;
- break;
- default:
- av_log(avctx, AV_LOG_ERROR,
- "Unknown Theora config packet: %d\n", ptype & ~0x80);
- break;
- }
- if (ptype != 0x81 && 8 * header_len[i] != get_bits_count(&gb))
- av_log(avctx, AV_LOG_WARNING,
- "%d bits left in packet %X\n",
- 8 * header_len[i] - get_bits_count(&gb), ptype);
- if (s->theora < 0x030200)
- break;
- }
-
- return vp3_decode_init(avctx);
-}
-
-AVCodec ff_theora_decoder = {
- .name = "theora",
- .long_name = NULL_IF_CONFIG_SMALL("Theora"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_THEORA,
- .priv_data_size = sizeof(Vp3DecodeContext),
- .init = theora_decode_init,
- .close = vp3_decode_end,
- .decode = vp3_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
- AV_CODEC_CAP_FRAME_THREADS,
- .flush = vp3_decode_flush,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy),
- .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context)
-};
-#endif
-
-AVCodec ff_vp3_decoder = {
- .name = "vp3",
- .long_name = NULL_IF_CONFIG_SMALL("On2 VP3"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_VP3,
- .priv_data_size = sizeof(Vp3DecodeContext),
- .init = vp3_decode_init,
- .close = vp3_decode_end,
- .decode = vp3_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
- AV_CODEC_CAP_FRAME_THREADS,
- .flush = vp3_decode_flush,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy),
- .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context),
-};
diff --git a/ffmpeg-2-8-11/libavcodec/vp3dsp.c b/ffmpeg-2-8-11/libavcodec/vp3dsp.c
deleted file mode 100644
index d8a3e0a..0000000
--- a/ffmpeg-2-8-11/libavcodec/vp3dsp.c
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (c) 2004 The FFmpeg Project
- *
- * 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
- * Standard C DSP-oriented functions cribbed from the original VP3
- * source code.
- */
-
-#include "libavutil/attributes.h"
-#include "libavutil/common.h"
-#include "libavutil/intreadwrite.h"
-
-#include "avcodec.h"
-#include "rnd_avg.h"
-#include "vp3dsp.h"
-
-#define IdctAdjustBeforeShift 8
-#define xC1S7 64277
-#define xC2S6 60547
-#define xC3S5 54491
-#define xC4S4 46341
-#define xC5S3 36410
-#define xC6S2 25080
-#define xC7S1 12785
-
-#define M(a, b) (((a) * (b)) >> 16)
-
-static av_always_inline void idct(uint8_t *dst, int stride,
- int16_t *input, int type)
-{
- int16_t *ip = input;
-
- int A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H;
- int Ed, Gd, Add, Bdd, Fd, Hd;
-
- int i;
-
- /* Inverse DCT on the rows now */
- for (i = 0; i < 8; i++) {
- /* Check for non-zero values */
- if (ip[0 * 8] | ip[1 * 8] | ip[2 * 8] | ip[3 * 8] |
- ip[4 * 8] | ip[5 * 8] | ip[6 * 8] | ip[7 * 8]) {
- A = M(xC1S7, ip[1 * 8]) + M(xC7S1, ip[7 * 8]);
- B = M(xC7S1, ip[1 * 8]) - M(xC1S7, ip[7 * 8]);
- C = M(xC3S5, ip[3 * 8]) + M(xC5S3, ip[5 * 8]);
- D = M(xC3S5, ip[5 * 8]) - M(xC5S3, ip[3 * 8]);
-
- Ad = M(xC4S4, (A - C));
- Bd = M(xC4S4, (B - D));
-
- Cd = A + C;
- Dd = B + D;
-
- E = M(xC4S4, (ip[0 * 8] + ip[4 * 8]));
- F = M(xC4S4, (ip[0 * 8] - ip[4 * 8]));
-
- G = M(xC2S6, ip[2 * 8]) + M(xC6S2, ip[6 * 8]);
- H = M(xC6S2, ip[2 * 8]) - M(xC2S6, ip[6 * 8]);
-
- Ed = E - G;
- Gd = E + G;
-
- Add = F + Ad;
- Bdd = Bd - H;
-
- Fd = F - Ad;
- Hd = Bd + H;
-
- /* Final sequence of operations over-write original inputs. */
- ip[0 * 8] = Gd + Cd;
- ip[7 * 8] = Gd - Cd;
-
- ip[1 * 8] = Add + Hd;
- ip[2 * 8] = Add - Hd;
-
- ip[3 * 8] = Ed + Dd;
- ip[4 * 8] = Ed - Dd;
-
- ip[5 * 8] = Fd + Bdd;
- ip[6 * 8] = Fd - Bdd;
- }
-
- ip += 1; /* next row */
- }
-
- ip = input;
-
- for (i = 0; i < 8; i++) {
- /* Check for non-zero values (bitwise or faster than ||) */
- if (ip[1] | ip[2] | ip[3] |
- ip[4] | ip[5] | ip[6] | ip[7]) {
- A = M(xC1S7, ip[1]) + M(xC7S1, ip[7]);
- B = M(xC7S1, ip[1]) - M(xC1S7, ip[7]);
- C = M(xC3S5, ip[3]) + M(xC5S3, ip[5]);
- D = M(xC3S5, ip[5]) - M(xC5S3, ip[3]);
-
- Ad = M(xC4S4, (A - C));
- Bd = M(xC4S4, (B - D));
-
- Cd = A + C;
- Dd = B + D;
-
- E = M(xC4S4, (ip[0] + ip[4])) + 8;
- F = M(xC4S4, (ip[0] - ip[4])) + 8;
-
- if (type == 1) { // HACK
- E += 16 * 128;
- F += 16 * 128;
- }
-
- G = M(xC2S6, ip[2]) + M(xC6S2, ip[6]);
- H = M(xC6S2, ip[2]) - M(xC2S6, ip[6]);
-
- Ed = E - G;
- Gd = E + G;
-
- Add = F + Ad;
- Bdd = Bd - H;
-
- Fd = F - Ad;
- Hd = Bd + H;
-
- /* Final sequence of operations over-write original inputs. */
- if (type == 1) {
- dst[0 * stride] = av_clip_uint8((Gd + Cd) >> 4);
- dst[7 * stride] = av_clip_uint8((Gd - Cd) >> 4);
-
- dst[1 * stride] = av_clip_uint8((Add + Hd) >> 4);
- dst[2 * stride] = av_clip_uint8((Add - Hd) >> 4);
-
- dst[3 * stride] = av_clip_uint8((Ed + Dd) >> 4);
- dst[4 * stride] = av_clip_uint8((Ed - Dd) >> 4);
-
- dst[5 * stride] = av_clip_uint8((Fd + Bdd) >> 4);
- dst[6 * stride] = av_clip_uint8((Fd - Bdd) >> 4);
- } else {
- dst[0 * stride] = av_clip_uint8(dst[0 * stride] + ((Gd + Cd) >> 4));
- dst[7 * stride] = av_clip_uint8(dst[7 * stride] + ((Gd - Cd) >> 4));
-
- dst[1 * stride] = av_clip_uint8(dst[1 * stride] + ((Add + Hd) >> 4));
- dst[2 * stride] = av_clip_uint8(dst[2 * stride] + ((Add - Hd) >> 4));
-
- dst[3 * stride] = av_clip_uint8(dst[3 * stride] + ((Ed + Dd) >> 4));
- dst[4 * stride] = av_clip_uint8(dst[4 * stride] + ((Ed - Dd) >> 4));
-
- dst[5 * stride] = av_clip_uint8(dst[5 * stride] + ((Fd + Bdd) >> 4));
- dst[6 * stride] = av_clip_uint8(dst[6 * stride] + ((Fd - Bdd) >> 4));
- }
- } else {
- if (type == 1) {
- dst[0*stride] =
- dst[1*stride] =
- dst[2*stride] =
- dst[3*stride] =
- dst[4*stride] =
- dst[5*stride] =
- dst[6*stride] =
- dst[7*stride] = av_clip_uint8(128 + ((xC4S4 * ip[0] + (IdctAdjustBeforeShift << 16)) >> 20));
- } else {
- if (ip[0]) {
- int v = (xC4S4 * ip[0] + (IdctAdjustBeforeShift << 16)) >> 20;
- dst[0 * stride] = av_clip_uint8(dst[0 * stride] + v);
- dst[1 * stride] = av_clip_uint8(dst[1 * stride] + v);
- dst[2 * stride] = av_clip_uint8(dst[2 * stride] + v);
- dst[3 * stride] = av_clip_uint8(dst[3 * stride] + v);
- dst[4 * stride] = av_clip_uint8(dst[4 * stride] + v);
- dst[5 * stride] = av_clip_uint8(dst[5 * stride] + v);
- dst[6 * stride] = av_clip_uint8(dst[6 * stride] + v);
- dst[7 * stride] = av_clip_uint8(dst[7 * stride] + v);
- }
- }
- }
-
- ip += 8; /* next column */
- dst++;
- }
-}
-
-static void vp3_idct_put_c(uint8_t *dest /* align 8 */, int line_size,
- int16_t *block /* align 16 */)
-{
- idct(dest, line_size, block, 1);
- memset(block, 0, sizeof(*block) * 64);
-}
-
-static void vp3_idct_add_c(uint8_t *dest /* align 8 */, int line_size,
- int16_t *block /* align 16 */)
-{
- idct(dest, line_size, block, 2);
- memset(block, 0, sizeof(*block) * 64);
-}
-
-static void vp3_idct_dc_add_c(uint8_t *dest /* align 8 */, int line_size,
- int16_t *block /* align 16 */)
-{
- int i, dc = (block[0] + 15) >> 5;
-
- for (i = 0; i < 8; i++) {
- dest[0] = av_clip_uint8(dest[0] + dc);
- dest[1] = av_clip_uint8(dest[1] + dc);
- dest[2] = av_clip_uint8(dest[2] + dc);
- dest[3] = av_clip_uint8(dest[3] + dc);
- dest[4] = av_clip_uint8(dest[4] + dc);
- dest[5] = av_clip_uint8(dest[5] + dc);
- dest[6] = av_clip_uint8(dest[6] + dc);
- dest[7] = av_clip_uint8(dest[7] + dc);
- dest += line_size;
- }
- block[0] = 0;
-}
-
-static void vp3_v_loop_filter_c(uint8_t *first_pixel, int stride,
- int *bounding_values)
-{
- unsigned char *end;
- int filter_value;
- const int nstride = -stride;
-
- for (end = first_pixel + 8; first_pixel < end; first_pixel++) {
- filter_value = (first_pixel[2 * nstride] - first_pixel[stride]) +
- (first_pixel[0] - first_pixel[nstride]) * 3;
- filter_value = bounding_values[(filter_value + 4) >> 3];
-
- first_pixel[nstride] = av_clip_uint8(first_pixel[nstride] + filter_value);
- first_pixel[0] = av_clip_uint8(first_pixel[0] - filter_value);
- }
-}
-
-static void vp3_h_loop_filter_c(uint8_t *first_pixel, int stride,
- int *bounding_values)
-{
- unsigned char *end;
- int filter_value;
-
- for (end = first_pixel + 8 * stride; first_pixel != end; first_pixel += stride) {
- filter_value = (first_pixel[-2] - first_pixel[1]) +
- (first_pixel[ 0] - first_pixel[-1]) * 3;
- filter_value = bounding_values[(filter_value + 4) >> 3];
-
- first_pixel[-1] = av_clip_uint8(first_pixel[-1] + filter_value);
- first_pixel[ 0] = av_clip_uint8(first_pixel[ 0] - filter_value);
- }
-}
-
-static void put_no_rnd_pixels_l2(uint8_t *dst, const uint8_t *src1,
- const uint8_t *src2, ptrdiff_t stride, int h)
-{
- int i;
-
- for (i = 0; i < h; i++) {
- uint32_t a, b;
-
- a = AV_RN32(&src1[i * stride]);
- b = AV_RN32(&src2[i * stride]);
- AV_WN32A(&dst[i * stride], no_rnd_avg32(a, b));
- a = AV_RN32(&src1[i * stride + 4]);
- b = AV_RN32(&src2[i * stride + 4]);
- AV_WN32A(&dst[i * stride + 4], no_rnd_avg32(a, b));
- }
-}
-
-av_cold void ff_vp3dsp_init(VP3DSPContext *c, int flags)
-{
- c->put_no_rnd_pixels_l2 = put_no_rnd_pixels_l2;
-
- c->idct_put = vp3_idct_put_c;
- c->idct_add = vp3_idct_add_c;
- c->idct_dc_add = vp3_idct_dc_add_c;
- c->v_loop_filter = vp3_v_loop_filter_c;
- c->h_loop_filter = vp3_h_loop_filter_c;
-
- if (ARCH_ARM)
- ff_vp3dsp_init_arm(c, flags);
- if (ARCH_PPC)
- ff_vp3dsp_init_ppc(c, flags);
- if (ARCH_X86)
- ff_vp3dsp_init_x86(c, flags);
-}
diff --git a/ffmpeg-2-8-11/libavcodec/vp5.c b/ffmpeg-2-8-11/libavcodec/vp5.c
deleted file mode 100644
index 4ec85eb..0000000
--- a/ffmpeg-2-8-11/libavcodec/vp5.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.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
- * VP5 compatible video decoder
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "avcodec.h"
-#include "get_bits.h"
-#include "internal.h"
-
-#include "vp56.h"
-#include "vp56data.h"
-#include "vp5data.h"
-
-
-static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
-{
- VP56RangeCoder *c = &s->c;
- int rows, cols;
-
- ff_vp56_init_range_decoder(&s->c, buf, buf_size);
- s->frames[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c);
- vp56_rac_get(c);
- ff_vp56_init_dequant(s, vp56_rac_gets(c, 6));
- if (s->frames[VP56_FRAME_CURRENT]->key_frame)
- {
- vp56_rac_gets(c, 8);
- if(vp56_rac_gets(c, 5) > 5)
- return AVERROR_INVALIDDATA;
- vp56_rac_gets(c, 2);
- if (vp56_rac_get(c)) {
- av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n");
- return AVERROR_PATCHWELCOME;
- }
- rows = vp56_rac_gets(c, 8); /* number of stored macroblock rows */
- cols = vp56_rac_gets(c, 8); /* number of stored macroblock cols */
- if (!rows || !cols) {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n",
- cols << 4, rows << 4);
- return AVERROR_INVALIDDATA;
- }
- vp56_rac_gets(c, 8); /* number of displayed macroblock rows */
- vp56_rac_gets(c, 8); /* number of displayed macroblock cols */
- vp56_rac_gets(c, 2);
- if (!s->macroblocks || /* first frame */
- 16*cols != s->avctx->coded_width ||
- 16*rows != s->avctx->coded_height) {
- int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows);
- if (ret < 0)
- return ret;
- return VP56_SIZE_CHANGE;
- }
- } else if (!s->macroblocks)
- return AVERROR_INVALIDDATA;
- return 0;
-}
-
-static void vp5_parse_vector_adjustment(VP56Context *s, VP56mv *vect)
-{
- VP56RangeCoder *c = &s->c;
- VP56Model *model = s->modelp;
- int comp, di;
-
- for (comp=0; comp<2; comp++) {
- int delta = 0;
- if (vp56_rac_get_prob_branchy(c, model->vector_dct[comp])) {
- int sign = vp56_rac_get_prob(c, model->vector_sig[comp]);
- di = vp56_rac_get_prob(c, model->vector_pdi[comp][0]);
- di |= vp56_rac_get_prob(c, model->vector_pdi[comp][1]) << 1;
- delta = vp56_rac_get_tree(c, ff_vp56_pva_tree,
- model->vector_pdv[comp]);
- delta = di | (delta << 2);
- delta = (delta ^ -sign) + sign;
- }
- if (!comp)
- vect->x = delta;
- else
- vect->y = delta;
- }
-}
-
-static void vp5_parse_vector_models(VP56Context *s)
-{
- VP56RangeCoder *c = &s->c;
- VP56Model *model = s->modelp;
- int comp, node;
-
- for (comp=0; comp<2; comp++) {
- if (vp56_rac_get_prob_branchy(c, vp5_vmc_pct[comp][0]))
- model->vector_dct[comp] = vp56_rac_gets_nn(c, 7);
- if (vp56_rac_get_prob_branchy(c, vp5_vmc_pct[comp][1]))
- model->vector_sig[comp] = vp56_rac_gets_nn(c, 7);
- if (vp56_rac_get_prob_branchy(c, vp5_vmc_pct[comp][2]))
- model->vector_pdi[comp][0] = vp56_rac_gets_nn(c, 7);
- if (vp56_rac_get_prob_branchy(c, vp5_vmc_pct[comp][3]))
- model->vector_pdi[comp][1] = vp56_rac_gets_nn(c, 7);
- }
-
- for (comp=0; comp<2; comp++)
- for (node=0; node<7; node++)
- if (vp56_rac_get_prob_branchy(c, vp5_vmc_pct[comp][4 + node]))
- model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7);
-}
-
-static int vp5_parse_coeff_models(VP56Context *s)
-{
- VP56RangeCoder *c = &s->c;
- VP56Model *model = s->modelp;
- uint8_t def_prob[11];
- int node, cg, ctx;
- int ct; /* code type */
- int pt; /* plane type (0 for Y, 1 for U or V) */
-
- memset(def_prob, 0x80, sizeof(def_prob));
-
- for (pt=0; pt<2; pt++)
- for (node=0; node<11; node++)
- if (vp56_rac_get_prob_branchy(c, vp5_dccv_pct[pt][node])) {
- def_prob[node] = vp56_rac_gets_nn(c, 7);
- model->coeff_dccv[pt][node] = def_prob[node];
- } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
- model->coeff_dccv[pt][node] = def_prob[node];
- }
-
- for (ct=0; ct<3; ct++)
- for (pt=0; pt<2; pt++)
- for (cg=0; cg<6; cg++)
- for (node=0; node<11; node++)
- if (vp56_rac_get_prob_branchy(c, vp5_ract_pct[ct][pt][cg][node])) {
- def_prob[node] = vp56_rac_gets_nn(c, 7);
- model->coeff_ract[pt][ct][cg][node] = def_prob[node];
- } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
- model->coeff_ract[pt][ct][cg][node] = def_prob[node];
- }
-
- /* coeff_dcct is a linear combination of coeff_dccv */
- for (pt=0; pt<2; pt++)
- for (ctx=0; ctx<36; ctx++)
- for (node=0; node<5; node++)
- model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp5_dccv_lc[node][ctx][0] + 128) >> 8) + vp5_dccv_lc[node][ctx][1], 1, 254);
-
- /* coeff_acct is a linear combination of coeff_ract */
- for (ct=0; ct<3; ct++)
- for (pt=0; pt<2; pt++)
- for (cg=0; cg<3; cg++)
- for (ctx=0; ctx<6; ctx++)
- for (node=0; node<5; node++)
- model->coeff_acct[pt][ct][cg][ctx][node] = av_clip(((model->coeff_ract[pt][ct][cg][node] * vp5_ract_lc[ct][cg][node][ctx][0] + 128) >> 8) + vp5_ract_lc[ct][cg][node][ctx][1], 1, 254);
- return 0;
-}
-
-static int vp5_parse_coeff(VP56Context *s)
-{
- VP56RangeCoder *c = &s->c;
- VP56Model *model = s->modelp;
- uint8_t *permute = s->idct_scantable;
- uint8_t *model1, *model2;
- int coeff, sign, coeff_idx;
- int b, i, cg, idx, ctx, ctx_last;
- int pt = 0; /* plane type (0 for Y, 1 for U or V) */
-
- if (c->end >= c->buffer && c->bits >= 0) {
- av_log(s->avctx, AV_LOG_ERROR, "End of AC stream reached in vp5_parse_coeff\n");
- return AVERROR_INVALIDDATA;
- }
-
- for (b=0; b<6; b++) {
- int ct = 1; /* code type */
-
- if (b > 3) pt = 1;
-
- ctx = 6*s->coeff_ctx[ff_vp56_b6to4[b]][0]
- + s->above_blocks[s->above_block_idx[b]].not_null_dc;
- model1 = model->coeff_dccv[pt];
- model2 = model->coeff_dcct[pt][ctx];
-
- coeff_idx = 0;
- for (;;) {
- if (vp56_rac_get_prob_branchy(c, model2[0])) {
- if (vp56_rac_get_prob_branchy(c, model2[2])) {
- if (vp56_rac_get_prob_branchy(c, model2[3])) {
- s->coeff_ctx[ff_vp56_b6to4[b]][coeff_idx] = 4;
- idx = vp56_rac_get_tree(c, ff_vp56_pc_tree, model1);
- sign = vp56_rac_get(c);
- coeff = ff_vp56_coeff_bias[idx+5];
- for (i=ff_vp56_coeff_bit_length[idx]; i>=0; i--)
- coeff += vp56_rac_get_prob(c, ff_vp56_coeff_parse_table[idx][i]) << i;
- } else {
- if (vp56_rac_get_prob_branchy(c, model2[4])) {
- coeff = 3 + vp56_rac_get_prob(c, model1[5]);
- s->coeff_ctx[ff_vp56_b6to4[b]][coeff_idx] = 3;
- } else {
- coeff = 2;
- s->coeff_ctx[ff_vp56_b6to4[b]][coeff_idx] = 2;
- }
- sign = vp56_rac_get(c);
- }
- ct = 2;
- } else {
- ct = 1;
- s->coeff_ctx[ff_vp56_b6to4[b]][coeff_idx] = 1;
- sign = vp56_rac_get(c);
- coeff = 1;
- }
- coeff = (coeff ^ -sign) + sign;
- if (coeff_idx)
- coeff *= s->dequant_ac;
- s->block_coeff[b][permute[coeff_idx]] = coeff;
- } else {
- if (ct && !vp56_rac_get_prob_branchy(c, model2[1]))
- break;
- ct = 0;
- s->coeff_ctx[ff_vp56_b6to4[b]][coeff_idx] = 0;
- }
- coeff_idx++;
- if (coeff_idx >= 64)
- break;
-
- cg = vp5_coeff_groups[coeff_idx];
- ctx = s->coeff_ctx[ff_vp56_b6to4[b]][coeff_idx];
- model1 = model->coeff_ract[pt][ct][cg];
- model2 = cg > 2 ? model1 : model->coeff_acct[pt][ct][cg][ctx];
- }
-
- ctx_last = FFMIN(s->coeff_ctx_last[ff_vp56_b6to4[b]], 24);
- s->coeff_ctx_last[ff_vp56_b6to4[b]] = coeff_idx;
- if (coeff_idx < ctx_last)
- for (i=coeff_idx; i<=ctx_last; i++)
- s->coeff_ctx[ff_vp56_b6to4[b]][i] = 5;
- s->above_blocks[s->above_block_idx[b]].not_null_dc = s->coeff_ctx[ff_vp56_b6to4[b]][0];
- }
- return 0;
-}
-
-static void vp5_default_models_init(VP56Context *s)
-{
- VP56Model *model = s->modelp;
- int i;
-
- for (i=0; i<2; i++) {
- model->vector_sig[i] = 0x80;
- model->vector_dct[i] = 0x80;
- model->vector_pdi[i][0] = 0x55;
- model->vector_pdi[i][1] = 0x80;
- }
- memcpy(model->mb_types_stats, ff_vp56_def_mb_types_stats, sizeof(model->mb_types_stats));
- memset(model->vector_pdv, 0x80, sizeof(model->vector_pdv));
-}
-
-static av_cold int vp5_decode_init(AVCodecContext *avctx)
-{
- VP56Context *s = avctx->priv_data;
- int ret;
-
- if ((ret = ff_vp56_init(avctx, 1, 0)) < 0)
- return ret;
- s->vp56_coord_div = vp5_coord_div;
- s->parse_vector_adjustment = vp5_parse_vector_adjustment;
- s->parse_coeff = vp5_parse_coeff;
- s->default_models_init = vp5_default_models_init;
- s->parse_vector_models = vp5_parse_vector_models;
- s->parse_coeff_models = vp5_parse_coeff_models;
- s->parse_header = vp5_parse_header;
-
- return 0;
-}
-
-AVCodec ff_vp5_decoder = {
- .name = "vp5",
- .long_name = NULL_IF_CONFIG_SMALL("On2 VP5"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_VP5,
- .priv_data_size = sizeof(VP56Context),
- .init = vp5_decode_init,
- .close = ff_vp56_free,
- .decode = ff_vp56_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/vp56.c b/ffmpeg-2-8-11/libavcodec/vp56.c
deleted file mode 100644
index d8fe994..0000000
--- a/ffmpeg-2-8-11/libavcodec/vp56.c
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- * Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.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
- * VP5 and VP6 compatible video decoder (common features)
- */
-
-#include "avcodec.h"
-#include "bytestream.h"
-#include "internal.h"
-#include "h264chroma.h"
-#include "vp56.h"
-#include "vp56data.h"
-
-
-void ff_vp56_init_dequant(VP56Context *s, int quantizer)
-{
- s->quantizer = quantizer;
- s->dequant_dc = ff_vp56_dc_dequant[quantizer] << 2;
- s->dequant_ac = ff_vp56_ac_dequant[quantizer] << 2;
-}
-
-static int vp56_get_vectors_predictors(VP56Context *s, int row, int col,
- VP56Frame ref_frame)
-{
- int nb_pred = 0;
- VP56mv vect[2] = {{0,0}, {0,0}};
- int pos, offset;
- VP56mv mvp;
-
- for (pos=0; pos<12; pos++) {
- mvp.x = col + ff_vp56_candidate_predictor_pos[pos][0];
- mvp.y = row + ff_vp56_candidate_predictor_pos[pos][1];
- if (mvp.x < 0 || mvp.x >= s->mb_width ||
- mvp.y < 0 || mvp.y >= s->mb_height)
- continue;
- offset = mvp.x + s->mb_width*mvp.y;
-
- if (ff_vp56_reference_frame[s->macroblocks[offset].type] != ref_frame)
- continue;
- if ((s->macroblocks[offset].mv.x == vect[0].x &&
- s->macroblocks[offset].mv.y == vect[0].y) ||
- (s->macroblocks[offset].mv.x == 0 &&
- s->macroblocks[offset].mv.y == 0))
- continue;
-
- vect[nb_pred++] = s->macroblocks[offset].mv;
- if (nb_pred > 1) {
- nb_pred = -1;
- break;
- }
- s->vector_candidate_pos = pos;
- }
-
- s->vector_candidate[0] = vect[0];
- s->vector_candidate[1] = vect[1];
-
- return nb_pred+1;
-}
-
-static void vp56_parse_mb_type_models(VP56Context *s)
-{
- VP56RangeCoder *c = &s->c;
- VP56Model *model = s->modelp;
- int i, ctx, type;
-
- for (ctx=0; ctx<3; ctx++) {
- if (vp56_rac_get_prob_branchy(c, 174)) {
- int idx = vp56_rac_gets(c, 4);
- memcpy(model->mb_types_stats[ctx],
- ff_vp56_pre_def_mb_type_stats[idx][ctx],
- sizeof(model->mb_types_stats[ctx]));
- }
- if (vp56_rac_get_prob_branchy(c, 254)) {
- for (type=0; type<10; type++) {
- for(i=0; i<2; i++) {
- if (vp56_rac_get_prob_branchy(c, 205)) {
- int delta, sign = vp56_rac_get(c);
-
- delta = vp56_rac_get_tree(c, ff_vp56_pmbtm_tree,
- ff_vp56_mb_type_model_model);
- if (!delta)
- delta = 4 * vp56_rac_gets(c, 7);
- model->mb_types_stats[ctx][type][i] += (delta ^ -sign) + sign;
- }
- }
- }
- }
- }
-
- /* compute MB type probability tables based on previous MB type */
- for (ctx=0; ctx<3; ctx++) {
- int p[10];
-
- for (type=0; type<10; type++)
- p[type] = 100 * model->mb_types_stats[ctx][type][1];
-
- for (type=0; type<10; type++) {
- int p02, p34, p0234, p17, p56, p89, p5689, p156789;
-
- /* conservative MB type probability */
- model->mb_type[ctx][type][0] = 255 - (255 * model->mb_types_stats[ctx][type][0]) / (1 + model->mb_types_stats[ctx][type][0] + model->mb_types_stats[ctx][type][1]);
-
- p[type] = 0; /* same MB type => weight is null */
-
- /* binary tree parsing probabilities */
- p02 = p[0] + p[2];
- p34 = p[3] + p[4];
- p0234 = p02 + p34;
- p17 = p[1] + p[7];
- p56 = p[5] + p[6];
- p89 = p[8] + p[9];
- p5689 = p56 + p89;
- p156789 = p17 + p5689;
-
- model->mb_type[ctx][type][1] = 1 + 255 * p0234/(1+p0234+p156789);
- model->mb_type[ctx][type][2] = 1 + 255 * p02 / (1+p0234);
- model->mb_type[ctx][type][3] = 1 + 255 * p17 / (1+p156789);
- model->mb_type[ctx][type][4] = 1 + 255 * p[0] / (1+p02);
- model->mb_type[ctx][type][5] = 1 + 255 * p[3] / (1+p34);
- model->mb_type[ctx][type][6] = 1 + 255 * p[1] / (1+p17);
- model->mb_type[ctx][type][7] = 1 + 255 * p56 / (1+p5689);
- model->mb_type[ctx][type][8] = 1 + 255 * p[5] / (1+p56);
- model->mb_type[ctx][type][9] = 1 + 255 * p[8] / (1+p89);
-
- /* restore initial value */
- p[type] = 100 * model->mb_types_stats[ctx][type][1];
- }
- }
-}
-
-static VP56mb vp56_parse_mb_type(VP56Context *s,
- VP56mb prev_type, int ctx)
-{
- uint8_t *mb_type_model = s->modelp->mb_type[ctx][prev_type];
- VP56RangeCoder *c = &s->c;
-
- if (vp56_rac_get_prob_branchy(c, mb_type_model[0]))
- return prev_type;
- else
- return vp56_rac_get_tree(c, ff_vp56_pmbt_tree, mb_type_model);
-}
-
-static void vp56_decode_4mv(VP56Context *s, int row, int col)
-{
- VP56mv mv = {0,0};
- int type[4];
- int b;
-
- /* parse each block type */
- for (b=0; b<4; b++) {
- type[b] = vp56_rac_gets(&s->c, 2);
- if (type[b])
- type[b]++; /* only returns 0, 2, 3 or 4 (all INTER_PF) */
- }
-
- /* get vectors */
- for (b=0; b<4; b++) {
- switch (type[b]) {
- case VP56_MB_INTER_NOVEC_PF:
- s->mv[b] = (VP56mv) {0,0};
- break;
- case VP56_MB_INTER_DELTA_PF:
- s->parse_vector_adjustment(s, &s->mv[b]);
- break;
- case VP56_MB_INTER_V1_PF:
- s->mv[b] = s->vector_candidate[0];
- break;
- case VP56_MB_INTER_V2_PF:
- s->mv[b] = s->vector_candidate[1];
- break;
- }
- mv.x += s->mv[b].x;
- mv.y += s->mv[b].y;
- }
-
- /* this is the one selected for the whole MB for prediction */
- s->macroblocks[row * s->mb_width + col].mv = s->mv[3];
-
- /* chroma vectors are average luma vectors */
- if (s->avctx->codec->id == AV_CODEC_ID_VP5) {
- s->mv[4].x = s->mv[5].x = RSHIFT(mv.x,2);
- s->mv[4].y = s->mv[5].y = RSHIFT(mv.y,2);
- } else {
- s->mv[4] = s->mv[5] = (VP56mv) {mv.x/4, mv.y/4};
- }
-}
-
-static VP56mb vp56_decode_mv(VP56Context *s, int row, int col)
-{
- VP56mv *mv, vect = {0,0};
- int ctx, b;
-
- ctx = vp56_get_vectors_predictors(s, row, col, VP56_FRAME_PREVIOUS);
- s->mb_type = vp56_parse_mb_type(s, s->mb_type, ctx);
- s->macroblocks[row * s->mb_width + col].type = s->mb_type;
-
- switch (s->mb_type) {
- case VP56_MB_INTER_V1_PF:
- mv = &s->vector_candidate[0];
- break;
-
- case VP56_MB_INTER_V2_PF:
- mv = &s->vector_candidate[1];
- break;
-
- case VP56_MB_INTER_V1_GF:
- vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);
- mv = &s->vector_candidate[0];
- break;
-
- case VP56_MB_INTER_V2_GF:
- vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);
- mv = &s->vector_candidate[1];
- break;
-
- case VP56_MB_INTER_DELTA_PF:
- s->parse_vector_adjustment(s, &vect);
- mv = &vect;
- break;
-
- case VP56_MB_INTER_DELTA_GF:
- vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);
- s->parse_vector_adjustment(s, &vect);
- mv = &vect;
- break;
-
- case VP56_MB_INTER_4V:
- vp56_decode_4mv(s, row, col);
- return s->mb_type;
-
- default:
- mv = &vect;
- break;
- }
-
- s->macroblocks[row*s->mb_width + col].mv = *mv;
-
- /* same vector for all blocks */
- for (b=0; b<6; b++)
- s->mv[b] = *mv;
-
- return s->mb_type;
-}
-
-static void vp56_add_predictors_dc(VP56Context *s, VP56Frame ref_frame)
-{
- int idx = s->idct_scantable[0];
- int b;
-
- for (b=0; b<6; b++) {
- VP56RefDc *ab = &s->above_blocks[s->above_block_idx[b]];
- VP56RefDc *lb = &s->left_block[ff_vp56_b6to4[b]];
- int count = 0;
- int dc = 0;
- int i;
-
- if (ref_frame == lb->ref_frame) {
- dc += lb->dc_coeff;
- count++;
- }
- if (ref_frame == ab->ref_frame) {
- dc += ab->dc_coeff;
- count++;
- }
- if (s->avctx->codec->id == AV_CODEC_ID_VP5)
- for (i=0; i<2; i++)
- if (count < 2 && ref_frame == ab[-1+2*i].ref_frame) {
- dc += ab[-1+2*i].dc_coeff;
- count++;
- }
- if (count == 0)
- dc = s->prev_dc[ff_vp56_b2p[b]][ref_frame];
- else if (count == 2)
- dc /= 2;
-
- s->block_coeff[b][idx] += dc;
- s->prev_dc[ff_vp56_b2p[b]][ref_frame] = s->block_coeff[b][idx];
- ab->dc_coeff = s->block_coeff[b][idx];
- ab->ref_frame = ref_frame;
- lb->dc_coeff = s->block_coeff[b][idx];
- lb->ref_frame = ref_frame;
- s->block_coeff[b][idx] *= s->dequant_dc;
- }
-}
-
-static void vp56_deblock_filter(VP56Context *s, uint8_t *yuv,
- ptrdiff_t stride, int dx, int dy)
-{
- int t = ff_vp56_filter_threshold[s->quantizer];
- if (dx) s->vp56dsp.edge_filter_hor(yuv + 10-dx , stride, t);
- if (dy) s->vp56dsp.edge_filter_ver(yuv + stride*(10-dy), stride, t);
-}
-
-static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src,
- ptrdiff_t stride, int x, int y)
-{
- uint8_t *dst = s->frames[VP56_FRAME_CURRENT]->data[plane] + s->block_offset[b];
- uint8_t *src_block;
- int src_offset;
- int overlap_offset = 0;
- int mask = s->vp56_coord_div[b] - 1;
- int deblock_filtering = s->deblock_filtering;
- int dx;
- int dy;
-
- if (s->avctx->skip_loop_filter >= AVDISCARD_ALL ||
- (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY
- && !s->frames[VP56_FRAME_CURRENT]->key_frame))
- deblock_filtering = 0;
-
- dx = s->mv[b].x / s->vp56_coord_div[b];
- dy = s->mv[b].y / s->vp56_coord_div[b];
-
- if (b >= 4) {
- x /= 2;
- y /= 2;
- }
- x += dx - 2;
- y += dy - 2;
-
- if (x<0 || x+12>=s->plane_width[plane] ||
- y<0 || y+12>=s->plane_height[plane]) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
- src + s->block_offset[b] + (dy-2)*stride + (dx-2),
- stride, stride,
- 12, 12, x, y,
- s->plane_width[plane],
- s->plane_height[plane]);
- src_block = s->edge_emu_buffer;
- src_offset = 2 + 2*stride;
- } else if (deblock_filtering) {
- /* only need a 12x12 block, but there is no such dsp function, */
- /* so copy a 16x12 block */
- s->hdsp.put_pixels_tab[0][0](s->edge_emu_buffer,
- src + s->block_offset[b] + (dy-2)*stride + (dx-2),
- stride, 12);
- src_block = s->edge_emu_buffer;
- src_offset = 2 + 2*stride;
- } else {
- src_block = src;
- src_offset = s->block_offset[b] + dy*stride + dx;
- }
-
- if (deblock_filtering)
- vp56_deblock_filter(s, src_block, stride, dx&7, dy&7);
-
- if (s->mv[b].x & mask)
- overlap_offset += (s->mv[b].x > 0) ? 1 : -1;
- if (s->mv[b].y & mask)
- overlap_offset += (s->mv[b].y > 0) ? stride : -stride;
-
- if (overlap_offset) {
- if (s->filter)
- s->filter(s, dst, src_block, src_offset, src_offset+overlap_offset,
- stride, s->mv[b], mask, s->filter_selection, b<4);
- else
- s->vp3dsp.put_no_rnd_pixels_l2(dst, src_block+src_offset,
- src_block+src_offset+overlap_offset,
- stride, 8);
- } else {
- s->hdsp.put_pixels_tab[1][0](dst, src_block+src_offset, stride, 8);
- }
-}
-
-static int vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
-{
- AVFrame *frame_current, *frame_ref;
- VP56mb mb_type;
- VP56Frame ref_frame;
- int b, ab, b_max, plane, off;
- int ret;
-
- if (s->frames[VP56_FRAME_CURRENT]->key_frame)
- mb_type = VP56_MB_INTRA;
- else
- mb_type = vp56_decode_mv(s, row, col);
- ref_frame = ff_vp56_reference_frame[mb_type];
-
- ret = s->parse_coeff(s);
- if (ret < 0)
- return ret;
-
- vp56_add_predictors_dc(s, ref_frame);
-
- frame_current = s->frames[VP56_FRAME_CURRENT];
- frame_ref = s->frames[ref_frame];
- if (mb_type != VP56_MB_INTRA && !frame_ref->data[0])
- return 0;
-
- ab = 6*is_alpha;
- b_max = 6 - 2*is_alpha;
-
- switch (mb_type) {
- case VP56_MB_INTRA:
- for (b=0; b<b_max; b++) {
- plane = ff_vp56_b2p[b+ab];
- s->vp3dsp.idct_put(frame_current->data[plane] + s->block_offset[b],
- s->stride[plane], s->block_coeff[b]);
- }
- break;
-
- case VP56_MB_INTER_NOVEC_PF:
- case VP56_MB_INTER_NOVEC_GF:
- for (b=0; b<b_max; b++) {
- plane = ff_vp56_b2p[b+ab];
- off = s->block_offset[b];
- s->hdsp.put_pixels_tab[1][0](frame_current->data[plane] + off,
- frame_ref->data[plane] + off,
- s->stride[plane], 8);
- s->vp3dsp.idct_add(frame_current->data[plane] + off,
- s->stride[plane], s->block_coeff[b]);
- }
- break;
-
- case VP56_MB_INTER_DELTA_PF:
- case VP56_MB_INTER_V1_PF:
- case VP56_MB_INTER_V2_PF:
- case VP56_MB_INTER_DELTA_GF:
- case VP56_MB_INTER_4V:
- case VP56_MB_INTER_V1_GF:
- case VP56_MB_INTER_V2_GF:
- for (b=0; b<b_max; b++) {
- int x_off = b==1 || b==3 ? 8 : 0;
- int y_off = b==2 || b==3 ? 8 : 0;
- plane = ff_vp56_b2p[b+ab];
- vp56_mc(s, b, plane, frame_ref->data[plane], s->stride[plane],
- 16*col+x_off, 16*row+y_off);
- s->vp3dsp.idct_add(frame_current->data[plane] + s->block_offset[b],
- s->stride[plane], s->block_coeff[b]);
- }
- break;
- }
-
- if (is_alpha) {
- s->block_coeff[4][0] = 0;
- s->block_coeff[5][0] = 0;
- }
- return 0;
-}
-
-static int vp56_size_changed(VP56Context *s)
-{
- AVCodecContext *avctx = s->avctx;
- int stride = s->frames[VP56_FRAME_CURRENT]->linesize[0];
- int i;
-
- s->plane_width[0] = s->plane_width[3] = avctx->coded_width;
- s->plane_width[1] = s->plane_width[2] = avctx->coded_width/2;
- s->plane_height[0] = s->plane_height[3] = avctx->coded_height;
- s->plane_height[1] = s->plane_height[2] = avctx->coded_height/2;
-
- for (i=0; i<4; i++)
- s->stride[i] = s->flip * s->frames[VP56_FRAME_CURRENT]->linesize[i];
-
- s->mb_width = (avctx->coded_width +15) / 16;
- s->mb_height = (avctx->coded_height+15) / 16;
-
- if (s->mb_width > 1000 || s->mb_height > 1000) {
- ff_set_dimensions(avctx, 0, 0);
- av_log(avctx, AV_LOG_ERROR, "picture too big\n");
- return AVERROR_INVALIDDATA;
- }
-
- av_reallocp_array(&s->above_blocks, 4*s->mb_width+6,
- sizeof(*s->above_blocks));
- av_reallocp_array(&s->macroblocks, s->mb_width*s->mb_height,
- sizeof(*s->macroblocks));
- av_free(s->edge_emu_buffer_alloc);
- s->edge_emu_buffer_alloc = av_malloc(16*stride);
- s->edge_emu_buffer = s->edge_emu_buffer_alloc;
- if (!s->above_blocks || !s->macroblocks || !s->edge_emu_buffer_alloc)
- return AVERROR(ENOMEM);
- if (s->flip < 0)
- s->edge_emu_buffer += 15 * stride;
-
- if (s->alpha_context)
- return vp56_size_changed(s->alpha_context);
-
- return 0;
-}
-
-static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *, int, int);
-
-int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *avpkt)
-{
- const uint8_t *buf = avpkt->data;
- VP56Context *s = avctx->priv_data;
- AVFrame *const p = s->frames[VP56_FRAME_CURRENT];
- int remaining_buf_size = avpkt->size;
- int av_uninit(alpha_offset);
- int i, res;
- int ret;
-
- if (s->has_alpha) {
- if (remaining_buf_size < 3)
- return AVERROR_INVALIDDATA;
- alpha_offset = bytestream_get_be24(&buf);
- remaining_buf_size -= 3;
- if (remaining_buf_size < alpha_offset)
- return AVERROR_INVALIDDATA;
- }
-
- res = s->parse_header(s, buf, remaining_buf_size);
- if (res < 0)
- return res;
-
- if (res == VP56_SIZE_CHANGE) {
- for (i = 0; i < 4; i++) {
- av_frame_unref(s->frames[i]);
- if (s->alpha_context)
- av_frame_unref(s->alpha_context->frames[i]);
- }
- }
-
- ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF);
- if (ret < 0)
- return ret;
-
- if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) {
- av_frame_unref(s->alpha_context->frames[VP56_FRAME_CURRENT]);
- if ((ret = av_frame_ref(s->alpha_context->frames[VP56_FRAME_CURRENT], p)) < 0) {
- av_frame_unref(p);
- return ret;
- }
- }
-
- if (res == VP56_SIZE_CHANGE) {
- if (vp56_size_changed(s)) {
- av_frame_unref(p);
- return AVERROR_INVALIDDATA;
- }
- }
-
- if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) {
- int bak_w = avctx->width;
- int bak_h = avctx->height;
- int bak_cw = avctx->coded_width;
- int bak_ch = avctx->coded_height;
- buf += alpha_offset;
- remaining_buf_size -= alpha_offset;
-
- res = s->alpha_context->parse_header(s->alpha_context, buf, remaining_buf_size);
- if (res != 0) {
- if(res==VP56_SIZE_CHANGE) {
- av_log(avctx, AV_LOG_ERROR, "Alpha reconfiguration\n");
- avctx->width = bak_w;
- avctx->height = bak_h;
- avctx->coded_width = bak_cw;
- avctx->coded_height = bak_ch;
- }
- av_frame_unref(p);
- return AVERROR_INVALIDDATA;
- }
- }
-
- avctx->execute2(avctx, ff_vp56_decode_mbs, 0, 0, (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) + 1);
-
- if ((res = av_frame_ref(data, p)) < 0)
- return res;
- *got_frame = 1;
-
- return avpkt->size;
-}
-
-static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data,
- int jobnr, int threadnr)
-{
- VP56Context *s0 = avctx->priv_data;
- int is_alpha = (jobnr == 1);
- VP56Context *s = is_alpha ? s0->alpha_context : s0;
- AVFrame *const p = s->frames[VP56_FRAME_CURRENT];
- int mb_row, mb_col, mb_row_flip, mb_offset = 0;
- int block, y, uv;
- ptrdiff_t stride_y, stride_uv;
- int res;
-
- if (p->key_frame) {
- p->pict_type = AV_PICTURE_TYPE_I;
- s->default_models_init(s);
- for (block=0; block<s->mb_height*s->mb_width; block++)
- s->macroblocks[block].type = VP56_MB_INTRA;
- } else {
- p->pict_type = AV_PICTURE_TYPE_P;
- vp56_parse_mb_type_models(s);
- s->parse_vector_models(s);
- s->mb_type = VP56_MB_INTER_NOVEC_PF;
- }
-
- if (s->parse_coeff_models(s))
- goto next;
-
- memset(s->prev_dc, 0, sizeof(s->prev_dc));
- s->prev_dc[1][VP56_FRAME_CURRENT] = 128;
- s->prev_dc[2][VP56_FRAME_CURRENT] = 128;
-
- for (block=0; block < 4*s->mb_width+6; block++) {
- s->above_blocks[block].ref_frame = VP56_FRAME_NONE;
- s->above_blocks[block].dc_coeff = 0;
- s->above_blocks[block].not_null_dc = 0;
- }
- s->above_blocks[2*s->mb_width + 2].ref_frame = VP56_FRAME_CURRENT;
- s->above_blocks[3*s->mb_width + 4].ref_frame = VP56_FRAME_CURRENT;
-
- stride_y = p->linesize[0];
- stride_uv = p->linesize[1];
-
- if (s->flip < 0)
- mb_offset = 7;
-
- /* main macroblocks loop */
- for (mb_row=0; mb_row<s->mb_height; mb_row++) {
- if (s->flip < 0)
- mb_row_flip = s->mb_height - mb_row - 1;
- else
- mb_row_flip = mb_row;
-
- for (block=0; block<4; block++) {
- s->left_block[block].ref_frame = VP56_FRAME_NONE;
- s->left_block[block].dc_coeff = 0;
- s->left_block[block].not_null_dc = 0;
- }
- memset(s->coeff_ctx, 0, sizeof(s->coeff_ctx));
- memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last));
-
- s->above_block_idx[0] = 1;
- s->above_block_idx[1] = 2;
- s->above_block_idx[2] = 1;
- s->above_block_idx[3] = 2;
- s->above_block_idx[4] = 2*s->mb_width + 2 + 1;
- s->above_block_idx[5] = 3*s->mb_width + 4 + 1;
-
- s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y;
- s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y;
- s->block_offset[1] = s->block_offset[0] + 8;
- s->block_offset[3] = s->block_offset[2] + 8;
- s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv;
- s->block_offset[5] = s->block_offset[4];
-
- for (mb_col=0; mb_col<s->mb_width; mb_col++) {
- int ret = vp56_decode_mb(s, mb_row, mb_col, is_alpha);
- if (ret < 0)
- return ret;
-
- for (y=0; y<4; y++) {
- s->above_block_idx[y] += 2;
- s->block_offset[y] += 16;
- }
-
- for (uv=4; uv<6; uv++) {
- s->above_block_idx[uv] += 1;
- s->block_offset[uv] += 8;
- }
- }
- }
-
-next:
- if (p->key_frame || s->golden_frame) {
- av_frame_unref(s->frames[VP56_FRAME_GOLDEN]);
- if ((res = av_frame_ref(s->frames[VP56_FRAME_GOLDEN], p)) < 0)
- return res;
- }
-
- av_frame_unref(s->frames[VP56_FRAME_PREVIOUS]);
- FFSWAP(AVFrame *, s->frames[VP56_FRAME_CURRENT],
- s->frames[VP56_FRAME_PREVIOUS]);
- return 0;
-}
-
-av_cold int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha)
-{
- VP56Context *s = avctx->priv_data;
- return ff_vp56_init_context(avctx, s, flip, has_alpha);
-}
-
-av_cold int ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
- int flip, int has_alpha)
-{
- int i;
-
- s->avctx = avctx;
- avctx->pix_fmt = has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P;
- if (avctx->skip_alpha) avctx->pix_fmt = AV_PIX_FMT_YUV420P;
-
- ff_h264chroma_init(&s->h264chroma, 8);
- ff_hpeldsp_init(&s->hdsp, avctx->flags);
- ff_videodsp_init(&s->vdsp, 8);
- ff_vp3dsp_init(&s->vp3dsp, avctx->flags);
- ff_vp56dsp_init(&s->vp56dsp, avctx->codec->id);
- for (i = 0; i < 64; i++) {
-#define TRANSPOSE(x) (((x) >> 3) | (((x) & 7) << 3))
- s->idct_scantable[i] = TRANSPOSE(ff_zigzag_direct[i]);
-#undef TRANSPOSE
- }
-
- for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) {
- s->frames[i] = av_frame_alloc();
- if (!s->frames[i]) {
- ff_vp56_free(avctx);
- return AVERROR(ENOMEM);
- }
- }
- s->edge_emu_buffer_alloc = NULL;
-
- s->above_blocks = NULL;
- s->macroblocks = NULL;
- s->quantizer = -1;
- s->deblock_filtering = 1;
- s->golden_frame = 0;
-
- s->filter = NULL;
-
- s->has_alpha = has_alpha;
-
- s->modelp = &s->model;
-
- if (flip) {
- s->flip = -1;
- s->frbi = 2;
- s->srbi = 0;
- } else {
- s->flip = 1;
- s->frbi = 0;
- s->srbi = 2;
- }
-
- return 0;
-}
-
-av_cold int ff_vp56_free(AVCodecContext *avctx)
-{
- VP56Context *s = avctx->priv_data;
- return ff_vp56_free_context(s);
-}
-
-av_cold int ff_vp56_free_context(VP56Context *s)
-{
- int i;
-
- av_freep(&s->above_blocks);
- av_freep(&s->macroblocks);
- av_freep(&s->edge_emu_buffer_alloc);
-
- for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++)
- av_frame_free(&s->frames[i]);
-
- return 0;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/vp56.h b/ffmpeg-2-8-11/libavcodec/vp56.h
deleted file mode 100644
index 34d4822..0000000
--- a/ffmpeg-2-8-11/libavcodec/vp56.h
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.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
- * VP5 and VP6 compatible video decoder (common features)
- */
-
-#ifndef AVCODEC_VP56_H
-#define AVCODEC_VP56_H
-
-#include "get_bits.h"
-#include "hpeldsp.h"
-#include "bytestream.h"
-#include "h264chroma.h"
-#include "videodsp.h"
-#include "vp3dsp.h"
-#include "vp56dsp.h"
-
-typedef struct vp56_context VP56Context;
-
-typedef enum {
- VP56_FRAME_NONE =-1,
- VP56_FRAME_CURRENT = 0,
- VP56_FRAME_PREVIOUS = 1,
- VP56_FRAME_GOLDEN = 2,
- VP56_FRAME_GOLDEN2 = 3,
-} VP56Frame;
-
-typedef enum {
- VP56_MB_INTER_NOVEC_PF = 0, /**< Inter MB, no vector, from previous frame */
- VP56_MB_INTRA = 1, /**< Intra MB */
- VP56_MB_INTER_DELTA_PF = 2, /**< Inter MB, above/left vector + delta, from previous frame */
- VP56_MB_INTER_V1_PF = 3, /**< Inter MB, first vector, from previous frame */
- VP56_MB_INTER_V2_PF = 4, /**< Inter MB, second vector, from previous frame */
- VP56_MB_INTER_NOVEC_GF = 5, /**< Inter MB, no vector, from golden frame */
- VP56_MB_INTER_DELTA_GF = 6, /**< Inter MB, above/left vector + delta, from golden frame */
- VP56_MB_INTER_4V = 7, /**< Inter MB, 4 vectors, from previous frame */
- VP56_MB_INTER_V1_GF = 8, /**< Inter MB, first vector, from golden frame */
- VP56_MB_INTER_V2_GF = 9, /**< Inter MB, second vector, from golden frame */
-} VP56mb;
-
-typedef struct VP56Tree {
- int8_t val;
- int8_t prob_idx;
-} VP56Tree;
-
-typedef struct VP56mv {
- DECLARE_ALIGNED(4, int16_t, x);
- int16_t y;
-} VP56mv;
-
-#define VP56_SIZE_CHANGE 1
-
-typedef void (*VP56ParseVectorAdjustment)(VP56Context *s,
- VP56mv *vect);
-typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src,
- int offset1, int offset2, int stride,
- VP56mv mv, int mask, int select, int luma);
-typedef int (*VP56ParseCoeff)(VP56Context *s);
-typedef void (*VP56DefaultModelsInit)(VP56Context *s);
-typedef void (*VP56ParseVectorModels)(VP56Context *s);
-typedef int (*VP56ParseCoeffModels)(VP56Context *s);
-typedef int (*VP56ParseHeader)(VP56Context *s, const uint8_t *buf,
- int buf_size);
-
-typedef struct VP56RangeCoder {
- int high;
- int bits; /* stored negated (i.e. negative "bits" is a positive number of
- bits left) in order to eliminate a negate in cache refilling */
- const uint8_t *buffer;
- const uint8_t *end;
- unsigned int code_word;
-} VP56RangeCoder;
-
-typedef struct VP56RefDc {
- uint8_t not_null_dc;
- VP56Frame ref_frame;
- int16_t dc_coeff;
-} VP56RefDc;
-
-typedef struct VP56Macroblock {
- uint8_t type;
- VP56mv mv;
-} VP56Macroblock;
-
-typedef struct VP56Model {
- uint8_t coeff_reorder[64]; /* used in vp6 only */
- uint8_t coeff_index_to_pos[64]; /* used in vp6 only */
- uint8_t vector_sig[2]; /* delta sign */
- uint8_t vector_dct[2]; /* delta coding types */
- uint8_t vector_pdi[2][2]; /* predefined delta init */
- uint8_t vector_pdv[2][7]; /* predefined delta values */
- uint8_t vector_fdv[2][8]; /* 8 bit delta value definition */
- uint8_t coeff_dccv[2][11]; /* DC coeff value */
- uint8_t coeff_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */
- uint8_t coeff_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */
- uint8_t coeff_dcct[2][36][5]; /* DC coeff coding type */
- uint8_t coeff_runv[2][14]; /* run value (vp6 only) */
- uint8_t mb_type[3][10][10]; /* model for decoding MB type */
- uint8_t mb_types_stats[3][10][2];/* contextual, next MB type stats */
-} VP56Model;
-
-struct vp56_context {
- AVCodecContext *avctx;
- H264ChromaContext h264chroma;
- HpelDSPContext hdsp;
- VideoDSPContext vdsp;
- VP3DSPContext vp3dsp;
- VP56DSPContext vp56dsp;
- uint8_t idct_scantable[64];
- AVFrame *frames[4];
- uint8_t *edge_emu_buffer_alloc;
- uint8_t *edge_emu_buffer;
- VP56RangeCoder c;
- VP56RangeCoder cc;
- VP56RangeCoder *ccp;
- int sub_version;
-
- /* frame info */
- int golden_frame;
- int plane_width[4];
- int plane_height[4];
- int mb_width; /* number of horizontal MB */
- int mb_height; /* number of vertical MB */
- int block_offset[6];
-
- int quantizer;
- uint16_t dequant_dc;
- uint16_t dequant_ac;
-
- /* DC predictors management */
- VP56RefDc *above_blocks;
- VP56RefDc left_block[4];
- int above_block_idx[6];
- int16_t prev_dc[3][3]; /* [plan][ref_frame] */
-
- /* blocks / macroblock */
- VP56mb mb_type;
- VP56Macroblock *macroblocks;
- DECLARE_ALIGNED(16, int16_t, block_coeff)[6][64];
-
- /* motion vectors */
- VP56mv mv[6]; /* vectors for each block in MB */
- VP56mv vector_candidate[2];
- int vector_candidate_pos;
-
- /* filtering hints */
- int filter_header; /* used in vp6 only */
- int deblock_filtering;
- int filter_selection;
- int filter_mode;
- int max_vector_length;
- int sample_variance_threshold;
-
- uint8_t coeff_ctx[4][64]; /* used in vp5 only */
- uint8_t coeff_ctx_last[4]; /* used in vp5 only */
-
- int has_alpha;
-
- /* upside-down flipping hints */
- int flip; /* are we flipping ? */
- int frbi; /* first row block index in MB */
- int srbi; /* second row block index in MB */
- int stride[4]; /* stride for each plan */
-
- const uint8_t *vp56_coord_div;
- VP56ParseVectorAdjustment parse_vector_adjustment;
- VP56Filter filter;
- VP56ParseCoeff parse_coeff;
- VP56DefaultModelsInit default_models_init;
- VP56ParseVectorModels parse_vector_models;
- VP56ParseCoeffModels parse_coeff_models;
- VP56ParseHeader parse_header;
-
- /* for "slice" parallelism between YUV and A */
- VP56Context *alpha_context;
-
- VP56Model *modelp;
- VP56Model model;
-
- /* huffman decoding */
- int use_huffman;
- GetBitContext gb;
- VLC dccv_vlc[2];
- VLC runv_vlc[2];
- VLC ract_vlc[2][3][6];
- unsigned int nb_null[2][2]; /* number of consecutive NULL DC/AC */
-};
-
-
-int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha);
-int ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
- int flip, int has_alpha);
-int ff_vp56_free(AVCodecContext *avctx);
-int ff_vp56_free_context(VP56Context *s);
-void ff_vp56_init_dequant(VP56Context *s, int quantizer);
-int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *avpkt);
-
-
-/**
- * vp56 specific range coder implementation
- */
-
-extern const uint8_t ff_vp56_norm_shift[256];
-void ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size);
-
-static av_always_inline unsigned int vp56_rac_renorm(VP56RangeCoder *c)
-{
- int shift = ff_vp56_norm_shift[c->high];
- int bits = c->bits;
- unsigned int code_word = c->code_word;
-
- c->high <<= shift;
- code_word <<= shift;
- bits += shift;
- if(bits >= 0 && c->buffer < c->end) {
- code_word |= bytestream_get_be16(&c->buffer) << bits;
- bits -= 16;
- }
- c->bits = bits;
- return code_word;
-}
-
-#if ARCH_ARM
-#include "arm/vp56_arith.h"
-#elif ARCH_X86
-#include "x86/vp56_arith.h"
-#endif
-
-#ifndef vp56_rac_get_prob
-#define vp56_rac_get_prob vp56_rac_get_prob
-static av_always_inline int vp56_rac_get_prob(VP56RangeCoder *c, uint8_t prob)
-{
- unsigned int code_word = vp56_rac_renorm(c);
- unsigned int low = 1 + (((c->high - 1) * prob) >> 8);
- unsigned int low_shift = low << 16;
- int bit = code_word >= low_shift;
-
- c->high = bit ? c->high - low : low;
- c->code_word = bit ? code_word - low_shift : code_word;
-
- return bit;
-}
-#endif
-
-#ifndef vp56_rac_get_prob_branchy
-// branchy variant, to be used where there's a branch based on the bit decoded
-static av_always_inline int vp56_rac_get_prob_branchy(VP56RangeCoder *c, int prob)
-{
- unsigned long code_word = vp56_rac_renorm(c);
- unsigned low = 1 + (((c->high - 1) * prob) >> 8);
- unsigned low_shift = low << 16;
-
- if (code_word >= low_shift) {
- c->high -= low;
- c->code_word = code_word - low_shift;
- return 1;
- }
-
- c->high = low;
- c->code_word = code_word;
- return 0;
-}
-#endif
-
-static av_always_inline int vp56_rac_get(VP56RangeCoder *c)
-{
- unsigned int code_word = vp56_rac_renorm(c);
- /* equiprobable */
- int low = (c->high + 1) >> 1;
- unsigned int low_shift = low << 16;
- int bit = code_word >= low_shift;
- if (bit) {
- c->high -= low;
- code_word -= low_shift;
- } else {
- c->high = low;
- }
-
- c->code_word = code_word;
- return bit;
-}
-
-// rounding is different than vp56_rac_get, is vp56_rac_get wrong?
-static av_always_inline int vp8_rac_get(VP56RangeCoder *c)
-{
- return vp56_rac_get_prob(c, 128);
-}
-
-static int vp56_rac_gets(VP56RangeCoder *c, int bits)
-{
- int value = 0;
-
- while (bits--) {
- value = (value << 1) | vp56_rac_get(c);
- }
-
- return value;
-}
-
-static int vp8_rac_get_uint(VP56RangeCoder *c, int bits)
-{
- int value = 0;
-
- while (bits--) {
- value = (value << 1) | vp8_rac_get(c);
- }
-
- return value;
-}
-
-// fixme: add 1 bit to all the calls to this?
-static av_unused int vp8_rac_get_sint(VP56RangeCoder *c, int bits)
-{
- int v;
-
- if (!vp8_rac_get(c))
- return 0;
-
- v = vp8_rac_get_uint(c, bits);
-
- if (vp8_rac_get(c))
- v = -v;
-
- return v;
-}
-
-// P(7)
-static av_unused int vp56_rac_gets_nn(VP56RangeCoder *c, int bits)
-{
- int v = vp56_rac_gets(c, 7) << 1;
- return v + !v;
-}
-
-static av_unused int vp8_rac_get_nn(VP56RangeCoder *c)
-{
- int v = vp8_rac_get_uint(c, 7) << 1;
- return v + !v;
-}
-
-static av_always_inline
-int vp56_rac_get_tree(VP56RangeCoder *c,
- const VP56Tree *tree,
- const uint8_t *probs)
-{
- while (tree->val > 0) {
- if (vp56_rac_get_prob_branchy(c, probs[tree->prob_idx]))
- tree += tree->val;
- else
- tree++;
- }
- return -tree->val;
-}
-
-// how probabilities are associated with decisions is different I think
-// well, the new scheme fits in the old but this way has one fewer branches per decision
-static av_always_inline int vp8_rac_get_tree(VP56RangeCoder *c, const int8_t (*tree)[2],
- const uint8_t *probs)
-{
- int i = 0;
-
- do {
- i = tree[i][vp56_rac_get_prob(c, probs[i])];
- } while (i > 0);
-
- return -i;
-}
-
-// DCTextra
-static av_always_inline int vp8_rac_get_coeff(VP56RangeCoder *c, const uint8_t *prob)
-{
- int v = 0;
-
- do {
- v = (v<<1) + vp56_rac_get_prob(c, *prob++);
- } while (*prob);
-
- return v;
-}
-
-#endif /* AVCODEC_VP56_H */
diff --git a/ffmpeg-2-8-11/libavcodec/vp56rac.c b/ffmpeg-2-8-11/libavcodec/vp56rac.c
deleted file mode 100644
index 6061b7e..0000000
--- a/ffmpeg-2-8-11/libavcodec/vp56rac.c
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * VP5/6/8 decoder
- * Copyright (c) 2010 Fiona Glaser <fiona at x264.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 "libavutil/common.h"
-#include "vp56.h"
-
-const uint8_t ff_vp56_norm_shift[256]= {
- 8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4,
- 3,3,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,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,
- 1,1,1,1,1,1,1,1,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,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-};
-
-void ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size)
-{
- c->high = 255;
- c->bits = -16;
- c->buffer = buf;
- c->end = buf + buf_size;
- c->code_word = bytestream_get_be24(&c->buffer);
-}
diff --git a/ffmpeg-2-8-11/libavcodec/vp6.c b/ffmpeg-2-8-11/libavcodec/vp6.c
deleted file mode 100644
index 7f0a9b7..0000000
--- a/ffmpeg-2-8-11/libavcodec/vp6.c
+++ /dev/null
@@ -1,716 +0,0 @@
-/*
- * Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.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
- * VP6 compatible video decoder
- *
- * The VP6F decoder accepts an optional 1 byte extradata. It is composed of:
- * - upper 4 bits: difference between encoded width and visible width
- * - lower 4 bits: difference between encoded height and visible height
- */
-
-#include <stdlib.h>
-
-#include "avcodec.h"
-#include "get_bits.h"
-#include "huffman.h"
-#include "internal.h"
-
-#include "vp56.h"
-#include "vp56data.h"
-#include "vp6data.h"
-
-#define VP6_MAX_HUFF_SIZE 12
-
-static int vp6_parse_coeff(VP56Context *s);
-static int vp6_parse_coeff_huffman(VP56Context *s);
-
-static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
-{
- VP56RangeCoder *c = &s->c;
- int parse_filter_info = 0;
- int coeff_offset = 0;
- int vrt_shift = 0;
- int sub_version;
- int rows, cols;
- int res = 0;
- int separated_coeff = buf[0] & 1;
-
- s->frames[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80);
- ff_vp56_init_dequant(s, (buf[0] >> 1) & 0x3F);
-
- if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
- sub_version = buf[1] >> 3;
- if (sub_version > 8)
- return AVERROR_INVALIDDATA;
- s->filter_header = buf[1] & 0x06;
- if (buf[1] & 1) {
- avpriv_report_missing_feature(s->avctx, "Interlacing");
- return AVERROR_PATCHWELCOME;
- }
- if (separated_coeff || !s->filter_header) {
- coeff_offset = AV_RB16(buf+2) - 2;
- buf += 2;
- buf_size -= 2;
- }
-
- rows = buf[2]; /* number of stored macroblock rows */
- cols = buf[3]; /* number of stored macroblock cols */
- /* buf[4] is number of displayed macroblock rows */
- /* buf[5] is number of displayed macroblock cols */
- if (!rows || !cols) {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n", cols << 4, rows << 4);
- return AVERROR_INVALIDDATA;
- }
-
- if (!s->macroblocks || /* first frame */
- 16*cols != s->avctx->coded_width ||
- 16*rows != s->avctx->coded_height) {
- if (s->avctx->extradata_size == 0 &&
- FFALIGN(s->avctx->width, 16) == 16 * cols &&
- FFALIGN(s->avctx->height, 16) == 16 * rows) {
- // We assume this is properly signalled container cropping,
- // in an F4V file. Just set the coded_width/height, don't
- // touch the cropped ones.
- s->avctx->coded_width = 16 * cols;
- s->avctx->coded_height = 16 * rows;
- } else {
- int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows);
- if (ret < 0)
- return ret;
-
- if (s->avctx->extradata_size == 1) {
- s->avctx->width -= s->avctx->extradata[0] >> 4;
- s->avctx->height -= s->avctx->extradata[0] & 0x0F;
- }
- }
- res = VP56_SIZE_CHANGE;
- }
-
- ff_vp56_init_range_decoder(c, buf+6, buf_size-6);
- vp56_rac_gets(c, 2);
-
- parse_filter_info = s->filter_header;
- if (sub_version < 8)
- vrt_shift = 5;
- s->sub_version = sub_version;
- s->golden_frame = 0;
- } else {
- if (!s->sub_version || !s->avctx->coded_width || !s->avctx->coded_height)
- return AVERROR_INVALIDDATA;
-
- if (separated_coeff || !s->filter_header) {
- coeff_offset = AV_RB16(buf+1) - 2;
- buf += 2;
- buf_size -= 2;
- }
- ff_vp56_init_range_decoder(c, buf+1, buf_size-1);
-
- s->golden_frame = vp56_rac_get(c);
- if (s->filter_header) {
- s->deblock_filtering = vp56_rac_get(c);
- if (s->deblock_filtering)
- vp56_rac_get(c);
- if (s->sub_version > 7)
- parse_filter_info = vp56_rac_get(c);
- }
- }
-
- if (parse_filter_info) {
- if (vp56_rac_get(c)) {
- s->filter_mode = 2;
- s->sample_variance_threshold = vp56_rac_gets(c, 5) << vrt_shift;
- s->max_vector_length = 2 << vp56_rac_gets(c, 3);
- } else if (vp56_rac_get(c)) {
- s->filter_mode = 1;
- } else {
- s->filter_mode = 0;
- }
- if (s->sub_version > 7)
- s->filter_selection = vp56_rac_gets(c, 4);
- else
- s->filter_selection = 16;
- }
-
- s->use_huffman = vp56_rac_get(c);
-
- s->parse_coeff = vp6_parse_coeff;
- if (coeff_offset) {
- buf += coeff_offset;
- buf_size -= coeff_offset;
- if (buf_size < 0) {
- if (s->frames[VP56_FRAME_CURRENT]->key_frame)
- ff_set_dimensions(s->avctx, 0, 0);
- return AVERROR_INVALIDDATA;
- }
- if (s->use_huffman) {
- s->parse_coeff = vp6_parse_coeff_huffman;
- init_get_bits(&s->gb, buf, buf_size<<3);
- } else {
- ff_vp56_init_range_decoder(&s->cc, buf, buf_size);
- s->ccp = &s->cc;
- }
- } else {
- s->ccp = &s->c;
- }
-
- return res;
-}
-
-static void vp6_coeff_order_table_init(VP56Context *s)
-{
- int i, pos, idx = 1;
-
- s->modelp->coeff_index_to_pos[0] = 0;
- for (i=0; i<16; i++)
- for (pos=1; pos<64; pos++)
- if (s->modelp->coeff_reorder[pos] == i)
- s->modelp->coeff_index_to_pos[idx++] = pos;
-}
-
-static void vp6_default_models_init(VP56Context *s)
-{
- VP56Model *model = s->modelp;
-
- model->vector_dct[0] = 0xA2;
- model->vector_dct[1] = 0xA4;
- model->vector_sig[0] = 0x80;
- model->vector_sig[1] = 0x80;
-
- memcpy(model->mb_types_stats, ff_vp56_def_mb_types_stats, sizeof(model->mb_types_stats));
- memcpy(model->vector_fdv, vp6_def_fdv_vector_model, sizeof(model->vector_fdv));
- memcpy(model->vector_pdv, vp6_def_pdv_vector_model, sizeof(model->vector_pdv));
- memcpy(model->coeff_runv, vp6_def_runv_coeff_model, sizeof(model->coeff_runv));
- memcpy(model->coeff_reorder, vp6_def_coeff_reorder, sizeof(model->coeff_reorder));
-
- vp6_coeff_order_table_init(s);
-}
-
-static void vp6_parse_vector_models(VP56Context *s)
-{
- VP56RangeCoder *c = &s->c;
- VP56Model *model = s->modelp;
- int comp, node;
-
- for (comp=0; comp<2; comp++) {
- if (vp56_rac_get_prob_branchy(c, vp6_sig_dct_pct[comp][0]))
- model->vector_dct[comp] = vp56_rac_gets_nn(c, 7);
- if (vp56_rac_get_prob_branchy(c, vp6_sig_dct_pct[comp][1]))
- model->vector_sig[comp] = vp56_rac_gets_nn(c, 7);
- }
-
- for (comp=0; comp<2; comp++)
- for (node=0; node<7; node++)
- if (vp56_rac_get_prob_branchy(c, vp6_pdv_pct[comp][node]))
- model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7);
-
- for (comp=0; comp<2; comp++)
- for (node=0; node<8; node++)
- if (vp56_rac_get_prob_branchy(c, vp6_fdv_pct[comp][node]))
- model->vector_fdv[comp][node] = vp56_rac_gets_nn(c, 7);
-}
-
-/* nodes must ascend by count, but with descending symbol order */
-static int vp6_huff_cmp(const void *va, const void *vb)
-{
- const Node *a = va, *b = vb;
- return (a->count - b->count)*16 + (b->sym - a->sym);
-}
-
-static int vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[],
- const uint8_t *map, unsigned size, VLC *vlc)
-{
- Node nodes[2*VP6_MAX_HUFF_SIZE], *tmp = &nodes[size];
- int a, b, i;
-
- /* first compute probabilities from model */
- tmp[0].count = 256;
- for (i=0; i<size-1; i++) {
- a = tmp[i].count * coeff_model[i] >> 8;
- b = tmp[i].count * (255 - coeff_model[i]) >> 8;
- nodes[map[2*i ]].count = a + !a;
- nodes[map[2*i+1]].count = b + !b;
- }
-
- ff_free_vlc(vlc);
- /* then build the huffman tree according to probabilities */
- return ff_huff_build_tree(s->avctx, vlc, size, FF_HUFFMAN_BITS,
- nodes, vp6_huff_cmp,
- FF_HUFFMAN_FLAG_HNODE_FIRST);
-}
-
-static int vp6_parse_coeff_models(VP56Context *s)
-{
- VP56RangeCoder *c = &s->c;
- VP56Model *model = s->modelp;
- int def_prob[11];
- int node, cg, ctx, pos;
- int ct; /* code type */
- int pt; /* plane type (0 for Y, 1 for U or V) */
-
- memset(def_prob, 0x80, sizeof(def_prob));
-
- for (pt=0; pt<2; pt++)
- for (node=0; node<11; node++)
- if (vp56_rac_get_prob_branchy(c, vp6_dccv_pct[pt][node])) {
- def_prob[node] = vp56_rac_gets_nn(c, 7);
- model->coeff_dccv[pt][node] = def_prob[node];
- } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
- model->coeff_dccv[pt][node] = def_prob[node];
- }
-
- if (vp56_rac_get(c)) {
- for (pos=1; pos<64; pos++)
- if (vp56_rac_get_prob_branchy(c, vp6_coeff_reorder_pct[pos]))
- model->coeff_reorder[pos] = vp56_rac_gets(c, 4);
- vp6_coeff_order_table_init(s);
- }
-
- for (cg=0; cg<2; cg++)
- for (node=0; node<14; node++)
- if (vp56_rac_get_prob_branchy(c, vp6_runv_pct[cg][node]))
- model->coeff_runv[cg][node] = vp56_rac_gets_nn(c, 7);
-
- for (ct=0; ct<3; ct++)
- for (pt=0; pt<2; pt++)
- for (cg=0; cg<6; cg++)
- for (node=0; node<11; node++)
- if (vp56_rac_get_prob_branchy(c, vp6_ract_pct[ct][pt][cg][node])) {
- def_prob[node] = vp56_rac_gets_nn(c, 7);
- model->coeff_ract[pt][ct][cg][node] = def_prob[node];
- } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
- model->coeff_ract[pt][ct][cg][node] = def_prob[node];
- }
-
- if (s->use_huffman) {
- for (pt=0; pt<2; pt++) {
- if (vp6_build_huff_tree(s, model->coeff_dccv[pt],
- vp6_huff_coeff_map, 12, &s->dccv_vlc[pt]))
- return -1;
- if (vp6_build_huff_tree(s, model->coeff_runv[pt],
- vp6_huff_run_map, 9, &s->runv_vlc[pt]))
- return -1;
- for (ct=0; ct<3; ct++)
- for (cg = 0; cg < 6; cg++)
- if (vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg],
- vp6_huff_coeff_map, 12,
- &s->ract_vlc[pt][ct][cg]))
- return -1;
- }
- memset(s->nb_null, 0, sizeof(s->nb_null));
- } else {
- /* coeff_dcct is a linear combination of coeff_dccv */
- for (pt=0; pt<2; pt++)
- for (ctx=0; ctx<3; ctx++)
- for (node=0; node<5; node++)
- model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp6_dccv_lc[ctx][node][0] + 128) >> 8) + vp6_dccv_lc[ctx][node][1], 1, 255);
- }
- return 0;
-}
-
-static void vp6_parse_vector_adjustment(VP56Context *s, VP56mv *vect)
-{
- VP56RangeCoder *c = &s->c;
- VP56Model *model = s->modelp;
- int comp;
-
- *vect = (VP56mv) {0,0};
- if (s->vector_candidate_pos < 2)
- *vect = s->vector_candidate[0];
-
- for (comp=0; comp<2; comp++) {
- int i, delta = 0;
-
- if (vp56_rac_get_prob_branchy(c, model->vector_dct[comp])) {
- static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4};
- for (i=0; i<sizeof(prob_order); i++) {
- int j = prob_order[i];
- delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][j])<<j;
- }
- if (delta & 0xF0)
- delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][3])<<3;
- else
- delta |= 8;
- } else {
- delta = vp56_rac_get_tree(c, ff_vp56_pva_tree,
- model->vector_pdv[comp]);
- }
-
- if (delta && vp56_rac_get_prob_branchy(c, model->vector_sig[comp]))
- delta = -delta;
-
- if (!comp)
- vect->x += delta;
- else
- vect->y += delta;
- }
-}
-
-/**
- * Read number of consecutive blocks with null DC or AC.
- * This value is < 74.
- */
-static unsigned vp6_get_nb_null(VP56Context *s)
-{
- unsigned val = get_bits(&s->gb, 2);
- if (val == 2)
- val += get_bits(&s->gb, 2);
- else if (val == 3) {
- val = get_bits1(&s->gb) << 2;
- val = 6+val + get_bits(&s->gb, 2+val);
- }
- return val;
-}
-
-static int vp6_parse_coeff_huffman(VP56Context *s)
-{
- VP56Model *model = s->modelp;
- uint8_t *permute = s->idct_scantable;
- VLC *vlc_coeff;
- int coeff, sign, coeff_idx;
- int b, cg, idx;
- int pt = 0; /* plane type (0 for Y, 1 for U or V) */
-
- for (b=0; b<6; b++) {
- int ct = 0; /* code type */
- if (b > 3) pt = 1;
- vlc_coeff = &s->dccv_vlc[pt];
-
- for (coeff_idx = 0;;) {
- int run = 1;
- if (coeff_idx<2 && s->nb_null[coeff_idx][pt]) {
- s->nb_null[coeff_idx][pt]--;
- if (coeff_idx)
- break;
- } else {
- if (get_bits_left(&s->gb) <= 0)
- return AVERROR_INVALIDDATA;
- coeff = get_vlc2(&s->gb, vlc_coeff->table, FF_HUFFMAN_BITS, 3);
- if (coeff == 0) {
- if (coeff_idx) {
- int pt = (coeff_idx >= 6);
- run += get_vlc2(&s->gb, s->runv_vlc[pt].table, FF_HUFFMAN_BITS, 3);
- if (run >= 9)
- run += get_bits(&s->gb, 6);
- } else
- s->nb_null[0][pt] = vp6_get_nb_null(s);
- ct = 0;
- } else if (coeff == 11) { /* end of block */
- if (coeff_idx == 1) /* first AC coeff ? */
- s->nb_null[1][pt] = vp6_get_nb_null(s);
- break;
- } else {
- int coeff2 = ff_vp56_coeff_bias[coeff];
- if (coeff > 4)
- coeff2 += get_bits(&s->gb, coeff <= 9 ? coeff - 4 : 11);
- ct = 1 + (coeff2 > 1);
- sign = get_bits1(&s->gb);
- coeff2 = (coeff2 ^ -sign) + sign;
- if (coeff_idx)
- coeff2 *= s->dequant_ac;
- idx = model->coeff_index_to_pos[coeff_idx];
- s->block_coeff[b][permute[idx]] = coeff2;
- }
- }
- coeff_idx+=run;
- if (coeff_idx >= 64)
- break;
- cg = FFMIN(vp6_coeff_groups[coeff_idx], 3);
- vlc_coeff = &s->ract_vlc[pt][ct][cg];
- }
- }
- return 0;
-}
-
-static int vp6_parse_coeff(VP56Context *s)
-{
- VP56RangeCoder *c = s->ccp;
- VP56Model *model = s->modelp;
- uint8_t *permute = s->idct_scantable;
- uint8_t *model1, *model2, *model3;
- int coeff, sign, coeff_idx;
- int b, i, cg, idx, ctx;
- int pt = 0; /* plane type (0 for Y, 1 for U or V) */
-
- if (c->end >= c->buffer && c->bits >= 0) {
- av_log(s->avctx, AV_LOG_ERROR, "End of AC stream reached in vp6_parse_coeff\n");
- return AVERROR_INVALIDDATA;
- }
-
- for (b=0; b<6; b++) {
- int ct = 1; /* code type */
- int run = 1;
-
- if (b > 3) pt = 1;
-
- ctx = s->left_block[ff_vp56_b6to4[b]].not_null_dc
- + s->above_blocks[s->above_block_idx[b]].not_null_dc;
- model1 = model->coeff_dccv[pt];
- model2 = model->coeff_dcct[pt][ctx];
-
- coeff_idx = 0;
- for (;;) {
- if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob_branchy(c, model2[0])) {
- /* parse a coeff */
- if (vp56_rac_get_prob_branchy(c, model2[2])) {
- if (vp56_rac_get_prob_branchy(c, model2[3])) {
- idx = vp56_rac_get_tree(c, ff_vp56_pc_tree, model1);
- coeff = ff_vp56_coeff_bias[idx+5];
- for (i=ff_vp56_coeff_bit_length[idx]; i>=0; i--)
- coeff += vp56_rac_get_prob(c, ff_vp56_coeff_parse_table[idx][i]) << i;
- } else {
- if (vp56_rac_get_prob_branchy(c, model2[4]))
- coeff = 3 + vp56_rac_get_prob(c, model1[5]);
- else
- coeff = 2;
- }
- ct = 2;
- } else {
- ct = 1;
- coeff = 1;
- }
- sign = vp56_rac_get(c);
- coeff = (coeff ^ -sign) + sign;
- if (coeff_idx)
- coeff *= s->dequant_ac;
- idx = model->coeff_index_to_pos[coeff_idx];
- s->block_coeff[b][permute[idx]] = coeff;
- run = 1;
- } else {
- /* parse a run */
- ct = 0;
- if (coeff_idx > 0) {
- if (!vp56_rac_get_prob_branchy(c, model2[1]))
- break;
-
- model3 = model->coeff_runv[coeff_idx >= 6];
- run = vp56_rac_get_tree(c, vp6_pcr_tree, model3);
- if (!run)
- for (run=9, i=0; i<6; i++)
- run += vp56_rac_get_prob(c, model3[i+8]) << i;
- }
- }
- coeff_idx += run;
- if (coeff_idx >= 64)
- break;
- cg = vp6_coeff_groups[coeff_idx];
- model1 = model2 = model->coeff_ract[pt][ct][cg];
- }
-
- s->left_block[ff_vp56_b6to4[b]].not_null_dc =
- s->above_blocks[s->above_block_idx[b]].not_null_dc = !!s->block_coeff[b][0];
- }
- return 0;
-}
-
-static int vp6_block_variance(uint8_t *src, int stride)
-{
- int sum = 0, square_sum = 0;
- int y, x;
-
- for (y=0; y<8; y+=2) {
- for (x=0; x<8; x+=2) {
- sum += src[x];
- square_sum += src[x]*src[x];
- }
- src += 2*stride;
- }
- return (16*square_sum - sum*sum) >> 8;
-}
-
-static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride,
- int delta, const int16_t *weights)
-{
- int x, y;
-
- for (y=0; y<8; y++) {
- for (x=0; x<8; x++) {
- dst[x] = av_clip_uint8(( src[x-delta ] * weights[0]
- + src[x ] * weights[1]
- + src[x+delta ] * weights[2]
- + src[x+2*delta] * weights[3] + 64) >> 7);
- }
- src += stride;
- dst += stride;
- }
-}
-
-static void vp6_filter_diag2(VP56Context *s, uint8_t *dst, uint8_t *src,
- int stride, int h_weight, int v_weight)
-{
- uint8_t *tmp = s->edge_emu_buffer+16;
- s->h264chroma.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0);
- s->h264chroma.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight);
-}
-
-static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src,
- int offset1, int offset2, int stride,
- VP56mv mv, int mask, int select, int luma)
-{
- int filter4 = 0;
- int x8 = mv.x & mask;
- int y8 = mv.y & mask;
-
- if (luma) {
- x8 *= 2;
- y8 *= 2;
- filter4 = s->filter_mode;
- if (filter4 == 2) {
- if (s->max_vector_length &&
- (FFABS(mv.x) > s->max_vector_length ||
- FFABS(mv.y) > s->max_vector_length)) {
- filter4 = 0;
- } else if (s->sample_variance_threshold
- && (vp6_block_variance(src+offset1, stride)
- < s->sample_variance_threshold)) {
- filter4 = 0;
- }
- }
- }
-
- if ((y8 && (offset2-offset1)*s->flip<0) || (!y8 && offset1 > offset2)) {
- offset1 = offset2;
- }
-
- if (filter4) {
- if (!y8) { /* left or right combine */
- vp6_filter_hv4(dst, src+offset1, stride, 1,
- vp6_block_copy_filter[select][x8]);
- } else if (!x8) { /* above or below combine */
- vp6_filter_hv4(dst, src+offset1, stride, stride,
- vp6_block_copy_filter[select][y8]);
- } else {
- s->vp56dsp.vp6_filter_diag4(dst, src+offset1+((mv.x^mv.y)>>31), stride,
- vp6_block_copy_filter[select][x8],
- vp6_block_copy_filter[select][y8]);
- }
- } else {
- if (!x8 || !y8) {
- s->h264chroma.put_h264_chroma_pixels_tab[0](dst, src + offset1, stride, 8, x8, y8);
- } else {
- vp6_filter_diag2(s, dst, src+offset1 + ((mv.x^mv.y)>>31), stride, x8, y8);
- }
- }
-}
-
-static av_cold void vp6_decode_init_context(VP56Context *s);
-
-static av_cold int vp6_decode_init(AVCodecContext *avctx)
-{
- VP56Context *s = avctx->priv_data;
- int ret;
-
- if ((ret = ff_vp56_init(avctx, avctx->codec->id == AV_CODEC_ID_VP6,
- avctx->codec->id == AV_CODEC_ID_VP6A)) < 0)
- return ret;
-
- vp6_decode_init_context(s);
-
- if (s->has_alpha) {
- s->alpha_context = av_mallocz(sizeof(VP56Context));
- ff_vp56_init_context(avctx, s->alpha_context,
- s->flip == -1, s->has_alpha);
- vp6_decode_init_context(s->alpha_context);
- }
-
- return 0;
-}
-
-static av_cold void vp6_decode_init_context(VP56Context *s)
-{
- s->deblock_filtering = 0;
- s->vp56_coord_div = vp6_coord_div;
- s->parse_vector_adjustment = vp6_parse_vector_adjustment;
- s->filter = vp6_filter;
- s->default_models_init = vp6_default_models_init;
- s->parse_vector_models = vp6_parse_vector_models;
- s->parse_coeff_models = vp6_parse_coeff_models;
- s->parse_header = vp6_parse_header;
-}
-
-static av_cold void vp6_decode_free_context(VP56Context *s);
-
-static av_cold int vp6_decode_free(AVCodecContext *avctx)
-{
- VP56Context *s = avctx->priv_data;
-
- ff_vp56_free(avctx);
- vp6_decode_free_context(s);
-
- if (s->alpha_context) {
- ff_vp56_free_context(s->alpha_context);
- vp6_decode_free_context(s->alpha_context);
- av_freep(&s->alpha_context);
- }
-
- return 0;
-}
-
-static av_cold void vp6_decode_free_context(VP56Context *s)
-{
- int pt, ct, cg;
-
- for (pt=0; pt<2; pt++) {
- ff_free_vlc(&s->dccv_vlc[pt]);
- ff_free_vlc(&s->runv_vlc[pt]);
- for (ct=0; ct<3; ct++)
- for (cg=0; cg<6; cg++)
- ff_free_vlc(&s->ract_vlc[pt][ct][cg]);
- }
-}
-
-AVCodec ff_vp6_decoder = {
- .name = "vp6",
- .long_name = NULL_IF_CONFIG_SMALL("On2 VP6"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_VP6,
- .priv_data_size = sizeof(VP56Context),
- .init = vp6_decode_init,
- .close = vp6_decode_free,
- .decode = ff_vp56_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
-
-/* flash version, not flipped upside-down */
-AVCodec ff_vp6f_decoder = {
- .name = "vp6f",
- .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_VP6F,
- .priv_data_size = sizeof(VP56Context),
- .init = vp6_decode_init,
- .close = vp6_decode_free,
- .decode = ff_vp56_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
-
-/* flash version, not flipped upside-down, with alpha channel */
-AVCodec ff_vp6a_decoder = {
- .name = "vp6a",
- .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_VP6A,
- .priv_data_size = sizeof(VP56Context),
- .init = vp6_decode_init,
- .close = vp6_decode_free,
- .decode = ff_vp56_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/vp8.c b/ffmpeg-2-8-11/libavcodec/vp8.c
deleted file mode 100644
index cb0c7cd..0000000
--- a/ffmpeg-2-8-11/libavcodec/vp8.c
+++ /dev/null
@@ -1,2855 +0,0 @@
-/*
- * VP7/VP8 compatible video decoder
- *
- * Copyright (C) 2010 David Conrad
- * Copyright (C) 2010 Ronald S. Bultje
- * Copyright (C) 2010 Fiona Glaser
- * Copyright (C) 2012 Daniel Kang
- * Copyright (C) 2014 Peter Ross
- *
- * 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 "avcodec.h"
-#include "internal.h"
-#include "rectangle.h"
-#include "thread.h"
-#include "vp8.h"
-#include "vp8data.h"
-
-#if ARCH_ARM
-# include "arm/vp8.h"
-#endif
-
-#if CONFIG_VP7_DECODER && CONFIG_VP8_DECODER
-#define VPX(vp7, f) (vp7 ? vp7_ ## f : vp8_ ## f)
-#elif CONFIG_VP7_DECODER
-#define VPX(vp7, f) vp7_ ## f
-#else // CONFIG_VP8_DECODER
-#define VPX(vp7, f) vp8_ ## f
-#endif
-
-static void free_buffers(VP8Context *s)
-{
- int i;
- if (s->thread_data)
- for (i = 0; i < MAX_THREADS; i++) {
-#if HAVE_THREADS
- pthread_cond_destroy(&s->thread_data[i].cond);
- pthread_mutex_destroy(&s->thread_data[i].lock);
-#endif
- av_freep(&s->thread_data[i].filter_strength);
- }
- av_freep(&s->thread_data);
- av_freep(&s->macroblocks_base);
- av_freep(&s->intra4x4_pred_mode_top);
- av_freep(&s->top_nnz);
- av_freep(&s->top_border);
-
- s->macroblocks = NULL;
-}
-
-static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref)
-{
- int ret;
- if ((ret = ff_thread_get_buffer(s->avctx, &f->tf,
- ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
- return ret;
- if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height))) {
- ff_thread_release_buffer(s->avctx, &f->tf);
- return AVERROR(ENOMEM);
- }
- return 0;
-}
-
-static void vp8_release_frame(VP8Context *s, VP8Frame *f)
-{
- av_buffer_unref(&f->seg_map);
- ff_thread_release_buffer(s->avctx, &f->tf);
-}
-
-#if CONFIG_VP8_DECODER
-static int vp8_ref_frame(VP8Context *s, VP8Frame *dst, VP8Frame *src)
-{
- int ret;
-
- vp8_release_frame(s, dst);
-
- if ((ret = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0)
- return ret;
- if (src->seg_map &&
- !(dst->seg_map = av_buffer_ref(src->seg_map))) {
- vp8_release_frame(s, dst);
- return AVERROR(ENOMEM);
- }
-
- return 0;
-}
-#endif /* CONFIG_VP8_DECODER */
-
-static void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem)
-{
- VP8Context *s = avctx->priv_data;
- int i;
-
- for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++)
- vp8_release_frame(s, &s->frames[i]);
- memset(s->framep, 0, sizeof(s->framep));
-
- if (free_mem)
- free_buffers(s);
-}
-
-static void vp8_decode_flush(AVCodecContext *avctx)
-{
- vp8_decode_flush_impl(avctx, 0);
-}
-
-static VP8Frame *vp8_find_free_buffer(VP8Context *s)
-{
- VP8Frame *frame = NULL;
- int i;
-
- // find a free buffer
- for (i = 0; i < 5; i++)
- if (&s->frames[i] != s->framep[VP56_FRAME_CURRENT] &&
- &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] &&
- &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] &&
- &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2]) {
- frame = &s->frames[i];
- break;
- }
- if (i == 5) {
- av_log(s->avctx, AV_LOG_FATAL, "Ran out of free frames!\n");
- abort();
- }
- if (frame->tf.f->data[0])
- vp8_release_frame(s, frame);
-
- return frame;
-}
-
-static av_always_inline
-int update_dimensions(VP8Context *s, int width, int height, int is_vp7)
-{
- AVCodecContext *avctx = s->avctx;
- int i, ret;
-
- if (width != s->avctx->width || ((width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) && s->macroblocks_base ||
- height != s->avctx->height) {
- vp8_decode_flush_impl(s->avctx, 1);
-
- ret = ff_set_dimensions(s->avctx, width, height);
- if (ret < 0)
- return ret;
- }
-
- s->mb_width = (s->avctx->coded_width + 15) / 16;
- s->mb_height = (s->avctx->coded_height + 15) / 16;
-
- s->mb_layout = is_vp7 || avctx->active_thread_type == FF_THREAD_SLICE &&
- avctx->thread_count > 1;
- if (!s->mb_layout) { // Frame threading and one thread
- s->macroblocks_base = av_mallocz((s->mb_width + s->mb_height * 2 + 1) *
- sizeof(*s->macroblocks));
- s->intra4x4_pred_mode_top = av_mallocz(s->mb_width * 4);
- } else // Sliced threading
- s->macroblocks_base = av_mallocz((s->mb_width + 2) * (s->mb_height + 2) *
- sizeof(*s->macroblocks));
- s->top_nnz = av_mallocz(s->mb_width * sizeof(*s->top_nnz));
- s->top_border = av_mallocz((s->mb_width + 1) * sizeof(*s->top_border));
- s->thread_data = av_mallocz(MAX_THREADS * sizeof(VP8ThreadData));
-
- if (!s->macroblocks_base || !s->top_nnz || !s->top_border ||
- !s->thread_data || (!s->intra4x4_pred_mode_top && !s->mb_layout)) {
- free_buffers(s);
- return AVERROR(ENOMEM);
- }
-
- for (i = 0; i < MAX_THREADS; i++) {
- s->thread_data[i].filter_strength =
- av_mallocz(s->mb_width * sizeof(*s->thread_data[0].filter_strength));
- if (!s->thread_data[i].filter_strength) {
- free_buffers(s);
- return AVERROR(ENOMEM);
- }
-#if HAVE_THREADS
- pthread_mutex_init(&s->thread_data[i].lock, NULL);
- pthread_cond_init(&s->thread_data[i].cond, NULL);
-#endif
- }
-
- s->macroblocks = s->macroblocks_base + 1;
-
- return 0;
-}
-
-static int vp7_update_dimensions(VP8Context *s, int width, int height)
-{
- return update_dimensions(s, width, height, IS_VP7);
-}
-
-static int vp8_update_dimensions(VP8Context *s, int width, int height)
-{
- return update_dimensions(s, width, height, IS_VP8);
-}
-
-
-static void parse_segment_info(VP8Context *s)
-{
- VP56RangeCoder *c = &s->c;
- int i;
-
- s->segmentation.update_map = vp8_rac_get(c);
-
- if (vp8_rac_get(c)) { // update segment feature data
- s->segmentation.absolute_vals = vp8_rac_get(c);
-
- for (i = 0; i < 4; i++)
- s->segmentation.base_quant[i] = vp8_rac_get_sint(c, 7);
-
- for (i = 0; i < 4; i++)
- s->segmentation.filter_level[i] = vp8_rac_get_sint(c, 6);
- }
- if (s->segmentation.update_map)
- for (i = 0; i < 3; i++)
- s->prob->segmentid[i] = vp8_rac_get(c) ? vp8_rac_get_uint(c, 8) : 255;
-}
-
-static void update_lf_deltas(VP8Context *s)
-{
- VP56RangeCoder *c = &s->c;
- int i;
-
- for (i = 0; i < 4; i++) {
- if (vp8_rac_get(c)) {
- s->lf_delta.ref[i] = vp8_rac_get_uint(c, 6);
-
- if (vp8_rac_get(c))
- s->lf_delta.ref[i] = -s->lf_delta.ref[i];
- }
- }
-
- for (i = MODE_I4x4; i <= VP8_MVMODE_SPLIT; i++) {
- if (vp8_rac_get(c)) {
- s->lf_delta.mode[i] = vp8_rac_get_uint(c, 6);
-
- if (vp8_rac_get(c))
- s->lf_delta.mode[i] = -s->lf_delta.mode[i];
- }
- }
-}
-
-static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size)
-{
- const uint8_t *sizes = buf;
- int i;
-
- s->num_coeff_partitions = 1 << vp8_rac_get_uint(&s->c, 2);
-
- buf += 3 * (s->num_coeff_partitions - 1);
- buf_size -= 3 * (s->num_coeff_partitions - 1);
- if (buf_size < 0)
- return -1;
-
- for (i = 0; i < s->num_coeff_partitions - 1; i++) {
- int size = AV_RL24(sizes + 3 * i);
- if (buf_size - size < 0)
- return -1;
-
- ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size);
- buf += size;
- buf_size -= size;
- }
- ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size);
-
- return 0;
-}
-
-static void vp7_get_quants(VP8Context *s)
-{
- VP56RangeCoder *c = &s->c;
-
- int yac_qi = vp8_rac_get_uint(c, 7);
- int ydc_qi = vp8_rac_get(c) ? vp8_rac_get_uint(c, 7) : yac_qi;
- int y2dc_qi = vp8_rac_get(c) ? vp8_rac_get_uint(c, 7) : yac_qi;
- int y2ac_qi = vp8_rac_get(c) ? vp8_rac_get_uint(c, 7) : yac_qi;
- int uvdc_qi = vp8_rac_get(c) ? vp8_rac_get_uint(c, 7) : yac_qi;
- int uvac_qi = vp8_rac_get(c) ? vp8_rac_get_uint(c, 7) : yac_qi;
-
- s->qmat[0].luma_qmul[0] = vp7_ydc_qlookup[ydc_qi];
- s->qmat[0].luma_qmul[1] = vp7_yac_qlookup[yac_qi];
- s->qmat[0].luma_dc_qmul[0] = vp7_y2dc_qlookup[y2dc_qi];
- s->qmat[0].luma_dc_qmul[1] = vp7_y2ac_qlookup[y2ac_qi];
- s->qmat[0].chroma_qmul[0] = FFMIN(vp7_ydc_qlookup[uvdc_qi], 132);
- s->qmat[0].chroma_qmul[1] = vp7_yac_qlookup[uvac_qi];
-}
-
-static void vp8_get_quants(VP8Context *s)
-{
- VP56RangeCoder *c = &s->c;
- int i, base_qi;
-
- int yac_qi = vp8_rac_get_uint(c, 7);
- int ydc_delta = vp8_rac_get_sint(c, 4);
- int y2dc_delta = vp8_rac_get_sint(c, 4);
- int y2ac_delta = vp8_rac_get_sint(c, 4);
- int uvdc_delta = vp8_rac_get_sint(c, 4);
- int uvac_delta = vp8_rac_get_sint(c, 4);
-
- for (i = 0; i < 4; i++) {
- if (s->segmentation.enabled) {
- base_qi = s->segmentation.base_quant[i];
- if (!s->segmentation.absolute_vals)
- base_qi += yac_qi;
- } else
- base_qi = yac_qi;
-
- s->qmat[i].luma_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + ydc_delta, 7)];
- s->qmat[i].luma_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi, 7)];
- s->qmat[i].luma_dc_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + y2dc_delta, 7)] * 2;
- /* 101581>>16 is equivalent to 155/100 */
- s->qmat[i].luma_dc_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi + y2ac_delta, 7)] * 101581 >> 16;
- s->qmat[i].chroma_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + uvdc_delta, 7)];
- s->qmat[i].chroma_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi + uvac_delta, 7)];
-
- s->qmat[i].luma_dc_qmul[1] = FFMAX(s->qmat[i].luma_dc_qmul[1], 8);
- s->qmat[i].chroma_qmul[0] = FFMIN(s->qmat[i].chroma_qmul[0], 132);
- }
-}
-
-/**
- * Determine which buffers golden and altref should be updated with after this frame.
- * The spec isn't clear here, so I'm going by my understanding of what libvpx does
- *
- * Intra frames update all 3 references
- * Inter frames update VP56_FRAME_PREVIOUS if the update_last flag is set
- * If the update (golden|altref) flag is set, it's updated with the current frame
- * if update_last is set, and VP56_FRAME_PREVIOUS otherwise.
- * If the flag is not set, the number read means:
- * 0: no update
- * 1: VP56_FRAME_PREVIOUS
- * 2: update golden with altref, or update altref with golden
- */
-static VP56Frame ref_to_update(VP8Context *s, int update, VP56Frame ref)
-{
- VP56RangeCoder *c = &s->c;
-
- if (update)
- return VP56_FRAME_CURRENT;
-
- switch (vp8_rac_get_uint(c, 2)) {
- case 1:
- return VP56_FRAME_PREVIOUS;
- case 2:
- return (ref == VP56_FRAME_GOLDEN) ? VP56_FRAME_GOLDEN2 : VP56_FRAME_GOLDEN;
- }
- return VP56_FRAME_NONE;
-}
-
-static void vp78_reset_probability_tables(VP8Context *s)
-{
- int i, j;
- for (i = 0; i < 4; i++)
- for (j = 0; j < 16; j++)
- memcpy(s->prob->token[i][j], vp8_token_default_probs[i][vp8_coeff_band[j]],
- sizeof(s->prob->token[i][j]));
-}
-
-static void vp78_update_probability_tables(VP8Context *s)
-{
- VP56RangeCoder *c = &s->c;
- int i, j, k, l, m;
-
- for (i = 0; i < 4; i++)
- for (j = 0; j < 8; j++)
- for (k = 0; k < 3; k++)
- for (l = 0; l < NUM_DCT_TOKENS-1; l++)
- if (vp56_rac_get_prob_branchy(c, vp8_token_update_probs[i][j][k][l])) {
- int prob = vp8_rac_get_uint(c, 8);
- for (m = 0; vp8_coeff_band_indexes[j][m] >= 0; m++)
- s->prob->token[i][vp8_coeff_band_indexes[j][m]][k][l] = prob;
- }
-}
-
-#define VP7_MVC_SIZE 17
-#define VP8_MVC_SIZE 19
-
-static void vp78_update_pred16x16_pred8x8_mvc_probabilities(VP8Context *s,
- int mvc_size)
-{
- VP56RangeCoder *c = &s->c;
- int i, j;
-
- if (vp8_rac_get(c))
- for (i = 0; i < 4; i++)
- s->prob->pred16x16[i] = vp8_rac_get_uint(c, 8);
- if (vp8_rac_get(c))
- for (i = 0; i < 3; i++)
- s->prob->pred8x8c[i] = vp8_rac_get_uint(c, 8);
-
- // 17.2 MV probability update
- for (i = 0; i < 2; i++)
- for (j = 0; j < mvc_size; j++)
- if (vp56_rac_get_prob_branchy(c, vp8_mv_update_prob[i][j]))
- s->prob->mvc[i][j] = vp8_rac_get_nn(c);
-}
-
-static void update_refs(VP8Context *s)
-{
- VP56RangeCoder *c = &s->c;
-
- int update_golden = vp8_rac_get(c);
- int update_altref = vp8_rac_get(c);
-
- s->update_golden = ref_to_update(s, update_golden, VP56_FRAME_GOLDEN);
- s->update_altref = ref_to_update(s, update_altref, VP56_FRAME_GOLDEN2);
-}
-
-static void copy_chroma(AVFrame *dst, AVFrame *src, int width, int height)
-{
- int i, j;
-
- for (j = 1; j < 3; j++) {
- for (i = 0; i < height / 2; i++)
- memcpy(dst->data[j] + i * dst->linesize[j],
- src->data[j] + i * src->linesize[j], width / 2);
- }
-}
-
-static void fade(uint8_t *dst, int dst_linesize,
- const uint8_t *src, int src_linesize,
- int width, int height,
- int alpha, int beta)
-{
- int i, j;
- for (j = 0; j < height; j++) {
- for (i = 0; i < width; i++) {
- uint8_t y = src[j * src_linesize + i];
- dst[j * dst_linesize + i] = av_clip_uint8(y + ((y * beta) >> 8) + alpha);
- }
- }
-}
-
-static int vp7_fade_frame(VP8Context *s, VP56RangeCoder *c)
-{
- int alpha = (int8_t) vp8_rac_get_uint(c, 8);
- int beta = (int8_t) vp8_rac_get_uint(c, 8);
- int ret;
-
- if (!s->keyframe && (alpha || beta)) {
- int width = s->mb_width * 16;
- int height = s->mb_height * 16;
- AVFrame *src, *dst;
-
- if (!s->framep[VP56_FRAME_PREVIOUS] ||
- !s->framep[VP56_FRAME_GOLDEN]) {
- av_log(s->avctx, AV_LOG_WARNING, "Discarding interframe without a prior keyframe!\n");
- return AVERROR_INVALIDDATA;
- }
-
- dst =
- src = s->framep[VP56_FRAME_PREVIOUS]->tf.f;
-
- /* preserve the golden frame, write a new previous frame */
- if (s->framep[VP56_FRAME_GOLDEN] == s->framep[VP56_FRAME_PREVIOUS]) {
- s->framep[VP56_FRAME_PREVIOUS] = vp8_find_free_buffer(s);
- if ((ret = vp8_alloc_frame(s, s->framep[VP56_FRAME_PREVIOUS], 1)) < 0)
- return ret;
-
- dst = s->framep[VP56_FRAME_PREVIOUS]->tf.f;
-
- copy_chroma(dst, src, width, height);
- }
-
- fade(dst->data[0], dst->linesize[0],
- src->data[0], src->linesize[0],
- width, height, alpha, beta);
- }
-
- return 0;
-}
-
-static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
-{
- VP56RangeCoder *c = &s->c;
- int part1_size, hscale, vscale, i, j, ret;
- int width = s->avctx->width;
- int height = s->avctx->height;
-
- if (buf_size < 4) {
- return AVERROR_INVALIDDATA;
- }
-
- s->profile = (buf[0] >> 1) & 7;
- if (s->profile > 1) {
- avpriv_request_sample(s->avctx, "Unknown profile %d", s->profile);
- return AVERROR_INVALIDDATA;
- }
-
- s->keyframe = !(buf[0] & 1);
- s->invisible = 0;
- part1_size = AV_RL24(buf) >> 4;
-
- if (buf_size < 4 - s->profile + part1_size) {
- av_log(s->avctx, AV_LOG_ERROR, "Buffer size %d is too small, needed : %d\n", buf_size, 4 - s->profile + part1_size);
- return AVERROR_INVALIDDATA;
- }
-
- buf += 4 - s->profile;
- buf_size -= 4 - s->profile;
-
- memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab, sizeof(s->put_pixels_tab));
-
- ff_vp56_init_range_decoder(c, buf, part1_size);
- buf += part1_size;
- buf_size -= part1_size;
-
- /* A. Dimension information (keyframes only) */
- if (s->keyframe) {
- width = vp8_rac_get_uint(c, 12);
- height = vp8_rac_get_uint(c, 12);
- hscale = vp8_rac_get_uint(c, 2);
- vscale = vp8_rac_get_uint(c, 2);
- if (hscale || vscale)
- avpriv_request_sample(s->avctx, "Upscaling");
-
- s->update_golden = s->update_altref = VP56_FRAME_CURRENT;
- vp78_reset_probability_tables(s);
- memcpy(s->prob->pred16x16, vp8_pred16x16_prob_inter,
- sizeof(s->prob->pred16x16));
- memcpy(s->prob->pred8x8c, vp8_pred8x8c_prob_inter,
- sizeof(s->prob->pred8x8c));
- for (i = 0; i < 2; i++)
- memcpy(s->prob->mvc[i], vp7_mv_default_prob[i],
- sizeof(vp7_mv_default_prob[i]));
- memset(&s->segmentation, 0, sizeof(s->segmentation));
- memset(&s->lf_delta, 0, sizeof(s->lf_delta));
- memcpy(s->prob[0].scan, zigzag_scan, sizeof(s->prob[0].scan));
- }
-
- if (s->keyframe || s->profile > 0)
- memset(s->inter_dc_pred, 0 , sizeof(s->inter_dc_pred));
-
- /* B. Decoding information for all four macroblock-level features */
- for (i = 0; i < 4; i++) {
- s->feature_enabled[i] = vp8_rac_get(c);
- if (s->feature_enabled[i]) {
- s->feature_present_prob[i] = vp8_rac_get_uint(c, 8);
-
- for (j = 0; j < 3; j++)
- s->feature_index_prob[i][j] =
- vp8_rac_get(c) ? vp8_rac_get_uint(c, 8) : 255;
-
- if (vp7_feature_value_size[s->profile][i])
- for (j = 0; j < 4; j++)
- s->feature_value[i][j] =
- vp8_rac_get(c) ? vp8_rac_get_uint(c, vp7_feature_value_size[s->profile][i]) : 0;
- }
- }
-
- s->segmentation.enabled = 0;
- s->segmentation.update_map = 0;
- s->lf_delta.enabled = 0;
-
- s->num_coeff_partitions = 1;
- ff_vp56_init_range_decoder(&s->coeff_partition[0], buf, buf_size);
-
- if (!s->macroblocks_base || /* first frame */
- width != s->avctx->width || height != s->avctx->height ||
- (width + 15) / 16 != s->mb_width || (height + 15) / 16 != s->mb_height) {
- if ((ret = vp7_update_dimensions(s, width, height)) < 0)
- return ret;
- }
-
- /* C. Dequantization indices */
- vp7_get_quants(s);
-
- /* D. Golden frame update flag (a Flag) for interframes only */
- if (!s->keyframe) {
- s->update_golden = vp8_rac_get(c) ? VP56_FRAME_CURRENT : VP56_FRAME_NONE;
- s->sign_bias[VP56_FRAME_GOLDEN] = 0;
- }
-
- s->update_last = 1;
- s->update_probabilities = 1;
- s->fade_present = 1;
-
- if (s->profile > 0) {
- s->update_probabilities = vp8_rac_get(c);
- if (!s->update_probabilities)
- s->prob[1] = s->prob[0];
-
- if (!s->keyframe)
- s->fade_present = vp8_rac_get(c);
- }
-
- /* E. Fading information for previous frame */
- if (s->fade_present && vp8_rac_get(c)) {
- if ((ret = vp7_fade_frame(s ,c)) < 0)
- return ret;
- }
-
- /* F. Loop filter type */
- if (!s->profile)
- s->filter.simple = vp8_rac_get(c);
-
- /* G. DCT coefficient ordering specification */
- if (vp8_rac_get(c))
- for (i = 1; i < 16; i++)
- s->prob[0].scan[i] = zigzag_scan[vp8_rac_get_uint(c, 4)];
-
- /* H. Loop filter levels */
- if (s->profile > 0)
- s->filter.simple = vp8_rac_get(c);
- s->filter.level = vp8_rac_get_uint(c, 6);
- s->filter.sharpness = vp8_rac_get_uint(c, 3);
-
- /* I. DCT coefficient probability update; 13.3 Token Probability Updates */
- vp78_update_probability_tables(s);
-
- s->mbskip_enabled = 0;
-
- /* J. The remaining frame header data occurs ONLY FOR INTERFRAMES */
- if (!s->keyframe) {
- s->prob->intra = vp8_rac_get_uint(c, 8);
- s->prob->last = vp8_rac_get_uint(c, 8);
- vp78_update_pred16x16_pred8x8_mvc_probabilities(s, VP7_MVC_SIZE);
- }
-
- return 0;
-}
-
-static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
-{
- VP56RangeCoder *c = &s->c;
- int header_size, hscale, vscale, ret;
- int width = s->avctx->width;
- int height = s->avctx->height;
-
- if (buf_size < 3) {
- av_log(s->avctx, AV_LOG_ERROR, "Insufficent data (%d) for header\n", buf_size);
- return AVERROR_INVALIDDATA;
- }
-
- s->keyframe = !(buf[0] & 1);
- s->profile = (buf[0]>>1) & 7;
- s->invisible = !(buf[0] & 0x10);
- header_size = AV_RL24(buf) >> 5;
- buf += 3;
- buf_size -= 3;
-
- if (s->profile > 3)
- av_log(s->avctx, AV_LOG_WARNING, "Unknown profile %d\n", s->profile);
-
- if (!s->profile)
- memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab,
- sizeof(s->put_pixels_tab));
- else // profile 1-3 use bilinear, 4+ aren't defined so whatever
- memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_bilinear_pixels_tab,
- sizeof(s->put_pixels_tab));
-
- if (header_size > buf_size - 7 * s->keyframe) {
- av_log(s->avctx, AV_LOG_ERROR, "Header size larger than data provided\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (s->keyframe) {
- if (AV_RL24(buf) != 0x2a019d) {
- av_log(s->avctx, AV_LOG_ERROR,
- "Invalid start code 0x%x\n", AV_RL24(buf));
- return AVERROR_INVALIDDATA;
- }
- width = AV_RL16(buf + 3) & 0x3fff;
- height = AV_RL16(buf + 5) & 0x3fff;
- hscale = buf[4] >> 6;
- vscale = buf[6] >> 6;
- buf += 7;
- buf_size -= 7;
-
- if (hscale || vscale)
- avpriv_request_sample(s->avctx, "Upscaling");
-
- s->update_golden = s->update_altref = VP56_FRAME_CURRENT;
- vp78_reset_probability_tables(s);
- memcpy(s->prob->pred16x16, vp8_pred16x16_prob_inter,
- sizeof(s->prob->pred16x16));
- memcpy(s->prob->pred8x8c, vp8_pred8x8c_prob_inter,
- sizeof(s->prob->pred8x8c));
- memcpy(s->prob->mvc, vp8_mv_default_prob,
- sizeof(s->prob->mvc));
- memset(&s->segmentation, 0, sizeof(s->segmentation));
- memset(&s->lf_delta, 0, sizeof(s->lf_delta));
- }
-
- ff_vp56_init_range_decoder(c, buf, header_size);
- buf += header_size;
- buf_size -= header_size;
-
- if (s->keyframe) {
- s->colorspace = vp8_rac_get(c);
- if (s->colorspace)
- av_log(s->avctx, AV_LOG_WARNING, "Unspecified colorspace\n");
- s->fullrange = vp8_rac_get(c);
- }
-
- if ((s->segmentation.enabled = vp8_rac_get(c)))
- parse_segment_info(s);
- else
- s->segmentation.update_map = 0; // FIXME: move this to some init function?
-
- s->filter.simple = vp8_rac_get(c);
- s->filter.level = vp8_rac_get_uint(c, 6);
- s->filter.sharpness = vp8_rac_get_uint(c, 3);
-
- if ((s->lf_delta.enabled = vp8_rac_get(c)))
- if (vp8_rac_get(c))
- update_lf_deltas(s);
-
- if (setup_partitions(s, buf, buf_size)) {
- av_log(s->avctx, AV_LOG_ERROR, "Invalid partitions\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (!s->macroblocks_base || /* first frame */
- width != s->avctx->width || height != s->avctx->height ||
- (width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height)
- if ((ret = vp8_update_dimensions(s, width, height)) < 0)
- return ret;
-
- vp8_get_quants(s);
-
- if (!s->keyframe) {
- update_refs(s);
- s->sign_bias[VP56_FRAME_GOLDEN] = vp8_rac_get(c);
- s->sign_bias[VP56_FRAME_GOLDEN2 /* altref */] = vp8_rac_get(c);
- }
-
- // if we aren't saving this frame's probabilities for future frames,
- // make a copy of the current probabilities
- if (!(s->update_probabilities = vp8_rac_get(c)))
- s->prob[1] = s->prob[0];
-
- s->update_last = s->keyframe || vp8_rac_get(c);
-
- vp78_update_probability_tables(s);
-
- if ((s->mbskip_enabled = vp8_rac_get(c)))
- s->prob->mbskip = vp8_rac_get_uint(c, 8);
-
- if (!s->keyframe) {
- s->prob->intra = vp8_rac_get_uint(c, 8);
- s->prob->last = vp8_rac_get_uint(c, 8);
- s->prob->golden = vp8_rac_get_uint(c, 8);
- vp78_update_pred16x16_pred8x8_mvc_probabilities(s, VP8_MVC_SIZE);
- }
-
- return 0;
-}
-
-static av_always_inline
-void clamp_mv(VP8Context *s, VP56mv *dst, const VP56mv *src)
-{
- dst->x = av_clip(src->x, av_clip(s->mv_min.x, INT16_MIN, INT16_MAX),
- av_clip(s->mv_max.x, INT16_MIN, INT16_MAX));
- dst->y = av_clip(src->y, av_clip(s->mv_min.y, INT16_MIN, INT16_MAX),
- av_clip(s->mv_max.y, INT16_MIN, INT16_MAX));
-}
-
-/**
- * Motion vector coding, 17.1.
- */
-static av_always_inline int read_mv_component(VP56RangeCoder *c, const uint8_t *p, int vp7)
-{
- int bit, x = 0;
-
- if (vp56_rac_get_prob_branchy(c, p[0])) {
- int i;
-
- for (i = 0; i < 3; i++)
- x += vp56_rac_get_prob(c, p[9 + i]) << i;
- for (i = (vp7 ? 7 : 9); i > 3; i--)
- x += vp56_rac_get_prob(c, p[9 + i]) << i;
- if (!(x & (vp7 ? 0xF0 : 0xFFF0)) || vp56_rac_get_prob(c, p[12]))
- x += 8;
- } else {
- // small_mvtree
- const uint8_t *ps = p + 2;
- bit = vp56_rac_get_prob(c, *ps);
- ps += 1 + 3 * bit;
- x += 4 * bit;
- bit = vp56_rac_get_prob(c, *ps);
- ps += 1 + bit;
- x += 2 * bit;
- x += vp56_rac_get_prob(c, *ps);
- }
-
- return (x && vp56_rac_get_prob(c, p[1])) ? -x : x;
-}
-
-static int vp7_read_mv_component(VP56RangeCoder *c, const uint8_t *p)
-{
- return read_mv_component(c, p, 1);
-}
-
-static int vp8_read_mv_component(VP56RangeCoder *c, const uint8_t *p)
-{
- return read_mv_component(c, p, 0);
-}
-
-static av_always_inline
-const uint8_t *get_submv_prob(uint32_t left, uint32_t top, int is_vp7)
-{
- if (is_vp7)
- return vp7_submv_prob;
-
- if (left == top)
- return vp8_submv_prob[4 - !!left];
- if (!top)
- return vp8_submv_prob[2];
- return vp8_submv_prob[1 - !!left];
-}
-
-/**
- * Split motion vector prediction, 16.4.
- * @returns the number of motion vectors parsed (2, 4 or 16)
- */
-static av_always_inline
-int decode_splitmvs(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb,
- int layout, int is_vp7)
-{
- int part_idx;
- int n, num;
- VP8Macroblock *top_mb;
- VP8Macroblock *left_mb = &mb[-1];
- const uint8_t *mbsplits_left = vp8_mbsplits[left_mb->partitioning];
- const uint8_t *mbsplits_top, *mbsplits_cur, *firstidx;
- VP56mv *top_mv;
- VP56mv *left_mv = left_mb->bmv;
- VP56mv *cur_mv = mb->bmv;
-
- if (!layout) // layout is inlined, s->mb_layout is not
- top_mb = &mb[2];
- else
- top_mb = &mb[-s->mb_width - 1];
- mbsplits_top = vp8_mbsplits[top_mb->partitioning];
- top_mv = top_mb->bmv;
-
- if (vp56_rac_get_prob_branchy(c, vp8_mbsplit_prob[0])) {
- if (vp56_rac_get_prob_branchy(c, vp8_mbsplit_prob[1]))
- part_idx = VP8_SPLITMVMODE_16x8 + vp56_rac_get_prob(c, vp8_mbsplit_prob[2]);
- else
- part_idx = VP8_SPLITMVMODE_8x8;
- } else {
- part_idx = VP8_SPLITMVMODE_4x4;
- }
-
- num = vp8_mbsplit_count[part_idx];
- mbsplits_cur = vp8_mbsplits[part_idx],
- firstidx = vp8_mbfirstidx[part_idx];
- mb->partitioning = part_idx;
-
- for (n = 0; n < num; n++) {
- int k = firstidx[n];
- uint32_t left, above;
- const uint8_t *submv_prob;
-
- if (!(k & 3))
- left = AV_RN32A(&left_mv[mbsplits_left[k + 3]]);
- else
- left = AV_RN32A(&cur_mv[mbsplits_cur[k - 1]]);
- if (k <= 3)
- above = AV_RN32A(&top_mv[mbsplits_top[k + 12]]);
- else
- above = AV_RN32A(&cur_mv[mbsplits_cur[k - 4]]);
-
- submv_prob = get_submv_prob(left, above, is_vp7);
-
- if (vp56_rac_get_prob_branchy(c, submv_prob[0])) {
- if (vp56_rac_get_prob_branchy(c, submv_prob[1])) {
- if (vp56_rac_get_prob_branchy(c, submv_prob[2])) {
- mb->bmv[n].y = mb->mv.y +
- read_mv_component(c, s->prob->mvc[0], is_vp7);
- mb->bmv[n].x = mb->mv.x +
- read_mv_component(c, s->prob->mvc[1], is_vp7);
- } else {
- AV_ZERO32(&mb->bmv[n]);
- }
- } else {
- AV_WN32A(&mb->bmv[n], above);
- }
- } else {
- AV_WN32A(&mb->bmv[n], left);
- }
- }
-
- return num;
-}
-
-/**
- * The vp7 reference decoder uses a padding macroblock column (added to right
- * edge of the frame) to guard against illegal macroblock offsets. The
- * algorithm has bugs that permit offsets to straddle the padding column.
- * This function replicates those bugs.
- *
- * @param[out] edge_x macroblock x address
- * @param[out] edge_y macroblock y address
- *
- * @return macroblock offset legal (boolean)
- */
-static int vp7_calculate_mb_offset(int mb_x, int mb_y, int mb_width,
- int xoffset, int yoffset, int boundary,
- int *edge_x, int *edge_y)
-{
- int vwidth = mb_width + 1;
- int new = (mb_y + yoffset) * vwidth + mb_x + xoffset;
- if (new < boundary || new % vwidth == vwidth - 1)
- return 0;
- *edge_y = new / vwidth;
- *edge_x = new % vwidth;
- return 1;
-}
-
-static const VP56mv *get_bmv_ptr(const VP8Macroblock *mb, int subblock)
-{
- return &mb->bmv[mb->mode == VP8_MVMODE_SPLIT ? vp8_mbsplits[mb->partitioning][subblock] : 0];
-}
-
-static av_always_inline
-void vp7_decode_mvs(VP8Context *s, VP8Macroblock *mb,
- int mb_x, int mb_y, int layout)
-{
- VP8Macroblock *mb_edge[12];
- enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR };
- enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
- int idx = CNT_ZERO;
- VP56mv near_mv[3];
- uint8_t cnt[3] = { 0 };
- VP56RangeCoder *c = &s->c;
- int i;
-
- AV_ZERO32(&near_mv[0]);
- AV_ZERO32(&near_mv[1]);
- AV_ZERO32(&near_mv[2]);
-
- for (i = 0; i < VP7_MV_PRED_COUNT; i++) {
- const VP7MVPred * pred = &vp7_mv_pred[i];
- int edge_x, edge_y;
-
- if (vp7_calculate_mb_offset(mb_x, mb_y, s->mb_width, pred->xoffset,
- pred->yoffset, !s->profile, &edge_x, &edge_y)) {
- VP8Macroblock *edge = mb_edge[i] = (s->mb_layout == 1)
- ? s->macroblocks_base + 1 + edge_x +
- (s->mb_width + 1) * (edge_y + 1)
- : s->macroblocks + edge_x +
- (s->mb_height - edge_y - 1) * 2;
- uint32_t mv = AV_RN32A(get_bmv_ptr(edge, vp7_mv_pred[i].subblock));
- if (mv) {
- if (AV_RN32A(&near_mv[CNT_NEAREST])) {
- if (mv == AV_RN32A(&near_mv[CNT_NEAREST])) {
- idx = CNT_NEAREST;
- } else if (AV_RN32A(&near_mv[CNT_NEAR])) {
- if (mv != AV_RN32A(&near_mv[CNT_NEAR]))
- continue;
- idx = CNT_NEAR;
- } else {
- AV_WN32A(&near_mv[CNT_NEAR], mv);
- idx = CNT_NEAR;
- }
- } else {
- AV_WN32A(&near_mv[CNT_NEAREST], mv);
- idx = CNT_NEAREST;
- }
- } else {
- idx = CNT_ZERO;
- }
- } else {
- idx = CNT_ZERO;
- }
- cnt[idx] += vp7_mv_pred[i].score;
- }
-
- mb->partitioning = VP8_SPLITMVMODE_NONE;
-
- if (vp56_rac_get_prob_branchy(c, vp7_mode_contexts[cnt[CNT_ZERO]][0])) {
- mb->mode = VP8_MVMODE_MV;
-
- if (vp56_rac_get_prob_branchy(c, vp7_mode_contexts[cnt[CNT_NEAREST]][1])) {
-
- if (vp56_rac_get_prob_branchy(c, vp7_mode_contexts[cnt[CNT_NEAR]][2])) {
-
- if (cnt[CNT_NEAREST] > cnt[CNT_NEAR])
- AV_WN32A(&mb->mv, cnt[CNT_ZERO] > cnt[CNT_NEAREST] ? 0 : AV_RN32A(&near_mv[CNT_NEAREST]));
- else
- AV_WN32A(&mb->mv, cnt[CNT_ZERO] > cnt[CNT_NEAR] ? 0 : AV_RN32A(&near_mv[CNT_NEAR]));
-
- if (vp56_rac_get_prob_branchy(c, vp7_mode_contexts[cnt[CNT_NEAR]][3])) {
- mb->mode = VP8_MVMODE_SPLIT;
- mb->mv = mb->bmv[decode_splitmvs(s, c, mb, layout, IS_VP7) - 1];
- } else {
- mb->mv.y += vp7_read_mv_component(c, s->prob->mvc[0]);
- mb->mv.x += vp7_read_mv_component(c, s->prob->mvc[1]);
- mb->bmv[0] = mb->mv;
- }
- } else {
- mb->mv = near_mv[CNT_NEAR];
- mb->bmv[0] = mb->mv;
- }
- } else {
- mb->mv = near_mv[CNT_NEAREST];
- mb->bmv[0] = mb->mv;
- }
- } else {
- mb->mode = VP8_MVMODE_ZERO;
- AV_ZERO32(&mb->mv);
- mb->bmv[0] = mb->mv;
- }
-}
-
-static av_always_inline
-void vp8_decode_mvs(VP8Context *s, VP8Macroblock *mb,
- int mb_x, int mb_y, int layout)
-{
- VP8Macroblock *mb_edge[3] = { 0 /* top */,
- mb - 1 /* left */,
- 0 /* top-left */ };
- enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV };
- enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
- int idx = CNT_ZERO;
- int cur_sign_bias = s->sign_bias[mb->ref_frame];
- int8_t *sign_bias = s->sign_bias;
- VP56mv near_mv[4];
- uint8_t cnt[4] = { 0 };
- VP56RangeCoder *c = &s->c;
-
- if (!layout) { // layout is inlined (s->mb_layout is not)
- mb_edge[0] = mb + 2;
- mb_edge[2] = mb + 1;
- } else {
- mb_edge[0] = mb - s->mb_width - 1;
- mb_edge[2] = mb - s->mb_width - 2;
- }
-
- AV_ZERO32(&near_mv[0]);
- AV_ZERO32(&near_mv[1]);
- AV_ZERO32(&near_mv[2]);
-
- /* Process MB on top, left and top-left */
-#define MV_EDGE_CHECK(n) \
- { \
- VP8Macroblock *edge = mb_edge[n]; \
- int edge_ref = edge->ref_frame; \
- if (edge_ref != VP56_FRAME_CURRENT) { \
- uint32_t mv = AV_RN32A(&edge->mv); \
- if (mv) { \
- if (cur_sign_bias != sign_bias[edge_ref]) { \
- /* SWAR negate of the values in mv. */ \
- mv = ~mv; \
- mv = ((mv & 0x7fff7fff) + \
- 0x00010001) ^ (mv & 0x80008000); \
- } \
- if (!n || mv != AV_RN32A(&near_mv[idx])) \
- AV_WN32A(&near_mv[++idx], mv); \
- cnt[idx] += 1 + (n != 2); \
- } else \
- cnt[CNT_ZERO] += 1 + (n != 2); \
- } \
- }
-
- MV_EDGE_CHECK(0)
- MV_EDGE_CHECK(1)
- MV_EDGE_CHECK(2)
-
- mb->partitioning = VP8_SPLITMVMODE_NONE;
- if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_ZERO]][0])) {
- mb->mode = VP8_MVMODE_MV;
-
- /* If we have three distinct MVs, merge first and last if they're the same */
- if (cnt[CNT_SPLITMV] &&
- AV_RN32A(&near_mv[1 + VP8_EDGE_TOP]) == AV_RN32A(&near_mv[1 + VP8_EDGE_TOPLEFT]))
- cnt[CNT_NEAREST] += 1;
-
- /* Swap near and nearest if necessary */
- if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) {
- FFSWAP(uint8_t, cnt[CNT_NEAREST], cnt[CNT_NEAR]);
- FFSWAP( VP56mv, near_mv[CNT_NEAREST], near_mv[CNT_NEAR]);
- }
-
- if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAREST]][1])) {
- if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAR]][2])) {
- /* Choose the best mv out of 0,0 and the nearest mv */
- clamp_mv(s, &mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]);
- cnt[CNT_SPLITMV] = ((mb_edge[VP8_EDGE_LEFT]->mode == VP8_MVMODE_SPLIT) +
- (mb_edge[VP8_EDGE_TOP]->mode == VP8_MVMODE_SPLIT)) * 2 +
- (mb_edge[VP8_EDGE_TOPLEFT]->mode == VP8_MVMODE_SPLIT);
-
- if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_SPLITMV]][3])) {
- mb->mode = VP8_MVMODE_SPLIT;
- mb->mv = mb->bmv[decode_splitmvs(s, c, mb, layout, IS_VP8) - 1];
- } else {
- mb->mv.y += vp8_read_mv_component(c, s->prob->mvc[0]);
- mb->mv.x += vp8_read_mv_component(c, s->prob->mvc[1]);
- mb->bmv[0] = mb->mv;
- }
- } else {
- clamp_mv(s, &mb->mv, &near_mv[CNT_NEAR]);
- mb->bmv[0] = mb->mv;
- }
- } else {
- clamp_mv(s, &mb->mv, &near_mv[CNT_NEAREST]);
- mb->bmv[0] = mb->mv;
- }
- } else {
- mb->mode = VP8_MVMODE_ZERO;
- AV_ZERO32(&mb->mv);
- mb->bmv[0] = mb->mv;
- }
-}
-
-static av_always_inline
-void decode_intra4x4_modes(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb,
- int mb_x, int keyframe, int layout)
-{
- uint8_t *intra4x4 = mb->intra4x4_pred_mode_mb;
-
- if (layout) {
- VP8Macroblock *mb_top = mb - s->mb_width - 1;
- memcpy(mb->intra4x4_pred_mode_top, mb_top->intra4x4_pred_mode_top, 4);
- }
- if (keyframe) {
- int x, y;
- uint8_t *top;
- uint8_t *const left = s->intra4x4_pred_mode_left;
- if (layout)
- top = mb->intra4x4_pred_mode_top;
- else
- top = s->intra4x4_pred_mode_top + 4 * mb_x;
- for (y = 0; y < 4; y++) {
- for (x = 0; x < 4; x++) {
- const uint8_t *ctx;
- ctx = vp8_pred4x4_prob_intra[top[x]][left[y]];
- *intra4x4 = vp8_rac_get_tree(c, vp8_pred4x4_tree, ctx);
- left[y] = top[x] = *intra4x4;
- intra4x4++;
- }
- }
- } else {
- int i;
- for (i = 0; i < 16; i++)
- intra4x4[i] = vp8_rac_get_tree(c, vp8_pred4x4_tree,
- vp8_pred4x4_prob_inter);
- }
-}
-
-static av_always_inline
-void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,
- uint8_t *segment, uint8_t *ref, int layout, int is_vp7)
-{
- VP56RangeCoder *c = &s->c;
- const char *vp7_feature_name[] = { "q-index",
- "lf-delta",
- "partial-golden-update",
- "blit-pitch" };
- if (is_vp7) {
- int i;
- *segment = 0;
- for (i = 0; i < 4; i++) {
- if (s->feature_enabled[i]) {
- if (vp56_rac_get_prob_branchy(c, s->feature_present_prob[i])) {
- int index = vp8_rac_get_tree(c, vp7_feature_index_tree,
- s->feature_index_prob[i]);
- av_log(s->avctx, AV_LOG_WARNING,
- "Feature %s present in macroblock (value 0x%x)\n",
- vp7_feature_name[i], s->feature_value[i][index]);
- }
- }
- }
- } else if (s->segmentation.update_map) {
- int bit = vp56_rac_get_prob(c, s->prob->segmentid[0]);
- *segment = vp56_rac_get_prob(c, s->prob->segmentid[1+bit]) + 2*bit;
- } else if (s->segmentation.enabled)
- *segment = ref ? *ref : *segment;
- mb->segment = *segment;
-
- mb->skip = s->mbskip_enabled ? vp56_rac_get_prob(c, s->prob->mbskip) : 0;
-
- if (s->keyframe) {
- mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_intra,
- vp8_pred16x16_prob_intra);
-
- if (mb->mode == MODE_I4x4) {
- decode_intra4x4_modes(s, c, mb, mb_x, 1, layout);
- } else {
- const uint32_t modes = (is_vp7 ? vp7_pred4x4_mode
- : vp8_pred4x4_mode)[mb->mode] * 0x01010101u;
- if (s->mb_layout)
- AV_WN32A(mb->intra4x4_pred_mode_top, modes);
- else
- AV_WN32A(s->intra4x4_pred_mode_top + 4 * mb_x, modes);
- AV_WN32A(s->intra4x4_pred_mode_left, modes);
- }
-
- mb->chroma_pred_mode = vp8_rac_get_tree(c, vp8_pred8x8c_tree,
- vp8_pred8x8c_prob_intra);
- mb->ref_frame = VP56_FRAME_CURRENT;
- } else if (vp56_rac_get_prob_branchy(c, s->prob->intra)) {
- // inter MB, 16.2
- if (vp56_rac_get_prob_branchy(c, s->prob->last))
- mb->ref_frame =
- (!is_vp7 && vp56_rac_get_prob(c, s->prob->golden)) ? VP56_FRAME_GOLDEN2 /* altref */
- : VP56_FRAME_GOLDEN;
- else
- mb->ref_frame = VP56_FRAME_PREVIOUS;
- s->ref_count[mb->ref_frame - 1]++;
-
- // motion vectors, 16.3
- if (is_vp7)
- vp7_decode_mvs(s, mb, mb_x, mb_y, layout);
- else
- vp8_decode_mvs(s, mb, mb_x, mb_y, layout);
- } else {
- // intra MB, 16.1
- mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_inter, s->prob->pred16x16);
-
- if (mb->mode == MODE_I4x4)
- decode_intra4x4_modes(s, c, mb, mb_x, 0, layout);
-
- mb->chroma_pred_mode = vp8_rac_get_tree(c, vp8_pred8x8c_tree,
- s->prob->pred8x8c);
- mb->ref_frame = VP56_FRAME_CURRENT;
- mb->partitioning = VP8_SPLITMVMODE_NONE;
- AV_ZERO32(&mb->bmv[0]);
- }
-}
-
-/**
- * @param r arithmetic bitstream reader context
- * @param block destination for block coefficients
- * @param probs probabilities to use when reading trees from the bitstream
- * @param i initial coeff index, 0 unless a separate DC block is coded
- * @param qmul array holding the dc/ac dequant factor at position 0/1
- *
- * @return 0 if no coeffs were decoded
- * otherwise, the index of the last coeff decoded plus one
- */
-static av_always_inline
-int decode_block_coeffs_internal(VP56RangeCoder *r, int16_t block[16],
- uint8_t probs[16][3][NUM_DCT_TOKENS - 1],
- int i, uint8_t *token_prob, int16_t qmul[2],
- const uint8_t scan[16], int vp7)
-{
- VP56RangeCoder c = *r;
- goto skip_eob;
- do {
- int coeff;
-restart:
- if (!vp56_rac_get_prob_branchy(&c, token_prob[0])) // DCT_EOB
- break;
-
-skip_eob:
- if (!vp56_rac_get_prob_branchy(&c, token_prob[1])) { // DCT_0
- if (++i == 16)
- break; // invalid input; blocks should end with EOB
- token_prob = probs[i][0];
- if (vp7)
- goto restart;
- goto skip_eob;
- }
-
- if (!vp56_rac_get_prob_branchy(&c, token_prob[2])) { // DCT_1
- coeff = 1;
- token_prob = probs[i + 1][1];
- } else {
- if (!vp56_rac_get_prob_branchy(&c, token_prob[3])) { // DCT 2,3,4
- coeff = vp56_rac_get_prob_branchy(&c, token_prob[4]);
- if (coeff)
- coeff += vp56_rac_get_prob(&c, token_prob[5]);
- coeff += 2;
- } else {
- // DCT_CAT*
- if (!vp56_rac_get_prob_branchy(&c, token_prob[6])) {
- if (!vp56_rac_get_prob_branchy(&c, token_prob[7])) { // DCT_CAT1
- coeff = 5 + vp56_rac_get_prob(&c, vp8_dct_cat1_prob[0]);
- } else { // DCT_CAT2
- coeff = 7;
- coeff += vp56_rac_get_prob(&c, vp8_dct_cat2_prob[0]) << 1;
- coeff += vp56_rac_get_prob(&c, vp8_dct_cat2_prob[1]);
- }
- } else { // DCT_CAT3 and up
- int a = vp56_rac_get_prob(&c, token_prob[8]);
- int b = vp56_rac_get_prob(&c, token_prob[9 + a]);
- int cat = (a << 1) + b;
- coeff = 3 + (8 << cat);
- coeff += vp8_rac_get_coeff(&c, ff_vp8_dct_cat_prob[cat]);
- }
- }
- token_prob = probs[i + 1][2];
- }
- block[scan[i]] = (vp8_rac_get(&c) ? -coeff : coeff) * qmul[!!i];
- } while (++i < 16);
-
- *r = c;
- return i;
-}
-
-static av_always_inline
-int inter_predict_dc(int16_t block[16], int16_t pred[2])
-{
- int16_t dc = block[0];
- int ret = 0;
-
- if (pred[1] > 3) {
- dc += pred[0];
- ret = 1;
- }
-
- if (!pred[0] | !dc | ((int32_t)pred[0] ^ (int32_t)dc) >> 31) {
- block[0] = pred[0] = dc;
- pred[1] = 0;
- } else {
- if (pred[0] == dc)
- pred[1]++;
- block[0] = pred[0] = dc;
- }
-
- return ret;
-}
-
-static int vp7_decode_block_coeffs_internal(VP56RangeCoder *r,
- int16_t block[16],
- uint8_t probs[16][3][NUM_DCT_TOKENS - 1],
- int i, uint8_t *token_prob,
- int16_t qmul[2],
- const uint8_t scan[16])
-{
- return decode_block_coeffs_internal(r, block, probs, i,
- token_prob, qmul, scan, IS_VP7);
-}
-
-#ifndef vp8_decode_block_coeffs_internal
-static int vp8_decode_block_coeffs_internal(VP56RangeCoder *r,
- int16_t block[16],
- uint8_t probs[16][3][NUM_DCT_TOKENS - 1],
- int i, uint8_t *token_prob,
- int16_t qmul[2])
-{
- return decode_block_coeffs_internal(r, block, probs, i,
- token_prob, qmul, zigzag_scan, IS_VP8);
-}
-#endif
-
-/**
- * @param c arithmetic bitstream reader context
- * @param block destination for block coefficients
- * @param probs probabilities to use when reading trees from the bitstream
- * @param i initial coeff index, 0 unless a separate DC block is coded
- * @param zero_nhood the initial prediction context for number of surrounding
- * all-zero blocks (only left/top, so 0-2)
- * @param qmul array holding the dc/ac dequant factor at position 0/1
- * @param scan scan pattern (VP7 only)
- *
- * @return 0 if no coeffs were decoded
- * otherwise, the index of the last coeff decoded plus one
- */
-static av_always_inline
-int decode_block_coeffs(VP56RangeCoder *c, int16_t block[16],
- uint8_t probs[16][3][NUM_DCT_TOKENS - 1],
- int i, int zero_nhood, int16_t qmul[2],
- const uint8_t scan[16], int vp7)
-{
- uint8_t *token_prob = probs[i][zero_nhood];
- if (!vp56_rac_get_prob_branchy(c, token_prob[0])) // DCT_EOB
- return 0;
- return vp7 ? vp7_decode_block_coeffs_internal(c, block, probs, i,
- token_prob, qmul, scan)
- : vp8_decode_block_coeffs_internal(c, block, probs, i,
- token_prob, qmul);
-}
-
-static av_always_inline
-void decode_mb_coeffs(VP8Context *s, VP8ThreadData *td, VP56RangeCoder *c,
- VP8Macroblock *mb, uint8_t t_nnz[9], uint8_t l_nnz[9],
- int is_vp7)
-{
- int i, x, y, luma_start = 0, luma_ctx = 3;
- int nnz_pred, nnz, nnz_total = 0;
- int segment = mb->segment;
- int block_dc = 0;
-
- if (mb->mode != MODE_I4x4 && (is_vp7 || mb->mode != VP8_MVMODE_SPLIT)) {
- nnz_pred = t_nnz[8] + l_nnz[8];
-
- // decode DC values and do hadamard
- nnz = decode_block_coeffs(c, td->block_dc, s->prob->token[1], 0,
- nnz_pred, s->qmat[segment].luma_dc_qmul,
- zigzag_scan, is_vp7);
- l_nnz[8] = t_nnz[8] = !!nnz;
-
- if (is_vp7 && mb->mode > MODE_I4x4) {
- nnz |= inter_predict_dc(td->block_dc,
- s->inter_dc_pred[mb->ref_frame - 1]);
- }
-
- if (nnz) {
- nnz_total += nnz;
- block_dc = 1;
- if (nnz == 1)
- s->vp8dsp.vp8_luma_dc_wht_dc(td->block, td->block_dc);
- else
- s->vp8dsp.vp8_luma_dc_wht(td->block, td->block_dc);
- }
- luma_start = 1;
- luma_ctx = 0;
- }
-
- // luma blocks
- for (y = 0; y < 4; y++)
- for (x = 0; x < 4; x++) {
- nnz_pred = l_nnz[y] + t_nnz[x];
- nnz = decode_block_coeffs(c, td->block[y][x],
- s->prob->token[luma_ctx],
- luma_start, nnz_pred,
- s->qmat[segment].luma_qmul,
- s->prob[0].scan, is_vp7);
- /* nnz+block_dc may be one more than the actual last index,
- * but we don't care */
- td->non_zero_count_cache[y][x] = nnz + block_dc;
- t_nnz[x] = l_nnz[y] = !!nnz;
- nnz_total += nnz;
- }
-
- // chroma blocks
- // TODO: what to do about dimensions? 2nd dim for luma is x,
- // but for chroma it's (y<<1)|x
- for (i = 4; i < 6; i++)
- for (y = 0; y < 2; y++)
- for (x = 0; x < 2; x++) {
- nnz_pred = l_nnz[i + 2 * y] + t_nnz[i + 2 * x];
- nnz = decode_block_coeffs(c, td->block[i][(y << 1) + x],
- s->prob->token[2], 0, nnz_pred,
- s->qmat[segment].chroma_qmul,
- s->prob[0].scan, is_vp7);
- td->non_zero_count_cache[i][(y << 1) + x] = nnz;
- t_nnz[i + 2 * x] = l_nnz[i + 2 * y] = !!nnz;
- nnz_total += nnz;
- }
-
- // if there were no coded coeffs despite the macroblock not being marked skip,
- // we MUST not do the inner loop filter and should not do IDCT
- // Since skip isn't used for bitstream prediction, just manually set it.
- if (!nnz_total)
- mb->skip = 1;
-}
-
-static av_always_inline
-void backup_mb_border(uint8_t *top_border, uint8_t *src_y,
- uint8_t *src_cb, uint8_t *src_cr,
- int linesize, int uvlinesize, int simple)
-{
- AV_COPY128(top_border, src_y + 15 * linesize);
- if (!simple) {
- AV_COPY64(top_border + 16, src_cb + 7 * uvlinesize);
- AV_COPY64(top_border + 24, src_cr + 7 * uvlinesize);
- }
-}
-
-static av_always_inline
-void xchg_mb_border(uint8_t *top_border, uint8_t *src_y, uint8_t *src_cb,
- uint8_t *src_cr, int linesize, int uvlinesize, int mb_x,
- int mb_y, int mb_width, int simple, int xchg)
-{
- uint8_t *top_border_m1 = top_border - 32; // for TL prediction
- src_y -= linesize;
- src_cb -= uvlinesize;
- src_cr -= uvlinesize;
-
-#define XCHG(a, b, xchg) \
- do { \
- if (xchg) \
- AV_SWAP64(b, a); \
- else \
- AV_COPY64(b, a); \
- } while (0)
-
- XCHG(top_border_m1 + 8, src_y - 8, xchg);
- XCHG(top_border, src_y, xchg);
- XCHG(top_border + 8, src_y + 8, 1);
- if (mb_x < mb_width - 1)
- XCHG(top_border + 32, src_y + 16, 1);
-
- // only copy chroma for normal loop filter
- // or to initialize the top row to 127
- if (!simple || !mb_y) {
- XCHG(top_border_m1 + 16, src_cb - 8, xchg);
- XCHG(top_border_m1 + 24, src_cr - 8, xchg);
- XCHG(top_border + 16, src_cb, 1);
- XCHG(top_border + 24, src_cr, 1);
- }
-}
-
-static av_always_inline
-int check_dc_pred8x8_mode(int mode, int mb_x, int mb_y)
-{
- if (!mb_x)
- return mb_y ? TOP_DC_PRED8x8 : DC_128_PRED8x8;
- else
- return mb_y ? mode : LEFT_DC_PRED8x8;
-}
-
-static av_always_inline
-int check_tm_pred8x8_mode(int mode, int mb_x, int mb_y, int vp7)
-{
- if (!mb_x)
- return mb_y ? VERT_PRED8x8 : (vp7 ? DC_128_PRED8x8 : DC_129_PRED8x8);
- else
- return mb_y ? mode : HOR_PRED8x8;
-}
-
-static av_always_inline
-int check_intra_pred8x8_mode_emuedge(int mode, int mb_x, int mb_y, int vp7)
-{
- switch (mode) {
- case DC_PRED8x8:
- return check_dc_pred8x8_mode(mode, mb_x, mb_y);
- case VERT_PRED8x8:
- return !mb_y ? (vp7 ? DC_128_PRED8x8 : DC_127_PRED8x8) : mode;
- case HOR_PRED8x8:
- return !mb_x ? (vp7 ? DC_128_PRED8x8 : DC_129_PRED8x8) : mode;
- case PLANE_PRED8x8: /* TM */
- return check_tm_pred8x8_mode(mode, mb_x, mb_y, vp7);
- }
- return mode;
-}
-
-static av_always_inline
-int check_tm_pred4x4_mode(int mode, int mb_x, int mb_y, int vp7)
-{
- if (!mb_x) {
- return mb_y ? VERT_VP8_PRED : (vp7 ? DC_128_PRED : DC_129_PRED);
- } else {
- return mb_y ? mode : HOR_VP8_PRED;
- }
-}
-
-static av_always_inline
-int check_intra_pred4x4_mode_emuedge(int mode, int mb_x, int mb_y,
- int *copy_buf, int vp7)
-{
- switch (mode) {
- case VERT_PRED:
- if (!mb_x && mb_y) {
- *copy_buf = 1;
- return mode;
- }
- /* fall-through */
- case DIAG_DOWN_LEFT_PRED:
- case VERT_LEFT_PRED:
- return !mb_y ? (vp7 ? DC_128_PRED : DC_127_PRED) : mode;
- case HOR_PRED:
- if (!mb_y) {
- *copy_buf = 1;
- return mode;
- }
- /* fall-through */
- case HOR_UP_PRED:
- return !mb_x ? (vp7 ? DC_128_PRED : DC_129_PRED) : mode;
- case TM_VP8_PRED:
- return check_tm_pred4x4_mode(mode, mb_x, mb_y, vp7);
- case DC_PRED: /* 4x4 DC doesn't use the same "H.264-style" exceptions
- * as 16x16/8x8 DC */
- case DIAG_DOWN_RIGHT_PRED:
- case VERT_RIGHT_PRED:
- case HOR_DOWN_PRED:
- if (!mb_y || !mb_x)
- *copy_buf = 1;
- return mode;
- }
- return mode;
-}
-
-static av_always_inline
-void intra_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3],
- VP8Macroblock *mb, int mb_x, int mb_y, int is_vp7)
-{
- int x, y, mode, nnz;
- uint32_t tr;
-
- /* for the first row, we need to run xchg_mb_border to init the top edge
- * to 127 otherwise, skip it if we aren't going to deblock */
- if (mb_y && (s->deblock_filter || !mb_y) && td->thread_nr == 0)
- xchg_mb_border(s->top_border[mb_x + 1], dst[0], dst[1], dst[2],
- s->linesize, s->uvlinesize, mb_x, mb_y, s->mb_width,
- s->filter.simple, 1);
-
- if (mb->mode < MODE_I4x4) {
- mode = check_intra_pred8x8_mode_emuedge(mb->mode, mb_x, mb_y, is_vp7);
- s->hpc.pred16x16[mode](dst[0], s->linesize);
- } else {
- uint8_t *ptr = dst[0];
- uint8_t *intra4x4 = mb->intra4x4_pred_mode_mb;
- const uint8_t lo = is_vp7 ? 128 : 127;
- const uint8_t hi = is_vp7 ? 128 : 129;
- uint8_t tr_top[4] = { lo, lo, lo, lo };
-
- // all blocks on the right edge of the macroblock use bottom edge
- // the top macroblock for their topright edge
- uint8_t *tr_right = ptr - s->linesize + 16;
-
- // if we're on the right edge of the frame, said edge is extended
- // from the top macroblock
- if (mb_y && mb_x == s->mb_width - 1) {
- tr = tr_right[-1] * 0x01010101u;
- tr_right = (uint8_t *) &tr;
- }
-
- if (mb->skip)
- AV_ZERO128(td->non_zero_count_cache);
-
- for (y = 0; y < 4; y++) {
- uint8_t *topright = ptr + 4 - s->linesize;
- for (x = 0; x < 4; x++) {
- int copy = 0, linesize = s->linesize;
- uint8_t *dst = ptr + 4 * x;
- LOCAL_ALIGNED(4, uint8_t, copy_dst, [5 * 8]);
-
- if ((y == 0 || x == 3) && mb_y == 0) {
- topright = tr_top;
- } else if (x == 3)
- topright = tr_right;
-
- mode = check_intra_pred4x4_mode_emuedge(intra4x4[x], mb_x + x,
- mb_y + y, ©, is_vp7);
- if (copy) {
- dst = copy_dst + 12;
- linesize = 8;
- if (!(mb_y + y)) {
- copy_dst[3] = lo;
- AV_WN32A(copy_dst + 4, lo * 0x01010101U);
- } else {
- AV_COPY32(copy_dst + 4, ptr + 4 * x - s->linesize);
- if (!(mb_x + x)) {
- copy_dst[3] = hi;
- } else {
- copy_dst[3] = ptr[4 * x - s->linesize - 1];
- }
- }
- if (!(mb_x + x)) {
- copy_dst[11] =
- copy_dst[19] =
- copy_dst[27] =
- copy_dst[35] = hi;
- } else {
- copy_dst[11] = ptr[4 * x - 1];
- copy_dst[19] = ptr[4 * x + s->linesize - 1];
- copy_dst[27] = ptr[4 * x + s->linesize * 2 - 1];
- copy_dst[35] = ptr[4 * x + s->linesize * 3 - 1];
- }
- }
- s->hpc.pred4x4[mode](dst, topright, linesize);
- if (copy) {
- AV_COPY32(ptr + 4 * x, copy_dst + 12);
- AV_COPY32(ptr + 4 * x + s->linesize, copy_dst + 20);
- AV_COPY32(ptr + 4 * x + s->linesize * 2, copy_dst + 28);
- AV_COPY32(ptr + 4 * x + s->linesize * 3, copy_dst + 36);
- }
-
- nnz = td->non_zero_count_cache[y][x];
- if (nnz) {
- if (nnz == 1)
- s->vp8dsp.vp8_idct_dc_add(ptr + 4 * x,
- td->block[y][x], s->linesize);
- else
- s->vp8dsp.vp8_idct_add(ptr + 4 * x,
- td->block[y][x], s->linesize);
- }
- topright += 4;
- }
-
- ptr += 4 * s->linesize;
- intra4x4 += 4;
- }
- }
-
- mode = check_intra_pred8x8_mode_emuedge(mb->chroma_pred_mode,
- mb_x, mb_y, is_vp7);
- s->hpc.pred8x8[mode](dst[1], s->uvlinesize);
- s->hpc.pred8x8[mode](dst[2], s->uvlinesize);
-
- if (mb_y && (s->deblock_filter || !mb_y) && td->thread_nr == 0)
- xchg_mb_border(s->top_border[mb_x + 1], dst[0], dst[1], dst[2],
- s->linesize, s->uvlinesize, mb_x, mb_y, s->mb_width,
- s->filter.simple, 0);
-}
-
-static const uint8_t subpel_idx[3][8] = {
- { 0, 1, 2, 1, 2, 1, 2, 1 }, // nr. of left extra pixels,
- // also function pointer index
- { 0, 3, 5, 3, 5, 3, 5, 3 }, // nr. of extra pixels required
- { 0, 2, 3, 2, 3, 2, 3, 2 }, // nr. of right extra pixels
-};
-
-/**
- * luma MC function
- *
- * @param s VP8 decoding context
- * @param dst target buffer for block data at block position
- * @param ref reference picture buffer at origin (0, 0)
- * @param mv motion vector (relative to block position) to get pixel data from
- * @param x_off horizontal position of block from origin (0, 0)
- * @param y_off vertical position of block from origin (0, 0)
- * @param block_w width of block (16, 8 or 4)
- * @param block_h height of block (always same as block_w)
- * @param width width of src/dst plane data
- * @param height height of src/dst plane data
- * @param linesize size of a single line of plane data, including padding
- * @param mc_func motion compensation function pointers (bilinear or sixtap MC)
- */
-static av_always_inline
-void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,
- ThreadFrame *ref, const VP56mv *mv,
- int x_off, int y_off, int block_w, int block_h,
- int width, int height, ptrdiff_t linesize,
- vp8_mc_func mc_func[3][3])
-{
- uint8_t *src = ref->f->data[0];
-
- if (AV_RN32A(mv)) {
- int src_linesize = linesize;
-
- int mx = (mv->x * 2) & 7, mx_idx = subpel_idx[0][mx];
- int my = (mv->y * 2) & 7, my_idx = subpel_idx[0][my];
-
- x_off += mv->x >> 2;
- y_off += mv->y >> 2;
-
- // edge emulation
- ff_thread_await_progress(ref, (3 + y_off + block_h + subpel_idx[2][my]) >> 4, 0);
- src += y_off * linesize + x_off;
- if (x_off < mx_idx || x_off >= width - block_w - subpel_idx[2][mx] ||
- y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
- s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
- src - my_idx * linesize - mx_idx,
- EDGE_EMU_LINESIZE, linesize,
- block_w + subpel_idx[1][mx],
- block_h + subpel_idx[1][my],
- x_off - mx_idx, y_off - my_idx,
- width, height);
- src = td->edge_emu_buffer + mx_idx + EDGE_EMU_LINESIZE * my_idx;
- src_linesize = EDGE_EMU_LINESIZE;
- }
- mc_func[my_idx][mx_idx](dst, linesize, src, src_linesize, block_h, mx, my);
- } else {
- ff_thread_await_progress(ref, (3 + y_off + block_h) >> 4, 0);
- mc_func[0][0](dst, linesize, src + y_off * linesize + x_off,
- linesize, block_h, 0, 0);
- }
-}
-
-/**
- * chroma MC function
- *
- * @param s VP8 decoding context
- * @param dst1 target buffer for block data at block position (U plane)
- * @param dst2 target buffer for block data at block position (V plane)
- * @param ref reference picture buffer at origin (0, 0)
- * @param mv motion vector (relative to block position) to get pixel data from
- * @param x_off horizontal position of block from origin (0, 0)
- * @param y_off vertical position of block from origin (0, 0)
- * @param block_w width of block (16, 8 or 4)
- * @param block_h height of block (always same as block_w)
- * @param width width of src/dst plane data
- * @param height height of src/dst plane data
- * @param linesize size of a single line of plane data, including padding
- * @param mc_func motion compensation function pointers (bilinear or sixtap MC)
- */
-static av_always_inline
-void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1,
- uint8_t *dst2, ThreadFrame *ref, const VP56mv *mv,
- int x_off, int y_off, int block_w, int block_h,
- int width, int height, ptrdiff_t linesize,
- vp8_mc_func mc_func[3][3])
-{
- uint8_t *src1 = ref->f->data[1], *src2 = ref->f->data[2];
-
- if (AV_RN32A(mv)) {
- int mx = mv->x & 7, mx_idx = subpel_idx[0][mx];
- int my = mv->y & 7, my_idx = subpel_idx[0][my];
-
- x_off += mv->x >> 3;
- y_off += mv->y >> 3;
-
- // edge emulation
- src1 += y_off * linesize + x_off;
- src2 += y_off * linesize + x_off;
- ff_thread_await_progress(ref, (3 + y_off + block_h + subpel_idx[2][my]) >> 3, 0);
- if (x_off < mx_idx || x_off >= width - block_w - subpel_idx[2][mx] ||
- y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
- s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
- src1 - my_idx * linesize - mx_idx,
- EDGE_EMU_LINESIZE, linesize,
- block_w + subpel_idx[1][mx],
- block_h + subpel_idx[1][my],
- x_off - mx_idx, y_off - my_idx, width, height);
- src1 = td->edge_emu_buffer + mx_idx + EDGE_EMU_LINESIZE * my_idx;
- mc_func[my_idx][mx_idx](dst1, linesize, src1, EDGE_EMU_LINESIZE, block_h, mx, my);
-
- s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
- src2 - my_idx * linesize - mx_idx,
- EDGE_EMU_LINESIZE, linesize,
- block_w + subpel_idx[1][mx],
- block_h + subpel_idx[1][my],
- x_off - mx_idx, y_off - my_idx, width, height);
- src2 = td->edge_emu_buffer + mx_idx + EDGE_EMU_LINESIZE * my_idx;
- mc_func[my_idx][mx_idx](dst2, linesize, src2, EDGE_EMU_LINESIZE, block_h, mx, my);
- } else {
- mc_func[my_idx][mx_idx](dst1, linesize, src1, linesize, block_h, mx, my);
- mc_func[my_idx][mx_idx](dst2, linesize, src2, linesize, block_h, mx, my);
- }
- } else {
- ff_thread_await_progress(ref, (3 + y_off + block_h) >> 3, 0);
- mc_func[0][0](dst1, linesize, src1 + y_off * linesize + x_off, linesize, block_h, 0, 0);
- mc_func[0][0](dst2, linesize, src2 + y_off * linesize + x_off, linesize, block_h, 0, 0);
- }
-}
-
-static av_always_inline
-void vp8_mc_part(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3],
- ThreadFrame *ref_frame, int x_off, int y_off,
- int bx_off, int by_off, int block_w, int block_h,
- int width, int height, VP56mv *mv)
-{
- VP56mv uvmv = *mv;
-
- /* Y */
- vp8_mc_luma(s, td, dst[0] + by_off * s->linesize + bx_off,
- ref_frame, mv, x_off + bx_off, y_off + by_off,
- block_w, block_h, width, height, s->linesize,
- s->put_pixels_tab[block_w == 8]);
-
- /* U/V */
- if (s->profile == 3) {
- /* this block only applies VP8; it is safe to check
- * only the profile, as VP7 profile <= 1 */
- uvmv.x &= ~7;
- uvmv.y &= ~7;
- }
- x_off >>= 1;
- y_off >>= 1;
- bx_off >>= 1;
- by_off >>= 1;
- width >>= 1;
- height >>= 1;
- block_w >>= 1;
- block_h >>= 1;
- vp8_mc_chroma(s, td, dst[1] + by_off * s->uvlinesize + bx_off,
- dst[2] + by_off * s->uvlinesize + bx_off, ref_frame,
- &uvmv, x_off + bx_off, y_off + by_off,
- block_w, block_h, width, height, s->uvlinesize,
- s->put_pixels_tab[1 + (block_w == 4)]);
-}
-
-/* Fetch pixels for estimated mv 4 macroblocks ahead.
- * Optimized for 64-byte cache lines. Inspired by ffh264 prefetch_motion. */
-static av_always_inline
-void prefetch_motion(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,
- int mb_xy, int ref)
-{
- /* Don't prefetch refs that haven't been used very often this frame. */
- if (s->ref_count[ref - 1] > (mb_xy >> 5)) {
- int x_off = mb_x << 4, y_off = mb_y << 4;
- int mx = (mb->mv.x >> 2) + x_off + 8;
- int my = (mb->mv.y >> 2) + y_off;
- uint8_t **src = s->framep[ref]->tf.f->data;
- int off = mx + (my + (mb_x & 3) * 4) * s->linesize + 64;
- /* For threading, a ff_thread_await_progress here might be useful, but
- * it actually slows down the decoder. Since a bad prefetch doesn't
- * generate bad decoder output, we don't run it here. */
- s->vdsp.prefetch(src[0] + off, s->linesize, 4);
- off = (mx >> 1) + ((my >> 1) + (mb_x & 7)) * s->uvlinesize + 64;
- s->vdsp.prefetch(src[1] + off, src[2] - src[1], 2);
- }
-}
-
-/**
- * Apply motion vectors to prediction buffer, chapter 18.
- */
-static av_always_inline
-void inter_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3],
- VP8Macroblock *mb, int mb_x, int mb_y)
-{
- int x_off = mb_x << 4, y_off = mb_y << 4;
- int width = 16 * s->mb_width, height = 16 * s->mb_height;
- ThreadFrame *ref = &s->framep[mb->ref_frame]->tf;
- VP56mv *bmv = mb->bmv;
-
- switch (mb->partitioning) {
- case VP8_SPLITMVMODE_NONE:
- vp8_mc_part(s, td, dst, ref, x_off, y_off,
- 0, 0, 16, 16, width, height, &mb->mv);
- break;
- case VP8_SPLITMVMODE_4x4: {
- int x, y;
- VP56mv uvmv;
-
- /* Y */
- for (y = 0; y < 4; y++) {
- for (x = 0; x < 4; x++) {
- vp8_mc_luma(s, td, dst[0] + 4 * y * s->linesize + x * 4,
- ref, &bmv[4 * y + x],
- 4 * x + x_off, 4 * y + y_off, 4, 4,
- width, height, s->linesize,
- s->put_pixels_tab[2]);
- }
- }
-
- /* U/V */
- x_off >>= 1;
- y_off >>= 1;
- width >>= 1;
- height >>= 1;
- for (y = 0; y < 2; y++) {
- for (x = 0; x < 2; x++) {
- uvmv.x = mb->bmv[2 * y * 4 + 2 * x ].x +
- mb->bmv[2 * y * 4 + 2 * x + 1].x +
- mb->bmv[(2 * y + 1) * 4 + 2 * x ].x +
- mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].x;
- uvmv.y = mb->bmv[2 * y * 4 + 2 * x ].y +
- mb->bmv[2 * y * 4 + 2 * x + 1].y +
- mb->bmv[(2 * y + 1) * 4 + 2 * x ].y +
- mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].y;
- uvmv.x = (uvmv.x + 2 + FF_SIGNBIT(uvmv.x)) >> 2;
- uvmv.y = (uvmv.y + 2 + FF_SIGNBIT(uvmv.y)) >> 2;
- if (s->profile == 3) {
- uvmv.x &= ~7;
- uvmv.y &= ~7;
- }
- vp8_mc_chroma(s, td, dst[1] + 4 * y * s->uvlinesize + x * 4,
- dst[2] + 4 * y * s->uvlinesize + x * 4, ref,
- &uvmv, 4 * x + x_off, 4 * y + y_off, 4, 4,
- width, height, s->uvlinesize,
- s->put_pixels_tab[2]);
- }
- }
- break;
- }
- case VP8_SPLITMVMODE_16x8:
- vp8_mc_part(s, td, dst, ref, x_off, y_off,
- 0, 0, 16, 8, width, height, &bmv[0]);
- vp8_mc_part(s, td, dst, ref, x_off, y_off,
- 0, 8, 16, 8, width, height, &bmv[1]);
- break;
- case VP8_SPLITMVMODE_8x16:
- vp8_mc_part(s, td, dst, ref, x_off, y_off,
- 0, 0, 8, 16, width, height, &bmv[0]);
- vp8_mc_part(s, td, dst, ref, x_off, y_off,
- 8, 0, 8, 16, width, height, &bmv[1]);
- break;
- case VP8_SPLITMVMODE_8x8:
- vp8_mc_part(s, td, dst, ref, x_off, y_off,
- 0, 0, 8, 8, width, height, &bmv[0]);
- vp8_mc_part(s, td, dst, ref, x_off, y_off,
- 8, 0, 8, 8, width, height, &bmv[1]);
- vp8_mc_part(s, td, dst, ref, x_off, y_off,
- 0, 8, 8, 8, width, height, &bmv[2]);
- vp8_mc_part(s, td, dst, ref, x_off, y_off,
- 8, 8, 8, 8, width, height, &bmv[3]);
- break;
- }
-}
-
-static av_always_inline
-void idct_mb(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], VP8Macroblock *mb)
-{
- int x, y, ch;
-
- if (mb->mode != MODE_I4x4) {
- uint8_t *y_dst = dst[0];
- for (y = 0; y < 4; y++) {
- uint32_t nnz4 = AV_RL32(td->non_zero_count_cache[y]);
- if (nnz4) {
- if (nnz4 & ~0x01010101) {
- for (x = 0; x < 4; x++) {
- if ((uint8_t) nnz4 == 1)
- s->vp8dsp.vp8_idct_dc_add(y_dst + 4 * x,
- td->block[y][x],
- s->linesize);
- else if ((uint8_t) nnz4 > 1)
- s->vp8dsp.vp8_idct_add(y_dst + 4 * x,
- td->block[y][x],
- s->linesize);
- nnz4 >>= 8;
- if (!nnz4)
- break;
- }
- } else {
- s->vp8dsp.vp8_idct_dc_add4y(y_dst, td->block[y], s->linesize);
- }
- }
- y_dst += 4 * s->linesize;
- }
- }
-
- for (ch = 0; ch < 2; ch++) {
- uint32_t nnz4 = AV_RL32(td->non_zero_count_cache[4 + ch]);
- if (nnz4) {
- uint8_t *ch_dst = dst[1 + ch];
- if (nnz4 & ~0x01010101) {
- for (y = 0; y < 2; y++) {
- for (x = 0; x < 2; x++) {
- if ((uint8_t) nnz4 == 1)
- s->vp8dsp.vp8_idct_dc_add(ch_dst + 4 * x,
- td->block[4 + ch][(y << 1) + x],
- s->uvlinesize);
- else if ((uint8_t) nnz4 > 1)
- s->vp8dsp.vp8_idct_add(ch_dst + 4 * x,
- td->block[4 + ch][(y << 1) + x],
- s->uvlinesize);
- nnz4 >>= 8;
- if (!nnz4)
- goto chroma_idct_end;
- }
- ch_dst += 4 * s->uvlinesize;
- }
- } else {
- s->vp8dsp.vp8_idct_dc_add4uv(ch_dst, td->block[4 + ch], s->uvlinesize);
- }
- }
-chroma_idct_end:
- ;
- }
-}
-
-static av_always_inline
-void filter_level_for_mb(VP8Context *s, VP8Macroblock *mb,
- VP8FilterStrength *f, int is_vp7)
-{
- int interior_limit, filter_level;
-
- if (s->segmentation.enabled) {
- filter_level = s->segmentation.filter_level[mb->segment];
- if (!s->segmentation.absolute_vals)
- filter_level += s->filter.level;
- } else
- filter_level = s->filter.level;
-
- if (s->lf_delta.enabled) {
- filter_level += s->lf_delta.ref[mb->ref_frame];
- filter_level += s->lf_delta.mode[mb->mode];
- }
-
- filter_level = av_clip_uintp2(filter_level, 6);
-
- interior_limit = filter_level;
- if (s->filter.sharpness) {
- interior_limit >>= (s->filter.sharpness + 3) >> 2;
- interior_limit = FFMIN(interior_limit, 9 - s->filter.sharpness);
- }
- interior_limit = FFMAX(interior_limit, 1);
-
- f->filter_level = filter_level;
- f->inner_limit = interior_limit;
- f->inner_filter = is_vp7 || !mb->skip || mb->mode == MODE_I4x4 ||
- mb->mode == VP8_MVMODE_SPLIT;
-}
-
-static av_always_inline
-void filter_mb(VP8Context *s, uint8_t *dst[3], VP8FilterStrength *f,
- int mb_x, int mb_y, int is_vp7)
-{
- int mbedge_lim, bedge_lim_y, bedge_lim_uv, hev_thresh;
- int filter_level = f->filter_level;
- int inner_limit = f->inner_limit;
- int inner_filter = f->inner_filter;
- int linesize = s->linesize;
- int uvlinesize = s->uvlinesize;
- static const uint8_t hev_thresh_lut[2][64] = {
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3 },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2 }
- };
-
- if (!filter_level)
- return;
-
- if (is_vp7) {
- bedge_lim_y = filter_level;
- bedge_lim_uv = filter_level * 2;
- mbedge_lim = filter_level + 2;
- } else {
- bedge_lim_y =
- bedge_lim_uv = filter_level * 2 + inner_limit;
- mbedge_lim = bedge_lim_y + 4;
- }
-
- hev_thresh = hev_thresh_lut[s->keyframe][filter_level];
-
- if (mb_x) {
- s->vp8dsp.vp8_h_loop_filter16y(dst[0], linesize,
- mbedge_lim, inner_limit, hev_thresh);
- s->vp8dsp.vp8_h_loop_filter8uv(dst[1], dst[2], uvlinesize,
- mbedge_lim, inner_limit, hev_thresh);
- }
-
-#define H_LOOP_FILTER_16Y_INNER(cond) \
- if (cond && inner_filter) { \
- s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 4, linesize, \
- bedge_lim_y, inner_limit, \
- hev_thresh); \
- s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 8, linesize, \
- bedge_lim_y, inner_limit, \
- hev_thresh); \
- s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 12, linesize, \
- bedge_lim_y, inner_limit, \
- hev_thresh); \
- s->vp8dsp.vp8_h_loop_filter8uv_inner(dst[1] + 4, dst[2] + 4, \
- uvlinesize, bedge_lim_uv, \
- inner_limit, hev_thresh); \
- }
-
- H_LOOP_FILTER_16Y_INNER(!is_vp7)
-
- if (mb_y) {
- s->vp8dsp.vp8_v_loop_filter16y(dst[0], linesize,
- mbedge_lim, inner_limit, hev_thresh);
- s->vp8dsp.vp8_v_loop_filter8uv(dst[1], dst[2], uvlinesize,
- mbedge_lim, inner_limit, hev_thresh);
- }
-
- if (inner_filter) {
- s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 4 * linesize,
- linesize, bedge_lim_y,
- inner_limit, hev_thresh);
- s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 8 * linesize,
- linesize, bedge_lim_y,
- inner_limit, hev_thresh);
- s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 12 * linesize,
- linesize, bedge_lim_y,
- inner_limit, hev_thresh);
- s->vp8dsp.vp8_v_loop_filter8uv_inner(dst[1] + 4 * uvlinesize,
- dst[2] + 4 * uvlinesize,
- uvlinesize, bedge_lim_uv,
- inner_limit, hev_thresh);
- }
-
- H_LOOP_FILTER_16Y_INNER(is_vp7)
-}
-
-static av_always_inline
-void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8FilterStrength *f,
- int mb_x, int mb_y)
-{
- int mbedge_lim, bedge_lim;
- int filter_level = f->filter_level;
- int inner_limit = f->inner_limit;
- int inner_filter = f->inner_filter;
- int linesize = s->linesize;
-
- if (!filter_level)
- return;
-
- bedge_lim = 2 * filter_level + inner_limit;
- mbedge_lim = bedge_lim + 4;
-
- if (mb_x)
- s->vp8dsp.vp8_h_loop_filter_simple(dst, linesize, mbedge_lim);
- if (inner_filter) {
- s->vp8dsp.vp8_h_loop_filter_simple(dst + 4, linesize, bedge_lim);
- s->vp8dsp.vp8_h_loop_filter_simple(dst + 8, linesize, bedge_lim);
- s->vp8dsp.vp8_h_loop_filter_simple(dst + 12, linesize, bedge_lim);
- }
-
- if (mb_y)
- s->vp8dsp.vp8_v_loop_filter_simple(dst, linesize, mbedge_lim);
- if (inner_filter) {
- s->vp8dsp.vp8_v_loop_filter_simple(dst + 4 * linesize, linesize, bedge_lim);
- s->vp8dsp.vp8_v_loop_filter_simple(dst + 8 * linesize, linesize, bedge_lim);
- s->vp8dsp.vp8_v_loop_filter_simple(dst + 12 * linesize, linesize, bedge_lim);
- }
-}
-
-#define MARGIN (16 << 2)
-static av_always_inline
-void vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe,
- VP8Frame *prev_frame, int is_vp7)
-{
- VP8Context *s = avctx->priv_data;
- int mb_x, mb_y;
-
- s->mv_min.y = -MARGIN;
- s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN;
- for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
- VP8Macroblock *mb = s->macroblocks_base +
- ((s->mb_width + 1) * (mb_y + 1) + 1);
- int mb_xy = mb_y * s->mb_width;
-
- AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED * 0x01010101);
-
- s->mv_min.x = -MARGIN;
- s->mv_max.x = ((s->mb_width - 1) << 6) + MARGIN;
- for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {
- if (mb_y == 0)
- AV_WN32A((mb - s->mb_width - 1)->intra4x4_pred_mode_top,
- DC_PRED * 0x01010101);
- decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,
- prev_frame && prev_frame->seg_map ?
- prev_frame->seg_map->data + mb_xy : NULL, 1, is_vp7);
- s->mv_min.x -= 64;
- s->mv_max.x -= 64;
- }
- s->mv_min.y -= 64;
- s->mv_max.y -= 64;
- }
-}
-
-static void vp7_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame,
- VP8Frame *prev_frame)
-{
- vp78_decode_mv_mb_modes(avctx, cur_frame, prev_frame, IS_VP7);
-}
-
-static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame,
- VP8Frame *prev_frame)
-{
- vp78_decode_mv_mb_modes(avctx, cur_frame, prev_frame, IS_VP8);
-}
-
-#if HAVE_THREADS
-#define check_thread_pos(td, otd, mb_x_check, mb_y_check) \
- do { \
- int tmp = (mb_y_check << 16) | (mb_x_check & 0xFFFF); \
- if (otd->thread_mb_pos < tmp) { \
- pthread_mutex_lock(&otd->lock); \
- td->wait_mb_pos = tmp; \
- do { \
- if (otd->thread_mb_pos >= tmp) \
- break; \
- pthread_cond_wait(&otd->cond, &otd->lock); \
- } while (1); \
- td->wait_mb_pos = INT_MAX; \
- pthread_mutex_unlock(&otd->lock); \
- } \
- } while (0)
-
-#define update_pos(td, mb_y, mb_x) \
- do { \
- int pos = (mb_y << 16) | (mb_x & 0xFFFF); \
- int sliced_threading = (avctx->active_thread_type == FF_THREAD_SLICE) && \
- (num_jobs > 1); \
- int is_null = !next_td || !prev_td; \
- int pos_check = (is_null) ? 1 \
- : (next_td != td && \
- pos >= next_td->wait_mb_pos) || \
- (prev_td != td && \
- pos >= prev_td->wait_mb_pos); \
- td->thread_mb_pos = pos; \
- if (sliced_threading && pos_check) { \
- pthread_mutex_lock(&td->lock); \
- pthread_cond_broadcast(&td->cond); \
- pthread_mutex_unlock(&td->lock); \
- } \
- } while (0)
-#else
-#define check_thread_pos(td, otd, mb_x_check, mb_y_check) while(0)
-#define update_pos(td, mb_y, mb_x) while(0)
-#endif
-
-static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
- int jobnr, int threadnr, int is_vp7)
-{
- VP8Context *s = avctx->priv_data;
- VP8ThreadData *prev_td, *next_td, *td = &s->thread_data[threadnr];
- int mb_y = td->thread_mb_pos >> 16;
- int mb_x, mb_xy = mb_y * s->mb_width;
- int num_jobs = s->num_jobs;
- VP8Frame *curframe = s->curframe, *prev_frame = s->prev_frame;
- VP56RangeCoder *c = &s->coeff_partition[mb_y & (s->num_coeff_partitions - 1)];
- VP8Macroblock *mb;
- uint8_t *dst[3] = {
- curframe->tf.f->data[0] + 16 * mb_y * s->linesize,
- curframe->tf.f->data[1] + 8 * mb_y * s->uvlinesize,
- curframe->tf.f->data[2] + 8 * mb_y * s->uvlinesize
- };
- if (mb_y == 0)
- prev_td = td;
- else
- prev_td = &s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
- if (mb_y == s->mb_height - 1)
- next_td = td;
- else
- next_td = &s->thread_data[(jobnr + 1) % num_jobs];
- if (s->mb_layout == 1)
- mb = s->macroblocks_base + ((s->mb_width + 1) * (mb_y + 1) + 1);
- else {
- // Make sure the previous frame has read its segmentation map,
- // if we re-use the same map.
- if (prev_frame && s->segmentation.enabled &&
- !s->segmentation.update_map)
- ff_thread_await_progress(&prev_frame->tf, mb_y, 0);
- mb = s->macroblocks + (s->mb_height - mb_y - 1) * 2;
- memset(mb - 1, 0, sizeof(*mb)); // zero left macroblock
- AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED * 0x01010101);
- }
-
- if (!is_vp7 || mb_y == 0)
- memset(td->left_nnz, 0, sizeof(td->left_nnz));
-
- s->mv_min.x = -MARGIN;
- s->mv_max.x = ((s->mb_width - 1) << 6) + MARGIN;
-
- for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {
- // Wait for previous thread to read mb_x+2, and reach mb_y-1.
- if (prev_td != td) {
- if (threadnr != 0) {
- check_thread_pos(td, prev_td,
- mb_x + (is_vp7 ? 2 : 1),
- mb_y - (is_vp7 ? 2 : 1));
- } else {
- check_thread_pos(td, prev_td,
- mb_x + (is_vp7 ? 2 : 1) + s->mb_width + 3,
- mb_y - (is_vp7 ? 2 : 1));
- }
- }
-
- s->vdsp.prefetch(dst[0] + (mb_x & 3) * 4 * s->linesize + 64,
- s->linesize, 4);
- s->vdsp.prefetch(dst[1] + (mb_x & 7) * s->uvlinesize + 64,
- dst[2] - dst[1], 2);
-
- if (!s->mb_layout)
- decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,
- prev_frame && prev_frame->seg_map ?
- prev_frame->seg_map->data + mb_xy : NULL, 0, is_vp7);
-
- prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_PREVIOUS);
-
- if (!mb->skip)
- decode_mb_coeffs(s, td, c, mb, s->top_nnz[mb_x], td->left_nnz, is_vp7);
-
- if (mb->mode <= MODE_I4x4)
- intra_predict(s, td, dst, mb, mb_x, mb_y, is_vp7);
- else
- inter_predict(s, td, dst, mb, mb_x, mb_y);
-
- prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_GOLDEN);
-
- if (!mb->skip) {
- idct_mb(s, td, dst, mb);
- } else {
- AV_ZERO64(td->left_nnz);
- AV_WN64(s->top_nnz[mb_x], 0); // array of 9, so unaligned
-
- /* Reset DC block predictors if they would exist
- * if the mb had coefficients */
- if (mb->mode != MODE_I4x4 && mb->mode != VP8_MVMODE_SPLIT) {
- td->left_nnz[8] = 0;
- s->top_nnz[mb_x][8] = 0;
- }
- }
-
- if (s->deblock_filter)
- filter_level_for_mb(s, mb, &td->filter_strength[mb_x], is_vp7);
-
- if (s->deblock_filter && num_jobs != 1 && threadnr == num_jobs - 1) {
- if (s->filter.simple)
- backup_mb_border(s->top_border[mb_x + 1], dst[0],
- NULL, NULL, s->linesize, 0, 1);
- else
- backup_mb_border(s->top_border[mb_x + 1], dst[0],
- dst[1], dst[2], s->linesize, s->uvlinesize, 0);
- }
-
- prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_GOLDEN2);
-
- dst[0] += 16;
- dst[1] += 8;
- dst[2] += 8;
- s->mv_min.x -= 64;
- s->mv_max.x -= 64;
-
- if (mb_x == s->mb_width + 1) {
- update_pos(td, mb_y, s->mb_width + 3);
- } else {
- update_pos(td, mb_y, mb_x);
- }
- }
-}
-
-static void vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
- int jobnr, int threadnr)
-{
- decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1);
-}
-
-static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
- int jobnr, int threadnr)
-{
- decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0);
-}
-
-static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata,
- int jobnr, int threadnr, int is_vp7)
-{
- VP8Context *s = avctx->priv_data;
- VP8ThreadData *td = &s->thread_data[threadnr];
- int mb_x, mb_y = td->thread_mb_pos >> 16, num_jobs = s->num_jobs;
- AVFrame *curframe = s->curframe->tf.f;
- VP8Macroblock *mb;
- VP8ThreadData *prev_td, *next_td;
- uint8_t *dst[3] = {
- curframe->data[0] + 16 * mb_y * s->linesize,
- curframe->data[1] + 8 * mb_y * s->uvlinesize,
- curframe->data[2] + 8 * mb_y * s->uvlinesize
- };
-
- if (s->mb_layout == 1)
- mb = s->macroblocks_base + ((s->mb_width + 1) * (mb_y + 1) + 1);
- else
- mb = s->macroblocks + (s->mb_height - mb_y - 1) * 2;
-
- if (mb_y == 0)
- prev_td = td;
- else
- prev_td = &s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
- if (mb_y == s->mb_height - 1)
- next_td = td;
- else
- next_td = &s->thread_data[(jobnr + 1) % num_jobs];
-
- for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb++) {
- VP8FilterStrength *f = &td->filter_strength[mb_x];
- if (prev_td != td)
- check_thread_pos(td, prev_td,
- (mb_x + 1) + (s->mb_width + 3), mb_y - 1);
- if (next_td != td)
- if (next_td != &s->thread_data[0])
- check_thread_pos(td, next_td, mb_x + 1, mb_y + 1);
-
- if (num_jobs == 1) {
- if (s->filter.simple)
- backup_mb_border(s->top_border[mb_x + 1], dst[0],
- NULL, NULL, s->linesize, 0, 1);
- else
- backup_mb_border(s->top_border[mb_x + 1], dst[0],
- dst[1], dst[2], s->linesize, s->uvlinesize, 0);
- }
-
- if (s->filter.simple)
- filter_mb_simple(s, dst[0], f, mb_x, mb_y);
- else
- filter_mb(s, dst, f, mb_x, mb_y, is_vp7);
- dst[0] += 16;
- dst[1] += 8;
- dst[2] += 8;
-
- update_pos(td, mb_y, (s->mb_width + 3) + mb_x);
- }
-}
-
-static void vp7_filter_mb_row(AVCodecContext *avctx, void *tdata,
- int jobnr, int threadnr)
-{
- filter_mb_row(avctx, tdata, jobnr, threadnr, 1);
-}
-
-static void vp8_filter_mb_row(AVCodecContext *avctx, void *tdata,
- int jobnr, int threadnr)
-{
- filter_mb_row(avctx, tdata, jobnr, threadnr, 0);
-}
-
-static av_always_inline
-int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr,
- int threadnr, int is_vp7)
-{
- VP8Context *s = avctx->priv_data;
- VP8ThreadData *td = &s->thread_data[jobnr];
- VP8ThreadData *next_td = NULL, *prev_td = NULL;
- VP8Frame *curframe = s->curframe;
- int mb_y, num_jobs = s->num_jobs;
-
- td->thread_nr = threadnr;
- for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) {
- if (mb_y >= s->mb_height)
- break;
- td->thread_mb_pos = mb_y << 16;
- s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr);
- if (s->deblock_filter)
- s->filter_mb_row(avctx, tdata, jobnr, threadnr);
- update_pos(td, mb_y, INT_MAX & 0xFFFF);
-
- s->mv_min.y -= 64;
- s->mv_max.y -= 64;
-
- if (avctx->active_thread_type == FF_THREAD_FRAME)
- ff_thread_report_progress(&curframe->tf, mb_y, 0);
- }
-
- return 0;
-}
-
-static int vp7_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata,
- int jobnr, int threadnr)
-{
- return vp78_decode_mb_row_sliced(avctx, tdata, jobnr, threadnr, IS_VP7);
-}
-
-static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata,
- int jobnr, int threadnr)
-{
- return vp78_decode_mb_row_sliced(avctx, tdata, jobnr, threadnr, IS_VP8);
-}
-
-
-static av_always_inline
-int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *avpkt, int is_vp7)
-{
- VP8Context *s = avctx->priv_data;
- int ret, i, referenced, num_jobs;
- enum AVDiscard skip_thresh;
- VP8Frame *av_uninit(curframe), *prev_frame;
-
- if (is_vp7)
- ret = vp7_decode_frame_header(s, avpkt->data, avpkt->size);
- else
- ret = vp8_decode_frame_header(s, avpkt->data, avpkt->size);
-
- if (ret < 0)
- goto err;
-
- prev_frame = s->framep[VP56_FRAME_CURRENT];
-
- referenced = s->update_last || s->update_golden == VP56_FRAME_CURRENT ||
- s->update_altref == VP56_FRAME_CURRENT;
-
- skip_thresh = !referenced ? AVDISCARD_NONREF
- : !s->keyframe ? AVDISCARD_NONKEY
- : AVDISCARD_ALL;
-
- if (avctx->skip_frame >= skip_thresh) {
- s->invisible = 1;
- memcpy(&s->next_framep[0], &s->framep[0], sizeof(s->framep[0]) * 4);
- goto skip_decode;
- }
- s->deblock_filter = s->filter.level && avctx->skip_loop_filter < skip_thresh;
-
- // release no longer referenced frames
- for (i = 0; i < 5; i++)
- if (s->frames[i].tf.f->data[0] &&
- &s->frames[i] != prev_frame &&
- &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] &&
- &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] &&
- &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2])
- vp8_release_frame(s, &s->frames[i]);
-
- curframe = s->framep[VP56_FRAME_CURRENT] = vp8_find_free_buffer(s);
-
- if (!s->colorspace)
- avctx->colorspace = AVCOL_SPC_BT470BG;
- if (s->fullrange)
- avctx->color_range = AVCOL_RANGE_JPEG;
- else
- avctx->color_range = AVCOL_RANGE_MPEG;
-
- /* Given that arithmetic probabilities are updated every frame, it's quite
- * likely that the values we have on a random interframe are complete
- * junk if we didn't start decode on a keyframe. So just don't display
- * anything rather than junk. */
- if (!s->keyframe && (!s->framep[VP56_FRAME_PREVIOUS] ||
- !s->framep[VP56_FRAME_GOLDEN] ||
- !s->framep[VP56_FRAME_GOLDEN2])) {
- av_log(avctx, AV_LOG_WARNING,
- "Discarding interframe without a prior keyframe!\n");
- ret = AVERROR_INVALIDDATA;
- goto err;
- }
-
- curframe->tf.f->key_frame = s->keyframe;
- curframe->tf.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I
- : AV_PICTURE_TYPE_P;
- if ((ret = vp8_alloc_frame(s, curframe, referenced)) < 0)
- goto err;
-
- // check if golden and altref are swapped
- if (s->update_altref != VP56_FRAME_NONE)
- s->next_framep[VP56_FRAME_GOLDEN2] = s->framep[s->update_altref];
- else
- s->next_framep[VP56_FRAME_GOLDEN2] = s->framep[VP56_FRAME_GOLDEN2];
-
- if (s->update_golden != VP56_FRAME_NONE)
- s->next_framep[VP56_FRAME_GOLDEN] = s->framep[s->update_golden];
- else
- s->next_framep[VP56_FRAME_GOLDEN] = s->framep[VP56_FRAME_GOLDEN];
-
- if (s->update_last)
- s->next_framep[VP56_FRAME_PREVIOUS] = curframe;
- else
- s->next_framep[VP56_FRAME_PREVIOUS] = s->framep[VP56_FRAME_PREVIOUS];
-
- s->next_framep[VP56_FRAME_CURRENT] = curframe;
-
- if (avctx->codec->update_thread_context)
- ff_thread_finish_setup(avctx);
-
- s->linesize = curframe->tf.f->linesize[0];
- s->uvlinesize = curframe->tf.f->linesize[1];
-
- memset(s->top_nnz, 0, s->mb_width * sizeof(*s->top_nnz));
- /* Zero macroblock structures for top/top-left prediction
- * from outside the frame. */
- if (!s->mb_layout)
- memset(s->macroblocks + s->mb_height * 2 - 1, 0,
- (s->mb_width + 1) * sizeof(*s->macroblocks));
- if (!s->mb_layout && s->keyframe)
- memset(s->intra4x4_pred_mode_top, DC_PRED, s->mb_width * 4);
-
- memset(s->ref_count, 0, sizeof(s->ref_count));
-
- if (s->mb_layout == 1) {
- // Make sure the previous frame has read its segmentation map,
- // if we re-use the same map.
- if (prev_frame && s->segmentation.enabled &&
- !s->segmentation.update_map)
- ff_thread_await_progress(&prev_frame->tf, 1, 0);
- if (is_vp7)
- vp7_decode_mv_mb_modes(avctx, curframe, prev_frame);
- else
- vp8_decode_mv_mb_modes(avctx, curframe, prev_frame);
- }
-
- if (avctx->active_thread_type == FF_THREAD_FRAME)
- num_jobs = 1;
- else
- num_jobs = FFMIN(s->num_coeff_partitions, avctx->thread_count);
- s->num_jobs = num_jobs;
- s->curframe = curframe;
- s->prev_frame = prev_frame;
- s->mv_min.y = -MARGIN;
- s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN;
- for (i = 0; i < MAX_THREADS; i++) {
- s->thread_data[i].thread_mb_pos = 0;
- s->thread_data[i].wait_mb_pos = INT_MAX;
- }
- if (is_vp7)
- avctx->execute2(avctx, vp7_decode_mb_row_sliced, s->thread_data, NULL,
- num_jobs);
- else
- avctx->execute2(avctx, vp8_decode_mb_row_sliced, s->thread_data, NULL,
- num_jobs);
-
- ff_thread_report_progress(&curframe->tf, INT_MAX, 0);
- memcpy(&s->framep[0], &s->next_framep[0], sizeof(s->framep[0]) * 4);
-
-skip_decode:
- // if future frames don't use the updated probabilities,
- // reset them to the values we saved
- if (!s->update_probabilities)
- s->prob[0] = s->prob[1];
-
- if (!s->invisible) {
- if ((ret = av_frame_ref(data, curframe->tf.f)) < 0)
- return ret;
- *got_frame = 1;
- }
-
- return avpkt->size;
-err:
- memcpy(&s->next_framep[0], &s->framep[0], sizeof(s->framep[0]) * 4);
- return ret;
-}
-
-int ff_vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *avpkt)
-{
- return vp78_decode_frame(avctx, data, got_frame, avpkt, IS_VP8);
-}
-
-#if CONFIG_VP7_DECODER
-static int vp7_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *avpkt)
-{
- return vp78_decode_frame(avctx, data, got_frame, avpkt, IS_VP7);
-}
-#endif /* CONFIG_VP7_DECODER */
-
-av_cold int ff_vp8_decode_free(AVCodecContext *avctx)
-{
- VP8Context *s = avctx->priv_data;
- int i;
-
- if (!s)
- return 0;
-
- vp8_decode_flush_impl(avctx, 1);
- for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++)
- av_frame_free(&s->frames[i].tf.f);
-
- return 0;
-}
-
-static av_cold int vp8_init_frames(VP8Context *s)
-{
- int i;
- for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) {
- s->frames[i].tf.f = av_frame_alloc();
- if (!s->frames[i].tf.f)
- return AVERROR(ENOMEM);
- }
- return 0;
-}
-
-static av_always_inline
-int vp78_decode_init(AVCodecContext *avctx, int is_vp7)
-{
- VP8Context *s = avctx->priv_data;
- int ret;
-
- s->avctx = avctx;
- s->vp7 = avctx->codec->id == AV_CODEC_ID_VP7;
- avctx->pix_fmt = AV_PIX_FMT_YUV420P;
- avctx->internal->allocate_progress = 1;
-
- ff_videodsp_init(&s->vdsp, 8);
-
- ff_vp78dsp_init(&s->vp8dsp);
- if (CONFIG_VP7_DECODER && is_vp7) {
- ff_h264_pred_init(&s->hpc, AV_CODEC_ID_VP7, 8, 1);
- ff_vp7dsp_init(&s->vp8dsp);
- s->decode_mb_row_no_filter = vp7_decode_mb_row_no_filter;
- s->filter_mb_row = vp7_filter_mb_row;
- } else if (CONFIG_VP8_DECODER && !is_vp7) {
- ff_h264_pred_init(&s->hpc, AV_CODEC_ID_VP8, 8, 1);
- ff_vp8dsp_init(&s->vp8dsp);
- s->decode_mb_row_no_filter = vp8_decode_mb_row_no_filter;
- s->filter_mb_row = vp8_filter_mb_row;
- }
-
- /* does not change for VP8 */
- memcpy(s->prob[0].scan, zigzag_scan, sizeof(s->prob[0].scan));
-
- if ((ret = vp8_init_frames(s)) < 0) {
- ff_vp8_decode_free(avctx);
- return ret;
- }
-
- return 0;
-}
-
-#if CONFIG_VP7_DECODER
-static int vp7_decode_init(AVCodecContext *avctx)
-{
- return vp78_decode_init(avctx, IS_VP7);
-}
-#endif /* CONFIG_VP7_DECODER */
-
-av_cold int ff_vp8_decode_init(AVCodecContext *avctx)
-{
- return vp78_decode_init(avctx, IS_VP8);
-}
-
-#if CONFIG_VP8_DECODER
-static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx)
-{
- VP8Context *s = avctx->priv_data;
- int ret;
-
- s->avctx = avctx;
-
- if ((ret = vp8_init_frames(s)) < 0) {
- ff_vp8_decode_free(avctx);
- return ret;
- }
-
- return 0;
-}
-
-#define REBASE(pic) ((pic) ? (pic) - &s_src->frames[0] + &s->frames[0] : NULL)
-
-static int vp8_decode_update_thread_context(AVCodecContext *dst,
- const AVCodecContext *src)
-{
- VP8Context *s = dst->priv_data, *s_src = src->priv_data;
- int i;
-
- if (s->macroblocks_base &&
- (s_src->mb_width != s->mb_width || s_src->mb_height != s->mb_height)) {
- free_buffers(s);
- s->mb_width = s_src->mb_width;
- s->mb_height = s_src->mb_height;
- }
-
- s->prob[0] = s_src->prob[!s_src->update_probabilities];
- s->segmentation = s_src->segmentation;
- s->lf_delta = s_src->lf_delta;
- memcpy(s->sign_bias, s_src->sign_bias, sizeof(s->sign_bias));
-
- for (i = 0; i < FF_ARRAY_ELEMS(s_src->frames); i++) {
- if (s_src->frames[i].tf.f->data[0]) {
- int ret = vp8_ref_frame(s, &s->frames[i], &s_src->frames[i]);
- if (ret < 0)
- return ret;
- }
- }
-
- s->framep[0] = REBASE(s_src->next_framep[0]);
- s->framep[1] = REBASE(s_src->next_framep[1]);
- s->framep[2] = REBASE(s_src->next_framep[2]);
- s->framep[3] = REBASE(s_src->next_framep[3]);
-
- return 0;
-}
-#endif /* CONFIG_VP8_DECODER */
-
-#if CONFIG_VP7_DECODER
-AVCodec ff_vp7_decoder = {
- .name = "vp7",
- .long_name = NULL_IF_CONFIG_SMALL("On2 VP7"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_VP7,
- .priv_data_size = sizeof(VP8Context),
- .init = vp7_decode_init,
- .close = ff_vp8_decode_free,
- .decode = vp7_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
- .flush = vp8_decode_flush,
-};
-#endif /* CONFIG_VP7_DECODER */
-
-#if CONFIG_VP8_DECODER
-AVCodec ff_vp8_decoder = {
- .name = "vp8",
- .long_name = NULL_IF_CONFIG_SMALL("On2 VP8"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_VP8,
- .priv_data_size = sizeof(VP8Context),
- .init = ff_vp8_decode_init,
- .close = ff_vp8_decode_free,
- .decode = ff_vp8_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
- AV_CODEC_CAP_SLICE_THREADS,
- .flush = vp8_decode_flush,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy),
- .update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_context),
-};
-#endif /* CONFIG_VP7_DECODER */
diff --git a/ffmpeg-2-8-11/libavcodec/vp8.h b/ffmpeg-2-8-11/libavcodec/vp8.h
deleted file mode 100644
index 2135bd9..0000000
--- a/ffmpeg-2-8-11/libavcodec/vp8.h
+++ /dev/null
@@ -1,318 +0,0 @@
-/*
- * VP8 compatible video decoder
- *
- * Copyright (C) 2010 David Conrad
- * Copyright (C) 2010 Ronald S. Bultje
- * Copyright (C) 2010 Fiona Glaser
- * Copyright (C) 2012 Daniel Kang
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#ifndef AVCODEC_VP8_H
-#define AVCODEC_VP8_H
-
-#include "libavutil/buffer.h"
-
-#include "h264pred.h"
-#include "thread.h"
-#include "vp56.h"
-#include "vp8dsp.h"
-
-#if HAVE_PTHREADS
-# include <pthread.h>
-#elif HAVE_OS2THREADS
-# include "compat/os2threads.h"
-#elif HAVE_W32THREADS
-# include "compat/w32pthreads.h"
-#endif
-
-#define VP8_MAX_QUANT 127
-
-enum dct_token {
- DCT_0,
- DCT_1,
- DCT_2,
- DCT_3,
- DCT_4,
- DCT_CAT1,
- DCT_CAT2,
- DCT_CAT3,
- DCT_CAT4,
- DCT_CAT5,
- DCT_CAT6,
- DCT_EOB,
-
- NUM_DCT_TOKENS
-};
-
-// used to signal 4x4 intra pred in luma MBs
-#define MODE_I4x4 4
-
-enum inter_mvmode {
- VP8_MVMODE_ZERO = MODE_I4x4 + 1,
- VP8_MVMODE_MV,
- VP8_MVMODE_SPLIT
-};
-
-enum inter_splitmvmode {
- VP8_SPLITMVMODE_16x8 = 0, ///< 2 16x8 blocks (vertical)
- VP8_SPLITMVMODE_8x16, ///< 2 8x16 blocks (horizontal)
- VP8_SPLITMVMODE_8x8, ///< 2x2 blocks of 8x8px each
- VP8_SPLITMVMODE_4x4, ///< 4x4 blocks of 4x4px each
- VP8_SPLITMVMODE_NONE, ///< (only used in prediction) no split MVs
-};
-
-typedef struct VP8FilterStrength {
- uint8_t filter_level;
- uint8_t inner_limit;
- uint8_t inner_filter;
-} VP8FilterStrength;
-
-typedef struct VP8Macroblock {
- uint8_t skip;
- // TODO: make it possible to check for at least (i4x4 or split_mv)
- // in one op. are others needed?
- uint8_t mode;
- uint8_t ref_frame;
- uint8_t partitioning;
- uint8_t chroma_pred_mode;
- uint8_t segment;
- uint8_t intra4x4_pred_mode_mb[16];
- DECLARE_ALIGNED(4, uint8_t, intra4x4_pred_mode_top)[4];
- VP56mv mv;
- VP56mv bmv[16];
-} VP8Macroblock;
-
-typedef struct VP8ThreadData {
- DECLARE_ALIGNED(16, int16_t, block)[6][4][16];
- DECLARE_ALIGNED(16, int16_t, block_dc)[16];
- /**
- * This is the index plus one of the last non-zero coeff
- * for each of the blocks in the current macroblock.
- * So, 0 -> no coeffs
- * 1 -> dc-only (special transform)
- * 2+-> full transform
- */
- DECLARE_ALIGNED(16, uint8_t, non_zero_count_cache)[6][4];
- /**
- * For coeff decode, we need to know whether the above block had non-zero
- * coefficients. This means for each macroblock, we need data for 4 luma
- * blocks, 2 u blocks, 2 v blocks, and the luma dc block, for a total of 9
- * per macroblock. We keep the last row in top_nnz.
- */
- DECLARE_ALIGNED(8, uint8_t, left_nnz)[9];
- int thread_nr;
-#if HAVE_THREADS
- pthread_mutex_t lock;
- pthread_cond_t cond;
-#endif
- int thread_mb_pos; // (mb_y << 16) | (mb_x & 0xFFFF)
- int wait_mb_pos; // What the current thread is waiting on.
-
-#define EDGE_EMU_LINESIZE 32
- DECLARE_ALIGNED(16, uint8_t, edge_emu_buffer)[21 * EDGE_EMU_LINESIZE];
- VP8FilterStrength *filter_strength;
-} VP8ThreadData;
-
-typedef struct VP8Frame {
- ThreadFrame tf;
- AVBufferRef *seg_map;
-} VP8Frame;
-
-typedef struct VP8intmv {
- int x;
- int y;
-} VP8intmv;
-
-#define MAX_THREADS 8
-typedef struct VP8Context {
- VP8ThreadData *thread_data;
- AVCodecContext *avctx;
- VP8Frame *framep[4];
- VP8Frame *next_framep[4];
- VP8Frame *curframe;
- VP8Frame *prev_frame;
-
- uint16_t mb_width; /* number of horizontal MB */
- uint16_t mb_height; /* number of vertical MB */
- int linesize;
- int uvlinesize;
-
- uint8_t keyframe;
- uint8_t deblock_filter;
- uint8_t mbskip_enabled;
- uint8_t profile;
- VP8intmv mv_min;
- VP8intmv mv_max;
-
- int8_t sign_bias[4]; ///< one state [0, 1] per ref frame type
- int ref_count[3];
-
- /**
- * Base parameters for segmentation, i.e. per-macroblock parameters.
- * These must be kept unchanged even if segmentation is not used for
- * a frame, since the values persist between interframes.
- */
- struct {
- uint8_t enabled;
- uint8_t absolute_vals;
- uint8_t update_map;
- int8_t base_quant[4];
- int8_t filter_level[4]; ///< base loop filter level
- } segmentation;
-
- struct {
- uint8_t simple;
- uint8_t level;
- uint8_t sharpness;
- } filter;
-
- VP8Macroblock *macroblocks;
-
- uint8_t *intra4x4_pred_mode_top;
- uint8_t intra4x4_pred_mode_left[4];
-
- /**
- * Macroblocks can have one of 4 different quants in a frame when
- * segmentation is enabled.
- * If segmentation is disabled, only the first segment's values are used.
- */
- struct {
- // [0] - DC qmul [1] - AC qmul
- int16_t luma_qmul[2];
- int16_t luma_dc_qmul[2]; ///< luma dc-only block quant
- int16_t chroma_qmul[2];
- } qmat[4];
-
- struct {
- uint8_t enabled; ///< whether each mb can have a different strength based on mode/ref
-
- /**
- * filter strength adjustment for the following macroblock modes:
- * [0-3] - i16x16 (always zero)
- * [4] - i4x4
- * [5] - zero mv
- * [6] - inter modes except for zero or split mv
- * [7] - split mv
- * i16x16 modes never have any adjustment
- */
- int8_t mode[VP8_MVMODE_SPLIT + 1];
-
- /**
- * filter strength adjustment for macroblocks that reference:
- * [0] - intra / VP56_FRAME_CURRENT
- * [1] - VP56_FRAME_PREVIOUS
- * [2] - VP56_FRAME_GOLDEN
- * [3] - altref / VP56_FRAME_GOLDEN2
- */
- int8_t ref[4];
- } lf_delta;
-
- uint8_t (*top_border)[16 + 8 + 8];
- uint8_t (*top_nnz)[9];
-
- VP56RangeCoder c; ///< header context, includes mb modes and motion vectors
-
- /**
- * These are all of the updatable probabilities for binary decisions.
- * They are only implictly reset on keyframes, making it quite likely
- * for an interframe to desync if a prior frame's header was corrupt
- * or missing outright!
- */
- struct {
- uint8_t segmentid[3];
- uint8_t mbskip;
- uint8_t intra;
- uint8_t last;
- uint8_t golden;
- uint8_t pred16x16[4];
- uint8_t pred8x8c[3];
- uint8_t token[4][16][3][NUM_DCT_TOKENS - 1];
- uint8_t mvc[2][19];
- uint8_t scan[16];
- } prob[2];
-
- VP8Macroblock *macroblocks_base;
- int invisible;
- int update_last; ///< update VP56_FRAME_PREVIOUS with the current one
- int update_golden; ///< VP56_FRAME_NONE if not updated, or which frame to copy if so
- int update_altref;
-
- /**
- * If this flag is not set, all the probability updates
- * are discarded after this frame is decoded.
- */
- int update_probabilities;
-
- /**
- * All coefficients are contained in separate arith coding contexts.
- * There can be 1, 2, 4, or 8 of these after the header context.
- */
- int num_coeff_partitions;
- VP56RangeCoder coeff_partition[8];
- VideoDSPContext vdsp;
- VP8DSPContext vp8dsp;
- H264PredContext hpc;
- vp8_mc_func put_pixels_tab[3][3][3];
- VP8Frame frames[5];
-
- uint8_t colorspace; ///< 0 is the only value allowed (meaning bt601)
- uint8_t fullrange; ///< whether we can skip clamping in dsp functions
-
- int num_jobs;
- /**
- * This describes the macroblock memory layout.
- * 0 -> Only width+height*2+1 macroblocks allocated (frame/single thread).
- * 1 -> Macroblocks for entire frame alloced (sliced thread).
- */
- int mb_layout;
-
- void (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr);
- void (*filter_mb_row)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr);
-
- int vp7;
-
- /**
- * Fade bit present in bitstream (VP7)
- */
- int fade_present;
-
- /**
- * Interframe DC prediction (VP7)
- * [0] VP56_FRAME_PREVIOUS
- * [1] VP56_FRAME_GOLDEN
- */
- uint16_t inter_dc_pred[2][2];
-
- /**
- * Macroblock features (VP7)
- */
- uint8_t feature_enabled[4];
- uint8_t feature_present_prob[4];
- uint8_t feature_index_prob[4][3];
- uint8_t feature_value[4][4];
-} VP8Context;
-
-int ff_vp8_decode_init(AVCodecContext *avctx);
-
-int ff_vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *avpkt);
-
-int ff_vp8_decode_free(AVCodecContext *avctx);
-
-#endif /* AVCODEC_VP8_H */
diff --git a/ffmpeg-2-8-11/libavcodec/vp8dsp.c b/ffmpeg-2-8-11/libavcodec/vp8dsp.c
deleted file mode 100644
index 07bea69..0000000
--- a/ffmpeg-2-8-11/libavcodec/vp8dsp.c
+++ /dev/null
@@ -1,741 +0,0 @@
-/*
- * Copyright (C) 2010 David Conrad
- * Copyright (C) 2010 Ronald S. Bultje
- * Copyright (C) 2014 Peter Ross
- *
- * 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
- * VP8 compatible video decoder
- */
-
-#include "libavutil/common.h"
-#include "libavutil/intreadwrite.h"
-
-#include "mathops.h"
-#include "vp8dsp.h"
-
-#define MK_IDCT_DC_ADD4_C(name) \
-static void name ## _idct_dc_add4uv_c(uint8_t *dst, int16_t block[4][16], \
- ptrdiff_t stride) \
-{ \
- name ## _idct_dc_add_c(dst + stride * 0 + 0, block[0], stride); \
- name ## _idct_dc_add_c(dst + stride * 0 + 4, block[1], stride); \
- name ## _idct_dc_add_c(dst + stride * 4 + 0, block[2], stride); \
- name ## _idct_dc_add_c(dst + stride * 4 + 4, block[3], stride); \
-} \
- \
-static void name ## _idct_dc_add4y_c(uint8_t *dst, int16_t block[4][16], \
- ptrdiff_t stride) \
-{ \
- name ## _idct_dc_add_c(dst + 0, block[0], stride); \
- name ## _idct_dc_add_c(dst + 4, block[1], stride); \
- name ## _idct_dc_add_c(dst + 8, block[2], stride); \
- name ## _idct_dc_add_c(dst + 12, block[3], stride); \
-}
-
-#if CONFIG_VP7_DECODER
-static void vp7_luma_dc_wht_c(int16_t block[4][4][16], int16_t dc[16])
-{
- int i, a1, b1, c1, d1;
- int16_t tmp[16];
-
- for (i = 0; i < 4; i++) {
- a1 = (dc[i * 4 + 0] + dc[i * 4 + 2]) * 23170;
- b1 = (dc[i * 4 + 0] - dc[i * 4 + 2]) * 23170;
- c1 = dc[i * 4 + 1] * 12540 - dc[i * 4 + 3] * 30274;
- d1 = dc[i * 4 + 1] * 30274 + dc[i * 4 + 3] * 12540;
- tmp[i * 4 + 0] = (a1 + d1) >> 14;
- tmp[i * 4 + 3] = (a1 - d1) >> 14;
- tmp[i * 4 + 1] = (b1 + c1) >> 14;
- tmp[i * 4 + 2] = (b1 - c1) >> 14;
- }
-
- for (i = 0; i < 4; i++) {
- a1 = (tmp[i + 0] + tmp[i + 8]) * 23170;
- b1 = (tmp[i + 0] - tmp[i + 8]) * 23170;
- c1 = tmp[i + 4] * 12540 - tmp[i + 12] * 30274;
- d1 = tmp[i + 4] * 30274 + tmp[i + 12] * 12540;
- AV_ZERO64(dc + i * 4);
- block[0][i][0] = (a1 + d1 + 0x20000) >> 18;
- block[3][i][0] = (a1 - d1 + 0x20000) >> 18;
- block[1][i][0] = (b1 + c1 + 0x20000) >> 18;
- block[2][i][0] = (b1 - c1 + 0x20000) >> 18;
- }
-}
-
-static void vp7_luma_dc_wht_dc_c(int16_t block[4][4][16], int16_t dc[16])
-{
- int i, val = (23170 * (23170 * dc[0] >> 14) + 0x20000) >> 18;
- dc[0] = 0;
-
- for (i = 0; i < 4; i++) {
- block[i][0][0] = val;
- block[i][1][0] = val;
- block[i][2][0] = val;
- block[i][3][0] = val;
- }
-}
-
-static void vp7_idct_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
-{
- int i, a1, b1, c1, d1;
- int16_t tmp[16];
-
- for (i = 0; i < 4; i++) {
- a1 = (block[i * 4 + 0] + block[i * 4 + 2]) * 23170;
- b1 = (block[i * 4 + 0] - block[i * 4 + 2]) * 23170;
- c1 = block[i * 4 + 1] * 12540 - block[i * 4 + 3] * 30274;
- d1 = block[i * 4 + 1] * 30274 + block[i * 4 + 3] * 12540;
- AV_ZERO64(block + i * 4);
- tmp[i * 4 + 0] = (a1 + d1) >> 14;
- tmp[i * 4 + 3] = (a1 - d1) >> 14;
- tmp[i * 4 + 1] = (b1 + c1) >> 14;
- tmp[i * 4 + 2] = (b1 - c1) >> 14;
- }
-
- for (i = 0; i < 4; i++) {
- a1 = (tmp[i + 0] + tmp[i + 8]) * 23170;
- b1 = (tmp[i + 0] - tmp[i + 8]) * 23170;
- c1 = tmp[i + 4] * 12540 - tmp[i + 12] * 30274;
- d1 = tmp[i + 4] * 30274 + tmp[i + 12] * 12540;
- dst[0 * stride + i] = av_clip_uint8(dst[0 * stride + i] +
- ((a1 + d1 + 0x20000) >> 18));
- dst[3 * stride + i] = av_clip_uint8(dst[3 * stride + i] +
- ((a1 - d1 + 0x20000) >> 18));
- dst[1 * stride + i] = av_clip_uint8(dst[1 * stride + i] +
- ((b1 + c1 + 0x20000) >> 18));
- dst[2 * stride + i] = av_clip_uint8(dst[2 * stride + i] +
- ((b1 - c1 + 0x20000) >> 18));
- }
-}
-
-static void vp7_idct_dc_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
-{
- int i, dc = (23170 * (23170 * block[0] >> 14) + 0x20000) >> 18;
- block[0] = 0;
-
- for (i = 0; i < 4; i++) {
- dst[0] = av_clip_uint8(dst[0] + dc);
- dst[1] = av_clip_uint8(dst[1] + dc);
- dst[2] = av_clip_uint8(dst[2] + dc);
- dst[3] = av_clip_uint8(dst[3] + dc);
- dst += stride;
- }
-}
-
-MK_IDCT_DC_ADD4_C(vp7)
-#endif /* CONFIG_VP7_DECODER */
-
-// TODO: Maybe add dequant
-#if CONFIG_VP8_DECODER
-static void vp8_luma_dc_wht_c(int16_t block[4][4][16], int16_t dc[16])
-{
- int i, t0, t1, t2, t3;
-
- for (i = 0; i < 4; i++) {
- t0 = dc[0 * 4 + i] + dc[3 * 4 + i];
- t1 = dc[1 * 4 + i] + dc[2 * 4 + i];
- t2 = dc[1 * 4 + i] - dc[2 * 4 + i];
- t3 = dc[0 * 4 + i] - dc[3 * 4 + i];
-
- dc[0 * 4 + i] = t0 + t1;
- dc[1 * 4 + i] = t3 + t2;
- dc[2 * 4 + i] = t0 - t1;
- dc[3 * 4 + i] = t3 - t2;
- }
-
- for (i = 0; i < 4; i++) {
- t0 = dc[i * 4 + 0] + dc[i * 4 + 3] + 3; // rounding
- t1 = dc[i * 4 + 1] + dc[i * 4 + 2];
- t2 = dc[i * 4 + 1] - dc[i * 4 + 2];
- t3 = dc[i * 4 + 0] - dc[i * 4 + 3] + 3; // rounding
- AV_ZERO64(dc + i * 4);
-
- block[i][0][0] = (t0 + t1) >> 3;
- block[i][1][0] = (t3 + t2) >> 3;
- block[i][2][0] = (t0 - t1) >> 3;
- block[i][3][0] = (t3 - t2) >> 3;
- }
-}
-
-static void vp8_luma_dc_wht_dc_c(int16_t block[4][4][16], int16_t dc[16])
-{
- int i, val = (dc[0] + 3) >> 3;
- dc[0] = 0;
-
- for (i = 0; i < 4; i++) {
- block[i][0][0] = val;
- block[i][1][0] = val;
- block[i][2][0] = val;
- block[i][3][0] = val;
- }
-}
-
-#define MUL_20091(a) ((((a) * 20091) >> 16) + (a))
-#define MUL_35468(a) (((a) * 35468) >> 16)
-
-static void vp8_idct_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
-{
- int i, t0, t1, t2, t3;
- int16_t tmp[16];
-
- for (i = 0; i < 4; i++) {
- t0 = block[0 * 4 + i] + block[2 * 4 + i];
- t1 = block[0 * 4 + i] - block[2 * 4 + i];
- t2 = MUL_35468(block[1 * 4 + i]) - MUL_20091(block[3 * 4 + i]);
- t3 = MUL_20091(block[1 * 4 + i]) + MUL_35468(block[3 * 4 + i]);
- block[0 * 4 + i] = 0;
- block[1 * 4 + i] = 0;
- block[2 * 4 + i] = 0;
- block[3 * 4 + i] = 0;
-
- tmp[i * 4 + 0] = t0 + t3;
- tmp[i * 4 + 1] = t1 + t2;
- tmp[i * 4 + 2] = t1 - t2;
- tmp[i * 4 + 3] = t0 - t3;
- }
-
- for (i = 0; i < 4; i++) {
- t0 = tmp[0 * 4 + i] + tmp[2 * 4 + i];
- t1 = tmp[0 * 4 + i] - tmp[2 * 4 + i];
- t2 = MUL_35468(tmp[1 * 4 + i]) - MUL_20091(tmp[3 * 4 + i]);
- t3 = MUL_20091(tmp[1 * 4 + i]) + MUL_35468(tmp[3 * 4 + i]);
-
- dst[0] = av_clip_uint8(dst[0] + ((t0 + t3 + 4) >> 3));
- dst[1] = av_clip_uint8(dst[1] + ((t1 + t2 + 4) >> 3));
- dst[2] = av_clip_uint8(dst[2] + ((t1 - t2 + 4) >> 3));
- dst[3] = av_clip_uint8(dst[3] + ((t0 - t3 + 4) >> 3));
- dst += stride;
- }
-}
-
-static void vp8_idct_dc_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
-{
- int i, dc = (block[0] + 4) >> 3;
- block[0] = 0;
-
- for (i = 0; i < 4; i++) {
- dst[0] = av_clip_uint8(dst[0] + dc);
- dst[1] = av_clip_uint8(dst[1] + dc);
- dst[2] = av_clip_uint8(dst[2] + dc);
- dst[3] = av_clip_uint8(dst[3] + dc);
- dst += stride;
- }
-}
-
-MK_IDCT_DC_ADD4_C(vp8)
-#endif /* CONFIG_VP8_DECODER */
-
-// because I like only having two parameters to pass functions...
-#define LOAD_PIXELS \
- int av_unused p3 = p[-4 * stride]; \
- int av_unused p2 = p[-3 * stride]; \
- int av_unused p1 = p[-2 * stride]; \
- int av_unused p0 = p[-1 * stride]; \
- int av_unused q0 = p[ 0 * stride]; \
- int av_unused q1 = p[ 1 * stride]; \
- int av_unused q2 = p[ 2 * stride]; \
- int av_unused q3 = p[ 3 * stride];
-
-#define clip_int8(n) (cm[(n) + 0x80] - 0x80)
-
-static av_always_inline void filter_common(uint8_t *p, ptrdiff_t stride,
- int is4tap, int is_vp7)
-{
- LOAD_PIXELS
- int a, f1, f2;
- const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
-
- a = 3 * (q0 - p0);
-
- if (is4tap)
- a += clip_int8(p1 - q1);
-
- a = clip_int8(a);
-
- // We deviate from the spec here with c(a+3) >> 3
- // since that's what libvpx does.
- f1 = FFMIN(a + 4, 127) >> 3;
-
- if (is_vp7)
- f2 = f1 - ((a & 7) == 4);
- else
- f2 = FFMIN(a + 3, 127) >> 3;
-
- // Despite what the spec says, we do need to clamp here to
- // be bitexact with libvpx.
- p[-1 * stride] = cm[p0 + f2];
- p[ 0 * stride] = cm[q0 - f1];
-
- // only used for _inner on blocks without high edge variance
- if (!is4tap) {
- a = (f1 + 1) >> 1;
- p[-2 * stride] = cm[p1 + a];
- p[ 1 * stride] = cm[q1 - a];
- }
-}
-
-static av_always_inline void vp7_filter_common(uint8_t *p, ptrdiff_t stride,
- int is4tap)
-{
- filter_common(p, stride, is4tap, IS_VP7);
-}
-
-static av_always_inline void vp8_filter_common(uint8_t *p, ptrdiff_t stride,
- int is4tap)
-{
- filter_common(p, stride, is4tap, IS_VP8);
-}
-
-static av_always_inline int vp7_simple_limit(uint8_t *p, ptrdiff_t stride,
- int flim)
-{
- LOAD_PIXELS
- return FFABS(p0 - q0) <= flim;
-}
-
-static av_always_inline int vp8_simple_limit(uint8_t *p, ptrdiff_t stride,
- int flim)
-{
- LOAD_PIXELS
- return 2 * FFABS(p0 - q0) + (FFABS(p1 - q1) >> 1) <= flim;
-}
-
-/**
- * E - limit at the macroblock edge
- * I - limit for interior difference
- */
-#define NORMAL_LIMIT(vpn) \
-static av_always_inline int vp ## vpn ## _normal_limit(uint8_t *p, \
- ptrdiff_t stride, \
- int E, int I) \
-{ \
- LOAD_PIXELS \
- return vp ## vpn ## _simple_limit(p, stride, E) && \
- FFABS(p3 - p2) <= I && FFABS(p2 - p1) <= I && \
- FFABS(p1 - p0) <= I && FFABS(q3 - q2) <= I && \
- FFABS(q2 - q1) <= I && FFABS(q1 - q0) <= I; \
-}
-
-NORMAL_LIMIT(7)
-NORMAL_LIMIT(8)
-
-// high edge variance
-static av_always_inline int hev(uint8_t *p, ptrdiff_t stride, int thresh)
-{
- LOAD_PIXELS
- return FFABS(p1 - p0) > thresh || FFABS(q1 - q0) > thresh;
-}
-
-static av_always_inline void filter_mbedge(uint8_t *p, ptrdiff_t stride)
-{
- int a0, a1, a2, w;
- const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
-
- LOAD_PIXELS
-
- w = clip_int8(p1 - q1);
- w = clip_int8(w + 3 * (q0 - p0));
-
- a0 = (27 * w + 63) >> 7;
- a1 = (18 * w + 63) >> 7;
- a2 = (9 * w + 63) >> 7;
-
- p[-3 * stride] = cm[p2 + a2];
- p[-2 * stride] = cm[p1 + a1];
- p[-1 * stride] = cm[p0 + a0];
- p[ 0 * stride] = cm[q0 - a0];
- p[ 1 * stride] = cm[q1 - a1];
- p[ 2 * stride] = cm[q2 - a2];
-}
-
-#define LOOP_FILTER(vpn, dir, size, stridea, strideb, maybe_inline) \
-static maybe_inline \
-void vpn ## _ ## dir ## _loop_filter ## size ## _c(uint8_t *dst, \
- ptrdiff_t stride, \
- int flim_E, int flim_I, \
- int hev_thresh) \
-{ \
- int i; \
- for (i = 0; i < size; i++) \
- if (vpn ## _normal_limit(dst + i * stridea, strideb, \
- flim_E, flim_I)) { \
- if (hev(dst + i * stridea, strideb, hev_thresh)) \
- vpn ## _filter_common(dst + i * stridea, strideb, 1); \
- else \
- filter_mbedge(dst + i * stridea, strideb); \
- } \
-} \
- \
-static maybe_inline \
-void vpn ## _ ## dir ## _loop_filter ## size ## _inner_c(uint8_t *dst, \
- ptrdiff_t stride, \
- int flim_E, \
- int flim_I, \
- int hev_thresh) \
-{ \
- int i; \
- for (i = 0; i < size; i++) \
- if (vpn ## _normal_limit(dst + i * stridea, strideb, \
- flim_E, flim_I)) { \
- int hv = hev(dst + i * stridea, strideb, hev_thresh); \
- if (hv) \
- vpn ## _filter_common(dst + i * stridea, strideb, 1); \
- else \
- vpn ## _filter_common(dst + i * stridea, strideb, 0); \
- } \
-}
-
-#define UV_LOOP_FILTER(vpn, dir, stridea, strideb) \
-LOOP_FILTER(vpn, dir, 8, stridea, strideb, av_always_inline) \
-static void vpn ## _ ## dir ## _loop_filter8uv_c(uint8_t *dstU, \
- uint8_t *dstV, \
- ptrdiff_t stride, int fE, \
- int fI, int hev_thresh) \
-{ \
- vpn ## _ ## dir ## _loop_filter8_c(dstU, stride, fE, fI, hev_thresh); \
- vpn ## _ ## dir ## _loop_filter8_c(dstV, stride, fE, fI, hev_thresh); \
-} \
- \
-static void vpn ## _ ## dir ## _loop_filter8uv_inner_c(uint8_t *dstU, \
- uint8_t *dstV, \
- ptrdiff_t stride, \
- int fE, int fI, \
- int hev_thresh) \
-{ \
- vpn ## _ ## dir ## _loop_filter8_inner_c(dstU, stride, fE, fI, \
- hev_thresh); \
- vpn ## _ ## dir ## _loop_filter8_inner_c(dstV, stride, fE, fI, \
- hev_thresh); \
-}
-
-#define LOOP_FILTER_SIMPLE(vpn) \
-static void vpn ## _v_loop_filter_simple_c(uint8_t *dst, ptrdiff_t stride, \
- int flim) \
-{ \
- int i; \
- for (i = 0; i < 16; i++) \
- if (vpn ## _simple_limit(dst + i, stride, flim)) \
- vpn ## _filter_common(dst + i, stride, 1); \
-} \
- \
-static void vpn ## _h_loop_filter_simple_c(uint8_t *dst, ptrdiff_t stride, \
- int flim) \
-{ \
- int i; \
- for (i = 0; i < 16; i++) \
- if (vpn ## _simple_limit(dst + i * stride, 1, flim)) \
- vpn ## _filter_common(dst + i * stride, 1, 1); \
-}
-
-#define LOOP_FILTERS(vpn) \
- LOOP_FILTER(vpn, v, 16, 1, stride, ) \
- LOOP_FILTER(vpn, h, 16, stride, 1, ) \
- UV_LOOP_FILTER(vpn, v, 1, stride) \
- UV_LOOP_FILTER(vpn, h, stride, 1) \
- LOOP_FILTER_SIMPLE(vpn) \
-
-static const uint8_t subpel_filters[7][6] = {
- { 0, 6, 123, 12, 1, 0 },
- { 2, 11, 108, 36, 8, 1 },
- { 0, 9, 93, 50, 6, 0 },
- { 3, 16, 77, 77, 16, 3 },
- { 0, 6, 50, 93, 9, 0 },
- { 1, 8, 36, 108, 11, 2 },
- { 0, 1, 12, 123, 6, 0 },
-};
-
-#define PUT_PIXELS(WIDTH) \
-static void put_vp8_pixels ## WIDTH ## _c(uint8_t *dst, ptrdiff_t dststride, \
- uint8_t *src, ptrdiff_t srcstride, \
- int h, int x, int y) \
-{ \
- int i; \
- for (i = 0; i < h; i++, dst += dststride, src += srcstride) \
- memcpy(dst, src, WIDTH); \
-}
-
-PUT_PIXELS(16)
-PUT_PIXELS(8)
-PUT_PIXELS(4)
-
-#define FILTER_6TAP(src, F, stride) \
- cm[(F[2] * src[x + 0 * stride] - F[1] * src[x - 1 * stride] + \
- F[0] * src[x - 2 * stride] + F[3] * src[x + 1 * stride] - \
- F[4] * src[x + 2 * stride] + F[5] * src[x + 3 * stride] + 64) >> 7]
-
-#define FILTER_4TAP(src, F, stride) \
- cm[(F[2] * src[x + 0 * stride] - F[1] * src[x - 1 * stride] + \
- F[3] * src[x + 1 * stride] - F[4] * src[x + 2 * stride] + 64) >> 7]
-
-#define VP8_EPEL_H(SIZE, TAPS) \
-static void put_vp8_epel ## SIZE ## _h ## TAPS ## _c(uint8_t *dst, \
- ptrdiff_t dststride, \
- uint8_t *src, \
- ptrdiff_t srcstride, \
- int h, int mx, int my) \
-{ \
- const uint8_t *filter = subpel_filters[mx - 1]; \
- const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; \
- int x, y; \
- for (y = 0; y < h; y++) { \
- for (x = 0; x < SIZE; x++) \
- dst[x] = FILTER_ ## TAPS ## TAP(src, filter, 1); \
- dst += dststride; \
- src += srcstride; \
- } \
-}
-
-#define VP8_EPEL_V(SIZE, TAPS) \
-static void put_vp8_epel ## SIZE ## _v ## TAPS ## _c(uint8_t *dst, \
- ptrdiff_t dststride, \
- uint8_t *src, \
- ptrdiff_t srcstride, \
- int h, int mx, int my) \
-{ \
- const uint8_t *filter = subpel_filters[my - 1]; \
- const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; \
- int x, y; \
- for (y = 0; y < h; y++) { \
- for (x = 0; x < SIZE; x++) \
- dst[x] = FILTER_ ## TAPS ## TAP(src, filter, srcstride); \
- dst += dststride; \
- src += srcstride; \
- } \
-}
-
-#define VP8_EPEL_HV(SIZE, HTAPS, VTAPS) \
-static void \
-put_vp8_epel ## SIZE ## _h ## HTAPS ## v ## VTAPS ## _c(uint8_t *dst, \
- ptrdiff_t dststride, \
- uint8_t *src, \
- ptrdiff_t srcstride, \
- int h, int mx, \
- int my) \
-{ \
- const uint8_t *filter = subpel_filters[mx - 1]; \
- const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; \
- int x, y; \
- uint8_t tmp_array[(2 * SIZE + VTAPS - 1) * SIZE]; \
- uint8_t *tmp = tmp_array; \
- src -= (2 - (VTAPS == 4)) * srcstride; \
- \
- for (y = 0; y < h + VTAPS - 1; y++) { \
- for (x = 0; x < SIZE; x++) \
- tmp[x] = FILTER_ ## HTAPS ## TAP(src, filter, 1); \
- tmp += SIZE; \
- src += srcstride; \
- } \
- tmp = tmp_array + (2 - (VTAPS == 4)) * SIZE; \
- filter = subpel_filters[my - 1]; \
- \
- for (y = 0; y < h; y++) { \
- for (x = 0; x < SIZE; x++) \
- dst[x] = FILTER_ ## VTAPS ## TAP(tmp, filter, SIZE); \
- dst += dststride; \
- tmp += SIZE; \
- } \
-}
-
-VP8_EPEL_H(16, 4)
-VP8_EPEL_H(8, 4)
-VP8_EPEL_H(4, 4)
-VP8_EPEL_H(16, 6)
-VP8_EPEL_H(8, 6)
-VP8_EPEL_H(4, 6)
-VP8_EPEL_V(16, 4)
-VP8_EPEL_V(8, 4)
-VP8_EPEL_V(4, 4)
-VP8_EPEL_V(16, 6)
-VP8_EPEL_V(8, 6)
-VP8_EPEL_V(4, 6)
-
-VP8_EPEL_HV(16, 4, 4)
-VP8_EPEL_HV(8, 4, 4)
-VP8_EPEL_HV(4, 4, 4)
-VP8_EPEL_HV(16, 4, 6)
-VP8_EPEL_HV(8, 4, 6)
-VP8_EPEL_HV(4, 4, 6)
-VP8_EPEL_HV(16, 6, 4)
-VP8_EPEL_HV(8, 6, 4)
-VP8_EPEL_HV(4, 6, 4)
-VP8_EPEL_HV(16, 6, 6)
-VP8_EPEL_HV(8, 6, 6)
-VP8_EPEL_HV(4, 6, 6)
-
-#define VP8_BILINEAR(SIZE) \
-static void put_vp8_bilinear ## SIZE ## _h_c(uint8_t *dst, ptrdiff_t dstride, \
- uint8_t *src, ptrdiff_t sstride, \
- int h, int mx, int my) \
-{ \
- int a = 8 - mx, b = mx; \
- int x, y; \
- for (y = 0; y < h; y++) { \
- for (x = 0; x < SIZE; x++) \
- dst[x] = (a * src[x] + b * src[x + 1] + 4) >> 3; \
- dst += dstride; \
- src += sstride; \
- } \
-} \
- \
-static void put_vp8_bilinear ## SIZE ## _v_c(uint8_t *dst, ptrdiff_t dstride, \
- uint8_t *src, ptrdiff_t sstride, \
- int h, int mx, int my) \
-{ \
- int c = 8 - my, d = my; \
- int x, y; \
- for (y = 0; y < h; y++) { \
- for (x = 0; x < SIZE; x++) \
- dst[x] = (c * src[x] + d * src[x + sstride] + 4) >> 3; \
- dst += dstride; \
- src += sstride; \
- } \
-} \
- \
-static void put_vp8_bilinear ## SIZE ## _hv_c(uint8_t *dst, \
- ptrdiff_t dstride, \
- uint8_t *src, \
- ptrdiff_t sstride, \
- int h, int mx, int my) \
-{ \
- int a = 8 - mx, b = mx; \
- int c = 8 - my, d = my; \
- int x, y; \
- uint8_t tmp_array[(2 * SIZE + 1) * SIZE]; \
- uint8_t *tmp = tmp_array; \
- for (y = 0; y < h + 1; y++) { \
- for (x = 0; x < SIZE; x++) \
- tmp[x] = (a * src[x] + b * src[x + 1] + 4) >> 3; \
- tmp += SIZE; \
- src += sstride; \
- } \
- tmp = tmp_array; \
- for (y = 0; y < h; y++) { \
- for (x = 0; x < SIZE; x++) \
- dst[x] = (c * tmp[x] + d * tmp[x + SIZE] + 4) >> 3; \
- dst += dstride; \
- tmp += SIZE; \
- } \
-}
-
-VP8_BILINEAR(16)
-VP8_BILINEAR(8)
-VP8_BILINEAR(4)
-
-#define VP78_MC_FUNC(IDX, SIZE) \
- dsp->put_vp8_epel_pixels_tab[IDX][0][0] = put_vp8_pixels ## SIZE ## _c; \
- dsp->put_vp8_epel_pixels_tab[IDX][0][1] = put_vp8_epel ## SIZE ## _h4_c; \
- dsp->put_vp8_epel_pixels_tab[IDX][0][2] = put_vp8_epel ## SIZE ## _h6_c; \
- dsp->put_vp8_epel_pixels_tab[IDX][1][0] = put_vp8_epel ## SIZE ## _v4_c; \
- dsp->put_vp8_epel_pixels_tab[IDX][1][1] = put_vp8_epel ## SIZE ## _h4v4_c; \
- dsp->put_vp8_epel_pixels_tab[IDX][1][2] = put_vp8_epel ## SIZE ## _h6v4_c; \
- dsp->put_vp8_epel_pixels_tab[IDX][2][0] = put_vp8_epel ## SIZE ## _v6_c; \
- dsp->put_vp8_epel_pixels_tab[IDX][2][1] = put_vp8_epel ## SIZE ## _h4v6_c; \
- dsp->put_vp8_epel_pixels_tab[IDX][2][2] = put_vp8_epel ## SIZE ## _h6v6_c
-
-#define VP78_BILINEAR_MC_FUNC(IDX, SIZE) \
- dsp->put_vp8_bilinear_pixels_tab[IDX][0][0] = put_vp8_pixels ## SIZE ## _c; \
- dsp->put_vp8_bilinear_pixels_tab[IDX][0][1] = put_vp8_bilinear ## SIZE ## _h_c; \
- dsp->put_vp8_bilinear_pixels_tab[IDX][0][2] = put_vp8_bilinear ## SIZE ## _h_c; \
- dsp->put_vp8_bilinear_pixels_tab[IDX][1][0] = put_vp8_bilinear ## SIZE ## _v_c; \
- dsp->put_vp8_bilinear_pixels_tab[IDX][1][1] = put_vp8_bilinear ## SIZE ## _hv_c; \
- dsp->put_vp8_bilinear_pixels_tab[IDX][1][2] = put_vp8_bilinear ## SIZE ## _hv_c; \
- dsp->put_vp8_bilinear_pixels_tab[IDX][2][0] = put_vp8_bilinear ## SIZE ## _v_c; \
- dsp->put_vp8_bilinear_pixels_tab[IDX][2][1] = put_vp8_bilinear ## SIZE ## _hv_c; \
- dsp->put_vp8_bilinear_pixels_tab[IDX][2][2] = put_vp8_bilinear ## SIZE ## _hv_c
-
-av_cold void ff_vp78dsp_init(VP8DSPContext *dsp)
-{
- VP78_MC_FUNC(0, 16);
- VP78_MC_FUNC(1, 8);
- VP78_MC_FUNC(2, 4);
-
- VP78_BILINEAR_MC_FUNC(0, 16);
- VP78_BILINEAR_MC_FUNC(1, 8);
- VP78_BILINEAR_MC_FUNC(2, 4);
-
- if (ARCH_ARM)
- ff_vp78dsp_init_arm(dsp);
- if (ARCH_PPC)
- ff_vp78dsp_init_ppc(dsp);
- if (ARCH_X86)
- ff_vp78dsp_init_x86(dsp);
-}
-
-#if CONFIG_VP7_DECODER
-LOOP_FILTERS(vp7)
-
-av_cold void ff_vp7dsp_init(VP8DSPContext *dsp)
-{
- dsp->vp8_luma_dc_wht = vp7_luma_dc_wht_c;
- dsp->vp8_luma_dc_wht_dc = vp7_luma_dc_wht_dc_c;
- dsp->vp8_idct_add = vp7_idct_add_c;
- dsp->vp8_idct_dc_add = vp7_idct_dc_add_c;
- dsp->vp8_idct_dc_add4y = vp7_idct_dc_add4y_c;
- dsp->vp8_idct_dc_add4uv = vp7_idct_dc_add4uv_c;
-
- dsp->vp8_v_loop_filter16y = vp7_v_loop_filter16_c;
- dsp->vp8_h_loop_filter16y = vp7_h_loop_filter16_c;
- dsp->vp8_v_loop_filter8uv = vp7_v_loop_filter8uv_c;
- dsp->vp8_h_loop_filter8uv = vp7_h_loop_filter8uv_c;
-
- dsp->vp8_v_loop_filter16y_inner = vp7_v_loop_filter16_inner_c;
- dsp->vp8_h_loop_filter16y_inner = vp7_h_loop_filter16_inner_c;
- dsp->vp8_v_loop_filter8uv_inner = vp7_v_loop_filter8uv_inner_c;
- dsp->vp8_h_loop_filter8uv_inner = vp7_h_loop_filter8uv_inner_c;
-
- dsp->vp8_v_loop_filter_simple = vp7_v_loop_filter_simple_c;
- dsp->vp8_h_loop_filter_simple = vp7_h_loop_filter_simple_c;
-}
-#endif /* CONFIG_VP7_DECODER */
-
-#if CONFIG_VP8_DECODER
-LOOP_FILTERS(vp8)
-
-av_cold void ff_vp8dsp_init(VP8DSPContext *dsp)
-{
- dsp->vp8_luma_dc_wht = vp8_luma_dc_wht_c;
- dsp->vp8_luma_dc_wht_dc = vp8_luma_dc_wht_dc_c;
- dsp->vp8_idct_add = vp8_idct_add_c;
- dsp->vp8_idct_dc_add = vp8_idct_dc_add_c;
- dsp->vp8_idct_dc_add4y = vp8_idct_dc_add4y_c;
- dsp->vp8_idct_dc_add4uv = vp8_idct_dc_add4uv_c;
-
- dsp->vp8_v_loop_filter16y = vp8_v_loop_filter16_c;
- dsp->vp8_h_loop_filter16y = vp8_h_loop_filter16_c;
- dsp->vp8_v_loop_filter8uv = vp8_v_loop_filter8uv_c;
- dsp->vp8_h_loop_filter8uv = vp8_h_loop_filter8uv_c;
-
- dsp->vp8_v_loop_filter16y_inner = vp8_v_loop_filter16_inner_c;
- dsp->vp8_h_loop_filter16y_inner = vp8_h_loop_filter16_inner_c;
- dsp->vp8_v_loop_filter8uv_inner = vp8_v_loop_filter8uv_inner_c;
- dsp->vp8_h_loop_filter8uv_inner = vp8_h_loop_filter8uv_inner_c;
-
- dsp->vp8_v_loop_filter_simple = vp8_v_loop_filter_simple_c;
- dsp->vp8_h_loop_filter_simple = vp8_h_loop_filter_simple_c;
-
- if (ARCH_ARM)
- ff_vp8dsp_init_arm(dsp);
- if (ARCH_X86)
- ff_vp8dsp_init_x86(dsp);
- if (ARCH_MIPS)
- ff_vp8dsp_init_mips(dsp);
-}
-#endif /* CONFIG_VP8_DECODER */
diff --git a/ffmpeg-2-8-11/libavcodec/vp9.c b/ffmpeg-2-8-11/libavcodec/vp9.c
deleted file mode 100644
index cd03c97..0000000
--- a/ffmpeg-2-8-11/libavcodec/vp9.c
+++ /dev/null
@@ -1,4372 +0,0 @@
-/*
- * VP9 compatible video decoder
- *
- * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
- * Copyright (C) 2013 Clément Bœsch <u pkh me>
- *
- * 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 "get_bits.h"
-#include "internal.h"
-#include "thread.h"
-#include "videodsp.h"
-#include "vp56.h"
-#include "vp9.h"
-#include "vp9data.h"
-#include "vp9dsp.h"
-#include "libavutil/avassert.h"
-#include "libavutil/pixdesc.h"
-
-#define VP9_SYNCCODE 0x498342
-
-enum CompPredMode {
- PRED_SINGLEREF,
- PRED_COMPREF,
- PRED_SWITCHABLE,
-};
-
-enum BlockLevel {
- BL_64X64,
- BL_32X32,
- BL_16X16,
- BL_8X8,
-};
-
-enum BlockSize {
- BS_64x64,
- BS_64x32,
- BS_32x64,
- BS_32x32,
- BS_32x16,
- BS_16x32,
- BS_16x16,
- BS_16x8,
- BS_8x16,
- BS_8x8,
- BS_8x4,
- BS_4x8,
- BS_4x4,
- N_BS_SIZES,
-};
-
-struct VP9mvrefPair {
- VP56mv mv[2];
- int8_t ref[2];
-};
-
-typedef struct VP9Frame {
- ThreadFrame tf;
- AVBufferRef *extradata;
- uint8_t *segmentation_map;
- struct VP9mvrefPair *mv;
- int uses_2pass;
-} VP9Frame;
-
-struct VP9Filter {
- uint8_t level[8 * 8];
- uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */]
- [8 /* rows */][4 /* 0=16, 1=8, 2=4, 3=inner4 */];
-};
-
-typedef struct VP9Block {
- uint8_t seg_id, intra, comp, ref[2], mode[4], uvmode, skip;
- enum FilterMode filter;
- VP56mv mv[4 /* b_idx */][2 /* ref */];
- enum BlockSize bs;
- enum TxfmMode tx, uvtx;
- enum BlockLevel bl;
- enum BlockPartition bp;
-} VP9Block;
-
-typedef struct VP9Context {
- VP9DSPContext dsp;
- VideoDSPContext vdsp;
- GetBitContext gb;
- VP56RangeCoder c;
- VP56RangeCoder *c_b;
- unsigned c_b_size;
- VP9Block *b_base, *b;
- int pass;
- int row, row7, col, col7;
- uint8_t *dst[3];
- ptrdiff_t y_stride, uv_stride;
-
- // bitstream header
- uint8_t keyframe, last_keyframe;
- uint8_t last_bpp, bpp, bpp_index, bytesperpixel;
- uint8_t invisible;
- uint8_t use_last_frame_mvs;
- uint8_t errorres;
- uint8_t ss_h, ss_v;
- uint8_t intraonly;
- uint8_t resetctx;
- uint8_t refreshrefmask;
- uint8_t highprecisionmvs;
- enum FilterMode filtermode;
- uint8_t allowcompinter;
- uint8_t fixcompref;
- uint8_t refreshctx;
- uint8_t parallelmode;
- uint8_t framectxid;
- uint8_t refidx[3];
- uint8_t signbias[3];
- uint8_t varcompref[2];
- ThreadFrame refs[8], next_refs[8];
-#define CUR_FRAME 0
-#define REF_FRAME_MVPAIR 1
-#define REF_FRAME_SEGMAP 2
- VP9Frame frames[3];
-
- struct {
- uint8_t level;
- int8_t sharpness;
- uint8_t lim_lut[64];
- uint8_t mblim_lut[64];
- } filter;
- struct {
- uint8_t enabled;
- int8_t mode[2];
- int8_t ref[4];
- } lf_delta;
- uint8_t yac_qi;
- int8_t ydc_qdelta, uvdc_qdelta, uvac_qdelta;
- uint8_t lossless;
-#define MAX_SEGMENT 8
- struct {
- uint8_t enabled;
- uint8_t temporal;
- uint8_t absolute_vals;
- uint8_t update_map;
- uint8_t ignore_refmap;
- struct {
- uint8_t q_enabled;
- uint8_t lf_enabled;
- uint8_t ref_enabled;
- uint8_t skip_enabled;
- uint8_t ref_val;
- int16_t q_val;
- int8_t lf_val;
- int16_t qmul[2][2];
- uint8_t lflvl[4][2];
- } feat[MAX_SEGMENT];
- } segmentation;
- struct {
- unsigned log2_tile_cols, log2_tile_rows;
- unsigned tile_cols, tile_rows;
- unsigned tile_row_start, tile_row_end, tile_col_start, tile_col_end;
- } tiling;
- unsigned sb_cols, sb_rows, rows, cols;
- struct {
- prob_context p;
- uint8_t coef[4][2][2][6][6][3];
- } prob_ctx[4];
- struct {
- prob_context p;
- uint8_t coef[4][2][2][6][6][11];
- uint8_t seg[7];
- uint8_t segpred[3];
- } prob;
- struct {
- unsigned y_mode[4][10];
- unsigned uv_mode[10][10];
- unsigned filter[4][3];
- unsigned mv_mode[7][4];
- unsigned intra[4][2];
- unsigned comp[5][2];
- unsigned single_ref[5][2][2];
- unsigned comp_ref[5][2];
- unsigned tx32p[2][4];
- unsigned tx16p[2][3];
- unsigned tx8p[2][2];
- unsigned skip[3][2];
- unsigned mv_joint[4];
- struct {
- unsigned sign[2];
- unsigned classes[11];
- unsigned class0[2];
- unsigned bits[10][2];
- unsigned class0_fp[2][4];
- unsigned fp[4];
- unsigned class0_hp[2];
- unsigned hp[2];
- } mv_comp[2];
- unsigned partition[4][4][4];
- unsigned coef[4][2][2][6][6][3];
- unsigned eob[4][2][2][6][6][2];
- } counts;
- enum TxfmMode txfmmode;
- enum CompPredMode comppredmode;
-
- // contextual (left/above) cache
- DECLARE_ALIGNED(16, uint8_t, left_y_nnz_ctx)[16];
- DECLARE_ALIGNED(16, uint8_t, left_mode_ctx)[16];
- DECLARE_ALIGNED(16, VP56mv, left_mv_ctx)[16][2];
- DECLARE_ALIGNED(16, uint8_t, left_uv_nnz_ctx)[2][16];
- DECLARE_ALIGNED(8, uint8_t, left_partition_ctx)[8];
- DECLARE_ALIGNED(8, uint8_t, left_skip_ctx)[8];
- DECLARE_ALIGNED(8, uint8_t, left_txfm_ctx)[8];
- DECLARE_ALIGNED(8, uint8_t, left_segpred_ctx)[8];
- DECLARE_ALIGNED(8, uint8_t, left_intra_ctx)[8];
- DECLARE_ALIGNED(8, uint8_t, left_comp_ctx)[8];
- DECLARE_ALIGNED(8, uint8_t, left_ref_ctx)[8];
- DECLARE_ALIGNED(8, uint8_t, left_filter_ctx)[8];
- uint8_t *above_partition_ctx;
- uint8_t *above_mode_ctx;
- // FIXME maybe merge some of the below in a flags field?
- uint8_t *above_y_nnz_ctx;
- uint8_t *above_uv_nnz_ctx[2];
- uint8_t *above_skip_ctx; // 1bit
- uint8_t *above_txfm_ctx; // 2bit
- uint8_t *above_segpred_ctx; // 1bit
- uint8_t *above_intra_ctx; // 1bit
- uint8_t *above_comp_ctx; // 1bit
- uint8_t *above_ref_ctx; // 2bit
- uint8_t *above_filter_ctx;
- VP56mv (*above_mv_ctx)[2];
-
- // whole-frame cache
- uint8_t *intra_pred_data[3];
- struct VP9Filter *lflvl;
- DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2];
-
- // block reconstruction intermediates
- int block_alloc_using_2pass;
- int16_t *block_base, *block, *uvblock_base[2], *uvblock[2];
- uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2];
- struct { int x, y; } min_mv, max_mv;
- DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64 * 2];
- DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][64 * 64 * 2];
- uint16_t mvscale[3][2];
- uint8_t mvstep[3][2];
-} VP9Context;
-
-static const uint8_t bwh_tab[2][N_BS_SIZES][2] = {
- {
- { 16, 16 }, { 16, 8 }, { 8, 16 }, { 8, 8 }, { 8, 4 }, { 4, 8 },
- { 4, 4 }, { 4, 2 }, { 2, 4 }, { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 },
- }, {
- { 8, 8 }, { 8, 4 }, { 4, 8 }, { 4, 4 }, { 4, 2 }, { 2, 4 },
- { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 },
- }
-};
-
-static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f)
-{
- VP9Context *s = ctx->priv_data;
- int ret, sz;
-
- if ((ret = ff_thread_get_buffer(ctx, &f->tf, AV_GET_BUFFER_FLAG_REF)) < 0)
- return ret;
- sz = 64 * s->sb_cols * s->sb_rows;
- if (!(f->extradata = av_buffer_allocz(sz * (1 + sizeof(struct VP9mvrefPair))))) {
- ff_thread_release_buffer(ctx, &f->tf);
- return AVERROR(ENOMEM);
- }
-
- f->segmentation_map = f->extradata->data;
- f->mv = (struct VP9mvrefPair *) (f->extradata->data + sz);
-
- return 0;
-}
-
-static void vp9_unref_frame(AVCodecContext *ctx, VP9Frame *f)
-{
- ff_thread_release_buffer(ctx, &f->tf);
- av_buffer_unref(&f->extradata);
- f->segmentation_map = NULL;
-}
-
-static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame *src)
-{
- int res;
-
- if ((res = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0) {
- return res;
- } else if (!(dst->extradata = av_buffer_ref(src->extradata))) {
- vp9_unref_frame(ctx, dst);
- return AVERROR(ENOMEM);
- }
-
- dst->segmentation_map = src->segmentation_map;
- dst->mv = src->mv;
- dst->uses_2pass = src->uses_2pass;
-
- return 0;
-}
-
-static int update_size(AVCodecContext *ctx, int w, int h, enum AVPixelFormat fmt)
-{
- VP9Context *s = ctx->priv_data;
- uint8_t *p;
- int bytesperpixel = s->bytesperpixel;
-
- av_assert0(w > 0 && h > 0);
-
- if (s->intra_pred_data[0] && w == ctx->width && h == ctx->height && ctx->pix_fmt == fmt)
- return 0;
-
- ctx->width = w;
- ctx->height = h;
- ctx->pix_fmt = fmt;
- s->sb_cols = (w + 63) >> 6;
- s->sb_rows = (h + 63) >> 6;
- s->cols = (w + 7) >> 3;
- s->rows = (h + 7) >> 3;
-
-#define assign(var, type, n) var = (type) p; p += s->sb_cols * (n) * sizeof(*var)
- av_freep(&s->intra_pred_data[0]);
- // FIXME we slightly over-allocate here for subsampled chroma, but a little
- // bit of padding shouldn't affect performance...
- p = av_malloc(s->sb_cols * (128 + 192 * bytesperpixel +
- sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx)));
- if (!p)
- return AVERROR(ENOMEM);
- assign(s->intra_pred_data[0], uint8_t *, 64 * bytesperpixel);
- assign(s->intra_pred_data[1], uint8_t *, 64 * bytesperpixel);
- assign(s->intra_pred_data[2], uint8_t *, 64 * bytesperpixel);
- assign(s->above_y_nnz_ctx, uint8_t *, 16);
- assign(s->above_mode_ctx, uint8_t *, 16);
- assign(s->above_mv_ctx, VP56mv(*)[2], 16);
- assign(s->above_uv_nnz_ctx[0], uint8_t *, 16);
- assign(s->above_uv_nnz_ctx[1], uint8_t *, 16);
- assign(s->above_partition_ctx, uint8_t *, 8);
- assign(s->above_skip_ctx, uint8_t *, 8);
- assign(s->above_txfm_ctx, uint8_t *, 8);
- assign(s->above_segpred_ctx, uint8_t *, 8);
- assign(s->above_intra_ctx, uint8_t *, 8);
- assign(s->above_comp_ctx, uint8_t *, 8);
- assign(s->above_ref_ctx, uint8_t *, 8);
- assign(s->above_filter_ctx, uint8_t *, 8);
- assign(s->lflvl, struct VP9Filter *, 1);
-#undef assign
-
- // these will be re-allocated a little later
- av_freep(&s->b_base);
- av_freep(&s->block_base);
-
- if (s->bpp != s->last_bpp) {
- ff_vp9dsp_init(&s->dsp, s->bpp);
- ff_videodsp_init(&s->vdsp, s->bpp);
- s->last_bpp = s->bpp;
- }
-
- return 0;
-}
-
-static int update_block_buffers(AVCodecContext *ctx)
-{
- VP9Context *s = ctx->priv_data;
- int chroma_blocks, chroma_eobs, bytesperpixel = s->bytesperpixel;
-
- if (s->b_base && s->block_base && s->block_alloc_using_2pass == s->frames[CUR_FRAME].uses_2pass)
- return 0;
-
- av_free(s->b_base);
- av_free(s->block_base);
- chroma_blocks = 64 * 64 >> (s->ss_h + s->ss_v);
- chroma_eobs = 16 * 16 >> (s->ss_h + s->ss_v);
- if (s->frames[CUR_FRAME].uses_2pass) {
- int sbs = s->sb_cols * s->sb_rows;
-
- s->b_base = av_malloc_array(s->cols * s->rows, sizeof(VP9Block));
- s->block_base = av_mallocz(((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) +
- 16 * 16 + 2 * chroma_eobs) * sbs);
- if (!s->b_base || !s->block_base)
- return AVERROR(ENOMEM);
- s->uvblock_base[0] = s->block_base + sbs * 64 * 64 * bytesperpixel;
- s->uvblock_base[1] = s->uvblock_base[0] + sbs * chroma_blocks * bytesperpixel;
- s->eob_base = (uint8_t *) (s->uvblock_base[1] + sbs * chroma_blocks * bytesperpixel);
- s->uveob_base[0] = s->eob_base + 16 * 16 * sbs;
- s->uveob_base[1] = s->uveob_base[0] + chroma_eobs * sbs;
- } else {
- s->b_base = av_malloc(sizeof(VP9Block));
- s->block_base = av_mallocz((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) +
- 16 * 16 + 2 * chroma_eobs);
- if (!s->b_base || !s->block_base)
- return AVERROR(ENOMEM);
- s->uvblock_base[0] = s->block_base + 64 * 64 * bytesperpixel;
- s->uvblock_base[1] = s->uvblock_base[0] + chroma_blocks * bytesperpixel;
- s->eob_base = (uint8_t *) (s->uvblock_base[1] + chroma_blocks * bytesperpixel);
- s->uveob_base[0] = s->eob_base + 16 * 16;
- s->uveob_base[1] = s->uveob_base[0] + chroma_eobs;
- }
- s->block_alloc_using_2pass = s->frames[CUR_FRAME].uses_2pass;
-
- return 0;
-}
-
-// for some reason the sign bit is at the end, not the start, of a bit sequence
-static av_always_inline int get_sbits_inv(GetBitContext *gb, int n)
-{
- int v = get_bits(gb, n);
- return get_bits1(gb) ? -v : v;
-}
-
-static av_always_inline int inv_recenter_nonneg(int v, int m)
-{
- return v > 2 * m ? v : v & 1 ? m - ((v + 1) >> 1) : m + (v >> 1);
-}
-
-// differential forward probability updates
-static int update_prob(VP56RangeCoder *c, int p)
-{
- static const int inv_map_table[255] = {
- 7, 20, 33, 46, 59, 72, 85, 98, 111, 124, 137, 150, 163, 176,
- 189, 202, 215, 228, 241, 254, 1, 2, 3, 4, 5, 6, 8, 9,
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24,
- 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39,
- 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
- 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
- 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 99, 100,
- 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 112, 113, 114, 115,
- 116, 117, 118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 130,
- 131, 132, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143, 144, 145,
- 146, 147, 148, 149, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160,
- 161, 162, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
- 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 190, 191,
- 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 203, 204, 205, 206,
- 207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219, 220, 221,
- 222, 223, 224, 225, 226, 227, 229, 230, 231, 232, 233, 234, 235, 236,
- 237, 238, 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
- 252, 253, 253,
- };
- int d;
-
- /* This code is trying to do a differential probability update. For a
- * current probability A in the range [1, 255], the difference to a new
- * probability of any value can be expressed differentially as 1-A,255-A
- * where some part of this (absolute range) exists both in positive as
- * well as the negative part, whereas another part only exists in one
- * half. We're trying to code this shared part differentially, i.e.
- * times two where the value of the lowest bit specifies the sign, and
- * the single part is then coded on top of this. This absolute difference
- * then again has a value of [0,254], but a bigger value in this range
- * indicates that we're further away from the original value A, so we
- * can code this as a VLC code, since higher values are increasingly
- * unlikely. The first 20 values in inv_map_table[] allow 'cheap, rough'
- * updates vs. the 'fine, exact' updates further down the range, which
- * adds one extra dimension to this differential update model. */
-
- if (!vp8_rac_get(c)) {
- d = vp8_rac_get_uint(c, 4) + 0;
- } else if (!vp8_rac_get(c)) {
- d = vp8_rac_get_uint(c, 4) + 16;
- } else if (!vp8_rac_get(c)) {
- d = vp8_rac_get_uint(c, 5) + 32;
- } else {
- d = vp8_rac_get_uint(c, 7);
- if (d >= 65)
- d = (d << 1) - 65 + vp8_rac_get(c);
- d += 64;
- av_assert2(d < FF_ARRAY_ELEMS(inv_map_table));
- }
-
- return p <= 128 ? 1 + inv_recenter_nonneg(inv_map_table[d], p - 1) :
- 255 - inv_recenter_nonneg(inv_map_table[d], 255 - p);
-}
-
-static enum AVPixelFormat read_colorspace_details(AVCodecContext *ctx)
-{
- static const enum AVColorSpace colorspaces[8] = {
- AVCOL_SPC_UNSPECIFIED, AVCOL_SPC_BT470BG, AVCOL_SPC_BT709, AVCOL_SPC_SMPTE170M,
- AVCOL_SPC_SMPTE240M, AVCOL_SPC_BT2020_NCL, AVCOL_SPC_RESERVED, AVCOL_SPC_RGB,
- };
- VP9Context *s = ctx->priv_data;
- enum AVPixelFormat res;
- int bits = ctx->profile <= 1 ? 0 : 1 + get_bits1(&s->gb); // 0:8, 1:10, 2:12
-
- s->bpp_index = bits;
- s->bpp = 8 + bits * 2;
- s->bytesperpixel = (7 + s->bpp) >> 3;
- ctx->colorspace = colorspaces[get_bits(&s->gb, 3)];
- if (ctx->colorspace == AVCOL_SPC_RGB) { // RGB = profile 1
- static const enum AVPixelFormat pix_fmt_rgb[3] = {
- AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12
- };
- if (ctx->profile & 1) {
- s->ss_h = s->ss_v = 0;
- res = pix_fmt_rgb[bits];
- ctx->color_range = AVCOL_RANGE_JPEG;
- if (get_bits1(&s->gb)) {
- av_log(ctx, AV_LOG_ERROR, "Reserved bit set in RGB\n");
- return AVERROR_INVALIDDATA;
- }
- } else {
- av_log(ctx, AV_LOG_ERROR, "RGB not supported in profile %d\n",
- ctx->profile);
- return AVERROR_INVALIDDATA;
- }
- } else {
- static const enum AVPixelFormat pix_fmt_for_ss[3][2 /* v */][2 /* h */] = {
- { { AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P },
- { AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV420P } },
- { { AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV422P10 },
- { AV_PIX_FMT_YUV440P10, AV_PIX_FMT_YUV420P10 } },
- { { AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12 },
- { AV_PIX_FMT_YUV440P12, AV_PIX_FMT_YUV420P12 } }
- };
- ctx->color_range = get_bits1(&s->gb) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
- if (ctx->profile & 1) {
- s->ss_h = get_bits1(&s->gb);
- s->ss_v = get_bits1(&s->gb);
- if ((res = pix_fmt_for_ss[bits][s->ss_v][s->ss_h]) == AV_PIX_FMT_YUV420P) {
- av_log(ctx, AV_LOG_ERROR, "YUV 4:2:0 not supported in profile %d\n",
- ctx->profile);
- return AVERROR_INVALIDDATA;
- } else if (get_bits1(&s->gb)) {
- av_log(ctx, AV_LOG_ERROR, "Profile %d color details reserved bit set\n",
- ctx->profile);
- return AVERROR_INVALIDDATA;
- }
- } else {
- s->ss_h = s->ss_v = 1;
- res = pix_fmt_for_ss[bits][1][1];
- }
- }
-
- return res;
-}
-
-static int decode_frame_header(AVCodecContext *ctx,
- const uint8_t *data, int size, int *ref)
-{
- VP9Context *s = ctx->priv_data;
- int c, i, j, k, l, m, n, w, h, max, size2, res, sharp;
- enum AVPixelFormat fmt = ctx->pix_fmt;
- int last_invisible;
- const uint8_t *data2;
-
- /* general header */
- if ((res = init_get_bits8(&s->gb, data, size)) < 0) {
- av_log(ctx, AV_LOG_ERROR, "Failed to initialize bitstream reader\n");
- return res;
- }
- if (get_bits(&s->gb, 2) != 0x2) { // frame marker
- av_log(ctx, AV_LOG_ERROR, "Invalid frame marker\n");
- return AVERROR_INVALIDDATA;
- }
- ctx->profile = get_bits1(&s->gb);
- ctx->profile |= get_bits1(&s->gb) << 1;
- if (ctx->profile == 3) ctx->profile += get_bits1(&s->gb);
- if (ctx->profile > 3) {
- av_log(ctx, AV_LOG_ERROR, "Profile %d is not yet supported\n", ctx->profile);
- return AVERROR_INVALIDDATA;
- }
- if (get_bits1(&s->gb)) {
- *ref = get_bits(&s->gb, 3);
- return 0;
- }
- s->last_keyframe = s->keyframe;
- s->keyframe = !get_bits1(&s->gb);
- last_invisible = s->invisible;
- s->invisible = !get_bits1(&s->gb);
- s->errorres = get_bits1(&s->gb);
- s->use_last_frame_mvs = !s->errorres && !last_invisible;
- if (s->keyframe) {
- if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode
- av_log(ctx, AV_LOG_ERROR, "Invalid sync code\n");
- return AVERROR_INVALIDDATA;
- }
- if ((fmt = read_colorspace_details(ctx)) < 0)
- return fmt;
- // for profile 1, here follows the subsampling bits
- s->refreshrefmask = 0xff;
- w = get_bits(&s->gb, 16) + 1;
- h = get_bits(&s->gb, 16) + 1;
- if (get_bits1(&s->gb)) // display size
- skip_bits(&s->gb, 32);
- } else {
- s->intraonly = s->invisible ? get_bits1(&s->gb) : 0;
- s->resetctx = s->errorres ? 0 : get_bits(&s->gb, 2);
- if (s->intraonly) {
- if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode
- av_log(ctx, AV_LOG_ERROR, "Invalid sync code\n");
- return AVERROR_INVALIDDATA;
- }
- if (ctx->profile >= 1) {
- if ((fmt = read_colorspace_details(ctx)) < 0)
- return fmt;
- } else {
- s->ss_h = s->ss_v = 1;
- s->bpp = 8;
- s->bpp_index = 0;
- s->bytesperpixel = 1;
- fmt = AV_PIX_FMT_YUV420P;
- ctx->colorspace = AVCOL_SPC_BT470BG;
- ctx->color_range = AVCOL_RANGE_JPEG;
- }
- s->refreshrefmask = get_bits(&s->gb, 8);
- w = get_bits(&s->gb, 16) + 1;
- h = get_bits(&s->gb, 16) + 1;
- if (get_bits1(&s->gb)) // display size
- skip_bits(&s->gb, 32);
- } else {
- s->refreshrefmask = get_bits(&s->gb, 8);
- s->refidx[0] = get_bits(&s->gb, 3);
- s->signbias[0] = get_bits1(&s->gb) && !s->errorres;
- s->refidx[1] = get_bits(&s->gb, 3);
- s->signbias[1] = get_bits1(&s->gb) && !s->errorres;
- s->refidx[2] = get_bits(&s->gb, 3);
- s->signbias[2] = get_bits1(&s->gb) && !s->errorres;
- if (!s->refs[s->refidx[0]].f->data[0] ||
- !s->refs[s->refidx[1]].f->data[0] ||
- !s->refs[s->refidx[2]].f->data[0]) {
- av_log(ctx, AV_LOG_ERROR, "Not all references are available\n");
- return AVERROR_INVALIDDATA;
- }
- if (get_bits1(&s->gb)) {
- w = s->refs[s->refidx[0]].f->width;
- h = s->refs[s->refidx[0]].f->height;
- } else if (get_bits1(&s->gb)) {
- w = s->refs[s->refidx[1]].f->width;
- h = s->refs[s->refidx[1]].f->height;
- } else if (get_bits1(&s->gb)) {
- w = s->refs[s->refidx[2]].f->width;
- h = s->refs[s->refidx[2]].f->height;
- } else {
- w = get_bits(&s->gb, 16) + 1;
- h = get_bits(&s->gb, 16) + 1;
- }
- // Note that in this code, "CUR_FRAME" is actually before we
- // have formally allocated a frame, and thus actually represents
- // the _last_ frame
- s->use_last_frame_mvs &= s->frames[CUR_FRAME].tf.f->width == w &&
- s->frames[CUR_FRAME].tf.f->height == h;
- if (get_bits1(&s->gb)) // display size
- skip_bits(&s->gb, 32);
- s->highprecisionmvs = get_bits1(&s->gb);
- s->filtermode = get_bits1(&s->gb) ? FILTER_SWITCHABLE :
- get_bits(&s->gb, 2);
- s->allowcompinter = (s->signbias[0] != s->signbias[1] ||
- s->signbias[0] != s->signbias[2]);
- if (s->allowcompinter) {
- if (s->signbias[0] == s->signbias[1]) {
- s->fixcompref = 2;
- s->varcompref[0] = 0;
- s->varcompref[1] = 1;
- } else if (s->signbias[0] == s->signbias[2]) {
- s->fixcompref = 1;
- s->varcompref[0] = 0;
- s->varcompref[1] = 2;
- } else {
- s->fixcompref = 0;
- s->varcompref[0] = 1;
- s->varcompref[1] = 2;
- }
- }
-
- for (i = 0; i < 3; i++) {
- AVFrame *ref = s->refs[s->refidx[i]].f;
- int refw = ref->width, refh = ref->height;
-
- if (ref->format != fmt) {
- av_log(ctx, AV_LOG_ERROR,
- "Ref pixfmt (%s) did not match current frame (%s)",
- av_get_pix_fmt_name(ref->format),
- av_get_pix_fmt_name(fmt));
- return AVERROR_INVALIDDATA;
- } else if (refw == w && refh == h) {
- s->mvscale[i][0] = s->mvscale[i][1] = 0;
- } else {
- if (w * 2 < refw || h * 2 < refh || w > 16 * refw || h > 16 * refh) {
- av_log(ctx, AV_LOG_ERROR,
- "Invalid ref frame dimensions %dx%d for frame size %dx%d\n",
- refw, refh, w, h);
- return AVERROR_INVALIDDATA;
- }
- s->mvscale[i][0] = (refw << 14) / w;
- s->mvscale[i][1] = (refh << 14) / h;
- s->mvstep[i][0] = 16 * s->mvscale[i][0] >> 14;
- s->mvstep[i][1] = 16 * s->mvscale[i][1] >> 14;
- }
- }
- }
- }
- s->refreshctx = s->errorres ? 0 : get_bits1(&s->gb);
- s->parallelmode = s->errorres ? 1 : get_bits1(&s->gb);
- s->framectxid = c = get_bits(&s->gb, 2);
-
- /* loopfilter header data */
- if (s->keyframe || s->errorres || s->intraonly) {
- // reset loopfilter defaults
- s->lf_delta.ref[0] = 1;
- s->lf_delta.ref[1] = 0;
- s->lf_delta.ref[2] = -1;
- s->lf_delta.ref[3] = -1;
- s->lf_delta.mode[0] = 0;
- s->lf_delta.mode[1] = 0;
- memset(s->segmentation.feat, 0, sizeof(s->segmentation.feat));
- }
- s->filter.level = get_bits(&s->gb, 6);
- sharp = get_bits(&s->gb, 3);
- // if sharpness changed, reinit lim/mblim LUTs. if it didn't change, keep
- // the old cache values since they are still valid
- if (s->filter.sharpness != sharp)
- memset(s->filter.lim_lut, 0, sizeof(s->filter.lim_lut));
- s->filter.sharpness = sharp;
- if ((s->lf_delta.enabled = get_bits1(&s->gb))) {
- if (get_bits1(&s->gb)) {
- for (i = 0; i < 4; i++)
- if (get_bits1(&s->gb))
- s->lf_delta.ref[i] = get_sbits_inv(&s->gb, 6);
- for (i = 0; i < 2; i++)
- if (get_bits1(&s->gb))
- s->lf_delta.mode[i] = get_sbits_inv(&s->gb, 6);
- }
- }
-
- /* quantization header data */
- s->yac_qi = get_bits(&s->gb, 8);
- s->ydc_qdelta = get_bits1(&s->gb) ? get_sbits_inv(&s->gb, 4) : 0;
- s->uvdc_qdelta = get_bits1(&s->gb) ? get_sbits_inv(&s->gb, 4) : 0;
- s->uvac_qdelta = get_bits1(&s->gb) ? get_sbits_inv(&s->gb, 4) : 0;
- s->lossless = s->yac_qi == 0 && s->ydc_qdelta == 0 &&
- s->uvdc_qdelta == 0 && s->uvac_qdelta == 0;
- if (s->lossless)
- ctx->properties |= FF_CODEC_PROPERTY_LOSSLESS;
-
- /* segmentation header info */
- s->segmentation.ignore_refmap = 0;
- if ((s->segmentation.enabled = get_bits1(&s->gb))) {
- if ((s->segmentation.update_map = get_bits1(&s->gb))) {
- for (i = 0; i < 7; i++)
- s->prob.seg[i] = get_bits1(&s->gb) ?
- get_bits(&s->gb, 8) : 255;
- if ((s->segmentation.temporal = get_bits1(&s->gb))) {
- for (i = 0; i < 3; i++)
- s->prob.segpred[i] = get_bits1(&s->gb) ?
- get_bits(&s->gb, 8) : 255;
- }
- }
- if ((!s->segmentation.update_map || s->segmentation.temporal) &&
- (w != s->frames[CUR_FRAME].tf.f->width ||
- h != s->frames[CUR_FRAME].tf.f->height)) {
- av_log(ctx, AV_LOG_WARNING,
- "Reference segmap (temp=%d,update=%d) enabled on size-change!\n",
- s->segmentation.temporal, s->segmentation.update_map);
- s->segmentation.ignore_refmap = 1;
- //return AVERROR_INVALIDDATA;
- }
-
- if (get_bits1(&s->gb)) {
- s->segmentation.absolute_vals = get_bits1(&s->gb);
- for (i = 0; i < 8; i++) {
- if ((s->segmentation.feat[i].q_enabled = get_bits1(&s->gb)))
- s->segmentation.feat[i].q_val = get_sbits_inv(&s->gb, 8);
- if ((s->segmentation.feat[i].lf_enabled = get_bits1(&s->gb)))
- s->segmentation.feat[i].lf_val = get_sbits_inv(&s->gb, 6);
- if ((s->segmentation.feat[i].ref_enabled = get_bits1(&s->gb)))
- s->segmentation.feat[i].ref_val = get_bits(&s->gb, 2);
- s->segmentation.feat[i].skip_enabled = get_bits1(&s->gb);
- }
- }
- }
-
- // set qmul[] based on Y/UV, AC/DC and segmentation Q idx deltas
- for (i = 0; i < (s->segmentation.enabled ? 8 : 1); i++) {
- int qyac, qydc, quvac, quvdc, lflvl, sh;
-
- if (s->segmentation.enabled && s->segmentation.feat[i].q_enabled) {
- if (s->segmentation.absolute_vals)
- qyac = av_clip_uintp2(s->segmentation.feat[i].q_val, 8);
- else
- qyac = av_clip_uintp2(s->yac_qi + s->segmentation.feat[i].q_val, 8);
- } else {
- qyac = s->yac_qi;
- }
- qydc = av_clip_uintp2(qyac + s->ydc_qdelta, 8);
- quvdc = av_clip_uintp2(qyac + s->uvdc_qdelta, 8);
- quvac = av_clip_uintp2(qyac + s->uvac_qdelta, 8);
- qyac = av_clip_uintp2(qyac, 8);
-
- s->segmentation.feat[i].qmul[0][0] = vp9_dc_qlookup[s->bpp_index][qydc];
- s->segmentation.feat[i].qmul[0][1] = vp9_ac_qlookup[s->bpp_index][qyac];
- s->segmentation.feat[i].qmul[1][0] = vp9_dc_qlookup[s->bpp_index][quvdc];
- s->segmentation.feat[i].qmul[1][1] = vp9_ac_qlookup[s->bpp_index][quvac];
-
- sh = s->filter.level >= 32;
- if (s->segmentation.enabled && s->segmentation.feat[i].lf_enabled) {
- if (s->segmentation.absolute_vals)
- lflvl = av_clip_uintp2(s->segmentation.feat[i].lf_val, 6);
- else
- lflvl = av_clip_uintp2(s->filter.level + s->segmentation.feat[i].lf_val, 6);
- } else {
- lflvl = s->filter.level;
- }
- if (s->lf_delta.enabled) {
- s->segmentation.feat[i].lflvl[0][0] =
- s->segmentation.feat[i].lflvl[0][1] =
- av_clip_uintp2(lflvl + (s->lf_delta.ref[0] << sh), 6);
- for (j = 1; j < 4; j++) {
- s->segmentation.feat[i].lflvl[j][0] =
- av_clip_uintp2(lflvl + ((s->lf_delta.ref[j] +
- s->lf_delta.mode[0]) * (1 << sh)), 6);
- s->segmentation.feat[i].lflvl[j][1] =
- av_clip_uintp2(lflvl + ((s->lf_delta.ref[j] +
- s->lf_delta.mode[1]) * (1 << sh)), 6);
- }
- } else {
- memset(s->segmentation.feat[i].lflvl, lflvl,
- sizeof(s->segmentation.feat[i].lflvl));
- }
- }
-
- /* tiling info */
- if ((res = update_size(ctx, w, h, fmt)) < 0) {
- av_log(ctx, AV_LOG_ERROR, "Failed to initialize decoder for %dx%d @ %d\n", w, h, fmt);
- return res;
- }
- for (s->tiling.log2_tile_cols = 0;
- (s->sb_cols >> s->tiling.log2_tile_cols) > 64;
- s->tiling.log2_tile_cols++) ;
- for (max = 0; (s->sb_cols >> max) >= 4; max++) ;
- max = FFMAX(0, max - 1);
- while (max > s->tiling.log2_tile_cols) {
- if (get_bits1(&s->gb))
- s->tiling.log2_tile_cols++;
- else
- break;
- }
- s->tiling.log2_tile_rows = decode012(&s->gb);
- s->tiling.tile_rows = 1 << s->tiling.log2_tile_rows;
- if (s->tiling.tile_cols != (1 << s->tiling.log2_tile_cols)) {
- s->tiling.tile_cols = 1 << s->tiling.log2_tile_cols;
- s->c_b = av_fast_realloc(s->c_b, &s->c_b_size,
- sizeof(VP56RangeCoder) * s->tiling.tile_cols);
- if (!s->c_b) {
- av_log(ctx, AV_LOG_ERROR, "Ran out of memory during range coder init\n");
- return AVERROR(ENOMEM);
- }
- }
-
- if (s->keyframe || s->errorres || (s->intraonly && s->resetctx == 3)) {
- s->prob_ctx[0].p = s->prob_ctx[1].p = s->prob_ctx[2].p =
- s->prob_ctx[3].p = vp9_default_probs;
- memcpy(s->prob_ctx[0].coef, vp9_default_coef_probs,
- sizeof(vp9_default_coef_probs));
- memcpy(s->prob_ctx[1].coef, vp9_default_coef_probs,
- sizeof(vp9_default_coef_probs));
- memcpy(s->prob_ctx[2].coef, vp9_default_coef_probs,
- sizeof(vp9_default_coef_probs));
- memcpy(s->prob_ctx[3].coef, vp9_default_coef_probs,
- sizeof(vp9_default_coef_probs));
- } else if (s->intraonly && s->resetctx == 2) {
- s->prob_ctx[c].p = vp9_default_probs;
- memcpy(s->prob_ctx[c].coef, vp9_default_coef_probs,
- sizeof(vp9_default_coef_probs));
- }
-
- // next 16 bits is size of the rest of the header (arith-coded)
- size2 = get_bits(&s->gb, 16);
- data2 = align_get_bits(&s->gb);
- if (size2 > size - (data2 - data)) {
- av_log(ctx, AV_LOG_ERROR, "Invalid compressed header size\n");
- return AVERROR_INVALIDDATA;
- }
- ff_vp56_init_range_decoder(&s->c, data2, size2);
- if (vp56_rac_get_prob_branchy(&s->c, 128)) { // marker bit
- av_log(ctx, AV_LOG_ERROR, "Marker bit was set\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (s->keyframe || s->intraonly) {
- memset(s->counts.coef, 0, sizeof(s->counts.coef));
- memset(s->counts.eob, 0, sizeof(s->counts.eob));
- } else {
- memset(&s->counts, 0, sizeof(s->counts));
- }
- // FIXME is it faster to not copy here, but do it down in the fw updates
- // as explicit copies if the fw update is missing (and skip the copy upon
- // fw update)?
- s->prob.p = s->prob_ctx[c].p;
-
- // txfm updates
- if (s->lossless) {
- s->txfmmode = TX_4X4;
- } else {
- s->txfmmode = vp8_rac_get_uint(&s->c, 2);
- if (s->txfmmode == 3)
- s->txfmmode += vp8_rac_get(&s->c);
-
- if (s->txfmmode == TX_SWITCHABLE) {
- for (i = 0; i < 2; i++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.tx8p[i] = update_prob(&s->c, s->prob.p.tx8p[i]);
- for (i = 0; i < 2; i++)
- for (j = 0; j < 2; j++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.tx16p[i][j] =
- update_prob(&s->c, s->prob.p.tx16p[i][j]);
- for (i = 0; i < 2; i++)
- for (j = 0; j < 3; j++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.tx32p[i][j] =
- update_prob(&s->c, s->prob.p.tx32p[i][j]);
- }
- }
-
- // coef updates
- for (i = 0; i < 4; i++) {
- uint8_t (*ref)[2][6][6][3] = s->prob_ctx[c].coef[i];
- if (vp8_rac_get(&s->c)) {
- for (j = 0; j < 2; j++)
- for (k = 0; k < 2; k++)
- for (l = 0; l < 6; l++)
- for (m = 0; m < 6; m++) {
- uint8_t *p = s->prob.coef[i][j][k][l][m];
- uint8_t *r = ref[j][k][l][m];
- if (m >= 3 && l == 0) // dc only has 3 pt
- break;
- for (n = 0; n < 3; n++) {
- if (vp56_rac_get_prob_branchy(&s->c, 252)) {
- p[n] = update_prob(&s->c, r[n]);
- } else {
- p[n] = r[n];
- }
- }
- p[3] = 0;
- }
- } else {
- for (j = 0; j < 2; j++)
- for (k = 0; k < 2; k++)
- for (l = 0; l < 6; l++)
- for (m = 0; m < 6; m++) {
- uint8_t *p = s->prob.coef[i][j][k][l][m];
- uint8_t *r = ref[j][k][l][m];
- if (m > 3 && l == 0) // dc only has 3 pt
- break;
- memcpy(p, r, 3);
- p[3] = 0;
- }
- }
- if (s->txfmmode == i)
- break;
- }
-
- // mode updates
- for (i = 0; i < 3; i++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.skip[i] = update_prob(&s->c, s->prob.p.skip[i]);
- if (!s->keyframe && !s->intraonly) {
- for (i = 0; i < 7; i++)
- for (j = 0; j < 3; j++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.mv_mode[i][j] =
- update_prob(&s->c, s->prob.p.mv_mode[i][j]);
-
- if (s->filtermode == FILTER_SWITCHABLE)
- for (i = 0; i < 4; i++)
- for (j = 0; j < 2; j++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.filter[i][j] =
- update_prob(&s->c, s->prob.p.filter[i][j]);
-
- for (i = 0; i < 4; i++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.intra[i] = update_prob(&s->c, s->prob.p.intra[i]);
-
- if (s->allowcompinter) {
- s->comppredmode = vp8_rac_get(&s->c);
- if (s->comppredmode)
- s->comppredmode += vp8_rac_get(&s->c);
- if (s->comppredmode == PRED_SWITCHABLE)
- for (i = 0; i < 5; i++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.comp[i] =
- update_prob(&s->c, s->prob.p.comp[i]);
- } else {
- s->comppredmode = PRED_SINGLEREF;
- }
-
- if (s->comppredmode != PRED_COMPREF) {
- for (i = 0; i < 5; i++) {
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.single_ref[i][0] =
- update_prob(&s->c, s->prob.p.single_ref[i][0]);
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.single_ref[i][1] =
- update_prob(&s->c, s->prob.p.single_ref[i][1]);
- }
- }
-
- if (s->comppredmode != PRED_SINGLEREF) {
- for (i = 0; i < 5; i++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.comp_ref[i] =
- update_prob(&s->c, s->prob.p.comp_ref[i]);
- }
-
- for (i = 0; i < 4; i++)
- for (j = 0; j < 9; j++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.y_mode[i][j] =
- update_prob(&s->c, s->prob.p.y_mode[i][j]);
-
- for (i = 0; i < 4; i++)
- for (j = 0; j < 4; j++)
- for (k = 0; k < 3; k++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.partition[3 - i][j][k] =
- update_prob(&s->c, s->prob.p.partition[3 - i][j][k]);
-
- // mv fields don't use the update_prob subexp model for some reason
- for (i = 0; i < 3; i++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.mv_joint[i] = (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
-
- for (i = 0; i < 2; i++) {
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.mv_comp[i].sign = (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
-
- for (j = 0; j < 10; j++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.mv_comp[i].classes[j] =
- (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
-
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.mv_comp[i].class0 = (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
-
- for (j = 0; j < 10; j++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.mv_comp[i].bits[j] =
- (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
- }
-
- for (i = 0; i < 2; i++) {
- for (j = 0; j < 2; j++)
- for (k = 0; k < 3; k++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.mv_comp[i].class0_fp[j][k] =
- (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
-
- for (j = 0; j < 3; j++)
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.mv_comp[i].fp[j] =
- (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
- }
-
- if (s->highprecisionmvs) {
- for (i = 0; i < 2; i++) {
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.mv_comp[i].class0_hp =
- (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
-
- if (vp56_rac_get_prob_branchy(&s->c, 252))
- s->prob.p.mv_comp[i].hp =
- (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
- }
- }
- }
-
- return (data2 - data) + size2;
-}
-
-static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src,
- VP9Context *s)
-{
- dst->x = av_clip(src->x, s->min_mv.x, s->max_mv.x);
- dst->y = av_clip(src->y, s->min_mv.y, s->max_mv.y);
-}
-
-static void find_ref_mvs(VP9Context *s,
- VP56mv *pmv, int ref, int z, int idx, int sb)
-{
- static const int8_t mv_ref_blk_off[N_BS_SIZES][8][2] = {
- [BS_64x64] = {{ 3, -1 }, { -1, 3 }, { 4, -1 }, { -1, 4 },
- { -1, -1 }, { 0, -1 }, { -1, 0 }, { 6, -1 }},
- [BS_64x32] = {{ 0, -1 }, { -1, 0 }, { 4, -1 }, { -1, 2 },
- { -1, -1 }, { 0, -3 }, { -3, 0 }, { 2, -1 }},
- [BS_32x64] = {{ -1, 0 }, { 0, -1 }, { -1, 4 }, { 2, -1 },
- { -1, -1 }, { -3, 0 }, { 0, -3 }, { -1, 2 }},
- [BS_32x32] = {{ 1, -1 }, { -1, 1 }, { 2, -1 }, { -1, 2 },
- { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }},
- [BS_32x16] = {{ 0, -1 }, { -1, 0 }, { 2, -1 }, { -1, -1 },
- { -1, 1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }},
- [BS_16x32] = {{ -1, 0 }, { 0, -1 }, { -1, 2 }, { -1, -1 },
- { 1, -1 }, { -3, 0 }, { 0, -3 }, { -3, -3 }},
- [BS_16x16] = {{ 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, 1 },
- { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }},
- [BS_16x8] = {{ 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, -1 },
- { 0, -2 }, { -2, 0 }, { -2, -1 }, { -1, -2 }},
- [BS_8x16] = {{ -1, 0 }, { 0, -1 }, { -1, 1 }, { -1, -1 },
- { -2, 0 }, { 0, -2 }, { -1, -2 }, { -2, -1 }},
- [BS_8x8] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
- { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }},
- [BS_8x4] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
- { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }},
- [BS_4x8] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
- { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }},
- [BS_4x4] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
- { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }},
- };
- VP9Block *b = s->b;
- int row = s->row, col = s->col, row7 = s->row7;
- const int8_t (*p)[2] = mv_ref_blk_off[b->bs];
-#define INVALID_MV 0x80008000U
- uint32_t mem = INVALID_MV, mem_sub8x8 = INVALID_MV;
- int i;
-
-#define RETURN_DIRECT_MV(mv) \
- do { \
- uint32_t m = AV_RN32A(&mv); \
- if (!idx) { \
- AV_WN32A(pmv, m); \
- return; \
- } else if (mem == INVALID_MV) { \
- mem = m; \
- } else if (m != mem) { \
- AV_WN32A(pmv, m); \
- return; \
- } \
- } while (0)
-
- if (sb >= 0) {
- if (sb == 2 || sb == 1) {
- RETURN_DIRECT_MV(b->mv[0][z]);
- } else if (sb == 3) {
- RETURN_DIRECT_MV(b->mv[2][z]);
- RETURN_DIRECT_MV(b->mv[1][z]);
- RETURN_DIRECT_MV(b->mv[0][z]);
- }
-
-#define RETURN_MV(mv) \
- do { \
- if (sb > 0) { \
- VP56mv tmp; \
- uint32_t m; \
- av_assert2(idx == 1); \
- av_assert2(mem != INVALID_MV); \
- if (mem_sub8x8 == INVALID_MV) { \
- clamp_mv(&tmp, &mv, s); \
- m = AV_RN32A(&tmp); \
- if (m != mem) { \
- AV_WN32A(pmv, m); \
- return; \
- } \
- mem_sub8x8 = AV_RN32A(&mv); \
- } else if (mem_sub8x8 != AV_RN32A(&mv)) { \
- clamp_mv(&tmp, &mv, s); \
- m = AV_RN32A(&tmp); \
- if (m != mem) { \
- AV_WN32A(pmv, m); \
- } else { \
- /* BUG I'm pretty sure this isn't the intention */ \
- AV_WN32A(pmv, 0); \
- } \
- return; \
- } \
- } else { \
- uint32_t m = AV_RN32A(&mv); \
- if (!idx) { \
- clamp_mv(pmv, &mv, s); \
- return; \
- } else if (mem == INVALID_MV) { \
- mem = m; \
- } else if (m != mem) { \
- clamp_mv(pmv, &mv, s); \
- return; \
- } \
- } \
- } while (0)
-
- if (row > 0) {
- struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col];
- if (mv->ref[0] == ref) {
- RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]);
- } else if (mv->ref[1] == ref) {
- RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]);
- }
- }
- if (col > s->tiling.tile_col_start) {
- struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1];
- if (mv->ref[0] == ref) {
- RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][0]);
- } else if (mv->ref[1] == ref) {
- RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][1]);
- }
- }
- i = 2;
- } else {
- i = 0;
- }
-
- // previously coded MVs in this neighbourhood, using same reference frame
- for (; i < 8; i++) {
- int c = p[i][0] + col, r = p[i][1] + row;
-
- if (c >= s->tiling.tile_col_start && c < s->cols && r >= 0 && r < s->rows) {
- struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
-
- if (mv->ref[0] == ref) {
- RETURN_MV(mv->mv[0]);
- } else if (mv->ref[1] == ref) {
- RETURN_MV(mv->mv[1]);
- }
- }
- }
-
- // MV at this position in previous frame, using same reference frame
- if (s->use_last_frame_mvs) {
- struct VP9mvrefPair *mv = &s->frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col];
-
- if (!s->frames[REF_FRAME_MVPAIR].uses_2pass)
- ff_thread_await_progress(&s->frames[REF_FRAME_MVPAIR].tf, row >> 3, 0);
- if (mv->ref[0] == ref) {
- RETURN_MV(mv->mv[0]);
- } else if (mv->ref[1] == ref) {
- RETURN_MV(mv->mv[1]);
- }
- }
-
-#define RETURN_SCALE_MV(mv, scale) \
- do { \
- if (scale) { \
- VP56mv mv_temp = { -mv.x, -mv.y }; \
- RETURN_MV(mv_temp); \
- } else { \
- RETURN_MV(mv); \
- } \
- } while (0)
-
- // previously coded MVs in this neighbourhood, using different reference frame
- for (i = 0; i < 8; i++) {
- int c = p[i][0] + col, r = p[i][1] + row;
-
- if (c >= s->tiling.tile_col_start && c < s->cols && r >= 0 && r < s->rows) {
- struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
-
- if (mv->ref[0] != ref && mv->ref[0] >= 0) {
- RETURN_SCALE_MV(mv->mv[0], s->signbias[mv->ref[0]] != s->signbias[ref]);
- }
- if (mv->ref[1] != ref && mv->ref[1] >= 0 &&
- // BUG - libvpx has this condition regardless of whether
- // we used the first ref MV and pre-scaling
- AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) {
- RETURN_SCALE_MV(mv->mv[1], s->signbias[mv->ref[1]] != s->signbias[ref]);
- }
- }
- }
-
- // MV at this position in previous frame, using different reference frame
- if (s->use_last_frame_mvs) {
- struct VP9mvrefPair *mv = &s->frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col];
-
- // no need to await_progress, because we already did that above
- if (mv->ref[0] != ref && mv->ref[0] >= 0) {
- RETURN_SCALE_MV(mv->mv[0], s->signbias[mv->ref[0]] != s->signbias[ref]);
- }
- if (mv->ref[1] != ref && mv->ref[1] >= 0 &&
- // BUG - libvpx has this condition regardless of whether
- // we used the first ref MV and pre-scaling
- AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) {
- RETURN_SCALE_MV(mv->mv[1], s->signbias[mv->ref[1]] != s->signbias[ref]);
- }
- }
-
- AV_ZERO32(pmv);
- clamp_mv(pmv, pmv, s);
-#undef INVALID_MV
-#undef RETURN_MV
-#undef RETURN_SCALE_MV
-}
-
-static av_always_inline int read_mv_component(VP9Context *s, int idx, int hp)
-{
- int bit, sign = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].sign);
- int n, c = vp8_rac_get_tree(&s->c, vp9_mv_class_tree,
- s->prob.p.mv_comp[idx].classes);
-
- s->counts.mv_comp[idx].sign[sign]++;
- s->counts.mv_comp[idx].classes[c]++;
- if (c) {
- int m;
-
- for (n = 0, m = 0; m < c; m++) {
- bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].bits[m]);
- n |= bit << m;
- s->counts.mv_comp[idx].bits[m][bit]++;
- }
- n <<= 3;
- bit = vp8_rac_get_tree(&s->c, vp9_mv_fp_tree, s->prob.p.mv_comp[idx].fp);
- n |= bit << 1;
- s->counts.mv_comp[idx].fp[bit]++;
- if (hp) {
- bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].hp);
- s->counts.mv_comp[idx].hp[bit]++;
- n |= bit;
- } else {
- n |= 1;
- // bug in libvpx - we count for bw entropy purposes even if the
- // bit wasn't coded
- s->counts.mv_comp[idx].hp[1]++;
- }
- n += 8 << c;
- } else {
- n = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0);
- s->counts.mv_comp[idx].class0[n]++;
- bit = vp8_rac_get_tree(&s->c, vp9_mv_fp_tree,
- s->prob.p.mv_comp[idx].class0_fp[n]);
- s->counts.mv_comp[idx].class0_fp[n][bit]++;
- n = (n << 3) | (bit << 1);
- if (hp) {
- bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0_hp);
- s->counts.mv_comp[idx].class0_hp[bit]++;
- n |= bit;
- } else {
- n |= 1;
- // bug in libvpx - we count for bw entropy purposes even if the
- // bit wasn't coded
- s->counts.mv_comp[idx].class0_hp[1]++;
- }
- }
-
- return sign ? -(n + 1) : (n + 1);
-}
-
-static void fill_mv(VP9Context *s,
- VP56mv *mv, int mode, int sb)
-{
- VP9Block *b = s->b;
-
- if (mode == ZEROMV) {
- AV_ZERO64(mv);
- } else {
- int hp;
-
- // FIXME cache this value and reuse for other subblocks
- find_ref_mvs(s, &mv[0], b->ref[0], 0, mode == NEARMV,
- mode == NEWMV ? -1 : sb);
- // FIXME maybe move this code into find_ref_mvs()
- if ((mode == NEWMV || sb == -1) &&
- !(hp = s->highprecisionmvs && abs(mv[0].x) < 64 && abs(mv[0].y) < 64)) {
- if (mv[0].y & 1) {
- if (mv[0].y < 0)
- mv[0].y++;
- else
- mv[0].y--;
- }
- if (mv[0].x & 1) {
- if (mv[0].x < 0)
- mv[0].x++;
- else
- mv[0].x--;
- }
- }
- if (mode == NEWMV) {
- enum MVJoint j = vp8_rac_get_tree(&s->c, vp9_mv_joint_tree,
- s->prob.p.mv_joint);
-
- s->counts.mv_joint[j]++;
- if (j >= MV_JOINT_V)
- mv[0].y += read_mv_component(s, 0, hp);
- if (j & 1)
- mv[0].x += read_mv_component(s, 1, hp);
- }
-
- if (b->comp) {
- // FIXME cache this value and reuse for other subblocks
- find_ref_mvs(s, &mv[1], b->ref[1], 1, mode == NEARMV,
- mode == NEWMV ? -1 : sb);
- if ((mode == NEWMV || sb == -1) &&
- !(hp = s->highprecisionmvs && abs(mv[1].x) < 64 && abs(mv[1].y) < 64)) {
- if (mv[1].y & 1) {
- if (mv[1].y < 0)
- mv[1].y++;
- else
- mv[1].y--;
- }
- if (mv[1].x & 1) {
- if (mv[1].x < 0)
- mv[1].x++;
- else
- mv[1].x--;
- }
- }
- if (mode == NEWMV) {
- enum MVJoint j = vp8_rac_get_tree(&s->c, vp9_mv_joint_tree,
- s->prob.p.mv_joint);
-
- s->counts.mv_joint[j]++;
- if (j >= MV_JOINT_V)
- mv[1].y += read_mv_component(s, 0, hp);
- if (j & 1)
- mv[1].x += read_mv_component(s, 1, hp);
- }
- }
- }
-}
-
-static av_always_inline void setctx_2d(uint8_t *ptr, int w, int h,
- ptrdiff_t stride, int v)
-{
- switch (w) {
- case 1:
- do {
- *ptr = v;
- ptr += stride;
- } while (--h);
- break;
- case 2: {
- int v16 = v * 0x0101;
- do {
- AV_WN16A(ptr, v16);
- ptr += stride;
- } while (--h);
- break;
- }
- case 4: {
- uint32_t v32 = v * 0x01010101;
- do {
- AV_WN32A(ptr, v32);
- ptr += stride;
- } while (--h);
- break;
- }
- case 8: {
-#if HAVE_FAST_64BIT
- uint64_t v64 = v * 0x0101010101010101ULL;
- do {
- AV_WN64A(ptr, v64);
- ptr += stride;
- } while (--h);
-#else
- uint32_t v32 = v * 0x01010101;
- do {
- AV_WN32A(ptr, v32);
- AV_WN32A(ptr + 4, v32);
- ptr += stride;
- } while (--h);
-#endif
- break;
- }
- }
-}
-
-static void decode_mode(AVCodecContext *ctx)
-{
- static const uint8_t left_ctx[N_BS_SIZES] = {
- 0x0, 0x8, 0x0, 0x8, 0xc, 0x8, 0xc, 0xe, 0xc, 0xe, 0xf, 0xe, 0xf
- };
- static const uint8_t above_ctx[N_BS_SIZES] = {
- 0x0, 0x0, 0x8, 0x8, 0x8, 0xc, 0xc, 0xc, 0xe, 0xe, 0xe, 0xf, 0xf
- };
- static const uint8_t max_tx_for_bl_bp[N_BS_SIZES] = {
- TX_32X32, TX_32X32, TX_32X32, TX_32X32, TX_16X16, TX_16X16,
- TX_16X16, TX_8X8, TX_8X8, TX_8X8, TX_4X4, TX_4X4, TX_4X4
- };
- VP9Context *s = ctx->priv_data;
- VP9Block *b = s->b;
- int row = s->row, col = s->col, row7 = s->row7;
- enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs];
- int bw4 = bwh_tab[1][b->bs][0], w4 = FFMIN(s->cols - col, bw4);
- int bh4 = bwh_tab[1][b->bs][1], h4 = FFMIN(s->rows - row, bh4), y;
- int have_a = row > 0, have_l = col > s->tiling.tile_col_start;
- int vref, filter_id;
-
- if (!s->segmentation.enabled) {
- b->seg_id = 0;
- } else if (s->keyframe || s->intraonly) {
- b->seg_id = !s->segmentation.update_map ? 0 :
- vp8_rac_get_tree(&s->c, vp9_segmentation_tree, s->prob.seg);
- } else if (!s->segmentation.update_map ||
- (s->segmentation.temporal &&
- vp56_rac_get_prob_branchy(&s->c,
- s->prob.segpred[s->above_segpred_ctx[col] +
- s->left_segpred_ctx[row7]]))) {
- if (!s->errorres && !s->segmentation.ignore_refmap) {
- int pred = 8, x;
- uint8_t *refsegmap = s->frames[REF_FRAME_SEGMAP].segmentation_map;
-
- if (!s->frames[REF_FRAME_SEGMAP].uses_2pass)
- ff_thread_await_progress(&s->frames[REF_FRAME_SEGMAP].tf, row >> 3, 0);
- for (y = 0; y < h4; y++) {
- int idx_base = (y + row) * 8 * s->sb_cols + col;
- for (x = 0; x < w4; x++)
- pred = FFMIN(pred, refsegmap[idx_base + x]);
- }
- av_assert1(pred < 8);
- b->seg_id = pred;
- } else {
- b->seg_id = 0;
- }
-
- memset(&s->above_segpred_ctx[col], 1, w4);
- memset(&s->left_segpred_ctx[row7], 1, h4);
- } else {
- b->seg_id = vp8_rac_get_tree(&s->c, vp9_segmentation_tree,
- s->prob.seg);
-
- memset(&s->above_segpred_ctx[col], 0, w4);
- memset(&s->left_segpred_ctx[row7], 0, h4);
- }
- if (s->segmentation.enabled &&
- (s->segmentation.update_map || s->keyframe || s->intraonly)) {
- setctx_2d(&s->frames[CUR_FRAME].segmentation_map[row * 8 * s->sb_cols + col],
- bw4, bh4, 8 * s->sb_cols, b->seg_id);
- }
-
- b->skip = s->segmentation.enabled &&
- s->segmentation.feat[b->seg_id].skip_enabled;
- if (!b->skip) {
- int c = s->left_skip_ctx[row7] + s->above_skip_ctx[col];
- b->skip = vp56_rac_get_prob(&s->c, s->prob.p.skip[c]);
- s->counts.skip[c][b->skip]++;
- }
-
- if (s->keyframe || s->intraonly) {
- b->intra = 1;
- } else if (s->segmentation.enabled && s->segmentation.feat[b->seg_id].ref_enabled) {
- b->intra = !s->segmentation.feat[b->seg_id].ref_val;
- } else {
- int c, bit;
-
- if (have_a && have_l) {
- c = s->above_intra_ctx[col] + s->left_intra_ctx[row7];
- c += (c == 2);
- } else {
- c = have_a ? 2 * s->above_intra_ctx[col] :
- have_l ? 2 * s->left_intra_ctx[row7] : 0;
- }
- bit = vp56_rac_get_prob(&s->c, s->prob.p.intra[c]);
- s->counts.intra[c][bit]++;
- b->intra = !bit;
- }
-
- if ((b->intra || !b->skip) && s->txfmmode == TX_SWITCHABLE) {
- int c;
- if (have_a) {
- if (have_l) {
- c = (s->above_skip_ctx[col] ? max_tx :
- s->above_txfm_ctx[col]) +
- (s->left_skip_ctx[row7] ? max_tx :
- s->left_txfm_ctx[row7]) > max_tx;
- } else {
- c = s->above_skip_ctx[col] ? 1 :
- (s->above_txfm_ctx[col] * 2 > max_tx);
- }
- } else if (have_l) {
- c = s->left_skip_ctx[row7] ? 1 :
- (s->left_txfm_ctx[row7] * 2 > max_tx);
- } else {
- c = 1;
- }
- switch (max_tx) {
- case TX_32X32:
- b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][0]);
- if (b->tx) {
- b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][1]);
- if (b->tx == 2)
- b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][2]);
- }
- s->counts.tx32p[c][b->tx]++;
- break;
- case TX_16X16:
- b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][0]);
- if (b->tx)
- b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][1]);
- s->counts.tx16p[c][b->tx]++;
- break;
- case TX_8X8:
- b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx8p[c]);
- s->counts.tx8p[c][b->tx]++;
- break;
- case TX_4X4:
- b->tx = TX_4X4;
- break;
- }
- } else {
- b->tx = FFMIN(max_tx, s->txfmmode);
- }
-
- if (s->keyframe || s->intraonly) {
- uint8_t *a = &s->above_mode_ctx[col * 2];
- uint8_t *l = &s->left_mode_ctx[(row7) << 1];
-
- b->comp = 0;
- if (b->bs > BS_8x8) {
- // FIXME the memory storage intermediates here aren't really
- // necessary, they're just there to make the code slightly
- // simpler for now
- b->mode[0] = a[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
- vp9_default_kf_ymode_probs[a[0]][l[0]]);
- if (b->bs != BS_8x4) {
- b->mode[1] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
- vp9_default_kf_ymode_probs[a[1]][b->mode[0]]);
- l[0] = a[1] = b->mode[1];
- } else {
- l[0] = a[1] = b->mode[1] = b->mode[0];
- }
- if (b->bs != BS_4x8) {
- b->mode[2] = a[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
- vp9_default_kf_ymode_probs[a[0]][l[1]]);
- if (b->bs != BS_8x4) {
- b->mode[3] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
- vp9_default_kf_ymode_probs[a[1]][b->mode[2]]);
- l[1] = a[1] = b->mode[3];
- } else {
- l[1] = a[1] = b->mode[3] = b->mode[2];
- }
- } else {
- b->mode[2] = b->mode[0];
- l[1] = a[1] = b->mode[3] = b->mode[1];
- }
- } else {
- b->mode[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
- vp9_default_kf_ymode_probs[*a][*l]);
- b->mode[3] = b->mode[2] = b->mode[1] = b->mode[0];
- // FIXME this can probably be optimized
- memset(a, b->mode[0], bwh_tab[0][b->bs][0]);
- memset(l, b->mode[0], bwh_tab[0][b->bs][1]);
- }
- b->uvmode = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
- vp9_default_kf_uvmode_probs[b->mode[3]]);
- } else if (b->intra) {
- b->comp = 0;
- if (b->bs > BS_8x8) {
- b->mode[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
- s->prob.p.y_mode[0]);
- s->counts.y_mode[0][b->mode[0]]++;
- if (b->bs != BS_8x4) {
- b->mode[1] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
- s->prob.p.y_mode[0]);
- s->counts.y_mode[0][b->mode[1]]++;
- } else {
- b->mode[1] = b->mode[0];
- }
- if (b->bs != BS_4x8) {
- b->mode[2] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
- s->prob.p.y_mode[0]);
- s->counts.y_mode[0][b->mode[2]]++;
- if (b->bs != BS_8x4) {
- b->mode[3] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
- s->prob.p.y_mode[0]);
- s->counts.y_mode[0][b->mode[3]]++;
- } else {
- b->mode[3] = b->mode[2];
- }
- } else {
- b->mode[2] = b->mode[0];
- b->mode[3] = b->mode[1];
- }
- } else {
- static const uint8_t size_group[10] = {
- 3, 3, 3, 3, 2, 2, 2, 1, 1, 1
- };
- int sz = size_group[b->bs];
-
- b->mode[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
- s->prob.p.y_mode[sz]);
- b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0];
- s->counts.y_mode[sz][b->mode[3]]++;
- }
- b->uvmode = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
- s->prob.p.uv_mode[b->mode[3]]);
- s->counts.uv_mode[b->mode[3]][b->uvmode]++;
- } else {
- static const uint8_t inter_mode_ctx_lut[14][14] = {
- { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
- { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
- { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
- { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
- { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
- { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
- { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
- { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
- { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
- { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
- { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 },
- { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 },
- { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 0, 3 },
- { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 4 },
- };
-
- if (s->segmentation.enabled && s->segmentation.feat[b->seg_id].ref_enabled) {
- av_assert2(s->segmentation.feat[b->seg_id].ref_val != 0);
- b->comp = 0;
- b->ref[0] = s->segmentation.feat[b->seg_id].ref_val - 1;
- } else {
- // read comp_pred flag
- if (s->comppredmode != PRED_SWITCHABLE) {
- b->comp = s->comppredmode == PRED_COMPREF;
- } else {
- int c;
-
- // FIXME add intra as ref=0xff (or -1) to make these easier?
- if (have_a) {
- if (have_l) {
- if (s->above_comp_ctx[col] && s->left_comp_ctx[row7]) {
- c = 4;
- } else if (s->above_comp_ctx[col]) {
- c = 2 + (s->left_intra_ctx[row7] ||
- s->left_ref_ctx[row7] == s->fixcompref);
- } else if (s->left_comp_ctx[row7]) {
- c = 2 + (s->above_intra_ctx[col] ||
- s->above_ref_ctx[col] == s->fixcompref);
- } else {
- c = (!s->above_intra_ctx[col] &&
- s->above_ref_ctx[col] == s->fixcompref) ^
- (!s->left_intra_ctx[row7] &&
- s->left_ref_ctx[row & 7] == s->fixcompref);
- }
- } else {
- c = s->above_comp_ctx[col] ? 3 :
- (!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->fixcompref);
- }
- } else if (have_l) {
- c = s->left_comp_ctx[row7] ? 3 :
- (!s->left_intra_ctx[row7] && s->left_ref_ctx[row7] == s->fixcompref);
- } else {
- c = 1;
- }
- b->comp = vp56_rac_get_prob(&s->c, s->prob.p.comp[c]);
- s->counts.comp[c][b->comp]++;
- }
-
- // read actual references
- // FIXME probably cache a few variables here to prevent repetitive
- // memory accesses below
- if (b->comp) /* two references */ {
- int fix_idx = s->signbias[s->fixcompref], var_idx = !fix_idx, c, bit;
-
- b->ref[fix_idx] = s->fixcompref;
- // FIXME can this codeblob be replaced by some sort of LUT?
- if (have_a) {
- if (have_l) {
- if (s->above_intra_ctx[col]) {
- if (s->left_intra_ctx[row7]) {
- c = 2;
- } else {
- c = 1 + 2 * (s->left_ref_ctx[row7] != s->varcompref[1]);
- }
- } else if (s->left_intra_ctx[row7]) {
- c = 1 + 2 * (s->above_ref_ctx[col] != s->varcompref[1]);
- } else {
- int refl = s->left_ref_ctx[row7], refa = s->above_ref_ctx[col];
-
- if (refl == refa && refa == s->varcompref[1]) {
- c = 0;
- } else if (!s->left_comp_ctx[row7] && !s->above_comp_ctx[col]) {
- if ((refa == s->fixcompref && refl == s->varcompref[0]) ||
- (refl == s->fixcompref && refa == s->varcompref[0])) {
- c = 4;
- } else {
- c = (refa == refl) ? 3 : 1;
- }
- } else if (!s->left_comp_ctx[row7]) {
- if (refa == s->varcompref[1] && refl != s->varcompref[1]) {
- c = 1;
- } else {
- c = (refl == s->varcompref[1] &&
- refa != s->varcompref[1]) ? 2 : 4;
- }
- } else if (!s->above_comp_ctx[col]) {
- if (refl == s->varcompref[1] && refa != s->varcompref[1]) {
- c = 1;
- } else {
- c = (refa == s->varcompref[1] &&
- refl != s->varcompref[1]) ? 2 : 4;
- }
- } else {
- c = (refl == refa) ? 4 : 2;
- }
- }
- } else {
- if (s->above_intra_ctx[col]) {
- c = 2;
- } else if (s->above_comp_ctx[col]) {
- c = 4 * (s->above_ref_ctx[col] != s->varcompref[1]);
- } else {
- c = 3 * (s->above_ref_ctx[col] != s->varcompref[1]);
- }
- }
- } else if (have_l) {
- if (s->left_intra_ctx[row7]) {
- c = 2;
- } else if (s->left_comp_ctx[row7]) {
- c = 4 * (s->left_ref_ctx[row7] != s->varcompref[1]);
- } else {
- c = 3 * (s->left_ref_ctx[row7] != s->varcompref[1]);
- }
- } else {
- c = 2;
- }
- bit = vp56_rac_get_prob(&s->c, s->prob.p.comp_ref[c]);
- b->ref[var_idx] = s->varcompref[bit];
- s->counts.comp_ref[c][bit]++;
- } else /* single reference */ {
- int bit, c;
-
- if (have_a && !s->above_intra_ctx[col]) {
- if (have_l && !s->left_intra_ctx[row7]) {
- if (s->left_comp_ctx[row7]) {
- if (s->above_comp_ctx[col]) {
- c = 1 + (!s->fixcompref || !s->left_ref_ctx[row7] ||
- !s->above_ref_ctx[col]);
- } else {
- c = (3 * !s->above_ref_ctx[col]) +
- (!s->fixcompref || !s->left_ref_ctx[row7]);
- }
- } else if (s->above_comp_ctx[col]) {
- c = (3 * !s->left_ref_ctx[row7]) +
- (!s->fixcompref || !s->above_ref_ctx[col]);
- } else {
- c = 2 * !s->left_ref_ctx[row7] + 2 * !s->above_ref_ctx[col];
- }
- } else if (s->above_intra_ctx[col]) {
- c = 2;
- } else if (s->above_comp_ctx[col]) {
- c = 1 + (!s->fixcompref || !s->above_ref_ctx[col]);
- } else {
- c = 4 * (!s->above_ref_ctx[col]);
- }
- } else if (have_l && !s->left_intra_ctx[row7]) {
- if (s->left_intra_ctx[row7]) {
- c = 2;
- } else if (s->left_comp_ctx[row7]) {
- c = 1 + (!s->fixcompref || !s->left_ref_ctx[row7]);
- } else {
- c = 4 * (!s->left_ref_ctx[row7]);
- }
- } else {
- c = 2;
- }
- bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][0]);
- s->counts.single_ref[c][0][bit]++;
- if (!bit) {
- b->ref[0] = 0;
- } else {
- // FIXME can this codeblob be replaced by some sort of LUT?
- if (have_a) {
- if (have_l) {
- if (s->left_intra_ctx[row7]) {
- if (s->above_intra_ctx[col]) {
- c = 2;
- } else if (s->above_comp_ctx[col]) {
- c = 1 + 2 * (s->fixcompref == 1 ||
- s->above_ref_ctx[col] == 1);
- } else if (!s->above_ref_ctx[col]) {
- c = 3;
- } else {
- c = 4 * (s->above_ref_ctx[col] == 1);
- }
- } else if (s->above_intra_ctx[col]) {
- if (s->left_intra_ctx[row7]) {
- c = 2;
- } else if (s->left_comp_ctx[row7]) {
- c = 1 + 2 * (s->fixcompref == 1 ||
- s->left_ref_ctx[row7] == 1);
- } else if (!s->left_ref_ctx[row7]) {
- c = 3;
- } else {
- c = 4 * (s->left_ref_ctx[row7] == 1);
- }
- } else if (s->above_comp_ctx[col]) {
- if (s->left_comp_ctx[row7]) {
- if (s->left_ref_ctx[row7] == s->above_ref_ctx[col]) {
- c = 3 * (s->fixcompref == 1 ||
- s->left_ref_ctx[row7] == 1);
- } else {
- c = 2;
- }
- } else if (!s->left_ref_ctx[row7]) {
- c = 1 + 2 * (s->fixcompref == 1 ||
- s->above_ref_ctx[col] == 1);
- } else {
- c = 3 * (s->left_ref_ctx[row7] == 1) +
- (s->fixcompref == 1 || s->above_ref_ctx[col] == 1);
- }
- } else if (s->left_comp_ctx[row7]) {
- if (!s->above_ref_ctx[col]) {
- c = 1 + 2 * (s->fixcompref == 1 ||
- s->left_ref_ctx[row7] == 1);
- } else {
- c = 3 * (s->above_ref_ctx[col] == 1) +
- (s->fixcompref == 1 || s->left_ref_ctx[row7] == 1);
- }
- } else if (!s->above_ref_ctx[col]) {
- if (!s->left_ref_ctx[row7]) {
- c = 3;
- } else {
- c = 4 * (s->left_ref_ctx[row7] == 1);
- }
- } else if (!s->left_ref_ctx[row7]) {
- c = 4 * (s->above_ref_ctx[col] == 1);
- } else {
- c = 2 * (s->left_ref_ctx[row7] == 1) +
- 2 * (s->above_ref_ctx[col] == 1);
- }
- } else {
- if (s->above_intra_ctx[col] ||
- (!s->above_comp_ctx[col] && !s->above_ref_ctx[col])) {
- c = 2;
- } else if (s->above_comp_ctx[col]) {
- c = 3 * (s->fixcompref == 1 || s->above_ref_ctx[col] == 1);
- } else {
- c = 4 * (s->above_ref_ctx[col] == 1);
- }
- }
- } else if (have_l) {
- if (s->left_intra_ctx[row7] ||
- (!s->left_comp_ctx[row7] && !s->left_ref_ctx[row7])) {
- c = 2;
- } else if (s->left_comp_ctx[row7]) {
- c = 3 * (s->fixcompref == 1 || s->left_ref_ctx[row7] == 1);
- } else {
- c = 4 * (s->left_ref_ctx[row7] == 1);
- }
- } else {
- c = 2;
- }
- bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][1]);
- s->counts.single_ref[c][1][bit]++;
- b->ref[0] = 1 + bit;
- }
- }
- }
-
- if (b->bs <= BS_8x8) {
- if (s->segmentation.enabled && s->segmentation.feat[b->seg_id].skip_enabled) {
- b->mode[0] = b->mode[1] = b->mode[2] = b->mode[3] = ZEROMV;
- } else {
- static const uint8_t off[10] = {
- 3, 0, 0, 1, 0, 0, 0, 0, 0, 0
- };
-
- // FIXME this needs to use the LUT tables from find_ref_mvs
- // because not all are -1,0/0,-1
- int c = inter_mode_ctx_lut[s->above_mode_ctx[col + off[b->bs]]]
- [s->left_mode_ctx[row7 + off[b->bs]]];
-
- b->mode[0] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree,
- s->prob.p.mv_mode[c]);
- b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0];
- s->counts.mv_mode[c][b->mode[0] - 10]++;
- }
- }
-
- if (s->filtermode == FILTER_SWITCHABLE) {
- int c;
-
- if (have_a && s->above_mode_ctx[col] >= NEARESTMV) {
- if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) {
- c = s->above_filter_ctx[col] == s->left_filter_ctx[row7] ?
- s->left_filter_ctx[row7] : 3;
- } else {
- c = s->above_filter_ctx[col];
- }
- } else if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) {
- c = s->left_filter_ctx[row7];
- } else {
- c = 3;
- }
-
- filter_id = vp8_rac_get_tree(&s->c, vp9_filter_tree,
- s->prob.p.filter[c]);
- s->counts.filter[c][filter_id]++;
- b->filter = vp9_filter_lut[filter_id];
- } else {
- b->filter = s->filtermode;
- }
-
- if (b->bs > BS_8x8) {
- int c = inter_mode_ctx_lut[s->above_mode_ctx[col]][s->left_mode_ctx[row7]];
-
- b->mode[0] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree,
- s->prob.p.mv_mode[c]);
- s->counts.mv_mode[c][b->mode[0] - 10]++;
- fill_mv(s, b->mv[0], b->mode[0], 0);
-
- if (b->bs != BS_8x4) {
- b->mode[1] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree,
- s->prob.p.mv_mode[c]);
- s->counts.mv_mode[c][b->mode[1] - 10]++;
- fill_mv(s, b->mv[1], b->mode[1], 1);
- } else {
- b->mode[1] = b->mode[0];
- AV_COPY32(&b->mv[1][0], &b->mv[0][0]);
- AV_COPY32(&b->mv[1][1], &b->mv[0][1]);
- }
-
- if (b->bs != BS_4x8) {
- b->mode[2] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree,
- s->prob.p.mv_mode[c]);
- s->counts.mv_mode[c][b->mode[2] - 10]++;
- fill_mv(s, b->mv[2], b->mode[2], 2);
-
- if (b->bs != BS_8x4) {
- b->mode[3] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree,
- s->prob.p.mv_mode[c]);
- s->counts.mv_mode[c][b->mode[3] - 10]++;
- fill_mv(s, b->mv[3], b->mode[3], 3);
- } else {
- b->mode[3] = b->mode[2];
- AV_COPY32(&b->mv[3][0], &b->mv[2][0]);
- AV_COPY32(&b->mv[3][1], &b->mv[2][1]);
- }
- } else {
- b->mode[2] = b->mode[0];
- AV_COPY32(&b->mv[2][0], &b->mv[0][0]);
- AV_COPY32(&b->mv[2][1], &b->mv[0][1]);
- b->mode[3] = b->mode[1];
- AV_COPY32(&b->mv[3][0], &b->mv[1][0]);
- AV_COPY32(&b->mv[3][1], &b->mv[1][1]);
- }
- } else {
- fill_mv(s, b->mv[0], b->mode[0], -1);
- AV_COPY32(&b->mv[1][0], &b->mv[0][0]);
- AV_COPY32(&b->mv[2][0], &b->mv[0][0]);
- AV_COPY32(&b->mv[3][0], &b->mv[0][0]);
- AV_COPY32(&b->mv[1][1], &b->mv[0][1]);
- AV_COPY32(&b->mv[2][1], &b->mv[0][1]);
- AV_COPY32(&b->mv[3][1], &b->mv[0][1]);
- }
-
- vref = b->ref[b->comp ? s->signbias[s->varcompref[0]] : 0];
- }
-
-#if HAVE_FAST_64BIT
-#define SPLAT_CTX(var, val, n) \
- switch (n) { \
- case 1: var = val; break; \
- case 2: AV_WN16A(&var, val * 0x0101); break; \
- case 4: AV_WN32A(&var, val * 0x01010101); break; \
- case 8: AV_WN64A(&var, val * 0x0101010101010101ULL); break; \
- case 16: { \
- uint64_t v64 = val * 0x0101010101010101ULL; \
- AV_WN64A( &var, v64); \
- AV_WN64A(&((uint8_t *) &var)[8], v64); \
- break; \
- } \
- }
-#else
-#define SPLAT_CTX(var, val, n) \
- switch (n) { \
- case 1: var = val; break; \
- case 2: AV_WN16A(&var, val * 0x0101); break; \
- case 4: AV_WN32A(&var, val * 0x01010101); break; \
- case 8: { \
- uint32_t v32 = val * 0x01010101; \
- AV_WN32A( &var, v32); \
- AV_WN32A(&((uint8_t *) &var)[4], v32); \
- break; \
- } \
- case 16: { \
- uint32_t v32 = val * 0x01010101; \
- AV_WN32A( &var, v32); \
- AV_WN32A(&((uint8_t *) &var)[4], v32); \
- AV_WN32A(&((uint8_t *) &var)[8], v32); \
- AV_WN32A(&((uint8_t *) &var)[12], v32); \
- break; \
- } \
- }
-#endif
-
- switch (bwh_tab[1][b->bs][0]) {
-#define SET_CTXS(dir, off, n) \
- do { \
- SPLAT_CTX(s->dir##_skip_ctx[off], b->skip, n); \
- SPLAT_CTX(s->dir##_txfm_ctx[off], b->tx, n); \
- SPLAT_CTX(s->dir##_partition_ctx[off], dir##_ctx[b->bs], n); \
- if (!s->keyframe && !s->intraonly) { \
- SPLAT_CTX(s->dir##_intra_ctx[off], b->intra, n); \
- SPLAT_CTX(s->dir##_comp_ctx[off], b->comp, n); \
- SPLAT_CTX(s->dir##_mode_ctx[off], b->mode[3], n); \
- if (!b->intra) { \
- SPLAT_CTX(s->dir##_ref_ctx[off], vref, n); \
- if (s->filtermode == FILTER_SWITCHABLE) { \
- SPLAT_CTX(s->dir##_filter_ctx[off], filter_id, n); \
- } \
- } \
- } \
- } while (0)
- case 1: SET_CTXS(above, col, 1); break;
- case 2: SET_CTXS(above, col, 2); break;
- case 4: SET_CTXS(above, col, 4); break;
- case 8: SET_CTXS(above, col, 8); break;
- }
- switch (bwh_tab[1][b->bs][1]) {
- case 1: SET_CTXS(left, row7, 1); break;
- case 2: SET_CTXS(left, row7, 2); break;
- case 4: SET_CTXS(left, row7, 4); break;
- case 8: SET_CTXS(left, row7, 8); break;
- }
-#undef SPLAT_CTX
-#undef SET_CTXS
-
- if (!s->keyframe && !s->intraonly) {
- if (b->bs > BS_8x8) {
- int mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]);
-
- AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][0], &b->mv[1][0]);
- AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][1], &b->mv[1][1]);
- AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][0], mv0);
- AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][1], mv1);
- AV_COPY32(&s->above_mv_ctx[col * 2 + 0][0], &b->mv[2][0]);
- AV_COPY32(&s->above_mv_ctx[col * 2 + 0][1], &b->mv[2][1]);
- AV_WN32A(&s->above_mv_ctx[col * 2 + 1][0], mv0);
- AV_WN32A(&s->above_mv_ctx[col * 2 + 1][1], mv1);
- } else {
- int n, mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]);
-
- for (n = 0; n < w4 * 2; n++) {
- AV_WN32A(&s->above_mv_ctx[col * 2 + n][0], mv0);
- AV_WN32A(&s->above_mv_ctx[col * 2 + n][1], mv1);
- }
- for (n = 0; n < h4 * 2; n++) {
- AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][0], mv0);
- AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][1], mv1);
- }
- }
- }
-
- // FIXME kinda ugly
- for (y = 0; y < h4; y++) {
- int x, o = (row + y) * s->sb_cols * 8 + col;
- struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[o];
-
- if (b->intra) {
- for (x = 0; x < w4; x++) {
- mv[x].ref[0] =
- mv[x].ref[1] = -1;
- }
- } else if (b->comp) {
- for (x = 0; x < w4; x++) {
- mv[x].ref[0] = b->ref[0];
- mv[x].ref[1] = b->ref[1];
- AV_COPY32(&mv[x].mv[0], &b->mv[3][0]);
- AV_COPY32(&mv[x].mv[1], &b->mv[3][1]);
- }
- } else {
- for (x = 0; x < w4; x++) {
- mv[x].ref[0] = b->ref[0];
- mv[x].ref[1] = -1;
- AV_COPY32(&mv[x].mv[0], &b->mv[3][0]);
- }
- }
- }
-}
-
-// FIXME merge cnt/eob arguments?
-static av_always_inline int
-decode_coeffs_b_generic(VP56RangeCoder *c, int16_t *coef, int n_coeffs,
- int is_tx32x32, int is8bitsperpixel, int bpp, unsigned (*cnt)[6][3],
- unsigned (*eob)[6][2], uint8_t (*p)[6][11],
- int nnz, const int16_t *scan, const int16_t (*nb)[2],
- const int16_t *band_counts, const int16_t *qmul)
-{
- int i = 0, band = 0, band_left = band_counts[band];
- uint8_t *tp = p[0][nnz];
- uint8_t cache[1024];
-
- do {
- int val, rc;
-
- val = vp56_rac_get_prob_branchy(c, tp[0]); // eob
- eob[band][nnz][val]++;
- if (!val)
- break;
-
- skip_eob:
- if (!vp56_rac_get_prob_branchy(c, tp[1])) { // zero
- cnt[band][nnz][0]++;
- if (!--band_left)
- band_left = band_counts[++band];
- cache[scan[i]] = 0;
- nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1;
- tp = p[band][nnz];
- if (++i == n_coeffs)
- break; //invalid input; blocks should end with EOB
- goto skip_eob;
- }
-
- rc = scan[i];
- if (!vp56_rac_get_prob_branchy(c, tp[2])) { // one
- cnt[band][nnz][1]++;
- val = 1;
- cache[rc] = 1;
- } else {
- // fill in p[3-10] (model fill) - only once per frame for each pos
- if (!tp[3])
- memcpy(&tp[3], vp9_model_pareto8[tp[2]], 8);
-
- cnt[band][nnz][2]++;
- if (!vp56_rac_get_prob_branchy(c, tp[3])) { // 2, 3, 4
- if (!vp56_rac_get_prob_branchy(c, tp[4])) {
- cache[rc] = val = 2;
- } else {
- val = 3 + vp56_rac_get_prob(c, tp[5]);
- cache[rc] = 3;
- }
- } else if (!vp56_rac_get_prob_branchy(c, tp[6])) { // cat1/2
- cache[rc] = 4;
- if (!vp56_rac_get_prob_branchy(c, tp[7])) {
- val = 5 + vp56_rac_get_prob(c, 159);
- } else {
- val = 7 + (vp56_rac_get_prob(c, 165) << 1);
- val += vp56_rac_get_prob(c, 145);
- }
- } else { // cat 3-6
- cache[rc] = 5;
- if (!vp56_rac_get_prob_branchy(c, tp[8])) {
- if (!vp56_rac_get_prob_branchy(c, tp[9])) {
- val = 11 + (vp56_rac_get_prob(c, 173) << 2);
- val += (vp56_rac_get_prob(c, 148) << 1);
- val += vp56_rac_get_prob(c, 140);
- } else {
- val = 19 + (vp56_rac_get_prob(c, 176) << 3);
- val += (vp56_rac_get_prob(c, 155) << 2);
- val += (vp56_rac_get_prob(c, 140) << 1);
- val += vp56_rac_get_prob(c, 135);
- }
- } else if (!vp56_rac_get_prob_branchy(c, tp[10])) {
- val = 35 + (vp56_rac_get_prob(c, 180) << 4);
- val += (vp56_rac_get_prob(c, 157) << 3);
- val += (vp56_rac_get_prob(c, 141) << 2);
- val += (vp56_rac_get_prob(c, 134) << 1);
- val += vp56_rac_get_prob(c, 130);
- } else {
- val = 67;
- if (!is8bitsperpixel) {
- if (bpp == 12) {
- val += vp56_rac_get_prob(c, 255) << 17;
- val += vp56_rac_get_prob(c, 255) << 16;
- }
- val += (vp56_rac_get_prob(c, 255) << 15);
- val += (vp56_rac_get_prob(c, 255) << 14);
- }
- val += (vp56_rac_get_prob(c, 254) << 13);
- val += (vp56_rac_get_prob(c, 254) << 12);
- val += (vp56_rac_get_prob(c, 254) << 11);
- val += (vp56_rac_get_prob(c, 252) << 10);
- val += (vp56_rac_get_prob(c, 249) << 9);
- val += (vp56_rac_get_prob(c, 243) << 8);
- val += (vp56_rac_get_prob(c, 230) << 7);
- val += (vp56_rac_get_prob(c, 196) << 6);
- val += (vp56_rac_get_prob(c, 177) << 5);
- val += (vp56_rac_get_prob(c, 153) << 4);
- val += (vp56_rac_get_prob(c, 140) << 3);
- val += (vp56_rac_get_prob(c, 133) << 2);
- val += (vp56_rac_get_prob(c, 130) << 1);
- val += vp56_rac_get_prob(c, 129);
- }
- }
- }
-#define STORE_COEF(c, i, v) do { \
- if (is8bitsperpixel) { \
- c[i] = v; \
- } else { \
- AV_WN32A(&c[i * 2], v); \
- } \
-} while (0)
- if (!--band_left)
- band_left = band_counts[++band];
- if (is_tx32x32)
- STORE_COEF(coef, rc, ((vp8_rac_get(c) ? -val : val) * qmul[!!i]) / 2);
- else
- STORE_COEF(coef, rc, (vp8_rac_get(c) ? -val : val) * qmul[!!i]);
- nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1;
- tp = p[band][nnz];
- } while (++i < n_coeffs);
-
- return i;
-}
-
-static int decode_coeffs_b_8bpp(VP9Context *s, int16_t *coef, int n_coeffs,
- unsigned (*cnt)[6][3], unsigned (*eob)[6][2],
- uint8_t (*p)[6][11], int nnz, const int16_t *scan,
- const int16_t (*nb)[2], const int16_t *band_counts,
- const int16_t *qmul)
-{
- return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 0, 1, 8, cnt, eob, p,
- nnz, scan, nb, band_counts, qmul);
-}
-
-static int decode_coeffs_b32_8bpp(VP9Context *s, int16_t *coef, int n_coeffs,
- unsigned (*cnt)[6][3], unsigned (*eob)[6][2],
- uint8_t (*p)[6][11], int nnz, const int16_t *scan,
- const int16_t (*nb)[2], const int16_t *band_counts,
- const int16_t *qmul)
-{
- return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 1, 1, 8, cnt, eob, p,
- nnz, scan, nb, band_counts, qmul);
-}
-
-static int decode_coeffs_b_16bpp(VP9Context *s, int16_t *coef, int n_coeffs,
- unsigned (*cnt)[6][3], unsigned (*eob)[6][2],
- uint8_t (*p)[6][11], int nnz, const int16_t *scan,
- const int16_t (*nb)[2], const int16_t *band_counts,
- const int16_t *qmul)
-{
- return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 0, 0, s->bpp, cnt, eob, p,
- nnz, scan, nb, band_counts, qmul);
-}
-
-static int decode_coeffs_b32_16bpp(VP9Context *s, int16_t *coef, int n_coeffs,
- unsigned (*cnt)[6][3], unsigned (*eob)[6][2],
- uint8_t (*p)[6][11], int nnz, const int16_t *scan,
- const int16_t (*nb)[2], const int16_t *band_counts,
- const int16_t *qmul)
-{
- return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 1, 0, s->bpp, cnt, eob, p,
- nnz, scan, nb, band_counts, qmul);
-}
-
-static av_always_inline int decode_coeffs(AVCodecContext *ctx, int is8bitsperpixel)
-{
- VP9Context *s = ctx->priv_data;
- VP9Block *b = s->b;
- int row = s->row, col = s->col;
- uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra];
- unsigned (*c)[6][3] = s->counts.coef[b->tx][0 /* y */][!b->intra];
- unsigned (*e)[6][2] = s->counts.eob[b->tx][0 /* y */][!b->intra];
- int w4 = bwh_tab[1][b->bs][0] << 1, h4 = bwh_tab[1][b->bs][1] << 1;
- int end_x = FFMIN(2 * (s->cols - col), w4);
- int end_y = FFMIN(2 * (s->rows - row), h4);
- int n, pl, x, y, res;
- int16_t (*qmul)[2] = s->segmentation.feat[b->seg_id].qmul;
- int tx = 4 * s->lossless + b->tx;
- const int16_t * const *yscans = vp9_scans[tx];
- const int16_t (* const *ynbs)[2] = vp9_scans_nb[tx];
- const int16_t *uvscan = vp9_scans[b->uvtx][DCT_DCT];
- const int16_t (*uvnb)[2] = vp9_scans_nb[b->uvtx][DCT_DCT];
- uint8_t *a = &s->above_y_nnz_ctx[col * 2];
- uint8_t *l = &s->left_y_nnz_ctx[(row & 7) << 1];
- static const int16_t band_counts[4][8] = {
- { 1, 2, 3, 4, 3, 16 - 13 },
- { 1, 2, 3, 4, 11, 64 - 21 },
- { 1, 2, 3, 4, 11, 256 - 21 },
- { 1, 2, 3, 4, 11, 1024 - 21 },
- };
- const int16_t *y_band_counts = band_counts[b->tx];
- const int16_t *uv_band_counts = band_counts[b->uvtx];
- int bytesperpixel = is8bitsperpixel ? 1 : 2;
- int total_coeff = 0;
-
-#define MERGE(la, end, step, rd) \
- for (n = 0; n < end; n += step) \
- la[n] = !!rd(&la[n])
-#define MERGE_CTX(step, rd) \
- do { \
- MERGE(l, end_y, step, rd); \
- MERGE(a, end_x, step, rd); \
- } while (0)
-
-#define DECODE_Y_COEF_LOOP(step, mode_index, v) \
- for (n = 0, y = 0; y < end_y; y += step) { \
- for (x = 0; x < end_x; x += step, n += step * step) { \
- enum TxfmType txtp = vp9_intra_txfm_type[b->mode[mode_index]]; \
- res = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \
- (s, s->block + 16 * n * bytesperpixel, 16 * step * step, \
- c, e, p, a[x] + l[y], yscans[txtp], \
- ynbs[txtp], y_band_counts, qmul[0]); \
- a[x] = l[y] = !!res; \
- total_coeff |= !!res; \
- if (step >= 4) { \
- AV_WN16A(&s->eob[n], res); \
- } else { \
- s->eob[n] = res; \
- } \
- } \
- }
-
-#define SPLAT(la, end, step, cond) \
- if (step == 2) { \
- for (n = 1; n < end; n += step) \
- la[n] = la[n - 1]; \
- } else if (step == 4) { \
- if (cond) { \
- for (n = 0; n < end; n += step) \
- AV_WN32A(&la[n], la[n] * 0x01010101); \
- } else { \
- for (n = 0; n < end; n += step) \
- memset(&la[n + 1], la[n], FFMIN(end - n - 1, 3)); \
- } \
- } else /* step == 8 */ { \
- if (cond) { \
- if (HAVE_FAST_64BIT) { \
- for (n = 0; n < end; n += step) \
- AV_WN64A(&la[n], la[n] * 0x0101010101010101ULL); \
- } else { \
- for (n = 0; n < end; n += step) { \
- uint32_t v32 = la[n] * 0x01010101; \
- AV_WN32A(&la[n], v32); \
- AV_WN32A(&la[n + 4], v32); \
- } \
- } \
- } else { \
- for (n = 0; n < end; n += step) \
- memset(&la[n + 1], la[n], FFMIN(end - n - 1, 7)); \
- } \
- }
-#define SPLAT_CTX(step) \
- do { \
- SPLAT(a, end_x, step, end_x == w4); \
- SPLAT(l, end_y, step, end_y == h4); \
- } while (0)
-
- /* y tokens */
- switch (b->tx) {
- case TX_4X4:
- DECODE_Y_COEF_LOOP(1, b->bs > BS_8x8 ? n : 0,);
- break;
- case TX_8X8:
- MERGE_CTX(2, AV_RN16A);
- DECODE_Y_COEF_LOOP(2, 0,);
- SPLAT_CTX(2);
- break;
- case TX_16X16:
- MERGE_CTX(4, AV_RN32A);
- DECODE_Y_COEF_LOOP(4, 0,);
- SPLAT_CTX(4);
- break;
- case TX_32X32:
- MERGE_CTX(8, AV_RN64A);
- DECODE_Y_COEF_LOOP(8, 0, 32);
- SPLAT_CTX(8);
- break;
- }
-
-#define DECODE_UV_COEF_LOOP(step, v) \
- for (n = 0, y = 0; y < end_y; y += step) { \
- for (x = 0; x < end_x; x += step, n += step * step) { \
- res = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \
- (s, s->uvblock[pl] + 16 * n * bytesperpixel, \
- 16 * step * step, c, e, p, a[x] + l[y], \
- uvscan, uvnb, uv_band_counts, qmul[1]); \
- a[x] = l[y] = !!res; \
- total_coeff |= !!res; \
- if (step >= 4) { \
- AV_WN16A(&s->uveob[pl][n], res); \
- } else { \
- s->uveob[pl][n] = res; \
- } \
- } \
- }
-
- p = s->prob.coef[b->uvtx][1 /* uv */][!b->intra];
- c = s->counts.coef[b->uvtx][1 /* uv */][!b->intra];
- e = s->counts.eob[b->uvtx][1 /* uv */][!b->intra];
- w4 >>= s->ss_h;
- end_x >>= s->ss_h;
- h4 >>= s->ss_v;
- end_y >>= s->ss_v;
- for (pl = 0; pl < 2; pl++) {
- a = &s->above_uv_nnz_ctx[pl][col << !s->ss_h];
- l = &s->left_uv_nnz_ctx[pl][(row & 7) << !s->ss_v];
- switch (b->uvtx) {
- case TX_4X4:
- DECODE_UV_COEF_LOOP(1,);
- break;
- case TX_8X8:
- MERGE_CTX(2, AV_RN16A);
- DECODE_UV_COEF_LOOP(2,);
- SPLAT_CTX(2);
- break;
- case TX_16X16:
- MERGE_CTX(4, AV_RN32A);
- DECODE_UV_COEF_LOOP(4,);
- SPLAT_CTX(4);
- break;
- case TX_32X32:
- MERGE_CTX(8, AV_RN64A);
- DECODE_UV_COEF_LOOP(8, 32);
- SPLAT_CTX(8);
- break;
- }
- }
-
- return total_coeff;
-}
-
-static int decode_coeffs_8bpp(AVCodecContext *ctx)
-{
- return decode_coeffs(ctx, 1);
-}
-
-static int decode_coeffs_16bpp(AVCodecContext *ctx)
-{
- return decode_coeffs(ctx, 0);
-}
-
-static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t **a,
- uint8_t *dst_edge, ptrdiff_t stride_edge,
- uint8_t *dst_inner, ptrdiff_t stride_inner,
- uint8_t *l, int col, int x, int w,
- int row, int y, enum TxfmMode tx,
- int p, int ss_h, int ss_v, int bytesperpixel)
-{
- int have_top = row > 0 || y > 0;
- int have_left = col > s->tiling.tile_col_start || x > 0;
- int have_right = x < w - 1;
- int bpp = s->bpp;
- static const uint8_t mode_conv[10][2 /* have_left */][2 /* have_top */] = {
- [VERT_PRED] = { { DC_127_PRED, VERT_PRED },
- { DC_127_PRED, VERT_PRED } },
- [HOR_PRED] = { { DC_129_PRED, DC_129_PRED },
- { HOR_PRED, HOR_PRED } },
- [DC_PRED] = { { DC_128_PRED, TOP_DC_PRED },
- { LEFT_DC_PRED, DC_PRED } },
- [DIAG_DOWN_LEFT_PRED] = { { DC_127_PRED, DIAG_DOWN_LEFT_PRED },
- { DC_127_PRED, DIAG_DOWN_LEFT_PRED } },
- [DIAG_DOWN_RIGHT_PRED] = { { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED },
- { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED } },
- [VERT_RIGHT_PRED] = { { VERT_RIGHT_PRED, VERT_RIGHT_PRED },
- { VERT_RIGHT_PRED, VERT_RIGHT_PRED } },
- [HOR_DOWN_PRED] = { { HOR_DOWN_PRED, HOR_DOWN_PRED },
- { HOR_DOWN_PRED, HOR_DOWN_PRED } },
- [VERT_LEFT_PRED] = { { DC_127_PRED, VERT_LEFT_PRED },
- { DC_127_PRED, VERT_LEFT_PRED } },
- [HOR_UP_PRED] = { { DC_129_PRED, DC_129_PRED },
- { HOR_UP_PRED, HOR_UP_PRED } },
- [TM_VP8_PRED] = { { DC_129_PRED, VERT_PRED },
- { HOR_PRED, TM_VP8_PRED } },
- };
- static const struct {
- uint8_t needs_left:1;
- uint8_t needs_top:1;
- uint8_t needs_topleft:1;
- uint8_t needs_topright:1;
- uint8_t invert_left:1;
- } edges[N_INTRA_PRED_MODES] = {
- [VERT_PRED] = { .needs_top = 1 },
- [HOR_PRED] = { .needs_left = 1 },
- [DC_PRED] = { .needs_top = 1, .needs_left = 1 },
- [DIAG_DOWN_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 },
- [DIAG_DOWN_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 },
- [VERT_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 },
- [HOR_DOWN_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 },
- [VERT_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 },
- [HOR_UP_PRED] = { .needs_left = 1, .invert_left = 1 },
- [TM_VP8_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 },
- [LEFT_DC_PRED] = { .needs_left = 1 },
- [TOP_DC_PRED] = { .needs_top = 1 },
- [DC_128_PRED] = { 0 },
- [DC_127_PRED] = { 0 },
- [DC_129_PRED] = { 0 }
- };
-
- av_assert2(mode >= 0 && mode < 10);
- mode = mode_conv[mode][have_left][have_top];
- if (edges[mode].needs_top) {
- uint8_t *top, *topleft;
- int n_px_need = 4 << tx, n_px_have = (((s->cols - col) << !ss_h) - x) * 4;
- int n_px_need_tr = 0;
-
- if (tx == TX_4X4 && edges[mode].needs_topright && have_right)
- n_px_need_tr = 4;
-
- // if top of sb64-row, use s->intra_pred_data[] instead of
- // dst[-stride] for intra prediction (it contains pre- instead of
- // post-loopfilter data)
- if (have_top) {
- top = !(row & 7) && !y ?
- s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel :
- y == 0 ? &dst_edge[-stride_edge] : &dst_inner[-stride_inner];
- if (have_left)
- topleft = !(row & 7) && !y ?
- s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel :
- y == 0 || x == 0 ? &dst_edge[-stride_edge] :
- &dst_inner[-stride_inner];
- }
-
- if (have_top &&
- (!edges[mode].needs_topleft || (have_left && top == topleft)) &&
- (tx != TX_4X4 || !edges[mode].needs_topright || have_right) &&
- n_px_need + n_px_need_tr <= n_px_have) {
- *a = top;
- } else {
- if (have_top) {
- if (n_px_need <= n_px_have) {
- memcpy(*a, top, n_px_need * bytesperpixel);
- } else {
-#define memset_bpp(c, i1, v, i2, num) do { \
- if (bytesperpixel == 1) { \
- memset(&(c)[(i1)], (v)[(i2)], (num)); \
- } else { \
- int n, val = AV_RN16A(&(v)[(i2) * 2]); \
- for (n = 0; n < (num); n++) { \
- AV_WN16A(&(c)[((i1) + n) * 2], val); \
- } \
- } \
-} while (0)
- memcpy(*a, top, n_px_have * bytesperpixel);
- memset_bpp(*a, n_px_have, (*a), n_px_have - 1, n_px_need - n_px_have);
- }
- } else {
-#define memset_val(c, val, num) do { \
- if (bytesperpixel == 1) { \
- memset((c), (val), (num)); \
- } else { \
- int n; \
- for (n = 0; n < (num); n++) { \
- AV_WN16A(&(c)[n * 2], (val)); \
- } \
- } \
-} while (0)
- memset_val(*a, (128 << (bpp - 8)) - 1, n_px_need);
- }
- if (edges[mode].needs_topleft) {
- if (have_left && have_top) {
-#define assign_bpp(c, i1, v, i2) do { \
- if (bytesperpixel == 1) { \
- (c)[(i1)] = (v)[(i2)]; \
- } else { \
- AV_COPY16(&(c)[(i1) * 2], &(v)[(i2) * 2]); \
- } \
-} while (0)
- assign_bpp(*a, -1, topleft, -1);
- } else {
-#define assign_val(c, i, v) do { \
- if (bytesperpixel == 1) { \
- (c)[(i)] = (v); \
- } else { \
- AV_WN16A(&(c)[(i) * 2], (v)); \
- } \
-} while (0)
- assign_val((*a), -1, (128 << (bpp - 8)) + (have_top ? +1 : -1));
- }
- }
- if (tx == TX_4X4 && edges[mode].needs_topright) {
- if (have_top && have_right &&
- n_px_need + n_px_need_tr <= n_px_have) {
- memcpy(&(*a)[4 * bytesperpixel], &top[4 * bytesperpixel], 4 * bytesperpixel);
- } else {
- memset_bpp(*a, 4, *a, 3, 4);
- }
- }
- }
- }
- if (edges[mode].needs_left) {
- if (have_left) {
- int n_px_need = 4 << tx, i, n_px_have = (((s->rows - row) << !ss_v) - y) * 4;
- uint8_t *dst = x == 0 ? dst_edge : dst_inner;
- ptrdiff_t stride = x == 0 ? stride_edge : stride_inner;
-
- if (edges[mode].invert_left) {
- if (n_px_need <= n_px_have) {
- for (i = 0; i < n_px_need; i++)
- assign_bpp(l, i, &dst[i * stride], -1);
- } else {
- for (i = 0; i < n_px_have; i++)
- assign_bpp(l, i, &dst[i * stride], -1);
- memset_bpp(l, n_px_have, l, n_px_have - 1, n_px_need - n_px_have);
- }
- } else {
- if (n_px_need <= n_px_have) {
- for (i = 0; i < n_px_need; i++)
- assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1);
- } else {
- for (i = 0; i < n_px_have; i++)
- assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1);
- memset_bpp(l, 0, l, n_px_need - n_px_have, n_px_need - n_px_have);
- }
- }
- } else {
- memset_val(l, (128 << (bpp - 8)) + 1, 4 << tx);
- }
- }
-
- return mode;
-}
-
-static av_always_inline void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off,
- ptrdiff_t uv_off, int bytesperpixel)
-{
- VP9Context *s = ctx->priv_data;
- VP9Block *b = s->b;
- int row = s->row, col = s->col;
- int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n;
- int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2);
- int end_x = FFMIN(2 * (s->cols - col), w4);
- int end_y = FFMIN(2 * (s->rows - row), h4);
- int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless;
- int uvstep1d = 1 << b->uvtx, p;
- uint8_t *dst = s->dst[0], *dst_r = s->frames[CUR_FRAME].tf.f->data[0] + y_off;
- LOCAL_ALIGNED_32(uint8_t, a_buf, [96]);
- LOCAL_ALIGNED_32(uint8_t, l, [64]);
-
- for (n = 0, y = 0; y < end_y; y += step1d) {
- uint8_t *ptr = dst, *ptr_r = dst_r;
- for (x = 0; x < end_x; x += step1d, ptr += 4 * step1d * bytesperpixel,
- ptr_r += 4 * step1d * bytesperpixel, n += step) {
- int mode = b->mode[b->bs > BS_8x8 && b->tx == TX_4X4 ?
- y * 2 + x : 0];
- uint8_t *a = &a_buf[32];
- enum TxfmType txtp = vp9_intra_txfm_type[mode];
- int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
-
- mode = check_intra_mode(s, mode, &a, ptr_r,
- s->frames[CUR_FRAME].tf.f->linesize[0],
- ptr, s->y_stride, l,
- col, x, w4, row, y, b->tx, 0, 0, 0, bytesperpixel);
- s->dsp.intra_pred[b->tx][mode](ptr, s->y_stride, l, a);
- if (eob)
- s->dsp.itxfm_add[tx][txtp](ptr, s->y_stride,
- s->block + 16 * n * bytesperpixel, eob);
- }
- dst_r += 4 * step1d * s->frames[CUR_FRAME].tf.f->linesize[0];
- dst += 4 * step1d * s->y_stride;
- }
-
- // U/V
- w4 >>= s->ss_h;
- end_x >>= s->ss_h;
- end_y >>= s->ss_v;
- step = 1 << (b->uvtx * 2);
- for (p = 0; p < 2; p++) {
- dst = s->dst[1 + p];
- dst_r = s->frames[CUR_FRAME].tf.f->data[1 + p] + uv_off;
- for (n = 0, y = 0; y < end_y; y += uvstep1d) {
- uint8_t *ptr = dst, *ptr_r = dst_r;
- for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d * bytesperpixel,
- ptr_r += 4 * uvstep1d * bytesperpixel, n += step) {
- int mode = b->uvmode;
- uint8_t *a = &a_buf[32];
- int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n];
-
- mode = check_intra_mode(s, mode, &a, ptr_r,
- s->frames[CUR_FRAME].tf.f->linesize[1],
- ptr, s->uv_stride, l, col, x, w4, row, y,
- b->uvtx, p + 1, s->ss_h, s->ss_v, bytesperpixel);
- s->dsp.intra_pred[b->uvtx][mode](ptr, s->uv_stride, l, a);
- if (eob)
- s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride,
- s->uvblock[p] + 16 * n * bytesperpixel, eob);
- }
- dst_r += 4 * uvstep1d * s->frames[CUR_FRAME].tf.f->linesize[1];
- dst += 4 * uvstep1d * s->uv_stride;
- }
- }
-}
-
-static void intra_recon_8bpp(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
-{
- intra_recon(ctx, y_off, uv_off, 1);
-}
-
-static void intra_recon_16bpp(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
-{
- intra_recon(ctx, y_off, uv_off, 2);
-}
-
-static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func smc,
- uint8_t *dst, ptrdiff_t dst_stride,
- const uint8_t *ref, ptrdiff_t ref_stride,
- ThreadFrame *ref_frame,
- ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv,
- int px, int py, int pw, int ph,
- int bw, int bh, int w, int h, int bytesperpixel,
- const uint16_t *scale, const uint8_t *step)
-{
-#define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14)
- int mx, my;
- int refbw_m1, refbh_m1;
- int th;
- VP56mv mv;
-
- mv.x = av_clip(in_mv->x, -(x + pw - px + 4) << 3, (s->cols * 8 - x + px + 3) << 3);
- mv.y = av_clip(in_mv->y, -(y + ph - py + 4) << 3, (s->rows * 8 - y + py + 3) << 3);
- // BUG libvpx seems to scale the two components separately. This introduces
- // rounding errors but we have to reproduce them to be exactly compatible
- // with the output from libvpx...
- mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0);
- my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1);
-
- y = my >> 4;
- x = mx >> 4;
- ref += y * ref_stride + x * bytesperpixel;
- mx &= 15;
- my &= 15;
- refbw_m1 = ((bw - 1) * step[0] + mx) >> 4;
- refbh_m1 = ((bh - 1) * step[1] + my) >> 4;
- // FIXME bilinear filter only needs 0/1 pixels, not 3/4
- // we use +7 because the last 7 pixels of each sbrow can be changed in
- // the longest loopfilter of the next sbrow
- th = (y + refbh_m1 + 4 + 7) >> 6;
- ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);
- if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 4 >= h - refbh_m1) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
- ref - 3 * ref_stride - 3 * bytesperpixel,
- 288, ref_stride,
- refbw_m1 + 8, refbh_m1 + 8,
- x - 3, y - 3, w, h);
- ref = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel;
- ref_stride = 288;
- }
- smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]);
-}
-
-static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func smc,
- uint8_t *dst_u, uint8_t *dst_v,
- ptrdiff_t dst_stride,
- const uint8_t *ref_u, ptrdiff_t src_stride_u,
- const uint8_t *ref_v, ptrdiff_t src_stride_v,
- ThreadFrame *ref_frame,
- ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv,
- int px, int py, int pw, int ph,
- int bw, int bh, int w, int h, int bytesperpixel,
- const uint16_t *scale, const uint8_t *step)
-{
- int mx, my;
- int refbw_m1, refbh_m1;
- int th;
- VP56mv mv;
-
- if (s->ss_h) {
- // BUG https://code.google.com/p/webm/issues/detail?id=820
- mv.x = av_clip(in_mv->x, -(x + pw - px + 4) << 4, (s->cols * 4 - x + px + 3) << 4);
- mx = scale_mv(mv.x, 0) + (scale_mv(x * 16, 0) & ~15) + (scale_mv(x * 32, 0) & 15);
- } else {
- mv.x = av_clip(in_mv->x, -(x + pw - px + 4) << 3, (s->cols * 8 - x + px + 3) << 3);
- mx = scale_mv(mv.x << 1, 0) + scale_mv(x * 16, 0);
- }
- if (s->ss_v) {
- // BUG https://code.google.com/p/webm/issues/detail?id=820
- mv.y = av_clip(in_mv->y, -(y + ph - py + 4) << 4, (s->rows * 4 - y + py + 3) << 4);
- my = scale_mv(mv.y, 1) + (scale_mv(y * 16, 1) & ~15) + (scale_mv(y * 32, 1) & 15);
- } else {
- mv.y = av_clip(in_mv->y, -(y + ph - py + 4) << 3, (s->rows * 8 - y + py + 3) << 3);
- my = scale_mv(mv.y << 1, 1) + scale_mv(y * 16, 1);
- }
-#undef scale_mv
- y = my >> 4;
- x = mx >> 4;
- ref_u += y * src_stride_u + x * bytesperpixel;
- ref_v += y * src_stride_v + x * bytesperpixel;
- mx &= 15;
- my &= 15;
- refbw_m1 = ((bw - 1) * step[0] + mx) >> 4;
- refbh_m1 = ((bh - 1) * step[1] + my) >> 4;
- // FIXME bilinear filter only needs 0/1 pixels, not 3/4
- // we use +7 because the last 7 pixels of each sbrow can be changed in
- // the longest loopfilter of the next sbrow
- th = (y + refbh_m1 + 4 + 7) >> (6 - s->ss_v);
- ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);
- if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 4 >= h - refbh_m1) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
- ref_u - 3 * src_stride_u - 3 * bytesperpixel,
- 288, src_stride_u,
- refbw_m1 + 8, refbh_m1 + 8,
- x - 3, y - 3, w, h);
- ref_u = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel;
- smc(dst_u, dst_stride, ref_u, 288, bh, mx, my, step[0], step[1]);
-
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
- ref_v - 3 * src_stride_v - 3 * bytesperpixel,
- 288, src_stride_v,
- refbw_m1 + 8, refbh_m1 + 8,
- x - 3, y - 3, w, h);
- ref_v = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel;
- smc(dst_v, dst_stride, ref_v, 288, bh, mx, my, step[0], step[1]);
- } else {
- smc(dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my, step[0], step[1]);
- smc(dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my, step[0], step[1]);
- }
-}
-
-#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \
- px, py, pw, ph, bw, bh, w, h, i) \
- mc_luma_scaled(s, s->dsp.s##mc, dst, dst_ls, src, src_ls, tref, row, col, \
- mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \
- s->mvscale[b->ref[i]], s->mvstep[b->ref[i]])
-#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \
- row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \
- mc_chroma_scaled(s, s->dsp.s##mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \
- row, col, mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \
- s->mvscale[b->ref[i]], s->mvstep[b->ref[i]])
-#define SCALED 1
-#define FN(x) x##_scaled_8bpp
-#define BYTES_PER_PIXEL 1
-#include "vp9_mc_template.c"
-#undef FN
-#undef BYTES_PER_PIXEL
-#define FN(x) x##_scaled_16bpp
-#define BYTES_PER_PIXEL 2
-#include "vp9_mc_template.c"
-#undef mc_luma_dir
-#undef mc_chroma_dir
-#undef FN
-#undef BYTES_PER_PIXEL
-#undef SCALED
-
-static av_always_inline void mc_luma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2],
- uint8_t *dst, ptrdiff_t dst_stride,
- const uint8_t *ref, ptrdiff_t ref_stride,
- ThreadFrame *ref_frame,
- ptrdiff_t y, ptrdiff_t x, const VP56mv *mv,
- int bw, int bh, int w, int h, int bytesperpixel)
-{
- int mx = mv->x, my = mv->y, th;
-
- y += my >> 3;
- x += mx >> 3;
- ref += y * ref_stride + x * bytesperpixel;
- mx &= 7;
- my &= 7;
- // FIXME bilinear filter only needs 0/1 pixels, not 3/4
- // we use +7 because the last 7 pixels of each sbrow can be changed in
- // the longest loopfilter of the next sbrow
- th = (y + bh + 4 * !!my + 7) >> 6;
- ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);
- if (x < !!mx * 3 || y < !!my * 3 ||
- x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
- ref - !!my * 3 * ref_stride - !!mx * 3 * bytesperpixel,
- 160, ref_stride,
- bw + !!mx * 7, bh + !!my * 7,
- x - !!mx * 3, y - !!my * 3, w, h);
- ref = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel;
- ref_stride = 160;
- }
- mc[!!mx][!!my](dst, dst_stride, ref, ref_stride, bh, mx << 1, my << 1);
-}
-
-static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2],
- uint8_t *dst_u, uint8_t *dst_v,
- ptrdiff_t dst_stride,
- const uint8_t *ref_u, ptrdiff_t src_stride_u,
- const uint8_t *ref_v, ptrdiff_t src_stride_v,
- ThreadFrame *ref_frame,
- ptrdiff_t y, ptrdiff_t x, const VP56mv *mv,
- int bw, int bh, int w, int h, int bytesperpixel)
-{
- int mx = mv->x << !s->ss_h, my = mv->y << !s->ss_v, th;
-
- y += my >> 4;
- x += mx >> 4;
- ref_u += y * src_stride_u + x * bytesperpixel;
- ref_v += y * src_stride_v + x * bytesperpixel;
- mx &= 15;
- my &= 15;
- // FIXME bilinear filter only needs 0/1 pixels, not 3/4
- // we use +7 because the last 7 pixels of each sbrow can be changed in
- // the longest loopfilter of the next sbrow
- th = (y + bh + 4 * !!my + 7) >> (6 - s->ss_v);
- ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);
- if (x < !!mx * 3 || y < !!my * 3 ||
- x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) {
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
- ref_u - !!my * 3 * src_stride_u - !!mx * 3 * bytesperpixel,
- 160, src_stride_u,
- bw + !!mx * 7, bh + !!my * 7,
- x - !!mx * 3, y - !!my * 3, w, h);
- ref_u = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel;
- mc[!!mx][!!my](dst_u, dst_stride, ref_u, 160, bh, mx, my);
-
- s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
- ref_v - !!my * 3 * src_stride_v - !!mx * 3 * bytesperpixel,
- 160, src_stride_v,
- bw + !!mx * 7, bh + !!my * 7,
- x - !!mx * 3, y - !!my * 3, w, h);
- ref_v = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel;
- mc[!!mx][!!my](dst_v, dst_stride, ref_v, 160, bh, mx, my);
- } else {
- mc[!!mx][!!my](dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my);
- mc[!!mx][!!my](dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my);
- }
-}
-
-#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \
- px, py, pw, ph, bw, bh, w, h, i) \
- mc_luma_unscaled(s, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \
- mv, bw, bh, w, h, bytesperpixel)
-#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \
- row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \
- mc_chroma_unscaled(s, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \
- row, col, mv, bw, bh, w, h, bytesperpixel)
-#define SCALED 0
-#define FN(x) x##_8bpp
-#define BYTES_PER_PIXEL 1
-#include "vp9_mc_template.c"
-#undef FN
-#undef BYTES_PER_PIXEL
-#define FN(x) x##_16bpp
-#define BYTES_PER_PIXEL 2
-#include "vp9_mc_template.c"
-#undef mc_luma_dir_dir
-#undef mc_chroma_dir_dir
-#undef FN
-#undef BYTES_PER_PIXEL
-#undef SCALED
-
-static av_always_inline void inter_recon(AVCodecContext *ctx, int bytesperpixel)
-{
- VP9Context *s = ctx->priv_data;
- VP9Block *b = s->b;
- int row = s->row, col = s->col;
-
- if (s->mvscale[b->ref[0]][0] || (b->comp && s->mvscale[b->ref[1]][0])) {
- if (bytesperpixel == 1) {
- inter_pred_scaled_8bpp(ctx);
- } else {
- inter_pred_scaled_16bpp(ctx);
- }
- } else {
- if (bytesperpixel == 1) {
- inter_pred_8bpp(ctx);
- } else {
- inter_pred_16bpp(ctx);
- }
- }
- if (!b->skip) {
- /* mostly copied intra_recon() */
-
- int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n;
- int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2);
- int end_x = FFMIN(2 * (s->cols - col), w4);
- int end_y = FFMIN(2 * (s->rows - row), h4);
- int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless;
- int uvstep1d = 1 << b->uvtx, p;
- uint8_t *dst = s->dst[0];
-
- // y itxfm add
- for (n = 0, y = 0; y < end_y; y += step1d) {
- uint8_t *ptr = dst;
- for (x = 0; x < end_x; x += step1d,
- ptr += 4 * step1d * bytesperpixel, n += step) {
- int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
-
- if (eob)
- s->dsp.itxfm_add[tx][DCT_DCT](ptr, s->y_stride,
- s->block + 16 * n * bytesperpixel, eob);
- }
- dst += 4 * s->y_stride * step1d;
- }
-
- // uv itxfm add
- end_x >>= s->ss_h;
- end_y >>= s->ss_v;
- step = 1 << (b->uvtx * 2);
- for (p = 0; p < 2; p++) {
- dst = s->dst[p + 1];
- for (n = 0, y = 0; y < end_y; y += uvstep1d) {
- uint8_t *ptr = dst;
- for (x = 0; x < end_x; x += uvstep1d,
- ptr += 4 * uvstep1d * bytesperpixel, n += step) {
- int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n];
-
- if (eob)
- s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride,
- s->uvblock[p] + 16 * n * bytesperpixel, eob);
- }
- dst += 4 * uvstep1d * s->uv_stride;
- }
- }
- }
-}
-
-static void inter_recon_8bpp(AVCodecContext *ctx)
-{
- inter_recon(ctx, 1);
-}
-
-static void inter_recon_16bpp(AVCodecContext *ctx)
-{
- inter_recon(ctx, 2);
-}
-
-static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_v,
- int row_and_7, int col_and_7,
- int w, int h, int col_end, int row_end,
- enum TxfmMode tx, int skip_inter)
-{
- static const unsigned wide_filter_col_mask[2] = { 0x11, 0x01 };
- static const unsigned wide_filter_row_mask[2] = { 0x03, 0x07 };
-
- // FIXME I'm pretty sure all loops can be replaced by a single LUT if
- // we make VP9Filter.mask uint64_t (i.e. row/col all single variable)
- // and make the LUT 5-indexed (bl, bp, is_uv, tx and row/col), and then
- // use row_and_7/col_and_7 as shifts (1*col_and_7+8*row_and_7)
-
- // the intended behaviour of the vp9 loopfilter is to work on 8-pixel
- // edges. This means that for UV, we work on two subsampled blocks at
- // a time, and we only use the topleft block's mode information to set
- // things like block strength. Thus, for any block size smaller than
- // 16x16, ignore the odd portion of the block.
- if (tx == TX_4X4 && (ss_v | ss_h)) {
- if (h == ss_v) {
- if (row_and_7 & 1)
- return;
- if (!row_end)
- h += 1;
- }
- if (w == ss_h) {
- if (col_and_7 & 1)
- return;
- if (!col_end)
- w += 1;
- }
- }
-
- if (tx == TX_4X4 && !skip_inter) {
- int t = 1 << col_and_7, m_col = (t << w) - t, y;
- // on 32-px edges, use the 8-px wide loopfilter; else, use 4-px wide
- int m_row_8 = m_col & wide_filter_col_mask[ss_h], m_row_4 = m_col - m_row_8;
-
- for (y = row_and_7; y < h + row_and_7; y++) {
- int col_mask_id = 2 - !(y & wide_filter_row_mask[ss_v]);
-
- mask[0][y][1] |= m_row_8;
- mask[0][y][2] |= m_row_4;
- // for odd lines, if the odd col is not being filtered,
- // skip odd row also:
- // .---. <-- a
- // | |
- // |___| <-- b
- // ^ ^
- // c d
- //
- // if a/c are even row/col and b/d are odd, and d is skipped,
- // e.g. right edge of size-66x66.webm, then skip b also (bug)
- if ((ss_h & ss_v) && (col_end & 1) && (y & 1)) {
- mask[1][y][col_mask_id] |= (t << (w - 1)) - t;
- } else {
- mask[1][y][col_mask_id] |= m_col;
- }
- if (!ss_h)
- mask[0][y][3] |= m_col;
- if (!ss_v) {
- if (ss_h && (col_end & 1))
- mask[1][y][3] |= (t << (w - 1)) - t;
- else
- mask[1][y][3] |= m_col;
- }
- }
- } else {
- int y, t = 1 << col_and_7, m_col = (t << w) - t;
-
- if (!skip_inter) {
- int mask_id = (tx == TX_8X8);
- static const unsigned masks[4] = { 0xff, 0x55, 0x11, 0x01 };
- int l2 = tx + ss_h - 1, step1d;
- int m_row = m_col & masks[l2];
-
- // at odd UV col/row edges tx16/tx32 loopfilter edges, force
- // 8wd loopfilter to prevent going off the visible edge.
- if (ss_h && tx > TX_8X8 && (w ^ (w - 1)) == 1) {
- int m_row_16 = ((t << (w - 1)) - t) & masks[l2];
- int m_row_8 = m_row - m_row_16;
-
- for (y = row_and_7; y < h + row_and_7; y++) {
- mask[0][y][0] |= m_row_16;
- mask[0][y][1] |= m_row_8;
- }
- } else {
- for (y = row_and_7; y < h + row_and_7; y++)
- mask[0][y][mask_id] |= m_row;
- }
-
- l2 = tx + ss_v - 1;
- step1d = 1 << l2;
- if (ss_v && tx > TX_8X8 && (h ^ (h - 1)) == 1) {
- for (y = row_and_7; y < h + row_and_7 - 1; y += step1d)
- mask[1][y][0] |= m_col;
- if (y - row_and_7 == h - 1)
- mask[1][y][1] |= m_col;
- } else {
- for (y = row_and_7; y < h + row_and_7; y += step1d)
- mask[1][y][mask_id] |= m_col;
- }
- } else if (tx != TX_4X4) {
- int mask_id;
-
- mask_id = (tx == TX_8X8) || (h == ss_v);
- mask[1][row_and_7][mask_id] |= m_col;
- mask_id = (tx == TX_8X8) || (w == ss_h);
- for (y = row_and_7; y < h + row_and_7; y++)
- mask[0][y][mask_id] |= t;
- } else {
- int t8 = t & wide_filter_col_mask[ss_h], t4 = t - t8;
-
- for (y = row_and_7; y < h + row_and_7; y++) {
- mask[0][y][2] |= t4;
- mask[0][y][1] |= t8;
- }
- mask[1][row_and_7][2 - !(row_and_7 & wide_filter_row_mask[ss_v])] |= m_col;
- }
- }
-}
-
-static void decode_b(AVCodecContext *ctx, int row, int col,
- struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff,
- enum BlockLevel bl, enum BlockPartition bp)
-{
- VP9Context *s = ctx->priv_data;
- VP9Block *b = s->b;
- enum BlockSize bs = bl * 3 + bp;
- int bytesperpixel = s->bytesperpixel;
- int w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl;
- int emu[2];
- AVFrame *f = s->frames[CUR_FRAME].tf.f;
-
- s->row = row;
- s->row7 = row & 7;
- s->col = col;
- s->col7 = col & 7;
- s->min_mv.x = -(128 + col * 64);
- s->min_mv.y = -(128 + row * 64);
- s->max_mv.x = 128 + (s->cols - col - w4) * 64;
- s->max_mv.y = 128 + (s->rows - row - h4) * 64;
- if (s->pass < 2) {
- b->bs = bs;
- b->bl = bl;
- b->bp = bp;
- decode_mode(ctx);
- b->uvtx = b->tx - ((s->ss_h && w4 * 2 == (1 << b->tx)) ||
- (s->ss_v && h4 * 2 == (1 << b->tx)));
-
- if (!b->skip) {
- int has_coeffs;
-
- if (bytesperpixel == 1) {
- has_coeffs = decode_coeffs_8bpp(ctx);
- } else {
- has_coeffs = decode_coeffs_16bpp(ctx);
- }
- if (!has_coeffs && b->bs <= BS_8x8 && !b->intra) {
- b->skip = 1;
- memset(&s->above_skip_ctx[col], 1, w4);
- memset(&s->left_skip_ctx[s->row7], 1, h4);
- }
- } else {
- int row7 = s->row7;
-
-#define SPLAT_ZERO_CTX(v, n) \
- switch (n) { \
- case 1: v = 0; break; \
- case 2: AV_ZERO16(&v); break; \
- case 4: AV_ZERO32(&v); break; \
- case 8: AV_ZERO64(&v); break; \
- case 16: AV_ZERO128(&v); break; \
- }
-#define SPLAT_ZERO_YUV(dir, var, off, n, dir2) \
- do { \
- SPLAT_ZERO_CTX(s->dir##_y_##var[off * 2], n * 2); \
- if (s->ss_##dir2) { \
- SPLAT_ZERO_CTX(s->dir##_uv_##var[0][off], n); \
- SPLAT_ZERO_CTX(s->dir##_uv_##var[1][off], n); \
- } else { \
- SPLAT_ZERO_CTX(s->dir##_uv_##var[0][off * 2], n * 2); \
- SPLAT_ZERO_CTX(s->dir##_uv_##var[1][off * 2], n * 2); \
- } \
- } while (0)
-
- switch (w4) {
- case 1: SPLAT_ZERO_YUV(above, nnz_ctx, col, 1, h); break;
- case 2: SPLAT_ZERO_YUV(above, nnz_ctx, col, 2, h); break;
- case 4: SPLAT_ZERO_YUV(above, nnz_ctx, col, 4, h); break;
- case 8: SPLAT_ZERO_YUV(above, nnz_ctx, col, 8, h); break;
- }
- switch (h4) {
- case 1: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 1, v); break;
- case 2: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 2, v); break;
- case 4: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 4, v); break;
- case 8: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 8, v); break;
- }
- }
- if (s->pass == 1) {
- s->b++;
- s->block += w4 * h4 * 64 * bytesperpixel;
- s->uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v);
- s->uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v);
- s->eob += 4 * w4 * h4;
- s->uveob[0] += 4 * w4 * h4 >> (s->ss_h + s->ss_v);
- s->uveob[1] += 4 * w4 * h4 >> (s->ss_h + s->ss_v);
-
- return;
- }
- }
-
- // emulated overhangs if the stride of the target buffer can't hold. This
- // makes it possible to support emu-edge and so on even if we have large block
- // overhangs
- emu[0] = (col + w4) * 8 > f->linesize[0] ||
- (row + h4) > s->rows;
- emu[1] = (col + w4) * 4 > f->linesize[1] ||
- (row + h4) > s->rows;
- if (emu[0]) {
- s->dst[0] = s->tmp_y;
- s->y_stride = 128;
- } else {
- s->dst[0] = f->data[0] + yoff;
- s->y_stride = f->linesize[0];
- }
- if (emu[1]) {
- s->dst[1] = s->tmp_uv[0];
- s->dst[2] = s->tmp_uv[1];
- s->uv_stride = 128;
- } else {
- s->dst[1] = f->data[1] + uvoff;
- s->dst[2] = f->data[2] + uvoff;
- s->uv_stride = f->linesize[1];
- }
- if (b->intra) {
- if (s->bpp > 8) {
- intra_recon_16bpp(ctx, yoff, uvoff);
- } else {
- intra_recon_8bpp(ctx, yoff, uvoff);
- }
- } else {
- if (s->bpp > 8) {
- inter_recon_16bpp(ctx);
- } else {
- inter_recon_8bpp(ctx);
- }
- }
- if (emu[0]) {
- int w = FFMIN(s->cols - col, w4) * 8, h = FFMIN(s->rows - row, h4) * 8, n, o = 0;
-
- for (n = 0; o < w; n++) {
- int bw = 64 >> n;
-
- av_assert2(n <= 4);
- if (w & bw) {
- s->dsp.mc[n][0][0][0][0](f->data[0] + yoff + o, f->linesize[0],
- s->tmp_y + o, 128, h, 0, 0);
- o += bw * bytesperpixel;
- }
- }
- }
- if (emu[1]) {
- int w = FFMIN(s->cols - col, w4) * 8 >> s->ss_h;
- int h = FFMIN(s->rows - row, h4) * 8 >> s->ss_v, n, o = 0;
-
- for (n = s->ss_h; o < w; n++) {
- int bw = 64 >> n;
-
- av_assert2(n <= 4);
- if (w & bw) {
- s->dsp.mc[n][0][0][0][0](f->data[1] + uvoff + o, f->linesize[1],
- s->tmp_uv[0] + o, 128, h, 0, 0);
- s->dsp.mc[n][0][0][0][0](f->data[2] + uvoff + o, f->linesize[2],
- s->tmp_uv[1] + o, 128, h, 0, 0);
- o += bw * bytesperpixel;
- }
- }
- }
-
- // pick filter level and find edges to apply filter to
- if (s->filter.level &&
- (lvl = s->segmentation.feat[b->seg_id].lflvl[b->intra ? 0 : b->ref[0] + 1]
- [b->mode[3] != ZEROMV]) > 0) {
- int x_end = FFMIN(s->cols - col, w4), y_end = FFMIN(s->rows - row, h4);
- int skip_inter = !b->intra && b->skip, col7 = s->col7, row7 = s->row7;
-
- setctx_2d(&lflvl->level[row7 * 8 + col7], w4, h4, 8, lvl);
- mask_edges(lflvl->mask[0], 0, 0, row7, col7, x_end, y_end, 0, 0, b->tx, skip_inter);
- if (s->ss_h || s->ss_v)
- mask_edges(lflvl->mask[1], s->ss_h, s->ss_v, row7, col7, x_end, y_end,
- s->cols & 1 && col + w4 >= s->cols ? s->cols & 7 : 0,
- s->rows & 1 && row + h4 >= s->rows ? s->rows & 7 : 0,
- b->uvtx, skip_inter);
-
- if (!s->filter.lim_lut[lvl]) {
- int sharp = s->filter.sharpness;
- int limit = lvl;
-
- if (sharp > 0) {
- limit >>= (sharp + 3) >> 2;
- limit = FFMIN(limit, 9 - sharp);
- }
- limit = FFMAX(limit, 1);
-
- s->filter.lim_lut[lvl] = limit;
- s->filter.mblim_lut[lvl] = 2 * (lvl + 2) + limit;
- }
- }
-
- if (s->pass == 2) {
- s->b++;
- s->block += w4 * h4 * 64 * bytesperpixel;
- s->uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h);
- s->uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h);
- s->eob += 4 * w4 * h4;
- s->uveob[0] += 4 * w4 * h4 >> (s->ss_v + s->ss_h);
- s->uveob[1] += 4 * w4 * h4 >> (s->ss_v + s->ss_h);
- }
-}
-
-static void decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl,
- ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl)
-{
- VP9Context *s = ctx->priv_data;
- int c = ((s->above_partition_ctx[col] >> (3 - bl)) & 1) |
- (((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1);
- const uint8_t *p = s->keyframe || s->intraonly ? vp9_default_kf_partition_probs[bl][c] :
- s->prob.p.partition[bl][c];
- enum BlockPartition bp;
- ptrdiff_t hbs = 4 >> bl;
- AVFrame *f = s->frames[CUR_FRAME].tf.f;
- ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1];
- int bytesperpixel = s->bytesperpixel;
-
- if (bl == BL_8X8) {
- bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p);
- decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
- } else if (col + hbs < s->cols) { // FIXME why not <=?
- if (row + hbs < s->rows) { // FIXME why not <=?
- bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p);
- switch (bp) {
- case PARTITION_NONE:
- decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
- break;
- case PARTITION_H:
- decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
- yoff += hbs * 8 * y_stride;
- uvoff += hbs * 8 * uv_stride >> s->ss_v;
- decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp);
- break;
- case PARTITION_V:
- decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
- yoff += hbs * 8 * bytesperpixel;
- uvoff += hbs * 8 * bytesperpixel >> s->ss_h;
- decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, bl, bp);
- break;
- case PARTITION_SPLIT:
- decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
- decode_sb(ctx, row, col + hbs, lflvl,
- yoff + 8 * hbs * bytesperpixel,
- uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1);
- yoff += hbs * 8 * y_stride;
- uvoff += hbs * 8 * uv_stride >> s->ss_v;
- decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
- decode_sb(ctx, row + hbs, col + hbs, lflvl,
- yoff + 8 * hbs * bytesperpixel,
- uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1);
- break;
- default:
- av_assert0(0);
- }
- } else if (vp56_rac_get_prob_branchy(&s->c, p[1])) {
- bp = PARTITION_SPLIT;
- decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
- decode_sb(ctx, row, col + hbs, lflvl,
- yoff + 8 * hbs * bytesperpixel,
- uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1);
- } else {
- bp = PARTITION_H;
- decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
- }
- } else if (row + hbs < s->rows) { // FIXME why not <=?
- if (vp56_rac_get_prob_branchy(&s->c, p[2])) {
- bp = PARTITION_SPLIT;
- decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
- yoff += hbs * 8 * y_stride;
- uvoff += hbs * 8 * uv_stride >> s->ss_v;
- decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
- } else {
- bp = PARTITION_V;
- decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
- }
- } else {
- bp = PARTITION_SPLIT;
- decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
- }
- s->counts.partition[bl][c][bp]++;
-}
-
-static void decode_sb_mem(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl,
- ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl)
-{
- VP9Context *s = ctx->priv_data;
- VP9Block *b = s->b;
- ptrdiff_t hbs = 4 >> bl;
- AVFrame *f = s->frames[CUR_FRAME].tf.f;
- ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1];
- int bytesperpixel = s->bytesperpixel;
-
- if (bl == BL_8X8) {
- av_assert2(b->bl == BL_8X8);
- decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp);
- } else if (s->b->bl == bl) {
- decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp);
- if (b->bp == PARTITION_H && row + hbs < s->rows) {
- yoff += hbs * 8 * y_stride;
- uvoff += hbs * 8 * uv_stride >> s->ss_v;
- decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp);
- } else if (b->bp == PARTITION_V && col + hbs < s->cols) {
- yoff += hbs * 8 * bytesperpixel;
- uvoff += hbs * 8 * bytesperpixel >> s->ss_h;
- decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp);
- }
- } else {
- decode_sb_mem(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
- if (col + hbs < s->cols) { // FIXME why not <=?
- if (row + hbs < s->rows) {
- decode_sb_mem(ctx, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel,
- uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1);
- yoff += hbs * 8 * y_stride;
- uvoff += hbs * 8 * uv_stride >> s->ss_v;
- decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
- decode_sb_mem(ctx, row + hbs, col + hbs, lflvl,
- yoff + 8 * hbs * bytesperpixel,
- uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1);
- } else {
- yoff += hbs * 8 * bytesperpixel;
- uvoff += hbs * 8 * bytesperpixel >> s->ss_h;
- decode_sb_mem(ctx, row, col + hbs, lflvl, yoff, uvoff, bl + 1);
- }
- } else if (row + hbs < s->rows) {
- yoff += hbs * 8 * y_stride;
- uvoff += hbs * 8 * uv_stride >> s->ss_v;
- decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
- }
- }
-}
-
-static av_always_inline void filter_plane_cols(VP9Context *s, int col, int ss_h, int ss_v,
- uint8_t *lvl, uint8_t (*mask)[4],
- uint8_t *dst, ptrdiff_t ls)
-{
- int y, x, bytesperpixel = s->bytesperpixel;
-
- // filter edges between columns (e.g. block1 | block2)
- for (y = 0; y < 8; y += 2 << ss_v, dst += 16 * ls, lvl += 16 << ss_v) {
- uint8_t *ptr = dst, *l = lvl, *hmask1 = mask[y], *hmask2 = mask[y + 1 + ss_v];
- unsigned hm1 = hmask1[0] | hmask1[1] | hmask1[2], hm13 = hmask1[3];
- unsigned hm2 = hmask2[1] | hmask2[2], hm23 = hmask2[3];
- unsigned hm = hm1 | hm2 | hm13 | hm23;
-
- for (x = 1; hm & ~(x - 1); x <<= 1, ptr += 8 * bytesperpixel >> ss_h) {
- if (col || x > 1) {
- if (hm1 & x) {
- int L = *l, H = L >> 4;
- int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
-
- if (hmask1[0] & x) {
- if (hmask2[0] & x) {
- av_assert2(l[8 << ss_v] == L);
- s->dsp.loop_filter_16[0](ptr, ls, E, I, H);
- } else {
- s->dsp.loop_filter_8[2][0](ptr, ls, E, I, H);
- }
- } else if (hm2 & x) {
- L = l[8 << ss_v];
- H |= (L >> 4) << 8;
- E |= s->filter.mblim_lut[L] << 8;
- I |= s->filter.lim_lut[L] << 8;
- s->dsp.loop_filter_mix2[!!(hmask1[1] & x)]
- [!!(hmask2[1] & x)]
- [0](ptr, ls, E, I, H);
- } else {
- s->dsp.loop_filter_8[!!(hmask1[1] & x)]
- [0](ptr, ls, E, I, H);
- }
- } else if (hm2 & x) {
- int L = l[8 << ss_v], H = L >> 4;
- int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
-
- s->dsp.loop_filter_8[!!(hmask2[1] & x)]
- [0](ptr + 8 * ls, ls, E, I, H);
- }
- }
- if (ss_h) {
- if (x & 0xAA)
- l += 2;
- } else {
- if (hm13 & x) {
- int L = *l, H = L >> 4;
- int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
-
- if (hm23 & x) {
- L = l[8 << ss_v];
- H |= (L >> 4) << 8;
- E |= s->filter.mblim_lut[L] << 8;
- I |= s->filter.lim_lut[L] << 8;
- s->dsp.loop_filter_mix2[0][0][0](ptr + 4 * bytesperpixel, ls, E, I, H);
- } else {
- s->dsp.loop_filter_8[0][0](ptr + 4 * bytesperpixel, ls, E, I, H);
- }
- } else if (hm23 & x) {
- int L = l[8 << ss_v], H = L >> 4;
- int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
-
- s->dsp.loop_filter_8[0][0](ptr + 8 * ls + 4 * bytesperpixel, ls, E, I, H);
- }
- l++;
- }
- }
- }
-}
-
-static av_always_inline void filter_plane_rows(VP9Context *s, int row, int ss_h, int ss_v,
- uint8_t *lvl, uint8_t (*mask)[4],
- uint8_t *dst, ptrdiff_t ls)
-{
- int y, x, bytesperpixel = s->bytesperpixel;
-
- // block1
- // filter edges between rows (e.g. ------)
- // block2
- for (y = 0; y < 8; y++, dst += 8 * ls >> ss_v) {
- uint8_t *ptr = dst, *l = lvl, *vmask = mask[y];
- unsigned vm = vmask[0] | vmask[1] | vmask[2], vm3 = vmask[3];
-
- for (x = 1; vm & ~(x - 1); x <<= (2 << ss_h), ptr += 16 * bytesperpixel, l += 2 << ss_h) {
- if (row || y) {
- if (vm & x) {
- int L = *l, H = L >> 4;
- int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
-
- if (vmask[0] & x) {
- if (vmask[0] & (x << (1 + ss_h))) {
- av_assert2(l[1 + ss_h] == L);
- s->dsp.loop_filter_16[1](ptr, ls, E, I, H);
- } else {
- s->dsp.loop_filter_8[2][1](ptr, ls, E, I, H);
- }
- } else if (vm & (x << (1 + ss_h))) {
- L = l[1 + ss_h];
- H |= (L >> 4) << 8;
- E |= s->filter.mblim_lut[L] << 8;
- I |= s->filter.lim_lut[L] << 8;
- s->dsp.loop_filter_mix2[!!(vmask[1] & x)]
- [!!(vmask[1] & (x << (1 + ss_h)))]
- [1](ptr, ls, E, I, H);
- } else {
- s->dsp.loop_filter_8[!!(vmask[1] & x)]
- [1](ptr, ls, E, I, H);
- }
- } else if (vm & (x << (1 + ss_h))) {
- int L = l[1 + ss_h], H = L >> 4;
- int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
-
- s->dsp.loop_filter_8[!!(vmask[1] & (x << (1 + ss_h)))]
- [1](ptr + 8 * bytesperpixel, ls, E, I, H);
- }
- }
- if (!ss_v) {
- if (vm3 & x) {
- int L = *l, H = L >> 4;
- int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
-
- if (vm3 & (x << (1 + ss_h))) {
- L = l[1 + ss_h];
- H |= (L >> 4) << 8;
- E |= s->filter.mblim_lut[L] << 8;
- I |= s->filter.lim_lut[L] << 8;
- s->dsp.loop_filter_mix2[0][0][1](ptr + ls * 4, ls, E, I, H);
- } else {
- s->dsp.loop_filter_8[0][1](ptr + ls * 4, ls, E, I, H);
- }
- } else if (vm3 & (x << (1 + ss_h))) {
- int L = l[1 + ss_h], H = L >> 4;
- int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
-
- s->dsp.loop_filter_8[0][1](ptr + ls * 4 + 8 * bytesperpixel, ls, E, I, H);
- }
- }
- }
- if (ss_v) {
- if (y & 1)
- lvl += 16;
- } else {
- lvl += 8;
- }
- }
-}
-
-static void loopfilter_sb(AVCodecContext *ctx, struct VP9Filter *lflvl,
- int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff)
-{
- VP9Context *s = ctx->priv_data;
- AVFrame *f = s->frames[CUR_FRAME].tf.f;
- uint8_t *dst = f->data[0] + yoff;
- ptrdiff_t ls_y = f->linesize[0], ls_uv = f->linesize[1];
- uint8_t (*uv_masks)[8][4] = lflvl->mask[s->ss_h | s->ss_v];
- int p;
-
- // FIXME in how far can we interleave the v/h loopfilter calls? E.g.
- // if you think of them as acting on a 8x8 block max, we can interleave
- // each v/h within the single x loop, but that only works if we work on
- // 8 pixel blocks, and we won't always do that (we want at least 16px
- // to use SSE2 optimizations, perhaps 32 for AVX2)
-
- filter_plane_cols(s, col, 0, 0, lflvl->level, lflvl->mask[0][0], dst, ls_y);
- filter_plane_rows(s, row, 0, 0, lflvl->level, lflvl->mask[0][1], dst, ls_y);
-
- for (p = 0; p < 2; p++) {
- dst = f->data[1 + p] + uvoff;
- filter_plane_cols(s, col, s->ss_h, s->ss_v, lflvl->level, uv_masks[0], dst, ls_uv);
- filter_plane_rows(s, row, s->ss_h, s->ss_v, lflvl->level, uv_masks[1], dst, ls_uv);
- }
-}
-
-static void set_tile_offset(int *start, int *end, int idx, int log2_n, int n)
-{
- int sb_start = ( idx * n) >> log2_n;
- int sb_end = ((idx + 1) * n) >> log2_n;
- *start = FFMIN(sb_start, n) << 3;
- *end = FFMIN(sb_end, n) << 3;
-}
-
-static av_always_inline void adapt_prob(uint8_t *p, unsigned ct0, unsigned ct1,
- int max_count, int update_factor)
-{
- unsigned ct = ct0 + ct1, p2, p1;
-
- if (!ct)
- return;
-
- update_factor = FASTDIV(update_factor * FFMIN(ct, max_count), max_count);
- p1 = *p;
- p2 = ((((int64_t) ct0) << 8) + (ct >> 1)) / ct;
- p2 = av_clip(p2, 1, 255);
-
- // (p1 * (256 - update_factor) + p2 * update_factor + 128) >> 8
- *p = p1 + (((p2 - p1) * update_factor + 128) >> 8);
-}
-
-static void adapt_probs(VP9Context *s)
-{
- int i, j, k, l, m;
- prob_context *p = &s->prob_ctx[s->framectxid].p;
- int uf = (s->keyframe || s->intraonly || !s->last_keyframe) ? 112 : 128;
-
- // coefficients
- for (i = 0; i < 4; i++)
- for (j = 0; j < 2; j++)
- for (k = 0; k < 2; k++)
- for (l = 0; l < 6; l++)
- for (m = 0; m < 6; m++) {
- uint8_t *pp = s->prob_ctx[s->framectxid].coef[i][j][k][l][m];
- unsigned *e = s->counts.eob[i][j][k][l][m];
- unsigned *c = s->counts.coef[i][j][k][l][m];
-
- if (l == 0 && m >= 3) // dc only has 3 pt
- break;
-
- adapt_prob(&pp[0], e[0], e[1], 24, uf);
- adapt_prob(&pp[1], c[0], c[1] + c[2], 24, uf);
- adapt_prob(&pp[2], c[1], c[2], 24, uf);
- }
-
- if (s->keyframe || s->intraonly) {
- memcpy(p->skip, s->prob.p.skip, sizeof(p->skip));
- memcpy(p->tx32p, s->prob.p.tx32p, sizeof(p->tx32p));
- memcpy(p->tx16p, s->prob.p.tx16p, sizeof(p->tx16p));
- memcpy(p->tx8p, s->prob.p.tx8p, sizeof(p->tx8p));
- return;
- }
-
- // skip flag
- for (i = 0; i < 3; i++)
- adapt_prob(&p->skip[i], s->counts.skip[i][0], s->counts.skip[i][1], 20, 128);
-
- // intra/inter flag
- for (i = 0; i < 4; i++)
- adapt_prob(&p->intra[i], s->counts.intra[i][0], s->counts.intra[i][1], 20, 128);
-
- // comppred flag
- if (s->comppredmode == PRED_SWITCHABLE) {
- for (i = 0; i < 5; i++)
- adapt_prob(&p->comp[i], s->counts.comp[i][0], s->counts.comp[i][1], 20, 128);
- }
-
- // reference frames
- if (s->comppredmode != PRED_SINGLEREF) {
- for (i = 0; i < 5; i++)
- adapt_prob(&p->comp_ref[i], s->counts.comp_ref[i][0],
- s->counts.comp_ref[i][1], 20, 128);
- }
-
- if (s->comppredmode != PRED_COMPREF) {
- for (i = 0; i < 5; i++) {
- uint8_t *pp = p->single_ref[i];
- unsigned (*c)[2] = s->counts.single_ref[i];
-
- adapt_prob(&pp[0], c[0][0], c[0][1], 20, 128);
- adapt_prob(&pp[1], c[1][0], c[1][1], 20, 128);
- }
- }
-
- // block partitioning
- for (i = 0; i < 4; i++)
- for (j = 0; j < 4; j++) {
- uint8_t *pp = p->partition[i][j];
- unsigned *c = s->counts.partition[i][j];
-
- adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
- adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
- adapt_prob(&pp[2], c[2], c[3], 20, 128);
- }
-
- // tx size
- if (s->txfmmode == TX_SWITCHABLE) {
- for (i = 0; i < 2; i++) {
- unsigned *c16 = s->counts.tx16p[i], *c32 = s->counts.tx32p[i];
-
- adapt_prob(&p->tx8p[i], s->counts.tx8p[i][0], s->counts.tx8p[i][1], 20, 128);
- adapt_prob(&p->tx16p[i][0], c16[0], c16[1] + c16[2], 20, 128);
- adapt_prob(&p->tx16p[i][1], c16[1], c16[2], 20, 128);
- adapt_prob(&p->tx32p[i][0], c32[0], c32[1] + c32[2] + c32[3], 20, 128);
- adapt_prob(&p->tx32p[i][1], c32[1], c32[2] + c32[3], 20, 128);
- adapt_prob(&p->tx32p[i][2], c32[2], c32[3], 20, 128);
- }
- }
-
- // interpolation filter
- if (s->filtermode == FILTER_SWITCHABLE) {
- for (i = 0; i < 4; i++) {
- uint8_t *pp = p->filter[i];
- unsigned *c = s->counts.filter[i];
-
- adapt_prob(&pp[0], c[0], c[1] + c[2], 20, 128);
- adapt_prob(&pp[1], c[1], c[2], 20, 128);
- }
- }
-
- // inter modes
- for (i = 0; i < 7; i++) {
- uint8_t *pp = p->mv_mode[i];
- unsigned *c = s->counts.mv_mode[i];
-
- adapt_prob(&pp[0], c[2], c[1] + c[0] + c[3], 20, 128);
- adapt_prob(&pp[1], c[0], c[1] + c[3], 20, 128);
- adapt_prob(&pp[2], c[1], c[3], 20, 128);
- }
-
- // mv joints
- {
- uint8_t *pp = p->mv_joint;
- unsigned *c = s->counts.mv_joint;
-
- adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
- adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
- adapt_prob(&pp[2], c[2], c[3], 20, 128);
- }
-
- // mv components
- for (i = 0; i < 2; i++) {
- uint8_t *pp;
- unsigned *c, (*c2)[2], sum;
-
- adapt_prob(&p->mv_comp[i].sign, s->counts.mv_comp[i].sign[0],
- s->counts.mv_comp[i].sign[1], 20, 128);
-
- pp = p->mv_comp[i].classes;
- c = s->counts.mv_comp[i].classes;
- sum = c[1] + c[2] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9] + c[10];
- adapt_prob(&pp[0], c[0], sum, 20, 128);
- sum -= c[1];
- adapt_prob(&pp[1], c[1], sum, 20, 128);
- sum -= c[2] + c[3];
- adapt_prob(&pp[2], c[2] + c[3], sum, 20, 128);
- adapt_prob(&pp[3], c[2], c[3], 20, 128);
- sum -= c[4] + c[5];
- adapt_prob(&pp[4], c[4] + c[5], sum, 20, 128);
- adapt_prob(&pp[5], c[4], c[5], 20, 128);
- sum -= c[6];
- adapt_prob(&pp[6], c[6], sum, 20, 128);
- adapt_prob(&pp[7], c[7] + c[8], c[9] + c[10], 20, 128);
- adapt_prob(&pp[8], c[7], c[8], 20, 128);
- adapt_prob(&pp[9], c[9], c[10], 20, 128);
-
- adapt_prob(&p->mv_comp[i].class0, s->counts.mv_comp[i].class0[0],
- s->counts.mv_comp[i].class0[1], 20, 128);
- pp = p->mv_comp[i].bits;
- c2 = s->counts.mv_comp[i].bits;
- for (j = 0; j < 10; j++)
- adapt_prob(&pp[j], c2[j][0], c2[j][1], 20, 128);
-
- for (j = 0; j < 2; j++) {
- pp = p->mv_comp[i].class0_fp[j];
- c = s->counts.mv_comp[i].class0_fp[j];
- adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
- adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
- adapt_prob(&pp[2], c[2], c[3], 20, 128);
- }
- pp = p->mv_comp[i].fp;
- c = s->counts.mv_comp[i].fp;
- adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
- adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
- adapt_prob(&pp[2], c[2], c[3], 20, 128);
-
- if (s->highprecisionmvs) {
- adapt_prob(&p->mv_comp[i].class0_hp, s->counts.mv_comp[i].class0_hp[0],
- s->counts.mv_comp[i].class0_hp[1], 20, 128);
- adapt_prob(&p->mv_comp[i].hp, s->counts.mv_comp[i].hp[0],
- s->counts.mv_comp[i].hp[1], 20, 128);
- }
- }
-
- // y intra modes
- for (i = 0; i < 4; i++) {
- uint8_t *pp = p->y_mode[i];
- unsigned *c = s->counts.y_mode[i], sum, s2;
-
- sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9];
- adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128);
- sum -= c[TM_VP8_PRED];
- adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128);
- sum -= c[VERT_PRED];
- adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128);
- s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED];
- sum -= s2;
- adapt_prob(&pp[3], s2, sum, 20, 128);
- s2 -= c[HOR_PRED];
- adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128);
- adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], 20, 128);
- sum -= c[DIAG_DOWN_LEFT_PRED];
- adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128);
- sum -= c[VERT_LEFT_PRED];
- adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128);
- adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128);
- }
-
- // uv intra modes
- for (i = 0; i < 10; i++) {
- uint8_t *pp = p->uv_mode[i];
- unsigned *c = s->counts.uv_mode[i], sum, s2;
-
- sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9];
- adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128);
- sum -= c[TM_VP8_PRED];
- adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128);
- sum -= c[VERT_PRED];
- adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128);
- s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED];
- sum -= s2;
- adapt_prob(&pp[3], s2, sum, 20, 128);
- s2 -= c[HOR_PRED];
- adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128);
- adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], 20, 128);
- sum -= c[DIAG_DOWN_LEFT_PRED];
- adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128);
- sum -= c[VERT_LEFT_PRED];
- adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128);
- adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128);
- }
-}
-
-static void free_buffers(VP9Context *s)
-{
- av_freep(&s->intra_pred_data[0]);
- av_freep(&s->b_base);
- av_freep(&s->block_base);
-}
-
-static av_cold int vp9_decode_free(AVCodecContext *ctx)
-{
- VP9Context *s = ctx->priv_data;
- int i;
-
- for (i = 0; i < 3; i++) {
- if (s->frames[i].tf.f->data[0])
- vp9_unref_frame(ctx, &s->frames[i]);
- av_frame_free(&s->frames[i].tf.f);
- }
- for (i = 0; i < 8; i++) {
- if (s->refs[i].f->data[0])
- ff_thread_release_buffer(ctx, &s->refs[i]);
- av_frame_free(&s->refs[i].f);
- if (s->next_refs[i].f->data[0])
- ff_thread_release_buffer(ctx, &s->next_refs[i]);
- av_frame_free(&s->next_refs[i].f);
- }
- free_buffers(s);
- av_freep(&s->c_b);
- s->c_b_size = 0;
-
- return 0;
-}
-
-
-static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
- int *got_frame, AVPacket *pkt)
-{
- const uint8_t *data = pkt->data;
- int size = pkt->size;
- VP9Context *s = ctx->priv_data;
- int res, tile_row, tile_col, i, ref, row, col;
- int retain_segmap_ref = s->frames[REF_FRAME_SEGMAP].segmentation_map &&
- (!s->segmentation.enabled || !s->segmentation.update_map);
- ptrdiff_t yoff, uvoff, ls_y, ls_uv;
- AVFrame *f;
- int bytesperpixel;
-
- if ((res = decode_frame_header(ctx, data, size, &ref)) < 0) {
- return res;
- } else if (res == 0) {
- if (!s->refs[ref].f->data[0]) {
- av_log(ctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref);
- return AVERROR_INVALIDDATA;
- }
- if ((res = av_frame_ref(frame, s->refs[ref].f)) < 0)
- return res;
- ((AVFrame *)frame)->pkt_pts = pkt->pts;
- ((AVFrame *)frame)->pkt_dts = pkt->dts;
- for (i = 0; i < 8; i++) {
- if (s->next_refs[i].f->data[0])
- ff_thread_release_buffer(ctx, &s->next_refs[i]);
- if (s->refs[i].f->data[0] &&
- (res = ff_thread_ref_frame(&s->next_refs[i], &s->refs[i])) < 0)
- return res;
- }
- *got_frame = 1;
- return pkt->size;
- }
- data += res;
- size -= res;
-
- if (!retain_segmap_ref || s->keyframe || s->intraonly) {
- if (s->frames[REF_FRAME_SEGMAP].tf.f->data[0])
- vp9_unref_frame(ctx, &s->frames[REF_FRAME_SEGMAP]);
- if (!s->keyframe && !s->intraonly && !s->errorres && s->frames[CUR_FRAME].tf.f->data[0] &&
- (res = vp9_ref_frame(ctx, &s->frames[REF_FRAME_SEGMAP], &s->frames[CUR_FRAME])) < 0)
- return res;
- }
- if (s->frames[REF_FRAME_MVPAIR].tf.f->data[0])
- vp9_unref_frame(ctx, &s->frames[REF_FRAME_MVPAIR]);
- if (!s->intraonly && !s->keyframe && !s->errorres && s->frames[CUR_FRAME].tf.f->data[0] &&
- (res = vp9_ref_frame(ctx, &s->frames[REF_FRAME_MVPAIR], &s->frames[CUR_FRAME])) < 0)
- return res;
- if (s->frames[CUR_FRAME].tf.f->data[0])
- vp9_unref_frame(ctx, &s->frames[CUR_FRAME]);
- if ((res = vp9_alloc_frame(ctx, &s->frames[CUR_FRAME])) < 0)
- return res;
- f = s->frames[CUR_FRAME].tf.f;
- f->key_frame = s->keyframe;
- f->pict_type = (s->keyframe || s->intraonly) ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
- ls_y = f->linesize[0];
- ls_uv =f->linesize[1];
-
- // ref frame setup
- for (i = 0; i < 8; i++) {
- if (s->next_refs[i].f->data[0])
- ff_thread_release_buffer(ctx, &s->next_refs[i]);
- if (s->refreshrefmask & (1 << i)) {
- res = ff_thread_ref_frame(&s->next_refs[i], &s->frames[CUR_FRAME].tf);
- } else if (s->refs[i].f->data[0]) {
- res = ff_thread_ref_frame(&s->next_refs[i], &s->refs[i]);
- }
- if (res < 0)
- return res;
- }
-
- // main tile decode loop
- bytesperpixel = s->bytesperpixel;
- memset(s->above_partition_ctx, 0, s->cols);
- memset(s->above_skip_ctx, 0, s->cols);
- if (s->keyframe || s->intraonly) {
- memset(s->above_mode_ctx, DC_PRED, s->cols * 2);
- } else {
- memset(s->above_mode_ctx, NEARESTMV, s->cols);
- }
- memset(s->above_y_nnz_ctx, 0, s->sb_cols * 16);
- memset(s->above_uv_nnz_ctx[0], 0, s->sb_cols * 16 >> s->ss_h);
- memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 16 >> s->ss_h);
- memset(s->above_segpred_ctx, 0, s->cols);
- s->pass = s->frames[CUR_FRAME].uses_2pass =
- ctx->active_thread_type == FF_THREAD_FRAME && s->refreshctx && !s->parallelmode;
- if ((res = update_block_buffers(ctx)) < 0) {
- av_log(ctx, AV_LOG_ERROR,
- "Failed to allocate block buffers\n");
- return res;
- }
- if (s->refreshctx && s->parallelmode) {
- int j, k, l, m;
-
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 2; j++)
- for (k = 0; k < 2; k++)
- for (l = 0; l < 6; l++)
- for (m = 0; m < 6; m++)
- memcpy(s->prob_ctx[s->framectxid].coef[i][j][k][l][m],
- s->prob.coef[i][j][k][l][m], 3);
- if (s->txfmmode == i)
- break;
- }
- s->prob_ctx[s->framectxid].p = s->prob.p;
- ff_thread_finish_setup(ctx);
- } else if (!s->refreshctx) {
- ff_thread_finish_setup(ctx);
- }
-
- do {
- yoff = uvoff = 0;
- s->b = s->b_base;
- s->block = s->block_base;
- s->uvblock[0] = s->uvblock_base[0];
- s->uvblock[1] = s->uvblock_base[1];
- s->eob = s->eob_base;
- s->uveob[0] = s->uveob_base[0];
- s->uveob[1] = s->uveob_base[1];
-
- for (tile_row = 0; tile_row < s->tiling.tile_rows; tile_row++) {
- set_tile_offset(&s->tiling.tile_row_start, &s->tiling.tile_row_end,
- tile_row, s->tiling.log2_tile_rows, s->sb_rows);
- if (s->pass != 2) {
- for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
- int64_t tile_size;
-
- if (tile_col == s->tiling.tile_cols - 1 &&
- tile_row == s->tiling.tile_rows - 1) {
- tile_size = size;
- } else {
- tile_size = AV_RB32(data);
- data += 4;
- size -= 4;
- }
- if (tile_size > size) {
- ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);
- return AVERROR_INVALIDDATA;
- }
- ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size);
- if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) { // marker bit
- ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);
- return AVERROR_INVALIDDATA;
- }
- data += tile_size;
- size -= tile_size;
- }
- }
-
- for (row = s->tiling.tile_row_start; row < s->tiling.tile_row_end;
- row += 8, yoff += ls_y * 64, uvoff += ls_uv * 64 >> s->ss_v) {
- struct VP9Filter *lflvl_ptr = s->lflvl;
- ptrdiff_t yoff2 = yoff, uvoff2 = uvoff;
-
- for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
- set_tile_offset(&s->tiling.tile_col_start, &s->tiling.tile_col_end,
- tile_col, s->tiling.log2_tile_cols, s->sb_cols);
-
- if (s->pass != 2) {
- memset(s->left_partition_ctx, 0, 8);
- memset(s->left_skip_ctx, 0, 8);
- if (s->keyframe || s->intraonly) {
- memset(s->left_mode_ctx, DC_PRED, 16);
- } else {
- memset(s->left_mode_ctx, NEARESTMV, 8);
- }
- memset(s->left_y_nnz_ctx, 0, 16);
- memset(s->left_uv_nnz_ctx, 0, 32);
- memset(s->left_segpred_ctx, 0, 8);
-
- memcpy(&s->c, &s->c_b[tile_col], sizeof(s->c));
- }
-
- for (col = s->tiling.tile_col_start;
- col < s->tiling.tile_col_end;
- col += 8, yoff2 += 64 * bytesperpixel,
- uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) {
- // FIXME integrate with lf code (i.e. zero after each
- // use, similar to invtxfm coefficients, or similar)
- if (s->pass != 1) {
- memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask));
- }
-
- if (s->pass == 2) {
- decode_sb_mem(ctx, row, col, lflvl_ptr,
- yoff2, uvoff2, BL_64X64);
- } else {
- decode_sb(ctx, row, col, lflvl_ptr,
- yoff2, uvoff2, BL_64X64);
- }
- }
- if (s->pass != 2) {
- memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c));
- }
- }
-
- if (s->pass == 1) {
- continue;
- }
-
- // backup pre-loopfilter reconstruction data for intra
- // prediction of next row of sb64s
- if (row + 8 < s->rows) {
- memcpy(s->intra_pred_data[0],
- f->data[0] + yoff + 63 * ls_y,
- 8 * s->cols * bytesperpixel);
- memcpy(s->intra_pred_data[1],
- f->data[1] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv,
- 8 * s->cols * bytesperpixel >> s->ss_h);
- memcpy(s->intra_pred_data[2],
- f->data[2] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv,
- 8 * s->cols * bytesperpixel >> s->ss_h);
- }
-
- // loopfilter one row
- if (s->filter.level) {
- yoff2 = yoff;
- uvoff2 = uvoff;
- lflvl_ptr = s->lflvl;
- for (col = 0; col < s->cols;
- col += 8, yoff2 += 64 * bytesperpixel,
- uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) {
- loopfilter_sb(ctx, lflvl_ptr, row, col, yoff2, uvoff2);
- }
- }
-
- // FIXME maybe we can make this more finegrained by running the
- // loopfilter per-block instead of after each sbrow
- // In fact that would also make intra pred left preparation easier?
- ff_thread_report_progress(&s->frames[CUR_FRAME].tf, row >> 3, 0);
- }
- }
-
- if (s->pass < 2 && s->refreshctx && !s->parallelmode) {
- adapt_probs(s);
- ff_thread_finish_setup(ctx);
- }
- } while (s->pass++ == 1);
- ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);
-
- // ref frame setup
- for (i = 0; i < 8; i++) {
- if (s->refs[i].f->data[0])
- ff_thread_release_buffer(ctx, &s->refs[i]);
- ff_thread_ref_frame(&s->refs[i], &s->next_refs[i]);
- }
-
- if (!s->invisible) {
- if ((res = av_frame_ref(frame, s->frames[CUR_FRAME].tf.f)) < 0)
- return res;
- *got_frame = 1;
- }
-
- return pkt->size;
-}
-
-static void vp9_decode_flush(AVCodecContext *ctx)
-{
- VP9Context *s = ctx->priv_data;
- int i;
-
- for (i = 0; i < 3; i++)
- vp9_unref_frame(ctx, &s->frames[i]);
- for (i = 0; i < 8; i++)
- ff_thread_release_buffer(ctx, &s->refs[i]);
-}
-
-static int init_frames(AVCodecContext *ctx)
-{
- VP9Context *s = ctx->priv_data;
- int i;
-
- for (i = 0; i < 3; i++) {
- s->frames[i].tf.f = av_frame_alloc();
- if (!s->frames[i].tf.f) {
- vp9_decode_free(ctx);
- av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i);
- return AVERROR(ENOMEM);
- }
- }
- for (i = 0; i < 8; i++) {
- s->refs[i].f = av_frame_alloc();
- s->next_refs[i].f = av_frame_alloc();
- if (!s->refs[i].f || !s->next_refs[i].f) {
- vp9_decode_free(ctx);
- av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i);
- return AVERROR(ENOMEM);
- }
- }
-
- return 0;
-}
-
-static av_cold int vp9_decode_init(AVCodecContext *ctx)
-{
- VP9Context *s = ctx->priv_data;
-
- ctx->internal->allocate_progress = 1;
- s->last_bpp = 0;
- s->filter.sharpness = -1;
-
- return init_frames(ctx);
-}
-
-static av_cold int vp9_decode_init_thread_copy(AVCodecContext *avctx)
-{
- return init_frames(avctx);
-}
-
-static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
-{
- int i, res;
- VP9Context *s = dst->priv_data, *ssrc = src->priv_data;
-
- // detect size changes in other threads
- if (s->intra_pred_data[0] &&
- (!ssrc->intra_pred_data[0] || s->cols != ssrc->cols || s->rows != ssrc->rows)) {
- free_buffers(s);
- }
-
- for (i = 0; i < 3; i++) {
- if (s->frames[i].tf.f->data[0])
- vp9_unref_frame(dst, &s->frames[i]);
- if (ssrc->frames[i].tf.f->data[0]) {
- if ((res = vp9_ref_frame(dst, &s->frames[i], &ssrc->frames[i])) < 0)
- return res;
- }
- }
- for (i = 0; i < 8; i++) {
- if (s->refs[i].f->data[0])
- ff_thread_release_buffer(dst, &s->refs[i]);
- if (ssrc->next_refs[i].f->data[0]) {
- if ((res = ff_thread_ref_frame(&s->refs[i], &ssrc->next_refs[i])) < 0)
- return res;
- }
- }
-
- s->invisible = ssrc->invisible;
- s->keyframe = ssrc->keyframe;
- s->intraonly = ssrc->intraonly;
- s->ss_v = ssrc->ss_v;
- s->ss_h = ssrc->ss_h;
- s->segmentation.enabled = ssrc->segmentation.enabled;
- s->segmentation.update_map = ssrc->segmentation.update_map;
- s->bytesperpixel = ssrc->bytesperpixel;
- s->bpp = ssrc->bpp;
- s->bpp_index = ssrc->bpp_index;
- memcpy(&s->prob_ctx, &ssrc->prob_ctx, sizeof(s->prob_ctx));
- memcpy(&s->lf_delta, &ssrc->lf_delta, sizeof(s->lf_delta));
- if (ssrc->segmentation.enabled) {
- memcpy(&s->segmentation.feat, &ssrc->segmentation.feat,
- sizeof(s->segmentation.feat));
- }
-
- return 0;
-}
-
-static const AVProfile profiles[] = {
- { FF_PROFILE_VP9_0, "Profile 0" },
- { FF_PROFILE_VP9_1, "Profile 1" },
- { FF_PROFILE_VP9_2, "Profile 2" },
- { FF_PROFILE_VP9_3, "Profile 3" },
- { FF_PROFILE_UNKNOWN },
-};
-
-AVCodec ff_vp9_decoder = {
- .name = "vp9",
- .long_name = NULL_IF_CONFIG_SMALL("Google VP9"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_VP9,
- .priv_data_size = sizeof(VP9Context),
- .init = vp9_decode_init,
- .close = vp9_decode_free,
- .decode = vp9_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
- .flush = vp9_decode_flush,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp9_decode_init_thread_copy),
- .update_thread_context = ONLY_IF_THREADS_ENABLED(vp9_decode_update_thread_context),
- .profiles = NULL_IF_CONFIG_SMALL(profiles),
-};
diff --git a/ffmpeg-2-8-11/libavcodec/wavpack.c b/ffmpeg-2-8-11/libavcodec/wavpack.c
deleted file mode 100644
index 9bafe65..0000000
--- a/ffmpeg-2-8-11/libavcodec/wavpack.c
+++ /dev/null
@@ -1,1129 +0,0 @@
-/*
- * WavPack lossless audio decoder
- * 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
- */
-
-#define BITSTREAM_READER_LE
-
-#include "libavutil/channel_layout.h"
-#include "avcodec.h"
-#include "get_bits.h"
-#include "internal.h"
-#include "thread.h"
-#include "unary.h"
-#include "bytestream.h"
-#include "wavpack.h"
-
-/**
- * @file
- * WavPack lossless audio decoder
- */
-
-typedef struct SavedContext {
- int offset;
- int size;
- int bits_used;
- uint32_t crc;
-} SavedContext;
-
-typedef struct WavpackFrameContext {
- AVCodecContext *avctx;
- int frame_flags;
- int stereo, stereo_in;
- int joint;
- uint32_t CRC;
- GetBitContext gb;
- int got_extra_bits;
- uint32_t crc_extra_bits;
- GetBitContext gb_extra_bits;
- int data_size; // in bits
- int samples;
- int terms;
- Decorr decorr[MAX_TERMS];
- int zero, one, zeroes;
- int extra_bits;
- int and, or, shift;
- int post_shift;
- int hybrid, hybrid_bitrate;
- int hybrid_maxclip, hybrid_minclip;
- int float_flag;
- int float_shift;
- int float_max_exp;
- WvChannel ch[2];
- int pos;
- SavedContext sc, extra_sc;
-} WavpackFrameContext;
-
-#define WV_MAX_FRAME_DECODERS 14
-
-typedef struct WavpackContext {
- AVCodecContext *avctx;
-
- WavpackFrameContext *fdec[WV_MAX_FRAME_DECODERS];
- int fdec_num;
-
- int block;
- int samples;
- int ch_offset;
-} WavpackContext;
-
-#define LEVEL_DECAY(a) (((a) + 0x80) >> 8)
-
-static av_always_inline int get_tail(GetBitContext *gb, int k)
-{
- int p, e, res;
-
- if (k < 1)
- return 0;
- p = av_log2(k);
- e = (1 << (p + 1)) - k - 1;
- res = p ? get_bits(gb, p) : 0;
- if (res >= e)
- res = (res << 1) - e + get_bits1(gb);
- return res;
-}
-
-static void update_error_limit(WavpackFrameContext *ctx)
-{
- int i, br[2], sl[2];
-
- for (i = 0; i <= ctx->stereo_in; i++) {
- ctx->ch[i].bitrate_acc += ctx->ch[i].bitrate_delta;
- br[i] = ctx->ch[i].bitrate_acc >> 16;
- sl[i] = LEVEL_DECAY(ctx->ch[i].slow_level);
- }
- if (ctx->stereo_in && ctx->hybrid_bitrate) {
- int balance = (sl[1] - sl[0] + br[1] + 1) >> 1;
- if (balance > br[0]) {
- br[1] = br[0] << 1;
- br[0] = 0;
- } else if (-balance > br[0]) {
- br[0] <<= 1;
- br[1] = 0;
- } else {
- br[1] = br[0] + balance;
- br[0] = br[0] - balance;
- }
- }
- for (i = 0; i <= ctx->stereo_in; i++) {
- if (ctx->hybrid_bitrate) {
- if (sl[i] - br[i] > -0x100)
- ctx->ch[i].error_limit = wp_exp2(sl[i] - br[i] + 0x100);
- else
- ctx->ch[i].error_limit = 0;
- } else {
- ctx->ch[i].error_limit = wp_exp2(br[i]);
- }
- }
-}
-
-static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb,
- int channel, int *last)
-{
- int t, t2;
- int sign, base, add, ret;
- WvChannel *c = &ctx->ch[channel];
-
- *last = 0;
-
- if ((ctx->ch[0].median[0] < 2U) && (ctx->ch[1].median[0] < 2U) &&
- !ctx->zero && !ctx->one) {
- if (ctx->zeroes) {
- ctx->zeroes--;
- if (ctx->zeroes) {
- c->slow_level -= LEVEL_DECAY(c->slow_level);
- return 0;
- }
- } else {
- t = get_unary_0_33(gb);
- if (t >= 2) {
- if (get_bits_left(gb) < t - 1)
- goto error;
- t = get_bits_long(gb, t - 1) | (1 << (t - 1));
- } else {
- if (get_bits_left(gb) < 0)
- goto error;
- }
- ctx->zeroes = t;
- if (ctx->zeroes) {
- memset(ctx->ch[0].median, 0, sizeof(ctx->ch[0].median));
- memset(ctx->ch[1].median, 0, sizeof(ctx->ch[1].median));
- c->slow_level -= LEVEL_DECAY(c->slow_level);
- return 0;
- }
- }
- }
-
- if (ctx->zero) {
- t = 0;
- ctx->zero = 0;
- } else {
- t = get_unary_0_33(gb);
- if (get_bits_left(gb) < 0)
- goto error;
- if (t == 16) {
- t2 = get_unary_0_33(gb);
- if (t2 < 2) {
- if (get_bits_left(gb) < 0)
- goto error;
- t += t2;
- } else {
- if (get_bits_left(gb) < t2 - 1)
- goto error;
- t += get_bits_long(gb, t2 - 1) | (1 << (t2 - 1));
- }
- }
-
- if (ctx->one) {
- ctx->one = t & 1;
- t = (t >> 1) + 1;
- } else {
- ctx->one = t & 1;
- t >>= 1;
- }
- ctx->zero = !ctx->one;
- }
-
- if (ctx->hybrid && !channel)
- update_error_limit(ctx);
-
- if (!t) {
- base = 0;
- add = GET_MED(0) - 1;
- DEC_MED(0);
- } else if (t == 1) {
- base = GET_MED(0);
- add = GET_MED(1) - 1;
- INC_MED(0);
- DEC_MED(1);
- } else if (t == 2) {
- base = GET_MED(0) + GET_MED(1);
- add = GET_MED(2) - 1;
- INC_MED(0);
- INC_MED(1);
- DEC_MED(2);
- } else {
- base = GET_MED(0) + GET_MED(1) + GET_MED(2) * (t - 2);
- add = GET_MED(2) - 1;
- INC_MED(0);
- INC_MED(1);
- INC_MED(2);
- }
- if (!c->error_limit) {
- if (add >= 0x2000000U) {
- av_log(ctx->avctx, AV_LOG_ERROR, "k %d is too large\n", add);
- goto error;
- }
- ret = base + get_tail(gb, add);
- if (get_bits_left(gb) <= 0)
- goto error;
- } else {
- int mid = (base * 2 + add + 1) >> 1;
- while (add > c->error_limit) {
- if (get_bits_left(gb) <= 0)
- goto error;
- if (get_bits1(gb)) {
- add -= (mid - base);
- base = mid;
- } else
- add = mid - base - 1;
- mid = (base * 2 + add + 1) >> 1;
- }
- ret = mid;
- }
- sign = get_bits1(gb);
- if (ctx->hybrid_bitrate)
- c->slow_level += wp_log2(ret) - LEVEL_DECAY(c->slow_level);
- return sign ? ~ret : ret;
-
-error:
- ret = get_bits_left(gb);
- if (ret <= 0) {
- av_log(ctx->avctx, AV_LOG_ERROR, "Too few bits (%d) left\n", ret);
- }
- *last = 1;
- return 0;
-}
-
-static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc,
- int S)
-{
- int bit;
-
- if (s->extra_bits) {
- S <<= s->extra_bits;
-
- if (s->got_extra_bits &&
- get_bits_left(&s->gb_extra_bits) >= s->extra_bits) {
- S |= get_bits_long(&s->gb_extra_bits, s->extra_bits);
- *crc = *crc * 9 + (S & 0xffff) * 3 + ((unsigned)S >> 16);
- }
- }
-
- bit = (S & s->and) | s->or;
- bit = ((S + bit) << s->shift) - bit;
-
- if (s->hybrid)
- bit = av_clip(bit, s->hybrid_minclip, s->hybrid_maxclip);
-
- return bit << s->post_shift;
-}
-
-static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S)
-{
- union {
- float f;
- uint32_t u;
- } value;
-
- unsigned int sign;
- int exp = s->float_max_exp;
-
- if (s->got_extra_bits) {
- const int max_bits = 1 + 23 + 8 + 1;
- const int left_bits = get_bits_left(&s->gb_extra_bits);
-
- if (left_bits + 8 * AV_INPUT_BUFFER_PADDING_SIZE < max_bits)
- return 0.0;
- }
-
- if (S) {
- S <<= s->float_shift;
- sign = S < 0;
- if (sign)
- S = -S;
- if (S >= 0x1000000) {
- if (s->got_extra_bits && get_bits1(&s->gb_extra_bits))
- S = get_bits(&s->gb_extra_bits, 23);
- else
- S = 0;
- exp = 255;
- } else if (exp) {
- int shift = 23 - av_log2(S);
- exp = s->float_max_exp;
- if (exp <= shift)
- shift = --exp;
- exp -= shift;
-
- if (shift) {
- S <<= shift;
- if ((s->float_flag & WV_FLT_SHIFT_ONES) ||
- (s->got_extra_bits &&
- (s->float_flag & WV_FLT_SHIFT_SAME) &&
- get_bits1(&s->gb_extra_bits))) {
- S |= (1 << shift) - 1;
- } else if (s->got_extra_bits &&
- (s->float_flag & WV_FLT_SHIFT_SENT)) {
- S |= get_bits(&s->gb_extra_bits, shift);
- }
- }
- } else {
- exp = s->float_max_exp;
- }
- S &= 0x7fffff;
- } else {
- sign = 0;
- exp = 0;
- if (s->got_extra_bits && (s->float_flag & WV_FLT_ZERO_SENT)) {
- if (get_bits1(&s->gb_extra_bits)) {
- S = get_bits(&s->gb_extra_bits, 23);
- if (s->float_max_exp >= 25)
- exp = get_bits(&s->gb_extra_bits, 8);
- sign = get_bits1(&s->gb_extra_bits);
- } else {
- if (s->float_flag & WV_FLT_ZERO_SIGN)
- sign = get_bits1(&s->gb_extra_bits);
- }
- }
- }
-
- *crc = *crc * 27 + S * 9 + exp * 3 + sign;
-
- value.u = (sign << 31) | (exp << 23) | S;
- return value.f;
-}
-
-static void wv_reset_saved_context(WavpackFrameContext *s)
-{
- s->pos = 0;
- s->sc.crc = s->extra_sc.crc = 0xFFFFFFFF;
-}
-
-static inline int wv_check_crc(WavpackFrameContext *s, uint32_t crc,
- uint32_t crc_extra_bits)
-{
- if (crc != s->CRC) {
- av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
- return AVERROR_INVALIDDATA;
- }
- if (s->got_extra_bits && crc_extra_bits != s->crc_extra_bits) {
- av_log(s->avctx, AV_LOG_ERROR, "Extra bits CRC error\n");
- return AVERROR_INVALIDDATA;
- }
-
- return 0;
-}
-
-static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb,
- void *dst_l, void *dst_r, const int type)
-{
- int i, j, count = 0;
- int last, t;
- int A, B, L, L2, R, R2;
- int pos = s->pos;
- uint32_t crc = s->sc.crc;
- uint32_t crc_extra_bits = s->extra_sc.crc;
- int16_t *dst16_l = dst_l;
- int16_t *dst16_r = dst_r;
- int32_t *dst32_l = dst_l;
- int32_t *dst32_r = dst_r;
- float *dstfl_l = dst_l;
- float *dstfl_r = dst_r;
-
- s->one = s->zero = s->zeroes = 0;
- do {
- L = wv_get_value(s, gb, 0, &last);
- if (last)
- break;
- R = wv_get_value(s, gb, 1, &last);
- if (last)
- break;
- for (i = 0; i < s->terms; i++) {
- t = s->decorr[i].value;
- if (t > 0) {
- if (t > 8) {
- if (t & 1) {
- A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1];
- B = 2 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1];
- } else {
- A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1;
- B = (3 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]) >> 1;
- }
- s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];
- s->decorr[i].samplesB[1] = s->decorr[i].samplesB[0];
- j = 0;
- } else {
- A = s->decorr[i].samplesA[pos];
- B = s->decorr[i].samplesB[pos];
- j = (pos + t) & 7;
- }
- if (type != AV_SAMPLE_FMT_S16P) {
- L2 = L + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10);
- R2 = R + ((s->decorr[i].weightB * (int64_t)B + 512) >> 10);
- } else {
- L2 = L + ((s->decorr[i].weightA * A + 512) >> 10);
- R2 = R + ((s->decorr[i].weightB * B + 512) >> 10);
- }
- if (A && L)
- s->decorr[i].weightA -= ((((L ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;
- if (B && R)
- s->decorr[i].weightB -= ((((R ^ B) >> 30) & 2) - 1) * s->decorr[i].delta;
- s->decorr[i].samplesA[j] = L = L2;
- s->decorr[i].samplesB[j] = R = R2;
- } else if (t == -1) {
- if (type != AV_SAMPLE_FMT_S16P)
- L2 = L + ((s->decorr[i].weightA * (int64_t)s->decorr[i].samplesA[0] + 512) >> 10);
- else
- L2 = L + ((s->decorr[i].weightA * s->decorr[i].samplesA[0] + 512) >> 10);
- UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, s->decorr[i].samplesA[0], L);
- L = L2;
- if (type != AV_SAMPLE_FMT_S16P)
- R2 = R + ((s->decorr[i].weightB * (int64_t)L2 + 512) >> 10);
- else
- R2 = R + ((s->decorr[i].weightB * L2 + 512) >> 10);
- UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, L2, R);
- R = R2;
- s->decorr[i].samplesA[0] = R;
- } else {
- if (type != AV_SAMPLE_FMT_S16P)
- R2 = R + ((s->decorr[i].weightB * (int64_t)s->decorr[i].samplesB[0] + 512) >> 10);
- else
- R2 = R + ((s->decorr[i].weightB * s->decorr[i].samplesB[0] + 512) >> 10);
- UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, s->decorr[i].samplesB[0], R);
- R = R2;
-
- if (t == -3) {
- R2 = s->decorr[i].samplesA[0];
- s->decorr[i].samplesA[0] = R;
- }
-
- if (type != AV_SAMPLE_FMT_S16P)
- L2 = L + ((s->decorr[i].weightA * (int64_t)R2 + 512) >> 10);
- else
- L2 = L + ((s->decorr[i].weightA * R2 + 512) >> 10);
- UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, R2, L);
- L = L2;
- s->decorr[i].samplesB[0] = L;
- }
- }
-
- if (type == AV_SAMPLE_FMT_S16P) {
- if (FFABS(L) + FFABS(R) > (1<<19)) {
- av_log(s->avctx, AV_LOG_ERROR, "sample %d %d too large\n", L, R);
- return AVERROR_INVALIDDATA;
- }
- }
-
- pos = (pos + 1) & 7;
- if (s->joint)
- L += (R -= (L >> 1));
- crc = (crc * 3 + L) * 3 + R;
-
- if (type == AV_SAMPLE_FMT_FLTP) {
- *dstfl_l++ = wv_get_value_float(s, &crc_extra_bits, L);
- *dstfl_r++ = wv_get_value_float(s, &crc_extra_bits, R);
- } else if (type == AV_SAMPLE_FMT_S32P) {
- *dst32_l++ = wv_get_value_integer(s, &crc_extra_bits, L);
- *dst32_r++ = wv_get_value_integer(s, &crc_extra_bits, R);
- } else {
- *dst16_l++ = wv_get_value_integer(s, &crc_extra_bits, L);
- *dst16_r++ = wv_get_value_integer(s, &crc_extra_bits, R);
- }
- count++;
- } while (!last && count < s->samples);
-
- wv_reset_saved_context(s);
-
- if (last && count < s->samples) {
- int size = av_get_bytes_per_sample(type);
- memset((uint8_t*)dst_l + count*size, 0, (s->samples-count)*size);
- memset((uint8_t*)dst_r + count*size, 0, (s->samples-count)*size);
- }
-
- if ((s->avctx->err_recognition & AV_EF_CRCCHECK) &&
- wv_check_crc(s, crc, crc_extra_bits))
- return AVERROR_INVALIDDATA;
-
- return 0;
-}
-
-static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb,
- void *dst, const int type)
-{
- int i, j, count = 0;
- int last, t;
- int A, S, T;
- int pos = s->pos;
- uint32_t crc = s->sc.crc;
- uint32_t crc_extra_bits = s->extra_sc.crc;
- int16_t *dst16 = dst;
- int32_t *dst32 = dst;
- float *dstfl = dst;
-
- s->one = s->zero = s->zeroes = 0;
- do {
- T = wv_get_value(s, gb, 0, &last);
- S = 0;
- if (last)
- break;
- for (i = 0; i < s->terms; i++) {
- t = s->decorr[i].value;
- if (t > 8) {
- if (t & 1)
- A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1];
- else
- A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1;
- s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];
- j = 0;
- } else {
- A = s->decorr[i].samplesA[pos];
- j = (pos + t) & 7;
- }
- if (type != AV_SAMPLE_FMT_S16P)
- S = T + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10);
- else
- S = T + ((s->decorr[i].weightA * A + 512) >> 10);
- if (A && T)
- s->decorr[i].weightA -= ((((T ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;
- s->decorr[i].samplesA[j] = T = S;
- }
- pos = (pos + 1) & 7;
- crc = crc * 3 + S;
-
- if (type == AV_SAMPLE_FMT_FLTP) {
- *dstfl++ = wv_get_value_float(s, &crc_extra_bits, S);
- } else if (type == AV_SAMPLE_FMT_S32P) {
- *dst32++ = wv_get_value_integer(s, &crc_extra_bits, S);
- } else {
- *dst16++ = wv_get_value_integer(s, &crc_extra_bits, S);
- }
- count++;
- } while (!last && count < s->samples);
-
- wv_reset_saved_context(s);
-
- if (last && count < s->samples) {
- int size = av_get_bytes_per_sample(type);
- memset((uint8_t*)dst + count*size, 0, (s->samples-count)*size);
- }
-
- if (s->avctx->err_recognition & AV_EF_CRCCHECK) {
- int ret = wv_check_crc(s, crc, crc_extra_bits);
- if (ret < 0 && s->avctx->err_recognition & AV_EF_EXPLODE)
- return ret;
- }
-
- return 0;
-}
-
-static av_cold int wv_alloc_frame_context(WavpackContext *c)
-{
- if (c->fdec_num == WV_MAX_FRAME_DECODERS)
- return -1;
-
- c->fdec[c->fdec_num] = av_mallocz(sizeof(**c->fdec));
- if (!c->fdec[c->fdec_num])
- return -1;
- c->fdec_num++;
- c->fdec[c->fdec_num - 1]->avctx = c->avctx;
- wv_reset_saved_context(c->fdec[c->fdec_num - 1]);
-
- return 0;
-}
-
-static int init_thread_copy(AVCodecContext *avctx)
-{
- WavpackContext *s = avctx->priv_data;
- s->avctx = avctx;
- return 0;
-}
-
-static av_cold int wavpack_decode_init(AVCodecContext *avctx)
-{
- WavpackContext *s = avctx->priv_data;
-
- s->avctx = avctx;
-
- s->fdec_num = 0;
-
- return 0;
-}
-
-static av_cold int wavpack_decode_end(AVCodecContext *avctx)
-{
- WavpackContext *s = avctx->priv_data;
- int i;
-
- for (i = 0; i < s->fdec_num; i++)
- av_freep(&s->fdec[i]);
- s->fdec_num = 0;
-
- return 0;
-}
-
-static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
- AVFrame *frame, const uint8_t *buf, int buf_size)
-{
- WavpackContext *wc = avctx->priv_data;
- ThreadFrame tframe = { .f = frame };
- WavpackFrameContext *s;
- GetByteContext gb;
- void *samples_l = NULL, *samples_r = NULL;
- int ret;
- int got_terms = 0, got_weights = 0, got_samples = 0,
- got_entropy = 0, got_bs = 0, got_float = 0, got_hybrid = 0;
- int i, j, id, size, ssize, weights, t;
- int bpp, chan = 0, chmask = 0, orig_bpp, sample_rate = 0;
- int multiblock;
-
- if (block_no >= wc->fdec_num && wv_alloc_frame_context(wc) < 0) {
- av_log(avctx, AV_LOG_ERROR, "Error creating frame decode context\n");
- return AVERROR_INVALIDDATA;
- }
-
- s = wc->fdec[block_no];
- if (!s) {
- av_log(avctx, AV_LOG_ERROR, "Context for block %d is not present\n",
- block_no);
- return AVERROR_INVALIDDATA;
- }
-
- memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr));
- memset(s->ch, 0, sizeof(s->ch));
- s->extra_bits = 0;
- s->and = s->or = s->shift = 0;
- s->got_extra_bits = 0;
-
- bytestream2_init(&gb, buf, buf_size);
-
- s->samples = bytestream2_get_le32(&gb);
- if (s->samples != wc->samples) {
- av_log(avctx, AV_LOG_ERROR, "Mismatching number of samples in "
- "a sequence: %d and %d\n", wc->samples, s->samples);
- return AVERROR_INVALIDDATA;
- }
- s->frame_flags = bytestream2_get_le32(&gb);
- bpp = av_get_bytes_per_sample(avctx->sample_fmt);
- orig_bpp = ((s->frame_flags & 0x03) + 1) << 3;
- multiblock = (s->frame_flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK;
-
- s->stereo = !(s->frame_flags & WV_MONO);
- s->stereo_in = (s->frame_flags & WV_FALSE_STEREO) ? 0 : s->stereo;
- s->joint = s->frame_flags & WV_JOINT_STEREO;
- s->hybrid = s->frame_flags & WV_HYBRID_MODE;
- s->hybrid_bitrate = s->frame_flags & WV_HYBRID_BITRATE;
- s->post_shift = bpp * 8 - orig_bpp + ((s->frame_flags >> 13) & 0x1f);
- s->hybrid_maxclip = ((1LL << (orig_bpp - 1)) - 1);
- s->hybrid_minclip = ((-1LL << (orig_bpp - 1)));
- s->CRC = bytestream2_get_le32(&gb);
-
- // parse metadata blocks
- while (bytestream2_get_bytes_left(&gb)) {
- id = bytestream2_get_byte(&gb);
- size = bytestream2_get_byte(&gb);
- if (id & WP_IDF_LONG) {
- size |= (bytestream2_get_byte(&gb)) << 8;
- size |= (bytestream2_get_byte(&gb)) << 16;
- }
- size <<= 1; // size is specified in words
- ssize = size;
- if (id & WP_IDF_ODD)
- size--;
- if (size < 0) {
- av_log(avctx, AV_LOG_ERROR,
- "Got incorrect block %02X with size %i\n", id, size);
- break;
- }
- if (bytestream2_get_bytes_left(&gb) < ssize) {
- av_log(avctx, AV_LOG_ERROR,
- "Block size %i is out of bounds\n", size);
- break;
- }
- switch (id & WP_IDF_MASK) {
- case WP_ID_DECTERMS:
- if (size > MAX_TERMS) {
- av_log(avctx, AV_LOG_ERROR, "Too many decorrelation terms\n");
- s->terms = 0;
- bytestream2_skip(&gb, ssize);
- continue;
- }
- s->terms = size;
- for (i = 0; i < s->terms; i++) {
- uint8_t val = bytestream2_get_byte(&gb);
- s->decorr[s->terms - i - 1].value = (val & 0x1F) - 5;
- s->decorr[s->terms - i - 1].delta = val >> 5;
- }
- got_terms = 1;
- break;
- case WP_ID_DECWEIGHTS:
- if (!got_terms) {
- av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");
- continue;
- }
- weights = size >> s->stereo_in;
- if (weights > MAX_TERMS || weights > s->terms) {
- av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n");
- bytestream2_skip(&gb, ssize);
- continue;
- }
- for (i = 0; i < weights; i++) {
- t = (int8_t)bytestream2_get_byte(&gb);
- s->decorr[s->terms - i - 1].weightA = t << 3;
- if (s->decorr[s->terms - i - 1].weightA > 0)
- s->decorr[s->terms - i - 1].weightA +=
- (s->decorr[s->terms - i - 1].weightA + 64) >> 7;
- if (s->stereo_in) {
- t = (int8_t)bytestream2_get_byte(&gb);
- s->decorr[s->terms - i - 1].weightB = t << 3;
- if (s->decorr[s->terms - i - 1].weightB > 0)
- s->decorr[s->terms - i - 1].weightB +=
- (s->decorr[s->terms - i - 1].weightB + 64) >> 7;
- }
- }
- got_weights = 1;
- break;
- case WP_ID_DECSAMPLES:
- if (!got_terms) {
- av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");
- continue;
- }
- t = 0;
- for (i = s->terms - 1; (i >= 0) && (t < size); i--) {
- if (s->decorr[i].value > 8) {
- s->decorr[i].samplesA[0] =
- wp_exp2(bytestream2_get_le16(&gb));
- s->decorr[i].samplesA[1] =
- wp_exp2(bytestream2_get_le16(&gb));
-
- if (s->stereo_in) {
- s->decorr[i].samplesB[0] =
- wp_exp2(bytestream2_get_le16(&gb));
- s->decorr[i].samplesB[1] =
- wp_exp2(bytestream2_get_le16(&gb));
- t += 4;
- }
- t += 4;
- } else if (s->decorr[i].value < 0) {
- s->decorr[i].samplesA[0] =
- wp_exp2(bytestream2_get_le16(&gb));
- s->decorr[i].samplesB[0] =
- wp_exp2(bytestream2_get_le16(&gb));
- t += 4;
- } else {
- for (j = 0; j < s->decorr[i].value; j++) {
- s->decorr[i].samplesA[j] =
- wp_exp2(bytestream2_get_le16(&gb));
- if (s->stereo_in) {
- s->decorr[i].samplesB[j] =
- wp_exp2(bytestream2_get_le16(&gb));
- }
- }
- t += s->decorr[i].value * 2 * (s->stereo_in + 1);
- }
- }
- got_samples = 1;
- break;
- case WP_ID_ENTROPY:
- if (size != 6 * (s->stereo_in + 1)) {
- av_log(avctx, AV_LOG_ERROR,
- "Entropy vars size should be %i, got %i.\n",
- 6 * (s->stereo_in + 1), size);
- bytestream2_skip(&gb, ssize);
- continue;
- }
- for (j = 0; j <= s->stereo_in; j++)
- for (i = 0; i < 3; i++) {
- s->ch[j].median[i] = wp_exp2(bytestream2_get_le16(&gb));
- }
- got_entropy = 1;
- break;
- case WP_ID_HYBRID:
- if (s->hybrid_bitrate) {
- for (i = 0; i <= s->stereo_in; i++) {
- s->ch[i].slow_level = wp_exp2(bytestream2_get_le16(&gb));
- size -= 2;
- }
- }
- for (i = 0; i < (s->stereo_in + 1); i++) {
- s->ch[i].bitrate_acc = bytestream2_get_le16(&gb) << 16;
- size -= 2;
- }
- if (size > 0) {
- for (i = 0; i < (s->stereo_in + 1); i++) {
- s->ch[i].bitrate_delta =
- wp_exp2((int16_t)bytestream2_get_le16(&gb));
- }
- } else {
- for (i = 0; i < (s->stereo_in + 1); i++)
- s->ch[i].bitrate_delta = 0;
- }
- got_hybrid = 1;
- break;
- case WP_ID_INT32INFO: {
- uint8_t val[4];
- if (size != 4) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid INT32INFO, size = %i\n",
- size);
- bytestream2_skip(&gb, ssize - 4);
- continue;
- }
- bytestream2_get_buffer(&gb, val, 4);
- if (val[0] > 32) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid INT32INFO, extra_bits = %d (> 32)\n", val[0]);
- continue;
- } else if (val[0]) {
- s->extra_bits = val[0];
- } else if (val[1]) {
- s->shift = val[1];
- } else if (val[2]) {
- s->and = s->or = 1;
- s->shift = val[2];
- } else if (val[3]) {
- s->and = 1;
- s->shift = val[3];
- }
- /* original WavPack decoder forces 32-bit lossy sound to be treated
- * as 24-bit one in order to have proper clipping */
- if (s->hybrid && bpp == 4 && s->post_shift < 8 && s->shift > 8) {
- s->post_shift += 8;
- s->shift -= 8;
- s->hybrid_maxclip >>= 8;
- s->hybrid_minclip >>= 8;
- }
- break;
- }
- case WP_ID_FLOATINFO:
- if (size != 4) {
- av_log(avctx, AV_LOG_ERROR,
- "Invalid FLOATINFO, size = %i\n", size);
- bytestream2_skip(&gb, ssize);
- continue;
- }
- s->float_flag = bytestream2_get_byte(&gb);
- s->float_shift = bytestream2_get_byte(&gb);
- s->float_max_exp = bytestream2_get_byte(&gb);
- got_float = 1;
- bytestream2_skip(&gb, 1);
- break;
- case WP_ID_DATA:
- s->sc.offset = bytestream2_tell(&gb);
- s->sc.size = size * 8;
- if ((ret = init_get_bits8(&s->gb, gb.buffer, size)) < 0)
- return ret;
- s->data_size = size * 8;
- bytestream2_skip(&gb, size);
- got_bs = 1;
- break;
- case WP_ID_EXTRABITS:
- if (size <= 4) {
- av_log(avctx, AV_LOG_ERROR, "Invalid EXTRABITS, size = %i\n",
- size);
- bytestream2_skip(&gb, size);
- continue;
- }
- s->extra_sc.offset = bytestream2_tell(&gb);
- s->extra_sc.size = size * 8;
- if ((ret = init_get_bits8(&s->gb_extra_bits, gb.buffer, size)) < 0)
- return ret;
- s->crc_extra_bits = get_bits_long(&s->gb_extra_bits, 32);
- bytestream2_skip(&gb, size);
- s->got_extra_bits = 1;
- break;
- case WP_ID_CHANINFO:
- if (size <= 1) {
- av_log(avctx, AV_LOG_ERROR,
- "Insufficient channel information\n");
- return AVERROR_INVALIDDATA;
- }
- chan = bytestream2_get_byte(&gb);
- switch (size - 2) {
- case 0:
- chmask = bytestream2_get_byte(&gb);
- break;
- case 1:
- chmask = bytestream2_get_le16(&gb);
- break;
- case 2:
- chmask = bytestream2_get_le24(&gb);
- break;
- case 3:
- chmask = bytestream2_get_le32(&gb);
- break;
- case 5:
- size = bytestream2_get_byte(&gb);
- if (avctx->channels != size)
- av_log(avctx, AV_LOG_WARNING, "%i channels signalled"
- " instead of %i.\n", size, avctx->channels);
- chan |= (bytestream2_get_byte(&gb) & 0xF) << 8;
- chmask = bytestream2_get_le16(&gb);
- break;
- default:
- av_log(avctx, AV_LOG_ERROR, "Invalid channel info size %d\n",
- size);
- chan = avctx->channels;
- chmask = avctx->channel_layout;
- }
- break;
- case WP_ID_SAMPLE_RATE:
- if (size != 3) {
- av_log(avctx, AV_LOG_ERROR, "Invalid custom sample rate.\n");
- return AVERROR_INVALIDDATA;
- }
- sample_rate = bytestream2_get_le24(&gb);
- break;
- default:
- bytestream2_skip(&gb, size);
- }
- if (id & WP_IDF_ODD)
- bytestream2_skip(&gb, 1);
- }
-
- if (!got_terms) {
- av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n");
- return AVERROR_INVALIDDATA;
- }
- if (!got_weights) {
- av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n");
- return AVERROR_INVALIDDATA;
- }
- if (!got_samples) {
- av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n");
- return AVERROR_INVALIDDATA;
- }
- if (!got_entropy) {
- av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n");
- return AVERROR_INVALIDDATA;
- }
- if (s->hybrid && !got_hybrid) {
- av_log(avctx, AV_LOG_ERROR, "Hybrid config not found\n");
- return AVERROR_INVALIDDATA;
- }
- if (!got_bs) {
- av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n");
- return AVERROR_INVALIDDATA;
- }
- if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLTP) {
- av_log(avctx, AV_LOG_ERROR, "Float information not found\n");
- return AVERROR_INVALIDDATA;
- }
- if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLTP) {
- const int size = get_bits_left(&s->gb_extra_bits);
- const int wanted = s->samples * s->extra_bits << s->stereo_in;
- if (size < wanted) {
- av_log(avctx, AV_LOG_ERROR, "Too small EXTRABITS\n");
- s->got_extra_bits = 0;
- }
- }
-
- if (!wc->ch_offset) {
- int sr = (s->frame_flags >> 23) & 0xf;
- if (sr == 0xf) {
- if (!sample_rate) {
- av_log(avctx, AV_LOG_ERROR, "Custom sample rate missing.\n");
- return AVERROR_INVALIDDATA;
- }
- avctx->sample_rate = sample_rate;
- } else
- avctx->sample_rate = wv_rates[sr];
-
- if (multiblock) {
- if (chan)
- avctx->channels = chan;
- if (chmask)
- avctx->channel_layout = chmask;
- } else {
- avctx->channels = s->stereo ? 2 : 1;
- avctx->channel_layout = s->stereo ? AV_CH_LAYOUT_STEREO :
- AV_CH_LAYOUT_MONO;
- }
-
- /* get output buffer */
- frame->nb_samples = s->samples + 1;
- if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
- return ret;
- frame->nb_samples = s->samples;
- }
-
- if (wc->ch_offset + s->stereo >= avctx->channels) {
- av_log(avctx, AV_LOG_WARNING, "Too many channels coded in a packet.\n");
- return (avctx->err_recognition & AV_EF_EXPLODE) ? AVERROR_INVALIDDATA : 0;
- }
-
- samples_l = frame->extended_data[wc->ch_offset];
- if (s->stereo)
- samples_r = frame->extended_data[wc->ch_offset + 1];
-
- wc->ch_offset += 1 + s->stereo;
-
- if (s->stereo_in) {
- ret = wv_unpack_stereo(s, &s->gb, samples_l, samples_r, avctx->sample_fmt);
- if (ret < 0)
- return ret;
- } else {
- ret = wv_unpack_mono(s, &s->gb, samples_l, avctx->sample_fmt);
- if (ret < 0)
- return ret;
-
- if (s->stereo)
- memcpy(samples_r, samples_l, bpp * s->samples);
- }
-
- return 0;
-}
-
-static void wavpack_decode_flush(AVCodecContext *avctx)
-{
- WavpackContext *s = avctx->priv_data;
- int i;
-
- for (i = 0; i < s->fdec_num; i++)
- wv_reset_saved_context(s->fdec[i]);
-}
-
-static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame_ptr, AVPacket *avpkt)
-{
- WavpackContext *s = avctx->priv_data;
- const uint8_t *buf = avpkt->data;
- int buf_size = avpkt->size;
- AVFrame *frame = data;
- int frame_size, ret, frame_flags;
-
- if (avpkt->size <= WV_HEADER_SIZE)
- return AVERROR_INVALIDDATA;
-
- s->block = 0;
- s->ch_offset = 0;
-
- /* determine number of samples */
- s->samples = AV_RL32(buf + 20);
- frame_flags = AV_RL32(buf + 24);
- if (s->samples <= 0 || s->samples > WV_MAX_SAMPLES) {
- av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n",
- s->samples);
- return AVERROR_INVALIDDATA;
- }
-
- if (frame_flags & 0x80) {
- avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
- } else if ((frame_flags & 0x03) <= 1) {
- avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
- } else {
- avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
- avctx->bits_per_raw_sample = ((frame_flags & 0x03) + 1) << 3;
- }
-
- while (buf_size > 0) {
- if (buf_size <= WV_HEADER_SIZE)
- break;
- frame_size = AV_RL32(buf + 4) - 12;
- buf += 20;
- buf_size -= 20;
- if (frame_size <= 0 || frame_size > buf_size) {
- av_log(avctx, AV_LOG_ERROR,
- "Block %d has invalid size (size %d vs. %d bytes left)\n",
- s->block, frame_size, buf_size);
- wavpack_decode_flush(avctx);
- return AVERROR_INVALIDDATA;
- }
- if ((ret = wavpack_decode_block(avctx, s->block,
- frame, buf, frame_size)) < 0) {
- wavpack_decode_flush(avctx);
- return ret;
- }
- s->block++;
- buf += frame_size;
- buf_size -= frame_size;
- }
-
- if (s->ch_offset != avctx->channels) {
- av_log(avctx, AV_LOG_ERROR, "Not enough channels coded in a packet.\n");
- return AVERROR_INVALIDDATA;
- }
-
- *got_frame_ptr = 1;
-
- return avpkt->size;
-}
-
-AVCodec ff_wavpack_decoder = {
- .name = "wavpack",
- .long_name = NULL_IF_CONFIG_SMALL("WavPack"),
- .type = AVMEDIA_TYPE_AUDIO,
- .id = AV_CODEC_ID_WAVPACK,
- .priv_data_size = sizeof(WavpackContext),
- .init = wavpack_decode_init,
- .close = wavpack_decode_end,
- .decode = wavpack_decode_frame,
- .flush = wavpack_decode_flush,
- .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/webp.c b/ffmpeg-2-8-11/libavcodec/webp.c
deleted file mode 100644
index 5c2961f..0000000
--- a/ffmpeg-2-8-11/libavcodec/webp.c
+++ /dev/null
@@ -1,1544 +0,0 @@
-/*
- * WebP (.webp) image decoder
- * Copyright (c) 2013 Aneesh Dogra <aneesh at sugarlabs.org>
- * Copyright (c) 2013 Justin Ruggles <justin.ruggles at gmail.com>
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-/**
- * @file
- * WebP image decoder
- *
- * @author Aneesh Dogra <aneesh at sugarlabs.org>
- * Container and Lossy decoding
- *
- * @author Justin Ruggles <justin.ruggles at gmail.com>
- * Lossless decoder
- * Compressed alpha for lossy
- *
- * @author James Almer <jamrial at gmail.com>
- * Exif metadata
- *
- * Unimplemented:
- * - Animation
- * - ICC profile
- * - XMP metadata
- */
-
-#define BITSTREAM_READER_LE
-#include "libavutil/imgutils.h"
-#include "avcodec.h"
-#include "bytestream.h"
-#include "exif.h"
-#include "internal.h"
-#include "get_bits.h"
-#include "thread.h"
-#include "vp8.h"
-
-#define VP8X_FLAG_ANIMATION 0x02
-#define VP8X_FLAG_XMP_METADATA 0x04
-#define VP8X_FLAG_EXIF_METADATA 0x08
-#define VP8X_FLAG_ALPHA 0x10
-#define VP8X_FLAG_ICC 0x20
-
-#define MAX_PALETTE_SIZE 256
-#define MAX_CACHE_BITS 11
-#define NUM_CODE_LENGTH_CODES 19
-#define HUFFMAN_CODES_PER_META_CODE 5
-#define NUM_LITERAL_CODES 256
-#define NUM_LENGTH_CODES 24
-#define NUM_DISTANCE_CODES 40
-#define NUM_SHORT_DISTANCES 120
-#define MAX_HUFFMAN_CODE_LENGTH 15
-
-static const uint16_t alphabet_sizes[HUFFMAN_CODES_PER_META_CODE] = {
- NUM_LITERAL_CODES + NUM_LENGTH_CODES,
- NUM_LITERAL_CODES, NUM_LITERAL_CODES, NUM_LITERAL_CODES,
- NUM_DISTANCE_CODES
-};
-
-static const uint8_t code_length_code_order[NUM_CODE_LENGTH_CODES] = {
- 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
-};
-
-static const int8_t lz77_distance_offsets[NUM_SHORT_DISTANCES][2] = {
- { 0, 1 }, { 1, 0 }, { 1, 1 }, { -1, 1 }, { 0, 2 }, { 2, 0 }, { 1, 2 }, { -1, 2 },
- { 2, 1 }, { -2, 1 }, { 2, 2 }, { -2, 2 }, { 0, 3 }, { 3, 0 }, { 1, 3 }, { -1, 3 },
- { 3, 1 }, { -3, 1 }, { 2, 3 }, { -2, 3 }, { 3, 2 }, { -3, 2 }, { 0, 4 }, { 4, 0 },
- { 1, 4 }, { -1, 4 }, { 4, 1 }, { -4, 1 }, { 3, 3 }, { -3, 3 }, { 2, 4 }, { -2, 4 },
- { 4, 2 }, { -4, 2 }, { 0, 5 }, { 3, 4 }, { -3, 4 }, { 4, 3 }, { -4, 3 }, { 5, 0 },
- { 1, 5 }, { -1, 5 }, { 5, 1 }, { -5, 1 }, { 2, 5 }, { -2, 5 }, { 5, 2 }, { -5, 2 },
- { 4, 4 }, { -4, 4 }, { 3, 5 }, { -3, 5 }, { 5, 3 }, { -5, 3 }, { 0, 6 }, { 6, 0 },
- { 1, 6 }, { -1, 6 }, { 6, 1 }, { -6, 1 }, { 2, 6 }, { -2, 6 }, { 6, 2 }, { -6, 2 },
- { 4, 5 }, { -4, 5 }, { 5, 4 }, { -5, 4 }, { 3, 6 }, { -3, 6 }, { 6, 3 }, { -6, 3 },
- { 0, 7 }, { 7, 0 }, { 1, 7 }, { -1, 7 }, { 5, 5 }, { -5, 5 }, { 7, 1 }, { -7, 1 },
- { 4, 6 }, { -4, 6 }, { 6, 4 }, { -6, 4 }, { 2, 7 }, { -2, 7 }, { 7, 2 }, { -7, 2 },
- { 3, 7 }, { -3, 7 }, { 7, 3 }, { -7, 3 }, { 5, 6 }, { -5, 6 }, { 6, 5 }, { -6, 5 },
- { 8, 0 }, { 4, 7 }, { -4, 7 }, { 7, 4 }, { -7, 4 }, { 8, 1 }, { 8, 2 }, { 6, 6 },
- { -6, 6 }, { 8, 3 }, { 5, 7 }, { -5, 7 }, { 7, 5 }, { -7, 5 }, { 8, 4 }, { 6, 7 },
- { -6, 7 }, { 7, 6 }, { -7, 6 }, { 8, 5 }, { 7, 7 }, { -7, 7 }, { 8, 6 }, { 8, 7 }
-};
-
-enum AlphaCompression {
- ALPHA_COMPRESSION_NONE,
- ALPHA_COMPRESSION_VP8L,
-};
-
-enum AlphaFilter {
- ALPHA_FILTER_NONE,
- ALPHA_FILTER_HORIZONTAL,
- ALPHA_FILTER_VERTICAL,
- ALPHA_FILTER_GRADIENT,
-};
-
-enum TransformType {
- PREDICTOR_TRANSFORM = 0,
- COLOR_TRANSFORM = 1,
- SUBTRACT_GREEN = 2,
- COLOR_INDEXING_TRANSFORM = 3,
-};
-
-enum PredictionMode {
- PRED_MODE_BLACK,
- PRED_MODE_L,
- PRED_MODE_T,
- PRED_MODE_TR,
- PRED_MODE_TL,
- PRED_MODE_AVG_T_AVG_L_TR,
- PRED_MODE_AVG_L_TL,
- PRED_MODE_AVG_L_T,
- PRED_MODE_AVG_TL_T,
- PRED_MODE_AVG_T_TR,
- PRED_MODE_AVG_AVG_L_TL_AVG_T_TR,
- PRED_MODE_SELECT,
- PRED_MODE_ADD_SUBTRACT_FULL,
- PRED_MODE_ADD_SUBTRACT_HALF,
-};
-
-enum HuffmanIndex {
- HUFF_IDX_GREEN = 0,
- HUFF_IDX_RED = 1,
- HUFF_IDX_BLUE = 2,
- HUFF_IDX_ALPHA = 3,
- HUFF_IDX_DIST = 4
-};
-
-/* The structure of WebP lossless is an optional series of transformation data,
- * followed by the primary image. The primary image also optionally contains
- * an entropy group mapping if there are multiple entropy groups. There is a
- * basic image type called an "entropy coded image" that is used for all of
- * these. The type of each entropy coded image is referred to by the
- * specification as its role. */
-enum ImageRole {
- /* Primary Image: Stores the actual pixels of the image. */
- IMAGE_ROLE_ARGB,
-
- /* Entropy Image: Defines which Huffman group to use for different areas of
- * the primary image. */
- IMAGE_ROLE_ENTROPY,
-
- /* Predictors: Defines which predictor type to use for different areas of
- * the primary image. */
- IMAGE_ROLE_PREDICTOR,
-
- /* Color Transform Data: Defines the color transformation for different
- * areas of the primary image. */
- IMAGE_ROLE_COLOR_TRANSFORM,
-
- /* Color Index: Stored as an image of height == 1. */
- IMAGE_ROLE_COLOR_INDEXING,
-
- IMAGE_ROLE_NB,
-};
-
-typedef struct HuffReader {
- VLC vlc; /* Huffman decoder context */
- int simple; /* whether to use simple mode */
- int nb_symbols; /* number of coded symbols */
- uint16_t simple_symbols[2]; /* symbols for simple mode */
-} HuffReader;
-
-typedef struct ImageContext {
- enum ImageRole role; /* role of this image */
- AVFrame *frame; /* AVFrame for data */
- int color_cache_bits; /* color cache size, log2 */
- uint32_t *color_cache; /* color cache data */
- int nb_huffman_groups; /* number of huffman groups */
- HuffReader *huffman_groups; /* reader for each huffman group */
- int size_reduction; /* relative size compared to primary image, log2 */
- int is_alpha_primary;
-} ImageContext;
-
-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 */
- AVCodecContext *avctx; /* parent AVCodecContext */
- int initialized; /* set once the VP8 context is initialized */
- int has_alpha; /* has a separate alpha chunk */
- enum AlphaCompression alpha_compression; /* compression type for alpha chunk */
- enum AlphaFilter alpha_filter; /* filtering method for alpha chunk */
- uint8_t *alpha_data; /* alpha chunk data */
- int alpha_data_size; /* alpha chunk data size */
- int has_exif; /* set after an EXIF chunk has been processed */
- AVDictionary *exif_metadata; /* EXIF chunk data */
- int width; /* image width */
- int height; /* image height */
- int lossless; /* indicates lossless or lossy */
-
- int nb_transforms; /* number of transforms */
- enum TransformType transforms[4]; /* transformations used in the image, in order */
- int reduced_width; /* reduced width for index image, if applicable */
- int nb_huffman_groups; /* number of huffman groups in the primary image */
- ImageContext image[IMAGE_ROLE_NB]; /* image context for each role */
-} WebPContext;
-
-#define GET_PIXEL(frame, x, y) \
- ((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x))
-
-#define GET_PIXEL_COMP(frame, x, y, c) \
- (*((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x) + c))
-
-static void image_ctx_free(ImageContext *img)
-{
- int i, j;
-
- av_free(img->color_cache);
- if (img->role != IMAGE_ROLE_ARGB && !img->is_alpha_primary)
- av_frame_free(&img->frame);
- if (img->huffman_groups) {
- for (i = 0; i < img->nb_huffman_groups; i++) {
- for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; j++)
- ff_free_vlc(&img->huffman_groups[i * HUFFMAN_CODES_PER_META_CODE + j].vlc);
- }
- av_free(img->huffman_groups);
- }
- 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) {
- if (r->nb_symbols == 1)
- return r->simple_symbols[0];
- else
- return r->simple_symbols[get_bits1(gb)];
- } else
- return webp_get_vlc(gb, r->vlc.table);
-}
-
-static int huff_reader_build_canonical(HuffReader *r, int *code_lengths,
- int alphabet_size)
-{
- int len = 0, sym, code = 0, ret;
- int max_code_length = 0;
- uint16_t *codes;
-
- /* special-case 1 symbol since the vlc reader cannot handle it */
- for (sym = 0; sym < alphabet_size; sym++) {
- if (code_lengths[sym] > 0) {
- len++;
- code = sym;
- if (len > 1)
- break;
- }
- }
- if (len == 1) {
- r->nb_symbols = 1;
- r->simple_symbols[0] = code;
- r->simple = 1;
- return 0;
- }
-
- for (sym = 0; sym < alphabet_size; sym++)
- max_code_length = FFMAX(max_code_length, code_lengths[sym]);
-
- if (max_code_length == 0 || max_code_length > MAX_HUFFMAN_CODE_LENGTH)
- return AVERROR(EINVAL);
-
- codes = av_malloc_array(alphabet_size, sizeof(*codes));
- if (!codes)
- return AVERROR(ENOMEM);
-
- code = 0;
- r->nb_symbols = 0;
- for (len = 1; len <= max_code_length; len++) {
- for (sym = 0; sym < alphabet_size; sym++) {
- if (code_lengths[sym] != len)
- continue;
- codes[sym] = code++;
- r->nb_symbols++;
- }
- code <<= 1;
- }
- if (!r->nb_symbols) {
- av_free(codes);
- return AVERROR_INVALIDDATA;
- }
-
- ret = init_vlc(&r->vlc, 8, alphabet_size,
- code_lengths, sizeof(*code_lengths), sizeof(*code_lengths),
- codes, sizeof(*codes), sizeof(*codes), 0);
- if (ret < 0) {
- av_free(codes);
- return ret;
- }
- r->simple = 0;
-
- av_free(codes);
- return 0;
-}
-
-static void read_huffman_code_simple(WebPContext *s, HuffReader *hc)
-{
- hc->nb_symbols = get_bits1(&s->gb) + 1;
-
- if (get_bits1(&s->gb))
- hc->simple_symbols[0] = get_bits(&s->gb, 8);
- else
- hc->simple_symbols[0] = get_bits1(&s->gb);
-
- if (hc->nb_symbols == 2)
- hc->simple_symbols[1] = get_bits(&s->gb, 8);
-
- hc->simple = 1;
-}
-
-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 };
- 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;
-
- for (i = 0; i < num_codes; i++)
- code_length_code_lengths[code_length_code_order[i]] = get_bits(&s->gb, 3);
-
- ret = huff_reader_build_canonical(&code_len_hc, code_length_code_lengths,
- NUM_CODE_LENGTH_CODES);
- if (ret < 0)
- goto finish;
-
- code_lengths = av_mallocz_array(alphabet_size, sizeof(*code_lengths));
- if (!code_lengths) {
- ret = AVERROR(ENOMEM);
- goto finish;
- }
-
- if (get_bits1(&s->gb)) {
- int bits = 2 + 2 * get_bits(&s->gb, 3);
- max_symbol = 2 + get_bits(&s->gb, bits);
- if (max_symbol > alphabet_size) {
- av_log(s->avctx, AV_LOG_ERROR, "max symbol %d > alphabet size %d\n",
- max_symbol, alphabet_size);
- ret = AVERROR_INVALIDDATA;
- goto finish;
- }
- } else {
- max_symbol = alphabet_size;
- }
-
- prev_code_len = 8;
- symbol = 0;
- while (symbol < alphabet_size) {
- int code_len;
-
- if (!max_symbol--)
- break;
- code_len = huff_reader_get_symbol(&code_len_hc, &s->gb);
- if (code_len < 16) {
- /* Code length code [0..15] indicates literal code lengths. */
- code_lengths[symbol++] = code_len;
- if (code_len)
- prev_code_len = code_len;
- } else {
- int repeat = 0, length = 0;
- switch (code_len) {
- case 16:
- /* Code 16 repeats the previous non-zero value [3..6] times,
- * i.e., 3 + ReadBits(2) times. If code 16 is used before a
- * non-zero value has been emitted, a value of 8 is repeated. */
- repeat = 3 + get_bits(&s->gb, 2);
- length = prev_code_len;
- break;
- case 17:
- /* Code 17 emits a streak of zeros [3..10], i.e.,
- * 3 + ReadBits(3) times. */
- repeat = 3 + get_bits(&s->gb, 3);
- break;
- case 18:
- /* Code 18 emits a streak of zeros of length [11..138], i.e.,
- * 11 + ReadBits(7) times. */
- repeat = 11 + get_bits(&s->gb, 7);
- break;
- }
- if (symbol + repeat > alphabet_size) {
- av_log(s->avctx, AV_LOG_ERROR,
- "invalid symbol %d + repeat %d > alphabet size %d\n",
- symbol, repeat, alphabet_size);
- ret = AVERROR_INVALIDDATA;
- goto finish;
- }
- while (repeat-- > 0)
- code_lengths[symbol++] = length;
- }
- }
-
- ret = huff_reader_build_canonical(hc, code_lengths, alphabet_size);
-
-finish:
- ff_free_vlc(&code_len_hc.vlc);
- av_free(code_lengths);
- return ret;
-}
-
-static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role,
- int w, int h);
-
-#define PARSE_BLOCK_SIZE(w, h) do { \
- block_bits = get_bits(&s->gb, 3) + 2; \
- blocks_w = FFALIGN((w), 1 << block_bits) >> block_bits; \
- blocks_h = FFALIGN((h), 1 << block_bits) >> block_bits; \
-} while (0)
-
-static int decode_entropy_image(WebPContext *s)
-{
- ImageContext *img;
- int ret, block_bits, width, blocks_w, blocks_h, x, y, max;
-
- width = s->width;
- if (s->reduced_width > 0)
- width = s->reduced_width;
-
- PARSE_BLOCK_SIZE(width, s->height);
-
- ret = decode_entropy_coded_image(s, IMAGE_ROLE_ENTROPY, blocks_w, blocks_h);
- if (ret < 0)
- return ret;
-
- img = &s->image[IMAGE_ROLE_ENTROPY];
- img->size_reduction = block_bits;
-
- /* the number of huffman groups is determined by the maximum group number
- * coded in the entropy image */
- max = 0;
- for (y = 0; y < img->frame->height; y++) {
- for (x = 0; x < img->frame->width; x++) {
- int p0 = GET_PIXEL_COMP(img->frame, x, y, 1);
- int p1 = GET_PIXEL_COMP(img->frame, x, y, 2);
- int p = p0 << 8 | p1;
- max = FFMAX(max, p);
- }
- }
- s->nb_huffman_groups = max + 1;
-
- return 0;
-}
-
-static int parse_transform_predictor(WebPContext *s)
-{
- int block_bits, blocks_w, blocks_h, ret;
-
- PARSE_BLOCK_SIZE(s->width, s->height);
-
- ret = decode_entropy_coded_image(s, IMAGE_ROLE_PREDICTOR, blocks_w,
- blocks_h);
- if (ret < 0)
- return ret;
-
- s->image[IMAGE_ROLE_PREDICTOR].size_reduction = block_bits;
-
- return 0;
-}
-
-static int parse_transform_color(WebPContext *s)
-{
- int block_bits, blocks_w, blocks_h, ret;
-
- PARSE_BLOCK_SIZE(s->width, s->height);
-
- ret = decode_entropy_coded_image(s, IMAGE_ROLE_COLOR_TRANSFORM, blocks_w,
- blocks_h);
- if (ret < 0)
- return ret;
-
- s->image[IMAGE_ROLE_COLOR_TRANSFORM].size_reduction = block_bits;
-
- return 0;
-}
-
-static int parse_transform_color_indexing(WebPContext *s)
-{
- ImageContext *img;
- int width_bits, index_size, ret, x;
- uint8_t *ct;
-
- index_size = get_bits(&s->gb, 8) + 1;
-
- if (index_size <= 2)
- width_bits = 3;
- else if (index_size <= 4)
- width_bits = 2;
- else if (index_size <= 16)
- width_bits = 1;
- else
- width_bits = 0;
-
- ret = decode_entropy_coded_image(s, IMAGE_ROLE_COLOR_INDEXING,
- index_size, 1);
- if (ret < 0)
- return ret;
-
- img = &s->image[IMAGE_ROLE_COLOR_INDEXING];
- img->size_reduction = width_bits;
- if (width_bits > 0)
- s->reduced_width = (s->width + ((1 << width_bits) - 1)) >> width_bits;
-
- /* color index values are delta-coded */
- ct = img->frame->data[0] + 4;
- for (x = 4; x < img->frame->width * 4; x++, ct++)
- ct[0] += ct[-4];
-
- return 0;
-}
-
-static HuffReader *get_huffman_group(WebPContext *s, ImageContext *img,
- int x, int y)
-{
- ImageContext *gimg = &s->image[IMAGE_ROLE_ENTROPY];
- int group = 0;
-
- if (gimg->size_reduction > 0) {
- int group_x = x >> gimg->size_reduction;
- int group_y = y >> gimg->size_reduction;
- int g0 = GET_PIXEL_COMP(gimg->frame, group_x, group_y, 1);
- int g1 = GET_PIXEL_COMP(gimg->frame, group_x, group_y, 2);
- group = g0 << 8 | g1;
- }
-
- return &img->huffman_groups[group * HUFFMAN_CODES_PER_META_CODE];
-}
-
-static av_always_inline void color_cache_put(ImageContext *img, uint32_t c)
-{
- uint32_t cache_idx = (0x1E35A7BD * c) >> (32 - img->color_cache_bits);
- img->color_cache[cache_idx] = c;
-}
-
-static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role,
- int w, int h)
-{
- ImageContext *img;
- HuffReader *hg;
- int i, j, ret, x, y, width;
-
- img = &s->image[role];
- img->role = role;
-
- if (!img->frame) {
- img->frame = av_frame_alloc();
- if (!img->frame)
- return AVERROR(ENOMEM);
- }
-
- img->frame->format = AV_PIX_FMT_ARGB;
- img->frame->width = w;
- img->frame->height = h;
-
- if (role == IMAGE_ROLE_ARGB && !img->is_alpha_primary) {
- ThreadFrame pt = { .f = img->frame };
- ret = ff_thread_get_buffer(s->avctx, &pt, 0);
- } else
- ret = av_frame_get_buffer(img->frame, 1);
- if (ret < 0)
- return ret;
-
- if (get_bits1(&s->gb)) {
- img->color_cache_bits = get_bits(&s->gb, 4);
- if (img->color_cache_bits < 1 || img->color_cache_bits > 11) {
- av_log(s->avctx, AV_LOG_ERROR, "invalid color cache bits: %d\n",
- img->color_cache_bits);
- return AVERROR_INVALIDDATA;
- }
- img->color_cache = av_mallocz_array(1 << img->color_cache_bits,
- sizeof(*img->color_cache));
- if (!img->color_cache)
- return AVERROR(ENOMEM);
- } else {
- img->color_cache_bits = 0;
- }
-
- img->nb_huffman_groups = 1;
- if (role == IMAGE_ROLE_ARGB && get_bits1(&s->gb)) {
- ret = decode_entropy_image(s);
- if (ret < 0)
- return ret;
- img->nb_huffman_groups = s->nb_huffman_groups;
- }
- img->huffman_groups = av_mallocz_array(img->nb_huffman_groups *
- HUFFMAN_CODES_PER_META_CODE,
- sizeof(*img->huffman_groups));
- if (!img->huffman_groups)
- return AVERROR(ENOMEM);
-
- for (i = 0; i < img->nb_huffman_groups; i++) {
- hg = &img->huffman_groups[i * HUFFMAN_CODES_PER_META_CODE];
- for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; j++) {
- int alphabet_size = alphabet_sizes[j];
- if (!j && img->color_cache_bits > 0)
- alphabet_size += 1 << img->color_cache_bits;
-
- if (get_bits1(&s->gb)) {
- read_huffman_code_simple(s, &hg[j]);
- } else {
- ret = read_huffman_code_normal(s, &hg[j], alphabet_size);
- if (ret < 0)
- return ret;
- }
- }
- }
-
- width = img->frame->width;
- if (role == IMAGE_ROLE_ARGB && s->reduced_width > 0)
- width = s->reduced_width;
-
- x = 0; y = 0;
- while (y < img->frame->height) {
- int v;
-
- hg = get_huffman_group(s, img, x, y);
- v = huff_reader_get_symbol(&hg[HUFF_IDX_GREEN], &s->gb);
- if (v < NUM_LITERAL_CODES) {
- /* literal pixel values */
- uint8_t *p = GET_PIXEL(img->frame, x, y);
- p[2] = v;
- p[1] = huff_reader_get_symbol(&hg[HUFF_IDX_RED], &s->gb);
- p[3] = huff_reader_get_symbol(&hg[HUFF_IDX_BLUE], &s->gb);
- p[0] = huff_reader_get_symbol(&hg[HUFF_IDX_ALPHA], &s->gb);
- if (img->color_cache_bits)
- color_cache_put(img, AV_RB32(p));
- x++;
- if (x == width) {
- x = 0;
- y++;
- }
- } else if (v < NUM_LITERAL_CODES + NUM_LENGTH_CODES) {
- /* LZ77 backwards mapping */
- int prefix_code, length, distance, ref_x, ref_y;
-
- /* parse length and distance */
- prefix_code = v - NUM_LITERAL_CODES;
- if (prefix_code < 4) {
- length = prefix_code + 1;
- } else {
- int extra_bits = (prefix_code - 2) >> 1;
- int offset = 2 + (prefix_code & 1) << extra_bits;
- length = offset + get_bits(&s->gb, extra_bits) + 1;
- }
- prefix_code = huff_reader_get_symbol(&hg[HUFF_IDX_DIST], &s->gb);
- if (prefix_code > 39) {
- av_log(s->avctx, AV_LOG_ERROR,
- "distance prefix code too large: %d\n", prefix_code);
- return AVERROR_INVALIDDATA;
- }
- if (prefix_code < 4) {
- distance = prefix_code + 1;
- } else {
- int extra_bits = prefix_code - 2 >> 1;
- int offset = 2 + (prefix_code & 1) << extra_bits;
- distance = offset + get_bits(&s->gb, extra_bits) + 1;
- }
-
- /* find reference location */
- if (distance <= NUM_SHORT_DISTANCES) {
- int xi = lz77_distance_offsets[distance - 1][0];
- int yi = lz77_distance_offsets[distance - 1][1];
- distance = FFMAX(1, xi + yi * width);
- } else {
- distance -= NUM_SHORT_DISTANCES;
- }
- ref_x = x;
- ref_y = y;
- if (distance <= x) {
- ref_x -= distance;
- distance = 0;
- } else {
- ref_x = 0;
- distance -= x;
- }
- while (distance >= width) {
- ref_y--;
- distance -= width;
- }
- if (distance > 0) {
- ref_x = width - distance;
- ref_y--;
- }
- ref_x = FFMAX(0, ref_x);
- ref_y = FFMAX(0, ref_y);
-
- /* copy pixels
- * source and dest regions can overlap and wrap lines, so just
- * copy per-pixel */
- for (i = 0; i < length; i++) {
- uint8_t *p_ref = GET_PIXEL(img->frame, ref_x, ref_y);
- uint8_t *p = GET_PIXEL(img->frame, x, y);
-
- AV_COPY32(p, p_ref);
- if (img->color_cache_bits)
- color_cache_put(img, AV_RB32(p));
- x++;
- ref_x++;
- if (x == width) {
- x = 0;
- y++;
- }
- if (ref_x == width) {
- ref_x = 0;
- ref_y++;
- }
- if (y == img->frame->height || ref_y == img->frame->height)
- break;
- }
- } else {
- /* read from color cache */
- uint8_t *p = GET_PIXEL(img->frame, x, y);
- int cache_idx = v - (NUM_LITERAL_CODES + NUM_LENGTH_CODES);
-
- if (!img->color_cache_bits) {
- av_log(s->avctx, AV_LOG_ERROR, "color cache not found\n");
- return AVERROR_INVALIDDATA;
- }
- if (cache_idx >= 1 << img->color_cache_bits) {
- av_log(s->avctx, AV_LOG_ERROR,
- "color cache index out-of-bounds\n");
- return AVERROR_INVALIDDATA;
- }
- AV_WB32(p, img->color_cache[cache_idx]);
- x++;
- if (x == width) {
- x = 0;
- y++;
- }
- }
- }
-
- return 0;
-}
-
-/* PRED_MODE_BLACK */
-static void inv_predict_0(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
- const uint8_t *p_t, const uint8_t *p_tr)
-{
- AV_WB32(p, 0xFF000000);
-}
-
-/* PRED_MODE_L */
-static void inv_predict_1(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
- const uint8_t *p_t, const uint8_t *p_tr)
-{
- AV_COPY32(p, p_l);
-}
-
-/* PRED_MODE_T */
-static void inv_predict_2(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
- const uint8_t *p_t, const uint8_t *p_tr)
-{
- AV_COPY32(p, p_t);
-}
-
-/* PRED_MODE_TR */
-static void inv_predict_3(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
- const uint8_t *p_t, const uint8_t *p_tr)
-{
- AV_COPY32(p, p_tr);
-}
-
-/* PRED_MODE_TL */
-static void inv_predict_4(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
- const uint8_t *p_t, const uint8_t *p_tr)
-{
- AV_COPY32(p, p_tl);
-}
-
-/* PRED_MODE_AVG_T_AVG_L_TR */
-static void inv_predict_5(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
- const uint8_t *p_t, const uint8_t *p_tr)
-{
- p[0] = p_t[0] + (p_l[0] + p_tr[0] >> 1) >> 1;
- p[1] = p_t[1] + (p_l[1] + p_tr[1] >> 1) >> 1;
- p[2] = p_t[2] + (p_l[2] + p_tr[2] >> 1) >> 1;
- p[3] = p_t[3] + (p_l[3] + p_tr[3] >> 1) >> 1;
-}
-
-/* PRED_MODE_AVG_L_TL */
-static void inv_predict_6(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
- const uint8_t *p_t, const uint8_t *p_tr)
-{
- p[0] = p_l[0] + p_tl[0] >> 1;
- p[1] = p_l[1] + p_tl[1] >> 1;
- p[2] = p_l[2] + p_tl[2] >> 1;
- p[3] = p_l[3] + p_tl[3] >> 1;
-}
-
-/* PRED_MODE_AVG_L_T */
-static void inv_predict_7(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
- const uint8_t *p_t, const uint8_t *p_tr)
-{
- p[0] = p_l[0] + p_t[0] >> 1;
- p[1] = p_l[1] + p_t[1] >> 1;
- p[2] = p_l[2] + p_t[2] >> 1;
- p[3] = p_l[3] + p_t[3] >> 1;
-}
-
-/* PRED_MODE_AVG_TL_T */
-static void inv_predict_8(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
- const uint8_t *p_t, const uint8_t *p_tr)
-{
- p[0] = p_tl[0] + p_t[0] >> 1;
- p[1] = p_tl[1] + p_t[1] >> 1;
- p[2] = p_tl[2] + p_t[2] >> 1;
- p[3] = p_tl[3] + p_t[3] >> 1;
-}
-
-/* PRED_MODE_AVG_T_TR */
-static void inv_predict_9(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
- const uint8_t *p_t, const uint8_t *p_tr)
-{
- p[0] = p_t[0] + p_tr[0] >> 1;
- p[1] = p_t[1] + p_tr[1] >> 1;
- p[2] = p_t[2] + p_tr[2] >> 1;
- p[3] = p_t[3] + p_tr[3] >> 1;
-}
-
-/* PRED_MODE_AVG_AVG_L_TL_AVG_T_TR */
-static void inv_predict_10(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
- const uint8_t *p_t, const uint8_t *p_tr)
-{
- p[0] = (p_l[0] + p_tl[0] >> 1) + (p_t[0] + p_tr[0] >> 1) >> 1;
- p[1] = (p_l[1] + p_tl[1] >> 1) + (p_t[1] + p_tr[1] >> 1) >> 1;
- p[2] = (p_l[2] + p_tl[2] >> 1) + (p_t[2] + p_tr[2] >> 1) >> 1;
- p[3] = (p_l[3] + p_tl[3] >> 1) + (p_t[3] + p_tr[3] >> 1) >> 1;
-}
-
-/* PRED_MODE_SELECT */
-static void inv_predict_11(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
- const uint8_t *p_t, const uint8_t *p_tr)
-{
- int diff = (FFABS(p_l[0] - p_tl[0]) - FFABS(p_t[0] - p_tl[0])) +
- (FFABS(p_l[1] - p_tl[1]) - FFABS(p_t[1] - p_tl[1])) +
- (FFABS(p_l[2] - p_tl[2]) - FFABS(p_t[2] - p_tl[2])) +
- (FFABS(p_l[3] - p_tl[3]) - FFABS(p_t[3] - p_tl[3]));
- if (diff <= 0)
- AV_COPY32(p, p_t);
- else
- AV_COPY32(p, p_l);
-}
-
-/* PRED_MODE_ADD_SUBTRACT_FULL */
-static void inv_predict_12(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
- const uint8_t *p_t, const uint8_t *p_tr)
-{
- p[0] = av_clip_uint8(p_l[0] + p_t[0] - p_tl[0]);
- p[1] = av_clip_uint8(p_l[1] + p_t[1] - p_tl[1]);
- p[2] = av_clip_uint8(p_l[2] + p_t[2] - p_tl[2]);
- p[3] = av_clip_uint8(p_l[3] + p_t[3] - p_tl[3]);
-}
-
-static av_always_inline uint8_t clamp_add_subtract_half(int a, int b, int c)
-{
- int d = a + b >> 1;
- return av_clip_uint8(d + (d - c) / 2);
-}
-
-/* PRED_MODE_ADD_SUBTRACT_HALF */
-static void inv_predict_13(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
- const uint8_t *p_t, const uint8_t *p_tr)
-{
- p[0] = clamp_add_subtract_half(p_l[0], p_t[0], p_tl[0]);
- p[1] = clamp_add_subtract_half(p_l[1], p_t[1], p_tl[1]);
- p[2] = clamp_add_subtract_half(p_l[2], p_t[2], p_tl[2]);
- p[3] = clamp_add_subtract_half(p_l[3], p_t[3], p_tl[3]);
-}
-
-typedef void (*inv_predict_func)(uint8_t *p, const uint8_t *p_l,
- const uint8_t *p_tl, const uint8_t *p_t,
- const uint8_t *p_tr);
-
-static const inv_predict_func inverse_predict[14] = {
- inv_predict_0, inv_predict_1, inv_predict_2, inv_predict_3,
- inv_predict_4, inv_predict_5, inv_predict_6, inv_predict_7,
- inv_predict_8, inv_predict_9, inv_predict_10, inv_predict_11,
- inv_predict_12, inv_predict_13,
-};
-
-static void inverse_prediction(AVFrame *frame, enum PredictionMode m, int x, int y)
-{
- uint8_t *dec, *p_l, *p_tl, *p_t, *p_tr;
- uint8_t p[4];
-
- dec = GET_PIXEL(frame, x, y);
- p_l = GET_PIXEL(frame, x - 1, y);
- p_tl = GET_PIXEL(frame, x - 1, y - 1);
- p_t = GET_PIXEL(frame, x, y - 1);
- if (x == frame->width - 1)
- p_tr = GET_PIXEL(frame, 0, y);
- else
- p_tr = GET_PIXEL(frame, x + 1, y - 1);
-
- inverse_predict[m](p, p_l, p_tl, p_t, p_tr);
-
- dec[0] += p[0];
- dec[1] += p[1];
- dec[2] += p[2];
- dec[3] += p[3];
-}
-
-static int apply_predictor_transform(WebPContext *s)
-{
- ImageContext *img = &s->image[IMAGE_ROLE_ARGB];
- ImageContext *pimg = &s->image[IMAGE_ROLE_PREDICTOR];
- int x, y;
-
- for (y = 0; y < img->frame->height; y++) {
- for (x = 0; x < img->frame->width; x++) {
- int tx = x >> pimg->size_reduction;
- int ty = y >> pimg->size_reduction;
- enum PredictionMode m = GET_PIXEL_COMP(pimg->frame, tx, ty, 2);
-
- if (x == 0) {
- if (y == 0)
- m = PRED_MODE_BLACK;
- else
- m = PRED_MODE_T;
- } else if (y == 0)
- m = PRED_MODE_L;
-
- if (m > 13) {
- av_log(s->avctx, AV_LOG_ERROR,
- "invalid predictor mode: %d\n", m);
- return AVERROR_INVALIDDATA;
- }
- inverse_prediction(img->frame, m, x, y);
- }
- }
- return 0;
-}
-
-static av_always_inline uint8_t color_transform_delta(uint8_t color_pred,
- uint8_t color)
-{
- return (int)ff_u8_to_s8(color_pred) * ff_u8_to_s8(color) >> 5;
-}
-
-static int apply_color_transform(WebPContext *s)
-{
- ImageContext *img, *cimg;
- int x, y, cx, cy;
- uint8_t *p, *cp;
-
- img = &s->image[IMAGE_ROLE_ARGB];
- cimg = &s->image[IMAGE_ROLE_COLOR_TRANSFORM];
-
- for (y = 0; y < img->frame->height; y++) {
- for (x = 0; x < img->frame->width; x++) {
- cx = x >> cimg->size_reduction;
- cy = y >> cimg->size_reduction;
- cp = GET_PIXEL(cimg->frame, cx, cy);
- p = GET_PIXEL(img->frame, x, y);
-
- p[1] += color_transform_delta(cp[3], p[2]);
- p[3] += color_transform_delta(cp[2], p[2]) +
- color_transform_delta(cp[1], p[1]);
- }
- }
- return 0;
-}
-
-static int apply_subtract_green_transform(WebPContext *s)
-{
- int x, y;
- ImageContext *img = &s->image[IMAGE_ROLE_ARGB];
-
- for (y = 0; y < img->frame->height; y++) {
- for (x = 0; x < img->frame->width; x++) {
- uint8_t *p = GET_PIXEL(img->frame, x, y);
- p[1] += p[2];
- p[3] += p[2];
- }
- }
- return 0;
-}
-
-static int apply_color_indexing_transform(WebPContext *s)
-{
- ImageContext *img;
- ImageContext *pal;
- int i, x, y;
- uint8_t *p;
-
- img = &s->image[IMAGE_ROLE_ARGB];
- pal = &s->image[IMAGE_ROLE_COLOR_INDEXING];
-
- if (pal->size_reduction > 0) {
- GetBitContext gb_g;
- uint8_t *line;
- int pixel_bits = 8 >> pal->size_reduction;
-
- line = av_malloc(img->frame->linesize[0]);
- if (!line)
- return AVERROR(ENOMEM);
-
- for (y = 0; y < img->frame->height; y++) {
- p = GET_PIXEL(img->frame, 0, y);
- memcpy(line, p, img->frame->linesize[0]);
- init_get_bits(&gb_g, line, img->frame->linesize[0] * 8);
- skip_bits(&gb_g, 16);
- i = 0;
- for (x = 0; x < img->frame->width; x++) {
- p = GET_PIXEL(img->frame, x, y);
- p[2] = get_bits(&gb_g, pixel_bits);
- i++;
- if (i == 1 << pal->size_reduction) {
- skip_bits(&gb_g, 24);
- i = 0;
- }
- }
- }
- av_free(line);
- }
-
- // switch to local palette if it's worth initializing it
- if (img->frame->height * img->frame->width > 300) {
- uint8_t palette[256 * 4];
- const int size = pal->frame->width * 4;
- av_assert0(size <= 1024U);
- memcpy(palette, GET_PIXEL(pal->frame, 0, 0), size); // copy palette
- // set extra entries to transparent black
- memset(palette + size, 0, 256 * 4 - size);
- for (y = 0; y < img->frame->height; y++) {
- for (x = 0; x < img->frame->width; x++) {
- p = GET_PIXEL(img->frame, x, y);
- i = p[2];
- AV_COPY32(p, &palette[i * 4]);
- }
- }
- } else {
- for (y = 0; y < img->frame->height; y++) {
- for (x = 0; x < img->frame->width; x++) {
- p = GET_PIXEL(img->frame, x, y);
- i = p[2];
- if (i >= pal->frame->width) {
- AV_WB32(p, 0x00000000);
- } else {
- const uint8_t *pi = GET_PIXEL(pal->frame, i, 0);
- AV_COPY32(p, pi);
- }
- }
- }
- }
-
- return 0;
-}
-
-static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p,
- int *got_frame, uint8_t *data_start,
- unsigned int data_size, int is_alpha_chunk)
-{
- WebPContext *s = avctx->priv_data;
- int w, h, ret, i, used;
-
- if (!is_alpha_chunk) {
- s->lossless = 1;
- avctx->pix_fmt = AV_PIX_FMT_ARGB;
- }
-
- ret = init_get_bits8(&s->gb, data_start, data_size);
- if (ret < 0)
- return ret;
-
- if (!is_alpha_chunk) {
- if (get_bits(&s->gb, 8) != 0x2F) {
- av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless signature\n");
- return AVERROR_INVALIDDATA;
- }
-
- w = get_bits(&s->gb, 14) + 1;
- h = get_bits(&s->gb, 14) + 1;
- if (s->width && s->width != w) {
- av_log(avctx, AV_LOG_WARNING, "Width mismatch. %d != %d\n",
- s->width, w);
- }
- s->width = w;
- if (s->height && s->height != h) {
- av_log(avctx, AV_LOG_WARNING, "Height mismatch. %d != %d\n",
- s->width, w);
- }
- s->height = h;
-
- ret = ff_set_dimensions(avctx, s->width, s->height);
- if (ret < 0)
- return ret;
-
- s->has_alpha = get_bits1(&s->gb);
-
- if (get_bits(&s->gb, 3) != 0x0) {
- av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless version\n");
- return AVERROR_INVALIDDATA;
- }
- } else {
- if (!s->width || !s->height)
- return AVERROR_BUG;
- w = s->width;
- h = s->height;
- }
-
- /* parse transformations */
- s->nb_transforms = 0;
- s->reduced_width = 0;
- used = 0;
- while (get_bits1(&s->gb)) {
- enum TransformType transform = get_bits(&s->gb, 2);
- if (used & (1 << transform)) {
- av_log(avctx, AV_LOG_ERROR, "Transform %d used more than once\n",
- transform);
- ret = AVERROR_INVALIDDATA;
- goto free_and_return;
- }
- used |= (1 << transform);
- s->transforms[s->nb_transforms++] = transform;
- switch (transform) {
- case PREDICTOR_TRANSFORM:
- ret = parse_transform_predictor(s);
- break;
- case COLOR_TRANSFORM:
- ret = parse_transform_color(s);
- break;
- case COLOR_INDEXING_TRANSFORM:
- ret = parse_transform_color_indexing(s);
- break;
- }
- if (ret < 0)
- goto free_and_return;
- }
-
- /* decode primary image */
- s->image[IMAGE_ROLE_ARGB].frame = p;
- if (is_alpha_chunk)
- s->image[IMAGE_ROLE_ARGB].is_alpha_primary = 1;
- ret = decode_entropy_coded_image(s, IMAGE_ROLE_ARGB, w, h);
- if (ret < 0)
- goto free_and_return;
-
- /* apply transformations */
- for (i = s->nb_transforms - 1; i >= 0; i--) {
- switch (s->transforms[i]) {
- case PREDICTOR_TRANSFORM:
- ret = apply_predictor_transform(s);
- break;
- case COLOR_TRANSFORM:
- ret = apply_color_transform(s);
- break;
- case SUBTRACT_GREEN:
- ret = apply_subtract_green_transform(s);
- break;
- case COLOR_INDEXING_TRANSFORM:
- ret = apply_color_indexing_transform(s);
- break;
- }
- if (ret < 0)
- goto free_and_return;
- }
-
- *got_frame = 1;
- p->pict_type = AV_PICTURE_TYPE_I;
- p->key_frame = 1;
- ret = data_size;
-
-free_and_return:
- for (i = 0; i < IMAGE_ROLE_NB; i++)
- image_ctx_free(&s->image[i]);
-
- return ret;
-}
-
-static void alpha_inverse_prediction(AVFrame *frame, enum AlphaFilter m)
-{
- int x, y, ls;
- uint8_t *dec;
-
- ls = frame->linesize[3];
-
- /* filter first row using horizontal filter */
- dec = frame->data[3] + 1;
- for (x = 1; x < frame->width; x++, dec++)
- *dec += *(dec - 1);
-
- /* filter first column using vertical filter */
- dec = frame->data[3] + ls;
- for (y = 1; y < frame->height; y++, dec += ls)
- *dec += *(dec - ls);
-
- /* filter the rest using the specified filter */
- switch (m) {
- case ALPHA_FILTER_HORIZONTAL:
- for (y = 1; y < frame->height; y++) {
- dec = frame->data[3] + y * ls + 1;
- for (x = 1; x < frame->width; x++, dec++)
- *dec += *(dec - 1);
- }
- break;
- case ALPHA_FILTER_VERTICAL:
- for (y = 1; y < frame->height; y++) {
- dec = frame->data[3] + y * ls + 1;
- for (x = 1; x < frame->width; x++, dec++)
- *dec += *(dec - ls);
- }
- break;
- case ALPHA_FILTER_GRADIENT:
- for (y = 1; y < frame->height; y++) {
- dec = frame->data[3] + y * ls + 1;
- for (x = 1; x < frame->width; x++, dec++)
- dec[0] += av_clip_uint8(*(dec - 1) + *(dec - ls) - *(dec - ls - 1));
- }
- break;
- }
-}
-
-static int vp8_lossy_decode_alpha(AVCodecContext *avctx, AVFrame *p,
- uint8_t *data_start,
- unsigned int data_size)
-{
- WebPContext *s = avctx->priv_data;
- int x, y, ret;
-
- if (s->alpha_compression == ALPHA_COMPRESSION_NONE) {
- GetByteContext gb;
-
- bytestream2_init(&gb, data_start, data_size);
- for (y = 0; y < s->height; y++)
- bytestream2_get_buffer(&gb, p->data[3] + p->linesize[3] * y,
- s->width);
- } else if (s->alpha_compression == ALPHA_COMPRESSION_VP8L) {
- uint8_t *ap, *pp;
- int alpha_got_frame = 0;
-
- s->alpha_frame = av_frame_alloc();
- if (!s->alpha_frame)
- return AVERROR(ENOMEM);
-
- ret = vp8_lossless_decode_frame(avctx, s->alpha_frame, &alpha_got_frame,
- data_start, data_size, 1);
- if (ret < 0) {
- av_frame_free(&s->alpha_frame);
- return ret;
- }
- if (!alpha_got_frame) {
- av_frame_free(&s->alpha_frame);
- return AVERROR_INVALIDDATA;
- }
-
- /* copy green component of alpha image to alpha plane of primary image */
- for (y = 0; y < s->height; y++) {
- ap = GET_PIXEL(s->alpha_frame, 0, y) + 2;
- pp = p->data[3] + p->linesize[3] * y;
- for (x = 0; x < s->width; x++) {
- *pp = *ap;
- pp++;
- ap += 4;
- }
- }
- av_frame_free(&s->alpha_frame);
- }
-
- /* apply alpha filtering */
- if (s->alpha_filter)
- alpha_inverse_prediction(p, s->alpha_filter);
-
- return 0;
-}
-
-static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p,
- int *got_frame, uint8_t *data_start,
- unsigned int data_size)
-{
- WebPContext *s = avctx->priv_data;
- AVPacket pkt;
- int ret;
-
- if (!s->initialized) {
- ff_vp8_decode_init(avctx);
- s->initialized = 1;
- if (s->has_alpha)
- avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
- }
- s->lossless = 0;
-
- if (data_size > INT_MAX) {
- av_log(avctx, AV_LOG_ERROR, "unsupported chunk size\n");
- return AVERROR_PATCHWELCOME;
- }
-
- av_init_packet(&pkt);
- pkt.data = data_start;
- pkt.size = data_size;
-
- ret = ff_vp8_decode_frame(avctx, p, got_frame, &pkt);
- if (s->has_alpha) {
- ret = vp8_lossy_decode_alpha(avctx, p, s->alpha_data,
- s->alpha_data_size);
- if (ret < 0)
- return ret;
- }
- return ret;
-}
-
-static int webp_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
- AVPacket *avpkt)
-{
- AVFrame * const p = data;
- WebPContext *s = avctx->priv_data;
- GetByteContext gb;
- int ret;
- uint32_t chunk_type, chunk_size;
- int vp8x_flags = 0;
-
- s->avctx = avctx;
- s->width = 0;
- s->height = 0;
- *got_frame = 0;
- s->has_alpha = 0;
- s->has_exif = 0;
- bytestream2_init(&gb, avpkt->data, avpkt->size);
-
- if (bytestream2_get_bytes_left(&gb) < 12)
- return AVERROR_INVALIDDATA;
-
- if (bytestream2_get_le32(&gb) != MKTAG('R', 'I', 'F', 'F')) {
- av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n");
- return AVERROR_INVALIDDATA;
- }
-
- chunk_size = bytestream2_get_le32(&gb);
- if (bytestream2_get_bytes_left(&gb) < chunk_size)
- return AVERROR_INVALIDDATA;
-
- if (bytestream2_get_le32(&gb) != MKTAG('W', 'E', 'B', 'P')) {
- av_log(avctx, AV_LOG_ERROR, "missing WEBP tag\n");
- return AVERROR_INVALIDDATA;
- }
-
- av_dict_free(&s->exif_metadata);
- while (bytestream2_get_bytes_left(&gb) > 8) {
- char chunk_str[5] = { 0 };
-
- chunk_type = bytestream2_get_le32(&gb);
- chunk_size = bytestream2_get_le32(&gb);
- if (chunk_size == UINT32_MAX)
- return AVERROR_INVALIDDATA;
- chunk_size += chunk_size & 1;
-
- if (bytestream2_get_bytes_left(&gb) < chunk_size)
- return AVERROR_INVALIDDATA;
-
- switch (chunk_type) {
- case MKTAG('V', 'P', '8', ' '):
- if (!*got_frame) {
- ret = vp8_lossy_decode_frame(avctx, p, got_frame,
- avpkt->data + bytestream2_tell(&gb),
- chunk_size);
- if (ret < 0)
- return ret;
- }
- bytestream2_skip(&gb, chunk_size);
- break;
- case MKTAG('V', 'P', '8', 'L'):
- if (!*got_frame) {
- ret = vp8_lossless_decode_frame(avctx, p, got_frame,
- avpkt->data + bytestream2_tell(&gb),
- chunk_size, 0);
- if (ret < 0)
- return ret;
- avctx->properties |= FF_CODEC_PROPERTY_LOSSLESS;
- }
- bytestream2_skip(&gb, chunk_size);
- break;
- case MKTAG('V', 'P', '8', 'X'):
- vp8x_flags = bytestream2_get_byte(&gb);
- bytestream2_skip(&gb, 3);
- s->width = bytestream2_get_le24(&gb) + 1;
- s->height = bytestream2_get_le24(&gb) + 1;
- ret = av_image_check_size(s->width, s->height, 0, avctx);
- if (ret < 0)
- return ret;
- break;
- case MKTAG('A', 'L', 'P', 'H'): {
- int alpha_header, filter_m, compression;
-
- if (!(vp8x_flags & VP8X_FLAG_ALPHA)) {
- av_log(avctx, AV_LOG_WARNING,
- "ALPHA chunk present, but alpha bit not set in the "
- "VP8X header\n");
- }
- if (chunk_size == 0) {
- av_log(avctx, AV_LOG_ERROR, "invalid ALPHA chunk size\n");
- return AVERROR_INVALIDDATA;
- }
- alpha_header = bytestream2_get_byte(&gb);
- s->alpha_data = avpkt->data + bytestream2_tell(&gb);
- s->alpha_data_size = chunk_size - 1;
- bytestream2_skip(&gb, s->alpha_data_size);
-
- filter_m = (alpha_header >> 2) & 0x03;
- compression = alpha_header & 0x03;
-
- if (compression > ALPHA_COMPRESSION_VP8L) {
- av_log(avctx, AV_LOG_VERBOSE,
- "skipping unsupported ALPHA chunk\n");
- } else {
- s->has_alpha = 1;
- s->alpha_compression = compression;
- s->alpha_filter = filter_m;
- }
-
- break;
- }
- case MKTAG('E', 'X', 'I', 'F'): {
- int le, ifd_offset, exif_offset = bytestream2_tell(&gb);
- GetByteContext exif_gb;
-
- if (s->has_exif) {
- av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra EXIF chunk\n");
- goto exif_end;
- }
- if (!(vp8x_flags & VP8X_FLAG_EXIF_METADATA))
- av_log(avctx, AV_LOG_WARNING,
- "EXIF chunk present, but Exif bit not set in the "
- "VP8X header\n");
-
- s->has_exif = 1;
- bytestream2_init(&exif_gb, avpkt->data + exif_offset,
- avpkt->size - exif_offset);
- if (ff_tdecode_header(&exif_gb, &le, &ifd_offset) < 0) {
- av_log(avctx, AV_LOG_ERROR, "invalid TIFF header "
- "in Exif data\n");
- goto exif_end;
- }
-
- bytestream2_seek(&exif_gb, ifd_offset, SEEK_SET);
- if (avpriv_exif_decode_ifd(avctx, &exif_gb, le, 0, &s->exif_metadata) < 0) {
- av_log(avctx, AV_LOG_ERROR, "error decoding Exif data\n");
- goto exif_end;
- }
-
- av_dict_copy(avpriv_frame_get_metadatap(data), s->exif_metadata, 0);
-
-exif_end:
- av_dict_free(&s->exif_metadata);
- bytestream2_skip(&gb, chunk_size);
- break;
- }
- case MKTAG('I', 'C', 'C', 'P'):
- case MKTAG('A', 'N', 'I', 'M'):
- case MKTAG('A', 'N', 'M', 'F'):
- case MKTAG('X', 'M', 'P', ' '):
- AV_WL32(chunk_str, chunk_type);
- av_log(avctx, AV_LOG_VERBOSE, "skipping unsupported chunk: %s\n",
- chunk_str);
- bytestream2_skip(&gb, chunk_size);
- break;
- default:
- AV_WL32(chunk_str, chunk_type);
- av_log(avctx, AV_LOG_VERBOSE, "skipping unknown chunk: %s\n",
- chunk_str);
- bytestream2_skip(&gb, chunk_size);
- break;
- }
- }
-
- if (!*got_frame) {
- av_log(avctx, AV_LOG_ERROR, "image data not found\n");
- return AVERROR_INVALIDDATA;
- }
-
- return avpkt->size;
-}
-
-static av_cold int webp_decode_close(AVCodecContext *avctx)
-{
- WebPContext *s = avctx->priv_data;
-
- if (s->initialized)
- return ff_vp8_decode_free(avctx);
-
- return 0;
-}
-
-AVCodec ff_webp_decoder = {
- .name = "webp",
- .long_name = NULL_IF_CONFIG_SMALL("WebP image"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_WEBP,
- .priv_data_size = sizeof(WebPContext),
- .decode = webp_decode_frame,
- .close = webp_decode_close,
- .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/wmv2dsp.c b/ffmpeg-2-8-11/libavcodec/wmv2dsp.c
deleted file mode 100644
index 40e0bef..0000000
--- a/ffmpeg-2-8-11/libavcodec/wmv2dsp.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * 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 "avcodec.h"
-#include "idctdsp.h"
-#include "mathops.h"
-#include "wmv2dsp.h"
-
-#define W0 2048
-#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
-#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
-#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
-#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */
-#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
-#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
-#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */
-
-static void wmv2_idct_row(short * b)
-{
- int s1, s2;
- int a0, a1, a2, a3, a4, a5, a6, a7;
-
- /* step 1 */
- a1 = W1 * b[1] + W7 * b[7];
- a7 = W7 * b[1] - W1 * b[7];
- a5 = W5 * b[5] + W3 * b[3];
- a3 = W3 * b[5] - W5 * b[3];
- a2 = W2 * b[2] + W6 * b[6];
- a6 = W6 * b[2] - W2 * b[6];
- a0 = W0 * b[0] + W0 * b[4];
- a4 = W0 * b[0] - W0 * b[4];
-
- /* step 2 */
- s1 = (181 * (a1 - a5 + a7 - a3) + 128) >> 8; // 1, 3, 5, 7
- s2 = (181 * (a1 - a5 - a7 + a3) + 128) >> 8;
-
- /* step 3 */
- b[0] = (a0 + a2 + a1 + a5 + (1 << 7)) >> 8;
- b[1] = (a4 + a6 + s1 + (1 << 7)) >> 8;
- b[2] = (a4 - a6 + s2 + (1 << 7)) >> 8;
- b[3] = (a0 - a2 + a7 + a3 + (1 << 7)) >> 8;
- b[4] = (a0 - a2 - a7 - a3 + (1 << 7)) >> 8;
- b[5] = (a4 - a6 - s2 + (1 << 7)) >> 8;
- b[6] = (a4 + a6 - s1 + (1 << 7)) >> 8;
- b[7] = (a0 + a2 - a1 - a5 + (1 << 7)) >> 8;
-}
-
-static void wmv2_idct_col(short * b)
-{
- int s1, s2;
- int a0, a1, a2, a3, a4, a5, a6, a7;
-
- /* step 1, with extended precision */
- a1 = (W1 * b[8 * 1] + W7 * b[8 * 7] + 4) >> 3;
- a7 = (W7 * b[8 * 1] - W1 * b[8 * 7] + 4) >> 3;
- a5 = (W5 * b[8 * 5] + W3 * b[8 * 3] + 4) >> 3;
- a3 = (W3 * b[8 * 5] - W5 * b[8 * 3] + 4) >> 3;
- a2 = (W2 * b[8 * 2] + W6 * b[8 * 6] + 4) >> 3;
- a6 = (W6 * b[8 * 2] - W2 * b[8 * 6] + 4) >> 3;
- a0 = (W0 * b[8 * 0] + W0 * b[8 * 4] ) >> 3;
- a4 = (W0 * b[8 * 0] - W0 * b[8 * 4] ) >> 3;
-
- /* step 2 */
- s1 = (181 * (a1 - a5 + a7 - a3) + 128) >> 8;
- s2 = (181 * (a1 - a5 - a7 + a3) + 128) >> 8;
-
- /* step 3 */
- b[8 * 0] = (a0 + a2 + a1 + a5 + (1 << 13)) >> 14;
- b[8 * 1] = (a4 + a6 + s1 + (1 << 13)) >> 14;
- b[8 * 2] = (a4 - a6 + s2 + (1 << 13)) >> 14;
- b[8 * 3] = (a0 - a2 + a7 + a3 + (1 << 13)) >> 14;
-
- b[8 * 4] = (a0 - a2 - a7 - a3 + (1 << 13)) >> 14;
- b[8 * 5] = (a4 - a6 - s2 + (1 << 13)) >> 14;
- b[8 * 6] = (a4 + a6 - s1 + (1 << 13)) >> 14;
- b[8 * 7] = (a0 + a2 - a1 - a5 + (1 << 13)) >> 14;
-}
-
-static void wmv2_idct_add_c(uint8_t *dest, int line_size, int16_t *block)
-{
- int i;
-
- for (i = 0; i < 64; i += 8)
- wmv2_idct_row(block + i);
- for (i = 0; i < 8; i++)
- wmv2_idct_col(block + i);
-
- for (i = 0; i < 8; i++) {
- dest[0] = av_clip_uint8(dest[0] + block[0]);
- dest[1] = av_clip_uint8(dest[1] + block[1]);
- dest[2] = av_clip_uint8(dest[2] + block[2]);
- dest[3] = av_clip_uint8(dest[3] + block[3]);
- dest[4] = av_clip_uint8(dest[4] + block[4]);
- dest[5] = av_clip_uint8(dest[5] + block[5]);
- dest[6] = av_clip_uint8(dest[6] + block[6]);
- dest[7] = av_clip_uint8(dest[7] + block[7]);
- dest += line_size;
- block += 8;
- }
-}
-
-static void wmv2_idct_put_c(uint8_t *dest, int line_size, int16_t *block)
-{
- int i;
-
- for (i = 0; i < 64; i += 8)
- wmv2_idct_row(block + i);
- for (i = 0; i < 8; i++)
- wmv2_idct_col(block + i);
-
- for (i = 0; i < 8; i++) {
- dest[0] = av_clip_uint8(block[0]);
- dest[1] = av_clip_uint8(block[1]);
- dest[2] = av_clip_uint8(block[2]);
- dest[3] = av_clip_uint8(block[3]);
- dest[4] = av_clip_uint8(block[4]);
- dest[5] = av_clip_uint8(block[5]);
- dest[6] = av_clip_uint8(block[6]);
- dest[7] = av_clip_uint8(block[7]);
- dest += line_size;
- block += 8;
- }
-}
-
-static void wmv2_mspel8_h_lowpass(uint8_t *dst, const uint8_t *src,
- int dstStride, int srcStride, int h)
-{
- const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
- int i;
-
- for (i = 0; i < h; i++) {
- dst[0] = cm[(9 * (src[0] + src[1]) - (src[-1] + src[2]) + 8) >> 4];
- dst[1] = cm[(9 * (src[1] + src[2]) - (src[0] + src[3]) + 8) >> 4];
- dst[2] = cm[(9 * (src[2] + src[3]) - (src[1] + src[4]) + 8) >> 4];
- dst[3] = cm[(9 * (src[3] + src[4]) - (src[2] + src[5]) + 8) >> 4];
- dst[4] = cm[(9 * (src[4] + src[5]) - (src[3] + src[6]) + 8) >> 4];
- dst[5] = cm[(9 * (src[5] + src[6]) - (src[4] + src[7]) + 8) >> 4];
- dst[6] = cm[(9 * (src[6] + src[7]) - (src[5] + src[8]) + 8) >> 4];
- dst[7] = cm[(9 * (src[7] + src[8]) - (src[6] + src[9]) + 8) >> 4];
- dst += dstStride;
- src += srcStride;
- }
-}
-
-static void wmv2_mspel8_v_lowpass(uint8_t *dst, const uint8_t *src,
- int dstStride, int srcStride, int w)
-{
- const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
- int i;
-
- for (i = 0; i < w; i++) {
- const int src_1 = src[-srcStride];
- const int src0 = src[0];
- const int src1 = src[srcStride];
- const int src2 = src[2 * srcStride];
- const int src3 = src[3 * srcStride];
- const int src4 = src[4 * srcStride];
- const int src5 = src[5 * srcStride];
- const int src6 = src[6 * srcStride];
- const int src7 = src[7 * srcStride];
- const int src8 = src[8 * srcStride];
- const int src9 = src[9 * srcStride];
- dst[0 * dstStride] = cm[(9 * (src0 + src1) - (src_1 + src2) + 8) >> 4];
- dst[1 * dstStride] = cm[(9 * (src1 + src2) - (src0 + src3) + 8) >> 4];
- dst[2 * dstStride] = cm[(9 * (src2 + src3) - (src1 + src4) + 8) >> 4];
- dst[3 * dstStride] = cm[(9 * (src3 + src4) - (src2 + src5) + 8) >> 4];
- dst[4 * dstStride] = cm[(9 * (src4 + src5) - (src3 + src6) + 8) >> 4];
- dst[5 * dstStride] = cm[(9 * (src5 + src6) - (src4 + src7) + 8) >> 4];
- dst[6 * dstStride] = cm[(9 * (src6 + src7) - (src5 + src8) + 8) >> 4];
- dst[7 * dstStride] = cm[(9 * (src7 + src8) - (src6 + src9) + 8) >> 4];
- src++;
- dst++;
- }
-}
-
-static void put_mspel8_mc10_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
-{
- uint8_t half[64];
-
- wmv2_mspel8_h_lowpass(half, src, 8, stride, 8);
- ff_put_pixels8_l2_8(dst, src, half, stride, stride, 8, 8);
-}
-
-static void put_mspel8_mc20_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
-{
- wmv2_mspel8_h_lowpass(dst, src, stride, stride, 8);
-}
-
-static void put_mspel8_mc30_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
-{
- uint8_t half[64];
-
- wmv2_mspel8_h_lowpass(half, src, 8, stride, 8);
- ff_put_pixels8_l2_8(dst, src + 1, half, stride, stride, 8, 8);
-}
-
-static void put_mspel8_mc02_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
-{
- wmv2_mspel8_v_lowpass(dst, src, stride, stride, 8);
-}
-
-static void put_mspel8_mc12_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
-{
- uint8_t halfH[88];
- uint8_t halfV[64];
- uint8_t halfHV[64];
-
- wmv2_mspel8_h_lowpass(halfH, src - stride, 8, stride, 11);
- wmv2_mspel8_v_lowpass(halfV, src, 8, stride, 8);
- wmv2_mspel8_v_lowpass(halfHV, halfH + 8, 8, 8, 8);
- ff_put_pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8);
-}
-
-static void put_mspel8_mc32_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
-{
- uint8_t halfH[88];
- uint8_t halfV[64];
- uint8_t halfHV[64];
-
- wmv2_mspel8_h_lowpass(halfH, src - stride, 8, stride, 11);
- wmv2_mspel8_v_lowpass(halfV, src + 1, 8, stride, 8);
- wmv2_mspel8_v_lowpass(halfHV, halfH + 8, 8, 8, 8);
- ff_put_pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8);
-}
-
-static void put_mspel8_mc22_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
-{
- uint8_t halfH[88];
-
- wmv2_mspel8_h_lowpass(halfH, src - stride, 8, stride, 11);
- wmv2_mspel8_v_lowpass(dst, halfH + 8, stride, 8, 8);
-}
-
-av_cold void ff_wmv2dsp_init(WMV2DSPContext *c)
-{
- c->idct_add = wmv2_idct_add_c;
- c->idct_put = wmv2_idct_put_c;
- c->idct_perm = FF_IDCT_PERM_NONE;
-
- c->put_mspel_pixels_tab[0] = ff_put_pixels8x8_c;
- c->put_mspel_pixels_tab[1] = put_mspel8_mc10_c;
- c->put_mspel_pixels_tab[2] = put_mspel8_mc20_c;
- c->put_mspel_pixels_tab[3] = put_mspel8_mc30_c;
- c->put_mspel_pixels_tab[4] = put_mspel8_mc02_c;
- c->put_mspel_pixels_tab[5] = put_mspel8_mc12_c;
- c->put_mspel_pixels_tab[6] = put_mspel8_mc22_c;
- c->put_mspel_pixels_tab[7] = put_mspel8_mc32_c;
-}
diff --git a/ffmpeg-2-8-11/libavcodec/wnv1.c b/ffmpeg-2-8-11/libavcodec/wnv1.c
deleted file mode 100644
index 9ff99b2..0000000
--- a/ffmpeg-2-8-11/libavcodec/wnv1.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Winnov WNV1 codec
- * Copyright (c) 2005 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
- */
-
-/**
- * @file
- * Winnov WNV1 codec.
- */
-
-#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 }
-};
-
-#define CODE_VLC_BITS 9
-static VLC code_vlc;
-
-/* returns modified base_value */
-static inline int wnv1_get_code(WNV1Context *w, int base_value)
-{
- int v = get_vlc2(&w->gb, code_vlc.table, CODE_VLC_BITS, 1);
-
- if (v == 15)
- return ff_reverse[get_bits(&w->gb, 8 - w->shift)];
- else
- return base_value + ((v - 7) << w->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;
- unsigned char *Y,*U,*V;
- int i, j, ret;
- int prev_y = 0, prev_u = 0, prev_v = 0;
- uint8_t *rbuf;
-
- if (buf_size <= 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);
- 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)
- return ret;
-
- if (buf[2] >> 4 == 6)
- l->shift = 2;
- else {
- l->shift = 8 - (buf[2] >> 4);
- if (l->shift > 4) {
- avpriv_request_sample(avctx,
- "Unknown WNV1 frame header value %i",
- buf[2] >> 4);
- l->shift = 4;
- }
- if (l->shift < 1) {
- avpriv_request_sample(avctx,
- "Unknown WNV1 frame header value %i",
- buf[2] >> 4);
- l->shift = 1;
- }
- }
-
- Y = p->data[0];
- U = p->data[1];
- 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 += p->linesize[0];
- U += p->linesize[1];
- V += p->linesize[2];
- }
-
-
- *got_frame = 1;
- av_free(rbuf);
-
- return buf_size;
-}
-
-static av_cold int decode_init(AVCodecContext *avctx)
-{
- static VLC_TYPE code_table[1 << CODE_VLC_BITS][2];
-
- 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);
-
- return 0;
-}
-
-AVCodec ff_wnv1_decoder = {
- .name = "wnv1",
- .long_name = NULL_IF_CONFIG_SMALL("Winnov WNV1"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_WNV1,
- .priv_data_size = sizeof(WNV1Context),
- .init = decode_init,
- .decode = decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/xwddec.c b/ffmpeg-2-8-11/libavcodec/xwddec.c
deleted file mode 100644
index 64cd841..0000000
--- a/ffmpeg-2-8-11/libavcodec/xwddec.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * XWD image format
- *
- * Copyright (c) 2012 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 <inttypes.h>
-
-#include "libavutil/imgutils.h"
-#include "avcodec.h"
-#include "bytestream.h"
-#include "internal.h"
-#include "xwd.h"
-
-static int xwd_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame, AVPacket *avpkt)
-{
- AVFrame *p = data;
- const uint8_t *buf = avpkt->data;
- int i, ret, buf_size = avpkt->size;
- uint32_t version, header_size, vclass, ncolors;
- uint32_t xoffset, be, bpp, lsize, rsize;
- uint32_t pixformat, pixdepth, bunit, bitorder, bpad;
- uint32_t rgb[3];
- uint8_t *ptr;
- GetByteContext gb;
-
- if (buf_size < XWD_HEADER_SIZE)
- return AVERROR_INVALIDDATA;
-
- bytestream2_init(&gb, buf, buf_size);
- header_size = bytestream2_get_be32u(&gb);
-
- version = bytestream2_get_be32u(&gb);
- if (version != XWD_VERSION) {
- av_log(avctx, AV_LOG_ERROR, "unsupported version\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (buf_size < header_size || header_size < XWD_HEADER_SIZE) {
- av_log(avctx, AV_LOG_ERROR, "invalid header size\n");
- return AVERROR_INVALIDDATA;
- }
-
- pixformat = bytestream2_get_be32u(&gb);
- pixdepth = bytestream2_get_be32u(&gb);
- avctx->width = bytestream2_get_be32u(&gb);
- avctx->height = bytestream2_get_be32u(&gb);
- xoffset = bytestream2_get_be32u(&gb);
- be = bytestream2_get_be32u(&gb);
- bunit = bytestream2_get_be32u(&gb);
- bitorder = bytestream2_get_be32u(&gb);
- bpad = bytestream2_get_be32u(&gb);
- bpp = bytestream2_get_be32u(&gb);
- lsize = bytestream2_get_be32u(&gb);
- vclass = bytestream2_get_be32u(&gb);
- rgb[0] = bytestream2_get_be32u(&gb);
- rgb[1] = bytestream2_get_be32u(&gb);
- rgb[2] = bytestream2_get_be32u(&gb);
- bytestream2_skipu(&gb, 8);
- ncolors = bytestream2_get_be32u(&gb);
- bytestream2_skipu(&gb, header_size - (XWD_HEADER_SIZE - 20));
-
- av_log(avctx, AV_LOG_DEBUG,
- "pixformat %"PRIu32", pixdepth %"PRIu32", bunit %"PRIu32", bitorder %"PRIu32", bpad %"PRIu32"\n",
- pixformat, pixdepth, bunit, bitorder, bpad);
- av_log(avctx, AV_LOG_DEBUG,
- "vclass %"PRIu32", ncolors %"PRIu32", bpp %"PRIu32", be %"PRIu32", lsize %"PRIu32", xoffset %"PRIu32"\n",
- vclass, ncolors, bpp, be, lsize, xoffset);
- av_log(avctx, AV_LOG_DEBUG,
- "red %0"PRIx32", green %0"PRIx32", blue %0"PRIx32"\n",
- rgb[0], rgb[1], rgb[2]);
-
- if (pixformat > XWD_Z_PIXMAP) {
- av_log(avctx, AV_LOG_ERROR, "invalid pixmap format\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (pixdepth == 0 || pixdepth > 32) {
- av_log(avctx, AV_LOG_ERROR, "invalid pixmap depth\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (xoffset) {
- avpriv_request_sample(avctx, "xoffset %"PRIu32"", xoffset);
- return AVERROR_PATCHWELCOME;
- }
-
- if (be > 1) {
- av_log(avctx, AV_LOG_ERROR, "invalid byte order\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (bitorder > 1) {
- av_log(avctx, AV_LOG_ERROR, "invalid bitmap bit order\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (bunit != 8 && bunit != 16 && bunit != 32) {
- av_log(avctx, AV_LOG_ERROR, "invalid bitmap unit\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (bpad != 8 && bpad != 16 && bpad != 32) {
- av_log(avctx, AV_LOG_ERROR, "invalid bitmap scan-line pad\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (bpp == 0 || bpp > 32) {
- av_log(avctx, AV_LOG_ERROR, "invalid bits per pixel\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (ncolors > 256) {
- av_log(avctx, AV_LOG_ERROR, "invalid number of entries in colormap\n");
- return AVERROR_INVALIDDATA;
- }
-
- if ((ret = av_image_check_size(avctx->width, avctx->height, 0, NULL)) < 0)
- return ret;
-
- rsize = FFALIGN(avctx->width * bpp, bpad) / 8;
- if (lsize < rsize) {
- av_log(avctx, AV_LOG_ERROR, "invalid bytes per scan-line\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (bytestream2_get_bytes_left(&gb) < ncolors * XWD_CMAP_SIZE + (uint64_t)avctx->height * lsize) {
- av_log(avctx, AV_LOG_ERROR, "input buffer too small\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (pixformat != XWD_Z_PIXMAP) {
- avpriv_report_missing_feature(avctx, "Pixmap format %"PRIu32, pixformat);
- return AVERROR_PATCHWELCOME;
- }
-
- avctx->pix_fmt = AV_PIX_FMT_NONE;
- switch (vclass) {
- case XWD_STATIC_GRAY:
- case XWD_GRAY_SCALE:
- if (bpp != 1 && bpp != 8)
- return AVERROR_INVALIDDATA;
- if (pixdepth == 1) {
- avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
- } else if (pixdepth == 8) {
- avctx->pix_fmt = AV_PIX_FMT_GRAY8;
- }
- break;
- case XWD_STATIC_COLOR:
- case XWD_PSEUDO_COLOR:
- if (bpp == 8)
- avctx->pix_fmt = AV_PIX_FMT_PAL8;
- break;
- case XWD_TRUE_COLOR:
- case XWD_DIRECT_COLOR:
- if (bpp != 16 && bpp != 24 && bpp != 32)
- return AVERROR_INVALIDDATA;
- if (bpp == 16 && pixdepth == 15) {
- if (rgb[0] == 0x7C00 && rgb[1] == 0x3E0 && rgb[2] == 0x1F)
- avctx->pix_fmt = be ? AV_PIX_FMT_RGB555BE : AV_PIX_FMT_RGB555LE;
- else if (rgb[0] == 0x1F && rgb[1] == 0x3E0 && rgb[2] == 0x7C00)
- avctx->pix_fmt = be ? AV_PIX_FMT_BGR555BE : AV_PIX_FMT_BGR555LE;
- } else if (bpp == 16 && pixdepth == 16) {
- if (rgb[0] == 0xF800 && rgb[1] == 0x7E0 && rgb[2] == 0x1F)
- avctx->pix_fmt = be ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_RGB565LE;
- else if (rgb[0] == 0x1F && rgb[1] == 0x7E0 && rgb[2] == 0xF800)
- avctx->pix_fmt = be ? AV_PIX_FMT_BGR565BE : AV_PIX_FMT_BGR565LE;
- } else if (bpp == 24) {
- if (rgb[0] == 0xFF0000 && rgb[1] == 0xFF00 && rgb[2] == 0xFF)
- avctx->pix_fmt = be ? AV_PIX_FMT_RGB24 : AV_PIX_FMT_BGR24;
- else if (rgb[0] == 0xFF && rgb[1] == 0xFF00 && rgb[2] == 0xFF0000)
- avctx->pix_fmt = be ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_RGB24;
- } else if (bpp == 32) {
- if (rgb[0] == 0xFF0000 && rgb[1] == 0xFF00 && rgb[2] == 0xFF)
- avctx->pix_fmt = be ? AV_PIX_FMT_ARGB : AV_PIX_FMT_BGRA;
- else if (rgb[0] == 0xFF && rgb[1] == 0xFF00 && rgb[2] == 0xFF0000)
- avctx->pix_fmt = be ? AV_PIX_FMT_ABGR : AV_PIX_FMT_RGBA;
- }
- bytestream2_skipu(&gb, ncolors * XWD_CMAP_SIZE);
- break;
- default:
- av_log(avctx, AV_LOG_ERROR, "invalid visual class\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
- avpriv_request_sample(avctx,
- "Unknown file: bpp %"PRIu32", pixdepth %"PRIu32", vclass %"PRIu32"",
- bpp, pixdepth, vclass);
- return AVERROR_PATCHWELCOME;
- }
-
- if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
- return ret;
-
- p->key_frame = 1;
- p->pict_type = AV_PICTURE_TYPE_I;
-
- if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
- uint32_t *dst = (uint32_t *)p->data[1];
- uint8_t red, green, blue;
-
- for (i = 0; i < ncolors; i++) {
-
- bytestream2_skipu(&gb, 4); // skip colormap entry number
- red = bytestream2_get_byteu(&gb);
- bytestream2_skipu(&gb, 1);
- green = bytestream2_get_byteu(&gb);
- bytestream2_skipu(&gb, 1);
- blue = bytestream2_get_byteu(&gb);
- bytestream2_skipu(&gb, 3); // skip bitmask flag and padding
-
- dst[i] = red << 16 | green << 8 | blue;
- }
- }
-
- ptr = p->data[0];
- for (i = 0; i < avctx->height; i++) {
- bytestream2_get_bufferu(&gb, ptr, rsize);
- bytestream2_skipu(&gb, lsize - rsize);
- ptr += p->linesize[0];
- }
-
- *got_frame = 1;
-
- return buf_size;
-}
-
-AVCodec ff_xwd_decoder = {
- .name = "xwd",
- .long_name = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_XWD,
- .decode = xwd_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavcodec/y41pdec.c b/ffmpeg-2-8-11/libavcodec/y41pdec.c
deleted file mode 100644
index 1b177d4..0000000
--- a/ffmpeg-2-8-11/libavcodec/y41pdec.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * y41p decoder
- *
- * Copyright (c) 2012 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 "avcodec.h"
-#include "internal.h"
-
-static av_cold int y41p_decode_init(AVCodecContext *avctx)
-{
- avctx->pix_fmt = AV_PIX_FMT_YUV411P;
- avctx->bits_per_raw_sample = 12;
-
- if (avctx->width & 7) {
- av_log(avctx, AV_LOG_WARNING, "y41p requires width to be divisible by 8.\n");
- }
-
- return 0;
-}
-
-static int y41p_decode_frame(AVCodecContext *avctx, void *data,
- int *got_frame, AVPacket *avpkt)
-{
- AVFrame *pic = data;
- uint8_t *src = avpkt->data;
- uint8_t *y, *u, *v;
- int i, j, ret;
-
- if (avpkt->size < 3LL * avctx->height * avctx->width / 2) {
- av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
- return AVERROR(EINVAL);
- }
-
- if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
- return ret;
-
- pic->key_frame = 1;
- pic->pict_type = AV_PICTURE_TYPE_I;
-
- for (i = avctx->height - 1; i >= 0 ; i--) {
- y = &pic->data[0][i * pic->linesize[0]];
- u = &pic->data[1][i * pic->linesize[1]];
- v = &pic->data[2][i * pic->linesize[2]];
- for (j = 0; j < avctx->width; j += 8) {
- *(u++) = *src++;
- *(y++) = *src++;
- *(v++) = *src++;
- *(y++) = *src++;
-
- *(u++) = *src++;
- *(y++) = *src++;
- *(v++) = *src++;
- *(y++) = *src++;
-
- *(y++) = *src++;
- *(y++) = *src++;
- *(y++) = *src++;
- *(y++) = *src++;
- }
- }
-
- *got_frame = 1;
-
- return avpkt->size;
-}
-
-AVCodec ff_y41p_decoder = {
- .name = "y41p",
- .long_name = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"),
- .type = AVMEDIA_TYPE_VIDEO,
- .id = AV_CODEC_ID_Y41P,
- .init = y41p_decode_init,
- .decode = y41p_decode_frame,
- .capabilities = AV_CODEC_CAP_DR1,
-};
diff --git a/ffmpeg-2-8-11/libavfilter/avfiltergraph.c b/ffmpeg-2-8-11/libavfilter/avfiltergraph.c
deleted file mode 100644
index bd3853f..0000000
--- a/ffmpeg-2-8-11/libavfilter/avfiltergraph.c
+++ /dev/null
@@ -1,1392 +0,0 @@
-/*
- * filter graphs
- * Copyright (c) 2008 Vitor Sessak
- * Copyright (c) 2007 Bobby Bingham
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-
-#include <string.h>
-
-#include "libavutil/avassert.h"
-#include "libavutil/avstring.h"
-#include "libavutil/bprint.h"
-#include "libavutil/channel_layout.h"
-#include "libavutil/internal.h"
-#include "libavutil/opt.h"
-#include "libavutil/pixdesc.h"
-
-#include "avfilter.h"
-#include "formats.h"
-#include "internal.h"
-#include "thread.h"
-
-#define OFFSET(x) offsetof(AVFilterGraph, x)
-#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
-static const AVOption filtergraph_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" },
- { "threads", "Maximum number of threads", OFFSET(nb_threads),
- AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
- {"scale_sws_opts" , "default scale filter options" , OFFSET(scale_sws_opts) ,
- AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
- {"aresample_swr_opts" , "default aresample filter options" , OFFSET(aresample_swr_opts) ,
- AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
- { NULL },
-};
-
-static const AVClass filtergraph_class = {
- .class_name = "AVFilterGraph",
- .item_name = av_default_item_name,
- .version = LIBAVUTIL_VERSION_INT,
- .option = filtergraph_options,
- .category = AV_CLASS_CATEGORY_FILTER,
-};
-
-#if !HAVE_THREADS
-void ff_graph_thread_free(AVFilterGraph *graph)
-{
-}
-
-int ff_graph_thread_init(AVFilterGraph *graph)
-{
- graph->thread_type = 0;
- graph->nb_threads = 1;
- return 0;
-}
-#endif
-
-AVFilterGraph *avfilter_graph_alloc(void)
-{
- AVFilterGraph *ret = av_mallocz(sizeof(*ret));
- if (!ret)
- return NULL;
-
- ret->internal = av_mallocz(sizeof(*ret->internal));
- if (!ret->internal) {
- av_freep(&ret);
- return NULL;
- }
-
- ret->av_class = &filtergraph_class;
- av_opt_set_defaults(ret);
-
- return ret;
-}
-
-void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter)
-{
- int i;
- for (i = 0; i < graph->nb_filters; i++) {
- if (graph->filters[i] == filter) {
- FFSWAP(AVFilterContext*, graph->filters[i],
- graph->filters[graph->nb_filters - 1]);
- graph->nb_filters--;
- return;
- }
- }
-}
-
-void avfilter_graph_free(AVFilterGraph **graph)
-{
- if (!*graph)
- return;
-
- while ((*graph)->nb_filters)
- avfilter_free((*graph)->filters[0]);
-
- ff_graph_thread_free(*graph);
-
- av_freep(&(*graph)->sink_links);
-
- av_freep(&(*graph)->scale_sws_opts);
- av_freep(&(*graph)->aresample_swr_opts);
- av_freep(&(*graph)->resample_lavr_opts);
- av_freep(&(*graph)->filters);
- av_freep(&(*graph)->internal);
- av_freep(graph);
-}
-
-#if FF_API_AVFILTER_OPEN
-int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
-{
- AVFilterContext **filters = av_realloc(graph->filters,
- sizeof(*filters) * (graph->nb_filters + 1));
- if (!filters)
- return AVERROR(ENOMEM);
-
- graph->filters = filters;
- graph->filters[graph->nb_filters++] = filter;
-
-#if FF_API_FOO_COUNT
-FF_DISABLE_DEPRECATION_WARNINGS
- graph->filter_count_unused = graph->nb_filters;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
- filter->graph = graph;
-
- return 0;
-}
-#endif
-
-int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt,
- const char *name, const char *args, void *opaque,
- AVFilterGraph *graph_ctx)
-{
- int ret;
-
- *filt_ctx = avfilter_graph_alloc_filter(graph_ctx, filt, name);
- if (!*filt_ctx)
- return AVERROR(ENOMEM);
-
- ret = avfilter_init_str(*filt_ctx, args);
- if (ret < 0)
- goto fail;
-
- return 0;
-
-fail:
- if (*filt_ctx)
- avfilter_free(*filt_ctx);
- *filt_ctx = NULL;
- return ret;
-}
-
-void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
-{
- graph->disable_auto_convert = flags;
-}
-
-AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
- const AVFilter *filter,
- const char *name)
-{
- AVFilterContext **filters, *s;
-
- if (graph->thread_type && !graph->internal->thread_execute) {
- if (graph->execute) {
- graph->internal->thread_execute = graph->execute;
- } else {
- int ret = ff_graph_thread_init(graph);
- if (ret < 0) {
- av_log(graph, AV_LOG_ERROR, "Error initializing threading.\n");
- return NULL;
- }
- }
- }
-
- s = ff_filter_alloc(filter, name);
- if (!s)
- return NULL;
-
- filters = av_realloc(graph->filters, sizeof(*filters) * (graph->nb_filters + 1));
- if (!filters) {
- avfilter_free(s);
- return NULL;
- }
-
- graph->filters = filters;
- graph->filters[graph->nb_filters++] = s;
-
-#if FF_API_FOO_COUNT
-FF_DISABLE_DEPRECATION_WARNINGS
- graph->filter_count_unused = graph->nb_filters;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
- s->graph = graph;
-
- return s;
-}
-
-/**
- * Check for the validity of graph.
- *
- * A graph is considered valid if all its input and output pads are
- * connected.
- *
- * @return >= 0 in case of success, a negative value otherwise
- */
-static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
-{
- AVFilterContext *filt;
- int i, j;
-
- for (i = 0; i < graph->nb_filters; i++) {
- const AVFilterPad *pad;
- filt = graph->filters[i];
-
- for (j = 0; j < filt->nb_inputs; j++) {
- if (!filt->inputs[j] || !filt->inputs[j]->src) {
- pad = &filt->input_pads[j];
- av_log(log_ctx, AV_LOG_ERROR,
- "Input pad \"%s\" with type %s of the filter instance \"%s\" of %s not connected to any source\n",
- pad->name, av_get_media_type_string(pad->type), filt->name, filt->filter->name);
- return AVERROR(EINVAL);
- }
- }
-
- for (j = 0; j < filt->nb_outputs; j++) {
- if (!filt->outputs[j] || !filt->outputs[j]->dst) {
- pad = &filt->output_pads[j];
- av_log(log_ctx, AV_LOG_ERROR,
- "Output pad \"%s\" with type %s of the filter instance \"%s\" of %s not connected to any destination\n",
- pad->name, av_get_media_type_string(pad->type), filt->name, filt->filter->name);
- return AVERROR(EINVAL);
- }
- }
- }
-
- return 0;
-}
-
-/**
- * Configure all the links of graphctx.
- *
- * @return >= 0 in case of success, a negative value otherwise
- */
-static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
-{
- AVFilterContext *filt;
- int i, ret;
-
- for (i = 0; i < graph->nb_filters; i++) {
- filt = graph->filters[i];
-
- if (!filt->nb_outputs) {
- if ((ret = avfilter_config_links(filt)))
- return ret;
- }
- }
-
- return 0;
-}
-
-AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, const char *name)
-{
- int i;
-
- for (i = 0; i < graph->nb_filters; i++)
- if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
- return graph->filters[i];
-
- return NULL;
-}
-
-static void sanitize_channel_layouts(void *log, AVFilterChannelLayouts *l)
-{
- if (!l)
- return;
- if (l->nb_channel_layouts) {
- if (l->all_layouts || l->all_counts)
- av_log(log, AV_LOG_WARNING, "All layouts set on non-empty list\n");
- l->all_layouts = l->all_counts = 0;
- } else {
- if (l->all_counts && !l->all_layouts)
- av_log(log, AV_LOG_WARNING, "All counts without all layouts\n");
- l->all_layouts = 1;
- }
-}
-
-static int filter_query_formats(AVFilterContext *ctx)
-{
- int ret, i;
- AVFilterFormats *formats;
- AVFilterChannelLayouts *chlayouts;
- AVFilterFormats *samplerates;
- enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
- ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
- AVMEDIA_TYPE_VIDEO;
-
- if ((ret = ctx->filter->query_formats(ctx)) < 0) {
- if (ret != AVERROR(EAGAIN))
- av_log(ctx, AV_LOG_ERROR, "Query format failed for '%s': %s\n",
- ctx->name, av_err2str(ret));
- return ret;
- }
-
- for (i = 0; i < ctx->nb_inputs; i++)
- sanitize_channel_layouts(ctx, ctx->inputs[i]->out_channel_layouts);
- for (i = 0; i < ctx->nb_outputs; i++)
- sanitize_channel_layouts(ctx, ctx->outputs[i]->in_channel_layouts);
-
- formats = ff_all_formats(type);
- if (!formats)
- return AVERROR(ENOMEM);
- ff_set_common_formats(ctx, formats);
- if (type == AVMEDIA_TYPE_AUDIO) {
- samplerates = ff_all_samplerates();
- if (!samplerates)
- return AVERROR(ENOMEM);
- ff_set_common_samplerates(ctx, samplerates);
- chlayouts = ff_all_channel_layouts();
- if (!chlayouts)
- return AVERROR(ENOMEM);
- ff_set_common_channel_layouts(ctx, chlayouts);
- }
- return 0;
-}
-
-static int formats_declared(AVFilterContext *f)
-{
- int i;
-
- for (i = 0; i < f->nb_inputs; i++) {
- if (!f->inputs[i]->out_formats)
- return 0;
- if (f->inputs[i]->type == AVMEDIA_TYPE_AUDIO &&
- !(f->inputs[i]->out_samplerates &&
- f->inputs[i]->out_channel_layouts))
- return 0;
- }
- for (i = 0; i < f->nb_outputs; i++) {
- if (!f->outputs[i]->in_formats)
- return 0;
- if (f->outputs[i]->type == AVMEDIA_TYPE_AUDIO &&
- !(f->outputs[i]->in_samplerates &&
- f->outputs[i]->in_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 {
- av_freep(&a->formats);
- 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.
- * @return >=0 if all links formats lists could be queried and merged;
- * AVERROR(EAGAIN) some progress was made in the queries or merging
- * and a later call may succeed;
- * AVERROR(EIO) (may be changed) plus a log message if no progress
- * was made and the negotiation is stuck;
- * a negative error code if some other error happened
- */
-static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
-{
- int i, j, ret;
- int scaler_count = 0, resampler_count = 0;
- int count_queried = 0; /* successful calls to query_formats() */
- int count_merged = 0; /* successful merge of formats lists */
- int count_already_merged = 0; /* lists already merged */
- int count_delayed = 0; /* lists that need to be merged later */
-
- for (i = 0; i < graph->nb_filters; i++) {
- AVFilterContext *f = graph->filters[i];
- if (formats_declared(f))
- continue;
- if (f->filter->query_formats)
- ret = filter_query_formats(f);
- else
- ret = ff_default_query_formats(f);
- if (ret < 0 && ret != AVERROR(EAGAIN))
- return ret;
- /* note: EAGAIN could indicate a partial success, not counted yet */
- count_queried += ret >= 0;
- }
-
- /* go through and merge as many format lists as possible */
- for (i = 0; i < graph->nb_filters; i++) {
- AVFilterContext *filter = graph->filters[i];
-
- for (j = 0; j < filter->nb_inputs; j++) {
- AVFilterLink *link = filter->inputs[j];
- int convert_needed = 0;
-
- 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))
- 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))
- convert_needed = 1;
- }
-
-#define MERGE_DISPATCH(field, statement) \
- if (!(link->in_ ## field && link->out_ ## field)) { \
- count_delayed++; \
- } else if (link->in_ ## field == link->out_ ## field) { \
- count_already_merged++; \
- } else if (!convert_needed) { \
- count_merged++; \
- statement \
- }
-
- 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(formats,
- if (!ff_merge_formats(link->in_formats, link->out_formats,
- link->type))
- convert_needed = 1;
- )
-#undef MERGE_DISPATCH
-
- if (convert_needed) {
- AVFilterContext *convert;
- AVFilter *filter;
- AVFilterLink *inlink, *outlink;
- char scale_args[256];
- char inst_name[30];
-
- /* couldn't merge format lists. auto-insert conversion filter */
- switch (link->type) {
- case AVMEDIA_TYPE_VIDEO:
- if (!(filter = avfilter_get_by_name("scale"))) {
- av_log(log_ctx, AV_LOG_ERROR, "'scale' filter "
- "not present, cannot convert pixel formats.\n");
- return AVERROR(EINVAL);
- }
-
- snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
- scaler_count++);
-
- if ((ret = avfilter_graph_create_filter(&convert, filter,
- inst_name, graph->scale_sws_opts, NULL,
- graph)) < 0)
- return ret;
- break;
- case AVMEDIA_TYPE_AUDIO:
- if (!(filter = avfilter_get_by_name("aresample"))) {
- av_log(log_ctx, AV_LOG_ERROR, "'aresample' filter "
- "not present, cannot convert audio formats.\n");
- return AVERROR(EINVAL);
- }
-
- snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",
- resampler_count++);
- scale_args[0] = '\0';
- if (graph->aresample_swr_opts)
- snprintf(scale_args, sizeof(scale_args), "%s",
- graph->aresample_swr_opts);
- if ((ret = avfilter_graph_create_filter(&convert, filter,
- inst_name, graph->aresample_swr_opts,
- NULL, graph)) < 0)
- return ret;
- break;
- default:
- return AVERROR(EINVAL);
- }
-
- if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
- return ret;
-
- if ((ret = filter_query_formats(convert)) < 0)
- return ret;
-
- 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);
- 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);
- }
- 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) {
- 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;
- }
- }
- }
- }
-
- av_log(graph, AV_LOG_DEBUG, "query_formats: "
- "%d queried, %d merged, %d already done, %d delayed\n",
- count_queried, count_merged, count_already_merged, count_delayed);
- if (count_delayed) {
- AVBPrint bp;
-
- /* if count_queried > 0, one filter at least did set its formats,
- that will give additional information to its neighbour;
- if count_merged > 0, one pair of formats lists at least was merged,
- that will give additional information to all connected filters;
- in both cases, progress was made and a new round must be done */
- if (count_queried || count_merged)
- return AVERROR(EAGAIN);
- av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
- for (i = 0; i < graph->nb_filters; i++)
- if (!formats_declared(graph->filters[i]))
- av_bprintf(&bp, "%s%s", bp.len ? ", " : "",
- graph->filters[i]->name);
- av_log(graph, AV_LOG_ERROR,
- "The following filters could not choose their formats: %s\n"
- "Consider inserting the (a)format filter near their input or "
- "output.\n", bp.str);
- return AVERROR(EIO);
- }
- return 0;
-}
-
-static int get_fmt_score(enum AVSampleFormat dst_fmt, enum AVSampleFormat src_fmt)
-{
- int score = 0;
-
- if (av_sample_fmt_is_planar(dst_fmt) != av_sample_fmt_is_planar(src_fmt))
- score ++;
-
- if (av_get_bytes_per_sample(dst_fmt) < av_get_bytes_per_sample(src_fmt)) {
- score += 100 * (av_get_bytes_per_sample(src_fmt) - av_get_bytes_per_sample(dst_fmt));
- }else
- score += 10 * (av_get_bytes_per_sample(dst_fmt) - av_get_bytes_per_sample(src_fmt));
-
- if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_S32 &&
- av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_FLT)
- score += 20;
-
- if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_FLT &&
- av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_S32)
- score += 2;
-
- return score;
-}
-
-static enum AVSampleFormat find_best_sample_fmt_of_2(enum AVSampleFormat dst_fmt1, enum AVSampleFormat dst_fmt2,
- enum AVSampleFormat src_fmt)
-{
- int score1, score2;
-
- score1 = get_fmt_score(dst_fmt1, src_fmt);
- score2 = get_fmt_score(dst_fmt2, src_fmt);
-
- return score1 < score2 ? dst_fmt1 : dst_fmt2;
-}
-
-static int pick_format(AVFilterLink *link, AVFilterLink *ref)
-{
- if (!link || !link->in_formats)
- return 0;
-
- if (link->type == AVMEDIA_TYPE_VIDEO) {
- if(ref && ref->type == AVMEDIA_TYPE_VIDEO){
- 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; i<link->in_formats->nb_formats; i++) {
- enum AVPixelFormat p = link->in_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(ref->format), has_alpha);
- link->in_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; i<link->in_formats->nb_formats; i++) {
- enum AVSampleFormat p = link->in_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(ref->format));
- link->in_formats->formats[0] = best;
- }
- }
-
- link->in_formats->nb_formats = 1;
- link->format = link->in_formats->formats[0];
-
- if (link->type == AVMEDIA_TYPE_AUDIO) {
- if (!link->in_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];
-
- if (link->in_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)
- 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];
- 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);
-
- return 0;
-}
-
-#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) \
- continue; \
- fmt = link->out_ ## 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) \
- continue; \
- fmts = out_link->in_ ## list; \
- \
- if (!out_link->in_ ## list->nb) { \
- add_format(&out_link->in_ ##list, fmt); \
- ret = 1; \
- break; \
- } \
- \
- for (k = 0; k < out_link->in_ ## list->nb; k++) \
- if (fmts->var[k] == fmt) { \
- fmts->var[0] = fmt; \
- fmts->nb = 1; \
- ret = 1; \
- break; \
- } \
- } \
- } \
-} while (0)
-
-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);
- REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats,
- 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)
- continue;
- fmt = inlink->out_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;
- if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1)
- continue;
-
- if (fmts->all_layouts &&
- (!FF_LAYOUT2COUNT(fmt) || fmts->all_counts)) {
- /* Turn the infinite list into a singleton */
- fmts->all_layouts = fmts->all_counts = 0;
- ff_add_channel_layout(&outlink->in_channel_layouts, fmt);
- break;
- }
-
- for (k = 0; k < outlink->in_channel_layouts->nb_channel_layouts; k++) {
- if (fmts->channel_layouts[k] == fmt) {
- fmts->channel_layouts[0] = fmt;
- fmts->nb_channel_layouts = 1;
- ret = 1;
- break;
- }
- }
- }
- }
-
- return ret;
-}
-
-static void reduce_formats(AVFilterGraph *graph)
-{
- int i, reduced;
-
- do {
- reduced = 0;
-
- for (i = 0; i < graph->nb_filters; i++)
- reduced |= reduce_formats_on_filter(graph->filters[i]);
- } while (reduced);
-}
-
-static void swap_samplerates_on_filter(AVFilterContext *filter)
-{
- AVFilterLink *link = NULL;
- int sample_rate;
- int i, j;
-
- for (i = 0; i < filter->nb_inputs; i++) {
- link = filter->inputs[i];
-
- if (link->type == AVMEDIA_TYPE_AUDIO &&
- link->out_samplerates->nb_formats== 1)
- break;
- }
- if (i == filter->nb_inputs)
- return;
-
- sample_rate = link->out_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)
- continue;
-
- for (j = 0; j < outlink->in_samplerates->nb_formats; j++) {
- int diff = abs(sample_rate - outlink->in_samplerates->formats[j]);
-
- if (diff < best_diff) {
- best_diff = diff;
- best_idx = j;
- }
- }
- FFSWAP(int, outlink->in_samplerates->formats[0],
- outlink->in_samplerates->formats[best_idx]);
- }
-}
-
-static void swap_samplerates(AVFilterGraph *graph)
-{
- int i;
-
- for (i = 0; i < graph->nb_filters; i++)
- swap_samplerates_on_filter(graph->filters[i]);
-}
-
-#define CH_CENTER_PAIR (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)
-#define CH_FRONT_PAIR (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT)
-#define CH_STEREO_PAIR (AV_CH_STEREO_LEFT | AV_CH_STEREO_RIGHT)
-#define CH_WIDE_PAIR (AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT)
-#define CH_SIDE_PAIR (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)
-#define CH_DIRECT_PAIR (AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT)
-#define CH_BACK_PAIR (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)
-
-/* allowable substitutions for channel pairs when comparing layouts,
- * ordered by priority for both values */
-static const uint64_t ch_subst[][2] = {
- { CH_FRONT_PAIR, CH_CENTER_PAIR },
- { CH_FRONT_PAIR, CH_WIDE_PAIR },
- { CH_FRONT_PAIR, AV_CH_FRONT_CENTER },
- { CH_CENTER_PAIR, CH_FRONT_PAIR },
- { CH_CENTER_PAIR, CH_WIDE_PAIR },
- { CH_CENTER_PAIR, AV_CH_FRONT_CENTER },
- { CH_WIDE_PAIR, CH_FRONT_PAIR },
- { CH_WIDE_PAIR, CH_CENTER_PAIR },
- { CH_WIDE_PAIR, AV_CH_FRONT_CENTER },
- { AV_CH_FRONT_CENTER, CH_FRONT_PAIR },
- { AV_CH_FRONT_CENTER, CH_CENTER_PAIR },
- { AV_CH_FRONT_CENTER, CH_WIDE_PAIR },
- { CH_SIDE_PAIR, CH_DIRECT_PAIR },
- { CH_SIDE_PAIR, CH_BACK_PAIR },
- { CH_SIDE_PAIR, AV_CH_BACK_CENTER },
- { CH_BACK_PAIR, CH_DIRECT_PAIR },
- { CH_BACK_PAIR, CH_SIDE_PAIR },
- { CH_BACK_PAIR, AV_CH_BACK_CENTER },
- { AV_CH_BACK_CENTER, CH_BACK_PAIR },
- { AV_CH_BACK_CENTER, CH_DIRECT_PAIR },
- { AV_CH_BACK_CENTER, CH_SIDE_PAIR },
-};
-
-static void swap_channel_layouts_on_filter(AVFilterContext *filter)
-{
- AVFilterLink *link = NULL;
- int i, j, k;
-
- for (i = 0; i < filter->nb_inputs; i++) {
- link = filter->inputs[i];
-
- if (link->type == AVMEDIA_TYPE_AUDIO &&
- link->out_channel_layouts->nb_channel_layouts == 1)
- break;
- }
- if (i == filter->nb_inputs)
- return;
-
- for (i = 0; i < filter->nb_outputs; i++) {
- AVFilterLink *outlink = filter->outputs[i];
- 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)
- 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];
- 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;
- int matched_channels, extra_channels;
- int score = 100000;
-
- if (FF_LAYOUT2COUNT(in_chlayout) || FF_LAYOUT2COUNT(out_chlayout)) {
- /* Compute score in case the input or output layout encodes
- a channel count; in this case the score is not altered by
- the computation afterwards, as in_chlayout and
- out_chlayout have both been set to 0 */
- if (FF_LAYOUT2COUNT(in_chlayout))
- in_channels = FF_LAYOUT2COUNT(in_chlayout);
- if (FF_LAYOUT2COUNT(out_chlayout))
- out_channels = FF_LAYOUT2COUNT(out_chlayout);
- score -= 10000 + FFABS(out_channels - in_channels) +
- (in_channels > out_channels ? 10000 : 0);
- in_chlayout = out_chlayout = 0;
- /* Let the remaining computation run, even if the score
- value is not altered */
- }
-
- /* channel substitution */
- for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {
- uint64_t cmp0 = ch_subst[k][0];
- uint64_t cmp1 = ch_subst[k][1];
- if (( in_chlayout & cmp0) && (!(out_chlayout & cmp0)) &&
- (out_chlayout & cmp1) && (!( in_chlayout & cmp1))) {
- in_chlayout &= ~cmp0;
- out_chlayout &= ~cmp1;
- /* add score for channel match, minus a deduction for
- having to do the substitution */
- score += 10 * av_get_channel_layout_nb_channels(cmp1) - 2;
- }
- }
-
- /* no penalty for LFE channel mismatch */
- if ( (in_chlayout & AV_CH_LOW_FREQUENCY) &&
- (out_chlayout & AV_CH_LOW_FREQUENCY))
- score += 10;
- in_chlayout &= ~AV_CH_LOW_FREQUENCY;
- out_chlayout &= ~AV_CH_LOW_FREQUENCY;
-
- matched_channels = av_get_channel_layout_nb_channels(in_chlayout &
- out_chlayout);
- extra_channels = av_get_channel_layout_nb_channels(out_chlayout &
- (~in_chlayout));
- score += 10 * matched_channels - 5 * extra_channels;
-
- if (score > best_score ||
- (count_diff < best_count_diff && score == best_score)) {
- best_score = score;
- best_idx = j;
- best_count_diff = count_diff;
- }
- }
- av_assert0(best_idx >= 0);
- FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],
- outlink->in_channel_layouts->channel_layouts[best_idx]);
- }
-
-}
-
-static void swap_channel_layouts(AVFilterGraph *graph)
-{
- int i;
-
- for (i = 0; i < graph->nb_filters; i++)
- swap_channel_layouts_on_filter(graph->filters[i]);
-}
-
-static void swap_sample_fmts_on_filter(AVFilterContext *filter)
-{
- AVFilterLink *link = NULL;
- int format, bps;
- int i, j;
-
- for (i = 0; i < filter->nb_inputs; i++) {
- link = filter->inputs[i];
-
- if (link->type == AVMEDIA_TYPE_AUDIO &&
- link->out_formats->nb_formats == 1)
- break;
- }
- if (i == filter->nb_inputs)
- return;
-
- format = link->out_formats->formats[0];
- bps = av_get_bytes_per_sample(format);
-
- for (i = 0; i < filter->nb_outputs; i++) {
- AVFilterLink *outlink = filter->outputs[i];
- int best_idx = -1, best_score = INT_MIN;
-
- if (outlink->type != AVMEDIA_TYPE_AUDIO ||
- outlink->in_formats->nb_formats < 2)
- continue;
-
- for (j = 0; j < outlink->in_formats->nb_formats; j++) {
- int out_format = outlink->in_formats->formats[j];
- int out_bps = av_get_bytes_per_sample(out_format);
- int score;
-
- if (av_get_packed_sample_fmt(out_format) == format ||
- av_get_planar_sample_fmt(out_format) == format) {
- best_idx = j;
- break;
- }
-
- /* for s32 and float prefer double to prevent loss of information */
- if (bps == 4 && out_bps == 8) {
- best_idx = j;
- break;
- }
-
- /* prefer closest higher or equal bps */
- score = -abs(out_bps - bps);
- if (out_bps >= bps)
- score += INT_MAX/2;
-
- if (score > best_score) {
- best_score = score;
- best_idx = j;
- }
- }
- av_assert0(best_idx >= 0);
- FFSWAP(int, outlink->in_formats->formats[0],
- outlink->in_formats->formats[best_idx]);
- }
-}
-
-static void swap_sample_fmts(AVFilterGraph *graph)
-{
- int i;
-
- for (i = 0; i < graph->nb_filters; i++)
- swap_sample_fmts_on_filter(graph->filters[i]);
-
-}
-
-static int pick_formats(AVFilterGraph *graph)
-{
- int i, j, ret;
- int change;
-
- do{
- change = 0;
- for (i = 0; i < graph->nb_filters; i++) {
- 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 ((ret = pick_format(filter->inputs[j], NULL)) < 0)
- return ret;
- change = 1;
- }
- }
- }
- 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 ((ret = pick_format(filter->outputs[j], NULL)) < 0)
- return ret;
- change = 1;
- }
- }
- }
- 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 ((ret = pick_format(filter->outputs[j], filter->inputs[0])) < 0)
- return ret;
- change = 1;
- }
- }
- }
- }
- }while(change);
-
- for (i = 0; i < graph->nb_filters; i++) {
- AVFilterContext *filter = graph->filters[i];
-
- for (j = 0; j < filter->nb_inputs; j++)
- if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
- return ret;
- for (j = 0; j < filter->nb_outputs; j++)
- if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
- return ret;
- }
- return 0;
-}
-
-/**
- * Configure the formats of all the links in the graph.
- */
-static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
-{
- int ret;
-
- /* find supported formats from sub-filters, and merge along links */
- while ((ret = query_formats(graph, log_ctx)) == AVERROR(EAGAIN))
- av_log(graph, AV_LOG_DEBUG, "query_formats not finished\n");
- if (ret < 0)
- return ret;
-
- /* Once everything is merged, it's possible that we'll still have
- * multiple valid media format choices. We try to minimize the amount
- * of format conversion inside filters */
- reduce_formats(graph);
-
- /* for audio filters, ensure the best format, sample rate and channel layout
- * is selected */
- swap_sample_fmts(graph);
- swap_samplerates(graph);
- swap_channel_layouts(graph);
-
- if ((ret = pick_formats(graph)) < 0)
- return ret;
-
- return 0;
-}
-
-static int graph_config_pointers(AVFilterGraph *graph,
- AVClass *log_ctx)
-{
- unsigned i, j;
- int sink_links_count = 0, n = 0;
- AVFilterContext *f;
- AVFilterLink **sinks;
-
- for (i = 0; i < graph->nb_filters; i++) {
- f = graph->filters[i];
- for (j = 0; j < f->nb_inputs; j++) {
- f->inputs[j]->graph = graph;
- f->inputs[j]->age_index = -1;
- }
- for (j = 0; j < f->nb_outputs; j++) {
- f->outputs[j]->graph = graph;
- f->outputs[j]->age_index= -1;
- }
- if (!f->nb_outputs) {
- if (f->nb_inputs > INT_MAX - sink_links_count)
- return AVERROR(EINVAL);
- sink_links_count += f->nb_inputs;
- }
- }
- sinks = av_calloc(sink_links_count, sizeof(*sinks));
- if (!sinks)
- return AVERROR(ENOMEM);
- for (i = 0; i < graph->nb_filters; i++) {
- f = graph->filters[i];
- if (!f->nb_outputs) {
- for (j = 0; j < f->nb_inputs; j++) {
- sinks[n] = f->inputs[j];
- f->inputs[j]->age_index = n++;
- }
- }
- }
- av_assert0(n == sink_links_count);
- graph->sink_links = sinks;
- graph->sink_links_count = sink_links_count;
- 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;
- 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-inserted 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)))
- return ret;
- if ((ret = graph_config_pointers(graphctx, log_ctx)))
- return ret;
-
- return 0;
-}
-
-int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags)
-{
- int i, r = AVERROR(ENOSYS);
-
- if (!graph)
- return r;
-
- if ((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) {
- r = avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST);
- if (r != AVERROR(ENOSYS))
- return r;
- }
-
- if (res_len && res)
- res[0] = 0;
-
- for (i = 0; i < graph->nb_filters; i++) {
- AVFilterContext *filter = graph->filters[i];
- if (!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)) {
- r = avfilter_process_command(filter, cmd, arg, res, res_len, flags);
- if (r != AVERROR(ENOSYS)) {
- if ((flags & AVFILTER_CMD_FLAG_ONE) || r < 0)
- return r;
- }
- }
- }
-
- return r;
-}
-
-int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *command, const char *arg, int flags, double ts)
-{
- int i;
-
- if(!graph)
- return 0;
-
- for (i = 0; i < graph->nb_filters; i++) {
- AVFilterContext *filter = graph->filters[i];
- if(filter && (!strcmp(target, "all") || !strcmp(target, filter->name) || !strcmp(target, filter->filter->name))){
- AVFilterCommand **queue = &filter->command_queue, *next;
- while (*queue && (*queue)->time <= ts)
- queue = &(*queue)->next;
- next = *queue;
- *queue = av_mallocz(sizeof(AVFilterCommand));
- (*queue)->command = av_strdup(command);
- (*queue)->arg = av_strdup(arg);
- (*queue)->time = ts;
- (*queue)->flags = flags;
- (*queue)->next = next;
- if(flags & AVFILTER_CMD_FLAG_ONE)
- return 0;
- }
- }
-
- return 0;
-}
-
-static void heap_bubble_up(AVFilterGraph *graph,
- AVFilterLink *link, int index)
-{
- AVFilterLink **links = graph->sink_links;
-
- av_assert0(index >= 0);
-
- while (index) {
- int parent = (index - 1) >> 1;
- if (links[parent]->current_pts >= link->current_pts)
- break;
- links[index] = links[parent];
- links[index]->age_index = index;
- index = parent;
- }
- links[index] = link;
- link->age_index = index;
-}
-
-static void heap_bubble_down(AVFilterGraph *graph,
- AVFilterLink *link, int index)
-{
- AVFilterLink **links = graph->sink_links;
-
- av_assert0(index >= 0);
-
- while (1) {
- int child = 2 * index + 1;
- if (child >= graph->sink_links_count)
- break;
- if (child + 1 < graph->sink_links_count &&
- links[child + 1]->current_pts < links[child]->current_pts)
- child++;
- if (link->current_pts < links[child]->current_pts)
- break;
- links[index] = links[child];
- links[index]->age_index = index;
- index = child;
- }
- links[index] = link;
- link->age_index = index;
-}
-
-void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link)
-{
- heap_bubble_up (graph, link, link->age_index);
- heap_bubble_down(graph, link, link->age_index);
-}
-
-
-int avfilter_graph_request_oldest(AVFilterGraph *graph)
-{
- while (graph->sink_links_count) {
- AVFilterLink *oldest = graph->sink_links[0];
- int r = ff_request_frame(oldest);
- if (r != AVERROR_EOF)
- return r;
- av_log(oldest->dst, AV_LOG_DEBUG, "EOF on sink link %s:%s.\n",
- oldest->dst ? oldest->dst->name : "unknown",
- oldest->dstpad ? oldest->dstpad->name : "unknown");
- /* EOF: remove the link from the heap */
- if (oldest->age_index < --graph->sink_links_count)
- heap_bubble_down(graph, graph->sink_links[graph->sink_links_count],
- oldest->age_index);
- oldest->age_index = -1;
- }
- return AVERROR_EOF;
-}
diff --git a/ffmpeg-2-8-11/libavfilter/vf_uspp.c b/ffmpeg-2-8-11/libavfilter/vf_uspp.c
deleted file mode 100644
index a89ca1f..0000000
--- a/ffmpeg-2-8-11/libavfilter/vf_uspp.c
+++ /dev/null
@@ -1,503 +0,0 @@
-/*
- * Copyright (c) 2003 Michael Niedermayer <michaelni at gmx.at>
- * Copyright (c) 2014 Arwa Arif <arwaarif1994 at gmail.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 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.
- */
-
-/**
- * @file
- * Ultra Slow/Simple Post-processing filter.
- *
- * Originally written by Michael Niedermayer for the MPlayer project, and
- * ported by Arwa Arif for FFmpeg.
- */
-
-#include "libavutil/avassert.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/opt.h"
-#include "libavutil/pixdesc.h"
-#include "internal.h"
-#include "avfilter.h"
-
-#define MAX_LEVEL 8 /* quality levels */
-#define BLOCK 16
-
-typedef struct {
- const AVClass *av_class;
- int log2_count;
- int hsub, vsub;
- int qp;
- int qscale_type;
- int temp_stride[3];
- uint8_t *src[3];
- uint16_t *temp[3];
- int outbuf_size;
- uint8_t *outbuf;
- AVCodecContext *avctx_enc[BLOCK*BLOCK];
- AVFrame *frame;
- AVFrame *frame_dec;
- uint8_t *non_b_qp_table;
- int non_b_qp_alloc_size;
- int use_bframe_qp;
-} USPPContext;
-
-#define OFFSET(x) offsetof(USPPContext, x)
-#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
-static const AVOption uspp_options[] = {
- { "quality", "set quality", OFFSET(log2_count), AV_OPT_TYPE_INT, {.i64 = 3}, 0, MAX_LEVEL, FLAGS },
- { "qp", "force a constant quantizer parameter", OFFSET(qp), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 63, FLAGS },
- { "use_bframe_qp", "use B-frames' QP", OFFSET(use_bframe_qp), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS },
- { NULL }
-};
-
-AVFILTER_DEFINE_CLASS(uspp);
-
-DECLARE_ALIGNED(8, static const uint8_t, dither)[8][8] = {
- { 0*4, 48*4, 12*4, 60*4, 3*4, 51*4, 15*4, 63*4, },
- { 32*4, 16*4, 44*4, 28*4, 35*4, 19*4, 47*4, 31*4, },
- { 8*4, 56*4, 4*4, 52*4, 11*4, 59*4, 7*4, 55*4, },
- { 40*4, 24*4, 36*4, 20*4, 43*4, 27*4, 39*4, 23*4, },
- { 2*4, 50*4, 14*4, 62*4, 1*4, 49*4, 13*4, 61*4, },
- { 34*4, 18*4, 46*4, 30*4, 33*4, 17*4, 45*4, 29*4, },
- { 10*4, 58*4, 6*4, 54*4, 9*4, 57*4, 5*4, 53*4, },
- { 42*4, 26*4, 38*4, 22*4, 41*4, 25*4, 37*4, 21*4, },
-};
-
-static const uint8_t offset[511][2] = {
- { 0, 0},
- { 0, 0}, { 8, 8}, // quality 1
- { 0, 0}, { 4, 4}, {12, 8}, { 8,12}, // quality 2
- { 0, 0}, {10, 2}, { 4, 4}, {14, 6}, { 8, 8}, { 2,10}, {12,12}, { 6,14}, // quality 3
-
- { 0, 0}, {10, 2}, { 4, 4}, {14, 6}, { 8, 8}, { 2,10}, {12,12}, { 6,14},
- { 5, 1}, {15, 3}, { 9, 5}, { 3, 7}, {13, 9}, { 7,11}, { 1,13}, {11,15}, // quality 4
-
- { 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9},
- { 2, 2}, {10, 2}, { 2,10}, {10,10}, { 7, 3}, {15, 3}, { 7,11}, {15,11},
- { 4, 4}, {12, 4}, { 4,12}, {12,12}, { 1, 5}, { 9, 5}, { 1,13}, { 9,13},
- { 6, 6}, {14, 6}, { 6,14}, {14,14}, { 3, 7}, {11, 7}, { 3,15}, {11,15}, // quality 5
-
- { 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 4, 0}, {12, 0}, { 4, 8}, {12, 8},
- { 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9},
- { 3, 2}, {11, 2}, { 3,10}, {11,10}, { 7, 2}, {15, 2}, { 7,10}, {15,10},
- { 2, 3}, {10, 3}, { 2,11}, {10,11}, { 6, 3}, {14, 3}, { 6,11}, {14,11},
- { 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 4, 4}, {12, 4}, { 4,12}, {12,12},
- { 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 5, 5}, {13, 5}, { 5,13}, {13,13},
- { 3, 6}, {11, 6}, { 3,14}, {11,14}, { 7, 6}, {15, 6}, { 7,14}, {15,14},
- { 2, 7}, {10, 7}, { 2,15}, {10,15}, { 6, 7}, {14, 7}, { 6,15}, {14,15}, // quality 6
-
- { 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 0, 2}, { 8, 2}, { 0,10}, { 8,10},
- { 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 0, 6}, { 8, 6}, { 0,14}, { 8,14},
- { 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 1, 3}, { 9, 3}, { 1,11}, { 9,11},
- { 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 1, 7}, { 9, 7}, { 1,15}, { 9,15},
- { 2, 0}, {10, 0}, { 2, 8}, {10, 8}, { 2, 2}, {10, 2}, { 2,10}, {10,10},
- { 2, 4}, {10, 4}, { 2,12}, {10,12}, { 2, 6}, {10, 6}, { 2,14}, {10,14},
- { 3, 1}, {11, 1}, { 3, 9}, {11, 9}, { 3, 3}, {11, 3}, { 3,11}, {11,11},
- { 3, 5}, {11, 5}, { 3,13}, {11,13}, { 3, 7}, {11, 7}, { 3,15}, {11,15},
- { 4, 0}, {12, 0}, { 4, 8}, {12, 8}, { 4, 2}, {12, 2}, { 4,10}, {12,10},
- { 4, 4}, {12, 4}, { 4,12}, {12,12}, { 4, 6}, {12, 6}, { 4,14}, {12,14},
- { 5, 1}, {13, 1}, { 5, 9}, {13, 9}, { 5, 3}, {13, 3}, { 5,11}, {13,11},
- { 5, 5}, {13, 5}, { 5,13}, {13,13}, { 5, 7}, {13, 7}, { 5,15}, {13,15},
- { 6, 0}, {14, 0}, { 6, 8}, {14, 8}, { 6, 2}, {14, 2}, { 6,10}, {14,10},
- { 6, 4}, {14, 4}, { 6,12}, {14,12}, { 6, 6}, {14, 6}, { 6,14}, {14,14},
- { 7, 1}, {15, 1}, { 7, 9}, {15, 9}, { 7, 3}, {15, 3}, { 7,11}, {15,11},
- { 7, 5}, {15, 5}, { 7,13}, {15,13}, { 7, 7}, {15, 7}, { 7,15}, {15,15}, // quality 7
-
- { 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 4, 4}, {12, 4}, { 4,12}, {12,12},
- { 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 4, 0}, {12, 0}, { 4, 8}, {12, 8},
- { 2, 2}, {10, 2}, { 2,10}, {10,10}, { 6, 6}, {14, 6}, { 6,14}, {14,14},
- { 2, 6}, {10, 6}, { 2,14}, {10,14}, { 6, 2}, {14, 2}, { 6,10}, {14,10},
- { 0, 2}, { 8, 2}, { 0,10}, { 8,10}, { 4, 6}, {12, 6}, { 4,14}, {12,14},
- { 0, 6}, { 8, 6}, { 0,14}, { 8,14}, { 4, 2}, {12, 2}, { 4,10}, {12,10},
- { 2, 0}, {10, 0}, { 2, 8}, {10, 8}, { 6, 4}, {14, 4}, { 6,12}, {14,12},
- { 2, 4}, {10, 4}, { 2,12}, {10,12}, { 6, 0}, {14, 0}, { 6, 8}, {14, 8},
- { 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 5, 5}, {13, 5}, { 5,13}, {13,13},
- { 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9},
- { 3, 3}, {11, 3}, { 3,11}, {11,11}, { 7, 7}, {15, 7}, { 7,15}, {15,15},
- { 3, 7}, {11, 7}, { 3,15}, {11,15}, { 7, 3}, {15, 3}, { 7,11}, {15,11},
- { 1, 3}, { 9, 3}, { 1,11}, { 9,11}, { 5, 7}, {13, 7}, { 5,15}, {13,15},
- { 1, 7}, { 9, 7}, { 1,15}, { 9,15}, { 5, 3}, {13, 3}, { 5,11}, {13,11}, // quality 8
- { 3, 1}, {11, 1}, { 3, 9}, {11, 9}, { 7, 5}, {15, 5}, { 7,13}, {15,13},
- { 3, 5}, {11, 5}, { 3,13}, {11,13}, { 7, 1}, {15, 1}, { 7, 9}, {15, 9},
- { 0, 1}, { 8, 1}, { 0, 9}, { 8, 9}, { 4, 5}, {12, 5}, { 4,13}, {12,13},
- { 0, 5}, { 8, 5}, { 0,13}, { 8,13}, { 4, 1}, {12, 1}, { 4, 9}, {12, 9},
- { 2, 3}, {10, 3}, { 2,11}, {10,11}, { 6, 7}, {14, 7}, { 6,15}, {14,15},
- { 2, 7}, {10, 7}, { 2,15}, {10,15}, { 6, 3}, {14, 3}, { 6,11}, {14,11},
- { 0, 3}, { 8, 3}, { 0,11}, { 8,11}, { 4, 7}, {12, 7}, { 4,15}, {12,15},
- { 0, 7}, { 8, 7}, { 0,15}, { 8,15}, { 4, 3}, {12, 3}, { 4,11}, {12,11},
- { 2, 1}, {10, 1}, { 2, 9}, {10, 9}, { 6, 5}, {14, 5}, { 6,13}, {14,13},
- { 2, 5}, {10, 5}, { 2,13}, {10,13}, { 6, 1}, {14, 1}, { 6, 9}, {14, 9},
- { 1, 0}, { 9, 0}, { 1, 8}, { 9, 8}, { 5, 4}, {13, 4}, { 5,12}, {13,12},
- { 1, 4}, { 9, 4}, { 1,12}, { 9,12}, { 5, 0}, {13, 0}, { 5, 8}, {13, 8},
- { 3, 2}, {11, 2}, { 3,10}, {11,10}, { 7, 6}, {15, 6}, { 7,14}, {15,14},
- { 3, 6}, {11, 6}, { 3,14}, {11,14}, { 7, 2}, {15, 2}, { 7,10}, {15,10},
- { 1, 2}, { 9, 2}, { 1,10}, { 9,10}, { 5, 6}, {13, 6}, { 5,14}, {13,14},
- { 1, 6}, { 9, 6}, { 1,14}, { 9,14}, { 5, 2}, {13, 2}, { 5,10}, {13,10},
- { 3, 0}, {11, 0}, { 3, 8}, {11, 8}, { 7, 4}, {15, 4}, { 7,12}, {15,12},
- { 3, 4}, {11, 4}, { 3,12}, {11,12}, { 7, 0}, {15, 0}, { 7, 8}, {15, 8},
-};
-
-static void store_slice_c(uint8_t *dst, const uint16_t *src,
- int dst_stride, int src_stride,
- int width, int height, int log2_scale)
-{
- int y, x;
-
-#define STORE(pos) do { \
- temp = ((src[x + y * src_stride + pos] << log2_scale) + d[pos]) >> 8; \
- if (temp & 0x100) temp = ~(temp >> 31); \
- dst[x + y * dst_stride + pos] = temp; \
-} while (0)
-
- for (y = 0; y < height; y++) {
- const uint8_t *d = dither[y&7];
- for (x = 0; x < width; x += 8) {
- int temp;
- STORE(0);
- STORE(1);
- STORE(2);
- STORE(3);
- STORE(4);
- STORE(5);
- STORE(6);
- STORE(7);
- }
- }
-}
-
-static void filter(USPPContext *p, uint8_t *dst[3], uint8_t *src[3],
- int dst_stride[3], int src_stride[3], int width,
- int height, uint8_t *qp_store, int qp_stride)
-{
- int x, y, i, j;
- const int count = 1<<p->log2_count;
-
- for (i = 0; i < 3; i++) {
- int is_chroma = !!i;
- int w = FF_CEIL_RSHIFT(width, is_chroma ? p->hsub : 0);
- int h = FF_CEIL_RSHIFT(height, is_chroma ? p->vsub : 0);
- int stride = p->temp_stride[i];
- int block = BLOCK >> (is_chroma ? p->hsub : 0);
-
- if (!src[i] || !dst[i])
- continue;
- for (y = 0; y < h; y++) {
- int index = block + block * stride + y * stride;
-
- memcpy(p->src[i] + index, src[i] + y * src_stride[i], w );
- for (x = 0; x < block; x++) {
- p->src[i][index - x - 1] = p->src[i][index + x ];
- p->src[i][index + w + x ] = p->src[i][index + w - x - 1];
- }
- }
- for (y = 0; y < block; y++) {
- memcpy(p->src[i] + ( block-1-y) * stride, p->src[i] + ( y+block ) * stride, stride);
- memcpy(p->src[i] + (h+block +y) * stride, p->src[i] + (h-y+block-1) * stride, stride);
- }
-
- p->frame->linesize[i] = stride;
- memset(p->temp[i], 0, (h + 2 * block) * stride * sizeof(int16_t));
- }
-
- if (p->qp)
- p->frame->quality = p->qp * FF_QP2LAMBDA;
- else {
- int qpsum=0;
- int qpcount = (height>>4) * (height>>4);
-
- for (y = 0; y < (height>>4); y++) {
- for (x = 0; x < (width>>4); x++)
- qpsum += qp_store[x + y * qp_stride];
- }
- p->frame->quality = ff_norm_qscale((qpsum + qpcount/2) / qpcount, p->qscale_type) * FF_QP2LAMBDA;
- }
-// init per MB qscale stuff FIXME
- p->frame->height = height;
- p->frame->width = width;
-
- for (i = 0; i < count; i++) {
- const int x1 = offset[i+count-1][0];
- const int y1 = offset[i+count-1][1];
- const int x1c = x1 >> p->hsub;
- const int y1c = y1 >> p->vsub;
- const int BLOCKc = BLOCK >> p->hsub;
- int offset;
- AVPacket pkt = {0};
- int got_pkt_ptr;
-
- av_init_packet(&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;
-
- avcodec_encode_video2(p->avctx_enc[i], &pkt, p->frame, &got_pkt_ptr);
- p->frame_dec = p->avctx_enc[i]->coded_frame;
-
- offset = (BLOCK-x1) + (BLOCK-y1) * p->frame_dec->linesize[0];
-
- for (y = 0; y < height; y++)
- for (x = 0; x < width; x++)
- p->temp[0][x + y * p->temp_stride[0]] += p->frame_dec->data[0][x + y * p->frame_dec->linesize[0] + offset];
-
- if (!src[2] || !dst[2])
- continue;
-
- offset = (BLOCKc-x1c) + (BLOCKc-y1c) * p->frame_dec->linesize[1];
-
- for (y = 0; y < FF_CEIL_RSHIFT(height, p->vsub); y++) {
- for (x = 0; x < FF_CEIL_RSHIFT(width, p->hsub); x++) {
- p->temp[1][x + y * p->temp_stride[1]] += p->frame_dec->data[1][x + y * p->frame_dec->linesize[1] + offset];
- p->temp[2][x + y * p->temp_stride[2]] += p->frame_dec->data[2][x + y * p->frame_dec->linesize[2] + offset];
- }
- }
- }
-
- for (j = 0; j < 3; j++) {
- int is_chroma = !!j;
- if (!dst[j])
- continue;
- store_slice_c(dst[j], p->temp[j], dst_stride[j], p->temp_stride[j],
- FF_CEIL_RSHIFT(width, is_chroma ? p->hsub : 0),
- FF_CEIL_RSHIFT(height, is_chroma ? p->vsub : 0),
- 8-p->log2_count);
- }
-}
-
-static int query_formats(AVFilterContext *ctx)
-{
- static const enum AVPixelFormat pix_fmts[] = {
- AV_PIX_FMT_YUV444P,
- AV_PIX_FMT_YUV420P,
- AV_PIX_FMT_YUV410P,
- AV_PIX_FMT_YUVJ444P,
- AV_PIX_FMT_YUVJ420P,
- AV_PIX_FMT_GRAY8,
- 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(AVFilterLink *inlink)
-{
-
- AVFilterContext *ctx = inlink->dst;
- USPPContext *uspp = ctx->priv;
- const int height = inlink->h;
- const int width = inlink->w;
- const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
- int i;
-
- 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);
- }
-
- uspp->hsub = desc->log2_chroma_w;
- uspp->vsub = desc->log2_chroma_h;
-
- for (i = 0; i < 3; i++) {
- int is_chroma = !!i;
- int w = (width + 4 * BLOCK-1) & (~(2 * BLOCK-1));
- int h = (height + 4 * BLOCK-1) & (~(2 * BLOCK-1));
-
- if (is_chroma) {
- w = FF_CEIL_RSHIFT(w, uspp->hsub);
- h = FF_CEIL_RSHIFT(h, uspp->vsub);
- }
-
- uspp->temp_stride[i] = w;
- if (!(uspp->temp[i] = av_malloc_array(uspp->temp_stride[i], h * sizeof(int16_t))))
- return AVERROR(ENOMEM);
- if (!(uspp->src [i] = av_malloc_array(uspp->temp_stride[i], h * sizeof(uint8_t))))
- return AVERROR(ENOMEM);
- }
-
- for (i = 0; i < (1<<uspp->log2_count); i++) {
- AVCodecContext *avctx_enc;
- AVDictionary *opts = NULL;
- int ret;
-
- if (!(uspp->avctx_enc[i] = avcodec_alloc_context3(NULL)))
- return AVERROR(ENOMEM);
-
- avctx_enc = uspp->avctx_enc[i];
- avctx_enc->width = width + BLOCK;
- avctx_enc->height = height + BLOCK;
- avctx_enc->time_base = (AVRational){1,25}; // meaningless
- avctx_enc->gop_size = INT_MAX;
- avctx_enc->max_b_frames = 0;
- avctx_enc->pix_fmt = inlink->format;
- avctx_enc->flags = AV_CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
- avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
- avctx_enc->global_quality = 123;
- av_dict_set(&opts, "no_bitstream", "1", 0);
- ret = avcodec_open2(avctx_enc, enc, &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->outbuf = av_malloc(uspp->outbuf_size)))
- return AVERROR(ENOMEM);
-
- return 0;
-}
-
-static int filter_frame(AVFilterLink *inlink, AVFrame *in)
-{
- AVFilterContext *ctx = inlink->dst;
- USPPContext *uspp = ctx->priv;
- AVFilterLink *outlink = ctx->outputs[0];
- AVFrame *out = in;
-
- int qp_stride = 0;
- uint8_t *qp_table = NULL;
-
- /* 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 (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 = FF_CEIL_RSHIFT(inlink->w, 4);
- h = 1;
- } else {
- w = qp_stride;
- h = FF_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->log2_count && !ctx->is_disabled) {
- if (!uspp->use_bframe_qp && uspp->non_b_qp_table)
- qp_table = uspp->non_b_qp_table;
-
- if (qp_table || uspp->qp) {
-
- /* get a new frame if in-place is not possible or if the dimensions
- * are not multiple of 8 */
- if (!av_frame_is_writable(in) || (inlink->w & 7) || (inlink->h & 7)) {
- const int aligned_w = FFALIGN(inlink->w, 8);
- const int aligned_h = FFALIGN(inlink->h, 8);
-
- out = ff_get_video_buffer(outlink, aligned_w, aligned_h);
- if (!out) {
- av_frame_free(&in);
- return AVERROR(ENOMEM);
- }
- av_frame_copy_props(out, in);
- out->width = in->width;
- out->height = in->height;
- }
-
- filter(uspp, out->data, in->data, out->linesize, in->linesize,
- inlink->w, inlink->h, qp_table, qp_stride);
- }
- }
-
- if (in != out) {
- if (in->data[3])
- av_image_copy_plane(out->data[3], out->linesize[3],
- in ->data[3], in ->linesize[3],
- inlink->w, inlink->h);
- av_frame_free(&in);
- }
- return ff_filter_frame(outlink, out);
-}
-
-static av_cold void uninit(AVFilterContext *ctx)
-{
- USPPContext *uspp = ctx->priv;
- int i;
-
- for (i = 0; i < 3; i++) {
- av_freep(&uspp->temp[i]);
- 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]);
- }
-
- av_freep(&uspp->non_b_qp_table);
- av_freep(&uspp->outbuf);
- av_frame_free(&uspp->frame);
-}
-
-static const AVFilterPad uspp_inputs[] = {
- {
- .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- .config_props = config_input,
- .filter_frame = filter_frame,
- },
- { NULL }
-};
-
-static const AVFilterPad uspp_outputs[] = {
- {
- .name = "default",
- .type = AVMEDIA_TYPE_VIDEO,
- },
- { NULL }
-};
-
-AVFilter ff_vf_uspp = {
- .name = "uspp",
- .description = NULL_IF_CONFIG_SMALL("Apply Ultra Simple / Slow Post-processing filter."),
- .priv_size = sizeof(USPPContext),
- .uninit = uninit,
- .query_formats = query_formats,
- .inputs = uspp_inputs,
- .outputs = uspp_outputs,
- .priv_class = &uspp_class,
- .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
-};
diff --git a/ffmpeg-2-8-11/libavformat/apngdec.c b/ffmpeg-2-8-11/libavformat/apngdec.c
deleted file mode 100644
index 84298ae..0000000
--- a/ffmpeg-2-8-11/libavformat/apngdec.c
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * APNG demuxer
- * Copyright (c) 2014 Benoit Fouet
- *
- * 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
- * APNG demuxer.
- * @see https://wiki.mozilla.org/APNG_Specification
- * @see http://www.w3.org/TR/PNG
- */
-
-#include "avformat.h"
-#include "avio_internal.h"
-#include "internal.h"
-#include "libavutil/imgutils.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/opt.h"
-#include "libavcodec/apng.h"
-#include "libavcodec/png.h"
-#include "libavcodec/bytestream.h"
-
-#define DEFAULT_APNG_FPS 15
-
-typedef struct APNGDemuxContext {
- const AVClass *class;
-
- int max_fps;
- int default_fps;
-
- int64_t pkt_pts;
- int pkt_duration;
-
- int is_key_frame;
-
- /*
- * loop options
- */
- int ignore_loop;
- uint32_t num_frames;
- uint32_t num_play;
- uint32_t cur_loop;
-} APNGDemuxContext;
-
-/*
- * To be a valid APNG file, we mandate, in this order:
- * PNGSIG
- * IHDR
- * ...
- * acTL
- * ...
- * IDAT
- */
-static int apng_probe(AVProbeData *p)
-{
- GetByteContext gb;
- int state = 0;
- uint32_t len, tag;
-
- bytestream2_init(&gb, p->buf, p->buf_size);
-
- if (bytestream2_get_be64(&gb) != PNGSIG)
- return 0;
-
- for (;;) {
- len = bytestream2_get_be32(&gb);
- if (len > 0x7fffffff)
- return 0;
-
- tag = bytestream2_get_le32(&gb);
- /* we don't check IDAT size, as this is the last tag
- * we check, and it may be larger than the probe buffer */
- if (tag != MKTAG('I', 'D', 'A', 'T') &&
- len + 4 > bytestream2_get_bytes_left(&gb))
- return 0;
-
- switch (tag) {
- case MKTAG('I', 'H', 'D', 'R'):
- if (len != 13)
- return 0;
- if (av_image_check_size(bytestream2_get_be32(&gb), bytestream2_get_be32(&gb), 0, NULL))
- return 0;
- bytestream2_skip(&gb, 9);
- state++;
- break;
- case MKTAG('a', 'c', 'T', 'L'):
- if (state != 1 ||
- len != 8 ||
- bytestream2_get_be32(&gb) == 0) /* 0 is not a valid value for number of frames */
- return 0;
- bytestream2_skip(&gb, 8);
- state++;
- break;
- case MKTAG('I', 'D', 'A', 'T'):
- if (state != 2)
- return 0;
- goto end;
- default:
- /* skip other tags */
- bytestream2_skip(&gb, len + 4);
- break;
- }
- }
-
-end:
- return AVPROBE_SCORE_MAX;
-}
-
-static int append_extradata(AVCodecContext *s, AVIOContext *pb, int len)
-{
- int previous_size = s->extradata_size;
- int new_size, ret;
- uint8_t *new_extradata;
-
- if (previous_size > INT_MAX - len)
- return AVERROR_INVALIDDATA;
-
- new_size = previous_size + len;
- new_extradata = av_realloc(s->extradata, new_size + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!new_extradata)
- return AVERROR(ENOMEM);
- s->extradata = new_extradata;
- s->extradata_size = new_size;
-
- if ((ret = avio_read(pb, s->extradata + previous_size, len)) < 0)
- return ret;
-
- return previous_size;
-}
-
-static int apng_read_header(AVFormatContext *s)
-{
- APNGDemuxContext *ctx = s->priv_data;
- AVIOContext *pb = s->pb;
- uint32_t len, tag;
- AVStream *st;
- int acTL_found = 0;
- int64_t ret = AVERROR_INVALIDDATA;
-
- /* verify PNGSIG */
- if (avio_rb64(pb) != PNGSIG)
- return ret;
-
- /* 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;
-
- st = avformat_new_stream(s, NULL);
- if (!st)
- return AVERROR(ENOMEM);
-
- /* set the timebase to something large enough (1/100,000 of second)
- * to hopefully cope with all sane frame durations */
- avpriv_set_pts_info(st, 64, 1, 100000);
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = AV_CODEC_ID_APNG;
- st->codec->width = avio_rb32(pb);
- st->codec->height = avio_rb32(pb);
- if ((ret = av_image_check_size(st->codec->width, st->codec->height, 0, s)) < 0)
- return ret;
-
- /* extradata will contain every chunk up to the first fcTL (excluded) */
- st->codec->extradata = av_malloc(len + 12 + AV_INPUT_BUFFER_PADDING_SIZE);
- if (!st->codec->extradata)
- return AVERROR(ENOMEM);
- st->codec->extradata_size = len + 12;
- AV_WB32(st->codec->extradata, len);
- AV_WL32(st->codec->extradata+4, tag);
- AV_WB32(st->codec->extradata+8, st->codec->width);
- AV_WB32(st->codec->extradata+12, st->codec->height);
- if ((ret = avio_read(pb, st->codec->extradata+16, 9)) < 0)
- goto fail;
-
- while (!avio_feof(pb)) {
- 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;
- } else if (offset < 0) {
- ret = offset;
- goto fail;
- } 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;
- }
- }
- if ((ctx->num_play == 1 || !acTL_found) &&
- ((ret = ffio_ensure_seekback(pb, 4 /* len */ + 4 /* tag */)) < 0))
- goto fail;
-
- len = avio_rb32(pb);
- if (len > 0x7fffffff) {
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
-
- 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->codec, pb, len + 12)) < 0)
- goto fail;
- acTL_found = 1;
- ctx->num_frames = AV_RB32(st->codec->extradata + ret + 8);
- ctx->num_play = AV_RB32(st->codec->extradata + ret + 12);
- av_log(s, AV_LOG_DEBUG, "num_frames: %"PRIu32", num_play: %"PRIu32"\n",
- ctx->num_frames, ctx->num_play);
- break;
- case MKTAG('f', 'c', 'T', 'L'):
- if (!acTL_found) {
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
- if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0)
- goto fail;
- return 0;
- default:
- if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||
- (ret = append_extradata(st->codec, pb, len + 12)) < 0)
- goto fail;
- }
- }
-
-fail:
- if (st->codec->extradata_size) {
- av_freep(&st->codec->extradata);
- st->codec->extradata_size = 0;
- }
- return ret;
-}
-
-static int decode_fctl_chunk(AVFormatContext *s, APNGDemuxContext *ctx, AVPacket *pkt)
-{
- uint32_t sequence_number, width, height, x_offset, y_offset;
- uint16_t delay_num, delay_den;
- uint8_t dispose_op, blend_op;
-
- sequence_number = avio_rb32(s->pb);
- width = avio_rb32(s->pb);
- height = avio_rb32(s->pb);
- x_offset = avio_rb32(s->pb);
- y_offset = avio_rb32(s->pb);
- delay_num = avio_rb16(s->pb);
- delay_den = avio_rb16(s->pb);
- dispose_op = avio_r8(s->pb);
- blend_op = avio_r8(s->pb);
- avio_skip(s->pb, 4); /* crc */
-
- /* default is hundredths of seconds */
- if (!delay_den)
- delay_den = 100;
- if (!delay_num || delay_den / delay_num > ctx->max_fps) {
- delay_num = 1;
- delay_den = ctx->default_fps;
- }
- ctx->pkt_duration = av_rescale_q(delay_num,
- (AVRational){ 1, delay_den },
- s->streams[0]->time_base);
-
- av_log(s, AV_LOG_DEBUG, "%s: "
- "sequence_number: %"PRId32", "
- "width: %"PRIu32", "
- "height: %"PRIu32", "
- "x_offset: %"PRIu32", "
- "y_offset: %"PRIu32", "
- "delay_num: %"PRIu16", "
- "delay_den: %"PRIu16", "
- "dispose_op: %d, "
- "blend_op: %d\n",
- __FUNCTION__,
- sequence_number,
- width,
- height,
- x_offset,
- y_offset,
- delay_num,
- delay_den,
- dispose_op,
- blend_op);
-
- if (width != s->streams[0]->codec->width ||
- height != s->streams[0]->codec->height ||
- x_offset != 0 ||
- y_offset != 0) {
- if (sequence_number == 0 ||
- x_offset >= s->streams[0]->codec->width ||
- width > s->streams[0]->codec->width - x_offset ||
- y_offset >= s->streams[0]->codec->height ||
- height > s->streams[0]->codec->height - y_offset)
- return AVERROR_INVALIDDATA;
- ctx->is_key_frame = 0;
- } else {
- if (sequence_number == 0 && dispose_op == APNG_DISPOSE_OP_PREVIOUS)
- dispose_op = APNG_DISPOSE_OP_BACKGROUND;
- ctx->is_key_frame = dispose_op == APNG_DISPOSE_OP_BACKGROUND ||
- blend_op == APNG_BLEND_OP_SOURCE;
- }
-
- return 0;
-}
-
-static int apng_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
- APNGDemuxContext *ctx = s->priv_data;
- int64_t ret;
- int64_t size;
- AVIOContext *pb = s->pb;
- uint32_t len, tag;
-
- /*
- * fcTL chunk length, in bytes:
- * 4 (length)
- * 4 (tag)
- * 26 (actual chunk)
- * 4 (crc) bytes
- * and needed next:
- * 4 (length)
- * 4 (tag (must be fdAT or IDAT))
- */
- /* if num_play is not 1, then the seekback is already guaranteed */
- if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 46)) < 0)
- return ret;
-
- len = avio_rb32(pb);
- tag = avio_rl32(pb);
- switch (tag) {
- case MKTAG('f', 'c', 'T', 'L'):
- if (len != 26)
- return AVERROR_INVALIDDATA;
-
- if ((ret = decode_fctl_chunk(s, ctx, pkt)) < 0)
- return ret;
-
- /* fcTL must precede fdAT or IDAT */
- len = avio_rb32(pb);
- tag = avio_rl32(pb);
- if (len > 0x7fffffff ||
- tag != MKTAG('f', 'd', 'A', 'T') &&
- tag != MKTAG('I', 'D', 'A', 'T'))
- return AVERROR_INVALIDDATA;
-
- size = 38 /* fcTL */ + 8 /* len, tag */ + len + 4 /* crc */;
- if (size > INT_MAX)
- return AVERROR(EINVAL);
-
- if ((ret = avio_seek(pb, -46, SEEK_CUR)) < 0 ||
- (ret = av_append_packet(pb, pkt, size)) < 0)
- return ret;
-
- if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 8)) < 0)
- return ret;
-
- len = avio_rb32(pb);
- tag = avio_rl32(pb);
- while (tag &&
- tag != MKTAG('f', 'c', 'T', 'L') &&
- tag != MKTAG('I', 'E', 'N', 'D')) {
- if (len > 0x7fffffff)
- return AVERROR_INVALIDDATA;
- if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||
- (ret = av_append_packet(pb, pkt, len + 12)) < 0)
- return ret;
- if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 8)) < 0)
- return ret;
- len = avio_rb32(pb);
- tag = avio_rl32(pb);
- }
- if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0)
- return ret;
-
- if (ctx->is_key_frame)
- pkt->flags |= AV_PKT_FLAG_KEY;
- pkt->pts = ctx->pkt_pts;
- pkt->duration = ctx->pkt_duration;
- ctx->pkt_pts += ctx->pkt_duration;
- return ret;
- case MKTAG('I', 'E', 'N', 'D'):
- ctx->cur_loop++;
- if (ctx->ignore_loop || ctx->num_play >= 1 && ctx->cur_loop == ctx->num_play) {
- avio_seek(pb, -8, SEEK_CUR);
- return AVERROR_EOF;
- }
- if ((ret = avio_seek(pb, s->streams[0]->codec->extradata_size + 8, SEEK_SET)) < 0)
- return ret;
- return 0;
- default:
- {
- char tag_buf[32];
-
- av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag);
- avpriv_request_sample(s, "In-stream tag=%s (0x%08X) len=%"PRIu32, tag_buf, tag, len);
- avio_skip(pb, len + 4);
- }
- }
-
- /* Handle the unsupported yet cases */
- return AVERROR_PATCHWELCOME;
-}
-
-static const AVOption options[] = {
- { "ignore_loop", "ignore loop setting" , offsetof(APNGDemuxContext, ignore_loop),
- AV_OPT_TYPE_INT, { .i64 = 1 } , 0, 1 , AV_OPT_FLAG_DECODING_PARAM },
- { "max_fps" , "maximum framerate (0 is no limit)" , offsetof(APNGDemuxContext, max_fps),
- AV_OPT_TYPE_INT, { .i64 = DEFAULT_APNG_FPS }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
- { "default_fps", "default framerate (0 is as fast as possible)", offsetof(APNGDemuxContext, default_fps),
- AV_OPT_TYPE_INT, { .i64 = DEFAULT_APNG_FPS }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
- { NULL },
-};
-
-static const AVClass demuxer_class = {
- .class_name = "APNG demuxer",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
- .category = AV_CLASS_CATEGORY_DEMUXER,
-};
-
-AVInputFormat ff_apng_demuxer = {
- .name = "apng",
- .long_name = NULL_IF_CONFIG_SMALL("Animated Portable Network Graphics"),
- .priv_data_size = sizeof(APNGDemuxContext),
- .read_probe = apng_probe,
- .read_header = apng_read_header,
- .read_packet = apng_read_packet,
- .flags = AVFMT_GENERIC_INDEX,
- .priv_class = &demuxer_class,
-};
diff --git a/ffmpeg-2-8-11/libavformat/avidec.c b/ffmpeg-2-8-11/libavformat/avidec.c
deleted file mode 100644
index cbe6c85..0000000
--- a/ffmpeg-2-8-11/libavformat/avidec.c
+++ /dev/null
@@ -1,1938 +0,0 @@
-/*
- * AVI demuxer
- * Copyright (c) 2001 Fabrice Bellard
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <inttypes.h>
-
-#include "libavutil/avassert.h"
-#include "libavutil/avstring.h"
-#include "libavutil/bswap.h"
-#include "libavutil/opt.h"
-#include "libavutil/dict.h"
-#include "libavutil/internal.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/mathematics.h"
-#include "avformat.h"
-#include "avi.h"
-#include "dv.h"
-#include "internal.h"
-#include "isom.h"
-#include "riff.h"
-#include "libavcodec/bytestream.h"
-#include "libavcodec/exif.h"
-#include "libavcodec/internal.h"
-
-typedef struct AVIStream {
- int64_t frame_offset; /* current frame (video) or byte (audio) counter
- * (used to compute the pts) */
- int remaining;
- int packet_size;
-
- uint32_t handler;
- uint32_t scale;
- uint32_t rate;
- int sample_size; /* size of one sample (or packet)
- * (in the rate/scale sense) in bytes */
-
- int64_t cum_len; /* temporary storage (used during seek) */
- int prefix; /* normally 'd'<<8 + 'c' or 'w'<<8 + 'b' */
- int prefix_count;
- uint32_t pal[256];
- int has_pal;
- int dshow_block_align; /* block align variable used to emulate bugs in
- * the MS dshow demuxer */
-
- AVFormatContext *sub_ctx;
- AVPacket sub_pkt;
- uint8_t *sub_buffer;
-
- int64_t seek_pos;
-} AVIStream;
-
-typedef struct AVIContext {
- const AVClass *class;
- int64_t riff_end;
- int64_t movi_end;
- int64_t fsize;
- int64_t io_fsize;
- int64_t movi_list;
- int64_t last_pkt_pos;
- int index_loaded;
- int is_odml;
- int non_interleaved;
- int stream_index;
- DVDemuxContext *dv_demux;
- int odml_depth;
- int use_odml;
-#define MAX_ODML_DEPTH 1000
- int64_t dts_max;
-} AVIContext;
-
-
-static const AVOption options[] = {
- { "use_odml", "use odml index", offsetof(AVIContext, use_odml), AV_OPT_TYPE_INT, {.i64 = 1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM},
- { NULL },
-};
-
-static const AVClass demuxer_class = {
- .class_name = "avi",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
- .category = AV_CLASS_CATEGORY_DEMUXER,
-};
-
-
-static const char avi_headers[][8] = {
- { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' ' },
- { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X' },
- { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19 },
- { 'O', 'N', '2', ' ', 'O', 'N', '2', 'f' },
- { 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' ' },
- { 0 }
-};
-
-static const AVMetadataConv avi_metadata_conv[] = {
- { "strn", "title" },
- { 0 },
-};
-
-static int avi_load_index(AVFormatContext *s);
-static int guess_ni_flag(AVFormatContext *s);
-
-#define print_tag(str, tag, size) \
- av_log(NULL, AV_LOG_TRACE, "pos:%"PRIX64" %s: tag=%c%c%c%c size=0x%x\n", \
- avio_tell(pb), str, tag & 0xff, \
- (tag >> 8) & 0xff, \
- (tag >> 16) & 0xff, \
- (tag >> 24) & 0xff, \
- size)
-
-static inline int get_duration(AVIStream *ast, int len)
-{
- if (ast->sample_size)
- return len;
- else if (ast->dshow_block_align)
- return (len + ast->dshow_block_align - 1) / ast->dshow_block_align;
- else
- return 1;
-}
-
-static int get_riff(AVFormatContext *s, AVIOContext *pb)
-{
- AVIContext *avi = s->priv_data;
- char header[8] = {0};
- int i;
-
- /* check RIFF header */
- avio_read(pb, header, 4);
- avi->riff_end = avio_rl32(pb); /* RIFF chunk size */
- avi->riff_end += avio_tell(pb); /* RIFF chunk end */
- avio_read(pb, header + 4, 4);
-
- for (i = 0; avi_headers[i][0]; i++)
- if (!memcmp(header, avi_headers[i], 8))
- break;
- if (!avi_headers[i][0])
- return AVERROR_INVALIDDATA;
-
- if (header[7] == 0x19)
- av_log(s, AV_LOG_INFO,
- "This file has been generated by a totally broken muxer.\n");
-
- return 0;
-}
-
-static int read_braindead_odml_indx(AVFormatContext *s, int frame_num)
-{
- AVIContext *avi = s->priv_data;
- AVIOContext *pb = s->pb;
- int longs_pre_entry = avio_rl16(pb);
- int index_sub_type = avio_r8(pb);
- int index_type = avio_r8(pb);
- int entries_in_use = avio_rl32(pb);
- int chunk_id = avio_rl32(pb);
- int64_t base = avio_rl64(pb);
- int stream_id = ((chunk_id & 0xFF) - '0') * 10 +
- ((chunk_id >> 8 & 0xFF) - '0');
- AVStream *st;
- AVIStream *ast;
- int i;
- int64_t last_pos = -1;
- int64_t filesize = avi->fsize;
-
- av_log(s, AV_LOG_TRACE,
- "longs_pre_entry:%d index_type:%d entries_in_use:%d "
- "chunk_id:%X base:%16"PRIX64" frame_num:%d\n",
- longs_pre_entry,
- index_type,
- entries_in_use,
- chunk_id,
- base,
- frame_num);
-
- if (stream_id >= s->nb_streams || stream_id < 0)
- return AVERROR_INVALIDDATA;
- st = s->streams[stream_id];
- ast = st->priv_data;
-
- if (index_sub_type)
- return AVERROR_INVALIDDATA;
-
- avio_rl32(pb);
-
- if (index_type && longs_pre_entry != 2)
- return AVERROR_INVALIDDATA;
- if (index_type > 1)
- return AVERROR_INVALIDDATA;
-
- if (filesize > 0 && base >= filesize) {
- av_log(s, AV_LOG_ERROR, "ODML index invalid\n");
- if (base >> 32 == (base & 0xFFFFFFFF) &&
- (base & 0xFFFFFFFF) < filesize &&
- filesize <= 0xFFFFFFFF)
- base &= 0xFFFFFFFF;
- else
- return AVERROR_INVALIDDATA;
- }
-
- for (i = 0; i < entries_in_use; i++) {
- if (index_type) {
- int64_t pos = avio_rl32(pb) + base - 8;
- int len = avio_rl32(pb);
- int key = len >= 0;
- len &= 0x7FFFFFFF;
-
- av_log(s, AV_LOG_TRACE, "pos:%"PRId64", len:%X\n", pos, len);
-
- if (avio_feof(pb))
- return AVERROR_INVALIDDATA;
-
- if (last_pos == pos || pos == base - 8)
- avi->non_interleaved = 1;
- if (last_pos != pos && len)
- av_add_index_entry(st, pos, ast->cum_len, len, 0,
- key ? AVINDEX_KEYFRAME : 0);
-
- ast->cum_len += get_duration(ast, len);
- last_pos = pos;
- } else {
- int64_t offset, pos;
- int duration;
- offset = avio_rl64(pb);
- avio_rl32(pb); /* size */
- duration = avio_rl32(pb);
-
- if (avio_feof(pb))
- return AVERROR_INVALIDDATA;
-
- pos = avio_tell(pb);
-
- if (avi->odml_depth > MAX_ODML_DEPTH) {
- av_log(s, AV_LOG_ERROR, "Too deeply nested ODML indexes\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (avio_seek(pb, offset + 8, SEEK_SET) < 0)
- return -1;
- avi->odml_depth++;
- read_braindead_odml_indx(s, frame_num);
- avi->odml_depth--;
- frame_num += duration;
-
- if (avio_seek(pb, pos, SEEK_SET) < 0) {
- av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index\n");
- return -1;
- }
-
- }
- }
- avi->index_loaded = 2;
- return 0;
-}
-
-static void clean_index(AVFormatContext *s)
-{
- int i;
- int64_t j;
-
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st = s->streams[i];
- AVIStream *ast = st->priv_data;
- int n = st->nb_index_entries;
- int max = ast->sample_size;
- int64_t pos, size, ts;
-
- if (n != 1 || ast->sample_size == 0)
- continue;
-
- while (max < 1024)
- max += max;
-
- pos = st->index_entries[0].pos;
- size = st->index_entries[0].size;
- ts = st->index_entries[0].timestamp;
-
- for (j = 0; j < size; j += max)
- av_add_index_entry(st, pos + j, ts + j, FFMIN(max, size - j), 0,
- AVINDEX_KEYFRAME);
- }
-}
-
-static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag,
- uint32_t size)
-{
- AVIOContext *pb = s->pb;
- char key[5] = { 0 };
- char *value;
-
- size += (size & 1);
-
- if (size == UINT_MAX)
- return AVERROR(EINVAL);
- value = av_malloc(size + 1);
- if (!value)
- return AVERROR(ENOMEM);
- if (avio_read(pb, value, size) != size)
- return AVERROR_INVALIDDATA;
- value[size] = 0;
-
- AV_WL32(key, tag);
-
- return av_dict_set(st ? &st->metadata : &s->metadata, key, value,
- AV_DICT_DONT_STRDUP_VAL);
-}
-
-static const char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
-
-static void avi_metadata_creation_time(AVDictionary **metadata, char *date)
-{
- char month[4], time[9], buffer[64];
- int i, day, year;
- /* parse standard AVI date format (ie. "Mon Mar 10 15:04:43 2003") */
- if (sscanf(date, "%*3s%*[ ]%3s%*[ ]%2d%*[ ]%8s%*[ ]%4d",
- month, &day, time, &year) == 4) {
- for (i = 0; i < 12; i++)
- if (!av_strcasecmp(month, months[i])) {
- snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s",
- year, i + 1, day, time);
- av_dict_set(metadata, "creation_time", buffer, 0);
- }
- } else if (date[4] == '/' && date[7] == '/') {
- date[4] = date[7] = '-';
- av_dict_set(metadata, "creation_time", date, 0);
- }
-}
-
-static void avi_read_nikon(AVFormatContext *s, uint64_t end)
-{
- while (avio_tell(s->pb) < end && !avio_feof(s->pb)) {
- uint32_t tag = avio_rl32(s->pb);
- uint32_t size = avio_rl32(s->pb);
- switch (tag) {
- case MKTAG('n', 'c', 't', 'g'): /* Nikon Tags */
- {
- uint64_t tag_end = avio_tell(s->pb) + size;
- while (avio_tell(s->pb) < tag_end && !avio_feof(s->pb)) {
- uint16_t tag = avio_rl16(s->pb);
- uint16_t size = avio_rl16(s->pb);
- const char *name = NULL;
- char buffer[64] = { 0 };
- size = FFMIN(size, tag_end - avio_tell(s->pb));
- size -= avio_read(s->pb, buffer,
- FFMIN(size, sizeof(buffer) - 1));
- switch (tag) {
- case 0x03:
- name = "maker";
- break;
- case 0x04:
- name = "model";
- break;
- case 0x13:
- name = "creation_time";
- if (buffer[4] == ':' && buffer[7] == ':')
- buffer[4] = buffer[7] = '-';
- break;
- }
- if (name)
- av_dict_set(&s->metadata, name, buffer, 0);
- avio_skip(s->pb, size);
- }
- break;
- }
- default:
- avio_skip(s->pb, size);
- break;
- }
- }
-}
-
-static int avi_extract_stream_metadata(AVStream *st)
-{
- GetByteContext gb;
- uint8_t *data = st->codec->extradata;
- int data_size = st->codec->extradata_size;
- int tag, offset;
-
- if (!data || data_size < 8) {
- return AVERROR_INVALIDDATA;
- }
-
- bytestream2_init(&gb, data, data_size);
-
- tag = bytestream2_get_le32(&gb);
-
- switch (tag) {
- case MKTAG('A', 'V', 'I', 'F'):
- // skip 4 byte padding
- bytestream2_skip(&gb, 4);
- offset = bytestream2_tell(&gb);
- bytestream2_init(&gb, data + offset, data_size - offset);
-
- // decode EXIF tags from IFD, AVI is always little-endian
- return avpriv_exif_decode_ifd(st->codec, &gb, 1, 0, &st->metadata);
- break;
- case MKTAG('C', 'A', 'S', 'I'):
- avpriv_request_sample(st->codec, "RIFF stream data tag type CASI (%u)", tag);
- break;
- case MKTAG('Z', 'o', 'r', 'a'):
- avpriv_request_sample(st->codec, "RIFF stream data tag type Zora (%u)", tag);
- break;
- default:
- break;
- }
-
- return 0;
-}
-
-static int calculate_bitrate(AVFormatContext *s)
-{
- AVIContext *avi = s->priv_data;
- int i, j;
- int64_t lensum = 0;
- int64_t maxpos = 0;
-
- for (i = 0; i<s->nb_streams; i++) {
- int64_t len = 0;
- AVStream *st = s->streams[i];
-
- if (!st->nb_index_entries)
- continue;
-
- for (j = 0; j < st->nb_index_entries; j++)
- len += st->index_entries[j].size;
- maxpos = FFMAX(maxpos, st->index_entries[j-1].pos);
- lensum += len;
- }
- if (maxpos < avi->io_fsize*9/10) // index does not cover the whole file
- return 0;
- if (lensum*9/10 > maxpos || lensum < maxpos*9/10) // frame sum and filesize mismatch
- return 0;
-
- for (i = 0; i<s->nb_streams; i++) {
- int64_t len = 0;
- AVStream *st = s->streams[i];
- int64_t duration;
- int64_t bitrate;
-
- for (j = 0; j < st->nb_index_entries; j++)
- len += st->index_entries[j].size;
-
- if (st->nb_index_entries < 2 || st->codec->bit_rate > 0)
- continue;
- duration = st->index_entries[j-1].timestamp - st->index_entries[0].timestamp;
- bitrate = av_rescale(8*len, st->time_base.den, duration * st->time_base.num);
- if (bitrate <= INT_MAX && bitrate > 0) {
- st->codec->bit_rate = bitrate;
- }
- }
- return 1;
-}
-
-static int avi_read_header(AVFormatContext *s)
-{
- AVIContext *avi = s->priv_data;
- AVIOContext *pb = s->pb;
- unsigned int tag, tag1, handler;
- int codec_type, stream_index, frame_period;
- unsigned int size;
- int i;
- AVStream *st;
- AVIStream *ast = NULL;
- int avih_width = 0, avih_height = 0;
- int amv_file_format = 0;
- uint64_t list_end = 0;
- int ret;
- AVDictionaryEntry *dict_entry;
-
- avi->stream_index = -1;
-
- ret = get_riff(s, pb);
- if (ret < 0)
- return ret;
-
- av_log(avi, AV_LOG_DEBUG, "use odml:%d\n", avi->use_odml);
-
- avi->io_fsize = avi->fsize = avio_size(pb);
- if (avi->fsize <= 0 || avi->fsize < avi->riff_end)
- avi->fsize = avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
-
- /* first list tag */
- stream_index = -1;
- codec_type = -1;
- frame_period = 0;
- for (;;) {
- if (avio_feof(pb))
- goto fail;
- tag = avio_rl32(pb);
- size = avio_rl32(pb);
-
- print_tag("tag", tag, size);
-
- switch (tag) {
- case MKTAG('L', 'I', 'S', 'T'):
- list_end = avio_tell(pb) + size;
- /* Ignored, except at start of video packets. */
- tag1 = avio_rl32(pb);
-
- print_tag("list", tag1, 0);
-
- if (tag1 == MKTAG('m', 'o', 'v', 'i')) {
- avi->movi_list = avio_tell(pb) - 4;
- if (size)
- avi->movi_end = avi->movi_list + size + (size & 1);
- else
- avi->movi_end = avi->fsize;
- av_log(NULL, AV_LOG_TRACE, "movi end=%"PRIx64"\n", avi->movi_end);
- goto end_of_header;
- } else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
- ff_read_riff_info(s, size - 4);
- else if (tag1 == MKTAG('n', 'c', 'd', 't'))
- avi_read_nikon(s, list_end);
-
- break;
- case MKTAG('I', 'D', 'I', 'T'):
- {
- unsigned char date[64] = { 0 };
- size += (size & 1);
- size -= avio_read(pb, date, FFMIN(size, sizeof(date) - 1));
- avio_skip(pb, size);
- avi_metadata_creation_time(&s->metadata, date);
- break;
- }
- case MKTAG('d', 'm', 'l', 'h'):
- avi->is_odml = 1;
- avio_skip(pb, size + (size & 1));
- break;
- case MKTAG('a', 'm', 'v', 'h'):
- amv_file_format = 1;
- case MKTAG('a', 'v', 'i', 'h'):
- /* AVI header */
- /* using frame_period is bad idea */
- frame_period = avio_rl32(pb);
- avio_rl32(pb); /* max. bytes per second */
- avio_rl32(pb);
- avi->non_interleaved |= avio_rl32(pb) & AVIF_MUSTUSEINDEX;
-
- avio_skip(pb, 2 * 4);
- avio_rl32(pb);
- avio_rl32(pb);
- avih_width = avio_rl32(pb);
- avih_height = avio_rl32(pb);
-
- avio_skip(pb, size - 10 * 4);
- break;
- case MKTAG('s', 't', 'r', 'h'):
- /* stream header */
-
- tag1 = avio_rl32(pb);
- handler = avio_rl32(pb); /* codec tag */
-
- if (tag1 == MKTAG('p', 'a', 'd', 's')) {
- avio_skip(pb, size - 8);
- break;
- } else {
- stream_index++;
- st = avformat_new_stream(s, NULL);
- if (!st)
- goto fail;
-
- st->id = stream_index;
- ast = av_mallocz(sizeof(AVIStream));
- if (!ast)
- goto fail;
- st->priv_data = ast;
- }
- if (amv_file_format)
- tag1 = stream_index ? MKTAG('a', 'u', 'd', 's')
- : MKTAG('v', 'i', 'd', 's');
-
- print_tag("strh", tag1, -1);
-
- if (tag1 == MKTAG('i', 'a', 'v', 's') ||
- tag1 == MKTAG('i', 'v', 'a', 's')) {
- int64_t dv_dur;
-
- /* After some consideration -- I don't think we
- * have to support anything but DV in type1 AVIs. */
- if (s->nb_streams != 1)
- goto fail;
-
- if (handler != MKTAG('d', 'v', 's', 'd') &&
- handler != MKTAG('d', 'v', 'h', 'd') &&
- handler != MKTAG('d', 'v', 's', 'l'))
- goto fail;
-
- ast = s->streams[0]->priv_data;
- av_freep(&s->streams[0]->codec->extradata);
- av_freep(&s->streams[0]->codec);
- if (s->streams[0]->info)
- av_freep(&s->streams[0]->info->duration_error);
- av_freep(&s->streams[0]->info);
- av_freep(&s->streams[0]);
- s->nb_streams = 0;
- if (CONFIG_DV_DEMUXER) {
- avi->dv_demux = avpriv_dv_init_demux(s);
- if (!avi->dv_demux)
- goto fail;
- } else
- goto fail;
- s->streams[0]->priv_data = ast;
- avio_skip(pb, 3 * 4);
- ast->scale = avio_rl32(pb);
- ast->rate = avio_rl32(pb);
- avio_skip(pb, 4); /* start time */
-
- dv_dur = avio_rl32(pb);
- if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) {
- dv_dur *= AV_TIME_BASE;
- s->duration = av_rescale(dv_dur, ast->scale, ast->rate);
- }
- /* else, leave duration alone; timing estimation in utils.c
- * will make a guess based on bitrate. */
-
- stream_index = s->nb_streams - 1;
- avio_skip(pb, size - 9 * 4);
- break;
- }
-
- av_assert0(stream_index < s->nb_streams);
- ast->handler = handler;
-
- avio_rl32(pb); /* flags */
- avio_rl16(pb); /* priority */
- avio_rl16(pb); /* language */
- avio_rl32(pb); /* initial frame */
- ast->scale = avio_rl32(pb);
- ast->rate = avio_rl32(pb);
- if (!(ast->scale && ast->rate)) {
- av_log(s, AV_LOG_WARNING,
- "scale/rate is %"PRIu32"/%"PRIu32" which is invalid. "
- "(This file has been generated by broken software.)\n",
- ast->scale,
- ast->rate);
- if (frame_period) {
- ast->rate = 1000000;
- ast->scale = frame_period;
- } else {
- ast->rate = 25;
- ast->scale = 1;
- }
- }
- avpriv_set_pts_info(st, 64, ast->scale, ast->rate);
-
- ast->cum_len = avio_rl32(pb); /* start */
- st->nb_frames = avio_rl32(pb);
-
- st->start_time = 0;
- avio_rl32(pb); /* buffer size */
- avio_rl32(pb); /* quality */
- if (ast->cum_len*ast->scale/ast->rate > 3600) {
- av_log(s, AV_LOG_ERROR, "crazy start time, iam scared, giving up\n");
- ast->cum_len = 0;
- }
- ast->sample_size = avio_rl32(pb); /* sample ssize */
- ast->cum_len *= FFMAX(1, ast->sample_size);
- av_log(s, AV_LOG_TRACE, "%"PRIu32" %"PRIu32" %d\n",
- ast->rate, ast->scale, ast->sample_size);
-
- switch (tag1) {
- case MKTAG('v', 'i', 'd', 's'):
- codec_type = AVMEDIA_TYPE_VIDEO;
-
- ast->sample_size = 0;
- st->avg_frame_rate = av_inv_q(st->time_base);
- break;
- case MKTAG('a', 'u', 'd', 's'):
- codec_type = AVMEDIA_TYPE_AUDIO;
- break;
- case MKTAG('t', 'x', 't', 's'):
- codec_type = AVMEDIA_TYPE_SUBTITLE;
- break;
- case MKTAG('d', 'a', 't', 's'):
- codec_type = AVMEDIA_TYPE_DATA;
- break;
- default:
- av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1);
- }
-
- if (ast->sample_size < 0) {
- if (s->error_recognition & AV_EF_EXPLODE) {
- av_log(s, AV_LOG_ERROR,
- "Invalid sample_size %d at stream %d\n",
- ast->sample_size,
- stream_index);
- goto fail;
- }
- av_log(s, AV_LOG_WARNING,
- "Invalid sample_size %d at stream %d "
- "setting it to 0\n",
- ast->sample_size,
- stream_index);
- ast->sample_size = 0;
- }
-
- if (ast->sample_size == 0) {
- st->duration = st->nb_frames;
- if (st->duration > 0 && avi->io_fsize > 0 && avi->riff_end > avi->io_fsize) {
- av_log(s, AV_LOG_DEBUG, "File is truncated adjusting duration\n");
- st->duration = av_rescale(st->duration, avi->io_fsize, avi->riff_end);
- }
- }
- ast->frame_offset = ast->cum_len;
- avio_skip(pb, size - 12 * 4);
- break;
- case MKTAG('s', 't', 'r', 'f'):
- /* stream header */
- if (!size)
- break;
- if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) {
- avio_skip(pb, size);
- } else {
- uint64_t cur_pos = avio_tell(pb);
- unsigned esize;
- if (cur_pos < list_end)
- size = FFMIN(size, list_end - cur_pos);
- st = s->streams[stream_index];
- if (st->codec->codec_type != AVMEDIA_TYPE_UNKNOWN) {
- avio_skip(pb, size);
- break;
- }
- switch (codec_type) {
- case AVMEDIA_TYPE_VIDEO:
- if (amv_file_format) {
- st->codec->width = avih_width;
- st->codec->height = avih_height;
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_id = AV_CODEC_ID_AMV;
- avio_skip(pb, size);
- break;
- }
- tag1 = ff_get_bmp_header(pb, st, &esize);
-
- if (tag1 == MKTAG('D', 'X', 'S', 'B') ||
- tag1 == MKTAG('D', 'X', 'S', 'A')) {
- st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
- st->codec->codec_tag = tag1;
- st->codec->codec_id = AV_CODEC_ID_XSUB;
- break;
- }
-
- if (size > 10 * 4 && size < (1 << 30) && size < avi->fsize) {
- if (esize == size-1 && (esize&1)) {
- st->codec->extradata_size = esize - 10 * 4;
- } else
- st->codec->extradata_size = size - 10 * 4;
- if (ff_get_extradata(st->codec, pb, st->codec->extradata_size) < 0)
- return AVERROR(ENOMEM);
- }
-
- // FIXME: check if the encoder really did this correctly
- if (st->codec->extradata_size & 1)
- avio_r8(pb);
-
- /* Extract palette from extradata if bpp <= 8.
- * This code assumes that extradata contains only palette.
- * This is true for all paletted codecs implemented in
- * FFmpeg. */
- if (st->codec->extradata_size &&
- (st->codec->bits_per_coded_sample <= 8)) {
- int pal_size = (1 << st->codec->bits_per_coded_sample) << 2;
- const uint8_t *pal_src;
-
- pal_size = FFMIN(pal_size, st->codec->extradata_size);
- pal_src = st->codec->extradata +
- st->codec->extradata_size - pal_size;
- /* Exclude the "BottomUp" field from the palette */
- if (pal_src - st->codec->extradata >= 9 &&
- !memcmp(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9))
- pal_src -= 9;
- for (i = 0; i < pal_size / 4; i++)
- ast->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i);
- ast->has_pal = 1;
- }
-
- print_tag("video", tag1, 0);
-
- st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- st->codec->codec_tag = tag1;
- st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags,
- tag1);
- /* If codec is not found yet, try with the mov tags. */
- if (!st->codec->codec_id) {
- char tag_buf[32];
- av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag1);
- st->codec->codec_id =
- ff_codec_get_id(ff_codec_movvideo_tags, tag1);
- if (st->codec->codec_id)
- av_log(s, AV_LOG_WARNING,
- "mov tag found in avi (fourcc %s)\n",
- tag_buf);
- }
- /* This is needed to get the pict type which is necessary
- * for generating correct pts. */
- st->need_parsing = AVSTREAM_PARSE_HEADERS;
-
- if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
- ast->handler == MKTAG('X', 'V', 'I', 'D'))
- st->codec->codec_tag = MKTAG('X', 'V', 'I', 'D');
-
- if (st->codec->codec_tag == MKTAG('V', 'S', 'S', 'H'))
- st->need_parsing = AVSTREAM_PARSE_FULL;
-
- if (st->codec->codec_tag == 0 && st->codec->height > 0 &&
- st->codec->extradata_size < 1U << 30) {
- st->codec->extradata_size += 9;
- if ((ret = av_reallocp(&st->codec->extradata,
- st->codec->extradata_size +
- AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
- st->codec->extradata_size = 0;
- return ret;
- } else
- memcpy(st->codec->extradata + st->codec->extradata_size - 9,
- "BottomUp", 9);
- }
- st->codec->height = FFABS(st->codec->height);
-
-// avio_skip(pb, size - 5 * 4);
- break;
- case AVMEDIA_TYPE_AUDIO:
- ret = ff_get_wav_header(s, pb, st->codec, size, 0);
- if (ret < 0)
- return ret;
- ast->dshow_block_align = st->codec->block_align;
- if (ast->sample_size && st->codec->block_align &&
- ast->sample_size != st->codec->block_align) {
- av_log(s,
- AV_LOG_WARNING,
- "sample size (%d) != block align (%d)\n",
- ast->sample_size,
- st->codec->block_align);
- ast->sample_size = st->codec->block_align;
- }
- /* 2-aligned
- * (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
- if (size & 1)
- avio_skip(pb, 1);
- /* Force parsing as several audio frames can be in
- * one packet and timestamps refer to packet start. */
- st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
- /* ADTS header is in extradata, AAC without header must be
- * stored as exact frames. Parser not needed and it will
- * fail. */
- if (st->codec->codec_id == AV_CODEC_ID_AAC &&
- st->codec->extradata_size)
- st->need_parsing = AVSTREAM_PARSE_NONE;
- // The flac parser does not work with AVSTREAM_PARSE_TIMESTAMPS
- if (st->codec->codec_id == AV_CODEC_ID_FLAC)
- st->need_parsing = AVSTREAM_PARSE_NONE;
- /* AVI files with Xan DPCM audio (wrongly) declare PCM
- * audio in the header but have Axan as stream_code_tag. */
- if (ast->handler == AV_RL32("Axan")) {
- st->codec->codec_id = AV_CODEC_ID_XAN_DPCM;
- st->codec->codec_tag = 0;
- ast->dshow_block_align = 0;
- }
- if (amv_file_format) {
- st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_AMV;
- ast->dshow_block_align = 0;
- }
- if ((st->codec->codec_id == AV_CODEC_ID_AAC ||
- st->codec->codec_id == AV_CODEC_ID_FLAC ||
- st->codec->codec_id == AV_CODEC_ID_MP2 ) && ast->dshow_block_align <= 4 && ast->dshow_block_align) {
- av_log(s, AV_LOG_DEBUG, "overriding invalid dshow_block_align of %d\n", ast->dshow_block_align);
- ast->dshow_block_align = 0;
- }
- if (st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 1024 && ast->sample_size == 1024 ||
- st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 4096 && ast->sample_size == 4096 ||
- st->codec->codec_id == AV_CODEC_ID_MP3 && ast->dshow_block_align == 1152 && ast->sample_size == 1152) {
- av_log(s, AV_LOG_DEBUG, "overriding sample_size\n");
- ast->sample_size = 0;
- }
- break;
- case AVMEDIA_TYPE_SUBTITLE:
- st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
- st->request_probe= 1;
- avio_skip(pb, size);
- break;
- default:
- st->codec->codec_type = AVMEDIA_TYPE_DATA;
- st->codec->codec_id = AV_CODEC_ID_NONE;
- st->codec->codec_tag = 0;
- avio_skip(pb, size);
- break;
- }
- }
- break;
- case MKTAG('s', 't', 'r', 'd'):
- if (stream_index >= (unsigned)s->nb_streams
- || s->streams[stream_index]->codec->extradata_size
- || s->streams[stream_index]->codec->codec_tag == MKTAG('H','2','6','4')) {
- avio_skip(pb, size);
- } else {
- uint64_t cur_pos = avio_tell(pb);
- if (cur_pos < list_end)
- size = FFMIN(size, list_end - cur_pos);
- st = s->streams[stream_index];
-
- if (size<(1<<30)) {
- if (ff_get_extradata(st->codec, pb, size) < 0)
- return AVERROR(ENOMEM);
- }
-
- if (st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
- avio_r8(pb);
-
- ret = avi_extract_stream_metadata(st);
- if (ret < 0) {
- av_log(s, AV_LOG_WARNING, "could not decoding EXIF data in stream header.\n");
- }
- }
- break;
- case MKTAG('i', 'n', 'd', 'x'):
- i = avio_tell(pb);
- if (pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) &&
- avi->use_odml &&
- read_braindead_odml_indx(s, 0) < 0 &&
- (s->error_recognition & AV_EF_EXPLODE))
- goto fail;
- avio_seek(pb, i + size, SEEK_SET);
- break;
- case MKTAG('v', 'p', 'r', 'p'):
- if (stream_index < (unsigned)s->nb_streams && size > 9 * 4) {
- AVRational active, active_aspect;
-
- st = s->streams[stream_index];
- avio_rl32(pb);
- avio_rl32(pb);
- avio_rl32(pb);
- avio_rl32(pb);
- avio_rl32(pb);
-
- active_aspect.den = avio_rl16(pb);
- active_aspect.num = avio_rl16(pb);
- active.num = avio_rl32(pb);
- active.den = avio_rl32(pb);
- avio_rl32(pb); // nbFieldsPerFrame
-
- if (active_aspect.num && active_aspect.den &&
- active.num && active.den) {
- st->sample_aspect_ratio = av_div_q(active_aspect, active);
- av_log(s, AV_LOG_TRACE, "vprp %d/%d %d/%d\n",
- active_aspect.num, active_aspect.den,
- active.num, active.den);
- }
- size -= 9 * 4;
- }
- avio_skip(pb, size);
- break;
- case MKTAG('s', 't', 'r', 'n'):
- if (s->nb_streams) {
- ret = avi_read_tag(s, s->streams[s->nb_streams - 1], tag, size);
- if (ret < 0)
- return ret;
- break;
- }
- default:
- if (size > 1000000) {
- av_log(s, AV_LOG_ERROR,
- "Something went wrong during header parsing, "
- "I will ignore it and try to continue anyway.\n");
- if (s->error_recognition & AV_EF_EXPLODE)
- goto fail;
- avi->movi_list = avio_tell(pb) - 4;
- avi->movi_end = avi->fsize;
- goto end_of_header;
- }
- /* skip tag */
- size += (size & 1);
- avio_skip(pb, size);
- break;
- }
- }
-
-end_of_header:
- /* check stream number */
- if (stream_index != s->nb_streams - 1) {
-
-fail:
- return AVERROR_INVALIDDATA;
- }
-
- if (!avi->index_loaded && pb->seekable)
- avi_load_index(s);
- calculate_bitrate(s);
- avi->index_loaded |= 1;
-
- if ((ret = guess_ni_flag(s)) < 0)
- return ret;
-
- avi->non_interleaved |= ret | (s->flags & AVFMT_FLAG_SORT_DTS);
-
- dict_entry = av_dict_get(s->metadata, "ISFT", NULL, 0);
- if (dict_entry && !strcmp(dict_entry->value, "PotEncoder"))
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st = s->streams[i];
- if ( st->codec->codec_id == AV_CODEC_ID_MPEG1VIDEO
- || st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
- st->need_parsing = AVSTREAM_PARSE_FULL;
- }
-
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st = s->streams[i];
- if (st->nb_index_entries)
- break;
- }
- // DV-in-AVI cannot be non-interleaved, if set this must be
- // a mis-detection.
- if (avi->dv_demux)
- avi->non_interleaved = 0;
- if (i == s->nb_streams && avi->non_interleaved) {
- av_log(s, AV_LOG_WARNING,
- "Non-interleaved AVI without index, switching to interleaved\n");
- avi->non_interleaved = 0;
- }
-
- if (avi->non_interleaved) {
- av_log(s, AV_LOG_INFO, "non-interleaved AVI\n");
- clean_index(s);
- }
-
- ff_metadata_conv_ctx(s, NULL, avi_metadata_conv);
- ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
-
- return 0;
-}
-
-static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt)
-{
- if (pkt->size >= 7 &&
- pkt->size < INT_MAX - AVPROBE_PADDING_SIZE &&
- !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data + 5) == 2) {
- uint8_t desc[256];
- int score = AVPROBE_SCORE_EXTENSION, ret;
- AVIStream *ast = st->priv_data;
- AVInputFormat *sub_demuxer;
- AVRational time_base;
- int size;
- 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 (desc_len > pb->buf_end - pb->buf_ptr)
- goto error;
-
- ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc));
- avio_skip(pb, desc_len - ret);
- if (*desc)
- av_dict_set(&st->metadata, "title", desc, 0);
-
- avio_rl16(pb); /* flags? */
- avio_rl32(pb); /* data size */
-
- size = pb->buf_end - pb->buf_ptr;
- pd = (AVProbeData) { .buf = av_mallocz(size + AVPROBE_PADDING_SIZE),
- .buf_size = size };
- if (!pd.buf)
- goto error;
- memcpy(pd.buf, pb->buf_ptr, size);
- sub_demuxer = av_probe_input_format2(&pd, 1, &score);
- av_freep(&pd.buf);
- if (!sub_demuxer)
- goto error;
-
- if (!(ast->sub_ctx = avformat_alloc_context()))
- goto error;
-
- ast->sub_ctx->pb = pb;
-
- if (ff_copy_whitelists(ast->sub_ctx, s) < 0)
- goto error;
-
- 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);
- *st->codec = *ast->sub_ctx->streams[0]->codec;
- ast->sub_ctx->streams[0]->codec->extradata = NULL;
- time_base = ast->sub_ctx->streams[0]->time_base;
- avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
- }
- ast->sub_buffer = pkt->data;
- memset(pkt, 0, sizeof(*pkt));
- return 1;
-
-error:
- av_freep(&ast->sub_ctx);
- av_freep(&pb);
- }
- return 0;
-}
-
-static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st,
- AVPacket *pkt)
-{
- AVIStream *ast, *next_ast = next_st->priv_data;
- int64_t ts, next_ts, ts_min = INT64_MAX;
- AVStream *st, *sub_st = NULL;
- int i;
-
- next_ts = av_rescale_q(next_ast->frame_offset, next_st->time_base,
- AV_TIME_BASE_Q);
-
- 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 (ts <= next_ts && ts < ts_min) {
- ts_min = ts;
- sub_st = st;
- }
- }
- }
-
- if (sub_st) {
- ast = sub_st->priv_data;
- *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;
- }
- return sub_st;
-}
-
-static int get_stream_idx(const unsigned *d)
-{
- if (d[0] >= '0' && d[0] <= '9' &&
- d[1] >= '0' && d[1] <= '9') {
- return (d[0] - '0') * 10 + (d[1] - '0');
- } else {
- return 100; // invalid stream ID
- }
-}
-
-/**
- *
- * @param exit_early set to 1 to just gather packet position without making the changes needed to actually read & return the packet
- */
-static int avi_sync(AVFormatContext *s, int exit_early)
-{
- AVIContext *avi = s->priv_data;
- AVIOContext *pb = s->pb;
- int n;
- unsigned int d[8];
- unsigned int size;
- int64_t i, sync;
-
-start_sync:
- memset(d, -1, sizeof(d));
- for (i = sync = avio_tell(pb); !avio_feof(pb); i++) {
- int j;
-
- for (j = 0; j < 7; j++)
- d[j] = d[j + 1];
- d[7] = avio_r8(pb);
-
- size = d[4] + (d[5] << 8) + (d[6] << 16) + (d[7] << 24);
-
- n = get_stream_idx(d + 2);
- ff_tlog(s, "%X %X %X %X %X %X %X %X %"PRId64" %u %d\n",
- d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
- if (i*(avi->io_fsize>0) + (uint64_t)size > avi->fsize || d[0] > 127)
- continue;
-
- // parse ix##
- if ((d[0] == 'i' && d[1] == 'x' && n < s->nb_streams) ||
- // parse JUNK
- (d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K') ||
- (d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1') ||
- (d[0] == 'i' && d[1] == 'n' && d[2] == 'd' && d[3] == 'x')) {
- avio_skip(pb, size);
- goto start_sync;
- }
-
- // parse stray LIST
- if (d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T') {
- avio_skip(pb, 4);
- goto start_sync;
- }
-
- n = get_stream_idx(d);
-
- if (!((i - avi->last_pkt_pos) & 1) &&
- get_stream_idx(d + 1) < s->nb_streams)
- continue;
-
- // detect ##ix chunk and skip
- if (d[2] == 'i' && d[3] == 'x' && n < s->nb_streams) {
- avio_skip(pb, size);
- goto start_sync;
- }
-
- if (avi->dv_demux && n != 0)
- continue;
-
- // parse ##dc/##wb
- if (n < s->nb_streams) {
- AVStream *st;
- AVIStream *ast;
- st = s->streams[n];
- ast = st->priv_data;
-
- if (!ast) {
- av_log(s, AV_LOG_WARNING, "Skipping foreign stream %d packet\n", n);
- continue;
- }
-
- if (s->nb_streams >= 2) {
- AVStream *st1 = s->streams[1];
- AVIStream *ast1 = st1->priv_data;
- // workaround for broken small-file-bug402.avi
- if ( d[2] == 'w' && d[3] == 'b'
- && n == 0
- && st ->codec->codec_type == AVMEDIA_TYPE_VIDEO
- && st1->codec->codec_type == AVMEDIA_TYPE_AUDIO
- && ast->prefix == 'd'*256+'c'
- && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count)
- ) {
- n = 1;
- st = st1;
- ast = ast1;
- av_log(s, AV_LOG_WARNING,
- "Invalid stream + prefix combination, assuming audio.\n");
- }
- }
-
- if (!avi->dv_demux &&
- ((st->discard >= AVDISCARD_DEFAULT && size == 0) /* ||
- // FIXME: needs a little reordering
- (st->discard >= AVDISCARD_NONKEY &&
- !(pkt->flags & AV_PKT_FLAG_KEY)) */
- || st->discard >= AVDISCARD_ALL)) {
- if (!exit_early) {
- ast->frame_offset += get_duration(ast, size);
- avio_skip(pb, size);
- goto start_sync;
- }
- }
-
- if (d[2] == 'p' && d[3] == 'c' && size <= 4 * 256 + 4) {
- int k = avio_r8(pb);
- int last = (k + avio_r8(pb) - 1) & 0xFF;
-
- avio_rl16(pb); // flags
-
- // b + (g << 8) + (r << 16);
- for (; k <= last; k++)
- ast->pal[k] = 0xFFU<<24 | avio_rb32(pb)>>8;
-
- ast->has_pal = 1;
- goto start_sync;
- } else if (((ast->prefix_count < 5 || sync + 9 > i) &&
- d[2] < 128 && d[3] < 128) ||
- d[2] * 256 + d[3] == ast->prefix /* ||
- (d[2] == 'd' && d[3] == 'c') ||
- (d[2] == 'w' && d[3] == 'b') */) {
- if (exit_early)
- return 0;
- if (d[2] * 256 + d[3] == ast->prefix)
- ast->prefix_count++;
- else {
- ast->prefix = d[2] * 256 + d[3];
- ast->prefix_count = 0;
- }
-
- avi->stream_index = n;
- ast->packet_size = size + 8;
- ast->remaining = size;
-
- if (size) {
- uint64_t pos = avio_tell(pb) - 8;
- if (!st->index_entries || !st->nb_index_entries ||
- st->index_entries[st->nb_index_entries - 1].pos < pos) {
- av_add_index_entry(st, pos, ast->frame_offset, size,
- 0, AVINDEX_KEYFRAME);
- }
- }
- return 0;
- }
- }
- }
-
- if (pb->error)
- return pb->error;
- return AVERROR_EOF;
-}
-
-static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
- AVIContext *avi = s->priv_data;
- AVIOContext *pb = s->pb;
- int err;
-#if FF_API_DESTRUCT_PACKET
- void *dstr;
-#endif
-
- if (CONFIG_DV_DEMUXER && avi->dv_demux) {
- int size = avpriv_dv_get_packet(avi->dv_demux, pkt);
- if (size >= 0)
- return size;
- else
- goto resync;
- }
-
- if (avi->non_interleaved) {
- int best_stream_index = 0;
- AVStream *best_st = NULL;
- AVIStream *best_ast;
- int64_t best_ts = INT64_MAX;
- int i;
-
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st = s->streams[i];
- AVIStream *ast = st->priv_data;
- int64_t ts = ast->frame_offset;
- int64_t last_ts;
-
- if (!st->nb_index_entries)
- continue;
-
- last_ts = st->index_entries[st->nb_index_entries - 1].timestamp;
- if (!ast->remaining && ts > last_ts)
- continue;
-
- ts = av_rescale_q(ts, st->time_base,
- (AVRational) { FFMAX(1, ast->sample_size),
- AV_TIME_BASE });
-
- av_log(s, AV_LOG_TRACE, "%"PRId64" %d/%d %"PRId64"\n", ts,
- st->time_base.num, st->time_base.den, ast->frame_offset);
- if (ts < best_ts) {
- best_ts = ts;
- best_st = st;
- best_stream_index = i;
- }
- }
- if (!best_st)
- return AVERROR_EOF;
-
- best_ast = best_st->priv_data;
- best_ts = best_ast->frame_offset;
- if (best_ast->remaining) {
- i = av_index_search_timestamp(best_st,
- best_ts,
- AVSEEK_FLAG_ANY |
- AVSEEK_FLAG_BACKWARD);
- } else {
- i = av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
- if (i >= 0)
- best_ast->frame_offset = best_st->index_entries[i].timestamp;
- }
-
- if (i >= 0) {
- int64_t pos = best_st->index_entries[i].pos;
- pos += best_ast->packet_size - best_ast->remaining;
- if (avio_seek(s->pb, pos + 8, SEEK_SET) < 0)
- return AVERROR_EOF;
-
- av_assert0(best_ast->remaining <= best_ast->packet_size);
-
- avi->stream_index = best_stream_index;
- if (!best_ast->remaining)
- best_ast->packet_size =
- best_ast->remaining = best_st->index_entries[i].size;
- }
- else
- return AVERROR_EOF;
- }
-
-resync:
- if (avi->stream_index >= 0) {
- AVStream *st = s->streams[avi->stream_index];
- AVIStream *ast = st->priv_data;
- int size, err;
-
- if (get_subtitle_pkt(s, st, pkt))
- return 0;
-
- // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
- if (ast->sample_size <= 1)
- size = INT_MAX;
- else if (ast->sample_size < 32)
- // arbitrary multiplier to avoid tiny packets for raw PCM data
- size = 1024 * ast->sample_size;
- else
- size = ast->sample_size;
-
- if (size > ast->remaining)
- size = ast->remaining;
- avi->last_pkt_pos = avio_tell(pb);
- err = av_get_packet(pb, pkt, size);
- if (err < 0)
- return err;
- size = err;
-
- if (ast->has_pal && pkt->size < (unsigned)INT_MAX / 2) {
- uint8_t *pal;
- pal = av_packet_new_side_data(pkt,
- AV_PKT_DATA_PALETTE,
- AVPALETTE_SIZE);
- if (!pal) {
- av_log(s, AV_LOG_ERROR,
- "Failed to allocate data for palette\n");
- } else {
- memcpy(pal, ast->pal, AVPALETTE_SIZE);
- ast->has_pal = 0;
- }
- }
-
- if (CONFIG_DV_DEMUXER && avi->dv_demux) {
- AVBufferRef *avbuf = pkt->buf;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- dstr = pkt->destruct;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
- pkt->data, pkt->size, pkt->pos);
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = dstr;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- pkt->buf = avbuf;
- pkt->flags |= AV_PKT_FLAG_KEY;
- if (size < 0)
- av_free_packet(pkt);
- } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE &&
- !st->codec->codec_tag && read_gab2_sub(s, st, pkt)) {
- ast->frame_offset++;
- avi->stream_index = -1;
- ast->remaining = 0;
- goto resync;
- } else {
- /* XXX: How to handle B-frames in AVI? */
- pkt->dts = ast->frame_offset;
-// pkt->dts += ast->start;
- if (ast->sample_size)
- pkt->dts /= ast->sample_size;
- av_log(s, AV_LOG_TRACE,
- "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d "
- "base:%d st:%d size:%d\n",
- pkt->dts,
- ast->frame_offset,
- ast->scale,
- ast->rate,
- ast->sample_size,
- AV_TIME_BASE,
- avi->stream_index,
- size);
- pkt->stream_index = avi->stream_index;
-
- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->index_entries) {
- AVIndexEntry *e;
- int index;
-
- index = av_index_search_timestamp(st, ast->frame_offset, AVSEEK_FLAG_ANY);
- e = &st->index_entries[index];
-
- if (index >= 0 && e->timestamp == ast->frame_offset) {
- if (index == st->nb_index_entries-1) {
- int key=1;
- uint32_t state=-1;
- if (st->codec->codec_id == AV_CODEC_ID_MPEG4) {
- const uint8_t *ptr = pkt->data, *end = ptr + FFMIN(size, 256);
- while (ptr < end) {
- ptr = avpriv_find_start_code(ptr, end, &state);
- if (state == 0x1B6 && ptr < end) {
- key = !(*ptr & 0xC0);
- break;
- }
- }
- }
- if (!key)
- e->flags &= ~AVINDEX_KEYFRAME;
- }
- if (e->flags & AVINDEX_KEYFRAME)
- pkt->flags |= AV_PKT_FLAG_KEY;
- }
- } else {
- pkt->flags |= AV_PKT_FLAG_KEY;
- }
- ast->frame_offset += get_duration(ast, pkt->size);
- }
- ast->remaining -= err;
- if (!ast->remaining) {
- avi->stream_index = -1;
- ast->packet_size = 0;
- }
-
- if (!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos) {
- av_free_packet(pkt);
- goto resync;
- }
- ast->seek_pos= 0;
-
- if (!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1) {
- int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);
-
- if (avi->dts_max - dts > 2*AV_TIME_BASE) {
- avi->non_interleaved= 1;
- av_log(s, AV_LOG_INFO, "Switching to NI mode, due to poor interleaving\n");
- }else if (avi->dts_max < dts)
- avi->dts_max = dts;
- }
-
- return 0;
- }
-
- if ((err = avi_sync(s, 0)) < 0)
- return err;
- goto resync;
-}
-
-/* XXX: We make the implicit supposition that the positions are sorted
- * for each stream. */
-static int avi_read_idx1(AVFormatContext *s, int size)
-{
- AVIContext *avi = s->priv_data;
- AVIOContext *pb = s->pb;
- int nb_index_entries, i;
- AVStream *st;
- AVIStream *ast;
- unsigned int index, tag, flags, pos, len, first_packet = 1;
- unsigned last_pos = -1;
- unsigned last_idx = -1;
- int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
- int anykey = 0;
-
- nb_index_entries = size / 16;
- if (nb_index_entries <= 0)
- return AVERROR_INVALIDDATA;
-
- idx1_pos = avio_tell(pb);
- avio_seek(pb, avi->movi_list + 4, SEEK_SET);
- if (avi_sync(s, 1) == 0)
- first_packet_pos = avio_tell(pb) - 8;
- avi->stream_index = -1;
- avio_seek(pb, idx1_pos, SEEK_SET);
-
- if (s->nb_streams == 1 && s->streams[0]->codec->codec_tag == AV_RL32("MMES")) {
- first_packet_pos = 0;
- data_offset = avi->movi_list;
- }
-
- /* Read the entries and sort them in each stream component. */
- for (i = 0; i < nb_index_entries; i++) {
- if (avio_feof(pb))
- return -1;
-
- tag = avio_rl32(pb);
- flags = avio_rl32(pb);
- pos = avio_rl32(pb);
- len = avio_rl32(pb);
- av_log(s, AV_LOG_TRACE, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
- i, tag, flags, pos, len);
-
- index = ((tag & 0xff) - '0') * 10;
- index += (tag >> 8 & 0xff) - '0';
- if (index >= s->nb_streams)
- continue;
- st = s->streams[index];
- ast = st->priv_data;
-
- if (first_packet && first_packet_pos) {
- if (avi->movi_list + 4 != pos || pos + 500 > first_packet_pos)
- data_offset = first_packet_pos - pos;
- first_packet = 0;
- }
- pos += data_offset;
-
- av_log(s, AV_LOG_TRACE, "%d cum_len=%"PRId64"\n", len, ast->cum_len);
-
- // even if we have only a single stream, we should
- // switch to non-interleaved to get correct timestamps
- if (last_pos == pos)
- avi->non_interleaved = 1;
- if (last_idx != pos && len) {
- av_add_index_entry(st, pos, ast->cum_len, len, 0,
- (flags & AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
- last_idx= pos;
- }
- ast->cum_len += get_duration(ast, len);
- last_pos = pos;
- anykey |= flags&AVIIF_INDEX;
- }
- if (!anykey) {
- for (index = 0; index < s->nb_streams; index++) {
- st = s->streams[index];
- if (st->nb_index_entries)
- st->index_entries[0].flags |= AVINDEX_KEYFRAME;
- }
- }
- return 0;
-}
-
-/* Scan the index and consider any file with streams more than
- * 2 seconds or 64MB apart non-interleaved. */
-static int check_stream_max_drift(AVFormatContext *s)
-{
- int64_t min_pos, pos;
- int i;
- int *idx = av_mallocz_array(s->nb_streams, sizeof(*idx));
- if (!idx)
- return AVERROR(ENOMEM);
- for (min_pos = pos = 0; min_pos != INT64_MAX; pos = min_pos + 1LU) {
- int64_t max_dts = INT64_MIN / 2;
- int64_t min_dts = INT64_MAX / 2;
- int64_t max_buffer = 0;
-
- min_pos = INT64_MAX;
-
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st = s->streams[i];
- AVIStream *ast = st->priv_data;
- int n = st->nb_index_entries;
- while (idx[i] < n && st->index_entries[idx[i]].pos < pos)
- idx[i]++;
- if (idx[i] < n) {
- int64_t dts;
- dts = av_rescale_q(st->index_entries[idx[i]].timestamp /
- FFMAX(ast->sample_size, 1),
- st->time_base, AV_TIME_BASE_Q);
- min_dts = FFMIN(min_dts, dts);
- min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos);
- }
- }
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st = s->streams[i];
- AVIStream *ast = st->priv_data;
-
- if (idx[i] && min_dts != INT64_MAX / 2) {
- int64_t dts;
- dts = av_rescale_q(st->index_entries[idx[i] - 1].timestamp /
- FFMAX(ast->sample_size, 1),
- st->time_base, AV_TIME_BASE_Q);
- max_dts = FFMAX(max_dts, dts);
- max_buffer = FFMAX(max_buffer,
- av_rescale(dts - min_dts,
- st->codec->bit_rate,
- AV_TIME_BASE));
- }
- }
- if (max_dts - min_dts > 2 * AV_TIME_BASE ||
- max_buffer > 1024 * 1024 * 8 * 8) {
- av_free(idx);
- return 1;
- }
- }
- av_free(idx);
- return 0;
-}
-
-static int guess_ni_flag(AVFormatContext *s)
-{
- int i;
- int64_t last_start = 0;
- int64_t first_end = INT64_MAX;
- int64_t oldpos = avio_tell(s->pb);
-
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st = s->streams[i];
- int n = st->nb_index_entries;
- unsigned int size;
-
- if (n <= 0)
- continue;
-
- if (n >= 2) {
- int64_t pos = st->index_entries[0].pos;
- unsigned tag[2];
- avio_seek(s->pb, pos, SEEK_SET);
- tag[0] = avio_r8(s->pb);
- tag[1] = avio_r8(s->pb);
- avio_rl16(s->pb);
- size = avio_rl32(s->pb);
- if (get_stream_idx(tag) == i && pos + size > st->index_entries[1].pos)
- last_start = INT64_MAX;
- if (get_stream_idx(tag) == i && size == st->index_entries[0].size + 8)
- last_start = INT64_MAX;
- }
-
- if (st->index_entries[0].pos > last_start)
- last_start = st->index_entries[0].pos;
- if (st->index_entries[n - 1].pos < first_end)
- first_end = st->index_entries[n - 1].pos;
- }
- avio_seek(s->pb, oldpos, SEEK_SET);
-
- if (last_start > first_end)
- return 1;
-
- return check_stream_max_drift(s);
-}
-
-static int avi_load_index(AVFormatContext *s)
-{
- AVIContext *avi = s->priv_data;
- AVIOContext *pb = s->pb;
- uint32_t tag, size;
- int64_t pos = avio_tell(pb);
- int64_t next;
- int ret = -1;
-
- if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
- goto the_end; // maybe truncated file
- av_log(s, AV_LOG_TRACE, "movi_end=0x%"PRIx64"\n", avi->movi_end);
- for (;;) {
- tag = avio_rl32(pb);
- size = avio_rl32(pb);
- if (avio_feof(pb))
- break;
- next = avio_tell(pb) + size + (size & 1);
-
- av_log(s, AV_LOG_TRACE, "tag=%c%c%c%c size=0x%x\n",
- tag & 0xff,
- (tag >> 8) & 0xff,
- (tag >> 16) & 0xff,
- (tag >> 24) & 0xff,
- size);
-
- if (tag == MKTAG('i', 'd', 'x', '1') &&
- avi_read_idx1(s, size) >= 0) {
- avi->index_loaded=2;
- ret = 0;
- }else if (tag == MKTAG('L', 'I', 'S', 'T')) {
- uint32_t tag1 = avio_rl32(pb);
-
- if (tag1 == MKTAG('I', 'N', 'F', 'O'))
- ff_read_riff_info(s, size - 4);
- }else if (!ret)
- break;
-
- if (avio_seek(pb, next, SEEK_SET) < 0)
- break; // something is wrong here
- }
-
-the_end:
- avio_seek(pb, pos, SEEK_SET);
- return ret;
-}
-
-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_free_packet(&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);
-}
-
-static int avi_read_seek(AVFormatContext *s, int stream_index,
- int64_t timestamp, int flags)
-{
- AVIContext *avi = s->priv_data;
- AVStream *st;
- int i, index;
- int64_t pos, pos_min;
- AVIStream *ast;
-
- /* Does not matter which stream is requested dv in avi has the
- * stream information in the first video stream.
- */
- if (avi->dv_demux)
- stream_index = 0;
-
- if (!avi->index_loaded) {
- /* we only load the index on demand */
- avi_load_index(s);
- avi->index_loaded |= 1;
- }
- av_assert0(stream_index >= 0);
-
- st = s->streams[stream_index];
- ast = st->priv_data;
- index = av_index_search_timestamp(st,
- timestamp * FFMAX(ast->sample_size, 1),
- flags);
- if (index < 0) {
- if (st->nb_index_entries > 0)
- av_log(s, AV_LOG_DEBUG, "Failed to find timestamp %"PRId64 " in index %"PRId64 " .. %"PRId64 "\n",
- timestamp * FFMAX(ast->sample_size, 1),
- st->index_entries[0].timestamp,
- st->index_entries[st->nb_index_entries - 1].timestamp);
- return AVERROR_INVALIDDATA;
- }
-
- /* find the position */
- pos = st->index_entries[index].pos;
- timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
-
- av_log(s, AV_LOG_TRACE, "XX %"PRId64" %d %"PRId64"\n",
- timestamp, index, st->index_entries[index].timestamp);
-
- if (CONFIG_DV_DEMUXER && avi->dv_demux) {
- /* One and only one real stream for DV in AVI, and it has video */
- /* offsets. Calling with other stream indexes should have failed */
- /* the av_index_search_timestamp call above. */
-
- if (avio_seek(s->pb, pos, SEEK_SET) < 0)
- return -1;
-
- /* Feed the DV video stream version of the timestamp to the */
- /* DV demux so it can synthesize correct timestamps. */
- ff_dv_offset_reset(avi->dv_demux, timestamp);
-
- avi->stream_index = -1;
- return 0;
- }
-
- pos_min = pos;
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st2 = s->streams[i];
- AVIStream *ast2 = st2->priv_data;
-
- ast2->packet_size =
- ast2->remaining = 0;
-
- if (ast2->sub_ctx) {
- seek_subtitle(st, st2, timestamp);
- continue;
- }
-
- if (st2->nb_index_entries <= 0)
- continue;
-
-// av_assert1(st2->codec->block_align);
- index = av_index_search_timestamp(st2,
- av_rescale_q(timestamp,
- st->time_base,
- st2->time_base) *
- FFMAX(ast2->sample_size, 1),
- flags |
- AVSEEK_FLAG_BACKWARD |
- (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
- if (index < 0)
- index = 0;
- ast2->seek_pos = st2->index_entries[index].pos;
- pos_min = FFMIN(pos_min,ast2->seek_pos);
- }
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st2 = s->streams[i];
- AVIStream *ast2 = st2->priv_data;
-
- if (ast2->sub_ctx || st2->nb_index_entries <= 0)
- continue;
-
- index = av_index_search_timestamp(
- st2,
- av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
- flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
- if (index < 0)
- index = 0;
- while (!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min)
- index--;
- ast2->frame_offset = st2->index_entries[index].timestamp;
- }
-
- /* do the seek */
- if (avio_seek(s->pb, pos_min, SEEK_SET) < 0) {
- av_log(s, AV_LOG_ERROR, "Seek failed\n");
- return -1;
- }
- avi->stream_index = -1;
- avi->dts_max = INT_MIN;
- return 0;
-}
-
-static int avi_read_close(AVFormatContext *s)
-{
- int i;
- AVIContext *avi = s->priv_data;
-
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st = s->streams[i];
- AVIStream *ast = st->priv_data;
- if (ast) {
- if (ast->sub_ctx) {
- av_freep(&ast->sub_ctx->pb);
- avformat_close_input(&ast->sub_ctx);
- }
- av_freep(&ast->sub_buffer);
- av_free_packet(&ast->sub_pkt);
- }
- }
-
- av_freep(&avi->dv_demux);
-
- return 0;
-}
-
-static int avi_probe(AVProbeData *p)
-{
- int i;
-
- /* check file header */
- for (i = 0; avi_headers[i][0]; i++)
- if (AV_RL32(p->buf ) == AV_RL32(avi_headers[i] ) &&
- AV_RL32(p->buf + 8) == AV_RL32(avi_headers[i] + 4))
- return AVPROBE_SCORE_MAX;
-
- return 0;
-}
-
-AVInputFormat ff_avi_demuxer = {
- .name = "avi",
- .long_name = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),
- .priv_data_size = sizeof(AVIContext),
- .extensions = "avi",
- .read_probe = avi_probe,
- .read_header = avi_read_header,
- .read_packet = avi_read_packet,
- .read_close = avi_read_close,
- .read_seek = avi_read_seek,
- .priv_class = &demuxer_class,
-};
diff --git a/ffmpeg-2-8-11/libavformat/concatdec.c b/ffmpeg-2-8-11/libavformat/concatdec.c
deleted file mode 100644
index b7145ef..0000000
--- a/ffmpeg-2-8-11/libavformat/concatdec.c
+++ /dev/null
@@ -1,728 +0,0 @@
-/*
- * Copyright (c) 2012 Nicolas George
- *
- * 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/intreadwrite.h"
-#include "libavutil/opt.h"
-#include "libavutil/parseutils.h"
-#include "libavutil/timestamp.h"
-#include "avformat.h"
-#include "internal.h"
-#include "url.h"
-
-typedef enum ConcatMatchMode {
- MATCH_ONE_TO_ONE,
- MATCH_EXACT_ID,
-} ConcatMatchMode;
-
-typedef struct ConcatStream {
- AVBitStreamFilterContext *bsf;
- int out_stream_index;
-} ConcatStream;
-
-typedef struct {
- char *url;
- int64_t start_time;
- int64_t file_start_time;
- int64_t file_inpoint;
- int64_t duration;
- ConcatStream *streams;
- int64_t inpoint;
- int64_t outpoint;
- AVDictionary *metadata;
- int nb_streams;
-} ConcatFile;
-
-typedef struct {
- AVClass *class;
- ConcatFile *files;
- ConcatFile *cur_file;
- unsigned nb_files;
- AVFormatContext *avf;
- int safe;
- int seekable;
- int eof;
- ConcatMatchMode stream_match_mode;
- unsigned auto_convert;
-} ConcatContext;
-
-static int concat_probe(AVProbeData *probe)
-{
- return memcmp(probe->buf, "ffconcat version 1.0", 20) ?
- 0 : AVPROBE_SCORE_MAX;
-}
-
-static char *get_keyword(uint8_t **cursor)
-{
- char *ret = *cursor += strspn(*cursor, SPACE_CHARS);
- *cursor += strcspn(*cursor, SPACE_CHARS);
- if (**cursor) {
- *((*cursor)++) = 0;
- *cursor += strspn(*cursor, SPACE_CHARS);
- }
- return ret;
-}
-
-static int safe_filename(const char *f)
-{
- const char *start = f;
-
- for (; *f; f++) {
- /* A-Za-z0-9_- */
- if (!((unsigned)((*f | 32) - 'a') < 26 ||
- (unsigned)(*f - '0') < 10 || *f == '_' || *f == '-')) {
- if (f == start)
- return 0;
- else if (*f == '/')
- start = f + 1;
- else if (*f != '.')
- return 0;
- }
- }
- return 1;
-}
-
-#define FAIL(retcode) do { ret = (retcode); goto fail; } while(0)
-
-static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile,
- unsigned *nb_files_alloc)
-{
- ConcatContext *cat = avf->priv_data;
- ConcatFile *file;
- char *url = NULL;
- const char *proto;
- size_t url_len, proto_len;
- int ret;
-
- if (cat->safe > 0 && !safe_filename(filename)) {
- av_log(avf, AV_LOG_ERROR, "Unsafe file name '%s'\n", filename);
- FAIL(AVERROR(EPERM));
- }
-
- proto = avio_find_protocol_name(filename);
- proto_len = proto ? strlen(proto) : 0;
- if (!memcmp(filename, proto, proto_len) &&
- (filename[proto_len] == ':' || filename[proto_len] == ',')) {
- url = filename;
- filename = NULL;
- } else {
- url_len = strlen(avf->filename) + strlen(filename) + 16;
- if (!(url = av_malloc(url_len)))
- FAIL(AVERROR(ENOMEM));
- ff_make_absolute_url(url, url_len, avf->filename, filename);
- av_freep(&filename);
- }
-
- if (cat->nb_files >= *nb_files_alloc) {
- size_t n = FFMAX(*nb_files_alloc * 2, 16);
- ConcatFile *new_files;
- if (n <= cat->nb_files || n > SIZE_MAX / sizeof(*cat->files) ||
- !(new_files = av_realloc(cat->files, n * sizeof(*cat->files))))
- FAIL(AVERROR(ENOMEM));
- cat->files = new_files;
- *nb_files_alloc = n;
- }
-
- file = &cat->files[cat->nb_files++];
- memset(file, 0, sizeof(*file));
- *rfile = file;
-
- file->url = url;
- file->start_time = AV_NOPTS_VALUE;
- file->duration = AV_NOPTS_VALUE;
- file->inpoint = AV_NOPTS_VALUE;
- file->outpoint = AV_NOPTS_VALUE;
-
- return 0;
-
-fail:
- av_free(url);
- av_free(filename);
- return ret;
-}
-
-static int copy_stream_props(AVStream *st, AVStream *source_st)
-{
- int ret;
-
- if (st->codec->codec_id || !source_st->codec->codec_id) {
- if (st->codec->extradata_size < source_st->codec->extradata_size) {
- ret = ff_alloc_extradata(st->codec,
- source_st->codec->extradata_size);
- if (ret < 0)
- return ret;
- }
- memcpy(st->codec->extradata, source_st->codec->extradata,
- source_st->codec->extradata_size);
- return 0;
- }
- if ((ret = avcodec_copy_context(st->codec, source_st->codec)) < 0)
- return ret;
- st->r_frame_rate = source_st->r_frame_rate;
- st->avg_frame_rate = source_st->avg_frame_rate;
- st->time_base = source_st->time_base;
- st->sample_aspect_ratio = source_st->sample_aspect_ratio;
-
- av_dict_copy(&st->metadata, source_st->metadata, 0);
- return 0;
-}
-
-static int detect_stream_specific(AVFormatContext *avf, int idx)
-{
- ConcatContext *cat = avf->priv_data;
- AVStream *st = cat->avf->streams[idx];
- ConcatStream *cs = &cat->cur_file->streams[idx];
- AVBitStreamFilterContext *bsf;
-
- if (cat->auto_convert && st->codec->codec_id == AV_CODEC_ID_H264 &&
- (st->codec->extradata_size < 4 || AV_RB32(st->codec->extradata) != 1)) {
- av_log(cat->avf, AV_LOG_INFO,
- "Auto-inserting h264_mp4toannexb bitstream filter\n");
- if (!(bsf = av_bitstream_filter_init("h264_mp4toannexb"))) {
- av_log(avf, AV_LOG_ERROR, "h264_mp4toannexb bitstream filter "
- "required for H.264 streams\n");
- return AVERROR_BSF_NOT_FOUND;
- }
- cs->bsf = bsf;
- }
- return 0;
-}
-
-static int match_streams_one_to_one(AVFormatContext *avf)
-{
- ConcatContext *cat = avf->priv_data;
- AVStream *st;
- int i, ret;
-
- for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++) {
- if (i < avf->nb_streams) {
- st = avf->streams[i];
- } else {
- if (!(st = avformat_new_stream(avf, NULL)))
- return AVERROR(ENOMEM);
- }
- if ((ret = copy_stream_props(st, cat->avf->streams[i])) < 0)
- return ret;
- cat->cur_file->streams[i].out_stream_index = i;
- }
- return 0;
-}
-
-static int match_streams_exact_id(AVFormatContext *avf)
-{
- ConcatContext *cat = avf->priv_data;
- AVStream *st;
- int i, j, ret;
-
- for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++) {
- st = cat->avf->streams[i];
- for (j = 0; j < avf->nb_streams; j++) {
- if (avf->streams[j]->id == st->id) {
- av_log(avf, AV_LOG_VERBOSE,
- "Match slave stream #%d with stream #%d id 0x%x\n",
- i, j, st->id);
- if ((ret = copy_stream_props(avf->streams[j], st)) < 0)
- return ret;
- cat->cur_file->streams[i].out_stream_index = j;
- }
- }
- }
- return 0;
-}
-
-static int match_streams(AVFormatContext *avf)
-{
- ConcatContext *cat = avf->priv_data;
- ConcatStream *map;
- int i, ret;
-
- if (cat->cur_file->nb_streams >= cat->avf->nb_streams)
- return 0;
- map = av_realloc(cat->cur_file->streams,
- cat->avf->nb_streams * sizeof(*map));
- if (!map)
- return AVERROR(ENOMEM);
- cat->cur_file->streams = map;
- memset(map + cat->cur_file->nb_streams, 0,
- (cat->avf->nb_streams - cat->cur_file->nb_streams) * sizeof(*map));
-
- for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++)
- map[i].out_stream_index = -1;
- switch (cat->stream_match_mode) {
- case MATCH_ONE_TO_ONE:
- ret = match_streams_one_to_one(avf);
- break;
- case MATCH_EXACT_ID:
- ret = match_streams_exact_id(avf);
- break;
- default:
- ret = AVERROR_BUG;
- }
- if (ret < 0)
- return ret;
- for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++)
- if ((ret = detect_stream_specific(avf, i)) < 0)
- return ret;
- cat->cur_file->nb_streams = cat->avf->nb_streams;
- return 0;
-}
-
-static int open_file(AVFormatContext *avf, unsigned fileno)
-{
- ConcatContext *cat = avf->priv_data;
- ConcatFile *file = &cat->files[fileno];
- int ret;
-
- if (cat->avf)
- avformat_close_input(&cat->avf);
-
- cat->avf = avformat_alloc_context();
- if (!cat->avf)
- return AVERROR(ENOMEM);
-
- cat->avf->interrupt_callback = avf->interrupt_callback;
-
- if ((ret = ff_copy_whitelists(cat->avf, avf)) < 0)
- return ret;
-
- if ((ret = avformat_open_input(&cat->avf, file->url, NULL, NULL)) < 0 ||
- (ret = avformat_find_stream_info(cat->avf, NULL)) < 0) {
- av_log(avf, AV_LOG_ERROR, "Impossible to open '%s'\n", file->url);
- avformat_close_input(&cat->avf);
- return ret;
- }
- cat->cur_file = file;
- if (file->start_time == AV_NOPTS_VALUE)
- file->start_time = !fileno ? 0 :
- cat->files[fileno - 1].start_time +
- cat->files[fileno - 1].duration;
- file->file_start_time = (cat->avf->start_time == AV_NOPTS_VALUE) ? 0 : cat->avf->start_time;
- file->file_inpoint = (file->inpoint == AV_NOPTS_VALUE) ? file->file_start_time : file->inpoint;
- if ((ret = match_streams(avf)) < 0)
- return ret;
- if (file->inpoint != AV_NOPTS_VALUE) {
- if ((ret = avformat_seek_file(cat->avf, -1, INT64_MIN, file->inpoint, file->inpoint, 0)) < 0)
- return ret;
- }
- return 0;
-}
-
-static int concat_read_close(AVFormatContext *avf)
-{
- ConcatContext *cat = avf->priv_data;
- unsigned i;
-
- if (cat->avf)
- avformat_close_input(&cat->avf);
- for (i = 0; i < cat->nb_files; i++) {
- av_freep(&cat->files[i].url);
- av_freep(&cat->files[i].streams);
- av_dict_free(&cat->files[i].metadata);
- }
- av_freep(&cat->files);
- return 0;
-}
-
-static int concat_read_header(AVFormatContext *avf)
-{
- ConcatContext *cat = avf->priv_data;
- uint8_t buf[4096];
- uint8_t *cursor, *keyword;
- int ret, line = 0, i;
- unsigned nb_files_alloc = 0;
- ConcatFile *file = NULL;
- int64_t time = 0;
-
- while (1) {
- if ((ret = ff_get_line(avf->pb, buf, sizeof(buf))) <= 0)
- break;
- line++;
- cursor = buf;
- keyword = get_keyword(&cursor);
- if (!*keyword || *keyword == '#')
- continue;
-
- if (!strcmp(keyword, "file")) {
- char *filename = av_get_token((const char **)&cursor, SPACE_CHARS);
- if (!filename) {
- av_log(avf, AV_LOG_ERROR, "Line %d: filename required\n", line);
- FAIL(AVERROR_INVALIDDATA);
- }
- if ((ret = add_file(avf, filename, &file, &nb_files_alloc)) < 0)
- goto fail;
- } else if (!strcmp(keyword, "duration") || !strcmp(keyword, "inpoint") || !strcmp(keyword, "outpoint")) {
- char *dur_str = get_keyword(&cursor);
- int64_t dur;
- if (!file) {
- av_log(avf, AV_LOG_ERROR, "Line %d: %s without file\n",
- line, keyword);
- FAIL(AVERROR_INVALIDDATA);
- }
- if ((ret = av_parse_time(&dur, dur_str, 1)) < 0) {
- av_log(avf, AV_LOG_ERROR, "Line %d: invalid %s '%s'\n",
- line, keyword, dur_str);
- goto fail;
- }
- if (!strcmp(keyword, "duration"))
- file->duration = dur;
- else if (!strcmp(keyword, "inpoint"))
- file->inpoint = dur;
- else if (!strcmp(keyword, "outpoint"))
- file->outpoint = dur;
- } else if (!strcmp(keyword, "file_packet_metadata")) {
- char *metadata;
- metadata = av_get_token((const char **)&cursor, SPACE_CHARS);
- if (!metadata) {
- av_log(avf, AV_LOG_ERROR, "Line %d: packet metadata required\n", line);
- FAIL(AVERROR_INVALIDDATA);
- }
- if (!file) {
- av_log(avf, AV_LOG_ERROR, "Line %d: %s without file\n",
- line, keyword);
- FAIL(AVERROR_INVALIDDATA);
- }
- if ((ret = av_dict_parse_string(&file->metadata, metadata, "=", "", 0)) < 0) {
- av_log(avf, AV_LOG_ERROR, "Line %d: failed to parse metadata string\n", line);
- av_freep(&metadata);
- FAIL(AVERROR_INVALIDDATA);
- }
- av_freep(&metadata);
- } else if (!strcmp(keyword, "stream")) {
- if (!avformat_new_stream(avf, NULL))
- FAIL(AVERROR(ENOMEM));
- } else if (!strcmp(keyword, "exact_stream_id")) {
- if (!avf->nb_streams) {
- av_log(avf, AV_LOG_ERROR, "Line %d: exact_stream_id without stream\n",
- line);
- FAIL(AVERROR_INVALIDDATA);
- }
- avf->streams[avf->nb_streams - 1]->id =
- strtol(get_keyword(&cursor), NULL, 0);
- } else if (!strcmp(keyword, "ffconcat")) {
- char *ver_kw = get_keyword(&cursor);
- char *ver_val = get_keyword(&cursor);
- if (strcmp(ver_kw, "version") || strcmp(ver_val, "1.0")) {
- av_log(avf, AV_LOG_ERROR, "Line %d: invalid version\n", line);
- FAIL(AVERROR_INVALIDDATA);
- }
- if (cat->safe < 0)
- cat->safe = 1;
- } else {
- av_log(avf, AV_LOG_ERROR, "Line %d: unknown keyword '%s'\n",
- line, keyword);
- FAIL(AVERROR_INVALIDDATA);
- }
- }
- if (ret < 0)
- goto fail;
- if (!cat->nb_files)
- FAIL(AVERROR_INVALIDDATA);
-
- for (i = 0; i < cat->nb_files; i++) {
- if (cat->files[i].start_time == AV_NOPTS_VALUE)
- cat->files[i].start_time = time;
- else
- time = cat->files[i].start_time;
- if (cat->files[i].duration == AV_NOPTS_VALUE) {
- if (cat->files[i].inpoint == AV_NOPTS_VALUE || cat->files[i].outpoint == AV_NOPTS_VALUE)
- break;
- cat->files[i].duration = cat->files[i].outpoint - cat->files[i].inpoint;
- }
- time += cat->files[i].duration;
- }
- if (i == cat->nb_files) {
- avf->duration = time;
- cat->seekable = 1;
- }
-
- cat->stream_match_mode = avf->nb_streams ? MATCH_EXACT_ID :
- MATCH_ONE_TO_ONE;
- if ((ret = open_file(avf, 0)) < 0)
- goto fail;
- return 0;
-
-fail:
- concat_read_close(avf);
- return ret;
-}
-
-static int open_next_file(AVFormatContext *avf)
-{
- ConcatContext *cat = avf->priv_data;
- unsigned fileno = cat->cur_file - cat->files;
-
- if (cat->cur_file->duration == AV_NOPTS_VALUE) {
- cat->cur_file->duration = cat->avf->duration;
- if (cat->cur_file->inpoint != AV_NOPTS_VALUE)
- cat->cur_file->duration -= (cat->cur_file->inpoint - cat->cur_file->file_start_time);
- if (cat->cur_file->outpoint != AV_NOPTS_VALUE)
- cat->cur_file->duration -= cat->avf->duration - (cat->cur_file->outpoint - cat->cur_file->file_start_time);
- }
-
- if (++fileno >= cat->nb_files) {
- cat->eof = 1;
- return AVERROR_EOF;
- }
- return open_file(avf, fileno);
-}
-
-static int filter_packet(AVFormatContext *avf, ConcatStream *cs, AVPacket *pkt)
-{
- AVStream *st = avf->streams[cs->out_stream_index];
- AVBitStreamFilterContext *bsf;
- AVPacket pkt2;
- int ret;
-
- av_assert0(cs->out_stream_index >= 0);
- for (bsf = cs->bsf; bsf; bsf = bsf->next) {
- pkt2 = *pkt;
- ret = av_bitstream_filter_filter(bsf, st->codec, NULL,
- &pkt2.data, &pkt2.size,
- pkt->data, pkt->size,
- !!(pkt->flags & AV_PKT_FLAG_KEY));
- if (ret < 0) {
- av_packet_unref(pkt);
- return ret;
- }
- av_assert0(pkt2.buf);
- if (ret == 0 && pkt2.data != pkt->data) {
- if ((ret = av_copy_packet(&pkt2, pkt)) < 0) {
- av_free(pkt2.data);
- return ret;
- }
- ret = 1;
- }
- if (ret > 0) {
- av_free_packet(pkt);
- pkt2.buf = av_buffer_create(pkt2.data, pkt2.size,
- av_buffer_default_free, NULL, 0);
- if (!pkt2.buf) {
- av_free(pkt2.data);
- return AVERROR(ENOMEM);
- }
- }
- *pkt = pkt2;
- }
- return 0;
-}
-
-/* Returns true if the packet dts is greater or equal to the specified outpoint. */
-static int packet_after_outpoint(ConcatContext *cat, AVPacket *pkt)
-{
- if (cat->cur_file->outpoint != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE) {
- return av_compare_ts(pkt->dts, cat->avf->streams[pkt->stream_index]->time_base,
- cat->cur_file->outpoint, AV_TIME_BASE_Q) >= 0;
- }
- return 0;
-}
-
-static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt)
-{
- ConcatContext *cat = avf->priv_data;
- int ret;
- int64_t delta;
- ConcatStream *cs;
- AVStream *st;
-
- if (cat->eof)
- return AVERROR_EOF;
-
- if (!cat->avf)
- return AVERROR(EIO);
-
- while (1) {
- ret = av_read_frame(cat->avf, pkt);
- if (ret == AVERROR_EOF || packet_after_outpoint(cat, pkt)) {
- if (ret == 0)
- av_packet_unref(pkt);
- if ((ret = open_next_file(avf)) < 0)
- return ret;
- continue;
- }
- if (ret < 0)
- return ret;
- if ((ret = match_streams(avf)) < 0) {
- av_packet_unref(pkt);
- return ret;
- }
- cs = &cat->cur_file->streams[pkt->stream_index];
- if (cs->out_stream_index < 0) {
- av_packet_unref(pkt);
- continue;
- }
- pkt->stream_index = cs->out_stream_index;
- break;
- }
- if ((ret = filter_packet(avf, cs, pkt)))
- return ret;
-
- st = cat->avf->streams[pkt->stream_index];
- av_log(avf, AV_LOG_DEBUG, "file:%d stream:%d pts:%s pts_time:%s dts:%s dts_time:%s",
- (unsigned)(cat->cur_file - cat->files), pkt->stream_index,
- av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
- av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
-
- delta = av_rescale_q(cat->cur_file->start_time - cat->cur_file->file_inpoint,
- AV_TIME_BASE_Q,
- cat->avf->streams[pkt->stream_index]->time_base);
- if (pkt->pts != AV_NOPTS_VALUE)
- pkt->pts += delta;
- if (pkt->dts != AV_NOPTS_VALUE)
- pkt->dts += delta;
- av_log(avf, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
- 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) {
- uint8_t* metadata;
- int metadata_len;
- char* packed_metadata = av_packet_pack_dictionary(cat->cur_file->metadata, &metadata_len);
- if (!packed_metadata)
- return AVERROR(ENOMEM);
- if (!(metadata = av_packet_new_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, metadata_len))) {
- av_freep(&packed_metadata);
- return AVERROR(ENOMEM);
- }
- memcpy(metadata, packed_metadata, metadata_len);
- av_freep(&packed_metadata);
- }
- return ret;
-}
-
-static void rescale_interval(AVRational tb_in, AVRational tb_out,
- int64_t *min_ts, int64_t *ts, int64_t *max_ts)
-{
- *ts = av_rescale_q (* ts, tb_in, tb_out);
- *min_ts = av_rescale_q_rnd(*min_ts, tb_in, tb_out,
- AV_ROUND_UP | AV_ROUND_PASS_MINMAX);
- *max_ts = av_rescale_q_rnd(*max_ts, tb_in, tb_out,
- AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
-}
-
-static int try_seek(AVFormatContext *avf, int stream,
- int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
-{
- ConcatContext *cat = avf->priv_data;
- int64_t t0 = cat->cur_file->start_time - cat->cur_file->file_inpoint;
-
- ts -= t0;
- min_ts = min_ts == INT64_MIN ? INT64_MIN : min_ts - t0;
- max_ts = max_ts == INT64_MAX ? INT64_MAX : max_ts - t0;
- if (stream >= 0) {
- if (stream >= cat->avf->nb_streams)
- return AVERROR(EIO);
- rescale_interval(AV_TIME_BASE_Q, cat->avf->streams[stream]->time_base,
- &min_ts, &ts, &max_ts);
- }
- return avformat_seek_file(cat->avf, stream, min_ts, ts, max_ts, flags);
-}
-
-static int real_seek(AVFormatContext *avf, int stream,
- int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
-{
- ConcatContext *cat = avf->priv_data;
- int ret, left, right;
-
- if (stream >= 0) {
- if (stream >= avf->nb_streams)
- return AVERROR(EINVAL);
- rescale_interval(avf->streams[stream]->time_base, AV_TIME_BASE_Q,
- &min_ts, &ts, &max_ts);
- }
-
- left = 0;
- right = cat->nb_files;
- while (right - left > 1) {
- int mid = (left + right) / 2;
- if (ts < cat->files[mid].start_time)
- right = mid;
- else
- left = mid;
- }
-
- if ((ret = open_file(avf, left)) < 0)
- return ret;
-
- ret = try_seek(avf, stream, min_ts, ts, max_ts, flags);
- if (ret < 0 &&
- left < cat->nb_files - 1 &&
- cat->files[left + 1].start_time < max_ts) {
- if ((ret = open_file(avf, left + 1)) < 0)
- return ret;
- ret = try_seek(avf, stream, min_ts, ts, max_ts, flags);
- }
- return ret;
-}
-
-static int concat_seek(AVFormatContext *avf, int stream,
- int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
-{
- ConcatContext *cat = avf->priv_data;
- ConcatFile *cur_file_saved = cat->cur_file;
- AVFormatContext *cur_avf_saved = cat->avf;
- int ret;
-
- if (!cat->seekable)
- return AVERROR(ESPIPE); /* XXX: can we use it? */
- if (flags & (AVSEEK_FLAG_BYTE | AVSEEK_FLAG_FRAME))
- return AVERROR(ENOSYS);
- cat->avf = NULL;
- if ((ret = real_seek(avf, stream, min_ts, ts, max_ts, flags)) < 0) {
- if (cat->avf)
- avformat_close_input(&cat->avf);
- cat->avf = cur_avf_saved;
- cat->cur_file = cur_file_saved;
- } else {
- avformat_close_input(&cur_avf_saved);
- cat->eof = 0;
- }
- return ret;
-}
-
-#define OFFSET(x) offsetof(ConcatContext, x)
-#define DEC AV_OPT_FLAG_DECODING_PARAM
-
-static const AVOption options[] = {
- { "safe", "enable safe mode",
- OFFSET(safe), AV_OPT_TYPE_INT, {.i64 = 1}, -1, 1, DEC },
- { "auto_convert", "automatically convert bitstream format",
- OFFSET(auto_convert), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, DEC },
- { NULL }
-};
-
-static const AVClass concat_class = {
- .class_name = "concat demuxer",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-
-AVInputFormat ff_concat_demuxer = {
- .name = "concat",
- .long_name = NULL_IF_CONFIG_SMALL("Virtual concatenation script"),
- .priv_data_size = sizeof(ConcatContext),
- .read_probe = concat_probe,
- .read_header = concat_read_header,
- .read_packet = concat_read_packet,
- .read_close = concat_read_close,
- .read_seek2 = concat_seek,
- .priv_class = &concat_class,
-};
diff --git a/ffmpeg-2-8-11/libavformat/hls.c b/ffmpeg-2-8-11/libavformat/hls.c
deleted file mode 100644
index c32ecb1..0000000
--- a/ffmpeg-2-8-11/libavformat/hls.c
+++ /dev/null
@@ -1,2018 +0,0 @@
-/*
- * Apple HTTP Live Streaming demuxer
- * Copyright (c) 2010 Martin Storsjo
- * Copyright (c) 2013 Anssi Hannula
- *
- * 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
- * Apple HTTP Live Streaming demuxer
- * http://tools.ietf.org/html/draft-pantos-http-live-streaming
- */
-
-#include "libavutil/avstring.h"
-#include "libavutil/avassert.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/opt.h"
-#include "libavutil/dict.h"
-#include "libavutil/time.h"
-#include "avformat.h"
-#include "internal.h"
-#include "avio_internal.h"
-#include "url.h"
-#include "id3v2.h"
-
-#define INITIAL_BUFFER_SIZE 32768
-
-#define MAX_FIELD_LEN 64
-#define MAX_CHARACTERISTICS_LEN 512
-
-#define MPEG_TIME_BASE 90000
-#define MPEG_TIME_BASE_Q (AVRational){1, MPEG_TIME_BASE}
-
-/*
- * An apple http stream consists of a playlist with media segment files,
- * played sequentially. There may be several playlists with the same
- * video content, in different bandwidth variants, that are played in
- * parallel (preferably only one bandwidth variant at a time). In this case,
- * the user supplied the url to a main playlist that only lists the variant
- * playlists.
- *
- * If the main playlist doesn't point at any variants, we still create
- * one anonymous toplevel variant for this, to maintain the structure.
- */
-
-enum KeyType {
- KEY_NONE,
- KEY_AES_128,
- KEY_SAMPLE_AES
-};
-
-struct segment {
- int64_t duration;
- int64_t url_offset;
- int64_t size;
- char *url;
- char *key;
- enum KeyType key_type;
- uint8_t iv[16];
- /* associated Media Initialization Section, treated as a segment */
- struct segment *init_section;
-};
-
-struct rendition;
-
-enum PlaylistType {
- PLS_TYPE_UNSPECIFIED,
- PLS_TYPE_EVENT,
- PLS_TYPE_VOD
-};
-
-/*
- * Each playlist has its own demuxer. If it currently is active,
- * it has an open AVIOContext too, and potentially an AVPacket
- * containing the next packet from this stream.
- */
-struct playlist {
- char url[MAX_URL_SIZE];
- AVIOContext pb;
- uint8_t* read_buffer;
- URLContext *input;
- AVFormatContext *parent;
- int index;
- AVFormatContext *ctx;
- AVPacket pkt;
- int stream_offset;
-
- int finished;
- enum PlaylistType type;
- int64_t target_duration;
- int start_seq_no;
- int n_segments;
- struct segment **segments;
- int needed, cur_needed;
- int cur_seq_no;
- int64_t cur_seg_offset;
- int64_t last_load_time;
-
- /* Currently active Media Initialization Section */
- struct segment *cur_init_section;
- uint8_t *init_sec_buf;
- unsigned int init_sec_buf_size;
- unsigned int init_sec_data_len;
- unsigned int init_sec_buf_read_offset;
-
- char key_url[MAX_URL_SIZE];
- uint8_t key[16];
-
- /* ID3 timestamp handling (elementary audio streams have ID3 timestamps
- * (and possibly other ID3 tags) in the beginning of each segment) */
- int is_id3_timestamped; /* -1: not yet known */
- int64_t id3_mpegts_timestamp; /* in mpegts tb */
- int64_t id3_offset; /* in stream original tb */
- uint8_t* id3_buf; /* temp buffer for id3 parsing */
- unsigned int id3_buf_size;
- AVDictionary *id3_initial; /* data from first id3 tag */
- int id3_found; /* ID3 tag found at some point */
- int id3_changed; /* ID3 tag data has changed at some point */
- ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */
-
- int64_t seek_timestamp;
- int seek_flags;
- int seek_stream_index; /* into subdemuxer stream array */
-
- /* Renditions associated with this playlist, if any.
- * Alternative rendition playlists have a single rendition associated
- * with them, and variant main Media Playlists may have
- * multiple (playlist-less) renditions associated with them. */
- int n_renditions;
- struct rendition **renditions;
-
- /* Media Initialization Sections (EXT-X-MAP) associated with this
- * playlist, if any. */
- int n_init_sections;
- struct segment **init_sections;
-};
-
-/*
- * Renditions are e.g. alternative subtitle or audio streams.
- * The rendition may either be an external playlist or it may be
- * contained in the main Media Playlist of the variant (in which case
- * playlist is NULL).
- */
-struct rendition {
- enum AVMediaType type;
- struct playlist *playlist;
- char group_id[MAX_FIELD_LEN];
- char language[MAX_FIELD_LEN];
- char name[MAX_FIELD_LEN];
- int disposition;
-};
-
-struct variant {
- int bandwidth;
-
- /* every variant contains at least the main Media Playlist in index 0 */
- int n_playlists;
- struct playlist **playlists;
-
- char audio_group[MAX_FIELD_LEN];
- char video_group[MAX_FIELD_LEN];
- char subtitles_group[MAX_FIELD_LEN];
-};
-
-typedef struct HLSContext {
- AVClass *class;
- int n_variants;
- struct variant **variants;
- int n_playlists;
- struct playlist **playlists;
- int n_renditions;
- struct rendition **renditions;
-
- int cur_seq_no;
- int live_start_index;
- int first_packet;
- int64_t first_timestamp;
- int64_t cur_timestamp;
- AVIOInterruptCB *interrupt_callback;
- char *user_agent; ///< holds HTTP user agent set as an AVOption to the HTTP protocol context
- char *cookies; ///< holds HTTP cookie values set in either the initial response or as an AVOption to the HTTP protocol context
- char *headers; ///< holds HTTP headers set as an AVOption to the HTTP protocol context
- AVDictionary *avio_opts;
-} HLSContext;
-
-static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
-{
- int len = ff_get_line(s, buf, maxlen);
- while (len > 0 && av_isspace(buf[len - 1]))
- buf[--len] = '\0';
- return len;
-}
-
-static void free_segment_list(struct playlist *pls)
-{
- int i;
- for (i = 0; i < pls->n_segments; i++) {
- av_freep(&pls->segments[i]->key);
- av_freep(&pls->segments[i]->url);
- av_freep(&pls->segments[i]);
- }
- av_freep(&pls->segments);
- pls->n_segments = 0;
-}
-
-static void free_init_section_list(struct playlist *pls)
-{
- int i;
- for (i = 0; i < pls->n_init_sections; i++) {
- av_freep(&pls->init_sections[i]->url);
- av_freep(&pls->init_sections[i]);
- }
- av_freep(&pls->init_sections);
- pls->n_init_sections = 0;
-}
-
-static void free_playlist_list(HLSContext *c)
-{
- int i;
- for (i = 0; i < c->n_playlists; i++) {
- struct playlist *pls = c->playlists[i];
- free_segment_list(pls);
- free_init_section_list(pls);
- av_freep(&pls->renditions);
- av_freep(&pls->id3_buf);
- av_dict_free(&pls->id3_initial);
- ff_id3v2_free_extra_meta(&pls->id3_deferred_extra);
- av_freep(&pls->init_sec_buf);
- av_free_packet(&pls->pkt);
- av_freep(&pls->pb.buffer);
- if (pls->input)
- ffurl_close(pls->input);
- if (pls->ctx) {
- pls->ctx->pb = NULL;
- avformat_close_input(&pls->ctx);
- }
- av_free(pls);
- }
- av_freep(&c->playlists);
- av_freep(&c->cookies);
- av_freep(&c->user_agent);
- c->n_playlists = 0;
-}
-
-static void free_variant_list(HLSContext *c)
-{
- int i;
- for (i = 0; i < c->n_variants; i++) {
- struct variant *var = c->variants[i];
- av_freep(&var->playlists);
- av_free(var);
- }
- av_freep(&c->variants);
- c->n_variants = 0;
-}
-
-static void free_rendition_list(HLSContext *c)
-{
- int i;
- for (i = 0; i < c->n_renditions; i++)
- av_freep(&c->renditions[i]);
- av_freep(&c->renditions);
- c->n_renditions = 0;
-}
-
-/*
- * Used to reset a statically allocated AVPacket to a clean slate,
- * 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);
- pls->seek_timestamp = AV_NOPTS_VALUE;
-
- pls->is_id3_timestamped = -1;
- pls->id3_mpegts_timestamp = AV_NOPTS_VALUE;
-
- dynarray_add(&c->playlists, &c->n_playlists, pls);
- return pls;
-}
-
-struct variant_info {
- char bandwidth[20];
- /* variant group ids: */
- char audio[MAX_FIELD_LEN];
- char video[MAX_FIELD_LEN];
- char subtitles[MAX_FIELD_LEN];
-};
-
-static struct variant *new_variant(HLSContext *c, struct variant_info *info,
- const char *url, const char *base)
-{
- struct variant *var;
- struct playlist *pls;
-
- pls = new_playlist(c, url, base);
- if (!pls)
- return NULL;
-
- var = av_mallocz(sizeof(struct variant));
- if (!var)
- return NULL;
-
- if (info) {
- var->bandwidth = atoi(info->bandwidth);
- strcpy(var->audio_group, info->audio);
- strcpy(var->video_group, info->video);
- strcpy(var->subtitles_group, info->subtitles);
- }
-
- dynarray_add(&c->variants, &c->n_variants, var);
- dynarray_add(&var->playlists, &var->n_playlists, pls);
- return var;
-}
-
-static void handle_variant_args(struct variant_info *info, const char *key,
- int key_len, char **dest, int *dest_len)
-{
- if (!strncmp(key, "BANDWIDTH=", key_len)) {
- *dest = info->bandwidth;
- *dest_len = sizeof(info->bandwidth);
- } else if (!strncmp(key, "AUDIO=", key_len)) {
- *dest = info->audio;
- *dest_len = sizeof(info->audio);
- } else if (!strncmp(key, "VIDEO=", key_len)) {
- *dest = info->video;
- *dest_len = sizeof(info->video);
- } else if (!strncmp(key, "SUBTITLES=", key_len)) {
- *dest = info->subtitles;
- *dest_len = sizeof(info->subtitles);
- }
-}
-
-struct key_info {
- char uri[MAX_URL_SIZE];
- char method[11];
- char iv[35];
-};
-
-static void handle_key_args(struct key_info *info, const char *key,
- int key_len, char **dest, int *dest_len)
-{
- if (!strncmp(key, "METHOD=", key_len)) {
- *dest = info->method;
- *dest_len = sizeof(info->method);
- } else if (!strncmp(key, "URI=", key_len)) {
- *dest = info->uri;
- *dest_len = sizeof(info->uri);
- } else if (!strncmp(key, "IV=", key_len)) {
- *dest = info->iv;
- *dest_len = sizeof(info->iv);
- }
-}
-
-struct init_section_info {
- char uri[MAX_URL_SIZE];
- char byterange[32];
-};
-
-static struct segment *new_init_section(struct playlist *pls,
- struct init_section_info *info,
- const char *url_base)
-{
- struct segment *sec;
- char *ptr;
- char tmp_str[MAX_URL_SIZE];
-
- if (!info->uri[0])
- return NULL;
-
- sec = av_mallocz(sizeof(*sec));
- if (!sec)
- return NULL;
-
- ff_make_absolute_url(tmp_str, sizeof(tmp_str), url_base, info->uri);
- sec->url = av_strdup(tmp_str);
- if (!sec->url) {
- av_free(sec);
- return NULL;
- }
-
- if (info->byterange[0]) {
- sec->size = atoi(info->byterange);
- ptr = strchr(info->byterange, '@');
- if (ptr)
- sec->url_offset = atoi(ptr+1);
- } else {
- /* the entire file is the init section */
- sec->size = -1;
- }
-
- dynarray_add(&pls->init_sections, &pls->n_init_sections, sec);
-
- return sec;
-}
-
-static void handle_init_section_args(struct init_section_info *info, const char *key,
- int key_len, char **dest, int *dest_len)
-{
- if (!strncmp(key, "URI=", key_len)) {
- *dest = info->uri;
- *dest_len = sizeof(info->uri);
- } else if (!strncmp(key, "BYTERANGE=", key_len)) {
- *dest = info->byterange;
- *dest_len = sizeof(info->byterange);
- }
-}
-
-struct rendition_info {
- char type[16];
- char uri[MAX_URL_SIZE];
- char group_id[MAX_FIELD_LEN];
- char language[MAX_FIELD_LEN];
- char assoc_language[MAX_FIELD_LEN];
- char name[MAX_FIELD_LEN];
- char defaultr[4];
- char forced[4];
- char characteristics[MAX_CHARACTERISTICS_LEN];
-};
-
-static struct rendition *new_rendition(HLSContext *c, struct rendition_info *info,
- const char *url_base)
-{
- struct rendition *rend;
- enum AVMediaType type = AVMEDIA_TYPE_UNKNOWN;
- char *characteristic;
- char *chr_ptr;
- char *saveptr;
-
- if (!strcmp(info->type, "AUDIO"))
- type = AVMEDIA_TYPE_AUDIO;
- else if (!strcmp(info->type, "VIDEO"))
- type = AVMEDIA_TYPE_VIDEO;
- else if (!strcmp(info->type, "SUBTITLES"))
- type = AVMEDIA_TYPE_SUBTITLE;
- else if (!strcmp(info->type, "CLOSED-CAPTIONS"))
- /* CLOSED-CAPTIONS is ignored since we do not support CEA-608 CC in
- * AVC SEI RBSP anyway */
- return NULL;
-
- if (type == AVMEDIA_TYPE_UNKNOWN)
- return NULL;
-
- /* URI is mandatory for subtitles as per spec */
- if (type == AVMEDIA_TYPE_SUBTITLE && !info->uri[0])
- return NULL;
-
- /* TODO: handle subtitles (each segment has to parsed separately) */
- if (type == AVMEDIA_TYPE_SUBTITLE)
- return NULL;
-
- rend = av_mallocz(sizeof(struct rendition));
- if (!rend)
- return NULL;
-
- dynarray_add(&c->renditions, &c->n_renditions, rend);
-
- rend->type = type;
- strcpy(rend->group_id, info->group_id);
- strcpy(rend->language, info->language);
- strcpy(rend->name, info->name);
-
- /* add the playlist if this is an external rendition */
- if (info->uri[0]) {
- rend->playlist = new_playlist(c, info->uri, url_base);
- if (rend->playlist)
- dynarray_add(&rend->playlist->renditions,
- &rend->playlist->n_renditions, rend);
- }
-
- if (info->assoc_language[0]) {
- int langlen = strlen(rend->language);
- if (langlen < sizeof(rend->language) - 3) {
- rend->language[langlen] = ',';
- strncpy(rend->language + langlen + 1, info->assoc_language,
- sizeof(rend->language) - langlen - 2);
- }
- }
-
- if (!strcmp(info->defaultr, "YES"))
- rend->disposition |= AV_DISPOSITION_DEFAULT;
- if (!strcmp(info->forced, "YES"))
- rend->disposition |= AV_DISPOSITION_FORCED;
-
- chr_ptr = info->characteristics;
- while ((characteristic = av_strtok(chr_ptr, ",", &saveptr))) {
- if (!strcmp(characteristic, "public.accessibility.describes-music-and-sound"))
- rend->disposition |= AV_DISPOSITION_HEARING_IMPAIRED;
- else if (!strcmp(characteristic, "public.accessibility.describes-video"))
- rend->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;
-
- chr_ptr = NULL;
- }
-
- return rend;
-}
-
-static void handle_rendition_args(struct rendition_info *info, const char *key,
- int key_len, char **dest, int *dest_len)
-{
- if (!strncmp(key, "TYPE=", key_len)) {
- *dest = info->type;
- *dest_len = sizeof(info->type);
- } else if (!strncmp(key, "URI=", key_len)) {
- *dest = info->uri;
- *dest_len = sizeof(info->uri);
- } else if (!strncmp(key, "GROUP-ID=", key_len)) {
- *dest = info->group_id;
- *dest_len = sizeof(info->group_id);
- } else if (!strncmp(key, "LANGUAGE=", key_len)) {
- *dest = info->language;
- *dest_len = sizeof(info->language);
- } else if (!strncmp(key, "ASSOC-LANGUAGE=", key_len)) {
- *dest = info->assoc_language;
- *dest_len = sizeof(info->assoc_language);
- } else if (!strncmp(key, "NAME=", key_len)) {
- *dest = info->name;
- *dest_len = sizeof(info->name);
- } else if (!strncmp(key, "DEFAULT=", key_len)) {
- *dest = info->defaultr;
- *dest_len = sizeof(info->defaultr);
- } else if (!strncmp(key, "FORCED=", key_len)) {
- *dest = info->forced;
- *dest_len = sizeof(info->forced);
- } else if (!strncmp(key, "CHARACTERISTICS=", key_len)) {
- *dest = info->characteristics;
- *dest_len = sizeof(info->characteristics);
- }
- /*
- * ignored:
- * - AUTOSELECT: client may autoselect based on e.g. system language
- * - INSTREAM-ID: EIA-608 closed caption number ("CC1".."CC4")
- */
-}
-
-/* used by parse_playlist to allocate a new variant+playlist when the
- * playlist is detected to be a Media Playlist (not Master Playlist)
- * and we have no parent Master Playlist (parsing of which would have
- * allocated the variant and playlist already)
- * *pls == NULL => Master Playlist or parentless Media Playlist
- * *pls != NULL => parented Media Playlist, playlist+variant allocated */
-static int ensure_playlist(HLSContext *c, struct playlist **pls, const char *url)
-{
- if (*pls)
- return 0;
- if (!new_variant(c, NULL, url, NULL))
- return AVERROR(ENOMEM);
- *pls = c->playlists[c->n_playlists - 1];
- return 0;
-}
-
-static int open_in(HLSContext *c, AVIOContext **in, const char *url)
-{
- AVDictionary *tmp = NULL;
- int ret;
-
- av_dict_copy(&tmp, c->avio_opts, 0);
-
- ret = avio_open2(in, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp);
-
- av_dict_free(&tmp);
- return ret;
-}
-
-static int url_connect(struct playlist *pls, AVDictionary *opts, AVDictionary *opts2)
-{
- AVDictionary *tmp = NULL;
- int ret;
-
- av_dict_copy(&tmp, opts, 0);
- av_dict_copy(&tmp, opts2, 0);
-
- if ((ret = ffurl_connect(pls->input, &tmp)) < 0) {
- ffurl_close(pls->input);
- pls->input = NULL;
- }
-
- av_dict_free(&tmp);
- return ret;
-}
-
-static void update_options(char **dest, const char *name, void *src)
-{
- av_freep(dest);
- av_opt_get(src, name, 0, (uint8_t**)dest);
- if (*dest && !strlen(*dest))
- av_freep(dest);
-}
-
-static int open_url(HLSContext *c, URLContext **uc, const char *url, AVDictionary *opts)
-{
- AVDictionary *tmp = NULL;
- int ret;
- const char *proto_name = avio_find_protocol_name(url);
-
- if (!proto_name)
- return AVERROR_INVALIDDATA;
-
- // only http(s) & file are allowed
- if (!av_strstart(proto_name, "http", NULL) && !av_strstart(proto_name, "file", NULL))
- return AVERROR_INVALIDDATA;
- if (!strncmp(proto_name, url, strlen(proto_name)) && url[strlen(proto_name)] == ':')
- ;
- else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5))
- return AVERROR_INVALIDDATA;
-
- av_dict_copy(&tmp, c->avio_opts, 0);
- av_dict_copy(&tmp, opts, 0);
-
- ret = ffurl_open(uc, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp);
- if( ret >= 0) {
- // update cookies on http response with setcookies.
- URLContext *u = *uc;
- update_options(&c->cookies, "cookies", u->priv_data);
- av_dict_set(&opts, "cookies", c->cookies, 0);
- }
-
- av_dict_free(&tmp);
-
- return ret;
-}
-
-static int parse_playlist(HLSContext *c, const char *url,
- struct playlist *pls, AVIOContext *in)
-{
- int ret = 0, is_segment = 0, is_variant = 0;
- int64_t duration = 0;
- enum KeyType key_type = KEY_NONE;
- uint8_t iv[16] = "";
- int has_iv = 0;
- char key[MAX_URL_SIZE] = "";
- char line[MAX_URL_SIZE];
- const char *ptr;
- int close_in = 0;
- int64_t seg_offset = 0;
- int64_t seg_size = -1;
- uint8_t *new_url = NULL;
- struct variant_info variant_info;
- char tmp_str[MAX_URL_SIZE];
- struct segment *cur_init_section = NULL;
-
- if (!in) {
-#if 1
- AVDictionary *opts = NULL;
- close_in = 1;
- /* Some HLS servers don't like being sent the range header */
- av_dict_set(&opts, "seekable", "0", 0);
-
- // broker prior HTTP options that should be consistent across requests
- av_dict_set(&opts, "user-agent", c->user_agent, 0);
- av_dict_set(&opts, "cookies", c->cookies, 0);
- av_dict_set(&opts, "headers", c->headers, 0);
-
- ret = avio_open2(&in, url, AVIO_FLAG_READ,
- c->interrupt_callback, &opts);
- av_dict_free(&opts);
- if (ret < 0)
- return ret;
-#else
- ret = open_in(c, &in, url);
- if (ret < 0)
- return ret;
- close_in = 1;
-#endif
- }
-
- if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0)
- url = new_url;
-
- read_chomp_line(in, line, sizeof(line));
- if (strcmp(line, "#EXTM3U")) {
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
-
- if (pls) {
- free_segment_list(pls);
- pls->finished = 0;
- pls->type = PLS_TYPE_UNSPECIFIED;
- }
- while (!avio_feof(in)) {
- read_chomp_line(in, line, sizeof(line));
- if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
- is_variant = 1;
- memset(&variant_info, 0, sizeof(variant_info));
- ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
- &variant_info);
- } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) {
- struct key_info info = {{0}};
- ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_key_args,
- &info);
- key_type = KEY_NONE;
- has_iv = 0;
- if (!strcmp(info.method, "AES-128"))
- key_type = KEY_AES_128;
- if (!strcmp(info.method, "SAMPLE-AES"))
- key_type = KEY_SAMPLE_AES;
- if (!strncmp(info.iv, "0x", 2) || !strncmp(info.iv, "0X", 2)) {
- ff_hex_to_data(iv, info.iv + 2);
- has_iv = 1;
- }
- av_strlcpy(key, info.uri, sizeof(key));
- } else if (av_strstart(line, "#EXT-X-MEDIA:", &ptr)) {
- struct rendition_info info = {{0}};
- ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_rendition_args,
- &info);
- new_rendition(c, &info, url);
- } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
- ret = ensure_playlist(c, &pls, url);
- if (ret < 0)
- goto fail;
- pls->target_duration = atoi(ptr) * AV_TIME_BASE;
- } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
- ret = ensure_playlist(c, &pls, url);
- if (ret < 0)
- goto fail;
- pls->start_seq_no = atoi(ptr);
- } else if (av_strstart(line, "#EXT-X-PLAYLIST-TYPE:", &ptr)) {
- ret = ensure_playlist(c, &pls, url);
- if (ret < 0)
- goto fail;
- if (!strcmp(ptr, "EVENT"))
- pls->type = PLS_TYPE_EVENT;
- else if (!strcmp(ptr, "VOD"))
- pls->type = PLS_TYPE_VOD;
- } else if (av_strstart(line, "#EXT-X-MAP:", &ptr)) {
- struct init_section_info info = {{0}};
- ret = ensure_playlist(c, &pls, url);
- if (ret < 0)
- goto fail;
- ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_init_section_args,
- &info);
- cur_init_section = new_init_section(pls, &info, url);
- } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
- if (pls)
- pls->finished = 1;
- } else if (av_strstart(line, "#EXTINF:", &ptr)) {
- is_segment = 1;
- duration = atof(ptr) * AV_TIME_BASE;
- } else if (av_strstart(line, "#EXT-X-BYTERANGE:", &ptr)) {
- seg_size = atoi(ptr);
- ptr = strchr(ptr, '@');
- if (ptr)
- seg_offset = atoi(ptr+1);
- } else if (av_strstart(line, "#", NULL)) {
- continue;
- } else if (line[0]) {
- if (is_variant) {
- if (!new_variant(c, &variant_info, line, url)) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- is_variant = 0;
- }
- if (is_segment) {
- struct segment *seg;
- if (!pls) {
- if (!new_variant(c, 0, url, NULL)) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- pls = c->playlists[c->n_playlists - 1];
- }
- seg = av_malloc(sizeof(struct segment));
- if (!seg) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- seg->duration = duration;
- seg->key_type = key_type;
- if (has_iv) {
- memcpy(seg->iv, iv, sizeof(iv));
- } else {
- int seq = pls->start_seq_no + pls->n_segments;
- memset(seg->iv, 0, sizeof(seg->iv));
- AV_WB32(seg->iv + 12, seq);
- }
-
- if (key_type != KEY_NONE) {
- ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, key);
- seg->key = av_strdup(tmp_str);
- if (!seg->key) {
- av_free(seg);
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- } else {
- seg->key = NULL;
- }
-
- ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, line);
- seg->url = av_strdup(tmp_str);
- if (!seg->url) {
- av_free(seg->key);
- av_free(seg);
- ret = AVERROR(ENOMEM);
- goto fail;
- }
-
- dynarray_add(&pls->segments, &pls->n_segments, seg);
- is_segment = 0;
-
- seg->size = seg_size;
- if (seg_size >= 0) {
- seg->url_offset = seg_offset;
- seg_offset += seg_size;
- seg_size = -1;
- } else {
- seg->url_offset = 0;
- seg_offset = 0;
- }
-
- seg->init_section = cur_init_section;
- }
- }
- }
- if (pls)
- pls->last_load_time = av_gettime_relative();
-
-fail:
- av_free(new_url);
- if (close_in)
- avio_close(in);
- return ret;
-}
-
-static struct segment *current_segment(struct playlist *pls)
-{
- return pls->segments[pls->cur_seq_no - pls->start_seq_no];
-}
-
-enum ReadFromURLMode {
- READ_NORMAL,
- READ_COMPLETE,
-};
-
-/* read from URLContext, limiting read to current segment */
-static int read_from_url(struct playlist *pls, struct segment *seg,
- uint8_t *buf, int buf_size,
- enum ReadFromURLMode mode)
-{
- int ret;
-
- /* limit read if the segment was only a part of a file */
- if (seg->size >= 0)
- buf_size = FFMIN(buf_size, seg->size - pls->cur_seg_offset);
-
- if (mode == READ_COMPLETE)
- ret = ffurl_read_complete(pls->input, buf, buf_size);
- else
- ret = ffurl_read(pls->input, buf, buf_size);
-
- if (ret > 0)
- pls->cur_seg_offset += ret;
-
- return ret;
-}
-
-/* Parse the raw ID3 data and pass contents to caller */
-static void parse_id3(AVFormatContext *s, AVIOContext *pb,
- AVDictionary **metadata, int64_t *dts,
- ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta)
-{
- static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp";
- ID3v2ExtraMeta *meta;
-
- ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta);
- for (meta = *extra_meta; meta; meta = meta->next) {
- if (!strcmp(meta->tag, "PRIV")) {
- ID3v2ExtraMetaPRIV *priv = meta->data;
- if (priv->datasize == 8 && !strcmp(priv->owner, id3_priv_owner_ts)) {
- /* 33-bit MPEG timestamp */
- int64_t ts = AV_RB64(priv->data);
- av_log(s, AV_LOG_DEBUG, "HLS ID3 audio timestamp %"PRId64"\n", ts);
- if ((ts & ~((1ULL << 33) - 1)) == 0)
- *dts = ts;
- else
- av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts);
- }
- } else if (!strcmp(meta->tag, "APIC") && apic)
- *apic = meta->data;
- }
-}
-
-/* Check if the ID3 metadata contents have changed */
-static int id3_has_changed_values(struct playlist *pls, AVDictionary *metadata,
- ID3v2ExtraMetaAPIC *apic)
-{
- AVDictionaryEntry *entry = NULL;
- AVDictionaryEntry *oldentry;
- /* check that no keys have changed values */
- while ((entry = av_dict_get(metadata, "", entry, AV_DICT_IGNORE_SUFFIX))) {
- oldentry = av_dict_get(pls->id3_initial, entry->key, NULL, AV_DICT_MATCH_CASE);
- if (!oldentry || strcmp(oldentry->value, entry->value) != 0)
- return 1;
- }
-
- /* check if apic appeared */
- if (apic && (pls->ctx->nb_streams != 2 || !pls->ctx->streams[1]->attached_pic.data))
- return 1;
-
- if (apic) {
- int size = pls->ctx->streams[1]->attached_pic.size;
- if (size != apic->buf->size - AV_INPUT_BUFFER_PADDING_SIZE)
- return 1;
-
- if (memcmp(apic->buf->data, pls->ctx->streams[1]->attached_pic.data, size) != 0)
- return 1;
- }
-
- return 0;
-}
-
-/* Parse ID3 data and handle the found data */
-static void handle_id3(AVIOContext *pb, struct playlist *pls)
-{
- AVDictionary *metadata = NULL;
- ID3v2ExtraMetaAPIC *apic = NULL;
- ID3v2ExtraMeta *extra_meta = NULL;
- int64_t timestamp = AV_NOPTS_VALUE;
-
- parse_id3(pls->ctx, pb, &metadata, ×tamp, &apic, &extra_meta);
-
- if (timestamp != AV_NOPTS_VALUE) {
- pls->id3_mpegts_timestamp = timestamp;
- pls->id3_offset = 0;
- }
-
- if (!pls->id3_found) {
- /* initial ID3 tags */
- av_assert0(!pls->id3_deferred_extra);
- pls->id3_found = 1;
-
- /* get picture attachment and set text metadata */
- if (pls->ctx->nb_streams)
- ff_id3v2_parse_apic(pls->ctx, &extra_meta);
- else
- /* demuxer not yet opened, defer picture attachment */
- pls->id3_deferred_extra = extra_meta;
-
- av_dict_copy(&pls->ctx->metadata, metadata, 0);
- pls->id3_initial = metadata;
-
- } else {
- if (!pls->id3_changed && id3_has_changed_values(pls, metadata, apic)) {
- avpriv_report_missing_feature(pls->ctx, "Changing ID3 metadata in HLS audio elementary stream");
- pls->id3_changed = 1;
- }
- av_dict_free(&metadata);
- }
-
- if (!pls->id3_deferred_extra)
- ff_id3v2_free_extra_meta(&extra_meta);
-}
-
-/* Intercept and handle ID3 tags between URLContext and AVIOContext */
-static void intercept_id3(struct playlist *pls, uint8_t *buf,
- int buf_size, int *len)
-{
- /* intercept id3 tags, we do not want to pass them to the raw
- * demuxer on all segment switches */
- int bytes;
- int id3_buf_pos = 0;
- int fill_buf = 0;
- struct segment *seg = current_segment(pls);
-
- /* gather all the id3 tags */
- while (1) {
- /* see if we can retrieve enough data for ID3 header */
- if (*len < ID3v2_HEADER_SIZE && buf_size >= ID3v2_HEADER_SIZE) {
- bytes = read_from_url(pls, seg, buf + *len, ID3v2_HEADER_SIZE - *len, READ_COMPLETE);
- if (bytes > 0) {
-
- if (bytes == ID3v2_HEADER_SIZE - *len)
- /* no EOF yet, so fill the caller buffer again after
- * we have stripped the ID3 tags */
- fill_buf = 1;
-
- *len += bytes;
-
- } else if (*len <= 0) {
- /* error/EOF */
- *len = bytes;
- fill_buf = 0;
- }
- }
-
- if (*len < ID3v2_HEADER_SIZE)
- break;
-
- if (ff_id3v2_match(buf, ID3v2_DEFAULT_MAGIC)) {
- int64_t maxsize = seg->size >= 0 ? seg->size : 1024*1024;
- int taglen = ff_id3v2_tag_len(buf);
- int tag_got_bytes = FFMIN(taglen, *len);
- int remaining = taglen - tag_got_bytes;
-
- if (taglen > maxsize) {
- av_log(pls->ctx, AV_LOG_ERROR, "Too large HLS ID3 tag (%d > %"PRId64" bytes)\n",
- taglen, maxsize);
- break;
- }
-
- /*
- * Copy the id3 tag to our temporary id3 buffer.
- * We could read a small id3 tag directly without memcpy, but
- * we would still need to copy the large tags, and handling
- * both of those cases together with the possibility for multiple
- * tags would make the handling a bit complex.
- */
- pls->id3_buf = av_fast_realloc(pls->id3_buf, &pls->id3_buf_size, id3_buf_pos + taglen);
- if (!pls->id3_buf)
- break;
- memcpy(pls->id3_buf + id3_buf_pos, buf, tag_got_bytes);
- id3_buf_pos += tag_got_bytes;
-
- /* strip the intercepted bytes */
- *len -= tag_got_bytes;
- memmove(buf, buf + tag_got_bytes, *len);
- av_log(pls->ctx, AV_LOG_DEBUG, "Stripped %d HLS ID3 bytes\n", tag_got_bytes);
-
- if (remaining > 0) {
- /* read the rest of the tag in */
- if (read_from_url(pls, seg, pls->id3_buf + id3_buf_pos, remaining, READ_COMPLETE) != remaining)
- break;
- id3_buf_pos += remaining;
- av_log(pls->ctx, AV_LOG_DEBUG, "Stripped additional %d HLS ID3 bytes\n", remaining);
- }
-
- } else {
- /* no more ID3 tags */
- break;
- }
- }
-
- /* re-fill buffer for the caller unless EOF */
- if (*len >= 0 && (fill_buf || *len == 0)) {
- bytes = read_from_url(pls, seg, buf + *len, buf_size - *len, READ_NORMAL);
-
- /* ignore error if we already had some data */
- if (bytes >= 0)
- *len += bytes;
- else if (*len == 0)
- *len = bytes;
- }
-
- if (pls->id3_buf) {
- /* Now parse all the ID3 tags */
- AVIOContext id3ioctx;
- ffio_init_context(&id3ioctx, pls->id3_buf, id3_buf_pos, 0, NULL, NULL, NULL, NULL);
- handle_id3(&id3ioctx, pls);
- }
-
- if (pls->is_id3_timestamped == -1)
- pls->is_id3_timestamped = (pls->id3_mpegts_timestamp != AV_NOPTS_VALUE);
-}
-
-static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg)
-{
- AVDictionary *opts = NULL;
- int ret;
-
- // broker prior HTTP options that should be consistent across requests
- av_dict_set(&opts, "user-agent", c->user_agent, 0);
- av_dict_set(&opts, "cookies", c->cookies, 0);
- av_dict_set(&opts, "headers", c->headers, 0);
- av_dict_set(&opts, "seekable", "0", 0);
-
- if (seg->size >= 0) {
- /* try to restrict the HTTP request to the part we want
- * (if this is in fact a HTTP request) */
- av_dict_set_int(&opts, "offset", seg->url_offset, 0);
- av_dict_set_int(&opts, "end_offset", seg->url_offset + seg->size, 0);
- }
-
- av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %"PRId64", playlist %d\n",
- seg->url, seg->url_offset, pls->index);
-
- if (seg->key_type == KEY_NONE) {
- ret = open_url(pls->parent->priv_data, &pls->input, seg->url, opts);
- } else if (seg->key_type == KEY_AES_128) {
-// HLSContext *c = var->parent->priv_data;
- char iv[33], key[33], url[MAX_URL_SIZE];
- if (strcmp(seg->key, pls->key_url)) {
- URLContext *uc;
- if (open_url(pls->parent->priv_data, &uc, seg->key, opts) == 0) {
- if (ffurl_read_complete(uc, pls->key, sizeof(pls->key))
- != sizeof(pls->key)) {
- av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
- seg->key);
- }
- ffurl_close(uc);
- } else {
- av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n",
- seg->key);
- }
- av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
- }
- ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);
- ff_data_to_hex(key, pls->key, sizeof(pls->key), 0);
- iv[32] = key[32] = '\0';
- if (strstr(seg->url, "://"))
- snprintf(url, sizeof(url), "crypto+%s", seg->url);
- else
- snprintf(url, sizeof(url), "crypto:%s", seg->url);
-
- if ((ret = ffurl_alloc(&pls->input, url, AVIO_FLAG_READ,
- &pls->parent->interrupt_callback)) < 0)
- goto cleanup;
- av_opt_set(pls->input->priv_data, "key", key, 0);
- av_opt_set(pls->input->priv_data, "iv", iv, 0);
-
- if ((ret = url_connect(pls, c->avio_opts, opts)) < 0) {
- goto cleanup;
- }
- ret = 0;
- } else if (seg->key_type == KEY_SAMPLE_AES) {
- av_log(pls->parent, AV_LOG_ERROR,
- "SAMPLE-AES encryption is not supported yet\n");
- ret = AVERROR_PATCHWELCOME;
- }
- else
- ret = AVERROR(ENOSYS);
-
- /* Seek to the requested position. If this was a HTTP request, the offset
- * should already be where want it to, but this allows e.g. local testing
- * without a HTTP server. */
- if (ret == 0 && seg->key_type == KEY_NONE && seg->url_offset) {
- int seekret = ffurl_seek(pls->input, 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);
- ret = seekret;
- ffurl_close(pls->input);
- pls->input = NULL;
- }
- }
-
-cleanup:
- av_dict_free(&opts);
- pls->cur_seg_offset = 0;
- return ret;
-}
-
-static int update_init_section(struct playlist *pls, struct segment *seg)
-{
- static const int max_init_section_size = 1024*1024;
- HLSContext *c = pls->parent->priv_data;
- int64_t sec_size;
- int64_t urlsize;
- int ret;
-
- if (seg->init_section == pls->cur_init_section)
- return 0;
-
- pls->cur_init_section = NULL;
-
- if (!seg->init_section)
- return 0;
-
- /* this will clobber playlist URLContext stuff, so this should be
- * called between segments only */
- ret = open_input(c, pls, seg->init_section);
- if (ret < 0) {
- av_log(pls->parent, AV_LOG_WARNING,
- "Failed to open an initialization section in playlist %d\n",
- pls->index);
- return ret;
- }
-
- if (seg->init_section->size >= 0)
- sec_size = seg->init_section->size;
- else if ((urlsize = ffurl_size(pls->input)) >= 0)
- sec_size = urlsize;
- else
- sec_size = max_init_section_size;
-
- av_log(pls->parent, AV_LOG_DEBUG,
- "Downloading an initialization section of size %"PRId64"\n",
- sec_size);
-
- sec_size = FFMIN(sec_size, max_init_section_size);
-
- av_fast_malloc(&pls->init_sec_buf, &pls->init_sec_buf_size, sec_size);
-
- ret = read_from_url(pls, seg->init_section, pls->init_sec_buf,
- pls->init_sec_buf_size, READ_COMPLETE);
- ffurl_close(pls->input);
- pls->input = NULL;
-
- if (ret < 0)
- return ret;
-
- pls->cur_init_section = seg->init_section;
- pls->init_sec_data_len = ret;
- pls->init_sec_buf_read_offset = 0;
-
- /* spec says audio elementary streams do not have media initialization
- * sections, so there should be no ID3 timestamps */
- pls->is_id3_timestamped = 0;
-
- return 0;
-}
-
-static int64_t default_reload_interval(struct playlist *pls)
-{
- return pls->n_segments > 0 ?
- pls->segments[pls->n_segments - 1]->duration :
- pls->target_duration;
-}
-
-static int read_data(void *opaque, uint8_t *buf, int buf_size)
-{
- struct playlist *v = opaque;
- HLSContext *c = v->parent->priv_data;
- int ret, i;
- int just_opened = 0;
-
-restart:
- if (!v->needed)
- return AVERROR_EOF;
-
- if (!v->input) {
- int64_t reload_interval;
- struct segment *seg;
-
- /* Check that the playlist is still needed before opening a new
- * segment. */
- if (v->ctx && v->ctx->nb_streams &&
- v->parent->nb_streams >= v->stream_offset + v->ctx->nb_streams) {
- v->needed = 0;
- for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
- i++) {
- if (v->parent->streams[i]->discard < AVDISCARD_ALL)
- v->needed = 1;
- }
- }
- if (!v->needed) {
- av_log(v->parent, AV_LOG_INFO, "No longer receiving playlist %d\n",
- v->index);
- return AVERROR_EOF;
- }
-
- /* If this is a live stream and the reload interval has elapsed since
- * the last playlist reload, reload the playlists now. */
- reload_interval = default_reload_interval(v);
-
-reload:
- if (!v->finished &&
- av_gettime_relative() - v->last_load_time >= reload_interval) {
- if ((ret = parse_playlist(c, v->url, v, NULL)) < 0) {
- av_log(v->parent, AV_LOG_WARNING, "Failed to reload playlist %d\n",
- v->index);
- return ret;
- }
- /* If we need to reload the playlist again below (if
- * there's still no more segments), switch to a reload
- * interval of half the target duration. */
- reload_interval = v->target_duration / 2;
- }
- if (v->cur_seq_no < v->start_seq_no) {
- av_log(NULL, AV_LOG_WARNING,
- "skipping %d segments ahead, expired from playlists\n",
- v->start_seq_no - v->cur_seq_no);
- v->cur_seq_no = v->start_seq_no;
- }
- if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
- if (v->finished)
- return AVERROR_EOF;
- while (av_gettime_relative() - v->last_load_time < reload_interval) {
- if (ff_check_interrupt(c->interrupt_callback))
- return AVERROR_EXIT;
- av_usleep(100*1000);
- }
- /* Enough time has elapsed since the last reload */
- goto reload;
- }
-
- seg = current_segment(v);
-
- /* load/update Media Initialization Section, if any */
- ret = update_init_section(v, seg);
- if (ret)
- return ret;
-
- ret = open_input(c, v, seg);
- if (ret < 0) {
- if (ff_check_interrupt(c->interrupt_callback))
- return AVERROR_EXIT;
- av_log(v->parent, AV_LOG_WARNING, "Failed to open segment of playlist %d\n",
- v->index);
- v->cur_seq_no += 1;
- goto reload;
- }
- just_opened = 1;
- }
-
- if (v->init_sec_buf_read_offset < v->init_sec_data_len) {
- /* Push init section out first before first actual segment */
- int copy_size = FFMIN(v->init_sec_data_len - v->init_sec_buf_read_offset, buf_size);
- memcpy(buf, v->init_sec_buf, copy_size);
- v->init_sec_buf_read_offset += copy_size;
- return copy_size;
- }
-
- ret = read_from_url(v, current_segment(v), buf, buf_size, READ_NORMAL);
- if (ret > 0) {
- if (just_opened && v->is_id3_timestamped != 0) {
- /* Intercept ID3 tags here, elementary audio streams are required
- * to convey timestamps using them in the beginning of each segment. */
- intercept_id3(v, buf, buf_size, &ret);
- }
-
- return ret;
- }
- ffurl_close(v->input);
- v->input = NULL;
- v->cur_seq_no++;
-
- c->cur_seq_no = v->cur_seq_no;
-
- goto restart;
-}
-
-static int playlist_in_multiple_variants(HLSContext *c, struct playlist *pls)
-{
- int variant_count = 0;
- int i, j;
-
- for (i = 0; i < c->n_variants && variant_count < 2; i++) {
- struct variant *v = c->variants[i];
-
- for (j = 0; j < v->n_playlists; j++) {
- if (v->playlists[j] == pls) {
- variant_count++;
- break;
- }
- }
- }
-
- return variant_count >= 2;
-}
-
-static void add_renditions_to_variant(HLSContext *c, struct variant *var,
- enum AVMediaType type, const char *group_id)
-{
- int i;
-
- for (i = 0; i < c->n_renditions; i++) {
- struct rendition *rend = c->renditions[i];
-
- if (rend->type == type && !strcmp(rend->group_id, group_id)) {
-
- if (rend->playlist)
- /* rendition is an external playlist
- * => add the playlist to the variant */
- dynarray_add(&var->playlists, &var->n_playlists, rend->playlist);
- else
- /* rendition is part of the variant main Media Playlist
- * => add the rendition to the main Media Playlist */
- dynarray_add(&var->playlists[0]->renditions,
- &var->playlists[0]->n_renditions,
- rend);
- }
- }
-}
-
-static void add_metadata_from_renditions(AVFormatContext *s, struct playlist *pls,
- enum AVMediaType type)
-{
- int rend_idx = 0;
- int i;
-
- for (i = 0; i < pls->ctx->nb_streams; i++) {
- AVStream *st = s->streams[pls->stream_offset + i];
-
- if (st->codec->codec_type != type)
- continue;
-
- for (; rend_idx < pls->n_renditions; rend_idx++) {
- struct rendition *rend = pls->renditions[rend_idx];
-
- if (rend->type != type)
- continue;
-
- if (rend->language[0])
- av_dict_set(&st->metadata, "language", rend->language, 0);
- if (rend->name[0])
- av_dict_set(&st->metadata, "comment", rend->name, 0);
-
- st->disposition |= rend->disposition;
- }
- if (rend_idx >=pls->n_renditions)
- break;
- }
-}
-
-/* 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)
-{
- int i;
- int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
- 0 : c->first_timestamp;
-
- if (timestamp < pos) {
- *seq_no = pls->start_seq_no;
- return 0;
- }
-
- for (i = 0; i < pls->n_segments; i++) {
- int64_t diff = pos + pls->segments[i]->duration - timestamp;
- if (diff > 0) {
- *seq_no = pls->start_seq_no + i;
- return 1;
- }
- pos += pls->segments[i]->duration;
- }
-
- *seq_no = pls->start_seq_no + pls->n_segments - 1;
-
- return 0;
-}
-
-static int select_cur_seq_no(HLSContext *c, struct playlist *pls)
-{
- int seq_no;
-
- if (!pls->finished && !c->first_packet &&
- av_gettime_relative() - pls->last_load_time >= default_reload_interval(pls))
- /* reload the playlist since it was suspended */
- parse_playlist(c, pls->url, pls, NULL);
-
- /* If playback is already in progress (we are just selecting a new
- * playlist) and this is a complete file, find the matching segment
- * by counting durations. */
- if (pls->finished && c->cur_timestamp != AV_NOPTS_VALUE) {
- find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no);
- return seq_no;
- }
-
- if (!pls->finished) {
- if (!c->first_packet && /* we are doing a segment selection during playback */
- c->cur_seq_no >= pls->start_seq_no &&
- c->cur_seq_no < pls->start_seq_no + pls->n_segments)
- /* While spec 3.4.3 says that we cannot assume anything about the
- * content at the same sequence number on different playlists,
- * in practice this seems to work and doing it otherwise would
- * require us to download a segment to inspect its timestamps. */
- return c->cur_seq_no;
-
- /* If this is a live stream, start live_start_index segments from the
- * start or end */
- if (c->live_start_index < 0)
- return pls->start_seq_no + FFMAX(pls->n_segments + c->live_start_index, 0);
- else
- return pls->start_seq_no + FFMIN(c->live_start_index, pls->n_segments - 1);
- }
-
- /* Otherwise just start on the first segment. */
- return pls->start_seq_no;
-}
-
-static int save_avio_options(AVFormatContext *s)
-{
- HLSContext *c = s->priv_data;
- const char *opts[] = { "headers", "user_agent", "user-agent", "cookies", NULL }, **opt = opts;
- uint8_t *buf;
- int ret = 0;
-
- while (*opt) {
- if (av_opt_get(s->pb, *opt, AV_OPT_SEARCH_CHILDREN, &buf) >= 0) {
- ret = av_dict_set(&c->avio_opts, *opt, buf,
- AV_DICT_DONT_STRDUP_VAL);
- if (ret < 0)
- return ret;
- }
- opt++;
- }
-
- return ret;
-}
-
-static int hls_read_header(AVFormatContext *s)
-{
- URLContext *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb->opaque;
- HLSContext *c = s->priv_data;
- int ret = 0, i, j, stream_offset = 0;
-
- c->interrupt_callback = &s->interrupt_callback;
-
- c->first_packet = 1;
- c->first_timestamp = AV_NOPTS_VALUE;
- c->cur_timestamp = AV_NOPTS_VALUE;
-
- // if the URL context is good, read important options we must broker later
- if (u && u->prot->priv_data_class) {
- // get the previous user agent & set back to null if string size is zero
- update_options(&c->user_agent, "user-agent", u->priv_data);
-
- // get the previous cookies & set back to null if string size is zero
- update_options(&c->cookies, "cookies", u->priv_data);
-
- // get the previous headers & set back to null if string size is zero
- update_options(&c->headers, "headers", u->priv_data);
- }
-
- if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
- goto fail;
-
- if ((ret = save_avio_options(s)) < 0)
- goto fail;
-
- /* Some HLS servers don't like being sent the range header */
- av_dict_set(&c->avio_opts, "seekable", "0", 0);
-
- if (c->n_variants == 0) {
- av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
- ret = AVERROR_EOF;
- goto fail;
- }
- /* If the playlist only contained playlists (Master Playlist),
- * parse each individual playlist. */
- if (c->n_playlists > 1 || c->playlists[0]->n_segments == 0) {
- for (i = 0; i < c->n_playlists; i++) {
- struct playlist *pls = c->playlists[i];
- if ((ret = parse_playlist(c, pls->url, pls, NULL)) < 0)
- goto fail;
- }
- }
-
- if (c->variants[0]->playlists[0]->n_segments == 0) {
- av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
- ret = AVERROR_EOF;
- goto fail;
- }
-
- /* If this isn't a live stream, calculate the total duration of the
- * stream. */
- if (c->variants[0]->playlists[0]->finished) {
- int64_t duration = 0;
- for (i = 0; i < c->variants[0]->playlists[0]->n_segments; i++)
- duration += c->variants[0]->playlists[0]->segments[i]->duration;
- s->duration = duration;
- }
-
- /* Associate renditions with variants */
- for (i = 0; i < c->n_variants; i++) {
- struct variant *var = c->variants[i];
-
- if (var->audio_group[0])
- add_renditions_to_variant(c, var, AVMEDIA_TYPE_AUDIO, var->audio_group);
- if (var->video_group[0])
- add_renditions_to_variant(c, var, AVMEDIA_TYPE_VIDEO, var->video_group);
- if (var->subtitles_group[0])
- add_renditions_to_variant(c, var, AVMEDIA_TYPE_SUBTITLE, var->subtitles_group);
- }
-
- /* Open the demuxer for each playlist */
- for (i = 0; i < c->n_playlists; i++) {
- struct playlist *pls = c->playlists[i];
- AVInputFormat *in_fmt = NULL;
-
- if (!(pls->ctx = avformat_alloc_context())) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
-
- if (pls->n_segments == 0)
- continue;
-
- pls->index = i;
- pls->needed = 1;
- pls->parent = s;
- pls->cur_seq_no = select_cur_seq_no(c, pls);
-
- pls->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
- if (!pls->read_buffer){
- ret = AVERROR(ENOMEM);
- avformat_free_context(pls->ctx);
- pls->ctx = NULL;
- goto fail;
- }
- ffio_init_context(&pls->pb, pls->read_buffer, INITIAL_BUFFER_SIZE, 0, pls,
- read_data, NULL, NULL);
- pls->pb.seekable = 0;
- ret = av_probe_input_buffer(&pls->pb, &in_fmt, pls->segments[0]->url,
- NULL, 0, 0);
- 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);
- avformat_free_context(pls->ctx);
- pls->ctx = NULL;
- goto fail;
- }
- pls->ctx->pb = &pls->pb;
- pls->stream_offset = stream_offset;
-
- if ((ret = ff_copy_whitelists(pls->ctx, s)) < 0)
- goto fail;
-
- ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, NULL);
- if (ret < 0)
- goto fail;
-
- if (pls->id3_deferred_extra && pls->ctx->nb_streams == 1) {
- ff_id3v2_parse_apic(pls->ctx, &pls->id3_deferred_extra);
- avformat_queue_attached_pictures(pls->ctx);
- ff_id3v2_free_extra_meta(&pls->id3_deferred_extra);
- pls->id3_deferred_extra = NULL;
- }
-
- pls->ctx->ctx_flags &= ~AVFMTCTX_NOHEADER;
- ret = avformat_find_stream_info(pls->ctx, NULL);
- if (ret < 0)
- goto fail;
-
- if (pls->is_id3_timestamped == -1)
- av_log(s, AV_LOG_WARNING, "No expected HTTP requests have been made\n");
-
- /* Create new AVStreams for each stream in this playlist */
- for (j = 0; j < pls->ctx->nb_streams; j++) {
- AVStream *st = avformat_new_stream(s, NULL);
- AVStream *ist = pls->ctx->streams[j];
- if (!st) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- st->id = i;
-
- avcodec_copy_context(st->codec, pls->ctx->streams[j]->codec);
-
- if (pls->is_id3_timestamped) /* custom timestamps via id3 */
- avpriv_set_pts_info(st, 33, 1, MPEG_TIME_BASE);
- else
- avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den);
- }
-
- add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_AUDIO);
- add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_VIDEO);
- add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_SUBTITLE);
-
- stream_offset += pls->ctx->nb_streams;
- }
-
- /* Create a program for each variant */
- for (i = 0; i < c->n_variants; i++) {
- struct variant *v = c->variants[i];
- AVProgram *program;
-
- program = av_new_program(s, i);
- if (!program)
- goto fail;
- av_dict_set_int(&program->metadata, "variant_bitrate", v->bandwidth, 0);
-
- for (j = 0; j < v->n_playlists; j++) {
- struct playlist *pls = v->playlists[j];
- int is_shared = playlist_in_multiple_variants(c, pls);
- int k;
-
- for (k = 0; k < pls->ctx->nb_streams; k++) {
- struct AVStream *st = s->streams[pls->stream_offset + k];
-
- ff_program_add_stream_index(s, i, pls->stream_offset + k);
-
- /* Set variant_bitrate for streams unique to this variant */
- if (!is_shared && v->bandwidth)
- av_dict_set_int(&st->metadata, "variant_bitrate", v->bandwidth, 0);
- }
- }
- }
-
- return 0;
-fail:
- free_playlist_list(c);
- free_variant_list(c);
- free_rendition_list(c);
- return ret;
-}
-
-static int recheck_discard_flags(AVFormatContext *s, int first)
-{
- HLSContext *c = s->priv_data;
- int i, changed = 0;
-
- /* Check if any new streams are needed */
- for (i = 0; i < c->n_playlists; i++)
- c->playlists[i]->cur_needed = 0;
-
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st = s->streams[i];
- struct playlist *pls = c->playlists[s->streams[i]->id];
- if (st->discard < AVDISCARD_ALL)
- pls->cur_needed = 1;
- }
- for (i = 0; i < c->n_playlists; i++) {
- struct playlist *pls = c->playlists[i];
- if (pls->cur_needed && !pls->needed) {
- pls->needed = 1;
- changed = 1;
- pls->cur_seq_no = select_cur_seq_no(c, pls);
- pls->pb.eof_reached = 0;
- if (c->cur_timestamp != AV_NOPTS_VALUE) {
- /* catch up */
- pls->seek_timestamp = c->cur_timestamp;
- 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);
- } else if (first && !pls->cur_needed && pls->needed) {
- if (pls->input)
- ffurl_close(pls->input);
- pls->input = NULL;
- pls->needed = 0;
- changed = 1;
- av_log(s, AV_LOG_INFO, "No longer receiving playlist %d\n", i);
- }
- }
- return changed;
-}
-
-static void fill_timing_for_id3_timestamped_stream(struct playlist *pls)
-{
- if (pls->id3_offset >= 0) {
- pls->pkt.dts = pls->id3_mpegts_timestamp +
- av_rescale_q(pls->id3_offset,
- pls->ctx->streams[pls->pkt.stream_index]->time_base,
- MPEG_TIME_BASE_Q);
- 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;
- }
-
- 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;
-}
-
-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;
-}
-
-static int compare_ts_with_wrapdetect(int64_t ts_a, struct playlist *pls_a,
- int64_t ts_b, struct playlist *pls_b)
-{
- int64_t scaled_ts_a = av_rescale_q(ts_a, get_timebase(pls_a), MPEG_TIME_BASE_Q);
- int64_t scaled_ts_b = av_rescale_q(ts_b, get_timebase(pls_b), MPEG_TIME_BASE_Q);
-
- return av_compare_mod(scaled_ts_a, scaled_ts_b, 1LL << 33);
-}
-
-static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
- HLSContext *c = s->priv_data;
- int ret, i, minplaylist = -1;
-
- recheck_discard_flags(s, c->first_packet);
- c->first_packet = 0;
-
- for (i = 0; i < c->n_playlists; i++) {
- 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) {
- while (1) {
- int64_t ts_diff;
- AVRational tb;
- 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) {
- /* 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,
- get_timebase(pls), AV_TIME_BASE_Q);
- }
-
- if (pls->seek_timestamp == AV_NOPTS_VALUE)
- break;
-
- if (pls->seek_stream_index < 0 ||
- pls->seek_stream_index == pls->pkt.stream_index) {
-
- 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,
- 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->seek_timestamp = AV_NOPTS_VALUE;
- break;
- }
- }
- av_free_packet(&pls->pkt);
- reset_packet(&pls->pkt);
- }
- }
- /* Check if this stream has the packet with the lowest dts */
- 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;
-
- if (dts == AV_NOPTS_VALUE ||
- (mindts != AV_NOPTS_VALUE && compare_ts_with_wrapdetect(dts, pls, mindts, minpls) < 0))
- minplaylist = i;
- }
- }
- }
-
- /* If we got a packet, return it */
- if (minplaylist >= 0) {
- struct playlist *pls = c->playlists[minplaylist];
- *pkt = pls->pkt;
- pkt->stream_index += pls->stream_offset;
- reset_packet(&c->playlists[minplaylist]->pkt);
-
- if (pkt->dts != AV_NOPTS_VALUE)
- c->cur_timestamp = av_rescale_q(pkt->dts,
- pls->ctx->streams[pls->pkt.stream_index]->time_base,
- AV_TIME_BASE_Q);
-
- return 0;
- }
- return AVERROR_EOF;
-}
-
-static int hls_close(AVFormatContext *s)
-{
- HLSContext *c = s->priv_data;
-
- free_playlist_list(c);
- free_variant_list(c);
- free_rendition_list(c);
-
- av_dict_free(&c->avio_opts);
-
- return 0;
-}
-
-static int hls_read_seek(AVFormatContext *s, int stream_index,
- int64_t timestamp, int flags)
-{
- HLSContext *c = s->priv_data;
- struct playlist *seek_pls = NULL;
- int i, seq_no;
- int64_t first_timestamp, seek_timestamp, duration;
-
- if ((flags & AVSEEK_FLAG_BYTE) ||
- !(c->variants[0]->playlists[0]->finished || c->variants[0]->playlists[0]->type == PLS_TYPE_EVENT))
- return AVERROR(ENOSYS);
-
- first_timestamp = c->first_timestamp == AV_NOPTS_VALUE ?
- 0 : c->first_timestamp;
-
- seek_timestamp = av_rescale_rnd(timestamp, AV_TIME_BASE,
- s->streams[stream_index]->time_base.den,
- flags & AVSEEK_FLAG_BACKWARD ?
- AV_ROUND_DOWN : AV_ROUND_UP);
-
- duration = s->duration == AV_NOPTS_VALUE ?
- 0 : s->duration;
-
- if (0 < duration && duration < seek_timestamp - first_timestamp)
- return AVERROR(EIO);
-
- /* find the playlist with the specified stream */
- for (i = 0; i < c->n_playlists; i++) {
- struct playlist *pls = c->playlists[i];
- if (stream_index >= pls->stream_offset &&
- stream_index - pls->stream_offset < pls->ctx->nb_streams) {
- seek_pls = pls;
- break;
- }
- }
- /* check if the timestamp is valid for the playlist with the
- * specified stream index */
- if (!seek_pls || !find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no))
- return AVERROR(EIO);
-
- /* set segment now so we do not need to search again below */
- seek_pls->cur_seq_no = seq_no;
- seek_pls->seek_stream_index = stream_index - seek_pls->stream_offset;
-
- for (i = 0; i < c->n_playlists; i++) {
- /* Reset reading */
- struct playlist *pls = c->playlists[i];
- if (pls->input) {
- ffurl_close(pls->input);
- pls->input = NULL;
- }
- av_free_packet(&pls->pkt);
- reset_packet(&pls->pkt);
- pls->pb.eof_reached = 0;
- /* Clear any buffered data */
- pls->pb.buf_end = pls->pb.buf_ptr = pls->pb.buffer;
- /* Reset the pos, to let the mpegts demuxer know we've seeked. */
- pls->pb.pos = 0;
- /* Flush the packet queue of the subdemuxer. */
- ff_read_frame_flush(pls->ctx);
-
- pls->seek_timestamp = seek_timestamp;
- pls->seek_flags = flags;
-
- if (pls != seek_pls) {
- /* set closest segment seq_no for playlists not handled above */
- find_timestamp_in_playlist(c, pls, seek_timestamp, &pls->cur_seq_no);
- /* seek the playlist to the given position without taking
- * keyframes into account since this playlist does not have the
- * specified stream where we should look for the keyframes */
- pls->seek_stream_index = -1;
- pls->seek_flags |= AVSEEK_FLAG_ANY;
- }
- }
-
- c->cur_timestamp = seek_timestamp;
-
- return 0;
-}
-
-static int hls_probe(AVProbeData *p)
-{
- /* Require #EXTM3U at the start, and either one of the ones below
- * somewhere for a proper match. */
- if (strncmp(p->buf, "#EXTM3U", 7))
- return 0;
- if (strstr(p->buf, "#EXT-X-STREAM-INF:") ||
- strstr(p->buf, "#EXT-X-TARGETDURATION:") ||
- strstr(p->buf, "#EXT-X-MEDIA-SEQUENCE:"))
- return AVPROBE_SCORE_MAX;
- return 0;
-}
-
-#define OFFSET(x) offsetof(HLSContext, x)
-#define FLAGS AV_OPT_FLAG_DECODING_PARAM
-static const AVOption hls_options[] = {
- {"live_start_index", "segment index to start live streams at (negative values are from the end)",
- OFFSET(live_start_index), AV_OPT_TYPE_INT, {.i64 = -3}, INT_MIN, INT_MAX, FLAGS},
- {NULL}
-};
-
-static const AVClass hls_class = {
- .class_name = "hls,applehttp",
- .item_name = av_default_item_name,
- .option = hls_options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-AVInputFormat ff_hls_demuxer = {
- .name = "hls,applehttp",
- .long_name = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
- .priv_class = &hls_class,
- .priv_data_size = sizeof(HLSContext),
- .read_probe = hls_probe,
- .read_header = hls_read_header,
- .read_packet = hls_read_packet,
- .read_close = hls_close,
- .read_seek = hls_read_seek,
-};
diff --git a/ffmpeg-2-8-11/libavformat/http.c b/ffmpeg-2-8-11/libavformat/http.c
deleted file mode 100644
index d2e9ae1..0000000
--- a/ffmpeg-2-8-11/libavformat/http.c
+++ /dev/null
@@ -1,1639 +0,0 @@
-/*
- * HTTP protocol for ffmpeg client
- * Copyright (c) 2000, 2001 Fabrice Bellard
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "config.h"
-
-#if CONFIG_ZLIB
-#include <zlib.h>
-#endif /* CONFIG_ZLIB */
-
-#include "libavutil/avassert.h"
-#include "libavutil/avstring.h"
-#include "libavutil/opt.h"
-
-#include "avformat.h"
-#include "http.h"
-#include "httpauth.h"
-#include "internal.h"
-#include "network.h"
-#include "os_support.h"
-#include "url.h"
-
-/* XXX: POST protocol is not completely implemented because ffmpeg uses
- * only a subset of it. */
-
-/* The IO buffer size is unrelated to the max URL size in itself, but needs
- * to be large enough to fit the full request headers (including long
- * path names). */
-#define BUFFER_SIZE MAX_URL_SIZE
-#define MAX_REDIRECTS 8
-#define HTTP_SINGLE 1
-#define HTTP_MUTLI 2
-typedef enum {
- LOWER_PROTO,
- READ_HEADERS,
- WRITE_REPLY_HEADERS,
- FINISH
-}HandshakeState;
-
-typedef struct HTTPContext {
- const AVClass *class;
- URLContext *hd;
- unsigned char buffer[BUFFER_SIZE], *buf_ptr, *buf_end;
- int line_count;
- int http_code;
- /* Used if "Transfer-Encoding: chunked" otherwise -1. */
- uint64_t chunksize;
- uint64_t off, end_off, filesize;
- char *location;
- HTTPAuthState auth_state;
- HTTPAuthState proxy_auth_state;
- char *headers;
- char *mime_type;
- char *user_agent;
- char *content_type;
- /* Set if the server correctly handles Connection: close and will close
- * the connection after feeding us the content. */
- int willclose;
- int seekable; /**< Control seekability, 0 = disable, 1 = enable, -1 = probe. */
- int chunked_post;
- /* A flag which indicates if the end of chunked encoding has been sent. */
- int end_chunked_post;
- /* A flag which indicates we have finished to read POST reply. */
- int end_header;
- /* A flag which indicates if we use persistent connections. */
- int multiple_requests;
- uint8_t *post_data;
- int post_datalen;
- int is_akamai;
- int is_mediagateway;
- char *cookies; ///< holds newline (\n) delimited Set-Cookie header field values (without the "Set-Cookie: " field name)
- /* A dictionary containing cookies keyed by cookie name */
- AVDictionary *cookie_dict;
- int icy;
- /* how much data was read since the last ICY metadata packet */
- uint64_t icy_data_read;
- /* after how many bytes of read data a new metadata packet will be found */
- uint64_t icy_metaint;
- char *icy_metadata_headers;
- char *icy_metadata_packet;
- AVDictionary *metadata;
-#if CONFIG_ZLIB
- int compressed;
- z_stream inflate_stream;
- uint8_t *inflate_buffer;
-#endif /* CONFIG_ZLIB */
- AVDictionary *chained_options;
- int send_expect_100;
- char *method;
- int reconnect;
- int listen;
- char *resource;
- int reply_code;
- int is_multi_client;
- HandshakeState handshake_step;
- int is_connected_server;
-} HTTPContext;
-
-#define OFFSET(x) offsetof(HTTPContext, x)
-#define D AV_OPT_FLAG_DECODING_PARAM
-#define E AV_OPT_FLAG_ENCODING_PARAM
-#define DEFAULT_USER_AGENT "Lavf/" AV_STRINGIFY(LIBAVFORMAT_VERSION)
-
-static const AVOption options[] = {
- { "seekable", "control seekability of connection", OFFSET(seekable), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, D },
- { "chunked_post", "use chunked transfer-encoding for posts", OFFSET(chunked_post), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, E },
- { "headers", "set custom HTTP headers, can override built in default headers", OFFSET(headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D | E },
- { "content_type", "set a specific content type for the POST messages", OFFSET(content_type), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D | E },
- { "user_agent", "override User-Agent header", OFFSET(user_agent), AV_OPT_TYPE_STRING, { .str = DEFAULT_USER_AGENT }, 0, 0, D },
- { "user-agent", "override User-Agent header", OFFSET(user_agent), AV_OPT_TYPE_STRING, { .str = DEFAULT_USER_AGENT }, 0, 0, D },
- { "multiple_requests", "use persistent connections", OFFSET(multiple_requests), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D | E },
- { "post_data", "set custom HTTP post data", OFFSET(post_data), AV_OPT_TYPE_BINARY, .flags = D | E },
- { "mime_type", "export the MIME type", OFFSET(mime_type), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY },
- { "cookies", "set cookies to be sent in applicable future requests, use newline delimited Set-Cookie HTTP field value syntax", OFFSET(cookies), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D },
- { "icy", "request ICY metadata", OFFSET(icy), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, D },
- { "icy_metadata_headers", "return ICY metadata headers", OFFSET(icy_metadata_headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_EXPORT },
- { "icy_metadata_packet", "return current ICY metadata packet", OFFSET(icy_metadata_packet), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_EXPORT },
- { "metadata", "metadata read from the bitstream", OFFSET(metadata), AV_OPT_TYPE_DICT, {0}, 0, 0, AV_OPT_FLAG_EXPORT },
- { "auth_type", "HTTP authentication type", OFFSET(auth_state.auth_type), AV_OPT_TYPE_INT, { .i64 = HTTP_AUTH_NONE }, HTTP_AUTH_NONE, HTTP_AUTH_BASIC, D | E, "auth_type"},
- { "none", "No auth method set, autodetect", 0, AV_OPT_TYPE_CONST, { .i64 = HTTP_AUTH_NONE }, 0, 0, D | E, "auth_type"},
- { "basic", "HTTP basic authentication", 0, AV_OPT_TYPE_CONST, { .i64 = HTTP_AUTH_BASIC }, 0, 0, D | E, "auth_type"},
- { "send_expect_100", "Force sending an Expect: 100-continue header for POST", OFFSET(send_expect_100), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, E },
- { "location", "The actual location of the data received", OFFSET(location), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D | E },
- { "offset", "initial byte offset", OFFSET(off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, D },
- { "end_offset", "try to limit the request to bytes preceding this offset", OFFSET(end_off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, D },
- { "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_INT, { .i64 = 0 }, 0, 1, D },
- { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, D | E },
- { "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
- { "reply_code", "The http status code to return to a client", OFFSET(reply_code), AV_OPT_TYPE_INT, { .i64 = 200}, INT_MIN, 599, E},
- { NULL }
-};
-
-static int http_connect(URLContext *h, const char *path, const char *local_path,
- const char *hoststr, const char *auth,
- const char *proxyauth, int *new_location);
-static int http_read_header(URLContext *h, int *new_location);
-
-void ff_http_init_auth_state(URLContext *dest, const URLContext *src)
-{
- memcpy(&((HTTPContext *)dest->priv_data)->auth_state,
- &((HTTPContext *)src->priv_data)->auth_state,
- sizeof(HTTPAuthState));
- memcpy(&((HTTPContext *)dest->priv_data)->proxy_auth_state,
- &((HTTPContext *)src->priv_data)->proxy_auth_state,
- sizeof(HTTPAuthState));
-}
-
-static int http_open_cnx_internal(URLContext *h, AVDictionary **options)
-{
- const char *path, *proxy_path, *lower_proto = "tcp", *local_path;
- char hostname[1024], hoststr[1024], proto[10];
- char auth[1024], proxyauth[1024] = "";
- char path1[MAX_URL_SIZE];
- char buf[1024], urlbuf[MAX_URL_SIZE];
- int port, use_proxy, err, location_changed = 0;
- HTTPContext *s = h->priv_data;
-
- av_url_split(proto, sizeof(proto), auth, sizeof(auth),
- hostname, sizeof(hostname), &port,
- path1, sizeof(path1), s->location);
- ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);
-
- proxy_path = getenv("http_proxy");
- use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), hostname) &&
- proxy_path && av_strstart(proxy_path, "http://", NULL);
-
- if (!strcmp(proto, "https")) {
- lower_proto = "tls";
- use_proxy = 0;
- if (port < 0)
- port = 443;
- }
- if (port < 0)
- port = 80;
-
- if (path1[0] == '\0')
- path = "/";
- else
- path = path1;
- local_path = path;
- if (use_proxy) {
- /* Reassemble the request URL without auth string - we don't
- * want to leak the auth to the proxy. */
- ff_url_join(urlbuf, sizeof(urlbuf), proto, NULL, hostname, port, "%s",
- path1);
- path = urlbuf;
- av_url_split(NULL, 0, proxyauth, sizeof(proxyauth),
- hostname, sizeof(hostname), &port, NULL, 0, proxy_path);
- }
-
- ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL);
-
- if (!s->hd) {
- err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE,
- &h->interrupt_callback, options);
- if (err < 0)
- return err;
- }
-
- err = http_connect(h, path, local_path, hoststr,
- auth, proxyauth, &location_changed);
- if (err < 0)
- return err;
-
- return location_changed;
-}
-
-/* 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;
-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;
-
- location_changed = http_open_cnx_internal(h, options);
- if (location_changed < 0)
- goto fail;
-
- attempts++;
- if (s->http_code == 401) {
- if ((cur_auth_type == HTTP_AUTH_NONE || s->auth_state.stale) &&
- s->auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) {
- ffurl_closep(&s->hd);
- goto redo;
- } else
- goto fail;
- }
- if (s->http_code == 407) {
- if ((cur_proxy_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) &&
- s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) {
- ffurl_closep(&s->hd);
- goto redo;
- } else
- goto fail;
- }
- if ((s->http_code == 301 || s->http_code == 302 ||
- s->http_code == 303 || s->http_code == 307) &&
- location_changed == 1) {
- /* url moved, get next */
- ffurl_closep(&s->hd);
- if (redirects++ >= MAX_REDIRECTS)
- return AVERROR(EIO);
- /* Restart the authentication process with the new target, which
- * might use a different auth mechanism. */
- memset(&s->auth_state, 0, sizeof(s->auth_state));
- attempts = 0;
- location_changed = 0;
- goto redo;
- }
- return 0;
-
-fail:
- if (s->hd)
- ffurl_closep(&s->hd);
- if (location_changed < 0)
- return location_changed;
- return ff_http_averror(s->http_code, AVERROR(EIO));
-}
-
-int ff_http_do_new_request(URLContext *h, const char *uri)
-{
- HTTPContext *s = h->priv_data;
- AVDictionary *options = NULL;
- int ret;
-
- s->off = 0;
- s->icy_data_read = 0;
- av_free(s->location);
- s->location = av_strdup(uri);
- if (!s->location)
- return AVERROR(ENOMEM);
-
- ret = http_open_cnx(h, &options);
- av_dict_free(&options);
- return ret;
-}
-
-int ff_http_averror(int status_code, int default_averror)
-{
- switch (status_code) {
- case 400: return AVERROR_HTTP_BAD_REQUEST;
- case 401: return AVERROR_HTTP_UNAUTHORIZED;
- case 403: return AVERROR_HTTP_FORBIDDEN;
- case 404: return AVERROR_HTTP_NOT_FOUND;
- default: break;
- }
- if (status_code >= 400 && status_code <= 499)
- return AVERROR_HTTP_OTHER_4XX;
- else if (status_code >= 500)
- return AVERROR_HTTP_SERVER_ERROR;
- else
- return default_averror;
-}
-
-static int http_write_reply(URLContext* h, int status_code)
-{
- int ret, body = 0, reply_code, message_len;
- const char *reply_text, *content_type;
- HTTPContext *s = h->priv_data;
- char message[BUFFER_SIZE];
- content_type = "text/plain";
-
- if (status_code < 0)
- body = 1;
- switch (status_code) {
- case AVERROR_HTTP_BAD_REQUEST:
- case 400:
- reply_code = 400;
- reply_text = "Bad Request";
- break;
- case AVERROR_HTTP_FORBIDDEN:
- case 403:
- reply_code = 403;
- reply_text = "Forbidden";
- break;
- case AVERROR_HTTP_NOT_FOUND:
- case 404:
- reply_code = 404;
- reply_text = "Not Found";
- break;
- case 200:
- reply_code = 200;
- reply_text = "OK";
- content_type = "application/octet-stream";
- break;
- case AVERROR_HTTP_SERVER_ERROR:
- case 500:
- reply_code = 500;
- reply_text = "Internal server error";
- break;
- default:
- return AVERROR(EINVAL);
- }
- if (body) {
- s->chunked_post = 0;
- message_len = snprintf(message, sizeof(message),
- "HTTP/1.1 %03d %s\r\n"
- "Content-Type: %s\r\n"
- "Content-Length: %zu\r\n"
- "\r\n"
- "%03d %s\r\n",
- reply_code,
- reply_text,
- content_type,
- strlen(reply_text) + 6, // 3 digit status code + space + \r\n
- reply_code,
- reply_text);
- } else {
- s->chunked_post = 1;
- message_len = snprintf(message, sizeof(message),
- "HTTP/1.1 %03d %s\r\n"
- "Content-Type: %s\r\n"
- "Transfer-Encoding: chunked\r\n"
- "\r\n",
- reply_code,
- reply_text,
- content_type);
- }
- av_log(h, AV_LOG_TRACE, "HTTP reply header: \n%s----\n", message);
- if ((ret = ffurl_write(s->hd, message, message_len)) < 0)
- return ret;
- return 0;
-}
-
-static void handle_http_errors(URLContext *h, int error)
-{
- av_assert0(error < 0);
- http_write_reply(h, error);
-}
-
-static int http_handshake(URLContext *c)
-{
- int ret, err, new_location;
- HTTPContext *ch = c->priv_data;
- URLContext *cl = ch->hd;
- switch (ch->handshake_step) {
- case LOWER_PROTO:
- av_log(c, AV_LOG_TRACE, "Lower protocol\n");
- if ((ret = ffurl_handshake(cl)) > 0)
- return 2 + ret;
- if (ret < 0)
- return ret;
- ch->handshake_step = READ_HEADERS;
- ch->is_connected_server = 1;
- return 2;
- case READ_HEADERS:
- av_log(c, AV_LOG_TRACE, "Read headers\n");
- if ((err = http_read_header(c, &new_location)) < 0) {
- handle_http_errors(c, err);
- return err;
- }
- ch->handshake_step = WRITE_REPLY_HEADERS;
- return 1;
- case WRITE_REPLY_HEADERS:
- av_log(c, AV_LOG_TRACE, "Reply code: %d\n", ch->reply_code);
- if ((err = http_write_reply(c, ch->reply_code)) < 0)
- return err;
- ch->handshake_step = FINISH;
- return 1;
- case FINISH:
- return 0;
- }
- // this should never be reached.
- return AVERROR(EINVAL);
-}
-
-static int http_listen(URLContext *h, const char *uri, int flags,
- AVDictionary **options) {
- HTTPContext *s = h->priv_data;
- int ret;
- char hostname[1024], proto[10];
- char lower_url[100];
- const char *lower_proto = "tcp";
- int port;
- av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
- NULL, 0, uri);
- if (!strcmp(proto, "https"))
- lower_proto = "tls";
- ff_url_join(lower_url, sizeof(lower_url), lower_proto, NULL, hostname, port,
- NULL);
- if ((ret = av_dict_set_int(options, "listen", s->listen, 0)) < 0)
- goto fail;
- if ((ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE,
- &h->interrupt_callback, options)) < 0)
- goto fail;
- s->handshake_step = LOWER_PROTO;
- if (s->listen == HTTP_SINGLE) { /* single client */
- s->reply_code = 200;
- while ((ret = http_handshake(h)) > 0);
- }
-fail:
- av_dict_free(&s->chained_options);
- return ret;
-}
-
-static int http_open(URLContext *h, const char *uri, int flags,
- AVDictionary **options)
-{
- HTTPContext *s = h->priv_data;
- int ret;
-
- if( s->seekable == 1 )
- h->is_streamed = 0;
- else
- h->is_streamed = 1;
-
- s->filesize = UINT64_MAX;
- s->location = av_strdup(uri);
- if (!s->location)
- return AVERROR(ENOMEM);
- if (options)
- av_dict_copy(&s->chained_options, *options, 0);
-
- if (s->headers) {
- int len = strlen(s->headers);
- if (len < 2 || strcmp("\r\n", s->headers + len - 2)) {
- av_log(h, AV_LOG_WARNING,
- "No trailing CRLF found in HTTP header.\n");
- ret = av_reallocp(&s->headers, len + 3);
- if (ret < 0)
- return ret;
- s->headers[len] = '\r';
- s->headers[len + 1] = '\n';
- s->headers[len + 2] = '\0';
- }
- }
-
- if (s->listen) {
- return http_listen(h, uri, flags, options);
- }
- ret = http_open_cnx(h, options);
- if (ret < 0)
- av_dict_free(&s->chained_options);
- return ret;
-}
-
-static int http_accept(URLContext *s, URLContext **c)
-{
- int ret;
- HTTPContext *sc = s->priv_data;
- HTTPContext *cc;
- URLContext *sl = sc->hd;
- URLContext *cl = NULL;
-
- av_assert0(sc->listen);
- if ((ret = ffurl_alloc(c, s->filename, s->flags, &sl->interrupt_callback)) < 0)
- goto fail;
- cc = (*c)->priv_data;
- if ((ret = ffurl_accept(sl, &cl)) < 0)
- goto fail;
- cc->hd = cl;
- cc->is_multi_client = 1;
-fail:
- return ret;
-}
-
-static int http_getc(HTTPContext *s)
-{
- int len;
- if (s->buf_ptr >= s->buf_end) {
- len = ffurl_read(s->hd, s->buffer, BUFFER_SIZE);
- if (len < 0) {
- return len;
- } else if (len == 0) {
- return AVERROR_EOF;
- } else {
- s->buf_ptr = s->buffer;
- s->buf_end = s->buffer + len;
- }
- }
- return *s->buf_ptr++;
-}
-
-static int http_get_line(HTTPContext *s, char *line, int line_size)
-{
- int ch;
- char *q;
-
- q = line;
- for (;;) {
- ch = http_getc(s);
- if (ch < 0)
- return ch;
- if (ch == '\n') {
- /* process line */
- if (q > line && q[-1] == '\r')
- q--;
- *q = '\0';
-
- return 0;
- } else {
- if ((q - line) < line_size - 1)
- *q++ = ch;
- }
- }
-}
-
-static int check_http_code(URLContext *h, int http_code, const char *end)
-{
- HTTPContext *s = h->priv_data;
- /* error codes are 4xx and 5xx, but regard 401 as a success, so we
- * don't abort until all headers have been parsed. */
- if (http_code >= 400 && http_code < 600 &&
- (http_code != 401 || s->auth_state.auth_type != HTTP_AUTH_NONE) &&
- (http_code != 407 || s->proxy_auth_state.auth_type != HTTP_AUTH_NONE)) {
- end += strspn(end, SPACE_CHARS);
- av_log(h, AV_LOG_WARNING, "HTTP error %d %s\n", http_code, end);
- return ff_http_averror(http_code, AVERROR(EIO));
- }
- return 0;
-}
-
-static int parse_location(HTTPContext *s, const char *p)
-{
- char redirected_location[MAX_URL_SIZE], *new_loc;
- ff_make_absolute_url(redirected_location, sizeof(redirected_location),
- s->location, p);
- new_loc = av_strdup(redirected_location);
- if (!new_loc)
- return AVERROR(ENOMEM);
- av_free(s->location);
- s->location = new_loc;
- return 0;
-}
-
-/* "bytes $from-$to/$document_size" */
-static void parse_content_range(URLContext *h, const char *p)
-{
- HTTPContext *s = h->priv_data;
- const char *slash;
-
- if (!strncmp(p, "bytes ", 6)) {
- p += 6;
- s->off = strtoull(p, NULL, 10);
- if ((slash = strchr(p, '/')) && strlen(slash) > 0)
- s->filesize = strtoull(slash + 1, NULL, 10);
- }
- if (s->seekable == -1 && (!s->is_akamai || s->filesize != 2147483647))
- h->is_streamed = 0; /* we _can_ in fact seek */
-}
-
-static int parse_content_encoding(URLContext *h, const char *p)
-{
- if (!av_strncasecmp(p, "gzip", 4) ||
- !av_strncasecmp(p, "deflate", 7)) {
-#if CONFIG_ZLIB
- HTTPContext *s = h->priv_data;
-
- s->compressed = 1;
- inflateEnd(&s->inflate_stream);
- if (inflateInit2(&s->inflate_stream, 32 + 15) != Z_OK) {
- av_log(h, AV_LOG_WARNING, "Error during zlib initialisation: %s\n",
- s->inflate_stream.msg);
- return AVERROR(ENOSYS);
- }
- if (zlibCompileFlags() & (1 << 17)) {
- av_log(h, AV_LOG_WARNING,
- "Your zlib was compiled without gzip support.\n");
- return AVERROR(ENOSYS);
- }
-#else
- av_log(h, AV_LOG_WARNING,
- "Compressed (%s) content, need zlib with gzip support\n", p);
- return AVERROR(ENOSYS);
-#endif /* CONFIG_ZLIB */
- } else if (!av_strncasecmp(p, "identity", 8)) {
- // The normal, no-encoding case (although servers shouldn't include
- // the header at all if this is the case).
- } else {
- av_log(h, AV_LOG_WARNING, "Unknown content coding: %s\n", p);
- }
- return 0;
-}
-
-// Concat all Icy- header lines
-static int parse_icy(HTTPContext *s, const char *tag, const char *p)
-{
- int len = 4 + strlen(p) + strlen(tag);
- int is_first = !s->icy_metadata_headers;
- int ret;
-
- av_dict_set(&s->metadata, tag, p, 0);
-
- if (s->icy_metadata_headers)
- len += strlen(s->icy_metadata_headers);
-
- if ((ret = av_reallocp(&s->icy_metadata_headers, len)) < 0)
- return ret;
-
- if (is_first)
- *s->icy_metadata_headers = '\0';
-
- av_strlcatf(s->icy_metadata_headers, len, "%s: %s\n", tag, p);
-
- return 0;
-}
-
-static int parse_cookie(HTTPContext *s, const char *p, AVDictionary **cookies)
-{
- char *eql, *name;
-
- // duplicate the cookie name (dict will dupe the value)
- if (!(eql = strchr(p, '='))) return AVERROR(EINVAL);
- if (!(name = av_strndup(p, eql - p))) return AVERROR(ENOMEM);
-
- // add the cookie to the dictionary
- av_dict_set(cookies, name, eql, AV_DICT_DONT_STRDUP_KEY);
-
- return 0;
-}
-
-static int cookie_string(AVDictionary *dict, char **cookies)
-{
- AVDictionaryEntry *e = NULL;
- int len = 1;
-
- // determine how much memory is needed for the cookies string
- while (e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))
- len += strlen(e->key) + strlen(e->value) + 1;
-
- // reallocate the cookies
- e = NULL;
- if (*cookies) av_free(*cookies);
- *cookies = av_malloc(len);
- if (!*cookies) return AVERROR(ENOMEM);
- *cookies[0] = '\0';
-
- // write out the cookies
- while (e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))
- av_strlcatf(*cookies, len, "%s%s\n", e->key, e->value);
-
- return 0;
-}
-
-static int process_line(URLContext *h, char *line, int line_count,
- int *new_location)
-{
- HTTPContext *s = h->priv_data;
- const char *auto_method = h->flags & AVIO_FLAG_READ ? "POST" : "GET";
- char *tag, *p, *end, *method, *resource, *version;
- int ret;
-
- /* end of header */
- if (line[0] == '\0') {
- s->end_header = 1;
- return 0;
- }
-
- p = line;
- if (line_count == 0) {
- if (s->is_connected_server) {
- // HTTP method
- method = p;
- while (*p && !av_isspace(*p))
- p++;
- *(p++) = '\0';
- av_log(h, AV_LOG_TRACE, "Received method: %s\n", method);
- if (s->method) {
- if (av_strcasecmp(s->method, method)) {
- av_log(h, AV_LOG_ERROR, "Received and expected HTTP method do not match. (%s expected, %s received)\n",
- s->method, method);
- return ff_http_averror(400, AVERROR(EIO));
- }
- } else {
- // use autodetected HTTP method to expect
- av_log(h, AV_LOG_TRACE, "Autodetected %s HTTP method\n", auto_method);
- if (av_strcasecmp(auto_method, method)) {
- av_log(h, AV_LOG_ERROR, "Received and autodetected HTTP method did not match "
- "(%s autodetected %s received)\n", auto_method, method);
- return ff_http_averror(400, AVERROR(EIO));
- }
- if (!(s->method = av_strdup(method)))
- return AVERROR(ENOMEM);
- }
-
- // HTTP resource
- while (av_isspace(*p))
- p++;
- resource = p;
- while (!av_isspace(*p))
- p++;
- *(p++) = '\0';
- av_log(h, AV_LOG_TRACE, "Requested resource: %s\n", resource);
- if (!(s->resource = av_strdup(resource)))
- return AVERROR(ENOMEM);
-
- // HTTP version
- while (av_isspace(*p))
- p++;
- version = p;
- while (*p && !av_isspace(*p))
- p++;
- *p = '\0';
- if (av_strncasecmp(version, "HTTP/", 5)) {
- av_log(h, AV_LOG_ERROR, "Malformed HTTP version string.\n");
- return ff_http_averror(400, AVERROR(EIO));
- }
- av_log(h, AV_LOG_TRACE, "HTTP version string: %s\n", version);
- } else {
- while (!av_isspace(*p) && *p != '\0')
- p++;
- while (av_isspace(*p))
- p++;
- s->http_code = strtol(p, &end, 10);
-
- av_log(h, AV_LOG_TRACE, "http_code=%d\n", s->http_code);
-
- if ((ret = check_http_code(h, s->http_code, end)) < 0)
- return ret;
- }
- } else {
- while (*p != '\0' && *p != ':')
- p++;
- if (*p != ':')
- return 1;
-
- *p = '\0';
- tag = line;
- p++;
- while (av_isspace(*p))
- p++;
- if (!av_strcasecmp(tag, "Location")) {
- if ((ret = parse_location(s, p)) < 0)
- return ret;
- *new_location = 1;
- } else if (!av_strcasecmp(tag, "Content-Length") &&
- s->filesize == UINT64_MAX) {
- s->filesize = strtoull(p, NULL, 10);
- } else if (!av_strcasecmp(tag, "Content-Range")) {
- parse_content_range(h, p);
- } else if (!av_strcasecmp(tag, "Accept-Ranges") &&
- !strncmp(p, "bytes", 5) &&
- s->seekable == -1) {
- h->is_streamed = 0;
- } else if (!av_strcasecmp(tag, "Transfer-Encoding") &&
- !av_strncasecmp(p, "chunked", 7)) {
- s->filesize = UINT64_MAX;
- s->chunksize = 0;
- } else if (!av_strcasecmp(tag, "WWW-Authenticate")) {
- ff_http_auth_handle_header(&s->auth_state, tag, p);
- } else if (!av_strcasecmp(tag, "Authentication-Info")) {
- ff_http_auth_handle_header(&s->auth_state, tag, p);
- } else if (!av_strcasecmp(tag, "Proxy-Authenticate")) {
- ff_http_auth_handle_header(&s->proxy_auth_state, tag, p);
- } else if (!av_strcasecmp(tag, "Connection")) {
- if (!strcmp(p, "close"))
- s->willclose = 1;
- } else if (!av_strcasecmp(tag, "Server")) {
- if (!av_strcasecmp(p, "AkamaiGHost")) {
- s->is_akamai = 1;
- } else if (!av_strncasecmp(p, "MediaGateway", 12)) {
- s->is_mediagateway = 1;
- }
- } else if (!av_strcasecmp(tag, "Content-Type")) {
- av_free(s->mime_type);
- s->mime_type = av_strdup(p);
- } else if (!av_strcasecmp(tag, "Set-Cookie")) {
- if (parse_cookie(s, p, &s->cookie_dict))
- av_log(h, AV_LOG_WARNING, "Unable to parse '%s'\n", p);
- } else if (!av_strcasecmp(tag, "Icy-MetaInt")) {
- s->icy_metaint = strtoull(p, NULL, 10);
- } else if (!av_strncasecmp(tag, "Icy-", 4)) {
- if ((ret = parse_icy(s, tag, p)) < 0)
- return ret;
- } else if (!av_strcasecmp(tag, "Content-Encoding")) {
- if ((ret = parse_content_encoding(h, p)) < 0)
- return ret;
- }
- }
- return 1;
-}
-
-/**
- * Create a string containing cookie values for use as a HTTP cookie header
- * field value for a particular path and domain from the cookie values stored in
- * the HTTP protocol context. The cookie string is stored in *cookies.
- *
- * @return a negative value if an error condition occurred, 0 otherwise
- */
-static int get_cookies(HTTPContext *s, char **cookies, const char *path,
- const char *domain)
-{
- // cookie strings will look like Set-Cookie header field values. Multiple
- // Set-Cookie fields will result in multiple values delimited by a newline
- int ret = 0;
- char *next, *cookie, *set_cookies = av_strdup(s->cookies), *cset_cookies = set_cookies;
-
- if (!set_cookies) return AVERROR(EINVAL);
-
- // destroy any cookies in the dictionary.
- av_dict_free(&s->cookie_dict);
-
- *cookies = NULL;
- while ((cookie = av_strtok(set_cookies, "\n", &next))) {
- int domain_offset = 0;
- char *param, *next_param, *cdomain = NULL, *cpath = NULL, *cvalue = NULL;
- set_cookies = NULL;
-
- // store the cookie in a dict in case it is updated in the response
- if (parse_cookie(s, cookie, &s->cookie_dict))
- av_log(s, AV_LOG_WARNING, "Unable to parse '%s'\n", cookie);
-
- while ((param = av_strtok(cookie, "; ", &next_param))) {
- if (cookie) {
- // first key-value pair is the actual cookie value
- cvalue = av_strdup(param);
- cookie = NULL;
- } else if (!av_strncasecmp("path=", param, 5)) {
- av_free(cpath);
- cpath = av_strdup(¶m[5]);
- } else if (!av_strncasecmp("domain=", param, 7)) {
- // if the cookie specifies a sub-domain, skip the leading dot thereby
- // supporting URLs that point to sub-domains and the master domain
- int leading_dot = (param[7] == '.');
- av_free(cdomain);
- cdomain = av_strdup(¶m[7+leading_dot]);
- } else {
- // ignore unknown attributes
- }
- }
- if (!cdomain)
- cdomain = av_strdup(domain);
-
- // ensure all of the necessary values are valid
- if (!cdomain || !cpath || !cvalue) {
- av_log(s, AV_LOG_WARNING,
- "Invalid cookie found, no value, path or domain specified\n");
- goto done_cookie;
- }
-
- // check if the request path matches the cookie path
- if (av_strncasecmp(path, cpath, strlen(cpath)))
- goto done_cookie;
-
- // the domain should be at least the size of our cookie domain
- domain_offset = strlen(domain) - strlen(cdomain);
- if (domain_offset < 0)
- goto done_cookie;
-
- // match the cookie domain
- if (av_strcasecmp(&domain[domain_offset], cdomain))
- goto done_cookie;
-
- // cookie parameters match, so copy the value
- if (!*cookies) {
- if (!(*cookies = av_strdup(cvalue))) {
- ret = AVERROR(ENOMEM);
- goto done_cookie;
- }
- } else {
- char *tmp = *cookies;
- size_t str_size = strlen(cvalue) + strlen(*cookies) + 3;
- if (!(*cookies = av_malloc(str_size))) {
- ret = AVERROR(ENOMEM);
- goto done_cookie;
- }
- snprintf(*cookies, str_size, "%s; %s", tmp, cvalue);
- av_free(tmp);
- }
-
- done_cookie:
- av_freep(&cdomain);
- av_freep(&cpath);
- av_freep(&cvalue);
- if (ret < 0) {
- if (*cookies) av_freep(cookies);
- av_free(cset_cookies);
- return ret;
- }
- }
-
- av_free(cset_cookies);
-
- return 0;
-}
-
-static inline int has_header(const char *str, const char *header)
-{
- /* header + 2 to skip over CRLF prefix. (make sure you have one!) */
- if (!str)
- return 0;
- return av_stristart(str, header + 2, NULL) || av_stristr(str, header);
-}
-
-static int http_read_header(URLContext *h, int *new_location)
-{
- HTTPContext *s = h->priv_data;
- char line[MAX_URL_SIZE];
- int err = 0;
-
- s->chunksize = UINT64_MAX;
-
- for (;;) {
- if ((err = http_get_line(s, line, sizeof(line))) < 0)
- return err;
-
- av_log(h, AV_LOG_TRACE, "header='%s'\n", line);
-
- err = process_line(h, line, s->line_count, new_location);
- if (err < 0)
- return err;
- if (err == 0)
- break;
- s->line_count++;
- }
-
- if (s->seekable == -1 && s->is_mediagateway && s->filesize == 2000000000)
- h->is_streamed = 1; /* we can in fact _not_ seek */
-
- // add any new cookies into the existing cookie string
- cookie_string(s->cookie_dict, &s->cookies);
- av_dict_free(&s->cookie_dict);
-
- return err;
-}
-
-static int http_connect(URLContext *h, const char *path, const char *local_path,
- const char *hoststr, const char *auth,
- const char *proxyauth, int *new_location)
-{
- HTTPContext *s = h->priv_data;
- int post, err;
- char headers[HTTP_HEADERS_SIZE] = "";
- char *authstr = NULL, *proxyauthstr = NULL;
- uint64_t off = s->off;
- int len = 0;
- const char *method;
- int send_expect_100 = 0;
-
- /* send http header */
- post = h->flags & AVIO_FLAG_WRITE;
-
- if (s->post_data) {
- /* force POST method and disable chunked encoding when
- * custom HTTP post data is set */
- post = 1;
- s->chunked_post = 0;
- }
-
- if (s->method)
- method = s->method;
- else
- method = post ? "POST" : "GET";
-
- authstr = ff_http_auth_create_response(&s->auth_state, auth,
- local_path, method);
- proxyauthstr = ff_http_auth_create_response(&s->proxy_auth_state, proxyauth,
- local_path, method);
- if (post && !s->post_data) {
- send_expect_100 = s->send_expect_100;
- /* The user has supplied authentication but we don't know the auth type,
- * send Expect: 100-continue to get the 401 response including the
- * WWW-Authenticate header, or an 100 continue if no auth actually
- * is needed. */
- if (auth && *auth &&
- s->auth_state.auth_type == HTTP_AUTH_NONE &&
- s->http_code != 401)
- send_expect_100 = 1;
- }
-
- /* set default headers if needed */
- if (!has_header(s->headers, "\r\nUser-Agent: "))
- len += av_strlcatf(headers + len, sizeof(headers) - len,
- "User-Agent: %s\r\n", s->user_agent);
- if (!has_header(s->headers, "\r\nAccept: "))
- len += av_strlcpy(headers + len, "Accept: */*\r\n",
- sizeof(headers) - len);
- // Note: we send this on purpose even when s->off is 0 when we're probing,
- // since it allows us to detect more reliably if a (non-conforming)
- // server supports seeking by analysing the reply headers.
- if (!has_header(s->headers, "\r\nRange: ") && !post && (s->off > 0 || s->end_off || s->seekable == -1)) {
- len += av_strlcatf(headers + len, sizeof(headers) - len,
- "Range: bytes=%"PRIu64"-", s->off);
- if (s->end_off)
- len += av_strlcatf(headers + len, sizeof(headers) - len,
- "%"PRId64, s->end_off - 1);
- len += av_strlcpy(headers + len, "\r\n",
- sizeof(headers) - len);
- }
- if (send_expect_100 && !has_header(s->headers, "\r\nExpect: "))
- len += av_strlcatf(headers + len, sizeof(headers) - len,
- "Expect: 100-continue\r\n");
-
- if (!has_header(s->headers, "\r\nConnection: ")) {
- if (s->multiple_requests)
- len += av_strlcpy(headers + len, "Connection: keep-alive\r\n",
- sizeof(headers) - len);
- else
- len += av_strlcpy(headers + len, "Connection: close\r\n",
- sizeof(headers) - len);
- }
-
- if (!has_header(s->headers, "\r\nHost: "))
- len += av_strlcatf(headers + len, sizeof(headers) - len,
- "Host: %s\r\n", hoststr);
- if (!has_header(s->headers, "\r\nContent-Length: ") && s->post_data)
- len += av_strlcatf(headers + len, sizeof(headers) - len,
- "Content-Length: %d\r\n", s->post_datalen);
-
- if (!has_header(s->headers, "\r\nContent-Type: ") && s->content_type)
- len += av_strlcatf(headers + len, sizeof(headers) - len,
- "Content-Type: %s\r\n", s->content_type);
- if (!has_header(s->headers, "\r\nCookie: ") && s->cookies) {
- char *cookies = NULL;
- if (!get_cookies(s, &cookies, path, hoststr) && cookies) {
- len += av_strlcatf(headers + len, sizeof(headers) - len,
- "Cookie: %s\r\n", cookies);
- av_free(cookies);
- }
- }
- if (!has_header(s->headers, "\r\nIcy-MetaData: ") && s->icy)
- len += av_strlcatf(headers + len, sizeof(headers) - len,
- "Icy-MetaData: %d\r\n", 1);
-
- /* now add in custom headers */
- if (s->headers)
- av_strlcpy(headers + len, s->headers, sizeof(headers) - len);
-
- snprintf(s->buffer, sizeof(s->buffer),
- "%s %s HTTP/1.1\r\n"
- "%s"
- "%s"
- "%s"
- "%s%s"
- "\r\n",
- method,
- path,
- post && s->chunked_post ? "Transfer-Encoding: chunked\r\n" : "",
- headers,
- authstr ? authstr : "",
- proxyauthstr ? "Proxy-" : "", proxyauthstr ? proxyauthstr : "");
-
- av_log(h, AV_LOG_DEBUG, "request: %s\n", s->buffer);
-
- if ((err = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0)
- goto done;
-
- if (s->post_data)
- if ((err = ffurl_write(s->hd, s->post_data, s->post_datalen)) < 0)
- goto done;
-
- /* init input buffer */
- s->buf_ptr = s->buffer;
- s->buf_end = s->buffer;
- s->line_count = 0;
- s->off = 0;
- s->icy_data_read = 0;
- s->filesize = UINT64_MAX;
- s->willclose = 0;
- s->end_chunked_post = 0;
- s->end_header = 0;
- if (post && !s->post_data && !send_expect_100) {
- /* Pretend that it did work. We didn't read any header yet, since
- * we've still to send the POST data, but the code calling this
- * function will check http_code after we return. */
- s->http_code = 200;
- err = 0;
- goto done;
- }
-
- /* wait for header */
- err = http_read_header(h, new_location);
- if (err < 0)
- goto done;
-
- if (*new_location)
- s->off = off;
-
- err = (off == s->off) ? 0 : -1;
-done:
- av_freep(&authstr);
- av_freep(&proxyauthstr);
- return err;
-}
-
-static int http_buf_read(URLContext *h, uint8_t *buf, int size)
-{
- HTTPContext *s = h->priv_data;
- int len;
-
- if (s->chunksize != UINT64_MAX) {
- if (!s->chunksize) {
- char line[32];
- int err;
-
- do {
- if ((err = http_get_line(s, line, sizeof(line))) < 0)
- return err;
- } while (!*line); /* skip CR LF from last chunk */
-
- s->chunksize = strtoull(line, NULL, 16);
-
- av_log(h, AV_LOG_TRACE,
- "Chunked encoding data size: %"PRIu64"'\n",
- s->chunksize);
-
- if (!s->chunksize)
- return 0;
- else if (s->chunksize == UINT64_MAX) {
- av_log(h, AV_LOG_ERROR, "Invalid chunk size %"PRIu64"\n",
- s->chunksize);
- return AVERROR(EINVAL);
- }
- }
- size = FFMIN(size, s->chunksize);
- }
-
- /* read bytes from input buffer first */
- len = s->buf_end - s->buf_ptr;
- if (len > 0) {
- if (len > size)
- len = size;
- memcpy(buf, s->buf_ptr, len);
- s->buf_ptr += len;
- } else {
- if ((!s->willclose || s->chunksize == UINT64_MAX) && s->off >= s->filesize)
- return AVERROR_EOF;
- len = ffurl_read(s->hd, buf, size);
- if (!len && (!s->willclose || s->chunksize == UINT64_MAX) && s->off < s->filesize) {
- av_log(h, AV_LOG_ERROR,
- "Stream ends prematurely at %"PRIu64", should be %"PRIu64"\n",
- s->off, s->filesize
- );
- return AVERROR(EIO);
- }
- }
- if (len > 0) {
- s->off += len;
- if (s->chunksize > 0) {
- av_assert0(s->chunksize >= len);
- s->chunksize -= len;
- }
- }
- return len;
-}
-
-#if CONFIG_ZLIB
-#define DECOMPRESS_BUF_SIZE (256 * 1024)
-static int http_buf_read_compressed(URLContext *h, uint8_t *buf, int size)
-{
- HTTPContext *s = h->priv_data;
- int ret;
-
- if (!s->inflate_buffer) {
- s->inflate_buffer = av_malloc(DECOMPRESS_BUF_SIZE);
- if (!s->inflate_buffer)
- return AVERROR(ENOMEM);
- }
-
- if (s->inflate_stream.avail_in == 0) {
- int read = http_buf_read(h, s->inflate_buffer, DECOMPRESS_BUF_SIZE);
- if (read <= 0)
- return read;
- s->inflate_stream.next_in = s->inflate_buffer;
- s->inflate_stream.avail_in = read;
- }
-
- s->inflate_stream.avail_out = size;
- s->inflate_stream.next_out = buf;
-
- ret = inflate(&s->inflate_stream, Z_SYNC_FLUSH);
- if (ret != Z_OK && ret != Z_STREAM_END)
- av_log(h, AV_LOG_WARNING, "inflate return value: %d, %s\n",
- ret, s->inflate_stream.msg);
-
- return size - s->inflate_stream.avail_out;
-}
-#endif /* CONFIG_ZLIB */
-
-static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int force_reconnect);
-
-static int http_read_stream(URLContext *h, uint8_t *buf, int size)
-{
- HTTPContext *s = h->priv_data;
- int err, new_location, read_ret, seek_ret;
-
- if (!s->hd)
- return AVERROR_EOF;
-
- if (s->end_chunked_post && !s->end_header) {
- err = http_read_header(h, &new_location);
- if (err < 0)
- return err;
- }
-
-#if CONFIG_ZLIB
- if (s->compressed)
- return http_buf_read_compressed(h, buf, size);
-#endif /* CONFIG_ZLIB */
- read_ret = http_buf_read(h, buf, size);
- if (read_ret < 0 && s->reconnect && !h->is_streamed && s->filesize > 0 && s->off < s->filesize) {
- av_log(h, AV_LOG_INFO, "Will reconnect at %"PRIu64".\n", s->off);
- seek_ret = http_seek_internal(h, s->off, SEEK_SET, 1);
- if (seek_ret != s->off) {
- av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRIu64".\n", s->off);
- return read_ret;
- }
-
- read_ret = http_buf_read(h, buf, size);
- }
-
- return read_ret;
-}
-
-// Like http_read_stream(), but no short reads.
-// Assumes partial reads are an error.
-static int http_read_stream_all(URLContext *h, uint8_t *buf, int size)
-{
- int pos = 0;
- while (pos < size) {
- int len = http_read_stream(h, buf + pos, size - pos);
- if (len < 0)
- return len;
- pos += len;
- }
- return pos;
-}
-
-static void update_metadata(HTTPContext *s, char *data)
-{
- char *key;
- char *val;
- char *end;
- char *next = data;
-
- while (*next) {
- key = next;
- val = strstr(key, "='");
- if (!val)
- break;
- end = strstr(val, "';");
- if (!end)
- break;
-
- *val = '\0';
- *end = '\0';
- val += 2;
-
- av_dict_set(&s->metadata, key, val, 0);
-
- next = end + 2;
- }
-}
-
-static int store_icy(URLContext *h, int size)
-{
- HTTPContext *s = h->priv_data;
- /* until next metadata packet */
- uint64_t remaining;
-
- if (s->icy_metaint < s->icy_data_read)
- return AVERROR_INVALIDDATA;
- remaining = s->icy_metaint - s->icy_data_read;
-
- if (!remaining) {
- /* The metadata packet is variable sized. It has a 1 byte header
- * which sets the length of the packet (divided by 16). If it's 0,
- * the metadata doesn't change. After the packet, icy_metaint bytes
- * of normal data follows. */
- uint8_t ch;
- int len = http_read_stream_all(h, &ch, 1);
- if (len < 0)
- return len;
- if (ch > 0) {
- char data[255 * 16 + 1];
- int ret;
- len = ch * 16;
- ret = http_read_stream_all(h, data, len);
- if (ret < 0)
- return ret;
- data[len + 1] = 0;
- if ((ret = av_opt_set(s, "icy_metadata_packet", data, 0)) < 0)
- return ret;
- update_metadata(s, data);
- }
- s->icy_data_read = 0;
- remaining = s->icy_metaint;
- }
-
- return FFMIN(size, remaining);
-}
-
-static int http_read(URLContext *h, uint8_t *buf, int size)
-{
- HTTPContext *s = h->priv_data;
-
- if (s->icy_metaint > 0) {
- size = store_icy(h, size);
- if (size < 0)
- return size;
- }
-
- size = http_read_stream(h, buf, size);
- if (size > 0)
- s->icy_data_read += size;
- return size;
-}
-
-/* used only when posting data */
-static int http_write(URLContext *h, const uint8_t *buf, int size)
-{
- char temp[11] = ""; /* 32-bit hex + CRLF + nul */
- int ret;
- char crlf[] = "\r\n";
- HTTPContext *s = h->priv_data;
-
- if (!s->chunked_post) {
- /* non-chunked data is sent without any special encoding */
- return ffurl_write(s->hd, buf, size);
- }
-
- /* silently ignore zero-size data since chunk encoding that would
- * signal EOF */
- if (size > 0) {
- /* upload data using chunked encoding */
- snprintf(temp, sizeof(temp), "%x\r\n", size);
-
- if ((ret = ffurl_write(s->hd, temp, strlen(temp))) < 0 ||
- (ret = ffurl_write(s->hd, buf, size)) < 0 ||
- (ret = ffurl_write(s->hd, crlf, sizeof(crlf) - 1)) < 0)
- return ret;
- }
- return size;
-}
-
-static int http_shutdown(URLContext *h, int flags)
-{
- int ret = 0;
- char footer[] = "0\r\n\r\n";
- HTTPContext *s = h->priv_data;
-
- /* signal end of chunked encoding if used */
- if (((flags & AVIO_FLAG_WRITE) && s->chunked_post) ||
- ((flags & AVIO_FLAG_READ) && s->chunked_post && s->listen)) {
- ret = ffurl_write(s->hd, footer, sizeof(footer) - 1);
- ret = ret > 0 ? 0 : ret;
- s->end_chunked_post = 1;
- }
-
- return ret;
-}
-
-static int http_close(URLContext *h)
-{
- int ret = 0;
- HTTPContext *s = h->priv_data;
-
-#if CONFIG_ZLIB
- inflateEnd(&s->inflate_stream);
- av_freep(&s->inflate_buffer);
-#endif /* CONFIG_ZLIB */
-
- if (!s->end_chunked_post)
- /* Close the write direction by sending the end of chunked encoding. */
- ret = http_shutdown(h, h->flags);
-
- if (s->hd)
- ffurl_closep(&s->hd);
- av_dict_free(&s->chained_options);
- return ret;
-}
-
-static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int force_reconnect)
-{
- HTTPContext *s = h->priv_data;
- URLContext *old_hd = s->hd;
- uint64_t old_off = s->off;
- uint8_t old_buf[BUFFER_SIZE];
- int old_buf_size, ret;
- AVDictionary *options = NULL;
-
- if (whence == AVSEEK_SIZE)
- return s->filesize;
- else if (!force_reconnect &&
- ((whence == SEEK_CUR && off == 0) ||
- (whence == SEEK_SET && off == s->off)))
- return s->off;
- else if ((s->filesize == UINT64_MAX && whence == SEEK_END) || h->is_streamed)
- return AVERROR(ENOSYS);
-
- if (whence == SEEK_CUR)
- off += s->off;
- else if (whence == SEEK_END)
- off += s->filesize;
- else if (whence != SEEK_SET)
- return AVERROR(EINVAL);
- if (off < 0)
- return AVERROR(EINVAL);
- s->off = off;
-
- /* we save the old context in case the seek fails */
- old_buf_size = s->buf_end - s->buf_ptr;
- memcpy(old_buf, s->buf_ptr, old_buf_size);
- s->hd = NULL;
-
- /* if it fails, continue on old connection */
- if ((ret = http_open_cnx(h, &options)) < 0) {
- av_dict_free(&options);
- memcpy(s->buffer, old_buf, old_buf_size);
- s->buf_ptr = s->buffer;
- s->buf_end = s->buffer + old_buf_size;
- s->hd = old_hd;
- s->off = old_off;
- return ret;
- }
- av_dict_free(&options);
- ffurl_close(old_hd);
- return off;
-}
-
-static int64_t http_seek(URLContext *h, int64_t off, int whence)
-{
- return http_seek_internal(h, off, whence, 0);
-}
-
-static int http_get_file_handle(URLContext *h)
-{
- HTTPContext *s = h->priv_data;
- return ffurl_get_file_handle(s->hd);
-}
-
-#define HTTP_CLASS(flavor) \
-static const AVClass flavor ## _context_class = { \
- .class_name = # flavor, \
- .item_name = av_default_item_name, \
- .option = options, \
- .version = LIBAVUTIL_VERSION_INT, \
-}
-
-#if CONFIG_HTTP_PROTOCOL
-HTTP_CLASS(http);
-
-URLProtocol ff_http_protocol = {
- .name = "http",
- .url_open2 = http_open,
- .url_accept = http_accept,
- .url_handshake = http_handshake,
- .url_read = http_read,
- .url_write = http_write,
- .url_seek = http_seek,
- .url_close = http_close,
- .url_get_file_handle = http_get_file_handle,
- .url_shutdown = http_shutdown,
- .priv_data_size = sizeof(HTTPContext),
- .priv_data_class = &http_context_class,
- .flags = URL_PROTOCOL_FLAG_NETWORK,
-};
-#endif /* CONFIG_HTTP_PROTOCOL */
-
-#if CONFIG_HTTPS_PROTOCOL
-HTTP_CLASS(https);
-
-URLProtocol ff_https_protocol = {
- .name = "https",
- .url_open2 = http_open,
- .url_read = http_read,
- .url_write = http_write,
- .url_seek = http_seek,
- .url_close = http_close,
- .url_get_file_handle = http_get_file_handle,
- .url_shutdown = http_shutdown,
- .priv_data_size = sizeof(HTTPContext),
- .priv_data_class = &https_context_class,
- .flags = URL_PROTOCOL_FLAG_NETWORK,
-};
-#endif /* CONFIG_HTTPS_PROTOCOL */
-
-#if CONFIG_HTTPPROXY_PROTOCOL
-static int http_proxy_close(URLContext *h)
-{
- HTTPContext *s = h->priv_data;
- if (s->hd)
- ffurl_closep(&s->hd);
- return 0;
-}
-
-static int http_proxy_open(URLContext *h, const char *uri, int flags)
-{
- HTTPContext *s = h->priv_data;
- char hostname[1024], hoststr[1024];
- char auth[1024], pathbuf[1024], *path;
- char lower_url[100];
- int port, ret = 0, attempts = 0;
- HTTPAuthType cur_auth_type;
- char *authstr;
- int new_loc;
-
- if( s->seekable == 1 )
- h->is_streamed = 0;
- else
- h->is_streamed = 1;
-
- av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,
- pathbuf, sizeof(pathbuf), uri);
- ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);
- path = pathbuf;
- if (*path == '/')
- path++;
-
- ff_url_join(lower_url, sizeof(lower_url), "tcp", NULL, hostname, port,
- NULL);
-redo:
- ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE,
- &h->interrupt_callback, NULL);
- if (ret < 0)
- return ret;
-
- authstr = ff_http_auth_create_response(&s->proxy_auth_state, auth,
- path, "CONNECT");
- snprintf(s->buffer, sizeof(s->buffer),
- "CONNECT %s HTTP/1.1\r\n"
- "Host: %s\r\n"
- "Connection: close\r\n"
- "%s%s"
- "\r\n",
- path,
- hoststr,
- authstr ? "Proxy-" : "", authstr ? authstr : "");
- av_freep(&authstr);
-
- if ((ret = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0)
- goto fail;
-
- s->buf_ptr = s->buffer;
- s->buf_end = s->buffer;
- s->line_count = 0;
- s->filesize = UINT64_MAX;
- cur_auth_type = s->proxy_auth_state.auth_type;
-
- /* Note: This uses buffering, potentially reading more than the
- * HTTP header. If tunneling a protocol where the server starts
- * the conversation, we might buffer part of that here, too.
- * Reading that requires using the proper ffurl_read() function
- * on this URLContext, not using the fd directly (as the tls
- * protocol does). This shouldn't be an issue for tls though,
- * since the client starts the conversation there, so there
- * is no extra data that we might buffer up here.
- */
- ret = http_read_header(h, &new_loc);
- if (ret < 0)
- goto fail;
-
- attempts++;
- if (s->http_code == 407 &&
- (cur_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) &&
- s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 2) {
- ffurl_closep(&s->hd);
- goto redo;
- }
-
- if (s->http_code < 400)
- return 0;
- ret = ff_http_averror(s->http_code, AVERROR(EIO));
-
-fail:
- http_proxy_close(h);
- return ret;
-}
-
-static int http_proxy_write(URLContext *h, const uint8_t *buf, int size)
-{
- HTTPContext *s = h->priv_data;
- return ffurl_write(s->hd, buf, size);
-}
-
-URLProtocol ff_httpproxy_protocol = {
- .name = "httpproxy",
- .url_open = http_proxy_open,
- .url_read = http_buf_read,
- .url_write = http_proxy_write,
- .url_close = http_proxy_close,
- .url_get_file_handle = http_get_file_handle,
- .priv_data_size = sizeof(HTTPContext),
- .flags = URL_PROTOCOL_FLAG_NETWORK,
-};
-#endif /* CONFIG_HTTPPROXY_PROTOCOL */
diff --git a/ffmpeg-2-8-11/libavformat/mpeg.c b/ffmpeg-2-8-11/libavformat/mpeg.c
deleted file mode 100644
index 24847ba..0000000
--- a/ffmpeg-2-8-11/libavformat/mpeg.c
+++ /dev/null
@@ -1,1037 +0,0 @@
-/*
- * MPEG1/2 demuxer
- * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "avformat.h"
-#include "internal.h"
-#include "mpeg.h"
-
-#if CONFIG_VOBSUB_DEMUXER
-# include "subtitles.h"
-# include "libavutil/bprint.h"
-# include "libavutil/opt.h"
-#endif
-
-#include "libavutil/avassert.h"
-
-/*********************************************/
-/* demux code */
-
-#define MAX_SYNC_SIZE 100000
-
-static int check_pes(const uint8_t *p, const uint8_t *end)
-{
- int pes1;
- int pes2 = (p[3] & 0xC0) == 0x80 &&
- (p[4] & 0xC0) != 0x40 &&
- ((p[4] & 0xC0) == 0x00 ||
- (p[4] & 0xC0) >> 2 == (p[6] & 0xF0));
-
- for (p += 3; p < end && *p == 0xFF; p++) ;
- if ((*p & 0xC0) == 0x40)
- p += 2;
-
- if ((*p & 0xF0) == 0x20)
- pes1 = p[0] & p[2] & p[4] & 1;
- else if ((*p & 0xF0) == 0x30)
- pes1 = p[0] & p[2] & p[4] & p[5] & p[7] & p[9] & 1;
- else
- pes1 = *p == 0x0F;
-
- return pes1 || pes2;
-}
-
-static int check_pack_header(const uint8_t *buf)
-{
- return (buf[1] & 0xC0) == 0x40 || (buf[1] & 0xF0) == 0x20;
-}
-
-static int mpegps_probe(AVProbeData *p)
-{
- uint32_t code = -1;
- int i;
- int sys = 0, pspack = 0, priv1 = 0, vid = 0;
- int audio = 0, invalid = 0, score = 0;
- int endpes = 0;
-
- for (i = 0; i < p->buf_size; i++) {
- code = (code << 8) + p->buf[i];
- if ((code & 0xffffff00) == 0x100) {
- int len = p->buf[i + 1] << 8 | p->buf[i + 2];
- int pes = endpes <= i && check_pes(p->buf + i, p->buf + p->buf_size);
- int pack = check_pack_header(p->buf + i);
-
- if (code == SYSTEM_HEADER_START_CODE)
- sys++;
- else if (code == PACK_START_CODE && pack)
- pspack++;
- else if ((code & 0xf0) == VIDEO_ID && pes) {
- endpes = i + len;
- vid++;
- }
- // skip pes payload to avoid start code emulation for private
- // and audio streams
- else if ((code & 0xe0) == AUDIO_ID && pes) {audio++; i+=len;}
- else if (code == PRIVATE_STREAM_1 && pes) {priv1++; i+=len;}
- else if (code == 0x1fd && pes) vid++; //VC1
-
- else if ((code & 0xf0) == VIDEO_ID && !pes) invalid++;
- else if ((code & 0xe0) == AUDIO_ID && !pes) invalid++;
- else if (code == PRIVATE_STREAM_1 && !pes) invalid++;
- }
- }
-
- if (vid + audio > invalid + 1) /* invalid VDR files nd short PES streams */
- score = AVPROBE_SCORE_EXTENSION / 2;
-
-// av_log(NULL, AV_LOG_ERROR, "vid:%d aud:%d sys:%d pspack:%d invalid:%d size:%d \n",
-// vid, audio, sys, pspack, invalid, p->buf_size);
-
- if (sys > invalid && sys * 9 <= pspack * 10)
- return (audio > 12 || vid > 3 || pspack > 2) ? AVPROBE_SCORE_EXTENSION + 2
- : AVPROBE_SCORE_EXTENSION / 2 + 1; // 1 more than mp3
- if (pspack > invalid && (priv1 + vid + audio) * 10 >= pspack * 9)
- return pspack > 2 ? AVPROBE_SCORE_EXTENSION + 2
- : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg
- if ((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys &&
- !pspack && p->buf_size > 2048 && vid + audio > invalid) /* PES stream */
- return (audio > 12 || vid > 6 + 2 * invalid) ? AVPROBE_SCORE_EXTENSION + 2
- : AVPROBE_SCORE_EXTENSION / 2;
-
- // 02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1
- // mp3_misidentified_2.mp3 has sys:0 priv1:0 pspack:0 vid:0 audio:6
- // Have\ Yourself\ a\ Merry\ Little\ Christmas.mp3 0 0 0 5 0 1 len:21618
- return score;
-}
-
-typedef struct MpegDemuxContext {
- AVClass *class;
- int32_t header_state;
- unsigned char psm_es_type[256];
- int sofdec;
- int dvd;
- int imkh_cctv;
-#if CONFIG_VOBSUB_DEMUXER
- AVFormatContext *sub_ctx;
- FFDemuxSubtitlesQueue q[32];
- char *sub_name;
-#endif
-} MpegDemuxContext;
-
-static int mpegps_read_header(AVFormatContext *s)
-{
- MpegDemuxContext *m = s->priv_data;
- char buffer[7];
- int64_t last_pos = avio_tell(s->pb);
-
- m->header_state = 0xff;
- s->ctx_flags |= AVFMTCTX_NOHEADER;
-
- avio_get_str(s->pb, 6, buffer, sizeof(buffer));
- if (!memcmp("IMKH", buffer, 4)) {
- m->imkh_cctv = 1;
- } else if (!memcmp("Sofdec", buffer, 6)) {
- m->sofdec = 1;
- } else
- avio_seek(s->pb, last_pos, SEEK_SET);
-
- /* no need to do more */
- return 0;
-}
-
-static int64_t get_pts(AVIOContext *pb, int c)
-{
- uint8_t buf[5];
-
- buf[0] = c < 0 ? avio_r8(pb) : c;
- avio_read(pb, buf + 1, 4);
-
- return ff_parse_pes_pts(buf);
-}
-
-static int find_next_start_code(AVIOContext *pb, int *size_ptr,
- int32_t *header_state)
-{
- unsigned int state, v;
- int val, n;
-
- state = *header_state;
- n = *size_ptr;
- while (n > 0) {
- if (avio_feof(pb))
- break;
- v = avio_r8(pb);
- n--;
- if (state == 0x000001) {
- state = ((state << 8) | v) & 0xffffff;
- val = state;
- goto found;
- }
- state = ((state << 8) | v) & 0xffffff;
- }
- val = -1;
-
-found:
- *header_state = state;
- *size_ptr = n;
- return val;
-}
-
-/**
- * Extract stream types from a program stream map
- * According to ISO/IEC 13818-1 ('MPEG-2 Systems') table 2-35
- *
- * @return number of bytes occupied by PSM in the bitstream
- */
-static long mpegps_psm_parse(MpegDemuxContext *m, AVIOContext *pb)
-{
- int psm_length, ps_info_length, es_map_length;
-
- psm_length = avio_rb16(pb);
- avio_r8(pb);
- avio_r8(pb);
- ps_info_length = avio_rb16(pb);
-
- /* skip program_stream_info */
- avio_skip(pb, ps_info_length);
- /*es_map_length = */avio_rb16(pb);
- /* Ignore es_map_length, trust psm_length */
- es_map_length = psm_length - ps_info_length - 10;
-
- /* at least one es available? */
- while (es_map_length >= 4) {
- unsigned char type = avio_r8(pb);
- unsigned char es_id = avio_r8(pb);
- uint16_t es_info_length = avio_rb16(pb);
-
- /* remember mapping from stream id to stream type */
- m->psm_es_type[es_id] = type;
- /* skip program_stream_info */
- avio_skip(pb, es_info_length);
- es_map_length -= 4 + es_info_length;
- }
- avio_rb32(pb); /* crc32 */
- return 2 + psm_length;
-}
-
-/* read the next PES header. Return its position in ppos
- * (if not NULL), and its start code, pts and dts.
- */
-static int mpegps_read_pes_header(AVFormatContext *s,
- int64_t *ppos, int *pstart_code,
- int64_t *ppts, int64_t *pdts)
-{
- MpegDemuxContext *m = s->priv_data;
- int len, size, startcode, c, flags, header_len;
- int pes_ext, ext2_len, id_ext, skip;
- int64_t pts, dts;
- int64_t last_sync = avio_tell(s->pb);
-
-error_redo:
- avio_seek(s->pb, last_sync, SEEK_SET);
-redo:
- /* next start code (should be immediately after) */
- m->header_state = 0xff;
- size = MAX_SYNC_SIZE;
- startcode = find_next_start_code(s->pb, &size, &m->header_state);
- last_sync = avio_tell(s->pb);
- if (startcode < 0) {
- if (avio_feof(s->pb))
- return AVERROR_EOF;
- // FIXME we should remember header_state
- return AVERROR(EAGAIN);
- }
-
- if (startcode == PACK_START_CODE)
- goto redo;
- if (startcode == SYSTEM_HEADER_START_CODE)
- goto redo;
- if (startcode == PADDING_STREAM) {
- avio_skip(s->pb, avio_rb16(s->pb));
- goto redo;
- }
- if (startcode == PRIVATE_STREAM_2) {
- if (!m->sofdec) {
- /* Need to detect whether this from a DVD or a 'Sofdec' stream */
- int len = avio_rb16(s->pb);
- int bytesread = 0;
- uint8_t *ps2buf = av_malloc(len);
-
- if (ps2buf) {
- bytesread = avio_read(s->pb, ps2buf, len);
-
- if (bytesread != len) {
- avio_skip(s->pb, len - bytesread);
- } else {
- uint8_t *p = 0;
- if (len >= 6)
- p = memchr(ps2buf, 'S', len - 5);
-
- if (p)
- m->sofdec = !memcmp(p+1, "ofdec", 5);
-
- m->sofdec -= !m->sofdec;
-
- if (m->sofdec < 0) {
- if (len == 980 && ps2buf[0] == 0) {
- /* PCI structure? */
- uint32_t startpts = AV_RB32(ps2buf + 0x0d);
- uint32_t endpts = AV_RB32(ps2buf + 0x11);
- uint8_t hours = ((ps2buf[0x19] >> 4) * 10) + (ps2buf[0x19] & 0x0f);
- uint8_t mins = ((ps2buf[0x1a] >> 4) * 10) + (ps2buf[0x1a] & 0x0f);
- uint8_t secs = ((ps2buf[0x1b] >> 4) * 10) + (ps2buf[0x1b] & 0x0f);
-
- m->dvd = (hours <= 23 &&
- mins <= 59 &&
- secs <= 59 &&
- (ps2buf[0x19] & 0x0f) < 10 &&
- (ps2buf[0x1a] & 0x0f) < 10 &&
- (ps2buf[0x1b] & 0x0f) < 10 &&
- endpts >= startpts);
- } else if (len == 1018 && ps2buf[0] == 1) {
- /* DSI structure? */
- uint8_t hours = ((ps2buf[0x1d] >> 4) * 10) + (ps2buf[0x1d] & 0x0f);
- uint8_t mins = ((ps2buf[0x1e] >> 4) * 10) + (ps2buf[0x1e] & 0x0f);
- uint8_t secs = ((ps2buf[0x1f] >> 4) * 10) + (ps2buf[0x1f] & 0x0f);
-
- m->dvd = (hours <= 23 &&
- mins <= 59 &&
- secs <= 59 &&
- (ps2buf[0x1d] & 0x0f) < 10 &&
- (ps2buf[0x1e] & 0x0f) < 10 &&
- (ps2buf[0x1f] & 0x0f) < 10);
- }
- }
- }
-
- av_free(ps2buf);
-
- /* If this isn't a DVD packet or no memory
- * could be allocated, just ignore it.
- * If we did, move back to the start of the
- * packet (plus 'length' field) */
- if (!m->dvd || avio_skip(s->pb, -(len + 2)) < 0) {
- /* Skip back failed.
- * This packet will be lost but that can't be helped
- * if we can't skip back
- */
- goto redo;
- }
- } else {
- /* No memory */
- avio_skip(s->pb, len);
- goto redo;
- }
- } else if (!m->dvd) {
- int len = avio_rb16(s->pb);
- avio_skip(s->pb, len);
- goto redo;
- }
- }
- if (startcode == PROGRAM_STREAM_MAP) {
- mpegps_psm_parse(m, s->pb);
- goto redo;
- }
-
- /* find matching stream */
- if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
- (startcode >= 0x1e0 && startcode <= 0x1ef) ||
- (startcode == 0x1bd) ||
- (startcode == PRIVATE_STREAM_2) ||
- (startcode == 0x1fd)))
- goto redo;
- if (ppos) {
- *ppos = avio_tell(s->pb) - 4;
- }
- len = avio_rb16(s->pb);
- pts =
- dts = AV_NOPTS_VALUE;
- if (startcode != PRIVATE_STREAM_2)
- {
- /* stuffing */
- for (;;) {
- if (len < 1)
- goto error_redo;
- c = avio_r8(s->pb);
- len--;
- /* XXX: for mpeg1, should test only bit 7 */
- if (c != 0xff)
- break;
- }
- if ((c & 0xc0) == 0x40) {
- /* buffer scale & size */
- avio_r8(s->pb);
- c = avio_r8(s->pb);
- len -= 2;
- }
- if ((c & 0xe0) == 0x20) {
- dts =
- pts = get_pts(s->pb, c);
- len -= 4;
- if (c & 0x10) {
- dts = get_pts(s->pb, -1);
- len -= 5;
- }
- } else if ((c & 0xc0) == 0x80) {
- /* mpeg 2 PES */
- flags = avio_r8(s->pb);
- header_len = avio_r8(s->pb);
- len -= 2;
- if (header_len > len)
- goto error_redo;
- len -= header_len;
- if (flags & 0x80) {
- dts = pts = get_pts(s->pb, -1);
- header_len -= 5;
- if (flags & 0x40) {
- dts = get_pts(s->pb, -1);
- header_len -= 5;
- }
- }
- if (flags & 0x3f && header_len == 0) {
- flags &= 0xC0;
- av_log(s, AV_LOG_WARNING, "Further flags set but no bytes left\n");
- }
- if (flags & 0x01) { /* PES extension */
- pes_ext = avio_r8(s->pb);
- header_len--;
- /* Skip PES private data, program packet sequence counter
- * and P-STD buffer */
- skip = (pes_ext >> 4) & 0xb;
- skip += skip & 0x9;
- if (pes_ext & 0x40 || skip > header_len) {
- av_log(s, AV_LOG_WARNING, "pes_ext %X is invalid\n", pes_ext);
- pes_ext = skip = 0;
- }
- avio_skip(s->pb, skip);
- header_len -= skip;
-
- if (pes_ext & 0x01) { /* PES extension 2 */
- ext2_len = avio_r8(s->pb);
- header_len--;
- if ((ext2_len & 0x7f) > 0) {
- id_ext = avio_r8(s->pb);
- if ((id_ext & 0x80) == 0)
- startcode = ((startcode & 0xff) << 8) | id_ext;
- header_len--;
- }
- }
- }
- if (header_len < 0)
- goto error_redo;
- avio_skip(s->pb, header_len);
- } else if (c != 0xf)
- goto redo;
- }
-
- if (startcode == PRIVATE_STREAM_1) {
- startcode = avio_r8(s->pb);
- len--;
- }
- if (len < 0)
- goto error_redo;
- if (dts != AV_NOPTS_VALUE && ppos) {
- int i;
- for (i = 0; i < s->nb_streams; i++) {
- if (startcode == s->streams[i]->id &&
- s->pb->seekable /* index useless on streams anyway */) {
- ff_reduce_index(s, i);
- av_add_index_entry(s->streams[i], *ppos, dts, 0, 0,
- AVINDEX_KEYFRAME /* FIXME keyframe? */);
- }
- }
- }
-
- *pstart_code = startcode;
- *ppts = pts;
- *pdts = dts;
- return len;
-}
-
-static int mpegps_read_packet(AVFormatContext *s,
- AVPacket *pkt)
-{
- MpegDemuxContext *m = s->priv_data;
- AVStream *st;
- int len, startcode, i, es_type, ret;
- int lpcm_header_len = -1; //Init to suppress warning
- int request_probe= 0;
- enum AVCodecID codec_id = AV_CODEC_ID_NONE;
- enum AVMediaType type;
- int64_t pts, dts, dummy_pos; // dummy_pos is needed for the index building to work
-
-redo:
- len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts);
- if (len < 0)
- return len;
-
- if (startcode >= 0x80 && startcode <= 0xcf) {
- if (len < 4)
- goto skip;
-
- /* audio: skip header */
- avio_r8(s->pb);
- lpcm_header_len = avio_rb16(s->pb);
- len -= 3;
- if (startcode >= 0xb0 && startcode <= 0xbf) {
- /* MLP/TrueHD audio has a 4-byte header */
- avio_r8(s->pb);
- len--;
- }
- }
-
- /* now find stream */
- for (i = 0; i < s->nb_streams; i++) {
- st = s->streams[i];
- if (st->id == startcode)
- goto found;
- }
-
- es_type = m->psm_es_type[startcode & 0xff];
- if (es_type == STREAM_TYPE_VIDEO_MPEG1) {
- codec_id = AV_CODEC_ID_MPEG2VIDEO;
- type = AVMEDIA_TYPE_VIDEO;
- } else if (es_type == STREAM_TYPE_VIDEO_MPEG2) {
- codec_id = AV_CODEC_ID_MPEG2VIDEO;
- type = AVMEDIA_TYPE_VIDEO;
- } else if (es_type == STREAM_TYPE_AUDIO_MPEG1 ||
- es_type == STREAM_TYPE_AUDIO_MPEG2) {
- codec_id = AV_CODEC_ID_MP3;
- type = AVMEDIA_TYPE_AUDIO;
- } else if (es_type == STREAM_TYPE_AUDIO_AAC) {
- codec_id = AV_CODEC_ID_AAC;
- type = AVMEDIA_TYPE_AUDIO;
- } else if (es_type == STREAM_TYPE_VIDEO_MPEG4) {
- codec_id = AV_CODEC_ID_MPEG4;
- type = AVMEDIA_TYPE_VIDEO;
- } else if (es_type == STREAM_TYPE_VIDEO_H264) {
- codec_id = AV_CODEC_ID_H264;
- type = AVMEDIA_TYPE_VIDEO;
- } else if (es_type == STREAM_TYPE_AUDIO_AC3) {
- codec_id = AV_CODEC_ID_AC3;
- type = AVMEDIA_TYPE_AUDIO;
- } else if (m->imkh_cctv && es_type == 0x91) {
- codec_id = AV_CODEC_ID_PCM_MULAW;
- type = AVMEDIA_TYPE_AUDIO;
- } else if (startcode >= 0x1e0 && startcode <= 0x1ef) {
- static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 };
- unsigned char buf[8];
-
- avio_read(s->pb, buf, 8);
- avio_seek(s->pb, -8, SEEK_CUR);
- if (!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1))
- codec_id = AV_CODEC_ID_CAVS;
- else
- request_probe= 1;
- type = AVMEDIA_TYPE_VIDEO;
- } else if (startcode == PRIVATE_STREAM_2) {
- type = AVMEDIA_TYPE_DATA;
- codec_id = AV_CODEC_ID_DVD_NAV;
- } else if (startcode >= 0x1c0 && startcode <= 0x1df) {
- type = AVMEDIA_TYPE_AUDIO;
- if (m->sofdec > 0) {
- codec_id = AV_CODEC_ID_ADPCM_ADX;
- // Auto-detect AC-3
- request_probe = 50;
- } else if (m->imkh_cctv && startcode == 0x1c0 && len > 80) {
- codec_id = AV_CODEC_ID_PCM_ALAW;
- request_probe = 50;
- } else {
- codec_id = AV_CODEC_ID_MP2;
- if (m->imkh_cctv)
- request_probe = 25;
- }
- } else if (startcode >= 0x80 && startcode <= 0x87) {
- type = AVMEDIA_TYPE_AUDIO;
- codec_id = AV_CODEC_ID_AC3;
- } else if ((startcode >= 0x88 && startcode <= 0x8f) ||
- (startcode >= 0x98 && startcode <= 0x9f)) {
- /* 0x90 - 0x97 is reserved for SDDS in DVD specs */
- type = AVMEDIA_TYPE_AUDIO;
- codec_id = AV_CODEC_ID_DTS;
- } else if (startcode >= 0xa0 && startcode <= 0xaf) {
- type = AVMEDIA_TYPE_AUDIO;
- if (lpcm_header_len == 6) {
- codec_id = AV_CODEC_ID_MLP;
- } else {
- codec_id = AV_CODEC_ID_PCM_DVD;
- }
- } else if (startcode >= 0xb0 && startcode <= 0xbf) {
- type = AVMEDIA_TYPE_AUDIO;
- codec_id = AV_CODEC_ID_TRUEHD;
- } else if (startcode >= 0xc0 && startcode <= 0xcf) {
- /* Used for both AC-3 and E-AC-3 in EVOB files */
- type = AVMEDIA_TYPE_AUDIO;
- codec_id = AV_CODEC_ID_AC3;
- } else if (startcode >= 0x20 && startcode <= 0x3f) {
- type = AVMEDIA_TYPE_SUBTITLE;
- codec_id = AV_CODEC_ID_DVD_SUBTITLE;
- } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) {
- type = AVMEDIA_TYPE_VIDEO;
- codec_id = AV_CODEC_ID_VC1;
- } else {
-skip:
- /* skip packet */
- avio_skip(s->pb, len);
- goto redo;
- }
- /* no stream found: add a new stream */
- st = avformat_new_stream(s, NULL);
- if (!st)
- goto skip;
- st->id = startcode;
- st->codec->codec_type = type;
- st->codec->codec_id = codec_id;
- if ( st->codec->codec_id == AV_CODEC_ID_PCM_MULAW
- || st->codec->codec_id == AV_CODEC_ID_PCM_ALAW) {
- st->codec->channels = 1;
- st->codec->channel_layout = AV_CH_LAYOUT_MONO;
- st->codec->sample_rate = 8000;
- }
- st->request_probe = request_probe;
- st->need_parsing = AVSTREAM_PARSE_FULL;
-
-found:
- if (st->discard >= AVDISCARD_ALL)
- goto skip;
- if (startcode >= 0xa0 && startcode <= 0xaf) {
- if (st->codec->codec_id == AV_CODEC_ID_MLP) {
- if (len < 6)
- goto skip;
- avio_skip(s->pb, 6);
- len -=6;
- }
- }
- ret = av_get_packet(s->pb, pkt, len);
-
- pkt->pts = pts;
- pkt->dts = dts;
- pkt->pos = dummy_pos;
- pkt->stream_index = st->index;
-
- if (s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_TRACE, "%d: pts=%0.3f dts=%0.3f size=%d\n",
- pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0,
- pkt->size);
-
- return (ret < 0) ? ret : 0;
-}
-
-static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,
- int64_t *ppos, int64_t pos_limit)
-{
- int len, startcode;
- int64_t pos, pts, dts;
-
- pos = *ppos;
- if (avio_seek(s->pb, pos, SEEK_SET) < 0)
- return AV_NOPTS_VALUE;
-
- for (;;) {
- len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts);
- if (len < 0) {
- if (s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_TRACE, "none (ret=%d)\n", len);
- return AV_NOPTS_VALUE;
- }
- if (startcode == s->streams[stream_index]->id &&
- dts != AV_NOPTS_VALUE) {
- break;
- }
- avio_skip(s->pb, len);
- }
- if (s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_TRACE, "pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n",
- pos, dts, dts / 90000.0);
- *ppos = pos;
- return dts;
-}
-
-AVInputFormat ff_mpegps_demuxer = {
- .name = "mpeg",
- .long_name = NULL_IF_CONFIG_SMALL("MPEG-PS (MPEG-2 Program Stream)"),
- .priv_data_size = sizeof(MpegDemuxContext),
- .read_probe = mpegps_probe,
- .read_header = mpegps_read_header,
- .read_packet = mpegps_read_packet,
- .read_timestamp = mpegps_read_dts,
- .flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
-};
-
-#if CONFIG_VOBSUB_DEMUXER
-
-#define REF_STRING "# VobSub index file,"
-#define MAX_LINE_SIZE 2048
-
-static int vobsub_probe(AVProbeData *p)
-{
- if (!strncmp(p->buf, REF_STRING, sizeof(REF_STRING) - 1))
- return AVPROBE_SCORE_MAX;
- return 0;
-}
-
-static int vobsub_read_header(AVFormatContext *s)
-{
- int i, ret = 0, header_parsed = 0, langidx = 0;
- MpegDemuxContext *vobsub = s->priv_data;
- size_t fname_len;
- char *header_str;
- AVBPrint header;
- int64_t delay = 0;
- AVStream *st = NULL;
- int stream_id = -1;
- char id[64] = {0};
- char alt[MAX_LINE_SIZE] = {0};
- AVInputFormat *iformat;
-
- if (!vobsub->sub_name) {
- char *ext;
- vobsub->sub_name = av_strdup(s->filename);
- if (!vobsub->sub_name) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
-
- fname_len = strlen(vobsub->sub_name);
- ext = vobsub->sub_name - 3 + fname_len;
- if (fname_len < 4 || *(ext - 1) != '.') {
- av_log(s, AV_LOG_ERROR, "The input index filename is too short "
- "to guess the associated .SUB file\n");
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- memcpy(ext, !strncmp(ext, "IDX", 3) ? "SUB" : "sub", 3);
- av_log(s, AV_LOG_VERBOSE, "IDX/SUB: %s -> %s\n", s->filename, vobsub->sub_name);
- }
-
- if (!(iformat = av_find_input_format("mpeg"))) {
- ret = AVERROR_DEMUXER_NOT_FOUND;
- goto end;
- }
-
- vobsub->sub_ctx = avformat_alloc_context();
- if (!vobsub->sub_ctx) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
-
- if ((ret = ff_copy_whitelists(vobsub->sub_ctx, s)) < 0)
- goto end;
-
- ret = avformat_open_input(&vobsub->sub_ctx, vobsub->sub_name, iformat, NULL);
- if (ret < 0) {
- av_log(s, AV_LOG_ERROR, "Unable to open %s as MPEG subtitles\n", vobsub->sub_name);
- goto end;
- }
-
- av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED);
- while (!avio_feof(s->pb)) {
- char line[MAX_LINE_SIZE];
- int len = ff_get_line(s->pb, line, sizeof(line));
-
- if (!len)
- break;
-
- line[strcspn(line, "\r\n")] = 0;
-
- if (!strncmp(line, "id:", 3)) {
- if (sscanf(line, "id: %63[^,], index: %u", id, &stream_id) != 2) {
- av_log(s, AV_LOG_WARNING, "Unable to parse index line '%s', "
- "assuming 'id: und, index: 0'\n", line);
- strcpy(id, "und");
- stream_id = 0;
- }
-
- if (stream_id >= FF_ARRAY_ELEMS(vobsub->q)) {
- av_log(s, AV_LOG_ERROR, "Maximum number of subtitles streams reached\n");
- ret = AVERROR(EINVAL);
- goto end;
- }
-
- header_parsed = 1;
- alt[0] = '\0';
- /* We do not create the stream immediately to avoid adding empty
- * streams. See the following timestamp entry. */
-
- av_log(s, AV_LOG_DEBUG, "IDX stream[%d] id=%s\n", stream_id, id);
-
- } else if (!strncmp(line, "timestamp:", 10)) {
- AVPacket *sub;
- int hh, mm, ss, ms;
- int64_t pos, timestamp;
- const char *p = line + 10;
-
- if (stream_id == -1) {
- av_log(s, AV_LOG_ERROR, "Timestamp declared before any stream\n");
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
-
- if (!st || st->id != stream_id) {
- st = avformat_new_stream(s, NULL);
- if (!st) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
- st->id = stream_id;
- st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
- st->codec->codec_id = AV_CODEC_ID_DVD_SUBTITLE;
- avpriv_set_pts_info(st, 64, 1, 1000);
- av_dict_set(&st->metadata, "language", id, 0);
- if (alt[0])
- av_dict_set(&st->metadata, "title", alt, 0);
- }
-
- if (sscanf(p, "%02d:%02d:%02d:%03d, filepos: %"SCNx64,
- &hh, &mm, &ss, &ms, &pos) != 5) {
- av_log(s, AV_LOG_ERROR, "Unable to parse timestamp line '%s', "
- "abort parsing\n", line);
- ret = AVERROR_INVALIDDATA;
- goto end;
- }
- timestamp = (hh*3600LL + mm*60LL + ss) * 1000LL + ms + delay;
- timestamp = av_rescale_q(timestamp, av_make_q(1, 1000), st->time_base);
-
- sub = ff_subtitles_queue_insert(&vobsub->q[s->nb_streams - 1], "", 0, 0);
- if (!sub) {
- ret = AVERROR(ENOMEM);
- goto end;
- }
- sub->pos = pos;
- sub->pts = timestamp;
- sub->stream_index = s->nb_streams - 1;
-
- } else if (!strncmp(line, "alt:", 4)) {
- const char *p = line + 4;
-
- while (*p == ' ')
- p++;
- av_log(s, AV_LOG_DEBUG, "IDX stream[%d] name=%s\n", stream_id, p);
- av_strlcpy(alt, p, sizeof(alt));
- header_parsed = 1;
-
- } else if (!strncmp(line, "delay:", 6)) {
- int sign = 1, hh = 0, mm = 0, ss = 0, ms = 0;
- const char *p = line + 6;
-
- while (*p == ' ')
- p++;
- if (*p == '-' || *p == '+') {
- sign = *p == '-' ? -1 : 1;
- p++;
- }
- sscanf(p, "%d:%d:%d:%d", &hh, &mm, &ss, &ms);
- delay = ((hh*3600LL + mm*60LL + ss) * 1000LL + ms) * sign;
-
- } else if (!strncmp(line, "langidx:", 8)) {
- const char *p = line + 8;
-
- if (sscanf(p, "%d", &langidx) != 1)
- av_log(s, AV_LOG_ERROR, "Invalid langidx specified\n");
-
- } else if (!header_parsed) {
- if (line[0] && line[0] != '#')
- av_bprintf(&header, "%s\n", line);
- }
- }
-
- if (langidx < s->nb_streams)
- s->streams[langidx]->disposition |= AV_DISPOSITION_DEFAULT;
-
- for (i = 0; i < s->nb_streams; i++) {
- vobsub->q[i].sort = SUB_SORT_POS_TS;
- ff_subtitles_queue_finalize(&vobsub->q[i]);
- }
-
- if (!av_bprint_is_complete(&header)) {
- av_bprint_finalize(&header, NULL);
- ret = AVERROR(ENOMEM);
- goto end;
- }
- av_bprint_finalize(&header, &header_str);
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *sub_st = s->streams[i];
- sub_st->codec->extradata = av_strdup(header_str);
- sub_st->codec->extradata_size = header.len;
- }
- av_free(header_str);
-
-end:
- return ret;
-}
-
-static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
- MpegDemuxContext *vobsub = s->priv_data;
- FFDemuxSubtitlesQueue *q;
- AVIOContext *pb = vobsub->sub_ctx->pb;
- int ret, psize, total_read = 0, i;
- AVPacket idx_pkt;
-
- int64_t min_ts = INT64_MAX;
- int sid = 0;
- for (i = 0; i < s->nb_streams; i++) {
- FFDemuxSubtitlesQueue *tmpq = &vobsub->q[i];
- int64_t ts;
- av_assert0(tmpq->nb_subs);
- ts = tmpq->subs[tmpq->current_sub_idx].pts;
- if (ts < min_ts) {
- min_ts = ts;
- sid = i;
- }
- }
- q = &vobsub->q[sid];
- ret = ff_subtitles_queue_read_packet(q, &idx_pkt);
- if (ret < 0)
- return ret;
-
- /* 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 - idx_pkt.pos;
- } else {
- int64_t fsize = avio_size(pb);
- psize = fsize < 0 ? 0xffff : fsize - idx_pkt.pos;
- }
-
- avio_seek(pb, idx_pkt.pos, SEEK_SET);
-
- av_init_packet(pkt);
- pkt->size = 0;
- pkt->data = NULL;
-
- do {
- int n, to_read, startcode;
- int64_t pts, dts;
- int64_t old_pos = avio_tell(pb), new_pos;
- int pkt_size;
-
- ret = mpegps_read_pes_header(vobsub->sub_ctx, NULL, &startcode, &pts, &dts);
- if (ret < 0) {
- if (pkt->size) // raise packet even if incomplete
- break;
- goto fail;
- }
- to_read = ret & 0xffff;
- new_pos = avio_tell(pb);
- pkt_size = ret + (new_pos - old_pos);
-
- /* this prevents reads above the current packet */
- if (total_read + pkt_size > psize)
- break;
- total_read += pkt_size;
-
- /* the current chunk doesn't match the stream index (unlikely) */
- if ((startcode & 0x1f) != s->streams[idx_pkt.stream_index]->id)
- break;
-
- ret = av_grow_packet(pkt, to_read);
- if (ret < 0)
- goto fail;
-
- n = avio_read(pb, pkt->data + (pkt->size - to_read), to_read);
- if (n < to_read)
- pkt->size -= to_read - n;
- } while (total_read < psize);
-
- pkt->pts = pkt->dts = idx_pkt.pts;
- pkt->pos = idx_pkt.pos;
- pkt->stream_index = idx_pkt.stream_index;
-
- av_free_packet(&idx_pkt);
- return 0;
-
-fail:
- av_free_packet(pkt);
- av_free_packet(&idx_pkt);
- return ret;
-}
-
-static int vobsub_read_seek(AVFormatContext *s, int stream_index,
- int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
-{
- MpegDemuxContext *vobsub = s->priv_data;
-
- /* Rescale requested timestamps based on the first stream (timebase is the
- * same for all subtitles stream within a .idx/.sub). Rescaling is done just
- * like in avformat_seek_file(). */
- if (stream_index == -1 && s->nb_streams != 1) {
- int i, ret = 0;
- AVRational time_base = s->streams[0]->time_base;
- ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base);
- min_ts = av_rescale_rnd(min_ts, time_base.den,
- time_base.num * (int64_t)AV_TIME_BASE,
- AV_ROUND_UP | AV_ROUND_PASS_MINMAX);
- max_ts = av_rescale_rnd(max_ts, time_base.den,
- time_base.num * (int64_t)AV_TIME_BASE,
- AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
- for (i = 0; i < s->nb_streams; i++) {
- int r = ff_subtitles_queue_seek(&vobsub->q[i], s, stream_index,
- min_ts, ts, max_ts, flags);
- if (r < 0)
- ret = r;
- }
- return ret;
- }
-
- if (stream_index == -1) // only 1 stream
- stream_index = 0;
- return ff_subtitles_queue_seek(&vobsub->q[stream_index], s, stream_index,
- min_ts, ts, max_ts, flags);
-}
-
-static int vobsub_read_close(AVFormatContext *s)
-{
- int i;
- MpegDemuxContext *vobsub = s->priv_data;
-
- for (i = 0; i < s->nb_streams; i++)
- ff_subtitles_queue_clean(&vobsub->q[i]);
- if (vobsub->sub_ctx)
- avformat_close_input(&vobsub->sub_ctx);
- return 0;
-}
-
-static const AVOption options[] = {
- { "sub_name", "URI for .sub file", offsetof(MpegDemuxContext, sub_name), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
- { NULL }
-};
-
-static const AVClass vobsub_demuxer_class = {
- .class_name = "vobsub",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-AVInputFormat ff_vobsub_demuxer = {
- .name = "vobsub",
- .long_name = NULL_IF_CONFIG_SMALL("VobSub subtitle format"),
- .priv_data_size = sizeof(MpegDemuxContext),
- .read_probe = vobsub_probe,
- .read_header = vobsub_read_header,
- .read_packet = vobsub_read_packet,
- .read_seek2 = vobsub_read_seek,
- .read_close = vobsub_read_close,
- .flags = AVFMT_SHOW_IDS,
- .extensions = "idx",
- .priv_class = &vobsub_demuxer_class,
-};
-#endif
diff --git a/ffmpeg-2-8-11/libavformat/mux.c b/ffmpeg-2-8-11/libavformat/mux.c
deleted file mode 100644
index 8d5867c..0000000
--- a/ffmpeg-2-8-11/libavformat/mux.c
+++ /dev/null
@@ -1,1121 +0,0 @@
-/*
- * muxing functions for use within FFmpeg
- * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include "avformat.h"
-#include "avio_internal.h"
-#include "internal.h"
-#include "libavcodec/internal.h"
-#include "libavcodec/bytestream.h"
-#include "libavutil/opt.h"
-#include "libavutil/dict.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/timestamp.h"
-#include "metadata.h"
-#include "id3v2.h"
-#include "libavutil/avassert.h"
-#include "libavutil/avstring.h"
-#include "libavutil/internal.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/parseutils.h"
-#include "libavutil/time.h"
-#include "riff.h"
-#include "audiointerleave.h"
-#include "url.h"
-#include <stdarg.h>
-#if CONFIG_NETWORK
-#include "network.h"
-#endif
-
-/**
- * @file
- * muxing functions for use within libavformat
- */
-
-/* fraction handling */
-
-/**
- * f = val + (num / den) + 0.5.
- *
- * 'num' is normalized so that it is such as 0 <= num < den.
- *
- * @param f fractional number
- * @param val integer value
- * @param num must be >= 0
- * @param den must be >= 1
- */
-static void frac_init(FFFrac *f, int64_t val, int64_t num, int64_t den)
-{
- num += (den >> 1);
- if (num >= den) {
- val += num / den;
- num = num % den;
- }
- f->val = val;
- f->num = num;
- f->den = den;
-}
-
-/**
- * Fractional addition to f: f = f + (incr / f->den).
- *
- * @param f fractional number
- * @param incr increment, can be positive or negative
- */
-static void frac_add(FFFrac *f, int64_t incr)
-{
- int64_t num, den;
-
- num = f->num + incr;
- den = f->den;
- if (num < 0) {
- f->val += num / den;
- num = num % den;
- if (num < 0) {
- num += den;
- f->val--;
- }
- } else if (num >= den) {
- f->val += num / den;
- num = num % den;
- }
- f->num = num;
-}
-
-AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precision)
-{
- AVRational q;
- int j;
-
- q = st->time_base;
-
- for (j=2; j<14; j+= 1+(j>2))
- while (q.den / q.num < min_precision && q.num % j == 0)
- q.num /= j;
- while (q.den / q.num < min_precision && q.den < (1<<24))
- q.den <<= 1;
-
- return q;
-}
-
-enum AVChromaLocation ff_choose_chroma_location(AVFormatContext *s, AVStream *st)
-{
- AVCodecContext *avctx = st->codec;
- const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(avctx->pix_fmt);
-
- if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED)
- return avctx->chroma_sample_location;
-
- if (pix_desc) {
- if (pix_desc->log2_chroma_h == 0) {
- return AVCHROMA_LOC_TOPLEFT;
- } else if (pix_desc->log2_chroma_w == 1 && pix_desc->log2_chroma_h == 1) {
- if (avctx->field_order == AV_FIELD_UNKNOWN || avctx->field_order == AV_FIELD_PROGRESSIVE) {
- switch (avctx->codec_id) {
- case AV_CODEC_ID_MJPEG:
- case AV_CODEC_ID_MPEG1VIDEO: return AVCHROMA_LOC_CENTER;
- }
- }
- if (avctx->field_order == AV_FIELD_UNKNOWN || avctx->field_order != AV_FIELD_PROGRESSIVE) {
- switch (avctx->codec_id) {
- case AV_CODEC_ID_MPEG2VIDEO: return AVCHROMA_LOC_LEFT;
- }
- }
- }
- }
-
- return AVCHROMA_LOC_UNSPECIFIED;
-
-}
-
-int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat,
- const char *format, const char *filename)
-{
- AVFormatContext *s = avformat_alloc_context();
- int ret = 0;
-
- *avctx = NULL;
- if (!s)
- goto nomem;
-
- if (!oformat) {
- if (format) {
- oformat = av_guess_format(format, NULL, NULL);
- if (!oformat) {
- av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format);
- ret = AVERROR(EINVAL);
- goto error;
- }
- } else {
- oformat = av_guess_format(NULL, filename, NULL);
- if (!oformat) {
- ret = AVERROR(EINVAL);
- av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'\n",
- filename);
- goto error;
- }
- }
- }
-
- s->oformat = oformat;
- if (s->oformat->priv_data_size > 0) {
- s->priv_data = av_mallocz(s->oformat->priv_data_size);
- if (!s->priv_data)
- goto nomem;
- if (s->oformat->priv_class) {
- *(const AVClass**)s->priv_data= s->oformat->priv_class;
- av_opt_set_defaults(s->priv_data);
- }
- } else
- s->priv_data = NULL;
-
- if (filename)
- av_strlcpy(s->filename, filename, sizeof(s->filename));
- *avctx = s;
- return 0;
-nomem:
- av_log(s, AV_LOG_ERROR, "Out of memory\n");
- ret = AVERROR(ENOMEM);
-error:
- avformat_free_context(s);
- return ret;
-}
-
-static int validate_codec_tag(AVFormatContext *s, AVStream *st)
-{
- const AVCodecTag *avctag;
- int n;
- enum AVCodecID id = AV_CODEC_ID_NONE;
- int64_t tag = -1;
-
- /**
- * Check that tag + id is in the table
- * If neither is in the table -> OK
- * If tag is in the table with another id -> FAIL
- * If id is in the table with another tag -> FAIL unless strict < normal
- */
- for (n = 0; s->oformat->codec_tag[n]; n++) {
- avctag = s->oformat->codec_tag[n];
- while (avctag->id != AV_CODEC_ID_NONE) {
- if (avpriv_toupper4(avctag->tag) == avpriv_toupper4(st->codec->codec_tag)) {
- id = avctag->id;
- if (id == st->codec->codec_id)
- return 1;
- }
- if (avctag->id == st->codec->codec_id)
- tag = avctag->tag;
- avctag++;
- }
- }
- if (id != AV_CODEC_ID_NONE)
- return 0;
- if (tag >= 0 && (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL))
- return 0;
- return 1;
-}
-
-
-static int init_muxer(AVFormatContext *s, AVDictionary **options)
-{
- int ret = 0, i;
- AVStream *st;
- AVDictionary *tmp = NULL;
- AVCodecContext *codec = NULL;
- AVOutputFormat *of = s->oformat;
- AVDictionaryEntry *e;
-
- if (options)
- av_dict_copy(&tmp, *options, 0);
-
- if ((ret = av_opt_set_dict(s, &tmp)) < 0)
- goto fail;
- if (s->priv_data && s->oformat->priv_class && *(const AVClass**)s->priv_data==s->oformat->priv_class &&
- (ret = av_opt_set_dict2(s->priv_data, &tmp, AV_OPT_SEARCH_CHILDREN)) < 0)
- goto fail;
-
- if (s->nb_streams && s->streams[0]->codec->flags & AV_CODEC_FLAG_BITEXACT) {
- if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
-#if FF_API_LAVF_BITEXACT
- av_log(s, AV_LOG_WARNING,
- "Setting the AVFormatContext to bitexact mode, because "
- "the AVCodecContext is in that mode. This behavior will "
- "change in the future. To keep the current behavior, set "
- "AVFormatContext.flags |= AVFMT_FLAG_BITEXACT.\n");
- s->flags |= AVFMT_FLAG_BITEXACT;
-#else
- av_log(s, AV_LOG_WARNING,
- "The AVFormatContext is not in set to bitexact mode, only "
- "the AVCodecContext. If this is not intended, set "
- "AVFormatContext.flags |= AVFMT_FLAG_BITEXACT.\n");
-#endif
- }
- }
-
- // some sanity checks
- if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) {
- av_log(s, AV_LOG_ERROR, "No streams to mux were specified\n");
- ret = AVERROR(EINVAL);
- goto fail;
- }
-
- for (i = 0; i < s->nb_streams; i++) {
- st = s->streams[i];
- codec = st->codec;
-
-#if FF_API_LAVF_CODEC_TB
-FF_DISABLE_DEPRECATION_WARNINGS
- if (!st->time_base.num && codec->time_base.num) {
- av_log(s, AV_LOG_WARNING, "Using AVStream.codec.time_base as a "
- "timebase hint to the muxer is deprecated. Set "
- "AVStream.time_base instead.\n");
- avpriv_set_pts_info(st, 64, codec->time_base.num, codec->time_base.den);
- }
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
- if (!st->time_base.num) {
- /* fall back on the default timebase values */
- if (codec->codec_type == AVMEDIA_TYPE_AUDIO && codec->sample_rate)
- avpriv_set_pts_info(st, 64, 1, codec->sample_rate);
- else
- avpriv_set_pts_info(st, 33, 1, 90000);
- }
-
- switch (codec->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- if (codec->sample_rate <= 0) {
- av_log(s, AV_LOG_ERROR, "sample rate not set\n");
- ret = AVERROR(EINVAL);
- goto fail;
- }
- if (!codec->block_align)
- codec->block_align = codec->channels *
- av_get_bits_per_sample(codec->codec_id) >> 3;
- break;
- case AVMEDIA_TYPE_VIDEO:
- if ((codec->width <= 0 || codec->height <= 0) &&
- !(of->flags & AVFMT_NODIMENSIONS)) {
- av_log(s, AV_LOG_ERROR, "dimensions not set\n");
- ret = AVERROR(EINVAL);
- goto fail;
- }
- if (av_cmp_q(st->sample_aspect_ratio, codec->sample_aspect_ratio)
- && FFABS(av_q2d(st->sample_aspect_ratio) - av_q2d(codec->sample_aspect_ratio)) > 0.004*av_q2d(st->sample_aspect_ratio)
- ) {
- if (st->sample_aspect_ratio.num != 0 &&
- st->sample_aspect_ratio.den != 0 &&
- codec->sample_aspect_ratio.num != 0 &&
- codec->sample_aspect_ratio.den != 0) {
- av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "
- "(%d/%d) and encoder layer (%d/%d)\n",
- st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
- codec->sample_aspect_ratio.num,
- codec->sample_aspect_ratio.den);
- ret = AVERROR(EINVAL);
- goto fail;
- }
- }
- break;
- }
-
- if (of->codec_tag) {
- if ( codec->codec_tag
- && codec->codec_id == AV_CODEC_ID_RAWVIDEO
- && ( av_codec_get_tag(of->codec_tag, codec->codec_id) == 0
- || av_codec_get_tag(of->codec_tag, codec->codec_id) == MKTAG('r', 'a', 'w', ' '))
- && !validate_codec_tag(s, st)) {
- // the current rawvideo encoding system ends up setting
- // the wrong codec_tag for avi/mov, we override it here
- codec->codec_tag = 0;
- }
- if (codec->codec_tag) {
- if (!validate_codec_tag(s, st)) {
- char tagbuf[32], tagbuf2[32];
- av_get_codec_tag_string(tagbuf, sizeof(tagbuf), codec->codec_tag);
- av_get_codec_tag_string(tagbuf2, sizeof(tagbuf2), av_codec_get_tag(s->oformat->codec_tag, codec->codec_id));
- av_log(s, AV_LOG_ERROR,
- "Tag %s/0x%08x incompatible with output codec id '%d' (%s)\n",
- tagbuf, codec->codec_tag, codec->codec_id, tagbuf2);
- ret = AVERROR_INVALIDDATA;
- goto fail;
- }
- } else
- codec->codec_tag = av_codec_get_tag(of->codec_tag, codec->codec_id);
- }
-
- if (of->flags & AVFMT_GLOBALHEADER &&
- !(codec->flags & AV_CODEC_FLAG_GLOBAL_HEADER))
- av_log(s, AV_LOG_WARNING,
- "Codec for stream %d does not use global headers "
- "but container format requires global headers\n", i);
-
- if (codec->codec_type != AVMEDIA_TYPE_ATTACHMENT)
- s->internal->nb_interleaved_streams++;
- }
-
- if (!s->priv_data && of->priv_data_size > 0) {
- s->priv_data = av_mallocz(of->priv_data_size);
- if (!s->priv_data) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- if (of->priv_class) {
- *(const AVClass **)s->priv_data = of->priv_class;
- av_opt_set_defaults(s->priv_data);
- if ((ret = av_opt_set_dict2(s->priv_data, &tmp, AV_OPT_SEARCH_CHILDREN)) < 0)
- goto fail;
- }
- }
-
- /* set muxer identification string */
- if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
- av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0);
- } else {
- av_dict_set(&s->metadata, "encoder", NULL, 0);
- }
-
- for (e = NULL; e = av_dict_get(s->metadata, "encoder-", e, AV_DICT_IGNORE_SUFFIX); ) {
- av_dict_set(&s->metadata, e->key, NULL, 0);
- }
-
- if (options) {
- av_dict_free(options);
- *options = tmp;
- }
-
- return 0;
-
-fail:
- av_dict_free(&tmp);
- return ret;
-}
-
-static int init_pts(AVFormatContext *s)
-{
- int i;
- AVStream *st;
-
- /* init PTS generation */
- for (i = 0; i < s->nb_streams; i++) {
- int64_t den = AV_NOPTS_VALUE;
- st = s->streams[i];
-
- switch (st->codec->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- den = (int64_t)st->time_base.num * st->codec->sample_rate;
- break;
- case AVMEDIA_TYPE_VIDEO:
- den = (int64_t)st->time_base.num * st->codec->time_base.den;
- break;
- default:
- break;
- }
-
- if (!st->priv_pts)
- st->priv_pts = av_mallocz(sizeof(*st->priv_pts));
- if (!st->priv_pts)
- return AVERROR(ENOMEM);
-
- if (den != AV_NOPTS_VALUE) {
- if (den <= 0)
- return AVERROR_INVALIDDATA;
-
- frac_init(st->priv_pts, 0, 0, den);
- }
- }
-
- return 0;
-}
-
-int avformat_write_header(AVFormatContext *s, AVDictionary **options)
-{
- int ret = 0;
-
- if ((ret = init_muxer(s, options)) < 0)
- return ret;
-
- if (s->oformat->write_header) {
- ret = s->oformat->write_header(s);
- if (ret >= 0 && s->pb && s->pb->error < 0)
- ret = s->pb->error;
- if (ret < 0)
- return ret;
- if (s->flush_packets && s->pb && s->pb->error >= 0 && s->flags & AVFMT_FLAG_FLUSH_PACKETS)
- avio_flush(s->pb);
- }
-
- if ((ret = init_pts(s)) < 0)
- return ret;
-
- if (s->avoid_negative_ts < 0) {
- av_assert2(s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO);
- if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) {
- s->avoid_negative_ts = 0;
- } else
- s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE;
- }
-
- return 0;
-}
-
-#define AV_PKT_FLAG_UNCODED_FRAME 0x2000
-
-/* Note: using sizeof(AVFrame) from outside lavu is unsafe in general, but
- it is only being used internally to this file as a consistency check.
- The value is chosen to be very unlikely to appear on its own and to cause
- immediate failure if used anywhere as a real size. */
-#define UNCODED_FRAME_PACKET_SIZE (INT_MIN / 3 * 2 + (int)sizeof(AVFrame))
-
-
-//FIXME merge with compute_pkt_fields
-static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt)
-{
- int delay = FFMAX(st->codec->has_b_frames, st->codec->max_b_frames > 0);
- int num, den, i;
- int frame_size;
-
- if (s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_TRACE, "compute_pkt_fields2: 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->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) {
- av_log(s, AV_LOG_WARNING, "Packet with invalid duration %d 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;
-
- //XXX/FIXME this is a temporary hack until all encoders output pts
- if ((pkt->pts == 0 || pkt->pts == AV_NOPTS_VALUE) && pkt->dts == AV_NOPTS_VALUE && !delay) {
- static int warned;
- if (!warned) {
- av_log(s, AV_LOG_WARNING, "Encoder did not produce proper pts, making some up.\n");
- warned = 1;
- }
- pkt->dts =
-// pkt->pts= st->cur_dts;
- pkt->pts = st->priv_pts->val;
- }
-
- //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; i<delay && st->pts_buffer[i] > st->pts_buffer[i + 1]; i++)
- FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i + 1]);
-
- pkt->dts = st->pts_buffer[0];
- }
-
- if (st->cur_dts && st->cur_dts != AV_NOPTS_VALUE &&
- ((!(s->oformat->flags & AVFMT_TS_NONSTRICT) &&
- st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE &&
- st->cur_dts >= pkt->dts) || st->cur_dts > pkt->dts)) {
- av_log(s, AV_LOG_ERROR,
- "Application provided invalid, non monotonically increasing dts to muxer in stream %d: %s >= %s\n",
- st->index, av_ts2str(st->cur_dts), av_ts2str(pkt->dts));
- return AVERROR(EINVAL);
- }
- if (pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts) {
- av_log(s, AV_LOG_ERROR,
- "pts (%s) < dts (%s) in stream %d\n",
- av_ts2str(pkt->pts), av_ts2str(pkt->dts),
- st->index);
- return AVERROR(EINVAL);
- }
-
- if (s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_TRACE, "av_write_frame: pts2:%s dts2:%s\n",
- av_ts2str(pkt->pts), av_ts2str(pkt->dts));
-
- st->cur_dts = pkt->dts;
- st->priv_pts->val = pkt->dts;
-
- /* update pts */
- switch (st->codec->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- frame_size = (pkt->flags & AV_PKT_FLAG_UNCODED_FRAME) ?
- ((AVFrame *)pkt->data)->nb_samples :
- av_get_audio_frame_duration(st->codec, pkt->size);
-
- /* HACK/FIXME, we skip the initial 0 size packets as they are most
- * likely equal to the encoder delay, but it would be better if we
- * had the real timestamps from the encoder */
- if (frame_size >= 0 && (pkt->size || st->priv_pts->num != st->priv_pts->den >> 1 || st->priv_pts->val)) {
- frac_add(st->priv_pts, (int64_t)st->time_base.den * frame_size);
- }
- break;
- case AVMEDIA_TYPE_VIDEO:
- frac_add(st->priv_pts, (int64_t)st->time_base.den * st->codec->time_base.num);
- break;
- }
- return 0;
-}
-
-/**
- * Make timestamps non negative, move side data from payload to internal struct, call muxer, and restore
- * sidedata.
- *
- * FIXME: this function should NEVER get undefined pts/dts beside when the
- * AVFMT_NOTIMESTAMPS is set.
- * Those additional safety checks should be dropped once the correct checks
- * are set in the callers.
- */
-static int write_packet(AVFormatContext *s, AVPacket *pkt)
-{
- int ret, did_split;
-
- if (s->output_ts_offset) {
- AVStream *st = s->streams[pkt->stream_index];
- int64_t 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;
- }
-
- if (s->avoid_negative_ts > 0) {
- AVStream *st = s->streams[pkt->stream_index];
- int64_t offset = st->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 &&
- (ts < 0 || s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)) {
- s->internal->offset = -ts;
- s->internal->offset_timebase = st->time_base;
- }
-
- if (s->internal->offset != AV_NOPTS_VALUE && !offset) {
- offset = st->mux_ts_offset =
- av_rescale_q_rnd(s->internal->offset,
- s->internal->offset_timebase,
- st->time_base,
- AV_ROUND_UP);
- }
-
- if (pkt->dts != AV_NOPTS_VALUE)
- pkt->dts += offset;
- if (pkt->pts != AV_NOPTS_VALUE)
- pkt->pts += offset;
-
- if (s->internal->avoid_negative_ts_use_pts) {
- if (pkt->pts != AV_NOPTS_VALUE && pkt->pts < 0) {
- av_log(s, AV_LOG_WARNING, "failed to avoid negative "
- "pts %s in stream %d.\n"
- "Try -avoid_negative_ts 1 as a possible workaround.\n",
- av_ts2str(pkt->dts),
- pkt->stream_index
- );
- }
- } else {
- av_assert2(pkt->dts == AV_NOPTS_VALUE || pkt->dts >= 0 || s->max_interleave_delta > 0);
- if (pkt->dts != AV_NOPTS_VALUE && pkt->dts < 0) {
- av_log(s, AV_LOG_WARNING,
- "Packets poorly interleaved, failed to avoid negative "
- "timestamp %s in stream %d.\n"
- "Try -max_interleave_delta 0 as a possible workaround.\n",
- av_ts2str(pkt->dts),
- pkt->stream_index
- );
- }
- }
- }
-
- did_split = av_packet_split_side_data(pkt);
- if ((pkt->flags & AV_PKT_FLAG_UNCODED_FRAME)) {
- AVFrame *frame = (AVFrame *)pkt->data;
- av_assert0(pkt->size == UNCODED_FRAME_PACKET_SIZE);
- ret = s->oformat->write_uncoded_frame(s, pkt->stream_index, &frame, 0);
- av_frame_free(&frame);
- } else {
- ret = s->oformat->write_packet(s, pkt);
- }
-
- if (s->flush_packets && s->pb && ret >= 0 && s->flags & AVFMT_FLAG_FLUSH_PACKETS)
- avio_flush(s->pb);
-
- if (did_split)
- av_packet_merge_side_data(pkt);
-
- return ret;
-}
-
-static int check_packet(AVFormatContext *s, AVPacket *pkt)
-{
- if (!pkt)
- return 0;
-
- if (pkt->stream_index < 0 || pkt->stream_index >= s->nb_streams) {
- av_log(s, AV_LOG_ERROR, "Invalid packet stream index: %d\n",
- pkt->stream_index);
- return AVERROR(EINVAL);
- }
-
- if (s->streams[pkt->stream_index]->codec->codec_type == AVMEDIA_TYPE_ATTACHMENT) {
- av_log(s, AV_LOG_ERROR, "Received a packet for an attachment stream.\n");
- return AVERROR(EINVAL);
- }
-
- return 0;
-}
-
-int av_write_frame(AVFormatContext *s, AVPacket *pkt)
-{
- int ret;
-
- ret = check_packet(s, pkt);
- if (ret < 0)
- return ret;
-
- if (!pkt) {
- if (s->oformat->flags & AVFMT_ALLOW_FLUSH) {
- ret = s->oformat->write_packet(s, NULL);
- if (s->flush_packets && s->pb && s->pb->error >= 0 && s->flags & AVFMT_FLAG_FLUSH_PACKETS)
- avio_flush(s->pb);
- if (ret >= 0 && s->pb && s->pb->error < 0)
- ret = s->pb->error;
- return ret;
- }
- return 1;
- }
-
- ret = compute_pkt_fields2(s, s->streams[pkt->stream_index], pkt);
-
- if (ret < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
- return ret;
-
- ret = write_packet(s, pkt);
- if (ret >= 0 && s->pb && s->pb->error < 0)
- ret = s->pb->error;
-
- if (ret >= 0)
- s->streams[pkt->stream_index]->nb_frames++;
- return ret;
-}
-
-#define CHUNK_START 0x1000
-
-int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
- int (*compare)(AVFormatContext *, AVPacket *, AVPacket *))
-{
- int ret;
- AVPacketList **next_point, *this_pktl;
- AVStream *st = s->streams[pkt->stream_index];
- int chunked = s->max_chunk_size || s->max_chunk_duration;
-
- this_pktl = av_mallocz(sizeof(AVPacketList));
- if (!this_pktl)
- return AVERROR(ENOMEM);
- this_pktl->pkt = *pkt;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = NULL; // do not free original but only the copy
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- pkt->buf = NULL;
- pkt->side_data = NULL;
- pkt->side_data_elems = 0;
- if ((pkt->flags & AV_PKT_FLAG_UNCODED_FRAME)) {
- av_assert0(pkt->size == UNCODED_FRAME_PACKET_SIZE);
- av_assert0(((AVFrame *)pkt->data)->buf);
- } else {
- // Duplicate the packet if it uses non-allocated memory
- if ((ret = av_dup_packet(&this_pktl->pkt)) < 0) {
- av_free(this_pktl);
- return ret;
- }
- }
-
- if (s->streams[pkt->stream_index]->last_in_packet_buffer) {
- next_point = &(st->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;
- this_pktl->pkt.flags |= CHUNK_START;
- if (max && st->interleaver_chunk_duration > max) {
- int64_t syncoffset = (st->codec->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;
- } else
- st->interleaver_chunk_duration = 0;
- }
- }
- if (*next_point) {
- if (chunked && !(this_pktl->pkt.flags & CHUNK_START))
- goto next_non_null;
-
- if (compare(s, &s->internal->packet_buffer_end->pkt, pkt)) {
- while ( *next_point
- && ((chunked && !((*next_point)->pkt.flags&CHUNK_START))
- || !compare(s, &(*next_point)->pkt, pkt)))
- next_point = &(*next_point)->next;
- if (*next_point)
- goto next_non_null;
- } else {
- next_point = &(s->internal->packet_buffer_end->next);
- }
- }
- av_assert1(!*next_point);
-
- s->internal->packet_buffer_end = this_pktl;
-next_non_null:
-
- this_pktl->next = *next_point;
-
- s->streams[pkt->stream_index]->last_in_packet_buffer =
- *next_point = this_pktl;
-
- return 0;
-}
-
-static int interleave_compare_dts(AVFormatContext *s, AVPacket *next,
- AVPacket *pkt)
-{
- AVStream *st = s->streams[pkt->stream_index];
- AVStream *st2 = s->streams[next->stream_index];
- int comp = av_compare_ts(next->dts, st2->time_base, pkt->dts,
- st->time_base);
- if (s->audio_preload && ((st->codec->codec_type == AVMEDIA_TYPE_AUDIO) != (st2->codec->codec_type == AVMEDIA_TYPE_AUDIO))) {
- int64_t ts = av_rescale_q(pkt ->dts, st ->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st ->codec->codec_type == AVMEDIA_TYPE_AUDIO);
- int64_t ts2= av_rescale_q(next->dts, st2->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st2->codec->codec_type == AVMEDIA_TYPE_AUDIO);
- if (ts == ts2) {
- ts= ( pkt ->dts* st->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st ->codec->codec_type == AVMEDIA_TYPE_AUDIO)* st->time_base.den)*st2->time_base.den
- -( next->dts*st2->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st2->codec->codec_type == AVMEDIA_TYPE_AUDIO)*st2->time_base.den)* st->time_base.den;
- ts2=0;
- }
- comp= (ts>ts2) - (ts<ts2);
- }
-
- if (comp == 0)
- return pkt->stream_index < next->stream_index;
- return comp > 0;
-}
-
-int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
- AVPacket *pkt, int flush)
-{
- AVPacketList *pktl;
- int stream_count = 0;
- int noninterleaved_count = 0;
- int i, ret;
-
- if (pkt) {
- if ((ret = ff_interleave_add_packet(s, pkt, interleave_compare_dts)) < 0)
- return ret;
- }
-
- for (i = 0; i < s->nb_streams; i++) {
- if (s->streams[i]->last_in_packet_buffer) {
- ++stream_count;
- } else if (s->streams[i]->codec->codec_type != AVMEDIA_TYPE_ATTACHMENT &&
- s->streams[i]->codec->codec_id != AV_CODEC_ID_VP8 &&
- s->streams[i]->codec->codec_id != AV_CODEC_ID_VP9) {
- ++noninterleaved_count;
- }
- }
-
- if (s->internal->nb_interleaved_streams == stream_count)
- flush = 1;
-
- if (s->max_interleave_delta > 0 &&
- s->internal->packet_buffer &&
- !flush &&
- s->internal->nb_interleaved_streams == stream_count+noninterleaved_count
- ) {
- AVPacket *top_pkt = &s->internal->packet_buffer->pkt;
- int64_t delta_dts = INT64_MIN;
- int64_t top_dts = av_rescale_q(top_pkt->dts,
- s->streams[top_pkt->stream_index]->time_base,
- AV_TIME_BASE_Q);
-
- for (i = 0; i < s->nb_streams; i++) {
- int64_t last_dts;
- const AVPacketList *last = s->streams[i]->last_in_packet_buffer;
-
- if (!last)
- continue;
-
- last_dts = av_rescale_q(last->pkt.dts,
- s->streams[i]->time_base,
- AV_TIME_BASE_Q);
- delta_dts = FFMAX(delta_dts, last_dts - top_dts);
- }
-
- if (delta_dts > s->max_interleave_delta) {
- av_log(s, AV_LOG_DEBUG,
- "Delay between the first packet and last packet in the "
- "muxing queue is %"PRId64" > %"PRId64": forcing output\n",
- delta_dts, s->max_interleave_delta);
- flush = 1;
- }
- }
-
- if (stream_count && flush) {
- AVStream *st;
- pktl = s->internal->packet_buffer;
- *out = pktl->pkt;
- st = s->streams[out->stream_index];
-
- s->internal->packet_buffer = pktl->next;
- if (!s->internal->packet_buffer)
- s->internal->packet_buffer_end = NULL;
-
- if (st->last_in_packet_buffer == pktl)
- st->last_in_packet_buffer = NULL;
- av_freep(&pktl);
-
- return 1;
- } else {
- av_init_packet(out);
- return 0;
- }
-}
-
-/**
- * Interleave an AVPacket correctly so it can be muxed.
- * @param out the interleaved packet will be output here
- * @param in the input packet
- * @param flush 1 if no further packets are available as input and all
- * remaining packets should be output
- * @return 1 if a packet was output, 0 if no packet could be output,
- * < 0 if an error occurred
- */
-static int interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush)
-{
- if (s->oformat->interleave_packet) {
- int ret = s->oformat->interleave_packet(s, out, in, flush);
- if (in)
- av_free_packet(in);
- return ret;
- } else
- return ff_interleave_packet_per_dts(s, out, in, flush);
-}
-
-int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
-{
- int ret, flush = 0;
-
- ret = check_packet(s, pkt);
- if (ret < 0)
- goto fail;
-
- if (pkt) {
- AVStream *st = s->streams[pkt->stream_index];
-
- if (s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_TRACE, "av_interleaved_write_frame size:%d dts:%s pts:%s\n",
- pkt->size, av_ts2str(pkt->dts), av_ts2str(pkt->pts));
-
- if ((ret = compute_pkt_fields2(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
- goto fail;
-
- if (pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
- ret = AVERROR(EINVAL);
- goto fail;
- }
- } else {
- av_log(s, AV_LOG_TRACE, "av_interleaved_write_frame FLUSH\n");
- flush = 1;
- }
-
- for (;; ) {
- AVPacket opkt;
- int ret = interleave_packet(s, &opkt, pkt, flush);
- if (pkt) {
- memset(pkt, 0, sizeof(*pkt));
- av_init_packet(pkt);
- pkt = NULL;
- }
- if (ret <= 0) //FIXME cleanup needed for ret<0 ?
- return ret;
-
- ret = write_packet(s, &opkt);
- if (ret >= 0)
- s->streams[opkt.stream_index]->nb_frames++;
-
- av_free_packet(&opkt);
-
- if (ret < 0)
- return ret;
- if(s->pb && s->pb->error)
- return s->pb->error;
- }
-fail:
- av_packet_unref(pkt);
- return ret;
-}
-
-int av_write_trailer(AVFormatContext *s)
-{
- int ret, i;
-
- for (;; ) {
- AVPacket pkt;
- ret = interleave_packet(s, &pkt, NULL, 1);
- if (ret < 0)
- goto fail;
- if (!ret)
- break;
-
- ret = write_packet(s, &pkt);
- if (ret >= 0)
- s->streams[pkt.stream_index]->nb_frames++;
-
- av_free_packet(&pkt);
-
- if (ret < 0)
- goto fail;
- if(s->pb && s->pb->error)
- goto fail;
- }
-
-fail:
- if (s->oformat->write_trailer)
- if (ret >= 0) {
- ret = s->oformat->write_trailer(s);
- } else {
- s->oformat->write_trailer(s);
- }
-
- if (s->pb)
- avio_flush(s->pb);
- if (ret == 0)
- ret = s->pb ? s->pb->error : 0;
- for (i = 0; i < s->nb_streams; i++) {
- av_freep(&s->streams[i]->priv_data);
- av_freep(&s->streams[i]->index_entries);
- }
- if (s->oformat->priv_class)
- av_opt_free(s->priv_data);
- av_freep(&s->priv_data);
- return ret;
-}
-
-int av_get_output_timestamp(struct AVFormatContext *s, int stream,
- int64_t *dts, int64_t *wall)
-{
- if (!s->oformat || !s->oformat->get_output_timestamp)
- return AVERROR(ENOSYS);
- s->oformat->get_output_timestamp(s, stream, dts, wall);
- return 0;
-}
-
-int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
- AVFormatContext *src, int interleave)
-{
- AVPacket local_pkt;
- int ret;
-
- local_pkt = *pkt;
- local_pkt.stream_index = dst_stream;
- if (pkt->pts != AV_NOPTS_VALUE)
- local_pkt.pts = av_rescale_q(pkt->pts,
- src->streams[pkt->stream_index]->time_base,
- dst->streams[dst_stream]->time_base);
- if (pkt->dts != AV_NOPTS_VALUE)
- local_pkt.dts = av_rescale_q(pkt->dts,
- src->streams[pkt->stream_index]->time_base,
- dst->streams[dst_stream]->time_base);
- if (pkt->duration)
- local_pkt.duration = av_rescale_q(pkt->duration,
- src->streams[pkt->stream_index]->time_base,
- dst->streams[dst_stream]->time_base);
-
- if (interleave) ret = av_interleaved_write_frame(dst, &local_pkt);
- else ret = av_write_frame(dst, &local_pkt);
- pkt->buf = local_pkt.buf;
- pkt->side_data = local_pkt.side_data;
- pkt->side_data_elems = local_pkt.side_data_elems;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- pkt->destruct = local_pkt.destruct;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- return ret;
-}
-
-static int av_write_uncoded_frame_internal(AVFormatContext *s, int stream_index,
- AVFrame *frame, int interleaved)
-{
- AVPacket pkt, *pktp;
-
- av_assert0(s->oformat);
- if (!s->oformat->write_uncoded_frame)
- return AVERROR(ENOSYS);
-
- if (!frame) {
- pktp = NULL;
- } else {
- pktp = &pkt;
- av_init_packet(&pkt);
- pkt.data = (void *)frame;
- pkt.size = UNCODED_FRAME_PACKET_SIZE;
- pkt.pts =
- pkt.dts = frame->pts;
- pkt.duration = av_frame_get_pkt_duration(frame);
- 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);
-}
-
-int av_write_uncoded_frame(AVFormatContext *s, int stream_index,
- AVFrame *frame)
-{
- return av_write_uncoded_frame_internal(s, stream_index, frame, 0);
-}
-
-int av_interleaved_write_uncoded_frame(AVFormatContext *s, int stream_index,
- AVFrame *frame)
-{
- return av_write_uncoded_frame_internal(s, stream_index, frame, 1);
-}
-
-int av_write_uncoded_frame_query(AVFormatContext *s, int stream_index)
-{
- av_assert0(s->oformat);
- if (!s->oformat->write_uncoded_frame)
- return AVERROR(ENOSYS);
- return s->oformat->write_uncoded_frame(s, stream_index, NULL,
- AV_WRITE_UNCODED_FRAME_QUERY);
-}
diff --git a/ffmpeg-2-8-11/libavformat/utils.c b/ffmpeg-2-8-11/libavformat/utils.c
deleted file mode 100644
index abc90c3..0000000
--- a/ffmpeg-2-8-11/libavformat/utils.c
+++ /dev/null
@@ -1,4624 +0,0 @@
-/*
- * various utility functions for use within FFmpeg
- * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
- *
- * This file is part of FFmpeg.
- *
- * FFmpeg is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * FFmpeg is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <stdarg.h>
-#include <stdint.h>
-
-#include "config.h"
-
-#include "libavutil/avassert.h"
-#include "libavutil/avstring.h"
-#include "libavutil/dict.h"
-#include "libavutil/internal.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/opt.h"
-#include "libavutil/parseutils.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/time.h"
-#include "libavutil/timestamp.h"
-
-#include "libavcodec/bytestream.h"
-#include "libavcodec/internal.h"
-#include "libavcodec/raw.h"
-
-#include "audiointerleave.h"
-#include "avformat.h"
-#include "avio_internal.h"
-#include "id3v2.h"
-#include "internal.h"
-#include "metadata.h"
-#if CONFIG_NETWORK
-#include "network.h"
-#endif
-#include "riff.h"
-#include "url.h"
-
-#include "libavutil/ffversion.h"
-const char av_format_ffversion[] = "FFmpeg version " FFMPEG_VERSION;
-
-/**
- * @file
- * various utility functions for use within FFmpeg
- */
-
-unsigned avformat_version(void)
-{
- av_assert0(LIBAVFORMAT_VERSION_MICRO >= 100);
- return LIBAVFORMAT_VERSION_INT;
-}
-
-const char *avformat_configuration(void)
-{
- return FFMPEG_CONFIGURATION;
-}
-
-const char *avformat_license(void)
-{
-#define LICENSE_PREFIX "libavformat license: "
- return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
-}
-
-#define RELATIVE_TS_BASE (INT64_MAX - (1LL<<48))
-
-static int is_relative(int64_t ts) {
- return ts > (RELATIVE_TS_BASE - (1LL<<48));
-}
-
-/**
- * Wrap a given time stamp, if there is an indication for an overflow
- *
- * @param st stream
- * @param timestamp the time stamp to wrap
- * @return resulting time stamp
- */
-static int64_t wrap_timestamp(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)
- return timestamp + (1ULL << st->pts_wrap_bits);
- else if (st->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET &&
- timestamp >= st->pts_wrap_reference)
- return timestamp - (1ULL << st->pts_wrap_bits);
- }
- return timestamp;
-}
-
-MAKE_ACCESSORS(AVStream, stream, AVRational, r_frame_rate)
-MAKE_ACCESSORS(AVStream, stream, char *, recommended_encoder_configuration)
-MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, video_codec)
-MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, audio_codec)
-MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, subtitle_codec)
-MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, data_codec)
-MAKE_ACCESSORS(AVFormatContext, format, int, metadata_header_padding)
-MAKE_ACCESSORS(AVFormatContext, format, void *, opaque)
-MAKE_ACCESSORS(AVFormatContext, format, av_format_control_message, control_message_cb)
-MAKE_ACCESSORS(AVFormatContext, format, AVOpenCallback, open_cb)
-
-int64_t av_stream_get_end_pts(const AVStream *st)
-{
- if (st->priv_pts) {
- return st->priv_pts->val;
- } else
- return AV_NOPTS_VALUE;
-}
-
-struct AVCodecParserContext *av_stream_get_parser(const AVStream *st)
-{
- return st->parser;
-}
-
-void av_format_inject_global_side_data(AVFormatContext *s)
-{
- int i;
- 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;
- }
-}
-
-int ff_copy_whitelists(AVFormatContext *dst, AVFormatContext *src)
-{
- av_assert0(!dst->codec_whitelist && !dst->format_whitelist);
- dst-> codec_whitelist = av_strdup(src->codec_whitelist);
- dst->format_whitelist = av_strdup(src->format_whitelist);
- if ( (src-> codec_whitelist && !dst-> codec_whitelist)
- || (src->format_whitelist && !dst->format_whitelist)) {
- av_log(dst, AV_LOG_ERROR, "Failed to duplicate whitelist\n");
- return AVERROR(ENOMEM);
- }
- return 0;
-}
-
-static const AVCodec *find_decoder(AVFormatContext *s, AVStream *st, enum AVCodecID codec_id)
-{
- if (st->codec->codec)
- return st->codec->codec;
-
- switch (st->codec->codec_type) {
- case AVMEDIA_TYPE_VIDEO:
- if (s->video_codec) return s->video_codec;
- break;
- case AVMEDIA_TYPE_AUDIO:
- if (s->audio_codec) return s->audio_codec;
- break;
- case AVMEDIA_TYPE_SUBTITLE:
- if (s->subtitle_codec) return s->subtitle_codec;
- break;
- }
-
- return avcodec_find_decoder(codec_id);
-}
-
-int av_format_get_probe_score(const AVFormatContext *s)
-{
- return s->probe_score;
-}
-
-/* an arbitrarily chosen "sane" max packet size -- 50M */
-#define SANE_CHUNK_SIZE (50000000)
-
-int ffio_limit(AVIOContext *s, int size)
-{
- if (s->maxsize>= 0) {
- int64_t remaining= s->maxsize - avio_tell(s);
- if (remaining < size) {
- int64_t newsize = avio_size(s);
- if (!s->maxsize || s->maxsize<newsize)
- s->maxsize = newsize - !newsize;
- remaining= s->maxsize - avio_tell(s);
- remaining= FFMAX(remaining, 0);
- }
-
- 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;
- }
- }
- return size;
-}
-
-/* Read the data in sane-sized chunks and append to pkt.
- * Return the number of bytes read or an error. */
-static int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size)
-{
- int64_t orig_pos = pkt->pos; // av_grow_packet might reset pos
- int orig_size = pkt->size;
- int ret;
-
- do {
- int prev_size = pkt->size;
- int read_size;
-
- /* When the caller requests a lot of data, limit it to the amount
- * left in file or SANE_CHUNK_SIZE when it is not known. */
- read_size = size;
- if (read_size > SANE_CHUNK_SIZE/10) {
- read_size = ffio_limit(s, read_size);
- // If filesize/maxsize is unknown, limit to SANE_CHUNK_SIZE
- if (s->maxsize < 0)
- read_size = FFMIN(read_size, SANE_CHUNK_SIZE);
- }
-
- ret = av_grow_packet(pkt, read_size);
- if (ret < 0)
- break;
-
- ret = avio_read(s, pkt->data + prev_size, read_size);
- if (ret != read_size) {
- av_shrink_packet(pkt, prev_size + FFMAX(ret, 0));
- break;
- }
-
- size -= read_size;
- } while (size > 0);
- if (size > 0)
- pkt->flags |= AV_PKT_FLAG_CORRUPT;
-
- pkt->pos = orig_pos;
- if (!pkt->size)
- av_free_packet(pkt);
- return pkt->size > orig_size ? pkt->size - orig_size : ret;
-}
-
-int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
-{
- av_init_packet(pkt);
- pkt->data = NULL;
- pkt->size = 0;
- pkt->pos = avio_tell(s);
-
- return append_packet_chunked(s, pkt, size);
-}
-
-int av_append_packet(AVIOContext *s, AVPacket *pkt, int size)
-{
- if (!pkt->size)
- return av_get_packet(s, pkt, size);
- return append_packet_chunked(s, pkt, size);
-}
-
-int av_filename_number_test(const char *filename)
-{
- char buf[1024];
- return filename &&
- (av_get_frame_filename(buf, sizeof(buf), filename, 1) >= 0);
-}
-
-static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st,
- AVProbeData *pd)
-{
- static const struct {
- const char *name;
- enum AVCodecID id;
- enum AVMediaType type;
- } fmt_id_type[] = {
- { "aac", AV_CODEC_ID_AAC, AVMEDIA_TYPE_AUDIO },
- { "ac3", AV_CODEC_ID_AC3, AVMEDIA_TYPE_AUDIO },
- { "dts", AV_CODEC_ID_DTS, AVMEDIA_TYPE_AUDIO },
- { "dvbsub", AV_CODEC_ID_DVB_SUBTITLE,AVMEDIA_TYPE_SUBTITLE },
- { "eac3", AV_CODEC_ID_EAC3, AVMEDIA_TYPE_AUDIO },
- { "h264", AV_CODEC_ID_H264, AVMEDIA_TYPE_VIDEO },
- { "hevc", AV_CODEC_ID_HEVC, AVMEDIA_TYPE_VIDEO },
- { "loas", AV_CODEC_ID_AAC_LATM, AVMEDIA_TYPE_AUDIO },
- { "m4v", AV_CODEC_ID_MPEG4, AVMEDIA_TYPE_VIDEO },
- { "mp3", AV_CODEC_ID_MP3, AVMEDIA_TYPE_AUDIO },
- { "mpegvideo", AV_CODEC_ID_MPEG2VIDEO, AVMEDIA_TYPE_VIDEO },
- { 0 }
- };
- int score;
- AVInputFormat *fmt = av_probe_input_format3(pd, 1, &score);
-
- if (fmt && st->request_probe <= score) {
- int i;
- av_log(s, AV_LOG_DEBUG,
- "Probe with size=%d, packets=%d detected %s with score=%d\n",
- pd->buf_size, MAX_PROBE_PACKETS - st->probe_packets,
- fmt->name, score);
- for (i = 0; fmt_id_type[i].name; i++) {
- if (!strcmp(fmt->name, fmt_id_type[i].name)) {
- st->codec->codec_id = fmt_id_type[i].id;
- st->codec->codec_type = fmt_id_type[i].type;
- return score;
- }
- }
- }
- return 0;
-}
-
-/************************************************************/
-/* input media file */
-
-int av_demuxer_open(AVFormatContext *ic) {
- int err;
-
- if (ic->format_whitelist && av_match_list(ic->iformat->name, ic->format_whitelist, ',') <= 0) {
- av_log(ic, AV_LOG_ERROR, "Format not on whitelist\n");
- return AVERROR(EINVAL);
- }
-
- if (ic->iformat->read_header) {
- err = ic->iformat->read_header(ic);
- if (err < 0)
- return err;
- }
-
- if (ic->pb && !ic->internal->data_offset)
- ic->internal->data_offset = avio_tell(ic->pb);
-
- return 0;
-}
-
-/* Open input file and probe the format if necessary. */
-static int init_input(AVFormatContext *s, const char *filename,
- AVDictionary **options)
-{
- int ret;
- AVProbeData pd = { filename, NULL, 0 };
- int score = AVPROBE_SCORE_RETRY;
-
- if (s->pb) {
- s->flags |= AVFMT_FLAG_CUSTOM_IO;
- if (!s->iformat)
- return av_probe_input_buffer2(s->pb, &s->iformat, filename,
- s, 0, s->format_probesize);
- else if (s->iformat->flags & AVFMT_NOFILE)
- av_log(s, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
- "will be ignored with AVFMT_NOFILE format.\n");
- return 0;
- }
-
- if ((s->iformat && s->iformat->flags & AVFMT_NOFILE) ||
- (!s->iformat && (s->iformat = av_probe_input_format2(&pd, 0, &score))))
- return score;
-
- if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ | s->avio_flags,
- &s->interrupt_callback, options)) < 0)
- return ret;
- if (s->iformat)
- return 0;
- return av_probe_input_buffer2(s->pb, &s->iformat, filename,
- s, 0, s->format_probesize);
-}
-
-static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt,
- AVPacketList **plast_pktl)
-{
- AVPacketList *pktl = av_mallocz(sizeof(AVPacketList));
- if (!pktl)
- return NULL;
-
- if (*packet_buffer)
- (*plast_pktl)->next = pktl;
- else
- *packet_buffer = pktl;
-
- /* Add the packet in the buffered packet list. */
- *plast_pktl = pktl;
- pktl->pkt = *pkt;
- return &pktl->pkt;
-}
-
-int avformat_queue_attached_pictures(AVFormatContext *s)
-{
- int i;
- for (i = 0; i < s->nb_streams; i++)
- if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC &&
- s->streams[i]->discard < AVDISCARD_ALL) {
- AVPacket copy = s->streams[i]->attached_pic;
- if (copy.size <= 0) {
- av_log(s, AV_LOG_WARNING,
- "Attached picture on stream %d has invalid size, "
- "ignoring\n", i);
- continue;
- }
- copy.buf = av_buffer_ref(copy.buf);
- if (!copy.buf)
- return AVERROR(ENOMEM);
-
- add_to_pktbuf(&s->internal->raw_packet_buffer, ©,
- &s->internal->raw_packet_buffer_end);
- }
- return 0;
-}
-
-int avformat_open_input(AVFormatContext **ps, const char *filename,
- AVInputFormat *fmt, AVDictionary **options)
-{
- AVFormatContext *s = *ps;
- int ret = 0;
- AVDictionary *tmp = NULL;
- ID3v2ExtraMeta *id3v2_extra_meta = NULL;
-
- if (!s && !(s = avformat_alloc_context()))
- return AVERROR(ENOMEM);
- if (!s->av_class) {
- av_log(NULL, AV_LOG_ERROR, "Input context has not been properly allocated by avformat_alloc_context() and is not NULL either\n");
- return AVERROR(EINVAL);
- }
- if (fmt)
- s->iformat = fmt;
-
- if (options)
- av_dict_copy(&tmp, *options, 0);
-
- if (s->pb) // must be before any goto fail
- s->flags |= AVFMT_FLAG_CUSTOM_IO;
-
- if ((ret = av_opt_set_dict(s, &tmp)) < 0)
- goto fail;
-
- if ((ret = init_input(s, filename, &tmp)) < 0)
- goto fail;
- s->probe_score = ret;
-
- if (s->format_whitelist && av_match_list(s->iformat->name, s->format_whitelist, ',') <= 0) {
- av_log(s, AV_LOG_ERROR, "Format not on whitelist\n");
- ret = AVERROR(EINVAL);
- goto fail;
- }
-
- avio_skip(s->pb, s->skip_initial_bytes);
-
- /* Check filename in case an image number is expected. */
- if (s->iformat->flags & AVFMT_NEEDNUMBER) {
- if (!av_filename_number_test(filename)) {
- ret = AVERROR(EINVAL);
- goto fail;
- }
- }
-
- s->duration = s->start_time = AV_NOPTS_VALUE;
- av_strlcpy(s->filename, filename ? filename : "", sizeof(s->filename));
-
- /* Allocate private data. */
- if (s->iformat->priv_data_size > 0) {
- if (!(s->priv_data = av_mallocz(s->iformat->priv_data_size))) {
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- if (s->iformat->priv_class) {
- *(const AVClass **) s->priv_data = s->iformat->priv_class;
- av_opt_set_defaults(s->priv_data);
- if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0)
- goto fail;
- }
- }
-
- /* e.g. AVFMT_NOFILE formats will not have a AVIOContext */
- if (s->pb)
- ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, 0);
-
- if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header)
- if ((ret = s->iformat->read_header(s)) < 0)
- goto fail;
-
- if (id3v2_extra_meta) {
- if (!strcmp(s->iformat->name, "mp3") || !strcmp(s->iformat->name, "aac") ||
- !strcmp(s->iformat->name, "tta")) {
- if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0)
- goto fail;
- } else
- av_log(s, AV_LOG_DEBUG, "demuxer does not support additional id3 data, skipping\n");
- }
- ff_id3v2_free_extra_meta(&id3v2_extra_meta);
-
- if ((ret = avformat_queue_attached_pictures(s)) < 0)
- goto fail;
-
- if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->pb && !s->internal->data_offset)
- s->internal->data_offset = avio_tell(s->pb);
-
- s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
-
- if (options) {
- av_dict_free(options);
- *options = tmp;
- }
- *ps = s;
- return 0;
-
-fail:
- ff_id3v2_free_extra_meta(&id3v2_extra_meta);
- av_dict_free(&tmp);
- if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO))
- avio_closep(&s->pb);
- avformat_free_context(s);
- *ps = NULL;
- return ret;
-}
-
-/*******************************************************/
-
-static void force_codec_ids(AVFormatContext *s, AVStream *st)
-{
- switch (st->codec->codec_type) {
- case AVMEDIA_TYPE_VIDEO:
- if (s->video_codec_id)
- st->codec->codec_id = s->video_codec_id;
- break;
- case AVMEDIA_TYPE_AUDIO:
- if (s->audio_codec_id)
- st->codec->codec_id = s->audio_codec_id;
- break;
- case AVMEDIA_TYPE_SUBTITLE:
- if (s->subtitle_codec_id)
- st->codec->codec_id = s->subtitle_codec_id;
- break;
- }
-}
-
-static int probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
-{
- if (st->request_probe>0) {
- AVProbeData *pd = &st->probe_data;
- int end;
- av_log(s, AV_LOG_DEBUG, "probing stream %d pp:%d\n", st->index, st->probe_packets);
- --st->probe_packets;
-
- if (pkt) {
- uint8_t *new_buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
- if (!new_buf) {
- av_log(s, AV_LOG_WARNING,
- "Failed to reallocate probe buffer for stream %d\n",
- st->index);
- goto no_packet;
- }
- pd->buf = new_buf;
- memcpy(pd->buf + pd->buf_size, pkt->data, pkt->size);
- pd->buf_size += pkt->size;
- memset(pd->buf + pd->buf_size, 0, AVPROBE_PADDING_SIZE);
- } else {
-no_packet:
- st->probe_packets = 0;
- if (!pd->buf_size) {
- av_log(s, AV_LOG_WARNING,
- "nothing to probe for stream %d\n", st->index);
- }
- }
-
- end= s->internal->raw_packet_buffer_remaining_size <= 0
- || st->probe_packets<= 0;
-
- if (end || av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)) {
- int score = set_codec_from_probe_data(s, st, pd);
- if ( (st->codec->codec_id != AV_CODEC_ID_NONE && score > AVPROBE_SCORE_STREAM_RETRY)
- || end) {
- pd->buf_size = 0;
- av_freep(&pd->buf);
- st->request_probe = -1;
- if (st->codec->codec_id != AV_CODEC_ID_NONE) {
- av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index);
- } else
- av_log(s, AV_LOG_WARNING, "probed stream %d failed\n", st->index);
- }
- force_codec_ids(s, st);
- }
- }
- return 0;
-}
-
-static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_index, AVPacket *pkt)
-{
- int64_t ref = pkt->dts;
- int i, pts_wrap_behavior;
- int64_t pts_wrap_reference;
- AVProgram *first_program;
-
- 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)
- return 0;
- ref &= (1LL << st->pts_wrap_bits)-1;
-
- // reference time stamp should be 60 s before first time stamp
- pts_wrap_reference = ref - av_rescale(60, st->time_base.den, st->time_base.num);
- // if first time stamp is not more than 1/8 and 60s before the wrap point, subtract rather than add wrap offset
- pts_wrap_behavior = (ref < (1LL << st->pts_wrap_bits) - (1LL << st->pts_wrap_bits-3)) ||
- (ref < (1LL << st->pts_wrap_bits) - av_rescale(60, st->time_base.den, st->time_base.num)) ?
- AV_PTS_WRAP_ADD_OFFSET : AV_PTS_WRAP_SUB_OFFSET;
-
- first_program = av_find_program_from_stream(s, NULL, stream_index);
-
- 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) {
- 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;
- }
- }
- 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;
- }
- }
- else {
- AVProgram *program = first_program;
- while (program) {
- if (program->pts_wrap_reference != AV_NOPTS_VALUE) {
- pts_wrap_reference = program->pts_wrap_reference;
- pts_wrap_behavior = program->pts_wrap_behavior;
- break;
- }
- program = av_find_program_from_stream(s, program, stream_index);
- }
-
- // update every program with differing pts_wrap_reference
- program = first_program;
- while (program) {
- if (program->pts_wrap_reference != pts_wrap_reference) {
- for (i = 0; i<program->nb_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;
- }
-
- program->pts_wrap_reference = pts_wrap_reference;
- program->pts_wrap_behavior = pts_wrap_behavior;
- }
- program = av_find_program_from_stream(s, program, stream_index);
- }
- }
- return 1;
-}
-
-int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
- int ret, i, err;
- AVStream *st;
-
- for (;;) {
- AVPacketList *pktl = s->internal->raw_packet_buffer;
-
- if (pktl) {
- *pkt = pktl->pkt;
- st = s->streams[pkt->stream_index];
- if (s->internal->raw_packet_buffer_remaining_size <= 0)
- if ((err = probe_codec(s, st, NULL)) < 0)
- return err;
- if (st->request_probe <= 0) {
- s->internal->raw_packet_buffer = pktl->next;
- s->internal->raw_packet_buffer_remaining_size += pkt->size;
- av_free(pktl);
- return 0;
- }
- }
-
- pkt->data = NULL;
- pkt->size = 0;
- av_init_packet(pkt);
- ret = s->iformat->read_packet(s, pkt);
- if (ret < 0) {
- if (!pktl || ret == AVERROR(EAGAIN))
- return ret;
- for (i = 0; i < s->nb_streams; i++) {
- st = s->streams[i];
- if (st->probe_packets || st->request_probe > 0)
- if ((err = probe_codec(s, st, NULL)) < 0)
- return err;
- av_assert0(st->request_probe <= 0);
- }
- continue;
- }
-
- if ((s->flags & AVFMT_FLAG_DISCARD_CORRUPT) &&
- (pkt->flags & AV_PKT_FLAG_CORRUPT)) {
- av_log(s, AV_LOG_WARNING,
- "Dropped corrupted packet (stream = %d)\n",
- pkt->stream_index);
- av_free_packet(pkt);
- continue;
- }
-
- if (pkt->stream_index >= (unsigned)s->nb_streams) {
- av_log(s, AV_LOG_ERROR, "Invalid stream index %d\n", pkt->stream_index);
- continue;
- }
-
- 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) {
- // correct first time stamps to negative values
- if (!is_relative(st->first_dts))
- st->first_dts = wrap_timestamp(st, st->first_dts);
- if (!is_relative(st->start_time))
- st->start_time = wrap_timestamp(st, st->start_time);
- if (!is_relative(st->cur_dts))
- st->cur_dts = wrap_timestamp(st, st->cur_dts);
- }
-
- pkt->dts = wrap_timestamp(st, pkt->dts);
- pkt->pts = wrap_timestamp(st, pkt->pts);
-
- force_codec_ids(s, st);
-
- /* TODO: audio: time filter; video: frame reordering (pts != dts) */
- 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)
- return ret;
-
- add_to_pktbuf(&s->internal->raw_packet_buffer, pkt,
- &s->internal->raw_packet_buffer_end);
- s->internal->raw_packet_buffer_remaining_size -= pkt->size;
-
- if ((err = probe_codec(s, st, pkt)) < 0)
- return err;
- }
-}
-
-
-/**********************************************************/
-
-static int determinable_frame_size(AVCodecContext *avctx)
-{
- if (/*avctx->codec_id == AV_CODEC_ID_AAC ||*/
- avctx->codec_id == AV_CODEC_ID_MP1 ||
- avctx->codec_id == AV_CODEC_ID_MP2 ||
- avctx->codec_id == AV_CODEC_ID_MP3/* ||
- avctx->codec_id == AV_CODEC_ID_CELT*/)
- return 1;
- return 0;
-}
-
-/**
- * Return the frame duration in seconds. Return 0 if not available.
- */
-void ff_compute_frame_duration(AVFormatContext *s, int *pnum, int *pden, AVStream *st,
- AVCodecParserContext *pc, AVPacket *pkt)
-{
- AVRational codec_framerate = s->iformat ? st->codec->framerate :
- av_mul_q(av_inv_q(st->codec->time_base), (AVRational){1, st->codec->ticks_per_frame});
- int frame_size;
-
- *pnum = 0;
- *pden = 0;
- switch (st->codec->codec_type) {
- case AVMEDIA_TYPE_VIDEO:
- if (st->r_frame_rate.num && !pc && s->iformat) {
- *pnum = st->r_frame_rate.den;
- *pden = st->r_frame_rate.num;
- } else if (st->time_base.num * 1000LL > st->time_base.den) {
- *pnum = st->time_base.num;
- *pden = st->time_base.den;
- } else if (codec_framerate.den * 1000LL > codec_framerate.num) {
- av_assert0(st->codec->ticks_per_frame);
- av_reduce(pnum, pden,
- codec_framerate.den,
- codec_framerate.num * (int64_t)st->codec->ticks_per_frame,
- INT_MAX);
-
- if (pc && pc->repeat_pict) {
- av_assert0(s->iformat); // this may be wrong for interlaced encoding but its not used for that case
- av_reduce(pnum, pden,
- (*pnum) * (1LL + pc->repeat_pict),
- (*pden),
- INT_MAX);
- }
- /* If this codec can be interlaced or progressive then we need
- * a parser to compute duration of a packet. Thus if we have
- * no parser in such case leave duration undefined. */
- if (st->codec->ticks_per_frame > 1 && !pc)
- *pnum = *pden = 0;
- }
- break;
- case AVMEDIA_TYPE_AUDIO:
- frame_size = av_get_audio_frame_duration(st->codec, pkt->size);
- if (frame_size <= 0 || st->codec->sample_rate <= 0)
- break;
- *pnum = frame_size;
- *pden = st->codec->sample_rate;
- break;
- default:
- break;
- }
-}
-
-static int is_intra_only(AVCodecContext *enc) {
- const AVCodecDescriptor *desc;
-
- if (enc->codec_type != AVMEDIA_TYPE_VIDEO)
- return 1;
-
- desc = av_codec_get_codec_descriptor(enc);
- if (!desc) {
- desc = avcodec_descriptor_get(enc->codec_id);
- av_codec_set_codec_descriptor(enc, desc);
- }
- if (desc)
- return !!(desc->props & AV_CODEC_PROP_INTRA_ONLY);
- return 0;
-}
-
-static int has_decode_delay_been_guessed(AVStream *st)
-{
- if (st->codec->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
- return 1;
-#if CONFIG_H264_DECODER
- if (st->codec->has_b_frames &&
- avpriv_h264_has_num_reorder_frames(st->codec) == st->codec->has_b_frames)
- return 1;
-#endif
- if (st->codec->has_b_frames<3)
- return st->nb_decoded_frames >= 7;
- else if (st->codec->has_b_frames<4)
- return st->nb_decoded_frames >= 18;
- else
- return st->nb_decoded_frames >= 20;
-}
-
-static AVPacketList *get_next_pkt(AVFormatContext *s, AVStream *st, AVPacketList *pktl)
-{
- if (pktl->next)
- return pktl->next;
- if (pktl == s->internal->packet_buffer_end)
- return s->internal->parse_queue;
- return NULL;
-}
-
-static int64_t select_from_pts_buffer(AVStream *st, int64_t *pts_buffer, int64_t dts) {
- int onein_oneout = st->codec->codec_id != AV_CODEC_ID_H264 &&
- st->codec->codec_id != AV_CODEC_ID_HEVC;
-
- if(!onein_oneout) {
- int delay = st->codec->has_b_frames;
- int i;
-
- if (dts == AV_NOPTS_VALUE) {
- int64_t best_score = INT64_MAX;
- for (i = 0; i<delay; i++) {
- if (st->pts_reorder_error_count[i]) {
- int64_t score = st->pts_reorder_error[i] / st->pts_reorder_error_count[i];
- if (score < best_score) {
- best_score = score;
- dts = pts_buffer[i];
- }
- }
- }
- } else {
- for (i = 0; i<delay; i++) {
- if (pts_buffer[i] != AV_NOPTS_VALUE) {
- int64_t diff = FFABS(pts_buffer[i] - dts)
- + (uint64_t)st->pts_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;
- }
- }
- }
- }
- }
-
- if (dts == AV_NOPTS_VALUE)
- dts = pts_buffer[0];
-
- return dts;
-}
-
-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;
- int64_t pts_buffer[MAX_REORDER_DELAY+1];
- int64_t shift;
- int i, delay;
-
- if (st->first_dts != AV_NOPTS_VALUE ||
- dts == AV_NOPTS_VALUE ||
- st->cur_dts == AV_NOPTS_VALUE ||
- is_relative(dts))
- return;
-
- delay = st->codec->has_b_frames;
- st->first_dts = dts - (st->cur_dts - RELATIVE_TS_BASE);
- st->cur_dts = dts;
- shift = st->first_dts - RELATIVE_TS_BASE;
-
- for (i = 0; i<MAX_REORDER_DELAY+1; i++)
- pts_buffer[i] = AV_NOPTS_VALUE;
-
- if (is_relative(pts))
- pts += shift;
-
- for (; pktl; pktl = get_next_pkt(s, st, pktl)) {
- if (pktl->pkt.stream_index != stream_index)
- continue;
- if (is_relative(pktl->pkt.pts))
- pktl->pkt.pts += shift;
-
- if (is_relative(pktl->pkt.dts))
- pktl->pkt.dts += shift;
-
- if (st->start_time == AV_NOPTS_VALUE && pktl->pkt.pts != AV_NOPTS_VALUE)
- st->start_time = pktl->pkt.pts;
-
- if (pktl->pkt.pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY && has_decode_delay_been_guessed(st)) {
- pts_buffer[0] = pktl->pkt.pts;
- for (i = 0; i<delay && pts_buffer[i] > pts_buffer[i + 1]; i++)
- FFSWAP(int64_t, pts_buffer[i], pts_buffer[i + 1]);
-
- pktl->pkt.dts = select_from_pts_buffer(st, pts_buffer, pktl->pkt.dts);
- }
- }
-
- if (st->start_time == AV_NOPTS_VALUE)
- st->start_time = pts;
-}
-
-static void update_initial_durations(AVFormatContext *s, AVStream *st,
- int stream_index, int duration)
-{
- AVPacketList *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)
- return;
- st->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) {
- if (pktl->pkt.pts != pktl->pkt.dts ||
- pktl->pkt.dts != AV_NOPTS_VALUE ||
- pktl->pkt.duration)
- break;
- cur_dts -= duration;
- }
- }
- if (pktl && pktl->pkt.dts != st->first_dts) {
- av_log(s, AV_LOG_DEBUG, "first_dts %s not matching first dts %s (pts %s, duration %d) in the queue\n",
- av_ts2str(st->first_dts), av_ts2str(pktl->pkt.dts), av_ts2str(pktl->pkt.pts), pktl->pkt.duration);
- return;
- }
- if (!pktl) {
- av_log(s, AV_LOG_DEBUG, "first_dts %s but no packet with dts in the queue\n", av_ts2str(st->first_dts));
- return;
- }
- pktl = s->internal->packet_buffer ? s->internal->packet_buffer : s->internal->parse_queue;
- st->first_dts = cur_dts;
- } else if (st->cur_dts != RELATIVE_TS_BASE)
- return;
-
- for (; pktl; pktl = get_next_pkt(s, st, pktl)) {
- if (pktl->pkt.stream_index != stream_index)
- continue;
- if (pktl->pkt.pts == pktl->pkt.dts &&
- (pktl->pkt.dts == AV_NOPTS_VALUE || pktl->pkt.dts == st->first_dts) &&
- !pktl->pkt.duration) {
- pktl->pkt.dts = cur_dts;
- if (!st->codec->has_b_frames)
- pktl->pkt.pts = cur_dts;
-// if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO)
- pktl->pkt.duration = duration;
- } else
- break;
- cur_dts = pktl->pkt.dts + pktl->pkt.duration;
- }
- if (!pktl)
- st->cur_dts = cur_dts;
-}
-
-static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
- AVCodecParserContext *pc, AVPacket *pkt,
- int64_t next_dts, int64_t next_pts)
-{
- int num, den, presentation_delayed, delay, i;
- int64_t offset;
- AVRational duration;
- int onein_oneout = st->codec->codec_id != AV_CODEC_ID_H264 &&
- st->codec->codec_id != AV_CODEC_ID_HEVC;
-
- if (s->flags & AVFMT_FLAG_NOFILLIN)
- return;
-
- if (st->codec->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++;
- } else {
- av_log(s, st->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++;
- }
- if (st->dts_ordered + st->dts_misordered > 250) {
- st->dts_ordered >>= 1;
- st->dts_misordered >>= 1;
- }
- }
-
- st->last_dts_for_order_check = pkt->dts;
- if (st->dts_ordered < 8*st->dts_misordered && pkt->dts == pkt->pts)
- pkt->dts = AV_NOPTS_VALUE;
- }
-
- if ((s->flags & AVFMT_FLAG_IGNDTS) && pkt->pts != AV_NOPTS_VALUE)
- pkt->dts = AV_NOPTS_VALUE;
-
- if (pc && pc->pict_type == AV_PICTURE_TYPE_B
- && !st->codec->has_b_frames)
- //FIXME Set low_delay = 0 when has_b_frames = 1
- st->codec->has_b_frames = 1;
-
- /* do we have a video B-frame ? */
- delay = st->codec->has_b_frames;
- presentation_delayed = 0;
-
- /* XXX: need has_b_frame, but cannot get it if the codec is
- * not initialized */
- if (delay &&
- pc && pc->pict_type != AV_PICTURE_TYPE_B)
- presentation_delayed = 1;
-
- if (pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE &&
- st->pts_wrap_bits < 63 &&
- 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;
- } else
- pkt->pts += 1LL << st->pts_wrap_bits;
- }
-
- /* Some MPEG-2 in MPEG-PS lack dts (issue #171 / input_file.mpg).
- * We take the conservative approach and discard both.
- * Note: If this is misbehaving for an H.264 file, then possibly
- * presentation_delayed is not set correctly. */
- if (delay == 1 && pkt->dts == pkt->pts &&
- pkt->dts != AV_NOPTS_VALUE && presentation_delayed) {
- av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination %"PRIi64"\n", pkt->dts);
- if ( strcmp(s->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2")
- && strcmp(s->iformat->name, "flv")) // otherwise we discard correct timestamps for vc1-wmapro.ism
- pkt->dts = AV_NOPTS_VALUE;
- }
-
- duration = av_mul_q((AVRational) {pkt->duration, 1}, st->time_base);
- if (pkt->duration == 0) {
- ff_compute_frame_duration(s, &num, &den, st, pc, pkt);
- if (den && num) {
- duration = (AVRational) {num, den};
- pkt->duration = av_rescale_rnd(1,
- num * (int64_t) st->time_base.den,
- den * (int64_t) st->time_base.num,
- AV_ROUND_DOWN);
- }
- }
-
- if (pkt->duration != 0 && (s->internal->packet_buffer || s->internal->parse_queue))
- update_initial_durations(s, st, pkt->stream_index, pkt->duration);
-
- /* Correct timestamps with byte offset if demuxers only have timestamps
- * on packet boundaries */
- if (pc && st->need_parsing == AVSTREAM_PARSE_TIMESTAMPS && pkt->size) {
- /* this will estimate bitrate based on this frame's duration and size */
- offset = av_rescale(pc->offset, pkt->duration, pkt->size);
- if (pkt->pts != AV_NOPTS_VALUE)
- pkt->pts += offset;
- if (pkt->dts != AV_NOPTS_VALUE)
- pkt->dts += offset;
- }
-
- /* This may be redundant, but it should not hurt. */
- if (pkt->dts != AV_NOPTS_VALUE &&
- pkt->pts != AV_NOPTS_VALUE &&
- pkt->pts > pkt->dts)
- presentation_delayed = 1;
-
- if (s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_TRACE,
- "IN delayed:%d pts:%s, dts:%s cur_dts:%s st:%d pc:%p duration:%d delay:%d onein_oneout:%d\n",
- presentation_delayed, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts),
- pkt->stream_index, pc, pkt->duration, delay, onein_oneout);
-
- /* Interpolate PTS and DTS if they are not present. We skip H264
- * currently because delay and has_b_frames are not reliably set. */
- if ((delay == 0 || (delay == 1 && pc)) &&
- onein_oneout) {
- if (presentation_delayed) {
- /* DTS = decompression timestamp */
- /* PTS = presentation timestamp */
- if (pkt->dts == AV_NOPTS_VALUE)
- pkt->dts = st->last_IP_pts;
- update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts, pkt);
- if (pkt->dts == AV_NOPTS_VALUE)
- pkt->dts = st->cur_dts;
-
- /* This is tricky: the dts must be incremented by the duration
- * of the frame we are displaying, i.e. the last I- or P-frame. */
- if (st->last_IP_duration == 0)
- st->last_IP_duration = pkt->duration;
- if (pkt->dts != AV_NOPTS_VALUE)
- st->cur_dts = pkt->dts + st->last_IP_duration;
- if (pkt->dts != AV_NOPTS_VALUE &&
- pkt->pts == AV_NOPTS_VALUE &&
- st->last_IP_duration > 0 &&
- ((uint64_t)st->cur_dts - (uint64_t)next_dts + 1) <= 2 &&
- next_dts != next_pts &&
- next_pts != AV_NOPTS_VALUE)
- pkt->pts = next_dts;
-
- st->last_IP_duration = pkt->duration;
- st->last_IP_pts = pkt->pts;
- /* Cannot compute PTS if not present (we can compute it only
- * by knowing the future. */
- } else if (pkt->pts != AV_NOPTS_VALUE ||
- pkt->dts != AV_NOPTS_VALUE ||
- pkt->duration ) {
-
- /* presentation is not delayed : PTS and DTS are the same */
- if (pkt->pts == AV_NOPTS_VALUE)
- pkt->pts = pkt->dts;
- update_initial_timestamps(s, pkt->stream_index, pkt->pts,
- pkt->pts, pkt);
- if (pkt->pts == AV_NOPTS_VALUE)
- pkt->pts = st->cur_dts;
- pkt->dts = pkt->pts;
- if (pkt->pts != AV_NOPTS_VALUE)
- st->cur_dts = av_add_stable(st->time_base, pkt->pts, duration, 1);
- }
- }
-
- if (pkt->pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY) {
- st->pts_buffer[0] = pkt->pts;
- for (i = 0; i<delay && st->pts_buffer[i] > st->pts_buffer[i + 1]; i++)
- FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i + 1]);
-
- if(has_decode_delay_been_guessed(st))
- pkt->dts = select_from_pts_buffer(st, st->pts_buffer, pkt->dts);
- }
- // We skipped it above so we try here.
- if (!onein_oneout)
- // This should happen on the first packet
- update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts, pkt);
- if (pkt->dts > st->cur_dts)
- st->cur_dts = pkt->dts;
-
- if (s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_TRACE, "OUTdelayed:%d/%d pts:%s, dts:%s cur_dts:%s\n",
- presentation_delayed, delay, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts));
-
- /* update flags */
- if (is_intra_only(st->codec))
- pkt->flags |= AV_PKT_FLAG_KEY;
- if (pc)
- pkt->convergence_duration = pc->convergence_duration;
-}
-
-static void free_packet_buffer(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end)
-{
- while (*pkt_buf) {
- AVPacketList *pktl = *pkt_buf;
- *pkt_buf = pktl->next;
- av_free_packet(&pktl->pkt);
- av_freep(&pktl);
- }
- *pkt_buf_end = NULL;
-}
-
-/**
- * Parse a packet, add all split parts to parse_queue.
- *
- * @param pkt Packet to parse, NULL when flushing the parser at end of stream.
- */
-static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index)
-{
- AVPacket out_pkt = { 0 }, flush_pkt = { 0 };
- AVStream *st = s->streams[stream_index];
- uint8_t *data = pkt ? pkt->data : NULL;
- int size = pkt ? pkt->size : 0;
- int ret = 0, got_output = 0;
-
- if (!pkt) {
- av_init_packet(&flush_pkt);
- pkt = &flush_pkt;
- got_output = 1;
- } else if (!size && 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);
- }
-
- while (size > 0 || (pkt == &flush_pkt && got_output)) {
- int len;
- int64_t next_pts = pkt->pts;
- int64_t next_dts = pkt->dts;
-
- av_init_packet(&out_pkt);
- len = av_parser_parse2(st->parser, st->codec,
- &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;
- size -= len;
-
- got_output = !!out_pkt.size;
-
- if (!out_pkt.size)
- continue;
-
- if (pkt->side_data) {
- 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;
- if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- if (st->codec->sample_rate > 0) {
- out_pkt.duration =
- av_rescale_q_rnd(st->parser->duration,
- (AVRational) { 1, st->codec->sample_rate },
- st->time_base,
- AV_ROUND_DOWN);
- }
- }
-
- out_pkt.stream_index = st->index;
- out_pkt.pts = st->parser->pts;
- out_pkt.dts = st->parser->dts;
- out_pkt.pos = st->parser->pos;
-
- if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW)
- 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;
-
- 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;
-
- compute_pkt_fields(s, st, st->parser, &out_pkt, next_dts, next_pts);
-
- if (out_pkt.data == pkt->data && out_pkt.size == pkt->size) {
- out_pkt.buf = pkt->buf;
- pkt->buf = NULL;
-#if FF_API_DESTRUCT_PACKET
-FF_DISABLE_DEPRECATION_WARNINGS
- out_pkt.destruct = pkt->destruct;
- pkt->destruct = NULL;
-FF_ENABLE_DEPRECATION_WARNINGS
-#endif
- }
- if ((ret = av_dup_packet(&out_pkt)) < 0)
- goto fail;
-
- if (!add_to_pktbuf(&s->internal->parse_queue, &out_pkt, &s->internal->parse_queue_end)) {
- av_free_packet(&out_pkt);
- ret = AVERROR(ENOMEM);
- goto fail;
- }
- }
-
- /* end of the stream => close and free the parser */
- if (pkt == &flush_pkt) {
- av_parser_close(st->parser);
- st->parser = NULL;
- }
-
-fail:
- av_free_packet(pkt);
- return ret;
-}
-
-static int read_from_packet_buffer(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->codec->sample_rate, st->time_base.den);
-}
-
-static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
-{
- int ret = 0, i, got_packet = 0;
- AVDictionary *metadata = NULL;
-
- av_init_packet(pkt);
-
- while (!got_packet && !s->internal->parse_queue) {
- AVStream *st;
- AVPacket cur_pkt;
-
- /* read next packet */
- ret = ff_read_packet(s, &cur_pkt);
- if (ret < 0) {
- if (ret == AVERROR(EAGAIN))
- return ret;
- /* flush the parsers */
- for (i = 0; i < s->nb_streams; i++) {
- st = s->streams[i];
- if (st->parser && st->need_parsing)
- parse_packet(s, NULL, st->index);
- }
- /* all remaining packets are now in parse_queue =>
- * really terminate parsing */
- break;
- }
- ret = 0;
- st = s->streams[cur_pkt.stream_index];
-
- if (cur_pkt.pts != AV_NOPTS_VALUE &&
- cur_pkt.dts != AV_NOPTS_VALUE &&
- cur_pkt.pts < cur_pkt.dts) {
- av_log(s, AV_LOG_WARNING,
- "Invalid timestamps stream=%d, pts=%s, dts=%s, size=%d\n",
- cur_pkt.stream_index,
- av_ts2str(cur_pkt.pts),
- av_ts2str(cur_pkt.dts),
- cur_pkt.size);
- }
- if (s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_DEBUG,
- "ff_read_packet stream=%d, pts=%s, dts=%s, size=%d, duration=%d, flags=%d\n",
- cur_pkt.stream_index,
- av_ts2str(cur_pkt.pts),
- av_ts2str(cur_pkt.dts),
- cur_pkt.size, cur_pkt.duration, cur_pkt.flags);
-
- if (st->need_parsing && !st->parser && !(s->flags & AVFMT_FLAG_NOPARSE)) {
- st->parser = av_parser_init(st->codec->codec_id);
- if (!st->parser) {
- av_log(s, AV_LOG_VERBOSE, "parser not found for codec "
- "%s, packets or times may be invalid.\n",
- avcodec_get_name(st->codec->codec_id));
- /* no parser available: just output the raw packets */
- st->need_parsing = AVSTREAM_PARSE_NONE;
- } else if (st->need_parsing == AVSTREAM_PARSE_HEADERS)
- st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
- else if (st->need_parsing == AVSTREAM_PARSE_FULL_ONCE)
- st->parser->flags |= PARSER_FLAG_ONCE;
- else if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW)
- st->parser->flags |= PARSER_FLAG_USE_CODEC_TS;
- }
-
- if (!st->need_parsing || !st->parser) {
- /* no parsing needed: we just output the packet as is */
- *pkt = cur_pkt;
- compute_pkt_fields(s, st, NULL, pkt, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
- if ((s->iformat->flags & AVFMT_GENERIC_INDEX) &&
- (pkt->flags & AV_PKT_FLAG_KEY) && pkt->dts != AV_NOPTS_VALUE) {
- ff_reduce_index(s, st->index);
- av_add_index_entry(st, pkt->pos, pkt->dts,
- 0, 0, AVINDEX_KEYFRAME);
- }
- got_packet = 1;
- } else if (st->discard < AVDISCARD_ALL) {
- if ((ret = parse_packet(s, &cur_pkt, cur_pkt.stream_index)) < 0)
- return ret;
- } else {
- /* free packet */
- av_free_packet(&cur_pkt);
- }
- if (pkt->flags & AV_PKT_FLAG_KEY)
- st->skip_to_keyframe = 0;
- if (st->skip_to_keyframe) {
- av_free_packet(&cur_pkt);
- if (got_packet) {
- *pkt = cur_pkt;
- }
- got_packet = 0;
- }
- }
-
- if (!got_packet && s->internal->parse_queue)
- ret = read_from_packet_buffer(&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) {
- 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 (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) {
- 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 + 4, discard_padding);
- av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d / discard %d\n", st->skip_samples, discard_padding);
- }
- st->skip_samples = 0;
- }
-
- if (st->inject_global_side_data) {
- for (i = 0; i < st->nb_side_data; i++) {
- AVPacketSideData *src_sd = &st->side_data[i];
- uint8_t *dst_data;
-
- 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);
- if (!dst_data) {
- av_log(s, AV_LOG_WARNING, "Could not inject global side data\n");
- continue;
- }
-
- memcpy(dst_data, src_sd->data, src_sd->size);
- }
- st->inject_global_side_data = 0;
- }
-
- if (!(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA))
- av_packet_merge_side_data(pkt);
- }
-
- av_opt_get_dict_val(s, "metadata", AV_OPT_SEARCH_CHILDREN, &metadata);
- if (metadata) {
- s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
- av_dict_copy(&s->metadata, metadata, 0);
- av_dict_free(&metadata);
- av_opt_set_dict_val(s, "metadata", NULL, AV_OPT_SEARCH_CHILDREN);
- }
-
- if (s->debug & FF_FDEBUG_TS)
- av_log(s, AV_LOG_DEBUG,
- "read_frame_internal stream=%d, pts=%s, dts=%s, "
- "size=%d, duration=%d, flags=%d\n",
- pkt->stream_index,
- av_ts2str(pkt->pts),
- av_ts2str(pkt->dts),
- pkt->size, pkt->duration, pkt->flags);
-
- return ret;
-}
-
-int av_read_frame(AVFormatContext *s, AVPacket *pkt)
-{
- const int genpts = s->flags & AVFMT_FLAG_GENPTS;
- int eof = 0;
- int ret;
- AVStream *st;
-
- if (!genpts) {
- ret = s->internal->packet_buffer
- ? read_from_packet_buffer(&s->internal->packet_buffer,
- &s->internal->packet_buffer_end, pkt)
- : read_frame_internal(s, pkt);
- if (ret < 0)
- return ret;
- goto return_packet;
- }
-
- for (;;) {
- AVPacketList *pktl = s->internal->packet_buffer;
-
- if (pktl) {
- AVPacket *next_pkt = &pktl->pkt;
-
- if (next_pkt->dts != AV_NOPTS_VALUE) {
- int wrap_bits = s->streams[next_pkt->stream_index]->pts_wrap_bits;
- // last dts seen for this stream. if any of packets following
- // current one had no dts, we will set this to AV_NOPTS_VALUE.
- int64_t last_dts = next_pkt->dts;
- while (pktl && next_pkt->pts == AV_NOPTS_VALUE) {
- if (pktl->pkt.stream_index == next_pkt->stream_index &&
- (av_compare_mod(next_pkt->dts, pktl->pkt.dts, 2LL << (wrap_bits - 1)) < 0)) {
- if (av_compare_mod(pktl->pkt.pts, pktl->pkt.dts, 2LL << (wrap_bits - 1))) {
- // not B-frame
- next_pkt->pts = pktl->pkt.dts;
- }
- if (last_dts != AV_NOPTS_VALUE) {
- // Once last dts was set to AV_NOPTS_VALUE, we don't change it.
- last_dts = pktl->pkt.dts;
- }
- }
- pktl = pktl->next;
- }
- if (eof && next_pkt->pts == AV_NOPTS_VALUE && last_dts != AV_NOPTS_VALUE) {
- // Fixing the last reference frame had none pts issue (For MXF etc).
- // We only do this when
- // 1. eof.
- // 2. we are not able to resolve a pts value for current packet.
- // 3. the packets for this stream at the end of the files had valid dts.
- next_pkt->pts = last_dts + next_pkt->duration;
- }
- pktl = s->internal->packet_buffer;
- }
-
- /* read packet from packet buffer, if there is data */
- 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 = read_from_packet_buffer(&s->internal->packet_buffer,
- &s->internal->packet_buffer_end, pkt);
- goto return_packet;
- }
- }
-
- ret = read_frame_internal(s, pkt);
- if (ret < 0) {
- if (pktl && ret != AVERROR(EAGAIN)) {
- eof = 1;
- continue;
- } else
- return ret;
- }
-
- if (av_dup_packet(add_to_pktbuf(&s->internal->packet_buffer, pkt,
- &s->internal->packet_buffer_end)) < 0)
- return AVERROR(ENOMEM);
- }
-
-return_packet:
-
- st = s->streams[pkt->stream_index];
- if ((s->iformat->flags & AVFMT_GENERIC_INDEX) && pkt->flags & AV_PKT_FLAG_KEY) {
- ff_reduce_index(s, st->index);
- av_add_index_entry(st, pkt->pos, pkt->dts, 0, 0, AVINDEX_KEYFRAME);
- }
-
- if (is_relative(pkt->dts))
- pkt->dts -= RELATIVE_TS_BASE;
- if (is_relative(pkt->pts))
- pkt->pts -= RELATIVE_TS_BASE;
-
- return ret;
-}
-
-/* XXX: suppress the packet queue */
-static void flush_packet_queue(AVFormatContext *s)
-{
- if (!s->internal)
- return;
- free_packet_buffer(&s->internal->parse_queue, &s->internal->parse_queue_end);
- free_packet_buffer(&s->internal->packet_buffer, &s->internal->packet_buffer_end);
- free_packet_buffer(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end);
-
- s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
-}
-
-/*******************************************************/
-/* seek support */
-
-int av_find_default_stream_index(AVFormatContext *s)
-{
- int i;
- AVStream *st;
- int best_stream = 0;
- int best_score = INT_MIN;
-
- if (s->nb_streams <= 0)
- return -1;
- for (i = 0; i < s->nb_streams; i++) {
- int score = 0;
- st = s->streams[i];
- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- if (st->disposition & AV_DISPOSITION_ATTACHED_PIC)
- score -= 400;
- if (st->codec->width && st->codec->height)
- score += 50;
- score+= 25;
- }
- if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- if (st->codec->sample_rate)
- score += 50;
- }
- if (st->codec_info_nb_frames)
- score += 12;
-
- if (st->discard != AVDISCARD_ALL)
- score += 200;
-
- if (score > best_score) {
- best_score = score;
- best_stream = i;
- }
- }
- return best_stream;
-}
-
-/** Flush the frame reader. */
-void ff_read_frame_flush(AVFormatContext *s)
-{
- AVStream *st;
- int i, j;
-
- flush_packet_queue(s);
-
- /* Reset read state for each stream. */
- for (i = 0; i < s->nb_streams; i++) {
- st = s->streams[i];
-
- if (st->parser) {
- av_parser_close(st->parser);
- st->parser = NULL;
- }
- st->last_IP_pts = AV_NOPTS_VALUE;
- st->last_dts_for_order_check = AV_NOPTS_VALUE;
- if (st->first_dts == AV_NOPTS_VALUE)
- st->cur_dts = RELATIVE_TS_BASE;
- else
- /* We set the current DTS to an unspecified origin. */
- st->cur_dts = AV_NOPTS_VALUE;
-
- st->probe_packets = MAX_PROBE_PACKETS;
-
- for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
- st->pts_buffer[j] = AV_NOPTS_VALUE;
-
- if (s->internal->inject_global_side_data)
- st->inject_global_side_data = 1;
-
- st->skip_samples = 0;
- }
-}
-
-void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
-{
- int i;
-
- for (i = 0; i < s->nb_streams; i++) {
- AVStream *st = s->streams[i];
-
- st->cur_dts =
- av_rescale(timestamp,
- st->time_base.den * (int64_t) ref_st->time_base.num,
- st->time_base.num * (int64_t) ref_st->time_base.den);
- }
-}
-
-void ff_reduce_index(AVFormatContext *s, int stream_index)
-{
- AVStream *st = s->streams[stream_index];
- unsigned int max_entries = s->max_index_size / sizeof(AVIndexEntry);
-
- if ((unsigned) st->nb_index_entries >= max_entries) {
- int i;
- for (i = 0; 2 * i < st->nb_index_entries; i++)
- st->index_entries[i] = st->index_entries[2 * i];
- st->nb_index_entries = i;
- }
-}
-
-int ff_add_index_entry(AVIndexEntry **index_entries,
- int *nb_index_entries,
- unsigned int *index_entries_allocated_size,
- int64_t pos, int64_t timestamp,
- int size, int distance, int flags)
-{
- AVIndexEntry *entries, *ie;
- int index;
-
- if ((unsigned) *nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
- return -1;
-
- if (timestamp == AV_NOPTS_VALUE)
- return AVERROR(EINVAL);
-
- if (size < 0 || size > 0x3FFFFFFF)
- return AVERROR(EINVAL);
-
- if (is_relative(timestamp)) //FIXME this maintains previous behavior but we should shift by the correct offset once known
- timestamp -= RELATIVE_TS_BASE;
-
- entries = av_fast_realloc(*index_entries,
- index_entries_allocated_size,
- (*nb_index_entries + 1) *
- sizeof(AVIndexEntry));
- if (!entries)
- return -1;
-
- *index_entries = entries;
-
- index = ff_index_search_timestamp(*index_entries, *nb_index_entries,
- timestamp, AVSEEK_FLAG_ANY);
-
- if (index < 0) {
- index = (*nb_index_entries)++;
- ie = &entries[index];
- av_assert0(index == 0 || ie[-1].timestamp < timestamp);
- } else {
- ie = &entries[index];
- if (ie->timestamp != timestamp) {
- if (ie->timestamp <= timestamp)
- return -1;
- memmove(entries + index + 1, entries + index,
- sizeof(AVIndexEntry) * (*nb_index_entries - index));
- (*nb_index_entries)++;
- } else if (ie->pos == pos && distance < ie->min_distance)
- // do not reduce the distance
- distance = ie->min_distance;
- }
-
- ie->pos = pos;
- ie->timestamp = timestamp;
- ie->min_distance = distance;
- ie->size = size;
- ie->flags = flags;
-
- return index;
-}
-
-int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
- int size, int distance, int flags)
-{
- timestamp = wrap_timestamp(st, timestamp);
- return ff_add_index_entry(&st->index_entries, &st->nb_index_entries,
- &st->index_entries_allocated_size, pos,
- timestamp, size, distance, flags);
-}
-
-int ff_index_search_timestamp(const AVIndexEntry *entries, int nb_entries,
- int64_t wanted_timestamp, int flags)
-{
- int a, b, m;
- int64_t timestamp;
-
- a = -1;
- b = nb_entries;
-
- // Optimize appending index entries at the end.
- if (b && entries[b - 1].timestamp < wanted_timestamp)
- a = b - 1;
-
- while (b - a > 1) {
- m = (a + b) >> 1;
- timestamp = entries[m].timestamp;
- if (timestamp >= wanted_timestamp)
- b = m;
- if (timestamp <= wanted_timestamp)
- a = m;
- }
- m = (flags & AVSEEK_FLAG_BACKWARD) ? a : b;
-
- if (!(flags & AVSEEK_FLAG_ANY))
- while (m >= 0 && m < nb_entries &&
- !(entries[m].flags & AVINDEX_KEYFRAME))
- m += (flags & AVSEEK_FLAG_BACKWARD) ? -1 : 1;
-
- if (m == nb_entries)
- return -1;
- return m;
-}
-
-void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
-{
- int ist1, ist2;
- int64_t pos_delta = 0;
- int64_t skip = 0;
- //We could use URLProtocol flags here but as many user applications do not use URLProtocols this would be unreliable
- const char *proto = avio_find_protocol_name(s->filename);
-
- if (!proto) {
- av_log(s, AV_LOG_INFO,
- "Protocol name not provided, cannot determine if input is local or "
- "a network protocol, buffers and access patterns cannot be configured "
- "optimally without knowing the protocol\n");
- }
-
- if (proto && !(strcmp(proto, "file") && strcmp(proto, "pipe") && strcmp(proto, "cache")))
- return;
-
- for (ist1 = 0; ist1 < s->nb_streams; ist1++) {
- AVStream *st1 = s->streams[ist1];
- for (ist2 = 0; ist2 < s->nb_streams; ist2++) {
- AVStream *st2 = s->streams[ist2];
- int i1, i2;
-
- if (ist1 == ist2)
- continue;
-
- for (i1 = i2 = 0; i1 < st1->nb_index_entries; i1++) {
- AVIndexEntry *e1 = &st1->index_entries[i1];
- int64_t e1_pts = av_rescale_q(e1->timestamp, st1->time_base, AV_TIME_BASE_Q);
-
- skip = FFMAX(skip, e1->size);
- for (; i2 < st2->nb_index_entries; i2++) {
- AVIndexEntry *e2 = &st2->index_entries[i2];
- int64_t e2_pts = av_rescale_q(e2->timestamp, st2->time_base, AV_TIME_BASE_Q);
- if (e2_pts - e1_pts < time_tolerance)
- continue;
- pos_delta = FFMAX(pos_delta, e1->pos - e2->pos);
- break;
- }
- }
- }
- }
-
- pos_delta *= 2;
- /* XXX This could be adjusted depending on protocol*/
- if (s->pb->buffer_size < pos_delta && pos_delta < (1<<24)) {
- av_log(s, AV_LOG_VERBOSE, "Reconfiguring buffers to size %"PRId64"\n", pos_delta);
- ffio_set_buf_size(s->pb, pos_delta);
- s->pb->short_seek_threshold = FFMAX(s->pb->short_seek_threshold, pos_delta/2);
- }
-
- if (skip < (1<<23)) {
- s->pb->short_seek_threshold = FFMAX(s->pb->short_seek_threshold, skip);
- }
-}
-
-int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int flags)
-{
- return ff_index_search_timestamp(st->index_entries, st->nb_index_entries,
- wanted_timestamp, flags);
-}
-
-static int64_t ff_read_timestamp(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit,
- int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
-{
- int64_t ts = read_timestamp(s, stream_index, ppos, pos_limit);
- if (stream_index >= 0)
- ts = wrap_timestamp(s->streams[stream_index], ts);
- return ts;
-}
-
-int ff_seek_frame_binary(AVFormatContext *s, int stream_index,
- int64_t target_ts, int flags)
-{
- AVInputFormat *avif = s->iformat;
- int64_t av_uninit(pos_min), av_uninit(pos_max), pos, pos_limit;
- int64_t ts_min, ts_max, ts;
- int index;
- int64_t ret;
- AVStream *st;
-
- if (stream_index < 0)
- return -1;
-
- av_log(s, AV_LOG_TRACE, "read_seek: %d %s\n", stream_index, av_ts2str(target_ts));
-
- ts_max =
- ts_min = AV_NOPTS_VALUE;
- pos_limit = -1; // GCC falsely says it may be uninitialized.
-
- st = s->streams[stream_index];
- if (st->index_entries) {
- AVIndexEntry *e;
-
- /* FIXME: Whole function must be checked for non-keyframe entries in
- * index case, especially read_timestamp(). */
- index = av_index_search_timestamp(st, target_ts,
- flags | AVSEEK_FLAG_BACKWARD);
- index = FFMAX(index, 0);
- e = &st->index_entries[index];
-
- if (e->timestamp <= target_ts || e->pos == e->min_distance) {
- pos_min = e->pos;
- ts_min = e->timestamp;
- av_log(s, AV_LOG_TRACE, "using cached pos_min=0x%"PRIx64" dts_min=%s\n",
- pos_min, av_ts2str(ts_min));
- } else {
- av_assert1(index == 0);
- }
-
- index = av_index_search_timestamp(st, target_ts,
- flags & ~AVSEEK_FLAG_BACKWARD);
- av_assert0(index < st->nb_index_entries);
- if (index >= 0) {
- e = &st->index_entries[index];
- av_assert1(e->timestamp >= target_ts);
- pos_max = e->pos;
- ts_max = e->timestamp;
- pos_limit = pos_max - e->min_distance;
- av_log(s, AV_LOG_TRACE, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64
- " dts_max=%s\n", pos_max, pos_limit, av_ts2str(ts_max));
- }
- }
-
- pos = ff_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit,
- ts_min, ts_max, flags, &ts, avif->read_timestamp);
- if (pos < 0)
- return -1;
-
- /* do the seek */
- if ((ret = avio_seek(s->pb, pos, SEEK_SET)) < 0)
- return ret;
-
- ff_read_frame_flush(s);
- ff_update_cur_dts(s, st, ts);
-
- return 0;
-}
-
-int ff_find_last_ts(AVFormatContext *s, int stream_index, int64_t *ts, int64_t *pos,
- int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
-{
- int64_t step = 1024;
- int64_t limit, ts_max;
- int64_t filesize = avio_size(s->pb);
- int64_t pos_max = filesize - 1;
- do {
- limit = pos_max;
- pos_max = FFMAX(0, (pos_max) - step);
- ts_max = ff_read_timestamp(s, stream_index,
- &pos_max, limit, read_timestamp);
- step += step;
- } while (ts_max == AV_NOPTS_VALUE && 2*limit > step);
- if (ts_max == AV_NOPTS_VALUE)
- return -1;
-
- for (;;) {
- int64_t tmp_pos = pos_max + 1;
- int64_t tmp_ts = ff_read_timestamp(s, stream_index,
- &tmp_pos, INT64_MAX, read_timestamp);
- if (tmp_ts == AV_NOPTS_VALUE)
- break;
- av_assert0(tmp_pos > pos_max);
- ts_max = tmp_ts;
- pos_max = tmp_pos;
- if (tmp_pos >= filesize)
- break;
- }
-
- if (ts)
- *ts = ts_max;
- if (pos)
- *pos = pos_max;
-
- return 0;
-}
-
-int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
- int64_t pos_min, int64_t pos_max, int64_t pos_limit,
- int64_t ts_min, int64_t ts_max,
- int flags, int64_t *ts_ret,
- int64_t (*read_timestamp)(struct AVFormatContext *, int,
- int64_t *, int64_t))
-{
- int64_t pos, ts;
- int64_t start_pos;
- int no_change;
- int ret;
-
- av_log(s, AV_LOG_TRACE, "gen_seek: %d %s\n", stream_index, av_ts2str(target_ts));
-
- if (ts_min == AV_NOPTS_VALUE) {
- pos_min = s->internal->data_offset;
- ts_min = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp);
- if (ts_min == AV_NOPTS_VALUE)
- return -1;
- }
-
- if (ts_min >= target_ts) {
- *ts_ret = ts_min;
- return pos_min;
- }
-
- if (ts_max == AV_NOPTS_VALUE) {
- if ((ret = ff_find_last_ts(s, stream_index, &ts_max, &pos_max, read_timestamp)) < 0)
- return ret;
- pos_limit = pos_max;
- }
-
- if (ts_max <= target_ts) {
- *ts_ret = ts_max;
- return pos_max;
- }
-
- av_assert0(ts_min < ts_max);
-
- no_change = 0;
- while (pos_min < pos_limit) {
- av_log(s, AV_LOG_TRACE,
- "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%s dts_max=%s\n",
- pos_min, pos_max, av_ts2str(ts_min), av_ts2str(ts_max));
- av_assert0(pos_limit <= pos_max);
-
- if (no_change == 0) {
- int64_t approximate_keyframe_distance = pos_max - pos_limit;
- // interpolate position (better than dichotomy)
- pos = av_rescale(target_ts - ts_min, pos_max - pos_min,
- ts_max - ts_min) +
- pos_min - approximate_keyframe_distance;
- } else if (no_change == 1) {
- // bisection if interpolation did not change min / max pos last time
- pos = (pos_min + pos_limit) >> 1;
- } else {
- /* linear search if bisection failed, can only happen if there
- * are very few or no keyframes between min/max */
- pos = pos_min;
- }
- if (pos <= pos_min)
- pos = pos_min + 1;
- else if (pos > pos_limit)
- pos = pos_limit;
- start_pos = pos;
-
- // May pass pos_limit instead of -1.
- ts = ff_read_timestamp(s, stream_index, &pos, INT64_MAX, read_timestamp);
- if (pos == pos_max)
- no_change++;
- else
- no_change = 0;
- av_log(s, AV_LOG_TRACE, "%"PRId64" %"PRId64" %"PRId64" / %s %s %s"
- " target:%s limit:%"PRId64" start:%"PRId64" noc:%d\n",
- pos_min, pos, pos_max,
- av_ts2str(ts_min), av_ts2str(ts), av_ts2str(ts_max), av_ts2str(target_ts),
- pos_limit, start_pos, no_change);
- if (ts == AV_NOPTS_VALUE) {
- av_log(s, AV_LOG_ERROR, "read_timestamp() failed in the middle\n");
- return -1;
- }
- if (target_ts <= ts) {
- pos_limit = start_pos - 1;
- pos_max = pos;
- ts_max = ts;
- }
- if (target_ts >= ts) {
- pos_min = pos;
- ts_min = ts;
- }
- }
-
- pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max;
- ts = (flags & AVSEEK_FLAG_BACKWARD) ? ts_min : ts_max;
-#if 0
- pos_min = pos;
- ts_min = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp);
- pos_min++;
- ts_max = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp);
- av_log(s, AV_LOG_TRACE, "pos=0x%"PRIx64" %s<=%s<=%s\n",
- pos, av_ts2str(ts_min), av_ts2str(target_ts), av_ts2str(ts_max));
-#endif
- *ts_ret = ts;
- return pos;
-}
-
-static int seek_frame_byte(AVFormatContext *s, int stream_index,
- int64_t pos, int flags)
-{
- int64_t pos_min, pos_max;
-
- pos_min = s->internal->data_offset;
- pos_max = avio_size(s->pb) - 1;
-
- if (pos < pos_min)
- pos = pos_min;
- else if (pos > pos_max)
- pos = pos_max;
-
- avio_seek(s->pb, pos, SEEK_SET);
-
- s->io_repositioned = 1;
-
- return 0;
-}
-
-static int seek_frame_generic(AVFormatContext *s, int stream_index,
- int64_t timestamp, int flags)
-{
- int index;
- int64_t ret;
- AVStream *st;
- AVIndexEntry *ie;
-
- st = s->streams[stream_index];
-
- index = av_index_search_timestamp(st, timestamp, flags);
-
- if (index < 0 && st->nb_index_entries &&
- timestamp < st->index_entries[0].timestamp)
- return -1;
-
- if (index < 0 || index == st->nb_index_entries - 1) {
- AVPacket pkt;
- int nonkey = 0;
-
- if (st->nb_index_entries) {
- av_assert0(st->index_entries);
- ie = &st->index_entries[st->nb_index_entries - 1];
- if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)
- return ret;
- ff_update_cur_dts(s, st, ie->timestamp);
- } else {
- if ((ret = avio_seek(s->pb, s->internal->data_offset, SEEK_SET)) < 0)
- return ret;
- }
- for (;;) {
- int read_status;
- do {
- read_status = av_read_frame(s, &pkt);
- } while (read_status == AVERROR(EAGAIN));
- if (read_status < 0)
- break;
- av_free_packet(&pkt);
- if (stream_index == pkt.stream_index && pkt.dts > timestamp) {
- if (pkt.flags & AV_PKT_FLAG_KEY)
- break;
- if (nonkey++ > 1000 && st->codec->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);
- break;
- }
- }
- }
- index = av_index_search_timestamp(st, timestamp, flags);
- }
- if (index < 0)
- return -1;
-
- ff_read_frame_flush(s);
- if (s->iformat->read_seek)
- if (s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0)
- return 0;
- ie = &st->index_entries[index];
- if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)
- return ret;
- ff_update_cur_dts(s, st, ie->timestamp);
-
- return 0;
-}
-
-static int seek_frame_internal(AVFormatContext *s, int stream_index,
- int64_t timestamp, int flags)
-{
- int ret;
- AVStream *st;
-
- if (flags & AVSEEK_FLAG_BYTE) {
- if (s->iformat->flags & AVFMT_NO_BYTE_SEEK)
- return -1;
- ff_read_frame_flush(s);
- return seek_frame_byte(s, stream_index, timestamp, flags);
- }
-
- if (stream_index < 0) {
- stream_index = av_find_default_stream_index(s);
- if (stream_index < 0)
- return -1;
-
- st = s->streams[stream_index];
- /* timestamp for default must be expressed in AV_TIME_BASE units */
- timestamp = av_rescale(timestamp, st->time_base.den,
- AV_TIME_BASE * (int64_t) st->time_base.num);
- }
-
- /* first, we try the format specific seek */
- if (s->iformat->read_seek) {
- ff_read_frame_flush(s);
- ret = s->iformat->read_seek(s, stream_index, timestamp, flags);
- } else
- ret = -1;
- if (ret >= 0)
- return 0;
-
- if (s->iformat->read_timestamp &&
- !(s->iformat->flags & AVFMT_NOBINSEARCH)) {
- ff_read_frame_flush(s);
- return ff_seek_frame_binary(s, stream_index, timestamp, flags);
- } else if (!(s->iformat->flags & AVFMT_NOGENSEARCH)) {
- ff_read_frame_flush(s);
- return seek_frame_generic(s, stream_index, timestamp, flags);
- } else
- return -1;
-}
-
-int av_seek_frame(AVFormatContext *s, int stream_index,
- int64_t timestamp, int flags)
-{
- int ret;
-
- if (s->iformat->read_seek2 && !s->iformat->read_seek) {
- int64_t min_ts = INT64_MIN, max_ts = INT64_MAX;
- if ((flags & AVSEEK_FLAG_BACKWARD))
- max_ts = timestamp;
- else
- min_ts = timestamp;
- return avformat_seek_file(s, stream_index, min_ts, timestamp, max_ts,
- flags & ~AVSEEK_FLAG_BACKWARD);
- }
-
- ret = seek_frame_internal(s, stream_index, timestamp, flags);
-
- if (ret >= 0)
- ret = avformat_queue_attached_pictures(s);
-
- return ret;
-}
-
-int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts,
- int64_t ts, int64_t max_ts, int flags)
-{
- if (min_ts > ts || max_ts < ts)
- return -1;
- if (stream_index < -1 || stream_index >= (int)s->nb_streams)
- return AVERROR(EINVAL);
-
- if (s->seek2any>0)
- flags |= AVSEEK_FLAG_ANY;
- flags &= ~AVSEEK_FLAG_BACKWARD;
-
- if (s->iformat->read_seek2) {
- int ret;
- ff_read_frame_flush(s);
-
- if (stream_index == -1 && s->nb_streams == 1) {
- AVRational time_base = s->streams[0]->time_base;
- ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base);
- min_ts = av_rescale_rnd(min_ts, time_base.den,
- time_base.num * (int64_t)AV_TIME_BASE,
- AV_ROUND_UP | AV_ROUND_PASS_MINMAX);
- max_ts = av_rescale_rnd(max_ts, time_base.den,
- time_base.num * (int64_t)AV_TIME_BASE,
- AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
- stream_index = 0;
- }
-
- ret = s->iformat->read_seek2(s, stream_index, min_ts,
- ts, max_ts, flags);
-
- if (ret >= 0)
- ret = avformat_queue_attached_pictures(s);
- return ret;
- }
-
- if (s->iformat->read_timestamp) {
- // try to seek via read_timestamp()
- }
-
- // Fall back on old API if new is not implemented but old is.
- // Note the old API has somewhat different semantics.
- if (s->iformat->read_seek || 1) {
- int dir = (ts - (uint64_t)min_ts > (uint64_t)max_ts - ts ? AVSEEK_FLAG_BACKWARD : 0);
- int ret = av_seek_frame(s, stream_index, ts, flags | dir);
- if (ret<0 && ts != min_ts && max_ts != ts) {
- ret = av_seek_frame(s, stream_index, dir ? max_ts : min_ts, flags | dir);
- if (ret >= 0)
- ret = av_seek_frame(s, stream_index, ts, flags | (dir^AVSEEK_FLAG_BACKWARD));
- }
- return ret;
- }
-
- // try some generic seek like seek_frame_generic() but with new ts semantics
- return -1; //unreachable
-}
-
-int avformat_flush(AVFormatContext *s)
-{
- ff_read_frame_flush(s);
- return 0;
-}
-
-/*******************************************************/
-
-/**
- * Return TRUE if the stream has accurate duration in any stream.
- *
- * @return TRUE if the stream has accurate duration for at least one component.
- */
-static int has_duration(AVFormatContext *ic)
-{
- int i;
- AVStream *st;
-
- for (i = 0; i < ic->nb_streams; i++) {
- st = ic->streams[i];
- if (st->duration != AV_NOPTS_VALUE)
- return 1;
- }
- if (ic->duration != AV_NOPTS_VALUE)
- return 1;
- return 0;
-}
-
-/**
- * Estimate the stream timings from the one of each components.
- *
- * Also computes the global bitrate if possible.
- */
-static void update_stream_timings(AVFormatContext *ic)
-{
- int64_t start_time, start_time1, start_time_text, end_time, end_time1;
- int64_t duration, duration1, filesize;
- int i;
- AVStream *st;
- AVProgram *p;
-
- start_time = INT64_MAX;
- start_time_text = INT64_MAX;
- end_time = INT64_MIN;
- duration = INT64_MIN;
- for (i = 0; i < ic->nb_streams; i++) {
- st = ic->streams[i];
- if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) {
- start_time1 = av_rescale_q(st->start_time, st->time_base,
- AV_TIME_BASE_Q);
- if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE || st->codec->codec_type == AVMEDIA_TYPE_DATA) {
- if (start_time1 < start_time_text)
- start_time_text = start_time1;
- } else
- start_time = FFMIN(start_time, start_time1);
- end_time1 = AV_NOPTS_VALUE;
- if (st->duration != AV_NOPTS_VALUE) {
- end_time1 = start_time1 +
- av_rescale_q(st->duration, st->time_base,
- AV_TIME_BASE_Q);
- end_time = FFMAX(end_time, end_time1);
- }
- for (p = NULL; (p = av_find_program_from_stream(ic, p, i)); ) {
- if (p->start_time == AV_NOPTS_VALUE || p->start_time > start_time1)
- p->start_time = start_time1;
- if (p->end_time < end_time1)
- p->end_time = end_time1;
- }
- }
- if (st->duration != AV_NOPTS_VALUE) {
- duration1 = av_rescale_q(st->duration, st->time_base,
- AV_TIME_BASE_Q);
- duration = FFMAX(duration, duration1);
- }
- }
- if (start_time == INT64_MAX || (start_time > start_time_text && start_time - start_time_text < AV_TIME_BASE))
- start_time = start_time_text;
- else if (start_time > start_time_text)
- av_log(ic, AV_LOG_VERBOSE, "Ignoring outlier non primary stream starttime %f\n", start_time_text / (float)AV_TIME_BASE);
-
- if (start_time != INT64_MAX) {
- ic->start_time = start_time;
- if (end_time != INT64_MIN) {
- if (ic->nb_programs) {
- for (i = 0; i < ic->nb_programs; i++) {
- p = ic->programs[i];
- if (p->start_time != AV_NOPTS_VALUE &&
- p->end_time > p->start_time &&
- p->end_time - (uint64_t)p->start_time <= INT64_MAX)
- duration = FFMAX(duration, p->end_time - p->start_time);
- }
- } else if (end_time >= start_time && end_time - (uint64_t)start_time <= INT64_MAX) {
- duration = FFMAX(duration, end_time - start_time);
- }
- }
- }
- if (duration != INT64_MIN && duration > 0 && ic->duration == AV_NOPTS_VALUE) {
- ic->duration = duration;
- }
- if (ic->pb && (filesize = avio_size(ic->pb)) > 0 && ic->duration > 0) {
- /* compute the bitrate */
- double bitrate = (double) filesize * 8.0 * AV_TIME_BASE /
- (double) ic->duration;
- if (bitrate >= 0 && bitrate <= INT_MAX)
- ic->bit_rate = bitrate;
- }
-}
-
-static void fill_all_stream_timings(AVFormatContext *ic)
-{
- int i;
- AVStream *st;
-
- update_stream_timings(ic);
- for (i = 0; i < ic->nb_streams; i++) {
- st = ic->streams[i];
- if (st->start_time == AV_NOPTS_VALUE) {
- if (ic->start_time != AV_NOPTS_VALUE)
- st->start_time = av_rescale_q(ic->start_time, AV_TIME_BASE_Q,
- st->time_base);
- if (ic->duration != AV_NOPTS_VALUE)
- st->duration = av_rescale_q(ic->duration, AV_TIME_BASE_Q,
- st->time_base);
- }
- }
-}
-
-static void estimate_timings_from_bit_rate(AVFormatContext *ic)
-{
- int64_t filesize, duration;
- int i, show_warning = 0;
- AVStream *st;
-
- /* if bit_rate is already set, we believe it */
- if (ic->bit_rate <= 0) {
- int bit_rate = 0;
- for (i = 0; i < ic->nb_streams; i++) {
- st = ic->streams[i];
- if (st->codec->bit_rate > 0) {
- if (INT_MAX - st->codec->bit_rate < bit_rate) {
- bit_rate = 0;
- break;
- }
- bit_rate += st->codec->bit_rate;
- } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->codec_info_nb_frames > 1) {
- // If we have a videostream with packets but without a bitrate
- // then consider the sum not known
- bit_rate = 0;
- break;
- }
- }
- ic->bit_rate = bit_rate;
- }
-
- /* if duration is already set, we believe it */
- if (ic->duration == AV_NOPTS_VALUE &&
- ic->bit_rate != 0) {
- filesize = ic->pb ? avio_size(ic->pb) : 0;
- if (filesize > ic->internal->data_offset) {
- filesize -= ic->internal->data_offset;
- for (i = 0; i < ic->nb_streams; i++) {
- st = ic->streams[i];
- if ( st->time_base.num <= INT64_MAX / ic->bit_rate
- && st->duration == AV_NOPTS_VALUE) {
- duration = av_rescale(8 * filesize, st->time_base.den,
- ic->bit_rate *
- (int64_t) st->time_base.num);
- st->duration = duration;
- show_warning = 1;
- }
- }
- }
- }
- if (show_warning)
- av_log(ic, AV_LOG_WARNING,
- "Estimating duration from bitrate, this may be inaccurate\n");
-}
-
-#define DURATION_MAX_READ_SIZE 250000LL
-#define DURATION_MAX_RETRY 6
-
-/* only usable for MPEG-PS streams */
-static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
-{
- AVPacket pkt1, *pkt = &pkt1;
- AVStream *st;
- int num, den, read_size, i, ret;
- int found_duration = 0;
- int is_end;
- int64_t filesize, offset, duration;
- int retry = 0;
-
- /* flush packet queue */
- flush_packet_queue(ic);
-
- for (i = 0; i < ic->nb_streams; i++) {
- st = ic->streams[i];
- if (st->start_time == AV_NOPTS_VALUE &&
- st->first_dts == AV_NOPTS_VALUE &&
- st->codec->codec_type != AVMEDIA_TYPE_UNKNOWN)
- av_log(st->codec, AV_LOG_WARNING,
- "start time for stream %d is not set in estimate_timings_from_pts\n", i);
-
- if (st->parser) {
- av_parser_close(st->parser);
- st->parser = NULL;
- }
- }
-
- av_opt_set(ic, "skip_changes", "1", AV_OPT_SEARCH_CHILDREN);
- /* estimate the end time (duration) */
- /* XXX: may need to support wrapping */
- filesize = ic->pb ? avio_size(ic->pb) : 0;
- do {
- is_end = found_duration;
- offset = filesize - (DURATION_MAX_READ_SIZE << retry);
- if (offset < 0)
- offset = 0;
-
- avio_seek(ic->pb, offset, SEEK_SET);
- read_size = 0;
- for (;;) {
- if (read_size >= DURATION_MAX_READ_SIZE << (FFMAX(retry - 1, 0)))
- break;
-
- do {
- ret = ff_read_packet(ic, pkt);
- } while (ret == AVERROR(EAGAIN));
- if (ret != 0)
- break;
- read_size += pkt->size;
- st = ic->streams[pkt->stream_index];
- if (pkt->pts != AV_NOPTS_VALUE &&
- (st->start_time != AV_NOPTS_VALUE ||
- st->first_dts != AV_NOPTS_VALUE)) {
- if (pkt->duration == 0) {
- ff_compute_frame_duration(ic, &num, &den, st, st->parser, pkt);
- if (den && num) {
- pkt->duration = av_rescale_rnd(1,
- num * (int64_t) st->time_base.den,
- den * (int64_t) st->time_base.num,
- AV_ROUND_DOWN);
- }
- }
- duration = pkt->pts + pkt->duration;
- found_duration = 1;
- if (st->start_time != AV_NOPTS_VALUE)
- duration -= st->start_time;
- 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))
- st->duration = duration;
- st->info->last_duration = duration;
- }
- }
- av_free_packet(pkt);
- }
-
- /* check if all audio/video streams have valid duration */
- if (!is_end) {
- is_end = 1;
- for (i = 0; i < ic->nb_streams; i++) {
- st = ic->streams[i];
- switch (st->codec->codec_type) {
- case AVMEDIA_TYPE_VIDEO:
- case AVMEDIA_TYPE_AUDIO:
- if (st->duration == AV_NOPTS_VALUE)
- is_end = 0;
- }
- }
- }
- } while (!is_end &&
- offset &&
- ++retry <= DURATION_MAX_RETRY);
-
- av_opt_set(ic, "skip_changes", "0", AV_OPT_SEARCH_CHILDREN);
-
- /* warn about audio/video streams which duration could not be estimated */
- for (i = 0; i < ic->nb_streams; i++) {
- st = ic->streams[i];
- if (st->duration == AV_NOPTS_VALUE) {
- switch (st->codec->codec_type) {
- case AVMEDIA_TYPE_VIDEO:
- case AVMEDIA_TYPE_AUDIO:
- if (st->start_time != AV_NOPTS_VALUE || st->first_dts != AV_NOPTS_VALUE) {
- av_log(ic, AV_LOG_DEBUG, "stream %d : no PTS found at end of file, duration not set\n", i);
- } else
- av_log(ic, AV_LOG_DEBUG, "stream %d : no TS found at start of file, duration not set\n", i);
- }
- }
- }
- fill_all_stream_timings(ic);
-
- avio_seek(ic->pb, old_offset, SEEK_SET);
- for (i = 0; i < ic->nb_streams; i++) {
- int j;
-
- 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;
- for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
- st->pts_buffer[j] = AV_NOPTS_VALUE;
- }
-}
-
-static void estimate_timings(AVFormatContext *ic, int64_t old_offset)
-{
- int64_t file_size;
-
- /* get the file size, if possible */
- if (ic->iformat->flags & AVFMT_NOFILE) {
- file_size = 0;
- } else {
- file_size = avio_size(ic->pb);
- file_size = FFMAX(0, file_size);
- }
-
- if ((!strcmp(ic->iformat->name, "mpeg") ||
- !strcmp(ic->iformat->name, "mpegts")) &&
- file_size && ic->pb->seekable) {
- /* get accurate estimate from the PTSes */
- estimate_timings_from_pts(ic, old_offset);
- ic->duration_estimation_method = AVFMT_DURATION_FROM_PTS;
- } else if (has_duration(ic)) {
- /* at least one component has timings - we use them for all
- * the components */
- fill_all_stream_timings(ic);
- ic->duration_estimation_method = AVFMT_DURATION_FROM_STREAM;
- } else {
- /* less precise: use bitrate info */
- estimate_timings_from_bit_rate(ic);
- ic->duration_estimation_method = AVFMT_DURATION_FROM_BITRATE;
- }
- update_stream_timings(ic);
-
- {
- int i;
- AVStream av_unused *st;
- for (i = 0; i < ic->nb_streams; i++) {
- st = ic->streams[i];
- av_log(ic, AV_LOG_TRACE, "%d: start_time: %0.3f duration: %0.3f\n", i,
- (double) st->start_time / AV_TIME_BASE,
- (double) st->duration / AV_TIME_BASE);
- }
- av_log(ic, AV_LOG_TRACE,
- "stream: start_time: %0.3f duration: %0.3f bitrate=%d kb/s\n",
- (double) ic->start_time / AV_TIME_BASE,
- (double) ic->duration / AV_TIME_BASE,
- ic->bit_rate / 1000);
- }
-}
-
-static int has_codec_parameters(AVStream *st, const char **errmsg_ptr)
-{
- AVCodecContext *avctx = st->codec;
-
-#define FAIL(errmsg) do { \
- if (errmsg_ptr) \
- *errmsg_ptr = errmsg; \
- return 0; \
- } while (0)
-
- if ( avctx->codec_id == AV_CODEC_ID_NONE
- && avctx->codec_type != AVMEDIA_TYPE_DATA)
- FAIL("unknown codec");
- switch (avctx->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- if (!avctx->frame_size && determinable_frame_size(avctx))
- FAIL("unspecified frame size");
- if (st->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)
- 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)
- FAIL("unspecified pixel format");
- if (st->codec->codec_id == AV_CODEC_ID_RV30 || st->codec->codec_id == AV_CODEC_ID_RV40)
- if (!st->sample_aspect_ratio.num && !st->codec->sample_aspect_ratio.num && !st->codec_info_nb_frames)
- FAIL("no frame in rv30/40 and no sar");
- break;
- case AVMEDIA_TYPE_SUBTITLE:
- if (avctx->codec_id == AV_CODEC_ID_HDMV_PGS_SUBTITLE && !avctx->width)
- FAIL("unspecified size");
- break;
- case AVMEDIA_TYPE_DATA:
- if (avctx->codec_id == AV_CODEC_ID_NONE) return 1;
- }
-
- return 1;
-}
-
-/* returns 1 or 0 if or if not decoded data was returned, or a negative error */
-static int try_decode_frame(AVFormatContext *s, AVStream *st, AVPacket *avpkt,
- AVDictionary **options)
-{
- const AVCodec *codec;
- int got_picture = 1, ret = 0;
- AVFrame *frame = av_frame_alloc();
- AVSubtitle subtitle;
- AVPacket pkt = *avpkt;
-
- if (!frame)
- return AVERROR(ENOMEM);
-
- if (!avcodec_is_open(st->codec) &&
- st->info->found_decoder <= 0 &&
- (st->codec->codec_id != -st->info->found_decoder || !st->codec->codec_id)) {
- AVDictionary *thread_opt = NULL;
-
- codec = find_decoder(s, st, st->codec->codec_id);
-
- if (!codec) {
- st->info->found_decoder = -st->codec->codec_id;
- ret = -1;
- goto fail;
- }
-
- /* 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);
- if (s->codec_whitelist)
- av_dict_set(options ? options : &thread_opt, "codec_whitelist", s->codec_whitelist, 0);
- ret = avcodec_open2(st->codec, codec, options ? options : &thread_opt);
- if (!options)
- av_dict_free(&thread_opt);
- if (ret < 0) {
- st->info->found_decoder = -st->codec->codec_id;
- goto fail;
- }
- st->info->found_decoder = 1;
- } else if (!st->info->found_decoder)
- st->info->found_decoder = 1;
-
- if (st->info->found_decoder < 0) {
- ret = -1;
- goto fail;
- }
-
- while ((pkt.size > 0 || (!pkt.data && got_picture)) &&
- ret >= 0 &&
- (!has_codec_parameters(st, NULL) || !has_decode_delay_been_guessed(st) ||
- (!st->codec_info_nb_frames &&
- (st->codec->codec->capabilities & AV_CODEC_CAP_CHANNEL_CONF)))) {
- got_picture = 0;
- switch (st->codec->codec_type) {
- case AVMEDIA_TYPE_VIDEO:
- ret = avcodec_decode_video2(st->codec, frame,
- &got_picture, &pkt);
- break;
- case AVMEDIA_TYPE_AUDIO:
- ret = avcodec_decode_audio4(st->codec, frame, &got_picture, &pkt);
- break;
- case AVMEDIA_TYPE_SUBTITLE:
- ret = avcodec_decode_subtitle2(st->codec, &subtitle,
- &got_picture, &pkt);
- ret = pkt.size;
- break;
- default:
- break;
- }
- if (ret >= 0) {
- if (got_picture)
- st->nb_decoded_frames++;
- pkt.data += ret;
- pkt.size -= ret;
- ret = got_picture;
- }
- }
-
- if (!pkt.data && !got_picture)
- ret = -1;
-
-fail:
- av_frame_free(&frame);
- return ret;
-}
-
-unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id)
-{
- while (tags->id != AV_CODEC_ID_NONE) {
- if (tags->id == id)
- return tags->tag;
- tags++;
- }
- return 0;
-}
-
-enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
-{
- int i;
- for (i = 0; tags[i].id != AV_CODEC_ID_NONE; i++)
- if (tag == tags[i].tag)
- return tags[i].id;
- for (i = 0; tags[i].id != AV_CODEC_ID_NONE; i++)
- if (avpriv_toupper4(tag) == avpriv_toupper4(tags[i].tag))
- return tags[i].id;
- return AV_CODEC_ID_NONE;
-}
-
-enum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags)
-{
- if (bps <= 0 || bps > 64)
- return AV_CODEC_ID_NONE;
-
- if (flt) {
- switch (bps) {
- case 32:
- return be ? AV_CODEC_ID_PCM_F32BE : AV_CODEC_ID_PCM_F32LE;
- case 64:
- return be ? AV_CODEC_ID_PCM_F64BE : AV_CODEC_ID_PCM_F64LE;
- default:
- return AV_CODEC_ID_NONE;
- }
- } else {
- bps += 7;
- bps >>= 3;
- if (sflags & (1 << (bps - 1))) {
- switch (bps) {
- case 1:
- return AV_CODEC_ID_PCM_S8;
- case 2:
- return be ? AV_CODEC_ID_PCM_S16BE : AV_CODEC_ID_PCM_S16LE;
- case 3:
- return be ? AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
- case 4:
- return be ? AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
- default:
- return AV_CODEC_ID_NONE;
- }
- } else {
- switch (bps) {
- case 1:
- return AV_CODEC_ID_PCM_U8;
- case 2:
- return be ? AV_CODEC_ID_PCM_U16BE : AV_CODEC_ID_PCM_U16LE;
- case 3:
- return be ? AV_CODEC_ID_PCM_U24BE : AV_CODEC_ID_PCM_U24LE;
- case 4:
- return be ? AV_CODEC_ID_PCM_U32BE : AV_CODEC_ID_PCM_U32LE;
- default:
- return AV_CODEC_ID_NONE;
- }
- }
- }
-}
-
-unsigned int av_codec_get_tag(const AVCodecTag *const *tags, enum AVCodecID id)
-{
- unsigned int tag;
- if (!av_codec_get_tag2(tags, id, &tag))
- return 0;
- return tag;
-}
-
-int av_codec_get_tag2(const AVCodecTag * const *tags, enum AVCodecID id,
- unsigned int *tag)
-{
- int i;
- for (i = 0; tags && tags[i]; i++) {
- const AVCodecTag *codec_tags = tags[i];
- while (codec_tags->id != AV_CODEC_ID_NONE) {
- if (codec_tags->id == id) {
- *tag = codec_tags->tag;
- return 1;
- }
- codec_tags++;
- }
- }
- return 0;
-}
-
-enum AVCodecID av_codec_get_id(const AVCodecTag *const *tags, unsigned int tag)
-{
- int i;
- for (i = 0; tags && tags[i]; i++) {
- enum AVCodecID id = ff_codec_get_id(tags[i], tag);
- if (id != AV_CODEC_ID_NONE)
- return id;
- }
- return AV_CODEC_ID_NONE;
-}
-
-static void compute_chapters_end(AVFormatContext *s)
-{
- unsigned int i, j;
- int64_t 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;
-
- for (j = 0; j < s->nb_chapters; j++) {
- AVChapter *ch1 = s->chapters[j];
- 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)
- end = next_start;
- }
- ch->end = (end == INT64_MAX) ? ch->start : end;
- }
-}
-
-static int get_std_framerate(int i)
-{
- if (i < 30*12)
- return (i + 1) * 1001;
- i -= 30*12;
-
- if (i < 30)
- return (i + 31) * 1001 * 12;
- i -= 30;
-
- if (i < 3)
- return ((const int[]) { 80, 120, 240})[i] * 1001 * 12;
-
- i -= 3;
-
- return ((const int[]) { 24, 30, 60, 12, 15, 48 })[i] * 1000 * 12;
-}
-
-/* Is the time base unreliable?
- * This is a heuristic to balance between quick acceptance of the values in
- * the headers vs. some extra checks.
- * Old DivX and Xvid often have nonsense timebases like 1fps or 2fps.
- * MPEG-2 commonly misuses field repeat flags to store different framerates.
- * And there are "variable" fps files this needs to detect as well. */
-static int tb_unreliable(AVCodecContext *c)
-{
- if (c->time_base.den >= 101LL * c->time_base.num ||
- c->time_base.den < 5LL * c->time_base.num ||
- // c->codec_tag == AV_RL32("DIVX") ||
- // c->codec_tag == AV_RL32("XVID") ||
- c->codec_tag == AV_RL32("mp4v") ||
- c->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
- c->codec_id == AV_CODEC_ID_GIF ||
- c->codec_id == AV_CODEC_ID_HEVC ||
- c->codec_id == AV_CODEC_ID_H264)
- return 1;
- return 0;
-}
-
-int ff_alloc_extradata(AVCodecContext *avctx, int size)
-{
- int ret;
-
- if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
- avctx->extradata = NULL;
- avctx->extradata_size = 0;
- return AVERROR(EINVAL);
- }
- avctx->extradata = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
- if (avctx->extradata) {
- memset(avctx->extradata + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- avctx->extradata_size = size;
- ret = 0;
- } else {
- avctx->extradata_size = 0;
- ret = AVERROR(ENOMEM);
- }
- return ret;
-}
-
-int ff_get_extradata(AVCodecContext *avctx, AVIOContext *pb, int size)
-{
- int ret = ff_alloc_extradata(avctx, size);
- if (ret < 0)
- return ret;
- ret = avio_read(pb, avctx->extradata, size);
- if (ret != size) {
- av_freep(&avctx->extradata);
- avctx->extradata_size = 0;
- av_log(avctx, AV_LOG_ERROR, "Failed to read extradata of size %d\n", size);
- return ret < 0 ? ret : AVERROR_INVALIDDATA;
- }
-
- return ret;
-}
-
-int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
-{
- int i, j;
- int64_t last = st->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)
- return AVERROR(ENOMEM);
-
-// if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
-// av_log(NULL, AV_LOG_ERROR, "%f\n", dts);
- for (i = 0; i<MAX_STD_TIMEBASES; i++) {
- if (st->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->info->duration_count++;
- st->info->rfps_duration_sum += duration;
-
- if (st->info->duration_count % 10 == 0) {
- int n = st->info->duration_count;
- for (i = 0; i<MAX_STD_TIMEBASES; i++) {
- if (st->info->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 (error0 > 0.04 && error1 > 0.04) {
- st->info->duration_error[0][1][i] = 2e10;
- st->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 (ts != AV_NOPTS_VALUE)
- st->info->last_dts = ts;
-
- return 0;
-}
-
-void ff_rfps_calculate(AVFormatContext *ic)
-{
- int i, j;
-
- for (i = 0; i < ic->nb_streams; i++) {
- AVStream *st = ic->streams[i];
-
- if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO)
- continue;
- // the check for tb_unreliable() is not completely correct, since this is not about handling
- // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
- // ipmovie.c produces.
- if (tb_unreliable(st->codec) && 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
- && tb_unreliable(st->codec)) {
- int num = 0;
- double best_error= 0.01;
- AVRational ref_rate = st->r_frame_rate.num ? st->r_frame_rate : av_inv_q(st->time_base);
-
- for (j= 0; j<MAX_STD_TIMEBASES; j++) {
- int k;
-
- if (st->info->codec_info_duration && st->info->codec_info_duration*av_q2d(st->time_base) < (1001*12.0)/get_std_framerate(j))
- continue;
- if (!st->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))
- 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;
-
- if (error < best_error && best_error> 0.000000001) {
- best_error= error;
- num = get_std_framerate(j);
- }
- if (error < 0.02)
- av_log(ic, AV_LOG_DEBUG, "rfps: %f %f\n", get_std_framerate(j) / 12.0/1001, error);
- }
- }
- // do not increase frame rate by more than 1 % in order to match a standard rate.
- if (num && (!ref_rate.num || (double)num/(12*1001) < 1.01 * av_q2d(ref_rate)))
- 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
- ) {
- 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;
- }
-}
-
-int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
-{
- int i, count, ret = 0, j;
- int64_t read_size;
- AVStream *st;
- AVPacket pkt1, *pkt;
- int64_t old_offset = avio_tell(ic->pb);
- // new streams might appear, no options for those
- int orig_nb_streams = ic->nb_streams;
- int flush_codecs;
-#if FF_API_PROBESIZE_32
- int64_t max_analyze_duration = ic->max_analyze_duration2;
-#else
- int64_t max_analyze_duration = ic->max_analyze_duration;
-#endif
- int64_t max_stream_analyze_duration;
- int64_t max_subtitle_analyze_duration;
-#if FF_API_PROBESIZE_32
- int64_t probesize = ic->probesize2;
-#else
- int64_t probesize = ic->probesize;
-#endif
-
- if (!max_analyze_duration)
- max_analyze_duration = ic->max_analyze_duration;
- if (ic->probesize)
- probesize = ic->probesize;
- flush_codecs = probesize > 0;
-
- av_opt_set(ic, "skip_clear", "1", AV_OPT_SEARCH_CHILDREN);
-
- max_stream_analyze_duration = max_analyze_duration;
- max_subtitle_analyze_duration = max_analyze_duration;
- if (!max_analyze_duration) {
- max_stream_analyze_duration =
- max_analyze_duration = 5*AV_TIME_BASE;
- max_subtitle_analyze_duration = 30*AV_TIME_BASE;
- if (!strcmp(ic->iformat->name, "flv"))
- max_stream_analyze_duration = 30*AV_TIME_BASE;
- }
-
- if (ic->pb)
- av_log(ic, AV_LOG_DEBUG, "Before avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d\n",
- avio_tell(ic->pb), ic->pb->bytes_read, ic->pb->seek_count);
-
- for (i = 0; i < ic->nb_streams; i++) {
- const AVCodec *codec;
- AVDictionary *thread_opt = NULL;
- st = ic->streams[i];
-
- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
- st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
-/* if (!st->time_base.num)
- st->time_base = */
- if (!st->codec->time_base.num)
- st->codec->time_base = st->time_base;
- }
- // only for the split stuff
- if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE) && st->request_probe <= 0) {
- st->parser = av_parser_init(st->codec->codec_id);
- if (st->parser) {
- if (st->need_parsing == AVSTREAM_PARSE_HEADERS) {
- st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
- } else if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW) {
- st->parser->flags |= PARSER_FLAG_USE_CODEC_TS;
- }
- } else if (st->need_parsing) {
- av_log(ic, AV_LOG_VERBOSE, "parser not found for codec "
- "%s, packets or times may be invalid.\n",
- avcodec_get_name(st->codec->codec_id));
- }
- }
- codec = find_decoder(ic, st, st->codec->codec_id);
-
- /* 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);
-
- if (ic->codec_whitelist)
- av_dict_set(options ? &options[i] : &thread_opt, "codec_whitelist", ic->codec_whitelist, 0);
-
- /* Ensure that subtitle_header is properly set. */
- if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
- && codec && !st->codec->codec) {
- if (avcodec_open2(st->codec, codec, options ? &options[i] : &thread_opt) < 0)
- av_log(ic, AV_LOG_WARNING,
- "Failed to open codec in av_find_stream_info\n");
- }
-
- // Try to just open decoders, in case this is enough to get parameters.
- if (!has_codec_parameters(st, NULL) && st->request_probe <= 0) {
- if (codec && !st->codec->codec)
- if (avcodec_open2(st->codec, codec, options ? &options[i] : &thread_opt) < 0)
- av_log(ic, AV_LOG_WARNING,
- "Failed to open codec in av_find_stream_info\n");
- }
- if (!options)
- av_dict_free(&thread_opt);
- }
-
- for (i = 0; i < ic->nb_streams; i++) {
-#if FF_API_R_FRAME_RATE
- ic->streams[i]->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;
- }
-
- count = 0;
- read_size = 0;
- for (;;) {
- int analyzed_all_streams;
- if (ff_check_interrupt(&ic->interrupt_callback)) {
- ret = AVERROR_EXIT;
- av_log(ic, AV_LOG_DEBUG, "interrupted\n");
- break;
- }
-
- /* check if one codec still needs to be handled */
- for (i = 0; i < ic->nb_streams; i++) {
- int fps_analyze_framecount = 20;
-
- st = ic->streams[i];
- if (!has_codec_parameters(st, NULL))
- break;
- /* If the timebase is coarse (like the usual millisecond precision
- * of mkv), we need to analyze more frames to reliably arrive at
- * the correct fps. */
- if (av_q2d(st->time_base) > 0.0005)
- fps_analyze_framecount *= 2;
- if (!tb_unreliable(st->codec))
- fps_analyze_framecount = 0;
- if (ic->fps_probe_size >= 0)
- fps_analyze_framecount = ic->fps_probe_size;
- if (st->disposition & AV_DISPOSITION_ATTACHED_PIC)
- fps_analyze_framecount = 0;
- /* variable fps and no guess at the real fps */
- if (!(st->r_frame_rate.num && st->avg_frame_rate.num) &&
- st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- int count = (ic->iformat->flags & AVFMT_NOTIMESTAMPS) ?
- st->info->codec_info_duration_fields/2 :
- st->info->duration_count;
- if (count < fps_analyze_framecount)
- break;
- }
- if (st->parser && st->parser->parser->split &&
- !st->codec->extradata)
- break;
- if (st->first_dts == AV_NOPTS_VALUE &&
- !(ic->iformat->flags & AVFMT_NOTIMESTAMPS) &&
- st->codec_info_nb_frames < ic->max_ts_probe &&
- (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
- st->codec->codec_type == AVMEDIA_TYPE_AUDIO))
- break;
- }
- analyzed_all_streams = 0;
- if (i == ic->nb_streams) {
- analyzed_all_streams = 1;
- /* NOTE: If the format has no header, then we need to read some
- * packets to get most of the streams, so we cannot stop here. */
- if (!(ic->ctx_flags & AVFMTCTX_NOHEADER)) {
- /* If we found the info for all the codecs, we can stop. */
- ret = count;
- av_log(ic, AV_LOG_DEBUG, "All info found\n");
- flush_codecs = 0;
- break;
- }
- }
- /* We did not get all the codec info, but we read too much data. */
- if (read_size >= probesize) {
- ret = count;
- av_log(ic, AV_LOG_DEBUG,
- "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]->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
- strcmp(ic->iformat->name, "image2"))
- av_log(ic, AV_LOG_WARNING,
- "Stream #%d: not enough frames to estimate rate; "
- "consider increasing probesize\n", i);
- break;
- }
-
- /* NOTE: A new stream can be added there if no header in file
- * (AVFMTCTX_NOHEADER). */
- ret = read_frame_internal(ic, &pkt1);
- if (ret == AVERROR(EAGAIN))
- continue;
-
- if (ret < 0) {
- /* EOF or error*/
- break;
- }
-
- if (ic->flags & AVFMT_FLAG_NOBUFFER)
- free_packet_buffer(&ic->internal->packet_buffer,
- &ic->internal->packet_buffer_end);
- {
- pkt = add_to_pktbuf(&ic->internal->packet_buffer, &pkt1,
- &ic->internal->packet_buffer_end);
- if (!pkt) {
- ret = AVERROR(ENOMEM);
- goto find_stream_info_err;
- }
- if ((ret = av_dup_packet(pkt)) < 0)
- goto find_stream_info_err;
- }
-
- st = ic->streams[pkt->stream_index];
- if (!(st->disposition & AV_DISPOSITION_ATTACHED_PIC))
- read_size += pkt->size;
-
- if (pkt->dts != AV_NOPTS_VALUE && st->codec_info_nb_frames > 1) {
- /* check for non-increasing dts */
- if (st->info->fps_last_dts != AV_NOPTS_VALUE &&
- st->info->fps_last_dts >= pkt->dts) {
- av_log(ic, AV_LOG_DEBUG,
- "Non-increasing DTS in stream %d: packet %d with DTS "
- "%"PRId64", packet %d with DTS %"PRId64"\n",
- st->index, st->info->fps_last_dts_idx,
- st->info->fps_last_dts, st->codec_info_nb_frames,
- pkt->dts);
- st->info->fps_first_dts =
- st->info->fps_last_dts = AV_NOPTS_VALUE;
- }
- /* 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 - st->info->fps_last_dts) / 1000 >
- (st->info->fps_last_dts - st->info->fps_first_dts) /
- (st->info->fps_last_dts_idx - st->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,
- pkt->dts);
- st->info->fps_first_dts =
- st->info->fps_last_dts = AV_NOPTS_VALUE;
- }
-
- /* update stored dts values */
- if (st->info->fps_first_dts == AV_NOPTS_VALUE) {
- st->info->fps_first_dts = pkt->dts;
- st->info->fps_first_dts_idx = st->codec_info_nb_frames;
- }
- st->info->fps_last_dts = pkt->dts;
- st->info->fps_last_dts_idx = st->codec_info_nb_frames;
- }
- if (st->codec_info_nb_frames>1) {
- 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);
- 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));
-
- if (analyzed_all_streams) limit = max_analyze_duration;
- else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) limit = max_subtitle_analyze_duration;
- else limit = max_stream_analyze_duration;
-
- if (t >= limit) {
- av_log(ic, AV_LOG_VERBOSE, "max_analyze_duration %"PRId64" reached at %"PRId64" microseconds st:%d\n",
- max_analyze_duration,
- t, pkt->stream_index);
- if (ic->flags & AVFMT_FLAG_NOBUFFER)
- av_packet_unref(pkt);
- break;
- }
- if (pkt->duration) {
- st->info->codec_info_duration += pkt->duration;
- st->info->codec_info_duration_fields += st->parser && st->need_parsing && st->codec->ticks_per_frame ==2 ? st->parser->repeat_pict + 1 : 2;
- }
- }
-#if FF_API_R_FRAME_RATE
- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
- ff_rfps_add_frame(ic, st, pkt->dts);
-#endif
- if (st->parser && st->parser->parser->split && !st->codec->extradata) {
- int i = st->parser->parser->split(st->codec, pkt->data, pkt->size);
- if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) {
- if (ff_alloc_extradata(st->codec, i))
- return AVERROR(ENOMEM);
- memcpy(st->codec->extradata, pkt->data,
- st->codec->extradata_size);
- }
- }
-
- /* If still no information, we try to open the codec and to
- * decompress the frame. We try to avoid that in most cases as
- * it takes longer and uses more memory. For MPEG-4, we need to
- * decompress for QuickTime.
- *
- * If AV_CODEC_CAP_CHANNEL_CONF is set this will force decoding of at
- * least one frame of codec data, this makes sure the codec initializes
- * the channel configuration and does not only trust the values from
- * the container. */
- try_decode_frame(ic, st, pkt,
- (options && i < orig_nb_streams) ? &options[i] : NULL);
-
- if (ic->flags & AVFMT_FLAG_NOBUFFER)
- av_packet_unref(pkt);
-
- st->codec_info_nb_frames++;
- count++;
- }
-
- if (flush_codecs) {
- AVPacket empty_pkt = { 0 };
- int err = 0;
- av_init_packet(&empty_pkt);
-
- for (i = 0; i < ic->nb_streams; i++) {
-
- st = ic->streams[i];
-
- /* flush the decoders */
- if (st->info->found_decoder == 1) {
- do {
- err = try_decode_frame(ic, st, &empty_pkt,
- (options && i < orig_nb_streams)
- ? &options[i] : NULL);
- } while (err > 0 && !has_codec_parameters(st, NULL));
-
- if (err < 0) {
- av_log(ic, AV_LOG_INFO,
- "decoding for stream %d failed\n", st->index);
- }
- }
- }
- }
-
- // close codecs which were opened in try_decode_frame()
- for (i = 0; i < ic->nb_streams; i++) {
- st = ic->streams[i];
- avcodec_close(st->codec);
- }
-
- ff_rfps_calculate(ic);
-
- for (i = 0; i < ic->nb_streams; i++) {
- st = ic->streams[i];
- if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- if (st->codec->codec_id == AV_CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample) {
- uint32_t tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
- if (avpriv_find_pix_fmt(avpriv_get_raw_pix_fmt_tags(), tag) == st->codec->pix_fmt)
- st->codec->codec_tag= tag;
- }
-
- /* estimate average framerate if not set by demuxer */
- if (st->info->codec_info_duration_fields &&
- !st->avg_frame_rate.num &&
- st->info->codec_info_duration) {
- int best_fps = 0;
- double best_error = 0.01;
-
- 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)
- 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);
-
- /* Round guessed framerate to a "standard" framerate if it's
- * within 1% of the original estimate. */
- for (j = 0; j < MAX_STD_TIMEBASES; j++) {
- AVRational std_fps = { get_std_framerate(j), 12 * 1001 };
- double error = fabs(av_q2d(st->avg_frame_rate) /
- av_q2d(std_fps) - 1);
-
- if (error < best_error) {
- best_error = error;
- best_fps = std_fps.num;
- }
- }
- if (best_fps)
- av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
- best_fps, 12 * 1001, INT_MAX);
- }
-
- if (!st->r_frame_rate.num) {
- if ( st->codec->time_base.den * (int64_t) st->time_base.num
- <= st->codec->time_base.num * st->codec->ticks_per_frame * (int64_t) st->time_base.den) {
- st->r_frame_rate.num = st->codec->time_base.den;
- st->r_frame_rate.den = st->codec->time_base.num * st->codec->ticks_per_frame;
- } else {
- st->r_frame_rate.num = st->time_base.den;
- st->r_frame_rate.den = st->time_base.num;
- }
- }
- if (st->display_aspect_ratio.num && st->display_aspect_ratio.den) {
- AVRational hw_ratio = { st->codec->height, st->codec->width };
- st->sample_aspect_ratio = av_mul_q(st->display_aspect_ratio,
- hw_ratio);
- }
- } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
- if (!st->codec->bits_per_coded_sample)
- st->codec->bits_per_coded_sample =
- av_get_bits_per_sample(st->codec->codec_id);
- // set stream disposition based on audio service type
- switch (st->codec->audio_service_type) {
- case AV_AUDIO_SERVICE_TYPE_EFFECTS:
- st->disposition = AV_DISPOSITION_CLEAN_EFFECTS;
- break;
- case AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED:
- st->disposition = AV_DISPOSITION_VISUAL_IMPAIRED;
- break;
- case AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED:
- st->disposition = AV_DISPOSITION_HEARING_IMPAIRED;
- break;
- case AV_AUDIO_SERVICE_TYPE_COMMENTARY:
- st->disposition = AV_DISPOSITION_COMMENT;
- break;
- case AV_AUDIO_SERVICE_TYPE_KARAOKE:
- st->disposition = AV_DISPOSITION_KARAOKE;
- break;
- }
- }
- }
-
- if (probesize)
- estimate_timings(ic, old_offset);
-
- av_opt_set(ic, "skip_clear", "0", AV_OPT_SEARCH_CHILDREN);
-
- if (ret >= 0 && ic->nb_streams)
- /* We could not have all the codec parameters before EOF. */
- ret = -1;
- for (i = 0; i < ic->nb_streams; i++) {
- const char *errmsg;
- st = ic->streams[i];
- if (!has_codec_parameters(st, &errmsg)) {
- char buf[256];
- avcodec_string(buf, sizeof(buf), st->codec, 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);
- } else {
- ret = 0;
- }
- }
-
- compute_chapters_end(ic);
-
-find_stream_info_err:
- for (i = 0; i < ic->nb_streams; i++) {
- st = ic->streams[i];
- if (ic->streams[i]->codec->codec_type != AVMEDIA_TYPE_AUDIO)
- ic->streams[i]->codec->thread_count = 0;
- if (st->info)
- av_freep(&st->info->duration_error);
- av_freep(&ic->streams[i]->info);
- }
- if (ic->pb)
- av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d\n",
- avio_tell(ic->pb), ic->pb->bytes_read, ic->pb->seek_count, count);
- return ret;
-}
-
-AVProgram *av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int s)
-{
- int i, j;
-
- for (i = 0; i < ic->nb_programs; i++) {
- if (ic->programs[i] == last) {
- last = NULL;
- } else {
- if (!last)
- for (j = 0; j < ic->programs[i]->nb_stream_indexes; j++)
- if (ic->programs[i]->stream_index[j] == s)
- return ic->programs[i];
- }
- }
- return NULL;
-}
-
-int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type,
- int wanted_stream_nb, int related_stream,
- AVCodec **decoder_ret, int flags)
-{
- int i, nb_streams = ic->nb_streams;
- int ret = AVERROR_STREAM_NOT_FOUND, best_count = -1, best_bitrate = -1, best_multiframe = -1, count, bitrate, multiframe;
- unsigned *program = NULL;
- const AVCodec *decoder = NULL, *best_decoder = NULL;
-
- if (related_stream >= 0 && wanted_stream_nb < 0) {
- AVProgram *p = av_find_program_from_stream(ic, NULL, related_stream);
- if (p) {
- program = p->stream_index;
- nb_streams = p->nb_stream_indexes;
- }
- }
- for (i = 0; i < nb_streams; i++) {
- int real_stream_index = program ? program[i] : i;
- AVStream *st = ic->streams[real_stream_index];
- AVCodecContext *avctx = st->codec;
- if (avctx->codec_type != type)
- continue;
- if (wanted_stream_nb >= 0 && real_stream_index != wanted_stream_nb)
- continue;
- if (wanted_stream_nb != real_stream_index &&
- st->disposition & (AV_DISPOSITION_HEARING_IMPAIRED |
- AV_DISPOSITION_VISUAL_IMPAIRED))
- continue;
- if (type == AVMEDIA_TYPE_AUDIO && !(avctx->channels && avctx->sample_rate))
- continue;
- if (decoder_ret) {
- decoder = find_decoder(ic, st, st->codec->codec_id);
- if (!decoder) {
- if (ret < 0)
- ret = AVERROR_DECODER_NOT_FOUND;
- continue;
- }
- }
- count = st->codec_info_nb_frames;
- bitrate = avctx->bit_rate;
- if (!bitrate)
- bitrate = avctx->rc_max_rate;
- multiframe = FFMIN(5, count);
- if ((best_multiframe > multiframe) ||
- (best_multiframe == multiframe && best_bitrate > bitrate) ||
- (best_multiframe == multiframe && best_bitrate == bitrate && best_count >= count))
- continue;
- best_count = count;
- best_bitrate = bitrate;
- best_multiframe = multiframe;
- ret = real_stream_index;
- best_decoder = decoder;
- if (program && i == nb_streams - 1 && ret < 0) {
- program = NULL;
- nb_streams = ic->nb_streams;
- /* no related stream found, try again with everything */
- i = 0;
- }
- }
- if (decoder_ret)
- *decoder_ret = (AVCodec*)best_decoder;
- return ret;
-}
-
-/*******************************************************/
-
-int av_read_play(AVFormatContext *s)
-{
- if (s->iformat->read_play)
- return s->iformat->read_play(s);
- if (s->pb)
- return avio_pause(s->pb, 0);
- return AVERROR(ENOSYS);
-}
-
-int av_read_pause(AVFormatContext *s)
-{
- if (s->iformat->read_pause)
- return s->iformat->read_pause(s);
- if (s->pb)
- return avio_pause(s->pb, 1);
- return AVERROR(ENOSYS);
-}
-
-void ff_free_stream(AVFormatContext *s, AVStream *st) {
- int j;
- av_assert0(s->nb_streams>0);
- av_assert0(s->streams[ s->nb_streams - 1 ] == st);
-
- for (j = 0; j < st->nb_side_data; j++)
- av_freep(&st->side_data[j].data);
- av_freep(&st->side_data);
- st->nb_side_data = 0;
-
- if (st->parser) {
- av_parser_close(st->parser);
- }
- if (st->attached_pic.data)
- av_free_packet(&st->attached_pic);
- av_dict_free(&st->metadata);
- av_freep(&st->probe_data.buf);
- av_freep(&st->index_entries);
- av_freep(&st->codec->extradata);
- av_freep(&st->codec->subtitle_header);
- av_freep(&st->codec);
- av_freep(&st->priv_data);
- if (st->info)
- av_freep(&st->info->duration_error);
- av_freep(&st->info);
- av_freep(&st->recommended_encoder_configuration);
- av_freep(&st->priv_pts);
- av_freep(&s->streams[ --s->nb_streams ]);
-}
-
-void avformat_free_context(AVFormatContext *s)
-{
- int i;
-
- if (!s)
- return;
-
- av_opt_free(s);
- if (s->iformat && s->iformat->priv_class && s->priv_data)
- av_opt_free(s->priv_data);
- if (s->oformat && s->oformat->priv_class && s->priv_data)
- av_opt_free(s->priv_data);
-
- for (i = s->nb_streams - 1; i >= 0; i--) {
- ff_free_stream(s, s->streams[i]);
- }
- for (i = s->nb_programs - 1; i >= 0; i--) {
- av_dict_free(&s->programs[i]->metadata);
- av_freep(&s->programs[i]->stream_index);
- av_freep(&s->programs[i]);
- }
- av_freep(&s->programs);
- av_freep(&s->priv_data);
- while (s->nb_chapters--) {
- av_dict_free(&s->chapters[s->nb_chapters]->metadata);
- av_freep(&s->chapters[s->nb_chapters]);
- }
- av_freep(&s->chapters);
- av_dict_free(&s->metadata);
- av_freep(&s->streams);
- av_freep(&s->internal);
- flush_packet_queue(s);
- av_free(s);
-}
-
-void avformat_close_input(AVFormatContext **ps)
-{
- AVFormatContext *s;
- AVIOContext *pb;
-
- if (!ps || !*ps)
- return;
-
- s = *ps;
- pb = s->pb;
-
- if ((s->iformat && strcmp(s->iformat->name, "image2") && s->iformat->flags & AVFMT_NOFILE) ||
- (s->flags & AVFMT_FLAG_CUSTOM_IO))
- pb = NULL;
-
- flush_packet_queue(s);
-
- if (s->iformat)
- if (s->iformat->read_close)
- s->iformat->read_close(s);
-
- avformat_free_context(s);
-
- *ps = NULL;
-
- avio_close(pb);
-}
-
-AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
-{
- AVStream *st;
- int i;
- AVStream **streams;
-
- if (s->nb_streams >= FFMIN(s->max_streams, INT_MAX/sizeof(*streams))) {
- if (s->max_streams < INT_MAX/sizeof(*streams))
- av_log(s, AV_LOG_ERROR, "Number of streams exceeds max_streams parameter (%d), see the documentation if you wish to increase it\n", s->max_streams);
- return NULL;
- }
- streams = av_realloc_array(s->streams, s->nb_streams + 1, sizeof(*streams));
- if (!streams)
- return NULL;
- s->streams = streams;
-
- 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;
-
- st->codec = avcodec_alloc_context3(c);
- if (!st->codec) {
- av_free(st->info);
- av_free(st);
- return NULL;
- }
- if (s->iformat) {
- /* no default bitrate if decoding */
- st->codec->bit_rate = 0;
-
- /* default pts setting is MPEG-like */
- avpriv_set_pts_info(st, 33, 1, 90000);
- }
-
- st->index = s->nb_streams;
- st->start_time = AV_NOPTS_VALUE;
- st->duration = AV_NOPTS_VALUE;
- /* we set the current DTS to 0 so that formats without any timestamps
- * but durations get some timestamps, formats with some unknown
- * timestamps have their first few packets buffered and the
- * timestamps corrected before they are returned to the user */
- st->cur_dts = s->iformat ? RELATIVE_TS_BASE : 0;
- st->first_dts = AV_NOPTS_VALUE;
- st->probe_packets = MAX_PROBE_PACKETS;
- st->pts_wrap_reference = AV_NOPTS_VALUE;
- st->pts_wrap_behavior = AV_PTS_WRAP_IGNORE;
-
- st->last_IP_pts = AV_NOPTS_VALUE;
- st->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->sample_aspect_ratio = (AVRational) { 0, 1 };
-
-#if FF_API_R_FRAME_RATE
- st->info->last_dts = AV_NOPTS_VALUE;
-#endif
- st->info->fps_first_dts = AV_NOPTS_VALUE;
- st->info->fps_last_dts = AV_NOPTS_VALUE;
-
- st->inject_global_side_data = s->internal->inject_global_side_data;
-
- s->streams[s->nb_streams++] = st;
- return st;
-}
-
-AVProgram *av_new_program(AVFormatContext *ac, int id)
-{
- AVProgram *program = NULL;
- int i;
-
- av_log(ac, AV_LOG_TRACE, "new_program: id=0x%04x\n", id);
-
- for (i = 0; i < ac->nb_programs; i++)
- if (ac->programs[i]->id == id)
- program = ac->programs[i];
-
- if (!program) {
- program = av_mallocz(sizeof(AVProgram));
- if (!program)
- return NULL;
- dynarray_add(&ac->programs, &ac->nb_programs, program);
- program->discard = AVDISCARD_NONE;
- }
- 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;
-}
-
-AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base,
- int64_t start, int64_t end, const char *title)
-{
- AVChapter *chapter = NULL;
- int i;
-
- 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 (!chapter) {
- chapter = av_mallocz(sizeof(AVChapter));
- if (!chapter)
- return NULL;
- dynarray_add(&s->chapters, &s->nb_chapters, chapter);
- }
- av_dict_set(&chapter->metadata, "title", title, 0);
- chapter->id = id;
- chapter->time_base = time_base;
- chapter->start = start;
- chapter->end = end;
-
- return chapter;
-}
-
-void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned idx)
-{
- int i, j;
- AVProgram *program = NULL;
- void *tmp;
-
- if (idx >= ac->nb_streams) {
- av_log(ac, AV_LOG_ERROR, "stream index %d is not valid\n", idx);
- return;
- }
-
- for (i = 0; i < ac->nb_programs; i++) {
- if (ac->programs[i]->id != progid)
- continue;
- program = ac->programs[i];
- for (j = 0; j < program->nb_stream_indexes; j++)
- if (program->stream_index[j] == idx)
- return;
-
- tmp = av_realloc_array(program->stream_index, program->nb_stream_indexes+1, sizeof(unsigned int));
- if (!tmp)
- return;
- program->stream_index = tmp;
- program->stream_index[program->nb_stream_indexes++] = idx;
- return;
- }
-}
-
-uint64_t ff_ntp_time(void)
-{
- return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
-}
-
-int av_get_frame_filename(char *buf, int buf_size, const char *path, int number)
-{
- const char *p;
- char *q, buf1[20], c;
- int nd, len, percentd_found;
-
- q = buf;
- p = path;
- percentd_found = 0;
- for (;;) {
- c = *p++;
- if (c == '\0')
- break;
- if (c == '%') {
- do {
- nd = 0;
- while (av_isdigit(*p))
- nd = nd * 10 + *p++ - '0';
- c = *p++;
- } while (av_isdigit(c));
-
- switch (c) {
- case '%':
- goto addchar;
- case 'd':
- if (percentd_found)
- goto fail;
- percentd_found = 1;
- if (number < 0)
- nd += 1;
- snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
- len = strlen(buf1);
- if ((q - buf + len) > buf_size - 1)
- goto fail;
- memcpy(q, buf1, len);
- q += len;
- break;
- default:
- goto fail;
- }
- } else {
-addchar:
- if ((q - buf) < buf_size - 1)
- *q++ = c;
- }
- }
- if (!percentd_found)
- goto fail;
- *q = '\0';
- return 0;
-fail:
- *q = '\0';
- return -1;
-}
-
-void av_url_split(char *proto, int proto_size,
- char *authorization, int authorization_size,
- char *hostname, int hostname_size,
- int *port_ptr, char *path, int path_size, const char *url)
-{
- const char *p, *ls, *ls2, *at, *at2, *col, *brk;
-
- if (port_ptr)
- *port_ptr = -1;
- if (proto_size > 0)
- proto[0] = 0;
- if (authorization_size > 0)
- authorization[0] = 0;
- if (hostname_size > 0)
- hostname[0] = 0;
- if (path_size > 0)
- path[0] = 0;
-
- /* parse protocol */
- if ((p = strchr(url, ':'))) {
- av_strlcpy(proto, url, FFMIN(proto_size, p + 1 - url));
- p++; /* skip ':' */
- if (*p == '/')
- p++;
- if (*p == '/')
- p++;
- } else {
- /* no protocol means plain filename */
- av_strlcpy(path, url, path_size);
- return;
- }
-
- /* separate path from hostname */
- ls = strchr(p, '/');
- ls2 = strchr(p, '?');
- if (!ls)
- ls = ls2;
- else if (ls && ls2)
- ls = FFMIN(ls, ls2);
- if (ls)
- av_strlcpy(path, ls, path_size);
- else
- ls = &p[strlen(p)]; // XXX
-
- /* the rest is hostname, use that to parse auth/port */
- if (ls != p) {
- /* authorization (user[:pass]@hostname) */
- at2 = p;
- while ((at = strchr(p, '@')) && at < ls) {
- av_strlcpy(authorization, at2,
- FFMIN(authorization_size, at + 1 - at2));
- p = at + 1; /* skip '@' */
- }
-
- if (*p == '[' && (brk = strchr(p, ']')) && brk < ls) {
- /* [host]:port */
- av_strlcpy(hostname, p + 1,
- FFMIN(hostname_size, brk - p));
- if (brk[1] == ':' && port_ptr)
- *port_ptr = atoi(brk + 2);
- } else if ((col = strchr(p, ':')) && col < ls) {
- av_strlcpy(hostname, p,
- FFMIN(col + 1 - p, hostname_size));
- if (port_ptr)
- *port_ptr = atoi(col + 1);
- } else
- av_strlcpy(hostname, p,
- FFMIN(ls + 1 - p, hostname_size));
- }
-}
-
-char *ff_data_to_hex(char *buff, const uint8_t *src, int s, int lowercase)
-{
- int i;
- static const char hex_table_uc[16] = { '0', '1', '2', '3',
- '4', '5', '6', '7',
- '8', '9', 'A', 'B',
- 'C', 'D', 'E', 'F' };
- static const char hex_table_lc[16] = { '0', '1', '2', '3',
- '4', '5', '6', '7',
- '8', '9', 'a', 'b',
- 'c', 'd', 'e', 'f' };
- const char *hex_table = lowercase ? hex_table_lc : hex_table_uc;
-
- for (i = 0; i < s; i++) {
- buff[i * 2] = hex_table[src[i] >> 4];
- buff[i * 2 + 1] = hex_table[src[i] & 0xF];
- }
-
- return buff;
-}
-
-int ff_hex_to_data(uint8_t *data, const char *p)
-{
- int c, len, v;
-
- len = 0;
- v = 1;
- for (;;) {
- p += strspn(p, SPACE_CHARS);
- if (*p == '\0')
- break;
- c = av_toupper((unsigned char) *p++);
- if (c >= '0' && c <= '9')
- c = c - '0';
- else if (c >= 'A' && c <= 'F')
- c = c - 'A' + 10;
- else
- break;
- v = (v << 4) | c;
- if (v & 0x100) {
- if (data)
- data[len] = v;
- len++;
- v = 1;
- }
- }
- return len;
-}
-
-void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits,
- unsigned int pts_num, unsigned int pts_den)
-{
- AVRational new_tb;
- if (av_reduce(&new_tb.num, &new_tb.den, pts_num, pts_den, INT_MAX)) {
- if (new_tb.num != pts_num)
- av_log(NULL, AV_LOG_DEBUG,
- "st:%d removing common factor %d from timebase\n",
- s->index, pts_num / new_tb.num);
- } else
- av_log(NULL, AV_LOG_WARNING,
- "st:%d has too large timebase, reducing\n", s->index);
-
- if (new_tb.num <= 0 || new_tb.den <= 0) {
- av_log(NULL, AV_LOG_ERROR,
- "Ignoring attempt to set invalid timebase %d/%d for st:%d\n",
- new_tb.num, new_tb.den,
- s->index);
- return;
- }
- s->time_base = new_tb;
- av_codec_set_pkt_timebase(s->codec, new_tb);
- s->pts_wrap_bits = pts_wrap_bits;
-}
-
-void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf,
- void *context)
-{
- const char *ptr = str;
-
- /* Parse key=value pairs. */
- for (;;) {
- const char *key;
- char *dest = NULL, *dest_end;
- int key_len, dest_len = 0;
-
- /* Skip whitespace and potential commas. */
- while (*ptr && (av_isspace(*ptr) || *ptr == ','))
- ptr++;
- if (!*ptr)
- break;
-
- key = ptr;
-
- if (!(ptr = strchr(key, '=')))
- break;
- ptr++;
- key_len = ptr - key;
-
- callback_get_buf(context, key, key_len, &dest, &dest_len);
- dest_end = dest + dest_len - 1;
-
- if (*ptr == '\"') {
- ptr++;
- while (*ptr && *ptr != '\"') {
- if (*ptr == '\\') {
- if (!ptr[1])
- break;
- if (dest && dest < dest_end)
- *dest++ = ptr[1];
- ptr += 2;
- } else {
- if (dest && dest < dest_end)
- *dest++ = *ptr;
- ptr++;
- }
- }
- if (*ptr == '\"')
- ptr++;
- } else {
- for (; *ptr && !(av_isspace(*ptr) || *ptr == ','); ptr++)
- if (dest && dest < dest_end)
- *dest++ = *ptr;
- }
- if (dest)
- *dest = 0;
- }
-}
-
-int ff_find_stream_index(AVFormatContext *s, int id)
-{
- int i;
- for (i = 0; i < s->nb_streams; i++)
- if (s->streams[i]->id == id)
- return i;
- return -1;
-}
-
-int64_t ff_iso8601_to_unix_time(const char *datestr)
-{
- struct tm time1 = { 0 }, time2 = { 0 };
- const char *ret1, *ret2;
- ret1 = av_small_strptime(datestr, "%Y - %m - %d %T", &time1);
- ret2 = av_small_strptime(datestr, "%Y - %m - %dT%T", &time2);
- if (ret2 && !ret1)
- return av_timegm(&time2);
- else
- return av_timegm(&time1);
-}
-
-int avformat_query_codec(const AVOutputFormat *ofmt, enum AVCodecID codec_id,
- int std_compliance)
-{
- if (ofmt) {
- unsigned int codec_tag;
- if (ofmt->query_codec)
- return ofmt->query_codec(codec_id, std_compliance);
- else if (ofmt->codec_tag)
- return !!av_codec_get_tag2(ofmt->codec_tag, codec_id, &codec_tag);
- else if (codec_id == ofmt->video_codec ||
- codec_id == ofmt->audio_codec ||
- codec_id == ofmt->subtitle_codec)
- return 1;
- }
- return AVERROR_PATCHWELCOME;
-}
-
-int avformat_network_init(void)
-{
-#if CONFIG_NETWORK
- int ret;
- ff_network_inited_globally = 1;
- if ((ret = ff_network_init()) < 0)
- return ret;
- if ((ret = ff_tls_init()) < 0)
- return ret;
-#endif
- return 0;
-}
-
-int avformat_network_deinit(void)
-{
-#if CONFIG_NETWORK
- ff_network_close();
- ff_tls_deinit();
- ff_network_inited_globally = 0;
-#endif
- return 0;
-}
-
-int ff_add_param_change(AVPacket *pkt, int32_t channels,
- uint64_t channel_layout, int32_t sample_rate,
- int32_t width, int32_t height)
-{
- uint32_t flags = 0;
- int size = 4;
- uint8_t *data;
- if (!pkt)
- return AVERROR(EINVAL);
- if (channels) {
- size += 4;
- flags |= AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT;
- }
- if (channel_layout) {
- size += 8;
- flags |= AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT;
- }
- if (sample_rate) {
- size += 4;
- flags |= AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE;
- }
- if (width || height) {
- size += 8;
- flags |= AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS;
- }
- data = av_packet_new_side_data(pkt, AV_PKT_DATA_PARAM_CHANGE, size);
- if (!data)
- return AVERROR(ENOMEM);
- bytestream_put_le32(&data, flags);
- if (channels)
- bytestream_put_le32(&data, channels);
- if (channel_layout)
- bytestream_put_le64(&data, channel_layout);
- if (sample_rate)
- bytestream_put_le32(&data, sample_rate);
- if (width || height) {
- bytestream_put_le32(&data, width);
- bytestream_put_le32(&data, height);
- }
- return 0;
-}
-
-AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame)
-{
- AVRational undef = {0, 1};
- AVRational stream_sample_aspect_ratio = stream ? stream->sample_aspect_ratio : undef;
- AVRational codec_sample_aspect_ratio = stream && stream->codec ? stream->codec->sample_aspect_ratio : undef;
- AVRational frame_sample_aspect_ratio = frame ? frame->sample_aspect_ratio : codec_sample_aspect_ratio;
-
- av_reduce(&stream_sample_aspect_ratio.num, &stream_sample_aspect_ratio.den,
- stream_sample_aspect_ratio.num, stream_sample_aspect_ratio.den, INT_MAX);
- if (stream_sample_aspect_ratio.num <= 0 || stream_sample_aspect_ratio.den <= 0)
- stream_sample_aspect_ratio = undef;
-
- av_reduce(&frame_sample_aspect_ratio.num, &frame_sample_aspect_ratio.den,
- frame_sample_aspect_ratio.num, frame_sample_aspect_ratio.den, INT_MAX);
- if (frame_sample_aspect_ratio.num <= 0 || frame_sample_aspect_ratio.den <= 0)
- frame_sample_aspect_ratio = undef;
-
- if (stream_sample_aspect_ratio.num)
- return stream_sample_aspect_ratio;
- else
- return frame_sample_aspect_ratio;
-}
-
-AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *frame)
-{
- AVRational fr = st->r_frame_rate;
- AVRational codec_fr = st->codec->framerate;
- AVRational avg_fr = st->avg_frame_rate;
-
- if (avg_fr.num > 0 && avg_fr.den > 0 && fr.num > 0 && fr.den > 0 &&
- av_q2d(avg_fr) < 70 && av_q2d(fr) > 210) {
- fr = avg_fr;
- }
-
-
- if (st->codec->ticks_per_frame > 1) {
- if ( codec_fr.num > 0 && codec_fr.den > 0 &&
- (fr.num == 0 || av_q2d(codec_fr) < av_q2d(fr)*0.7 && fabs(1.0 - av_q2d(av_div_q(avg_fr, fr))) > 0.1))
- fr = codec_fr;
- }
-
- return fr;
-}
-
-int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
- const char *spec)
-{
- if (*spec <= '9' && *spec >= '0') /* opt:index */
- return strtol(spec, NULL, 0) == st->index;
- else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
- *spec == 't' || *spec == 'V') { /* opt:[vasdtV] */
- enum AVMediaType type;
- int nopic = 0;
-
- switch (*spec++) {
- case 'v': type = AVMEDIA_TYPE_VIDEO; break;
- case 'a': type = AVMEDIA_TYPE_AUDIO; break;
- case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
- case 'd': type = AVMEDIA_TYPE_DATA; break;
- case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
- case 'V': type = AVMEDIA_TYPE_VIDEO; nopic = 1; break;
- default: av_assert0(0);
- }
- if (type != st->codec->codec_type)
- return 0;
- if (nopic && (st->disposition & AV_DISPOSITION_ATTACHED_PIC))
- return 0;
- if (*spec++ == ':') { /* possibly followed by :index */
- int i, index = strtol(spec, NULL, 0);
- for (i = 0; i < s->nb_streams; i++)
- if (s->streams[i]->codec->codec_type == type &&
- !(nopic && (st->disposition & AV_DISPOSITION_ATTACHED_PIC)) &&
- index-- == 0)
- return i == st->index;
- return 0;
- }
- return 1;
- } else if (*spec == 'p' && *(spec + 1) == ':') {
- int prog_id, i, j;
- char *endptr;
- spec += 2;
- prog_id = strtol(spec, &endptr, 0);
- for (i = 0; i < s->nb_programs; i++) {
- if (s->programs[i]->id != prog_id)
- continue;
-
- if (*endptr++ == ':') {
- int stream_idx = strtol(endptr, NULL, 0);
- return stream_idx >= 0 &&
- stream_idx < s->programs[i]->nb_stream_indexes &&
- st->index == s->programs[i]->stream_index[stream_idx];
- }
-
- for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
- if (st->index == s->programs[i]->stream_index[j])
- return 1;
- }
- return 0;
- } else if (*spec == '#' ||
- (*spec == 'i' && *(spec + 1) == ':')) {
- int stream_id;
- char *endptr;
- spec += 1 + (*spec == 'i');
- stream_id = strtol(spec, &endptr, 0);
- if (!*endptr)
- return stream_id == st->id;
- } else if (*spec == 'm' && *(spec + 1) == ':') {
- AVDictionaryEntry *tag;
- char *key, *val;
- int ret;
-
- spec += 2;
- val = strchr(spec, ':');
-
- key = val ? av_strndup(spec, val - spec) : av_strdup(spec);
- if (!key)
- return AVERROR(ENOMEM);
-
- tag = av_dict_get(st->metadata, key, NULL, 0);
- if (tag) {
- if (!val || !strcmp(tag->value, val + 1))
- ret = 1;
- else
- ret = 0;
- } else
- ret = 0;
-
- av_freep(&key);
- return ret;
- } else if (*spec == 'u') {
- AVCodecContext *avctx = st->codec;
- int val;
- switch (avctx->codec_type) {
- case AVMEDIA_TYPE_AUDIO:
- val = avctx->sample_rate && avctx->channels;
- if (avctx->sample_fmt == AV_SAMPLE_FMT_NONE)
- return 0;
- break;
- case AVMEDIA_TYPE_VIDEO:
- val = avctx->width && avctx->height;
- if (avctx->pix_fmt == AV_PIX_FMT_NONE)
- return 0;
- break;
- case AVMEDIA_TYPE_UNKNOWN:
- val = 0;
- break;
- default:
- val = 1;
- break;
- }
- return avctx->codec_id != AV_CODEC_ID_NONE && val != 0;
- } else if (!*spec) /* empty specifier, matches everything */
- return 1;
-
- av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
- return AVERROR(EINVAL);
-}
-
-int ff_generate_avci_extradata(AVStream *st)
-{
- static const uint8_t avci100_1080p_extradata[] = {
- // SPS
- 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
- 0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
- 0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
- 0x18, 0x21, 0x02, 0x56, 0xb9, 0x3d, 0x7d, 0x7e,
- 0x4f, 0xe3, 0x3f, 0x11, 0xf1, 0x9e, 0x08, 0xb8,
- 0x8c, 0x54, 0x43, 0xc0, 0x78, 0x02, 0x27, 0xe2,
- 0x70, 0x1e, 0x30, 0x10, 0x10, 0x14, 0x00, 0x00,
- 0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xca,
- 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- // PPS
- 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
- 0xd0
- };
- static const uint8_t avci100_1080i_extradata[] = {
- // SPS
- 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
- 0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
- 0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
- 0x18, 0x21, 0x03, 0x3a, 0x46, 0x65, 0x6a, 0x65,
- 0x24, 0xad, 0xe9, 0x12, 0x32, 0x14, 0x1a, 0x26,
- 0x34, 0xad, 0xa4, 0x41, 0x82, 0x23, 0x01, 0x50,
- 0x2b, 0x1a, 0x24, 0x69, 0x48, 0x30, 0x40, 0x2e,
- 0x11, 0x12, 0x08, 0xc6, 0x8c, 0x04, 0x41, 0x28,
- 0x4c, 0x34, 0xf0, 0x1e, 0x01, 0x13, 0xf2, 0xe0,
- 0x3c, 0x60, 0x20, 0x20, 0x28, 0x00, 0x00, 0x03,
- 0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x94, 0x20,
- // PPS
- 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
- 0xd0
- };
- static const uint8_t avci50_1080p_extradata[] = {
- // SPS
- 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
- 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
- 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
- 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
- 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
- 0x6e, 0x6c, 0xd3, 0x3c, 0x05, 0xa0, 0x22, 0x7e,
- 0x5f, 0xfc, 0x00, 0x0c, 0x00, 0x13, 0x8c, 0x04,
- 0x04, 0x05, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00,
- 0x00, 0x03, 0x00, 0x32, 0x84, 0x00, 0x00, 0x00,
- // PPS
- 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
- 0x11
- };
- static const uint8_t avci50_1080i_extradata[] = {
- // SPS
- 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
- 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
- 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
- 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6e, 0x61,
- 0x87, 0x3e, 0x73, 0x4d, 0x98, 0x0c, 0x03, 0x06,
- 0x9c, 0x0b, 0x73, 0xe6, 0xc0, 0xb5, 0x18, 0x63,
- 0x0d, 0x39, 0xe0, 0x5b, 0x02, 0xd4, 0xc6, 0x19,
- 0x1a, 0x79, 0x8c, 0x32, 0x34, 0x24, 0xf0, 0x16,
- 0x81, 0x13, 0xf7, 0xff, 0x80, 0x02, 0x00, 0x01,
- 0xf1, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x03,
- 0x00, 0x20, 0x00, 0x00, 0x06, 0x50, 0x80, 0x00,
- // PPS
- 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
- 0x11
- };
- static const uint8_t avci100_720p_extradata[] = {
- // SPS
- 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
- 0xb6, 0xd4, 0x20, 0x2a, 0x33, 0x1d, 0xc7, 0x62,
- 0xa1, 0x08, 0x40, 0x54, 0x66, 0x3b, 0x8e, 0xc5,
- 0x42, 0x02, 0x10, 0x25, 0x64, 0x2c, 0x89, 0xe8,
- 0x85, 0xe4, 0x21, 0x4b, 0x90, 0x83, 0x06, 0x95,
- 0xd1, 0x06, 0x46, 0x97, 0x20, 0xc8, 0xd7, 0x43,
- 0x08, 0x11, 0xc2, 0x1e, 0x4c, 0x91, 0x0f, 0x01,
- 0x40, 0x16, 0xec, 0x07, 0x8c, 0x04, 0x04, 0x05,
- 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03,
- 0x00, 0x64, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
- // PPS
- 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x31, 0x12,
- 0x11
- };
- static const uint8_t avci50_720p_extradata[] = {
- // SPS
- 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x20,
- 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
- 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
- 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
- 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
- 0x6e, 0x6c, 0xd3, 0x3c, 0x0f, 0x01, 0x6e, 0xff,
- 0xc0, 0x00, 0xc0, 0x01, 0x38, 0xc0, 0x40, 0x40,
- 0x50, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00,
- 0x06, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
- // PPS
- 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
- 0x11
- };
-
- const uint8_t *data = NULL;
- int size = 0;
-
- if (st->codec->width == 1920) {
- if (st->codec->field_order == AV_FIELD_PROGRESSIVE) {
- data = avci100_1080p_extradata;
- size = sizeof(avci100_1080p_extradata);
- } else {
- data = avci100_1080i_extradata;
- size = sizeof(avci100_1080i_extradata);
- }
- } else if (st->codec->width == 1440) {
- if (st->codec->field_order == AV_FIELD_PROGRESSIVE) {
- data = avci50_1080p_extradata;
- size = sizeof(avci50_1080p_extradata);
- } else {
- data = avci50_1080i_extradata;
- size = sizeof(avci50_1080i_extradata);
- }
- } else if (st->codec->width == 1280) {
- data = avci100_720p_extradata;
- size = sizeof(avci100_720p_extradata);
- } else if (st->codec->width == 960) {
- data = avci50_720p_extradata;
- size = sizeof(avci50_720p_extradata);
- }
-
- if (!size)
- return 0;
-
- av_freep(&st->codec->extradata);
- if (ff_alloc_extradata(st->codec, size))
- return AVERROR(ENOMEM);
- memcpy(st->codec->extradata, data, size);
-
- return 0;
-}
-
-uint8_t *av_stream_get_side_data(AVStream *st, enum AVPacketSideDataType type,
- int *size)
-{
- int i;
-
- for (i = 0; i < st->nb_side_data; i++) {
- if (st->side_data[i].type == type) {
- if (size)
- *size = st->side_data[i].size;
- return st->side_data[i].data;
- }
- }
- return NULL;
-}
-
-uint8_t *ff_stream_new_side_data(AVStream *st, enum AVPacketSideDataType type,
- int size)
-{
- AVPacketSideData *sd, *tmp;
- int i;
- uint8_t *data = av_malloc(size);
-
- if (!data)
- return NULL;
-
- for (i = 0; i < st->nb_side_data; i++) {
- sd = &st->side_data[i];
-
- if (sd->type == type) {
- av_freep(&sd->data);
- sd->data = data;
- sd->size = size;
- return sd->data;
- }
- }
-
- tmp = av_realloc_array(st->side_data, st->nb_side_data + 1, sizeof(*tmp));
- if (!tmp) {
- av_freep(&data);
- return NULL;
- }
-
- st->side_data = tmp;
- st->nb_side_data++;
-
- sd = &st->side_data[st->nb_side_data - 1];
- sd->type = type;
- sd->data = data;
- sd->size = size;
- return data;
-}
diff --git a/ffmpeg-2-8-11/libavformat/wavdec.c b/ffmpeg-2-8-11/libavformat/wavdec.c
deleted file mode 100644
index 666fa31..0000000
--- a/ffmpeg-2-8-11/libavformat/wavdec.c
+++ /dev/null
@@ -1,793 +0,0 @@
-/*
- * WAV demuxer
- * Copyright (c) 2001, 2002 Fabrice Bellard
- *
- * Sony Wave64 demuxer
- * RF64 demuxer
- * Copyright (c) 2009 Daniel Verkamp
- *
- * 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 <stdint.h>
-
-#include "libavutil/avassert.h"
-#include "libavutil/dict.h"
-#include "libavutil/intreadwrite.h"
-#include "libavutil/log.h"
-#include "libavutil/mathematics.h"
-#include "libavutil/opt.h"
-#include "avformat.h"
-#include "avio.h"
-#include "avio_internal.h"
-#include "internal.h"
-#include "metadata.h"
-#include "pcm.h"
-#include "riff.h"
-#include "w64.h"
-#include "spdif.h"
-
-typedef struct WAVDemuxContext {
- const AVClass *class;
- int64_t data_end;
- int w64;
- int64_t smv_data_ofs;
- int smv_block_size;
- int smv_frames_per_jpeg;
- int smv_block;
- int smv_last_stream;
- int smv_eof;
- int audio_eof;
- int ignore_length;
- 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;
-
-#if CONFIG_WAV_DEMUXER
-
-static int64_t next_tag(AVIOContext *pb, uint32_t *tag, int big_endian)
-{
- *tag = avio_rl32(pb);
- if (!big_endian) {
- return avio_rl32(pb);
- } else {
- return avio_rb32(pb);
- }
-}
-
-/* RIFF chunks are always at even offsets relative to where they start. */
-static int64_t wav_seek_tag(WAVDemuxContext * wav, AVIOContext *s, int64_t offset, int whence)
-{
- offset += offset < INT64_MAX && offset + wav->unaligned & 1;
-
- return avio_seek(s, offset, whence);
-}
-
-/* return the size of the found tag */
-static int64_t find_tag(WAVDemuxContext * wav, AVIOContext *pb, uint32_t tag1)
-{
- unsigned int tag;
- int64_t size;
-
- for (;;) {
- if (avio_feof(pb))
- return AVERROR_EOF;
- size = next_tag(pb, &tag, wav->rifx);
- if (tag == tag1)
- break;
- wav_seek_tag(wav, pb, size, SEEK_CUR);
- }
- return size;
-}
-
-static int wav_probe(AVProbeData *p)
-{
- /* check file header */
- if (p->buf_size <= 32)
- return 0;
- if (!memcmp(p->buf + 8, "WAVE", 4)) {
- if (!memcmp(p->buf, "RIFF", 4) || !memcmp(p->buf, "RIFX", 4))
- /* Since the ACT demuxer has a standard WAV header at the top of
- * 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) &&
- !memcmp(p->buf + 12, "ds64", 4))
- return AVPROBE_SCORE_MAX;
- }
- return 0;
-}
-
-static void handle_stream_probing(AVStream *st)
-{
- if (st->codec->codec_id == AV_CODEC_ID_PCM_S16LE) {
- st->request_probe = AVPROBE_SCORE_EXTENSION;
- st->probe_packets = FFMIN(st->probe_packets, 32);
- }
-}
-
-static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
-{
- AVIOContext *pb = s->pb;
- WAVDemuxContext *wav = s->priv_data;
- int ret;
-
- /* parse fmt header */
- *st = avformat_new_stream(s, NULL);
- if (!*st)
- return AVERROR(ENOMEM);
-
- ret = ff_get_wav_header(s, pb, (*st)->codec, size, wav->rifx);
- if (ret < 0)
- return ret;
- handle_stream_probing(*st);
-
- (*st)->need_parsing = AVSTREAM_PARSE_FULL_RAW;
-
- avpriv_set_pts_info(*st, 64, 1, (*st)->codec->sample_rate);
-
- return 0;
-}
-
-static inline int wav_parse_bext_string(AVFormatContext *s, const char *key,
- int length)
-{
- char temp[257];
- int ret;
-
- av_assert0(length <= sizeof(temp));
- if ((ret = avio_read(s->pb, temp, length)) < 0)
- return ret;
-
- temp[length] = 0;
-
- if (strlen(temp))
- return av_dict_set(&s->metadata, key, temp, 0);
-
- return 0;
-}
-
-static int wav_parse_bext_tag(AVFormatContext *s, int64_t size)
-{
- char temp[131], *coding_history;
- int ret, x;
- uint64_t time_reference;
- int64_t umid_parts[8], umid_mask = 0;
-
- if ((ret = wav_parse_bext_string(s, "description", 256)) < 0 ||
- (ret = wav_parse_bext_string(s, "originator", 32)) < 0 ||
- (ret = wav_parse_bext_string(s, "originator_reference", 32)) < 0 ||
- (ret = wav_parse_bext_string(s, "origination_date", 10)) < 0 ||
- (ret = wav_parse_bext_string(s, "origination_time", 8)) < 0)
- return ret;
-
- time_reference = avio_rl64(s->pb);
- snprintf(temp, sizeof(temp), "%"PRIu64, time_reference);
- if ((ret = av_dict_set(&s->metadata, "time_reference", temp, 0)) < 0)
- return ret;
-
- /* check if version is >= 1, in which case an UMID may be present */
- if (avio_rl16(s->pb) >= 1) {
- for (x = 0; x < 8; x++)
- umid_mask |= umid_parts[x] = avio_rb64(s->pb);
-
- if (umid_mask) {
- /* the string formatting below is per SMPTE 330M-2004 Annex C */
- if (umid_parts[4] == 0 && umid_parts[5] == 0 &&
- umid_parts[6] == 0 && umid_parts[7] == 0) {
- /* basic UMID */
- snprintf(temp, sizeof(temp),
- "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
- umid_parts[0], umid_parts[1],
- umid_parts[2], umid_parts[3]);
- } else {
- /* extended UMID */
- snprintf(temp, sizeof(temp),
- "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64
- "%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
- umid_parts[0], umid_parts[1],
- umid_parts[2], umid_parts[3],
- umid_parts[4], umid_parts[5],
- umid_parts[6], umid_parts[7]);
- }
-
- if ((ret = av_dict_set(&s->metadata, "umid", temp, 0)) < 0)
- return ret;
- }
-
- avio_skip(s->pb, 190);
- } else
- avio_skip(s->pb, 254);
-
- if (size > 602) {
- /* CodingHistory present */
- size -= 602;
-
- if (!(coding_history = av_malloc(size + 1)))
- return AVERROR(ENOMEM);
-
- if ((ret = avio_read(s->pb, coding_history, size)) < 0)
- return ret;
-
- coding_history[size] = 0;
- if ((ret = av_dict_set(&s->metadata, "coding_history", coding_history,
- AV_DICT_DONT_STRDUP_VAL)) < 0)
- return ret;
- }
-
- return 0;
-}
-
-static const AVMetadataConv wav_metadata_conv[] = {
- { "description", "comment" },
- { "originator", "encoded_by" },
- { "origination_date", "date" },
- { "origination_time", "creation_time" },
- { 0 },
-};
-
-/* wav input */
-static int wav_read_header(AVFormatContext *s)
-{
- int64_t size, av_uninit(data_size);
- int64_t sample_count = 0;
- int rf64 = 0;
- char start_code[32];
- uint32_t tag;
- AVIOContext *pb = s->pb;
- AVStream *st = NULL;
- WAVDemuxContext *wav = s->priv_data;
- int ret, got_fmt = 0;
- int64_t next_tag_ofs, data_ofs = -1;
-
- wav->unaligned = avio_tell(s->pb) & 1;
-
- wav->smv_data_ofs = -1;
-
- /* read chunk ID */
- tag = avio_rl32(pb);
- switch (tag) {
- case MKTAG('R', 'I', 'F', 'F'):
- break;
- case MKTAG('R', 'I', 'F', 'X'):
- wav->rifx = 1;
- break;
- case MKTAG('R', 'F', '6', '4'):
- rf64 = 1;
- break;
- default:
- av_get_codec_tag_string(start_code, sizeof(start_code), tag);
- av_log(s, AV_LOG_ERROR, "invalid start code %s in RIFF header\n", start_code);
- return AVERROR_INVALIDDATA;
- }
-
- /* read chunk size */
- avio_rl32(pb);
-
- /* read format */
- if (avio_rl32(pb) != MKTAG('W', 'A', 'V', 'E')) {
- av_log(s, AV_LOG_ERROR, "invalid format in RIFF header\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (rf64) {
- if (avio_rl32(pb) != MKTAG('d', 's', '6', '4'))
- return AVERROR_INVALIDDATA;
- size = avio_rl32(pb);
- if (size < 24)
- return AVERROR_INVALIDDATA;
- avio_rl64(pb); /* RIFF size */
-
- data_size = avio_rl64(pb);
- sample_count = avio_rl64(pb);
-
- if (data_size < 0 || sample_count < 0) {
- av_log(s, AV_LOG_ERROR, "negative data_size and/or sample_count in "
- "ds64: data_size = %"PRId64", sample_count = %"PRId64"\n",
- data_size, sample_count);
- return AVERROR_INVALIDDATA;
- }
- avio_skip(pb, size - 24); /* skip rest of ds64 chunk */
-
- }
-
- for (;;) {
- AVStream *vst;
- size = next_tag(pb, &tag, wav->rifx);
- next_tag_ofs = avio_tell(pb) + size;
-
- if (avio_feof(pb))
- break;
-
- switch (tag) {
- case MKTAG('f', 'm', 't', ' '):
- /* only parse the first 'fmt ' tag found */
- if (!got_fmt && (ret = wav_parse_fmt_tag(s, size, &st)) < 0) {
- return ret;
- } else if (got_fmt)
- av_log(s, AV_LOG_WARNING, "found more than one 'fmt ' tag\n");
-
- got_fmt = 1;
- break;
- case MKTAG('d', 'a', 't', 'a'):
- if (!got_fmt) {
- av_log(s, AV_LOG_ERROR,
- "found no 'fmt ' tag before the 'data' tag\n");
- return AVERROR_INVALIDDATA;
- }
-
- if (rf64) {
- next_tag_ofs = wav->data_end = avio_tell(pb) + data_size;
- } else if (size != 0xFFFFFFFF) {
- data_size = size;
- next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX;
- } else {
- av_log(s, AV_LOG_WARNING, "Ignoring maximum wav data size, "
- "file may be invalid\n");
- data_size = 0;
- next_tag_ofs = wav->data_end = INT64_MAX;
- }
-
- data_ofs = avio_tell(pb);
-
- /* 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 || (!rf64 && !size))
- goto break_loop;
- break;
- case MKTAG('f', 'a', 'c', 't'):
- if (!sample_count)
- sample_count = (!wav->rifx ? avio_rl32(pb) : avio_rb32(pb));
- break;
- case MKTAG('b', 'e', 'x', 't'):
- if ((ret = wav_parse_bext_tag(s, size)) < 0)
- return ret;
- break;
- case MKTAG('S','M','V','0'):
- if (!got_fmt) {
- av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'SMV0' tag\n");
- return AVERROR_INVALIDDATA;
- }
- // SMV file, a wav file with video appended.
- if (size != MKTAG('0','2','0','0')) {
- av_log(s, AV_LOG_ERROR, "Unknown SMV version found\n");
- goto break_loop;
- }
- av_log(s, AV_LOG_DEBUG, "Found SMV data\n");
- wav->smv_given_first = 0;
- vst = avformat_new_stream(s, NULL);
- if (!vst)
- return AVERROR(ENOMEM);
- avio_r8(pb);
- vst->id = 1;
- vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
- vst->codec->codec_id = AV_CODEC_ID_SMVJPEG;
- vst->codec->width = avio_rl24(pb);
- vst->codec->height = avio_rl24(pb);
- if (ff_alloc_extradata(vst->codec, 4)) {
- av_log(s, AV_LOG_ERROR, "Could not allocate extradata.\n");
- return AVERROR(ENOMEM);
- }
- size = avio_rl24(pb);
- wav->smv_data_ofs = avio_tell(pb) + (size - 5) * 3;
- avio_rl24(pb);
- wav->smv_block_size = avio_rl24(pb);
- avpriv_set_pts_info(vst, 32, 1, avio_rl24(pb));
- vst->duration = avio_rl24(pb);
- avio_rl24(pb);
- avio_rl24(pb);
- wav->smv_frames_per_jpeg = avio_rl24(pb);
- if (wav->smv_frames_per_jpeg > 65536) {
- av_log(s, AV_LOG_ERROR, "too many frames per jpeg\n");
- return AVERROR_INVALIDDATA;
- }
- AV_WL32(vst->codec->extradata, wav->smv_frames_per_jpeg);
- wav->smv_cur_pt = 0;
- goto break_loop;
- case MKTAG('L', 'I', 'S', 'T'):
- if (size < 4) {
- av_log(s, AV_LOG_ERROR, "too short LIST tag\n");
- return AVERROR_INVALIDDATA;
- }
- switch (avio_rl32(pb)) {
- case MKTAG('I', 'N', 'F', 'O'):
- ff_read_riff_info(s, size - 4);
- }
- break;
- }
-
- /* seek to next tag unless we know that we'll run into EOF */
- if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) ||
- wav_seek_tag(wav, pb, next_tag_ofs, SEEK_SET) < 0) {
- break;
- }
- }
-
-break_loop:
- if (data_ofs < 0) {
- av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
- return AVERROR_INVALIDDATA;
- }
-
- avio_seek(pb, data_ofs, SEEK_SET);
-
- if (data_size > (INT64_MAX>>3)) {
- av_log(s, AV_LOG_WARNING, "Data size %"PRId64" is too large\n", data_size);
- data_size = 0;
- }
-
- if ( st->codec->bit_rate > 0 && data_size > 0
- && st->codec->sample_rate > 0
- && sample_count > 0 && st->codec->channels > 1
- && sample_count % st->codec->channels == 0) {
- if (fabs(8.0 * data_size * st->codec->channels * st->codec->sample_rate /
- sample_count /st->codec->bit_rate - 1.0) < 0.3)
- sample_count /= st->codec->channels;
- }
-
- if ( data_size > 0 && sample_count && st->codec->channels
- && (data_size << 3) / sample_count / st->codec->channels > st->codec->bits_per_coded_sample + 1) {
- av_log(s, AV_LOG_WARNING, "ignoring wrong sample_count %"PRId64"\n", sample_count);
- sample_count = 0;
- }
-
- /* G.729 hack (for Ticket4577)
- * FIXME: Come up with cleaner, more general solution */
- if (st->codec->codec_id == AV_CODEC_ID_G729 && sample_count && (data_size << 3) > sample_count) {
- av_log(s, AV_LOG_WARNING, "ignoring wrong sample_count %"PRId64"\n", sample_count);
- sample_count = 0;
- }
-
- if (!sample_count || av_get_exact_bits_per_sample(st->codec->codec_id) > 0)
- if ( st->codec->channels
- && data_size
- && av_get_bits_per_sample(st->codec->codec_id)
- && wav->data_end <= avio_size(pb))
- sample_count = (data_size << 3)
- /
- (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
-
- if (sample_count)
- st->duration = sample_count;
-
- ff_metadata_conv_ctx(s, NULL, wav_metadata_conv);
- ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
-
- return 0;
-}
-
-/**
- * Find chunk with w64 GUID by skipping over other chunks.
- * @return the size of the found chunk
- */
-static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16])
-{
- uint8_t guid[16];
- int64_t size;
-
- while (!avio_feof(pb)) {
- avio_read(pb, guid, 16);
- size = avio_rl64(pb);
- if (size <= 24)
- return AVERROR_INVALIDDATA;
- if (!memcmp(guid, guid1, 16))
- return size;
- avio_skip(pb, FFALIGN(size, INT64_C(8)) - 24);
- }
- return AVERROR_EOF;
-}
-
-#define MAX_SIZE 4096
-
-static int wav_read_packet(AVFormatContext *s, AVPacket *pkt)
-{
- int ret, size;
- int64_t left;
- AVStream *st;
- WAVDemuxContext *wav = s->priv_data;
-
- if (CONFIG_SPDIF_DEMUXER && wav->spdif == 0 &&
- s->streams[0]->codec->codec_tag == 1) {
- enum AVCodecID codec;
- ret = ff_spdif_probe(s->pb->buffer, s->pb->buf_end - s->pb->buffer,
- &codec);
- if (ret > AVPROBE_SCORE_EXTENSION) {
- s->streams[0]->codec->codec_id = codec;
- wav->spdif = 1;
- } else {
- wav->spdif = -1;
- }
- }
- if (CONFIG_SPDIF_DEMUXER && wav->spdif == 1)
- return ff_spdif_read_packet(s, pkt);
-
- if (wav->smv_data_ofs > 0) {
- int64_t audio_dts, video_dts;
-smv_retry:
- audio_dts = (int32_t)s->streams[0]->cur_dts;
- video_dts = (int32_t)s->streams[1]->cur_dts;
-
- if (audio_dts != AV_NOPTS_VALUE && video_dts != AV_NOPTS_VALUE) {
- /*We always return a video frame first to get the pixel format first*/
- wav->smv_last_stream = wav->smv_given_first ?
- av_compare_ts(video_dts, s->streams[1]->time_base,
- audio_dts, s->streams[0]->time_base) > 0 : 0;
- wav->smv_given_first = 1;
- }
- wav->smv_last_stream = !wav->smv_last_stream;
- wav->smv_last_stream |= wav->audio_eof;
- wav->smv_last_stream &= !wav->smv_eof;
- if (wav->smv_last_stream) {
- uint64_t old_pos = avio_tell(s->pb);
- uint64_t new_pos = wav->smv_data_ofs +
- wav->smv_block * wav->smv_block_size;
- if (avio_seek(s->pb, new_pos, SEEK_SET) < 0) {
- ret = AVERROR_EOF;
- goto smv_out;
- }
- size = avio_rl24(s->pb);
- ret = av_get_packet(s->pb, pkt, size);
- 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->stream_index = 1;
-smv_out:
- avio_seek(s->pb, old_pos, SEEK_SET);
- if (ret == AVERROR_EOF) {
- wav->smv_eof = 1;
- goto smv_retry;
- }
- return ret;
- }
- }
-
- st = s->streams[0];
-
- left = wav->data_end - avio_tell(s->pb);
- if (wav->ignore_length)
- left = INT_MAX;
- if (left <= 0) {
- if (CONFIG_W64_DEMUXER && wav->w64)
- left = find_guid(s->pb, ff_w64_guid_data) - 24;
- else
- left = find_tag(wav, s->pb, MKTAG('d', 'a', 't', 'a'));
- if (left < 0) {
- wav->audio_eof = 1;
- if (wav->smv_data_ofs > 0 && !wav->smv_eof)
- goto smv_retry;
- return AVERROR_EOF;
- }
- wav->data_end = avio_tell(s->pb) + left;
- }
-
- size = MAX_SIZE;
- if (st->codec->block_align > 1) {
- if (size < st->codec->block_align)
- size = st->codec->block_align;
- size = (size / st->codec->block_align) * st->codec->block_align;
- }
- size = FFMIN(size, left);
- ret = av_get_packet(s->pb, pkt, size);
- if (ret < 0)
- return ret;
- pkt->stream_index = 0;
-
- return ret;
-}
-
-static int wav_read_seek(AVFormatContext *s,
- int stream_index, int64_t timestamp, int flags)
-{
- WAVDemuxContext *wav = s->priv_data;
- AVStream *st;
- wav->smv_eof = 0;
- wav->audio_eof = 0;
- if (wav->smv_data_ofs > 0) {
- int64_t smv_timestamp = timestamp;
- if (stream_index == 0)
- smv_timestamp = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[1]->time_base);
- else
- 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;
- }
- }
-
- st = s->streams[0];
- switch (st->codec->codec_id) {
- case AV_CODEC_ID_MP2:
- case AV_CODEC_ID_MP3:
- case AV_CODEC_ID_AC3:
- case AV_CODEC_ID_DTS:
- /* use generic seeking with dynamically generated indexes */
- return -1;
- default:
- break;
- }
- 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_INT, { .i64 = 0 }, 0, 1, DEC },
- { NULL },
-};
-
-static const AVClass wav_demuxer_class = {
- .class_name = "WAV demuxer",
- .item_name = av_default_item_name,
- .option = demux_options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-AVInputFormat ff_wav_demuxer = {
- .name = "wav",
- .long_name = NULL_IF_CONFIG_SMALL("WAV / WAVE (Waveform Audio)"),
- .priv_data_size = sizeof(WAVDemuxContext),
- .read_probe = wav_probe,
- .read_header = wav_read_header,
- .read_packet = wav_read_packet,
- .read_seek = wav_read_seek,
- .flags = AVFMT_GENERIC_INDEX,
- .codec_tag = (const AVCodecTag * const []) { ff_codec_wav_tags, 0 },
- .priv_class = &wav_demuxer_class,
-};
-#endif /* CONFIG_WAV_DEMUXER */
-
-#if CONFIG_W64_DEMUXER
-static int w64_probe(AVProbeData *p)
-{
- if (p->buf_size <= 40)
- return 0;
- if (!memcmp(p->buf, ff_w64_guid_riff, 16) &&
- !memcmp(p->buf + 24, ff_w64_guid_wave, 16))
- return AVPROBE_SCORE_MAX;
- else
- return 0;
-}
-
-static int w64_read_header(AVFormatContext *s)
-{
- int64_t size, data_ofs = 0;
- AVIOContext *pb = s->pb;
- WAVDemuxContext *wav = s->priv_data;
- AVStream *st;
- uint8_t guid[16];
- int ret;
-
- avio_read(pb, guid, 16);
- if (memcmp(guid, ff_w64_guid_riff, 16))
- return AVERROR_INVALIDDATA;
-
- /* riff + wave + fmt + sizes */
- if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8)
- return AVERROR_INVALIDDATA;
-
- avio_read(pb, guid, 16);
- if (memcmp(guid, ff_w64_guid_wave, 16)) {
- av_log(s, AV_LOG_ERROR, "could not find wave guid\n");
- return AVERROR_INVALIDDATA;
- }
-
- wav->w64 = 1;
-
- st = avformat_new_stream(s, NULL);
- if (!st)
- return AVERROR(ENOMEM);
-
- while (!avio_feof(pb)) {
- if (avio_read(pb, guid, 16) != 16)
- break;
- size = avio_rl64(pb);
- if (size <= 24 || INT64_MAX - size < avio_tell(pb))
- return AVERROR_INVALIDDATA;
-
- if (!memcmp(guid, ff_w64_guid_fmt, 16)) {
- /* subtract chunk header size - normal wav file doesn't count it */
- ret = ff_get_wav_header(s, pb, st->codec, size - 24, 0);
- if (ret < 0)
- return ret;
- avio_skip(pb, FFALIGN(size, INT64_C(8)) - size);
-
- avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
- } else if (!memcmp(guid, ff_w64_guid_fact, 16)) {
- int64_t samples;
-
- samples = avio_rl64(pb);
- if (samples > 0)
- st->duration = samples;
- } else if (!memcmp(guid, ff_w64_guid_data, 16)) {
- wav->data_end = avio_tell(pb) + size - 24;
-
- data_ofs = avio_tell(pb);
- if (!pb->seekable)
- break;
-
- avio_skip(pb, size - 24);
- } else if (!memcmp(guid, ff_w64_guid_summarylist, 16)) {
- int64_t start, end, cur;
- uint32_t count, chunk_size, i;
-
- start = avio_tell(pb);
- end = start + FFALIGN(size, INT64_C(8)) - 24;
- count = avio_rl32(pb);
-
- for (i = 0; i < count; i++) {
- char chunk_key[5], *value;
-
- if (avio_feof(pb) || (cur = avio_tell(pb)) < 0 || cur > end - 8 /* = tag + size */)
- break;
-
- chunk_key[4] = 0;
- avio_read(pb, chunk_key, 4);
- chunk_size = avio_rl32(pb);
-
- value = av_mallocz(chunk_size + 1);
- if (!value)
- return AVERROR(ENOMEM);
-
- ret = avio_get_str16le(pb, chunk_size, value, chunk_size);
- avio_skip(pb, chunk_size - ret);
-
- av_dict_set(&s->metadata, chunk_key, value, AV_DICT_DONT_STRDUP_VAL);
- }
-
- avio_skip(pb, end - avio_tell(pb));
- } else {
- av_log(s, AV_LOG_DEBUG, "unknown guid: "FF_PRI_GUID"\n", FF_ARG_GUID(guid));
- avio_skip(pb, FFALIGN(size, INT64_C(8)) - 24);
- }
- }
-
- if (!data_ofs)
- return AVERROR_EOF;
-
- ff_metadata_conv_ctx(s, NULL, wav_metadata_conv);
- ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
-
- handle_stream_probing(st);
- st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
-
- avio_seek(pb, data_ofs, SEEK_SET);
-
- return 0;
-}
-
-AVInputFormat ff_w64_demuxer = {
- .name = "w64",
- .long_name = NULL_IF_CONFIG_SMALL("Sony Wave64"),
- .priv_data_size = sizeof(WAVDemuxContext),
- .read_probe = w64_probe,
- .read_header = w64_read_header,
- .read_packet = wav_read_packet,
- .read_seek = wav_read_seek,
- .flags = AVFMT_GENERIC_INDEX,
- .codec_tag = (const AVCodecTag * const []) { ff_codec_wav_tags, 0 },
-};
-#endif /* CONFIG_W64_DEMUXER */
diff --git a/ffmpeg-2-8-11/libavformat/webmdashenc.c b/ffmpeg-2-8-11/libavformat/webmdashenc.c
deleted file mode 100644
index 898e464..0000000
--- a/ffmpeg-2-8-11/libavformat/webmdashenc.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/*
- * WebM DASH Manifest XML muxer
- * Copyright (c) 2014 Vignesh Venkatasubramanian
- *
- * 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
- */
-
-/*
- * WebM DASH Specification:
- * https://sites.google.com/a/webmproject.org/wiki/adaptive-streaming/webm-dash-specification
- * ISO DASH Specification:
- * http://standards.iso.org/ittf/PubliclyAvailableStandards/c065274_ISO_IEC_23009-1_2014.zip
- */
-
-#include <float.h>
-#include <stdint.h>
-#include <string.h>
-
-#include "avformat.h"
-#include "avio_internal.h"
-#include "matroska.h"
-
-#include "libavutil/avstring.h"
-#include "libavutil/dict.h"
-#include "libavutil/opt.h"
-#include "libavutil/time_internal.h"
-
-typedef struct AdaptationSet {
- char id[10];
- int *streams;
- int nb_streams;
-} AdaptationSet;
-
-typedef struct WebMDashMuxContext {
- const AVClass *class;
- char *adaptation_sets;
- AdaptationSet *as;
- int nb_as;
- int representation_id;
- int is_live;
- int chunk_start_index;
- int chunk_duration;
- char *utc_timing_url;
- double time_shift_buffer_depth;
- int minimum_update_period;
- int debug_mode;
-} WebMDashMuxContext;
-
-static const char *get_codec_name(int codec_id)
-{
- switch (codec_id) {
- case AV_CODEC_ID_VP8:
- return "vp8";
- case AV_CODEC_ID_VP9:
- return "vp9";
- case AV_CODEC_ID_VORBIS:
- return "vorbis";
- case AV_CODEC_ID_OPUS:
- return "opus";
- }
- return NULL;
-}
-
-static double get_duration(AVFormatContext *s)
-{
- int i = 0;
- double max = 0.0;
- for (i = 0; i < s->nb_streams; i++) {
- AVDictionaryEntry *duration = av_dict_get(s->streams[i]->metadata,
- DURATION, NULL, 0);
- if (!duration || atof(duration->value) < 0) continue;
- if (atof(duration->value) > max) max = atof(duration->value);
- }
- return max / 1000;
-}
-
-static int write_header(AVFormatContext *s)
-{
- WebMDashMuxContext *w = s->priv_data;
- double min_buffer_time = 1.0;
- avio_printf(s->pb, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
- avio_printf(s->pb, "<MPD\n");
- avio_printf(s->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");
- if (!w->is_live) {
- avio_printf(s->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",
- 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) {
- time_t local_time = time(NULL);
- struct tm gmt_buffer;
- struct tm *gmt = gmtime_r(&local_time, &gmt_buffer);
- char gmt_iso[21];
- if (!strftime(gmt_iso, 21, "%Y-%m-%dT%H:%M:%SZ", gmt)) {
- return AVERROR_UNKNOWN;
- }
- if (w->debug_mode) {
- 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");
- if (w->utc_timing_url) {
- avio_printf(s->pb, "<UTCTiming\n");
- avio_printf(s->pb, " schemeIdUri=\"urn:mpeg:dash:utc:http-iso:2014\"\n");
- avio_printf(s->pb, " value=\"%s\"/>\n", w->utc_timing_url);
- }
- }
- return 0;
-}
-
-static void write_footer(AVFormatContext *s)
-{
- avio_printf(s->pb, "</MPD>\n");
-}
-
-static int subsegment_alignment(AVFormatContext *s, AdaptationSet *as) {
- int i;
- AVDictionaryEntry *gold = av_dict_get(s->streams[as->streams[0]]->metadata,
- CUE_TIMESTAMPS, NULL, 0);
- if (!gold) return 0;
- 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;
- }
- return 1;
-}
-
-static int bitstream_switching(AVFormatContext *s, AdaptationSet *as) {
- int i;
- AVDictionaryEntry *gold_track_num = av_dict_get(s->streams[as->streams[0]]->metadata,
- TRACK_NUMBER, NULL, 0);
- AVCodecContext *gold_codec = s->streams[as->streams[0]]->codec;
- 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,
- TRACK_NUMBER, NULL, 0);
- AVCodecContext *codec = s->streams[as->streams[i]]->codec;
- if (!track_num ||
- strncmp(gold_track_num->value, track_num->value, strlen(gold_track_num->value)) ||
- gold_codec->codec_id != codec->codec_id ||
- gold_codec->extradata_size != codec->extradata_size ||
- memcmp(gold_codec->extradata, codec->extradata, codec->extradata_size)) {
- return 0;
- }
- }
- return 1;
-}
-
-/*
- * 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,
- int output_width, int output_height,
- 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);
- if ((w->is_live && (!filename)) ||
- (!w->is_live && (!irange || !cues_start || !cues_end || !filename || !bandwidth))) {
- return AVERROR_INVALIDDATA;
- }
- avio_printf(s->pb, "<Representation id=\"%s\"", id);
- // FIXME: For live, This should be obtained from the input file or as an AVOption.
- avio_printf(s->pb, " bandwidth=\"%s\"",
- w->is_live ? (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO ? "128000" : "1000000") : bandwidth->value);
- if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO && output_width)
- avio_printf(s->pb, " width=\"%d\"", stream->codec->width);
- if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO && output_height)
- avio_printf(s->pb, " height=\"%d\"", stream->codec->height);
- if (stream->codec->codec_type = AVMEDIA_TYPE_AUDIO && output_sample_rate)
- avio_printf(s->pb, " audioSamplingRate=\"%d\"", stream->codec->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->codec->codec_id));
- avio_printf(s->pb, " mimeType=\"%s/webm\"",
- stream->codec->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, ">");
- } else {
- avio_printf(s->pb, ">\n");
- avio_printf(s->pb, "<BaseURL>%s</BaseURL>\n", filename->value);
- avio_printf(s->pb, "<SegmentBase\n");
- avio_printf(s->pb, " indexRange=\"%s-%s\">\n", cues_start->value, cues_end->value);
- avio_printf(s->pb, "<Initialization\n");
- avio_printf(s->pb, " range=\"0-%s\" />\n", irange->value);
- avio_printf(s->pb, "</SegmentBase>\n");
- }
- avio_printf(s->pb, "</Representation>\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) {
- int first_width, i;
- if (as->nb_streams < 2) return 1;
- first_width = s->streams[as->streams[0]]->codec->width;
- for (i = 1; i < as->nb_streams; i++)
- if (first_width != s->streams[as->streams[i]]->codec->width)
- return 0;
- return 1;
-}
-
-/*
- * Checks if height of all streams are the same. Returns 1 if true, 0 otherwise.
- */
-static int check_matching_height(AVFormatContext *s, AdaptationSet *as) {
- int first_height, i;
- if (as->nb_streams < 2) return 1;
- first_height = s->streams[as->streams[0]]->codec->height;
- for (i = 1; i < as->nb_streams; i++)
- if (first_height != s->streams[as->streams[i]]->codec->height)
- return 0;
- return 1;
-}
-
-/*
- * 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) {
- int first_sample_rate, i;
- if (as->nb_streams < 2) return 1;
- first_sample_rate = s->streams[as->streams[0]]->codec->sample_rate;
- for (i = 1; i < as->nb_streams; i++)
- if (first_sample_rate != s->streams[as->streams[i]]->codec->sample_rate)
- return 0;
- return 1;
-}
-
-static void free_adaptation_sets(AVFormatContext *s) {
- WebMDashMuxContext *w = s->priv_data;
- int i;
- for (i = 0; i < w->nb_as; i++) {
- av_freep(&w->as[i].streams);
- }
- av_freep(&w->as);
- w->nb_as = 0;
-}
-
-/*
- * 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.
- *
- * Name of the header file should conform to the following pattern:
- * <file_description>_<representation_id>.hdr where <file_description> can be
- * anything. The chunks should be named according to the following pattern:
- * <file_description>_<representation_id>_<chunk_number>.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 *temp_pos = NULL;
- char *filename_str = av_strdup(filename);
- if (!filename_str) return AVERROR(ENOMEM);
- temp_pos = av_stristr(filename_str, "_");
- while (temp_pos) {
- underscore_pos = temp_pos + 1;
- temp_pos = av_stristr(temp_pos + 1, "_");
- }
- if (!underscore_pos) return AVERROR_INVALIDDATA;
- period_pos = av_stristr(underscore_pos, ".");
- if (!period_pos) return AVERROR_INVALIDDATA;
- *(underscore_pos - 1) = 0;
- if (representation_id) {
- *representation_id = av_malloc(period_pos - underscore_pos + 1);
- if (!(*representation_id)) return AVERROR(ENOMEM);
- 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)) return AVERROR(ENOMEM);
- }
- if (media_pattern) {
- *media_pattern = av_asprintf("%s_$RepresentationID$_$Number$.chk",
- filename_str);
- if (!(*media_pattern)) return AVERROR(ENOMEM);
- }
- av_free(filename_str);
- return 0;
-}
-
-/*
- * Writes an Adaptation Set. Returns 0 on success and < 0 on failure.
- */
-static int write_adaptation_set(AVFormatContext *s, int as_index)
-{
- WebMDashMuxContext *w = s->priv_data;
- AdaptationSet *as = &w->as[as_index];
- AVCodecContext *codec = s->streams[as->streams[0]]->codec;
- AVDictionaryEntry *lang;
- int i;
- static const char boolean[2][6] = { "false", "true" };
- int subsegmentStartsWithSAP = 1;
-
- // Width, Height and Sample Rate will go in the AdaptationSet tag if they
- // are the same for all contained Representations. otherwise, they will go
- // on their respective Representation tag. For live streams, they always go
- // in the Representation tag.
- int width_in_as = 1, height_in_as = 1, sample_rate_in_as = 1;
- if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- 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, "<AdaptationSet id=\"%s\"", as->id);
- avio_printf(s->pb, " mimeType=\"%s/webm\"",
- codec->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio");
- avio_printf(s->pb, " codecs=\"%s\"", get_codec_name(codec->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);
-
- if (codec->codec_type == AVMEDIA_TYPE_VIDEO && width_in_as)
- avio_printf(s->pb, " width=\"%d\"", codec->width);
- if (codec->codec_type == AVMEDIA_TYPE_VIDEO && height_in_as)
- avio_printf(s->pb, " height=\"%d\"", codec->height);
- if (codec->codec_type == AVMEDIA_TYPE_AUDIO && sample_rate_in_as)
- avio_printf(s->pb, " audioSamplingRate=\"%d\"", codec->sample_rate);
-
- avio_printf(s->pb, " bitstreamSwitching=\"%s\"",
- boolean[bitstream_switching(s, as)]);
- avio_printf(s->pb, " subsegmentAlignment=\"%s\"",
- boolean[w->is_live || subsegment_alignment(s, as)]);
-
- for (i = 0; i < as->nb_streams; i++) {
- AVDictionaryEntry *kf = av_dict_get(s->streams[as->streams[i]]->metadata,
- 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");
-
- 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);
- if (ret) return ret;
- avio_printf(s->pb, "<ContentComponent id=\"1\" type=\"%s\"/>\n",
- codec->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio");
- avio_printf(s->pb, "<SegmentTemplate");
- avio_printf(s->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);
- }
-
- for (i = 0; i < as->nb_streams; i++) {
- char *representation_id = NULL;
- int ret;
- if (w->is_live) {
- AVDictionaryEntry *filename =
- av_dict_get(s->streams[as->streams[i]]->metadata, FILENAME, NULL, 0);
- if (!filename)
- return AVERROR(EINVAL);
- if (ret = parse_filename(filename->value, &representation_id, NULL, NULL))
- return ret;
- } else {
- representation_id = av_asprintf("%d", w->representation_id++);
- if (!representation_id) return AVERROR(ENOMEM);
- }
- ret = write_representation(s, s->streams[as->streams[i]],
- representation_id, !width_in_as,
- !height_in_as, !sample_rate_in_as);
- av_free(representation_id);
- if (ret) return ret;
- }
- avio_printf(s->pb, "</AdaptationSet>\n");
- return 0;
-}
-
-static int to_integer(char *p, int len)
-{
- int ret;
- char *q = av_malloc(sizeof(char) * len);
- if (!q)
- return AVERROR(ENOMEM);
- av_strlcpy(q, p, len);
- ret = atoi(q);
- av_free(q);
- return ret;
-}
-
-static int parse_adaptation_sets(AVFormatContext *s)
-{
- WebMDashMuxContext *w = s->priv_data;
- char *p = w->adaptation_sets;
- char *q;
- enum { new_set, parsed_id, parsing_streams } state;
- // syntax id=0,streams=0,1,2 id=1,streams=3,4 and so on
- state = new_set;
- while (p < w->adaptation_sets + strlen(w->adaptation_sets)) {
- if (*p == ' ')
- continue;
- else if (state == new_set && !strncmp(p, "id=", 3)) {
- void *mem = av_realloc(w->as, sizeof(*w->as) * (w->nb_as + 1));
- if (mem == NULL)
- return AVERROR(ENOMEM);
- w->as = mem;
- ++w->nb_as;
- w->as[w->nb_as - 1].nb_streams = 0;
- w->as[w->nb_as - 1].streams = NULL;
- p += 3; // consume "id="
- q = w->as[w->nb_as - 1].id;
- while (*p != ',') *q++ = *p++;
- *q = 0;
- p++;
- state = parsed_id;
- } else if (state == parsed_id && !strncmp(p, "streams=", 8)) {
- p += 8; // consume "streams="
- state = parsing_streams;
- } else if (state == parsing_streams) {
- struct AdaptationSet *as = &w->as[w->nb_as - 1];
- q = p;
- while (*q != '\0' && *q != ',' && *q != ' ') q++;
- as->streams = av_realloc(as->streams, sizeof(*as->streams) * ++as->nb_streams);
- if (as->streams == NULL)
- return AVERROR(ENOMEM);
- as->streams[as->nb_streams - 1] = to_integer(p, q - p + 1);
- if (as->streams[as->nb_streams - 1] < 0) return -1;
- if (*q == '\0') break;
- if (*q == ' ') state = new_set;
- p = ++q;
- } else {
- return -1;
- }
- }
- return 0;
-}
-
-static int webm_dash_manifest_write_header(AVFormatContext *s)
-{
- int i;
- double start = 0.0;
- int ret;
- WebMDashMuxContext *w = s->priv_data;
- ret = parse_adaptation_sets(s);
- if (ret < 0) {
- goto fail;
- }
- ret = write_header(s);
- if (ret < 0) {
- goto fail;
- }
- avio_printf(s->pb, "<Period id=\"0\"");
- avio_printf(s->pb, " start=\"PT%gS\"", start);
- if (!w->is_live) {
- avio_printf(s->pb, " duration=\"PT%gS\"", get_duration(s));
- }
- avio_printf(s->pb, " >\n");
-
- for (i = 0; i < w->nb_as; i++) {
- ret = write_adaptation_set(s, i);
- if (ret < 0) {
- goto fail;
- }
- }
-
- avio_printf(s->pb, "</Period>\n");
- write_footer(s);
-fail:
- free_adaptation_sets(s);
- return ret < 0 ? ret : 0;
-}
-
-static int webm_dash_manifest_write_packet(AVFormatContext *s, AVPacket *pkt)
-{
- return AVERROR_EOF;
-}
-
-static int webm_dash_manifest_write_trailer(AVFormatContext *s)
-{
- free_adaptation_sets(s);
- return 0;
-}
-
-#define OFFSET(x) offsetof(WebMDashMuxContext, x)
-static const AVOption options[] = {
- { "adaptation_sets", "Adaptation sets. Syntax: id=0,streams=0,1,2 id=1,streams=3,4 and so on", OFFSET(adaptation_sets), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
- { "debug_mode", "[private option - users should never set this]. set this to 1 to create deterministic output", OFFSET(debug_mode), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
- { "live", "set this to 1 to create a live stream manifest", OFFSET(is_live), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
- { "chunk_start_index", "start index of the chunk", OFFSET(chunk_start_index), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
- { "chunk_duration_ms", "duration of each chunk (in milliseconds)", OFFSET(chunk_duration), AV_OPT_TYPE_INT, {.i64 = 1000}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
- { "utc_timing_url", "URL of the page that will return the UTC timestamp in ISO format", OFFSET(utc_timing_url), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
- { "time_shift_buffer_depth", "Smallest time (in seconds) shifting buffer for which any Representation is guaranteed to be available.", OFFSET(time_shift_buffer_depth), AV_OPT_TYPE_DOUBLE, { .dbl = 60.0 }, 1.0, DBL_MAX, AV_OPT_FLAG_ENCODING_PARAM },
- { "minimum_update_period", "Minimum Update Period (in seconds) of the manifest.", OFFSET(minimum_update_period), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
- { NULL },
-};
-
-#if CONFIG_WEBM_DASH_MANIFEST_MUXER
-static const AVClass webm_dash_class = {
- .class_name = "WebM DASH Manifest muxer",
- .item_name = av_default_item_name,
- .option = options,
- .version = LIBAVUTIL_VERSION_INT,
-};
-
-AVOutputFormat ff_webm_dash_manifest_muxer = {
- .name = "webm_dash_manifest",
- .long_name = NULL_IF_CONFIG_SMALL("WebM DASH Manifest"),
- .mime_type = "application/xml",
- .extensions = "xml",
- .priv_data_size = sizeof(WebMDashMuxContext),
- .write_header = webm_dash_manifest_write_header,
- .write_packet = webm_dash_manifest_write_packet,
- .write_trailer = webm_dash_manifest_write_trailer,
- .priv_class = &webm_dash_class,
-};
-#endif
diff --git a/ffmpeg-2-8-11/libavutil/internal.h b/ffmpeg-2-8-11/libavutil/internal.h
deleted file mode 100644
index 047f742..0000000
--- a/ffmpeg-2-8-11/libavutil/internal.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * copyright (c) 2006 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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 internal API header
- */
-
-#ifndef AVUTIL_INTERNAL_H
-#define AVUTIL_INTERNAL_H
-
-#if !defined(DEBUG) && !defined(NDEBUG)
-# define NDEBUG
-#endif
-
-#include <limits.h>
-#include <stdint.h>
-#include <stddef.h>
-#include <assert.h>
-#include "config.h"
-#include "attributes.h"
-#include "timer.h"
-#include "cpu.h"
-#include "dict.h"
-#include "pixfmt.h"
-#include "version.h"
-
-#if ARCH_X86
-# include "x86/emms.h"
-#endif
-
-#ifndef emms_c
-# define emms_c() while(0)
-#endif
-
-#ifndef attribute_align_arg
-#if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2)
-# define attribute_align_arg __attribute__((force_align_arg_pointer))
-#else
-# define attribute_align_arg
-#endif
-#endif
-
-#if defined(_MSC_VER) && CONFIG_SHARED
-# define av_export __declspec(dllimport)
-#else
-# define av_export
-#endif
-
-#if HAVE_PRAGMA_DEPRECATED
-# if defined(__ICL) || defined (__INTEL_COMPILER)
-# define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:1478))
-# define FF_ENABLE_DEPRECATION_WARNINGS __pragma(warning(pop))
-# elif defined(_MSC_VER)
-# define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:4996))
-# define FF_ENABLE_DEPRECATION_WARNINGS __pragma(warning(pop))
-# else
-# define FF_DISABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
-# define FF_ENABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic warning \"-Wdeprecated-declarations\"")
-# endif
-#else
-# define FF_DISABLE_DEPRECATION_WARNINGS
-# define FF_ENABLE_DEPRECATION_WARNINGS
-#endif
-
-
-#define FF_MEMORY_POISON 0x2a
-
-#define MAKE_ACCESSORS(str, name, type, field) \
- type av_##name##_get_##field(const str *s) { return s->field; } \
- void av_##name##_set_##field(str *s, type v) { s->field = v; }
-
-// 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.
- */
-#define AV_CHECK_OFFSET(s, m, o) struct check_##o { \
- 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 LOCAL_ALIGNED(a, t, v, ...) E1(LOCAL_ALIGNED_A(a, t, v, __VA_ARGS__,,))
-
-#if HAVE_LOCAL_ALIGNED_8
-# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,))
-#else
-# define LOCAL_ALIGNED_8(t, v, ...) LOCAL_ALIGNED(8, t, v, __VA_ARGS__)
-#endif
-
-#if HAVE_LOCAL_ALIGNED_16
-# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,))
-#else
-# define LOCAL_ALIGNED_16(t, v, ...) LOCAL_ALIGNED(16, t, v, __VA_ARGS__)
-#endif
-
-#if HAVE_LOCAL_ALIGNED_32
-# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_D(32, t, v, __VA_ARGS__,,))
-#else
-# define LOCAL_ALIGNED_32(t, v, ...) LOCAL_ALIGNED(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;\
- }\
-}
-
-#include "libm.h"
-
-/**
- * Return NULL if CONFIG_SMALL is true, otherwise the argument
- * without modification. Used to disable the definition of strings
- * (for example AVCodec long_names).
- */
-#if CONFIG_SMALL
-# define NULL_IF_CONFIG_SMALL(x) NULL
-#else
-# define NULL_IF_CONFIG_SMALL(x) x
-#endif
-
-/**
- * Define a function with only the non-default version specified.
- *
- * On systems with ELF shared libraries, all symbols exported from
- * FFmpeg libraries are tagged with the name and major version of the
- * library to which they belong. If a function is moved from one
- * library to another, a wrapper must be retained in the original
- * location to preserve binary compatibility.
- *
- * Functions defined with this macro will never be used to resolve
- * symbols by the build-time linker.
- *
- * @param type return type of function
- * @param name name of function
- * @param args argument list of function
- * @param ver version tag to assign function
- */
-#if HAVE_SYMVER_ASM_LABEL
-# define FF_SYMVER(type, name, args, ver) \
- type ff_##name args __asm__ (EXTERN_PREFIX #name "@" ver); \
- type ff_##name args
-#elif HAVE_SYMVER_GNU_ASM
-# define FF_SYMVER(type, name, args, ver) \
- __asm__ (".symver ff_" #name "," EXTERN_PREFIX #name "@" ver); \
- type ff_##name args; \
- type ff_##name args
-#endif
-
-/**
- * Return NULL if a threading library has not been enabled.
- * Used to disable threading functions in AVCodec definitions
- * when not needed.
- */
-#if HAVE_THREADS
-# define ONLY_IF_THREADS_ENABLED(x) x
-#else
-# define ONLY_IF_THREADS_ENABLED(x) NULL
-#endif
-
-/**
- * Log a generic warning message about a missing feature.
- *
- * @param[in] avc a pointer to an arbitrary struct of which the first
- * field is a pointer to an AVClass struct
- * @param[in] msg string containing the name of the missing feature
- */
-void avpriv_report_missing_feature(void *avc,
- const char *msg, ...) av_printf_format(2, 3);
-
-/**
- * Log a generic warning message about a missing feature.
- * Additionally request that a sample showcasing the feature be uploaded.
- *
- * @param[in] avc a pointer to an arbitrary struct of which the first field is
- * a pointer to an AVClass struct
- * @param[in] msg string containing the name of the missing feature
- */
-void avpriv_request_sample(void *avc,
- const char *msg, ...) av_printf_format(2, 3);
-
-#if HAVE_LIBC_MSVCRT
-#include <crtversion.h>
-#if defined(_VC_CRT_MAJOR_VERSION) && _VC_CRT_MAJOR_VERSION < 14
-#pragma comment(linker, "/include:" EXTERN_PREFIX "avpriv_strtod")
-#pragma comment(linker, "/include:" EXTERN_PREFIX "avpriv_snprintf")
-#endif
-
-#define avpriv_open ff_open
-#define PTRDIFF_SPECIFIER "Id"
-#define SIZE_SPECIFIER "Iu"
-#else
-#define PTRDIFF_SPECIFIER "td"
-#define SIZE_SPECIFIER "zu"
-#endif
-
-#ifdef DEBUG
-# define ff_dlog(ctx, ...) av_log(ctx, AV_LOG_DEBUG, __VA_ARGS__)
-#else
-# define ff_dlog(ctx, ...) do { if (0) av_log(ctx, AV_LOG_DEBUG, __VA_ARGS__); } while (0)
-#endif
-
-/**
- * A wrapper for open() setting O_CLOEXEC.
- */
-int avpriv_open(const char *filename, int flags, ...);
-
-int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt);
-
-static av_always_inline av_const int avpriv_mirror(int x, int w)
-{
- if (!w)
- return 0;
-
- while ((unsigned)x > (unsigned)w) {
- x = -x;
- if (x < 0)
- x += 2 * w;
- }
- return x;
-}
-
-#if FF_API_GET_CHANNEL_LAYOUT_COMPAT
-uint64_t ff_get_channel_layout(const char *name, int compat);
-#endif
-
-void ff_check_pixfmt_descriptors(void);
-
-extern const uint8_t ff_reverse[256];
-
-#endif /* AVUTIL_INTERNAL_H */
diff --git a/ffmpeg-2-8-11/libavutil/softfloat.h b/ffmpeg-2-8-11/libavutil/softfloat.h
deleted file mode 100644
index 1b590a9..0000000
--- a/ffmpeg-2-8-11/libavutil/softfloat.h
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (c) 2006 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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_SOFTFLOAT_H
-#define AVUTIL_SOFTFLOAT_H
-
-#include <stdint.h>
-#include "common.h"
-
-#include "avassert.h"
-#include "softfloat_tables.h"
-
-#define MIN_EXP -149
-#define MAX_EXP 126
-#define ONE_BITS 29
-
-typedef struct SoftFloat{
- int32_t mant;
- int32_t exp;
-}SoftFloat;
-
-static const SoftFloat FLOAT_0 = { 0, MIN_EXP};
-static const SoftFloat FLOAT_05 = { 0x20000000, 0};
-static const SoftFloat FLOAT_1 = { 0x20000000, 1};
-static const SoftFloat FLOAT_EPSILON = { 0x29F16B12, -16};
-static const SoftFloat FLOAT_1584893192 = { 0x32B771ED, 1};
-static const SoftFloat FLOAT_100000 = { 0x30D40000, 17};
-static const SoftFloat FLOAT_0999999 = { 0x3FFFFBCE, 0};
-
-static inline av_const double av_sf2double(SoftFloat v) {
- v.exp -= ONE_BITS +1;
- if(v.exp > 0) return (double)v.mant * (double)(1 << v.exp);
- else return (double)v.mant / (double)(1 << (-v.exp));
-}
-
-static av_const SoftFloat av_normalize_sf(SoftFloat a){
- if(a.mant){
-#if 1
- while((a.mant + 0x1FFFFFFFU)<0x3FFFFFFFU){
- a.mant += a.mant;
- a.exp -= 1;
- }
-#else
- int s=ONE_BITS - av_log2(FFABS(a.mant));
- a.exp -= s;
- a.mant <<= s;
-#endif
- if(a.exp < MIN_EXP){
- a.exp = MIN_EXP;
- a.mant= 0;
- }
- }else{
- a.exp= MIN_EXP;
- }
- return a;
-}
-
-static inline av_const SoftFloat av_normalize1_sf(SoftFloat a){
-#if 1
- if((int32_t)(a.mant + 0x40000000U) <= 0){
- a.exp++;
- a.mant>>=1;
- }
- av_assert2(a.mant < 0x40000000 && a.mant > -0x40000000);
- return a;
-#elif 1
- int t= a.mant + 0x40000000 < 0;
- return (SoftFloat){ a.mant>>t, a.exp+t};
-#else
- int t= (a.mant + 0x3FFFFFFFU)>>31;
- return (SoftFloat){a.mant>>t, a.exp+t};
-#endif
-}
-
-/**
- * @return Will not be more denormalized than a*b. So if either input is
- * normalized, then the output will not be worse then the other input.
- * If both are normalized, then the output will be normalized.
- */
-static inline av_const SoftFloat av_mul_sf(SoftFloat a, SoftFloat b){
- a.exp += b.exp;
- av_assert2((int32_t)((a.mant * (int64_t)b.mant) >> ONE_BITS) == (a.mant * (int64_t)b.mant) >> ONE_BITS);
- a.mant = (a.mant * (int64_t)b.mant) >> ONE_BITS;
- a = av_normalize1_sf((SoftFloat){a.mant, a.exp - 1});
- if (!a.mant || a.exp < MIN_EXP)
- return FLOAT_0;
- return a;
-}
-
-/**
- * b has to be normalized and not zero.
- * @return Will not be more denormalized than a.
- */
-static inline av_const SoftFloat av_div_sf(SoftFloat a, SoftFloat b){
- a.exp -= b.exp;
- a.mant = ((int64_t)a.mant<<(ONE_BITS+1)) / b.mant;
- a = av_normalize1_sf(a);
- if (!a.mant || a.exp < MIN_EXP)
- return FLOAT_0;
- return a;
-}
-
-static inline av_const int av_cmp_sf(SoftFloat a, SoftFloat b){
- int t= a.exp - b.exp;
- if (t <-31) return - b.mant ;
- else if (t < 0) return (a.mant >> (-t)) - b.mant ;
- else if (t < 32) return a.mant - (b.mant >> t);
- else return a.mant ;
-}
-
-static inline av_const int av_gt_sf(SoftFloat a, SoftFloat b)
-{
- int t= a.exp - b.exp;
- if (t <-31) return 0 > b.mant ;
- else if (t < 0) return (a.mant >> (-t)) > b.mant ;
- else if (t < 32) return a.mant > (b.mant >> t);
- else return a.mant > 0 ;
-}
-
-static inline av_const SoftFloat av_add_sf(SoftFloat a, SoftFloat b){
- int t= a.exp - b.exp;
- if (t <-31) return b;
- else if (t < 0) return av_normalize_sf(av_normalize1_sf((SoftFloat){ b.mant + (a.mant >> (-t)), b.exp}));
- else if (t < 32) return av_normalize_sf(av_normalize1_sf((SoftFloat){ a.mant + (b.mant >> t ), a.exp}));
- else return a;
-}
-
-static inline av_const SoftFloat av_sub_sf(SoftFloat a, SoftFloat b){
- return av_add_sf(a, (SoftFloat){ -b.mant, b.exp});
-}
-
-//FIXME log, exp, pow
-
-/**
- * Converts a mantisse and exponent to a SoftFloat
- * @returns a SoftFloat with value v * 2^frac_bits
- */
-static inline av_const SoftFloat av_int2sf(int v, int frac_bits){
- int exp_offset = 0;
- if(v <= INT_MIN + 1){
- exp_offset = 1;
- v>>=1;
- }
- return av_normalize_sf(av_normalize1_sf((SoftFloat){v, ONE_BITS + 1 - frac_bits + exp_offset}));
-}
-
-/**
- * Rounding is to -inf.
- */
-static inline av_const int av_sf2int(SoftFloat v, int frac_bits){
- v.exp += frac_bits - (ONE_BITS + 1);
- if(v.exp >= 0) return v.mant << v.exp ;
- else return v.mant >>(-v.exp);
-}
-
-/**
- * Rounding-to-nearest used.
- */
-static av_always_inline SoftFloat av_sqrt_sf(SoftFloat val)
-{
- int tabIndex, rem;
-
- if (val.mant == 0)
- val.exp = MIN_EXP;
- else if (val.mant < 0)
- abort();
- else
- {
- tabIndex = (val.mant - 0x20000000) >> 20;
-
- rem = val.mant & 0xFFFFF;
- val.mant = (int)(((int64_t)av_sqrttbl_sf[tabIndex] * (0x100000 - rem) +
- (int64_t)av_sqrttbl_sf[tabIndex + 1] * rem +
- 0x80000) >> 20);
- val.mant = (int)(((int64_t)av_sqr_exp_multbl_sf[val.exp & 1] * val.mant +
- 0x10000000) >> 29);
-
- if (val.mant < 0x40000000)
- val.exp -= 2;
- else
- val.mant >>= 1;
-
- val.exp = (val.exp >> 1) + 1;
- }
-
- return val;
-}
-
-/**
- * Rounding-to-nearest used.
- */
-static av_unused void av_sincos_sf(int a, int *s, int *c)
-{
- int idx, sign;
- int sv, cv;
- int st, ct;
-
- idx = a >> 26;
- sign = (idx << 27) >> 31;
- cv = av_costbl_1_sf[idx & 0xf];
- cv = (cv ^ sign) - sign;
-
- idx -= 8;
- sign = (idx << 27) >> 31;
- sv = av_costbl_1_sf[idx & 0xf];
- sv = (sv ^ sign) - sign;
-
- idx = a >> 21;
- ct = av_costbl_2_sf[idx & 0x1f];
- st = av_sintbl_2_sf[idx & 0x1f];
-
- idx = (int)(((int64_t)cv * ct - (int64_t)sv * st + 0x20000000) >> 30);
-
- sv = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30);
-
- cv = idx;
-
- idx = a >> 16;
- ct = av_costbl_3_sf[idx & 0x1f];
- st = av_sintbl_3_sf[idx & 0x1f];
-
- idx = (int)(((int64_t)cv * ct - (int64_t)sv * st + 0x20000000) >> 30);
-
- sv = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30);
- cv = idx;
-
- idx = a >> 11;
-
- ct = (int)(((int64_t)av_costbl_4_sf[idx & 0x1f] * (0x800 - (a & 0x7ff)) +
- (int64_t)av_costbl_4_sf[(idx & 0x1f)+1]*(a & 0x7ff) +
- 0x400) >> 11);
- st = (int)(((int64_t)av_sintbl_4_sf[idx & 0x1f] * (0x800 - (a & 0x7ff)) +
- (int64_t)av_sintbl_4_sf[(idx & 0x1f) + 1] * (a & 0x7ff) +
- 0x400) >> 11);
-
- *c = (int)(((int64_t)cv * ct + (int64_t)sv * st + 0x20000000) >> 30);
-
- *s = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30);
-}
-
-#endif /* AVUTIL_SOFTFLOAT_H */
diff --git a/ffmpeg-2-8-11/libswresample/resample.c b/ffmpeg-2-8-11/libswresample/resample.c
deleted file mode 100644
index 8f3eb41..0000000
--- a/ffmpeg-2-8-11/libswresample/resample.c
+++ /dev/null
@@ -1,441 +0,0 @@
-/*
- * audio resampling
- * Copyright (c) 2004-2012 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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
- * audio resampling
- * @author Michael Niedermayer <michaelni at gmx.at>
- */
-
-#include "libavutil/avassert.h"
-#include "resample.h"
-
-/**
- * 0th order modified bessel function of the first kind.
- */
-static double bessel(double x){
- double v=1;
- double lastv=0;
- double t=1;
- int i;
- static const double inv[100]={
- 1.0/( 1* 1), 1.0/( 2* 2), 1.0/( 3* 3), 1.0/( 4* 4), 1.0/( 5* 5), 1.0/( 6* 6), 1.0/( 7* 7), 1.0/( 8* 8), 1.0/( 9* 9), 1.0/(10*10),
- 1.0/(11*11), 1.0/(12*12), 1.0/(13*13), 1.0/(14*14), 1.0/(15*15), 1.0/(16*16), 1.0/(17*17), 1.0/(18*18), 1.0/(19*19), 1.0/(20*20),
- 1.0/(21*21), 1.0/(22*22), 1.0/(23*23), 1.0/(24*24), 1.0/(25*25), 1.0/(26*26), 1.0/(27*27), 1.0/(28*28), 1.0/(29*29), 1.0/(30*30),
- 1.0/(31*31), 1.0/(32*32), 1.0/(33*33), 1.0/(34*34), 1.0/(35*35), 1.0/(36*36), 1.0/(37*37), 1.0/(38*38), 1.0/(39*39), 1.0/(40*40),
- 1.0/(41*41), 1.0/(42*42), 1.0/(43*43), 1.0/(44*44), 1.0/(45*45), 1.0/(46*46), 1.0/(47*47), 1.0/(48*48), 1.0/(49*49), 1.0/(50*50),
- 1.0/(51*51), 1.0/(52*52), 1.0/(53*53), 1.0/(54*54), 1.0/(55*55), 1.0/(56*56), 1.0/(57*57), 1.0/(58*58), 1.0/(59*59), 1.0/(60*60),
- 1.0/(61*61), 1.0/(62*62), 1.0/(63*63), 1.0/(64*64), 1.0/(65*65), 1.0/(66*66), 1.0/(67*67), 1.0/(68*68), 1.0/(69*69), 1.0/(70*70),
- 1.0/(71*71), 1.0/(72*72), 1.0/(73*73), 1.0/(74*74), 1.0/(75*75), 1.0/(76*76), 1.0/(77*77), 1.0/(78*78), 1.0/(79*79), 1.0/(80*80),
- 1.0/(81*81), 1.0/(82*82), 1.0/(83*83), 1.0/(84*84), 1.0/(85*85), 1.0/(86*86), 1.0/(87*87), 1.0/(88*88), 1.0/(89*89), 1.0/(90*90),
- 1.0/(91*91), 1.0/(92*92), 1.0/(93*93), 1.0/(94*94), 1.0/(95*95), 1.0/(96*96), 1.0/(97*97), 1.0/(98*98), 1.0/(99*99), 1.0/(10000)
- };
-
- x= x*x/4;
- for(i=0; v != lastv; i++){
- lastv=v;
- t *= x*inv[i];
- v += t;
- av_assert2(i<99);
- }
- return v;
-}
-
-/**
- * builds a polyphase filterbank.
- * @param factor resampling factor
- * @param scale wanted sum of coefficients for each filter
- * @param filter_type filter type
- * @param kaiser_beta kaiser window beta
- * @return 0 on success, negative on error
- */
-static int build_filter(ResampleContext *c, void *filter, double factor, int tap_count, int alloc, int phase_count, int scale,
- int filter_type, int kaiser_beta){
- int ph, i;
- double x, y, w;
- double *tab = av_malloc_array(tap_count, sizeof(*tab));
- const int center= (tap_count-1)/2;
-
- if (!tab)
- return AVERROR(ENOMEM);
-
- /* if upsampling, only need to interpolate, no filter */
- if (factor > 1.0)
- factor = 1.0;
-
- for(ph=0;ph<phase_count;ph++) {
- double norm = 0;
- for(i=0;i<tap_count;i++) {
- x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
- if (x == 0) y = 1.0;
- else y = sin(x) / x;
- switch(filter_type){
- case SWR_FILTER_TYPE_CUBIC:{
- const float d= -0.5; //first order derivative = -0.5
- x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
- if(x<1.0) y= 1 - 3*x*x + 2*x*x*x + d*( -x*x + x*x*x);
- else y= d*(-4 + 8*x - 5*x*x + x*x*x);
- break;}
- case SWR_FILTER_TYPE_BLACKMAN_NUTTALL:
- w = 2.0*x / (factor*tap_count) + M_PI;
- y *= 0.3635819 - 0.4891775 * cos(w) + 0.1365995 * cos(2*w) - 0.0106411 * cos(3*w);
- break;
- case SWR_FILTER_TYPE_KAISER:
- w = 2.0*x / (factor*tap_count*M_PI);
- y *= bessel(kaiser_beta*sqrt(FFMAX(1-w*w, 0)));
- break;
- default:
- av_assert0(0);
- }
-
- tab[i] = y;
- norm += y;
- }
-
- /* normalize so that an uniform color remains the same */
- switch(c->format){
- case AV_SAMPLE_FMT_S16P:
- for(i=0;i<tap_count;i++)
- ((int16_t*)filter)[ph * alloc + i] = av_clip(lrintf(tab[i] * scale / norm), INT16_MIN, INT16_MAX);
- break;
- case AV_SAMPLE_FMT_S32P:
- for(i=0;i<tap_count;i++)
- ((int32_t*)filter)[ph * alloc + i] = av_clipl_int32(llrint(tab[i] * scale / norm));
- break;
- case AV_SAMPLE_FMT_FLTP:
- for(i=0;i<tap_count;i++)
- ((float*)filter)[ph * alloc + i] = tab[i] * scale / norm;
- break;
- case AV_SAMPLE_FMT_DBLP:
- for(i=0;i<tap_count;i++)
- ((double*)filter)[ph * alloc + i] = tab[i] * scale / norm;
- break;
- }
- }
-#if 0
- {
-#define LEN 1024
- int j,k;
- double sine[LEN + tap_count];
- double filtered[LEN];
- double maxff=-2, minff=2, maxsf=-2, minsf=2;
- for(i=0; i<LEN; i++){
- double ss=0, sf=0, ff=0;
- for(j=0; j<LEN+tap_count; j++)
- sine[j]= cos(i*j*M_PI/LEN);
- for(j=0; j<LEN; j++){
- double sum=0;
- ph=0;
- for(k=0; k<tap_count; k++)
- sum += filter[ph * tap_count + k] * sine[k+j];
- filtered[j]= sum / (1<<FILTER_SHIFT);
- ss+= sine[j + center] * sine[j + center];
- ff+= filtered[j] * filtered[j];
- sf+= sine[j + center] * filtered[j];
- }
- ss= sqrt(2*ss/LEN);
- ff= sqrt(2*ff/LEN);
- sf= 2*sf/LEN;
- maxff= FFMAX(maxff, ff);
- minff= FFMIN(minff, ff);
- maxsf= FFMAX(maxsf, sf);
- minsf= FFMIN(minsf, sf);
- if(i%11==0){
- av_log(NULL, AV_LOG_ERROR, "i:%4d ss:%f ff:%13.6e-%13.6e sf:%13.6e-%13.6e\n", i, ss, maxff, minff, maxsf, minsf);
- minff=minsf= 2;
- maxff=maxsf= -2;
- }
- }
- }
-#endif
-
- av_free(tab);
- return 0;
-}
-
-static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
- double cutoff0, enum AVSampleFormat format, enum SwrFilterType filter_type, int kaiser_beta,
- double precision, int cheby)
-{
- double cutoff = cutoff0? cutoff0 : 0.97;
- double factor= FFMIN(out_rate * cutoff / in_rate, 1.0);
- int phase_count= 1<<phase_shift;
-
- if (!c || c->phase_shift != phase_shift || c->linear!=linear || c->factor != factor
- || c->filter_length != FFMAX((int)ceil(filter_size/factor), 1) || c->format != format
- || c->filter_type != filter_type || c->kaiser_beta != kaiser_beta) {
- c = av_mallocz(sizeof(*c));
- if (!c)
- return NULL;
-
- c->format= format;
-
- c->felem_size= av_get_bytes_per_sample(c->format);
-
- switch(c->format){
- case AV_SAMPLE_FMT_S16P:
- c->filter_shift = 15;
- break;
- case AV_SAMPLE_FMT_S32P:
- c->filter_shift = 30;
- break;
- case AV_SAMPLE_FMT_FLTP:
- case AV_SAMPLE_FMT_DBLP:
- c->filter_shift = 0;
- break;
- default:
- av_log(NULL, AV_LOG_ERROR, "Unsupported sample format\n");
- av_assert0(0);
- }
-
- if (filter_size/factor > INT32_MAX/256) {
- av_log(NULL, AV_LOG_ERROR, "Filter length too large\n");
- goto error;
- }
-
- c->phase_shift = phase_shift;
- c->phase_mask = phase_count - 1;
- c->linear = linear;
- c->factor = factor;
- c->filter_length = FFMAX((int)ceil(filter_size/factor), 1);
- c->filter_alloc = FFALIGN(c->filter_length, 8);
- c->filter_bank = av_calloc(c->filter_alloc, (phase_count+1)*c->felem_size);
- c->filter_type = filter_type;
- c->kaiser_beta = kaiser_beta;
- if (!c->filter_bank)
- goto error;
- if (build_filter(c, (void*)c->filter_bank, factor, c->filter_length, c->filter_alloc, phase_count, 1<<c->filter_shift, filter_type, kaiser_beta))
- goto error;
- memcpy(c->filter_bank + (c->filter_alloc*phase_count+1)*c->felem_size, c->filter_bank, (c->filter_alloc-1)*c->felem_size);
- memcpy(c->filter_bank + (c->filter_alloc*phase_count )*c->felem_size, c->filter_bank + (c->filter_alloc - 1)*c->felem_size, c->felem_size);
- }
-
- c->compensation_distance= 0;
- if(!av_reduce(&c->src_incr, &c->dst_incr, out_rate, in_rate * (int64_t)phase_count, INT32_MAX/2))
- goto error;
- while (c->dst_incr < (1<<20) && c->src_incr < (1<<20)) {
- c->dst_incr *= 2;
- c->src_incr *= 2;
- }
- c->ideal_dst_incr = c->dst_incr;
- c->dst_incr_div = c->dst_incr / c->src_incr;
- c->dst_incr_mod = c->dst_incr % c->src_incr;
-
- c->index= -phase_count*((c->filter_length-1)/2);
- c->frac= 0;
-
- swri_resample_dsp_init(c);
-
- return c;
-error:
- av_freep(&c->filter_bank);
- av_free(c);
- return NULL;
-}
-
-static void resample_free(ResampleContext **c){
- if(!*c)
- return;
- av_freep(&(*c)->filter_bank);
- av_freep(c);
-}
-
-static int set_compensation(ResampleContext *c, int sample_delta, int compensation_distance){
- c->compensation_distance= compensation_distance;
- if (compensation_distance)
- c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance;
- else
- c->dst_incr = c->ideal_dst_incr;
-
- c->dst_incr_div = c->dst_incr / c->src_incr;
- c->dst_incr_mod = c->dst_incr % c->src_incr;
-
- return 0;
-}
-
-static int swri_resample(ResampleContext *c,
- uint8_t *dst, const uint8_t *src, int *consumed,
- int src_size, int dst_size, int update_ctx)
-{
- if (c->filter_length == 1 && c->phase_shift == 0) {
- int index= c->index;
- int frac= c->frac;
- int64_t index2= (1LL<<32)*c->frac/c->src_incr + (1LL<<32)*index;
- int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr;
- int new_size = (src_size * (int64_t)c->src_incr - frac + c->dst_incr - 1) / c->dst_incr;
-
- dst_size= FFMIN(dst_size, new_size);
- c->dsp.resample_one(dst, src, dst_size, index2, incr);
-
- index += dst_size * c->dst_incr_div;
- index += (frac + dst_size * (int64_t)c->dst_incr_mod) / c->src_incr;
- av_assert2(index >= 0);
- *consumed= index;
- if (update_ctx) {
- c->frac = (frac + dst_size * (int64_t)c->dst_incr_mod) % c->src_incr;
- c->index = 0;
- }
- } else {
- int64_t end_index = (1LL + src_size - c->filter_length) << c->phase_shift;
- int64_t delta_frac = (end_index - c->index) * c->src_incr - c->frac;
- int delta_n = (delta_frac + c->dst_incr - 1) / c->dst_incr;
-
- dst_size = FFMIN(dst_size, delta_n);
- if (dst_size > 0) {
- *consumed = c->dsp.resample(c, dst, src, dst_size, update_ctx);
- } else {
- *consumed = 0;
- }
- }
-
- return dst_size;
-}
-
-static int multiple_resample(ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed){
- int i, ret= -1;
- int av_unused mm_flags = av_get_cpu_flags();
- int need_emms = c->format == AV_SAMPLE_FMT_S16P && ARCH_X86_32 &&
- (mm_flags & (AV_CPU_FLAG_MMX2 | AV_CPU_FLAG_SSE2)) == AV_CPU_FLAG_MMX2;
- int64_t max_src_size = (INT64_MAX >> (c->phase_shift+1)) / c->src_incr;
-
- if (c->compensation_distance)
- dst_size = FFMIN(dst_size, c->compensation_distance);
- src_size = FFMIN(src_size, max_src_size);
-
- for(i=0; i<dst->ch_count; i++){
- ret= swri_resample(c, dst->ch[i], src->ch[i],
- consumed, src_size, dst_size, i+1==dst->ch_count);
- }
- if(need_emms)
- emms_c();
-
- if (c->compensation_distance) {
- c->compensation_distance -= ret;
- if (!c->compensation_distance) {
- c->dst_incr = c->ideal_dst_incr;
- c->dst_incr_div = c->dst_incr / c->src_incr;
- c->dst_incr_mod = c->dst_incr % c->src_incr;
- }
- }
-
- return ret;
-}
-
-static int64_t get_delay(struct SwrContext *s, int64_t base){
- ResampleContext *c = s->resample;
- int64_t num = s->in_buffer_count - (c->filter_length-1)/2;
- num *= 1 << c->phase_shift;
- num -= c->index;
- num *= c->src_incr;
- num -= c->frac;
- return av_rescale(num, base, s->in_sample_rate*(int64_t)c->src_incr << c->phase_shift);
-}
-
-static int64_t get_out_samples(struct SwrContext *s, int in_samples) {
- ResampleContext *c = s->resample;
- // The + 2 are added to allow implementations to be slightly inaccurate, they should not be needed currently.
- // They also make it easier to proof that changes and optimizations do not
- // break the upper bound.
- int64_t num = s->in_buffer_count + 2LL + in_samples;
- num *= 1 << c->phase_shift;
- num -= c->index;
- num = av_rescale_rnd(num, s->out_sample_rate, ((int64_t)s->in_sample_rate) << c->phase_shift, AV_ROUND_UP) + 2;
-
- if (c->compensation_distance) {
- if (num > INT_MAX)
- return AVERROR(EINVAL);
-
- num = FFMAX(num, (num * c->ideal_dst_incr - 1) / c->dst_incr + 1);
- }
- return num;
-}
-
-static int resample_flush(struct SwrContext *s) {
- AudioData *a= &s->in_buffer;
- int i, j, ret;
- if((ret = swri_realloc_audio(a, s->in_buffer_index + 2*s->in_buffer_count)) < 0)
- return ret;
- av_assert0(a->planar);
- for(i=0; i<a->ch_count; i++){
- for(j=0; j<s->in_buffer_count; j++){
- memcpy(a->ch[i] + (s->in_buffer_index+s->in_buffer_count+j )*a->bps,
- a->ch[i] + (s->in_buffer_index+s->in_buffer_count-j-1)*a->bps, a->bps);
- }
- }
- s->in_buffer_count += (s->in_buffer_count+1)/2;
- return 0;
-}
-
-// in fact the whole handle multiple ridiculously small buffers might need more thinking...
-static int invert_initial_buffer(ResampleContext *c, AudioData *dst, const AudioData *src,
- int in_count, int *out_idx, int *out_sz)
-{
- int n, ch, num = FFMIN(in_count + *out_sz, c->filter_length + 1), res;
-
- if (c->index >= 0)
- return 0;
-
- if ((res = swri_realloc_audio(dst, c->filter_length * 2 + 1)) < 0)
- return res;
-
- // copy
- for (n = *out_sz; n < num; n++) {
- for (ch = 0; ch < src->ch_count; ch++) {
- memcpy(dst->ch[ch] + ((c->filter_length + n) * c->felem_size),
- src->ch[ch] + ((n - *out_sz) * c->felem_size), c->felem_size);
- }
- }
-
- // if not enough data is in, return and wait for more
- if (num < c->filter_length + 1) {
- *out_sz = num;
- *out_idx = c->filter_length;
- return INT_MAX;
- }
-
- // else invert
- for (n = 1; n <= c->filter_length; n++) {
- for (ch = 0; ch < src->ch_count; ch++) {
- memcpy(dst->ch[ch] + ((c->filter_length - n) * c->felem_size),
- dst->ch[ch] + ((c->filter_length + n) * c->felem_size),
- c->felem_size);
- }
- }
-
- res = num - *out_sz;
- *out_idx = c->filter_length + (c->index >> c->phase_shift);
- *out_sz = FFMAX(*out_sz + c->filter_length,
- 1 + c->filter_length * 2) - *out_idx;
- c->index &= c->phase_mask;
-
- return FFMAX(res, 0);
-}
-
-struct Resampler const swri_resampler={
- resample_init,
- resample_free,
- multiple_resample,
- resample_flush,
- set_compensation,
- get_delay,
- invert_initial_buffer,
- get_out_samples,
-};
diff --git a/ffmpeg-2-8-11/libswscale/swscale-test.c b/ffmpeg-2-8-11/libswscale/swscale-test.c
deleted file mode 100644
index b79bb23..0000000
--- a/ffmpeg-2-8-11/libswscale/swscale-test.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * Copyright (C) 2003-2011 Michael Niedermayer <michaelni at gmx.at>
- *
- * 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include <stdarg.h>
-
-#undef HAVE_AV_CONFIG_H
-#include "libavutil/imgutils.h"
-#include "libavutil/mem.h"
-#include "libavutil/avutil.h"
-#include "libavutil/crc.h"
-#include "libavutil/pixdesc.h"
-#include "libavutil/lfg.h"
-#include "swscale.h"
-
-/* HACK Duplicated from swscale_internal.h.
- * Should be removed when a cleaner pixel format system exists. */
-#define isGray(x) \
- ((x) == AV_PIX_FMT_GRAY8 || \
- (x) == AV_PIX_FMT_YA8 || \
- (x) == AV_PIX_FMT_GRAY16BE || \
- (x) == AV_PIX_FMT_GRAY16LE || \
- (x) == AV_PIX_FMT_YA16BE || \
- (x) == AV_PIX_FMT_YA16LE)
-#define hasChroma(x) \
- (!(isGray(x) || \
- (x) == AV_PIX_FMT_MONOBLACK || \
- (x) == AV_PIX_FMT_MONOWHITE))
-#define isALPHA(x) \
- ((x) == AV_PIX_FMT_BGR32 || \
- (x) == AV_PIX_FMT_BGR32_1 || \
- (x) == AV_PIX_FMT_RGB32 || \
- (x) == AV_PIX_FMT_RGB32_1 || \
- (x) == AV_PIX_FMT_YUVA420P)
-
-static uint64_t getSSD(const uint8_t *src1, const uint8_t *src2, int stride1,
- int stride2, int w, int h)
-{
- int x, y;
- uint64_t ssd = 0;
-
- for (y = 0; y < h; y++) {
- for (x = 0; x < w; x++) {
- int d = src1[x + y * stride1] - src2[x + y * stride2];
- ssd += d * d;
- }
- }
- return ssd;
-}
-
-struct Results {
- uint64_t ssdY;
- uint64_t ssdU;
- uint64_t ssdV;
- uint64_t ssdA;
- uint32_t crc;
-};
-
-// test by ref -> src -> dst -> out & compare out against ref
-// ref & out are YV12
-static int doTest(uint8_t *ref[4], int refStride[4], int w, int h,
- enum AVPixelFormat srcFormat, enum AVPixelFormat dstFormat,
- int srcW, int srcH, int dstW, int dstH, int flags,
- struct Results *r)
-{
- const AVPixFmtDescriptor *desc_yuva420p = av_pix_fmt_desc_get(AV_PIX_FMT_YUVA420P);
- const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(srcFormat);
- const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(dstFormat);
- static enum AVPixelFormat cur_srcFormat;
- static int cur_srcW, cur_srcH;
- static uint8_t *src[4];
- static int srcStride[4];
- uint8_t *dst[4] = { 0 };
- uint8_t *out[4] = { 0 };
- int dstStride[4] = {0};
- int i;
- uint64_t ssdY, ssdU = 0, ssdV = 0, ssdA = 0;
- struct SwsContext *dstContext = NULL, *outContext = NULL;
- uint32_t crc = 0;
- int res = 0;
-
- if (cur_srcFormat != srcFormat || cur_srcW != srcW || cur_srcH != srcH) {
- struct SwsContext *srcContext = NULL;
- int p;
-
- for (p = 0; p < 4; p++)
- av_freep(&src[p]);
-
- av_image_fill_linesizes(srcStride, srcFormat, srcW);
- for (p = 0; p < 4; p++) {
- srcStride[p] = FFALIGN(srcStride[p], 16);
- if (srcStride[p])
- src[p] = av_mallocz(srcStride[p] * srcH + 16);
- if (srcStride[p] && !src[p]) {
- perror("Malloc");
- res = -1;
- goto end;
- }
- }
- srcContext = sws_getContext(w, h, AV_PIX_FMT_YUVA420P, srcW, srcH,
- srcFormat, SWS_BILINEAR, NULL, NULL, NULL);
- if (!srcContext) {
- fprintf(stderr, "Failed to get %s ---> %s\n",
- desc_yuva420p->name,
- desc_src->name);
- res = -1;
- goto end;
- }
- sws_scale(srcContext, (const uint8_t * const*)ref, refStride, 0, h, src, srcStride);
- sws_freeContext(srcContext);
-
- cur_srcFormat = srcFormat;
- cur_srcW = srcW;
- cur_srcH = srcH;
- }
-
- av_image_fill_linesizes(dstStride, dstFormat, dstW);
- for (i = 0; i < 4; i++) {
- /* Image buffers passed into libswscale can be allocated any way you
- * prefer, as long as they're aligned enough for the architecture, and
- * they're freed appropriately (such as using av_free for buffers
- * allocated with av_malloc). */
- /* An extra 16 bytes is being allocated because some scalers may write
- * out of bounds. */
- dstStride[i] = FFALIGN(dstStride[i], 16);
- if (dstStride[i])
- dst[i] = av_mallocz(dstStride[i] * dstH + 16);
- if (dstStride[i] && !dst[i]) {
- perror("Malloc");
- res = -1;
-
- goto end;
- }
- }
-
- dstContext = sws_getContext(srcW, srcH, srcFormat, dstW, dstH, dstFormat,
- flags, NULL, NULL, NULL);
- if (!dstContext) {
- fprintf(stderr, "Failed to get %s ---> %s\n",
- desc_src->name, desc_dst->name);
- res = -1;
- goto end;
- }
-
- printf(" %s %dx%d -> %s %3dx%3d flags=%2d",
- desc_src->name, srcW, srcH,
- desc_dst->name, dstW, dstH,
- flags);
- fflush(stdout);
-
- sws_scale(dstContext, (const uint8_t * const*)src, srcStride, 0, srcH, dst, dstStride);
-
- for (i = 0; i < 4 && dstStride[i]; i++)
- crc = av_crc(av_crc_get_table(AV_CRC_32_IEEE), crc, dst[i],
- dstStride[i] * dstH);
-
- if (r && crc == r->crc) {
- ssdY = r->ssdY;
- ssdU = r->ssdU;
- ssdV = r->ssdV;
- ssdA = r->ssdA;
- } else {
- for (i = 0; i < 4; i++) {
- refStride[i] = FFALIGN(refStride[i], 16);
- if (refStride[i])
- out[i] = av_mallocz(refStride[i] * h);
- if (refStride[i] && !out[i]) {
- perror("Malloc");
- res = -1;
- goto end;
- }
- }
- outContext = sws_getContext(dstW, dstH, dstFormat, w, h,
- AV_PIX_FMT_YUVA420P, SWS_BILINEAR,
- NULL, NULL, NULL);
- if (!outContext) {
- fprintf(stderr, "Failed to get %s ---> %s\n",
- desc_dst->name,
- desc_yuva420p->name);
- res = -1;
- goto end;
- }
- sws_scale(outContext, (const uint8_t * const*)dst, dstStride, 0, dstH, out, refStride);
-
- ssdY = getSSD(ref[0], out[0], refStride[0], refStride[0], w, h);
- if (hasChroma(srcFormat) && hasChroma(dstFormat)) {
- //FIXME check that output is really gray
- ssdU = getSSD(ref[1], out[1], refStride[1], refStride[1],
- (w + 1) >> 1, (h + 1) >> 1);
- ssdV = getSSD(ref[2], out[2], refStride[2], refStride[2],
- (w + 1) >> 1, (h + 1) >> 1);
- }
- if (isALPHA(srcFormat) && isALPHA(dstFormat))
- ssdA = getSSD(ref[3], out[3], refStride[3], refStride[3], w, h);
-
- ssdY /= w * h;
- ssdU /= w * h / 4;
- ssdV /= w * h / 4;
- ssdA /= w * h;
-
- sws_freeContext(outContext);
-
- for (i = 0; i < 4; i++)
- if (refStride[i])
- av_free(out[i]);
- }
-
- printf(" CRC=%08x SSD=%5"PRId64 ",%5"PRId64 ",%5"PRId64 ",%5"PRId64 "\n",
- crc, ssdY, ssdU, ssdV, ssdA);
-
-end:
- sws_freeContext(dstContext);
-
- for (i = 0; i < 4; i++)
- if (dstStride[i])
- av_free(dst[i]);
-
- return res;
-}
-
-static void selfTest(uint8_t *ref[4], int refStride[4], int w, int h,
- enum AVPixelFormat srcFormat_in,
- enum AVPixelFormat dstFormat_in)
-{
- const int flags[] = { SWS_FAST_BILINEAR, SWS_BILINEAR, SWS_BICUBIC,
- SWS_X, SWS_POINT, SWS_AREA, 0 };
- const int srcW = w;
- const int srcH = h;
- const int dstW[] = { srcW - srcW / 3, srcW, srcW + srcW / 3, 0 };
- const int dstH[] = { srcH - srcH / 3, srcH, srcH + srcH / 3, 0 };
- enum AVPixelFormat srcFormat, dstFormat;
- const AVPixFmtDescriptor *desc_src, *desc_dst;
-
- for (srcFormat = srcFormat_in != AV_PIX_FMT_NONE ? srcFormat_in : 0;
- srcFormat < AV_PIX_FMT_NB; srcFormat++) {
- if (!sws_isSupportedInput(srcFormat) ||
- !sws_isSupportedOutput(srcFormat))
- continue;
-
- desc_src = av_pix_fmt_desc_get(srcFormat);
-
- for (dstFormat = dstFormat_in != AV_PIX_FMT_NONE ? dstFormat_in : 0;
- dstFormat < AV_PIX_FMT_NB; dstFormat++) {
- int i, j, k;
- int res = 0;
-
- if (!sws_isSupportedInput(dstFormat) ||
- !sws_isSupportedOutput(dstFormat))
- continue;
-
- desc_dst = av_pix_fmt_desc_get(dstFormat);
-
- printf("%s -> %s\n", desc_src->name, desc_dst->name);
- fflush(stdout);
-
- for (k = 0; flags[k] && !res; k++)
- for (i = 0; dstW[i] && !res; i++)
- for (j = 0; dstH[j] && !res; j++)
- res = doTest(ref, refStride, w, h,
- srcFormat, dstFormat,
- srcW, srcH, dstW[i], dstH[j], flags[k],
- NULL);
- if (dstFormat_in != AV_PIX_FMT_NONE)
- break;
- }
- if (srcFormat_in != AV_PIX_FMT_NONE)
- break;
- }
-}
-
-static int fileTest(uint8_t *ref[4], int refStride[4], int w, int h, FILE *fp,
- enum AVPixelFormat srcFormat_in,
- enum AVPixelFormat dstFormat_in)
-{
- char buf[256];
-
- while (fgets(buf, sizeof(buf), fp)) {
- struct Results r;
- enum AVPixelFormat srcFormat;
- char srcStr[12];
- int srcW, srcH;
- enum AVPixelFormat dstFormat;
- char dstStr[12];
- int dstW, dstH;
- int flags;
- int ret;
-
- ret = sscanf(buf,
- " %12s %dx%d -> %12s %dx%d flags=%d CRC=%x"
- " SSD=%"SCNd64 ", %"SCNd64 ", %"SCNd64 ", %"SCNd64 "\n",
- srcStr, &srcW, &srcH, dstStr, &dstW, &dstH,
- &flags, &r.crc, &r.ssdY, &r.ssdU, &r.ssdV, &r.ssdA);
- if (ret != 12) {
- srcStr[0] = dstStr[0] = 0;
- ret = sscanf(buf, "%12s -> %12s\n", srcStr, dstStr);
- }
-
- srcFormat = av_get_pix_fmt(srcStr);
- dstFormat = av_get_pix_fmt(dstStr);
-
- if (srcFormat == AV_PIX_FMT_NONE || dstFormat == AV_PIX_FMT_NONE ||
- srcW > 8192U || srcH > 8192U || dstW > 8192U || dstH > 8192U) {
- fprintf(stderr, "malformed input file\n");
- return -1;
- }
- if ((srcFormat_in != AV_PIX_FMT_NONE && srcFormat_in != srcFormat) ||
- (dstFormat_in != AV_PIX_FMT_NONE && dstFormat_in != dstFormat))
- continue;
- if (ret != 12) {
- printf("%s", buf);
- continue;
- }
-
- doTest(ref, refStride, w, h,
- srcFormat, dstFormat,
- srcW, srcH, dstW, dstH, flags,
- &r);
- }
-
- return 0;
-}
-
-#define W 96
-#define H 96
-
-int main(int argc, char **argv)
-{
- enum AVPixelFormat srcFormat = AV_PIX_FMT_NONE;
- enum AVPixelFormat dstFormat = AV_PIX_FMT_NONE;
- uint8_t *rgb_data = av_malloc(W * H * 4);
- const uint8_t * const rgb_src[4] = { rgb_data, NULL, NULL, NULL };
- int rgb_stride[4] = { 4 * W, 0, 0, 0 };
- uint8_t *data = av_malloc(4 * W * H);
- uint8_t *src[4] = { data, data + W * H, data + W * H * 2, data + W * H * 3 };
- int stride[4] = { W, W, W, W };
- int x, y;
- struct SwsContext *sws;
- AVLFG rand;
- int res = -1;
- int i;
- FILE *fp = NULL;
-
- if (!rgb_data || !data)
- return -1;
-
- 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], "r");
- if (!fp) {
- fprintf(stderr, "could not open '%s'\n", argv[i + 1]);
- goto error;
- }
- } else if (!strcmp(argv[i], "-src")) {
- srcFormat = av_get_pix_fmt(argv[i + 1]);
- if (srcFormat == AV_PIX_FMT_NONE) {
- fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
- return -1;
- }
- } else if (!strcmp(argv[i], "-dst")) {
- dstFormat = av_get_pix_fmt(argv[i + 1]);
- if (dstFormat == AV_PIX_FMT_NONE) {
- fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
- return -1;
- }
- } else {
-bad_option:
- fprintf(stderr, "bad option or argument missing (%s)\n", argv[i]);
- goto error;
- }
- }
-
- sws = sws_getContext(W / 12, H / 12, AV_PIX_FMT_RGB32, W, H,
- AV_PIX_FMT_YUVA420P, SWS_BILINEAR, NULL, NULL, NULL);
-
- av_lfg_init(&rand, 1);
-
- 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, src, stride);
- sws_freeContext(sws);
- av_free(rgb_data);
-
- if(fp) {
- res = fileTest(src, stride, W, H, fp, srcFormat, dstFormat);
- fclose(fp);
- } else {
- selfTest(src, stride, W, H, srcFormat, dstFormat);
- res = 0;
- }
-error:
- av_free(data);
-
- return res;
-}
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp5 b/ffmpeg-2-8-11/tests/ref/fate/vp5
deleted file mode 100644
index 0e601ba..0000000
--- a/ffmpeg-2-8-11/tests/ref/fate/vp5
+++ /dev/null
@@ -1,248 +0,0 @@
-#tb 0: 1001/24000
-0, 0, 0, 1, 233472, 0x27488413
-0, 1, 1, 1, 233472, 0x4af384b5
-0, 2, 2, 1, 233472, 0x948d845d
-0, 3, 3, 1, 233472, 0xd6ed845e
-0, 4, 4, 1, 233472, 0x230f8444
-0, 5, 5, 1, 233472, 0x230f8444
-0, 6, 6, 1, 233472, 0x230f8444
-0, 7, 7, 1, 233472, 0xa5078424
-0, 8, 8, 1, 233472, 0xa5078424
-0, 9, 9, 1, 233472, 0xa5078424
-0, 10, 10, 1, 233472, 0xa5078424
-0, 11, 11, 1, 233472, 0xa5078424
-0, 12, 12, 1, 233472, 0xa5078424
-0, 13, 13, 1, 233472, 0xa5078424
-0, 14, 14, 1, 233472, 0xa5078424
-0, 15, 15, 1, 233472, 0xa5078424
-0, 16, 16, 1, 233472, 0xa5078424
-0, 17, 17, 1, 233472, 0xa5078424
-0, 18, 18, 1, 233472, 0xa5078424
-0, 19, 19, 1, 233472, 0xa5078424
-0, 20, 20, 1, 233472, 0xa5078424
-0, 21, 21, 1, 233472, 0xa5078424
-0, 22, 22, 1, 233472, 0xa5078424
-0, 23, 23, 1, 233472, 0xa5078424
-0, 24, 24, 1, 233472, 0xa5078424
-0, 25, 25, 1, 233472, 0xa5078424
-0, 26, 26, 1, 233472, 0xa5078424
-0, 27, 27, 1, 233472, 0xa5078424
-0, 28, 28, 1, 233472, 0xa5078424
-0, 29, 29, 1, 233472, 0xa5078424
-0, 30, 30, 1, 233472, 0xa5078424
-0, 31, 31, 1, 233472, 0xa5078424
-0, 32, 32, 1, 233472, 0xa5078424
-0, 33, 33, 1, 233472, 0xa5078424
-0, 34, 34, 1, 233472, 0xa5078424
-0, 35, 35, 1, 233472, 0xa5078424
-0, 36, 36, 1, 233472, 0xa5078424
-0, 37, 37, 1, 233472, 0xa5078424
-0, 38, 38, 1, 233472, 0xa5078424
-0, 39, 39, 1, 233472, 0xa5078424
-0, 40, 40, 1, 233472, 0x05667dea
-0, 41, 41, 1, 233472, 0x6ae1823e
-0, 42, 42, 1, 233472, 0x3c8a7ea9
-0, 43, 43, 1, 233472, 0xcae2832a
-0, 44, 44, 1, 233472, 0x547a7ec2
-0, 45, 45, 1, 233472, 0xa6628327
-0, 46, 46, 1, 233472, 0xecd77edc
-0, 47, 47, 1, 233472, 0xe9538356
-0, 48, 48, 1, 233472, 0xca297eb1
-0, 49, 49, 1, 233472, 0xe5648329
-0, 50, 50, 1, 233472, 0xad8c7e94
-0, 51, 51, 1, 233472, 0xca0d82fc
-0, 52, 52, 1, 233472, 0x62277e8d
-0, 53, 53, 1, 233472, 0x7ef782f5
-0, 54, 54, 1, 233472, 0x09b27e8d
-0, 55, 55, 1, 233472, 0x66f382f5
-0, 56, 56, 1, 233472, 0x0aaa7e8d
-0, 57, 57, 1, 233472, 0x676b82f5
-0, 58, 58, 1, 233472, 0x0a8a7e8d
-0, 59, 59, 1, 233472, 0x670b82f5
-0, 60, 60, 1, 233472, 0x09fa7e8d
-0, 61, 61, 1, 233472, 0x671b82f5
-0, 62, 62, 1, 233472, 0x0ac27e8d
-0, 63, 63, 1, 233472, 0x674382f5
-0, 64, 64, 1, 233472, 0x0a727e8d
-0, 65, 65, 1, 233472, 0x673382f5
-0, 66, 66, 1, 233472, 0x0a127e8d
-0, 67, 67, 1, 233472, 0x66f382f5
-0, 68, 68, 1, 233472, 0x0aaa7e8d
-0, 69, 69, 1, 233472, 0x676b82f5
-0, 70, 70, 1, 233472, 0x0a8a7e8d
-0, 71, 71, 1, 233472, 0x670b82f5
-0, 72, 72, 1, 233472, 0x09fa7e8d
-0, 73, 73, 1, 233472, 0x671b82f5
-0, 74, 74, 1, 233472, 0x0ac27e8d
-0, 75, 75, 1, 233472, 0x674382f5
-0, 76, 76, 1, 233472, 0x0a727e8d
-0, 77, 77, 1, 233472, 0x673382f5
-0, 78, 78, 1, 233472, 0x0a127e8d
-0, 79, 79, 1, 233472, 0xa3917e7f
-0, 80, 80, 1, 233472, 0x0554868d
-0, 81, 81, 1, 233472, 0x05ba6d7a
-0, 82, 82, 1, 233472, 0x05ba6d7a
-0, 83, 83, 1, 233472, 0x05ba6d7a
-0, 84, 84, 1, 233472, 0x05ba6d7a
-0, 85, 85, 1, 233472, 0x05ba6d7a
-0, 86, 86, 1, 233472, 0x05ba6d7a
-0, 87, 87, 1, 233472, 0x05ba6d7a
-0, 88, 88, 1, 233472, 0x05ba6d7a
-0, 89, 89, 1, 233472, 0x05ba6d7a
-0, 90, 90, 1, 233472, 0x05ba6d7a
-0, 91, 91, 1, 233472, 0x05ba6d7a
-0, 92, 92, 1, 233472, 0x05ba6d7a
-0, 93, 93, 1, 233472, 0x05ba6d7a
-0, 94, 94, 1, 233472, 0x05ba6d7a
-0, 95, 95, 1, 233472, 0x05ba6d7a
-0, 96, 96, 1, 233472, 0x05ba6d7a
-0, 97, 97, 1, 233472, 0x05ba6d7a
-0, 98, 98, 1, 233472, 0x05ba6d7a
-0, 99, 99, 1, 233472, 0x05ba6d7a
-0, 100, 100, 1, 233472, 0x05ba6d7a
-0, 101, 101, 1, 233472, 0x05ba6d7a
-0, 102, 102, 1, 233472, 0x05ba6d7a
-0, 103, 103, 1, 233472, 0x05ba6d7a
-0, 104, 104, 1, 233472, 0x3a6a6d61
-0, 105, 105, 1, 233472, 0x0bab7adc
-0, 106, 106, 1, 233472, 0x12b44993
-0, 107, 107, 1, 233472, 0xa20ad6d1
-0, 108, 108, 1, 233472, 0xfd916a4a
-0, 109, 109, 1, 233472, 0xd34f3e95
-0, 110, 110, 1, 233472, 0x19571d5c
-0, 111, 111, 1, 233472, 0x7c8351ad
-0, 112, 112, 1, 233472, 0xea279823
-0, 113, 113, 1, 233472, 0xc5011cfd
-0, 114, 114, 1, 233472, 0xbd7fb9af
-0, 115, 115, 1, 233472, 0xdfb3bb7c
-0, 116, 116, 1, 233472, 0x6d631236
-0, 117, 117, 1, 233472, 0xdb579a7b
-0, 118, 118, 1, 233472, 0x47584a3e
-0, 119, 119, 1, 233472, 0x7a27a914
-0, 120, 120, 1, 233472, 0x2996270d
-0, 121, 121, 1, 233472, 0xefeaa7ed
-0, 122, 122, 1, 233472, 0xa3e74ae1
-0, 123, 123, 1, 233472, 0x8a51d61c
-0, 124, 124, 1, 233472, 0x25085ee7
-0, 125, 125, 1, 233472, 0x0a811253
-0, 126, 126, 1, 233472, 0x7d3eda84
-0, 127, 127, 1, 233472, 0xd0a0887d
-0, 128, 128, 1, 233472, 0xc9e6702c
-0, 129, 129, 1, 233472, 0x0da14346
-0, 130, 130, 1, 233472, 0x040f0605
-0, 131, 131, 1, 233472, 0x76ea841a
-0, 132, 132, 1, 233472, 0x105b6600
-0, 133, 133, 1, 233472, 0x73015e08
-0, 134, 134, 1, 233472, 0xe77d6662
-0, 135, 135, 1, 233472, 0x7514fcd1
-0, 136, 136, 1, 233472, 0xb091a850
-0, 137, 137, 1, 233472, 0x74ccdccd
-0, 138, 138, 1, 233472, 0xd1c002fc
-0, 139, 139, 1, 233472, 0x7bfcfdac
-0, 140, 140, 1, 233472, 0xf48a133f
-0, 141, 141, 1, 233472, 0x279c16dd
-0, 142, 142, 1, 233472, 0x58427907
-0, 143, 143, 1, 233472, 0x4668a8f2
-0, 144, 144, 1, 233472, 0x93fb555f
-0, 145, 145, 1, 233472, 0x49ed3cf2
-0, 146, 146, 1, 233472, 0xd620fac9
-0, 147, 147, 1, 233472, 0xe4efae83
-0, 148, 148, 1, 233472, 0xe4d377be
-0, 149, 149, 1, 233472, 0x6fc229c1
-0, 150, 150, 1, 233472, 0xab5a8898
-0, 151, 151, 1, 233472, 0x58a493dd
-0, 152, 152, 1, 233472, 0x5c1c1093
-0, 153, 153, 1, 233472, 0x2d831af9
-0, 154, 154, 1, 233472, 0x9a0d3cdf
-0, 155, 155, 1, 233472, 0x2be78f0b
-0, 156, 156, 1, 233472, 0xfc7cc656
-0, 157, 157, 1, 233472, 0xaa8624b7
-0, 158, 158, 1, 233472, 0xb9c9afc1
-0, 159, 159, 1, 233472, 0x709e8009
-0, 160, 160, 1, 233472, 0xd2260830
-0, 161, 161, 1, 233472, 0xadb3954e
-0, 162, 162, 1, 233472, 0x74fc3e65
-0, 163, 163, 1, 233472, 0xb4bcdea4
-0, 164, 164, 1, 233472, 0x60c46cf5
-0, 165, 165, 1, 233472, 0x0e48eff8
-0, 166, 166, 1, 233472, 0x60e46733
-0, 167, 167, 1, 233472, 0x708ec89f
-0, 168, 168, 1, 233472, 0x1f11264e
-0, 169, 169, 1, 233472, 0x6cba8300
-0, 170, 170, 1, 233472, 0xd1a5d756
-0, 171, 171, 1, 233472, 0xb936621e
-0, 172, 172, 1, 233472, 0x1667b4af
-0, 173, 173, 1, 233472, 0xc212276d
-0, 174, 174, 1, 233472, 0x9d7a871d
-0, 175, 175, 1, 233472, 0xb52834f9
-0, 176, 176, 1, 233472, 0x983bde84
-0, 177, 177, 1, 233472, 0xd1c63d88
-0, 178, 178, 1, 233472, 0xa38cb687
-0, 179, 179, 1, 233472, 0xd81bf8ff
-0, 180, 180, 1, 233472, 0x688b231a
-0, 181, 181, 1, 233472, 0xd5ad3038
-0, 182, 182, 1, 233472, 0xcd227f74
-0, 183, 183, 1, 233472, 0x81ec23d6
-0, 184, 184, 1, 233472, 0x52c1cd86
-0, 185, 185, 1, 233472, 0xa4199853
-0, 186, 186, 1, 233472, 0xe82c83e4
-0, 187, 187, 1, 233472, 0xe9810f88
-0, 188, 188, 1, 233472, 0x37e95ae7
-0, 189, 189, 1, 233472, 0xf6974d5d
-0, 190, 190, 1, 233472, 0x31788551
-0, 191, 191, 1, 233472, 0x00d6c539
-0, 192, 192, 1, 233472, 0xdbb52151
-0, 193, 193, 1, 233472, 0x594433d3
-0, 194, 194, 1, 233472, 0xeec44f91
-0, 195, 195, 1, 233472, 0x302894bf
-0, 196, 196, 1, 233472, 0x44f5ddc3
-0, 197, 197, 1, 233472, 0x6c1edd28
-0, 198, 198, 1, 233472, 0x7fd1e412
-0, 199, 199, 1, 233472, 0xd771f11b
-0, 200, 200, 1, 233472, 0x09c675d5
-0, 201, 201, 1, 233472, 0x8fd9112e
-0, 202, 202, 1, 233472, 0x602002e5
-0, 203, 203, 1, 233472, 0xb9a22029
-0, 204, 204, 1, 233472, 0x18e99807
-0, 205, 205, 1, 233472, 0x3d8657d8
-0, 206, 206, 1, 233472, 0x4cd73a85
-0, 207, 207, 1, 233472, 0x84ddb474
-0, 208, 208, 1, 233472, 0x69636bb8
-0, 209, 209, 1, 233472, 0xa0436d50
-0, 210, 210, 1, 233472, 0x93c86d78
-0, 211, 211, 1, 233472, 0x05ba6d7a
-0, 212, 212, 1, 233472, 0x05ba6d7a
-0, 213, 213, 1, 233472, 0x05ba6d7a
-0, 214, 214, 1, 233472, 0x126c6406
-0, 215, 215, 1, 233472, 0xe3885a3a
-0, 216, 216, 1, 233472, 0xf1256fe9
-0, 217, 217, 1, 233472, 0x5a84377e
-0, 218, 218, 1, 233472, 0x7c392d90
-0, 219, 219, 1, 233472, 0x8a74df48
-0, 220, 220, 1, 233472, 0xfa394653
-0, 221, 221, 1, 233472, 0xcbe0cc1b
-0, 222, 222, 1, 233472, 0xbf8639cf
-0, 223, 223, 1, 233472, 0x7dd2c935
-0, 224, 224, 1, 233472, 0x1093148f
-0, 225, 225, 1, 233472, 0x624d7d3e
-0, 226, 226, 1, 233472, 0xb340cd65
-0, 227, 227, 1, 233472, 0x6c0ae5c6
-0, 228, 228, 1, 233472, 0x0c5eaf73
-0, 229, 229, 1, 233472, 0x27be64ce
-0, 230, 230, 1, 233472, 0xac8990f4
-0, 231, 231, 1, 233472, 0x1f935102
-0, 232, 232, 1, 233472, 0x6e57d96f
-0, 233, 233, 1, 233472, 0xf246ea4d
-0, 234, 234, 1, 233472, 0x18058011
-0, 235, 235, 1, 233472, 0x5951fe6e
-0, 236, 236, 1, 233472, 0x0f10371d
-0, 237, 237, 1, 233472, 0xe1481043
-0, 238, 238, 1, 233472, 0xdedeefcc
-0, 239, 239, 1, 233472, 0xf8865db2
-0, 240, 240, 1, 233472, 0xe1b3d4d6
-0, 241, 241, 1, 233472, 0x81962c43
-0, 242, 242, 1, 233472, 0xe903d0bb
-0, 243, 243, 1, 233472, 0x6f530ac6
-0, 244, 244, 1, 233472, 0x94f7466c
-0, 245, 245, 1, 233472, 0xa8c1d365
-0, 246, 246, 1, 233472, 0xedcff050
diff --git a/ffmpeg-2-8-11/.gitattributes b/ffmpeg-2-8-12/.gitattributes
similarity index 100%
rename from ffmpeg-2-8-11/.gitattributes
rename to ffmpeg-2-8-12/.gitattributes
diff --git a/ffmpeg-2-8-11/COPYING.GPLv2 b/ffmpeg-2-8-12/COPYING.GPLv2
similarity index 100%
rename from ffmpeg-2-8-11/COPYING.GPLv2
rename to ffmpeg-2-8-12/COPYING.GPLv2
diff --git a/ffmpeg-2-8-11/COPYING.GPLv3 b/ffmpeg-2-8-12/COPYING.GPLv3
similarity index 100%
rename from ffmpeg-2-8-11/COPYING.GPLv3
rename to ffmpeg-2-8-12/COPYING.GPLv3
diff --git a/ffmpeg-2-8-11/COPYING.LGPLv2.1 b/ffmpeg-2-8-12/COPYING.LGPLv2.1
similarity index 100%
rename from ffmpeg-2-8-11/COPYING.LGPLv2.1
rename to ffmpeg-2-8-12/COPYING.LGPLv2.1
diff --git a/ffmpeg-2-8-11/COPYING.LGPLv3 b/ffmpeg-2-8-12/COPYING.LGPLv3
similarity index 100%
rename from ffmpeg-2-8-11/COPYING.LGPLv3
rename to ffmpeg-2-8-12/COPYING.LGPLv3
diff --git a/ffmpeg-2-8-11/CREDITS b/ffmpeg-2-8-12/CREDITS
similarity index 100%
rename from ffmpeg-2-8-11/CREDITS
rename to ffmpeg-2-8-12/CREDITS
diff --git a/ffmpeg-2-8-12/Changelog b/ffmpeg-2-8-12/Changelog
new file mode 100644
index 0000000..962ada5
--- /dev/null
+++ b/ffmpeg-2-8-12/Changelog
@@ -0,0 +1,2161 @@
+Entries are sorted chronologically from oldest to youngest within each release,
+releases are sorted from youngest to oldest.
+
+version 2.8.12:
+- avcodec/mjpegdec: Check that reference frame matches the current frame
+- avcodec/tiff: Avoid loosing allocated geotag values
+- avcodec/cavs: Fix runtime error: signed integer overflow: -12648062 * 256 cannot be represented in type 'int'
+- avformat/hls: Check local file extensions
+- avcodec/qdrw: Fix null pointer dereference
+- avutil/softfloat: Fix sign error in and improve documentation of av_int2sf()
+- avcodec/hevc_ps: Fix runtime error: index 32 out of bounds for type 'uint8_t [32]'
+- avcodec/pafvideo: Check packet size and frame code before ff_reget_buffer()
+- avcodec/ac3dec_fixed: Fix runtime error: left shift of 419 by 23 places cannot be represented in type 'int'
+- avcodec/aacps: Fix runtime error: left shift of 1073741824 by 1 places cannot be represented in type 'INTFLOAT' (aka 'int')
+- avcodec/wavpack: Fix runtime error: shift exponent 32 is too large for 32-bit type 'int'
+- avcodec/wavpack: Fix runtime error: signed integer overflow: 2013265955 - -134217694 cannot be represented in type 'int'
+- avcodec/cinepak: Check input packet size before frame reallocation
+- avcodec/hevc_ps: Fix runtime error: signed integer overflow: 2147483628 + 256 cannot be represented in type 'int'
+- avcodec/ra144: Fixes runtime error: signed integer overflow: 7160 * 327138 cannot be represented in type 'int'
+- avcodec/pnm: Use ff_set_dimensions()
+- avcodec/cavsdec: Fix runtime error: signed integer overflow: 59 + 2147483600 cannot be represented in type 'int'
+- avformat/avidec: Limit formats in gab2 to srt and ass/ssa
+- avcodec/acelp_pitch_delay: Fix runtime error: value 4.83233e+39 is outside the range of representable values of type 'float'
+- avcodec/wavpack: Check float_shift
+- avcodec/wavpack: Fix runtime error: signed integer overflow: 24 * -2147483648 cannot be represented in type 'int'
+- avcodec/ansi: Fix frame memleak
+- avcodec/jpeg2000dec: Use ff_set_dimensions()
+- avcodec/truemotion2: Fix passing null pointer to memset()
+- avcodec/truemotion2: Fix runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
+- avcodec/ra144: Fix runtime error: signed integer overflow: -2449 * 1398101 cannot be represented in type 'int'
+- avcodec/ra144: Fix runtime error: signed integer overflow: 11184810 * 404 cannot be represented in type 'int'
+- avcodec/aac_defines: Add missing () to AAC_HALF_SUM() macro
+- avcodec/webp: Fixes null pointer dereference
+- avcodec/aacdec_fixed: Fix runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
+- avcodec/snow: Fix runtime error: signed integer overflow: 1086573993 + 1086573994 cannot be represented in type 'int'
+- avcodec/jpeg2000: Fix runtime error: signed integer overflow: 4185 + 2147483394 cannot be represented in type 'int'
+- avcodec/jpeg2000dec: Check tile offsets more completely
+- avcodec/aacdec_fixed: Fix multiple runtime error: shift exponent 127 is too large for 32-bit type 'int'
+- avcodec/wnv1: More strict buffer size check
+- avcodec/libfdk-aacdec: Correct buffer_size parameter
+- avcodec/sbrdsp_template: Fix: runtime error: signed integer overflow: 849815297 + 1315389781 cannot be represented in type 'int'
+- avcodec/ivi_dsp: Fix runtime error: left shift of negative value -2
+- doc/filters: Clarify scale2ref example
+- avcodec/mlpdec: Do not leave invalid values in matrix_out_ch[] on error
+- avcodec/ra144dec: Fix runtime error: left shift of negative value -17
+- avformat/mux: Fix copy an paste typo
+- avutil/internal: Do not enable CHECKED with DEBUG
+- avcodec/aacdec_fixed: Fix runtime error: signed integer overflow: -2147483648 * -1 cannot be represented in type 'int'
+- avcodec/smc: Check remaining input
+- avcodec/jpeg2000dec: Fix copy and paste error
+- avcodec/jpeg2000dec: Check tile offsets
+- avcodec/sanm: Fix uninitialized reference frames
+- avcodec/jpeglsdec: Check get_bits_left() before decoding a picture
+- avcodec/ivi_dsp: Fix multiple runtime error: left shift of negative value -71
+- avcodec/mjpegdec: Fix runtime error: signed integer overflow: -32767 * 130560 cannot be represented in type 'int'
+- avcodec/aacdec_fixed: Fix runtime error: shift exponent 34 is too large for 32-bit type 'int'
+- avcodec/mpeg4videodec: Check for multiple VOL headers
+- avcodec/vmnc: Check location before use
+- avcodec/takdec: Fix runtime error: signed integer overflow: 8192 * 524308 cannot be represented in type 'int'
+- avcodec/aac_defines: Fix: runtime error: left shift of negative value -2
+- avcodec/takdec: Fix runtime error: left shift of negative value -63
+- avcodec/mlpdsp: Fix runtime error: signed integer overflow: -24419392 * 128 cannot be represented in type 'int'
+- avcodec/sbrdsp_fixed: fix runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
+- avcodec/aacsbr_fixed: Fix multiple runtime error: shift exponent 170 is too large for 32-bit type 'int'
+- avcodec/hevc_sei: fix amount of bits skipped when reading picture timing SEI message
+- avformat/concatdec: fix the h264 annexb extradata check
+- avformat/utils: free AVStream.codec properly in free_stream()
+- avcodec/options: do a more thorough clean up in avcodec_copy_context()
+- avcodec/options: factorize avcodec_copy_context() cleanup code
+- avcodec/mlpdec: Do not leave a invalid num_primitive_matrices in the context
+- avcodec/aacsbr_fixed: Fix multiple runtime error: shift exponent 150 is too large for 32-bit type 'int'
+- avcodec/mimic: Use ff_set_dimensions() to set the dimensions
+- avcodec/fic: Fix multiple runtime error: signed integer overflow: 5793 * 419752 cannot be represented in type 'int'
+- avcodec/mlpdec: Fix: runtime error: left shift of negative value -8
+- avcodec/dfa: Fix: runtime error: signed integer overflow: -14202 * 196877 cannot be represented in type 'int'
+- avcodec/aacdec: Fix runtime error: signed integer overflow: 2147483520 + 255 cannot be represented in type 'int'
+- avcodec/aacdec_template: Fix fixed point scale in decode_cce()
+- avcodec/flicvideo: Check frame_size before decrementing
+- avcodec/mlpdec: Fix runtime error: left shift of negative value -1
+- avcodec/takdec: Fix runtime error: left shift of negative value -42
+- avcodec/hq_hqa: Fix: runtime error: signed integer overflow: -255 * 10180917 cannot be represented in type 'int'
+- avcodec/truemotion1: Fix multiple runtime error: signed integer overflow: 1246906962 * 2 cannot be represented in type 'int'
+- avcodec/svq3: Fix runtime error: left shift of negative value -6
+- avcodec/tiff: reset sampling[] if its invalid
+- avcodec/aacps: Fix undefined behavior
+- avcodec/opus_silk: Fix integer overflow and out of array read
+- avcodec/flacdec: Return error code instead of 0 for failures
+- avcodec/snowdec: Check width
+- avcodec/webp: Update canvas size in vp8_lossy_decode_frame() as in vp8_lossless_decode_frame()
+- avcodec/webp: Factor update_canvas_size() out
+- avcodec/cllc: Check prefix
+- avcodec/dds: Fix runtime error: left shift of 210 by 24 places cannot be represented in type 'int'
+- avcodec/mpeg4videodec: Clear sprite wraping on unsupported cases in VOP decode
+- avcodec/ac3dec: Fix: runtime error: index -1 out of bounds for type 'INTFLOAT [2]'
+- avcodec/hqxdsp: Fix runtime error: signed integer overflow: -196264 * 11585 cannot be represented in type 'int'
+- libswscale/tests/swscale: Fix uninitialized variables
+- avcodec/ffv1dec: Fix runtime error: signed integer overflow: 1550964438 + 1550964438 cannot be represented in type 'int'
+- avcodec/webp: Fix signedness in prefix_code check
+- avcodec/svq3: Fix runtime error: signed integer overflow: 169 * 12717677 cannot be represented in type 'int'
+- avcodec/mlpdec: Check that there is enough data for headers
+- avcodec/ac3dec: Keep track of band structure
+- avcodec/webp: Add missing input padding
+- avcodec/aacdec_fixed: Fix runtime error: left shift of negative value -1
+- avcodec/aacsbr_template: Do not change bs_num_env before its checked
+- avcodec/mlp: Fix multiple runtime error: left shift of negative value -1
+- avcodec/vp8dsp: vp7_luma_dc_wht_c: Fix multiple runtime error: signed integer overflow: -1366381240 + -1262413604 cannot be represented in type 'int'
+- avcodec/avcodec: Limit the number of side data elements per packet
+- avcodec/texturedsp: Fix runtime error: left shift of 255 by 24 places cannot be represented in type 'int'
+- avcodec/wmv2dsp: Fix runtime error: signed integer overflow: 181 * -17047030 cannot be represented in type 'int'
+- avcodec/diracdec: Fix Assertion frame->buf[0] failed at libavcodec/decode.c:610
+- avcodec/msmpeg4dec: Check for cbpy VLC errors
+- avcodec/cllc: Check num_bits
+- avcodec/cllc: Factor VLC_BITS/DEPTH out, do not use repeated literal numbers
+- avcodec/dvbsubdec: Check entry_id
+- avcodec/aacdec_fixed: Fix multiple shift exponent 33 is too large for 32-bit type 'int'
+- avcodec/mpeg12dec: Fixes runtime error: division by zero
+- avcodec/webp: Always set pix_fmt
+- avfilter/vf_uspp: Fix currently unused input frame dimensions
+- avcodec/truemotion1: Fix multiple runtime error: left shift of negative value -1
+- avcodec/eatqi: Fix runtime error: signed integer overflow: 4466147 * 1075 cannot be represented in type 'int'
+- avcodec/dss_sp: Fix runtime error: signed integer overflow: 2147481189 + 4096 cannot be represented in type 'int'
+- avformat/wavdec: Check chunk_size
+- avcodec/cavs: Check updated MV
+- avcodec/y41pdec: Fix width in input buffer size check
+- avcodec/svq3: Fix multiple runtime error: signed integer overflow: -237341 * 24552 cannot be represented in type 'int'
+- avcodec/texturedsp: Fix runtime error: left shift of 218 by 24 places cannot be represented in type 'int'
+- avcodec/lagarith: Check scale_factor
+- avcodec/lagarith: Fix runtime error: left shift of negative value -1
+- avcodec/takdec: Fix multiple runtime error: left shift of negative value -1
+- avcodec/indeo2: Check for invalid VLCs
+- avcodec/htmlsubtitles: Check for string truncation and return error
+- avcodec/bmvvideo: Fix runtime error: left shift of 137 by 24 places cannot be represented in type 'int'
+- avcodec/dss_sp: Fix multiple runtime error: signed integer overflow: -15699 * -164039 cannot be represented in type 'int'
+- avcodec/dvbsubdec: check region dimensions
+- avcodec/vp8dsp: Fixes: runtime error: signed integer overflow: 1330143360 - -1023040530 cannot be represented in type 'int'
+- avcodec/hqxdsp: Fix multiple runtime error: signed integer overflow: 248220 * 21407 cannot be represented in type 'int' in idct_col()
+- avcodec/cavsdec: Check sym_factor
+- avcodec/cdxl: Check format for BGR24
+- avcodec/ffv1dec: Fix copying planes of paletted formats
+- avcodec/wmv2dsp: Fix runtime error: signed integer overflow: 181 * -12156865 cannot be represented in type 'int'
+- avcodec/xwddec: Check bpp more completely
+- avcodec/s302m: Fix left shift of 8 by 28 places cannot be represented in type 'int'
+- avcodec/eamad: Fix runtime error: signed integer overflow: 49674 * 49858 cannot be represented in type 'int'
+- avcodec/g726: Fix runtime error: left shift of negative value -2
+- avcodec/ra144: Fix runtime error: left shift of negative value -798
+- avcodec/mss34dsp: Fix multiple signed integer overflow
+- avcodec/targa_y216dec: Fix width type
+- avcodec/ivi_dsp: Fix multiple left shift of negative value -2
+- avcodec/svq3: Fix multiple runtime error: signed integer overflow: 44161 * 61694 cannot be represented in type 'int'
+- avcodec/msmpeg4dec: Correct table depth
+- avcodec/dds: Fix runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
+- avcodec/cdxl: Check format parameter
+- avutil/softfloat: Fix overflow in av_div_sf()
+- avcodec/hq_hqa: Fix runtime error: left shift of negative value -207
+- avcodec/mss3: Change types in rac_get_model_sym() to match the types they are initialized from
+- avcodec/shorten: Check k in get_uint()
+- avcodec/webp: Fix null pointer dereference
+- avcodec/dfa: Fix signed integer overflow: -2147483648 - 1 cannot be represented in type 'int'
+- avcodec/mimic: Fix runtime error: left shift of negative value -1
+- avcodec/fic: Fix multiple left shift of negative value -15
+- avcodec/mlpdec: Fix runtime error: left shift of negative value -22
+- avcodec/snowdec: Check qbias
+- avutil/softfloat: Fix multiple runtime error: left shift of negative value -8
+- avcodec/aacsbr_template: Do not leave bs_num_env invalid
+- avcodec/mdec: Fix signed integer overflow: 28835400 * 83 cannot be represented in type 'int'
+- avcodec/dfa: Fix off by 1 error
+- avcodec/nellymoser: Fix multiple left shift of negative value -8591
+- avcodec/cdxl: Fix signed integer overflow: 14243456 * 164 cannot be represented in type 'int'
+- avcodec/g722: Fix multiple runtime error: left shift of negative value -1
+- avcodec/dss_sp: Fix multiple left shift of negative value -466
+- avcodec/wnv1: Fix runtime error: left shift of negative value -1
+- avcodec/tiertexseqv: set the fixed dimenasions, do not depend on the demuxer doing so
+- avcodec/mjpegdec: Fix runtime error: signed integer overflow: -24543 * 2031616 cannot be represented in type 'int'
+- avcodec/cavsdec: Fix undefined behavior from integer overflow
+- avcodec/dvdsubdec: Fix runtime error: left shift of 242 by 24 places cannot be represented in type 'int'
+- libavcodec/mpeg4videodec: Convert sprite_offset to 64bit
+- avcodec/pngdec: Use ff_set_dimensions()
+- avcodec/msvideo1: Check buffer size before re-getting the frame
+- avcodec/h264_cavlc: Fix undefined behavior on qscale overflow
+- avcodec/svq3: Increase offsets to prevent integer overflows
+- avcodec/indeo2: Check remaining bits in ir2_decode_plane()
+- avcodec/vp3: Check remaining bits in unpack_dct_coeffs()
+- avcodec/mdec: Fix runtime error: left shift of negative value -127
+- libavcodec/exr : fix float to uint16 conversion for negative float value
+- avformat/webmdashenc: Validate the 'streams' adaptation sets parameter
+- avformat/webmdashenc: Require the 'adaptation_sets' option to be set
+- avcodec/dvdsubdec: Fixes 2 runtime error: left shift of 170 by 24 places cannot be represented in type 'int'
+- avfilter/avfiltergraph: Add assert to write down in machine readable form what is assumed about sample rates in swap_samplerates_on_filter()
+- avcodec/tiff: Perform multiply in tiff_unpack_lzma() as 64bit
+- avcodec/vdpau_hevc: Fix potential out-of-bounds write
+- avcodec/tiff: Check geotag count for being non zero
+- avcodec/vp56: Check avctx->error_concealment before enabling EC
+- avcodec/tiff: Check stripsize strippos for overflow
+- avcodec/mpegaudiodec_template: Make l3_unscale() work with e=0
+- avcodec/tiff: Check for multiple geo key directories
+- avcodec/wavpack: Fix runtime error: shift exponent 32 is too large for 32-bit type 'int'
+- avcodec/rv34: Fix runtime error: signed integer overflow: 36880 * 66288 cannot be represented in type 'int'
+- avcodec/amrwbdec: Fix runtime error: left shift of negative value -1
+- avcodec/mpeg4videodec: Fix runtime error: signed integer overflow: -135088512 * 16 cannot be represented in type 'int'
+- avcodec/h264_mvpred: Fix runtime error: left shift of negative value -1
+- avcodec/mjpegdec: Fix runtime error: left shift of negative value -127
+- avcodec/wavpack: Fix runtime error: left shift of negative value -5
+- avcodec/wavpack: Fix runtime error: left shift of negative value -2
+- avcodec/mpeg4videodec: Fix runtime error: signed integer overflow: 134527392 * 16 cannot be represented in type 'int'
+- avcodec/mpeg12dec: Fix runtime error: left shift of negative value -13
+- avcodec/h264_mvpred: Fix multiple runtime error: left shift of negative value
+- avcodec/adxdec: Fix runtime error: left shift of negative value -1
+- avcodec/mpeg4videodec: Improve the overflow checks in mpeg4_decode_sprite_trajectory()
+- avcodec/mjpegdec: Fix runtime error: left shift of negative value -511
+- avcodec/h264_direct: Fix runtime error: left shift of negative value -14
+- avcodec/pictordec: Check plane value before doing value/mask computations
+- avcodec/mpeg4videodec: Fix runtime error: left shift of negative value -2650
+- avcodec/eac3dec: Fix runtime error: left shift of negative value -3
+- avcodec/mpeg12dec: Fix runtime error: left shift of negative value -2
+- avcodec/mpeg4videodec: Check the other 3 sprite points for intermediate overflows
+- avcodec/mpeg4videodec: Check sprite_offset in addition to shifts
+- avcodec/mpeg4video: Fix runtime error: left shift of negative value
+- avcodec/ituh263dec: Fix runtime error: left shift of negative value -22
+- avcodec/rv40: Fix runtime error: left shift of negative value
+- avcodec/h264_cabac: runtime error: signed integer overflow: 2147483647 + 14 cannot be represented in type 'int'
+- avcodec/mpeg4videodec: Fix runtime error: shift exponent -2 is negative
+- avcodec/mjpegdec: Fix runtime error: left shift of negative value -507
+- avcodec/eac3dec: Fix runtime error: left shift of negative value
+- avcodec/vp6: clear dimensions on failed resolution change in vp6_parse_header()
+- avcodec/vp56: Reset have_undamaged_frame on resolution changes
+- avcodec/vp8: Fix hang with slice threads
+- avcodec/vp8: Check for the bitstream end per MB in decode_mb_row_no_filter()
+- avcodec/vp568: Check that there is enough data for ff_vp56_init_range_decoder()
+- avcodec/vp8: remove redundant check
+- avcodec/vp56: Require a correctly decoded frame before using vp56_conceal_mb()
+- avcodec/vp3: Do not return random positive values but the buf size
+- avcodec/vp8: Check for bitsteam end in decode_mb_row_no_filter()
+- avcodec/vp56: Factorize vp56_render_mb() out
+- avcodec/vp3dsp: Fix multiple signed integer overflow: 46341 * 47523 cannot be represented in type 'int'
+- Add CHECK/SUINT code
+- avcodec/mpeg12dec: Fix runtime error: left shift of negative value -1
+- avcodec/vp56: Clear dimensions in case of failure in the middle of a resolution change
+- avcodec/vp56: Implement very basic error concealment
+- avcodec/amrwbdec: Fix 2 runtime errors: left shift of negative value -1
+- avcodec/pngdec: Fix runtime error: left shift of 152 by 24 places cannot be represented in type 'int'
+- avcodec/vp56: Fix sign typo
+- avcodec/mpegaudiodec_template: Correct return code on id3 tag discarding
+- avcodec/rv34: Simplify and factor get_slice_offset() code
+- avcodec/pictordec: Do not read more than nb_planes
+- avcodec/srtdec: Fix signed integer overflow: 1811992524 * 384 cannot be represented in type 'int'
+- avcodec/pngdec: Check bit depth for validity
+- avcodec/mpeg12dec: Fix runtime error: left shift of negative value
+- avcodec/wavpacl: Fix runtime error: left shift of negative value -1
+- avformat/http: Check for truncated buffers in http_connect()
+- (github/release/2.8) avformat/apng: fix setting frame delay when max_fps is set to no limit
+- swresample/resample: free existing ResampleContext on reinit
+- swresample/resample: move resample_free() higher in the file
+- lavf/mpeg: Initialize a stack variable used by memcmp().
+- lavc/avpacket: Initialize a variable in error path.
+
+version 2.8.11
+- avcodec/h264_slice: Clear ref_counts on redundant slices
+- lavf/mov.c: Avoid heap allocation wrap in mov_read_uuid
+- lavf/mov.c: Avoid heap allocation wrap in mov_read_hdlr
+- avcodec/pictordec: Fix logic error
+- avcodec/movtextdec: Fix decode_styl() cleanup
+- lavf/matroskadec: fix is_keyframe for early Blocks
+- configure: bump year
+- avcodec/pngdec: Check trns more completely
+- avcodec/interplayvideo: Move parameter change check up
+- avcodec/mjpegdec: Check for for the bitstream end in mjpeg_decode_scan_progressive_ac()
+- avformat/flacdec: Check avio_read result when reading flac block header.
+- avcodec/utils: correct align value for interplay
+- avcodec/vp56: Check for the bitstream end, pass error codes on
+- avcodec/mjpegdec: Check remaining bitstream in ljpeg_decode_yuv_scan()
+- avcodec/pngdec: Fix off by 1 size in decode_zbuf()
+- avformat/avidec: skip odml master index chunks in avi_sync
+- avcodec/mjpegdec: Check for rgb before flipping
+- avutil/random_seed: Reduce the time needed on systems with very low precision clock()
+- avutil/random_seed: Improve get_generic_seed() with higher precision clock()
+- avformat/utils: Print verbose error message if stream count exceeds max_streams
+- avformat/options_table: Set the default maximum number of streams to 1000
+- avutil: Add av_image_check_size2()
+- avformat: Add max_streams option
+- avcodec/ffv1enc: Allocate smaller packet if the worst case size cannot be allocated
+- avcodec/mpeg4videodec: Fix undefined shifts in mpeg4_decode_sprite_trajectory()
+- avformat/oggdec: Skip streams in duration correction that did not had their duration set.
+- avcodec/ffv1enc: Fix size of first slice
+- pgssubdec: reset rle_data_len/rle_remaining_len on allocation error
+
+version 2.8.10
+- avformat/http: Match chunksize checks to master..3.0
+- Changelog: fix typos
+- ffserver: Check chunk size
+- Avoid using the term "file" and prefer "url" in some docs and comments
+- avformat/rtmppkt: Check for packet size mismatches
+- zmqsend: Initialize ret to 0
+- configure: check for strtoull on msvc
+- http: move chunk handling from http_read_stream() to http_buf_read().
+- http: make length/offset-related variables unsigned.
+
+version 2.8.9
+- avcodec/flacdec: Fix undefined shift in decode_subframe()
+- avcodec/get_bits: Fix get_sbits_long(0)
+- avformat/ffmdec: Check media type for chunks
+- avcodec/flacdec: Fix signed integer overflow in decode_subframe_fixed()
+- avcodec/flacdsp_template: Fix undefined shift in flac_decorrelate_indep_c
+- avformat/oggparsespeex: Check frames_per_packet and packet_size
+- avformat/utils: Check start/end before computing duration in update_stream_timings()
+- avcodec/flac_parser: Update nb_headers_buffered
+- avformat/idroqdec: Check chunk_size for being too large
+- filmstripdec: correctly check image dimensions
+- mss2: only use error correction for matching block counts
+- softfloat: decrease MIN_EXP to cover full float range
+- libopusdec: default to stereo for invalid number of channels
+- sbgdec: prevent NULL pointer access
+- smacker: limit recursion depth of smacker_decode_bigtree
+- mxfdec: fix NULL pointer dereference in mxf_read_packet_old
+- libschroedingerdec: fix leaking of framewithpts
+- libschroedingerdec: don't produce empty frames
+- softfloat: handle -INT_MAX correctly
+- pnmdec: make sure v is capped by maxval
+- smvjpegdec: make sure cur_frame is not negative
+- icodec: correctly check avio_read return value
+- icodec: fix leaking pkt on error
+- dvbsubdec: fix division by zero in compute_default_clut
+- proresdec_lgpl: explicitly check coff[3] against slice_data_size
+- escape124: reject codebook size 0
+- mpegts: prevent division by zero
+- matroskadec: fix NULL pointer dereference in webm_dash_manifest_read_header
+- mpegaudio_parser: don't return AVERROR_PATCHWELCOME
+- mxfdec: fix NULL pointer dereference
+- diracdec: check return code of get_buffer_with_edge
+- ppc: pixblockdsp: do unaligned block accesses correctly again
+- mpeg12dec: unref discarded picture from extradata
+- cavsdec: unref frame before referencing again
+- avformat: prevent triggering request_probe assert in ff_read_packet
+- avformat/mpeg: Adjust vid probe threshold to correct mis-detection
+- avcodec/rv40: Test remaining space in loop of get_dimension()
+- avcodec/ituh263dec: Avoid spending a long time in slice sync
+- avcodec/movtextdec: Add error message for tsmb_size check
+- avcodec/movtextdec: Fix tsmb_size check==0 check
+- avcodec/movtextdec: Fix potential integer overflow
+- avcodec/sunrast: Fix input buffer pointer check
+- avcodec/tscc: Check side data size before use
+- avcodec/rawdec: Check side data size before use
+- avcodec/msvideo1: Check side data size before use
+- avcodec/qpeg: Check side data size before use
+- avcodec/qtrle: Check side data size before use
+- avcodec/msrle: Check side data size before use
+- avcodec/kmvc: Check side data size before use
+- avcodec/idcinvideo: Check side data size before use
+- avcodec/cinepak: Check side data size before use
+- avcodec/8bps: Check side data size before use
+- avcodec/dvdsubdec: Fix off by 1 error
+- avcodec/dvdsubdec: Fix buf_size check
+- vp9: change order of operations in adapt_prob().
+- avcodec/interplayvideo: Check side data size before use
+- avformat/mxfdec: Check size to avoid integer overflow in mxf_read_utf16_string()
+- avcodec/mpegvideo_enc: Clear mmx state in ff_mpv_reallocate_putbitbuffer()
+- avcodec/utils: Clear MMX state before returning from avcodec_default_execute*()
+- cmdutils: fix typos
+- lavfi: fix typos
+- lavc: fix typos
+- tools: fix grammar error
+- avutil/mips/generic_macros_msa: rename macro variable which causes segfault for mips r6
+- videodsp: fix 1-byte overread in top/bottom READ_NUM_BYTES iterations.
+- avformat/avidec: Check nb_streams in read_gab2_sub()
+- avformat/avidec: Remove ancient assert
+- lavc/movtextdec.c: Avoid infinite loop on invalid data.
+- avcodec/ansi: Check dimensions
+- avcodec/cavsdsp: use av_clip_uint8() for idct
+
+version 2.8.8
+- avformat/movenc: Check packet in mov_write_single_packet() too
+- avformat/movenc: Factor check_pkt() out
+- avformat/utils: fix timebase error in avformat_seek_file()
+- avcodec/g726: Add missing ADDB output mask
+- avcodec/avpacket: clear side_data_elems
+- avcodec/ccaption_dec: Use simple array instead of AVBuffer
+- swscale/swscale_unscaled: Try to fix Rgb16ToPlanarRgb16Wrapper() with slices
+- swscale/swscale_unscaled: Fix packed_16bpc_bswap() with slices
+- avformat/avidec: Fix infinite loop in avi_read_nikon()
+- cmdutils: fix implicit declaration of SetDllDirectory function
+- cmdutils: check for SetDllDirectory() availability
+- avcodec/aacenc: Tighter input checks
+- libavcodec/wmalosslessdec: Check the remaining bits
+- avcodec/diracdec: Check numx/y
+- avcodec/indeo2: check ctab
+- avformat/swfdec: Fix inflate() error code check
+- avcodec/h264: Put context_count check back
+- cmdutils: remove the current working directory from the DLL search path on win32
+- avcodec/raw: Fix decoding of ilacetest.mov
+- avcodec/ffv1enc: Fix assertion failure with non zero bits per sample
+- avformat/oggdec: Fix integer overflow with invalid pts
+- ffplay: Fix invalid array index
+- avcodec/vp9_parser: Check the input frame sizes for being consistent
+- libavformat/rtpdec_asf: zero initialize the AVIOContext struct
+- libavutil/opt: Small bugfix in example.
+- libx264: Increase x264 opts character limit to 4096
+- avformat/mov: Check sample size
+- avformat/format: Fix registering a format more than once and related races
+- avcodec/flac_parser: Raise threshold for detecting invalid data
+- avfilter/vf_telecine: Make frame writable before writing into it
+- avcodec/mpc8: Correct end truncation
+- avcodec/mpegvideo: Do not clear the parse context during init
+- MAINTAINERs cleanup (remove myself from things i de facto do not maintain)
+- avcodec/h264: Fix off by 1 context count
+- avcodec/alsdec: Check r to prevent out of array read
+- avcodec/alsdec: fix max bits in ltp prefix code
+- avcodec/utils: check skip_samples signedness
+- avformat/mpegts: Do not trust BSSD descriptor, it is sometimes not an S302M stream
+- avcodec/bmp_parser: Check fsize
+- avcodec/bmp_parser: reset state
+- avcodec/bmp_parser: Fix remaining size
+- avcodec/bmp_parser: Fix frame_start_found in cross frame cases
+- avfilter/af_amix: do not fail if there are no samples in output_frame()
+- avformat/allformats: Making av_register_all() thread-safe.
+- avcodec/mpegvideo: Deallocate last/next picture earlier
+- avcodec/bmp_parser: Fix state
+- avformat/oggparseopus: Fix Undefined behavior in oggparseopus.c and libavformat/utils.c
+- doc/developer.texi: Add a code of conduct
+- avformat/avidec: Detect index with too short entries
+- avformat/utils: Check negative bps before shifting in ff_get_pcm_codec_id()
+- avformat/utils: Do not compute the bitrate from duration == 0
+- ffmpeg: Check that r_frame_rate is set before attempting to use it
+- swresample/rematrix: Use clipping s16 rematrixing if overflows are possible
+- swresample/rematrix: Use error diffusion to avoid error in the DC component of the matrix
+- libavformat/oggdec: Free stream private when header parsing fails.
+- avformat/utils: Check bps before using it in a shift in ff_get_pcm_codec_id()
+- avformat/oggparseopus: Check that granule pos is within the supported range
+- avcodec/mjpegdec: Do not try to detect last scan but apply idct after all scans for progressive jpeg
+- avformat/options_table: Add missing identifier for very strict compliance
+- librtmp: Avoid an infiniloop setting connection arguments
+- avformat/oggparsevp8: fix pts calculation on pages ending with an invisible frame
+
+
+version 2.8.7
+- avcodec/motion_est: Attempt to fix "short data segment overflowed" on IA64
+- avformat/ffmdec: Check pix_fmt
+- avcodec/ttaenc: Reallocate packet if its too small
+- pgssubdec: fix subpicture output colorspace and range
+- avcodec/ac3dec: Reset SPX when switching from EAC3 to AC3
+- avfilter/vf_drawtext: Check return code of load_glyph()
+- avcodec/takdec: add code that got somehow lost in process of REing
+- avcodec/apedec: fix decoding of stereo files with one channel full of silence
+- avcodec/avpacket: Fix off by 5 error
+- avcodec/h264: Fix for H.264 configuration parsing
+- avcodec/bmp_parser: Ensure remaining_size is not too small in startcode packet crossing corner case
+- avfilter/src_movie: fix how we check for overflows with seek_point
+- avcodec/j2kenc: Add attribution to OpenJPEG project:
+- avcodec/h264_slice: Check PPS more extensively when its not copied
+- avcodec/libutvideodec: copy frame so it has reference counters when refcounted_frames is set
+- avformat/rtpdec_jpeg: fix low contrast image on low quality setting
+- avcodec/mjpegenc_common: Store approximate aspect if exact cannot be stored
+- lavc/hevc: Allow arbitrary garbage in bytestream as long as at least one NAL unit is found.
+- avcodec/resample: Remove disabled and faulty code
+- indeo2: Fix banding artefacts
+- indeo2data: K&R formatting cosmetics
+- avcodec/imgconvert: Support non-planar colorspaces while padding
+- avutil/random_seed: Add the runtime in cycles of the main loop to the entropy pool
+- avutil/channel_layout: AV_CH_LAYOUT_6POINT1_BACK not reachable in parsing
+- avformat/concatdec: set safe mode to enabled instead of auto
+- avformat/utils: fix dts from pts code in compute_pkt_fields() during ascending delay
+- avformat/rtpenc: Fix integer overflow in NTP_TO_RTP_FORMAT
+- avformat/cache: Fix memleak of tree entries
+- lavf/mov: downgrade sidx errors to non-fatal warnings; fixes trac #5216 (cherry picked from commit 22dbc1caaf13e4bb17c9e0164a5b1ccaf490e428)
+- lavf/mov: fix sidx with edit lists (cherry picked from commit 3617e69d50dd9dd07b5011dfb9477a9d1a630354)
+- avcodec/mjpegdec: Fix decoding slightly odd progressive jpeg
+- libwebpenc_animencoder: print library messages in verbose log levels
+- libwebpenc_animencoder: zero initialize the WebPAnimEncoderOptions struct
+- doc/utils: fix typo for min() description
+- avcodec/avpacket: clear priv in av_init_packet()
+- swscale/utils: Fix chrSrcHSubSample for GBRAP16
+- swscale/input: Fix GBRAP16 input
+- postproc: fix unaligned access
+- avutil/pixdesc: Make get_color_type() aware of CIE XYZ formats
+- avcodec/h264: Execute error concealment before marking the frame as done.
+- swscale/x86/output: Fix yuv2planeX_16* with unaligned destination
+- swscale/x86/output: Move code into yuv2planeX_mainloop
+- avutil/frame: Free destination qp_table_buf in frame_copy_props()
+
+
+version 2.8.6
+- avcodec/jpeg2000dec: More completely check cdef
+- avutil/opt: check for and handle errors in av_opt_set_dict2()
+- avcodec/flacenc: fix calculation of bits required in case of custom sample rate
+- avformat: Document urls a bit
+- avformat/libquvi: Set default demuxer and protocol limitations
+- avformat/concat: Check protocol prefix
+- doc/demuxers: Document enable_drefs and use_absolute_path
+- avcodec/mjpegdec: Check for end for both bytes in unescaping
+- avcodec/mpegvideo_enc: Check for integer overflow in ff_mpv_reallocate_putbitbuffer()
+- avformat/avformat: Replace some references to filenames by urls
+- avcodec/wmaenc: Check ff_wma_init() for failure
+- avcodec/mpeg12enc: Move high resolution thread check to before initializing threads
+- avformat/img2dec: Use AVOpenCallback
+- avformat/avio: Limit url option parsing to the documented cases
+- avformat/img2dec: do not interpret the filename by default if a IO context has been opened
+- avcodec/ass_split: Fix null pointer dereference in ff_ass_style_get()
+- mov: Add an option to toggle dref opening
+- avcodec/gif: Fix lzw buffer size
+- avcodec/put_bits: Assert buf_ptr in flush_put_bits()
+- avcodec/tiff: Check subsample & rps values more completely
+- swscale/swscale: Add some sanity checks for srcSlice* parameters
+- swscale/x86/rgb2rgb_template: Fix planar2x() for short width
+- swscale/swscale_unscaled: Fix odd height inputs for bayer_to_yv12_wrapper()
+- swscale/swscale_unscaled: Fix odd height inputs for bayer_to_rgb24_wrapper()
+- avcodec/aacenc: Check both channels for finiteness
+- asfdec_o: check for too small size in asf_read_unknown
+- asfdec_o: break if EOF is reached after asf_read_packet_header
+- asfdec_o: make sure packet_size is non-zero before seeking
+- asfdec_o: prevent overflow causing seekback
+- asfdec_o: check avio_skip in asf_read_simple_index
+- asfdec_o: reject size > INT64_MAX in asf_read_unknown
+- asfdec_o: only set asf_pkt->data_size after sanity checks
+- Merge commit '8375dc1dd101d51baa430f34c0bcadfa37873896'
+- dca: fix misaligned access in avpriv_dca_convert_bitstream
+- brstm: fix missing closing brace
+- brstm: also allocate b->table in read_packet
+- brstm: make sure an ADPC chunk was read for adpcm_thp
+- vorbisdec: reject rangebits 0 with non-0 partitions
+- vorbisdec: reject channel mapping with less than two channels
+- ffmdec: reset packet_end in case of failure
+- avformat/ipmovie: put video decoding_map_size into packet and use it in decoder
+- avformat/brstm: fix overflow
+
+
+version 2.8.5
+- avformat/hls: Even stricter URL checks
+- avformat/hls: More strict url checks
+- avcodec/pngenc: Fix mixed up linesizes
+- avcodec/pngenc: Replace memcpy by av_image_copy()
+- swscale/vscale: Check that 2 tap filters are bilinear before using bilinear code
+- swscale: Move VScalerContext into vscale.c
+- swscale/utils: Detect and skip unneeded sws_setColorspaceDetails() calls
+- swscale/yuv2rgb: Increase YUV2RGB table headroom
+- swscale/yuv2rgb: Factor YUVRGB_TABLE_LUMA_HEADROOM out
+- avformat/hls: forbid all protocols except http(s) & file
+- avformat/aviobuf: Fix end check in put_str16()
+- avformat/asfenc: Check pts
+- avcodec/mpeg4video: Check time_incr
+- avcodec/wavpackenc: Check the number of channels
+- avcodec/wavpackenc: Headers are per channel
+- avcodec/aacdec_template: Check id_map
+- avcodec/dvdec: Fix "left shift of negative value -254"
+- avcodec/g2meet: Check for ff_els_decode_bit() failure in epic_decode_run_length()
+- avcodec/mjpegdec: Fix negative shift
+- avcodec/mss2: Check for repeat overflow
+- avformat: Add integer fps from 31 to 60 to get_std_framerate()
+- avformat/ivfenc: fix division by zero
+- avcodec/mpegvideo_enc: Clip bits_per_raw_sample within valid range
+- avfilter/vf_scale: set proper out frame color range
+- avcodec/motion_est: Fix mv_penalty table size
+- avcodec/h264_slice: Fix integer overflow in implicit weight computation
+- swscale/utils: Use normal bilinear scaler if fast cannot be used due to tiny dimensions
+- avcodec/put_bits: Always check buffer end before writing
+- mjpegdec: extend check for incompatible values of s->rgb and s->ls
+- swscale/utils: Fix intermediate format for cascaded alpha downscaling
+- avformat/mov: Update handbrake_version threshold for full mp3 parsing
+- x86/float_dsp: zero extend offset from ff_scalarproduct_float_sse
+- avfilter/vf_zoompan: do not free frame we pushed to lavfi
+- nuv: sanitize negative fps rate
+- nutdec: reject negative value_len in read_sm_data
+- xwddec: prevent overflow of lsize * avctx->height
+- nutdec: only copy the header if it exists
+- exr: fix out of bounds read in get_code
+- on2avc: limit number of bits to 30 in get_egolomb
+
+
+version 2.8.4
+- rawdec: only exempt BIT0 with need_copy from buffer sanity check
+- mlvdec: check that index_entries exist
+- avcodec/mpeg4videodec: also for empty partitioned slices
+- avcodec/h264_refs: Fix long_idx check
+- avcodec/h264_mc_template: prefetch list1 only if it is used in the MB
+- avcodec/h264_slice: Simplify ref2frm indexing
+- avfilter/vf_mpdecimate: Add missing emms_c()
+- sonic: make sure num_taps * channels is not larger than frame_size
+- opus_silk: fix typo causing overflow in silk_stabilize_lsf
+- ffm: reject invalid codec_id and codec_type
+- golomb: always check for invalid UE golomb codes in get_ue_golomb
+- sbr_qmf_analysis: sanitize input for 32-bit imdct
+- sbrdsp_fixed: assert that input values are in the valid range
+- aacsbr: ensure strictly monotone time borders
+- aacenc: update max_sfb when num_swb changes
+- aaccoder: prevent crash of anmr coder
+- ffmdec: reject zero-sized chunks
+- swscale/x86/rgb2rgb_template: Fallback to mmx in interleaveBytes() if the alignment is insufficient for SSE*
+- swscale/x86/rgb2rgb_template: Do not crash on misaligend stride
+- avformat/mxfenc: Do not crash if there is no packet in the first stream
+- lavf/tee: fix side data double free.
+- avformat/hlsenc: Check the return code of avformat_write_header()
+- avformat/mov: Enable parser for mp3s by old HandBrake
+- avformat/mxfenc: Fix integer overflow in length computation
+- avformat/utils: estimate_timings_from_pts - increase retry counter, fixes invalid duration for ts files with hevc codec
+- avformat/matroskaenc: Check codecdelay before use
+- avutil/mathematics: Fix division by 0
+- mjpegdec: consider chroma subsampling in size check
+- libvpxenc: remove some unused ctrl id mappings
+- avcodec/vp3: ensure header is parsed successfully before tables
+- avcodec/jpeg2000dec: Check bpno in decode_cblk()
+- avcodec/pgssubdec: Fix left shift of 255 by 24 places cannot be represented in type int
+- swscale/utils: Fix for runtime error: left shift of negative value -1
+- avcodec/hevc: Fix integer overflow of entry_point_offset
+- avcodec/dirac_parser: Check that there is a previous PU before accessing it
+- avcodec/dirac_parser: Add basic validity checks for next_pu_offset and prev_pu_offset
+- avcodec/dirac_parser: Fix potential overflows in pointer checks
+- avcodec/wmaprodec: Check bits per sample to be within the range not causing integer overflows
+- avcodec/wmaprodec: Fix overflow of cutoff
+- avformat/smacker: fix integer overflow with pts_inc
+- avcodec/vp3: Fix "runtime error: left shift of negative value"
+- avformat/riffdec: Initialize bitrate
+- mpegencts: Fix overflow in cbr mode period calculations
+- avutil/timecode: Fix fps check
+- avutil/mathematics: return INT64_MIN (=AV_NOPTS_VALUE) from av_rescale_rnd() for overflows
+- avcodec/apedec: Check length in long_filter_high_3800()
+- avcodec/vp3: always set pix_fmt in theora_decode_header()
+- avcodec/mpeg4videodec: Check available data before reading custom matrix
+- avutil/mathematics: Do not treat INT64_MIN as positive in av_rescale_rnd
+- avutil/integer: Fix av_mod_i() with negative dividend
+- avformat/dump: Fix integer overflow in av_dump_format()
+- avcodec/h264_refs: Check that long references match before use
+- avcodec/utils: Clear dimensions in ff_get_buffer() on failure
+- avcodec/utils: Use 64bit for aspect ratio calculation in avcodec_string()
+- avcodec/hevc: Check max ctb addresses for WPP
+- avcodec/vp3: Clear context on reinitialization failure
+- avcodec/hevc: allocate entries unconditionally
+- avcodec/hevc_cabac: Fix multiple integer overflows
+- avcodec/jpeg2000dwt: Check ndeclevels before calling dwt_encode*()
+- avcodec/jpeg2000dwt: Check ndeclevels before calling dwt_decode*()
+- avcodec/hevc: Check entry_point_offsets
+- lavf/rtpenc_jpeg: Less strict check for standard Huffman tables.
+- avcodec/ffv1dec: Clear quant_table_count if its invalid
+- avcodec/ffv1dec: Print an error if the quant table count is invalid
+- doc/filters/drawtext: fix centering example
+
+
+version 2.8.3
+- avcodec/cabac: Check initial cabac decoder state
+- avcodec/cabac_functions: Fix "left shift of negative value -31767"
+- avcodec/h264_slice: Limit max_contexts when slice_context_count is initialized
+- rtmpcrypt: Do the xtea decryption in little endian mode
+- avformat/matroskadec: Check subtitle stream before dereferencing
+- avcodec/pngdec: Replace assert by request for sample for unsupported TRNS cases
+- avformat/utils: Do not init parser if probing is unfinished
+- avcodec/jpeg2000dec: Fix potential integer overflow with tile dimensions
+- avcodec/jpeg2000: Use av_image_check_size() in ff_jpeg2000_init_component()
+- avcodec/wmaprodec: Check for overread in decode_packet()
+- avcodec/smacker: Check that the data size is a multiple of a sample vector
+- avcodec/takdec: Skip last p2 sample (which is unused)
+- avcodec/dxtory: Fix input size check in dxtory_decode_v1_410()
+- avcodec/dxtory: Fix input size check in dxtory_decode_v1_420()
+- avcodec/error_resilience: avoid accessing previous or next frames tables beyond height
+- avcodec/dpx: Move need_align to act per line
+- avcodec/flashsv: Check size before updating it
+- avcodec/ivi: Check image dimensions
+- avcodec/utils: Better check for channels in av_get_audio_frame_duration()
+- avcodec/jpeg2000dec: Check for duplicate SIZ marker
+- aacsbr: don't call sbr_dequant twice without intermediate read_sbr_data
+- hqx: correct type and size check of info_offset
+- mxfdec: check edit_rate also for physical_track
+- avcodec/jpeg2000: Change coord to 32bit to support larger than 32k width or height
+- avcodec/jpeg2000dec: Check SIZ dimensions to be within the supported range
+- avcodec/jpeg2000: Check comp coords to be within the supported size
+- mpegvideo: clear overread in clear_context
+- avcodec/avrndec: Use the AVFrame format instead of the context
+- dds: disable palette flag for compressed images
+- dds: validate compressed source buffer size
+- dds: validate source buffer size before copying
+- dvdsubdec: validate offset2 similar to offset1
+- brstm: reject negative sample rate
+- aacps: avoid division by zero in stereo_processing
+- softfloat: assert when the argument of av_sqrt_sf is negative
+
+version 2.8.2
+- various fixes in the aac_fixed decoder
+- various fixes in softfloat
+- swresample/resample: increase precision for compensation
+- lavf/mov: add support for sidx fragment indexes
+- avformat/mxfenc: Only store user comment related tags when needed
+- tests/fate/avformat: Fix fate-lavf
+- doc/ffmpeg: Clarify that the sdp_file option requires an rtp output.
+- ffmpeg: Don't try and write sdp info if none of the outputs had an rtp format.
+- apng: use correct size for output buffer
+- jvdec: avoid unsigned overflow in comparison
+- avcodec/jpeg2000dec: Clip all tile coordinates
+- avcodec/microdvddec: Check for string end in 'P' case
+- avcodec/dirac_parser: Fix undefined memcpy() use
+- avformat/xmv: Discard remainder of packet on error
+- avformat/xmv: factor return check out of if/else
+- avcodec/mpeg12dec: Do not call show_bits() with invalid bits
+- avcodec/faxcompr: Add missing runs check in decode_uncompressed()
+- libavutil/channel_layout: Check strtol*() for failure
+- avformat/mpegts: Only start probing data streams within probe_packets
+- avcodec/hevc_ps: Check chroma_format_idc
+- avcodec/ffv1dec: Check for 0 quant tables
+- avcodec/mjpegdec: Reinitialize IDCT on BPP changes
+- avcodec/mjpegdec: Check index in ljpeg_decode_yuv_scan() before using it
+- avutil/file_open: avoid file handle inheritance on Windows
+- avcodec/h264_slice: Disable slice threads if there are multiple access units in a packet
+- avformat/hls: update cookies on setcookie response
+- opusdec: Don't run vector_fmul_scalar on zero length arrays
+- avcodec/opusdec: Fix extra samples read index
+- avcodec/ffv1: Initialize vlc_state on allocation
+- avcodec/ffv1dec: update progress in case of broken pointer chains
+- avcodec/ffv1dec: Clear slice coordinates if they are invalid or slice header decoding fails for other reasons
+- rtsp: Allow $ as interleaved packet indicator before a complete response header
+- videodsp: don't overread edges in vfix3 emu_edge.
+- avformat/mp3dec: improve junk skipping heuristic
+- concatdec: fix file_start_time calculation regression
+- avcodec: loongson optimize h264dsp idct and loop filter with mmi
+- avcodec/jpeg2000dec: Clear properties in jpeg2000_dec_cleanup() too
+- avformat/hls: add support for EXT-X-MAP
+- avformat/hls: fix segment selection regression on track changes of live streams
+- configure: Require libkvazaar < 0.7.
+- avcodec/vp8: Do not use num_coeff_partitions in thread/buffer setup
+
+
+version 2.8.1:
+- swscale: fix ticket #4881
+- doc: fix spelling errors
+- hls: only seek if there is an offset
+- asfdec: add more checks for size left in asf packet buffer
+- asfdec: alloc enough space for storing name in asf_read_metadata_obj
+- avcodec/pngdec: Check blend_op.
+- h264_mp4toannexb: fix pps offfset fault when there are more than one sps in avcc
+- avcodec/h264_mp4toannexb_bsf: Use av_freep() to free spspps_buf
+- avformat/avidec: Workaround broken initial frame
+- avformat/hls: fix some cases of HLS streams which require cookies
+- avcodec/pngdec: reset has_trns after every decode_frame_png()
+- lavf/img2dec: Fix memory leak
+- avcodec/mp3: fix skipping zeros
+- avformat/srtdec: make sure we probe a number
+- configure: check for ID3D11VideoContext
+- avformat/vobsub: compare correct packet stream IDs
+- avformat/srtdec: more lenient first line probing
+- avformat/srtdec: fix number check for the first character
+- avcodec/mips: build fix for MSA 64bit
+- avcodec/mips: build fix for MSA
+- avformat/httpauth: Add space after commas in HTTP/RTSP auth header
+- libavformat/hlsenc: Use of uninitialized memory unlinking old files
+- avcodec/x86/sbrdsp: Fix using uninitialized upper 32bit of noise
+- avcodec/ffv1dec: Fix off by 1 error in quant_table_count check
+- avcodec/ffv1dec: Explicitly check read_quant_table() return value
+- dnxhddata: correct weight tables
+- dnxhddec: decode and use interlace mb flag
+- swscale: fix ticket #4877
+- avcodec/rangecoder: Check e
+- avcodec/ffv1: separate slice_count from max_slice_count
+- swscale: fix ticket 4850
+- cmdutils: Filter dst/srcw/h
+- avutil/log: fix zero length gnu_printf format string warning
+- lavf/webvttenc: Require webvtt file to contain exactly one WebVTT stream.
+- swscale/swscale: Fix "unused variable" warning
+- avcodec/mjpegdec: Fix decoding RGBA RCT LJPEG
+- MAINTAINERS: add 2.8, drop 2.2
+- doc: mention libavcodec can decode Opus natively
+- hevc: properly handle no_rasl_output_flag when removing pictures from the DPB
+- avfilter/af_ladspa: process all channels for nb_handles > 1
+- configure: add libsoxr to swresample's pkgconfig
+- lavc: Fix compilation with --disable-everything --enable-parser=mpeg4video.
+
+version 2.8:
+- colorkey video filter
+- BFSTM/BCSTM demuxer
+- little-endian ADPCM_THP decoder
+- Hap decoder and encoder
+- DirectDraw Surface image/texture decoder
+- ssim filter
+- optional new ASF demuxer
+- showvolume filter
+- Many improvements to the JPEG 2000 decoder
+- Go2Meeting decoding support
+- adrawgraph audio and drawgraph video filter
+- removegrain video filter
+- Intel QSV-accelerated MPEG-2 video and HEVC encoding
+- Intel QSV-accelerated MPEG-2 video and HEVC decoding
+- Intel QSV-accelerated VC-1 video decoding
+- libkvazaar HEVC encoder
+- erosion, dilation, deflate and inflate video filters
+- Dynamic Audio Normalizer as dynaudnorm filter
+- Reverse video and areverse audio filter
+- Random filter
+- deband filter
+- AAC fixed-point decoding
+- sidechaincompress audio filter
+- bitstream filter for converting HEVC from MP4 to Annex B
+- acrossfade audio filter
+- allyuv and allrgb video sources
+- atadenoise video filter
+- OS X VideoToolbox support
+- aphasemeter filter
+- showfreqs filter
+- vectorscope filter
+- waveform filter
+- hstack and vstack filter
+- Support DNx100 (1440x1080 at 8)
+- VAAPI hevc hwaccel
+- VDPAU hevc hwaccel
+- framerate filter
+- Switched default encoders for webm to VP9 and Opus
+- Removed experimental flag from the JPEG 2000 encoder
+
+
+version 2.7:
+- FFT video filter
+- TDSC decoder
+- DTS lossless extension (XLL) decoding (not lossless, disabled by default)
+- showwavespic filter
+- DTS decoding through libdcadec
+- Drop support for nvenc API before 5.0
+- nvenc HEVC encoder
+- Detelecine filter
+- Intel QSV-accelerated H.264 encoding
+- MMAL-accelerated H.264 decoding
+- basic APNG encoder and muxer with default extension "apng"
+- unpack DivX-style packed B-frames in MPEG-4 bitstream filter
+- WebM Live Chunk Muxer
+- nvenc level and tier options
+- chorus filter
+- Canopus HQ/HQA decoder
+- Automatically rotate videos based on metadata in ffmpeg
+- improved Quickdraw compatibility
+- VP9 high bit-depth and extended colorspaces decoding support
+- WebPAnimEncoder API when available for encoding and muxing WebP
+- Direct3D11-accelerated decoding
+- Support Secure Transport
+- Multipart JPEG demuxer
+
+
+version 2.6:
+- nvenc encoder
+- 10bit spp filter
+- colorlevels filter
+- RIFX format for *.wav files
+- RTP/mpegts muxer
+- non continuous cache protocol support
+- tblend filter
+- cropdetect support for non 8bpp, absolute (if limit >= 1) and relative (if limit < 1.0) threshold
+- Camellia symmetric block cipher
+- OpenH264 encoder wrapper
+- VOC seeking support
+- Closed caption Decoder
+- fspp, uspp, pp7 MPlayer postprocessing filters ported to native filters
+- showpalette filter
+- Twofish symmetric block cipher
+- Support DNx100 (960x720 at 8)
+- eq2 filter ported from libmpcodecs as eq filter
+- removed libmpcodecs
+- Changed default DNxHD colour range in QuickTime .mov derivatives to mpeg range
+- ported softpulldown filter from libmpcodecs as repeatfields filter
+- dcshift filter
+- RTP depacketizer for loss tolerant payload format for MP3 audio (RFC 5219)
+- RTP depacketizer for AC3 payload format (RFC 4184)
+- palettegen and paletteuse filters
+- VP9 RTP payload format (draft 0) experimental depacketizer
+- RTP depacketizer for DV (RFC 6469)
+- DXVA2-accelerated HEVC decoding
+- AAC ELD 480 decoding
+- Intel QSV-accelerated H.264 decoding
+- DSS SP decoder and DSS demuxer
+- Fix stsd atom corruption in DNxHD QuickTimes
+- Canopus HQX decoder
+- RTP depacketization of T.140 text (RFC 4103)
+- Port MIPS optimizations to 64-bit
+
+
+version 2.5:
+- HEVC/H.265 RTP payload format (draft v6) packetizer
+- SUP/PGS subtitle demuxer
+- ffprobe -show_pixel_formats option
+- CAST128 symmetric block cipher, ECB mode
+- STL subtitle demuxer and decoder
+- libutvideo YUV 4:2:2 10bit support
+- XCB-based screen-grabber
+- UDP-Lite support (RFC 3828)
+- xBR scaling filter
+- AVFoundation screen capturing support
+- ffserver supports codec private options
+- creating DASH compatible fragmented MP4, MPEG-DASH segmenting muxer
+- WebP muxer with animated WebP support
+- zygoaudio decoding support
+- APNG demuxer
+- postproc visualization support
+
+
+version 2.4:
+- Icecast protocol
+- ported lenscorrection filter from frei0r filter
+- large optimizations in dctdnoiz to make it usable
+- ICY metadata are now requested by default with the HTTP protocol
+- support for using metadata in stream specifiers in fftools
+- LZMA compression support in TIFF decoder
+- H.261 RTP payload format (RFC 4587) depacketizer and experimental packetizer
+- HEVC/H.265 RTP payload format (draft v6) depacketizer
+- added codecview filter to visualize information exported by some codecs
+- Matroska 3D support thorugh side data
+- HTML generation using texi2html is deprecated in favor of makeinfo/texi2any
+- silenceremove filter
+
+
+version 2.3:
+- AC3 fixed-point decoding
+- shuffleplanes filter
+- subfile protocol
+- Phantom Cine demuxer
+- replaygain data export
+- VP7 video decoder
+- Alias PIX image encoder and decoder
+- Improvements to the BRender PIX image decoder
+- Improvements to the XBM decoder
+- QTKit input device
+- improvements to OpenEXR image decoder
+- support decoding 16-bit RLE SGI images
+- GDI screen grabbing for Windows
+- alternative rendition support for HTTP Live Streaming
+- AVFoundation input device
+- Direct Stream Digital (DSD) decoder
+- Magic Lantern Video (MLV) demuxer
+- On2 AVC (Audio for Video) decoder
+- support for decoding through DXVA2 in ffmpeg
+- libbs2b-based stereo-to-binaural audio filter
+- libx264 reference frames count limiting depending on level
+- native Opus decoder
+- display matrix export and rotation API
+- WebVTT encoder
+- showcqt multimedia filter
+- zoompan filter
+- signalstats filter
+- hqx filter (hq2x, hq3x, hq4x)
+- flanger filter
+- Image format auto-detection
+- LRC demuxer and muxer
+- Samba protocol (via libsmbclient)
+- WebM DASH Manifest muxer
+- libfribidi support in drawtext
+
+
+version 2.2:
+
+- HNM version 4 demuxer and video decoder
+- Live HDS muxer
+- setsar/setdar filters now support variables in ratio expressions
+- elbg filter
+- string validation in ffprobe
+- support for decoding through VDPAU in ffmpeg (the -hwaccel option)
+- complete Voxware MetaSound decoder
+- remove mp3_header_compress bitstream filter
+- Windows resource files for shared libraries
+- aeval filter
+- stereoscopic 3d metadata handling
+- WebP encoding via libwebp
+- ATRAC3+ decoder
+- VP8 in Ogg demuxing
+- side & metadata support in NUT
+- framepack filter
+- XYZ12 rawvideo support in NUT
+- Exif metadata support in WebP decoder
+- OpenGL device
+- Use metadata_header_padding to control padding in ID3 tags (currently used in
+ MP3, AIFF, and OMA files), FLAC header, and the AVI "junk" block.
+- Mirillis FIC video decoder
+- Support DNx444
+- libx265 encoder
+- dejudder filter
+- Autodetect VDA like all other hardware accelerations
+- aliases and defaults for Ogg subtypes (opus, spx)
+
+
+version 2.1:
+
+- aecho filter
+- perspective filter ported from libmpcodecs
+- ffprobe -show_programs option
+- compand filter
+- RTMP seek support
+- when transcoding with ffmpeg (i.e. not streamcopying), -ss is now accurate
+ even when used as an input option. Previous behavior can be restored with
+ the -noaccurate_seek option.
+- ffmpeg -t option can now be used for inputs, to limit the duration of
+ data read from an input file
+- incomplete Voxware MetaSound decoder
+- read EXIF metadata from JPEG
+- DVB teletext decoder
+- phase filter ported from libmpcodecs
+- w3fdif filter
+- Opus support in Matroska
+- FFV1 version 1.3 is stable and no longer experimental
+- FFV1: YUVA(444,422,420) 9, 10 and 16 bit support
+- changed DTS stream id in lavf mpeg ps muxer from 0x8a to 0x88, to be
+ more consistent with other muxers.
+- adelay filter
+- pullup filter ported from libmpcodecs
+- ffprobe -read_intervals option
+- Lossless and alpha support for WebP decoder
+- Error Resilient AAC syntax (ER AAC LC) decoding
+- Low Delay AAC (ER AAC LD) decoding
+- mux chapters in ASF files
+- SFTP protocol (via libssh)
+- libx264: add ability to encode in YUVJ422P and YUVJ444P
+- Fraps: use BT.709 colorspace by default for yuv, as reference fraps decoder does
+- make decoding alpha optional for prores, ffv1 and vp6 by setting
+ the skip_alpha flag.
+- ladspa wrapper filter
+- native VP9 decoder
+- dpx parser
+- max_error_rate parameter in ffmpeg
+- PulseAudio output device
+- ReplayGain scanner
+- Enhanced Low Delay AAC (ER AAC ELD) decoding (no LD SBR support)
+- Linux framebuffer output device
+- HEVC decoder
+- raw HEVC, HEVC in MOV/MP4, HEVC in Matroska, HEVC in MPEG-TS demuxing
+- mergeplanes filter
+
+
+version 2.0:
+
+- curves filter
+- reference-counting for AVFrame and AVPacket data
+- ffmpeg now fails when input options are used for output file
+ or vice versa
+- support for Monkey's Audio versions from 3.93
+- perms and aperms filters
+- audio filtering support in ffplay
+- 10% faster aac encoding on x86 and MIPS
+- sine audio filter source
+- WebP demuxing and decoding support
+- ffmpeg options -filter_script and -filter_complex_script, which allow a
+ filtergraph description to be read from a file
+- OpenCL support
+- audio phaser filter
+- separatefields filter
+- libquvi demuxer
+- uniform options syntax across all filters
+- telecine filter
+- interlace filter
+- smptehdbars source
+- inverse telecine filters (fieldmatch and decimate)
+- colorbalance filter
+- colorchannelmixer filter
+- The matroska demuxer can now output proper verbatim ASS packets. It will
+ become the default at the next libavformat major bump.
+- decent native animated GIF encoding
+- asetrate filter
+- interleave filter
+- timeline editing with filters
+- vidstabdetect and vidstabtransform filters for video stabilization using
+ the vid.stab library
+- astats filter
+- trim and atrim filters
+- ffmpeg -t and -ss (output-only) options are now sample-accurate when
+ transcoding audio
+- Matroska muxer can now put the index at the beginning of the file.
+- extractplanes filter
+- avectorscope filter
+- ADPCM DTK decoder
+- ADP demuxer
+- RSD demuxer
+- RedSpark demuxer
+- ADPCM IMA Radical decoder
+- zmq filters
+- DCT denoiser filter (dctdnoiz)
+- Wavelet denoiser filter ported from libmpcodecs as owdenoise (formerly "ow")
+- Apple Intermediate Codec decoder
+- Escape 130 video decoder
+- FTP protocol support
+- V4L2 output device
+- 3D LUT filter (lut3d)
+- SMPTE 302M audio encoder
+- support for slice multithreading in libavfilter
+- Hald CLUT support (generation and filtering)
+- VC-1 interlaced B-frame support
+- support for WavPack muxing (raw and in Matroska)
+- XVideo output device
+- vignette filter
+- True Audio (TTA) encoder
+- Go2Webinar decoder
+- mcdeint filter ported from libmpcodecs
+- sab filter ported from libmpcodecs
+- ffprobe -show_chapters option
+- WavPack encoding through libwavpack
+- rotate filter
+- spp filter ported from libmpcodecs
+- libgme support
+- psnr filter
+
+
+version 1.2:
+
+- VDPAU hardware acceleration through normal hwaccel
+- SRTP support
+- Error diffusion dither in Swscale
+- Chained Ogg support
+- Theora Midstream reconfiguration support
+- EVRC decoder
+- audio fade filter
+- filtering audio with unknown channel layout
+- allpass, bass, bandpass, bandreject, biquad, equalizer, highpass, lowpass
+ and treble audio filter
+- improved showspectrum filter, with multichannel support and sox-like colors
+- histogram filter
+- tee muxer
+- il filter ported from libmpcodecs
+- support ID3v2 tags in ASF files
+- encrypted TTA stream decoding support
+- RF64 support in WAV muxer
+- noise filter ported from libmpcodecs
+- Subtitles character encoding conversion
+- blend filter
+- stereo3d filter ported from libmpcodecs
+
+
+version 1.1:
+
+- stream disposition information printing in ffprobe
+- filter for loudness analysis following EBU R128
+- Opus encoder using libopus
+- ffprobe -select_streams option
+- Pinnacle TARGA CineWave YUV16 decoder
+- TAK demuxer, decoder and parser
+- DTS-HD demuxer
+- remove -same_quant, it hasn't worked for years
+- FFM2 support
+- X-Face image encoder and decoder
+- 24-bit FLAC encoding
+- multi-channel ALAC encoding up to 7.1
+- metadata (INFO tag) support in WAV muxer
+- subtitles raw text decoder
+- support for building DLLs using MSVC
+- LVF demuxer
+- ffescape tool
+- metadata (info chunk) support in CAF muxer
+- field filter ported from libmpcodecs
+- AVR demuxer
+- geq filter ported from libmpcodecs
+- remove ffserver daemon mode
+- AST muxer/demuxer
+- new expansion syntax for drawtext
+- BRender PIX image decoder
+- ffprobe -show_entries option
+- ffprobe -sections option
+- ADPCM IMA Dialogic decoder
+- BRSTM demuxer
+- animated GIF decoder and demuxer
+- PVF demuxer
+- subtitles filter
+- IRCAM muxer/demuxer
+- Paris Audio File demuxer
+- Virtual concatenation demuxer
+- VobSub demuxer
+- JSON captions for TED talks decoding support
+- SOX Resampler support in libswresample
+- aselect filter
+- SGI RLE 8-bit / Silicon Graphics RLE 8-bit video decoder
+- Silicon Graphics Motion Video Compressor 1 & 2 decoder
+- Silicon Graphics Movie demuxer
+- apad filter
+- Resolution & pixel format change support with multithreading for H.264
+- documentation split into per-component manuals
+- pp (postproc) filter ported from MPlayer
+- NIST Sphere demuxer
+- MPL2, VPlayer, MPlayer, AQTitle, PJS and SubViewer v1 subtitles demuxers and decoders
+- Sony Wave64 muxer
+- adobe and limelight publisher authentication in RTMP
+- data: URI scheme
+- support building on the Plan 9 operating system
+- kerndeint filter ported from MPlayer
+- histeq filter ported from VirtualDub
+- Megalux Frame demuxer
+- 012v decoder
+- Improved AVC Intra decoding support
+
+
+version 1.0:
+
+- INI and flat output in ffprobe
+- Scene detection in libavfilter
+- Indeo Audio decoder
+- channelsplit audio filter
+- setnsamples audio filter
+- atempo filter
+- ffprobe -show_data option
+- RTMPT protocol support
+- iLBC encoding/decoding via libilbc
+- Microsoft Screen 1 decoder
+- join audio filter
+- audio channel mapping filter
+- Microsoft ATC Screen decoder
+- RTSP listen mode
+- TechSmith Screen Codec 2 decoder
+- AAC encoding via libfdk-aac
+- Microsoft Expression Encoder Screen decoder
+- RTMPS protocol support
+- RTMPTS protocol support
+- RTMPE protocol support
+- RTMPTE protocol support
+- showwaves and showspectrum filter
+- LucasArts SMUSH SANM playback support
+- LucasArts SMUSH VIMA audio decoder (ADPCM)
+- LucasArts SMUSH demuxer
+- SAMI, RealText and SubViewer demuxers and decoders
+- Heart Of Darkness PAF playback support
+- iec61883 device
+- asettb filter
+- new option: -progress
+- 3GPP Timed Text encoder/decoder
+- GeoTIFF decoder support
+- ffmpeg -(no)stdin option
+- Opus decoder using libopus
+- caca output device using libcaca
+- alphaextract and alphamerge filters
+- concat filter
+- flite filter
+- Canopus Lossless Codec decoder
+- bitmap subtitles in filters (experimental and temporary)
+- MP2 encoding via TwoLAME
+- bmp parser
+- smptebars source
+- asetpts filter
+- hue filter
+- ICO muxer
+- SubRip encoder and decoder without embedded timing
+- edge detection filter
+- framestep filter
+- ffmpeg -shortest option is now per-output file
+ -pass and -passlogfile are now per-output stream
+- volume measurement filter
+- Ut Video encoder
+- Microsoft Screen 2 decoder
+- smartblur filter ported from MPlayer
+- CPiA decoder
+- decimate filter ported from MPlayer
+- RTP depacketization of JPEG
+- Smooth Streaming live segmenter muxer
+- F4V muxer
+- sendcmd and asendcmd filters
+- WebVTT demuxer and decoder (simple tags supported)
+- RTP packetization of JPEG
+- faststart option in the MOV/MP4 muxer
+- support for building with MSVC
+
+
+version 0.11:
+
+- Fixes: CVE-2012-2772, CVE-2012-2774, CVE-2012-2775, CVE-2012-2776, CVE-2012-2777,
+ CVE-2012-2779, CVE-2012-2782, CVE-2012-2783, CVE-2012-2784, CVE-2012-2785,
+ CVE-2012-2786, CVE-2012-2787, CVE-2012-2788, CVE-2012-2789, CVE-2012-2790,
+ CVE-2012-2791, CVE-2012-2792, CVE-2012-2793, CVE-2012-2794, CVE-2012-2795,
+ CVE-2012-2796, CVE-2012-2797, CVE-2012-2798, CVE-2012-2799, CVE-2012-2800,
+ CVE-2012-2801, CVE-2012-2802, CVE-2012-2803, CVE-2012-2804,
+- v408 Quicktime and Microsoft AYUV Uncompressed 4:4:4:4 encoder and decoder
+- setfield filter
+- CDXL demuxer and decoder
+- Apple ProRes encoder
+- ffprobe -count_packets and -count_frames options
+- Sun Rasterfile Encoder
+- ID3v2 attached pictures reading and writing
+- WMA Lossless decoder
+- bluray protocol
+- blackdetect filter
+- libutvideo encoder wrapper (--enable-libutvideo)
+- swapuv filter
+- bbox filter
+- XBM encoder and decoder
+- RealAudio Lossless decoder
+- ZeroCodec decoder
+- tile video filter
+- Metal Gear Solid: The Twin Snakes demuxer
+- OpenEXR image decoder
+- removelogo filter
+- drop support for ffmpeg without libavfilter
+- drawtext video filter: fontconfig support
+- ffmpeg -benchmark_all option
+- super2xsai filter ported from libmpcodecs
+- add libavresample audio conversion library for compatibility
+- MicroDVD decoder
+- Avid Meridien (AVUI) encoder and decoder
+- accept + prefix to -pix_fmt option to disable automatic conversions.
+- complete audio filtering in libavfilter and ffmpeg
+- add fps filter
+- vorbis parser
+- png parser
+- audio mix filter
+- ffv1: support (draft) version 1.3
+
+
+version 0.10:
+
+- Fixes: CVE-2011-3929, CVE-2011-3934, CVE-2011-3935, CVE-2011-3936,
+ CVE-2011-3937, CVE-2011-3940, CVE-2011-3941, CVE-2011-3944,
+ CVE-2011-3945, CVE-2011-3946, CVE-2011-3947, CVE-2011-3949,
+ CVE-2011-3950, CVE-2011-3951, CVE-2011-3952
+- v410 Quicktime Uncompressed 4:4:4 10-bit encoder and decoder
+- SBaGen (SBG) binaural beats script demuxer
+- OpenMG Audio muxer
+- Timecode extraction in DV and MOV
+- thumbnail video filter
+- XML output in ffprobe
+- asplit audio filter
+- tinterlace video filter
+- astreamsync audio filter
+- amerge audio filter
+- ISMV (Smooth Streaming) muxer
+- GSM audio parser
+- SMJPEG muxer
+- XWD encoder and decoder
+- Automatic thread count based on detection number of (available) CPU cores
+- y41p Brooktree Uncompressed 4:1:1 12-bit encoder and decoder
+- ffprobe -show_error option
+- Avid 1:1 10-bit RGB Packer codec
+- v308 Quicktime Uncompressed 4:4:4 encoder and decoder
+- yuv4 libquicktime packed 4:2:0 encoder and decoder
+- ffprobe -show_frames option
+- silencedetect audio filter
+- ffprobe -show_program_version, -show_library_versions, -show_versions options
+- rv34: frame-level multi-threading
+- optimized iMDCT transform on x86 using SSE for for mpegaudiodec
+- Improved PGS subtitle decoder
+- dumpgraph option to lavfi device
+- r210 and r10k encoders
+- ffwavesynth decoder
+- aviocat tool
+- ffeval tool
+- support encoding and decoding 4-channel SGI images
+
+
+version 0.9:
+
+- openal input device added
+- boxblur filter added
+- BWF muxer
+- Flash Screen Video 2 decoder
+- lavfi input device added
+- added avconv, which is almost the same for now, except
+for a few incompatible changes in the options, which will hopefully make them
+easier to use. The changes are:
+ * The options placement is now strictly enforced! While in theory the
+ options for ffmpeg should be given in [input options] -i INPUT [output
+ options] OUTPUT order, in practice it was possible to give output options
+ before the -i and it mostly worked. Except when it didn't - the behavior was
+ a bit inconsistent. In avconv, it is not possible to mix input and output
+ options. All non-global options are reset after an input or output filename.
+ * All per-file options are now truly per-file - they apply only to the next
+ input or output file and specifying different values for different files
+ will now work properly (notably -ss and -t options).
+ * All per-stream options are now truly per-stream - it is possible to
+ specify which stream(s) should a given option apply to. See the Stream
+ specifiers section in the avconv manual for details.
+ * In ffmpeg some options (like -newvideo/-newaudio/...) are irregular in the
+ sense that they're specified after the output filename instead of before,
+ like all other options. In avconv this irregularity is removed, all options
+ apply to the next input or output file.
+ * -newvideo/-newaudio/-newsubtitle options were removed. Not only were they
+ irregular and highly confusing, they were also redundant. In avconv the -map
+ option will create new streams in the output file and map input streams to
+ them. E.g. avconv -i INPUT -map 0 OUTPUT will create an output stream for
+ each stream in the first input file.
+ * The -map option now has slightly different and more powerful syntax:
+ + Colons (':') are used to separate file index/stream type/stream index
+ instead of dots. Comma (',') is used to separate the sync stream instead
+ of colon.. This is done for consistency with other options.
+ + It's possible to specify stream type. E.g. -map 0:a:2 creates an
+ output stream from the third input audio stream.
+ + Omitting the stream index now maps all the streams of the given type,
+ not just the first. E.g. -map 0:s creates output streams for all the
+ subtitle streams in the first input file.
+ + Since -map can now match multiple streams, negative mappings were
+ introduced. Negative mappings disable some streams from an already
+ defined map. E.g. '-map 0 -map -0:a:1' means 'create output streams for
+ all the stream in the first input file, except for the second audio
+ stream'.
+ * There is a new option -c (or -codec) for choosing the decoder/encoder to
+ use, which makes it possible to precisely specify target stream(s) consistently with
+ other options. E.g. -c:v lib264 sets the codec for all video streams, -c:a:0
+ libvorbis sets the codec for the first audio stream and -c copy copies all
+ the streams without reencoding. Old -vcodec/-acodec/-scodec options are now
+ aliases to -c:v/a/s
+ * It is now possible to precisely specify which stream should an AVOption
+ apply to. E.g. -b:v:0 2M sets the bitrate for the first video stream, while
+ -b:a 128k sets the bitrate for all audio streams. Note that the old -ab 128k
+ syntax is deprecated and will stop working soon.
+ * -map_chapters now takes only an input file index and applies to the next
+ output file. This is consistent with how all the other options work.
+ * -map_metadata now takes only an input metadata specifier and applies to
+ the next output file. Output metadata specifier is now part of the option
+ name, similarly to the AVOptions/map/codec feature above.
+ * -metadata can now be used to set metadata on streams and chapters, e.g.
+ -metadata:s:1 language=eng sets the language of the first stream to 'eng'.
+ This made -vlang/-alang/-slang options redundant, so they were removed.
+ * -qscale option now uses stream specifiers and applies to all streams, not
+ just video. I.e. plain -qscale number would now apply to all streams. To get
+ the old behavior, use -qscale:v. Also there is now a shortcut -q for -qscale
+ and -aq is now an alias for -q:a.
+ * -vbsf/-absf/-sbsf options were removed and replaced by a -bsf option which
+ uses stream specifiers. Use -bsf:v/a/s instead of the old options.
+ * -itsscale option now uses stream specifiers, so its argument is only the
+ scale parameter.
+ * -intra option was removed, use -g 0 for the same effect.
+ * -psnr option was removed, use -flags +psnr for the same effect.
+ * -vf option is now an alias to the new -filter option, which uses stream specifiers.
+ * -vframes/-aframes/-dframes options are now aliases to the new -frames option.
+ * -vtag/-atag/-stag options are now aliases to the new -tag option.
+- XMV demuxer
+- LOAS demuxer
+- ashowinfo filter added
+- Windows Media Image decoder
+- amovie source added
+- LATM muxer/demuxer
+- Speex encoder via libspeex
+- JSON output in ffprobe
+- WTV muxer
+- Optional C++ Support (needed for libstagefright)
+- H.264 Decoding on Android via Stagefright
+- Prores decoder
+- BIN/XBIN/ADF/IDF text file decoder
+- aconvert audio filter added
+- audio support to lavfi input device added
+- libcdio-paranoia input device for audio CD grabbing
+- Apple ProRes decoder
+- CELT in Ogg demuxing
+- G.723.1 demuxer and decoder
+- libmodplug support (--enable-libmodplug)
+- VC-1 interlaced decoding
+- libutvideo wrapper (--enable-libutvideo)
+- aevalsrc audio source added
+- Ut Video decoder
+- Speex encoding via libspeex
+- 4:2:2 H.264 decoding support
+- 4:2:2 and 4:4:4 H.264 encoding with libx264
+- Pulseaudio input device
+- Prores encoder
+- Video Decoder Acceleration (VDA) HWAccel module.
+- replacement Indeo 3 decoder
+- new ffmpeg option: -map_channel
+- volume audio filter added
+- earwax audio filter added
+- libv4l2 support (--enable-libv4l2)
+- TLS/SSL and HTTPS protocol support
+- AVOptions API rewritten and documented
+- most of CODEC_FLAG2_*, some CODEC_FLAG_* and many codec-specific fields in
+ AVCodecContext deprecated. Codec private options should be used instead.
+- Properly working defaults in libx264 wrapper, support for native presets.
+- Encrypted OMA files support
+- Discworld II BMV decoding support
+- VBLE Decoder
+- OS X Video Decoder Acceleration (VDA) support
+- compact and csv output in ffprobe
+- pan audio filter
+- IFF Amiga Continuous Bitmap (ACBM) decoder
+- ass filter
+- CRI ADX audio format muxer and demuxer
+- Playstation Portable PMP format demuxer
+- Microsoft Windows ICO demuxer
+- life source
+- PCM format support in OMA demuxer
+- CLJR encoder
+- new option: -report
+- Dxtory capture format decoder
+- cellauto source
+- Simple segmenting muxer
+- Indeo 4 decoder
+- SMJPEG demuxer
+
+
+version 0.8:
+
+- many many things we forgot because we rather write code than changelogs
+- WebM support in Matroska de/muxer
+- low overhead Ogg muxing
+- MMS-TCP support
+- VP8 de/encoding via libvpx
+- Demuxer for On2's IVF format
+- Pictor/PC Paint decoder
+- HE-AAC v2 decoder
+- HE-AAC v2 encoding with libaacplus
+- libfaad2 wrapper removed
+- DTS-ES extension (XCh) decoding support
+- native VP8 decoder
+- RTSP tunneling over HTTP
+- RTP depacketization of SVQ3
+- -strict inofficial replaced by -strict unofficial
+- ffplay -exitonkeydown and -exitonmousedown options added
+- native GSM / GSM MS decoder
+- RTP depacketization of QDM2
+- ANSI/ASCII art playback system
+- Lego Mindstorms RSO de/muxer
+- libavcore added (and subsequently removed)
+- SubRip subtitle file muxer and demuxer
+- Chinese AVS encoding via libxavs
+- ffprobe -show_packets option added
+- RTP packetization of Theora and Vorbis
+- RTP depacketization of MP4A-LATM
+- RTP packetization and depacketization of VP8
+- hflip filter
+- Apple HTTP Live Streaming demuxer
+- a64 codec
+- MMS-HTTP support
+- G.722 ADPCM audio encoder/decoder
+- R10k video decoder
+- ocv_smooth filter
+- frei0r wrapper filter
+- change crop filter syntax to width:height:x:y
+- make the crop filter accept parametric expressions
+- make ffprobe accept AVFormatContext options
+- yadif filter
+- blackframe filter
+- Demuxer for Leitch/Harris' VR native stream format (LXF)
+- RTP depacketization of the X-QT QuickTime format
+- SAP (Session Announcement Protocol, RFC 2974) muxer and demuxer
+- cropdetect filter
+- ffmpeg -crop* options removed
+- transpose filter added
+- ffmpeg -force_key_frames option added
+- demuxer for receiving raw rtp:// URLs without an SDP description
+- single stream LATM/LOAS decoder
+- setpts filter added
+- Win64 support for optimized x86 assembly functions
+- MJPEG/AVI1 to JPEG/JFIF bitstream filter
+- ASS subtitle encoder and decoder
+- IEC 61937 encapsulation for E-AC-3, TrueHD, DTS-HD (for HDMI passthrough)
+- overlay filter added
+- rename aspect filter to setdar, and pixelaspect to setsar
+- IEC 61937 demuxer
+- Mobotix .mxg demuxer
+- frei0r source added
+- hqdn3d filter added
+- RTP depacketization of QCELP
+- FLAC parser added
+- gradfun filter added
+- AMR-WB decoder
+- replace the ocv_smooth filter with a more generic ocv filter
+- Windows Televison (WTV) demuxer
+- FFmpeg metadata format muxer and demuxer
+- SubRip (srt) subtitle encoder and decoder
+- floating-point AC-3 encoder added
+- Lagarith decoder
+- ffmpeg -copytb option added
+- IVF muxer added
+- Wing Commander IV movies decoder added
+- movie source added
+- Bink version 'b' audio and video decoder
+- Bitmap Brothers JV playback system
+- Apple HTTP Live Streaming protocol handler
+- sndio support for playback and record
+- Linux framebuffer input device added
+- Chronomaster DFA decoder
+- DPX image encoder
+- MicroDVD subtitle file muxer and demuxer
+- Playstation Portable PMP format demuxer
+- fieldorder video filter added
+- AAC encoding via libvo-aacenc
+- AMR-WB encoding via libvo-amrwbenc
+- xWMA demuxer
+- Mobotix MxPEG decoder
+- VP8 frame-multithreading
+- NEON optimizations for VP8
+- Lots of deprecated API cruft removed
+- fft and imdct optimizations for AVX (Sandy Bridge) processors
+- showinfo filter added
+- SMPTE 302M AES3 audio decoder
+- Apple Core Audio Format muxer
+- 9bit and 10bit per sample support in the H.264 decoder
+- 9bit and 10bit FFV1 encoding / decoding
+- split filter added
+- select filter added
+- sdl output device added
+- libmpcodecs video filter support (3 times as many filters than before)
+- mpeg2 aspect ratio dection fixed
+- libxvid aspect pickiness fixed
+- Frame multithreaded decoding
+- E-AC-3 audio encoder
+- ac3enc: add channel coupling support
+- floating-point sample format support to the ac3, eac3, dca, aac, and vorbis decoders.
+- H264/MPEG frame-level multi-threading
+- All av_metadata_* functions renamed to av_dict_* and moved to libavutil
+- 4:4:4 H.264 decoding support
+- 10-bit H.264 optimizations for x86
+- lut, lutrgb, and lutyuv filters added
+- buffersink libavfilter sink added
+- Bump libswscale for recently reported ABI break
+- New J2K encoder (via OpenJPEG)
+
+
+version 0.7:
+
+- all the changes for 0.8, but keeping API/ABI compatibility with the 0.6 release
+
+
+version 0.6:
+
+- PB-frame decoding for H.263
+- deprecated vhook subsystem removed
+- deprecated old scaler removed
+- VQF demuxer
+- Alpha channel scaler
+- PCX encoder
+- RTP packetization of H.263
+- RTP packetization of AMR
+- RTP depacketization of Vorbis
+- CorePNG decoding support
+- Cook multichannel decoding support
+- introduced avlanguage helpers in libavformat
+- 8088flex TMV demuxer and decoder
+- per-stream language-tags extraction in asfdec
+- V210 decoder and encoder
+- remaining GPL parts in AC-3 decoder converted to LGPL
+- QCP demuxer
+- SoX native format muxer and demuxer
+- AMR-NB decoding/encoding, AMR-WB decoding via OpenCORE libraries
+- DPX image decoder
+- Electronic Arts Madcow decoder
+- DivX (XSUB) subtitle encoder
+- nonfree libamr support for AMR-NB/WB decoding/encoding removed
+- experimental AAC encoder
+- RTP depacketization of ASF and RTSP from WMS servers
+- RTMP support in libavformat
+- noX handling for OPT_BOOL X options
+- Wave64 demuxer
+- IEC-61937 compatible Muxer
+- TwinVQ decoder
+- Bluray (PGS) subtitle decoder
+- LPCM support in MPEG-TS (HDMV RID as found on Blu-ray disks)
+- WMA Pro decoder
+- Core Audio Format demuxer
+- ATRAC1 decoder
+- MD STUDIO audio demuxer
+- RF64 support in WAV demuxer
+- MPEG-4 Audio Lossless Coding (ALS) decoder
+- -formats option split into -formats, -codecs, -bsfs, and -protocols
+- IV8 demuxer
+- CDG demuxer and decoder
+- R210 decoder
+- Auravision Aura 1 and 2 decoders
+- Deluxe Paint Animation playback system
+- SIPR decoder
+- Adobe Filmstrip muxer and demuxer
+- RTP depacketization of H.263
+- Bink demuxer and audio/video decoders
+- enable symbol versioning by default for linkers that support it
+- IFF PBM/ILBM bitmap decoder
+- concat protocol
+- Indeo 5 decoder
+- RTP depacketization of AMR
+- WMA Voice decoder
+- ffprobe tool
+- AMR-NB decoder
+- RTSP muxer
+- HE-AAC v1 decoder
+- Kega Game Video (KGV1) decoder
+- VorbisComment writing for FLAC, Ogg FLAC and Ogg Speex files
+- RTP depacketization of Theora
+- HTTP Digest authentication
+- RTMP/RTMPT/RTMPS/RTMPE/RTMPTE protocol support via librtmp
+- Psygnosis YOP demuxer and video decoder
+- spectral extension support in the E-AC-3 decoder
+- unsharp video filter
+- RTP hinting in the mov/3gp/mp4 muxer
+- Dirac in Ogg demuxing
+- seek to keyframes in Ogg
+- 4:2:2 and 4:4:4 Theora decoding
+- 35% faster VP3/Theora decoding
+- faster AAC decoding
+- faster H.264 decoding
+- RealAudio 1.0 (14.4K) encoder
+
+
+version 0.5:
+
+- DV50 AKA DVCPRO50 encoder, decoder, muxer and demuxer
+- TechSmith Camtasia (TSCC) video decoder
+- IBM Ultimotion (ULTI) video decoder
+- Sierra Online audio file demuxer and decoder
+- Apple QuickDraw (qdrw) video decoder
+- Creative ADPCM audio decoder (16 bits as well as 8 bits schemes)
+- Electronic Arts Multimedia (WVE/UV2/etc.) file demuxer
+- Miro VideoXL (VIXL) video decoder
+- H.261 video encoder
+- QPEG video decoder
+- Nullsoft Video (NSV) file demuxer
+- Shorten audio decoder
+- LOCO video decoder
+- Apple Lossless Audio Codec (ALAC) decoder
+- Winnov WNV1 video decoder
+- Autodesk Animator Studio Codec (AASC) decoder
+- Indeo 2 video decoder
+- Fraps FPS1 video decoder
+- Snow video encoder/decoder
+- Sonic audio encoder/decoder
+- Vorbis audio decoder
+- Macromedia ADPCM decoder
+- Duck TrueMotion 2 video decoder
+- support for decoding FLX and DTA extensions in FLIC files
+- H.264 custom quantization matrices support
+- ffserver fixed, it should now be usable again
+- QDM2 audio decoder
+- Real Cooker audio decoder
+- TrueSpeech audio decoder
+- WMA2 audio decoder fixed, now all files should play correctly
+- RealAudio 14.4 and 28.8 decoders fixed
+- JPEG-LS decoder
+- build system improvements
+- tabs and trailing whitespace removed from the codebase
+- CamStudio video decoder
+- AIFF/AIFF-C audio format, encoding and decoding
+- ADTS AAC file reading and writing
+- Creative VOC file reading and writing
+- American Laser Games multimedia (*.mm) playback system
+- Zip Motion Blocks Video decoder
+- improved Theora/VP3 decoder
+- True Audio (TTA) decoder
+- AVS demuxer and video decoder
+- JPEG-LS encoder
+- Smacker demuxer and decoder
+- NuppelVideo/MythTV demuxer and RTjpeg decoder
+- KMVC decoder
+- MPEG-2 intra VLC support
+- MPEG-2 4:2:2 encoder
+- Flash Screen Video decoder
+- GXF demuxer
+- Chinese AVS decoder
+- GXF muxer
+- MXF demuxer
+- VC-1/WMV3/WMV9 video decoder
+- MacIntel support
+- AviSynth support
+- VMware video decoder
+- VP5 video decoder
+- VP6 video decoder
+- WavPack lossless audio decoder
+- Targa (.TGA) picture decoder
+- Vorbis audio encoder
+- Delphine Software .cin demuxer/audio and video decoder
+- Tiertex .seq demuxer/video decoder
+- MTV demuxer
+- TIFF picture encoder and decoder
+- GIF picture decoder
+- Intel Music Coder decoder
+- Zip Motion Blocks Video encoder
+- Musepack decoder
+- Flash Screen Video encoder
+- Theora encoding via libtheora
+- BMP encoder
+- WMA encoder
+- GSM-MS encoder and decoder
+- DCA decoder
+- DXA demuxer and decoder
+- DNxHD decoder
+- Gamecube movie (.THP) playback system
+- Blackfin optimizations
+- Interplay C93 demuxer and video decoder
+- Bethsoft VID demuxer and video decoder
+- CRYO APC demuxer
+- ATRAC3 decoder
+- V.Flash PTX decoder
+- RoQ muxer, RoQ audio encoder
+- Renderware TXD demuxer and decoder
+- extern C declarations for C++ removed from headers
+- sws_flags command line option
+- codebook generator
+- RoQ video encoder
+- QTRLE encoder
+- OS/2 support removed and restored again
+- AC-3 decoder
+- NUT muxer
+- additional SPARC (VIS) optimizations
+- Matroska muxer
+- slice-based parallel H.264 decoding
+- Monkey's Audio demuxer and decoder
+- AMV audio and video decoder
+- DNxHD encoder
+- H.264 PAFF decoding
+- Nellymoser ASAO decoder
+- Beam Software SIFF demuxer and decoder
+- libvorbis Vorbis decoding removed in favor of native decoder
+- IntraX8 (J-Frame) subdecoder for WMV2 and VC-1
+- Ogg (Theora, Vorbis and FLAC) muxer
+- The "device" muxers and demuxers are now in a new libavdevice library
+- PC Paintbrush PCX decoder
+- Sun Rasterfile decoder
+- TechnoTrend PVA demuxer
+- Linux Media Labs MPEG-4 (LMLM4) demuxer
+- AVM2 (Flash 9) SWF muxer
+- QT variant of IMA ADPCM encoder
+- VFW grabber
+- iPod/iPhone compatible mp4 muxer
+- Mimic decoder
+- MSN TCP Webcam stream demuxer
+- RL2 demuxer / decoder
+- IFF demuxer
+- 8SVX audio decoder
+- non-recursive Makefiles
+- BFI demuxer
+- MAXIS EA XA (.xa) demuxer / decoder
+- BFI video decoder
+- OMA demuxer
+- MLP/TrueHD decoder
+- Electronic Arts CMV decoder
+- Motion Pixels Video decoder
+- Motion Pixels MVI demuxer
+- removed animated GIF decoder/demuxer
+- D-Cinema audio muxer
+- Electronic Arts TGV decoder
+- Apple Lossless Audio Codec (ALAC) encoder
+- AAC decoder
+- floating point PCM encoder/decoder
+- MXF muxer
+- DV100 AKA DVCPRO HD decoder and demuxer
+- E-AC-3 support added to AC-3 decoder
+- Nellymoser ASAO encoder
+- ASS and SSA demuxer and muxer
+- liba52 wrapper removed
+- SVQ3 watermark decoding support
+- Speex decoding via libspeex
+- Electronic Arts TGQ decoder
+- RV40 decoder
+- QCELP / PureVoice decoder
+- RV30 decoder
+- hybrid WavPack support
+- R3D REDCODE demuxer
+- ALSA support for playback and record
+- Electronic Arts TQI decoder
+- OpenJPEG based JPEG 2000 decoder
+- NC (NC4600) camera file demuxer
+- Gopher client support
+- MXF D-10 muxer
+- generic metadata API
+- flash ScreenVideo2 encoder
+
+
+version 0.4.9-pre1:
+
+- DV encoder, DV muxer
+- Microsoft RLE video decoder
+- Microsoft Video-1 decoder
+- Apple Animation (RLE) decoder
+- Apple Graphics (SMC) decoder
+- Apple Video (RPZA) decoder
+- Cinepak decoder
+- Sega FILM (CPK) file demuxer
+- Westwood multimedia support (VQA & AUD files)
+- Id Quake II CIN playback support
+- 8BPS video decoder
+- FLIC playback support
+- RealVideo 2.0 (RV20) decoder
+- Duck TrueMotion v1 (DUCK) video decoder
+- Sierra VMD demuxer and video decoder
+- MSZH and ZLIB decoder support
+- SVQ1 video encoder
+- AMR-WB support
+- PPC optimizations
+- rate distortion optimal cbp support
+- rate distorted optimal ac prediction for MPEG-4
+- rate distorted optimal lambda->qp support
+- AAC encoding with libfaac
+- Sunplus JPEG codec (SP5X) support
+- use Lagrange multipler instead of QP for ratecontrol
+- Theora/VP3 decoding support
+- XA and ADX ADPCM codecs
+- export MPEG-2 active display area / pan scan
+- Add support for configuring with IBM XLC
+- floating point AAN DCT
+- initial support for zygo video (not complete)
+- RGB ffv1 support
+- new audio/video parser API
+- av_log() system
+- av_read_frame() and av_seek_frame() support
+- missing last frame fixes
+- seek by mouse in ffplay
+- noise reduction of DCT coefficients
+- H.263 OBMC & 4MV support
+- H.263 alternative inter vlc support
+- H.263 loop filter
+- H.263 slice structured mode
+- interlaced DCT support for MPEG-2 encoding
+- stuffing to stay above min_bitrate
+- MB type & QP visualization
+- frame stepping for ffplay
+- interlaced motion estimation
+- alternate scantable support
+- SVCD scan offset support
+- closed GOP support
+- SSE2 FDCT
+- quantizer noise shaping
+- G.726 ADPCM audio codec
+- MS ADPCM encoding
+- multithreaded/SMP motion estimation
+- multithreaded/SMP encoding for MPEG-1/MPEG-2/MPEG-4/H.263
+- multithreaded/SMP decoding for MPEG-2
+- FLAC decoder
+- Metrowerks CodeWarrior suppport
+- H.263+ custom pcf support
+- nicer output for 'ffmpeg -formats'
+- Matroska demuxer
+- SGI image format, encoding and decoding
+- H.264 loop filter support
+- H.264 CABAC support
+- nicer looking arrows for the motion vector visualization
+- improved VCD support
+- audio timestamp drift compensation
+- MPEG-2 YUV 422/444 support
+- polyphase kaiser windowed sinc and blackman nuttall windowed sinc audio resample
+- better image scaling
+- H.261 support
+- correctly interleave packets during encoding
+- VIS optimized motion compensation
+- intra_dc_precision>0 encoding support
+- support reuse of motion vectors/MB types/field select values of the source video
+- more accurate deblock filter
+- padding support
+- many optimizations and bugfixes
+- FunCom ISS audio file demuxer and according ADPCM decoding
+
+
+version 0.4.8:
+
+- MPEG-2 video encoding (Michael)
+- Id RoQ playback subsystem (Mike Melanson and Tim Ferguson)
+- Wing Commander III Movie (.mve) file playback subsystem (Mike Melanson
+ and Mario Brito)
+- Xan DPCM audio decoder (Mario Brito)
+- Interplay MVE playback subsystem (Mike Melanson)
+- Duck DK3 and DK4 ADPCM audio decoders (Mike Melanson)
+
+
+version 0.4.7:
+
+- RealAudio 1.0 (14_4) and 2.0 (28_8) native decoders. Author unknown, code from mplayerhq
+ (originally from public domain player for Amiga at http://www.honeypot.net/audio)
+- current version now also compiles with older GCC (Fabrice)
+- 4X multimedia playback system including 4xm file demuxer (Mike
+ Melanson), and 4X video and audio codecs (Michael)
+- Creative YUV (CYUV) decoder (Mike Melanson)
+- FFV1 codec (our very simple lossless intra only codec, compresses much better
+ than HuffYUV) (Michael)
+- ASV1 (Asus), H.264, Intel indeo3 codecs have been added (various)
+- tiny PNG encoder and decoder, tiny GIF decoder, PAM decoder (PPM with
+ alpha support), JPEG YUV colorspace support. (Fabrice Bellard)
+- ffplay has been replaced with a newer version which uses SDL (optionally)
+ for multiplatform support (Fabrice)
+- Sorenson Version 3 codec (SVQ3) support has been added (decoding only) - donated
+ by anonymous
+- AMR format has been added (Johannes Carlsson)
+- 3GP support has been added (Johannes Carlsson)
+- VP3 codec has been added (Mike Melanson)
+- more MPEG-1/2 fixes
+- better multiplatform support, MS Visual Studio fixes (various)
+- AltiVec optimizations (Magnus Damn and others)
+- SH4 processor support has been added (BERO)
+- new public interfaces (avcodec_get_pix_fmt) (Roman Shaposhnick)
+- VOB streaming support (Brian Foley)
+- better MP3 autodetection (Andriy Rysin)
+- qpel encoding (Michael)
+- 4mv+b frames encoding finally fixed (Michael)
+- chroma ME (Michael)
+- 5 comparison functions for ME (Michael)
+- B-frame encoding speedup (Michael)
+- WMV2 codec (unfinished - Michael)
+- user specified diamond size for EPZS (Michael)
+- Playstation STR playback subsystem, still experimental (Mike and Michael)
+- ASV2 codec (Michael)
+- CLJR decoder (Alex)
+
+.. And lots more new enhancements and fixes.
+
+
+version 0.4.6:
+
+- completely new integer only MPEG audio layer 1/2/3 decoder rewritten
+ from scratch
+- Recoded DCT and motion vector search with gcc (no longer depends on nasm)
+- fix quantization bug in AC3 encoder
+- added PCM codecs and format. Corrected WAV/AVI/ASF PCM issues
+- added prototype ffplay program
+- added GOB header parsing on H.263/H.263+ decoder (Juanjo)
+- bug fix on MCBPC tables of H.263 (Juanjo)
+- bug fix on DC coefficients of H.263 (Juanjo)
+- added Advanced Prediction Mode on H.263/H.263+ decoder (Juanjo)
+- now we can decode H.263 streams found in QuickTime files (Juanjo)
+- now we can decode H.263 streams found in VIVO v1 files(Juanjo)
+- preliminary RTP "friendly" mode for H.263/H.263+ coding. (Juanjo)
+- added GOB header for H.263/H.263+ coding on RTP mode (Juanjo)
+- now H.263 picture size is returned on the first decoded frame (Juanjo)
+- added first regression tests
+- added MPEG-2 TS demuxer
+- new demux API for libav
+- more accurate and faster IDCT (Michael)
+- faster and entropy-controlled motion search (Michael)
+- two pass video encoding (Michael)
+- new video rate control (Michael)
+- added MSMPEG4V1, MSMPEGV2 and WMV1 support (Michael)
+- great performance improvement of video encoders and decoders (Michael)
+- new and faster bit readers and vlc parsers (Michael)
+- high quality encoding mode: tries all macroblock/VLC types (Michael)
+- added DV video decoder
+- preliminary RTP/RTSP support in ffserver and libavformat
+- H.263+ AIC decoding/encoding support (Juanjo)
+- VCD MPEG-PS mode (Juanjo)
+- PSNR stuff (Juanjo)
+- simple stats output (Juanjo)
+- 16-bit and 15-bit RGB/BGR/GBR support (Bisqwit)
+
+
+version 0.4.5:
+
+- some header fixes (Zdenek Kabelac <kabi at informatics.muni.cz>)
+- many MMX optimizations (Nick Kurshev <nickols_k at mail.ru>)
+- added configure system (actually a small shell script)
+- added MPEG audio layer 1/2/3 decoding using LGPL'ed mpglib by
+ Michael Hipp (temporary solution - waiting for integer only
+ decoder)
+- fixed VIDIOCSYNC interrupt
+- added Intel H.263 decoding support ('I263' AVI fourCC)
+- added Real Video 1.0 decoding (needs further testing)
+- simplified image formats again. Added PGM format (=grey
+ pgm). Renamed old PGM to PGMYUV.
+- fixed msmpeg4 slice issues (tell me if you still find problems)
+- fixed OpenDivX bugs with newer versions (added VOL header decoding)
+- added support for MPlayer interface
+- added macroblock skip optimization
+- added MJPEG decoder
+- added mmx/mmxext IDCT from libmpeg2
+- added pgmyuvpipe, ppm, and ppm_pipe formats (original patch by Celer
+ <celer at shell.scrypt.net>)
+- added pixel format conversion layer (e.g. for MJPEG or PPM)
+- added deinterlacing option
+- MPEG-1/2 fixes
+- MPEG-4 vol header fixes (Jonathan Marsden <snmjbm at pacbell.net>)
+- ARM optimizations (Lionel Ulmer <lionel.ulmer at free.fr>).
+- Windows porting of file converter
+- added MJPEG raw format (input/output)
+- added JPEG image format support (input/output)
+
+
+version 0.4.4:
+
+- fixed some std header definitions (Bjorn Lindgren
+ <bjorn.e.lindgren at telia.com>).
+- added MPEG demuxer (MPEG-1 and 2 compatible).
+- added ASF demuxer
+- added prototype RM demuxer
+- added AC3 decoding (done with libac3 by Aaron Holtzman)
+- added decoding codec parameter guessing (.e.g. for MPEG, because the
+ header does not include them)
+- fixed header generation in MPEG-1, AVI and ASF muxer: wmplayer can now
+ play them (only tested video)
+- fixed H.263 white bug
+- fixed phase rounding in img resample filter
+- add MMX code for polyphase img resample filter
+- added CPU autodetection
+- added generic title/author/copyright/comment string handling (ASF and RM
+ use them)
+- added SWF demux to extract MP3 track (not usable yet because no MP3
+ decoder)
+- added fractional frame rate support
+- codecs are no longer searched by read_header() (should fix ffserver
+ segfault)
+
+
+version 0.4.3:
+
+- BGR24 patch (initial patch by Jeroen Vreeken <pe1rxq at amsat.org>)
+- fixed raw yuv output
+- added motion rounding support in MPEG-4
+- fixed motion bug rounding in MSMPEG4
+- added B-frame handling in video core
+- added full MPEG-1 decoding support
+- added partial (frame only) MPEG-2 support
+- changed the FOURCC code for H.263 to "U263" to be able to see the
+ +AVI/H.263 file with the UB Video H.263+ decoder. MPlayer works with
+ this +codec ;) (JuanJo).
+- Halfpel motion estimation after MB type selection (JuanJo)
+- added pgm and .Y.U.V output format
+- suppressed 'img:' protocol. Simply use: /tmp/test%d.[pgm|Y] as input or
+ output.
+- added pgmpipe I/O format (original patch from Martin Aumueller
+ <lists at reserv.at>, but changed completely since we use a format
+ instead of a protocol)
+
+
+version 0.4.2:
+
+- added H.263/MPEG-4/MSMPEG4 decoding support. MPEG-4 decoding support
+ (for OpenDivX) is almost complete: 8x8 MVs and rounding are
+ missing. MSMPEG4 support is complete.
+- added prototype MPEG-1 decoder. Only I- and P-frames handled yet (it
+ can decode ffmpeg MPEGs :-)).
+- added libavcodec API documentation (see apiexample.c).
+- fixed image polyphase bug (the bottom of some images could be
+ greenish)
+- added support for non clipped motion vectors (decoding only)
+ and image sizes non-multiple of 16
+- added support for AC prediction (decoding only)
+- added file overwrite confirmation (can be disabled with -y)
+- added custom size picture to H.263 using H.263+ (Juanjo)
+
+
+version 0.4.1:
+
+- added MSMPEG4 (aka DivX) compatible encoder. Changed default codec
+ of AVI and ASF to DIV3.
+- added -me option to set motion estimation method
+ (default=log). suppressed redundant -hq option.
+- added options -acodec and -vcodec to force a given codec (useful for
+ AVI for example)
+- fixed -an option
+- improved dct_quantize speed
+- factorized some motion estimation code
+
+
+version 0.4.0:
+
+- removing grab code from ffserver and moved it to ffmpeg. Added
+ multistream support to ffmpeg.
+- added timeshifting support for live feeds (option ?date=xxx in the
+ URL)
+- added high quality image resize code with polyphase filter (need
+ mmx/see optimization). Enable multiple image size support in ffserver.
+- added multi live feed support in ffserver
+- suppressed master feature from ffserver (it should be done with an
+ external program which opens the .ffm url and writes it to another
+ ffserver)
+- added preliminary support for video stream parsing (WAV and AVI half
+ done). Added proper support for audio/video file conversion in
+ ffmpeg.
+- added preliminary support for video file sending from ffserver
+- redesigning I/O subsystem: now using URL based input and output
+ (see avio.h)
+- added WAV format support
+- added "tty user interface" to ffmpeg to stop grabbing gracefully
+- added MMX/SSE optimizations to SAD (Sums of Absolutes Differences)
+ (Juan J. Sierralta P. a.k.a. "Juanjo" <juanjo at atmlab.utfsm.cl>)
+- added MMX DCT from mpeg2_movie 1.5 (Juanjo)
+- added new motion estimation algorithms, log and phods (Juanjo)
+- changed directories: libav for format handling, libavcodec for
+ codecs
+
+
+version 0.3.4:
+
+- added stereo in MPEG audio encoder
+
+
+version 0.3.3:
+
+- added 'high quality' mode which use motion vectors. It can be used in
+ real time at low resolution.
+- fixed rounding problems which caused quality problems at high
+ bitrates and large GOP size
+
+
+version 0.3.2: small fixes
+
+- ASF fixes
+- put_seek bug fix
+
+
+version 0.3.1: added avi/divx support
+
+- added AVI support
+- added MPEG-4 codec compatible with OpenDivX. It is based on the H.263 codec
+- added sound for flash format (not tested)
+
+
+version 0.3: initial public release
diff --git a/ffmpeg-2-8-11/INSTALL.md b/ffmpeg-2-8-12/INSTALL.md
similarity index 100%
rename from ffmpeg-2-8-11/INSTALL.md
rename to ffmpeg-2-8-12/INSTALL.md
diff --git a/ffmpeg-2-8-11/LICENSE.md b/ffmpeg-2-8-12/LICENSE.md
similarity index 100%
rename from ffmpeg-2-8-11/LICENSE.md
rename to ffmpeg-2-8-12/LICENSE.md
diff --git a/ffmpeg-2-8-11/MAINTAINERS b/ffmpeg-2-8-12/MAINTAINERS
similarity index 100%
rename from ffmpeg-2-8-11/MAINTAINERS
rename to ffmpeg-2-8-12/MAINTAINERS
diff --git a/ffmpeg-2-8-11/Makefile b/ffmpeg-2-8-12/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/Makefile
rename to ffmpeg-2-8-12/Makefile
diff --git a/ffmpeg-2-8-11/README.md b/ffmpeg-2-8-12/README.md
similarity index 100%
rename from ffmpeg-2-8-11/README.md
rename to ffmpeg-2-8-12/README.md
diff --git a/ffmpeg-2-8-12/RELEASE b/ffmpeg-2-8-12/RELEASE
new file mode 100644
index 0000000..56f5e1b
--- /dev/null
+++ b/ffmpeg-2-8-12/RELEASE
@@ -0,0 +1 @@
+2.8.12
diff --git a/ffmpeg-2-8-11/RELEASE_NOTES b/ffmpeg-2-8-12/RELEASE_NOTES
similarity index 100%
rename from ffmpeg-2-8-11/RELEASE_NOTES
rename to ffmpeg-2-8-12/RELEASE_NOTES
diff --git a/ffmpeg-2-8-12/VERSION b/ffmpeg-2-8-12/VERSION
new file mode 100644
index 0000000..56f5e1b
--- /dev/null
+++ b/ffmpeg-2-8-12/VERSION
@@ -0,0 +1 @@
+2.8.12
diff --git a/ffmpeg-2-8-11/arch.mak b/ffmpeg-2-8-12/arch.mak
similarity index 100%
rename from ffmpeg-2-8-11/arch.mak
rename to ffmpeg-2-8-12/arch.mak
diff --git a/ffmpeg-2-8-11/cmdutils.c b/ffmpeg-2-8-12/cmdutils.c
similarity index 100%
rename from ffmpeg-2-8-11/cmdutils.c
rename to ffmpeg-2-8-12/cmdutils.c
diff --git a/ffmpeg-2-8-11/cmdutils.h b/ffmpeg-2-8-12/cmdutils.h
similarity index 100%
rename from ffmpeg-2-8-11/cmdutils.h
rename to ffmpeg-2-8-12/cmdutils.h
diff --git a/ffmpeg-2-8-11/cmdutils_common_opts.h b/ffmpeg-2-8-12/cmdutils_common_opts.h
similarity index 100%
rename from ffmpeg-2-8-11/cmdutils_common_opts.h
rename to ffmpeg-2-8-12/cmdutils_common_opts.h
diff --git a/ffmpeg-2-8-11/cmdutils_opencl.c b/ffmpeg-2-8-12/cmdutils_opencl.c
similarity index 100%
rename from ffmpeg-2-8-11/cmdutils_opencl.c
rename to ffmpeg-2-8-12/cmdutils_opencl.c
diff --git a/ffmpeg-2-8-11/common.mak b/ffmpeg-2-8-12/common.mak
similarity index 100%
rename from ffmpeg-2-8-11/common.mak
rename to ffmpeg-2-8-12/common.mak
diff --git a/ffmpeg-2-8-11/compat/aix/math.h b/ffmpeg-2-8-12/compat/aix/math.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/aix/math.h
rename to ffmpeg-2-8-12/compat/aix/math.h
diff --git a/ffmpeg-2-8-11/compat/avisynth/avisynth_c.h b/ffmpeg-2-8-12/compat/avisynth/avisynth_c.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/avisynth/avisynth_c.h
rename to ffmpeg-2-8-12/compat/avisynth/avisynth_c.h
diff --git a/ffmpeg-2-8-11/compat/avisynth/avs/capi.h b/ffmpeg-2-8-12/compat/avisynth/avs/capi.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/avisynth/avs/capi.h
rename to ffmpeg-2-8-12/compat/avisynth/avs/capi.h
diff --git a/ffmpeg-2-8-11/compat/avisynth/avs/config.h b/ffmpeg-2-8-12/compat/avisynth/avs/config.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/avisynth/avs/config.h
rename to ffmpeg-2-8-12/compat/avisynth/avs/config.h
diff --git a/ffmpeg-2-8-11/compat/avisynth/avs/types.h b/ffmpeg-2-8-12/compat/avisynth/avs/types.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/avisynth/avs/types.h
rename to ffmpeg-2-8-12/compat/avisynth/avs/types.h
diff --git a/ffmpeg-2-8-11/compat/avisynth/avxsynth_c.h b/ffmpeg-2-8-12/compat/avisynth/avxsynth_c.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/avisynth/avxsynth_c.h
rename to ffmpeg-2-8-12/compat/avisynth/avxsynth_c.h
diff --git a/ffmpeg-2-8-11/compat/avisynth/windowsPorts/basicDataTypeConversions.h b/ffmpeg-2-8-12/compat/avisynth/windowsPorts/basicDataTypeConversions.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/avisynth/windowsPorts/basicDataTypeConversions.h
rename to ffmpeg-2-8-12/compat/avisynth/windowsPorts/basicDataTypeConversions.h
diff --git a/ffmpeg-2-8-11/compat/avisynth/windowsPorts/windows2linux.h b/ffmpeg-2-8-12/compat/avisynth/windowsPorts/windows2linux.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/avisynth/windowsPorts/windows2linux.h
rename to ffmpeg-2-8-12/compat/avisynth/windowsPorts/windows2linux.h
diff --git a/ffmpeg-2-8-11/compat/float/float.h b/ffmpeg-2-8-12/compat/float/float.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/float/float.h
rename to ffmpeg-2-8-12/compat/float/float.h
diff --git a/ffmpeg-2-8-11/compat/float/limits.h b/ffmpeg-2-8-12/compat/float/limits.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/float/limits.h
rename to ffmpeg-2-8-12/compat/float/limits.h
diff --git a/ffmpeg-2-8-11/compat/getopt.c b/ffmpeg-2-8-12/compat/getopt.c
similarity index 100%
rename from ffmpeg-2-8-11/compat/getopt.c
rename to ffmpeg-2-8-12/compat/getopt.c
diff --git a/ffmpeg-2-8-11/compat/msvcrt/snprintf.c b/ffmpeg-2-8-12/compat/msvcrt/snprintf.c
similarity index 100%
rename from ffmpeg-2-8-11/compat/msvcrt/snprintf.c
rename to ffmpeg-2-8-12/compat/msvcrt/snprintf.c
diff --git a/ffmpeg-2-8-11/compat/msvcrt/snprintf.h b/ffmpeg-2-8-12/compat/msvcrt/snprintf.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/msvcrt/snprintf.h
rename to ffmpeg-2-8-12/compat/msvcrt/snprintf.h
diff --git a/ffmpeg-2-8-11/compat/os2threads.h b/ffmpeg-2-8-12/compat/os2threads.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/os2threads.h
rename to ffmpeg-2-8-12/compat/os2threads.h
diff --git a/ffmpeg-2-8-11/compat/plan9/head b/ffmpeg-2-8-12/compat/plan9/head
similarity index 100%
rename from ffmpeg-2-8-11/compat/plan9/head
rename to ffmpeg-2-8-12/compat/plan9/head
diff --git a/ffmpeg-2-8-11/compat/plan9/main.c b/ffmpeg-2-8-12/compat/plan9/main.c
similarity index 100%
rename from ffmpeg-2-8-11/compat/plan9/main.c
rename to ffmpeg-2-8-12/compat/plan9/main.c
diff --git a/ffmpeg-2-8-11/compat/plan9/printf b/ffmpeg-2-8-12/compat/plan9/printf
similarity index 100%
rename from ffmpeg-2-8-11/compat/plan9/printf
rename to ffmpeg-2-8-12/compat/plan9/printf
diff --git a/ffmpeg-2-8-11/compat/strtod.c b/ffmpeg-2-8-12/compat/strtod.c
similarity index 100%
rename from ffmpeg-2-8-11/compat/strtod.c
rename to ffmpeg-2-8-12/compat/strtod.c
diff --git a/ffmpeg-2-8-11/compat/tms470/math.h b/ffmpeg-2-8-12/compat/tms470/math.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/tms470/math.h
rename to ffmpeg-2-8-12/compat/tms470/math.h
diff --git a/ffmpeg-2-8-11/compat/va_copy.h b/ffmpeg-2-8-12/compat/va_copy.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/va_copy.h
rename to ffmpeg-2-8-12/compat/va_copy.h
diff --git a/ffmpeg-2-8-11/compat/w32pthreads.h b/ffmpeg-2-8-12/compat/w32pthreads.h
similarity index 100%
rename from ffmpeg-2-8-11/compat/w32pthreads.h
rename to ffmpeg-2-8-12/compat/w32pthreads.h
diff --git a/ffmpeg-2-8-11/compat/windows/makedef b/ffmpeg-2-8-12/compat/windows/makedef
similarity index 100%
rename from ffmpeg-2-8-11/compat/windows/makedef
rename to ffmpeg-2-8-12/compat/windows/makedef
diff --git a/ffmpeg-2-8-11/compat/windows/mslink b/ffmpeg-2-8-12/compat/windows/mslink
similarity index 100%
rename from ffmpeg-2-8-11/compat/windows/mslink
rename to ffmpeg-2-8-12/compat/windows/mslink
diff --git a/ffmpeg-2-8-11/configure b/ffmpeg-2-8-12/configure
similarity index 100%
rename from ffmpeg-2-8-11/configure
rename to ffmpeg-2-8-12/configure
diff --git a/ffmpeg-2-8-11/doc/APIchanges b/ffmpeg-2-8-12/doc/APIchanges
similarity index 100%
rename from ffmpeg-2-8-11/doc/APIchanges
rename to ffmpeg-2-8-12/doc/APIchanges
diff --git a/ffmpeg-2-8-12/doc/Doxyfile b/ffmpeg-2-8-12/doc/Doxyfile
new file mode 100644
index 0000000..91f1211
--- /dev/null
+++ b/ffmpeg-2-8-12/doc/Doxyfile
@@ -0,0 +1,1626 @@
+# Doxyfile 1.7.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the
+# iconv built into libc) for the transcoding. See
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = FFmpeg
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER = 2.8.12
+
+# With the PROJECT_LOGO tag one can specify a logo or icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will
+# copy the logo to the output directory.
+PROJECT_LOGO =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY = doc/doxy
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,
+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English
+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,
+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak,
+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH = .
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for
+# Java. For instance, namespaces will be presented as packages, qualified
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources only. Doxygen will then generate output that is more tailored for
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given extension.
+# Doxygen has a built-in mapping, but you can override or extend it using this
+# tag. The format is ext=language, where ext is a file extension, and language
+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,
+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make
+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C
+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions
+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.
+
+EXTENSION_MAPPING =
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate getter
+# and setter methods for a property. Setting this option to YES (the default)
+# will make doxygen to replace the get and set methods by a property in the
+# documentation. This will only work if the methods are indeed getting or
+# setting a simple type. If this is not the case, or you want to show the
+# methods anyway, you should set this option to NO.
+
+IDL_PROPERTY_SUPPORT = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum
+# is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT = YES
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penality.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will roughly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base
+# name of the file that contains the anonymous namespace. By default
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = YES
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen
+# will list include files with double quotes in the documentation
+# rather than with sharp brackets.
+
+FORCE_LOCAL_INCLUDES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen
+# will sort the (brief and detailed) documentation of class members so that
+# constructors and destructors are listed first. If set to NO (the default)
+# the constructors will appear in the respective orders defined by
+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.
+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO
+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the
+# hierarchy of group names into alphabetical order. If set to NO (the default)
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
+# This will remove the Files entry from the Quick Index and from the
+# Folder Tree View (if specified). The default is YES.
+
+SHOW_FILES = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the
+# Namespaces page.
+# This will remove the Namespaces entry from the Quick Index
+# and from the Folder Tree View (if specified). The default is YES.
+
+SHOW_NAMESPACES = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. The create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option.
+# You can optionally specify a file name after the option, if omitted
+# DoxygenLayout.xml will be used as the name of the layout file.
+
+LAYOUT_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = YES
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT =
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
+# also the default input encoding. Doxygen uses libiconv (or the iconv built
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for
+# the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = YES
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS = *.git \
+ *.d
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH = doc/examples/
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS = *.c
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output.
+# If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis.
+# Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match.
+# The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.
+# Otherwise they will link to the documentation.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.
+# Doxygen will adjust the colors in the stylesheet and background images
+# according to this color. Hue is specified as an angle on a colorwheel,
+# see http://en.wikipedia.org/wiki/Hue for more information.
+# For instance the value 0 represents red, 60 is yellow, 120 is green,
+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.
+# The allowed range is 0 to 359.
+
+#HTML_COLORSTYLE_HUE = 120
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of
+# the colors in the HTML output. For a value of 0 the output will use
+# grayscales only. A value of 255 will produce the most vivid colors.
+
+HTML_COLORSTYLE_SAT = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to
+# the luminance component of the colors in the HTML output. Values below
+# 100 gradually make the output lighter, whereas values above 100 make
+# the output darker. The value divided by 100 is the actual gamma applied,
+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,
+# and 100 does not change the gamma.
+
+HTML_COLORSTYLE_GAMMA = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting
+# this to NO can help when comparing the output of multiple runs.
+
+HTML_TIMESTAMP = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files
+# will be generated that can be used as input for Apple's Xcode 3
+# integrated development environment, introduced with OS X 10.5 (Leopard).
+# To create a documentation set, doxygen will generate a Makefile in the
+# HTML output directory. Running make will produce the docset in that
+# directory and running "make install" will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find
+# it at startup.
+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+
+GENERATE_DOCSET = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the
+# feed. A documentation feed provides an umbrella under which multiple
+# documentation sets from a single provider (such as a company or product suite)
+# can be grouped.
+
+DOCSET_FEEDNAME = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that
+# should uniquely identify the documentation set bundle. This should be a
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID = org.doxygen.Project
+
+# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+
+DOCSET_PUBLISHER_ID = org.doxygen.Publisher
+
+# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.
+
+DOCSET_PUBLISHER_NAME = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING
+# is used to encode HtmlHelp index (hhk), content (hhc) and project file
+# content.
+
+CHM_INDEX_ENCODING =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated
+# that can be used as input for Qt's qhelpgenerator to generate a
+# Qt Compressed Help (.qch) of the generated HTML documentation.
+
+GENERATE_QHP = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can
+# be used to specify the file name of the resulting .qch file.
+# The path specified is relative to the HTML output folder.
+
+QCH_FILE =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#namespace
+
+QHP_NAMESPACE = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating
+# Qt Help Project output. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#virtual-folders
+
+QHP_VIRTUAL_FOLDER = doc
+
+# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to
+# add. For more information please see
+# http://doc.trolltech.com/qthelpproject.html#custom-filters
+
+QHP_CUST_FILTER_NAME =
+
+# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+QHP_SECT_FILTER_ATTRS =
+
+# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can
+# be used to specify the location of Qt's qhelpgenerator.
+# If non-empty doxygen will try to run qhelpgenerator on the generated
+# .qhp file.
+
+QHG_LOCATION =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files
+# will be generated, which together with the HTML files, form an Eclipse help
+# plugin. To install this plugin and make it available under the help contents
+# menu in Eclipse, the contents of the directory containing the HTML and XML
+# files needs to be copied into the plugins directory of eclipse. The name of
+# the directory within the plugins directory should be the same as
+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before
+# the help appears.
+
+GENERATE_ECLIPSEHELP = NO
+
+# A unique identifier for the eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have
+# this name.
+
+ECLIPSE_DOC_ID = org.doxygen.Project
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information.
+# If the tag value is set to YES, a side panel will be generated
+# containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open
+# links to external symbols imported via tag files in a separate window.
+
+EXT_LINKS_IN_WINDOW = NO
+
+# Use this tag to change the font size of Latex formulas included
+# as images in the HTML documentation. The default is 10. Note that
+# when you change the font size after a successful doxygen run you need
+# to manually remove any form_*.png images from the HTML output directory
+# to force them to be regenerated.
+
+FORMULA_FONTSIZE = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are
+# not supported properly for IE 6.0, but are supported on all modern browsers.
+# Note that when changing this option you need to delete any form_*.png files
+# in the HTML output before the changes have effect.
+
+FORMULA_TRANSPARENT = YES
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box
+# for the HTML output. The underlying search engine uses javascript
+# and DHTML and should work on any modern browser. Note that when using
+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets
+# (GENERATE_DOCSET) there is already a search function so this one should
+# typically be disabled. For large projects the javascript based search engine
+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.
+
+SEARCHENGINE = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a PHP enabled web server instead of at the web client
+# using Javascript. Doxygen will generate the search PHP script and index
+# file to put on the web server. The advantage of the server
+# based approach is that it scales better to large projects and allows
+# full text search. The disadvances is that it is more difficult to setup
+# and does not have live searching capabilities.
+
+SERVER_BASED_SEARCH = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+# Note that when enabling USE_PDFLATEX this option is only used for
+# generating bitmaps for formulas in the HTML output, but not in the
+# Makefile that is written to the output directory.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+# If LATEX_SOURCE_CODE is set to YES then doxygen will include
+# source code with syntax highlighting in the LaTeX output.
+# Note that which sources are shown also depends on other settings
+# such as SOURCE_BROWSER.
+
+LATEX_SOURCE_CODE = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader.
+# This is useful
+# if you want to understand what is going on.
+# On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED = "__attribute__(x)=" \
+ "DECLARE_ALIGNED(a,t,n)=t n" \
+ "offsetof(x,y)=0x42" \
+ av_alloc_size \
+ AV_GCC_VERSION_AT_LEAST(x,y)=1 \
+ __GNUC__=1 \
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED = declare_idct \
+ READ_PAR_DATA \
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+#
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+#
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE =
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is
+# allowed to run in parallel. When set to 0 (the default) doxygen will
+# base this on the number of processors available in the system. You can set it
+# explicitly to a value larger than 0 to get control over the balance
+# between CPU load and processing speed.
+
+DOT_NUM_THREADS = 0
+
+# By default doxygen will write a font called FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need need to make sure dot is able to find the font,
+# which can be done by putting it in a standard location or by setting the
+# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
+# containing the font.
+
+DOT_FONTNAME = FreeSans
+
+# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.
+# The default size is 10pt.
+
+DOT_FONTSIZE = 10
+
+# By default doxygen will tell dot to use the output directory to look for the
+# FreeSans.ttf font (which doxygen will put there itself). If you specify a
+# different font using DOT_FONTNAME you can set the path where dot
+# can find it using this tag.
+
+DOT_FONTPATH =
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then
+# doxygen will generate a call dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable call graphs
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then
+# doxygen will generate a caller dependency graph for every global function
+# or class method. Note that enabling this option will significantly increase
+# the time of a run. So in most cases it will be better to enable caller
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the
+# number of direct children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not
+# seem to support this out of the box. Warning: Depending on the platform used,
+# enabling this option may lead to badly anti-aliased labels on the edges of
+# a graph (i.e. they become hard to read).
+
+DOT_TRANSPARENT = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
diff --git a/ffmpeg-2-8-11/doc/Makefile b/ffmpeg-2-8-12/doc/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/doc/Makefile
rename to ffmpeg-2-8-12/doc/Makefile
diff --git a/ffmpeg-2-8-11/doc/authors.texi b/ffmpeg-2-8-12/doc/authors.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/authors.texi
rename to ffmpeg-2-8-12/doc/authors.texi
diff --git a/ffmpeg-2-8-11/doc/bitstream_filters.texi b/ffmpeg-2-8-12/doc/bitstream_filters.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/bitstream_filters.texi
rename to ffmpeg-2-8-12/doc/bitstream_filters.texi
diff --git a/ffmpeg-2-8-11/doc/bootstrap.min.css b/ffmpeg-2-8-12/doc/bootstrap.min.css
similarity index 100%
rename from ffmpeg-2-8-11/doc/bootstrap.min.css
rename to ffmpeg-2-8-12/doc/bootstrap.min.css
diff --git a/ffmpeg-2-8-11/doc/build_system.txt b/ffmpeg-2-8-12/doc/build_system.txt
similarity index 100%
rename from ffmpeg-2-8-11/doc/build_system.txt
rename to ffmpeg-2-8-12/doc/build_system.txt
diff --git a/ffmpeg-2-8-11/doc/codecs.texi b/ffmpeg-2-8-12/doc/codecs.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/codecs.texi
rename to ffmpeg-2-8-12/doc/codecs.texi
diff --git a/ffmpeg-2-8-11/doc/decoders.texi b/ffmpeg-2-8-12/doc/decoders.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/decoders.texi
rename to ffmpeg-2-8-12/doc/decoders.texi
diff --git a/ffmpeg-2-8-11/doc/default.css b/ffmpeg-2-8-12/doc/default.css
similarity index 100%
rename from ffmpeg-2-8-11/doc/default.css
rename to ffmpeg-2-8-12/doc/default.css
diff --git a/ffmpeg-2-8-11/doc/demuxers.texi b/ffmpeg-2-8-12/doc/demuxers.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/demuxers.texi
rename to ffmpeg-2-8-12/doc/demuxers.texi
diff --git a/ffmpeg-2-8-11/doc/developer.texi b/ffmpeg-2-8-12/doc/developer.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/developer.texi
rename to ffmpeg-2-8-12/doc/developer.texi
diff --git a/ffmpeg-2-8-11/doc/devices.texi b/ffmpeg-2-8-12/doc/devices.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/devices.texi
rename to ffmpeg-2-8-12/doc/devices.texi
diff --git a/ffmpeg-2-8-11/doc/doxy-wrapper.sh b/ffmpeg-2-8-12/doc/doxy-wrapper.sh
similarity index 100%
rename from ffmpeg-2-8-11/doc/doxy-wrapper.sh
rename to ffmpeg-2-8-12/doc/doxy-wrapper.sh
diff --git a/ffmpeg-2-8-11/doc/encoders.texi b/ffmpeg-2-8-12/doc/encoders.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/encoders.texi
rename to ffmpeg-2-8-12/doc/encoders.texi
diff --git a/ffmpeg-2-8-11/doc/errno.txt b/ffmpeg-2-8-12/doc/errno.txt
similarity index 100%
rename from ffmpeg-2-8-11/doc/errno.txt
rename to ffmpeg-2-8-12/doc/errno.txt
diff --git a/ffmpeg-2-8-11/doc/examples/Makefile b/ffmpeg-2-8-12/doc/examples/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/Makefile
rename to ffmpeg-2-8-12/doc/examples/Makefile
diff --git a/ffmpeg-2-8-11/doc/examples/README b/ffmpeg-2-8-12/doc/examples/README
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/README
rename to ffmpeg-2-8-12/doc/examples/README
diff --git a/ffmpeg-2-8-11/doc/examples/avio_dir_cmd.c b/ffmpeg-2-8-12/doc/examples/avio_dir_cmd.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/avio_dir_cmd.c
rename to ffmpeg-2-8-12/doc/examples/avio_dir_cmd.c
diff --git a/ffmpeg-2-8-11/doc/examples/avio_reading.c b/ffmpeg-2-8-12/doc/examples/avio_reading.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/avio_reading.c
rename to ffmpeg-2-8-12/doc/examples/avio_reading.c
diff --git a/ffmpeg-2-8-11/doc/examples/decoding_encoding.c b/ffmpeg-2-8-12/doc/examples/decoding_encoding.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/decoding_encoding.c
rename to ffmpeg-2-8-12/doc/examples/decoding_encoding.c
diff --git a/ffmpeg-2-8-11/doc/examples/demuxing_decoding.c b/ffmpeg-2-8-12/doc/examples/demuxing_decoding.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/demuxing_decoding.c
rename to ffmpeg-2-8-12/doc/examples/demuxing_decoding.c
diff --git a/ffmpeg-2-8-11/doc/examples/extract_mvs.c b/ffmpeg-2-8-12/doc/examples/extract_mvs.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/extract_mvs.c
rename to ffmpeg-2-8-12/doc/examples/extract_mvs.c
diff --git a/ffmpeg-2-8-11/doc/examples/filter_audio.c b/ffmpeg-2-8-12/doc/examples/filter_audio.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/filter_audio.c
rename to ffmpeg-2-8-12/doc/examples/filter_audio.c
diff --git a/ffmpeg-2-8-11/doc/examples/filtering_audio.c b/ffmpeg-2-8-12/doc/examples/filtering_audio.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/filtering_audio.c
rename to ffmpeg-2-8-12/doc/examples/filtering_audio.c
diff --git a/ffmpeg-2-8-11/doc/examples/filtering_video.c b/ffmpeg-2-8-12/doc/examples/filtering_video.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/filtering_video.c
rename to ffmpeg-2-8-12/doc/examples/filtering_video.c
diff --git a/ffmpeg-2-8-11/doc/examples/http_multiclient.c b/ffmpeg-2-8-12/doc/examples/http_multiclient.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/http_multiclient.c
rename to ffmpeg-2-8-12/doc/examples/http_multiclient.c
diff --git a/ffmpeg-2-8-11/doc/examples/metadata.c b/ffmpeg-2-8-12/doc/examples/metadata.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/metadata.c
rename to ffmpeg-2-8-12/doc/examples/metadata.c
diff --git a/ffmpeg-2-8-11/doc/examples/muxing.c b/ffmpeg-2-8-12/doc/examples/muxing.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/muxing.c
rename to ffmpeg-2-8-12/doc/examples/muxing.c
diff --git a/ffmpeg-2-8-11/doc/examples/qsvdec.c b/ffmpeg-2-8-12/doc/examples/qsvdec.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/qsvdec.c
rename to ffmpeg-2-8-12/doc/examples/qsvdec.c
diff --git a/ffmpeg-2-8-11/doc/examples/remuxing.c b/ffmpeg-2-8-12/doc/examples/remuxing.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/remuxing.c
rename to ffmpeg-2-8-12/doc/examples/remuxing.c
diff --git a/ffmpeg-2-8-11/doc/examples/resampling_audio.c b/ffmpeg-2-8-12/doc/examples/resampling_audio.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/resampling_audio.c
rename to ffmpeg-2-8-12/doc/examples/resampling_audio.c
diff --git a/ffmpeg-2-8-11/doc/examples/scaling_video.c b/ffmpeg-2-8-12/doc/examples/scaling_video.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/scaling_video.c
rename to ffmpeg-2-8-12/doc/examples/scaling_video.c
diff --git a/ffmpeg-2-8-11/doc/examples/transcode_aac.c b/ffmpeg-2-8-12/doc/examples/transcode_aac.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/transcode_aac.c
rename to ffmpeg-2-8-12/doc/examples/transcode_aac.c
diff --git a/ffmpeg-2-8-11/doc/examples/transcoding.c b/ffmpeg-2-8-12/doc/examples/transcoding.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/examples/transcoding.c
rename to ffmpeg-2-8-12/doc/examples/transcoding.c
diff --git a/ffmpeg-2-8-11/doc/faq.texi b/ffmpeg-2-8-12/doc/faq.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/faq.texi
rename to ffmpeg-2-8-12/doc/faq.texi
diff --git a/ffmpeg-2-8-11/doc/fate.texi b/ffmpeg-2-8-12/doc/fate.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/fate.texi
rename to ffmpeg-2-8-12/doc/fate.texi
diff --git a/ffmpeg-2-8-11/doc/fate_config.sh.template b/ffmpeg-2-8-12/doc/fate_config.sh.template
similarity index 100%
rename from ffmpeg-2-8-11/doc/fate_config.sh.template
rename to ffmpeg-2-8-12/doc/fate_config.sh.template
diff --git a/ffmpeg-2-8-11/doc/ffmpeg-bitstream-filters.texi b/ffmpeg-2-8-12/doc/ffmpeg-bitstream-filters.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffmpeg-bitstream-filters.texi
rename to ffmpeg-2-8-12/doc/ffmpeg-bitstream-filters.texi
diff --git a/ffmpeg-2-8-11/doc/ffmpeg-codecs.texi b/ffmpeg-2-8-12/doc/ffmpeg-codecs.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffmpeg-codecs.texi
rename to ffmpeg-2-8-12/doc/ffmpeg-codecs.texi
diff --git a/ffmpeg-2-8-11/doc/ffmpeg-devices.texi b/ffmpeg-2-8-12/doc/ffmpeg-devices.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffmpeg-devices.texi
rename to ffmpeg-2-8-12/doc/ffmpeg-devices.texi
diff --git a/ffmpeg-2-8-11/doc/ffmpeg-filters.texi b/ffmpeg-2-8-12/doc/ffmpeg-filters.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffmpeg-filters.texi
rename to ffmpeg-2-8-12/doc/ffmpeg-filters.texi
diff --git a/ffmpeg-2-8-11/doc/ffmpeg-formats.texi b/ffmpeg-2-8-12/doc/ffmpeg-formats.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffmpeg-formats.texi
rename to ffmpeg-2-8-12/doc/ffmpeg-formats.texi
diff --git a/ffmpeg-2-8-11/doc/ffmpeg-protocols.texi b/ffmpeg-2-8-12/doc/ffmpeg-protocols.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffmpeg-protocols.texi
rename to ffmpeg-2-8-12/doc/ffmpeg-protocols.texi
diff --git a/ffmpeg-2-8-11/doc/ffmpeg-resampler.texi b/ffmpeg-2-8-12/doc/ffmpeg-resampler.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffmpeg-resampler.texi
rename to ffmpeg-2-8-12/doc/ffmpeg-resampler.texi
diff --git a/ffmpeg-2-8-11/doc/ffmpeg-scaler.texi b/ffmpeg-2-8-12/doc/ffmpeg-scaler.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffmpeg-scaler.texi
rename to ffmpeg-2-8-12/doc/ffmpeg-scaler.texi
diff --git a/ffmpeg-2-8-11/doc/ffmpeg-utils.texi b/ffmpeg-2-8-12/doc/ffmpeg-utils.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffmpeg-utils.texi
rename to ffmpeg-2-8-12/doc/ffmpeg-utils.texi
diff --git a/ffmpeg-2-8-11/doc/ffmpeg.texi b/ffmpeg-2-8-12/doc/ffmpeg.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffmpeg.texi
rename to ffmpeg-2-8-12/doc/ffmpeg.texi
diff --git a/ffmpeg-2-8-11/doc/ffmpeg.txt b/ffmpeg-2-8-12/doc/ffmpeg.txt
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffmpeg.txt
rename to ffmpeg-2-8-12/doc/ffmpeg.txt
diff --git a/ffmpeg-2-8-11/doc/ffplay.texi b/ffmpeg-2-8-12/doc/ffplay.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffplay.texi
rename to ffmpeg-2-8-12/doc/ffplay.texi
diff --git a/ffmpeg-2-8-11/doc/ffprobe.texi b/ffmpeg-2-8-12/doc/ffprobe.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffprobe.texi
rename to ffmpeg-2-8-12/doc/ffprobe.texi
diff --git a/ffmpeg-2-8-11/doc/ffprobe.xsd b/ffmpeg-2-8-12/doc/ffprobe.xsd
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffprobe.xsd
rename to ffmpeg-2-8-12/doc/ffprobe.xsd
diff --git a/ffmpeg-2-8-11/doc/ffserver.conf b/ffmpeg-2-8-12/doc/ffserver.conf
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffserver.conf
rename to ffmpeg-2-8-12/doc/ffserver.conf
diff --git a/ffmpeg-2-8-11/doc/ffserver.texi b/ffmpeg-2-8-12/doc/ffserver.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/ffserver.texi
rename to ffmpeg-2-8-12/doc/ffserver.texi
diff --git a/ffmpeg-2-8-11/doc/fftools-common-opts.texi b/ffmpeg-2-8-12/doc/fftools-common-opts.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/fftools-common-opts.texi
rename to ffmpeg-2-8-12/doc/fftools-common-opts.texi
diff --git a/ffmpeg-2-8-11/doc/filter_design.txt b/ffmpeg-2-8-12/doc/filter_design.txt
similarity index 100%
rename from ffmpeg-2-8-11/doc/filter_design.txt
rename to ffmpeg-2-8-12/doc/filter_design.txt
diff --git a/ffmpeg-2-8-12/doc/filters.texi b/ffmpeg-2-8-12/doc/filters.texi
new file mode 100644
index 0000000..410608e
--- /dev/null
+++ b/ffmpeg-2-8-12/doc/filters.texi
@@ -0,0 +1,13524 @@
+ at chapter Filtering Introduction
+ at c man begin FILTERING INTRODUCTION
+
+Filtering in FFmpeg is enabled through the libavfilter library.
+
+In libavfilter, a filter can have multiple inputs and multiple
+outputs.
+To illustrate the sorts of things that are possible, we consider the
+following filtergraph.
+
+ at verbatim
+ [main]
+input --> split ---------------------> overlay --> output
+ | ^
+ |[tmp] [flip]|
+ +-----> crop --> vflip -------+
+ at end verbatim
+
+This filtergraph splits the input stream in two streams, then sends one
+stream through the crop filter and the vflip filter, before merging it
+back with the other stream by overlaying it on top. You can use the
+following command to achieve this:
+
+ at example
+ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT
+ at end example
+
+The result will be that the top half of the video is mirrored
+onto the bottom half of the output video.
+
+Filters in the same linear chain are separated by commas, and distinct
+linear chains of filters are separated by semicolons. In our example,
+ at var{crop,vflip} are in one linear chain, @var{split} and
+ at var{overlay} are separately in another. The points where the linear
+chains join are labelled by names enclosed in square brackets. In the
+example, the split filter generates two outputs that are associated to
+the labels @var{[main]} and @var{[tmp]}.
+
+The stream sent to the second output of @var{split}, labelled as
+ at var{[tmp]}, is processed through the @var{crop} filter, which crops
+away the lower half part of the video, and then vertically flipped. The
+ at var{overlay} filter takes in input the first unchanged output of the
+split filter (which was labelled as @var{[main]}), and overlay on its
+lower half the output generated by the @var{crop,vflip} filterchain.
+
+Some filters take in input a list of parameters: they are specified
+after the filter name and an equal sign, and are separated from each other
+by a colon.
+
+There exist so-called @var{source filters} that do not have an
+audio/video input, and @var{sink filters} that will not have audio/video
+output.
+
+ at c man end FILTERING INTRODUCTION
+
+ at chapter graph2dot
+ at c man begin GRAPH2DOT
+
+The @file{graph2dot} program included in the FFmpeg @file{tools}
+directory can be used to parse a filtergraph description and issue a
+corresponding textual representation in the dot language.
+
+Invoke the command:
+ at example
+graph2dot -h
+ at end example
+
+to see how to use @file{graph2dot}.
+
+You can then pass the dot description to the @file{dot} program (from
+the graphviz suite of programs) and obtain a graphical representation
+of the filtergraph.
+
+For example the sequence of commands:
+ at example
+echo @var{GRAPH_DESCRIPTION} | \
+tools/graph2dot -o graph.tmp && \
+dot -Tpng graph.tmp -o graph.png && \
+display graph.png
+ at end example
+
+can be used to create and display an image representing the graph
+described by the @var{GRAPH_DESCRIPTION} string. Note that this string must be
+a complete self-contained graph, with its inputs and outputs explicitly defined.
+For example if your command line is of the form:
+ at example
+ffmpeg -i infile -vf scale=640:360 outfile
+ at end example
+your @var{GRAPH_DESCRIPTION} string will need to be of the form:
+ at example
+nullsrc,scale=640:360,nullsink
+ at end example
+you may also need to set the @var{nullsrc} parameters and add a @var{format}
+filter in order to simulate a specific input file.
+
+ at c man end GRAPH2DOT
+
+ at chapter Filtergraph description
+ at c man begin FILTERGRAPH DESCRIPTION
+
+A filtergraph is a directed graph of connected filters. It can contain
+cycles, and there can be multiple links between a pair of
+filters. Each link has one input pad on one side connecting it to one
+filter from which it takes its input, and one output pad on the other
+side connecting it to one filter accepting its output.
+
+Each filter in a filtergraph is an instance of a filter class
+registered in the application, which defines the features and the
+number of input and output pads of the filter.
+
+A filter with no input pads is called a "source", and a filter with no
+output pads is called a "sink".
+
+ at anchor{Filtergraph syntax}
+ at section Filtergraph syntax
+
+A filtergraph has a textual representation, which is recognized by the
+ at option{-filter}/@option{-vf}/@option{-af} and
+ at option{-filter_complex} options in @command{ffmpeg} and
+ at option{-vf}/@option{-af} in @command{ffplay}, and by the
+ at code{avfilter_graph_parse_ptr()} function defined in
+ at file{libavfilter/avfilter.h}.
+
+A filterchain consists of a sequence of connected filters, each one
+connected to the previous one in the sequence. A filterchain is
+represented by a list of ","-separated filter descriptions.
+
+A filtergraph consists of a sequence of filterchains. A sequence of
+filterchains is represented by a list of ";"-separated filterchain
+descriptions.
+
+A filter is represented by a string of the form:
+[@var{in_link_1}]...[@var{in_link_N}]@var{filter_name}=@var{arguments}[@var{out_link_1}]...[@var{out_link_M}]
+
+ at var{filter_name} is the name of the filter class of which the
+described filter is an instance of, and has to be the name of one of
+the filter classes registered in the program.
+The name of the filter class is optionally followed by a string
+"=@var{arguments}".
+
+ at var{arguments} is a string which contains the parameters used to
+initialize the filter instance. It may have one of two forms:
+ at itemize
+
+ at item
+A ':'-separated list of @var{key=value} pairs.
+
+ at item
+A ':'-separated list of @var{value}. In this case, the keys are assumed to be
+the option names in the order they are declared. E.g. the @code{fade} filter
+declares three options in this order -- @option{type}, @option{start_frame} and
+ at option{nb_frames}. Then the parameter list @var{in:0:30} means that the value
+ at var{in} is assigned to the option @option{type}, @var{0} to
+ at option{start_frame} and @var{30} to @option{nb_frames}.
+
+ at item
+A ':'-separated list of mixed direct @var{value} and long @var{key=value}
+pairs. The direct @var{value} must precede the @var{key=value} pairs, and
+follow the same constraints order of the previous point. The following
+ at var{key=value} pairs can be set in any preferred order.
+
+ at end itemize
+
+If the option value itself is a list of items (e.g. the @code{format} filter
+takes a list of pixel formats), the items in the list are usually separated by
+ at samp{|}.
+
+The list of arguments can be quoted using the character @samp{'} as initial
+and ending mark, and the character @samp{\} for escaping the characters
+within the quoted text; otherwise the argument string is considered
+terminated when the next special character (belonging to the set
+ at samp{[]=;,}) is encountered.
+
+The name and arguments of the filter are optionally preceded and
+followed by a list of link labels.
+A link label allows one to name a link and associate it to a filter output
+or input pad. The preceding labels @var{in_link_1}
+... @var{in_link_N}, are associated to the filter input pads,
+the following labels @var{out_link_1} ... @var{out_link_M}, are
+associated to the output pads.
+
+When two link labels with the same name are found in the
+filtergraph, a link between the corresponding input and output pad is
+created.
+
+If an output pad is not labelled, it is linked by default to the first
+unlabelled input pad of the next filter in the filterchain.
+For example in the filterchain
+ at example
+nullsrc, split[L1], [L2]overlay, nullsink
+ at end example
+the split filter instance has two output pads, and the overlay filter
+instance two input pads. The first output pad of split is labelled
+"L1", the first input pad of overlay is labelled "L2", and the second
+output pad of split is linked to the second input pad of overlay,
+which are both unlabelled.
+
+In a filter description, if the input label of the first filter is not
+specified, "in" is assumed; if the output label of the last filter is not
+specified, "out" is assumed.
+
+In a complete filterchain all the unlabelled filter input and output
+pads must be connected. A filtergraph is considered valid if all the
+filter input and output pads of all the filterchains are connected.
+
+Libavfilter will automatically insert @ref{scale} filters where format
+conversion is required. It is possible to specify swscale flags
+for those automatically inserted scalers by prepending
+ at code{sws_flags=@var{flags};}
+to the filtergraph description.
+
+Here is a BNF description of the filtergraph syntax:
+ at example
+ at var{NAME} ::= sequence of alphanumeric characters and '_'
+ at var{LINKLABEL} ::= "[" @var{NAME} "]"
+ at var{LINKLABELS} ::= @var{LINKLABEL} [@var{LINKLABELS}]
+ at var{FILTER_ARGUMENTS} ::= sequence of chars (possibly quoted)
+ at var{FILTER} ::= [@var{LINKLABELS}] @var{NAME} ["=" @var{FILTER_ARGUMENTS}] [@var{LINKLABELS}]
+ at var{FILTERCHAIN} ::= @var{FILTER} [, at var{FILTERCHAIN}]
+ at var{FILTERGRAPH} ::= [sws_flags=@var{flags};] @var{FILTERCHAIN} [;@var{FILTERGRAPH}]
+ at end example
+
+ at section Notes on filtergraph escaping
+
+Filtergraph description composition entails several levels of
+escaping. See @ref{quoting_and_escaping,,the "Quoting and escaping"
+section in the ffmpeg-utils(1) manual,ffmpeg-utils} for more
+information about the employed escaping procedure.
+
+A first level escaping affects the content of each filter option
+value, which may contain the special character @code{:} used to
+separate values, or one of the escaping characters @code{\'}.
+
+A second level escaping affects the whole filter description, which
+may contain the escaping characters @code{\'} or the special
+characters @code{[],;} used by the filtergraph description.
+
+Finally, when you specify a filtergraph on a shell commandline, you
+need to perform a third level escaping for the shell special
+characters contained within it.
+
+For example, consider the following string to be embedded in
+the @ref{drawtext} filter description @option{text} value:
+ at example
+this is a 'string': may contain one, or more, special characters
+ at end example
+
+This string contains the @code{'} special escaping character, and the
+ at code{:} special character, so it needs to be escaped in this way:
+ at example
+text=this is a \'string\'\: may contain one, or more, special characters
+ at end example
+
+A second level of escaping is required when embedding the filter
+description in a filtergraph description, in order to escape all the
+filtergraph special characters. Thus the example above becomes:
+ at example
+drawtext=text=this is a \\\'string\\\'\\: may contain one\, or more\, special characters
+ at end example
+(note that in addition to the @code{\'} escaping special characters,
+also @code{,} needs to be escaped).
+
+Finally an additional level of escaping is needed when writing the
+filtergraph description in a shell command, which depends on the
+escaping rules of the adopted shell. For example, assuming that
+ at code{\} is special and needs to be escaped with another @code{\}, the
+previous string will finally result in:
+ at example
+-vf "drawtext=text=this is a \\\\\\'string\\\\\\'\\\\: may contain one\\, or more\\, special characters"
+ at end example
+
+ at chapter Timeline editing
+
+Some filters support a generic @option{enable} option. For the filters
+supporting timeline editing, this option can be set to an expression which is
+evaluated before sending a frame to the filter. If the evaluation is non-zero,
+the filter will be enabled, otherwise the frame will be sent unchanged to the
+next filter in the filtergraph.
+
+The expression accepts the following values:
+ at table @samp
+ at item t
+timestamp expressed in seconds, NAN if the input timestamp is unknown
+
+ at item n
+sequential number of the input frame, starting from 0
+
+ at item pos
+the position in the file of the input frame, NAN if unknown
+
+ at item w
+ at item h
+width and height of the input frame if video
+ at end table
+
+Additionally, these filters support an @option{enable} command that can be used
+to re-define the expression.
+
+Like any other filtering option, the @option{enable} option follows the same
+rules.
+
+For example, to enable a blur filter (@ref{smartblur}) from 10 seconds to 3
+minutes, and a @ref{curves} filter starting at 3 seconds:
+ at example
+smartblur = enable='between(t,10,3*60)',
+curves = enable='gte(t,3)' : preset=cross_process
+ at end example
+
+ at c man end FILTERGRAPH DESCRIPTION
+
+ at chapter Audio Filters
+ at c man begin AUDIO FILTERS
+
+When you configure your FFmpeg build, you can disable any of the
+existing filters using @code{--disable-filters}.
+The configure output will show the audio filters included in your
+build.
+
+Below is a description of the currently available audio filters.
+
+ at section acrossfade
+
+Apply cross fade from one input audio stream to another input audio stream.
+The cross fade is applied for specified duration near the end of first stream.
+
+The filter accepts the following options:
+
+ at table @option
+ at item nb_samples, ns
+Specify the number of samples for which the cross fade effect has to last.
+At the end of the cross fade effect the first input audio will be completely
+silent. Default is 44100.
+
+ at item duration, d
+Specify the duration of the cross fade effect. See
+ at ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}
+for the accepted syntax.
+By default the duration is determined by @var{nb_samples}.
+If set this option is used instead of @var{nb_samples}.
+
+ at item overlap, o
+Should first stream end overlap with second stream start. Default is enabled.
+
+ at item curve1
+Set curve for cross fade transition for first stream.
+
+ at item curve2
+Set curve for cross fade transition for second stream.
+
+For description of available curve types see @ref{afade} filter description.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Cross fade from one input to another:
+ at example
+ffmpeg -i first.flac -i second.flac -filter_complex acrossfade=d=10:c1=exp:c2=exp output.flac
+ at end example
+
+ at item
+Cross fade from one input to another but without overlapping:
+ at example
+ffmpeg -i first.flac -i second.flac -filter_complex acrossfade=d=10:o=0:c1=exp:c2=exp output.flac
+ at end example
+ at end itemize
+
+ at section adelay
+
+Delay one or more audio channels.
+
+Samples in delayed channel are filled with silence.
+
+The filter accepts the following option:
+
+ at table @option
+ at item delays
+Set list of delays in milliseconds for each channel separated by '|'.
+At least one delay greater than 0 should be provided.
+Unused delays will be silently ignored. If number of given delays is
+smaller than number of channels all remaining channels will not be delayed.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Delay first channel by 1.5 seconds, the third channel by 0.5 seconds and leave
+the second channel (and any other channels that may be present) unchanged.
+ at example
+adelay=1500|0|500
+ at end example
+ at end itemize
+
+ at section aecho
+
+Apply echoing to the input audio.
+
+Echoes are reflected sound and can occur naturally amongst mountains
+(and sometimes large buildings) when talking or shouting; digital echo
+effects emulate this behaviour and are often used to help fill out the
+sound of a single instrument or vocal. The time difference between the
+original signal and the reflection is the @code{delay}, and the
+loudness of the reflected signal is the @code{decay}.
+Multiple echoes can have different delays and decays.
+
+A description of the accepted parameters follows.
+
+ at table @option
+ at item in_gain
+Set input gain of reflected signal. Default is @code{0.6}.
+
+ at item out_gain
+Set output gain of reflected signal. Default is @code{0.3}.
+
+ at item delays
+Set list of time intervals in milliseconds between original signal and reflections
+separated by '|'. Allowed range for each @code{delay} is @code{(0 - 90000.0]}.
+Default is @code{1000}.
+
+ at item decays
+Set list of loudnesses of reflected signals separated by '|'.
+Allowed range for each @code{decay} is @code{(0 - 1.0]}.
+Default is @code{0.5}.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Make it sound as if there are twice as many instruments as are actually playing:
+ at example
+aecho=0.8:0.88:60:0.4
+ at end example
+
+ at item
+If delay is very short, then it sound like a (metallic) robot playing music:
+ at example
+aecho=0.8:0.88:6:0.4
+ at end example
+
+ at item
+A longer delay will sound like an open air concert in the mountains:
+ at example
+aecho=0.8:0.9:1000:0.3
+ at end example
+
+ at item
+Same as above but with one more mountain:
+ at example
+aecho=0.8:0.9:1000|1800:0.3|0.25
+ at end example
+ at end itemize
+
+ at section aeval
+
+Modify an audio signal according to the specified expressions.
+
+This filter accepts one or more expressions (one for each channel),
+which are evaluated and used to modify a corresponding audio signal.
+
+It accepts the following parameters:
+
+ at table @option
+ at item exprs
+Set the '|'-separated expressions list for each separate channel. If
+the number of input channels is greater than the number of
+expressions, the last specified expression is used for the remaining
+output channels.
+
+ at item channel_layout, c
+Set output channel layout. If not specified, the channel layout is
+specified by the number of expressions. If set to @samp{same}, it will
+use by default the same input channel layout.
+ at end table
+
+Each expression in @var{exprs} can contain the following constants and functions:
+
+ at table @option
+ at item ch
+channel number of the current expression
+
+ at item n
+number of the evaluated sample, starting from 0
+
+ at item s
+sample rate
+
+ at item t
+time of the evaluated sample expressed in seconds
+
+ at item nb_in_channels
+ at item nb_out_channels
+input and output number of channels
+
+ at item val(CH)
+the value of input channel with number @var{CH}
+ at end table
+
+Note: this filter is slow. For faster processing you should use a
+dedicated filter.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Half volume:
+ at example
+aeval=val(ch)/2:c=same
+ at end example
+
+ at item
+Invert phase of the second channel:
+ at example
+aeval=val(0)|-val(1)
+ at end example
+ at end itemize
+
+ at anchor{afade}
+ at section afade
+
+Apply fade-in/out effect to input audio.
+
+A description of the accepted parameters follows.
+
+ at table @option
+ at item type, t
+Specify the effect type, can be either @code{in} for fade-in, or
+ at code{out} for a fade-out effect. Default is @code{in}.
+
+ at item start_sample, ss
+Specify the number of the start sample for starting to apply the fade
+effect. Default is 0.
+
+ at item nb_samples, ns
+Specify the number of samples for which the fade effect has to last. At
+the end of the fade-in effect the output audio will have the same
+volume as the input audio, at the end of the fade-out transition
+the output audio will be silence. Default is 44100.
+
+ at item start_time, st
+Specify the start time of the fade effect. Default is 0.
+The value must be specified as a time duration; see
+ at ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}
+for the accepted syntax.
+If set this option is used instead of @var{start_sample}.
+
+ at item duration, d
+Specify the duration of the fade effect. See
+ at ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}
+for the accepted syntax.
+At the end of the fade-in effect the output audio will have the same
+volume as the input audio, at the end of the fade-out transition
+the output audio will be silence.
+By default the duration is determined by @var{nb_samples}.
+If set this option is used instead of @var{nb_samples}.
+
+ at item curve
+Set curve for fade transition.
+
+It accepts the following values:
+ at table @option
+ at item tri
+select triangular, linear slope (default)
+ at item qsin
+select quarter of sine wave
+ at item hsin
+select half of sine wave
+ at item esin
+select exponential sine wave
+ at item log
+select logarithmic
+ at item ipar
+select inverted parabola
+ at item qua
+select quadratic
+ at item cub
+select cubic
+ at item squ
+select square root
+ at item cbr
+select cubic root
+ at item par
+select parabola
+ at item exp
+select exponential
+ at item iqsin
+select inverted quarter of sine wave
+ at item ihsin
+select inverted half of sine wave
+ at item dese
+select double-exponential seat
+ at item desi
+select double-exponential sigmoid
+ at end table
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Fade in first 15 seconds of audio:
+ at example
+afade=t=in:ss=0:d=15
+ at end example
+
+ at item
+Fade out last 25 seconds of a 900 seconds audio:
+ at example
+afade=t=out:st=875:d=25
+ at end example
+ at end itemize
+
+ at anchor{aformat}
+ at section aformat
+
+Set output format constraints for the input audio. The framework will
+negotiate the most appropriate format to minimize conversions.
+
+It accepts the following parameters:
+ at table @option
+
+ at item sample_fmts
+A '|'-separated list of requested sample formats.
+
+ at item sample_rates
+A '|'-separated list of requested sample rates.
+
+ at item channel_layouts
+A '|'-separated list of requested channel layouts.
+
+See @ref{channel layout syntax,,the Channel Layout section in the ffmpeg-utils(1) manual,ffmpeg-utils}
+for the required syntax.
+ at end table
+
+If a parameter is omitted, all values are allowed.
+
+Force the output to either unsigned 8-bit or signed 16-bit stereo
+ at example
+aformat=sample_fmts=u8|s16:channel_layouts=stereo
+ at end example
+
+ at section allpass
+
+Apply a two-pole all-pass filter with central frequency (in Hz)
+ at var{frequency}, and filter-width @var{width}.
+An all-pass filter changes the audio's frequency to phase relationship
+without changing its frequency to amplitude relationship.
+
+The filter accepts the following options:
+
+ at table @option
+ at item frequency, f
+Set frequency in Hz.
+
+ at item width_type
+Set method to specify band-width of filter.
+ at table @option
+ at item h
+Hz
+ at item q
+Q-Factor
+ at item o
+octave
+ at item s
+slope
+ at end table
+
+ at item width, w
+Specify the band-width of a filter in width_type units.
+ at end table
+
+ at anchor{amerge}
+ at section amerge
+
+Merge two or more audio streams into a single multi-channel stream.
+
+The filter accepts the following options:
+
+ at table @option
+
+ at item inputs
+Set the number of inputs. Default is 2.
+
+ at end table
+
+If the channel layouts of the inputs are disjoint, and therefore compatible,
+the channel layout of the output will be set accordingly and the channels
+will be reordered as necessary. If the channel layouts of the inputs are not
+disjoint, the output will have all the channels of the first input then all
+the channels of the second input, in that order, and the channel layout of
+the output will be the default value corresponding to the total number of
+channels.
+
+For example, if the first input is in 2.1 (FL+FR+LF) and the second input
+is FC+BL+BR, then the output will be in 5.1, with the channels in the
+following order: a1, a2, b1, a3, b2, b3 (a1 is the first channel of the
+first input, b1 is the first channel of the second input).
+
+On the other hand, if both input are in stereo, the output channels will be
+in the default order: a1, a2, b1, b2, and the channel layout will be
+arbitrarily set to 4.0, which may or may not be the expected value.
+
+All inputs must have the same sample rate, and format.
+
+If inputs do not have the same duration, the output will stop with the
+shortest.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Merge two mono files into a stereo stream:
+ at example
+amovie=left.wav [l] ; amovie=right.mp3 [r] ; [l] [r] amerge
+ at end example
+
+ at item
+Multiple merges assuming 1 video stream and 6 audio streams in @file{input.mkv}:
+ at example
+ffmpeg -i input.mkv -filter_complex "[0:1][0:2][0:3][0:4][0:5][0:6] amerge=inputs=6" -c:a pcm_s16le output.mkv
+ at end example
+ at end itemize
+
+ at section amix
+
+Mixes multiple audio inputs into a single output.
+
+Note that this filter only supports float samples (the @var{amerge}
+and @var{pan} audio filters support many formats). If the @var{amix}
+input has integer samples then @ref{aresample} will be automatically
+inserted to perform the conversion to float samples.
+
+For example
+ at example
+ffmpeg -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex amix=inputs=3:duration=first:dropout_transition=3 OUTPUT
+ at end example
+will mix 3 input audio streams to a single output with the same duration as the
+first input and a dropout transition time of 3 seconds.
+
+It accepts the following parameters:
+ at table @option
+
+ at item inputs
+The number of inputs. If unspecified, it defaults to 2.
+
+ at item duration
+How to determine the end-of-stream.
+ at table @option
+
+ at item longest
+The duration of the longest input. (default)
+
+ at item shortest
+The duration of the shortest input.
+
+ at item first
+The duration of the first input.
+
+ at end table
+
+ at item dropout_transition
+The transition time, in seconds, for volume renormalization when an input
+stream ends. The default value is 2 seconds.
+
+ at end table
+
+ at section anull
+
+Pass the audio source unchanged to the output.
+
+ at section apad
+
+Pad the end of an audio stream with silence.
+
+This can be used together with @command{ffmpeg} @option{-shortest} to
+extend audio streams to the same length as the video stream.
+
+A description of the accepted options follows.
+
+ at table @option
+ at item packet_size
+Set silence packet size. Default value is 4096.
+
+ at item pad_len
+Set the number of samples of silence to add to the end. After the
+value is reached, the stream is terminated. This option is mutually
+exclusive with @option{whole_len}.
+
+ at item whole_len
+Set the minimum total number of samples in the output audio stream. If
+the value is longer than the input audio length, silence is added to
+the end, until the value is reached. This option is mutually exclusive
+with @option{pad_len}.
+ at end table
+
+If neither the @option{pad_len} nor the @option{whole_len} option is
+set, the filter will add silence to the end of the input stream
+indefinitely.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Add 1024 samples of silence to the end of the input:
+ at example
+apad=pad_len=1024
+ at end example
+
+ at item
+Make sure the audio output will contain at least 10000 samples, pad
+the input with silence if required:
+ at example
+apad=whole_len=10000
+ at end example
+
+ at item
+Use @command{ffmpeg} to pad the audio input with silence, so that the
+video stream will always result the shortest and will be converted
+until the end in the output file when using the @option{shortest}
+option:
+ at example
+ffmpeg -i VIDEO -i AUDIO -filter_complex "[1:0]apad" -shortest OUTPUT
+ at end example
+ at end itemize
+
+ at section aphaser
+Add a phasing effect to the input audio.
+
+A phaser filter creates series of peaks and troughs in the frequency spectrum.
+The position of the peaks and troughs are modulated so that they vary over time, creating a sweeping effect.
+
+A description of the accepted parameters follows.
+
+ at table @option
+ at item in_gain
+Set input gain. Default is 0.4.
+
+ at item out_gain
+Set output gain. Default is 0.74
+
+ at item delay
+Set delay in milliseconds. Default is 3.0.
+
+ at item decay
+Set decay. Default is 0.4.
+
+ at item speed
+Set modulation speed in Hz. Default is 0.5.
+
+ at item type
+Set modulation type. Default is triangular.
+
+It accepts the following values:
+ at table @samp
+ at item triangular, t
+ at item sinusoidal, s
+ at end table
+ at end table
+
+ at anchor{aresample}
+ at section aresample
+
+Resample the input audio to the specified parameters, using the
+libswresample library. If none are specified then the filter will
+automatically convert between its input and output.
+
+This filter is also able to stretch/squeeze the audio data to make it match
+the timestamps or to inject silence / cut out audio to make it match the
+timestamps, do a combination of both or do neither.
+
+The filter accepts the syntax
+[@var{sample_rate}:]@var{resampler_options}, where @var{sample_rate}
+expresses a sample rate and @var{resampler_options} is a list of
+ at var{key}=@var{value} pairs, separated by ":". See the
+ffmpeg-resampler manual for the complete list of supported options.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Resample the input audio to 44100Hz:
+ at example
+aresample=44100
+ at end example
+
+ at item
+Stretch/squeeze samples to the given timestamps, with a maximum of 1000
+samples per second compensation:
+ at example
+aresample=async=1000
+ at end example
+ at end itemize
+
+ at section asetnsamples
+
+Set the number of samples per each output audio frame.
+
+The last output packet may contain a different number of samples, as
+the filter will flush all the remaining samples when the input audio
+signal its end.
+
+The filter accepts the following options:
+
+ at table @option
+
+ at item nb_out_samples, n
+Set the number of frames per each output audio frame. The number is
+intended as the number of samples @emph{per each channel}.
+Default value is 1024.
+
+ at item pad, p
+If set to 1, the filter will pad the last audio frame with zeroes, so
+that the last frame will contain the same number of samples as the
+previous ones. Default value is 1.
+ at end table
+
+For example, to set the number of per-frame samples to 1234 and
+disable padding for the last frame, use:
+ at example
+asetnsamples=n=1234:p=0
+ at end example
+
+ at section asetrate
+
+Set the sample rate without altering the PCM data.
+This will result in a change of speed and pitch.
+
+The filter accepts the following options:
+
+ at table @option
+ at item sample_rate, r
+Set the output sample rate. Default is 44100 Hz.
+ at end table
+
+ at section ashowinfo
+
+Show a line containing various information for each input audio frame.
+The input audio is not modified.
+
+The shown line contains a sequence of key/value pairs of the form
+ at var{key}:@var{value}.
+
+The following values are shown in the output:
+
+ at table @option
+ at item n
+The (sequential) number of the input frame, starting from 0.
+
+ at item pts
+The presentation timestamp of the input frame, in time base units; the time base
+depends on the filter input pad, and is usually 1/@var{sample_rate}.
+
+ at item pts_time
+The presentation timestamp of the input frame in seconds.
+
+ at item pos
+position of the frame in the input stream, -1 if this information in
+unavailable and/or meaningless (for example in case of synthetic audio)
+
+ at item fmt
+The sample format.
+
+ at item chlayout
+The channel layout.
+
+ at item rate
+The sample rate for the audio frame.
+
+ at item nb_samples
+The number of samples (per channel) in the frame.
+
+ at item checksum
+The Adler-32 checksum (printed in hexadecimal) of the audio data. For planar
+audio, the data is treated as if all the planes were concatenated.
+
+ at item plane_checksums
+A list of Adler-32 checksums for each data plane.
+ at end table
+
+ at anchor{astats}
+ at section astats
+
+Display time domain statistical information about the audio channels.
+Statistics are calculated and displayed for each audio channel and,
+where applicable, an overall figure is also given.
+
+It accepts the following option:
+ at table @option
+ at item length
+Short window length in seconds, used for peak and trough RMS measurement.
+Default is @code{0.05} (50 milliseconds). Allowed range is @code{[0.1 - 10]}.
+
+ at item metadata
+
+Set metadata injection. All the metadata keys are prefixed with @code{lavfi.astats.X},
+where @code{X} is channel number starting from 1 or string @code{Overall}. Default is
+disabled.
+
+Available keys for each channel are:
+DC_offset
+Min_level
+Max_level
+Min_difference
+Max_difference
+Mean_difference
+Peak_level
+RMS_peak
+RMS_trough
+Crest_factor
+Flat_factor
+Peak_count
+Bit_depth
+
+and for Overall:
+DC_offset
+Min_level
+Max_level
+Min_difference
+Max_difference
+Mean_difference
+Peak_level
+RMS_level
+RMS_peak
+RMS_trough
+Flat_factor
+Peak_count
+Bit_depth
+Number_of_samples
+
+For example full key look like this @code{lavfi.astats.1.DC_offset} or
+this @code{lavfi.astats.Overall.Peak_count}.
+
+For description what each key means read below.
+
+ at item reset
+Set number of frame after which stats are going to be recalculated.
+Default is disabled.
+ at end table
+
+A description of each shown parameter follows:
+
+ at table @option
+ at item DC offset
+Mean amplitude displacement from zero.
+
+ at item Min level
+Minimal sample level.
+
+ at item Max level
+Maximal sample level.
+
+ at item Min difference
+Minimal difference between two consecutive samples.
+
+ at item Max difference
+Maximal difference between two consecutive samples.
+
+ at item Mean difference
+Mean difference between two consecutive samples.
+The average of each difference between two consecutive samples.
+
+ at item Peak level dB
+ at item RMS level dB
+Standard peak and RMS level measured in dBFS.
+
+ at item RMS peak dB
+ at item RMS trough dB
+Peak and trough values for RMS level measured over a short window.
+
+ at item Crest factor
+Standard ratio of peak to RMS level (note: not in dB).
+
+ at item Flat factor
+Flatness (i.e. consecutive samples with the same value) of the signal at its peak levels
+(i.e. either @var{Min level} or @var{Max level}).
+
+ at item Peak count
+Number of occasions (not the number of samples) that the signal attained either
+ at var{Min level} or @var{Max level}.
+
+ at item Bit depth
+Overall bit depth of audio. Number of bits used for each sample.
+ at end table
+
+ at section astreamsync
+
+Forward two audio streams and control the order the buffers are forwarded.
+
+The filter accepts the following options:
+
+ at table @option
+ at item expr, e
+Set the expression deciding which stream should be
+forwarded next: if the result is negative, the first stream is forwarded; if
+the result is positive or zero, the second stream is forwarded. It can use
+the following variables:
+
+ at table @var
+ at item b1 b2
+number of buffers forwarded so far on each stream
+ at item s1 s2
+number of samples forwarded so far on each stream
+ at item t1 t2
+current timestamp of each stream
+ at end table
+
+The default value is @code{t1-t2}, which means to always forward the stream
+that has a smaller timestamp.
+ at end table
+
+ at subsection Examples
+
+Stress-test @code{amerge} by randomly sending buffers on the wrong
+input, while avoiding too much of a desynchronization:
+ at example
+amovie=file.ogg [a] ; amovie=file.mp3 [b] ;
+[a] [b] astreamsync=(2*random(1))-1+tanh(5*(t1-t2)) [a2] [b2] ;
+[a2] [b2] amerge
+ at end example
+
+ at section asyncts
+
+Synchronize audio data with timestamps by squeezing/stretching it and/or
+dropping samples/adding silence when needed.
+
+This filter is not built by default, please use @ref{aresample} to do squeezing/stretching.
+
+It accepts the following parameters:
+ at table @option
+
+ at item compensate
+Enable stretching/squeezing the data to make it match the timestamps. Disabled
+by default. When disabled, time gaps are covered with silence.
+
+ at item min_delta
+The minimum difference between timestamps and audio data (in seconds) to trigger
+adding/dropping samples. The default value is 0.1. If you get an imperfect
+sync with this filter, try setting this parameter to 0.
+
+ at item max_comp
+The maximum compensation in samples per second. Only relevant with compensate=1.
+The default value is 500.
+
+ at item first_pts
+Assume that the first PTS should be this value. The time base is 1 / sample
+rate. This allows for padding/trimming at the start of the stream. By default,
+no assumption is made about the first frame's expected PTS, so no padding or
+trimming is done. For example, this could be set to 0 to pad the beginning with
+silence if an audio stream starts after the video stream or to trim any samples
+with a negative PTS due to encoder delay.
+
+ at end table
+
+ at section atempo
+
+Adjust audio tempo.
+
+The filter accepts exactly one parameter, the audio tempo. If not
+specified then the filter will assume nominal 1.0 tempo. Tempo must
+be in the [0.5, 2.0] range.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Slow down audio to 80% tempo:
+ at example
+atempo=0.8
+ at end example
+
+ at item
+To speed up audio to 125% tempo:
+ at example
+atempo=1.25
+ at end example
+ at end itemize
+
+ at section atrim
+
+Trim the input so that the output contains one continuous subpart of the input.
+
+It accepts the following parameters:
+ at table @option
+ at item start
+Timestamp (in seconds) of the start of the section to keep. I.e. the audio
+sample with the timestamp @var{start} will be the first sample in the output.
+
+ at item end
+Specify time of the first audio sample that will be dropped, i.e. the
+audio sample immediately preceding the one with the timestamp @var{end} will be
+the last sample in the output.
+
+ at item start_pts
+Same as @var{start}, except this option sets the start timestamp in samples
+instead of seconds.
+
+ at item end_pts
+Same as @var{end}, except this option sets the end timestamp in samples instead
+of seconds.
+
+ at item duration
+The maximum duration of the output in seconds.
+
+ at item start_sample
+The number of the first sample that should be output.
+
+ at item end_sample
+The number of the first sample that should be dropped.
+ at end table
+
+ at option{start}, @option{end}, and @option{duration} are expressed as time
+duration specifications; see
+ at ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}.
+
+Note that the first two sets of the start/end options and the @option{duration}
+option look at the frame timestamp, while the _sample options simply count the
+samples that pass through the filter. So start/end_pts and start/end_sample will
+give different results when the timestamps are wrong, inexact or do not start at
+zero. Also note that this filter does not modify the timestamps. If you wish
+to have the output timestamps start at zero, insert the asetpts filter after the
+atrim filter.
+
+If multiple start or end options are set, this filter tries to be greedy and
+keep all samples that match at least one of the specified constraints. To keep
+only the part that matches all the constraints at once, chain multiple atrim
+filters.
+
+The defaults are such that all the input is kept. So it is possible to set e.g.
+just the end values to keep everything before the specified time.
+
+Examples:
+ at itemize
+ at item
+Drop everything except the second minute of input:
+ at example
+ffmpeg -i INPUT -af atrim=60:120
+ at end example
+
+ at item
+Keep only the first 1000 samples:
+ at example
+ffmpeg -i INPUT -af atrim=end_sample=1000
+ at end example
+
+ at end itemize
+
+ at section bandpass
+
+Apply a two-pole Butterworth band-pass filter with central
+frequency @var{frequency}, and (3dB-point) band-width width.
+The @var{csg} option selects a constant skirt gain (peak gain = Q)
+instead of the default: constant 0dB peak gain.
+The filter roll off at 6dB per octave (20dB per decade).
+
+The filter accepts the following options:
+
+ at table @option
+ at item frequency, f
+Set the filter's central frequency. Default is @code{3000}.
+
+ at item csg
+Constant skirt gain if set to 1. Defaults to 0.
+
+ at item width_type
+Set method to specify band-width of filter.
+ at table @option
+ at item h
+Hz
+ at item q
+Q-Factor
+ at item o
+octave
+ at item s
+slope
+ at end table
+
+ at item width, w
+Specify the band-width of a filter in width_type units.
+ at end table
+
+ at section bandreject
+
+Apply a two-pole Butterworth band-reject filter with central
+frequency @var{frequency}, and (3dB-point) band-width @var{width}.
+The filter roll off at 6dB per octave (20dB per decade).
+
+The filter accepts the following options:
+
+ at table @option
+ at item frequency, f
+Set the filter's central frequency. Default is @code{3000}.
+
+ at item width_type
+Set method to specify band-width of filter.
+ at table @option
+ at item h
+Hz
+ at item q
+Q-Factor
+ at item o
+octave
+ at item s
+slope
+ at end table
+
+ at item width, w
+Specify the band-width of a filter in width_type units.
+ at end table
+
+ at section bass
+
+Boost or cut the bass (lower) frequencies of the audio using a two-pole
+shelving filter with a response similar to that of a standard
+hi-fi's tone-controls. This is also known as shelving equalisation (EQ).
+
+The filter accepts the following options:
+
+ at table @option
+ at item gain, g
+Give the gain at 0 Hz. Its useful range is about -20
+(for a large cut) to +20 (for a large boost).
+Beware of clipping when using a positive gain.
+
+ at item frequency, f
+Set the filter's central frequency and so can be used
+to extend or reduce the frequency range to be boosted or cut.
+The default value is @code{100} Hz.
+
+ at item width_type
+Set method to specify band-width of filter.
+ at table @option
+ at item h
+Hz
+ at item q
+Q-Factor
+ at item o
+octave
+ at item s
+slope
+ at end table
+
+ at item width, w
+Determine how steep is the filter's shelf transition.
+ at end table
+
+ at section biquad
+
+Apply a biquad IIR filter with the given coefficients.
+Where @var{b0}, @var{b1}, @var{b2} and @var{a0}, @var{a1}, @var{a2}
+are the numerator and denominator coefficients respectively.
+
+ at section bs2b
+Bauer stereo to binaural transformation, which improves headphone listening of
+stereo audio records.
+
+It accepts the following parameters:
+ at table @option
+
+ at item profile
+Pre-defined crossfeed level.
+ at table @option
+
+ at item default
+Default level (fcut=700, feed=50).
+
+ at item cmoy
+Chu Moy circuit (fcut=700, feed=60).
+
+ at item jmeier
+Jan Meier circuit (fcut=650, feed=95).
+
+ at end table
+
+ at item fcut
+Cut frequency (in Hz).
+
+ at item feed
+Feed level (in Hz).
+
+ at end table
+
+ at section channelmap
+
+Remap input channels to new locations.
+
+It accepts the following parameters:
+ at table @option
+ at item channel_layout
+The channel layout of the output stream.
+
+ at item map
+Map channels from input to output. The argument is a '|'-separated list of
+mappings, each in the @code{@var{in_channel}- at var{out_channel}} or
+ at var{in_channel} form. @var{in_channel} can be either the name of the input
+channel (e.g. FL for front left) or its index in the input channel layout.
+ at var{out_channel} is the name of the output channel or its index in the output
+channel layout. If @var{out_channel} is not given then it is implicitly an
+index, starting with zero and increasing by one for each mapping.
+ at end table
+
+If no mapping is present, the filter will implicitly map input channels to
+output channels, preserving indices.
+
+For example, assuming a 5.1+downmix input MOV file,
+ at example
+ffmpeg -i in.mov -filter 'channelmap=map=DL-FL|DR-FR' out.wav
+ at end example
+will create an output WAV file tagged as stereo from the downmix channels of
+the input.
+
+To fix a 5.1 WAV improperly encoded in AAC's native channel order
+ at example
+ffmpeg -i in.wav -filter 'channelmap=1|2|0|5|3|4:5.1' out.wav
+ at end example
+
+ at section channelsplit
+
+Split each channel from an input audio stream into a separate output stream.
+
+It accepts the following parameters:
+ at table @option
+ at item channel_layout
+The channel layout of the input stream. The default is "stereo".
+ at end table
+
+For example, assuming a stereo input MP3 file,
+ at example
+ffmpeg -i in.mp3 -filter_complex channelsplit out.mkv
+ at end example
+will create an output Matroska file with two audio streams, one containing only
+the left channel and the other the right channel.
+
+Split a 5.1 WAV file into per-channel files:
+ at example
+ffmpeg -i in.wav -filter_complex
+'channelsplit=channel_layout=5.1[FL][FR][FC][LFE][SL][SR]'
+-map '[FL]' front_left.wav -map '[FR]' front_right.wav -map '[FC]'
+front_center.wav -map '[LFE]' lfe.wav -map '[SL]' side_left.wav -map '[SR]'
+side_right.wav
+ at end example
+
+ at section chorus
+Add a chorus effect to the audio.
+
+Can make a single vocal sound like a chorus, but can also be applied to instrumentation.
+
+Chorus resembles an echo effect with a short delay, but whereas with echo the delay is
+constant, with chorus, it is varied using using sinusoidal or triangular modulation.
+The modulation depth defines the range the modulated delay is played before or after
+the delay. Hence the delayed sound will sound slower or faster, that is the delayed
+sound tuned around the original one, like in a chorus where some vocals are slightly
+off key.
+
+It accepts the following parameters:
+ at table @option
+ at item in_gain
+Set input gain. Default is 0.4.
+
+ at item out_gain
+Set output gain. Default is 0.4.
+
+ at item delays
+Set delays. A typical delay is around 40ms to 60ms.
+
+ at item decays
+Set decays.
+
+ at item speeds
+Set speeds.
+
+ at item depths
+Set depths.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+A single delay:
+ at example
+chorus=0.7:0.9:55:0.4:0.25:2
+ at end example
+
+ at item
+Two delays:
+ at example
+chorus=0.6:0.9:50|60:0.4|0.32:0.25|0.4:2|1.3
+ at end example
+
+ at item
+Fuller sounding chorus with three delays:
+ at example
+chorus=0.5:0.9:50|60|40:0.4|0.32|0.3:0.25|0.4|0.3:2|2.3|1.3
+ at end example
+ at end itemize
+
+ at section compand
+Compress or expand the audio's dynamic range.
+
+It accepts the following parameters:
+
+ at table @option
+
+ at item attacks
+ at item decays
+A list of times in seconds for each channel over which the instantaneous level
+of the input signal is averaged to determine its volume. @var{attacks} refers to
+increase of volume and @var{decays} refers to decrease of volume. For most
+situations, the attack time (response to the audio getting louder) should be
+shorter than the decay time, because the human ear is more sensitive to sudden
+loud audio than sudden soft audio. A typical value for attack is 0.3 seconds and
+a typical value for decay is 0.8 seconds.
+If specified number of attacks & decays is lower than number of channels, the last
+set attack/decay will be used for all remaining channels.
+
+ at item points
+A list of points for the transfer function, specified in dB relative to the
+maximum possible signal amplitude. Each key points list must be defined using
+the following syntax: @code{x0/y0|x1/y1|x2/y2|....} or
+ at code{x0/y0 x1/y1 x2/y2 ....}
+
+The input values must be in strictly increasing order but the transfer function
+does not have to be monotonically rising. The point @code{0/0} is assumed but
+may be overridden (by @code{0/out-dBn}). Typical values for the transfer
+function are @code{-70/-70|-60/-20}.
+
+ at item soft-knee
+Set the curve radius in dB for all joints. It defaults to 0.01.
+
+ at item gain
+Set the additional gain in dB to be applied at all points on the transfer
+function. This allows for easy adjustment of the overall gain.
+It defaults to 0.
+
+ at item volume
+Set an initial volume, in dB, to be assumed for each channel when filtering
+starts. This permits the user to supply a nominal level initially, so that, for
+example, a very large gain is not applied to initial signal levels before the
+companding has begun to operate. A typical value for audio which is initially
+quiet is -90 dB. It defaults to 0.
+
+ at item delay
+Set a delay, in seconds. The input audio is analyzed immediately, but audio is
+delayed before being fed to the volume adjuster. Specifying a delay
+approximately equal to the attack/decay times allows the filter to effectively
+operate in predictive rather than reactive mode. It defaults to 0.
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Make music with both quiet and loud passages suitable for listening to in a
+noisy environment:
+ at example
+compand=.3|.3:1|1:-90/-60|-60/-40|-40/-30|-20/-20:6:0:-90:0.2
+ at end example
+
+Another example for audio with whisper and explosion parts:
+ at example
+compand=0|0:1|1:-90/-900|-70/-70|-30/-9|0/-3:6:0:0:0
+ at end example
+
+ at item
+A noise gate for when the noise is at a lower level than the signal:
+ at example
+compand=.1|.1:.2|.2:-900/-900|-50.1/-900|-50/-50:.01:0:-90:.1
+ at end example
+
+ at item
+Here is another noise gate, this time for when the noise is at a higher level
+than the signal (making it, in some ways, similar to squelch):
+ at example
+compand=.1|.1:.1|.1:-45.1/-45.1|-45/-900|0/-900:.01:45:-90:.1
+ at end example
+ at end itemize
+
+ at section dcshift
+Apply a DC shift to the audio.
+
+This can be useful to remove a DC offset (caused perhaps by a hardware problem
+in the recording chain) from the audio. The effect of a DC offset is reduced
+headroom and hence volume. The @ref{astats} filter can be used to determine if
+a signal has a DC offset.
+
+ at table @option
+ at item shift
+Set the DC shift, allowed range is [-1, 1]. It indicates the amount to shift
+the audio.
+
+ at item limitergain
+Optional. It should have a value much less than 1 (e.g. 0.05 or 0.02) and is
+used to prevent clipping.
+ at end table
+
+ at section dynaudnorm
+Dynamic Audio Normalizer.
+
+This filter applies a certain amount of gain to the input audio in order
+to bring its peak magnitude to a target level (e.g. 0 dBFS). However, in
+contrast to more "simple" normalization algorithms, the Dynamic Audio
+Normalizer *dynamically* re-adjusts the gain factor to the input audio.
+This allows for applying extra gain to the "quiet" sections of the audio
+while avoiding distortions or clipping the "loud" sections. In other words:
+The Dynamic Audio Normalizer will "even out" the volume of quiet and loud
+sections, in the sense that the volume of each section is brought to the
+same target level. Note, however, that the Dynamic Audio Normalizer achieves
+this goal *without* applying "dynamic range compressing". It will retain 100%
+of the dynamic range *within* each section of the audio file.
+
+ at table @option
+ at item f
+Set the frame length in milliseconds. In range from 10 to 8000 milliseconds.
+Default is 500 milliseconds.
+The Dynamic Audio Normalizer processes the input audio in small chunks,
+referred to as frames. This is required, because a peak magnitude has no
+meaning for just a single sample value. Instead, we need to determine the
+peak magnitude for a contiguous sequence of sample values. While a "standard"
+normalizer would simply use the peak magnitude of the complete file, the
+Dynamic Audio Normalizer determines the peak magnitude individually for each
+frame. The length of a frame is specified in milliseconds. By default, the
+Dynamic Audio Normalizer uses a frame length of 500 milliseconds, which has
+been found to give good results with most files.
+Note that the exact frame length, in number of samples, will be determined
+automatically, based on the sampling rate of the individual input audio file.
+
+ at item g
+Set the Gaussian filter window size. In range from 3 to 301, must be odd
+number. Default is 31.
+Probably the most important parameter of the Dynamic Audio Normalizer is the
+ at code{window size} of the Gaussian smoothing filter. The filter's window size
+is specified in frames, centered around the current frame. For the sake of
+simplicity, this must be an odd number. Consequently, the default value of 31
+takes into account the current frame, as well as the 15 preceding frames and
+the 15 subsequent frames. Using a larger window results in a stronger
+smoothing effect and thus in less gain variation, i.e. slower gain
+adaptation. Conversely, using a smaller window results in a weaker smoothing
+effect and thus in more gain variation, i.e. faster gain adaptation.
+In other words, the more you increase this value, the more the Dynamic Audio
+Normalizer will behave like a "traditional" normalization filter. On the
+contrary, the more you decrease this value, the more the Dynamic Audio
+Normalizer will behave like a dynamic range compressor.
+
+ at item p
+Set the target peak value. This specifies the highest permissible magnitude
+level for the normalized audio input. This filter will try to approach the
+target peak magnitude as closely as possible, but at the same time it also
+makes sure that the normalized signal will never exceed the peak magnitude.
+A frame's maximum local gain factor is imposed directly by the target peak
+magnitude. The default value is 0.95 and thus leaves a headroom of 5%*.
+It is not recommended to go above this value.
+
+ at item m
+Set the maximum gain factor. In range from 1.0 to 100.0. Default is 10.0.
+The Dynamic Audio Normalizer determines the maximum possible (local) gain
+factor for each input frame, i.e. the maximum gain factor that does not
+result in clipping or distortion. The maximum gain factor is determined by
+the frame's highest magnitude sample. However, the Dynamic Audio Normalizer
+additionally bounds the frame's maximum gain factor by a predetermined
+(global) maximum gain factor. This is done in order to avoid excessive gain
+factors in "silent" or almost silent frames. By default, the maximum gain
+factor is 10.0, For most inputs the default value should be sufficient and
+it usually is not recommended to increase this value. Though, for input
+with an extremely low overall volume level, it may be necessary to allow even
+higher gain factors. Note, however, that the Dynamic Audio Normalizer does
+not simply apply a "hard" threshold (i.e. cut off values above the threshold).
+Instead, a "sigmoid" threshold function will be applied. This way, the
+gain factors will smoothly approach the threshold value, but never exceed that
+value.
+
+ at item r
+Set the target RMS. In range from 0.0 to 1.0. Default is 0.0 - disabled.
+By default, the Dynamic Audio Normalizer performs "peak" normalization.
+This means that the maximum local gain factor for each frame is defined
+(only) by the frame's highest magnitude sample. This way, the samples can
+be amplified as much as possible without exceeding the maximum signal
+level, i.e. without clipping. Optionally, however, the Dynamic Audio
+Normalizer can also take into account the frame's root mean square,
+abbreviated RMS. In electrical engineering, the RMS is commonly used to
+determine the power of a time-varying signal. It is therefore considered
+that the RMS is a better approximation of the "perceived loudness" than
+just looking at the signal's peak magnitude. Consequently, by adjusting all
+frames to a constant RMS value, a uniform "perceived loudness" can be
+established. If a target RMS value has been specified, a frame's local gain
+factor is defined as the factor that would result in exactly that RMS value.
+Note, however, that the maximum local gain factor is still restricted by the
+frame's highest magnitude sample, in order to prevent clipping.
+
+ at item n
+Enable channels coupling. By default is enabled.
+By default, the Dynamic Audio Normalizer will amplify all channels by the same
+amount. This means the same gain factor will be applied to all channels, i.e.
+the maximum possible gain factor is determined by the "loudest" channel.
+However, in some recordings, it may happen that the volume of the different
+channels is uneven, e.g. one channel may be "quieter" than the other one(s).
+In this case, this option can be used to disable the channel coupling. This way,
+the gain factor will be determined independently for each channel, depending
+only on the individual channel's highest magnitude sample. This allows for
+harmonizing the volume of the different channels.
+
+ at item c
+Enable DC bias correction. By default is disabled.
+An audio signal (in the time domain) is a sequence of sample values.
+In the Dynamic Audio Normalizer these sample values are represented in the
+-1.0 to 1.0 range, regardless of the original input format. Normally, the
+audio signal, or "waveform", should be centered around the zero point.
+That means if we calculate the mean value of all samples in a file, or in a
+single frame, then the result should be 0.0 or at least very close to that
+value. If, however, there is a significant deviation of the mean value from
+0.0, in either positive or negative direction, this is referred to as a
+DC bias or DC offset. Since a DC bias is clearly undesirable, the Dynamic
+Audio Normalizer provides optional DC bias correction.
+With DC bias correction enabled, the Dynamic Audio Normalizer will determine
+the mean value, or "DC correction" offset, of each input frame and subtract
+that value from all of the frame's sample values which ensures those samples
+are centered around 0.0 again. Also, in order to avoid "gaps" at the frame
+boundaries, the DC correction offset values will be interpolated smoothly
+between neighbouring frames.
+
+ at item b
+Enable alternative boundary mode. By default is disabled.
+The Dynamic Audio Normalizer takes into account a certain neighbourhood
+around each frame. This includes the preceding frames as well as the
+subsequent frames. However, for the "boundary" frames, located at the very
+beginning and at the very end of the audio file, not all neighbouring
+frames are available. In particular, for the first few frames in the audio
+file, the preceding frames are not known. And, similarly, for the last few
+frames in the audio file, the subsequent frames are not known. Thus, the
+question arises which gain factors should be assumed for the missing frames
+in the "boundary" region. The Dynamic Audio Normalizer implements two modes
+to deal with this situation. The default boundary mode assumes a gain factor
+of exactly 1.0 for the missing frames, resulting in a smooth "fade in" and
+"fade out" at the beginning and at the end of the input, respectively.
+
+ at item s
+Set the compress factor. In range from 0.0 to 30.0. Default is 0.0.
+By default, the Dynamic Audio Normalizer does not apply "traditional"
+compression. This means that signal peaks will not be pruned and thus the
+full dynamic range will be retained within each local neighbourhood. However,
+in some cases it may be desirable to combine the Dynamic Audio Normalizer's
+normalization algorithm with a more "traditional" compression.
+For this purpose, the Dynamic Audio Normalizer provides an optional compression
+(thresholding) function. If (and only if) the compression feature is enabled,
+all input frames will be processed by a soft knee thresholding function prior
+to the actual normalization process. Put simply, the thresholding function is
+going to prune all samples whose magnitude exceeds a certain threshold value.
+However, the Dynamic Audio Normalizer does not simply apply a fixed threshold
+value. Instead, the threshold value will be adjusted for each individual
+frame.
+In general, smaller parameters result in stronger compression, and vice versa.
+Values below 3.0 are not recommended, because audible distortion may appear.
+ at end table
+
+ at section earwax
+
+Make audio easier to listen to on headphones.
+
+This filter adds `cues' to 44.1kHz stereo (i.e. audio CD format) audio
+so that when listened to on headphones the stereo image is moved from
+inside your head (standard for headphones) to outside and in front of
+the listener (standard for speakers).
+
+Ported from SoX.
+
+ at section equalizer
+
+Apply a two-pole peaking equalisation (EQ) filter. With this
+filter, the signal-level at and around a selected frequency can
+be increased or decreased, whilst (unlike bandpass and bandreject
+filters) that at all other frequencies is unchanged.
+
+In order to produce complex equalisation curves, this filter can
+be given several times, each with a different central frequency.
+
+The filter accepts the following options:
+
+ at table @option
+ at item frequency, f
+Set the filter's central frequency in Hz.
+
+ at item width_type
+Set method to specify band-width of filter.
+ at table @option
+ at item h
+Hz
+ at item q
+Q-Factor
+ at item o
+octave
+ at item s
+slope
+ at end table
+
+ at item width, w
+Specify the band-width of a filter in width_type units.
+
+ at item gain, g
+Set the required gain or attenuation in dB.
+Beware of clipping when using a positive gain.
+ at end table
+
+ at subsection Examples
+ at itemize
+ at item
+Attenuate 10 dB at 1000 Hz, with a bandwidth of 200 Hz:
+ at example
+equalizer=f=1000:width_type=h:width=200:g=-10
+ at end example
+
+ at item
+Apply 2 dB gain at 1000 Hz with Q 1 and attenuate 5 dB at 100 Hz with Q 2:
+ at example
+equalizer=f=1000:width_type=q:width=1:g=2,equalizer=f=100:width_type=q:width=2:g=-5
+ at end example
+ at end itemize
+
+ at section flanger
+Apply a flanging effect to the audio.
+
+The filter accepts the following options:
+
+ at table @option
+ at item delay
+Set base delay in milliseconds. Range from 0 to 30. Default value is 0.
+
+ at item depth
+Set added swep delay in milliseconds. Range from 0 to 10. Default value is 2.
+
+ at item regen
+Set percentage regeneration (delayed signal feedback). Range from -95 to 95.
+Default value is 0.
+
+ at item width
+Set percentage of delayed signal mixed with original. Range from 0 to 100.
+Default value is 71.
+
+ at item speed
+Set sweeps per second (Hz). Range from 0.1 to 10. Default value is 0.5.
+
+ at item shape
+Set swept wave shape, can be @var{triangular} or @var{sinusoidal}.
+Default value is @var{sinusoidal}.
+
+ at item phase
+Set swept wave percentage-shift for multi channel. Range from 0 to 100.
+Default value is 25.
+
+ at item interp
+Set delay-line interpolation, @var{linear} or @var{quadratic}.
+Default is @var{linear}.
+ at end table
+
+ at section highpass
+
+Apply a high-pass filter with 3dB point frequency.
+The filter can be either single-pole, or double-pole (the default).
+The filter roll off at 6dB per pole per octave (20dB per pole per decade).
+
+The filter accepts the following options:
+
+ at table @option
+ at item frequency, f
+Set frequency in Hz. Default is 3000.
+
+ at item poles, p
+Set number of poles. Default is 2.
+
+ at item width_type
+Set method to specify band-width of filter.
+ at table @option
+ at item h
+Hz
+ at item q
+Q-Factor
+ at item o
+octave
+ at item s
+slope
+ at end table
+
+ at item width, w
+Specify the band-width of a filter in width_type units.
+Applies only to double-pole filter.
+The default is 0.707q and gives a Butterworth response.
+ at end table
+
+ at section join
+
+Join multiple input streams into one multi-channel stream.
+
+It accepts the following parameters:
+ at table @option
+
+ at item inputs
+The number of input streams. It defaults to 2.
+
+ at item channel_layout
+The desired output channel layout. It defaults to stereo.
+
+ at item map
+Map channels from inputs to output. The argument is a '|'-separated list of
+mappings, each in the @code{@var{input_idx}. at var{in_channel}- at var{out_channel}}
+form. @var{input_idx} is the 0-based index of the input stream. @var{in_channel}
+can be either the name of the input channel (e.g. FL for front left) or its
+index in the specified input stream. @var{out_channel} is the name of the output
+channel.
+ at end table
+
+The filter will attempt to guess the mappings when they are not specified
+explicitly. It does so by first trying to find an unused matching input channel
+and if that fails it picks the first unused input channel.
+
+Join 3 inputs (with properly set channel layouts):
+ at example
+ffmpeg -i INPUT1 -i INPUT2 -i INPUT3 -filter_complex join=inputs=3 OUTPUT
+ at end example
+
+Build a 5.1 output from 6 single-channel streams:
+ at example
+ffmpeg -i fl -i fr -i fc -i sl -i sr -i lfe -filter_complex
+'join=inputs=6:channel_layout=5.1:map=0.0-FL|1.0-FR|2.0-FC|3.0-SL|4.0-SR|5.0-LFE'
+out
+ at end example
+
+ at section ladspa
+
+Load a LADSPA (Linux Audio Developer's Simple Plugin API) plugin.
+
+To enable compilation of this filter you need to configure FFmpeg with
+ at code{--enable-ladspa}.
+
+ at table @option
+ at item file, f
+Specifies the name of LADSPA plugin library to load. If the environment
+variable @env{LADSPA_PATH} is defined, the LADSPA plugin is searched in
+each one of the directories specified by the colon separated list in
+ at env{LADSPA_PATH}, otherwise in the standard LADSPA paths, which are in
+this order: @file{HOME/.ladspa/lib/}, @file{/usr/local/lib/ladspa/},
+ at file{/usr/lib/ladspa/}.
+
+ at item plugin, p
+Specifies the plugin within the library. Some libraries contain only
+one plugin, but others contain many of them. If this is not set filter
+will list all available plugins within the specified library.
+
+ at item controls, c
+Set the '|' separated list of controls which are zero or more floating point
+values that determine the behavior of the loaded plugin (for example delay,
+threshold or gain).
+Controls need to be defined using the following syntax:
+c0=@var{value0}|c1=@var{value1}|c2=@var{value2}|..., where
+ at var{valuei} is the value set on the @var{i}-th control.
+If @option{controls} is set to @code{help}, all available controls and
+their valid ranges are printed.
+
+ at item sample_rate, s
+Specify the sample rate, default to 44100. Only used if plugin have
+zero inputs.
+
+ at item nb_samples, n
+Set the number of samples per channel per each output frame, default
+is 1024. Only used if plugin have zero inputs.
+
+ at item duration, d
+Set the minimum duration of the sourced audio. See
+ at ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}
+for the accepted syntax.
+Note that the resulting duration may be greater than the specified duration,
+as the generated audio is always cut at the end of a complete frame.
+If not specified, or the expressed duration is negative, the audio is
+supposed to be generated forever.
+Only used if plugin have zero inputs.
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+List all available plugins within amp (LADSPA example plugin) library:
+ at example
+ladspa=file=amp
+ at end example
+
+ at item
+List all available controls and their valid ranges for @code{vcf_notch}
+plugin from @code{VCF} library:
+ at example
+ladspa=f=vcf:p=vcf_notch:c=help
+ at end example
+
+ at item
+Simulate low quality audio equipment using @code{Computer Music Toolkit} (CMT)
+plugin library:
+ at example
+ladspa=file=cmt:plugin=lofi:controls=c0=22|c1=12|c2=12
+ at end example
+
+ at item
+Add reverberation to the audio using TAP-plugins
+(Tom's Audio Processing plugins):
+ at example
+ladspa=file=tap_reverb:tap_reverb
+ at end example
+
+ at item
+Generate white noise, with 0.2 amplitude:
+ at example
+ladspa=file=cmt:noise_source_white:c=c0=.2
+ at end example
+
+ at item
+Generate 20 bpm clicks using plugin @code{C* Click - Metronome} from the
+ at code{C* Audio Plugin Suite} (CAPS) library:
+ at example
+ladspa=file=caps:Click:c=c1=20'
+ at end example
+
+ at item
+Apply @code{C* Eq10X2 - Stereo 10-band equaliser} effect:
+ at example
+ladspa=caps:Eq10X2:c=c0=-48|c9=-24|c3=12|c4=2
+ at end example
+ at end itemize
+
+ at subsection Commands
+
+This filter supports the following commands:
+ at table @option
+ at item cN
+Modify the @var{N}-th control value.
+
+If the specified value is not valid, it is ignored and prior one is kept.
+ at end table
+
+ at section lowpass
+
+Apply a low-pass filter with 3dB point frequency.
+The filter can be either single-pole or double-pole (the default).
+The filter roll off at 6dB per pole per octave (20dB per pole per decade).
+
+The filter accepts the following options:
+
+ at table @option
+ at item frequency, f
+Set frequency in Hz. Default is 500.
+
+ at item poles, p
+Set number of poles. Default is 2.
+
+ at item width_type
+Set method to specify band-width of filter.
+ at table @option
+ at item h
+Hz
+ at item q
+Q-Factor
+ at item o
+octave
+ at item s
+slope
+ at end table
+
+ at item width, w
+Specify the band-width of a filter in width_type units.
+Applies only to double-pole filter.
+The default is 0.707q and gives a Butterworth response.
+ at end table
+
+ at anchor{pan}
+ at section pan
+
+Mix channels with specific gain levels. The filter accepts the output
+channel layout followed by a set of channels definitions.
+
+This filter is also designed to efficiently remap the channels of an audio
+stream.
+
+The filter accepts parameters of the form:
+"@var{l}|@var{outdef}|@var{outdef}|..."
+
+ at table @option
+ at item l
+output channel layout or number of channels
+
+ at item outdef
+output channel specification, of the form:
+"@var{out_name}=[@var{gain}*]@var{in_name}[+[@var{gain}*]@var{in_name}...]"
+
+ at item out_name
+output channel to define, either a channel name (FL, FR, etc.) or a channel
+number (c0, c1, etc.)
+
+ at item gain
+multiplicative coefficient for the channel, 1 leaving the volume unchanged
+
+ at item in_name
+input channel to use, see out_name for details; it is not possible to mix
+named and numbered input channels
+ at end table
+
+If the `=' in a channel specification is replaced by `<', then the gains for
+that specification will be renormalized so that the total is 1, thus
+avoiding clipping noise.
+
+ at subsection Mixing examples
+
+For example, if you want to down-mix from stereo to mono, but with a bigger
+factor for the left channel:
+ at example
+pan=1c|c0=0.9*c0+0.1*c1
+ at end example
+
+A customized down-mix to stereo that works automatically for 3-, 4-, 5- and
+7-channels surround:
+ at example
+pan=stereo| FL < FL + 0.5*FC + 0.6*BL + 0.6*SL | FR < FR + 0.5*FC + 0.6*BR + 0.6*SR
+ at end example
+
+Note that @command{ffmpeg} integrates a default down-mix (and up-mix) system
+that should be preferred (see "-ac" option) unless you have very specific
+needs.
+
+ at subsection Remapping examples
+
+The channel remapping will be effective if, and only if:
+
+ at itemize
+ at item gain coefficients are zeroes or ones,
+ at item only one input per channel output,
+ at end itemize
+
+If all these conditions are satisfied, the filter will notify the user ("Pure
+channel mapping detected"), and use an optimized and lossless method to do the
+remapping.
+
+For example, if you have a 5.1 source and want a stereo audio stream by
+dropping the extra channels:
+ at example
+pan="stereo| c0=FL | c1=FR"
+ at end example
+
+Given the same source, you can also switch front left and front right channels
+and keep the input channel layout:
+ at example
+pan="5.1| c0=c1 | c1=c0 | c2=c2 | c3=c3 | c4=c4 | c5=c5"
+ at end example
+
+If the input is a stereo audio stream, you can mute the front left channel (and
+still keep the stereo channel layout) with:
+ at example
+pan="stereo|c1=c1"
+ at end example
+
+Still with a stereo audio stream input, you can copy the right channel in both
+front left and right:
+ at example
+pan="stereo| c0=FR | c1=FR"
+ at end example
+
+ at section replaygain
+
+ReplayGain scanner filter. This filter takes an audio stream as an input and
+outputs it unchanged.
+At end of filtering it displays @code{track_gain} and @code{track_peak}.
+
+ at section resample
+
+Convert the audio sample format, sample rate and channel layout. It is
+not meant to be used directly.
+
+ at section sidechaincompress
+
+This filter acts like normal compressor but has the ability to compress
+detected signal using second input signal.
+It needs two input streams and returns one output stream.
+First input stream will be processed depending on second stream signal.
+The filtered signal then can be filtered with other filters in later stages of
+processing. See @ref{pan} and @ref{amerge} filter.
+
+The filter accepts the following options:
+
+ at table @option
+ at item threshold
+If a signal of second stream raises above this level it will affect the gain
+reduction of first stream.
+By default is 0.125. Range is between 0.00097563 and 1.
+
+ at item ratio
+Set a ratio about which the signal is reduced. 1:2 means that if the level
+raised 4dB above the threshold, it will be only 2dB above after the reduction.
+Default is 2. Range is between 1 and 20.
+
+ at item attack
+Amount of milliseconds the signal has to rise above the threshold before gain
+reduction starts. Default is 20. Range is between 0.01 and 2000.
+
+ at item release
+Amount of milliseconds the signal has to fall below the threshold before
+reduction is decreased again. Default is 250. Range is between 0.01 and 9000.
+
+ at item makeup
+Set the amount by how much signal will be amplified after processing.
+Default is 2. Range is from 1 and 64.
+
+ at item knee
+Curve the sharp knee around the threshold to enter gain reduction more softly.
+Default is 2.82843. Range is between 1 and 8.
+
+ at item link
+Choose if the @code{average} level between all channels of side-chain stream
+or the louder(@code{maximum}) channel of side-chain stream affects the
+reduction. Default is @code{average}.
+
+ at item detection
+Should the exact signal be taken in case of @code{peak} or an RMS one in case
+of @code{rms}. Default is @code{rms} which is mainly smoother.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Full ffmpeg example taking 2 audio inputs, 1st input to be compressed
+depending on the signal of 2nd input and later compressed signal to be
+merged with 2nd input:
+ at example
+ffmpeg -i main.flac -i sidechain.flac -filter_complex "[1:a]asplit=2[sc][mix];[0:a][sc]sidechaincompress[compr];[compr][mix]amerge"
+ at end example
+ at end itemize
+
+ at section silencedetect
+
+Detect silence in an audio stream.
+
+This filter logs a message when it detects that the input audio volume is less
+or equal to a noise tolerance value for a duration greater or equal to the
+minimum detected noise duration.
+
+The printed times and duration are expressed in seconds.
+
+The filter accepts the following options:
+
+ at table @option
+ at item duration, d
+Set silence duration until notification (default is 2 seconds).
+
+ at item noise, n
+Set noise tolerance. Can be specified in dB (in case "dB" is appended to the
+specified value) or amplitude ratio. Default is -60dB, or 0.001.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Detect 5 seconds of silence with -50dB noise tolerance:
+ at example
+silencedetect=n=-50dB:d=5
+ at end example
+
+ at item
+Complete example with @command{ffmpeg} to detect silence with 0.0001 noise
+tolerance in @file{silence.mp3}:
+ at example
+ffmpeg -i silence.mp3 -af silencedetect=noise=0.0001 -f null -
+ at end example
+ at end itemize
+
+ at section silenceremove
+
+Remove silence from the beginning, middle or end of the audio.
+
+The filter accepts the following options:
+
+ at table @option
+ at item start_periods
+This value is used to indicate if audio should be trimmed at beginning of
+the audio. A value of zero indicates no silence should be trimmed from the
+beginning. When specifying a non-zero value, it trims audio up until it
+finds non-silence. Normally, when trimming silence from beginning of audio
+the @var{start_periods} will be @code{1} but it can be increased to higher
+values to trim all audio up to specific count of non-silence periods.
+Default value is @code{0}.
+
+ at item start_duration
+Specify the amount of time that non-silence must be detected before it stops
+trimming audio. By increasing the duration, bursts of noises can be treated
+as silence and trimmed off. Default value is @code{0}.
+
+ at item start_threshold
+This indicates what sample value should be treated as silence. For digital
+audio, a value of @code{0} may be fine but for audio recorded from analog,
+you may wish to increase the value to account for background noise.
+Can be specified in dB (in case "dB" is appended to the specified value)
+or amplitude ratio. Default value is @code{0}.
+
+ at item stop_periods
+Set the count for trimming silence from the end of audio.
+To remove silence from the middle of a file, specify a @var{stop_periods}
+that is negative. This value is then treated as a positive value and is
+used to indicate the effect should restart processing as specified by
+ at var{start_periods}, making it suitable for removing periods of silence
+in the middle of the audio.
+Default value is @code{0}.
+
+ at item stop_duration
+Specify a duration of silence that must exist before audio is not copied any
+more. By specifying a higher duration, silence that is wanted can be left in
+the audio.
+Default value is @code{0}.
+
+ at item stop_threshold
+This is the same as @option{start_threshold} but for trimming silence from
+the end of audio.
+Can be specified in dB (in case "dB" is appended to the specified value)
+or amplitude ratio. Default value is @code{0}.
+
+ at item leave_silence
+This indicate that @var{stop_duration} length of audio should be left intact
+at the beginning of each period of silence.
+For example, if you want to remove long pauses between words but do not want
+to remove the pauses completely. Default value is @code{0}.
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+The following example shows how this filter can be used to start a recording
+that does not contain the delay at the start which usually occurs between
+pressing the record button and the start of the performance:
+ at example
+silenceremove=1:5:0.02
+ at end example
+ at end itemize
+
+ at section treble
+
+Boost or cut treble (upper) frequencies of the audio using a two-pole
+shelving filter with a response similar to that of a standard
+hi-fi's tone-controls. This is also known as shelving equalisation (EQ).
+
+The filter accepts the following options:
+
+ at table @option
+ at item gain, g
+Give the gain at whichever is the lower of ~22 kHz and the
+Nyquist frequency. Its useful range is about -20 (for a large cut)
+to +20 (for a large boost). Beware of clipping when using a positive gain.
+
+ at item frequency, f
+Set the filter's central frequency and so can be used
+to extend or reduce the frequency range to be boosted or cut.
+The default value is @code{3000} Hz.
+
+ at item width_type
+Set method to specify band-width of filter.
+ at table @option
+ at item h
+Hz
+ at item q
+Q-Factor
+ at item o
+octave
+ at item s
+slope
+ at end table
+
+ at item width, w
+Determine how steep is the filter's shelf transition.
+ at end table
+
+ at section volume
+
+Adjust the input audio volume.
+
+It accepts the following parameters:
+ at table @option
+
+ at item volume
+Set audio volume expression.
+
+Output values are clipped to the maximum value.
+
+The output audio volume is given by the relation:
+ at example
+ at var{output_volume} = @var{volume} * @var{input_volume}
+ at end example
+
+The default value for @var{volume} is "1.0".
+
+ at item precision
+This parameter represents the mathematical precision.
+
+It determines which input sample formats will be allowed, which affects the
+precision of the volume scaling.
+
+ at table @option
+ at item fixed
+8-bit fixed-point; this limits input sample format to U8, S16, and S32.
+ at item float
+32-bit floating-point; this limits input sample format to FLT. (default)
+ at item double
+64-bit floating-point; this limits input sample format to DBL.
+ at end table
+
+ at item replaygain
+Choose the behaviour on encountering ReplayGain side data in input frames.
+
+ at table @option
+ at item drop
+Remove ReplayGain side data, ignoring its contents (the default).
+
+ at item ignore
+Ignore ReplayGain side data, but leave it in the frame.
+
+ at item track
+Prefer the track gain, if present.
+
+ at item album
+Prefer the album gain, if present.
+ at end table
+
+ at item replaygain_preamp
+Pre-amplification gain in dB to apply to the selected replaygain gain.
+
+Default value for @var{replaygain_preamp} is 0.0.
+
+ at item eval
+Set when the volume expression is evaluated.
+
+It accepts the following values:
+ at table @samp
+ at item once
+only evaluate expression once during the filter initialization, or
+when the @samp{volume} command is sent
+
+ at item frame
+evaluate expression for each incoming frame
+ at end table
+
+Default value is @samp{once}.
+ at end table
+
+The volume expression can contain the following parameters.
+
+ at table @option
+ at item n
+frame number (starting at zero)
+ at item nb_channels
+number of channels
+ at item nb_consumed_samples
+number of samples consumed by the filter
+ at item nb_samples
+number of samples in the current frame
+ at item pos
+original frame position in the file
+ at item pts
+frame PTS
+ at item sample_rate
+sample rate
+ at item startpts
+PTS at start of stream
+ at item startt
+time at start of stream
+ at item t
+frame time
+ at item tb
+timestamp timebase
+ at item volume
+last set volume value
+ at end table
+
+Note that when @option{eval} is set to @samp{once} only the
+ at var{sample_rate} and @var{tb} variables are available, all other
+variables will evaluate to NAN.
+
+ at subsection Commands
+
+This filter supports the following commands:
+ at table @option
+ at item volume
+Modify the volume expression.
+The command accepts the same syntax of the corresponding option.
+
+If the specified expression is not valid, it is kept at its current
+value.
+ at item replaygain_noclip
+Prevent clipping by limiting the gain applied.
+
+Default value for @var{replaygain_noclip} is 1.
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Halve the input audio volume:
+ at example
+volume=volume=0.5
+volume=volume=1/2
+volume=volume=-6.0206dB
+ at end example
+
+In all the above example the named key for @option{volume} can be
+omitted, for example like in:
+ at example
+volume=0.5
+ at end example
+
+ at item
+Increase input audio power by 6 decibels using fixed-point precision:
+ at example
+volume=volume=6dB:precision=fixed
+ at end example
+
+ at item
+Fade volume after time 10 with an annihilation period of 5 seconds:
+ at example
+volume='if(lt(t,10),1,max(1-(t-10)/5,0))':eval=frame
+ at end example
+ at end itemize
+
+ at section volumedetect
+
+Detect the volume of the input video.
+
+The filter has no parameters. The input is not modified. Statistics about
+the volume will be printed in the log when the input stream end is reached.
+
+In particular it will show the mean volume (root mean square), maximum
+volume (on a per-sample basis), and the beginning of a histogram of the
+registered volume values (from the maximum value to a cumulated 1/1000 of
+the samples).
+
+All volumes are in decibels relative to the maximum PCM value.
+
+ at subsection Examples
+
+Here is an excerpt of the output:
+ at example
+[Parsed_volumedetect_0 @ 0xa23120] mean_volume: -27 dB
+[Parsed_volumedetect_0 @ 0xa23120] max_volume: -4 dB
+[Parsed_volumedetect_0 @ 0xa23120] histogram_4db: 6
+[Parsed_volumedetect_0 @ 0xa23120] histogram_5db: 62
+[Parsed_volumedetect_0 @ 0xa23120] histogram_6db: 286
+[Parsed_volumedetect_0 @ 0xa23120] histogram_7db: 1042
+[Parsed_volumedetect_0 @ 0xa23120] histogram_8db: 2551
+[Parsed_volumedetect_0 @ 0xa23120] histogram_9db: 4609
+[Parsed_volumedetect_0 @ 0xa23120] histogram_10db: 8409
+ at end example
+
+It means that:
+ at itemize
+ at item
+The mean square energy is approximately -27 dB, or 10^-2.7.
+ at item
+The largest sample is at -4 dB, or more precisely between -4 dB and -5 dB.
+ at item
+There are 6 samples at -4 dB, 62 at -5 dB, 286 at -6 dB, etc.
+ at end itemize
+
+In other words, raising the volume by +4 dB does not cause any clipping,
+raising it by +5 dB causes clipping for 6 samples, etc.
+
+ at c man end AUDIO FILTERS
+
+ at chapter Audio Sources
+ at c man begin AUDIO SOURCES
+
+Below is a description of the currently available audio sources.
+
+ at section abuffer
+
+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}.
+
+It accepts the following parameters:
+ at table @option
+
+ at item time_base
+The timebase which will be used for timestamps of submitted frames. It must be
+either a floating-point number or in @var{numerator}/@var{denominator} form.
+
+ at item sample_rate
+The sample rate of the incoming audio buffers.
+
+ at item sample_fmt
+The sample format of the incoming audio buffers.
+Either a sample format name or its corresponding integer representation from
+the enum AVSampleFormat in @file{libavutil/samplefmt.h}
+
+ at item channel_layout
+The channel layout of the incoming audio buffers.
+Either a channel layout name from channel_layout_map in
+ at file{libavutil/channel_layout.c} or its corresponding integer representation
+from the AV_CH_LAYOUT_* macros in @file{libavutil/channel_layout.h}
+
+ at item channels
+The number of channels of the incoming audio buffers.
+If both @var{channels} and @var{channel_layout} are specified, then they
+must be consistent.
+
+ at end table
+
+ at subsection Examples
+
+ at example
+abuffer=sample_rate=44100:sample_fmt=s16p:channel_layout=stereo
+ at end example
+
+will instruct the source to accept planar 16bit signed stereo at 44100Hz.
+Since the sample format with name "s16p" corresponds to the number
+6 and the "stereo" channel layout corresponds to the value 0x3, this is
+equivalent to:
+ at example
+abuffer=sample_rate=44100:sample_fmt=6:channel_layout=0x3
+ at end example
+
+ at section aevalsrc
+
+Generate an audio signal specified by an expression.
+
+This source accepts in input one or more expressions (one for each
+channel), which are evaluated and used to generate a corresponding
+audio signal.
+
+This source accepts the following options:
+
+ at table @option
+ at item exprs
+Set the '|'-separated expressions list for each separate channel. In case the
+ at option{channel_layout} option is not specified, the selected channel layout
+depends on the number of provided expressions. Otherwise the last
+specified expression is applied to the remaining output channels.
+
+ at item channel_layout, c
+Set the channel layout. The number of channels in the specified layout
+must be equal to the number of specified expressions.
+
+ at item duration, d
+Set the minimum duration of the sourced audio. See
+ at ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}
+for the accepted syntax.
+Note that the resulting duration may be greater than the specified
+duration, as the generated audio is always cut at the end of a
+complete frame.
+
+If not specified, or the expressed duration is negative, the audio is
+supposed to be generated forever.
+
+ at item nb_samples, n
+Set the number of samples per channel per each output frame,
+default to 1024.
+
+ at item sample_rate, s
+Specify the sample rate, default to 44100.
+ at end table
+
+Each expression in @var{exprs} can contain the following constants:
+
+ at table @option
+ at item n
+number of the evaluated sample, starting from 0
+
+ at item t
+time of the evaluated sample expressed in seconds, starting from 0
+
+ at item s
+sample rate
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Generate silence:
+ at example
+aevalsrc=0
+ at end example
+
+ at item
+Generate a sin signal with frequency of 440 Hz, set sample rate to
+8000 Hz:
+ at example
+aevalsrc="sin(440*2*PI*t):s=8000"
+ at end example
+
+ at item
+Generate a two channels signal, specify the channel layout (Front
+Center + Back Center) explicitly:
+ at example
+aevalsrc="sin(420*2*PI*t)|cos(430*2*PI*t):c=FC|BC"
+ at end example
+
+ at item
+Generate white noise:
+ at example
+aevalsrc="-2+random(0)"
+ at end example
+
+ at item
+Generate an amplitude modulated signal:
+ at example
+aevalsrc="sin(10*2*PI*t)*sin(880*2*PI*t)"
+ at end example
+
+ at item
+Generate 2.5 Hz binaural beats on a 360 Hz carrier:
+ at example
+aevalsrc="0.1*sin(2*PI*(360-2.5/2)*t) | 0.1*sin(2*PI*(360+2.5/2)*t)"
+ at end example
+
+ at end itemize
+
+ at section anullsrc
+
+The null audio source, return unprocessed audio frames. It is mainly useful
+as a template and to be employed in analysis / debugging tools, or as
+the source for filters which ignore the input data (for example the sox
+synth filter).
+
+This source accepts the following options:
+
+ at table @option
+
+ at item channel_layout, cl
+
+Specifies the channel layout, and can be either an integer or a string
+representing a channel layout. The default value of @var{channel_layout}
+is "stereo".
+
+Check the channel_layout_map definition in
+ at file{libavutil/channel_layout.c} for the mapping between strings and
+channel layout values.
+
+ at item sample_rate, r
+Specifies the sample rate, and defaults to 44100.
+
+ at item nb_samples, n
+Set the number of samples per requested frames.
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Set the sample rate to 48000 Hz and the channel layout to AV_CH_LAYOUT_MONO.
+ at example
+anullsrc=r=48000:cl=4
+ at end example
+
+ at item
+Do the same operation with a more obvious syntax:
+ at example
+anullsrc=r=48000:cl=mono
+ at end example
+ at end itemize
+
+All the parameters need to be explicitly defined.
+
+ at section flite
+
+Synthesize a voice utterance using the libflite library.
+
+To enable compilation of this filter you need to configure FFmpeg with
+ at code{--enable-libflite}.
+
+Note that the flite library is not thread-safe.
+
+The filter accepts the following options:
+
+ at table @option
+
+ at item list_voices
+If set to 1, list the names of the available voices and exit
+immediately. Default value is 0.
+
+ at item nb_samples, n
+Set the maximum number of samples per frame. Default value is 512.
+
+ at item textfile
+Set the filename containing the text to speak.
+
+ at item text
+Set the text to speak.
+
+ at item voice, v
+Set the voice to use for the speech synthesis. Default value is
+ at code{kal}. See also the @var{list_voices} option.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Read from file @file{speech.txt}, and synthesize the text using the
+standard flite voice:
+ at example
+flite=textfile=speech.txt
+ at end example
+
+ at item
+Read the specified text selecting the @code{slt} voice:
+ at example
+flite=text='So fare thee well, poor devil of a Sub-Sub, whose commentator I am':voice=slt
+ at end example
+
+ at item
+Input text to ffmpeg:
+ at example
+ffmpeg -f lavfi -i flite=text='So fare thee well, poor devil of a Sub-Sub, whose commentator I am':voice=slt
+ at end example
+
+ at item
+Make @file{ffplay} speak the specified text, using @code{flite} and
+the @code{lavfi} device:
+ at example
+ffplay -f lavfi flite=text='No more be grieved for which that thou hast done.'
+ at end example
+ at end itemize
+
+For more information about libflite, check:
+ at url{http://www.speech.cs.cmu.edu/flite/}
+
+ at section sine
+
+Generate an audio signal made of a sine wave with amplitude 1/8.
+
+The audio signal is bit-exact.
+
+The filter accepts the following options:
+
+ at table @option
+
+ at item frequency, f
+Set the carrier frequency. Default is 440 Hz.
+
+ at item beep_factor, b
+Enable a periodic beep every second with frequency @var{beep_factor} times
+the carrier frequency. Default is 0, meaning the beep is disabled.
+
+ at item sample_rate, r
+Specify the sample rate, default is 44100.
+
+ at item duration, d
+Specify the duration of the generated audio stream.
+
+ at item samples_per_frame
+Set the number of samples per output frame, default is 1024.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+
+ at item
+Generate a simple 440 Hz sine wave:
+ at example
+sine
+ at end example
+
+ at item
+Generate a 220 Hz sine wave with a 880 Hz beep each second, for 5 seconds:
+ at example
+sine=220:4:d=5
+sine=f=220:b=4:d=5
+sine=frequency=220:beep_factor=4:duration=5
+ at end example
+
+ at end itemize
+
+ at c man end AUDIO SOURCES
+
+ at chapter Audio Sinks
+ at c man begin AUDIO SINKS
+
+Below is a description of the currently available audio sinks.
+
+ at section abuffersink
+
+Buffer audio frames, and make them available to the end of filter chain.
+
+This sink is mainly intended for programmatic use, in particular
+through the interface defined in @file{libavfilter/buffersink.h}
+or the options system.
+
+It accepts a pointer to an AVABufferSinkContext structure, which
+defines the incoming buffers' formats, to be passed as the opaque
+parameter to @code{avfilter_init_filter} for initialization.
+ at section anullsink
+
+Null audio sink; do absolutely nothing with the input audio. It is
+mainly useful as a template and for use in analysis / debugging
+tools.
+
+ at c man end AUDIO SINKS
+
+ at chapter Video Filters
+ at c man begin VIDEO FILTERS
+
+When you configure your FFmpeg build, you can disable any of the
+existing filters using @code{--disable-filters}.
+The configure output will show the video filters included in your
+build.
+
+Below is a description of the currently available video filters.
+
+ at section alphaextract
+
+Extract the alpha component from the input as a grayscale video. This
+is especially useful with the @var{alphamerge} filter.
+
+ at section alphamerge
+
+Add or replace the alpha component of the primary input with the
+grayscale value of a second input. This is intended for use with
+ at var{alphaextract} to allow the transmission or storage of frame
+sequences that have alpha in a format that doesn't support an alpha
+channel.
+
+For example, to reconstruct full frames from a normal YUV-encoded video
+and a separate video created with @var{alphaextract}, you might use:
+ at example
+movie=in_alpha.mkv [alpha]; [in][alpha] alphamerge [out]
+ at 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.
+
+ at section ass
+
+Same as the @ref{subtitles} filter, except that it doesn't require libavcodec
+and libavformat to work. On the other hand, it is limited to ASS (Advanced
+Substation Alpha) subtitles files.
+
+This filter accepts the following option in addition to the common options from
+the @ref{subtitles} filter:
+
+ at table @option
+ at item shaping
+Set the shaping engine
+
+Available values are:
+ at table @samp
+ at item auto
+The default libass shaping engine, which is the best available.
+ at item simple
+Fast, font-agnostic shaper that can do only substitutions
+ at item complex
+Slower shaper using OpenType for substitutions and positioning
+ at end table
+
+The default is @code{auto}.
+ at end table
+
+ at section atadenoise
+Apply an Adaptive Temporal Averaging Denoiser to the video input.
+
+The filter accepts the following options:
+
+ at table @option
+ at item 0a
+Set threshold A for 1st plane. Default is 0.02.
+Valid range is 0 to 0.3.
+
+ at item 0b
+Set threshold B for 1st plane. Default is 0.04.
+Valid range is 0 to 5.
+
+ at item 1a
+Set threshold A for 2nd plane. Default is 0.02.
+Valid range is 0 to 0.3.
+
+ at item 1b
+Set threshold B for 2nd plane. Default is 0.04.
+Valid range is 0 to 5.
+
+ at item 2a
+Set threshold A for 3rd plane. Default is 0.02.
+Valid range is 0 to 0.3.
+
+ at item 2b
+Set threshold B for 3rd plane. Default is 0.04.
+Valid range is 0 to 5.
+
+Threshold A is designed to react on abrupt changes in the input signal and
+threshold B is designed to react on continuous changes in the input signal.
+
+ at item s
+Set number of frames filter will use for averaging. Default is 33. Must be odd
+number in range [5, 129].
+ at end table
+
+ at section bbox
+
+Compute the bounding box for the non-black pixels in the input frame
+luminance plane.
+
+This filter computes the bounding box containing all the pixels with a
+luminance value greater than the minimum allowed value.
+The parameters describing the bounding box are printed on the filter
+log.
+
+The filter accepts the following option:
+
+ at table @option
+ at item min_val
+Set the minimal luminance value. Default is @code{16}.
+ at end table
+
+ at section blackdetect
+
+Detect video intervals that are (almost) completely black. Can be
+useful to detect chapter transitions, commercials, or invalid
+recordings. Output lines contains the time for the start, end and
+duration of the detected black interval expressed in seconds.
+
+In order to display the output lines, you need to set the loglevel at
+least to the AV_LOG_INFO value.
+
+The filter accepts the following options:
+
+ at table @option
+ at item black_min_duration, d
+Set the minimum detected black duration expressed in seconds. It must
+be a non-negative floating point number.
+
+Default value is 2.0.
+
+ at item picture_black_ratio_th, pic_th
+Set the threshold for considering a picture "black".
+Express the minimum value for the ratio:
+ at example
+ at var{nb_black_pixels} / @var{nb_pixels}
+ at end example
+
+for which a picture is considered black.
+Default value is 0.98.
+
+ at item pixel_black_th, pix_th
+Set the threshold for considering a pixel "black".
+
+The threshold expresses the maximum pixel luminance value for which a
+pixel is considered "black". The provided value is scaled according to
+the following equation:
+ at example
+ at var{absolute_threshold} = @var{luminance_minimum_value} + @var{pixel_black_th} * @var{luminance_range_size}
+ at end example
+
+ at var{luminance_range_size} and @var{luminance_minimum_value} depend on
+the input video format, the range is [0-255] for YUV full-range
+formats and [16-235] for YUV non full-range formats.
+
+Default value is 0.10.
+ at end table
+
+The following example sets the maximum pixel threshold to the minimum
+value, and detects only black intervals of 2 or more seconds:
+ at example
+blackdetect=d=2:pix_th=0.00
+ at end example
+
+ at section blackframe
+
+Detect frames that are (almost) completely black. Can be useful to
+detect chapter transitions or commercials. Output lines consist of
+the frame number of the detected frame, the percentage of blackness,
+the position in the file if known or -1 and the timestamp in seconds.
+
+In order to display the output lines, you need to set the loglevel at
+least to the AV_LOG_INFO value.
+
+It accepts the following parameters:
+
+ at table @option
+
+ at item amount
+The percentage of the pixels that have to be below the threshold; it defaults to
+ at code{98}.
+
+ at item threshold, thresh
+The threshold below which a pixel value is considered black; it defaults to
+ at code{32}.
+
+ at end table
+
+ at section blend, tblend
+
+Blend two video frames into each other.
+
+The @code{blend} filter takes two input streams and outputs one
+stream, the first input is the "top" layer and second input is
+"bottom" layer. Output terminates when shortest input terminates.
+
+The @code{tblend} (time blend) filter takes two consecutive frames
+from one single stream, and outputs the result obtained by blending
+the new frame on top of the old frame.
+
+A description of the accepted options follows.
+
+ at table @option
+ at item c0_mode
+ at item c1_mode
+ at item c2_mode
+ at item c3_mode
+ at item all_mode
+Set blend mode for specific pixel component or all pixel components in case
+of @var{all_mode}. Default value is @code{normal}.
+
+Available values for component modes are:
+ at table @samp
+ at item addition
+ at item and
+ at item average
+ at item burn
+ at item darken
+ at item difference
+ at item difference128
+ at item divide
+ at item dodge
+ at item exclusion
+ at item glow
+ at item hardlight
+ at item hardmix
+ at item lighten
+ at item linearlight
+ at item multiply
+ at item negation
+ at item normal
+ at item or
+ at item overlay
+ at item phoenix
+ at item pinlight
+ at item reflect
+ at item screen
+ at item softlight
+ at item subtract
+ at item vividlight
+ at item xor
+ at end table
+
+ at item c0_opacity
+ at item c1_opacity
+ at item c2_opacity
+ at item c3_opacity
+ at item all_opacity
+Set blend opacity for specific pixel component or all pixel components in case
+of @var{all_opacity}. Only used in combination with pixel component blend modes.
+
+ at item c0_expr
+ at item c1_expr
+ at item c2_expr
+ at item c3_expr
+ at item all_expr
+Set blend expression for specific pixel component or all pixel components in case
+of @var{all_expr}. Note that related mode options will be ignored if those are set.
+
+The expressions can use the following variables:
+
+ at table @option
+ at item N
+The sequential number of the filtered frame, starting from @code{0}.
+
+ at item X
+ at item Y
+the coordinates of the current sample
+
+ at item W
+ at item H
+the width and height of currently filtered plane
+
+ at item SW
+ at item SH
+Width and height scale depending on the currently filtered plane. It is the
+ratio between the corresponding luma plane number of pixels and the current
+plane ones. E.g. for YUV4:2:0 the values are @code{1,1} for the luma plane, and
+ at code{0.5,0.5} for chroma planes.
+
+ at item T
+Time of the current frame, expressed in seconds.
+
+ at item TOP, A
+Value of pixel component at current location for first video frame (top layer).
+
+ at item BOTTOM, B
+Value of pixel component at current location for second video frame (bottom layer).
+ at end table
+
+ at item shortest
+Force termination when the shortest input terminates. Default is
+ at code{0}. This option is only defined for the @code{blend} filter.
+
+ at item repeatlast
+Continue applying the last bottom frame after the end of the stream. A value of
+ at code{0} disable the filter after the last frame of the bottom layer is reached.
+Default is @code{1}. This option is only defined for the @code{blend} filter.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Apply transition from bottom layer to top layer in first 10 seconds:
+ at example
+blend=all_expr='A*(if(gte(T,10),1,T/10))+B*(1-(if(gte(T,10),1,T/10)))'
+ at end example
+
+ at item
+Apply 1x1 checkerboard effect:
+ at example
+blend=all_expr='if(eq(mod(X,2),mod(Y,2)),A,B)'
+ at end example
+
+ at item
+Apply uncover left effect:
+ at example
+blend=all_expr='if(gte(N*SW+X,W),A,B)'
+ at end example
+
+ at item
+Apply uncover down effect:
+ at example
+blend=all_expr='if(gte(Y-N*SH,0),A,B)'
+ at end example
+
+ at item
+Apply uncover up-left effect:
+ at example
+blend=all_expr='if(gte(T*SH*40+Y,H)*gte((T*40*SW+X)*W/H,W),A,B)'
+ at end example
+
+ at item
+Display differences between the current and the previous frame:
+ at example
+tblend=all_mode=difference128
+ at end example
+ at end itemize
+
+ at section boxblur
+
+Apply a boxblur algorithm to the input video.
+
+It accepts the following parameters:
+
+ at table @option
+
+ at item luma_radius, lr
+ at item luma_power, lp
+ at item chroma_radius, cr
+ at item chroma_power, cp
+ at item alpha_radius, ar
+ at item alpha_power, ap
+
+ at end table
+
+A description of the accepted options follows.
+
+ at table @option
+ at item luma_radius, lr
+ at item chroma_radius, cr
+ at item alpha_radius, ar
+Set an expression for the box radius in pixels used for blurring the
+corresponding input plane.
+
+The radius value must be a non-negative number, and must not be
+greater than the value of the expression @code{min(w,h)/2} for the
+luma and alpha planes, and of @code{min(cw,ch)/2} for the chroma
+planes.
+
+Default value for @option{luma_radius} is "2". If not specified,
+ at option{chroma_radius} and @option{alpha_radius} default to the
+corresponding value set for @option{luma_radius}.
+
+The expressions can contain the following constants:
+ at table @option
+ at item w
+ at item h
+The input width and height in pixels.
+
+ at item cw
+ at item ch
+The input chroma image width and height in pixels.
+
+ at item hsub
+ at item vsub
+The horizontal and vertical chroma subsample values. For example, for the
+pixel format "yuv422p", @var{hsub} is 2 and @var{vsub} is 1.
+ at end table
+
+ at item luma_power, lp
+ at item chroma_power, cp
+ at item alpha_power, ap
+Specify how many times the boxblur filter is applied to the
+corresponding plane.
+
+Default value for @option{luma_power} is 2. If not specified,
+ at option{chroma_power} and @option{alpha_power} default to the
+corresponding value set for @option{luma_power}.
+
+A value of 0 will disable the effect.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Apply a boxblur filter with the luma, chroma, and alpha radii
+set to 2:
+ at example
+boxblur=luma_radius=2:luma_power=1
+boxblur=2:1
+ at end example
+
+ at item
+Set the luma radius to 2, and alpha and chroma radius to 0:
+ at example
+boxblur=2:1:cr=0:ar=0
+ at end example
+
+ at item
+Set the luma and chroma radii to a fraction of the video dimension:
+ at example
+boxblur=luma_radius=min(h\,w)/10:luma_power=1:chroma_radius=min(cw\,ch)/10:chroma_power=1
+ at end example
+ at end itemize
+
+ at section codecview
+
+Visualize information exported by some codecs.
+
+Some codecs can export information through frames using side-data or other
+means. For example, some MPEG based codecs export motion vectors through the
+ at var{export_mvs} flag in the codec @option{flags2} option.
+
+The filter accepts the following option:
+
+ at table @option
+ at item mv
+Set motion vectors to visualize.
+
+Available flags for @var{mv} are:
+
+ at table @samp
+ at item pf
+forward predicted MVs of P-frames
+ at item bf
+forward predicted MVs of B-frames
+ at item bb
+backward predicted MVs of B-frames
+ at end table
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Visualizes multi-directionals MVs from P and B-Frames using @command{ffplay}:
+ at example
+ffplay -flags2 +export_mvs input.mpg -vf codecview=mv=pf+bf+bb
+ at end example
+ at end itemize
+
+ at section colorbalance
+Modify intensity of primary colors (red, green and blue) of input frames.
+
+The filter allows an input frame to be adjusted in the shadows, midtones or highlights
+regions for the red-cyan, green-magenta or blue-yellow balance.
+
+A positive adjustment value shifts the balance towards the primary color, a negative
+value towards the complementary color.
+
+The filter accepts the following options:
+
+ at table @option
+ at item rs
+ at item gs
+ at item bs
+Adjust red, green and blue shadows (darkest pixels).
+
+ at item rm
+ at item gm
+ at item bm
+Adjust red, green and blue midtones (medium pixels).
+
+ at item rh
+ at item gh
+ at item bh
+Adjust red, green and blue highlights (brightest pixels).
+
+Allowed ranges for options are @code{[-1.0, 1.0]}. Defaults are @code{0}.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Add red color cast to shadows:
+ at example
+colorbalance=rs=.3
+ at end example
+ at end itemize
+
+ at section colorkey
+RGB colorspace color keying.
+
+The filter accepts the following options:
+
+ at table @option
+ at item color
+The color which will be replaced with transparency.
+
+ at item similarity
+Similarity percentage with the key color.
+
+0.01 matches only the exact key color, while 1.0 matches everything.
+
+ at item blend
+Blend percentage.
+
+0.0 makes pixels either fully transparent, or not transparent at all.
+
+Higher values result in semi-transparent pixels, with a higher transparency
+the more similar the pixels color is to the key color.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Make every green pixel in the input image transparent:
+ at example
+ffmpeg -i input.png -vf colorkey=green out.png
+ at end example
+
+ at item
+Overlay a greenscreen-video on top of a static background image.
+ at example
+ffmpeg -i background.png -i video.mp4 -filter_complex "[1:v]colorkey=0x3BBD1E:0.3:0.2[ckout];[0:v][ckout]overlay[out]" -map "[out]" output.flv
+ at end example
+ at end itemize
+
+ at section colorlevels
+
+Adjust video input frames using levels.
+
+The filter accepts the following options:
+
+ at table @option
+ at item rimin
+ at item gimin
+ at item bimin
+ at item aimin
+Adjust red, green, blue and alpha input black point.
+Allowed ranges for options are @code{[-1.0, 1.0]}. Defaults are @code{0}.
+
+ at item rimax
+ at item gimax
+ at item bimax
+ at item aimax
+Adjust red, green, blue and alpha input white point.
+Allowed ranges for options are @code{[-1.0, 1.0]}. Defaults are @code{1}.
+
+Input levels are used to lighten highlights (bright tones), darken shadows
+(dark tones), change the balance of bright and dark tones.
+
+ at item romin
+ at item gomin
+ at item bomin
+ at item aomin
+Adjust red, green, blue and alpha output black point.
+Allowed ranges for options are @code{[0, 1.0]}. Defaults are @code{0}.
+
+ at item romax
+ at item gomax
+ at item bomax
+ at item aomax
+Adjust red, green, blue and alpha output white point.
+Allowed ranges for options are @code{[0, 1.0]}. Defaults are @code{1}.
+
+Output levels allows manual selection of a constrained output level range.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Make video output darker:
+ at example
+colorlevels=rimin=0.058:gimin=0.058:bimin=0.058
+ at end example
+
+ at item
+Increase contrast:
+ at example
+colorlevels=rimin=0.039:gimin=0.039:bimin=0.039:rimax=0.96:gimax=0.96:bimax=0.96
+ at end example
+
+ at item
+Make video output lighter:
+ at example
+colorlevels=rimax=0.902:gimax=0.902:bimax=0.902
+ at end example
+
+ at item
+Increase brightness:
+ at example
+colorlevels=romin=0.5:gomin=0.5:bomin=0.5
+ at end example
+ at end itemize
+
+ at section colorchannelmixer
+
+Adjust video input frames by re-mixing color channels.
+
+This filter modifies a color channel by adding the values associated to
+the other channels of the same pixels. For example if the value to
+modify is red, the output value will be:
+ at example
+ at var{red}=@var{red}*@var{rr} + @var{blue}*@var{rb} + @var{green}*@var{rg} + @var{alpha}*@var{ra}
+ at end example
+
+The filter accepts the following options:
+
+ at table @option
+ at item rr
+ at item rg
+ at item rb
+ at item ra
+Adjust contribution of input red, green, blue and alpha channels for output red channel.
+Default is @code{1} for @var{rr}, and @code{0} for @var{rg}, @var{rb} and @var{ra}.
+
+ at item gr
+ at item gg
+ at item gb
+ at item ga
+Adjust contribution of input red, green, blue and alpha channels for output green channel.
+Default is @code{1} for @var{gg}, and @code{0} for @var{gr}, @var{gb} and @var{ga}.
+
+ at item br
+ at item bg
+ at item bb
+ at item ba
+Adjust contribution of input red, green, blue and alpha channels for output blue channel.
+Default is @code{1} for @var{bb}, and @code{0} for @var{br}, @var{bg} and @var{ba}.
+
+ at item ar
+ at item ag
+ at item ab
+ at item aa
+Adjust contribution of input red, green, blue and alpha channels for output alpha channel.
+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]}.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Convert source to grayscale:
+ at example
+colorchannelmixer=.3:.4:.3:0:.3:.4:.3:0:.3:.4:.3
+ at end example
+ at item
+Simulate sepia tones:
+ at example
+colorchannelmixer=.393:.769:.189:0:.349:.686:.168:0:.272:.534:.131
+ at end example
+ at end itemize
+
+ at section colormatrix
+
+Convert color matrix.
+
+The filter accepts the following options:
+
+ at table @option
+ at item src
+ at item dst
+Specify the source and destination color matrix. Both values must be
+specified.
+
+The accepted values are:
+ at table @samp
+ at item bt709
+BT.709
+
+ at item bt601
+BT.601
+
+ at item smpte240m
+SMPTE-240M
+
+ at item fcc
+FCC
+ at end table
+ at end table
+
+For example to convert from BT.601 to SMPTE-240M, use the command:
+ at example
+colormatrix=bt601:smpte240m
+ at end example
+
+ at section copy
+
+Copy the input source unchanged to the output. This is mainly useful for
+testing purposes.
+
+ at section crop
+
+Crop the input video to given dimensions.
+
+It accepts the following parameters:
+
+ at table @option
+ at item w, out_w
+The width of the output video. It defaults to @code{iw}.
+This expression is evaluated only once during the filter
+configuration, or when the @samp{w} or @samp{out_w} command is sent.
+
+ at item h, out_h
+The height of the output video. It defaults to @code{ih}.
+This expression is evaluated only once during the filter
+configuration, or when the @samp{h} or @samp{out_h} command is sent.
+
+ at item x
+The horizontal position, in the input video, of the left edge of the output
+video. It defaults to @code{(in_w-out_w)/2}.
+This expression is evaluated per-frame.
+
+ at item y
+The vertical position, in the input video, of the top edge of the output video.
+It defaults to @code{(in_h-out_h)/2}.
+This expression is evaluated per-frame.
+
+ at item keep_aspect
+If set to 1 will force the output display aspect ratio
+to be the same of the input, by changing the output sample aspect
+ratio. It defaults to 0.
+ at end table
+
+The @var{out_w}, @var{out_h}, @var{x}, @var{y} parameters are
+expressions containing the following constants:
+
+ at table @option
+ at item x
+ at item y
+The computed values for @var{x} and @var{y}. They are evaluated for
+each new frame.
+
+ at item in_w
+ at item in_h
+The input width and height.
+
+ at item iw
+ at item ih
+These are the same as @var{in_w} and @var{in_h}.
+
+ at item out_w
+ at item out_h
+The output (cropped) width and height.
+
+ at item ow
+ at item oh
+These are the same as @var{out_w} and @var{out_h}.
+
+ at item a
+same as @var{iw} / @var{ih}
+
+ at item sar
+input sample aspect ratio
+
+ at item dar
+input display aspect ratio, it is the same as (@var{iw} / @var{ih}) * @var{sar}
+
+ at item hsub
+ at item vsub
+horizontal and vertical chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+
+ at item n
+The number of the input frame, starting from 0.
+
+ at item pos
+the position in the file of the input frame, NAN if unknown
+
+ at item t
+The timestamp expressed in seconds. It's NAN if the input timestamp is unknown.
+
+ at end table
+
+The expression for @var{out_w} may depend on the value of @var{out_h},
+and the expression for @var{out_h} may depend on @var{out_w}, but they
+cannot depend on @var{x} and @var{y}, as @var{x} and @var{y} are
+evaluated after @var{out_w} and @var{out_h}.
+
+The @var{x} and @var{y} parameters specify the expressions for the
+position of the top-left corner of the output (non-cropped) area. They
+are evaluated for each frame. If the evaluated value is not valid, it
+is approximated to the nearest valid value.
+
+The expression for @var{x} may depend on @var{y}, and the expression
+for @var{y} may depend on @var{x}.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Crop area with size 100x100 at position (12,34).
+ at example
+crop=100:100:12:34
+ at end example
+
+Using named options, the example above becomes:
+ at example
+crop=w=100:h=100:x=12:y=34
+ at end example
+
+ at item
+Crop the central input area with size 100x100:
+ at example
+crop=100:100
+ at end example
+
+ at item
+Crop the central input area with size 2/3 of the input video:
+ at example
+crop=2/3*in_w:2/3*in_h
+ at end example
+
+ at item
+Crop the input video central square:
+ at example
+crop=out_w=in_h
+crop=in_h
+ at end example
+
+ at item
+Delimit the rectangle with the top-left corner placed at position
+100:100 and the right-bottom corner corresponding to the right-bottom
+corner of the input image.
+ at example
+crop=in_w-100:in_h-100:100:100
+ at end example
+
+ at item
+Crop 10 pixels from the left and right borders, and 20 pixels from
+the top and bottom borders
+ at example
+crop=in_w-2*10:in_h-2*20
+ at end example
+
+ at item
+Keep only the bottom right quarter of the input image:
+ at example
+crop=in_w/2:in_h/2:in_w/2:in_h/2
+ at end example
+
+ at item
+Crop height for getting Greek harmony:
+ at example
+crop=in_w:1/PHI*in_w
+ at end example
+
+ at item
+Apply trembling effect:
+ at example
+crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(n/10):(in_h-out_h)/2 +((in_h-out_h)/2)*sin(n/7)
+ at end example
+
+ at item
+Apply erratic camera effect depending on timestamp:
+ at example
+crop=in_w/2:in_h/2:(in_w-out_w)/2+((in_w-out_w)/2)*sin(t*10):(in_h-out_h)/2 +((in_h-out_h)/2)*sin(t*13)"
+ at end example
+
+ at item
+Set x depending on the value of y:
+ at example
+crop=in_w/2:in_h/2:y:10+10*sin(n/10)
+ at end example
+ at end itemize
+
+ at subsection Commands
+
+This filter supports the following commands:
+ at table @option
+ at item w, out_w
+ at item h, out_h
+ at item x
+ at item y
+Set width/height of the output video and the horizontal/vertical position
+in the input video.
+The command accepts the same syntax of the corresponding option.
+
+If the specified expression is not valid, it is kept at its current
+value.
+ at end table
+
+ at section cropdetect
+
+Auto-detect the crop size.
+
+It calculates the necessary cropping parameters and prints the
+recommended parameters via the logging system. The detected dimensions
+correspond to the non-black area of the input video.
+
+It accepts the following parameters:
+
+ at table @option
+
+ at item limit
+Set higher black value threshold, which can be optionally specified
+from nothing (0) to everything (255 for 8bit based formats). An intensity
+value greater to the set value is considered non-black. It defaults to 24.
+You can also specify a value between 0.0 and 1.0 which will be scaled depending
+on the bitdepth of the pixel format.
+
+ at item round
+The value which the width/height should be divisible by. It defaults to
+16. The offset is automatically adjusted to center the video. Use 2 to
+get only even dimensions (needed for 4:2:2 video). 16 is best when
+encoding to most video codecs.
+
+ at 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
+detect the current optimal crop area. Default value is 0.
+
+This can be useful when channel logos distort the video area. 0
+indicates 'never reset', and returns the largest area encountered during
+playback.
+ at end table
+
+ at anchor{curves}
+ at section curves
+
+Apply color adjustments using curves.
+
+This filter is similar to the Adobe Photoshop and GIMP curves tools. Each
+component (red, green and blue) has its values defined by @var{N} key points
+tied from each other using a smooth curve. The x-axis represents the pixel
+values from the input frame, and the y-axis the new pixel values to be set for
+the output frame.
+
+By default, a component curve is defined by the two points @var{(0;0)} and
+ at var{(1;1)}. This creates a straight line where each original pixel value is
+"adjusted" to its own value, which means no change to the image.
+
+The filter allows you to redefine these two points and add some more. A new
+curve (using a natural cubic spline interpolation) will be define to pass
+smoothly through all these new coordinates. The new defined points needs to be
+strictly increasing over the x-axis, and their @var{x} and @var{y} values must
+be in the @var{[0;1]} interval. If the computed curves happened to go outside
+the vector spaces, the values will be clipped accordingly.
+
+If there is no key point defined in @code{x=0}, the filter will automatically
+insert a @var{(0;0)} point. In the same way, if there is no key point defined
+in @code{x=1}, the filter will automatically insert a @var{(1;1)} point.
+
+The filter accepts the following options:
+
+ at table @option
+ at item preset
+Select one of the available color presets. This option can be used in addition
+to the @option{r}, @option{g}, @option{b} parameters; in this case, the later
+options takes priority on the preset values.
+Available presets are:
+ at table @samp
+ at item none
+ at item color_negative
+ at item cross_process
+ at item darker
+ at item increase_contrast
+ at item lighter
+ at item linear_contrast
+ at item medium_contrast
+ at item negative
+ at item strong_contrast
+ at item vintage
+ at end table
+Default is @code{none}.
+ at item master, m
+Set the master key points. These points will define a second pass mapping. It
+is sometimes called a "luminance" or "value" mapping. It can be used with
+ at option{r}, @option{g}, @option{b} or @option{all} since it acts like a
+post-processing LUT.
+ at item red, r
+Set the key points for the red component.
+ at item green, g
+Set the key points for the green component.
+ at item blue, b
+Set the key points for the blue component.
+ at item all
+Set the key points for all components (not including master).
+Can be used in addition to the other key points component
+options. In this case, the unset component(s) will fallback on this
+ at option{all} setting.
+ at item psfile
+Specify a Photoshop curves file (@code{.asv}) to import the settings from.
+ at end table
+
+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 ...}.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Increase slightly the middle level of blue:
+ at example
+curves=blue='0.5/0.58'
+ at end example
+
+ at item
+Vintage effect:
+ at example
+curves=r='0/0.11 .42/.51 1/0.95':g='0.50/0.48':b='0/0.22 .49/.44 1/0.8'
+ at end example
+Here we obtain the following coordinates for each components:
+ at table @var
+ at item red
+ at code{(0;0.11) (0.42;0.51) (1;0.95)}
+ at item green
+ at code{(0;0) (0.50;0.48) (1;1)}
+ at item blue
+ at code{(0;0.22) (0.49;0.44) (1;0.80)}
+ at end table
+
+ at item
+The previous example can also be achieved with the associated built-in preset:
+ at example
+curves=preset=vintage
+ at end example
+
+ at item
+Or simply:
+ at example
+curves=vintage
+ at end example
+
+ at item
+Use a Photoshop preset and redefine the points of the green component:
+ at example
+curves=psfile='MyCurvesPresets/purple.asv':green='0.45/0.53'
+ at end example
+ at end itemize
+
+ at section dctdnoiz
+
+Denoise frames using 2D DCT (frequency domain filtering).
+
+This filter is not designed for real time.
+
+The filter accepts the following options:
+
+ at table @option
+ at item sigma, s
+Set the noise sigma constant.
+
+This @var{sigma} defines a hard threshold of @code{3 * sigma}; every DCT
+coefficient (absolute value) below this threshold with be dropped.
+
+If you need a more advanced filtering, see @option{expr}.
+
+Default is @code{0}.
+
+ at item overlap
+Set number overlapping pixels for each block. Since the filter can be slow, you
+may want to reduce this value, at the cost of a less effective filter and the
+risk of various artefacts.
+
+If the overlapping value doesn't permit processing the whole input width or
+height, a warning will be displayed and according borders won't be denoised.
+
+Default value is @var{blocksize}-1, which is the best possible setting.
+
+ at item expr, e
+Set the coefficient factor expression.
+
+For each coefficient of a DCT block, this expression will be evaluated as a
+multiplier value for the coefficient.
+
+If this is option is set, the @option{sigma} option will be ignored.
+
+The absolute value of the coefficient can be accessed through the @var{c}
+variable.
+
+ at item n
+Set the @var{blocksize} using the number of bits. @code{1<<@var{n}} defines the
+ at var{blocksize}, which is the width and height of the processed blocks.
+
+The default value is @var{3} (8x8) and can be raised to @var{4} for a
+ at var{blocksize} of 16x16. Note that changing this setting has huge consequences
+on the speed processing. Also, a larger block size does not necessarily means a
+better de-noising.
+ at end table
+
+ at subsection Examples
+
+Apply a denoise with a @option{sigma} of @code{4.5}:
+ at example
+dctdnoiz=4.5
+ at end example
+
+The same operation can be achieved using the expression system:
+ at example
+dctdnoiz=e='gte(c, 4.5*3)'
+ at end example
+
+Violent denoise using a block size of @code{16x16}:
+ at example
+dctdnoiz=15:n=4
+ at end example
+
+ at section deband
+
+Remove banding artifacts from input video.
+It works by replacing banded pixels with average value of referenced pixels.
+
+The filter accepts the following options:
+
+ at table @option
+ at item 1thr
+ at item 2thr
+ at item 3thr
+ at item 4thr
+Set banding detection threshold for each plane. Default is 0.02.
+Valid range is 0.00003 to 0.5.
+If difference between current pixel and reference pixel is less than threshold,
+it will be considered as banded.
+
+ at item range, r
+Banding detection range in pixels. Default is 16. If positive, random number
+in range 0 to set value will be used. If negative, exact absolute value
+will be used.
+The range defines square of four pixels around current pixel.
+
+ at item direction, d
+Set direction in radians from which four pixel will be compared. If positive,
+random direction from 0 to set direction will be picked. If negative, exact of
+absolute value will be picked. For example direction 0, -PI or -2*PI radians
+will pick only pixels on same row and -PI/2 will pick only pixels on same
+column.
+
+ at item blur
+If enabled, current pixel is compared with average value of all four
+surrounding pixels. The default is enabled. If disabled current pixel is
+compared with all four surrounding pixels. The pixel is considered banded
+if only all four differences with surrounding pixels are less than threshold.
+ at end table
+
+ at anchor{decimate}
+ at section decimate
+
+Drop duplicated frames at regular intervals.
+
+The filter accepts the following options:
+
+ at table @option
+ at item cycle
+Set the number of frames from which one will be dropped. Setting this to
+ at var{N} means one frame in every batch of @var{N} frames will be dropped.
+Default is @code{5}.
+
+ at item dupthresh
+Set the threshold for duplicate detection. If the difference metric for a frame
+is less than or equal to this value, then it is declared as duplicate. Default
+is @code{1.1}
+
+ at item scthresh
+Set scene change threshold. Default is @code{15}.
+
+ at item blockx
+ at item blocky
+Set the size of the x and y-axis blocks used during metric calculations.
+Larger blocks give better noise suppression, but also give worse detection of
+small movements. Must be a power of two. Default is @code{32}.
+
+ at item ppsrc
+Mark main input as a pre-processed input and activate clean source input
+stream. This allows the input to be pre-processed with various filters to help
+the metrics calculation while keeping the frame selection lossless. When set to
+ at code{1}, the first stream is for the pre-processed input, and the second
+stream is the clean source from where the kept frames are chosen. Default is
+ at code{0}.
+
+ at item chroma
+Set whether or not chroma is considered in the metric calculations. Default is
+ at code{1}.
+ at end table
+
+ at section deflate
+
+Apply deflate effect to the video.
+
+This filter replaces the pixel by the local(3x3) average by taking into account
+only values lower than the pixel.
+
+It accepts the following options:
+
+ at table @option
+ at item threshold0
+ at item threshold1
+ at item threshold2
+ at item threshold3
+Limit the maximum change for each plane, default is 65535.
+If 0, plane will remain unchanged.
+ at end table
+
+ at section dejudder
+
+Remove judder produced by partially interlaced telecined content.
+
+Judder can be introduced, for instance, by @ref{pullup} filter. If the original
+source was partially telecined content then the output of @code{pullup,dejudder}
+will have a variable frame rate. May change the recorded frame rate of the
+container. Aside from that change, this filter will not affect constant frame
+rate video.
+
+The option available in this filter is:
+ at table @option
+
+ at item cycle
+Specify the length of the window over which the judder repeats.
+
+Accepts any integer greater than 1. Useful values are:
+ at table @samp
+
+ at item 4
+If the original was telecined from 24 to 30 fps (Film to NTSC).
+
+ at item 5
+If the original was telecined from 25 to 30 fps (PAL to NTSC).
+
+ at item 20
+If a mixture of the two.
+ at end table
+
+The default is @samp{4}.
+ at end table
+
+ at section delogo
+
+Suppress a TV station logo by a simple interpolation of the surrounding
+pixels. Just set a rectangle covering the logo and watch it disappear
+(and sometimes something even uglier appear - your mileage may vary).
+
+It accepts the following parameters:
+ at table @option
+
+ at item x
+ at item y
+Specify the top left corner coordinates of the logo. They must be
+specified.
+
+ at item w
+ at item h
+Specify the width and height of the logo to clear. They must be
+specified.
+
+ at item band, t
+Specify the thickness of the fuzzy edge of the rectangle (added to
+ at var{w} and @var{h}). The default value is 4.
+
+ at 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.
+The default value is 0.
+
+The rectangle is drawn on the outermost pixels which will be (partly)
+replaced with interpolated values. The values of the next pixels
+immediately outside this rectangle in each direction will be used to
+compute the interpolated pixel values inside the rectangle.
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Set a rectangle covering the area with top left corner coordinates 0,0
+and size 100x77, and a band of size 10:
+ at example
+delogo=x=0:y=0:w=100:h=77:band=10
+ at end example
+
+ at end itemize
+
+ at section deshake
+
+Attempt to fix small changes in horizontal and/or vertical shift. This
+filter helps remove camera shake from hand-holding a camera, bumping a
+tripod, moving on a vehicle, etc.
+
+The filter accepts the following options:
+
+ at table @option
+
+ at item x
+ at item y
+ at item w
+ at item h
+Specify a rectangular area where to limit the search for motion
+vectors.
+If desired the search for motion vectors can be limited to a
+rectangular area of the frame defined by its top left corner, width
+and height. These parameters have the same meaning as the drawbox
+filter which can be used to visualise the position of the bounding
+box.
+
+This is useful when simultaneous movement of subjects within the frame
+might be confused for camera motion by the motion vector search.
+
+If any or all of @var{x}, @var{y}, @var{w} and @var{h} are set to -1
+then the full frame is used. This allows later options to be set
+without specifying the bounding box for the motion vector search.
+
+Default - search the whole frame.
+
+ at item rx
+ at item ry
+Specify the maximum extent of movement in x and y directions in the
+range 0-64 pixels. Default 16.
+
+ at item edge
+Specify how to generate pixels to fill blanks at the edge of the
+frame. Available values are:
+ at table @samp
+ at item blank, 0
+Fill zeroes at blank locations
+ at item original, 1
+Original image at blank locations
+ at item clamp, 2
+Extruded edge value at blank locations
+ at item mirror, 3
+Mirrored edge at blank locations
+ at end table
+Default value is @samp{mirror}.
+
+ at item blocksize
+Specify the blocksize to use for motion search. Range 4-128 pixels,
+default 8.
+
+ at item contrast
+Specify the contrast threshold for blocks. Only blocks with more than
+the specified contrast (difference between darkest and lightest
+pixels) will be considered. Range 1-255, default 125.
+
+ at item search
+Specify the search strategy. Available values are:
+ at table @samp
+ at item exhaustive, 0
+Set exhaustive search
+ at item less, 1
+Set less exhaustive search.
+ at end table
+Default value is @samp{exhaustive}.
+
+ at item filename
+If set then a detailed log of the motion search is written to the
+specified file.
+
+ at item opencl
+If set to 1, specify using OpenCL capabilities, only available if
+FFmpeg was configured with @code{--enable-opencl}. Default value is 0.
+
+ at end table
+
+ at section detelecine
+
+Apply an exact inverse of the telecine operation. It requires a predefined
+pattern specified using the pattern option which must be the same as that passed
+to the telecine filter.
+
+This filter accepts the following options:
+
+ at table @option
+ at item first_field
+ at table @samp
+ at item top, t
+top field first
+ at item bottom, b
+bottom field first
+The default value is @code{top}.
+ at end table
+
+ at item pattern
+A string of numbers representing the pulldown pattern you wish to apply.
+The default value is @code{23}.
+
+ at item start_frame
+A number representing position of the first frame with respect to the telecine
+pattern. This is to be used if the stream is cut. The default value is @code{0}.
+ at end table
+
+ at section dilation
+
+Apply dilation effect to the video.
+
+This filter replaces the pixel by the local(3x3) maximum.
+
+It accepts the following options:
+
+ at table @option
+ at item threshold0
+ at item threshold1
+ at item threshold2
+ at item threshold3
+Limit the maximum change for each plane, default is 65535.
+If 0, plane will remain unchanged.
+
+ at item coordinates
+Flag which specifies the pixel to refer to. Default is 255 i.e. all eight
+pixels are used.
+
+Flags to local 3x3 coordinates maps like this:
+
+ 1 2 3
+ 4 5
+ 6 7 8
+ at end table
+
+ at section drawbox
+
+Draw a colored box on the input image.
+
+It accepts the following parameters:
+
+ at table @option
+ at item x
+ at item y
+The expressions which specify the top left corner coordinates of the box. It defaults to 0.
+
+ at item width, w
+ at item height, h
+The expressions which specify the width and height of the box; if 0 they are interpreted as
+the input width and height. It defaults to 0.
+
+ at item color, c
+Specify the color of the box to write. For the general syntax of this option,
+check the "Color" section in the ffmpeg-utils manual. If the special
+value @code{invert} is used, the box edge color is the same as the
+video with inverted luma.
+
+ at item thickness, t
+The expression which sets the thickness of the box edge. Default value is @code{3}.
+
+See below for the list of accepted constants.
+ at end table
+
+The parameters for @var{x}, @var{y}, @var{w} and @var{h} and @var{t} are expressions containing the
+following constants:
+
+ at table @option
+ at item dar
+The input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar}.
+
+ at item hsub
+ at item vsub
+horizontal and vertical chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+
+ at item in_h, ih
+ at item in_w, iw
+The input width and height.
+
+ at item sar
+The input sample aspect ratio.
+
+ at item x
+ at item y
+The x and y offset coordinates where the box is drawn.
+
+ at item w
+ at item h
+The width and height of the drawn box.
+
+ at item t
+The thickness of the drawn box.
+
+These constants allow the @var{x}, @var{y}, @var{w}, @var{h} and @var{t} expressions to refer to
+each other, so you may for example specify @code{y=x/dar} or @code{h=w/dar}.
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Draw a black box around the edge of the input image:
+ at example
+drawbox
+ at end example
+
+ at item
+Draw a box with color red and an opacity of 50%:
+ at example
+drawbox=10:20:200:60:red@@0.5
+ at end example
+
+The previous example can be specified as:
+ at example
+drawbox=x=10:y=20:w=200:h=60:color=red@@0.5
+ at end example
+
+ at item
+Fill the box with pink color:
+ at example
+drawbox=x=10:y=10:w=100:h=100:color=pink@@0.5:t=max
+ at end example
+
+ at item
+Draw a 2-pixel red 2.40:1 mask:
+ at example
+drawbox=x=-t:y=0.5*(ih-iw/2.4)-t:w=iw+t*2:h=iw/2.4+t*2:t=2:c=red
+ at end example
+ at end itemize
+
+ at section drawgraph, adrawgraph
+
+Draw a graph using input video or audio metadata.
+
+It accepts the following parameters:
+
+ at table @option
+ at item m1
+Set 1st frame metadata key from which metadata values will be used to draw a graph.
+
+ at item fg1
+Set 1st foreground color expression.
+
+ at item m2
+Set 2nd frame metadata key from which metadata values will be used to draw a graph.
+
+ at item fg2
+Set 2nd foreground color expression.
+
+ at item m3
+Set 3rd frame metadata key from which metadata values will be used to draw a graph.
+
+ at item fg3
+Set 3rd foreground color expression.
+
+ at item m4
+Set 4th frame metadata key from which metadata values will be used to draw a graph.
+
+ at item fg4
+Set 4th foreground color expression.
+
+ at item min
+Set minimal value of metadata value.
+
+ at item max
+Set maximal value of metadata value.
+
+ at item bg
+Set graph background color. Default is white.
+
+ at item mode
+Set graph mode.
+
+Available values for mode is:
+ at table @samp
+ at item bar
+ at item dot
+ at item line
+ at end table
+
+Default is @code{line}.
+
+ at item slide
+Set slide mode.
+
+Available values for slide is:
+ at table @samp
+ at item frame
+Draw new frame when right border is reached.
+
+ at item replace
+Replace old columns with new ones.
+
+ at item scroll
+Scroll from right to left.
+
+ at item rscroll
+Scroll from left to right.
+ at end table
+
+Default is @code{frame}.
+
+ at item size
+Set size of graph video. For the syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+The default value is @code{900x256}.
+
+The foreground color expressions can use the following variables:
+ at table @option
+ at item MIN
+Minimal value of metadata value.
+
+ at item MAX
+Maximal value of metadata value.
+
+ at item VAL
+Current metadata key value.
+ at end table
+
+The color is defined as 0xAABBGGRR.
+ at end table
+
+Example using metadata from @ref{signalstats} filter:
+ at example
+signalstats,drawgraph=lavfi.signalstats.YAVG:min=0:max=255
+ at end example
+
+Example using metadata from @ref{ebur128} filter:
+ at example
+ebur128=metadata=1,adrawgraph=lavfi.r128.M:min=-120:max=5
+ at end example
+
+ at section drawgrid
+
+Draw a grid on the input image.
+
+It accepts the following parameters:
+
+ at table @option
+ at item x
+ at item y
+The expressions which specify the coordinates of some point of grid intersection (meant to configure offset). Both default to 0.
+
+ at item width, w
+ at item height, h
+The expressions which specify the width and height of the grid cell, if 0 they are interpreted as the
+input width and height, respectively, minus @code{thickness}, so image gets
+framed. Default to 0.
+
+ at item color, c
+Specify the color of the grid. For the general syntax of this option,
+check the "Color" section in the ffmpeg-utils manual. If the special
+value @code{invert} is used, the grid color is the same as the
+video with inverted luma.
+
+ at item thickness, t
+The expression which sets the thickness of the grid line. Default value is @code{1}.
+
+See below for the list of accepted constants.
+ at end table
+
+The parameters for @var{x}, @var{y}, @var{w} and @var{h} and @var{t} are expressions containing the
+following constants:
+
+ at table @option
+ at item dar
+The input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar}.
+
+ at item hsub
+ at item vsub
+horizontal and vertical chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+
+ at item in_h, ih
+ at item in_w, iw
+The input grid cell width and height.
+
+ at item sar
+The input sample aspect ratio.
+
+ at item x
+ at item y
+The x and y coordinates of some point of grid intersection (meant to configure offset).
+
+ at item w
+ at item h
+The width and height of the drawn cell.
+
+ at item t
+The thickness of the drawn cell.
+
+These constants allow the @var{x}, @var{y}, @var{w}, @var{h} and @var{t} expressions to refer to
+each other, so you may for example specify @code{y=x/dar} or @code{h=w/dar}.
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Draw a grid with cell 100x100 pixels, thickness 2 pixels, with color red and an opacity of 50%:
+ at example
+drawgrid=width=100:height=100:thickness=2:color=red@@0.5
+ at end example
+
+ at item
+Draw a white 3x3 grid with an opacity of 50%:
+ at example
+drawgrid=w=iw/3:h=ih/3:t=2:c=white@@0.5
+ at end example
+ at end itemize
+
+ at anchor{drawtext}
+ at section drawtext
+
+Draw a text string or text from a specified file on top of a video, using the
+libfreetype library.
+
+To enable compilation of this filter, you need to configure FFmpeg with
+ at code{--enable-libfreetype}.
+To enable default font fallback and the @var{font} option you need to
+configure FFmpeg with @code{--enable-libfontconfig}.
+To enable the @var{text_shaping} option, you need to configure FFmpeg with
+ at code{--enable-libfribidi}.
+
+ at subsection Syntax
+
+It accepts the following parameters:
+
+ at table @option
+
+ at item box
+Used to draw a box around text using the background color.
+The value must be either 1 (enable) or 0 (disable).
+The default value of @var{box} is 0.
+
+ at item boxborderw
+Set the width of the border to be drawn around the box using @var{boxcolor}.
+The default value of @var{boxborderw} is 0.
+
+ at item boxcolor
+The color to be used for drawing box around text. For the syntax of this
+option, check the "Color" section in the ffmpeg-utils manual.
+
+The default value of @var{boxcolor} is "white".
+
+ at item borderw
+Set the width of the border to be drawn around the text using @var{bordercolor}.
+The default value of @var{borderw} is 0.
+
+ at item bordercolor
+Set the color to be used for drawing border around text. For the syntax of this
+option, check the "Color" section in the ffmpeg-utils manual.
+
+The default value of @var{bordercolor} is "black".
+
+ at item expansion
+Select how the @var{text} is expanded. Can be either @code{none},
+ at code{strftime} (deprecated) or
+ at code{normal} (default). See the @ref{drawtext_expansion, Text expansion} section
+below for details.
+
+ at item fix_bounds
+If true, check and fix text coords to avoid clipping.
+
+ at item fontcolor
+The color to be used for drawing fonts. For the syntax of this option, check
+the "Color" section in the ffmpeg-utils manual.
+
+The default value of @var{fontcolor} is "black".
+
+ at item fontcolor_expr
+String which is expanded the same way as @var{text} to obtain dynamic
+ at var{fontcolor} value. By default this option has empty value and is not
+processed. When this option is set, it overrides @var{fontcolor} option.
+
+ at item font
+The font family to be used for drawing text. By default Sans.
+
+ at item fontfile
+The font file to be used for drawing text. The path must be included.
+This parameter is mandatory if the fontconfig support is disabled.
+
+ at item draw
+This option does not exist, please see the timeline system
+
+ at item alpha
+Draw the text applying alpha blending. The value can
+be either a number between 0.0 and 1.0
+The expression accepts the same variables @var{x, y} do.
+The default value is 1.
+Please see fontcolor_expr
+
+ at item fontsize
+The font size to be used for drawing text.
+The default value of @var{fontsize} is 16.
+
+ at item text_shaping
+If set to 1, attempt to shape the text (for example, reverse the order of
+right-to-left text and join Arabic characters) before drawing it.
+Otherwise, just draw the text exactly as given.
+By default 1 (if supported).
+
+ at item ft_load_flags
+The flags to be used for loading the fonts.
+
+The flags map the corresponding flags supported by libfreetype, and are
+a combination of the following values:
+ at table @var
+ at item default
+ at item no_scale
+ at item no_hinting
+ at item render
+ at item no_bitmap
+ at item vertical_layout
+ at item force_autohint
+ at item crop_bitmap
+ at item pedantic
+ at item ignore_global_advance_width
+ at item no_recurse
+ at item ignore_transform
+ at item monochrome
+ at item linear_design
+ at item no_autohint
+ at end table
+
+Default value is "default".
+
+For more information consult the documentation for the FT_LOAD_*
+libfreetype flags.
+
+ at item shadowcolor
+The color to be used for drawing a shadow behind the drawn text. For the
+syntax of this option, check the "Color" section in the ffmpeg-utils manual.
+
+The default value of @var{shadowcolor} is "black".
+
+ at item shadowx
+ at item shadowy
+The x and y offsets for the text shadow position with respect to the
+position of the text. They can be either positive or negative
+values. The default value for both is "0".
+
+ at item start_number
+The starting frame number for the n/frame_num variable. The default value
+is "0".
+
+ at item tabsize
+The size in number of spaces to use for rendering the tab.
+Default value is 4.
+
+ at item timecode
+Set the initial timecode representation in "hh:mm:ss[:;.]ff"
+format. It can be used with or without text parameter. @var{timecode_rate}
+option must be specified.
+
+ at item timecode_rate, rate, r
+Set the timecode frame rate (timecode only).
+
+ at item text
+The text string to be drawn. The text must be a sequence of UTF-8
+encoded characters.
+This parameter is mandatory if no file is specified with the parameter
+ at var{textfile}.
+
+ at item textfile
+A text file containing text to be drawn. The text must be a sequence
+of UTF-8 encoded characters.
+
+This parameter is mandatory if no text string is specified with the
+parameter @var{text}.
+
+If both @var{text} and @var{textfile} are specified, an error is thrown.
+
+ at item reload
+If set to 1, the @var{textfile} will be reloaded before each frame.
+Be sure to update it atomically, or it may be read partially, or even fail.
+
+ at item x
+ at item y
+The expressions which specify the offsets where text will be drawn
+within the video frame. They are relative to the top/left border of the
+output image.
+
+The default value of @var{x} and @var{y} is "0".
+
+See below for the list of accepted constants and functions.
+ at end table
+
+The parameters for @var{x} and @var{y} are expressions containing the
+following constants and functions:
+
+ at table @option
+ at item dar
+input display aspect ratio, it is the same as (@var{w} / @var{h}) * @var{sar}
+
+ at item hsub
+ at item vsub
+horizontal and vertical chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+
+ at item line_h, lh
+the height of each text line
+
+ at item main_h, h, H
+the input height
+
+ at item main_w, w, W
+the input width
+
+ at item max_glyph_a, ascent
+the maximum distance from the baseline to the highest/upper grid
+coordinate used to place a glyph outline point, for all the rendered
+glyphs.
+It is a positive value, due to the grid's orientation with the Y axis
+upwards.
+
+ at item max_glyph_d, descent
+the maximum distance from the baseline to the lowest grid coordinate
+used to place a glyph outline point, for all the rendered glyphs.
+This is a negative value, due to the grid's orientation, with the Y axis
+upwards.
+
+ at item max_glyph_h
+maximum glyph height, that is the maximum height for all the glyphs
+contained in the rendered text, it is equivalent to @var{ascent} -
+ at var{descent}.
+
+ at item max_glyph_w
+maximum glyph width, that is the maximum width for all the glyphs
+contained in the rendered text
+
+ at item n
+the number of input frame, starting from 0
+
+ at item rand(min, max)
+return a random number included between @var{min} and @var{max}
+
+ at item sar
+The input sample aspect ratio.
+
+ at item t
+timestamp expressed in seconds, NAN if the input timestamp is unknown
+
+ at item text_h, th
+the height of the rendered text
+
+ at item text_w, tw
+the width of the rendered text
+
+ at item x
+ at item y
+the x and y offset coordinates where the text is drawn.
+
+These parameters allow the @var{x} and @var{y} expressions to refer
+each other, so you can for example specify @code{y=x/dar}.
+ at end table
+
+ at anchor{drawtext_expansion}
+ at subsection Text expansion
+
+If @option{expansion} is set to @code{strftime},
+the filter recognizes strftime() sequences in the provided text and
+expands them accordingly. Check the documentation of strftime(). This
+feature is deprecated.
+
+If @option{expansion} is set to @code{none}, the text is printed verbatim.
+
+If @option{expansion} is set to @code{normal} (which is the default),
+the following expansion mechanism is used.
+
+The backslash character @samp{\}, followed by any character, always expands to
+the second character.
+
+Sequence of the form @code{%@{...@}} are expanded. The text between the
+braces is a function name, possibly followed by arguments separated by ':'.
+If the arguments contain special characters or delimiters (':' or '@}'),
+they should be escaped.
+
+Note that they probably must also be escaped as the value for the
+ at option{text} option in the filter argument string and as the filter
+argument in the filtergraph description, and possibly also for the shell,
+that makes up to four levels of escaping; using a text file avoids these
+problems.
+
+The following functions are available:
+
+ at table @command
+
+ at item expr, e
+The expression evaluation result.
+
+It must take one argument specifying the expression to be evaluated,
+which accepts the same constants and functions as the @var{x} and
+ at var{y} values. Note that not all constants should be used, for
+example the text size is not known when evaluating the expression, so
+the constants @var{text_w} and @var{text_h} will have an undefined
+value.
+
+ at item expr_int_format, eif
+Evaluate the expression's value and output as formatted integer.
+
+The first argument is the expression to be evaluated, just as for the @var{expr} function.
+The second argument specifies the output format. Allowed values are @samp{x},
+ at samp{X}, @samp{d} and @samp{u}. They are treated exactly as in the
+ at code{printf} function.
+The third parameter is optional and sets the number of positions taken by the output.
+It can be used to add padding with zeros from the left.
+
+ at item gmtime
+The time at which the filter is running, expressed in UTC.
+It can accept an argument: a strftime() format string.
+
+ at item localtime
+The time at which the filter is running, expressed in the local time zone.
+It can accept an argument: a strftime() format string.
+
+ at item metadata
+Frame metadata. It must take one argument specifying metadata key.
+
+ at item n, frame_num
+The frame number, starting from 0.
+
+ at item pict_type
+A 1 character description of the current picture type.
+
+ at item pts
+The timestamp of the current frame.
+It can take up to two arguments.
+
+The first argument is the format of the timestamp; it defaults to @code{flt}
+for seconds as a decimal number with microsecond accuracy; @code{hms} stands
+for a formatted @var{[-]HH:MM:SS.mmm} timestamp with millisecond accuracy.
+
+The second argument is an offset added to the timestamp.
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Draw "Test Text" with font FreeSerif, using the default values for the
+optional parameters.
+
+ at example
+drawtext="fontfile=/usr/share/fonts/truetype/freefont/FreeSerif.ttf: text='Test Text'"
+ at end example
+
+ at item
+Draw 'Test Text' with font FreeSerif of size 24 at position x=100
+and y=50 (counting from the top-left corner of the screen), text is
+yellow with a red box around it. Both the text and the box have an
+opacity of 20%.
+
+ at example
+drawtext="fontfile=/usr/share/fonts/truetype/freefont/FreeSerif.ttf: text='Test Text':\
+ x=100: y=50: fontsize=24: fontcolor=yellow@@0.2: box=1: boxcolor=red@@0.2"
+ at end example
+
+Note that the double quotes are not necessary if spaces are not used
+within the parameter list.
+
+ at item
+Show the text at the center of the video frame:
+ at example
+drawtext="fontsize=30:fontfile=FreeSerif.ttf:text='hello world':x=(w-text_w)/2:y=(h-text_h)/2"
+ at end example
+
+ at item
+Show a text line sliding from right to left in the last row of the video
+frame. The file @file{LONG_LINE} is assumed to contain a single line
+with no newlines.
+ at example
+drawtext="fontsize=15:fontfile=FreeSerif.ttf:text=LONG_LINE:y=h-line_h:x=-50*t"
+ at end example
+
+ at item
+Show the content of file @file{CREDITS} off the bottom of the frame and scroll up.
+ at example
+drawtext="fontsize=20:fontfile=FreeSerif.ttf:textfile=CREDITS:y=h-20*t"
+ at end example
+
+ at item
+Draw a single green letter "g", at the center of the input video.
+The glyph baseline is placed at half screen height.
+ at example
+drawtext="fontsize=60:fontfile=FreeSerif.ttf:fontcolor=green:text=g:x=(w-max_glyph_w)/2:y=h/2-ascent"
+ at end example
+
+ at item
+Show text for 1 second every 3 seconds:
+ at example
+drawtext="fontfile=FreeSerif.ttf:fontcolor=white:x=100:y=x/dar:enable=lt(mod(t\,3)\,1):text='blink'"
+ at end example
+
+ at item
+Use fontconfig to set the font. Note that the colons need to be escaped.
+ at example
+drawtext='fontfile=Linux Libertine O-40\:style=Semibold:text=FFmpeg'
+ at end example
+
+ at item
+Print the date of a real-time encoding (see strftime(3)):
+ at example
+drawtext='fontfile=FreeSans.ttf:text=%@{localtime\:%a %b %d %Y@}'
+ at end example
+
+ at item
+Show text fading in and out (appearing/disappearing):
+ at example
+#!/bin/sh
+DS=1.0 # display start
+DE=10.0 # display end
+FID=1.5 # fade in duration
+FOD=5 # fade out duration
+ffplay -f lavfi "color,drawtext=text=TEST:fontsize=50:fontfile=FreeSerif.ttf:fontcolor_expr=ff0000%@{eif\\\\: clip(255*(1*between(t\\, $DS + $FID\\, $DE - $FOD) + ((t - $DS)/$FID)*between(t\\, $DS\\, $DS + $FID) + (-(t - $DE)/$FOD)*between(t\\, $DE - $FOD\\, $DE) )\\, 0\\, 255) \\\\: x\\\\: 2 @}"
+ at end example
+
+ at end itemize
+
+For more information about libfreetype, check:
+ at url{http://www.freetype.org/}.
+
+For more information about fontconfig, check:
+ at url{http://freedesktop.org/software/fontconfig/fontconfig-user.html}.
+
+For more information about libfribidi, check:
+ at url{http://fribidi.org/}.
+
+ at section edgedetect
+
+Detect and draw edges. The filter uses the Canny Edge Detection algorithm.
+
+The filter accepts the following options:
+
+ at table @option
+ at item low
+ at item high
+Set low and high threshold values used by the Canny thresholding
+algorithm.
+
+The high threshold selects the "strong" edge pixels, which are then
+connected through 8-connectivity with the "weak" edge pixels selected
+by the low threshold.
+
+ at var{low} and @var{high} threshold values must be chosen in the range
+[0,1], and @var{low} should be lesser or equal to @var{high}.
+
+Default value for @var{low} is @code{20/255}, and default value for @var{high}
+is @code{50/255}.
+
+ at item mode
+Define the drawing mode.
+
+ at table @samp
+ at item wires
+Draw white/gray wires on black background.
+
+ at item colormix
+Mix the colors to create a paint/cartoon effect.
+ at end table
+
+Default value is @var{wires}.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Standard edge detection with custom values for the hysteresis thresholding:
+ at example
+edgedetect=low=0.1:high=0.4
+ at end example
+
+ at item
+Painting effect without thresholding:
+ at example
+edgedetect=mode=colormix:high=0
+ at end example
+ at end itemize
+
+ at section eq
+Set brightness, contrast, saturation and approximate gamma adjustment.
+
+The filter accepts the following options:
+
+ at table @option
+ at item contrast
+Set the contrast expression. The value must be a float value in range
+ at code{-2.0} to @code{2.0}. The default value is "0".
+
+ at item brightness
+Set the brightness expression. The value must be a float value in
+range @code{-1.0} to @code{1.0}. The default value is "0".
+
+ at item saturation
+Set the saturation expression. The value must be a float in
+range @code{0.0} to @code{3.0}. The default value is "1".
+
+ at item gamma
+Set the gamma expression. The value must be a float in range
+ at code{0.1} to @code{10.0}. The default value is "1".
+
+ at item gamma_r
+Set the gamma expression for red. The value must be a float in
+range @code{0.1} to @code{10.0}. The default value is "1".
+
+ at item gamma_g
+Set the gamma expression for green. The value must be a float in range
+ at code{0.1} to @code{10.0}. The default value is "1".
+
+ at item gamma_b
+Set the gamma expression for blue. The value must be a float in range
+ at code{0.1} to @code{10.0}. The default value is "1".
+
+ at item gamma_weight
+Set the gamma weight expression. It can be used to reduce the effect
+of a high gamma value on bright image areas, e.g. keep them from
+getting overamplified and just plain white. The value must be a float
+in range @code{0.0} to @code{1.0}. A value of @code{0.0} turns the
+gamma correction all the way down while @code{1.0} leaves it at its
+full strength. Default is "1".
+
+ at item eval
+Set when the expressions for brightness, contrast, saturation and
+gamma expressions are evaluated.
+
+It accepts the following values:
+ at table @samp
+ at item init
+only evaluate expressions once during the filter initialization or
+when a command is processed
+
+ at item frame
+evaluate expressions for each incoming frame
+ at end table
+
+Default value is @samp{init}.
+ at end table
+
+The expressions accept the following parameters:
+ at table @option
+ at item n
+frame count of the input frame starting from 0
+
+ at item pos
+byte position of the corresponding packet in the input file, NAN if
+unspecified
+
+ at item r
+frame rate of the input video, NAN if the input frame rate is unknown
+
+ at item t
+timestamp expressed in seconds, NAN if the input timestamp is unknown
+ at end table
+
+ at subsection Commands
+The filter supports the following commands:
+
+ at table @option
+ at item contrast
+Set the contrast expression.
+
+ at item brightness
+Set the brightness expression.
+
+ at item saturation
+Set the saturation expression.
+
+ at item gamma
+Set the gamma expression.
+
+ at item gamma_r
+Set the gamma_r expression.
+
+ at item gamma_g
+Set gamma_g expression.
+
+ at item gamma_b
+Set gamma_b expression.
+
+ at item gamma_weight
+Set gamma_weight expression.
+
+The command accepts the same syntax of the corresponding option.
+
+If the specified expression is not valid, it is kept at its current
+value.
+
+ at end table
+
+ at section erosion
+
+Apply erosion effect to the video.
+
+This filter replaces the pixel by the local(3x3) minimum.
+
+It accepts the following options:
+
+ at table @option
+ at item threshold0
+ at item threshold1
+ at item threshold2
+ at item threshold3
+Limit the maximum change for each plane, default is 65535.
+If 0, plane will remain unchanged.
+
+ at item coordinates
+Flag which specifies the pixel to refer to. Default is 255 i.e. all eight
+pixels are used.
+
+Flags to local 3x3 coordinates maps like this:
+
+ 1 2 3
+ 4 5
+ 6 7 8
+ at end table
+
+ at section extractplanes
+
+Extract color channel components from input video stream into
+separate grayscale video streams.
+
+The filter accepts the following option:
+
+ at table @option
+ at item planes
+Set plane(s) to extract.
+
+Available values for planes are:
+ at table @samp
+ at item y
+ at item u
+ at item v
+ at item a
+ at item r
+ at item g
+ at item b
+ at end table
+
+Choosing planes not available in the input will result in an error.
+That means you cannot select @code{r}, @code{g}, @code{b} planes
+with @code{y}, @code{u}, @code{v} planes at same time.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Extract luma, u and v color channel component from input video frame
+into 3 grayscale outputs:
+ at example
+ffmpeg -i video.avi -filter_complex 'extractplanes=y+u+v[y][u][v]' -map '[y]' y.avi -map '[u]' u.avi -map '[v]' v.avi
+ at end example
+ at end itemize
+
+ at section elbg
+
+Apply a posterize effect using the ELBG (Enhanced LBG) algorithm.
+
+For each input image, the filter will compute the optimal mapping from
+the input to the output given the codebook length, that is the number
+of distinct output colors.
+
+This filter accepts the following options.
+
+ at table @option
+ at item codebook_length, l
+Set codebook length. The value must be a positive integer, and
+represents the number of distinct output colors. Default value is 256.
+
+ at item nb_steps, n
+Set the maximum number of iterations to apply for computing the optimal
+mapping. The higher the value the better the result and the higher the
+computation time. Default value is 1.
+
+ at item seed, s
+Set a random seed, must be an integer included between 0 and
+UINT32_MAX. If not specified, or if explicitly set to -1, the filter
+will try to use a good random seed on a best effort basis.
+
+ at item pal8
+Set pal8 output pixel format. This option does not work with codebook
+length greater than 256.
+ at end table
+
+ at section fade
+
+Apply a fade-in/out effect to the input video.
+
+It accepts the following parameters:
+
+ at table @option
+ at item type, t
+The effect type can be either "in" for a fade-in, or "out" for a fade-out
+effect.
+Default is @code{in}.
+
+ at item start_frame, s
+Specify the number of the frame to start applying the fade
+effect at. Default is 0.
+
+ at item nb_frames, n
+The number of frames that the fade effect lasts. At the end of the
+fade-in effect, the output video will have the same intensity as the input video.
+At the end of the fade-out transition, the output video will be filled with the
+selected @option{color}.
+Default is 25.
+
+ at item alpha
+If set to 1, fade only alpha channel, if one exists on the input.
+Default value is 0.
+
+ at item start_time, st
+Specify the timestamp (in seconds) of the frame to start to apply the fade
+effect. If both start_frame and start_time are specified, the fade will start at
+whichever comes last. Default is 0.
+
+ at item duration, d
+The number of seconds for which the fade effect has to last. At the end of the
+fade-in effect the output video will have the same intensity as the input video,
+at the end of the fade-out transition the output video will be filled with the
+selected @option{color}.
+If both duration and nb_frames are specified, duration is used. Default is 0
+(nb_frames is used by default).
+
+ at item color, c
+Specify the color of the fade. Default is "black".
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Fade in the first 30 frames of video:
+ at example
+fade=in:0:30
+ at end example
+
+The command above is equivalent to:
+ at example
+fade=t=in:s=0:n=30
+ at end example
+
+ at item
+Fade out the last 45 frames of a 200-frame video:
+ at example
+fade=out:155:45
+fade=type=out:start_frame=155:nb_frames=45
+ at end example
+
+ at item
+Fade in the first 25 frames and fade out the last 25 frames of a 1000-frame video:
+ at example
+fade=in:0:25, fade=out:975:25
+ at end example
+
+ at item
+Make the first 5 frames yellow, then fade in from frame 5-24:
+ at example
+fade=in:5:20:color=yellow
+ at end example
+
+ at item
+Fade in alpha over first 25 frames of video:
+ at example
+fade=in:0:25:alpha=1
+ at end example
+
+ at item
+Make the first 5.5 seconds black, then fade in for 0.5 seconds:
+ at example
+fade=t=in:st=5.5:d=0.5
+ at end example
+
+ at end itemize
+
+ at section fftfilt
+Apply arbitrary expressions to samples in frequency domain
+
+ at table @option
+ at item dc_Y
+Adjust the dc value (gain) of the luma plane of the image. The filter
+accepts an integer value in range @code{0} to @code{1000}. The default
+value is set to @code{0}.
+
+ at item dc_U
+Adjust the dc value (gain) of the 1st chroma plane of the image. The
+filter accepts an integer value in range @code{0} to @code{1000}. The
+default value is set to @code{0}.
+
+ at item dc_V
+Adjust the dc value (gain) of the 2nd chroma plane of the image. The
+filter accepts an integer value in range @code{0} to @code{1000}. The
+default value is set to @code{0}.
+
+ at item weight_Y
+Set the frequency domain weight expression for the luma plane.
+
+ at item weight_U
+Set the frequency domain weight expression for the 1st chroma plane.
+
+ at item weight_V
+Set the frequency domain weight expression for the 2nd chroma plane.
+
+The filter accepts the following variables:
+ at item X
+ at item Y
+The coordinates of the current sample.
+
+ at item W
+ at item H
+The width and height of the image.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+High-pass:
+ at example
+fftfilt=dc_Y=128:weight_Y='squish(1-(Y+X)/100)'
+ at end example
+
+ at item
+Low-pass:
+ at example
+fftfilt=dc_Y=0:weight_Y='squish((Y+X)/100-1)'
+ at end example
+
+ at item
+Sharpen:
+ at example
+fftfilt=dc_Y=0:weight_Y='1+squish(1-(Y+X)/100)'
+ at end example
+
+ at end itemize
+
+ at section field
+
+Extract a single field from an interlaced image using stride
+arithmetic to avoid wasting CPU time. The output frames are marked as
+non-interlaced.
+
+The filter accepts the following options:
+
+ at table @option
+ at item type
+Specify whether to extract the top (if the value is @code{0} or
+ at code{top}) or the bottom field (if the value is @code{1} or
+ at code{bottom}).
+ at end table
+
+ at section fieldmatch
+
+Field matching filter for inverse telecine. It is meant to reconstruct the
+progressive frames from a telecined stream. The filter does not drop duplicated
+frames, so to achieve a complete inverse telecine @code{fieldmatch} needs to be
+followed by a decimation filter such as @ref{decimate} in the filtergraph.
+
+The separation of the field matching and the decimation is notably motivated by
+the possibility of inserting a de-interlacing filter fallback between the two.
+If the source has mixed telecined and real interlaced content,
+ at code{fieldmatch} will not be able to match fields for the interlaced parts.
+But these remaining combed frames will be marked as interlaced, and thus can be
+de-interlaced by a later filter such as @ref{yadif} before decimation.
+
+In addition to the various configuration options, @code{fieldmatch} can take an
+optional second stream, activated through the @option{ppsrc} option. If
+enabled, the frames reconstruction will be based on the fields and frames from
+this second stream. This allows the first input to be pre-processed in order to
+help the various algorithms of the filter, while keeping the output lossless
+(assuming the fields are matched properly). Typically, a field-aware denoiser,
+or brightness/contrast adjustments can help.
+
+Note that this filter uses the same algorithms as TIVTC/TFM (AviSynth project)
+and VIVTC/VFM (VapourSynth project). The later is a light clone of TFM from
+which @code{fieldmatch} is based on. While the semantic and usage are very
+close, some behaviour and options names can differ.
+
+The @ref{decimate} filter currently only works for constant frame rate input.
+If your input has mixed telecined (30fps) and progressive content with a lower
+framerate like 24fps use the following filterchain to produce the necessary cfr
+stream: @code{dejudder,fps=30000/1001,fieldmatch,decimate}.
+
+The filter accepts the following options:
+
+ at table @option
+ at item order
+Specify the assumed field order of the input stream. Available values are:
+
+ at table @samp
+ at item auto
+Auto detect parity (use FFmpeg's internal parity value).
+ at item bff
+Assume bottom field first.
+ at item tff
+Assume top field first.
+ at end table
+
+Note that it is sometimes recommended not to trust the parity announced by the
+stream.
+
+Default value is @var{auto}.
+
+ at item mode
+Set the matching mode or strategy to use. @option{pc} mode is the safest in the
+sense that it won't risk creating jerkiness due to duplicate frames when
+possible, but if there are bad edits or blended fields it will end up
+outputting combed frames when a good match might actually exist. On the other
+hand, @option{pcn_ub} mode is the most risky in terms of creating jerkiness,
+but will almost always find a good frame if there is one. The other values are
+all somewhere in between @option{pc} and @option{pcn_ub} in terms of risking
+jerkiness and creating duplicate frames versus finding good matches in sections
+with bad edits, orphaned fields, blended fields, etc.
+
+More details about p/c/n/u/b are available in @ref{p/c/n/u/b meaning} section.
+
+Available values are:
+
+ at table @samp
+ at item pc
+2-way matching (p/c)
+ at item pc_n
+2-way matching, and trying 3rd match if still combed (p/c + n)
+ at item pc_u
+2-way matching, and trying 3rd match (same order) if still combed (p/c + u)
+ at item pc_n_ub
+2-way matching, trying 3rd match if still combed, and trying 4th/5th matches if
+still combed (p/c + n + u/b)
+ at item pcn
+3-way matching (p/c/n)
+ at item pcn_ub
+3-way matching, and trying 4th/5th matches if all 3 of the original matches are
+detected as combed (p/c/n + u/b)
+ at end table
+
+The parenthesis at the end indicate the matches that would be used for that
+mode assuming @option{order}=@var{tff} (and @option{field} on @var{auto} or
+ at var{top}).
+
+In terms of speed @option{pc} mode is by far the fastest and @option{pcn_ub} is
+the slowest.
+
+Default value is @var{pc_n}.
+
+ at item ppsrc
+Mark the main input stream as a pre-processed input, and enable the secondary
+input stream as the clean source to pick the fields from. See the filter
+introduction for more details. It is similar to the @option{clip2} feature from
+VFM/TFM.
+
+Default value is @code{0} (disabled).
+
+ at item field
+Set the field to match from. It is recommended to set this to the same value as
+ at option{order} unless you experience matching failures with that setting. In
+certain circumstances changing the field that is used to match from can have a
+large impact on matching performance. Available values are:
+
+ at table @samp
+ at item auto
+Automatic (same value as @option{order}).
+ at item bottom
+Match from the bottom field.
+ at item top
+Match from the top field.
+ at end table
+
+Default value is @var{auto}.
+
+ at item mchroma
+Set whether or not chroma is included during the match comparisons. In most
+cases it is recommended to leave this enabled. You should set this to @code{0}
+only if your clip has bad chroma problems such as heavy rainbowing or other
+artifacts. Setting this to @code{0} could also be used to speed things up at
+the cost of some accuracy.
+
+Default value is @code{1}.
+
+ at item y0
+ at item y1
+These define an exclusion band which excludes the lines between @option{y0} and
+ at option{y1} from being included in the field matching decision. An exclusion
+band can be used to ignore subtitles, a logo, or other things that may
+interfere with the matching. @option{y0} sets the starting scan line and
+ at option{y1} sets the ending line; all lines in between @option{y0} and
+ at option{y1} (including @option{y0} and @option{y1}) will be ignored. Setting
+ at option{y0} and @option{y1} to the same value will disable the feature.
+ at option{y0} and @option{y1} defaults to @code{0}.
+
+ at item scthresh
+Set the scene change detection threshold as a percentage of maximum change on
+the luma plane. Good values are in the @code{[8.0, 14.0]} range. Scene change
+detection is only relevant in case @option{combmatch}=@var{sc}. The range for
+ at option{scthresh} is @code{[0.0, 100.0]}.
+
+Default value is @code{12.0}.
+
+ at item combmatch
+When @option{combatch} is not @var{none}, @code{fieldmatch} will take into
+account the combed scores of matches when deciding what match to use as the
+final match. Available values are:
+
+ at table @samp
+ at item none
+No final matching based on combed scores.
+ at item sc
+Combed scores are only used when a scene change is detected.
+ at item full
+Use combed scores all the time.
+ at end table
+
+Default is @var{sc}.
+
+ at item combdbg
+Force @code{fieldmatch} to calculate the combed metrics for certain matches and
+print them. This setting is known as @option{micout} in TFM/VFM vocabulary.
+Available values are:
+
+ at table @samp
+ at item none
+No forced calculation.
+ at item pcn
+Force p/c/n calculations.
+ at item pcnub
+Force p/c/n/u/b calculations.
+ at end table
+
+Default value is @var{none}.
+
+ at item cthresh
+This is the area combing threshold used for combed frame detection. This
+essentially controls how "strong" or "visible" combing must be to be detected.
+Larger values mean combing must be more visible and smaller values mean combing
+can be less visible or strong and still be detected. Valid settings are from
+ at code{-1} (every pixel will be detected as combed) to @code{255} (no pixel will
+be detected as combed). This is basically a pixel difference value. A good
+range is @code{[8, 12]}.
+
+Default value is @code{9}.
+
+ at item chroma
+Sets whether or not chroma is considered in the combed frame decision. Only
+disable this if your source has chroma problems (rainbowing, etc.) that are
+causing problems for the combed frame detection with chroma enabled. Actually,
+using @option{chroma}=@var{0} is usually more reliable, except for the case
+where there is chroma only combing in the source.
+
+Default value is @code{0}.
+
+ at item blockx
+ at item blocky
+Respectively set the x-axis and y-axis size of the window used during combed
+frame detection. This has to do with the size of the area in which
+ at option{combpel} pixels are required to be detected as combed for a frame to be
+declared combed. See the @option{combpel} parameter description for more info.
+Possible values are any number that is a power of 2 starting at 4 and going up
+to 512.
+
+Default value is @code{16}.
+
+ at item combpel
+The number of combed pixels inside any of the @option{blocky} by
+ at option{blockx} size blocks on the frame for the frame to be detected as
+combed. While @option{cthresh} controls how "visible" the combing must be, this
+setting controls "how much" combing there must be in any localized area (a
+window defined by the @option{blockx} and @option{blocky} settings) on the
+frame. Minimum value is @code{0} and maximum is @code{blocky x blockx} (at
+which point no frames will ever be detected as combed). This setting is known
+as @option{MI} in TFM/VFM vocabulary.
+
+Default value is @code{80}.
+ at end table
+
+ at anchor{p/c/n/u/b meaning}
+ at subsection p/c/n/u/b meaning
+
+ at subsubsection p/c/n
+
+We assume the following telecined stream:
+
+ at example
+Top fields: 1 2 2 3 4
+Bottom fields: 1 2 3 4 4
+ at end example
+
+The numbers correspond to the progressive frame the fields relate to. Here, the
+first two frames are progressive, the 3rd and 4th are combed, and so on.
+
+When @code{fieldmatch} is configured to run a matching from bottom
+(@option{field}=@var{bottom}) this is how this input stream get transformed:
+
+ at example
+Input stream:
+ T 1 2 2 3 4
+ B 1 2 3 4 4 <-- matching reference
+
+Matches: c c n n c
+
+Output stream:
+ T 1 2 3 4 4
+ B 1 2 3 4 4
+ at end example
+
+As a result of the field matching, we can see that some frames get duplicated.
+To perform a complete inverse telecine, you need to rely on a decimation filter
+after this operation. See for instance the @ref{decimate} filter.
+
+The same operation now matching from top fields (@option{field}=@var{top})
+looks like this:
+
+ at example
+Input stream:
+ T 1 2 2 3 4 <-- matching reference
+ B 1 2 3 4 4
+
+Matches: c c p p c
+
+Output stream:
+ T 1 2 2 3 4
+ B 1 2 2 3 4
+ at end example
+
+In these examples, we can see what @var{p}, @var{c} and @var{n} mean;
+basically, they refer to the frame and field of the opposite parity:
+
+ at itemize
+ at item @var{p} matches the field of the opposite parity in the previous frame
+ at item @var{c} matches the field of the opposite parity in the current frame
+ at item @var{n} matches the field of the opposite parity in the next frame
+ at end itemize
+
+ at subsubsection u/b
+
+The @var{u} and @var{b} matching are a bit special in the sense that they match
+from the opposite parity flag. In the following examples, we assume that we are
+currently matching the 2nd frame (Top:2, bottom:2). According to the match, a
+'x' is placed above and below each matched fields.
+
+With bottom matching (@option{field}=@var{bottom}):
+ at example
+Match: c p n b u
+
+ x x x x x
+ Top 1 2 2 1 2 2 1 2 2 1 2 2 1 2 2
+ Bottom 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
+ x x x x x
+
+Output frames:
+ 2 1 2 2 2
+ 2 2 2 1 3
+ at end example
+
+With top matching (@option{field}=@var{top}):
+ at example
+Match: c p n b u
+
+ x x x x x
+ Top 1 2 2 1 2 2 1 2 2 1 2 2 1 2 2
+ Bottom 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
+ x x x x x
+
+Output frames:
+ 2 2 2 1 2
+ 2 1 3 2 2
+ at end example
+
+ at subsection Examples
+
+Simple IVTC of a top field first telecined stream:
+ at example
+fieldmatch=order=tff:combmatch=none, decimate
+ at end example
+
+Advanced IVTC, with fallback on @ref{yadif} for still combed frames:
+ at example
+fieldmatch=order=tff:combmatch=full, yadif=deint=interlaced, decimate
+ at end example
+
+ at section fieldorder
+
+Transform the field order of the input video.
+
+It accepts the following parameters:
+
+ at table @option
+
+ at item order
+The output field order. Valid values are @var{tff} for top field first or @var{bff}
+for bottom field first.
+ at end table
+
+The default value is @samp{tff}.
+
+The transformation is done by shifting the picture content up or down
+by one line, and filling the remaining line with appropriate picture content.
+This method is consistent with most broadcast field order converters.
+
+If the input video is not flagged as being interlaced, or it is already
+flagged as being of the required output field order, then this filter does
+not alter the incoming video.
+
+It is very useful when converting to or from PAL DV material,
+which is bottom field first.
+
+For example:
+ at example
+ffmpeg -i in.vob -vf "fieldorder=bff" out.dv
+ at end example
+
+ at section fifo
+
+Buffer input images and send them when they are requested.
+
+It is mainly useful when auto-inserted by the libavfilter
+framework.
+
+It does not take parameters.
+
+ at section find_rect
+
+Find a rectangular object
+
+It accepts the following options:
+
+ at table @option
+ at item object
+Filepath of the object image, needs to be in gray8.
+
+ at item threshold
+Detection threshold, default is 0.5.
+
+ at item mipmaps
+Number of mipmaps, default is 3.
+
+ at item xmin, ymin, xmax, ymax
+Specifies the rectangle in which to search.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Generate a representative palette of a given video using @command{ffmpeg}:
+ at example
+ffmpeg -i file.ts -vf find_rect=newref.pgm,cover_rect=cover.jpg:mode=cover new.mkv
+ at end example
+ at end itemize
+
+ at section cover_rect
+
+Cover a rectangular object
+
+It accepts the following options:
+
+ at table @option
+ at item cover
+Filepath of the optional cover image, needs to be in yuv420.
+
+ at item mode
+Set covering mode.
+
+It accepts the following values:
+ at table @samp
+ at item cover
+cover it by the supplied image
+ at item blur
+cover it by interpolating the surrounding pixels
+ at end table
+
+Default value is @var{blur}.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Generate a representative palette of a given video using @command{ffmpeg}:
+ at example
+ffmpeg -i file.ts -vf find_rect=newref.pgm,cover_rect=cover.jpg:mode=cover new.mkv
+ at end example
+ at end itemize
+
+ at anchor{format}
+ at section format
+
+Convert the input video to one of the specified pixel formats.
+Libavfilter will try to pick one that is suitable as input to
+the next filter.
+
+It accepts the following parameters:
+ at table @option
+
+ at item pix_fmts
+A '|'-separated list of pixel format names, such as
+"pix_fmts=yuv420p|monow|rgb24".
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Convert the input video to the @var{yuv420p} format
+ at example
+format=pix_fmts=yuv420p
+ at end example
+
+Convert the input video to any of the formats in the list
+ at example
+format=pix_fmts=yuv420p|yuv444p|yuv410p
+ at end example
+ at end itemize
+
+ at anchor{fps}
+ at section fps
+
+Convert the video to specified constant frame rate by duplicating or dropping
+frames as necessary.
+
+It accepts the following parameters:
+ at table @option
+
+ at item fps
+The desired output frame rate. The default is @code{25}.
+
+ at item round
+Rounding method.
+
+Possible values are:
+ at table @option
+ at item zero
+zero round towards 0
+ at item inf
+round away from 0
+ at item down
+round towards -infinity
+ at item up
+round towards +infinity
+ at item near
+round to nearest
+ at end table
+The default is @code{near}.
+
+ at item start_time
+Assume the first PTS should be the given value, in seconds. This allows for
+padding/trimming at the start of stream. By default, no assumption is made
+about the first frame's expected PTS, so no padding or trimming is done.
+For example, this could be set to 0 to pad the beginning with duplicates of
+the first frame if a video stream starts after the audio stream or to trim any
+frames with a negative PTS.
+
+ at end table
+
+Alternatively, the options can be specified as a flat string:
+ at var{fps}[:@var{round}].
+
+See also the @ref{setpts} filter.
+
+ at subsection Examples
+
+ at itemize
+ at item
+A typical usage in order to set the fps to 25:
+ at example
+fps=fps=25
+ at end example
+
+ at item
+Sets the fps to 24, using abbreviation and rounding method to round to nearest:
+ at example
+fps=fps=film:round=near
+ at end example
+ at end itemize
+
+ at section framepack
+
+Pack two different video streams into a stereoscopic video, setting proper
+metadata on supported codecs. The two views should have the same size and
+framerate and processing will stop when the shorter video ends. Please note
+that you may conveniently adjust view properties with the @ref{scale} and
+ at ref{fps} filters.
+
+It accepts the following parameters:
+ at table @option
+
+ at item format
+The desired packing format. Supported values are:
+
+ at table @option
+
+ at item sbs
+The views are next to each other (default).
+
+ at item tab
+The views are on top of each other.
+
+ at item lines
+The views are packed by line.
+
+ at item columns
+The views are packed by column.
+
+ at item frameseq
+The views are temporally interleaved.
+
+ at end table
+
+ at end table
+
+Some examples:
+
+ at example
+# Convert left and right views into a frame-sequential video
+ffmpeg -i LEFT -i RIGHT -filter_complex framepack=frameseq OUTPUT
+
+# Convert views into a side-by-side video with the same output resolution as the input
+ffmpeg -i LEFT -i RIGHT -filter_complex [0:v]scale=w=iw/2[left],[1:v]scale=w=iw/2[right],[left][right]framepack=sbs OUTPUT
+ at end example
+
+ at section framerate
+
+Change the frame rate by interpolating new video output frames from the source
+frames.
+
+This filter is not designed to function correctly with interlaced media. If
+you wish to change the frame rate of interlaced media then you are required
+to deinterlace before this filter and re-interlace after this filter.
+
+A description of the accepted options follows.
+
+ at table @option
+ at item fps
+Specify the output frames per second. This option can also be specified
+as a value alone. The default is @code{50}.
+
+ at item interp_start
+Specify the start of a range where the output frame will be created as a
+linear interpolation of two frames. The range is [@code{0}- at code{255}],
+the default is @code{15}.
+
+ at item interp_end
+Specify the end of a range where the output frame will be created as a
+linear interpolation of two frames. The range is [@code{0}- at code{255}],
+the default is @code{240}.
+
+ at item scene
+Specify the level at which a scene change is detected as a value between
+0 and 100 to indicate a new scene; a low value reflects a low
+probability for the current frame to introduce a new scene, while a higher
+value means the current frame is more likely to be one.
+The default is @code{7}.
+
+ at item flags
+Specify flags influencing the filter process.
+
+Available value for @var{flags} is:
+
+ at table @option
+ at item scene_change_detect, scd
+Enable scene change detection using the value of the option @var{scene}.
+This flag is enabled by default.
+ at end table
+ at end table
+
+ at section framestep
+
+Select one frame every N-th frame.
+
+This filter accepts the following option:
+ at table @option
+ at item step
+Select frame after every @code{step} frames.
+Allowed values are positive integers higher than 0. Default value is @code{1}.
+ at end table
+
+ at anchor{frei0r}
+ at section frei0r
+
+Apply a frei0r effect to the input video.
+
+To enable the compilation of this filter, you need to install the frei0r
+header and configure FFmpeg with @code{--enable-frei0r}.
+
+It accepts the following parameters:
+
+ at table @option
+
+ at item filter_name
+The name of the frei0r effect to load. If the environment variable
+ at env{FREI0R_PATH} is defined, the frei0r effect is searched for in each of the
+directories specified by the colon-separated list in @env{FREIOR_PATH}.
+Otherwise, the standard frei0r paths are searched, in this order:
+ at file{HOME/.frei0r-1/lib/}, @file{/usr/local/lib/frei0r-1/},
+ at file{/usr/lib/frei0r-1/}.
+
+ at item filter_params
+A '|'-separated list of parameters to pass to the frei0r effect.
+
+ at end table
+
+A frei0r effect parameter can be a boolean (its value is either
+"y" or "n"), a double, a color (specified as
+ at var{R}/@var{G}/@var{B}, where @var{R}, @var{G}, and @var{B} are floating point
+numbers between 0.0 and 1.0, inclusive) or by a color description specified in the "Color"
+section in the ffmpeg-utils manual), a position (specified as @var{X}/@var{Y}, where
+ at var{X} and @var{Y} are floating point numbers) and/or a string.
+
+The number and types of parameters depend on the loaded effect. If an
+effect parameter is not specified, the default value is set.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Apply the distort0r effect, setting the first two double parameters:
+ at example
+frei0r=filter_name=distort0r:filter_params=0.5|0.01
+ at end example
+
+ at item
+Apply the colordistance effect, taking a color as the first parameter:
+ at example
+frei0r=colordistance:0.2/0.3/0.4
+frei0r=colordistance:violet
+frei0r=colordistance:0x112233
+ at end example
+
+ at item
+Apply the perspective effect, specifying the top left and top right image
+positions:
+ at example
+frei0r=perspective:0.2/0.2|0.8/0.2
+ at end example
+ at end itemize
+
+For more information, see
+ at url{http://frei0r.dyne.org}
+
+ at section fspp
+
+Apply fast and simple postprocessing. It is a faster version of @ref{spp}.
+
+It splits (I)DCT into horizontal/vertical passes. Unlike the simple post-
+processing filter, one of them is performed once per block, not per pixel.
+This allows for much higher speed.
+
+The filter accepts the following options:
+
+ at table @option
+ at item quality
+Set quality. This option defines the number of levels for averaging. It accepts
+an integer in the range 4-5. Default value is @code{4}.
+
+ at item qp
+Force a constant quantization parameter. It accepts an integer in range 0-63.
+If not set, the filter will use the QP from the video stream (if available).
+
+ at item strength
+Set filter strength. It accepts an integer in range -15 to 32. Lower values mean
+more details but also more artifacts, while higher values make the image smoother
+but also blurrier. Default value is @code{0} − PSNR optimal.
+
+ at item use_bframe_qp
+Enable the use of the QP from the B-Frames if set to @code{1}. Using this
+option may cause flicker since the B-Frames have often larger QP. Default is
+ at code{0} (not enabled).
+
+ at end table
+
+ at section geq
+
+The filter accepts the following options:
+
+ at table @option
+ at item lum_expr, lum
+Set the luminance expression.
+ at item cb_expr, cb
+Set the chrominance blue expression.
+ at item cr_expr, cr
+Set the chrominance red expression.
+ at item alpha_expr, a
+Set the alpha expression.
+ at item red_expr, r
+Set the red expression.
+ at item green_expr, g
+Set the green expression.
+ at item blue_expr, b
+Set the blue expression.
+ at end table
+
+The colorspace is selected according to the specified options. If one
+of the @option{lum_expr}, @option{cb_expr}, or @option{cr_expr}
+options is specified, the filter will automatically select a YCbCr
+colorspace. If one of the @option{red_expr}, @option{green_expr}, or
+ at option{blue_expr} options is specified, it will select an RGB
+colorspace.
+
+If one of the chrominance expression is not defined, it falls back on the other
+one. If no alpha expression is specified it will evaluate to opaque value.
+If none of chrominance expressions are specified, they will evaluate
+to the luminance expression.
+
+The expressions can use the following variables and functions:
+
+ at table @option
+ at item N
+The sequential number of the filtered frame, starting from @code{0}.
+
+ at item X
+ at item Y
+The coordinates of the current sample.
+
+ at item W
+ at item H
+The width and height of the image.
+
+ at item SW
+ at item SH
+Width and height scale depending on the currently filtered plane. It is the
+ratio between the corresponding luma plane number of pixels and the current
+plane ones. E.g. for YUV4:2:0 the values are @code{1,1} for the luma plane, and
+ at code{0.5,0.5} for chroma planes.
+
+ at item T
+Time of the current frame, expressed in seconds.
+
+ at item p(x, y)
+Return the value of the pixel at location (@var{x}, at var{y}) of the current
+plane.
+
+ at item lum(x, y)
+Return the value of the pixel at location (@var{x}, at var{y}) of the luminance
+plane.
+
+ at item cb(x, y)
+Return the value of the pixel at location (@var{x}, at var{y}) of the
+blue-difference chroma plane. Return 0 if there is no such plane.
+
+ at item cr(x, y)
+Return the value of the pixel at location (@var{x}, at var{y}) of the
+red-difference chroma plane. Return 0 if there is no such plane.
+
+ at item r(x, y)
+ at item g(x, y)
+ at item b(x, y)
+Return the value of the pixel at location (@var{x}, at var{y}) of the
+red/green/blue component. Return 0 if there is no such component.
+
+ at item alpha(x, y)
+Return the value of the pixel at location (@var{x}, at var{y}) of the alpha
+plane. Return 0 if there is no such plane.
+ at end table
+
+For functions, if @var{x} and @var{y} are outside the area, the value will be
+automatically clipped to the closer edge.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Flip the image horizontally:
+ at example
+geq=p(W-X\,Y)
+ at end example
+
+ at item
+Generate a bidimensional sine wave, with angle @code{PI/3} and a
+wavelength of 100 pixels:
+ at example
+geq=128 + 100*sin(2*(PI/100)*(cos(PI/3)*(X-50*T) + sin(PI/3)*Y)):128:128
+ at end example
+
+ at item
+Generate a fancy enigmatic moving light:
+ at example
+nullsrc=s=256x256,geq=random(1)/hypot(X-cos(N*0.07)*W/2-W/2\,Y-sin(N*0.09)*H/2-H/2)^2*1000000*sin(N*0.02):128:128
+ at end example
+
+ at item
+Generate a quick emboss effect:
+ at example
+format=gray,geq=lum_expr='(p(X,Y)+(256-p(X-4,Y-4)))/2'
+ at end example
+
+ at item
+Modify RGB components depending on pixel position:
+ at example
+geq=r='X/W*r(X,Y)':g='(1-X/W)*g(X,Y)':b='(H-Y)/H*b(X,Y)'
+ at end example
+
+ at item
+Create a radial gradient that is the same size as the input (also see
+the @ref{vignette} filter):
+ at example
+geq=lum=255*gauss((X/W-0.5)*3)*gauss((Y/H-0.5)*3)/gauss(0)/gauss(0),format=gray
+ at end example
+
+ at item
+Create a linear gradient to use as a mask for another filter, then
+compose with @ref{overlay}. In this example the video will gradually
+become more blurry from the top to the bottom of the y-axis as defined
+by the linear gradient:
+ at example
+ffmpeg -i input.mp4 -filter_complex "geq=lum=255*(Y/H),format=gray[grad];[0:v]boxblur=4[blur];[blur][grad]alphamerge[alpha];[0:v][alpha]overlay" output.mp4
+ at end example
+ at end itemize
+
+ at section gradfun
+
+Fix the banding artifacts that are sometimes introduced into nearly flat
+regions by truncation to 8bit color depth.
+Interpolate the gradients that should go where the bands are, and
+dither them.
+
+It is designed for playback only. Do not use it prior to
+lossy compression, because compression tends to lose the dither and
+bring back the bands.
+
+It accepts the following parameters:
+
+ at table @option
+
+ at item strength
+The maximum amount by which the filter will change any one pixel. This is also
+the threshold for detecting nearly flat regions. Acceptable values range from
+.51 to 64; the default value is 1.2. Out-of-range values will be clipped to the
+valid range.
+
+ at item radius
+The neighborhood to fit the gradient to. A larger radius makes for smoother
+gradients, but also prevents the filter from modifying the pixels near detailed
+regions. Acceptable values are 8-32; the default value is 16. Out-of-range
+values will be clipped to the valid range.
+
+ at end table
+
+Alternatively, the options can be specified as a flat string:
+ at var{strength}[:@var{radius}]
+
+ at subsection Examples
+
+ at itemize
+ at item
+Apply the filter with a @code{3.5} strength and radius of @code{8}:
+ at example
+gradfun=3.5:8
+ at end example
+
+ at item
+Specify radius, omitting the strength (which will fall-back to the default
+value):
+ at example
+gradfun=radius=8
+ at end example
+
+ at end itemize
+
+ at anchor{haldclut}
+ at section haldclut
+
+Apply a Hald CLUT to a video stream.
+
+First input is the video stream to process, and second one is the Hald CLUT.
+The Hald CLUT input can be a simple picture or a complete video stream.
+
+The filter accepts the following options:
+
+ at table @option
+ at item shortest
+Force termination when the shortest input terminates. Default is @code{0}.
+ at item repeatlast
+Continue applying the last CLUT after the end of the stream. A value of
+ at code{0} disable the filter after the last frame of the CLUT is reached.
+Default is @code{1}.
+ at end table
+
+ at code{haldclut} also has the same interpolation options as @ref{lut3d} (both
+filters share the same internals).
+
+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}.
+
+ at subsection Workflow examples
+
+ at subsubsection Hald CLUT video stream
+
+Generate an identity Hald CLUT stream altered with various effects:
+ at example
+ffmpeg -f lavfi -i @ref{haldclutsrc}=8 -vf "hue=H=2*PI*t:s=sin(2*PI*t)+1, curves=cross_process" -t 10 -c:v ffv1 clut.nut
+ at end example
+
+Note: make sure you use a lossless codec.
+
+Then use it with @code{haldclut} to apply it on some random stream:
+ at example
+ffmpeg -f lavfi -i mandelbrot -i clut.nut -filter_complex '[0][1] haldclut' -t 20 mandelclut.mkv
+ at end example
+
+The Hald CLUT will be applied to the 10 first seconds (duration of
+ at file{clut.nut}), then the latest picture of that CLUT stream will be applied
+to the remaining frames of the @code{mandelbrot} stream.
+
+ at subsubsection Hald CLUT with preview
+
+A Hald CLUT is supposed to be a squared image of @code{Level*Level*Level} by
+ at code{Level*Level*Level} pixels. For a given Hald CLUT, FFmpeg will select the
+biggest possible square starting at the top left of the picture. The remaining
+padding pixels (bottom or right) will be ignored. This area can be used to add
+a preview of the Hald CLUT.
+
+Typically, the following generated Hald CLUT will be supported by the
+ at code{haldclut} filter:
+
+ at example
+ffmpeg -f lavfi -i @ref{haldclutsrc}=8 -vf "
+ pad=iw+320 [padded_clut];
+ smptebars=s=320x256, split [a][b];
+ [padded_clut][a] overlay=W-320:h, curves=color_negative [main];
+ [main][b] overlay=W-320" -frames:v 1 clut.png
+ at end example
+
+It contains the original and a preview of the effect of the CLUT: SMPTE color
+bars are displayed on the right-top, and below the same color bars processed by
+the color changes.
+
+Then, the effect of this Hald CLUT can be visualized with:
+ at example
+ffplay input.mkv -vf "movie=clut.png, [in] haldclut"
+ at end example
+
+ at section hflip
+
+Flip the input video horizontally.
+
+For example, to horizontally flip the input video with @command{ffmpeg}:
+ at example
+ffmpeg -i in.avi -vf "hflip" out.avi
+ at end example
+
+ at section histeq
+This filter applies a global color histogram equalization on a
+per-frame basis.
+
+It can be used to correct video that has a compressed range of pixel
+intensities. The filter redistributes the pixel intensities to
+equalize their distribution across the intensity range. It may be
+viewed as an "automatically adjusting contrast filter". This filter is
+useful only for correcting degraded or poorly captured source
+video.
+
+The filter accepts the following options:
+
+ at table @option
+ at item strength
+Determine the amount of equalization to be applied. As the strength
+is reduced, the distribution of pixel intensities more-and-more
+approaches that of the input frame. The value must be a float number
+in the range [0,1] and defaults to 0.200.
+
+ at item intensity
+Set the maximum intensity that can generated and scale the output
+values appropriately. The strength should be set as desired and then
+the intensity can be limited if needed to avoid washing-out. The value
+must be a float number in the range [0,1] and defaults to 0.210.
+
+ at item antibanding
+Set the antibanding level. If enabled the filter will randomly vary
+the luminance of output pixels by a small amount to avoid banding of
+the histogram. Possible values are @code{none}, @code{weak} or
+ at code{strong}. It defaults to @code{none}.
+ at end table
+
+ at section histogram
+
+Compute and draw a color distribution histogram for the input video.
+
+The computed histogram is a representation of the color component
+distribution in an image.
+
+The filter accepts the following options:
+
+ at table @option
+ at item mode
+Set histogram mode.
+
+It accepts the following values:
+ at table @samp
+ at item levels
+Standard histogram that displays the color components distribution in an
+image. Displays color graph for each color component. Shows distribution of
+the Y, U, V, A or R, G, B components, depending on input format, in the
+current frame. Below each graph a color component scale meter is shown.
+
+ at item color
+Displays chroma values (U/V color placement) in a two dimensional
+graph (which is called a vectorscope). The brighter a pixel in the
+vectorscope, the more pixels of the input frame correspond to that pixel
+(i.e., more pixels have this chroma value). The V component is displayed on
+the horizontal (X) axis, with the leftmost side being V = 0 and the rightmost
+side being V = 255. The U component is displayed on the vertical (Y) axis,
+with the top representing U = 0 and the bottom representing U = 255.
+
+The position of a white pixel in the graph corresponds to the chroma value of
+a pixel of the input clip. The graph can therefore be used to read the hue
+(color flavor) and the saturation (the dominance of the hue in the color). As
+the hue of a color changes, it moves around the square. At the center of the
+square the saturation is zero, which means that the corresponding pixel has no
+color. If the amount of a specific color is increased (while leaving the other
+colors unchanged) the saturation increases, and the indicator moves towards
+the edge of the square.
+
+ at item color2
+Chroma values in vectorscope, similar as @code{color} but actual chroma values
+are displayed.
+
+ at item waveform
+Per row/column color component graph. In row mode, the graph on the left side
+represents color component value 0 and the right side represents value = 255.
+In column mode, the top side represents color component value = 0 and bottom
+side represents value = 255.
+ at end table
+Default value is @code{levels}.
+
+ at item level_height
+Set height of level in @code{levels}. Default value is @code{200}.
+Allowed range is [50, 2048].
+
+ at item scale_height
+Set height of color scale in @code{levels}. Default value is @code{12}.
+Allowed range is [0, 40].
+
+ at item step
+Set step for @code{waveform} mode. Smaller values are useful to find out how
+many values of the same luminance are distributed across input rows/columns.
+Default value is @code{10}. Allowed range is [1, 255].
+
+ at item waveform_mode
+Set mode for @code{waveform}. Can be either @code{row}, or @code{column}.
+Default is @code{row}.
+
+ at item waveform_mirror
+Set mirroring mode for @code{waveform}. @code{0} means unmirrored, @code{1}
+means mirrored. In mirrored mode, higher values will be represented on the left
+side for @code{row} mode and at the top for @code{column} mode. Default is
+ at code{0} (unmirrored).
+
+ at item display_mode
+Set display mode for @code{waveform} and @code{levels}.
+It accepts the following values:
+ at table @samp
+ at item parade
+Display separate graph for the color components side by side in
+ at code{row} waveform mode or one below the other in @code{column} waveform mode
+for @code{waveform} histogram mode. For @code{levels} histogram mode,
+per color component graphs are placed below each other.
+
+Using this display mode in @code{waveform} histogram mode makes it easy to
+spot color casts in the highlights and shadows of an image, by comparing the
+contours of the top and the bottom graphs of each waveform. Since whites,
+grays, and blacks are characterized by exactly equal amounts of red, green,
+and blue, neutral areas of the picture should display three waveforms of
+roughly equal width/height. If not, the correction is easy to perform by
+making level adjustments the three waveforms.
+
+ at item overlay
+Presents information identical to that in the @code{parade}, except
+that the graphs representing color components are superimposed directly
+over one another.
+
+This display mode in @code{waveform} histogram mode makes it easier to spot
+relative differences or similarities in overlapping areas of the color
+components that are supposed to be identical, such as neutral whites, grays,
+or blacks.
+ at end table
+Default is @code{parade}.
+
+ at item levels_mode
+Set mode for @code{levels}. Can be either @code{linear}, or @code{logarithmic}.
+Default is @code{linear}.
+
+ at item components
+Set what color components to display for mode @code{levels}.
+Default is @code{7}.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+
+ at item
+Calculate and draw histogram:
+ at example
+ffplay -i input -vf histogram
+ at end example
+
+ at end itemize
+
+ at anchor{hqdn3d}
+ at section hqdn3d
+
+This is a high precision/quality 3d denoise filter. It aims to reduce
+image noise, producing smooth images and making still images really
+still. It should enhance compressibility.
+
+It accepts the following optional parameters:
+
+ at table @option
+ at item luma_spatial
+A non-negative floating point number which specifies spatial luma strength.
+It defaults to 4.0.
+
+ at item chroma_spatial
+A non-negative floating point number which specifies spatial chroma strength.
+It defaults to 3.0*@var{luma_spatial}/4.0.
+
+ at item luma_tmp
+A floating point number which specifies luma temporal strength. It defaults to
+6.0*@var{luma_spatial}/4.0.
+
+ at item chroma_tmp
+A floating point number which specifies chroma temporal strength. It defaults to
+ at var{luma_tmp}*@var{chroma_spatial}/@var{luma_spatial}.
+ at end table
+
+ at section hqx
+
+Apply a high-quality magnification filter designed for pixel art. This filter
+was originally created by Maxim Stepin.
+
+It accepts the following option:
+
+ at table @option
+ at item n
+Set the scaling dimension: @code{2} for @code{hq2x}, @code{3} for
+ at code{hq3x} and @code{4} for @code{hq4x}.
+Default is @code{3}.
+ at end table
+
+ at section hstack
+Stack input videos horizontally.
+
+All streams must be of same pixel format and of same height.
+
+Note that this filter is faster than using @ref{overlay} and @ref{pad} filter
+to create same output.
+
+The filter accept the following option:
+
+ at table @option
+ at item nb_inputs
+Set number of input streams. Default is 2.
+ at end table
+
+ at section hue
+
+Modify the hue and/or the saturation of the input.
+
+It accepts the following parameters:
+
+ at table @option
+ at item h
+Specify the hue angle as a number of degrees. It accepts an expression,
+and defaults to "0".
+
+ at item s
+Specify the saturation in the [-10,10] range. It accepts an expression and
+defaults to "1".
+
+ at item H
+Specify the hue angle as a number of radians. It accepts an
+expression, and defaults to "0".
+
+ at item b
+Specify the brightness in the [-10,10] range. It accepts an expression and
+defaults to "0".
+ at end table
+
+ at option{h} and @option{H} are mutually exclusive, and can't be
+specified at the same time.
+
+The @option{b}, @option{h}, @option{H} and @option{s} option values are
+expressions containing the following constants:
+
+ at table @option
+ at item n
+frame count of the input frame starting from 0
+
+ at item pts
+presentation timestamp of the input frame expressed in time base units
+
+ at item r
+frame rate of the input video, NAN if the input frame rate is unknown
+
+ at item t
+timestamp expressed in seconds, NAN if the input timestamp is unknown
+
+ at item tb
+time base of the input video
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Set the hue to 90 degrees and the saturation to 1.0:
+ at example
+hue=h=90:s=1
+ at end example
+
+ at item
+Same command but expressing the hue in radians:
+ at example
+hue=H=PI/2:s=1
+ at end example
+
+ at item
+Rotate hue and make the saturation swing between 0
+and 2 over a period of 1 second:
+ at example
+hue="H=2*PI*t: s=sin(2*PI*t)+1"
+ at end example
+
+ at item
+Apply a 3 seconds saturation fade-in effect starting at 0:
+ at example
+hue="s=min(t/3\,1)"
+ at end example
+
+The general fade-in expression can be written as:
+ at example
+hue="s=min(0\, max((t-START)/DURATION\, 1))"
+ at end example
+
+ at item
+Apply a 3 seconds saturation fade-out effect starting at 5 seconds:
+ at example
+hue="s=max(0\, min(1\, (8-t)/3))"
+ at end example
+
+The general fade-out expression can be written as:
+ at example
+hue="s=max(0\, min(1\, (START+DURATION-t)/DURATION))"
+ at end example
+
+ at end itemize
+
+ at subsection Commands
+
+This filter supports the following commands:
+ at table @option
+ at item b
+ at item s
+ at item h
+ at item H
+Modify the hue and/or the saturation and/or brightness of the input video.
+The command accepts the same syntax of the corresponding option.
+
+If the specified expression is not valid, it is kept at its current
+value.
+ at end table
+
+ at section idet
+
+Detect video interlacing type.
+
+This filter tries to detect if the input frames as interlaced, progressive,
+top or bottom field first. It will also try and detect fields that are
+repeated between adjacent frames (a sign of telecine).
+
+Single frame detection considers only immediately adjacent frames when classifying each frame.
+Multiple frame detection incorporates the classification history of previous frames.
+
+The filter will log these metadata values:
+
+ at table @option
+ at item single.current_frame
+Detected type of current frame using single-frame detection. One of:
+``tff'' (top field first), ``bff'' (bottom field first),
+``progressive'', or ``undetermined''
+
+ at item single.tff
+Cumulative number of frames detected as top field first using single-frame detection.
+
+ at item multiple.tff
+Cumulative number of frames detected as top field first using multiple-frame detection.
+
+ at item single.bff
+Cumulative number of frames detected as bottom field first using single-frame detection.
+
+ at item multiple.current_frame
+Detected type of current frame using multiple-frame detection. One of:
+``tff'' (top field first), ``bff'' (bottom field first),
+``progressive'', or ``undetermined''
+
+ at item multiple.bff
+Cumulative number of frames detected as bottom field first using multiple-frame detection.
+
+ at item single.progressive
+Cumulative number of frames detected as progressive using single-frame detection.
+
+ at item multiple.progressive
+Cumulative number of frames detected as progressive using multiple-frame detection.
+
+ at item single.undetermined
+Cumulative number of frames that could not be classified using single-frame detection.
+
+ at item multiple.undetermined
+Cumulative number of frames that could not be classified using multiple-frame detection.
+
+ at item repeated.current_frame
+Which field in the current frame is repeated from the last. One of ``neither'', ``top'', or ``bottom''.
+
+ at item repeated.neither
+Cumulative number of frames with no repeated field.
+
+ at item repeated.top
+Cumulative number of frames with the top field repeated from the previous frame's top field.
+
+ at item repeated.bottom
+Cumulative number of frames with the bottom field repeated from the previous frame's bottom field.
+ at end table
+
+The filter accepts the following options:
+
+ at table @option
+ at item intl_thres
+Set interlacing threshold.
+ at item prog_thres
+Set progressive threshold.
+ at item repeat_thres
+Threshold for repeated field detection.
+ at item half_life
+Number of frames after which a given frame's contribution to the
+statistics is halved (i.e., it contributes only 0.5 to it's
+classification). The default of 0 means that all frames seen are given
+full weight of 1.0 forever.
+ at item analyze_interlaced_flag
+When this is not 0 then idet will use the specified number of frames to determine
+if the interlaced flag is accurate, it will not count undetermined frames.
+If the flag is found to be accurate it will be used without any further
+computations, if it is found to be inaccurate it will be cleared without any
+further computations. This allows inserting the idet filter as a low computational
+method to clean up the interlaced flag
+ at end table
+
+ at section il
+
+Deinterleave or interleave fields.
+
+This filter allows one to process interlaced images fields without
+deinterlacing them. Deinterleaving splits the input frame into 2
+fields (so called half pictures). Odd lines are moved to the top
+half of the output image, even lines to the bottom half.
+You can process (filter) them independently and then re-interleave them.
+
+The filter accepts the following options:
+
+ at table @option
+ at item luma_mode, l
+ at item chroma_mode, c
+ at item alpha_mode, a
+Available values for @var{luma_mode}, @var{chroma_mode} and
+ at var{alpha_mode} are:
+
+ at table @samp
+ at item none
+Do nothing.
+
+ at item deinterleave, d
+Deinterleave fields, placing one above the other.
+
+ at item interleave, i
+Interleave fields. Reverse the effect of deinterleaving.
+ at end table
+Default value is @code{none}.
+
+ at item luma_swap, ls
+ at item chroma_swap, cs
+ at item alpha_swap, as
+Swap luma/chroma/alpha fields. Exchange even & odd lines. Default value is @code{0}.
+ at end table
+
+ at section inflate
+
+Apply inflate effect to the video.
+
+This filter replaces the pixel by the local(3x3) average by taking into account
+only values higher than the pixel.
+
+It accepts the following options:
+
+ at table @option
+ at item threshold0
+ at item threshold1
+ at item threshold2
+ at item threshold3
+Limit the maximum change for each plane, default is 65535.
+If 0, plane will remain unchanged.
+ at end table
+
+ at section interlace
+
+Simple interlacing filter from progressive contents. This interleaves upper (or
+lower) lines from odd frames with lower (or upper) lines from even frames,
+halving the frame rate and preserving image height.
+
+ at example
+ Original Original New Frame
+ Frame 'j' Frame 'j+1' (tff)
+ ========== =========== ==================
+ Line 0 --------------------> Frame 'j' Line 0
+ Line 1 Line 1 ----> Frame 'j+1' Line 1
+ Line 2 ---------------------> Frame 'j' Line 2
+ Line 3 Line 3 ----> Frame 'j+1' Line 3
+ ... ... ...
+New Frame + 1 will be generated by Frame 'j+2' and Frame 'j+3' and so on
+ at end example
+
+It accepts the following optional parameters:
+
+ at table @option
+ at item scan
+This determines whether the interlaced frame is taken from the even
+(tff - default) or odd (bff) lines of the progressive frame.
+
+ at item lowpass
+Enable (default) or disable the vertical lowpass filter to avoid twitter
+interlacing and reduce moire patterns.
+ at end table
+
+ at section kerndeint
+
+Deinterlace input video by applying Donald Graft's adaptive kernel
+deinterling. Work on interlaced parts of a video to produce
+progressive frames.
+
+The description of the accepted parameters follows.
+
+ at table @option
+ at item thresh
+Set the threshold which affects the filter's tolerance when
+determining if a pixel line must be processed. It must be an integer
+in the range [0,255] and defaults to 10. A value of 0 will result in
+applying the process on every pixels.
+
+ at item map
+Paint pixels exceeding the threshold value to white if set to 1.
+Default is 0.
+
+ at item order
+Set the fields order. Swap fields if set to 1, leave fields alone if
+0. Default is 0.
+
+ at item sharp
+Enable additional sharpening if set to 1. Default is 0.
+
+ at item twoway
+Enable twoway sharpening if set to 1. Default is 0.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Apply default values:
+ at example
+kerndeint=thresh=10:map=0:order=0:sharp=0:twoway=0
+ at end example
+
+ at item
+Enable additional sharpening:
+ at example
+kerndeint=sharp=1
+ at end example
+
+ at item
+Paint processed pixels in white:
+ at example
+kerndeint=map=1
+ at end example
+ at end itemize
+
+ at section lenscorrection
+
+Correct radial lens distortion
+
+This filter can be used to correct for radial distortion as can result from the use
+of wide angle lenses, and thereby re-rectify the image. To find the right parameters
+one can use tools available for example as part of opencv or simply trial-and-error.
+To use opencv use the calibration sample (under samples/cpp) from the opencv sources
+and extract the k1 and k2 coefficients from the resulting matrix.
+
+Note that effectively the same filter is available in the open-source tools Krita and
+Digikam from the KDE project.
+
+In contrast to the @ref{vignette} filter, which can also be used to compensate lens errors,
+this filter corrects the distortion of the image, whereas @ref{vignette} corrects the
+brightness distribution, so you may want to use both filters together in certain
+cases, though you will have to take care of ordering, i.e. whether vignetting should
+be applied before or after lens correction.
+
+ at subsection Options
+
+The filter accepts the following options:
+
+ at table @option
+ at item cx
+Relative x-coordinate of the focal point of the image, and thereby the center of the
+distortion. This value has a range [0,1] and is expressed as fractions of the image
+width.
+ at item cy
+Relative y-coordinate of the focal point of the image, and thereby the center of the
+distortion. This value has a range [0,1] and is expressed as fractions of the image
+height.
+ at item k1
+Coefficient of the quadratic correction term. 0.5 means no correction.
+ at item k2
+Coefficient of the double quadratic correction term. 0.5 means no correction.
+ at end table
+
+The formula that generates the correction is:
+
+ at var{r_src} = @var{r_tgt} * (1 + @var{k1} * (@var{r_tgt} / @var{r_0})^2 + @var{k2} * (@var{r_tgt} / @var{r_0})^4)
+
+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.
+
+ at anchor{lut3d}
+ at section lut3d
+
+Apply a 3D LUT to an input video.
+
+The filter accepts the following options:
+
+ at table @option
+ at item file
+Set the 3D LUT file name.
+
+Currently supported formats:
+ at table @samp
+ at item 3dl
+AfterEffects
+ at item cube
+Iridas
+ at item dat
+DaVinci
+ at item m3d
+Pandora
+ at end table
+ at item interp
+Select interpolation mode.
+
+Available values are:
+
+ at table @samp
+ at item nearest
+Use values from the nearest defined point.
+ at item trilinear
+Interpolate values using the 8 points defining a cube.
+ at item tetrahedral
+Interpolate values using a tetrahedron.
+ at end table
+ at end table
+
+ at section lut, lutrgb, lutyuv
+
+Compute a look-up table for binding each pixel component input value
+to an output value, and apply it to the input video.
+
+ at var{lutyuv} applies a lookup table to a YUV input video, @var{lutrgb}
+to an RGB input video.
+
+These filters accept the following parameters:
+ at table @option
+ at item c0
+set first pixel component expression
+ at item c1
+set second pixel component expression
+ at item c2
+set third pixel component expression
+ at item c3
+set fourth pixel component expression, corresponds to the alpha component
+
+ at item r
+set red component expression
+ at item g
+set green component expression
+ at item b
+set blue component expression
+ at item a
+alpha component expression
+
+ at item y
+set Y/luminance component expression
+ at item u
+set U/Cb component expression
+ at item v
+set V/Cr component expression
+ at end table
+
+Each of them specifies the expression to use for computing the lookup table for
+the corresponding pixel component values.
+
+The exact component associated to each of the @var{c*} options depends on the
+format in input.
+
+The @var{lut} filter requires either YUV or RGB pixel formats in input,
+ at var{lutrgb} requires RGB pixel formats in input, and @var{lutyuv} requires YUV.
+
+The expressions can contain the following constants and functions:
+
+ at table @option
+ at item w
+ at item h
+The input width and height.
+
+ at item val
+The input value for the pixel component.
+
+ at item clipval
+The input value, clipped to the @var{minval}- at var{maxval} range.
+
+ at item maxval
+The maximum value for the pixel component.
+
+ at item minval
+The minimum value for the pixel component.
+
+ at item negval
+The negated value for the pixel component value, clipped to the
+ at var{minval}- at var{maxval} range; it corresponds to the expression
+"maxval-clipval+minval".
+
+ at item clip(val)
+The computed value in @var{val}, clipped to the
+ at var{minval}- at var{maxval} range.
+
+ at item gammaval(gamma)
+The computed gamma correction value of the pixel component value,
+clipped to the @var{minval}- at var{maxval} range. It corresponds to the
+expression
+"pow((clipval-minval)/(maxval-minval)\, at var{gamma})*(maxval-minval)+minval"
+
+ at end table
+
+All expressions default to "val".
+
+ at subsection Examples
+
+ at itemize
+ at item
+Negate input video:
+ at example
+lutrgb="r=maxval+minval-val:g=maxval+minval-val:b=maxval+minval-val"
+lutyuv="y=maxval+minval-val:u=maxval+minval-val:v=maxval+minval-val"
+ at end example
+
+The above is the same as:
+ at example
+lutrgb="r=negval:g=negval:b=negval"
+lutyuv="y=negval:u=negval:v=negval"
+ at end example
+
+ at item
+Negate luminance:
+ at example
+lutyuv=y=negval
+ at end example
+
+ at item
+Remove chroma components, turning the video into a graytone image:
+ at example
+lutyuv="u=128:v=128"
+ at end example
+
+ at item
+Apply a luma burning effect:
+ at example
+lutyuv="y=2*val"
+ at end example
+
+ at item
+Remove green and blue components:
+ at example
+lutrgb="g=0:b=0"
+ at end example
+
+ at item
+Set a constant alpha channel value on input:
+ at example
+format=rgba,lutrgb=a="maxval-minval/2"
+ at end example
+
+ at item
+Correct luminance gamma by a factor of 0.5:
+ at example
+lutyuv=y=gammaval(0.5)
+ at end example
+
+ at item
+Discard least significant bits of luma:
+ at example
+lutyuv=y='bitand(val, 128+64+32)'
+ at end example
+ at end itemize
+
+ at section mergeplanes
+
+Merge color channel components from several video streams.
+
+The filter accepts up to 4 input streams, and merge selected input
+planes to the output video.
+
+This filter accepts the following options:
+ at table @option
+ at item mapping
+Set input to output plane mapping. Default is @code{0}.
+
+The mappings is specified as a bitmap. It should be specified as a
+hexadecimal number in the form 0xAa[Bb[Cc[Dd]]]. 'Aa' describes the
+mapping for the first plane of the output stream. 'A' sets the number of
+the input stream to use (from 0 to 3), and 'a' the plane number of the
+corresponding input to use (from 0 to 3). The rest of the mappings is
+similar, 'Bb' describes the mapping for the output stream second
+plane, 'Cc' describes the mapping for the output stream third plane and
+'Dd' describes the mapping for the output stream fourth plane.
+
+ at item format
+Set output pixel format. Default is @code{yuva444p}.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Merge three gray video streams of same width and height into single video stream:
+ at example
+[a0][a1][a2]mergeplanes=0x001020:yuv444p
+ at end example
+
+ at item
+Merge 1st yuv444p stream and 2nd gray video stream into yuva444p video stream:
+ at example
+[a0][a1]mergeplanes=0x00010210:yuva444p
+ at end example
+
+ at item
+Swap Y and A plane in yuva444p stream:
+ at example
+format=yuva444p,mergeplanes=0x03010200:yuva444p
+ at end example
+
+ at item
+Swap U and V plane in yuv420p stream:
+ at example
+format=yuv420p,mergeplanes=0x000201:yuv420p
+ at end example
+
+ at item
+Cast a rgb24 clip to yuv444p:
+ at example
+format=rgb24,mergeplanes=0x000102:yuv444p
+ at end example
+ at end itemize
+
+ at section mcdeint
+
+Apply motion-compensation deinterlacing.
+
+It needs one field per frame as input and must thus be used together
+with yadif=1/3 or equivalent.
+
+This filter accepts the following options:
+ at table @option
+ at item mode
+Set the deinterlacing mode.
+
+It accepts one of the following values:
+ at table @samp
+ at item fast
+ at item medium
+ at item slow
+use iterative motion estimation
+ at item extra_slow
+like @samp{slow}, but use multiple reference frames.
+ at end table
+Default value is @samp{fast}.
+
+ at item parity
+Set the picture field parity assumed for the input video. It must be
+one of the following values:
+
+ at table @samp
+ at item 0, tff
+assume top field first
+ at item 1, bff
+assume bottom field first
+ at end table
+
+Default value is @samp{bff}.
+
+ at item qp
+Set per-block quantization parameter (QP) used by the internal
+encoder.
+
+Higher values should result in a smoother motion vector field but less
+optimal individual vectors. Default value is 1.
+ at end table
+
+ at section mpdecimate
+
+Drop frames that do not differ greatly from the previous frame in
+order to reduce frame rate.
+
+The main use of this filter is for very-low-bitrate encoding
+(e.g. streaming over dialup modem), but it could in theory be used for
+fixing movies that were inverse-telecined incorrectly.
+
+A description of the accepted options follows.
+
+ at table @option
+ at item max
+Set the maximum number of consecutive frames which can be dropped (if
+positive), or the minimum interval between dropped frames (if
+negative). If the value is 0, the frame is dropped unregarding the
+number of previous sequentially dropped frames.
+
+Default value is 0.
+
+ at item hi
+ at item lo
+ at item frac
+Set the dropping threshold values.
+
+Values for @option{hi} and @option{lo} are for 8x8 pixel blocks and
+represent actual pixel value differences, so a threshold of 64
+corresponds to 1 unit of difference for each pixel, or the same spread
+out differently over the block.
+
+A frame is a candidate for dropping if no 8x8 blocks differ by more
+than a threshold of @option{hi}, and if no more than @option{frac} blocks (1
+meaning the whole image) differ by more than a threshold of @option{lo}.
+
+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.
+ at end table
+
+
+ at section negate
+
+Negate input video.
+
+It accepts an integer in input; if non-zero it negates the
+alpha component (if available). The default value in input is 0.
+
+ at section noformat
+
+Force libavfilter not to use any of the specified pixel formats for the
+input to the next filter.
+
+It accepts the following parameters:
+ at table @option
+
+ at item pix_fmts
+A '|'-separated list of pixel format names, such as
+apix_fmts=yuv420p|monow|rgb24".
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Force libavfilter to use a format different from @var{yuv420p} for the
+input to the vflip filter:
+ at example
+noformat=pix_fmts=yuv420p,vflip
+ at end example
+
+ at item
+Convert the input video to any of the formats not contained in the list:
+ at example
+noformat=yuv420p|yuv444p|yuv410p
+ at end example
+ at end itemize
+
+ at section noise
+
+Add noise on video input frame.
+
+The filter accepts the following options:
+
+ at table @option
+ at item all_seed
+ at item c0_seed
+ at item c1_seed
+ at item c2_seed
+ at item c3_seed
+Set noise seed for specific pixel component or all pixel components in case
+of @var{all_seed}. Default value is @code{123457}.
+
+ at item all_strength, alls
+ at item c0_strength, c0s
+ at item c1_strength, c1s
+ at item c2_strength, c2s
+ at item c3_strength, c3s
+Set noise strength for specific pixel component or all pixel components in case
+ at var{all_strength}. Default value is @code{0}. Allowed range is [0, 100].
+
+ at item all_flags, allf
+ at item c0_flags, c0f
+ at item c1_flags, c1f
+ at item c2_flags, c2f
+ at item c3_flags, c3f
+Set pixel component flags or set flags for all components if @var{all_flags}.
+Available values for component flags are:
+ at table @samp
+ at item a
+averaged temporal noise (smoother)
+ at item p
+mix random noise with a (semi)regular pattern
+ at item t
+temporal noise (noise pattern changes between frames)
+ at item u
+uniform noise (gaussian otherwise)
+ at end table
+ at end table
+
+ at subsection Examples
+
+Add temporal and uniform noise to input video:
+ at example
+noise=alls=20:allf=t+u
+ at end example
+
+ at section null
+
+Pass the video source unchanged to the output.
+
+ at section ocv
+
+Apply a video transform using libopencv.
+
+To enable this filter, install the libopencv library and headers and
+configure FFmpeg with @code{--enable-libopencv}.
+
+It accepts the following parameters:
+
+ at table @option
+
+ at item filter_name
+The name of the libopencv filter to apply.
+
+ at item filter_params
+The parameters to pass to the libopencv filter. If not specified, the default
+values are assumed.
+
+ at end table
+
+Refer to the official libopencv documentation for more precise
+information:
+ at url{http://docs.opencv.org/master/modules/imgproc/doc/filtering.html}
+
+Several libopencv filters are supported; see the following subsections.
+
+ at anchor{dilate}
+ at subsection dilate
+
+Dilate an image by using a specific structuring element.
+It corresponds to the libopencv function @code{cvDilate}.
+
+It accepts the parameters: @var{struct_el}|@var{nb_iterations}.
+
+ at var{struct_el} represents a structuring element, and has the syntax:
+ at var{cols}x at var{rows}+ at var{anchor_x}x at var{anchor_y}/@var{shape}
+
+ at var{cols} and @var{rows} represent the number of columns and rows of
+the structuring element, @var{anchor_x} and @var{anchor_y} the anchor
+point, and @var{shape} the shape for the structuring element. @var{shape}
+must be "rect", "cross", "ellipse", or "custom".
+
+If the value for @var{shape} is "custom", it must be followed by a
+string of the form "=@var{filename}". The file with name
+ at var{filename} is assumed to represent a binary image, with each
+printable character corresponding to a bright pixel. When a custom
+ at var{shape} is used, @var{cols} and @var{rows} are ignored, the number
+or columns and rows of the read file are assumed instead.
+
+The default value for @var{struct_el} is "3x3+0x0/rect".
+
+ at var{nb_iterations} specifies the number of times the transform is
+applied to the image, and defaults to 1.
+
+Some examples:
+ at example
+# Use the default values
+ocv=dilate
+
+# Dilate using a structuring element with a 5x5 cross, iterating two times
+ocv=filter_name=dilate:filter_params=5x5+2x2/cross|2
+
+# Read the shape from the file diamond.shape, iterating two times.
+# The file diamond.shape may contain a pattern of characters like this
+# *
+# ***
+# *****
+# ***
+# *
+# The specified columns and rows are ignored
+# but the anchor point coordinates are not
+ocv=dilate:0x0+2x2/custom=diamond.shape|2
+ at end example
+
+ at subsection erode
+
+Erode an image by using a specific structuring element.
+It corresponds to the libopencv function @code{cvErode}.
+
+It accepts the parameters: @var{struct_el}:@var{nb_iterations},
+with the same syntax and semantics as the @ref{dilate} filter.
+
+ at subsection smooth
+
+Smooth the input video.
+
+The filter takes the following parameters:
+ at var{type}|@var{param1}|@var{param2}|@var{param3}|@var{param4}.
+
+ at var{type} is the type of smooth filter to apply, and must be one of
+the following values: "blur", "blur_no_scale", "median", "gaussian",
+or "bilateral". The default value is "gaussian".
+
+The meaning of @var{param1}, @var{param2}, @var{param3}, and @var{param4}
+depend on the smooth type. @var{param1} and
+ at var{param2} accept integer positive values or 0. @var{param3} and
+ at var{param4} accept floating point values.
+
+The default value for @var{param1} is 3. The default value for the
+other parameters is 0.
+
+These parameters correspond to the parameters assigned to the
+libopencv function @code{cvSmooth}.
+
+ at anchor{overlay}
+ at section overlay
+
+Overlay one video on top of another.
+
+It takes two inputs and has one output. The first input is the "main"
+video on which the second input is overlaid.
+
+It accepts the following parameters:
+
+A description of the accepted options follows.
+
+ at table @option
+ at item x
+ at item y
+Set the expression for the x and y coordinates of the overlaid video
+on the main video. Default value is "0" for both expressions. In case
+the expression is invalid, it is set to a huge value (meaning that the
+overlay will not be displayed within the output visible area).
+
+ at item eof_action
+The action to take when EOF is encountered on the secondary input; it accepts
+one of the following values:
+
+ at table @option
+ at item repeat
+Repeat the last frame (the default).
+ at item endall
+End both streams.
+ at item pass
+Pass the main input through.
+ at end table
+
+ at item eval
+Set when the expressions for @option{x}, and @option{y} are evaluated.
+
+It accepts the following values:
+ at table @samp
+ at item init
+only evaluate expressions once during the filter initialization or
+when a command is processed
+
+ at item frame
+evaluate expressions for each incoming frame
+ at end table
+
+Default value is @samp{frame}.
+
+ at item shortest
+If set to 1, force the output to terminate when the shortest input
+terminates. Default value is 0.
+
+ at item format
+Set the format for the output video.
+
+It accepts the following values:
+ at table @samp
+ at item yuv420
+force YUV420 output
+
+ at item yuv422
+force YUV422 output
+
+ at item yuv444
+force YUV444 output
+
+ at item rgb
+force RGB output
+ at end table
+
+Default value is @samp{yuv420}.
+
+ at item rgb @emph{(deprecated)}
+If set to 1, force the filter to accept inputs in the RGB
+color space. Default value is 0. This option is deprecated, use
+ at option{format} instead.
+
+ at item repeatlast
+If set to 1, force the filter to draw the last overlay frame over the
+main input until the end of the stream. A value of 0 disables this
+behavior. Default value is 1.
+ at end table
+
+The @option{x}, and @option{y} expressions can contain the following
+parameters.
+
+ at table @option
+ at item main_w, W
+ at item main_h, H
+The main input width and height.
+
+ at item overlay_w, w
+ at item overlay_h, h
+The overlay input width and height.
+
+ at item x
+ at item y
+The computed values for @var{x} and @var{y}. They are evaluated for
+each new frame.
+
+ at item hsub
+ at item vsub
+horizontal and vertical chroma subsample values of the output
+format. For example for the pixel format "yuv422p" @var{hsub} is 2 and
+ at var{vsub} is 1.
+
+ at item n
+the number of input frame, starting from 0
+
+ at item pos
+the position in the file of the input frame, NAN if unknown
+
+ at item t
+The timestamp, expressed in seconds. It's NAN if the input timestamp is unknown.
+
+ at end table
+
+Note that the @var{n}, @var{pos}, @var{t} variables are available only
+when evaluation is done @emph{per frame}, and will evaluate to NAN
+when @option{eval} is set to @samp{init}.
+
+Be aware that frames are taken from each input video in timestamp
+order, hence, if their initial timestamps differ, it is a good idea
+to pass the two inputs through a @var{setpts=PTS-STARTPTS} filter to
+have them begin in the same zero timestamp, as the example for
+the @var{movie} filter does.
+
+You can chain together more overlays but you should test the
+efficiency of such approach.
+
+ at subsection Commands
+
+This filter supports the following commands:
+ at table @option
+ at item x
+ at item y
+Modify the x and y of the overlay input.
+The command accepts the same syntax of the corresponding option.
+
+If the specified expression is not valid, it is kept at its current
+value.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Draw the overlay at 10 pixels from the bottom right corner of the main
+video:
+ at example
+overlay=main_w-overlay_w-10:main_h-overlay_h-10
+ at end example
+
+Using named options the example above becomes:
+ at example
+overlay=x=main_w-overlay_w-10:y=main_h-overlay_h-10
+ at end example
+
+ at item
+Insert a transparent PNG logo in the bottom left corner of the input,
+using the @command{ffmpeg} tool with the @code{-filter_complex} option:
+ at example
+ffmpeg -i input -i logo -filter_complex 'overlay=10:main_h-overlay_h-10' output
+ at end example
+
+ at item
+Insert 2 different transparent PNG logos (second logo on bottom
+right corner) using the @command{ffmpeg} tool:
+ at example
+ffmpeg -i input -i logo1 -i logo2 -filter_complex 'overlay=x=10:y=H-h-10,overlay=x=W-w-10:y=H-h-10' output
+ at end example
+
+ at item
+Add a transparent color layer on top of the main video; @code{WxH}
+must specify the size of the main input to the overlay filter:
+ at example
+color=color=red@@.3:size=WxH [over]; [in][over] overlay [out]
+ at end example
+
+ at item
+Play an original video and a filtered version (here with the deshake
+filter) side by side using the @command{ffplay} tool:
+ at example
+ffplay input.avi -vf 'split[a][b]; [a]pad=iw*2:ih[src]; [b]deshake[filt]; [src][filt]overlay=w'
+ at end example
+
+The above command is the same as:
+ at example
+ffplay input.avi -vf 'split[b], pad=iw*2[src], [b]deshake, [src]overlay=w'
+ at end example
+
+ at item
+Make a sliding overlay appearing from the left to the right top part of the
+screen starting since time 2:
+ at example
+overlay=x='if(gte(t,2), -w+(t-2)*20, NAN)':y=0
+ at end example
+
+ at item
+Compose output by putting two input videos side to side:
+ at example
+ffmpeg -i left.avi -i right.avi -filter_complex "
+nullsrc=size=200x100 [background];
+[0:v] setpts=PTS-STARTPTS, scale=100x100 [left];
+[1:v] setpts=PTS-STARTPTS, scale=100x100 [right];
+[background][left] overlay=shortest=1 [background+left];
+[background+left][right] overlay=shortest=1:x=100 [left+right]
+"
+ at end example
+
+ at item
+Mask 10-20 seconds of a video by applying the delogo filter to a section
+ at example
+ffmpeg -i test.avi -codec:v:0 wmv2 -ar 11025 -b:v 9000k
+-vf '[in]split[split_main][split_delogo];[split_delogo]trim=start=360:end=371,delogo=0:0:640:480[delogoed];[split_main][delogoed]overlay=eof_action=pass[out]'
+masked.avi
+ at end example
+
+ at item
+Chain several overlays in cascade:
+ at example
+nullsrc=s=200x200 [bg];
+testsrc=s=100x100, split=4 [in0][in1][in2][in3];
+[in0] lutrgb=r=0, [bg] overlay=0:0 [mid0];
+[in1] lutrgb=g=0, [mid0] overlay=100:0 [mid1];
+[in2] lutrgb=b=0, [mid1] overlay=0:100 [mid2];
+[in3] null, [mid2] overlay=100:100 [out0]
+ at end example
+
+ at end itemize
+
+ at section owdenoise
+
+Apply Overcomplete Wavelet denoiser.
+
+The filter accepts the following options:
+
+ at table @option
+ at item depth
+Set depth.
+
+Larger depth values will denoise lower frequency components more, but
+slow down filtering.
+
+Must be an int in the range 8-16, default is @code{8}.
+
+ at item luma_strength, ls
+Set luma strength.
+
+Must be a double value in the range 0-1000, default is @code{1.0}.
+
+ at item chroma_strength, cs
+Set chroma strength.
+
+Must be a double value in the range 0-1000, default is @code{1.0}.
+ at end table
+
+ at anchor{pad}
+ at section pad
+
+Add paddings to the input image, and place the original input at the
+provided @var{x}, @var{y} coordinates.
+
+It accepts the following parameters:
+
+ at table @option
+ at item width, w
+ at item height, h
+Specify an expression for the size of the output image with the
+paddings added. If the value for @var{width} or @var{height} is 0, the
+corresponding input size is used for the output.
+
+The @var{width} expression can reference the value set by the
+ at var{height} expression, and vice versa.
+
+The default value of @var{width} and @var{height} is 0.
+
+ at item x
+ at item y
+Specify the offsets to place the input image at within the padded area,
+with respect to the top/left border of the output image.
+
+The @var{x} expression can reference the value set by the @var{y}
+expression, and vice versa.
+
+The default value of @var{x} and @var{y} is 0.
+
+ at item color
+Specify the color of the padded area. For the syntax of this option,
+check the "Color" section in the ffmpeg-utils manual.
+
+The default value of @var{color} is "black".
+ at end table
+
+The value for the @var{width}, @var{height}, @var{x}, and @var{y}
+options are expressions containing the following constants:
+
+ at table @option
+ at item in_w
+ at item in_h
+The input video width and height.
+
+ at item iw
+ at item ih
+These are the same as @var{in_w} and @var{in_h}.
+
+ at item out_w
+ at item out_h
+The output width and height (the size of the padded area), as
+specified by the @var{width} and @var{height} expressions.
+
+ at item ow
+ at item oh
+These are the same as @var{out_w} and @var{out_h}.
+
+ at item x
+ at item y
+The x and y offsets as specified by the @var{x} and @var{y}
+expressions, or NAN if not yet specified.
+
+ at item a
+same as @var{iw} / @var{ih}
+
+ at item sar
+input sample aspect ratio
+
+ at item dar
+input display aspect ratio, it is the same as (@var{iw} / @var{ih}) * @var{sar}
+
+ at item hsub
+ at item vsub
+The horizontal and vertical chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Add paddings with the color "violet" to the input video. The output video
+size is 640x480, and the top-left corner of the input video is placed at
+column 0, row 40
+ at example
+pad=640:480:0:40:violet
+ at end example
+
+The example above is equivalent to the following command:
+ at example
+pad=width=640:height=480:x=0:y=40:color=violet
+ at end example
+
+ at item
+Pad the input to get an output with dimensions increased by 3/2,
+and put the input video at the center of the padded area:
+ at example
+pad="3/2*iw:3/2*ih:(ow-iw)/2:(oh-ih)/2"
+ at end example
+
+ at item
+Pad the input to get a squared output with size equal to the maximum
+value between the input width and height, and put the input video at
+the center of the padded area:
+ at example
+pad="max(iw\,ih):ow:(ow-iw)/2:(oh-ih)/2"
+ at end example
+
+ at item
+Pad the input to get a final w/h ratio of 16:9:
+ at example
+pad="ih*16/9:ih:(ow-iw)/2:(oh-ih)/2"
+ at end example
+
+ at item
+In case of anamorphic video, in order to set the output display aspect
+correctly, it is necessary to use @var{sar} in the expression,
+according to the relation:
+ at example
+(ih * X / ih) * sar = output_dar
+X = output_dar / sar
+ at end example
+
+Thus the previous example needs to be modified to:
+ at example
+pad="ih*16/9/sar:ih:(ow-iw)/2:(oh-ih)/2"
+ at end example
+
+ at item
+Double the output size and put the input video in the bottom-right
+corner of the output padded area:
+ at example
+pad="2*iw:2*ih:ow-iw:oh-ih"
+ at end example
+ at end itemize
+
+ at anchor{palettegen}
+ at section palettegen
+
+Generate one palette for a whole video stream.
+
+It accepts the following options:
+
+ at table @option
+ at item max_colors
+Set the maximum number of colors to quantize in the palette.
+Note: the palette will still contain 256 colors; the unused palette entries
+will be black.
+
+ at item reserve_transparent
+Create a palette of 255 colors maximum and reserve the last one for
+transparency. Reserving the transparency color is useful for GIF optimization.
+If not set, the maximum of colors in the palette will be 256. You probably want
+to disable this option for a standalone image.
+Set by default.
+
+ at item stats_mode
+Set statistics mode.
+
+It accepts the following values:
+ at table @samp
+ at item full
+Compute full frame histograms.
+ at item diff
+Compute histograms only for the part that differs from previous frame. This
+might be relevant to give more importance to the moving part of your input if
+the background is static.
+ at end table
+
+Default value is @var{full}.
+ at end table
+
+The filter also exports the frame metadata @code{lavfi.color_quant_ratio}
+(@code{nb_color_in / nb_color_out}) which you can use to evaluate the degree of
+color quantization of the palette. This information is also visible at
+ at var{info} logging level.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Generate a representative palette of a given video using @command{ffmpeg}:
+ at example
+ffmpeg -i input.mkv -vf palettegen palette.png
+ at end example
+ at end itemize
+
+ at section paletteuse
+
+Use a palette to downsample an input video stream.
+
+The filter takes two inputs: one video stream and a palette. The palette must
+be a 256 pixels image.
+
+It accepts the following options:
+
+ at table @option
+ at item dither
+Select dithering mode. Available algorithms are:
+ at table @samp
+ at item bayer
+Ordered 8x8 bayer dithering (deterministic)
+ at item heckbert
+Dithering as defined by Paul Heckbert in 1982 (simple error diffusion).
+Note: this dithering is sometimes considered "wrong" and is included as a
+reference.
+ at item floyd_steinberg
+Floyd and Steingberg dithering (error diffusion)
+ at item sierra2
+Frankie Sierra dithering v2 (error diffusion)
+ at item sierra2_4a
+Frankie Sierra dithering v2 "Lite" (error diffusion)
+ at end table
+
+Default is @var{sierra2_4a}.
+
+ at item bayer_scale
+When @var{bayer} dithering is selected, this option defines the scale of the
+pattern (how much the crosshatch pattern is visible). A low value means more
+visible pattern for less banding, and higher value means less visible pattern
+at the cost of more banding.
+
+The option must be an integer value in the range [0,5]. Default is @var{2}.
+
+ at item diff_mode
+If set, define the zone to process
+
+ at table @samp
+ at item rectangle
+Only the changing rectangle will be reprocessed. This is similar to GIF
+cropping/offsetting compression mechanism. This option can be useful for speed
+if only a part of the image is changing, and has use cases such as limiting the
+scope of the error diffusal @option{dither} to the rectangle that bounds the
+moving scene (it leads to more deterministic output if the scene doesn't change
+much, and as a result less moving noise and better GIF compression).
+ at end table
+
+Default is @var{none}.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Use a palette (generated for example with @ref{palettegen}) to encode a GIF
+using @command{ffmpeg}:
+ at example
+ffmpeg -i input.mkv -i palette.png -lavfi paletteuse output.gif
+ at end example
+ at end itemize
+
+ at section perspective
+
+Correct perspective of video not recorded perpendicular to the screen.
+
+A description of the accepted parameters follows.
+
+ at table @option
+ at item x0
+ at item y0
+ at item x1
+ at item y1
+ at item x2
+ at item y2
+ at item x3
+ at item y3
+Set coordinates expression for top left, top right, bottom left and bottom right corners.
+Default values are @code{0:0:W:0:0:H:W:H} with which perspective will remain unchanged.
+If the @code{sense} option is set to @code{source}, then the specified points will be sent
+to the corners of the destination. If the @code{sense} option is set to @code{destination},
+then the corners of the source will be sent to the specified coordinates.
+
+The expressions can use the following variables:
+
+ at table @option
+ at item W
+ at item H
+the width and height of video frame.
+ at end table
+
+ at item interpolation
+Set interpolation for perspective correction.
+
+It accepts the following values:
+ at table @samp
+ at item linear
+ at item cubic
+ at end table
+
+Default value is @samp{linear}.
+
+ at item sense
+Set interpretation of coordinate options.
+
+It accepts the following values:
+ at table @samp
+ at item 0, source
+
+Send point in the source specified by the given coordinates to
+the corners of the destination.
+
+ at item 1, destination
+
+Send the corners of the source to the point in the destination specified
+by the given coordinates.
+
+Default value is @samp{source}.
+ at end table
+ at end table
+
+ at section phase
+
+Delay interlaced video by one field time so that the field order changes.
+
+The intended use is to fix PAL movies that have been captured with the
+opposite field order to the film-to-video transfer.
+
+A description of the accepted parameters follows.
+
+ at table @option
+ at item mode
+Set phase mode.
+
+It accepts the following values:
+ at table @samp
+ at item t
+Capture field order top-first, transfer bottom-first.
+Filter will delay the bottom field.
+
+ at item b
+Capture field order bottom-first, transfer top-first.
+Filter will delay the top field.
+
+ at item p
+Capture and transfer with the same field order. This mode only exists
+for the documentation of the other options to refer to, but if you
+actually select it, the filter will faithfully do nothing.
+
+ at item a
+Capture field order determined automatically by field flags, transfer
+opposite.
+Filter selects among @samp{t} and @samp{b} modes on a frame by frame
+basis using field flags. If no field information is available,
+then this works just like @samp{u}.
+
+ at item u
+Capture unknown or varying, transfer opposite.
+Filter selects among @samp{t} and @samp{b} on a frame by frame basis by
+analyzing the images and selecting the alternative that produces best
+match between the fields.
+
+ at item T
+Capture top-first, transfer unknown or varying.
+Filter selects among @samp{t} and @samp{p} using image analysis.
+
+ at item B
+Capture bottom-first, transfer unknown or varying.
+Filter selects among @samp{b} and @samp{p} using image analysis.
+
+ at item A
+Capture determined by field flags, transfer unknown or varying.
+Filter selects among @samp{t}, @samp{b} and @samp{p} using field flags and
+image analysis. If no field information is available, then this works just
+like @samp{U}. This is the default mode.
+
+ at item U
+Both capture and transfer unknown or varying.
+Filter selects among @samp{t}, @samp{b} and @samp{p} using image analysis only.
+ at end table
+ at end table
+
+ at section pixdesctest
+
+Pixel format descriptor test filter, mainly useful for internal
+testing. The output video should be equal to the input video.
+
+For example:
+ at example
+format=monow, pixdesctest
+ at end example
+
+can be used to test the monowhite pixel format descriptor definition.
+
+ at section pp
+
+Enable the specified chain of postprocessing subfilters using libpostproc. This
+library should be automatically selected with a GPL build (@code{--enable-gpl}).
+Subfilters must be separated by '/' and can be disabled by prepending a '-'.
+Each subfilter and some options have a short and a long name that can be used
+interchangeably, i.e. dr/dering are the same.
+
+The filters accept the following options:
+
+ at table @option
+ at item subfilters
+Set postprocessing subfilters string.
+ at end table
+
+All subfilters share common options to determine their scope:
+
+ at table @option
+ at item a/autoq
+Honor the quality commands for this subfilter.
+
+ at item c/chrom
+Do chrominance filtering, too (default).
+
+ at item y/nochrom
+Do luminance filtering only (no chrominance).
+
+ at item n/noluma
+Do chrominance filtering only (no luminance).
+ at end table
+
+These options can be appended after the subfilter name, separated by a '|'.
+
+Available subfilters are:
+
+ at table @option
+ at item hb/hdeblock[|difference[|flatness]]
+Horizontal deblocking filter
+ at table @option
+ at item difference
+Difference factor where higher values mean more deblocking (default: @code{32}).
+ at item flatness
+Flatness threshold where lower values mean more deblocking (default: @code{39}).
+ at end table
+
+ at item vb/vdeblock[|difference[|flatness]]
+Vertical deblocking filter
+ at table @option
+ at item difference
+Difference factor where higher values mean more deblocking (default: @code{32}).
+ at item flatness
+Flatness threshold where lower values mean more deblocking (default: @code{39}).
+ at end table
+
+ at item ha/hadeblock[|difference[|flatness]]
+Accurate horizontal deblocking filter
+ at table @option
+ at item difference
+Difference factor where higher values mean more deblocking (default: @code{32}).
+ at item flatness
+Flatness threshold where lower values mean more deblocking (default: @code{39}).
+ at end table
+
+ at item va/vadeblock[|difference[|flatness]]
+Accurate vertical deblocking filter
+ at table @option
+ at item difference
+Difference factor where higher values mean more deblocking (default: @code{32}).
+ at item flatness
+Flatness threshold where lower values mean more deblocking (default: @code{39}).
+ at end table
+ at end table
+
+The horizontal and vertical deblocking filters share the difference and
+flatness values so you cannot set different horizontal and vertical
+thresholds.
+
+ at table @option
+ at item h1/x1hdeblock
+Experimental horizontal deblocking filter
+
+ at item v1/x1vdeblock
+Experimental vertical deblocking filter
+
+ at item dr/dering
+Deringing filter
+
+ at item tn/tmpnoise[|threshold1[|threshold2[|threshold3]]], temporal noise reducer
+ at table @option
+ at item threshold1
+larger -> stronger filtering
+ at item threshold2
+larger -> stronger filtering
+ at item threshold3
+larger -> stronger filtering
+ at end table
+
+ at item al/autolevels[:f/fullyrange], automatic brightness / contrast correction
+ at table @option
+ at item f/fullyrange
+Stretch luminance to @code{0-255}.
+ at end table
+
+ at item lb/linblenddeint
+Linear blend deinterlacing filter that deinterlaces the given block by
+filtering all lines with a @code{(1 2 1)} filter.
+
+ at item li/linipoldeint
+Linear interpolating deinterlacing filter that deinterlaces the given block by
+linearly interpolating every second line.
+
+ at item ci/cubicipoldeint
+Cubic interpolating deinterlacing filter deinterlaces the given block by
+cubically interpolating every second line.
+
+ at item md/mediandeint
+Median deinterlacing filter that deinterlaces the given block by applying a
+median filter to every second line.
+
+ at item fd/ffmpegdeint
+FFmpeg deinterlacing filter that deinterlaces the given block by filtering every
+second line with a @code{(-1 4 2 4 -1)} filter.
+
+ at item l5/lowpass5
+Vertically applied FIR lowpass deinterlacing filter that deinterlaces the given
+block by filtering all lines with a @code{(-1 2 6 2 -1)} filter.
+
+ at item fq/forceQuant[|quantizer]
+Overrides the quantizer table from the input with the constant quantizer you
+specify.
+ at table @option
+ at item quantizer
+Quantizer to use
+ at end table
+
+ at item de/default
+Default pp filter combination (@code{hb|a,vb|a,dr|a})
+
+ at item fa/fast
+Fast pp filter combination (@code{h1|a,v1|a,dr|a})
+
+ at item ac
+High quality pp filter combination (@code{ha|a|128|7,va|a,dr|a})
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Apply horizontal and vertical deblocking, deringing and automatic
+brightness/contrast:
+ at example
+pp=hb/vb/dr/al
+ at end example
+
+ at item
+Apply default filters without brightness/contrast correction:
+ at example
+pp=de/-al
+ at end example
+
+ at item
+Apply default filters and temporal denoiser:
+ at example
+pp=default/tmpnoise|1|2|3
+ at end example
+
+ at item
+Apply deblocking on luminance only, and switch vertical deblocking on or off
+automatically depending on available CPU time:
+ at example
+pp=hb|y/vb|a
+ at end example
+ at end itemize
+
+ at section pp7
+Apply Postprocessing filter 7. It is variant of the @ref{spp} filter,
+similar to spp = 6 with 7 point DCT, where only the center sample is
+used after IDCT.
+
+The filter accepts the following options:
+
+ at table @option
+ at item qp
+Force a constant quantization parameter. It accepts an integer in range
+0 to 63. If not set, the filter will use the QP from the video stream
+(if available).
+
+ at item mode
+Set thresholding mode. Available modes are:
+
+ at table @samp
+ at item hard
+Set hard thresholding.
+ at item soft
+Set soft thresholding (better de-ringing effect, but likely blurrier).
+ at item medium
+Set medium thresholding (good results, default).
+ at end table
+ at end table
+
+ at section psnr
+
+Obtain the average, maximum and minimum PSNR (Peak Signal to Noise
+Ratio) between two input videos.
+
+This filter takes in input two input videos, the first input is
+considered the "main" source and is passed unchanged to the
+output. The second input is used as a "reference" video for computing
+the PSNR.
+
+Both video inputs 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 PSNR is printed through the logging system.
+
+The filter stores the accumulated MSE (mean squared error) of each
+frame, and at the end of the processing it is averaged across all frames
+equally, and the following formula is applied to obtain the PSNR:
+
+ at example
+PSNR = 10*log10(MAX^2/MSE)
+ at end example
+
+Where MAX is the average of the maximum values of each component of the
+image.
+
+The description of the accepted parameters follows.
+
+ at table @option
+ at item stats_file, f
+If specified the filter will use the named file to save the PSNR of
+each individual frame.
+ at end table
+
+The file printed if @var{stats_file} is selected, contains a sequence of
+key/value pairs of the form @var{key}:@var{value} for each compared
+couple of frames.
+
+A description of each shown parameter follows:
+
+ at table @option
+ at item n
+sequential number of the input frame, starting from 1
+
+ at item mse_avg
+Mean Square Error pixel-by-pixel average difference of the compared
+frames, averaged over all the image components.
+
+ at item mse_y, mse_u, mse_v, mse_r, mse_g, mse_g, mse_a
+Mean Square Error pixel-by-pixel average difference of the compared
+frames for the component specified by the suffix.
+
+ at item psnr_y, psnr_u, psnr_v, psnr_r, psnr_g, psnr_b, psnr_a
+Peak Signal to Noise ratio of the compared frames for the component
+specified by the suffix.
+ at end table
+
+For example:
+ at example
+movie=ref_movie.mpg, setpts=PTS-STARTPTS [main];
+[main][ref] psnr="stats_file=stats.log" [out]
+ at end example
+
+On this example the input file being processed is compared with the
+reference file @file{ref_movie.mpg}. The PSNR of each individual frame
+is stored in @file{stats.log}.
+
+ at anchor{pullup}
+ at section pullup
+
+Pulldown reversal (inverse telecine) filter, capable of handling mixed
+hard-telecine, 24000/1001 fps progressive, and 30000/1001 fps progressive
+content.
+
+The pullup filter is designed to take advantage of future context in making
+its decisions. This filter is stateless in the sense that it does not lock
+onto a pattern to follow, but it instead looks forward to the following
+fields in order to identify matches and rebuild progressive frames.
+
+To produce content with an even framerate, insert the fps filter after
+pullup, use @code{fps=24000/1001} if the input frame rate is 29.97fps,
+ at code{fps=24} for 30fps and the (rare) telecined 25fps input.
+
+The filter accepts the following options:
+
+ at table @option
+ at item jl
+ at item jr
+ at item jt
+ at item jb
+These options set the amount of "junk" to ignore at the left, right, top, and
+bottom of the image, respectively. Left and right are in units of 8 pixels,
+while top and bottom are in units of 2 lines.
+The default is 8 pixels on each side.
+
+ at item sb
+Set the strict breaks. Setting this option to 1 will reduce the chances of
+filter generating an occasional mismatched frame, but it may also cause an
+excessive number of frames to be dropped during high motion sequences.
+Conversely, setting it to -1 will make filter match fields more easily.
+This may help processing of video where there is slight blurring between
+the fields, but may also cause there to be interlaced frames in the output.
+Default value is @code{0}.
+
+ at item mp
+Set the metric plane to use. It accepts the following values:
+ at table @samp
+ at item l
+Use luma plane.
+
+ at item u
+Use chroma blue plane.
+
+ at item v
+Use chroma red plane.
+ at end table
+
+This option may be set to use chroma plane instead of the default luma plane
+for doing filter's computations. This may improve accuracy on very clean
+source material, but more likely will decrease accuracy, especially if there
+is chroma noise (rainbow effect) or any grayscale video.
+The main purpose of setting @option{mp} to a chroma plane is to reduce CPU
+load and make pullup usable in realtime on slow machines.
+ at end table
+
+For best results (without duplicated frames in the output file) it is
+necessary to change the output frame rate. For example, to inverse
+telecine NTSC input:
+ at example
+ffmpeg -i input -vf pullup -r 24000/1001 ...
+ at end example
+
+ at section qp
+
+Change video quantization parameters (QP).
+
+The filter accepts the following option:
+
+ at table @option
+ at item qp
+Set expression for quantization parameter.
+ at end table
+
+The expression is evaluated through the eval API and can contain, among others,
+the following constants:
+
+ at table @var
+ at item known
+1 if index is not 129, 0 otherwise.
+
+ at item qp
+Sequentional index starting from -129 to 128.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Some equation like:
+ at example
+qp=2+2*sin(PI*qp)
+ at end example
+ at end itemize
+
+ at section random
+
+Flush video frames from internal cache of frames into a random order.
+No frame is discarded.
+Inspired by @ref{frei0r} nervous filter.
+
+ at table @option
+ at item frames
+Set size in number of frames of internal cache, in range from @code{2} to
+ at code{512}. Default is @code{30}.
+
+ at item seed
+Set seed for random number generator, must be an integer included between
+ at code{0} and @code{UINT32_MAX}. If not specified, or if explicitly set to
+less than @code{0}, the filter will try to use a good random seed on a
+best effort basis.
+ at end table
+
+ at section removegrain
+
+The removegrain filter is a spatial denoiser for progressive video.
+
+ at table @option
+ at item m0
+Set mode for the first plane.
+
+ at item m1
+Set mode for the second plane.
+
+ at item m2
+Set mode for the third plane.
+
+ at item m3
+Set mode for the fourth plane.
+ at end table
+
+Range of mode is from 0 to 24. Description of each mode follows:
+
+ at table @var
+ at item 0
+Leave input plane unchanged. Default.
+
+ at item 1
+Clips the pixel with the minimum and maximum of the 8 neighbour pixels.
+
+ at item 2
+Clips the pixel with the second minimum and maximum of the 8 neighbour pixels.
+
+ at item 3
+Clips the pixel with the third minimum and maximum of the 8 neighbour pixels.
+
+ at item 4
+Clips the pixel with the fourth minimum and maximum of the 8 neighbour pixels.
+This is equivalent to a median filter.
+
+ at item 5
+Line-sensitive clipping giving the minimal change.
+
+ at item 6
+Line-sensitive clipping, intermediate.
+
+ at item 7
+Line-sensitive clipping, intermediate.
+
+ at item 8
+Line-sensitive clipping, intermediate.
+
+ at item 9
+Line-sensitive clipping on a line where the neighbours pixels are the closest.
+
+ at item 10
+Replaces the target pixel with the closest neighbour.
+
+ at item 11
+[1 2 1] horizontal and vertical kernel blur.
+
+ at item 12
+Same as mode 11.
+
+ at item 13
+Bob mode, interpolates top field from the line where the neighbours
+pixels are the closest.
+
+ at item 14
+Bob mode, interpolates bottom field from the line where the neighbours
+pixels are the closest.
+
+ at item 15
+Bob mode, interpolates top field. Same as 13 but with a more complicated
+interpolation formula.
+
+ at item 16
+Bob mode, interpolates bottom field. Same as 14 but with a more complicated
+interpolation formula.
+
+ at item 17
+Clips the pixel with the minimum and maximum of respectively the maximum and
+minimum of each pair of opposite neighbour pixels.
+
+ at item 18
+Line-sensitive clipping using opposite neighbours whose greatest distance from
+the current pixel is minimal.
+
+ at item 19
+Replaces the pixel with the average of its 8 neighbours.
+
+ at item 20
+Averages the 9 pixels ([1 1 1] horizontal and vertical blur).
+
+ at item 21
+Clips pixels using the averages of opposite neighbour.
+
+ at item 22
+Same as mode 21 but simpler and faster.
+
+ at item 23
+Small edge and halo removal, but reputed useless.
+
+ at item 24
+Similar as 23.
+ at end table
+
+ at section removelogo
+
+Suppress a TV station logo, using an image file to determine which
+pixels comprise the logo. It works by filling in the pixels that
+comprise the logo with neighboring pixels.
+
+The filter accepts the following options:
+
+ at table @option
+ at item filename, f
+Set the filter bitmap file, which can be any image format supported by
+libavformat. The width and height of the image file must match those of the
+video stream being processed.
+ at end table
+
+Pixels in the provided bitmap image with a value of zero are not
+considered part of the logo, non-zero pixels are considered part of
+the logo. If you use white (255) for the logo and black (0) for the
+rest, you will be safe. For making the filter bitmap, it is
+recommended to take a screen capture of a black frame with the logo
+visible, and then using a threshold filter followed by the erode
+filter once or twice.
+
+If needed, little splotches can be fixed manually. Remember that if
+logo pixels are not covered, the filter quality will be much
+reduced. Marking too many pixels as part of the logo does not hurt as
+much, but it will increase the amount of blurring needed to cover over
+the image and will destroy more information than necessary, and extra
+pixels will slow things down on a large logo.
+
+ at section repeatfields
+
+This filter uses the repeat_field flag from the Video ES headers and hard repeats
+fields based on its value.
+
+ at section reverse, areverse
+
+Reverse a clip.
+
+Warning: This filter requires memory to buffer the entire clip, so trimming
+is suggested.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Take the first 5 seconds of a clip, and reverse it.
+ at example
+trim=end=5,reverse
+ at end example
+ at end itemize
+
+ at section rotate
+
+Rotate video by an arbitrary angle expressed in radians.
+
+The filter accepts the following options:
+
+A description of the optional parameters follows.
+ at table @option
+ at item angle, a
+Set an expression for the angle by which to rotate the input video
+clockwise, expressed as a number of radians. A negative value will
+result in a counter-clockwise rotation. By default it is set to "0".
+
+This expression is evaluated for each frame.
+
+ at item out_w, ow
+Set the output width expression, default value is "iw".
+This expression is evaluated just once during configuration.
+
+ at item out_h, oh
+Set the output height expression, default value is "ih".
+This expression is evaluated just once during configuration.
+
+ at item bilinear
+Enable bilinear interpolation if set to 1, a value of 0 disables
+it. Default value is 1.
+
+ at item fillcolor, c
+Set the color used to fill the output area not covered by the rotated
+image. For the general syntax of this option, check the "Color" section in the
+ffmpeg-utils manual. 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".
+ at end table
+
+The expressions for the angle and the output size can contain the
+following constants and functions:
+
+ at table @option
+ at item n
+sequential number of the input frame, starting from 0. It is always NAN
+before the first frame is filtered.
+
+ at item t
+time in seconds of the input frame, it is set to 0 when the filter is
+configured. It is always NAN before the first frame is filtered.
+
+ at item hsub
+ at item vsub
+horizontal and vertical chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+
+ at item in_w, iw
+ at item in_h, ih
+the input video width and height
+
+ at item out_w, ow
+ at item out_h, oh
+the output width and height, that is the size of the padded area as
+specified by the @var{width} and @var{height} expressions
+
+ at item rotw(a)
+ at item roth(a)
+the minimal width/height required for completely containing the input
+video rotated by @var{a} radians.
+
+These are only available when computing the @option{out_w} and
+ at option{out_h} expressions.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Rotate the input by PI/6 radians clockwise:
+ at example
+rotate=PI/6
+ at end example
+
+ at item
+Rotate the input by PI/6 radians counter-clockwise:
+ at example
+rotate=-PI/6
+ at end example
+
+ at item
+Rotate the input by 45 degrees clockwise:
+ at example
+rotate=45*PI/180
+ at end example
+
+ at item
+Apply a constant rotation with period T, starting from an angle of PI/3:
+ at example
+rotate=PI/3+2*PI*t/T
+ at end example
+
+ at item
+Make the input video rotation oscillating with a period of T
+seconds and an amplitude of A radians:
+ at example
+rotate=A*sin(2*PI/T*t)
+ at end example
+
+ at item
+Rotate the video, output size is chosen so that the whole rotating
+input video is always completely contained in the output:
+ at example
+rotate='2*PI*t:ow=hypot(iw,ih):oh=ow'
+ at end example
+
+ at item
+Rotate the video, reduce the output size so that no background is ever
+shown:
+ at example
+rotate=2*PI*t:ow='min(iw,ih)/sqrt(2)':oh=ow:c=none
+ at end example
+ at end itemize
+
+ at subsection Commands
+
+The filter supports the following commands:
+
+ at table @option
+ at item a, angle
+Set the angle expression.
+The command accepts the same syntax of the corresponding option.
+
+If the specified expression is not valid, it is kept at its current
+value.
+ at end table
+
+ at section sab
+
+Apply Shape Adaptive Blur.
+
+The filter accepts the following options:
+
+ at table @option
+ at item luma_radius, lr
+Set luma blur filter strength, must be a value in range 0.1-4.0, default
+value is 1.0. A greater value will result in a more blurred image, and
+in slower processing.
+
+ at item luma_pre_filter_radius, lpfr
+Set luma pre-filter radius, must be a value in the 0.1-2.0 range, default
+value is 1.0.
+
+ at item luma_strength, ls
+Set luma maximum difference between pixels to still be considered, must
+be a value in the 0.1-100.0 range, default value is 1.0.
+
+ at item chroma_radius, cr
+Set chroma blur filter strength, must be a value in range 0.1-4.0. A
+greater value will result in a more blurred image, and in slower
+processing.
+
+ at item chroma_pre_filter_radius, cpfr
+Set chroma pre-filter radius, must be a value in the 0.1-2.0 range.
+
+ at item chroma_strength, cs
+Set chroma maximum difference between pixels to still be considered,
+must be a value in the 0.1-100.0 range.
+ at end table
+
+Each chroma option value, if not explicitly specified, is set to the
+corresponding luma option value.
+
+ at anchor{scale}
+ at section scale
+
+Scale (resize) the input video, using the libswscale library.
+
+The scale filter forces the output display aspect ratio to be the same
+of the input, by changing the output sample aspect ratio.
+
+If the input image format is different from the format requested by
+the next filter, the scale filter will convert the input to the
+requested format.
+
+ at subsection Options
+The filter accepts the following options, or any of the options
+supported by the libswscale scaler.
+
+See @ref{scaler_options,,the ffmpeg-scaler manual,ffmpeg-scaler} for
+the complete list of scaler options.
+
+ at table @option
+ at item width, w
+ at item height, h
+Set the output video dimension expression. Default value is the input
+dimension.
+
+If the value is 0, the input width is used for the output.
+
+If one of the values is -1, the scale filter will use a value that
+maintains the aspect ratio of the input image, calculated from the
+other specified dimension. If both of them are -1, the input size is
+used
+
+If one of the values is -n with n > 1, the scale filter will also use a value
+that maintains the aspect ratio of the input image, calculated from the other
+specified dimension. After that it will, however, make sure that the calculated
+dimension is divisible by n and adjust the value if necessary.
+
+See below for the list of accepted constants for use in the dimension
+expression.
+
+ at item interl
+Set the interlacing mode. It accepts the following values:
+
+ at table @samp
+ at item 1
+Force interlaced aware scaling.
+
+ at item 0
+Do not apply interlaced scaling.
+
+ at item -1
+Select interlaced aware scaling depending on whether the source frames
+are flagged as interlaced or not.
+ at end table
+
+Default value is @samp{0}.
+
+ at item flags
+Set libswscale scaling flags. See
+ at ref{sws_flags,,the ffmpeg-scaler manual,ffmpeg-scaler} for the
+complete list of values. If not explicitly specified the filter applies
+the default flags.
+
+ at item size, s
+Set the video size. For the syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+
+ at item in_color_matrix
+ at item out_color_matrix
+Set in/output YCbCr color space type.
+
+This allows the autodetected value to be overridden as well as allows forcing
+a specific value used for the output and encoder.
+
+If not specified, the color space type depends on the pixel format.
+
+Possible values:
+
+ at table @samp
+ at item auto
+Choose automatically.
+
+ at item bt709
+Format conforming to International Telecommunication Union (ITU)
+Recommendation BT.709.
+
+ at item fcc
+Set color space conforming to the United States Federal Communications
+Commission (FCC) Code of Federal Regulations (CFR) Title 47 (2003) 73.682 (a).
+
+ at item bt601
+Set color space conforming to:
+
+ at itemize
+ at item
+ITU Radiocommunication Sector (ITU-R) Recommendation BT.601
+
+ at item
+ITU-R Rec. BT.470-6 (1998) Systems B, B1, and G
+
+ at item
+Society of Motion Picture and Television Engineers (SMPTE) ST 170:2004
+
+ at end itemize
+
+ at item smpte240m
+Set color space conforming to SMPTE ST 240:1999.
+ at end table
+
+ at item in_range
+ at item out_range
+Set in/output YCbCr sample range.
+
+This allows the autodetected value to be overridden as well as allows forcing
+a specific value used for the output and encoder. If not specified, the
+range depends on the pixel format. Possible values:
+
+ at table @samp
+ at item auto
+Choose automatically.
+
+ at item jpeg/full/pc
+Set full range (0-255 in case of 8-bit luma).
+
+ at item mpeg/tv
+Set "MPEG" range (16-235 in case of 8-bit luma).
+ at end table
+
+ at item force_original_aspect_ratio
+Enable decreasing or increasing output video width or height if necessary to
+keep the original aspect ratio. Possible values:
+
+ at table @samp
+ at item disable
+Scale the video as specified and disable this feature.
+
+ at item decrease
+The output video dimensions will automatically be decreased if needed.
+
+ at item increase
+The output video dimensions will automatically be increased if needed.
+
+ at end table
+
+One useful instance of this option is that when you know a specific device's
+maximum allowed resolution, you can use this to limit the output video to
+that, while retaining the aspect ratio. For example, device A allows
+1280x720 playback, and your video is 1920x800. Using this option (set it to
+decrease) and specifying 1280x720 to the command line makes the output
+1280x533.
+
+Please note that this is a different thing than specifying -1 for @option{w}
+or @option{h}, you still need to specify the output resolution for this option
+to work.
+
+ at end table
+
+The values of the @option{w} and @option{h} options are expressions
+containing the following constants:
+
+ at table @var
+ at item in_w
+ at item in_h
+The input width and height
+
+ at item iw
+ at item ih
+These are the same as @var{in_w} and @var{in_h}.
+
+ at item out_w
+ at item out_h
+The output (scaled) width and height
+
+ at item ow
+ at item oh
+These are the same as @var{out_w} and @var{out_h}
+
+ at item a
+The same as @var{iw} / @var{ih}
+
+ at item sar
+input sample aspect ratio
+
+ at item dar
+The input display aspect ratio. Calculated from @code{(iw / ih) * sar}.
+
+ at item hsub
+ at item vsub
+horizontal and vertical input chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+
+ at item ohsub
+ at item ovsub
+horizontal and vertical output chroma subsample values. For example for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Scale the input video to a size of 200x100
+ at example
+scale=w=200:h=100
+ at end example
+
+This is equivalent to:
+ at example
+scale=200:100
+ at end example
+
+or:
+ at example
+scale=200x100
+ at end example
+
+ at item
+Specify a size abbreviation for the output size:
+ at example
+scale=qcif
+ at end example
+
+which can also be written as:
+ at example
+scale=size=qcif
+ at end example
+
+ at item
+Scale the input to 2x:
+ at example
+scale=w=2*iw:h=2*ih
+ at end example
+
+ at item
+The above is the same as:
+ at example
+scale=2*in_w:2*in_h
+ at end example
+
+ at item
+Scale the input to 2x with forced interlaced scaling:
+ at example
+scale=2*iw:2*ih:interl=1
+ at end example
+
+ at item
+Scale the input to half size:
+ at example
+scale=w=iw/2:h=ih/2
+ at end example
+
+ at item
+Increase the width, and set the height to the same size:
+ at example
+scale=3/2*iw:ow
+ at end example
+
+ at item
+Seek Greek harmony:
+ at example
+scale=iw:1/PHI*iw
+scale=ih*PHI:ih
+ at end example
+
+ at item
+Increase the height, and set the width to 3/2 of the height:
+ at example
+scale=w=3/2*oh:h=3/5*ih
+ at end example
+
+ at item
+Increase the size, making the size a multiple of the chroma
+subsample values:
+ at example
+scale="trunc(3/2*iw/hsub)*hsub:trunc(3/2*ih/vsub)*vsub"
+ at end example
+
+ at item
+Increase the width to a maximum of 500 pixels,
+keeping the same aspect ratio as the input:
+ at example
+scale=w='min(500\, iw*3/2):h=-1'
+ at end example
+ at end itemize
+
+ at subsection Commands
+
+This filter supports the following commands:
+ at table @option
+ at item width, w
+ at item height, h
+Set the output video dimension expression.
+The command accepts the same syntax of the corresponding option.
+
+If the specified expression is not valid, it is kept at its current
+value.
+ at end table
+
+ at section scale2ref
+
+Scale (resize) the input video, based on a reference video.
+
+See the scale filter for available options, scale2ref supports the same but
+uses the reference video instead of the main input as basis.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Scale a subtitle stream (b) to match the main video (a) in size before overlaying
+ at example
+'scale2ref[b][a];[a][b]overlay'
+ at end example
+ at end itemize
+
+ at section separatefields
+
+The @code{separatefields} takes a frame-based video input and splits
+each frame into its components fields, producing a new half height clip
+with twice the frame rate and twice the frame count.
+
+This filter use field-dominance information in frame to decide which
+of each pair of fields to place first in the output.
+If it gets it wrong use @ref{setfield} filter before @code{separatefields} filter.
+
+ at section setdar, setsar
+
+The @code{setdar} filter sets the Display Aspect Ratio for the filter
+output video.
+
+This is done by changing the specified Sample (aka Pixel) Aspect
+Ratio, according to the following equation:
+ at example
+ at var{DAR} = @var{HORIZONTAL_RESOLUTION} / @var{VERTICAL_RESOLUTION} * @var{SAR}
+ at end example
+
+Keep in mind that the @code{setdar} filter does not modify the pixel
+dimensions of the video frame. Also, the display aspect ratio set by
+this filter may be changed by later filters in the filterchain,
+e.g. in case of scaling or if another "setdar" or a "setsar" filter is
+applied.
+
+The @code{setsar} filter sets the Sample (aka Pixel) Aspect Ratio for
+the filter output video.
+
+Note that as a consequence of the application of this filter, the
+output display aspect ratio will change according to the equation
+above.
+
+Keep in mind that the sample aspect ratio set by the @code{setsar}
+filter may be changed by later filters in the filterchain, e.g. if
+another "setsar" or a "setdar" filter is applied.
+
+It accepts the following parameters:
+
+ at table @option
+ at item r, ratio, dar (@code{setdar} only), sar (@code{setsar} only)
+Set the aspect ratio used by the filter.
+
+The parameter can be a floating point number string, an expression, or
+a string of the form @var{num}:@var{den}, where @var{num} and
+ at var{den} are the numerator and denominator of the aspect ratio. If
+the parameter is not specified, it is assumed the value "0".
+In case the form "@var{num}:@var{den}" is used, the @code{:} character
+should be escaped.
+
+ at item max
+Set the maximum integer value to use for expressing numerator and
+denominator when reducing the expressed aspect ratio to a rational.
+Default value is @code{100}.
+
+ at end table
+
+The parameter @var{sar} is an expression containing
+the following constants:
+
+ at table @option
+ at item E, PI, PHI
+These are approximated values for the mathematical constants e
+(Euler's number), pi (Greek pi), and phi (the golden ratio).
+
+ at item w, h
+The input width and height.
+
+ at item a
+These are the same as @var{w} / @var{h}.
+
+ at item sar
+The input sample aspect ratio.
+
+ at item dar
+The input display aspect ratio. It is the same as
+(@var{w} / @var{h}) * @var{sar}.
+
+ at item hsub, vsub
+Horizontal and vertical chroma subsample values. For example, for the
+pixel format "yuv422p" @var{hsub} is 2 and @var{vsub} is 1.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+
+ at item
+To change the display aspect ratio to 16:9, specify one of the following:
+ at example
+setdar=dar=1.77777
+setdar=dar=16/9
+setdar=dar=1.77777
+ at end example
+
+ at item
+To change the sample aspect ratio to 10:11, specify:
+ at example
+setsar=sar=10/11
+ at end example
+
+ at item
+To set a display aspect ratio of 16:9, and specify a maximum integer value of
+1000 in the aspect ratio reduction, use the command:
+ at example
+setdar=ratio=16/9:max=1000
+ at end example
+
+ at end itemize
+
+ at anchor{setfield}
+ at section setfield
+
+Force field for the output video frame.
+
+The @code{setfield} filter marks the interlace type field for the
+output frames. It does not change the input frame, but only sets the
+corresponding property, which affects how the frame is treated by
+following filters (e.g. @code{fieldorder} or @code{yadif}).
+
+The filter accepts the following options:
+
+ at table @option
+
+ at item mode
+Available values are:
+
+ at table @samp
+ at item auto
+Keep the same field property.
+
+ at item bff
+Mark the frame as bottom-field-first.
+
+ at item tff
+Mark the frame as top-field-first.
+
+ at item prog
+Mark the frame as progressive.
+ at end table
+ at end table
+
+ at section showinfo
+
+Show a line containing various information for each input video frame.
+The input video is not modified.
+
+The shown line contains a sequence of key/value pairs of the form
+ at var{key}:@var{value}.
+
+The following values are shown in the output:
+
+ at table @option
+ at item n
+The (sequential) number of the input frame, starting from 0.
+
+ at item pts
+The Presentation TimeStamp of the input frame, expressed as a number of
+time base units. The time base unit depends on the filter input pad.
+
+ at item pts_time
+The Presentation TimeStamp of the input frame, expressed as a number of
+seconds.
+
+ at item pos
+The position of the frame in the input stream, or -1 if this information is
+unavailable and/or meaningless (for example in case of synthetic video).
+
+ at item fmt
+The pixel format name.
+
+ at item sar
+The sample aspect ratio of the input frame, expressed in the form
+ at var{num}/@var{den}.
+
+ at item s
+The size of the input frame. For the syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+
+ at item i
+The type of interlaced mode ("P" for "progressive", "T" for top field first, "B"
+for bottom field first).
+
+ at item iskey
+This is 1 if the frame is a key frame, 0 otherwise.
+
+ at item type
+The picture type of the input frame ("I" for an I-frame, "P" for a
+P-frame, "B" for a B-frame, or "?" for an unknown type).
+Also refer to the documentation of the @code{AVPictureType} enum and of
+the @code{av_get_picture_type_char} function defined in
+ at file{libavutil/avutil.h}.
+
+ at item checksum
+The Adler-32 checksum (printed in hexadecimal) of all the planes of the input frame.
+
+ at item plane_checksum
+The Adler-32 checksum (printed in hexadecimal) of each plane of the input frame,
+expressed in the form "[@var{c0} @var{c1} @var{c2} @var{c3}]".
+ at end table
+
+ at section showpalette
+
+Displays the 256 colors palette of each frame. This filter is only relevant for
+ at var{pal8} pixel format frames.
+
+It accepts the following option:
+
+ at table @option
+ at item s
+Set the size of the box used to represent one palette color entry. Default is
+ at code{30} (for a @code{30x30} pixel box).
+ at end table
+
+ at section shuffleplanes
+
+Reorder and/or duplicate video planes.
+
+It accepts the following parameters:
+
+ at table @option
+
+ at item map0
+The index of the input plane to be used as the first output plane.
+
+ at item map1
+The index of the input plane to be used as the second output plane.
+
+ at item map2
+The index of the input plane to be used as the third output plane.
+
+ at item map3
+The index of the input plane to be used as the fourth output plane.
+
+ at end table
+
+The first plane has the index 0. The default is to keep the input unchanged.
+
+Swap the second and third planes of the input:
+ at example
+ffmpeg -i INPUT -vf shuffleplanes=0:2:1:3 OUTPUT
+ at end example
+
+ at anchor{signalstats}
+ at section signalstats
+Evaluate various visual metrics that assist in determining issues associated
+with the digitization of analog video media.
+
+By default the filter will log these metadata values:
+
+ at table @option
+ at item YMIN
+Display the minimal Y value contained within the input frame. Expressed in
+range of [0-255].
+
+ at item YLOW
+Display the Y value at the 10% percentile within the input frame. Expressed in
+range of [0-255].
+
+ at item YAVG
+Display the average Y value within the input frame. Expressed in range of
+[0-255].
+
+ at item YHIGH
+Display the Y value at the 90% percentile within the input frame. Expressed in
+range of [0-255].
+
+ at item YMAX
+Display the maximum Y value contained within the input frame. Expressed in
+range of [0-255].
+
+ at item UMIN
+Display the minimal U value contained within the input frame. Expressed in
+range of [0-255].
+
+ at item ULOW
+Display the U value at the 10% percentile within the input frame. Expressed in
+range of [0-255].
+
+ at item UAVG
+Display the average U value within the input frame. Expressed in range of
+[0-255].
+
+ at item UHIGH
+Display the U value at the 90% percentile within the input frame. Expressed in
+range of [0-255].
+
+ at item UMAX
+Display the maximum U value contained within the input frame. Expressed in
+range of [0-255].
+
+ at item VMIN
+Display the minimal V value contained within the input frame. Expressed in
+range of [0-255].
+
+ at item VLOW
+Display the V value at the 10% percentile within the input frame. Expressed in
+range of [0-255].
+
+ at item VAVG
+Display the average V value within the input frame. Expressed in range of
+[0-255].
+
+ at item VHIGH
+Display the V value at the 90% percentile within the input frame. Expressed in
+range of [0-255].
+
+ at item VMAX
+Display the maximum V value contained within the input frame. Expressed in
+range of [0-255].
+
+ at item SATMIN
+Display the minimal saturation value contained within the input frame.
+Expressed in range of [0-~181.02].
+
+ at item SATLOW
+Display the saturation value at the 10% percentile within the input frame.
+Expressed in range of [0-~181.02].
+
+ at item SATAVG
+Display the average saturation value within the input frame. Expressed in range
+of [0-~181.02].
+
+ at item SATHIGH
+Display the saturation value at the 90% percentile within the input frame.
+Expressed in range of [0-~181.02].
+
+ at item SATMAX
+Display the maximum saturation value contained within the input frame.
+Expressed in range of [0-~181.02].
+
+ at item HUEMED
+Display the median value for hue within the input frame. Expressed in range of
+[0-360].
+
+ at item HUEAVG
+Display the average value for hue within the input frame. Expressed in range of
+[0-360].
+
+ at item YDIF
+Display the average of sample value difference between all values of the Y
+plane in the current frame and corresponding values of the previous input frame.
+Expressed in range of [0-255].
+
+ at item UDIF
+Display the average of sample value difference between all values of the U
+plane in the current frame and corresponding values of the previous input frame.
+Expressed in range of [0-255].
+
+ at item VDIF
+Display the average of sample value difference between all values of the V
+plane in the current frame and corresponding values of the previous input frame.
+Expressed in range of [0-255].
+ at end table
+
+The filter accepts the following options:
+
+ at table @option
+ at item stat
+ at item out
+
+ at option{stat} specify an additional form of image analysis.
+ at option{out} output video with the specified type of pixel highlighted.
+
+Both options accept the following values:
+
+ at table @samp
+ at item tout
+Identify @var{temporal outliers} pixels. A @var{temporal outlier} is a pixel
+unlike the neighboring pixels of the same field. Examples of temporal outliers
+include the results of video dropouts, head clogs, or tape tracking issues.
+
+ at item vrep
+Identify @var{vertical line repetition}. Vertical line repetition includes
+similar rows of pixels within a frame. In born-digital video vertical line
+repetition is common, but this pattern is uncommon in video digitized from an
+analog source. When it occurs in video that results from the digitization of an
+analog source it can indicate concealment from a dropout compensator.
+
+ at item brng
+Identify pixels that fall outside of legal broadcast range.
+ at end table
+
+ at item color, c
+Set the highlight color for the @option{out} option. The default color is
+yellow.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Output data of various video metrics:
+ at example
+ffprobe -f lavfi movie=example.mov,signalstats="stat=tout+vrep+brng" -show_frames
+ at end example
+
+ at item
+Output specific data about the minimum and maximum values of the Y plane per frame:
+ at example
+ffprobe -f lavfi movie=example.mov,signalstats -show_entries frame_tags=lavfi.signalstats.YMAX,lavfi.signalstats.YMIN
+ at end example
+
+ at item
+Playback video while highlighting pixels that are outside of broadcast range in red.
+ at example
+ffplay example.mov -vf signalstats="out=brng:color=red"
+ at end example
+
+ at item
+Playback video with signalstats metadata drawn over the frame.
+ at example
+ffplay example.mov -vf signalstats=stat=brng+vrep+tout,drawtext=fontfile=FreeSerif.ttf:textfile=signalstat_drawtext.txt
+ at end example
+
+The contents of signalstat_drawtext.txt used in the command are:
+ at example
+time %@{pts:hms@}
+Y (%@{metadata:lavfi.signalstats.YMIN@}-%@{metadata:lavfi.signalstats.YMAX@})
+U (%@{metadata:lavfi.signalstats.UMIN@}-%@{metadata:lavfi.signalstats.UMAX@})
+V (%@{metadata:lavfi.signalstats.VMIN@}-%@{metadata:lavfi.signalstats.VMAX@})
+saturation maximum: %@{metadata:lavfi.signalstats.SATMAX@}
+
+ at end example
+ at end itemize
+
+ at anchor{smartblur}
+ at section smartblur
+
+Blur the input video without impacting the outlines.
+
+It accepts the following options:
+
+ at table @option
+ at item luma_radius, lr
+Set the luma radius. The option value must be a float number in
+the range [0.1,5.0] that specifies the variance of the gaussian filter
+used to blur the image (slower if larger). Default value is 1.0.
+
+ at item luma_strength, ls
+Set the luma strength. The option value must be a float number
+in the range [-1.0,1.0] that configures the blurring. A value included
+in [0.0,1.0] will blur the image whereas a value included in
+[-1.0,0.0] will sharpen the image. Default value is 1.0.
+
+ at item luma_threshold, lt
+Set the luma threshold used as a coefficient to determine
+whether a pixel should be blurred or not. The option value must be an
+integer in the range [-30,30]. A value of 0 will filter all the image,
+a value included in [0,30] will filter flat areas and a value included
+in [-30,0] will filter edges. Default value is 0.
+
+ at item chroma_radius, cr
+Set the chroma radius. The option value must be a float number in
+the range [0.1,5.0] that specifies the variance of the gaussian filter
+used to blur the image (slower if larger). Default value is 1.0.
+
+ at item chroma_strength, cs
+Set the chroma strength. The option value must be a float number
+in the range [-1.0,1.0] that configures the blurring. A value included
+in [0.0,1.0] will blur the image whereas a value included in
+[-1.0,0.0] will sharpen the image. Default value is 1.0.
+
+ at item chroma_threshold, ct
+Set the chroma threshold used as a coefficient to determine
+whether a pixel should be blurred or not. The option value must be an
+integer in the range [-30,30]. A value of 0 will filter all the image,
+a value included in [0,30] will filter flat areas and a value included
+in [-30,0] will filter edges. Default value is 0.
+ at end table
+
+If a chroma option is not explicitly set, the corresponding luma value
+is set.
+
+ at section ssim
+
+Obtain the SSIM (Structural SImilarity Metric) between two input videos.
+
+This filter takes in input two input videos, the first input is
+considered the "main" source and is passed unchanged to the
+output. The second input is used as a "reference" video for computing
+the SSIM.
+
+Both video inputs 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 filter stores the calculated SSIM of each frame.
+
+The description of the accepted parameters follows.
+
+ at table @option
+ at item stats_file, f
+If specified the filter will use the named file to save the SSIM of
+each individual frame.
+ at end table
+
+The file printed if @var{stats_file} is selected, contains a sequence of
+key/value pairs of the form @var{key}:@var{value} for each compared
+couple of frames.
+
+A description of each shown parameter follows:
+
+ at table @option
+ at item n
+sequential number of the input frame, starting from 1
+
+ at item Y, U, V, R, G, B
+SSIM of the compared frames for the component specified by the suffix.
+
+ at item All
+SSIM of the compared frames for the whole frame.
+
+ at item dB
+Same as above but in dB representation.
+ at end table
+
+For example:
+ at example
+movie=ref_movie.mpg, setpts=PTS-STARTPTS [main];
+[main][ref] ssim="stats_file=stats.log" [out]
+ at end example
+
+On this example the input file being processed is compared with the
+reference file @file{ref_movie.mpg}. The SSIM of each individual frame
+is stored in @file{stats.log}.
+
+Another example with both psnr and ssim at same time:
+ at example
+ffmpeg -i main.mpg -i ref.mpg -lavfi "ssim;[0:v][1:v]psnr" -f null -
+ at end example
+
+ at section stereo3d
+
+Convert between different stereoscopic image formats.
+
+The filters accept the following options:
+
+ at table @option
+ at item in
+Set stereoscopic image format of input.
+
+Available values for input image formats are:
+ at table @samp
+ at item sbsl
+side by side parallel (left eye left, right eye right)
+
+ at item sbsr
+side by side crosseye (right eye left, left eye right)
+
+ at item sbs2l
+side by side parallel with half width resolution
+(left eye left, right eye right)
+
+ at item sbs2r
+side by side crosseye with half width resolution
+(right eye left, left eye right)
+
+ at item abl
+above-below (left eye above, right eye below)
+
+ at item abr
+above-below (right eye above, left eye below)
+
+ at item ab2l
+above-below with half height resolution
+(left eye above, right eye below)
+
+ at item ab2r
+above-below with half height resolution
+(right eye above, left eye below)
+
+ at item al
+alternating frames (left eye first, right eye second)
+
+ at item ar
+alternating frames (right eye first, left eye second)
+
+Default value is @samp{sbsl}.
+ at end table
+
+ at item out
+Set stereoscopic image format of output.
+
+Available values for output image formats are all the input formats as well as:
+ at table @samp
+ at item arbg
+anaglyph red/blue gray
+(red filter on left eye, blue filter on right eye)
+
+ at item argg
+anaglyph red/green gray
+(red filter on left eye, green filter on right eye)
+
+ at item arcg
+anaglyph red/cyan gray
+(red filter on left eye, cyan filter on right eye)
+
+ at item arch
+anaglyph red/cyan half colored
+(red filter on left eye, cyan filter on right eye)
+
+ at item arcc
+anaglyph red/cyan color
+(red filter on left eye, cyan filter on right eye)
+
+ at item arcd
+anaglyph red/cyan color optimized with the least squares projection of dubois
+(red filter on left eye, cyan filter on right eye)
+
+ at item agmg
+anaglyph green/magenta gray
+(green filter on left eye, magenta filter on right eye)
+
+ at item agmh
+anaglyph green/magenta half colored
+(green filter on left eye, magenta filter on right eye)
+
+ at item agmc
+anaglyph green/magenta colored
+(green filter on left eye, magenta filter on right eye)
+
+ at item agmd
+anaglyph green/magenta color optimized with the least squares projection of dubois
+(green filter on left eye, magenta filter on right eye)
+
+ at item aybg
+anaglyph yellow/blue gray
+(yellow filter on left eye, blue filter on right eye)
+
+ at item aybh
+anaglyph yellow/blue half colored
+(yellow filter on left eye, blue filter on right eye)
+
+ at item aybc
+anaglyph yellow/blue colored
+(yellow filter on left eye, blue filter on right eye)
+
+ at item aybd
+anaglyph yellow/blue color optimized with the least squares projection of dubois
+(yellow filter on left eye, blue filter on right eye)
+
+ at item irl
+interleaved rows (left eye has top row, right eye starts on next row)
+
+ at item irr
+interleaved rows (right eye has top row, left eye starts on next row)
+
+ at item ml
+mono output (left eye only)
+
+ at item mr
+mono output (right eye only)
+ at end table
+
+Default value is @samp{arcd}.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Convert input video from side by side parallel to anaglyph yellow/blue dubois:
+ at example
+stereo3d=sbsl:aybd
+ at end example
+
+ at item
+Convert input video from above below (left eye above, right eye below) to side by side crosseye.
+ at example
+stereo3d=abl:sbsr
+ at end example
+ at end itemize
+
+ at anchor{spp}
+ at section spp
+
+Apply a simple postprocessing filter that compresses and decompresses the image
+at several (or - in the case of @option{quality} level @code{6} - all) shifts
+and average the results.
+
+The filter accepts the following options:
+
+ at table @option
+ at item quality
+Set quality. This option defines the number of levels for averaging. It accepts
+an integer in the range 0-6. If set to @code{0}, the filter will have no
+effect. A value of @code{6} means the higher quality. For each increment of
+that value the speed drops by a factor of approximately 2. Default value is
+ at code{3}.
+
+ at item qp
+Force a constant quantization parameter. If not set, the filter will use the QP
+from the video stream (if available).
+
+ at item mode
+Set thresholding mode. Available modes are:
+
+ at table @samp
+ at item hard
+Set hard thresholding (default).
+ at item soft
+Set soft thresholding (better de-ringing effect, but likely blurrier).
+ at end table
+
+ at item use_bframe_qp
+Enable the use of the QP from the B-Frames if set to @code{1}. Using this
+option may cause flicker since the B-Frames have often larger QP. Default is
+ at code{0} (not enabled).
+ at end table
+
+ at anchor{subtitles}
+ at section subtitles
+
+Draw subtitles on top of input video using the libass library.
+
+To enable compilation of this filter you need to configure FFmpeg with
+ at code{--enable-libass}. This filter also requires a build with libavcodec and
+libavformat to convert the passed subtitles file to ASS (Advanced Substation
+Alpha) subtitles format.
+
+The filter accepts the following options:
+
+ at table @option
+ at item filename, f
+Set the filename of the subtitle file to read. It must be specified.
+
+ at item original_size
+Specify the size of the original video, the video for which the ASS file
+was composed. For the syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+Due to a misdesign in ASS aspect ratio arithmetic, this is necessary to
+correctly scale the fonts if the aspect ratio has been changed.
+
+ at item fontsdir
+Set a directory path containing fonts that can be used by the filter.
+These fonts will be used in addition to whatever the font provider uses.
+
+ at item charenc
+Set subtitles input character encoding. @code{subtitles} filter only. Only
+useful if not UTF-8.
+
+ at item stream_index, si
+Set subtitles stream index. @code{subtitles} filter only.
+
+ at item force_style
+Override default style or script info parameters of the subtitles. It accepts a
+string containing ASS style format @code{KEY=VALUE} couples separated by ",".
+ at end table
+
+If the first key is not specified, it is assumed that the first value
+specifies the @option{filename}.
+
+For example, to render the file @file{sub.srt} on top of the input
+video, use the command:
+ at example
+subtitles=sub.srt
+ at end example
+
+which is equivalent to:
+ at example
+subtitles=filename=sub.srt
+ at end example
+
+To render the default subtitles stream from file @file{video.mkv}, use:
+ at example
+subtitles=video.mkv
+ at end example
+
+To render the second subtitles stream from that file, use:
+ at example
+subtitles=video.mkv:si=1
+ at end example
+
+To make the subtitles stream from @file{sub.srt} appear in transparent green
+ at code{DejaVu Serif}, use:
+ at example
+subtitles=sub.srt:force_style='FontName=DejaVu Serif,PrimaryColour=&HAA00FF00'
+ at end example
+
+ at section super2xsai
+
+Scale the input by 2x and smooth using the Super2xSaI (Scale and
+Interpolate) pixel art scaling algorithm.
+
+Useful for enlarging pixel art images without reducing sharpness.
+
+ at section swapuv
+Swap U & V plane.
+
+ at section telecine
+
+Apply telecine process to the video.
+
+This filter accepts the following options:
+
+ at table @option
+ at item first_field
+ at table @samp
+ at item top, t
+top field first
+ at item bottom, b
+bottom field first
+The default value is @code{top}.
+ at end table
+
+ at item pattern
+A string of numbers representing the pulldown pattern you wish to apply.
+The default value is @code{23}.
+ at end table
+
+ at example
+Some typical patterns:
+
+NTSC output (30i):
+27.5p: 32222
+24p: 23 (classic)
+24p: 2332 (preferred)
+20p: 33
+18p: 334
+16p: 3444
+
+PAL output (25i):
+27.5p: 12222
+24p: 222222222223 ("Euro pulldown")
+16.67p: 33
+16p: 33333334
+ at end example
+
+ at section thumbnail
+Select the most representative frame in a given sequence of consecutive frames.
+
+The filter accepts the following options:
+
+ at table @option
+ at item n
+Set the frames batch size to analyze; in a set of @var{n} frames, the filter
+will pick one of them, and then handle the next batch of @var{n} frames until
+the end. Default is @code{100}.
+ at end table
+
+Since the filter keeps track of the whole frames sequence, a bigger @var{n}
+value will result in a higher memory usage, so a high value is not recommended.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Extract one picture each 50 frames:
+ at example
+thumbnail=50
+ at end example
+
+ at item
+Complete example of a thumbnail creation with @command{ffmpeg}:
+ at example
+ffmpeg -i in.avi -vf thumbnail,scale=300:200 -frames:v 1 out.png
+ at end example
+ at end itemize
+
+ at section tile
+
+Tile several successive frames together.
+
+The filter accepts the following options:
+
+ at table @option
+
+ at item layout
+Set the grid size (i.e. the number of lines and columns). For the syntax of
+this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+
+ at item nb_frames
+Set the maximum number of frames to render in the given area. It must be less
+than or equal to @var{w}x at var{h}. The default value is @code{0}, meaning all
+the area will be used.
+
+ at item margin
+Set the outer border margin in pixels.
+
+ at item padding
+Set the inner border thickness (i.e. the number of pixels between frames). For
+more advanced padding options (such as having different values for the edges),
+refer to the pad video filter.
+
+ at item color
+Specify the color of the unused area. For the syntax of this option, check the
+"Color" section in the ffmpeg-utils manual. The default value of @var{color}
+is "black".
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Produce 8x8 PNG tiles of all keyframes (@option{-skip_frame nokey}) in a movie:
+ at example
+ffmpeg -skip_frame nokey -i file.avi -vf 'scale=128:72,tile=8x8' -an -vsync 0 keyframes%03d.png
+ at end example
+The @option{-vsync 0} is necessary to prevent @command{ffmpeg} from
+duplicating each output frame to accommodate the originally detected frame
+rate.
+
+ at item
+Display @code{5} pictures in an area of @code{3x2} frames,
+with @code{7} pixels between them, and @code{2} pixels of initial margin, using
+mixed flat and named options:
+ at example
+tile=3x2:nb_frames=5:padding=7:margin=2
+ at end example
+ at end itemize
+
+ at section tinterlace
+
+Perform various types of temporal field interlacing.
+
+Frames are counted starting from 1, so the first input frame is
+considered odd.
+
+The filter accepts the following options:
+
+ at table @option
+
+ at item mode
+Specify the mode of the interlacing. This option can also be specified
+as a value alone. See below for a list of values for this option.
+
+Available values are:
+
+ at table @samp
+ at item merge, 0
+Move odd frames into the upper field, even into the lower field,
+generating a double height frame at half frame rate.
+ at example
+ ------> time
+Input:
+Frame 1 Frame 2 Frame 3 Frame 4
+
+11111 22222 33333 44444
+11111 22222 33333 44444
+11111 22222 33333 44444
+11111 22222 33333 44444
+
+Output:
+11111 33333
+22222 44444
+11111 33333
+22222 44444
+11111 33333
+22222 44444
+11111 33333
+22222 44444
+ at end example
+
+ at item drop_odd, 1
+Only output even frames, odd frames are dropped, generating a frame with
+unchanged height at half frame rate.
+
+ at example
+ ------> time
+Input:
+Frame 1 Frame 2 Frame 3 Frame 4
+
+11111 22222 33333 44444
+11111 22222 33333 44444
+11111 22222 33333 44444
+11111 22222 33333 44444
+
+Output:
+ 22222 44444
+ 22222 44444
+ 22222 44444
+ 22222 44444
+ at end example
+
+ at item drop_even, 2
+Only output odd frames, even frames are dropped, generating a frame with
+unchanged height at half frame rate.
+
+ at example
+ ------> time
+Input:
+Frame 1 Frame 2 Frame 3 Frame 4
+
+11111 22222 33333 44444
+11111 22222 33333 44444
+11111 22222 33333 44444
+11111 22222 33333 44444
+
+Output:
+11111 33333
+11111 33333
+11111 33333
+11111 33333
+ at end example
+
+ at item pad, 3
+Expand each frame to full height, but pad alternate lines with black,
+generating a frame with double height at the same input frame rate.
+
+ at example
+ ------> time
+Input:
+Frame 1 Frame 2 Frame 3 Frame 4
+
+11111 22222 33333 44444
+11111 22222 33333 44444
+11111 22222 33333 44444
+11111 22222 33333 44444
+
+Output:
+11111 ..... 33333 .....
+..... 22222 ..... 44444
+11111 ..... 33333 .....
+..... 22222 ..... 44444
+11111 ..... 33333 .....
+..... 22222 ..... 44444
+11111 ..... 33333 .....
+..... 22222 ..... 44444
+ at end example
+
+
+ at item interleave_top, 4
+Interleave the upper field from odd frames with the lower field from
+even frames, generating a frame with unchanged height at half frame rate.
+
+ at example
+ ------> time
+Input:
+Frame 1 Frame 2 Frame 3 Frame 4
+
+11111<- 22222 33333<- 44444
+11111 22222<- 33333 44444<-
+11111<- 22222 33333<- 44444
+11111 22222<- 33333 44444<-
+
+Output:
+11111 33333
+22222 44444
+11111 33333
+22222 44444
+ at end example
+
+
+ at item interleave_bottom, 5
+Interleave the lower field from odd frames with the upper field from
+even frames, generating a frame with unchanged height at half frame rate.
+
+ at example
+ ------> time
+Input:
+Frame 1 Frame 2 Frame 3 Frame 4
+
+11111 22222<- 33333 44444<-
+11111<- 22222 33333<- 44444
+11111 22222<- 33333 44444<-
+11111<- 22222 33333<- 44444
+
+Output:
+22222 44444
+11111 33333
+22222 44444
+11111 33333
+ at end example
+
+
+ at item interlacex2, 6
+Double frame rate with unchanged height. Frames are inserted each
+containing the second temporal field from the previous input frame and
+the first temporal field from the next input frame. This mode relies on
+the top_field_first flag. Useful for interlaced video displays with no
+field synchronisation.
+
+ at example
+ ------> time
+Input:
+Frame 1 Frame 2 Frame 3 Frame 4
+
+11111 22222 33333 44444
+ 11111 22222 33333 44444
+11111 22222 33333 44444
+ 11111 22222 33333 44444
+
+Output:
+11111 22222 22222 33333 33333 44444 44444
+ 11111 11111 22222 22222 33333 33333 44444
+11111 22222 22222 33333 33333 44444 44444
+ 11111 11111 22222 22222 33333 33333 44444
+ at end example
+
+
+ at end table
+
+Numeric values are deprecated but are accepted for backward
+compatibility reasons.
+
+Default mode is @code{merge}.
+
+ at item flags
+Specify flags influencing the filter process.
+
+Available value for @var{flags} is:
+
+ at table @option
+ at item low_pass_filter, vlfp
+Enable vertical low-pass filtering in the filter.
+Vertical low-pass filtering is required when creating an interlaced
+destination from a progressive source which contains high-frequency
+vertical detail. Filtering will reduce interlace 'twitter' and Moire
+patterning.
+
+Vertical low-pass filtering can only be enabled for @option{mode}
+ at var{interleave_top} and @var{interleave_bottom}.
+
+ at end table
+ at end table
+
+ at section transpose
+
+Transpose rows with columns in the input video and optionally flip it.
+
+It accepts the following parameters:
+
+ at table @option
+
+ at item dir
+Specify the transposition direction.
+
+Can assume the following values:
+ at table @samp
+ at item 0, 4, cclock_flip
+Rotate by 90 degrees counterclockwise and vertically flip (default), that is:
+ at example
+L.R L.l
+. . -> . .
+l.r R.r
+ at end example
+
+ at item 1, 5, clock
+Rotate by 90 degrees clockwise, that is:
+ at example
+L.R l.L
+. . -> . .
+l.r r.R
+ at end example
+
+ at item 2, 6, cclock
+Rotate by 90 degrees counterclockwise, that is:
+ at example
+L.R R.r
+. . -> . .
+l.r L.l
+ at end example
+
+ at item 3, 7, clock_flip
+Rotate by 90 degrees clockwise and vertically flip, that is:
+ at example
+L.R r.R
+. . -> . .
+l.r l.L
+ at end example
+ at end table
+
+For values between 4-7, the transposition is only done if the input
+video geometry is portrait and not landscape. These values are
+deprecated, the @code{passthrough} option should be used instead.
+
+Numerical values are deprecated, and should be dropped in favor of
+symbolic constants.
+
+ at item passthrough
+Do not apply the transposition if the input geometry matches the one
+specified by the specified value. It accepts the following values:
+ at table @samp
+ at item none
+Always apply transposition.
+ at item portrait
+Preserve portrait geometry (when @var{height} >= @var{width}).
+ at item landscape
+Preserve landscape geometry (when @var{width} >= @var{height}).
+ at end table
+
+Default value is @code{none}.
+ at end table
+
+For example to rotate by 90 degrees clockwise and preserve portrait
+layout:
+ at example
+transpose=dir=1:passthrough=portrait
+ at end example
+
+The command above can also be specified as:
+ at example
+transpose=1:portrait
+ at end example
+
+ at section trim
+Trim the input so that the output contains one continuous subpart of the input.
+
+It accepts the following parameters:
+ at table @option
+ at item start
+Specify the time of the start of the kept section, i.e. the frame with the
+timestamp @var{start} will be the first frame in the output.
+
+ at item end
+Specify the time of the first frame that will be dropped, i.e. the frame
+immediately preceding the one with the timestamp @var{end} will be the last
+frame in the output.
+
+ at item start_pts
+This is the same as @var{start}, except this option sets the start timestamp
+in timebase units instead of seconds.
+
+ at item end_pts
+This is the same as @var{end}, except this option sets the end timestamp
+in timebase units instead of seconds.
+
+ at item duration
+The maximum duration of the output in seconds.
+
+ at item start_frame
+The number of the first frame that should be passed to the output.
+
+ at item end_frame
+The number of the first frame that should be dropped.
+ at end table
+
+ at option{start}, @option{end}, and @option{duration} are expressed as time
+duration specifications; see
+ at ref{time duration syntax,,the Time duration section in the ffmpeg-utils(1) manual,ffmpeg-utils}
+for the accepted syntax.
+
+Note that the first two sets of the start/end options and the @option{duration}
+option look at the frame timestamp, while the _frame variants simply count the
+frames that pass through the filter. Also note that this filter does not modify
+the timestamps. If you wish for the output timestamps to start at zero, insert a
+setpts filter after the trim filter.
+
+If multiple start or end options are set, this filter tries to be greedy and
+keep all the frames that match at least one of the specified constraints. To keep
+only the part that matches all the constraints at once, chain multiple trim
+filters.
+
+The defaults are such that all the input is kept. So it is possible to set e.g.
+just the end values to keep everything before the specified time.
+
+Examples:
+ at itemize
+ at item
+Drop everything except the second minute of input:
+ at example
+ffmpeg -i INPUT -vf trim=60:120
+ at end example
+
+ at item
+Keep only the first second:
+ at example
+ffmpeg -i INPUT -vf trim=duration=1
+ at end example
+
+ at end itemize
+
+
+ at anchor{unsharp}
+ at section unsharp
+
+Sharpen or blur the input video.
+
+It accepts the following parameters:
+
+ at table @option
+ at item luma_msize_x, lx
+Set the luma matrix horizontal size. It must be an odd integer between
+3 and 63. The default value is 5.
+
+ at item luma_msize_y, ly
+Set the luma matrix vertical size. It must be an odd integer between 3
+and 63. The default value is 5.
+
+ at item luma_amount, la
+Set the luma effect strength. It must be a floating point number, reasonable
+values lay between -1.5 and 1.5.
+
+Negative values will blur the input video, while positive values will
+sharpen it, a value of zero will disable the effect.
+
+Default value is 1.0.
+
+ at item chroma_msize_x, cx
+Set the chroma matrix horizontal size. It must be an odd integer
+between 3 and 63. The default value is 5.
+
+ at item chroma_msize_y, cy
+Set the chroma matrix vertical size. It must be an odd integer
+between 3 and 63. The default value is 5.
+
+ at item chroma_amount, ca
+Set the chroma effect strength. It must be a floating point number, reasonable
+values lay between -1.5 and 1.5.
+
+Negative values will blur the input video, while positive values will
+sharpen it, a value of zero will disable the effect.
+
+Default value is 0.0.
+
+ at item opencl
+If set to 1, specify using OpenCL capabilities, only available if
+FFmpeg was configured with @code{--enable-opencl}. Default value is 0.
+
+ at end table
+
+All parameters are optional and default to the equivalent of the
+string '5:5:1.0:5:5:0.0'.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Apply strong luma sharpen effect:
+ at example
+unsharp=luma_msize_x=7:luma_msize_y=7:luma_amount=2.5
+ at end example
+
+ at item
+Apply a strong blur of both luma and chroma parameters:
+ at example
+unsharp=7:7:-2:7:7:-2
+ at end example
+ at end itemize
+
+ at section uspp
+
+Apply ultra slow/simple postprocessing filter that compresses and decompresses
+the image at several (or - in the case of @option{quality} level @code{8} - all)
+shifts and average the results.
+
+The way this differs from the behavior of spp is that uspp actually encodes &
+decodes each case with libavcodec Snow, whereas spp uses a simplified intra only 8x8
+DCT similar to MJPEG.
+
+The filter accepts the following options:
+
+ at table @option
+ at item quality
+Set quality. This option defines the number of levels for averaging. It accepts
+an integer in the range 0-8. If set to @code{0}, the filter will have no
+effect. A value of @code{8} means the higher quality. For each increment of
+that value the speed drops by a factor of approximately 2. Default value is
+ at code{3}.
+
+ at item qp
+Force a constant quantization parameter. If not set, the filter will use the QP
+from the video stream (if available).
+ at end table
+
+ at section vectorscope
+
+Display 2 color component values in the two dimensional graph (which is called
+a vectorscope).
+
+This filter accepts the following options:
+
+ at table @option
+ at item mode, m
+Set vectorscope mode.
+
+It accepts the following values:
+ at table @samp
+ at item gray
+Gray values are displayed on graph, higher brightness means more pixels have
+same component color value on location in graph. This is the default mode.
+
+ at item color
+Gray values are displayed on graph. Surrounding pixels values which are not
+present in video frame are drawn in gradient of 2 color components which are
+set by option @code{x} and @code{y}.
+
+ at item color2
+Actual color components values present in video frame are displayed on graph.
+
+ at item color3
+Similar as color2 but higher frequency of same values @code{x} and @code{y}
+on graph increases value of another color component, which is luminance by
+default values of @code{x} and @code{y}.
+
+ at item color4
+Actual colors present in video frame are displayed on graph. If two different
+colors map to same position on graph then color with higher value of component
+not present in graph is picked.
+ at end table
+
+ at item x
+Set which color component will be represented on X-axis. Default is @code{1}.
+
+ at item y
+Set which color component will be represented on Y-axis. Default is @code{2}.
+
+ at item intensity, i
+Set intensity, used by modes: gray, color and color3 for increasing brightness
+of color component which represents frequency of (X, Y) location in graph.
+
+ at item envelope, e
+ at table @samp
+ at item none
+No envelope, this is default.
+
+ at item instant
+Instant envelope, even darkest single pixel will be clearly highlighted.
+
+ at item peak
+Hold maximum and minimum values presented in graph over time. This way you
+can still spot out of range values without constantly looking at vectorscope.
+
+ at item peak+instant
+Peak and instant envelope combined together.
+ at end table
+ at end table
+
+ at anchor{vidstabdetect}
+ at section vidstabdetect
+
+Analyze video stabilization/deshaking. Perform pass 1 of 2, see
+ at ref{vidstabtransform} for pass 2.
+
+This filter generates a file with relative translation and rotation
+transform information about subsequent frames, which is then used by
+the @ref{vidstabtransform} filter.
+
+To enable compilation of this filter you need to configure FFmpeg with
+ at code{--enable-libvidstab}.
+
+This filter accepts the following options:
+
+ at table @option
+ at item result
+Set the path to the file used to write the transforms information.
+Default value is @file{transforms.trf}.
+
+ at item shakiness
+Set how shaky the video is and how quick the camera is. It accepts an
+integer in the range 1-10, a value of 1 means little shakiness, a
+value of 10 means strong shakiness. Default value is 5.
+
+ at item accuracy
+Set the accuracy of the detection process. It must be a value in the
+range 1-15. A value of 1 means low accuracy, a value of 15 means high
+accuracy. Default value is 15.
+
+ at item stepsize
+Set stepsize of the search process. The region around minimum is
+scanned with 1 pixel resolution. Default value is 6.
+
+ at item mincontrast
+Set minimum contrast. Below this value a local measurement field is
+discarded. Must be a floating point value in the range 0-1. Default
+value is 0.3.
+
+ at item tripod
+Set reference frame number for tripod mode.
+
+If enabled, the motion of the frames is compared to a reference frame
+in the filtered stream, identified by the specified number. The idea
+is to compensate all movements in a more-or-less static scene and keep
+the camera view absolutely still.
+
+If set to 0, it is disabled. The frames are counted starting from 1.
+
+ at item show
+Show fields and transforms in the resulting frames. It accepts an
+integer in the range 0-2. Default value is 0, which disables any
+visualization.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Use default values:
+ at example
+vidstabdetect
+ at end example
+
+ at item
+Analyze strongly shaky movie and put the results in file
+ at file{mytransforms.trf}:
+ at example
+vidstabdetect=shakiness=10:accuracy=15:result="mytransforms.trf"
+ at end example
+
+ at item
+Visualize the result of internal transformations in the resulting
+video:
+ at example
+vidstabdetect=show=1
+ at end example
+
+ at item
+Analyze a video with medium shakiness using @command{ffmpeg}:
+ at example
+ffmpeg -i input -vf vidstabdetect=shakiness=5:show=1 dummy.avi
+ at end example
+ at end itemize
+
+ at anchor{vidstabtransform}
+ at section vidstabtransform
+
+Video stabilization/deshaking: pass 2 of 2,
+see @ref{vidstabdetect} for pass 1.
+
+Read a file with transform information for each frame and
+apply/compensate them. Together with the @ref{vidstabdetect}
+filter this can be used to deshake videos. See also
+ at url{http://public.hronopik.de/vid.stab}. It is important to also use
+the @ref{unsharp} filter, see below.
+
+To enable compilation of this filter you need to configure FFmpeg with
+ at code{--enable-libvidstab}.
+
+ at subsection Options
+
+ at table @option
+ at item input
+Set path to the file used to read the transforms. Default value is
+ at file{transforms.trf}.
+
+ at item smoothing
+Set the number of frames (value*2 + 1) used for lowpass filtering the
+camera movements. Default value is 10.
+
+For example a number of 10 means that 21 frames are used (10 in the
+past and 10 in the future) to smoothen the motion in the video. A
+larger value leads to a smoother video, but limits the acceleration of
+the camera (pan/tilt movements). 0 is a special case where a static
+camera is simulated.
+
+ at item optalgo
+Set the camera path optimization algorithm.
+
+Accepted values are:
+ at table @samp
+ at item gauss
+gaussian kernel low-pass filter on camera motion (default)
+ at item avg
+averaging on transformations
+ at end table
+
+ at item maxshift
+Set maximal number of pixels to translate frames. Default value is -1,
+meaning no limit.
+
+ at item maxangle
+Set maximal angle in radians (degree*PI/180) to rotate frames. Default
+value is -1, meaning no limit.
+
+ at item crop
+Specify how to deal with borders that may be visible due to movement
+compensation.
+
+Available values are:
+ at table @samp
+ at item keep
+keep image information from previous frame (default)
+ at item black
+fill the border black
+ at end table
+
+ at item invert
+Invert transforms if set to 1. Default value is 0.
+
+ at item relative
+Consider transforms as relative to previous frame if set to 1,
+absolute if set to 0. Default value is 0.
+
+ at item zoom
+Set percentage to zoom. A positive value will result in a zoom-in
+effect, a negative value in a zoom-out effect. Default value is 0 (no
+zoom).
+
+ at item optzoom
+Set optimal zooming to avoid borders.
+
+Accepted values are:
+ at table @samp
+ at item 0
+disabled
+ at item 1
+optimal static zoom value is determined (only very strong movements
+will lead to visible borders) (default)
+ at item 2
+optimal adaptive zoom value is determined (no borders will be
+visible), see @option{zoomspeed}
+ at end table
+
+Note that the value given at zoom is added to the one calculated here.
+
+ at item zoomspeed
+Set percent to zoom maximally each frame (enabled when
+ at option{optzoom} is set to 2). Range is from 0 to 5, default value is
+0.25.
+
+ at item interpol
+Specify type of interpolation.
+
+Available values are:
+ at table @samp
+ at item no
+no interpolation
+ at item linear
+linear only horizontal
+ at item bilinear
+linear in both directions (default)
+ at item bicubic
+cubic in both directions (slow)
+ at end table
+
+ at item tripod
+Enable virtual tripod mode if set to 1, which is equivalent to
+ at code{relative=0:smoothing=0}. Default value is 0.
+
+Use also @code{tripod} option of @ref{vidstabdetect}.
+
+ at item debug
+Increase log verbosity if set to 1. Also the detected global motions
+are written to the temporary file @file{global_motions.trf}. Default
+value is 0.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Use @command{ffmpeg} for a typical stabilization with default values:
+ at example
+ffmpeg -i inp.mpeg -vf vidstabtransform,unsharp=5:5:0.8:3:3:0.4 inp_stabilized.mpeg
+ at end example
+
+Note the use of the @ref{unsharp} filter which is always recommended.
+
+ at item
+Zoom in a bit more and load transform data from a given file:
+ at example
+vidstabtransform=zoom=5:input="mytransforms.trf"
+ at end example
+
+ at item
+Smoothen the video even more:
+ at example
+vidstabtransform=smoothing=30
+ at end example
+ at end itemize
+
+ at section vflip
+
+Flip the input video vertically.
+
+For example, to vertically flip a video with @command{ffmpeg}:
+ at example
+ffmpeg -i in.avi -vf "vflip" out.avi
+ at end example
+
+ at anchor{vignette}
+ at section vignette
+
+Make or reverse a natural vignetting effect.
+
+The filter accepts the following options:
+
+ at table @option
+ at item angle, a
+Set lens angle expression as a number of radians.
+
+The value is clipped in the @code{[0,PI/2]} range.
+
+Default value: @code{"PI/5"}
+
+ at item x0
+ at item y0
+Set center coordinates expressions. Respectively @code{"w/2"} and @code{"h/2"}
+by default.
+
+ at item mode
+Set forward/backward mode.
+
+Available modes are:
+ at table @samp
+ at item forward
+The larger the distance from the central point, the darker the image becomes.
+
+ at item backward
+The larger the distance from the central point, the brighter the image becomes.
+This can be used to reverse a vignette effect, though there is no automatic
+detection to extract the lens @option{angle} and other settings (yet). It can
+also be used to create a burning effect.
+ at end table
+
+Default value is @samp{forward}.
+
+ at item eval
+Set evaluation mode for the expressions (@option{angle}, @option{x0}, @option{y0}).
+
+It accepts the following values:
+ at table @samp
+ at item init
+Evaluate expressions only once during the filter initialization.
+
+ at item frame
+Evaluate expressions for each incoming frame. This is way slower than the
+ at samp{init} mode since it requires all the scalers to be re-computed, but it
+allows advanced dynamic expressions.
+ at end table
+
+Default value is @samp{init}.
+
+ at item dither
+Set dithering to reduce the circular banding effects. Default is @code{1}
+(enabled).
+
+ at item aspect
+Set vignette aspect. This setting allows one to adjust the shape of the vignette.
+Setting this value to the SAR of the input will make a rectangular vignetting
+following the dimensions of the video.
+
+Default is @code{1/1}.
+ at end table
+
+ at subsection Expressions
+
+The @option{alpha}, @option{x0} and @option{y0} expressions can contain the
+following parameters.
+
+ at table @option
+ at item w
+ at item h
+input width and height
+
+ at item n
+the number of input frame, starting from 0
+
+ at item pts
+the PTS (Presentation TimeStamp) time of the filtered video frame, expressed in
+ at var{TB} units, NAN if undefined
+
+ at item r
+frame rate of the input video, NAN if the input frame rate is unknown
+
+ at item t
+the PTS (Presentation TimeStamp) of the filtered video frame,
+expressed in seconds, NAN if undefined
+
+ at item tb
+time base of the input video
+ at end table
+
+
+ at subsection Examples
+
+ at itemize
+ at item
+Apply simple strong vignetting effect:
+ at example
+vignette=PI/4
+ at end example
+
+ at item
+Make a flickering vignetting:
+ at example
+vignette='PI/4+random(1)*PI/50':eval=frame
+ at end example
+
+ at end itemize
+
+ at section vstack
+Stack input videos vertically.
+
+All streams must be of same pixel format and of same width.
+
+Note that this filter is faster than using @ref{overlay} and @ref{pad} filter
+to create same output.
+
+The filter accept the following option:
+
+ at table @option
+ at item nb_inputs
+Set number of input streams. Default is 2.
+ at end table
+
+ at section w3fdif
+
+Deinterlace the input video ("w3fdif" stands for "Weston 3 Field
+Deinterlacing Filter").
+
+Based on the process described by Martin Weston for BBC R&D, and
+implemented based on the de-interlace algorithm written by Jim
+Easterbrook for BBC R&D, the Weston 3 field deinterlacing filter
+uses filter coefficients calculated by BBC R&D.
+
+There are two sets of filter coefficients, so called "simple":
+and "complex". Which set of filter coefficients is used can
+be set by passing an optional parameter:
+
+ at table @option
+ at item filter
+Set the interlacing filter coefficients. Accepts one of the following values:
+
+ at table @samp
+ at item simple
+Simple filter coefficient set.
+ at item complex
+More-complex filter coefficient set.
+ at end table
+Default value is @samp{complex}.
+
+ at item deint
+Specify which frames to deinterlace. Accept one of the following values:
+
+ at table @samp
+ at item all
+Deinterlace all frames,
+ at item interlaced
+Only deinterlace frames marked as interlaced.
+ at end table
+
+Default value is @samp{all}.
+ at end table
+
+ at section waveform
+Video waveform monitor.
+
+The waveform monitor plots color component intensity. By default luminance
+only. Each column of the waveform corresponds to a column of pixels in the
+source video.
+
+It accepts the following options:
+
+ at table @option
+ at item mode, m
+Can be either @code{row}, or @code{column}. Default is @code{column}.
+In row mode, the graph on the left side represents color component value 0 and
+the right side represents value = 255. In column mode, the top side represents
+color component value = 0 and bottom side represents value = 255.
+
+ at item intensity, i
+Set intensity. Smaller values are useful to find out how many values of the same
+luminance are distributed across input rows/columns.
+Default value is @code{0.04}. Allowed range is [0, 1].
+
+ at item mirror, r
+Set mirroring mode. @code{0} means unmirrored, @code{1} means mirrored.
+In mirrored mode, higher values will be represented on the left
+side for @code{row} mode and at the top for @code{column} mode. Default is
+ at code{1} (mirrored).
+
+ at item display, d
+Set display mode.
+It accepts the following values:
+ at table @samp
+ at item overlay
+Presents information identical to that in the @code{parade}, except
+that the graphs representing color components are superimposed directly
+over one another.
+
+This display mode makes it easier to spot relative differences or similarities
+in overlapping areas of the color components that are supposed to be identical,
+such as neutral whites, grays, or blacks.
+
+ at item parade
+Display separate graph for the color components side by side in
+ at code{row} mode or one below the other in @code{column} mode.
+
+Using this display mode makes it easy to spot color casts in the highlights
+and shadows of an image, by comparing the contours of the top and the bottom
+graphs of each waveform. Since whites, grays, and blacks are characterized
+by exactly equal amounts of red, green, and blue, neutral areas of the picture
+should display three waveforms of roughly equal width/height. If not, the
+correction is easy to perform by making level adjustments the three waveforms.
+ at end table
+Default is @code{parade}.
+
+ at item components, c
+Set which color components to display. Default is 1, which means only luminance
+or red color component if input is in RGB colorspace. If is set for example to
+7 it will display all 3 (if) available color components.
+
+ at item envelope, e
+ at table @samp
+ at item none
+No envelope, this is default.
+
+ at item instant
+Instant envelope, minimum and maximum values presented in graph will be easily
+visible even with small @code{step} value.
+
+ at item peak
+Hold minimum and maximum values presented in graph across time. This way you
+can still spot out of range values without constantly looking at waveforms.
+
+ at item peak+instant
+Peak and instant envelope combined together.
+ at end table
+
+ at item filter, f
+ at table @samp
+ at item lowpass
+No filtering, this is default.
+
+ at item flat
+Luma and chroma combined together.
+
+ at item aflat
+Similar as above, but shows difference between blue and red chroma.
+
+ at item chroma
+Displays only chroma.
+
+ at item achroma
+Similar as above, but shows difference between blue and red chroma.
+
+ at item color
+Displays actual color value on waveform.
+ at end table
+ at end table
+
+ at section xbr
+Apply the xBR high-quality magnification filter which is designed for pixel
+art. It follows a set of edge-detection rules, see
+ at url{http://www.libretro.com/forums/viewtopic.php?f=6&t=134}.
+
+It accepts the following option:
+
+ at table @option
+ at item n
+Set the scaling dimension: @code{2} for @code{2xBR}, @code{3} for
+ at code{3xBR} and @code{4} for @code{4xBR}.
+Default is @code{3}.
+ at end table
+
+ at anchor{yadif}
+ at section yadif
+
+Deinterlace the input video ("yadif" means "yet another deinterlacing
+filter").
+
+It accepts the following parameters:
+
+
+ at table @option
+
+ at item mode
+The interlacing mode to adopt. It accepts one of the following values:
+
+ at table @option
+ at item 0, send_frame
+Output one frame for each frame.
+ at item 1, send_field
+Output one frame for each field.
+ at item 2, send_frame_nospatial
+Like @code{send_frame}, but it skips the spatial interlacing check.
+ at item 3, send_field_nospatial
+Like @code{send_field}, but it skips the spatial interlacing check.
+ at end table
+
+The default value is @code{send_frame}.
+
+ at item parity
+The picture field parity assumed for the input interlaced video. It accepts one
+of the following values:
+
+ at table @option
+ at item 0, tff
+Assume the top field is first.
+ at item 1, bff
+Assume the bottom field is first.
+ at item -1, auto
+Enable automatic detection of field parity.
+ at 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.
+
+ at item deint
+Specify which frames to deinterlace. Accept one of the following
+values:
+
+ at table @option
+ at item 0, all
+Deinterlace all frames.
+ at item 1, interlaced
+Only deinterlace frames marked as interlaced.
+ at end table
+
+The default value is @code{all}.
+ at end table
+
+ at section zoompan
+
+Apply Zoom & Pan effect.
+
+This filter accepts the following options:
+
+ at table @option
+ at item zoom, z
+Set the zoom expression. Default is 1.
+
+ at item x
+ at item y
+Set the x and y expression. Default is 0.
+
+ at 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.
+
+ at item s
+Set the output image size, default is 'hd720'.
+ at end table
+
+Each expression can contain the following constants:
+
+ at table @option
+ at item in_w, iw
+Input width.
+
+ at item in_h, ih
+Input height.
+
+ at item out_w, ow
+Output width.
+
+ at item out_h, oh
+Output height.
+
+ at item in
+Input frame count.
+
+ at item on
+Output frame count.
+
+ at item x
+ at item y
+Last calculated 'x' and 'y' position from 'x' and 'y' expression
+for current input frame.
+
+ at item px
+ at item py
+'x' and 'y' of last output frame of previous input frame or 0 when there was
+not yet such frame (first input frame).
+
+ at item zoom
+Last calculated zoom from 'z' expression for current input frame.
+
+ at item pzoom
+Last calculated zoom of last output frame of previous input frame.
+
+ at item duration
+Number of output frames for current input frame. Calculated from 'd' expression
+for each input frame.
+
+ at item pduration
+number of output frames created for previous input frame
+
+ at item a
+Rational number: input width / input height
+
+ at item sar
+sample aspect ratio
+
+ at item dar
+display aspect ratio
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Zoom-in up to 1.5 and pan at same time to some spot near center of picture:
+ at 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
+ at end example
+
+ at item
+Zoom-in up to 1.5 and pan always at center of picture:
+ at example
+zoompan=z='min(zoom+0.0015,1.5)':d=700:x='iw/2-(iw/zoom/2)':y='ih/2-(ih/zoom/2)'
+ at end example
+ at end itemize
+
+ at c man end VIDEO FILTERS
+
+ at chapter Video Sources
+ at c man begin VIDEO SOURCES
+
+Below is a description of the currently available video sources.
+
+ at section buffer
+
+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}.
+
+It accepts the following parameters:
+
+ at table @option
+
+ at item video_size
+Specify the size (width and height) of the buffered video frames. For the
+syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+
+ at item width
+The input video width.
+
+ at item height
+The input video height.
+
+ at item pix_fmt
+A string representing the pixel format of the buffered video frames.
+It may be a number corresponding to a pixel format, or a pixel format
+name.
+
+ at item time_base
+Specify the timebase assumed by the timestamps of the buffered frames.
+
+ at item frame_rate
+Specify the frame rate expected for the video stream.
+
+ at item pixel_aspect, sar
+The sample (pixel) aspect ratio of the input video.
+
+ at item sws_param
+Specify the optional parameters to be used for the scale filter which
+is automatically inserted when an input change is detected in the
+input size or format.
+ at end table
+
+For example:
+ at example
+buffer=width=320:height=240:pix_fmt=yuv410p:time_base=1/24:sar=1
+ at end example
+
+will instruct the source to accept video frames with size 320x240 and
+with format "yuv410p", assuming 1/24 as the timestamps timebase and
+square pixels (1:1 sample aspect ratio).
+Since the pixel format with name "yuv410p" corresponds to the number 6
+(check the enum AVPixelFormat definition in @file{libavutil/pixfmt.h}),
+this example corresponds to:
+ at example
+buffer=size=320x240:pixfmt=6:time_base=1/24:pixel_aspect=1/1
+ at end example
+
+Alternatively, the options can be specified as a flat string, but this
+syntax is deprecated:
+
+ at var{width}:@var{height}:@var{pix_fmt}:@var{time_base.num}:@var{time_base.den}:@var{pixel_aspect.num}:@var{pixel_aspect.den}[:@var{sws_param}]
+
+ at section cellauto
+
+Create a pattern generated by an elementary cellular automaton.
+
+The initial state of the cellular automaton can be defined through the
+ at option{filename}, and @option{pattern} options. If such options are
+not specified an initial state is created randomly.
+
+At each new frame a new row in the video is filled with the result of
+the cellular automaton next generation. The behavior when the whole
+frame is filled is defined by the @option{scroll} option.
+
+This source accepts the following options:
+
+ at table @option
+ at item filename, f
+Read the initial cellular automaton state, i.e. the starting row, from
+the specified file.
+In the file, each non-whitespace character is considered an alive
+cell, a newline will terminate the row, and further characters in the
+file will be ignored.
+
+ at item pattern, p
+Read the initial cellular automaton state, i.e. the starting row, from
+the specified string.
+
+Each non-whitespace character in the string is considered an alive
+cell, a newline will terminate the row, and further characters in the
+string will be ignored.
+
+ at item rate, r
+Set the video rate, that is the number of frames generated per second.
+Default is 25.
+
+ at item random_fill_ratio, ratio
+Set the random fill ratio for the initial cellular automaton row. It
+is a floating point number value ranging from 0 to 1, defaults to
+1/PHI.
+
+This option is ignored when a file or a pattern is specified.
+
+ at item random_seed, seed
+Set the seed for filling randomly the initial row, must be an integer
+included between 0 and UINT32_MAX. If not specified, or if explicitly
+set to -1, the filter will try to use a good random seed on a best
+effort basis.
+
+ at item rule
+Set the cellular automaton rule, it is a number ranging from 0 to 255.
+Default value is 110.
+
+ at item size, s
+Set the size of the output video. For the syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+
+If @option{filename} or @option{pattern} is specified, the size is set
+by default to the width of the specified initial state row, and the
+height is set to @var{width} * PHI.
+
+If @option{size} is set, it must contain the width of the specified
+pattern string, and the specified pattern will be centered in the
+larger row.
+
+If a filename or a pattern string is not specified, the size value
+defaults to "320x518" (used for a randomly generated initial state).
+
+ at item scroll
+If set to 1, scroll the output upward when all the rows in the output
+have been already filled. If set to 0, the new generated row will be
+written over the top row just after the bottom row is filled.
+Defaults to 1.
+
+ at item start_full, full
+If set to 1, completely fill the output with generated rows before
+outputting the first frame.
+This is the default behavior, for disabling set the value to 0.
+
+ at item stitch
+If set to 1, stitch the left and right row edges together.
+This is the default behavior, for disabling set the value to 0.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Read the initial state from @file{pattern}, and specify an output of
+size 200x400.
+ at example
+cellauto=f=pattern:s=200x400
+ at end example
+
+ at item
+Generate a random initial row with a width of 200 cells, with a fill
+ratio of 2/3:
+ at example
+cellauto=ratio=2/3:s=200x200
+ at end example
+
+ at item
+Create a pattern generated by rule 18 starting by a single alive cell
+centered on an initial row with width 100:
+ at example
+cellauto=p=@@:s=100x400:full=0:rule=18
+ at end example
+
+ at item
+Specify a more elaborated initial pattern:
+ at example
+cellauto=p='@@@@ @@ @@@@':s=100x400:full=0:rule=18
+ at end example
+
+ at end itemize
+
+ at section mandelbrot
+
+Generate a Mandelbrot set fractal, and progressively zoom towards the
+point specified with @var{start_x} and @var{start_y}.
+
+This source accepts the following options:
+
+ at table @option
+
+ at item end_pts
+Set the terminal pts value. Default value is 400.
+
+ at item end_scale
+Set the terminal scale value.
+Must be a floating point value. Default value is 0.3.
+
+ at item inner
+Set the inner coloring mode, that is the algorithm used to draw the
+Mandelbrot fractal internal region.
+
+It shall assume one of the following values:
+ at table @option
+ at item black
+Set black mode.
+ at item convergence
+Show time until convergence.
+ at item mincol
+Set color based on point closest to the origin of the iterations.
+ at item period
+Set period mode.
+ at end table
+
+Default value is @var{mincol}.
+
+ at item bailout
+Set the bailout value. Default value is 10.0.
+
+ at item maxiter
+Set the maximum of iterations performed by the rendering
+algorithm. Default value is 7189.
+
+ at item outer
+Set outer coloring mode.
+It shall assume one of following values:
+ at table @option
+ at item iteration_count
+Set iteration cound mode.
+ at item normalized_iteration_count
+set normalized iteration count mode.
+ at end table
+Default value is @var{normalized_iteration_count}.
+
+ at item rate, r
+Set frame rate, expressed as number of frames per second. Default
+value is "25".
+
+ at item size, s
+Set frame size. For the syntax of this option, check the "Video
+size" section in the ffmpeg-utils manual. Default value is "640x480".
+
+ at item start_scale
+Set the initial scale value. Default value is 3.0.
+
+ at item start_x
+Set the initial x position. Must be a floating point value between
+-100 and 100. Default value is -0.743643887037158704752191506114774.
+
+ at item start_y
+Set the initial y position. Must be a floating point value between
+-100 and 100. Default value is -0.131825904205311970493132056385139.
+ at end table
+
+ at section mptestsrc
+
+Generate various test patterns, as generated by the MPlayer test filter.
+
+The size of the generated video is fixed, and is 256x256.
+This source is useful in particular for testing encoding features.
+
+This source accepts the following options:
+
+ at table @option
+
+ at item rate, r
+Specify the frame rate of the sourced video, as the number of frames
+generated per second. It has to be a string in the format
+ at var{frame_rate_num}/@var{frame_rate_den}, an integer number, a floating point
+number or a valid video frame rate abbreviation. The default value is
+"25".
+
+ at item duration, d
+Set the duration of the sourced video. See
+ at 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.
+
+ at item test, t
+
+Set the number or the name of the test to perform. Supported tests are:
+ at table @option
+ at item dc_luma
+ at item dc_chroma
+ at item freq_luma
+ at item freq_chroma
+ at item amp_luma
+ at item amp_chroma
+ at item cbp
+ at item mv
+ at item ring1
+ at item ring2
+ at item all
+
+ at end table
+
+Default value is "all", which will cycle through the list of all tests.
+ at end table
+
+Some examples:
+ at example
+mptestsrc=t=dc_luma
+ at end example
+
+will generate a "dc_luma" test pattern.
+
+ at section frei0r_src
+
+Provide a frei0r source.
+
+To enable compilation of this filter you need to install the frei0r
+header and configure FFmpeg with @code{--enable-frei0r}.
+
+This source accepts the following parameters:
+
+ at table @option
+
+ at item size
+The size of the video to generate. For the syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+
+ at item framerate
+The framerate of the generated video. It may be a string of the form
+ at var{num}/@var{den} or a frame rate abbreviation.
+
+ at item filter_name
+The name to the frei0r source to load. For more information regarding frei0r and
+how to set the parameters, read the @ref{frei0r} section in the video filters
+documentation.
+
+ at item filter_params
+A '|'-separated list of parameters to pass to the frei0r source.
+
+ at end table
+
+For example, to generate a frei0r partik0l source with size 200x200
+and frame rate 10 which is overlaid on the overlay filter main input:
+ at example
+frei0r_src=size=200x200:framerate=10:filter_name=partik0l:filter_params=1234 [overlay]; [in][overlay] overlay
+ at end example
+
+ at section life
+
+Generate a life pattern.
+
+This source is based on a generalization of John Conway's life game.
+
+The sourced input represents a life grid, each pixel represents a cell
+which can be in one of two possible states, alive or dead. Every cell
+interacts with its eight neighbours, which are the cells that are
+horizontally, vertically, or diagonally adjacent.
+
+At each interaction the grid evolves according to the adopted rule,
+which specifies the number of neighbor alive cells which will make a
+cell stay alive or born. The @option{rule} option allows one to specify
+the rule to adopt.
+
+This source accepts the following options:
+
+ at table @option
+ at item filename, f
+Set the file from which to read the initial grid state. In the file,
+each non-whitespace character is considered an alive cell, and newline
+is used to delimit the end of each row.
+
+If this option is not specified, the initial grid is generated
+randomly.
+
+ at item rate, r
+Set the video rate, that is the number of frames generated per second.
+Default is 25.
+
+ at item random_fill_ratio, ratio
+Set the random fill ratio for the initial random grid. It is a
+floating point number value ranging from 0 to 1, defaults to 1/PHI.
+It is ignored when a file is specified.
+
+ at item random_seed, seed
+Set the seed for filling the initial random grid, must be an integer
+included between 0 and UINT32_MAX. If not specified, or if explicitly
+set to -1, the filter will try to use a good random seed on a best
+effort basis.
+
+ at item rule
+Set the life rule.
+
+A rule can be specified with a code of the kind "S at var{NS}/B at var{NB}",
+where @var{NS} and @var{NB} are sequences of numbers in the range 0-8,
+ at var{NS} specifies the number of alive neighbor cells which make a
+live cell stay alive, and @var{NB} the number of alive neighbor cells
+which make a dead cell to become alive (i.e. to "born").
+"s" and "b" can be used in place of "S" and "B", respectively.
+
+Alternatively a rule can be specified by an 18-bits integer. The 9
+high order bits are used to encode the next cell state if it is alive
+for each number of neighbor alive cells, the low order bits specify
+the rule for "borning" new cells. Higher order bits encode for an
+higher number of neighbor cells.
+For example the number 6153 = @code{(12<<9)+9} specifies a stay alive
+rule of 12 and a born rule of 9, which corresponds to "S23/B03".
+
+Default value is "S23/B3", which is the original Conway's game of life
+rule, and will keep a cell alive if it has 2 or 3 neighbor alive
+cells, and will born a new cell if there are three alive cells around
+a dead cell.
+
+ at item size, s
+Set the size of the output video. For the syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+
+If @option{filename} is specified, the size is set by default to the
+same size of the input file. If @option{size} is set, it must contain
+the size specified in the input file, and the initial grid defined in
+that file is centered in the larger resulting area.
+
+If a filename is not specified, the size value defaults to "320x240"
+(used for a randomly generated initial grid).
+
+ at item stitch
+If set to 1, stitch the left and right grid edges together, and the
+top and bottom edges also. Defaults to 1.
+
+ at item mold
+Set cell mold speed. If set, a dead cell will go from @option{death_color} to
+ at option{mold_color} with a step of @option{mold}. @option{mold} can have a
+value from 0 to 255.
+
+ at item life_color
+Set the color of living (or new born) cells.
+
+ at item death_color
+Set the color of dead cells. If @option{mold} is set, this is the first color
+used to represent a dead cell.
+
+ at item mold_color
+Set mold color, for definitely dead and moldy cells.
+
+For the syntax of these 3 color options, check the "Color" section in the
+ffmpeg-utils manual.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Read a grid from @file{pattern}, and center it on a grid of size
+300x300 pixels:
+ at example
+life=f=pattern:s=300x300
+ at end example
+
+ at item
+Generate a random grid of size 200x200, with a fill ratio of 2/3:
+ at example
+life=ratio=2/3:s=200x200
+ at end example
+
+ at item
+Specify a custom rule for evolving a randomly generated grid:
+ at example
+life=rule=S14/B34
+ at end example
+
+ at item
+Full example with slow death effect (mold) using @command{ffplay}:
+ at example
+ffplay -f lavfi life=s=300x200:mold=10:r=60:ratio=0.1:death_color=#C83232:life_color=#00ff00,scale=1200:800:flags=16
+ at end example
+ at end itemize
+
+ at anchor{allrgb}
+ at anchor{allyuv}
+ at anchor{color}
+ at anchor{haldclutsrc}
+ at anchor{nullsrc}
+ at anchor{rgbtestsrc}
+ at anchor{smptebars}
+ at anchor{smptehdbars}
+ at anchor{testsrc}
+ at section allrgb, allyuv, color, haldclutsrc, nullsrc, rgbtestsrc, smptebars, smptehdbars, testsrc
+
+The @code{allrgb} source returns frames of size 4096x4096 of all rgb colors.
+
+The @code{allyuv} source returns frames of size 4096x4096 of all yuv colors.
+
+The @code{color} source provides an uniformly colored input.
+
+The @code{haldclutsrc} source provides an identity Hald CLUT. See also
+ at ref{haldclut} filter.
+
+The @code{nullsrc} source returns unprocessed video frames. It is
+mainly useful to be employed in analysis / debugging tools, or as the
+source for filters which ignore the input data.
+
+The @code{rgbtestsrc} source generates an RGB test pattern useful for
+detecting RGB vs BGR issues. You should see a red, green and blue
+stripe from top to bottom.
+
+The @code{smptebars} source generates a color bars pattern, based on
+the SMPTE Engineering Guideline EG 1-1990.
+
+The @code{smptehdbars} source generates a color bars pattern, based on
+the SMPTE RP 219-2002.
+
+The @code{testsrc} source generates a test video pattern, showing a
+color pattern, a scrolling gradient and a timestamp. This is mainly
+intended for testing purposes.
+
+The sources accept the following parameters:
+
+ at table @option
+
+ at item color, c
+Specify the color of the source, only available in the @code{color}
+source. For the syntax of this option, check the "Color" section in the
+ffmpeg-utils manual.
+
+ at item level
+Specify the level of the Hald CLUT, only available in the @code{haldclutsrc}
+source. A level of @code{N} generates a picture of @code{N*N*N} by @code{N*N*N}
+pixels to be used as identity matrix for 3D lookup tables. Each component is
+coded on a @code{1/(N*N)} scale.
+
+ at item size, s
+Specify the size of the sourced video. For the syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+The default value is @code{320x240}.
+
+This option is not available with the @code{haldclutsrc} filter.
+
+ at item rate, r
+Specify the frame rate of the sourced video, as the number of frames
+generated per second. It has to be a string in the format
+ at var{frame_rate_num}/@var{frame_rate_den}, an integer number, a floating point
+number or a valid video frame rate abbreviation. The default value is
+"25".
+
+ at item sar
+Set the sample aspect ratio of the sourced video.
+
+ at item duration, d
+Set the duration of the sourced video. See
+ at 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.
+
+ at item decimals, n
+Set the number of decimals to show in the timestamp, only available in the
+ at code{testsrc} source.
+
+The displayed timestamp value will correspond to the original
+timestamp value multiplied by the power of 10 of the specified
+value. Default value is 0.
+ at end table
+
+For example the following:
+ at example
+testsrc=duration=5.3:size=qcif:rate=10
+ at end example
+
+will generate a video with a duration of 5.3 seconds, with size
+176x144 and a frame rate of 10 frames per second.
+
+The following graph description will generate a red source
+with an opacity of 0.2, with size "qcif" and a frame rate of 10
+frames per second.
+ at example
+color=c=red@@0.2:s=qcif:r=10
+ at end example
+
+If the input content is to be ignored, @code{nullsrc} can be used. The
+following command generates noise in the luminance plane by employing
+the @code{geq} filter:
+ at example
+nullsrc=s=256x256, geq=random(1)*255:128:128
+ at end example
+
+ at subsection Commands
+
+The @code{color} source supports the following commands:
+
+ at table @option
+ at item c, color
+Set the color of the created image. Accepts the same syntax of the
+corresponding @option{color} option.
+ at end table
+
+ at c man end VIDEO SOURCES
+
+ at chapter Video Sinks
+ at c man begin VIDEO SINKS
+
+Below is a description of the currently available video sinks.
+
+ at section buffersink
+
+Buffer video frames, and make them available to the end of the filter
+graph.
+
+This sink is mainly intended for programmatic use, in particular
+through the interface defined in @file{libavfilter/buffersink.h}
+or the options system.
+
+It accepts a pointer to an AVBufferSinkContext structure, which
+defines the incoming buffers' formats, to be passed as the opaque
+parameter to @code{avfilter_init_filter} for initialization.
+
+ at section nullsink
+
+Null video sink: do absolutely nothing with the input video. It is
+mainly useful as a template and for use in analysis / debugging
+tools.
+
+ at c man end VIDEO SINKS
+
+ at chapter Multimedia Filters
+ at c man begin MULTIMEDIA FILTERS
+
+Below is a description of the currently available multimedia filters.
+
+ at section aphasemeter
+
+Convert input audio to a video output, displaying the audio phase.
+
+The filter accepts the following options:
+
+ at table @option
+ at item rate, r
+Set the output frame rate. Default value is @code{25}.
+
+ at item size, s
+Set the video size for the output. For the syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+Default value is @code{800x400}.
+
+ at item rc
+ at item gc
+ at item bc
+Specify the red, green, blue contrast. Default values are @code{2},
+ at code{7} and @code{1}.
+Allowed range is @code{[0, 255]}.
+
+ at item mpc
+Set color which will be used for drawing median phase. If color is
+ at code{none} which is default, no median phase value will be drawn.
+ at end table
+
+The filter also exports the frame metadata @code{lavfi.aphasemeter.phase} which
+represents mean phase of current audio frame. Value is in range @code{[-1, 1]}.
+The @code{-1} means left and right channels are completely out of phase and
+ at code{1} means channels are in phase.
+
+ at section avectorscope
+
+Convert input audio to a video output, representing the audio vector
+scope.
+
+The filter is used to measure the difference between channels of stereo
+audio stream. A monoaural signal, consisting of identical left and right
+signal, results in straight vertical line. Any stereo separation is visible
+as a deviation from this line, creating a Lissajous figure.
+If the straight (or deviation from it) but horizontal line appears this
+indicates that the left and right channels are out of phase.
+
+The filter accepts the following options:
+
+ at table @option
+ at item mode, m
+Set the vectorscope mode.
+
+Available values are:
+ at table @samp
+ at item lissajous
+Lissajous rotated by 45 degrees.
+
+ at item lissajous_xy
+Same as above but not rotated.
+
+ at item polar
+Shape resembling half of circle.
+ at end table
+
+Default value is @samp{lissajous}.
+
+ at item size, s
+Set the video size for the output. For the syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+Default value is @code{400x400}.
+
+ at item rate, r
+Set the output frame rate. Default value is @code{25}.
+
+ at item rc
+ at item gc
+ at item bc
+ at item ac
+Specify the red, green, blue and alpha contrast. Default values are @code{40},
+ at code{160}, @code{80} and @code{255}.
+Allowed range is @code{[0, 255]}.
+
+ at item rf
+ at item gf
+ at item bf
+ at item af
+Specify the red, green, blue and alpha fade. Default values are @code{15},
+ at code{10}, @code{5} and @code{5}.
+Allowed range is @code{[0, 255]}.
+
+ at item zoom
+Set the zoom factor. Default value is @code{1}. Allowed range is @code{[1, 10]}.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Complete example using @command{ffplay}:
+ at example
+ffplay -f lavfi 'amovie=input.mp3, asplit [a][out1];
+ [a] avectorscope=zoom=1.3:rc=2:gc=200:bc=10:rf=1:gf=8:bf=7 [out0]'
+ at end example
+ at end itemize
+
+ at section concat
+
+Concatenate audio and video streams, joining them together one after the
+other.
+
+The filter works on segments of synchronized video and audio streams. All
+segments must have the same number of streams of each type, and that will
+also be the number of streams at output.
+
+The filter accepts the following options:
+
+ at table @option
+
+ at item n
+Set the number of segments. Default is 2.
+
+ at item v
+Set the number of output video streams, that is also the number of video
+streams in each segment. Default is 1.
+
+ at item a
+Set the number of output audio streams, that is also the number of audio
+streams in each segment. Default is 0.
+
+ at item unsafe
+Activate unsafe mode: do not fail if segments have a different format.
+
+ at end table
+
+The filter has @var{v}+ at var{a} outputs: first @var{v} video outputs, then
+ at var{a} audio outputs.
+
+There are @var{n}x(@var{v}+ at var{a}) inputs: first the inputs for the first
+segment, in the same order as the outputs, then the inputs for the second
+segment, etc.
+
+Related streams do not always have exactly the same duration, for various
+reasons including codec frame size or sloppy authoring. For that reason,
+related synchronized streams (e.g. a video and its audio track) should be
+concatenated at once. The concat filter will use the duration of the longest
+stream in each segment (except the last one), and if necessary pad shorter
+audio streams with silence.
+
+For this filter to work correctly, all segments must start at timestamp 0.
+
+All corresponding streams must have the same parameters in all segments; the
+filtering system will automatically select a common pixel format for video
+streams, and a common sample format, sample rate and channel layout for
+audio streams, but other settings, such as resolution, must be converted
+explicitly by the user.
+
+Different frame rates are acceptable but will result in variable frame rate
+at output; be sure to configure the output file to handle it.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Concatenate an opening, an episode and an ending, all in bilingual version
+(video in stream 0, audio in streams 1 and 2):
+ at example
+ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv -filter_complex \
+ '[0:0] [0:1] [0:2] [1:0] [1:1] [1:2] [2:0] [2:1] [2:2]
+ concat=n=3:v=1:a=2 [v] [a1] [a2]' \
+ -map '[v]' -map '[a1]' -map '[a2]' output.mkv
+ at end example
+
+ at item
+Concatenate two parts, handling audio and video separately, using the
+(a)movie sources, and adjusting the resolution:
+ at example
+movie=part1.mp4, scale=512:288 [v1] ; amovie=part1.mp4 [a1] ;
+movie=part2.mp4, scale=512:288 [v2] ; amovie=part2.mp4 [a2] ;
+[v1] [v2] concat [outv] ; [a1] [a2] concat=v=0:a=1 [outa]
+ at end example
+Note that a desync will happen at the stitch if the audio and video streams
+do not have exactly the same duration in the first file.
+
+ at end itemize
+
+ at anchor{ebur128}
+ at section ebur128
+
+EBU R128 scanner filter. This filter takes an audio stream as input and outputs
+it unchanged. By default, it logs a message at a frequency of 10Hz with the
+Momentary loudness (identified by @code{M}), Short-term loudness (@code{S}),
+Integrated loudness (@code{I}) and Loudness Range (@code{LRA}).
+
+The filter also has a video output (see the @var{video} option) with a real
+time graph to observe the loudness evolution. The graphic contains the logged
+message mentioned above, so it is not printed anymore when this option is set,
+unless the verbose logging is set. The main graphing area contains the
+short-term loudness (3 seconds of analysis), and the gauge on the right is for
+the momentary loudness (400 milliseconds).
+
+More information about the Loudness Recommendation EBU R128 on
+ at url{http://tech.ebu.ch/loudness}.
+
+The filter accepts the following options:
+
+ at table @option
+
+ at item video
+Activate the video output. The audio stream is passed unchanged whether this
+option is set or no. The video stream will be the first output stream if
+activated. Default is @code{0}.
+
+ at item size
+Set the video size. This option is for video only. For the syntax of this
+option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+Default and minimum resolution is @code{640x480}.
+
+ at item meter
+Set the EBU scale meter. Default is @code{9}. Common values are @code{9} and
+ at code{18}, respectively for EBU scale meter +9 and EBU scale meter +18. Any
+other integer value between this range is allowed.
+
+ at item metadata
+Set metadata injection. If set to @code{1}, the audio input will be segmented
+into 100ms output frames, each of them containing various loudness information
+in metadata. All the metadata keys are prefixed with @code{lavfi.r128.}.
+
+Default is @code{0}.
+
+ at item framelog
+Force the frame logging level.
+
+Available values are:
+ at table @samp
+ at item info
+information logging level
+ at item verbose
+verbose logging level
+ at end table
+
+By default, the logging level is set to @var{info}. If the @option{video} or
+the @option{metadata} options are set, it switches to @var{verbose}.
+
+ at item peak
+Set peak mode(s).
+
+Available modes can be cumulated (the option is a @code{flag} type). Possible
+values are:
+ at table @samp
+ at item none
+Disable any peak mode (default).
+ at item sample
+Enable sample-peak mode.
+
+Simple peak mode looking for the higher sample value. It logs a message
+for sample-peak (identified by @code{SPK}).
+ at item true
+Enable true-peak mode.
+
+If enabled, the peak lookup is done on an over-sampled version of the input
+stream for better peak accuracy. It logs a message for true-peak.
+(identified by @code{TPK}) and true-peak per frame (identified by @code{FTPK}).
+This mode requires a build with @code{libswresample}.
+ at end table
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Real-time graph using @command{ffplay}, with a EBU scale meter +18:
+ at example
+ffplay -f lavfi -i "amovie=input.mp3,ebur128=video=1:meter=18 [out0][out1]"
+ at end example
+
+ at item
+Run an analysis with @command{ffmpeg}:
+ at example
+ffmpeg -nostats -i input.mp3 -filter_complex ebur128 -f null -
+ at end example
+ at end itemize
+
+ at section interleave, ainterleave
+
+Temporally interleave frames from several inputs.
+
+ at code{interleave} works with video inputs, @code{ainterleave} with audio.
+
+These filters read frames from several inputs and send the oldest
+queued frame to the output.
+
+Input streams must have a well defined, monotonically increasing frame
+timestamp values.
+
+In order to submit one frame to output, these filters need to enqueue
+at least one frame for each input, so they cannot work in case one
+input is not yet terminated and will not receive incoming frames.
+
+For example consider the case when one input is a @code{select} filter
+which always drop input frames. The @code{interleave} filter will keep
+reading from that input, but it will never be able to send new frames
+to output until the input will send an end-of-stream signal.
+
+Also, depending on inputs synchronization, the filters will drop
+frames in case one input receives more frames than the other ones, and
+the queue is already filled.
+
+These filters accept the following options:
+
+ at table @option
+ at item nb_inputs, n
+Set the number of different inputs, it is 2 by default.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Interleave frames belonging to different streams using @command{ffmpeg}:
+ at example
+ffmpeg -i bambi.avi -i pr0n.mkv -filter_complex "[0:v][1:v] interleave" out.avi
+ at end example
+
+ at item
+Add flickering blur effect:
+ at example
+select='if(gt(random(0), 0.2), 1, 2)':n=2 [tmp], boxblur=2:2, [tmp] interleave
+ at end example
+ at end itemize
+
+ at section perms, aperms
+
+Set read/write permissions for the output frames.
+
+These filters are mainly aimed at developers to test direct path in the
+following filter in the filtergraph.
+
+The filters accept the following options:
+
+ at table @option
+ at item mode
+Select the permissions mode.
+
+It accepts the following values:
+ at table @samp
+ at item none
+Do nothing. This is the default.
+ at item ro
+Set all the output frames read-only.
+ at item rw
+Set all the output frames directly writable.
+ at item toggle
+Make the frame read-only if writable, and writable if read-only.
+ at item random
+Set each output frame read-only or writable randomly.
+ at end table
+
+ at item seed
+Set the seed for the @var{random} mode, must be an integer included between
+ at code{0} and @code{UINT32_MAX}. If not specified, or if explicitly set to
+ at code{-1}, the filter will try to use a good random seed on a best effort
+basis.
+ at end table
+
+Note: in case of auto-inserted filter between the permission filter and the
+following one, the permission might not be received as expected in that
+following filter. Inserting a @ref{format} or @ref{aformat} filter before the
+perms/aperms filter can avoid this problem.
+
+ at section select, aselect
+
+Select frames to pass in output.
+
+This filter accepts the following options:
+
+ at table @option
+
+ at item expr, e
+Set expression, which is evaluated for each input frame.
+
+If the expression is evaluated to zero, the frame is discarded.
+
+If the evaluation result is negative or NaN, the frame is sent to the
+first output; otherwise it is sent to the output with index
+ at code{ceil(val)-1}, assuming that the input index starts from 0.
+
+For example a value of @code{1.2} corresponds to the output with index
+ at code{ceil(1.2)-1 = 2-1 = 1}, that is the second output.
+
+ at item outputs, n
+Set the number of outputs. The output to which to send the selected
+frame is based on the result of the evaluation. Default value is 1.
+ at end table
+
+The expression can contain the following constants:
+
+ at table @option
+ at item n
+The (sequential) number of the filtered frame, starting from 0.
+
+ at item selected_n
+The (sequential) number of the selected frame, starting from 0.
+
+ at item prev_selected_n
+The sequential number of the last selected frame. It's NAN if undefined.
+
+ at item TB
+The timebase of the input timestamps.
+
+ at item pts
+The PTS (Presentation TimeStamp) of the filtered video frame,
+expressed in @var{TB} units. It's NAN if undefined.
+
+ at item t
+The PTS of the filtered video frame,
+expressed in seconds. It's NAN if undefined.
+
+ at item prev_pts
+The PTS of the previously filtered video frame. It's NAN if undefined.
+
+ at item prev_selected_pts
+The PTS of the last previously filtered video frame. It's NAN if undefined.
+
+ at item prev_selected_t
+The PTS of the last previously selected video frame. It's NAN if undefined.
+
+ at item start_pts
+The PTS of the first video frame in the video. It's NAN if undefined.
+
+ at item start_t
+The time of the first video frame in the video. It's NAN if undefined.
+
+ at item pict_type @emph{(video only)}
+The type of the filtered frame. It can assume one of the following
+values:
+ at table @option
+ at item I
+ at item P
+ at item B
+ at item S
+ at item SI
+ at item SP
+ at item BI
+ at end table
+
+ at item interlace_type @emph{(video only)}
+The frame interlace type. It can assume one of the following values:
+ at table @option
+ at item PROGRESSIVE
+The frame is progressive (not interlaced).
+ at item TOPFIRST
+The frame is top-field-first.
+ at item BOTTOMFIRST
+The frame is bottom-field-first.
+ at end table
+
+ at item consumed_sample_n @emph{(audio only)}
+the number of selected samples before the current frame
+
+ at item samples_n @emph{(audio only)}
+the number of samples in the current frame
+
+ at item sample_rate @emph{(audio only)}
+the input sample rate
+
+ at item key
+This is 1 if the filtered frame is a key-frame, 0 otherwise.
+
+ at item pos
+the position in the file of the filtered frame, -1 if the information
+is not available (e.g. for synthetic video)
+
+ at item scene @emph{(video only)}
+value between 0 and 1 to indicate a new scene; a low value reflects a low
+probability for the current frame to introduce a new scene, while a higher
+value means the current frame is more likely to be one (see the example below)
+
+ at end table
+
+The default value of the select expression is "1".
+
+ at subsection Examples
+
+ at itemize
+ at item
+Select all frames in input:
+ at example
+select
+ at end example
+
+The example above is the same as:
+ at example
+select=1
+ at end example
+
+ at item
+Skip all frames:
+ at example
+select=0
+ at end example
+
+ at item
+Select only I-frames:
+ at example
+select='eq(pict_type\,I)'
+ at end example
+
+ at item
+Select one frame every 100:
+ at example
+select='not(mod(n\,100))'
+ at end example
+
+ at item
+Select only frames contained in the 10-20 time interval:
+ at example
+select=between(t\,10\,20)
+ at end example
+
+ at item
+Select only I frames contained in the 10-20 time interval:
+ at example
+select=between(t\,10\,20)*eq(pict_type\,I)
+ at end example
+
+ at item
+Select frames with a minimum distance of 10 seconds:
+ at example
+select='isnan(prev_selected_t)+gte(t-prev_selected_t\,10)'
+ at end example
+
+ at item
+Use aselect to select only audio frames with samples number > 100:
+ at example
+aselect='gt(samples_n\,100)'
+ at end example
+
+ at item
+Create a mosaic of the first scenes:
+ at example
+ffmpeg -i video.avi -vf select='gt(scene\,0.4)',scale=160:120,tile -frames:v 1 preview.png
+ at end example
+
+Comparing @var{scene} against a value between 0.3 and 0.5 is generally a sane
+choice.
+
+ at item
+Send even and odd frames to separate outputs, and compose them:
+ at example
+select=n=2:e='mod(n, 2)+1' [odd][even]; [odd] pad=h=2*ih [tmp]; [tmp][even] overlay=y=h
+ at end example
+ at end itemize
+
+ at section sendcmd, asendcmd
+
+Send commands to filters in the filtergraph.
+
+These filters read commands to be sent to other filters in the
+filtergraph.
+
+ at code{sendcmd} must be inserted between two video filters,
+ at code{asendcmd} must be inserted between two audio filters, but apart
+from that they act the same way.
+
+The specification of commands can be provided in the filter arguments
+with the @var{commands} option, or in a file specified by the
+ at var{filename} option.
+
+These filters accept the following options:
+ at table @option
+ at item commands, c
+Set the commands to be read and sent to the other filters.
+ at item filename, f
+Set the filename of the commands to be read and sent to the other
+filters.
+ at end table
+
+ at subsection Commands syntax
+
+A commands description consists of a sequence of interval
+specifications, comprising a list of commands to be executed when a
+particular event related to that interval occurs. The occurring event
+is typically the current frame time entering or leaving a given time
+interval.
+
+An interval is specified by the following syntax:
+ at example
+ at var{START}[- at var{END}] @var{COMMANDS};
+ at end example
+
+The time interval is specified by the @var{START} and @var{END} times.
+ at var{END} is optional and defaults to the maximum time.
+
+The current frame time is considered within the specified interval if
+it is included in the interval [@var{START}, @var{END}), that is when
+the time is greater or equal to @var{START} and is lesser than
+ at var{END}.
+
+ at var{COMMANDS} consists of a sequence of one or more command
+specifications, separated by ",", relating to that interval. The
+syntax of a command specification is given by:
+ at example
+[@var{FLAGS}] @var{TARGET} @var{COMMAND} @var{ARG}
+ at end example
+
+ at var{FLAGS} is optional and specifies the type of events relating to
+the time interval which enable sending the specified command, and must
+be a non-null sequence of identifier flags separated by "+" or "|" and
+enclosed between "[" and "]".
+
+The following flags are recognized:
+ at table @option
+ at item enter
+The command is sent when the current frame timestamp enters the
+specified interval. In other words, the command is sent when the
+previous frame timestamp was not in the given interval, and the
+current is.
+
+ at item leave
+The command is sent when the current frame timestamp leaves the
+specified interval. In other words, the command is sent when the
+previous frame timestamp was in the given interval, and the
+current is not.
+ at end table
+
+If @var{FLAGS} is not specified, a default value of @code{[enter]} is
+assumed.
+
+ at var{TARGET} specifies the target of the command, usually the name of
+the filter class or a specific filter instance name.
+
+ at var{COMMAND} specifies the name of the command for the target filter.
+
+ at var{ARG} is optional and specifies the optional list of argument for
+the given @var{COMMAND}.
+
+Between one interval specification and another, whitespaces, or
+sequences of characters starting with @code{#} until the end of line,
+are ignored and can be used to annotate comments.
+
+A simplified BNF description of the commands specification syntax
+follows:
+ at example
+ at var{COMMAND_FLAG} ::= "enter" | "leave"
+ at var{COMMAND_FLAGS} ::= @var{COMMAND_FLAG} [(+|"|")@var{COMMAND_FLAG}]
+ at var{COMMAND} ::= ["[" @var{COMMAND_FLAGS} "]"] @var{TARGET} @var{COMMAND} [@var{ARG}]
+ at var{COMMANDS} ::= @var{COMMAND} [, at var{COMMANDS}]
+ at var{INTERVAL} ::= @var{START}[- at var{END}] @var{COMMANDS}
+ at var{INTERVALS} ::= @var{INTERVAL}[;@var{INTERVALS}]
+ at end example
+
+ at subsection Examples
+
+ at itemize
+ at item
+Specify audio tempo change at second 4:
+ at example
+asendcmd=c='4.0 atempo tempo 1.5',atempo
+ at end example
+
+ at item
+Specify a list of drawtext and hue commands in a file.
+ at example
+# show text in the interval 5-10
+5.0-10.0 [enter] drawtext reinit 'fontfile=FreeSerif.ttf:text=hello world',
+ [leave] drawtext reinit 'fontfile=FreeSerif.ttf:text=';
+
+# desaturate the image in the interval 15-20
+15.0-20.0 [enter] hue s 0,
+ [enter] drawtext reinit 'fontfile=FreeSerif.ttf:text=nocolor',
+ [leave] hue s 1,
+ [leave] drawtext reinit 'fontfile=FreeSerif.ttf:text=color';
+
+# apply an exponential saturation fade-out effect, starting from time 25
+25 [enter] hue s exp(25-t)
+ at end example
+
+A filtergraph allowing to read and process the above command list
+stored in a file @file{test.cmd}, can be specified with:
+ at example
+sendcmd=f=test.cmd,drawtext=fontfile=FreeSerif.ttf:text='',hue
+ at end example
+ at end itemize
+
+ at anchor{setpts}
+ at section setpts, asetpts
+
+Change the PTS (presentation timestamp) of the input frames.
+
+ at code{setpts} works on video frames, @code{asetpts} on audio frames.
+
+This filter accepts the following options:
+
+ at table @option
+
+ at item expr
+The expression which is evaluated for each frame to construct its timestamp.
+
+ at end table
+
+The expression is evaluated through the eval API and can contain the following
+constants:
+
+ at table @option
+ at item FRAME_RATE
+frame rate, only defined for constant frame-rate video
+
+ at item PTS
+The presentation timestamp in input
+
+ at item N
+The count of the input frame for video or the number of consumed samples,
+not including the current frame for audio, starting from 0.
+
+ at item NB_CONSUMED_SAMPLES
+The number of consumed samples, not including the current frame (only
+audio)
+
+ at item NB_SAMPLES, S
+The number of samples in the current frame (only audio)
+
+ at item SAMPLE_RATE, SR
+The audio sample rate.
+
+ at item STARTPTS
+The PTS of the first frame.
+
+ at item STARTT
+the time in seconds of the first frame
+
+ at item INTERLACED
+State whether the current frame is interlaced.
+
+ at item T
+the time in seconds of the current frame
+
+ at item POS
+original position in the file of the frame, or undefined if undefined
+for the current frame
+
+ at item PREV_INPTS
+The previous input PTS.
+
+ at item PREV_INT
+previous input time in seconds
+
+ at item PREV_OUTPTS
+The previous output PTS.
+
+ at item PREV_OUTT
+previous output time in seconds
+
+ at item RTCTIME
+The wallclock (RTC) time in microseconds. This is deprecated, use time(0)
+instead.
+
+ at item RTCSTART
+The wallclock (RTC) time at the start of the movie in microseconds.
+
+ at item TB
+The timebase of the input timestamps.
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Start counting PTS from zero
+ at example
+setpts=PTS-STARTPTS
+ at end example
+
+ at item
+Apply fast motion effect:
+ at example
+setpts=0.5*PTS
+ at end example
+
+ at item
+Apply slow motion effect:
+ at example
+setpts=2.0*PTS
+ at end example
+
+ at item
+Set fixed rate of 25 frames per second:
+ at example
+setpts=N/(25*TB)
+ at end example
+
+ at item
+Set fixed rate 25 fps with some jitter:
+ at example
+setpts='1/(25*TB) * (N + 0.05 * sin(N*2*PI/25))'
+ at end example
+
+ at item
+Apply an offset of 10 seconds to the input PTS:
+ at example
+setpts=PTS+10/TB
+ at end example
+
+ at item
+Generate timestamps from a "live source" and rebase onto the current timebase:
+ at example
+setpts='(RTCTIME - RTCSTART) / (TB * 1000000)'
+ at end example
+
+ at item
+Generate timestamps by counting samples:
+ at example
+asetpts=N/SR/TB
+ at end example
+
+ at end itemize
+
+ at section settb, asettb
+
+Set the timebase to use for the output frames timestamps.
+It is mainly useful for testing timebase configuration.
+
+It accepts the following parameters:
+
+ at table @option
+
+ at item expr, tb
+The expression which is evaluated into the output timebase.
+
+ at end table
+
+The value for @option{tb} is an arithmetic expression representing a
+rational. The expression can contain the constants "AVTB" (the default
+timebase), "intb" (the input timebase) and "sr" (the sample rate,
+audio only). Default value is "intb".
+
+ at subsection Examples
+
+ at itemize
+ at item
+Set the timebase to 1/25:
+ at example
+settb=expr=1/25
+ at end example
+
+ at item
+Set the timebase to 1/10:
+ at example
+settb=expr=0.1
+ at end example
+
+ at item
+Set the timebase to 1001/1000:
+ at example
+settb=1+0.001
+ at end example
+
+ at item
+Set the timebase to 2*intb:
+ at example
+settb=2*intb
+ at end example
+
+ at item
+Set the default timebase value:
+ at example
+settb=AVTB
+ at end example
+ at end itemize
+
+ at section showcqt
+Convert input audio to a video output representing
+frequency spectrum logarithmically (using constant Q transform with
+Brown-Puckette algorithm), with musical tone scale, from E0 to D#10 (10 octaves).
+
+The filter accepts the following options:
+
+ at table @option
+ at item volume
+Specify transform volume (multiplier) expression. The expression can contain
+variables:
+ at table @option
+ at item frequency, freq, f
+the frequency where transform is evaluated
+ at item timeclamp, tc
+value of timeclamp option
+ at end table
+and functions:
+ at table @option
+ at item a_weighting(f)
+A-weighting of equal loudness
+ at item b_weighting(f)
+B-weighting of equal loudness
+ at item c_weighting(f)
+C-weighting of equal loudness
+ at end table
+Default value is @code{16}.
+
+ at item tlength
+Specify transform length expression. The expression can contain variables:
+ at table @option
+ at item frequency, freq, f
+the frequency where transform is evaluated
+ at item timeclamp, tc
+value of timeclamp option
+ at end table
+Default value is @code{384/f*tc/(384/f+tc)}.
+
+ at item timeclamp
+Specify the transform timeclamp. At low frequency, there is trade-off between
+accuracy in time domain and frequency domain. If timeclamp is lower,
+event in time domain is represented more accurately (such as fast bass drum),
+otherwise event in frequency domain is represented more accurately
+(such as bass guitar). Acceptable value is [0.1, 1.0]. Default value is @code{0.17}.
+
+ at item coeffclamp
+Specify the transform coeffclamp. If coeffclamp is lower, transform is
+more accurate, otherwise transform is faster. Acceptable value is [0.1, 10.0].
+Default value is @code{1.0}.
+
+ at item gamma
+Specify gamma. Lower gamma makes the spectrum more contrast, higher gamma
+makes the spectrum having more range. Acceptable value is [1.0, 7.0].
+Default value is @code{3.0}.
+
+ at item gamma2
+Specify gamma of bargraph. Acceptable value is [1.0, 7.0].
+Default value is @code{1.0}.
+
+ at item fontfile
+Specify font file for use with freetype. If not specified, use embedded font.
+
+ at item fontcolor
+Specify font color expression. This is arithmetic expression that should return
+integer value 0xRRGGBB. The expression can contain variables:
+ at table @option
+ at item frequency, freq, f
+the frequency where transform is evaluated
+ at item timeclamp, tc
+value of timeclamp option
+ at end table
+and functions:
+ at table @option
+ at item midi(f)
+midi number of frequency f, some midi numbers: E0(16), C1(24), C2(36), A4(69)
+ at item r(x), g(x), b(x)
+red, green, and blue value of intensity x
+ at end table
+Default value is @code{st(0, (midi(f)-59.5)/12);
+st(1, if(between(ld(0),0,1), 0.5-0.5*cos(2*PI*ld(0)), 0));
+r(1-ld(1)) + b(ld(1))}
+
+ at item fullhd
+If set to 1 (the default), the video size is 1920x1080 (full HD),
+if set to 0, the video size is 960x540. Use this option to make CPU usage lower.
+
+ at item fps
+Specify video fps. Default value is @code{25}.
+
+ at item count
+Specify number of transform per frame, so there are fps*count transforms
+per second. Note that audio data rate must be divisible by fps*count.
+Default value is @code{6}.
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Playing audio while showing the spectrum:
+ at example
+ffplay -f lavfi 'amovie=a.mp3, asplit [a][out1]; [a] showcqt [out0]'
+ at end example
+
+ at item
+Same as above, but with frame rate 30 fps:
+ at example
+ffplay -f lavfi 'amovie=a.mp3, asplit [a][out1]; [a] showcqt=fps=30:count=5 [out0]'
+ at end example
+
+ at item
+Playing at 960x540 and lower CPU usage:
+ at example
+ffplay -f lavfi 'amovie=a.mp3, asplit [a][out1]; [a] showcqt=fullhd=0:count=3 [out0]'
+ at end example
+
+ at item
+A1 and its harmonics: A1, A2, (near)E3, A3:
+ at example
+ffplay -f lavfi 'aevalsrc=0.1*sin(2*PI*55*t)+0.1*sin(4*PI*55*t)+0.1*sin(6*PI*55*t)+0.1*sin(8*PI*55*t),
+ asplit[a][out1]; [a] showcqt [out0]'
+ at end example
+
+ at item
+Same as above, but with more accuracy in frequency domain (and slower):
+ at example
+ffplay -f lavfi 'aevalsrc=0.1*sin(2*PI*55*t)+0.1*sin(4*PI*55*t)+0.1*sin(6*PI*55*t)+0.1*sin(8*PI*55*t),
+ asplit[a][out1]; [a] showcqt=timeclamp=0.5 [out0]'
+ at end example
+
+ at item
+B-weighting of equal loudness
+ at example
+volume=16*b_weighting(f)
+ at end example
+
+ at item
+Lower Q factor
+ at example
+tlength=100/f*tc/(100/f+tc)
+ at end example
+
+ at item
+Custom fontcolor, C-note is colored green, others are colored blue
+ at example
+fontcolor='if(mod(floor(midi(f)+0.5),12), 0x0000FF, g(1))'
+ at end example
+
+ at item
+Custom gamma, now spectrum is linear to the amplitude.
+ at example
+gamma=2:gamma2=2
+ at end example
+
+ at end itemize
+
+ at section showfreqs
+
+Convert input audio to video output representing the audio power spectrum.
+Audio amplitude is on Y-axis while frequency is on X-axis.
+
+The filter accepts the following options:
+
+ at table @option
+ at item size, s
+Specify size of video. For the syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+Default is @code{1024x512}.
+
+ at item mode
+Set display mode.
+This set how each frequency bin will be represented.
+
+It accepts the following values:
+ at table @samp
+ at item line
+ at item bar
+ at item dot
+ at end table
+Default is @code{bar}.
+
+ at item ascale
+Set amplitude scale.
+
+It accepts the following values:
+ at table @samp
+ at item lin
+Linear scale.
+
+ at item sqrt
+Square root scale.
+
+ at item cbrt
+Cubic root scale.
+
+ at item log
+Logarithmic scale.
+ at end table
+Default is @code{log}.
+
+ at item fscale
+Set frequency scale.
+
+It accepts the following values:
+ at table @samp
+ at item lin
+Linear scale.
+
+ at item log
+Logarithmic scale.
+
+ at item rlog
+Reverse logarithmic scale.
+ at end table
+Default is @code{lin}.
+
+ at item win_size
+Set window size.
+
+It accepts the following values:
+ at table @samp
+ at item w16
+ at item w32
+ at item w64
+ at item w128
+ at item w256
+ at item w512
+ at item w1024
+ at item w2048
+ at item w4096
+ at item w8192
+ at item w16384
+ at item w32768
+ at item w65536
+ at end table
+Default is @code{w2048}
+
+ at item win_func
+Set windowing function.
+
+It accepts the following values:
+ at table @samp
+ at item rect
+ at item bartlett
+ at item hanning
+ at item hamming
+ at item blackman
+ at item welch
+ at item flattop
+ at item bharris
+ at item bnuttall
+ at item bhann
+ at item sine
+ at item nuttall
+ at end table
+Default is @code{hanning}.
+
+ at item overlap
+Set window overlap. In range @code{[0, 1]}. Default is @code{1},
+which means optimal overlap for selected window function will be picked.
+
+ at item averaging
+Set time averaging. Setting this to 0 will display current maximal peaks.
+Default is @code{1}, which means time averaging is disabled.
+
+ at item color
+Specify list of colors separated by space or by '|' which will be used to
+draw channel frequencies. Unrecognized or missing colors will be replaced
+by white color.
+ at end table
+
+ at section showspectrum
+
+Convert input audio to a video output, representing the audio frequency
+spectrum.
+
+The filter accepts the following options:
+
+ at table @option
+ at item size, s
+Specify the video size for the output. For the syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+Default value is @code{640x512}.
+
+ at item slide
+Specify how the spectrum should slide along the window.
+
+It accepts the following values:
+ at table @samp
+ at item replace
+the samples start again on the left when they reach the right
+ at item scroll
+the samples scroll from right to left
+ at item fullframe
+frames are only produced when the samples reach the right
+ at end table
+
+Default value is @code{replace}.
+
+ at item mode
+Specify display mode.
+
+It accepts the following values:
+ at table @samp
+ at item combined
+all channels are displayed in the same row
+ at item separate
+all channels are displayed in separate rows
+ at end table
+
+Default value is @samp{combined}.
+
+ at item color
+Specify display color mode.
+
+It accepts the following values:
+ at table @samp
+ at item channel
+each channel is displayed in a separate color
+ at item intensity
+each channel is is displayed using the same color scheme
+ at end table
+
+Default value is @samp{channel}.
+
+ at item scale
+Specify scale used for calculating intensity color values.
+
+It accepts the following values:
+ at table @samp
+ at item lin
+linear
+ at item sqrt
+square root, default
+ at item cbrt
+cubic root
+ at item log
+logarithmic
+ at end table
+
+Default value is @samp{sqrt}.
+
+ at item saturation
+Set saturation modifier for displayed colors. Negative values provide
+alternative color scheme. @code{0} is no saturation at all.
+Saturation must be in [-10.0, 10.0] range.
+Default value is @code{1}.
+
+ at item win_func
+Set window function.
+
+It accepts the following values:
+ at table @samp
+ at item none
+No samples pre-processing (do not expect this to be faster)
+ at item hann
+Hann window
+ at item hamming
+Hamming window
+ at item blackman
+Blackman window
+ at end table
+
+Default value is @code{hann}.
+ at end table
+
+The usage is very similar to the showwaves filter; see the examples in that
+section.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Large window with logarithmic color scaling:
+ at example
+showspectrum=s=1280x480:scale=log
+ at end example
+
+ at item
+Complete example for a colored and sliding spectrum per channel using @command{ffplay}:
+ at example
+ffplay -f lavfi 'amovie=input.mp3, asplit [a][out1];
+ [a] showspectrum=mode=separate:color=intensity:slide=1:scale=cbrt [out0]'
+ at end example
+ at end itemize
+
+ at section showvolume
+
+Convert input audio volume to a video output.
+
+The filter accepts the following options:
+
+ at table @option
+ at item rate, r
+Set video rate.
+
+ at item b
+Set border width, allowed range is [0, 5]. Default is 1.
+
+ at item w
+Set channel width, allowed range is [40, 1080]. Default is 400.
+
+ at item h
+Set channel height, allowed range is [1, 100]. Default is 20.
+
+ at item f
+Set fade, allowed range is [1, 255]. Default is 20.
+
+ at item c
+Set volume color expression.
+
+The expression can use the following variables:
+
+ at table @option
+ at item VOLUME
+Current max volume of channel in dB.
+
+ at item CHANNEL
+Current channel number, starting from 0.
+ at end table
+
+ at item t
+If set, displays channel names. Default is enabled.
+ at end table
+
+ at section showwaves
+
+Convert input audio to a video output, representing the samples waves.
+
+The filter accepts the following options:
+
+ at table @option
+ at item size, s
+Specify the video size for the output. For the syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+Default value is @code{600x240}.
+
+ at item mode
+Set display mode.
+
+Available values are:
+ at table @samp
+ at item point
+Draw a point for each sample.
+
+ at item line
+Draw a vertical line for each sample.
+
+ at item p2p
+Draw a point for each sample and a line between them.
+
+ at item cline
+Draw a centered vertical line for each sample.
+ at end table
+
+Default value is @code{point}.
+
+ at item n
+Set the number of samples which are printed on the same column. A
+larger value will decrease the frame rate. Must be a positive
+integer. This option can be set only if the value for @var{rate}
+is not explicitly specified.
+
+ at item rate, r
+Set the (approximate) output frame rate. This is done by setting the
+option @var{n}. Default value is "25".
+
+ at item split_channels
+Set if channels should be drawn separately or overlap. Default value is 0.
+
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Output the input file audio and the corresponding video representation
+at the same time:
+ at example
+amovie=a.mp3,asplit[out0],showwaves[out1]
+ at end example
+
+ at item
+Create a synthetic signal and show it with showwaves, forcing a
+frame rate of 30 frames per second:
+ at example
+aevalsrc=sin(1*2*PI*t)*sin(880*2*PI*t):cos(2*PI*200*t),asplit[out0],showwaves=r=30[out1]
+ at end example
+ at end itemize
+
+ at section showwavespic
+
+Convert input audio to a single video frame, representing the samples waves.
+
+The filter accepts the following options:
+
+ at table @option
+ at item size, s
+Specify the video size for the output. For the syntax of this option, check the
+ at ref{video size syntax,,"Video size" section in the ffmpeg-utils manual,ffmpeg-utils}.
+Default value is @code{600x240}.
+
+ at item split_channels
+Set if channels should be drawn separately or overlap. Default value is 0.
+ at end table
+
+ at subsection Examples
+
+ at itemize
+ at item
+Extract a channel split representation of the wave form of a whole audio track
+in a 1024x800 picture using @command{ffmpeg}:
+ at example
+ffmpeg -i audio.flac -lavfi showwavespic=split_channels=1:s=1024x800 waveform.png
+ at end example
+ at end itemize
+
+ at section split, asplit
+
+Split input into several identical outputs.
+
+ at code{asplit} works with audio input, @code{split} with video.
+
+The filter accepts a single parameter which specifies the number of outputs. If
+unspecified, it defaults to 2.
+
+ at subsection Examples
+
+ at itemize
+ at item
+Create two separate outputs from the same input:
+ at example
+[in] split [out0][out1]
+ at end example
+
+ at item
+To create 3 or more outputs, you need to specify the number of
+outputs, like in:
+ at example
+[in] asplit=3 [out0][out1][out2]
+ at end example
+
+ at item
+Create two separate outputs from the same input, one cropped and
+one padded:
+ at example
+[in] split [splitout1][splitout2];
+[splitout1] crop=100:100:0:0 [cropout];
+[splitout2] pad=200:200:100:100 [padout];
+ at end example
+
+ at item
+Create 5 copies of the input audio with @command{ffmpeg}:
+ at example
+ffmpeg -i INPUT -filter_complex asplit=5 OUTPUT
+ at end example
+ at end itemize
+
+ at section zmq, azmq
+
+Receive commands sent through a libzmq client, and forward them to
+filters in the filtergraph.
+
+ at code{zmq} and @code{azmq} work as a pass-through filters. @code{zmq}
+must be inserted between two video filters, @code{azmq} between two
+audio filters.
+
+To enable these filters you need to install the libzmq library and
+headers and configure FFmpeg with @code{--enable-libzmq}.
+
+For more information about libzmq see:
+ at url{http://www.zeromq.org/}
+
+The @code{zmq} and @code{azmq} filters work as a libzmq server, which
+receives messages sent through a network interface defined by the
+ at option{bind_address} option.
+
+The received message must be in the form:
+ at example
+ at var{TARGET} @var{COMMAND} [@var{ARG}]
+ at end example
+
+ at var{TARGET} specifies the target of the command, usually the name of
+the filter class or a specific filter instance name.
+
+ at var{COMMAND} specifies the name of the command for the target filter.
+
+ at var{ARG} is optional and specifies the optional argument list for the
+given @var{COMMAND}.
+
+Upon reception, the message is processed and the corresponding command
+is injected into the filtergraph. Depending on the result, the filter
+will send a reply to the client, adopting the format:
+ at example
+ at var{ERROR_CODE} @var{ERROR_REASON}
+ at var{MESSAGE}
+ at end example
+
+ at var{MESSAGE} is optional.
+
+ at subsection Examples
+
+Look at @file{tools/zmqsend} for an example of a zmq client which can
+be used to send commands processed by these filters.
+
+Consider the following filtergraph generated by @command{ffplay}
+ at example
+ffplay -dumpgraph 1 -f lavfi "
+color=s=100x100:c=red [l];
+color=s=100x100:c=blue [r];
+nullsrc=s=200x100, zmq [bg];
+[bg][l] overlay [bg+l];
+[bg+l][r] overlay=x=100 "
+ at end example
+
+To change the color of the left side of the video, the following
+command can be used:
+ at example
+echo Parsed_color_0 c yellow | tools/zmqsend
+ at end example
+
+To change the right side:
+ at example
+echo Parsed_color_1 c pink | tools/zmqsend
+ at end example
+
+ at c man end MULTIMEDIA FILTERS
+
+ at chapter Multimedia Sources
+ at c man begin MULTIMEDIA SOURCES
+
+Below is a description of the currently available multimedia sources.
+
+ at section amovie
+
+This is the same as @ref{movie} source, except it selects an audio
+stream by default.
+
+ at anchor{movie}
+ at section movie
+
+Read audio and/or video stream(s) from a movie container.
+
+It accepts the following parameters:
+
+ at table @option
+ at item filename
+The name of the resource to read (not necessarily a file; it can also be a
+device or a stream accessed through some protocol).
+
+ at item format_name, f
+Specifies the format assumed for the movie to read, and can be either
+the name of a container or an input device. If not specified, the
+format is guessed from @var{movie_name} or by probing.
+
+ at item seek_point, sp
+Specifies the seek point in seconds. The frames will be output
+starting from this seek point. The parameter is evaluated with
+ at code{av_strtod}, so the numerical value may be suffixed by an IS
+postfix. The default value is "0".
+
+ at item streams, s
+Specifies the streams to read. Several streams can be specified,
+separated by "+". The source will then have as many outputs, in the
+same order. The syntax is explained in the ``Stream specifiers''
+section in the ffmpeg manual. Two special names, "dv" and "da" specify
+respectively the default (best suited) video and audio stream. Default
+is "dv", or "da" if the filter is called as "amovie".
+
+ at item stream_index, si
+Specifies the index of the video stream to read. If the value is -1,
+the most suitable video stream will be automatically selected. The default
+value is "-1". Deprecated. If the filter is called "amovie", it will select
+audio instead of video.
+
+ at item loop
+Specifies how many times to read the stream in sequence.
+If the value is less than 1, the stream will be read again and again.
+Default value is "1".
+
+Note that when the movie is looped the source timestamps are not
+changed, so it will generate non monotonically increasing timestamps.
+ at end table
+
+It allows overlaying a second video on top of the main input of
+a filtergraph, as shown in this graph:
+ at example
+input -----------> deltapts0 --> overlay --> output
+ ^
+ |
+movie --> scale--> deltapts1 -------+
+ at end example
+ at subsection Examples
+
+ at itemize
+ at item
+Skip 3.2 seconds from the start of the AVI file in.avi, and overlay it
+on top of the input labelled "in":
+ at example
+movie=in.avi:seek_point=3.2, scale=180:-1, setpts=PTS-STARTPTS [over];
+[in] setpts=PTS-STARTPTS [main];
+[main][over] overlay=16:16 [out]
+ at end example
+
+ at item
+Read from a video4linux2 device, and overlay it on top of the input
+labelled "in":
+ at example
+movie=/dev/video0:f=video4linux2, scale=180:-1, setpts=PTS-STARTPTS [over];
+[in] setpts=PTS-STARTPTS [main];
+[main][over] overlay=16:16 [out]
+ at end example
+
+ at item
+Read the first video stream and the audio stream with id 0x81 from
+dvd.vob; the video is connected to the pad named "video" and the audio is
+connected to the pad named "audio":
+ at example
+movie=dvd.vob:s=v:0+#0x81 [video] [audio]
+ at end example
+ at end itemize
+
+ at c man end MULTIMEDIA SOURCES
diff --git a/ffmpeg-2-8-11/doc/formats.texi b/ffmpeg-2-8-12/doc/formats.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/formats.texi
rename to ffmpeg-2-8-12/doc/formats.texi
diff --git a/ffmpeg-2-8-11/doc/general.texi b/ffmpeg-2-8-12/doc/general.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/general.texi
rename to ffmpeg-2-8-12/doc/general.texi
diff --git a/ffmpeg-2-8-11/doc/git-howto.texi b/ffmpeg-2-8-12/doc/git-howto.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/git-howto.texi
rename to ffmpeg-2-8-12/doc/git-howto.texi
diff --git a/ffmpeg-2-8-11/doc/indevs.texi b/ffmpeg-2-8-12/doc/indevs.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/indevs.texi
rename to ffmpeg-2-8-12/doc/indevs.texi
diff --git a/ffmpeg-2-8-11/doc/issue_tracker.txt b/ffmpeg-2-8-12/doc/issue_tracker.txt
similarity index 100%
rename from ffmpeg-2-8-11/doc/issue_tracker.txt
rename to ffmpeg-2-8-12/doc/issue_tracker.txt
diff --git a/ffmpeg-2-8-11/doc/libavcodec.texi b/ffmpeg-2-8-12/doc/libavcodec.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/libavcodec.texi
rename to ffmpeg-2-8-12/doc/libavcodec.texi
diff --git a/ffmpeg-2-8-11/doc/libavdevice.texi b/ffmpeg-2-8-12/doc/libavdevice.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/libavdevice.texi
rename to ffmpeg-2-8-12/doc/libavdevice.texi
diff --git a/ffmpeg-2-8-11/doc/libavfilter.texi b/ffmpeg-2-8-12/doc/libavfilter.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/libavfilter.texi
rename to ffmpeg-2-8-12/doc/libavfilter.texi
diff --git a/ffmpeg-2-8-11/doc/libavformat.texi b/ffmpeg-2-8-12/doc/libavformat.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/libavformat.texi
rename to ffmpeg-2-8-12/doc/libavformat.texi
diff --git a/ffmpeg-2-8-11/doc/libavutil.texi b/ffmpeg-2-8-12/doc/libavutil.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/libavutil.texi
rename to ffmpeg-2-8-12/doc/libavutil.texi
diff --git a/ffmpeg-2-8-11/doc/libswresample.texi b/ffmpeg-2-8-12/doc/libswresample.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/libswresample.texi
rename to ffmpeg-2-8-12/doc/libswresample.texi
diff --git a/ffmpeg-2-8-11/doc/libswscale.texi b/ffmpeg-2-8-12/doc/libswscale.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/libswscale.texi
rename to ffmpeg-2-8-12/doc/libswscale.texi
diff --git a/ffmpeg-2-8-11/doc/metadata.texi b/ffmpeg-2-8-12/doc/metadata.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/metadata.texi
rename to ffmpeg-2-8-12/doc/metadata.texi
diff --git a/ffmpeg-2-8-11/doc/mips.txt b/ffmpeg-2-8-12/doc/mips.txt
similarity index 100%
rename from ffmpeg-2-8-11/doc/mips.txt
rename to ffmpeg-2-8-12/doc/mips.txt
diff --git a/ffmpeg-2-8-11/doc/multithreading.txt b/ffmpeg-2-8-12/doc/multithreading.txt
similarity index 100%
rename from ffmpeg-2-8-11/doc/multithreading.txt
rename to ffmpeg-2-8-12/doc/multithreading.txt
diff --git a/ffmpeg-2-8-11/doc/muxers.texi b/ffmpeg-2-8-12/doc/muxers.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/muxers.texi
rename to ffmpeg-2-8-12/doc/muxers.texi
diff --git a/ffmpeg-2-8-11/doc/nut.texi b/ffmpeg-2-8-12/doc/nut.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/nut.texi
rename to ffmpeg-2-8-12/doc/nut.texi
diff --git a/ffmpeg-2-8-11/doc/optimization.txt b/ffmpeg-2-8-12/doc/optimization.txt
similarity index 100%
rename from ffmpeg-2-8-11/doc/optimization.txt
rename to ffmpeg-2-8-12/doc/optimization.txt
diff --git a/ffmpeg-2-8-11/doc/outdevs.texi b/ffmpeg-2-8-12/doc/outdevs.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/outdevs.texi
rename to ffmpeg-2-8-12/doc/outdevs.texi
diff --git a/ffmpeg-2-8-11/doc/platform.texi b/ffmpeg-2-8-12/doc/platform.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/platform.texi
rename to ffmpeg-2-8-12/doc/platform.texi
diff --git a/ffmpeg-2-8-11/doc/print_options.c b/ffmpeg-2-8-12/doc/print_options.c
similarity index 100%
rename from ffmpeg-2-8-11/doc/print_options.c
rename to ffmpeg-2-8-12/doc/print_options.c
diff --git a/ffmpeg-2-8-11/doc/protocols.texi b/ffmpeg-2-8-12/doc/protocols.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/protocols.texi
rename to ffmpeg-2-8-12/doc/protocols.texi
diff --git a/ffmpeg-2-8-11/doc/rate_distortion.txt b/ffmpeg-2-8-12/doc/rate_distortion.txt
similarity index 100%
rename from ffmpeg-2-8-11/doc/rate_distortion.txt
rename to ffmpeg-2-8-12/doc/rate_distortion.txt
diff --git a/ffmpeg-2-8-11/doc/resampler.texi b/ffmpeg-2-8-12/doc/resampler.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/resampler.texi
rename to ffmpeg-2-8-12/doc/resampler.texi
diff --git a/ffmpeg-2-8-11/doc/scaler.texi b/ffmpeg-2-8-12/doc/scaler.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/scaler.texi
rename to ffmpeg-2-8-12/doc/scaler.texi
diff --git a/ffmpeg-2-8-11/doc/snow.txt b/ffmpeg-2-8-12/doc/snow.txt
similarity index 100%
rename from ffmpeg-2-8-11/doc/snow.txt
rename to ffmpeg-2-8-12/doc/snow.txt
diff --git a/ffmpeg-2-8-11/doc/style.min.css b/ffmpeg-2-8-12/doc/style.min.css
similarity index 100%
rename from ffmpeg-2-8-11/doc/style.min.css
rename to ffmpeg-2-8-12/doc/style.min.css
diff --git a/ffmpeg-2-8-11/doc/swresample.txt b/ffmpeg-2-8-12/doc/swresample.txt
similarity index 100%
rename from ffmpeg-2-8-11/doc/swresample.txt
rename to ffmpeg-2-8-12/doc/swresample.txt
diff --git a/ffmpeg-2-8-11/doc/swscale.txt b/ffmpeg-2-8-12/doc/swscale.txt
similarity index 100%
rename from ffmpeg-2-8-11/doc/swscale.txt
rename to ffmpeg-2-8-12/doc/swscale.txt
diff --git a/ffmpeg-2-8-11/doc/t2h.init b/ffmpeg-2-8-12/doc/t2h.init
similarity index 100%
rename from ffmpeg-2-8-11/doc/t2h.init
rename to ffmpeg-2-8-12/doc/t2h.init
diff --git a/ffmpeg-2-8-11/doc/t2h.pm b/ffmpeg-2-8-12/doc/t2h.pm
similarity index 100%
rename from ffmpeg-2-8-11/doc/t2h.pm
rename to ffmpeg-2-8-12/doc/t2h.pm
diff --git a/ffmpeg-2-8-11/doc/tablegen.txt b/ffmpeg-2-8-12/doc/tablegen.txt
similarity index 100%
rename from ffmpeg-2-8-11/doc/tablegen.txt
rename to ffmpeg-2-8-12/doc/tablegen.txt
diff --git a/ffmpeg-2-8-11/doc/texi2pod.pl b/ffmpeg-2-8-12/doc/texi2pod.pl
similarity index 100%
rename from ffmpeg-2-8-11/doc/texi2pod.pl
rename to ffmpeg-2-8-12/doc/texi2pod.pl
diff --git a/ffmpeg-2-8-11/doc/texidep.pl b/ffmpeg-2-8-12/doc/texidep.pl
similarity index 100%
rename from ffmpeg-2-8-11/doc/texidep.pl
rename to ffmpeg-2-8-12/doc/texidep.pl
diff --git a/ffmpeg-2-8-11/doc/utils.texi b/ffmpeg-2-8-12/doc/utils.texi
similarity index 100%
rename from ffmpeg-2-8-11/doc/utils.texi
rename to ffmpeg-2-8-12/doc/utils.texi
diff --git a/ffmpeg-2-8-11/doc/writing_filters.txt b/ffmpeg-2-8-12/doc/writing_filters.txt
similarity index 100%
rename from ffmpeg-2-8-11/doc/writing_filters.txt
rename to ffmpeg-2-8-12/doc/writing_filters.txt
diff --git a/ffmpeg-2-8-11/ffmpeg.c b/ffmpeg-2-8-12/ffmpeg.c
similarity index 100%
rename from ffmpeg-2-8-11/ffmpeg.c
rename to ffmpeg-2-8-12/ffmpeg.c
diff --git a/ffmpeg-2-8-11/ffmpeg.h b/ffmpeg-2-8-12/ffmpeg.h
similarity index 100%
rename from ffmpeg-2-8-11/ffmpeg.h
rename to ffmpeg-2-8-12/ffmpeg.h
diff --git a/ffmpeg-2-8-11/ffmpeg_dxva2.c b/ffmpeg-2-8-12/ffmpeg_dxva2.c
similarity index 100%
rename from ffmpeg-2-8-11/ffmpeg_dxva2.c
rename to ffmpeg-2-8-12/ffmpeg_dxva2.c
diff --git a/ffmpeg-2-8-11/ffmpeg_filter.c b/ffmpeg-2-8-12/ffmpeg_filter.c
similarity index 100%
rename from ffmpeg-2-8-11/ffmpeg_filter.c
rename to ffmpeg-2-8-12/ffmpeg_filter.c
diff --git a/ffmpeg-2-8-11/ffmpeg_opt.c b/ffmpeg-2-8-12/ffmpeg_opt.c
similarity index 100%
rename from ffmpeg-2-8-11/ffmpeg_opt.c
rename to ffmpeg-2-8-12/ffmpeg_opt.c
diff --git a/ffmpeg-2-8-11/ffmpeg_vdpau.c b/ffmpeg-2-8-12/ffmpeg_vdpau.c
similarity index 100%
rename from ffmpeg-2-8-11/ffmpeg_vdpau.c
rename to ffmpeg-2-8-12/ffmpeg_vdpau.c
diff --git a/ffmpeg-2-8-11/ffmpeg_videotoolbox.c b/ffmpeg-2-8-12/ffmpeg_videotoolbox.c
similarity index 100%
rename from ffmpeg-2-8-11/ffmpeg_videotoolbox.c
rename to ffmpeg-2-8-12/ffmpeg_videotoolbox.c
diff --git a/ffmpeg-2-8-11/ffplay.c b/ffmpeg-2-8-12/ffplay.c
similarity index 100%
rename from ffmpeg-2-8-11/ffplay.c
rename to ffmpeg-2-8-12/ffplay.c
diff --git a/ffmpeg-2-8-11/ffprobe.c b/ffmpeg-2-8-12/ffprobe.c
similarity index 100%
rename from ffmpeg-2-8-11/ffprobe.c
rename to ffmpeg-2-8-12/ffprobe.c
diff --git a/ffmpeg-2-8-11/ffserver.c b/ffmpeg-2-8-12/ffserver.c
similarity index 100%
rename from ffmpeg-2-8-11/ffserver.c
rename to ffmpeg-2-8-12/ffserver.c
diff --git a/ffmpeg-2-8-11/ffserver_config.c b/ffmpeg-2-8-12/ffserver_config.c
similarity index 100%
rename from ffmpeg-2-8-11/ffserver_config.c
rename to ffmpeg-2-8-12/ffserver_config.c
diff --git a/ffmpeg-2-8-11/ffserver_config.h b/ffmpeg-2-8-12/ffserver_config.h
similarity index 100%
rename from ffmpeg-2-8-11/ffserver_config.h
rename to ffmpeg-2-8-12/ffserver_config.h
diff --git a/ffmpeg-2-8-11/libavcodec/012v.c b/ffmpeg-2-8-12/libavcodec/012v.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/012v.c
rename to ffmpeg-2-8-12/libavcodec/012v.c
diff --git a/ffmpeg-2-8-11/libavcodec/4xm.c b/ffmpeg-2-8-12/libavcodec/4xm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/4xm.c
rename to ffmpeg-2-8-12/libavcodec/4xm.c
diff --git a/ffmpeg-2-8-11/libavcodec/8bps.c b/ffmpeg-2-8-12/libavcodec/8bps.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/8bps.c
rename to ffmpeg-2-8-12/libavcodec/8bps.c
diff --git a/ffmpeg-2-8-11/libavcodec/8svx.c b/ffmpeg-2-8-12/libavcodec/8svx.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/8svx.c
rename to ffmpeg-2-8-12/libavcodec/8svx.c
diff --git a/ffmpeg-2-8-11/libavcodec/Makefile b/ffmpeg-2-8-12/libavcodec/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/Makefile
rename to ffmpeg-2-8-12/libavcodec/Makefile
diff --git a/ffmpeg-2-8-11/libavcodec/a64colors.h b/ffmpeg-2-8-12/libavcodec/a64colors.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/a64colors.h
rename to ffmpeg-2-8-12/libavcodec/a64colors.h
diff --git a/ffmpeg-2-8-11/libavcodec/a64multienc.c b/ffmpeg-2-8-12/libavcodec/a64multienc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/a64multienc.c
rename to ffmpeg-2-8-12/libavcodec/a64multienc.c
diff --git a/ffmpeg-2-8-11/libavcodec/a64tables.h b/ffmpeg-2-8-12/libavcodec/a64tables.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/a64tables.h
rename to ffmpeg-2-8-12/libavcodec/a64tables.h
diff --git a/ffmpeg-2-8-11/libavcodec/aac.h b/ffmpeg-2-8-12/libavcodec/aac.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aac.h
rename to ffmpeg-2-8-12/libavcodec/aac.h
diff --git a/ffmpeg-2-8-11/libavcodec/aac_ac3_parser.c b/ffmpeg-2-8-12/libavcodec/aac_ac3_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aac_ac3_parser.c
rename to ffmpeg-2-8-12/libavcodec/aac_ac3_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/aac_ac3_parser.h b/ffmpeg-2-8-12/libavcodec/aac_ac3_parser.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aac_ac3_parser.h
rename to ffmpeg-2-8-12/libavcodec/aac_ac3_parser.h
diff --git a/ffmpeg-2-8-11/libavcodec/aac_adtstoasc_bsf.c b/ffmpeg-2-8-12/libavcodec/aac_adtstoasc_bsf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aac_adtstoasc_bsf.c
rename to ffmpeg-2-8-12/libavcodec/aac_adtstoasc_bsf.c
diff --git a/ffmpeg-2-8-12/libavcodec/aac_defines.h b/ffmpeg-2-8-12/libavcodec/aac_defines.h
new file mode 100644
index 0000000..a833dc3
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/aac_defines.h
@@ -0,0 +1,114 @@
+/*
+ * AAC defines
+ *
+ * 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_AAC_DEFINES_H
+#define AVCODEC_AAC_DEFINES_H
+
+#ifndef USE_FIXED
+#define USE_FIXED 0
+#endif
+
+#if USE_FIXED
+
+#include "libavutil/softfloat.h"
+
+#define FFT_FLOAT 0
+#define FFT_FIXED_32 1
+
+#define AAC_RENAME(x) x ## _fixed
+#define AAC_RENAME_32(x) x ## _fixed_32
+#define INTFLOAT int
+#define INT64FLOAT int64_t
+#define SHORTFLOAT int16_t
+#define AAC_FLOAT SoftFloat
+#define AAC_SIGNE int
+#define FIXR(a) ((int)((a) * 1 + 0.5))
+#define FIXR10(a) ((int)((a) * 1024.0 + 0.5))
+#define Q23(a) (int)((a) * 8388608.0 + 0.5)
+#define Q30(x) (int)((x)*1073741824.0 + 0.5)
+#define Q31(x) (int)((x)*2147483648.0 + 0.5)
+#define RANGE15(x) x
+#define GET_GAIN(x, y) (-(y) * (1 << (x))) + 1024
+#define AAC_MUL16(x, y) (int)(((int64_t)(x) * (y) + 0x8000) >> 16)
+#define AAC_MUL26(x, y) (int)(((int64_t)(x) * (y) + 0x2000000) >> 26)
+#define AAC_MUL30(x, y) (int)(((int64_t)(x) * (y) + 0x20000000) >> 30)
+#define AAC_MUL31(x, y) (int)(((int64_t)(x) * (y) + 0x40000000) >> 31)
+#define AAC_MADD28(x, y, a, b) (int)((((int64_t)(x) * (y)) + \
+ ((int64_t)(a) * (b)) + \
+ 0x8000000) >> 28)
+#define AAC_MADD30(x, y, a, b) (int)((((int64_t)(x) * (y)) + \
+ ((int64_t)(a) * (b)) + \
+ 0x20000000) >> 30)
+#define AAC_MADD30_V8(x, y, a, b, c, d, e, f) (int)((((int64_t)(x) * (y)) + \
+ ((int64_t)(a) * (b)) + \
+ ((int64_t)(c) * (d)) + \
+ ((int64_t)(e) * (f)) + \
+ 0x20000000) >> 30)
+#define AAC_MSUB30(x, y, a, b) (int)((((int64_t)(x) * (y)) - \
+ ((int64_t)(a) * (b)) + \
+ 0x20000000) >> 30)
+#define AAC_MSUB30_V8(x, y, a, b, c, d, e, f) (int)((((int64_t)(x) * (y)) + \
+ ((int64_t)(a) * (b)) - \
+ ((int64_t)(c) * (d)) - \
+ ((int64_t)(e) * (f)) + \
+ 0x20000000) >> 30)
+#define AAC_MSUB31_V3(x, y, z) (int)((((int64_t)(x) * (z)) - \
+ ((int64_t)(y) * (z)) + \
+ 0x40000000) >> 31)
+#define AAC_HALF_SUM(x, y) (((x) >> 1) + ((y) >> 1))
+#define AAC_SRA_R(x, y) (int)(((x) + (1 << ((y) - 1))) >> (y))
+
+#else
+
+#define FFT_FLOAT 1
+#define FFT_FIXED_32 0
+
+#define AAC_RENAME(x) x
+#define AAC_RENAME_32(x) x
+#define INTFLOAT float
+#define INT64FLOAT float
+#define SHORTFLOAT float
+#define AAC_FLOAT float
+#define AAC_SIGNE unsigned
+#define FIXR(x) ((float)(x))
+#define FIXR10(x) ((float)(x))
+#define Q23(x) x
+#define Q30(x) x
+#define Q31(x) x
+#define RANGE15(x) (32768.0 * (x))
+#define GET_GAIN(x, y) powf((x), -(y))
+#define AAC_MUL16(x, y) ((x) * (y))
+#define AAC_MUL26(x, y) ((x) * (y))
+#define AAC_MUL30(x, y) ((x) * (y))
+#define AAC_MUL31(x, y) ((x) * (y))
+#define AAC_MADD28(x, y, a, b) ((x) * (y) + (a) * (b))
+#define AAC_MADD30(x, y, a, b) ((x) * (y) + (a) * (b))
+#define AAC_MADD30_V8(x, y, a, b, c, d, e, f) ((x) * (y) + (a) * (b) + \
+ (c) * (d) + (e) * (f))
+#define AAC_MSUB30(x, y, a, b) ((x) * (y) - (a) * (b))
+#define AAC_MSUB30_V8(x, y, a, b, c, d, e, f) ((x) * (y) + (a) * (b) - \
+ (c) * (d) - (e) * (f))
+#define AAC_MSUB31_V3(x, y, z) ((x) - (y)) * (z)
+#define AAC_HALF_SUM(x, y) ((x) + (y)) * 0.5f
+#define AAC_SRA_R(x, y) (x)
+
+#endif /* USE_FIXED */
+
+#endif /* AVCODEC_AAC_DEFINES_H */
diff --git a/ffmpeg-2-8-11/libavcodec/aac_parser.c b/ffmpeg-2-8-12/libavcodec/aac_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aac_parser.c
rename to ffmpeg-2-8-12/libavcodec/aac_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/aac_tablegen.c b/ffmpeg-2-8-12/libavcodec/aac_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aac_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/aac_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/aac_tablegen.h b/ffmpeg-2-8-12/libavcodec/aac_tablegen.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aac_tablegen.h
rename to ffmpeg-2-8-12/libavcodec/aac_tablegen.h
diff --git a/ffmpeg-2-8-11/libavcodec/aac_tablegen_decl.h b/ffmpeg-2-8-12/libavcodec/aac_tablegen_decl.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aac_tablegen_decl.h
rename to ffmpeg-2-8-12/libavcodec/aac_tablegen_decl.h
diff --git a/ffmpeg-2-8-11/libavcodec/aacadtsdec.c b/ffmpeg-2-8-12/libavcodec/aacadtsdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacadtsdec.c
rename to ffmpeg-2-8-12/libavcodec/aacadtsdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacadtsdec.h b/ffmpeg-2-8-12/libavcodec/aacadtsdec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacadtsdec.h
rename to ffmpeg-2-8-12/libavcodec/aacadtsdec.h
diff --git a/ffmpeg-2-8-11/libavcodec/aaccoder.c b/ffmpeg-2-8-12/libavcodec/aaccoder.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aaccoder.c
rename to ffmpeg-2-8-12/libavcodec/aaccoder.c
diff --git a/ffmpeg-2-8-12/libavcodec/aacdec.c b/ffmpeg-2-8-12/libavcodec/aacdec.c
new file mode 100644
index 0000000..950cec0
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/aacdec.c
@@ -0,0 +1,583 @@
+/*
+ * AAC decoder
+ * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
+ * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
+ * Copyright (c) 2008-2013 Alex Converse <alex.converse at gmail.com>
+ *
+ * AAC LATM decoder
+ * Copyright (c) 2008-2010 Paul Kendall <paul at kcbbs.gen.nz>
+ * Copyright (c) 2010 Janne Grunau <janne-libav at jannau.net>
+ *
+ * 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
+ * AAC decoder
+ * @author Oded Shimon ( ods15 ods15 dyndns org )
+ * @author Maxim Gavrilov ( maxim.gavrilov gmail com )
+ */
+
+#define FFT_FLOAT 1
+#define FFT_FIXED_32 0
+#define USE_FIXED 0
+
+#include "libavutil/float_dsp.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "get_bits.h"
+#include "fft.h"
+#include "imdct15.h"
+#include "lpc.h"
+#include "kbdwin.h"
+#include "sinewin.h"
+
+#include "aac.h"
+#include "aactab.h"
+#include "aacdectab.h"
+#include "cbrt_tablegen.h"
+#include "sbr.h"
+#include "aacsbr.h"
+#include "mpeg4audio.h"
+#include "aacadtsdec.h"
+#include "libavutil/intfloat.h"
+
+#include <errno.h>
+#include <math.h>
+#include <stdint.h>
+#include <string.h>
+
+#if ARCH_ARM
+# include "arm/aac.h"
+#elif ARCH_MIPS
+# include "mips/aacdec_mips.h"
+#endif
+
+static av_always_inline void reset_predict_state(PredictorState *ps)
+{
+ ps->r0 = 0.0f;
+ ps->r1 = 0.0f;
+ ps->cor0 = 0.0f;
+ ps->cor1 = 0.0f;
+ ps->var0 = 1.0f;
+ ps->var1 = 1.0f;
+}
+
+#ifndef VMUL2
+static inline float *VMUL2(float *dst, const float *v, unsigned idx,
+ const float *scale)
+{
+ float s = *scale;
+ *dst++ = v[idx & 15] * s;
+ *dst++ = v[idx>>4 & 15] * s;
+ return dst;
+}
+#endif
+
+#ifndef VMUL4
+static inline float *VMUL4(float *dst, const float *v, unsigned idx,
+ const float *scale)
+{
+ float s = *scale;
+ *dst++ = v[idx & 3] * s;
+ *dst++ = v[idx>>2 & 3] * s;
+ *dst++ = v[idx>>4 & 3] * s;
+ *dst++ = v[idx>>6 & 3] * s;
+ return dst;
+}
+#endif
+
+#ifndef VMUL2S
+static inline float *VMUL2S(float *dst, const float *v, unsigned idx,
+ unsigned sign, const float *scale)
+{
+ union av_intfloat32 s0, s1;
+
+ s0.f = s1.f = *scale;
+ s0.i ^= sign >> 1 << 31;
+ s1.i ^= sign << 31;
+
+ *dst++ = v[idx & 15] * s0.f;
+ *dst++ = v[idx>>4 & 15] * s1.f;
+
+ return dst;
+}
+#endif
+
+#ifndef VMUL4S
+static inline float *VMUL4S(float *dst, const float *v, unsigned idx,
+ unsigned sign, const float *scale)
+{
+ unsigned nz = idx >> 12;
+ union av_intfloat32 s = { .f = *scale };
+ union av_intfloat32 t;
+
+ t.i = s.i ^ (sign & 1U<<31);
+ *dst++ = v[idx & 3] * t.f;
+
+ sign <<= nz & 1; nz >>= 1;
+ t.i = s.i ^ (sign & 1U<<31);
+ *dst++ = v[idx>>2 & 3] * t.f;
+
+ sign <<= nz & 1; nz >>= 1;
+ t.i = s.i ^ (sign & 1U<<31);
+ *dst++ = v[idx>>4 & 3] * t.f;
+
+ sign <<= nz & 1;
+ t.i = s.i ^ (sign & 1U<<31);
+ *dst++ = v[idx>>6 & 3] * t.f;
+
+ return dst;
+}
+#endif
+
+static av_always_inline float flt16_round(float pf)
+{
+ union av_intfloat32 tmp;
+ tmp.f = pf;
+ tmp.i = (tmp.i + 0x00008000U) & 0xFFFF0000U;
+ return tmp.f;
+}
+
+static av_always_inline float flt16_even(float pf)
+{
+ union av_intfloat32 tmp;
+ tmp.f = pf;
+ tmp.i = (tmp.i + 0x00007FFFU + (tmp.i & 0x00010000U >> 16)) & 0xFFFF0000U;
+ return tmp.f;
+}
+
+static av_always_inline float flt16_trunc(float pf)
+{
+ union av_intfloat32 pun;
+ pun.f = pf;
+ pun.i &= 0xFFFF0000U;
+ return pun.f;
+}
+
+static av_always_inline void predict(PredictorState *ps, float *coef,
+ int output_enable)
+{
+ const float a = 0.953125; // 61.0 / 64
+ const float alpha = 0.90625; // 29.0 / 32
+ float e0, e1;
+ float pv;
+ float k1, k2;
+ float r0 = ps->r0, r1 = ps->r1;
+ float cor0 = ps->cor0, cor1 = ps->cor1;
+ float var0 = ps->var0, var1 = ps->var1;
+
+ k1 = var0 > 1 ? cor0 * flt16_even(a / var0) : 0;
+ k2 = var1 > 1 ? cor1 * flt16_even(a / var1) : 0;
+
+ pv = flt16_round(k1 * r0 + k2 * r1);
+ if (output_enable)
+ *coef += pv;
+
+ e0 = *coef;
+ e1 = e0 - k1 * r0;
+
+ ps->cor1 = flt16_trunc(alpha * cor1 + r1 * e1);
+ ps->var1 = flt16_trunc(alpha * var1 + 0.5f * (r1 * r1 + e1 * e1));
+ ps->cor0 = flt16_trunc(alpha * cor0 + r0 * e0);
+ ps->var0 = flt16_trunc(alpha * var0 + 0.5f * (r0 * r0 + e0 * e0));
+
+ ps->r1 = flt16_trunc(a * (r0 - k1 * e0));
+ ps->r0 = flt16_trunc(a * e0);
+}
+
+/**
+ * Apply dependent channel coupling (applied before IMDCT).
+ *
+ * @param index index into coupling gain array
+ */
+static void apply_dependent_coupling(AACContext *ac,
+ SingleChannelElement *target,
+ ChannelElement *cce, int index)
+{
+ IndividualChannelStream *ics = &cce->ch[0].ics;
+ const uint16_t *offsets = ics->swb_offset;
+ float *dest = target->coeffs;
+ const float *src = cce->ch[0].coeffs;
+ int g, i, group, k, idx = 0;
+ if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Dependent coupling is not supported together with LTP\n");
+ return;
+ }
+ for (g = 0; g < ics->num_window_groups; g++) {
+ for (i = 0; i < ics->max_sfb; i++, idx++) {
+ if (cce->ch[0].band_type[idx] != ZERO_BT) {
+ const float gain = cce->coup.gain[index][idx];
+ for (group = 0; group < ics->group_len[g]; group++) {
+ for (k = offsets[i]; k < offsets[i + 1]; k++) {
+ // FIXME: SIMDify
+ dest[group * 128 + k] += gain * src[group * 128 + k];
+ }
+ }
+ }
+ }
+ dest += ics->group_len[g] * 128;
+ src += ics->group_len[g] * 128;
+ }
+}
+
+/**
+ * Apply independent channel coupling (applied after IMDCT).
+ *
+ * @param index index into coupling gain array
+ */
+static void apply_independent_coupling(AACContext *ac,
+ SingleChannelElement *target,
+ ChannelElement *cce, int index)
+{
+ int i;
+ const float gain = cce->coup.gain[index][0];
+ const float *src = cce->ch[0].ret;
+ float *dest = target->ret;
+ const int len = 1024 << (ac->oc[1].m4ac.sbr == 1);
+
+ for (i = 0; i < len; i++)
+ dest[i] += gain * src[i];
+}
+
+#include "aacdec_template.c"
+
+#define LOAS_SYNC_WORD 0x2b7 ///< 11 bits LOAS sync word
+
+struct LATMContext {
+ AACContext aac_ctx; ///< containing AACContext
+ int initialized; ///< initialized after a valid extradata was seen
+
+ // parser data
+ int audio_mux_version_A; ///< LATM syntax version
+ int frame_length_type; ///< 0/1 variable/fixed frame length
+ int frame_length; ///< frame length for fixed frame length
+};
+
+static inline uint32_t latm_get_value(GetBitContext *b)
+{
+ int length = get_bits(b, 2);
+
+ return get_bits_long(b, (length+1)*8);
+}
+
+static int latm_decode_audio_specific_config(struct LATMContext *latmctx,
+ GetBitContext *gb, int asclen)
+{
+ AACContext *ac = &latmctx->aac_ctx;
+ AVCodecContext *avctx = ac->avctx;
+ MPEG4AudioConfig m4ac = { 0 };
+ int config_start_bit = get_bits_count(gb);
+ int sync_extension = 0;
+ int bits_consumed, esize;
+
+ if (asclen) {
+ sync_extension = 1;
+ asclen = FFMIN(asclen, get_bits_left(gb));
+ } else
+ asclen = get_bits_left(gb);
+
+ if (config_start_bit % 8) {
+ avpriv_request_sample(latmctx->aac_ctx.avctx,
+ "Non-byte-aligned audio-specific config");
+ return AVERROR_PATCHWELCOME;
+ }
+ if (asclen <= 0)
+ return AVERROR_INVALIDDATA;
+ bits_consumed = decode_audio_specific_config(NULL, avctx, &m4ac,
+ gb->buffer + (config_start_bit / 8),
+ asclen, sync_extension);
+
+ if (bits_consumed < 0)
+ return AVERROR_INVALIDDATA;
+
+ if (!latmctx->initialized ||
+ ac->oc[1].m4ac.sample_rate != m4ac.sample_rate ||
+ ac->oc[1].m4ac.chan_config != m4ac.chan_config) {
+
+ if(latmctx->initialized) {
+ av_log(avctx, AV_LOG_INFO, "audio config changed\n");
+ } else {
+ av_log(avctx, AV_LOG_DEBUG, "initializing latmctx\n");
+ }
+ latmctx->initialized = 0;
+
+ esize = (bits_consumed+7) / 8;
+
+ if (avctx->extradata_size < esize) {
+ av_free(avctx->extradata);
+ avctx->extradata = av_malloc(esize + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!avctx->extradata)
+ return AVERROR(ENOMEM);
+ }
+
+ avctx->extradata_size = esize;
+ memcpy(avctx->extradata, gb->buffer + (config_start_bit/8), esize);
+ memset(avctx->extradata+esize, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ }
+ skip_bits_long(gb, bits_consumed);
+
+ return bits_consumed;
+}
+
+static int read_stream_mux_config(struct LATMContext *latmctx,
+ GetBitContext *gb)
+{
+ int ret, audio_mux_version = get_bits(gb, 1);
+
+ latmctx->audio_mux_version_A = 0;
+ if (audio_mux_version)
+ latmctx->audio_mux_version_A = get_bits(gb, 1);
+
+ if (!latmctx->audio_mux_version_A) {
+
+ if (audio_mux_version)
+ latm_get_value(gb); // taraFullness
+
+ skip_bits(gb, 1); // allStreamSameTimeFraming
+ skip_bits(gb, 6); // numSubFrames
+ // numPrograms
+ if (get_bits(gb, 4)) { // numPrograms
+ avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple programs");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ // for each program (which there is only one in DVB)
+
+ // for each layer (which there is only one in DVB)
+ if (get_bits(gb, 3)) { // numLayer
+ avpriv_request_sample(latmctx->aac_ctx.avctx, "Multiple layers");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ // for all but first stream: use_same_config = get_bits(gb, 1);
+ if (!audio_mux_version) {
+ if ((ret = latm_decode_audio_specific_config(latmctx, gb, 0)) < 0)
+ return ret;
+ } else {
+ int ascLen = latm_get_value(gb);
+ if ((ret = latm_decode_audio_specific_config(latmctx, gb, ascLen)) < 0)
+ return ret;
+ ascLen -= ret;
+ skip_bits_long(gb, ascLen);
+ }
+
+ latmctx->frame_length_type = get_bits(gb, 3);
+ switch (latmctx->frame_length_type) {
+ case 0:
+ skip_bits(gb, 8); // latmBufferFullness
+ break;
+ case 1:
+ latmctx->frame_length = get_bits(gb, 9);
+ break;
+ case 3:
+ case 4:
+ case 5:
+ skip_bits(gb, 6); // CELP frame length table index
+ break;
+ case 6:
+ case 7:
+ skip_bits(gb, 1); // HVXC frame length table index
+ break;
+ }
+
+ if (get_bits(gb, 1)) { // other data
+ if (audio_mux_version) {
+ latm_get_value(gb); // other_data_bits
+ } else {
+ int esc;
+ do {
+ esc = get_bits(gb, 1);
+ skip_bits(gb, 8);
+ } while (esc);
+ }
+ }
+
+ if (get_bits(gb, 1)) // crc present
+ skip_bits(gb, 8); // config_crc
+ }
+
+ return 0;
+}
+
+static int read_payload_length_info(struct LATMContext *ctx, GetBitContext *gb)
+{
+ uint8_t tmp;
+
+ if (ctx->frame_length_type == 0) {
+ int mux_slot_length = 0;
+ do {
+ if (get_bits_left(gb) < 8)
+ return AVERROR_INVALIDDATA;
+ tmp = get_bits(gb, 8);
+ mux_slot_length += tmp;
+ } while (tmp == 255);
+ return mux_slot_length;
+ } else if (ctx->frame_length_type == 1) {
+ return ctx->frame_length;
+ } else if (ctx->frame_length_type == 3 ||
+ ctx->frame_length_type == 5 ||
+ ctx->frame_length_type == 7) {
+ skip_bits(gb, 2); // mux_slot_length_coded
+ }
+ return 0;
+}
+
+static int read_audio_mux_element(struct LATMContext *latmctx,
+ GetBitContext *gb)
+{
+ int err;
+ uint8_t use_same_mux = get_bits(gb, 1);
+ if (!use_same_mux) {
+ if ((err = read_stream_mux_config(latmctx, gb)) < 0)
+ return err;
+ } else if (!latmctx->aac_ctx.avctx->extradata) {
+ av_log(latmctx->aac_ctx.avctx, AV_LOG_DEBUG,
+ "no decoder config found\n");
+ return AVERROR(EAGAIN);
+ }
+ if (latmctx->audio_mux_version_A == 0) {
+ int mux_slot_length_bytes = read_payload_length_info(latmctx, gb);
+ if (mux_slot_length_bytes < 0 || mux_slot_length_bytes * 8LL > get_bits_left(gb)) {
+ av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, "incomplete frame\n");
+ return AVERROR_INVALIDDATA;
+ } else if (mux_slot_length_bytes * 8 + 256 < get_bits_left(gb)) {
+ av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR,
+ "frame length mismatch %d << %d\n",
+ mux_slot_length_bytes * 8, get_bits_left(gb));
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ return 0;
+}
+
+
+static int latm_decode_frame(AVCodecContext *avctx, void *out,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ struct LATMContext *latmctx = avctx->priv_data;
+ int muxlength, err;
+ GetBitContext gb;
+
+ if ((err = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0)
+ return err;
+
+ // check for LOAS sync word
+ if (get_bits(&gb, 11) != LOAS_SYNC_WORD)
+ return AVERROR_INVALIDDATA;
+
+ muxlength = get_bits(&gb, 13) + 3;
+ // not enough data, the parser should have sorted this out
+ if (muxlength > avpkt->size)
+ return AVERROR_INVALIDDATA;
+
+ if ((err = read_audio_mux_element(latmctx, &gb)) < 0)
+ return err;
+
+ if (!latmctx->initialized) {
+ if (!avctx->extradata) {
+ *got_frame_ptr = 0;
+ return avpkt->size;
+ } else {
+ push_output_configuration(&latmctx->aac_ctx);
+ if ((err = decode_audio_specific_config(
+ &latmctx->aac_ctx, avctx, &latmctx->aac_ctx.oc[1].m4ac,
+ avctx->extradata, avctx->extradata_size*8LL, 1)) < 0) {
+ pop_output_configuration(&latmctx->aac_ctx);
+ return err;
+ }
+ latmctx->initialized = 1;
+ }
+ }
+
+ if (show_bits(&gb, 12) == 0xfff) {
+ av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR,
+ "ADTS header detected, probably as result of configuration "
+ "misparsing\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ switch (latmctx->aac_ctx.oc[1].m4ac.object_type) {
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_LTP:
+ case AOT_ER_AAC_LD:
+ case AOT_ER_AAC_ELD:
+ err = aac_decode_er_frame(avctx, out, got_frame_ptr, &gb);
+ break;
+ default:
+ err = aac_decode_frame_int(avctx, out, got_frame_ptr, &gb, avpkt);
+ }
+ if (err < 0)
+ return err;
+
+ return muxlength;
+}
+
+static av_cold int latm_decode_init(AVCodecContext *avctx)
+{
+ struct LATMContext *latmctx = avctx->priv_data;
+ int ret = aac_decode_init(avctx);
+
+ if (avctx->extradata_size > 0)
+ latmctx->initialized = !ret;
+
+ return ret;
+}
+
+AVCodec ff_aac_decoder = {
+ .name = "aac",
+ .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_AAC,
+ .priv_data_size = sizeof(AACContext),
+ .init = aac_decode_init,
+ .close = aac_decode_close,
+ .decode = aac_decode_frame,
+ .sample_fmts = (const enum AVSampleFormat[]) {
+ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
+ },
+ .capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
+ .channel_layouts = aac_channel_layout,
+ .flush = flush,
+ .priv_class = &aac_decoder_class,
+ .profiles = profiles,
+};
+
+/*
+ Note: This decoder filter is intended to decode LATM streams transferred
+ in MPEG transport streams which only contain one program.
+ To do a more complex LATM demuxing a separate LATM demuxer should be used.
+*/
+AVCodec ff_aac_latm_decoder = {
+ .name = "aac_latm",
+ .long_name = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Coding LATM syntax)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_AAC_LATM,
+ .priv_data_size = sizeof(struct LATMContext),
+ .init = latm_decode_init,
+ .close = aac_decode_close,
+ .decode = latm_decode_frame,
+ .sample_fmts = (const enum AVSampleFormat[]) {
+ AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE
+ },
+ .capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
+ .channel_layouts = aac_channel_layout,
+ .flush = flush,
+ .profiles = profiles,
+};
diff --git a/ffmpeg-2-8-12/libavcodec/aacdec_fixed.c b/ffmpeg-2-8-12/libavcodec/aacdec_fixed.c
new file mode 100644
index 0000000..f4503ca
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/aacdec_fixed.c
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2013
+ * MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * AAC decoder fixed-point implementation
+ *
+ * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
+ * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * AAC decoder
+ * @author Oded Shimon ( ods15 ods15 dyndns org )
+ * @author Maxim Gavrilov ( maxim.gavrilov gmail com )
+ *
+ * Fixed point implementation
+ * @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com )
+ */
+
+#define FFT_FLOAT 0
+#define FFT_FIXED_32 1
+#define USE_FIXED 1
+
+#include "libavutil/fixed_dsp.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "get_bits.h"
+#include "fft.h"
+#include "lpc.h"
+#include "kbdwin.h"
+#include "sinewin.h"
+
+#include "aac.h"
+#include "aactab.h"
+#include "aacdectab.h"
+#include "cbrt_tablegen.h"
+#include "sbr.h"
+#include "aacsbr.h"
+#include "mpeg4audio.h"
+#include "aacadtsdec.h"
+#include "libavutil/intfloat.h"
+
+#include <math.h>
+#include <string.h>
+
+static av_always_inline void reset_predict_state(PredictorState *ps)
+{
+ ps->r0.mant = 0;
+ ps->r0.exp = 0;
+ ps->r1.mant = 0;
+ ps->r1.exp = 0;
+ ps->cor0.mant = 0;
+ ps->cor0.exp = 0;
+ ps->cor1.mant = 0;
+ ps->cor1.exp = 0;
+ ps->var0.mant = 0x20000000;
+ ps->var0.exp = 1;
+ ps->var1.mant = 0x20000000;
+ ps->var1.exp = 1;
+}
+
+static const int exp2tab[4] = { Q31(1.0000000000/2), Q31(1.1892071150/2), Q31(1.4142135624/2), Q31(1.6817928305/2) }; // 2^0, 2^0.25, 2^0.5, 2^0.75
+
+static inline int *DEC_SPAIR(int *dst, unsigned idx)
+{
+ dst[0] = (idx & 15) - 4;
+ dst[1] = (idx >> 4 & 15) - 4;
+
+ return dst + 2;
+}
+
+static inline int *DEC_SQUAD(int *dst, unsigned idx)
+{
+ dst[0] = (idx & 3) - 1;
+ dst[1] = (idx >> 2 & 3) - 1;
+ dst[2] = (idx >> 4 & 3) - 1;
+ dst[3] = (idx >> 6 & 3) - 1;
+
+ return dst + 4;
+}
+
+static inline int *DEC_UPAIR(int *dst, unsigned idx, unsigned sign)
+{
+ dst[0] = (idx & 15) * (1 - (sign & 0xFFFFFFFE));
+ dst[1] = (idx >> 4 & 15) * (1 - ((sign & 1) * 2));
+
+ return dst + 2;
+}
+
+static inline int *DEC_UQUAD(int *dst, unsigned idx, unsigned sign)
+{
+ unsigned nz = idx >> 12;
+
+ dst[0] = (idx & 3) * (1 + (((int)sign >> 31) * 2));
+ sign <<= nz & 1;
+ nz >>= 1;
+ dst[1] = (idx >> 2 & 3) * (1 + (((int)sign >> 31) * 2));
+ sign <<= nz & 1;
+ nz >>= 1;
+ dst[2] = (idx >> 4 & 3) * (1 + (((int)sign >> 31) * 2));
+ sign <<= nz & 1;
+ nz >>= 1;
+ dst[3] = (idx >> 6 & 3) * (1 + (((int)sign >> 31) * 2));
+
+ return dst + 4;
+}
+
+static void vector_pow43(int *coefs, int len)
+{
+ int i, coef;
+
+ for (i=0; i<len; i++) {
+ coef = coefs[i];
+ if (coef < 0)
+ coef = -(int)cbrt_tab[-coef];
+ else
+ coef = (int)cbrt_tab[coef];
+ coefs[i] = coef;
+ }
+}
+
+static void subband_scale(int *dst, int *src, int scale, int offset, int len)
+{
+ int ssign = scale < 0 ? -1 : 1;
+ int s = FFABS(scale);
+ unsigned int round;
+ int i, out, c = exp2tab[s & 3];
+
+ s = offset - (s >> 2);
+
+ if (s > 31) {
+ for (i=0; i<len; i++) {
+ dst[i] = 0;
+ }
+ } else if (s > 0) {
+ round = 1 << (s-1);
+ for (i=0; i<len; i++) {
+ out = (int)(((int64_t)src[i] * c) >> 32);
+ dst[i] = ((int)(out+round) >> s) * ssign;
+ }
+ }
+ else {
+ s = s + 32;
+ round = 1 << (s-1);
+ for (i=0; i<len; i++) {
+ out = (int)((int64_t)((int64_t)src[i] * c + round) >> s);
+ dst[i] = out * (unsigned)ssign;
+ }
+ }
+}
+
+static void noise_scale(int *coefs, int scale, int band_energy, int len)
+{
+ int ssign = scale < 0 ? -1 : 1;
+ int s = FFABS(scale);
+ unsigned int round;
+ int i, out, c = exp2tab[s & 3];
+ int nlz = 0;
+
+ while (band_energy > 0x7fff) {
+ band_energy >>= 1;
+ nlz++;
+ }
+ c /= band_energy;
+ s = 21 + nlz - (s >> 2);
+
+ if (s > 31) {
+ for (i=0; i<len; i++) {
+ coefs[i] = 0;
+ }
+ } else if (s >= 0) {
+ round = s ? 1 << (s-1) : 0;
+ for (i=0; i<len; i++) {
+ out = (int)(((int64_t)coefs[i] * c) >> 32);
+ coefs[i] = ((int)(out+round) >> s) * ssign;
+ }
+ }
+ else {
+ s = s + 32;
+ round = 1 << (s-1);
+ for (i=0; i<len; i++) {
+ out = (int)((int64_t)((int64_t)coefs[i] * c + round) >> s);
+ coefs[i] = out * ssign;
+ }
+ }
+}
+
+static av_always_inline SoftFloat flt16_round(SoftFloat pf)
+{
+ SoftFloat tmp;
+ int s;
+
+ tmp.exp = pf.exp;
+ s = pf.mant >> 31;
+ tmp.mant = (pf.mant ^ s) - s;
+ tmp.mant = (tmp.mant + 0x00200000U) & 0xFFC00000U;
+ tmp.mant = (tmp.mant ^ s) - s;
+
+ return tmp;
+}
+
+static av_always_inline SoftFloat flt16_even(SoftFloat pf)
+{
+ SoftFloat tmp;
+ int s;
+
+ tmp.exp = pf.exp;
+ s = pf.mant >> 31;
+ tmp.mant = (pf.mant ^ s) - s;
+ tmp.mant = (tmp.mant + 0x001FFFFFU + (tmp.mant & 0x00400000U >> 16)) & 0xFFC00000U;
+ tmp.mant = (tmp.mant ^ s) - s;
+
+ return tmp;
+}
+
+static av_always_inline SoftFloat flt16_trunc(SoftFloat pf)
+{
+ SoftFloat pun;
+ int s;
+
+ pun.exp = pf.exp;
+ s = pf.mant >> 31;
+ pun.mant = (pf.mant ^ s) - s;
+ pun.mant = pun.mant & 0xFFC00000U;
+ pun.mant = (pun.mant ^ s) - s;
+
+ return pun;
+}
+
+static av_always_inline void predict(PredictorState *ps, int *coef,
+ int output_enable)
+{
+ const SoftFloat a = { 1023410176, 0 }; // 61.0 / 64
+ const SoftFloat alpha = { 973078528, 0 }; // 29.0 / 32
+ SoftFloat e0, e1;
+ SoftFloat pv;
+ SoftFloat k1, k2;
+ SoftFloat r0 = ps->r0, r1 = ps->r1;
+ SoftFloat cor0 = ps->cor0, cor1 = ps->cor1;
+ SoftFloat var0 = ps->var0, var1 = ps->var1;
+ SoftFloat tmp;
+
+ if (var0.exp > 1 || (var0.exp == 1 && var0.mant > 0x20000000)) {
+ k1 = av_mul_sf(cor0, flt16_even(av_div_sf(a, var0)));
+ }
+ else {
+ k1.mant = 0;
+ k1.exp = 0;
+ }
+
+ if (var1.exp > 1 || (var1.exp == 1 && var1.mant > 0x20000000)) {
+ k2 = av_mul_sf(cor1, flt16_even(av_div_sf(a, var1)));
+ }
+ else {
+ k2.mant = 0;
+ k2.exp = 0;
+ }
+
+ tmp = av_mul_sf(k1, r0);
+ pv = flt16_round(av_add_sf(tmp, av_mul_sf(k2, r1)));
+ if (output_enable) {
+ int shift = 28 - pv.exp;
+
+ if (shift < 31)
+ *coef += (pv.mant + (1 << (shift - 1))) >> shift;
+ }
+
+ e0 = av_int2sf(*coef, 2);
+ e1 = av_sub_sf(e0, tmp);
+
+ ps->cor1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor1), av_mul_sf(r1, e1)));
+ tmp = av_add_sf(av_mul_sf(r1, r1), av_mul_sf(e1, e1));
+ tmp.exp--;
+ ps->var1 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var1), tmp));
+ ps->cor0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, cor0), av_mul_sf(r0, e0)));
+ tmp = av_add_sf(av_mul_sf(r0, r0), av_mul_sf(e0, e0));
+ tmp.exp--;
+ ps->var0 = flt16_trunc(av_add_sf(av_mul_sf(alpha, var0), tmp));
+
+ ps->r1 = flt16_trunc(av_mul_sf(a, av_sub_sf(r0, av_mul_sf(k1, e0))));
+ ps->r0 = flt16_trunc(av_mul_sf(a, e0));
+}
+
+
+static const int cce_scale_fixed[8] = {
+ Q30(1.0), //2^(0/8)
+ Q30(1.0905077327), //2^(1/8)
+ Q30(1.1892071150), //2^(2/8)
+ Q30(1.2968395547), //2^(3/8)
+ Q30(1.4142135624), //2^(4/8)
+ Q30(1.5422108254), //2^(5/8)
+ Q30(1.6817928305), //2^(6/8)
+ Q30(1.8340080864), //2^(7/8)
+};
+
+/**
+ * Apply dependent channel coupling (applied before IMDCT).
+ *
+ * @param index index into coupling gain array
+ */
+static void apply_dependent_coupling_fixed(AACContext *ac,
+ SingleChannelElement *target,
+ ChannelElement *cce, int index)
+{
+ IndividualChannelStream *ics = &cce->ch[0].ics;
+ const uint16_t *offsets = ics->swb_offset;
+ int *dest = target->coeffs;
+ const int *src = cce->ch[0].coeffs;
+ int g, i, group, k, idx = 0;
+ if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Dependent coupling is not supported together with LTP\n");
+ return;
+ }
+ for (g = 0; g < ics->num_window_groups; g++) {
+ for (i = 0; i < ics->max_sfb; i++, idx++) {
+ if (cce->ch[0].band_type[idx] != ZERO_BT) {
+ const int gain = cce->coup.gain[index][idx];
+ int shift, round, c, tmp;
+
+ if (gain < 0) {
+ c = -cce_scale_fixed[-gain & 7];
+ shift = (-gain-1024) >> 3;
+ }
+ else {
+ c = cce_scale_fixed[gain & 7];
+ shift = (gain-1024) >> 3;
+ }
+
+ if (shift < -31) {
+ // Nothing to do
+ } else if (shift < 0) {
+ shift = -shift;
+ round = 1 << (shift - 1);
+
+ for (group = 0; group < ics->group_len[g]; group++) {
+ for (k = offsets[i]; k < offsets[i + 1]; k++) {
+ tmp = (int)(((int64_t)src[group * 128 + k] * c + \
+ (int64_t)0x1000000000) >> 37);
+ dest[group * 128 + k] += (tmp + round) >> shift;
+ }
+ }
+ }
+ else {
+ for (group = 0; group < ics->group_len[g]; group++) {
+ for (k = offsets[i]; k < offsets[i + 1]; k++) {
+ tmp = (int)(((int64_t)src[group * 128 + k] * c + \
+ (int64_t)0x1000000000) >> 37);
+ dest[group * 128 + k] += tmp << shift;
+ }
+ }
+ }
+ }
+ }
+ dest += ics->group_len[g] * 128;
+ src += ics->group_len[g] * 128;
+ }
+}
+
+/**
+ * Apply independent channel coupling (applied after IMDCT).
+ *
+ * @param index index into coupling gain array
+ */
+static void apply_independent_coupling_fixed(AACContext *ac,
+ SingleChannelElement *target,
+ ChannelElement *cce, int index)
+{
+ int i, c, shift, round, tmp;
+ const int gain = cce->coup.gain[index][0];
+ const int *src = cce->ch[0].ret;
+ int *dest = target->ret;
+ const int len = 1024 << (ac->oc[1].m4ac.sbr == 1);
+
+ c = cce_scale_fixed[gain & 7];
+ shift = (gain-1024) >> 3;
+ if (shift < 0) {
+ shift = -shift;
+ round = 1 << (shift - 1);
+
+ for (i = 0; i < len; i++) {
+ tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
+ dest[i] += (tmp + round) >> shift;
+ }
+ }
+ else {
+ for (i = 0; i < len; i++) {
+ tmp = (int)(((int64_t)src[i] * c + (int64_t)0x1000000000) >> 37);
+ dest[i] += tmp << shift;
+ }
+ }
+}
+
+#include "aacdec_template.c"
+
+AVCodec ff_aac_fixed_decoder = {
+ .name = "aac_fixed",
+ .long_name = NULL_IF_CONFIG_SMALL("AAC (Advanced Audio Coding)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_AAC,
+ .priv_data_size = sizeof(AACContext),
+ .init = aac_decode_init,
+ .close = aac_decode_close,
+ .decode = aac_decode_frame,
+ .sample_fmts = (const enum AVSampleFormat[]) {
+ AV_SAMPLE_FMT_S32P, AV_SAMPLE_FMT_NONE
+ },
+ .capabilities = AV_CODEC_CAP_CHANNEL_CONF | AV_CODEC_CAP_DR1,
+ .channel_layouts = aac_channel_layout,
+ .flush = flush,
+};
diff --git a/ffmpeg-2-8-12/libavcodec/aacdec_template.c b/ffmpeg-2-8-12/libavcodec/aacdec_template.c
new file mode 100644
index 0000000..2920d06
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/aacdec_template.c
@@ -0,0 +1,3242 @@
+/*
+ * AAC decoder
+ * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org )
+ * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com )
+ * Copyright (c) 2008-2013 Alex Converse <alex.converse at gmail.com>
+ *
+ * AAC LATM decoder
+ * Copyright (c) 2008-2010 Paul Kendall <paul at kcbbs.gen.nz>
+ * Copyright (c) 2010 Janne Grunau <janne-libav at jannau.net>
+ *
+ * AAC decoder fixed-point implementation
+ * Copyright (c) 2013
+ * MIPS Technologies, Inc., California.
+ *
+ * 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
+ * AAC decoder
+ * @author Oded Shimon ( ods15 ods15 dyndns org )
+ * @author Maxim Gavrilov ( maxim.gavrilov gmail com )
+ *
+ * AAC decoder fixed-point implementation
+ * @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com )
+ * @author Nedeljko Babic ( nedeljko.babic imgtec com )
+ */
+
+/*
+ * supported tools
+ *
+ * Support? Name
+ * N (code in SoC repo) gain control
+ * Y block switching
+ * Y window shapes - standard
+ * N window shapes - Low Delay
+ * Y filterbank - standard
+ * N (code in SoC repo) filterbank - Scalable Sample Rate
+ * Y Temporal Noise Shaping
+ * Y Long Term Prediction
+ * Y intensity stereo
+ * Y channel coupling
+ * Y frequency domain prediction
+ * Y Perceptual Noise Substitution
+ * Y Mid/Side stereo
+ * N Scalable Inverse AAC Quantization
+ * N Frequency Selective Switch
+ * N upsampling filter
+ * Y quantization & coding - AAC
+ * N quantization & coding - TwinVQ
+ * N quantization & coding - BSAC
+ * N AAC Error Resilience tools
+ * N Error Resilience payload syntax
+ * N Error Protection tool
+ * N CELP
+ * N Silence Compression
+ * N HVXC
+ * N HVXC 4kbits/s VR
+ * N Structured Audio tools
+ * N Structured Audio Sample Bank Format
+ * N MIDI
+ * N Harmonic and Individual Lines plus Noise
+ * N Text-To-Speech Interface
+ * Y Spectral Band Replication
+ * Y (not in this code) Layer-1
+ * Y (not in this code) Layer-2
+ * Y (not in this code) Layer-3
+ * N SinuSoidal Coding (Transient, Sinusoid, Noise)
+ * Y Parametric Stereo
+ * N Direct Stream Transfer
+ * Y (not in fixed point code) Enhanced AAC Low Delay (ER AAC ELD)
+ *
+ * Note: - HE AAC v1 comprises LC AAC with Spectral Band Replication.
+ * - HE AAC v2 comprises LC AAC with Spectral Band Replication and
+ Parametric Stereo.
+ */
+
+static VLC vlc_scalefactors;
+static VLC vlc_spectral[11];
+
+static int output_configure(AACContext *ac,
+ uint8_t layout_map[MAX_ELEM_ID*4][3], int tags,
+ enum OCStatus oc_type, int get_new_frame);
+
+#define overread_err "Input buffer exhausted before END element found\n"
+
+static int count_channels(uint8_t (*layout)[3], int tags)
+{
+ int i, sum = 0;
+ for (i = 0; i < tags; i++) {
+ int syn_ele = layout[i][0];
+ int pos = layout[i][2];
+ sum += (1 + (syn_ele == TYPE_CPE)) *
+ (pos != AAC_CHANNEL_OFF && pos != AAC_CHANNEL_CC);
+ }
+ return sum;
+}
+
+/**
+ * Check for the channel element in the current channel position configuration.
+ * If it exists, make sure the appropriate element is allocated and map the
+ * channel order to match the internal FFmpeg channel layout.
+ *
+ * @param che_pos current channel position configuration
+ * @param type channel element type
+ * @param id channel element id
+ * @param channels count of the number of channels in the configuration
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static av_cold int che_configure(AACContext *ac,
+ enum ChannelPosition che_pos,
+ int type, int id, int *channels)
+{
+ if (*channels >= MAX_CHANNELS)
+ return AVERROR_INVALIDDATA;
+ if (che_pos) {
+ if (!ac->che[type][id]) {
+ if (!(ac->che[type][id] = av_mallocz(sizeof(ChannelElement))))
+ return AVERROR(ENOMEM);
+ AAC_RENAME(ff_aac_sbr_ctx_init)(ac, &ac->che[type][id]->sbr);
+ }
+ if (type != TYPE_CCE) {
+ if (*channels >= MAX_CHANNELS - (type == TYPE_CPE || (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1))) {
+ av_log(ac->avctx, AV_LOG_ERROR, "Too many channels\n");
+ return AVERROR_INVALIDDATA;
+ }
+ ac->output_element[(*channels)++] = &ac->che[type][id]->ch[0];
+ if (type == TYPE_CPE ||
+ (type == TYPE_SCE && ac->oc[1].m4ac.ps == 1)) {
+ ac->output_element[(*channels)++] = &ac->che[type][id]->ch[1];
+ }
+ }
+ } else {
+ if (ac->che[type][id])
+ AAC_RENAME(ff_aac_sbr_ctx_close)(&ac->che[type][id]->sbr);
+ av_freep(&ac->che[type][id]);
+ }
+ return 0;
+}
+
+static int frame_configure_elements(AVCodecContext *avctx)
+{
+ AACContext *ac = avctx->priv_data;
+ int type, id, ch, ret;
+
+ /* set channel pointers to internal buffers by default */
+ for (type = 0; type < 4; type++) {
+ for (id = 0; id < MAX_ELEM_ID; id++) {
+ ChannelElement *che = ac->che[type][id];
+ if (che) {
+ che->ch[0].ret = che->ch[0].ret_buf;
+ che->ch[1].ret = che->ch[1].ret_buf;
+ }
+ }
+ }
+
+ /* get output buffer */
+ av_frame_unref(ac->frame);
+ if (!avctx->channels)
+ return 1;
+
+ ac->frame->nb_samples = 2048;
+ if ((ret = ff_get_buffer(avctx, ac->frame, 0)) < 0)
+ return ret;
+
+ /* map output channel pointers to AVFrame data */
+ for (ch = 0; ch < avctx->channels; ch++) {
+ if (ac->output_element[ch])
+ ac->output_element[ch]->ret = (INTFLOAT *)ac->frame->extended_data[ch];
+ }
+
+ return 0;
+}
+
+struct elem_to_channel {
+ uint64_t av_position;
+ uint8_t syn_ele;
+ uint8_t elem_id;
+ uint8_t aac_position;
+};
+
+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)
+{
+ if (layout_map[offset][0] == TYPE_CPE) {
+ e2c_vec[offset] = (struct elem_to_channel) {
+ .av_position = left | right,
+ .syn_ele = TYPE_CPE,
+ .elem_id = layout_map[offset][1],
+ .aac_position = pos
+ };
+ return 1;
+ } else {
+ e2c_vec[offset] = (struct elem_to_channel) {
+ .av_position = left,
+ .syn_ele = TYPE_SCE,
+ .elem_id = layout_map[offset][1],
+ .aac_position = pos
+ };
+ e2c_vec[offset + 1] = (struct elem_to_channel) {
+ .av_position = right,
+ .syn_ele = TYPE_SCE,
+ .elem_id = layout_map[offset + 1][1],
+ .aac_position = pos
+ };
+ return 2;
+ }
+}
+
+static int count_paired_channels(uint8_t (*layout_map)[3], int tags, int pos,
+ int *current)
+{
+ int num_pos_channels = 0;
+ int first_cpe = 0;
+ int sce_parity = 0;
+ int i;
+ for (i = *current; i < tags; i++) {
+ if (layout_map[i][2] != pos)
+ break;
+ if (layout_map[i][0] == TYPE_CPE) {
+ if (sce_parity) {
+ if (pos == AAC_CHANNEL_FRONT && !first_cpe) {
+ sce_parity = 0;
+ } else {
+ return -1;
+ }
+ }
+ num_pos_channels += 2;
+ first_cpe = 1;
+ } else {
+ num_pos_channels++;
+ sce_parity ^= 1;
+ }
+ }
+ if (sce_parity &&
+ ((pos == AAC_CHANNEL_FRONT && first_cpe) || pos == AAC_CHANNEL_SIDE))
+ return -1;
+ *current = i;
+ return num_pos_channels;
+}
+
+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;
+
+ if (FF_ARRAY_ELEMS(e2c_vec) < tags)
+ return 0;
+
+ i = 0;
+ num_front_channels =
+ count_paired_channels(layout_map, tags, AAC_CHANNEL_FRONT, &i);
+ if (num_front_channels < 0)
+ return 0;
+ num_side_channels =
+ count_paired_channels(layout_map, tags, AAC_CHANNEL_SIDE, &i);
+ if (num_side_channels < 0)
+ return 0;
+ num_back_channels =
+ count_paired_channels(layout_map, tags, AAC_CHANNEL_BACK, &i);
+ if (num_back_channels < 0)
+ return 0;
+
+ if (num_side_channels == 0 && num_back_channels >= 4) {
+ num_side_channels = 2;
+ num_back_channels -= 2;
+ }
+
+ i = 0;
+ if (num_front_channels & 1) {
+ e2c_vec[i] = (struct elem_to_channel) {
+ .av_position = AV_CH_FRONT_CENTER,
+ .syn_ele = TYPE_SCE,
+ .elem_id = layout_map[i][1],
+ .aac_position = AAC_CHANNEL_FRONT
+ };
+ i++;
+ num_front_channels--;
+ }
+ if (num_front_channels >= 4) {
+ i += assign_pair(e2c_vec, layout_map, i,
+ AV_CH_FRONT_LEFT_OF_CENTER,
+ AV_CH_FRONT_RIGHT_OF_CENTER,
+ AAC_CHANNEL_FRONT);
+ 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);
+ num_front_channels -= 2;
+ }
+ while (num_front_channels >= 2) {
+ i += assign_pair(e2c_vec, layout_map, i,
+ UINT64_MAX,
+ UINT64_MAX,
+ AAC_CHANNEL_FRONT);
+ num_front_channels -= 2;
+ }
+
+ if (num_side_channels >= 2) {
+ i += assign_pair(e2c_vec, layout_map, i,
+ AV_CH_SIDE_LEFT,
+ AV_CH_SIDE_RIGHT,
+ AAC_CHANNEL_FRONT);
+ num_side_channels -= 2;
+ }
+ while (num_side_channels >= 2) {
+ i += assign_pair(e2c_vec, layout_map, i,
+ UINT64_MAX,
+ UINT64_MAX,
+ AAC_CHANNEL_SIDE);
+ num_side_channels -= 2;
+ }
+
+ while (num_back_channels >= 4) {
+ i += assign_pair(e2c_vec, layout_map, i,
+ UINT64_MAX,
+ UINT64_MAX,
+ AAC_CHANNEL_BACK);
+ 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);
+ num_back_channels -= 2;
+ }
+ if (num_back_channels) {
+ e2c_vec[i] = (struct elem_to_channel) {
+ .av_position = AV_CH_BACK_CENTER,
+ .syn_ele = TYPE_SCE,
+ .elem_id = layout_map[i][1],
+ .aac_position = AAC_CHANNEL_BACK
+ };
+ i++;
+ num_back_channels--;
+ }
+
+ if (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) {
+ e2c_vec[i] = (struct elem_to_channel) {
+ .av_position = AV_CH_LOW_FREQUENCY,
+ .syn_ele = TYPE_LFE,
+ .elem_id = layout_map[i][1],
+ .aac_position = AAC_CHANNEL_LFE
+ };
+ i++;
+ }
+ while (i < tags && layout_map[i][2] == AAC_CHANNEL_LFE) {
+ e2c_vec[i] = (struct elem_to_channel) {
+ .av_position = UINT64_MAX,
+ .syn_ele = TYPE_LFE,
+ .elem_id = layout_map[i][1],
+ .aac_position = AAC_CHANNEL_LFE
+ };
+ i++;
+ }
+
+ // Must choose a stable sort
+ 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);
+
+ 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;
+}
+
+/**
+ * Save current output configuration if and only if it has been locked.
+ */
+static void push_output_configuration(AACContext *ac) {
+ if (ac->oc[1].status == OC_LOCKED || ac->oc[0].status == OC_NONE) {
+ ac->oc[0] = ac->oc[1];
+ }
+ ac->oc[1].status = OC_NONE;
+}
+
+/**
+ * Restore the previous output configuration if and only if the current
+ * configuration is unlocked.
+ */
+static void pop_output_configuration(AACContext *ac) {
+ if (ac->oc[1].status != OC_LOCKED && ac->oc[0].status != OC_NONE) {
+ ac->oc[1] = ac->oc[0];
+ ac->avctx->channels = ac->oc[1].channels;
+ ac->avctx->channel_layout = ac->oc[1].channel_layout;
+ output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags,
+ ac->oc[1].status, 0);
+ }
+}
+
+/**
+ * Configure output channel order based on the current program
+ * configuration element.
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int output_configure(AACContext *ac,
+ uint8_t layout_map[MAX_ELEM_ID * 4][3], int tags,
+ enum OCStatus oc_type, int get_new_frame)
+{
+ AVCodecContext *avctx = ac->avctx;
+ int i, channels = 0, ret;
+ uint64_t layout = 0;
+ uint8_t id_map[TYPE_END][MAX_ELEM_ID] = {{ 0 }};
+ uint8_t type_counts[TYPE_END] = { 0 };
+
+ if (ac->oc[1].layout_map != layout_map) {
+ memcpy(ac->oc[1].layout_map, layout_map, tags * sizeof(layout_map[0]));
+ ac->oc[1].layout_map_tags = tags;
+ }
+ for (i = 0; i < tags; i++) {
+ int type = layout_map[i][0];
+ int id = layout_map[i][1];
+ id_map[type][id] = type_counts[type]++;
+ if (id_map[type][id] >= MAX_ELEM_ID) {
+ avpriv_request_sample(ac->avctx, "Remapped id too large\n");
+ return AVERROR_PATCHWELCOME;
+ }
+ }
+ // Try to sniff a reasonable channel order, otherwise output the
+ // channels in the order the PCE declared them.
+ if (avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE)
+ layout = sniff_channel_order(layout_map, tags);
+ for (i = 0; i < tags; i++) {
+ int type = layout_map[i][0];
+ int id = layout_map[i][1];
+ int iid = id_map[type][id];
+ int position = layout_map[i][2];
+ // Allocate or free elements depending on if they are in the
+ // current program configuration.
+ ret = che_configure(ac, position, type, iid, &channels);
+ if (ret < 0)
+ return ret;
+ ac->tag_che_map[type][id] = ac->che[type][iid];
+ }
+ if (ac->oc[1].m4ac.ps == 1 && channels == 2) {
+ if (layout == AV_CH_FRONT_CENTER) {
+ layout = AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT;
+ } else {
+ layout = 0;
+ }
+ }
+
+ if (layout) avctx->channel_layout = layout;
+ ac->oc[1].channel_layout = layout;
+ avctx->channels = ac->oc[1].channels = channels;
+ ac->oc[1].status = oc_type;
+
+ if (get_new_frame) {
+ if ((ret = frame_configure_elements(ac->avctx)) < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static void flush(AVCodecContext *avctx)
+{
+ AACContext *ac= avctx->priv_data;
+ int type, i, j;
+
+ for (type = 3; type >= 0; type--) {
+ for (i = 0; i < MAX_ELEM_ID; i++) {
+ ChannelElement *che = ac->che[type][i];
+ if (che) {
+ for (j = 0; j <= 1; j++) {
+ memset(che->ch[j].saved, 0, sizeof(che->ch[j].saved));
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Set up channel positions based on a default channel configuration
+ * as specified in table 1.17.
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int set_default_channel_config(AVCodecContext *avctx,
+ uint8_t (*layout_map)[3],
+ int *tags,
+ int channel_config)
+{
+ if (channel_config < 1 || (channel_config > 7 && channel_config < 11) ||
+ channel_config > 12) {
+ av_log(avctx, AV_LOG_ERROR,
+ "invalid default channel configuration (%d)\n",
+ channel_config);
+ return AVERROR_INVALIDDATA;
+ }
+ *tags = tags_per_config[channel_config];
+ memcpy(layout_map, aac_channel_layout_map[channel_config - 1],
+ *tags * sizeof(*layout_map));
+
+ /*
+ * AAC specification has 7.1(wide) as a default layout for 8-channel streams.
+ * However, at least Nero AAC encoder encodes 7.1 streams using the default
+ * channel config 7, mapping the side channels of the original audio stream
+ * to the second AAC_CHANNEL_FRONT pair in the AAC stream. Similarly, e.g. FAAD
+ * decodes the second AAC_CHANNEL_FRONT pair as side channels, therefore decoding
+ * the incorrect streams as if they were correct (and as the encoder intended).
+ *
+ * As actual intended 7.1(wide) streams are very rare, default to assuming a
+ * 7.1 layout was intended.
+ */
+ if (channel_config == 7 && avctx->strict_std_compliance < FF_COMPLIANCE_STRICT) {
+ av_log(avctx, AV_LOG_INFO, "Assuming an incorrectly encoded 7.1 channel layout"
+ " instead of a spec-compliant 7.1(wide) layout, use -strict %d to decode"
+ " according to the specification instead.\n", FF_COMPLIANCE_STRICT);
+ layout_map[2][2] = AAC_CHANNEL_SIDE;
+ }
+
+ return 0;
+}
+
+static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
+{
+ /* For PCE based channel configurations map the channels solely based
+ * on tags. */
+ if (!ac->oc[1].m4ac.chan_config) {
+ return ac->tag_che_map[type][elem_id];
+ }
+ // Allow single CPE stereo files to be signalled with mono configuration.
+ if (!ac->tags_mapped && type == TYPE_CPE &&
+ ac->oc[1].m4ac.chan_config == 1) {
+ uint8_t layout_map[MAX_ELEM_ID*4][3];
+ int layout_map_tags;
+ push_output_configuration(ac);
+
+ av_log(ac->avctx, AV_LOG_DEBUG, "mono with CPE\n");
+
+ if (set_default_channel_config(ac->avctx, layout_map,
+ &layout_map_tags, 2) < 0)
+ return NULL;
+ if (output_configure(ac, layout_map, layout_map_tags,
+ OC_TRIAL_FRAME, 1) < 0)
+ return NULL;
+
+ ac->oc[1].m4ac.chan_config = 2;
+ ac->oc[1].m4ac.ps = 0;
+ }
+ // And vice-versa
+ if (!ac->tags_mapped && type == TYPE_SCE &&
+ ac->oc[1].m4ac.chan_config == 2) {
+ uint8_t layout_map[MAX_ELEM_ID * 4][3];
+ int layout_map_tags;
+ push_output_configuration(ac);
+
+ av_log(ac->avctx, AV_LOG_DEBUG, "stereo with SCE\n");
+
+ if (set_default_channel_config(ac->avctx, layout_map,
+ &layout_map_tags, 1) < 0)
+ return NULL;
+ if (output_configure(ac, layout_map, layout_map_tags,
+ OC_TRIAL_FRAME, 1) < 0)
+ return NULL;
+
+ ac->oc[1].m4ac.chan_config = 1;
+ if (ac->oc[1].m4ac.sbr)
+ ac->oc[1].m4ac.ps = -1;
+ }
+ /* For indexed channel configurations map the channels solely based
+ * on position. */
+ switch (ac->oc[1].m4ac.chan_config) {
+ case 12:
+ case 7:
+ if (ac->tags_mapped == 3 && type == TYPE_CPE) {
+ ac->tags_mapped++;
+ return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][2];
+ }
+ case 11:
+ if (ac->tags_mapped == 2 &&
+ ac->oc[1].m4ac.chan_config == 11 &&
+ type == TYPE_SCE) {
+ ac->tags_mapped++;
+ return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1];
+ }
+ case 6:
+ /* Some streams incorrectly code 5.1 audio as
+ * SCE[0] CPE[0] CPE[1] SCE[1]
+ * instead of
+ * SCE[0] CPE[0] CPE[1] LFE[0].
+ * If we seem to have encountered such a stream, transfer
+ * the LFE[0] element to the SCE[1]'s mapping */
+ if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) {
+ if (!ac->warned_remapping_once && (type != TYPE_LFE || elem_id != 0)) {
+ av_log(ac->avctx, AV_LOG_WARNING,
+ "This stream seems to incorrectly report its last channel as %s[%d], mapping to LFE[0]\n",
+ type == TYPE_SCE ? "SCE" : "LFE", elem_id);
+ ac->warned_remapping_once++;
+ }
+ ac->tags_mapped++;
+ return ac->tag_che_map[type][elem_id] = ac->che[TYPE_LFE][0];
+ }
+ case 5:
+ if (ac->tags_mapped == 2 && type == TYPE_CPE) {
+ ac->tags_mapped++;
+ return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][1];
+ }
+ case 4:
+ /* Some streams incorrectly code 4.0 audio as
+ * SCE[0] CPE[0] LFE[0]
+ * instead of
+ * SCE[0] CPE[0] SCE[1].
+ * If we seem to have encountered such a stream, transfer
+ * the SCE[1] element to the LFE[0]'s mapping */
+ if (ac->tags_mapped == tags_per_config[ac->oc[1].m4ac.chan_config] - 1 && (type == TYPE_LFE || type == TYPE_SCE)) {
+ if (!ac->warned_remapping_once && (type != TYPE_SCE || elem_id != 1)) {
+ av_log(ac->avctx, AV_LOG_WARNING,
+ "This stream seems to incorrectly report its last channel as %s[%d], mapping to SCE[1]\n",
+ type == TYPE_SCE ? "SCE" : "LFE", elem_id);
+ ac->warned_remapping_once++;
+ }
+ ac->tags_mapped++;
+ return ac->tag_che_map[type][elem_id] = ac->che[TYPE_SCE][1];
+ }
+ if (ac->tags_mapped == 2 &&
+ ac->oc[1].m4ac.chan_config == 4 &&
+ type == TYPE_SCE) {
+ ac->tags_mapped++;
+ return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][1];
+ }
+ case 3:
+ case 2:
+ if (ac->tags_mapped == (ac->oc[1].m4ac.chan_config != 2) &&
+ type == TYPE_CPE) {
+ ac->tags_mapped++;
+ return ac->tag_che_map[TYPE_CPE][elem_id] = ac->che[TYPE_CPE][0];
+ } else if (ac->oc[1].m4ac.chan_config == 2) {
+ return NULL;
+ }
+ case 1:
+ if (!ac->tags_mapped && type == TYPE_SCE) {
+ ac->tags_mapped++;
+ return ac->tag_che_map[TYPE_SCE][elem_id] = ac->che[TYPE_SCE][0];
+ }
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Decode an array of 4 bit element IDs, optionally interleaved with a
+ * stereo/mono switching bit.
+ *
+ * @param type speaker type/position for these channels
+ */
+static void decode_channel_map(uint8_t layout_map[][3],
+ enum ChannelPosition type,
+ GetBitContext *gb, int n)
+{
+ while (n--) {
+ enum RawDataBlockType syn_ele;
+ switch (type) {
+ case AAC_CHANNEL_FRONT:
+ case AAC_CHANNEL_BACK:
+ case AAC_CHANNEL_SIDE:
+ syn_ele = get_bits1(gb);
+ break;
+ case AAC_CHANNEL_CC:
+ skip_bits1(gb);
+ syn_ele = TYPE_CCE;
+ break;
+ case AAC_CHANNEL_LFE:
+ syn_ele = TYPE_LFE;
+ break;
+ default:
+ // AAC_CHANNEL_OFF has no channel map
+ av_assert0(0);
+ }
+ layout_map[0][0] = syn_ele;
+ layout_map[0][1] = get_bits(gb, 4);
+ layout_map[0][2] = type;
+ layout_map++;
+ }
+}
+
+/**
+ * Decode program configuration element; reference: table 4.2.
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac,
+ uint8_t (*layout_map)[3],
+ GetBitContext *gb)
+{
+ int num_front, num_side, num_back, num_lfe, num_assoc_data, num_cc;
+ int sampling_index;
+ int comment_len;
+ int tags;
+
+ skip_bits(gb, 2); // object_type
+
+ sampling_index = get_bits(gb, 4);
+ if (m4ac->sampling_index != sampling_index)
+ av_log(avctx, AV_LOG_WARNING,
+ "Sample rate index in program config element does not "
+ "match the sample rate index configured by the container.\n");
+
+ num_front = get_bits(gb, 4);
+ num_side = get_bits(gb, 4);
+ num_back = get_bits(gb, 4);
+ num_lfe = get_bits(gb, 2);
+ num_assoc_data = get_bits(gb, 3);
+ num_cc = get_bits(gb, 4);
+
+ if (get_bits1(gb))
+ skip_bits(gb, 4); // mono_mixdown_tag
+ if (get_bits1(gb))
+ skip_bits(gb, 4); // stereo_mixdown_tag
+
+ if (get_bits1(gb))
+ skip_bits(gb, 3); // mixdown_coeff_index and pseudo_surround
+
+ if (get_bits_left(gb) < 4 * (num_front + num_side + num_back + num_lfe + num_assoc_data + num_cc)) {
+ av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err);
+ return -1;
+ }
+ decode_channel_map(layout_map , AAC_CHANNEL_FRONT, gb, num_front);
+ tags = num_front;
+ decode_channel_map(layout_map + tags, AAC_CHANNEL_SIDE, gb, num_side);
+ tags += num_side;
+ decode_channel_map(layout_map + tags, AAC_CHANNEL_BACK, gb, num_back);
+ tags += num_back;
+ decode_channel_map(layout_map + tags, AAC_CHANNEL_LFE, gb, num_lfe);
+ tags += num_lfe;
+
+ skip_bits_long(gb, 4 * num_assoc_data);
+
+ decode_channel_map(layout_map + tags, AAC_CHANNEL_CC, gb, num_cc);
+ tags += num_cc;
+
+ align_get_bits(gb);
+
+ /* comment field, first byte is length */
+ comment_len = get_bits(gb, 8) * 8;
+ if (get_bits_left(gb) < comment_len) {
+ av_log(avctx, AV_LOG_ERROR, "decode_pce: " overread_err);
+ return AVERROR_INVALIDDATA;
+ }
+ skip_bits_long(gb, comment_len);
+ return tags;
+}
+
+/**
+ * Decode GA "General Audio" specific configuration; reference: table 4.1.
+ *
+ * @param ac pointer to AACContext, may be null
+ * @param avctx pointer to AVCCodecContext, used for logging
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int decode_ga_specific_config(AACContext *ac, AVCodecContext *avctx,
+ GetBitContext *gb,
+ MPEG4AudioConfig *m4ac,
+ int channel_config)
+{
+ int extension_flag, ret, ep_config, res_flags;
+ uint8_t layout_map[MAX_ELEM_ID*4][3];
+ int tags = 0;
+
+ if (get_bits1(gb)) { // frameLengthFlag
+ avpriv_request_sample(avctx, "960/120 MDCT window");
+ return AVERROR_PATCHWELCOME;
+ }
+ m4ac->frame_length_short = 0;
+
+ if (get_bits1(gb)) // dependsOnCoreCoder
+ skip_bits(gb, 14); // coreCoderDelay
+ extension_flag = get_bits1(gb);
+
+ if (m4ac->object_type == AOT_AAC_SCALABLE ||
+ m4ac->object_type == AOT_ER_AAC_SCALABLE)
+ skip_bits(gb, 3); // layerNr
+
+ if (channel_config == 0) {
+ skip_bits(gb, 4); // element_instance_tag
+ tags = decode_pce(avctx, m4ac, layout_map, gb);
+ if (tags < 0)
+ return tags;
+ } else {
+ if ((ret = set_default_channel_config(avctx, layout_map,
+ &tags, channel_config)))
+ return ret;
+ }
+
+ if (count_channels(layout_map, tags) > 1) {
+ m4ac->ps = 0;
+ } else if (m4ac->sbr == 1 && m4ac->ps == -1)
+ m4ac->ps = 1;
+
+ if (ac && (ret = output_configure(ac, layout_map, tags, OC_GLOBAL_HDR, 0)))
+ return ret;
+
+ if (extension_flag) {
+ switch (m4ac->object_type) {
+ case AOT_ER_BSAC:
+ skip_bits(gb, 5); // numOfSubFrame
+ skip_bits(gb, 11); // layer_length
+ break;
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_LTP:
+ case AOT_ER_AAC_SCALABLE:
+ case AOT_ER_AAC_LD:
+ res_flags = get_bits(gb, 3);
+ if (res_flags) {
+ avpriv_report_missing_feature(avctx,
+ "AAC data resilience (flags %x)",
+ res_flags);
+ return AVERROR_PATCHWELCOME;
+ }
+ break;
+ }
+ skip_bits1(gb); // extensionFlag3 (TBD in version 3)
+ }
+ switch (m4ac->object_type) {
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_LTP:
+ case AOT_ER_AAC_SCALABLE:
+ case AOT_ER_AAC_LD:
+ ep_config = get_bits(gb, 2);
+ if (ep_config) {
+ avpriv_report_missing_feature(avctx,
+ "epConfig %d", ep_config);
+ return AVERROR_PATCHWELCOME;
+ }
+ }
+ return 0;
+}
+
+static int decode_eld_specific_config(AACContext *ac, AVCodecContext *avctx,
+ GetBitContext *gb,
+ MPEG4AudioConfig *m4ac,
+ int channel_config)
+{
+ int ret, ep_config, res_flags;
+ uint8_t layout_map[MAX_ELEM_ID*4][3];
+ int tags = 0;
+ const int ELDEXT_TERM = 0;
+
+ m4ac->ps = 0;
+ m4ac->sbr = 0;
+#if USE_FIXED
+ if (get_bits1(gb)) { // frameLengthFlag
+ avpriv_request_sample(avctx, "960/120 MDCT window");
+ return AVERROR_PATCHWELCOME;
+ }
+#else
+ m4ac->frame_length_short = get_bits1(gb);
+#endif
+ res_flags = get_bits(gb, 3);
+ if (res_flags) {
+ avpriv_report_missing_feature(avctx,
+ "AAC data resilience (flags %x)",
+ res_flags);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if (get_bits1(gb)) { // ldSbrPresentFlag
+ avpriv_report_missing_feature(avctx,
+ "Low Delay SBR");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ while (get_bits(gb, 4) != ELDEXT_TERM) {
+ int len = get_bits(gb, 4);
+ if (len == 15)
+ len += get_bits(gb, 8);
+ if (len == 15 + 255)
+ len += get_bits(gb, 16);
+ if (get_bits_left(gb) < len * 8 + 4) {
+ av_log(avctx, AV_LOG_ERROR, overread_err);
+ return AVERROR_INVALIDDATA;
+ }
+ skip_bits_long(gb, 8 * len);
+ }
+
+ if ((ret = set_default_channel_config(avctx, layout_map,
+ &tags, channel_config)))
+ return ret;
+
+ if (ac && (ret = output_configure(ac, layout_map, tags, OC_GLOBAL_HDR, 0)))
+ return ret;
+
+ ep_config = get_bits(gb, 2);
+ if (ep_config) {
+ avpriv_report_missing_feature(avctx,
+ "epConfig %d", ep_config);
+ return AVERROR_PATCHWELCOME;
+ }
+ return 0;
+}
+
+/**
+ * Decode audio specific configuration; reference: table 1.13.
+ *
+ * @param ac pointer to AACContext, may be null
+ * @param avctx pointer to AVCCodecContext, used for logging
+ * @param m4ac pointer to MPEG4AudioConfig, used for parsing
+ * @param data pointer to buffer holding an audio specific config
+ * @param bit_size size of audio specific config or data in bits
+ * @param sync_extension look for an appended sync extension
+ *
+ * @return Returns error status or number of consumed bits. <0 - error
+ */
+static int decode_audio_specific_config(AACContext *ac,
+ AVCodecContext *avctx,
+ MPEG4AudioConfig *m4ac,
+ const uint8_t *data, int64_t bit_size,
+ int sync_extension)
+{
+ GetBitContext gb;
+ int i, ret;
+
+ if (bit_size < 0 || bit_size > INT_MAX) {
+ av_log(avctx, AV_LOG_ERROR, "Audio specific config size is invalid\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ ff_dlog(avctx, "audio specific config size %d\n", (int)bit_size >> 3);
+ for (i = 0; i < bit_size >> 3; i++)
+ ff_dlog(avctx, "%02x ", data[i]);
+ ff_dlog(avctx, "\n");
+
+ if ((ret = init_get_bits(&gb, data, bit_size)) < 0)
+ return ret;
+
+ if ((i = avpriv_mpeg4audio_get_config(m4ac, data, bit_size,
+ sync_extension)) < 0)
+ return AVERROR_INVALIDDATA;
+ if (m4ac->sampling_index > 12) {
+ av_log(avctx, AV_LOG_ERROR,
+ "invalid sampling rate index %d\n",
+ m4ac->sampling_index);
+ return AVERROR_INVALIDDATA;
+ }
+ if (m4ac->object_type == AOT_ER_AAC_LD &&
+ (m4ac->sampling_index < 3 || m4ac->sampling_index > 7)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "invalid low delay sampling rate index %d\n",
+ m4ac->sampling_index);
+ return AVERROR_INVALIDDATA;
+ }
+
+ skip_bits_long(&gb, i);
+
+ switch (m4ac->object_type) {
+ case AOT_AAC_MAIN:
+ case AOT_AAC_LC:
+ case AOT_AAC_LTP:
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_LD:
+ if ((ret = decode_ga_specific_config(ac, avctx, &gb,
+ m4ac, m4ac->chan_config)) < 0)
+ return ret;
+ break;
+ case AOT_ER_AAC_ELD:
+ if ((ret = decode_eld_specific_config(ac, avctx, &gb,
+ m4ac, m4ac->chan_config)) < 0)
+ return ret;
+ break;
+ default:
+ avpriv_report_missing_feature(avctx,
+ "Audio object type %s%d",
+ m4ac->sbr == 1 ? "SBR+" : "",
+ m4ac->object_type);
+ return AVERROR(ENOSYS);
+ }
+
+ ff_dlog(avctx,
+ "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n",
+ m4ac->object_type, m4ac->chan_config, m4ac->sampling_index,
+ m4ac->sample_rate, m4ac->sbr,
+ m4ac->ps);
+
+ return get_bits_count(&gb);
+}
+
+/**
+ * linear congruential pseudorandom number generator
+ *
+ * @param previous_val pointer to the current state of the generator
+ *
+ * @return Returns a 32-bit pseudorandom integer
+ */
+static av_always_inline int lcg_random(unsigned previous_val)
+{
+ union { unsigned u; int s; } v = { previous_val * 1664525u + 1013904223 };
+ return v.s;
+}
+
+static void reset_all_predictors(PredictorState *ps)
+{
+ int i;
+ for (i = 0; i < MAX_PREDICTORS; i++)
+ reset_predict_state(&ps[i]);
+}
+
+static int sample_rate_idx (int rate)
+{
+ if (92017 <= rate) return 0;
+ else if (75132 <= rate) return 1;
+ else if (55426 <= rate) return 2;
+ else if (46009 <= rate) return 3;
+ else if (37566 <= rate) return 4;
+ else if (27713 <= rate) return 5;
+ else if (23004 <= rate) return 6;
+ else if (18783 <= rate) return 7;
+ else if (13856 <= rate) return 8;
+ else if (11502 <= rate) return 9;
+ else if (9391 <= rate) return 10;
+ else return 11;
+}
+
+static void reset_predictor_group(PredictorState *ps, int group_num)
+{
+ int i;
+ for (i = group_num - 1; i < MAX_PREDICTORS; i += 30)
+ 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 int aac_decode_init(AVCodecContext *avctx)
+{
+ AACContext *ac = avctx->priv_data;
+ int ret;
+
+ ac->avctx = avctx;
+ ac->oc[1].m4ac.sample_rate = avctx->sample_rate;
+
+ aacdec_init(ac);
+#if USE_FIXED
+ avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
+#else
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
+#endif /* USE_FIXED */
+
+ if (avctx->extradata_size > 0) {
+ if ((ret = decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
+ avctx->extradata,
+ avctx->extradata_size * 8LL,
+ 1)) < 0)
+ return ret;
+ } else {
+ int sr, i;
+ uint8_t layout_map[MAX_ELEM_ID*4][3];
+ int layout_map_tags;
+
+ sr = sample_rate_idx(avctx->sample_rate);
+ ac->oc[1].m4ac.sampling_index = sr;
+ ac->oc[1].m4ac.channels = avctx->channels;
+ ac->oc[1].m4ac.sbr = -1;
+ ac->oc[1].m4ac.ps = -1;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(ff_mpeg4audio_channels); i++)
+ if (ff_mpeg4audio_channels[i] == avctx->channels)
+ break;
+ if (i == FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) {
+ i = 0;
+ }
+ ac->oc[1].m4ac.chan_config = i;
+
+ if (ac->oc[1].m4ac.chan_config) {
+ int ret = set_default_channel_config(avctx, layout_map,
+ &layout_map_tags, ac->oc[1].m4ac.chan_config);
+ if (!ret)
+ output_configure(ac, layout_map, layout_map_tags,
+ OC_GLOBAL_HDR, 0);
+ else if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if (avctx->channels > MAX_CHANNELS) {
+ av_log(avctx, AV_LOG_ERROR, "Too many channels\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ 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);
+
+ AAC_RENAME(ff_aac_sbr_init)();
+
+#if USE_FIXED
+ ac->fdsp = avpriv_alloc_fixed_dsp(avctx->flags & AV_CODEC_FLAG_BITEXACT);
+#else
+ ac->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT);
+#endif /* USE_FIXED */
+ if (!ac->fdsp) {
+ return AVERROR(ENOMEM);
+ }
+
+ ac->random_state = 0x1f2e3d4c;
+
+ ff_aac_tableinit();
+
+ INIT_VLC_STATIC(&vlc_scalefactors, 7,
+ FF_ARRAY_ELEMS(ff_aac_scalefactor_code),
+ ff_aac_scalefactor_bits,
+ sizeof(ff_aac_scalefactor_bits[0]),
+ sizeof(ff_aac_scalefactor_bits[0]),
+ ff_aac_scalefactor_code,
+ sizeof(ff_aac_scalefactor_code[0]),
+ sizeof(ff_aac_scalefactor_code[0]),
+ 352);
+
+ AAC_RENAME_32(ff_mdct_init)(&ac->mdct, 11, 1, 1.0 / RANGE15(1024.0));
+ AAC_RENAME_32(ff_mdct_init)(&ac->mdct_ld, 10, 1, 1.0 / RANGE15(512.0));
+ AAC_RENAME_32(ff_mdct_init)(&ac->mdct_small, 8, 1, 1.0 / RANGE15(128.0));
+ AAC_RENAME_32(ff_mdct_init)(&ac->mdct_ltp, 11, 0, RANGE15(-2.0));
+#if !USE_FIXED
+ ret = ff_imdct15_init(&ac->mdct480, 5);
+ if (ret < 0)
+ return ret;
+#endif
+ // 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);
+ 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(cbrt_tableinit)();
+
+ return 0;
+}
+
+/**
+ * Skip data_stream_element; reference: table 4.10.
+ */
+static int skip_data_stream_element(AACContext *ac, GetBitContext *gb)
+{
+ int byte_align = get_bits1(gb);
+ int count = get_bits(gb, 8);
+ if (count == 255)
+ count += get_bits(gb, 8);
+ if (byte_align)
+ align_get_bits(gb);
+
+ if (get_bits_left(gb) < 8 * count) {
+ av_log(ac->avctx, AV_LOG_ERROR, "skip_data_stream_element: "overread_err);
+ return AVERROR_INVALIDDATA;
+ }
+ skip_bits_long(gb, 8 * count);
+ return 0;
+}
+
+static int decode_prediction(AACContext *ac, IndividualChannelStream *ics,
+ GetBitContext *gb)
+{
+ int sfb;
+ if (get_bits1(gb)) {
+ ics->predictor_reset_group = get_bits(gb, 5);
+ if (ics->predictor_reset_group == 0 ||
+ ics->predictor_reset_group > 30) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Invalid Predictor Reset Group.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ for (sfb = 0; sfb < FFMIN(ics->max_sfb, ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index]); sfb++) {
+ ics->prediction_used[sfb] = get_bits1(gb);
+ }
+ return 0;
+}
+
+/**
+ * Decode Long Term Prediction data; reference: table 4.xx.
+ */
+static void decode_ltp(LongTermPrediction *ltp,
+ GetBitContext *gb, uint8_t max_sfb)
+{
+ int sfb;
+
+ ltp->lag = get_bits(gb, 11);
+ ltp->coef = ltp_coef[get_bits(gb, 3)];
+ for (sfb = 0; sfb < FFMIN(max_sfb, MAX_LTP_LONG_SFB); sfb++)
+ ltp->used[sfb] = get_bits1(gb);
+}
+
+/**
+ * Decode Individual Channel Stream info; reference: table 4.6.
+ */
+static int decode_ics_info(AACContext *ac, IndividualChannelStream *ics,
+ GetBitContext *gb)
+{
+ const MPEG4AudioConfig *const m4ac = &ac->oc[1].m4ac;
+ const int aot = m4ac->object_type;
+ const int sampling_index = m4ac->sampling_index;
+ if (aot != AOT_ER_AAC_ELD) {
+ if (get_bits1(gb)) {
+ av_log(ac->avctx, AV_LOG_ERROR, "Reserved bit set.\n");
+ if (ac->avctx->err_recognition & AV_EF_BITSTREAM)
+ return AVERROR_INVALIDDATA;
+ }
+ ics->window_sequence[1] = ics->window_sequence[0];
+ ics->window_sequence[0] = get_bits(gb, 2);
+ if (aot == AOT_ER_AAC_LD &&
+ ics->window_sequence[0] != ONLY_LONG_SEQUENCE) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "AAC LD is only defined for ONLY_LONG_SEQUENCE but "
+ "window sequence %d found.\n", ics->window_sequence[0]);
+ ics->window_sequence[0] = ONLY_LONG_SEQUENCE;
+ return AVERROR_INVALIDDATA;
+ }
+ ics->use_kb_window[1] = ics->use_kb_window[0];
+ ics->use_kb_window[0] = get_bits1(gb);
+ }
+ ics->num_window_groups = 1;
+ ics->group_len[0] = 1;
+ if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+ int i;
+ ics->max_sfb = get_bits(gb, 4);
+ for (i = 0; i < 7; i++) {
+ if (get_bits1(gb)) {
+ ics->group_len[ics->num_window_groups - 1]++;
+ } else {
+ ics->num_window_groups++;
+ ics->group_len[ics->num_window_groups - 1] = 1;
+ }
+ }
+ ics->num_windows = 8;
+ ics->swb_offset = ff_swb_offset_128[sampling_index];
+ ics->num_swb = ff_aac_num_swb_128[sampling_index];
+ ics->tns_max_bands = ff_tns_max_bands_128[sampling_index];
+ ics->predictor_present = 0;
+ } else {
+ ics->max_sfb = get_bits(gb, 6);
+ ics->num_windows = 1;
+ if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD) {
+ if (m4ac->frame_length_short) {
+ ics->swb_offset = ff_swb_offset_480[sampling_index];
+ ics->num_swb = ff_aac_num_swb_480[sampling_index];
+ ics->tns_max_bands = ff_tns_max_bands_480[sampling_index];
+ } else {
+ ics->swb_offset = ff_swb_offset_512[sampling_index];
+ ics->num_swb = ff_aac_num_swb_512[sampling_index];
+ ics->tns_max_bands = ff_tns_max_bands_512[sampling_index];
+ }
+ if (!ics->num_swb || !ics->swb_offset)
+ return AVERROR_BUG;
+ } else {
+ ics->swb_offset = ff_swb_offset_1024[sampling_index];
+ ics->num_swb = ff_aac_num_swb_1024[sampling_index];
+ ics->tns_max_bands = ff_tns_max_bands_1024[sampling_index];
+ }
+ if (aot != AOT_ER_AAC_ELD) {
+ ics->predictor_present = get_bits1(gb);
+ ics->predictor_reset_group = 0;
+ }
+ if (ics->predictor_present) {
+ if (aot == AOT_AAC_MAIN) {
+ if (decode_prediction(ac, ics, gb)) {
+ goto fail;
+ }
+ } else if (aot == AOT_AAC_LC ||
+ aot == AOT_ER_AAC_LC) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Prediction is not allowed in AAC-LC.\n");
+ goto fail;
+ } else {
+ if (aot == AOT_ER_AAC_LD) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "LTP in ER AAC LD not yet implemented.\n");
+ return AVERROR_PATCHWELCOME;
+ }
+ if ((ics->ltp.present = get_bits(gb, 1)))
+ decode_ltp(&ics->ltp, gb, ics->max_sfb);
+ }
+ }
+ }
+
+ if (ics->max_sfb > ics->num_swb) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Number of scalefactor bands in group (%d) "
+ "exceeds limit (%d).\n",
+ ics->max_sfb, ics->num_swb);
+ goto fail;
+ }
+
+ return 0;
+fail:
+ ics->max_sfb = 0;
+ return AVERROR_INVALIDDATA;
+}
+
+/**
+ * Decode band types (section_data payload); reference: table 4.46.
+ *
+ * @param band_type array of the used band type
+ * @param band_type_run_end array of the last scalefactor band of a band type run
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int decode_band_types(AACContext *ac, enum BandType band_type[120],
+ int band_type_run_end[120], GetBitContext *gb,
+ IndividualChannelStream *ics)
+{
+ int g, idx = 0;
+ const int bits = (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) ? 3 : 5;
+ for (g = 0; g < ics->num_window_groups; g++) {
+ int k = 0;
+ while (k < ics->max_sfb) {
+ uint8_t sect_end = k;
+ int sect_len_incr;
+ int sect_band_type = get_bits(gb, 4);
+ if (sect_band_type == 12) {
+ av_log(ac->avctx, AV_LOG_ERROR, "invalid band type\n");
+ return AVERROR_INVALIDDATA;
+ }
+ do {
+ sect_len_incr = get_bits(gb, bits);
+ sect_end += sect_len_incr;
+ if (get_bits_left(gb) < 0) {
+ av_log(ac->avctx, AV_LOG_ERROR, "decode_band_types: "overread_err);
+ return AVERROR_INVALIDDATA;
+ }
+ if (sect_end > ics->max_sfb) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Number of bands (%d) exceeds limit (%d).\n",
+ sect_end, ics->max_sfb);
+ return AVERROR_INVALIDDATA;
+ }
+ } while (sect_len_incr == (1 << bits) - 1);
+ for (; k < sect_end; k++) {
+ band_type [idx] = sect_band_type;
+ band_type_run_end[idx++] = sect_end;
+ }
+ }
+ }
+ return 0;
+}
+
+/**
+ * Decode scalefactors; reference: table 4.47.
+ *
+ * @param global_gain first scalefactor value as scalefactors are differentially coded
+ * @param band_type array of the used band type
+ * @param band_type_run_end array of the last scalefactor band of a band type run
+ * @param sf array of scalefactors or intensity stereo positions
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int decode_scalefactors(AACContext *ac, INTFLOAT sf[120], GetBitContext *gb,
+ unsigned int global_gain,
+ IndividualChannelStream *ics,
+ enum BandType band_type[120],
+ int band_type_run_end[120])
+{
+ int g, i, idx = 0;
+ int offset[3] = { global_gain, global_gain - NOISE_OFFSET, 0 };
+ int clipped_offset;
+ int noise_flag = 1;
+ for (g = 0; g < ics->num_window_groups; g++) {
+ for (i = 0; i < ics->max_sfb;) {
+ int run_end = band_type_run_end[idx];
+ if (band_type[idx] == ZERO_BT) {
+ for (; i < run_end; i++, idx++)
+ sf[idx] = FIXR(0.);
+ } else if ((band_type[idx] == INTENSITY_BT) ||
+ (band_type[idx] == INTENSITY_BT2)) {
+ for (; i < run_end; i++, idx++) {
+ offset[2] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - SCALE_DIFF_ZERO;
+ clipped_offset = av_clip(offset[2], -155, 100);
+ if (offset[2] != clipped_offset) {
+ avpriv_request_sample(ac->avctx,
+ "If you heard an audible artifact, there may be a bug in the decoder. "
+ "Clipped intensity stereo position (%d -> %d)",
+ offset[2], clipped_offset);
+ }
+#if USE_FIXED
+ sf[idx] = 100 - clipped_offset;
+#else
+ sf[idx] = ff_aac_pow2sf_tab[-clipped_offset + POW_SF2_ZERO];
+#endif /* USE_FIXED */
+ }
+ } else if (band_type[idx] == NOISE_BT) {
+ for (; i < run_end; i++, idx++) {
+ if (noise_flag-- > 0)
+ offset[1] += get_bits(gb, NOISE_PRE_BITS) - NOISE_PRE;
+ else
+ offset[1] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - SCALE_DIFF_ZERO;
+ clipped_offset = av_clip(offset[1], -100, 155);
+ if (offset[1] != clipped_offset) {
+ avpriv_request_sample(ac->avctx,
+ "If you heard an audible artifact, there may be a bug in the decoder. "
+ "Clipped noise gain (%d -> %d)",
+ offset[1], clipped_offset);
+ }
+#if USE_FIXED
+ sf[idx] = -(100 + clipped_offset);
+#else
+ sf[idx] = -ff_aac_pow2sf_tab[clipped_offset + POW_SF2_ZERO];
+#endif /* USE_FIXED */
+ }
+ } else {
+ for (; i < run_end; i++, idx++) {
+ offset[0] += get_vlc2(gb, vlc_scalefactors.table, 7, 3) - SCALE_DIFF_ZERO;
+ if (offset[0] > 255U) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Scalefactor (%d) out of range.\n", offset[0]);
+ return AVERROR_INVALIDDATA;
+ }
+#if USE_FIXED
+ sf[idx] = -offset[0];
+#else
+ sf[idx] = -ff_aac_pow2sf_tab[offset[0] - 100 + POW_SF2_ZERO];
+#endif /* USE_FIXED */
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/**
+ * Decode pulse data; reference: table 4.7.
+ */
+static int decode_pulses(Pulse *pulse, GetBitContext *gb,
+ const uint16_t *swb_offset, int num_swb)
+{
+ int i, pulse_swb;
+ pulse->num_pulse = get_bits(gb, 2) + 1;
+ pulse_swb = get_bits(gb, 6);
+ if (pulse_swb >= num_swb)
+ return -1;
+ pulse->pos[0] = swb_offset[pulse_swb];
+ pulse->pos[0] += get_bits(gb, 5);
+ if (pulse->pos[0] >= swb_offset[num_swb])
+ return -1;
+ pulse->amp[0] = get_bits(gb, 4);
+ for (i = 1; i < pulse->num_pulse; i++) {
+ pulse->pos[i] = get_bits(gb, 5) + pulse->pos[i - 1];
+ if (pulse->pos[i] >= swb_offset[num_swb])
+ return -1;
+ pulse->amp[i] = get_bits(gb, 4);
+ }
+ return 0;
+}
+
+/**
+ * Decode Temporal Noise Shaping data; reference: table 4.48.
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int decode_tns(AACContext *ac, TemporalNoiseShaping *tns,
+ GetBitContext *gb, const IndividualChannelStream *ics)
+{
+ int w, filt, i, coef_len, coef_res, coef_compress;
+ const int is8 = ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE;
+ const int tns_max_order = is8 ? 7 : ac->oc[1].m4ac.object_type == AOT_AAC_MAIN ? 20 : 12;
+ for (w = 0; w < ics->num_windows; w++) {
+ if ((tns->n_filt[w] = get_bits(gb, 2 - is8))) {
+ coef_res = get_bits1(gb);
+
+ for (filt = 0; filt < tns->n_filt[w]; filt++) {
+ int tmp2_idx;
+ tns->length[w][filt] = get_bits(gb, 6 - 2 * is8);
+
+ if ((tns->order[w][filt] = get_bits(gb, 5 - 2 * is8)) > tns_max_order) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "TNS filter order %d is greater than maximum %d.\n",
+ tns->order[w][filt], tns_max_order);
+ tns->order[w][filt] = 0;
+ return AVERROR_INVALIDDATA;
+ }
+ if (tns->order[w][filt]) {
+ tns->direction[w][filt] = get_bits1(gb);
+ coef_compress = get_bits1(gb);
+ coef_len = coef_res + 3 - coef_compress;
+ tmp2_idx = 2 * coef_compress + coef_res;
+
+ for (i = 0; i < tns->order[w][filt]; i++)
+ tns->coef[w][filt][i] = tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)];
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/**
+ * Decode Mid/Side data; reference: table 4.54.
+ *
+ * @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s;
+ * [1] mask is decoded from bitstream; [2] mask is all 1s;
+ * [3] reserved for scalable AAC
+ */
+static void decode_mid_side_stereo(ChannelElement *cpe, GetBitContext *gb,
+ int ms_present)
+{
+ int idx;
+ int max_idx = cpe->ch[0].ics.num_window_groups * cpe->ch[0].ics.max_sfb;
+ if (ms_present == 1) {
+ for (idx = 0; idx < max_idx; idx++)
+ cpe->ms_mask[idx] = get_bits1(gb);
+ } else if (ms_present == 2) {
+ memset(cpe->ms_mask, 1, max_idx * sizeof(cpe->ms_mask[0]));
+ }
+}
+
+/**
+ * Decode spectral data; reference: table 4.50.
+ * Dequantize and scale spectral data; reference: 4.6.3.3.
+ *
+ * @param coef array of dequantized, scaled spectral data
+ * @param sf array of scalefactors or intensity stereo positions
+ * @param pulse_present set if pulses are present
+ * @param pulse pointer to pulse data struct
+ * @param band_type array of the used band type
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int decode_spectrum_and_dequant(AACContext *ac, INTFLOAT coef[1024],
+ GetBitContext *gb, const INTFLOAT sf[120],
+ int pulse_present, const Pulse *pulse,
+ const IndividualChannelStream *ics,
+ enum BandType band_type[120])
+{
+ int i, k, g, idx = 0;
+ const int c = 1024 / ics->num_windows;
+ const uint16_t *offsets = ics->swb_offset;
+ INTFLOAT *coef_base = coef;
+
+ for (g = 0; g < ics->num_windows; g++)
+ memset(coef + g * 128 + offsets[ics->max_sfb], 0,
+ sizeof(INTFLOAT) * (c - offsets[ics->max_sfb]));
+
+ for (g = 0; g < ics->num_window_groups; g++) {
+ unsigned g_len = ics->group_len[g];
+
+ for (i = 0; i < ics->max_sfb; i++, idx++) {
+ const unsigned cbt_m1 = band_type[idx] - 1;
+ INTFLOAT *cfo = coef + offsets[i];
+ int off_len = offsets[i + 1] - offsets[i];
+ int group;
+
+ if (cbt_m1 >= INTENSITY_BT2 - 1) {
+ for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
+ memset(cfo, 0, off_len * sizeof(*cfo));
+ }
+ } else if (cbt_m1 == NOISE_BT - 1) {
+ for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
+#if !USE_FIXED
+ float scale;
+#endif /* !USE_FIXED */
+ INTFLOAT band_energy;
+
+ for (k = 0; k < off_len; k++) {
+ ac->random_state = lcg_random(ac->random_state);
+#if USE_FIXED
+ cfo[k] = ac->random_state >> 3;
+#else
+ cfo[k] = ac->random_state;
+#endif /* USE_FIXED */
+ }
+
+#if USE_FIXED
+ band_energy = ac->fdsp->scalarproduct_fixed(cfo, cfo, off_len);
+ band_energy = fixed_sqrt(band_energy, 31);
+ noise_scale(cfo, sf[idx], band_energy, off_len);
+#else
+ band_energy = ac->fdsp->scalarproduct_float(cfo, cfo, off_len);
+ scale = sf[idx] / sqrtf(band_energy);
+ ac->fdsp->vector_fmul_scalar(cfo, cfo, scale, off_len);
+#endif /* USE_FIXED */
+ }
+ } else {
+#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);
+
+ switch (cbt_m1 >> 1) {
+ case 0:
+ for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
+ INTFLOAT *cf = cfo;
+ int len = off_len;
+
+ do {
+ int code;
+ unsigned cb_idx;
+
+ UPDATE_CACHE(re, gb);
+ GET_VLC(code, re, gb, vlc_tab, 8, 2);
+ cb_idx = cb_vector_idx[code];
+#if USE_FIXED
+ cf = DEC_SQUAD(cf, cb_idx);
+#else
+ cf = VMUL4(cf, vq, cb_idx, sf + idx);
+#endif /* USE_FIXED */
+ } while (len -= 4);
+ }
+ break;
+
+ case 1:
+ for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
+ INTFLOAT *cf = cfo;
+ int len = off_len;
+
+ do {
+ int code;
+ unsigned nnz;
+ unsigned cb_idx;
+ uint32_t bits;
+
+ UPDATE_CACHE(re, gb);
+ GET_VLC(code, re, gb, vlc_tab, 8, 2);
+ cb_idx = cb_vector_idx[code];
+ nnz = cb_idx >> 8 & 15;
+ bits = nnz ? GET_CACHE(re, gb) : 0;
+ LAST_SKIP_BITS(re, gb, nnz);
+#if USE_FIXED
+ cf = DEC_UQUAD(cf, cb_idx, bits);
+#else
+ cf = VMUL4S(cf, vq, cb_idx, bits, sf + idx);
+#endif /* USE_FIXED */
+ } while (len -= 4);
+ }
+ break;
+
+ case 2:
+ for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
+ INTFLOAT *cf = cfo;
+ int len = off_len;
+
+ do {
+ int code;
+ unsigned cb_idx;
+
+ UPDATE_CACHE(re, gb);
+ GET_VLC(code, re, gb, vlc_tab, 8, 2);
+ cb_idx = cb_vector_idx[code];
+#if USE_FIXED
+ cf = DEC_SPAIR(cf, cb_idx);
+#else
+ cf = VMUL2(cf, vq, cb_idx, sf + idx);
+#endif /* USE_FIXED */
+ } while (len -= 2);
+ }
+ break;
+
+ case 3:
+ case 4:
+ for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
+ INTFLOAT *cf = cfo;
+ int len = off_len;
+
+ do {
+ int code;
+ unsigned nnz;
+ unsigned cb_idx;
+ unsigned sign;
+
+ UPDATE_CACHE(re, gb);
+ GET_VLC(code, re, gb, vlc_tab, 8, 2);
+ cb_idx = cb_vector_idx[code];
+ nnz = cb_idx >> 8 & 15;
+ sign = nnz ? SHOW_UBITS(re, gb, nnz) << (cb_idx >> 12) : 0;
+ LAST_SKIP_BITS(re, gb, nnz);
+#if USE_FIXED
+ cf = DEC_UPAIR(cf, cb_idx, sign);
+#else
+ cf = VMUL2S(cf, vq, cb_idx, sign, sf + idx);
+#endif /* USE_FIXED */
+ } while (len -= 2);
+ }
+ break;
+
+ default:
+ for (group = 0; group < (AAC_SIGNE)g_len; group++, cfo+=128) {
+#if USE_FIXED
+ int *icf = cfo;
+ int v;
+#else
+ float *cf = cfo;
+ uint32_t *icf = (uint32_t *) cf;
+#endif /* USE_FIXED */
+ int len = off_len;
+
+ do {
+ int code;
+ unsigned nzt, nnz;
+ unsigned cb_idx;
+ uint32_t bits;
+ int j;
+
+ UPDATE_CACHE(re, gb);
+ GET_VLC(code, re, gb, vlc_tab, 8, 2);
+
+ if (!code) {
+ *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);
+ LAST_SKIP_BITS(re, gb, nnz);
+
+ for (j = 0; j < 2; j++) {
+ if (nzt & 1<<j) {
+ uint32_t b;
+ int n;
+ /* The total length of escape_sequence must be < 22 bits according
+ to the specification (i.e. max is 111111110xxxxxxxxxxxx). */
+ UPDATE_CACHE(re, gb);
+ b = GET_CACHE(re, gb);
+ b = 31 - av_log2(~b);
+
+ if (b > 8) {
+ av_log(ac->avctx, AV_LOG_ERROR, "error in spectral data, ESC overflow\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ SKIP_BITS(re, gb, b + 1);
+ b += 4;
+ n = (1 << b) + SHOW_UBITS(re, gb, b);
+ LAST_SKIP_BITS(re, gb, b);
+#if USE_FIXED
+ v = n;
+ if (bits & 1U<<31)
+ v = -v;
+ *icf++ = v;
+#else
+ *icf++ = cbrt_tab[n] | (bits & 1U<<31);
+#endif /* USE_FIXED */
+ bits <<= 1;
+ } else {
+#if USE_FIXED
+ v = cb_idx & 15;
+ if (bits & 1U<<31)
+ v = -v;
+ *icf++ = v;
+#else
+ unsigned v = ((const uint32_t*)vq)[cb_idx & 15];
+ *icf++ = (bits & 1U<<31) | v;
+#endif /* USE_FIXED */
+ bits <<= !!v;
+ }
+ cb_idx >>= 4;
+ }
+ } while (len -= 2);
+#if !USE_FIXED
+ ac->fdsp->vector_fmul_scalar(cfo, cfo, sf[idx], off_len);
+#endif /* !USE_FIXED */
+ }
+ }
+
+ CLOSE_READER(re, gb);
+ }
+ }
+ coef += g_len << 7;
+ }
+
+ if (pulse_present) {
+ idx = 0;
+ for (i = 0; i < pulse->num_pulse; i++) {
+ INTFLOAT co = coef_base[ pulse->pos[i] ];
+ while (offsets[idx + 1] <= pulse->pos[i])
+ idx++;
+ if (band_type[idx] != NOISE_BT && sf[idx]) {
+ INTFLOAT ico = -pulse->amp[i];
+#if USE_FIXED
+ if (co) {
+ ico = co + (co > 0 ? -ico : ico);
+ }
+ coef_base[ pulse->pos[i] ] = ico;
+#else
+ if (co) {
+ co /= sf[idx];
+ ico = co / sqrtf(sqrtf(fabsf(co))) + (co > 0 ? -ico : ico);
+ }
+ coef_base[ pulse->pos[i] ] = cbrtf(fabsf(ico)) * ico * sf[idx];
+#endif /* USE_FIXED */
+ }
+ }
+ }
+#if USE_FIXED
+ coef = coef_base;
+ idx = 0;
+ for (g = 0; g < ics->num_window_groups; g++) {
+ unsigned g_len = ics->group_len[g];
+
+ for (i = 0; i < ics->max_sfb; i++, idx++) {
+ const unsigned cbt_m1 = band_type[idx] - 1;
+ int *cfo = coef + offsets[i];
+ int off_len = offsets[i + 1] - offsets[i];
+ int group;
+
+ if (cbt_m1 < NOISE_BT - 1) {
+ for (group = 0; group < (int)g_len; group++, cfo+=128) {
+ ac->vector_pow43(cfo, off_len);
+ ac->subband_scale(cfo, cfo, sf[idx], 34, off_len);
+ }
+ }
+ }
+ coef += g_len << 7;
+ }
+#endif /* USE_FIXED */
+ return 0;
+}
+
+/**
+ * Apply AAC-Main style frequency domain prediction.
+ */
+static void apply_prediction(AACContext *ac, SingleChannelElement *sce)
+{
+ int sfb, k;
+
+ if (!sce->ics.predictor_initialized) {
+ reset_all_predictors(sce->predictor_state);
+ sce->ics.predictor_initialized = 1;
+ }
+
+ if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
+ for (sfb = 0;
+ sfb < ff_aac_pred_sfb_max[ac->oc[1].m4ac.sampling_index];
+ sfb++) {
+ for (k = sce->ics.swb_offset[sfb];
+ k < sce->ics.swb_offset[sfb + 1];
+ k++) {
+ predict(&sce->predictor_state[k], &sce->coeffs[k],
+ sce->ics.predictor_present &&
+ sce->ics.prediction_used[sfb]);
+ }
+ }
+ if (sce->ics.predictor_reset_group)
+ reset_predictor_group(sce->predictor_state,
+ sce->ics.predictor_reset_group);
+ } else
+ reset_all_predictors(sce->predictor_state);
+}
+
+/**
+ * Decode an individual_channel_stream payload; reference: table 4.44.
+ *
+ * @param common_window Channels have independent [0], or shared [1], Individual Channel Stream information.
+ * @param scale_flag scalable [1] or non-scalable [0] AAC (Unused until scalable AAC is implemented.)
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int decode_ics(AACContext *ac, SingleChannelElement *sce,
+ GetBitContext *gb, int common_window, int scale_flag)
+{
+ Pulse pulse;
+ TemporalNoiseShaping *tns = &sce->tns;
+ IndividualChannelStream *ics = &sce->ics;
+ INTFLOAT *out = sce->coeffs;
+ int global_gain, eld_syntax, er_syntax, pulse_present = 0;
+ int ret;
+
+ eld_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD;
+ er_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_LC ||
+ ac->oc[1].m4ac.object_type == AOT_ER_AAC_LTP ||
+ ac->oc[1].m4ac.object_type == AOT_ER_AAC_LD ||
+ ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD;
+
+ /* This assignment is to silence a GCC warning about the variable being used
+ * uninitialized when in fact it always is.
+ */
+ pulse.num_pulse = 0;
+
+ global_gain = get_bits(gb, 8);
+
+ if (!common_window && !scale_flag) {
+ if (decode_ics_info(ac, ics, gb) < 0)
+ return AVERROR_INVALIDDATA;
+ }
+
+ if ((ret = decode_band_types(ac, sce->band_type,
+ sce->band_type_run_end, gb, ics)) < 0)
+ return ret;
+ if ((ret = decode_scalefactors(ac, sce->sf, gb, global_gain, ics,
+ sce->band_type, sce->band_type_run_end)) < 0)
+ return ret;
+
+ pulse_present = 0;
+ if (!scale_flag) {
+ if (!eld_syntax && (pulse_present = get_bits1(gb))) {
+ if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Pulse tool not allowed in eight short sequence.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (decode_pulses(&pulse, gb, ics->swb_offset, ics->num_swb)) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Pulse data corrupt or invalid.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ tns->present = get_bits1(gb);
+ if (tns->present && !er_syntax)
+ if (decode_tns(ac, tns, gb, ics) < 0)
+ return AVERROR_INVALIDDATA;
+ if (!eld_syntax && get_bits1(gb)) {
+ avpriv_request_sample(ac->avctx, "SSR");
+ return AVERROR_PATCHWELCOME;
+ }
+ // I see no textual basis in the spec for this occurring after SSR gain
+ // control, but this is what both reference and real implmentations do
+ if (tns->present && er_syntax)
+ if (decode_tns(ac, tns, gb, ics) < 0)
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present,
+ &pulse, ics, sce->band_type) < 0)
+ return AVERROR_INVALIDDATA;
+
+ if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN && !common_window)
+ apply_prediction(ac, sce);
+
+ return 0;
+}
+
+/**
+ * Mid/Side stereo decoding; reference: 4.6.8.1.3.
+ */
+static void apply_mid_side_stereo(AACContext *ac, ChannelElement *cpe)
+{
+ const IndividualChannelStream *ics = &cpe->ch[0].ics;
+ INTFLOAT *ch0 = cpe->ch[0].coeffs;
+ INTFLOAT *ch1 = cpe->ch[1].coeffs;
+ int g, i, group, idx = 0;
+ const uint16_t *offsets = ics->swb_offset;
+ for (g = 0; g < ics->num_window_groups; g++) {
+ for (i = 0; i < ics->max_sfb; i++, idx++) {
+ if (cpe->ms_mask[idx] &&
+ cpe->ch[0].band_type[idx] < NOISE_BT &&
+ cpe->ch[1].band_type[idx] < NOISE_BT) {
+#if USE_FIXED
+ for (group = 0; group < ics->group_len[g]; group++) {
+ ac->fdsp->butterflies_fixed(ch0 + group * 128 + offsets[i],
+ ch1 + group * 128 + offsets[i],
+ offsets[i+1] - offsets[i]);
+#else
+ for (group = 0; group < ics->group_len[g]; group++) {
+ ac->fdsp->butterflies_float(ch0 + group * 128 + offsets[i],
+ ch1 + group * 128 + offsets[i],
+ offsets[i+1] - offsets[i]);
+#endif /* USE_FIXED */
+ }
+ }
+ }
+ ch0 += ics->group_len[g] * 128;
+ ch1 += ics->group_len[g] * 128;
+ }
+}
+
+/**
+ * intensity stereo decoding; reference: 4.6.8.2.3
+ *
+ * @param ms_present Indicates mid/side stereo presence. [0] mask is all 0s;
+ * [1] mask is decoded from bitstream; [2] mask is all 1s;
+ * [3] reserved for scalable AAC
+ */
+static void apply_intensity_stereo(AACContext *ac,
+ ChannelElement *cpe, int ms_present)
+{
+ const IndividualChannelStream *ics = &cpe->ch[1].ics;
+ SingleChannelElement *sce1 = &cpe->ch[1];
+ INTFLOAT *coef0 = cpe->ch[0].coeffs, *coef1 = cpe->ch[1].coeffs;
+ const uint16_t *offsets = ics->swb_offset;
+ int g, group, i, idx = 0;
+ int c;
+ INTFLOAT scale;
+ for (g = 0; g < ics->num_window_groups; g++) {
+ for (i = 0; i < ics->max_sfb;) {
+ if (sce1->band_type[idx] == INTENSITY_BT ||
+ sce1->band_type[idx] == INTENSITY_BT2) {
+ const int bt_run_end = sce1->band_type_run_end[idx];
+ for (; i < bt_run_end; i++, idx++) {
+ c = -1 + 2 * (sce1->band_type[idx] - 14);
+ if (ms_present)
+ c *= 1 - 2 * cpe->ms_mask[idx];
+ scale = c * sce1->sf[idx];
+ for (group = 0; group < ics->group_len[g]; group++)
+#if USE_FIXED
+ ac->subband_scale(coef1 + group * 128 + offsets[i],
+ coef0 + group * 128 + offsets[i],
+ scale,
+ 23,
+ offsets[i + 1] - offsets[i]);
+#else
+ ac->fdsp->vector_fmul_scalar(coef1 + group * 128 + offsets[i],
+ coef0 + group * 128 + offsets[i],
+ scale,
+ offsets[i + 1] - offsets[i]);
+#endif /* USE_FIXED */
+ }
+ } else {
+ int bt_run_end = sce1->band_type_run_end[idx];
+ idx += bt_run_end - i;
+ i = bt_run_end;
+ }
+ }
+ coef0 += ics->group_len[g] * 128;
+ coef1 += ics->group_len[g] * 128;
+ }
+}
+
+/**
+ * Decode a channel_pair_element; reference: table 4.4.
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int decode_cpe(AACContext *ac, GetBitContext *gb, ChannelElement *cpe)
+{
+ int i, ret, common_window, ms_present = 0;
+ int eld_syntax = ac->oc[1].m4ac.object_type == AOT_ER_AAC_ELD;
+
+ common_window = eld_syntax || get_bits1(gb);
+ if (common_window) {
+ if (decode_ics_info(ac, &cpe->ch[0].ics, gb))
+ return AVERROR_INVALIDDATA;
+ i = cpe->ch[1].ics.use_kb_window[0];
+ cpe->ch[1].ics = cpe->ch[0].ics;
+ cpe->ch[1].ics.use_kb_window[1] = i;
+ if (cpe->ch[1].ics.predictor_present &&
+ (ac->oc[1].m4ac.object_type != AOT_AAC_MAIN))
+ if ((cpe->ch[1].ics.ltp.present = get_bits(gb, 1)))
+ decode_ltp(&cpe->ch[1].ics.ltp, gb, cpe->ch[1].ics.max_sfb);
+ ms_present = get_bits(gb, 2);
+ if (ms_present == 3) {
+ av_log(ac->avctx, AV_LOG_ERROR, "ms_present = 3 is reserved.\n");
+ return AVERROR_INVALIDDATA;
+ } else if (ms_present)
+ decode_mid_side_stereo(cpe, gb, ms_present);
+ }
+ if ((ret = decode_ics(ac, &cpe->ch[0], gb, common_window, 0)))
+ return ret;
+ if ((ret = decode_ics(ac, &cpe->ch[1], gb, common_window, 0)))
+ return ret;
+
+ if (common_window) {
+ if (ms_present)
+ apply_mid_side_stereo(ac, cpe);
+ if (ac->oc[1].m4ac.object_type == AOT_AAC_MAIN) {
+ apply_prediction(ac, &cpe->ch[0]);
+ apply_prediction(ac, &cpe->ch[1]);
+ }
+ }
+
+ apply_intensity_stereo(ac, cpe, ms_present);
+ return 0;
+}
+
+static const float cce_scale[] = {
+ 1.09050773266525765921, //2^(1/8)
+ 1.18920711500272106672, //2^(1/4)
+ M_SQRT2,
+ 2,
+};
+
+/**
+ * Decode coupling_channel_element; reference: table 4.8.
+ *
+ * @return Returns error status. 0 - OK, !0 - error
+ */
+static int decode_cce(AACContext *ac, GetBitContext *gb, ChannelElement *che)
+{
+ int num_gain = 0;
+ int c, g, sfb, ret;
+ int sign;
+ INTFLOAT scale;
+ SingleChannelElement *sce = &che->ch[0];
+ ChannelCoupling *coup = &che->coup;
+
+ coup->coupling_point = 2 * get_bits1(gb);
+ coup->num_coupled = get_bits(gb, 3);
+ for (c = 0; c <= coup->num_coupled; c++) {
+ num_gain++;
+ coup->type[c] = get_bits1(gb) ? TYPE_CPE : TYPE_SCE;
+ coup->id_select[c] = get_bits(gb, 4);
+ if (coup->type[c] == TYPE_CPE) {
+ coup->ch_select[c] = get_bits(gb, 2);
+ if (coup->ch_select[c] == 3)
+ num_gain++;
+ } else
+ coup->ch_select[c] = 2;
+ }
+ coup->coupling_point += get_bits1(gb) || (coup->coupling_point >> 1);
+
+ sign = get_bits(gb, 1);
+#if USE_FIXED
+ scale = get_bits(gb, 2);
+#else
+ scale = cce_scale[get_bits(gb, 2)];
+#endif
+
+ if ((ret = decode_ics(ac, sce, gb, 0, 0)))
+ return ret;
+
+ for (c = 0; c < num_gain; c++) {
+ int idx = 0;
+ int cge = 1;
+ int gain = 0;
+ INTFLOAT gain_cache = FIXR10(1.);
+ if (c) {
+ cge = coup->coupling_point == AFTER_IMDCT ? 1 : get_bits1(gb);
+ gain = cge ? get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60: 0;
+ gain_cache = GET_GAIN(scale, gain);
+ }
+ if (coup->coupling_point == AFTER_IMDCT) {
+ coup->gain[c][0] = gain_cache;
+ } else {
+ for (g = 0; g < sce->ics.num_window_groups; g++) {
+ for (sfb = 0; sfb < sce->ics.max_sfb; sfb++, idx++) {
+ if (sce->band_type[idx] != ZERO_BT) {
+ if (!cge) {
+ int t = get_vlc2(gb, vlc_scalefactors.table, 7, 3) - 60;
+ if (t) {
+ int s = 1;
+ t = gain += t;
+ if (sign) {
+ s -= 2 * (t & 0x1);
+ t >>= 1;
+ }
+ gain_cache = GET_GAIN(scale, t) * s;
+ }
+ }
+ coup->gain[c][idx] = gain_cache;
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+/**
+ * Parse whether channels are to be excluded from Dynamic Range Compression; reference: table 4.53.
+ *
+ * @return Returns number of bytes consumed.
+ */
+static int decode_drc_channel_exclusions(DynamicRangeControl *che_drc,
+ GetBitContext *gb)
+{
+ int i;
+ int num_excl_chan = 0;
+
+ do {
+ for (i = 0; i < 7; i++)
+ che_drc->exclude_mask[num_excl_chan++] = get_bits1(gb);
+ } while (num_excl_chan < MAX_CHANNELS - 7 && get_bits1(gb));
+
+ return num_excl_chan / 7;
+}
+
+/**
+ * Decode dynamic range information; reference: table 4.52.
+ *
+ * @return Returns number of bytes consumed.
+ */
+static int decode_dynamic_range(DynamicRangeControl *che_drc,
+ GetBitContext *gb)
+{
+ int n = 1;
+ int drc_num_bands = 1;
+ int i;
+
+ /* pce_tag_present? */
+ if (get_bits1(gb)) {
+ che_drc->pce_instance_tag = get_bits(gb, 4);
+ skip_bits(gb, 4); // tag_reserved_bits
+ n++;
+ }
+
+ /* excluded_chns_present? */
+ if (get_bits1(gb)) {
+ n += decode_drc_channel_exclusions(che_drc, gb);
+ }
+
+ /* drc_bands_present? */
+ if (get_bits1(gb)) {
+ che_drc->band_incr = get_bits(gb, 4);
+ che_drc->interpolation_scheme = get_bits(gb, 4);
+ n++;
+ drc_num_bands += che_drc->band_incr;
+ for (i = 0; i < drc_num_bands; i++) {
+ che_drc->band_top[i] = get_bits(gb, 8);
+ n++;
+ }
+ }
+
+ /* prog_ref_level_present? */
+ if (get_bits1(gb)) {
+ che_drc->prog_ref_level = get_bits(gb, 7);
+ skip_bits1(gb); // prog_ref_level_reserved_bits
+ n++;
+ }
+
+ for (i = 0; i < drc_num_bands; i++) {
+ che_drc->dyn_rng_sgn[i] = get_bits1(gb);
+ che_drc->dyn_rng_ctl[i] = get_bits(gb, 7);
+ n++;
+ }
+
+ return n;
+}
+
+static int decode_fill(AACContext *ac, GetBitContext *gb, int len) {
+ uint8_t buf[256];
+ int i, major, minor;
+
+ if (len < 13+7*8)
+ goto unknown;
+
+ get_bits(gb, 13); len -= 13;
+
+ for(i=0; i+1<sizeof(buf) && len>=8; i++, len-=8)
+ buf[i] = get_bits(gb, 8);
+
+ buf[i] = 0;
+ if (ac->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(ac->avctx, AV_LOG_DEBUG, "FILL:%s\n", buf);
+
+ if (sscanf(buf, "libfaac %d.%d", &major, &minor) == 2){
+ ac->avctx->internal->skip_samples = 1024;
+ }
+
+unknown:
+ skip_bits_long(gb, len);
+
+ return 0;
+}
+
+/**
+ * Decode extension data (incomplete); reference: table 4.51.
+ *
+ * @param cnt length of TYPE_FIL syntactic element in bytes
+ *
+ * @return Returns number of bytes consumed
+ */
+static int decode_extension_payload(AACContext *ac, GetBitContext *gb, int cnt,
+ ChannelElement *che, enum RawDataBlockType elem_type)
+{
+ int crc_flag = 0;
+ int res = cnt;
+ int type = get_bits(gb, 4);
+
+ if (ac->avctx->debug & FF_DEBUG_STARTCODE)
+ av_log(ac->avctx, AV_LOG_DEBUG, "extension type: %d len:%d\n", type, cnt);
+
+ switch (type) { // extension type
+ case EXT_SBR_DATA_CRC:
+ crc_flag++;
+ case EXT_SBR_DATA:
+ if (!che) {
+ av_log(ac->avctx, AV_LOG_ERROR, "SBR was found before the first channel element.\n");
+ return res;
+ } else if (!ac->oc[1].m4ac.sbr) {
+ av_log(ac->avctx, AV_LOG_ERROR, "SBR signaled to be not-present but was found in the bitstream.\n");
+ skip_bits_long(gb, 8 * cnt - 4);
+ return res;
+ } else if (ac->oc[1].m4ac.sbr == -1 && ac->oc[1].status == OC_LOCKED) {
+ av_log(ac->avctx, AV_LOG_ERROR, "Implicit SBR was found with a first occurrence after the first frame.\n");
+ skip_bits_long(gb, 8 * cnt - 4);
+ return res;
+ } else if (ac->oc[1].m4ac.ps == -1 && ac->oc[1].status < OC_LOCKED && ac->avctx->channels == 1) {
+ ac->oc[1].m4ac.sbr = 1;
+ ac->oc[1].m4ac.ps = 1;
+ ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
+ output_configure(ac, ac->oc[1].layout_map, ac->oc[1].layout_map_tags,
+ ac->oc[1].status, 1);
+ } else {
+ ac->oc[1].m4ac.sbr = 1;
+ ac->avctx->profile = FF_PROFILE_AAC_HE;
+ }
+ res = AAC_RENAME(ff_decode_sbr_extension)(ac, &che->sbr, gb, crc_flag, cnt, elem_type);
+ break;
+ case EXT_DYNAMIC_RANGE:
+ res = decode_dynamic_range(&ac->che_drc, gb);
+ break;
+ case EXT_FILL:
+ decode_fill(ac, gb, 8 * cnt - 4);
+ break;
+ case EXT_FILL_DATA:
+ case EXT_DATA_ELEMENT:
+ default:
+ skip_bits_long(gb, 8 * cnt - 4);
+ break;
+ };
+ return res;
+}
+
+/**
+ * Decode Temporal Noise Shaping filter coefficients and apply all-pole filters; reference: 4.6.9.3.
+ *
+ * @param decode 1 if tool is used normally, 0 if tool is used in LTP.
+ * @param coef spectral coefficients
+ */
+static void apply_tns(INTFLOAT coef[1024], TemporalNoiseShaping *tns,
+ IndividualChannelStream *ics, int decode)
+{
+ const int mmm = FFMIN(ics->tns_max_bands, ics->max_sfb);
+ int w, filt, m, i;
+ int bottom, top, order, start, end, size, inc;
+ INTFLOAT lpc[TNS_MAX_ORDER];
+ INTFLOAT tmp[TNS_MAX_ORDER+1];
+
+ for (w = 0; w < ics->num_windows; w++) {
+ bottom = ics->num_swb;
+ for (filt = 0; filt < tns->n_filt[w]; filt++) {
+ top = bottom;
+ bottom = FFMAX(0, top - tns->length[w][filt]);
+ order = tns->order[w][filt];
+ if (order == 0)
+ continue;
+
+ // tns_decode_coef
+ AAC_RENAME(compute_lpc_coefs)(tns->coef[w][filt], order, lpc, 0, 0, 0);
+
+ start = ics->swb_offset[FFMIN(bottom, mmm)];
+ end = ics->swb_offset[FFMIN( top, mmm)];
+ if ((size = end - start) <= 0)
+ continue;
+ if (tns->direction[w][filt]) {
+ inc = -1;
+ start = end - 1;
+ } else {
+ inc = 1;
+ }
+ start += w * 128;
+
+ if (decode) {
+ // ar filter
+ for (m = 0; m < size; m++, start += inc)
+ for (i = 1; i <= FFMIN(m, order); i++)
+ coef[start] -= AAC_MUL26(coef[start - i * inc], lpc[i - 1]);
+ } else {
+ // ma filter
+ for (m = 0; m < size; m++, start += inc) {
+ tmp[0] = coef[start];
+ for (i = 1; i <= FFMIN(m, order); i++)
+ coef[start] += AAC_MUL26(tmp[i], lpc[i - 1]);
+ for (i = order; i > 0; i--)
+ tmp[i] = tmp[i - 1];
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Apply windowing and MDCT to obtain the spectral
+ * coefficient from the predicted sample by LTP.
+ */
+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);
+
+ if (ics->window_sequence[0] != LONG_STOP_SEQUENCE) {
+ ac->fdsp->vector_fmul(in, in, lwindow_prev, 1024);
+ } else {
+ memset(in, 0, 448 * sizeof(*in));
+ ac->fdsp->vector_fmul(in + 448, in + 448, swindow_prev, 128);
+ }
+ if (ics->window_sequence[0] != LONG_START_SEQUENCE) {
+ ac->fdsp->vector_fmul_reverse(in + 1024, in + 1024, lwindow, 1024);
+ } else {
+ ac->fdsp->vector_fmul_reverse(in + 1024 + 448, in + 1024 + 448, swindow, 128);
+ memset(in + 1024 + 576, 0, 448 * sizeof(*in));
+ }
+ ac->mdct_ltp.mdct_calc(&ac->mdct_ltp, out, in);
+}
+
+/**
+ * Apply the long term prediction
+ */
+static void apply_ltp(AACContext *ac, SingleChannelElement *sce)
+{
+ const LongTermPrediction *ltp = &sce->ics.ltp;
+ const uint16_t *offsets = sce->ics.swb_offset;
+ int i, sfb;
+
+ if (sce->ics.window_sequence[0] != EIGHT_SHORT_SEQUENCE) {
+ INTFLOAT *predTime = sce->ret;
+ INTFLOAT *predFreq = ac->buf_mdct;
+ int16_t num_samples = 2048;
+
+ if (ltp->lag < 1024)
+ num_samples = ltp->lag + 1024;
+ for (i = 0; i < num_samples; i++)
+ predTime[i] = AAC_MUL30(sce->ltp_state[i + 2048 - ltp->lag], ltp->coef);
+ memset(&predTime[i], 0, (2048 - i) * sizeof(*predTime));
+
+ ac->windowing_and_mdct_ltp(ac, predFreq, predTime, &sce->ics);
+
+ if (sce->tns.present)
+ ac->apply_tns(predFreq, &sce->tns, &sce->ics, 0);
+
+ for (sfb = 0; sfb < FFMIN(sce->ics.max_sfb, MAX_LTP_LONG_SFB); sfb++)
+ if (ltp->used[sfb])
+ for (i = offsets[sfb]; i < offsets[sfb + 1]; i++)
+ sce->coeffs[i] += predFreq[i];
+ }
+}
+
+/**
+ * Update the LTP buffer for next frame
+ */
+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);
+ int i;
+
+ if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+ memcpy(saved_ltp, saved, 512 * sizeof(*saved_ltp));
+ memset(saved_ltp + 576, 0, 448 * sizeof(*saved_ltp));
+ ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
+
+ for (i = 0; i < 64; i++)
+ saved_ltp[i + 512] = AAC_MUL31(ac->buf_mdct[1023 - i], swindow[63 - i]);
+ } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
+ memcpy(saved_ltp, ac->buf_mdct + 512, 448 * sizeof(*saved_ltp));
+ memset(saved_ltp + 576, 0, 448 * sizeof(*saved_ltp));
+ ac->fdsp->vector_fmul_reverse(saved_ltp + 448, ac->buf_mdct + 960, &swindow[64], 64);
+
+ for (i = 0; i < 64; i++)
+ saved_ltp[i + 512] = AAC_MUL31(ac->buf_mdct[1023 - i], swindow[63 - i]);
+ } else { // LONG_STOP or ONLY_LONG
+ ac->fdsp->vector_fmul_reverse(saved_ltp, ac->buf_mdct + 512, &lwindow[512], 512);
+
+ for (i = 0; i < 512; i++)
+ saved_ltp[i + 512] = AAC_MUL31(ac->buf_mdct[1023 - i], lwindow[511 - i]);
+ }
+
+ memcpy(sce->ltp_state, sce->ltp_state+1024, 1024 * sizeof(*sce->ltp_state));
+ memcpy(sce->ltp_state+1024, sce->ret, 1024 * sizeof(*sce->ltp_state));
+ memcpy(sce->ltp_state+2048, saved_ltp, 1024 * sizeof(*sce->ltp_state));
+}
+
+/**
+ * Conduct IMDCT and windowing.
+ */
+static void imdct_and_windowing(AACContext *ac, SingleChannelElement *sce)
+{
+ IndividualChannelStream *ics = &sce->ics;
+ 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);
+ INTFLOAT *buf = ac->buf_mdct;
+ INTFLOAT *temp = ac->temp;
+ int i;
+
+ // imdct
+ if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+ for (i = 0; i < 1024; i += 128)
+ ac->mdct_small.imdct_half(&ac->mdct_small, buf + i, in + i);
+ } else {
+ ac->mdct.imdct_half(&ac->mdct, buf, in);
+#if USE_FIXED
+ for (i=0; i<1024; i++)
+ buf[i] = (buf[i] + 4) >> 3;
+#endif /* USE_FIXED */
+ }
+
+ /* window overlapping
+ * NOTE: To simplify the overlapping code, all 'meaningless' short to long
+ * and long to short transitions are considered to be short to short
+ * transitions. This leaves just two cases (long to long and short to short)
+ * with a little special sauce for EIGHT_SHORT_SEQUENCE.
+ */
+ if ((ics->window_sequence[1] == ONLY_LONG_SEQUENCE || ics->window_sequence[1] == LONG_STOP_SEQUENCE) &&
+ (ics->window_sequence[0] == ONLY_LONG_SEQUENCE || ics->window_sequence[0] == LONG_START_SEQUENCE)) {
+ ac->fdsp->vector_fmul_window( out, saved, buf, lwindow_prev, 512);
+ } else {
+ memcpy( out, saved, 448 * sizeof(*out));
+
+ if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+ ac->fdsp->vector_fmul_window(out + 448 + 0*128, saved + 448, buf + 0*128, swindow_prev, 64);
+ ac->fdsp->vector_fmul_window(out + 448 + 1*128, buf + 0*128 + 64, buf + 1*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(out + 448 + 2*128, buf + 1*128 + 64, buf + 2*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(out + 448 + 3*128, buf + 2*128 + 64, buf + 3*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(temp, buf + 3*128 + 64, buf + 4*128, swindow, 64);
+ memcpy( out + 448 + 4*128, temp, 64 * sizeof(*out));
+ } else {
+ ac->fdsp->vector_fmul_window(out + 448, saved + 448, buf, swindow_prev, 64);
+ memcpy( out + 576, buf + 64, 448 * sizeof(*out));
+ }
+ }
+
+ // buffer update
+ if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) {
+ memcpy( saved, temp + 64, 64 * sizeof(*saved));
+ ac->fdsp->vector_fmul_window(saved + 64, buf + 4*128 + 64, buf + 5*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(saved + 192, buf + 5*128 + 64, buf + 6*128, swindow, 64);
+ ac->fdsp->vector_fmul_window(saved + 320, buf + 6*128 + 64, buf + 7*128, swindow, 64);
+ memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(*saved));
+ } else if (ics->window_sequence[0] == LONG_START_SEQUENCE) {
+ memcpy( saved, buf + 512, 448 * sizeof(*saved));
+ memcpy( saved + 448, buf + 7*128 + 64, 64 * sizeof(*saved));
+ } else { // LONG_STOP or ONLY_LONG
+ memcpy( saved, buf + 512, 512 * sizeof(*saved));
+ }
+}
+
+static void imdct_and_windowing_ld(AACContext *ac, SingleChannelElement *sce)
+{
+ IndividualChannelStream *ics = &sce->ics;
+ INTFLOAT *in = sce->coeffs;
+ INTFLOAT *out = sce->ret;
+ INTFLOAT *saved = sce->saved;
+ INTFLOAT *buf = ac->buf_mdct;
+#if USE_FIXED
+ int i;
+#endif /* USE_FIXED */
+
+ // imdct
+ ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
+
+#if USE_FIXED
+ for (i = 0; i < 1024; i++)
+ buf[i] = (buf[i] + 2) >> 2;
+#endif /* USE_FIXED */
+
+ // window overlapping
+ 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);
+ memcpy( out + 320, buf + 64, 192 * sizeof(*out));
+ } else {
+ ac->fdsp->vector_fmul_window(out, saved, buf, AAC_RENAME(ff_sine_512), 256);
+ }
+
+ // buffer update
+ memcpy(saved, buf + 256, 256 * sizeof(*saved));
+}
+
+static void imdct_and_windowing_eld(AACContext *ac, SingleChannelElement *sce)
+{
+ INTFLOAT *in = sce->coeffs;
+ INTFLOAT *out = sce->ret;
+ INTFLOAT *saved = sce->saved;
+ INTFLOAT *buf = ac->buf_mdct;
+ int i;
+ const int n = ac->oc[1].m4ac.frame_length_short ? 480 : 512;
+ const int n2 = n >> 1;
+ const int n4 = n >> 2;
+ const INTFLOAT *const window = n == 480 ? AAC_RENAME(ff_aac_eld_window_480) :
+ AAC_RENAME(ff_aac_eld_window_512);
+
+ // Inverse transform, mapped to the conventional IMDCT by
+ // Chivukula, R.K.; Reznik, Y.A.; Devarajan, V.,
+ // "Efficient algorithms for MPEG-4 AAC-ELD, AAC-LD and AAC-LC filterbanks,"
+ // International Conference on Audio, Language and Image Processing, ICALIP 2008.
+ // URL: http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=4590245&isnumber=4589950
+ for (i = 0; i < n2; i+=2) {
+ INTFLOAT temp;
+ temp = in[i ]; in[i ] = -in[n - 1 - i]; in[n - 1 - i] = temp;
+ temp = -in[i + 1]; in[i + 1] = in[n - 2 - i]; in[n - 2 - i] = temp;
+ }
+#if !USE_FIXED
+ if (n == 480)
+ ac->mdct480->imdct_half(ac->mdct480, buf, in, 1, -1.f/(16*1024*960));
+ else
+#endif
+ ac->mdct.imdct_half(&ac->mdct_ld, buf, in);
+
+#if USE_FIXED
+ for (i = 0; i < 1024; i++)
+ buf[i] = (buf[i] + 1) >> 1;
+#endif /* USE_FIXED */
+
+ for (i = 0; i < n; i+=2) {
+ buf[i] = -buf[i];
+ }
+ // Like with the regular IMDCT at this point we still have the middle half
+ // of a transform but with even symmetry on the left and odd symmetry on
+ // the right
+
+ // window overlapping
+ // The spec says to use samples [0..511] but the reference decoder uses
+ // samples [128..639].
+ for (i = n4; i < n2; i ++) {
+ out[i - n4] = AAC_MUL31( buf[ n2 - 1 - i] , window[i - n4]) +
+ AAC_MUL31( saved[ i + n2] , window[i + n - n4]) +
+ AAC_MUL31(-saved[n + n2 - 1 - i] , window[i + 2*n - n4]) +
+ AAC_MUL31(-saved[ 2*n + n2 + i] , window[i + 3*n - n4]);
+ }
+ for (i = 0; i < n2; i ++) {
+ out[n4 + i] = AAC_MUL31( buf[ i] , window[i + n2 - n4]) +
+ AAC_MUL31(-saved[ n - 1 - i] , window[i + n2 + n - n4]) +
+ AAC_MUL31(-saved[ n + i] , window[i + n2 + 2*n - n4]) +
+ AAC_MUL31( saved[2*n + n - 1 - i] , window[i + n2 + 3*n - n4]);
+ }
+ for (i = 0; i < n4; i ++) {
+ out[n2 + n4 + i] = AAC_MUL31( buf[ i + n2] , window[i + n - n4]) +
+ AAC_MUL31(-saved[n2 - 1 - i] , window[i + 2*n - n4]) +
+ AAC_MUL31(-saved[n + n2 + i] , window[i + 3*n - n4]);
+ }
+
+ // buffer update
+ memmove(saved + n, saved, 2 * n * sizeof(*saved));
+ memcpy( saved, buf, n * sizeof(*saved));
+}
+
+/**
+ * channel coupling transformation interface
+ *
+ * @param apply_coupling_method pointer to (in)dependent coupling function
+ */
+static void apply_channel_coupling(AACContext *ac, ChannelElement *cc,
+ enum RawDataBlockType type, int elem_id,
+ enum CouplingPoint coupling_point,
+ void (*apply_coupling_method)(AACContext *ac, SingleChannelElement *target, ChannelElement *cce, int index))
+{
+ int i, c;
+
+ for (i = 0; i < MAX_ELEM_ID; i++) {
+ ChannelElement *cce = ac->che[TYPE_CCE][i];
+ int index = 0;
+
+ if (cce && cce->coup.coupling_point == coupling_point) {
+ ChannelCoupling *coup = &cce->coup;
+
+ for (c = 0; c <= coup->num_coupled; c++) {
+ if (coup->type[c] == type && coup->id_select[c] == elem_id) {
+ if (coup->ch_select[c] != 1) {
+ apply_coupling_method(ac, &cc->ch[0], cce, index);
+ if (coup->ch_select[c] != 0)
+ index++;
+ }
+ if (coup->ch_select[c] != 2)
+ apply_coupling_method(ac, &cc->ch[1], cce, index++);
+ } else
+ index += 1 + (coup->ch_select[c] == 3);
+ }
+ }
+ }
+}
+
+/**
+ * Convert spectral data to samples, applying all supported tools as appropriate.
+ */
+static void spectral_to_sample(AACContext *ac, int samples)
+{
+ int i, type;
+ void (*imdct_and_window)(AACContext *ac, SingleChannelElement *sce);
+ switch (ac->oc[1].m4ac.object_type) {
+ case AOT_ER_AAC_LD:
+ imdct_and_window = imdct_and_windowing_ld;
+ break;
+ case AOT_ER_AAC_ELD:
+ imdct_and_window = imdct_and_windowing_eld;
+ break;
+ default:
+ imdct_and_window = ac->imdct_and_windowing;
+ }
+ for (type = 3; type >= 0; type--) {
+ for (i = 0; i < MAX_ELEM_ID; i++) {
+ ChannelElement *che = ac->che[type][i];
+ if (che && che->present) {
+ if (type <= TYPE_CPE)
+ apply_channel_coupling(ac, che, type, i, BEFORE_TNS, AAC_RENAME(apply_dependent_coupling));
+ if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP) {
+ if (che->ch[0].ics.predictor_present) {
+ if (che->ch[0].ics.ltp.present)
+ ac->apply_ltp(ac, &che->ch[0]);
+ if (che->ch[1].ics.ltp.present && type == TYPE_CPE)
+ ac->apply_ltp(ac, &che->ch[1]);
+ }
+ }
+ if (che->ch[0].tns.present)
+ ac->apply_tns(che->ch[0].coeffs, &che->ch[0].tns, &che->ch[0].ics, 1);
+ if (che->ch[1].tns.present)
+ ac->apply_tns(che->ch[1].coeffs, &che->ch[1].tns, &che->ch[1].ics, 1);
+ if (type <= TYPE_CPE)
+ apply_channel_coupling(ac, che, type, i, BETWEEN_TNS_AND_IMDCT, AAC_RENAME(apply_dependent_coupling));
+ if (type != TYPE_CCE || che->coup.coupling_point == AFTER_IMDCT) {
+ imdct_and_window(ac, &che->ch[0]);
+ if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP)
+ ac->update_ltp(ac, &che->ch[0]);
+ if (type == TYPE_CPE) {
+ imdct_and_window(ac, &che->ch[1]);
+ if (ac->oc[1].m4ac.object_type == AOT_AAC_LTP)
+ ac->update_ltp(ac, &che->ch[1]);
+ }
+ if (ac->oc[1].m4ac.sbr > 0) {
+ AAC_RENAME(ff_sbr_apply)(ac, &che->sbr, type, che->ch[0].ret, che->ch[1].ret);
+ }
+ }
+ if (type <= TYPE_CCE)
+ apply_channel_coupling(ac, che, type, i, AFTER_IMDCT, AAC_RENAME(apply_independent_coupling));
+
+#if USE_FIXED
+ {
+ int j;
+ /* preparation for resampler */
+ for(j = 0; j<samples; j++){
+ che->ch[0].ret[j] = (int32_t)av_clipl_int32((int64_t)che->ch[0].ret[j]<<7)+0x8000;
+ if(type == TYPE_CPE)
+ che->ch[1].ret[j] = (int32_t)av_clipl_int32((int64_t)che->ch[1].ret[j]<<7)+0x8000;
+ }
+ }
+#endif /* USE_FIXED */
+ che->present = 0;
+ } else if (che) {
+ av_log(ac->avctx, AV_LOG_VERBOSE, "ChannelElement %d.%d missing \n", type, i);
+ }
+ }
+ }
+}
+
+static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb)
+{
+ int size;
+ AACADTSHeaderInfo hdr_info;
+ uint8_t layout_map[MAX_ELEM_ID*4][3];
+ int layout_map_tags, ret;
+
+ size = avpriv_aac_parse_header(gb, &hdr_info);
+ if (size > 0) {
+ if (!ac->warned_num_aac_frames && hdr_info.num_aac_frames != 1) {
+ // This is 2 for "VLB " audio in NSV files.
+ // See samples/nsv/vlb_audio.
+ avpriv_report_missing_feature(ac->avctx,
+ "More than one AAC RDB per ADTS frame");
+ ac->warned_num_aac_frames = 1;
+ }
+ push_output_configuration(ac);
+ if (hdr_info.chan_config) {
+ ac->oc[1].m4ac.chan_config = hdr_info.chan_config;
+ if ((ret = set_default_channel_config(ac->avctx,
+ layout_map,
+ &layout_map_tags,
+ hdr_info.chan_config)) < 0)
+ return ret;
+ if ((ret = output_configure(ac, layout_map, layout_map_tags,
+ FFMAX(ac->oc[1].status,
+ OC_TRIAL_FRAME), 0)) < 0)
+ return ret;
+ } else {
+ ac->oc[1].m4ac.chan_config = 0;
+ /**
+ * dual mono frames in Japanese DTV can have chan_config 0
+ * WITHOUT specifying PCE.
+ * thus, set dual mono as default.
+ */
+ if (ac->dmono_mode && ac->oc[0].status == OC_NONE) {
+ layout_map_tags = 2;
+ layout_map[0][0] = layout_map[1][0] = TYPE_SCE;
+ layout_map[0][2] = layout_map[1][2] = AAC_CHANNEL_FRONT;
+ layout_map[0][1] = 0;
+ layout_map[1][1] = 1;
+ if (output_configure(ac, layout_map, layout_map_tags,
+ OC_TRIAL_FRAME, 0))
+ return -7;
+ }
+ }
+ ac->oc[1].m4ac.sample_rate = hdr_info.sample_rate;
+ ac->oc[1].m4ac.sampling_index = hdr_info.sampling_index;
+ ac->oc[1].m4ac.object_type = hdr_info.object_type;
+ ac->oc[1].m4ac.frame_length_short = 0;
+ if (ac->oc[0].status != OC_LOCKED ||
+ ac->oc[0].m4ac.chan_config != hdr_info.chan_config ||
+ ac->oc[0].m4ac.sample_rate != hdr_info.sample_rate) {
+ ac->oc[1].m4ac.sbr = -1;
+ ac->oc[1].m4ac.ps = -1;
+ }
+ if (!hdr_info.crc_absent)
+ skip_bits(gb, 16);
+ }
+ return size;
+}
+
+static int aac_decode_er_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, GetBitContext *gb)
+{
+ AACContext *ac = avctx->priv_data;
+ const MPEG4AudioConfig *const m4ac = &ac->oc[1].m4ac;
+ ChannelElement *che;
+ int err, i;
+ int samples = m4ac->frame_length_short ? 960 : 1024;
+ int chan_config = m4ac->chan_config;
+ int aot = m4ac->object_type;
+
+ if (aot == AOT_ER_AAC_LD || aot == AOT_ER_AAC_ELD)
+ samples >>= 1;
+
+ ac->frame = data;
+
+ if ((err = frame_configure_elements(avctx)) < 0)
+ return err;
+
+ // The FF_PROFILE_AAC_* defines are all object_type - 1
+ // This may lead to an undefined profile being signaled
+ ac->avctx->profile = aot - 1;
+
+ ac->tags_mapped = 0;
+
+ if (chan_config < 0 || (chan_config >= 8 && chan_config < 11) || chan_config >= 13) {
+ avpriv_request_sample(avctx, "Unknown ER channel configuration %d",
+ chan_config);
+ return AVERROR_INVALIDDATA;
+ }
+ for (i = 0; i < tags_per_config[chan_config]; i++) {
+ const int elem_type = aac_channel_layout_map[chan_config-1][i][0];
+ const int elem_id = aac_channel_layout_map[chan_config-1][i][1];
+ if (!(che=get_che(ac, elem_type, elem_id))) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "channel element %d.%d is not allocated\n",
+ elem_type, elem_id);
+ return AVERROR_INVALIDDATA;
+ }
+ che->present = 1;
+ if (aot != AOT_ER_AAC_ELD)
+ skip_bits(gb, 4);
+ switch (elem_type) {
+ case TYPE_SCE:
+ err = decode_ics(ac, &che->ch[0], gb, 0, 0);
+ break;
+ case TYPE_CPE:
+ err = decode_cpe(ac, gb, che);
+ break;
+ case TYPE_LFE:
+ err = decode_ics(ac, &che->ch[0], gb, 0, 0);
+ break;
+ }
+ if (err < 0)
+ return err;
+ }
+
+ spectral_to_sample(ac, samples);
+
+ if (!ac->frame->data[0] && samples) {
+ av_log(avctx, AV_LOG_ERROR, "no frame data found\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ ac->frame->nb_samples = samples;
+ ac->frame->sample_rate = avctx->sample_rate;
+ *got_frame_ptr = 1;
+
+ skip_bits_long(gb, get_bits_left(gb));
+ return 0;
+}
+
+static int aac_decode_frame_int(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, GetBitContext *gb, AVPacket *avpkt)
+{
+ AACContext *ac = avctx->priv_data;
+ ChannelElement *che = NULL, *che_prev = NULL;
+ enum RawDataBlockType elem_type, elem_type_prev = TYPE_END;
+ int err, elem_id;
+ int samples = 0, multiplier, audio_found = 0, pce_found = 0;
+ int is_dmono, sce_count = 0;
+
+ ac->frame = data;
+
+ if (show_bits(gb, 12) == 0xfff) {
+ if ((err = parse_adts_frame_header(ac, gb)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error decoding AAC frame header.\n");
+ goto fail;
+ }
+ if (ac->oc[1].m4ac.sampling_index > 12) {
+ av_log(ac->avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", ac->oc[1].m4ac.sampling_index);
+ err = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ }
+
+ if ((err = frame_configure_elements(avctx)) < 0)
+ goto fail;
+
+ // The FF_PROFILE_AAC_* defines are all object_type - 1
+ // This may lead to an undefined profile being signaled
+ ac->avctx->profile = ac->oc[1].m4ac.object_type - 1;
+
+ ac->tags_mapped = 0;
+ // parse
+ while ((elem_type = get_bits(gb, 3)) != TYPE_END) {
+ elem_id = get_bits(gb, 4);
+
+ if (avctx->debug & FF_DEBUG_STARTCODE)
+ av_log(avctx, AV_LOG_DEBUG, "Elem type:%x id:%x\n", elem_type, elem_id);
+
+ if (!avctx->channels && elem_type != TYPE_PCE) {
+ err = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ if (elem_type < TYPE_DSE) {
+ if (!(che=get_che(ac, elem_type, elem_id))) {
+ av_log(ac->avctx, AV_LOG_ERROR, "channel element %d.%d is not allocated\n",
+ elem_type, elem_id);
+ err = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ samples = 1024;
+ che->present = 1;
+ }
+
+ switch (elem_type) {
+
+ case TYPE_SCE:
+ err = decode_ics(ac, &che->ch[0], gb, 0, 0);
+ audio_found = 1;
+ sce_count++;
+ break;
+
+ case TYPE_CPE:
+ err = decode_cpe(ac, gb, che);
+ audio_found = 1;
+ break;
+
+ case TYPE_CCE:
+ err = decode_cce(ac, gb, che);
+ break;
+
+ case TYPE_LFE:
+ err = decode_ics(ac, &che->ch[0], gb, 0, 0);
+ audio_found = 1;
+ break;
+
+ case TYPE_DSE:
+ err = skip_data_stream_element(ac, gb);
+ break;
+
+ case TYPE_PCE: {
+ uint8_t layout_map[MAX_ELEM_ID*4][3];
+ int tags;
+ push_output_configuration(ac);
+ tags = decode_pce(avctx, &ac->oc[1].m4ac, layout_map, gb);
+ if (tags < 0) {
+ err = tags;
+ break;
+ }
+ if (pce_found) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Not evaluating a further program_config_element as this construct is dubious at best.\n");
+ } else {
+ err = output_configure(ac, layout_map, tags, OC_TRIAL_PCE, 1);
+ if (!err)
+ ac->oc[1].m4ac.chan_config = 0;
+ pce_found = 1;
+ }
+ break;
+ }
+
+ case TYPE_FIL:
+ if (elem_id == 15)
+ elem_id += get_bits(gb, 8) - 1;
+ if (get_bits_left(gb) < 8 * elem_id) {
+ av_log(avctx, AV_LOG_ERROR, "TYPE_FIL: "overread_err);
+ err = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ while (elem_id > 0)
+ elem_id -= decode_extension_payload(ac, gb, elem_id, che_prev, elem_type_prev);
+ err = 0; /* FIXME */
+ break;
+
+ default:
+ err = AVERROR_BUG; /* should not happen, but keeps compiler happy */
+ break;
+ }
+
+ che_prev = che;
+ elem_type_prev = elem_type;
+
+ if (err)
+ goto fail;
+
+ if (get_bits_left(gb) < 3) {
+ av_log(avctx, AV_LOG_ERROR, overread_err);
+ err = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ }
+
+ if (!avctx->channels) {
+ *got_frame_ptr = 0;
+ return 0;
+ }
+
+ multiplier = (ac->oc[1].m4ac.sbr == 1) ? ac->oc[1].m4ac.ext_sample_rate > ac->oc[1].m4ac.sample_rate : 0;
+ samples <<= multiplier;
+
+ spectral_to_sample(ac, samples);
+
+ if (ac->oc[1].status && audio_found) {
+ avctx->sample_rate = ac->oc[1].m4ac.sample_rate << multiplier;
+ avctx->frame_size = samples;
+ ac->oc[1].status = OC_LOCKED;
+ }
+
+ if (multiplier) {
+ int side_size;
+ const uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_SKIP_SAMPLES, &side_size);
+ if (side && side_size>=4)
+ AV_WL32(side, 2*AV_RL32(side));
+ }
+
+ if (!ac->frame->data[0] && samples) {
+ av_log(avctx, AV_LOG_ERROR, "no frame data found\n");
+ err = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ if (samples) {
+ ac->frame->nb_samples = samples;
+ ac->frame->sample_rate = avctx->sample_rate;
+ } else
+ av_frame_unref(ac->frame);
+ *got_frame_ptr = !!samples;
+
+ /* for dual-mono audio (SCE + SCE) */
+ is_dmono = ac->dmono_mode && sce_count == 2 &&
+ ac->oc[1].channel_layout == (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT);
+ if (is_dmono) {
+ if (ac->dmono_mode == 1)
+ ((AVFrame *)data)->data[1] =((AVFrame *)data)->data[0];
+ else if (ac->dmono_mode == 2)
+ ((AVFrame *)data)->data[0] =((AVFrame *)data)->data[1];
+ }
+
+ return 0;
+fail:
+ pop_output_configuration(ac);
+ return err;
+}
+
+static int aac_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ AACContext *ac = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ GetBitContext gb;
+ int buf_consumed;
+ int buf_offset;
+ int err;
+ int 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;
+ const uint8_t *jp_dualmono = av_packet_get_side_data(avpkt,
+ AV_PKT_DATA_JP_DUALMONO,
+ &jp_dualmono_size);
+
+ if (new_extradata && 0) {
+ av_free(avctx->extradata);
+ avctx->extradata = av_mallocz(new_extradata_size +
+ AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!avctx->extradata)
+ return AVERROR(ENOMEM);
+ avctx->extradata_size = new_extradata_size;
+ memcpy(avctx->extradata, new_extradata, new_extradata_size);
+ push_output_configuration(ac);
+ if (decode_audio_specific_config(ac, ac->avctx, &ac->oc[1].m4ac,
+ avctx->extradata,
+ avctx->extradata_size*8LL, 1) < 0) {
+ pop_output_configuration(ac);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ ac->dmono_mode = 0;
+ if (jp_dualmono && jp_dualmono_size > 0)
+ ac->dmono_mode = 1 + *jp_dualmono;
+ if (ac->force_dmono_mode >= 0)
+ ac->dmono_mode = ac->force_dmono_mode;
+
+ if (INT_MAX / 8 <= buf_size)
+ return AVERROR_INVALIDDATA;
+
+ if ((err = init_get_bits8(&gb, buf, buf_size)) < 0)
+ return err;
+
+ switch (ac->oc[1].m4ac.object_type) {
+ case AOT_ER_AAC_LC:
+ case AOT_ER_AAC_LTP:
+ case AOT_ER_AAC_LD:
+ case AOT_ER_AAC_ELD:
+ err = aac_decode_er_frame(avctx, data, got_frame_ptr, &gb);
+ break;
+ default:
+ err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb, avpkt);
+ }
+ if (err < 0)
+ return err;
+
+ buf_consumed = (get_bits_count(&gb) + 7) >> 3;
+ for (buf_offset = buf_consumed; buf_offset < buf_size; buf_offset++)
+ if (buf[buf_offset])
+ break;
+
+ return buf_size > buf_offset ? buf_consumed : buf_size;
+}
+
+static av_cold int aac_decode_close(AVCodecContext *avctx)
+{
+ AACContext *ac = avctx->priv_data;
+ int i, type;
+
+ for (i = 0; i < MAX_ELEM_ID; i++) {
+ for (type = 0; type < 4; type++) {
+ if (ac->che[type][i])
+ AAC_RENAME(ff_aac_sbr_ctx_close)(&ac->che[type][i]->sbr);
+ av_freep(&ac->che[type][i]);
+ }
+ }
+
+ ff_mdct_end(&ac->mdct);
+ ff_mdct_end(&ac->mdct_small);
+ ff_mdct_end(&ac->mdct_ld);
+ ff_mdct_end(&ac->mdct_ltp);
+#if !USE_FIXED
+ ff_imdct15_uninit(&ac->mdct480);
+#endif
+ av_freep(&ac->fdsp);
+ return 0;
+}
+
+static void aacdec_init(AACContext *c)
+{
+ c->imdct_and_windowing = imdct_and_windowing;
+ c->apply_ltp = apply_ltp;
+ c->apply_tns = apply_tns;
+ c->windowing_and_mdct_ltp = windowing_and_mdct_ltp;
+ c->update_ltp = update_ltp;
+#if USE_FIXED
+ c->vector_pow43 = vector_pow43;
+ c->subband_scale = subband_scale;
+#endif
+
+#if !USE_FIXED
+ if(ARCH_MIPS)
+ ff_aacdec_init_mips(c);
+#endif /* !USE_FIXED */
+}
+/**
+ * AVOptions for Japanese DTV specific extensions (ADTS only)
+ */
+#define AACDEC_FLAGS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
+static const AVOption options[] = {
+ {"dual_mono_mode", "Select the channel to decode for dual mono",
+ offsetof(AACContext, force_dmono_mode), AV_OPT_TYPE_INT, {.i64=-1}, -1, 2,
+ AACDEC_FLAGS, "dual_mono_mode"},
+
+ {"auto", "autoselection", 0, AV_OPT_TYPE_CONST, {.i64=-1}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"},
+ {"main", "Select Main/Left channel", 0, AV_OPT_TYPE_CONST, {.i64= 1}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"},
+ {"sub" , "Select Sub/Right channel", 0, AV_OPT_TYPE_CONST, {.i64= 2}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"},
+ {"both", "Select both channels", 0, AV_OPT_TYPE_CONST, {.i64= 0}, INT_MIN, INT_MAX, AACDEC_FLAGS, "dual_mono_mode"},
+
+ {NULL},
+};
+
+static const AVClass aac_decoder_class = {
+ .class_name = "AAC decoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVProfile profiles[] = {
+ { FF_PROFILE_AAC_MAIN, "Main" },
+ { FF_PROFILE_AAC_LOW, "LC" },
+ { FF_PROFILE_AAC_SSR, "SSR" },
+ { FF_PROFILE_AAC_LTP, "LTP" },
+ { FF_PROFILE_AAC_HE, "HE-AAC" },
+ { FF_PROFILE_AAC_HE_V2, "HE-AACv2" },
+ { FF_PROFILE_AAC_LD, "LD" },
+ { FF_PROFILE_AAC_ELD, "ELD" },
+ { FF_PROFILE_UNKNOWN },
+};
diff --git a/ffmpeg-2-8-11/libavcodec/aacdectab.h b/ffmpeg-2-8-12/libavcodec/aacdectab.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacdectab.h
rename to ffmpeg-2-8-12/libavcodec/aacdectab.h
diff --git a/ffmpeg-2-8-11/libavcodec/aacenc.c b/ffmpeg-2-8-12/libavcodec/aacenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacenc.c
rename to ffmpeg-2-8-12/libavcodec/aacenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacenc.h b/ffmpeg-2-8-12/libavcodec/aacenc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacenc.h
rename to ffmpeg-2-8-12/libavcodec/aacenc.h
diff --git a/ffmpeg-2-8-11/libavcodec/aacenc_is.c b/ffmpeg-2-8-12/libavcodec/aacenc_is.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacenc_is.c
rename to ffmpeg-2-8-12/libavcodec/aacenc_is.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacenc_is.h b/ffmpeg-2-8-12/libavcodec/aacenc_is.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacenc_is.h
rename to ffmpeg-2-8-12/libavcodec/aacenc_is.h
diff --git a/ffmpeg-2-8-11/libavcodec/aacenc_pred.c b/ffmpeg-2-8-12/libavcodec/aacenc_pred.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacenc_pred.c
rename to ffmpeg-2-8-12/libavcodec/aacenc_pred.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacenc_pred.h b/ffmpeg-2-8-12/libavcodec/aacenc_pred.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacenc_pred.h
rename to ffmpeg-2-8-12/libavcodec/aacenc_pred.h
diff --git a/ffmpeg-2-8-11/libavcodec/aacenc_quantization.h b/ffmpeg-2-8-12/libavcodec/aacenc_quantization.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacenc_quantization.h
rename to ffmpeg-2-8-12/libavcodec/aacenc_quantization.h
diff --git a/ffmpeg-2-8-11/libavcodec/aacenc_tns.c b/ffmpeg-2-8-12/libavcodec/aacenc_tns.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacenc_tns.c
rename to ffmpeg-2-8-12/libavcodec/aacenc_tns.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacenc_tns.h b/ffmpeg-2-8-12/libavcodec/aacenc_tns.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacenc_tns.h
rename to ffmpeg-2-8-12/libavcodec/aacenc_tns.h
diff --git a/ffmpeg-2-8-11/libavcodec/aacenc_utils.h b/ffmpeg-2-8-12/libavcodec/aacenc_utils.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacenc_utils.h
rename to ffmpeg-2-8-12/libavcodec/aacenc_utils.h
diff --git a/ffmpeg-2-8-11/libavcodec/aacenctab.c b/ffmpeg-2-8-12/libavcodec/aacenctab.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacenctab.c
rename to ffmpeg-2-8-12/libavcodec/aacenctab.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacenctab.h b/ffmpeg-2-8-12/libavcodec/aacenctab.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacenctab.h
rename to ffmpeg-2-8-12/libavcodec/aacenctab.h
diff --git a/ffmpeg-2-8-12/libavcodec/aacps.c b/ffmpeg-2-8-12/libavcodec/aacps.c
new file mode 100644
index 0000000..01f6d1f
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/aacps.c
@@ -0,0 +1,1049 @@
+/*
+ * MPEG-4 Parametric Stereo decoding functions
+ * Copyright (c) 2010 Alex Converse <alex.converse at gmail.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
+ *
+ * Note: Rounding-to-nearest used unless otherwise stated
+ *
+ */
+
+#include <stdint.h>
+#include "libavutil/common.h"
+#include "libavutil/mathematics.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "aacps.h"
+#if USE_FIXED
+#include "aacps_fixed_tablegen.h"
+#else
+#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 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 -1; \
+}
+
+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;
+ for (i = 0; i < PS_MAX_NR_IPDOPD; i++) {
+ opd_hist[i] = 0;
+ ipd_hist[i] = 0;
+ }
+}
+
+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);
+ } 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)
+{
+ int i, j;
+ for (i = 0; i < len; i++, in++) {
+ INT64FLOAT re_in = AAC_MUL31(filter[6], in[6][0]); //real inphase
+ INT64FLOAT re_op = 0.0f; //real out of phase
+ INT64FLOAT im_in = AAC_MUL31(filter[6], in[6][1]); //imag inphase
+ INT64FLOAT im_op = 0.0f; //imag out of phase
+ for (j = 0; j < 6; j += 2) {
+ re_op += (INT64FLOAT)filter[j+1] * (in[j+1][0] + in[12-j-1][0]);
+ im_op += (INT64FLOAT)filter[j+1] * (in[j+1][1] + in[12-j-1][1]);
+ }
+
+#if USE_FIXED
+ re_op = (re_op + 0x40000000) >> 31;
+ im_op = (im_op + 0x40000000) >> 31;
+#endif /* USE_FIXED */
+
+ out[ reverse][i][0] = (INTFLOAT)(re_in + re_op);
+ out[ reverse][i][1] = (INTFLOAT)(im_in + im_op);
+ out[!reverse][i][0] = (INTFLOAT)(re_in - re_op);
+ out[!reverse][i][1] = (INTFLOAT)(im_in - im_op);
+ }
+}
+
+/** Split one subband into 6 subsubbands with a complex filter */
+static void hybrid6_cx(PSDSPContext *dsp, INTFLOAT (*in)[2], INTFLOAT (*out)[32][2],
+ TABLE_CONST INTFLOAT (*filter)[8][2], int len)
+{
+ int i;
+ int N = 8;
+ LOCAL_ALIGNED_16(INTFLOAT, temp, [8], [2]);
+
+ for (i = 0; i < len; i++, in++) {
+ dsp->hybrid_analysis(temp, in, (const INTFLOAT (*)[8][2]) filter, 1, N);
+ out[0][i][0] = temp[6][0];
+ out[0][i][1] = temp[6][1];
+ out[1][i][0] = temp[7][0];
+ out[1][i][1] = temp[7][1];
+ out[2][i][0] = temp[0][0];
+ out[2][i][1] = temp[0][1];
+ out[3][i][0] = temp[1][0];
+ out[3][i][1] = temp[1][1];
+ out[4][i][0] = temp[2][0] + temp[5][0];
+ out[4][i][1] = temp[2][1] + temp[5][1];
+ out[5][i][0] = temp[3][0] + temp[4][0];
+ out[5][i][1] = temp[3][1] + temp[4][1];
+ }
+}
+
+static void hybrid4_8_12_cx(PSDSPContext *dsp,
+ INTFLOAT (*in)[2], INTFLOAT (*out)[32][2],
+ TABLE_CONST INTFLOAT (*filter)[8][2], int N, int len)
+{
+ int i;
+
+ for (i = 0; i < len; i++, in++) {
+ dsp->hybrid_analysis(out[0] + i, in, (const INTFLOAT (*)[8][2]) filter, 32, N);
+ }
+}
+
+static void hybrid_analysis(PSDSPContext *dsp, INTFLOAT out[91][32][2],
+ INTFLOAT in[5][44][2], INTFLOAT L[2][38][64],
+ int is34, int len)
+{
+ int i, j;
+ for (i = 0; i < 5; i++) {
+ for (j = 0; j < 38; j++) {
+ in[i][j+6][0] = L[0][j][i];
+ in[i][j+6][1] = L[1][j][i];
+ }
+ }
+ if (is34) {
+ hybrid4_8_12_cx(dsp, in[0], out, f34_0_12, 12, len);
+ hybrid4_8_12_cx(dsp, in[1], out+12, f34_1_8, 8, len);
+ hybrid4_8_12_cx(dsp, in[2], out+20, f34_2_4, 4, len);
+ hybrid4_8_12_cx(dsp, in[3], out+24, f34_2_4, 4, len);
+ hybrid4_8_12_cx(dsp, in[4], out+28, f34_2_4, 4, len);
+ dsp->hybrid_analysis_ileave(out + 27, L, 5, len);
+ } else {
+ hybrid6_cx(dsp, in[0], out, f20_0_8, len);
+ hybrid2_re(in[1], out+6, g1_Q2, len, 1);
+ hybrid2_re(in[2], out+8, g1_Q2, len, 0);
+ dsp->hybrid_analysis_ileave(out + 7, L, 3, len);
+ }
+ //update in_buf
+ for (i = 0; i < 5; i++) {
+ memcpy(in[i], in[i]+32, 6 * sizeof(in[i][0]));
+ }
+}
+
+static void hybrid_synthesis(PSDSPContext *dsp, INTFLOAT out[2][38][64],
+ INTFLOAT in[91][32][2], int is34, int len)
+{
+ int i, n;
+ if (is34) {
+ for (n = 0; n < len; n++) {
+ memset(out[0][n], 0, 5*sizeof(out[0][n][0]));
+ memset(out[1][n], 0, 5*sizeof(out[1][n][0]));
+ for (i = 0; i < 12; i++) {
+ out[0][n][0] += in[ i][n][0];
+ out[1][n][0] += in[ i][n][1];
+ }
+ for (i = 0; i < 8; i++) {
+ out[0][n][1] += in[12+i][n][0];
+ out[1][n][1] += in[12+i][n][1];
+ }
+ for (i = 0; i < 4; i++) {
+ out[0][n][2] += in[20+i][n][0];
+ out[1][n][2] += in[20+i][n][1];
+ out[0][n][3] += in[24+i][n][0];
+ out[1][n][3] += in[24+i][n][1];
+ out[0][n][4] += in[28+i][n][0];
+ out[1][n][4] += in[28+i][n][1];
+ }
+ }
+ dsp->hybrid_synthesis_deint(out, in + 27, 5, len);
+ } else {
+ for (n = 0; n < len; n++) {
+ out[0][n][0] = in[0][n][0] + in[1][n][0] + in[2][n][0] +
+ in[3][n][0] + in[4][n][0] + in[5][n][0];
+ out[1][n][0] = in[0][n][1] + in[1][n][1] + in[2][n][1] +
+ in[3][n][1] + in[4][n][1] + in[5][n][1];
+ out[0][n][1] = in[6][n][0] + in[7][n][0];
+ out[1][n][1] = in[6][n][1] + in[7][n][1];
+ out[0][n][2] = in[8][n][0] + in[9][n][0];
+ out[1][n][2] = in[8][n][1] + in[9][n][1];
+ }
+ dsp->hybrid_synthesis_deint(out, in + 7, 3, len);
+ }
+}
+
+/// All-pass filter decay slope
+#define DECAY_SLOPE Q30(0.05f)
+/// Number of frequency bands that can be addressed by the parameter index, b(k)
+static const int NR_PAR_BANDS[] = { 20, 34 };
+static const int NR_IPDOPD_BANDS[] = { 11, 17 };
+/// Number of frequency bands that can be addressed by the sub subband index, k
+static const int NR_BANDS[] = { 71, 91 };
+/// Start frequency band for the all-pass filter decay slope
+static const int DECAY_CUTOFF[] = { 10, 32 };
+/// Number of all-pass filer bands
+static const int NR_ALLPASS_BANDS[] = { 30, 50 };
+/// First stereo band using the short one sample delay
+static const int SHORT_DELAY_BAND[] = { 42, 62 };
+
+/** Table 8.46 */
+static void map_idx_10_to_20(int8_t *par_mapped, const int8_t *par, int full)
+{
+ int b;
+ if (full)
+ b = 9;
+ else {
+ b = 4;
+ par_mapped[10] = 0;
+ }
+ for (; b >= 0; b--) {
+ par_mapped[2*b+1] = par_mapped[2*b] = par[b];
+ }
+}
+
+static void map_idx_34_to_20(int8_t *par_mapped, const int8_t *par, int full)
+{
+ par_mapped[ 0] = (2*par[ 0] + par[ 1]) / 3;
+ par_mapped[ 1] = ( par[ 1] + 2*par[ 2]) / 3;
+ par_mapped[ 2] = (2*par[ 3] + par[ 4]) / 3;
+ par_mapped[ 3] = ( par[ 4] + 2*par[ 5]) / 3;
+ par_mapped[ 4] = ( par[ 6] + par[ 7]) / 2;
+ par_mapped[ 5] = ( par[ 8] + par[ 9]) / 2;
+ par_mapped[ 6] = par[10];
+ par_mapped[ 7] = par[11];
+ par_mapped[ 8] = ( par[12] + par[13]) / 2;
+ par_mapped[ 9] = ( par[14] + par[15]) / 2;
+ par_mapped[10] = par[16];
+ if (full) {
+ par_mapped[11] = par[17];
+ par_mapped[12] = par[18];
+ par_mapped[13] = par[19];
+ par_mapped[14] = ( par[20] + par[21]) / 2;
+ par_mapped[15] = ( par[22] + par[23]) / 2;
+ par_mapped[16] = ( par[24] + par[25]) / 2;
+ par_mapped[17] = ( par[26] + par[27]) / 2;
+ par_mapped[18] = ( par[28] + par[29] + par[30] + par[31]) / 4;
+ par_mapped[19] = ( par[32] + par[33]) / 2;
+ }
+}
+
+static void map_val_34_to_20(INTFLOAT par[PS_MAX_NR_IIDICC])
+{
+#if USE_FIXED
+ par[ 0] = (int)(((int64_t)(par[ 0] + (par[ 1]>>1)) * 1431655765 + \
+ 0x40000000) >> 31);
+ par[ 1] = (int)(((int64_t)((par[ 1]>>1) + par[ 2]) * 1431655765 + \
+ 0x40000000) >> 31);
+ par[ 2] = (int)(((int64_t)(par[ 3] + (par[ 4]>>1)) * 1431655765 + \
+ 0x40000000) >> 31);
+ par[ 3] = (int)(((int64_t)((par[ 4]>>1) + par[ 5]) * 1431655765 + \
+ 0x40000000) >> 31);
+#else
+ par[ 0] = (2*par[ 0] + par[ 1]) * 0.33333333f;
+ par[ 1] = ( par[ 1] + 2*par[ 2]) * 0.33333333f;
+ par[ 2] = (2*par[ 3] + par[ 4]) * 0.33333333f;
+ par[ 3] = ( par[ 4] + 2*par[ 5]) * 0.33333333f;
+#endif /* USE_FIXED */
+ par[ 4] = AAC_HALF_SUM(par[ 6], par[ 7]);
+ par[ 5] = AAC_HALF_SUM(par[ 8], par[ 9]);
+ par[ 6] = par[10];
+ par[ 7] = par[11];
+ par[ 8] = AAC_HALF_SUM(par[12], par[13]);
+ par[ 9] = AAC_HALF_SUM(par[14], par[15]);
+ par[10] = par[16];
+ par[11] = par[17];
+ par[12] = par[18];
+ par[13] = par[19];
+ par[14] = AAC_HALF_SUM(par[20], par[21]);
+ par[15] = AAC_HALF_SUM(par[22], par[23]);
+ par[16] = AAC_HALF_SUM(par[24], par[25]);
+ par[17] = AAC_HALF_SUM(par[26], par[27]);
+#if USE_FIXED
+ par[18] = (((par[28]+2)>>2) + ((par[29]+2)>>2) + ((par[30]+2)>>2) + ((par[31]+2)>>2));
+#else
+ par[18] = ( par[28] + par[29] + par[30] + par[31]) * 0.25f;
+#endif /* USE_FIXED */
+ par[19] = AAC_HALF_SUM(par[32], par[33]);
+}
+
+static void map_idx_10_to_34(int8_t *par_mapped, const int8_t *par, int full)
+{
+ if (full) {
+ par_mapped[33] = par[9];
+ par_mapped[32] = par[9];
+ par_mapped[31] = par[9];
+ par_mapped[30] = par[9];
+ par_mapped[29] = par[9];
+ par_mapped[28] = par[9];
+ par_mapped[27] = par[8];
+ par_mapped[26] = par[8];
+ par_mapped[25] = par[8];
+ par_mapped[24] = par[8];
+ par_mapped[23] = par[7];
+ par_mapped[22] = par[7];
+ par_mapped[21] = par[7];
+ par_mapped[20] = par[7];
+ par_mapped[19] = par[6];
+ par_mapped[18] = par[6];
+ par_mapped[17] = par[5];
+ par_mapped[16] = par[5];
+ } else {
+ par_mapped[16] = 0;
+ }
+ par_mapped[15] = par[4];
+ par_mapped[14] = par[4];
+ par_mapped[13] = par[4];
+ par_mapped[12] = par[4];
+ par_mapped[11] = par[3];
+ par_mapped[10] = par[3];
+ par_mapped[ 9] = par[2];
+ par_mapped[ 8] = par[2];
+ par_mapped[ 7] = par[2];
+ par_mapped[ 6] = par[2];
+ par_mapped[ 5] = par[1];
+ par_mapped[ 4] = par[1];
+ par_mapped[ 3] = par[1];
+ par_mapped[ 2] = par[0];
+ par_mapped[ 1] = par[0];
+ par_mapped[ 0] = par[0];
+}
+
+static void map_idx_20_to_34(int8_t *par_mapped, const int8_t *par, int full)
+{
+ if (full) {
+ par_mapped[33] = par[19];
+ par_mapped[32] = par[19];
+ par_mapped[31] = par[18];
+ par_mapped[30] = par[18];
+ par_mapped[29] = par[18];
+ par_mapped[28] = par[18];
+ par_mapped[27] = par[17];
+ par_mapped[26] = par[17];
+ par_mapped[25] = par[16];
+ par_mapped[24] = par[16];
+ par_mapped[23] = par[15];
+ par_mapped[22] = par[15];
+ par_mapped[21] = par[14];
+ par_mapped[20] = par[14];
+ par_mapped[19] = par[13];
+ par_mapped[18] = par[12];
+ par_mapped[17] = par[11];
+ }
+ par_mapped[16] = par[10];
+ par_mapped[15] = par[ 9];
+ par_mapped[14] = par[ 9];
+ par_mapped[13] = par[ 8];
+ par_mapped[12] = par[ 8];
+ par_mapped[11] = par[ 7];
+ par_mapped[10] = par[ 6];
+ par_mapped[ 9] = par[ 5];
+ par_mapped[ 8] = par[ 5];
+ par_mapped[ 7] = par[ 4];
+ par_mapped[ 6] = par[ 4];
+ par_mapped[ 5] = par[ 3];
+ par_mapped[ 4] = (par[ 2] + par[ 3]) / 2;
+ par_mapped[ 3] = par[ 2];
+ par_mapped[ 2] = par[ 1];
+ par_mapped[ 1] = (par[ 0] + par[ 1]) / 2;
+ par_mapped[ 0] = par[ 0];
+}
+
+static void map_val_20_to_34(INTFLOAT par[PS_MAX_NR_IIDICC])
+{
+ par[33] = par[19];
+ par[32] = par[19];
+ par[31] = par[18];
+ par[30] = par[18];
+ par[29] = par[18];
+ par[28] = par[18];
+ par[27] = par[17];
+ par[26] = par[17];
+ par[25] = par[16];
+ par[24] = par[16];
+ par[23] = par[15];
+ par[22] = par[15];
+ par[21] = par[14];
+ par[20] = par[14];
+ par[19] = par[13];
+ par[18] = par[12];
+ par[17] = par[11];
+ par[16] = par[10];
+ par[15] = par[ 9];
+ par[14] = par[ 9];
+ par[13] = par[ 8];
+ par[12] = par[ 8];
+ par[11] = par[ 7];
+ par[10] = par[ 6];
+ par[ 9] = par[ 5];
+ par[ 8] = par[ 5];
+ par[ 7] = par[ 4];
+ par[ 6] = par[ 4];
+ par[ 5] = par[ 3];
+ par[ 4] = AAC_HALF_SUM(par[ 2], par[ 3]);
+ par[ 3] = par[ 2];
+ par[ 2] = par[ 1];
+ par[ 1] = AAC_HALF_SUM(par[ 0], par[ 1]);
+}
+
+static void decorrelation(PSContext *ps, INTFLOAT (*out)[32][2], const INTFLOAT (*s)[32][2], int is34)
+{
+ LOCAL_ALIGNED_16(INTFLOAT, power, [34], [PS_QMF_TIME_SLOTS]);
+ LOCAL_ALIGNED_16(INTFLOAT, transient_gain, [34], [PS_QMF_TIME_SLOTS]);
+ INTFLOAT *peak_decay_nrg = ps->peak_decay_nrg;
+ INTFLOAT *power_smooth = ps->power_smooth;
+ INTFLOAT *peak_decay_diff_smooth = ps->peak_decay_diff_smooth;
+ INTFLOAT (*delay)[PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2] = ps->delay;
+ INTFLOAT (*ap_delay)[PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2] = ps->ap_delay;
+#if !USE_FIXED
+ 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;
+ 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) {
+ 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));
+ memset(ps->delay, 0, sizeof(ps->delay));
+ memset(ps->ap_delay, 0, sizeof(ps->ap_delay));
+ }
+
+ for (k = 0; k < NR_BANDS[is34]; k++) {
+ int i = k_to_i[k];
+ ps->dsp.add_squares(power[i], s[k], nL - n0);
+ }
+
+ //Transient detection
+#if USE_FIXED
+ for (i = 0; i < NR_PAR_BANDS[is34]; i++) {
+ for (n = n0; n < nL; n++) {
+ int decayed_peak;
+ int denom;
+
+ decayed_peak = (int)(((int64_t)peak_decay_factor * \
+ peak_decay_nrg[i] + 0x40000000) >> 31);
+ peak_decay_nrg[i] = FFMAX(decayed_peak, power[i][n]);
+ power_smooth[i] += (power[i][n] - power_smooth[i] + 2) >> 2;
+ peak_decay_diff_smooth[i] += (peak_decay_nrg[i] - power[i][n] - \
+ peak_decay_diff_smooth[i] + 2) >> 2;
+ denom = peak_decay_diff_smooth[i] + (peak_decay_diff_smooth[i] >> 1);
+ if (denom > power_smooth[i]) {
+ int p = power_smooth[i];
+ while (denom < 0x40000000) {
+ denom <<= 1;
+ p <<= 1;
+ }
+ transient_gain[i][n] = p / (denom >> 16);
+ }
+ else {
+ transient_gain[i][n] = 1 << 16;
+ }
+ }
+ }
+#else
+ for (i = 0; i < NR_PAR_BANDS[is34]; i++) {
+ for (n = n0; n < nL; n++) {
+ float decayed_peak = peak_decay_factor * peak_decay_nrg[i];
+ float denom;
+ peak_decay_nrg[i] = FFMAX(decayed_peak, power[i][n]);
+ power_smooth[i] += a_smooth * (power[i][n] - power_smooth[i]);
+ peak_decay_diff_smooth[i] += a_smooth * (peak_decay_nrg[i] - power[i][n] - peak_decay_diff_smooth[i]);
+ denom = transient_impact * peak_decay_diff_smooth[i];
+ transient_gain[i][n] = (denom > power_smooth[i]) ?
+ power_smooth[i] / denom : 1.0f;
+ }
+ }
+
+#endif /* USE_FIXED */
+ //Decorrelation and transient reduction
+ // PS_AP_LINKS - 1
+ // -----
+ // | | Q_fract_allpass[k][m]*z^-link_delay[m] - a[m]*g_decay_slope[k]
+ //H[k][z] = z^-2 * phi_fract[k] * | | ----------------------------------------------------------------
+ // | | 1 - a[m]*g_decay_slope[k]*Q_fract_allpass[k][m]*z^-link_delay[m]
+ // m = 0
+ //d[k][z] (out) = transient_gain_mapped[k][z] * H[k][z] * s[k][z]
+ for (k = 0; k < NR_ALLPASS_BANDS[is34]; k++) {
+ int b = k_to_i[k];
+#if USE_FIXED
+ int g_decay_slope;
+
+ if (k - DECAY_CUTOFF[is34] <= 0) {
+ g_decay_slope = 1 << 30;
+ }
+ else if (k - DECAY_CUTOFF[is34] >= 20) {
+ g_decay_slope = 0;
+ }
+ else {
+ g_decay_slope = (1 << 30) - DECAY_SLOPE * (k - DECAY_CUTOFF[is34]);
+ }
+#else
+ float g_decay_slope = 1.f - DECAY_SLOPE * (k - DECAY_CUTOFF[is34]);
+ g_decay_slope = av_clipf(g_decay_slope, 0.f, 1.f);
+#endif /* USE_FIXED */
+ memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0]));
+ memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0]));
+ for (m = 0; m < PS_AP_LINKS; m++) {
+ memcpy(ap_delay[k][m], ap_delay[k][m]+numQMFSlots, 5*sizeof(ap_delay[k][m][0]));
+ }
+ ps->dsp.decorrelate(out[k], delay[k] + PS_MAX_DELAY - 2, ap_delay[k],
+ phi_fract[is34][k],
+ (const INTFLOAT (*)[2]) Q_fract_allpass[is34][k],
+ transient_gain[b], g_decay_slope, nL - n0);
+ }
+ for (; k < SHORT_DELAY_BAND[is34]; k++) {
+ int i = k_to_i[k];
+ memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0]));
+ memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0]));
+ //H = delay 14
+ ps->dsp.mul_pair_single(out[k], delay[k] + PS_MAX_DELAY - 14,
+ transient_gain[i], nL - n0);
+ }
+ for (; k < NR_BANDS[is34]; k++) {
+ int i = k_to_i[k];
+ memcpy(delay[k], delay[k]+nL, PS_MAX_DELAY*sizeof(delay[k][0]));
+ memcpy(delay[k]+PS_MAX_DELAY, s[k], numQMFSlots*sizeof(delay[k][0]));
+ //H = delay 1
+ ps->dsp.mul_pair_single(out[k], delay[k] + PS_MAX_DELAY - 1,
+ transient_gain[i], nL - n0);
+ }
+}
+
+static void remap34(int8_t (**p_par_mapped)[PS_MAX_NR_IIDICC],
+ int8_t (*par)[PS_MAX_NR_IIDICC],
+ int num_par, int num_env, int full)
+{
+ int8_t (*par_mapped)[PS_MAX_NR_IIDICC] = *p_par_mapped;
+ int e;
+ if (num_par == 20 || num_par == 11) {
+ for (e = 0; e < num_env; e++) {
+ map_idx_20_to_34(par_mapped[e], par[e], full);
+ }
+ } else if (num_par == 10 || num_par == 5) {
+ for (e = 0; e < num_env; e++) {
+ map_idx_10_to_34(par_mapped[e], par[e], full);
+ }
+ } else {
+ *p_par_mapped = par;
+ }
+}
+
+static void remap20(int8_t (**p_par_mapped)[PS_MAX_NR_IIDICC],
+ int8_t (*par)[PS_MAX_NR_IIDICC],
+ int num_par, int num_env, int full)
+{
+ int8_t (*par_mapped)[PS_MAX_NR_IIDICC] = *p_par_mapped;
+ int e;
+ if (num_par == 34 || num_par == 17) {
+ for (e = 0; e < num_env; e++) {
+ map_idx_34_to_20(par_mapped[e], par[e], full);
+ }
+ } else if (num_par == 10 || num_par == 5) {
+ for (e = 0; e < num_env; e++) {
+ map_idx_10_to_20(par_mapped[e], par[e], full);
+ }
+ } else {
+ *p_par_mapped = par;
+ }
+}
+
+static void stereo_processing(PSContext *ps, INTFLOAT (*l)[32][2], INTFLOAT (*r)[32][2], int is34)
+{
+ int e, b, k;
+
+ 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;
+ INTFLOAT (*H22)[PS_MAX_NUM_ENV+1][PS_MAX_NR_IIDICC] = ps->H22;
+ int8_t *opd_hist = ps->opd_hist;
+ int8_t *ipd_hist = ps->ipd_hist;
+ int8_t iid_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];
+ int8_t icc_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];
+ int8_t ipd_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];
+ int8_t opd_mapped_buf[PS_MAX_NUM_ENV][PS_MAX_NR_IIDICC];
+ int8_t (*iid_mapped)[PS_MAX_NR_IIDICC] = iid_mapped_buf;
+ 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;
+
+ //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 (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);
+ }
+ if (!ps->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]);
+ map_val_20_to_34(H12[1][0]);
+ map_val_20_to_34(H21[0][0]);
+ map_val_20_to_34(H21[1][0]);
+ map_val_20_to_34(H22[0][0]);
+ map_val_20_to_34(H22[1][0]);
+ 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);
+ }
+ if (ps->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]);
+ map_val_34_to_20(H12[1][0]);
+ map_val_34_to_20(H21[0][0]);
+ map_val_34_to_20(H21[1][0]);
+ map_val_34_to_20(H22[0][0]);
+ map_val_34_to_20(H22[1][0]);
+ ipdopd_reset(ipd_hist, opd_hist);
+ }
+ }
+
+ //Mixing
+ for (e = 0; e < ps->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];
+
+ if (!PS_BASELINE && ps->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;
+ INTFLOAT ipd_adj_re, ipd_adj_im;
+ int opd_idx = opd_hist[b] * 8 + opd_mapped[e][b];
+ int ipd_idx = ipd_hist[b] * 8 + ipd_mapped[e][b];
+ INTFLOAT opd_re = pd_re_smooth[opd_idx];
+ INTFLOAT opd_im = pd_im_smooth[opd_idx];
+ INTFLOAT ipd_re = pd_re_smooth[ipd_idx];
+ INTFLOAT ipd_im = pd_im_smooth[ipd_idx];
+ opd_hist[b] = opd_idx & 0x3F;
+ ipd_hist[b] = ipd_idx & 0x3F;
+
+ ipd_adj_re = AAC_MADD30(opd_re, ipd_re, opd_im, ipd_im);
+ ipd_adj_im = AAC_MSUB30(opd_im, ipd_re, opd_re, ipd_im);
+ h11i = AAC_MUL30(h11, opd_im);
+ h11 = AAC_MUL30(h11, opd_re);
+ h12i = AAC_MUL30(h12, ipd_adj_im);
+ h12 = AAC_MUL30(h12, ipd_adj_re);
+ h21i = AAC_MUL30(h21, opd_im);
+ h21 = AAC_MUL30(h21, opd_re);
+ h22i = AAC_MUL30(h22, ipd_adj_im);
+ h22 = AAC_MUL30(h22, ipd_adj_re);
+ H11[1][e+1][b] = h11i;
+ H12[1][e+1][b] = h12i;
+ H21[1][e+1][b] = h21i;
+ H22[1][e+1][b] = h22i;
+ }
+ H11[0][e+1][b] = h11;
+ H12[0][e+1][b] = h12;
+ H21[0][e+1][b] = h21;
+ H22[0][e+1][b] = h22;
+ }
+ 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];
+ INTFLOAT width = Q30(1.f) / ((stop - start) ? (stop - start) : 1);
+#if USE_FIXED
+ width = FFMIN(2U*width, INT_MAX);
+#endif
+ b = k_to_i[k];
+ h[0][0] = H11[0][e][b];
+ 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) {
+ //Is this necessary? ps_04_new seems unchanged
+ if ((is34 && k <= 13 && k >= 9) || (!is34 && k <= 1)) {
+ h[1][0] = -H11[1][e][b];
+ h[1][1] = -H12[1][e][b];
+ h[1][2] = -H21[1][e][b];
+ h[1][3] = -H22[1][e][b];
+ } else {
+ h[1][0] = H11[1][e][b];
+ h[1][1] = H12[1][e][b];
+ h[1][2] = H21[1][e][b];
+ h[1][3] = H22[1][e][b];
+ }
+ }
+ //Interpolation
+ h_step[0][0] = AAC_MSUB31_V3(H11[0][e+1][b], h[0][0], width);
+ 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) {
+ 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);
+ }
+ ps->dsp.stereo_interpolate[!PS_BASELINE && ps->enable_ipdopd](
+ l[k] + 1 + start, r[k] + 1 + start,
+ h, h_step, stop - start);
+ }
+ }
+}
+
+int AAC_RENAME(ff_ps_apply)(AVCodecContext *avctx, PSContext *ps, INTFLOAT L[2][38][64], INTFLOAT R[2][38][64], int top)
+{
+ INTFLOAT (*Lbuf)[32][2] = ps->Lbuf;
+ INTFLOAT (*Rbuf)[32][2] = ps->Rbuf;
+ const int len = 32;
+ int is34 = ps->is34bands;
+
+ top += NR_BANDS[is34] - 64;
+ memset(ps->delay+top, 0, (NR_BANDS[is34] - top)*sizeof(ps->delay[0]));
+ if (top < NR_ALLPASS_BANDS[is34])
+ memset(ps->ap_delay + top, 0, (NR_ALLPASS_BANDS[is34] - top)*sizeof(ps->ap_delay[0]));
+
+ hybrid_analysis(&ps->dsp, Lbuf, ps->in_buf, L, is34, len);
+ decorrelation(ps, Rbuf, (const INTFLOAT (*)[32][2]) Lbuf, is34);
+ stereo_processing(ps, Lbuf, Rbuf, is34);
+ hybrid_synthesis(&ps->dsp, L, Lbuf, is34, len);
+ hybrid_synthesis(&ps->dsp, R, Rbuf, is34, len);
+
+ 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();
+}
+
+av_cold void AAC_RENAME(ff_ps_ctx_init)(PSContext *ps)
+{
+ AAC_RENAME(ff_psdsp_init)(&ps->dsp);
+}
diff --git a/ffmpeg-2-8-11/libavcodec/aacps.h b/ffmpeg-2-8-12/libavcodec/aacps.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacps.h
rename to ffmpeg-2-8-12/libavcodec/aacps.h
diff --git a/ffmpeg-2-8-11/libavcodec/aacps_fixed.c b/ffmpeg-2-8-12/libavcodec/aacps_fixed.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacps_fixed.c
rename to ffmpeg-2-8-12/libavcodec/aacps_fixed.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacps_fixed_tablegen.c b/ffmpeg-2-8-12/libavcodec/aacps_fixed_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacps_fixed_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/aacps_fixed_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacps_fixed_tablegen.h b/ffmpeg-2-8-12/libavcodec/aacps_fixed_tablegen.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacps_fixed_tablegen.h
rename to ffmpeg-2-8-12/libavcodec/aacps_fixed_tablegen.h
diff --git a/ffmpeg-2-8-11/libavcodec/aacps_float.c b/ffmpeg-2-8-12/libavcodec/aacps_float.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacps_float.c
rename to ffmpeg-2-8-12/libavcodec/aacps_float.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacps_tablegen.c b/ffmpeg-2-8-12/libavcodec/aacps_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacps_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/aacps_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacps_tablegen.h b/ffmpeg-2-8-12/libavcodec/aacps_tablegen.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacps_tablegen.h
rename to ffmpeg-2-8-12/libavcodec/aacps_tablegen.h
diff --git a/ffmpeg-2-8-11/libavcodec/aacps_tablegen_template.c b/ffmpeg-2-8-12/libavcodec/aacps_tablegen_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacps_tablegen_template.c
rename to ffmpeg-2-8-12/libavcodec/aacps_tablegen_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacpsdata.c b/ffmpeg-2-8-12/libavcodec/aacpsdata.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacpsdata.c
rename to ffmpeg-2-8-12/libavcodec/aacpsdata.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacpsdsp.h b/ffmpeg-2-8-12/libavcodec/aacpsdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacpsdsp.h
rename to ffmpeg-2-8-12/libavcodec/aacpsdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/aacpsdsp_fixed.c b/ffmpeg-2-8-12/libavcodec/aacpsdsp_fixed.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacpsdsp_fixed.c
rename to ffmpeg-2-8-12/libavcodec/aacpsdsp_fixed.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacpsdsp_float.c b/ffmpeg-2-8-12/libavcodec/aacpsdsp_float.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacpsdsp_float.c
rename to ffmpeg-2-8-12/libavcodec/aacpsdsp_float.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacpsdsp_template.c b/ffmpeg-2-8-12/libavcodec/aacpsdsp_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacpsdsp_template.c
rename to ffmpeg-2-8-12/libavcodec/aacpsdsp_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacpsy.c b/ffmpeg-2-8-12/libavcodec/aacpsy.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacpsy.c
rename to ffmpeg-2-8-12/libavcodec/aacpsy.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacsbr.c b/ffmpeg-2-8-12/libavcodec/aacsbr.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacsbr.c
rename to ffmpeg-2-8-12/libavcodec/aacsbr.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacsbr.h b/ffmpeg-2-8-12/libavcodec/aacsbr.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacsbr.h
rename to ffmpeg-2-8-12/libavcodec/aacsbr.h
diff --git a/ffmpeg-2-8-12/libavcodec/aacsbr_fixed.c b/ffmpeg-2-8-12/libavcodec/aacsbr_fixed.c
new file mode 100644
index 0000000..2410c25
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/aacsbr_fixed.c
@@ -0,0 +1,610 @@
+/*
+ * Copyright (c) 2013
+ * MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * AAC Spectral Band Replication decoding functions (fixed-point)
+ * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
+ * Copyright (c) 2009-2010 Alex Converse <alex.converse at gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * AAC Spectral Band Replication decoding functions (fixed-point)
+ * Note: Rounding-to-nearest used unless otherwise stated
+ * @author Robert Swain ( rob opendot cl )
+ * @author Stanislav Ocovaj ( stanislav.ocovaj imgtec com )
+ */
+#define USE_FIXED 1
+
+#include "aac.h"
+#include "sbr.h"
+#include "aacsbr.h"
+#include "aacsbrdata.h"
+#include "aacsbr_fixed_tablegen.h"
+#include "fft.h"
+#include "aacps.h"
+#include "sbrdsp.h"
+#include "libavutil/internal.h"
+#include "libavutil/libm.h"
+#include "libavutil/avassert.h"
+
+#include <stdint.h>
+#include <float.h>
+#include <math.h>
+
+static VLC vlc_sbr[10];
+static void aacsbr_func_ptr_init(AACSBRContext *c);
+static const int CONST_LN2 = Q31(0.6931471806/256); // ln(2)/256
+static const int CONST_RECIP_LN2 = Q31(0.7213475204); // 0.5/ln(2)
+static const int CONST_076923 = Q31(0.76923076923076923077f);
+
+static const int fixed_log_table[10] =
+{
+ Q31(1.0/2), Q31(1.0/3), Q31(1.0/4), Q31(1.0/5), Q31(1.0/6),
+ Q31(1.0/7), Q31(1.0/8), Q31(1.0/9), Q31(1.0/10), Q31(1.0/11)
+};
+
+static int fixed_log(int x)
+{
+ int i, ret, xpow, tmp;
+
+ ret = x;
+ xpow = x;
+ for (i=0; i<10; i+=2){
+ xpow = (int)(((int64_t)xpow * x + 0x40000000) >> 31);
+ tmp = (int)(((int64_t)xpow * fixed_log_table[i] + 0x40000000) >> 31);
+ ret -= tmp;
+
+ xpow = (int)(((int64_t)xpow * x + 0x40000000) >> 31);
+ tmp = (int)(((int64_t)xpow * fixed_log_table[i+1] + 0x40000000) >> 31);
+ ret += tmp;
+ }
+
+ return ret;
+}
+
+static const int fixed_exp_table[7] =
+{
+ Q31(1.0/2), Q31(1.0/6), Q31(1.0/24), Q31(1.0/120),
+ Q31(1.0/720), Q31(1.0/5040), Q31(1.0/40320)
+};
+
+static int fixed_exp(int x)
+{
+ int i, ret, xpow, tmp;
+
+ ret = 0x800000 + x;
+ xpow = x;
+ for (i=0; i<7; i++){
+ xpow = (int)(((int64_t)xpow * x + 0x400000) >> 23);
+ tmp = (int)(((int64_t)xpow * fixed_exp_table[i] + 0x40000000) >> 31);
+ ret += tmp;
+ }
+
+ return ret;
+}
+
+static void make_bands(int16_t* bands, int start, int stop, int num_bands)
+{
+ int k, previous, present;
+ int base, prod, nz = 0;
+
+ base = (stop << 23) / start;
+ while (base < 0x40000000){
+ base <<= 1;
+ nz++;
+ }
+ base = fixed_log(base - 0x80000000);
+ base = (((base + 0x80) >> 8) + (8-nz)*CONST_LN2) / num_bands;
+ base = fixed_exp(base);
+
+ previous = start;
+ prod = start << 23;
+
+ for (k = 0; k < num_bands-1; k++) {
+ prod = (int)(((int64_t)prod * base + 0x400000) >> 23);
+ present = (prod + 0x400000) >> 23;
+ bands[k] = present - previous;
+ previous = present;
+ }
+ bands[num_bands-1] = stop - previous;
+}
+
+/// Dequantization and stereo decoding (14496-3 sp04 p203)
+static void sbr_dequant(SpectralBandReplication *sbr, int id_aac)
+{
+ int k, e;
+ int ch;
+
+ if (id_aac == TYPE_CPE && sbr->bs_coupling) {
+ int alpha = sbr->data[0].bs_amp_res ? 2 : 1;
+ int pan_offset = sbr->data[0].bs_amp_res ? 12 : 24;
+ for (e = 1; e <= sbr->data[0].bs_num_env; e++) {
+ for (k = 0; k < sbr->n[sbr->data[0].bs_freq_res[e]]; k++) {
+ SoftFloat temp1, temp2, fac;
+
+ temp1.exp = sbr->data[0].env_facs[e][k].mant * alpha + 14;
+ if (temp1.exp & 1)
+ temp1.mant = 759250125;
+ else
+ temp1.mant = 0x20000000;
+ temp1.exp = (temp1.exp >> 1) + 1;
+ if (temp1.exp > 66) { // temp1 > 1E20
+ av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n");
+ temp1 = FLOAT_1;
+ }
+
+ temp2.exp = (pan_offset - sbr->data[1].env_facs[e][k].mant) * alpha;
+ if (temp2.exp & 1)
+ temp2.mant = 759250125;
+ else
+ temp2.mant = 0x20000000;
+ temp2.exp = (temp2.exp >> 1) + 1;
+ fac = av_div_sf(temp1, av_add_sf(FLOAT_1, temp2));
+ sbr->data[0].env_facs[e][k] = fac;
+ sbr->data[1].env_facs[e][k] = av_mul_sf(fac, temp2);
+ }
+ }
+ for (e = 1; e <= sbr->data[0].bs_num_noise; e++) {
+ for (k = 0; k < sbr->n_q; k++) {
+ SoftFloat temp1, temp2, fac;
+
+ temp1.exp = NOISE_FLOOR_OFFSET - \
+ sbr->data[0].noise_facs[e][k].mant + 2;
+ temp1.mant = 0x20000000;
+ if (temp1.exp > 66) { // temp1 > 1E20
+ av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n");
+ temp1 = FLOAT_1;
+ }
+ temp2.exp = 12 - sbr->data[1].noise_facs[e][k].mant + 1;
+ temp2.mant = 0x20000000;
+ fac = av_div_sf(temp1, av_add_sf(FLOAT_1, temp2));
+ sbr->data[0].noise_facs[e][k] = fac;
+ sbr->data[1].noise_facs[e][k] = av_mul_sf(fac, temp2);
+ }
+ }
+ } else { // SCE or one non-coupled CPE
+ for (ch = 0; ch < (id_aac == TYPE_CPE) + 1; ch++) {
+ int alpha = sbr->data[ch].bs_amp_res ? 2 : 1;
+ for (e = 1; e <= sbr->data[ch].bs_num_env; e++)
+ for (k = 0; k < sbr->n[sbr->data[ch].bs_freq_res[e]]; k++){
+ SoftFloat temp1;
+
+ temp1.exp = alpha * sbr->data[ch].env_facs[e][k].mant + 12;
+ if (temp1.exp & 1)
+ temp1.mant = 759250125;
+ else
+ temp1.mant = 0x20000000;
+ temp1.exp = (temp1.exp >> 1) + 1;
+ if (temp1.exp > 66) { // temp1 > 1E20
+ av_log(NULL, AV_LOG_ERROR, "envelope scalefactor overflow in dequant\n");
+ temp1 = FLOAT_1;
+ }
+ sbr->data[ch].env_facs[e][k] = temp1;
+ }
+ for (e = 1; e <= sbr->data[ch].bs_num_noise; e++)
+ for (k = 0; k < sbr->n_q; k++){
+ sbr->data[ch].noise_facs[e][k].exp = NOISE_FLOOR_OFFSET - \
+ sbr->data[ch].noise_facs[e][k].mant + 1;
+ sbr->data[ch].noise_facs[e][k].mant = 0x20000000;
+ }
+ }
+ }
+}
+
+/** High Frequency Generation (14496-3 sp04 p214+) and Inverse Filtering
+ * (14496-3 sp04 p214)
+ * Warning: This routine does not seem numerically stable.
+ */
+static void sbr_hf_inverse_filter(SBRDSPContext *dsp,
+ int (*alpha0)[2], int (*alpha1)[2],
+ const int X_low[32][40][2], int k0)
+{
+ int k;
+ int shift, round;
+
+ for (k = 0; k < k0; k++) {
+ SoftFloat phi[3][2][2];
+ SoftFloat a00, a01, a10, a11;
+ SoftFloat dk;
+
+ dsp->autocorrelate(X_low[k], phi);
+
+ dk = av_sub_sf(av_mul_sf(phi[2][1][0], phi[1][0][0]),
+ av_mul_sf(av_add_sf(av_mul_sf(phi[1][1][0], phi[1][1][0]),
+ av_mul_sf(phi[1][1][1], phi[1][1][1])), FLOAT_0999999));
+
+ if (!dk.mant) {
+ a10 = FLOAT_0;
+ a11 = FLOAT_0;
+ } else {
+ SoftFloat temp_real, temp_im;
+ temp_real = av_sub_sf(av_sub_sf(av_mul_sf(phi[0][0][0], phi[1][1][0]),
+ av_mul_sf(phi[0][0][1], phi[1][1][1])),
+ av_mul_sf(phi[0][1][0], phi[1][0][0]));
+ temp_im = av_sub_sf(av_add_sf(av_mul_sf(phi[0][0][0], phi[1][1][1]),
+ av_mul_sf(phi[0][0][1], phi[1][1][0])),
+ av_mul_sf(phi[0][1][1], phi[1][0][0]));
+
+ a10 = av_div_sf(temp_real, dk);
+ a11 = av_div_sf(temp_im, dk);
+ }
+
+ if (!phi[1][0][0].mant) {
+ a00 = FLOAT_0;
+ a01 = FLOAT_0;
+ } else {
+ SoftFloat temp_real, temp_im;
+ temp_real = av_add_sf(phi[0][0][0],
+ av_add_sf(av_mul_sf(a10, phi[1][1][0]),
+ av_mul_sf(a11, phi[1][1][1])));
+ temp_im = av_add_sf(phi[0][0][1],
+ av_sub_sf(av_mul_sf(a11, phi[1][1][0]),
+ av_mul_sf(a10, phi[1][1][1])));
+
+ temp_real.mant = -temp_real.mant;
+ temp_im.mant = -temp_im.mant;
+ a00 = av_div_sf(temp_real, phi[1][0][0]);
+ a01 = av_div_sf(temp_im, phi[1][0][0]);
+ }
+
+ shift = a00.exp;
+ if (shift >= 3)
+ alpha0[k][0] = 0x7fffffff;
+ else if (shift <= -30)
+ alpha0[k][0] = 0;
+ else {
+ a00.mant <<= 1;
+ shift = 2-shift;
+ if (shift == 0)
+ alpha0[k][0] = a00.mant;
+ else {
+ round = 1 << (shift-1);
+ alpha0[k][0] = (a00.mant + round) >> shift;
+ }
+ }
+
+ shift = a01.exp;
+ if (shift >= 3)
+ alpha0[k][1] = 0x7fffffff;
+ else if (shift <= -30)
+ alpha0[k][1] = 0;
+ else {
+ a01.mant <<= 1;
+ shift = 2-shift;
+ if (shift == 0)
+ alpha0[k][1] = a01.mant;
+ else {
+ round = 1 << (shift-1);
+ alpha0[k][1] = (a01.mant + round) >> shift;
+ }
+ }
+ shift = a10.exp;
+ if (shift >= 3)
+ alpha1[k][0] = 0x7fffffff;
+ else if (shift <= -30)
+ alpha1[k][0] = 0;
+ else {
+ a10.mant <<= 1;
+ shift = 2-shift;
+ if (shift == 0)
+ alpha1[k][0] = a10.mant;
+ else {
+ round = 1 << (shift-1);
+ alpha1[k][0] = (a10.mant + round) >> shift;
+ }
+ }
+
+ shift = a11.exp;
+ if (shift >= 3)
+ alpha1[k][1] = 0x7fffffff;
+ else if (shift <= -30)
+ alpha1[k][1] = 0;
+ else {
+ a11.mant <<= 1;
+ shift = 2-shift;
+ if (shift == 0)
+ alpha1[k][1] = a11.mant;
+ else {
+ round = 1 << (shift-1);
+ alpha1[k][1] = (a11.mant + round) >> shift;
+ }
+ }
+
+ shift = (int)(((int64_t)(alpha1[k][0]>>1) * (alpha1[k][0]>>1) + \
+ (int64_t)(alpha1[k][1]>>1) * (alpha1[k][1]>>1) + \
+ 0x40000000) >> 31);
+ if (shift >= 0x20000000){
+ alpha1[k][0] = 0;
+ alpha1[k][1] = 0;
+ alpha0[k][0] = 0;
+ alpha0[k][1] = 0;
+ }
+
+ shift = (int)(((int64_t)(alpha0[k][0]>>1) * (alpha0[k][0]>>1) + \
+ (int64_t)(alpha0[k][1]>>1) * (alpha0[k][1]>>1) + \
+ 0x40000000) >> 31);
+ if (shift >= 0x20000000){
+ alpha1[k][0] = 0;
+ alpha1[k][1] = 0;
+ alpha0[k][0] = 0;
+ alpha0[k][1] = 0;
+ }
+ }
+}
+
+/// Chirp Factors (14496-3 sp04 p214)
+static void sbr_chirp(SpectralBandReplication *sbr, SBRData *ch_data)
+{
+ int i;
+ int new_bw;
+ static const int bw_tab[] = { 0, 1610612736, 1932735283, 2104533975 };
+ int64_t accu;
+
+ for (i = 0; i < sbr->n_q; i++) {
+ if (ch_data->bs_invf_mode[0][i] + ch_data->bs_invf_mode[1][i] == 1)
+ new_bw = 1288490189;
+ else
+ new_bw = bw_tab[ch_data->bs_invf_mode[0][i]];
+
+ if (new_bw < ch_data->bw_array[i]){
+ accu = (int64_t)new_bw * 1610612736;
+ accu += (int64_t)ch_data->bw_array[i] * 0x20000000;
+ new_bw = (int)((accu + 0x40000000) >> 31);
+ } else {
+ accu = (int64_t)new_bw * 1946157056;
+ accu += (int64_t)ch_data->bw_array[i] * 201326592;
+ new_bw = (int)((accu + 0x40000000) >> 31);
+ }
+ ch_data->bw_array[i] = new_bw < 0x2000000 ? 0 : new_bw;
+ }
+}
+
+/**
+ * Calculation of levels of additional HF signal components (14496-3 sp04 p219)
+ * and Calculation of gain (14496-3 sp04 p219)
+ */
+static void sbr_gain_calc(AACContext *ac, SpectralBandReplication *sbr,
+ SBRData *ch_data, const int e_a[2])
+{
+ int e, k, m;
+ // max gain limits : -3dB, 0dB, 3dB, inf dB (limiter off)
+ static const SoftFloat limgain[4] = { { 760155524, 0 }, { 0x20000000, 1 },
+ { 758351638, 1 }, { 625000000, 34 } };
+
+ for (e = 0; e < ch_data->bs_num_env; e++) {
+ int delta = !((e == e_a[1]) || (e == e_a[0]));
+ for (k = 0; k < sbr->n_lim; k++) {
+ SoftFloat gain_boost, gain_max;
+ SoftFloat sum[2];
+ sum[0] = sum[1] = FLOAT_0;
+ for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
+ const SoftFloat temp = av_div_sf(sbr->e_origmapped[e][m],
+ av_add_sf(FLOAT_1, sbr->q_mapped[e][m]));
+ sbr->q_m[e][m] = av_sqrt_sf(av_mul_sf(temp, sbr->q_mapped[e][m]));
+ sbr->s_m[e][m] = av_sqrt_sf(av_mul_sf(temp, av_int2sf(ch_data->s_indexmapped[e + 1][m], 0)));
+ if (!sbr->s_mapped[e][m]) {
+ if (delta) {
+ sbr->gain[e][m] = av_sqrt_sf(av_div_sf(sbr->e_origmapped[e][m],
+ av_mul_sf(av_add_sf(FLOAT_1, sbr->e_curr[e][m]),
+ av_add_sf(FLOAT_1, sbr->q_mapped[e][m]))));
+ } else {
+ sbr->gain[e][m] = av_sqrt_sf(av_div_sf(sbr->e_origmapped[e][m],
+ av_add_sf(FLOAT_1, sbr->e_curr[e][m])));
+ }
+ } else {
+ sbr->gain[e][m] = av_sqrt_sf(
+ av_div_sf(
+ av_mul_sf(sbr->e_origmapped[e][m], sbr->q_mapped[e][m]),
+ av_mul_sf(
+ av_add_sf(FLOAT_1, sbr->e_curr[e][m]),
+ av_add_sf(FLOAT_1, sbr->q_mapped[e][m]))));
+ }
+ }
+ for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
+ sum[0] = av_add_sf(sum[0], sbr->e_origmapped[e][m]);
+ sum[1] = av_add_sf(sum[1], sbr->e_curr[e][m]);
+ }
+ gain_max = av_mul_sf(limgain[sbr->bs_limiter_gains],
+ av_sqrt_sf(
+ av_div_sf(
+ av_add_sf(FLOAT_EPSILON, sum[0]),
+ av_add_sf(FLOAT_EPSILON, sum[1]))));
+ if (av_gt_sf(gain_max, FLOAT_100000))
+ gain_max = FLOAT_100000;
+ for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
+ SoftFloat q_m_max = av_div_sf(
+ av_mul_sf(sbr->q_m[e][m], gain_max),
+ sbr->gain[e][m]);
+ if (av_gt_sf(sbr->q_m[e][m], q_m_max))
+ sbr->q_m[e][m] = q_m_max;
+ if (av_gt_sf(sbr->gain[e][m], gain_max))
+ sbr->gain[e][m] = gain_max;
+ }
+ sum[0] = sum[1] = FLOAT_0;
+ for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
+ sum[0] = av_add_sf(sum[0], sbr->e_origmapped[e][m]);
+ sum[1] = av_add_sf(sum[1],
+ av_mul_sf(
+ av_mul_sf(sbr->e_curr[e][m],
+ sbr->gain[e][m]),
+ sbr->gain[e][m]));
+ sum[1] = av_add_sf(sum[1],
+ av_mul_sf(sbr->s_m[e][m], sbr->s_m[e][m]));
+ if (delta && !sbr->s_m[e][m].mant)
+ sum[1] = av_add_sf(sum[1],
+ av_mul_sf(sbr->q_m[e][m], sbr->q_m[e][m]));
+ }
+ gain_boost = av_sqrt_sf(
+ av_div_sf(
+ av_add_sf(FLOAT_EPSILON, sum[0]),
+ av_add_sf(FLOAT_EPSILON, sum[1])));
+ if (av_gt_sf(gain_boost, FLOAT_1584893192))
+ gain_boost = FLOAT_1584893192;
+
+ for (m = sbr->f_tablelim[k] - sbr->kx[1]; m < sbr->f_tablelim[k + 1] - sbr->kx[1]; m++) {
+ sbr->gain[e][m] = av_mul_sf(sbr->gain[e][m], gain_boost);
+ sbr->q_m[e][m] = av_mul_sf(sbr->q_m[e][m], gain_boost);
+ sbr->s_m[e][m] = av_mul_sf(sbr->s_m[e][m], gain_boost);
+ }
+ }
+ }
+}
+
+/// Assembling HF Signals (14496-3 sp04 p220)
+static void sbr_hf_assemble(int Y1[38][64][2],
+ const int X_high[64][40][2],
+ SpectralBandReplication *sbr, SBRData *ch_data,
+ const int e_a[2])
+{
+ int e, i, j, m;
+ const int h_SL = 4 * !sbr->bs_smoothing_mode;
+ const int kx = sbr->kx[1];
+ const int m_max = sbr->m[1];
+ static const SoftFloat h_smooth[5] = {
+ { 715827883, -1 },
+ { 647472402, -1 },
+ { 937030863, -2 },
+ { 989249804, -3 },
+ { 546843842, -4 },
+ };
+ SoftFloat (*g_temp)[48] = ch_data->g_temp, (*q_temp)[48] = ch_data->q_temp;
+ int indexnoise = ch_data->f_indexnoise;
+ int indexsine = ch_data->f_indexsine;
+
+ if (sbr->reset) {
+ for (i = 0; i < h_SL; i++) {
+ memcpy(g_temp[i + 2*ch_data->t_env[0]], sbr->gain[0], m_max * sizeof(sbr->gain[0][0]));
+ memcpy(q_temp[i + 2*ch_data->t_env[0]], sbr->q_m[0], m_max * sizeof(sbr->q_m[0][0]));
+ }
+ } else if (h_SL) {
+ for (i = 0; i < 4; i++) {
+ memcpy(g_temp[i + 2 * ch_data->t_env[0]],
+ g_temp[i + 2 * ch_data->t_env_num_env_old],
+ sizeof(g_temp[0]));
+ memcpy(q_temp[i + 2 * ch_data->t_env[0]],
+ q_temp[i + 2 * ch_data->t_env_num_env_old],
+ sizeof(q_temp[0]));
+ }
+ }
+
+ for (e = 0; e < ch_data->bs_num_env; e++) {
+ for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) {
+ memcpy(g_temp[h_SL + i], sbr->gain[e], m_max * sizeof(sbr->gain[0][0]));
+ memcpy(q_temp[h_SL + i], sbr->q_m[e], m_max * sizeof(sbr->q_m[0][0]));
+ }
+ }
+
+ for (e = 0; e < ch_data->bs_num_env; e++) {
+ for (i = 2 * ch_data->t_env[e]; i < 2 * ch_data->t_env[e + 1]; i++) {
+ SoftFloat g_filt_tab[48];
+ SoftFloat q_filt_tab[48];
+ SoftFloat *g_filt, *q_filt;
+
+ if (h_SL && e != e_a[0] && e != e_a[1]) {
+ g_filt = g_filt_tab;
+ q_filt = q_filt_tab;
+ for (m = 0; m < m_max; m++) {
+ const int idx1 = i + h_SL;
+ g_filt[m].mant = g_filt[m].exp = 0;
+ q_filt[m].mant = q_filt[m].exp = 0;
+ for (j = 0; j <= h_SL; j++) {
+ g_filt[m] = av_add_sf(g_filt[m],
+ av_mul_sf(g_temp[idx1 - j][m],
+ h_smooth[j]));
+ q_filt[m] = av_add_sf(q_filt[m],
+ av_mul_sf(q_temp[idx1 - j][m],
+ h_smooth[j]));
+ }
+ }
+ } else {
+ g_filt = g_temp[i + h_SL];
+ q_filt = q_temp[i];
+ }
+
+ sbr->dsp.hf_g_filt(Y1[i] + kx, X_high + kx, g_filt, m_max,
+ i + ENVELOPE_ADJUSTMENT_OFFSET);
+
+ if (e != e_a[0] && e != e_a[1]) {
+ sbr->dsp.hf_apply_noise[indexsine](Y1[i] + kx, sbr->s_m[e],
+ q_filt, indexnoise,
+ kx, m_max);
+ } else {
+ int idx = indexsine&1;
+ int A = (1-((indexsine+(kx & 1))&2));
+ int B = (A^(-idx)) + idx;
+ int *out = &Y1[i][kx][idx];
+ int shift, round;
+
+ SoftFloat *in = sbr->s_m[e];
+ for (m = 0; m+1 < m_max; m+=2) {
+ shift = 22 - in[m ].exp;
+ if (shift < 32) {
+ round = 1 << (shift-1);
+ out[2*m ] += (in[m ].mant * A + round) >> shift;
+ }
+
+ shift = 22 - in[m+1].exp;
+ if (shift < 32) {
+ round = 1 << (shift-1);
+ out[2*m+2] += (in[m+1].mant * B + round) >> shift;
+ }
+ }
+ if(m_max&1)
+ {
+ shift = 22 - in[m ].exp;
+ if (shift < 32) {
+ round = 1 << (shift-1);
+ out[2*m ] += (in[m ].mant * A + round) >> shift;
+ }
+ }
+ }
+ indexnoise = (indexnoise + m_max) & 0x1ff;
+ indexsine = (indexsine + 1) & 3;
+ }
+ }
+ ch_data->f_indexnoise = indexnoise;
+ ch_data->f_indexsine = indexsine;
+}
+
+#include "aacsbr_template.c"
diff --git a/ffmpeg-2-8-11/libavcodec/aacsbr_fixed_tablegen.c b/ffmpeg-2-8-12/libavcodec/aacsbr_fixed_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacsbr_fixed_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/aacsbr_fixed_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacsbr_fixed_tablegen.h b/ffmpeg-2-8-12/libavcodec/aacsbr_fixed_tablegen.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacsbr_fixed_tablegen.h
rename to ffmpeg-2-8-12/libavcodec/aacsbr_fixed_tablegen.h
diff --git a/ffmpeg-2-8-11/libavcodec/aacsbr_tablegen.c b/ffmpeg-2-8-12/libavcodec/aacsbr_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacsbr_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/aacsbr_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/aacsbr_tablegen.h b/ffmpeg-2-8-12/libavcodec/aacsbr_tablegen.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacsbr_tablegen.h
rename to ffmpeg-2-8-12/libavcodec/aacsbr_tablegen.h
diff --git a/ffmpeg-2-8-11/libavcodec/aacsbr_tablegen_common.h b/ffmpeg-2-8-12/libavcodec/aacsbr_tablegen_common.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacsbr_tablegen_common.h
rename to ffmpeg-2-8-12/libavcodec/aacsbr_tablegen_common.h
diff --git a/ffmpeg-2-8-12/libavcodec/aacsbr_template.c b/ffmpeg-2-8-12/libavcodec/aacsbr_template.c
new file mode 100644
index 0000000..d0d5ea4
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/aacsbr_template.c
@@ -0,0 +1,1567 @@
+/*
+ * AAC Spectral Band Replication decoding functions
+ * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
+ * Copyright (c) 2009-2010 Alex Converse <alex.converse at gmail.com>
+ *
+ * Fixed point code
+ * Copyright (c) 2013
+ * MIPS Technologies, Inc., California.
+ *
+ * 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
+ * AAC Spectral Band Replication decoding functions
+ * @author Robert Swain ( rob opendot cl )
+ * @author Stanislav Ocovaj ( stanislav.ocovaj at imgtec.com )
+ * @author Zoran Basaric ( zoran.basaric at imgtec.com )
+ */
+
+av_cold void AAC_RENAME(ff_aac_sbr_init)(void)
+{
+ static const struct {
+ const void *sbr_codes, *sbr_bits;
+ const unsigned int table_size, elem_size;
+ } sbr_tmp[] = {
+ SBR_VLC_ROW(t_huffman_env_1_5dB),
+ SBR_VLC_ROW(f_huffman_env_1_5dB),
+ SBR_VLC_ROW(t_huffman_env_bal_1_5dB),
+ SBR_VLC_ROW(f_huffman_env_bal_1_5dB),
+ SBR_VLC_ROW(t_huffman_env_3_0dB),
+ SBR_VLC_ROW(f_huffman_env_3_0dB),
+ SBR_VLC_ROW(t_huffman_env_bal_3_0dB),
+ SBR_VLC_ROW(f_huffman_env_bal_3_0dB),
+ SBR_VLC_ROW(t_huffman_noise_3_0dB),
+ SBR_VLC_ROW(t_huffman_noise_bal_3_0dB),
+ };
+
+ // SBR VLC table initialization
+ SBR_INIT_VLC_STATIC(0, 1098);
+ SBR_INIT_VLC_STATIC(1, 1092);
+ SBR_INIT_VLC_STATIC(2, 768);
+ SBR_INIT_VLC_STATIC(3, 1026);
+ SBR_INIT_VLC_STATIC(4, 1058);
+ SBR_INIT_VLC_STATIC(5, 1052);
+ SBR_INIT_VLC_STATIC(6, 544);
+ SBR_INIT_VLC_STATIC(7, 544);
+ SBR_INIT_VLC_STATIC(8, 592);
+ SBR_INIT_VLC_STATIC(9, 512);
+
+ aacsbr_tableinit();
+
+ AAC_RENAME(ff_ps_init)();
+}
+
+/** Places SBR in pure upsampling mode. */
+static void sbr_turnoff(SpectralBandReplication *sbr) {
+ sbr->start = 0;
+ sbr->ready_for_dequant = 0;
+ // Init defults used in pure upsampling mode
+ sbr->kx[1] = 32; //Typo in spec, kx' inits to 32
+ sbr->m[1] = 0;
+ // Reset values for first SBR header
+ sbr->data[0].e_a[1] = sbr->data[1].e_a[1] = -1;
+ memset(&sbr->spectrum_params, -1, sizeof(SpectrumParameters));
+}
+
+av_cold void AAC_RENAME(ff_aac_sbr_ctx_init)(AACContext *ac, SpectralBandReplication *sbr)
+{
+ if(sbr->mdct.mdct_bits)
+ return;
+ sbr->kx[0] = sbr->kx[1];
+ sbr_turnoff(sbr);
+ sbr->data[0].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128);
+ sbr->data[1].synthesis_filterbank_samples_offset = SBR_SYNTHESIS_BUF_SIZE - (1280 - 128);
+ /* SBR requires samples to be scaled to +/-32768.0 to work correctly.
+ * mdct scale factors are adjusted to scale up from +/-1.0 at analysis
+ * and scale back down at synthesis. */
+ AAC_RENAME_32(ff_mdct_init)(&sbr->mdct, 7, 1, 1.0 / (64 * 32768.0));
+ AAC_RENAME_32(ff_mdct_init)(&sbr->mdct_ana, 7, 1, -2.0 * 32768.0);
+ AAC_RENAME(ff_ps_ctx_init)(&sbr->ps);
+ AAC_RENAME(ff_sbrdsp_init)(&sbr->dsp);
+ aacsbr_func_ptr_init(&sbr->c);
+}
+
+av_cold void AAC_RENAME(ff_aac_sbr_ctx_close)(SpectralBandReplication *sbr)
+{
+ AAC_RENAME_32(ff_mdct_end)(&sbr->mdct);
+ AAC_RENAME_32(ff_mdct_end)(&sbr->mdct_ana);
+}
+
+static int qsort_comparison_function_int16(const void *a, const void *b)
+{
+ return *(const int16_t *)a - *(const int16_t *)b;
+}
+
+static inline int in_table_int16(const int16_t *table, int last_el, int16_t needle)
+{
+ int i;
+ for (i = 0; i <= last_el; i++)
+ if (table[i] == needle)
+ return 1;
+ return 0;
+}
+
+/// Limiter Frequency Band Table (14496-3 sp04 p198)
+static void sbr_make_f_tablelim(SpectralBandReplication *sbr)
+{
+ int k;
+ if (sbr->bs_limiter_bands > 0) {
+ static const INTFLOAT bands_warped[3] = { Q23(1.32715174233856803909f), //2^(0.49/1.2)
+ Q23(1.18509277094158210129f), //2^(0.49/2)
+ Q23(1.11987160404675912501f) }; //2^(0.49/3)
+ const INTFLOAT lim_bands_per_octave_warped = bands_warped[sbr->bs_limiter_bands - 1];
+ int16_t patch_borders[7];
+ uint16_t *in = sbr->f_tablelim + 1, *out = sbr->f_tablelim;
+
+ patch_borders[0] = sbr->kx[1];
+ for (k = 1; k <= sbr->num_patches; k++)
+ patch_borders[k] = patch_borders[k-1] + sbr->patch_num_subbands[k-1];
+
+ memcpy(sbr->f_tablelim, sbr->f_tablelow,
+ (sbr->n[0] + 1) * sizeof(sbr->f_tablelow[0]));
+ if (sbr->num_patches > 1)
+ memcpy(sbr->f_tablelim + sbr->n[0] + 1, patch_borders + 1,
+ (sbr->num_patches - 1) * sizeof(patch_borders[0]));
+
+ qsort(sbr->f_tablelim, sbr->num_patches + sbr->n[0],
+ sizeof(sbr->f_tablelim[0]),
+ qsort_comparison_function_int16);
+
+ sbr->n_lim = sbr->n[0] + sbr->num_patches - 1;
+ while (out < sbr->f_tablelim + sbr->n_lim) {
+#if USE_FIXED
+ if ((*in << 23) >= *out * lim_bands_per_octave_warped) {
+#else
+ if (*in >= *out * lim_bands_per_octave_warped) {
+#endif /* USE_FIXED */
+ *++out = *in++;
+ } else if (*in == *out ||
+ !in_table_int16(patch_borders, sbr->num_patches, *in)) {
+ in++;
+ sbr->n_lim--;
+ } else if (!in_table_int16(patch_borders, sbr->num_patches, *out)) {
+ *out = *in++;
+ sbr->n_lim--;
+ } else {
+ *++out = *in++;
+ }
+ }
+ } else {
+ sbr->f_tablelim[0] = sbr->f_tablelow[0];
+ sbr->f_tablelim[1] = sbr->f_tablelow[sbr->n[0]];
+ sbr->n_lim = 1;
+ }
+}
+
+static unsigned int read_sbr_header(SpectralBandReplication *sbr, GetBitContext *gb)
+{
+ unsigned int cnt = get_bits_count(gb);
+ uint8_t bs_header_extra_1;
+ uint8_t bs_header_extra_2;
+ int old_bs_limiter_bands = sbr->bs_limiter_bands;
+ SpectrumParameters old_spectrum_params;
+
+ sbr->start = 1;
+ sbr->ready_for_dequant = 0;
+
+ // Save last spectrum parameters variables to compare to new ones
+ memcpy(&old_spectrum_params, &sbr->spectrum_params, sizeof(SpectrumParameters));
+
+ sbr->bs_amp_res_header = get_bits1(gb);
+ sbr->spectrum_params.bs_start_freq = get_bits(gb, 4);
+ sbr->spectrum_params.bs_stop_freq = get_bits(gb, 4);
+ sbr->spectrum_params.bs_xover_band = get_bits(gb, 3);
+ skip_bits(gb, 2); // bs_reserved
+
+ bs_header_extra_1 = get_bits1(gb);
+ bs_header_extra_2 = get_bits1(gb);
+
+ if (bs_header_extra_1) {
+ sbr->spectrum_params.bs_freq_scale = get_bits(gb, 2);
+ sbr->spectrum_params.bs_alter_scale = get_bits1(gb);
+ sbr->spectrum_params.bs_noise_bands = get_bits(gb, 2);
+ } else {
+ sbr->spectrum_params.bs_freq_scale = 2;
+ sbr->spectrum_params.bs_alter_scale = 1;
+ sbr->spectrum_params.bs_noise_bands = 2;
+ }
+
+ // Check if spectrum parameters changed
+ if (memcmp(&old_spectrum_params, &sbr->spectrum_params, sizeof(SpectrumParameters)))
+ sbr->reset = 1;
+
+ if (bs_header_extra_2) {
+ sbr->bs_limiter_bands = get_bits(gb, 2);
+ sbr->bs_limiter_gains = get_bits(gb, 2);
+ sbr->bs_interpol_freq = get_bits1(gb);
+ sbr->bs_smoothing_mode = get_bits1(gb);
+ } else {
+ sbr->bs_limiter_bands = 2;
+ sbr->bs_limiter_gains = 2;
+ sbr->bs_interpol_freq = 1;
+ sbr->bs_smoothing_mode = 1;
+ }
+
+ if (sbr->bs_limiter_bands != old_bs_limiter_bands && !sbr->reset)
+ sbr_make_f_tablelim(sbr);
+
+ return get_bits_count(gb) - cnt;
+}
+
+static int array_min_int16(const int16_t *array, int nel)
+{
+ int i, min = array[0];
+ for (i = 1; i < nel; i++)
+ min = FFMIN(array[i], min);
+ return min;
+}
+
+static int check_n_master(AVCodecContext *avctx, int n_master, int bs_xover_band)
+{
+ // Requirements (14496-3 sp04 p205)
+ if (n_master <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid n_master: %d\n", n_master);
+ return -1;
+ }
+ if (bs_xover_band >= n_master) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid bitstream, crossover band index beyond array bounds: %d\n",
+ bs_xover_band);
+ return -1;
+ }
+ return 0;
+}
+
+/// Master Frequency Band Table (14496-3 sp04 p194)
+static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr,
+ SpectrumParameters *spectrum)
+{
+ unsigned int temp, max_qmf_subbands = 0;
+ unsigned int start_min, stop_min;
+ int k;
+ const int8_t *sbr_offset_ptr;
+ int16_t stop_dk[13];
+
+ if (sbr->sample_rate < 32000) {
+ temp = 3000;
+ } else if (sbr->sample_rate < 64000) {
+ temp = 4000;
+ } else
+ temp = 5000;
+
+ switch (sbr->sample_rate) {
+ case 16000:
+ sbr_offset_ptr = sbr_offset[0];
+ break;
+ case 22050:
+ sbr_offset_ptr = sbr_offset[1];
+ break;
+ case 24000:
+ sbr_offset_ptr = sbr_offset[2];
+ break;
+ case 32000:
+ sbr_offset_ptr = sbr_offset[3];
+ break;
+ case 44100: case 48000: case 64000:
+ sbr_offset_ptr = sbr_offset[4];
+ break;
+ case 88200: case 96000: case 128000: case 176400: case 192000:
+ sbr_offset_ptr = sbr_offset[5];
+ break;
+ default:
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Unsupported sample rate for SBR: %d\n", sbr->sample_rate);
+ return -1;
+ }
+
+ start_min = ((temp << 7) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
+ stop_min = ((temp << 8) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
+
+ sbr->k[0] = start_min + sbr_offset_ptr[spectrum->bs_start_freq];
+
+ if (spectrum->bs_stop_freq < 14) {
+ sbr->k[2] = stop_min;
+ make_bands(stop_dk, stop_min, 64, 13);
+ qsort(stop_dk, 13, sizeof(stop_dk[0]), qsort_comparison_function_int16);
+ for (k = 0; k < spectrum->bs_stop_freq; k++)
+ sbr->k[2] += stop_dk[k];
+ } else if (spectrum->bs_stop_freq == 14) {
+ sbr->k[2] = 2*sbr->k[0];
+ } else if (spectrum->bs_stop_freq == 15) {
+ sbr->k[2] = 3*sbr->k[0];
+ } else {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Invalid bs_stop_freq: %d\n", spectrum->bs_stop_freq);
+ return -1;
+ }
+ sbr->k[2] = FFMIN(64, sbr->k[2]);
+
+ // Requirements (14496-3 sp04 p205)
+ if (sbr->sample_rate <= 32000) {
+ max_qmf_subbands = 48;
+ } else if (sbr->sample_rate == 44100) {
+ max_qmf_subbands = 35;
+ } else if (sbr->sample_rate >= 48000)
+ max_qmf_subbands = 32;
+ else
+ av_assert0(0);
+
+ if (sbr->k[2] - sbr->k[0] > max_qmf_subbands) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Invalid bitstream, too many QMF subbands: %d\n", sbr->k[2] - sbr->k[0]);
+ return -1;
+ }
+
+ if (!spectrum->bs_freq_scale) {
+ int dk, k2diff;
+
+ dk = spectrum->bs_alter_scale + 1;
+ sbr->n_master = ((sbr->k[2] - sbr->k[0] + (dk&2)) >> dk) << 1;
+ if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))
+ return -1;
+
+ for (k = 1; k <= sbr->n_master; k++)
+ sbr->f_master[k] = dk;
+
+ k2diff = sbr->k[2] - sbr->k[0] - sbr->n_master * dk;
+ if (k2diff < 0) {
+ sbr->f_master[1]--;
+ sbr->f_master[2]-= (k2diff < -1);
+ } else if (k2diff) {
+ sbr->f_master[sbr->n_master]++;
+ }
+
+ sbr->f_master[0] = sbr->k[0];
+ for (k = 1; k <= sbr->n_master; k++)
+ sbr->f_master[k] += sbr->f_master[k - 1];
+
+ } else {
+ int half_bands = 7 - spectrum->bs_freq_scale; // bs_freq_scale = {1,2,3}
+ int two_regions, num_bands_0;
+ int vdk0_max, vdk1_min;
+ int16_t vk0[49];
+#if USE_FIXED
+ int tmp, nz = 0;
+#endif /* USE_FIXED */
+
+ if (49 * sbr->k[2] > 110 * sbr->k[0]) {
+ two_regions = 1;
+ sbr->k[1] = 2 * sbr->k[0];
+ } else {
+ two_regions = 0;
+ sbr->k[1] = sbr->k[2];
+ }
+
+#if USE_FIXED
+ tmp = (sbr->k[1] << 23) / sbr->k[0];
+ while (tmp < 0x40000000) {
+ tmp <<= 1;
+ nz++;
+ }
+ tmp = fixed_log(tmp - 0x80000000);
+ tmp = (int)(((int64_t)tmp * CONST_RECIP_LN2 + 0x20000000) >> 30);
+ tmp = (((tmp + 0x80) >> 8) + ((8 - nz) << 23)) * half_bands;
+ num_bands_0 = ((tmp + 0x400000) >> 23) * 2;
+#else
+ num_bands_0 = lrintf(half_bands * log2f(sbr->k[1] / (float)sbr->k[0])) * 2;
+#endif /* USE_FIXED */
+
+ if (num_bands_0 <= 0) { // Requirements (14496-3 sp04 p205)
+ av_log(ac->avctx, AV_LOG_ERROR, "Invalid num_bands_0: %d\n", num_bands_0);
+ return -1;
+ }
+
+ vk0[0] = 0;
+
+ make_bands(vk0+1, sbr->k[0], sbr->k[1], num_bands_0);
+
+ qsort(vk0 + 1, num_bands_0, sizeof(vk0[1]), qsort_comparison_function_int16);
+ vdk0_max = vk0[num_bands_0];
+
+ vk0[0] = sbr->k[0];
+ for (k = 1; k <= num_bands_0; k++) {
+ if (vk0[k] <= 0) { // Requirements (14496-3 sp04 p205)
+ av_log(ac->avctx, AV_LOG_ERROR, "Invalid vDk0[%d]: %d\n", k, vk0[k]);
+ return -1;
+ }
+ vk0[k] += vk0[k-1];
+ }
+
+ if (two_regions) {
+ int16_t vk1[49];
+#if USE_FIXED
+ int num_bands_1;
+
+ tmp = (sbr->k[2] << 23) / sbr->k[1];
+ nz = 0;
+ while (tmp < 0x40000000) {
+ tmp <<= 1;
+ nz++;
+ }
+ tmp = fixed_log(tmp - 0x80000000);
+ tmp = (int)(((int64_t)tmp * CONST_RECIP_LN2 + 0x20000000) >> 30);
+ tmp = (((tmp + 0x80) >> 8) + ((8 - nz) << 23)) * half_bands;
+ if (spectrum->bs_alter_scale)
+ tmp = (int)(((int64_t)tmp * CONST_076923 + 0x40000000) >> 31);
+ num_bands_1 = ((tmp + 0x400000) >> 23) * 2;
+#else
+ float invwarp = spectrum->bs_alter_scale ? 0.76923076923076923077f
+ : 1.0f; // bs_alter_scale = {0,1}
+ int num_bands_1 = lrintf(half_bands * invwarp *
+ log2f(sbr->k[2] / (float)sbr->k[1])) * 2;
+#endif /* USE_FIXED */
+ make_bands(vk1+1, sbr->k[1], sbr->k[2], num_bands_1);
+
+ vdk1_min = array_min_int16(vk1 + 1, num_bands_1);
+
+ if (vdk1_min < vdk0_max) {
+ int change;
+ qsort(vk1 + 1, num_bands_1, sizeof(vk1[1]), qsort_comparison_function_int16);
+ change = FFMIN(vdk0_max - vk1[1], (vk1[num_bands_1] - vk1[1]) >> 1);
+ vk1[1] += change;
+ vk1[num_bands_1] -= change;
+ }
+
+ qsort(vk1 + 1, num_bands_1, sizeof(vk1[1]), qsort_comparison_function_int16);
+
+ vk1[0] = sbr->k[1];
+ for (k = 1; k <= num_bands_1; k++) {
+ if (vk1[k] <= 0) { // Requirements (14496-3 sp04 p205)
+ av_log(ac->avctx, AV_LOG_ERROR, "Invalid vDk1[%d]: %d\n", k, vk1[k]);
+ return -1;
+ }
+ vk1[k] += vk1[k-1];
+ }
+
+ sbr->n_master = num_bands_0 + num_bands_1;
+ if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))
+ return -1;
+ memcpy(&sbr->f_master[0], vk0,
+ (num_bands_0 + 1) * sizeof(sbr->f_master[0]));
+ memcpy(&sbr->f_master[num_bands_0 + 1], vk1 + 1,
+ num_bands_1 * sizeof(sbr->f_master[0]));
+
+ } else {
+ sbr->n_master = num_bands_0;
+ if (check_n_master(ac->avctx, sbr->n_master, sbr->spectrum_params.bs_xover_band))
+ return -1;
+ memcpy(sbr->f_master, vk0, (num_bands_0 + 1) * sizeof(sbr->f_master[0]));
+ }
+ }
+
+ return 0;
+}
+
+/// High Frequency Generation - Patch Construction (14496-3 sp04 p216 fig. 4.46)
+static int sbr_hf_calc_npatches(AACContext *ac, SpectralBandReplication *sbr)
+{
+ int i, k, last_k = -1, last_msb = -1, sb = 0;
+ int msb = sbr->k[0];
+ int usb = sbr->kx[1];
+ int goal_sb = ((1000 << 11) + (sbr->sample_rate >> 1)) / sbr->sample_rate;
+
+ sbr->num_patches = 0;
+
+ if (goal_sb < sbr->kx[1] + sbr->m[1]) {
+ for (k = 0; sbr->f_master[k] < goal_sb; k++) ;
+ } else
+ k = sbr->n_master;
+
+ do {
+ int odd = 0;
+ if (k == last_k && msb == last_msb) {
+ av_log(ac->avctx, AV_LOG_ERROR, "patch construction failed\n");
+ return AVERROR_INVALIDDATA;
+ }
+ last_k = k;
+ last_msb = msb;
+ for (i = k; i == k || sb > (sbr->k[0] - 1 + msb - odd); i--) {
+ sb = sbr->f_master[i];
+ odd = (sb + sbr->k[0]) & 1;
+ }
+
+ // Requirements (14496-3 sp04 p205) sets the maximum number of patches to 5.
+ // After this check the final number of patches can still be six which is
+ // illegal however the Coding Technologies decoder check stream has a final
+ // count of 6 patches
+ if (sbr->num_patches > 5) {
+ av_log(ac->avctx, AV_LOG_ERROR, "Too many patches: %d\n", sbr->num_patches);
+ return -1;
+ }
+
+ sbr->patch_num_subbands[sbr->num_patches] = FFMAX(sb - usb, 0);
+ sbr->patch_start_subband[sbr->num_patches] = sbr->k[0] - odd - sbr->patch_num_subbands[sbr->num_patches];
+
+ if (sbr->patch_num_subbands[sbr->num_patches] > 0) {
+ usb = sb;
+ msb = sb;
+ sbr->num_patches++;
+ } else
+ msb = sbr->kx[1];
+
+ if (sbr->f_master[k] - sb < 3)
+ k = sbr->n_master;
+ } while (sb != sbr->kx[1] + sbr->m[1]);
+
+ if (sbr->num_patches > 1 &&
+ sbr->patch_num_subbands[sbr->num_patches - 1] < 3)
+ sbr->num_patches--;
+
+ return 0;
+}
+
+/// Derived Frequency Band Tables (14496-3 sp04 p197)
+static int sbr_make_f_derived(AACContext *ac, SpectralBandReplication *sbr)
+{
+ int k, temp;
+#if USE_FIXED
+ int nz = 0;
+#endif /* USE_FIXED */
+
+ sbr->n[1] = sbr->n_master - sbr->spectrum_params.bs_xover_band;
+ sbr->n[0] = (sbr->n[1] + 1) >> 1;
+
+ memcpy(sbr->f_tablehigh, &sbr->f_master[sbr->spectrum_params.bs_xover_band],
+ (sbr->n[1] + 1) * sizeof(sbr->f_master[0]));
+ sbr->m[1] = sbr->f_tablehigh[sbr->n[1]] - sbr->f_tablehigh[0];
+ sbr->kx[1] = sbr->f_tablehigh[0];
+
+ // Requirements (14496-3 sp04 p205)
+ if (sbr->kx[1] + sbr->m[1] > 64) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Stop frequency border too high: %d\n", sbr->kx[1] + sbr->m[1]);
+ return -1;
+ }
+ if (sbr->kx[1] > 32) {
+ av_log(ac->avctx, AV_LOG_ERROR, "Start frequency border too high: %d\n", sbr->kx[1]);
+ return -1;
+ }
+
+ sbr->f_tablelow[0] = sbr->f_tablehigh[0];
+ temp = sbr->n[1] & 1;
+ for (k = 1; k <= sbr->n[0]; k++)
+ sbr->f_tablelow[k] = sbr->f_tablehigh[2 * k - temp];
+#if USE_FIXED
+ temp = (sbr->k[2] << 23) / sbr->kx[1];
+ while (temp < 0x40000000) {
+ temp <<= 1;
+ nz++;
+ }
+ temp = fixed_log(temp - 0x80000000);
+ temp = (int)(((int64_t)temp * CONST_RECIP_LN2 + 0x20000000) >> 30);
+ temp = (((temp + 0x80) >> 8) + ((8 - nz) << 23)) * sbr->spectrum_params.bs_noise_bands;
+
+ sbr->n_q = (temp + 0x400000) >> 23;
+ if (sbr->n_q < 1)
+ sbr->n_q = 1;
+#else
+ sbr->n_q = FFMAX(1, lrintf(sbr->spectrum_params.bs_noise_bands *
+ log2f(sbr->k[2] / (float)sbr->kx[1]))); // 0 <= bs_noise_bands <= 3
+#endif /* USE_FIXED */
+
+ if (sbr->n_q > 5) {
+ av_log(ac->avctx, AV_LOG_ERROR, "Too many noise floor scale factors: %d\n", sbr->n_q);
+ return -1;
+ }
+
+ sbr->f_tablenoise[0] = sbr->f_tablelow[0];
+ temp = 0;
+ for (k = 1; k <= sbr->n_q; k++) {
+ temp += (sbr->n[0] - temp) / (sbr->n_q + 1 - k);
+ sbr->f_tablenoise[k] = sbr->f_tablelow[temp];
+ }
+
+ if (sbr_hf_calc_npatches(ac, sbr) < 0)
+ return -1;
+
+ sbr_make_f_tablelim(sbr);
+
+ sbr->data[0].f_indexnoise = 0;
+ sbr->data[1].f_indexnoise = 0;
+
+ return 0;
+}
+
+static av_always_inline void get_bits1_vector(GetBitContext *gb, uint8_t *vec,
+ int elements)
+{
+ int i;
+ for (i = 0; i < elements; i++) {
+ vec[i] = get_bits1(gb);
+ }
+}
+
+/** ceil(log2(index+1)) */
+static const int8_t ceil_log2[] = {
+ 0, 1, 2, 2, 3, 3,
+};
+
+static int read_sbr_grid(AACContext *ac, SpectralBandReplication *sbr,
+ GetBitContext *gb, SBRData *ch_data)
+{
+ int i;
+ int bs_pointer = 0;
+ // frameLengthFlag ? 15 : 16; 960 sample length frames unsupported; this value is numTimeSlots
+ int abs_bord_trail = 16;
+ int num_rel_lead, num_rel_trail;
+ unsigned bs_num_env_old = ch_data->bs_num_env;
+ int bs_frame_class, bs_num_env;
+
+ ch_data->bs_freq_res[0] = ch_data->bs_freq_res[ch_data->bs_num_env];
+ ch_data->bs_amp_res = sbr->bs_amp_res_header;
+ ch_data->t_env_num_env_old = ch_data->t_env[bs_num_env_old];
+
+ switch (bs_frame_class = get_bits(gb, 2)) {
+ case FIXFIX:
+ bs_num_env = 1 << get_bits(gb, 2);
+ if (bs_num_env > 4) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Invalid bitstream, too many SBR envelopes in FIXFIX type SBR frame: %d\n",
+ bs_num_env);
+ return -1;
+ }
+ ch_data->bs_num_env = bs_num_env;
+ num_rel_lead = ch_data->bs_num_env - 1;
+ if (ch_data->bs_num_env == 1)
+ ch_data->bs_amp_res = 0;
+
+
+ ch_data->t_env[0] = 0;
+ ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
+
+ abs_bord_trail = (abs_bord_trail + (ch_data->bs_num_env >> 1)) /
+ ch_data->bs_num_env;
+ for (i = 0; i < num_rel_lead; i++)
+ ch_data->t_env[i + 1] = ch_data->t_env[i] + abs_bord_trail;
+
+ ch_data->bs_freq_res[1] = get_bits1(gb);
+ for (i = 1; i < ch_data->bs_num_env; i++)
+ ch_data->bs_freq_res[i + 1] = ch_data->bs_freq_res[1];
+ break;
+ case FIXVAR:
+ abs_bord_trail += get_bits(gb, 2);
+ num_rel_trail = get_bits(gb, 2);
+ ch_data->bs_num_env = num_rel_trail + 1;
+ ch_data->t_env[0] = 0;
+ ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
+
+ for (i = 0; i < num_rel_trail; i++)
+ ch_data->t_env[ch_data->bs_num_env - 1 - i] =
+ ch_data->t_env[ch_data->bs_num_env - i] - 2 * get_bits(gb, 2) - 2;
+
+ bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]);
+
+ for (i = 0; i < ch_data->bs_num_env; i++)
+ ch_data->bs_freq_res[ch_data->bs_num_env - i] = get_bits1(gb);
+ break;
+ case VARFIX:
+ ch_data->t_env[0] = get_bits(gb, 2);
+ num_rel_lead = get_bits(gb, 2);
+ ch_data->bs_num_env = num_rel_lead + 1;
+ ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
+
+ for (i = 0; i < num_rel_lead; i++)
+ ch_data->t_env[i + 1] = ch_data->t_env[i] + 2 * get_bits(gb, 2) + 2;
+
+ bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]);
+
+ get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env);
+ break;
+ case VARVAR:
+ ch_data->t_env[0] = get_bits(gb, 2);
+ abs_bord_trail += get_bits(gb, 2);
+ num_rel_lead = get_bits(gb, 2);
+ num_rel_trail = get_bits(gb, 2);
+ bs_num_env = num_rel_lead + num_rel_trail + 1;
+
+ if (bs_num_env > 5) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Invalid bitstream, too many SBR envelopes in VARVAR type SBR frame: %d\n",
+ bs_num_env);
+ return -1;
+ }
+ ch_data->bs_num_env = bs_num_env;
+
+ ch_data->t_env[ch_data->bs_num_env] = abs_bord_trail;
+
+ for (i = 0; i < num_rel_lead; i++)
+ ch_data->t_env[i + 1] = ch_data->t_env[i] + 2 * get_bits(gb, 2) + 2;
+ for (i = 0; i < num_rel_trail; i++)
+ ch_data->t_env[ch_data->bs_num_env - 1 - i] =
+ ch_data->t_env[ch_data->bs_num_env - i] - 2 * get_bits(gb, 2) - 2;
+
+ bs_pointer = get_bits(gb, ceil_log2[ch_data->bs_num_env]);
+
+ get_bits1_vector(gb, ch_data->bs_freq_res + 1, ch_data->bs_num_env);
+ break;
+ }
+ ch_data->bs_frame_class = bs_frame_class;
+
+ av_assert0(bs_pointer >= 0);
+ if (bs_pointer > ch_data->bs_num_env + 1) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Invalid bitstream, bs_pointer points to a middle noise border outside the time borders table: %d\n",
+ bs_pointer);
+ return -1;
+ }
+
+ for (i = 1; i <= ch_data->bs_num_env; i++) {
+ if (ch_data->t_env[i-1] >= ch_data->t_env[i]) {
+ av_log(ac->avctx, AV_LOG_ERROR, "Not strictly monotone time borders\n");
+ return -1;
+ }
+ }
+
+ ch_data->bs_num_noise = (ch_data->bs_num_env > 1) + 1;
+
+ ch_data->t_q[0] = ch_data->t_env[0];
+ ch_data->t_q[ch_data->bs_num_noise] = ch_data->t_env[ch_data->bs_num_env];
+ if (ch_data->bs_num_noise > 1) {
+ int idx;
+ if (ch_data->bs_frame_class == FIXFIX) {
+ idx = ch_data->bs_num_env >> 1;
+ } else if (ch_data->bs_frame_class & 1) { // FIXVAR or VARVAR
+ idx = ch_data->bs_num_env - FFMAX(bs_pointer - 1, 1);
+ } else { // VARFIX
+ if (!bs_pointer)
+ idx = 1;
+ else if (bs_pointer == 1)
+ idx = ch_data->bs_num_env - 1;
+ else // bs_pointer > 1
+ idx = bs_pointer - 1;
+ }
+ ch_data->t_q[1] = ch_data->t_env[idx];
+ }
+
+ ch_data->e_a[0] = -(ch_data->e_a[1] != bs_num_env_old); // l_APrev
+ ch_data->e_a[1] = -1;
+ if ((ch_data->bs_frame_class & 1) && bs_pointer) { // FIXVAR or VARVAR and bs_pointer != 0
+ ch_data->e_a[1] = ch_data->bs_num_env + 1 - bs_pointer;
+ } else if ((ch_data->bs_frame_class == 2) && (bs_pointer > 1)) // VARFIX and bs_pointer > 1
+ ch_data->e_a[1] = bs_pointer - 1;
+
+ return 0;
+}
+
+static void copy_sbr_grid(SBRData *dst, const SBRData *src) {
+ //These variables are saved from the previous frame rather than copied
+ dst->bs_freq_res[0] = dst->bs_freq_res[dst->bs_num_env];
+ dst->t_env_num_env_old = dst->t_env[dst->bs_num_env];
+ dst->e_a[0] = -(dst->e_a[1] != dst->bs_num_env);
+
+ //These variables are read from the bitstream and therefore copied
+ memcpy(dst->bs_freq_res+1, src->bs_freq_res+1, sizeof(dst->bs_freq_res)-sizeof(*dst->bs_freq_res));
+ memcpy(dst->t_env, src->t_env, sizeof(dst->t_env));
+ memcpy(dst->t_q, src->t_q, sizeof(dst->t_q));
+ dst->bs_num_env = src->bs_num_env;
+ dst->bs_amp_res = src->bs_amp_res;
+ dst->bs_num_noise = src->bs_num_noise;
+ dst->bs_frame_class = src->bs_frame_class;
+ dst->e_a[1] = src->e_a[1];
+}
+
+/// Read how the envelope and noise floor data is delta coded
+static void read_sbr_dtdf(SpectralBandReplication *sbr, GetBitContext *gb,
+ SBRData *ch_data)
+{
+ get_bits1_vector(gb, ch_data->bs_df_env, ch_data->bs_num_env);
+ get_bits1_vector(gb, ch_data->bs_df_noise, ch_data->bs_num_noise);
+}
+
+/// Read inverse filtering data
+static void read_sbr_invf(SpectralBandReplication *sbr, GetBitContext *gb,
+ SBRData *ch_data)
+{
+ int i;
+
+ memcpy(ch_data->bs_invf_mode[1], ch_data->bs_invf_mode[0], 5 * sizeof(uint8_t));
+ for (i = 0; i < sbr->n_q; i++)
+ ch_data->bs_invf_mode[0][i] = get_bits(gb, 2);
+}
+
+static void read_sbr_envelope(SpectralBandReplication *sbr, GetBitContext *gb,
+ SBRData *ch_data, int ch)
+{
+ int bits;
+ int i, j, k;
+ VLC_TYPE (*t_huff)[2], (*f_huff)[2];
+ int t_lav, f_lav;
+ const int delta = (ch == 1 && sbr->bs_coupling == 1) + 1;
+ const int odd = sbr->n[1] & 1;
+
+ if (sbr->bs_coupling && ch) {
+ if (ch_data->bs_amp_res) {
+ bits = 5;
+ t_huff = vlc_sbr[T_HUFFMAN_ENV_BAL_3_0DB].table;
+ t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_BAL_3_0DB];
+ f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_3_0DB].table;
+ f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_3_0DB];
+ } else {
+ bits = 6;
+ t_huff = vlc_sbr[T_HUFFMAN_ENV_BAL_1_5DB].table;
+ t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_BAL_1_5DB];
+ f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_1_5DB].table;
+ f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_1_5DB];
+ }
+ } else {
+ if (ch_data->bs_amp_res) {
+ bits = 6;
+ t_huff = vlc_sbr[T_HUFFMAN_ENV_3_0DB].table;
+ t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_3_0DB];
+ f_huff = vlc_sbr[F_HUFFMAN_ENV_3_0DB].table;
+ f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_3_0DB];
+ } else {
+ bits = 7;
+ t_huff = vlc_sbr[T_HUFFMAN_ENV_1_5DB].table;
+ t_lav = vlc_sbr_lav[T_HUFFMAN_ENV_1_5DB];
+ f_huff = vlc_sbr[F_HUFFMAN_ENV_1_5DB].table;
+ f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_1_5DB];
+ }
+ }
+
+#if USE_FIXED
+ for (i = 0; i < ch_data->bs_num_env; i++) {
+ if (ch_data->bs_df_env[i]) {
+ // bs_freq_res[0] == bs_freq_res[bs_num_env] from prev frame
+ if (ch_data->bs_freq_res[i + 1] == ch_data->bs_freq_res[i]) {
+ for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++)
+ ch_data->env_facs[i + 1][j].mant = ch_data->env_facs[i][j].mant + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
+ } else if (ch_data->bs_freq_res[i + 1]) {
+ for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) {
+ k = (j + odd) >> 1; // find k such that f_tablelow[k] <= f_tablehigh[j] < f_tablelow[k + 1]
+ ch_data->env_facs[i + 1][j].mant = ch_data->env_facs[i][k].mant + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
+ }
+ } else {
+ for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) {
+ k = j ? 2*j - odd : 0; // find k such that f_tablehigh[k] == f_tablelow[j]
+ ch_data->env_facs[i + 1][j].mant = ch_data->env_facs[i][k].mant + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
+ }
+ }
+ } else {
+ ch_data->env_facs[i + 1][0].mant = delta * get_bits(gb, bits); // bs_env_start_value_balance
+ for (j = 1; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++)
+ ch_data->env_facs[i + 1][j].mant = ch_data->env_facs[i + 1][j - 1].mant + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav);
+ }
+ }
+#else
+ for (i = 0; i < ch_data->bs_num_env; i++) {
+ if (ch_data->bs_df_env[i]) {
+ // bs_freq_res[0] == bs_freq_res[bs_num_env] from prev frame
+ if (ch_data->bs_freq_res[i + 1] == ch_data->bs_freq_res[i]) {
+ for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++)
+ ch_data->env_facs[i + 1][j] = ch_data->env_facs[i][j] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
+ } else if (ch_data->bs_freq_res[i + 1]) {
+ for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) {
+ k = (j + odd) >> 1; // find k such that f_tablelow[k] <= f_tablehigh[j] < f_tablelow[k + 1]
+ ch_data->env_facs[i + 1][j] = ch_data->env_facs[i][k] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
+ }
+ } else {
+ for (j = 0; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++) {
+ k = j ? 2*j - odd : 0; // find k such that f_tablehigh[k] == f_tablelow[j]
+ ch_data->env_facs[i + 1][j] = ch_data->env_facs[i][k] + delta * (get_vlc2(gb, t_huff, 9, 3) - t_lav);
+ }
+ }
+ } else {
+ ch_data->env_facs[i + 1][0] = delta * get_bits(gb, bits); // bs_env_start_value_balance
+ for (j = 1; j < sbr->n[ch_data->bs_freq_res[i + 1]]; j++)
+ ch_data->env_facs[i + 1][j] = ch_data->env_facs[i + 1][j - 1] + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav);
+ }
+ }
+#endif /* USE_FIXED */
+
+ //assign 0th elements of env_facs from last elements
+ memcpy(ch_data->env_facs[0], ch_data->env_facs[ch_data->bs_num_env],
+ sizeof(ch_data->env_facs[0]));
+}
+
+static void read_sbr_noise(SpectralBandReplication *sbr, GetBitContext *gb,
+ SBRData *ch_data, int ch)
+{
+ int i, j;
+ VLC_TYPE (*t_huff)[2], (*f_huff)[2];
+ int t_lav, f_lav;
+ int delta = (ch == 1 && sbr->bs_coupling == 1) + 1;
+
+ if (sbr->bs_coupling && ch) {
+ t_huff = vlc_sbr[T_HUFFMAN_NOISE_BAL_3_0DB].table;
+ t_lav = vlc_sbr_lav[T_HUFFMAN_NOISE_BAL_3_0DB];
+ f_huff = vlc_sbr[F_HUFFMAN_ENV_BAL_3_0DB].table;
+ f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_BAL_3_0DB];
+ } else {
+ t_huff = vlc_sbr[T_HUFFMAN_NOISE_3_0DB].table;
+ t_lav = vlc_sbr_lav[T_HUFFMAN_NOISE_3_0DB];
+ f_huff = vlc_sbr[F_HUFFMAN_ENV_3_0DB].table;
+ f_lav = vlc_sbr_lav[F_HUFFMAN_ENV_3_0DB];
+ }
+
+#if USE_FIXED
+ for (i = 0; i < ch_data->bs_num_noise; i++) {
+ if (ch_data->bs_df_noise[i]) {
+ for (j = 0; j < sbr->n_q; j++)
+ ch_data->noise_facs[i + 1][j].mant = ch_data->noise_facs[i][j].mant + delta * (get_vlc2(gb, t_huff, 9, 2) - t_lav);
+ } else {
+ ch_data->noise_facs[i + 1][0].mant = delta * get_bits(gb, 5); // bs_noise_start_value_balance or bs_noise_start_value_level
+ for (j = 1; j < sbr->n_q; j++)
+ ch_data->noise_facs[i + 1][j].mant = ch_data->noise_facs[i + 1][j - 1].mant + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav);
+ }
+ }
+#else
+ for (i = 0; i < ch_data->bs_num_noise; i++) {
+ if (ch_data->bs_df_noise[i]) {
+ for (j = 0; j < sbr->n_q; j++)
+ ch_data->noise_facs[i + 1][j] = ch_data->noise_facs[i][j] + delta * (get_vlc2(gb, t_huff, 9, 2) - t_lav);
+ } else {
+ ch_data->noise_facs[i + 1][0] = delta * get_bits(gb, 5); // bs_noise_start_value_balance or bs_noise_start_value_level
+ for (j = 1; j < sbr->n_q; j++)
+ ch_data->noise_facs[i + 1][j] = ch_data->noise_facs[i + 1][j - 1] + delta * (get_vlc2(gb, f_huff, 9, 3) - f_lav);
+ }
+ }
+#endif /* USE_FIXED */
+
+ //assign 0th elements of noise_facs from last elements
+ memcpy(ch_data->noise_facs[0], ch_data->noise_facs[ch_data->bs_num_noise],
+ sizeof(ch_data->noise_facs[0]));
+}
+
+static void read_sbr_extension(AACContext *ac, SpectralBandReplication *sbr,
+ GetBitContext *gb,
+ int bs_extension_id, int *num_bits_left)
+{
+ switch (bs_extension_id) {
+ case EXTENSION_ID_PS:
+ if (!ac->oc[1].m4ac.ps) {
+ av_log(ac->avctx, AV_LOG_ERROR, "Parametric Stereo signaled to be not-present but was found in the bitstream.\n");
+ skip_bits_long(gb, *num_bits_left); // bs_fill_bits
+ *num_bits_left = 0;
+ } else {
+#if 1
+ *num_bits_left -= AAC_RENAME(ff_ps_read_data)(ac->avctx, gb, &sbr->ps, *num_bits_left);
+ ac->avctx->profile = FF_PROFILE_AAC_HE_V2;
+#else
+ avpriv_report_missing_feature(ac->avctx, "Parametric Stereo");
+ skip_bits_long(gb, *num_bits_left); // bs_fill_bits
+ *num_bits_left = 0;
+#endif
+ }
+ break;
+ default:
+ // some files contain 0-padding
+ if (bs_extension_id || *num_bits_left > 16 || show_bits(gb, *num_bits_left))
+ avpriv_request_sample(ac->avctx, "Reserved SBR extensions");
+ skip_bits_long(gb, *num_bits_left); // bs_fill_bits
+ *num_bits_left = 0;
+ break;
+ }
+}
+
+static int read_sbr_single_channel_element(AACContext *ac,
+ SpectralBandReplication *sbr,
+ GetBitContext *gb)
+{
+ if (get_bits1(gb)) // bs_data_extra
+ skip_bits(gb, 4); // bs_reserved
+
+ if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]))
+ return -1;
+ read_sbr_dtdf(sbr, gb, &sbr->data[0]);
+ read_sbr_invf(sbr, gb, &sbr->data[0]);
+ read_sbr_envelope(sbr, gb, &sbr->data[0], 0);
+ read_sbr_noise(sbr, gb, &sbr->data[0], 0);
+
+ if ((sbr->data[0].bs_add_harmonic_flag = get_bits1(gb)))
+ get_bits1_vector(gb, sbr->data[0].bs_add_harmonic, sbr->n[1]);
+
+ return 0;
+}
+
+static int read_sbr_channel_pair_element(AACContext *ac,
+ SpectralBandReplication *sbr,
+ GetBitContext *gb)
+{
+ if (get_bits1(gb)) // bs_data_extra
+ skip_bits(gb, 8); // bs_reserved
+
+ if ((sbr->bs_coupling = get_bits1(gb))) {
+ if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]))
+ return -1;
+ copy_sbr_grid(&sbr->data[1], &sbr->data[0]);
+ read_sbr_dtdf(sbr, gb, &sbr->data[0]);
+ read_sbr_dtdf(sbr, gb, &sbr->data[1]);
+ read_sbr_invf(sbr, gb, &sbr->data[0]);
+ memcpy(sbr->data[1].bs_invf_mode[1], sbr->data[1].bs_invf_mode[0], sizeof(sbr->data[1].bs_invf_mode[0]));
+ memcpy(sbr->data[1].bs_invf_mode[0], sbr->data[0].bs_invf_mode[0], sizeof(sbr->data[1].bs_invf_mode[0]));
+ read_sbr_envelope(sbr, gb, &sbr->data[0], 0);
+ read_sbr_noise(sbr, gb, &sbr->data[0], 0);
+ read_sbr_envelope(sbr, gb, &sbr->data[1], 1);
+ read_sbr_noise(sbr, gb, &sbr->data[1], 1);
+ } else {
+ if (read_sbr_grid(ac, sbr, gb, &sbr->data[0]) ||
+ read_sbr_grid(ac, sbr, gb, &sbr->data[1]))
+ return -1;
+ read_sbr_dtdf(sbr, gb, &sbr->data[0]);
+ read_sbr_dtdf(sbr, gb, &sbr->data[1]);
+ read_sbr_invf(sbr, gb, &sbr->data[0]);
+ read_sbr_invf(sbr, gb, &sbr->data[1]);
+ read_sbr_envelope(sbr, gb, &sbr->data[0], 0);
+ read_sbr_envelope(sbr, gb, &sbr->data[1], 1);
+ read_sbr_noise(sbr, gb, &sbr->data[0], 0);
+ read_sbr_noise(sbr, gb, &sbr->data[1], 1);
+ }
+
+ if ((sbr->data[0].bs_add_harmonic_flag = get_bits1(gb)))
+ get_bits1_vector(gb, sbr->data[0].bs_add_harmonic, sbr->n[1]);
+ if ((sbr->data[1].bs_add_harmonic_flag = get_bits1(gb)))
+ get_bits1_vector(gb, sbr->data[1].bs_add_harmonic, sbr->n[1]);
+
+ return 0;
+}
+
+static unsigned int read_sbr_data(AACContext *ac, SpectralBandReplication *sbr,
+ GetBitContext *gb, int id_aac)
+{
+ unsigned int cnt = get_bits_count(gb);
+
+ sbr->id_aac = id_aac;
+ sbr->ready_for_dequant = 1;
+
+ if (id_aac == TYPE_SCE || id_aac == TYPE_CCE) {
+ if (read_sbr_single_channel_element(ac, sbr, gb)) {
+ sbr_turnoff(sbr);
+ return get_bits_count(gb) - cnt;
+ }
+ } else if (id_aac == TYPE_CPE) {
+ if (read_sbr_channel_pair_element(ac, sbr, gb)) {
+ sbr_turnoff(sbr);
+ return get_bits_count(gb) - cnt;
+ }
+ } else {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Invalid bitstream - cannot apply SBR to element type %d\n", id_aac);
+ sbr_turnoff(sbr);
+ return get_bits_count(gb) - cnt;
+ }
+ if (get_bits1(gb)) { // bs_extended_data
+ int num_bits_left = get_bits(gb, 4); // bs_extension_size
+ if (num_bits_left == 15)
+ num_bits_left += get_bits(gb, 8); // bs_esc_count
+
+ num_bits_left <<= 3;
+ while (num_bits_left > 7) {
+ num_bits_left -= 2;
+ read_sbr_extension(ac, sbr, gb, get_bits(gb, 2), &num_bits_left); // bs_extension_id
+ }
+ if (num_bits_left < 0) {
+ av_log(ac->avctx, AV_LOG_ERROR, "SBR Extension over read.\n");
+ }
+ if (num_bits_left > 0)
+ skip_bits(gb, num_bits_left);
+ }
+
+ return get_bits_count(gb) - cnt;
+}
+
+static void sbr_reset(AACContext *ac, SpectralBandReplication *sbr)
+{
+ int err;
+ err = sbr_make_f_master(ac, sbr, &sbr->spectrum_params);
+ if (err >= 0)
+ err = sbr_make_f_derived(ac, sbr);
+ if (err < 0) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "SBR reset failed. Switching SBR to pure upsampling mode.\n");
+ sbr_turnoff(sbr);
+ }
+}
+
+/**
+ * Decode Spectral Band Replication extension data; reference: table 4.55.
+ *
+ * @param crc flag indicating the presence of CRC checksum
+ * @param cnt length of TYPE_FIL syntactic element in bytes
+ *
+ * @return Returns number of bytes consumed from the TYPE_FIL element.
+ */
+int AAC_RENAME(ff_decode_sbr_extension)(AACContext *ac, SpectralBandReplication *sbr,
+ GetBitContext *gb_host, int crc, int cnt, int id_aac)
+{
+ unsigned int num_sbr_bits = 0, num_align_bits;
+ unsigned bytes_read;
+ GetBitContext gbc = *gb_host, *gb = &gbc;
+ skip_bits_long(gb_host, cnt*8 - 4);
+
+ sbr->reset = 0;
+
+ if (!sbr->sample_rate)
+ sbr->sample_rate = 2 * ac->oc[1].m4ac.sample_rate; //TODO use the nominal sample rate for arbitrary sample rate support
+ if (!ac->oc[1].m4ac.ext_sample_rate)
+ ac->oc[1].m4ac.ext_sample_rate = 2 * ac->oc[1].m4ac.sample_rate;
+
+ if (crc) {
+ skip_bits(gb, 10); // bs_sbr_crc_bits; TODO - implement CRC check
+ num_sbr_bits += 10;
+ }
+
+ //Save some state from the previous frame.
+ sbr->kx[0] = sbr->kx[1];
+ sbr->m[0] = sbr->m[1];
+ sbr->kx_and_m_pushed = 1;
+
+ num_sbr_bits++;
+ if (get_bits1(gb)) // bs_header_flag
+ num_sbr_bits += read_sbr_header(sbr, gb);
+
+ if (sbr->reset)
+ sbr_reset(ac, sbr);
+
+ if (sbr->start)
+ num_sbr_bits += read_sbr_data(ac, sbr, gb, id_aac);
+
+ num_align_bits = ((cnt << 3) - 4 - num_sbr_bits) & 7;
+ bytes_read = ((num_sbr_bits + num_align_bits + 4) >> 3);
+
+ if (bytes_read > cnt) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "Expected to read %d SBR bytes actually read %d.\n", cnt, bytes_read);
+ }
+ return cnt;
+}
+
+/**
+ * Analysis QMF Bank (14496-3 sp04 p206)
+ *
+ * @param x pointer to the beginning of the first sample window
+ * @param W array of complex-valued samples split into subbands
+ */
+#ifndef sbr_qmf_analysis
+#if USE_FIXED
+static void sbr_qmf_analysis(AVFixedDSPContext *dsp, FFTContext *mdct,
+#else
+static void sbr_qmf_analysis(AVFloatDSPContext *dsp, FFTContext *mdct,
+#endif /* USE_FIXED */
+ SBRDSPContext *sbrdsp, const INTFLOAT *in, INTFLOAT *x,
+ INTFLOAT z[320], INTFLOAT W[2][32][32][2], int buf_idx)
+{
+ int i;
+#if USE_FIXED
+ int j;
+#endif
+ memcpy(x , x+1024, (320-32)*sizeof(x[0]));
+ memcpy(x+288, in, 1024*sizeof(x[0]));
+ for (i = 0; i < 32; i++) { // numTimeSlots*RATE = 16*2 as 960 sample frames
+ // are not supported
+ dsp->vector_fmul_reverse(z, sbr_qmf_window_ds, x, 320);
+ sbrdsp->sum64x5(z);
+ sbrdsp->qmf_pre_shuffle(z);
+#if USE_FIXED
+ for (j = 64; j < 128; j++) {
+ if (z[j] > 1<<24) {
+ av_log(NULL, AV_LOG_WARNING,
+ "sbr_qmf_analysis: value %09d too large, setting to %09d\n",
+ z[j], 1<<24);
+ z[j] = 1<<24;
+ } else if (z[j] < -(1<<24)) {
+ av_log(NULL, AV_LOG_WARNING,
+ "sbr_qmf_analysis: value %09d too small, setting to %09d\n",
+ z[j], -(1<<24));
+ z[j] = -(1<<24);
+ }
+ }
+#endif
+ mdct->imdct_half(mdct, z, z+64);
+ sbrdsp->qmf_post_shuffle(W[buf_idx][i], z);
+ x += 32;
+ }
+}
+#endif
+
+/**
+ * Synthesis QMF Bank (14496-3 sp04 p206) and Downsampled Synthesis QMF Bank
+ * (14496-3 sp04 p206)
+ */
+#ifndef sbr_qmf_synthesis
+static void sbr_qmf_synthesis(FFTContext *mdct,
+#if USE_FIXED
+ SBRDSPContext *sbrdsp, AVFixedDSPContext *dsp,
+#else
+ SBRDSPContext *sbrdsp, AVFloatDSPContext *dsp,
+#endif /* USE_FIXED */
+ INTFLOAT *out, INTFLOAT X[2][38][64],
+ INTFLOAT mdct_buf[2][64],
+ INTFLOAT *v0, int *v_off, const unsigned int div)
+{
+ int i, n;
+ const INTFLOAT *sbr_qmf_window = div ? sbr_qmf_window_ds : sbr_qmf_window_us;
+ const int step = 128 >> div;
+ INTFLOAT *v;
+ for (i = 0; i < 32; i++) {
+ if (*v_off < step) {
+ int saved_samples = (1280 - 128) >> div;
+ memcpy(&v0[SBR_SYNTHESIS_BUF_SIZE - saved_samples], v0, saved_samples * sizeof(INTFLOAT));
+ *v_off = SBR_SYNTHESIS_BUF_SIZE - saved_samples - step;
+ } else {
+ *v_off -= step;
+ }
+ v = v0 + *v_off;
+ if (div) {
+ for (n = 0; n < 32; n++) {
+ X[0][i][ n] = -X[0][i][n];
+ X[0][i][32+n] = X[1][i][31-n];
+ }
+ mdct->imdct_half(mdct, mdct_buf[0], X[0][i]);
+ sbrdsp->qmf_deint_neg(v, mdct_buf[0]);
+ } else {
+ sbrdsp->neg_odd_64(X[1][i]);
+ mdct->imdct_half(mdct, mdct_buf[0], X[0][i]);
+ mdct->imdct_half(mdct, mdct_buf[1], X[1][i]);
+ sbrdsp->qmf_deint_bfly(v, mdct_buf[1], mdct_buf[0]);
+ }
+ dsp->vector_fmul (out, v , sbr_qmf_window , 64 >> div);
+ dsp->vector_fmul_add(out, v + ( 192 >> div), sbr_qmf_window + ( 64 >> div), out , 64 >> div);
+ dsp->vector_fmul_add(out, v + ( 256 >> div), sbr_qmf_window + (128 >> div), out , 64 >> div);
+ dsp->vector_fmul_add(out, v + ( 448 >> div), sbr_qmf_window + (192 >> div), out , 64 >> div);
+ dsp->vector_fmul_add(out, v + ( 512 >> div), sbr_qmf_window + (256 >> div), out , 64 >> div);
+ dsp->vector_fmul_add(out, v + ( 704 >> div), sbr_qmf_window + (320 >> div), out , 64 >> div);
+ dsp->vector_fmul_add(out, v + ( 768 >> div), sbr_qmf_window + (384 >> div), out , 64 >> div);
+ dsp->vector_fmul_add(out, v + ( 960 >> div), sbr_qmf_window + (448 >> div), out , 64 >> div);
+ dsp->vector_fmul_add(out, v + (1024 >> div), sbr_qmf_window + (512 >> div), out , 64 >> div);
+ dsp->vector_fmul_add(out, v + (1216 >> div), sbr_qmf_window + (576 >> div), out , 64 >> div);
+ out += 64 >> div;
+ }
+}
+#endif
+
+/// Generate the subband filtered lowband
+static int sbr_lf_gen(AACContext *ac, SpectralBandReplication *sbr,
+ INTFLOAT X_low[32][40][2], const INTFLOAT W[2][32][32][2],
+ int buf_idx)
+{
+ int i, k;
+ const int t_HFGen = 8;
+ const int i_f = 32;
+ memset(X_low, 0, 32*sizeof(*X_low));
+ for (k = 0; k < sbr->kx[1]; k++) {
+ for (i = t_HFGen; i < i_f + t_HFGen; i++) {
+ X_low[k][i][0] = W[buf_idx][i - t_HFGen][k][0];
+ X_low[k][i][1] = W[buf_idx][i - t_HFGen][k][1];
+ }
+ }
+ buf_idx = 1-buf_idx;
+ for (k = 0; k < sbr->kx[0]; k++) {
+ for (i = 0; i < t_HFGen; i++) {
+ X_low[k][i][0] = W[buf_idx][i + i_f - t_HFGen][k][0];
+ X_low[k][i][1] = W[buf_idx][i + i_f - t_HFGen][k][1];
+ }
+ }
+ return 0;
+}
+
+/// High Frequency Generator (14496-3 sp04 p215)
+static int sbr_hf_gen(AACContext *ac, SpectralBandReplication *sbr,
+ INTFLOAT X_high[64][40][2], const INTFLOAT X_low[32][40][2],
+ const INTFLOAT (*alpha0)[2], const INTFLOAT (*alpha1)[2],
+ const INTFLOAT bw_array[5], const uint8_t *t_env,
+ int bs_num_env)
+{
+ int j, x;
+ int g = 0;
+ int k = sbr->kx[1];
+ for (j = 0; j < sbr->num_patches; j++) {
+ for (x = 0; x < sbr->patch_num_subbands[j]; x++, k++) {
+ const int p = sbr->patch_start_subband[j] + x;
+ while (g <= sbr->n_q && k >= sbr->f_tablenoise[g])
+ g++;
+ g--;
+
+ if (g < 0) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "ERROR : no subband found for frequency %d\n", k);
+ return -1;
+ }
+
+ sbr->dsp.hf_gen(X_high[k] + ENVELOPE_ADJUSTMENT_OFFSET,
+ X_low[p] + ENVELOPE_ADJUSTMENT_OFFSET,
+ alpha0[p], alpha1[p], bw_array[g],
+ 2 * t_env[0], 2 * t_env[bs_num_env]);
+ }
+ }
+ if (k < sbr->m[1] + sbr->kx[1])
+ memset(X_high + k, 0, (sbr->m[1] + sbr->kx[1] - k) * sizeof(*X_high));
+
+ return 0;
+}
+
+/// Generate the subband filtered lowband
+static int sbr_x_gen(SpectralBandReplication *sbr, INTFLOAT X[2][38][64],
+ const INTFLOAT Y0[38][64][2], const INTFLOAT Y1[38][64][2],
+ const INTFLOAT X_low[32][40][2], int ch)
+{
+ int k, i;
+ const int i_f = 32;
+ const int i_Temp = FFMAX(2*sbr->data[ch].t_env_num_env_old - i_f, 0);
+ memset(X, 0, 2*sizeof(*X));
+ for (k = 0; k < sbr->kx[0]; k++) {
+ for (i = 0; i < i_Temp; i++) {
+ X[0][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][0];
+ X[1][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][1];
+ }
+ }
+ for (; k < sbr->kx[0] + sbr->m[0]; k++) {
+ for (i = 0; i < i_Temp; i++) {
+ X[0][i][k] = Y0[i + i_f][k][0];
+ X[1][i][k] = Y0[i + i_f][k][1];
+ }
+ }
+
+ for (k = 0; k < sbr->kx[1]; k++) {
+ for (i = i_Temp; i < 38; i++) {
+ X[0][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][0];
+ X[1][i][k] = X_low[k][i + ENVELOPE_ADJUSTMENT_OFFSET][1];
+ }
+ }
+ for (; k < sbr->kx[1] + sbr->m[1]; k++) {
+ for (i = i_Temp; i < i_f; i++) {
+ X[0][i][k] = Y1[i][k][0];
+ X[1][i][k] = Y1[i][k][1];
+ }
+ }
+ return 0;
+}
+
+/** High Frequency Adjustment (14496-3 sp04 p217) and Mapping
+ * (14496-3 sp04 p217)
+ */
+static int sbr_mapping(AACContext *ac, SpectralBandReplication *sbr,
+ SBRData *ch_data, int e_a[2])
+{
+ int e, i, m;
+
+ memset(ch_data->s_indexmapped[1], 0, 7*sizeof(ch_data->s_indexmapped[1]));
+ for (e = 0; e < ch_data->bs_num_env; e++) {
+ const unsigned int ilim = sbr->n[ch_data->bs_freq_res[e + 1]];
+ uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow;
+ int k;
+
+ if (sbr->kx[1] != table[0]) {
+ av_log(ac->avctx, AV_LOG_ERROR, "kx != f_table{high,low}[0]. "
+ "Derived frequency tables were not regenerated.\n");
+ sbr_turnoff(sbr);
+ return AVERROR_BUG;
+ }
+ for (i = 0; i < ilim; i++)
+ for (m = table[i]; m < table[i + 1]; m++)
+ sbr->e_origmapped[e][m - sbr->kx[1]] = ch_data->env_facs[e+1][i];
+
+ // ch_data->bs_num_noise > 1 => 2 noise floors
+ k = (ch_data->bs_num_noise > 1) && (ch_data->t_env[e] >= ch_data->t_q[1]);
+ for (i = 0; i < sbr->n_q; i++)
+ for (m = sbr->f_tablenoise[i]; m < sbr->f_tablenoise[i + 1]; m++)
+ sbr->q_mapped[e][m - sbr->kx[1]] = ch_data->noise_facs[k+1][i];
+
+ for (i = 0; i < sbr->n[1]; i++) {
+ if (ch_data->bs_add_harmonic_flag) {
+ const unsigned int m_midpoint =
+ (sbr->f_tablehigh[i] + sbr->f_tablehigh[i + 1]) >> 1;
+
+ ch_data->s_indexmapped[e + 1][m_midpoint - sbr->kx[1]] = ch_data->bs_add_harmonic[i] *
+ (e >= e_a[1] || (ch_data->s_indexmapped[0][m_midpoint - sbr->kx[1]] == 1));
+ }
+ }
+
+ for (i = 0; i < ilim; i++) {
+ int additional_sinusoid_present = 0;
+ for (m = table[i]; m < table[i + 1]; m++) {
+ if (ch_data->s_indexmapped[e + 1][m - sbr->kx[1]]) {
+ additional_sinusoid_present = 1;
+ break;
+ }
+ }
+ memset(&sbr->s_mapped[e][table[i] - sbr->kx[1]], additional_sinusoid_present,
+ (table[i + 1] - table[i]) * sizeof(sbr->s_mapped[e][0]));
+ }
+ }
+
+ memcpy(ch_data->s_indexmapped[0], ch_data->s_indexmapped[ch_data->bs_num_env], sizeof(ch_data->s_indexmapped[0]));
+ return 0;
+}
+
+/// Estimation of current envelope (14496-3 sp04 p218)
+static void sbr_env_estimate(AAC_FLOAT (*e_curr)[48], INTFLOAT X_high[64][40][2],
+ SpectralBandReplication *sbr, SBRData *ch_data)
+{
+ int e, m;
+ int kx1 = sbr->kx[1];
+
+ if (sbr->bs_interpol_freq) {
+ for (e = 0; e < ch_data->bs_num_env; e++) {
+#if USE_FIXED
+ const SoftFloat recip_env_size = av_int2sf(0x20000000 / (ch_data->t_env[e + 1] - ch_data->t_env[e]), 30);
+#else
+ const float recip_env_size = 0.5f / (ch_data->t_env[e + 1] - ch_data->t_env[e]);
+#endif /* USE_FIXED */
+ int ilb = ch_data->t_env[e] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;
+ int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;
+
+ for (m = 0; m < sbr->m[1]; m++) {
+ AAC_FLOAT sum = sbr->dsp.sum_square(X_high[m+kx1] + ilb, iub - ilb);
+#if USE_FIXED
+ e_curr[e][m] = av_mul_sf(sum, recip_env_size);
+#else
+ e_curr[e][m] = sum * recip_env_size;
+#endif /* USE_FIXED */
+ }
+ }
+ } else {
+ int k, p;
+
+ for (e = 0; e < ch_data->bs_num_env; e++) {
+ const int env_size = 2 * (ch_data->t_env[e + 1] - ch_data->t_env[e]);
+ int ilb = ch_data->t_env[e] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;
+ int iub = ch_data->t_env[e + 1] * 2 + ENVELOPE_ADJUSTMENT_OFFSET;
+ const uint16_t *table = ch_data->bs_freq_res[e + 1] ? sbr->f_tablehigh : sbr->f_tablelow;
+
+ for (p = 0; p < sbr->n[ch_data->bs_freq_res[e + 1]]; p++) {
+#if USE_FIXED
+ SoftFloat sum = FLOAT_0;
+ const SoftFloat den = av_int2sf(0x20000000 / (env_size * (table[p + 1] - table[p])), 29);
+ for (k = table[p]; k < table[p + 1]; k++) {
+ sum = av_add_sf(sum, sbr->dsp.sum_square(X_high[k] + ilb, iub - ilb));
+ }
+ sum = av_mul_sf(sum, den);
+#else
+ float sum = 0.0f;
+ const int den = env_size * (table[p + 1] - table[p]);
+
+ for (k = table[p]; k < table[p + 1]; k++) {
+ sum += sbr->dsp.sum_square(X_high[k] + ilb, iub - ilb);
+ }
+ sum /= den;
+#endif /* USE_FIXED */
+ for (k = table[p]; k < table[p + 1]; k++) {
+ e_curr[e][k - kx1] = sum;
+ }
+ }
+ }
+ }
+}
+
+void AAC_RENAME(ff_sbr_apply)(AACContext *ac, SpectralBandReplication *sbr, int id_aac,
+ INTFLOAT* L, INTFLOAT* R)
+{
+ int downsampled = ac->oc[1].m4ac.ext_sample_rate < sbr->sample_rate;
+ int ch;
+ int nch = (id_aac == TYPE_CPE) ? 2 : 1;
+ int err;
+
+ if (id_aac != sbr->id_aac) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "element type mismatch %d != %d\n", id_aac, sbr->id_aac);
+ sbr_turnoff(sbr);
+ }
+
+ if (sbr->start && !sbr->ready_for_dequant) {
+ av_log(ac->avctx, AV_LOG_ERROR,
+ "No quantized data read for sbr_dequant.\n");
+ sbr_turnoff(sbr);
+ }
+
+ if (!sbr->kx_and_m_pushed) {
+ sbr->kx[0] = sbr->kx[1];
+ sbr->m[0] = sbr->m[1];
+ } else {
+ sbr->kx_and_m_pushed = 0;
+ }
+
+ if (sbr->start) {
+ sbr_dequant(sbr, id_aac);
+ sbr->ready_for_dequant = 0;
+ }
+ for (ch = 0; ch < nch; ch++) {
+ /* decode channel */
+ sbr_qmf_analysis(ac->fdsp, &sbr->mdct_ana, &sbr->dsp, ch ? R : L, sbr->data[ch].analysis_filterbank_samples,
+ (INTFLOAT*)sbr->qmf_filter_scratch,
+ sbr->data[ch].W, sbr->data[ch].Ypos);
+ sbr->c.sbr_lf_gen(ac, sbr, sbr->X_low,
+ (const INTFLOAT (*)[32][32][2]) sbr->data[ch].W,
+ sbr->data[ch].Ypos);
+ sbr->data[ch].Ypos ^= 1;
+ if (sbr->start) {
+ sbr->c.sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1,
+ (const INTFLOAT (*)[40][2]) sbr->X_low, sbr->k[0]);
+ sbr_chirp(sbr, &sbr->data[ch]);
+ av_assert0(sbr->data[ch].bs_num_env > 0);
+ sbr_hf_gen(ac, sbr, sbr->X_high,
+ (const INTFLOAT (*)[40][2]) sbr->X_low,
+ (const INTFLOAT (*)[2]) sbr->alpha0,
+ (const INTFLOAT (*)[2]) sbr->alpha1,
+ sbr->data[ch].bw_array, sbr->data[ch].t_env,
+ sbr->data[ch].bs_num_env);
+
+ // hf_adj
+ err = sbr_mapping(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
+ if (!err) {
+ sbr_env_estimate(sbr->e_curr, sbr->X_high, sbr, &sbr->data[ch]);
+ sbr_gain_calc(ac, sbr, &sbr->data[ch], sbr->data[ch].e_a);
+ sbr->c.sbr_hf_assemble(sbr->data[ch].Y[sbr->data[ch].Ypos],
+ (const INTFLOAT (*)[40][2]) sbr->X_high,
+ sbr, &sbr->data[ch],
+ sbr->data[ch].e_a);
+ }
+ }
+
+ /* synthesis */
+ sbr->c.sbr_x_gen(sbr, sbr->X[ch],
+ (const INTFLOAT (*)[64][2]) sbr->data[ch].Y[1-sbr->data[ch].Ypos],
+ (const INTFLOAT (*)[64][2]) sbr->data[ch].Y[ sbr->data[ch].Ypos],
+ (const INTFLOAT (*)[40][2]) sbr->X_low, ch);
+ }
+
+ if (ac->oc[1].m4ac.ps == 1) {
+ if (sbr->ps.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]));
+ }
+ nch = 2;
+ }
+
+ sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, ac->fdsp,
+ L, sbr->X[0], sbr->qmf_filter_scratch,
+ sbr->data[0].synthesis_filterbank_samples,
+ &sbr->data[0].synthesis_filterbank_samples_offset,
+ downsampled);
+ if (nch == 2)
+ sbr_qmf_synthesis(&sbr->mdct, &sbr->dsp, ac->fdsp,
+ R, sbr->X[1], sbr->qmf_filter_scratch,
+ sbr->data[1].synthesis_filterbank_samples,
+ &sbr->data[1].synthesis_filterbank_samples_offset,
+ downsampled);
+}
+
+static void aacsbr_func_ptr_init(AACSBRContext *c)
+{
+ c->sbr_lf_gen = sbr_lf_gen;
+ c->sbr_hf_assemble = sbr_hf_assemble;
+ c->sbr_x_gen = sbr_x_gen;
+ c->sbr_hf_inverse_filter = sbr_hf_inverse_filter;
+
+#if !USE_FIXED
+ if(ARCH_MIPS)
+ ff_aacsbr_func_ptr_init_mips(c);
+#endif
+}
diff --git a/ffmpeg-2-8-11/libavcodec/aacsbrdata.h b/ffmpeg-2-8-12/libavcodec/aacsbrdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aacsbrdata.h
rename to ffmpeg-2-8-12/libavcodec/aacsbrdata.h
diff --git a/ffmpeg-2-8-11/libavcodec/aactab.c b/ffmpeg-2-8-12/libavcodec/aactab.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aactab.c
rename to ffmpeg-2-8-12/libavcodec/aactab.c
diff --git a/ffmpeg-2-8-11/libavcodec/aactab.h b/ffmpeg-2-8-12/libavcodec/aactab.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aactab.h
rename to ffmpeg-2-8-12/libavcodec/aactab.h
diff --git a/ffmpeg-2-8-11/libavcodec/aandcttab.c b/ffmpeg-2-8-12/libavcodec/aandcttab.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aandcttab.c
rename to ffmpeg-2-8-12/libavcodec/aandcttab.c
diff --git a/ffmpeg-2-8-11/libavcodec/aandcttab.h b/ffmpeg-2-8-12/libavcodec/aandcttab.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aandcttab.h
rename to ffmpeg-2-8-12/libavcodec/aandcttab.h
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/Makefile b/ffmpeg-2-8-12/libavcodec/aarch64/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/Makefile
rename to ffmpeg-2-8-12/libavcodec/aarch64/Makefile
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/asm-offsets.h b/ffmpeg-2-8-12/libavcodec/aarch64/asm-offsets.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/asm-offsets.h
rename to ffmpeg-2-8-12/libavcodec/aarch64/asm-offsets.h
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/cabac.h b/ffmpeg-2-8-12/libavcodec/aarch64/cabac.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/cabac.h
rename to ffmpeg-2-8-12/libavcodec/aarch64/cabac.h
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/fft_init_aarch64.c b/ffmpeg-2-8-12/libavcodec/aarch64/fft_init_aarch64.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/fft_init_aarch64.c
rename to ffmpeg-2-8-12/libavcodec/aarch64/fft_init_aarch64.c
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/fft_neon.S b/ffmpeg-2-8-12/libavcodec/aarch64/fft_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/fft_neon.S
rename to ffmpeg-2-8-12/libavcodec/aarch64/fft_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/h264chroma_init_aarch64.c b/ffmpeg-2-8-12/libavcodec/aarch64/h264chroma_init_aarch64.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/h264chroma_init_aarch64.c
rename to ffmpeg-2-8-12/libavcodec/aarch64/h264chroma_init_aarch64.c
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/h264cmc_neon.S b/ffmpeg-2-8-12/libavcodec/aarch64/h264cmc_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/h264cmc_neon.S
rename to ffmpeg-2-8-12/libavcodec/aarch64/h264cmc_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/h264dsp_init_aarch64.c b/ffmpeg-2-8-12/libavcodec/aarch64/h264dsp_init_aarch64.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/h264dsp_init_aarch64.c
rename to ffmpeg-2-8-12/libavcodec/aarch64/h264dsp_init_aarch64.c
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/h264dsp_neon.S b/ffmpeg-2-8-12/libavcodec/aarch64/h264dsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/h264dsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/aarch64/h264dsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/h264idct_neon.S b/ffmpeg-2-8-12/libavcodec/aarch64/h264idct_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/h264idct_neon.S
rename to ffmpeg-2-8-12/libavcodec/aarch64/h264idct_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/h264pred_init.c b/ffmpeg-2-8-12/libavcodec/aarch64/h264pred_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/h264pred_init.c
rename to ffmpeg-2-8-12/libavcodec/aarch64/h264pred_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/h264pred_neon.S b/ffmpeg-2-8-12/libavcodec/aarch64/h264pred_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/h264pred_neon.S
rename to ffmpeg-2-8-12/libavcodec/aarch64/h264pred_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/h264qpel_init_aarch64.c b/ffmpeg-2-8-12/libavcodec/aarch64/h264qpel_init_aarch64.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/h264qpel_init_aarch64.c
rename to ffmpeg-2-8-12/libavcodec/aarch64/h264qpel_init_aarch64.c
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/h264qpel_neon.S b/ffmpeg-2-8-12/libavcodec/aarch64/h264qpel_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/h264qpel_neon.S
rename to ffmpeg-2-8-12/libavcodec/aarch64/h264qpel_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/hpeldsp_init_aarch64.c b/ffmpeg-2-8-12/libavcodec/aarch64/hpeldsp_init_aarch64.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/hpeldsp_init_aarch64.c
rename to ffmpeg-2-8-12/libavcodec/aarch64/hpeldsp_init_aarch64.c
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/hpeldsp_neon.S b/ffmpeg-2-8-12/libavcodec/aarch64/hpeldsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/hpeldsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/aarch64/hpeldsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/imdct15_init.c b/ffmpeg-2-8-12/libavcodec/aarch64/imdct15_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/imdct15_init.c
rename to ffmpeg-2-8-12/libavcodec/aarch64/imdct15_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/imdct15_neon.S b/ffmpeg-2-8-12/libavcodec/aarch64/imdct15_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/imdct15_neon.S
rename to ffmpeg-2-8-12/libavcodec/aarch64/imdct15_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/mdct_neon.S b/ffmpeg-2-8-12/libavcodec/aarch64/mdct_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/mdct_neon.S
rename to ffmpeg-2-8-12/libavcodec/aarch64/mdct_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/mpegaudiodsp_init.c b/ffmpeg-2-8-12/libavcodec/aarch64/mpegaudiodsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/mpegaudiodsp_init.c
rename to ffmpeg-2-8-12/libavcodec/aarch64/mpegaudiodsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/mpegaudiodsp_neon.S b/ffmpeg-2-8-12/libavcodec/aarch64/mpegaudiodsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/mpegaudiodsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/aarch64/mpegaudiodsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/neon.S b/ffmpeg-2-8-12/libavcodec/aarch64/neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/neon.S
rename to ffmpeg-2-8-12/libavcodec/aarch64/neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/neontest.c b/ffmpeg-2-8-12/libavcodec/aarch64/neontest.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/neontest.c
rename to ffmpeg-2-8-12/libavcodec/aarch64/neontest.c
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/rv40dsp_init_aarch64.c b/ffmpeg-2-8-12/libavcodec/aarch64/rv40dsp_init_aarch64.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/rv40dsp_init_aarch64.c
rename to ffmpeg-2-8-12/libavcodec/aarch64/rv40dsp_init_aarch64.c
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/vc1dsp_init_aarch64.c b/ffmpeg-2-8-12/libavcodec/aarch64/vc1dsp_init_aarch64.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/vc1dsp_init_aarch64.c
rename to ffmpeg-2-8-12/libavcodec/aarch64/vc1dsp_init_aarch64.c
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/videodsp.S b/ffmpeg-2-8-12/libavcodec/aarch64/videodsp.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/videodsp.S
rename to ffmpeg-2-8-12/libavcodec/aarch64/videodsp.S
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/videodsp_init.c b/ffmpeg-2-8-12/libavcodec/aarch64/videodsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/videodsp_init.c
rename to ffmpeg-2-8-12/libavcodec/aarch64/videodsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/vorbisdsp_init.c b/ffmpeg-2-8-12/libavcodec/aarch64/vorbisdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/vorbisdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/aarch64/vorbisdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/aarch64/vorbisdsp_neon.S b/ffmpeg-2-8-12/libavcodec/aarch64/vorbisdsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aarch64/vorbisdsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/aarch64/vorbisdsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/aasc.c b/ffmpeg-2-8-12/libavcodec/aasc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aasc.c
rename to ffmpeg-2-8-12/libavcodec/aasc.c
diff --git a/ffmpeg-2-8-11/libavcodec/ac3.c b/ffmpeg-2-8-12/libavcodec/ac3.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3.c
rename to ffmpeg-2-8-12/libavcodec/ac3.c
diff --git a/ffmpeg-2-8-11/libavcodec/ac3.h b/ffmpeg-2-8-12/libavcodec/ac3.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3.h
rename to ffmpeg-2-8-12/libavcodec/ac3.h
diff --git a/ffmpeg-2-8-11/libavcodec/ac3_parser.c b/ffmpeg-2-8-12/libavcodec/ac3_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3_parser.c
rename to ffmpeg-2-8-12/libavcodec/ac3_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/ac3_parser.h b/ffmpeg-2-8-12/libavcodec/ac3_parser.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3_parser.h
rename to ffmpeg-2-8-12/libavcodec/ac3_parser.h
diff --git a/ffmpeg-2-8-12/libavcodec/ac3dec.c b/ffmpeg-2-8-12/libavcodec/ac3dec.c
new file mode 100644
index 0000000..138bb69
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/ac3dec.c
@@ -0,0 +1,1647 @@
+/*
+ * AC-3 Audio Decoder
+ * This code was developed as part of Google Summer of Code 2006.
+ * E-AC-3 support was added as part of Google Summer of Code 2007.
+ *
+ * Copyright (c) 2006 Kartikey Mahendra BHATT (bhattkm at gmail dot com)
+ * Copyright (c) 2007-2008 Bartlomiej Wolowiec <bartek.wolowiec at gmail.com>
+ * Copyright (c) 2007 Justin Ruggles <justin.ruggles at gmail.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 <stdio.h>
+#include <stddef.h>
+#include <math.h>
+#include <string.h>
+
+#include "libavutil/channel_layout.h"
+#include "libavutil/crc.h"
+#include "libavutil/downmix_info.h"
+#include "libavutil/opt.h"
+#include "bswapdsp.h"
+#include "internal.h"
+#include "aac_ac3_parser.h"
+#include "ac3_parser.h"
+#include "ac3dec.h"
+#include "ac3dec_data.h"
+#include "kbdwin.h"
+
+/**
+ * table for ungrouping 3 values in 7 bits.
+ * used for exponents and bap=2 mantissas
+ */
+static uint8_t ungroup_3_in_7_bits_tab[128][3];
+
+/** tables for ungrouping mantissas */
+static int b1_mantissas[32][3];
+static int b2_mantissas[128][3];
+static int b3_mantissas[8];
+static int b4_mantissas[128][2];
+static int b5_mantissas[16];
+
+/**
+ * Quantization table: levels for symmetric. bits for asymmetric.
+ * reference: Table 7.18 Mapping of bap to Quantizer
+ */
+static const uint8_t quantization_tab[16] = {
+ 0, 3, 5, 7, 11, 15,
+ 5, 6, 7, 8, 9, 10, 11, 12, 14, 16
+};
+
+/** dynamic range table. converts codes to scale factors. */
+static float dynamic_range_tab[256];
+static float heavy_dynamic_range_tab[256];
+
+/** Adjustments in dB gain */
+static const float gain_levels[9] = {
+ LEVEL_PLUS_3DB,
+ LEVEL_PLUS_1POINT5DB,
+ LEVEL_ONE,
+ LEVEL_MINUS_1POINT5DB,
+ LEVEL_MINUS_3DB,
+ LEVEL_MINUS_4POINT5DB,
+ LEVEL_MINUS_6DB,
+ LEVEL_ZERO,
+ LEVEL_MINUS_9DB
+};
+
+/** Adjustments in dB gain (LFE, +10 to -21 dB) */
+static const float gain_levels_lfe[32] = {
+ 3.162275, 2.818382, 2.511886, 2.238719, 1.995261, 1.778278, 1.584893,
+ 1.412536, 1.258924, 1.122018, 1.000000, 0.891251, 0.794328, 0.707946,
+ 0.630957, 0.562341, 0.501187, 0.446683, 0.398107, 0.354813, 0.316227,
+ 0.281838, 0.251188, 0.223872, 0.199526, 0.177828, 0.158489, 0.141253,
+ 0.125892, 0.112201, 0.100000, 0.089125
+};
+
+/**
+ * Table for default stereo downmixing coefficients
+ * reference: Section 7.8.2 Downmixing Into Two Channels
+ */
+static const uint8_t ac3_default_coeffs[8][5][2] = {
+ { { 2, 7 }, { 7, 2 }, },
+ { { 4, 4 }, },
+ { { 2, 7 }, { 7, 2 }, },
+ { { 2, 7 }, { 5, 5 }, { 7, 2 }, },
+ { { 2, 7 }, { 7, 2 }, { 6, 6 }, },
+ { { 2, 7 }, { 5, 5 }, { 7, 2 }, { 8, 8 }, },
+ { { 2, 7 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, },
+ { { 2, 7 }, { 5, 5 }, { 7, 2 }, { 6, 7 }, { 7, 6 }, },
+};
+
+/**
+ * Symmetrical Dequantization
+ * reference: Section 7.3.3 Expansion of Mantissas for Symmetrical Quantization
+ * Tables 7.19 to 7.23
+ */
+static inline int
+symmetric_dequant(int code, int levels)
+{
+ return ((code - (levels >> 1)) * (1 << 24)) / levels;
+}
+
+/*
+ * Initialize tables at runtime.
+ */
+static av_cold void ac3_tables_init(void)
+{
+ int i;
+
+ /* generate table for ungrouping 3 values in 7 bits
+ reference: Section 7.1.3 Exponent Decoding */
+ for (i = 0; i < 128; i++) {
+ ungroup_3_in_7_bits_tab[i][0] = i / 25;
+ ungroup_3_in_7_bits_tab[i][1] = (i % 25) / 5;
+ ungroup_3_in_7_bits_tab[i][2] = (i % 25) % 5;
+ }
+
+ /* generate grouped mantissa tables
+ reference: Section 7.3.5 Ungrouping of Mantissas */
+ for (i = 0; i < 32; i++) {
+ /* bap=1 mantissas */
+ b1_mantissas[i][0] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][0], 3);
+ b1_mantissas[i][1] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][1], 3);
+ b1_mantissas[i][2] = symmetric_dequant(ff_ac3_ungroup_3_in_5_bits_tab[i][2], 3);
+ }
+ for (i = 0; i < 128; i++) {
+ /* bap=2 mantissas */
+ b2_mantissas[i][0] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][0], 5);
+ b2_mantissas[i][1] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][1], 5);
+ b2_mantissas[i][2] = symmetric_dequant(ungroup_3_in_7_bits_tab[i][2], 5);
+
+ /* bap=4 mantissas */
+ b4_mantissas[i][0] = symmetric_dequant(i / 11, 11);
+ b4_mantissas[i][1] = symmetric_dequant(i % 11, 11);
+ }
+ /* generate ungrouped mantissa tables
+ reference: Tables 7.21 and 7.23 */
+ for (i = 0; i < 7; i++) {
+ /* bap=3 mantissas */
+ b3_mantissas[i] = symmetric_dequant(i, 7);
+ }
+ for (i = 0; i < 15; i++) {
+ /* bap=5 mantissas */
+ b5_mantissas[i] = symmetric_dequant(i, 15);
+ }
+
+ /* generate dynamic range table
+ reference: Section 7.7.1 Dynamic Range Control */
+ for (i = 0; i < 256; i++) {
+ int v = (i >> 5) - ((i >> 7) << 3) - 5;
+ dynamic_range_tab[i] = powf(2.0f, v) * ((i & 0x1F) | 0x20);
+ }
+
+ /* generate compr dynamic range table
+ reference: Section 7.7.2 Heavy Compression */
+ for (i = 0; i < 256; i++) {
+ int v = (i >> 4) - ((i >> 7) << 4) - 4;
+ heavy_dynamic_range_tab[i] = powf(2.0f, v) * ((i & 0xF) | 0x10);
+ }
+
+}
+
+/**
+ * AVCodec initialization
+ */
+static av_cold int ac3_decode_init(AVCodecContext *avctx)
+{
+ AC3DecodeContext *s = avctx->priv_data;
+ int i;
+
+ s->avctx = avctx;
+
+ ff_ac3_common_init();
+ ac3_tables_init();
+ ff_mdct_init(&s->imdct_256, 8, 1, 1.0);
+ ff_mdct_init(&s->imdct_512, 9, 1, 1.0);
+ 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);
+#endif
+
+ ff_ac3dsp_init(&s->ac3dsp, avctx->flags & AV_CODEC_FLAG_BITEXACT);
+ av_lfg_init(&s->dith_state, 0);
+
+ if (USE_FIXED)
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+ else
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
+
+ /* allow downmixing to stereo or mono */
+#if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (avctx->request_channels == 1)
+ avctx->request_channel_layout = AV_CH_LAYOUT_MONO;
+ else if (avctx->request_channels == 2)
+ avctx->request_channel_layout = AV_CH_LAYOUT_STEREO;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ if (avctx->channels > 1 &&
+ avctx->request_channel_layout == AV_CH_LAYOUT_MONO)
+ avctx->channels = 1;
+ else if (avctx->channels > 2 &&
+ avctx->request_channel_layout == AV_CH_LAYOUT_STEREO)
+ avctx->channels = 2;
+ s->downmixed = 1;
+
+ for (i = 0; i < AC3_MAX_CHANNELS; i++) {
+ s->xcfptr[i] = s->transform_coeffs[i];
+ s->dlyptr[i] = s->delay[i];
+ }
+
+ return 0;
+}
+
+/**
+ * Parse the 'sync info' and 'bit stream info' from the AC-3 bitstream.
+ * GetBitContext within AC3DecodeContext must point to
+ * the start of the synchronized AC-3 bitstream.
+ */
+static int ac3_parse_header(AC3DecodeContext *s)
+{
+ GetBitContext *gbc = &s->gbc;
+ int i;
+
+ /* read the rest of the bsi. read twice for dual mono mode. */
+ i = !s->channel_mode;
+ do {
+ s->dialog_normalization[(!s->channel_mode)-i] = -get_bits(gbc, 5);
+ if (s->dialog_normalization[(!s->channel_mode)-i] == 0) {
+ s->dialog_normalization[(!s->channel_mode)-i] = -31;
+ }
+ if (s->target_level != 0) {
+ s->level_gain[(!s->channel_mode)-i] = powf(2.0f,
+ (float)(s->target_level -
+ s->dialog_normalization[(!s->channel_mode)-i])/6.0f);
+ }
+ if (s->compression_exists[(!s->channel_mode)-i] = get_bits1(gbc)) {
+ s->heavy_dynamic_range[(!s->channel_mode)-i] =
+ AC3_HEAVY_RANGE(get_bits(gbc, 8));
+ }
+ if (get_bits1(gbc))
+ skip_bits(gbc, 8); //skip language code
+ if (get_bits1(gbc))
+ skip_bits(gbc, 7); //skip audio production information
+ } while (i--);
+
+ skip_bits(gbc, 2); //skip copyright bit and original bitstream bit
+
+ /* skip the timecodes or parse the Alternate Bit Stream Syntax */
+ if (s->bitstream_id != 6) {
+ if (get_bits1(gbc))
+ skip_bits(gbc, 14); //skip timecode1
+ if (get_bits1(gbc))
+ skip_bits(gbc, 14); //skip timecode2
+ } else {
+ if (get_bits1(gbc)) {
+ s->preferred_downmix = get_bits(gbc, 2);
+ s->center_mix_level_ltrt = get_bits(gbc, 3);
+ s->surround_mix_level_ltrt = av_clip(get_bits(gbc, 3), 3, 7);
+ s->center_mix_level = get_bits(gbc, 3);
+ s->surround_mix_level = av_clip(get_bits(gbc, 3), 3, 7);
+ }
+ if (get_bits1(gbc)) {
+ s->dolby_surround_ex_mode = get_bits(gbc, 2);
+ s->dolby_headphone_mode = get_bits(gbc, 2);
+ skip_bits(gbc, 10); // skip adconvtyp (1), xbsi2 (8), encinfo (1)
+ }
+ }
+
+ /* skip additional bitstream info */
+ if (get_bits1(gbc)) {
+ i = get_bits(gbc, 6);
+ do {
+ skip_bits(gbc, 8);
+ } while (i--);
+ }
+
+ return 0;
+}
+
+/**
+ * Common function to parse AC-3 or E-AC-3 frame header
+ */
+static int parse_frame_header(AC3DecodeContext *s)
+{
+ AC3HeaderInfo hdr, *phdr=&hdr;
+ int err;
+
+ err = avpriv_ac3_parse_header2(&s->gbc, &phdr);
+ if (err)
+ return err;
+
+ /* get decoding parameters from header info */
+ s->bit_alloc_params.sr_code = hdr.sr_code;
+ s->bitstream_id = hdr.bitstream_id;
+ s->bitstream_mode = hdr.bitstream_mode;
+ s->channel_mode = hdr.channel_mode;
+ s->lfe_on = hdr.lfe_on;
+ s->bit_alloc_params.sr_shift = hdr.sr_shift;
+ s->sample_rate = hdr.sample_rate;
+ s->bit_rate = hdr.bit_rate;
+ s->channels = hdr.channels;
+ s->fbw_channels = s->channels - s->lfe_on;
+ s->lfe_ch = s->fbw_channels + 1;
+ s->frame_size = hdr.frame_size;
+ s->preferred_downmix = AC3_DMIXMOD_NOTINDICATED;
+ s->center_mix_level = hdr.center_mix_level;
+ s->center_mix_level_ltrt = 4; // -3.0dB
+ s->surround_mix_level = hdr.surround_mix_level;
+ s->surround_mix_level_ltrt = 4; // -3.0dB
+ s->lfe_mix_level_exists = 0;
+ s->num_blocks = hdr.num_blocks;
+ s->frame_type = hdr.frame_type;
+ s->substreamid = hdr.substreamid;
+ s->dolby_surround_mode = hdr.dolby_surround_mode;
+ s->dolby_surround_ex_mode = AC3_DSUREXMOD_NOTINDICATED;
+ s->dolby_headphone_mode = AC3_DHEADPHONMOD_NOTINDICATED;
+
+ if (s->lfe_on) {
+ s->start_freq[s->lfe_ch] = 0;
+ s->end_freq[s->lfe_ch] = 7;
+ s->num_exp_groups[s->lfe_ch] = 2;
+ s->channel_in_cpl[s->lfe_ch] = 0;
+ }
+
+ if (s->bitstream_id <= 10) {
+ s->eac3 = 0;
+ s->snr_offset_strategy = 2;
+ s->block_switch_syntax = 1;
+ s->dither_flag_syntax = 1;
+ s->bit_allocation_syntax = 1;
+ s->fast_gain_syntax = 0;
+ s->first_cpl_leak = 0;
+ s->dba_syntax = 1;
+ s->skip_syntax = 1;
+ memset(s->channel_uses_aht, 0, sizeof(s->channel_uses_aht));
+ return ac3_parse_header(s);
+ } else if (CONFIG_EAC3_DECODER) {
+ s->eac3 = 1;
+ return ff_eac3_parse_header(s);
+ } else {
+ av_log(s->avctx, AV_LOG_ERROR, "E-AC-3 support not compiled in\n");
+ return AVERROR(ENOSYS);
+ }
+}
+
+/**
+ * Set stereo downmixing coefficients based on frame header info.
+ * reference: Section 7.8.2 Downmixing Into Two Channels
+ */
+static void set_downmix_coeffs(AC3DecodeContext *s)
+{
+ int i;
+ float cmix = gain_levels[s-> center_mix_level];
+ float smix = gain_levels[s->surround_mix_level];
+ float norm0, norm1;
+ float downmix_coeffs[AC3_MAX_CHANNELS][2];
+
+ for (i = 0; i < s->fbw_channels; i++) {
+ downmix_coeffs[i][0] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]];
+ downmix_coeffs[i][1] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]];
+ }
+ if (s->channel_mode > 1 && s->channel_mode & 1) {
+ downmix_coeffs[1][0] = downmix_coeffs[1][1] = cmix;
+ }
+ if (s->channel_mode == AC3_CHMODE_2F1R || s->channel_mode == AC3_CHMODE_3F1R) {
+ int nf = s->channel_mode - 2;
+ downmix_coeffs[nf][0] = downmix_coeffs[nf][1] = smix * LEVEL_MINUS_3DB;
+ }
+ if (s->channel_mode == AC3_CHMODE_2F2R || s->channel_mode == AC3_CHMODE_3F2R) {
+ int nf = s->channel_mode - 4;
+ downmix_coeffs[nf][0] = downmix_coeffs[nf+1][1] = smix;
+ }
+
+ /* renormalize */
+ norm0 = norm1 = 0.0;
+ for (i = 0; i < s->fbw_channels; i++) {
+ norm0 += downmix_coeffs[i][0];
+ norm1 += downmix_coeffs[i][1];
+ }
+ norm0 = 1.0f / norm0;
+ norm1 = 1.0f / norm1;
+ for (i = 0; i < s->fbw_channels; i++) {
+ downmix_coeffs[i][0] *= norm0;
+ downmix_coeffs[i][1] *= norm1;
+ }
+
+ if (s->output_mode == AC3_CHMODE_MONO) {
+ for (i = 0; i < s->fbw_channels; i++)
+ downmix_coeffs[i][0] = (downmix_coeffs[i][0] +
+ downmix_coeffs[i][1]) * LEVEL_MINUS_3DB;
+ }
+ for (i = 0; i < s->fbw_channels; i++) {
+ s->downmix_coeffs[i][0] = FIXR12(downmix_coeffs[i][0]);
+ s->downmix_coeffs[i][1] = FIXR12(downmix_coeffs[i][1]);
+ }
+}
+
+/**
+ * Decode the grouped exponents according to exponent strategy.
+ * reference: Section 7.1.3 Exponent Decoding
+ */
+static int decode_exponents(GetBitContext *gbc, int exp_strategy, int ngrps,
+ uint8_t absexp, int8_t *dexps)
+{
+ int i, j, grp, group_size;
+ int dexp[256];
+ int expacc, prevexp;
+
+ /* unpack groups */
+ group_size = exp_strategy + (exp_strategy == EXP_D45);
+ for (grp = 0, i = 0; grp < ngrps; grp++) {
+ expacc = get_bits(gbc, 7);
+ dexp[i++] = ungroup_3_in_7_bits_tab[expacc][0];
+ dexp[i++] = ungroup_3_in_7_bits_tab[expacc][1];
+ dexp[i++] = ungroup_3_in_7_bits_tab[expacc][2];
+ }
+
+ /* convert to absolute exps and expand groups */
+ prevexp = absexp;
+ for (i = 0, j = 0; i < ngrps * 3; i++) {
+ prevexp += dexp[i] - 2;
+ if (prevexp > 24U)
+ return -1;
+ switch (group_size) {
+ case 4: dexps[j++] = prevexp;
+ dexps[j++] = prevexp;
+ case 2: dexps[j++] = prevexp;
+ case 1: dexps[j++] = prevexp;
+ }
+ }
+ return 0;
+}
+
+/**
+ * Generate transform coefficients for each coupled channel in the coupling
+ * range using the coupling coefficients and coupling coordinates.
+ * reference: Section 7.4.3 Coupling Coordinate Format
+ */
+static void calc_transform_coeffs_cpl(AC3DecodeContext *s)
+{
+ int bin, band, ch;
+
+ bin = s->start_freq[CPL_CH];
+ for (band = 0; band < s->num_cpl_bands; band++) {
+ int band_start = bin;
+ int band_end = bin + s->cpl_band_sizes[band];
+ for (ch = 1; ch <= s->fbw_channels; ch++) {
+ if (s->channel_in_cpl[ch]) {
+ int cpl_coord = s->cpl_coords[ch][band] << 5;
+ for (bin = band_start; bin < band_end; bin++) {
+ s->fixed_coeffs[ch][bin] =
+ MULH(s->fixed_coeffs[CPL_CH][bin] * (1 << 4), cpl_coord);
+ }
+ if (ch == 2 && s->phase_flags[band]) {
+ for (bin = band_start; bin < band_end; bin++)
+ s->fixed_coeffs[2][bin] = -s->fixed_coeffs[2][bin];
+ }
+ }
+ }
+ bin = band_end;
+ }
+}
+
+/**
+ * Grouped mantissas for 3-level 5-level and 11-level quantization
+ */
+typedef struct mant_groups {
+ int b1_mant[2];
+ int b2_mant[2];
+ int b4_mant;
+ int b1;
+ int b2;
+ int b4;
+} mant_groups;
+
+/**
+ * Decode the transform coefficients for a particular channel
+ * reference: Section 7.3 Quantization and Decoding of Mantissas
+ */
+static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, mant_groups *m)
+{
+ int start_freq = s->start_freq[ch_index];
+ int end_freq = s->end_freq[ch_index];
+ uint8_t *baps = s->bap[ch_index];
+ int8_t *exps = s->dexps[ch_index];
+ int32_t *coeffs = s->fixed_coeffs[ch_index];
+ int dither = (ch_index == CPL_CH) || s->dither_flag[ch_index];
+ GetBitContext *gbc = &s->gbc;
+ int freq;
+
+ for (freq = start_freq; freq < end_freq; freq++) {
+ int bap = baps[freq];
+ int mantissa;
+ switch (bap) {
+ case 0:
+ /* random noise with approximate range of -0.707 to 0.707 */
+ if (dither)
+ mantissa = (((av_lfg_get(&s->dith_state)>>8)*181)>>8) - 5931008;
+ else
+ mantissa = 0;
+ break;
+ case 1:
+ if (m->b1) {
+ m->b1--;
+ mantissa = m->b1_mant[m->b1];
+ } else {
+ int bits = get_bits(gbc, 5);
+ mantissa = b1_mantissas[bits][0];
+ m->b1_mant[1] = b1_mantissas[bits][1];
+ m->b1_mant[0] = b1_mantissas[bits][2];
+ m->b1 = 2;
+ }
+ break;
+ case 2:
+ if (m->b2) {
+ m->b2--;
+ mantissa = m->b2_mant[m->b2];
+ } else {
+ int bits = get_bits(gbc, 7);
+ mantissa = b2_mantissas[bits][0];
+ m->b2_mant[1] = b2_mantissas[bits][1];
+ m->b2_mant[0] = b2_mantissas[bits][2];
+ m->b2 = 2;
+ }
+ break;
+ case 3:
+ mantissa = b3_mantissas[get_bits(gbc, 3)];
+ break;
+ case 4:
+ if (m->b4) {
+ m->b4 = 0;
+ mantissa = m->b4_mant;
+ } else {
+ int bits = get_bits(gbc, 7);
+ mantissa = b4_mantissas[bits][0];
+ m->b4_mant = b4_mantissas[bits][1];
+ m->b4 = 1;
+ }
+ break;
+ case 5:
+ mantissa = b5_mantissas[get_bits(gbc, 4)];
+ break;
+ default: /* 6 to 15 */
+ /* Shift mantissa and sign-extend it. */
+ if (bap > 15) {
+ av_log(s->avctx, AV_LOG_ERROR, "bap %d is invalid in plain AC-3\n", bap);
+ bap = 15;
+ }
+ mantissa = (unsigned)get_sbits(gbc, quantization_tab[bap]) << (24 - quantization_tab[bap]);
+ break;
+ }
+ coeffs[freq] = mantissa >> exps[freq];
+ }
+}
+
+/**
+ * Remove random dithering from coupling range coefficients with zero-bit
+ * mantissas for coupled channels which do not use dithering.
+ * reference: Section 7.3.4 Dither for Zero Bit Mantissas (bap=0)
+ */
+static void remove_dithering(AC3DecodeContext *s) {
+ int ch, i;
+
+ for (ch = 1; ch <= s->fbw_channels; ch++) {
+ if (!s->dither_flag[ch] && s->channel_in_cpl[ch]) {
+ for (i = s->start_freq[CPL_CH]; i < s->end_freq[CPL_CH]; i++) {
+ if (!s->bap[CPL_CH][i])
+ s->fixed_coeffs[ch][i] = 0;
+ }
+ }
+ }
+}
+
+static void decode_transform_coeffs_ch(AC3DecodeContext *s, int blk, int ch,
+ mant_groups *m)
+{
+ if (!s->channel_uses_aht[ch]) {
+ ac3_decode_transform_coeffs_ch(s, ch, m);
+ } else {
+ /* if AHT is used, mantissas for all blocks are encoded in the first
+ block of the frame. */
+ int bin;
+ if (CONFIG_EAC3_DECODER && !blk)
+ ff_eac3_decode_transform_coeffs_aht_ch(s, ch);
+ for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
+ s->fixed_coeffs[ch][bin] = s->pre_mantissa[ch][bin][blk] >> s->dexps[ch][bin];
+ }
+ }
+}
+
+/**
+ * Decode the transform coefficients.
+ */
+static void decode_transform_coeffs(AC3DecodeContext *s, int blk)
+{
+ int ch, end;
+ int got_cplchan = 0;
+ mant_groups m;
+
+ m.b1 = m.b2 = m.b4 = 0;
+
+ for (ch = 1; ch <= s->channels; ch++) {
+ /* transform coefficients for full-bandwidth channel */
+ decode_transform_coeffs_ch(s, blk, ch, &m);
+ /* transform coefficients for coupling channel come right after the
+ coefficients for the first coupled channel*/
+ if (s->channel_in_cpl[ch]) {
+ if (!got_cplchan) {
+ decode_transform_coeffs_ch(s, blk, CPL_CH, &m);
+ calc_transform_coeffs_cpl(s);
+ got_cplchan = 1;
+ }
+ end = s->end_freq[CPL_CH];
+ } else {
+ end = s->end_freq[ch];
+ }
+ do
+ s->fixed_coeffs[ch][end] = 0;
+ while (++end < 256);
+ }
+
+ /* zero the dithered coefficients for appropriate channels */
+ remove_dithering(s);
+}
+
+/**
+ * Stereo rematrixing.
+ * reference: Section 7.5.4 Rematrixing : Decoding Technique
+ */
+static void do_rematrixing(AC3DecodeContext *s)
+{
+ int bnd, i;
+ int end, bndend;
+
+ end = FFMIN(s->end_freq[1], s->end_freq[2]);
+
+ for (bnd = 0; bnd < s->num_rematrixing_bands; bnd++) {
+ if (s->rematrixing_flags[bnd]) {
+ bndend = FFMIN(end, ff_ac3_rematrix_band_tab[bnd + 1]);
+ for (i = ff_ac3_rematrix_band_tab[bnd]; i < bndend; i++) {
+ int tmp0 = s->fixed_coeffs[1][i];
+ s->fixed_coeffs[1][i] += s->fixed_coeffs[2][i];
+ s->fixed_coeffs[2][i] = tmp0 - s->fixed_coeffs[2][i];
+ }
+ }
+ }
+}
+
+/**
+ * Inverse MDCT Transform.
+ * Convert frequency domain coefficients to time-domain audio samples.
+ * reference: Section 7.9.4 Transformation Equations
+ */
+static inline void do_imdct(AC3DecodeContext *s, int channels)
+{
+ int ch;
+
+ for (ch = 1; ch <= channels; ch++) {
+ if (s->block_switch[ch]) {
+ int i;
+ FFTSample *x = s->tmp_output + 128;
+ for (i = 0; i < 128; i++)
+ x[i] = s->transform_coeffs[ch][2 * i];
+ s->imdct_256.imdct_half(&s->imdct_256, s->tmp_output, x);
+#if USE_FIXED
+ s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1],
+ s->tmp_output, s->window, 128, 8);
+#else
+ s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
+ s->tmp_output, s->window, 128);
+#endif
+ for (i = 0; i < 128; i++)
+ x[i] = s->transform_coeffs[ch][2 * i + 1];
+ s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch - 1], x);
+ } else {
+ s->imdct_512.imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]);
+#if USE_FIXED
+ s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1],
+ s->tmp_output, s->window, 128, 8);
+#else
+ s->fdsp->vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1],
+ s->tmp_output, s->window, 128);
+#endif
+ memcpy(s->delay[ch - 1], s->tmp_output + 128, 128 * sizeof(FFTSample));
+ }
+ }
+}
+
+/**
+ * Upmix delay samples from stereo to original channel layout.
+ */
+static void ac3_upmix_delay(AC3DecodeContext *s)
+{
+ int channel_data_size = sizeof(s->delay[0]);
+ switch (s->channel_mode) {
+ case AC3_CHMODE_DUALMONO:
+ case AC3_CHMODE_STEREO:
+ /* upmix mono to stereo */
+ memcpy(s->delay[1], s->delay[0], channel_data_size);
+ break;
+ case AC3_CHMODE_2F2R:
+ memset(s->delay[3], 0, channel_data_size);
+ case AC3_CHMODE_2F1R:
+ memset(s->delay[2], 0, channel_data_size);
+ break;
+ case AC3_CHMODE_3F2R:
+ memset(s->delay[4], 0, channel_data_size);
+ case AC3_CHMODE_3F1R:
+ memset(s->delay[3], 0, channel_data_size);
+ case AC3_CHMODE_3F:
+ memcpy(s->delay[2], s->delay[1], channel_data_size);
+ memset(s->delay[1], 0, channel_data_size);
+ break;
+ }
+}
+
+/**
+ * Decode band structure for coupling, spectral extension, or enhanced coupling.
+ * The band structure defines how many subbands are in each band. For each
+ * subband in the range, 1 means it is combined with the previous band, and 0
+ * means that it starts a new band.
+ *
+ * @param[in] gbc bit reader context
+ * @param[in] blk block number
+ * @param[in] eac3 flag to indicate E-AC-3
+ * @param[in] ecpl flag to indicate enhanced coupling
+ * @param[in] start_subband subband number for start of range
+ * @param[in] end_subband subband number for end of range
+ * @param[in] default_band_struct default band structure table
+ * @param[out] num_bands number of bands (optionally NULL)
+ * @param[out] band_sizes array containing the number of bins in each band (optionally NULL)
+ * @param[in,out] band_struct current band structure
+ */
+static void decode_band_structure(GetBitContext *gbc, int blk, int eac3,
+ int ecpl, int start_subband, int end_subband,
+ const uint8_t *default_band_struct,
+ int *num_bands, uint8_t *band_sizes,
+ uint8_t *band_struct, int band_struct_size)
+{
+ int subbnd, bnd, n_subbands, n_bands=0;
+ uint8_t bnd_sz[22];
+
+ n_subbands = end_subband - start_subband;
+
+ if (!blk)
+ memcpy(band_struct, default_band_struct, band_struct_size);
+
+ av_assert0(band_struct_size >= start_subband + n_subbands);
+
+ band_struct += start_subband + 1;
+
+ /* decode band structure from bitstream or use default */
+ if (!eac3 || get_bits1(gbc)) {
+ for (subbnd = 0; subbnd < n_subbands - 1; subbnd++) {
+ band_struct[subbnd] = get_bits1(gbc);
+ }
+ }
+
+ /* calculate number of bands and band sizes based on band structure.
+ note that the first 4 subbands in enhanced coupling span only 6 bins
+ instead of 12. */
+ if (num_bands || band_sizes ) {
+ n_bands = n_subbands;
+ bnd_sz[0] = ecpl ? 6 : 12;
+ for (bnd = 0, subbnd = 1; subbnd < n_subbands; subbnd++) {
+ int subbnd_size = (ecpl && subbnd < 4) ? 6 : 12;
+ if (band_struct[subbnd - 1]) {
+ n_bands--;
+ bnd_sz[bnd] += subbnd_size;
+ } else {
+ bnd_sz[++bnd] = subbnd_size;
+ }
+ }
+ }
+
+ /* set optional output params */
+ if (num_bands)
+ *num_bands = n_bands;
+ if (band_sizes)
+ memcpy(band_sizes, bnd_sz, n_bands);
+}
+
+/**
+ * Decode a single audio block from the AC-3 bitstream.
+ */
+static int decode_audio_block(AC3DecodeContext *s, int blk)
+{
+ int fbw_channels = s->fbw_channels;
+ int channel_mode = s->channel_mode;
+ int i, bnd, seg, ch;
+ int different_transforms;
+ int downmix_output;
+ int cpl_in_use;
+ GetBitContext *gbc = &s->gbc;
+ uint8_t bit_alloc_stages[AC3_MAX_CHANNELS] = { 0 };
+
+ /* block switch flags */
+ different_transforms = 0;
+ if (s->block_switch_syntax) {
+ for (ch = 1; ch <= fbw_channels; ch++) {
+ s->block_switch[ch] = get_bits1(gbc);
+ if (ch > 1 && s->block_switch[ch] != s->block_switch[1])
+ different_transforms = 1;
+ }
+ }
+
+ /* dithering flags */
+ if (s->dither_flag_syntax) {
+ for (ch = 1; ch <= fbw_channels; ch++) {
+ s->dither_flag[ch] = get_bits1(gbc);
+ }
+ }
+
+ /* dynamic range */
+ i = !s->channel_mode;
+ do {
+ if (get_bits1(gbc)) {
+ /* Allow asymmetric application of DRC when drc_scale > 1.
+ Amplification of quiet sounds is enhanced */
+ int range_bits = get_bits(gbc, 8);
+ INTFLOAT range = AC3_RANGE(range_bits);
+ if (range_bits <= 127 || s->drc_scale <= 1.0)
+ s->dynamic_range[i] = AC3_DYNAMIC_RANGE(range);
+ else
+ s->dynamic_range[i] = range;
+ } else if (blk == 0) {
+ s->dynamic_range[i] = AC3_DYNAMIC_RANGE1;
+ }
+ } while (i--);
+
+ /* spectral extension strategy */
+ if (s->eac3 && (!blk || get_bits1(gbc))) {
+ s->spx_in_use = get_bits1(gbc);
+ if (s->spx_in_use) {
+ int dst_start_freq, dst_end_freq, src_start_freq,
+ start_subband, end_subband;
+
+ /* determine which channels use spx */
+ if (s->channel_mode == AC3_CHMODE_MONO) {
+ s->channel_uses_spx[1] = 1;
+ } else {
+ for (ch = 1; ch <= fbw_channels; ch++)
+ s->channel_uses_spx[ch] = get_bits1(gbc);
+ }
+
+ /* get the frequency bins of the spx copy region and the spx start
+ and end subbands */
+ dst_start_freq = get_bits(gbc, 2);
+ start_subband = get_bits(gbc, 3) + 2;
+ if (start_subband > 7)
+ start_subband += start_subband - 7;
+ end_subband = get_bits(gbc, 3) + 5;
+#if USE_FIXED
+ s->spx_dst_end_freq = end_freq_inv_tab[end_subband-5];
+#endif
+ if (end_subband > 7)
+ end_subband += end_subband - 7;
+ dst_start_freq = dst_start_freq * 12 + 25;
+ src_start_freq = start_subband * 12 + 25;
+ dst_end_freq = end_subband * 12 + 25;
+
+ /* check validity of spx ranges */
+ if (start_subband >= end_subband) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension "
+ "range (%d >= %d)\n", start_subband, end_subband);
+ return AVERROR_INVALIDDATA;
+ }
+ if (dst_start_freq >= src_start_freq) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension "
+ "copy start bin (%d >= %d)\n", dst_start_freq, src_start_freq);
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->spx_dst_start_freq = dst_start_freq;
+ s->spx_src_start_freq = src_start_freq;
+ if (!USE_FIXED)
+ s->spx_dst_end_freq = dst_end_freq;
+
+ decode_band_structure(gbc, blk, s->eac3, 0,
+ start_subband, end_subband,
+ ff_eac3_default_spx_band_struct,
+ &s->num_spx_bands,
+ s->spx_band_sizes,
+ s->spx_band_struct, sizeof(s->spx_band_struct));
+ }
+ }
+ if (!s->eac3 || !s->spx_in_use) {
+ s->spx_in_use = 0;
+ for (ch = 1; ch <= fbw_channels; ch++) {
+ s->channel_uses_spx[ch] = 0;
+ s->first_spx_coords[ch] = 1;
+ }
+ }
+
+ /* spectral extension coordinates */
+ if (s->spx_in_use) {
+ for (ch = 1; ch <= fbw_channels; ch++) {
+ if (s->channel_uses_spx[ch]) {
+ if (s->first_spx_coords[ch] || get_bits1(gbc)) {
+ INTFLOAT spx_blend;
+ int bin, master_spx_coord;
+
+ s->first_spx_coords[ch] = 0;
+ spx_blend = AC3_SPX_BLEND(get_bits(gbc, 5));
+ master_spx_coord = get_bits(gbc, 2) * 3;
+
+ bin = s->spx_src_start_freq;
+ for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
+ int bandsize = s->spx_band_sizes[bnd];
+ int spx_coord_exp, spx_coord_mant;
+ INTFLOAT nratio, sblend, nblend;
+#if USE_FIXED
+ /* calculate blending factors */
+ int64_t accu = ((bin << 23) + (bandsize << 22))
+ * (int64_t)s->spx_dst_end_freq;
+ nratio = (int)(accu >> 32);
+ nratio -= spx_blend << 18;
+
+ if (nratio < 0) {
+ nblend = 0;
+ sblend = 0x800000;
+ } else if (nratio > 0x7fffff) {
+ nblend = 14529495; // sqrt(3) in FP.23
+ sblend = 0;
+ } else {
+ nblend = fixed_sqrt(nratio, 23);
+ accu = (int64_t)nblend * 1859775393;
+ nblend = (int)((accu + (1<<29)) >> 30);
+ sblend = fixed_sqrt(0x800000 - nratio, 23);
+ }
+#else
+ float spx_coord;
+
+ /* calculate blending factors */
+ nratio = ((float)((bin + (bandsize >> 1))) / s->spx_dst_end_freq) - spx_blend;
+ nratio = av_clipf(nratio, 0.0f, 1.0f);
+ nblend = sqrtf(3.0f * nratio); // noise is scaled by sqrt(3)
+ // to give unity variance
+ sblend = sqrtf(1.0f - nratio);
+#endif
+ bin += bandsize;
+
+ /* decode spx coordinates */
+ spx_coord_exp = get_bits(gbc, 4);
+ spx_coord_mant = get_bits(gbc, 2);
+ if (spx_coord_exp == 15) spx_coord_mant <<= 1;
+ else spx_coord_mant += 4;
+ spx_coord_mant <<= (25 - spx_coord_exp - master_spx_coord);
+
+ /* multiply noise and signal blending factors by spx coordinate */
+#if USE_FIXED
+ accu = (int64_t)nblend * spx_coord_mant;
+ s->spx_noise_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23);
+ accu = (int64_t)sblend * spx_coord_mant;
+ s->spx_signal_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23);
+#else
+ spx_coord = spx_coord_mant * (1.0f / (1 << 23));
+ s->spx_noise_blend [ch][bnd] = nblend * spx_coord;
+ s->spx_signal_blend[ch][bnd] = sblend * spx_coord;
+#endif
+ }
+ }
+ } else {
+ s->first_spx_coords[ch] = 1;
+ }
+ }
+ }
+
+ /* coupling strategy */
+ if (s->eac3 ? s->cpl_strategy_exists[blk] : get_bits1(gbc)) {
+ memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS);
+ if (!s->eac3)
+ s->cpl_in_use[blk] = get_bits1(gbc);
+ if (s->cpl_in_use[blk]) {
+ /* coupling in use */
+ int cpl_start_subband, cpl_end_subband;
+
+ if (channel_mode < AC3_CHMODE_STEREO) {
+ av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* check for enhanced coupling */
+ if (s->eac3 && get_bits1(gbc)) {
+ /* TODO: parse enhanced coupling strategy info */
+ avpriv_request_sample(s->avctx, "Enhanced coupling");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ /* determine which channels are coupled */
+ if (s->eac3 && s->channel_mode == AC3_CHMODE_STEREO) {
+ s->channel_in_cpl[1] = 1;
+ s->channel_in_cpl[2] = 1;
+ } else {
+ for (ch = 1; ch <= fbw_channels; ch++)
+ s->channel_in_cpl[ch] = get_bits1(gbc);
+ }
+
+ /* phase flags in use */
+ if (channel_mode == AC3_CHMODE_STEREO)
+ s->phase_flags_in_use = get_bits1(gbc);
+
+ /* coupling frequency range */
+ cpl_start_subband = get_bits(gbc, 4);
+ cpl_end_subband = s->spx_in_use ? (s->spx_src_start_freq - 37) / 12 :
+ get_bits(gbc, 4) + 3;
+ if (cpl_start_subband >= cpl_end_subband) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d >= %d)\n",
+ cpl_start_subband, cpl_end_subband);
+ return AVERROR_INVALIDDATA;
+ }
+ s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37;
+ s->end_freq[CPL_CH] = cpl_end_subband * 12 + 37;
+
+ decode_band_structure(gbc, blk, s->eac3, 0, cpl_start_subband,
+ cpl_end_subband,
+ ff_eac3_default_cpl_band_struct,
+ &s->num_cpl_bands, s->cpl_band_sizes,
+ s->cpl_band_struct, sizeof(s->cpl_band_struct));
+ } else {
+ /* coupling not in use */
+ for (ch = 1; ch <= fbw_channels; ch++) {
+ s->channel_in_cpl[ch] = 0;
+ s->first_cpl_coords[ch] = 1;
+ }
+ s->first_cpl_leak = s->eac3;
+ s->phase_flags_in_use = 0;
+ }
+ } else if (!s->eac3) {
+ if (!blk) {
+ av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must "
+ "be present in block 0\n");
+ return AVERROR_INVALIDDATA;
+ } else {
+ s->cpl_in_use[blk] = s->cpl_in_use[blk-1];
+ }
+ }
+ cpl_in_use = s->cpl_in_use[blk];
+
+ /* coupling coordinates */
+ if (cpl_in_use) {
+ int cpl_coords_exist = 0;
+
+ for (ch = 1; ch <= fbw_channels; ch++) {
+ if (s->channel_in_cpl[ch]) {
+ if ((s->eac3 && s->first_cpl_coords[ch]) || get_bits1(gbc)) {
+ int master_cpl_coord, cpl_coord_exp, cpl_coord_mant;
+ s->first_cpl_coords[ch] = 0;
+ cpl_coords_exist = 1;
+ master_cpl_coord = 3 * get_bits(gbc, 2);
+ for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
+ cpl_coord_exp = get_bits(gbc, 4);
+ cpl_coord_mant = get_bits(gbc, 4);
+ if (cpl_coord_exp == 15)
+ s->cpl_coords[ch][bnd] = cpl_coord_mant << 22;
+ else
+ s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16) << 21;
+ s->cpl_coords[ch][bnd] >>= (cpl_coord_exp + master_cpl_coord);
+ }
+ } else if (!blk) {
+ av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must "
+ "be present in block 0\n");
+ return AVERROR_INVALIDDATA;
+ }
+ } else {
+ /* channel not in coupling */
+ s->first_cpl_coords[ch] = 1;
+ }
+ }
+ /* phase flags */
+ if (channel_mode == AC3_CHMODE_STEREO && cpl_coords_exist) {
+ for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {
+ s->phase_flags[bnd] = s->phase_flags_in_use? get_bits1(gbc) : 0;
+ }
+ }
+ }
+
+ /* stereo rematrixing strategy and band structure */
+ if (channel_mode == AC3_CHMODE_STEREO) {
+ if ((s->eac3 && !blk) || get_bits1(gbc)) {
+ s->num_rematrixing_bands = 4;
+ if (cpl_in_use && s->start_freq[CPL_CH] <= 61) {
+ s->num_rematrixing_bands -= 1 + (s->start_freq[CPL_CH] == 37);
+ } else if (s->spx_in_use && s->spx_src_start_freq <= 61) {
+ s->num_rematrixing_bands--;
+ }
+ for (bnd = 0; bnd < s->num_rematrixing_bands; bnd++)
+ s->rematrixing_flags[bnd] = get_bits1(gbc);
+ } else if (!blk) {
+ av_log(s->avctx, AV_LOG_WARNING, "Warning: "
+ "new rematrixing strategy not present in block 0\n");
+ s->num_rematrixing_bands = 0;
+ }
+ }
+
+ /* exponent strategies for each channel */
+ for (ch = !cpl_in_use; ch <= s->channels; ch++) {
+ if (!s->eac3)
+ s->exp_strategy[blk][ch] = get_bits(gbc, 2 - (ch == s->lfe_ch));
+ if (s->exp_strategy[blk][ch] != EXP_REUSE)
+ bit_alloc_stages[ch] = 3;
+ }
+
+ /* channel bandwidth */
+ for (ch = 1; ch <= fbw_channels; ch++) {
+ s->start_freq[ch] = 0;
+ if (s->exp_strategy[blk][ch] != EXP_REUSE) {
+ int group_size;
+ int prev = s->end_freq[ch];
+ if (s->channel_in_cpl[ch])
+ s->end_freq[ch] = s->start_freq[CPL_CH];
+ else if (s->channel_uses_spx[ch])
+ s->end_freq[ch] = s->spx_src_start_freq;
+ else {
+ int bandwidth_code = get_bits(gbc, 6);
+ if (bandwidth_code > 60) {
+ av_log(s->avctx, AV_LOG_ERROR, "bandwidth code = %d > 60\n", bandwidth_code);
+ return AVERROR_INVALIDDATA;
+ }
+ s->end_freq[ch] = bandwidth_code * 3 + 73;
+ }
+ group_size = 3 << (s->exp_strategy[blk][ch] - 1);
+ s->num_exp_groups[ch] = (s->end_freq[ch] + group_size-4) / group_size;
+ if (blk > 0 && s->end_freq[ch] != prev)
+ memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS);
+ }
+ }
+ if (cpl_in_use && s->exp_strategy[blk][CPL_CH] != EXP_REUSE) {
+ s->num_exp_groups[CPL_CH] = (s->end_freq[CPL_CH] - s->start_freq[CPL_CH]) /
+ (3 << (s->exp_strategy[blk][CPL_CH] - 1));
+ }
+
+ /* decode exponents for each channel */
+ for (ch = !cpl_in_use; ch <= s->channels; ch++) {
+ if (s->exp_strategy[blk][ch] != EXP_REUSE) {
+ s->dexps[ch][0] = get_bits(gbc, 4) << !ch;
+ if (decode_exponents(gbc, s->exp_strategy[blk][ch],
+ s->num_exp_groups[ch], s->dexps[ch][0],
+ &s->dexps[ch][s->start_freq[ch]+!!ch])) {
+ av_log(s->avctx, AV_LOG_ERROR, "exponent out-of-range\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (ch != CPL_CH && ch != s->lfe_ch)
+ skip_bits(gbc, 2); /* skip gainrng */
+ }
+ }
+
+ /* bit allocation information */
+ if (s->bit_allocation_syntax) {
+ if (get_bits1(gbc)) {
+ s->bit_alloc_params.slow_decay = ff_ac3_slow_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift;
+ s->bit_alloc_params.fast_decay = ff_ac3_fast_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift;
+ s->bit_alloc_params.slow_gain = ff_ac3_slow_gain_tab[get_bits(gbc, 2)];
+ s->bit_alloc_params.db_per_bit = ff_ac3_db_per_bit_tab[get_bits(gbc, 2)];
+ s->bit_alloc_params.floor = ff_ac3_floor_tab[get_bits(gbc, 3)];
+ for (ch = !cpl_in_use; ch <= s->channels; ch++)
+ bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
+ } else if (!blk) {
+ av_log(s->avctx, AV_LOG_ERROR, "new bit allocation info must "
+ "be present in block 0\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ /* signal-to-noise ratio offsets and fast gains (signal-to-mask ratios) */
+ if (!s->eac3 || !blk) {
+ if (s->snr_offset_strategy && get_bits1(gbc)) {
+ int snr = 0;
+ int csnr;
+ csnr = (get_bits(gbc, 6) - 15) << 4;
+ for (i = ch = !cpl_in_use; ch <= s->channels; ch++) {
+ /* snr offset */
+ if (ch == i || s->snr_offset_strategy == 2)
+ snr = (csnr + get_bits(gbc, 4)) << 2;
+ /* run at least last bit allocation stage if snr offset changes */
+ if (blk && s->snr_offset[ch] != snr) {
+ bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 1);
+ }
+ s->snr_offset[ch] = snr;
+
+ /* fast gain (normal AC-3 only) */
+ if (!s->eac3) {
+ int prev = s->fast_gain[ch];
+ s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)];
+ /* run last 2 bit allocation stages if fast gain changes */
+ if (blk && prev != s->fast_gain[ch])
+ bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
+ }
+ }
+ } else if (!s->eac3 && !blk) {
+ av_log(s->avctx, AV_LOG_ERROR, "new snr offsets must be present in block 0\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ /* fast gain (E-AC-3 only) */
+ if (s->fast_gain_syntax && get_bits1(gbc)) {
+ for (ch = !cpl_in_use; ch <= s->channels; ch++) {
+ int prev = s->fast_gain[ch];
+ s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)];
+ /* run last 2 bit allocation stages if fast gain changes */
+ if (blk && prev != s->fast_gain[ch])
+ bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
+ }
+ } else if (s->eac3 && !blk) {
+ for (ch = !cpl_in_use; ch <= s->channels; ch++)
+ s->fast_gain[ch] = ff_ac3_fast_gain_tab[4];
+ }
+
+ /* E-AC-3 to AC-3 converter SNR offset */
+ if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT && get_bits1(gbc)) {
+ skip_bits(gbc, 10); // skip converter snr offset
+ }
+
+ /* coupling leak information */
+ if (cpl_in_use) {
+ if (s->first_cpl_leak || get_bits1(gbc)) {
+ int fl = get_bits(gbc, 3);
+ int sl = get_bits(gbc, 3);
+ /* run last 2 bit allocation stages for coupling channel if
+ coupling leak changes */
+ if (blk && (fl != s->bit_alloc_params.cpl_fast_leak ||
+ sl != s->bit_alloc_params.cpl_slow_leak)) {
+ bit_alloc_stages[CPL_CH] = FFMAX(bit_alloc_stages[CPL_CH], 2);
+ }
+ s->bit_alloc_params.cpl_fast_leak = fl;
+ s->bit_alloc_params.cpl_slow_leak = sl;
+ } else if (!s->eac3 && !blk) {
+ av_log(s->avctx, AV_LOG_ERROR, "new coupling leak info must "
+ "be present in block 0\n");
+ return AVERROR_INVALIDDATA;
+ }
+ s->first_cpl_leak = 0;
+ }
+
+ /* delta bit allocation information */
+ if (s->dba_syntax && get_bits1(gbc)) {
+ /* delta bit allocation exists (strategy) */
+ for (ch = !cpl_in_use; ch <= fbw_channels; ch++) {
+ s->dba_mode[ch] = get_bits(gbc, 2);
+ if (s->dba_mode[ch] == DBA_RESERVED) {
+ av_log(s->avctx, AV_LOG_ERROR, "delta bit allocation strategy reserved\n");
+ return AVERROR_INVALIDDATA;
+ }
+ bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
+ }
+ /* channel delta offset, len and bit allocation */
+ for (ch = !cpl_in_use; ch <= fbw_channels; ch++) {
+ if (s->dba_mode[ch] == DBA_NEW) {
+ s->dba_nsegs[ch] = get_bits(gbc, 3) + 1;
+ for (seg = 0; seg < s->dba_nsegs[ch]; seg++) {
+ s->dba_offsets[ch][seg] = get_bits(gbc, 5);
+ s->dba_lengths[ch][seg] = get_bits(gbc, 4);
+ s->dba_values[ch][seg] = get_bits(gbc, 3);
+ }
+ /* run last 2 bit allocation stages if new dba values */
+ bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);
+ }
+ }
+ } else if (blk == 0) {
+ for (ch = 0; ch <= s->channels; ch++) {
+ s->dba_mode[ch] = DBA_NONE;
+ }
+ }
+
+ /* Bit allocation */
+ for (ch = !cpl_in_use; ch <= s->channels; ch++) {
+ if (bit_alloc_stages[ch] > 2) {
+ /* Exponent mapping into PSD and PSD integration */
+ ff_ac3_bit_alloc_calc_psd(s->dexps[ch],
+ s->start_freq[ch], s->end_freq[ch],
+ s->psd[ch], s->band_psd[ch]);
+ }
+ if (bit_alloc_stages[ch] > 1) {
+ /* Compute excitation function, Compute masking curve, and
+ Apply delta bit allocation */
+ if (ff_ac3_bit_alloc_calc_mask(&s->bit_alloc_params, s->band_psd[ch],
+ s->start_freq[ch], s->end_freq[ch],
+ s->fast_gain[ch], (ch == s->lfe_ch),
+ s->dba_mode[ch], s->dba_nsegs[ch],
+ s->dba_offsets[ch], s->dba_lengths[ch],
+ s->dba_values[ch], s->mask[ch])) {
+ av_log(s->avctx, AV_LOG_ERROR, "error in bit allocation\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ if (bit_alloc_stages[ch] > 0) {
+ /* Compute bit allocation */
+ const uint8_t *bap_tab = s->channel_uses_aht[ch] ?
+ ff_eac3_hebap_tab : ff_ac3_bap_tab;
+ s->ac3dsp.bit_alloc_calc_bap(s->mask[ch], s->psd[ch],
+ s->start_freq[ch], s->end_freq[ch],
+ s->snr_offset[ch],
+ s->bit_alloc_params.floor,
+ bap_tab, s->bap[ch]);
+ }
+ }
+
+ /* unused dummy data */
+ if (s->skip_syntax && get_bits1(gbc)) {
+ int skipl = get_bits(gbc, 9);
+ while (skipl--)
+ skip_bits(gbc, 8);
+ }
+
+ /* unpack the transform coefficients
+ this also uncouples channels if coupling is in use. */
+ decode_transform_coeffs(s, blk);
+
+ /* TODO: generate enhanced coupling coordinates and uncouple */
+
+ /* recover coefficients if rematrixing is in use */
+ if (s->channel_mode == AC3_CHMODE_STEREO)
+ do_rematrixing(s);
+
+ /* apply scaling to coefficients (headroom, dynrng) */
+ for (ch = 1; ch <= s->channels; ch++) {
+ int audio_channel = 0;
+ INTFLOAT gain;
+ if (s->channel_mode == AC3_CHMODE_DUALMONO && ch <= 2)
+ audio_channel = 2-ch;
+ if (s->heavy_compression && s->compression_exists[audio_channel])
+ gain = s->heavy_dynamic_range[audio_channel];
+ else
+ gain = s->dynamic_range[audio_channel];
+
+#if USE_FIXED
+ scale_coefs(s->transform_coeffs[ch], s->fixed_coeffs[ch], gain, 256);
+#else
+ if (s->target_level != 0)
+ gain = gain * s->level_gain[audio_channel];
+ gain *= 1.0 / 4194304.0f;
+ s->fmt_conv.int32_to_float_fmul_scalar(s->transform_coeffs[ch],
+ s->fixed_coeffs[ch], gain, 256);
+#endif
+ }
+
+ /* apply spectral extension to high frequency bins */
+ if (CONFIG_EAC3_DECODER && s->spx_in_use) {
+ ff_eac3_apply_spectral_extension(s);
+ }
+
+ /* downmix and MDCT. order depends on whether block switching is used for
+ any channel in this block. this is because coefficients for the long
+ and short transforms cannot be mixed. */
+ downmix_output = s->channels != s->out_channels &&
+ !((s->output_mode & AC3_OUTPUT_LFEON) &&
+ s->fbw_channels == s->out_channels);
+ if (different_transforms) {
+ /* the delay samples have already been downmixed, so we upmix the delay
+ samples in order to reconstruct all channels before downmixing. */
+ if (s->downmixed) {
+ s->downmixed = 0;
+ ac3_upmix_delay(s);
+ }
+
+ do_imdct(s, s->channels);
+
+ if (downmix_output) {
+#if USE_FIXED
+ ac3_downmix_c_fixed16(s->outptr, s->downmix_coeffs,
+ s->out_channels, s->fbw_channels, 256);
+#else
+ s->ac3dsp.downmix(s->outptr, s->downmix_coeffs,
+ s->out_channels, s->fbw_channels, 256);
+#endif
+ }
+ } else {
+ if (downmix_output) {
+ s->ac3dsp.AC3_RENAME(downmix)(s->xcfptr + 1, s->downmix_coeffs,
+ s->out_channels, s->fbw_channels, 256);
+ }
+
+ if (downmix_output && !s->downmixed) {
+ s->downmixed = 1;
+ s->ac3dsp.AC3_RENAME(downmix)(s->dlyptr, s->downmix_coeffs,
+ s->out_channels, s->fbw_channels, 128);
+ }
+
+ do_imdct(s, s->out_channels);
+ }
+
+ return 0;
+}
+
+/**
+ * Decode a single AC-3 frame.
+ */
+static int ac3_decode_frame(AVCodecContext * avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ AVFrame *frame = data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ AC3DecodeContext *s = avctx->priv_data;
+ int blk, ch, err, ret;
+ const uint8_t *channel_map;
+ const SHORTFLOAT *output[AC3_MAX_CHANNELS];
+ enum AVMatrixEncoding matrix_encoding;
+ AVDownmixInfo *downmix_info;
+
+ /* copy input buffer to decoder context to avoid reading past the end
+ of the buffer, which can be caused by a damaged input stream. */
+ if (buf_size >= 2 && AV_RB16(buf) == 0x770B) {
+ // seems to be byte-swapped AC-3
+ int cnt = FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE) >> 1;
+ s->bdsp.bswap16_buf((uint16_t *) s->input_buffer,
+ (const uint16_t *) buf, cnt);
+ } else
+ memcpy(s->input_buffer, buf, FFMIN(buf_size, AC3_FRAME_BUFFER_SIZE));
+ buf = s->input_buffer;
+ /* initialize the GetBitContext with the start of valid AC-3 Frame */
+ if ((ret = init_get_bits8(&s->gbc, buf, buf_size)) < 0)
+ return ret;
+
+ /* parse the syncinfo */
+ err = parse_frame_header(s);
+
+ if (err) {
+ switch (err) {
+ case AAC_AC3_PARSE_ERROR_SYNC:
+ av_log(avctx, AV_LOG_ERROR, "frame sync error\n");
+ return AVERROR_INVALIDDATA;
+ case AAC_AC3_PARSE_ERROR_BSID:
+ av_log(avctx, AV_LOG_ERROR, "invalid bitstream id\n");
+ break;
+ case AAC_AC3_PARSE_ERROR_SAMPLE_RATE:
+ av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n");
+ break;
+ case AAC_AC3_PARSE_ERROR_FRAME_SIZE:
+ av_log(avctx, AV_LOG_ERROR, "invalid frame size\n");
+ break;
+ case AAC_AC3_PARSE_ERROR_FRAME_TYPE:
+ /* skip frame if CRC is ok. otherwise use error concealment. */
+ /* TODO: add support for substreams and dependent frames */
+ if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT || s->substreamid) {
+ av_log(avctx, AV_LOG_WARNING, "unsupported frame type : "
+ "skipping frame\n");
+ *got_frame_ptr = 0;
+ return buf_size;
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "invalid frame type\n");
+ }
+ break;
+ case AAC_AC3_PARSE_ERROR_CRC:
+ case AAC_AC3_PARSE_ERROR_CHANNEL_CFG:
+ break;
+ default: // Normal AVERROR do not try to recover.
+ *got_frame_ptr = 0;
+ return err;
+ }
+ } else {
+ /* check that reported frame size fits in input buffer */
+ if (s->frame_size > buf_size) {
+ av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
+ err = AAC_AC3_PARSE_ERROR_FRAME_SIZE;
+ } else if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) {
+ /* check for crc mismatch */
+ if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, &buf[2],
+ s->frame_size - 2)) {
+ av_log(avctx, AV_LOG_ERROR, "frame CRC mismatch\n");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ err = AAC_AC3_PARSE_ERROR_CRC;
+ }
+ }
+ }
+
+ /* if frame is ok, set audio parameters */
+ if (!err) {
+ avctx->sample_rate = s->sample_rate;
+ avctx->bit_rate = s->bit_rate;
+ }
+
+ /* channel config */
+ if (!err || (s->channels && s->out_channels != s->channels)) {
+ s->out_channels = s->channels;
+ s->output_mode = s->channel_mode;
+ if (s->lfe_on)
+ s->output_mode |= AC3_OUTPUT_LFEON;
+ if (s->channels > 1 &&
+ avctx->request_channel_layout == AV_CH_LAYOUT_MONO) {
+ s->out_channels = 1;
+ s->output_mode = AC3_CHMODE_MONO;
+ } else if (s->channels > 2 &&
+ avctx->request_channel_layout == AV_CH_LAYOUT_STEREO) {
+ s->out_channels = 2;
+ s->output_mode = AC3_CHMODE_STEREO;
+ }
+
+ s->loro_center_mix_level = gain_levels[s-> center_mix_level];
+ s->loro_surround_mix_level = gain_levels[s->surround_mix_level];
+ s->ltrt_center_mix_level = LEVEL_MINUS_3DB;
+ s->ltrt_surround_mix_level = LEVEL_MINUS_3DB;
+ /* set downmixing coefficients if needed */
+ if (s->channels != s->out_channels && !((s->output_mode & AC3_OUTPUT_LFEON) &&
+ s->fbw_channels == s->out_channels)) {
+ set_downmix_coeffs(s);
+ }
+ } else if (!s->channels) {
+ av_log(avctx, AV_LOG_ERROR, "unable to determine channel mode\n");
+ return AVERROR_INVALIDDATA;
+ }
+ avctx->channels = s->out_channels;
+ avctx->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode & ~AC3_OUTPUT_LFEON];
+ if (s->output_mode & AC3_OUTPUT_LFEON)
+ avctx->channel_layout |= AV_CH_LOW_FREQUENCY;
+
+ /* set audio service type based on bitstream mode for AC-3 */
+ avctx->audio_service_type = s->bitstream_mode;
+ if (s->bitstream_mode == 0x7 && s->channels > 1)
+ avctx->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
+
+ /* get output buffer */
+ frame->nb_samples = s->num_blocks * AC3_BLOCK_SIZE;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+
+ /* decode the audio blocks */
+ channel_map = ff_ac3_dec_channel_map[s->output_mode & ~AC3_OUTPUT_LFEON][s->lfe_on];
+ for (ch = 0; ch < AC3_MAX_CHANNELS; ch++) {
+ output[ch] = s->output[ch];
+ s->outptr[ch] = s->output[ch];
+ }
+ for (ch = 0; ch < s->channels; ch++) {
+ if (ch < s->out_channels)
+ s->outptr[channel_map[ch]] = (SHORTFLOAT *)frame->data[ch];
+ }
+ for (blk = 0; blk < s->num_blocks; blk++) {
+ if (!err && decode_audio_block(s, blk)) {
+ av_log(avctx, AV_LOG_ERROR, "error decoding the audio block\n");
+ err = 1;
+ }
+ if (err)
+ for (ch = 0; ch < s->out_channels; ch++)
+ memcpy(((SHORTFLOAT*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT));
+ for (ch = 0; ch < s->out_channels; ch++)
+ output[ch] = s->outptr[channel_map[ch]];
+ for (ch = 0; ch < s->out_channels; ch++) {
+ if (!ch || channel_map[ch])
+ s->outptr[channel_map[ch]] += AC3_BLOCK_SIZE;
+ }
+ }
+
+ av_frame_set_decode_error_flags(frame, err ? FF_DECODE_ERROR_INVALID_BITSTREAM : 0);
+
+ /* keep last block for error concealment in next frame */
+ for (ch = 0; ch < s->out_channels; ch++)
+ memcpy(s->output[ch], output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT));
+
+ /*
+ * AVMatrixEncoding
+ *
+ * Check whether the input layout is compatible, and make sure we're not
+ * downmixing (else the matrix encoding is no longer applicable).
+ */
+ matrix_encoding = AV_MATRIX_ENCODING_NONE;
+ if (s->channel_mode == AC3_CHMODE_STEREO &&
+ s->channel_mode == (s->output_mode & ~AC3_OUTPUT_LFEON)) {
+ if (s->dolby_surround_mode == AC3_DSURMOD_ON)
+ matrix_encoding = AV_MATRIX_ENCODING_DOLBY;
+ else if (s->dolby_headphone_mode == AC3_DHEADPHONMOD_ON)
+ matrix_encoding = AV_MATRIX_ENCODING_DOLBYHEADPHONE;
+ } else if (s->channel_mode >= AC3_CHMODE_2F2R &&
+ s->channel_mode == (s->output_mode & ~AC3_OUTPUT_LFEON)) {
+ switch (s->dolby_surround_ex_mode) {
+ case AC3_DSUREXMOD_ON: // EX or PLIIx
+ matrix_encoding = AV_MATRIX_ENCODING_DOLBYEX;
+ break;
+ case AC3_DSUREXMOD_PLIIZ:
+ matrix_encoding = AV_MATRIX_ENCODING_DPLIIZ;
+ break;
+ default: // not indicated or off
+ break;
+ }
+ }
+ if ((ret = ff_side_data_update_matrix_encoding(frame, matrix_encoding)) < 0)
+ return ret;
+
+ /* AVDownmixInfo */
+ if ((downmix_info = av_downmix_info_update_side_data(frame))) {
+ switch (s->preferred_downmix) {
+ case AC3_DMIXMOD_LTRT:
+ downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_LTRT;
+ break;
+ case AC3_DMIXMOD_LORO:
+ downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_LORO;
+ break;
+ case AC3_DMIXMOD_DPLII:
+ downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_DPLII;
+ break;
+ default:
+ downmix_info->preferred_downmix_type = AV_DOWNMIX_TYPE_UNKNOWN;
+ break;
+ }
+ downmix_info->center_mix_level = gain_levels[s-> center_mix_level];
+ downmix_info->center_mix_level_ltrt = gain_levels[s-> center_mix_level_ltrt];
+ downmix_info->surround_mix_level = gain_levels[s-> surround_mix_level];
+ downmix_info->surround_mix_level_ltrt = gain_levels[s->surround_mix_level_ltrt];
+ if (s->lfe_mix_level_exists)
+ downmix_info->lfe_mix_level = gain_levels_lfe[s->lfe_mix_level];
+ else
+ downmix_info->lfe_mix_level = 0.0; // -inf dB
+ } else
+ return AVERROR(ENOMEM);
+
+ *got_frame_ptr = 1;
+
+ return FFMIN(buf_size, s->frame_size);
+}
+
+/**
+ * Uninitialize the AC-3 decoder.
+ */
+static av_cold int ac3_decode_end(AVCodecContext *avctx)
+{
+ AC3DecodeContext *s = avctx->priv_data;
+ ff_mdct_end(&s->imdct_512);
+ ff_mdct_end(&s->imdct_256);
+ av_freep(&s->fdsp);
+
+ return 0;
+}
+
+#define OFFSET(x) offsetof(AC3DecodeContext, x)
+#define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM)
diff --git a/ffmpeg-2-8-12/libavcodec/ac3dec.h b/ffmpeg-2-8-12/libavcodec/ac3dec.h
new file mode 100644
index 0000000..fe3cf86
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/ac3dec.h
@@ -0,0 +1,263 @@
+/*
+ * Common code between the AC-3 and E-AC-3 decoders
+ * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec at gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Common code between the AC-3 and E-AC-3 decoders.
+ *
+ * Summary of MDCT Coefficient Grouping:
+ * The individual MDCT coefficient indices are often referred to in the
+ * (E-)AC-3 specification as frequency bins. These bins are grouped together
+ * into subbands of 12 coefficients each. The subbands are grouped together
+ * into bands as defined in the bitstream by the band structures, which
+ * determine the number of bands and the size of each band. The full spectrum
+ * of 256 frequency bins is divided into 1 DC bin + 21 subbands = 253 bins.
+ * This system of grouping coefficients is used for channel bandwidth, stereo
+ * rematrixing, channel coupling, enhanced coupling, and spectral extension.
+ *
+ * +-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-+
+ * |1| |12| | [12|12|12|12] | | | | | | | | | | | | |3|
+ * +-+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+-+
+ * ~~~ ~~~~ ~~~~~~~~~~~~~ ~~~
+ * | | | |
+ * | | | 3 unused frequency bins--+
+ * | | |
+ * | | +--1 band containing 4 subbands
+ * | |
+ * | +--1 subband of 12 frequency bins
+ * |
+ * +--DC frequency bin
+ */
+
+#ifndef AVCODEC_AC3DEC_H
+#define AVCODEC_AC3DEC_H
+
+#include "libavutil/float_dsp.h"
+#include "libavutil/fixed_dsp.h"
+#include "libavutil/lfg.h"
+#include "ac3.h"
+#include "ac3dsp.h"
+#include "bswapdsp.h"
+#include "get_bits.h"
+#include "fft.h"
+#include "fmtconvert.h"
+
+#define AC3_OUTPUT_LFEON 8
+
+#define SPX_MAX_BANDS 17
+
+/** Large enough for maximum possible frame size when the specification limit is ignored */
+#define AC3_FRAME_BUFFER_SIZE 32768
+
+typedef struct AC3DecodeContext {
+ AVClass *class; ///< class for AVOptions
+ AVCodecContext *avctx; ///< parent context
+ GetBitContext gbc; ///< bitstream reader
+
+///@name Bit stream information
+///@{
+ int frame_type; ///< frame type (strmtyp)
+ int substreamid; ///< substream identification
+ int frame_size; ///< current frame size, in bytes
+ int bit_rate; ///< stream bit rate, in bits-per-second
+ int sample_rate; ///< sample frequency, in Hz
+ int num_blocks; ///< number of audio blocks
+ int bitstream_id; ///< bitstream id (bsid)
+ int bitstream_mode; ///< bitstream mode (bsmod)
+ int channel_mode; ///< channel mode (acmod)
+ int lfe_on; ///< lfe channel in use
+ int dialog_normalization[2]; ///< dialog level in dBFS (dialnorm)
+ int compression_exists[2]; ///< compression field is valid for frame (compre)
+ int compression_gain[2]; ///< gain to apply for heavy compression (compr)
+ int channel_map; ///< custom channel map
+ int preferred_downmix; ///< Preferred 2-channel downmix mode (dmixmod)
+ int center_mix_level; ///< Center mix level index
+ int center_mix_level_ltrt; ///< Center mix level index for Lt/Rt (ltrtcmixlev)
+ int surround_mix_level; ///< Surround mix level index
+ int surround_mix_level_ltrt; ///< Surround mix level index for Lt/Rt (ltrtsurmixlev)
+ int lfe_mix_level_exists; ///< indicates if lfemixlevcod is specified (lfemixlevcode)
+ int lfe_mix_level; ///< LFE mix level index (lfemixlevcod)
+ int eac3; ///< indicates if current frame is E-AC-3
+ int dolby_surround_mode; ///< dolby surround mode (dsurmod)
+ int dolby_surround_ex_mode; ///< dolby surround ex mode (dsurexmod)
+ int dolby_headphone_mode; ///< dolby headphone mode (dheadphonmod)
+///@}
+
+ int preferred_stereo_downmix;
+ float ltrt_center_mix_level;
+ float ltrt_surround_mix_level;
+ float loro_center_mix_level;
+ float loro_surround_mix_level;
+ int target_level; ///< target level in dBFS
+ float level_gain[2];
+
+///@name Frame syntax parameters
+ int snr_offset_strategy; ///< SNR offset strategy (snroffststr)
+ int block_switch_syntax; ///< block switch syntax enabled (blkswe)
+ int dither_flag_syntax; ///< dither flag syntax enabled (dithflage)
+ int bit_allocation_syntax; ///< bit allocation model syntax enabled (bamode)
+ int fast_gain_syntax; ///< fast gain codes enabled (frmfgaincode)
+ int dba_syntax; ///< delta bit allocation syntax enabled (dbaflde)
+ int skip_syntax; ///< skip field syntax enabled (skipflde)
+ ///@}
+
+///@name Standard coupling
+ int cpl_in_use[AC3_MAX_BLOCKS]; ///< coupling in use (cplinu)
+ int cpl_strategy_exists[AC3_MAX_BLOCKS];///< coupling strategy exists (cplstre)
+ int channel_in_cpl[AC3_MAX_CHANNELS]; ///< channel in coupling (chincpl)
+ int phase_flags_in_use; ///< phase flags in use (phsflginu)
+ int phase_flags[AC3_MAX_CPL_BANDS]; ///< phase flags (phsflg)
+ int num_cpl_bands; ///< number of coupling bands (ncplbnd)
+ uint8_t cpl_band_struct[AC3_MAX_CPL_BANDS];
+ uint8_t cpl_band_sizes[AC3_MAX_CPL_BANDS]; ///< number of coeffs in each coupling band
+ int firstchincpl; ///< first channel in coupling
+ int first_cpl_coords[AC3_MAX_CHANNELS]; ///< first coupling coordinates states (firstcplcos)
+ int cpl_coords[AC3_MAX_CHANNELS][AC3_MAX_CPL_BANDS]; ///< coupling coordinates (cplco)
+///@}
+
+///@name Spectral extension
+///@{
+ int spx_in_use; ///< spectral extension in use (spxinu)
+ uint8_t channel_uses_spx[AC3_MAX_CHANNELS]; ///< channel uses spectral extension (chinspx)
+ int8_t spx_atten_code[AC3_MAX_CHANNELS]; ///< spx attenuation code (spxattencod)
+ int spx_src_start_freq; ///< spx start frequency bin
+ int spx_dst_end_freq; ///< spx end frequency bin
+ int spx_dst_start_freq; ///< spx starting frequency bin for copying (copystartmant)
+ ///< the copy region ends at the start of the spx region.
+ int num_spx_bands; ///< number of spx bands (nspxbnds)
+ uint8_t spx_band_struct[SPX_MAX_BANDS];
+ uint8_t spx_band_sizes[SPX_MAX_BANDS]; ///< number of bins in each spx band
+ uint8_t first_spx_coords[AC3_MAX_CHANNELS]; ///< first spx coordinates states (firstspxcos)
+ INTFLOAT spx_noise_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS]; ///< spx noise blending factor (nblendfact)
+ INTFLOAT spx_signal_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS];///< spx signal blending factor (sblendfact)
+///@}
+
+///@name Adaptive hybrid transform
+ int channel_uses_aht[AC3_MAX_CHANNELS]; ///< channel AHT in use (chahtinu)
+ int pre_mantissa[AC3_MAX_CHANNELS][AC3_MAX_COEFS][AC3_MAX_BLOCKS]; ///< pre-IDCT mantissas
+///@}
+
+///@name Channel
+ int fbw_channels; ///< number of full-bandwidth channels
+ int channels; ///< number of total channels
+ int lfe_ch; ///< index of LFE channel
+ SHORTFLOAT downmix_coeffs[AC3_MAX_CHANNELS][2]; ///< stereo downmix coefficients
+ int downmixed; ///< indicates if coeffs are currently downmixed
+ int output_mode; ///< output channel configuration
+ int out_channels; ///< number of output channels
+///@}
+
+///@name Dynamic range
+ INTFLOAT dynamic_range[2]; ///< dynamic range
+ INTFLOAT drc_scale; ///< percentage of dynamic range compression to be applied
+ int heavy_compression; ///< apply heavy compression
+ INTFLOAT heavy_dynamic_range[2]; ///< heavy dynamic range compression
+///@}
+
+///@name Bandwidth
+ int start_freq[AC3_MAX_CHANNELS]; ///< start frequency bin (strtmant)
+ int end_freq[AC3_MAX_CHANNELS]; ///< end frequency bin (endmant)
+///@}
+
+///@name Rematrixing
+ int num_rematrixing_bands; ///< number of rematrixing bands (nrematbnd)
+ int rematrixing_flags[4]; ///< rematrixing flags (rematflg)
+///@}
+
+///@name Exponents
+ int num_exp_groups[AC3_MAX_CHANNELS]; ///< Number of exponent groups (nexpgrp)
+ int8_t dexps[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< decoded exponents
+ int exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS]; ///< exponent strategies (expstr)
+///@}
+
+///@name Bit allocation
+ AC3BitAllocParameters bit_alloc_params; ///< bit allocation parameters
+ int first_cpl_leak; ///< first coupling leak state (firstcplleak)
+ int snr_offset[AC3_MAX_CHANNELS]; ///< signal-to-noise ratio offsets (snroffst)
+ int fast_gain[AC3_MAX_CHANNELS]; ///< fast gain values/SMR's (fgain)
+ uint8_t bap[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< bit allocation pointers
+ int16_t psd[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< scaled exponents
+ int16_t band_psd[AC3_MAX_CHANNELS][AC3_CRITICAL_BANDS]; ///< interpolated exponents
+ int16_t mask[AC3_MAX_CHANNELS][AC3_CRITICAL_BANDS]; ///< masking curve values
+ int dba_mode[AC3_MAX_CHANNELS]; ///< delta bit allocation mode
+ int dba_nsegs[AC3_MAX_CHANNELS]; ///< number of delta segments
+ uint8_t dba_offsets[AC3_MAX_CHANNELS][8]; ///< delta segment offsets
+ uint8_t dba_lengths[AC3_MAX_CHANNELS][8]; ///< delta segment lengths
+ uint8_t dba_values[AC3_MAX_CHANNELS][8]; ///< delta values for each segment
+///@}
+
+///@name Zero-mantissa dithering
+ int dither_flag[AC3_MAX_CHANNELS]; ///< dither flags (dithflg)
+ AVLFG dith_state; ///< for dither generation
+///@}
+
+///@name IMDCT
+ int block_switch[AC3_MAX_CHANNELS]; ///< block switch flags (blksw)
+ FFTContext imdct_512; ///< for 512 sample IMDCT
+ FFTContext imdct_256; ///< for 256 sample IMDCT
+///@}
+
+///@name Optimization
+ BswapDSPContext bdsp;
+#if USE_FIXED
+ AVFixedDSPContext *fdsp;
+#else
+ AVFloatDSPContext *fdsp;
+#endif
+ AC3DSPContext ac3dsp;
+ FmtConvertContext fmt_conv; ///< optimized conversion functions
+///@}
+
+ SHORTFLOAT *outptr[AC3_MAX_CHANNELS];
+ INTFLOAT *xcfptr[AC3_MAX_CHANNELS];
+ INTFLOAT *dlyptr[AC3_MAX_CHANNELS];
+
+///@name Aligned arrays
+ DECLARE_ALIGNED(16, int, fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< fixed-point transform coefficients
+ DECLARE_ALIGNED(32, INTFLOAT, transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< transform coefficients
+ DECLARE_ALIGNED(32, INTFLOAT, delay)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< delay - added to the next block
+ DECLARE_ALIGNED(32, INTFLOAT, window)[AC3_BLOCK_SIZE]; ///< window coefficients
+ DECLARE_ALIGNED(32, INTFLOAT, tmp_output)[AC3_BLOCK_SIZE]; ///< temporary storage for output before windowing
+ DECLARE_ALIGNED(32, SHORTFLOAT, output)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< output after imdct transform and windowing
+ DECLARE_ALIGNED(32, uint8_t, input_buffer)[AC3_FRAME_BUFFER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; ///< temp buffer to prevent overread
+///@}
+} AC3DecodeContext;
+
+/**
+ * Parse the E-AC-3 frame header.
+ * This parses both the bit stream info and audio frame header.
+ */
+static int ff_eac3_parse_header(AC3DecodeContext *s);
+
+/**
+ * Decode mantissas in a single channel for the entire frame.
+ * This is used when AHT mode is enabled.
+ */
+static void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch);
+
+/**
+ * Apply spectral extension to each channel by copying lower frequency
+ * coefficients to higher frequency bins and applying side information to
+ * approximate the original high frequency signal.
+ */
+static void ff_eac3_apply_spectral_extension(AC3DecodeContext *s);
+
+#endif /* AVCODEC_AC3DEC_H */
diff --git a/ffmpeg-2-8-11/libavcodec/ac3dec_data.c b/ffmpeg-2-8-12/libavcodec/ac3dec_data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3dec_data.c
rename to ffmpeg-2-8-12/libavcodec/ac3dec_data.c
diff --git a/ffmpeg-2-8-11/libavcodec/ac3dec_data.h b/ffmpeg-2-8-12/libavcodec/ac3dec_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3dec_data.h
rename to ffmpeg-2-8-12/libavcodec/ac3dec_data.h
diff --git a/ffmpeg-2-8-12/libavcodec/ac3dec_fixed.c b/ffmpeg-2-8-12/libavcodec/ac3dec_fixed.c
new file mode 100644
index 0000000..d6dee6c
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/ac3dec_fixed.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2012
+ * MIPS Technologies, Inc., California.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Author: Stanislav Ocovaj (socovaj at mips.com)
+ *
+ * AC3 fixed-point decoder for MIPS platforms
+ *
+ * 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
+ */
+
+#define FFT_FLOAT 0
+#define USE_FIXED 1
+#define FFT_FIXED_32 1
+#include "ac3dec.h"
+
+
+static const int end_freq_inv_tab[8] =
+{
+ 50529027, 44278013, 39403370, 32292987, 27356480, 23729101, 20951060, 18755316
+};
+
+static void scale_coefs (
+ int32_t *dst,
+ const int32_t *src,
+ int dynrng,
+ int len)
+{
+ int i, shift, round;
+ int16_t mul;
+ int temp, temp1, temp2, temp3, temp4, temp5, temp6, temp7;
+
+ mul = (dynrng & 0x1f) + 0x20;
+ shift = 4 - (sign_extend(dynrng, 9) >> 5);
+ if (shift > 0 ) {
+ round = 1 << (shift-1);
+ for (i=0; i<len; i+=8) {
+
+ temp = src[i] * mul;
+ temp1 = src[i+1] * mul;
+ temp = temp + round;
+ temp2 = src[i+2] * mul;
+
+ temp1 = temp1 + round;
+ dst[i] = temp >> shift;
+ temp3 = src[i+3] * mul;
+ temp2 = temp2 + round;
+
+ dst[i+1] = temp1 >> shift;
+ temp4 = src[i + 4] * mul;
+ temp3 = temp3 + round;
+ dst[i+2] = temp2 >> shift;
+
+ temp5 = src[i+5] * mul;
+ temp4 = temp4 + round;
+ dst[i+3] = temp3 >> shift;
+ temp6 = src[i+6] * mul;
+
+ dst[i+4] = temp4 >> shift;
+ temp5 = temp5 + round;
+ temp7 = src[i+7] * mul;
+ temp6 = temp6 + round;
+
+ dst[i+5] = temp5 >> shift;
+ temp7 = temp7 + round;
+ dst[i+6] = temp6 >> shift;
+ dst[i+7] = temp7 >> shift;
+
+ }
+ } else {
+ shift = -shift;
+ for (i=0; i<len; i+=8) {
+
+ temp = src[i] * mul;
+ temp1 = src[i+1] * mul;
+ temp2 = src[i+2] * mul;
+
+ dst[i] = temp << shift;
+ temp3 = src[i+3] * mul;
+
+ dst[i+1] = temp1 << shift;
+ temp4 = src[i + 4] * mul;
+ dst[i+2] = temp2 << shift;
+
+ temp5 = src[i+5] * mul;
+ dst[i+3] = temp3 << shift;
+ temp6 = src[i+6] * mul;
+
+ dst[i+4] = temp4 << shift;
+ temp7 = src[i+7] * mul;
+
+ dst[i+5] = temp5 << shift;
+ dst[i+6] = temp6 << shift;
+ dst[i+7] = temp7 << shift;
+
+ }
+ }
+}
+
+/**
+ * Downmix samples from original signal to stereo or mono (this is for 16-bit samples
+ * and fixed point decoder - original (for 32-bit samples) is in ac3dsp.c).
+ */
+static void ac3_downmix_c_fixed16(int16_t **samples, int16_t (*matrix)[2],
+ int out_ch, int in_ch, int len)
+{
+ int i, j;
+ int v0, v1;
+ if (out_ch == 2) {
+ for (i = 0; i < len; i++) {
+ v0 = v1 = 0;
+ for (j = 0; j < in_ch; j++) {
+ v0 += samples[j][i] * matrix[j][0];
+ v1 += samples[j][i] * matrix[j][1];
+ }
+ samples[0][i] = (v0+2048)>>12;
+ samples[1][i] = (v1+2048)>>12;
+ }
+ } else if (out_ch == 1) {
+ for (i = 0; i < len; i++) {
+ v0 = 0;
+ for (j = 0; j < in_ch; j++)
+ v0 += samples[j][i] * matrix[j][0];
+ samples[0][i] = (v0+2048)>>12;
+ }
+ }
+}
+
+#include "eac3dec.c"
+#include "ac3dec.c"
+
+static const AVOption options[] = {
+ { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 6.0, PAR },
+ { "heavy_compr", "heavy dynamic range compression enabled", OFFSET(heavy_compression), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, PAR },
+ { NULL},
+};
+
+static const AVClass ac3_decoder_class = {
+ .class_name = "Fixed-Point AC-3 Decoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_ac3_fixed_decoder = {
+ .name = "ac3_fixed",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_AC3,
+ .priv_data_size = sizeof (AC3DecodeContext),
+ .init = ac3_decode_init,
+ .close = ac3_decode_end,
+ .decode = ac3_decode_frame,
+ .capabilities = 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,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/ac3dec_float.c b/ffmpeg-2-8-12/libavcodec/ac3dec_float.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3dec_float.c
rename to ffmpeg-2-8-12/libavcodec/ac3dec_float.c
diff --git a/ffmpeg-2-8-11/libavcodec/ac3dsp.c b/ffmpeg-2-8-12/libavcodec/ac3dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3dsp.c
rename to ffmpeg-2-8-12/libavcodec/ac3dsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/ac3dsp.h b/ffmpeg-2-8-12/libavcodec/ac3dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3dsp.h
rename to ffmpeg-2-8-12/libavcodec/ac3dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/ac3enc.c b/ffmpeg-2-8-12/libavcodec/ac3enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3enc.c
rename to ffmpeg-2-8-12/libavcodec/ac3enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/ac3enc.h b/ffmpeg-2-8-12/libavcodec/ac3enc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3enc.h
rename to ffmpeg-2-8-12/libavcodec/ac3enc.h
diff --git a/ffmpeg-2-8-11/libavcodec/ac3enc_fixed.c b/ffmpeg-2-8-12/libavcodec/ac3enc_fixed.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3enc_fixed.c
rename to ffmpeg-2-8-12/libavcodec/ac3enc_fixed.c
diff --git a/ffmpeg-2-8-11/libavcodec/ac3enc_float.c b/ffmpeg-2-8-12/libavcodec/ac3enc_float.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3enc_float.c
rename to ffmpeg-2-8-12/libavcodec/ac3enc_float.c
diff --git a/ffmpeg-2-8-11/libavcodec/ac3enc_opts_template.c b/ffmpeg-2-8-12/libavcodec/ac3enc_opts_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3enc_opts_template.c
rename to ffmpeg-2-8-12/libavcodec/ac3enc_opts_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/ac3enc_template.c b/ffmpeg-2-8-12/libavcodec/ac3enc_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3enc_template.c
rename to ffmpeg-2-8-12/libavcodec/ac3enc_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/ac3tab.c b/ffmpeg-2-8-12/libavcodec/ac3tab.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3tab.c
rename to ffmpeg-2-8-12/libavcodec/ac3tab.c
diff --git a/ffmpeg-2-8-11/libavcodec/ac3tab.h b/ffmpeg-2-8-12/libavcodec/ac3tab.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ac3tab.h
rename to ffmpeg-2-8-12/libavcodec/ac3tab.h
diff --git a/ffmpeg-2-8-11/libavcodec/acelp_filters.c b/ffmpeg-2-8-12/libavcodec/acelp_filters.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/acelp_filters.c
rename to ffmpeg-2-8-12/libavcodec/acelp_filters.c
diff --git a/ffmpeg-2-8-11/libavcodec/acelp_filters.h b/ffmpeg-2-8-12/libavcodec/acelp_filters.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/acelp_filters.h
rename to ffmpeg-2-8-12/libavcodec/acelp_filters.h
diff --git a/ffmpeg-2-8-12/libavcodec/acelp_pitch_delay.c b/ffmpeg-2-8-12/libavcodec/acelp_pitch_delay.c
new file mode 100644
index 0000000..02a60e4
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/acelp_pitch_delay.c
@@ -0,0 +1,190 @@
+/*
+ * gain code, gain pitch and pitch delay decoding
+ *
+ * Copyright (c) 2008 Vladimir Voroshilov
+ *
+ * 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/float_dsp.h"
+#include "libavutil/libm.h"
+#include "libavutil/mathematics.h"
+#include "avcodec.h"
+#include "acelp_pitch_delay.h"
+#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,
+ int log2_ma_pred_order,
+ int erasure)
+{
+ int i;
+ int avg_gain=quant_energy[(1 << log2_ma_pred_order) - 1]; // (5.10)
+
+ for(i=(1 << log2_ma_pred_order) - 1; i>0; i--)
+ {
+ avg_gain += quant_energy[i-1];
+ quant_energy[i] = quant_energy[i-1];
+ }
+
+ if(erasure)
+ quant_energy[0] = FFMAX(avg_gain >> log2_ma_pred_order, -10240) - 4096; // -10 and -4 in (5.10)
+ else
+ quant_energy[0] = (6165 * ((ff_log2_q15(gain_corr_factor) >> 2) - (13 << 13))) >> 13;
+}
+
+int16_t ff_acelp_decode_gain_code(
+ AudioDSPContext *adsp,
+ int gain_corr_factor,
+ const int16_t* fc_v,
+ int mr_energy,
+ const int16_t* quant_energy,
+ const int16_t* ma_prediction_coeff,
+ int subframe_size,
+ int ma_pred_order)
+{
+ int i;
+
+ mr_energy <<= 10;
+
+ for(i=0; i<ma_pred_order; i++)
+ mr_energy += quant_energy[i] * ma_prediction_coeff[i];
+
+#ifdef G729_BITEXACT
+ mr_energy += (((-6165LL * ff_log2(dsp->scalarproduct_int16(fc_v, fc_v, subframe_size, 0))) >> 3) & ~0x3ff);
+
+ mr_energy = (5439 * (mr_energy >> 15)) >> 8; // (0.15) = (0.15) * (7.23)
+
+ return bidir_sal(
+ ((ff_exp2(mr_energy & 0x7fff) + 16) >> 5) * (gain_corr_factor >> 1),
+ (mr_energy >> 15) - 25
+ );
+#else
+ mr_energy = gain_corr_factor * exp(M_LN10 / (20 << 23) * mr_energy) /
+ sqrt(adsp->scalarproduct_int16(fc_v, fc_v, subframe_size));
+ return mr_energy >> 12;
+#endif
+}
+
+float ff_amr_set_fixed_gain(float fixed_gain_factor, float fixed_mean_energy,
+ float *prediction_error, float energy_mean,
+ const float *pred_table)
+{
+ // Equations 66-69:
+ // ^g_c = ^gamma_gc * 100.05 (predicted dB + mean dB - dB of fixed vector)
+ // Note 10^(0.05 * -10log(average x2)) = 1/sqrt((average x2)).
+ float val = fixed_gain_factor *
+ exp2f(M_LOG2_10 * 0.05 *
+ (avpriv_scalarproduct_float_c(pred_table, prediction_error, 4) +
+ energy_mean)) /
+ sqrtf(fixed_mean_energy ? fixed_mean_energy : 1.0);
+
+ // update quantified prediction error energy history
+ memmove(&prediction_error[0], &prediction_error[1],
+ 3 * sizeof(prediction_error[0]));
+ prediction_error[3] = 20.0 * log10f(fixed_gain_factor);
+
+ return val;
+}
+
+void ff_decode_pitch_lag(int *lag_int, int *lag_frac, int pitch_index,
+ const int prev_lag_int, const int subframe,
+ int third_as_first, int resolution)
+{
+ /* Note n * 10923 >> 15 is floor(x/3) for 0 <= n <= 32767 */
+ if (subframe == 0 || (subframe == 2 && third_as_first)) {
+
+ if (pitch_index < 197)
+ pitch_index += 59;
+ else
+ pitch_index = 3 * pitch_index - 335;
+
+ } else {
+ if (resolution == 4) {
+ int search_range_min = av_clip(prev_lag_int - 5, PITCH_DELAY_MIN,
+ PITCH_DELAY_MAX - 9);
+
+ // decoding with 4-bit resolution
+ if (pitch_index < 4) {
+ // integer only precision for [search_range_min, search_range_min+3]
+ pitch_index = 3 * (pitch_index + search_range_min) + 1;
+ } else if (pitch_index < 12) {
+ // 1/3 fractional precision for [search_range_min+3 1/3, search_range_min+5 2/3]
+ pitch_index += 3 * search_range_min + 7;
+ } else {
+ // integer only precision for [search_range_min+6, search_range_min+9]
+ pitch_index = 3 * (pitch_index + search_range_min - 6) + 1;
+ }
+ } else {
+ // decoding with 5 or 6 bit resolution, 1/3 fractional precision
+ pitch_index--;
+
+ if (resolution == 5) {
+ pitch_index += 3 * av_clip(prev_lag_int - 10, PITCH_DELAY_MIN,
+ PITCH_DELAY_MAX - 19);
+ } else
+ pitch_index += 3 * av_clip(prev_lag_int - 5, PITCH_DELAY_MIN,
+ PITCH_DELAY_MAX - 9);
+ }
+ }
+ *lag_int = pitch_index * 10923 >> 15;
+ *lag_frac = pitch_index - 3 * *lag_int - 1;
+}
diff --git a/ffmpeg-2-8-11/libavcodec/acelp_pitch_delay.h b/ffmpeg-2-8-12/libavcodec/acelp_pitch_delay.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/acelp_pitch_delay.h
rename to ffmpeg-2-8-12/libavcodec/acelp_pitch_delay.h
diff --git a/ffmpeg-2-8-11/libavcodec/acelp_vectors.c b/ffmpeg-2-8-12/libavcodec/acelp_vectors.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/acelp_vectors.c
rename to ffmpeg-2-8-12/libavcodec/acelp_vectors.c
diff --git a/ffmpeg-2-8-11/libavcodec/acelp_vectors.h b/ffmpeg-2-8-12/libavcodec/acelp_vectors.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/acelp_vectors.h
rename to ffmpeg-2-8-12/libavcodec/acelp_vectors.h
diff --git a/ffmpeg-2-8-11/libavcodec/adpcm.c b/ffmpeg-2-8-12/libavcodec/adpcm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/adpcm.c
rename to ffmpeg-2-8-12/libavcodec/adpcm.c
diff --git a/ffmpeg-2-8-11/libavcodec/adpcm.h b/ffmpeg-2-8-12/libavcodec/adpcm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/adpcm.h
rename to ffmpeg-2-8-12/libavcodec/adpcm.h
diff --git a/ffmpeg-2-8-11/libavcodec/adpcm_data.c b/ffmpeg-2-8-12/libavcodec/adpcm_data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/adpcm_data.c
rename to ffmpeg-2-8-12/libavcodec/adpcm_data.c
diff --git a/ffmpeg-2-8-11/libavcodec/adpcm_data.h b/ffmpeg-2-8-12/libavcodec/adpcm_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/adpcm_data.h
rename to ffmpeg-2-8-12/libavcodec/adpcm_data.h
diff --git a/ffmpeg-2-8-11/libavcodec/adpcmenc.c b/ffmpeg-2-8-12/libavcodec/adpcmenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/adpcmenc.c
rename to ffmpeg-2-8-12/libavcodec/adpcmenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/adx.c b/ffmpeg-2-8-12/libavcodec/adx.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/adx.c
rename to ffmpeg-2-8-12/libavcodec/adx.c
diff --git a/ffmpeg-2-8-11/libavcodec/adx.h b/ffmpeg-2-8-12/libavcodec/adx.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/adx.h
rename to ffmpeg-2-8-12/libavcodec/adx.h
diff --git a/ffmpeg-2-8-11/libavcodec/adx_parser.c b/ffmpeg-2-8-12/libavcodec/adx_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/adx_parser.c
rename to ffmpeg-2-8-12/libavcodec/adx_parser.c
diff --git a/ffmpeg-2-8-12/libavcodec/adxdec.c b/ffmpeg-2-8-12/libavcodec/adxdec.c
new file mode 100644
index 0000000..178ea99
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/adxdec.c
@@ -0,0 +1,189 @@
+/*
+ * ADX ADPCM codecs
+ * Copyright (c) 2001,2003 BERO
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "adx.h"
+#include "get_bits.h"
+#include "internal.h"
+
+/**
+ * @file
+ * SEGA CRI adx codecs.
+ *
+ * Reference documents:
+ * http://ku-www.ss.titech.ac.jp/~yatsushi/adx.html
+ * adx2wav & wav2adx http://www.geocities.co.jp/Playtown/2004/
+ */
+
+static av_cold int adx_decode_init(AVCodecContext *avctx)
+{
+ ADXContext *c = avctx->priv_data;
+ int ret, header_size;
+
+ if (avctx->extradata_size >= 24) {
+ if ((ret = ff_adx_decode_header(avctx, avctx->extradata,
+ avctx->extradata_size, &header_size,
+ c->coeff)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n");
+ return AVERROR_INVALIDDATA;
+ }
+ c->channels = avctx->channels;
+ c->header_parsed = 1;
+ }
+
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+
+ return 0;
+}
+
+/**
+ * Decode 32 samples from 18 bytes.
+ *
+ * A 16-bit scalar value is applied to 32 residuals, which then have a
+ * 2nd-order LPC filter applied to it to form the output signal for a single
+ * channel.
+ */
+static int adx_decode(ADXContext *c, int16_t *out, int offset,
+ const uint8_t *in, int ch)
+{
+ ADXChannelState *prev = &c->prev[ch];
+ GetBitContext gb;
+ int scale = AV_RB16(in);
+ int i;
+ int s0, s1, s2, d;
+
+ /* check if this is an EOF packet */
+ if (scale & 0x8000)
+ return -1;
+
+ init_get_bits(&gb, in + 2, (BLOCK_SIZE - 2) * 8);
+ out += offset;
+ s1 = prev->s1;
+ s2 = prev->s2;
+ for (i = 0; i < BLOCK_SAMPLES; i++) {
+ d = get_sbits(&gb, 4);
+ s0 = ((d * (1 << COEFF_BITS)) * scale + c->coeff[0] * s1 + c->coeff[1] * s2) >> COEFF_BITS;
+ s2 = s1;
+ s1 = av_clip_int16(s0);
+ *out++ = s1;
+ }
+ prev->s1 = s1;
+ prev->s2 = s2;
+
+ return 0;
+}
+
+static int adx_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ AVFrame *frame = data;
+ int buf_size = avpkt->size;
+ ADXContext *c = avctx->priv_data;
+ int16_t **samples;
+ int samples_offset;
+ const uint8_t *buf = avpkt->data;
+ const uint8_t *buf_end = buf + avpkt->size;
+ int num_blocks, ch, ret;
+
+ if (c->eof) {
+ *got_frame_ptr = 0;
+ return buf_size;
+ }
+
+ if (!c->header_parsed && buf_size >= 2 && AV_RB16(buf) == 0x8000) {
+ int header_size;
+ if ((ret = ff_adx_decode_header(avctx, buf, buf_size, &header_size,
+ c->coeff)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n");
+ return AVERROR_INVALIDDATA;
+ }
+ c->channels = avctx->channels;
+ c->header_parsed = 1;
+ if (buf_size < header_size)
+ return AVERROR_INVALIDDATA;
+ buf += header_size;
+ buf_size -= header_size;
+ }
+ if (!c->header_parsed)
+ return AVERROR_INVALIDDATA;
+
+ /* calculate number of blocks in the packet */
+ num_blocks = buf_size / (BLOCK_SIZE * c->channels);
+
+ /* if the packet is not an even multiple of BLOCK_SIZE, check for an EOF
+ packet */
+ if (!num_blocks || buf_size % (BLOCK_SIZE * avctx->channels)) {
+ if (buf_size >= 4 && (AV_RB16(buf) & 0x8000)) {
+ c->eof = 1;
+ *got_frame_ptr = 0;
+ return avpkt->size;
+ }
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* get output buffer */
+ frame->nb_samples = num_blocks * BLOCK_SAMPLES;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+ samples = (int16_t **)frame->extended_data;
+ samples_offset = 0;
+
+ while (num_blocks--) {
+ for (ch = 0; ch < c->channels; ch++) {
+ if (buf_end - buf < BLOCK_SIZE || adx_decode(c, samples[ch], samples_offset, buf, ch)) {
+ c->eof = 1;
+ buf = avpkt->data + avpkt->size;
+ break;
+ }
+ buf_size -= BLOCK_SIZE;
+ buf += BLOCK_SIZE;
+ }
+ if (!c->eof)
+ samples_offset += BLOCK_SAMPLES;
+ }
+
+ frame->nb_samples = samples_offset;
+ *got_frame_ptr = 1;
+
+ return buf - avpkt->data;
+}
+
+static void adx_decode_flush(AVCodecContext *avctx)
+{
+ ADXContext *c = avctx->priv_data;
+ memset(c->prev, 0, sizeof(c->prev));
+ c->eof = 0;
+}
+
+AVCodec ff_adpcm_adx_decoder = {
+ .name = "adpcm_adx",
+ .long_name = NULL_IF_CONFIG_SMALL("SEGA CRI ADX ADPCM"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_ADPCM_ADX,
+ .priv_data_size = sizeof(ADXContext),
+ .init = adx_decode_init,
+ .decode = adx_decode_frame,
+ .flush = adx_decode_flush,
+ .capabilities = AV_CODEC_CAP_DR1,
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+ AV_SAMPLE_FMT_NONE },
+};
diff --git a/ffmpeg-2-8-11/libavcodec/adxenc.c b/ffmpeg-2-8-12/libavcodec/adxenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/adxenc.c
rename to ffmpeg-2-8-12/libavcodec/adxenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/aic.c b/ffmpeg-2-8-12/libavcodec/aic.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aic.c
rename to ffmpeg-2-8-12/libavcodec/aic.c
diff --git a/ffmpeg-2-8-11/libavcodec/alac.c b/ffmpeg-2-8-12/libavcodec/alac.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alac.c
rename to ffmpeg-2-8-12/libavcodec/alac.c
diff --git a/ffmpeg-2-8-11/libavcodec/alac_data.c b/ffmpeg-2-8-12/libavcodec/alac_data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alac_data.c
rename to ffmpeg-2-8-12/libavcodec/alac_data.c
diff --git a/ffmpeg-2-8-11/libavcodec/alac_data.h b/ffmpeg-2-8-12/libavcodec/alac_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alac_data.h
rename to ffmpeg-2-8-12/libavcodec/alac_data.h
diff --git a/ffmpeg-2-8-11/libavcodec/alacenc.c b/ffmpeg-2-8-12/libavcodec/alacenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alacenc.c
rename to ffmpeg-2-8-12/libavcodec/alacenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/aliaspixdec.c b/ffmpeg-2-8-12/libavcodec/aliaspixdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aliaspixdec.c
rename to ffmpeg-2-8-12/libavcodec/aliaspixdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/aliaspixenc.c b/ffmpeg-2-8-12/libavcodec/aliaspixenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aliaspixenc.c
rename to ffmpeg-2-8-12/libavcodec/aliaspixenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/allcodecs.c b/ffmpeg-2-8-12/libavcodec/allcodecs.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/allcodecs.c
rename to ffmpeg-2-8-12/libavcodec/allcodecs.c
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/Makefile b/ffmpeg-2-8-12/libavcodec/alpha/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/Makefile
rename to ffmpeg-2-8-12/libavcodec/alpha/Makefile
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/asm.h b/ffmpeg-2-8-12/libavcodec/alpha/asm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/asm.h
rename to ffmpeg-2-8-12/libavcodec/alpha/asm.h
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/blockdsp_alpha.c b/ffmpeg-2-8-12/libavcodec/alpha/blockdsp_alpha.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/blockdsp_alpha.c
rename to ffmpeg-2-8-12/libavcodec/alpha/blockdsp_alpha.c
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/hpeldsp_alpha.c b/ffmpeg-2-8-12/libavcodec/alpha/hpeldsp_alpha.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/hpeldsp_alpha.c
rename to ffmpeg-2-8-12/libavcodec/alpha/hpeldsp_alpha.c
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/hpeldsp_alpha.h b/ffmpeg-2-8-12/libavcodec/alpha/hpeldsp_alpha.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/hpeldsp_alpha.h
rename to ffmpeg-2-8-12/libavcodec/alpha/hpeldsp_alpha.h
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/hpeldsp_alpha_asm.S b/ffmpeg-2-8-12/libavcodec/alpha/hpeldsp_alpha_asm.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/hpeldsp_alpha_asm.S
rename to ffmpeg-2-8-12/libavcodec/alpha/hpeldsp_alpha_asm.S
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/idctdsp_alpha.c b/ffmpeg-2-8-12/libavcodec/alpha/idctdsp_alpha.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/idctdsp_alpha.c
rename to ffmpeg-2-8-12/libavcodec/alpha/idctdsp_alpha.c
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/idctdsp_alpha.h b/ffmpeg-2-8-12/libavcodec/alpha/idctdsp_alpha.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/idctdsp_alpha.h
rename to ffmpeg-2-8-12/libavcodec/alpha/idctdsp_alpha.h
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/idctdsp_alpha_asm.S b/ffmpeg-2-8-12/libavcodec/alpha/idctdsp_alpha_asm.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/idctdsp_alpha_asm.S
rename to ffmpeg-2-8-12/libavcodec/alpha/idctdsp_alpha_asm.S
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/me_cmp_alpha.c b/ffmpeg-2-8-12/libavcodec/alpha/me_cmp_alpha.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/me_cmp_alpha.c
rename to ffmpeg-2-8-12/libavcodec/alpha/me_cmp_alpha.c
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/me_cmp_mvi_asm.S b/ffmpeg-2-8-12/libavcodec/alpha/me_cmp_mvi_asm.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/me_cmp_mvi_asm.S
rename to ffmpeg-2-8-12/libavcodec/alpha/me_cmp_mvi_asm.S
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/mpegvideo_alpha.c b/ffmpeg-2-8-12/libavcodec/alpha/mpegvideo_alpha.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/mpegvideo_alpha.c
rename to ffmpeg-2-8-12/libavcodec/alpha/mpegvideo_alpha.c
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/pixblockdsp_alpha.c b/ffmpeg-2-8-12/libavcodec/alpha/pixblockdsp_alpha.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/pixblockdsp_alpha.c
rename to ffmpeg-2-8-12/libavcodec/alpha/pixblockdsp_alpha.c
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/regdef.h b/ffmpeg-2-8-12/libavcodec/alpha/regdef.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/regdef.h
rename to ffmpeg-2-8-12/libavcodec/alpha/regdef.h
diff --git a/ffmpeg-2-8-11/libavcodec/alpha/simple_idct_alpha.c b/ffmpeg-2-8-12/libavcodec/alpha/simple_idct_alpha.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alpha/simple_idct_alpha.c
rename to ffmpeg-2-8-12/libavcodec/alpha/simple_idct_alpha.c
diff --git a/ffmpeg-2-8-11/libavcodec/alsdec.c b/ffmpeg-2-8-12/libavcodec/alsdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/alsdec.c
rename to ffmpeg-2-8-12/libavcodec/alsdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/amr.h b/ffmpeg-2-8-12/libavcodec/amr.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/amr.h
rename to ffmpeg-2-8-12/libavcodec/amr.h
diff --git a/ffmpeg-2-8-11/libavcodec/amrnbdata.h b/ffmpeg-2-8-12/libavcodec/amrnbdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/amrnbdata.h
rename to ffmpeg-2-8-12/libavcodec/amrnbdata.h
diff --git a/ffmpeg-2-8-11/libavcodec/amrnbdec.c b/ffmpeg-2-8-12/libavcodec/amrnbdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/amrnbdec.c
rename to ffmpeg-2-8-12/libavcodec/amrnbdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/amrwbdata.h b/ffmpeg-2-8-12/libavcodec/amrwbdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/amrwbdata.h
rename to ffmpeg-2-8-12/libavcodec/amrwbdata.h
diff --git a/ffmpeg-2-8-12/libavcodec/amrwbdec.c b/ffmpeg-2-8-12/libavcodec/amrwbdec.c
new file mode 100644
index 0000000..c7a99ad
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/amrwbdec.c
@@ -0,0 +1,1279 @@
+/*
+ * AMR wideband decoder
+ * Copyright (c) 2010 Marcelo Galvao Povoa
+ *
+ * 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
+ * AMR wideband decoder
+ */
+
+#include "libavutil/channel_layout.h"
+#include "libavutil/common.h"
+#include "libavutil/float_dsp.h"
+#include "libavutil/lfg.h"
+
+#include "avcodec.h"
+#include "lsp.h"
+#include "celp_filters.h"
+#include "celp_math.h"
+#include "acelp_filters.h"
+#include "acelp_vectors.h"
+#include "acelp_pitch_delay.h"
+#include "internal.h"
+
+#define AMR_USE_16BIT_TABLES
+#include "amr.h"
+
+#include "amrwbdata.h"
+#include "mips/amrwbdec_mips.h"
+
+typedef struct AMRWBContext {
+ AMRWBFrame frame; ///< AMRWB parameters decoded from bitstream
+ enum Mode fr_cur_mode; ///< mode index of current frame
+ uint8_t fr_quality; ///< frame quality index (FQI)
+ float isf_cur[LP_ORDER]; ///< working ISF vector from current frame
+ float isf_q_past[LP_ORDER]; ///< quantized ISF vector of the previous frame
+ float isf_past_final[LP_ORDER]; ///< final processed ISF vector of the previous frame
+ double isp[4][LP_ORDER]; ///< ISP vectors from current frame
+ double isp_sub4_past[LP_ORDER]; ///< ISP vector for the 4th subframe of the previous frame
+
+ float lp_coef[4][LP_ORDER]; ///< Linear Prediction Coefficients from ISP vector
+
+ uint8_t base_pitch_lag; ///< integer part of pitch lag for the next relative subframe
+ uint8_t pitch_lag_int; ///< integer part of pitch lag of the previous subframe
+
+ float excitation_buf[AMRWB_P_DELAY_MAX + LP_ORDER + 2 + AMRWB_SFR_SIZE]; ///< current excitation and all necessary excitation history
+ float *excitation; ///< points to current excitation in excitation_buf[]
+
+ float pitch_vector[AMRWB_SFR_SIZE]; ///< adaptive codebook (pitch) vector for current subframe
+ float fixed_vector[AMRWB_SFR_SIZE]; ///< algebraic codebook (fixed) vector for current subframe
+
+ float prediction_error[4]; ///< quantified prediction errors {20log10(^gamma_gc)} for previous four subframes
+ float pitch_gain[6]; ///< quantified pitch gains for the current and previous five subframes
+ float fixed_gain[2]; ///< quantified fixed gains for the current and previous subframes
+
+ float tilt_coef; ///< {beta_1} related to the voicing of the previous subframe
+
+ float prev_sparse_fixed_gain; ///< previous fixed gain; used by anti-sparseness to determine "onset"
+ uint8_t prev_ir_filter_nr; ///< previous impulse response filter "impNr": 0 - strong, 1 - medium, 2 - none
+ float prev_tr_gain; ///< previous initial gain used by noise enhancer for threshold
+
+ float samples_az[LP_ORDER + AMRWB_SFR_SIZE]; ///< low-band samples and memory from synthesis at 12.8kHz
+ float samples_up[UPS_MEM_SIZE + AMRWB_SFR_SIZE]; ///< low-band samples and memory processed for upsampling
+ float samples_hb[LP_ORDER_16k + AMRWB_SFR_SIZE_16k]; ///< high-band samples and memory from synthesis at 16kHz
+
+ float hpf_31_mem[2], hpf_400_mem[2]; ///< previous values in the high pass filters
+ float demph_mem[1]; ///< previous value in the de-emphasis filter
+ float bpf_6_7_mem[HB_FIR_SIZE]; ///< previous values in the high-band band pass filter
+ float lpf_7_mem[HB_FIR_SIZE]; ///< previous values in the high-band low pass filter
+
+ AVLFG prng; ///< random number generator for white noise excitation
+ uint8_t first_frame; ///< flag active during decoding of the first frame
+ ACELPFContext acelpf_ctx; ///< context for filters for ACELP-based codecs
+ ACELPVContext acelpv_ctx; ///< context for vector operations for ACELP-based codecs
+ CELPFContext celpf_ctx; ///< context for filters for CELP-based codecs
+ CELPMContext celpm_ctx; ///< context for fixed point math operations
+
+} AMRWBContext;
+
+static av_cold int amrwb_decode_init(AVCodecContext *avctx)
+{
+ AMRWBContext *ctx = avctx->priv_data;
+ int i;
+
+ if (avctx->channels > 1) {
+ avpriv_report_missing_feature(avctx, "multi-channel AMR");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ avctx->channels = 1;
+ avctx->channel_layout = AV_CH_LAYOUT_MONO;
+ if (!avctx->sample_rate)
+ avctx->sample_rate = 16000;
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLT;
+
+ av_lfg_init(&ctx->prng, 1);
+
+ ctx->excitation = &ctx->excitation_buf[AMRWB_P_DELAY_MAX + LP_ORDER + 1];
+ ctx->first_frame = 1;
+
+ for (i = 0; i < LP_ORDER; i++)
+ ctx->isf_past_final[i] = isf_init[i] * (1.0f / (1 << 15));
+
+ for (i = 0; i < 4; i++)
+ ctx->prediction_error[i] = MIN_ENERGY;
+
+ ff_acelp_filter_init(&ctx->acelpf_ctx);
+ ff_acelp_vectors_init(&ctx->acelpv_ctx);
+ ff_celp_filter_init(&ctx->celpf_ctx);
+ ff_celp_math_init(&ctx->celpm_ctx);
+
+ return 0;
+}
+
+/**
+ * Decode the frame header in the "MIME/storage" format. This format
+ * is simpler and does not carry the auxiliary frame information.
+ *
+ * @param[in] ctx The Context
+ * @param[in] buf Pointer to the input buffer
+ *
+ * @return The decoded header length in bytes
+ */
+static int decode_mime_header(AMRWBContext *ctx, const uint8_t *buf)
+{
+ /* Decode frame header (1st octet) */
+ ctx->fr_cur_mode = buf[0] >> 3 & 0x0F;
+ ctx->fr_quality = (buf[0] & 0x4) == 0x4;
+
+ return 1;
+}
+
+/**
+ * Decode quantized ISF vectors using 36-bit indexes (6K60 mode only).
+ *
+ * @param[in] ind Array of 5 indexes
+ * @param[out] isf_q Buffer for isf_q[LP_ORDER]
+ *
+ */
+static void decode_isf_indices_36b(uint16_t *ind, float *isf_q)
+{
+ int i;
+
+ for (i = 0; i < 9; i++)
+ isf_q[i] = dico1_isf[ind[0]][i] * (1.0f / (1 << 15));
+
+ for (i = 0; i < 7; i++)
+ isf_q[i + 9] = dico2_isf[ind[1]][i] * (1.0f / (1 << 15));
+
+ for (i = 0; i < 5; i++)
+ isf_q[i] += dico21_isf_36b[ind[2]][i] * (1.0f / (1 << 15));
+
+ for (i = 0; i < 4; i++)
+ isf_q[i + 5] += dico22_isf_36b[ind[3]][i] * (1.0f / (1 << 15));
+
+ for (i = 0; i < 7; i++)
+ isf_q[i + 9] += dico23_isf_36b[ind[4]][i] * (1.0f / (1 << 15));
+}
+
+/**
+ * Decode quantized ISF vectors using 46-bit indexes (except 6K60 mode).
+ *
+ * @param[in] ind Array of 7 indexes
+ * @param[out] isf_q Buffer for isf_q[LP_ORDER]
+ *
+ */
+static void decode_isf_indices_46b(uint16_t *ind, float *isf_q)
+{
+ int i;
+
+ for (i = 0; i < 9; i++)
+ isf_q[i] = dico1_isf[ind[0]][i] * (1.0f / (1 << 15));
+
+ for (i = 0; i < 7; i++)
+ isf_q[i + 9] = dico2_isf[ind[1]][i] * (1.0f / (1 << 15));
+
+ for (i = 0; i < 3; i++)
+ isf_q[i] += dico21_isf[ind[2]][i] * (1.0f / (1 << 15));
+
+ for (i = 0; i < 3; i++)
+ isf_q[i + 3] += dico22_isf[ind[3]][i] * (1.0f / (1 << 15));
+
+ for (i = 0; i < 3; i++)
+ isf_q[i + 6] += dico23_isf[ind[4]][i] * (1.0f / (1 << 15));
+
+ for (i = 0; i < 3; i++)
+ isf_q[i + 9] += dico24_isf[ind[5]][i] * (1.0f / (1 << 15));
+
+ for (i = 0; i < 4; i++)
+ isf_q[i + 12] += dico25_isf[ind[6]][i] * (1.0f / (1 << 15));
+}
+
+/**
+ * Apply mean and past ISF values using the prediction factor.
+ * Updates past ISF vector.
+ *
+ * @param[in,out] isf_q Current quantized ISF
+ * @param[in,out] isf_past Past quantized ISF
+ *
+ */
+static void isf_add_mean_and_past(float *isf_q, float *isf_past)
+{
+ int i;
+ float tmp;
+
+ for (i = 0; i < LP_ORDER; i++) {
+ tmp = isf_q[i];
+ isf_q[i] += isf_mean[i] * (1.0f / (1 << 15));
+ isf_q[i] += PRED_FACTOR * isf_past[i];
+ isf_past[i] = tmp;
+ }
+}
+
+/**
+ * Interpolate the fourth ISP vector from current and past frames
+ * to obtain an ISP vector for each subframe.
+ *
+ * @param[in,out] isp_q ISPs for each subframe
+ * @param[in] isp4_past Past ISP for subframe 4
+ */
+static void interpolate_isp(double isp_q[4][LP_ORDER], const double *isp4_past)
+{
+ int i, k;
+
+ for (k = 0; k < 3; k++) {
+ float c = isfp_inter[k];
+ for (i = 0; i < LP_ORDER; i++)
+ isp_q[k][i] = (1.0 - c) * isp4_past[i] + c * isp_q[3][i];
+ }
+}
+
+/**
+ * Decode an adaptive codebook index into pitch lag (except 6k60, 8k85 modes).
+ * Calculate integer lag and fractional lag always using 1/4 resolution.
+ * In 1st and 3rd subframes the index is relative to last subframe integer lag.
+ *
+ * @param[out] lag_int Decoded integer pitch lag
+ * @param[out] lag_frac Decoded fractional pitch lag
+ * @param[in] pitch_index Adaptive codebook pitch index
+ * @param[in,out] base_lag_int Base integer lag used in relative subframes
+ * @param[in] subframe Current subframe index (0 to 3)
+ */
+static void decode_pitch_lag_high(int *lag_int, int *lag_frac, int pitch_index,
+ uint8_t *base_lag_int, int subframe)
+{
+ if (subframe == 0 || subframe == 2) {
+ if (pitch_index < 376) {
+ *lag_int = (pitch_index + 137) >> 2;
+ *lag_frac = pitch_index - (*lag_int << 2) + 136;
+ } else if (pitch_index < 440) {
+ *lag_int = (pitch_index + 257 - 376) >> 1;
+ *lag_frac = (pitch_index - (*lag_int << 1) + 256 - 376) * 2;
+ /* the actual resolution is 1/2 but expressed as 1/4 */
+ } else {
+ *lag_int = pitch_index - 280;
+ *lag_frac = 0;
+ }
+ /* minimum lag for next subframe */
+ *base_lag_int = av_clip(*lag_int - 8 - (*lag_frac < 0),
+ AMRWB_P_DELAY_MIN, AMRWB_P_DELAY_MAX - 15);
+ // XXX: the spec states clearly that *base_lag_int should be
+ // the nearest integer to *lag_int (minus 8), but the ref code
+ // actually always uses its floor, I'm following the latter
+ } else {
+ *lag_int = (pitch_index + 1) >> 2;
+ *lag_frac = pitch_index - (*lag_int << 2);
+ *lag_int += *base_lag_int;
+ }
+}
+
+/**
+ * Decode an adaptive codebook index into pitch lag for 8k85 and 6k60 modes.
+ * The description is analogous to decode_pitch_lag_high, but in 6k60 the
+ * relative index is used for all subframes except the first.
+ */
+static void decode_pitch_lag_low(int *lag_int, int *lag_frac, int pitch_index,
+ uint8_t *base_lag_int, int subframe, enum Mode mode)
+{
+ if (subframe == 0 || (subframe == 2 && mode != MODE_6k60)) {
+ if (pitch_index < 116) {
+ *lag_int = (pitch_index + 69) >> 1;
+ *lag_frac = (pitch_index - (*lag_int << 1) + 68) * 2;
+ } else {
+ *lag_int = pitch_index - 24;
+ *lag_frac = 0;
+ }
+ // XXX: same problem as before
+ *base_lag_int = av_clip(*lag_int - 8 - (*lag_frac < 0),
+ AMRWB_P_DELAY_MIN, AMRWB_P_DELAY_MAX - 15);
+ } else {
+ *lag_int = (pitch_index + 1) >> 1;
+ *lag_frac = (pitch_index - (*lag_int << 1)) * 2;
+ *lag_int += *base_lag_int;
+ }
+}
+
+/**
+ * Find the pitch vector by interpolating the past excitation at the
+ * pitch delay, which is obtained in this function.
+ *
+ * @param[in,out] ctx The context
+ * @param[in] amr_subframe Current subframe data
+ * @param[in] subframe Current subframe index (0 to 3)
+ */
+static void decode_pitch_vector(AMRWBContext *ctx,
+ const AMRWBSubFrame *amr_subframe,
+ const int subframe)
+{
+ int pitch_lag_int, pitch_lag_frac;
+ int i;
+ float *exc = ctx->excitation;
+ enum Mode mode = ctx->fr_cur_mode;
+
+ if (mode <= MODE_8k85) {
+ decode_pitch_lag_low(&pitch_lag_int, &pitch_lag_frac, amr_subframe->adap,
+ &ctx->base_pitch_lag, subframe, mode);
+ } else
+ decode_pitch_lag_high(&pitch_lag_int, &pitch_lag_frac, amr_subframe->adap,
+ &ctx->base_pitch_lag, subframe);
+
+ ctx->pitch_lag_int = pitch_lag_int;
+ pitch_lag_int += pitch_lag_frac > 0;
+
+ /* Calculate the pitch vector by interpolating the past excitation at the
+ pitch lag using a hamming windowed sinc function */
+ ctx->acelpf_ctx.acelp_interpolatef(exc,
+ exc + 1 - pitch_lag_int,
+ ac_inter, 4,
+ pitch_lag_frac + (pitch_lag_frac > 0 ? 0 : 4),
+ LP_ORDER, AMRWB_SFR_SIZE + 1);
+
+ /* Check which pitch signal path should be used
+ * 6k60 and 8k85 modes have the ltp flag set to 0 */
+ if (amr_subframe->ltp) {
+ memcpy(ctx->pitch_vector, exc, AMRWB_SFR_SIZE * sizeof(float));
+ } else {
+ for (i = 0; i < AMRWB_SFR_SIZE; i++)
+ ctx->pitch_vector[i] = 0.18 * exc[i - 1] + 0.64 * exc[i] +
+ 0.18 * exc[i + 1];
+ memcpy(exc, ctx->pitch_vector, AMRWB_SFR_SIZE * sizeof(float));
+ }
+}
+
+/** Get x bits in the index interval [lsb,lsb+len-1] inclusive */
+#define BIT_STR(x,lsb,len) (((x) >> (lsb)) & ((1 << (len)) - 1))
+
+/** Get the bit at specified position */
+#define BIT_POS(x, p) (((x) >> (p)) & 1)
+
+/**
+ * The next six functions decode_[i]p_track decode exactly i pulses
+ * positions and amplitudes (-1 or 1) in a subframe track using
+ * an encoded pulse indexing (TS 26.190 section 5.8.2).
+ *
+ * The results are given in out[], in which a negative number means
+ * amplitude -1 and vice versa (i.e., ampl(x) = x / abs(x) ).
+ *
+ * @param[out] out Output buffer (writes i elements)
+ * @param[in] code Pulse index (no. of bits varies, see below)
+ * @param[in] m (log2) Number of potential positions
+ * @param[in] off Offset for decoded positions
+ */
+static inline void decode_1p_track(int *out, int code, int m, int off)
+{
+ int pos = BIT_STR(code, 0, m) + off; ///code: m+1 bits
+
+ out[0] = BIT_POS(code, m) ? -pos : pos;
+}
+
+static inline void decode_2p_track(int *out, int code, int m, int off) ///code: 2m+1 bits
+{
+ int pos0 = BIT_STR(code, m, m) + off;
+ int pos1 = BIT_STR(code, 0, m) + off;
+
+ out[0] = BIT_POS(code, 2*m) ? -pos0 : pos0;
+ out[1] = BIT_POS(code, 2*m) ? -pos1 : pos1;
+ out[1] = pos0 > pos1 ? -out[1] : out[1];
+}
+
+static void decode_3p_track(int *out, int code, int m, int off) ///code: 3m+1 bits
+{
+ int half_2p = BIT_POS(code, 2*m - 1) << (m - 1);
+
+ decode_2p_track(out, BIT_STR(code, 0, 2*m - 1),
+ m - 1, off + half_2p);
+ decode_1p_track(out + 2, BIT_STR(code, 2*m, m + 1), m, off);
+}
+
+static void decode_4p_track(int *out, int code, int m, int off) ///code: 4m bits
+{
+ int half_4p, subhalf_2p;
+ int b_offset = 1 << (m - 1);
+
+ switch (BIT_STR(code, 4*m - 2, 2)) { /* case ID (2 bits) */
+ case 0: /* 0 pulses in A, 4 pulses in B or vice versa */
+ half_4p = BIT_POS(code, 4*m - 3) << (m - 1); // which has 4 pulses
+ subhalf_2p = BIT_POS(code, 2*m - 3) << (m - 2);
+
+ decode_2p_track(out, BIT_STR(code, 0, 2*m - 3),
+ m - 2, off + half_4p + subhalf_2p);
+ decode_2p_track(out + 2, BIT_STR(code, 2*m - 2, 2*m - 1),
+ m - 1, off + half_4p);
+ break;
+ case 1: /* 1 pulse in A, 3 pulses in B */
+ decode_1p_track(out, BIT_STR(code, 3*m - 2, m),
+ m - 1, off);
+ decode_3p_track(out + 1, BIT_STR(code, 0, 3*m - 2),
+ m - 1, off + b_offset);
+ break;
+ case 2: /* 2 pulses in each half */
+ decode_2p_track(out, BIT_STR(code, 2*m - 1, 2*m - 1),
+ m - 1, off);
+ decode_2p_track(out + 2, BIT_STR(code, 0, 2*m - 1),
+ m - 1, off + b_offset);
+ break;
+ case 3: /* 3 pulses in A, 1 pulse in B */
+ decode_3p_track(out, BIT_STR(code, m, 3*m - 2),
+ m - 1, off);
+ decode_1p_track(out + 3, BIT_STR(code, 0, m),
+ m - 1, off + b_offset);
+ break;
+ }
+}
+
+static void decode_5p_track(int *out, int code, int m, int off) ///code: 5m bits
+{
+ int half_3p = BIT_POS(code, 5*m - 1) << (m - 1);
+
+ decode_3p_track(out, BIT_STR(code, 2*m + 1, 3*m - 2),
+ m - 1, off + half_3p);
+
+ decode_2p_track(out + 3, BIT_STR(code, 0, 2*m + 1), m, off);
+}
+
+static void decode_6p_track(int *out, int code, int m, int off) ///code: 6m-2 bits
+{
+ int b_offset = 1 << (m - 1);
+ /* which half has more pulses in cases 0 to 2 */
+ int half_more = BIT_POS(code, 6*m - 5) << (m - 1);
+ int half_other = b_offset - half_more;
+
+ switch (BIT_STR(code, 6*m - 4, 2)) { /* case ID (2 bits) */
+ case 0: /* 0 pulses in A, 6 pulses in B or vice versa */
+ decode_1p_track(out, BIT_STR(code, 0, m),
+ m - 1, off + half_more);
+ decode_5p_track(out + 1, BIT_STR(code, m, 5*m - 5),
+ m - 1, off + half_more);
+ break;
+ case 1: /* 1 pulse in A, 5 pulses in B or vice versa */
+ decode_1p_track(out, BIT_STR(code, 0, m),
+ m - 1, off + half_other);
+ decode_5p_track(out + 1, BIT_STR(code, m, 5*m - 5),
+ m - 1, off + half_more);
+ break;
+ case 2: /* 2 pulses in A, 4 pulses in B or vice versa */
+ decode_2p_track(out, BIT_STR(code, 0, 2*m - 1),
+ m - 1, off + half_other);
+ decode_4p_track(out + 2, BIT_STR(code, 2*m - 1, 4*m - 4),
+ m - 1, off + half_more);
+ break;
+ case 3: /* 3 pulses in A, 3 pulses in B */
+ decode_3p_track(out, BIT_STR(code, 3*m - 2, 3*m - 2),
+ m - 1, off);
+ decode_3p_track(out + 3, BIT_STR(code, 0, 3*m - 2),
+ m - 1, off + b_offset);
+ break;
+ }
+}
+
+/**
+ * Decode the algebraic codebook index to pulse positions and signs,
+ * then construct the algebraic codebook vector.
+ *
+ * @param[out] fixed_vector Buffer for the fixed codebook excitation
+ * @param[in] pulse_hi MSBs part of the pulse index array (higher modes only)
+ * @param[in] pulse_lo LSBs part of the pulse index array
+ * @param[in] mode Mode of the current frame
+ */
+static void decode_fixed_vector(float *fixed_vector, const uint16_t *pulse_hi,
+ const uint16_t *pulse_lo, const enum Mode mode)
+{
+ /* sig_pos stores for each track the decoded pulse position indexes
+ * (1-based) multiplied by its corresponding amplitude (+1 or -1) */
+ int sig_pos[4][6];
+ int spacing = (mode == MODE_6k60) ? 2 : 4;
+ int i, j;
+
+ switch (mode) {
+ case MODE_6k60:
+ for (i = 0; i < 2; i++)
+ decode_1p_track(sig_pos[i], pulse_lo[i], 5, 1);
+ break;
+ case MODE_8k85:
+ for (i = 0; i < 4; i++)
+ decode_1p_track(sig_pos[i], pulse_lo[i], 4, 1);
+ break;
+ case MODE_12k65:
+ for (i = 0; i < 4; i++)
+ decode_2p_track(sig_pos[i], pulse_lo[i], 4, 1);
+ break;
+ case MODE_14k25:
+ for (i = 0; i < 2; i++)
+ decode_3p_track(sig_pos[i], pulse_lo[i], 4, 1);
+ for (i = 2; i < 4; i++)
+ decode_2p_track(sig_pos[i], pulse_lo[i], 4, 1);
+ break;
+ case MODE_15k85:
+ for (i = 0; i < 4; i++)
+ decode_3p_track(sig_pos[i], pulse_lo[i], 4, 1);
+ break;
+ case MODE_18k25:
+ for (i = 0; i < 4; i++)
+ decode_4p_track(sig_pos[i], (int) pulse_lo[i] +
+ ((int) pulse_hi[i] << 14), 4, 1);
+ break;
+ case MODE_19k85:
+ for (i = 0; i < 2; i++)
+ decode_5p_track(sig_pos[i], (int) pulse_lo[i] +
+ ((int) pulse_hi[i] << 10), 4, 1);
+ for (i = 2; i < 4; i++)
+ decode_4p_track(sig_pos[i], (int) pulse_lo[i] +
+ ((int) pulse_hi[i] << 14), 4, 1);
+ break;
+ case MODE_23k05:
+ case MODE_23k85:
+ for (i = 0; i < 4; i++)
+ decode_6p_track(sig_pos[i], (int) pulse_lo[i] +
+ ((int) pulse_hi[i] << 11), 4, 1);
+ break;
+ }
+
+ memset(fixed_vector, 0, sizeof(float) * AMRWB_SFR_SIZE);
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < pulses_nb_per_mode_tr[mode][i]; j++) {
+ int pos = (FFABS(sig_pos[i][j]) - 1) * spacing + i;
+
+ fixed_vector[pos] += sig_pos[i][j] < 0 ? -1.0 : 1.0;
+ }
+}
+
+/**
+ * Decode pitch gain and fixed gain correction factor.
+ *
+ * @param[in] vq_gain Vector-quantized index for gains
+ * @param[in] mode Mode of the current frame
+ * @param[out] fixed_gain_factor Decoded fixed gain correction factor
+ * @param[out] pitch_gain Decoded pitch gain
+ */
+static void decode_gains(const uint8_t vq_gain, const enum Mode mode,
+ float *fixed_gain_factor, float *pitch_gain)
+{
+ const int16_t *gains = (mode <= MODE_8k85 ? qua_gain_6b[vq_gain] :
+ qua_gain_7b[vq_gain]);
+
+ *pitch_gain = gains[0] * (1.0f / (1 << 14));
+ *fixed_gain_factor = gains[1] * (1.0f / (1 << 11));
+}
+
+/**
+ * Apply pitch sharpening filters to the fixed codebook vector.
+ *
+ * @param[in] ctx The context
+ * @param[in,out] fixed_vector Fixed codebook excitation
+ */
+// XXX: Spec states this procedure should be applied when the pitch
+// lag is less than 64, but this checking seems absent in reference and AMR-NB
+static void pitch_sharpening(AMRWBContext *ctx, float *fixed_vector)
+{
+ int i;
+
+ /* Tilt part */
+ for (i = AMRWB_SFR_SIZE - 1; i != 0; i--)
+ fixed_vector[i] -= fixed_vector[i - 1] * ctx->tilt_coef;
+
+ /* Periodicity enhancement part */
+ for (i = ctx->pitch_lag_int; i < AMRWB_SFR_SIZE; i++)
+ fixed_vector[i] += fixed_vector[i - ctx->pitch_lag_int] * 0.85;
+}
+
+/**
+ * Calculate the voicing factor (-1.0 = unvoiced to 1.0 = voiced).
+ *
+ * @param[in] p_vector, f_vector Pitch and fixed excitation vectors
+ * @param[in] p_gain, f_gain Pitch and fixed gains
+ * @param[in] ctx The context
+ */
+// XXX: There is something wrong with the precision here! The magnitudes
+// of the energies are not correct. Please check the reference code carefully
+static float voice_factor(float *p_vector, float p_gain,
+ float *f_vector, float f_gain,
+ CELPMContext *ctx)
+{
+ double p_ener = (double) ctx->dot_productf(p_vector, p_vector,
+ AMRWB_SFR_SIZE) *
+ p_gain * p_gain;
+ double f_ener = (double) ctx->dot_productf(f_vector, f_vector,
+ AMRWB_SFR_SIZE) *
+ f_gain * f_gain;
+
+ return (p_ener - f_ener) / (p_ener + f_ener);
+}
+
+/**
+ * Reduce fixed vector sparseness by smoothing with one of three IR filters,
+ * also known as "adaptive phase dispersion".
+ *
+ * @param[in] ctx The context
+ * @param[in,out] fixed_vector Unfiltered fixed vector
+ * @param[out] buf Space for modified vector if necessary
+ *
+ * @return The potentially overwritten filtered fixed vector address
+ */
+static float *anti_sparseness(AMRWBContext *ctx,
+ float *fixed_vector, float *buf)
+{
+ int ir_filter_nr;
+
+ if (ctx->fr_cur_mode > MODE_8k85) // no filtering in higher modes
+ return fixed_vector;
+
+ if (ctx->pitch_gain[0] < 0.6) {
+ ir_filter_nr = 0; // strong filtering
+ } else if (ctx->pitch_gain[0] < 0.9) {
+ ir_filter_nr = 1; // medium filtering
+ } else
+ ir_filter_nr = 2; // no filtering
+
+ /* detect 'onset' */
+ if (ctx->fixed_gain[0] > 3.0 * ctx->fixed_gain[1]) {
+ if (ir_filter_nr < 2)
+ ir_filter_nr++;
+ } else {
+ int i, count = 0;
+
+ for (i = 0; i < 6; i++)
+ if (ctx->pitch_gain[i] < 0.6)
+ count++;
+
+ if (count > 2)
+ ir_filter_nr = 0;
+
+ if (ir_filter_nr > ctx->prev_ir_filter_nr + 1)
+ ir_filter_nr--;
+ }
+
+ /* update ir filter strength history */
+ ctx->prev_ir_filter_nr = ir_filter_nr;
+
+ ir_filter_nr += (ctx->fr_cur_mode == MODE_8k85);
+
+ if (ir_filter_nr < 2) {
+ int i;
+ const float *coef = ir_filters_lookup[ir_filter_nr];
+
+ /* Circular convolution code in the reference
+ * decoder was modified to avoid using one
+ * extra array. The filtered vector is given by:
+ *
+ * c2(n) = sum(i,0,len-1){ c(i) * coef( (n - i + len) % len ) }
+ */
+
+ memset(buf, 0, sizeof(float) * AMRWB_SFR_SIZE);
+ for (i = 0; i < AMRWB_SFR_SIZE; i++)
+ if (fixed_vector[i])
+ ff_celp_circ_addf(buf, buf, coef, i, fixed_vector[i],
+ AMRWB_SFR_SIZE);
+ fixed_vector = buf;
+ }
+
+ return fixed_vector;
+}
+
+/**
+ * Calculate a stability factor {teta} based on distance between
+ * current and past isf. A value of 1 shows maximum signal stability.
+ */
+static float stability_factor(const float *isf, const float *isf_past)
+{
+ int i;
+ float acc = 0.0;
+
+ for (i = 0; i < LP_ORDER - 1; i++)
+ acc += (isf[i] - isf_past[i]) * (isf[i] - isf_past[i]);
+
+ // XXX: This part is not so clear from the reference code
+ // the result is more accurate changing the "/ 256" to "* 512"
+ return FFMAX(0.0, 1.25 - acc * 0.8 * 512);
+}
+
+/**
+ * Apply a non-linear fixed gain smoothing in order to reduce
+ * fluctuation in the energy of excitation.
+ *
+ * @param[in] fixed_gain Unsmoothed fixed gain
+ * @param[in,out] prev_tr_gain Previous threshold gain (updated)
+ * @param[in] voice_fac Frame voicing factor
+ * @param[in] stab_fac Frame stability factor
+ *
+ * @return The smoothed gain
+ */
+static float noise_enhancer(float fixed_gain, float *prev_tr_gain,
+ float voice_fac, float stab_fac)
+{
+ float sm_fac = 0.5 * (1 - voice_fac) * stab_fac;
+ float g0;
+
+ // XXX: the following fixed-point constants used to in(de)crement
+ // gain by 1.5dB were taken from the reference code, maybe it could
+ // be simpler
+ if (fixed_gain < *prev_tr_gain) {
+ g0 = FFMIN(*prev_tr_gain, fixed_gain + fixed_gain *
+ (6226 * (1.0f / (1 << 15)))); // +1.5 dB
+ } else
+ g0 = FFMAX(*prev_tr_gain, fixed_gain *
+ (27536 * (1.0f / (1 << 15)))); // -1.5 dB
+
+ *prev_tr_gain = g0; // update next frame threshold
+
+ return sm_fac * g0 + (1 - sm_fac) * fixed_gain;
+}
+
+/**
+ * Filter the fixed_vector to emphasize the higher frequencies.
+ *
+ * @param[in,out] fixed_vector Fixed codebook vector
+ * @param[in] voice_fac Frame voicing factor
+ */
+static void pitch_enhancer(float *fixed_vector, float voice_fac)
+{
+ int i;
+ float cpe = 0.125 * (1 + voice_fac);
+ float last = fixed_vector[0]; // holds c(i - 1)
+
+ fixed_vector[0] -= cpe * fixed_vector[1];
+
+ for (i = 1; i < AMRWB_SFR_SIZE - 1; i++) {
+ float cur = fixed_vector[i];
+
+ fixed_vector[i] -= cpe * (last + fixed_vector[i + 1]);
+ last = cur;
+ }
+
+ fixed_vector[AMRWB_SFR_SIZE - 1] -= cpe * last;
+}
+
+/**
+ * Conduct 16th order linear predictive coding synthesis from excitation.
+ *
+ * @param[in] ctx Pointer to the AMRWBContext
+ * @param[in] lpc Pointer to the LPC coefficients
+ * @param[out] excitation Buffer for synthesis final excitation
+ * @param[in] fixed_gain Fixed codebook gain for synthesis
+ * @param[in] fixed_vector Algebraic codebook vector
+ * @param[in,out] samples Pointer to the output samples and memory
+ */
+static void synthesis(AMRWBContext *ctx, float *lpc, float *excitation,
+ float fixed_gain, const float *fixed_vector,
+ float *samples)
+{
+ ctx->acelpv_ctx.weighted_vector_sumf(excitation, ctx->pitch_vector, fixed_vector,
+ ctx->pitch_gain[0], fixed_gain, AMRWB_SFR_SIZE);
+
+ /* emphasize pitch vector contribution in low bitrate modes */
+ if (ctx->pitch_gain[0] > 0.5 && ctx->fr_cur_mode <= MODE_8k85) {
+ int i;
+ float energy = ctx->celpm_ctx.dot_productf(excitation, excitation,
+ AMRWB_SFR_SIZE);
+
+ // XXX: Weird part in both ref code and spec. A unknown parameter
+ // {beta} seems to be identical to the current pitch gain
+ float pitch_factor = 0.25 * ctx->pitch_gain[0] * ctx->pitch_gain[0];
+
+ for (i = 0; i < AMRWB_SFR_SIZE; i++)
+ excitation[i] += pitch_factor * ctx->pitch_vector[i];
+
+ ff_scale_vector_to_given_sum_of_squares(excitation, excitation,
+ energy, AMRWB_SFR_SIZE);
+ }
+
+ ctx->celpf_ctx.celp_lp_synthesis_filterf(samples, lpc, excitation,
+ AMRWB_SFR_SIZE, LP_ORDER);
+}
+
+/**
+ * Apply to synthesis a de-emphasis filter of the form:
+ * H(z) = 1 / (1 - m * z^-1)
+ *
+ * @param[out] out Output buffer
+ * @param[in] in Input samples array with in[-1]
+ * @param[in] m Filter coefficient
+ * @param[in,out] mem State from last filtering
+ */
+static void de_emphasis(float *out, float *in, float m, float mem[1])
+{
+ int i;
+
+ out[0] = in[0] + m * mem[0];
+
+ for (i = 1; i < AMRWB_SFR_SIZE; i++)
+ out[i] = in[i] + out[i - 1] * m;
+
+ mem[0] = out[AMRWB_SFR_SIZE - 1];
+}
+
+/**
+ * Upsample a signal by 5/4 ratio (from 12.8kHz to 16kHz) using
+ * a FIR interpolation filter. Uses past data from before *in address.
+ *
+ * @param[out] out Buffer for interpolated signal
+ * @param[in] in Current signal data (length 0.8*o_size)
+ * @param[in] o_size Output signal length
+ * @param[in] ctx The context
+ */
+static void upsample_5_4(float *out, const float *in, int o_size, CELPMContext *ctx)
+{
+ const float *in0 = in - UPS_FIR_SIZE + 1;
+ int i, j, k;
+ int int_part = 0, frac_part;
+
+ i = 0;
+ for (j = 0; j < o_size / 5; j++) {
+ out[i] = in[int_part];
+ frac_part = 4;
+ i++;
+
+ for (k = 1; k < 5; k++) {
+ out[i] = ctx->dot_productf(in0 + int_part,
+ upsample_fir[4 - frac_part],
+ UPS_MEM_SIZE);
+ int_part++;
+ frac_part--;
+ i++;
+ }
+ }
+}
+
+/**
+ * Calculate the high-band gain based on encoded index (23k85 mode) or
+ * on the low-band speech signal and the Voice Activity Detection flag.
+ *
+ * @param[in] ctx The context
+ * @param[in] synth LB speech synthesis at 12.8k
+ * @param[in] hb_idx Gain index for mode 23k85 only
+ * @param[in] vad VAD flag for the frame
+ */
+static float find_hb_gain(AMRWBContext *ctx, const float *synth,
+ uint16_t hb_idx, uint8_t vad)
+{
+ int wsp = (vad > 0);
+ float tilt;
+
+ if (ctx->fr_cur_mode == MODE_23k85)
+ return qua_hb_gain[hb_idx] * (1.0f / (1 << 14));
+
+ tilt = ctx->celpm_ctx.dot_productf(synth, synth + 1, AMRWB_SFR_SIZE - 1) /
+ ctx->celpm_ctx.dot_productf(synth, synth, AMRWB_SFR_SIZE);
+
+ /* return gain bounded by [0.1, 1.0] */
+ return av_clipf((1.0 - FFMAX(0.0, tilt)) * (1.25 - 0.25 * wsp), 0.1, 1.0);
+}
+
+/**
+ * Generate the high-band excitation with the same energy from the lower
+ * one and scaled by the given gain.
+ *
+ * @param[in] ctx The context
+ * @param[out] hb_exc Buffer for the excitation
+ * @param[in] synth_exc Low-band excitation used for synthesis
+ * @param[in] hb_gain Wanted excitation gain
+ */
+static void scaled_hb_excitation(AMRWBContext *ctx, float *hb_exc,
+ const float *synth_exc, float hb_gain)
+{
+ int i;
+ float energy = ctx->celpm_ctx.dot_productf(synth_exc, synth_exc,
+ AMRWB_SFR_SIZE);
+
+ /* Generate a white-noise excitation */
+ for (i = 0; i < AMRWB_SFR_SIZE_16k; i++)
+ hb_exc[i] = 32768.0 - (uint16_t) av_lfg_get(&ctx->prng);
+
+ ff_scale_vector_to_given_sum_of_squares(hb_exc, hb_exc,
+ energy * hb_gain * hb_gain,
+ AMRWB_SFR_SIZE_16k);
+}
+
+/**
+ * Calculate the auto-correlation for the ISF difference vector.
+ */
+static float auto_correlation(float *diff_isf, float mean, int lag)
+{
+ int i;
+ float sum = 0.0;
+
+ for (i = 7; i < LP_ORDER - 2; i++) {
+ float prod = (diff_isf[i] - mean) * (diff_isf[i - lag] - mean);
+ sum += prod * prod;
+ }
+ return sum;
+}
+
+/**
+ * Extrapolate a ISF vector to the 16kHz range (20th order LP)
+ * used at mode 6k60 LP filter for the high frequency band.
+ *
+ * @param[out] isf Buffer for extrapolated isf; contains LP_ORDER
+ * values on input
+ */
+static void extrapolate_isf(float isf[LP_ORDER_16k])
+{
+ float diff_isf[LP_ORDER - 2], diff_mean;
+ float corr_lag[3];
+ float est, scale;
+ int i, j, i_max_corr;
+
+ isf[LP_ORDER_16k - 1] = isf[LP_ORDER - 1];
+
+ /* Calculate the difference vector */
+ for (i = 0; i < LP_ORDER - 2; i++)
+ diff_isf[i] = isf[i + 1] - isf[i];
+
+ diff_mean = 0.0;
+ for (i = 2; i < LP_ORDER - 2; i++)
+ diff_mean += diff_isf[i] * (1.0f / (LP_ORDER - 4));
+
+ /* Find which is the maximum autocorrelation */
+ i_max_corr = 0;
+ for (i = 0; i < 3; i++) {
+ corr_lag[i] = auto_correlation(diff_isf, diff_mean, i + 2);
+
+ if (corr_lag[i] > corr_lag[i_max_corr])
+ i_max_corr = i;
+ }
+ i_max_corr++;
+
+ for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++)
+ isf[i] = isf[i - 1] + isf[i - 1 - i_max_corr]
+ - isf[i - 2 - i_max_corr];
+
+ /* Calculate an estimate for ISF(18) and scale ISF based on the error */
+ est = 7965 + (isf[2] - isf[3] - isf[4]) / 6.0;
+ scale = 0.5 * (FFMIN(est, 7600) - isf[LP_ORDER - 2]) /
+ (isf[LP_ORDER_16k - 2] - isf[LP_ORDER - 2]);
+
+ for (i = LP_ORDER - 1, j = 0; i < LP_ORDER_16k - 1; i++, j++)
+ diff_isf[j] = scale * (isf[i] - isf[i - 1]);
+
+ /* Stability insurance */
+ for (i = 1; i < LP_ORDER_16k - LP_ORDER; i++)
+ if (diff_isf[i] + diff_isf[i - 1] < 5.0) {
+ if (diff_isf[i] > diff_isf[i - 1]) {
+ diff_isf[i - 1] = 5.0 - diff_isf[i];
+ } else
+ diff_isf[i] = 5.0 - diff_isf[i - 1];
+ }
+
+ for (i = LP_ORDER - 1, j = 0; i < LP_ORDER_16k - 1; i++, j++)
+ isf[i] = isf[i - 1] + diff_isf[j] * (1.0f / (1 << 15));
+
+ /* Scale the ISF vector for 16000 Hz */
+ for (i = 0; i < LP_ORDER_16k - 1; i++)
+ isf[i] *= 0.8;
+}
+
+/**
+ * Spectral expand the LP coefficients using the equation:
+ * y[i] = x[i] * (gamma ** i)
+ *
+ * @param[out] out Output buffer (may use input array)
+ * @param[in] lpc LP coefficients array
+ * @param[in] gamma Weighting factor
+ * @param[in] size LP array size
+ */
+static void lpc_weighting(float *out, const float *lpc, float gamma, int size)
+{
+ int i;
+ float fac = gamma;
+
+ for (i = 0; i < size; i++) {
+ out[i] = lpc[i] * fac;
+ fac *= gamma;
+ }
+}
+
+/**
+ * Conduct 20th order linear predictive coding synthesis for the high
+ * frequency band excitation at 16kHz.
+ *
+ * @param[in] ctx The context
+ * @param[in] subframe Current subframe index (0 to 3)
+ * @param[in,out] samples Pointer to the output speech samples
+ * @param[in] exc Generated white-noise scaled excitation
+ * @param[in] isf Current frame isf vector
+ * @param[in] isf_past Past frame final isf vector
+ */
+static void hb_synthesis(AMRWBContext *ctx, int subframe, float *samples,
+ const float *exc, const float *isf, const float *isf_past)
+{
+ float hb_lpc[LP_ORDER_16k];
+ enum Mode mode = ctx->fr_cur_mode;
+
+ if (mode == MODE_6k60) {
+ float e_isf[LP_ORDER_16k]; // ISF vector for extrapolation
+ double e_isp[LP_ORDER_16k];
+
+ ctx->acelpv_ctx.weighted_vector_sumf(e_isf, isf_past, isf, isfp_inter[subframe],
+ 1.0 - isfp_inter[subframe], LP_ORDER);
+
+ extrapolate_isf(e_isf);
+
+ e_isf[LP_ORDER_16k - 1] *= 2.0;
+ ff_acelp_lsf2lspd(e_isp, e_isf, LP_ORDER_16k);
+ ff_amrwb_lsp2lpc(e_isp, hb_lpc, LP_ORDER_16k);
+
+ lpc_weighting(hb_lpc, hb_lpc, 0.9, LP_ORDER_16k);
+ } else {
+ lpc_weighting(hb_lpc, ctx->lp_coef[subframe], 0.6, LP_ORDER);
+ }
+
+ ctx->celpf_ctx.celp_lp_synthesis_filterf(samples, hb_lpc, exc, AMRWB_SFR_SIZE_16k,
+ (mode == MODE_6k60) ? LP_ORDER_16k : LP_ORDER);
+}
+
+/**
+ * Apply a 15th order filter to high-band samples.
+ * The filter characteristic depends on the given coefficients.
+ *
+ * @param[out] out Buffer for filtered output
+ * @param[in] fir_coef Filter coefficients
+ * @param[in,out] mem State from last filtering (updated)
+ * @param[in] in Input speech data (high-band)
+ *
+ * @remark It is safe to pass the same array in in and out parameters
+ */
+
+#ifndef hb_fir_filter
+static void hb_fir_filter(float *out, const float fir_coef[HB_FIR_SIZE + 1],
+ float mem[HB_FIR_SIZE], const float *in)
+{
+ int i, j;
+ float data[AMRWB_SFR_SIZE_16k + HB_FIR_SIZE]; // past and current samples
+
+ memcpy(data, mem, HB_FIR_SIZE * sizeof(float));
+ memcpy(data + HB_FIR_SIZE, in, AMRWB_SFR_SIZE_16k * sizeof(float));
+
+ for (i = 0; i < AMRWB_SFR_SIZE_16k; i++) {
+ out[i] = 0.0;
+ for (j = 0; j <= HB_FIR_SIZE; j++)
+ out[i] += data[i + j] * fir_coef[j];
+ }
+
+ memcpy(mem, data + AMRWB_SFR_SIZE_16k, HB_FIR_SIZE * sizeof(float));
+}
+#endif /* hb_fir_filter */
+
+/**
+ * Update context state before the next subframe.
+ */
+static void update_sub_state(AMRWBContext *ctx)
+{
+ memmove(&ctx->excitation_buf[0], &ctx->excitation_buf[AMRWB_SFR_SIZE],
+ (AMRWB_P_DELAY_MAX + LP_ORDER + 1) * sizeof(float));
+
+ memmove(&ctx->pitch_gain[1], &ctx->pitch_gain[0], 5 * sizeof(float));
+ memmove(&ctx->fixed_gain[1], &ctx->fixed_gain[0], 1 * sizeof(float));
+
+ memmove(&ctx->samples_az[0], &ctx->samples_az[AMRWB_SFR_SIZE],
+ LP_ORDER * sizeof(float));
+ memmove(&ctx->samples_up[0], &ctx->samples_up[AMRWB_SFR_SIZE],
+ UPS_MEM_SIZE * sizeof(float));
+ memmove(&ctx->samples_hb[0], &ctx->samples_hb[AMRWB_SFR_SIZE_16k],
+ LP_ORDER_16k * sizeof(float));
+}
+
+static int amrwb_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ AMRWBContext *ctx = avctx->priv_data;
+ AVFrame *frame = data;
+ AMRWBFrame *cf = &ctx->frame;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ int expected_fr_size, header_size;
+ float *buf_out;
+ float spare_vector[AMRWB_SFR_SIZE]; // extra stack space to hold result from anti-sparseness processing
+ float fixed_gain_factor; // fixed gain correction factor (gamma)
+ float *synth_fixed_vector; // pointer to the fixed vector that synthesis should use
+ float synth_fixed_gain; // the fixed gain that synthesis should use
+ float voice_fac, stab_fac; // parameters used for gain smoothing
+ float synth_exc[AMRWB_SFR_SIZE]; // post-processed excitation for synthesis
+ float hb_exc[AMRWB_SFR_SIZE_16k]; // excitation for the high frequency band
+ float hb_samples[AMRWB_SFR_SIZE_16k]; // filtered high-band samples from synthesis
+ float hb_gain;
+ int sub, i, ret;
+
+ /* get output buffer */
+ frame->nb_samples = 4 * AMRWB_SFR_SIZE_16k;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+ buf_out = (float *)frame->data[0];
+
+ header_size = decode_mime_header(ctx, buf);
+ if (ctx->fr_cur_mode > MODE_SID) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid mode %d\n", ctx->fr_cur_mode);
+ return AVERROR_INVALIDDATA;
+ }
+ expected_fr_size = ((cf_sizes_wb[ctx->fr_cur_mode] + 7) >> 3) + 1;
+
+ if (buf_size < expected_fr_size) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Frame too small (%d bytes). Truncated file?\n", buf_size);
+ *got_frame_ptr = 0;
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!ctx->fr_quality || ctx->fr_cur_mode > MODE_SID)
+ av_log(avctx, AV_LOG_ERROR, "Encountered a bad or corrupted frame\n");
+
+ if (ctx->fr_cur_mode == MODE_SID) { /* Comfort noise frame */
+ avpriv_request_sample(avctx, "SID mode");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ ff_amr_bit_reorder((uint16_t *) &ctx->frame, sizeof(AMRWBFrame),
+ buf + header_size, amr_bit_orderings_by_mode[ctx->fr_cur_mode]);
+
+ /* Decode the quantized ISF vector */
+ if (ctx->fr_cur_mode == MODE_6k60) {
+ decode_isf_indices_36b(cf->isp_id, ctx->isf_cur);
+ } else {
+ decode_isf_indices_46b(cf->isp_id, ctx->isf_cur);
+ }
+
+ isf_add_mean_and_past(ctx->isf_cur, ctx->isf_q_past);
+ ff_set_min_dist_lsf(ctx->isf_cur, MIN_ISF_SPACING, LP_ORDER - 1);
+
+ stab_fac = stability_factor(ctx->isf_cur, ctx->isf_past_final);
+
+ ctx->isf_cur[LP_ORDER - 1] *= 2.0;
+ ff_acelp_lsf2lspd(ctx->isp[3], ctx->isf_cur, LP_ORDER);
+
+ /* Generate a ISP vector for each subframe */
+ if (ctx->first_frame) {
+ ctx->first_frame = 0;
+ memcpy(ctx->isp_sub4_past, ctx->isp[3], LP_ORDER * sizeof(double));
+ }
+ interpolate_isp(ctx->isp, ctx->isp_sub4_past);
+
+ for (sub = 0; sub < 4; sub++)
+ ff_amrwb_lsp2lpc(ctx->isp[sub], ctx->lp_coef[sub], LP_ORDER);
+
+ for (sub = 0; sub < 4; sub++) {
+ const AMRWBSubFrame *cur_subframe = &cf->subframe[sub];
+ float *sub_buf = buf_out + sub * AMRWB_SFR_SIZE_16k;
+
+ /* Decode adaptive codebook (pitch vector) */
+ decode_pitch_vector(ctx, cur_subframe, sub);
+ /* Decode innovative codebook (fixed vector) */
+ decode_fixed_vector(ctx->fixed_vector, cur_subframe->pul_ih,
+ cur_subframe->pul_il, ctx->fr_cur_mode);
+
+ pitch_sharpening(ctx, ctx->fixed_vector);
+
+ decode_gains(cur_subframe->vq_gain, ctx->fr_cur_mode,
+ &fixed_gain_factor, &ctx->pitch_gain[0]);
+
+ ctx->fixed_gain[0] =
+ ff_amr_set_fixed_gain(fixed_gain_factor,
+ ctx->celpm_ctx.dot_productf(ctx->fixed_vector,
+ ctx->fixed_vector,
+ AMRWB_SFR_SIZE) /
+ AMRWB_SFR_SIZE,
+ ctx->prediction_error,
+ ENERGY_MEAN, energy_pred_fac);
+
+ /* Calculate voice factor and store tilt for next subframe */
+ voice_fac = voice_factor(ctx->pitch_vector, ctx->pitch_gain[0],
+ ctx->fixed_vector, ctx->fixed_gain[0],
+ &ctx->celpm_ctx);
+ ctx->tilt_coef = voice_fac * 0.25 + 0.25;
+
+ /* Construct current excitation */
+ for (i = 0; i < AMRWB_SFR_SIZE; i++) {
+ ctx->excitation[i] *= ctx->pitch_gain[0];
+ ctx->excitation[i] += ctx->fixed_gain[0] * ctx->fixed_vector[i];
+ ctx->excitation[i] = truncf(ctx->excitation[i]);
+ }
+
+ /* Post-processing of excitation elements */
+ synth_fixed_gain = noise_enhancer(ctx->fixed_gain[0], &ctx->prev_tr_gain,
+ voice_fac, stab_fac);
+
+ synth_fixed_vector = anti_sparseness(ctx, ctx->fixed_vector,
+ spare_vector);
+
+ pitch_enhancer(synth_fixed_vector, voice_fac);
+
+ synthesis(ctx, ctx->lp_coef[sub], synth_exc, synth_fixed_gain,
+ synth_fixed_vector, &ctx->samples_az[LP_ORDER]);
+
+ /* Synthesis speech post-processing */
+ de_emphasis(&ctx->samples_up[UPS_MEM_SIZE],
+ &ctx->samples_az[LP_ORDER], PREEMPH_FAC, ctx->demph_mem);
+
+ ctx->acelpf_ctx.acelp_apply_order_2_transfer_function(&ctx->samples_up[UPS_MEM_SIZE],
+ &ctx->samples_up[UPS_MEM_SIZE], hpf_zeros, hpf_31_poles,
+ hpf_31_gain, ctx->hpf_31_mem, AMRWB_SFR_SIZE);
+
+ upsample_5_4(sub_buf, &ctx->samples_up[UPS_FIR_SIZE],
+ AMRWB_SFR_SIZE_16k, &ctx->celpm_ctx);
+
+ /* High frequency band (6.4 - 7.0 kHz) generation part */
+ ctx->acelpf_ctx.acelp_apply_order_2_transfer_function(hb_samples,
+ &ctx->samples_up[UPS_MEM_SIZE], hpf_zeros, hpf_400_poles,
+ hpf_400_gain, ctx->hpf_400_mem, AMRWB_SFR_SIZE);
+
+ hb_gain = find_hb_gain(ctx, hb_samples,
+ cur_subframe->hb_gain, cf->vad);
+
+ scaled_hb_excitation(ctx, hb_exc, synth_exc, hb_gain);
+
+ hb_synthesis(ctx, sub, &ctx->samples_hb[LP_ORDER_16k],
+ hb_exc, ctx->isf_cur, ctx->isf_past_final);
+
+ /* High-band post-processing filters */
+ hb_fir_filter(hb_samples, bpf_6_7_coef, ctx->bpf_6_7_mem,
+ &ctx->samples_hb[LP_ORDER_16k]);
+
+ if (ctx->fr_cur_mode == MODE_23k85)
+ hb_fir_filter(hb_samples, lpf_7_coef, ctx->lpf_7_mem,
+ hb_samples);
+
+ /* Add the low and high frequency bands */
+ for (i = 0; i < AMRWB_SFR_SIZE_16k; i++)
+ sub_buf[i] = (sub_buf[i] + hb_samples[i]) * (1.0f / (1 << 15));
+
+ /* Update buffers and history */
+ update_sub_state(ctx);
+ }
+
+ /* update state for next frame */
+ memcpy(ctx->isp_sub4_past, ctx->isp[3], LP_ORDER * sizeof(ctx->isp[3][0]));
+ memcpy(ctx->isf_past_final, ctx->isf_cur, LP_ORDER * sizeof(float));
+
+ *got_frame_ptr = 1;
+
+ return expected_fr_size;
+}
+
+AVCodec ff_amrwb_decoder = {
+ .name = "amrwb",
+ .long_name = NULL_IF_CONFIG_SMALL("AMR-WB (Adaptive Multi-Rate WideBand)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_AMR_WB,
+ .priv_data_size = sizeof(AMRWBContext),
+ .init = amrwb_decode_init,
+ .decode = amrwb_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+ .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_FLT,
+ AV_SAMPLE_FMT_NONE },
+};
diff --git a/ffmpeg-2-8-11/libavcodec/anm.c b/ffmpeg-2-8-12/libavcodec/anm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/anm.c
rename to ffmpeg-2-8-12/libavcodec/anm.c
diff --git a/ffmpeg-2-8-12/libavcodec/ansi.c b/ffmpeg-2-8-12/libavcodec/ansi.c
new file mode 100644
index 0000000..31405b4
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/ansi.c
@@ -0,0 +1,486 @@
+/*
+ * ASCII/ANSI art decoder
+ * Copyright (c) 2010 Peter Ross <pross at 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
+ * ASCII/ANSI art decoder
+ */
+
+#include "libavutil/common.h"
+#include "libavutil/frame.h"
+#include "libavutil/lfg.h"
+#include "libavutil/xga_font_data.h"
+#include "avcodec.h"
+#include "cga_data.h"
+#include "internal.h"
+
+#define ATTR_BOLD 0x01 /**< Bold/Bright-foreground (mode 1) */
+#define ATTR_FAINT 0x02 /**< Faint (mode 2) */
+#define ATTR_UNDERLINE 0x08 /**< Underline (mode 4) */
+#define ATTR_BLINK 0x10 /**< Blink/Bright-background (mode 5) */
+#define ATTR_REVERSE 0x40 /**< Reverse (mode 7) */
+#define ATTR_CONCEALED 0x80 /**< Concealed (mode 8) */
+
+#define DEFAULT_FG_COLOR 7 /**< CGA color index */
+#define DEFAULT_BG_COLOR 0
+#define DEFAULT_SCREEN_MODE 3 /**< 80x25 */
+
+#define FONT_WIDTH 8 /**< Font width */
+
+/** map ansi color index to cga palette index */
+static const uint8_t ansi_to_cga[16] = {
+ 0, 4, 2, 6, 1, 5, 3, 7, 8, 12, 10, 14, 9, 13, 11, 15
+};
+
+typedef struct AnsiContext {
+ AVFrame *frame;
+ int x; /**< x cursor position (pixels) */
+ int y; /**< y cursor position (pixels) */
+ int sx; /**< saved x cursor position (pixels) */
+ int sy; /**< saved y cursor position (pixels) */
+ const uint8_t* font; /**< font */
+ int font_height; /**< font height */
+ int attributes; /**< attribute flags */
+ int fg; /**< foreground color */
+ int bg; /**< background color */
+ int first_frame;
+
+ /* ansi parser state machine */
+ enum {
+ STATE_NORMAL = 0,
+ STATE_ESCAPE,
+ STATE_CODE,
+ STATE_MUSIC_PREAMBLE
+ } state;
+#define MAX_NB_ARGS 4
+ int args[MAX_NB_ARGS];
+ int nb_args; /**< number of arguments (may exceed MAX_NB_ARGS) */
+} AnsiContext;
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ AnsiContext *s = avctx->priv_data;
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
+ /* defaults */
+ s->font = avpriv_vga16_font;
+ s->font_height = 16;
+ s->fg = DEFAULT_FG_COLOR;
+ s->bg = DEFAULT_BG_COLOR;
+
+ if (!avctx->width || !avctx->height) {
+ int ret = ff_set_dimensions(avctx, 80 << 3, 25 << 4);
+ if (ret < 0)
+ return ret;
+ } else if (avctx->width % FONT_WIDTH || avctx->height % s->font_height) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid dimensions %d %d\n", avctx->width, avctx->height);
+ return AVERROR(EINVAL);
+ }
+
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static void set_palette(uint32_t *pal)
+{
+ int r, g, b;
+ memcpy(pal, ff_cga_palette, 16 * 4);
+ pal += 16;
+#define COLOR(x) ((x) * 40 + 55)
+ for (r = 0; r < 6; r++)
+ for (g = 0; g < 6; g++)
+ for (b = 0; b < 6; b++)
+ *pal++ = 0xFF000000 | (COLOR(r) << 16) | (COLOR(g) << 8) | COLOR(b);
+#define GRAY(x) ((x) * 10 + 8)
+ for (g = 0; g < 24; g++)
+ *pal++ = 0xFF000000 | (GRAY(g) << 16) | (GRAY(g) << 8) | GRAY(g);
+}
+
+static void hscroll(AVCodecContext *avctx)
+{
+ AnsiContext *s = avctx->priv_data;
+ int i;
+
+ if (s->y <= avctx->height - 2*s->font_height) {
+ s->y += s->font_height;
+ return;
+ }
+
+ i = 0;
+ for (; i < avctx->height - s->font_height; i++)
+ memcpy(s->frame->data[0] + i * s->frame->linesize[0],
+ s->frame->data[0] + (i + s->font_height) * s->frame->linesize[0],
+ avctx->width);
+ for (; i < avctx->height; i++)
+ memset(s->frame->data[0] + i * s->frame->linesize[0],
+ DEFAULT_BG_COLOR, avctx->width);
+}
+
+static void erase_line(AVCodecContext * avctx, int xoffset, int xlength)
+{
+ AnsiContext *s = avctx->priv_data;
+ int i;
+ for (i = 0; i < s->font_height; i++)
+ memset(s->frame->data[0] + (s->y + i)*s->frame->linesize[0] + xoffset,
+ DEFAULT_BG_COLOR, xlength);
+}
+
+static void erase_screen(AVCodecContext *avctx)
+{
+ AnsiContext *s = avctx->priv_data;
+ int i;
+ for (i = 0; i < avctx->height; i++)
+ memset(s->frame->data[0] + i * s->frame->linesize[0], DEFAULT_BG_COLOR, avctx->width);
+ s->x = s->y = 0;
+}
+
+/**
+ * Draw character to screen
+ */
+static void draw_char(AVCodecContext *avctx, int c)
+{
+ AnsiContext *s = avctx->priv_data;
+ int fg = s->fg;
+ int bg = s->bg;
+
+ if ((s->attributes & ATTR_BOLD))
+ fg += 8;
+ if ((s->attributes & ATTR_BLINK))
+ bg += 8;
+ if ((s->attributes & ATTR_REVERSE))
+ FFSWAP(int, fg, bg);
+ if ((s->attributes & ATTR_CONCEALED))
+ fg = bg;
+ ff_draw_pc_font(s->frame->data[0] + s->y * s->frame->linesize[0] + s->x,
+ s->frame->linesize[0], s->font, s->font_height, c, fg, bg);
+ s->x += FONT_WIDTH;
+ if (s->x > avctx->width - FONT_WIDTH) {
+ s->x = 0;
+ hscroll(avctx);
+ }
+}
+
+/**
+ * Execute ANSI escape code
+ * @return 0 on success, negative on error
+ */
+static int execute_code(AVCodecContext * avctx, int c)
+{
+ AnsiContext *s = avctx->priv_data;
+ int ret, i;
+ int width = avctx->width;
+ int height = avctx->height;
+
+ switch(c) {
+ case 'A': //Cursor Up
+ s->y = FFMAX(s->y - (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), 0);
+ break;
+ case 'B': //Cursor Down
+ s->y = FFMIN(s->y + (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), avctx->height - s->font_height);
+ break;
+ case 'C': //Cursor Right
+ s->x = FFMIN(s->x + (s->nb_args > 0 ? s->args[0]*FONT_WIDTH : FONT_WIDTH), avctx->width - FONT_WIDTH);
+ break;
+ case 'D': //Cursor Left
+ s->x = FFMAX(s->x - (s->nb_args > 0 ? s->args[0]*FONT_WIDTH : FONT_WIDTH), 0);
+ break;
+ case 'H': //Cursor Position
+ case 'f': //Horizontal and Vertical Position
+ s->y = s->nb_args > 0 ? av_clip((s->args[0] - 1)*s->font_height, 0, avctx->height - s->font_height) : 0;
+ s->x = s->nb_args > 1 ? av_clip((s->args[1] - 1)*FONT_WIDTH, 0, avctx->width - FONT_WIDTH) : 0;
+ break;
+ case 'h': //set creen mode
+ case 'l': //reset screen mode
+ if (s->nb_args < 2)
+ s->args[0] = DEFAULT_SCREEN_MODE;
+ switch(s->args[0]) {
+ case 0: case 1: case 4: case 5: case 13: case 19: //320x200 (25 rows)
+ s->font = avpriv_cga_font;
+ s->font_height = 8;
+ width = 40<<3;
+ height = 25<<3;
+ break;
+ case 2: case 3: //640x400 (25 rows)
+ s->font = avpriv_vga16_font;
+ s->font_height = 16;
+ width = 80<<3;
+ height = 25<<4;
+ break;
+ case 6: case 14: //640x200 (25 rows)
+ s->font = avpriv_cga_font;
+ s->font_height = 8;
+ width = 80<<3;
+ height = 25<<3;
+ break;
+ case 7: //set line wrapping
+ break;
+ case 15: case 16: //640x350 (43 rows)
+ s->font = avpriv_cga_font;
+ s->font_height = 8;
+ width = 80<<3;
+ height = 43<<3;
+ break;
+ case 17: case 18: //640x480 (60 rows)
+ s->font = avpriv_cga_font;
+ s->font_height = 8;
+ width = 80<<3;
+ height = 60<<4;
+ break;
+ default:
+ avpriv_request_sample(avctx, "Unsupported screen mode");
+ }
+ s->x = av_clip(s->x, 0, width - FONT_WIDTH);
+ s->y = av_clip(s->y, 0, height - s->font_height);
+ if (width != avctx->width || height != avctx->height) {
+ av_frame_unref(s->frame);
+ ret = ff_set_dimensions(avctx, width, height);
+ if (ret < 0)
+ return ret;
+ if ((ret = ff_get_buffer(avctx, s->frame,
+ AV_GET_BUFFER_FLAG_REF)) < 0)
+ return ret;
+ s->frame->pict_type = AV_PICTURE_TYPE_I;
+ s->frame->palette_has_changed = 1;
+ set_palette((uint32_t *)s->frame->data[1]);
+ erase_screen(avctx);
+ } else if (c == 'l') {
+ erase_screen(avctx);
+ }
+ break;
+ case 'J': //Erase in Page
+ switch (s->args[0]) {
+ case 0:
+ erase_line(avctx, s->x, avctx->width - s->x);
+ if (s->y < avctx->height - s->font_height)
+ memset(s->frame->data[0] + (s->y + s->font_height)*s->frame->linesize[0],
+ DEFAULT_BG_COLOR, (avctx->height - s->y - s->font_height)*s->frame->linesize[0]);
+ break;
+ case 1:
+ erase_line(avctx, 0, s->x);
+ if (s->y > 0)
+ memset(s->frame->data[0], DEFAULT_BG_COLOR, s->y * s->frame->linesize[0]);
+ break;
+ case 2:
+ erase_screen(avctx);
+ }
+ break;
+ case 'K': //Erase in Line
+ switch(s->args[0]) {
+ case 0:
+ erase_line(avctx, s->x, avctx->width - s->x);
+ break;
+ case 1:
+ erase_line(avctx, 0, s->x);
+ break;
+ case 2:
+ erase_line(avctx, 0, avctx->width);
+ }
+ break;
+ case 'm': //Select Graphics Rendition
+ if (s->nb_args == 0) {
+ s->nb_args = 1;
+ s->args[0] = 0;
+ }
+ for (i = 0; i < FFMIN(s->nb_args, MAX_NB_ARGS); i++) {
+ int m = s->args[i];
+ if (m == 0) {
+ s->attributes = 0;
+ s->fg = DEFAULT_FG_COLOR;
+ s->bg = DEFAULT_BG_COLOR;
+ } else if (m == 1 || m == 2 || m == 4 || m == 5 || m == 7 || m == 8) {
+ s->attributes |= 1 << (m - 1);
+ } else if (m >= 30 && m <= 37) {
+ s->fg = ansi_to_cga[m - 30];
+ } else if (m == 38 && i + 2 < FFMIN(s->nb_args, MAX_NB_ARGS) && s->args[i + 1] == 5 && s->args[i + 2] < 256) {
+ int index = s->args[i + 2];
+ s->fg = index < 16 ? ansi_to_cga[index] : index;
+ i += 2;
+ } else if (m == 39) {
+ s->fg = ansi_to_cga[DEFAULT_FG_COLOR];
+ } else if (m >= 40 && m <= 47) {
+ s->bg = ansi_to_cga[m - 40];
+ } else if (m == 48 && i + 2 < FFMIN(s->nb_args, MAX_NB_ARGS) && s->args[i + 1] == 5 && s->args[i + 2] < 256) {
+ int index = s->args[i + 2];
+ s->bg = index < 16 ? ansi_to_cga[index] : index;
+ i += 2;
+ } else if (m == 49) {
+ s->fg = ansi_to_cga[DEFAULT_BG_COLOR];
+ } else {
+ avpriv_request_sample(avctx, "Unsupported rendition parameter");
+ }
+ }
+ break;
+ case 'n': //Device Status Report
+ case 'R': //report current line and column
+ /* ignore */
+ break;
+ case 's': //Save Cursor Position
+ s->sx = s->x;
+ s->sy = s->y;
+ break;
+ case 'u': //Restore Cursor Position
+ s->x = av_clip(s->sx, 0, avctx->width - FONT_WIDTH);
+ s->y = av_clip(s->sy, 0, avctx->height - s->font_height);
+ break;
+ default:
+ avpriv_request_sample(avctx, "Unknown escape code");
+ break;
+ }
+ s->x = av_clip(s->x, 0, avctx->width - FONT_WIDTH);
+ s->y = av_clip(s->y, 0, avctx->height - s->font_height);
+ return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ AnsiContext *s = avctx->priv_data;
+ uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ const uint8_t *buf_end = buf+buf_size;
+ int ret, i, count;
+
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
+ return ret;
+ if (!avctx->frame_number) {
+ for (i=0; i<avctx->height; i++)
+ memset(s->frame->data[0]+ i*s->frame->linesize[0], 0, avctx->width);
+ memset(s->frame->data[1], 0, AVPALETTE_SIZE);
+ }
+
+ s->frame->pict_type = AV_PICTURE_TYPE_I;
+ s->frame->palette_has_changed = 1;
+ set_palette((uint32_t *)s->frame->data[1]);
+ if (!s->first_frame) {
+ erase_screen(avctx);
+ s->first_frame = 1;
+ }
+
+ while(buf < buf_end) {
+ switch(s->state) {
+ case STATE_NORMAL:
+ switch (buf[0]) {
+ case 0x00: //NUL
+ case 0x07: //BEL
+ case 0x1A: //SUB
+ /* ignore */
+ break;
+ case 0x08: //BS
+ s->x = FFMAX(s->x - 1, 0);
+ break;
+ case 0x09: //HT
+ i = s->x / FONT_WIDTH;
+ count = ((i + 8) & ~7) - i;
+ for (i = 0; i < count; i++)
+ draw_char(avctx, ' ');
+ break;
+ case 0x0A: //LF
+ hscroll(avctx);
+ case 0x0D: //CR
+ s->x = 0;
+ break;
+ case 0x0C: //FF
+ erase_screen(avctx);
+ break;
+ case 0x1B: //ESC
+ s->state = STATE_ESCAPE;
+ break;
+ default:
+ draw_char(avctx, buf[0]);
+ }
+ break;
+ case STATE_ESCAPE:
+ if (buf[0] == '[') {
+ s->state = STATE_CODE;
+ s->nb_args = 0;
+ s->args[0] = -1;
+ } else {
+ s->state = STATE_NORMAL;
+ draw_char(avctx, 0x1B);
+ continue;
+ }
+ break;
+ case STATE_CODE:
+ switch(buf[0]) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (s->nb_args < MAX_NB_ARGS && s->args[s->nb_args] < 6553)
+ s->args[s->nb_args] = FFMAX(s->args[s->nb_args], 0) * 10 + buf[0] - '0';
+ break;
+ case ';':
+ s->nb_args++;
+ if (s->nb_args < MAX_NB_ARGS)
+ s->args[s->nb_args] = 0;
+ break;
+ case 'M':
+ s->state = STATE_MUSIC_PREAMBLE;
+ break;
+ case '=': case '?':
+ /* ignore */
+ break;
+ default:
+ if (s->nb_args > MAX_NB_ARGS)
+ av_log(avctx, AV_LOG_WARNING, "args overflow (%i)\n", s->nb_args);
+ if (s->nb_args < MAX_NB_ARGS && s->args[s->nb_args] >= 0)
+ s->nb_args++;
+ if ((ret = execute_code(avctx, buf[0])) < 0)
+ return ret;
+ s->state = STATE_NORMAL;
+ }
+ break;
+ case STATE_MUSIC_PREAMBLE:
+ if (buf[0] == 0x0E || buf[0] == 0x1B)
+ s->state = STATE_NORMAL;
+ /* ignore music data */
+ break;
+ }
+ buf++;
+ }
+
+ *got_frame = 1;
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
+ return ret;
+ return buf_size;
+}
+
+static av_cold int decode_close(AVCodecContext *avctx)
+{
+ AnsiContext *s = avctx->priv_data;
+
+ av_frame_free(&s->frame);
+ return 0;
+}
+
+AVCodec ff_ansi_decoder = {
+ .name = "ansi",
+ .long_name = NULL_IF_CONFIG_SMALL("ASCII/ANSI art"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_ANSI,
+ .priv_data_size = sizeof(AnsiContext),
+ .init = decode_init,
+ .close = decode_close,
+ .decode = decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/apedec.c b/ffmpeg-2-8-12/libavcodec/apedec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/apedec.c
rename to ffmpeg-2-8-12/libavcodec/apedec.c
diff --git a/ffmpeg-2-8-11/libavcodec/apng.h b/ffmpeg-2-8-12/libavcodec/apng.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/apng.h
rename to ffmpeg-2-8-12/libavcodec/apng.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/Makefile b/ffmpeg-2-8-12/libavcodec/arm/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/Makefile
rename to ffmpeg-2-8-12/libavcodec/arm/Makefile
diff --git a/ffmpeg-2-8-11/libavcodec/arm/aac.h b/ffmpeg-2-8-12/libavcodec/arm/aac.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/aac.h
rename to ffmpeg-2-8-12/libavcodec/arm/aac.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/aacpsdsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/aacpsdsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/aacpsdsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/aacpsdsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/aacpsdsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/aacpsdsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/aacpsdsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/aacpsdsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/ac3dsp_arm.S b/ffmpeg-2-8-12/libavcodec/arm/ac3dsp_arm.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/ac3dsp_arm.S
rename to ffmpeg-2-8-12/libavcodec/arm/ac3dsp_arm.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/ac3dsp_armv6.S b/ffmpeg-2-8-12/libavcodec/arm/ac3dsp_armv6.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/ac3dsp_armv6.S
rename to ffmpeg-2-8-12/libavcodec/arm/ac3dsp_armv6.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/ac3dsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/ac3dsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/ac3dsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/ac3dsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/ac3dsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/ac3dsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/ac3dsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/ac3dsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/asm-offsets.h b/ffmpeg-2-8-12/libavcodec/arm/asm-offsets.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/asm-offsets.h
rename to ffmpeg-2-8-12/libavcodec/arm/asm-offsets.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/audiodsp_arm.h b/ffmpeg-2-8-12/libavcodec/arm/audiodsp_arm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/audiodsp_arm.h
rename to ffmpeg-2-8-12/libavcodec/arm/audiodsp_arm.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/audiodsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/audiodsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/audiodsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/audiodsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/audiodsp_init_neon.c b/ffmpeg-2-8-12/libavcodec/arm/audiodsp_init_neon.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/audiodsp_init_neon.c
rename to ffmpeg-2-8-12/libavcodec/arm/audiodsp_init_neon.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/audiodsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/audiodsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/audiodsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/audiodsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/blockdsp_arm.h b/ffmpeg-2-8-12/libavcodec/arm/blockdsp_arm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/blockdsp_arm.h
rename to ffmpeg-2-8-12/libavcodec/arm/blockdsp_arm.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/blockdsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/blockdsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/blockdsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/blockdsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/blockdsp_init_neon.c b/ffmpeg-2-8-12/libavcodec/arm/blockdsp_init_neon.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/blockdsp_init_neon.c
rename to ffmpeg-2-8-12/libavcodec/arm/blockdsp_init_neon.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/blockdsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/blockdsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/blockdsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/blockdsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/cabac.h b/ffmpeg-2-8-12/libavcodec/arm/cabac.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/cabac.h
rename to ffmpeg-2-8-12/libavcodec/arm/cabac.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/dca.h b/ffmpeg-2-8-12/libavcodec/arm/dca.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/dca.h
rename to ffmpeg-2-8-12/libavcodec/arm/dca.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/dcadsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/dcadsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/dcadsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/dcadsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/dcadsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/dcadsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/dcadsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/dcadsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/dcadsp_vfp.S b/ffmpeg-2-8-12/libavcodec/arm/dcadsp_vfp.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/dcadsp_vfp.S
rename to ffmpeg-2-8-12/libavcodec/arm/dcadsp_vfp.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/dct-test.c b/ffmpeg-2-8-12/libavcodec/arm/dct-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/dct-test.c
rename to ffmpeg-2-8-12/libavcodec/arm/dct-test.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/fft_fixed_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/fft_fixed_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/fft_fixed_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/fft_fixed_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/fft_fixed_neon.S b/ffmpeg-2-8-12/libavcodec/arm/fft_fixed_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/fft_fixed_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/fft_fixed_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/fft_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/fft_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/fft_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/fft_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/fft_neon.S b/ffmpeg-2-8-12/libavcodec/arm/fft_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/fft_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/fft_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/fft_vfp.S b/ffmpeg-2-8-12/libavcodec/arm/fft_vfp.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/fft_vfp.S
rename to ffmpeg-2-8-12/libavcodec/arm/fft_vfp.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/flacdsp_arm.S b/ffmpeg-2-8-12/libavcodec/arm/flacdsp_arm.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/flacdsp_arm.S
rename to ffmpeg-2-8-12/libavcodec/arm/flacdsp_arm.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/flacdsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/flacdsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/flacdsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/flacdsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/fmtconvert_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/fmtconvert_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/fmtconvert_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/fmtconvert_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/fmtconvert_neon.S b/ffmpeg-2-8-12/libavcodec/arm/fmtconvert_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/fmtconvert_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/fmtconvert_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/fmtconvert_vfp.S b/ffmpeg-2-8-12/libavcodec/arm/fmtconvert_vfp.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/fmtconvert_vfp.S
rename to ffmpeg-2-8-12/libavcodec/arm/fmtconvert_vfp.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/g722dsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/g722dsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/g722dsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/g722dsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/g722dsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/g722dsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/g722dsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/g722dsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/h264chroma_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/h264chroma_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/h264chroma_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/h264chroma_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/h264cmc_neon.S b/ffmpeg-2-8-12/libavcodec/arm/h264cmc_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/h264cmc_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/h264cmc_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/h264dsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/h264dsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/h264dsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/h264dsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/h264dsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/h264dsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/h264dsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/h264dsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/h264idct_neon.S b/ffmpeg-2-8-12/libavcodec/arm/h264idct_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/h264idct_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/h264idct_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/h264pred_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/h264pred_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/h264pred_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/h264pred_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/h264pred_neon.S b/ffmpeg-2-8-12/libavcodec/arm/h264pred_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/h264pred_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/h264pred_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/h264qpel_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/h264qpel_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/h264qpel_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/h264qpel_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/h264qpel_neon.S b/ffmpeg-2-8-12/libavcodec/arm/h264qpel_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/h264qpel_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/h264qpel_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/hevcdsp_arm.h b/ffmpeg-2-8-12/libavcodec/arm/hevcdsp_arm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/hevcdsp_arm.h
rename to ffmpeg-2-8-12/libavcodec/arm/hevcdsp_arm.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/hevcdsp_deblock_neon.S b/ffmpeg-2-8-12/libavcodec/arm/hevcdsp_deblock_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/hevcdsp_deblock_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/hevcdsp_deblock_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/hevcdsp_idct_neon.S b/ffmpeg-2-8-12/libavcodec/arm/hevcdsp_idct_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/hevcdsp_idct_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/hevcdsp_idct_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/hevcdsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/hevcdsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/hevcdsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/hevcdsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/hevcdsp_init_neon.c b/ffmpeg-2-8-12/libavcodec/arm/hevcdsp_init_neon.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/hevcdsp_init_neon.c
rename to ffmpeg-2-8-12/libavcodec/arm/hevcdsp_init_neon.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/hevcdsp_qpel_neon.S b/ffmpeg-2-8-12/libavcodec/arm/hevcdsp_qpel_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/hevcdsp_qpel_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/hevcdsp_qpel_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/hpeldsp_arm.S b/ffmpeg-2-8-12/libavcodec/arm/hpeldsp_arm.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/hpeldsp_arm.S
rename to ffmpeg-2-8-12/libavcodec/arm/hpeldsp_arm.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/hpeldsp_arm.h b/ffmpeg-2-8-12/libavcodec/arm/hpeldsp_arm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/hpeldsp_arm.h
rename to ffmpeg-2-8-12/libavcodec/arm/hpeldsp_arm.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/hpeldsp_armv6.S b/ffmpeg-2-8-12/libavcodec/arm/hpeldsp_armv6.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/hpeldsp_armv6.S
rename to ffmpeg-2-8-12/libavcodec/arm/hpeldsp_armv6.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/hpeldsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/hpeldsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/hpeldsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/hpeldsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/hpeldsp_init_armv6.c b/ffmpeg-2-8-12/libavcodec/arm/hpeldsp_init_armv6.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/hpeldsp_init_armv6.c
rename to ffmpeg-2-8-12/libavcodec/arm/hpeldsp_init_armv6.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/hpeldsp_init_neon.c b/ffmpeg-2-8-12/libavcodec/arm/hpeldsp_init_neon.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/hpeldsp_init_neon.c
rename to ffmpeg-2-8-12/libavcodec/arm/hpeldsp_init_neon.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/hpeldsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/hpeldsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/hpeldsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/hpeldsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/idct.h b/ffmpeg-2-8-12/libavcodec/arm/idct.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/idct.h
rename to ffmpeg-2-8-12/libavcodec/arm/idct.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/idctdsp_arm.S b/ffmpeg-2-8-12/libavcodec/arm/idctdsp_arm.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/idctdsp_arm.S
rename to ffmpeg-2-8-12/libavcodec/arm/idctdsp_arm.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/idctdsp_arm.h b/ffmpeg-2-8-12/libavcodec/arm/idctdsp_arm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/idctdsp_arm.h
rename to ffmpeg-2-8-12/libavcodec/arm/idctdsp_arm.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/idctdsp_armv6.S b/ffmpeg-2-8-12/libavcodec/arm/idctdsp_armv6.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/idctdsp_armv6.S
rename to ffmpeg-2-8-12/libavcodec/arm/idctdsp_armv6.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/idctdsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/idctdsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/idctdsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/idctdsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/idctdsp_init_armv5te.c b/ffmpeg-2-8-12/libavcodec/arm/idctdsp_init_armv5te.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/idctdsp_init_armv5te.c
rename to ffmpeg-2-8-12/libavcodec/arm/idctdsp_init_armv5te.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/idctdsp_init_armv6.c b/ffmpeg-2-8-12/libavcodec/arm/idctdsp_init_armv6.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/idctdsp_init_armv6.c
rename to ffmpeg-2-8-12/libavcodec/arm/idctdsp_init_armv6.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/idctdsp_init_neon.c b/ffmpeg-2-8-12/libavcodec/arm/idctdsp_init_neon.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/idctdsp_init_neon.c
rename to ffmpeg-2-8-12/libavcodec/arm/idctdsp_init_neon.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/idctdsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/idctdsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/idctdsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/idctdsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/int_neon.S b/ffmpeg-2-8-12/libavcodec/arm/int_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/int_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/int_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/jrevdct_arm.S b/ffmpeg-2-8-12/libavcodec/arm/jrevdct_arm.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/jrevdct_arm.S
rename to ffmpeg-2-8-12/libavcodec/arm/jrevdct_arm.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/lossless_audiodsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/lossless_audiodsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/lossless_audiodsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/lossless_audiodsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/lossless_audiodsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/lossless_audiodsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/lossless_audiodsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/lossless_audiodsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mathops.h b/ffmpeg-2-8-12/libavcodec/arm/mathops.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mathops.h
rename to ffmpeg-2-8-12/libavcodec/arm/mathops.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mdct_fixed_neon.S b/ffmpeg-2-8-12/libavcodec/arm/mdct_fixed_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mdct_fixed_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/mdct_fixed_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mdct_neon.S b/ffmpeg-2-8-12/libavcodec/arm/mdct_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mdct_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/mdct_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mdct_vfp.S b/ffmpeg-2-8-12/libavcodec/arm/mdct_vfp.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mdct_vfp.S
rename to ffmpeg-2-8-12/libavcodec/arm/mdct_vfp.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/me_cmp_armv6.S b/ffmpeg-2-8-12/libavcodec/arm/me_cmp_armv6.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/me_cmp_armv6.S
rename to ffmpeg-2-8-12/libavcodec/arm/me_cmp_armv6.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/me_cmp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/me_cmp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/me_cmp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/me_cmp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mlpdsp_armv5te.S b/ffmpeg-2-8-12/libavcodec/arm/mlpdsp_armv5te.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mlpdsp_armv5te.S
rename to ffmpeg-2-8-12/libavcodec/arm/mlpdsp_armv5te.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mlpdsp_armv6.S b/ffmpeg-2-8-12/libavcodec/arm/mlpdsp_armv6.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mlpdsp_armv6.S
rename to ffmpeg-2-8-12/libavcodec/arm/mlpdsp_armv6.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mlpdsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/mlpdsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mlpdsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/mlpdsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mpegaudiodsp_fixed_armv6.S b/ffmpeg-2-8-12/libavcodec/arm/mpegaudiodsp_fixed_armv6.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mpegaudiodsp_fixed_armv6.S
rename to ffmpeg-2-8-12/libavcodec/arm/mpegaudiodsp_fixed_armv6.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mpegaudiodsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/mpegaudiodsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mpegaudiodsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/mpegaudiodsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mpegvideo_arm.c b/ffmpeg-2-8-12/libavcodec/arm/mpegvideo_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mpegvideo_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/mpegvideo_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mpegvideo_arm.h b/ffmpeg-2-8-12/libavcodec/arm/mpegvideo_arm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mpegvideo_arm.h
rename to ffmpeg-2-8-12/libavcodec/arm/mpegvideo_arm.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mpegvideo_armv5te.c b/ffmpeg-2-8-12/libavcodec/arm/mpegvideo_armv5te.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mpegvideo_armv5te.c
rename to ffmpeg-2-8-12/libavcodec/arm/mpegvideo_armv5te.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mpegvideo_armv5te_s.S b/ffmpeg-2-8-12/libavcodec/arm/mpegvideo_armv5te_s.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mpegvideo_armv5te_s.S
rename to ffmpeg-2-8-12/libavcodec/arm/mpegvideo_armv5te_s.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mpegvideo_neon.S b/ffmpeg-2-8-12/libavcodec/arm/mpegvideo_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mpegvideo_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/mpegvideo_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mpegvideoencdsp_armv6.S b/ffmpeg-2-8-12/libavcodec/arm/mpegvideoencdsp_armv6.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mpegvideoencdsp_armv6.S
rename to ffmpeg-2-8-12/libavcodec/arm/mpegvideoencdsp_armv6.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/mpegvideoencdsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/mpegvideoencdsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/mpegvideoencdsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/mpegvideoencdsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/neon.S b/ffmpeg-2-8-12/libavcodec/arm/neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/neontest.c b/ffmpeg-2-8-12/libavcodec/arm/neontest.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/neontest.c
rename to ffmpeg-2-8-12/libavcodec/arm/neontest.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/pixblockdsp_armv6.S b/ffmpeg-2-8-12/libavcodec/arm/pixblockdsp_armv6.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/pixblockdsp_armv6.S
rename to ffmpeg-2-8-12/libavcodec/arm/pixblockdsp_armv6.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/pixblockdsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/pixblockdsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/pixblockdsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/pixblockdsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/rdft_neon.S b/ffmpeg-2-8-12/libavcodec/arm/rdft_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/rdft_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/rdft_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/rv34dsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/rv34dsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/rv34dsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/rv34dsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/rv34dsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/rv34dsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/rv34dsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/rv34dsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/rv40dsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/rv40dsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/rv40dsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/rv40dsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/rv40dsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/rv40dsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/rv40dsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/rv40dsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/sbrdsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/sbrdsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/sbrdsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/sbrdsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/sbrdsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/sbrdsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/sbrdsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/sbrdsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/simple_idct_arm.S b/ffmpeg-2-8-12/libavcodec/arm/simple_idct_arm.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/simple_idct_arm.S
rename to ffmpeg-2-8-12/libavcodec/arm/simple_idct_arm.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/simple_idct_armv5te.S b/ffmpeg-2-8-12/libavcodec/arm/simple_idct_armv5te.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/simple_idct_armv5te.S
rename to ffmpeg-2-8-12/libavcodec/arm/simple_idct_armv5te.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/simple_idct_armv6.S b/ffmpeg-2-8-12/libavcodec/arm/simple_idct_armv6.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/simple_idct_armv6.S
rename to ffmpeg-2-8-12/libavcodec/arm/simple_idct_armv6.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/simple_idct_neon.S b/ffmpeg-2-8-12/libavcodec/arm/simple_idct_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/simple_idct_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/simple_idct_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/startcode.h b/ffmpeg-2-8-12/libavcodec/arm/startcode.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/startcode.h
rename to ffmpeg-2-8-12/libavcodec/arm/startcode.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/startcode_armv6.S b/ffmpeg-2-8-12/libavcodec/arm/startcode_armv6.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/startcode_armv6.S
rename to ffmpeg-2-8-12/libavcodec/arm/startcode_armv6.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/synth_filter_neon.S b/ffmpeg-2-8-12/libavcodec/arm/synth_filter_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/synth_filter_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/synth_filter_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/synth_filter_vfp.S b/ffmpeg-2-8-12/libavcodec/arm/synth_filter_vfp.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/synth_filter_vfp.S
rename to ffmpeg-2-8-12/libavcodec/arm/synth_filter_vfp.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vc1dsp.h b/ffmpeg-2-8-12/libavcodec/arm/vc1dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vc1dsp.h
rename to ffmpeg-2-8-12/libavcodec/arm/vc1dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vc1dsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/vc1dsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vc1dsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/vc1dsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vc1dsp_init_neon.c b/ffmpeg-2-8-12/libavcodec/arm/vc1dsp_init_neon.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vc1dsp_init_neon.c
rename to ffmpeg-2-8-12/libavcodec/arm/vc1dsp_init_neon.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vc1dsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/vc1dsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vc1dsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/vc1dsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/videodsp_arm.h b/ffmpeg-2-8-12/libavcodec/arm/videodsp_arm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/videodsp_arm.h
rename to ffmpeg-2-8-12/libavcodec/arm/videodsp_arm.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/videodsp_armv5te.S b/ffmpeg-2-8-12/libavcodec/arm/videodsp_armv5te.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/videodsp_armv5te.S
rename to ffmpeg-2-8-12/libavcodec/arm/videodsp_armv5te.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/videodsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/videodsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/videodsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/videodsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/videodsp_init_armv5te.c b/ffmpeg-2-8-12/libavcodec/arm/videodsp_init_armv5te.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/videodsp_init_armv5te.c
rename to ffmpeg-2-8-12/libavcodec/arm/videodsp_init_armv5te.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vorbisdsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/vorbisdsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vorbisdsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/vorbisdsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vorbisdsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/vorbisdsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vorbisdsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/vorbisdsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vp3dsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/vp3dsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vp3dsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/vp3dsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vp3dsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/vp3dsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vp3dsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/vp3dsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vp56_arith.h b/ffmpeg-2-8-12/libavcodec/arm/vp56_arith.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vp56_arith.h
rename to ffmpeg-2-8-12/libavcodec/arm/vp56_arith.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vp6dsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/vp6dsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vp6dsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/vp6dsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vp6dsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/vp6dsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vp6dsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/vp6dsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vp8.h b/ffmpeg-2-8-12/libavcodec/arm/vp8.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vp8.h
rename to ffmpeg-2-8-12/libavcodec/arm/vp8.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vp8_armv6.S b/ffmpeg-2-8-12/libavcodec/arm/vp8_armv6.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vp8_armv6.S
rename to ffmpeg-2-8-12/libavcodec/arm/vp8_armv6.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vp8dsp.h b/ffmpeg-2-8-12/libavcodec/arm/vp8dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vp8dsp.h
rename to ffmpeg-2-8-12/libavcodec/arm/vp8dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vp8dsp_armv6.S b/ffmpeg-2-8-12/libavcodec/arm/vp8dsp_armv6.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vp8dsp_armv6.S
rename to ffmpeg-2-8-12/libavcodec/arm/vp8dsp_armv6.S
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vp8dsp_init_arm.c b/ffmpeg-2-8-12/libavcodec/arm/vp8dsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vp8dsp_init_arm.c
rename to ffmpeg-2-8-12/libavcodec/arm/vp8dsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vp8dsp_init_armv6.c b/ffmpeg-2-8-12/libavcodec/arm/vp8dsp_init_armv6.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vp8dsp_init_armv6.c
rename to ffmpeg-2-8-12/libavcodec/arm/vp8dsp_init_armv6.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vp8dsp_init_neon.c b/ffmpeg-2-8-12/libavcodec/arm/vp8dsp_init_neon.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vp8dsp_init_neon.c
rename to ffmpeg-2-8-12/libavcodec/arm/vp8dsp_init_neon.c
diff --git a/ffmpeg-2-8-11/libavcodec/arm/vp8dsp_neon.S b/ffmpeg-2-8-12/libavcodec/arm/vp8dsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/arm/vp8dsp_neon.S
rename to ffmpeg-2-8-12/libavcodec/arm/vp8dsp_neon.S
diff --git a/ffmpeg-2-8-11/libavcodec/ass.c b/ffmpeg-2-8-12/libavcodec/ass.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ass.c
rename to ffmpeg-2-8-12/libavcodec/ass.c
diff --git a/ffmpeg-2-8-11/libavcodec/ass.h b/ffmpeg-2-8-12/libavcodec/ass.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ass.h
rename to ffmpeg-2-8-12/libavcodec/ass.h
diff --git a/ffmpeg-2-8-11/libavcodec/ass_split.c b/ffmpeg-2-8-12/libavcodec/ass_split.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ass_split.c
rename to ffmpeg-2-8-12/libavcodec/ass_split.c
diff --git a/ffmpeg-2-8-11/libavcodec/ass_split.h b/ffmpeg-2-8-12/libavcodec/ass_split.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ass_split.h
rename to ffmpeg-2-8-12/libavcodec/ass_split.h
diff --git a/ffmpeg-2-8-11/libavcodec/assdec.c b/ffmpeg-2-8-12/libavcodec/assdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/assdec.c
rename to ffmpeg-2-8-12/libavcodec/assdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/assenc.c b/ffmpeg-2-8-12/libavcodec/assenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/assenc.c
rename to ffmpeg-2-8-12/libavcodec/assenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/asv.c b/ffmpeg-2-8-12/libavcodec/asv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/asv.c
rename to ffmpeg-2-8-12/libavcodec/asv.c
diff --git a/ffmpeg-2-8-11/libavcodec/asv.h b/ffmpeg-2-8-12/libavcodec/asv.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/asv.h
rename to ffmpeg-2-8-12/libavcodec/asv.h
diff --git a/ffmpeg-2-8-11/libavcodec/asvdec.c b/ffmpeg-2-8-12/libavcodec/asvdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/asvdec.c
rename to ffmpeg-2-8-12/libavcodec/asvdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/asvenc.c b/ffmpeg-2-8-12/libavcodec/asvenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/asvenc.c
rename to ffmpeg-2-8-12/libavcodec/asvenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/atrac.c b/ffmpeg-2-8-12/libavcodec/atrac.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/atrac.c
rename to ffmpeg-2-8-12/libavcodec/atrac.c
diff --git a/ffmpeg-2-8-11/libavcodec/atrac.h b/ffmpeg-2-8-12/libavcodec/atrac.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/atrac.h
rename to ffmpeg-2-8-12/libavcodec/atrac.h
diff --git a/ffmpeg-2-8-11/libavcodec/atrac1.c b/ffmpeg-2-8-12/libavcodec/atrac1.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/atrac1.c
rename to ffmpeg-2-8-12/libavcodec/atrac1.c
diff --git a/ffmpeg-2-8-11/libavcodec/atrac1data.h b/ffmpeg-2-8-12/libavcodec/atrac1data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/atrac1data.h
rename to ffmpeg-2-8-12/libavcodec/atrac1data.h
diff --git a/ffmpeg-2-8-11/libavcodec/atrac3.c b/ffmpeg-2-8-12/libavcodec/atrac3.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/atrac3.c
rename to ffmpeg-2-8-12/libavcodec/atrac3.c
diff --git a/ffmpeg-2-8-11/libavcodec/atrac3data.h b/ffmpeg-2-8-12/libavcodec/atrac3data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/atrac3data.h
rename to ffmpeg-2-8-12/libavcodec/atrac3data.h
diff --git a/ffmpeg-2-8-11/libavcodec/atrac3plus.c b/ffmpeg-2-8-12/libavcodec/atrac3plus.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/atrac3plus.c
rename to ffmpeg-2-8-12/libavcodec/atrac3plus.c
diff --git a/ffmpeg-2-8-11/libavcodec/atrac3plus.h b/ffmpeg-2-8-12/libavcodec/atrac3plus.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/atrac3plus.h
rename to ffmpeg-2-8-12/libavcodec/atrac3plus.h
diff --git a/ffmpeg-2-8-11/libavcodec/atrac3plus_data.h b/ffmpeg-2-8-12/libavcodec/atrac3plus_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/atrac3plus_data.h
rename to ffmpeg-2-8-12/libavcodec/atrac3plus_data.h
diff --git a/ffmpeg-2-8-11/libavcodec/atrac3plusdec.c b/ffmpeg-2-8-12/libavcodec/atrac3plusdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/atrac3plusdec.c
rename to ffmpeg-2-8-12/libavcodec/atrac3plusdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/atrac3plusdsp.c b/ffmpeg-2-8-12/libavcodec/atrac3plusdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/atrac3plusdsp.c
rename to ffmpeg-2-8-12/libavcodec/atrac3plusdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/audio_frame_queue.c b/ffmpeg-2-8-12/libavcodec/audio_frame_queue.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/audio_frame_queue.c
rename to ffmpeg-2-8-12/libavcodec/audio_frame_queue.c
diff --git a/ffmpeg-2-8-11/libavcodec/audio_frame_queue.h b/ffmpeg-2-8-12/libavcodec/audio_frame_queue.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/audio_frame_queue.h
rename to ffmpeg-2-8-12/libavcodec/audio_frame_queue.h
diff --git a/ffmpeg-2-8-11/libavcodec/audioconvert.c b/ffmpeg-2-8-12/libavcodec/audioconvert.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/audioconvert.c
rename to ffmpeg-2-8-12/libavcodec/audioconvert.c
diff --git a/ffmpeg-2-8-11/libavcodec/audioconvert.h b/ffmpeg-2-8-12/libavcodec/audioconvert.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/audioconvert.h
rename to ffmpeg-2-8-12/libavcodec/audioconvert.h
diff --git a/ffmpeg-2-8-11/libavcodec/audiodsp.c b/ffmpeg-2-8-12/libavcodec/audiodsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/audiodsp.c
rename to ffmpeg-2-8-12/libavcodec/audiodsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/audiodsp.h b/ffmpeg-2-8-12/libavcodec/audiodsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/audiodsp.h
rename to ffmpeg-2-8-12/libavcodec/audiodsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/aura.c b/ffmpeg-2-8-12/libavcodec/aura.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/aura.c
rename to ffmpeg-2-8-12/libavcodec/aura.c
diff --git a/ffmpeg-2-8-12/libavcodec/avcodec.h b/ffmpeg-2-8-12/libavcodec/avcodec.h
new file mode 100644
index 0000000..4c1c31a
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/avcodec.h
@@ -0,0 +1,5623 @@
+/*
+ * copyright (c) 2001 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_AVCODEC_H
+#define AVCODEC_AVCODEC_H
+
+/**
+ * @file
+ * @ingroup libavc
+ * Libavcodec external API header
+ */
+
+#include <errno.h>
+#include "libavutil/samplefmt.h"
+#include "libavutil/attributes.h"
+#include "libavutil/avutil.h"
+#include "libavutil/buffer.h"
+#include "libavutil/cpu.h"
+#include "libavutil/channel_layout.h"
+#include "libavutil/dict.h"
+#include "libavutil/frame.h"
+#include "libavutil/log.h"
+#include "libavutil/pixfmt.h"
+#include "libavutil/rational.h"
+
+#include "version.h"
+
+/**
+ * @defgroup libavc Encoding/Decoding Library
+ * @{
+ *
+ * @defgroup lavc_decoding Decoding
+ * @{
+ * @}
+ *
+ * @defgroup lavc_encoding Encoding
+ * @{
+ * @}
+ *
+ * @defgroup lavc_codec Codecs
+ * @{
+ * @defgroup lavc_codec_native Native Codecs
+ * @{
+ * @}
+ * @defgroup lavc_codec_wrappers External library wrappers
+ * @{
+ * @}
+ * @defgroup lavc_codec_hwaccel Hardware Accelerators bridge
+ * @{
+ * @}
+ * @}
+ * @defgroup lavc_internal Internal
+ * @{
+ * @}
+ * @}
+ *
+ */
+
+/**
+ * @defgroup lavc_core Core functions/structures.
+ * @ingroup libavc
+ *
+ * Basic definitions, functions for querying libavcodec capabilities,
+ * allocating core structures, etc.
+ * @{
+ */
+
+
+/**
+ * Identify the syntax and semantics of the bitstream.
+ * The principle is roughly:
+ * Two decoders with the same ID can decode the same streams.
+ * Two encoders with the same ID can encode compatible streams.
+ * There may be slight deviations from the principle due to implementation
+ * details.
+ *
+ * If you add a codec ID to this list, add it so that
+ * 1. no value of a existing codec ID changes (that would break ABI),
+ * 2. Give it a value which when taken as ASCII is recognized uniquely by a human as this specific codec.
+ * This ensures that 2 forks can independently add AVCodecIDs without producing conflicts.
+ *
+ * After adding new codec IDs, do not forget to add an entry to the codec
+ * descriptor list and bump libavcodec minor version.
+ */
+enum AVCodecID {
+ AV_CODEC_ID_NONE,
+
+ /* video codecs */
+ AV_CODEC_ID_MPEG1VIDEO,
+ AV_CODEC_ID_MPEG2VIDEO, ///< preferred ID for MPEG-1/2 video decoding
+#if FF_API_XVMC
+ AV_CODEC_ID_MPEG2VIDEO_XVMC,
+#endif /* FF_API_XVMC */
+ AV_CODEC_ID_H261,
+ AV_CODEC_ID_H263,
+ AV_CODEC_ID_RV10,
+ AV_CODEC_ID_RV20,
+ AV_CODEC_ID_MJPEG,
+ AV_CODEC_ID_MJPEGB,
+ AV_CODEC_ID_LJPEG,
+ AV_CODEC_ID_SP5X,
+ AV_CODEC_ID_JPEGLS,
+ AV_CODEC_ID_MPEG4,
+ AV_CODEC_ID_RAWVIDEO,
+ AV_CODEC_ID_MSMPEG4V1,
+ AV_CODEC_ID_MSMPEG4V2,
+ AV_CODEC_ID_MSMPEG4V3,
+ AV_CODEC_ID_WMV1,
+ AV_CODEC_ID_WMV2,
+ AV_CODEC_ID_H263P,
+ AV_CODEC_ID_H263I,
+ AV_CODEC_ID_FLV1,
+ AV_CODEC_ID_SVQ1,
+ AV_CODEC_ID_SVQ3,
+ AV_CODEC_ID_DVVIDEO,
+ AV_CODEC_ID_HUFFYUV,
+ AV_CODEC_ID_CYUV,
+ AV_CODEC_ID_H264,
+ AV_CODEC_ID_INDEO3,
+ AV_CODEC_ID_VP3,
+ AV_CODEC_ID_THEORA,
+ AV_CODEC_ID_ASV1,
+ AV_CODEC_ID_ASV2,
+ AV_CODEC_ID_FFV1,
+ AV_CODEC_ID_4XM,
+ AV_CODEC_ID_VCR1,
+ AV_CODEC_ID_CLJR,
+ AV_CODEC_ID_MDEC,
+ AV_CODEC_ID_ROQ,
+ AV_CODEC_ID_INTERPLAY_VIDEO,
+ AV_CODEC_ID_XAN_WC3,
+ AV_CODEC_ID_XAN_WC4,
+ AV_CODEC_ID_RPZA,
+ AV_CODEC_ID_CINEPAK,
+ AV_CODEC_ID_WS_VQA,
+ AV_CODEC_ID_MSRLE,
+ AV_CODEC_ID_MSVIDEO1,
+ AV_CODEC_ID_IDCIN,
+ AV_CODEC_ID_8BPS,
+ AV_CODEC_ID_SMC,
+ AV_CODEC_ID_FLIC,
+ AV_CODEC_ID_TRUEMOTION1,
+ AV_CODEC_ID_VMDVIDEO,
+ AV_CODEC_ID_MSZH,
+ AV_CODEC_ID_ZLIB,
+ AV_CODEC_ID_QTRLE,
+ AV_CODEC_ID_TSCC,
+ AV_CODEC_ID_ULTI,
+ AV_CODEC_ID_QDRAW,
+ AV_CODEC_ID_VIXL,
+ AV_CODEC_ID_QPEG,
+ AV_CODEC_ID_PNG,
+ AV_CODEC_ID_PPM,
+ AV_CODEC_ID_PBM,
+ AV_CODEC_ID_PGM,
+ AV_CODEC_ID_PGMYUV,
+ AV_CODEC_ID_PAM,
+ AV_CODEC_ID_FFVHUFF,
+ AV_CODEC_ID_RV30,
+ AV_CODEC_ID_RV40,
+ AV_CODEC_ID_VC1,
+ AV_CODEC_ID_WMV3,
+ AV_CODEC_ID_LOCO,
+ AV_CODEC_ID_WNV1,
+ AV_CODEC_ID_AASC,
+ AV_CODEC_ID_INDEO2,
+ AV_CODEC_ID_FRAPS,
+ AV_CODEC_ID_TRUEMOTION2,
+ AV_CODEC_ID_BMP,
+ AV_CODEC_ID_CSCD,
+ AV_CODEC_ID_MMVIDEO,
+ AV_CODEC_ID_ZMBV,
+ AV_CODEC_ID_AVS,
+ AV_CODEC_ID_SMACKVIDEO,
+ AV_CODEC_ID_NUV,
+ AV_CODEC_ID_KMVC,
+ AV_CODEC_ID_FLASHSV,
+ AV_CODEC_ID_CAVS,
+ AV_CODEC_ID_JPEG2000,
+ AV_CODEC_ID_VMNC,
+ AV_CODEC_ID_VP5,
+ AV_CODEC_ID_VP6,
+ AV_CODEC_ID_VP6F,
+ AV_CODEC_ID_TARGA,
+ AV_CODEC_ID_DSICINVIDEO,
+ AV_CODEC_ID_TIERTEXSEQVIDEO,
+ AV_CODEC_ID_TIFF,
+ AV_CODEC_ID_GIF,
+ AV_CODEC_ID_DXA,
+ AV_CODEC_ID_DNXHD,
+ AV_CODEC_ID_THP,
+ AV_CODEC_ID_SGI,
+ AV_CODEC_ID_C93,
+ AV_CODEC_ID_BETHSOFTVID,
+ AV_CODEC_ID_PTX,
+ AV_CODEC_ID_TXD,
+ AV_CODEC_ID_VP6A,
+ AV_CODEC_ID_AMV,
+ AV_CODEC_ID_VB,
+ AV_CODEC_ID_PCX,
+ AV_CODEC_ID_SUNRAST,
+ AV_CODEC_ID_INDEO4,
+ AV_CODEC_ID_INDEO5,
+ AV_CODEC_ID_MIMIC,
+ AV_CODEC_ID_RL2,
+ AV_CODEC_ID_ESCAPE124,
+ AV_CODEC_ID_DIRAC,
+ AV_CODEC_ID_BFI,
+ AV_CODEC_ID_CMV,
+ AV_CODEC_ID_MOTIONPIXELS,
+ AV_CODEC_ID_TGV,
+ AV_CODEC_ID_TGQ,
+ AV_CODEC_ID_TQI,
+ AV_CODEC_ID_AURA,
+ AV_CODEC_ID_AURA2,
+ AV_CODEC_ID_V210X,
+ AV_CODEC_ID_TMV,
+ AV_CODEC_ID_V210,
+ AV_CODEC_ID_DPX,
+ AV_CODEC_ID_MAD,
+ AV_CODEC_ID_FRWU,
+ AV_CODEC_ID_FLASHSV2,
+ AV_CODEC_ID_CDGRAPHICS,
+ AV_CODEC_ID_R210,
+ AV_CODEC_ID_ANM,
+ AV_CODEC_ID_BINKVIDEO,
+ AV_CODEC_ID_IFF_ILBM,
+ AV_CODEC_ID_IFF_BYTERUN1,
+ AV_CODEC_ID_KGV1,
+ AV_CODEC_ID_YOP,
+ AV_CODEC_ID_VP8,
+ AV_CODEC_ID_PICTOR,
+ AV_CODEC_ID_ANSI,
+ AV_CODEC_ID_A64_MULTI,
+ AV_CODEC_ID_A64_MULTI5,
+ AV_CODEC_ID_R10K,
+ AV_CODEC_ID_MXPEG,
+ AV_CODEC_ID_LAGARITH,
+ AV_CODEC_ID_PRORES,
+ AV_CODEC_ID_JV,
+ AV_CODEC_ID_DFA,
+ AV_CODEC_ID_WMV3IMAGE,
+ AV_CODEC_ID_VC1IMAGE,
+ AV_CODEC_ID_UTVIDEO,
+ AV_CODEC_ID_BMV_VIDEO,
+ AV_CODEC_ID_VBLE,
+ AV_CODEC_ID_DXTORY,
+ AV_CODEC_ID_V410,
+ AV_CODEC_ID_XWD,
+ AV_CODEC_ID_CDXL,
+ AV_CODEC_ID_XBM,
+ AV_CODEC_ID_ZEROCODEC,
+ AV_CODEC_ID_MSS1,
+ AV_CODEC_ID_MSA1,
+ AV_CODEC_ID_TSCC2,
+ AV_CODEC_ID_MTS2,
+ AV_CODEC_ID_CLLC,
+ AV_CODEC_ID_MSS2,
+ AV_CODEC_ID_VP9,
+ AV_CODEC_ID_AIC,
+ AV_CODEC_ID_ESCAPE130_DEPRECATED,
+ AV_CODEC_ID_G2M_DEPRECATED,
+ AV_CODEC_ID_WEBP_DEPRECATED,
+ AV_CODEC_ID_HNM4_VIDEO,
+ AV_CODEC_ID_HEVC_DEPRECATED,
+ AV_CODEC_ID_FIC,
+ AV_CODEC_ID_ALIAS_PIX,
+ AV_CODEC_ID_BRENDER_PIX_DEPRECATED,
+ AV_CODEC_ID_PAF_VIDEO_DEPRECATED,
+ AV_CODEC_ID_EXR_DEPRECATED,
+ AV_CODEC_ID_VP7_DEPRECATED,
+ AV_CODEC_ID_SANM_DEPRECATED,
+ AV_CODEC_ID_SGIRLE_DEPRECATED,
+ AV_CODEC_ID_MVC1_DEPRECATED,
+ AV_CODEC_ID_MVC2_DEPRECATED,
+ AV_CODEC_ID_HQX,
+ AV_CODEC_ID_TDSC,
+ AV_CODEC_ID_HQ_HQA,
+ AV_CODEC_ID_HAP,
+ AV_CODEC_ID_DDS,
+
+ AV_CODEC_ID_BRENDER_PIX= MKBETAG('B','P','I','X'),
+ AV_CODEC_ID_Y41P = MKBETAG('Y','4','1','P'),
+ AV_CODEC_ID_ESCAPE130 = MKBETAG('E','1','3','0'),
+ AV_CODEC_ID_EXR = MKBETAG('0','E','X','R'),
+ AV_CODEC_ID_AVRP = MKBETAG('A','V','R','P'),
+
+ AV_CODEC_ID_012V = MKBETAG('0','1','2','V'),
+ AV_CODEC_ID_G2M = MKBETAG( 0 ,'G','2','M'),
+ AV_CODEC_ID_AVUI = MKBETAG('A','V','U','I'),
+ AV_CODEC_ID_AYUV = MKBETAG('A','Y','U','V'),
+ AV_CODEC_ID_TARGA_Y216 = MKBETAG('T','2','1','6'),
+ AV_CODEC_ID_V308 = MKBETAG('V','3','0','8'),
+ AV_CODEC_ID_V408 = MKBETAG('V','4','0','8'),
+ AV_CODEC_ID_YUV4 = MKBETAG('Y','U','V','4'),
+ AV_CODEC_ID_SANM = MKBETAG('S','A','N','M'),
+ AV_CODEC_ID_PAF_VIDEO = MKBETAG('P','A','F','V'),
+ AV_CODEC_ID_AVRN = MKBETAG('A','V','R','n'),
+ AV_CODEC_ID_CPIA = MKBETAG('C','P','I','A'),
+ AV_CODEC_ID_XFACE = MKBETAG('X','F','A','C'),
+ AV_CODEC_ID_SGIRLE = MKBETAG('S','G','I','R'),
+ AV_CODEC_ID_MVC1 = MKBETAG('M','V','C','1'),
+ AV_CODEC_ID_MVC2 = MKBETAG('M','V','C','2'),
+ AV_CODEC_ID_SNOW = MKBETAG('S','N','O','W'),
+ AV_CODEC_ID_WEBP = MKBETAG('W','E','B','P'),
+ AV_CODEC_ID_SMVJPEG = MKBETAG('S','M','V','J'),
+ AV_CODEC_ID_HEVC = MKBETAG('H','2','6','5'),
+#define AV_CODEC_ID_H265 AV_CODEC_ID_HEVC
+ AV_CODEC_ID_VP7 = MKBETAG('V','P','7','0'),
+ AV_CODEC_ID_APNG = MKBETAG('A','P','N','G'),
+
+ /* various PCM "codecs" */
+ AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
+ AV_CODEC_ID_PCM_S16LE = 0x10000,
+ AV_CODEC_ID_PCM_S16BE,
+ AV_CODEC_ID_PCM_U16LE,
+ AV_CODEC_ID_PCM_U16BE,
+ AV_CODEC_ID_PCM_S8,
+ AV_CODEC_ID_PCM_U8,
+ AV_CODEC_ID_PCM_MULAW,
+ AV_CODEC_ID_PCM_ALAW,
+ AV_CODEC_ID_PCM_S32LE,
+ AV_CODEC_ID_PCM_S32BE,
+ AV_CODEC_ID_PCM_U32LE,
+ AV_CODEC_ID_PCM_U32BE,
+ AV_CODEC_ID_PCM_S24LE,
+ AV_CODEC_ID_PCM_S24BE,
+ AV_CODEC_ID_PCM_U24LE,
+ AV_CODEC_ID_PCM_U24BE,
+ AV_CODEC_ID_PCM_S24DAUD,
+ AV_CODEC_ID_PCM_ZORK,
+ AV_CODEC_ID_PCM_S16LE_PLANAR,
+ AV_CODEC_ID_PCM_DVD,
+ AV_CODEC_ID_PCM_F32BE,
+ AV_CODEC_ID_PCM_F32LE,
+ AV_CODEC_ID_PCM_F64BE,
+ AV_CODEC_ID_PCM_F64LE,
+ AV_CODEC_ID_PCM_BLURAY,
+ AV_CODEC_ID_PCM_LXF,
+ AV_CODEC_ID_S302M,
+ AV_CODEC_ID_PCM_S8_PLANAR,
+ AV_CODEC_ID_PCM_S24LE_PLANAR_DEPRECATED,
+ AV_CODEC_ID_PCM_S32LE_PLANAR_DEPRECATED,
+ AV_CODEC_ID_PCM_S16BE_PLANAR_DEPRECATED,
+ AV_CODEC_ID_PCM_S24LE_PLANAR = MKBETAG(24,'P','S','P'),
+ AV_CODEC_ID_PCM_S32LE_PLANAR = MKBETAG(32,'P','S','P'),
+ AV_CODEC_ID_PCM_S16BE_PLANAR = MKBETAG('P','S','P',16),
+
+ /* various ADPCM codecs */
+ AV_CODEC_ID_ADPCM_IMA_QT = 0x11000,
+ AV_CODEC_ID_ADPCM_IMA_WAV,
+ AV_CODEC_ID_ADPCM_IMA_DK3,
+ AV_CODEC_ID_ADPCM_IMA_DK4,
+ AV_CODEC_ID_ADPCM_IMA_WS,
+ AV_CODEC_ID_ADPCM_IMA_SMJPEG,
+ AV_CODEC_ID_ADPCM_MS,
+ AV_CODEC_ID_ADPCM_4XM,
+ AV_CODEC_ID_ADPCM_XA,
+ AV_CODEC_ID_ADPCM_ADX,
+ AV_CODEC_ID_ADPCM_EA,
+ AV_CODEC_ID_ADPCM_G726,
+ AV_CODEC_ID_ADPCM_CT,
+ AV_CODEC_ID_ADPCM_SWF,
+ AV_CODEC_ID_ADPCM_YAMAHA,
+ AV_CODEC_ID_ADPCM_SBPRO_4,
+ AV_CODEC_ID_ADPCM_SBPRO_3,
+ AV_CODEC_ID_ADPCM_SBPRO_2,
+ AV_CODEC_ID_ADPCM_THP,
+ AV_CODEC_ID_ADPCM_IMA_AMV,
+ AV_CODEC_ID_ADPCM_EA_R1,
+ AV_CODEC_ID_ADPCM_EA_R3,
+ AV_CODEC_ID_ADPCM_EA_R2,
+ AV_CODEC_ID_ADPCM_IMA_EA_SEAD,
+ AV_CODEC_ID_ADPCM_IMA_EA_EACS,
+ AV_CODEC_ID_ADPCM_EA_XAS,
+ AV_CODEC_ID_ADPCM_EA_MAXIS_XA,
+ AV_CODEC_ID_ADPCM_IMA_ISS,
+ AV_CODEC_ID_ADPCM_G722,
+ AV_CODEC_ID_ADPCM_IMA_APC,
+ AV_CODEC_ID_ADPCM_VIMA_DEPRECATED,
+ AV_CODEC_ID_ADPCM_VIMA = MKBETAG('V','I','M','A'),
+#if FF_API_VIMA_DECODER
+ AV_CODEC_ID_VIMA = MKBETAG('V','I','M','A'),
+#endif
+ AV_CODEC_ID_ADPCM_AFC = MKBETAG('A','F','C',' '),
+ AV_CODEC_ID_ADPCM_IMA_OKI = MKBETAG('O','K','I',' '),
+ AV_CODEC_ID_ADPCM_DTK = MKBETAG('D','T','K',' '),
+ AV_CODEC_ID_ADPCM_IMA_RAD = MKBETAG('R','A','D',' '),
+ AV_CODEC_ID_ADPCM_G726LE = MKBETAG('6','2','7','G'),
+ AV_CODEC_ID_ADPCM_THP_LE = MKBETAG('T','H','P','L'),
+
+ /* AMR */
+ AV_CODEC_ID_AMR_NB = 0x12000,
+ AV_CODEC_ID_AMR_WB,
+
+ /* RealAudio codecs*/
+ AV_CODEC_ID_RA_144 = 0x13000,
+ AV_CODEC_ID_RA_288,
+
+ /* various DPCM codecs */
+ AV_CODEC_ID_ROQ_DPCM = 0x14000,
+ AV_CODEC_ID_INTERPLAY_DPCM,
+ AV_CODEC_ID_XAN_DPCM,
+ AV_CODEC_ID_SOL_DPCM,
+
+ /* audio codecs */
+ AV_CODEC_ID_MP2 = 0x15000,
+ AV_CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3
+ AV_CODEC_ID_AAC,
+ AV_CODEC_ID_AC3,
+ AV_CODEC_ID_DTS,
+ AV_CODEC_ID_VORBIS,
+ AV_CODEC_ID_DVAUDIO,
+ AV_CODEC_ID_WMAV1,
+ AV_CODEC_ID_WMAV2,
+ AV_CODEC_ID_MACE3,
+ AV_CODEC_ID_MACE6,
+ AV_CODEC_ID_VMDAUDIO,
+ AV_CODEC_ID_FLAC,
+ AV_CODEC_ID_MP3ADU,
+ AV_CODEC_ID_MP3ON4,
+ AV_CODEC_ID_SHORTEN,
+ AV_CODEC_ID_ALAC,
+ AV_CODEC_ID_WESTWOOD_SND1,
+ AV_CODEC_ID_GSM, ///< as in Berlin toast format
+ AV_CODEC_ID_QDM2,
+ AV_CODEC_ID_COOK,
+ AV_CODEC_ID_TRUESPEECH,
+ AV_CODEC_ID_TTA,
+ AV_CODEC_ID_SMACKAUDIO,
+ AV_CODEC_ID_QCELP,
+ AV_CODEC_ID_WAVPACK,
+ AV_CODEC_ID_DSICINAUDIO,
+ AV_CODEC_ID_IMC,
+ AV_CODEC_ID_MUSEPACK7,
+ AV_CODEC_ID_MLP,
+ AV_CODEC_ID_GSM_MS, /* as found in WAV */
+ AV_CODEC_ID_ATRAC3,
+#if FF_API_VOXWARE
+ AV_CODEC_ID_VOXWARE,
+#endif
+ AV_CODEC_ID_APE,
+ AV_CODEC_ID_NELLYMOSER,
+ AV_CODEC_ID_MUSEPACK8,
+ AV_CODEC_ID_SPEEX,
+ AV_CODEC_ID_WMAVOICE,
+ AV_CODEC_ID_WMAPRO,
+ AV_CODEC_ID_WMALOSSLESS,
+ AV_CODEC_ID_ATRAC3P,
+ AV_CODEC_ID_EAC3,
+ AV_CODEC_ID_SIPR,
+ AV_CODEC_ID_MP1,
+ AV_CODEC_ID_TWINVQ,
+ AV_CODEC_ID_TRUEHD,
+ AV_CODEC_ID_MP4ALS,
+ AV_CODEC_ID_ATRAC1,
+ AV_CODEC_ID_BINKAUDIO_RDFT,
+ AV_CODEC_ID_BINKAUDIO_DCT,
+ AV_CODEC_ID_AAC_LATM,
+ AV_CODEC_ID_QDMC,
+ AV_CODEC_ID_CELT,
+ AV_CODEC_ID_G723_1,
+ AV_CODEC_ID_G729,
+ AV_CODEC_ID_8SVX_EXP,
+ AV_CODEC_ID_8SVX_FIB,
+ AV_CODEC_ID_BMV_AUDIO,
+ AV_CODEC_ID_RALF,
+ AV_CODEC_ID_IAC,
+ AV_CODEC_ID_ILBC,
+ AV_CODEC_ID_OPUS_DEPRECATED,
+ AV_CODEC_ID_COMFORT_NOISE,
+ AV_CODEC_ID_TAK_DEPRECATED,
+ AV_CODEC_ID_METASOUND,
+ AV_CODEC_ID_PAF_AUDIO_DEPRECATED,
+ AV_CODEC_ID_ON2AVC,
+ AV_CODEC_ID_DSS_SP,
+ AV_CODEC_ID_FFWAVESYNTH = MKBETAG('F','F','W','S'),
+ AV_CODEC_ID_SONIC = MKBETAG('S','O','N','C'),
+ AV_CODEC_ID_SONIC_LS = MKBETAG('S','O','N','L'),
+ AV_CODEC_ID_PAF_AUDIO = MKBETAG('P','A','F','A'),
+ AV_CODEC_ID_OPUS = MKBETAG('O','P','U','S'),
+ AV_CODEC_ID_TAK = MKBETAG('t','B','a','K'),
+ AV_CODEC_ID_EVRC = MKBETAG('s','e','v','c'),
+ AV_CODEC_ID_SMV = MKBETAG('s','s','m','v'),
+ AV_CODEC_ID_DSD_LSBF = MKBETAG('D','S','D','L'),
+ AV_CODEC_ID_DSD_MSBF = MKBETAG('D','S','D','M'),
+ AV_CODEC_ID_DSD_LSBF_PLANAR = MKBETAG('D','S','D','1'),
+ AV_CODEC_ID_DSD_MSBF_PLANAR = MKBETAG('D','S','D','8'),
+ AV_CODEC_ID_4GV = MKBETAG('s','4','g','v'),
+
+ /* subtitle codecs */
+ AV_CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs.
+ AV_CODEC_ID_DVD_SUBTITLE = 0x17000,
+ AV_CODEC_ID_DVB_SUBTITLE,
+ AV_CODEC_ID_TEXT, ///< raw UTF-8 text
+ AV_CODEC_ID_XSUB,
+ AV_CODEC_ID_SSA,
+ AV_CODEC_ID_MOV_TEXT,
+ AV_CODEC_ID_HDMV_PGS_SUBTITLE,
+ AV_CODEC_ID_DVB_TELETEXT,
+ AV_CODEC_ID_SRT,
+ AV_CODEC_ID_MICRODVD = MKBETAG('m','D','V','D'),
+ AV_CODEC_ID_EIA_608 = MKBETAG('c','6','0','8'),
+ AV_CODEC_ID_JACOSUB = MKBETAG('J','S','U','B'),
+ AV_CODEC_ID_SAMI = MKBETAG('S','A','M','I'),
+ AV_CODEC_ID_REALTEXT = MKBETAG('R','T','X','T'),
+ AV_CODEC_ID_STL = MKBETAG('S','p','T','L'),
+ AV_CODEC_ID_SUBVIEWER1 = MKBETAG('S','b','V','1'),
+ AV_CODEC_ID_SUBVIEWER = MKBETAG('S','u','b','V'),
+ AV_CODEC_ID_SUBRIP = MKBETAG('S','R','i','p'),
+ AV_CODEC_ID_WEBVTT = MKBETAG('W','V','T','T'),
+ AV_CODEC_ID_MPL2 = MKBETAG('M','P','L','2'),
+ AV_CODEC_ID_VPLAYER = MKBETAG('V','P','l','r'),
+ AV_CODEC_ID_PJS = MKBETAG('P','h','J','S'),
+ AV_CODEC_ID_ASS = MKBETAG('A','S','S',' '), ///< ASS as defined in Matroska
+ AV_CODEC_ID_HDMV_TEXT_SUBTITLE = MKBETAG('B','D','T','X'),
+
+ /* other specific kind of codecs (generally used for attachments) */
+ AV_CODEC_ID_FIRST_UNKNOWN = 0x18000, ///< A dummy ID pointing at the start of various fake codecs.
+ AV_CODEC_ID_TTF = 0x18000,
+ AV_CODEC_ID_BINTEXT = MKBETAG('B','T','X','T'),
+ AV_CODEC_ID_XBIN = MKBETAG('X','B','I','N'),
+ AV_CODEC_ID_IDF = MKBETAG( 0 ,'I','D','F'),
+ AV_CODEC_ID_OTF = MKBETAG( 0 ,'O','T','F'),
+ AV_CODEC_ID_SMPTE_KLV = MKBETAG('K','L','V','A'),
+ AV_CODEC_ID_DVD_NAV = MKBETAG('D','N','A','V'),
+ AV_CODEC_ID_TIMED_ID3 = MKBETAG('T','I','D','3'),
+ AV_CODEC_ID_BIN_DATA = MKBETAG('D','A','T','A'),
+
+
+ AV_CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it
+
+ AV_CODEC_ID_MPEG2TS = 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS
+ * stream (only used by libavformat) */
+ AV_CODEC_ID_MPEG4SYSTEMS = 0x20001, /**< _FAKE_ codec to indicate a MPEG-4 Systems
+ * stream (only used by libavformat) */
+ AV_CODEC_ID_FFMETADATA = 0x21000, ///< Dummy codec for streams containing only metadata information.
+
+#if FF_API_CODEC_ID
+#include "old_codec_ids.h"
+#endif
+};
+
+/**
+ * This struct describes the properties of a single codec described by an
+ * AVCodecID.
+ * @see avcodec_descriptor_get()
+ */
+typedef struct AVCodecDescriptor {
+ enum AVCodecID id;
+ enum AVMediaType type;
+ /**
+ * Name of the codec described by this descriptor. It is non-empty and
+ * unique for each codec descriptor. It should contain alphanumeric
+ * characters and '_' only.
+ */
+ const char *name;
+ /**
+ * A more descriptive name for this codec. May be NULL.
+ */
+ const char *long_name;
+ /**
+ * Codec properties, a combination of AV_CODEC_PROP_* flags.
+ */
+ int props;
+
+ /**
+ * MIME type(s) associated with the codec.
+ * May be NULL; if not, a NULL-terminated array of MIME types.
+ * The first item is always non-NULL and is the preferred MIME type.
+ */
+ const char *const *mime_types;
+} AVCodecDescriptor;
+
+/**
+ * Codec uses only intra compression.
+ * Video codecs only.
+ */
+#define AV_CODEC_PROP_INTRA_ONLY (1 << 0)
+/**
+ * Codec supports lossy compression. Audio and video codecs only.
+ * @note a codec may support both lossy and lossless
+ * compression modes
+ */
+#define AV_CODEC_PROP_LOSSY (1 << 1)
+/**
+ * Codec supports lossless compression. Audio and video codecs only.
+ */
+#define AV_CODEC_PROP_LOSSLESS (1 << 2)
+/**
+ * Codec supports frame reordering. That is, the coded order (the order in which
+ * the encoded packets are output by the encoders / stored / input to the
+ * decoders) may be different from the presentation order of the corresponding
+ * frames.
+ *
+ * For codecs that do not have this property set, PTS and DTS should always be
+ * equal.
+ */
+#define AV_CODEC_PROP_REORDER (1 << 3)
+/**
+ * Subtitle codec is bitmap based
+ * Decoded AVSubtitle data can be read from the AVSubtitleRect->pict field.
+ */
+#define AV_CODEC_PROP_BITMAP_SUB (1 << 16)
+/**
+ * Subtitle codec is text based.
+ * Decoded AVSubtitle data can be read from the AVSubtitleRect->ass field.
+ */
+#define AV_CODEC_PROP_TEXT_SUB (1 << 17)
+
+/**
+ * @ingroup lavc_decoding
+ * Required number of additionally allocated bytes at the end of the input bitstream for decoding.
+ * This is mainly needed because some optimized bitstream readers read
+ * 32 or 64 bit at once and could read over the end.<br>
+ * Note: If the first 23 bits of the additional bytes are not 0, then damaged
+ * MPEG bitstreams could cause overread and segfault.
+ */
+#define AV_INPUT_BUFFER_PADDING_SIZE 32
+
+/**
+ * @ingroup lavc_encoding
+ * minimum encoding buffer size
+ * Used to avoid some checks during header writing.
+ */
+#define AV_INPUT_BUFFER_MIN_SIZE 16384
+
+#if FF_API_WITHOUT_PREFIX
+/**
+ * @deprecated use AV_INPUT_BUFFER_PADDING_SIZE instead
+ */
+#define FF_INPUT_BUFFER_PADDING_SIZE 32
+
+/**
+ * @deprecated use AV_INPUT_BUFFER_MIN_SIZE instead
+ */
+#define FF_MIN_BUFFER_SIZE 16384
+#endif /* FF_API_WITHOUT_PREFIX */
+
+/**
+ * @ingroup lavc_encoding
+ * motion estimation type.
+ * @deprecated use codec private option instead
+ */
+#if FF_API_MOTION_EST
+enum Motion_Est_ID {
+ ME_ZERO = 1, ///< no search, that is use 0,0 vector whenever one is needed
+ ME_FULL,
+ ME_LOG,
+ ME_PHODS,
+ ME_EPZS, ///< enhanced predictive zonal search
+ ME_X1, ///< reserved for experiments
+ ME_HEX, ///< hexagon based search
+ ME_UMH, ///< uneven multi-hexagon search
+ ME_TESA, ///< transformed exhaustive search algorithm
+ ME_ITER=50, ///< iterative search
+};
+#endif
+
+/**
+ * @ingroup lavc_decoding
+ */
+enum AVDiscard{
+ /* We leave some space between them for extensions (drop some
+ * keyframes for intra-only or drop just some bidir frames). */
+ AVDISCARD_NONE =-16, ///< discard nothing
+ AVDISCARD_DEFAULT = 0, ///< discard useless packets like 0 size packets in avi
+ AVDISCARD_NONREF = 8, ///< discard all non reference
+ AVDISCARD_BIDIR = 16, ///< discard all bidirectional frames
+ AVDISCARD_NONINTRA= 24, ///< discard all non intra frames
+ AVDISCARD_NONKEY = 32, ///< discard all frames except keyframes
+ AVDISCARD_ALL = 48, ///< discard all
+};
+
+enum AVAudioServiceType {
+ AV_AUDIO_SERVICE_TYPE_MAIN = 0,
+ AV_AUDIO_SERVICE_TYPE_EFFECTS = 1,
+ AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED = 2,
+ AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED = 3,
+ AV_AUDIO_SERVICE_TYPE_DIALOGUE = 4,
+ AV_AUDIO_SERVICE_TYPE_COMMENTARY = 5,
+ AV_AUDIO_SERVICE_TYPE_EMERGENCY = 6,
+ AV_AUDIO_SERVICE_TYPE_VOICE_OVER = 7,
+ AV_AUDIO_SERVICE_TYPE_KARAOKE = 8,
+ AV_AUDIO_SERVICE_TYPE_NB , ///< Not part of ABI
+};
+
+/**
+ * @ingroup lavc_encoding
+ */
+typedef struct RcOverride{
+ int start_frame;
+ int end_frame;
+ int qscale; // If this is 0 then quality_factor will be used instead.
+ float quality_factor;
+} RcOverride;
+
+#if FF_API_MAX_BFRAMES
+/**
+ * @deprecated there is no libavcodec-wide limit on the number of B-frames
+ */
+#define FF_MAX_B_FRAMES 16
+#endif
+
+/* encoding support
+ These flags can be passed in AVCodecContext.flags before initialization.
+ Note: Not everything is supported yet.
+*/
+
+/**
+ * Allow decoders to produce frames with data planes that are not aligned
+ * to CPU requirements (e.g. due to cropping).
+ */
+#define AV_CODEC_FLAG_UNALIGNED (1 << 0)
+/**
+ * Use fixed qscale.
+ */
+#define AV_CODEC_FLAG_QSCALE (1 << 1)
+/**
+ * 4 MV per MB allowed / advanced prediction for H.263.
+ */
+#define AV_CODEC_FLAG_4MV (1 << 2)
+/**
+ * Output even those frames that might be corrupted.
+ */
+#define AV_CODEC_FLAG_OUTPUT_CORRUPT (1 << 3)
+/**
+ * Use qpel MC.
+ */
+#define AV_CODEC_FLAG_QPEL (1 << 4)
+/**
+ * Use internal 2pass ratecontrol in first pass mode.
+ */
+#define AV_CODEC_FLAG_PASS1 (1 << 9)
+/**
+ * Use internal 2pass ratecontrol in second pass mode.
+ */
+#define AV_CODEC_FLAG_PASS2 (1 << 10)
+/**
+ * loop filter.
+ */
+#define AV_CODEC_FLAG_LOOP_FILTER (1 << 11)
+/**
+ * Only decode/encode grayscale.
+ */
+#define AV_CODEC_FLAG_GRAY (1 << 13)
+/**
+ * error[?] variables will be set during encoding.
+ */
+#define AV_CODEC_FLAG_PSNR (1 << 15)
+/**
+ * Input bitstream might be truncated at a random location
+ * instead of only at frame boundaries.
+ */
+#define AV_CODEC_FLAG_TRUNCATED (1 << 16)
+/**
+ * Use interlaced DCT.
+ */
+#define AV_CODEC_FLAG_INTERLACED_DCT (1 << 18)
+/**
+ * Force low delay.
+ */
+#define AV_CODEC_FLAG_LOW_DELAY (1 << 19)
+/**
+ * Place global headers in extradata instead of every keyframe.
+ */
+#define AV_CODEC_FLAG_GLOBAL_HEADER (1 << 22)
+/**
+ * Use only bitexact stuff (except (I)DCT).
+ */
+#define AV_CODEC_FLAG_BITEXACT (1 << 23)
+/* Fx : Flag for h263+ extra options */
+/**
+ * H.263 advanced intra coding / MPEG-4 AC prediction
+ */
+#define AV_CODEC_FLAG_AC_PRED (1 << 24)
+/**
+ * interlaced motion estimation
+ */
+#define AV_CODEC_FLAG_INTERLACED_ME (1 << 29)
+/**
+ * Allow non spec compliant speedup tricks.
+ */
+#define AV_CODEC_FLAG_CLOSED_GOP (1U << 31)
+
+#define AV_CODEC_FLAG2_FAST (1 << 0)
+/**
+ * Skip bitstream encoding.
+ */
+#define AV_CODEC_FLAG2_NO_OUTPUT (1 << 2)
+/**
+ * Place global headers at every keyframe instead of in extradata.
+ */
+#define AV_CODEC_FLAG2_LOCAL_HEADER (1 << 3)
+
+/**
+ * timecode is in drop frame format. DEPRECATED!!!!
+ */
+#define AV_CODEC_FLAG2_DROP_FRAME_TIMECODE (1 << 13)
+
+/**
+ * Input bitstream might be truncated at a packet boundaries
+ * instead of only at frame boundaries.
+ */
+#define AV_CODEC_FLAG2_CHUNKS (1 << 15)
+/**
+ * Discard cropping information from SPS.
+ */
+#define AV_CODEC_FLAG2_IGNORE_CROP (1 << 16)
+
+/**
+ * Show all frames before the first keyframe
+ */
+#define AV_CODEC_FLAG2_SHOW_ALL (1 << 22)
+/**
+ * Export motion vectors through frame side data
+ */
+#define AV_CODEC_FLAG2_EXPORT_MVS (1 << 28)
+/**
+ * Do not skip samples and export skip information as frame side data
+ */
+#define AV_CODEC_FLAG2_SKIP_MANUAL (1 << 29)
+
+/* Unsupported options :
+ * Syntax Arithmetic coding (SAC)
+ * Reference Picture Selection
+ * Independent Segment Decoding */
+/* /Fx */
+/* codec capabilities */
+
+/**
+ * Decoder can use draw_horiz_band callback.
+ */
+#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.
+ */
+#define AV_CODEC_CAP_DR1 (1 << 1)
+#define AV_CODEC_CAP_TRUNCATED (1 << 3)
+/**
+ * Encoder or decoder requires flushing with NULL input at the end in order to
+ * give the complete and correct output.
+ *
+ * NOTE: If this flag is not set, the codec is guaranteed to never be fed with
+ * with NULL data. The user can still send NULL data to the public encode
+ * or decode function, but libavcodec will not pass it along to the codec
+ * unless this flag is set.
+ *
+ * Decoders:
+ * The decoder has a non-zero delay and needs to be fed with avpkt->data=NULL,
+ * avpkt->size=0 at the end to get the delayed data until the decoder no longer
+ * returns frames.
+ *
+ * Encoders:
+ * The encoder needs to be fed with NULL data at the end of encoding until the
+ * encoder no longer returns data.
+ *
+ * NOTE: For encoders implementing the AVCodec.encode2() function, setting this
+ * flag also means that the encoder must set the pts and duration for
+ * each output packet. If this flag is not set, the pts and duration will
+ * be determined by libavcodec from the input frame.
+ */
+#define AV_CODEC_CAP_DELAY (1 << 5)
+/**
+ * Codec can be fed a final frame with a smaller size.
+ * This can be used to prevent truncation of the last audio samples.
+ */
+#define AV_CODEC_CAP_SMALL_LAST_FRAME (1 << 6)
+
+#if FF_API_CAP_VDPAU
+/**
+ * Codec can export data for HW decoding (VDPAU).
+ */
+#define AV_CODEC_CAP_HWACCEL_VDPAU (1 << 7)
+#endif
+
+/**
+ * Codec can output multiple frames per AVPacket
+ * Normally demuxers return one frame at a time, demuxers which do not do
+ * are connected to a parser to split what they return into proper frames.
+ * This flag is reserved to the very rare category of codecs which have a
+ * bitstream that cannot be split into frames without timeconsuming
+ * operations like full decoding. Demuxers carring such bitstreams thus
+ * may return multiple frames in a packet. This has many disadvantages like
+ * prohibiting stream copy in many cases thus it should only be considered
+ * as a last resort.
+ */
+#define AV_CODEC_CAP_SUBFRAMES (1 << 8)
+/**
+ * Codec is experimental and is thus avoided in favor of non experimental
+ * encoders
+ */
+#define AV_CODEC_CAP_EXPERIMENTAL (1 << 9)
+/**
+ * Codec should fill in channel configuration and samplerate instead of container
+ */
+#define AV_CODEC_CAP_CHANNEL_CONF (1 << 10)
+/**
+ * Codec supports frame-level multithreading.
+ */
+#define AV_CODEC_CAP_FRAME_THREADS (1 << 12)
+/**
+ * Codec supports slice-based (or partition-based) multithreading.
+ */
+#define AV_CODEC_CAP_SLICE_THREADS (1 << 13)
+/**
+ * Codec supports changed parameters at any point.
+ */
+#define AV_CODEC_CAP_PARAM_CHANGE (1 << 14)
+/**
+ * Codec supports avctx->thread_count == 0 (auto).
+ */
+#define AV_CODEC_CAP_AUTO_THREADS (1 << 15)
+/**
+ * Audio encoder supports receiving a different number of samples in each call.
+ */
+#define AV_CODEC_CAP_VARIABLE_FRAME_SIZE (1 << 16)
+/**
+ * Codec is intra only.
+ */
+#define AV_CODEC_CAP_INTRA_ONLY 0x40000000
+/**
+ * Codec is lossless.
+ */
+#define AV_CODEC_CAP_LOSSLESS 0x80000000
+
+
+#if FF_API_WITHOUT_PREFIX
+/**
+ * Allow decoders to produce frames with data planes that are not aligned
+ * to CPU requirements (e.g. due to cropping).
+ */
+#define CODEC_FLAG_UNALIGNED AV_CODEC_FLAG_UNALIGNED
+#define CODEC_FLAG_QSCALE AV_CODEC_FLAG_QSCALE
+#define CODEC_FLAG_4MV AV_CODEC_FLAG_4MV
+#define CODEC_FLAG_OUTPUT_CORRUPT AV_CODEC_FLAG_OUTPUT_CORRUPT
+#define CODEC_FLAG_QPEL AV_CODEC_FLAG_QPEL
+#if FF_API_GMC
+/**
+ * @deprecated use the "gmc" private option of the libxvid encoder
+ */
+#define CODEC_FLAG_GMC 0x0020 ///< Use GMC.
+#endif
+#if FF_API_MV0
+/**
+ * @deprecated use the flag "mv0" in the "mpv_flags" private option of the
+ * mpegvideo encoders
+ */
+#define CODEC_FLAG_MV0 0x0040
+#endif
+#if FF_API_INPUT_PRESERVED
+/**
+ * @deprecated passing reference-counted frames to the encoders replaces this
+ * flag
+ */
+#define CODEC_FLAG_INPUT_PRESERVED 0x0100
+#endif
+#define CODEC_FLAG_PASS1 AV_CODEC_FLAG_PASS1
+#define CODEC_FLAG_PASS2 AV_CODEC_FLAG_PASS2
+#define CODEC_FLAG_GRAY AV_CODEC_FLAG_GRAY
+#if FF_API_EMU_EDGE
+/**
+ * @deprecated edges are not used/required anymore. I.e. this flag is now always
+ * set.
+ */
+#define CODEC_FLAG_EMU_EDGE 0x4000
+#endif
+#define CODEC_FLAG_PSNR AV_CODEC_FLAG_PSNR
+#define CODEC_FLAG_TRUNCATED AV_CODEC_FLAG_TRUNCATED
+
+#if FF_API_NORMALIZE_AQP
+/**
+ * @deprecated use the flag "naq" in the "mpv_flags" private option of the
+ * mpegvideo encoders
+ */
+#define CODEC_FLAG_NORMALIZE_AQP 0x00020000
+#endif
+#define CODEC_FLAG_INTERLACED_DCT AV_CODEC_FLAG_INTERLACED_DCT
+#define CODEC_FLAG_LOW_DELAY AV_CODEC_FLAG_LOW_DELAY
+#define CODEC_FLAG_GLOBAL_HEADER AV_CODEC_FLAG_GLOBAL_HEADER
+#define CODEC_FLAG_BITEXACT AV_CODEC_FLAG_BITEXACT
+#define CODEC_FLAG_AC_PRED AV_CODEC_FLAG_AC_PRED
+#define CODEC_FLAG_LOOP_FILTER AV_CODEC_FLAG_LOOP_FILTER
+#define CODEC_FLAG_INTERLACED_ME AV_CODEC_FLAG_INTERLACED_ME
+#define CODEC_FLAG_CLOSED_GOP AV_CODEC_FLAG_CLOSED_GOP
+#define CODEC_FLAG2_FAST AV_CODEC_FLAG2_FAST
+#define CODEC_FLAG2_NO_OUTPUT AV_CODEC_FLAG2_NO_OUTPUT
+#define CODEC_FLAG2_LOCAL_HEADER AV_CODEC_FLAG2_LOCAL_HEADER
+#define CODEC_FLAG2_DROP_FRAME_TIMECODE AV_CODEC_FLAG2_DROP_FRAME_TIMECODE
+#define CODEC_FLAG2_IGNORE_CROP AV_CODEC_FLAG2_IGNORE_CROP
+
+#define CODEC_FLAG2_CHUNKS AV_CODEC_FLAG2_CHUNKS
+#define CODEC_FLAG2_SHOW_ALL AV_CODEC_FLAG2_SHOW_ALL
+#define CODEC_FLAG2_EXPORT_MVS AV_CODEC_FLAG2_EXPORT_MVS
+#define CODEC_FLAG2_SKIP_MANUAL AV_CODEC_FLAG2_SKIP_MANUAL
+
+/* Unsupported options :
+ * Syntax Arithmetic coding (SAC)
+ * Reference Picture Selection
+ * Independent Segment Decoding */
+/* /Fx */
+/* codec capabilities */
+
+#define CODEC_CAP_DRAW_HORIZ_BAND AV_CODEC_CAP_DRAW_HORIZ_BAND ///< Decoder can use draw_horiz_band callback.
+/**
+ * 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.
+ */
+#define CODEC_CAP_DR1 AV_CODEC_CAP_DR1
+#define CODEC_CAP_TRUNCATED AV_CODEC_CAP_TRUNCATED
+#if FF_API_XVMC
+/* Codec can export data for HW decoding. This flag indicates that
+ * the codec would call get_format() with list that might contain HW accelerated
+ * pixel formats (XvMC, VDPAU, VAAPI, etc). The application can pick any of them
+ * including raw image format.
+ * The application can use the passed context to determine bitstream version,
+ * chroma format, resolution etc.
+ */
+#define CODEC_CAP_HWACCEL 0x0010
+#endif /* FF_API_XVMC */
+/**
+ * Encoder or decoder requires flushing with NULL input at the end in order to
+ * give the complete and correct output.
+ *
+ * NOTE: If this flag is not set, the codec is guaranteed to never be fed with
+ * with NULL data. The user can still send NULL data to the public encode
+ * or decode function, but libavcodec will not pass it along to the codec
+ * unless this flag is set.
+ *
+ * Decoders:
+ * The decoder has a non-zero delay and needs to be fed with avpkt->data=NULL,
+ * avpkt->size=0 at the end to get the delayed data until the decoder no longer
+ * returns frames.
+ *
+ * Encoders:
+ * The encoder needs to be fed with NULL data at the end of encoding until the
+ * encoder no longer returns data.
+ *
+ * NOTE: For encoders implementing the AVCodec.encode2() function, setting this
+ * flag also means that the encoder must set the pts and duration for
+ * each output packet. If this flag is not set, the pts and duration will
+ * be determined by libavcodec from the input frame.
+ */
+#define CODEC_CAP_DELAY AV_CODEC_CAP_DELAY
+/**
+ * Codec can be fed a final frame with a smaller size.
+ * This can be used to prevent truncation of the last audio samples.
+ */
+#define CODEC_CAP_SMALL_LAST_FRAME AV_CODEC_CAP_SMALL_LAST_FRAME
+#if FF_API_CAP_VDPAU
+/**
+ * Codec can export data for HW decoding (VDPAU).
+ */
+#define CODEC_CAP_HWACCEL_VDPAU AV_CODEC_CAP_HWACCEL_VDPAU
+#endif
+/**
+ * Codec can output multiple frames per AVPacket
+ * Normally demuxers return one frame at a time, demuxers which do not do
+ * are connected to a parser to split what they return into proper frames.
+ * This flag is reserved to the very rare category of codecs which have a
+ * bitstream that cannot be split into frames without timeconsuming
+ * operations like full decoding. Demuxers carring such bitstreams thus
+ * may return multiple frames in a packet. This has many disadvantages like
+ * prohibiting stream copy in many cases thus it should only be considered
+ * as a last resort.
+ */
+#define CODEC_CAP_SUBFRAMES AV_CODEC_CAP_SUBFRAMES
+/**
+ * Codec is experimental and is thus avoided in favor of non experimental
+ * encoders
+ */
+#define CODEC_CAP_EXPERIMENTAL AV_CODEC_CAP_EXPERIMENTAL
+/**
+ * Codec should fill in channel configuration and samplerate instead of container
+ */
+#define CODEC_CAP_CHANNEL_CONF AV_CODEC_CAP_CHANNEL_CONF
+#if FF_API_NEG_LINESIZES
+/**
+ * @deprecated no codecs use this capability
+ */
+#define CODEC_CAP_NEG_LINESIZES 0x0800
+#endif
+/**
+ * Codec supports frame-level multithreading.
+ */
+#define CODEC_CAP_FRAME_THREADS AV_CODEC_CAP_FRAME_THREADS
+/**
+ * Codec supports slice-based (or partition-based) multithreading.
+ */
+#define CODEC_CAP_SLICE_THREADS AV_CODEC_CAP_SLICE_THREADS
+/**
+ * Codec supports changed parameters at any point.
+ */
+#define CODEC_CAP_PARAM_CHANGE AV_CODEC_CAP_PARAM_CHANGE
+/**
+ * Codec supports avctx->thread_count == 0 (auto).
+ */
+#define CODEC_CAP_AUTO_THREADS AV_CODEC_CAP_AUTO_THREADS
+/**
+ * Audio encoder supports receiving a different number of samples in each call.
+ */
+#define CODEC_CAP_VARIABLE_FRAME_SIZE AV_CODEC_CAP_VARIABLE_FRAME_SIZE
+/**
+ * Codec is intra only.
+ */
+#define CODEC_CAP_INTRA_ONLY AV_CODEC_CAP_INTRA_ONLY
+/**
+ * Codec is lossless.
+ */
+#define CODEC_CAP_LOSSLESS AV_CODEC_CAP_LOSSLESS
+
+/**
+ * HWAccel is experimental and is thus avoided in favor of non experimental
+ * codecs
+ */
+#define HWACCEL_CODEC_CAP_EXPERIMENTAL 0x0200
+#endif /* FF_API_WITHOUT_PREFIX */
+
+#if FF_API_MB_TYPE
+//The following defines may change, don't expect compatibility if you use them.
+#define MB_TYPE_INTRA4x4 0x0001
+#define MB_TYPE_INTRA16x16 0x0002 //FIXME H.264-specific
+#define MB_TYPE_INTRA_PCM 0x0004 //FIXME H.264-specific
+#define MB_TYPE_16x16 0x0008
+#define MB_TYPE_16x8 0x0010
+#define MB_TYPE_8x16 0x0020
+#define MB_TYPE_8x8 0x0040
+#define MB_TYPE_INTERLACED 0x0080
+#define MB_TYPE_DIRECT2 0x0100 //FIXME
+#define MB_TYPE_ACPRED 0x0200
+#define MB_TYPE_GMC 0x0400
+#define MB_TYPE_SKIP 0x0800
+#define MB_TYPE_P0L0 0x1000
+#define MB_TYPE_P1L0 0x2000
+#define MB_TYPE_P0L1 0x4000
+#define MB_TYPE_P1L1 0x8000
+#define MB_TYPE_L0 (MB_TYPE_P0L0 | MB_TYPE_P1L0)
+#define MB_TYPE_L1 (MB_TYPE_P0L1 | MB_TYPE_P1L1)
+#define MB_TYPE_L0L1 (MB_TYPE_L0 | MB_TYPE_L1)
+#define MB_TYPE_QUANT 0x00010000
+#define MB_TYPE_CBP 0x00020000
+//Note bits 24-31 are reserved for codec specific use (h264 ref0, mpeg1 0mv, ...)
+#endif
+
+/**
+ * Pan Scan area.
+ * This specifies the area which should be displayed.
+ * Note there may be multiple such areas for one frame.
+ */
+typedef struct AVPanScan{
+ /**
+ * id
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int id;
+
+ /**
+ * width and height in 1/16 pel
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int width;
+ int height;
+
+ /**
+ * position of the top left corner in 1/16 pel for up to 3 fields/frames
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int16_t position[3][2];
+}AVPanScan;
+
+#if FF_API_QSCALE_TYPE
+#define FF_QSCALE_TYPE_MPEG1 0
+#define FF_QSCALE_TYPE_MPEG2 1
+#define FF_QSCALE_TYPE_H264 2
+#define FF_QSCALE_TYPE_VP56 3
+#endif
+
+#if FF_API_GET_BUFFER
+#define FF_BUFFER_TYPE_INTERNAL 1
+#define FF_BUFFER_TYPE_USER 2 ///< direct rendering buffers (image is (de)allocated by user)
+#define FF_BUFFER_TYPE_SHARED 4 ///< Buffer from somewhere else; don't deallocate image (data/base), all other tables are not shared.
+#define FF_BUFFER_TYPE_COPY 8 ///< Just a (modified) copy of some other buffer, don't deallocate anything.
+
+#define FF_BUFFER_HINTS_VALID 0x01 // Buffer hints value is meaningful (if 0 ignore).
+#define FF_BUFFER_HINTS_READABLE 0x02 // Codec will read from buffer.
+#define FF_BUFFER_HINTS_PRESERVE 0x04 // User must not alter buffer content.
+#define FF_BUFFER_HINTS_REUSABLE 0x08 // Codec will reuse the buffer (update).
+#endif
+
+/**
+ * The decoder will keep a reference to the frame and may reuse it later.
+ */
+#define AV_GET_BUFFER_FLAG_REF (1 << 0)
+
+/**
+ * @defgroup lavc_packet AVPacket
+ *
+ * Types and functions for working with AVPacket.
+ * @{
+ */
+enum AVPacketSideDataType {
+ AV_PKT_DATA_PALETTE,
+ AV_PKT_DATA_NEW_EXTRADATA,
+
+ /**
+ * An AV_PKT_DATA_PARAM_CHANGE side data packet is laid out as follows:
+ * @code
+ * u32le param_flags
+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT)
+ * s32le channel_count
+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT)
+ * u64le channel_layout
+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE)
+ * s32le sample_rate
+ * if (param_flags & AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS)
+ * s32le width
+ * s32le height
+ * @endcode
+ */
+ AV_PKT_DATA_PARAM_CHANGE,
+
+ /**
+ * An AV_PKT_DATA_H263_MB_INFO side data packet contains a number of
+ * structures with info about macroblocks relevant to splitting the
+ * packet into smaller packets on macroblock edges (e.g. as for RFC 2190).
+ * That is, it does not necessarily contain info about all macroblocks,
+ * as long as the distance between macroblocks in the info is smaller
+ * than the target payload size.
+ * Each MB info structure is 12 bytes, and is laid out as follows:
+ * @code
+ * u32le bit offset from the start of the packet
+ * u8 current quantizer at the start of the macroblock
+ * u8 GOB number
+ * u16le macroblock address within the GOB
+ * u8 horizontal MV predictor
+ * u8 vertical MV predictor
+ * u8 horizontal MV predictor for block number 3
+ * u8 vertical MV predictor for block number 3
+ * @endcode
+ */
+ AV_PKT_DATA_H263_MB_INFO,
+
+ /**
+ * This side data should be associated with an audio stream and contains
+ * ReplayGain information in form of the AVReplayGain struct.
+ */
+ AV_PKT_DATA_REPLAYGAIN,
+
+ /**
+ * This side data contains a 3x3 transformation matrix describing an affine
+ * transformation that needs to be applied to the decoded video frames for
+ * correct presentation.
+ *
+ * See libavutil/display.h for a detailed description of the data.
+ */
+ AV_PKT_DATA_DISPLAYMATRIX,
+
+ /**
+ * This side data should be associated with a video stream and contains
+ * Stereoscopic 3D information in form of the AVStereo3D struct.
+ */
+ AV_PKT_DATA_STEREO3D,
+
+ /**
+ * This side data should be associated with an audio stream and corresponds
+ * to enum AVAudioServiceType.
+ */
+ AV_PKT_DATA_AUDIO_SERVICE_TYPE,
+
+ /**
+ * This side data contains quality related information from the encoder.
+ * @code
+ * u32le quality factor of the compressed frame. Allowed range is between 1 (good) and FF_LAMBDA_MAX (bad).
+ * u8 picture type
+ * u8 error count
+ * u16 reserved
+ * u64le[error count] sum of squared differences between encoder in and output
+ * @endcode
+ */
+ AV_PKT_DATA_QUALITY_STATS,
+
+ /**
+ * Recommmends skipping the specified number of samples
+ * @code
+ * u32le number of samples to skip from start of this packet
+ * u32le number of samples to skip from end of this packet
+ * u8 reason for start skip
+ * u8 reason for end skip (0=padding silence, 1=convergence)
+ * @endcode
+ */
+ AV_PKT_DATA_SKIP_SAMPLES=70,
+
+ /**
+ * An AV_PKT_DATA_JP_DUALMONO side data packet indicates that
+ * the packet may contain "dual mono" audio specific to Japanese DTV
+ * and if it is true, recommends only the selected channel to be used.
+ * @code
+ * u8 selected channels (0=mail/left, 1=sub/right, 2=both)
+ * @endcode
+ */
+ AV_PKT_DATA_JP_DUALMONO,
+
+ /**
+ * A list of zero terminated key/value strings. There is no end marker for
+ * the list, so it is required to rely on the side data size to stop.
+ */
+ AV_PKT_DATA_STRINGS_METADATA,
+
+ /**
+ * Subtitle event position
+ * @code
+ * u32le x1
+ * u32le y1
+ * u32le x2
+ * u32le y2
+ * @endcode
+ */
+ AV_PKT_DATA_SUBTITLE_POSITION,
+
+ /**
+ * Data found in BlockAdditional element of matroska container. There is
+ * no end marker for the data, so it is required to rely on the side data
+ * size to recognize the end. 8 byte id (as found in BlockAddId) followed
+ * by data.
+ */
+ AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
+
+ /**
+ * The optional first identifier line of a WebVTT cue.
+ */
+ AV_PKT_DATA_WEBVTT_IDENTIFIER,
+
+ /**
+ * The optional settings (rendering instructions) that immediately
+ * follow the timestamp specifier of a WebVTT cue.
+ */
+ AV_PKT_DATA_WEBVTT_SETTINGS,
+
+ /**
+ * A list of zero terminated key/value strings. There is no end marker for
+ * the list, so it is required to rely on the side data size to stop. This
+ * side data includes updated metadata which appeared in the stream.
+ */
+ AV_PKT_DATA_METADATA_UPDATE,
+
+ /**
+ * The number of side data elements (in fact a bit more than it).
+ * This is not part of the public API/ABI in the sense that it may
+ * change when new side data types are added.
+ * This must stay the last enum value.
+ * If its value becomes huge, some code using it
+ * needs to be updated as it assumes it to be smaller than other limits.
+ */
+ AV_PKT_DATA_NB
+};
+
+#define AV_PKT_DATA_QUALITY_FACTOR AV_PKT_DATA_QUALITY_STATS //DEPRECATED
+
+typedef struct AVPacketSideData {
+ uint8_t *data;
+ int size;
+ enum AVPacketSideDataType type;
+} AVPacketSideData;
+
+/**
+ * This structure stores compressed data. It is typically exported by demuxers
+ * and then passed as input to decoders, or received as output from encoders and
+ * then passed to muxers.
+ *
+ * For video, it should typically contain one compressed frame. For audio it may
+ * contain several compressed frames.
+ *
+ * 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 or destruct (deprecated)
+ * fields. If either is set, the packet data is dynamically allocated and is
+ * valid indefinitely until av_free_packet() is called (which in turn calls
+ * av_buffer_unref()/the destruct callback to free the data). If neither is set,
+ * the packet data is typically backed by some static buffer somewhere and is
+ * only valid for a limited time (e.g. until the next read call when demuxing).
+ *
+ * The side data is always allocated with av_malloc() and is freed in
+ * av_free_packet().
+ */
+typedef struct AVPacket {
+ /**
+ * A reference to the reference-counted buffer where the packet data is
+ * stored.
+ * May be NULL, then the packet data is not reference-counted.
+ */
+ AVBufferRef *buf;
+ /**
+ * Presentation timestamp in AVStream->time_base units; the time at which
+ * the decompressed packet will be presented to the user.
+ * Can be AV_NOPTS_VALUE if it is not stored in the file.
+ * pts MUST be larger or equal to dts as presentation cannot happen before
+ * decompression, unless one wants to view hex dumps. Some formats misuse
+ * the terms dts and pts/cts to mean something different. Such timestamps
+ * must be converted to true pts/dts before they are stored in AVPacket.
+ */
+ int64_t pts;
+ /**
+ * Decompression timestamp in AVStream->time_base units; the time at which
+ * the packet is decompressed.
+ * Can be AV_NOPTS_VALUE if it is not stored in the file.
+ */
+ int64_t dts;
+ uint8_t *data;
+ int size;
+ int stream_index;
+ /**
+ * A combination of AV_PKT_FLAG values
+ */
+ int flags;
+ /**
+ * Additional packet data that can be provided by the container.
+ * Packet can contain several types of side information.
+ */
+ AVPacketSideData *side_data;
+ int side_data_elems;
+
+ /**
+ * Duration of this packet in AVStream->time_base units, 0 if unknown.
+ * Equals next_pts - this_pts in presentation order.
+ */
+ int duration;
+#if FF_API_DESTRUCT_PACKET
+ attribute_deprecated
+ void (*destruct)(struct AVPacket *);
+ attribute_deprecated
+ void *priv;
+#endif
+ int64_t pos; ///< byte position in stream, -1 if unknown
+
+ /**
+ * Time difference in AVStream->time_base units from the pts of this
+ * packet to the point at which the output from the decoder has converged
+ * independent from the availability of previous frames. That is, the
+ * frames are virtually identical no matter if decoding started from
+ * the very first frame or from this keyframe.
+ * Is AV_NOPTS_VALUE if unknown.
+ * This field is not the display duration of the current packet.
+ * This field has no meaning if the packet does not have AV_PKT_FLAG_KEY
+ * set.
+ *
+ * The purpose of this field is to allow seeking in streams that have no
+ * keyframes in the conventional sense. It corresponds to the
+ * recovery point SEI in H.264 and match_time_delta in NUT. It is also
+ * essential for some types of subtitle streams to ensure that all
+ * subtitles are correctly displayed after seeking.
+ */
+ int64_t convergence_duration;
+} AVPacket;
+#define AV_PKT_FLAG_KEY 0x0001 ///< The packet contains a keyframe
+#define AV_PKT_FLAG_CORRUPT 0x0002 ///< The packet content is corrupted
+
+enum AVSideDataParamChangeFlags {
+ AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT = 0x0001,
+ AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT = 0x0002,
+ AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE = 0x0004,
+ AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS = 0x0008,
+};
+/**
+ * @}
+ */
+
+struct AVCodecInternal;
+
+enum AVFieldOrder {
+ AV_FIELD_UNKNOWN,
+ AV_FIELD_PROGRESSIVE,
+ AV_FIELD_TT, //< Top coded_first, top displayed first
+ AV_FIELD_BB, //< Bottom coded first, bottom displayed first
+ AV_FIELD_TB, //< Top coded first, bottom displayed first
+ AV_FIELD_BT, //< Bottom coded first, top displayed first
+};
+
+/**
+ * main external API structure.
+ * New fields can be added to the end with minor version bumps.
+ * Removal, reordering and changes to existing fields require a major
+ * version bump.
+ * Please use AVOptions (av_opt* / av_set/get*()) to access these fields from user
+ * applications.
+ * sizeof(AVCodecContext) must not be used outside libav*.
+ */
+typedef struct AVCodecContext {
+ /**
+ * information on struct for av_log
+ * - set by avcodec_alloc_context3
+ */
+ const AVClass *av_class;
+ int log_level_offset;
+
+ enum AVMediaType codec_type; /* see AVMEDIA_TYPE_xxx */
+ const struct AVCodec *codec;
+#if FF_API_CODEC_NAME
+ /**
+ * @deprecated this field is not used for anything in libavcodec
+ */
+ attribute_deprecated
+ char codec_name[32];
+#endif
+ enum AVCodecID codec_id; /* see AV_CODEC_ID_xxx */
+
+ /**
+ * fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
+ * This is used to work around some encoder bugs.
+ * A demuxer should set this to what is stored in the field used to identify the codec.
+ * If there are multiple such fields in a container then the demuxer should choose the one
+ * which maximizes the information about the used codec.
+ * If the codec tag field in a container is larger than 32 bits then the demuxer should
+ * remap the longer ID to 32 bits with a table or other structure. Alternatively a new
+ * extra_codec_tag + size could be added but for this a clear advantage must be demonstrated
+ * first.
+ * - encoding: Set by user, if not then the default based on codec_id will be used.
+ * - decoding: Set by user, will be converted to uppercase by libavcodec during init.
+ */
+ unsigned int codec_tag;
+
+#if FF_API_STREAM_CODEC_TAG
+ /**
+ * @deprecated this field is unused
+ */
+ attribute_deprecated
+ unsigned int stream_codec_tag;
+#endif
+
+ void *priv_data;
+
+ /**
+ * Private context used for internal data.
+ *
+ * Unlike priv_data, this is not codec-specific. It is used in general
+ * libavcodec functions.
+ */
+ struct AVCodecInternal *internal;
+
+ /**
+ * Private data of the user, can be used to carry app specific stuff.
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ void *opaque;
+
+ /**
+ * the average bitrate
+ * - encoding: Set by user; unused for constant quantizer encoding.
+ * - decoding: Set by user, may be overwritten by libavcodec
+ * if this info is available in the stream
+ */
+ int bit_rate;
+
+ /**
+ * number of bits the bitstream is allowed to diverge from the reference.
+ * the reference can be CBR (for CBR pass1) or VBR (for pass2)
+ * - encoding: Set by user; unused for constant quantizer encoding.
+ * - decoding: unused
+ */
+ int bit_rate_tolerance;
+
+ /**
+ * Global quality for codecs which cannot change it per frame.
+ * This should be proportional to MPEG-1/2/4 qscale.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int global_quality;
+
+ /**
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int compression_level;
+#define FF_COMPRESSION_DEFAULT -1
+
+ /**
+ * AV_CODEC_FLAG_*.
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int flags;
+
+ /**
+ * AV_CODEC_FLAG2_*
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int flags2;
+
+ /**
+ * some codecs need / can use extradata like Huffman tables.
+ * mjpeg: Huffman tables
+ * rv10: additional flags
+ * mpeg4: global headers (they can be in the bitstream or here)
+ * The allocated memory should be AV_INPUT_BUFFER_PADDING_SIZE bytes larger
+ * than extradata_size to avoid problems if it is read with the bitstream reader.
+ * The bytewise contents of extradata must not depend on the architecture or CPU endianness.
+ * - encoding: Set/allocated/freed by libavcodec.
+ * - decoding: Set/allocated/freed by user.
+ */
+ uint8_t *extradata;
+ int extradata_size;
+
+ /**
+ * This is the fundamental unit of time (in seconds) in terms
+ * of which frame timestamps are represented. For fixed-fps content,
+ * timebase should be 1/framerate and timestamp increments should be
+ * identically 1.
+ * This often, but not always is the inverse of the frame rate or field rate
+ * for video.
+ * - encoding: MUST be set by user.
+ * - decoding: the use of this field for decoding is deprecated.
+ * Use framerate instead.
+ */
+ AVRational time_base;
+
+ /**
+ * For some codecs, the time base is closer to the field rate than the frame rate.
+ * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration
+ * if no telecine is used ...
+ *
+ * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2.
+ */
+ int ticks_per_frame;
+
+ /**
+ * Codec delay.
+ *
+ * Encoding: Number of frames delay there will be from the encoder input to
+ * the decoder output. (we assume the decoder matches the spec)
+ * Decoding: Number of frames delay in addition to what a standard decoder
+ * as specified in the spec would produce.
+ *
+ * Video:
+ * Number of frames the decoded output will be delayed relative to the
+ * encoded input.
+ *
+ * Audio:
+ * For encoding, this field is unused (see initial_padding).
+ *
+ * For decoding, this is the number of samples the decoder needs to
+ * output before the decoder's output is valid. When seeking, you should
+ * start decoding this many samples prior to your desired seek point.
+ *
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by libavcodec.
+ */
+ int delay;
+
+
+ /* video only */
+ /**
+ * picture width / height.
+ *
+ * @note Those fields may not match the values of the last
+ * AVFrame outputted by avcodec_decode_video2 due frame
+ * reordering.
+ *
+ * - encoding: MUST be set by user.
+ * - decoding: May be set by the user before opening the decoder if known e.g.
+ * from the container. Some decoders will require the dimensions
+ * to be set by the caller. During decoding, the decoder may
+ * overwrite those values as required while parsing the data.
+ */
+ int width, height;
+
+ /**
+ * Bitstream width / height, may be different from width/height e.g. when
+ * the decoded frame is cropped before being output or lowres is enabled.
+ *
+ * @note Those field may not match the value of the last
+ * AVFrame outputted by avcodec_decode_video2 due frame
+ * reordering.
+ *
+ * - encoding: unused
+ * - decoding: May be set by the user before opening the decoder if known
+ * e.g. from the container. During decoding, the decoder may
+ * overwrite those values as required while parsing the data.
+ */
+ int coded_width, coded_height;
+
+#if FF_API_ASPECT_EXTENDED
+#define FF_ASPECT_EXTENDED 15
+#endif
+
+ /**
+ * the number of pictures in a group of pictures, or 0 for intra_only
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int gop_size;
+
+ /**
+ * Pixel format, see AV_PIX_FMT_xxx.
+ * May be set by the demuxer if known from headers.
+ * May be overridden by the decoder if it knows better.
+ *
+ * @note This field may not match the value of the last
+ * AVFrame outputted by avcodec_decode_video2 due frame
+ * reordering.
+ *
+ * - encoding: Set by user.
+ * - decoding: Set by user if known, overridden by libavcodec while
+ * parsing the data.
+ */
+ enum AVPixelFormat pix_fmt;
+
+#if FF_API_MOTION_EST
+ /**
+ * This option does nothing
+ * @deprecated use codec private options instead
+ */
+ attribute_deprecated int me_method;
+#endif
+
+ /**
+ * If non NULL, 'draw_horiz_band' is called by the libavcodec
+ * decoder to draw a horizontal band. It improves cache usage. Not
+ * all codecs can do that. You must check the codec capabilities
+ * beforehand.
+ * When multithreading is used, it may be called from multiple threads
+ * at the same time; threads might draw different parts of the same AVFrame,
+ * or multiple AVFrames, and there is no guarantee that slices will be drawn
+ * in order.
+ * The function is also used by hardware acceleration APIs.
+ * It is called at least once during frame decoding to pass
+ * the data needed for hardware render.
+ * In that mode instead of pixel data, AVFrame points to
+ * a structure specific to the acceleration API. The application
+ * reads the structure and can change some fields to indicate progress
+ * or mark state.
+ * - encoding: unused
+ * - decoding: Set by user.
+ * @param height the height of the slice
+ * @param y the y position of the slice
+ * @param type 1->top field, 2->bottom field, 3->frame
+ * @param offset offset into the AVFrame.data from which the slice should be read
+ */
+ void (*draw_horiz_band)(struct AVCodecContext *s,
+ const AVFrame *src, int offset[AV_NUM_DATA_POINTERS],
+ int y, int type, int height);
+
+ /**
+ * callback to negotiate the pixelFormat
+ * @param fmt is the list of formats which are supported by the codec,
+ * it is terminated by -1 as 0 is a valid format, the formats are ordered by quality.
+ * The first is always the native one.
+ * @note The callback may be called again immediately if initialization for
+ * the selected (hardware-accelerated) pixel format failed.
+ * @warning Behavior is undefined if the callback returns a value not
+ * in the fmt list of formats.
+ * @return the chosen format
+ * - encoding: unused
+ * - decoding: Set by user, if not set the native format will be chosen.
+ */
+ enum AVPixelFormat (*get_format)(struct AVCodecContext *s, const enum AVPixelFormat * fmt);
+
+ /**
+ * maximum number of B-frames between non-B-frames
+ * Note: The output will be delayed by max_b_frames+1 relative to the input.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int max_b_frames;
+
+ /**
+ * qscale factor between IP and B-frames
+ * If > 0 then the last P-frame quantizer will be used (q= lastp_q*factor+offset).
+ * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float b_quant_factor;
+
+#if FF_API_RC_STRATEGY
+ /** @deprecated use codec private option instead */
+ attribute_deprecated int rc_strategy;
+#define FF_RC_STRATEGY_XVID 1
+#endif
+
+ int b_frame_strategy;
+
+ /**
+ * qscale offset between IP and B-frames
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float b_quant_offset;
+
+ /**
+ * Size of the frame reordering buffer in the decoder.
+ * For MPEG-2 it is 1 IPB or 0 low delay IP.
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by libavcodec.
+ */
+ int has_b_frames;
+
+ /**
+ * 0-> h263 quant 1-> mpeg quant
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mpeg_quant;
+
+ /**
+ * qscale factor between P and I-frames
+ * If > 0 then the last p frame quantizer will be used (q= lastp_q*factor+offset).
+ * If < 0 then normal ratecontrol will be done (q= -normal_q*factor+offset).
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float i_quant_factor;
+
+ /**
+ * qscale offset between P and I-frames
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float i_quant_offset;
+
+ /**
+ * luminance masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float lumi_masking;
+
+ /**
+ * temporary complexity masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float temporal_cplx_masking;
+
+ /**
+ * spatial complexity masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float spatial_cplx_masking;
+
+ /**
+ * p block masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float p_masking;
+
+ /**
+ * darkness masking (0-> disabled)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ float dark_masking;
+
+ /**
+ * slice count
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by user (or 0).
+ */
+ int slice_count;
+ /**
+ * prediction method (needed for huffyuv)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int prediction_method;
+#define FF_PRED_LEFT 0
+#define FF_PRED_PLANE 1
+#define FF_PRED_MEDIAN 2
+
+ /**
+ * slice offsets in the frame in bytes
+ * - encoding: Set/allocated by libavcodec.
+ * - decoding: Set/allocated by user (or NULL).
+ */
+ int *slice_offset;
+
+ /**
+ * sample aspect ratio (0 if unknown)
+ * That is the width of a pixel divided by the height of the pixel.
+ * Numerator and denominator must be relatively prime and smaller than 256 for some video standards.
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ AVRational sample_aspect_ratio;
+
+ /**
+ * motion estimation comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_cmp;
+ /**
+ * subpixel motion estimation comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_sub_cmp;
+ /**
+ * macroblock comparison function (not supported yet)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mb_cmp;
+ /**
+ * interlaced DCT comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int ildct_cmp;
+#define FF_CMP_SAD 0
+#define FF_CMP_SSE 1
+#define FF_CMP_SATD 2
+#define FF_CMP_DCT 3
+#define FF_CMP_PSNR 4
+#define FF_CMP_BIT 5
+#define FF_CMP_RD 6
+#define FF_CMP_ZERO 7
+#define FF_CMP_VSAD 8
+#define FF_CMP_VSSE 9
+#define FF_CMP_NSSE 10
+#define FF_CMP_W53 11
+#define FF_CMP_W97 12
+#define FF_CMP_DCTMAX 13
+#define FF_CMP_DCT264 14
+#define FF_CMP_CHROMA 256
+
+ /**
+ * ME diamond size & shape
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int dia_size;
+
+ /**
+ * amount of previous MV predictors (2a+1 x 2a+1 square)
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int last_predictor_count;
+
+ /**
+ * prepass for motion estimation
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int pre_me;
+
+ /**
+ * motion estimation prepass comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_pre_cmp;
+
+ /**
+ * ME prepass diamond size & shape
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int pre_dia_size;
+
+ /**
+ * subpel ME quality
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_subpel_quality;
+
+#if FF_API_AFD
+ /**
+ * DTG active format information (additional aspect ratio
+ * information only used in DVB MPEG-2 transport streams)
+ * 0 if not set.
+ *
+ * - encoding: unused
+ * - decoding: Set by decoder.
+ * @deprecated Deprecated in favor of AVSideData
+ */
+ attribute_deprecated int dtg_active_format;
+#define FF_DTG_AFD_SAME 8
+#define FF_DTG_AFD_4_3 9
+#define FF_DTG_AFD_16_9 10
+#define FF_DTG_AFD_14_9 11
+#define FF_DTG_AFD_4_3_SP_14_9 13
+#define FF_DTG_AFD_16_9_SP_14_9 14
+#define FF_DTG_AFD_SP_4_3 15
+#endif /* FF_API_AFD */
+
+ /**
+ * maximum motion estimation search range in subpel units
+ * If 0 then no limit.
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_range;
+
+#if FF_API_QUANT_BIAS
+ /**
+ * @deprecated use encoder private option instead
+ */
+ attribute_deprecated int intra_quant_bias;
+#define FF_DEFAULT_QUANT_BIAS 999999
+
+ /**
+ * @deprecated use encoder private option instead
+ */
+ attribute_deprecated int inter_quant_bias;
+#endif
+
+ /**
+ * slice flags
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int slice_flags;
+#define SLICE_FLAG_CODED_ORDER 0x0001 ///< draw_horiz_band() is called in coded order instead of display
+#define SLICE_FLAG_ALLOW_FIELD 0x0002 ///< allow draw_horiz_band() with field slices (MPEG2 field pics)
+#define SLICE_FLAG_ALLOW_PLANE 0x0004 ///< allow draw_horiz_band() with 1 component at a time (SVQ1)
+
+#if FF_API_XVMC
+ /**
+ * XVideo Motion Acceleration
+ * - encoding: forbidden
+ * - decoding: set by decoder
+ * @deprecated XvMC doesn't need it anymore.
+ */
+ attribute_deprecated int xvmc_acceleration;
+#endif /* FF_API_XVMC */
+
+ /**
+ * macroblock decision mode
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mb_decision;
+#define FF_MB_DECISION_SIMPLE 0 ///< uses mb_cmp
+#define FF_MB_DECISION_BITS 1 ///< chooses the one which needs the fewest bits
+#define FF_MB_DECISION_RD 2 ///< rate distortion
+
+ /**
+ * custom intra quantization matrix
+ * - encoding: Set by user, can be NULL.
+ * - decoding: Set by libavcodec.
+ */
+ uint16_t *intra_matrix;
+
+ /**
+ * custom inter quantization matrix
+ * - encoding: Set by user, can be NULL.
+ * - decoding: Set by libavcodec.
+ */
+ uint16_t *inter_matrix;
+
+ /**
+ * scene change detection threshold
+ * 0 is default, larger means fewer detected scene changes.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int scenechange_threshold;
+
+ /**
+ * noise reduction strength
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int noise_reduction;
+
+#if FF_API_MPV_OPT
+ /**
+ * @deprecated this field is unused
+ */
+ attribute_deprecated
+ int me_threshold;
+
+ /**
+ * @deprecated this field is unused
+ */
+ attribute_deprecated
+ int mb_threshold;
+#endif
+
+ /**
+ * precision of the intra DC coefficient - 8
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec
+ */
+ int intra_dc_precision;
+
+ /**
+ * Number of macroblock rows at the top which are skipped.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int skip_top;
+
+ /**
+ * Number of macroblock rows at the bottom which are skipped.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int skip_bottom;
+
+#if FF_API_MPV_OPT
+ /**
+ * @deprecated use encoder private options instead
+ */
+ attribute_deprecated
+ float border_masking;
+#endif
+
+ /**
+ * minimum MB lagrange multipler
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mb_lmin;
+
+ /**
+ * maximum MB lagrange multipler
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mb_lmax;
+
+ /**
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int me_penalty_compensation;
+
+ /**
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int bidir_refine;
+
+ /**
+ *
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int brd_scale;
+
+ /**
+ * minimum GOP size
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int keyint_min;
+
+ /**
+ * number of reference frames
+ * - encoding: Set by user.
+ * - decoding: Set by lavc.
+ */
+ int refs;
+
+ /**
+ * chroma qp offset from luma
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int chromaoffset;
+
+#if FF_API_UNUSED_MEMBERS
+ /**
+ * Multiplied by qscale for each frame and added to scene_change_score.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ attribute_deprecated int scenechange_factor;
+#endif
+
+ /**
+ *
+ * Note: Value depends upon the compare function used for fullpel ME.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int mv0_threshold;
+
+ /**
+ * Adjust sensitivity of b_frame_strategy 1.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int b_sensitivity;
+
+ /**
+ * Chromaticity coordinates of the source primaries.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVColorPrimaries color_primaries;
+
+ /**
+ * Color Transfer Characteristic.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVColorTransferCharacteristic color_trc;
+
+ /**
+ * YUV colorspace type.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVColorSpace colorspace;
+
+ /**
+ * MPEG vs JPEG YUV range.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVColorRange color_range;
+
+ /**
+ * This defines the location of chroma samples.
+ * - encoding: Set by user
+ * - decoding: Set by libavcodec
+ */
+ enum AVChromaLocation chroma_sample_location;
+
+ /**
+ * Number of slices.
+ * Indicates number of picture subdivisions. Used for parallelized
+ * decoding.
+ * - encoding: Set by user
+ * - decoding: unused
+ */
+ int slices;
+
+ /** Field order
+ * - encoding: set by libavcodec
+ * - decoding: Set by user.
+ */
+ enum AVFieldOrder field_order;
+
+ /* audio only */
+ int sample_rate; ///< samples per second
+ int channels; ///< number of audio channels
+
+ /**
+ * audio sample format
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ enum AVSampleFormat sample_fmt; ///< sample format
+
+ /* The following data should not be initialized. */
+ /**
+ * Number of samples per channel in an audio frame.
+ *
+ * - encoding: set by libavcodec in avcodec_open2(). Each submitted frame
+ * except the last must contain exactly frame_size samples per channel.
+ * May be 0 when the codec has AV_CODEC_CAP_VARIABLE_FRAME_SIZE set, then the
+ * frame size is not restricted.
+ * - decoding: may be set by some decoders to indicate constant frame size
+ */
+ int frame_size;
+
+ /**
+ * Frame counter, set by libavcodec.
+ *
+ * - decoding: total number of frames returned from the decoder so far.
+ * - encoding: total number of frames passed to the encoder so far.
+ *
+ * @note the counter is not incremented if encoding/decoding resulted in
+ * an error.
+ */
+ int frame_number;
+
+ /**
+ * number of bytes per packet if constant and known or 0
+ * Used by some WAV based audio codecs.
+ */
+ int block_align;
+
+ /**
+ * Audio cutoff bandwidth (0 means "automatic")
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int cutoff;
+
+#if FF_API_REQUEST_CHANNELS
+ /**
+ * Decoder should decode to this many channels if it can (0 for default)
+ * - encoding: unused
+ * - decoding: Set by user.
+ * @deprecated Deprecated in favor of request_channel_layout.
+ */
+ attribute_deprecated int request_channels;
+#endif
+
+ /**
+ * Audio channel layout.
+ * - encoding: set by user.
+ * - decoding: set by user, may be overwritten by libavcodec.
+ */
+ uint64_t channel_layout;
+
+ /**
+ * Request decoder to use this channel layout if it can (0 for default)
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ uint64_t request_channel_layout;
+
+ /**
+ * Type of service that the audio stream conveys.
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ enum AVAudioServiceType audio_service_type;
+
+ /**
+ * desired sample format
+ * - encoding: Not used.
+ * - decoding: Set by user.
+ * Decoder will decode to this format if it can.
+ */
+ enum AVSampleFormat request_sample_fmt;
+
+#if FF_API_GET_BUFFER
+ /**
+ * Called at the beginning of each frame to get a buffer for it.
+ *
+ * The function will set AVFrame.data[], AVFrame.linesize[].
+ * AVFrame.extended_data[] must also be set, but it should be the same as
+ * AVFrame.data[] except for planar audio with more channels than can fit
+ * in AVFrame.data[]. In that case, AVFrame.data[] shall still contain as
+ * many data pointers as it can hold.
+ *
+ * if CODEC_CAP_DR1 is not set then get_buffer() must call
+ * avcodec_default_get_buffer() instead of providing buffers allocated by
+ * some other means.
+ *
+ * AVFrame.data[] should be 32- or 16-byte-aligned unless the CPU doesn't
+ * need it. avcodec_default_get_buffer() aligns the output buffer properly,
+ * but if get_buffer() is overridden then alignment considerations should
+ * be taken into account.
+ *
+ * @see avcodec_default_get_buffer()
+ *
+ * Video:
+ *
+ * If pic.reference is set then the frame will be read later by libavcodec.
+ * avcodec_align_dimensions2() should be used to find the required width and
+ * height, as they normally need to be rounded up to the next multiple of 16.
+ *
+ * If frame multithreading is used and thread_safe_callbacks is set,
+ * it may be called from a different thread, but not from more than one at
+ * once. Does not need to be reentrant.
+ *
+ * @see release_buffer(), reget_buffer()
+ * @see avcodec_align_dimensions2()
+ *
+ * Audio:
+ *
+ * Decoders request a buffer of a particular size by setting
+ * AVFrame.nb_samples prior to calling get_buffer(). The decoder may,
+ * however, utilize only part of the buffer by setting AVFrame.nb_samples
+ * to a smaller value in the output frame.
+ *
+ * Decoders cannot use the buffer after returning from
+ * avcodec_decode_audio4(), so they will not call release_buffer(), as it
+ * is assumed to be released immediately upon return. In some rare cases,
+ * a decoder may need to call get_buffer() more than once in a single
+ * call to avcodec_decode_audio4(). In that case, when get_buffer() is
+ * called again after it has already been called once, the previously
+ * acquired buffer is assumed to be released at that time and may not be
+ * reused by the decoder.
+ *
+ * As a convenience, av_samples_get_buffer_size() and
+ * av_samples_fill_arrays() in libavutil may be used by custom get_buffer()
+ * functions to find the required data size and to fill data pointers and
+ * linesize. In AVFrame.linesize, only linesize[0] may be set for audio
+ * since all planes must be the same size.
+ *
+ * @see av_samples_get_buffer_size(), av_samples_fill_arrays()
+ *
+ * - encoding: unused
+ * - decoding: Set by libavcodec, user can override.
+ *
+ * @deprecated use get_buffer2()
+ */
+ attribute_deprecated
+ int (*get_buffer)(struct AVCodecContext *c, AVFrame *pic);
+
+ /**
+ * Called to release buffers which were allocated with get_buffer.
+ * A released buffer can be reused in get_buffer().
+ * pic.data[*] must be set to NULL.
+ * May be called from a different thread if frame multithreading is used,
+ * but not by more than one thread at once, so does not need to be reentrant.
+ * - encoding: unused
+ * - decoding: Set by libavcodec, user can override.
+ *
+ * @deprecated custom freeing callbacks should be set from get_buffer2()
+ */
+ attribute_deprecated
+ void (*release_buffer)(struct AVCodecContext *c, AVFrame *pic);
+
+ /**
+ * Called at the beginning of a frame to get cr buffer for it.
+ * Buffer type (size, hints) must be the same. libavcodec won't check it.
+ * libavcodec will pass previous buffer in pic, function should return
+ * same buffer or new buffer with old frame "painted" into it.
+ * If pic.data[0] == NULL must behave like get_buffer().
+ * if CODEC_CAP_DR1 is not set then reget_buffer() must call
+ * avcodec_default_reget_buffer() instead of providing buffers allocated by
+ * some other means.
+ * - encoding: unused
+ * - decoding: Set by libavcodec, user can override.
+ */
+ attribute_deprecated
+ int (*reget_buffer)(struct AVCodecContext *c, AVFrame *pic);
+#endif
+
+ /**
+ * This callback is called at the beginning of each frame to get data
+ * buffer(s) for it. There may be one contiguous buffer for all the data or
+ * there may be a buffer per each data plane or anything in between. What
+ * this means is, you may set however many entries in buf[] you feel necessary.
+ * Each buffer must be reference-counted using the AVBuffer API (see description
+ * of buf[] below).
+ *
+ * The following fields will be set in the frame before this callback is
+ * called:
+ * - format
+ * - width, height (video only)
+ * - sample_rate, channel_layout, nb_samples (audio only)
+ * Their values may differ from the corresponding values in
+ * AVCodecContext. This callback must use the frame values, not the codec
+ * context values, to calculate the required buffer size.
+ *
+ * This callback must fill the following fields in the frame:
+ * - data[]
+ * - linesize[]
+ * - extended_data:
+ * * if the data is planar audio with more than 8 channels, then this
+ * callback must allocate and fill extended_data to contain all pointers
+ * to all data planes. data[] must hold as many pointers as it can.
+ * extended_data must be allocated with av_malloc() and will be freed in
+ * av_frame_unref().
+ * * otherwise exended_data must point to data
+ * - buf[] must contain one or more pointers to AVBufferRef structures. Each of
+ * the frame's data and extended_data pointers must be contained in these. That
+ * is, one AVBufferRef for each allocated chunk of memory, not necessarily one
+ * AVBufferRef per data[] entry. See: av_buffer_create(), av_buffer_alloc(),
+ * and av_buffer_ref().
+ * - extended_buf and nb_extended_buf must be allocated with av_malloc() by
+ * this callback and filled with the extra buffers if there are more
+ * buffers than buf[] can hold. extended_buf will be freed in
+ * av_frame_unref().
+ *
+ * If AV_CODEC_CAP_DR1 is not set then get_buffer2() must call
+ * avcodec_default_get_buffer2() instead of providing buffers allocated by
+ * some other means.
+ *
+ * Each data plane must be aligned to the maximum required by the target
+ * CPU.
+ *
+ * @see avcodec_default_get_buffer2()
+ *
+ * Video:
+ *
+ * If AV_GET_BUFFER_FLAG_REF is set in flags then the frame may be reused
+ * (read and/or written to if it is writable) later by libavcodec.
+ *
+ * avcodec_align_dimensions2() should be used to find the required width and
+ * height, as they normally need to be rounded up to the next multiple of 16.
+ *
+ * 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.
+ *
+ * @see avcodec_align_dimensions2()
+ *
+ * Audio:
+ *
+ * Decoders request a buffer of a particular size by setting
+ * AVFrame.nb_samples prior to calling get_buffer2(). The decoder may,
+ * however, utilize only part of the buffer by setting AVFrame.nb_samples
+ * to a smaller value in the output frame.
+ *
+ * As a convenience, av_samples_get_buffer_size() and
+ * av_samples_fill_arrays() in libavutil may be used by custom get_buffer2()
+ * functions to find the required data size and to fill data pointers and
+ * linesize. In AVFrame.linesize, only linesize[0] may be set for audio
+ * since all planes must be the same size.
+ *
+ * @see av_samples_get_buffer_size(), av_samples_fill_arrays()
+ *
+ * - encoding: unused
+ * - decoding: Set by libavcodec, user can override.
+ */
+ int (*get_buffer2)(struct AVCodecContext *s, AVFrame *frame, int flags);
+
+ /**
+ * If non-zero, the decoded audio and video frames returned from
+ * avcodec_decode_video2() and avcodec_decode_audio4() are reference-counted
+ * and are valid indefinitely. The caller must free them with
+ * av_frame_unref() when they are not needed anymore.
+ * Otherwise, the decoded frames must not be freed by the caller and are
+ * only valid until the next decode call.
+ *
+ * - encoding: unused
+ * - decoding: set by the caller before avcodec_open2().
+ */
+ int refcounted_frames;
+
+ /* - encoding parameters */
+ float qcompress; ///< amount of qscale change between easy & hard scenes (0.0-1.0)
+ float qblur; ///< amount of qscale smoothing over time (0.0-1.0)
+
+ /**
+ * minimum quantizer
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int qmin;
+
+ /**
+ * maximum quantizer
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int qmax;
+
+ /**
+ * maximum quantizer difference between frames
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int max_qdiff;
+
+#if FF_API_MPV_OPT
+ /**
+ * @deprecated use encoder private options instead
+ */
+ attribute_deprecated
+ float rc_qsquish;
+
+ attribute_deprecated
+ float rc_qmod_amp;
+ attribute_deprecated
+ int rc_qmod_freq;
+#endif
+
+ /**
+ * decoder bitstream buffer size
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int rc_buffer_size;
+
+ /**
+ * ratecontrol override, see RcOverride
+ * - encoding: Allocated/set/freed by user.
+ * - decoding: unused
+ */
+ int rc_override_count;
+ RcOverride *rc_override;
+
+#if FF_API_MPV_OPT
+ /**
+ * @deprecated use encoder private options instead
+ */
+ attribute_deprecated
+ const char *rc_eq;
+#endif
+
+ /**
+ * maximum bitrate
+ * - encoding: Set by user.
+ * - decoding: Set by user, may be overwritten by libavcodec.
+ */
+ int rc_max_rate;
+
+ /**
+ * minimum bitrate
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int rc_min_rate;
+
+#if FF_API_MPV_OPT
+ /**
+ * @deprecated use encoder private options instead
+ */
+ attribute_deprecated
+ float rc_buffer_aggressivity;
+
+ attribute_deprecated
+ float rc_initial_cplx;
+#endif
+
+ /**
+ * Ratecontrol attempt to use, at maximum, <value> of what can be used without an underflow.
+ * - encoding: Set by user.
+ * - decoding: unused.
+ */
+ float rc_max_available_vbv_use;
+
+ /**
+ * Ratecontrol attempt to use, at least, <value> times the amount needed to prevent a vbv overflow.
+ * - encoding: Set by user.
+ * - decoding: unused.
+ */
+ float rc_min_vbv_overflow_use;
+
+ /**
+ * Number of bits which should be loaded into the rc buffer before decoding starts.
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int rc_initial_buffer_occupancy;
+
+#define FF_CODER_TYPE_VLC 0
+#define FF_CODER_TYPE_AC 1
+#define FF_CODER_TYPE_RAW 2
+#define FF_CODER_TYPE_RLE 3
+#if FF_API_UNUSED_MEMBERS
+#define FF_CODER_TYPE_DEFLATE 4
+#endif /* FF_API_UNUSED_MEMBERS */
+ /**
+ * coder type
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int coder_type;
+
+ /**
+ * context model
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int context_model;
+
+#if FF_API_MPV_OPT
+ /**
+ * @deprecated use encoder private options instead
+ */
+ attribute_deprecated
+ int lmin;
+
+ /**
+ * @deprecated use encoder private options instead
+ */
+ attribute_deprecated
+ int lmax;
+#endif
+
+ /**
+ * frame skip threshold
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int frame_skip_threshold;
+
+ /**
+ * frame skip factor
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int frame_skip_factor;
+
+ /**
+ * frame skip exponent
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int frame_skip_exp;
+
+ /**
+ * frame skip comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int frame_skip_cmp;
+
+ /**
+ * trellis RD quantization
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int trellis;
+
+ /**
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int min_prediction_order;
+
+ /**
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int max_prediction_order;
+
+ /**
+ * GOP timecode frame start number
+ * - encoding: Set by user, in non drop frame format
+ * - decoding: Set by libavcodec (timecode in the 25 bits format, -1 if unset)
+ */
+ int64_t timecode_frame_start;
+
+ /* The RTP callback: This function is called */
+ /* every time the encoder has a packet to send. */
+ /* It depends on the encoder if the data starts */
+ /* with a Start Code (it should). H.263 does. */
+ /* mb_nb contains the number of macroblocks */
+ /* encoded in the RTP payload. */
+ void (*rtp_callback)(struct AVCodecContext *avctx, void *data, int size, int mb_nb);
+
+ int rtp_payload_size; /* The size of the RTP payload: the coder will */
+ /* do its best to deliver a chunk with size */
+ /* below rtp_payload_size, the chunk will start */
+ /* with a start code on some codecs like H.263. */
+ /* This doesn't take account of any particular */
+ /* headers inside the transmitted RTP payload. */
+
+ /* statistics, used for 2-pass encoding */
+ int mv_bits;
+ int header_bits;
+ int i_tex_bits;
+ int p_tex_bits;
+ int i_count;
+ int p_count;
+ int skip_count;
+ int misc_bits;
+
+ /**
+ * number of bits used for the previously encoded frame
+ * - encoding: Set by libavcodec.
+ * - decoding: unused
+ */
+ int frame_bits;
+
+ /**
+ * pass1 encoding statistics output buffer
+ * - encoding: Set by libavcodec.
+ * - decoding: unused
+ */
+ char *stats_out;
+
+ /**
+ * pass2 encoding statistics input buffer
+ * Concatenated stuff from stats_out of pass1 should be placed here.
+ * - encoding: Allocated/set/freed by user.
+ * - decoding: unused
+ */
+ char *stats_in;
+
+ /**
+ * Work around bugs in encoders which sometimes cannot be detected automatically.
+ * - encoding: Set by user
+ * - decoding: Set by user
+ */
+ int workaround_bugs;
+#define FF_BUG_AUTODETECT 1 ///< autodetection
+#if FF_API_OLD_MSMPEG4
+#define FF_BUG_OLD_MSMPEG4 2
+#endif
+#define FF_BUG_XVID_ILACE 4
+#define FF_BUG_UMP4 8
+#define FF_BUG_NO_PADDING 16
+#define FF_BUG_AMV 32
+#if FF_API_AC_VLC
+#define FF_BUG_AC_VLC 0 ///< Will be removed, libavcodec can now handle these non-compliant files by default.
+#endif
+#define FF_BUG_QPEL_CHROMA 64
+#define FF_BUG_STD_QPEL 128
+#define FF_BUG_QPEL_CHROMA2 256
+#define FF_BUG_DIRECT_BLOCKSIZE 512
+#define FF_BUG_EDGE 1024
+#define FF_BUG_HPEL_CHROMA 2048
+#define FF_BUG_DC_CLIP 4096
+#define FF_BUG_MS 8192 ///< Work around various bugs in Microsoft's broken decoders.
+#define FF_BUG_TRUNCATED 16384
+
+ /**
+ * strictly follow the standard (MPEG4, ...).
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ * Setting this to STRICT or higher means the encoder and decoder will
+ * generally do stupid things, whereas setting it to unofficial or lower
+ * will mean the encoder might produce output that is not supported by all
+ * spec-compliant decoders. Decoders don't differentiate between normal,
+ * unofficial and experimental (that is, they always try to decode things
+ * when they can) unless they are explicitly asked to behave stupidly
+ * (=strictly conform to the specs)
+ */
+ int strict_std_compliance;
+#define FF_COMPLIANCE_VERY_STRICT 2 ///< Strictly conform to an older more strict version of the spec or reference software.
+#define FF_COMPLIANCE_STRICT 1 ///< Strictly conform to all the things in the spec no matter what consequences.
+#define FF_COMPLIANCE_NORMAL 0
+#define FF_COMPLIANCE_UNOFFICIAL -1 ///< Allow unofficial extensions
+#define FF_COMPLIANCE_EXPERIMENTAL -2 ///< Allow nonstandardized experimental things.
+
+ /**
+ * error concealment flags
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int error_concealment;
+#define FF_EC_GUESS_MVS 1
+#define FF_EC_DEBLOCK 2
+#define FF_EC_FAVOR_INTER 256
+
+ /**
+ * debug
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int debug;
+#define FF_DEBUG_PICT_INFO 1
+#define FF_DEBUG_RC 2
+#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
+#if FF_API_UNUSED_MEMBERS
+#define FF_DEBUG_PTS 0x00000200
+#endif /* FF_API_UNUSED_MEMBERS */
+#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 ///< only access through AVOptions from outside libavcodec
+#define FF_DEBUG_VIS_MB_TYPE 0x00004000 ///< only access through AVOptions from outside libavcodec
+#endif
+#define FF_DEBUG_BUFFERS 0x00008000
+#define FF_DEBUG_THREADS 0x00010000
+#define FF_DEBUG_GREEN_MD 0x00800000
+#define FF_DEBUG_NOMC 0x01000000
+
+#if FF_API_DEBUG_MV
+ /**
+ * debug
+ * Code outside libavcodec should access this field using AVOptions
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int debug_mv;
+#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames
+#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames
+#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames
+#endif
+
+ /**
+ * Error recognition; may misdetect some more or less valid parts as errors.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int err_recognition;
+
+/**
+ * Verify checksums embedded in the bitstream (could be of either encoded or
+ * decoded data, depending on the codec) and print an error message on mismatch.
+ * If AV_EF_EXPLODE is also set, a mismatching checksum will result in the
+ * decoder returning an error.
+ */
+#define AV_EF_CRCCHECK (1<<0)
+#define AV_EF_BITSTREAM (1<<1) ///< detect bitstream specification deviations
+#define AV_EF_BUFFER (1<<2) ///< detect improper bitstream length
+#define AV_EF_EXPLODE (1<<3) ///< abort decoding on minor error detection
+
+#define AV_EF_IGNORE_ERR (1<<15) ///< ignore errors and continue
+#define AV_EF_CAREFUL (1<<16) ///< consider things that violate the spec, are fast to calculate and have not been seen in the wild as errors
+#define AV_EF_COMPLIANT (1<<17) ///< consider all spec non compliances as errors
+#define AV_EF_AGGRESSIVE (1<<18) ///< consider things that a sane encoder should not do as an error
+
+
+ /**
+ * opaque 64bit number (generally a PTS) that will be reordered and
+ * output in AVFrame.reordered_opaque
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ int64_t reordered_opaque;
+
+ /**
+ * Hardware accelerator in use
+ * - encoding: unused.
+ * - decoding: Set by libavcodec
+ */
+ struct AVHWAccel *hwaccel;
+
+ /**
+ * Hardware accelerator context.
+ * For some hardware accelerators, a global context needs to be
+ * provided by the user. In that case, this holds display-dependent
+ * data FFmpeg cannot instantiate itself. Please refer to the
+ * FFmpeg HW accelerator documentation to know how to fill this
+ * is. e.g. for VA API, this is a struct vaapi_context.
+ * - encoding: unused
+ * - decoding: Set by user
+ */
+ void *hwaccel_context;
+
+ /**
+ * error
+ * - encoding: Set by libavcodec if flags & AV_CODEC_FLAG_PSNR.
+ * - decoding: unused
+ */
+ uint64_t error[AV_NUM_DATA_POINTERS];
+
+ /**
+ * DCT algorithm, see FF_DCT_* below
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int dct_algo;
+#define FF_DCT_AUTO 0
+#define FF_DCT_FASTINT 1
+#define FF_DCT_INT 2
+#define FF_DCT_MMX 3
+#define FF_DCT_ALTIVEC 5
+#define FF_DCT_FAAN 6
+
+ /**
+ * IDCT algorithm, see FF_IDCT_* below.
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int idct_algo;
+#define FF_IDCT_AUTO 0
+#define FF_IDCT_INT 1
+#define FF_IDCT_SIMPLE 2
+#define FF_IDCT_SIMPLEMMX 3
+#define FF_IDCT_ARM 7
+#define FF_IDCT_ALTIVEC 8
+#if FF_API_ARCH_SH4
+#define FF_IDCT_SH4 9
+#endif
+#define FF_IDCT_SIMPLEARM 10
+#if FF_API_UNUSED_MEMBERS
+#define FF_IDCT_IPP 13
+#endif /* FF_API_UNUSED_MEMBERS */
+#define FF_IDCT_XVID 14
+#if FF_API_IDCT_XVIDMMX
+#define FF_IDCT_XVIDMMX 14
+#endif /* FF_API_IDCT_XVIDMMX */
+#define FF_IDCT_SIMPLEARMV5TE 16
+#define FF_IDCT_SIMPLEARMV6 17
+#if FF_API_ARCH_SPARC
+#define FF_IDCT_SIMPLEVIS 18
+#endif
+#define FF_IDCT_FAAN 20
+#define FF_IDCT_SIMPLENEON 22
+#if FF_API_ARCH_ALPHA
+#define FF_IDCT_SIMPLEALPHA 23
+#endif
+#define FF_IDCT_SIMPLEAUTO 128
+
+ /**
+ * bits per sample/pixel from the demuxer (needed for huffyuv).
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by user.
+ */
+ int bits_per_coded_sample;
+
+ /**
+ * Bits per sample/pixel of internal libavcodec pixel/sample format.
+ * - encoding: set by user.
+ * - decoding: set by libavcodec.
+ */
+ int bits_per_raw_sample;
+
+#if FF_API_LOWRES
+ /**
+ * low resolution decoding, 1-> 1/2 size, 2->1/4 size
+ * - encoding: unused
+ * - decoding: Set by user.
+ * Code outside libavcodec should access this field using:
+ * av_codec_{get,set}_lowres(avctx)
+ */
+ int lowres;
+#endif
+
+#if FF_API_CODED_FRAME
+ /**
+ * the picture in the bitstream
+ * - encoding: Set by libavcodec.
+ * - decoding: unused
+ *
+ * @deprecated use the quality factor packet side data instead
+ */
+ attribute_deprecated AVFrame *coded_frame;
+#endif
+
+ /**
+ * thread count
+ * is used to decide how many independent tasks should be passed to execute()
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int thread_count;
+
+ /**
+ * Which multithreading methods to use.
+ * Use of FF_THREAD_FRAME will increase decoding delay by one frame per thread,
+ * so clients which cannot provide future frames should not use it.
+ *
+ * - encoding: Set by user, otherwise the default is used.
+ * - decoding: Set by user, otherwise the default is used.
+ */
+ int thread_type;
+#define FF_THREAD_FRAME 1 ///< Decode more than one frame at once
+#define FF_THREAD_SLICE 2 ///< Decode more than one part of a single frame at once
+
+ /**
+ * Which multithreading methods are in use by the codec.
+ * - encoding: Set by libavcodec.
+ * - decoding: Set by libavcodec.
+ */
+ int active_thread_type;
+
+ /**
+ * Set by the client if its custom get_buffer() callback can be called
+ * synchronously from another thread, which allows faster multithreaded decoding.
+ * draw_horiz_band() will be called from other threads regardless of this setting.
+ * Ignored if the default get_buffer() is used.
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int thread_safe_callbacks;
+
+ /**
+ * The codec may call this to execute several independent things.
+ * It will return only after finishing all tasks.
+ * The user may replace this with some multithreaded implementation,
+ * the default implementation will execute the parts serially.
+ * @param count the number of things to execute
+ * - encoding: Set by libavcodec, user can override.
+ * - decoding: Set by libavcodec, user can override.
+ */
+ int (*execute)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg), void *arg2, int *ret, int count, int size);
+
+ /**
+ * The codec may call this to execute several independent things.
+ * It will return only after finishing all tasks.
+ * The user may replace this with some multithreaded implementation,
+ * the default implementation will execute the parts serially.
+ * Also see avcodec_thread_init and e.g. the --enable-pthread configure option.
+ * @param c context passed also to func
+ * @param count the number of things to execute
+ * @param arg2 argument passed unchanged to func
+ * @param ret return values of executed functions, must have space for "count" values. May be NULL.
+ * @param func function that will be called count times, with jobnr from 0 to count-1.
+ * threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS and so that no
+ * two instances of func executing at the same time will have the same threadnr.
+ * @return always 0 currently, but code should handle a future improvement where when any call to func
+ * returns < 0 no further calls to func may be done and < 0 is returned.
+ * - encoding: Set by libavcodec, user can override.
+ * - decoding: Set by libavcodec, user can override.
+ */
+ int (*execute2)(struct AVCodecContext *c, int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr), void *arg2, int *ret, int count);
+
+#if FF_API_THREAD_OPAQUE
+ /**
+ * @deprecated this field should not be used from outside of lavc
+ */
+ attribute_deprecated
+ void *thread_opaque;
+#endif
+
+ /**
+ * noise vs. sse weight for the nsse comparison function
+ * - encoding: Set by user.
+ * - decoding: unused
+ */
+ int nsse_weight;
+
+ /**
+ * profile
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int profile;
+#define FF_PROFILE_UNKNOWN -99
+#define FF_PROFILE_RESERVED -100
+
+#define FF_PROFILE_AAC_MAIN 0
+#define FF_PROFILE_AAC_LOW 1
+#define FF_PROFILE_AAC_SSR 2
+#define FF_PROFILE_AAC_LTP 3
+#define FF_PROFILE_AAC_HE 4
+#define FF_PROFILE_AAC_HE_V2 28
+#define FF_PROFILE_AAC_LD 22
+#define FF_PROFILE_AAC_ELD 38
+#define FF_PROFILE_MPEG2_AAC_LOW 128
+#define FF_PROFILE_MPEG2_AAC_HE 131
+
+#define FF_PROFILE_DTS 20
+#define FF_PROFILE_DTS_ES 30
+#define FF_PROFILE_DTS_96_24 40
+#define FF_PROFILE_DTS_HD_HRA 50
+#define FF_PROFILE_DTS_HD_MA 60
+#define FF_PROFILE_DTS_EXPRESS 70
+
+#define FF_PROFILE_MPEG2_422 0
+#define FF_PROFILE_MPEG2_HIGH 1
+#define FF_PROFILE_MPEG2_SS 2
+#define FF_PROFILE_MPEG2_SNR_SCALABLE 3
+#define FF_PROFILE_MPEG2_MAIN 4
+#define FF_PROFILE_MPEG2_SIMPLE 5
+
+#define FF_PROFILE_H264_CONSTRAINED (1<<9) // 8+1; constraint_set1_flag
+#define FF_PROFILE_H264_INTRA (1<<11) // 8+3; constraint_set3_flag
+
+#define FF_PROFILE_H264_BASELINE 66
+#define FF_PROFILE_H264_CONSTRAINED_BASELINE (66|FF_PROFILE_H264_CONSTRAINED)
+#define FF_PROFILE_H264_MAIN 77
+#define FF_PROFILE_H264_EXTENDED 88
+#define FF_PROFILE_H264_HIGH 100
+#define FF_PROFILE_H264_HIGH_10 110
+#define FF_PROFILE_H264_HIGH_10_INTRA (110|FF_PROFILE_H264_INTRA)
+#define FF_PROFILE_H264_HIGH_422 122
+#define FF_PROFILE_H264_HIGH_422_INTRA (122|FF_PROFILE_H264_INTRA)
+#define FF_PROFILE_H264_HIGH_444 144
+#define FF_PROFILE_H264_HIGH_444_PREDICTIVE 244
+#define FF_PROFILE_H264_HIGH_444_INTRA (244|FF_PROFILE_H264_INTRA)
+#define FF_PROFILE_H264_CAVLC_444 44
+
+#define FF_PROFILE_VC1_SIMPLE 0
+#define FF_PROFILE_VC1_MAIN 1
+#define FF_PROFILE_VC1_COMPLEX 2
+#define FF_PROFILE_VC1_ADVANCED 3
+
+#define FF_PROFILE_MPEG4_SIMPLE 0
+#define FF_PROFILE_MPEG4_SIMPLE_SCALABLE 1
+#define FF_PROFILE_MPEG4_CORE 2
+#define FF_PROFILE_MPEG4_MAIN 3
+#define FF_PROFILE_MPEG4_N_BIT 4
+#define FF_PROFILE_MPEG4_SCALABLE_TEXTURE 5
+#define FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION 6
+#define FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE 7
+#define FF_PROFILE_MPEG4_HYBRID 8
+#define FF_PROFILE_MPEG4_ADVANCED_REAL_TIME 9
+#define FF_PROFILE_MPEG4_CORE_SCALABLE 10
+#define FF_PROFILE_MPEG4_ADVANCED_CODING 11
+#define FF_PROFILE_MPEG4_ADVANCED_CORE 12
+#define FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE 13
+#define FF_PROFILE_MPEG4_SIMPLE_STUDIO 14
+#define FF_PROFILE_MPEG4_ADVANCED_SIMPLE 15
+
+#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0 0
+#define FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1 1
+#define FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION 2
+#define FF_PROFILE_JPEG2000_DCINEMA_2K 3
+#define FF_PROFILE_JPEG2000_DCINEMA_4K 4
+
+#define FF_PROFILE_VP9_0 0
+#define FF_PROFILE_VP9_1 1
+#define FF_PROFILE_VP9_2 2
+#define FF_PROFILE_VP9_3 3
+
+#define FF_PROFILE_HEVC_MAIN 1
+#define FF_PROFILE_HEVC_MAIN_10 2
+#define FF_PROFILE_HEVC_MAIN_STILL_PICTURE 3
+#define FF_PROFILE_HEVC_REXT 4
+
+ /**
+ * level
+ * - encoding: Set by user.
+ * - decoding: Set by libavcodec.
+ */
+ int level;
+#define FF_LEVEL_UNKNOWN -99
+
+ /**
+ * Skip loop filtering for selected frames.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ enum AVDiscard skip_loop_filter;
+
+ /**
+ * Skip IDCT/dequantization for selected frames.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ enum AVDiscard skip_idct;
+
+ /**
+ * Skip decoding for selected frames.
+ * - encoding: unused
+ * - decoding: Set by user.
+ */
+ enum AVDiscard skip_frame;
+
+ /**
+ * Header containing style information for text subtitles.
+ * For SUBTITLE_ASS subtitle type, it should contain the whole ASS
+ * [Script Info] and [V4+ Styles] section, plus the [Events] line and
+ * the Format line following. It shouldn't include any Dialogue line.
+ * - encoding: Set/allocated/freed by user (before avcodec_open2())
+ * - decoding: Set/allocated/freed by libavcodec (by avcodec_open2())
+ */
+ uint8_t *subtitle_header;
+ int subtitle_header_size;
+
+#if FF_API_ERROR_RATE
+ /**
+ * @deprecated use the 'error_rate' private AVOption of the mpegvideo
+ * encoders
+ */
+ attribute_deprecated
+ int error_rate;
+#endif
+
+#if FF_API_CODEC_PKT
+ /**
+ * @deprecated this field is not supposed to be accessed from outside lavc
+ */
+ attribute_deprecated
+ AVPacket *pkt;
+#endif
+
+ /**
+ * VBV delay coded in the last frame (in periods of a 27 MHz clock).
+ * Used for compliant TS muxing.
+ * - encoding: Set by libavcodec.
+ * - decoding: unused.
+ */
+ uint64_t vbv_delay;
+
+ /**
+ * Encoding only. Allow encoders to output packets that do not contain any
+ * encoded data, only side data.
+ *
+ * Some encoders need to output such packets, e.g. to update some stream
+ * parameters at the end of encoding.
+ *
+ * All callers are strongly recommended to set this option to 1 and update
+ * their code to deal with such packets, since this behaviour may become
+ * always enabled in the future (then this option will be deprecated and
+ * later removed). To avoid ABI issues when this happens, the callers should
+ * use AVOptions to set this field.
+ */
+ int side_data_only_packets;
+
+ /**
+ * Audio only. The number of "priming" samples (padding) inserted by the
+ * encoder at the beginning of the audio. I.e. this number of leading
+ * decoded samples must be discarded by the caller to get the original audio
+ * without leading padding.
+ *
+ * - decoding: unused
+ * - encoding: Set by libavcodec. The timestamps on the output packets are
+ * adjusted by the encoder so that they always refer to the
+ * first sample of the data actually contained in the packet,
+ * including any added padding. E.g. if the timebase is
+ * 1/samplerate and the timestamp of the first input sample is
+ * 0, the timestamp of the first output packet will be
+ * -initial_padding.
+ */
+ int initial_padding;
+
+ /**
+ * - decoding: For codecs that store a framerate value in the compressed
+ * bitstream, the decoder may export it here. { 0, 1} when
+ * unknown.
+ * - encoding: unused
+ */
+ AVRational framerate;
+
+ /**
+ * Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
+ * - encoding: unused.
+ * - decoding: Set by libavcodec before calling get_format()
+ */
+ enum AVPixelFormat sw_pix_fmt;
+
+ /**
+ * Timebase in which pkt_dts/pts and AVPacket.dts/pts are.
+ * Code outside libavcodec should access this field using:
+ * av_codec_{get,set}_pkt_timebase(avctx)
+ * - encoding unused.
+ * - decoding set by user.
+ */
+ AVRational pkt_timebase;
+
+ /**
+ * AVCodecDescriptor
+ * Code outside libavcodec should access this field using:
+ * av_codec_{get,set}_codec_descriptor(avctx)
+ * - encoding: unused.
+ * - decoding: set by libavcodec.
+ */
+ const AVCodecDescriptor *codec_descriptor;
+
+#if !FF_API_LOWRES
+ /**
+ * low resolution decoding, 1-> 1/2 size, 2->1/4 size
+ * - encoding: unused
+ * - decoding: Set by user.
+ * Code outside libavcodec should access this field using:
+ * av_codec_{get,set}_lowres(avctx)
+ */
+ int lowres;
+#endif
+
+ /**
+ * Current statistics for PTS correction.
+ * - decoding: maintained and used by libavcodec, not intended to be used by user apps
+ * - encoding: unused
+ */
+ int64_t pts_correction_num_faulty_pts; /// Number of incorrect PTS values so far
+ int64_t pts_correction_num_faulty_dts; /// Number of incorrect DTS values so far
+ int64_t pts_correction_last_pts; /// PTS of the last frame
+ int64_t pts_correction_last_dts; /// DTS of the last frame
+
+ /**
+ * Character encoding of the input subtitles file.
+ * - decoding: set by user
+ * - encoding: unused
+ */
+ char *sub_charenc;
+
+ /**
+ * Subtitles character encoding mode. Formats or codecs might be adjusting
+ * this setting (if they are doing the conversion themselves for instance).
+ * - decoding: set by libavcodec
+ * - encoding: unused
+ */
+ int sub_charenc_mode;
+#define FF_SUB_CHARENC_MODE_DO_NOTHING -1 ///< do nothing (demuxer outputs a stream supposed to be already in UTF-8, or the codec is bitmap for instance)
+#define FF_SUB_CHARENC_MODE_AUTOMATIC 0 ///< libavcodec will select the mode itself
+#define FF_SUB_CHARENC_MODE_PRE_DECODER 1 ///< the AVPacket data needs to be recoded to UTF-8 before being fed to the decoder, requires iconv
+
+ /**
+ * Skip processing alpha if supported by codec.
+ * Note that if the format uses pre-multiplied alpha (common with VP6,
+ * and recommended due to better video quality/compression)
+ * the image will look as if alpha-blended onto a black background.
+ * However for formats that do not use pre-multiplied alpha
+ * there might be serious artefacts (though e.g. libswscale currently
+ * assumes pre-multiplied alpha anyway).
+ * Code outside libavcodec should access this field using AVOptions
+ *
+ * - decoding: set by user
+ * - encoding: unused
+ */
+ int skip_alpha;
+
+ /**
+ * Number of samples to skip after a discontinuity
+ * - decoding: unused
+ * - encoding: set by libavcodec
+ */
+ int seek_preroll;
+
+#if !FF_API_DEBUG_MV
+ /**
+ * debug motion vectors
+ * Code outside libavcodec should access this field using AVOptions
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ int debug_mv;
+#define FF_DEBUG_VIS_MV_P_FOR 0x00000001 //visualize forward predicted MVs of P frames
+#define FF_DEBUG_VIS_MV_B_FOR 0x00000002 //visualize forward predicted MVs of B frames
+#define FF_DEBUG_VIS_MV_B_BACK 0x00000004 //visualize backward predicted MVs of B frames
+#endif
+
+ /**
+ * custom intra quantization matrix
+ * Code outside libavcodec should access this field using av_codec_g/set_chroma_intra_matrix()
+ * - encoding: Set by user, can be NULL.
+ * - decoding: unused.
+ */
+ uint16_t *chroma_intra_matrix;
+
+ /**
+ * dump format separator.
+ * can be ", " or "\n " or anything else
+ * Code outside libavcodec should access this field using AVOptions
+ * (NO direct access).
+ * - encoding: Set by user.
+ * - decoding: Set by user.
+ */
+ uint8_t *dump_separator;
+
+ /**
+ * ',' separated list of allowed decoders.
+ * If NULL then all are allowed
+ * - encoding: unused
+ * - decoding: set by user through AVOPtions (NO direct access)
+ */
+ char *codec_whitelist;
+
+ /*
+ * Properties of the stream that gets decoded
+ * To be accessed through av_codec_get_properties() (NO direct access)
+ * - encoding: unused
+ * - decoding: set by libavcodec
+ */
+ unsigned properties;
+#define FF_CODEC_PROPERTY_LOSSLESS 0x00000001
+#define FF_CODEC_PROPERTY_CLOSED_CAPTIONS 0x00000002
+} AVCodecContext;
+
+AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx);
+void av_codec_set_pkt_timebase (AVCodecContext *avctx, AVRational val);
+
+const AVCodecDescriptor *av_codec_get_codec_descriptor(const AVCodecContext *avctx);
+void av_codec_set_codec_descriptor(AVCodecContext *avctx, const AVCodecDescriptor *desc);
+
+unsigned av_codec_get_codec_properties(const AVCodecContext *avctx);
+
+int av_codec_get_lowres(const AVCodecContext *avctx);
+void av_codec_set_lowres(AVCodecContext *avctx, int val);
+
+int av_codec_get_seek_preroll(const AVCodecContext *avctx);
+void av_codec_set_seek_preroll(AVCodecContext *avctx, int val);
+
+uint16_t *av_codec_get_chroma_intra_matrix(const AVCodecContext *avctx);
+void av_codec_set_chroma_intra_matrix(AVCodecContext *avctx, uint16_t *val);
+
+/**
+ * AVProfile.
+ */
+typedef struct AVProfile {
+ int profile;
+ const char *name; ///< short name for the profile
+} AVProfile;
+
+typedef struct AVCodecDefault AVCodecDefault;
+
+struct AVSubtitle;
+
+/**
+ * AVCodec.
+ */
+typedef struct AVCodec {
+ /**
+ * Name of the codec implementation.
+ * The name is globally unique among encoders and among decoders (but an
+ * encoder and a decoder can share the same name).
+ * This is the primary way to find a codec from the user perspective.
+ */
+ const char *name;
+ /**
+ * Descriptive name for the codec, meant to be more human readable than name.
+ * You should use the NULL_IF_CONFIG_SMALL() macro to define it.
+ */
+ const char *long_name;
+ enum AVMediaType type;
+ enum AVCodecID id;
+ /**
+ * Codec capabilities.
+ * see AV_CODEC_CAP_*
+ */
+ int capabilities;
+ const AVRational *supported_framerates; ///< array of supported framerates, or NULL if any, array is terminated by {0,0}
+ const enum AVPixelFormat *pix_fmts; ///< array of supported pixel formats, or NULL if unknown, array is terminated by -1
+ const int *supported_samplerates; ///< array of supported audio samplerates, or NULL if unknown, array is terminated by 0
+ const enum AVSampleFormat *sample_fmts; ///< array of supported sample formats, or NULL if unknown, array is terminated by -1
+ const uint64_t *channel_layouts; ///< array of support channel layouts, or NULL if unknown. array is terminated by 0
+ uint8_t max_lowres; ///< maximum value for lowres supported by the decoder, no direct access, use av_codec_get_max_lowres()
+ const AVClass *priv_class; ///< AVClass for the private context
+ const AVProfile *profiles; ///< array of recognized profiles, or NULL if unknown, array is terminated by {FF_PROFILE_UNKNOWN}
+
+ /*****************************************************************
+ * No fields below this line are part of the public API. They
+ * may not be used outside of libavcodec and can be changed and
+ * removed at will.
+ * New public fields should be added right above.
+ *****************************************************************
+ */
+ int priv_data_size;
+ struct AVCodec *next;
+ /**
+ * @name Frame-level threading support functions
+ * @{
+ */
+ /**
+ * If defined, called on thread contexts when they are created.
+ * If the codec allocates writable tables in init(), re-allocate them here.
+ * priv_data will be set to a copy of the original.
+ */
+ int (*init_thread_copy)(AVCodecContext *);
+ /**
+ * Copy necessary context variables from a previous thread context to the current one.
+ * If not defined, the next thread will start automatically; otherwise, the codec
+ * must call ff_thread_finish_setup().
+ *
+ * dst and src will (rarely) point to the same context, in which case memcpy should be skipped.
+ */
+ int (*update_thread_context)(AVCodecContext *dst, const AVCodecContext *src);
+ /** @} */
+
+ /**
+ * Private codec-specific defaults.
+ */
+ const AVCodecDefault *defaults;
+
+ /**
+ * Initialize codec static data, called from avcodec_register().
+ */
+ void (*init_static_data)(struct AVCodec *codec);
+
+ int (*init)(AVCodecContext *);
+ int (*encode_sub)(AVCodecContext *, uint8_t *buf, int buf_size,
+ const struct AVSubtitle *sub);
+ /**
+ * Encode data to an AVPacket.
+ *
+ * @param avctx codec context
+ * @param avpkt output AVPacket (may contain a user-provided buffer)
+ * @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.
+ * @return 0 on success, negative error code on failure
+ */
+ int (*encode2)(AVCodecContext *avctx, AVPacket *avpkt, const AVFrame *frame,
+ int *got_packet_ptr);
+ int (*decode)(AVCodecContext *, void *outdata, int *outdata_size, AVPacket *avpkt);
+ int (*close)(AVCodecContext *);
+ /**
+ * Flush buffers.
+ * Will be called when seeking
+ */
+ void (*flush)(AVCodecContext *);
+ /**
+ * Internal codec capabilities.
+ * See FF_CODEC_CAP_* in internal.h
+ */
+ int caps_internal;
+} AVCodec;
+
+int av_codec_get_max_lowres(const AVCodec *codec);
+
+struct MpegEncContext;
+
+/**
+ * @defgroup lavc_hwaccel AVHWAccel
+ * @{
+ */
+typedef struct AVHWAccel {
+ /**
+ * Name of the hardware accelerated codec.
+ * The name is globally unique among encoders and among decoders (but an
+ * encoder and a decoder can share the same name).
+ */
+ const char *name;
+
+ /**
+ * Type of codec implemented by the hardware accelerator.
+ *
+ * See AVMEDIA_TYPE_xxx
+ */
+ enum AVMediaType type;
+
+ /**
+ * Codec implemented by the hardware accelerator.
+ *
+ * See AV_CODEC_ID_xxx
+ */
+ enum AVCodecID id;
+
+ /**
+ * Supported pixel format.
+ *
+ * Only hardware accelerated formats are supported here.
+ */
+ enum AVPixelFormat pix_fmt;
+
+ /**
+ * Hardware accelerated codec capabilities.
+ * see HWACCEL_CODEC_CAP_*
+ */
+ int capabilities;
+
+ /*****************************************************************
+ * No fields below this line are part of the public API. They
+ * may not be used outside of libavcodec and can be changed and
+ * removed at will.
+ * New public fields should be added right above.
+ *****************************************************************
+ */
+ struct AVHWAccel *next;
+
+ /**
+ * Allocate a custom buffer
+ */
+ int (*alloc_frame)(AVCodecContext *avctx, AVFrame *frame);
+
+ /**
+ * Called at the beginning of each frame or field picture.
+ *
+ * Meaningful frame information (codec specific) is guaranteed to
+ * be parsed at this point. This function is mandatory.
+ *
+ * Note that buf can be NULL along with buf_size set to 0.
+ * Otherwise, this means the whole frame is available at this point.
+ *
+ * @param avctx the codec context
+ * @param buf the frame data buffer base
+ * @param buf_size the size of the frame in bytes
+ * @return zero if successful, a negative value otherwise
+ */
+ int (*start_frame)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size);
+
+ /**
+ * Callback for each slice.
+ *
+ * Meaningful slice information (codec specific) is guaranteed to
+ * be parsed at this point. This function is mandatory.
+ * The only exception is XvMC, that works on MB level.
+ *
+ * @param avctx the codec context
+ * @param buf the slice data buffer base
+ * @param buf_size the size of the slice in bytes
+ * @return zero if successful, a negative value otherwise
+ */
+ int (*decode_slice)(AVCodecContext *avctx, const uint8_t *buf, uint32_t buf_size);
+
+ /**
+ * Called at the end of each frame or field picture.
+ *
+ * The whole picture is parsed at this point and can now be sent
+ * to the hardware accelerator. This function is mandatory.
+ *
+ * @param avctx the codec context
+ * @return zero if successful, a negative value otherwise
+ */
+ int (*end_frame)(AVCodecContext *avctx);
+
+ /**
+ * Size of per-frame hardware accelerator private data.
+ *
+ * Private data is allocated with av_mallocz() before
+ * AVCodecContext.get_buffer() and deallocated after
+ * AVCodecContext.release_buffer().
+ */
+ int frame_priv_data_size;
+
+ /**
+ * Called for every Macroblock in a slice.
+ *
+ * XvMC uses it to replace the ff_mpv_decode_mb().
+ * Instead of decoding to raw picture, MB parameters are
+ * stored in an array provided by the video driver.
+ *
+ * @param s the mpeg context
+ */
+ void (*decode_mb)(struct MpegEncContext *s);
+
+ /**
+ * Initialize the hwaccel private data.
+ *
+ * This will be called from ff_get_format(), after hwaccel and
+ * hwaccel_context are set and the hwaccel private data in AVCodecInternal
+ * is allocated.
+ */
+ int (*init)(AVCodecContext *avctx);
+
+ /**
+ * Uninitialize the hwaccel private data.
+ *
+ * This will be called from get_format() or avcodec_close(), after hwaccel
+ * and hwaccel_context are already uninitialized.
+ */
+ int (*uninit)(AVCodecContext *avctx);
+
+ /**
+ * Size of the private data to allocate in
+ * AVCodecInternal.hwaccel_priv_data.
+ */
+ int priv_data_size;
+} AVHWAccel;
+
+/**
+ * Hardware acceleration should be used for decoding even if the codec level
+ * used is unknown or higher than the maximum supported level reported by the
+ * hardware driver.
+ *
+ * It's generally a good idea to pass this flag unless you have a specific
+ * reason not to, as hardware tends to under-report supported levels.
+ */
+#define AV_HWACCEL_FLAG_IGNORE_LEVEL (1 << 0)
+
+/**
+ * Hardware acceleration can output YUV pixel formats with a different chroma
+ * sampling than 4:2:0 and/or other than 8 bits per component.
+ */
+#define AV_HWACCEL_FLAG_ALLOW_HIGH_DEPTH (1 << 1)
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup lavc_picture AVPicture
+ *
+ * Functions for working with AVPicture
+ * @{
+ */
+
+/**
+ * Picture data structure.
+ *
+ * Up to four components can be stored into it, the last component is
+ * alpha.
+ */
+typedef struct AVPicture {
+ uint8_t *data[AV_NUM_DATA_POINTERS]; ///< pointers to the image data planes
+ int linesize[AV_NUM_DATA_POINTERS]; ///< number of bytes per line
+} AVPicture;
+
+/**
+ * @}
+ */
+
+enum AVSubtitleType {
+ SUBTITLE_NONE,
+
+ SUBTITLE_BITMAP, ///< A bitmap, pict will be set
+
+ /**
+ * Plain text, the text field must be set by the decoder and is
+ * authoritative. ass and pict fields may contain approximations.
+ */
+ SUBTITLE_TEXT,
+
+ /**
+ * Formatted text, the ass field must be set by the decoder and is
+ * authoritative. pict and text fields may contain approximations.
+ */
+ SUBTITLE_ASS,
+};
+
+#define AV_SUBTITLE_FLAG_FORCED 0x00000001
+
+typedef struct AVSubtitleRect {
+ int x; ///< top left corner of pict, undefined when pict is not set
+ int y; ///< top left corner of pict, undefined when pict is not set
+ int w; ///< width of pict, undefined when pict is not set
+ int h; ///< height of pict, undefined when pict is not set
+ int nb_colors; ///< number of colors in pict, undefined when pict is not set
+
+ /**
+ * data+linesize for the bitmap of this subtitle.
+ * can be set for text/ass as well once they are rendered
+ */
+ AVPicture pict;
+ enum AVSubtitleType type;
+
+ char *text; ///< 0 terminated plain UTF-8 text
+
+ /**
+ * 0 terminated ASS/SSA compatible event line.
+ * The presentation of this is unaffected by the other values in this
+ * struct.
+ */
+ char *ass;
+
+ int flags;
+} AVSubtitleRect;
+
+typedef struct AVSubtitle {
+ uint16_t format; /* 0 = graphics */
+ uint32_t start_display_time; /* relative to packet pts, in ms */
+ uint32_t end_display_time; /* relative to packet pts, in ms */
+ unsigned num_rects;
+ AVSubtitleRect **rects;
+ int64_t pts; ///< Same as packet pts, in AV_TIME_BASE
+} AVSubtitle;
+
+/**
+ * If c is NULL, returns the first registered codec,
+ * if c is non-NULL, returns the next registered codec after c,
+ * or NULL if c is the last one.
+ */
+AVCodec *av_codec_next(const AVCodec *c);
+
+/**
+ * Return the LIBAVCODEC_VERSION_INT constant.
+ */
+unsigned avcodec_version(void);
+
+/**
+ * Return the libavcodec build-time configuration.
+ */
+const char *avcodec_configuration(void);
+
+/**
+ * Return the libavcodec license.
+ */
+const char *avcodec_license(void);
+
+/**
+ * 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()
+ */
+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
+ */
+void avcodec_register_all(void);
+
+/**
+ * Allocate an AVCodecContext and set its fields to default values. The
+ * resulting struct should be freed with avcodec_free_context().
+ *
+ * @param codec if non-NULL, allocate private data and initialize defaults
+ * for the given codec. It is illegal to then call avcodec_open2()
+ * with a different codec.
+ * If NULL, then the codec-specific defaults won't be initialized,
+ * which may result in suboptimal default settings (this is
+ * important mainly for encoders, e.g. libx264).
+ *
+ * @return An AVCodecContext filled with default values or NULL on failure.
+ * @see avcodec_get_context_defaults
+ */
+AVCodecContext *avcodec_alloc_context3(const AVCodec *codec);
+
+/**
+ * Free the codec context and everything associated with it and write NULL to
+ * the provided pointer.
+ */
+void avcodec_free_context(AVCodecContext **avctx);
+
+/**
+ * Set the fields of the given AVCodecContext to default values corresponding
+ * to the given codec (defaults may be codec-dependent).
+ *
+ * Do not call this function if a non-NULL codec has been passed
+ * to avcodec_alloc_context3() that allocated this AVCodecContext.
+ * If codec is non-NULL, it is illegal to call avcodec_open2() with a
+ * different codec on this AVCodecContext.
+ */
+int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec);
+
+/**
+ * Get the AVClass for AVCodecContext. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *avcodec_get_class(void);
+
+/**
+ * Get the AVClass for AVFrame. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *avcodec_get_frame_class(void);
+
+/**
+ * Get the AVClass for AVSubtitleRect. It can be used in combination with
+ * AV_OPT_SEARCH_FAKE_OBJ for examining options.
+ *
+ * @see av_opt_find().
+ */
+const AVClass *avcodec_get_subtitle_rect_class(void);
+
+/**
+ * Copy the settings of the source AVCodecContext into the destination
+ * AVCodecContext. The resulting destination codec context will be
+ * unopened, i.e. you are required to call avcodec_open2() before you
+ * can use this AVCodecContext to decode/encode video/audio data.
+ *
+ * @param dest target codec context, should be initialized with
+ * avcodec_alloc_context3(NULL), but otherwise uninitialized
+ * @param src source codec context
+ * @return AVERROR() on error (e.g. memory allocation error), 0 on success
+ */
+int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src);
+
+#if FF_API_AVFRAME_LAVC
+/**
+ * @deprecated use av_frame_alloc()
+ */
+attribute_deprecated
+AVFrame *avcodec_alloc_frame(void);
+
+/**
+ * Set the fields of the given AVFrame to default values.
+ *
+ * @param frame The AVFrame of which the fields should be set to default values.
+ *
+ * @deprecated use av_frame_unref()
+ */
+attribute_deprecated
+void avcodec_get_frame_defaults(AVFrame *frame);
+
+/**
+ * Free the frame and any dynamically allocated objects in it,
+ * e.g. extended_data.
+ *
+ * @param frame frame to be freed. The pointer will be set to NULL.
+ *
+ * @warning this function does NOT free the data buffers themselves
+ * (it does not know how, since they might have been allocated with
+ * a custom get_buffer()).
+ *
+ * @deprecated use av_frame_free()
+ */
+attribute_deprecated
+void avcodec_free_frame(AVFrame **frame);
+#endif
+
+/**
+ * Initialize the AVCodecContext to use the given AVCodec. Prior to using this
+ * function the context has to be allocated with avcodec_alloc_context3().
+ *
+ * The functions avcodec_find_decoder_by_name(), avcodec_find_encoder_by_name(),
+ * avcodec_find_decoder() and avcodec_find_encoder() provide an easy way for
+ * retrieving a codec.
+ *
+ * @warning This function is not thread safe!
+ *
+ * @note Always call this function before using decoding routines (such as
+ * @ref avcodec_decode_video2()).
+ *
+ * @code
+ * avcodec_register_all();
+ * av_dict_set(&opts, "b", "2.5M", 0);
+ * codec = avcodec_find_decoder(AV_CODEC_ID_H264);
+ * if (!codec)
+ * exit(1);
+ *
+ * context = avcodec_alloc_context3(codec);
+ *
+ * if (avcodec_open2(context, codec, opts) < 0)
+ * exit(1);
+ * @endcode
+ *
+ * @param avctx The context to initialize.
+ * @param codec The codec to open this context for. If a non-NULL codec has been
+ * previously passed to avcodec_alloc_context3() or
+ * avcodec_get_context_defaults3() for this context, then this
+ * parameter MUST be either NULL or equal to the previously passed
+ * codec.
+ * @param options A dictionary filled with AVCodecContext and codec-private options.
+ * On return this object will be filled with options that were not found.
+ *
+ * @return zero on success, a negative value on error
+ * @see avcodec_alloc_context3(), avcodec_find_decoder(), avcodec_find_encoder(),
+ * av_dict_set(), av_opt_find().
+ */
+int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
+
+/**
+ * Close a given AVCodecContext and free all the data associated with it
+ * (but not the AVCodecContext itself).
+ *
+ * Calling this function on an AVCodecContext that hasn't been opened will free
+ * the codec-specific data allocated in avcodec_alloc_context3() /
+ * avcodec_get_context_defaults3() with a non-NULL codec. Subsequent calls will
+ * do nothing.
+ */
+int avcodec_close(AVCodecContext *avctx);
+
+/**
+ * Free all allocated data in the given subtitle struct.
+ *
+ * @param sub AVSubtitle to free.
+ */
+void avsubtitle_free(AVSubtitle *sub);
+
+/**
+ * @}
+ */
+
+/**
+ * @addtogroup lavc_packet
+ * @{
+ */
+
+#if FF_API_DESTRUCT_PACKET
+/**
+ * Default packet destructor.
+ * @deprecated use the AVBuffer API instead
+ */
+attribute_deprecated
+void av_destruct_packet(AVPacket *pkt);
+#endif
+
+/**
+ * Initialize optional fields of a packet with default values.
+ *
+ * Note, this does not touch the data and size members, which have to be
+ * initialized separately.
+ *
+ * @param pkt packet
+ */
+void av_init_packet(AVPacket *pkt);
+
+/**
+ * Allocate the payload of a packet and initialize its fields with
+ * default values.
+ *
+ * @param pkt packet
+ * @param size wanted payload size
+ * @return 0 if OK, AVERROR_xxx otherwise
+ */
+int av_new_packet(AVPacket *pkt, int size);
+
+/**
+ * Reduce packet size, correctly zeroing padding
+ *
+ * @param pkt packet
+ * @param size new size
+ */
+void av_shrink_packet(AVPacket *pkt, int size);
+
+/**
+ * Increase packet size, correctly zeroing padding
+ *
+ * @param pkt packet
+ * @param grow_by number of bytes by which to increase the size of the packet
+ */
+int av_grow_packet(AVPacket *pkt, int grow_by);
+
+/**
+ * Initialize a reference-counted packet from av_malloc()ed data.
+ *
+ * @param pkt packet to be initialized. This function will set the data, size,
+ * buf and destruct fields, all others are left untouched.
+ * @param data Data allocated by av_malloc() to be used as packet data. If this
+ * function returns successfully, the data is owned by the underlying AVBuffer.
+ * The caller may not access the data through other means.
+ * @param size size of data in bytes, without the padding. I.e. the full buffer
+ * size is assumed to be size + AV_INPUT_BUFFER_PADDING_SIZE.
+ *
+ * @return 0 on success, a negative AVERROR on error
+ */
+int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size);
+
+/**
+ * @warning This is a hack - the packet memory allocation stuff is broken. The
+ * packet is allocated if it was not really allocated.
+ */
+int av_dup_packet(AVPacket *pkt);
+
+/**
+ * Copy packet, including contents
+ *
+ * @return 0 on success, negative AVERROR on fail
+ */
+int av_copy_packet(AVPacket *dst, const AVPacket *src);
+
+/**
+ * Copy packet side data
+ *
+ * @return 0 on success, negative AVERROR on fail
+ */
+int av_copy_packet_side_data(AVPacket *dst, const AVPacket *src);
+
+/**
+ * Free a packet.
+ *
+ * @param pkt packet to free
+ */
+void av_free_packet(AVPacket *pkt);
+
+/**
+ * Allocate new information of a packet.
+ *
+ * @param pkt packet
+ * @param type side information type
+ * @param size side information size
+ * @return pointer to fresh allocated data or NULL otherwise
+ */
+uint8_t* av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
+ int size);
+
+/**
+ * Shrink the already allocated side data buffer
+ *
+ * @param pkt packet
+ * @param type side information type
+ * @param size new side information size
+ * @return 0 on success, < 0 on failure
+ */
+int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
+ int size);
+
+/**
+ * Get side information from packet.
+ *
+ * @param pkt packet
+ * @param type desired side information type
+ * @param size pointer for side information size to store (optional)
+ * @return pointer to data if present or NULL otherwise
+ */
+uint8_t* av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
+ int *size);
+
+int av_packet_merge_side_data(AVPacket *pkt);
+
+int av_packet_split_side_data(AVPacket *pkt);
+
+const char *av_packet_side_data_name(enum AVPacketSideDataType type);
+
+/**
+ * Pack a dictionary for use in side_data.
+ *
+ * @param dict The dictionary to pack.
+ * @param size pointer to store the size of the returned data
+ * @return pointer to data if successful, NULL otherwise
+ */
+uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size);
+/**
+ * Unpack a dictionary from side_data.
+ *
+ * @param data data from side_data
+ * @param size size of the data
+ * @param dict the metadata storage dictionary
+ * @return 0 on success, < 0 on failure
+ */
+int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict);
+
+
+/**
+ * Convenience function to free all the side data stored.
+ * All the other fields stay untouched.
+ *
+ * @param pkt packet
+ */
+void av_packet_free_side_data(AVPacket *pkt);
+
+/**
+ * Setup a new reference to the data described by a given packet
+ *
+ * If src is reference-counted, setup dst as a new reference to the
+ * buffer in src. Otherwise allocate a new buffer in dst and copy the
+ * data from src into it.
+ *
+ * All the other fields are copied from src.
+ *
+ * @see av_packet_unref
+ *
+ * @param dst Destination packet
+ * @param src Source packet
+ *
+ * @return 0 on success, a negative AVERROR on error.
+ */
+int av_packet_ref(AVPacket *dst, const AVPacket *src);
+
+/**
+ * Wipe the packet.
+ *
+ * Unreference the buffer referenced by the packet and reset the
+ * remaining packet fields to their default values.
+ *
+ * @param pkt The packet to be unreferenced.
+ */
+void av_packet_unref(AVPacket *pkt);
+
+/**
+ * Move every field in src to dst and reset src.
+ *
+ * @see av_packet_unref
+ *
+ * @param src Source packet, will be reset
+ * @param dst Destination packet
+ */
+void av_packet_move_ref(AVPacket *dst, AVPacket *src);
+
+/**
+ * Copy only "properties" fields from src to dst.
+ *
+ * Properties for the purpose of this function are all the fields
+ * beside those related to the packet data (buf, data, size)
+ *
+ * @param dst Destination packet
+ * @param src Source packet
+ *
+ * @return 0 on success AVERROR on failure.
+ *
+ */
+int av_packet_copy_props(AVPacket *dst, const AVPacket *src);
+
+/**
+ * Convert valid timing fields (timestamps / durations) in a packet from one
+ * timebase to another. Timestamps with unknown values (AV_NOPTS_VALUE) will be
+ * ignored.
+ *
+ * @param pkt packet on which the conversion will be performed
+ * @param tb_src source timebase, in which the timing fields in pkt are
+ * expressed
+ * @param tb_dst destination timebase, to which the timing fields will be
+ * converted
+ */
+void av_packet_rescale_ts(AVPacket *pkt, AVRational tb_src, AVRational tb_dst);
+
+/**
+ * @}
+ */
+
+/**
+ * @addtogroup lavc_decoding
+ * @{
+ */
+
+/**
+ * Find a registered decoder with a matching codec ID.
+ *
+ * @param id AVCodecID of the requested decoder
+ * @return A decoder if one was found, NULL otherwise.
+ */
+AVCodec *avcodec_find_decoder(enum AVCodecID id);
+
+/**
+ * Find a registered decoder with the specified name.
+ *
+ * @param name name of the requested decoder
+ * @return A decoder if one was found, NULL otherwise.
+ */
+AVCodec *avcodec_find_decoder_by_name(const char *name);
+
+#if FF_API_GET_BUFFER
+attribute_deprecated int avcodec_default_get_buffer(AVCodecContext *s, AVFrame *pic);
+attribute_deprecated void avcodec_default_release_buffer(AVCodecContext *s, AVFrame *pic);
+attribute_deprecated int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic);
+#endif
+
+/**
+ * The default callback for AVCodecContext.get_buffer2(). It is made public so
+ * it can be called by custom get_buffer2() implementations for decoders without
+ * AV_CODEC_CAP_DR1 set.
+ */
+int avcodec_default_get_buffer2(AVCodecContext *s, AVFrame *frame, int flags);
+
+#if FF_API_EMU_EDGE
+/**
+ * Return the amount of padding in pixels which the get_buffer callback must
+ * provide around the edge of the image for codecs which do not have the
+ * CODEC_FLAG_EMU_EDGE flag.
+ *
+ * @return Required padding in pixels.
+ *
+ * @deprecated CODEC_FLAG_EMU_EDGE is deprecated, so this function is no longer
+ * needed
+ */
+attribute_deprecated
+unsigned avcodec_get_edge_width(void);
+#endif
+
+/**
+ * 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
+ * padding.
+ *
+ * May only be used if a codec with AV_CODEC_CAP_DR1 has been opened.
+ */
+void avcodec_align_dimensions(AVCodecContext *s, int *width, int *height);
+
+/**
+ * Modify width and height values so that they will result in a memory
+ * buffer that is acceptable for the codec if you also ensure that all
+ * line sizes are a multiple of the respective linesize_align[i].
+ *
+ * May only be used if a codec with AV_CODEC_CAP_DR1 has been opened.
+ */
+void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height,
+ int linesize_align[AV_NUM_DATA_POINTERS]);
+
+/**
+ * Converts AVChromaLocation to swscale x/y chroma position.
+ *
+ * The positions represent the chroma (0,0) position in a coordinates system
+ * with luma (0,0) representing the origin and luma(1,1) representing 256,256
+ *
+ * @param xpos horizontal chroma sample position
+ * @param ypos vertical chroma sample position
+ */
+int avcodec_enum_to_chroma_pos(int *xpos, int *ypos, enum AVChromaLocation pos);
+
+/**
+ * Converts swscale x/y chroma position to AVChromaLocation.
+ *
+ * The positions represent the chroma (0,0) position in a coordinates system
+ * with luma (0,0) representing the origin and luma(1,1) representing 256,256
+ *
+ * @param xpos horizontal chroma sample position
+ * @param ypos vertical chroma sample position
+ */
+enum AVChromaLocation avcodec_chroma_pos_to_enum(int xpos, int ypos);
+
+#if FF_API_OLD_DECODE_AUDIO
+/**
+ * Wrapper function which calls avcodec_decode_audio4.
+ *
+ * @deprecated Use avcodec_decode_audio4 instead.
+ *
+ * Decode the audio frame of size avpkt->size from avpkt->data into samples.
+ * Some decoders may support multiple frames in a single AVPacket, such
+ * decoders would then just decode the first frame. In this case,
+ * avcodec_decode_audio3 has to be called again with an AVPacket that contains
+ * the remaining data in order to decode the second frame etc.
+ * If no frame
+ * could be outputted, frame_size_ptr is zero. Otherwise, it is the
+ * decompressed frame size in bytes.
+ *
+ * @warning You must set frame_size_ptr to the allocated size of the
+ * output buffer before calling avcodec_decode_audio3().
+ *
+ * @warning The input buffer must be FF_INPUT_BUFFER_PADDING_SIZE larger than
+ * the actual read bytes because some optimized bitstream readers read 32 or 64
+ * bits at once and could read over the end.
+ *
+ * @warning The end of the input buffer avpkt->data should be set to 0 to ensure that
+ * no overreading happens for damaged MPEG streams.
+ *
+ * @warning You must not provide a custom get_buffer() when using
+ * avcodec_decode_audio3(). Doing so will override it with
+ * avcodec_default_get_buffer. Use avcodec_decode_audio4() instead,
+ * which does allow the application to provide a custom get_buffer().
+ *
+ * @note You might have to align the input buffer avpkt->data and output buffer
+ * samples. The alignment requirements depend on the CPU: On some CPUs it isn't
+ * necessary at all, on others it won't work at all if not aligned and on others
+ * it will work but it will have an impact on performance.
+ *
+ * In practice, avpkt->data should have 4 byte alignment at minimum and
+ * samples should be 16 byte aligned unless the CPU doesn't need it
+ * (AltiVec and SSE do).
+ *
+ * @note Codecs which have the CODEC_CAP_DELAY capability set have a delay
+ * between input and output, these need to be fed with avpkt->data=NULL,
+ * avpkt->size=0 at the end to return the remaining frames.
+ *
+ * @param avctx the codec context
+ * @param[out] samples the output buffer, sample type in avctx->sample_fmt
+ * If the sample format is planar, each channel plane will
+ * be the same size, with no padding between channels.
+ * @param[in,out] frame_size_ptr the output buffer size in bytes
+ * @param[in] avpkt The input AVPacket containing the input buffer.
+ * You can create such packet with av_init_packet() and by then setting
+ * data and size, some decoders might in addition need other fields.
+ * All decoders are designed to use the least fields possible though.
+ * @return On error a negative value is returned, otherwise the number of bytes
+ * used or zero if no frame data was decompressed (used) from the input AVPacket.
+ */
+attribute_deprecated int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
+ int *frame_size_ptr,
+ AVPacket *avpkt);
+#endif
+
+/**
+ * Decode the audio frame of size avpkt->size from avpkt->data into frame.
+ *
+ * Some decoders may support multiple frames in a single AVPacket. Such
+ * decoders would then just decode the first frame and the return value would be
+ * less than the packet size. In this case, avcodec_decode_audio4 has to be
+ * called again with an AVPacket containing the remaining data in order to
+ * decode the second frame, etc... Even if no frames are returned, the packet
+ * needs to be fed to the decoder with remaining data until it is completely
+ * consumed or an error occurs.
+ *
+ * Some decoders (those marked with AV_CODEC_CAP_DELAY) have a delay between input
+ * and output. This means that for some packets they will not immediately
+ * produce decoded output and need to be flushed at the end of decoding to get
+ * all the decoded data. Flushing is done by calling this function with packets
+ * with avpkt->data set to NULL and avpkt->size set to 0 until it stops
+ * returning samples. It is safe to flush even those decoders that are not
+ * marked with AV_CODEC_CAP_DELAY, then no samples will be returned.
+ *
+ * @warning The input buffer, avpkt->data must be AV_INPUT_BUFFER_PADDING_SIZE
+ * larger than the actual read bytes because some optimized bitstream
+ * readers read 32 or 64 bits at once and could read over the end.
+ *
+ * @note The AVCodecContext MUST have been opened with @ref avcodec_open2()
+ * before packets may be fed to the decoder.
+ *
+ * @param avctx the codec context
+ * @param[out] frame The AVFrame in which to store decoded audio samples.
+ * The decoder will allocate a buffer for the decoded frame by
+ * calling the AVCodecContext.get_buffer2() callback.
+ * When AVCodecContext.refcounted_frames is set to 1, the frame is
+ * reference counted and the returned reference belongs to the
+ * caller. The caller must release the frame using av_frame_unref()
+ * when the frame is no longer needed. The caller may safely write
+ * to the frame if av_frame_is_writable() returns 1.
+ * When AVCodecContext.refcounted_frames is set to 0, the returned
+ * reference belongs to the decoder and is valid only until the
+ * next call to this function or until closing or flushing the
+ * decoder. The caller may not write to it.
+ * @param[out] got_frame_ptr Zero if no frame could be decoded, otherwise it is
+ * non-zero. Note that this field being set to zero
+ * does not mean that an error has occurred. For
+ * decoders with AV_CODEC_CAP_DELAY set, no given decode
+ * call is guaranteed to produce a frame.
+ * @param[in] avpkt The input AVPacket containing the input buffer.
+ * At least avpkt->data and avpkt->size should be set. Some
+ * decoders might also require additional fields to be set.
+ * @return A negative error code is returned if an error occurred during
+ * decoding, otherwise the number of bytes consumed from the input
+ * AVPacket is returned.
+ */
+int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame,
+ int *got_frame_ptr, const AVPacket *avpkt);
+
+/**
+ * Decode the video frame of size avpkt->size from avpkt->data into picture.
+ * Some decoders may support multiple frames in a single AVPacket, such
+ * decoders would then just decode the first frame.
+ *
+ * @warning The input buffer must be AV_INPUT_BUFFER_PADDING_SIZE larger than
+ * the actual read bytes because some optimized bitstream readers read 32 or 64
+ * bits at once and could read over the end.
+ *
+ * @warning The end of the input buffer buf should be set to 0 to ensure that
+ * no overreading happens for damaged MPEG streams.
+ *
+ * @note Codecs which have the AV_CODEC_CAP_DELAY capability set have a delay
+ * between input and output, these need to be fed with avpkt->data=NULL,
+ * avpkt->size=0 at the end to return the remaining frames.
+ *
+ * @note The AVCodecContext MUST have been opened with @ref avcodec_open2()
+ * before packets may be fed to the decoder.
+ *
+ * @param avctx the codec context
+ * @param[out] picture The AVFrame in which the decoded video frame will be stored.
+ * Use av_frame_alloc() to get an AVFrame. The codec will
+ * allocate memory for the actual bitmap by calling the
+ * AVCodecContext.get_buffer2() callback.
+ * When AVCodecContext.refcounted_frames is set to 1, the frame is
+ * reference counted and the returned reference belongs to the
+ * caller. The caller must release the frame using av_frame_unref()
+ * when the frame is no longer needed. The caller may safely write
+ * to the frame if av_frame_is_writable() returns 1.
+ * When AVCodecContext.refcounted_frames is set to 0, the returned
+ * reference belongs to the decoder and is valid only until the
+ * next call to this function or until closing or flushing the
+ * decoder. The caller may not write to it.
+ *
+ * @param[in] avpkt The input AVPacket containing the input buffer.
+ * You can create such packet with av_init_packet() and by then setting
+ * data and size, some decoders might in addition need other fields like
+ * flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least
+ * fields possible.
+ * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero.
+ * @return On error a negative value is returned, otherwise the number of bytes
+ * used or zero if no frame could be decompressed.
+ */
+int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
+ int *got_picture_ptr,
+ const AVPacket *avpkt);
+
+/**
+ * Decode a subtitle message.
+ * Return a negative value on error, otherwise return the number of bytes used.
+ * If no subtitle could be decompressed, got_sub_ptr is zero.
+ * Otherwise, the subtitle is stored in *sub.
+ * Note that AV_CODEC_CAP_DR1 is not available for subtitle codecs. This is for
+ * simplicity, because the performance difference is expect to be negligible
+ * and reusing a get_buffer written for video codecs would probably perform badly
+ * due to a potentially very different allocation pattern.
+ *
+ * Some decoders (those marked with CODEC_CAP_DELAY) have a delay between input
+ * and output. This means that for some packets they will not immediately
+ * produce decoded output and need to be flushed at the end of decoding to get
+ * all the decoded data. Flushing is done by calling this function with packets
+ * with avpkt->data set to NULL and avpkt->size set to 0 until it stops
+ * returning subtitles. It is safe to flush even those decoders that are not
+ * marked with CODEC_CAP_DELAY, then no subtitles will be returned.
+ *
+ * @note The AVCodecContext MUST have been opened with @ref avcodec_open2()
+ * before packets may be fed to the decoder.
+ *
+ * @param avctx the codec context
+ * @param[out] sub The Preallocated AVSubtitle in which the decoded subtitle will be stored,
+ * must be freed with avsubtitle_free if *got_sub_ptr is set.
+ * @param[in,out] got_sub_ptr Zero if no subtitle could be decompressed, otherwise, it is nonzero.
+ * @param[in] avpkt The input AVPacket containing the input buffer.
+ */
+int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub,
+ int *got_sub_ptr,
+ AVPacket *avpkt);
+
+/**
+ * @defgroup lavc_parsing Frame parsing
+ * @{
+ */
+
+enum AVPictureStructure {
+ AV_PICTURE_STRUCTURE_UNKNOWN, //< unknown
+ AV_PICTURE_STRUCTURE_TOP_FIELD, //< coded as top field
+ AV_PICTURE_STRUCTURE_BOTTOM_FIELD, //< coded as bottom field
+ AV_PICTURE_STRUCTURE_FRAME, //< coded as frame
+};
+
+typedef struct AVCodecParserContext {
+ void *priv_data;
+ struct AVCodecParser *parser;
+ int64_t frame_offset; /* offset of the current frame */
+ int64_t cur_offset; /* current offset
+ (incremented by each av_parser_parse()) */
+ int64_t next_frame_offset; /* offset of the next frame */
+ /* video info */
+ int pict_type; /* XXX: Put it back in AVCodecContext. */
+ /**
+ * This field is used for proper frame duration computation in lavf.
+ * It signals, how much longer the frame duration of the current frame
+ * is compared to normal frame duration.
+ *
+ * frame_duration = (1 + repeat_pict) * time_base
+ *
+ * It is used by codecs like H.264 to display telecined material.
+ */
+ int repeat_pict; /* XXX: Put it back in AVCodecContext. */
+ int64_t pts; /* pts of the current frame */
+ int64_t dts; /* dts of the current frame */
+
+ /* private data */
+ int64_t last_pts;
+ int64_t last_dts;
+ int fetch_timestamp;
+
+#define AV_PARSER_PTS_NB 4
+ int cur_frame_start_index;
+ int64_t cur_frame_offset[AV_PARSER_PTS_NB];
+ int64_t cur_frame_pts[AV_PARSER_PTS_NB];
+ int64_t cur_frame_dts[AV_PARSER_PTS_NB];
+
+ int flags;
+#define PARSER_FLAG_COMPLETE_FRAMES 0x0001
+#define PARSER_FLAG_ONCE 0x0002
+/// Set if the parser has a valid file offset
+#define PARSER_FLAG_FETCHED_OFFSET 0x0004
+#define PARSER_FLAG_USE_CODEC_TS 0x1000
+
+ int64_t offset; ///< byte offset from starting packet start
+ int64_t cur_frame_end[AV_PARSER_PTS_NB];
+
+ /**
+ * Set by parser to 1 for key frames and 0 for non-key frames.
+ * It is initialized to -1, so if the parser doesn't set this flag,
+ * old-style fallback using AV_PICTURE_TYPE_I picture type as key frames
+ * will be used.
+ */
+ int key_frame;
+
+ /**
+ * Time difference in stream time base units from the pts of this
+ * packet to the point at which the output from the decoder has converged
+ * independent from the availability of previous frames. That is, the
+ * frames are virtually identical no matter if decoding started from
+ * the very first frame or from this keyframe.
+ * Is AV_NOPTS_VALUE if unknown.
+ * This field is not the display duration of the current frame.
+ * This field has no meaning if the packet does not have AV_PKT_FLAG_KEY
+ * set.
+ *
+ * The purpose of this field is to allow seeking in streams that have no
+ * keyframes in the conventional sense. It corresponds to the
+ * recovery point SEI in H.264 and match_time_delta in NUT. It is also
+ * essential for some types of subtitle streams to ensure that all
+ * subtitles are correctly displayed after seeking.
+ */
+ int64_t convergence_duration;
+
+ // Timestamp generation support:
+ /**
+ * Synchronization point for start of timestamp generation.
+ *
+ * Set to >0 for sync point, 0 for no sync point and <0 for undefined
+ * (default).
+ *
+ * For example, this corresponds to presence of H.264 buffering period
+ * SEI message.
+ */
+ int dts_sync_point;
+
+ /**
+ * Offset of the current timestamp against last timestamp sync point in
+ * units of AVCodecContext.time_base.
+ *
+ * Set to INT_MIN when dts_sync_point unused. Otherwise, it must
+ * contain a valid timestamp offset.
+ *
+ * Note that the timestamp of sync point has usually a nonzero
+ * dts_ref_dts_delta, which refers to the previous sync point. Offset of
+ * the next frame after timestamp sync point will be usually 1.
+ *
+ * For example, this corresponds to H.264 cpb_removal_delay.
+ */
+ int dts_ref_dts_delta;
+
+ /**
+ * Presentation delay of current frame in units of AVCodecContext.time_base.
+ *
+ * Set to INT_MIN when dts_sync_point unused. Otherwise, it must
+ * contain valid non-negative timestamp delta (presentation time of a frame
+ * must not lie in the past).
+ *
+ * This delay represents the difference between decoding and presentation
+ * time of the frame.
+ *
+ * For example, this corresponds to H.264 dpb_output_delay.
+ */
+ int pts_dts_delta;
+
+ /**
+ * Position of the packet in file.
+ *
+ * Analogous to cur_frame_pts/dts
+ */
+ int64_t cur_frame_pos[AV_PARSER_PTS_NB];
+
+ /**
+ * Byte position of currently parsed frame in stream.
+ */
+ int64_t pos;
+
+ /**
+ * Previous frame byte position.
+ */
+ int64_t last_pos;
+
+ /**
+ * Duration of the current frame.
+ * For audio, this is in units of 1 / AVCodecContext.sample_rate.
+ * For all other types, this is in units of AVCodecContext.time_base.
+ */
+ int duration;
+
+ enum AVFieldOrder field_order;
+
+ /**
+ * Indicate whether a picture is coded as a frame, top field or bottom field.
+ *
+ * For example, H.264 field_pic_flag equal to 0 corresponds to
+ * AV_PICTURE_STRUCTURE_FRAME. An H.264 picture with field_pic_flag
+ * equal to 1 and bottom_field_flag equal to 0 corresponds to
+ * AV_PICTURE_STRUCTURE_TOP_FIELD.
+ */
+ enum AVPictureStructure picture_structure;
+
+ /**
+ * Picture number incremented in presentation or output order.
+ * This field may be reinitialized at the first picture of a new sequence.
+ *
+ * For example, this corresponds to H.264 PicOrderCnt.
+ */
+ int output_picture_number;
+
+ /**
+ * Dimensions of the decoded video intended for presentation.
+ */
+ int width;
+ int height;
+
+ /**
+ * Dimensions of the coded video.
+ */
+ int coded_width;
+ int coded_height;
+
+ /**
+ * The format of the coded data, corresponds to enum AVPixelFormat for video
+ * and for enum AVSampleFormat for audio.
+ *
+ * Note that a decoder can have considerable freedom in how exactly it
+ * decodes the data, so the format reported here might be different from the
+ * one returned by a decoder.
+ */
+ int format;
+} AVCodecParserContext;
+
+typedef struct AVCodecParser {
+ int codec_ids[5]; /* several codec IDs are permitted */
+ int priv_data_size;
+ int (*parser_init)(AVCodecParserContext *s);
+ /* This callback never returns an error, a negative value means that
+ * the frame start was in a previous packet. */
+ int (*parser_parse)(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ const uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size);
+ void (*parser_close)(AVCodecParserContext *s);
+ int (*split)(AVCodecContext *avctx, const uint8_t *buf, int buf_size);
+ struct AVCodecParser *next;
+} AVCodecParser;
+
+AVCodecParser *av_parser_next(const AVCodecParser *c);
+
+void av_register_codec_parser(AVCodecParser *parser);
+AVCodecParserContext *av_parser_init(int codec_id);
+
+/**
+ * Parse a packet.
+ *
+ * @param s parser context.
+ * @param avctx codec context.
+ * @param poutbuf set to pointer to parsed buffer or NULL if not yet finished.
+ * @param poutbuf_size set to size of parsed buffer or zero if not yet finished.
+ * @param buf input buffer.
+ * @param buf_size input length, to signal EOF, this should be 0 (so that the last frame can be output).
+ * @param pts input presentation timestamp.
+ * @param dts input decoding timestamp.
+ * @param pos input byte position in stream.
+ * @return the number of bytes of the input bitstream used.
+ *
+ * Example:
+ * @code
+ * while(in_len){
+ * len = av_parser_parse2(myparser, AVCodecContext, &data, &size,
+ * in_data, in_len,
+ * pts, dts, pos);
+ * in_data += len;
+ * in_len -= len;
+ *
+ * if(size)
+ * decode_frame(data, size);
+ * }
+ * @endcode
+ */
+int av_parser_parse2(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size,
+ int64_t pts, int64_t dts,
+ int64_t pos);
+
+/**
+ * @return 0 if the output buffer is a subset of the input, 1 if it is allocated and must be freed
+ * @deprecated use AVBitStreamFilter
+ */
+int av_parser_change(AVCodecParserContext *s,
+ AVCodecContext *avctx,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size, int keyframe);
+void av_parser_close(AVCodecParserContext *s);
+
+/**
+ * @}
+ * @}
+ */
+
+/**
+ * @addtogroup lavc_encoding
+ * @{
+ */
+
+/**
+ * Find a registered encoder with a matching codec ID.
+ *
+ * @param id AVCodecID of the requested encoder
+ * @return An encoder if one was found, NULL otherwise.
+ */
+AVCodec *avcodec_find_encoder(enum AVCodecID id);
+
+/**
+ * Find a registered encoder with the specified name.
+ *
+ * @param name name of the requested encoder
+ * @return An encoder if one was found, NULL otherwise.
+ */
+AVCodec *avcodec_find_encoder_by_name(const char *name);
+
+#if FF_API_OLD_ENCODE_AUDIO
+/**
+ * Encode an audio frame from samples into buf.
+ *
+ * @deprecated Use avcodec_encode_audio2 instead.
+ *
+ * @note The output buffer should be at least FF_MIN_BUFFER_SIZE bytes large.
+ * However, for codecs with avctx->frame_size equal to 0 (e.g. PCM) the user
+ * will know how much space is needed because it depends on the value passed
+ * in buf_size as described below. In that case a lower value can be used.
+ *
+ * @param avctx the codec context
+ * @param[out] buf the output buffer
+ * @param[in] buf_size the output buffer size
+ * @param[in] samples the input buffer containing the samples
+ * The number of samples read from this buffer is frame_size*channels,
+ * both of which are defined in avctx.
+ * For codecs which have avctx->frame_size equal to 0 (e.g. PCM) the number of
+ * samples read from samples is equal to:
+ * buf_size * 8 / (avctx->channels * av_get_bits_per_sample(avctx->codec_id))
+ * This also implies that av_get_bits_per_sample() must not return 0 for these
+ * codecs.
+ * @return On error a negative value is returned, on success zero or the number
+ * of bytes used to encode the data read from the input buffer.
+ */
+int attribute_deprecated avcodec_encode_audio(AVCodecContext *avctx,
+ uint8_t *buf, int buf_size,
+ const short *samples);
+#endif
+
+/**
+ * Encode a frame of audio.
+ *
+ * Takes input samples from frame and writes the next output packet, if
+ * available, to avpkt. The output packet does not necessarily contain data for
+ * the most recent frame, as encoders can delay, split, and combine input frames
+ * internally as needed.
+ *
+ * @param avctx codec context
+ * @param avpkt output AVPacket.
+ * The user can supply an output buffer by setting
+ * avpkt->data and avpkt->size prior to calling the
+ * function, but if the size of the user-provided data is not
+ * large enough, encoding will fail. If avpkt->data and
+ * avpkt->size are set, avpkt->destruct must also be set. All
+ * other AVPacket fields will be reset by the encoder using
+ * av_init_packet(). If avpkt->data is NULL, the encoder will
+ * allocate it. The encoder will set avpkt->size to the size
+ * of the output packet.
+ *
+ * If this function fails or produces no output, avpkt will be
+ * freed using av_free_packet() (i.e. avpkt->destruct will be
+ * called to free the user supplied buffer).
+ * @param[in] frame AVFrame containing the raw audio data to be encoded.
+ * May be NULL when flushing an encoder that has the
+ * AV_CODEC_CAP_DELAY capability set.
+ * If AV_CODEC_CAP_VARIABLE_FRAME_SIZE is set, then each frame
+ * can have any number of samples.
+ * If it is not set, frame->nb_samples must be equal to
+ * avctx->frame_size for all frames except the last.
+ * The final frame may be smaller than avctx->frame_size.
+ * @param[out] got_packet_ptr This field is set to 1 by libavcodec if the
+ * output packet is non-empty, and to 0 if it is
+ * empty. If the function returns an error, the
+ * packet can be assumed to be invalid, and the
+ * value of got_packet_ptr is undefined and should
+ * not be used.
+ * @return 0 on success, negative error code on failure
+ */
+int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt,
+ const AVFrame *frame, int *got_packet_ptr);
+
+#if FF_API_OLD_ENCODE_VIDEO
+/**
+ * @deprecated use avcodec_encode_video2() instead.
+ *
+ * Encode a video frame from pict into buf.
+ * The input picture should be
+ * stored using a specific format, namely avctx.pix_fmt.
+ *
+ * @param avctx the codec context
+ * @param[out] buf the output buffer for the bitstream of encoded frame
+ * @param[in] buf_size the size of the output buffer in bytes
+ * @param[in] pict the input picture to encode
+ * @return On error a negative value is returned, on success zero or the number
+ * of bytes used from the output buffer.
+ */
+attribute_deprecated
+int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size,
+ const AVFrame *pict);
+#endif
+
+/**
+ * Encode a frame of video.
+ *
+ * Takes input raw video data from frame and writes the next output packet, if
+ * available, to avpkt. The output packet does not necessarily contain data for
+ * the most recent frame, as encoders can delay and reorder input frames
+ * internally as needed.
+ *
+ * @param avctx codec context
+ * @param avpkt output AVPacket.
+ * The user can supply an output buffer by setting
+ * avpkt->data and avpkt->size prior to calling the
+ * function, but if the size of the user-provided data is not
+ * large enough, encoding will fail. All other AVPacket fields
+ * will be reset by the encoder using av_init_packet(). If
+ * avpkt->data is NULL, the encoder will allocate it.
+ * The encoder will set avpkt->size to the size of the
+ * output packet. The returned data (if any) belongs to the
+ * caller, he is responsible for freeing it.
+ *
+ * If this function fails or produces no output, avpkt will be
+ * freed using av_free_packet() (i.e. avpkt->destruct will be
+ * called to free the user supplied buffer).
+ * @param[in] frame AVFrame containing the raw video data to be encoded.
+ * May be NULL when flushing an encoder that has the
+ * AV_CODEC_CAP_DELAY capability set.
+ * @param[out] got_packet_ptr This field is set to 1 by libavcodec if the
+ * output packet is non-empty, and to 0 if it is
+ * empty. If the function returns an error, the
+ * packet can be assumed to be invalid, and the
+ * value of got_packet_ptr is undefined and should
+ * not be used.
+ * @return 0 on success, negative error code on failure
+ */
+int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt,
+ const AVFrame *frame, int *got_packet_ptr);
+
+int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size,
+ const AVSubtitle *sub);
+
+
+/**
+ * @}
+ */
+
+#if FF_API_AVCODEC_RESAMPLE
+/**
+ * @defgroup lavc_resample Audio resampling
+ * @ingroup libavc
+ * @deprecated use libswresample instead
+ *
+ * @{
+ */
+struct ReSampleContext;
+struct AVResampleContext;
+
+typedef struct ReSampleContext ReSampleContext;
+
+/**
+ * Initialize audio resampling context.
+ *
+ * @param output_channels number of output channels
+ * @param input_channels number of input channels
+ * @param output_rate output sample rate
+ * @param input_rate input sample rate
+ * @param sample_fmt_out requested output sample format
+ * @param sample_fmt_in input sample format
+ * @param filter_length length of each FIR filter in the filterbank relative to the cutoff frequency
+ * @param log2_phase_count log2 of the number of entries in the polyphase filterbank
+ * @param linear if 1 then the used FIR filter will be linearly interpolated
+ between the 2 closest, if 0 the closest will be used
+ * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate
+ * @return allocated ReSampleContext, NULL if error occurred
+ */
+attribute_deprecated
+ReSampleContext *av_audio_resample_init(int output_channels, int input_channels,
+ int output_rate, int input_rate,
+ enum AVSampleFormat sample_fmt_out,
+ enum AVSampleFormat sample_fmt_in,
+ int filter_length, int log2_phase_count,
+ int linear, double cutoff);
+
+attribute_deprecated
+int audio_resample(ReSampleContext *s, short *output, short *input, int nb_samples);
+
+/**
+ * Free resample context.
+ *
+ * @param s a non-NULL pointer to a resample context previously
+ * created with av_audio_resample_init()
+ */
+attribute_deprecated
+void audio_resample_close(ReSampleContext *s);
+
+
+/**
+ * Initialize an audio resampler.
+ * Note, if either rate is not an integer then simply scale both rates up so they are.
+ * @param filter_length length of each FIR filter in the filterbank relative to the cutoff freq
+ * @param log2_phase_count log2 of the number of entries in the polyphase filterbank
+ * @param linear If 1 then the used FIR filter will be linearly interpolated
+ between the 2 closest, if 0 the closest will be used
+ * @param cutoff cutoff frequency, 1.0 corresponds to half the output sampling rate
+ */
+attribute_deprecated
+struct AVResampleContext *av_resample_init(int out_rate, int in_rate, int filter_length, int log2_phase_count, int linear, double cutoff);
+
+/**
+ * Resample an array of samples using a previously configured context.
+ * @param src an array of unconsumed samples
+ * @param consumed the number of samples of src which have been consumed are returned here
+ * @param src_size the number of unconsumed samples available
+ * @param dst_size the amount of space in samples available in dst
+ * @param update_ctx If this is 0 then the context will not be modified, that way several channels can be resampled with the same context.
+ * @return the number of samples written in dst or -1 if an error occurred
+ */
+attribute_deprecated
+int av_resample(struct AVResampleContext *c, short *dst, short *src, int *consumed, int src_size, int dst_size, int update_ctx);
+
+
+/**
+ * Compensate samplerate/timestamp drift. The compensation is done by changing
+ * the resampler parameters, so no audible clicks or similar distortions occur
+ * @param compensation_distance distance in output samples over which the compensation should be performed
+ * @param sample_delta number of output samples which should be output less
+ *
+ * example: av_resample_compensate(c, 10, 500)
+ * here instead of 510 samples only 500 samples would be output
+ *
+ * note, due to rounding the actual compensation might be slightly different,
+ * especially if the compensation_distance is large and the in_rate used during init is small
+ */
+attribute_deprecated
+void av_resample_compensate(struct AVResampleContext *c, int sample_delta, int compensation_distance);
+attribute_deprecated
+void av_resample_close(struct AVResampleContext *c);
+
+/**
+ * @}
+ */
+#endif
+
+/**
+ * @addtogroup lavc_picture
+ * @{
+ */
+
+/**
+ * Allocate memory for the pixels of a picture and setup the AVPicture
+ * fields for it.
+ *
+ * Call avpicture_free() to free it.
+ *
+ * @param picture the picture structure to be filled in
+ * @param pix_fmt the pixel format of the picture
+ * @param width the width of the picture
+ * @param height the height of the picture
+ * @return zero if successful, a negative error code otherwise
+ *
+ * @see av_image_alloc(), avpicture_fill()
+ */
+int avpicture_alloc(AVPicture *picture, enum AVPixelFormat pix_fmt, int width, int height);
+
+/**
+ * Free a picture previously allocated by avpicture_alloc().
+ * The data buffer used by the AVPicture is freed, but the AVPicture structure
+ * itself is not.
+ *
+ * @param picture the AVPicture to be freed
+ */
+void avpicture_free(AVPicture *picture);
+
+/**
+ * Setup the picture fields based on the specified image parameters
+ * and the provided image data buffer.
+ *
+ * The picture fields are filled in by using the image data buffer
+ * pointed to by ptr.
+ *
+ * If ptr is NULL, the function will fill only the picture linesize
+ * array and return the required size for the image buffer.
+ *
+ * To allocate an image buffer and fill the picture data in one call,
+ * use avpicture_alloc().
+ *
+ * @param picture the picture to be filled in
+ * @param ptr buffer where the image data is stored, or NULL
+ * @param pix_fmt the pixel format of the image
+ * @param width the width of the image in pixels
+ * @param height the height of the image in pixels
+ * @return the size in bytes required for src, a negative error code
+ * in case of failure
+ *
+ * @see av_image_fill_arrays()
+ */
+int avpicture_fill(AVPicture *picture, const uint8_t *ptr,
+ enum AVPixelFormat pix_fmt, int width, int height);
+
+/**
+ * Copy pixel data from an AVPicture into a buffer.
+ *
+ * avpicture_get_size() can be used to compute the required size for
+ * the buffer to fill.
+ *
+ * @param src source picture with filled data
+ * @param pix_fmt picture pixel format
+ * @param width picture width
+ * @param height picture height
+ * @param dest destination buffer
+ * @param dest_size destination buffer size in bytes
+ * @return the number of bytes written to dest, or a negative value
+ * (error code) on error, for example if the destination buffer is not
+ * big enough
+ *
+ * @see av_image_copy_to_buffer()
+ */
+int avpicture_layout(const AVPicture *src, enum AVPixelFormat pix_fmt,
+ int width, int height,
+ unsigned char *dest, int dest_size);
+
+/**
+ * Calculate the size in bytes that a picture of the given width and height
+ * would occupy if stored in the given picture format.
+ *
+ * @param pix_fmt picture pixel format
+ * @param width picture width
+ * @param height picture height
+ * @return the computed picture buffer size or a negative error code
+ * in case of error
+ *
+ * @see av_image_get_buffer_size().
+ */
+int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height);
+
+#if FF_API_DEINTERLACE
+/**
+ * deinterlace - if not supported return -1
+ *
+ * @deprecated - use yadif (in libavfilter) instead
+ */
+attribute_deprecated
+int avpicture_deinterlace(AVPicture *dst, const AVPicture *src,
+ enum AVPixelFormat pix_fmt, int width, int height);
+#endif
+/**
+ * Copy image src to dst. Wraps av_image_copy().
+ */
+void av_picture_copy(AVPicture *dst, const AVPicture *src,
+ enum AVPixelFormat pix_fmt, int width, int height);
+
+/**
+ * Crop image top and left side.
+ */
+int av_picture_crop(AVPicture *dst, const AVPicture *src,
+ enum AVPixelFormat pix_fmt, int top_band, int left_band);
+
+/**
+ * Pad image.
+ */
+int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, enum AVPixelFormat pix_fmt,
+ int padtop, int padbottom, int padleft, int padright, int *color);
+
+/**
+ * @}
+ */
+
+/**
+ * @defgroup lavc_misc Utility functions
+ * @ingroup libavc
+ *
+ * Miscellaneous utility functions related to both encoding and decoding
+ * (or neither).
+ * @{
+ */
+
+/**
+ * @defgroup lavc_misc_pixfmt Pixel formats
+ *
+ * Functions for working with pixel formats.
+ * @{
+ */
+
+/**
+ * Utility function to access log2_chroma_w log2_chroma_h from
+ * the pixel format AVPixFmtDescriptor.
+ *
+ * This function asserts that pix_fmt is valid. See av_pix_fmt_get_chroma_sub_sample
+ * for one that returns a failure code and continues in case of invalid
+ * pix_fmts.
+ *
+ * @param[in] pix_fmt the pixel format
+ * @param[out] h_shift store log2_chroma_w
+ * @param[out] v_shift store log2_chroma_h
+ *
+ * @see av_pix_fmt_get_chroma_sub_sample
+ */
+
+void avcodec_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift);
+
+/**
+ * Return a value representing the fourCC code associated to the
+ * pixel format pix_fmt, or 0 if no associated fourCC code can be
+ * found.
+ */
+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
+ * may occur. For example, when converting from RGB24 to GRAY, the color
+ * information will be lost. Similarly, other losses occur when converting from
+ * some formats to other formats. avcodec_find_best_pix_fmt_of_2() searches which of
+ * the given pixel formats should be used to suffer the least amount of loss.
+ * The pixel formats from which it chooses one, are determined by the
+ * pix_fmt_list parameter.
+ *
+ *
+ * @param[in] pix_fmt_list AV_PIX_FMT_NONE terminated array of pixel formats to choose from
+ * @param[in] src_pix_fmt source pixel format
+ * @param[in] has_alpha Whether the source pixel format alpha channel is used.
+ * @param[out] loss_ptr Combination of flags informing you what kind of losses will occur.
+ * @return The best pixel format to convert to or -1 if none was found.
+ */
+enum AVPixelFormat avcodec_find_best_pix_fmt_of_list(const enum AVPixelFormat *pix_fmt_list,
+ enum AVPixelFormat src_pix_fmt,
+ int has_alpha, int *loss_ptr);
+
+/**
+ * @deprecated see av_find_best_pix_fmt_of_2()
+ */
+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
+#if AV_HAVE_INCOMPATIBLE_LIBAV_ABI
+enum AVPixelFormat avcodec_find_best_pix_fmt2(const enum AVPixelFormat *pix_fmt_list,
+ enum AVPixelFormat src_pix_fmt,
+ int has_alpha, int *loss_ptr);
+#else
+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);
+
+/**
+ * @}
+ */
+
+#if FF_API_SET_DIMENSIONS
+/**
+ * @deprecated this function is not supposed to be used from outside of lavc
+ */
+attribute_deprecated
+void avcodec_set_dimensions(AVCodecContext *s, int width, int height);
+#endif
+
+/**
+ * Put a string representing the codec tag codec_tag in buf.
+ *
+ * @param buf buffer to place codec tag in
+ * @param buf_size size in bytes of buf
+ * @param codec_tag codec tag to assign
+ * @return the length of the string that would have been generated if
+ * enough space had been available, excluding the trailing null
+ */
+size_t av_get_codec_tag_string(char *buf, size_t buf_size, unsigned int codec_tag);
+
+void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode);
+
+/**
+ * Return a name for the specified profile, if available.
+ *
+ * @param codec the codec that is searched for the given profile
+ * @param profile the profile value for which a name is requested
+ * @return A name for the profile if found, NULL otherwise.
+ */
+const char *av_get_profile_name(const AVCodec *codec, int profile);
+
+int avcodec_default_execute(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2),void *arg, int *ret, int count, int size);
+int avcodec_default_execute2(AVCodecContext *c, int (*func)(AVCodecContext *c2, void *arg2, int, int),void *arg, int *ret, int count);
+//FIXME func typedef
+
+/**
+ * Fill AVFrame audio data and linesize pointers.
+ *
+ * The buffer buf must be a preallocated buffer with a size big enough
+ * to contain the specified samples amount. The filled AVFrame data
+ * pointers will point to this buffer.
+ *
+ * AVFrame extended_data channel pointers are allocated if necessary for
+ * planar audio.
+ *
+ * @param frame the AVFrame
+ * frame->nb_samples must be set prior to calling the
+ * function. This function fills in frame->data,
+ * frame->extended_data, frame->linesize[0].
+ * @param nb_channels channel count
+ * @param sample_fmt sample format
+ * @param buf buffer to use for frame data
+ * @param buf_size size of buffer
+ * @param align plane size sample alignment (0 = default)
+ * @return >=0 on success, negative error code on failure
+ * @todo return the size in bytes required to store the samples in
+ * case of success, at the next libavutil bump
+ */
+int avcodec_fill_audio_frame(AVFrame *frame, int nb_channels,
+ enum AVSampleFormat sample_fmt, const uint8_t *buf,
+ int buf_size, int align);
+
+/**
+ * Reset the internal decoder state / flush internal buffers. Should be called
+ * e.g. when seeking or when switching to a different stream.
+ *
+ * @note when refcounted frames are not used (i.e. avctx->refcounted_frames is 0),
+ * this invalidates the frames previously returned from the decoder. When
+ * refcounted frames are used, the decoder just releases any references it might
+ * keep internally, but the caller's reference remains valid.
+ */
+void avcodec_flush_buffers(AVCodecContext *avctx);
+
+/**
+ * Return codec bits per sample.
+ *
+ * @param[in] codec_id the codec
+ * @return Number of bits per sample or zero if unknown for the given codec.
+ */
+int av_get_bits_per_sample(enum AVCodecID codec_id);
+
+/**
+ * Return the PCM codec associated with a sample format.
+ * @param be endianness, 0 for little, 1 for big,
+ * -1 (or anything else) for native
+ * @return AV_CODEC_ID_PCM_* or AV_CODEC_ID_NONE
+ */
+enum AVCodecID av_get_pcm_codec(enum AVSampleFormat fmt, int be);
+
+/**
+ * Return codec bits per sample.
+ * Only return non-zero if the bits per sample is exactly correct, not an
+ * approximation.
+ *
+ * @param[in] codec_id the codec
+ * @return Number of bits per sample or zero if unknown for the given codec.
+ */
+int av_get_exact_bits_per_sample(enum AVCodecID codec_id);
+
+/**
+ * Return audio frame duration.
+ *
+ * @param avctx codec context
+ * @param frame_bytes size of the frame, or 0 if unknown
+ * @return frame duration, in samples, if known. 0 if not able to
+ * determine.
+ */
+int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes);
+
+
+typedef struct AVBitStreamFilterContext {
+ void *priv_data;
+ struct AVBitStreamFilter *filter;
+ AVCodecParserContext *parser;
+ struct AVBitStreamFilterContext *next;
+} AVBitStreamFilterContext;
+
+
+typedef struct AVBitStreamFilter {
+ const char *name;
+ int priv_data_size;
+ int (*filter)(AVBitStreamFilterContext *bsfc,
+ AVCodecContext *avctx, const char *args,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size, int keyframe);
+ void (*close)(AVBitStreamFilterContext *bsfc);
+ struct AVBitStreamFilter *next;
+} AVBitStreamFilter;
+
+/**
+ * Register a bitstream filter.
+ *
+ * The filter will be accessible to the application code through
+ * av_bitstream_filter_next() or can be directly initialized with
+ * av_bitstream_filter_init().
+ *
+ * @see avcodec_register_all()
+ */
+void av_register_bitstream_filter(AVBitStreamFilter *bsf);
+
+/**
+ * Create and initialize a bitstream filter context given a bitstream
+ * filter name.
+ *
+ * The returned context must be freed with av_bitstream_filter_close().
+ *
+ * @param name the name of the bitstream filter
+ * @return a bitstream filter context if a matching filter was found
+ * and successfully initialized, NULL otherwise
+ */
+AVBitStreamFilterContext *av_bitstream_filter_init(const char *name);
+
+/**
+ * Filter bitstream.
+ *
+ * This function filters the buffer buf with size buf_size, and places the
+ * filtered buffer in the buffer pointed to by poutbuf.
+ *
+ * The output buffer must be freed by the caller.
+ *
+ * @param bsfc bitstream filter context created by av_bitstream_filter_init()
+ * @param avctx AVCodecContext accessed by the filter, may be NULL.
+ * If specified, this must point to the encoder context of the
+ * output stream the packet is sent to.
+ * @param args arguments which specify the filter configuration, may be NULL
+ * @param poutbuf pointer which is updated to point to the filtered buffer
+ * @param poutbuf_size pointer which is updated to the filtered buffer size in bytes
+ * @param buf buffer containing the data to filter
+ * @param buf_size size in bytes of buf
+ * @param keyframe set to non-zero if the buffer to filter corresponds to a key-frame packet data
+ * @return >= 0 in case of success, or a negative error code in case of failure
+ *
+ * If the return value is positive, an output buffer is allocated and
+ * is available in *poutbuf, and is distinct from the input buffer.
+ *
+ * If the return value is 0, the output buffer is not allocated and
+ * should be considered identical to the input buffer, or in case
+ * *poutbuf was set it points to the input buffer (not necessarily to
+ * its starting address).
+ */
+int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
+ AVCodecContext *avctx, const char *args,
+ uint8_t **poutbuf, int *poutbuf_size,
+ const uint8_t *buf, int buf_size, int keyframe);
+
+/**
+ * Release bitstream filter context.
+ *
+ * @param bsf the bitstream filter context created with
+ * av_bitstream_filter_init(), can be NULL
+ */
+void av_bitstream_filter_close(AVBitStreamFilterContext *bsf);
+
+/**
+ * If f is NULL, return the first registered bitstream filter,
+ * if f is non-NULL, return the next registered bitstream filter
+ * after f, or NULL if f is the last one.
+ *
+ * This function can be used to iterate over all registered bitstream
+ * filters.
+ */
+AVBitStreamFilter *av_bitstream_filter_next(const AVBitStreamFilter *f);
+
+/* memory */
+
+/**
+ * Same behaviour av_fast_malloc but the buffer has additional
+ * AV_INPUT_BUFFER_PADDING_SIZE at the end which will always be 0.
+ *
+ * In addition the whole buffer will initially and after resizes
+ * be 0-initialized so that no uninitialized data will ever appear.
+ */
+void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size);
+
+/**
+ * Same behaviour av_fast_padded_malloc except that buffer will always
+ * be 0-initialized after call.
+ */
+void av_fast_padded_mallocz(void *ptr, unsigned int *size, size_t min_size);
+
+/**
+ * Encode extradata length to a buffer. Used by xiph codecs.
+ *
+ * @param s buffer to write to; must be at least (v/255+1) bytes long
+ * @param v size of extradata in bytes
+ * @return number of bytes written to the buffer.
+ */
+unsigned int av_xiphlacing(unsigned char *s, unsigned int v);
+
+#if FF_API_MISSING_SAMPLE
+/**
+ * Log a generic warning message about a missing feature. This function is
+ * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.)
+ * only, and would normally not be used by applications.
+ * @param[in] avc a pointer to an arbitrary struct of which the first field is
+ * a pointer to an AVClass struct
+ * @param[in] feature string containing the name of the missing feature
+ * @param[in] want_sample indicates if samples are wanted which exhibit this feature.
+ * If want_sample is non-zero, additional verbage will be added to the log
+ * message which tells the user how to report samples to the development
+ * mailing list.
+ * @deprecated Use avpriv_report_missing_feature() instead.
+ */
+attribute_deprecated
+void av_log_missing_feature(void *avc, const char *feature, int want_sample);
+
+/**
+ * Log a generic warning message asking for a sample. This function is
+ * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.)
+ * only, and would normally not be used by applications.
+ * @param[in] avc a pointer to an arbitrary struct of which the first field is
+ * a pointer to an AVClass struct
+ * @param[in] msg string containing an optional message, or NULL if no message
+ * @deprecated Use avpriv_request_sample() instead.
+ */
+attribute_deprecated
+void av_log_ask_for_sample(void *avc, const char *msg, ...) av_printf_format(2, 3);
+#endif /* FF_API_MISSING_SAMPLE */
+
+/**
+ * Register the hardware accelerator hwaccel.
+ */
+void av_register_hwaccel(AVHWAccel *hwaccel);
+
+/**
+ * If hwaccel is NULL, returns the first registered hardware accelerator,
+ * if hwaccel is non-NULL, returns the next registered hardware accelerator
+ * after hwaccel, or NULL if hwaccel is the last one.
+ */
+AVHWAccel *av_hwaccel_next(const AVHWAccel *hwaccel);
+
+
+/**
+ * Lock operation used by lockmgr
+ */
+enum AVLockOp {
+ AV_LOCK_CREATE, ///< Create a mutex
+ AV_LOCK_OBTAIN, ///< Lock the mutex
+ AV_LOCK_RELEASE, ///< Unlock the mutex
+ AV_LOCK_DESTROY, ///< Free mutex resources
+};
+
+/**
+ * Register a user provided lock manager supporting the operations
+ * specified by AVLockOp. The "mutex" argument to the function points
+ * to a (void *) where the lockmgr should store/get a pointer to a user
+ * allocated mutex. It is NULL upon AV_LOCK_CREATE and equal to the
+ * value left by the last call for all other ops. If the lock manager is
+ * unable to perform the op then it should leave the mutex in the same
+ * state as when it was called and return a non-zero value. However,
+ * when called with AV_LOCK_DESTROY the mutex will always be assumed to
+ * have been successfully destroyed. If av_lockmgr_register succeeds
+ * it will return a non-negative value, if it fails it will return a
+ * negative value and destroy all mutex and unregister all callbacks.
+ * av_lockmgr_register is not thread-safe, it must be called from a
+ * single thread before any calls which make use of locking are used.
+ *
+ * @param cb User defined callback. av_lockmgr_register invokes calls
+ * to this callback and the previously registered callback.
+ * The callback will be used to create more than one mutex
+ * each of which must be backed by its own underlying locking
+ * mechanism (i.e. do not use a single static object to
+ * implement your lock manager). If cb is set to NULL the
+ * lockmgr will be unregistered.
+ */
+int av_lockmgr_register(int (*cb)(void **mutex, enum AVLockOp op));
+
+/**
+ * Get the type of the given codec.
+ */
+enum AVMediaType avcodec_get_type(enum AVCodecID codec_id);
+
+/**
+ * Get the name of a codec.
+ * @return a static string identifying the codec; never NULL
+ */
+const char *avcodec_get_name(enum AVCodecID id);
+
+/**
+ * @return a positive value if s is open (i.e. avcodec_open2() was called on it
+ * with no corresponding avcodec_close()), 0 otherwise.
+ */
+int avcodec_is_open(AVCodecContext *s);
+
+/**
+ * @return a non-zero number if codec is an encoder, zero otherwise
+ */
+int av_codec_is_encoder(const AVCodec *codec);
+
+/**
+ * @return a non-zero number if codec is a decoder, zero otherwise
+ */
+int av_codec_is_decoder(const AVCodec *codec);
+
+/**
+ * @return descriptor for given codec ID or NULL if no descriptor exists.
+ */
+const AVCodecDescriptor *avcodec_descriptor_get(enum AVCodecID id);
+
+/**
+ * Iterate over all codec descriptors known to libavcodec.
+ *
+ * @param prev previous descriptor. NULL to get the first descriptor.
+ *
+ * @return next descriptor or NULL after the last descriptor
+ */
+const AVCodecDescriptor *avcodec_descriptor_next(const AVCodecDescriptor *prev);
+
+/**
+ * @return codec descriptor with the given name or NULL if no such descriptor
+ * exists.
+ */
+const AVCodecDescriptor *avcodec_descriptor_get_by_name(const char *name);
+
+/**
+ * @}
+ */
+
+#endif /* AVCODEC_AVCODEC_H */
diff --git a/ffmpeg-2-8-11/libavcodec/avcodecres.rc b/ffmpeg-2-8-12/libavcodec/avcodecres.rc
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/avcodecres.rc
rename to ffmpeg-2-8-12/libavcodec/avcodecres.rc
diff --git a/ffmpeg-2-8-11/libavcodec/avdct.c b/ffmpeg-2-8-12/libavcodec/avdct.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/avdct.c
rename to ffmpeg-2-8-12/libavcodec/avdct.c
diff --git a/ffmpeg-2-8-11/libavcodec/avdct.h b/ffmpeg-2-8-12/libavcodec/avdct.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/avdct.h
rename to ffmpeg-2-8-12/libavcodec/avdct.h
diff --git a/ffmpeg-2-8-11/libavcodec/avfft.c b/ffmpeg-2-8-12/libavcodec/avfft.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/avfft.c
rename to ffmpeg-2-8-12/libavcodec/avfft.c
diff --git a/ffmpeg-2-8-11/libavcodec/avfft.h b/ffmpeg-2-8-12/libavcodec/avfft.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/avfft.h
rename to ffmpeg-2-8-12/libavcodec/avfft.h
diff --git a/ffmpeg-2-8-12/libavcodec/avpacket.c b/ffmpeg-2-8-12/libavcodec/avpacket.c
new file mode 100644
index 0000000..6e9aede
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/avpacket.c
@@ -0,0 +1,641 @@
+/*
+ * AVPacket functions for libavcodec
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <string.h>
+
+#include "libavutil/avassert.h"
+#include "libavutil/common.h"
+#include "libavutil/internal.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/mem.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+
+#if FF_API_DESTRUCT_PACKET
+
+void av_destruct_packet(AVPacket *pkt)
+{
+ av_freep(&pkt->data);
+ pkt->size = 0;
+}
+
+/* a dummy destruct callback for the callers that assume AVPacket.destruct ==
+ * NULL => static data */
+static void dummy_destruct_packet(AVPacket *pkt)
+{
+ av_assert0(0);
+}
+#endif
+
+void av_init_packet(AVPacket *pkt)
+{
+ pkt->pts = AV_NOPTS_VALUE;
+ pkt->dts = AV_NOPTS_VALUE;
+ pkt->pos = -1;
+ pkt->duration = 0;
+ pkt->convergence_duration = 0;
+ pkt->flags = 0;
+ pkt->stream_index = 0;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+ pkt->destruct = NULL;
+ pkt->priv = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ pkt->buf = NULL;
+ pkt->side_data = NULL;
+ pkt->side_data_elems = 0;
+}
+
+static int packet_alloc(AVBufferRef **buf, int size)
+{
+ int ret;
+ if ((unsigned)size >= (unsigned)size + AV_INPUT_BUFFER_PADDING_SIZE)
+ return AVERROR(EINVAL);
+
+ ret = av_buffer_realloc(buf, size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (ret < 0)
+ return ret;
+
+ memset((*buf)->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+
+ return 0;
+}
+
+int av_new_packet(AVPacket *pkt, int size)
+{
+ AVBufferRef *buf = NULL;
+ int ret = packet_alloc(&buf, size);
+ if (ret < 0)
+ return ret;
+
+ av_init_packet(pkt);
+ pkt->buf = buf;
+ pkt->data = buf->data;
+ pkt->size = size;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+ pkt->destruct = dummy_destruct_packet;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ return 0;
+}
+
+void av_shrink_packet(AVPacket *pkt, int size)
+{
+ if (pkt->size <= size)
+ return;
+ pkt->size = size;
+ memset(pkt->data + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+}
+
+int av_grow_packet(AVPacket *pkt, int grow_by)
+{
+ int new_size;
+ av_assert0((unsigned)pkt->size <= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!pkt->size)
+ return av_new_packet(pkt, grow_by);
+ if ((unsigned)grow_by >
+ INT_MAX - (pkt->size + AV_INPUT_BUFFER_PADDING_SIZE))
+ return -1;
+
+ new_size = pkt->size + grow_by + AV_INPUT_BUFFER_PADDING_SIZE;
+ if (pkt->buf) {
+ int ret = av_buffer_realloc(&pkt->buf, new_size);
+ if (ret < 0)
+ return ret;
+ } else {
+ pkt->buf = av_buffer_alloc(new_size);
+ if (!pkt->buf)
+ return AVERROR(ENOMEM);
+ memcpy(pkt->buf->data, pkt->data, FFMIN(pkt->size, pkt->size + grow_by));
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+ pkt->destruct = dummy_destruct_packet;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ }
+ pkt->data = pkt->buf->data;
+ pkt->size += grow_by;
+ memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+
+ return 0;
+}
+
+int av_packet_from_data(AVPacket *pkt, uint8_t *data, int size)
+{
+ if (size >= INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
+ return AVERROR(EINVAL);
+
+ pkt->buf = av_buffer_create(data, size + AV_INPUT_BUFFER_PADDING_SIZE,
+ av_buffer_default_free, NULL, 0);
+ if (!pkt->buf)
+ return AVERROR(ENOMEM);
+
+ pkt->data = data;
+ pkt->size = size;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+ pkt->destruct = dummy_destruct_packet;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ return 0;
+}
+
+#define ALLOC_MALLOC(data, size) data = av_malloc(size)
+#define ALLOC_BUF(data, size) \
+do { \
+ av_buffer_realloc(&pkt->buf, size); \
+ data = pkt->buf ? pkt->buf->data : NULL; \
+} while (0)
+
+#define DUP_DATA(dst, src, size, padding, ALLOC) \
+ do { \
+ void *data; \
+ if (padding) { \
+ if ((unsigned)(size) > \
+ (unsigned)(size) + AV_INPUT_BUFFER_PADDING_SIZE) \
+ goto failed_alloc; \
+ ALLOC(data, size + AV_INPUT_BUFFER_PADDING_SIZE); \
+ } else { \
+ ALLOC(data, size); \
+ } \
+ if (!data) \
+ goto failed_alloc; \
+ memcpy(data, src, size); \
+ if (padding) \
+ memset((uint8_t *)data + size, 0, \
+ AV_INPUT_BUFFER_PADDING_SIZE); \
+ dst = data; \
+ } while (0)
+
+/* Makes duplicates of data, side_data, but does not copy any other fields */
+static int copy_packet_data(AVPacket *pkt, const AVPacket *src, int dup)
+{
+ pkt->data = NULL;
+ pkt->side_data = NULL;
+ pkt->side_data_elems = 0;
+ if (pkt->buf) {
+ AVBufferRef *ref = av_buffer_ref(src->buf);
+ if (!ref)
+ return AVERROR(ENOMEM);
+ pkt->buf = ref;
+ pkt->data = ref->data;
+ } else {
+ DUP_DATA(pkt->data, src->data, pkt->size, 1, ALLOC_BUF);
+ }
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+ pkt->destruct = dummy_destruct_packet;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ if (src->side_data_elems && dup) {
+ pkt->side_data = src->side_data;
+ pkt->side_data_elems = src->side_data_elems;
+ }
+ if (src->side_data_elems && !dup) {
+ return av_copy_packet_side_data(pkt, src);
+ }
+ return 0;
+
+failed_alloc:
+ av_free_packet(pkt);
+ return AVERROR(ENOMEM);
+}
+
+int av_copy_packet_side_data(AVPacket *pkt, const AVPacket *src)
+{
+ if (src->side_data_elems) {
+ int i;
+ DUP_DATA(pkt->side_data, src->side_data,
+ src->side_data_elems * sizeof(*src->side_data), 0, ALLOC_MALLOC);
+ if (src != pkt) {
+ memset(pkt->side_data, 0,
+ src->side_data_elems * sizeof(*src->side_data));
+ }
+ for (i = 0; i < src->side_data_elems; i++) {
+ DUP_DATA(pkt->side_data[i].data, src->side_data[i].data,
+ src->side_data[i].size, 1, ALLOC_MALLOC);
+ pkt->side_data[i].size = src->side_data[i].size;
+ pkt->side_data[i].type = src->side_data[i].type;
+ }
+ }
+ pkt->side_data_elems = src->side_data_elems;
+ return 0;
+
+failed_alloc:
+ av_free_packet(pkt);
+ return AVERROR(ENOMEM);
+}
+
+int av_dup_packet(AVPacket *pkt)
+{
+ AVPacket tmp_pkt;
+
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (!pkt->buf && pkt->data
+#if FF_API_DESTRUCT_PACKET
+ && !pkt->destruct
+#endif
+ ) {
+FF_ENABLE_DEPRECATION_WARNINGS
+ tmp_pkt = *pkt;
+ return copy_packet_data(pkt, &tmp_pkt, 1);
+ }
+ return 0;
+}
+
+int av_copy_packet(AVPacket *dst, const AVPacket *src)
+{
+ *dst = *src;
+ return copy_packet_data(dst, src, 0);
+}
+
+void av_packet_free_side_data(AVPacket *pkt)
+{
+ int i;
+ for (i = 0; i < pkt->side_data_elems; i++)
+ av_freep(&pkt->side_data[i].data);
+ av_freep(&pkt->side_data);
+ pkt->side_data_elems = 0;
+}
+
+void av_free_packet(AVPacket *pkt)
+{
+ if (pkt) {
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (pkt->buf)
+ av_buffer_unref(&pkt->buf);
+#if FF_API_DESTRUCT_PACKET
+ else if (pkt->destruct)
+ pkt->destruct(pkt);
+ pkt->destruct = NULL;
+#endif
+FF_ENABLE_DEPRECATION_WARNINGS
+ pkt->data = NULL;
+ pkt->size = 0;
+
+ av_packet_free_side_data(pkt);
+ }
+}
+
+uint8_t *av_packet_new_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
+ int size)
+{
+ int elems = pkt->side_data_elems;
+
+ if ((unsigned)elems + 1 > AV_PKT_DATA_NB)
+ return NULL;
+ if ((unsigned)size > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE)
+ return NULL;
+
+
+ pkt->side_data = av_realloc(pkt->side_data,
+ (elems + 1) * sizeof(*pkt->side_data));
+ if (!pkt->side_data)
+ return NULL;
+
+ pkt->side_data[elems].data = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!pkt->side_data[elems].data)
+ return NULL;
+ pkt->side_data[elems].size = size;
+ pkt->side_data[elems].type = type;
+ pkt->side_data_elems++;
+
+ return pkt->side_data[elems].data;
+}
+
+uint8_t *av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
+ int *size)
+{
+ int i;
+
+ for (i = 0; i < pkt->side_data_elems; i++) {
+ if (pkt->side_data[i].type == type) {
+ if (size)
+ *size = pkt->side_data[i].size;
+ return pkt->side_data[i].data;
+ }
+ }
+ if (size)
+ *size = 0;
+ return NULL;
+}
+
+const char *av_packet_side_data_name(enum AVPacketSideDataType type)
+{
+ switch(type) {
+ case AV_PKT_DATA_PALETTE: return "Palette";
+ case AV_PKT_DATA_NEW_EXTRADATA: return "New Extradata";
+ case AV_PKT_DATA_PARAM_CHANGE: return "Param Change";
+ case AV_PKT_DATA_H263_MB_INFO: return "H263 MB Info";
+ case AV_PKT_DATA_REPLAYGAIN: return "Replay Gain";
+ case AV_PKT_DATA_DISPLAYMATRIX: return "Display Matrix";
+ case AV_PKT_DATA_STEREO3D: return "Stereo 3D";
+ case AV_PKT_DATA_AUDIO_SERVICE_TYPE: return "Audio Service Type";
+ case AV_PKT_DATA_SKIP_SAMPLES: return "Skip Samples";
+ case AV_PKT_DATA_JP_DUALMONO: return "JP Dual Mono";
+ case AV_PKT_DATA_STRINGS_METADATA: return "Strings Metadata";
+ case AV_PKT_DATA_SUBTITLE_POSITION: return "Subtitle Position";
+ case AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL: return "Matroska BlockAdditional";
+ case AV_PKT_DATA_WEBVTT_IDENTIFIER: return "WebVTT ID";
+ case AV_PKT_DATA_WEBVTT_SETTINGS: return "WebVTT Settings";
+ case AV_PKT_DATA_METADATA_UPDATE: return "Metadata Update";
+ }
+ return NULL;
+}
+
+#define FF_MERGE_MARKER 0x8c4d9d108e25e9feULL
+
+int av_packet_merge_side_data(AVPacket *pkt){
+ if(pkt->side_data_elems){
+ AVBufferRef *buf;
+ int i;
+ uint8_t *p;
+ uint64_t size= pkt->size + 8LL + AV_INPUT_BUFFER_PADDING_SIZE;
+ AVPacket old= *pkt;
+ for (i=0; i<old.side_data_elems; i++) {
+ size += old.side_data[i].size + 5LL;
+ }
+ if (size > INT_MAX)
+ return AVERROR(EINVAL);
+ buf = av_buffer_alloc(size);
+ if (!buf)
+ return AVERROR(ENOMEM);
+ pkt->buf = buf;
+ pkt->data = p = buf->data;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+ pkt->destruct = dummy_destruct_packet;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ pkt->size = size - AV_INPUT_BUFFER_PADDING_SIZE;
+ bytestream_put_buffer(&p, old.data, old.size);
+ for (i=old.side_data_elems-1; i>=0; i--) {
+ bytestream_put_buffer(&p, old.side_data[i].data, old.side_data[i].size);
+ bytestream_put_be32(&p, old.side_data[i].size);
+ *p++ = old.side_data[i].type | ((i==old.side_data_elems-1)*128);
+ }
+ bytestream_put_be64(&p, FF_MERGE_MARKER);
+ av_assert0(p-pkt->data == pkt->size);
+ memset(p, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ av_free_packet(&old);
+ pkt->side_data_elems = 0;
+ pkt->side_data = NULL;
+ return 1;
+ }
+ return 0;
+}
+
+int av_packet_split_side_data(AVPacket *pkt){
+ if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){
+ int i;
+ unsigned int size;
+ uint8_t *p;
+
+ p = pkt->data + pkt->size - 8 - 5;
+ for (i=1; ; i++){
+ size = AV_RB32(p);
+ if (size>INT_MAX - 5 || p - pkt->data < size)
+ return 0;
+ if (p[4]&128)
+ break;
+ if (p - pkt->data < size + 5)
+ return 0;
+ p-= size+5;
+ }
+
+ if (i > AV_PKT_DATA_NB)
+ return AVERROR(ERANGE);
+
+ pkt->side_data = av_malloc_array(i, sizeof(*pkt->side_data));
+ if (!pkt->side_data)
+ return AVERROR(ENOMEM);
+
+ p= pkt->data + pkt->size - 8 - 5;
+ for (i=0; ; i++){
+ size= AV_RB32(p);
+ av_assert0(size<=INT_MAX - 5 && p - pkt->data >= size);
+ pkt->side_data[i].data = av_mallocz(size + AV_INPUT_BUFFER_PADDING_SIZE);
+ pkt->side_data[i].size = size;
+ pkt->side_data[i].type = p[4]&127;
+ if (!pkt->side_data[i].data)
+ return AVERROR(ENOMEM);
+ memcpy(pkt->side_data[i].data, p-size, size);
+ pkt->size -= size + 5;
+ if(p[4]&128)
+ break;
+ p-= size+5;
+ }
+ pkt->size -= 8;
+ pkt->side_data_elems = i+1;
+ return 1;
+ }
+ return 0;
+}
+
+uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size)
+{
+ AVDictionaryEntry *t = NULL;
+ uint8_t *data = NULL;
+ *size = 0;
+
+ if (!dict)
+ return NULL;
+
+ while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) {
+ const size_t keylen = strlen(t->key);
+ const size_t valuelen = strlen(t->value);
+ const size_t new_size = *size + keylen + 1 + valuelen + 1;
+ uint8_t *const new_data = av_realloc(data, new_size);
+
+ if (!new_data)
+ goto fail;
+ data = new_data;
+ if (new_size > INT_MAX)
+ goto fail;
+
+ memcpy(data + *size, t->key, keylen + 1);
+ memcpy(data + *size + keylen + 1, t->value, valuelen + 1);
+
+ *size = new_size;
+ }
+
+ return data;
+
+fail:
+ av_freep(&data);
+ *size = 0;
+ return NULL;
+}
+
+int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict)
+{
+ const uint8_t *end = data + size;
+ int ret = 0;
+
+ if (!dict || !data || !size)
+ return ret;
+ if (size && end[-1])
+ return AVERROR_INVALIDDATA;
+ while (data < end) {
+ const uint8_t *key = data;
+ const uint8_t *val = data + strlen(key) + 1;
+
+ if (val >= end)
+ return AVERROR_INVALIDDATA;
+
+ ret = av_dict_set(dict, key, val, 0);
+ if (ret < 0)
+ break;
+ data = val + strlen(val) + 1;
+ }
+
+ return ret;
+}
+
+int av_packet_shrink_side_data(AVPacket *pkt, enum AVPacketSideDataType type,
+ int size)
+{
+ int i;
+
+ for (i = 0; i < pkt->side_data_elems; i++) {
+ if (pkt->side_data[i].type == type) {
+ if (size > pkt->side_data[i].size)
+ return AVERROR(ENOMEM);
+ pkt->side_data[i].size = size;
+ return 0;
+ }
+ }
+ return AVERROR(ENOENT);
+}
+
+int av_packet_copy_props(AVPacket *dst, const AVPacket *src)
+{
+ int i;
+
+ dst->pts = src->pts;
+ dst->dts = src->dts;
+ dst->pos = src->pos;
+ dst->duration = src->duration;
+ dst->convergence_duration = src->convergence_duration;
+ dst->flags = src->flags;
+ dst->stream_index = src->stream_index;
+
+ for (i = 0; i < src->side_data_elems; i++) {
+ enum AVPacketSideDataType type = src->side_data[i].type;
+ int size = src->side_data[i].size;
+ uint8_t *src_data = src->side_data[i].data;
+ uint8_t *dst_data = av_packet_new_side_data(dst, type, size);
+
+ if (!dst_data) {
+ av_packet_free_side_data(dst);
+ return AVERROR(ENOMEM);
+ }
+ memcpy(dst_data, src_data, size);
+ }
+
+ return 0;
+}
+
+void av_packet_unref(AVPacket *pkt)
+{
+ av_packet_free_side_data(pkt);
+ av_buffer_unref(&pkt->buf);
+ av_init_packet(pkt);
+ pkt->data = NULL;
+ pkt->size = 0;
+}
+
+int av_packet_ref(AVPacket *dst, const AVPacket *src)
+{
+ int ret;
+
+ ret = av_packet_copy_props(dst, src);
+ if (ret < 0)
+ return ret;
+
+ if (!src->buf) {
+ ret = packet_alloc(&dst->buf, src->size);
+ if (ret < 0)
+ goto fail;
+ memcpy(dst->buf->data, src->data, src->size);
+ } else {
+ dst->buf = av_buffer_ref(src->buf);
+ if (!dst->buf) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ }
+
+ dst->size = src->size;
+ dst->data = dst->buf->data;
+ return 0;
+fail:
+ av_packet_free_side_data(dst);
+ return ret;
+}
+
+void av_packet_move_ref(AVPacket *dst, AVPacket *src)
+{
+ *dst = *src;
+ av_init_packet(src);
+}
+
+void av_packet_rescale_ts(AVPacket *pkt, AVRational src_tb, AVRational dst_tb)
+{
+ if (pkt->pts != AV_NOPTS_VALUE)
+ pkt->pts = av_rescale_q(pkt->pts, src_tb, dst_tb);
+ if (pkt->dts != AV_NOPTS_VALUE)
+ pkt->dts = av_rescale_q(pkt->dts, src_tb, dst_tb);
+ if (pkt->duration > 0)
+ pkt->duration = av_rescale_q(pkt->duration, src_tb, dst_tb);
+ if (pkt->convergence_duration > 0)
+ pkt->convergence_duration = av_rescale_q(pkt->convergence_duration, src_tb, dst_tb);
+}
+
+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;
+ int i;
+
+ side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, &side_data_size);
+ if (!side_data) {
+ side_data_size = 4+4+8*error_count;
+ side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,
+ side_data_size);
+ }
+
+ if (!side_data || side_data_size < 4+4+8*error_count)
+ return AVERROR(ENOMEM);
+
+ AV_WL32(side_data , quality );
+ side_data[4] = pict_type;
+ side_data[5] = error_count;
+ for (i = 0; i<error_count; i++)
+ AV_WL64(side_data+8 + 8*i , error[i]);
+
+ return 0;
+}
diff --git a/ffmpeg-2-8-11/libavcodec/avpicture.c b/ffmpeg-2-8-12/libavcodec/avpicture.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/avpicture.c
rename to ffmpeg-2-8-12/libavcodec/avpicture.c
diff --git a/ffmpeg-2-8-11/libavcodec/avr32/mathops.h b/ffmpeg-2-8-12/libavcodec/avr32/mathops.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/avr32/mathops.h
rename to ffmpeg-2-8-12/libavcodec/avr32/mathops.h
diff --git a/ffmpeg-2-8-11/libavcodec/avrndec.c b/ffmpeg-2-8-12/libavcodec/avrndec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/avrndec.c
rename to ffmpeg-2-8-12/libavcodec/avrndec.c
diff --git a/ffmpeg-2-8-11/libavcodec/avs.c b/ffmpeg-2-8-12/libavcodec/avs.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/avs.c
rename to ffmpeg-2-8-12/libavcodec/avs.c
diff --git a/ffmpeg-2-8-11/libavcodec/avuidec.c b/ffmpeg-2-8-12/libavcodec/avuidec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/avuidec.c
rename to ffmpeg-2-8-12/libavcodec/avuidec.c
diff --git a/ffmpeg-2-8-11/libavcodec/avuienc.c b/ffmpeg-2-8-12/libavcodec/avuienc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/avuienc.c
rename to ffmpeg-2-8-12/libavcodec/avuienc.c
diff --git a/ffmpeg-2-8-11/libavcodec/bethsoftvideo.c b/ffmpeg-2-8-12/libavcodec/bethsoftvideo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bethsoftvideo.c
rename to ffmpeg-2-8-12/libavcodec/bethsoftvideo.c
diff --git a/ffmpeg-2-8-11/libavcodec/bethsoftvideo.h b/ffmpeg-2-8-12/libavcodec/bethsoftvideo.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bethsoftvideo.h
rename to ffmpeg-2-8-12/libavcodec/bethsoftvideo.h
diff --git a/ffmpeg-2-8-11/libavcodec/bfi.c b/ffmpeg-2-8-12/libavcodec/bfi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bfi.c
rename to ffmpeg-2-8-12/libavcodec/bfi.c
diff --git a/ffmpeg-2-8-11/libavcodec/bfin/README b/ffmpeg-2-8-12/libavcodec/bfin/README
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bfin/README
rename to ffmpeg-2-8-12/libavcodec/bfin/README
diff --git a/ffmpeg-2-8-11/libavcodec/bgmc.c b/ffmpeg-2-8-12/libavcodec/bgmc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bgmc.c
rename to ffmpeg-2-8-12/libavcodec/bgmc.c
diff --git a/ffmpeg-2-8-11/libavcodec/bgmc.h b/ffmpeg-2-8-12/libavcodec/bgmc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bgmc.h
rename to ffmpeg-2-8-12/libavcodec/bgmc.h
diff --git a/ffmpeg-2-8-11/libavcodec/bink.c b/ffmpeg-2-8-12/libavcodec/bink.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bink.c
rename to ffmpeg-2-8-12/libavcodec/bink.c
diff --git a/ffmpeg-2-8-11/libavcodec/binkaudio.c b/ffmpeg-2-8-12/libavcodec/binkaudio.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/binkaudio.c
rename to ffmpeg-2-8-12/libavcodec/binkaudio.c
diff --git a/ffmpeg-2-8-11/libavcodec/binkdata.h b/ffmpeg-2-8-12/libavcodec/binkdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/binkdata.h
rename to ffmpeg-2-8-12/libavcodec/binkdata.h
diff --git a/ffmpeg-2-8-11/libavcodec/binkdsp.c b/ffmpeg-2-8-12/libavcodec/binkdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/binkdsp.c
rename to ffmpeg-2-8-12/libavcodec/binkdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/binkdsp.h b/ffmpeg-2-8-12/libavcodec/binkdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/binkdsp.h
rename to ffmpeg-2-8-12/libavcodec/binkdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/bintext.c b/ffmpeg-2-8-12/libavcodec/bintext.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bintext.c
rename to ffmpeg-2-8-12/libavcodec/bintext.c
diff --git a/ffmpeg-2-8-11/libavcodec/bintext.h b/ffmpeg-2-8-12/libavcodec/bintext.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bintext.h
rename to ffmpeg-2-8-12/libavcodec/bintext.h
diff --git a/ffmpeg-2-8-11/libavcodec/bit_depth_template.c b/ffmpeg-2-8-12/libavcodec/bit_depth_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bit_depth_template.c
rename to ffmpeg-2-8-12/libavcodec/bit_depth_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/bitstream.c b/ffmpeg-2-8-12/libavcodec/bitstream.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bitstream.c
rename to ffmpeg-2-8-12/libavcodec/bitstream.c
diff --git a/ffmpeg-2-8-11/libavcodec/bitstream_filter.c b/ffmpeg-2-8-12/libavcodec/bitstream_filter.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bitstream_filter.c
rename to ffmpeg-2-8-12/libavcodec/bitstream_filter.c
diff --git a/ffmpeg-2-8-11/libavcodec/blockdsp.c b/ffmpeg-2-8-12/libavcodec/blockdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/blockdsp.c
rename to ffmpeg-2-8-12/libavcodec/blockdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/blockdsp.h b/ffmpeg-2-8-12/libavcodec/blockdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/blockdsp.h
rename to ffmpeg-2-8-12/libavcodec/blockdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/bmp.c b/ffmpeg-2-8-12/libavcodec/bmp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bmp.c
rename to ffmpeg-2-8-12/libavcodec/bmp.c
diff --git a/ffmpeg-2-8-11/libavcodec/bmp.h b/ffmpeg-2-8-12/libavcodec/bmp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bmp.h
rename to ffmpeg-2-8-12/libavcodec/bmp.h
diff --git a/ffmpeg-2-8-11/libavcodec/bmp_parser.c b/ffmpeg-2-8-12/libavcodec/bmp_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bmp_parser.c
rename to ffmpeg-2-8-12/libavcodec/bmp_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/bmpenc.c b/ffmpeg-2-8-12/libavcodec/bmpenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bmpenc.c
rename to ffmpeg-2-8-12/libavcodec/bmpenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/bmvaudio.c b/ffmpeg-2-8-12/libavcodec/bmvaudio.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bmvaudio.c
rename to ffmpeg-2-8-12/libavcodec/bmvaudio.c
diff --git a/ffmpeg-2-8-12/libavcodec/bmvvideo.c b/ffmpeg-2-8-12/libavcodec/bmvvideo.c
new file mode 100644
index 0000000..cf7f0a0
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/bmvvideo.c
@@ -0,0 +1,298 @@
+/*
+ * Discworld II BMV video decoder
+ * Copyright (c) 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 "libavutil/avassert.h"
+#include "libavutil/common.h"
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+
+enum BMVFlags{
+ BMV_NOP = 0,
+ BMV_END,
+ BMV_DELTA,
+ BMV_INTRA,
+
+ BMV_SCROLL = 0x04,
+ BMV_PALETTE = 0x08,
+ BMV_COMMAND = 0x10,
+ BMV_AUDIO = 0x20,
+ BMV_EXT = 0x40,
+ BMV_PRINT = 0x80
+};
+
+#define SCREEN_WIDE 640
+#define SCREEN_HIGH 429
+
+typedef struct BMVDecContext {
+ AVCodecContext *avctx;
+
+ uint8_t *frame, frame_base[SCREEN_WIDE * (SCREEN_HIGH + 1)];
+ uint32_t pal[256];
+ const uint8_t *stream;
+} BMVDecContext;
+
+#define NEXT_BYTE(v) (v) = forward ? (v) + 1 : (v) - 1;
+
+static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, int frame_off)
+{
+ unsigned val, saved_val = 0;
+ int tmplen = src_len;
+ const uint8_t *src, *source_end = source + src_len;
+ uint8_t *frame_end = frame + SCREEN_WIDE * SCREEN_HIGH;
+ uint8_t *dst, *dst_end;
+ int len, mask;
+ int forward = (frame_off <= -SCREEN_WIDE) || (frame_off >= 0);
+ int read_two_nibbles, flag;
+ int advance_mode;
+ int mode = 0;
+ int i;
+
+ if (src_len <= 0)
+ return AVERROR_INVALIDDATA;
+
+ if (forward) {
+ src = source;
+ dst = frame;
+ dst_end = frame_end;
+ } else {
+ src = source + src_len - 1;
+ dst = frame_end - 1;
+ dst_end = frame - 1;
+ }
+ for (;;) {
+ int shift = 0;
+ flag = 0;
+
+ /* The mode/len decoding is a bit strange:
+ * values are coded as variable-length codes with nibble units,
+ * code end is signalled by two top bits in the nibble being nonzero.
+ * And since data is bytepacked and we read two nibbles at a time,
+ * we may get a nibble belonging to the next code.
+ * Hence this convoluted loop.
+ */
+ if (!mode || (tmplen == 4)) {
+ if (src < source || src >= source_end)
+ return AVERROR_INVALIDDATA;
+ val = *src;
+ read_two_nibbles = 1;
+ } else {
+ val = saved_val;
+ read_two_nibbles = 0;
+ }
+ if (!(val & 0xC)) {
+ for (;;) {
+ if(shift>22)
+ return -1;
+ if (!read_two_nibbles) {
+ if (src < source || src >= source_end)
+ return AVERROR_INVALIDDATA;
+ shift += 2;
+ val |= (unsigned)*src << shift;
+ if (*src & 0xC)
+ break;
+ }
+ // two upper bits of the nibble is zero,
+ // so shift top nibble value down into their place
+ read_two_nibbles = 0;
+ shift += 2;
+ mask = (1 << shift) - 1;
+ val = ((val >> 2) & ~mask) | (val & mask);
+ NEXT_BYTE(src);
+ if ((val & (0xC << shift))) {
+ flag = 1;
+ break;
+ }
+ }
+ } else if (mode) {
+ flag = tmplen != 4;
+ }
+ if (flag) {
+ tmplen = 4;
+ } else {
+ saved_val = val >> (4 + shift);
+ tmplen = 0;
+ val &= (1 << (shift + 4)) - 1;
+ NEXT_BYTE(src);
+ }
+ advance_mode = val & 1;
+ len = (val >> 1) - 1;
+ av_assert0(len>0);
+ mode += 1 + advance_mode;
+ if (mode >= 4)
+ mode -= 3;
+ if (len <= 0 || FFABS(dst_end - dst) < len)
+ return AVERROR_INVALIDDATA;
+ switch (mode) {
+ case 1:
+ if (forward) {
+ if (dst - frame + SCREEN_WIDE < frame_off ||
+ dst - frame + SCREEN_WIDE + frame_off < 0 ||
+ frame_end - dst < frame_off + len ||
+ frame_end - dst < len)
+ return AVERROR_INVALIDDATA;
+ for (i = 0; i < len; i++)
+ dst[i] = dst[frame_off + i];
+ dst += len;
+ } else {
+ dst -= len;
+ if (dst - frame + SCREEN_WIDE < frame_off ||
+ dst - frame + SCREEN_WIDE + frame_off < 0 ||
+ frame_end - dst < frame_off + len ||
+ frame_end - dst < len)
+ return AVERROR_INVALIDDATA;
+ for (i = len - 1; i >= 0; i--)
+ dst[i] = dst[frame_off + i];
+ }
+ break;
+ case 2:
+ if (forward) {
+ if (source + src_len - src < len)
+ return AVERROR_INVALIDDATA;
+ memcpy(dst, src, len);
+ dst += len;
+ src += len;
+ } else {
+ if (src - source < len)
+ return AVERROR_INVALIDDATA;
+ dst -= len;
+ src -= len;
+ memcpy(dst, src, len);
+ }
+ break;
+ case 3:
+ val = forward ? dst[-1] : dst[1];
+ if (forward) {
+ memset(dst, val, len);
+ dst += len;
+ } else {
+ dst -= len;
+ memset(dst, val, len);
+ }
+ break;
+ }
+ if (dst == dst_end)
+ return 0;
+ }
+ return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *pkt)
+{
+ BMVDecContext * const c = avctx->priv_data;
+ AVFrame *frame = data;
+ int type, scr_off;
+ int i, ret;
+ uint8_t *srcptr, *outptr;
+
+ c->stream = pkt->data;
+ type = bytestream_get_byte(&c->stream);
+ if (type & BMV_AUDIO) {
+ int blobs = bytestream_get_byte(&c->stream);
+ if (pkt->size < blobs * 65 + 2) {
+ av_log(avctx, AV_LOG_ERROR, "Audio data doesn't fit in frame\n");
+ return AVERROR_INVALIDDATA;
+ }
+ c->stream += blobs * 65;
+ }
+ if (type & BMV_COMMAND) {
+ int command_size = (type & BMV_PRINT) ? 8 : 10;
+ if (c->stream - pkt->data + command_size > pkt->size) {
+ av_log(avctx, AV_LOG_ERROR, "Command data doesn't fit in frame\n");
+ return AVERROR_INVALIDDATA;
+ }
+ c->stream += command_size;
+ }
+ if (type & BMV_PALETTE) {
+ if (c->stream - pkt->data > pkt->size - 768) {
+ av_log(avctx, AV_LOG_ERROR, "Palette data doesn't fit in frame\n");
+ return AVERROR_INVALIDDATA;
+ }
+ for (i = 0; i < 256; i++)
+ c->pal[i] = 0xFFU << 24 | bytestream_get_be24(&c->stream);
+ }
+ if (type & BMV_SCROLL) {
+ if (c->stream - pkt->data > pkt->size - 2) {
+ av_log(avctx, AV_LOG_ERROR, "Screen offset data doesn't fit in frame\n");
+ return AVERROR_INVALIDDATA;
+ }
+ scr_off = (int16_t)bytestream_get_le16(&c->stream);
+ } else if ((type & BMV_INTRA) == BMV_INTRA) {
+ scr_off = -640;
+ } else {
+ scr_off = 0;
+ }
+
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+
+ if (decode_bmv_frame(c->stream, pkt->size - (c->stream - pkt->data), c->frame, scr_off)) {
+ av_log(avctx, AV_LOG_ERROR, "Error decoding frame data\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ memcpy(frame->data[1], c->pal, AVPALETTE_SIZE);
+ frame->palette_has_changed = type & BMV_PALETTE;
+
+ outptr = frame->data[0];
+ srcptr = c->frame;
+
+ for (i = 0; i < avctx->height; i++) {
+ memcpy(outptr, srcptr, avctx->width);
+ srcptr += avctx->width;
+ outptr += frame->linesize[0];
+ }
+
+ *got_frame = 1;
+
+ /* always report that the buffer was completely consumed */
+ return pkt->size;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ BMVDecContext * const c = avctx->priv_data;
+
+ c->avctx = avctx;
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
+ if (avctx->width != SCREEN_WIDE || avctx->height != SCREEN_HIGH) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid dimension %dx%d\n", avctx->width, avctx->height);
+ return AVERROR_INVALIDDATA;
+ }
+
+ c->frame = c->frame_base + 640;
+
+ return 0;
+}
+
+AVCodec ff_bmv_video_decoder = {
+ .name = "bmv_video",
+ .long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV video"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_BMV_VIDEO,
+ .priv_data_size = sizeof(BMVDecContext),
+ .init = decode_init,
+ .decode = decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/brenderpix.c b/ffmpeg-2-8-12/libavcodec/brenderpix.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/brenderpix.c
rename to ffmpeg-2-8-12/libavcodec/brenderpix.c
diff --git a/ffmpeg-2-8-11/libavcodec/bswapdsp.c b/ffmpeg-2-8-12/libavcodec/bswapdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bswapdsp.c
rename to ffmpeg-2-8-12/libavcodec/bswapdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/bswapdsp.h b/ffmpeg-2-8-12/libavcodec/bswapdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bswapdsp.h
rename to ffmpeg-2-8-12/libavcodec/bswapdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/bytestream.h b/ffmpeg-2-8-12/libavcodec/bytestream.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/bytestream.h
rename to ffmpeg-2-8-12/libavcodec/bytestream.h
diff --git a/ffmpeg-2-8-11/libavcodec/c93.c b/ffmpeg-2-8-12/libavcodec/c93.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/c93.c
rename to ffmpeg-2-8-12/libavcodec/c93.c
diff --git a/ffmpeg-2-8-11/libavcodec/cabac.c b/ffmpeg-2-8-12/libavcodec/cabac.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cabac.c
rename to ffmpeg-2-8-12/libavcodec/cabac.c
diff --git a/ffmpeg-2-8-11/libavcodec/cabac.h b/ffmpeg-2-8-12/libavcodec/cabac.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cabac.h
rename to ffmpeg-2-8-12/libavcodec/cabac.h
diff --git a/ffmpeg-2-8-11/libavcodec/cabac_functions.h b/ffmpeg-2-8-12/libavcodec/cabac_functions.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cabac_functions.h
rename to ffmpeg-2-8-12/libavcodec/cabac_functions.h
diff --git a/ffmpeg-2-8-11/libavcodec/cabac_tablegen.c b/ffmpeg-2-8-12/libavcodec/cabac_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cabac_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/cabac_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/cabac_tablegen.h b/ffmpeg-2-8-12/libavcodec/cabac_tablegen.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cabac_tablegen.h
rename to ffmpeg-2-8-12/libavcodec/cabac_tablegen.h
diff --git a/ffmpeg-2-8-11/libavcodec/canopus.c b/ffmpeg-2-8-12/libavcodec/canopus.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/canopus.c
rename to ffmpeg-2-8-12/libavcodec/canopus.c
diff --git a/ffmpeg-2-8-11/libavcodec/canopus.h b/ffmpeg-2-8-12/libavcodec/canopus.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/canopus.h
rename to ffmpeg-2-8-12/libavcodec/canopus.h
diff --git a/ffmpeg-2-8-12/libavcodec/cavs.c b/ffmpeg-2-8-12/libavcodec/cavs.c
new file mode 100644
index 0000000..9a4a03e
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/cavs.c
@@ -0,0 +1,861 @@
+/*
+ * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
+ * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer at gmx.de>
+ *
+ * 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
+ * Chinese AVS video (AVS1-P2, JiZhun profile) decoder
+ * @author Stefan Gehrer <stefan.gehrer at gmx.de>
+ */
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "golomb.h"
+#include "h264chroma.h"
+#include "idctdsp.h"
+#include "internal.h"
+#include "mathops.h"
+#include "qpeldsp.h"
+#include "cavs.h"
+
+static const uint8_t alpha_tab[64] = {
+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 3, 3,
+ 4, 4, 5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 18, 20,
+ 22, 24, 26, 28, 30, 33, 33, 35, 35, 36, 37, 37, 39, 39, 42, 44,
+ 46, 48, 50, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64
+};
+
+static const uint8_t beta_tab[64] = {
+ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
+ 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6,
+ 6, 7, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 23, 24, 24, 25, 25, 26, 27
+};
+
+static const uint8_t tc_tab[64] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4,
+ 5, 5, 5, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9
+};
+
+/** mark block as unavailable, i.e. out of picture
+ * or not yet decoded */
+static const cavs_vector un_mv = { 0, 0, 1, NOT_AVAIL };
+
+static const int8_t left_modifier_l[8] = { 0, -1, 6, -1, -1, 7, 6, 7 };
+static const int8_t top_modifier_l[8] = { -1, 1, 5, -1, -1, 5, 7, 7 };
+static const int8_t left_modifier_c[7] = { 5, -1, 2, -1, 6, 5, 6 };
+static const int8_t top_modifier_c[7] = { 4, 1, -1, -1, 4, 6, 6 };
+
+/*****************************************************************************
+ *
+ * in-loop deblocking filter
+ *
+ ****************************************************************************/
+
+static inline int get_bs(cavs_vector *mvP, cavs_vector *mvQ, int b)
+{
+ if ((mvP->ref == REF_INTRA) || (mvQ->ref == REF_INTRA))
+ return 2;
+ if((abs(mvP->x - mvQ->x) >= 4) ||
+ (abs(mvP->y - mvQ->y) >= 4) ||
+ (mvP->ref != mvQ->ref))
+ return 1;
+ if (b) {
+ mvP += MV_BWD_OFFS;
+ mvQ += MV_BWD_OFFS;
+ if((abs(mvP->x - mvQ->x) >= 4) ||
+ (abs(mvP->y - mvQ->y) >= 4) ||
+ (mvP->ref != mvQ->ref))
+ return 1;
+ }
+ return 0;
+}
+
+#define SET_PARAMS \
+ alpha = alpha_tab[av_clip_uintp2(qp_avg + h->alpha_offset, 6)]; \
+ beta = beta_tab[av_clip_uintp2(qp_avg + h->beta_offset, 6)]; \
+ tc = tc_tab[av_clip_uintp2(qp_avg + h->alpha_offset, 6)];
+
+/**
+ * in-loop deblocking filter for a single macroblock
+ *
+ * boundary strength (bs) mapping:
+ *
+ * --4---5--
+ * 0 2 |
+ * | 6 | 7 |
+ * 1 3 |
+ * ---------
+ *
+ */
+void ff_cavs_filter(AVSContext *h, enum cavs_mb mb_type)
+{
+ uint8_t bs[8];
+ int qp_avg, alpha, beta, tc;
+ int i;
+
+ /* save un-deblocked lines */
+ h->topleft_border_y = h->top_border_y[h->mbx * 16 + 15];
+ h->topleft_border_u = h->top_border_u[h->mbx * 10 + 8];
+ h->topleft_border_v = h->top_border_v[h->mbx * 10 + 8];
+ memcpy(&h->top_border_y[h->mbx * 16], h->cy + 15 * h->l_stride, 16);
+ memcpy(&h->top_border_u[h->mbx * 10 + 1], h->cu + 7 * h->c_stride, 8);
+ memcpy(&h->top_border_v[h->mbx * 10 + 1], h->cv + 7 * h->c_stride, 8);
+ for (i = 0; i < 8; i++) {
+ h->left_border_y[i * 2 + 1] = *(h->cy + 15 + (i * 2 + 0) * h->l_stride);
+ h->left_border_y[i * 2 + 2] = *(h->cy + 15 + (i * 2 + 1) * h->l_stride);
+ h->left_border_u[i + 1] = *(h->cu + 7 + i * h->c_stride);
+ h->left_border_v[i + 1] = *(h->cv + 7 + i * h->c_stride);
+ }
+ if (!h->loop_filter_disable) {
+ /* determine bs */
+ if (mb_type == I_8X8)
+ memset(bs, 2, 8);
+ else {
+ memset(bs, 0, 8);
+ if (ff_cavs_partition_flags[mb_type] & SPLITV) {
+ bs[2] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X1], mb_type > P_8X8);
+ bs[3] = get_bs(&h->mv[MV_FWD_X2], &h->mv[MV_FWD_X3], mb_type > P_8X8);
+ }
+ if (ff_cavs_partition_flags[mb_type] & SPLITH) {
+ bs[6] = get_bs(&h->mv[MV_FWD_X0], &h->mv[MV_FWD_X2], mb_type > P_8X8);
+ bs[7] = get_bs(&h->mv[MV_FWD_X1], &h->mv[MV_FWD_X3], mb_type > P_8X8);
+ }
+ bs[0] = get_bs(&h->mv[MV_FWD_A1], &h->mv[MV_FWD_X0], mb_type > P_8X8);
+ bs[1] = get_bs(&h->mv[MV_FWD_A3], &h->mv[MV_FWD_X2], mb_type > P_8X8);
+ bs[4] = get_bs(&h->mv[MV_FWD_B2], &h->mv[MV_FWD_X0], mb_type > P_8X8);
+ bs[5] = get_bs(&h->mv[MV_FWD_B3], &h->mv[MV_FWD_X1], mb_type > P_8X8);
+ }
+ if (AV_RN64(bs)) {
+ if (h->flags & A_AVAIL) {
+ qp_avg = (h->qp + h->left_qp + 1) >> 1;
+ SET_PARAMS;
+ h->cdsp.cavs_filter_lv(h->cy, h->l_stride, alpha, beta, tc, bs[0], bs[1]);
+ qp_avg = (ff_cavs_chroma_qp[h->qp] + ff_cavs_chroma_qp[h->left_qp] + 1) >> 1;
+ SET_PARAMS;
+ h->cdsp.cavs_filter_cv(h->cu, h->c_stride, alpha, beta, tc, bs[0], bs[1]);
+ h->cdsp.cavs_filter_cv(h->cv, h->c_stride, alpha, beta, tc, bs[0], bs[1]);
+ }
+ qp_avg = h->qp;
+ SET_PARAMS;
+ h->cdsp.cavs_filter_lv(h->cy + 8, h->l_stride, alpha, beta, tc, bs[2], bs[3]);
+ h->cdsp.cavs_filter_lh(h->cy + 8 * h->l_stride, h->l_stride, alpha, beta, tc, bs[6], bs[7]);
+
+ if (h->flags & B_AVAIL) {
+ qp_avg = (h->qp + h->top_qp[h->mbx] + 1) >> 1;
+ SET_PARAMS;
+ h->cdsp.cavs_filter_lh(h->cy, h->l_stride, alpha, beta, tc, bs[4], bs[5]);
+ qp_avg = (ff_cavs_chroma_qp[h->qp] + ff_cavs_chroma_qp[h->top_qp[h->mbx]] + 1) >> 1;
+ SET_PARAMS;
+ h->cdsp.cavs_filter_ch(h->cu, h->c_stride, alpha, beta, tc, bs[4], bs[5]);
+ h->cdsp.cavs_filter_ch(h->cv, h->c_stride, alpha, beta, tc, bs[4], bs[5]);
+ }
+ }
+ }
+ h->left_qp = h->qp;
+ h->top_qp[h->mbx] = h->qp;
+}
+
+#undef SET_PARAMS
+
+/*****************************************************************************
+ *
+ * spatial intra prediction
+ *
+ ****************************************************************************/
+
+void ff_cavs_load_intra_pred_luma(AVSContext *h, uint8_t *top,
+ uint8_t **left, int block)
+{
+ int i;
+
+ switch (block) {
+ case 0:
+ *left = h->left_border_y;
+ h->left_border_y[0] = h->left_border_y[1];
+ memset(&h->left_border_y[17], h->left_border_y[16], 9);
+ memcpy(&top[1], &h->top_border_y[h->mbx * 16], 16);
+ top[17] = top[16];
+ top[0] = top[1];
+ if ((h->flags & A_AVAIL) && (h->flags & B_AVAIL))
+ h->left_border_y[0] = top[0] = h->topleft_border_y;
+ break;
+ case 1:
+ *left = h->intern_border_y;
+ for (i = 0; i < 8; i++)
+ h->intern_border_y[i + 1] = *(h->cy + 7 + i * h->l_stride);
+ memset(&h->intern_border_y[9], h->intern_border_y[8], 9);
+ h->intern_border_y[0] = h->intern_border_y[1];
+ memcpy(&top[1], &h->top_border_y[h->mbx * 16 + 8], 8);
+ if (h->flags & C_AVAIL)
+ memcpy(&top[9], &h->top_border_y[(h->mbx + 1) * 16], 8);
+ else
+ memset(&top[9], top[8], 9);
+ top[17] = top[16];
+ top[0] = top[1];
+ if (h->flags & B_AVAIL)
+ h->intern_border_y[0] = top[0] = h->top_border_y[h->mbx * 16 + 7];
+ break;
+ case 2:
+ *left = &h->left_border_y[8];
+ memcpy(&top[1], h->cy + 7 * h->l_stride, 16);
+ top[17] = top[16];
+ top[0] = top[1];
+ if (h->flags & A_AVAIL)
+ top[0] = h->left_border_y[8];
+ break;
+ case 3:
+ *left = &h->intern_border_y[8];
+ for (i = 0; i < 8; i++)
+ h->intern_border_y[i + 9] = *(h->cy + 7 + (i + 8) * h->l_stride);
+ memset(&h->intern_border_y[17], h->intern_border_y[16], 9);
+ memcpy(&top[0], h->cy + 7 + 7 * h->l_stride, 9);
+ memset(&top[9], top[8], 9);
+ break;
+ }
+}
+
+void ff_cavs_load_intra_pred_chroma(AVSContext *h)
+{
+ /* extend borders by one pixel */
+ h->left_border_u[9] = h->left_border_u[8];
+ h->left_border_v[9] = h->left_border_v[8];
+ if(h->flags & C_AVAIL) {
+ h->top_border_u[h->mbx*10 + 9] = h->top_border_u[h->mbx*10 + 11];
+ h->top_border_v[h->mbx*10 + 9] = h->top_border_v[h->mbx*10 + 11];
+ } else {
+ h->top_border_u[h->mbx * 10 + 9] = h->top_border_u[h->mbx * 10 + 8];
+ h->top_border_v[h->mbx * 10 + 9] = h->top_border_v[h->mbx * 10 + 8];
+ }
+ if((h->flags & A_AVAIL) && (h->flags & B_AVAIL)) {
+ h->top_border_u[h->mbx * 10] = h->left_border_u[0] = h->topleft_border_u;
+ h->top_border_v[h->mbx * 10] = h->left_border_v[0] = h->topleft_border_v;
+ } else {
+ h->left_border_u[0] = h->left_border_u[1];
+ h->left_border_v[0] = h->left_border_v[1];
+ h->top_border_u[h->mbx * 10] = h->top_border_u[h->mbx * 10 + 1];
+ h->top_border_v[h->mbx * 10] = h->top_border_v[h->mbx * 10 + 1];
+ }
+}
+
+static void intra_pred_vert(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
+{
+ int y;
+ uint64_t a = AV_RN64(&top[1]);
+ for (y = 0; y < 8; y++)
+ *((uint64_t *)(d + y * stride)) = a;
+}
+
+static void intra_pred_horiz(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
+{
+ int y;
+ uint64_t a;
+ for (y = 0; y < 8; y++) {
+ a = left[y + 1] * 0x0101010101010101ULL;
+ *((uint64_t *)(d + y * stride)) = a;
+ }
+}
+
+static void intra_pred_dc_128(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
+{
+ int y;
+ uint64_t a = 0x8080808080808080ULL;
+ for (y = 0; y < 8; y++)
+ *((uint64_t *)(d + y * stride)) = a;
+}
+
+static void intra_pred_plane(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
+{
+ int x, y, ia;
+ int ih = 0;
+ int iv = 0;
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+
+ for (x = 0; x < 4; x++) {
+ ih += (x + 1) * (top[5 + x] - top[3 - x]);
+ iv += (x + 1) * (left[5 + x] - left[3 - x]);
+ }
+ ia = (top[8] + left[8]) << 4;
+ ih = (17 * ih + 16) >> 5;
+ iv = (17 * iv + 16) >> 5;
+ for (y = 0; y < 8; y++)
+ for (x = 0; x < 8; x++)
+ d[y * stride + x] = cm[(ia + (x - 3) * ih + (y - 3) * iv + 16) >> 5];
+}
+
+#define LOWPASS(ARRAY, INDEX) \
+ ((ARRAY[(INDEX) - 1] + 2 * ARRAY[(INDEX)] + ARRAY[(INDEX) + 1] + 2) >> 2)
+
+static void intra_pred_lp(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
+{
+ int x, y;
+ for (y = 0; y < 8; y++)
+ for (x = 0; x < 8; x++)
+ d[y * stride + x] = (LOWPASS(top, x + 1) + LOWPASS(left, y + 1)) >> 1;
+}
+
+static void intra_pred_down_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
+{
+ int x, y;
+ for (y = 0; y < 8; y++)
+ for (x = 0; x < 8; x++)
+ d[y * stride + x] = (LOWPASS(top, x + y + 2) + LOWPASS(left, x + y + 2)) >> 1;
+}
+
+static void intra_pred_down_right(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
+{
+ int x, y;
+ for (y = 0; y < 8; y++)
+ for (x = 0; x < 8; x++)
+ if (x == y)
+ d[y * stride + x] = (left[1] + 2 * top[0] + top[1] + 2) >> 2;
+ else if (x > y)
+ d[y * stride + x] = LOWPASS(top, x - y);
+ else
+ d[y * stride + x] = LOWPASS(left, y - x);
+}
+
+static void intra_pred_lp_left(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
+{
+ int x, y;
+ for (y = 0; y < 8; y++)
+ for (x = 0; x < 8; x++)
+ d[y * stride + x] = LOWPASS(left, y + 1);
+}
+
+static void intra_pred_lp_top(uint8_t *d, uint8_t *top, uint8_t *left, int stride)
+{
+ int x, y;
+ for (y = 0; y < 8; y++)
+ for (x = 0; x < 8; x++)
+ d[y * stride + x] = LOWPASS(top, x + 1);
+}
+
+#undef LOWPASS
+
+static inline void modify_pred(const int8_t *mod_table, int *mode)
+{
+ *mode = mod_table[*mode];
+ if (*mode < 0) {
+ av_log(NULL, AV_LOG_ERROR, "Illegal intra prediction mode\n");
+ *mode = 0;
+ }
+}
+
+void ff_cavs_modify_mb_i(AVSContext *h, int *pred_mode_uv)
+{
+ /* save pred modes before they get modified */
+ h->pred_mode_Y[3] = h->pred_mode_Y[5];
+ h->pred_mode_Y[6] = h->pred_mode_Y[8];
+ h->top_pred_Y[h->mbx * 2 + 0] = h->pred_mode_Y[7];
+ h->top_pred_Y[h->mbx * 2 + 1] = h->pred_mode_Y[8];
+
+ /* modify pred modes according to availability of neighbour samples */
+ if (!(h->flags & A_AVAIL)) {
+ modify_pred(left_modifier_l, &h->pred_mode_Y[4]);
+ modify_pred(left_modifier_l, &h->pred_mode_Y[7]);
+ modify_pred(left_modifier_c, pred_mode_uv);
+ }
+ if (!(h->flags & B_AVAIL)) {
+ modify_pred(top_modifier_l, &h->pred_mode_Y[4]);
+ modify_pred(top_modifier_l, &h->pred_mode_Y[5]);
+ modify_pred(top_modifier_c, pred_mode_uv);
+ }
+}
+
+/*****************************************************************************
+ *
+ * motion compensation
+ *
+ ****************************************************************************/
+
+static inline void mc_dir_part(AVSContext *h, AVFrame *pic, int chroma_height,
+ int delta, int list, uint8_t *dest_y,
+ uint8_t *dest_cb, uint8_t *dest_cr,
+ int src_x_offset, int src_y_offset,
+ qpel_mc_func *qpix_op,
+ h264_chroma_mc_func chroma_op, cavs_vector *mv)
+{
+ const int mx = mv->x + src_x_offset * 8;
+ const int my = mv->y + src_y_offset * 8;
+ const int luma_xy = (mx & 3) + ((my & 3) << 2);
+ uint8_t *src_y = pic->data[0] + (mx >> 2) + (my >> 2) * h->l_stride;
+ uint8_t *src_cb = pic->data[1] + (mx >> 3) + (my >> 3) * h->c_stride;
+ uint8_t *src_cr = pic->data[2] + (mx >> 3) + (my >> 3) * h->c_stride;
+ int extra_width = 0;
+ int extra_height = extra_width;
+ const int full_mx = mx >> 2;
+ const int full_my = my >> 2;
+ const int pic_width = 16 * h->mb_width;
+ const int pic_height = 16 * h->mb_height;
+ int emu = 0;
+
+ if (!pic->data[0])
+ return;
+ if (mx & 7)
+ extra_width -= 3;
+ if (my & 7)
+ extra_height -= 3;
+
+ if (full_mx < 0 - extra_width ||
+ full_my < 0 - extra_height ||
+ full_mx + 16 /* FIXME */ > pic_width + extra_width ||
+ full_my + 16 /* FIXME */ > pic_height + extra_height) {
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer,
+ src_y - 2 - 2 * h->l_stride,
+ h->l_stride, h->l_stride,
+ 16 + 5, 16 + 5 /* FIXME */,
+ full_mx - 2, full_my - 2,
+ pic_width, pic_height);
+ src_y = h->edge_emu_buffer + 2 + 2 * h->l_stride;
+ emu = 1;
+ }
+
+ // FIXME try variable height perhaps?
+ qpix_op[luma_xy](dest_y, src_y, h->l_stride);
+
+ if (emu) {
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb,
+ h->c_stride, h->c_stride,
+ 9, 9 /* FIXME */,
+ mx >> 3, my >> 3,
+ pic_width >> 1, pic_height >> 1);
+ src_cb = h->edge_emu_buffer;
+ }
+ chroma_op(dest_cb, src_cb, h->c_stride, chroma_height, mx & 7, my & 7);
+
+ if (emu) {
+ h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr,
+ h->c_stride, h->c_stride,
+ 9, 9 /* FIXME */,
+ mx >> 3, my >> 3,
+ pic_width >> 1, pic_height >> 1);
+ src_cr = h->edge_emu_buffer;
+ }
+ chroma_op(dest_cr, src_cr, h->c_stride, chroma_height, mx & 7, my & 7);
+}
+
+static inline void mc_part_std(AVSContext *h, int chroma_height, int delta,
+ uint8_t *dest_y,
+ uint8_t *dest_cb,
+ uint8_t *dest_cr,
+ int x_offset, int y_offset,
+ qpel_mc_func *qpix_put,
+ h264_chroma_mc_func chroma_put,
+ qpel_mc_func *qpix_avg,
+ h264_chroma_mc_func chroma_avg,
+ cavs_vector *mv)
+{
+ qpel_mc_func *qpix_op = qpix_put;
+ h264_chroma_mc_func chroma_op = chroma_put;
+
+ dest_y += x_offset * 2 + y_offset * h->l_stride * 2;
+ dest_cb += x_offset + y_offset * h->c_stride;
+ dest_cr += x_offset + y_offset * h->c_stride;
+ x_offset += 8 * h->mbx;
+ y_offset += 8 * h->mby;
+
+ if (mv->ref >= 0) {
+ AVFrame *ref = h->DPB[mv->ref].f;
+ mc_dir_part(h, ref, chroma_height, delta, 0,
+ dest_y, dest_cb, dest_cr, x_offset, y_offset,
+ qpix_op, chroma_op, mv);
+
+ qpix_op = qpix_avg;
+ chroma_op = chroma_avg;
+ }
+
+ if ((mv + MV_BWD_OFFS)->ref >= 0) {
+ AVFrame *ref = h->DPB[0].f;
+ mc_dir_part(h, ref, chroma_height, delta, 1,
+ dest_y, dest_cb, dest_cr, x_offset, y_offset,
+ qpix_op, chroma_op, mv + MV_BWD_OFFS);
+ }
+}
+
+void ff_cavs_inter(AVSContext *h, enum cavs_mb mb_type)
+{
+ if (ff_cavs_partition_flags[mb_type] == 0) { // 16x16
+ mc_part_std(h, 8, 0, h->cy, h->cu, h->cv, 0, 0,
+ h->cdsp.put_cavs_qpel_pixels_tab[0],
+ h->h264chroma.put_h264_chroma_pixels_tab[0],
+ h->cdsp.avg_cavs_qpel_pixels_tab[0],
+ h->h264chroma.avg_h264_chroma_pixels_tab[0],
+ &h->mv[MV_FWD_X0]);
+ } else {
+ mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 0,
+ h->cdsp.put_cavs_qpel_pixels_tab[1],
+ h->h264chroma.put_h264_chroma_pixels_tab[1],
+ h->cdsp.avg_cavs_qpel_pixels_tab[1],
+ h->h264chroma.avg_h264_chroma_pixels_tab[1],
+ &h->mv[MV_FWD_X0]);
+ mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 0,
+ h->cdsp.put_cavs_qpel_pixels_tab[1],
+ h->h264chroma.put_h264_chroma_pixels_tab[1],
+ h->cdsp.avg_cavs_qpel_pixels_tab[1],
+ h->h264chroma.avg_h264_chroma_pixels_tab[1],
+ &h->mv[MV_FWD_X1]);
+ mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 0, 4,
+ h->cdsp.put_cavs_qpel_pixels_tab[1],
+ h->h264chroma.put_h264_chroma_pixels_tab[1],
+ h->cdsp.avg_cavs_qpel_pixels_tab[1],
+ h->h264chroma.avg_h264_chroma_pixels_tab[1],
+ &h->mv[MV_FWD_X2]);
+ mc_part_std(h, 4, 0, h->cy, h->cu, h->cv, 4, 4,
+ h->cdsp.put_cavs_qpel_pixels_tab[1],
+ h->h264chroma.put_h264_chroma_pixels_tab[1],
+ h->cdsp.avg_cavs_qpel_pixels_tab[1],
+ h->h264chroma.avg_h264_chroma_pixels_tab[1],
+ &h->mv[MV_FWD_X3]);
+ }
+}
+
+/*****************************************************************************
+ *
+ * motion vector prediction
+ *
+ ****************************************************************************/
+
+static inline void scale_mv(AVSContext *h, int *d_x, int *d_y,
+ cavs_vector *src, int distp)
+{
+ int64_t den = h->scale_den[FFMAX(src->ref, 0)];
+ *d_x = (src->x * distp * den + 256 + FF_SIGNBIT(src->x)) >> 9;
+ *d_y = (src->y * distp * den + 256 + FF_SIGNBIT(src->y)) >> 9;
+}
+
+static inline void mv_pred_median(AVSContext *h,
+ cavs_vector *mvP,
+ cavs_vector *mvA,
+ cavs_vector *mvB,
+ cavs_vector *mvC)
+{
+ int ax, ay, bx, by, cx, cy;
+ int len_ab, len_bc, len_ca, len_mid;
+
+ /* scale candidates according to their temporal span */
+ scale_mv(h, &ax, &ay, mvA, mvP->dist);
+ scale_mv(h, &bx, &by, mvB, mvP->dist);
+ scale_mv(h, &cx, &cy, mvC, mvP->dist);
+ /* find the geometrical median of the three candidates */
+ len_ab = abs(ax - bx) + abs(ay - by);
+ len_bc = abs(bx - cx) + abs(by - cy);
+ len_ca = abs(cx - ax) + abs(cy - ay);
+ len_mid = mid_pred(len_ab, len_bc, len_ca);
+ if (len_mid == len_ab) {
+ mvP->x = cx;
+ mvP->y = cy;
+ } else if (len_mid == len_bc) {
+ mvP->x = ax;
+ mvP->y = ay;
+ } else {
+ mvP->x = bx;
+ mvP->y = by;
+ }
+}
+
+void ff_cavs_mv(AVSContext *h, enum cavs_mv_loc nP, enum cavs_mv_loc nC,
+ enum cavs_mv_pred mode, enum cavs_block size, int ref)
+{
+ cavs_vector *mvP = &h->mv[nP];
+ cavs_vector *mvA = &h->mv[nP-1];
+ cavs_vector *mvB = &h->mv[nP-4];
+ cavs_vector *mvC = &h->mv[nC];
+ const cavs_vector *mvP2 = NULL;
+
+ mvP->ref = ref;
+ mvP->dist = h->dist[mvP->ref];
+ if (mvC->ref == NOT_AVAIL || (nP == MV_FWD_X3) || (nP == MV_BWD_X3 ))
+ mvC = &h->mv[nP - 5]; // set to top-left (mvD)
+ if (mode == MV_PRED_PSKIP &&
+ (mvA->ref == NOT_AVAIL ||
+ mvB->ref == NOT_AVAIL ||
+ (mvA->x | mvA->y | mvA->ref) == 0 ||
+ (mvB->x | mvB->y | mvB->ref) == 0)) {
+ mvP2 = &un_mv;
+ /* if there is only one suitable candidate, take it */
+ } else if (mvA->ref >= 0 && mvB->ref < 0 && mvC->ref < 0) {
+ mvP2 = mvA;
+ } else if (mvA->ref < 0 && mvB->ref >= 0 && mvC->ref < 0) {
+ mvP2 = mvB;
+ } else if (mvA->ref < 0 && mvB->ref < 0 && mvC->ref >= 0) {
+ mvP2 = mvC;
+ } else if (mode == MV_PRED_LEFT && mvA->ref == ref) {
+ mvP2 = mvA;
+ } else if (mode == MV_PRED_TOP && mvB->ref == ref) {
+ mvP2 = mvB;
+ } else if (mode == MV_PRED_TOPRIGHT && mvC->ref == ref) {
+ mvP2 = mvC;
+ }
+ if (mvP2) {
+ mvP->x = mvP2->x;
+ mvP->y = mvP2->y;
+ } else
+ mv_pred_median(h, mvP, mvA, mvB, mvC);
+
+ if (mode < MV_PRED_PSKIP) {
+ int mx = get_se_golomb(&h->gb) + (unsigned)mvP->x;
+ int my = get_se_golomb(&h->gb) + (unsigned)mvP->y;
+
+ if (mx != (int16_t)mx || my != (int16_t)my) {
+ av_log(h->avctx, AV_LOG_ERROR, "MV %d %d out of supported range\n", mx, my);
+ } else {
+ mvP->x = mx;
+ mvP->y = my;
+ }
+ }
+ set_mvs(mvP, size);
+}
+
+/*****************************************************************************
+ *
+ * macroblock level
+ *
+ ****************************************************************************/
+
+/**
+ * initialise predictors for motion vectors and intra prediction
+ */
+void ff_cavs_init_mb(AVSContext *h)
+{
+ int i;
+
+ /* copy predictors from top line (MB B and C) into cache */
+ for (i = 0; i < 3; i++) {
+ h->mv[MV_FWD_B2 + i] = h->top_mv[0][h->mbx * 2 + i];
+ h->mv[MV_BWD_B2 + i] = h->top_mv[1][h->mbx * 2 + i];
+ }
+ h->pred_mode_Y[1] = h->top_pred_Y[h->mbx * 2 + 0];
+ h->pred_mode_Y[2] = h->top_pred_Y[h->mbx * 2 + 1];
+ /* clear top predictors if MB B is not available */
+ if (!(h->flags & B_AVAIL)) {
+ h->mv[MV_FWD_B2] = un_mv;
+ h->mv[MV_FWD_B3] = un_mv;
+ h->mv[MV_BWD_B2] = un_mv;
+ h->mv[MV_BWD_B3] = un_mv;
+ h->pred_mode_Y[1] = h->pred_mode_Y[2] = NOT_AVAIL;
+ h->flags &= ~(C_AVAIL | D_AVAIL);
+ } else if (h->mbx) {
+ h->flags |= D_AVAIL;
+ }
+ if (h->mbx == h->mb_width - 1) // MB C not available
+ h->flags &= ~C_AVAIL;
+ /* clear top-right predictors if MB C is not available */
+ if (!(h->flags & C_AVAIL)) {
+ h->mv[MV_FWD_C2] = un_mv;
+ h->mv[MV_BWD_C2] = un_mv;
+ }
+ /* clear top-left predictors if MB D is not available */
+ if (!(h->flags & D_AVAIL)) {
+ h->mv[MV_FWD_D3] = un_mv;
+ h->mv[MV_BWD_D3] = un_mv;
+ }
+}
+
+/**
+ * save predictors for later macroblocks and increase
+ * macroblock address
+ * @return 0 if end of frame is reached, 1 otherwise
+ */
+int ff_cavs_next_mb(AVSContext *h)
+{
+ int i;
+
+ h->flags |= A_AVAIL;
+ h->cy += 16;
+ h->cu += 8;
+ h->cv += 8;
+ /* copy mvs as predictors to the left */
+ for (i = 0; i <= 20; i += 4)
+ h->mv[i] = h->mv[i + 2];
+ /* copy bottom mvs from cache to top line */
+ h->top_mv[0][h->mbx * 2 + 0] = h->mv[MV_FWD_X2];
+ h->top_mv[0][h->mbx * 2 + 1] = h->mv[MV_FWD_X3];
+ h->top_mv[1][h->mbx * 2 + 0] = h->mv[MV_BWD_X2];
+ h->top_mv[1][h->mbx * 2 + 1] = h->mv[MV_BWD_X3];
+ /* next MB address */
+ h->mbidx++;
+ h->mbx++;
+ if (h->mbx == h->mb_width) { // New mb line
+ h->flags = B_AVAIL | C_AVAIL;
+ /* clear left pred_modes */
+ h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
+ /* clear left mv predictors */
+ for (i = 0; i <= 20; i += 4)
+ h->mv[i] = un_mv;
+ h->mbx = 0;
+ h->mby++;
+ /* re-calculate sample pointers */
+ h->cy = h->cur.f->data[0] + h->mby * 16 * h->l_stride;
+ h->cu = h->cur.f->data[1] + h->mby * 8 * h->c_stride;
+ h->cv = h->cur.f->data[2] + h->mby * 8 * h->c_stride;
+ if (h->mby == h->mb_height) { // Frame end
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/*****************************************************************************
+ *
+ * frame level
+ *
+ ****************************************************************************/
+
+int ff_cavs_init_pic(AVSContext *h)
+{
+ int i;
+
+ /* clear some predictors */
+ for (i = 0; i <= 20; i += 4)
+ h->mv[i] = un_mv;
+ h->mv[MV_BWD_X0] = ff_cavs_dir_mv;
+ set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
+ h->mv[MV_FWD_X0] = ff_cavs_dir_mv;
+ set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
+ h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
+ h->cy = h->cur.f->data[0];
+ h->cu = h->cur.f->data[1];
+ h->cv = h->cur.f->data[2];
+ h->l_stride = h->cur.f->linesize[0];
+ h->c_stride = h->cur.f->linesize[1];
+ h->luma_scan[2] = 8 * h->l_stride;
+ h->luma_scan[3] = 8 * h->l_stride + 8;
+ h->mbx = h->mby = h->mbidx = 0;
+ h->flags = 0;
+
+ return 0;
+}
+
+/*****************************************************************************
+ *
+ * headers and interface
+ *
+ ****************************************************************************/
+
+/**
+ * some predictions require data from the top-neighbouring macroblock.
+ * this data has to be stored for one complete row of macroblocks
+ * and this storage space is allocated here
+ */
+int ff_cavs_init_top_lines(AVSContext *h)
+{
+ /* alloc top line of predictors */
+ h->top_qp = av_mallocz(h->mb_width);
+ h->top_mv[0] = av_mallocz_array(h->mb_width * 2 + 1, sizeof(cavs_vector));
+ h->top_mv[1] = av_mallocz_array(h->mb_width * 2 + 1, sizeof(cavs_vector));
+ h->top_pred_Y = av_mallocz_array(h->mb_width * 2, sizeof(*h->top_pred_Y));
+ h->top_border_y = av_mallocz_array(h->mb_width + 1, 16);
+ h->top_border_u = av_mallocz_array(h->mb_width, 10);
+ h->top_border_v = av_mallocz_array(h->mb_width, 10);
+
+ /* alloc space for co-located MVs and types */
+ h->col_mv = av_mallocz_array(h->mb_width * h->mb_height,
+ 4 * sizeof(cavs_vector));
+ h->col_type_base = av_mallocz(h->mb_width * h->mb_height);
+ h->block = av_mallocz(64 * sizeof(int16_t));
+
+ if (!h->top_qp || !h->top_mv[0] || !h->top_mv[1] || !h->top_pred_Y ||
+ !h->top_border_y || !h->top_border_u || !h->top_border_v ||
+ !h->col_mv || !h->col_type_base || !h->block) {
+ av_freep(&h->top_qp);
+ av_freep(&h->top_mv[0]);
+ av_freep(&h->top_mv[1]);
+ av_freep(&h->top_pred_Y);
+ av_freep(&h->top_border_y);
+ av_freep(&h->top_border_u);
+ av_freep(&h->top_border_v);
+ av_freep(&h->col_mv);
+ av_freep(&h->col_type_base);
+ av_freep(&h->block);
+ return AVERROR(ENOMEM);
+ }
+ return 0;
+}
+
+av_cold int ff_cavs_init(AVCodecContext *avctx)
+{
+ AVSContext *h = avctx->priv_data;
+
+ ff_blockdsp_init(&h->bdsp, avctx);
+ ff_h264chroma_init(&h->h264chroma, 8);
+ ff_idctdsp_init(&h->idsp, avctx);
+ ff_videodsp_init(&h->vdsp, 8);
+ ff_cavsdsp_init(&h->cdsp, avctx);
+ ff_init_scantable_permutation(h->idsp.idct_permutation,
+ h->cdsp.idct_perm);
+ ff_init_scantable(h->idsp.idct_permutation, &h->scantable, ff_zigzag_direct);
+
+ h->avctx = avctx;
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+ h->cur.f = av_frame_alloc();
+ h->DPB[0].f = av_frame_alloc();
+ h->DPB[1].f = av_frame_alloc();
+ if (!h->cur.f || !h->DPB[0].f || !h->DPB[1].f) {
+ ff_cavs_end(avctx);
+ return AVERROR(ENOMEM);
+ }
+
+ h->luma_scan[0] = 0;
+ h->luma_scan[1] = 8;
+ h->intra_pred_l[INTRA_L_VERT] = intra_pred_vert;
+ h->intra_pred_l[INTRA_L_HORIZ] = intra_pred_horiz;
+ h->intra_pred_l[INTRA_L_LP] = intra_pred_lp;
+ h->intra_pred_l[INTRA_L_DOWN_LEFT] = intra_pred_down_left;
+ h->intra_pred_l[INTRA_L_DOWN_RIGHT] = intra_pred_down_right;
+ h->intra_pred_l[INTRA_L_LP_LEFT] = intra_pred_lp_left;
+ h->intra_pred_l[INTRA_L_LP_TOP] = intra_pred_lp_top;
+ h->intra_pred_l[INTRA_L_DC_128] = intra_pred_dc_128;
+ h->intra_pred_c[INTRA_C_LP] = intra_pred_lp;
+ h->intra_pred_c[INTRA_C_HORIZ] = intra_pred_horiz;
+ h->intra_pred_c[INTRA_C_VERT] = intra_pred_vert;
+ h->intra_pred_c[INTRA_C_PLANE] = intra_pred_plane;
+ h->intra_pred_c[INTRA_C_LP_LEFT] = intra_pred_lp_left;
+ h->intra_pred_c[INTRA_C_LP_TOP] = intra_pred_lp_top;
+ h->intra_pred_c[INTRA_C_DC_128] = intra_pred_dc_128;
+ h->mv[7] = un_mv;
+ h->mv[19] = un_mv;
+ return 0;
+}
+
+av_cold int ff_cavs_end(AVCodecContext *avctx)
+{
+ AVSContext *h = avctx->priv_data;
+
+ av_frame_free(&h->cur.f);
+ av_frame_free(&h->DPB[0].f);
+ av_frame_free(&h->DPB[1].f);
+
+ av_freep(&h->top_qp);
+ av_freep(&h->top_mv[0]);
+ av_freep(&h->top_mv[1]);
+ av_freep(&h->top_pred_Y);
+ av_freep(&h->top_border_y);
+ av_freep(&h->top_border_u);
+ av_freep(&h->top_border_v);
+ av_freep(&h->col_mv);
+ av_freep(&h->col_type_base);
+ av_freep(&h->block);
+ av_freep(&h->edge_emu_buffer);
+ return 0;
+}
diff --git a/ffmpeg-2-8-11/libavcodec/cavs.h b/ffmpeg-2-8-12/libavcodec/cavs.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cavs.h
rename to ffmpeg-2-8-12/libavcodec/cavs.h
diff --git a/ffmpeg-2-8-11/libavcodec/cavs_parser.c b/ffmpeg-2-8-12/libavcodec/cavs_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cavs_parser.c
rename to ffmpeg-2-8-12/libavcodec/cavs_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/cavsdata.c b/ffmpeg-2-8-12/libavcodec/cavsdata.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cavsdata.c
rename to ffmpeg-2-8-12/libavcodec/cavsdata.c
diff --git a/ffmpeg-2-8-12/libavcodec/cavsdec.c b/ffmpeg-2-8-12/libavcodec/cavsdec.c
new file mode 100644
index 0000000..3aec0dd
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/cavsdec.c
@@ -0,0 +1,1273 @@
+/*
+ * Chinese AVS video (AVS1-P2, JiZhun profile) decoder.
+ * Copyright (c) 2006 Stefan Gehrer <stefan.gehrer at gmx.de>
+ *
+ * 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
+ * Chinese AVS video (AVS1-P2, JiZhun profile) decoder
+ * @author Stefan Gehrer <stefan.gehrer at gmx.de>
+ */
+
+#include "libavutil/avassert.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "golomb.h"
+#include "cavs.h"
+#include "internal.h"
+#include "mpeg12data.h"
+#include "mpegvideo.h"
+
+static const uint8_t mv_scan[4] = {
+ MV_FWD_X0, MV_FWD_X1,
+ MV_FWD_X2, MV_FWD_X3
+};
+
+static const uint8_t cbp_tab[64][2] = {
+ { 63, 0 }, { 15, 15 }, { 31, 63 }, { 47, 31 }, { 0, 16 }, { 14, 32 }, { 13, 47 }, { 11, 13 },
+ { 7, 14 }, { 5, 11 }, { 10, 12 }, { 8, 5 }, { 12, 10 }, { 61, 7 }, { 4, 48 }, { 55, 3 },
+ { 1, 2 }, { 2, 8 }, { 59, 4 }, { 3, 1 }, { 62, 61 }, { 9, 55 }, { 6, 59 }, { 29, 62 },
+ { 45, 29 }, { 51, 27 }, { 23, 23 }, { 39, 19 }, { 27, 30 }, { 46, 28 }, { 53, 9 }, { 30, 6 },
+ { 43, 60 }, { 37, 21 }, { 60, 44 }, { 16, 26 }, { 21, 51 }, { 28, 35 }, { 19, 18 }, { 35, 20 },
+ { 42, 24 }, { 26, 53 }, { 44, 17 }, { 32, 37 }, { 58, 39 }, { 24, 45 }, { 20, 58 }, { 17, 43 },
+ { 18, 42 }, { 48, 46 }, { 22, 36 }, { 33, 33 }, { 25, 34 }, { 49, 40 }, { 40, 52 }, { 36, 49 },
+ { 34, 50 }, { 50, 56 }, { 52, 25 }, { 54, 22 }, { 41, 54 }, { 56, 57 }, { 38, 41 }, { 57, 38 }
+};
+
+static const uint8_t scan3x3[4] = { 4, 5, 7, 8 };
+
+static const uint8_t dequant_shift[64] = {
+ 14, 14, 14, 14, 14, 14, 14, 14,
+ 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 12, 12, 12, 12, 12, 12, 12,
+ 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 10, 10, 10, 10, 10, 10, 10,
+ 10, 9, 9, 9, 9, 9, 9, 9,
+ 9, 8, 8, 8, 8, 8, 8, 8,
+ 7, 7, 7, 7, 7, 7, 7, 7
+};
+
+static const uint16_t dequant_mul[64] = {
+ 32768, 36061, 38968, 42495, 46341, 50535, 55437, 60424,
+ 32932, 35734, 38968, 42495, 46177, 50535, 55109, 59933,
+ 65535, 35734, 38968, 42577, 46341, 50617, 55027, 60097,
+ 32809, 35734, 38968, 42454, 46382, 50576, 55109, 60056,
+ 65535, 35734, 38968, 42495, 46320, 50515, 55109, 60076,
+ 65535, 35744, 38968, 42495, 46341, 50535, 55099, 60087,
+ 65535, 35734, 38973, 42500, 46341, 50535, 55109, 60097,
+ 32771, 35734, 38965, 42497, 46341, 50535, 55109, 60099
+};
+
+#define EOB 0, 0, 0
+
+static const struct dec_2dvlc intra_dec[7] = {
+ {
+ { //level / run / table_inc
+ { 1, 1, 1 }, { -1, 1, 1 }, { 1, 2, 1 }, { -1, 2, 1 }, { 1, 3, 1 }, { -1, 3, 1 },
+ { 1, 4, 1 }, { -1, 4, 1 }, { 1, 5, 1 }, { -1, 5, 1 }, { 1, 6, 1 }, { -1, 6, 1 },
+ { 1, 7, 1 }, { -1, 7, 1 }, { 1, 8, 1 }, { -1, 8, 1 }, { 1, 9, 1 }, { -1, 9, 1 },
+ { 1, 10, 1 }, { -1, 10, 1 }, { 1, 11, 1 }, { -1, 11, 1 }, { 2, 1, 2 }, { -2, 1, 2 },
+ { 1, 12, 1 }, { -1, 12, 1 }, { 1, 13, 1 }, { -1, 13, 1 }, { 1, 14, 1 }, { -1, 14, 1 },
+ { 1, 15, 1 }, { -1, 15, 1 }, { 2, 2, 2 }, { -2, 2, 2 }, { 1, 16, 1 }, { -1, 16, 1 },
+ { 1, 17, 1 }, { -1, 17, 1 }, { 3, 1, 3 }, { -3, 1, 3 }, { 1, 18, 1 }, { -1, 18, 1 },
+ { 1, 19, 1 }, { -1, 19, 1 }, { 2, 3, 2 }, { -2, 3, 2 }, { 1, 20, 1 }, { -1, 20, 1 },
+ { 1, 21, 1 }, { -1, 21, 1 }, { 2, 4, 2 }, { -2, 4, 2 }, { 1, 22, 1 }, { -1, 22, 1 },
+ { 2, 5, 2 }, { -2, 5, 2 }, { 1, 23, 1 }, { -1, 23, 1 }, { EOB }
+ },
+ //level_add
+ { 0, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1 },
+ 2, //golomb_order
+ 0, //inc_limit
+ 23, //max_run
+ },
+ {
+ { //level / run
+ { 1, 1, 0 }, { -1, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 2, 1, 1 }, { -2, 1, 1 },
+ { 1, 3, 0 }, { -1, 3, 0 }, { EOB }, { 1, 4, 0 }, { -1, 4, 0 }, { 1, 5, 0 },
+ { -1, 5, 0 }, { 1, 6, 0 }, { -1, 6, 0 }, { 3, 1, 2 }, { -3, 1, 2 }, { 2, 2, 1 },
+ { -2, 2, 1 }, { 1, 7, 0 }, { -1, 7, 0 }, { 1, 8, 0 }, { -1, 8, 0 }, { 1, 9, 0 },
+ { -1, 9, 0 }, { 2, 3, 1 }, { -2, 3, 1 }, { 4, 1, 2 }, { -4, 1, 2 }, { 1, 10, 0 },
+ { -1, 10, 0 }, { 1, 11, 0 }, { -1, 11, 0 }, { 2, 4, 1 }, { -2, 4, 1 }, { 3, 2, 2 },
+ { -3, 2, 2 }, { 1, 12, 0 }, { -1, 12, 0 }, { 2, 5, 1 }, { -2, 5, 1 }, { 5, 1, 3 },
+ { -5, 1, 3 }, { 1, 13, 0 }, { -1, 13, 0 }, { 2, 6, 1 }, { -2, 6, 1 }, { 1, 14, 0 },
+ { -1, 14, 0 }, { 2, 7, 1 }, { -2, 7, 1 }, { 2, 8, 1 }, { -2, 8, 1 }, { 3, 3, 2 },
+ { -3, 3, 2 }, { 6, 1, 3 }, { -6, 1, 3 }, { 1, 15, 0 }, { -1, 15, 0 }
+ },
+ //level_add
+ { 0, 7, 4, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ 2, //golomb_order
+ 1, //inc_limit
+ 15, //max_run
+ },
+ {
+ { //level / run
+ { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 },
+ { 3, 1, 1 }, { -3, 1, 1 }, { EOB }, { 1, 3, 0 }, { -1, 3, 0 }, { 2, 2, 0 },
+ { -2, 2, 0 }, { 4, 1, 1 }, { -4, 1, 1 }, { 1, 4, 0 }, { -1, 4, 0 }, { 5, 1, 2 },
+ { -5, 1, 2 }, { 1, 5, 0 }, { -1, 5, 0 }, { 3, 2, 1 }, { -3, 2, 1 }, { 2, 3, 0 },
+ { -2, 3, 0 }, { 1, 6, 0 }, { -1, 6, 0 }, { 6, 1, 2 }, { -6, 1, 2 }, { 2, 4, 0 },
+ { -2, 4, 0 }, { 1, 7, 0 }, { -1, 7, 0 }, { 4, 2, 1 }, { -4, 2, 1 }, { 7, 1, 2 },
+ { -7, 1, 2 }, { 3, 3, 1 }, { -3, 3, 1 }, { 2, 5, 0 }, { -2, 5, 0 }, { 1, 8, 0 },
+ { -1, 8, 0 }, { 2, 6, 0 }, { -2, 6, 0 }, { 8, 1, 3 }, { -8, 1, 3 }, { 1, 9, 0 },
+ { -1, 9, 0 }, { 5, 2, 2 }, { -5, 2, 2 }, { 3, 4, 1 }, { -3, 4, 1 }, { 2, 7, 0 },
+ { -2, 7, 0 }, { 9, 1, 3 }, { -9, 1, 3 }, { 1, 10, 0 }, { -1, 10, 0 }
+ },
+ //level_add
+ { 0, 10, 6, 4, 4, 3, 3, 3, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ 2, //golomb_order
+ 2, //inc_limit
+ 10, //max_run
+ },
+ {
+ { //level / run
+ { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 }, { -3, 1, 0 },
+ { 1, 2, 0 }, { -1, 2, 0 }, { EOB }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 1 },
+ { -5, 1, 1 }, { 2, 2, 0 }, { -2, 2, 0 }, { 1, 3, 0 }, { -1, 3, 0 }, { 6, 1, 1 },
+ { -6, 1, 1 }, { 3, 2, 0 }, { -3, 2, 0 }, { 7, 1, 1 }, { -7, 1, 1 }, { 1, 4, 0 },
+ { -1, 4, 0 }, { 8, 1, 2 }, { -8, 1, 2 }, { 2, 3, 0 }, { -2, 3, 0 }, { 4, 2, 0 },
+ { -4, 2, 0 }, { 1, 5, 0 }, { -1, 5, 0 }, { 9, 1, 2 }, { -9, 1, 2 }, { 5, 2, 1 },
+ { -5, 2, 1 }, { 2, 4, 0 }, { -2, 4, 0 }, { 10, 1, 2 }, {-10, 1, 2 }, { 3, 3, 0 },
+ { -3, 3, 0 }, { 1, 6, 0 }, { -1, 6, 0 }, { 11, 1, 3 }, {-11, 1, 3 }, { 6, 2, 1 },
+ { -6, 2, 1 }, { 1, 7, 0 }, { -1, 7, 0 }, { 2, 5, 0 }, { -2, 5, 0 }, { 3, 4, 0 },
+ { -3, 4, 0 }, { 12, 1, 3 }, {-12, 1, 3 }, { 4, 3, 0 }, { -4, 3, 0 }
+ },
+ //level_add
+ { 0, 13, 7, 5, 4, 3, 2, 2, -1, -1, -1 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ 2, //golomb_order
+ 4, //inc_limit
+ 7, //max_run
+ },
+ {
+ { //level / run
+ { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 }, { -3, 1, 0 },
+ { EOB }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 0 }, { -5, 1, 0 }, { 6, 1, 0 },
+ { -6, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 7, 1, 0 }, { -7, 1, 0 }, { 8, 1, 1 },
+ { -8, 1, 1 }, { 2, 2, 0 }, { -2, 2, 0 }, { 9, 1, 1 }, { -9, 1, 1 }, { 10, 1, 1 },
+ {-10, 1, 1 }, { 1, 3, 0 }, { -1, 3, 0 }, { 3, 2, 0 }, { -3, 2, 0 }, { 11, 1, 2 },
+ {-11, 1, 2 }, { 4, 2, 0 }, { -4, 2, 0 }, { 12, 1, 2 }, {-12, 1, 2 }, { 13, 1, 2 },
+ {-13, 1, 2 }, { 5, 2, 0 }, { -5, 2, 0 }, { 1, 4, 0 }, { -1, 4, 0 }, { 2, 3, 0 },
+ { -2, 3, 0 }, { 14, 1, 2 }, {-14, 1, 2 }, { 6, 2, 0 }, { -6, 2, 0 }, { 15, 1, 2 },
+ {-15, 1, 2 }, { 16, 1, 2 }, {-16, 1, 2 }, { 3, 3, 0 }, { -3, 3, 0 }, { 1, 5, 0 },
+ { -1, 5, 0 }, { 7, 2, 0 }, { -7, 2, 0 }, { 17, 1, 2 }, {-17, 1, 2 }
+ },
+ //level_add
+ { 0,18, 8, 4, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ 2, //golomb_order
+ 7, //inc_limit
+ 5, //max_run
+ },
+ {
+ { //level / run
+ { EOB }, { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 },
+ { -3, 1, 0 }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 0 }, { -5, 1, 0 }, { 6, 1, 0 },
+ { -6, 1, 0 }, { 7, 1, 0 }, { -7, 1, 0 }, { 8, 1, 0 }, { -8, 1, 0 }, { 9, 1, 0 },
+ { -9, 1, 0 }, { 10, 1, 0 }, {-10, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 11, 1, 1 },
+ {-11, 1, 1 }, { 12, 1, 1 }, {-12, 1, 1 }, { 13, 1, 1 }, {-13, 1, 1 }, { 2, 2, 0 },
+ { -2, 2, 0 }, { 14, 1, 1 }, {-14, 1, 1 }, { 15, 1, 1 }, {-15, 1, 1 }, { 3, 2, 0 },
+ { -3, 2, 0 }, { 16, 1, 1 }, {-16, 1, 1 }, { 1, 3, 0 }, { -1, 3, 0 }, { 17, 1, 1 },
+ {-17, 1, 1 }, { 4, 2, 0 }, { -4, 2, 0 }, { 18, 1, 1 }, {-18, 1, 1 }, { 5, 2, 0 },
+ { -5, 2, 0 }, { 19, 1, 1 }, {-19, 1, 1 }, { 20, 1, 1 }, {-20, 1, 1 }, { 6, 2, 0 },
+ { -6, 2, 0 }, { 21, 1, 1 }, {-21, 1, 1 }, { 2, 3, 0 }, { -2, 3, 0 }
+ },
+ //level_add
+ { 0, 22, 7, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ 2, //golomb_order
+ 10, //inc_limit
+ 3, //max_run
+ },
+ {
+ { //level / run
+ { EOB }, { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 },
+ { -3, 1, 0 }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 0 }, { -5, 1, 0 }, { 6, 1, 0 },
+ { -6, 1, 0 }, { 7, 1, 0 }, { -7, 1, 0 }, { 8, 1, 0 }, { -8, 1, 0 }, { 9, 1, 0 },
+ { -9, 1, 0 }, { 10, 1, 0 }, {-10, 1, 0 }, { 11, 1, 0 }, {-11, 1, 0 }, { 12, 1, 0 },
+ {-12, 1, 0 }, { 13, 1, 0 }, {-13, 1, 0 }, { 14, 1, 0 }, {-14, 1, 0 }, { 15, 1, 0 },
+ {-15, 1, 0 }, { 16, 1, 0 }, {-16, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 17, 1, 0 },
+ {-17, 1, 0 }, { 18, 1, 0 }, {-18, 1, 0 }, { 19, 1, 0 }, {-19, 1, 0 }, { 20, 1, 0 },
+ {-20, 1, 0 }, { 21, 1, 0 }, {-21, 1, 0 }, { 2, 2, 0 }, { -2, 2, 0 }, { 22, 1, 0 },
+ {-22, 1, 0 }, { 23, 1, 0 }, {-23, 1, 0 }, { 24, 1, 0 }, {-24, 1, 0 }, { 25, 1, 0 },
+ {-25, 1, 0 }, { 3, 2, 0 }, { -3, 2, 0 }, { 26, 1, 0 }, {-26, 1, 0 }
+ },
+ //level_add
+ { 0, 27, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ 2, //golomb_order
+ INT_MAX, //inc_limit
+ 2, //max_run
+ }
+};
+
+static const struct dec_2dvlc inter_dec[7] = {
+ {
+ { //level / run
+ { 1, 1, 1 }, { -1, 1, 1 }, { 1, 2, 1 }, { -1, 2, 1 }, { 1, 3, 1 }, { -1, 3, 1 },
+ { 1, 4, 1 }, { -1, 4, 1 }, { 1, 5, 1 }, { -1, 5, 1 }, { 1, 6, 1 }, { -1, 6, 1 },
+ { 1, 7, 1 }, { -1, 7, 1 }, { 1, 8, 1 }, { -1, 8, 1 }, { 1, 9, 1 }, { -1, 9, 1 },
+ { 1, 10, 1 }, { -1, 10, 1 }, { 1, 11, 1 }, { -1, 11, 1 }, { 1, 12, 1 }, { -1, 12, 1 },
+ { 1, 13, 1 }, { -1, 13, 1 }, { 2, 1, 2 }, { -2, 1, 2 }, { 1, 14, 1 }, { -1, 14, 1 },
+ { 1, 15, 1 }, { -1, 15, 1 }, { 1, 16, 1 }, { -1, 16, 1 }, { 1, 17, 1 }, { -1, 17, 1 },
+ { 1, 18, 1 }, { -1, 18, 1 }, { 1, 19, 1 }, { -1, 19, 1 }, { 3, 1, 3 }, { -3, 1, 3 },
+ { 1, 20, 1 }, { -1, 20, 1 }, { 1, 21, 1 }, { -1, 21, 1 }, { 2, 2, 2 }, { -2, 2, 2 },
+ { 1, 22, 1 }, { -1, 22, 1 }, { 1, 23, 1 }, { -1, 23, 1 }, { 1, 24, 1 }, { -1, 24, 1 },
+ { 1, 25, 1 }, { -1, 25, 1 }, { 1, 26, 1 }, { -1, 26, 1 }, { EOB }
+ },
+ //level_add
+ { 0, 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
+ 3, //golomb_order
+ 0, //inc_limit
+ 26 //max_run
+ },
+ {
+ { //level / run
+ { 1, 1, 0 }, { -1, 1, 0 }, { EOB }, { 1, 2, 0 }, { -1, 2, 0 }, { 1, 3, 0 },
+ { -1, 3, 0 }, { 1, 4, 0 }, { -1, 4, 0 }, { 1, 5, 0 }, { -1, 5, 0 }, { 1, 6, 0 },
+ { -1, 6, 0 }, { 2, 1, 1 }, { -2, 1, 1 }, { 1, 7, 0 }, { -1, 7, 0 }, { 1, 8, 0 },
+ { -1, 8, 0 }, { 1, 9, 0 }, { -1, 9, 0 }, { 1, 10, 0 }, { -1, 10, 0 }, { 2, 2, 1 },
+ { -2, 2, 1 }, { 1, 11, 0 }, { -1, 11, 0 }, { 1, 12, 0 }, { -1, 12, 0 }, { 3, 1, 2 },
+ { -3, 1, 2 }, { 1, 13, 0 }, { -1, 13, 0 }, { 1, 14, 0 }, { -1, 14, 0 }, { 2, 3, 1 },
+ { -2, 3, 1 }, { 1, 15, 0 }, { -1, 15, 0 }, { 2, 4, 1 }, { -2, 4, 1 }, { 1, 16, 0 },
+ { -1, 16, 0 }, { 2, 5, 1 }, { -2, 5, 1 }, { 1, 17, 0 }, { -1, 17, 0 }, { 4, 1, 3 },
+ { -4, 1, 3 }, { 2, 6, 1 }, { -2, 6, 1 }, { 1, 18, 0 }, { -1, 18, 0 }, { 1, 19, 0 },
+ { -1, 19, 0 }, { 2, 7, 1 }, { -2, 7, 1 }, { 3, 2, 2 }, { -3, 2, 2 }
+ },
+ //level_add
+ { 0, 5, 4, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1 },
+ 2, //golomb_order
+ 1, //inc_limit
+ 19 //max_run
+ },
+ {
+ { //level / run
+ { 1, 1, 0 }, { -1, 1, 0 }, { EOB }, { 1, 2, 0 }, { -1, 2, 0 }, { 2, 1, 0 },
+ { -2, 1, 0 }, { 1, 3, 0 }, { -1, 3, 0 }, { 1, 4, 0 }, { -1, 4, 0 }, { 3, 1, 1 },
+ { -3, 1, 1 }, { 2, 2, 0 }, { -2, 2, 0 }, { 1, 5, 0 }, { -1, 5, 0 }, { 1, 6, 0 },
+ { -1, 6, 0 }, { 1, 7, 0 }, { -1, 7, 0 }, { 2, 3, 0 }, { -2, 3, 0 }, { 4, 1, 2 },
+ { -4, 1, 2 }, { 1, 8, 0 }, { -1, 8, 0 }, { 3, 2, 1 }, { -3, 2, 1 }, { 2, 4, 0 },
+ { -2, 4, 0 }, { 1, 9, 0 }, { -1, 9, 0 }, { 1, 10, 0 }, { -1, 10, 0 }, { 5, 1, 2 },
+ { -5, 1, 2 }, { 2, 5, 0 }, { -2, 5, 0 }, { 1, 11, 0 }, { -1, 11, 0 }, { 2, 6, 0 },
+ { -2, 6, 0 }, { 1, 12, 0 }, { -1, 12, 0 }, { 3, 3, 1 }, { -3, 3, 1 }, { 6, 1, 2 },
+ { -6, 1, 2 }, { 4, 2, 2 }, { -4, 2, 2 }, { 1, 13, 0 }, { -1, 13, 0 }, { 2, 7, 0 },
+ { -2, 7, 0 }, { 3, 4, 1 }, { -3, 4, 1 }, { 1, 14, 0 }, { -1, 14, 0 }
+ },
+ //level_add
+ { 0, 7, 5, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ 2, //golomb_order
+ 2, //inc_limit
+ 14 //max_run
+ },
+ {
+ { //level / run
+ { 1, 1, 0 }, { -1, 1, 0 }, { EOB }, { 2, 1, 0 }, { -2, 1, 0 }, { 1, 2, 0 },
+ { -1, 2, 0 }, { 3, 1, 0 }, { -3, 1, 0 }, { 1, 3, 0 }, { -1, 3, 0 }, { 2, 2, 0 },
+ { -2, 2, 0 }, { 4, 1, 1 }, { -4, 1, 1 }, { 1, 4, 0 }, { -1, 4, 0 }, { 5, 1, 1 },
+ { -5, 1, 1 }, { 1, 5, 0 }, { -1, 5, 0 }, { 3, 2, 0 }, { -3, 2, 0 }, { 2, 3, 0 },
+ { -2, 3, 0 }, { 1, 6, 0 }, { -1, 6, 0 }, { 6, 1, 1 }, { -6, 1, 1 }, { 2, 4, 0 },
+ { -2, 4, 0 }, { 1, 7, 0 }, { -1, 7, 0 }, { 4, 2, 1 }, { -4, 2, 1 }, { 7, 1, 2 },
+ { -7, 1, 2 }, { 3, 3, 0 }, { -3, 3, 0 }, { 1, 8, 0 }, { -1, 8, 0 }, { 2, 5, 0 },
+ { -2, 5, 0 }, { 8, 1, 2 }, { -8, 1, 2 }, { 1, 9, 0 }, { -1, 9, 0 }, { 3, 4, 0 },
+ { -3, 4, 0 }, { 2, 6, 0 }, { -2, 6, 0 }, { 5, 2, 1 }, { -5, 2, 1 }, { 1, 10, 0 },
+ { -1, 10, 0 }, { 9, 1, 2 }, { -9, 1, 2 }, { 4, 3, 1 }, { -4, 3, 1 }
+ },
+ //level_add
+ { 0,10, 6, 5, 4, 3, 3, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ 2, //golomb_order
+ 3, //inc_limit
+ 10 //max_run
+ },
+ {
+ { //level / run
+ { 1, 1, 0 }, { -1, 1, 0 }, { EOB }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 },
+ { -3, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 0 },
+ { -5, 1, 0 }, { 2, 2, 0 }, { -2, 2, 0 }, { 1, 3, 0 }, { -1, 3, 0 }, { 6, 1, 0 },
+ { -6, 1, 0 }, { 3, 2, 0 }, { -3, 2, 0 }, { 7, 1, 1 }, { -7, 1, 1 }, { 1, 4, 0 },
+ { -1, 4, 0 }, { 8, 1, 1 }, { -8, 1, 1 }, { 2, 3, 0 }, { -2, 3, 0 }, { 4, 2, 0 },
+ { -4, 2, 0 }, { 1, 5, 0 }, { -1, 5, 0 }, { 9, 1, 1 }, { -9, 1, 1 }, { 5, 2, 0 },
+ { -5, 2, 0 }, { 2, 4, 0 }, { -2, 4, 0 }, { 1, 6, 0 }, { -1, 6, 0 }, { 10, 1, 2 },
+ {-10, 1, 2 }, { 3, 3, 0 }, { -3, 3, 0 }, { 11, 1, 2 }, {-11, 1, 2 }, { 1, 7, 0 },
+ { -1, 7, 0 }, { 6, 2, 0 }, { -6, 2, 0 }, { 3, 4, 0 }, { -3, 4, 0 }, { 2, 5, 0 },
+ { -2, 5, 0 }, { 12, 1, 2 }, {-12, 1, 2 }, { 4, 3, 0 }, { -4, 3, 0 }
+ },
+ //level_add
+ { 0, 13, 7, 5, 4, 3, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ 2, //golomb_order
+ 6, //inc_limit
+ 7 //max_run
+ },
+ {
+ { //level / run
+ { EOB }, { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 },
+ { -3, 1, 0 }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 0 }, { -5, 1, 0 }, { 1, 2, 0 },
+ { -1, 2, 0 }, { 6, 1, 0 }, { -6, 1, 0 }, { 7, 1, 0 }, { -7, 1, 0 }, { 8, 1, 0 },
+ { -8, 1, 0 }, { 2, 2, 0 }, { -2, 2, 0 }, { 9, 1, 0 }, { -9, 1, 0 }, { 1, 3, 0 },
+ { -1, 3, 0 }, { 10, 1, 1 }, { -10, 1, 1 }, { 3, 2, 0 }, { -3, 2, 0 }, { 11, 1, 1 },
+ { -11, 1, 1 }, { 4, 2, 0 }, { -4, 2, 0 }, { 12, 1, 1 }, { -12, 1, 1 }, { 1, 4, 0 },
+ { -1, 4, 0 }, { 2, 3, 0 }, { -2, 3, 0 }, { 13, 1, 1 }, { -13, 1, 1 }, { 5, 2, 0 },
+ { -5, 2, 0 }, { 14, 1, 1 }, { -14, 1, 1 }, { 6, 2, 0 }, { -6, 2, 0 }, { 1, 5, 0 },
+ { -1, 5, 0 }, { 15, 1, 1 }, { -15, 1, 1 }, { 3, 3, 0 }, { -3, 3, 0 }, { 16, 1, 1 },
+ { -16, 1, 1 }, { 2, 4, 0 }, { -2, 4, 0 }, { 7, 2, 0 }, { -7, 2, 0 }
+ },
+ //level_add
+ { 0, 17, 8, 4, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ 2, //golomb_order
+ 9, //inc_limit
+ 5 //max_run
+ },
+ {
+ { //level / run
+ { EOB }, { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 },
+ { -3, 1, 0 }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 0 }, { -5, 1, 0 }, { 6, 1, 0 },
+ { -6, 1, 0 }, { 7, 1, 0 }, { -7, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 8, 1, 0 },
+ { -8, 1, 0 }, { 9, 1, 0 }, { -9, 1, 0 }, { 10, 1, 0 }, { -10, 1, 0 }, { 11, 1, 0 },
+ { -11, 1, 0 }, { 12, 1, 0 }, { -12, 1, 0 }, { 2, 2, 0 }, { -2, 2, 0 }, { 13, 1, 0 },
+ { -13, 1, 0 }, { 1, 3, 0 }, { -1, 3, 0 }, { 14, 1, 0 }, { -14, 1, 0 }, { 15, 1, 0 },
+ { -15, 1, 0 }, { 3, 2, 0 }, { -3, 2, 0 }, { 16, 1, 0 }, { -16, 1, 0 }, { 17, 1, 0 },
+ { -17, 1, 0 }, { 18, 1, 0 }, { -18, 1, 0 }, { 4, 2, 0 }, { -4, 2, 0 }, { 19, 1, 0 },
+ { -19, 1, 0 }, { 20, 1, 0 }, { -20, 1, 0 }, { 2, 3, 0 }, { -2, 3, 0 }, { 1, 4, 0 },
+ { -1, 4, 0 }, { 5, 2, 0 }, { -5, 2, 0 }, { 21, 1, 0 }, { -21, 1, 0 }
+ },
+ //level_add
+ { 0, 22, 6, 3, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ 2, //golomb_order
+ INT_MAX, //inc_limit
+ 4 //max_run
+ }
+};
+
+static const struct dec_2dvlc chroma_dec[5] = {
+ {
+ { //level / run
+ { 1, 1, 1 }, { -1, 1, 1 }, { 1, 2, 1 }, { -1, 2, 1 }, { 1, 3, 1 }, { -1, 3, 1 },
+ { 1, 4, 1 }, { -1, 4, 1 }, { 1, 5, 1 }, { -1, 5, 1 }, { 1, 6, 1 }, { -1, 6, 1 },
+ { 1, 7, 1 }, { -1, 7, 1 }, { 2, 1, 2 }, { -2, 1, 2 }, { 1, 8, 1 }, { -1, 8, 1 },
+ { 1, 9, 1 }, { -1, 9, 1 }, { 1, 10, 1 }, { -1, 10, 1 }, { 1, 11, 1 }, { -1, 11, 1 },
+ { 1, 12, 1 }, { -1, 12, 1 }, { 1, 13, 1 }, { -1, 13, 1 }, { 1, 14, 1 }, { -1, 14, 1 },
+ { 1, 15, 1 }, { -1, 15, 1 }, { 3, 1, 3 }, { -3, 1, 3 }, { 1, 16, 1 }, { -1, 16, 1 },
+ { 1, 17, 1 }, { -1, 17, 1 }, { 1, 18, 1 }, { -1, 18, 1 }, { 1, 19, 1 }, { -1, 19, 1 },
+ { 1, 20, 1 }, { -1, 20, 1 }, { 1, 21, 1 }, { -1, 21, 1 }, { 1, 22, 1 }, { -1, 22, 1 },
+ { 2, 2, 2 }, { -2, 2, 2 }, { 1, 23, 1 }, { -1, 23, 1 }, { 1, 24, 1 }, { -1, 24, 1 },
+ { 1, 25, 1 }, { -1, 25, 1 }, { 4, 1, 3 }, { -4, 1, 3 }, { EOB }
+ },
+ //level_add
+ { 0, 5, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1 },
+ 2, //golomb_order
+ 0, //inc_limit
+ 25 //max_run
+ },
+ {
+ { //level / run
+ { EOB }, { 1, 1, 0 }, { -1, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 2, 1, 1 },
+ { -2, 1, 1 }, { 1, 3, 0 }, { -1, 3, 0 }, { 1, 4, 0 }, { -1, 4, 0 }, { 1, 5, 0 },
+ { -1, 5, 0 }, { 1, 6, 0 }, { -1, 6, 0 }, { 3, 1, 2 }, { -3, 1, 2 }, { 1, 7, 0 },
+ { -1, 7, 0 }, { 1, 8, 0 }, { -1, 8, 0 }, { 2, 2, 1 }, { -2, 2, 1 }, { 1, 9, 0 },
+ { -1, 9, 0 }, { 1, 10, 0 }, { -1, 10, 0 }, { 1, 11, 0 }, { -1, 11, 0 }, { 4, 1, 2 },
+ { -4, 1, 2 }, { 1, 12, 0 }, { -1, 12, 0 }, { 1, 13, 0 }, { -1, 13, 0 }, { 1, 14, 0 },
+ { -1, 14, 0 }, { 2, 3, 1 }, { -2, 3, 1 }, { 1, 15, 0 }, { -1, 15, 0 }, { 2, 4, 1 },
+ { -2, 4, 1 }, { 5, 1, 3 }, { -5, 1, 3 }, { 3, 2, 2 }, { -3, 2, 2 }, { 1, 16, 0 },
+ { -1, 16, 0 }, { 1, 17, 0 }, { -1, 17, 0 }, { 1, 18, 0 }, { -1, 18, 0 }, { 2, 5, 1 },
+ { -2, 5, 1 }, { 1, 19, 0 }, { -1, 19, 0 }, { 1, 20, 0 }, { -1, 20, 0 }
+ },
+ //level_add
+ { 0, 6, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1 },
+ 0, //golomb_order
+ 1, //inc_limit
+ 20 //max_run
+ },
+ {
+ { //level / run
+ { 1, 1, 0 }, { -1, 1, 0 }, { EOB }, { 2, 1, 0 }, { -2, 1, 0 }, { 1, 2, 0 },
+ { -1, 2, 0 }, { 3, 1, 1 }, { -3, 1, 1 }, { 1, 3, 0 }, { -1, 3, 0 }, { 4, 1, 1 },
+ { -4, 1, 1 }, { 2, 2, 0 }, { -2, 2, 0 }, { 1, 4, 0 }, { -1, 4, 0 }, { 5, 1, 2 },
+ { -5, 1, 2 }, { 1, 5, 0 }, { -1, 5, 0 }, { 3, 2, 1 }, { -3, 2, 1 }, { 2, 3, 0 },
+ { -2, 3, 0 }, { 1, 6, 0 }, { -1, 6, 0 }, { 6, 1, 2 }, { -6, 1, 2 }, { 1, 7, 0 },
+ { -1, 7, 0 }, { 2, 4, 0 }, { -2, 4, 0 }, { 7, 1, 2 }, { -7, 1, 2 }, { 1, 8, 0 },
+ { -1, 8, 0 }, { 4, 2, 1 }, { -4, 2, 1 }, { 1, 9, 0 }, { -1, 9, 0 }, { 3, 3, 1 },
+ { -3, 3, 1 }, { 2, 5, 0 }, { -2, 5, 0 }, { 2, 6, 0 }, { -2, 6, 0 }, { 8, 1, 2 },
+ { -8, 1, 2 }, { 1, 10, 0 }, { -1, 10, 0 }, { 1, 11, 0 }, { -1, 11, 0 }, { 9, 1, 2 },
+ { -9, 1, 2 }, { 5, 2, 2 }, { -5, 2, 2 }, { 3, 4, 1 }, { -3, 4, 1 },
+ },
+ //level_add
+ { 0,10, 6, 4, 4, 3, 3, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ 1, //golomb_order
+ 2, //inc_limit
+ 11 //max_run
+ },
+ {
+ { //level / run
+ { EOB }, { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 },
+ { -3, 1, 0 }, { 4, 1, 0 }, { -4, 1, 0 }, { 1, 2, 0 }, { -1, 2, 0 }, { 5, 1, 1 },
+ { -5, 1, 1 }, { 2, 2, 0 }, { -2, 2, 0 }, { 6, 1, 1 }, { -6, 1, 1 }, { 1, 3, 0 },
+ { -1, 3, 0 }, { 7, 1, 1 }, { -7, 1, 1 }, { 3, 2, 0 }, { -3, 2, 0 }, { 8, 1, 1 },
+ { -8, 1, 1 }, { 1, 4, 0 }, { -1, 4, 0 }, { 2, 3, 0 }, { -2, 3, 0 }, { 9, 1, 1 },
+ { -9, 1, 1 }, { 4, 2, 0 }, { -4, 2, 0 }, { 1, 5, 0 }, { -1, 5, 0 }, { 10, 1, 1 },
+ {-10, 1, 1 }, { 3, 3, 0 }, { -3, 3, 0 }, { 5, 2, 1 }, { -5, 2, 1 }, { 2, 4, 0 },
+ { -2, 4, 0 }, { 11, 1, 1 }, {-11, 1, 1 }, { 1, 6, 0 }, { -1, 6, 0 }, { 12, 1, 1 },
+ {-12, 1, 1 }, { 1, 7, 0 }, { -1, 7, 0 }, { 6, 2, 1 }, { -6, 2, 1 }, { 13, 1, 1 },
+ {-13, 1, 1 }, { 2, 5, 0 }, { -2, 5, 0 }, { 1, 8, 0 }, { -1, 8, 0 },
+ },
+ //level_add
+ { 0, 14, 7, 4, 3, 3, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 },
+ 1, //golomb_order
+ 4, //inc_limit
+ 8 //max_run
+ },
+ {
+ { //level / run
+ { EOB }, { 1, 1, 0 }, { -1, 1, 0 }, { 2, 1, 0 }, { -2, 1, 0 }, { 3, 1, 0 },
+ { -3, 1, 0 }, { 4, 1, 0 }, { -4, 1, 0 }, { 5, 1, 0 }, { -5, 1, 0 }, { 6, 1, 0 },
+ { -6, 1, 0 }, { 7, 1, 0 }, { -7, 1, 0 }, { 8, 1, 0 }, { -8, 1, 0 }, { 1, 2, 0 },
+ { -1, 2, 0 }, { 9, 1, 0 }, { -9, 1, 0 }, { 10, 1, 0 }, { -10, 1, 0 }, { 11, 1, 0 },
+ { -11, 1, 0 }, { 2, 2, 0 }, { -2, 2, 0 }, { 12, 1, 0 }, { -12, 1, 0 }, { 13, 1, 0 },
+ { -13, 1, 0 }, { 3, 2, 0 }, { -3, 2, 0 }, { 14, 1, 0 }, { -14, 1, 0 }, { 1, 3, 0 },
+ { -1, 3, 0 }, { 15, 1, 0 }, { -15, 1, 0 }, { 4, 2, 0 }, { -4, 2, 0 }, { 16, 1, 0 },
+ { -16, 1, 0 }, { 17, 1, 0 }, { -17, 1, 0 }, { 5, 2, 0 }, { -5, 2, 0 }, { 1, 4, 0 },
+ { -1, 4, 0 }, { 2, 3, 0 }, { -2, 3, 0 }, { 18, 1, 0 }, { -18, 1, 0 }, { 6, 2, 0 },
+ { -6, 2, 0 }, { 19, 1, 0 }, { -19, 1, 0 }, { 1, 5, 0 }, { -1, 5, 0 },
+ },
+ //level_add
+ { 0, 20, 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 },
+ 0, //golomb_order
+ INT_MAX, //inc_limit
+ 5, //max_run
+ }
+};
+
+#undef EOB
+
+/*****************************************************************************
+ *
+ * motion vector prediction
+ *
+ ****************************************************************************/
+
+static inline void store_mvs(AVSContext *h)
+{
+ h->col_mv[h->mbidx * 4 + 0] = h->mv[MV_FWD_X0];
+ h->col_mv[h->mbidx * 4 + 1] = h->mv[MV_FWD_X1];
+ h->col_mv[h->mbidx * 4 + 2] = h->mv[MV_FWD_X2];
+ h->col_mv[h->mbidx * 4 + 3] = h->mv[MV_FWD_X3];
+}
+
+static inline void mv_pred_direct(AVSContext *h, cavs_vector *pmv_fw,
+ cavs_vector *col_mv)
+{
+ cavs_vector *pmv_bw = pmv_fw + MV_BWD_OFFS;
+ unsigned den = h->direct_den[col_mv->ref];
+ int m = FF_SIGNBIT(col_mv->x);
+
+ pmv_fw->dist = h->dist[1];
+ pmv_bw->dist = h->dist[0];
+ pmv_fw->ref = 1;
+ pmv_bw->ref = 0;
+ /* scale the co-located motion vector according to its temporal span */
+ pmv_fw->x = (((den + (den * col_mv->x * pmv_fw->dist ^ m) - m - 1) >> 14) ^ m) - m;
+ pmv_bw->x = m - (((den + (den * col_mv->x * pmv_bw->dist ^ m) - m - 1) >> 14) ^ m);
+ m = FF_SIGNBIT(col_mv->y);
+ pmv_fw->y = (((den + (den * col_mv->y * pmv_fw->dist ^ m) - m - 1) >> 14) ^ m) - m;
+ pmv_bw->y = m - (((den + (den * col_mv->y * pmv_bw->dist ^ m) - m - 1) >> 14) ^ m);
+}
+
+static inline void mv_pred_sym(AVSContext *h, cavs_vector *src,
+ enum cavs_block size)
+{
+ cavs_vector *dst = src + MV_BWD_OFFS;
+
+ /* backward mv is the scaled and negated forward mv */
+ dst->x = -((src->x * h->sym_factor + 256) >> 9);
+ dst->y = -((src->y * h->sym_factor + 256) >> 9);
+ dst->ref = 0;
+ dst->dist = h->dist[0];
+ set_mvs(dst, size);
+}
+
+/*****************************************************************************
+ *
+ * residual data decoding
+ *
+ ****************************************************************************/
+
+/** kth-order exponential golomb code */
+static inline int get_ue_code(GetBitContext *gb, int order)
+{
+ unsigned ret = get_ue_golomb(gb);
+ if (ret >= ((1U<<31)>>order)) {
+ av_log(NULL, AV_LOG_ERROR, "get_ue_code: value too larger\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (order) {
+ return (ret<<order) + get_bits(gb, order);
+ }
+ return ret;
+}
+
+static inline int dequant(AVSContext *h, int16_t *level_buf, uint8_t *run_buf,
+ int16_t *dst, int mul, int shift, int coeff_num)
+{
+ int round = 1 << (shift - 1);
+ int pos = -1;
+ const uint8_t *scantab = h->scantable.permutated;
+
+ /* inverse scan and dequantization */
+ while (--coeff_num >= 0) {
+ pos += run_buf[coeff_num];
+ if (pos > 63) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "position out of block bounds at pic %d MB(%d,%d)\n",
+ h->cur.poc, h->mbx, h->mby);
+ return AVERROR_INVALIDDATA;
+ }
+ dst[scantab[pos]] = (level_buf[coeff_num] * mul + round) >> shift;
+ }
+ return 0;
+}
+
+/**
+ * decode coefficients from one 8x8 block, dequantize, inverse transform
+ * and add them to sample block
+ * @param r pointer to 2D VLC table
+ * @param esc_golomb_order escape codes are k-golomb with this order k
+ * @param qp quantizer
+ * @param dst location of sample block
+ * @param stride line stride in frame buffer
+ */
+static int decode_residual_block(AVSContext *h, GetBitContext *gb,
+ const struct dec_2dvlc *r, int esc_golomb_order,
+ int qp, uint8_t *dst, int stride)
+{
+ int i, esc_code, level, mask, ret;
+ unsigned int level_code, run;
+ int16_t level_buf[65];
+ uint8_t run_buf[65];
+ int16_t *block = h->block;
+
+ for (i = 0; i < 65; i++) {
+ level_code = get_ue_code(gb, r->golomb_order);
+ if (level_code >= ESCAPE_CODE) {
+ run = ((level_code - ESCAPE_CODE) >> 1) + 1;
+ if(run > 64) {
+ av_log(h->avctx, AV_LOG_ERROR, "run %d is too large\n", run);
+ return AVERROR_INVALIDDATA;
+ }
+ esc_code = get_ue_code(gb, esc_golomb_order);
+ if (esc_code < 0 || esc_code > 32767) {
+ av_log(h->avctx, AV_LOG_ERROR, "esc_code invalid\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ level = esc_code + (run > r->max_run ? 1 : r->level_add[run]);
+ while (level > r->inc_limit)
+ r++;
+ mask = -(level_code & 1);
+ level = (level ^ mask) - mask;
+ } else {
+ level = r->rltab[level_code][0];
+ if (!level) //end of block signal
+ break;
+ run = r->rltab[level_code][1];
+ r += r->rltab[level_code][2];
+ }
+ level_buf[i] = level;
+ run_buf[i] = run;
+ }
+ if ((ret = dequant(h, level_buf, run_buf, block, dequant_mul[qp],
+ dequant_shift[qp], i)) < 0)
+ return ret;
+ h->cdsp.cavs_idct8_add(dst, block, stride);
+ h->bdsp.clear_block(block);
+ return 0;
+}
+
+
+static inline void decode_residual_chroma(AVSContext *h)
+{
+ if (h->cbp & (1 << 4))
+ decode_residual_block(h, &h->gb, chroma_dec, 0,
+ ff_cavs_chroma_qp[h->qp], h->cu, h->c_stride);
+ if (h->cbp & (1 << 5))
+ decode_residual_block(h, &h->gb, chroma_dec, 0,
+ ff_cavs_chroma_qp[h->qp], h->cv, h->c_stride);
+}
+
+static inline int decode_residual_inter(AVSContext *h)
+{
+ int block;
+
+ /* get coded block pattern */
+ int cbp = get_ue_golomb(&h->gb);
+ if (cbp > 63U) {
+ av_log(h->avctx, AV_LOG_ERROR, "illegal inter cbp %d\n", cbp);
+ return AVERROR_INVALIDDATA;
+ }
+ h->cbp = cbp_tab[cbp][1];
+
+ /* get quantizer */
+ if (h->cbp && !h->qp_fixed)
+ h->qp = (h->qp + (unsigned)get_se_golomb(&h->gb)) & 63;
+ for (block = 0; block < 4; block++)
+ if (h->cbp & (1 << block))
+ decode_residual_block(h, &h->gb, inter_dec, 0, h->qp,
+ h->cy + h->luma_scan[block], h->l_stride);
+ decode_residual_chroma(h);
+
+ return 0;
+}
+
+/*****************************************************************************
+ *
+ * macroblock level
+ *
+ ****************************************************************************/
+
+static inline void set_mv_intra(AVSContext *h)
+{
+ h->mv[MV_FWD_X0] = ff_cavs_intra_mv;
+ set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
+ h->mv[MV_BWD_X0] = ff_cavs_intra_mv;
+ set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
+ if (h->cur.f->pict_type != AV_PICTURE_TYPE_B)
+ h->col_type_base[h->mbidx] = I_8X8;
+}
+
+static int decode_mb_i(AVSContext *h, int cbp_code)
+{
+ GetBitContext *gb = &h->gb;
+ unsigned pred_mode_uv;
+ int block;
+ uint8_t top[18];
+ uint8_t *left = NULL;
+ uint8_t *d;
+
+ ff_cavs_init_mb(h);
+
+ /* get intra prediction modes from stream */
+ for (block = 0; block < 4; block++) {
+ int nA, nB, predpred;
+ int pos = scan3x3[block];
+
+ nA = h->pred_mode_Y[pos - 1];
+ nB = h->pred_mode_Y[pos - 3];
+ predpred = FFMIN(nA, nB);
+ if (predpred == NOT_AVAIL) // if either is not available
+ predpred = INTRA_L_LP;
+ if (!get_bits1(gb)) {
+ int rem_mode = get_bits(gb, 2);
+ predpred = rem_mode + (rem_mode >= predpred);
+ }
+ h->pred_mode_Y[pos] = predpred;
+ }
+ pred_mode_uv = get_ue_golomb(gb);
+ if (pred_mode_uv > 6) {
+ av_log(h->avctx, AV_LOG_ERROR, "illegal intra chroma pred mode\n");
+ return AVERROR_INVALIDDATA;
+ }
+ ff_cavs_modify_mb_i(h, &pred_mode_uv);
+
+ /* get coded block pattern */
+ if (h->cur.f->pict_type == AV_PICTURE_TYPE_I)
+ cbp_code = get_ue_golomb(gb);
+ if (cbp_code > 63U) {
+ av_log(h->avctx, AV_LOG_ERROR, "illegal intra cbp\n");
+ return AVERROR_INVALIDDATA;
+ }
+ h->cbp = cbp_tab[cbp_code][0];
+ if (h->cbp && !h->qp_fixed)
+ h->qp = (h->qp + get_se_golomb(gb)) & 63; //qp_delta
+
+ /* luma intra prediction interleaved with residual decode/transform/add */
+ for (block = 0; block < 4; block++) {
+ d = h->cy + h->luma_scan[block];
+ ff_cavs_load_intra_pred_luma(h, top, &left, block);
+ h->intra_pred_l[h->pred_mode_Y[scan3x3[block]]]
+ (d, top, left, h->l_stride);
+ if (h->cbp & (1<<block))
+ decode_residual_block(h, gb, intra_dec, 1, h->qp, d, h->l_stride);
+ }
+
+ /* chroma intra prediction */
+ ff_cavs_load_intra_pred_chroma(h);
+ h->intra_pred_c[pred_mode_uv](h->cu, &h->top_border_u[h->mbx * 10],
+ h->left_border_u, h->c_stride);
+ h->intra_pred_c[pred_mode_uv](h->cv, &h->top_border_v[h->mbx * 10],
+ h->left_border_v, h->c_stride);
+
+ decode_residual_chroma(h);
+ ff_cavs_filter(h, I_8X8);
+ set_mv_intra(h);
+ return 0;
+}
+
+static inline void set_intra_mode_default(AVSContext *h)
+{
+ if (h->stream_revision > 0) {
+ h->pred_mode_Y[3] = h->pred_mode_Y[6] = NOT_AVAIL;
+ h->top_pred_Y[h->mbx * 2 + 0] = h->top_pred_Y[h->mbx * 2 + 1] = NOT_AVAIL;
+ } else {
+ h->pred_mode_Y[3] = h->pred_mode_Y[6] = INTRA_L_LP;
+ h->top_pred_Y[h->mbx * 2 + 0] = h->top_pred_Y[h->mbx * 2 + 1] = INTRA_L_LP;
+ }
+}
+
+static void decode_mb_p(AVSContext *h, enum cavs_mb mb_type)
+{
+ GetBitContext *gb = &h->gb;
+ int ref[4];
+
+ ff_cavs_init_mb(h);
+ switch (mb_type) {
+ case P_SKIP:
+ ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_PSKIP, BLK_16X16, 0);
+ break;
+ case P_16X16:
+ ref[0] = h->ref_flag ? 0 : get_bits1(gb);
+ ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, ref[0]);
+ break;
+ case P_16X8:
+ ref[0] = h->ref_flag ? 0 : get_bits1(gb);
+ ref[2] = h->ref_flag ? 0 : get_bits1(gb);
+ ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_TOP, BLK_16X8, ref[0]);
+ ff_cavs_mv(h, MV_FWD_X2, MV_FWD_A1, MV_PRED_LEFT, BLK_16X8, ref[2]);
+ break;
+ case P_8X16:
+ ref[0] = h->ref_flag ? 0 : get_bits1(gb);
+ ref[1] = h->ref_flag ? 0 : get_bits1(gb);
+ ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT, BLK_8X16, ref[0]);
+ ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_TOPRIGHT, BLK_8X16, ref[1]);
+ break;
+ case P_8X8:
+ ref[0] = h->ref_flag ? 0 : get_bits1(gb);
+ ref[1] = h->ref_flag ? 0 : get_bits1(gb);
+ ref[2] = h->ref_flag ? 0 : get_bits1(gb);
+ ref[3] = h->ref_flag ? 0 : get_bits1(gb);
+ ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_MEDIAN, BLK_8X8, ref[0]);
+ ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_MEDIAN, BLK_8X8, ref[1]);
+ ff_cavs_mv(h, MV_FWD_X2, MV_FWD_X1, MV_PRED_MEDIAN, BLK_8X8, ref[2]);
+ ff_cavs_mv(h, MV_FWD_X3, MV_FWD_X0, MV_PRED_MEDIAN, BLK_8X8, ref[3]);
+ }
+ ff_cavs_inter(h, mb_type);
+ set_intra_mode_default(h);
+ store_mvs(h);
+ if (mb_type != P_SKIP)
+ decode_residual_inter(h);
+ ff_cavs_filter(h, mb_type);
+ h->col_type_base[h->mbidx] = mb_type;
+}
+
+static int decode_mb_b(AVSContext *h, enum cavs_mb mb_type)
+{
+ int block;
+ enum cavs_sub_mb sub_type[4];
+ int flags;
+
+ ff_cavs_init_mb(h);
+
+ /* reset all MVs */
+ h->mv[MV_FWD_X0] = ff_cavs_dir_mv;
+ set_mvs(&h->mv[MV_FWD_X0], BLK_16X16);
+ h->mv[MV_BWD_X0] = ff_cavs_dir_mv;
+ set_mvs(&h->mv[MV_BWD_X0], BLK_16X16);
+ switch (mb_type) {
+ case B_SKIP:
+ case B_DIRECT:
+ if (!h->col_type_base[h->mbidx]) {
+ /* intra MB at co-location, do in-plane prediction */
+ ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_BSKIP, BLK_16X16, 1);
+ ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_BSKIP, BLK_16X16, 0);
+ } else
+ /* direct prediction from co-located P MB, block-wise */
+ for (block = 0; block < 4; block++)
+ mv_pred_direct(h, &h->mv[mv_scan[block]],
+ &h->col_mv[h->mbidx * 4 + block]);
+ break;
+ case B_FWD_16X16:
+ ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, 1);
+ break;
+ case B_SYM_16X16:
+ ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_MEDIAN, BLK_16X16, 1);
+ mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_16X16);
+ break;
+ case B_BWD_16X16:
+ ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_MEDIAN, BLK_16X16, 0);
+ break;
+ case B_8X8:
+#define TMP_UNUSED_INX 7
+ flags = 0;
+ for (block = 0; block < 4; block++)
+ sub_type[block] = get_bits(&h->gb, 2);
+ for (block = 0; block < 4; block++) {
+ switch (sub_type[block]) {
+ case B_SUB_DIRECT:
+ if (!h->col_type_base[h->mbidx]) {
+ /* intra MB at co-location, do in-plane prediction */
+ if(flags==0) {
+ // if col-MB is a Intra MB, current Block size is 16x16.
+ // AVS standard section 9.9.1
+ if(block>0){
+ h->mv[TMP_UNUSED_INX ] = h->mv[MV_FWD_X0 ];
+ h->mv[TMP_UNUSED_INX + MV_BWD_OFFS] = h->mv[MV_FWD_X0 + MV_BWD_OFFS];
+ }
+ ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2,
+ MV_PRED_BSKIP, BLK_8X8, 1);
+ ff_cavs_mv(h, MV_FWD_X0+MV_BWD_OFFS,
+ MV_FWD_C2+MV_BWD_OFFS,
+ MV_PRED_BSKIP, BLK_8X8, 0);
+ if(block>0) {
+ flags = mv_scan[block];
+ h->mv[flags ] = h->mv[MV_FWD_X0 ];
+ h->mv[flags + MV_BWD_OFFS] = h->mv[MV_FWD_X0 + MV_BWD_OFFS];
+ h->mv[MV_FWD_X0 ] = h->mv[TMP_UNUSED_INX ];
+ h->mv[MV_FWD_X0 + MV_BWD_OFFS] = h->mv[TMP_UNUSED_INX + MV_BWD_OFFS];
+ } else
+ flags = MV_FWD_X0;
+ } else {
+ h->mv[mv_scan[block] ] = h->mv[flags ];
+ h->mv[mv_scan[block] + MV_BWD_OFFS] = h->mv[flags + MV_BWD_OFFS];
+ }
+ } else
+ mv_pred_direct(h, &h->mv[mv_scan[block]],
+ &h->col_mv[h->mbidx * 4 + block]);
+ break;
+ case B_SUB_FWD:
+ ff_cavs_mv(h, mv_scan[block], mv_scan[block] - 3,
+ MV_PRED_MEDIAN, BLK_8X8, 1);
+ break;
+ case B_SUB_SYM:
+ ff_cavs_mv(h, mv_scan[block], mv_scan[block] - 3,
+ MV_PRED_MEDIAN, BLK_8X8, 1);
+ mv_pred_sym(h, &h->mv[mv_scan[block]], BLK_8X8);
+ break;
+ }
+ }
+#undef TMP_UNUSED_INX
+ for (block = 0; block < 4; block++) {
+ if (sub_type[block] == B_SUB_BWD)
+ ff_cavs_mv(h, mv_scan[block] + MV_BWD_OFFS,
+ mv_scan[block] + MV_BWD_OFFS - 3,
+ MV_PRED_MEDIAN, BLK_8X8, 0);
+ }
+ break;
+ default:
+ if (mb_type <= B_SYM_16X16) {
+ av_log(h->avctx, AV_LOG_ERROR, "Invalid mb_type %d in B frame\n", mb_type);
+ return AVERROR_INVALIDDATA;
+ }
+ av_assert2(mb_type < B_8X8);
+ flags = ff_cavs_partition_flags[mb_type];
+ if (mb_type & 1) { /* 16x8 macroblock types */
+ if (flags & FWD0)
+ ff_cavs_mv(h, MV_FWD_X0, MV_FWD_C2, MV_PRED_TOP, BLK_16X8, 1);
+ if (flags & SYM0)
+ mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_16X8);
+ if (flags & FWD1)
+ ff_cavs_mv(h, MV_FWD_X2, MV_FWD_A1, MV_PRED_LEFT, BLK_16X8, 1);
+ if (flags & SYM1)
+ mv_pred_sym(h, &h->mv[MV_FWD_X2], BLK_16X8);
+ if (flags & BWD0)
+ ff_cavs_mv(h, MV_BWD_X0, MV_BWD_C2, MV_PRED_TOP, BLK_16X8, 0);
+ if (flags & BWD1)
+ ff_cavs_mv(h, MV_BWD_X2, MV_BWD_A1, MV_PRED_LEFT, BLK_16X8, 0);
+ } else { /* 8x16 macroblock types */
+ if (flags & FWD0)
+ ff_cavs_mv(h, MV_FWD_X0, MV_FWD_B3, MV_PRED_LEFT, BLK_8X16, 1);
+ if (flags & SYM0)
+ mv_pred_sym(h, &h->mv[MV_FWD_X0], BLK_8X16);
+ if (flags & FWD1)
+ ff_cavs_mv(h, MV_FWD_X1, MV_FWD_C2, MV_PRED_TOPRIGHT, BLK_8X16, 1);
+ if (flags & SYM1)
+ mv_pred_sym(h, &h->mv[MV_FWD_X1], BLK_8X16);
+ if (flags & BWD0)
+ ff_cavs_mv(h, MV_BWD_X0, MV_BWD_B3, MV_PRED_LEFT, BLK_8X16, 0);
+ if (flags & BWD1)
+ ff_cavs_mv(h, MV_BWD_X1, MV_BWD_C2, MV_PRED_TOPRIGHT, BLK_8X16, 0);
+ }
+ }
+ ff_cavs_inter(h, mb_type);
+ set_intra_mode_default(h);
+ if (mb_type != B_SKIP)
+ decode_residual_inter(h);
+ ff_cavs_filter(h, mb_type);
+
+ return 0;
+}
+
+/*****************************************************************************
+ *
+ * slice level
+ *
+ ****************************************************************************/
+
+static inline int decode_slice_header(AVSContext *h, GetBitContext *gb)
+{
+ if (h->stc > 0xAF)
+ av_log(h->avctx, AV_LOG_ERROR, "unexpected start code 0x%02x\n", h->stc);
+
+ if (h->stc >= h->mb_height) {
+ av_log(h->avctx, AV_LOG_ERROR, "stc 0x%02x is too large\n", h->stc);
+ return AVERROR_INVALIDDATA;
+ }
+
+ h->mby = h->stc;
+ h->mbidx = h->mby * h->mb_width;
+
+ /* mark top macroblocks as unavailable */
+ h->flags &= ~(B_AVAIL | C_AVAIL);
+ if (!h->pic_qp_fixed) {
+ h->qp_fixed = get_bits1(gb);
+ h->qp = get_bits(gb, 6);
+ }
+ /* inter frame or second slice can have weighting params */
+ if ((h->cur.f->pict_type != AV_PICTURE_TYPE_I) ||
+ (!h->pic_structure && h->mby >= h->mb_width / 2))
+ if (get_bits1(gb)) { //slice_weighting_flag
+ av_log(h->avctx, AV_LOG_ERROR,
+ "weighted prediction not yet supported\n");
+ }
+ return 0;
+}
+
+static inline int check_for_slice(AVSContext *h)
+{
+ GetBitContext *gb = &h->gb;
+ int align;
+
+ if (h->mbx)
+ return 0;
+ align = (-get_bits_count(gb)) & 7;
+ /* check for stuffing byte */
+ if (!align && (show_bits(gb, 8) == 0x80))
+ align = 8;
+ if ((show_bits_long(gb, 24 + align) & 0xFFFFFF) == 0x000001) {
+ skip_bits_long(gb, 24 + align);
+ h->stc = get_bits(gb, 8);
+ if (h->stc >= h->mb_height)
+ return 0;
+ decode_slice_header(h, gb);
+ return 1;
+ }
+ return 0;
+}
+
+/*****************************************************************************
+ *
+ * frame level
+ *
+ ****************************************************************************/
+
+static int decode_pic(AVSContext *h)
+{
+ int ret;
+ int skip_count = -1;
+ enum cavs_mb mb_type;
+
+ if (!h->top_qp) {
+ av_log(h->avctx, AV_LOG_ERROR, "No sequence header decoded yet\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ av_frame_unref(h->cur.f);
+
+ skip_bits(&h->gb, 16);//bbv_dwlay
+ if (h->stc == PIC_PB_START_CODE) {
+ h->cur.f->pict_type = get_bits(&h->gb, 2) + AV_PICTURE_TYPE_I;
+ if (h->cur.f->pict_type > AV_PICTURE_TYPE_B) {
+ av_log(h->avctx, AV_LOG_ERROR, "illegal picture type\n");
+ return AVERROR_INVALIDDATA;
+ }
+ /* make sure we have the reference frames we need */
+ if (!h->DPB[0].f->data[0] ||
+ (!h->DPB[1].f->data[0] && h->cur.f->pict_type == AV_PICTURE_TYPE_B))
+ return AVERROR_INVALIDDATA;
+ } else {
+ h->cur.f->pict_type = AV_PICTURE_TYPE_I;
+ if (get_bits1(&h->gb))
+ skip_bits(&h->gb, 24);//time_code
+ /* old sample clips were all progressive and no low_delay,
+ bump stream revision if detected otherwise */
+ if (h->low_delay || !(show_bits(&h->gb, 9) & 1))
+ h->stream_revision = 1;
+ /* similarly test top_field_first and repeat_first_field */
+ else if (show_bits(&h->gb, 11) & 3)
+ h->stream_revision = 1;
+ if (h->stream_revision > 0)
+ skip_bits(&h->gb, 1); //marker_bit
+ }
+
+ ret = ff_get_buffer(h->avctx, h->cur.f, h->cur.f->pict_type == AV_PICTURE_TYPE_B ?
+ 0 : AV_GET_BUFFER_FLAG_REF);
+ if (ret < 0)
+ return ret;
+
+ if (!h->edge_emu_buffer) {
+ int alloc_size = FFALIGN(FFABS(h->cur.f->linesize[0]) + 32, 32);
+ h->edge_emu_buffer = av_mallocz(alloc_size * 2 * 24);
+ if (!h->edge_emu_buffer)
+ return AVERROR(ENOMEM);
+ }
+
+ if ((ret = ff_cavs_init_pic(h)) < 0)
+ return ret;
+ h->cur.poc = get_bits(&h->gb, 8) * 2;
+
+ /* get temporal distances and MV scaling factors */
+ if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
+ h->dist[0] = (h->cur.poc - h->DPB[0].poc) & 511;
+ } else {
+ h->dist[0] = (h->DPB[0].poc - h->cur.poc) & 511;
+ }
+ h->dist[1] = (h->cur.poc - h->DPB[1].poc) & 511;
+ h->scale_den[0] = h->dist[0] ? 512/h->dist[0] : 0;
+ h->scale_den[1] = h->dist[1] ? 512/h->dist[1] : 0;
+ if (h->cur.f->pict_type == AV_PICTURE_TYPE_B) {
+ h->sym_factor = h->dist[0] * h->scale_den[1];
+ if (FFABS(h->sym_factor) > 32768) {
+ av_log(h->avctx, AV_LOG_ERROR, "sym_factor %d too large\n", h->sym_factor);
+ return AVERROR_INVALIDDATA;
+ }
+ } else {
+ h->direct_den[0] = h->dist[0] ? 16384 / h->dist[0] : 0;
+ h->direct_den[1] = h->dist[1] ? 16384 / h->dist[1] : 0;
+ }
+
+ if (h->low_delay)
+ get_ue_golomb(&h->gb); //bbv_check_times
+ h->progressive = get_bits1(&h->gb);
+ h->pic_structure = 1;
+ if (!h->progressive)
+ h->pic_structure = get_bits1(&h->gb);
+ if (!h->pic_structure && h->stc == PIC_PB_START_CODE)
+ skip_bits1(&h->gb); //advanced_pred_mode_disable
+ skip_bits1(&h->gb); //top_field_first
+ skip_bits1(&h->gb); //repeat_first_field
+ h->pic_qp_fixed =
+ h->qp_fixed = get_bits1(&h->gb);
+ h->qp = get_bits(&h->gb, 6);
+ if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) {
+ if (!h->progressive && !h->pic_structure)
+ skip_bits1(&h->gb);//what is this?
+ skip_bits(&h->gb, 4); //reserved bits
+ } else {
+ if (!(h->cur.f->pict_type == AV_PICTURE_TYPE_B && h->pic_structure == 1))
+ h->ref_flag = get_bits1(&h->gb);
+ skip_bits(&h->gb, 4); //reserved bits
+ h->skip_mode_flag = get_bits1(&h->gb);
+ }
+ h->loop_filter_disable = get_bits1(&h->gb);
+ if (!h->loop_filter_disable && get_bits1(&h->gb)) {
+ h->alpha_offset = get_se_golomb(&h->gb);
+ h->beta_offset = get_se_golomb(&h->gb);
+ } else {
+ h->alpha_offset = h->beta_offset = 0;
+ }
+ if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) {
+ do {
+ check_for_slice(h);
+ decode_mb_i(h, 0);
+ } while (ff_cavs_next_mb(h));
+ } else if (h->cur.f->pict_type == AV_PICTURE_TYPE_P) {
+ do {
+ if (check_for_slice(h))
+ skip_count = -1;
+ if (h->skip_mode_flag && (skip_count < 0))
+ skip_count = get_ue_golomb(&h->gb);
+ if (h->skip_mode_flag && skip_count--) {
+ decode_mb_p(h, P_SKIP);
+ } else {
+ mb_type = get_ue_golomb(&h->gb) + P_SKIP + h->skip_mode_flag;
+ if (mb_type > P_8X8)
+ decode_mb_i(h, mb_type - P_8X8 - 1);
+ else
+ decode_mb_p(h, mb_type);
+ }
+ } while (ff_cavs_next_mb(h));
+ } else { /* AV_PICTURE_TYPE_B */
+ do {
+ if (check_for_slice(h))
+ skip_count = -1;
+ if (h->skip_mode_flag && (skip_count < 0))
+ skip_count = get_ue_golomb(&h->gb);
+ if (h->skip_mode_flag && skip_count--) {
+ decode_mb_b(h, B_SKIP);
+ } else {
+ mb_type = get_ue_golomb(&h->gb) + B_SKIP + h->skip_mode_flag;
+ if (mb_type > B_8X8)
+ decode_mb_i(h, mb_type - B_8X8 - 1);
+ else
+ decode_mb_b(h, mb_type);
+ }
+ } while (ff_cavs_next_mb(h));
+ }
+ if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
+ av_frame_unref(h->DPB[1].f);
+ FFSWAP(AVSFrame, h->cur, h->DPB[1]);
+ FFSWAP(AVSFrame, h->DPB[0], h->DPB[1]);
+ }
+ return 0;
+}
+
+/*****************************************************************************
+ *
+ * headers and interface
+ *
+ ****************************************************************************/
+
+static int decode_seq_header(AVSContext *h)
+{
+ int frame_rate_code;
+ int width, height;
+ int ret;
+
+ h->profile = get_bits(&h->gb, 8);
+ h->level = get_bits(&h->gb, 8);
+ skip_bits1(&h->gb); //progressive sequence
+
+ width = get_bits(&h->gb, 14);
+ height = get_bits(&h->gb, 14);
+ if ((h->width || h->height) && (h->width != width || h->height != height)) {
+ avpriv_report_missing_feature(h->avctx,
+ "Width/height changing in CAVS");
+ return AVERROR_PATCHWELCOME;
+ }
+ if (width <= 0 || height <= 0) {
+ av_log(h->avctx, AV_LOG_ERROR, "Dimensions invalid\n");
+ return AVERROR_INVALIDDATA;
+ }
+ skip_bits(&h->gb, 2); //chroma format
+ skip_bits(&h->gb, 3); //sample_precision
+ h->aspect_ratio = get_bits(&h->gb, 4);
+ frame_rate_code = get_bits(&h->gb, 4);
+ if (frame_rate_code == 0 || frame_rate_code > 13) {
+ av_log(h->avctx, AV_LOG_WARNING,
+ "frame_rate_code %d is invalid\n", frame_rate_code);
+ frame_rate_code = 1;
+ }
+
+ skip_bits(&h->gb, 18); //bit_rate_lower
+ skip_bits1(&h->gb); //marker_bit
+ skip_bits(&h->gb, 12); //bit_rate_upper
+ h->low_delay = get_bits1(&h->gb);
+
+ ret = ff_set_dimensions(h->avctx, width, height);
+ if (ret < 0)
+ return ret;
+
+ h->width = width;
+ h->height = height;
+ h->mb_width = (h->width + 15) >> 4;
+ h->mb_height = (h->height + 15) >> 4;
+ h->avctx->framerate = ff_mpeg12_frame_rate_tab[frame_rate_code];
+ if (!h->top_qp)
+ return ff_cavs_init_top_lines(h);
+ return 0;
+}
+
+static void cavs_flush(AVCodecContext * avctx)
+{
+ AVSContext *h = avctx->priv_data;
+ h->got_keyframe = 0;
+}
+
+static int cavs_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ AVSContext *h = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ uint32_t stc = -1;
+ int input_size, ret;
+ const uint8_t *buf_end;
+ const uint8_t *buf_ptr;
+
+ if (buf_size == 0) {
+ if (!h->low_delay && h->DPB[0].f->data[0]) {
+ *got_frame = 1;
+ av_frame_move_ref(data, h->DPB[0].f);
+ }
+ return 0;
+ }
+
+ h->stc = 0;
+
+ buf_ptr = buf;
+ buf_end = buf + buf_size;
+ for(;;) {
+ buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &stc);
+ if ((stc & 0xFFFFFE00) || buf_ptr == buf_end) {
+ if (!h->stc)
+ av_log(h->avctx, AV_LOG_WARNING, "no frame decoded\n");
+ return FFMAX(0, buf_ptr - buf);
+ }
+ input_size = (buf_end - buf_ptr) * 8;
+ switch (stc) {
+ case CAVS_START_CODE:
+ init_get_bits(&h->gb, buf_ptr, input_size);
+ decode_seq_header(h);
+ break;
+ case PIC_I_START_CODE:
+ if (!h->got_keyframe) {
+ av_frame_unref(h->DPB[0].f);
+ av_frame_unref(h->DPB[1].f);
+ h->got_keyframe = 1;
+ }
+ case PIC_PB_START_CODE:
+ if (*got_frame)
+ av_frame_unref(data);
+ *got_frame = 0;
+ if (!h->got_keyframe)
+ break;
+ init_get_bits(&h->gb, buf_ptr, input_size);
+ h->stc = stc;
+ if (decode_pic(h))
+ break;
+ *got_frame = 1;
+ if (h->cur.f->pict_type != AV_PICTURE_TYPE_B) {
+ if (h->DPB[!h->low_delay].f->data[0]) {
+ if ((ret = av_frame_ref(data, h->DPB[!h->low_delay].f)) < 0)
+ return ret;
+ } else {
+ *got_frame = 0;
+ }
+ } else {
+ av_frame_move_ref(data, h->cur.f);
+ }
+ break;
+ case EXT_START_CODE:
+ //mpeg_decode_extension(avctx, buf_ptr, input_size);
+ break;
+ case USER_START_CODE:
+ //mpeg_decode_user_data(avctx, buf_ptr, input_size);
+ break;
+ default:
+ if (stc <= SLICE_MAX_START_CODE) {
+ init_get_bits(&h->gb, buf_ptr, input_size);
+ decode_slice_header(h, &h->gb);
+ }
+ break;
+ }
+ }
+}
+
+AVCodec ff_cavs_decoder = {
+ .name = "cavs",
+ .long_name = NULL_IF_CONFIG_SMALL("Chinese AVS (Audio Video Standard) (AVS1-P2, JiZhun profile)"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_CAVS,
+ .priv_data_size = sizeof(AVSContext),
+ .init = ff_cavs_init,
+ .close = ff_cavs_end,
+ .decode = cavs_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY,
+ .flush = cavs_flush,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/cavsdsp.c b/ffmpeg-2-8-12/libavcodec/cavsdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cavsdsp.c
rename to ffmpeg-2-8-12/libavcodec/cavsdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/cavsdsp.h b/ffmpeg-2-8-12/libavcodec/cavsdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cavsdsp.h
rename to ffmpeg-2-8-12/libavcodec/cavsdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/cbrt_fixed_tablegen.c b/ffmpeg-2-8-12/libavcodec/cbrt_fixed_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cbrt_fixed_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/cbrt_fixed_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/cbrt_tablegen.c b/ffmpeg-2-8-12/libavcodec/cbrt_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cbrt_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/cbrt_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/cbrt_tablegen.h b/ffmpeg-2-8-12/libavcodec/cbrt_tablegen.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cbrt_tablegen.h
rename to ffmpeg-2-8-12/libavcodec/cbrt_tablegen.h
diff --git a/ffmpeg-2-8-11/libavcodec/cbrt_tablegen_template.c b/ffmpeg-2-8-12/libavcodec/cbrt_tablegen_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cbrt_tablegen_template.c
rename to ffmpeg-2-8-12/libavcodec/cbrt_tablegen_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/ccaption_dec.c b/ffmpeg-2-8-12/libavcodec/ccaption_dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ccaption_dec.c
rename to ffmpeg-2-8-12/libavcodec/ccaption_dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/cdgraphics.c b/ffmpeg-2-8-12/libavcodec/cdgraphics.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cdgraphics.c
rename to ffmpeg-2-8-12/libavcodec/cdgraphics.c
diff --git a/ffmpeg-2-8-12/libavcodec/cdxl.c b/ffmpeg-2-8-12/libavcodec/cdxl.c
new file mode 100644
index 0000000..3eaf194
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/cdxl.c
@@ -0,0 +1,309 @@
+/*
+ * CDXL video decoder
+ * Copyright (c) 2011-2012 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
+ * Commodore CDXL video decoder
+ * @author Paul B Mahol
+ */
+
+#define UNCHECKED_BITSTREAM_READER 1
+
+#include "libavutil/intreadwrite.h"
+#include "libavutil/imgutils.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "internal.h"
+
+#define BIT_PLANAR 0x00
+#define CHUNKY 0x20
+#define BYTE_PLANAR 0x40
+#define BIT_LINE 0x80
+#define BYTE_LINE 0xC0
+
+typedef struct CDXLVideoContext {
+ AVCodecContext *avctx;
+ int bpp;
+ int format;
+ int padded_bits;
+ const uint8_t *palette;
+ int palette_size;
+ const uint8_t *video;
+ int video_size;
+ uint8_t *new_video;
+ int new_video_size;
+} CDXLVideoContext;
+
+static av_cold int cdxl_decode_init(AVCodecContext *avctx)
+{
+ CDXLVideoContext *c = avctx->priv_data;
+
+ c->new_video_size = 0;
+ c->avctx = avctx;
+
+ return 0;
+}
+
+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);
+ }
+}
+
+static void bitplanar2chunky(CDXLVideoContext *c, int linesize, uint8_t *out)
+{
+ GetBitContext gb;
+ int x, y, plane;
+
+ if (init_get_bits8(&gb, c->video, c->video_size) < 0)
+ return;
+ for (plane = 0; plane < c->bpp; plane++) {
+ for (y = 0; y < c->avctx->height; y++) {
+ for (x = 0; x < c->avctx->width; x++)
+ out[linesize * y + x] |= get_bits1(&gb) << plane;
+ skip_bits(&gb, c->padded_bits);
+ }
+ }
+}
+
+static void bitline2chunky(CDXLVideoContext *c, int linesize, uint8_t *out)
+{
+ GetBitContext gb;
+ int x, y, plane;
+
+ if (init_get_bits8(&gb, c->video, c->video_size) < 0)
+ return;
+ for (y = 0; y < c->avctx->height; y++) {
+ for (plane = 0; plane < c->bpp; plane++) {
+ for (x = 0; x < c->avctx->width; x++)
+ out[linesize * y + x] |= get_bits1(&gb) << plane;
+ skip_bits(&gb, c->padded_bits);
+ }
+ }
+}
+
+static void import_format(CDXLVideoContext *c, int linesize, uint8_t *out)
+{
+ memset(out, 0, linesize * c->avctx->height);
+
+ switch (c->format) {
+ case BIT_PLANAR:
+ bitplanar2chunky(c, linesize, out);
+ break;
+ case BIT_LINE:
+ bitline2chunky(c, linesize, out);
+ break;
+ }
+}
+
+static void cdxl_decode_rgb(CDXLVideoContext *c, AVFrame *frame)
+{
+ uint32_t *new_palette = (uint32_t *)frame->data[1];
+
+ memset(frame->data[1], 0, AVPALETTE_SIZE);
+ import_palette(c, new_palette);
+ import_format(c, frame->linesize[0], frame->data[0]);
+}
+
+static void cdxl_decode_ham6(CDXLVideoContext *c, AVFrame *frame)
+{
+ AVCodecContext *avctx = c->avctx;
+ uint32_t new_palette[16], r, g, b;
+ uint8_t *ptr, *out, index, op;
+ int x, y;
+
+ ptr = c->new_video;
+ out = frame->data[0];
+
+ import_palette(c, new_palette);
+ import_format(c, avctx->width, c->new_video);
+
+ for (y = 0; y < avctx->height; y++) {
+ r = new_palette[0] & 0xFF0000;
+ g = new_palette[0] & 0xFF00;
+ b = new_palette[0] & 0xFF;
+ for (x = 0; x < avctx->width; x++) {
+ index = *ptr++;
+ op = index >> 4;
+ index &= 15;
+ switch (op) {
+ case 0:
+ r = new_palette[index] & 0xFF0000;
+ g = new_palette[index] & 0xFF00;
+ b = new_palette[index] & 0xFF;
+ break;
+ case 1:
+ b = index * 0x11;
+ break;
+ case 2:
+ r = index * 0x11 << 16;
+ break;
+ case 3:
+ g = index * 0x11 << 8;
+ break;
+ }
+ AV_WL24(out + x * 3, r | g | b);
+ }
+ out += frame->linesize[0];
+ }
+}
+
+static void cdxl_decode_ham8(CDXLVideoContext *c, AVFrame *frame)
+{
+ AVCodecContext *avctx = c->avctx;
+ uint32_t new_palette[64], r, g, b;
+ uint8_t *ptr, *out, index, op;
+ int x, y;
+
+ ptr = c->new_video;
+ out = frame->data[0];
+
+ import_palette(c, new_palette);
+ import_format(c, avctx->width, c->new_video);
+
+ for (y = 0; y < avctx->height; y++) {
+ r = new_palette[0] & 0xFF0000;
+ g = new_palette[0] & 0xFF00;
+ b = new_palette[0] & 0xFF;
+ for (x = 0; x < avctx->width; x++) {
+ index = *ptr++;
+ op = index >> 6;
+ index &= 63;
+ switch (op) {
+ case 0:
+ r = new_palette[index] & 0xFF0000;
+ g = new_palette[index] & 0xFF00;
+ b = new_palette[index] & 0xFF;
+ break;
+ case 1:
+ b = (index << 2) | (b & 3);
+ break;
+ case 2:
+ r = (index << 18) | (r & (3 << 16));
+ break;
+ case 3:
+ g = (index << 10) | (g & (3 << 8));
+ break;
+ }
+ AV_WL24(out + x * 3, r | g | b);
+ }
+ out += frame->linesize[0];
+ }
+}
+
+static int cdxl_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame, AVPacket *pkt)
+{
+ CDXLVideoContext *c = avctx->priv_data;
+ AVFrame * const p = data;
+ int ret, w, h, encoding, aligned_width, buf_size = pkt->size;
+ const uint8_t *buf = pkt->data;
+
+ if (buf_size < 32)
+ return AVERROR_INVALIDDATA;
+ encoding = buf[1] & 7;
+ c->format = buf[1] & 0xE0;
+ w = AV_RB16(&buf[14]);
+ h = AV_RB16(&buf[16]);
+ c->bpp = buf[19];
+ c->palette_size = AV_RB16(&buf[20]);
+ c->palette = buf + 32;
+ c->video = c->palette + c->palette_size;
+ c->video_size = buf_size - c->palette_size - 32;
+
+ if (c->palette_size > 512)
+ return AVERROR_INVALIDDATA;
+ if (buf_size < c->palette_size + 32)
+ return AVERROR_INVALIDDATA;
+ if (c->bpp < 1)
+ return AVERROR_INVALIDDATA;
+ if (c->format != BIT_PLANAR && c->format != BIT_LINE) {
+ avpriv_request_sample(avctx, "Pixel format 0x%0x", c->format);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
+ return ret;
+
+ aligned_width = FFALIGN(c->avctx->width, 16);
+ c->padded_bits = aligned_width - c->avctx->width;
+ if (c->video_size < aligned_width * avctx->height * (int64_t)c->bpp / 8)
+ return AVERROR_INVALIDDATA;
+ if (!encoding && c->palette_size && c->bpp <= 8 && c->format != CHUNKY) {
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ } else if (encoding == 1 && (c->bpp == 6 || c->bpp == 8) && c->format != CHUNKY) {
+ if (c->palette_size != (1 << (c->bpp - 1)))
+ return AVERROR_INVALIDDATA;
+ avctx->pix_fmt = AV_PIX_FMT_BGR24;
+ } else {
+ avpriv_request_sample(avctx, "Encoding %d and bpp %d",
+ encoding, c->bpp);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
+ return ret;
+ p->pict_type = AV_PICTURE_TYPE_I;
+
+ if (encoding) {
+ av_fast_padded_malloc(&c->new_video, &c->new_video_size,
+ h * w + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!c->new_video)
+ return AVERROR(ENOMEM);
+ if (c->bpp == 8)
+ cdxl_decode_ham8(c, p);
+ else
+ cdxl_decode_ham6(c, p);
+ } else {
+ cdxl_decode_rgb(c, p);
+ }
+ *got_frame = 1;
+
+ return buf_size;
+}
+
+static av_cold int cdxl_decode_end(AVCodecContext *avctx)
+{
+ CDXLVideoContext *c = avctx->priv_data;
+
+ av_freep(&c->new_video);
+
+ return 0;
+}
+
+AVCodec ff_cdxl_decoder = {
+ .name = "cdxl",
+ .long_name = NULL_IF_CONFIG_SMALL("Commodore CDXL video"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_CDXL,
+ .priv_data_size = sizeof(CDXLVideoContext),
+ .init = cdxl_decode_init,
+ .close = cdxl_decode_end,
+ .decode = cdxl_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/celp_filters.c b/ffmpeg-2-8-12/libavcodec/celp_filters.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/celp_filters.c
rename to ffmpeg-2-8-12/libavcodec/celp_filters.c
diff --git a/ffmpeg-2-8-11/libavcodec/celp_filters.h b/ffmpeg-2-8-12/libavcodec/celp_filters.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/celp_filters.h
rename to ffmpeg-2-8-12/libavcodec/celp_filters.h
diff --git a/ffmpeg-2-8-11/libavcodec/celp_math.c b/ffmpeg-2-8-12/libavcodec/celp_math.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/celp_math.c
rename to ffmpeg-2-8-12/libavcodec/celp_math.c
diff --git a/ffmpeg-2-8-11/libavcodec/celp_math.h b/ffmpeg-2-8-12/libavcodec/celp_math.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/celp_math.h
rename to ffmpeg-2-8-12/libavcodec/celp_math.h
diff --git a/ffmpeg-2-8-11/libavcodec/cga_data.c b/ffmpeg-2-8-12/libavcodec/cga_data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cga_data.c
rename to ffmpeg-2-8-12/libavcodec/cga_data.c
diff --git a/ffmpeg-2-8-11/libavcodec/cga_data.h b/ffmpeg-2-8-12/libavcodec/cga_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cga_data.h
rename to ffmpeg-2-8-12/libavcodec/cga_data.h
diff --git a/ffmpeg-2-8-11/libavcodec/chomp_bsf.c b/ffmpeg-2-8-12/libavcodec/chomp_bsf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/chomp_bsf.c
rename to ffmpeg-2-8-12/libavcodec/chomp_bsf.c
diff --git a/ffmpeg-2-8-12/libavcodec/cinepak.c b/ffmpeg-2-8-12/libavcodec/cinepak.c
new file mode 100644
index 0000000..7a74662
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/cinepak.c
@@ -0,0 +1,491 @@
+/*
+ * Cinepak Video Decoder
+ * Copyright (c) 2003 The FFmpeg Project
+ *
+ * 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
+ * Cinepak video decoder
+ * @author Ewald Snel <ewald at rambo.its.tudelft.nl>
+ *
+ * @see For more information on the Cinepak algorithm, visit:
+ * http://www.csse.monash.edu.au/~timf/
+ * @see For more information on the quirky data inside Sega FILM/CPK files, visit:
+ * http://wiki.multimedia.cx/index.php?title=Sega_FILM
+ *
+ * Cinepak colorspace support (c) 2013 Rl, Aetey Global Technologies AB
+ * @author Cinepak colorspace, Rl, Aetey Global Technologies AB
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libavutil/common.h"
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "internal.h"
+
+
+typedef uint8_t cvid_codebook[12];
+
+#define MAX_STRIPS 32
+
+typedef struct cvid_strip {
+ uint16_t id;
+ uint16_t x1, y1;
+ uint16_t x2, y2;
+ cvid_codebook v4_codebook[256];
+ cvid_codebook v1_codebook[256];
+} cvid_strip;
+
+typedef struct CinepakContext {
+
+ AVCodecContext *avctx;
+ AVFrame *frame;
+
+ const unsigned char *data;
+ int size;
+
+ int width, height;
+
+ int palette_video;
+ cvid_strip strips[MAX_STRIPS];
+
+ int sega_film_skip_bytes;
+
+ uint32_t pal[256];
+} CinepakContext;
+
+static void cinepak_decode_codebook (cvid_codebook *codebook,
+ int chunk_id, int size, const uint8_t *data)
+{
+ const uint8_t *eod = (data + size);
+ uint32_t flag, mask;
+ int i, n;
+ uint8_t *p;
+
+ /* check if this chunk contains 4- or 6-element vectors */
+ n = (chunk_id & 0x04) ? 4 : 6;
+ flag = 0;
+ mask = 0;
+
+ p = codebook[0];
+ for (i=0; i < 256; i++) {
+ if ((chunk_id & 0x01) && !(mask >>= 1)) {
+ if ((data + 4) > eod)
+ break;
+
+ flag = AV_RB32 (data);
+ data += 4;
+ mask = 0x80000000;
+ }
+
+ if (!(chunk_id & 0x01) || (flag & mask)) {
+ int k, kk;
+
+ if ((data + n) > eod)
+ break;
+
+ for (k = 0; k < 4; ++k) {
+ int r = *data++;
+ for (kk = 0; kk < 3; ++kk)
+ *p++ = r;
+ }
+ if (n == 6) {
+ int r, g, b, u, v;
+ u = *(int8_t *)data++;
+ v = *(int8_t *)data++;
+ p -= 12;
+ for(k=0; k<4; ++k) {
+ r = *p++ + v*2;
+ g = *p++ - (u/2) - v;
+ b = *p + u*2;
+ p -= 2;
+ *p++ = av_clip_uint8(r);
+ *p++ = av_clip_uint8(g);
+ *p++ = av_clip_uint8(b);
+ }
+ }
+ } else {
+ p += 12;
+ }
+ }
+}
+
+static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip,
+ int chunk_id, int size, const uint8_t *data)
+{
+ const uint8_t *eod = (data + size);
+ uint32_t flag, mask;
+ uint8_t *cb0, *cb1, *cb2, *cb3;
+ int x, y;
+ char *ip0, *ip1, *ip2, *ip3;
+
+ flag = 0;
+ mask = 0;
+
+ for (y=strip->y1; y < strip->y2; y+=4) {
+
+/* take care of y dimension not being multiple of 4, such streams exist */
+ ip0 = ip1 = ip2 = ip3 = s->frame->data[0] +
+ (s->palette_video?strip->x1:strip->x1*3) + (y * s->frame->linesize[0]);
+ if(s->avctx->height - y > 1) {
+ ip1 = ip0 + s->frame->linesize[0];
+ if(s->avctx->height - y > 2) {
+ ip2 = ip1 + s->frame->linesize[0];
+ if(s->avctx->height - y > 3) {
+ ip3 = ip2 + s->frame->linesize[0];
+ }
+ }
+ }
+/* to get the correct picture for not-multiple-of-4 cases let us fill
+ * each block from the bottom up, thus possibly overwriting the top line
+ * more than once but ending with the correct data in place
+ * (instead of in-loop checking) */
+
+ for (x=strip->x1; x < strip->x2; x+=4) {
+ if ((chunk_id & 0x01) && !(mask >>= 1)) {
+ if ((data + 4) > eod)
+ return AVERROR_INVALIDDATA;
+
+ flag = AV_RB32 (data);
+ data += 4;
+ mask = 0x80000000;
+ }
+
+ if (!(chunk_id & 0x01) || (flag & mask)) {
+ if (!(chunk_id & 0x02) && !(mask >>= 1)) {
+ if ((data + 4) > eod)
+ return AVERROR_INVALIDDATA;
+
+ flag = AV_RB32 (data);
+ data += 4;
+ mask = 0x80000000;
+ }
+
+ if ((chunk_id & 0x02) || (~flag & mask)) {
+ uint8_t *p;
+ if (data >= eod)
+ return AVERROR_INVALIDDATA;
+
+ p = strip->v1_codebook[*data++];
+ if (s->palette_video) {
+ ip3[0] = ip3[1] = ip2[0] = ip2[1] = p[6];
+ ip3[2] = ip3[3] = ip2[2] = ip2[3] = p[9];
+ ip1[0] = ip1[1] = ip0[0] = ip0[1] = p[0];
+ ip1[2] = ip1[3] = ip0[2] = ip0[3] = p[3];
+ } else {
+ p += 6;
+ memcpy(ip3 + 0, p, 3); memcpy(ip3 + 3, p, 3);
+ memcpy(ip2 + 0, p, 3); memcpy(ip2 + 3, p, 3);
+ p += 3; /* ... + 9 */
+ memcpy(ip3 + 6, p, 3); memcpy(ip3 + 9, p, 3);
+ memcpy(ip2 + 6, p, 3); memcpy(ip2 + 9, p, 3);
+ p -= 9; /* ... + 0 */
+ memcpy(ip1 + 0, p, 3); memcpy(ip1 + 3, p, 3);
+ memcpy(ip0 + 0, p, 3); memcpy(ip0 + 3, p, 3);
+ p += 3; /* ... + 3 */
+ memcpy(ip1 + 6, p, 3); memcpy(ip1 + 9, p, 3);
+ memcpy(ip0 + 6, p, 3); memcpy(ip0 + 9, p, 3);
+ }
+
+ } else if (flag & mask) {
+ if ((data + 4) > eod)
+ return AVERROR_INVALIDDATA;
+
+ cb0 = strip->v4_codebook[*data++];
+ cb1 = strip->v4_codebook[*data++];
+ cb2 = strip->v4_codebook[*data++];
+ cb3 = strip->v4_codebook[*data++];
+ if (s->palette_video) {
+ uint8_t *p;
+ p = ip3;
+ *p++ = cb2[6];
+ *p++ = cb2[9];
+ *p++ = cb3[6];
+ *p = cb3[9];
+ p = ip2;
+ *p++ = cb2[0];
+ *p++ = cb2[3];
+ *p++ = cb3[0];
+ *p = cb3[3];
+ p = ip1;
+ *p++ = cb0[6];
+ *p++ = cb0[9];
+ *p++ = cb1[6];
+ *p = cb1[9];
+ p = ip0;
+ *p++ = cb0[0];
+ *p++ = cb0[3];
+ *p++ = cb1[0];
+ *p = cb1[3];
+ } else {
+ memcpy(ip3 + 0, cb2 + 6, 6);
+ memcpy(ip3 + 6, cb3 + 6, 6);
+ memcpy(ip2 + 0, cb2 + 0, 6);
+ memcpy(ip2 + 6, cb3 + 0, 6);
+ memcpy(ip1 + 0, cb0 + 6, 6);
+ memcpy(ip1 + 6, cb1 + 6, 6);
+ memcpy(ip0 + 0, cb0 + 0, 6);
+ memcpy(ip0 + 6, cb1 + 0, 6);
+ }
+
+ }
+ }
+
+ if (s->palette_video) {
+ ip0 += 4; ip1 += 4;
+ ip2 += 4; ip3 += 4;
+ } else {
+ ip0 += 12; ip1 += 12;
+ ip2 += 12; ip3 += 12;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int cinepak_decode_strip (CinepakContext *s,
+ cvid_strip *strip, const uint8_t *data, int size)
+{
+ const uint8_t *eod = (data + size);
+ int chunk_id, chunk_size;
+
+ /* coordinate sanity checks */
+ if (strip->x2 > s->width ||
+ strip->y2 > s->height ||
+ strip->x1 >= strip->x2 || strip->y1 >= strip->y2)
+ return AVERROR_INVALIDDATA;
+
+ while ((data + 4) <= eod) {
+ chunk_id = data[0];
+ chunk_size = AV_RB24 (&data[1]) - 4;
+ if(chunk_size < 0)
+ return AVERROR_INVALIDDATA;
+
+ data += 4;
+ chunk_size = ((data + chunk_size) > eod) ? (eod - data) : chunk_size;
+
+ switch (chunk_id) {
+
+ case 0x20:
+ case 0x21:
+ case 0x24:
+ case 0x25:
+ cinepak_decode_codebook (strip->v4_codebook, chunk_id,
+ chunk_size, data);
+ break;
+
+ case 0x22:
+ case 0x23:
+ case 0x26:
+ case 0x27:
+ cinepak_decode_codebook (strip->v1_codebook, chunk_id,
+ chunk_size, data);
+ break;
+
+ case 0x30:
+ case 0x31:
+ case 0x32:
+ return cinepak_decode_vectors (s, strip, chunk_id,
+ chunk_size, data);
+ }
+
+ data += chunk_size;
+ }
+
+ return AVERROR_INVALIDDATA;
+}
+
+static int cinepak_decode (CinepakContext *s)
+{
+ const uint8_t *eod = (s->data + s->size);
+ int i, result, strip_size, frame_flags, num_strips;
+ int y0 = 0;
+ int encoded_buf_size;
+
+ frame_flags = s->data[0];
+ num_strips = AV_RB16 (&s->data[8]);
+ encoded_buf_size = AV_RB24(&s->data[1]);
+
+ /* if this is the first frame, check for deviant Sega FILM data */
+ if (s->sega_film_skip_bytes == -1) {
+ if (!encoded_buf_size) {
+ avpriv_request_sample(s->avctx, "encoded_buf_size 0");
+ return AVERROR_PATCHWELCOME;
+ }
+ if (encoded_buf_size != s->size && (s->size % encoded_buf_size) != 0) {
+ /* If the encoded frame size differs from the frame size as indicated
+ * by the container file, this data likely comes from a Sega FILM/CPK file.
+ * If the frame header is followed by the bytes FE 00 00 06 00 00 then
+ * this is probably one of the two known files that have 6 extra bytes
+ * after the frame header. Else, assume 2 extra bytes. The container
+ * size also cannot be a multiple of the encoded size. */
+ if (s->size >= 16 &&
+ (s->data[10] == 0xFE) &&
+ (s->data[11] == 0x00) &&
+ (s->data[12] == 0x00) &&
+ (s->data[13] == 0x06) &&
+ (s->data[14] == 0x00) &&
+ (s->data[15] == 0x00))
+ s->sega_film_skip_bytes = 6;
+ else
+ s->sega_film_skip_bytes = 2;
+ } else
+ s->sega_film_skip_bytes = 0;
+ }
+
+ s->data += 10 + s->sega_film_skip_bytes;
+
+ num_strips = FFMIN(num_strips, MAX_STRIPS);
+
+ s->frame->key_frame = 0;
+
+ for (i=0; i < num_strips; i++) {
+ if ((s->data + 12) > eod)
+ return AVERROR_INVALIDDATA;
+
+ s->strips[i].id = s->data[0];
+/* zero y1 means "relative to the previous stripe" */
+ if (!(s->strips[i].y1 = AV_RB16 (&s->data[4])))
+ s->strips[i].y2 = (s->strips[i].y1 = y0) + AV_RB16 (&s->data[8]);
+ else
+ s->strips[i].y2 = AV_RB16 (&s->data[8]);
+ s->strips[i].x1 = AV_RB16 (&s->data[6]);
+ s->strips[i].x2 = AV_RB16 (&s->data[10]);
+
+ if (s->strips[i].id == 0x10)
+ s->frame->key_frame = 1;
+
+ strip_size = AV_RB24 (&s->data[1]) - 12;
+ if (strip_size < 0)
+ return AVERROR_INVALIDDATA;
+ s->data += 12;
+ strip_size = ((s->data + strip_size) > eod) ? (eod - s->data) : strip_size;
+
+ if ((i > 0) && !(frame_flags & 0x01)) {
+ memcpy (s->strips[i].v4_codebook, s->strips[i-1].v4_codebook,
+ sizeof(s->strips[i].v4_codebook));
+ memcpy (s->strips[i].v1_codebook, s->strips[i-1].v1_codebook,
+ sizeof(s->strips[i].v1_codebook));
+ }
+
+ result = cinepak_decode_strip (s, &s->strips[i], s->data, strip_size);
+
+ if (result != 0)
+ return result;
+
+ s->data += strip_size;
+ y0 = s->strips[i].y2;
+ }
+ return 0;
+}
+
+static av_cold int cinepak_decode_init(AVCodecContext *avctx)
+{
+ CinepakContext *s = avctx->priv_data;
+
+ s->avctx = avctx;
+ s->width = (avctx->width + 3) & ~3;
+ s->height = (avctx->height + 3) & ~3;
+
+ s->sega_film_skip_bytes = -1; /* uninitialized state */
+
+ // check for paletted data
+ if (avctx->bits_per_coded_sample != 8) {
+ s->palette_video = 0;
+ avctx->pix_fmt = AV_PIX_FMT_RGB24;
+ } else {
+ s->palette_video = 1;
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ }
+
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static int cinepak_decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int ret = 0, buf_size = avpkt->size;
+ CinepakContext *s = avctx->priv_data;
+
+ s->data = buf;
+ s->size = buf_size;
+
+ if (s->size < 10)
+ return AVERROR_INVALIDDATA;
+
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
+ return ret;
+
+ if (s->palette_video) {
+ int 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;
+ memcpy(s->pal, pal, AVPALETTE_SIZE);
+ } else if (pal) {
+ av_log(avctx, AV_LOG_ERROR, "Palette size %d is wrong\n", size);
+ }
+ }
+
+ if ((ret = cinepak_decode(s)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "cinepak_decode failed\n");
+ }
+
+ if (s->palette_video)
+ memcpy (s->frame->data[1], s->pal, AVPALETTE_SIZE);
+
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
+ return ret;
+
+ *got_frame = 1;
+
+ /* report that the buffer was completely consumed */
+ return buf_size;
+}
+
+static av_cold int cinepak_decode_end(AVCodecContext *avctx)
+{
+ CinepakContext *s = avctx->priv_data;
+
+ av_frame_free(&s->frame);
+
+ return 0;
+}
+
+AVCodec ff_cinepak_decoder = {
+ .name = "cinepak",
+ .long_name = NULL_IF_CONFIG_SMALL("Cinepak"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_CINEPAK,
+ .priv_data_size = sizeof(CinepakContext),
+ .init = cinepak_decode_init,
+ .close = cinepak_decode_end,
+ .decode = cinepak_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/cinepakenc.c b/ffmpeg-2-8-12/libavcodec/cinepakenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cinepakenc.c
rename to ffmpeg-2-8-12/libavcodec/cinepakenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/cljrdec.c b/ffmpeg-2-8-12/libavcodec/cljrdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cljrdec.c
rename to ffmpeg-2-8-12/libavcodec/cljrdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/cljrenc.c b/ffmpeg-2-8-12/libavcodec/cljrenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cljrenc.c
rename to ffmpeg-2-8-12/libavcodec/cljrenc.c
diff --git a/ffmpeg-2-8-12/libavcodec/cllc.c b/ffmpeg-2-8-12/libavcodec/cllc.c
new file mode 100644
index 0000000..97d3ae4
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/cllc.c
@@ -0,0 +1,514 @@
+/*
+ * Canopus Lossless Codec decoder
+ *
+ * Copyright (c) 2012-2013 Derek Buitenhuis
+ *
+ * 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 <inttypes.h>
+
+#include "libavutil/intreadwrite.h"
+#include "bswapdsp.h"
+#include "canopus.h"
+#include "get_bits.h"
+#include "avcodec.h"
+#include "internal.h"
+
+#define VLC_BITS 7
+#define VLC_DEPTH 2
+
+
+typedef struct CLLCContext {
+ AVCodecContext *avctx;
+ BswapDSPContext bdsp;
+
+ uint8_t *swapped_buf;
+ int swapped_buf_size;
+} CLLCContext;
+
+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 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;
+ }
+
+ for (i = 0; i < num_lens; i++) {
+ num_codes = get_bits(gb, 9);
+ 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;
+ }
+
+ 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);
+}
+
+/*
+ * Unlike the RGB24 read/restore, which reads in a component at a time,
+ * ARGB read/restore reads in ARGB quads.
+ */
+static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left,
+ VLC *vlc, uint8_t *outbuf)
+{
+ uint8_t *dst;
+ int pred[4];
+ int code;
+ int i;
+
+ OPEN_READER(bits, gb);
+
+ dst = outbuf;
+ pred[0] = top_left[0];
+ pred[1] = top_left[1];
+ pred[2] = top_left[2];
+ pred[3] = top_left[3];
+
+ for (i = 0; i < ctx->avctx->width; i++) {
+ /* Always get the alpha component */
+ UPDATE_CACHE(bits, gb);
+ GET_VLC(code, bits, gb, vlc[0].table, VLC_BITS, VLC_DEPTH);
+
+ pred[0] += code;
+ dst[0] = pred[0];
+
+ /* Skip the components if they are entirely transparent */
+ if (dst[0]) {
+ /* Red */
+ UPDATE_CACHE(bits, gb);
+ GET_VLC(code, bits, gb, vlc[1].table, VLC_BITS, VLC_DEPTH);
+
+ pred[1] += code;
+ dst[1] = pred[1];
+
+ /* Green */
+ UPDATE_CACHE(bits, gb);
+ GET_VLC(code, bits, gb, vlc[2].table, VLC_BITS, VLC_DEPTH);
+
+ pred[2] += code;
+ dst[2] = pred[2];
+
+ /* Blue */
+ UPDATE_CACHE(bits, gb);
+ GET_VLC(code, bits, gb, vlc[3].table, VLC_BITS, VLC_DEPTH);
+
+ pred[3] += code;
+ dst[3] = pred[3];
+ } else {
+ dst[1] = 0;
+ dst[2] = 0;
+ dst[3] = 0;
+ }
+
+ dst += 4;
+ }
+
+ CLOSE_READER(bits, gb);
+
+ top_left[0] = outbuf[0];
+
+ /* Only stash components if they are not transparent */
+ if (top_left[0]) {
+ top_left[1] = outbuf[1];
+ top_left[2] = outbuf[2];
+ top_left[3] = outbuf[3];
+ }
+
+ return 0;
+}
+
+static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb,
+ int *top_left, VLC *vlc, uint8_t *outbuf)
+{
+ uint8_t *dst;
+ int pred, code;
+ int i;
+
+ OPEN_READER(bits, gb);
+
+ dst = outbuf;
+ pred = *top_left;
+
+ /* Simultaneously read and restore the line */
+ for (i = 0; i < ctx->avctx->width; i++) {
+ UPDATE_CACHE(bits, gb);
+ GET_VLC(code, bits, gb, vlc->table, VLC_BITS, VLC_DEPTH);
+
+ pred += code;
+ dst[0] = pred;
+ dst += 3;
+ }
+
+ CLOSE_READER(bits, gb);
+
+ /* Stash the first pixel */
+ *top_left = outbuf[0];
+
+ return 0;
+}
+
+static int read_yuv_component_line(CLLCContext *ctx, GetBitContext *gb,
+ int *top_left, VLC *vlc, uint8_t *outbuf,
+ int is_chroma)
+{
+ int pred, code;
+ int i;
+
+ OPEN_READER(bits, gb);
+
+ pred = *top_left;
+
+ /* Simultaneously read and restore the line */
+ for (i = 0; i < ctx->avctx->width >> is_chroma; i++) {
+ UPDATE_CACHE(bits, gb);
+ GET_VLC(code, bits, gb, vlc->table, VLC_BITS, VLC_DEPTH);
+
+ pred += code;
+ outbuf[i] = pred;
+ }
+
+ CLOSE_READER(bits, gb);
+
+ /* Stash the first pixel */
+ *top_left = outbuf[0];
+
+ return 0;
+}
+
+static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
+{
+ AVCodecContext *avctx = ctx->avctx;
+ uint8_t *dst;
+ int pred[4];
+ int ret;
+ int i, j;
+ VLC vlc[4];
+
+ pred[0] = 0;
+ pred[1] = 0x80;
+ pred[2] = 0x80;
+ pred[3] = 0x80;
+
+ dst = pic->data[0];
+
+ skip_bits(gb, 16);
+
+ /* Read in code table for each plane */
+ for (i = 0; i < 4; i++) {
+ ret = read_code_table(ctx, gb, &vlc[i]);
+ if (ret < 0) {
+ for (j = 0; j <= i; j++)
+ ff_free_vlc(&vlc[j]);
+
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Could not read code table %d.\n", i);
+ return ret;
+ }
+ }
+
+ /* Read in and restore every line */
+ for (i = 0; i < avctx->height; i++) {
+ read_argb_line(ctx, gb, pred, vlc, dst);
+
+ dst += pic->linesize[0];
+ }
+
+ for (i = 0; i < 4; i++)
+ ff_free_vlc(&vlc[i]);
+
+ return 0;
+}
+
+static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
+{
+ AVCodecContext *avctx = ctx->avctx;
+ uint8_t *dst;
+ int pred[3];
+ int ret;
+ int i, j;
+ VLC vlc[3];
+
+ pred[0] = 0x80;
+ pred[1] = 0x80;
+ pred[2] = 0x80;
+
+ dst = pic->data[0];
+
+ skip_bits(gb, 16);
+
+ /* Read in code table for each plane */
+ for (i = 0; i < 3; i++) {
+ ret = read_code_table(ctx, gb, &vlc[i]);
+ if (ret < 0) {
+ for (j = 0; j <= i; j++)
+ ff_free_vlc(&vlc[j]);
+
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Could not read code table %d.\n", i);
+ return ret;
+ }
+ }
+
+ /* Read in and restore every line */
+ for (i = 0; i < avctx->height; i++) {
+ for (j = 0; j < 3; j++)
+ read_rgb24_component_line(ctx, gb, &pred[j], &vlc[j], &dst[j]);
+
+ dst += pic->linesize[0];
+ }
+
+ for (i = 0; i < 3; i++)
+ ff_free_vlc(&vlc[i]);
+
+ return 0;
+}
+
+static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
+{
+ AVCodecContext *avctx = ctx->avctx;
+ uint8_t block;
+ uint8_t *dst[3];
+ int pred[3];
+ int ret;
+ int i, j;
+ VLC vlc[2];
+
+ pred[0] = 0x80;
+ pred[1] = 0x80;
+ pred[2] = 0x80;
+
+ dst[0] = pic->data[0];
+ dst[1] = pic->data[1];
+ dst[2] = pic->data[2];
+
+ skip_bits(gb, 8);
+
+ block = get_bits(gb, 8);
+ if (block) {
+ avpriv_request_sample(ctx->avctx, "Blocked YUV");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ /* Read in code table for luma and chroma */
+ for (i = 0; i < 2; i++) {
+ ret = read_code_table(ctx, gb, &vlc[i]);
+ if (ret < 0) {
+ for (j = 0; j <= i; j++)
+ ff_free_vlc(&vlc[j]);
+
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Could not read code table %d.\n", i);
+ return ret;
+ }
+ }
+
+ /* Read in and restore every line */
+ for (i = 0; i < avctx->height; i++) {
+ read_yuv_component_line(ctx, gb, &pred[0], &vlc[0], dst[0], 0); /* Y */
+ read_yuv_component_line(ctx, gb, &pred[1], &vlc[1], dst[1], 1); /* U */
+ read_yuv_component_line(ctx, gb, &pred[2], &vlc[1], dst[2], 1); /* V */
+
+ for (j = 0; j < 3; j++)
+ dst[j] += pic->linesize[j];
+ }
+
+ for (i = 0; i < 2; i++)
+ ff_free_vlc(&vlc[i]);
+
+ return 0;
+}
+
+static int cllc_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_picture_ptr, AVPacket *avpkt)
+{
+ CLLCContext *ctx = avctx->priv_data;
+ AVFrame *pic = data;
+ uint8_t *src = avpkt->data;
+ uint32_t info_tag, info_offset;
+ int data_size;
+ GetBitContext gb;
+ int coding_type, ret;
+
+ if (avpkt->size < 4 + 4) {
+ av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ info_offset = 0;
+ info_tag = AV_RL32(src);
+ if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
+ info_offset = AV_RL32(src + 4);
+ if (info_offset > UINT32_MAX - 8 || info_offset + 8 > avpkt->size) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n",
+ info_offset);
+ return AVERROR_INVALIDDATA;
+ }
+ ff_canopus_parse_info_tag(avctx, src + 8, info_offset);
+
+ info_offset += 8;
+ src += info_offset;
+ }
+
+ data_size = (avpkt->size - info_offset) & ~1;
+
+ /* Make sure our bswap16'd buffer is big enough */
+ av_fast_padded_malloc(&ctx->swapped_buf,
+ &ctx->swapped_buf_size, data_size);
+ if (!ctx->swapped_buf) {
+ av_log(avctx, AV_LOG_ERROR, "Could not allocate swapped buffer.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ /* bswap16 the buffer since CLLC's bitreader works in 16-bit words */
+ ctx->bdsp.bswap16_buf((uint16_t *) ctx->swapped_buf, (uint16_t *) src,
+ data_size / 2);
+
+ if ((ret = init_get_bits8(&gb, ctx->swapped_buf, data_size)) < 0)
+ return ret;
+
+ /*
+ * Read in coding type. The types are as follows:
+ *
+ * 0 - YUY2
+ * 1 - BGR24 (Triples)
+ * 2 - BGR24 (Quads)
+ * 3 - BGRA
+ */
+ coding_type = (AV_RL32(src) >> 8) & 0xFF;
+ av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type);
+
+ switch (coding_type) {
+ case 0:
+ avctx->pix_fmt = AV_PIX_FMT_YUV422P;
+ avctx->bits_per_raw_sample = 8;
+
+ if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
+ return ret;
+
+ ret = decode_yuv_frame(ctx, &gb, pic);
+ if (ret < 0)
+ return ret;
+
+ break;
+ case 1:
+ case 2:
+ avctx->pix_fmt = AV_PIX_FMT_RGB24;
+ avctx->bits_per_raw_sample = 8;
+
+ if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
+ return ret;
+
+ ret = decode_rgb24_frame(ctx, &gb, pic);
+ if (ret < 0)
+ return ret;
+
+ break;
+ case 3:
+ avctx->pix_fmt = AV_PIX_FMT_ARGB;
+ avctx->bits_per_raw_sample = 8;
+
+ if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
+ return ret;
+
+ ret = decode_argb_frame(ctx, &gb, pic);
+ if (ret < 0)
+ return ret;
+
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Unknown coding type: %d.\n", coding_type);
+ return AVERROR_INVALIDDATA;
+ }
+
+ pic->key_frame = 1;
+ pic->pict_type = AV_PICTURE_TYPE_I;
+
+ *got_picture_ptr = 1;
+
+ return avpkt->size;
+}
+
+static av_cold int cllc_decode_close(AVCodecContext *avctx)
+{
+ CLLCContext *ctx = avctx->priv_data;
+
+ av_freep(&ctx->swapped_buf);
+
+ return 0;
+}
+
+static av_cold int cllc_decode_init(AVCodecContext *avctx)
+{
+ CLLCContext *ctx = avctx->priv_data;
+
+ /* Initialize various context values */
+ ctx->avctx = avctx;
+ ctx->swapped_buf = NULL;
+ ctx->swapped_buf_size = 0;
+
+ ff_bswapdsp_init(&ctx->bdsp);
+
+ return 0;
+}
+
+AVCodec ff_cllc_decoder = {
+ .name = "cllc",
+ .long_name = NULL_IF_CONFIG_SMALL("Canopus Lossless Codec"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_CLLC,
+ .priv_data_size = sizeof(CLLCContext),
+ .init = cllc_decode_init,
+ .decode = cllc_decode_frame,
+ .close = cllc_decode_close,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/cngdec.c b/ffmpeg-2-8-12/libavcodec/cngdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cngdec.c
rename to ffmpeg-2-8-12/libavcodec/cngdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/cngenc.c b/ffmpeg-2-8-12/libavcodec/cngenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cngenc.c
rename to ffmpeg-2-8-12/libavcodec/cngenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/codec_desc.c b/ffmpeg-2-8-12/libavcodec/codec_desc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/codec_desc.c
rename to ffmpeg-2-8-12/libavcodec/codec_desc.c
diff --git a/ffmpeg-2-8-11/libavcodec/cook.c b/ffmpeg-2-8-12/libavcodec/cook.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cook.c
rename to ffmpeg-2-8-12/libavcodec/cook.c
diff --git a/ffmpeg-2-8-11/libavcodec/cook_parser.c b/ffmpeg-2-8-12/libavcodec/cook_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cook_parser.c
rename to ffmpeg-2-8-12/libavcodec/cook_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/cookdata.h b/ffmpeg-2-8-12/libavcodec/cookdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cookdata.h
rename to ffmpeg-2-8-12/libavcodec/cookdata.h
diff --git a/ffmpeg-2-8-11/libavcodec/copy_block.h b/ffmpeg-2-8-12/libavcodec/copy_block.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/copy_block.h
rename to ffmpeg-2-8-12/libavcodec/copy_block.h
diff --git a/ffmpeg-2-8-11/libavcodec/cos_tablegen.c b/ffmpeg-2-8-12/libavcodec/cos_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cos_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/cos_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/cpia.c b/ffmpeg-2-8-12/libavcodec/cpia.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cpia.c
rename to ffmpeg-2-8-12/libavcodec/cpia.c
diff --git a/ffmpeg-2-8-11/libavcodec/crystalhd.c b/ffmpeg-2-8-12/libavcodec/crystalhd.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/crystalhd.c
rename to ffmpeg-2-8-12/libavcodec/crystalhd.c
diff --git a/ffmpeg-2-8-11/libavcodec/cscd.c b/ffmpeg-2-8-12/libavcodec/cscd.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cscd.c
rename to ffmpeg-2-8-12/libavcodec/cscd.c
diff --git a/ffmpeg-2-8-11/libavcodec/cyuv.c b/ffmpeg-2-8-12/libavcodec/cyuv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/cyuv.c
rename to ffmpeg-2-8-12/libavcodec/cyuv.c
diff --git a/ffmpeg-2-8-11/libavcodec/d3d11va.h b/ffmpeg-2-8-12/libavcodec/d3d11va.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/d3d11va.h
rename to ffmpeg-2-8-12/libavcodec/d3d11va.h
diff --git a/ffmpeg-2-8-11/libavcodec/dca.c b/ffmpeg-2-8-12/libavcodec/dca.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dca.c
rename to ffmpeg-2-8-12/libavcodec/dca.c
diff --git a/ffmpeg-2-8-11/libavcodec/dca.h b/ffmpeg-2-8-12/libavcodec/dca.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dca.h
rename to ffmpeg-2-8-12/libavcodec/dca.h
diff --git a/ffmpeg-2-8-11/libavcodec/dca_exss.c b/ffmpeg-2-8-12/libavcodec/dca_exss.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dca_exss.c
rename to ffmpeg-2-8-12/libavcodec/dca_exss.c
diff --git a/ffmpeg-2-8-11/libavcodec/dca_parser.c b/ffmpeg-2-8-12/libavcodec/dca_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dca_parser.c
rename to ffmpeg-2-8-12/libavcodec/dca_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/dca_syncwords.h b/ffmpeg-2-8-12/libavcodec/dca_syncwords.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dca_syncwords.h
rename to ffmpeg-2-8-12/libavcodec/dca_syncwords.h
diff --git a/ffmpeg-2-8-11/libavcodec/dca_xll.c b/ffmpeg-2-8-12/libavcodec/dca_xll.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dca_xll.c
rename to ffmpeg-2-8-12/libavcodec/dca_xll.c
diff --git a/ffmpeg-2-8-11/libavcodec/dcadata.c b/ffmpeg-2-8-12/libavcodec/dcadata.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dcadata.c
rename to ffmpeg-2-8-12/libavcodec/dcadata.c
diff --git a/ffmpeg-2-8-11/libavcodec/dcadata.h b/ffmpeg-2-8-12/libavcodec/dcadata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dcadata.h
rename to ffmpeg-2-8-12/libavcodec/dcadata.h
diff --git a/ffmpeg-2-8-11/libavcodec/dcadec.c b/ffmpeg-2-8-12/libavcodec/dcadec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dcadec.c
rename to ffmpeg-2-8-12/libavcodec/dcadec.c
diff --git a/ffmpeg-2-8-11/libavcodec/dcadsp.c b/ffmpeg-2-8-12/libavcodec/dcadsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dcadsp.c
rename to ffmpeg-2-8-12/libavcodec/dcadsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/dcadsp.h b/ffmpeg-2-8-12/libavcodec/dcadsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dcadsp.h
rename to ffmpeg-2-8-12/libavcodec/dcadsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/dcaenc.c b/ffmpeg-2-8-12/libavcodec/dcaenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dcaenc.c
rename to ffmpeg-2-8-12/libavcodec/dcaenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/dcaenc.h b/ffmpeg-2-8-12/libavcodec/dcaenc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dcaenc.h
rename to ffmpeg-2-8-12/libavcodec/dcaenc.h
diff --git a/ffmpeg-2-8-11/libavcodec/dcahuff.h b/ffmpeg-2-8-12/libavcodec/dcahuff.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dcahuff.h
rename to ffmpeg-2-8-12/libavcodec/dcahuff.h
diff --git a/ffmpeg-2-8-11/libavcodec/dct-test.c b/ffmpeg-2-8-12/libavcodec/dct-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dct-test.c
rename to ffmpeg-2-8-12/libavcodec/dct-test.c
diff --git a/ffmpeg-2-8-11/libavcodec/dct.c b/ffmpeg-2-8-12/libavcodec/dct.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dct.c
rename to ffmpeg-2-8-12/libavcodec/dct.c
diff --git a/ffmpeg-2-8-11/libavcodec/dct.h b/ffmpeg-2-8-12/libavcodec/dct.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dct.h
rename to ffmpeg-2-8-12/libavcodec/dct.h
diff --git a/ffmpeg-2-8-11/libavcodec/dct32.h b/ffmpeg-2-8-12/libavcodec/dct32.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dct32.h
rename to ffmpeg-2-8-12/libavcodec/dct32.h
diff --git a/ffmpeg-2-8-11/libavcodec/dct32_fixed.c b/ffmpeg-2-8-12/libavcodec/dct32_fixed.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dct32_fixed.c
rename to ffmpeg-2-8-12/libavcodec/dct32_fixed.c
diff --git a/ffmpeg-2-8-11/libavcodec/dct32_float.c b/ffmpeg-2-8-12/libavcodec/dct32_float.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dct32_float.c
rename to ffmpeg-2-8-12/libavcodec/dct32_float.c
diff --git a/ffmpeg-2-8-11/libavcodec/dct32_template.c b/ffmpeg-2-8-12/libavcodec/dct32_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dct32_template.c
rename to ffmpeg-2-8-12/libavcodec/dct32_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/dctref.c b/ffmpeg-2-8-12/libavcodec/dctref.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dctref.c
rename to ffmpeg-2-8-12/libavcodec/dctref.c
diff --git a/ffmpeg-2-8-11/libavcodec/dctref.h b/ffmpeg-2-8-12/libavcodec/dctref.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dctref.h
rename to ffmpeg-2-8-12/libavcodec/dctref.h
diff --git a/ffmpeg-2-8-12/libavcodec/dds.c b/ffmpeg-2-8-12/libavcodec/dds.c
new file mode 100644
index 0000000..02051b8
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/dds.c
@@ -0,0 +1,720 @@
+/*
+ * DirectDraw Surface image decoder
+ * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * DDS decoder
+ *
+ * https://msdn.microsoft.com/en-us/library/bb943982%28v=vs.85%29.aspx
+ */
+
+#include <stdint.h>
+
+#include "libavutil/imgutils.h"
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+#include "texturedsp.h"
+#include "thread.h"
+
+#define DDPF_FOURCC (1 << 2)
+#define DDPF_PALETTE (1 << 5)
+#define DDPF_NORMALMAP (1U << 31)
+
+enum DDSPostProc {
+ DDS_NONE = 0,
+ DDS_ALPHA_EXP,
+ DDS_NORMAL_MAP,
+ DDS_RAW_YCOCG,
+ DDS_SWAP_ALPHA,
+ DDS_SWIZZLE_A2XY,
+ DDS_SWIZZLE_RBXG,
+ DDS_SWIZZLE_RGXB,
+ DDS_SWIZZLE_RXBG,
+ DDS_SWIZZLE_RXGB,
+ DDS_SWIZZLE_XGBR,
+ DDS_SWIZZLE_XRBG,
+ DDS_SWIZZLE_XGXR,
+};
+
+enum DDSDXGIFormat {
+ DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
+ DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
+ DXGI_FORMAT_R16G16B16A16_UNORM = 11,
+ DXGI_FORMAT_R16G16B16A16_UINT = 12,
+ DXGI_FORMAT_R16G16B16A16_SNORM = 13,
+ DXGI_FORMAT_R16G16B16A16_SINT = 14,
+
+ DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
+ DXGI_FORMAT_R8G8B8A8_UNORM = 28,
+ DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
+ DXGI_FORMAT_R8G8B8A8_UINT = 30,
+ DXGI_FORMAT_R8G8B8A8_SNORM = 31,
+ DXGI_FORMAT_R8G8B8A8_SINT = 32,
+
+ DXGI_FORMAT_BC1_TYPELESS = 70,
+ DXGI_FORMAT_BC1_UNORM = 71,
+ DXGI_FORMAT_BC1_UNORM_SRGB = 72,
+ DXGI_FORMAT_BC2_TYPELESS = 73,
+ DXGI_FORMAT_BC2_UNORM = 74,
+ DXGI_FORMAT_BC2_UNORM_SRGB = 75,
+ DXGI_FORMAT_BC3_TYPELESS = 76,
+ DXGI_FORMAT_BC3_UNORM = 77,
+ DXGI_FORMAT_BC3_UNORM_SRGB = 78,
+ DXGI_FORMAT_BC4_TYPELESS = 79,
+ DXGI_FORMAT_BC4_UNORM = 80,
+ DXGI_FORMAT_BC4_SNORM = 81,
+ DXGI_FORMAT_BC5_TYPELESS = 82,
+ DXGI_FORMAT_BC5_UNORM = 83,
+ DXGI_FORMAT_BC5_SNORM = 84,
+ DXGI_FORMAT_B5G6R5_UNORM = 85,
+ DXGI_FORMAT_B8G8R8A8_UNORM = 87,
+ DXGI_FORMAT_B8G8R8X8_UNORM = 88,
+ DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
+ DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
+ DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
+ DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
+};
+
+typedef struct DDSContext {
+ TextureDSPContext texdsp;
+ GetByteContext gbc;
+
+ int compressed;
+ int paletted;
+ enum DDSPostProc postproc;
+
+ const uint8_t *tex_data; // Compressed texture
+ int tex_ratio; // Compression ratio
+ int slice_count; // Number of slices for threaded operations
+
+ /* Pointer to the selected compress or decompress function. */
+ int (*tex_funct)(uint8_t *dst, ptrdiff_t stride, const uint8_t *block);
+} DDSContext;
+
+static int parse_pixel_format(AVCodecContext *avctx)
+{
+ DDSContext *ctx = avctx->priv_data;
+ GetByteContext *gbc = &ctx->gbc;
+ char buf[32];
+ uint32_t flags, fourcc, gimp_tag;
+ enum DDSDXGIFormat dxgi;
+ int size, bpp, r, g, b, a;
+ int alpha_exponent, ycocg_classic, ycocg_scaled, normal_map, array;
+
+ /* Alternative DDS implementations use reserved1 as custom header. */
+ bytestream2_skip(gbc, 4 * 3);
+ gimp_tag = bytestream2_get_le32(gbc);
+ alpha_exponent = gimp_tag == MKTAG('A', 'E', 'X', 'P');
+ ycocg_classic = gimp_tag == MKTAG('Y', 'C', 'G', '1');
+ ycocg_scaled = gimp_tag == MKTAG('Y', 'C', 'G', '2');
+ bytestream2_skip(gbc, 4 * 7);
+
+ /* Now the real DDPF starts. */
+ size = bytestream2_get_le32(gbc);
+ if (size != 32) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid pixel format header %d.\n", size);
+ return AVERROR_INVALIDDATA;
+ }
+ flags = bytestream2_get_le32(gbc);
+ ctx->compressed = flags & DDPF_FOURCC;
+ ctx->paletted = flags & DDPF_PALETTE;
+ normal_map = flags & DDPF_NORMALMAP;
+ fourcc = bytestream2_get_le32(gbc);
+
+ if (ctx->compressed && ctx->paletted) {
+ av_log(avctx, AV_LOG_WARNING,
+ "Disabling invalid palette flag for compressed dds.\n");
+ ctx->paletted = 0;
+ }
+
+ bpp = bytestream2_get_le32(gbc); // rgbbitcount
+ r = bytestream2_get_le32(gbc); // rbitmask
+ g = bytestream2_get_le32(gbc); // gbitmask
+ b = bytestream2_get_le32(gbc); // bbitmask
+ a = bytestream2_get_le32(gbc); // abitmask
+
+ bytestream2_skip(gbc, 4); // caps
+ bytestream2_skip(gbc, 4); // caps2
+ bytestream2_skip(gbc, 4); // caps3
+ bytestream2_skip(gbc, 4); // caps4
+ bytestream2_skip(gbc, 4); // reserved2
+
+ av_get_codec_tag_string(buf, sizeof(buf), fourcc);
+ av_log(avctx, AV_LOG_VERBOSE, "fourcc %s bpp %d "
+ "r 0x%x g 0x%x b 0x%x a 0x%x\n", buf, bpp, r, g, b, a);
+ if (gimp_tag) {
+ av_get_codec_tag_string(buf, sizeof(buf), gimp_tag);
+ av_log(avctx, AV_LOG_VERBOSE, "and GIMP-DDS tag %s\n", buf);
+ }
+
+ if (ctx->compressed)
+ avctx->pix_fmt = AV_PIX_FMT_RGBA;
+
+ if (ctx->compressed) {
+ switch (fourcc) {
+ case MKTAG('D', 'X', 'T', '1'):
+ ctx->tex_ratio = 8;
+ ctx->tex_funct = ctx->texdsp.dxt1a_block;
+ break;
+ case MKTAG('D', 'X', 'T', '2'):
+ ctx->tex_ratio = 16;
+ ctx->tex_funct = ctx->texdsp.dxt2_block;
+ break;
+ case MKTAG('D', 'X', 'T', '3'):
+ ctx->tex_ratio = 16;
+ ctx->tex_funct = ctx->texdsp.dxt3_block;
+ break;
+ case MKTAG('D', 'X', 'T', '4'):
+ ctx->tex_ratio = 16;
+ ctx->tex_funct = ctx->texdsp.dxt4_block;
+ break;
+ case MKTAG('D', 'X', 'T', '5'):
+ ctx->tex_ratio = 16;
+ if (ycocg_scaled)
+ ctx->tex_funct = ctx->texdsp.dxt5ys_block;
+ else if (ycocg_classic)
+ ctx->tex_funct = ctx->texdsp.dxt5y_block;
+ else
+ ctx->tex_funct = ctx->texdsp.dxt5_block;
+ break;
+ case MKTAG('R', 'X', 'G', 'B'):
+ ctx->tex_ratio = 16;
+ ctx->tex_funct = ctx->texdsp.dxt5_block;
+ /* This format may be considered as a normal map,
+ * but it is handled differently in a separate postproc. */
+ ctx->postproc = DDS_SWIZZLE_RXGB;
+ normal_map = 0;
+ break;
+ case MKTAG('A', 'T', 'I', '1'):
+ case MKTAG('B', 'C', '4', 'U'):
+ ctx->tex_ratio = 8;
+ ctx->tex_funct = ctx->texdsp.rgtc1u_block;
+ break;
+ case MKTAG('B', 'C', '4', 'S'):
+ ctx->tex_ratio = 8;
+ ctx->tex_funct = ctx->texdsp.rgtc1s_block;
+ break;
+ case MKTAG('A', 'T', 'I', '2'):
+ /* RGT2 variant with swapped R and G (3Dc)*/
+ ctx->tex_ratio = 16;
+ ctx->tex_funct = ctx->texdsp.dxn3dc_block;
+ break;
+ case MKTAG('B', 'C', '5', 'U'):
+ ctx->tex_ratio = 16;
+ ctx->tex_funct = ctx->texdsp.rgtc2u_block;
+ break;
+ case MKTAG('B', 'C', '5', 'S'):
+ ctx->tex_ratio = 16;
+ ctx->tex_funct = ctx->texdsp.rgtc2s_block;
+ break;
+ case MKTAG('U', 'Y', 'V', 'Y'):
+ ctx->compressed = 0;
+ avctx->pix_fmt = AV_PIX_FMT_UYVY422;
+ break;
+ case MKTAG('Y', 'U', 'Y', '2'):
+ ctx->compressed = 0;
+ avctx->pix_fmt = AV_PIX_FMT_YUYV422;
+ break;
+ case MKTAG('P', '8', ' ', ' '):
+ /* ATI Palette8, same as normal palette */
+ ctx->compressed = 0;
+ ctx->paletted = 1;
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ break;
+ case MKTAG('D', 'X', '1', '0'):
+ /* DirectX 10 extra header */
+ dxgi = bytestream2_get_le32(gbc);
+ bytestream2_skip(gbc, 4); // resourceDimension
+ bytestream2_skip(gbc, 4); // miscFlag
+ array = bytestream2_get_le32(gbc);
+ bytestream2_skip(gbc, 4); // miscFlag2
+
+ if (array != 0)
+ av_log(avctx, AV_LOG_VERBOSE,
+ "Found array of size %d (ignored).\n", array);
+
+ /* Only BC[1-5] are actually compressed. */
+ ctx->compressed = (dxgi >= 70) && (dxgi <= 84);
+
+ av_log(avctx, AV_LOG_VERBOSE, "DXGI format %d.\n", dxgi);
+ switch (dxgi) {
+ /* RGB types. */
+ case DXGI_FORMAT_R16G16B16A16_TYPELESS:
+ case DXGI_FORMAT_R16G16B16A16_FLOAT:
+ case DXGI_FORMAT_R16G16B16A16_UNORM:
+ case DXGI_FORMAT_R16G16B16A16_UINT:
+ case DXGI_FORMAT_R16G16B16A16_SNORM:
+ case DXGI_FORMAT_R16G16B16A16_SINT:
+ avctx->pix_fmt = AV_PIX_FMT_BGRA64;
+ break;
+ case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
+ avctx->colorspace = AVCOL_SPC_RGB;
+ case DXGI_FORMAT_R8G8B8A8_TYPELESS:
+ case DXGI_FORMAT_R8G8B8A8_UNORM:
+ case DXGI_FORMAT_R8G8B8A8_UINT:
+ case DXGI_FORMAT_R8G8B8A8_SNORM:
+ case DXGI_FORMAT_R8G8B8A8_SINT:
+ avctx->pix_fmt = AV_PIX_FMT_BGRA;
+ break;
+ case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
+ avctx->colorspace = AVCOL_SPC_RGB;
+ case DXGI_FORMAT_B8G8R8A8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8A8_UNORM:
+ avctx->pix_fmt = AV_PIX_FMT_RGBA;
+ break;
+ case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
+ avctx->colorspace = AVCOL_SPC_RGB;
+ case DXGI_FORMAT_B8G8R8X8_TYPELESS:
+ case DXGI_FORMAT_B8G8R8X8_UNORM:
+ avctx->pix_fmt = AV_PIX_FMT_RGBA; // opaque
+ break;
+ case DXGI_FORMAT_B5G6R5_UNORM:
+ avctx->pix_fmt = AV_PIX_FMT_RGB565LE;
+ break;
+ /* Texture types. */
+ case DXGI_FORMAT_BC1_UNORM_SRGB:
+ avctx->colorspace = AVCOL_SPC_RGB;
+ case DXGI_FORMAT_BC1_TYPELESS:
+ case DXGI_FORMAT_BC1_UNORM:
+ ctx->tex_ratio = 8;
+ ctx->tex_funct = ctx->texdsp.dxt1a_block;
+ break;
+ case DXGI_FORMAT_BC2_UNORM_SRGB:
+ avctx->colorspace = AVCOL_SPC_RGB;
+ case DXGI_FORMAT_BC2_TYPELESS:
+ case DXGI_FORMAT_BC2_UNORM:
+ ctx->tex_ratio = 16;
+ ctx->tex_funct = ctx->texdsp.dxt3_block;
+ break;
+ case DXGI_FORMAT_BC3_UNORM_SRGB:
+ avctx->colorspace = AVCOL_SPC_RGB;
+ case DXGI_FORMAT_BC3_TYPELESS:
+ case DXGI_FORMAT_BC3_UNORM:
+ ctx->tex_ratio = 16;
+ ctx->tex_funct = ctx->texdsp.dxt5_block;
+ break;
+ case DXGI_FORMAT_BC4_TYPELESS:
+ case DXGI_FORMAT_BC4_UNORM:
+ ctx->tex_ratio = 8;
+ ctx->tex_funct = ctx->texdsp.rgtc1u_block;
+ break;
+ case DXGI_FORMAT_BC4_SNORM:
+ ctx->tex_ratio = 8;
+ ctx->tex_funct = ctx->texdsp.rgtc1s_block;
+ break;
+ case DXGI_FORMAT_BC5_TYPELESS:
+ case DXGI_FORMAT_BC5_UNORM:
+ ctx->tex_ratio = 16;
+ ctx->tex_funct = ctx->texdsp.rgtc2u_block;
+ break;
+ case DXGI_FORMAT_BC5_SNORM:
+ ctx->tex_ratio = 16;
+ ctx->tex_funct = ctx->texdsp.rgtc2s_block;
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR,
+ "Unsupported DXGI format %d.\n", dxgi);
+ return AVERROR_INVALIDDATA;
+ }
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Unsupported %s fourcc.\n", buf);
+ return AVERROR_INVALIDDATA;
+ }
+ } else if (ctx->paletted) {
+ if (bpp == 8) {
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "Unsupported palette bpp %d.\n", bpp);
+ return AVERROR_INVALIDDATA;
+ }
+ } else {
+ /* 8 bpp */
+ if (bpp == 8 && r == 0xff && g == 0 && b == 0 && a == 0)
+ avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+ /* 16 bpp */
+ else if (bpp == 16 && r == 0xff && g == 0 && b == 0 && a == 0xff00)
+ avctx->pix_fmt = AV_PIX_FMT_YA8;
+ else if (bpp == 16 && r == 0xffff && g == 0 && b == 0 && a == 0)
+ avctx->pix_fmt = AV_PIX_FMT_GRAY16LE;
+ else if (bpp == 16 && r == 0xf800 && g == 0x7e0 && b == 0x1f && a == 0)
+ avctx->pix_fmt = AV_PIX_FMT_RGB565LE;
+ /* 24 bpp */
+ else if (bpp == 24 && r == 0xff0000 && g == 0xff00 && b == 0xff && a == 0)
+ avctx->pix_fmt = AV_PIX_FMT_BGR24;
+ /* 32 bpp */
+ else if (bpp == 32 && r == 0xff0000 && g == 0xff00 && b == 0xff && a == 0)
+ avctx->pix_fmt = AV_PIX_FMT_BGR0; // opaque
+ else if (bpp == 32 && r == 0xff && g == 0xff00 && b == 0xff0000 && a == 0)
+ avctx->pix_fmt = AV_PIX_FMT_RGB0; // opaque
+ else if (bpp == 32 && r == 0xff0000 && g == 0xff00 && b == 0xff && a == 0xff000000)
+ avctx->pix_fmt = AV_PIX_FMT_BGRA;
+ else if (bpp == 32 && r == 0xff && g == 0xff00 && b == 0xff0000 && a == 0xff000000)
+ avctx->pix_fmt = AV_PIX_FMT_RGBA;
+ /* give up */
+ else {
+ av_log(avctx, AV_LOG_ERROR, "Unknown pixel format "
+ "[bpp %d r 0x%x g 0x%x b 0x%x a 0x%x].\n", bpp, r, g, b, a);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ /* Set any remaining post-proc that should happen before frame is ready. */
+ if (alpha_exponent)
+ ctx->postproc = DDS_ALPHA_EXP;
+ else if (normal_map)
+ ctx->postproc = DDS_NORMAL_MAP;
+ else if (ycocg_classic && !ctx->compressed)
+ ctx->postproc = DDS_RAW_YCOCG;
+ else if (avctx->pix_fmt == AV_PIX_FMT_YA8)
+ ctx->postproc = DDS_SWAP_ALPHA;
+
+ /* ATI/NVidia variants sometimes add swizzling in bpp. */
+ switch (bpp) {
+ case MKTAG('A', '2', 'X', 'Y'):
+ ctx->postproc = DDS_SWIZZLE_A2XY;
+ break;
+ case MKTAG('x', 'G', 'B', 'R'):
+ ctx->postproc = DDS_SWIZZLE_XGBR;
+ break;
+ case MKTAG('x', 'R', 'B', 'G'):
+ ctx->postproc = DDS_SWIZZLE_XRBG;
+ break;
+ case MKTAG('R', 'B', 'x', 'G'):
+ ctx->postproc = DDS_SWIZZLE_RBXG;
+ break;
+ case MKTAG('R', 'G', 'x', 'B'):
+ ctx->postproc = DDS_SWIZZLE_RGXB;
+ break;
+ case MKTAG('R', 'x', 'B', 'G'):
+ ctx->postproc = DDS_SWIZZLE_RXBG;
+ break;
+ case MKTAG('x', 'G', 'x', 'R'):
+ ctx->postproc = DDS_SWIZZLE_XGXR;
+ break;
+ case MKTAG('A', '2', 'D', '5'):
+ ctx->postproc = DDS_NORMAL_MAP;
+ break;
+ }
+
+ return 0;
+}
+
+static int decompress_texture_thread(AVCodecContext *avctx, void *arg,
+ int slice, int thread_nb)
+{
+ DDSContext *ctx = avctx->priv_data;
+ AVFrame *frame = arg;
+ const uint8_t *d = ctx->tex_data;
+ int w_block = avctx->coded_width / TEXTURE_BLOCK_W;
+ int h_block = avctx->coded_height / TEXTURE_BLOCK_H;
+ int x, y;
+ int start_slice, end_slice;
+ int base_blocks_per_slice = h_block / ctx->slice_count;
+ int remainder_blocks = h_block % ctx->slice_count;
+
+ /* When the frame height (in blocks) doesn't divide evenly between the
+ * number of slices, spread the remaining blocks evenly between the first
+ * operations */
+ start_slice = slice * base_blocks_per_slice;
+ /* Add any extra blocks (one per slice) that have been added before this slice */
+ start_slice += FFMIN(slice, remainder_blocks);
+
+ end_slice = start_slice + base_blocks_per_slice;
+ /* Add an extra block if there are still remainder blocks to be accounted for */
+ if (slice < remainder_blocks)
+ end_slice++;
+
+ for (y = start_slice; y < end_slice; y++) {
+ uint8_t *p = frame->data[0] + y * frame->linesize[0] * TEXTURE_BLOCK_H;
+ int off = y * w_block;
+ for (x = 0; x < w_block; x++) {
+ ctx->tex_funct(p + x * 16, frame->linesize[0],
+ d + (off + x) * ctx->tex_ratio);
+ }
+ }
+
+ return 0;
+}
+
+static void do_swizzle(AVFrame *frame, int x, int y)
+{
+ int i;
+ for (i = 0; i < frame->linesize[0] * frame->height; i += 4) {
+ uint8_t *src = frame->data[0] + i;
+ FFSWAP(uint8_t, src[x], src[y]);
+ }
+}
+
+static void run_postproc(AVCodecContext *avctx, AVFrame *frame)
+{
+ DDSContext *ctx = avctx->priv_data;
+ int i, x_off;
+
+ switch (ctx->postproc) {
+ case DDS_ALPHA_EXP:
+ /* Alpha-exponential mode divides each channel by the maximum
+ * R, G or B value, and stores the multiplying factor in the
+ * alpha channel. */
+ av_log(avctx, AV_LOG_DEBUG, "Post-processing alpha exponent.\n");
+
+ for (i = 0; i < frame->linesize[0] * frame->height; i += 4) {
+ uint8_t *src = frame->data[0] + i;
+ int r = src[0];
+ int g = src[1];
+ int b = src[2];
+ int a = src[3];
+
+ src[0] = r * a / 255;
+ src[1] = g * a / 255;
+ src[2] = b * a / 255;
+ src[3] = 255;
+ }
+ break;
+ case DDS_NORMAL_MAP:
+ /* Normal maps work in the XYZ color space and they encode
+ * X in R or in A, depending on the texture type, Y in G and
+ * derive Z with a square root of the distance.
+ *
+ * http://www.realtimecollisiondetection.net/blog/?p=28 */
+ av_log(avctx, AV_LOG_DEBUG, "Post-processing normal map.\n");
+
+ x_off = ctx->tex_ratio == 8 ? 0 : 3;
+ for (i = 0; i < frame->linesize[0] * frame->height; i += 4) {
+ uint8_t *src = frame->data[0] + i;
+ int x = src[x_off];
+ int y = src[1];
+ int z = 127;
+
+ int d = (255 * 255 - x * x - y * y) / 2;
+ if (d > 0)
+ z = rint(sqrtf(d));
+
+ src[0] = x;
+ src[1] = y;
+ src[2] = z;
+ src[3] = 255;
+ }
+ break;
+ case DDS_RAW_YCOCG:
+ /* Data is Y-Co-Cg-A and not RGBA, but they are represented
+ * with the same masks in the DDPF header. */
+ av_log(avctx, AV_LOG_DEBUG, "Post-processing raw YCoCg.\n");
+
+ for (i = 0; i < frame->linesize[0] * frame->height; i += 4) {
+ uint8_t *src = frame->data[0] + i;
+ int a = src[0];
+ int cg = src[1] - 128;
+ int co = src[2] - 128;
+ int y = src[3];
+
+ src[0] = av_clip_uint8(y + co - cg);
+ src[1] = av_clip_uint8(y + cg);
+ src[2] = av_clip_uint8(y - co - cg);
+ src[3] = a;
+ }
+ break;
+ case DDS_SWAP_ALPHA:
+ /* Alpha and Luma are stored swapped. */
+ av_log(avctx, AV_LOG_DEBUG, "Post-processing swapped Luma/Alpha.\n");
+
+ for (i = 0; i < frame->linesize[0] * frame->height; i += 2) {
+ uint8_t *src = frame->data[0] + i;
+ FFSWAP(uint8_t, src[0], src[1]);
+ }
+ break;
+ case DDS_SWIZZLE_A2XY:
+ /* Swap R and G, often used to restore a standard RGTC2. */
+ av_log(avctx, AV_LOG_DEBUG, "Post-processing A2XY swizzle.\n");
+ do_swizzle(frame, 0, 1);
+ break;
+ case DDS_SWIZZLE_RBXG:
+ /* Swap G and A, then B and new A (G). */
+ av_log(avctx, AV_LOG_DEBUG, "Post-processing RBXG swizzle.\n");
+ do_swizzle(frame, 1, 3);
+ do_swizzle(frame, 2, 3);
+ break;
+ case DDS_SWIZZLE_RGXB:
+ /* Swap B and A. */
+ av_log(avctx, AV_LOG_DEBUG, "Post-processing RGXB swizzle.\n");
+ do_swizzle(frame, 2, 3);
+ break;
+ case DDS_SWIZZLE_RXBG:
+ /* Swap G and A. */
+ av_log(avctx, AV_LOG_DEBUG, "Post-processing RXBG swizzle.\n");
+ do_swizzle(frame, 1, 3);
+ break;
+ case DDS_SWIZZLE_RXGB:
+ /* Swap R and A (misleading name). */
+ av_log(avctx, AV_LOG_DEBUG, "Post-processing RXGB swizzle.\n");
+ do_swizzle(frame, 0, 3);
+ break;
+ case DDS_SWIZZLE_XGBR:
+ /* Swap B and A, then R and new A (B). */
+ av_log(avctx, AV_LOG_DEBUG, "Post-processing XGBR swizzle.\n");
+ do_swizzle(frame, 2, 3);
+ do_swizzle(frame, 0, 3);
+ break;
+ case DDS_SWIZZLE_XGXR:
+ /* Swap G and A, then R and new A (G), then new R (G) and new G (A).
+ * This variant does not store any B component. */
+ av_log(avctx, AV_LOG_DEBUG, "Post-processing XGXR swizzle.\n");
+ do_swizzle(frame, 1, 3);
+ do_swizzle(frame, 0, 3);
+ do_swizzle(frame, 0, 1);
+ break;
+ case DDS_SWIZZLE_XRBG:
+ /* Swap G and A, then R and new A (G). */
+ av_log(avctx, AV_LOG_DEBUG, "Post-processing XRBG swizzle.\n");
+ do_swizzle(frame, 1, 3);
+ do_swizzle(frame, 0, 3);
+ break;
+ }
+}
+
+static int dds_decode(AVCodecContext *avctx, void *data,
+ int *got_frame, AVPacket *avpkt)
+{
+ DDSContext *ctx = avctx->priv_data;
+ GetByteContext *gbc = &ctx->gbc;
+ AVFrame *frame = data;
+ int mipmap;
+ int ret;
+
+ ff_texturedsp_init(&ctx->texdsp);
+ bytestream2_init(gbc, avpkt->data, avpkt->size);
+
+ if (bytestream2_get_bytes_left(gbc) < 128) {
+ av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).",
+ bytestream2_get_bytes_left(gbc));
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (bytestream2_get_le32(gbc) != MKTAG('D', 'D', 'S', ' ') ||
+ bytestream2_get_le32(gbc) != 124) { // header size
+ av_log(avctx, AV_LOG_ERROR, "Invalid DDS header.");
+ return AVERROR_INVALIDDATA;
+ }
+
+ bytestream2_skip(gbc, 4); // flags
+
+ avctx->height = bytestream2_get_le32(gbc);
+ avctx->width = bytestream2_get_le32(gbc);
+ ret = av_image_check_size(avctx->width, avctx->height, 0, avctx);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid image size %dx%d.\n",
+ avctx->width, avctx->height);
+ return ret;
+ }
+
+ /* Since codec is based on 4x4 blocks, size is aligned to 4. */
+ avctx->coded_width = FFALIGN(avctx->width, TEXTURE_BLOCK_W);
+ avctx->coded_height = FFALIGN(avctx->height, TEXTURE_BLOCK_H);
+
+ bytestream2_skip(gbc, 4); // pitch
+ bytestream2_skip(gbc, 4); // depth
+ mipmap = bytestream2_get_le32(gbc);
+ if (mipmap != 0)
+ av_log(avctx, AV_LOG_VERBOSE, "Found %d mipmaps (ignored).\n", mipmap);
+
+ /* Extract pixel format information, considering additional elements
+ * in reserved1 and reserved2. */
+ ret = parse_pixel_format(avctx);
+ if (ret < 0)
+ return ret;
+
+ ret = ff_get_buffer(avctx, frame, 0);
+ if (ret < 0)
+ return ret;
+
+ if (ctx->compressed) {
+ int size = (avctx->coded_height / TEXTURE_BLOCK_H) *
+ (avctx->coded_width / TEXTURE_BLOCK_W) * ctx->tex_ratio;
+ ctx->slice_count = av_clip(avctx->thread_count, 1,
+ avctx->coded_height / TEXTURE_BLOCK_H);
+
+ if (bytestream2_get_bytes_left(gbc) < size) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Compressed Buffer is too small (%d < %d).\n",
+ bytestream2_get_bytes_left(gbc), size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* Use the decompress function on the texture, one block per thread. */
+ ctx->tex_data = gbc->buffer;
+ avctx->execute2(avctx, decompress_texture_thread, frame, NULL, ctx->slice_count);
+ } else {
+ int linesize = av_image_get_linesize(avctx->pix_fmt, frame->width, 0);
+
+ if (ctx->paletted) {
+ int i;
+ /* Use the first 1024 bytes as palette, then copy the rest. */
+ bytestream2_get_buffer(gbc, frame->data[1], 256 * 4);
+ for (i = 0; i < 256; i++)
+ AV_WN32(frame->data[1] + i*4,
+ (frame->data[1][2+i*4]<<0)+
+ (frame->data[1][1+i*4]<<8)+
+ (frame->data[1][0+i*4]<<16)+
+ ((unsigned)frame->data[1][3+i*4]<<24)
+ );
+
+ frame->palette_has_changed = 1;
+ }
+
+ if (bytestream2_get_bytes_left(gbc) < frame->height * linesize) {
+ av_log(avctx, AV_LOG_ERROR, "Buffer is too small (%d < %d).\n",
+ bytestream2_get_bytes_left(gbc), frame->height * linesize);
+ return AVERROR_INVALIDDATA;
+ }
+
+ av_image_copy_plane(frame->data[0], frame->linesize[0],
+ gbc->buffer, linesize,
+ linesize, frame->height);
+ }
+
+ /* Run any post processing here if needed. */
+ if (avctx->pix_fmt == AV_PIX_FMT_BGRA ||
+ avctx->pix_fmt == AV_PIX_FMT_RGBA ||
+ avctx->pix_fmt == AV_PIX_FMT_RGB0 ||
+ avctx->pix_fmt == AV_PIX_FMT_BGR0 ||
+ avctx->pix_fmt == AV_PIX_FMT_YA8)
+ run_postproc(avctx, frame);
+
+ /* Frame is ready to be output. */
+ frame->pict_type = AV_PICTURE_TYPE_I;
+ frame->key_frame = 1;
+ *got_frame = 1;
+
+ return avpkt->size;
+}
+
+AVCodec ff_dds_decoder = {
+ .name = "dds",
+ .long_name = NULL_IF_CONFIG_SMALL("DirectDraw Surface image decoder"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_DDS,
+ .decode = dds_decode,
+ .priv_data_size = sizeof(DDSContext),
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE
+};
diff --git a/ffmpeg-2-8-12/libavcodec/dfa.c b/ffmpeg-2-8-12/libavcodec/dfa.c
new file mode 100644
index 0000000..8067ac9
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/dfa.c
@@ -0,0 +1,423 @@
+/*
+ * Chronomaster DFA Video Decoder
+ * Copyright (c) 2011 Konstantin Shishkov
+ * based on work by Vladimir "VAG" Gneushev
+ *
+ * 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 <inttypes.h>
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/mem.h"
+
+typedef struct DfaContext {
+ uint32_t pal[256];
+ uint8_t *frame_buf;
+} DfaContext;
+
+static av_cold int dfa_decode_init(AVCodecContext *avctx)
+{
+ DfaContext *s = avctx->priv_data;
+
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
+ if (!avctx->width || !avctx->height)
+ return AVERROR_INVALIDDATA;
+
+ av_assert0(av_image_check_size(avctx->width, avctx->height, 0, avctx) >= 0);
+
+ s->frame_buf = av_mallocz(avctx->width * avctx->height);
+ if (!s->frame_buf)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static int decode_copy(GetByteContext *gb, uint8_t *frame, int width, int height)
+{
+ const int size = width * height;
+
+ if (bytestream2_get_buffer(gb, frame, size) != size)
+ return AVERROR_INVALIDDATA;
+ return 0;
+}
+
+static int decode_tsw1(GetByteContext *gb, uint8_t *frame, int width, int height)
+{
+ const uint8_t *frame_start = frame;
+ const uint8_t *frame_end = frame + width * height;
+ int mask = 0x10000, bitbuf = 0;
+ int v, count;
+ unsigned segments;
+ unsigned offset;
+
+ segments = bytestream2_get_le32(gb);
+ offset = bytestream2_get_le32(gb);
+ if (segments == 0 && offset == frame_end - frame)
+ return 0; // skip frame
+ if (frame_end - frame <= offset)
+ return AVERROR_INVALIDDATA;
+ frame += offset;
+ while (segments--) {
+ if (bytestream2_get_bytes_left(gb) < 2)
+ return AVERROR_INVALIDDATA;
+ if (mask == 0x10000) {
+ bitbuf = bytestream2_get_le16u(gb);
+ mask = 1;
+ }
+ if (frame_end - frame < 2)
+ return AVERROR_INVALIDDATA;
+ if (bitbuf & mask) {
+ v = bytestream2_get_le16(gb);
+ offset = (v & 0x1FFF) << 1;
+ count = ((v >> 13) + 2) << 1;
+ if (frame - frame_start < offset || frame_end - frame < count)
+ return AVERROR_INVALIDDATA;
+ av_memcpy_backptr(frame, offset, count);
+ frame += count;
+ } else {
+ *frame++ = bytestream2_get_byte(gb);
+ *frame++ = bytestream2_get_byte(gb);
+ }
+ mask <<= 1;
+ }
+
+ return 0;
+}
+
+static int decode_dsw1(GetByteContext *gb, uint8_t *frame, int width, int height)
+{
+ const uint8_t *frame_start = frame;
+ const uint8_t *frame_end = frame + width * height;
+ int mask = 0x10000, bitbuf = 0;
+ int v, offset, count, segments;
+
+ segments = bytestream2_get_le16(gb);
+ while (segments--) {
+ if (bytestream2_get_bytes_left(gb) < 2)
+ return AVERROR_INVALIDDATA;
+ if (mask == 0x10000) {
+ bitbuf = bytestream2_get_le16u(gb);
+ mask = 1;
+ }
+ if (frame_end - frame < 2)
+ return AVERROR_INVALIDDATA;
+ if (bitbuf & mask) {
+ v = bytestream2_get_le16(gb);
+ offset = (v & 0x1FFF) << 1;
+ count = ((v >> 13) + 2) << 1;
+ if (frame - frame_start < offset || frame_end - frame < count)
+ return AVERROR_INVALIDDATA;
+ av_memcpy_backptr(frame, offset, count);
+ frame += count;
+ } else if (bitbuf & (mask << 1)) {
+ frame += bytestream2_get_le16(gb);
+ } else {
+ *frame++ = bytestream2_get_byte(gb);
+ *frame++ = bytestream2_get_byte(gb);
+ }
+ mask <<= 2;
+ }
+
+ return 0;
+}
+
+static int decode_dds1(GetByteContext *gb, uint8_t *frame, int width, int height)
+{
+ const uint8_t *frame_start = frame;
+ const uint8_t *frame_end = frame + width * height;
+ int mask = 0x10000, bitbuf = 0;
+ int i, v, offset, count, segments;
+
+ segments = bytestream2_get_le16(gb);
+ while (segments--) {
+ if (bytestream2_get_bytes_left(gb) < 2)
+ return AVERROR_INVALIDDATA;
+ if (mask == 0x10000) {
+ bitbuf = bytestream2_get_le16u(gb);
+ mask = 1;
+ }
+
+ if (bitbuf & mask) {
+ v = bytestream2_get_le16(gb);
+ offset = (v & 0x1FFF) << 2;
+ count = ((v >> 13) + 2) << 1;
+ if (frame - frame_start < offset || frame_end - frame < count*2 + width)
+ return AVERROR_INVALIDDATA;
+ for (i = 0; i < count; i++) {
+ frame[0] = frame[1] =
+ frame[width] = frame[width + 1] = frame[-offset];
+
+ frame += 2;
+ }
+ } else if (bitbuf & (mask << 1)) {
+ v = bytestream2_get_le16(gb)*2;
+ if (frame - frame_end < v)
+ return AVERROR_INVALIDDATA;
+ frame += v;
+ } else {
+ if (frame_end - frame < width + 4)
+ return AVERROR_INVALIDDATA;
+ frame[0] = frame[1] =
+ frame[width] = frame[width + 1] = bytestream2_get_byte(gb);
+ frame += 2;
+ frame[0] = frame[1] =
+ frame[width] = frame[width + 1] = bytestream2_get_byte(gb);
+ frame += 2;
+ }
+ mask <<= 2;
+ }
+
+ return 0;
+}
+
+static int decode_bdlt(GetByteContext *gb, uint8_t *frame, int width, int height)
+{
+ uint8_t *line_ptr;
+ int count, lines, segments;
+
+ count = bytestream2_get_le16(gb);
+ if (count >= height)
+ return AVERROR_INVALIDDATA;
+ frame += width * count;
+ lines = bytestream2_get_le16(gb);
+ if (count + lines > height)
+ return AVERROR_INVALIDDATA;
+
+ while (lines--) {
+ if (bytestream2_get_bytes_left(gb) < 1)
+ return AVERROR_INVALIDDATA;
+ line_ptr = frame;
+ frame += width;
+ segments = bytestream2_get_byteu(gb);
+ while (segments--) {
+ if (frame - line_ptr <= bytestream2_peek_byte(gb))
+ return AVERROR_INVALIDDATA;
+ line_ptr += bytestream2_get_byte(gb);
+ count = (int8_t)bytestream2_get_byte(gb);
+ if (count >= 0) {
+ if (frame - line_ptr < count)
+ return AVERROR_INVALIDDATA;
+ if (bytestream2_get_buffer(gb, line_ptr, count) != count)
+ return AVERROR_INVALIDDATA;
+ } else {
+ count = -count;
+ if (frame - line_ptr < count)
+ return AVERROR_INVALIDDATA;
+ memset(line_ptr, bytestream2_get_byte(gb), count);
+ }
+ line_ptr += count;
+ }
+ }
+
+ return 0;
+}
+
+static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height)
+{
+ const uint8_t *frame_end = frame + width * height;
+ uint8_t *line_ptr;
+ int count, i, v, lines, segments;
+ int y = 0;
+
+ lines = bytestream2_get_le16(gb);
+ if (lines > height)
+ return AVERROR_INVALIDDATA;
+
+ while (lines--) {
+ if (bytestream2_get_bytes_left(gb) < 2)
+ return AVERROR_INVALIDDATA;
+ segments = bytestream2_get_le16u(gb);
+ while ((segments & 0xC000) == 0xC000) {
+ unsigned skip_lines = -(int16_t)segments;
+ int64_t delta = -((int16_t)segments * (int64_t)width);
+ if (frame_end - frame <= delta || y + lines + skip_lines > height)
+ return AVERROR_INVALIDDATA;
+ frame += delta;
+ y += skip_lines;
+ segments = bytestream2_get_le16(gb);
+ }
+
+ if (frame_end <= frame)
+ return AVERROR_INVALIDDATA;
+ if (segments & 0x8000) {
+ frame[width - 1] = segments & 0xFF;
+ segments = bytestream2_get_le16(gb);
+ }
+ line_ptr = frame;
+ if (frame_end - frame < width)
+ return AVERROR_INVALIDDATA;
+ frame += width;
+ y++;
+ while (segments--) {
+ if (frame - line_ptr <= bytestream2_peek_byte(gb))
+ return AVERROR_INVALIDDATA;
+ line_ptr += bytestream2_get_byte(gb);
+ count = (int8_t)bytestream2_get_byte(gb);
+ if (count >= 0) {
+ if (frame - line_ptr < count * 2)
+ return AVERROR_INVALIDDATA;
+ if (bytestream2_get_buffer(gb, line_ptr, count * 2) != count * 2)
+ return AVERROR_INVALIDDATA;
+ line_ptr += count * 2;
+ } else {
+ count = -count;
+ if (frame - line_ptr < count * 2)
+ return AVERROR_INVALIDDATA;
+ v = bytestream2_get_le16(gb);
+ for (i = 0; i < count; i++)
+ bytestream_put_le16(&line_ptr, v);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int decode_tdlt(GetByteContext *gb, uint8_t *frame, int width, int height)
+{
+ const uint8_t *frame_end = frame + width * height;
+ uint32_t segments = bytestream2_get_le32(gb);
+ int skip, copy;
+
+ while (segments--) {
+ if (bytestream2_get_bytes_left(gb) < 2)
+ return AVERROR_INVALIDDATA;
+ copy = bytestream2_get_byteu(gb) * 2;
+ skip = bytestream2_get_byteu(gb) * 2;
+ if (frame_end - frame < copy + skip ||
+ bytestream2_get_bytes_left(gb) < copy)
+ return AVERROR_INVALIDDATA;
+ frame += skip;
+ bytestream2_get_buffer(gb, frame, copy);
+ frame += copy;
+ }
+
+ return 0;
+}
+
+static int decode_blck(GetByteContext *gb, uint8_t *frame, int width, int height)
+{
+ memset(frame, 0, width * height);
+ return 0;
+}
+
+
+typedef int (*chunk_decoder)(GetByteContext *gb, uint8_t *frame, int width, int height);
+
+static const chunk_decoder decoder[8] = {
+ decode_copy, decode_tsw1, decode_bdlt, decode_wdlt,
+ decode_tdlt, decode_dsw1, decode_blck, decode_dds1,
+};
+
+static const char* chunk_name[8] = {
+ "COPY", "TSW1", "BDLT", "WDLT", "TDLT", "DSW1", "BLCK", "DDS1"
+};
+
+static int dfa_decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ AVFrame *frame = data;
+ DfaContext *s = avctx->priv_data;
+ GetByteContext gb;
+ const uint8_t *buf = avpkt->data;
+ uint32_t chunk_type, chunk_size;
+ uint8_t *dst;
+ int ret;
+ int i, pal_elems;
+ int version = avctx->extradata_size==2 ? AV_RL16(avctx->extradata) : 0;
+
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+
+ bytestream2_init(&gb, avpkt->data, avpkt->size);
+ while (bytestream2_get_bytes_left(&gb) > 0) {
+ bytestream2_skip(&gb, 4);
+ chunk_size = bytestream2_get_le32(&gb);
+ chunk_type = bytestream2_get_le32(&gb);
+ if (!chunk_type)
+ break;
+ if (chunk_type == 1) {
+ pal_elems = FFMIN(chunk_size / 3, 256);
+ for (i = 0; i < pal_elems; i++) {
+ s->pal[i] = bytestream2_get_be24(&gb) << 2;
+ s->pal[i] |= 0xFFU << 24 | (s->pal[i] >> 6) & 0x30303;
+ }
+ frame->palette_has_changed = 1;
+ } else if (chunk_type <= 9) {
+ if (decoder[chunk_type - 2](&gb, s->frame_buf, avctx->width, avctx->height)) {
+ av_log(avctx, AV_LOG_ERROR, "Error decoding %s chunk\n",
+ chunk_name[chunk_type - 2]);
+ return AVERROR_INVALIDDATA;
+ }
+ } else {
+ av_log(avctx, AV_LOG_WARNING,
+ "Ignoring unknown chunk type %"PRIu32"\n",
+ chunk_type);
+ }
+ buf += chunk_size;
+ }
+
+ buf = s->frame_buf;
+ dst = frame->data[0];
+ for (i = 0; i < avctx->height; i++) {
+ if(version == 0x100) {
+ int j;
+ for(j = 0; j < avctx->width; j++) {
+ dst[j] = buf[ (i&3)*(avctx->width /4) + (j/4) +
+ ((j&3)*(avctx->height/4) + (i/4))*avctx->width];
+ }
+ } else {
+ memcpy(dst, buf, avctx->width);
+ buf += avctx->width;
+ }
+ dst += frame->linesize[0];
+ }
+ memcpy(frame->data[1], s->pal, sizeof(s->pal));
+
+ *got_frame = 1;
+
+ return avpkt->size;
+}
+
+static av_cold int dfa_decode_end(AVCodecContext *avctx)
+{
+ DfaContext *s = avctx->priv_data;
+
+ av_freep(&s->frame_buf);
+
+ return 0;
+}
+
+AVCodec ff_dfa_decoder = {
+ .name = "dfa",
+ .long_name = NULL_IF_CONFIG_SMALL("Chronomaster DFA"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_DFA,
+ .priv_data_size = sizeof(DfaContext),
+ .init = dfa_decode_init,
+ .close = dfa_decode_end,
+ .decode = dfa_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/dirac.c b/ffmpeg-2-8-12/libavcodec/dirac.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dirac.c
rename to ffmpeg-2-8-12/libavcodec/dirac.c
diff --git a/ffmpeg-2-8-11/libavcodec/dirac.h b/ffmpeg-2-8-12/libavcodec/dirac.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dirac.h
rename to ffmpeg-2-8-12/libavcodec/dirac.h
diff --git a/ffmpeg-2-8-11/libavcodec/dirac_arith.c b/ffmpeg-2-8-12/libavcodec/dirac_arith.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dirac_arith.c
rename to ffmpeg-2-8-12/libavcodec/dirac_arith.c
diff --git a/ffmpeg-2-8-11/libavcodec/dirac_arith.h b/ffmpeg-2-8-12/libavcodec/dirac_arith.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dirac_arith.h
rename to ffmpeg-2-8-12/libavcodec/dirac_arith.h
diff --git a/ffmpeg-2-8-11/libavcodec/dirac_dwt.c b/ffmpeg-2-8-12/libavcodec/dirac_dwt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dirac_dwt.c
rename to ffmpeg-2-8-12/libavcodec/dirac_dwt.c
diff --git a/ffmpeg-2-8-11/libavcodec/dirac_dwt.h b/ffmpeg-2-8-12/libavcodec/dirac_dwt.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dirac_dwt.h
rename to ffmpeg-2-8-12/libavcodec/dirac_dwt.h
diff --git a/ffmpeg-2-8-11/libavcodec/dirac_parser.c b/ffmpeg-2-8-12/libavcodec/dirac_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dirac_parser.c
rename to ffmpeg-2-8-12/libavcodec/dirac_parser.c
diff --git a/ffmpeg-2-8-12/libavcodec/diracdec.c b/ffmpeg-2-8-12/libavcodec/diracdec.c
new file mode 100644
index 0000000..929832b
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/diracdec.c
@@ -0,0 +1,2055 @@
+/*
+ * Copyright (C) 2007 Marco Gerards <marco at gnu.org>
+ * Copyright (C) 2009 David Conrad
+ * Copyright (C) 2011 Jordi Ortiz
+ *
+ * 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
+ * Dirac Decoder
+ * @author Marco Gerards <marco at gnu.org>, David Conrad, Jordi Ortiz <nenjordi at gmail.com>
+ */
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "bytestream.h"
+#include "internal.h"
+#include "golomb.h"
+#include "dirac_arith.h"
+#include "mpeg12data.h"
+#include "libavcodec/mpegvideo.h"
+#include "mpegvideoencdsp.h"
+#include "dirac_dwt.h"
+#include "dirac.h"
+#include "diracdsp.h"
+#include "videodsp.h"
+
+/**
+ * The spec limits the number of wavelet decompositions to 4 for both
+ * level 1 (VC-2) and 128 (long-gop default).
+ * 5 decompositions is the maximum before >16-bit buffers are needed.
+ * Schroedinger allows this for DD 9,7 and 13,7 wavelets only, limiting
+ * the others to 4 decompositions (or 3 for the fidelity filter).
+ *
+ * We use this instead of MAX_DECOMPOSITIONS to save some memory.
+ */
+#define MAX_DWT_LEVELS 5
+
+/**
+ * The spec limits this to 3 for frame coding, but in practice can be as high as 6
+ */
+#define MAX_REFERENCE_FRAMES 8
+#define MAX_DELAY 5 /* limit for main profile for frame coding (TODO: field coding) */
+#define MAX_FRAMES (MAX_REFERENCE_FRAMES + MAX_DELAY + 1)
+#define MAX_QUANT 68 /* max quant for VC-2 */
+#define MAX_BLOCKSIZE 32 /* maximum xblen/yblen we support */
+
+/**
+ * DiracBlock->ref flags, if set then the block does MC from the given ref
+ */
+#define DIRAC_REF_MASK_REF1 1
+#define DIRAC_REF_MASK_REF2 2
+#define DIRAC_REF_MASK_GLOBAL 4
+
+/**
+ * Value of Picture.reference when Picture is not a reference picture, but
+ * is held for delayed output.
+ */
+#define DELAYED_PIC_REF 4
+
+#define CALC_PADDING(size, depth) \
+ (((size + (1 << depth) - 1) >> depth) << depth)
+
+#define DIVRNDUP(a, b) (((a) + (b) - 1) / (b))
+
+typedef struct {
+ AVFrame *avframe;
+ int interpolated[3]; /* 1 if hpel[] is valid */
+ uint8_t *hpel[3][4];
+ uint8_t *hpel_base[3][4];
+ int reference;
+} DiracFrame;
+
+typedef struct {
+ union {
+ int16_t mv[2][2];
+ int16_t dc[3];
+ } u; /* anonymous unions aren't in C99 :( */
+ uint8_t ref;
+} DiracBlock;
+
+typedef struct SubBand {
+ int level;
+ int orientation;
+ int stride;
+ int width;
+ int height;
+ int quant;
+ IDWTELEM *ibuf;
+ struct SubBand *parent;
+
+ /* for low delay */
+ unsigned length;
+ const uint8_t *coeff_data;
+} SubBand;
+
+typedef struct Plane {
+ int width;
+ int height;
+ ptrdiff_t stride;
+
+ int idwt_width;
+ int idwt_height;
+ int idwt_stride;
+ IDWTELEM *idwt_buf;
+ IDWTELEM *idwt_buf_base;
+ IDWTELEM *idwt_tmp;
+
+ /* block length */
+ uint8_t xblen;
+ uint8_t yblen;
+ /* block separation (block n+1 starts after this many pixels in block n) */
+ uint8_t xbsep;
+ uint8_t ybsep;
+ /* amount of overspill on each edge (half of the overlap between blocks) */
+ uint8_t xoffset;
+ uint8_t yoffset;
+
+ SubBand band[MAX_DWT_LEVELS][4];
+} Plane;
+
+typedef struct DiracContext {
+ AVCodecContext *avctx;
+ MpegvideoEncDSPContext mpvencdsp;
+ VideoDSPContext vdsp;
+ DiracDSPContext diracdsp;
+ GetBitContext gb;
+ dirac_source_params source;
+ int seen_sequence_header;
+ int frame_number; /* number of the next frame to display */
+ Plane plane[3];
+ int chroma_x_shift;
+ int chroma_y_shift;
+
+ int zero_res; /* zero residue flag */
+ int is_arith; /* whether coeffs use arith or golomb coding */
+ int low_delay; /* use the low delay syntax */
+ int globalmc_flag; /* use global motion compensation */
+ int num_refs; /* number of reference pictures */
+
+ /* wavelet decoding */
+ unsigned wavelet_depth; /* depth of the IDWT */
+ unsigned wavelet_idx;
+
+ /**
+ * schroedinger older than 1.0.8 doesn't store
+ * quant delta if only one codebook exists in a band
+ */
+ unsigned old_delta_quant;
+ unsigned codeblock_mode;
+
+ struct {
+ unsigned width;
+ unsigned height;
+ } codeblock[MAX_DWT_LEVELS+1];
+
+ struct {
+ unsigned num_x; /* number of horizontal slices */
+ unsigned num_y; /* number of vertical slices */
+ AVRational bytes; /* average bytes per slice */
+ uint8_t quant[MAX_DWT_LEVELS][4]; /* [DIRAC_STD] E.1 */
+ } lowdelay;
+
+ struct {
+ int pan_tilt[2]; /* pan/tilt vector */
+ int zrs[2][2]; /* zoom/rotate/shear matrix */
+ int perspective[2]; /* perspective vector */
+ unsigned zrs_exp;
+ unsigned perspective_exp;
+ } globalmc[2];
+
+ /* motion compensation */
+ uint8_t mv_precision; /* [DIRAC_STD] REFS_WT_PRECISION */
+ int16_t weight[2]; /* [DIRAC_STD] REF1_WT and REF2_WT */
+ unsigned weight_log2denom; /* [DIRAC_STD] REFS_WT_PRECISION */
+
+ int blwidth; /* number of blocks (horizontally) */
+ int blheight; /* number of blocks (vertically) */
+ int sbwidth; /* number of superblocks (horizontally) */
+ int sbheight; /* number of superblocks (vertically) */
+
+ uint8_t *sbsplit;
+ DiracBlock *blmotion;
+
+ uint8_t *edge_emu_buffer[4];
+ uint8_t *edge_emu_buffer_base;
+
+ uint16_t *mctmp; /* buffer holding the MC data multiplied by OBMC weights */
+ uint8_t *mcscratch;
+ int buffer_stride;
+
+ DECLARE_ALIGNED(16, uint8_t, obmc_weight)[3][MAX_BLOCKSIZE*MAX_BLOCKSIZE];
+
+ void (*put_pixels_tab[4])(uint8_t *dst, const uint8_t *src[5], int stride, int h);
+ void (*avg_pixels_tab[4])(uint8_t *dst, const uint8_t *src[5], int stride, int h);
+ void (*add_obmc)(uint16_t *dst, const uint8_t *src, int stride, const uint8_t *obmc_weight, int yblen);
+ dirac_weight_func weight_func;
+ dirac_biweight_func biweight_func;
+
+ DiracFrame *current_picture;
+ DiracFrame *ref_pics[2];
+
+ DiracFrame *ref_frames[MAX_REFERENCE_FRAMES+1];
+ DiracFrame *delay_frames[MAX_DELAY+1];
+ DiracFrame all_frames[MAX_FRAMES];
+} DiracContext;
+
+/**
+ * Dirac Specification ->
+ * Parse code values. 9.6.1 Table 9.1
+ */
+enum dirac_parse_code {
+ pc_seq_header = 0x00,
+ pc_eos = 0x10,
+ pc_aux_data = 0x20,
+ pc_padding = 0x30,
+};
+
+enum dirac_subband {
+ subband_ll = 0,
+ subband_hl = 1,
+ subband_lh = 2,
+ subband_hh = 3,
+ subband_nb,
+};
+
+static const uint8_t default_qmat[][4][4] = {
+ { { 5, 3, 3, 0}, { 0, 4, 4, 1}, { 0, 5, 5, 2}, { 0, 6, 6, 3} },
+ { { 4, 2, 2, 0}, { 0, 4, 4, 2}, { 0, 5, 5, 3}, { 0, 7, 7, 5} },
+ { { 5, 3, 3, 0}, { 0, 4, 4, 1}, { 0, 5, 5, 2}, { 0, 6, 6, 3} },
+ { { 8, 4, 4, 0}, { 0, 4, 4, 0}, { 0, 4, 4, 0}, { 0, 4, 4, 0} },
+ { { 8, 4, 4, 0}, { 0, 4, 4, 0}, { 0, 4, 4, 0}, { 0, 4, 4, 0} },
+ { { 0, 4, 4, 8}, { 0, 8, 8, 12}, { 0, 13, 13, 17}, { 0, 17, 17, 21} },
+ { { 3, 1, 1, 0}, { 0, 4, 4, 2}, { 0, 6, 6, 5}, { 0, 9, 9, 7} },
+};
+
+static const int qscale_tab[MAX_QUANT+1] = {
+ 4, 5, 6, 7, 8, 10, 11, 13,
+ 16, 19, 23, 27, 32, 38, 45, 54,
+ 64, 76, 91, 108, 128, 152, 181, 215,
+ 256, 304, 362, 431, 512, 609, 724, 861,
+ 1024, 1218, 1448, 1722, 2048, 2435, 2896, 3444,
+ 4096, 4871, 5793, 6889, 8192, 9742, 11585, 13777,
+ 16384, 19484, 23170, 27554, 32768, 38968, 46341, 55109,
+ 65536, 77936
+};
+
+static const int qoffset_intra_tab[MAX_QUANT+1] = {
+ 1, 2, 3, 4, 4, 5, 6, 7,
+ 8, 10, 12, 14, 16, 19, 23, 27,
+ 32, 38, 46, 54, 64, 76, 91, 108,
+ 128, 152, 181, 216, 256, 305, 362, 431,
+ 512, 609, 724, 861, 1024, 1218, 1448, 1722,
+ 2048, 2436, 2897, 3445, 4096, 4871, 5793, 6889,
+ 8192, 9742, 11585, 13777, 16384, 19484, 23171, 27555,
+ 32768, 38968
+};
+
+static const int qoffset_inter_tab[MAX_QUANT+1] = {
+ 1, 2, 2, 3, 3, 4, 4, 5,
+ 6, 7, 9, 10, 12, 14, 17, 20,
+ 24, 29, 34, 41, 48, 57, 68, 81,
+ 96, 114, 136, 162, 192, 228, 272, 323,
+ 384, 457, 543, 646, 768, 913, 1086, 1292,
+ 1536, 1827, 2172, 2583, 3072, 3653, 4344, 5166,
+ 6144, 7307, 8689, 10333, 12288, 14613, 17378, 20666,
+ 24576, 29226
+};
+
+/* magic number division by 3 from schroedinger */
+static inline int divide3(int x)
+{
+ return ((x+1)*21845 + 10922) >> 16;
+}
+
+static DiracFrame *remove_frame(DiracFrame *framelist[], int picnum)
+{
+ DiracFrame *remove_pic = NULL;
+ int i, remove_idx = -1;
+
+ for (i = 0; framelist[i]; i++)
+ if (framelist[i]->avframe->display_picture_number == picnum) {
+ remove_pic = framelist[i];
+ remove_idx = i;
+ }
+
+ if (remove_pic)
+ for (i = remove_idx; framelist[i]; i++)
+ framelist[i] = framelist[i+1];
+
+ return remove_pic;
+}
+
+static int add_frame(DiracFrame *framelist[], int maxframes, DiracFrame *frame)
+{
+ int i;
+ for (i = 0; i < maxframes; i++)
+ if (!framelist[i]) {
+ framelist[i] = frame;
+ return 0;
+ }
+ return -1;
+}
+
+static int alloc_sequence_buffers(DiracContext *s)
+{
+ int sbwidth = DIVRNDUP(s->source.width, 4);
+ int sbheight = DIVRNDUP(s->source.height, 4);
+ int i, w, h, top_padding;
+
+ /* todo: think more about this / use or set Plane here */
+ for (i = 0; i < 3; i++) {
+ int max_xblen = MAX_BLOCKSIZE >> (i ? s->chroma_x_shift : 0);
+ int max_yblen = MAX_BLOCKSIZE >> (i ? s->chroma_y_shift : 0);
+ w = s->source.width >> (i ? s->chroma_x_shift : 0);
+ h = s->source.height >> (i ? s->chroma_y_shift : 0);
+
+ /* we allocate the max we support here since num decompositions can
+ * change from frame to frame. Stride is aligned to 16 for SIMD, and
+ * 1<<MAX_DWT_LEVELS top padding to avoid if(y>0) in arith decoding
+ * MAX_BLOCKSIZE padding for MC: blocks can spill up to half of that
+ * on each side */
+ top_padding = FFMAX(1<<MAX_DWT_LEVELS, max_yblen/2);
+ w = FFALIGN(CALC_PADDING(w, MAX_DWT_LEVELS), 8); /* FIXME: Should this be 16 for SSE??? */
+ h = top_padding + CALC_PADDING(h, MAX_DWT_LEVELS) + max_yblen/2;
+
+ s->plane[i].idwt_buf_base = av_mallocz_array((w+max_xblen), h * sizeof(IDWTELEM));
+ s->plane[i].idwt_tmp = av_malloc_array((w+16), sizeof(IDWTELEM));
+ s->plane[i].idwt_buf = s->plane[i].idwt_buf_base + top_padding*w;
+ if (!s->plane[i].idwt_buf_base || !s->plane[i].idwt_tmp)
+ return AVERROR(ENOMEM);
+ }
+
+ /* fixme: allocate using real stride here */
+ s->sbsplit = av_malloc_array(sbwidth, sbheight);
+ s->blmotion = av_malloc_array(sbwidth, sbheight * 16 * sizeof(*s->blmotion));
+
+ if (!s->sbsplit || !s->blmotion)
+ return AVERROR(ENOMEM);
+ return 0;
+}
+
+static int alloc_buffers(DiracContext *s, int stride)
+{
+ int w = s->source.width;
+ int h = s->source.height;
+
+ av_assert0(stride >= w);
+ stride += 64;
+
+ if (s->buffer_stride >= stride)
+ return 0;
+ s->buffer_stride = 0;
+
+ av_freep(&s->edge_emu_buffer_base);
+ memset(s->edge_emu_buffer, 0, sizeof(s->edge_emu_buffer));
+ av_freep(&s->mctmp);
+ av_freep(&s->mcscratch);
+
+ s->edge_emu_buffer_base = av_malloc_array(stride, MAX_BLOCKSIZE);
+
+ s->mctmp = av_malloc_array((stride+MAX_BLOCKSIZE), (h+MAX_BLOCKSIZE) * sizeof(*s->mctmp));
+ s->mcscratch = av_malloc_array(stride, MAX_BLOCKSIZE);
+
+ if (!s->edge_emu_buffer_base || !s->mctmp || !s->mcscratch)
+ return AVERROR(ENOMEM);
+
+ s->buffer_stride = stride;
+ return 0;
+}
+
+static void free_sequence_buffers(DiracContext *s)
+{
+ int i, j, k;
+
+ for (i = 0; i < MAX_FRAMES; i++) {
+ if (s->all_frames[i].avframe->data[0]) {
+ av_frame_unref(s->all_frames[i].avframe);
+ memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated));
+ }
+
+ for (j = 0; j < 3; j++)
+ for (k = 1; k < 4; k++)
+ av_freep(&s->all_frames[i].hpel_base[j][k]);
+ }
+
+ memset(s->ref_frames, 0, sizeof(s->ref_frames));
+ memset(s->delay_frames, 0, sizeof(s->delay_frames));
+
+ for (i = 0; i < 3; i++) {
+ av_freep(&s->plane[i].idwt_buf_base);
+ av_freep(&s->plane[i].idwt_tmp);
+ }
+
+ s->buffer_stride = 0;
+ av_freep(&s->sbsplit);
+ av_freep(&s->blmotion);
+ av_freep(&s->edge_emu_buffer_base);
+
+ av_freep(&s->mctmp);
+ av_freep(&s->mcscratch);
+}
+
+static av_cold int dirac_decode_init(AVCodecContext *avctx)
+{
+ DiracContext *s = avctx->priv_data;
+ int i;
+
+ s->avctx = avctx;
+ s->frame_number = -1;
+
+ ff_diracdsp_init(&s->diracdsp);
+ ff_mpegvideoencdsp_init(&s->mpvencdsp, avctx);
+ ff_videodsp_init(&s->vdsp, 8);
+
+ for (i = 0; i < MAX_FRAMES; i++) {
+ s->all_frames[i].avframe = av_frame_alloc();
+ if (!s->all_frames[i].avframe) {
+ while (i > 0)
+ av_frame_free(&s->all_frames[--i].avframe);
+ return AVERROR(ENOMEM);
+ }
+ }
+
+ return 0;
+}
+
+static void dirac_decode_flush(AVCodecContext *avctx)
+{
+ DiracContext *s = avctx->priv_data;
+ free_sequence_buffers(s);
+ s->seen_sequence_header = 0;
+ s->frame_number = -1;
+}
+
+static av_cold int dirac_decode_end(AVCodecContext *avctx)
+{
+ DiracContext *s = avctx->priv_data;
+ int i;
+
+ dirac_decode_flush(avctx);
+ for (i = 0; i < MAX_FRAMES; i++)
+ av_frame_free(&s->all_frames[i].avframe);
+
+ return 0;
+}
+
+#define SIGN_CTX(x) (CTX_SIGN_ZERO + ((x) > 0) - ((x) < 0))
+
+static inline void coeff_unpack_arith(DiracArith *c, int qfactor, int qoffset,
+ SubBand *b, IDWTELEM *buf, int x, int y)
+{
+ int coeff, sign;
+ int sign_pred = 0;
+ int pred_ctx = CTX_ZPZN_F1;
+
+ /* Check if the parent subband has a 0 in the corresponding position */
+ if (b->parent)
+ pred_ctx += !!b->parent->ibuf[b->parent->stride * (y>>1) + (x>>1)] << 1;
+
+ if (b->orientation == subband_hl)
+ sign_pred = buf[-b->stride];
+
+ /* Determine if the pixel has only zeros in its neighbourhood */
+ if (x) {
+ pred_ctx += !(buf[-1] | buf[-b->stride] | buf[-1-b->stride]);
+ if (b->orientation == subband_lh)
+ sign_pred = buf[-1];
+ } else {
+ pred_ctx += !buf[-b->stride];
+ }
+
+ coeff = dirac_get_arith_uint(c, pred_ctx, CTX_COEFF_DATA);
+ if (coeff) {
+ coeff = (coeff * qfactor + qoffset + 2) >> 2;
+ sign = dirac_get_arith_bit(c, SIGN_CTX(sign_pred));
+ coeff = (coeff ^ -sign) + sign;
+ }
+ *buf = coeff;
+}
+
+static inline int coeff_unpack_golomb(GetBitContext *gb, int qfactor, int qoffset)
+{
+ int sign, coeff;
+
+ coeff = svq3_get_ue_golomb(gb);
+ if (coeff) {
+ coeff = (coeff * qfactor + qoffset + 2) >> 2;
+ sign = get_bits1(gb);
+ coeff = (coeff ^ -sign) + sign;
+ }
+ return coeff;
+}
+
+/**
+ * Decode the coeffs in the rectangle defined by left, right, top, bottom
+ * [DIRAC_STD] 13.4.3.2 Codeblock unpacking loop. codeblock()
+ */
+static inline void codeblock(DiracContext *s, SubBand *b,
+ GetBitContext *gb, DiracArith *c,
+ int left, int right, int top, int bottom,
+ int blockcnt_one, int is_arith)
+{
+ int x, y, zero_block;
+ int qoffset, qfactor;
+ IDWTELEM *buf;
+
+ /* check for any coded coefficients in this codeblock */
+ if (!blockcnt_one) {
+ if (is_arith)
+ zero_block = dirac_get_arith_bit(c, CTX_ZERO_BLOCK);
+ else
+ zero_block = get_bits1(gb);
+
+ if (zero_block)
+ return;
+ }
+
+ if (s->codeblock_mode && !(s->old_delta_quant && blockcnt_one)) {
+ int quant = b->quant;
+ if (is_arith)
+ quant += dirac_get_arith_int(c, CTX_DELTA_Q_F, CTX_DELTA_Q_DATA);
+ else
+ quant += dirac_get_se_golomb(gb);
+ if (quant < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid quant\n");
+ return;
+ }
+ b->quant = quant;
+ }
+
+ b->quant = FFMIN(b->quant, MAX_QUANT);
+
+ qfactor = qscale_tab[b->quant];
+ /* TODO: context pointer? */
+ if (!s->num_refs)
+ qoffset = qoffset_intra_tab[b->quant];
+ else
+ qoffset = qoffset_inter_tab[b->quant];
+
+ buf = b->ibuf + top * b->stride;
+ for (y = top; y < bottom; y++) {
+ for (x = left; x < right; x++) {
+ /* [DIRAC_STD] 13.4.4 Subband coefficients. coeff_unpack() */
+ if (is_arith)
+ coeff_unpack_arith(c, qfactor, qoffset, b, buf+x, x, y);
+ else
+ buf[x] = coeff_unpack_golomb(gb, qfactor, qoffset);
+ }
+ buf += b->stride;
+ }
+}
+
+/**
+ * Dirac Specification ->
+ * 13.3 intra_dc_prediction(band)
+ */
+static inline void intra_dc_prediction(SubBand *b)
+{
+ IDWTELEM *buf = b->ibuf;
+ int x, y;
+
+ for (x = 1; x < b->width; x++)
+ buf[x] += buf[x-1];
+ buf += b->stride;
+
+ for (y = 1; y < b->height; y++) {
+ buf[0] += buf[-b->stride];
+
+ for (x = 1; x < b->width; x++) {
+ int pred = buf[x - 1] + buf[x - b->stride] + buf[x - b->stride-1];
+ buf[x] += divide3(pred);
+ }
+ buf += b->stride;
+ }
+}
+
+/**
+ * Dirac Specification ->
+ * 13.4.2 Non-skipped subbands. subband_coeffs()
+ */
+static av_always_inline void decode_subband_internal(DiracContext *s, SubBand *b, int is_arith)
+{
+ int cb_x, cb_y, left, right, top, bottom;
+ DiracArith c;
+ GetBitContext gb;
+ int cb_width = s->codeblock[b->level + (b->orientation != subband_ll)].width;
+ int cb_height = s->codeblock[b->level + (b->orientation != subband_ll)].height;
+ int blockcnt_one = (cb_width + cb_height) == 2;
+
+ if (!b->length)
+ return;
+
+ init_get_bits8(&gb, b->coeff_data, b->length);
+
+ if (is_arith)
+ ff_dirac_init_arith_decoder(&c, &gb, b->length);
+
+ top = 0;
+ for (cb_y = 0; cb_y < cb_height; cb_y++) {
+ bottom = (b->height * (cb_y+1LL)) / cb_height;
+ left = 0;
+ for (cb_x = 0; cb_x < cb_width; cb_x++) {
+ right = (b->width * (cb_x+1LL)) / cb_width;
+ codeblock(s, b, &gb, &c, left, right, top, bottom, blockcnt_one, is_arith);
+ left = right;
+ }
+ top = bottom;
+ }
+
+ if (b->orientation == subband_ll && s->num_refs == 0)
+ intra_dc_prediction(b);
+}
+
+static int decode_subband_arith(AVCodecContext *avctx, void *b)
+{
+ DiracContext *s = avctx->priv_data;
+ decode_subband_internal(s, b, 1);
+ return 0;
+}
+
+static int decode_subband_golomb(AVCodecContext *avctx, void *arg)
+{
+ DiracContext *s = avctx->priv_data;
+ SubBand **b = arg;
+ decode_subband_internal(s, *b, 0);
+ return 0;
+}
+
+/**
+ * Dirac Specification ->
+ * [DIRAC_STD] 13.4.1 core_transform_data()
+ */
+static void decode_component(DiracContext *s, int comp)
+{
+ AVCodecContext *avctx = s->avctx;
+ SubBand *bands[3*MAX_DWT_LEVELS+1];
+ enum dirac_subband orientation;
+ int level, num_bands = 0;
+
+ /* Unpack all subbands at all levels. */
+ for (level = 0; level < s->wavelet_depth; level++) {
+ for (orientation = !!level; orientation < 4; orientation++) {
+ SubBand *b = &s->plane[comp].band[level][orientation];
+ bands[num_bands++] = b;
+
+ align_get_bits(&s->gb);
+ /* [DIRAC_STD] 13.4.2 subband() */
+ b->length = svq3_get_ue_golomb(&s->gb);
+ if (b->length) {
+ b->quant = svq3_get_ue_golomb(&s->gb);
+ align_get_bits(&s->gb);
+ b->coeff_data = s->gb.buffer + get_bits_count(&s->gb)/8;
+ b->length = FFMIN(b->length, FFMAX(get_bits_left(&s->gb)/8, 0));
+ skip_bits_long(&s->gb, b->length*8);
+ }
+ }
+ /* arithmetic coding has inter-level dependencies, so we can only execute one level at a time */
+ if (s->is_arith)
+ avctx->execute(avctx, decode_subband_arith, &s->plane[comp].band[level][!!level],
+ NULL, 4-!!level, sizeof(SubBand));
+ }
+ /* golomb coding has no inter-level dependencies, so we can execute all subbands in parallel */
+ if (!s->is_arith)
+ avctx->execute(avctx, decode_subband_golomb, bands, NULL, num_bands, sizeof(SubBand*));
+}
+
+/* [DIRAC_STD] 13.5.5.2 Luma slice subband data. luma_slice_band(level,orient,sx,sy) --> if b2 == NULL */
+/* [DIRAC_STD] 13.5.5.3 Chroma slice subband data. chroma_slice_band(level,orient,sx,sy) --> if b2 != NULL */
+static void lowdelay_subband(DiracContext *s, GetBitContext *gb, int quant,
+ int slice_x, int slice_y, int bits_end,
+ SubBand *b1, SubBand *b2)
+{
+ int left = b1->width * slice_x / s->lowdelay.num_x;
+ int right = b1->width *(slice_x+1) / s->lowdelay.num_x;
+ int top = b1->height * slice_y / s->lowdelay.num_y;
+ int bottom = b1->height *(slice_y+1) / s->lowdelay.num_y;
+
+ int qfactor = qscale_tab[FFMIN(quant, MAX_QUANT)];
+ int qoffset = qoffset_intra_tab[FFMIN(quant, MAX_QUANT)];
+
+ IDWTELEM *buf1 = b1->ibuf + top * b1->stride;
+ IDWTELEM *buf2 = b2 ? b2->ibuf + top * b2->stride : NULL;
+ int x, y;
+ /* we have to constantly check for overread since the spec explicitly
+ requires this, with the meaning that all remaining coeffs are set to 0 */
+ if (get_bits_count(gb) >= bits_end)
+ return;
+
+ for (y = top; y < bottom; y++) {
+ for (x = left; x < right; x++) {
+ buf1[x] = coeff_unpack_golomb(gb, qfactor, qoffset);
+ if (get_bits_count(gb) >= bits_end)
+ return;
+ if (buf2) {
+ buf2[x] = coeff_unpack_golomb(gb, qfactor, qoffset);
+ if (get_bits_count(gb) >= bits_end)
+ return;
+ }
+ }
+ buf1 += b1->stride;
+ if (buf2)
+ buf2 += b2->stride;
+ }
+}
+
+struct lowdelay_slice {
+ GetBitContext gb;
+ int slice_x;
+ int slice_y;
+ int bytes;
+};
+
+
+/**
+ * Dirac Specification ->
+ * 13.5.2 Slices. slice(sx,sy)
+ */
+static int decode_lowdelay_slice(AVCodecContext *avctx, void *arg)
+{
+ DiracContext *s = avctx->priv_data;
+ struct lowdelay_slice *slice = arg;
+ GetBitContext *gb = &slice->gb;
+ enum dirac_subband orientation;
+ int level, quant, chroma_bits, chroma_end;
+
+ int quant_base = get_bits(gb, 7); /*[DIRAC_STD] qindex */
+ int length_bits = av_log2(8 * slice->bytes)+1;
+ int luma_bits = get_bits_long(gb, length_bits);
+ int luma_end = get_bits_count(gb) + FFMIN(luma_bits, get_bits_left(gb));
+
+ /* [DIRAC_STD] 13.5.5.2 luma_slice_band */
+ for (level = 0; level < s->wavelet_depth; level++)
+ for (orientation = !!level; orientation < 4; orientation++) {
+ quant = FFMAX(quant_base - s->lowdelay.quant[level][orientation], 0);
+ lowdelay_subband(s, gb, quant, slice->slice_x, slice->slice_y, luma_end,
+ &s->plane[0].band[level][orientation], NULL);
+ }
+
+ /* consume any unused bits from luma */
+ skip_bits_long(gb, get_bits_count(gb) - luma_end);
+
+ chroma_bits = 8*slice->bytes - 7 - length_bits - luma_bits;
+ chroma_end = get_bits_count(gb) + FFMIN(chroma_bits, get_bits_left(gb));
+ /* [DIRAC_STD] 13.5.5.3 chroma_slice_band */
+ for (level = 0; level < s->wavelet_depth; level++)
+ for (orientation = !!level; orientation < 4; orientation++) {
+ quant = FFMAX(quant_base - s->lowdelay.quant[level][orientation], 0);
+ lowdelay_subband(s, gb, quant, slice->slice_x, slice->slice_y, chroma_end,
+ &s->plane[1].band[level][orientation],
+ &s->plane[2].band[level][orientation]);
+ }
+
+ return 0;
+}
+
+/**
+ * Dirac Specification ->
+ * 13.5.1 low_delay_transform_data()
+ */
+static int decode_lowdelay(DiracContext *s)
+{
+ AVCodecContext *avctx = s->avctx;
+ int slice_x, slice_y, bytes, bufsize;
+ const uint8_t *buf;
+ struct lowdelay_slice *slices;
+ int slice_num = 0;
+
+ slices = av_mallocz_array(s->lowdelay.num_x, s->lowdelay.num_y * sizeof(struct lowdelay_slice));
+ if (!slices)
+ return AVERROR(ENOMEM);
+
+ align_get_bits(&s->gb);
+ /*[DIRAC_STD] 13.5.2 Slices. slice(sx,sy) */
+ buf = s->gb.buffer + get_bits_count(&s->gb)/8;
+ bufsize = get_bits_left(&s->gb);
+
+ for (slice_y = 0; bufsize > 0 && slice_y < s->lowdelay.num_y; slice_y++)
+ for (slice_x = 0; bufsize > 0 && slice_x < s->lowdelay.num_x; slice_x++) {
+ bytes = (slice_num+1) * s->lowdelay.bytes.num / s->lowdelay.bytes.den
+ - slice_num * s->lowdelay.bytes.num / s->lowdelay.bytes.den;
+
+ slices[slice_num].bytes = bytes;
+ slices[slice_num].slice_x = slice_x;
+ slices[slice_num].slice_y = slice_y;
+ init_get_bits(&slices[slice_num].gb, buf, bufsize);
+ slice_num++;
+
+ buf += bytes;
+ if (bufsize/8 >= bytes)
+ bufsize -= bytes*8;
+ else
+ bufsize = 0;
+ }
+
+ avctx->execute(avctx, decode_lowdelay_slice, slices, NULL, slice_num,
+ sizeof(struct lowdelay_slice)); /* [DIRAC_STD] 13.5.2 Slices */
+ intra_dc_prediction(&s->plane[0].band[0][0]); /* [DIRAC_STD] 13.3 intra_dc_prediction() */
+ intra_dc_prediction(&s->plane[1].band[0][0]); /* [DIRAC_STD] 13.3 intra_dc_prediction() */
+ intra_dc_prediction(&s->plane[2].band[0][0]); /* [DIRAC_STD] 13.3 intra_dc_prediction() */
+ av_free(slices);
+ return 0;
+}
+
+static void init_planes(DiracContext *s)
+{
+ int i, w, h, level, orientation;
+
+ for (i = 0; i < 3; i++) {
+ Plane *p = &s->plane[i];
+
+ p->width = s->source.width >> (i ? s->chroma_x_shift : 0);
+ p->height = s->source.height >> (i ? s->chroma_y_shift : 0);
+ p->idwt_width = w = CALC_PADDING(p->width , s->wavelet_depth);
+ p->idwt_height = h = CALC_PADDING(p->height, s->wavelet_depth);
+ p->idwt_stride = FFALIGN(p->idwt_width, 8);
+
+ for (level = s->wavelet_depth-1; level >= 0; level--) {
+ w = w>>1;
+ h = h>>1;
+ for (orientation = !!level; orientation < 4; orientation++) {
+ SubBand *b = &p->band[level][orientation];
+
+ b->ibuf = p->idwt_buf;
+ b->level = level;
+ b->stride = p->idwt_stride << (s->wavelet_depth - level);
+ b->width = w;
+ b->height = h;
+ b->orientation = orientation;
+
+ if (orientation & 1)
+ b->ibuf += w;
+ if (orientation > 1)
+ b->ibuf += b->stride>>1;
+
+ if (level)
+ b->parent = &p->band[level-1][orientation];
+ }
+ }
+
+ if (i > 0) {
+ p->xblen = s->plane[0].xblen >> s->chroma_x_shift;
+ p->yblen = s->plane[0].yblen >> s->chroma_y_shift;
+ p->xbsep = s->plane[0].xbsep >> s->chroma_x_shift;
+ p->ybsep = s->plane[0].ybsep >> s->chroma_y_shift;
+ }
+
+ p->xoffset = (p->xblen - p->xbsep)/2;
+ p->yoffset = (p->yblen - p->ybsep)/2;
+ }
+}
+
+/**
+ * Unpack the motion compensation parameters
+ * Dirac Specification ->
+ * 11.2 Picture prediction data. picture_prediction()
+ */
+static int dirac_unpack_prediction_parameters(DiracContext *s)
+{
+ static const uint8_t default_blen[] = { 4, 12, 16, 24 };
+
+ GetBitContext *gb = &s->gb;
+ unsigned idx, ref;
+
+ align_get_bits(gb);
+ /* [DIRAC_STD] 11.2.2 Block parameters. block_parameters() */
+ /* Luma and Chroma are equal. 11.2.3 */
+ idx = svq3_get_ue_golomb(gb); /* [DIRAC_STD] index */
+
+ if (idx > 4) {
+ av_log(s->avctx, AV_LOG_ERROR, "Block prediction index too high\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (idx == 0) {
+ s->plane[0].xblen = svq3_get_ue_golomb(gb);
+ s->plane[0].yblen = svq3_get_ue_golomb(gb);
+ s->plane[0].xbsep = svq3_get_ue_golomb(gb);
+ s->plane[0].ybsep = svq3_get_ue_golomb(gb);
+ } else {
+ /*[DIRAC_STD] preset_block_params(index). Table 11.1 */
+ s->plane[0].xblen = default_blen[idx-1];
+ s->plane[0].yblen = default_blen[idx-1];
+ s->plane[0].xbsep = 4 * idx;
+ s->plane[0].ybsep = 4 * idx;
+ }
+ /*[DIRAC_STD] 11.2.4 motion_data_dimensions()
+ Calculated in function dirac_unpack_block_motion_data */
+
+ if (s->plane[0].xblen % (1 << s->chroma_x_shift) != 0 ||
+ s->plane[0].yblen % (1 << s->chroma_y_shift) != 0 ||
+ !s->plane[0].xblen || !s->plane[0].yblen) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "invalid x/y block length (%d/%d) for x/y chroma shift (%d/%d)\n",
+ s->plane[0].xblen, s->plane[0].yblen, s->chroma_x_shift, s->chroma_y_shift);
+ return AVERROR_INVALIDDATA;
+ }
+ if (!s->plane[0].xbsep || !s->plane[0].ybsep || s->plane[0].xbsep < s->plane[0].xblen/2 || s->plane[0].ybsep < s->plane[0].yblen/2) {
+ av_log(s->avctx, AV_LOG_ERROR, "Block separation too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->plane[0].xbsep > s->plane[0].xblen || s->plane[0].ybsep > s->plane[0].yblen) {
+ av_log(s->avctx, AV_LOG_ERROR, "Block separation greater than size\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (FFMAX(s->plane[0].xblen, s->plane[0].yblen) > MAX_BLOCKSIZE) {
+ av_log(s->avctx, AV_LOG_ERROR, "Unsupported large block size\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ /*[DIRAC_STD] 11.2.5 Motion vector precision. motion_vector_precision()
+ Read motion vector precision */
+ s->mv_precision = svq3_get_ue_golomb(gb);
+ if (s->mv_precision > 3) {
+ av_log(s->avctx, AV_LOG_ERROR, "MV precision finer than eighth-pel\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /*[DIRAC_STD] 11.2.6 Global motion. global_motion()
+ Read the global motion compensation parameters */
+ s->globalmc_flag = get_bits1(gb);
+ if (s->globalmc_flag) {
+ memset(s->globalmc, 0, sizeof(s->globalmc));
+ /* [DIRAC_STD] pan_tilt(gparams) */
+ for (ref = 0; ref < s->num_refs; ref++) {
+ if (get_bits1(gb)) {
+ s->globalmc[ref].pan_tilt[0] = dirac_get_se_golomb(gb);
+ s->globalmc[ref].pan_tilt[1] = dirac_get_se_golomb(gb);
+ }
+ /* [DIRAC_STD] zoom_rotate_shear(gparams)
+ zoom/rotation/shear parameters */
+ if (get_bits1(gb)) {
+ s->globalmc[ref].zrs_exp = svq3_get_ue_golomb(gb);
+ s->globalmc[ref].zrs[0][0] = dirac_get_se_golomb(gb);
+ s->globalmc[ref].zrs[0][1] = dirac_get_se_golomb(gb);
+ s->globalmc[ref].zrs[1][0] = dirac_get_se_golomb(gb);
+ s->globalmc[ref].zrs[1][1] = dirac_get_se_golomb(gb);
+ } else {
+ s->globalmc[ref].zrs[0][0] = 1;
+ s->globalmc[ref].zrs[1][1] = 1;
+ }
+ /* [DIRAC_STD] perspective(gparams) */
+ if (get_bits1(gb)) {
+ s->globalmc[ref].perspective_exp = svq3_get_ue_golomb(gb);
+ s->globalmc[ref].perspective[0] = dirac_get_se_golomb(gb);
+ s->globalmc[ref].perspective[1] = dirac_get_se_golomb(gb);
+ }
+ }
+ }
+
+ /*[DIRAC_STD] 11.2.7 Picture prediction mode. prediction_mode()
+ Picture prediction mode, not currently used. */
+ if (svq3_get_ue_golomb(gb)) {
+ av_log(s->avctx, AV_LOG_ERROR, "Unknown picture prediction mode\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* [DIRAC_STD] 11.2.8 Reference picture weight. reference_picture_weights()
+ just data read, weight calculation will be done later on. */
+ s->weight_log2denom = 1;
+ s->weight[0] = 1;
+ s->weight[1] = 1;
+
+ if (get_bits1(gb)) {
+ s->weight_log2denom = svq3_get_ue_golomb(gb);
+ s->weight[0] = dirac_get_se_golomb(gb);
+ if (s->num_refs == 2)
+ s->weight[1] = dirac_get_se_golomb(gb);
+ }
+ return 0;
+}
+
+/**
+ * Dirac Specification ->
+ * 11.3 Wavelet transform data. wavelet_transform()
+ */
+static int dirac_unpack_idwt_params(DiracContext *s)
+{
+ GetBitContext *gb = &s->gb;
+ int i, level;
+ unsigned tmp;
+
+#define CHECKEDREAD(dst, cond, errmsg) \
+ tmp = svq3_get_ue_golomb(gb); \
+ if (cond) { \
+ av_log(s->avctx, AV_LOG_ERROR, errmsg); \
+ return AVERROR_INVALIDDATA; \
+ }\
+ dst = tmp;
+
+ align_get_bits(gb);
+
+ s->zero_res = s->num_refs ? get_bits1(gb) : 0;
+ if (s->zero_res)
+ return 0;
+
+ /*[DIRAC_STD] 11.3.1 Transform parameters. transform_parameters() */
+ CHECKEDREAD(s->wavelet_idx, tmp > 6, "wavelet_idx is too big\n")
+
+ CHECKEDREAD(s->wavelet_depth, tmp > MAX_DWT_LEVELS || tmp < 1, "invalid number of DWT decompositions\n")
+
+ if (!s->low_delay) {
+ /* Codeblock parameters (core syntax only) */
+ if (get_bits1(gb)) {
+ for (i = 0; i <= s->wavelet_depth; i++) {
+ CHECKEDREAD(s->codeblock[i].width , tmp < 1 || tmp > (s->avctx->width >>s->wavelet_depth-i), "codeblock width invalid\n")
+ CHECKEDREAD(s->codeblock[i].height, tmp < 1 || tmp > (s->avctx->height>>s->wavelet_depth-i), "codeblock height invalid\n")
+ }
+
+ CHECKEDREAD(s->codeblock_mode, tmp > 1, "unknown codeblock mode\n")
+ } else
+ for (i = 0; i <= s->wavelet_depth; i++)
+ s->codeblock[i].width = s->codeblock[i].height = 1;
+ } else {
+ /* Slice parameters + quantization matrix*/
+ /*[DIRAC_STD] 11.3.4 Slice coding Parameters (low delay syntax only). slice_parameters() */
+ s->lowdelay.num_x = svq3_get_ue_golomb(gb);
+ s->lowdelay.num_y = svq3_get_ue_golomb(gb);
+ if (s->lowdelay.num_x * s->lowdelay.num_y == 0 ||
+ s->lowdelay.num_x * (uint64_t)s->lowdelay.num_y > INT_MAX) {
+ av_log(s->avctx,AV_LOG_ERROR,"Invalid numx/y\n");
+ s->lowdelay.num_x = s->lowdelay.num_y = 0;
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->lowdelay.bytes.num = svq3_get_ue_golomb(gb);
+ s->lowdelay.bytes.den = svq3_get_ue_golomb(gb);
+
+ if (s->lowdelay.bytes.den <= 0) {
+ av_log(s->avctx,AV_LOG_ERROR,"Invalid lowdelay.bytes.den\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* [DIRAC_STD] 11.3.5 Quantisation matrices (low-delay syntax). quant_matrix() */
+ if (get_bits1(gb)) {
+ av_log(s->avctx,AV_LOG_DEBUG,"Low Delay: Has Custom Quantization Matrix!\n");
+ /* custom quantization matrix */
+ s->lowdelay.quant[0][0] = svq3_get_ue_golomb(gb);
+ for (level = 0; level < s->wavelet_depth; level++) {
+ s->lowdelay.quant[level][1] = svq3_get_ue_golomb(gb);
+ s->lowdelay.quant[level][2] = svq3_get_ue_golomb(gb);
+ s->lowdelay.quant[level][3] = svq3_get_ue_golomb(gb);
+ }
+ } else {
+ if (s->wavelet_depth > 4) {
+ av_log(s->avctx,AV_LOG_ERROR,"Mandatory custom low delay matrix missing for depth %d\n", s->wavelet_depth);
+ return AVERROR_INVALIDDATA;
+ }
+ /* default quantization matrix */
+ for (level = 0; level < s->wavelet_depth; level++)
+ for (i = 0; i < 4; i++) {
+ s->lowdelay.quant[level][i] = default_qmat[s->wavelet_idx][level][i];
+ /* haar with no shift differs for different depths */
+ if (s->wavelet_idx == 3)
+ s->lowdelay.quant[level][i] += 4*(s->wavelet_depth-1 - level);
+ }
+ }
+ }
+ return 0;
+}
+
+static inline int pred_sbsplit(uint8_t *sbsplit, int stride, int x, int y)
+{
+ static const uint8_t avgsplit[7] = { 0, 0, 1, 1, 1, 2, 2 };
+
+ if (!(x|y))
+ return 0;
+ else if (!y)
+ return sbsplit[-1];
+ else if (!x)
+ return sbsplit[-stride];
+
+ return avgsplit[sbsplit[-1] + sbsplit[-stride] + sbsplit[-stride-1]];
+}
+
+static inline int pred_block_mode(DiracBlock *block, int stride, int x, int y, int refmask)
+{
+ int pred;
+
+ if (!(x|y))
+ return 0;
+ else if (!y)
+ return block[-1].ref & refmask;
+ else if (!x)
+ return block[-stride].ref & refmask;
+
+ /* return the majority */
+ pred = (block[-1].ref & refmask) + (block[-stride].ref & refmask) + (block[-stride-1].ref & refmask);
+ return (pred >> 1) & refmask;
+}
+
+static inline void pred_block_dc(DiracBlock *block, int stride, int x, int y)
+{
+ int i, n = 0;
+
+ memset(block->u.dc, 0, sizeof(block->u.dc));
+
+ if (x && !(block[-1].ref & 3)) {
+ for (i = 0; i < 3; i++)
+ block->u.dc[i] += block[-1].u.dc[i];
+ n++;
+ }
+
+ if (y && !(block[-stride].ref & 3)) {
+ for (i = 0; i < 3; i++)
+ block->u.dc[i] += block[-stride].u.dc[i];
+ n++;
+ }
+
+ if (x && y && !(block[-1-stride].ref & 3)) {
+ for (i = 0; i < 3; i++)
+ block->u.dc[i] += block[-1-stride].u.dc[i];
+ n++;
+ }
+
+ if (n == 2) {
+ for (i = 0; i < 3; i++)
+ block->u.dc[i] = (block->u.dc[i]+1)>>1;
+ } else if (n == 3) {
+ for (i = 0; i < 3; i++)
+ block->u.dc[i] = divide3(block->u.dc[i]);
+ }
+}
+
+static inline void pred_mv(DiracBlock *block, int stride, int x, int y, int ref)
+{
+ int16_t *pred[3];
+ int refmask = ref+1;
+ int mask = refmask | DIRAC_REF_MASK_GLOBAL; /* exclude gmc blocks */
+ int n = 0;
+
+ if (x && (block[-1].ref & mask) == refmask)
+ pred[n++] = block[-1].u.mv[ref];
+
+ if (y && (block[-stride].ref & mask) == refmask)
+ pred[n++] = block[-stride].u.mv[ref];
+
+ if (x && y && (block[-stride-1].ref & mask) == refmask)
+ pred[n++] = block[-stride-1].u.mv[ref];
+
+ switch (n) {
+ case 0:
+ block->u.mv[ref][0] = 0;
+ block->u.mv[ref][1] = 0;
+ break;
+ case 1:
+ block->u.mv[ref][0] = pred[0][0];
+ block->u.mv[ref][1] = pred[0][1];
+ break;
+ case 2:
+ block->u.mv[ref][0] = (pred[0][0] + pred[1][0] + 1) >> 1;
+ block->u.mv[ref][1] = (pred[0][1] + pred[1][1] + 1) >> 1;
+ break;
+ case 3:
+ block->u.mv[ref][0] = mid_pred(pred[0][0], pred[1][0], pred[2][0]);
+ block->u.mv[ref][1] = mid_pred(pred[0][1], pred[1][1], pred[2][1]);
+ break;
+ }
+}
+
+static void global_mv(DiracContext *s, DiracBlock *block, int x, int y, int ref)
+{
+ int ez = s->globalmc[ref].zrs_exp;
+ int ep = s->globalmc[ref].perspective_exp;
+ int (*A)[2] = s->globalmc[ref].zrs;
+ int *b = s->globalmc[ref].pan_tilt;
+ int *c = s->globalmc[ref].perspective;
+
+ int m = (1<<ep) - (c[0]*x + c[1]*y);
+ int mx = m * ((A[0][0] * x + A[0][1]*y) + (1<<ez) * b[0]);
+ int my = m * ((A[1][0] * x + A[1][1]*y) + (1<<ez) * b[1]);
+
+ block->u.mv[ref][0] = (mx + (1<<(ez+ep))) >> (ez+ep);
+ block->u.mv[ref][1] = (my + (1<<(ez+ep))) >> (ez+ep);
+}
+
+static void decode_block_params(DiracContext *s, DiracArith arith[8], DiracBlock *block,
+ int stride, int x, int y)
+{
+ int i;
+
+ block->ref = pred_block_mode(block, stride, x, y, DIRAC_REF_MASK_REF1);
+ block->ref ^= dirac_get_arith_bit(arith, CTX_PMODE_REF1);
+
+ if (s->num_refs == 2) {
+ block->ref |= pred_block_mode(block, stride, x, y, DIRAC_REF_MASK_REF2);
+ block->ref ^= dirac_get_arith_bit(arith, CTX_PMODE_REF2) << 1;
+ }
+
+ if (!block->ref) {
+ pred_block_dc(block, stride, x, y);
+ for (i = 0; i < 3; i++)
+ block->u.dc[i] += dirac_get_arith_int(arith+1+i, CTX_DC_F1, CTX_DC_DATA);
+ return;
+ }
+
+ if (s->globalmc_flag) {
+ block->ref |= pred_block_mode(block, stride, x, y, DIRAC_REF_MASK_GLOBAL);
+ block->ref ^= dirac_get_arith_bit(arith, CTX_GLOBAL_BLOCK) << 2;
+ }
+
+ for (i = 0; i < s->num_refs; i++)
+ if (block->ref & (i+1)) {
+ if (block->ref & DIRAC_REF_MASK_GLOBAL) {
+ global_mv(s, block, x, y, i);
+ } else {
+ pred_mv(block, stride, x, y, i);
+ block->u.mv[i][0] += dirac_get_arith_int(arith + 4 + 2 * i, CTX_MV_F1, CTX_MV_DATA);
+ block->u.mv[i][1] += dirac_get_arith_int(arith + 5 + 2 * i, CTX_MV_F1, CTX_MV_DATA);
+ }
+ }
+}
+
+/**
+ * Copies the current block to the other blocks covered by the current superblock split mode
+ */
+static void propagate_block_data(DiracBlock *block, int stride, int size)
+{
+ int x, y;
+ DiracBlock *dst = block;
+
+ for (x = 1; x < size; x++)
+ dst[x] = *block;
+
+ for (y = 1; y < size; y++) {
+ dst += stride;
+ for (x = 0; x < size; x++)
+ dst[x] = *block;
+ }
+}
+
+/**
+ * Dirac Specification ->
+ * 12. Block motion data syntax
+ */
+static int dirac_unpack_block_motion_data(DiracContext *s)
+{
+ GetBitContext *gb = &s->gb;
+ uint8_t *sbsplit = s->sbsplit;
+ int i, x, y, q, p;
+ DiracArith arith[8];
+
+ align_get_bits(gb);
+
+ /* [DIRAC_STD] 11.2.4 and 12.2.1 Number of blocks and superblocks */
+ s->sbwidth = DIVRNDUP(s->source.width, 4*s->plane[0].xbsep);
+ s->sbheight = DIVRNDUP(s->source.height, 4*s->plane[0].ybsep);
+ s->blwidth = 4 * s->sbwidth;
+ s->blheight = 4 * s->sbheight;
+
+ /* [DIRAC_STD] 12.3.1 Superblock splitting modes. superblock_split_modes()
+ decode superblock split modes */
+ ff_dirac_init_arith_decoder(arith, gb, svq3_get_ue_golomb(gb)); /* svq3_get_ue_golomb(gb) is the length */
+ for (y = 0; y < s->sbheight; y++) {
+ for (x = 0; x < s->sbwidth; x++) {
+ unsigned int split = dirac_get_arith_uint(arith, CTX_SB_F1, CTX_SB_DATA);
+ if (split > 2)
+ return AVERROR_INVALIDDATA;
+ sbsplit[x] = (split + pred_sbsplit(sbsplit+x, s->sbwidth, x, y)) % 3;
+ }
+ sbsplit += s->sbwidth;
+ }
+
+ /* setup arith decoding */
+ ff_dirac_init_arith_decoder(arith, gb, svq3_get_ue_golomb(gb));
+ for (i = 0; i < s->num_refs; i++) {
+ ff_dirac_init_arith_decoder(arith + 4 + 2 * i, gb, svq3_get_ue_golomb(gb));
+ ff_dirac_init_arith_decoder(arith + 5 + 2 * i, gb, svq3_get_ue_golomb(gb));
+ }
+ for (i = 0; i < 3; i++)
+ ff_dirac_init_arith_decoder(arith+1+i, gb, svq3_get_ue_golomb(gb));
+
+ for (y = 0; y < s->sbheight; y++)
+ for (x = 0; x < s->sbwidth; x++) {
+ int blkcnt = 1 << s->sbsplit[y * s->sbwidth + x];
+ int step = 4 >> s->sbsplit[y * s->sbwidth + x];
+
+ for (q = 0; q < blkcnt; q++)
+ for (p = 0; p < blkcnt; p++) {
+ int bx = 4 * x + p*step;
+ int by = 4 * y + q*step;
+ DiracBlock *block = &s->blmotion[by*s->blwidth + bx];
+ decode_block_params(s, arith, block, s->blwidth, bx, by);
+ propagate_block_data(block, s->blwidth, step);
+ }
+ }
+
+ return 0;
+}
+
+static int weight(int i, int blen, int offset)
+{
+#define ROLLOFF(i) offset == 1 ? ((i) ? 5 : 3) : \
+ (1 + (6*(i) + offset - 1) / (2*offset - 1))
+
+ if (i < 2*offset)
+ return ROLLOFF(i);
+ else if (i > blen-1 - 2*offset)
+ return ROLLOFF(blen-1 - i);
+ return 8;
+}
+
+static void init_obmc_weight_row(Plane *p, uint8_t *obmc_weight, int stride,
+ int left, int right, int wy)
+{
+ int x;
+ for (x = 0; left && x < p->xblen >> 1; x++)
+ obmc_weight[x] = wy*8;
+ for (; x < p->xblen >> right; x++)
+ obmc_weight[x] = wy*weight(x, p->xblen, p->xoffset);
+ for (; x < p->xblen; x++)
+ obmc_weight[x] = wy*8;
+ for (; x < stride; x++)
+ obmc_weight[x] = 0;
+}
+
+static void init_obmc_weight(Plane *p, uint8_t *obmc_weight, int stride,
+ int left, int right, int top, int bottom)
+{
+ int y;
+ for (y = 0; top && y < p->yblen >> 1; y++) {
+ init_obmc_weight_row(p, obmc_weight, stride, left, right, 8);
+ obmc_weight += stride;
+ }
+ for (; y < p->yblen >> bottom; y++) {
+ int wy = weight(y, p->yblen, p->yoffset);
+ init_obmc_weight_row(p, obmc_weight, stride, left, right, wy);
+ obmc_weight += stride;
+ }
+ for (; y < p->yblen; y++) {
+ init_obmc_weight_row(p, obmc_weight, stride, left, right, 8);
+ obmc_weight += stride;
+ }
+}
+
+static void init_obmc_weights(DiracContext *s, Plane *p, int by)
+{
+ int top = !by;
+ int bottom = by == s->blheight-1;
+
+ /* don't bother re-initing for rows 2 to blheight-2, the weights don't change */
+ if (top || bottom || by == 1) {
+ init_obmc_weight(p, s->obmc_weight[0], MAX_BLOCKSIZE, 1, 0, top, bottom);
+ init_obmc_weight(p, s->obmc_weight[1], MAX_BLOCKSIZE, 0, 0, top, bottom);
+ init_obmc_weight(p, s->obmc_weight[2], MAX_BLOCKSIZE, 0, 1, top, bottom);
+ }
+}
+
+static const uint8_t epel_weights[4][4][4] = {
+ {{ 16, 0, 0, 0 },
+ { 12, 4, 0, 0 },
+ { 8, 8, 0, 0 },
+ { 4, 12, 0, 0 }},
+ {{ 12, 0, 4, 0 },
+ { 9, 3, 3, 1 },
+ { 6, 6, 2, 2 },
+ { 3, 9, 1, 3 }},
+ {{ 8, 0, 8, 0 },
+ { 6, 2, 6, 2 },
+ { 4, 4, 4, 4 },
+ { 2, 6, 2, 6 }},
+ {{ 4, 0, 12, 0 },
+ { 3, 1, 9, 3 },
+ { 2, 2, 6, 6 },
+ { 1, 3, 3, 9 }}
+};
+
+/**
+ * For block x,y, determine which of the hpel planes to do bilinear
+ * interpolation from and set src[] to the location in each hpel plane
+ * to MC from.
+ *
+ * @return the index of the put_dirac_pixels_tab function to use
+ * 0 for 1 plane (fpel,hpel), 1 for 2 planes (qpel), 2 for 4 planes (qpel), and 3 for epel
+ */
+static int mc_subpel(DiracContext *s, DiracBlock *block, const uint8_t *src[5],
+ int x, int y, int ref, int plane)
+{
+ Plane *p = &s->plane[plane];
+ uint8_t **ref_hpel = s->ref_pics[ref]->hpel[plane];
+ int motion_x = block->u.mv[ref][0];
+ int motion_y = block->u.mv[ref][1];
+ int mx, my, i, epel, nplanes = 0;
+
+ if (plane) {
+ motion_x >>= s->chroma_x_shift;
+ motion_y >>= s->chroma_y_shift;
+ }
+
+ mx = motion_x & ~(-1U << s->mv_precision);
+ my = motion_y & ~(-1U << s->mv_precision);
+ motion_x >>= s->mv_precision;
+ motion_y >>= s->mv_precision;
+ /* normalize subpel coordinates to epel */
+ /* TODO: template this function? */
+ mx <<= 3 - s->mv_precision;
+ my <<= 3 - s->mv_precision;
+
+ x += motion_x;
+ y += motion_y;
+ epel = (mx|my)&1;
+
+ /* hpel position */
+ if (!((mx|my)&3)) {
+ nplanes = 1;
+ src[0] = ref_hpel[(my>>1)+(mx>>2)] + y*p->stride + x;
+ } else {
+ /* qpel or epel */
+ nplanes = 4;
+ for (i = 0; i < 4; i++)
+ src[i] = ref_hpel[i] + y*p->stride + x;
+
+ /* if we're interpolating in the right/bottom halves, adjust the planes as needed
+ we increment x/y because the edge changes for half of the pixels */
+ if (mx > 4) {
+ src[0] += 1;
+ src[2] += 1;
+ x++;
+ }
+ if (my > 4) {
+ src[0] += p->stride;
+ src[1] += p->stride;
+ y++;
+ }
+
+ /* hpel planes are:
+ [0]: F [1]: H
+ [2]: V [3]: C */
+ if (!epel) {
+ /* check if we really only need 2 planes since either mx or my is
+ a hpel position. (epel weights of 0 handle this there) */
+ if (!(mx&3)) {
+ /* mx == 0: average [0] and [2]
+ mx == 4: average [1] and [3] */
+ src[!mx] = src[2 + !!mx];
+ nplanes = 2;
+ } else if (!(my&3)) {
+ src[0] = src[(my>>1) ];
+ src[1] = src[(my>>1)+1];
+ nplanes = 2;
+ }
+ } else {
+ /* adjust the ordering if needed so the weights work */
+ if (mx > 4) {
+ FFSWAP(const uint8_t *, src[0], src[1]);
+ FFSWAP(const uint8_t *, src[2], src[3]);
+ }
+ if (my > 4) {
+ FFSWAP(const uint8_t *, src[0], src[2]);
+ FFSWAP(const uint8_t *, src[1], src[3]);
+ }
+ src[4] = epel_weights[my&3][mx&3];
+ }
+ }
+
+ /* fixme: v/h _edge_pos */
+ if (x + p->xblen > p->width +EDGE_WIDTH/2 ||
+ y + p->yblen > p->height+EDGE_WIDTH/2 ||
+ x < 0 || y < 0) {
+ for (i = 0; i < nplanes; i++) {
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer[i], src[i],
+ p->stride, p->stride,
+ p->xblen, p->yblen, x, y,
+ p->width+EDGE_WIDTH/2, p->height+EDGE_WIDTH/2);
+ src[i] = s->edge_emu_buffer[i];
+ }
+ }
+ return (nplanes>>1) + epel;
+}
+
+static void add_dc(uint16_t *dst, int dc, int stride,
+ uint8_t *obmc_weight, int xblen, int yblen)
+{
+ int x, y;
+ dc += 128;
+
+ for (y = 0; y < yblen; y++) {
+ for (x = 0; x < xblen; x += 2) {
+ dst[x ] += dc * obmc_weight[x ];
+ dst[x+1] += dc * obmc_weight[x+1];
+ }
+ dst += stride;
+ obmc_weight += MAX_BLOCKSIZE;
+ }
+}
+
+static void block_mc(DiracContext *s, DiracBlock *block,
+ uint16_t *mctmp, uint8_t *obmc_weight,
+ int plane, int dstx, int dsty)
+{
+ Plane *p = &s->plane[plane];
+ const uint8_t *src[5];
+ int idx;
+
+ switch (block->ref&3) {
+ case 0: /* DC */
+ add_dc(mctmp, block->u.dc[plane], p->stride, obmc_weight, p->xblen, p->yblen);
+ return;
+ case 1:
+ case 2:
+ idx = mc_subpel(s, block, src, dstx, dsty, (block->ref&3)-1, plane);
+ s->put_pixels_tab[idx](s->mcscratch, src, p->stride, p->yblen);
+ if (s->weight_func)
+ s->weight_func(s->mcscratch, p->stride, s->weight_log2denom,
+ s->weight[0] + s->weight[1], p->yblen);
+ break;
+ case 3:
+ idx = mc_subpel(s, block, src, dstx, dsty, 0, plane);
+ s->put_pixels_tab[idx](s->mcscratch, src, p->stride, p->yblen);
+ idx = mc_subpel(s, block, src, dstx, dsty, 1, plane);
+ if (s->biweight_func) {
+ /* fixme: +32 is a quick hack */
+ s->put_pixels_tab[idx](s->mcscratch + 32, src, p->stride, p->yblen);
+ s->biweight_func(s->mcscratch, s->mcscratch+32, p->stride, s->weight_log2denom,
+ s->weight[0], s->weight[1], p->yblen);
+ } else
+ s->avg_pixels_tab[idx](s->mcscratch, src, p->stride, p->yblen);
+ break;
+ }
+ s->add_obmc(mctmp, s->mcscratch, p->stride, obmc_weight, p->yblen);
+}
+
+static void mc_row(DiracContext *s, DiracBlock *block, uint16_t *mctmp, int plane, int dsty)
+{
+ Plane *p = &s->plane[plane];
+ int x, dstx = p->xbsep - p->xoffset;
+
+ block_mc(s, block, mctmp, s->obmc_weight[0], plane, -p->xoffset, dsty);
+ mctmp += p->xbsep;
+
+ for (x = 1; x < s->blwidth-1; x++) {
+ block_mc(s, block+x, mctmp, s->obmc_weight[1], plane, dstx, dsty);
+ dstx += p->xbsep;
+ mctmp += p->xbsep;
+ }
+ block_mc(s, block+x, mctmp, s->obmc_weight[2], plane, dstx, dsty);
+}
+
+static void select_dsp_funcs(DiracContext *s, int width, int height, int xblen, int yblen)
+{
+ int idx = 0;
+ if (xblen > 8)
+ idx = 1;
+ if (xblen > 16)
+ idx = 2;
+
+ memcpy(s->put_pixels_tab, s->diracdsp.put_dirac_pixels_tab[idx], sizeof(s->put_pixels_tab));
+ memcpy(s->avg_pixels_tab, s->diracdsp.avg_dirac_pixels_tab[idx], sizeof(s->avg_pixels_tab));
+ s->add_obmc = s->diracdsp.add_dirac_obmc[idx];
+ if (s->weight_log2denom > 1 || s->weight[0] != 1 || s->weight[1] != 1) {
+ s->weight_func = s->diracdsp.weight_dirac_pixels_tab[idx];
+ s->biweight_func = s->diracdsp.biweight_dirac_pixels_tab[idx];
+ } else {
+ s->weight_func = NULL;
+ s->biweight_func = NULL;
+ }
+}
+
+static int interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, int width, int height)
+{
+ /* chroma allocates an edge of 8 when subsampled
+ which for 4:2:2 means an h edge of 16 and v edge of 8
+ just use 8 for everything for the moment */
+ int i, edge = EDGE_WIDTH/2;
+
+ ref->hpel[plane][0] = ref->avframe->data[plane];
+ s->mpvencdsp.draw_edges(ref->hpel[plane][0], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */
+
+ /* no need for hpel if we only have fpel vectors */
+ if (!s->mv_precision)
+ return 0;
+
+ for (i = 1; i < 4; i++) {
+ if (!ref->hpel_base[plane][i])
+ ref->hpel_base[plane][i] = av_malloc((height+2*edge) * ref->avframe->linesize[plane] + 32);
+ if (!ref->hpel_base[plane][i]) {
+ return AVERROR(ENOMEM);
+ }
+ /* we need to be 16-byte aligned even for chroma */
+ ref->hpel[plane][i] = ref->hpel_base[plane][i] + edge*ref->avframe->linesize[plane] + 16;
+ }
+
+ if (!ref->interpolated[plane]) {
+ s->diracdsp.dirac_hpel_filter(ref->hpel[plane][1], ref->hpel[plane][2],
+ ref->hpel[plane][3], ref->hpel[plane][0],
+ ref->avframe->linesize[plane], width, height);
+ s->mpvencdsp.draw_edges(ref->hpel[plane][1], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
+ s->mpvencdsp.draw_edges(ref->hpel[plane][2], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
+ s->mpvencdsp.draw_edges(ref->hpel[plane][3], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM);
+ }
+ ref->interpolated[plane] = 1;
+
+ return 0;
+}
+
+/**
+ * Dirac Specification ->
+ * 13.0 Transform data syntax. transform_data()
+ */
+static int dirac_decode_frame_internal(DiracContext *s)
+{
+ DWTContext d;
+ int y, i, comp, dsty;
+ int ret;
+
+ if (s->low_delay) {
+ /* [DIRAC_STD] 13.5.1 low_delay_transform_data() */
+ for (comp = 0; comp < 3; comp++) {
+ Plane *p = &s->plane[comp];
+ memset(p->idwt_buf, 0, p->idwt_stride * p->idwt_height * sizeof(IDWTELEM));
+ }
+ if (!s->zero_res) {
+ if ((ret = decode_lowdelay(s)) < 0)
+ return ret;
+ }
+ }
+
+ for (comp = 0; comp < 3; comp++) {
+ Plane *p = &s->plane[comp];
+ uint8_t *frame = s->current_picture->avframe->data[comp];
+
+ /* FIXME: small resolutions */
+ for (i = 0; i < 4; i++)
+ s->edge_emu_buffer[i] = s->edge_emu_buffer_base + i*FFALIGN(p->width, 16);
+
+ if (!s->zero_res && !s->low_delay)
+ {
+ memset(p->idwt_buf, 0, p->idwt_stride * p->idwt_height * sizeof(IDWTELEM));
+ decode_component(s, comp); /* [DIRAC_STD] 13.4.1 core_transform_data() */
+ }
+ ret = ff_spatial_idwt_init2(&d, p->idwt_buf, p->idwt_width, p->idwt_height, p->idwt_stride,
+ s->wavelet_idx+2, s->wavelet_depth, p->idwt_tmp);
+ if (ret < 0)
+ return ret;
+
+ if (!s->num_refs) { /* intra */
+ for (y = 0; y < p->height; y += 16) {
+ ff_spatial_idwt_slice2(&d, y+16); /* decode */
+ s->diracdsp.put_signed_rect_clamped(frame + y*p->stride, p->stride,
+ p->idwt_buf + y*p->idwt_stride, p->idwt_stride, p->width, 16);
+ }
+ } else { /* inter */
+ int rowheight = p->ybsep*p->stride;
+
+ select_dsp_funcs(s, p->width, p->height, p->xblen, p->yblen);
+
+ for (i = 0; i < s->num_refs; i++) {
+ int ret = interpolate_refplane(s, s->ref_pics[i], comp, p->width, p->height);
+ if (ret < 0)
+ return ret;
+ }
+
+ memset(s->mctmp, 0, 4*p->yoffset*p->stride);
+
+ dsty = -p->yoffset;
+ for (y = 0; y < s->blheight; y++) {
+ int h = 0,
+ start = FFMAX(dsty, 0);
+ uint16_t *mctmp = s->mctmp + y*rowheight;
+ DiracBlock *blocks = s->blmotion + y*s->blwidth;
+
+ init_obmc_weights(s, p, y);
+
+ if (y == s->blheight-1 || start+p->ybsep > p->height)
+ h = p->height - start;
+ else
+ h = p->ybsep - (start - dsty);
+ if (h < 0)
+ break;
+
+ memset(mctmp+2*p->yoffset*p->stride, 0, 2*rowheight);
+ mc_row(s, blocks, mctmp, comp, dsty);
+
+ mctmp += (start - dsty)*p->stride + p->xoffset;
+ ff_spatial_idwt_slice2(&d, start + h); /* decode */
+ s->diracdsp.add_rect_clamped(frame + start*p->stride, mctmp, p->stride,
+ p->idwt_buf + start*p->idwt_stride, p->idwt_stride, p->width, h);
+
+ dsty += p->ybsep;
+ }
+ }
+ }
+
+
+ return 0;
+}
+
+static int get_buffer_with_edge(AVCodecContext *avctx, AVFrame *f, int flags)
+{
+ int ret, i;
+ int chroma_x_shift, chroma_y_shift;
+ avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_x_shift, &chroma_y_shift);
+
+ f->width = avctx->width + 2 * EDGE_WIDTH;
+ f->height = avctx->height + 2 * EDGE_WIDTH + 2;
+ ret = ff_get_buffer(avctx, f, flags);
+ if (ret < 0)
+ return ret;
+
+ for (i = 0; f->data[i]; i++) {
+ int offset = (EDGE_WIDTH >> (i && i<3 ? chroma_y_shift : 0)) *
+ f->linesize[i] + 32;
+ f->data[i] += offset;
+ }
+ f->width = avctx->width;
+ f->height = avctx->height;
+
+ return 0;
+}
+
+/**
+ * Dirac Specification ->
+ * 11.1.1 Picture Header. picture_header()
+ */
+static int dirac_decode_picture_header(DiracContext *s)
+{
+ unsigned retire, picnum;
+ int i, j, ret;
+ int64_t refdist, refnum;
+ GetBitContext *gb = &s->gb;
+
+ /* [DIRAC_STD] 11.1.1 Picture Header. picture_header() PICTURE_NUM */
+ picnum = s->current_picture->avframe->display_picture_number = get_bits_long(gb, 32);
+
+
+ av_log(s->avctx,AV_LOG_DEBUG,"PICTURE_NUM: %d\n",picnum);
+
+ /* if this is the first keyframe after a sequence header, start our
+ reordering from here */
+ if (s->frame_number < 0)
+ s->frame_number = picnum;
+
+ s->ref_pics[0] = s->ref_pics[1] = NULL;
+ for (i = 0; i < s->num_refs; i++) {
+ refnum = (picnum + dirac_get_se_golomb(gb)) & 0xFFFFFFFF;
+ refdist = INT64_MAX;
+
+ /* find the closest reference to the one we want */
+ /* Jordi: this is needed if the referenced picture hasn't yet arrived */
+ for (j = 0; j < MAX_REFERENCE_FRAMES && refdist; j++)
+ if (s->ref_frames[j]
+ && FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum) < refdist) {
+ s->ref_pics[i] = s->ref_frames[j];
+ refdist = FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum);
+ }
+
+ if (!s->ref_pics[i] || refdist)
+ av_log(s->avctx, AV_LOG_DEBUG, "Reference not found\n");
+
+ /* if there were no references at all, allocate one */
+ if (!s->ref_pics[i])
+ for (j = 0; j < MAX_FRAMES; j++)
+ if (!s->all_frames[j].avframe->data[0]) {
+ s->ref_pics[i] = &s->all_frames[j];
+ ret = get_buffer_with_edge(s->avctx, s->ref_pics[i]->avframe, AV_GET_BUFFER_FLAG_REF);
+ if (ret < 0)
+ return ret;
+ break;
+ }
+
+ if (!s->ref_pics[i]) {
+ av_log(s->avctx, AV_LOG_ERROR, "Reference could not be allocated\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ }
+
+ /* retire the reference frames that are not used anymore */
+ if (s->current_picture->reference) {
+ retire = (picnum + dirac_get_se_golomb(gb)) & 0xFFFFFFFF;
+ if (retire != picnum) {
+ DiracFrame *retire_pic = remove_frame(s->ref_frames, retire);
+
+ if (retire_pic)
+ retire_pic->reference &= DELAYED_PIC_REF;
+ else
+ av_log(s->avctx, AV_LOG_DEBUG, "Frame to retire not found\n");
+ }
+
+ /* if reference array is full, remove the oldest as per the spec */
+ while (add_frame(s->ref_frames, MAX_REFERENCE_FRAMES, s->current_picture)) {
+ av_log(s->avctx, AV_LOG_ERROR, "Reference frame overflow\n");
+ remove_frame(s->ref_frames, s->ref_frames[0]->avframe->display_picture_number)->reference &= DELAYED_PIC_REF;
+ }
+ }
+
+ if (s->num_refs) {
+ ret = dirac_unpack_prediction_parameters(s); /* [DIRAC_STD] 11.2 Picture Prediction Data. picture_prediction() */
+ if (ret < 0)
+ return ret;
+ ret = dirac_unpack_block_motion_data(s); /* [DIRAC_STD] 12. Block motion data syntax */
+ if (ret < 0)
+ return ret;
+ }
+ ret = dirac_unpack_idwt_params(s); /* [DIRAC_STD] 11.3 Wavelet transform data */
+ if (ret < 0)
+ return ret;
+
+ init_planes(s);
+ return 0;
+}
+
+static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame)
+{
+ DiracFrame *out = s->delay_frames[0];
+ int i, out_idx = 0;
+ int ret;
+
+ /* find frame with lowest picture number */
+ for (i = 1; s->delay_frames[i]; i++)
+ if (s->delay_frames[i]->avframe->display_picture_number < out->avframe->display_picture_number) {
+ out = s->delay_frames[i];
+ out_idx = i;
+ }
+
+ for (i = out_idx; s->delay_frames[i]; i++)
+ s->delay_frames[i] = s->delay_frames[i+1];
+
+ if (out) {
+ out->reference ^= DELAYED_PIC_REF;
+ if((ret = av_frame_ref(picture, out->avframe)) < 0)
+ return ret;
+ *got_frame = 1;
+ }
+
+ return 0;
+}
+
+/**
+ * Dirac Specification ->
+ * 9.6 Parse Info Header Syntax. parse_info()
+ * 4 byte start code + byte parse code + 4 byte size + 4 byte previous size
+ */
+#define DATA_UNIT_HEADER_SIZE 13
+
+/* [DIRAC_STD] dirac_decode_data_unit makes reference to the while defined in 9.3
+ inside the function parse_sequence() */
+static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int size)
+{
+ DiracContext *s = avctx->priv_data;
+ DiracFrame *pic = NULL;
+ int ret, i, parse_code;
+ unsigned tmp;
+
+ if (size < DATA_UNIT_HEADER_SIZE)
+ return AVERROR_INVALIDDATA;
+
+ parse_code = buf[4];
+
+ init_get_bits(&s->gb, &buf[13], 8*(size - DATA_UNIT_HEADER_SIZE));
+
+ if (parse_code == pc_seq_header) {
+ if (s->seen_sequence_header)
+ return 0;
+
+ /* [DIRAC_STD] 10. Sequence header */
+ ret = avpriv_dirac_parse_sequence_header(avctx, &s->gb, &s->source);
+ if (ret < 0)
+ return ret;
+
+ avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift);
+
+ ret = alloc_sequence_buffers(s);
+ if (ret < 0)
+ return ret;
+
+ s->seen_sequence_header = 1;
+ } else if (parse_code == pc_eos) { /* [DIRAC_STD] End of Sequence */
+ free_sequence_buffers(s);
+ s->seen_sequence_header = 0;
+ } else if (parse_code == pc_aux_data) {
+ if (buf[13] == 1) { /* encoder implementation/version */
+ int ver[3];
+ /* versions older than 1.0.8 don't store quant delta for
+ subbands with only one codeblock */
+ if (sscanf(buf+14, "Schroedinger %d.%d.%d", ver, ver+1, ver+2) == 3)
+ if (ver[0] == 1 && ver[1] == 0 && ver[2] <= 7)
+ s->old_delta_quant = 1;
+ }
+ } else if (parse_code & 0x8) { /* picture data unit */
+ if (!s->seen_sequence_header) {
+ av_log(avctx, AV_LOG_DEBUG, "Dropping frame without sequence header\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* find an unused frame */
+ for (i = 0; i < MAX_FRAMES; i++)
+ if (s->all_frames[i].avframe->data[0] == NULL)
+ pic = &s->all_frames[i];
+ if (!pic) {
+ av_log(avctx, AV_LOG_ERROR, "framelist full\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ av_frame_unref(pic->avframe);
+
+ /* [DIRAC_STD] Defined in 9.6.1 ... */
+ tmp = parse_code & 0x03; /* [DIRAC_STD] num_refs() */
+ if (tmp > 2) {
+ av_log(avctx, AV_LOG_ERROR, "num_refs of 3\n");
+ return AVERROR_INVALIDDATA;
+ }
+ s->num_refs = tmp;
+ s->is_arith = (parse_code & 0x48) == 0x08; /* [DIRAC_STD] using_ac() */
+ s->low_delay = (parse_code & 0x88) == 0x88; /* [DIRAC_STD] is_low_delay() */
+ pic->reference = (parse_code & 0x0C) == 0x0C; /* [DIRAC_STD] is_reference() */
+ pic->avframe->key_frame = s->num_refs == 0; /* [DIRAC_STD] is_intra() */
+ pic->avframe->pict_type = s->num_refs + 1; /* Definition of AVPictureType in avutil.h */
+
+ if ((ret = get_buffer_with_edge(avctx, pic->avframe, (parse_code & 0x0C) == 0x0C ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
+ return ret;
+ s->current_picture = pic;
+ s->plane[0].stride = pic->avframe->linesize[0];
+ s->plane[1].stride = pic->avframe->linesize[1];
+ s->plane[2].stride = pic->avframe->linesize[2];
+
+ if (alloc_buffers(s, FFMAX3(FFABS(s->plane[0].stride), FFABS(s->plane[1].stride), FFABS(s->plane[2].stride))) < 0)
+ return AVERROR(ENOMEM);
+
+ /* [DIRAC_STD] 11.1 Picture parse. picture_parse() */
+ ret = dirac_decode_picture_header(s);
+ if (ret < 0)
+ return ret;
+
+ /* [DIRAC_STD] 13.0 Transform data syntax. transform_data() */
+ ret = dirac_decode_frame_internal(s);
+ if (ret < 0)
+ return ret;
+ }
+ return 0;
+}
+
+static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt)
+{
+ DiracContext *s = avctx->priv_data;
+ AVFrame *picture = data;
+ uint8_t *buf = pkt->data;
+ int buf_size = pkt->size;
+ int i, buf_idx = 0;
+ int ret;
+ unsigned data_unit_size;
+
+ /* release unused frames */
+ for (i = 0; i < MAX_FRAMES; i++)
+ if (s->all_frames[i].avframe->data[0] && !s->all_frames[i].reference) {
+ av_frame_unref(s->all_frames[i].avframe);
+ memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated));
+ }
+
+ s->current_picture = NULL;
+ *got_frame = 0;
+
+ /* end of stream, so flush delayed pics */
+ if (buf_size == 0)
+ return get_delayed_pic(s, (AVFrame *)data, got_frame);
+
+ for (;;) {
+ /*[DIRAC_STD] Here starts the code from parse_info() defined in 9.6
+ [DIRAC_STD] PARSE_INFO_PREFIX = "BBCD" as defined in ISO/IEC 646
+ BBCD start code search */
+ for (; buf_idx + DATA_UNIT_HEADER_SIZE < buf_size; buf_idx++) {
+ if (buf[buf_idx ] == 'B' && buf[buf_idx+1] == 'B' &&
+ buf[buf_idx+2] == 'C' && buf[buf_idx+3] == 'D')
+ break;
+ }
+ /* BBCD found or end of data */
+ if (buf_idx + DATA_UNIT_HEADER_SIZE >= buf_size)
+ break;
+
+ data_unit_size = AV_RB32(buf+buf_idx+5);
+ if (data_unit_size > buf_size - buf_idx || !data_unit_size) {
+ if(data_unit_size > buf_size - buf_idx)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Data unit with size %d is larger than input buffer, discarding\n",
+ data_unit_size);
+ buf_idx += 4;
+ continue;
+ }
+ /* [DIRAC_STD] dirac_decode_data_unit makes reference to the while defined in 9.3 inside the function parse_sequence() */
+ ret = dirac_decode_data_unit(avctx, buf+buf_idx, data_unit_size);
+ if (ret < 0)
+ {
+ av_log(s->avctx, AV_LOG_ERROR,"Error in dirac_decode_data_unit\n");
+ return ret;
+ }
+ buf_idx += data_unit_size;
+ }
+
+ if (!s->current_picture)
+ return buf_size;
+
+ if (s->current_picture->avframe->display_picture_number > s->frame_number) {
+ DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number);
+
+ s->current_picture->reference |= DELAYED_PIC_REF;
+
+ if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) {
+ int min_num = s->delay_frames[0]->avframe->display_picture_number;
+ /* Too many delayed frames, so we display the frame with the lowest pts */
+ av_log(avctx, AV_LOG_ERROR, "Delay frame overflow\n");
+
+ for (i = 1; s->delay_frames[i]; i++)
+ if (s->delay_frames[i]->avframe->display_picture_number < min_num)
+ min_num = s->delay_frames[i]->avframe->display_picture_number;
+
+ delayed_frame = remove_frame(s->delay_frames, min_num);
+ add_frame(s->delay_frames, MAX_DELAY, s->current_picture);
+ }
+
+ if (delayed_frame) {
+ delayed_frame->reference ^= DELAYED_PIC_REF;
+ if((ret=av_frame_ref(data, delayed_frame->avframe)) < 0)
+ return ret;
+ *got_frame = 1;
+ }
+ } else if (s->current_picture->avframe->display_picture_number == s->frame_number) {
+ /* The right frame at the right time :-) */
+ if((ret=av_frame_ref(data, s->current_picture->avframe)) < 0)
+ return ret;
+ *got_frame = 1;
+ }
+
+ if (*got_frame)
+ s->frame_number = picture->display_picture_number + 1;
+
+ return buf_idx;
+}
+
+AVCodec ff_dirac_decoder = {
+ .name = "dirac",
+ .long_name = NULL_IF_CONFIG_SMALL("BBC Dirac VC-2"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_DIRAC,
+ .priv_data_size = sizeof(DiracContext),
+ .init = dirac_decode_init,
+ .close = dirac_decode_end,
+ .decode = dirac_decode_frame,
+ .capabilities = AV_CODEC_CAP_DELAY,
+ .flush = dirac_decode_flush,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/diracdsp.c b/ffmpeg-2-8-12/libavcodec/diracdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/diracdsp.c
rename to ffmpeg-2-8-12/libavcodec/diracdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/diracdsp.h b/ffmpeg-2-8-12/libavcodec/diracdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/diracdsp.h
rename to ffmpeg-2-8-12/libavcodec/diracdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/dnxhd_parser.c b/ffmpeg-2-8-12/libavcodec/dnxhd_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dnxhd_parser.c
rename to ffmpeg-2-8-12/libavcodec/dnxhd_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/dnxhddata.c b/ffmpeg-2-8-12/libavcodec/dnxhddata.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dnxhddata.c
rename to ffmpeg-2-8-12/libavcodec/dnxhddata.c
diff --git a/ffmpeg-2-8-11/libavcodec/dnxhddata.h b/ffmpeg-2-8-12/libavcodec/dnxhddata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dnxhddata.h
rename to ffmpeg-2-8-12/libavcodec/dnxhddata.h
diff --git a/ffmpeg-2-8-11/libavcodec/dnxhddec.c b/ffmpeg-2-8-12/libavcodec/dnxhddec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dnxhddec.c
rename to ffmpeg-2-8-12/libavcodec/dnxhddec.c
diff --git a/ffmpeg-2-8-11/libavcodec/dnxhdenc.c b/ffmpeg-2-8-12/libavcodec/dnxhdenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dnxhdenc.c
rename to ffmpeg-2-8-12/libavcodec/dnxhdenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/dnxhdenc.h b/ffmpeg-2-8-12/libavcodec/dnxhdenc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dnxhdenc.h
rename to ffmpeg-2-8-12/libavcodec/dnxhdenc.h
diff --git a/ffmpeg-2-8-11/libavcodec/dpcm.c b/ffmpeg-2-8-12/libavcodec/dpcm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dpcm.c
rename to ffmpeg-2-8-12/libavcodec/dpcm.c
diff --git a/ffmpeg-2-8-11/libavcodec/dpx.c b/ffmpeg-2-8-12/libavcodec/dpx.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dpx.c
rename to ffmpeg-2-8-12/libavcodec/dpx.c
diff --git a/ffmpeg-2-8-11/libavcodec/dpx_parser.c b/ffmpeg-2-8-12/libavcodec/dpx_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dpx_parser.c
rename to ffmpeg-2-8-12/libavcodec/dpx_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/dpxenc.c b/ffmpeg-2-8-12/libavcodec/dpxenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dpxenc.c
rename to ffmpeg-2-8-12/libavcodec/dpxenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/dsd_tablegen.c b/ffmpeg-2-8-12/libavcodec/dsd_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dsd_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/dsd_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/dsd_tablegen.h b/ffmpeg-2-8-12/libavcodec/dsd_tablegen.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dsd_tablegen.h
rename to ffmpeg-2-8-12/libavcodec/dsd_tablegen.h
diff --git a/ffmpeg-2-8-11/libavcodec/dsddec.c b/ffmpeg-2-8-12/libavcodec/dsddec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dsddec.c
rename to ffmpeg-2-8-12/libavcodec/dsddec.c
diff --git a/ffmpeg-2-8-11/libavcodec/dsicinaudio.c b/ffmpeg-2-8-12/libavcodec/dsicinaudio.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dsicinaudio.c
rename to ffmpeg-2-8-12/libavcodec/dsicinaudio.c
diff --git a/ffmpeg-2-8-11/libavcodec/dsicinvideo.c b/ffmpeg-2-8-12/libavcodec/dsicinvideo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dsicinvideo.c
rename to ffmpeg-2-8-12/libavcodec/dsicinvideo.c
diff --git a/ffmpeg-2-8-12/libavcodec/dss_sp.c b/ffmpeg-2-8-12/libavcodec/dss_sp.c
new file mode 100644
index 0000000..f5dfda3
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/dss_sp.c
@@ -0,0 +1,787 @@
+/*
+ * Digital Speech Standard - Standard Play mode (DSS SP) audio decoder.
+ * Copyright (C) 2014 Oleksij Rempel <linux at rempel-privat.de>
+ *
+ * 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/common.h"
+#include "libavutil/mem.h"
+#include "libavutil/opt.h"
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "internal.h"
+
+#define SUBFRAMES 4
+#define PULSE_MAX 8
+
+#define DSS_SP_FRAME_SIZE 42
+#define DSS_SP_SAMPLE_COUNT (66 * SUBFRAMES)
+#define DSS_SP_FORMULA(a, b, c) ((int)((((a) * (1 << 15)) + (b) * (unsigned)(c)) + 0x4000) >> 15)
+
+typedef struct DssSpSubframe {
+ int16_t gain;
+ int32_t combined_pulse_pos;
+ int16_t pulse_pos[7];
+ int16_t pulse_val[7];
+} DssSpSubframe;
+
+typedef struct DssSpFrame {
+ int16_t filter_idx[14];
+ int16_t sf_adaptive_gain[SUBFRAMES];
+ int16_t pitch_lag[SUBFRAMES];
+ struct DssSpSubframe sf[SUBFRAMES];
+} DssSpFrame;
+
+typedef struct DssSpContext {
+ AVCodecContext *avctx;
+ int32_t excitation[288 + 6];
+ int32_t history[187];
+ DssSpFrame fparam;
+ int32_t working_buffer[SUBFRAMES][72];
+ int32_t audio_buf[15];
+ int32_t err_buf1[15];
+ int32_t lpc_filter[14];
+ int32_t filter[15];
+ int32_t vector_buf[72];
+ int noise_state;
+ int32_t err_buf2[15];
+
+ int pulse_dec_mode;
+
+ DECLARE_ALIGNED(16, uint8_t, bits)[DSS_SP_FRAME_SIZE +
+ AV_INPUT_BUFFER_PADDING_SIZE];
+} DssSpContext;
+
+/*
+ * Used for the coding/decoding of the pulse positions for the MP-MLQ codebook.
+ */
+static const uint32_t dss_sp_combinatorial_table[PULSE_MAX][72] = {
+ { 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0 },
+ { 0, 1, 2, 3, 4, 5,
+ 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53,
+ 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71 },
+ { 0, 0, 1, 3, 6, 10,
+ 15, 21, 28, 36, 45, 55,
+ 66, 78, 91, 105, 120, 136,
+ 153, 171, 190, 210, 231, 253,
+ 276, 300, 325, 351, 378, 406,
+ 435, 465, 496, 528, 561, 595,
+ 630, 666, 703, 741, 780, 820,
+ 861, 903, 946, 990, 1035, 1081,
+ 1128, 1176, 1225, 1275, 1326, 1378,
+ 1431, 1485, 1540, 1596, 1653, 1711,
+ 1770, 1830, 1891, 1953, 2016, 2080,
+ 2145, 2211, 2278, 2346, 2415, 2485 },
+ { 0, 0, 0, 1, 4, 10,
+ 20, 35, 56, 84, 120, 165,
+ 220, 286, 364, 455, 560, 680,
+ 816, 969, 1140, 1330, 1540, 1771,
+ 2024, 2300, 2600, 2925, 3276, 3654,
+ 4060, 4495, 4960, 5456, 5984, 6545,
+ 7140, 7770, 8436, 9139, 9880, 10660,
+ 11480, 12341, 13244, 14190, 15180, 16215,
+ 17296, 18424, 19600, 20825, 22100, 23426,
+ 24804, 26235, 27720, 29260, 30856, 32509,
+ 34220, 35990, 37820, 39711, 41664, 43680,
+ 45760, 47905, 50116, 52394, 54740, 57155 },
+ { 0, 0, 0, 0, 1, 5,
+ 15, 35, 70, 126, 210, 330,
+ 495, 715, 1001, 1365, 1820, 2380,
+ 3060, 3876, 4845, 5985, 7315, 8855,
+ 10626, 12650, 14950, 17550, 20475, 23751,
+ 27405, 31465, 35960, 40920, 46376, 52360,
+ 58905, 66045, 73815, 82251, 91390, 101270,
+ 111930, 123410, 135751, 148995, 163185, 178365,
+ 194580, 211876, 230300, 249900, 270725, 292825,
+ 316251, 341055, 367290, 395010, 424270, 455126,
+ 487635, 521855, 557845, 595665, 635376, 677040,
+ 720720, 766480, 814385, 864501, 916895, 971635 },
+ { 0, 0, 0, 0, 0, 1,
+ 6, 21, 56, 126, 252, 462,
+ 792, 1287, 2002, 3003, 4368, 6188,
+ 8568, 11628, 15504, 20349, 26334, 33649,
+ 42504, 53130, 65780, 80730, 98280, 118755,
+ 142506, 169911, 201376, 237336, 278256, 324632,
+ 376992, 435897, 501942, 575757, 658008, 749398,
+ 850668, 962598, 1086008, 1221759, 1370754, 1533939,
+ 1712304, 1906884, 2118760, 2349060, 2598960, 2869685,
+ 3162510, 3478761, 3819816, 4187106, 4582116, 5006386,
+ 5461512, 5949147, 6471002, 7028847, 7624512, 8259888,
+ 8936928, 9657648, 10424128, 11238513, 12103014, 13019909 },
+ { 0, 0, 0, 0, 0, 0,
+ 1, 7, 28, 84, 210, 462,
+ 924, 1716, 3003, 5005, 8008, 12376,
+ 18564, 27132, 38760, 54264, 74613, 100947,
+ 134596, 177100, 230230, 296010, 376740, 475020,
+ 593775, 736281, 906192, 1107568, 1344904, 1623160,
+ 1947792, 2324784, 2760681, 3262623, 3838380, 4496388,
+ 5245786, 6096454, 7059052, 8145060, 9366819, 10737573,
+ 12271512, 13983816, 15890700, 18009460, 20358520, 22957480,
+ 25827165, 28989675, 32468436, 36288252, 40475358, 45057474,
+ 50063860, 55525372, 61474519, 67945521, 74974368, 82598880,
+ 90858768, 99795696, 109453344, 119877472, 131115985, 143218999 },
+ { 0, 0, 0, 0, 0, 0,
+ 0, 1, 8, 36, 120, 330,
+ 792, 1716, 3432, 6435, 11440, 19448,
+ 31824, 50388, 77520, 116280, 170544, 245157,
+ 346104, 480700, 657800, 888030, 1184040, 1560780,
+ 2035800, 2629575, 3365856, 4272048, 5379616, 6724520,
+ 8347680, 10295472, 12620256, 15380937, 18643560, 22481940,
+ 26978328, 32224114, 38320568, 45379620, 53524680, 62891499,
+ 73629072, 85900584, 99884400, 115775100, 133784560, 154143080,
+ 177100560, 202927725, 231917400, 264385836, 300674088, 341149446,
+ 386206920, 436270780, 491796152, 553270671, 621216192, 696190560,
+ 778789440, 869648208, 969443904, 1078897248, 1198774720, 1329890705 },
+};
+
+static const int16_t dss_sp_filter_cb[14][32] = {
+ { -32653, -32587, -32515, -32438, -32341, -32216, -32062, -31881,
+ -31665, -31398, -31080, -30724, -30299, -29813, -29248, -28572,
+ -27674, -26439, -24666, -22466, -19433, -16133, -12218, -7783,
+ -2834, 1819, 6544, 11260, 16050, 20220, 24774, 28120 },
+
+ { -27503, -24509, -20644, -17496, -14187, -11277, -8420, -5595,
+ -3013, -624, 1711, 3880, 5844, 7774, 9739, 11592,
+ 13364, 14903, 16426, 17900, 19250, 20586, 21803, 23006,
+ 24142, 25249, 26275, 27300, 28359, 29249, 30118, 31183 },
+
+ { -27827, -24208, -20943, -17781, -14843, -11848, -9066, -6297,
+ -3660, -910, 1918, 5025, 8223, 11649, 15086, 18423,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ { -17128, -11975, -8270, -5123, -2296, 183, 2503, 4707,
+ 6798, 8945, 11045, 13239, 15528, 18248, 21115, 24785,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ { -21557, -17280, -14286, -11644, -9268, -7087, -4939, -2831,
+ -691, 1407, 3536, 5721, 8125, 10677, 13721, 17731,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ { -15030, -10377, -7034, -4327, -1900, 364, 2458, 4450,
+ 6422, 8374, 10374, 12486, 14714, 16997, 19626, 22954,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ { -16155, -12362, -9698, -7460, -5258, -3359, -1547, 219,
+ 1916, 3599, 5299, 6994, 8963, 11226, 13716, 16982,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ { -14742, -9848, -6921, -4648, -2769, -1065, 499, 2083,
+ 3633, 5219, 6857, 8580, 10410, 12672, 15561, 20101,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ { -11099, -7014, -3855, -1025, 1680, 4544, 7807, 11932,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ { -9060, -4570, -1381, 1419, 4034, 6728, 9865, 14149,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ { -12450, -7985, -4596, -1734, 961, 3629, 6865, 11142,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ { -11831, -7404, -4010, -1096, 1606, 4291, 7386, 11482,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ { -13404, -9250, -5995, -3312, -890, 1594, 4464, 8198,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ { -11239, -7220, -4040, -1406, 971, 3321, 6006, 9697,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0 },
+};
+
+static const uint16_t dss_sp_fixed_cb_gain[64] = {
+ 0, 4, 8, 13, 17, 22, 26, 31,
+ 35, 40, 44, 48, 53, 58, 63, 69,
+ 76, 83, 91, 99, 109, 119, 130, 142,
+ 155, 170, 185, 203, 222, 242, 265, 290,
+ 317, 346, 378, 414, 452, 494, 540, 591,
+ 646, 706, 771, 843, 922, 1007, 1101, 1204,
+ 1316, 1438, 1572, 1719, 1879, 2053, 2244, 2453,
+ 2682, 2931, 3204, 3502, 3828, 4184, 4574, 5000,
+};
+
+static const int16_t dss_sp_pulse_val[8] = {
+ -31182, -22273, -13364, -4455, 4455, 13364, 22273, 31182
+};
+
+static const uint16_t binary_decreasing_array[] = {
+ 32767, 16384, 8192, 4096, 2048, 1024, 512, 256,
+ 128, 64, 32, 16, 8, 4, 2,
+};
+
+static const uint16_t dss_sp_unc_decreasing_array[] = {
+ 32767, 26214, 20972, 16777, 13422, 10737, 8590, 6872,
+ 5498, 4398, 3518, 2815, 2252, 1801, 1441,
+};
+
+static const uint16_t dss_sp_adaptive_gain[] = {
+ 102, 231, 360, 488, 617, 746, 875, 1004,
+ 1133, 1261, 1390, 1519, 1648, 1777, 1905, 2034,
+ 2163, 2292, 2421, 2550, 2678, 2807, 2936, 3065,
+ 3194, 3323, 3451, 3580, 3709, 3838, 3967, 4096,
+};
+
+static const int32_t dss_sp_sinc[67] = {
+ 262, 293, 323, 348, 356, 336, 269, 139,
+ -67, -358, -733, -1178, -1668, -2162, -2607, -2940,
+ -3090, -2986, -2562, -1760, -541, 1110, 3187, 5651,
+ 8435, 11446, 14568, 17670, 20611, 23251, 25460, 27125,
+ 28160, 28512, 28160,
+ 27125, 25460, 23251, 20611, 17670, 14568, 11446, 8435,
+ 5651, 3187, 1110, -541, -1760, -2562, -2986, -3090,
+ -2940, -2607, -2162, -1668, -1178, -733, -358, -67,
+ 139, 269, 336, 356, 348, 323, 293, 262,
+};
+
+static av_cold int dss_sp_decode_init(AVCodecContext *avctx)
+{
+ DssSpContext *p = avctx->priv_data;
+ avctx->channel_layout = AV_CH_LAYOUT_MONO;
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ avctx->channels = 1;
+ avctx->sample_rate = 11025;
+
+ memset(p->history, 0, sizeof(p->history));
+ p->pulse_dec_mode = 1;
+ p->avctx = avctx;
+
+ return 0;
+}
+
+static void dss_sp_unpack_coeffs(DssSpContext *p, const uint8_t *src)
+{
+ GetBitContext gb;
+ DssSpFrame *fparam = &p->fparam;
+ int i;
+ int subframe_idx;
+ uint32_t combined_pitch;
+ uint32_t tmp;
+ uint32_t pitch_lag;
+
+ for (i = 0; i < DSS_SP_FRAME_SIZE; i += 2) {
+ p->bits[i] = src[i + 1];
+ p->bits[i + 1] = src[i];
+ }
+
+ init_get_bits(&gb, p->bits, DSS_SP_FRAME_SIZE * 8);
+
+ for (i = 0; i < 2; i++)
+ fparam->filter_idx[i] = get_bits(&gb, 5);
+ for (; i < 8; i++)
+ fparam->filter_idx[i] = get_bits(&gb, 4);
+ for (; i < 14; i++)
+ fparam->filter_idx[i] = get_bits(&gb, 3);
+
+ for (subframe_idx = 0; subframe_idx < 4; subframe_idx++) {
+ fparam->sf_adaptive_gain[subframe_idx] = get_bits(&gb, 5);
+
+ fparam->sf[subframe_idx].combined_pulse_pos = get_bits_long(&gb, 31);
+
+ fparam->sf[subframe_idx].gain = get_bits(&gb, 6);
+
+ for (i = 0; i < 7; i++)
+ fparam->sf[subframe_idx].pulse_val[i] = get_bits(&gb, 3);
+ }
+
+ for (subframe_idx = 0; subframe_idx < 4; subframe_idx++) {
+ unsigned int C72_binomials[PULSE_MAX] = {
+ 72, 2556, 59640, 1028790, 13991544, 156238908, 1473109704,
+ 3379081753
+ };
+ unsigned int combined_pulse_pos =
+ fparam->sf[subframe_idx].combined_pulse_pos;
+ int index = 6;
+
+ if (combined_pulse_pos < C72_binomials[PULSE_MAX - 1]) {
+ if (p->pulse_dec_mode) {
+ int pulse, pulse_idx;
+ pulse = PULSE_MAX - 1;
+ pulse_idx = 71;
+ combined_pulse_pos =
+ fparam->sf[subframe_idx].combined_pulse_pos;
+
+ /* this part seems to be close to g723.1 gen_fcb_excitation()
+ * RATE_6300 */
+
+ /* TODO: what is 7? size of subframe? */
+ for (i = 0; i < 7; i++) {
+ for (;
+ combined_pulse_pos <
+ dss_sp_combinatorial_table[pulse][pulse_idx];
+ --pulse_idx)
+ ;
+ combined_pulse_pos -=
+ dss_sp_combinatorial_table[pulse][pulse_idx];
+ pulse--;
+ fparam->sf[subframe_idx].pulse_pos[i] = pulse_idx;
+ }
+ }
+ } else {
+ p->pulse_dec_mode = 0;
+
+ /* why do we need this? */
+ fparam->sf[subframe_idx].pulse_pos[6] = 0;
+
+ for (i = 71; i >= 0; i--) {
+ if (C72_binomials[index] <= combined_pulse_pos) {
+ combined_pulse_pos -= C72_binomials[index];
+
+ fparam->sf[subframe_idx].pulse_pos[6 - index] = i;
+
+ if (!index)
+ break;
+ --index;
+ }
+ --C72_binomials[0];
+ if (index) {
+ int a;
+ for (a = 0; a < index; a++)
+ C72_binomials[a + 1] -= C72_binomials[a];
+ }
+ }
+ }
+ }
+
+ combined_pitch = get_bits(&gb, 24);
+
+ fparam->pitch_lag[0] = (combined_pitch % 151) + 36;
+
+ combined_pitch /= 151;
+
+ for (i = 1; i < SUBFRAMES - 1; i++) {
+ fparam->pitch_lag[i] = combined_pitch % 48;
+ combined_pitch /= 48;
+ }
+ if (combined_pitch > 47) {
+ av_log (p->avctx, AV_LOG_WARNING, "combined_pitch was too large\n");
+ combined_pitch = 0;
+ }
+ fparam->pitch_lag[i] = combined_pitch;
+
+ pitch_lag = fparam->pitch_lag[0];
+ for (i = 1; i < SUBFRAMES; i++) {
+ if (pitch_lag > 162) {
+ fparam->pitch_lag[i] += 162 - 23;
+ } else {
+ tmp = pitch_lag - 23;
+ if (tmp < 36)
+ tmp = 36;
+ fparam->pitch_lag[i] += tmp;
+ }
+ pitch_lag = fparam->pitch_lag[i];
+ }
+}
+
+static void dss_sp_unpack_filter(DssSpContext *p)
+{
+ int i;
+
+ for (i = 0; i < 14; i++)
+ p->lpc_filter[i] = dss_sp_filter_cb[i][p->fparam.filter_idx[i]];
+}
+
+static void dss_sp_convert_coeffs(int32_t *lpc_filter, int32_t *coeffs)
+{
+ int a, a_plus, i;
+
+ coeffs[0] = 0x2000;
+ for (a = 0; a < 14; a++) {
+ a_plus = a + 1;
+ coeffs[a_plus] = lpc_filter[a] >> 2;
+ if (a_plus / 2 >= 1) {
+ for (i = 1; i <= a_plus / 2; i++) {
+ int coeff_1, coeff_2, tmp;
+
+ coeff_1 = coeffs[i];
+ coeff_2 = coeffs[a_plus - i];
+
+ tmp = DSS_SP_FORMULA(coeff_1, lpc_filter[a], coeff_2);
+ coeffs[i] = av_clip_int16(tmp);
+
+ tmp = DSS_SP_FORMULA(coeff_2, lpc_filter[a], coeff_1);
+ coeffs[a_plus - i] = av_clip_int16(tmp);
+ }
+ }
+ }
+}
+
+static void dss_sp_add_pulses(int32_t *vector_buf,
+ const struct DssSpSubframe *sf)
+{
+ int i;
+
+ for (i = 0; i < 7; i++)
+ vector_buf[sf->pulse_pos[i]] += (dss_sp_fixed_cb_gain[sf->gain] *
+ dss_sp_pulse_val[sf->pulse_val[i]] +
+ 0x4000) >> 15;
+}
+
+static void dss_sp_gen_exc(int32_t *vector, int32_t *prev_exc,
+ int pitch_lag, int gain)
+{
+ int i;
+
+ /* do we actually need this check? we can use just [a3 - i % a3]
+ * for both cases */
+ if (pitch_lag < 72)
+ for (i = 0; i < 72; i++)
+ vector[i] = prev_exc[pitch_lag - i % pitch_lag];
+ else
+ for (i = 0; i < 72; i++)
+ vector[i] = prev_exc[pitch_lag - i];
+
+ for (i = 0; i < 72; i++) {
+ int tmp = gain * vector[i] >> 11;
+ vector[i] = av_clip_int16(tmp);
+ }
+}
+
+static void dss_sp_scale_vector(int32_t *vec, int bits, int size)
+{
+ int i;
+
+ if (bits < 0)
+ for (i = 0; i < size; i++)
+ vec[i] = vec[i] >> -bits;
+ else
+ for (i = 0; i < size; i++)
+ vec[i] = vec[i] * (1 << bits);
+}
+
+static void dss_sp_update_buf(int32_t *hist, int32_t *vector)
+{
+ int i;
+
+ for (i = 114; i > 0; i--)
+ vector[i + 72] = vector[i];
+
+ for (i = 0; i < 72; i++)
+ vector[72 - i] = hist[i];
+}
+
+static void dss_sp_shift_sq_sub(const int32_t *filter_buf,
+ int32_t *error_buf, int32_t *dst)
+{
+ int a;
+
+ for (a = 0; a < 72; a++) {
+ int i, tmp;
+
+ tmp = dst[a] * filter_buf[0];
+
+ for (i = 14; i > 0; i--)
+ tmp -= error_buf[i] * (unsigned)filter_buf[i];
+
+ for (i = 14; i > 0; i--)
+ error_buf[i] = error_buf[i - 1];
+
+ tmp = (int)(tmp + 4096U) >> 13;
+
+ error_buf[1] = tmp;
+
+ dst[a] = av_clip_int16(tmp);
+ }
+}
+
+static void dss_sp_shift_sq_add(const int32_t *filter_buf, int32_t *audio_buf,
+ int32_t *dst)
+{
+ int a;
+
+ for (a = 0; a < 72; a++) {
+ int i, tmp = 0;
+
+ audio_buf[0] = dst[a];
+
+ for (i = 14; i >= 0; i--)
+ tmp += audio_buf[i] * filter_buf[i];
+
+ for (i = 14; i > 0; i--)
+ audio_buf[i] = audio_buf[i - 1];
+
+ tmp = (tmp + 4096) >> 13;
+
+ dst[a] = av_clip_int16(tmp);
+ }
+}
+
+static void dss_sp_vec_mult(const int32_t *src, int32_t *dst,
+ const int16_t *mult)
+{
+ int i;
+
+ dst[0] = src[0];
+
+ for (i = 1; i < 15; i++)
+ dst[i] = (src[i] * mult[i] + 0x4000) >> 15;
+}
+
+static int dss_sp_get_normalize_bits(int32_t *vector_buf, int16_t size)
+{
+ unsigned int val;
+ int max_val;
+ int i;
+
+ val = 1;
+ for (i = 0; i < size; i++)
+ val |= FFABS(vector_buf[i]);
+
+ for (max_val = 0; val <= 0x4000; ++max_val)
+ val *= 2;
+ return max_val;
+}
+
+static int dss_sp_vector_sum(DssSpContext *p, int size)
+{
+ int i, sum = 0;
+ for (i = 0; i < size; i++)
+ sum += FFABS(p->vector_buf[i]);
+ return sum;
+}
+
+static void dss_sp_sf_synthesis(DssSpContext *p, int32_t lpc_filter,
+ int32_t *dst, int size)
+{
+ int32_t tmp_buf[15];
+ int32_t noise[72];
+ int bias, vsum_2 = 0, vsum_1 = 0, v36, normalize_bits;
+ int i, tmp;
+
+ if (size > 0) {
+ vsum_1 = dss_sp_vector_sum(p, size);
+
+ if (vsum_1 > 0xFFFFF)
+ vsum_1 = 0xFFFFF;
+ }
+
+ normalize_bits = dss_sp_get_normalize_bits(p->vector_buf, size);
+
+ dss_sp_scale_vector(p->vector_buf, normalize_bits - 3, size);
+ dss_sp_scale_vector(p->audio_buf, normalize_bits, 15);
+ dss_sp_scale_vector(p->err_buf1, normalize_bits, 15);
+
+ v36 = p->err_buf1[1];
+
+ dss_sp_vec_mult(p->filter, tmp_buf, binary_decreasing_array);
+ dss_sp_shift_sq_add(tmp_buf, p->audio_buf, p->vector_buf);
+
+ dss_sp_vec_mult(p->filter, tmp_buf, dss_sp_unc_decreasing_array);
+ dss_sp_shift_sq_sub(tmp_buf, p->err_buf1, p->vector_buf);
+
+ /* lpc_filter can be negative */
+ lpc_filter = lpc_filter >> 1;
+ if (lpc_filter >= 0)
+ lpc_filter = 0;
+
+ if (size > 1) {
+ for (i = size - 1; i > 0; i--) {
+ tmp = DSS_SP_FORMULA(p->vector_buf[i], lpc_filter,
+ p->vector_buf[i - 1]);
+ p->vector_buf[i] = av_clip_int16(tmp);
+ }
+ }
+
+ tmp = DSS_SP_FORMULA(p->vector_buf[0], lpc_filter, v36);
+ p->vector_buf[0] = av_clip_int16(tmp);
+
+ dss_sp_scale_vector(p->vector_buf, -normalize_bits, size);
+ dss_sp_scale_vector(p->audio_buf, -normalize_bits, 15);
+ dss_sp_scale_vector(p->err_buf1, -normalize_bits, 15);
+
+ if (size > 0)
+ vsum_2 = dss_sp_vector_sum(p, size);
+
+ if (vsum_2 >= 0x40)
+ tmp = (vsum_1 << 11) / vsum_2;
+ else
+ tmp = 1;
+
+ bias = 409 * tmp >> 15 << 15;
+ tmp = (bias + 32358 * p->noise_state) >> 15;
+ noise[0] = av_clip_int16(tmp);
+
+ for (i = 1; i < size; i++) {
+ tmp = (bias + 32358 * noise[i - 1]) >> 15;
+ noise[i] = av_clip_int16(tmp);
+ }
+
+ p->noise_state = noise[size - 1];
+ for (i = 0; i < size; i++) {
+ tmp = (p->vector_buf[i] * noise[i]) >> 11;
+ dst[i] = av_clip_int16(tmp);
+ }
+}
+
+static void dss_sp_update_state(DssSpContext *p, int32_t *dst)
+{
+ int i, offset = 6, counter = 0, a = 0;
+
+ for (i = 0; i < 6; i++)
+ p->excitation[i] = p->excitation[288 + i];
+
+ for (i = 0; i < 72 * SUBFRAMES; i++)
+ p->excitation[6 + i] = dst[i];
+
+ do {
+ int tmp = 0;
+
+ for (i = 0; i < 6; i++)
+ tmp += p->excitation[offset--] * dss_sp_sinc[a + i * 11];
+
+ offset += 7;
+
+ tmp >>= 15;
+ dst[counter] = av_clip_int16(tmp);
+
+ counter++;
+
+ a = (a + 1) % 11;
+ if (!a)
+ offset++;
+ } while (offset < FF_ARRAY_ELEMS(p->excitation));
+}
+
+static void dss_sp_32to16bit(int16_t *dst, int32_t *src, int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++)
+ dst[i] = av_clip_int16(src[i]);
+}
+
+static int dss_sp_decode_one_frame(DssSpContext *p,
+ int16_t *abuf_dst, const uint8_t *abuf_src)
+{
+ int i, j;
+
+ dss_sp_unpack_coeffs(p, abuf_src);
+
+ dss_sp_unpack_filter(p);
+
+ dss_sp_convert_coeffs(p->lpc_filter, p->filter);
+
+ for (j = 0; j < SUBFRAMES; j++) {
+ dss_sp_gen_exc(p->vector_buf, p->history,
+ p->fparam.pitch_lag[j],
+ dss_sp_adaptive_gain[p->fparam.sf_adaptive_gain[j]]);
+
+ dss_sp_add_pulses(p->vector_buf, &p->fparam.sf[j]);
+
+ dss_sp_update_buf(p->vector_buf, p->history);
+
+ for (i = 0; i < 72; i++)
+ p->vector_buf[i] = p->history[72 - i];
+
+ dss_sp_shift_sq_sub(p->filter,
+ p->err_buf2, p->vector_buf);
+
+ dss_sp_sf_synthesis(p, p->lpc_filter[0],
+ &p->working_buffer[j][0], 72);
+ }
+
+ dss_sp_update_state(p, &p->working_buffer[0][0]);
+
+ dss_sp_32to16bit(abuf_dst,
+ &p->working_buffer[0][0], 264);
+ return 0;
+}
+
+static int dss_sp_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ DssSpContext *p = avctx->priv_data;
+ AVFrame *frame = data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+
+ int16_t *out;
+ int ret;
+
+ if (buf_size < DSS_SP_FRAME_SIZE) {
+ if (buf_size)
+ av_log(avctx, AV_LOG_WARNING,
+ "Expected %d bytes, got %d - skipping packet.\n",
+ DSS_SP_FRAME_SIZE, buf_size);
+ *got_frame_ptr = 0;
+ return AVERROR_INVALIDDATA;
+ }
+
+ frame->nb_samples = DSS_SP_SAMPLE_COUNT;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed.\n");
+ return ret;
+ }
+
+ out = (int16_t *)frame->data[0];
+
+ dss_sp_decode_one_frame(p, out, buf);
+
+ *got_frame_ptr = 1;
+
+ return DSS_SP_FRAME_SIZE;
+}
+
+AVCodec ff_dss_sp_decoder = {
+ .name = "dss_sp",
+ .long_name = NULL_IF_CONFIG_SMALL("Digital Speech Standard - Standard Play mode (DSS SP)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_DSS_SP,
+ .priv_data_size = sizeof(DssSpContext),
+ .init = dss_sp_decode_init,
+ .decode = dss_sp_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/dump_extradata_bsf.c b/ffmpeg-2-8-12/libavcodec/dump_extradata_bsf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dump_extradata_bsf.c
rename to ffmpeg-2-8-12/libavcodec/dump_extradata_bsf.c
diff --git a/ffmpeg-2-8-11/libavcodec/dv.c b/ffmpeg-2-8-12/libavcodec/dv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dv.c
rename to ffmpeg-2-8-12/libavcodec/dv.c
diff --git a/ffmpeg-2-8-11/libavcodec/dv.h b/ffmpeg-2-8-12/libavcodec/dv.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dv.h
rename to ffmpeg-2-8-12/libavcodec/dv.h
diff --git a/ffmpeg-2-8-11/libavcodec/dv_profile.c b/ffmpeg-2-8-12/libavcodec/dv_profile.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dv_profile.c
rename to ffmpeg-2-8-12/libavcodec/dv_profile.c
diff --git a/ffmpeg-2-8-11/libavcodec/dv_profile.h b/ffmpeg-2-8-12/libavcodec/dv_profile.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dv_profile.h
rename to ffmpeg-2-8-12/libavcodec/dv_profile.h
diff --git a/ffmpeg-2-8-11/libavcodec/dv_profile_internal.h b/ffmpeg-2-8-12/libavcodec/dv_profile_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dv_profile_internal.h
rename to ffmpeg-2-8-12/libavcodec/dv_profile_internal.h
diff --git a/ffmpeg-2-8-11/libavcodec/dv_tablegen.c b/ffmpeg-2-8-12/libavcodec/dv_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dv_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/dv_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/dv_tablegen.h b/ffmpeg-2-8-12/libavcodec/dv_tablegen.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dv_tablegen.h
rename to ffmpeg-2-8-12/libavcodec/dv_tablegen.h
diff --git a/ffmpeg-2-8-11/libavcodec/dvbsub.c b/ffmpeg-2-8-12/libavcodec/dvbsub.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dvbsub.c
rename to ffmpeg-2-8-12/libavcodec/dvbsub.c
diff --git a/ffmpeg-2-8-11/libavcodec/dvbsub_parser.c b/ffmpeg-2-8-12/libavcodec/dvbsub_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dvbsub_parser.c
rename to ffmpeg-2-8-12/libavcodec/dvbsub_parser.c
diff --git a/ffmpeg-2-8-12/libavcodec/dvbsubdec.c b/ffmpeg-2-8-12/libavcodec/dvbsubdec.c
new file mode 100644
index 0000000..73669cf
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/dvbsubdec.c
@@ -0,0 +1,1751 @@
+/*
+ * DVB subtitle decoding
+ * Copyright (c) 2005 Ian Caulfield
+ *
+ * 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 "get_bits.h"
+#include "bytestream.h"
+#include "internal.h"
+#include "libavutil/colorspace.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+
+#define DVBSUB_PAGE_SEGMENT 0x10
+#define DVBSUB_REGION_SEGMENT 0x11
+#define DVBSUB_CLUT_SEGMENT 0x12
+#define DVBSUB_OBJECT_SEGMENT 0x13
+#define DVBSUB_DISPLAYDEFINITION_SEGMENT 0x14
+#define DVBSUB_DISPLAY_SEGMENT 0x80
+
+#define cm (ff_crop_tab + MAX_NEG_CROP)
+
+#ifdef DEBUG
+#if 0
+static void png_save(const char *filename, uint8_t *bitmap, int w, int h,
+ uint32_t *rgba_palette)
+{
+ int x, y, v;
+ FILE *f;
+ char fname[40], fname2[40];
+ char command[1024];
+
+ snprintf(fname, 40, "%s.ppm", filename);
+
+ f = fopen(fname, "w");
+ if (!f) {
+ perror(fname);
+ return;
+ }
+ fprintf(f, "P6\n"
+ "%d %d\n"
+ "%d\n",
+ w, h, 255);
+ for(y = 0; y < h; y++) {
+ for(x = 0; x < w; x++) {
+ v = rgba_palette[bitmap[y * w + x]];
+ putc((v >> 16) & 0xff, f);
+ putc((v >> 8) & 0xff, f);
+ putc((v >> 0) & 0xff, f);
+ }
+ }
+ fclose(f);
+
+
+ snprintf(fname2, 40, "%s-a.pgm", filename);
+
+ f = fopen(fname2, "w");
+ if (!f) {
+ perror(fname2);
+ return;
+ }
+ fprintf(f, "P5\n"
+ "%d %d\n"
+ "%d\n",
+ w, h, 255);
+ for(y = 0; y < h; y++) {
+ for(x = 0; x < w; x++) {
+ v = rgba_palette[bitmap[y * w + x]];
+ putc((v >> 24) & 0xff, f);
+ }
+ }
+ fclose(f);
+
+ snprintf(command, 1024, "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);
+ system(command);
+
+ snprintf(command, 1024, "rm %s %s", fname, fname2);
+ system(command);
+}
+#endif
+
+static void png_save2(const char *filename, uint32_t *bitmap, int w, int h)
+{
+ int x, y, v;
+ FILE *f;
+ char fname[40], fname2[40];
+ char command[1024];
+
+ snprintf(fname, sizeof(fname), "%s.ppm", filename);
+
+ f = fopen(fname, "w");
+ if (!f) {
+ perror(fname);
+ return;
+ }
+ fprintf(f, "P6\n"
+ "%d %d\n"
+ "%d\n",
+ w, h, 255);
+ for(y = 0; y < h; y++) {
+ for(x = 0; x < w; x++) {
+ v = bitmap[y * w + x];
+ putc((v >> 16) & 0xff, f);
+ putc((v >> 8) & 0xff, f);
+ putc((v >> 0) & 0xff, f);
+ }
+ }
+ fclose(f);
+
+
+ snprintf(fname2, sizeof(fname2), "%s-a.pgm", filename);
+
+ f = fopen(fname2, "w");
+ if (!f) {
+ perror(fname2);
+ return;
+ }
+ fprintf(f, "P5\n"
+ "%d %d\n"
+ "%d\n",
+ w, h, 255);
+ for(y = 0; y < h; y++) {
+ for(x = 0; x < w; x++) {
+ v = bitmap[y * w + x];
+ putc((v >> 24) & 0xff, f);
+ }
+ }
+ fclose(f);
+
+ snprintf(command, sizeof(command), "pnmtopng -alpha %s %s > %s.png 2> /dev/null", fname2, fname, filename);
+ system(command);
+
+ snprintf(command, sizeof(command), "rm %s %s", fname, fname2);
+ system(command);
+}
+#endif
+
+#define RGBA(r,g,b,a) (((unsigned)(a) << 24) | ((r) << 16) | ((g) << 8) | (b))
+
+typedef struct DVBSubCLUT {
+ int id;
+ int version;
+
+ uint32_t clut4[4];
+ uint32_t clut16[16];
+ uint32_t clut256[256];
+
+ struct DVBSubCLUT *next;
+} DVBSubCLUT;
+
+static DVBSubCLUT default_clut;
+
+typedef struct DVBSubObjectDisplay {
+ int object_id;
+ int region_id;
+
+ int x_pos;
+ int y_pos;
+
+ int fgcolor;
+ int bgcolor;
+
+ struct DVBSubObjectDisplay *region_list_next;
+ struct DVBSubObjectDisplay *object_list_next;
+} DVBSubObjectDisplay;
+
+typedef struct DVBSubObject {
+ int id;
+ int version;
+
+ int type;
+
+ DVBSubObjectDisplay *display_list;
+
+ struct DVBSubObject *next;
+} DVBSubObject;
+
+typedef struct DVBSubRegionDisplay {
+ int region_id;
+
+ int x_pos;
+ int y_pos;
+
+ struct DVBSubRegionDisplay *next;
+} DVBSubRegionDisplay;
+
+typedef struct DVBSubRegion {
+ int id;
+ int version;
+
+ int width;
+ int height;
+ int depth;
+
+ int clut;
+ int bgcolor;
+
+ uint8_t *pbuf;
+ int buf_size;
+ int dirty;
+
+ DVBSubObjectDisplay *display_list;
+
+ struct DVBSubRegion *next;
+} DVBSubRegion;
+
+typedef struct DVBSubDisplayDefinition {
+ int version;
+
+ int x;
+ int y;
+ int width;
+ int height;
+} DVBSubDisplayDefinition;
+
+typedef struct DVBSubContext {
+ AVClass *class;
+ int composition_id;
+ int ancillary_id;
+
+ int version;
+ int time_out;
+ int compute_edt; /**< if 1 end display time calculated using pts
+ if 0 (Default) calculated using time out */
+ int compute_clut;
+ int substream;
+ int64_t prev_start;
+ DVBSubRegion *region_list;
+ DVBSubCLUT *clut_list;
+ DVBSubObject *object_list;
+
+ DVBSubRegionDisplay *display_list;
+ DVBSubDisplayDefinition *display_definition;
+} DVBSubContext;
+
+
+static DVBSubObject* get_object(DVBSubContext *ctx, int object_id)
+{
+ DVBSubObject *ptr = ctx->object_list;
+
+ while (ptr && ptr->id != object_id) {
+ ptr = ptr->next;
+ }
+
+ return ptr;
+}
+
+static DVBSubCLUT* get_clut(DVBSubContext *ctx, int clut_id)
+{
+ DVBSubCLUT *ptr = ctx->clut_list;
+
+ while (ptr && ptr->id != clut_id) {
+ ptr = ptr->next;
+ }
+
+ return ptr;
+}
+
+static DVBSubRegion* get_region(DVBSubContext *ctx, int region_id)
+{
+ DVBSubRegion *ptr = ctx->region_list;
+
+ while (ptr && ptr->id != region_id) {
+ ptr = ptr->next;
+ }
+
+ return ptr;
+}
+
+static void delete_region_display_list(DVBSubContext *ctx, DVBSubRegion *region)
+{
+ DVBSubObject *object, *obj2, **obj2_ptr;
+ DVBSubObjectDisplay *display, *obj_disp, **obj_disp_ptr;
+
+ while (region->display_list) {
+ display = region->display_list;
+
+ object = get_object(ctx, display->object_id);
+
+ if (object) {
+ obj_disp_ptr = &object->display_list;
+ obj_disp = *obj_disp_ptr;
+
+ while (obj_disp && obj_disp != display) {
+ obj_disp_ptr = &obj_disp->object_list_next;
+ obj_disp = *obj_disp_ptr;
+ }
+
+ if (obj_disp) {
+ *obj_disp_ptr = obj_disp->object_list_next;
+
+ if (!object->display_list) {
+ obj2_ptr = &ctx->object_list;
+ obj2 = *obj2_ptr;
+
+ while (obj2 != object) {
+ av_assert0(obj2);
+ obj2_ptr = &obj2->next;
+ obj2 = *obj2_ptr;
+ }
+
+ *obj2_ptr = obj2->next;
+
+ av_freep(&obj2);
+ }
+ }
+ }
+
+ region->display_list = display->region_list_next;
+
+ av_freep(&display);
+ }
+
+}
+
+static void delete_cluts(DVBSubContext *ctx)
+{
+ while (ctx->clut_list) {
+ DVBSubCLUT *clut = ctx->clut_list;
+
+ ctx->clut_list = clut->next;
+
+ av_freep(&clut);
+ }
+}
+
+static void delete_objects(DVBSubContext *ctx)
+{
+ while (ctx->object_list) {
+ DVBSubObject *object = ctx->object_list;
+
+ ctx->object_list = object->next;
+
+ av_freep(&object);
+ }
+}
+
+static void delete_regions(DVBSubContext *ctx)
+{
+ while (ctx->region_list) {
+ DVBSubRegion *region = ctx->region_list;
+
+ ctx->region_list = region->next;
+
+ delete_region_display_list(ctx, region);
+
+ av_freep(®ion->pbuf);
+ av_freep(®ion);
+ }
+}
+
+static av_cold int dvbsub_init_decoder(AVCodecContext *avctx)
+{
+ int i, r, g, b, a = 0;
+ DVBSubContext *ctx = avctx->priv_data;
+
+ if (ctx->substream < 0) {
+ ctx->composition_id = -1;
+ ctx->ancillary_id = -1;
+ } else if (!avctx->extradata || (avctx->extradata_size < 4) || ((avctx->extradata_size % 5 != 0) && (avctx->extradata_size != 4))) {
+ av_log(avctx, AV_LOG_WARNING, "Invalid DVB subtitles stream extradata!\n");
+ ctx->composition_id = -1;
+ ctx->ancillary_id = -1;
+ } else {
+ if (avctx->extradata_size > 5*ctx->substream + 2) {
+ ctx->composition_id = AV_RB16(avctx->extradata + 5*ctx->substream);
+ ctx->ancillary_id = AV_RB16(avctx->extradata + 5*ctx->substream + 2);
+ } else {
+ av_log(avctx, AV_LOG_WARNING, "Selected DVB subtitles sub-stream %d is not available\n", ctx->substream);
+ ctx->composition_id = AV_RB16(avctx->extradata);
+ ctx->ancillary_id = AV_RB16(avctx->extradata + 2);
+ }
+ }
+
+ ctx->version = -1;
+ ctx->prev_start = AV_NOPTS_VALUE;
+
+ default_clut.id = -1;
+ default_clut.next = NULL;
+
+ default_clut.clut4[0] = RGBA( 0, 0, 0, 0);
+ default_clut.clut4[1] = RGBA(255, 255, 255, 255);
+ default_clut.clut4[2] = RGBA( 0, 0, 0, 255);
+ default_clut.clut4[3] = RGBA(127, 127, 127, 255);
+
+ default_clut.clut16[0] = RGBA( 0, 0, 0, 0);
+ for (i = 1; i < 16; i++) {
+ if (i < 8) {
+ r = (i & 1) ? 255 : 0;
+ g = (i & 2) ? 255 : 0;
+ b = (i & 4) ? 255 : 0;
+ } else {
+ r = (i & 1) ? 127 : 0;
+ g = (i & 2) ? 127 : 0;
+ b = (i & 4) ? 127 : 0;
+ }
+ default_clut.clut16[i] = RGBA(r, g, b, 255);
+ }
+
+ default_clut.clut256[0] = RGBA( 0, 0, 0, 0);
+ for (i = 1; i < 256; i++) {
+ if (i < 8) {
+ r = (i & 1) ? 255 : 0;
+ g = (i & 2) ? 255 : 0;
+ b = (i & 4) ? 255 : 0;
+ a = 63;
+ } else {
+ switch (i & 0x88) {
+ case 0x00:
+ r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
+ g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
+ b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
+ a = 255;
+ break;
+ case 0x08:
+ r = ((i & 1) ? 85 : 0) + ((i & 0x10) ? 170 : 0);
+ g = ((i & 2) ? 85 : 0) + ((i & 0x20) ? 170 : 0);
+ b = ((i & 4) ? 85 : 0) + ((i & 0x40) ? 170 : 0);
+ a = 127;
+ break;
+ case 0x80:
+ r = 127 + ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
+ g = 127 + ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
+ b = 127 + ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
+ a = 255;
+ break;
+ case 0x88:
+ r = ((i & 1) ? 43 : 0) + ((i & 0x10) ? 85 : 0);
+ g = ((i & 2) ? 43 : 0) + ((i & 0x20) ? 85 : 0);
+ b = ((i & 4) ? 43 : 0) + ((i & 0x40) ? 85 : 0);
+ a = 255;
+ break;
+ }
+ }
+ default_clut.clut256[i] = RGBA(r, g, b, a);
+ }
+
+ return 0;
+}
+
+static av_cold int dvbsub_close_decoder(AVCodecContext *avctx)
+{
+ DVBSubContext *ctx = avctx->priv_data;
+ DVBSubRegionDisplay *display;
+
+ delete_regions(ctx);
+
+ delete_objects(ctx);
+
+ delete_cluts(ctx);
+
+ av_freep(&ctx->display_definition);
+
+ while (ctx->display_list) {
+ display = ctx->display_list;
+ ctx->display_list = display->next;
+
+ av_freep(&display);
+ }
+
+ return 0;
+}
+
+static int dvbsub_read_2bit_string(AVCodecContext *avctx,
+ uint8_t *destbuf, int dbuf_len,
+ const uint8_t **srcbuf, int buf_size,
+ int non_mod, uint8_t *map_table, int x_pos)
+{
+ GetBitContext gb;
+
+ int bits;
+ int run_length;
+ int pixels_read = x_pos;
+
+ init_get_bits(&gb, *srcbuf, buf_size << 3);
+
+ destbuf += x_pos;
+
+ while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
+ bits = get_bits(&gb, 2);
+
+ if (bits) {
+ if (non_mod != 1 || bits != 1) {
+ if (map_table)
+ *destbuf++ = map_table[bits];
+ else
+ *destbuf++ = bits;
+ }
+ pixels_read++;
+ } else {
+ bits = get_bits1(&gb);
+ if (bits == 1) {
+ run_length = get_bits(&gb, 3) + 3;
+ bits = get_bits(&gb, 2);
+
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ else {
+ if (map_table)
+ bits = map_table[bits];
+ while (run_length-- > 0 && pixels_read < dbuf_len) {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ } else {
+ bits = get_bits1(&gb);
+ if (bits == 0) {
+ bits = get_bits(&gb, 2);
+ if (bits == 2) {
+ run_length = get_bits(&gb, 4) + 12;
+ bits = get_bits(&gb, 2);
+
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ else {
+ if (map_table)
+ bits = map_table[bits];
+ while (run_length-- > 0 && pixels_read < dbuf_len) {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ } else if (bits == 3) {
+ run_length = get_bits(&gb, 8) + 29;
+ bits = get_bits(&gb, 2);
+
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ else {
+ if (map_table)
+ bits = map_table[bits];
+ while (run_length-- > 0 && pixels_read < dbuf_len) {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ } else if (bits == 1) {
+ if (map_table)
+ bits = map_table[0];
+ else
+ bits = 0;
+ run_length = 2;
+ while (run_length-- > 0 && pixels_read < dbuf_len) {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ } else {
+ (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
+ return pixels_read;
+ }
+ } else {
+ if (map_table)
+ bits = map_table[0];
+ else
+ bits = 0;
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ }
+ }
+
+ if (get_bits(&gb, 6))
+ av_log(avctx, AV_LOG_ERROR, "line overflow\n");
+
+ (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
+
+ return pixels_read;
+}
+
+static int dvbsub_read_4bit_string(AVCodecContext *avctx, uint8_t *destbuf, int dbuf_len,
+ const uint8_t **srcbuf, int buf_size,
+ int non_mod, uint8_t *map_table, int x_pos)
+{
+ GetBitContext gb;
+
+ int bits;
+ int run_length;
+ int pixels_read = x_pos;
+
+ init_get_bits(&gb, *srcbuf, buf_size << 3);
+
+ destbuf += x_pos;
+
+ while (get_bits_count(&gb) < buf_size << 3 && pixels_read < dbuf_len) {
+ bits = get_bits(&gb, 4);
+
+ if (bits) {
+ if (non_mod != 1 || bits != 1) {
+ if (map_table)
+ *destbuf++ = map_table[bits];
+ else
+ *destbuf++ = bits;
+ }
+ pixels_read++;
+ } else {
+ bits = get_bits1(&gb);
+ if (bits == 0) {
+ run_length = get_bits(&gb, 3);
+
+ if (run_length == 0) {
+ (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
+ return pixels_read;
+ }
+
+ run_length += 2;
+
+ if (map_table)
+ bits = map_table[0];
+ else
+ bits = 0;
+
+ while (run_length-- > 0 && pixels_read < dbuf_len) {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ } else {
+ bits = get_bits1(&gb);
+ if (bits == 0) {
+ run_length = get_bits(&gb, 2) + 4;
+ bits = get_bits(&gb, 4);
+
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ else {
+ if (map_table)
+ bits = map_table[bits];
+ while (run_length-- > 0 && pixels_read < dbuf_len) {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ } else {
+ bits = get_bits(&gb, 2);
+ if (bits == 2) {
+ run_length = get_bits(&gb, 4) + 9;
+ bits = get_bits(&gb, 4);
+
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ else {
+ if (map_table)
+ bits = map_table[bits];
+ while (run_length-- > 0 && pixels_read < dbuf_len) {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ } else if (bits == 3) {
+ run_length = get_bits(&gb, 8) + 25;
+ bits = get_bits(&gb, 4);
+
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ else {
+ if (map_table)
+ bits = map_table[bits];
+ while (run_length-- > 0 && pixels_read < dbuf_len) {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ } else if (bits == 1) {
+ if (map_table)
+ bits = map_table[0];
+ else
+ bits = 0;
+ run_length = 2;
+ while (run_length-- > 0 && pixels_read < dbuf_len) {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ } else {
+ if (map_table)
+ bits = map_table[0];
+ else
+ bits = 0;
+ *destbuf++ = bits;
+ pixels_read ++;
+ }
+ }
+ }
+ }
+ }
+
+ if (get_bits(&gb, 8))
+ av_log(avctx, AV_LOG_ERROR, "line overflow\n");
+
+ (*srcbuf) += (get_bits_count(&gb) + 7) >> 3;
+
+ return pixels_read;
+}
+
+static int dvbsub_read_8bit_string(AVCodecContext *avctx,
+ uint8_t *destbuf, int dbuf_len,
+ const uint8_t **srcbuf, int buf_size,
+ int non_mod, uint8_t *map_table, int x_pos)
+{
+ const uint8_t *sbuf_end = (*srcbuf) + buf_size;
+ int bits;
+ int run_length;
+ int pixels_read = x_pos;
+
+ destbuf += x_pos;
+
+ while (*srcbuf < sbuf_end && pixels_read < dbuf_len) {
+ bits = *(*srcbuf)++;
+
+ if (bits) {
+ if (non_mod != 1 || bits != 1) {
+ if (map_table)
+ *destbuf++ = map_table[bits];
+ else
+ *destbuf++ = bits;
+ }
+ pixels_read++;
+ } else {
+ bits = *(*srcbuf)++;
+ run_length = bits & 0x7f;
+ if ((bits & 0x80) == 0) {
+ if (run_length == 0) {
+ return pixels_read;
+ }
+
+ bits = 0;
+ } else {
+ bits = *(*srcbuf)++;
+ }
+ if (non_mod == 1 && bits == 1)
+ pixels_read += run_length;
+ else {
+ if (map_table)
+ bits = map_table[bits];
+ while (run_length-- > 0 && pixels_read < dbuf_len) {
+ *destbuf++ = bits;
+ pixels_read++;
+ }
+ }
+ }
+ }
+
+ if (*(*srcbuf)++)
+ av_log(avctx, AV_LOG_ERROR, "line overflow\n");
+
+ return pixels_read;
+}
+
+static void compute_default_clut(AVPicture *frame, int w, int h)
+{
+ uint8_t list[256] = {0};
+ uint8_t list_inv[256];
+ int counttab[256] = {0};
+ int count, i, x, y;
+
+#define V(x,y) frame->data[0][(x) + (y)*frame->linesize[0]]
+ for (y = 0; y<h; y++) {
+ for (x = 0; x<w; x++) {
+ int v = V(x,y) + 1;
+ int vl = x ? V(x-1,y) + 1 : 0;
+ int vr = x+1<w ? V(x+1,y) + 1 : 0;
+ int vt = y ? V(x,y-1) + 1 : 0;
+ int vb = y+1<h ? V(x,y+1) + 1 : 0;
+ counttab[v-1] += !!((v!=vl) + (v!=vr) + (v!=vt) + (v!=vb));
+ }
+ }
+#define L(x,y) list[ frame->data[0][(x) + (y)*frame->linesize[0]] ]
+
+ for (i = 0; i<256; i++) {
+ int scoretab[256] = {0};
+ int bestscore = 0;
+ int bestv = 0;
+ for (y = 0; y<h; y++) {
+ for (x = 0; x<w; x++) {
+ int v = frame->data[0][x + y*frame->linesize[0]];
+ int l_m = list[v];
+ int l_l = x ? L(x-1, y) : 1;
+ int l_r = x+1<w ? L(x+1, y) : 1;
+ int l_t = y ? L(x, y-1) : 1;
+ int l_b = y+1<h ? L(x, y+1) : 1;
+ int score;
+ if (l_m)
+ continue;
+ scoretab[v] += l_l + l_r + l_t + l_b;
+ score = 1024LL*scoretab[v] / counttab[v];
+ if (score > bestscore) {
+ bestscore = score;
+ bestv = v;
+ }
+ }
+ }
+ if (!bestscore)
+ break;
+ list [ bestv ] = 1;
+ list_inv[ i ] = bestv;
+ }
+
+ count = FFMAX(i - 1, 1);
+ for (i--; i>=0; i--) {
+ int v = i*255/count;
+ AV_WN32(frame->data[1] + 4*list_inv[i], RGBA(v/2,v,v/2,v));
+ }
+}
+
+
+static int save_subtitle_set(AVCodecContext *avctx, AVSubtitle *sub, int *got_output)
+{
+ DVBSubContext *ctx = avctx->priv_data;
+ DVBSubRegionDisplay *display;
+ DVBSubDisplayDefinition *display_def = ctx->display_definition;
+ DVBSubRegion *region;
+ AVSubtitleRect *rect;
+ DVBSubCLUT *clut;
+ uint32_t *clut_table;
+ int i;
+ int offset_x=0, offset_y=0;
+ int ret = 0;
+
+
+ if (display_def) {
+ offset_x = display_def->x;
+ offset_y = display_def->y;
+ }
+
+ /* Not touching AVSubtitles again*/
+ if(sub->num_rects) {
+ avpriv_request_sample(ctx, "Different Version of Segment asked Twice");
+ return AVERROR_PATCHWELCOME;
+ }
+ for (display = ctx->display_list; display; display = display->next) {
+ region = get_region(ctx, display->region_id);
+ if (region && region->dirty)
+ sub->num_rects++;
+ }
+
+ if(ctx->compute_edt == 0) {
+ sub->end_display_time = ctx->time_out * 1000;
+ *got_output = 1;
+ } else if (ctx->prev_start != AV_NOPTS_VALUE) {
+ sub->end_display_time = av_rescale_q((sub->pts - ctx->prev_start ), AV_TIME_BASE_Q, (AVRational){ 1, 1000 }) - 1;
+ *got_output = 1;
+ }
+ if (sub->num_rects > 0) {
+
+ sub->rects = av_mallocz_array(sizeof(*sub->rects), sub->num_rects);
+ if (!sub->rects) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ for(i=0; i<sub->num_rects; i++)
+ sub->rects[i] = av_mallocz(sizeof(*sub->rects[i]));
+
+ i = 0;
+
+ for (display = ctx->display_list; display; display = display->next) {
+ region = get_region(ctx, display->region_id);
+
+ if (!region)
+ continue;
+
+ if (!region->dirty)
+ continue;
+
+ rect = sub->rects[i];
+ rect->x = display->x_pos + offset_x;
+ rect->y = display->y_pos + offset_y;
+ rect->w = region->width;
+ rect->h = region->height;
+ rect->nb_colors = (1 << region->depth);
+ rect->type = SUBTITLE_BITMAP;
+ rect->pict.linesize[0] = region->width;
+
+ clut = get_clut(ctx, region->clut);
+
+ if (!clut)
+ clut = &default_clut;
+
+ switch (region->depth) {
+ case 2:
+ clut_table = clut->clut4;
+ break;
+ case 8:
+ clut_table = clut->clut256;
+ break;
+ case 4:
+ default:
+ clut_table = clut->clut16;
+ break;
+ }
+
+ rect->pict.data[1] = av_mallocz(AVPALETTE_SIZE);
+ if (!rect->pict.data[1]) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ memcpy(rect->pict.data[1], clut_table, (1 << region->depth) * sizeof(uint32_t));
+
+ rect->pict.data[0] = av_malloc(region->buf_size);
+ if (!rect->pict.data[0]) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ memcpy(rect->pict.data[0], region->pbuf, region->buf_size);
+
+ if ((clut == &default_clut && ctx->compute_clut == -1) || ctx->compute_clut == 1)
+ compute_default_clut(&rect->pict, rect->w, rect->h);
+
+ i++;
+ }
+ }
+
+ return 0;
+fail:
+ if (sub->rects) {
+ for(i=0; i<sub->num_rects; i++) {
+ rect = sub->rects[i];
+ if (rect) {
+ av_freep(&rect->pict.data[0]);
+ av_freep(&rect->pict.data[1]);
+ }
+ av_freep(&sub->rects[i]);
+ }
+ av_freep(&sub->rects);
+ }
+ sub->num_rects = 0;
+ return ret;
+}
+
+static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDisplay *display,
+ const uint8_t *buf, int buf_size, int top_bottom, int non_mod)
+{
+ DVBSubContext *ctx = avctx->priv_data;
+
+ DVBSubRegion *region = get_region(ctx, display->region_id);
+ const uint8_t *buf_end = buf + buf_size;
+ uint8_t *pbuf;
+ int x_pos, y_pos;
+ int i;
+
+ uint8_t map2to4[] = { 0x0, 0x7, 0x8, 0xf};
+ uint8_t map2to8[] = {0x00, 0x77, 0x88, 0xff};
+ uint8_t map4to8[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
+ uint8_t *map_table;
+
+#if 0
+ ff_dlog(avctx, "DVB pixel block size %d, %s field:\n", buf_size,
+ top_bottom ? "bottom" : "top");
+
+ for (i = 0; i < buf_size; i++) {
+ if (i % 16 == 0)
+ ff_dlog(avctx, "0x%8p: ", buf+i);
+
+ ff_dlog(avctx, "%02x ", buf[i]);
+ if (i % 16 == 15)
+ ff_dlog(avctx, "\n");
+ }
+
+ if (i % 16)
+ ff_dlog(avctx, "\n");
+#endif
+
+ if (!region)
+ return;
+
+ pbuf = region->pbuf;
+ region->dirty = 1;
+
+ x_pos = display->x_pos;
+ y_pos = display->y_pos;
+
+ y_pos += top_bottom;
+
+ while (buf < buf_end) {
+ if ((*buf!=0xf0 && x_pos >= region->width) || y_pos >= region->height) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid object location! %d-%d %d-%d %02x\n", x_pos, region->width, y_pos, region->height, *buf);
+ return;
+ }
+
+ switch (*buf++) {
+ case 0x10:
+ if (region->depth == 8)
+ map_table = map2to8;
+ else if (region->depth == 4)
+ map_table = map2to4;
+ else
+ map_table = NULL;
+
+ x_pos = dvbsub_read_2bit_string(avctx, pbuf + (y_pos * region->width),
+ region->width, &buf, buf_end - buf,
+ non_mod, map_table, x_pos);
+ break;
+ case 0x11:
+ if (region->depth < 4) {
+ av_log(avctx, AV_LOG_ERROR, "4-bit pixel string in %d-bit region!\n", region->depth);
+ return;
+ }
+
+ if (region->depth == 8)
+ map_table = map4to8;
+ else
+ map_table = NULL;
+
+ x_pos = dvbsub_read_4bit_string(avctx, pbuf + (y_pos * region->width),
+ region->width, &buf, buf_end - buf,
+ non_mod, map_table, x_pos);
+ break;
+ case 0x12:
+ if (region->depth < 8) {
+ av_log(avctx, AV_LOG_ERROR, "8-bit pixel string in %d-bit region!\n", region->depth);
+ return;
+ }
+
+ x_pos = dvbsub_read_8bit_string(avctx, pbuf + (y_pos * region->width),
+ region->width, &buf, buf_end - buf,
+ non_mod, NULL, x_pos);
+ break;
+
+ case 0x20:
+ map2to4[0] = (*buf) >> 4;
+ map2to4[1] = (*buf++) & 0xf;
+ map2to4[2] = (*buf) >> 4;
+ map2to4[3] = (*buf++) & 0xf;
+ break;
+ case 0x21:
+ for (i = 0; i < 4; i++)
+ map2to8[i] = *buf++;
+ break;
+ case 0x22:
+ for (i = 0; i < 16; i++)
+ map4to8[i] = *buf++;
+ break;
+
+ case 0xf0:
+ x_pos = display->x_pos;
+ y_pos += 2;
+ break;
+ default:
+ av_log(avctx, AV_LOG_INFO, "Unknown/unsupported pixel block 0x%x\n", *(buf-1));
+ }
+ }
+
+}
+
+static int dvbsub_parse_object_segment(AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size)
+{
+ DVBSubContext *ctx = avctx->priv_data;
+
+ const uint8_t *buf_end = buf + buf_size;
+ int object_id;
+ DVBSubObject *object;
+ DVBSubObjectDisplay *display;
+ int top_field_len, bottom_field_len;
+
+ int coding_method, non_modifying_color;
+
+ object_id = AV_RB16(buf);
+ buf += 2;
+
+ object = get_object(ctx, object_id);
+
+ if (!object)
+ return AVERROR_INVALIDDATA;
+
+ coding_method = ((*buf) >> 2) & 3;
+ non_modifying_color = ((*buf++) >> 1) & 1;
+
+ if (coding_method == 0) {
+ top_field_len = AV_RB16(buf);
+ buf += 2;
+ bottom_field_len = AV_RB16(buf);
+ buf += 2;
+
+ if (buf + top_field_len + bottom_field_len > buf_end) {
+ av_log(avctx, AV_LOG_ERROR, "Field data size %d+%d too large\n", top_field_len, bottom_field_len);
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (display = object->display_list; display; display = display->object_list_next) {
+ const uint8_t *block = buf;
+ int bfl = bottom_field_len;
+
+ dvbsub_parse_pixel_data_block(avctx, display, block, top_field_len, 0,
+ non_modifying_color);
+
+ if (bottom_field_len > 0)
+ block = buf + top_field_len;
+ else
+ bfl = top_field_len;
+
+ dvbsub_parse_pixel_data_block(avctx, display, block, bfl, 1,
+ non_modifying_color);
+ }
+
+/* } else if (coding_method == 1) {*/
+
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "Unknown object coding %d\n", coding_method);
+ }
+
+ return 0;
+}
+
+static int dvbsub_parse_clut_segment(AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size)
+{
+ DVBSubContext *ctx = avctx->priv_data;
+
+ const uint8_t *buf_end = buf + buf_size;
+ int i, clut_id;
+ int version;
+ DVBSubCLUT *clut;
+ int entry_id, depth , full_range;
+ int y, cr, cb, alpha;
+ int r, g, b, r_add, g_add, b_add;
+
+ ff_dlog(avctx, "DVB clut packet:\n");
+
+ for (i=0; i < buf_size; i++) {
+ ff_dlog(avctx, "%02x ", buf[i]);
+ if (i % 16 == 15)
+ ff_dlog(avctx, "\n");
+ }
+
+ if (i % 16)
+ ff_dlog(avctx, "\n");
+
+ clut_id = *buf++;
+ version = ((*buf)>>4)&15;
+ buf += 1;
+
+ clut = get_clut(ctx, clut_id);
+
+ if (!clut) {
+ clut = av_malloc(sizeof(DVBSubCLUT));
+ if (!clut)
+ return AVERROR(ENOMEM);
+
+ memcpy(clut, &default_clut, sizeof(DVBSubCLUT));
+
+ clut->id = clut_id;
+ clut->version = -1;
+
+ clut->next = ctx->clut_list;
+ ctx->clut_list = clut;
+ }
+
+ if (clut->version != version) {
+
+ clut->version = version;
+
+ while (buf + 4 < buf_end) {
+ entry_id = *buf++;
+
+ depth = (*buf) & 0xe0;
+
+ 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);
+ }
+ }
+
+ return 0;
+}
+
+
+static int dvbsub_parse_region_segment(AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size)
+{
+ DVBSubContext *ctx = avctx->priv_data;
+
+ const uint8_t *buf_end = buf + buf_size;
+ int region_id, object_id;
+ int av_unused version;
+ DVBSubRegion *region;
+ DVBSubObject *object;
+ DVBSubObjectDisplay *display;
+ int fill;
+ int ret;
+
+ if (buf_size < 10)
+ return AVERROR_INVALIDDATA;
+
+ region_id = *buf++;
+
+ region = get_region(ctx, region_id);
+
+ if (!region) {
+ region = av_mallocz(sizeof(DVBSubRegion));
+ if (!region)
+ return AVERROR(ENOMEM);
+
+ region->id = region_id;
+ region->version = -1;
+
+ region->next = ctx->region_list;
+ ctx->region_list = region;
+ }
+
+ version = ((*buf)>>4) & 15;
+ fill = ((*buf++) >> 3) & 1;
+
+ region->width = AV_RB16(buf);
+ buf += 2;
+ region->height = AV_RB16(buf);
+ buf += 2;
+
+ ret = av_image_check_size(region->width, region->height, 0, avctx);
+ if (ret < 0) {
+ region->width= region->height= 0;
+ return ret;
+ }
+
+ if (region->width * region->height != region->buf_size) {
+ av_free(region->pbuf);
+
+ region->buf_size = region->width * region->height;
+
+ region->pbuf = av_malloc(region->buf_size);
+ if (!region->pbuf) {
+ region->buf_size =
+ region->width =
+ region->height = 0;
+ return AVERROR(ENOMEM);
+ }
+
+ fill = 1;
+ region->dirty = 0;
+ }
+
+ region->depth = 1 << (((*buf++) >> 2) & 7);
+ if(region->depth<2 || region->depth>8){
+ av_log(avctx, AV_LOG_ERROR, "region depth %d is invalid\n", region->depth);
+ region->depth= 4;
+ }
+ region->clut = *buf++;
+
+ if (region->depth == 8) {
+ region->bgcolor = *buf++;
+ buf += 1;
+ } else {
+ buf += 1;
+
+ if (region->depth == 4)
+ region->bgcolor = (((*buf++) >> 4) & 15);
+ else
+ region->bgcolor = (((*buf++) >> 2) & 3);
+ }
+
+ ff_dlog(avctx, "Region %d, (%dx%d)\n", region_id, region->width, region->height);
+
+ if (fill) {
+ memset(region->pbuf, region->bgcolor, region->buf_size);
+ ff_dlog(avctx, "Fill region (%d)\n", region->bgcolor);
+ }
+
+ delete_region_display_list(ctx, region);
+
+ while (buf + 5 < buf_end) {
+ object_id = AV_RB16(buf);
+ buf += 2;
+
+ object = get_object(ctx, object_id);
+
+ if (!object) {
+ object = av_mallocz(sizeof(DVBSubObject));
+ if (!object)
+ return AVERROR(ENOMEM);
+
+ object->id = object_id;
+ object->next = ctx->object_list;
+ ctx->object_list = object;
+ }
+
+ object->type = (*buf) >> 6;
+
+ display = av_mallocz(sizeof(DVBSubObjectDisplay));
+ if (!display)
+ return AVERROR(ENOMEM);
+
+ display->object_id = object_id;
+ display->region_id = region_id;
+
+ display->x_pos = AV_RB16(buf) & 0xfff;
+ buf += 2;
+ display->y_pos = AV_RB16(buf) & 0xfff;
+ buf += 2;
+
+ if ((object->type == 1 || object->type == 2) && buf+1 < buf_end) {
+ display->fgcolor = *buf++;
+ display->bgcolor = *buf++;
+ }
+
+ display->region_list_next = region->display_list;
+ region->display_list = display;
+
+ display->object_list_next = object->display_list;
+ object->display_list = display;
+ }
+
+ return 0;
+}
+
+static int dvbsub_parse_page_segment(AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size, AVSubtitle *sub, int *got_output)
+{
+ DVBSubContext *ctx = avctx->priv_data;
+ DVBSubRegionDisplay *display;
+ DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;
+
+ const uint8_t *buf_end = buf + buf_size;
+ int region_id;
+ int page_state;
+ int timeout;
+ int version;
+
+ if (buf_size < 1)
+ return AVERROR_INVALIDDATA;
+
+ timeout = *buf++;
+ version = ((*buf)>>4) & 15;
+ page_state = ((*buf++) >> 2) & 3;
+
+ if (ctx->version == version) {
+ return 0;
+ }
+
+ ctx->time_out = timeout;
+ ctx->version = version;
+
+ ff_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state);
+
+ if(ctx->compute_edt == 1)
+ save_subtitle_set(avctx, sub, got_output);
+
+ if (page_state == 1 || page_state == 2) {
+ delete_regions(ctx);
+ delete_objects(ctx);
+ delete_cluts(ctx);
+ }
+
+ tmp_display_list = ctx->display_list;
+ ctx->display_list = NULL;
+
+ while (buf + 5 < buf_end) {
+ region_id = *buf++;
+ buf += 1;
+
+ display = tmp_display_list;
+ tmp_ptr = &tmp_display_list;
+
+ while (display && display->region_id != region_id) {
+ tmp_ptr = &display->next;
+ display = display->next;
+ }
+
+ if (!display) {
+ display = av_mallocz(sizeof(DVBSubRegionDisplay));
+ if (!display)
+ return AVERROR(ENOMEM);
+ }
+
+ display->region_id = region_id;
+
+ display->x_pos = AV_RB16(buf);
+ buf += 2;
+ display->y_pos = AV_RB16(buf);
+ buf += 2;
+
+ *tmp_ptr = display->next;
+
+ display->next = ctx->display_list;
+ ctx->display_list = display;
+
+ ff_dlog(avctx, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos);
+ }
+
+ while (tmp_display_list) {
+ display = tmp_display_list;
+
+ tmp_display_list = display->next;
+
+ av_freep(&display);
+ }
+
+ return 0;
+}
+
+
+#ifdef DEBUG
+static void save_display_set(DVBSubContext *ctx)
+{
+ DVBSubRegion *region;
+ DVBSubRegionDisplay *display;
+ DVBSubCLUT *clut;
+ uint32_t *clut_table;
+ int x_pos, y_pos, width, height;
+ int x, y, y_off, x_off;
+ uint32_t *pbuf;
+ char filename[32];
+ static int fileno_index = 0;
+
+ x_pos = -1;
+ y_pos = -1;
+ width = 0;
+ height = 0;
+
+ for (display = ctx->display_list; display; display = display->next) {
+ region = get_region(ctx, display->region_id);
+
+ if (!region)
+ return;
+
+ if (x_pos == -1) {
+ x_pos = display->x_pos;
+ y_pos = display->y_pos;
+ width = region->width;
+ height = region->height;
+ } else {
+ if (display->x_pos < x_pos) {
+ width += (x_pos - display->x_pos);
+ x_pos = display->x_pos;
+ }
+
+ if (display->y_pos < y_pos) {
+ height += (y_pos - display->y_pos);
+ y_pos = display->y_pos;
+ }
+
+ if (display->x_pos + region->width > x_pos + width) {
+ width = display->x_pos + region->width - x_pos;
+ }
+
+ if (display->y_pos + region->height > y_pos + height) {
+ height = display->y_pos + region->height - y_pos;
+ }
+ }
+ }
+
+ if (x_pos >= 0) {
+
+ pbuf = av_malloc(width * height * 4);
+ if (!pbuf)
+ return;
+
+ for (display = ctx->display_list; display; display = display->next) {
+ region = get_region(ctx, display->region_id);
+
+ if (!region)
+ return;
+
+ x_off = display->x_pos - x_pos;
+ y_off = display->y_pos - y_pos;
+
+ clut = get_clut(ctx, region->clut);
+
+ if (!clut)
+ clut = &default_clut;
+
+ switch (region->depth) {
+ case 2:
+ clut_table = clut->clut4;
+ break;
+ case 8:
+ clut_table = clut->clut256;
+ break;
+ case 4:
+ default:
+ clut_table = clut->clut16;
+ break;
+ }
+
+ for (y = 0; y < region->height; y++) {
+ for (x = 0; x < region->width; x++) {
+ pbuf[((y + y_off) * width) + x_off + x] =
+ clut_table[region->pbuf[y * region->width + x]];
+ }
+ }
+
+ }
+
+ snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index);
+
+ png_save2(filename, pbuf, width, height);
+
+ av_freep(&pbuf);
+ }
+
+ fileno_index++;
+}
+#endif
+
+static int dvbsub_parse_display_definition_segment(AVCodecContext *avctx,
+ const uint8_t *buf,
+ int buf_size)
+{
+ DVBSubContext *ctx = avctx->priv_data;
+ DVBSubDisplayDefinition *display_def = ctx->display_definition;
+ int dds_version, info_byte;
+
+ if (buf_size < 5)
+ return AVERROR_INVALIDDATA;
+
+ info_byte = bytestream_get_byte(&buf);
+ dds_version = info_byte >> 4;
+ if (display_def && display_def->version == dds_version)
+ return 0; // already have this display definition version
+
+ if (!display_def) {
+ display_def = av_mallocz(sizeof(*display_def));
+ if (!display_def)
+ return AVERROR(ENOMEM);
+ ctx->display_definition = display_def;
+ }
+
+ display_def->version = dds_version;
+ display_def->x = 0;
+ display_def->y = 0;
+ display_def->width = bytestream_get_be16(&buf) + 1;
+ display_def->height = bytestream_get_be16(&buf) + 1;
+ if (!avctx->width || !avctx->height) {
+ avctx->width = display_def->width;
+ avctx->height = display_def->height;
+ }
+
+ if (info_byte & 1<<3) { // display_window_flag
+ if (buf_size < 13)
+ return AVERROR_INVALIDDATA;
+
+ display_def->x = bytestream_get_be16(&buf);
+ display_def->width = bytestream_get_be16(&buf) - display_def->x + 1;
+ display_def->y = bytestream_get_be16(&buf);
+ display_def->height = bytestream_get_be16(&buf) - display_def->y + 1;
+ }
+
+ return 0;
+}
+
+static int dvbsub_display_end_segment(AVCodecContext *avctx, const uint8_t *buf,
+ int buf_size, AVSubtitle *sub,int *got_output)
+{
+ DVBSubContext *ctx = avctx->priv_data;
+
+ if(ctx->compute_edt == 0)
+ save_subtitle_set(avctx, sub, got_output);
+#ifdef DEBUG
+ save_display_set(ctx);
+#endif
+ return 0;
+}
+
+static int dvbsub_decode(AVCodecContext *avctx,
+ void *data, int *data_size,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ DVBSubContext *ctx = avctx->priv_data;
+ AVSubtitle *sub = data;
+ const uint8_t *p, *p_end;
+ int segment_type;
+ int page_id;
+ int segment_length;
+ int i;
+ int ret = 0;
+ int got_segment = 0;
+ int got_dds = 0;
+
+ ff_dlog(avctx, "DVB sub packet:\n");
+
+ for (i=0; i < buf_size; i++) {
+ ff_dlog(avctx, "%02x ", buf[i]);
+ if (i % 16 == 15)
+ ff_dlog(avctx, "\n");
+ }
+
+ if (i % 16)
+ ff_dlog(avctx, "\n");
+
+ if (buf_size <= 6 || *buf != 0x0f) {
+ ff_dlog(avctx, "incomplete or broken packet");
+ return AVERROR_INVALIDDATA;
+ }
+
+ p = buf;
+ p_end = buf + buf_size;
+
+ while (p_end - p >= 6 && *p == 0x0f) {
+ p += 1;
+ segment_type = *p++;
+ page_id = AV_RB16(p);
+ p += 2;
+ segment_length = AV_RB16(p);
+ p += 2;
+
+ if (avctx->debug & FF_DEBUG_STARTCODE) {
+ av_log(avctx, AV_LOG_DEBUG, "segment_type:%d page_id:%d segment_length:%d\n", segment_type, page_id, segment_length);
+ }
+
+ if (p_end - p < segment_length) {
+ ff_dlog(avctx, "incomplete or broken packet");
+ ret = -1;
+ goto end;
+ }
+
+ if (page_id == ctx->composition_id || page_id == ctx->ancillary_id ||
+ ctx->composition_id == -1 || ctx->ancillary_id == -1) {
+ int ret = 0;
+ switch (segment_type) {
+ case DVBSUB_PAGE_SEGMENT:
+ ret = dvbsub_parse_page_segment(avctx, p, segment_length, sub, data_size);
+ got_segment |= 1;
+ break;
+ case DVBSUB_REGION_SEGMENT:
+ ret = dvbsub_parse_region_segment(avctx, p, segment_length);
+ got_segment |= 2;
+ break;
+ case DVBSUB_CLUT_SEGMENT:
+ ret = dvbsub_parse_clut_segment(avctx, p, segment_length);
+ if (ret < 0) goto end;
+ got_segment |= 4;
+ break;
+ case DVBSUB_OBJECT_SEGMENT:
+ ret = dvbsub_parse_object_segment(avctx, p, segment_length);
+ got_segment |= 8;
+ break;
+ case DVBSUB_DISPLAYDEFINITION_SEGMENT:
+ ret = dvbsub_parse_display_definition_segment(avctx, p,
+ segment_length);
+ got_dds = 1;
+ break;
+ case DVBSUB_DISPLAY_SEGMENT:
+ ret = dvbsub_display_end_segment(avctx, p, segment_length, sub, data_size);
+ if (got_segment == 15 && !got_dds && !avctx->width && !avctx->height) {
+ // Default from ETSI EN 300 743 V1.3.1 (7.2.1)
+ avctx->width = 720;
+ avctx->height = 576;
+ }
+ got_segment |= 16;
+ break;
+ default:
+ ff_dlog(avctx, "Subtitling segment type 0x%x, page id %d, length %d\n",
+ segment_type, page_id, segment_length);
+ break;
+ }
+ if (ret < 0)
+ goto end;
+ }
+
+ p += segment_length;
+ }
+ // Some streams do not send a display segment but if we have all the other
+ // segments then we need no further data.
+ if (got_segment == 15) {
+ av_log(avctx, AV_LOG_DEBUG, "Missing display_end_segment, emulating\n");
+ dvbsub_display_end_segment(avctx, p, 0, sub, data_size);
+ }
+
+end:
+ if(ret < 0) {
+ *data_size = 0;
+ avsubtitle_free(sub);
+ return ret;
+ } else {
+ if(ctx->compute_edt == 1 )
+ FFSWAP(int64_t, ctx->prev_start, sub->pts);
+ }
+
+ return p - buf;
+}
+
+#define DS AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_SUBTITLE_PARAM
+static const AVOption options[] = {
+ {"compute_edt", "compute end of time using pts or timeout", offsetof(DVBSubContext, compute_edt), AV_OPT_TYPE_INT, {.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_INT, {.i64 = -1}, -1, 1, DS},
+ {"dvb_substream", "", offsetof(DVBSubContext, substream), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 63, DS},
+ {NULL}
+};
+static const AVClass dvbsubdec_class = {
+ .class_name = "DVB Sub Decoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_dvbsub_decoder = {
+ .name = "dvbsub",
+ .long_name = NULL_IF_CONFIG_SMALL("DVB subtitles"),
+ .type = AVMEDIA_TYPE_SUBTITLE,
+ .id = AV_CODEC_ID_DVB_SUBTITLE,
+ .priv_data_size = sizeof(DVBSubContext),
+ .init = dvbsub_init_decoder,
+ .close = dvbsub_close_decoder,
+ .decode = dvbsub_decode,
+ .priv_class = &dvbsubdec_class,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/dvd_nav_parser.c b/ffmpeg-2-8-12/libavcodec/dvd_nav_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dvd_nav_parser.c
rename to ffmpeg-2-8-12/libavcodec/dvd_nav_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/dvdata.c b/ffmpeg-2-8-12/libavcodec/dvdata.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dvdata.c
rename to ffmpeg-2-8-12/libavcodec/dvdata.c
diff --git a/ffmpeg-2-8-11/libavcodec/dvdata.h b/ffmpeg-2-8-12/libavcodec/dvdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dvdata.h
rename to ffmpeg-2-8-12/libavcodec/dvdata.h
diff --git a/ffmpeg-2-8-11/libavcodec/dvdec.c b/ffmpeg-2-8-12/libavcodec/dvdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dvdec.c
rename to ffmpeg-2-8-12/libavcodec/dvdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/dvdsub_parser.c b/ffmpeg-2-8-12/libavcodec/dvdsub_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dvdsub_parser.c
rename to ffmpeg-2-8-12/libavcodec/dvdsub_parser.c
diff --git a/ffmpeg-2-8-12/libavcodec/dvdsubdec.c b/ffmpeg-2-8-12/libavcodec/dvdsubdec.c
new file mode 100644
index 0000000..5e0820e
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/dvdsubdec.c
@@ -0,0 +1,761 @@
+/*
+ * DVD subtitle decoding
+ * 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 "get_bits.h"
+#include "internal.h"
+
+#include "libavutil/attributes.h"
+#include "libavutil/colorspace.h"
+#include "libavutil/opt.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bswap.h"
+
+typedef struct DVDSubContext
+{
+ AVClass *class;
+ uint32_t palette[16];
+ char *palette_str;
+ char *ifo_str;
+ int has_palette;
+ uint8_t colormap[4];
+ uint8_t alpha[256];
+ uint8_t buf[0x10000];
+ int buf_size;
+ int forced_subs_only;
+#ifdef DEBUG
+ int sub_id;
+#endif
+} DVDSubContext;
+
+static void yuv_a_to_rgba(const uint8_t *ycbcr, const uint8_t *alpha, uint32_t *rgba, int num_values)
+{
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ uint8_t r, g, b;
+ int i, y, cb, cr;
+ int r_add, g_add, b_add;
+
+ for (i = num_values; i > 0; i--) {
+ y = *ycbcr++;
+ cr = *ycbcr++;
+ cb = *ycbcr++;
+ YUV_TO_RGB1_CCIR(cb, cr);
+ YUV_TO_RGB2_CCIR(r, g, b, y);
+ *rgba++ = ((unsigned)*alpha++ << 24) | (r << 16) | (g << 8) | b;
+ }
+}
+
+static int decode_run_2bit(GetBitContext *gb, int *color)
+{
+ unsigned int v, t;
+
+ v = 0;
+ for (t = 1; v < t && t <= 0x40; t <<= 2)
+ v = (v << 4) | get_bits(gb, 4);
+ *color = v & 3;
+ if (v < 4) { /* Code for fill rest of line */
+ return INT_MAX;
+ }
+ return v >> 2;
+}
+
+static int decode_run_8bit(GetBitContext *gb, int *color)
+{
+ int len;
+ int has_run = get_bits1(gb);
+ if (get_bits1(gb))
+ *color = get_bits(gb, 8);
+ else
+ *color = get_bits(gb, 2);
+ if (has_run) {
+ if (get_bits1(gb)) {
+ len = get_bits(gb, 7);
+ if (len == 0)
+ len = INT_MAX;
+ else
+ len += 9;
+ } else
+ len = get_bits(gb, 3) + 2;
+ } else
+ len = 1;
+ return len;
+}
+
+static int decode_rle(uint8_t *bitmap, int linesize, int w, int h,
+ const uint8_t *buf, int start, int buf_size, int is_8bit)
+{
+ GetBitContext gb;
+ int bit_len;
+ int x, y, len, color;
+ uint8_t *d;
+
+ if (start >= buf_size)
+ return -1;
+
+ if (w <= 0 || h <= 0)
+ return -1;
+
+ bit_len = (buf_size - start) * 8;
+ init_get_bits(&gb, buf + start, bit_len);
+
+ x = 0;
+ y = 0;
+ d = bitmap;
+ for(;;) {
+ if (get_bits_count(&gb) > bit_len)
+ return -1;
+ if (is_8bit)
+ len = decode_run_8bit(&gb, &color);
+ else
+ len = decode_run_2bit(&gb, &color);
+ len = FFMIN(len, w - x);
+ memset(d + x, color, len);
+ x += len;
+ if (x >= w) {
+ y++;
+ if (y >= h)
+ break;
+ d += linesize;
+ x = 0;
+ /* byte align */
+ align_get_bits(&gb);
+ }
+ }
+ return 0;
+}
+
+static void guess_palette(DVDSubContext* ctx,
+ uint32_t *rgba_palette,
+ uint32_t subtitle_color)
+{
+ static const uint8_t level_map[4][4] = {
+ // this configuration (full range, lowest to highest) in tests
+ // seemed most common, so assume this
+ {0xff},
+ {0x00, 0xff},
+ {0x00, 0x80, 0xff},
+ {0x00, 0x55, 0xaa, 0xff},
+ };
+ uint8_t color_used[16] = { 0 };
+ int nb_opaque_colors, i, level, j, r, g, b;
+ uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha;
+
+ if(ctx->has_palette) {
+ for(i = 0; i < 4; i++)
+ rgba_palette[i] = (ctx->palette[colormap[i]] & 0x00ffffff)
+ | ((alpha[i] * 17U) << 24);
+ return;
+ }
+
+ for(i = 0; i < 4; i++)
+ rgba_palette[i] = 0;
+
+ nb_opaque_colors = 0;
+ for(i = 0; i < 4; i++) {
+ if (alpha[i] != 0 && !color_used[colormap[i]]) {
+ color_used[colormap[i]] = 1;
+ nb_opaque_colors++;
+ }
+ }
+
+ if (nb_opaque_colors == 0)
+ return;
+
+ j = 0;
+ memset(color_used, 0, 16);
+ for(i = 0; i < 4; i++) {
+ if (alpha[i] != 0) {
+ if (!color_used[colormap[i]]) {
+ level = level_map[nb_opaque_colors - 1][j];
+ r = (((subtitle_color >> 16) & 0xff) * level) >> 8;
+ g = (((subtitle_color >> 8) & 0xff) * level) >> 8;
+ b = (((subtitle_color >> 0) & 0xff) * level) >> 8;
+ rgba_palette[i] = b | (g << 8) | (r << 16) | ((alpha[i] * 17U) << 24);
+ color_used[colormap[i]] = (i + 1);
+ j++;
+ } else {
+ rgba_palette[i] = (rgba_palette[color_used[colormap[i]] - 1] & 0x00ffffff) |
+ ((alpha[i] * 17U) << 24);
+ }
+ }
+ }
+}
+
+static void reset_rects(AVSubtitle *sub_header)
+{
+ int i;
+
+ if (sub_header->rects) {
+ for (i = 0; i < sub_header->num_rects; i++) {
+ av_freep(&sub_header->rects[i]->pict.data[0]);
+ av_freep(&sub_header->rects[i]->pict.data[1]);
+ av_freep(&sub_header->rects[i]);
+ }
+ av_freep(&sub_header->rects);
+ sub_header->num_rects = 0;
+ }
+}
+
+#define READ_OFFSET(a) (big_offsets ? AV_RB32(a) : AV_RB16(a))
+
+static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header,
+ const uint8_t *buf, int buf_size)
+{
+ int cmd_pos, pos, cmd, x1, y1, x2, y2, offset1, offset2, next_cmd_pos;
+ int big_offsets, offset_size, is_8bit = 0;
+ const uint8_t *yuv_palette = NULL;
+ uint8_t *colormap = ctx->colormap, *alpha = ctx->alpha;
+ int date;
+ int i;
+ int is_menu = 0;
+
+ if (buf_size < 10)
+ return -1;
+
+ if (AV_RB16(buf) == 0) { /* HD subpicture with 4-byte offsets */
+ big_offsets = 1;
+ offset_size = 4;
+ cmd_pos = 6;
+ } else {
+ big_offsets = 0;
+ offset_size = 2;
+ cmd_pos = 2;
+ }
+
+ cmd_pos = READ_OFFSET(buf + cmd_pos);
+
+ if (cmd_pos < 0 || cmd_pos > buf_size - 2 - offset_size)
+ return AVERROR(EAGAIN);
+
+ while (cmd_pos > 0 && cmd_pos < buf_size - 2 - offset_size) {
+ date = AV_RB16(buf + cmd_pos);
+ next_cmd_pos = READ_OFFSET(buf + cmd_pos + 2);
+ ff_dlog(NULL, "cmd_pos=0x%04x next=0x%04x date=%d\n",
+ cmd_pos, next_cmd_pos, date);
+ pos = cmd_pos + 2 + offset_size;
+ offset1 = -1;
+ offset2 = -1;
+ x1 = y1 = x2 = y2 = 0;
+ while (pos < buf_size) {
+ cmd = buf[pos++];
+ ff_dlog(NULL, "cmd=%02x\n", cmd);
+ switch(cmd) {
+ case 0x00:
+ /* menu subpicture */
+ is_menu = 1;
+ break;
+ case 0x01:
+ /* set start date */
+ sub_header->start_display_time = (date << 10) / 90;
+ break;
+ case 0x02:
+ /* set end date */
+ sub_header->end_display_time = (date << 10) / 90;
+ break;
+ case 0x03:
+ /* set colormap */
+ if ((buf_size - pos) < 2)
+ goto fail;
+ colormap[3] = buf[pos] >> 4;
+ colormap[2] = buf[pos] & 0x0f;
+ colormap[1] = buf[pos + 1] >> 4;
+ colormap[0] = buf[pos + 1] & 0x0f;
+ pos += 2;
+ break;
+ case 0x04:
+ /* set alpha */
+ if ((buf_size - pos) < 2)
+ goto fail;
+ alpha[3] = buf[pos] >> 4;
+ alpha[2] = buf[pos] & 0x0f;
+ alpha[1] = buf[pos + 1] >> 4;
+ alpha[0] = buf[pos + 1] & 0x0f;
+ pos += 2;
+ ff_dlog(NULL, "alpha=%x%x%x%x\n", alpha[0],alpha[1],alpha[2],alpha[3]);
+ break;
+ case 0x05:
+ case 0x85:
+ if ((buf_size - pos) < 6)
+ goto fail;
+ x1 = (buf[pos] << 4) | (buf[pos + 1] >> 4);
+ x2 = ((buf[pos + 1] & 0x0f) << 8) | buf[pos + 2];
+ y1 = (buf[pos + 3] << 4) | (buf[pos + 4] >> 4);
+ y2 = ((buf[pos + 4] & 0x0f) << 8) | buf[pos + 5];
+ if (cmd & 0x80)
+ is_8bit = 1;
+ ff_dlog(NULL, "x1=%d x2=%d y1=%d y2=%d\n", x1, x2, y1, y2);
+ pos += 6;
+ break;
+ case 0x06:
+ if ((buf_size - pos) < 4)
+ goto fail;
+ offset1 = AV_RB16(buf + pos);
+ offset2 = AV_RB16(buf + pos + 2);
+ ff_dlog(NULL, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2);
+ pos += 4;
+ break;
+ case 0x86:
+ if ((buf_size - pos) < 8)
+ goto fail;
+ offset1 = AV_RB32(buf + pos);
+ offset2 = AV_RB32(buf + pos + 4);
+ ff_dlog(NULL, "offset1=0x%04x offset2=0x%04x\n", offset1, offset2);
+ pos += 8;
+ break;
+
+ case 0x83:
+ /* HD set palette */
+ if ((buf_size - pos) < 768)
+ goto fail;
+ yuv_palette = buf + pos;
+ pos += 768;
+ break;
+ case 0x84:
+ /* HD set contrast (alpha) */
+ if ((buf_size - pos) < 256)
+ goto fail;
+ for (i = 0; i < 256; i++)
+ alpha[i] = 0xFF - buf[pos+i];
+ pos += 256;
+ break;
+
+ case 0xff:
+ goto the_end;
+ default:
+ ff_dlog(NULL, "unrecognised subpicture command 0x%x\n", cmd);
+ goto the_end;
+ }
+ }
+ the_end:
+ if (offset1 >= 0 && offset2 >= 0) {
+ int w, h;
+ uint8_t *bitmap;
+
+ /* decode the bitmap */
+ w = x2 - x1 + 1;
+ if (w < 0)
+ w = 0;
+ h = y2 - y1 + 1;
+ if (h < 0)
+ h = 0;
+ if (w > 0 && h > 0) {
+ reset_rects(sub_header);
+
+ sub_header->rects = av_mallocz(sizeof(*sub_header->rects));
+ if (!sub_header->rects)
+ goto fail;
+ sub_header->rects[0] = av_mallocz(sizeof(AVSubtitleRect));
+ if (!sub_header->rects[0])
+ goto fail;
+ sub_header->num_rects = 1;
+ bitmap = sub_header->rects[0]->pict.data[0] = av_malloc(w * h);
+ if (!bitmap)
+ goto fail;
+ if (decode_rle(bitmap, w * 2, w, (h + 1) / 2,
+ buf, offset1, buf_size, is_8bit) < 0)
+ goto fail;
+ if (decode_rle(bitmap + w, w * 2, w, h / 2,
+ buf, offset2, buf_size, is_8bit) < 0)
+ goto fail;
+ sub_header->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE);
+ if (!sub_header->rects[0]->pict.data[1])
+ goto fail;
+ if (is_8bit) {
+ if (!yuv_palette)
+ goto fail;
+ sub_header->rects[0]->nb_colors = 256;
+ yuv_a_to_rgba(yuv_palette, alpha, (uint32_t*)sub_header->rects[0]->pict.data[1], 256);
+ } else {
+ sub_header->rects[0]->nb_colors = 4;
+ guess_palette(ctx, (uint32_t*)sub_header->rects[0]->pict.data[1],
+ 0xffff00);
+ }
+ sub_header->rects[0]->x = x1;
+ sub_header->rects[0]->y = y1;
+ sub_header->rects[0]->w = w;
+ sub_header->rects[0]->h = h;
+ sub_header->rects[0]->type = SUBTITLE_BITMAP;
+ sub_header->rects[0]->pict.linesize[0] = w;
+ sub_header->rects[0]->flags = is_menu ? AV_SUBTITLE_FLAG_FORCED : 0;
+ }
+ }
+ if (next_cmd_pos < cmd_pos) {
+ av_log(NULL, AV_LOG_ERROR, "Invalid command offset\n");
+ break;
+ }
+ if (next_cmd_pos == cmd_pos)
+ break;
+ cmd_pos = next_cmd_pos;
+ }
+ if (sub_header->num_rects > 0)
+ return is_menu;
+ fail:
+ reset_rects(sub_header);
+ return -1;
+}
+
+static int is_transp(const uint8_t *buf, int pitch, int n,
+ const uint8_t *transp_color)
+{
+ int i;
+ for(i = 0; i < n; i++) {
+ if (!transp_color[*buf])
+ return 0;
+ buf += pitch;
+ }
+ return 1;
+}
+
+/* return 0 if empty rectangle, 1 if non empty */
+static int find_smallest_bounding_rectangle(AVSubtitle *s)
+{
+ uint8_t transp_color[256] = { 0 };
+ int y1, y2, x1, x2, y, w, h, i;
+ uint8_t *bitmap;
+
+ if (s->num_rects == 0 || !s->rects || s->rects[0]->w <= 0 || s->rects[0]->h <= 0)
+ return 0;
+
+ for(i = 0; i < s->rects[0]->nb_colors; i++) {
+ if ((((uint32_t*)s->rects[0]->pict.data[1])[i] >> 24) == 0)
+ transp_color[i] = 1;
+ }
+ y1 = 0;
+ while (y1 < s->rects[0]->h && is_transp(s->rects[0]->pict.data[0] + y1 * s->rects[0]->pict.linesize[0],
+ 1, s->rects[0]->w, transp_color))
+ y1++;
+ if (y1 == s->rects[0]->h) {
+ av_freep(&s->rects[0]->pict.data[0]);
+ s->rects[0]->w = s->rects[0]->h = 0;
+ return 0;
+ }
+
+ y2 = s->rects[0]->h - 1;
+ while (y2 > 0 && is_transp(s->rects[0]->pict.data[0] + y2 * s->rects[0]->pict.linesize[0], 1,
+ s->rects[0]->w, transp_color))
+ y2--;
+ x1 = 0;
+ while (x1 < (s->rects[0]->w - 1) && is_transp(s->rects[0]->pict.data[0] + x1, s->rects[0]->pict.linesize[0],
+ s->rects[0]->h, transp_color))
+ x1++;
+ x2 = s->rects[0]->w - 1;
+ while (x2 > 0 && is_transp(s->rects[0]->pict.data[0] + x2, s->rects[0]->pict.linesize[0], s->rects[0]->h,
+ transp_color))
+ x2--;
+ w = x2 - x1 + 1;
+ h = y2 - y1 + 1;
+ bitmap = av_malloc(w * h);
+ if (!bitmap)
+ return 1;
+ for(y = 0; y < h; y++) {
+ memcpy(bitmap + w * y, s->rects[0]->pict.data[0] + x1 + (y1 + y) * s->rects[0]->pict.linesize[0], w);
+ }
+ av_freep(&s->rects[0]->pict.data[0]);
+ s->rects[0]->pict.data[0] = bitmap;
+ s->rects[0]->pict.linesize[0] = w;
+ s->rects[0]->w = w;
+ s->rects[0]->h = h;
+ s->rects[0]->x += x1;
+ s->rects[0]->y += y1;
+ return 1;
+}
+
+#ifdef DEBUG
+#define ALPHA_MIX(A,BACK,FORE) (((255-(A)) * (BACK) + (A) * (FORE)) / 255)
+static void ppm_save(const char *filename, uint8_t *bitmap, int w, int h,
+ uint32_t *rgba_palette)
+{
+ int x, y, alpha;
+ uint32_t v;
+ int back[3] = {0, 255, 0}; /* green background */
+ FILE *f;
+
+ f = fopen(filename, "w");
+ if (!f) {
+ perror(filename);
+ return;
+ }
+ fprintf(f, "P6\n"
+ "%d %d\n"
+ "%d\n",
+ w, h, 255);
+ for(y = 0; y < h; y++) {
+ for(x = 0; x < w; x++) {
+ v = rgba_palette[bitmap[y * w + x]];
+ alpha = v >> 24;
+ putc(ALPHA_MIX(alpha, back[0], (v >> 16) & 0xff), f);
+ putc(ALPHA_MIX(alpha, back[1], (v >> 8) & 0xff), f);
+ putc(ALPHA_MIX(alpha, back[2], (v >> 0) & 0xff), f);
+ }
+ }
+ fclose(f);
+}
+#endif
+
+static int append_to_cached_buf(AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size)
+{
+ DVDSubContext *ctx = avctx->priv_data;
+
+ av_assert0(buf_size >= 0 && ctx->buf_size <= sizeof(ctx->buf));
+ if (buf_size >= sizeof(ctx->buf) - ctx->buf_size) {
+ av_log(avctx, AV_LOG_WARNING, "Attempt to reconstruct "
+ "too large SPU packets aborted.\n");
+ ctx->buf_size = 0;
+ return AVERROR_INVALIDDATA;
+ }
+ memcpy(ctx->buf + ctx->buf_size, buf, buf_size);
+ ctx->buf_size += buf_size;
+ return 0;
+}
+
+static int dvdsub_decode(AVCodecContext *avctx,
+ void *data, int *data_size,
+ AVPacket *avpkt)
+{
+ DVDSubContext *ctx = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ AVSubtitle *sub = data;
+ int is_menu;
+
+ if (ctx->buf_size) {
+ int ret = append_to_cached_buf(avctx, buf, buf_size);
+ if (ret < 0) {
+ *data_size = 0;
+ return ret;
+ }
+ buf = ctx->buf;
+ buf_size = ctx->buf_size;
+ }
+
+ is_menu = decode_dvd_subtitles(ctx, sub, buf, buf_size);
+ if (is_menu == AVERROR(EAGAIN)) {
+ *data_size = 0;
+ return append_to_cached_buf(avctx, buf, buf_size);
+ }
+
+ if (is_menu < 0) {
+ no_subtitle:
+ reset_rects(sub);
+ *data_size = 0;
+
+ return buf_size;
+ }
+ if (!is_menu && find_smallest_bounding_rectangle(sub) == 0)
+ goto no_subtitle;
+
+ if (ctx->forced_subs_only && !(sub->rects[0]->flags & AV_SUBTITLE_FLAG_FORCED))
+ goto no_subtitle;
+
+#if defined(DEBUG)
+ {
+ char ppm_name[32];
+
+ snprintf(ppm_name, sizeof(ppm_name), "/tmp/%05d.ppm", ctx->sub_id++);
+ ff_dlog(NULL, "start=%d ms end =%d ms\n",
+ sub->start_display_time,
+ sub->end_display_time);
+ ppm_save(ppm_name, sub->rects[0]->pict.data[0],
+ sub->rects[0]->w, sub->rects[0]->h, (uint32_t*) sub->rects[0]->pict.data[1]);
+ }
+#endif
+
+ ctx->buf_size = 0;
+ *data_size = 1;
+ return buf_size;
+}
+
+static void parse_palette(DVDSubContext *ctx, char *p)
+{
+ int i;
+
+ ctx->has_palette = 1;
+ for(i=0;i<16;i++) {
+ ctx->palette[i] = strtoul(p, &p, 16);
+ while(*p == ',' || av_isspace(*p))
+ p++;
+ }
+}
+
+static int parse_ifo_palette(DVDSubContext *ctx, char *p)
+{
+ FILE *ifo;
+ char ifostr[12];
+ uint32_t sp_pgci, pgci, off_pgc, pgc;
+ uint8_t r, g, b, yuv[65], *buf;
+ int i, y, cb, cr, r_add, g_add, b_add;
+ int ret = 0;
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+
+ ctx->has_palette = 0;
+ if ((ifo = fopen(p, "r")) == NULL) {
+ av_log(ctx, AV_LOG_WARNING, "Unable to open IFO file \"%s\": %s\n", p, av_err2str(AVERROR(errno)));
+ return AVERROR_EOF;
+ }
+ if (fread(ifostr, 12, 1, ifo) != 1 || memcmp(ifostr, "DVDVIDEO-VTS", 12)) {
+ av_log(ctx, AV_LOG_WARNING, "\"%s\" is not a proper IFO file\n", p);
+ ret = AVERROR_INVALIDDATA;
+ goto end;
+ }
+ if (fseek(ifo, 0xCC, SEEK_SET) == -1) {
+ ret = AVERROR(errno);
+ goto end;
+ }
+ if (fread(&sp_pgci, 4, 1, ifo) == 1) {
+ pgci = av_be2ne32(sp_pgci) * 2048;
+ if (fseek(ifo, pgci + 0x0C, SEEK_SET) == -1) {
+ ret = AVERROR(errno);
+ goto end;
+ }
+ if (fread(&off_pgc, 4, 1, ifo) == 1) {
+ pgc = pgci + av_be2ne32(off_pgc);
+ if (fseek(ifo, pgc + 0xA4, SEEK_SET) == -1) {
+ ret = AVERROR(errno);
+ goto end;
+ }
+ if (fread(yuv, 64, 1, ifo) == 1) {
+ buf = yuv;
+ for(i=0; i<16; i++) {
+ y = *++buf;
+ cr = *++buf;
+ cb = *++buf;
+ YUV_TO_RGB1_CCIR(cb, cr);
+ YUV_TO_RGB2_CCIR(r, g, b, y);
+ ctx->palette[i] = (r << 16) + (g << 8) + b;
+ buf++;
+ }
+ ctx->has_palette = 1;
+ }
+ }
+ }
+ if (ctx->has_palette == 0) {
+ av_log(ctx, AV_LOG_WARNING, "Failed to read palette from IFO file \"%s\"\n", p);
+ ret = AVERROR_INVALIDDATA;
+ }
+end:
+ fclose(ifo);
+ return ret;
+}
+
+static int dvdsub_parse_extradata(AVCodecContext *avctx)
+{
+ DVDSubContext *ctx = (DVDSubContext*) avctx->priv_data;
+ char *dataorig, *data;
+ int ret = 1;
+
+ if (!avctx->extradata || !avctx->extradata_size)
+ return 1;
+
+ dataorig = data = av_malloc(avctx->extradata_size+1);
+ if (!data)
+ return AVERROR(ENOMEM);
+ memcpy(data, avctx->extradata, avctx->extradata_size);
+ data[avctx->extradata_size] = '\0';
+
+ for(;;) {
+ int pos = strcspn(data, "\n\r");
+ if (pos==0 && *data==0)
+ break;
+
+ if (strncmp("palette:", data, 8) == 0) {
+ parse_palette(ctx, data + 8);
+ } else if (strncmp("size:", data, 5) == 0) {
+ int w, h;
+ if (sscanf(data + 5, "%dx%d", &w, &h) == 2) {
+ ret = ff_set_dimensions(avctx, w, h);
+ if (ret < 0)
+ goto fail;
+ }
+ }
+
+ data += pos;
+ data += strspn(data, "\n\r");
+ }
+
+fail:
+ av_free(dataorig);
+ return ret;
+}
+
+static av_cold int dvdsub_init(AVCodecContext *avctx)
+{
+ DVDSubContext *ctx = avctx->priv_data;
+ int ret;
+
+ if ((ret = dvdsub_parse_extradata(avctx)) < 0)
+ return ret;
+
+ if (ctx->ifo_str)
+ parse_ifo_palette(ctx, ctx->ifo_str);
+ if (ctx->palette_str)
+ parse_palette(ctx, ctx->palette_str);
+ if (ctx->has_palette) {
+ int i;
+ av_log(avctx, AV_LOG_DEBUG, "palette:");
+ for(i=0;i<16;i++)
+ av_log(avctx, AV_LOG_DEBUG, " 0x%06x", ctx->palette[i]);
+ av_log(avctx, AV_LOG_DEBUG, "\n");
+ }
+
+ return 1;
+}
+
+static void dvdsub_flush(AVCodecContext *avctx)
+{
+ DVDSubContext *ctx = avctx->priv_data;
+ ctx->buf_size = 0;
+}
+
+static av_cold int dvdsub_close(AVCodecContext *avctx)
+{
+ dvdsub_flush(avctx);
+ return 0;
+}
+
+#define OFFSET(field) offsetof(DVDSubContext, field)
+#define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+ { "palette", "set the global palette", OFFSET(palette_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD },
+ { "ifo_palette", "obtain the global palette from .IFO file", OFFSET(ifo_str), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD },
+ { "forced_subs_only", "Only show forced subtitles", OFFSET(forced_subs_only), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, SD},
+ { NULL }
+};
+static const AVClass dvdsub_class = {
+ .class_name = "dvdsubdec",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_dvdsub_decoder = {
+ .name = "dvdsub",
+ .long_name = NULL_IF_CONFIG_SMALL("DVD subtitles"),
+ .type = AVMEDIA_TYPE_SUBTITLE,
+ .id = AV_CODEC_ID_DVD_SUBTITLE,
+ .priv_data_size = sizeof(DVDSubContext),
+ .init = dvdsub_init,
+ .decode = dvdsub_decode,
+ .flush = dvdsub_flush,
+ .close = dvdsub_close,
+ .priv_class = &dvdsub_class,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/dvdsubenc.c b/ffmpeg-2-8-12/libavcodec/dvdsubenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dvdsubenc.c
rename to ffmpeg-2-8-12/libavcodec/dvdsubenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/dvenc.c b/ffmpeg-2-8-12/libavcodec/dvenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dvenc.c
rename to ffmpeg-2-8-12/libavcodec/dvenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/dxa.c b/ffmpeg-2-8-12/libavcodec/dxa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dxa.c
rename to ffmpeg-2-8-12/libavcodec/dxa.c
diff --git a/ffmpeg-2-8-11/libavcodec/dxtory.c b/ffmpeg-2-8-12/libavcodec/dxtory.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dxtory.c
rename to ffmpeg-2-8-12/libavcodec/dxtory.c
diff --git a/ffmpeg-2-8-11/libavcodec/dxva2.c b/ffmpeg-2-8-12/libavcodec/dxva2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dxva2.c
rename to ffmpeg-2-8-12/libavcodec/dxva2.c
diff --git a/ffmpeg-2-8-11/libavcodec/dxva2.h b/ffmpeg-2-8-12/libavcodec/dxva2.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dxva2.h
rename to ffmpeg-2-8-12/libavcodec/dxva2.h
diff --git a/ffmpeg-2-8-11/libavcodec/dxva2_h264.c b/ffmpeg-2-8-12/libavcodec/dxva2_h264.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dxva2_h264.c
rename to ffmpeg-2-8-12/libavcodec/dxva2_h264.c
diff --git a/ffmpeg-2-8-11/libavcodec/dxva2_hevc.c b/ffmpeg-2-8-12/libavcodec/dxva2_hevc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dxva2_hevc.c
rename to ffmpeg-2-8-12/libavcodec/dxva2_hevc.c
diff --git a/ffmpeg-2-8-11/libavcodec/dxva2_internal.h b/ffmpeg-2-8-12/libavcodec/dxva2_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dxva2_internal.h
rename to ffmpeg-2-8-12/libavcodec/dxva2_internal.h
diff --git a/ffmpeg-2-8-11/libavcodec/dxva2_mpeg2.c b/ffmpeg-2-8-12/libavcodec/dxva2_mpeg2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dxva2_mpeg2.c
rename to ffmpeg-2-8-12/libavcodec/dxva2_mpeg2.c
diff --git a/ffmpeg-2-8-11/libavcodec/dxva2_vc1.c b/ffmpeg-2-8-12/libavcodec/dxva2_vc1.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/dxva2_vc1.c
rename to ffmpeg-2-8-12/libavcodec/dxva2_vc1.c
diff --git a/ffmpeg-2-8-11/libavcodec/eac3_data.c b/ffmpeg-2-8-12/libavcodec/eac3_data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/eac3_data.c
rename to ffmpeg-2-8-12/libavcodec/eac3_data.c
diff --git a/ffmpeg-2-8-11/libavcodec/eac3_data.h b/ffmpeg-2-8-12/libavcodec/eac3_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/eac3_data.h
rename to ffmpeg-2-8-12/libavcodec/eac3_data.h
diff --git a/ffmpeg-2-8-12/libavcodec/eac3dec.c b/ffmpeg-2-8-12/libavcodec/eac3dec.c
new file mode 100644
index 0000000..001a404
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/eac3dec.c
@@ -0,0 +1,612 @@
+/*
+ * E-AC-3 decoder
+ * Copyright (c) 2007 Bartlomiej Wolowiec <bartek.wolowiec at gmail.com>
+ * Copyright (c) 2008 Justin Ruggles
+ *
+ * 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
+ */
+
+/*
+ * There are several features of E-AC-3 that this decoder does not yet support.
+ *
+ * Enhanced Coupling
+ * No known samples exist. If any ever surface, this feature should not be
+ * too difficult to implement.
+ *
+ * Reduced Sample Rates
+ * No known samples exist. The spec also does not give clear information
+ * on how this is to be implemented.
+ *
+ * Dependent Streams
+ * Only the independent stream is currently decoded. Any dependent
+ * streams are skipped. We have only come across two examples of this, and
+ * they are both just test streams, one for HD-DVD and the other for
+ * Blu-ray.
+ *
+ * Transient Pre-noise Processing
+ * This is side information which a decoder should use to reduce artifacts
+ * caused by transients. There are samples which are known to have this
+ * information, but this decoder currently ignores it.
+ */
+
+
+#include "avcodec.h"
+#include "internal.h"
+#include "aac_ac3_parser.h"
+#include "ac3.h"
+#include "ac3_parser.h"
+#include "ac3dec.h"
+#include "ac3dec_data.h"
+#include "eac3_data.h"
+
+/** gain adaptive quantization mode */
+typedef enum {
+ EAC3_GAQ_NO =0,
+ EAC3_GAQ_12,
+ EAC3_GAQ_14,
+ EAC3_GAQ_124
+} EAC3GaqMode;
+
+#define EAC3_SR_CODE_REDUCED 3
+
+static void ff_eac3_apply_spectral_extension(AC3DecodeContext *s)
+{
+ int bin, bnd, ch, i;
+ uint8_t wrapflag[SPX_MAX_BANDS]={1,0,}, num_copy_sections, copy_sizes[SPX_MAX_BANDS];
+ float rms_energy[SPX_MAX_BANDS];
+
+ /* Set copy index mapping table. Set wrap flags to apply a notch filter at
+ wrap points later on. */
+ bin = s->spx_dst_start_freq;
+ num_copy_sections = 0;
+ for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
+ int copysize;
+ int bandsize = s->spx_band_sizes[bnd];
+ if (bin + bandsize > s->spx_src_start_freq) {
+ copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq;
+ bin = s->spx_dst_start_freq;
+ wrapflag[bnd] = 1;
+ }
+ for (i = 0; i < bandsize; i += copysize) {
+ if (bin == s->spx_src_start_freq) {
+ copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq;
+ bin = s->spx_dst_start_freq;
+ }
+ copysize = FFMIN(bandsize - i, s->spx_src_start_freq - bin);
+ bin += copysize;
+ }
+ }
+ copy_sizes[num_copy_sections++] = bin - s->spx_dst_start_freq;
+
+ for (ch = 1; ch <= s->fbw_channels; ch++) {
+ if (!s->channel_uses_spx[ch])
+ continue;
+
+ /* Copy coeffs from normal bands to extension bands */
+ bin = s->spx_src_start_freq;
+ for (i = 0; i < num_copy_sections; i++) {
+ memcpy(&s->transform_coeffs[ch][bin],
+ &s->transform_coeffs[ch][s->spx_dst_start_freq],
+ copy_sizes[i]*sizeof(INTFLOAT));
+ bin += copy_sizes[i];
+ }
+
+ /* Calculate RMS energy for each SPX band. */
+ bin = s->spx_src_start_freq;
+ for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
+ int bandsize = s->spx_band_sizes[bnd];
+ float accum = 0.0f;
+ for (i = 0; i < bandsize; i++) {
+ float coeff = s->transform_coeffs[ch][bin++];
+ accum += coeff * coeff;
+ }
+ rms_energy[bnd] = sqrtf(accum / bandsize);
+ }
+
+ /* Apply a notch filter at transitions between normal and extension
+ bands and at all wrap points. */
+ if (s->spx_atten_code[ch] >= 0) {
+ const float *atten_tab = ff_eac3_spx_atten_tab[s->spx_atten_code[ch]];
+ bin = s->spx_src_start_freq - 2;
+ for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
+ if (wrapflag[bnd]) {
+ INTFLOAT *coeffs = &s->transform_coeffs[ch][bin];
+ coeffs[0] *= atten_tab[0];
+ coeffs[1] *= atten_tab[1];
+ coeffs[2] *= atten_tab[2];
+ coeffs[3] *= atten_tab[1];
+ coeffs[4] *= atten_tab[0];
+ }
+ bin += s->spx_band_sizes[bnd];
+ }
+ }
+
+ /* Apply noise-blended coefficient scaling based on previously
+ calculated RMS energy, blending factors, and SPX coordinates for
+ each band. */
+ bin = s->spx_src_start_freq;
+ for (bnd = 0; bnd < s->num_spx_bands; bnd++) {
+ float nscale = s->spx_noise_blend[ch][bnd] * rms_energy[bnd] * (1.0f / INT32_MIN);
+ float sscale = s->spx_signal_blend[ch][bnd];
+#if USE_FIXED
+ // spx_noise_blend and spx_signal_blend are both FP.23
+ nscale *= 1.0 / (1<<23);
+ sscale *= 1.0 / (1<<23);
+#endif
+ for (i = 0; i < s->spx_band_sizes[bnd]; i++) {
+ float noise = nscale * (int32_t)av_lfg_get(&s->dith_state);
+ s->transform_coeffs[ch][bin] *= sscale;
+ s->transform_coeffs[ch][bin++] += noise;
+ }
+ }
+ }
+}
+
+
+/** lrint(M_SQRT2*cos(2*M_PI/12)*(1<<23)) */
+#define COEFF_0 10273905LL
+
+/** lrint(M_SQRT2*cos(0*M_PI/12)*(1<<23)) = lrint(M_SQRT2*(1<<23)) */
+#define COEFF_1 11863283LL
+
+/** lrint(M_SQRT2*cos(5*M_PI/12)*(1<<23)) */
+#define COEFF_2 3070444LL
+
+/**
+ * Calculate 6-point IDCT of the pre-mantissas.
+ * All calculations are 24-bit fixed-point.
+ */
+static void idct6(int pre_mant[6])
+{
+ int tmp;
+ int even0, even1, even2, odd0, odd1, odd2;
+
+ odd1 = pre_mant[1] - pre_mant[3] - pre_mant[5];
+
+ even2 = ( pre_mant[2] * COEFF_0) >> 23;
+ tmp = ( pre_mant[4] * COEFF_1) >> 23;
+ odd0 = ((pre_mant[1] + pre_mant[5]) * COEFF_2) >> 23;
+
+ even0 = pre_mant[0] + (tmp >> 1);
+ even1 = pre_mant[0] - tmp;
+
+ tmp = even0;
+ even0 = tmp + even2;
+ even2 = tmp - even2;
+
+ tmp = odd0;
+ odd0 = tmp + pre_mant[1] + pre_mant[3];
+ odd2 = tmp + pre_mant[5] - pre_mant[3];
+
+ pre_mant[0] = even0 + odd0;
+ pre_mant[1] = even1 + odd1;
+ pre_mant[2] = even2 + odd2;
+ pre_mant[3] = even2 - odd2;
+ pre_mant[4] = even1 - odd1;
+ pre_mant[5] = even0 - odd0;
+}
+
+static void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch)
+{
+ int bin, blk, gs;
+ int end_bap, gaq_mode;
+ GetBitContext *gbc = &s->gbc;
+ int gaq_gain[AC3_MAX_COEFS];
+
+ gaq_mode = get_bits(gbc, 2);
+ end_bap = (gaq_mode < 2) ? 12 : 17;
+
+ /* if GAQ gain is used, decode gain codes for bins with hebap between
+ 8 and end_bap */
+ gs = 0;
+ if (gaq_mode == EAC3_GAQ_12 || gaq_mode == EAC3_GAQ_14) {
+ /* read 1-bit GAQ gain codes */
+ for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
+ if (s->bap[ch][bin] > 7 && s->bap[ch][bin] < end_bap)
+ gaq_gain[gs++] = get_bits1(gbc) << (gaq_mode-1);
+ }
+ } else if (gaq_mode == EAC3_GAQ_124) {
+ /* read 1.67-bit GAQ gain codes (3 codes in 5 bits) */
+ int gc = 2;
+ for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
+ if (s->bap[ch][bin] > 7 && s->bap[ch][bin] < 17) {
+ if (gc++ == 2) {
+ int group_code = get_bits(gbc, 5);
+ if (group_code > 26) {
+ av_log(s->avctx, AV_LOG_WARNING, "GAQ gain group code out-of-range\n");
+ group_code = 26;
+ }
+ gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][0];
+ gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][1];
+ gaq_gain[gs++] = ff_ac3_ungroup_3_in_5_bits_tab[group_code][2];
+ gc = 0;
+ }
+ }
+ }
+ }
+
+ gs=0;
+ for (bin = s->start_freq[ch]; bin < s->end_freq[ch]; bin++) {
+ int hebap = s->bap[ch][bin];
+ int bits = ff_eac3_bits_vs_hebap[hebap];
+ if (!hebap) {
+ /* zero-mantissa dithering */
+ for (blk = 0; blk < 6; blk++) {
+ s->pre_mantissa[ch][bin][blk] = (av_lfg_get(&s->dith_state) & 0x7FFFFF) - 0x400000;
+ }
+ } else if (hebap < 8) {
+ /* Vector Quantization */
+ int v = get_bits(gbc, bits);
+ for (blk = 0; blk < 6; blk++) {
+ s->pre_mantissa[ch][bin][blk] = ff_eac3_mantissa_vq[hebap][v][blk] * (1 << 8);
+ }
+ } else {
+ /* Gain Adaptive Quantization */
+ int gbits, log_gain;
+ if (gaq_mode != EAC3_GAQ_NO && hebap < end_bap) {
+ log_gain = gaq_gain[gs++];
+ } else {
+ log_gain = 0;
+ }
+ gbits = bits - log_gain;
+
+ for (blk = 0; blk < 6; blk++) {
+ int mant = get_sbits(gbc, gbits);
+ if (log_gain && mant == -(1 << (gbits-1))) {
+ /* large mantissa */
+ int b;
+ int mbits = bits - (2 - log_gain);
+ mant = get_sbits(gbc, mbits);
+ mant = ((unsigned)mant) << (23 - (mbits - 1));
+ /* remap mantissa value to correct for asymmetric quantization */
+ if (mant >= 0)
+ b = 1 << (23 - log_gain);
+ else
+ b = ff_eac3_gaq_remap_2_4_b[hebap-8][log_gain-1] * (1 << 8);
+ mant += ((ff_eac3_gaq_remap_2_4_a[hebap-8][log_gain-1] * (int64_t)mant) >> 15) + b;
+ } else {
+ /* small mantissa, no GAQ, or Gk=1 */
+ mant *= (1 << 24 - bits);
+ if (!log_gain) {
+ /* remap mantissa value for no GAQ or Gk=1 */
+ mant += (ff_eac3_gaq_remap_1[hebap-8] * (int64_t)mant) >> 15;
+ }
+ }
+ s->pre_mantissa[ch][bin][blk] = mant;
+ }
+ }
+ idct6(s->pre_mantissa[ch][bin]);
+ }
+}
+
+static int ff_eac3_parse_header(AC3DecodeContext *s)
+{
+ int i, blk, ch;
+ int ac3_exponent_strategy, parse_aht_info, parse_spx_atten_data;
+ int parse_transient_proc_info;
+ int num_cpl_blocks;
+ GetBitContext *gbc = &s->gbc;
+
+ /* An E-AC-3 stream can have multiple independent streams which the
+ application can select from. each independent stream can also contain
+ dependent streams which are used to add or replace channels. */
+ if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) {
+ avpriv_request_sample(s->avctx, "Dependent substream decoding");
+ return AAC_AC3_PARSE_ERROR_FRAME_TYPE;
+ } else if (s->frame_type == EAC3_FRAME_TYPE_RESERVED) {
+ av_log(s->avctx, AV_LOG_ERROR, "Reserved frame type\n");
+ return AAC_AC3_PARSE_ERROR_FRAME_TYPE;
+ }
+
+ /* The substream id indicates which substream this frame belongs to. each
+ independent stream has its own substream id, and the dependent streams
+ associated to an independent stream have matching substream id's. */
+ if (s->substreamid) {
+ /* only decode substream with id=0. skip any additional substreams. */
+ avpriv_request_sample(s->avctx, "Additional substreams");
+ return AAC_AC3_PARSE_ERROR_FRAME_TYPE;
+ }
+
+ if (s->bit_alloc_params.sr_code == EAC3_SR_CODE_REDUCED) {
+ /* The E-AC-3 specification does not tell how to handle reduced sample
+ rates in bit allocation. The best assumption would be that it is
+ handled like AC-3 DolbyNet, but we cannot be sure until we have a
+ sample which utilizes this feature. */
+ avpriv_request_sample(s->avctx, "Reduced sampling rate");
+ return AVERROR_PATCHWELCOME;
+ }
+ skip_bits(gbc, 5); // skip bitstream id
+
+ /* volume control params */
+ for (i = 0; i < (s->channel_mode ? 1 : 2); i++) {
+ skip_bits(gbc, 5); // skip dialog normalization
+ if (get_bits1(gbc)) {
+ skip_bits(gbc, 8); // skip compression gain word
+ }
+ }
+
+ /* dependent stream channel map */
+ if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT) {
+ if (get_bits1(gbc)) {
+ skip_bits(gbc, 16); // skip custom channel map
+ }
+ }
+
+ /* mixing metadata */
+ if (get_bits1(gbc)) {
+ /* center and surround mix levels */
+ if (s->channel_mode > AC3_CHMODE_STEREO) {
+ s->preferred_downmix = get_bits(gbc, 2);
+ if (s->channel_mode & 1) {
+ /* if three front channels exist */
+ s->center_mix_level_ltrt = get_bits(gbc, 3);
+ s->center_mix_level = get_bits(gbc, 3);
+ }
+ if (s->channel_mode & 4) {
+ /* if a surround channel exists */
+ s->surround_mix_level_ltrt = av_clip(get_bits(gbc, 3), 3, 7);
+ s->surround_mix_level = av_clip(get_bits(gbc, 3), 3, 7);
+ }
+ }
+
+ /* lfe mix level */
+ if (s->lfe_on && (s->lfe_mix_level_exists = get_bits1(gbc))) {
+ s->lfe_mix_level = get_bits(gbc, 5);
+ }
+
+ /* info for mixing with other streams and substreams */
+ if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT) {
+ for (i = 0; i < (s->channel_mode ? 1 : 2); i++) {
+ // TODO: apply program scale factor
+ if (get_bits1(gbc)) {
+ skip_bits(gbc, 6); // skip program scale factor
+ }
+ }
+ if (get_bits1(gbc)) {
+ skip_bits(gbc, 6); // skip external program scale factor
+ }
+ /* skip mixing parameter data */
+ switch(get_bits(gbc, 2)) {
+ case 1: skip_bits(gbc, 5); break;
+ case 2: skip_bits(gbc, 12); break;
+ case 3: {
+ int mix_data_size = (get_bits(gbc, 5) + 2) << 3;
+ skip_bits_long(gbc, mix_data_size);
+ break;
+ }
+ }
+ /* skip pan information for mono or dual mono source */
+ if (s->channel_mode < AC3_CHMODE_STEREO) {
+ for (i = 0; i < (s->channel_mode ? 1 : 2); i++) {
+ if (get_bits1(gbc)) {
+ /* note: this is not in the ATSC A/52B specification
+ reference: ETSI TS 102 366 V1.1.1
+ section: E.1.3.1.25 */
+ skip_bits(gbc, 8); // skip pan mean direction index
+ skip_bits(gbc, 6); // skip reserved paninfo bits
+ }
+ }
+ }
+ /* skip mixing configuration information */
+ if (get_bits1(gbc)) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
+ if (s->num_blocks == 1 || get_bits1(gbc)) {
+ skip_bits(gbc, 5);
+ }
+ }
+ }
+ }
+ }
+
+ /* informational metadata */
+ if (get_bits1(gbc)) {
+ s->bitstream_mode = get_bits(gbc, 3);
+ skip_bits(gbc, 2); // skip copyright bit and original bitstream bit
+ if (s->channel_mode == AC3_CHMODE_STEREO) {
+ s->dolby_surround_mode = get_bits(gbc, 2);
+ s->dolby_headphone_mode = get_bits(gbc, 2);
+ }
+ if (s->channel_mode >= AC3_CHMODE_2F2R) {
+ s->dolby_surround_ex_mode = get_bits(gbc, 2);
+ }
+ for (i = 0; i < (s->channel_mode ? 1 : 2); i++) {
+ if (get_bits1(gbc)) {
+ skip_bits(gbc, 8); // skip mix level, room type, and A/D converter type
+ }
+ }
+ if (s->bit_alloc_params.sr_code != EAC3_SR_CODE_REDUCED) {
+ skip_bits1(gbc); // skip source sample rate code
+ }
+ }
+
+ /* converter synchronization flag
+ If frames are less than six blocks, this bit should be turned on
+ once every 6 blocks to indicate the start of a frame set.
+ reference: RFC 4598, Section 2.1.3 Frame Sets */
+ if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT && s->num_blocks != 6) {
+ skip_bits1(gbc); // skip converter synchronization flag
+ }
+
+ /* original frame size code if this stream was converted from AC-3 */
+ if (s->frame_type == EAC3_FRAME_TYPE_AC3_CONVERT &&
+ (s->num_blocks == 6 || get_bits1(gbc))) {
+ skip_bits(gbc, 6); // skip frame size code
+ }
+
+ /* additional bitstream info */
+ if (get_bits1(gbc)) {
+ int addbsil = get_bits(gbc, 6);
+ for (i = 0; i < addbsil + 1; i++) {
+ skip_bits(gbc, 8); // skip additional bit stream info
+ }
+ }
+
+ /* audio frame syntax flags, strategy data, and per-frame data */
+
+ if (s->num_blocks == 6) {
+ ac3_exponent_strategy = get_bits1(gbc);
+ parse_aht_info = get_bits1(gbc);
+ } else {
+ /* less than 6 blocks, so use AC-3-style exponent strategy syntax, and
+ do not use AHT */
+ ac3_exponent_strategy = 1;
+ parse_aht_info = 0;
+ }
+
+ s->snr_offset_strategy = get_bits(gbc, 2);
+ parse_transient_proc_info = get_bits1(gbc);
+
+ s->block_switch_syntax = get_bits1(gbc);
+ if (!s->block_switch_syntax)
+ memset(s->block_switch, 0, sizeof(s->block_switch));
+
+ s->dither_flag_syntax = get_bits1(gbc);
+ if (!s->dither_flag_syntax) {
+ for (ch = 1; ch <= s->fbw_channels; ch++)
+ s->dither_flag[ch] = 1;
+ }
+ s->dither_flag[CPL_CH] = s->dither_flag[s->lfe_ch] = 0;
+
+ s->bit_allocation_syntax = get_bits1(gbc);
+ if (!s->bit_allocation_syntax) {
+ /* set default bit allocation parameters */
+ s->bit_alloc_params.slow_decay = ff_ac3_slow_decay_tab[2];
+ s->bit_alloc_params.fast_decay = ff_ac3_fast_decay_tab[1];
+ s->bit_alloc_params.slow_gain = ff_ac3_slow_gain_tab [1];
+ s->bit_alloc_params.db_per_bit = ff_ac3_db_per_bit_tab[2];
+ s->bit_alloc_params.floor = ff_ac3_floor_tab [7];
+ }
+
+ s->fast_gain_syntax = get_bits1(gbc);
+ s->dba_syntax = get_bits1(gbc);
+ s->skip_syntax = get_bits1(gbc);
+ parse_spx_atten_data = get_bits1(gbc);
+
+ /* coupling strategy occurrence and coupling use per block */
+ num_cpl_blocks = 0;
+ if (s->channel_mode > 1) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
+ s->cpl_strategy_exists[blk] = (!blk || get_bits1(gbc));
+ if (s->cpl_strategy_exists[blk]) {
+ s->cpl_in_use[blk] = get_bits1(gbc);
+ } else {
+ s->cpl_in_use[blk] = s->cpl_in_use[blk-1];
+ }
+ num_cpl_blocks += s->cpl_in_use[blk];
+ }
+ } else {
+ memset(s->cpl_in_use, 0, sizeof(s->cpl_in_use));
+ }
+
+ /* exponent strategy data */
+ if (ac3_exponent_strategy) {
+ /* AC-3-style exponent strategy syntax */
+ for (blk = 0; blk < s->num_blocks; blk++) {
+ for (ch = !s->cpl_in_use[blk]; ch <= s->fbw_channels; ch++) {
+ s->exp_strategy[blk][ch] = get_bits(gbc, 2);
+ }
+ }
+ } else {
+ /* LUT-based exponent strategy syntax */
+ for (ch = !((s->channel_mode > 1) && num_cpl_blocks); ch <= s->fbw_channels; ch++) {
+ int frmchexpstr = get_bits(gbc, 5);
+ for (blk = 0; blk < 6; blk++) {
+ s->exp_strategy[blk][ch] = ff_eac3_frm_expstr[frmchexpstr][blk];
+ }
+ }
+ }
+ /* LFE exponent strategy */
+ if (s->lfe_on) {
+ for (blk = 0; blk < s->num_blocks; blk++) {
+ s->exp_strategy[blk][s->lfe_ch] = get_bits1(gbc);
+ }
+ }
+ /* original exponent strategies if this stream was converted from AC-3 */
+ if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT &&
+ (s->num_blocks == 6 || get_bits1(gbc))) {
+ skip_bits(gbc, 5 * s->fbw_channels); // skip converter channel exponent strategy
+ }
+
+ /* determine which channels use AHT */
+ if (parse_aht_info) {
+ /* For AHT to be used, all non-zero blocks must reuse exponents from
+ the first block. Furthermore, for AHT to be used in the coupling
+ channel, all blocks must use coupling and use the same coupling
+ strategy. */
+ s->channel_uses_aht[CPL_CH]=0;
+ for (ch = (num_cpl_blocks != 6); ch <= s->channels; ch++) {
+ int use_aht = 1;
+ for (blk = 1; blk < 6; blk++) {
+ if ((s->exp_strategy[blk][ch] != EXP_REUSE) ||
+ (!ch && s->cpl_strategy_exists[blk])) {
+ use_aht = 0;
+ break;
+ }
+ }
+ s->channel_uses_aht[ch] = use_aht && get_bits1(gbc);
+ }
+ } else {
+ memset(s->channel_uses_aht, 0, sizeof(s->channel_uses_aht));
+ }
+
+ /* per-frame SNR offset */
+ if (!s->snr_offset_strategy) {
+ int csnroffst = (get_bits(gbc, 6) - 15) << 4;
+ int snroffst = (csnroffst + get_bits(gbc, 4)) << 2;
+ for (ch = 0; ch <= s->channels; ch++)
+ s->snr_offset[ch] = snroffst;
+ }
+
+ /* transient pre-noise processing data */
+ if (parse_transient_proc_info) {
+ for (ch = 1; ch <= s->fbw_channels; ch++) {
+ if (get_bits1(gbc)) { // channel in transient processing
+ skip_bits(gbc, 10); // skip transient processing location
+ skip_bits(gbc, 8); // skip transient processing length
+ }
+ }
+ }
+
+ /* spectral extension attenuation data */
+ for (ch = 1; ch <= s->fbw_channels; ch++) {
+ if (parse_spx_atten_data && get_bits1(gbc)) {
+ s->spx_atten_code[ch] = get_bits(gbc, 5);
+ } else {
+ s->spx_atten_code[ch] = -1;
+ }
+ }
+
+ /* block start information */
+ if (s->num_blocks > 1 && get_bits1(gbc)) {
+ /* reference: Section E2.3.2.27
+ nblkstrtbits = (numblks - 1) * (4 + ceiling(log2(words_per_frame)))
+ The spec does not say what this data is or what it's used for.
+ It is likely the offset of each block within the frame. */
+ int block_start_bits = (s->num_blocks-1) * (4 + av_log2(s->frame_size-2));
+ skip_bits_long(gbc, block_start_bits);
+ avpriv_request_sample(s->avctx, "Block start info");
+ }
+
+ /* syntax state initialization */
+ for (ch = 1; ch <= s->fbw_channels; ch++) {
+ s->first_spx_coords[ch] = 1;
+ s->first_cpl_coords[ch] = 1;
+ }
+ s->first_cpl_leak = 1;
+
+ return 0;
+}
diff --git a/ffmpeg-2-8-11/libavcodec/eac3enc.c b/ffmpeg-2-8-12/libavcodec/eac3enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/eac3enc.c
rename to ffmpeg-2-8-12/libavcodec/eac3enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/eac3enc.h b/ffmpeg-2-8-12/libavcodec/eac3enc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/eac3enc.h
rename to ffmpeg-2-8-12/libavcodec/eac3enc.h
diff --git a/ffmpeg-2-8-11/libavcodec/eacmv.c b/ffmpeg-2-8-12/libavcodec/eacmv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/eacmv.c
rename to ffmpeg-2-8-12/libavcodec/eacmv.c
diff --git a/ffmpeg-2-8-11/libavcodec/eaidct.c b/ffmpeg-2-8-12/libavcodec/eaidct.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/eaidct.c
rename to ffmpeg-2-8-12/libavcodec/eaidct.c
diff --git a/ffmpeg-2-8-11/libavcodec/eaidct.h b/ffmpeg-2-8-12/libavcodec/eaidct.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/eaidct.h
rename to ffmpeg-2-8-12/libavcodec/eaidct.h
diff --git a/ffmpeg-2-8-12/libavcodec/eamad.c b/ffmpeg-2-8-12/libavcodec/eamad.c
new file mode 100644
index 0000000..0525394
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/eamad.c
@@ -0,0 +1,352 @@
+/*
+ * Electronic Arts Madcow Video Decoder
+ * Copyright (c) 2007-2009 Peter Ross
+ *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Electronic Arts Madcow Video Decoder
+ * @author Peter Ross <pross at xvid.org>
+ *
+ * @see technical details at
+ * http://wiki.multimedia.cx/index.php?title=Electronic_Arts_MAD
+ */
+
+#include "avcodec.h"
+#include "blockdsp.h"
+#include "bytestream.h"
+#include "bswapdsp.h"
+#include "get_bits.h"
+#include "aandcttab.h"
+#include "eaidct.h"
+#include "idctdsp.h"
+#include "internal.h"
+#include "mpeg12data.h"
+#include "mpeg12vlc.h"
+
+#define EA_PREAMBLE_SIZE 8
+#define MADk_TAG MKTAG('M', 'A', 'D', 'k') /* MAD i-frame */
+#define MADm_TAG MKTAG('M', 'A', 'D', 'm') /* MAD p-frame */
+#define MADe_TAG MKTAG('M', 'A', 'D', 'e') /* MAD lqp-frame */
+
+typedef struct MadContext {
+ AVCodecContext *avctx;
+ BlockDSPContext bdsp;
+ BswapDSPContext bbdsp;
+ IDCTDSPContext idsp;
+ AVFrame *last_frame;
+ GetBitContext gb;
+ void *bitstream_buf;
+ unsigned int bitstream_buf_size;
+ DECLARE_ALIGNED(16, int16_t, block)[64];
+ ScanTable scantable;
+ uint16_t quant_matrix[64];
+ int mb_x;
+ int mb_y;
+} MadContext;
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ MadContext *s = avctx->priv_data;
+ s->avctx = avctx;
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+ ff_blockdsp_init(&s->bdsp, avctx);
+ ff_bswapdsp_init(&s->bbdsp);
+ ff_idctdsp_init(&s->idsp, avctx);
+ ff_init_scantable_permutation(s->idsp.idct_permutation, FF_IDCT_PERM_NONE);
+ ff_init_scantable(s->idsp.idct_permutation, &s->scantable, ff_zigzag_direct);
+ ff_mpeg12_init_vlcs();
+
+ s->last_frame = av_frame_alloc();
+ if (!s->last_frame)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static inline void comp(unsigned char *dst, int dst_stride,
+ unsigned char *src, int src_stride, int add)
+{
+ int j, i;
+ for (j=0; j<8; j++)
+ for (i=0; i<8; i++)
+ dst[j*dst_stride + i] = av_clip_uint8(src[j*src_stride + i] + add);
+}
+
+static inline void comp_block(MadContext *t, AVFrame *frame,
+ int mb_x, int mb_y,
+ int j, int mv_x, int mv_y, int add)
+{
+ if (j < 4) {
+ unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame->linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x;
+ if (offset >= (t->avctx->height - 7) * t->last_frame->linesize[0] - 7)
+ return;
+ comp(frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3),
+ frame->linesize[0],
+ t->last_frame->data[0] + offset,
+ t->last_frame->linesize[0], add);
+ } else if (!(t->avctx->flags & AV_CODEC_FLAG_GRAY)) {
+ int index = j - 3;
+ unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame->linesize[index] + mb_x * 8 + (mv_x/2);
+ if (offset >= (t->avctx->height/2 - 7) * t->last_frame->linesize[index] - 7)
+ return;
+ comp(frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x * 8,
+ frame->linesize[index],
+ t->last_frame->data[index] + offset,
+ t->last_frame->linesize[index], add);
+ }
+}
+
+static inline void idct_put(MadContext *t, AVFrame *frame, int16_t *block,
+ int mb_x, int mb_y, int j)
+{
+ if (j < 4) {
+ ff_ea_idct_put_c(
+ frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3),
+ frame->linesize[0], block);
+ } else if (!(t->avctx->flags & AV_CODEC_FLAG_GRAY)) {
+ int index = j - 3;
+ ff_ea_idct_put_c(
+ frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x*8,
+ frame->linesize[index], block);
+ }
+}
+
+static inline int decode_block_intra(MadContext *s, int16_t * block)
+{
+ int level, i, j, run;
+ RLTable *rl = &ff_rl_mpeg1;
+ const uint8_t *scantable = s->scantable.permutated;
+ int16_t *quant_matrix = s->quant_matrix;
+
+ block[0] = (128 + get_sbits(&s->gb, 8)) * quant_matrix[0];
+
+ /* The RL decoder is derived from mpeg1_decode_block_intra;
+ Escaped level and run values a decoded differently */
+ i = 0;
+ {
+ OPEN_READER(re, &s->gb);
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+
+ if (level == 127) {
+ break;
+ } else if (level != 0) {
+ i += run;
+ if (i > 63) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ j = scantable[i];
+ level = (level*quant_matrix[j]) >> 4;
+ level = (level-1)|1;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 10); SKIP_BITS(re, &s->gb, 10);
+
+ UPDATE_CACHE(re, &s->gb);
+ run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6);
+
+ i += run;
+ if (i > 63) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ j = scantable[i];
+ if (level < 0) {
+ level = -level;
+ level = (level*quant_matrix[j]) >> 4;
+ level = (level-1)|1;
+ level = -level;
+ } else {
+ level = (level*quant_matrix[j]) >> 4;
+ level = (level-1)|1;
+ }
+ }
+
+ block[j] = level;
+ }
+ CLOSE_READER(re, &s->gb);
+ }
+ return 0;
+}
+
+static int decode_motion(GetBitContext *gb)
+{
+ int value = 0;
+ if (get_bits1(gb)) {
+ if (get_bits1(gb))
+ value = -17;
+ value += get_bits(gb, 4) + 1;
+ }
+ return value;
+}
+
+static int decode_mb(MadContext *s, AVFrame *frame, int inter)
+{
+ int mv_map = 0;
+ int av_uninit(mv_x), av_uninit(mv_y);
+ int j;
+
+ if (inter) {
+ int v = decode210(&s->gb);
+ if (v < 2) {
+ mv_map = v ? get_bits(&s->gb, 6) : 63;
+ mv_x = decode_motion(&s->gb);
+ mv_y = decode_motion(&s->gb);
+ }
+ }
+
+ for (j=0; j<6; j++) {
+ if (mv_map & (1<<j)) { // mv_x and mv_y are guarded by mv_map
+ int add = 2*decode_motion(&s->gb);
+ if (s->last_frame->data[0])
+ comp_block(s, frame, s->mb_x, s->mb_y, j, mv_x, mv_y, add);
+ } else {
+ s->bdsp.clear_block(s->block);
+ if(decode_block_intra(s, s->block) < 0)
+ return -1;
+ idct_put(s, frame, s->block, s->mb_x, s->mb_y, j);
+ }
+ }
+ return 0;
+}
+
+static void calc_quant_matrix(MadContext *s, int qscale)
+{
+ int i;
+
+ s->quant_matrix[0] = (ff_inv_aanscales[0]*ff_mpeg1_default_intra_matrix[0]) >> 11;
+ for (i=1; i<64; i++)
+ s->quant_matrix[i] = (ff_inv_aanscales[i]*ff_mpeg1_default_intra_matrix[i]*qscale + 32) >> 10;
+}
+
+static int decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ MadContext *s = avctx->priv_data;
+ AVFrame *frame = data;
+ GetByteContext gb;
+ int width, height;
+ int chunk_type;
+ int inter, ret;
+
+ bytestream2_init(&gb, buf, buf_size);
+
+ chunk_type = bytestream2_get_le32(&gb);
+ inter = (chunk_type == MADm_TAG || chunk_type == MADe_TAG);
+ bytestream2_skip(&gb, 10);
+
+ av_reduce(&avctx->framerate.den, &avctx->framerate.num,
+ bytestream2_get_le16(&gb), 1000, 1<<30);
+
+ width = bytestream2_get_le16(&gb);
+ height = bytestream2_get_le16(&gb);
+ bytestream2_skip(&gb, 1);
+ calc_quant_matrix(s, bytestream2_get_byte(&gb));
+ bytestream2_skip(&gb, 2);
+
+ if (bytestream2_get_bytes_left(&gb) < 2) {
+ av_log(avctx, AV_LOG_ERROR, "Input data too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (width < 16 || height < 16) {
+ av_log(avctx, AV_LOG_ERROR, "Dimensions too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (avctx->width != width || avctx->height != height) {
+ av_frame_unref(s->last_frame);
+ if((width * (int64_t)height)/2048*7 > bytestream2_get_bytes_left(&gb))
+ return AVERROR_INVALIDDATA;
+ if ((ret = ff_set_dimensions(avctx, width, height)) < 0)
+ return ret;
+ }
+
+ if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
+ return ret;
+
+ if (inter && !s->last_frame->data[0]) {
+ av_log(avctx, AV_LOG_WARNING, "Missing reference frame.\n");
+ ret = ff_get_buffer(avctx, s->last_frame, AV_GET_BUFFER_FLAG_REF);
+ if (ret < 0)
+ return ret;
+ memset(s->last_frame->data[0], 0, s->last_frame->height *
+ s->last_frame->linesize[0]);
+ memset(s->last_frame->data[1], 0x80, s->last_frame->height / 2 *
+ s->last_frame->linesize[1]);
+ memset(s->last_frame->data[2], 0x80, s->last_frame->height / 2 *
+ s->last_frame->linesize[2]);
+ }
+
+ av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size,
+ bytestream2_get_bytes_left(&gb));
+ if (!s->bitstream_buf)
+ return AVERROR(ENOMEM);
+ s->bbdsp.bswap16_buf(s->bitstream_buf, (const uint16_t *)(buf + bytestream2_tell(&gb)),
+ bytestream2_get_bytes_left(&gb) / 2);
+ memset((uint8_t*)s->bitstream_buf + bytestream2_get_bytes_left(&gb), 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ init_get_bits(&s->gb, s->bitstream_buf, 8*(bytestream2_get_bytes_left(&gb)));
+
+ for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++)
+ for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++)
+ if(decode_mb(s, frame, inter) < 0)
+ return AVERROR_INVALIDDATA;
+
+ *got_frame = 1;
+
+ if (chunk_type != MADe_TAG) {
+ av_frame_unref(s->last_frame);
+ if ((ret = av_frame_ref(s->last_frame, frame)) < 0)
+ return ret;
+ }
+
+ return buf_size;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ MadContext *t = avctx->priv_data;
+ av_frame_free(&t->last_frame);
+ av_freep(&t->bitstream_buf);
+ return 0;
+}
+
+AVCodec ff_eamad_decoder = {
+ .name = "eamad",
+ .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Madcow Video"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MAD,
+ .priv_data_size = sizeof(MadContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/eatgq.c b/ffmpeg-2-8-12/libavcodec/eatgq.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/eatgq.c
rename to ffmpeg-2-8-12/libavcodec/eatgq.c
diff --git a/ffmpeg-2-8-11/libavcodec/eatgv.c b/ffmpeg-2-8-12/libavcodec/eatgv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/eatgv.c
rename to ffmpeg-2-8-12/libavcodec/eatgv.c
diff --git a/ffmpeg-2-8-12/libavcodec/eatqi.c b/ffmpeg-2-8-12/libavcodec/eatqi.c
new file mode 100644
index 0000000..75f914c
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/eatqi.c
@@ -0,0 +1,166 @@
+/*
+ * Electronic Arts TQI Video Decoder
+ * Copyright (c) 2007-2009 Peter Ross <pross at 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Electronic Arts TQI Video Decoder
+ * @author Peter Ross <pross at xvid.org>
+ * @see http://wiki.multimedia.cx/index.php?title=Electronic_Arts_TQI
+ */
+
+#include "avcodec.h"
+#include "blockdsp.h"
+#include "bswapdsp.h"
+#include "get_bits.h"
+#include "aandcttab.h"
+#include "eaidct.h"
+#include "idctdsp.h"
+#include "internal.h"
+#include "mpeg12.h"
+#include "mpegvideo.h"
+
+typedef struct TqiContext {
+ MpegEncContext s;
+ BswapDSPContext bsdsp;
+ void *bitstream_buf;
+ unsigned int bitstream_buf_size;
+ DECLARE_ALIGNED(16, int16_t, block)[6][64];
+} TqiContext;
+
+static av_cold int tqi_decode_init(AVCodecContext *avctx)
+{
+ TqiContext *t = avctx->priv_data;
+ MpegEncContext *s = &t->s;
+ s->avctx = avctx;
+ ff_blockdsp_init(&s->bdsp, avctx);
+ ff_bswapdsp_init(&t->bsdsp);
+ ff_idctdsp_init(&s->idsp, avctx);
+ ff_init_scantable_permutation(s->idsp.idct_permutation, FF_IDCT_PERM_NONE);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
+ s->qscale = 1;
+ avctx->framerate = (AVRational){ 15, 1 };
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+ ff_mpeg12_init_vlcs();
+ return 0;
+}
+
+static int tqi_decode_mb(MpegEncContext *s, int16_t (*block)[64])
+{
+ int n;
+ s->bdsp.clear_blocks(block[0]);
+ for (n=0; n<6; n++)
+ if (ff_mpeg1_decode_block_intra(s, block[n], n) < 0)
+ return -1;
+
+ return 0;
+}
+
+static inline void tqi_idct_put(TqiContext *t, AVFrame *frame, int16_t (*block)[64])
+{
+ MpegEncContext *s = &t->s;
+ int linesize = frame->linesize[0];
+ uint8_t *dest_y = frame->data[0] + (s->mb_y * 16* linesize ) + s->mb_x * 16;
+ uint8_t *dest_cb = frame->data[1] + (s->mb_y * 8 * frame->linesize[1]) + s->mb_x * 8;
+ uint8_t *dest_cr = frame->data[2] + (s->mb_y * 8 * frame->linesize[2]) + s->mb_x * 8;
+
+ ff_ea_idct_put_c(dest_y , linesize, block[0]);
+ ff_ea_idct_put_c(dest_y + 8, linesize, block[1]);
+ ff_ea_idct_put_c(dest_y + 8*linesize , linesize, block[2]);
+ ff_ea_idct_put_c(dest_y + 8*linesize + 8, linesize, block[3]);
+ if(!(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
+ ff_ea_idct_put_c(dest_cb, frame->linesize[1], block[4]);
+ ff_ea_idct_put_c(dest_cr, frame->linesize[2], block[5]);
+ }
+}
+
+static void tqi_calculate_qtable(MpegEncContext *s, int quant)
+{
+ const int64_t qscale = (215 - 2*quant)*5;
+ int i;
+ s->intra_matrix[0] = (ff_inv_aanscales[0]*ff_mpeg1_default_intra_matrix[0])>>11;
+ for(i=1; i<64; i++)
+ s->intra_matrix[i] = (ff_inv_aanscales[i]*ff_mpeg1_default_intra_matrix[i]*qscale + 32)>>14;
+}
+
+static int tqi_decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ const uint8_t *buf_end = buf+buf_size;
+ TqiContext *t = avctx->priv_data;
+ MpegEncContext *s = &t->s;
+ AVFrame *frame = data;
+ int ret;
+
+ s->width = AV_RL16(&buf[0]);
+ s->height = AV_RL16(&buf[2]);
+ tqi_calculate_qtable(s, buf[4]);
+ buf += 8;
+
+ ret = ff_set_dimensions(s->avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
+
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+
+ av_fast_padded_malloc(&t->bitstream_buf, &t->bitstream_buf_size,
+ buf_end - buf);
+ if (!t->bitstream_buf)
+ return AVERROR(ENOMEM);
+ t->bsdsp.bswap_buf(t->bitstream_buf, (const uint32_t *) buf,
+ (buf_end - buf) / 4);
+ init_get_bits(&s->gb, t->bitstream_buf, 8*(buf_end-buf));
+
+ s->last_dc[0] = s->last_dc[1] = s->last_dc[2] = 0;
+ for (s->mb_y=0; s->mb_y<(avctx->height+15)/16; s->mb_y++)
+ for (s->mb_x=0; s->mb_x<(avctx->width+15)/16; s->mb_x++)
+ {
+ if (tqi_decode_mb(s, t->block) < 0)
+ goto end;
+ tqi_idct_put(t, frame, t->block);
+ }
+ end:
+
+ *got_frame = 1;
+ return buf_size;
+}
+
+static av_cold int tqi_decode_end(AVCodecContext *avctx)
+{
+ TqiContext *t = avctx->priv_data;
+ av_freep(&t->bitstream_buf);
+ return 0;
+}
+
+AVCodec ff_eatqi_decoder = {
+ .name = "eatqi",
+ .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts TQI Video"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_TQI,
+ .priv_data_size = sizeof(TqiContext),
+ .init = tqi_decode_init,
+ .close = tqi_decode_end,
+ .decode = tqi_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/elbg.c b/ffmpeg-2-8-12/libavcodec/elbg.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/elbg.c
rename to ffmpeg-2-8-12/libavcodec/elbg.c
diff --git a/ffmpeg-2-8-11/libavcodec/elbg.h b/ffmpeg-2-8-12/libavcodec/elbg.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/elbg.h
rename to ffmpeg-2-8-12/libavcodec/elbg.h
diff --git a/ffmpeg-2-8-11/libavcodec/elsdec.c b/ffmpeg-2-8-12/libavcodec/elsdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/elsdec.c
rename to ffmpeg-2-8-12/libavcodec/elsdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/elsdec.h b/ffmpeg-2-8-12/libavcodec/elsdec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/elsdec.h
rename to ffmpeg-2-8-12/libavcodec/elsdec.h
diff --git a/ffmpeg-2-8-11/libavcodec/error_resilience.c b/ffmpeg-2-8-12/libavcodec/error_resilience.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/error_resilience.c
rename to ffmpeg-2-8-12/libavcodec/error_resilience.c
diff --git a/ffmpeg-2-8-11/libavcodec/error_resilience.h b/ffmpeg-2-8-12/libavcodec/error_resilience.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/error_resilience.h
rename to ffmpeg-2-8-12/libavcodec/error_resilience.h
diff --git a/ffmpeg-2-8-11/libavcodec/escape124.c b/ffmpeg-2-8-12/libavcodec/escape124.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/escape124.c
rename to ffmpeg-2-8-12/libavcodec/escape124.c
diff --git a/ffmpeg-2-8-11/libavcodec/escape130.c b/ffmpeg-2-8-12/libavcodec/escape130.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/escape130.c
rename to ffmpeg-2-8-12/libavcodec/escape130.c
diff --git a/ffmpeg-2-8-11/libavcodec/evrcdata.h b/ffmpeg-2-8-12/libavcodec/evrcdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/evrcdata.h
rename to ffmpeg-2-8-12/libavcodec/evrcdata.h
diff --git a/ffmpeg-2-8-11/libavcodec/evrcdec.c b/ffmpeg-2-8-12/libavcodec/evrcdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/evrcdec.c
rename to ffmpeg-2-8-12/libavcodec/evrcdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/exif.c b/ffmpeg-2-8-12/libavcodec/exif.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/exif.c
rename to ffmpeg-2-8-12/libavcodec/exif.c
diff --git a/ffmpeg-2-8-11/libavcodec/exif.h b/ffmpeg-2-8-12/libavcodec/exif.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/exif.h
rename to ffmpeg-2-8-12/libavcodec/exif.h
diff --git a/ffmpeg-2-8-12/libavcodec/exr.c b/ffmpeg-2-8-12/libavcodec/exr.c
new file mode 100644
index 0000000..4000068
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/exr.c
@@ -0,0 +1,1453 @@
+/*
+ * OpenEXR (.exr) image decoder
+ * Copyright (c) 2009 Jimmy Christensen
+ *
+ * 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 decoder
+ * @author Jimmy Christensen
+ *
+ * For more information on the OpenEXR format, visit:
+ * http://openexr.com/
+ *
+ * exr_flt2uint() and exr_halflt2uint() is credited to Reimar Döffinger.
+ * exr_half2float() is credited to Aaftab Munshi, Dan Ginsburg, Dave Shreiner.
+ */
+
+#include <float.h>
+#include <zlib.h>
+
+#include "libavutil/imgutils.h"
+#include "libavutil/intfloat.h"
+#include "libavutil/opt.h"
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "mathops.h"
+#include "thread.h"
+
+enum ExrCompr {
+ EXR_RAW,
+ EXR_RLE,
+ EXR_ZIP1,
+ EXR_ZIP16,
+ EXR_PIZ,
+ EXR_PXR24,
+ EXR_B44,
+ EXR_B44A,
+ EXR_UNKN,
+};
+
+enum ExrPixelType {
+ EXR_UINT,
+ EXR_HALF,
+ EXR_FLOAT,
+ EXR_UNKNOWN,
+};
+
+typedef struct EXRChannel {
+ int xsub, ysub;
+ enum ExrPixelType pixel_type;
+} EXRChannel;
+
+typedef struct EXRThreadData {
+ uint8_t *uncompressed_data;
+ int uncompressed_size;
+
+ uint8_t *tmp;
+ int tmp_size;
+
+ uint8_t *bitmap;
+ uint16_t *lut;
+} EXRThreadData;
+
+typedef struct EXRContext {
+ AVClass *class;
+ AVFrame *picture;
+ AVCodecContext *avctx;
+
+ enum ExrCompr compression;
+ enum ExrPixelType pixel_type;
+ int channel_offsets[4]; // 0 = red, 1 = green, 2 = blue and 3 = alpha
+ const AVPixFmtDescriptor *desc;
+
+ int w, h;
+ uint32_t xmax, xmin;
+ uint32_t ymax, ymin;
+ uint32_t xdelta, ydelta;
+ int ysize;
+
+ uint64_t scan_line_size;
+ int scan_lines_per_block;
+
+ GetByteContext gb;
+ const uint8_t *buf;
+ int buf_size;
+
+ EXRChannel *channels;
+ int nb_channels;
+
+ EXRThreadData *thread_data;
+
+ const char *layer;
+
+ float gamma;
+ uint16_t gamma_table[65536];
+} 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;
+}
+
+
+/**
+ * Convert from 32-bit float as uint32_t to uint16_t.
+ *
+ * @param v 32-bit float
+ *
+ * @return normalized 16-bit unsigned int
+ */
+static inline uint16_t exr_flt2uint(int32_t v)
+{
+ int32_t exp = v >> 23;
+ // "HACK": negative values result in exp< 0, so clipping them to 0
+ // is also handled by this condition, avoids explicit check for sign bit.
+ if (exp <= 127 + 7 - 24) // we would shift out all bits anyway
+ return 0;
+ if (exp >= 127)
+ return 0xffff;
+ v &= 0x007fffff;
+ return (v + (1 << 23)) >> (127 + 7 - exp);
+}
+
+/**
+ * Convert from 16-bit float as uint16_t to uint16_t.
+ *
+ * @param v 16-bit float
+ *
+ * @return normalized 16-bit unsigned int
+ */
+static inline uint16_t exr_halflt2uint(uint16_t v)
+{
+ unsigned exp = 14 - (v >> 10);
+ if (exp >= 14) {
+ if (exp == 14)
+ return (v >> 9) & 1;
+ else
+ return (v & 0x8000) ? 0 : 0xffff;
+ }
+ v <<= 6;
+ return (v + (1 << 16)) >> (exp + 1);
+}
+
+static void predictor(uint8_t *src, int size)
+{
+ uint8_t *t = src + 1;
+ uint8_t *stop = src + size;
+
+ while (t < stop) {
+ int d = (int) t[-1] + (int) t[0] - 128;
+ t[0] = d;
+ ++t;
+ }
+}
+
+static void reorder_pixels(uint8_t *src, uint8_t *dst, int size)
+{
+ const int8_t *t1 = src;
+ const int8_t *t2 = src + (size + 1) / 2;
+ int8_t *s = dst;
+ int8_t *stop = s + size;
+
+ while (1) {
+ if (s < stop)
+ *(s++) = *(t1++);
+ else
+ break;
+
+ if (s < stop)
+ *(s++) = *(t2++);
+ else
+ break;
+ }
+}
+
+static int zip_uncompress(const uint8_t *src, int compressed_size,
+ int uncompressed_size, EXRThreadData *td)
+{
+ unsigned long dest_len = uncompressed_size;
+
+ if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK ||
+ dest_len != uncompressed_size)
+ return AVERROR_INVALIDDATA;
+
+ predictor(td->tmp, uncompressed_size);
+ reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size);
+
+ return 0;
+}
+
+static int rle_uncompress(const uint8_t *src, int compressed_size,
+ int uncompressed_size, EXRThreadData *td)
+{
+ uint8_t *d = td->tmp;
+ const int8_t *s = src;
+ int ssize = compressed_size;
+ int dsize = uncompressed_size;
+ uint8_t *dend = d + dsize;
+ int count;
+
+ while (ssize > 0) {
+ count = *s++;
+
+ if (count < 0) {
+ count = -count;
+
+ if ((dsize -= count) < 0 ||
+ (ssize -= count + 1) < 0)
+ return AVERROR_INVALIDDATA;
+
+ while (count--)
+ *d++ = *s++;
+ } else {
+ count++;
+
+ if ((dsize -= count) < 0 ||
+ (ssize -= 2) < 0)
+ return AVERROR_INVALIDDATA;
+
+ while (count--)
+ *d++ = *s;
+
+ s++;
+ }
+ }
+
+ if (dend != d)
+ return AVERROR_INVALIDDATA;
+
+ predictor(td->tmp, uncompressed_size);
+ reorder_pixels(td->tmp, td->uncompressed_data, uncompressed_size);
+
+ return 0;
+}
+
+#define USHORT_RANGE (1 << 16)
+#define BITMAP_SIZE (1 << 13)
+
+static uint16_t reverse_lut(const uint8_t *bitmap, uint16_t *lut)
+{
+ int i, k = 0;
+
+ for (i = 0; i < USHORT_RANGE; i++)
+ if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7))))
+ lut[k++] = i;
+
+ i = k - 1;
+
+ memset(lut + k, 0, (USHORT_RANGE - k) * 2);
+
+ return i;
+}
+
+static void apply_lut(const uint16_t *lut, uint16_t *dst, int dsize)
+{
+ int i;
+
+ for (i = 0; i < dsize; ++i)
+ dst[i] = lut[dst[i]];
+}
+
+#define HUF_ENCBITS 16 // literal (value) bit length
+#define HUF_DECBITS 14 // decoding bit size (>= 8)
+
+#define HUF_ENCSIZE ((1 << HUF_ENCBITS) + 1) // encoding table size
+#define HUF_DECSIZE (1 << HUF_DECBITS) // decoding table size
+#define HUF_DECMASK (HUF_DECSIZE - 1)
+
+typedef struct HufDec {
+ int len;
+ int lit;
+ int *p;
+} HufDec;
+
+static void huf_canonical_code_table(uint64_t *hcode)
+{
+ uint64_t c, n[59] = { 0 };
+ int i;
+
+ for (i = 0; i < HUF_ENCSIZE; ++i)
+ n[hcode[i]] += 1;
+
+ c = 0;
+ for (i = 58; i > 0; --i) {
+ uint64_t nc = ((c + n[i]) >> 1);
+ n[i] = c;
+ c = nc;
+ }
+
+ for (i = 0; i < HUF_ENCSIZE; ++i) {
+ int l = hcode[i];
+
+ if (l > 0)
+ hcode[i] = l | (n[l]++ << 6);
+ }
+}
+
+#define SHORT_ZEROCODE_RUN 59
+#define LONG_ZEROCODE_RUN 63
+#define SHORTEST_LONG_RUN (2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN)
+#define LONGEST_LONG_RUN (255 + SHORTEST_LONG_RUN)
+
+static int huf_unpack_enc_table(GetByteContext *gb,
+ int32_t im, int32_t iM, uint64_t *hcode)
+{
+ GetBitContext gbit;
+ int ret = init_get_bits8(&gbit, gb->buffer, bytestream2_get_bytes_left(gb));
+ if (ret < 0)
+ return ret;
+
+ for (; im <= iM; im++) {
+ uint64_t l = hcode[im] = get_bits(&gbit, 6);
+
+ if (l == LONG_ZEROCODE_RUN) {
+ int zerun = get_bits(&gbit, 8) + SHORTEST_LONG_RUN;
+
+ if (im + zerun > iM + 1)
+ return AVERROR_INVALIDDATA;
+
+ while (zerun--)
+ hcode[im++] = 0;
+
+ im--;
+ } else if (l >= SHORT_ZEROCODE_RUN) {
+ int zerun = l - SHORT_ZEROCODE_RUN + 2;
+
+ if (im + zerun > iM + 1)
+ return AVERROR_INVALIDDATA;
+
+ while (zerun--)
+ hcode[im++] = 0;
+
+ im--;
+ }
+ }
+
+ bytestream2_skip(gb, (get_bits_count(&gbit) + 7) / 8);
+ huf_canonical_code_table(hcode);
+
+ return 0;
+}
+
+static int huf_build_dec_table(const uint64_t *hcode, int im,
+ int iM, HufDec *hdecod)
+{
+ for (; im <= iM; im++) {
+ uint64_t c = hcode[im] >> 6;
+ int i, l = hcode[im] & 63;
+
+ if (c >> l)
+ return AVERROR_INVALIDDATA;
+
+ if (l > HUF_DECBITS) {
+ HufDec *pl = hdecod + (c >> (l - HUF_DECBITS));
+ if (pl->len)
+ return AVERROR_INVALIDDATA;
+
+ pl->lit++;
+
+ pl->p = av_realloc(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, 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;
+ get_code(pl.lit, rlc, c, lc, gb, out, oe, outb);
+ } else {
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if (out - outb != no)
+ return AVERROR_INVALIDDATA;
+ return 0;
+}
+
+static int huf_uncompress(GetByteContext *gb,
+ uint16_t *dst, int dst_size)
+{
+ int32_t src_size, im, iM;
+ uint32_t nBits;
+ uint64_t *freq;
+ HufDec *hdec;
+ int ret, i;
+
+ src_size = bytestream2_get_le32(gb);
+ im = bytestream2_get_le32(gb);
+ iM = bytestream2_get_le32(gb);
+ bytestream2_skip(gb, 4);
+ nBits = bytestream2_get_le32(gb);
+ if (im < 0 || im >= HUF_ENCSIZE ||
+ iM < 0 || iM >= HUF_ENCSIZE ||
+ src_size < 0)
+ return AVERROR_INVALIDDATA;
+
+ bytestream2_skip(gb, 4);
+
+ freq = av_mallocz_array(HUF_ENCSIZE, sizeof(*freq));
+ hdec = av_mallocz_array(HUF_DECSIZE, sizeof(*hdec));
+ if (!freq || !hdec) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ if ((ret = huf_unpack_enc_table(gb, im, iM, freq)) < 0)
+ goto fail;
+
+ if (nBits > 8 * bytestream2_get_bytes_left(gb)) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ if ((ret = huf_build_dec_table(freq, im, iM, hdec)) < 0)
+ goto fail;
+ ret = huf_decode(freq, hdec, gb, nBits, iM, dst_size, dst);
+
+fail:
+ for (i = 0; i < HUF_DECSIZE; i++)
+ if (hdec)
+ av_freep(&hdec[i].p);
+
+ av_free(freq);
+ av_free(hdec);
+
+ return ret;
+}
+
+static inline void wdec14(uint16_t l, uint16_t h, uint16_t *a, uint16_t *b)
+{
+ int16_t ls = l;
+ int16_t hs = h;
+ int hi = hs;
+ int ai = ls + (hi & 1) + (hi >> 1);
+ int16_t as = ai;
+ int16_t bs = ai - hi;
+
+ *a = as;
+ *b = bs;
+}
+
+#define NBITS 16
+#define A_OFFSET (1 << (NBITS - 1))
+#define MOD_MASK ((1 << NBITS) - 1)
+
+static inline void wdec16(uint16_t l, uint16_t h, uint16_t *a, uint16_t *b)
+{
+ int m = l;
+ int d = h;
+ int bb = (m - (d >> 1)) & MOD_MASK;
+ int aa = (d + bb - A_OFFSET) & MOD_MASK;
+ *b = bb;
+ *a = aa;
+}
+
+static void wav_decode(uint16_t *in, int nx, int ox,
+ int ny, int oy, uint16_t mx)
+{
+ int w14 = (mx < (1 << 14));
+ int n = (nx > ny) ? ny : nx;
+ int p = 1;
+ int p2;
+
+ while (p <= n)
+ p <<= 1;
+
+ p >>= 1;
+ p2 = p;
+ p >>= 1;
+
+ while (p >= 1) {
+ uint16_t *py = in;
+ uint16_t *ey = in + oy * (ny - p2);
+ uint16_t i00, i01, i10, i11;
+ int oy1 = oy * p;
+ int oy2 = oy * p2;
+ int ox1 = ox * p;
+ int ox2 = ox * p2;
+
+ for (; py <= ey; py += oy2) {
+ uint16_t *px = py;
+ uint16_t *ex = py + ox * (nx - p2);
+
+ for (; px <= ex; px += ox2) {
+ uint16_t *p01 = px + ox1;
+ uint16_t *p10 = px + oy1;
+ uint16_t *p11 = p10 + ox1;
+
+ if (w14) {
+ wdec14(*px, *p10, &i00, &i10);
+ wdec14(*p01, *p11, &i01, &i11);
+ wdec14(i00, i01, px, p01);
+ wdec14(i10, i11, p10, p11);
+ } else {
+ wdec16(*px, *p10, &i00, &i10);
+ wdec16(*p01, *p11, &i01, &i11);
+ wdec16(i00, i01, px, p01);
+ wdec16(i10, i11, p10, p11);
+ }
+ }
+
+ if (nx & p) {
+ uint16_t *p10 = px + oy1;
+
+ if (w14)
+ wdec14(*px, *p10, &i00, p10);
+ else
+ wdec16(*px, *p10, &i00, p10);
+
+ *px = i00;
+ }
+ }
+
+ if (ny & p) {
+ uint16_t *px = py;
+ uint16_t *ex = py + ox * (nx - p2);
+
+ for (; px <= ex; px += ox2) {
+ uint16_t *p01 = px + ox1;
+
+ if (w14)
+ wdec14(*px, *p01, &i00, p01);
+ else
+ wdec16(*px, *p01, &i00, p01);
+
+ *px = i00;
+ }
+ }
+
+ p2 = p;
+ p >>= 1;
+ }
+}
+
+static int piz_uncompress(EXRContext *s, const uint8_t *src, int ssize,
+ int dsize, EXRThreadData *td)
+{
+ GetByteContext gb;
+ uint16_t maxval, min_non_zero, max_non_zero;
+ uint16_t *ptr;
+ uint16_t *tmp = (uint16_t *)td->tmp;
+ uint8_t *out;
+ int ret, i, j;
+
+ if (!td->bitmap)
+ td->bitmap = av_malloc(BITMAP_SIZE);
+ if (!td->lut)
+ td->lut = av_malloc(1 << 17);
+ if (!td->bitmap || !td->lut) {
+ av_freep(&td->bitmap);
+ av_freep(&td->lut);
+ return AVERROR(ENOMEM);
+ }
+
+ bytestream2_init(&gb, src, ssize);
+ min_non_zero = bytestream2_get_le16(&gb);
+ max_non_zero = bytestream2_get_le16(&gb);
+
+ if (max_non_zero >= BITMAP_SIZE)
+ return AVERROR_INVALIDDATA;
+
+ memset(td->bitmap, 0, FFMIN(min_non_zero, BITMAP_SIZE));
+ if (min_non_zero <= max_non_zero)
+ bytestream2_get_buffer(&gb, td->bitmap + min_non_zero,
+ max_non_zero - min_non_zero + 1);
+ memset(td->bitmap + max_non_zero, 0, BITMAP_SIZE - max_non_zero);
+
+ maxval = reverse_lut(td->bitmap, td->lut);
+
+ ret = huf_uncompress(&gb, tmp, dsize / sizeof(uint16_t));
+ if (ret)
+ return ret;
+
+ ptr = tmp;
+ for (i = 0; i < s->nb_channels; i++) {
+ EXRChannel *channel = &s->channels[i];
+ int size = channel->pixel_type;
+
+ for (j = 0; j < size; j++)
+ wav_decode(ptr + j, s->xdelta, size, s->ysize,
+ s->xdelta * size, maxval);
+ ptr += s->xdelta * s->ysize * size;
+ }
+
+ apply_lut(td->lut, tmp, dsize / sizeof(uint16_t));
+
+ out = td->uncompressed_data;
+ for (i = 0; i < s->ysize; i++)
+ for (j = 0; j < s->nb_channels; j++) {
+ uint16_t *in = tmp + j * s->xdelta * s->ysize + i * s->xdelta;
+ memcpy(out, in, s->xdelta * 2);
+ out += s->xdelta * 2;
+ }
+
+ return 0;
+}
+
+static int pxr24_uncompress(EXRContext *s, const uint8_t *src,
+ int compressed_size, int uncompressed_size,
+ EXRThreadData *td)
+{
+ unsigned long dest_len = uncompressed_size;
+ const uint8_t *in = td->tmp;
+ uint8_t *out;
+ int c, i, j;
+
+ if (uncompress(td->tmp, &dest_len, src, compressed_size) != Z_OK ||
+ dest_len != uncompressed_size)
+ return AVERROR_INVALIDDATA;
+
+ out = td->uncompressed_data;
+ for (i = 0; i < s->ysize; i++)
+ for (c = 0; c < s->nb_channels; c++) {
+ EXRChannel *channel = &s->channels[c];
+ const uint8_t *ptr[4];
+ uint32_t pixel = 0;
+
+ switch (channel->pixel_type) {
+ case EXR_FLOAT:
+ ptr[0] = in;
+ ptr[1] = ptr[0] + s->xdelta;
+ ptr[2] = ptr[1] + s->xdelta;
+ in = ptr[2] + s->xdelta;
+
+ for (j = 0; j < s->xdelta; ++j) {
+ uint32_t diff = (*(ptr[0]++) << 24) |
+ (*(ptr[1]++) << 16) |
+ (*(ptr[2]++) << 8);
+ pixel += diff;
+ bytestream_put_le32(&out, pixel);
+ }
+ break;
+ case EXR_HALF:
+ ptr[0] = in;
+ ptr[1] = ptr[0] + s->xdelta;
+ in = ptr[1] + s->xdelta;
+ for (j = 0; j < s->xdelta; j++) {
+ uint32_t diff = (*(ptr[0]++) << 8) | *(ptr[1]++);
+
+ pixel += diff;
+ bytestream_put_le16(&out, pixel);
+ }
+ break;
+ default:
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ return 0;
+}
+
+static int decode_block(AVCodecContext *avctx, void *tdata,
+ int jobnr, int threadnr)
+{
+ EXRContext *s = avctx->priv_data;
+ AVFrame *const p = s->picture;
+ EXRThreadData *td = &s->thread_data[threadnr];
+ const uint8_t *channel_buffer[4] = { 0 };
+ const uint8_t *buf = s->buf;
+ uint64_t line_offset, uncompressed_size;
+ uint32_t xdelta = s->xdelta;
+ uint16_t *ptr_x;
+ uint8_t *ptr;
+ uint32_t data_size, line;
+ const uint8_t *src;
+ int axmax = (avctx->width - (s->xmax + 1)) * 2 * s->desc->nb_components;
+ int bxmin = s->xmin * 2 * s->desc->nb_components;
+ int i, x, buf_size = s->buf_size;
+ float one_gamma = 1.0f / s->gamma;
+ int ret;
+
+ line_offset = AV_RL64(s->gb.buffer + jobnr * 8);
+ // Check if the buffer has the required bytes needed from the offset
+ if (line_offset > buf_size - 8)
+ return AVERROR_INVALIDDATA;
+
+ src = buf + line_offset + 8;
+ line = AV_RL32(src - 8);
+ if (line < s->ymin || line > s->ymax)
+ return AVERROR_INVALIDDATA;
+
+ data_size = AV_RL32(src - 4);
+ if (data_size <= 0 || data_size > buf_size)
+ return AVERROR_INVALIDDATA;
+
+ s->ysize = FFMIN(s->scan_lines_per_block, s->ymax - line + 1);
+ uncompressed_size = s->scan_line_size * s->ysize;
+ if ((s->compression == EXR_RAW && (data_size != uncompressed_size ||
+ line_offset > buf_size - uncompressed_size)) ||
+ (s->compression != EXR_RAW && (data_size > uncompressed_size ||
+ line_offset > buf_size - data_size))) {
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (data_size < uncompressed_size) {
+ av_fast_padded_malloc(&td->uncompressed_data,
+ &td->uncompressed_size, uncompressed_size);
+ av_fast_padded_malloc(&td->tmp, &td->tmp_size, uncompressed_size);
+ if (!td->uncompressed_data || !td->tmp)
+ return AVERROR(ENOMEM);
+
+ ret = AVERROR_INVALIDDATA;
+ switch (s->compression) {
+ case EXR_ZIP1:
+ case EXR_ZIP16:
+ ret = zip_uncompress(src, data_size, uncompressed_size, td);
+ break;
+ case EXR_PIZ:
+ ret = piz_uncompress(s, src, data_size, uncompressed_size, td);
+ break;
+ case EXR_PXR24:
+ ret = pxr24_uncompress(s, src, data_size, uncompressed_size, td);
+ break;
+ case EXR_RLE:
+ ret = rle_uncompress(src, data_size, uncompressed_size, td);
+ }
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "decode_block() failed.\n");
+ return ret;
+ }
+ src = td->uncompressed_data;
+ }
+
+ channel_buffer[0] = src + xdelta * s->channel_offsets[0];
+ channel_buffer[1] = src + xdelta * s->channel_offsets[1];
+ channel_buffer[2] = src + xdelta * s->channel_offsets[2];
+ if (s->channel_offsets[3] >= 0)
+ channel_buffer[3] = src + xdelta * s->channel_offsets[3];
+
+ ptr = p->data[0] + line * p->linesize[0];
+ for (i = 0;
+ i < s->scan_lines_per_block && line + i <= s->ymax;
+ i++, ptr += p->linesize[0]) {
+ const uint8_t *r, *g, *b, *a;
+
+ r = channel_buffer[0];
+ g = channel_buffer[1];
+ b = channel_buffer[2];
+ if (channel_buffer[3])
+ a = channel_buffer[3];
+
+ ptr_x = (uint16_t *) ptr;
+
+ // Zero out the start if xmin is not 0
+ memset(ptr_x, 0, bxmin);
+ ptr_x += s->xmin * s->desc->nb_components;
+ if (s->pixel_type == EXR_FLOAT) {
+ // 32-bit
+ for (x = 0; x < xdelta; x++) {
+ union av_intfloat32 t;
+ t.i = bytestream_get_le32(&r);
+ if (t.f > 0.0f) /* avoid negative values */
+ t.f = powf(t.f, one_gamma);
+ *ptr_x++ = exr_flt2uint(t.i);
+
+ t.i = bytestream_get_le32(&g);
+ if (t.f > 0.0f)
+ t.f = powf(t.f, one_gamma);
+ *ptr_x++ = exr_flt2uint(t.i);
+
+ t.i = bytestream_get_le32(&b);
+ if (t.f > 0.0f)
+ t.f = powf(t.f, one_gamma);
+ *ptr_x++ = exr_flt2uint(t.i);
+ if (channel_buffer[3])
+ *ptr_x++ = exr_flt2uint(bytestream_get_le32(&a));
+ }
+ } else {
+ // 16-bit
+ for (x = 0; x < xdelta; x++) {
+ *ptr_x++ = s->gamma_table[bytestream_get_le16(&r)];
+ *ptr_x++ = s->gamma_table[bytestream_get_le16(&g)];
+ *ptr_x++ = s->gamma_table[bytestream_get_le16(&b)];
+ if (channel_buffer[3])
+ *ptr_x++ = exr_halflt2uint(bytestream_get_le16(&a));
+ }
+ }
+
+ // Zero out the end if xmax+1 is not w
+ memset(ptr_x, 0, axmax);
+
+ channel_buffer[0] += s->scan_line_size;
+ channel_buffer[1] += s->scan_line_size;
+ channel_buffer[2] += s->scan_line_size;
+ if (channel_buffer[3])
+ channel_buffer[3] += s->scan_line_size;
+ }
+
+ return 0;
+}
+
+/**
+ * Check if the variable name corresponds to its data type.
+ *
+ * @param s the EXRContext
+ * @param value_name name of the variable to check
+ * @param value_type type of the variable to check
+ * @param minimum_length minimum length of the variable data
+ *
+ * @return bytes to read containing variable data
+ * -1 if variable is not found
+ * 0 if buffer ended prematurely
+ */
+static int check_header_variable(EXRContext *s,
+ const char *value_name,
+ const char *value_type,
+ unsigned int minimum_length)
+{
+ int var_size = -1;
+
+ if (bytestream2_get_bytes_left(&s->gb) >= minimum_length &&
+ !strcmp(s->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);
+ // don't go read past boundaries
+ if (var_size > bytestream2_get_bytes_left(&s->gb))
+ var_size = 0;
+ } else {
+ // value_type not found, reset the buffer
+ s->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);
+ }
+ }
+
+ return var_size;
+}
+
+static int decode_header(EXRContext *s)
+{
+ int current_channel_offset = 0;
+ int magic_number, version, flags, i;
+
+ s->xmin = ~0;
+ s->xmax = ~0;
+ s->ymin = ~0;
+ s->ymax = ~0;
+ s->xdelta = ~0;
+ s->ydelta = ~0;
+ s->channel_offsets[0] = -1;
+ s->channel_offsets[1] = -1;
+ s->channel_offsets[2] = -1;
+ s->channel_offsets[3] = -1;
+ s->pixel_type = EXR_UNKNOWN;
+ s->compression = EXR_UNKN;
+ s->nb_channels = 0;
+ s->w = 0;
+ s->h = 0;
+
+ if (bytestream2_get_bytes_left(&s->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);
+ if (magic_number != 20000630) {
+ /* As per documentation of OpenEXR, it is supposed to be
+ * int 20000630 little-endian */
+ av_log(s->avctx, AV_LOG_ERROR, "Wrong magic number %d.\n", magic_number);
+ return AVERROR_INVALIDDATA;
+ }
+
+ version = bytestream2_get_byte(&s->gb);
+ if (version != 2) {
+ avpriv_report_missing_feature(s->avctx, "Version %d", version);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ flags = bytestream2_get_le24(&s->gb);
+ if (flags & 0x02) {
+ avpriv_report_missing_feature(s->avctx, "Tile support");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ // Parse the header
+ while (bytestream2_get_bytes_left(&s->gb) > 0 && *s->gb.buffer) {
+ int var_size;
+ if ((var_size = check_header_variable(s, "channels",
+ "chlist", 38)) >= 0) {
+ GetByteContext ch_gb;
+ if (!var_size)
+ return AVERROR_INVALIDDATA;
+
+ bytestream2_init(&ch_gb, s->gb.buffer, var_size);
+
+ while (bytestream2_get_bytes_left(&ch_gb) >= 19) {
+ EXRChannel *channel;
+ enum ExrPixelType current_pixel_type;
+ int channel_index = -1;
+ int xsub, ysub;
+
+ if (strcmp(s->layer, "") != 0) {
+ if (strncmp(ch_gb.buffer, s->layer, strlen(s->layer)) == 0) {
+ ch_gb.buffer += strlen(s->layer);
+ if (*ch_gb.buffer == '.')
+ ch_gb.buffer++; /* skip dot if not given */
+ av_log(s->avctx, AV_LOG_INFO,
+ "Layer %s.%s matched.\n", s->layer, ch_gb.buffer);
+ }
+ }
+
+ if (!strcmp(ch_gb.buffer, "R") ||
+ !strcmp(ch_gb.buffer, "X") ||
+ !strcmp(ch_gb.buffer, "U"))
+ channel_index = 0;
+ else if (!strcmp(ch_gb.buffer, "G") ||
+ !strcmp(ch_gb.buffer, "Y") ||
+ !strcmp(ch_gb.buffer, "V"))
+ channel_index = 1;
+ else if (!strcmp(ch_gb.buffer, "B") ||
+ !strcmp(ch_gb.buffer, "Z") ||
+ !strcmp(ch_gb.buffer, "W"))
+ channel_index = 2;
+ else if (!strcmp(ch_gb.buffer, "A"))
+ channel_index = 3;
+ else
+ av_log(s->avctx, AV_LOG_WARNING,
+ "Unsupported channel %.256s.\n", ch_gb.buffer);
+
+ /* skip until you get a 0 */
+ while (bytestream2_get_bytes_left(&ch_gb) > 0 &&
+ bytestream2_get_byte(&ch_gb))
+ continue;
+
+ if (bytestream2_get_bytes_left(&ch_gb) < 4) {
+ av_log(s->avctx, AV_LOG_ERROR, "Incomplete header.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ current_pixel_type = bytestream2_get_le32(&ch_gb);
+ if (current_pixel_type >= EXR_UNKNOWN) {
+ avpriv_report_missing_feature(s->avctx,
+ "Pixel type %d.\n",
+ current_pixel_type);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ bytestream2_skip(&ch_gb, 4);
+ xsub = bytestream2_get_le32(&ch_gb);
+ ysub = bytestream2_get_le32(&ch_gb);
+ if (xsub != 1 || ysub != 1) {
+ avpriv_report_missing_feature(s->avctx,
+ "Subsampling %dx%d",
+ xsub, ysub);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if (channel_index >= 0) {
+ if (s->pixel_type != EXR_UNKNOWN &&
+ s->pixel_type != current_pixel_type) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "RGB channels not of the same depth.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ s->pixel_type = current_pixel_type;
+ s->channel_offsets[channel_index] = current_channel_offset;
+ }
+
+ s->channels = av_realloc(s->channels,
+ ++s->nb_channels * sizeof(EXRChannel));
+ if (!s->channels)
+ return AVERROR(ENOMEM);
+ channel = &s->channels[s->nb_channels - 1];
+ channel->pixel_type = current_pixel_type;
+ channel->xsub = xsub;
+ channel->ysub = ysub;
+
+ current_channel_offset += 1 << current_pixel_type;
+ }
+
+ /* Check if all channels are set with an offset or if the channels
+ * are causing an overflow */
+ if (FFMIN3(s->channel_offsets[0],
+ s->channel_offsets[1],
+ s->channel_offsets[2]) < 0) {
+ if (s->channel_offsets[0] < 0)
+ av_log(s->avctx, AV_LOG_ERROR, "Missing red channel.\n");
+ if (s->channel_offsets[1] < 0)
+ av_log(s->avctx, AV_LOG_ERROR, "Missing green channel.\n");
+ if (s->channel_offsets[2] < 0)
+ av_log(s->avctx, AV_LOG_ERROR, "Missing blue channel.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ // skip one last byte and update main gb
+ s->gb.buffer = ch_gb.buffer + 1;
+ continue;
+ } else if ((var_size = check_header_variable(s, "dataWindow", "box2i",
+ 31)) >= 0) {
+ if (!var_size)
+ return AVERROR_INVALIDDATA;
+
+ s->xmin = bytestream2_get_le32(&s->gb);
+ s->ymin = bytestream2_get_le32(&s->gb);
+ s->xmax = bytestream2_get_le32(&s->gb);
+ s->ymax = bytestream2_get_le32(&s->gb);
+ s->xdelta = (s->xmax - s->xmin) + 1;
+ s->ydelta = (s->ymax - s->ymin) + 1;
+
+ continue;
+ } else if ((var_size = check_header_variable(s, "displayWindow",
+ "box2i", 34)) >= 0) {
+ if (!var_size)
+ return AVERROR_INVALIDDATA;
+
+ bytestream2_skip(&s->gb, 8);
+ s->w = bytestream2_get_le32(&s->gb) + 1;
+ s->h = bytestream2_get_le32(&s->gb) + 1;
+
+ continue;
+ } else if ((var_size = check_header_variable(s, "lineOrder",
+ "lineOrder", 25)) >= 0) {
+ int line_order;
+ if (!var_size)
+ return AVERROR_INVALIDDATA;
+
+ line_order = bytestream2_get_byte(&s->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");
+ return AVERROR_INVALIDDATA;
+ }
+
+ continue;
+ } else if ((var_size = check_header_variable(s, "pixelAspectRatio",
+ "float", 31)) >= 0) {
+ if (!var_size)
+ return AVERROR_INVALIDDATA;
+
+ ff_set_sar(s->avctx,
+ av_d2q(av_int2float(bytestream2_get_le32(&s->gb)), 255));
+
+ continue;
+ } else if ((var_size = check_header_variable(s, "compression",
+ "compression", 29)) >= 0) {
+ if (!var_size)
+ return AVERROR_INVALIDDATA;
+
+ if (s->compression == EXR_UNKN)
+ s->compression = bytestream2_get_byte(&s->gb);
+ else
+ av_log(s->avctx, AV_LOG_WARNING,
+ "Found more than one compression attribute.\n");
+
+ continue;
+ }
+
+ // Check if there are enough bytes for a header
+ if (bytestream2_get_bytes_left(&s->gb) <= 9) {
+ av_log(s->avctx, AV_LOG_ERROR, "Incomplete header\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ // Process unknown variables
+ for (i = 0; i < 2; i++) // value_name and value_type
+ while (bytestream2_get_byte(&s->gb) != 0);
+
+ // Skip variable length
+ bytestream2_skip(&s->gb, bytestream2_get_le32(&s->gb));
+ }
+
+ if (s->compression == EXR_UNKN) {
+ av_log(s->avctx, AV_LOG_ERROR, "Missing compression attribute.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ s->scan_line_size = s->xdelta * current_channel_offset;
+
+ if (bytestream2_get_bytes_left(&s->gb) <= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Incomplete frame.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ // aaand we are done
+ bytestream2_skip(&s->gb, 1);
+ return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame, AVPacket *avpkt)
+{
+ EXRContext *s = avctx->priv_data;
+ ThreadFrame frame = { .f = data };
+ AVFrame *picture = data;
+ uint8_t *ptr;
+
+ int y, ret;
+ int out_line_size;
+ int scan_line_blocks;
+
+ bytestream2_init(&s->gb, avpkt->data, avpkt->size);
+
+ if ((ret = decode_header(s)) < 0)
+ return ret;
+
+ switch (s->pixel_type) {
+ case EXR_FLOAT:
+ case EXR_HALF:
+ if (s->channel_offsets[3] >= 0)
+ avctx->pix_fmt = AV_PIX_FMT_RGBA64;
+ else
+ avctx->pix_fmt = AV_PIX_FMT_RGB48;
+ break;
+ case EXR_UINT:
+ avpriv_request_sample(avctx, "32-bit unsigned int");
+ return AVERROR_PATCHWELCOME;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Missing channel list.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ switch (s->compression) {
+ case EXR_RAW:
+ case EXR_RLE:
+ case EXR_ZIP1:
+ s->scan_lines_per_block = 1;
+ break;
+ case EXR_PXR24:
+ case EXR_ZIP16:
+ s->scan_lines_per_block = 16;
+ break;
+ case EXR_PIZ:
+ s->scan_lines_per_block = 32;
+ 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) {
+ av_log(avctx, AV_LOG_ERROR, "Wrong or missing size information.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if ((ret = ff_set_dimensions(avctx, s->w, s->h)) < 0)
+ return ret;
+
+ s->desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+ if (!s->desc)
+ return AVERROR_INVALIDDATA;
+ out_line_size = avctx->width * 2 * s->desc->nb_components;
+ scan_line_blocks = (s->ydelta + s->scan_lines_per_block - 1) /
+ s->scan_lines_per_block;
+
+ if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+ return ret;
+
+ if (bytestream2_get_bytes_left(&s->gb) < scan_line_blocks * 8)
+ return AVERROR_INVALIDDATA;
+
+ // save pointer we are going to use in decode_block
+ s->buf = avpkt->data;
+ s->buf_size = avpkt->size;
+ ptr = picture->data[0];
+
+ // Zero out the start if ymin is not 0
+ for (y = 0; y < s->ymin; y++) {
+ memset(ptr, 0, out_line_size);
+ ptr += picture->linesize[0];
+ }
+
+ s->picture = picture;
+ avctx->execute2(avctx, decode_block, s->thread_data, NULL, scan_line_blocks);
+
+ // Zero out the end if ymax+1 is not h
+ for (y = s->ymax + 1; y < avctx->height; y++) {
+ memset(ptr, 0, out_line_size);
+ ptr += picture->linesize[0];
+ }
+
+ picture->pict_type = AV_PICTURE_TYPE_I;
+ *got_frame = 1;
+
+ return avpkt->size;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ EXRContext *s = avctx->priv_data;
+ uint32_t i;
+ union av_intfloat32 t;
+ float one_gamma = 1.0f / s->gamma;
+
+ s->avctx = avctx;
+
+ if (one_gamma > 0.9999f && one_gamma < 1.0001f) {
+ for (i = 0; i < 65536; ++i)
+ s->gamma_table[i] = exr_halflt2uint(i);
+ } else {
+ for (i = 0; i < 65536; ++i) {
+ t = exr_half2float(i);
+ /* If negative value we reuse half value */
+ if (t.f <= 0.0f) {
+ s->gamma_table[i] = exr_halflt2uint(i);
+ } else {
+ t.f = powf(t.f, one_gamma);
+ s->gamma_table[i] = exr_flt2uint(t.i);
+ }
+ }
+ }
+
+ // allocate thread data, used for non EXR_RAW compreesion types
+ s->thread_data = av_mallocz_array(avctx->thread_count, sizeof(EXRThreadData));
+ if (!s->thread_data)
+ return AVERROR_INVALIDDATA;
+
+ return 0;
+}
+
+static int decode_init_thread_copy(AVCodecContext *avctx)
+{ EXRContext *s = avctx->priv_data;
+
+ // allocate thread data, used for non EXR_RAW compreesion types
+ s->thread_data = av_mallocz_array(avctx->thread_count, sizeof(EXRThreadData));
+ if (!s->thread_data)
+ return AVERROR_INVALIDDATA;
+
+ return 0;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ EXRContext *s = avctx->priv_data;
+ int i;
+ for (i = 0; i < avctx->thread_count; i++) {
+ EXRThreadData *td = &s->thread_data[i];
+ av_freep(&td->uncompressed_data);
+ av_freep(&td->tmp);
+ av_freep(&td->bitmap);
+ av_freep(&td->lut);
+ }
+
+ av_freep(&s->thread_data);
+ av_freep(&s->channels);
+
+ return 0;
+}
+
+#define OFFSET(x) offsetof(EXRContext, x)
+#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+ { "layer", "Set the decoding layer", OFFSET(layer),
+ AV_OPT_TYPE_STRING, { .str = "" }, 0, 0, VD },
+ { "gamma", "Set the float gamma value when decoding", OFFSET(gamma),
+ AV_OPT_TYPE_FLOAT, { .dbl = 1.0f }, 0.001, FLT_MAX, VD },
+ { NULL },
+};
+
+static const AVClass exr_class = {
+ .class_name = "EXR",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_exr_decoder = {
+ .name = "exr",
+ .long_name = NULL_IF_CONFIG_SMALL("OpenEXR image"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_EXR,
+ .priv_data_size = sizeof(EXRContext),
+ .init = decode_init,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_SLICE_THREADS,
+ .priv_class = &exr_class,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/faandct.c b/ffmpeg-2-8-12/libavcodec/faandct.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/faandct.c
rename to ffmpeg-2-8-12/libavcodec/faandct.c
diff --git a/ffmpeg-2-8-11/libavcodec/faandct.h b/ffmpeg-2-8-12/libavcodec/faandct.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/faandct.h
rename to ffmpeg-2-8-12/libavcodec/faandct.h
diff --git a/ffmpeg-2-8-11/libavcodec/faanidct.c b/ffmpeg-2-8-12/libavcodec/faanidct.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/faanidct.c
rename to ffmpeg-2-8-12/libavcodec/faanidct.c
diff --git a/ffmpeg-2-8-11/libavcodec/faanidct.h b/ffmpeg-2-8-12/libavcodec/faanidct.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/faanidct.h
rename to ffmpeg-2-8-12/libavcodec/faanidct.h
diff --git a/ffmpeg-2-8-11/libavcodec/faxcompr.c b/ffmpeg-2-8-12/libavcodec/faxcompr.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/faxcompr.c
rename to ffmpeg-2-8-12/libavcodec/faxcompr.c
diff --git a/ffmpeg-2-8-11/libavcodec/faxcompr.h b/ffmpeg-2-8-12/libavcodec/faxcompr.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/faxcompr.h
rename to ffmpeg-2-8-12/libavcodec/faxcompr.h
diff --git a/ffmpeg-2-8-11/libavcodec/fdctdsp.c b/ffmpeg-2-8-12/libavcodec/fdctdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fdctdsp.c
rename to ffmpeg-2-8-12/libavcodec/fdctdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/fdctdsp.h b/ffmpeg-2-8-12/libavcodec/fdctdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fdctdsp.h
rename to ffmpeg-2-8-12/libavcodec/fdctdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/fft-fixed-test.c b/ffmpeg-2-8-12/libavcodec/fft-fixed-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fft-fixed-test.c
rename to ffmpeg-2-8-12/libavcodec/fft-fixed-test.c
diff --git a/ffmpeg-2-8-11/libavcodec/fft-fixed32-test.c b/ffmpeg-2-8-12/libavcodec/fft-fixed32-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fft-fixed32-test.c
rename to ffmpeg-2-8-12/libavcodec/fft-fixed32-test.c
diff --git a/ffmpeg-2-8-11/libavcodec/fft-internal.h b/ffmpeg-2-8-12/libavcodec/fft-internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fft-internal.h
rename to ffmpeg-2-8-12/libavcodec/fft-internal.h
diff --git a/ffmpeg-2-8-11/libavcodec/fft-test.c b/ffmpeg-2-8-12/libavcodec/fft-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fft-test.c
rename to ffmpeg-2-8-12/libavcodec/fft-test.c
diff --git a/ffmpeg-2-8-11/libavcodec/fft.h b/ffmpeg-2-8-12/libavcodec/fft.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fft.h
rename to ffmpeg-2-8-12/libavcodec/fft.h
diff --git a/ffmpeg-2-8-11/libavcodec/fft_fixed.c b/ffmpeg-2-8-12/libavcodec/fft_fixed.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fft_fixed.c
rename to ffmpeg-2-8-12/libavcodec/fft_fixed.c
diff --git a/ffmpeg-2-8-11/libavcodec/fft_fixed_32.c b/ffmpeg-2-8-12/libavcodec/fft_fixed_32.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fft_fixed_32.c
rename to ffmpeg-2-8-12/libavcodec/fft_fixed_32.c
diff --git a/ffmpeg-2-8-11/libavcodec/fft_float.c b/ffmpeg-2-8-12/libavcodec/fft_float.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fft_float.c
rename to ffmpeg-2-8-12/libavcodec/fft_float.c
diff --git a/ffmpeg-2-8-11/libavcodec/fft_init_table.c b/ffmpeg-2-8-12/libavcodec/fft_init_table.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fft_init_table.c
rename to ffmpeg-2-8-12/libavcodec/fft_init_table.c
diff --git a/ffmpeg-2-8-11/libavcodec/fft_table.h b/ffmpeg-2-8-12/libavcodec/fft_table.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fft_table.h
rename to ffmpeg-2-8-12/libavcodec/fft_table.h
diff --git a/ffmpeg-2-8-11/libavcodec/fft_template.c b/ffmpeg-2-8-12/libavcodec/fft_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fft_template.c
rename to ffmpeg-2-8-12/libavcodec/fft_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/ffv1.c b/ffmpeg-2-8-12/libavcodec/ffv1.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ffv1.c
rename to ffmpeg-2-8-12/libavcodec/ffv1.c
diff --git a/ffmpeg-2-8-11/libavcodec/ffv1.h b/ffmpeg-2-8-12/libavcodec/ffv1.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ffv1.h
rename to ffmpeg-2-8-12/libavcodec/ffv1.h
diff --git a/ffmpeg-2-8-12/libavcodec/ffv1dec.c b/ffmpeg-2-8-12/libavcodec/ffv1dec.c
new file mode 100644
index 0000000..52a5686
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/ffv1dec.c
@@ -0,0 +1,1142 @@
+/*
+ * FFV1 decoder
+ *
+ * Copyright (c) 2003-2013 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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
+ * FF Video Codec 1 (a lossless codec) decoder
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/crc.h"
+#include "libavutil/opt.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/timer.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "get_bits.h"
+#include "rangecoder.h"
+#include "golomb.h"
+#include "mathops.h"
+#include "ffv1.h"
+
+static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state,
+ int is_signed)
+{
+ if (get_rac(c, state + 0))
+ return 0;
+ else {
+ int i, e;
+ unsigned a;
+ e = 0;
+ while (get_rac(c, state + 1 + FFMIN(e, 9))) { // 1..10
+ e++;
+ if (e > 31)
+ return AVERROR_INVALIDDATA;
+ }
+
+ a = 1;
+ for (i = e - 1; i >= 0; i--)
+ a += a + get_rac(c, state + 22 + FFMIN(i, 9)); // 22..31
+
+ e = -(is_signed && get_rac(c, state + 11 + FFMIN(e, 10))); // 11..21
+ return (a ^ e) - e;
+ }
+}
+
+static av_noinline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed)
+{
+ return get_symbol_inline(c, state, is_signed);
+}
+
+static inline int get_vlc_symbol(GetBitContext *gb, VlcState *const state,
+ int bits)
+{
+ int k, i, v, ret;
+
+ i = state->count;
+ k = 0;
+ while (i < state->error_sum) { // FIXME: optimize
+ k++;
+ i += i;
+ }
+
+ v = get_sr_golomb(gb, k, 12, bits);
+ ff_dlog(NULL, "v:%d bias:%d error:%d drift:%d count:%d k:%d",
+ v, state->bias, state->error_sum, state->drift, state->count, k);
+
+#if 0 // JPEG LS
+ if (k == 0 && 2 * state->drift <= -state->count)
+ v ^= (-1);
+#else
+ v ^= ((2 * state->drift + state->count) >> 31);
+#endif
+
+ ret = fold(v + state->bias, bits);
+
+ update_vlc_state(state, v);
+
+ return ret;
+}
+
+static av_always_inline void decode_line(FFV1Context *s, int w,
+ int16_t *sample[2],
+ int plane_index, int bits)
+{
+ PlaneContext *const p = &s->plane[plane_index];
+ RangeCoder *const c = &s->c;
+ int x;
+ int run_count = 0;
+ int run_mode = 0;
+ int run_index = s->run_index;
+
+ if (s->slice_coding_mode == 1) {
+ int i;
+ for (x = 0; x < w; x++) {
+ int v = 0;
+ for (i=0; i<bits; i++) {
+ uint8_t state = 128;
+ v += v + get_rac(c, &state);
+ }
+ sample[1][x] = v;
+ }
+ return;
+ }
+
+ for (x = 0; x < w; x++) {
+ int diff, context, sign;
+
+ context = get_context(p, sample[1] + x, sample[0] + x, sample[1] + x);
+ if (context < 0) {
+ context = -context;
+ sign = 1;
+ } else
+ sign = 0;
+
+ av_assert2(context < p->context_count);
+
+ if (s->ac) {
+ diff = get_symbol_inline(c, p->state[context], 1);
+ } else {
+ if (context == 0 && run_mode == 0)
+ run_mode = 1;
+
+ if (run_mode) {
+ if (run_count == 0 && run_mode == 1) {
+ if (get_bits1(&s->gb)) {
+ run_count = 1 << ff_log2_run[run_index];
+ if (x + run_count <= w)
+ run_index++;
+ } else {
+ if (ff_log2_run[run_index])
+ run_count = get_bits(&s->gb, ff_log2_run[run_index]);
+ else
+ run_count = 0;
+ if (run_index)
+ run_index--;
+ run_mode = 2;
+ }
+ }
+ run_count--;
+ if (run_count < 0) {
+ run_mode = 0;
+ run_count = 0;
+ diff = get_vlc_symbol(&s->gb, &p->vlc_state[context],
+ bits);
+ if (diff >= 0)
+ diff++;
+ } else
+ diff = 0;
+ } else
+ diff = get_vlc_symbol(&s->gb, &p->vlc_state[context], bits);
+
+ ff_dlog(s->avctx, "count:%d index:%d, mode:%d, x:%d pos:%d\n",
+ run_count, run_index, run_mode, x, get_bits_count(&s->gb));
+ }
+
+ if (sign)
+ diff = -diff;
+
+ sample[1][x] = av_mod_uintp2(predict(sample[1] + x, sample[0] + x) + diff, bits);
+ }
+ s->run_index = run_index;
+}
+
+static void decode_plane(FFV1Context *s, uint8_t *src,
+ int w, int h, int stride, int plane_index)
+{
+ int x, y;
+ int16_t *sample[2];
+ sample[0] = s->sample_buffer + 3;
+ sample[1] = s->sample_buffer + w + 6 + 3;
+
+ s->run_index = 0;
+
+ memset(s->sample_buffer, 0, 2 * (w + 6) * sizeof(*s->sample_buffer));
+
+ for (y = 0; y < h; y++) {
+ int16_t *temp = sample[0]; // FIXME: try a normal buffer
+
+ sample[0] = sample[1];
+ sample[1] = temp;
+
+ sample[1][-1] = sample[0][0];
+ sample[0][w] = sample[0][w - 1];
+
+// { START_TIMER
+ if (s->avctx->bits_per_raw_sample <= 8) {
+ decode_line(s, w, sample, plane_index, 8);
+ for (x = 0; x < w; x++)
+ src[x + stride * y] = sample[1][x];
+ } else {
+ decode_line(s, w, sample, plane_index, s->avctx->bits_per_raw_sample);
+ if (s->packed_at_lsb) {
+ for (x = 0; x < w; x++) {
+ ((uint16_t*)(src + stride*y))[x] = sample[1][x];
+ }
+ } else {
+ for (x = 0; x < w; x++) {
+ ((uint16_t*)(src + stride*y))[x] = sample[1][x] << (16 - s->avctx->bits_per_raw_sample);
+ }
+ }
+ }
+// STOP_TIMER("decode-line") }
+ }
+}
+
+static void decode_rgb_frame(FFV1Context *s, uint8_t *src[3], int w, int h, int stride[3])
+{
+ int x, y, p;
+ int16_t *sample[4][2];
+ int lbd = s->avctx->bits_per_raw_sample <= 8;
+ int bits = s->avctx->bits_per_raw_sample > 0 ? s->avctx->bits_per_raw_sample : 8;
+ int offset = 1 << bits;
+
+ for (x = 0; x < 4; x++) {
+ sample[x][0] = s->sample_buffer + x * 2 * (w + 6) + 3;
+ sample[x][1] = s->sample_buffer + (x * 2 + 1) * (w + 6) + 3;
+ }
+
+ s->run_index = 0;
+
+ memset(s->sample_buffer, 0, 8 * (w + 6) * sizeof(*s->sample_buffer));
+
+ for (y = 0; y < h; y++) {
+ for (p = 0; p < 3 + s->transparency; p++) {
+ int16_t *temp = sample[p][0]; // FIXME: try a normal buffer
+
+ sample[p][0] = sample[p][1];
+ sample[p][1] = temp;
+
+ sample[p][1][-1]= sample[p][0][0 ];
+ sample[p][0][ w]= sample[p][0][w-1];
+ if (lbd && s->slice_coding_mode == 0)
+ decode_line(s, w, sample[p], (p + 1)/2, 9);
+ else
+ decode_line(s, w, sample[p], (p + 1)/2, bits + (s->slice_coding_mode != 1));
+ }
+ for (x = 0; x < w; x++) {
+ int g = sample[0][1][x];
+ int b = sample[1][1][x];
+ int r = sample[2][1][x];
+ int a = sample[3][1][x];
+
+ if (s->slice_coding_mode != 1) {
+ b -= offset;
+ r -= offset;
+ g -= (b * s->slice_rct_by_coef + r * s->slice_rct_ry_coef) >> 2;
+ b += g;
+ r += g;
+ }
+
+ if (lbd)
+ *((uint32_t*)(src[0] + x*4 + stride[0]*y)) = b + (g<<8) + (r<<16) + (a<<24);
+ else {
+ *((uint16_t*)(src[0] + x*2 + stride[0]*y)) = b;
+ *((uint16_t*)(src[1] + x*2 + stride[1]*y)) = g;
+ *((uint16_t*)(src[2] + x*2 + stride[2]*y)) = r;
+ }
+ }
+ }
+}
+
+static int decode_slice_header(FFV1Context *f, FFV1Context *fs)
+{
+ RangeCoder *c = &fs->c;
+ uint8_t state[CONTEXT_SIZE];
+ unsigned ps, i, context_count;
+ memset(state, 128, sizeof(state));
+
+ av_assert0(f->version > 2);
+
+ fs->slice_x = get_symbol(c, state, 0) * f->width ;
+ fs->slice_y = get_symbol(c, state, 0) * f->height;
+ fs->slice_width = (get_symbol(c, state, 0) + 1) * f->width + fs->slice_x;
+ fs->slice_height = (get_symbol(c, state, 0) + 1) * f->height + fs->slice_y;
+
+ fs->slice_x /= f->num_h_slices;
+ fs->slice_y /= f->num_v_slices;
+ fs->slice_width = fs->slice_width /f->num_h_slices - fs->slice_x;
+ fs->slice_height = fs->slice_height/f->num_v_slices - fs->slice_y;
+ if ((unsigned)fs->slice_width > f->width || (unsigned)fs->slice_height > f->height)
+ return -1;
+ if ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width > f->width
+ || (unsigned)fs->slice_y + (uint64_t)fs->slice_height > f->height)
+ return -1;
+
+ for (i = 0; i < f->plane_count; i++) {
+ PlaneContext * const p = &fs->plane[i];
+ int idx = get_symbol(c, state, 0);
+ if (idx >= (unsigned)f->quant_table_count) {
+ av_log(f->avctx, AV_LOG_ERROR, "quant_table_index out of range\n");
+ return -1;
+ }
+ p->quant_table_index = idx;
+ memcpy(p->quant_table, f->quant_tables[idx], sizeof(p->quant_table));
+ context_count = f->context_count[idx];
+
+ if (p->context_count < context_count) {
+ av_freep(&p->state);
+ av_freep(&p->vlc_state);
+ }
+ p->context_count = context_count;
+ }
+
+ ps = get_symbol(c, state, 0);
+ if (ps == 1) {
+ f->cur->interlaced_frame = 1;
+ f->cur->top_field_first = 1;
+ } else if (ps == 2) {
+ f->cur->interlaced_frame = 1;
+ f->cur->top_field_first = 0;
+ } else if (ps == 3) {
+ f->cur->interlaced_frame = 0;
+ }
+ f->cur->sample_aspect_ratio.num = get_symbol(c, state, 0);
+ f->cur->sample_aspect_ratio.den = get_symbol(c, state, 0);
+
+ if (av_image_check_sar(f->width, f->height,
+ f->cur->sample_aspect_ratio) < 0) {
+ av_log(f->avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n",
+ f->cur->sample_aspect_ratio.num,
+ f->cur->sample_aspect_ratio.den);
+ f->cur->sample_aspect_ratio = (AVRational){ 0, 1 };
+ }
+
+ if (fs->version > 3) {
+ fs->slice_reset_contexts = get_rac(c, state);
+ fs->slice_coding_mode = get_symbol(c, state, 0);
+ if (fs->slice_coding_mode != 1) {
+ fs->slice_rct_by_coef = get_symbol(c, state, 0);
+ fs->slice_rct_ry_coef = get_symbol(c, state, 0);
+ if ((uint64_t)fs->slice_rct_by_coef + (uint64_t)fs->slice_rct_ry_coef > 4) {
+ av_log(f->avctx, AV_LOG_ERROR, "slice_rct_y_coef out of range\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int decode_slice(AVCodecContext *c, void *arg)
+{
+ FFV1Context *fs = *(void **)arg;
+ FFV1Context *f = fs->avctx->priv_data;
+ int width, height, x, y, ret;
+ const int ps = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step_minus1 + 1;
+ AVFrame * const p = f->cur;
+ int i, si;
+
+ for( si=0; fs != f->slice_context[si]; si ++)
+ ;
+
+ if(f->fsrc && !p->key_frame)
+ ff_thread_await_progress(&f->last_picture, si, 0);
+
+ if(f->fsrc && !p->key_frame) {
+ FFV1Context *fssrc = f->fsrc->slice_context[si];
+ FFV1Context *fsdst = f->slice_context[si];
+ av_assert1(fsdst->plane_count == fssrc->plane_count);
+ av_assert1(fsdst == fs);
+
+ if (!p->key_frame)
+ fsdst->slice_damaged |= fssrc->slice_damaged;
+
+ for (i = 0; i < f->plane_count; i++) {
+ PlaneContext *psrc = &fssrc->plane[i];
+ PlaneContext *pdst = &fsdst->plane[i];
+
+ av_free(pdst->state);
+ av_free(pdst->vlc_state);
+ memcpy(pdst, psrc, sizeof(*pdst));
+ pdst->state = NULL;
+ pdst->vlc_state = NULL;
+
+ if (fssrc->ac) {
+ pdst->state = av_malloc_array(CONTEXT_SIZE, psrc->context_count);
+ memcpy(pdst->state, psrc->state, CONTEXT_SIZE * psrc->context_count);
+ } else {
+ pdst->vlc_state = av_malloc_array(sizeof(*pdst->vlc_state), psrc->context_count);
+ memcpy(pdst->vlc_state, psrc->vlc_state, sizeof(*pdst->vlc_state) * psrc->context_count);
+ }
+ }
+ }
+
+ fs->slice_rct_by_coef = 1;
+ fs->slice_rct_ry_coef = 1;
+
+ if (f->version > 2) {
+ if (ff_ffv1_init_slice_state(f, fs) < 0)
+ return AVERROR(ENOMEM);
+ if (decode_slice_header(f, fs) < 0) {
+ fs->slice_x = fs->slice_y = fs->slice_height = fs->slice_width = 0;
+ fs->slice_damaged = 1;
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ if ((ret = ff_ffv1_init_slice_state(f, fs)) < 0)
+ return ret;
+ if (f->cur->key_frame || fs->slice_reset_contexts)
+ ff_ffv1_clear_slice_state(f, fs);
+
+ width = fs->slice_width;
+ height = fs->slice_height;
+ x = fs->slice_x;
+ y = fs->slice_y;
+
+ if (!fs->ac) {
+ if (f->version == 3 && f->micro_version > 1 || f->version > 3)
+ get_rac(&fs->c, (uint8_t[]) { 129 });
+ fs->ac_byte_count = f->version > 2 || (!x && !y) ? fs->c.bytestream - fs->c.bytestream_start - 1 : 0;
+ init_get_bits(&fs->gb,
+ fs->c.bytestream_start + fs->ac_byte_count,
+ (fs->c.bytestream_end - fs->c.bytestream_start - fs->ac_byte_count) * 8);
+ }
+
+ av_assert1(width && height);
+ if (f->colorspace == 0) {
+ const int chroma_width = FF_CEIL_RSHIFT(width, f->chroma_h_shift);
+ const int chroma_height = FF_CEIL_RSHIFT(height, f->chroma_v_shift);
+ const int cx = x >> f->chroma_h_shift;
+ const int cy = y >> f->chroma_v_shift;
+ decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0);
+
+ if (f->chroma_planes) {
+ decode_plane(fs, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1);
+ decode_plane(fs, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1);
+ }
+ if (fs->transparency)
+ decode_plane(fs, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], (f->version >= 4 && !f->chroma_planes) ? 1 : 2);
+ } else {
+ uint8_t *planes[3] = { p->data[0] + ps * x + y * p->linesize[0],
+ p->data[1] + ps * x + y * p->linesize[1],
+ p->data[2] + ps * x + y * p->linesize[2] };
+ decode_rgb_frame(fs, planes, width, height, p->linesize);
+ }
+ if (fs->ac && f->version > 2) {
+ int v;
+ get_rac(&fs->c, (uint8_t[]) { 129 });
+ v = fs->c.bytestream_end - fs->c.bytestream - 2 - 5*f->ec;
+ if (v) {
+ av_log(f->avctx, AV_LOG_ERROR, "bytestream end mismatching by %d\n", v);
+ fs->slice_damaged = 1;
+ }
+ }
+
+ emms_c();
+
+ ff_thread_report_progress(&f->picture, si, 0);
+
+ return 0;
+}
+
+static int read_quant_table(RangeCoder *c, int16_t *quant_table, int scale)
+{
+ int v;
+ int i = 0;
+ uint8_t state[CONTEXT_SIZE];
+
+ memset(state, 128, sizeof(state));
+
+ for (v = 0; i < 128; v++) {
+ unsigned len = get_symbol(c, state, 0) + 1;
+
+ if (len > 128 - i || !len)
+ return AVERROR_INVALIDDATA;
+
+ while (len--) {
+ quant_table[i] = scale * v;
+ i++;
+ }
+ }
+
+ for (i = 1; i < 128; i++)
+ quant_table[256 - i] = -quant_table[i];
+ quant_table[128] = -quant_table[127];
+
+ return 2 * v - 1;
+}
+
+static int read_quant_tables(RangeCoder *c,
+ int16_t quant_table[MAX_CONTEXT_INPUTS][256])
+{
+ int i;
+ int context_count = 1;
+
+ for (i = 0; i < 5; i++) {
+ int ret = read_quant_table(c, quant_table[i], context_count);
+ if (ret < 0)
+ return ret;
+ context_count *= ret;
+ if (context_count > 32768U) {
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ return (context_count + 1) / 2;
+}
+
+static int read_extra_header(FFV1Context *f)
+{
+ RangeCoder *const c = &f->c;
+ uint8_t state[CONTEXT_SIZE];
+ int i, j, k, ret;
+ uint8_t state2[32][CONTEXT_SIZE];
+ unsigned crc = 0;
+
+ memset(state2, 128, sizeof(state2));
+ memset(state, 128, sizeof(state));
+
+ ff_init_range_decoder(c, f->avctx->extradata, f->avctx->extradata_size);
+ ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
+
+ f->version = get_symbol(c, state, 0);
+ if (f->version < 2) {
+ av_log(f->avctx, AV_LOG_ERROR, "Invalid version in global header\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (f->version > 2) {
+ c->bytestream_end -= 4;
+ f->micro_version = get_symbol(c, state, 0);
+ if (f->micro_version < 0)
+ return AVERROR_INVALIDDATA;
+ }
+ f->ac = f->avctx->coder_type = get_symbol(c, state, 0);
+ if (f->ac > 1) {
+ for (i = 1; i < 256; i++)
+ f->state_transition[i] = get_symbol(c, state, 1) + c->one_state[i];
+ }
+
+ f->colorspace = get_symbol(c, state, 0); //YUV cs type
+ f->avctx->bits_per_raw_sample = get_symbol(c, state, 0);
+ f->chroma_planes = get_rac(c, state);
+ f->chroma_h_shift = get_symbol(c, state, 0);
+ f->chroma_v_shift = get_symbol(c, state, 0);
+ f->transparency = get_rac(c, state);
+ f->plane_count = 1 + (f->chroma_planes || f->version<4) + f->transparency;
+ f->num_h_slices = 1 + get_symbol(c, state, 0);
+ f->num_v_slices = 1 + get_symbol(c, state, 0);
+
+ if (f->chroma_h_shift > 4U || f->chroma_v_shift > 4U) {
+ av_log(f->avctx, AV_LOG_ERROR, "chroma shift parameters %d %d are invalid\n",
+ f->chroma_h_shift, f->chroma_v_shift);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (f->num_h_slices > (unsigned)f->width || !f->num_h_slices ||
+ f->num_v_slices > (unsigned)f->height || !f->num_v_slices
+ ) {
+ av_log(f->avctx, AV_LOG_ERROR, "slice count invalid\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ f->quant_table_count = get_symbol(c, state, 0);
+ if (f->quant_table_count > (unsigned)MAX_QUANT_TABLES || !f->quant_table_count) {
+ av_log(f->avctx, AV_LOG_ERROR, "quant table count %d is invalid\n", f->quant_table_count);
+ f->quant_table_count = 0;
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (i = 0; i < f->quant_table_count; i++) {
+ f->context_count[i] = read_quant_tables(c, f->quant_tables[i]);
+ if (f->context_count[i] < 0) {
+ av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ if ((ret = ff_ffv1_allocate_initial_states(f)) < 0)
+ return ret;
+
+ for (i = 0; i < f->quant_table_count; i++)
+ if (get_rac(c, state)) {
+ for (j = 0; j < f->context_count[i]; j++)
+ for (k = 0; k < CONTEXT_SIZE; k++) {
+ int pred = j ? f->initial_states[i][j - 1][k] : 128;
+ f->initial_states[i][j][k] =
+ (pred + get_symbol(c, state2[k], 1)) & 0xFF;
+ }
+ }
+
+ if (f->version > 2) {
+ f->ec = get_symbol(c, state, 0);
+ if (f->micro_version > 2)
+ f->intra = get_symbol(c, state, 0);
+ }
+
+ if (f->version > 2) {
+ unsigned v;
+ v = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0,
+ f->avctx->extradata, f->avctx->extradata_size);
+ if (v || f->avctx->extradata_size < 4) {
+ av_log(f->avctx, AV_LOG_ERROR, "CRC mismatch %X!\n", v);
+ return AVERROR_INVALIDDATA;
+ }
+ crc = AV_RB32(f->avctx->extradata + f->avctx->extradata_size - 4);
+ }
+
+ if (f->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(f->avctx, AV_LOG_DEBUG,
+ "global: ver:%d.%d, coder:%d, colorspace: %d bpr:%d chroma:%d(%d:%d), alpha:%d slices:%dx%d qtabs:%d ec:%d intra:%d CRC:0x%08X\n",
+ f->version, f->micro_version,
+ f->ac,
+ f->colorspace,
+ f->avctx->bits_per_raw_sample,
+ f->chroma_planes, f->chroma_h_shift, f->chroma_v_shift,
+ f->transparency,
+ f->num_h_slices, f->num_v_slices,
+ f->quant_table_count,
+ f->ec,
+ f->intra,
+ crc
+ );
+ return 0;
+}
+
+static int read_header(FFV1Context *f)
+{
+ uint8_t state[CONTEXT_SIZE];
+ int i, j, context_count = -1; //-1 to avoid warning
+ RangeCoder *const c = &f->slice_context[0]->c;
+
+ memset(state, 128, sizeof(state));
+
+ if (f->version < 2) {
+ int chroma_planes, chroma_h_shift, chroma_v_shift, transparency, colorspace, bits_per_raw_sample;
+ unsigned v= get_symbol(c, state, 0);
+ if (v >= 2) {
+ av_log(f->avctx, AV_LOG_ERROR, "invalid version %d in ver01 header\n", v);
+ return AVERROR_INVALIDDATA;
+ }
+ f->version = v;
+ f->ac = f->avctx->coder_type = get_symbol(c, state, 0);
+ if (f->ac > 1) {
+ for (i = 1; i < 256; i++)
+ f->state_transition[i] = get_symbol(c, state, 1) + c->one_state[i];
+ }
+
+ colorspace = get_symbol(c, state, 0); //YUV cs type
+ bits_per_raw_sample = f->version > 0 ? get_symbol(c, state, 0) : f->avctx->bits_per_raw_sample;
+ chroma_planes = get_rac(c, state);
+ chroma_h_shift = get_symbol(c, state, 0);
+ chroma_v_shift = get_symbol(c, state, 0);
+ transparency = get_rac(c, state);
+ if (colorspace == 0 && f->avctx->skip_alpha)
+ transparency = 0;
+
+ if (f->plane_count) {
+ if (colorspace != f->colorspace ||
+ bits_per_raw_sample != f->avctx->bits_per_raw_sample ||
+ chroma_planes != f->chroma_planes ||
+ chroma_h_shift != f->chroma_h_shift ||
+ chroma_v_shift != f->chroma_v_shift ||
+ transparency != f->transparency) {
+ av_log(f->avctx, AV_LOG_ERROR, "Invalid change of global parameters\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if (chroma_h_shift > 4U || chroma_v_shift > 4U) {
+ av_log(f->avctx, AV_LOG_ERROR, "chroma shift parameters %d %d are invalid\n",
+ chroma_h_shift, chroma_v_shift);
+ return AVERROR_INVALIDDATA;
+ }
+
+ f->colorspace = colorspace;
+ f->avctx->bits_per_raw_sample = bits_per_raw_sample;
+ f->chroma_planes = chroma_planes;
+ f->chroma_h_shift = chroma_h_shift;
+ f->chroma_v_shift = chroma_v_shift;
+ f->transparency = transparency;
+
+ f->plane_count = 2 + f->transparency;
+ }
+
+ if (f->colorspace == 0) {
+ if (!f->transparency && !f->chroma_planes) {
+ if (f->avctx->bits_per_raw_sample <= 8)
+ f->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+ else
+ f->avctx->pix_fmt = AV_PIX_FMT_GRAY16;
+ } else if (f->avctx->bits_per_raw_sample<=8 && !f->transparency) {
+ switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
+ case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P; break;
+ case 0x01: f->avctx->pix_fmt = AV_PIX_FMT_YUV440P; break;
+ case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P; break;
+ case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P; break;
+ case 0x20: f->avctx->pix_fmt = AV_PIX_FMT_YUV411P; break;
+ case 0x22: f->avctx->pix_fmt = AV_PIX_FMT_YUV410P; break;
+ }
+ } else if (f->avctx->bits_per_raw_sample <= 8 && f->transparency) {
+ switch(16*f->chroma_h_shift + f->chroma_v_shift) {
+ case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUVA444P; break;
+ case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUVA422P; break;
+ case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUVA420P; break;
+ }
+ } else if (f->avctx->bits_per_raw_sample == 9 && !f->transparency) {
+ f->packed_at_lsb = 1;
+ switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
+ case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P9; break;
+ case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P9; break;
+ case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P9; break;
+ }
+ } else if (f->avctx->bits_per_raw_sample == 9 && f->transparency) {
+ f->packed_at_lsb = 1;
+ switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
+ case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUVA444P9; break;
+ case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUVA422P9; break;
+ case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUVA420P9; break;
+ }
+ } else if (f->avctx->bits_per_raw_sample == 10 && !f->transparency) {
+ f->packed_at_lsb = 1;
+ switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
+ case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P10; break;
+ case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P10; break;
+ case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P10; break;
+ }
+ } else if (f->avctx->bits_per_raw_sample == 10 && f->transparency) {
+ f->packed_at_lsb = 1;
+ switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
+ case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUVA444P10; break;
+ case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUVA422P10; break;
+ case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUVA420P10; break;
+ }
+ } else if (f->avctx->bits_per_raw_sample == 16 && !f->transparency){
+ switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
+ case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUV444P16; break;
+ case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUV422P16; break;
+ case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUV420P16; break;
+ }
+ } else if (f->avctx->bits_per_raw_sample == 16 && f->transparency){
+ switch(16 * f->chroma_h_shift + f->chroma_v_shift) {
+ case 0x00: f->avctx->pix_fmt = AV_PIX_FMT_YUVA444P16; break;
+ case 0x10: f->avctx->pix_fmt = AV_PIX_FMT_YUVA422P16; break;
+ case 0x11: f->avctx->pix_fmt = AV_PIX_FMT_YUVA420P16; break;
+ }
+ }
+ } else if (f->colorspace == 1) {
+ if (f->chroma_h_shift || f->chroma_v_shift) {
+ av_log(f->avctx, AV_LOG_ERROR,
+ "chroma subsampling not supported in this colorspace\n");
+ return AVERROR(ENOSYS);
+ }
+ if ( f->avctx->bits_per_raw_sample == 9)
+ f->avctx->pix_fmt = AV_PIX_FMT_GBRP9;
+ else if (f->avctx->bits_per_raw_sample == 10)
+ f->avctx->pix_fmt = AV_PIX_FMT_GBRP10;
+ else if (f->avctx->bits_per_raw_sample == 12)
+ f->avctx->pix_fmt = AV_PIX_FMT_GBRP12;
+ else if (f->avctx->bits_per_raw_sample == 14)
+ f->avctx->pix_fmt = AV_PIX_FMT_GBRP14;
+ else
+ if (f->transparency) f->avctx->pix_fmt = AV_PIX_FMT_RGB32;
+ else f->avctx->pix_fmt = AV_PIX_FMT_0RGB32;
+ } else {
+ av_log(f->avctx, AV_LOG_ERROR, "colorspace not supported\n");
+ return AVERROR(ENOSYS);
+ }
+ if (f->avctx->pix_fmt == AV_PIX_FMT_NONE) {
+ av_log(f->avctx, AV_LOG_ERROR, "format not supported\n");
+ return AVERROR(ENOSYS);
+ }
+
+ ff_dlog(f->avctx, "%d %d %d\n",
+ f->chroma_h_shift, f->chroma_v_shift, f->avctx->pix_fmt);
+ if (f->version < 2) {
+ context_count = read_quant_tables(c, f->quant_table);
+ if (context_count < 0) {
+ av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n");
+ return AVERROR_INVALIDDATA;
+ }
+ f->slice_count = f->max_slice_count;
+ } else if (f->version < 3) {
+ f->slice_count = get_symbol(c, state, 0);
+ } else {
+ const uint8_t *p = c->bytestream_end;
+ for (f->slice_count = 0;
+ f->slice_count < MAX_SLICES && 3 < p - c->bytestream_start;
+ f->slice_count++) {
+ int trailer = 3 + 5*!!f->ec;
+ int size = AV_RB24(p-trailer);
+ if (size + trailer > p - c->bytestream_start)
+ break;
+ p -= size + trailer;
+ }
+ }
+ if (f->slice_count > (unsigned)MAX_SLICES || f->slice_count <= 0 || f->slice_count > f->max_slice_count) {
+ av_log(f->avctx, AV_LOG_ERROR, "slice count %d is invalid (max=%d)\n", f->slice_count, f->max_slice_count);
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (j = 0; j < f->slice_count; j++) {
+ FFV1Context *fs = f->slice_context[j];
+ fs->ac = f->ac;
+ fs->packed_at_lsb = f->packed_at_lsb;
+
+ fs->slice_damaged = 0;
+
+ if (f->version == 2) {
+ fs->slice_x = get_symbol(c, state, 0) * f->width ;
+ fs->slice_y = get_symbol(c, state, 0) * f->height;
+ fs->slice_width = (get_symbol(c, state, 0) + 1) * f->width + fs->slice_x;
+ fs->slice_height = (get_symbol(c, state, 0) + 1) * f->height + fs->slice_y;
+
+ fs->slice_x /= f->num_h_slices;
+ fs->slice_y /= f->num_v_slices;
+ fs->slice_width = fs->slice_width / f->num_h_slices - fs->slice_x;
+ fs->slice_height = fs->slice_height / f->num_v_slices - fs->slice_y;
+ if ((unsigned)fs->slice_width > f->width ||
+ (unsigned)fs->slice_height > f->height)
+ return AVERROR_INVALIDDATA;
+ if ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width > f->width
+ || (unsigned)fs->slice_y + (uint64_t)fs->slice_height > f->height)
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (i = 0; i < f->plane_count; i++) {
+ PlaneContext *const p = &fs->plane[i];
+
+ if (f->version == 2) {
+ int idx = get_symbol(c, state, 0);
+ if (idx > (unsigned)f->quant_table_count) {
+ av_log(f->avctx, AV_LOG_ERROR,
+ "quant_table_index out of range\n");
+ return AVERROR_INVALIDDATA;
+ }
+ p->quant_table_index = idx;
+ memcpy(p->quant_table, f->quant_tables[idx],
+ sizeof(p->quant_table));
+ context_count = f->context_count[idx];
+ } else {
+ memcpy(p->quant_table, f->quant_table, sizeof(p->quant_table));
+ }
+
+ if (f->version <= 2) {
+ av_assert0(context_count >= 0);
+ if (p->context_count < context_count) {
+ av_freep(&p->state);
+ av_freep(&p->vlc_state);
+ }
+ p->context_count = context_count;
+ }
+ }
+ }
+ return 0;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ FFV1Context *f = avctx->priv_data;
+ int ret;
+
+ if ((ret = ff_ffv1_common_init(avctx)) < 0)
+ return ret;
+
+ if (avctx->extradata && (ret = read_extra_header(f)) < 0)
+ return ret;
+
+ if ((ret = ff_ffv1_init_slice_contexts(f)) < 0)
+ return ret;
+
+ avctx->internal->allocate_progress = 1;
+
+ return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
+{
+ uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ FFV1Context *f = avctx->priv_data;
+ RangeCoder *const c = &f->slice_context[0]->c;
+ int i, ret;
+ uint8_t keystate = 128;
+ uint8_t *buf_p;
+ AVFrame *p;
+
+ if (f->last_picture.f)
+ ff_thread_release_buffer(avctx, &f->last_picture);
+ FFSWAP(ThreadFrame, f->picture, f->last_picture);
+
+ f->cur = p = f->picture.f;
+
+ if (f->version < 3 && avctx->field_order > AV_FIELD_PROGRESSIVE) {
+ /* we have interlaced material flagged in container */
+ p->interlaced_frame = 1;
+ if (avctx->field_order == AV_FIELD_TT || avctx->field_order == AV_FIELD_TB)
+ p->top_field_first = 1;
+ }
+
+ f->avctx = avctx;
+ ff_init_range_decoder(c, buf, buf_size);
+ ff_build_rac_states(c, 0.05 * (1LL << 32), 256 - 8);
+
+ p->pict_type = AV_PICTURE_TYPE_I; //FIXME I vs. P
+ if (get_rac(c, &keystate)) {
+ p->key_frame = 1;
+ f->key_frame_ok = 0;
+ if ((ret = read_header(f)) < 0)
+ return ret;
+ f->key_frame_ok = 1;
+ } else {
+ if (!f->key_frame_ok) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Cannot decode non-keyframe without valid keyframe\n");
+ return AVERROR_INVALIDDATA;
+ }
+ p->key_frame = 0;
+ }
+
+ if ((ret = ff_thread_get_buffer(avctx, &f->picture, AV_GET_BUFFER_FLAG_REF)) < 0)
+ return ret;
+
+ if (avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(avctx, AV_LOG_DEBUG, "ver:%d keyframe:%d coder:%d ec:%d slices:%d bps:%d\n",
+ f->version, p->key_frame, f->ac, f->ec, f->slice_count, f->avctx->bits_per_raw_sample);
+
+ ff_thread_finish_setup(avctx);
+
+ buf_p = buf + buf_size;
+ for (i = f->slice_count - 1; i >= 0; i--) {
+ FFV1Context *fs = f->slice_context[i];
+ 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 (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);
+ return AVERROR_INVALIDDATA;
+ }
+ buf_p -= v;
+
+ if (f->ec) {
+ unsigned crc = av_crc(av_crc_get_table(AV_CRC_32_IEEE), 0, buf_p, v);
+ if (crc) {
+ int64_t ts = avpkt->pts != AV_NOPTS_VALUE ? avpkt->pts : avpkt->dts;
+ av_log(f->avctx, AV_LOG_ERROR, "CRC mismatch %X!", crc);
+ if (ts != AV_NOPTS_VALUE && avctx->pkt_timebase.num) {
+ av_log(f->avctx, AV_LOG_ERROR, "at %f seconds\n", ts*av_q2d(avctx->pkt_timebase));
+ } else if (ts != AV_NOPTS_VALUE) {
+ av_log(f->avctx, AV_LOG_ERROR, "at %"PRId64"\n", ts);
+ } else {
+ av_log(f->avctx, AV_LOG_ERROR, "\n");
+ }
+ fs->slice_damaged = 1;
+ }
+ if (avctx->debug & FF_DEBUG_PICT_INFO) {
+ av_log(avctx, AV_LOG_DEBUG, "slice %d, CRC: 0x%08X\n", i, AV_RB32(buf_p + v - 4));
+ }
+ }
+
+ if (i) {
+ ff_init_range_decoder(&fs->c, buf_p, v);
+ } else
+ fs->c.bytestream_end = buf_p + v;
+
+ fs->avctx = avctx;
+ fs->cur = p;
+ }
+
+ avctx->execute(avctx,
+ decode_slice,
+ &f->slice_context[0],
+ NULL,
+ f->slice_count,
+ sizeof(void*));
+
+ for (i = f->slice_count - 1; i >= 0; i--) {
+ FFV1Context *fs = f->slice_context[i];
+ int j;
+ if (fs->slice_damaged && f->last_picture.f->data[0]) {
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+ const uint8_t *src[4];
+ uint8_t *dst[4];
+ ff_thread_await_progress(&f->last_picture, INT_MAX, 0);
+ for (j = 0; j < desc->nb_components; j++) {
+ int sh = (j == 1 || j == 2) ? f->chroma_h_shift : 0;
+ int sv = (j == 1 || j == 2) ? f->chroma_v_shift : 0;
+ dst[j] = p->data[j] + p->linesize[j] *
+ (fs->slice_y >> sv) + (fs->slice_x >> sh);
+ src[j] = f->last_picture.f->data[j] + f->last_picture.f->linesize[j] *
+ (fs->slice_y >> sv) + (fs->slice_x >> sh);
+
+ }
+ if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
+ desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
+ dst[1] = p->data[1];
+ src[1] = f->last_picture.f->data[1];
+ }
+ av_image_copy(dst, p->linesize, src,
+ f->last_picture.f->linesize,
+ avctx->pix_fmt,
+ fs->slice_width,
+ fs->slice_height);
+ }
+ }
+ ff_thread_report_progress(&f->picture, INT_MAX, 0);
+
+ f->picture_number++;
+
+ if (f->last_picture.f)
+ ff_thread_release_buffer(avctx, &f->last_picture);
+ f->cur = NULL;
+ if ((ret = av_frame_ref(data, f->picture.f)) < 0)
+ return ret;
+
+ *got_frame = 1;
+
+ return buf_size;
+}
+
+static int init_thread_copy(AVCodecContext *avctx)
+{
+ FFV1Context *f = avctx->priv_data;
+ int i, ret;
+
+ f->picture.f = NULL;
+ f->last_picture.f = NULL;
+ f->sample_buffer = NULL;
+ f->max_slice_count = 0;
+ f->slice_count = 0;
+
+ for (i = 0; i < f->quant_table_count; i++) {
+ av_assert0(f->version > 1);
+ f->initial_states[i] = av_memdup(f->initial_states[i],
+ f->context_count[i] * sizeof(*f->initial_states[i]));
+ }
+
+ f->picture.f = av_frame_alloc();
+ f->last_picture.f = av_frame_alloc();
+
+ if ((ret = ff_ffv1_init_slice_contexts(f)) < 0)
+ return ret;
+
+ return 0;
+}
+
+static void copy_fields(FFV1Context *fsdst, FFV1Context *fssrc, FFV1Context *fsrc)
+{
+ fsdst->version = fsrc->version;
+ fsdst->micro_version = fsrc->micro_version;
+ fsdst->chroma_planes = fsrc->chroma_planes;
+ fsdst->chroma_h_shift = fsrc->chroma_h_shift;
+ fsdst->chroma_v_shift = fsrc->chroma_v_shift;
+ fsdst->transparency = fsrc->transparency;
+ fsdst->plane_count = fsrc->plane_count;
+ fsdst->ac = fsrc->ac;
+ fsdst->colorspace = fsrc->colorspace;
+
+ fsdst->ec = fsrc->ec;
+ fsdst->intra = fsrc->intra;
+ fsdst->slice_damaged = fssrc->slice_damaged;
+ fsdst->key_frame_ok = fsrc->key_frame_ok;
+
+ fsdst->bits_per_raw_sample = fsrc->bits_per_raw_sample;
+ fsdst->packed_at_lsb = fsrc->packed_at_lsb;
+ fsdst->slice_count = fsrc->slice_count;
+ if (fsrc->version<3){
+ fsdst->slice_x = fssrc->slice_x;
+ fsdst->slice_y = fssrc->slice_y;
+ fsdst->slice_width = fssrc->slice_width;
+ fsdst->slice_height = fssrc->slice_height;
+ }
+}
+
+static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
+{
+ FFV1Context *fsrc = src->priv_data;
+ FFV1Context *fdst = dst->priv_data;
+ int i, ret;
+
+ if (dst == src)
+ return 0;
+
+ {
+ ThreadFrame picture = fdst->picture, last_picture = fdst->last_picture;
+ uint8_t (*initial_states[MAX_QUANT_TABLES])[32];
+ struct FFV1Context *slice_context[MAX_SLICES];
+ memcpy(initial_states, fdst->initial_states, sizeof(fdst->initial_states));
+ memcpy(slice_context, fdst->slice_context , sizeof(fdst->slice_context));
+
+ memcpy(fdst, fsrc, sizeof(*fdst));
+ memcpy(fdst->initial_states, initial_states, sizeof(fdst->initial_states));
+ memcpy(fdst->slice_context, slice_context , sizeof(fdst->slice_context));
+ fdst->picture = picture;
+ fdst->last_picture = last_picture;
+ for (i = 0; i<fdst->num_h_slices * fdst->num_v_slices; i++) {
+ FFV1Context *fssrc = fsrc->slice_context[i];
+ FFV1Context *fsdst = fdst->slice_context[i];
+ copy_fields(fsdst, fssrc, fsrc);
+ }
+ av_assert0(!fdst->plane[0].state);
+ av_assert0(!fdst->sample_buffer);
+ }
+
+ av_assert1(fdst->max_slice_count == fsrc->max_slice_count);
+
+
+ ff_thread_release_buffer(dst, &fdst->picture);
+ if (fsrc->picture.f->data[0]) {
+ if ((ret = ff_thread_ref_frame(&fdst->picture, &fsrc->picture)) < 0)
+ return ret;
+ }
+
+ fdst->fsrc = fsrc;
+
+ return 0;
+}
+
+AVCodec ff_ffv1_decoder = {
+ .name = "ffv1",
+ .long_name = NULL_IF_CONFIG_SMALL("FFmpeg video codec #1"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_FFV1,
+ .priv_data_size = sizeof(FFV1Context),
+ .init = decode_init,
+ .close = ff_ffv1_close,
+ .decode = decode_frame,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
+ .capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/ |
+ AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_SLICE_THREADS,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/ffv1enc.c b/ffmpeg-2-8-12/libavcodec/ffv1enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ffv1enc.c
rename to ffmpeg-2-8-12/libavcodec/ffv1enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/ffwavesynth.c b/ffmpeg-2-8-12/libavcodec/ffwavesynth.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ffwavesynth.c
rename to ffmpeg-2-8-12/libavcodec/ffwavesynth.c
diff --git a/ffmpeg-2-8-12/libavcodec/fic.c b/ffmpeg-2-8-12/libavcodec/fic.c
new file mode 100644
index 0000000..2fa5c48
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/fic.c
@@ -0,0 +1,481 @@
+/*
+ * Mirillis FIC decoder
+ *
+ * Copyright (c) 2014 Konstantin Shishkov
+ * Copyright (c) 2014 Derek Buitenhuis
+ *
+ * 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/opt.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "get_bits.h"
+#include "golomb.h"
+
+typedef struct FICThreadContext {
+ DECLARE_ALIGNED(16, int16_t, block)[64];
+ uint8_t *src;
+ int slice_h;
+ int src_size;
+ int y_off;
+} FICThreadContext;
+
+typedef struct FICContext {
+ AVClass *class;
+ AVCodecContext *avctx;
+ AVFrame *frame;
+ AVFrame *final_frame;
+
+ FICThreadContext *slice_data;
+ int slice_data_size;
+
+ const uint8_t *qmat;
+
+ enum AVPictureType cur_frame_type;
+
+ int aligned_width, aligned_height;
+ int num_slices, slice_h;
+
+ uint8_t cursor_buf[4096];
+ int skip_cursor;
+} FICContext;
+
+static const uint8_t fic_qmat_hq[64] = {
+ 1, 2, 2, 2, 3, 3, 3, 4,
+ 2, 2, 2, 3, 3, 3, 4, 4,
+ 2, 2, 3, 3, 3, 4, 4, 4,
+ 2, 2, 3, 3, 3, 4, 4, 5,
+ 2, 3, 3, 3, 4, 4, 5, 6,
+ 3, 3, 3, 4, 4, 5, 6, 7,
+ 3, 3, 3, 4, 4, 5, 7, 7,
+ 3, 3, 4, 4, 5, 7, 7, 7,
+};
+
+static const uint8_t fic_qmat_lq[64] = {
+ 1, 5, 6, 7, 8, 9, 9, 11,
+ 5, 5, 7, 8, 9, 9, 11, 12,
+ 6, 7, 8, 9, 9, 11, 11, 12,
+ 7, 7, 8, 9, 9, 11, 12, 13,
+ 7, 8, 9, 9, 10, 11, 13, 16,
+ 8, 9, 9, 10, 11, 13, 16, 19,
+ 8, 9, 9, 11, 12, 15, 18, 23,
+ 9, 9, 11, 12, 15, 18, 23, 27
+};
+
+static const uint8_t fic_header[7] = { 0, 0, 1, 'F', 'I', 'C', 'V' };
+
+#define FIC_HEADER_SIZE 27
+
+static av_always_inline void fic_idct(int16_t *blk, int step, int shift, int rnd)
+{
+ const int t0 = 27246 * blk[3 * step] + 18405 * blk[5 * step];
+ const int t1 = 27246 * blk[5 * step] - 18405 * blk[3 * step];
+ const int t2 = 6393 * blk[7 * step] + 32139 * blk[1 * step];
+ const int t3 = 6393 * blk[1 * step] - 32139 * blk[7 * step];
+ const unsigned t4 = 5793U * (t2 + t0 + 0x800 >> 12);
+ const unsigned t5 = 5793U * (t3 + t1 + 0x800 >> 12);
+ const unsigned t6 = t2 - t0;
+ const unsigned t7 = t3 - t1;
+ const unsigned t8 = 17734 * blk[2 * step] - 42813 * blk[6 * step];
+ const unsigned t9 = 17734 * blk[6 * step] + 42814 * blk[2 * step];
+ const unsigned tA = (blk[0 * step] - blk[4 * step]) * 32768 + rnd;
+ const unsigned tB = (blk[0 * step] + blk[4 * step]) * 32768 + rnd;
+ blk[0 * step] = (int)( t4 + t9 + tB) >> shift;
+ blk[1 * step] = (int)( t6 + t7 + t8 + tA) >> shift;
+ blk[2 * step] = (int)( t6 - t7 - t8 + tA) >> shift;
+ blk[3 * step] = (int)( t5 - t9 + tB) >> shift;
+ blk[4 * step] = (int)( -t5 - t9 + tB) >> shift;
+ blk[5 * step] = (int)(-(t6 - t7) - t8 + tA) >> shift;
+ blk[6 * step] = (int)(-(t6 + t7) + t8 + tA) >> shift;
+ blk[7 * step] = (int)( -t4 + t9 + tB) >> shift;
+}
+
+static void fic_idct_put(uint8_t *dst, int stride, int16_t *block)
+{
+ int i, j;
+ int16_t *ptr;
+
+ ptr = block;
+ fic_idct(ptr++, 8, 13, (1 << 12) + (1 << 17));
+ for (i = 1; i < 8; i++) {
+ fic_idct(ptr, 8, 13, 1 << 12);
+ ptr++;
+ }
+
+ ptr = block;
+ for (i = 0; i < 8; i++) {
+ fic_idct(ptr, 1, 20, 0);
+ ptr += 8;
+ }
+
+ ptr = block;
+ for (j = 0; j < 8; j++) {
+ for (i = 0; i < 8; i++)
+ dst[i] = av_clip_uint8(ptr[i]);
+ dst += stride;
+ ptr += 8;
+ }
+}
+static int fic_decode_block(FICContext *ctx, GetBitContext *gb,
+ uint8_t *dst, int stride, int16_t *block)
+{
+ int i, num_coeff;
+
+ /* Is it a skip block? */
+ if (get_bits1(gb)) {
+ /* This is a P-frame. */
+ ctx->frame->key_frame = 0;
+ ctx->frame->pict_type = AV_PICTURE_TYPE_P;
+
+ return 0;
+ }
+
+ memset(block, 0, sizeof(*block) * 64);
+
+ num_coeff = get_bits(gb, 7);
+ if (num_coeff > 64)
+ return AVERROR_INVALIDDATA;
+
+ for (i = 0; i < num_coeff; i++)
+ block[ff_zigzag_direct[i]] = get_se_golomb(gb) *
+ ctx->qmat[ff_zigzag_direct[i]];
+
+ fic_idct_put(dst, stride, block);
+
+ return 0;
+}
+
+static int fic_decode_slice(AVCodecContext *avctx, void *tdata)
+{
+ FICContext *ctx = avctx->priv_data;
+ FICThreadContext *tctx = tdata;
+ GetBitContext gb;
+ uint8_t *src = tctx->src;
+ int slice_h = tctx->slice_h;
+ int src_size = tctx->src_size;
+ int y_off = tctx->y_off;
+ int x, y, p;
+
+ init_get_bits(&gb, src, src_size * 8);
+
+ for (p = 0; p < 3; p++) {
+ int stride = ctx->frame->linesize[p];
+ uint8_t* dst = ctx->frame->data[p] + (y_off >> !!p) * stride;
+
+ for (y = 0; y < (slice_h >> !!p); y += 8) {
+ for (x = 0; x < (ctx->aligned_width >> !!p); x += 8) {
+ int ret;
+
+ if ((ret = fic_decode_block(ctx, &gb, dst + x, stride, tctx->block)) != 0)
+ return ret;
+ }
+
+ dst += 8 * stride;
+ }
+ }
+
+ return 0;
+}
+
+static av_always_inline void fic_alpha_blend(uint8_t *dst, uint8_t *src,
+ int size, uint8_t *alpha)
+{
+ int i;
+
+ for (i = 0; i < size; i++)
+ dst[i] += ((src[i] - dst[i]) * alpha[i]) >> 8;
+}
+
+static void fic_draw_cursor(AVCodecContext *avctx, int cur_x, int cur_y)
+{
+ FICContext *ctx = avctx->priv_data;
+ uint8_t *ptr = ctx->cursor_buf;
+ uint8_t *dstptr[3];
+ uint8_t planes[4][1024];
+ uint8_t chroma[3][256];
+ int i, j, p;
+
+ /* Convert to YUVA444. */
+ for (i = 0; i < 1024; i++) {
+ planes[0][i] = (( 25 * ptr[0] + 129 * ptr[1] + 66 * ptr[2]) / 255) + 16;
+ planes[1][i] = ((-38 * ptr[0] + 112 * ptr[1] + -74 * ptr[2]) / 255) + 128;
+ planes[2][i] = ((-18 * ptr[0] + 112 * ptr[1] + -94 * ptr[2]) / 255) + 128;
+ planes[3][i] = ptr[3];
+
+ ptr += 4;
+ }
+
+ /* Subsample chroma. */
+ for (i = 0; i < 32; i += 2)
+ for (j = 0; j < 32; j += 2)
+ for (p = 0; p < 3; p++)
+ chroma[p][16 * (i / 2) + j / 2] = (planes[p + 1][32 * i + j ] +
+ planes[p + 1][32 * i + j + 1] +
+ planes[p + 1][32 * (i + 1) + j ] +
+ planes[p + 1][32 * (i + 1) + j + 1]) / 4;
+
+ /* Seek to x/y pos of cursor. */
+ for (i = 0; i < 3; i++)
+ dstptr[i] = ctx->final_frame->data[i] +
+ (ctx->final_frame->linesize[i] * (cur_y >> !!i)) +
+ (cur_x >> !!i) + !!i;
+
+ /* Copy. */
+ for (i = 0; i < FFMIN(32, avctx->height - cur_y) - 1; i += 2) {
+ int lsize = FFMIN(32, avctx->width - cur_x);
+ int csize = lsize / 2;
+
+ fic_alpha_blend(dstptr[0],
+ planes[0] + i * 32, lsize, planes[3] + i * 32);
+ fic_alpha_blend(dstptr[0] + ctx->final_frame->linesize[0],
+ planes[0] + (i + 1) * 32, lsize, planes[3] + (i + 1) * 32);
+ fic_alpha_blend(dstptr[1],
+ chroma[0] + (i / 2) * 16, csize, chroma[2] + (i / 2) * 16);
+ fic_alpha_blend(dstptr[2],
+ chroma[1] + (i / 2) * 16, csize, chroma[2] + (i / 2) * 16);
+
+ dstptr[0] += ctx->final_frame->linesize[0] * 2;
+ dstptr[1] += ctx->final_frame->linesize[1];
+ dstptr[2] += ctx->final_frame->linesize[2];
+ }
+}
+
+static int fic_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame, AVPacket *avpkt)
+{
+ FICContext *ctx = avctx->priv_data;
+ uint8_t *src = avpkt->data;
+ int ret;
+ int slice, nslices;
+ int msize;
+ int tsize;
+ int cur_x, cur_y;
+ int skip_cursor = ctx->skip_cursor;
+ uint8_t *sdata;
+
+ if ((ret = ff_reget_buffer(avctx, ctx->frame)) < 0)
+ return ret;
+
+ /* Header + at least one slice (4) */
+ if (avpkt->size < FIC_HEADER_SIZE + 4) {
+ av_log(avctx, AV_LOG_ERROR, "Frame data is too small.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* Check for header. */
+ if (memcmp(src, fic_header, 7))
+ av_log(avctx, AV_LOG_WARNING, "Invalid FIC Header.\n");
+
+ /* Is it a skip frame? */
+ if (src[17]) {
+ if (!ctx->final_frame) {
+ av_log(avctx, AV_LOG_WARNING, "Initial frame is skipped\n");
+ return AVERROR_INVALIDDATA;
+ }
+ goto skip;
+ }
+
+ nslices = src[13];
+ if (!nslices) {
+ av_log(avctx, AV_LOG_ERROR, "Zero slices found.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* High or Low Quality Matrix? */
+ ctx->qmat = src[23] ? fic_qmat_hq : fic_qmat_lq;
+
+ /* Skip cursor data. */
+ tsize = AV_RB24(src + 24);
+ if (tsize > avpkt->size - FIC_HEADER_SIZE) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Packet is too small to contain cursor (%d vs %d bytes).\n",
+ tsize, avpkt->size - FIC_HEADER_SIZE);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!tsize)
+ skip_cursor = 1;
+
+ if (!skip_cursor && tsize < 32) {
+ av_log(avctx, AV_LOG_WARNING,
+ "Cursor data too small. Skipping cursor.\n");
+ skip_cursor = 1;
+ }
+
+ /* Cursor position. */
+ cur_x = AV_RL16(src + 33);
+ cur_y = AV_RL16(src + 35);
+ if (!skip_cursor && (cur_x > avctx->width || cur_y > avctx->height)) {
+ av_log(avctx, AV_LOG_WARNING,
+ "Invalid cursor position: (%d,%d). Skipping cusor.\n",
+ cur_x, cur_y);
+ skip_cursor = 1;
+ }
+
+ if (!skip_cursor && (AV_RL16(src + 37) != 32 || AV_RL16(src + 39) != 32)) {
+ av_log(avctx, AV_LOG_WARNING,
+ "Invalid cursor size. Skipping cursor.\n");
+ skip_cursor = 1;
+ }
+
+ /* Slice height for all but the last slice. */
+ ctx->slice_h = 16 * (ctx->aligned_height >> 4) / nslices;
+ if (ctx->slice_h % 16)
+ ctx->slice_h = FFALIGN(ctx->slice_h - 16, 16);
+
+ /* First slice offset and remaining data. */
+ sdata = src + tsize + FIC_HEADER_SIZE + 4 * nslices;
+ msize = avpkt->size - nslices * 4 - tsize - FIC_HEADER_SIZE;
+
+ if (msize <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Not enough frame data to decode.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /*
+ * Set the frametype to I initially. It will be set to P if the frame
+ * has any dependencies (skip blocks). There will be a race condition
+ * inside the slice decode function to set these, but we do not care.
+ * since they will only ever be set to 0/P.
+ */
+ ctx->frame->key_frame = 1;
+ ctx->frame->pict_type = AV_PICTURE_TYPE_I;
+
+ /* Allocate slice data. */
+ av_fast_malloc(&ctx->slice_data, &ctx->slice_data_size,
+ nslices * sizeof(ctx->slice_data[0]));
+ if (!ctx->slice_data_size) {
+ av_log(avctx, AV_LOG_ERROR, "Could not allocate slice data.\n");
+ return AVERROR(ENOMEM);
+ }
+ memset(ctx->slice_data, 0, nslices * sizeof(ctx->slice_data[0]));
+
+ for (slice = 0; slice < nslices; slice++) {
+ unsigned slice_off = AV_RB32(src + tsize + FIC_HEADER_SIZE + slice * 4);
+ unsigned slice_size;
+ int y_off = ctx->slice_h * slice;
+ int slice_h = ctx->slice_h;
+
+ /*
+ * Either read the slice size, or consume all data left.
+ * Also, special case the last slight height.
+ */
+ if (slice == nslices - 1) {
+ slice_size = msize;
+ slice_h = FFALIGN(avctx->height - ctx->slice_h * (nslices - 1), 16);
+ } else {
+ slice_size = AV_RB32(src + tsize + FIC_HEADER_SIZE + slice * 4 + 4);
+ }
+
+ if (slice_size < slice_off || slice_size > msize)
+ continue;
+
+ slice_size -= slice_off;
+
+ ctx->slice_data[slice].src = sdata + slice_off;
+ ctx->slice_data[slice].src_size = slice_size;
+ ctx->slice_data[slice].slice_h = slice_h;
+ ctx->slice_data[slice].y_off = y_off;
+ }
+
+ if ((ret = avctx->execute(avctx, fic_decode_slice, ctx->slice_data,
+ NULL, nslices, sizeof(ctx->slice_data[0]))) < 0)
+ return ret;
+
+ av_frame_free(&ctx->final_frame);
+ ctx->final_frame = av_frame_clone(ctx->frame);
+ if (!ctx->final_frame) {
+ av_log(avctx, AV_LOG_ERROR, "Could not clone frame buffer.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ /* Make sure we use a user-supplied buffer. */
+ if ((ret = ff_reget_buffer(avctx, ctx->final_frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Could not make frame writable.\n");
+ return ret;
+ }
+
+ /* Draw cursor. */
+ if (!skip_cursor) {
+ memcpy(ctx->cursor_buf, src + 59, 32 * 32 * 4);
+ fic_draw_cursor(avctx, cur_x, cur_y);
+ }
+
+skip:
+ *got_frame = 1;
+ if ((ret = av_frame_ref(data, ctx->final_frame)) < 0)
+ return ret;
+
+ return avpkt->size;
+}
+
+static av_cold int fic_decode_close(AVCodecContext *avctx)
+{
+ FICContext *ctx = avctx->priv_data;
+
+ av_freep(&ctx->slice_data);
+ av_frame_free(&ctx->final_frame);
+ av_frame_free(&ctx->frame);
+
+ return 0;
+}
+
+static av_cold int fic_decode_init(AVCodecContext *avctx)
+{
+ FICContext *ctx = avctx->priv_data;
+
+ /* Initialize various context values */
+ ctx->avctx = avctx;
+ ctx->aligned_width = FFALIGN(avctx->width, 16);
+ ctx->aligned_height = FFALIGN(avctx->height, 16);
+
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+ avctx->bits_per_raw_sample = 8;
+
+ ctx->frame = av_frame_alloc();
+ if (!ctx->frame)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static const AVOption options[] = {
+{ "skip_cursor", "skip the cursor", offsetof(FICContext, skip_cursor), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_VIDEO_PARAM },
+{ NULL },
+};
+
+static const AVClass fic_decoder_class = {
+ .class_name = "FIC encoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_fic_decoder = {
+ .name = "fic",
+ .long_name = NULL_IF_CONFIG_SMALL("Mirillis FIC"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_FIC,
+ .priv_data_size = sizeof(FICContext),
+ .init = fic_decode_init,
+ .decode = fic_decode_frame,
+ .close = fic_decode_close,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
+ .priv_class = &fic_decoder_class,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/file_open.c b/ffmpeg-2-8-12/libavcodec/file_open.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/file_open.c
rename to ffmpeg-2-8-12/libavcodec/file_open.c
diff --git a/ffmpeg-2-8-11/libavcodec/flac.c b/ffmpeg-2-8-12/libavcodec/flac.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flac.c
rename to ffmpeg-2-8-12/libavcodec/flac.c
diff --git a/ffmpeg-2-8-11/libavcodec/flac.h b/ffmpeg-2-8-12/libavcodec/flac.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flac.h
rename to ffmpeg-2-8-12/libavcodec/flac.h
diff --git a/ffmpeg-2-8-11/libavcodec/flac_parser.c b/ffmpeg-2-8-12/libavcodec/flac_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flac_parser.c
rename to ffmpeg-2-8-12/libavcodec/flac_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/flacdata.c b/ffmpeg-2-8-12/libavcodec/flacdata.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flacdata.c
rename to ffmpeg-2-8-12/libavcodec/flacdata.c
diff --git a/ffmpeg-2-8-11/libavcodec/flacdata.h b/ffmpeg-2-8-12/libavcodec/flacdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flacdata.h
rename to ffmpeg-2-8-12/libavcodec/flacdata.h
diff --git a/ffmpeg-2-8-12/libavcodec/flacdec.c b/ffmpeg-2-8-12/libavcodec/flacdec.c
new file mode 100644
index 0000000..4ab2b42
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/flacdec.c
@@ -0,0 +1,676 @@
+/*
+ * FLAC (Free Lossless Audio Codec) decoder
+ * Copyright (c) 2003 Alex Beregszaszi
+ *
+ * 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
+ * FLAC (Free Lossless Audio Codec) decoder
+ * @author Alex Beregszaszi
+ * @see http://flac.sourceforge.net/
+ *
+ * This decoder can be used in 1 of 2 ways: Either raw FLAC data can be fed
+ * through, starting from the initial 'fLaC' signature; or by passing the
+ * 34-byte streaminfo structure through avctx->extradata[_size] followed
+ * by data starting with the 0xFFF8 marker.
+ */
+
+#include <limits.h>
+
+#include "libavutil/avassert.h"
+#include "libavutil/crc.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "get_bits.h"
+#include "bytestream.h"
+#include "golomb.h"
+#include "flac.h"
+#include "flacdata.h"
+#include "flacdsp.h"
+#include "thread.h"
+#include "unary.h"
+
+
+typedef struct FLACContext {
+ AVClass *class;
+ struct FLACStreaminfo flac_stream_info;
+
+ AVCodecContext *avctx; ///< parent AVCodecContext
+ GetBitContext gb; ///< GetBitContext initialized to start at the current frame
+
+ int blocksize; ///< number of samples in the current frame
+ int sample_shift; ///< shift required to make output samples 16-bit or 32-bit
+ int ch_mode; ///< channel decorrelation type in the current frame
+ int got_streaminfo; ///< indicates if the STREAMINFO has been read
+
+ int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples
+ uint8_t *decoded_buffer;
+ unsigned int decoded_buffer_size;
+ int buggy_lpc; ///< use workaround for old lavc encoded files
+
+ FLACDSPContext dsp;
+} FLACContext;
+
+static int allocate_buffers(FLACContext *s);
+
+static void flac_set_bps(FLACContext *s)
+{
+ enum AVSampleFormat req = s->avctx->request_sample_fmt;
+ int need32 = s->flac_stream_info.bps > 16;
+ int want32 = av_get_bytes_per_sample(req) > 2;
+ int planar = av_sample_fmt_is_planar(req);
+
+ if (need32 || want32) {
+ if (planar)
+ s->avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
+ else
+ s->avctx->sample_fmt = AV_SAMPLE_FMT_S32;
+ s->sample_shift = 32 - s->flac_stream_info.bps;
+ } else {
+ if (planar)
+ s->avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+ else
+ s->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ s->sample_shift = 16 - s->flac_stream_info.bps;
+ }
+}
+
+static av_cold int flac_decode_init(AVCodecContext *avctx)
+{
+ enum FLACExtradataFormat format;
+ uint8_t *streaminfo;
+ int ret;
+ FLACContext *s = avctx->priv_data;
+ s->avctx = avctx;
+
+ /* for now, the raw FLAC header is allowed to be passed to the decoder as
+ frame data instead of extradata. */
+ if (!avctx->extradata)
+ return 0;
+
+ if (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo))
+ return AVERROR_INVALIDDATA;
+
+ /* initialize based on the demuxer-supplied streamdata header */
+ ff_flac_parse_streaminfo(avctx, &s->flac_stream_info, streaminfo);
+ ret = allocate_buffers(s);
+ if (ret < 0)
+ return ret;
+ flac_set_bps(s);
+ ff_flacdsp_init(&s->dsp, avctx->sample_fmt,
+ s->flac_stream_info.channels, s->flac_stream_info.bps);
+ s->got_streaminfo = 1;
+
+ return 0;
+}
+
+static void dump_headers(AVCodecContext *avctx, FLACStreaminfo *s)
+{
+ av_log(avctx, AV_LOG_DEBUG, " Max Blocksize: %d\n", s->max_blocksize);
+ av_log(avctx, AV_LOG_DEBUG, " Max Framesize: %d\n", s->max_framesize);
+ av_log(avctx, AV_LOG_DEBUG, " Samplerate: %d\n", s->samplerate);
+ av_log(avctx, AV_LOG_DEBUG, " Channels: %d\n", s->channels);
+ av_log(avctx, AV_LOG_DEBUG, " Bits: %d\n", s->bps);
+}
+
+static int allocate_buffers(FLACContext *s)
+{
+ int buf_size;
+ int ret;
+
+ av_assert0(s->flac_stream_info.max_blocksize);
+
+ buf_size = av_samples_get_buffer_size(NULL, s->flac_stream_info.channels,
+ s->flac_stream_info.max_blocksize,
+ AV_SAMPLE_FMT_S32P, 0);
+ if (buf_size < 0)
+ return buf_size;
+
+ av_fast_malloc(&s->decoded_buffer, &s->decoded_buffer_size, buf_size);
+ if (!s->decoded_buffer)
+ return AVERROR(ENOMEM);
+
+ ret = av_samples_fill_arrays((uint8_t **)s->decoded, NULL,
+ s->decoded_buffer,
+ s->flac_stream_info.channels,
+ s->flac_stream_info.max_blocksize,
+ AV_SAMPLE_FMT_S32P, 0);
+ return ret < 0 ? ret : 0;
+}
+
+/**
+ * Parse the STREAMINFO from an inline header.
+ * @param s the flac decoding context
+ * @param buf input buffer, starting with the "fLaC" marker
+ * @param buf_size buffer size
+ * @return non-zero if metadata is invalid
+ */
+static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size)
+{
+ int metadata_type, metadata_size, ret;
+
+ if (buf_size < FLAC_STREAMINFO_SIZE+8) {
+ /* need more data */
+ return 0;
+ }
+ flac_parse_block_header(&buf[4], NULL, &metadata_type, &metadata_size);
+ if (metadata_type != FLAC_METADATA_TYPE_STREAMINFO ||
+ metadata_size != FLAC_STREAMINFO_SIZE) {
+ return AVERROR_INVALIDDATA;
+ }
+ ff_flac_parse_streaminfo(s->avctx, &s->flac_stream_info, &buf[8]);
+ ret = allocate_buffers(s);
+ if (ret < 0)
+ return ret;
+ flac_set_bps(s);
+ ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt,
+ s->flac_stream_info.channels, s->flac_stream_info.bps);
+ s->got_streaminfo = 1;
+
+ return 0;
+}
+
+/**
+ * Determine the size of an inline header.
+ * @param buf input buffer, starting with the "fLaC" marker
+ * @param buf_size buffer size
+ * @return number of bytes in the header, or 0 if more data is needed
+ */
+static int get_metadata_size(const uint8_t *buf, int buf_size)
+{
+ int metadata_last, metadata_size;
+ const uint8_t *buf_end = buf + buf_size;
+
+ buf += 4;
+ do {
+ if (buf_end - buf < 4)
+ return AVERROR_INVALIDDATA;
+ flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size);
+ buf += 4;
+ if (buf_end - buf < metadata_size) {
+ /* need more data in order to read the complete header */
+ return AVERROR_INVALIDDATA;
+ }
+ buf += metadata_size;
+ } while (!metadata_last);
+
+ return buf_size - (buf_end - buf);
+}
+
+static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order)
+{
+ int i, tmp, partition, method_type, rice_order;
+ int rice_bits, rice_esc;
+ int samples;
+
+ method_type = get_bits(&s->gb, 2);
+ if (method_type > 1) {
+ av_log(s->avctx, AV_LOG_ERROR, "illegal residual coding method %d\n",
+ method_type);
+ return AVERROR_INVALIDDATA;
+ }
+
+ rice_order = get_bits(&s->gb, 4);
+
+ samples= s->blocksize >> rice_order;
+ if (samples << rice_order != s->blocksize) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid rice order: %i blocksize %i\n",
+ rice_order, s->blocksize);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (pred_order > samples) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid predictor order: %i > %i\n",
+ pred_order, samples);
+ return AVERROR_INVALIDDATA;
+ }
+
+ rice_bits = 4 + method_type;
+ rice_esc = (1 << rice_bits) - 1;
+
+ decoded += pred_order;
+ i= pred_order;
+ for (partition = 0; partition < (1 << rice_order); partition++) {
+ tmp = get_bits(&s->gb, rice_bits);
+ if (tmp == rice_esc) {
+ tmp = get_bits(&s->gb, 5);
+ for (; i < samples; i++)
+ *decoded++ = get_sbits_long(&s->gb, tmp);
+ } else {
+ for (; i < samples; i++) {
+ *decoded++ = get_sr_golomb_flac(&s->gb, tmp, INT_MAX, 0);
+ }
+ }
+ i= 0;
+ }
+
+ return 0;
+}
+
+static int decode_subframe_fixed(FLACContext *s, int32_t *decoded,
+ int pred_order, int bps)
+{
+ const int blocksize = s->blocksize;
+ unsigned av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d);
+ int i;
+ int ret;
+
+ /* warm up samples */
+ for (i = 0; i < pred_order; i++) {
+ decoded[i] = get_sbits_long(&s->gb, bps);
+ }
+
+ if ((ret = decode_residuals(s, decoded, pred_order)) < 0)
+ return ret;
+
+ if (pred_order > 0)
+ a = decoded[pred_order-1];
+ if (pred_order > 1)
+ b = a - decoded[pred_order-2];
+ if (pred_order > 2)
+ c = b - decoded[pred_order-2] + decoded[pred_order-3];
+ if (pred_order > 3)
+ d = c - decoded[pred_order-2] + 2*decoded[pred_order-3] - decoded[pred_order-4];
+
+ switch (pred_order) {
+ case 0:
+ break;
+ case 1:
+ for (i = pred_order; i < blocksize; i++)
+ decoded[i] = a += decoded[i];
+ break;
+ case 2:
+ for (i = pred_order; i < blocksize; i++)
+ decoded[i] = a += b += decoded[i];
+ break;
+ case 3:
+ for (i = pred_order; i < blocksize; i++)
+ decoded[i] = a += b += c += decoded[i];
+ break;
+ case 4:
+ for (i = pred_order; i < blocksize; i++)
+ decoded[i] = a += b += c += d += decoded[i];
+ break;
+ default:
+ av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order);
+ return AVERROR_INVALIDDATA;
+ }
+
+ return 0;
+}
+
+static void lpc_analyze_remodulate(int32_t *decoded, const int coeffs[32],
+ int order, int qlevel, int len, int bps)
+{
+ int i, j;
+ int ebps = 1 << (bps-1);
+ unsigned sigma = 0;
+
+ for (i = order; i < len; i++)
+ sigma |= decoded[i] + ebps;
+
+ if (sigma < 2*ebps)
+ return;
+
+ for (i = len - 1; i >= order; i--) {
+ int64_t p = 0;
+ for (j = 0; j < order; j++)
+ p += coeffs[j] * (int64_t)decoded[i-order+j];
+ decoded[i] -= p >> qlevel;
+ }
+ for (i = order; i < len; i++, decoded++) {
+ int32_t p = 0;
+ for (j = 0; j < order; j++)
+ p += coeffs[j] * (uint32_t)decoded[j];
+ decoded[j] += p >> qlevel;
+ }
+}
+
+static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order,
+ int bps)
+{
+ int i, ret;
+ int coeff_prec, qlevel;
+ int coeffs[32];
+
+ /* warm up samples */
+ for (i = 0; i < pred_order; i++) {
+ decoded[i] = get_sbits_long(&s->gb, bps);
+ }
+
+ coeff_prec = get_bits(&s->gb, 4) + 1;
+ if (coeff_prec == 16) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid coeff precision\n");
+ return AVERROR_INVALIDDATA;
+ }
+ qlevel = get_sbits(&s->gb, 5);
+ if (qlevel < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "qlevel %d not supported, maybe buggy stream\n",
+ qlevel);
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (i = 0; i < pred_order; i++) {
+ coeffs[pred_order - i - 1] = get_sbits(&s->gb, coeff_prec);
+ }
+
+ if ((ret = decode_residuals(s, decoded, pred_order)) < 0)
+ return ret;
+
+ if ( ( s->buggy_lpc && s->flac_stream_info.bps <= 16)
+ || ( !s->buggy_lpc && bps <= 16
+ && bps + coeff_prec + av_log2(pred_order) <= 32)) {
+ s->dsp.lpc16(decoded, coeffs, pred_order, qlevel, s->blocksize);
+ } else {
+ s->dsp.lpc32(decoded, coeffs, pred_order, qlevel, s->blocksize);
+ if (s->flac_stream_info.bps <= 16)
+ lpc_analyze_remodulate(decoded, coeffs, pred_order, qlevel, s->blocksize, bps);
+ }
+
+ return 0;
+}
+
+static inline int decode_subframe(FLACContext *s, int channel)
+{
+ int32_t *decoded = s->decoded[channel];
+ int type, wasted = 0;
+ int bps = s->flac_stream_info.bps;
+ int i, tmp, ret;
+
+ if (channel == 0) {
+ if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE)
+ bps++;
+ } else {
+ if (s->ch_mode == FLAC_CHMODE_LEFT_SIDE || s->ch_mode == FLAC_CHMODE_MID_SIDE)
+ bps++;
+ }
+
+ if (get_bits1(&s->gb)) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid subframe padding\n");
+ return AVERROR_INVALIDDATA;
+ }
+ type = get_bits(&s->gb, 6);
+
+ if (get_bits1(&s->gb)) {
+ int left = get_bits_left(&s->gb);
+ if ( left <= 0 ||
+ (left < bps && !show_bits_long(&s->gb, left)) ||
+ !show_bits_long(&s->gb, bps)) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid number of wasted bits > available bits (%d) - left=%d\n",
+ bps, left);
+ return AVERROR_INVALIDDATA;
+ }
+ wasted = 1 + get_unary(&s->gb, 1, get_bits_left(&s->gb));
+ bps -= wasted;
+ }
+ if (bps > 32) {
+ avpriv_report_missing_feature(s->avctx, "Decorrelated bit depth > 32");
+ return AVERROR_PATCHWELCOME;
+ }
+
+//FIXME use av_log2 for types
+ if (type == 0) {
+ tmp = get_sbits_long(&s->gb, bps);
+ for (i = 0; i < s->blocksize; i++)
+ decoded[i] = tmp;
+ } else if (type == 1) {
+ for (i = 0; i < s->blocksize; i++)
+ decoded[i] = get_sbits_long(&s->gb, bps);
+ } else if ((type >= 8) && (type <= 12)) {
+ if ((ret = decode_subframe_fixed(s, decoded, type & ~0x8, bps)) < 0)
+ return ret;
+ } else if (type >= 32) {
+ if ((ret = decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps)) < 0)
+ return ret;
+ } else {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (wasted) {
+ int i;
+ for (i = 0; i < s->blocksize; i++)
+ decoded[i] = (unsigned)decoded[i] << wasted;
+ }
+
+ return 0;
+}
+
+static int decode_frame(FLACContext *s)
+{
+ int i, ret;
+ GetBitContext *gb = &s->gb;
+ FLACFrameInfo fi;
+
+ if ((ret = ff_flac_decode_frame_header(s->avctx, gb, &fi, 0)) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid frame header\n");
+ return ret;
+ }
+
+ if ( s->flac_stream_info.channels
+ && fi.channels != s->flac_stream_info.channels
+ && s->got_streaminfo) {
+ s->flac_stream_info.channels = s->avctx->channels = fi.channels;
+ ff_flac_set_channel_layout(s->avctx);
+ ret = allocate_buffers(s);
+ if (ret < 0)
+ return ret;
+ }
+ s->flac_stream_info.channels = s->avctx->channels = fi.channels;
+ if (!s->avctx->channel_layout)
+ ff_flac_set_channel_layout(s->avctx);
+ s->ch_mode = fi.ch_mode;
+
+ if (!s->flac_stream_info.bps && !fi.bps) {
+ av_log(s->avctx, AV_LOG_ERROR, "bps not found in STREAMINFO or frame header\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (!fi.bps) {
+ fi.bps = s->flac_stream_info.bps;
+ } else if (s->flac_stream_info.bps && fi.bps != s->flac_stream_info.bps) {
+ av_log(s->avctx, AV_LOG_ERROR, "switching bps mid-stream is not "
+ "supported\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!s->flac_stream_info.bps) {
+ s->flac_stream_info.bps = s->avctx->bits_per_raw_sample = fi.bps;
+ flac_set_bps(s);
+ }
+
+ if (!s->flac_stream_info.max_blocksize)
+ s->flac_stream_info.max_blocksize = FLAC_MAX_BLOCKSIZE;
+ if (fi.blocksize > s->flac_stream_info.max_blocksize) {
+ av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", fi.blocksize,
+ s->flac_stream_info.max_blocksize);
+ return AVERROR_INVALIDDATA;
+ }
+ s->blocksize = fi.blocksize;
+
+ if (!s->flac_stream_info.samplerate && !fi.samplerate) {
+ av_log(s->avctx, AV_LOG_ERROR, "sample rate not found in STREAMINFO"
+ " or frame header\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (fi.samplerate == 0)
+ fi.samplerate = s->flac_stream_info.samplerate;
+ s->flac_stream_info.samplerate = s->avctx->sample_rate = fi.samplerate;
+
+ if (!s->got_streaminfo) {
+ ret = allocate_buffers(s);
+ if (ret < 0)
+ return ret;
+ s->got_streaminfo = 1;
+ dump_headers(s->avctx, &s->flac_stream_info);
+ }
+ ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt,
+ s->flac_stream_info.channels, s->flac_stream_info.bps);
+
+// dump_headers(s->avctx, &s->flac_stream_info);
+
+ /* subframes */
+ for (i = 0; i < s->flac_stream_info.channels; i++) {
+ if ((ret = decode_subframe(s, i)) < 0)
+ return ret;
+ }
+
+ align_get_bits(gb);
+
+ /* frame footer */
+ skip_bits(gb, 16); /* data crc */
+
+ return 0;
+}
+
+static int flac_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ AVFrame *frame = data;
+ ThreadFrame tframe = { .f = data };
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ FLACContext *s = avctx->priv_data;
+ int bytes_read = 0;
+ int ret;
+
+ *got_frame_ptr = 0;
+
+ if (s->flac_stream_info.max_framesize == 0) {
+ s->flac_stream_info.max_framesize =
+ ff_flac_get_max_frame_size(s->flac_stream_info.max_blocksize ? s->flac_stream_info.max_blocksize : FLAC_MAX_BLOCKSIZE,
+ FLAC_MAX_CHANNELS, 32);
+ }
+
+ if (buf_size > 5 && !memcmp(buf, "\177FLAC", 5)) {
+ av_log(s->avctx, AV_LOG_DEBUG, "skipping flac header packet 1\n");
+ return buf_size;
+ }
+
+ if (buf_size > 0 && (*buf & 0x7F) == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
+ av_log(s->avctx, AV_LOG_DEBUG, "skipping vorbis comment\n");
+ return buf_size;
+ }
+
+ /* check that there is at least the smallest decodable amount of data.
+ this amount corresponds to the smallest valid FLAC frame possible.
+ FF F8 69 02 00 00 9A 00 00 34 46 */
+ if (buf_size < FLAC_MIN_FRAME_SIZE)
+ return buf_size;
+
+ /* check for inline header */
+ if (AV_RB32(buf) == MKBETAG('f','L','a','C')) {
+ if (!s->got_streaminfo && (ret = parse_streaminfo(s, buf, buf_size))) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid header\n");
+ return ret;
+ }
+ return get_metadata_size(buf, buf_size);
+ }
+
+ /* decode frame */
+ if ((ret = init_get_bits8(&s->gb, buf, buf_size)) < 0)
+ return ret;
+ if ((ret = decode_frame(s)) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n");
+ return ret;
+ }
+ bytes_read = get_bits_count(&s->gb)/8;
+
+ if ((s->avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_COMPLIANT)) &&
+ av_crc(av_crc_get_table(AV_CRC_16_ANSI),
+ 0, buf, bytes_read)) {
+ av_log(s->avctx, AV_LOG_ERROR, "CRC error at PTS %"PRId64"\n", avpkt->pts);
+ if (s->avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* get output buffer */
+ frame->nb_samples = s->blocksize;
+ if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
+ return ret;
+
+ s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded,
+ s->flac_stream_info.channels,
+ s->blocksize, s->sample_shift);
+
+ if (bytes_read > buf_size) {
+ av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size);
+ return AVERROR_INVALIDDATA;
+ }
+ if (bytes_read < buf_size) {
+ av_log(s->avctx, AV_LOG_DEBUG, "underread: %d orig size: %d\n",
+ buf_size - bytes_read, buf_size);
+ }
+
+ *got_frame_ptr = 1;
+
+ return bytes_read;
+}
+
+static int init_thread_copy(AVCodecContext *avctx)
+{
+ FLACContext *s = avctx->priv_data;
+ s->decoded_buffer = NULL;
+ s->decoded_buffer_size = 0;
+ s->avctx = avctx;
+ if (s->flac_stream_info.max_blocksize)
+ return allocate_buffers(s);
+ return 0;
+}
+
+static av_cold int flac_decode_close(AVCodecContext *avctx)
+{
+ FLACContext *s = avctx->priv_data;
+
+ av_freep(&s->decoded_buffer);
+
+ return 0;
+}
+
+static const AVOption options[] = {
+{ "use_buggy_lpc", "emulate old buggy lavc behavior", offsetof(FLACContext, buggy_lpc), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM },
+{ NULL },
+};
+
+static const AVClass flac_decoder_class = {
+ "FLAC decoder",
+ av_default_item_name,
+ options,
+ LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_flac_decoder = {
+ .name = "flac",
+ .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_FLAC,
+ .priv_data_size = sizeof(FLACContext),
+ .init = flac_decode_init,
+ .close = flac_decode_close,
+ .decode = flac_decode_frame,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
+ .capabilities = 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,
+ AV_SAMPLE_FMT_S32P,
+ AV_SAMPLE_FMT_NONE },
+ .priv_class = &flac_decoder_class,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/flacdsp.c b/ffmpeg-2-8-12/libavcodec/flacdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flacdsp.c
rename to ffmpeg-2-8-12/libavcodec/flacdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/flacdsp.h b/ffmpeg-2-8-12/libavcodec/flacdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flacdsp.h
rename to ffmpeg-2-8-12/libavcodec/flacdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/flacdsp_lpc_template.c b/ffmpeg-2-8-12/libavcodec/flacdsp_lpc_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flacdsp_lpc_template.c
rename to ffmpeg-2-8-12/libavcodec/flacdsp_lpc_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/flacdsp_template.c b/ffmpeg-2-8-12/libavcodec/flacdsp_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flacdsp_template.c
rename to ffmpeg-2-8-12/libavcodec/flacdsp_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/flacenc.c b/ffmpeg-2-8-12/libavcodec/flacenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flacenc.c
rename to ffmpeg-2-8-12/libavcodec/flacenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/flashsv.c b/ffmpeg-2-8-12/libavcodec/flashsv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flashsv.c
rename to ffmpeg-2-8-12/libavcodec/flashsv.c
diff --git a/ffmpeg-2-8-11/libavcodec/flashsv2enc.c b/ffmpeg-2-8-12/libavcodec/flashsv2enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flashsv2enc.c
rename to ffmpeg-2-8-12/libavcodec/flashsv2enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/flashsvenc.c b/ffmpeg-2-8-12/libavcodec/flashsvenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flashsvenc.c
rename to ffmpeg-2-8-12/libavcodec/flashsvenc.c
diff --git a/ffmpeg-2-8-12/libavcodec/flicvideo.c b/ffmpeg-2-8-12/libavcodec/flicvideo.c
new file mode 100644
index 0000000..6f0961c
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/flicvideo.c
@@ -0,0 +1,823 @@
+/*
+ * FLI/FLC Animation Video Decoder
+ * Copyright (c) 2003, 2004 The FFmpeg Project
+ *
+ * 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
+ * Autodesk Animator FLI/FLC Video Decoder
+ * by Mike Melanson (melanson at pcisys.net)
+ * for more information on the .fli/.flc file format and all of its many
+ * variations, visit:
+ * http://www.compuphase.com/flic.htm
+ *
+ * This decoder outputs PAL8/RGB555/RGB565 and maybe one day RGB24
+ * colorspace data, depending on the FLC. To use this decoder, be
+ * sure that your demuxer sends the FLI file header to the decoder via
+ * the extradata chunk in AVCodecContext. The chunk should be 128 bytes
+ * large. The only exception is for FLI files from the game "Magic Carpet",
+ * in which the header is only 12 bytes.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+#include "mathops.h"
+
+#define FLI_256_COLOR 4
+#define FLI_DELTA 7
+#define FLI_COLOR 11
+#define FLI_LC 12
+#define FLI_BLACK 13
+#define FLI_BRUN 15
+#define FLI_COPY 16
+#define FLI_MINI 18
+#define FLI_DTA_BRUN 25
+#define FLI_DTA_COPY 26
+#define FLI_DTA_LC 27
+
+#define FLI_TYPE_CODE (0xAF11)
+#define FLC_FLX_TYPE_CODE (0xAF12)
+#define FLC_DTA_TYPE_CODE (0xAF44) /* Marks an "Extended FLC" comes from Dave's Targa Animator (DTA) */
+#define FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE (0xAF13)
+
+#define CHECK_PIXEL_PTR(n) \
+ if (pixel_ptr + n > pixel_limit) { \
+ av_log (s->avctx, AV_LOG_ERROR, "Invalid pixel_ptr = %d > pixel_limit = %d\n", \
+ pixel_ptr + n, pixel_limit); \
+ return AVERROR_INVALIDDATA; \
+ } \
+
+typedef struct FlicDecodeContext {
+ AVCodecContext *avctx;
+ AVFrame *frame;
+
+ unsigned int palette[256];
+ int new_palette;
+ int fli_type; /* either 0xAF11 or 0xAF12, affects palette resolution */
+} FlicDecodeContext;
+
+static av_cold int flic_decode_init(AVCodecContext *avctx)
+{
+ FlicDecodeContext *s = avctx->priv_data;
+ unsigned char *fli_header = (unsigned char *)avctx->extradata;
+ int depth;
+
+ if (avctx->extradata_size != 0 &&
+ avctx->extradata_size != 12 &&
+ avctx->extradata_size != 128 &&
+ avctx->extradata_size != 256 &&
+ avctx->extradata_size != 904 &&
+ avctx->extradata_size != 1024) {
+ av_log(avctx, AV_LOG_ERROR, "Unexpected extradata size %d\n", avctx->extradata_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->avctx = avctx;
+
+ if (s->avctx->extradata_size == 12) {
+ /* special case for magic carpet FLIs */
+ s->fli_type = FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE;
+ depth = 8;
+ } else if (avctx->extradata_size == 1024) {
+ uint8_t *ptr = avctx->extradata;
+ int i;
+
+ for (i = 0; i < 256; i++) {
+ s->palette[i] = AV_RL32(ptr);
+ ptr += 4;
+ }
+ depth = 8;
+ /* FLI in MOV, see e.g. FFmpeg trac issue #626 */
+ } else if (avctx->extradata_size == 0 ||
+ avctx->extradata_size == 256 ||
+ /* see FFmpeg ticket #1234 */
+ avctx->extradata_size == 904) {
+ s->fli_type = FLI_TYPE_CODE;
+ depth = 8;
+ } else {
+ s->fli_type = AV_RL16(&fli_header[4]);
+ depth = AV_RL16(&fli_header[12]);
+ }
+
+ if (depth == 0) {
+ depth = 8; /* Some FLC generators set depth to zero, when they mean 8Bpp. Fix up here */
+ }
+
+ if ((s->fli_type == FLC_FLX_TYPE_CODE) && (depth == 16)) {
+ depth = 15; /* Original Autodesk FLX's say the depth is 16Bpp when it is really 15Bpp */
+ }
+
+ switch (depth) {
+ case 8 : avctx->pix_fmt = AV_PIX_FMT_PAL8; break;
+ case 15 : avctx->pix_fmt = AV_PIX_FMT_RGB555; break;
+ case 16 : avctx->pix_fmt = AV_PIX_FMT_RGB565; break;
+ case 24 : avctx->pix_fmt = AV_PIX_FMT_BGR24; /* Supposedly BGR, but havent any files to test with */
+ avpriv_request_sample(avctx, "24Bpp FLC/FLX");
+ return AVERROR_PATCHWELCOME;
+ default :
+ av_log(avctx, AV_LOG_ERROR, "Unknown FLC/FLX depth of %d Bpp is unsupported.\n",depth);
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
+
+ s->new_palette = 0;
+
+ return 0;
+}
+
+static int flic_decode_frame_8BPP(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ const uint8_t *buf, int buf_size)
+{
+ FlicDecodeContext *s = avctx->priv_data;
+
+ GetByteContext g2;
+ int pixel_ptr;
+ int palette_ptr;
+ unsigned char palette_idx1;
+ unsigned char palette_idx2;
+
+ unsigned int frame_size;
+ int num_chunks;
+
+ unsigned int chunk_size;
+ int chunk_type;
+
+ int i, j, ret;
+
+ int color_packets;
+ int color_changes;
+ int color_shift;
+ unsigned char r, g, b;
+
+ int lines;
+ int compressed_lines;
+ int starting_line;
+ signed short line_packets;
+ int y_ptr;
+ int byte_run;
+ int pixel_skip;
+ int pixel_countdown;
+ unsigned char *pixels;
+ unsigned int pixel_limit;
+
+ bytestream2_init(&g2, buf, buf_size);
+
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
+ return ret;
+
+ pixels = s->frame->data[0];
+ pixel_limit = s->avctx->height * s->frame->linesize[0];
+ if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + AV_INPUT_BUFFER_PADDING_SIZE))
+ return AVERROR_INVALIDDATA;
+ frame_size = bytestream2_get_le32(&g2);
+ if (frame_size > buf_size)
+ frame_size = buf_size;
+ bytestream2_skip(&g2, 2); /* skip the magic number */
+ num_chunks = bytestream2_get_le16(&g2);
+ bytestream2_skip(&g2, 8); /* skip padding */
+
+ if (frame_size < 16)
+ return AVERROR_INVALIDDATA;
+
+ frame_size -= 16;
+
+ /* iterate through the chunks */
+ while ((frame_size >= 6) && (num_chunks > 0) &&
+ bytestream2_get_bytes_left(&g2) >= 4) {
+ int stream_ptr_after_chunk;
+ chunk_size = bytestream2_get_le32(&g2);
+ if (chunk_size > frame_size) {
+ av_log(avctx, AV_LOG_WARNING,
+ "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
+ chunk_size = frame_size;
+ }
+ stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
+
+ chunk_type = bytestream2_get_le16(&g2);
+
+ switch (chunk_type) {
+ case FLI_256_COLOR:
+ case FLI_COLOR:
+ /* check special case: If this file is from the Magic Carpet
+ * game and uses 6-bit colors even though it reports 256-color
+ * chunks in a 0xAF12-type file (fli_type is set to 0xAF13 during
+ * initialization) */
+ if ((chunk_type == FLI_256_COLOR) && (s->fli_type != FLC_MAGIC_CARPET_SYNTHETIC_TYPE_CODE))
+ color_shift = 0;
+ else
+ color_shift = 2;
+ /* set up the palette */
+ color_packets = bytestream2_get_le16(&g2);
+ palette_ptr = 0;
+ for (i = 0; i < color_packets; i++) {
+ /* first byte is how many colors to skip */
+ palette_ptr += bytestream2_get_byte(&g2);
+
+ /* next byte indicates how many entries to change */
+ color_changes = bytestream2_get_byte(&g2);
+
+ /* if there are 0 color changes, there are actually 256 */
+ if (color_changes == 0)
+ color_changes = 256;
+
+ if (bytestream2_tell(&g2) + color_changes * 3 > stream_ptr_after_chunk)
+ break;
+
+ for (j = 0; j < color_changes; j++) {
+ unsigned int entry;
+
+ /* wrap around, for good measure */
+ if ((unsigned)palette_ptr >= 256)
+ palette_ptr = 0;
+
+ r = bytestream2_get_byte(&g2) << color_shift;
+ g = bytestream2_get_byte(&g2) << color_shift;
+ b = bytestream2_get_byte(&g2) << color_shift;
+ entry = 0xFFU << 24 | r << 16 | g << 8 | b;
+ if (color_shift == 2)
+ entry |= entry >> 6 & 0x30303;
+ if (s->palette[palette_ptr] != entry)
+ s->new_palette = 1;
+ s->palette[palette_ptr++] = entry;
+ }
+ }
+ break;
+
+ case FLI_DELTA:
+ y_ptr = 0;
+ compressed_lines = bytestream2_get_le16(&g2);
+ while (compressed_lines > 0) {
+ if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
+ break;
+ line_packets = bytestream2_get_le16(&g2);
+ if ((line_packets & 0xC000) == 0xC000) {
+ // line skip opcode
+ line_packets = -line_packets;
+ y_ptr += line_packets * s->frame->linesize[0];
+ } else if ((line_packets & 0xC000) == 0x4000) {
+ av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets);
+ } else if ((line_packets & 0xC000) == 0x8000) {
+ // "last byte" opcode
+ pixel_ptr= y_ptr + s->frame->linesize[0] - 1;
+ CHECK_PIXEL_PTR(0);
+ pixels[pixel_ptr] = line_packets & 0xff;
+ } else {
+ compressed_lines--;
+ pixel_ptr = y_ptr;
+ CHECK_PIXEL_PTR(0);
+ pixel_countdown = s->avctx->width;
+ for (i = 0; i < line_packets; i++) {
+ if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
+ break;
+ /* account for the skip bytes */
+ pixel_skip = bytestream2_get_byte(&g2);
+ pixel_ptr += pixel_skip;
+ pixel_countdown -= pixel_skip;
+ byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
+ if (byte_run < 0) {
+ byte_run = -byte_run;
+ palette_idx1 = bytestream2_get_byte(&g2);
+ palette_idx2 = bytestream2_get_byte(&g2);
+ CHECK_PIXEL_PTR(byte_run * 2);
+ for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
+ pixels[pixel_ptr++] = palette_idx1;
+ pixels[pixel_ptr++] = palette_idx2;
+ }
+ } else {
+ CHECK_PIXEL_PTR(byte_run * 2);
+ if (bytestream2_tell(&g2) + byte_run * 2 > stream_ptr_after_chunk)
+ break;
+ for (j = 0; j < byte_run * 2; j++, pixel_countdown--) {
+ pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
+ }
+ }
+ }
+
+ y_ptr += s->frame->linesize[0];
+ }
+ }
+ break;
+
+ case FLI_LC:
+ /* line compressed */
+ starting_line = bytestream2_get_le16(&g2);
+ y_ptr = 0;
+ y_ptr += starting_line * s->frame->linesize[0];
+
+ compressed_lines = bytestream2_get_le16(&g2);
+ while (compressed_lines > 0) {
+ pixel_ptr = y_ptr;
+ CHECK_PIXEL_PTR(0);
+ pixel_countdown = s->avctx->width;
+ if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
+ break;
+ line_packets = bytestream2_get_byte(&g2);
+ if (line_packets > 0) {
+ for (i = 0; i < line_packets; i++) {
+ /* account for the skip bytes */
+ if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
+ break;
+ pixel_skip = bytestream2_get_byte(&g2);
+ pixel_ptr += pixel_skip;
+ pixel_countdown -= pixel_skip;
+ byte_run = sign_extend(bytestream2_get_byte(&g2),8);
+ if (byte_run > 0) {
+ CHECK_PIXEL_PTR(byte_run);
+ if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
+ break;
+ for (j = 0; j < byte_run; j++, pixel_countdown--) {
+ pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
+ }
+ } else if (byte_run < 0) {
+ byte_run = -byte_run;
+ palette_idx1 = bytestream2_get_byte(&g2);
+ CHECK_PIXEL_PTR(byte_run);
+ for (j = 0; j < byte_run; j++, pixel_countdown--) {
+ pixels[pixel_ptr++] = palette_idx1;
+ }
+ }
+ }
+ }
+
+ y_ptr += s->frame->linesize[0];
+ compressed_lines--;
+ }
+ break;
+
+ case FLI_BLACK:
+ /* set the whole frame to color 0 (which is usually black) */
+ memset(pixels, 0,
+ s->frame->linesize[0] * s->avctx->height);
+ break;
+
+ case FLI_BRUN:
+ /* Byte run compression: This chunk type only occurs in the first
+ * FLI frame and it will update the entire frame. */
+ y_ptr = 0;
+ for (lines = 0; lines < s->avctx->height; lines++) {
+ pixel_ptr = y_ptr;
+ /* disregard the line packets; instead, iterate through all
+ * pixels on a row */
+ bytestream2_skip(&g2, 1);
+ pixel_countdown = s->avctx->width;
+ while (pixel_countdown > 0) {
+ if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
+ break;
+ byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
+ if (!byte_run) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid byte run value.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (byte_run > 0) {
+ palette_idx1 = bytestream2_get_byte(&g2);
+ CHECK_PIXEL_PTR(byte_run);
+ for (j = 0; j < byte_run; j++) {
+ pixels[pixel_ptr++] = palette_idx1;
+ pixel_countdown--;
+ if (pixel_countdown < 0)
+ av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
+ pixel_countdown, lines);
+ }
+ } else { /* copy bytes if byte_run < 0 */
+ byte_run = -byte_run;
+ CHECK_PIXEL_PTR(byte_run);
+ if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
+ break;
+ for (j = 0; j < byte_run; j++) {
+ pixels[pixel_ptr++] = bytestream2_get_byte(&g2);
+ pixel_countdown--;
+ if (pixel_countdown < 0)
+ av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
+ pixel_countdown, lines);
+ }
+ }
+ }
+
+ y_ptr += s->frame->linesize[0];
+ }
+ break;
+
+ case FLI_COPY:
+ /* copy the chunk (uncompressed frame) */
+ if (chunk_size - 6 != s->avctx->width * s->avctx->height) {
+ av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
+ "has incorrect size, skipping chunk\n", chunk_size - 6);
+ bytestream2_skip(&g2, chunk_size - 6);
+ } else {
+ for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
+ y_ptr += s->frame->linesize[0]) {
+ bytestream2_get_buffer(&g2, &pixels[y_ptr],
+ s->avctx->width);
+ }
+ }
+ break;
+
+ case FLI_MINI:
+ /* some sort of a thumbnail? disregard this chunk... */
+ break;
+
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
+ break;
+ }
+
+ if (stream_ptr_after_chunk - bytestream2_tell(&g2) > 0)
+ bytestream2_skip(&g2, stream_ptr_after_chunk - bytestream2_tell(&g2));
+
+ frame_size -= chunk_size;
+ num_chunks--;
+ }
+
+ /* by the end of the chunk, the stream ptr should equal the frame
+ * size (minus 1 or 2, possibly); if it doesn't, issue a warning */
+ if (bytestream2_get_bytes_left(&g2) > 2)
+ av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
+ "and final chunk ptr = %d\n", buf_size,
+ buf_size - bytestream2_get_bytes_left(&g2));
+
+ /* make the palette available on the way out */
+ memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
+ if (s->new_palette) {
+ s->frame->palette_has_changed = 1;
+ s->new_palette = 0;
+ }
+
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
+ return ret;
+
+ *got_frame = 1;
+
+ return buf_size;
+}
+
+static int flic_decode_frame_15_16BPP(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ const uint8_t *buf, int buf_size)
+{
+ /* Note, the only difference between the 15Bpp and 16Bpp */
+ /* Format is the pixel format, the packets are processed the same. */
+ FlicDecodeContext *s = avctx->priv_data;
+
+ GetByteContext g2;
+ int pixel_ptr;
+ unsigned char palette_idx1;
+
+ unsigned int frame_size;
+ int num_chunks;
+
+ unsigned int chunk_size;
+ int chunk_type;
+
+ int i, j, ret;
+
+ int lines;
+ int compressed_lines;
+ signed short line_packets;
+ int y_ptr;
+ int byte_run;
+ int pixel_skip;
+ int pixel_countdown;
+ unsigned char *pixels;
+ int pixel;
+ unsigned int pixel_limit;
+
+ bytestream2_init(&g2, buf, buf_size);
+
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
+ return ret;
+
+ pixels = s->frame->data[0];
+ pixel_limit = s->avctx->height * s->frame->linesize[0];
+
+ frame_size = bytestream2_get_le32(&g2);
+ bytestream2_skip(&g2, 2); /* skip the magic number */
+ num_chunks = bytestream2_get_le16(&g2);
+ bytestream2_skip(&g2, 8); /* skip padding */
+ if (frame_size > buf_size)
+ frame_size = buf_size;
+
+ if (frame_size < 16)
+ return AVERROR_INVALIDDATA;
+ frame_size -= 16;
+
+ /* iterate through the chunks */
+ while ((frame_size > 0) && (num_chunks > 0) &&
+ bytestream2_get_bytes_left(&g2) >= 4) {
+ int stream_ptr_after_chunk;
+ chunk_size = bytestream2_get_le32(&g2);
+ if (chunk_size > frame_size) {
+ av_log(avctx, AV_LOG_WARNING,
+ "Invalid chunk_size = %u > frame_size = %u\n", chunk_size, frame_size);
+ chunk_size = frame_size;
+ }
+ stream_ptr_after_chunk = bytestream2_tell(&g2) - 4 + chunk_size;
+
+ chunk_type = bytestream2_get_le16(&g2);
+
+
+ switch (chunk_type) {
+ case FLI_256_COLOR:
+ case FLI_COLOR:
+ /* For some reason, it seems that non-palettized flics do
+ * include one of these chunks in their first frame.
+ * Why I do not know, it seems rather extraneous. */
+ ff_dlog(avctx,
+ "Unexpected Palette chunk %d in non-palettized FLC\n",
+ chunk_type);
+ bytestream2_skip(&g2, chunk_size - 6);
+ break;
+
+ case FLI_DELTA:
+ case FLI_DTA_LC:
+ y_ptr = 0;
+ compressed_lines = bytestream2_get_le16(&g2);
+ while (compressed_lines > 0) {
+ if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
+ break;
+ line_packets = bytestream2_get_le16(&g2);
+ if (line_packets < 0) {
+ line_packets = -line_packets;
+ y_ptr += line_packets * s->frame->linesize[0];
+ } else {
+ compressed_lines--;
+ pixel_ptr = y_ptr;
+ CHECK_PIXEL_PTR(0);
+ pixel_countdown = s->avctx->width;
+ for (i = 0; i < line_packets; i++) {
+ /* account for the skip bytes */
+ if (bytestream2_tell(&g2) + 2 > stream_ptr_after_chunk)
+ break;
+ pixel_skip = bytestream2_get_byte(&g2);
+ pixel_ptr += (pixel_skip*2); /* Pixel is 2 bytes wide */
+ pixel_countdown -= pixel_skip;
+ byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
+ if (byte_run < 0) {
+ byte_run = -byte_run;
+ pixel = bytestream2_get_le16(&g2);
+ CHECK_PIXEL_PTR(2 * byte_run);
+ for (j = 0; j < byte_run; j++, pixel_countdown -= 2) {
+ *((signed short*)(&pixels[pixel_ptr])) = pixel;
+ pixel_ptr += 2;
+ }
+ } else {
+ if (bytestream2_tell(&g2) + 2*byte_run > stream_ptr_after_chunk)
+ break;
+ CHECK_PIXEL_PTR(2 * byte_run);
+ for (j = 0; j < byte_run; j++, pixel_countdown--) {
+ *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
+ pixel_ptr += 2;
+ }
+ }
+ }
+
+ y_ptr += s->frame->linesize[0];
+ }
+ }
+ break;
+
+ case FLI_LC:
+ av_log(avctx, AV_LOG_ERROR, "Unexpected FLI_LC chunk in non-palettized FLC\n");
+ bytestream2_skip(&g2, chunk_size - 6);
+ break;
+
+ case FLI_BLACK:
+ /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */
+ memset(pixels, 0x0000,
+ s->frame->linesize[0] * s->avctx->height);
+ break;
+
+ case FLI_BRUN:
+ y_ptr = 0;
+ for (lines = 0; lines < s->avctx->height; lines++) {
+ pixel_ptr = y_ptr;
+ /* disregard the line packets; instead, iterate through all
+ * pixels on a row */
+ bytestream2_skip(&g2, 1);
+ pixel_countdown = (s->avctx->width * 2);
+
+ while (pixel_countdown > 0) {
+ if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
+ break;
+ byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
+ if (byte_run > 0) {
+ palette_idx1 = bytestream2_get_byte(&g2);
+ CHECK_PIXEL_PTR(byte_run);
+ for (j = 0; j < byte_run; j++) {
+ pixels[pixel_ptr++] = palette_idx1;
+ pixel_countdown--;
+ if (pixel_countdown < 0)
+ av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) (linea%d)\n",
+ pixel_countdown, lines);
+ }
+ } else { /* copy bytes if byte_run < 0 */
+ byte_run = -byte_run;
+ if (bytestream2_tell(&g2) + byte_run > stream_ptr_after_chunk)
+ break;
+ CHECK_PIXEL_PTR(byte_run);
+ for (j = 0; j < byte_run; j++) {
+ palette_idx1 = bytestream2_get_byte(&g2);
+ pixels[pixel_ptr++] = palette_idx1;
+ pixel_countdown--;
+ if (pixel_countdown < 0)
+ av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d) at line %d\n",
+ pixel_countdown, lines);
+ }
+ }
+ }
+
+ /* Now FLX is strange, in that it is "byte" as opposed to "pixel" run length compressed.
+ * This does not give us any good opportunity to perform word endian conversion
+ * during decompression. So if it is required (i.e., this is not a LE target, we do
+ * a second pass over the line here, swapping the bytes.
+ */
+#if HAVE_BIGENDIAN
+ pixel_ptr = y_ptr;
+ pixel_countdown = s->avctx->width;
+ while (pixel_countdown > 0) {
+ *((signed short*)(&pixels[pixel_ptr])) = AV_RL16(&buf[pixel_ptr]);
+ pixel_ptr += 2;
+ }
+#endif
+ y_ptr += s->frame->linesize[0];
+ }
+ break;
+
+ case FLI_DTA_BRUN:
+ y_ptr = 0;
+ for (lines = 0; lines < s->avctx->height; lines++) {
+ pixel_ptr = y_ptr;
+ /* disregard the line packets; instead, iterate through all
+ * pixels on a row */
+ bytestream2_skip(&g2, 1);
+ pixel_countdown = s->avctx->width; /* Width is in pixels, not bytes */
+
+ while (pixel_countdown > 0) {
+ if (bytestream2_tell(&g2) + 1 > stream_ptr_after_chunk)
+ break;
+ byte_run = sign_extend(bytestream2_get_byte(&g2), 8);
+ if (byte_run > 0) {
+ pixel = bytestream2_get_le16(&g2);
+ CHECK_PIXEL_PTR(2 * byte_run);
+ for (j = 0; j < byte_run; j++) {
+ *((signed short*)(&pixels[pixel_ptr])) = pixel;
+ pixel_ptr += 2;
+ pixel_countdown--;
+ if (pixel_countdown < 0)
+ av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
+ pixel_countdown);
+ }
+ } else { /* copy pixels if byte_run < 0 */
+ byte_run = -byte_run;
+ if (bytestream2_tell(&g2) + 2 * byte_run > stream_ptr_after_chunk)
+ break;
+ CHECK_PIXEL_PTR(2 * byte_run);
+ for (j = 0; j < byte_run; j++) {
+ *((signed short*)(&pixels[pixel_ptr])) = bytestream2_get_le16(&g2);
+ pixel_ptr += 2;
+ pixel_countdown--;
+ if (pixel_countdown < 0)
+ av_log(avctx, AV_LOG_ERROR, "pixel_countdown < 0 (%d)\n",
+ pixel_countdown);
+ }
+ }
+ }
+
+ y_ptr += s->frame->linesize[0];
+ }
+ break;
+
+ case FLI_COPY:
+ case FLI_DTA_COPY:
+ /* copy the chunk (uncompressed frame) */
+ if (chunk_size - 6 > (unsigned int)(s->avctx->width * s->avctx->height)*2) {
+ av_log(avctx, AV_LOG_ERROR, "In chunk FLI_COPY : source data (%d bytes) " \
+ "bigger than image, skipping chunk\n", chunk_size - 6);
+ bytestream2_skip(&g2, chunk_size - 6);
+ } else {
+
+ for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height;
+ y_ptr += s->frame->linesize[0]) {
+
+ pixel_countdown = s->avctx->width;
+ pixel_ptr = 0;
+ while (pixel_countdown > 0) {
+ *((signed short*)(&pixels[y_ptr + pixel_ptr])) = bytestream2_get_le16(&g2);
+ pixel_ptr += 2;
+ pixel_countdown--;
+ }
+ }
+ }
+ break;
+
+ case FLI_MINI:
+ /* some sort of a thumbnail? disregard this chunk... */
+ bytestream2_skip(&g2, chunk_size - 6);
+ break;
+
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Unrecognized chunk type: %d\n", chunk_type);
+ break;
+ }
+
+ frame_size -= chunk_size;
+ num_chunks--;
+ }
+
+ /* by the end of the chunk, the stream ptr should equal the frame
+ * size (minus 1, possibly); if it doesn't, issue a warning */
+ if ((bytestream2_get_bytes_left(&g2) != 0) && (bytestream2_get_bytes_left(&g2) != 1))
+ av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \
+ "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2));
+
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
+ return ret;
+
+ *got_frame = 1;
+
+ return buf_size;
+}
+
+static int flic_decode_frame_24BPP(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ const uint8_t *buf, int buf_size)
+{
+ av_log(avctx, AV_LOG_ERROR, "24Bpp FLC Unsupported due to lack of test files.\n");
+ return AVERROR_PATCHWELCOME;
+}
+
+static int flic_decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
+ return flic_decode_frame_8BPP(avctx, data, got_frame,
+ buf, buf_size);
+ }
+ else if ((avctx->pix_fmt == AV_PIX_FMT_RGB555) ||
+ (avctx->pix_fmt == AV_PIX_FMT_RGB565)) {
+ return flic_decode_frame_15_16BPP(avctx, data, got_frame,
+ buf, buf_size);
+ }
+ else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
+ return flic_decode_frame_24BPP(avctx, data, got_frame,
+ buf, buf_size);
+ }
+
+ /* Should not get here, ever as the pix_fmt is processed */
+ /* in flic_decode_init and the above if should deal with */
+ /* the finite set of possibilites allowable by here. */
+ /* But in case we do, just error out. */
+ av_log(avctx, AV_LOG_ERROR, "Unknown FLC format, my science cannot explain how this happened.\n");
+ return AVERROR_BUG;
+}
+
+
+static av_cold int flic_decode_end(AVCodecContext *avctx)
+{
+ FlicDecodeContext *s = avctx->priv_data;
+
+ av_frame_free(&s->frame);
+
+ return 0;
+}
+
+AVCodec ff_flic_decoder = {
+ .name = "flic",
+ .long_name = NULL_IF_CONFIG_SMALL("Autodesk Animator Flic video"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_FLIC,
+ .priv_data_size = sizeof(FlicDecodeContext),
+ .init = flic_decode_init,
+ .close = flic_decode_end,
+ .decode = flic_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/flv.h b/ffmpeg-2-8-12/libavcodec/flv.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flv.h
rename to ffmpeg-2-8-12/libavcodec/flv.h
diff --git a/ffmpeg-2-8-11/libavcodec/flvdec.c b/ffmpeg-2-8-12/libavcodec/flvdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flvdec.c
rename to ffmpeg-2-8-12/libavcodec/flvdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/flvenc.c b/ffmpeg-2-8-12/libavcodec/flvenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/flvenc.c
rename to ffmpeg-2-8-12/libavcodec/flvenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/fmtconvert.c b/ffmpeg-2-8-12/libavcodec/fmtconvert.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fmtconvert.c
rename to ffmpeg-2-8-12/libavcodec/fmtconvert.c
diff --git a/ffmpeg-2-8-11/libavcodec/fmtconvert.h b/ffmpeg-2-8-12/libavcodec/fmtconvert.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fmtconvert.h
rename to ffmpeg-2-8-12/libavcodec/fmtconvert.h
diff --git a/ffmpeg-2-8-11/libavcodec/frame_thread_encoder.c b/ffmpeg-2-8-12/libavcodec/frame_thread_encoder.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/frame_thread_encoder.c
rename to ffmpeg-2-8-12/libavcodec/frame_thread_encoder.c
diff --git a/ffmpeg-2-8-11/libavcodec/frame_thread_encoder.h b/ffmpeg-2-8-12/libavcodec/frame_thread_encoder.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/frame_thread_encoder.h
rename to ffmpeg-2-8-12/libavcodec/frame_thread_encoder.h
diff --git a/ffmpeg-2-8-11/libavcodec/fraps.c b/ffmpeg-2-8-12/libavcodec/fraps.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/fraps.c
rename to ffmpeg-2-8-12/libavcodec/fraps.c
diff --git a/ffmpeg-2-8-11/libavcodec/frwu.c b/ffmpeg-2-8-12/libavcodec/frwu.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/frwu.c
rename to ffmpeg-2-8-12/libavcodec/frwu.c
diff --git a/ffmpeg-2-8-11/libavcodec/g2meet.c b/ffmpeg-2-8-12/libavcodec/g2meet.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/g2meet.c
rename to ffmpeg-2-8-12/libavcodec/g2meet.c
diff --git a/ffmpeg-2-8-12/libavcodec/g722.c b/ffmpeg-2-8-12/libavcodec/g722.c
new file mode 100644
index 0000000..ef7ca6d
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/g722.c
@@ -0,0 +1,163 @@
+/*
+ * G.722 ADPCM audio encoder/decoder
+ *
+ * Copyright (c) CMU 1993 Computer Science, Speech Group
+ * Chengxiang Lu and Alex Hauptmann
+ * Copyright (c) 2005 Steve Underwood <steveu at coppice.org>
+ * Copyright (c) 2009 Kenan Gillet
+ * Copyright (c) 2010 Martin Storsjo
+ *
+ * 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
+ * G.722 ADPCM audio codec
+ *
+ * This G.722 decoder is a bit-exact implementation of the ITU G.722
+ * specification for all three specified bitrates - 64000bps, 56000bps
+ * and 48000bps. It passes the ITU tests.
+ *
+ * @note For the 56000bps and 48000bps bitrates, the lowest 1 or 2 bits
+ * respectively of each byte are ignored.
+ */
+
+#include "mathops.h"
+#include "g722.h"
+
+static const int8_t sign_lookup[2] = { -1, 1 };
+
+static const int16_t inv_log2_table[32] = {
+ 2048, 2093, 2139, 2186, 2233, 2282, 2332, 2383,
+ 2435, 2489, 2543, 2599, 2656, 2714, 2774, 2834,
+ 2896, 2960, 3025, 3091, 3158, 3228, 3298, 3371,
+ 3444, 3520, 3597, 3676, 3756, 3838, 3922, 4008
+};
+static const int16_t high_log_factor_step[2] = { 798, -214 };
+const int16_t ff_g722_high_inv_quant[4] = { -926, -202, 926, 202 };
+/**
+ * low_log_factor_step[index] == wl[rl42[index]]
+ */
+static const int16_t low_log_factor_step[16] = {
+ -60, 3042, 1198, 538, 334, 172, 58, -30,
+ 3042, 1198, 538, 334, 172, 58, -30, -60
+};
+const int16_t ff_g722_low_inv_quant4[16] = {
+ 0, -2557, -1612, -1121, -786, -530, -323, -150,
+ 2557, 1612, 1121, 786, 530, 323, 150, 0
+};
+const int16_t ff_g722_low_inv_quant6[64] = {
+ -17, -17, -17, -17, -3101, -2738, -2376, -2088,
+ -1873, -1689, -1535, -1399, -1279, -1170, -1072, -982,
+ -899, -822, -750, -682, -618, -558, -501, -447,
+ -396, -347, -300, -254, -211, -170, -130, -91,
+ 3101, 2738, 2376, 2088, 1873, 1689, 1535, 1399,
+ 1279, 1170, 1072, 982, 899, 822, 750, 682,
+ 618, 558, 501, 447, 396, 347, 300, 254,
+ 211, 170, 130, 91, 54, 17, -54, -17
+};
+
+static inline void s_zero(int cur_diff, struct G722Band *band)
+{
+ int s_zero = 0;
+
+ #define ACCUM(k, x, d) do { \
+ int tmp = x; \
+ band->zero_mem[k] = ((band->zero_mem[k] * 255) >> 8) + \
+ d*((band->diff_mem[k]^cur_diff) < 0 ? -128 : 128); \
+ band->diff_mem[k] = tmp; \
+ s_zero += (tmp * band->zero_mem[k]) >> 15; \
+ } while (0)
+ if (cur_diff) {
+ ACCUM(5, band->diff_mem[4], 1);
+ ACCUM(4, band->diff_mem[3], 1);
+ ACCUM(3, band->diff_mem[2], 1);
+ ACCUM(2, band->diff_mem[1], 1);
+ ACCUM(1, band->diff_mem[0], 1);
+ ACCUM(0, cur_diff * 2, 1);
+ } else {
+ ACCUM(5, band->diff_mem[4], 0);
+ ACCUM(4, band->diff_mem[3], 0);
+ ACCUM(3, band->diff_mem[2], 0);
+ ACCUM(2, band->diff_mem[1], 0);
+ ACCUM(1, band->diff_mem[0], 0);
+ ACCUM(0, cur_diff * 2, 0);
+ }
+ #undef ACCUM
+ band->s_zero = s_zero;
+}
+
+/**
+ * adaptive predictor
+ *
+ * @param cur_diff the dequantized and scaled delta calculated from the
+ * current codeword
+ */
+static void do_adaptive_prediction(struct G722Band *band, const int cur_diff)
+{
+ int sg[2], limit, cur_qtzd_reconst;
+
+ const int cur_part_reconst = band->s_zero + cur_diff < 0;
+
+ sg[0] = sign_lookup[cur_part_reconst != band->part_reconst_mem[0]];
+ sg[1] = sign_lookup[cur_part_reconst == band->part_reconst_mem[1]];
+ band->part_reconst_mem[1] = band->part_reconst_mem[0];
+ band->part_reconst_mem[0] = cur_part_reconst;
+
+ band->pole_mem[1] = av_clip((sg[0] * av_clip(band->pole_mem[0], -8191, 8191) >> 5) +
+ (sg[1] * 128) + (band->pole_mem[1] * 127 >> 7), -12288, 12288);
+
+ limit = 15360 - band->pole_mem[1];
+ band->pole_mem[0] = av_clip(-192 * sg[0] + (band->pole_mem[0] * 255 >> 8), -limit, limit);
+
+ s_zero(cur_diff, band);
+
+ cur_qtzd_reconst = av_clip_int16((band->s_predictor + cur_diff) * 2);
+ band->s_predictor = av_clip_int16(band->s_zero +
+ (band->pole_mem[0] * cur_qtzd_reconst >> 15) +
+ (band->pole_mem[1] * band->prev_qtzd_reconst >> 15));
+ band->prev_qtzd_reconst = cur_qtzd_reconst;
+}
+
+static inline int linear_scale_factor(const int log_factor)
+{
+ const int wd1 = inv_log2_table[(log_factor >> 6) & 31];
+ const int shift = log_factor >> 11;
+ return shift < 0 ? wd1 >> -shift : wd1 << shift;
+}
+
+void ff_g722_update_low_predictor(struct G722Band *band, const int ilow)
+{
+ do_adaptive_prediction(band,
+ band->scale_factor * ff_g722_low_inv_quant4[ilow] >> 10);
+
+ // quantizer adaptation
+ band->log_factor = av_clip((band->log_factor * 127 >> 7) +
+ low_log_factor_step[ilow], 0, 18432);
+ band->scale_factor = linear_scale_factor(band->log_factor - (8 << 11));
+}
+
+void ff_g722_update_high_predictor(struct G722Band *band, const int dhigh,
+ const int ihigh)
+{
+ do_adaptive_prediction(band, dhigh);
+
+ // quantizer adaptation
+ band->log_factor = av_clip((band->log_factor * 127 >> 7) +
+ high_log_factor_step[ihigh&1], 0, 22528);
+ band->scale_factor = linear_scale_factor(band->log_factor - (10 << 11));
+}
diff --git a/ffmpeg-2-8-11/libavcodec/g722.h b/ffmpeg-2-8-12/libavcodec/g722.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/g722.h
rename to ffmpeg-2-8-12/libavcodec/g722.h
diff --git a/ffmpeg-2-8-11/libavcodec/g722dec.c b/ffmpeg-2-8-12/libavcodec/g722dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/g722dec.c
rename to ffmpeg-2-8-12/libavcodec/g722dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/g722dsp.c b/ffmpeg-2-8-12/libavcodec/g722dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/g722dsp.c
rename to ffmpeg-2-8-12/libavcodec/g722dsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/g722dsp.h b/ffmpeg-2-8-12/libavcodec/g722dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/g722dsp.h
rename to ffmpeg-2-8-12/libavcodec/g722dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/g722enc.c b/ffmpeg-2-8-12/libavcodec/g722enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/g722enc.c
rename to ffmpeg-2-8-12/libavcodec/g722enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/g723_1.c b/ffmpeg-2-8-12/libavcodec/g723_1.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/g723_1.c
rename to ffmpeg-2-8-12/libavcodec/g723_1.c
diff --git a/ffmpeg-2-8-11/libavcodec/g723_1_data.h b/ffmpeg-2-8-12/libavcodec/g723_1_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/g723_1_data.h
rename to ffmpeg-2-8-12/libavcodec/g723_1_data.h
diff --git a/ffmpeg-2-8-12/libavcodec/g726.c b/ffmpeg-2-8-12/libavcodec/g726.c
new file mode 100644
index 0000000..4be44b2
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/g726.c
@@ -0,0 +1,496 @@
+/*
+ * G.726 ADPCM audio codec
+ * Copyright (c) 2004 Roman Shaposhnik
+ *
+ * This is a very straightforward rendition of the G.726
+ * Section 4 "Computational Details".
+ *
+ * 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 <limits.h>
+
+#include "libavutil/channel_layout.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "get_bits.h"
+#include "put_bits.h"
+
+/**
+ * G.726 11bit float.
+ * G.726 Standard uses rather odd 11bit floating point arithmetic for
+ * numerous occasions. It's a mystery to me why they did it this way
+ * instead of simply using 32bit integer arithmetic.
+ */
+typedef struct Float11 {
+ uint8_t sign; /**< 1bit sign */
+ uint8_t exp; /**< 4bit exponent */
+ uint8_t mant; /**< 6bit mantissa */
+} Float11;
+
+static inline Float11* i2f(int i, Float11* f)
+{
+ f->sign = (i < 0);
+ if (f->sign)
+ i = -i;
+ f->exp = av_log2_16bit(i) + !!i;
+ f->mant = i? (i<<6) >> f->exp : 1<<5;
+ return f;
+}
+
+static inline int16_t mult(Float11* f1, Float11* f2)
+{
+ int res, exp;
+
+ exp = f1->exp + f2->exp;
+ res = (((f1->mant * f2->mant) + 0x30) >> 4);
+ res = exp > 19 ? res << (exp - 19) : res >> (19 - exp);
+ return (f1->sign ^ f2->sign) ? -res : res;
+}
+
+static inline int sgn(int value)
+{
+ return (value < 0) ? -1 : 1;
+}
+
+typedef struct G726Tables {
+ const int* quant; /**< quantization table */
+ const int16_t* iquant; /**< inverse quantization table */
+ const int16_t* W; /**< special table #1 ;-) */
+ const uint8_t* F; /**< special table #2 */
+} G726Tables;
+
+typedef struct G726Context {
+ AVClass *class;
+ G726Tables tbls; /**< static tables needed for computation */
+
+ Float11 sr[2]; /**< prev. reconstructed samples */
+ Float11 dq[6]; /**< prev. difference */
+ int a[2]; /**< second order predictor coeffs */
+ int b[6]; /**< sixth order predictor coeffs */
+ int pk[2]; /**< signs of prev. 2 sez + dq */
+
+ int ap; /**< scale factor control */
+ int yu; /**< fast scale factor */
+ int yl; /**< slow scale factor */
+ int dms; /**< short average magnitude of F[i] */
+ int dml; /**< long average magnitude of F[i] */
+ int td; /**< tone detect */
+
+ int se; /**< estimated signal for the next iteration */
+ int sez; /**< estimated second order prediction */
+ int y; /**< quantizer scaling factor for the next iteration */
+ int code_size;
+ int little_endian; /**< little-endian bitstream as used in aiff and Sun AU */
+} G726Context;
+
+static const int quant_tbl16[] = /**< 16kbit/s 2bits per sample */
+ { 260, INT_MAX };
+static const int16_t iquant_tbl16[] =
+ { 116, 365, 365, 116 };
+static const int16_t W_tbl16[] =
+ { -22, 439, 439, -22 };
+static const uint8_t F_tbl16[] =
+ { 0, 7, 7, 0 };
+
+static const int quant_tbl24[] = /**< 24kbit/s 3bits per sample */
+ { 7, 217, 330, INT_MAX };
+static const int16_t iquant_tbl24[] =
+ { INT16_MIN, 135, 273, 373, 373, 273, 135, INT16_MIN };
+static const int16_t W_tbl24[] =
+ { -4, 30, 137, 582, 582, 137, 30, -4 };
+static const uint8_t F_tbl24[] =
+ { 0, 1, 2, 7, 7, 2, 1, 0 };
+
+static const int quant_tbl32[] = /**< 32kbit/s 4bits per sample */
+ { -125, 79, 177, 245, 299, 348, 399, INT_MAX };
+static const int16_t iquant_tbl32[] =
+ { INT16_MIN, 4, 135, 213, 273, 323, 373, 425,
+ 425, 373, 323, 273, 213, 135, 4, INT16_MIN };
+static const int16_t W_tbl32[] =
+ { -12, 18, 41, 64, 112, 198, 355, 1122,
+ 1122, 355, 198, 112, 64, 41, 18, -12};
+static const uint8_t F_tbl32[] =
+ { 0, 0, 0, 1, 1, 1, 3, 7, 7, 3, 1, 1, 1, 0, 0, 0 };
+
+static const int quant_tbl40[] = /**< 40kbit/s 5bits per sample */
+ { -122, -16, 67, 138, 197, 249, 297, 338,
+ 377, 412, 444, 474, 501, 527, 552, INT_MAX };
+static const int16_t iquant_tbl40[] =
+ { INT16_MIN, -66, 28, 104, 169, 224, 274, 318,
+ 358, 395, 429, 459, 488, 514, 539, 566,
+ 566, 539, 514, 488, 459, 429, 395, 358,
+ 318, 274, 224, 169, 104, 28, -66, INT16_MIN };
+static const int16_t W_tbl40[] =
+ { 14, 14, 24, 39, 40, 41, 58, 100,
+ 141, 179, 219, 280, 358, 440, 529, 696,
+ 696, 529, 440, 358, 280, 219, 179, 141,
+ 100, 58, 41, 40, 39, 24, 14, 14 };
+static const uint8_t F_tbl40[] =
+ { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 3, 4, 5, 6, 6,
+ 6, 6, 5, 4, 3, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
+
+static const G726Tables G726Tables_pool[] =
+ {{ quant_tbl16, iquant_tbl16, W_tbl16, F_tbl16 },
+ { quant_tbl24, iquant_tbl24, W_tbl24, F_tbl24 },
+ { quant_tbl32, iquant_tbl32, W_tbl32, F_tbl32 },
+ { quant_tbl40, iquant_tbl40, W_tbl40, F_tbl40 }};
+
+
+/**
+ * Para 4.2.2 page 18: Adaptive quantizer.
+ */
+static inline uint8_t quant(G726Context* c, int d)
+{
+ int sign, exp, i, dln;
+
+ sign = i = 0;
+ if (d < 0) {
+ sign = 1;
+ d = -d;
+ }
+ exp = av_log2_16bit(d);
+ dln = ((exp<<7) + (((d<<7)>>exp)&0x7f)) - (c->y>>2);
+
+ while (c->tbls.quant[i] < INT_MAX && c->tbls.quant[i] < dln)
+ ++i;
+
+ if (sign)
+ i = ~i;
+ if (c->code_size != 2 && i == 0) /* I'm not sure this is a good idea */
+ i = 0xff;
+
+ return i;
+}
+
+/**
+ * Para 4.2.3 page 22: Inverse adaptive quantizer.
+ */
+static inline int16_t inverse_quant(G726Context* c, int i)
+{
+ int dql, dex, dqt;
+
+ dql = c->tbls.iquant[i] + (c->y >> 2);
+ dex = (dql>>7) & 0xf; /* 4bit exponent */
+ dqt = (1<<7) + (dql & 0x7f); /* log2 -> linear */
+ return (dql < 0) ? 0 : ((dqt<<dex) >> 7);
+}
+
+static int16_t g726_decode(G726Context* c, int I)
+{
+ int dq, re_signal, pk0, fa1, i, tr, ylint, ylfrac, thr2, al, dq0;
+ Float11 f;
+ int I_sig= I >> (c->code_size - 1);
+
+ dq = inverse_quant(c, I);
+
+ /* Transition detect */
+ ylint = (c->yl >> 15);
+ ylfrac = (c->yl >> 10) & 0x1f;
+ thr2 = (ylint > 9) ? 0x1f << 10 : (0x20 + ylfrac) << ylint;
+ tr= (c->td == 1 && dq > ((3*thr2)>>2));
+
+ if (I_sig) /* get the sign */
+ dq = -dq;
+ re_signal = (int16_t)(c->se + dq);
+
+ /* Update second order predictor coefficient A2 and A1 */
+ pk0 = (c->sez + dq) ? sgn(c->sez + dq) : 0;
+ dq0 = dq ? sgn(dq) : 0;
+ if (tr) {
+ c->a[0] = 0;
+ c->a[1] = 0;
+ for (i=0; i<6; i++)
+ c->b[i] = 0;
+ } else {
+ /* This is a bit crazy, but it really is +255 not +256 */
+ fa1 = av_clip_intp2((-c->a[0]*c->pk[0]*pk0)>>5, 8);
+
+ c->a[1] += 128*pk0*c->pk[1] + fa1 - (c->a[1]>>7);
+ c->a[1] = av_clip(c->a[1], -12288, 12288);
+ c->a[0] += 64*3*pk0*c->pk[0] - (c->a[0] >> 8);
+ c->a[0] = av_clip(c->a[0], -(15360 - c->a[1]), 15360 - c->a[1]);
+
+ for (i=0; i<6; i++)
+ c->b[i] += 128*dq0*sgn(-c->dq[i].sign) - (c->b[i]>>8);
+ }
+
+ /* Update Dq and Sr and Pk */
+ c->pk[1] = c->pk[0];
+ c->pk[0] = pk0 ? pk0 : 1;
+ c->sr[1] = c->sr[0];
+ i2f(re_signal, &c->sr[0]);
+ for (i=5; i>0; i--)
+ c->dq[i] = c->dq[i-1];
+ i2f(dq, &c->dq[0]);
+ c->dq[0].sign = I_sig; /* Isn't it crazy ?!?! */
+
+ c->td = c->a[1] < -11776;
+
+ /* Update Ap */
+ c->dms += (c->tbls.F[I]<<4) + ((- c->dms) >> 5);
+ c->dml += (c->tbls.F[I]<<4) + ((- c->dml) >> 7);
+ if (tr)
+ c->ap = 256;
+ else {
+ c->ap += (-c->ap) >> 4;
+ if (c->y <= 1535 || c->td || abs((c->dms << 2) - c->dml) >= (c->dml >> 3))
+ c->ap += 0x20;
+ }
+
+ /* Update Yu and Yl */
+ c->yu = av_clip(c->y + c->tbls.W[I] + ((-c->y)>>5), 544, 5120);
+ c->yl += c->yu + ((-c->yl)>>6);
+
+ /* Next iteration for Y */
+ al = (c->ap >= 256) ? 1<<6 : c->ap >> 2;
+ c->y = (c->yl + (c->yu - (c->yl>>6))*al) >> 6;
+
+ /* Next iteration for SE and SEZ */
+ c->se = 0;
+ for (i=0; i<6; i++)
+ c->se += mult(i2f(c->b[i] >> 2, &f), &c->dq[i]);
+ c->sez = c->se >> 1;
+ for (i=0; i<2; i++)
+ c->se += mult(i2f(c->a[i] >> 2, &f), &c->sr[i]);
+ c->se >>= 1;
+
+ return av_clip(re_signal * 4, -0xffff, 0xffff);
+}
+
+static av_cold int g726_reset(G726Context *c)
+{
+ int i;
+
+ c->tbls = G726Tables_pool[c->code_size - 2];
+ for (i=0; i<2; i++) {
+ c->sr[i].mant = 1<<5;
+ c->pk[i] = 1;
+ }
+ for (i=0; i<6; i++) {
+ c->dq[i].mant = 1<<5;
+ }
+ c->yu = 544;
+ c->yl = 34816;
+
+ c->y = 544;
+
+ return 0;
+}
+
+#if CONFIG_ADPCM_G726_ENCODER
+static int16_t g726_encode(G726Context* c, int16_t sig)
+{
+ uint8_t i;
+
+ i = av_mod_uintp2(quant(c, sig/4 - c->se), c->code_size);
+ g726_decode(c, i);
+ return i;
+}
+
+/* Interfacing to the libavcodec */
+
+static av_cold int g726_encode_init(AVCodecContext *avctx)
+{
+ G726Context* c = avctx->priv_data;
+
+ if (avctx->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL &&
+ avctx->sample_rate != 8000) {
+ av_log(avctx, AV_LOG_ERROR, "Sample rates other than 8kHz are not "
+ "allowed when the compliance level is higher than unofficial. "
+ "Resample or reduce the compliance level.\n");
+ return AVERROR(EINVAL);
+ }
+ if (avctx->sample_rate <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid sample rate %d\n",
+ avctx->sample_rate);
+ return AVERROR(EINVAL);
+ }
+
+ if(avctx->channels != 1){
+ av_log(avctx, AV_LOG_ERROR, "Only mono is supported\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (avctx->bit_rate)
+ c->code_size = (avctx->bit_rate + avctx->sample_rate/2) / avctx->sample_rate;
+
+ c->code_size = av_clip(c->code_size, 2, 5);
+ avctx->bit_rate = c->code_size * avctx->sample_rate;
+ avctx->bits_per_coded_sample = c->code_size;
+
+ g726_reset(c);
+
+ /* select a frame size that will end on a byte boundary and have a size of
+ approximately 1024 bytes */
+ avctx->frame_size = ((int[]){ 4096, 2736, 2048, 1640 })[c->code_size - 2];
+
+ return 0;
+}
+
+static int g726_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
+ const AVFrame *frame, int *got_packet_ptr)
+{
+ G726Context *c = avctx->priv_data;
+ const int16_t *samples = (const int16_t *)frame->data[0];
+ PutBitContext pb;
+ int i, ret, out_size;
+
+ out_size = (frame->nb_samples * c->code_size + 7) / 8;
+ if ((ret = ff_alloc_packet2(avctx, avpkt, out_size, 0)) < 0)
+ return ret;
+ init_put_bits(&pb, avpkt->data, avpkt->size);
+
+ for (i = 0; i < frame->nb_samples; i++)
+ put_bits(&pb, c->code_size, g726_encode(c, *samples++));
+
+ flush_put_bits(&pb);
+
+ avpkt->size = out_size;
+ *got_packet_ptr = 1;
+ return 0;
+}
+
+#define OFFSET(x) offsetof(G726Context, x)
+#define AE AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+ { "code_size", "Bits per code", OFFSET(code_size), AV_OPT_TYPE_INT, { .i64 = 4 }, 2, 5, AE },
+ { NULL },
+};
+
+static const AVClass g726_class = {
+ .class_name = "g726",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVCodecDefault defaults[] = {
+ { "b", "0" },
+ { NULL },
+};
+
+AVCodec ff_adpcm_g726_encoder = {
+ .name = "g726",
+ .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_ADPCM_G726,
+ .priv_data_size = sizeof(G726Context),
+ .init = g726_encode_init,
+ .encode2 = g726_encode_frame,
+ .capabilities = AV_CODEC_CAP_SMALL_LAST_FRAME,
+ .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_NONE },
+ .priv_class = &g726_class,
+ .defaults = defaults,
+};
+#endif
+
+#if CONFIG_ADPCM_G726_DECODER || CONFIG_ADPCM_G726LE_DECODER
+static av_cold int g726_decode_init(AVCodecContext *avctx)
+{
+ G726Context* c = avctx->priv_data;
+
+ if(avctx->channels > 1){
+ avpriv_request_sample(avctx, "Decoding more than one channel");
+ return AVERROR_PATCHWELCOME;
+ }
+ avctx->channels = 1;
+ avctx->channel_layout = AV_CH_LAYOUT_MONO;
+
+ c->little_endian = !strcmp(avctx->codec->name, "g726le");
+
+ c->code_size = avctx->bits_per_coded_sample;
+ if (c->code_size < 2 || c->code_size > 5) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid number of bits %d\n", c->code_size);
+ return AVERROR(EINVAL);
+ }
+ g726_reset(c);
+
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ return 0;
+}
+
+static int g726_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ AVFrame *frame = data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ G726Context *c = avctx->priv_data;
+ int16_t *samples;
+ GetBitContext gb;
+ int out_samples, ret;
+
+ out_samples = buf_size * 8 / c->code_size;
+
+ /* get output buffer */
+ frame->nb_samples = out_samples;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+ samples = (int16_t *)frame->data[0];
+
+ init_get_bits(&gb, buf, buf_size * 8);
+
+ while (out_samples--)
+ *samples++ = g726_decode(c, c->little_endian ?
+ get_bits_le(&gb, c->code_size) :
+ get_bits(&gb, c->code_size));
+
+ if (get_bits_left(&gb) > 0)
+ av_log(avctx, AV_LOG_ERROR, "Frame invalidly split, missing parser?\n");
+
+ *got_frame_ptr = 1;
+
+ return buf_size;
+}
+
+static void g726_decode_flush(AVCodecContext *avctx)
+{
+ G726Context *c = avctx->priv_data;
+ g726_reset(c);
+}
+#endif
+
+#if CONFIG_ADPCM_G726_DECODER
+AVCodec ff_adpcm_g726_decoder = {
+ .name = "g726",
+ .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_ADPCM_G726,
+ .priv_data_size = sizeof(G726Context),
+ .init = g726_decode_init,
+ .decode = g726_decode_frame,
+ .flush = g726_decode_flush,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
+#endif
+
+#if CONFIG_ADPCM_G726LE_DECODER
+AVCodec ff_adpcm_g726le_decoder = {
+ .name = "g726le",
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_ADPCM_G726LE,
+ .priv_data_size = sizeof(G726Context),
+ .init = g726_decode_init,
+ .decode = g726_decode_frame,
+ .flush = g726_decode_flush,
+ .capabilities = AV_CODEC_CAP_DR1,
+ .long_name = NULL_IF_CONFIG_SMALL("G.726 ADPCM little-endian"),
+};
+#endif
diff --git a/ffmpeg-2-8-11/libavcodec/g729.h b/ffmpeg-2-8-12/libavcodec/g729.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/g729.h
rename to ffmpeg-2-8-12/libavcodec/g729.h
diff --git a/ffmpeg-2-8-11/libavcodec/g729_parser.c b/ffmpeg-2-8-12/libavcodec/g729_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/g729_parser.c
rename to ffmpeg-2-8-12/libavcodec/g729_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/g729data.h b/ffmpeg-2-8-12/libavcodec/g729data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/g729data.h
rename to ffmpeg-2-8-12/libavcodec/g729data.h
diff --git a/ffmpeg-2-8-11/libavcodec/g729dec.c b/ffmpeg-2-8-12/libavcodec/g729dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/g729dec.c
rename to ffmpeg-2-8-12/libavcodec/g729dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/g729postfilter.c b/ffmpeg-2-8-12/libavcodec/g729postfilter.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/g729postfilter.c
rename to ffmpeg-2-8-12/libavcodec/g729postfilter.c
diff --git a/ffmpeg-2-8-11/libavcodec/g729postfilter.h b/ffmpeg-2-8-12/libavcodec/g729postfilter.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/g729postfilter.h
rename to ffmpeg-2-8-12/libavcodec/g729postfilter.h
diff --git a/ffmpeg-2-8-11/libavcodec/get_bits.h b/ffmpeg-2-8-12/libavcodec/get_bits.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/get_bits.h
rename to ffmpeg-2-8-12/libavcodec/get_bits.h
diff --git a/ffmpeg-2-8-11/libavcodec/gif.c b/ffmpeg-2-8-12/libavcodec/gif.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/gif.c
rename to ffmpeg-2-8-12/libavcodec/gif.c
diff --git a/ffmpeg-2-8-11/libavcodec/gif.h b/ffmpeg-2-8-12/libavcodec/gif.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/gif.h
rename to ffmpeg-2-8-12/libavcodec/gif.h
diff --git a/ffmpeg-2-8-11/libavcodec/gifdec.c b/ffmpeg-2-8-12/libavcodec/gifdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/gifdec.c
rename to ffmpeg-2-8-12/libavcodec/gifdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/golomb-test.c b/ffmpeg-2-8-12/libavcodec/golomb-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/golomb-test.c
rename to ffmpeg-2-8-12/libavcodec/golomb-test.c
diff --git a/ffmpeg-2-8-11/libavcodec/golomb.c b/ffmpeg-2-8-12/libavcodec/golomb.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/golomb.c
rename to ffmpeg-2-8-12/libavcodec/golomb.c
diff --git a/ffmpeg-2-8-11/libavcodec/golomb.h b/ffmpeg-2-8-12/libavcodec/golomb.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/golomb.h
rename to ffmpeg-2-8-12/libavcodec/golomb.h
diff --git a/ffmpeg-2-8-11/libavcodec/gsm.h b/ffmpeg-2-8-12/libavcodec/gsm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/gsm.h
rename to ffmpeg-2-8-12/libavcodec/gsm.h
diff --git a/ffmpeg-2-8-11/libavcodec/gsm_parser.c b/ffmpeg-2-8-12/libavcodec/gsm_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/gsm_parser.c
rename to ffmpeg-2-8-12/libavcodec/gsm_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/gsmdec.c b/ffmpeg-2-8-12/libavcodec/gsmdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/gsmdec.c
rename to ffmpeg-2-8-12/libavcodec/gsmdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/gsmdec_data.c b/ffmpeg-2-8-12/libavcodec/gsmdec_data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/gsmdec_data.c
rename to ffmpeg-2-8-12/libavcodec/gsmdec_data.c
diff --git a/ffmpeg-2-8-11/libavcodec/gsmdec_data.h b/ffmpeg-2-8-12/libavcodec/gsmdec_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/gsmdec_data.h
rename to ffmpeg-2-8-12/libavcodec/gsmdec_data.h
diff --git a/ffmpeg-2-8-11/libavcodec/gsmdec_template.c b/ffmpeg-2-8-12/libavcodec/gsmdec_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/gsmdec_template.c
rename to ffmpeg-2-8-12/libavcodec/gsmdec_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/h261.c b/ffmpeg-2-8-12/libavcodec/h261.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h261.c
rename to ffmpeg-2-8-12/libavcodec/h261.c
diff --git a/ffmpeg-2-8-11/libavcodec/h261.h b/ffmpeg-2-8-12/libavcodec/h261.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h261.h
rename to ffmpeg-2-8-12/libavcodec/h261.h
diff --git a/ffmpeg-2-8-11/libavcodec/h261_parser.c b/ffmpeg-2-8-12/libavcodec/h261_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h261_parser.c
rename to ffmpeg-2-8-12/libavcodec/h261_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/h261data.c b/ffmpeg-2-8-12/libavcodec/h261data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h261data.c
rename to ffmpeg-2-8-12/libavcodec/h261data.c
diff --git a/ffmpeg-2-8-11/libavcodec/h261dec.c b/ffmpeg-2-8-12/libavcodec/h261dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h261dec.c
rename to ffmpeg-2-8-12/libavcodec/h261dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/h261enc.c b/ffmpeg-2-8-12/libavcodec/h261enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h261enc.c
rename to ffmpeg-2-8-12/libavcodec/h261enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/h263.c b/ffmpeg-2-8-12/libavcodec/h263.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h263.c
rename to ffmpeg-2-8-12/libavcodec/h263.c
diff --git a/ffmpeg-2-8-11/libavcodec/h263.h b/ffmpeg-2-8-12/libavcodec/h263.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h263.h
rename to ffmpeg-2-8-12/libavcodec/h263.h
diff --git a/ffmpeg-2-8-11/libavcodec/h263_parser.c b/ffmpeg-2-8-12/libavcodec/h263_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h263_parser.c
rename to ffmpeg-2-8-12/libavcodec/h263_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/h263_parser.h b/ffmpeg-2-8-12/libavcodec/h263_parser.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h263_parser.h
rename to ffmpeg-2-8-12/libavcodec/h263_parser.h
diff --git a/ffmpeg-2-8-11/libavcodec/h263data.c b/ffmpeg-2-8-12/libavcodec/h263data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h263data.c
rename to ffmpeg-2-8-12/libavcodec/h263data.c
diff --git a/ffmpeg-2-8-11/libavcodec/h263data.h b/ffmpeg-2-8-12/libavcodec/h263data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h263data.h
rename to ffmpeg-2-8-12/libavcodec/h263data.h
diff --git a/ffmpeg-2-8-11/libavcodec/h263dec.c b/ffmpeg-2-8-12/libavcodec/h263dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h263dec.c
rename to ffmpeg-2-8-12/libavcodec/h263dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/h263dsp.c b/ffmpeg-2-8-12/libavcodec/h263dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h263dsp.c
rename to ffmpeg-2-8-12/libavcodec/h263dsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/h263dsp.h b/ffmpeg-2-8-12/libavcodec/h263dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h263dsp.h
rename to ffmpeg-2-8-12/libavcodec/h263dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/h264.c b/ffmpeg-2-8-12/libavcodec/h264.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264.c
rename to ffmpeg-2-8-12/libavcodec/h264.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264.h b/ffmpeg-2-8-12/libavcodec/h264.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264.h
rename to ffmpeg-2-8-12/libavcodec/h264.h
diff --git a/ffmpeg-2-8-12/libavcodec/h264_cabac.c b/ffmpeg-2-8-12/libavcodec/h264_cabac.c
new file mode 100644
index 0000000..b0b1daf
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/h264_cabac.c
@@ -0,0 +1,2465 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... cabac decoding
+ * Copyright (c) 2003 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * H.264 / AVC / MPEG4 part10 cabac decoding.
+ * @author Michael Niedermayer <michaelni at gmx.at>
+ */
+
+#define CABAC(h) 1
+#define UNCHECKED_BITSTREAM_READER 1
+#define INT_BIT (CHAR_BIT * sizeof(int))
+
+#include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
+#include "libavutil/timer.h"
+#include "config.h"
+#include "cabac.h"
+#include "cabac_functions.h"
+#include "internal.h"
+#include "avcodec.h"
+#include "h264.h"
+#include "h264data.h"
+#include "h264_mvpred.h"
+#include "golomb.h"
+#include "mpegutils.h"
+
+#if ARCH_X86
+#include "x86/h264_i386.h"
+#endif
+
+/* Cabac pre state table */
+
+static const int8_t cabac_context_init_I[1024][2] =
+{
+ /* 0 - 10 */
+ { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 },
+ { 2, 54 }, { 3, 74 }, { -28,127 }, { -23, 104 },
+ { -6, 53 }, { -1, 54 }, { 7, 51 },
+
+ /* 11 - 23 unsused for I */
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
+ { 0, 0 },
+
+ /* 24- 39 */
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
+
+ /* 40 - 53 */
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
+ { 0, 0 }, { 0, 0 },
+
+ /* 54 - 59 */
+ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
+ { 0, 0 }, { 0, 0 },
+
+ /* 60 - 69 */
+ { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 },
+ { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 },
+ { 13, 41 }, { 3, 62 },
+
+ /* 70 -> 87 */
+ { 0, 11 }, { 1, 55 }, { 0, 69 }, { -17, 127 },
+ { -13, 102 },{ 0, 82 }, { -7, 74 }, { -21, 107 },
+ { -27, 127 },{ -31, 127 },{ -24, 127 }, { -18, 95 },
+ { -27, 127 },{ -21, 114 },{ -30, 127 }, { -17, 123 },
+ { -12, 115 },{ -16, 122 },
+
+ /* 88 -> 104 */
+ { -11, 115 },{ -12, 63 }, { -2, 68 }, { -15, 84 },
+ { -13, 104 },{ -3, 70 }, { -8, 93 }, { -10, 90 },
+ { -30, 127 },{ -1, 74 }, { -6, 97 }, { -7, 91 },
+ { -20, 127 },{ -4, 56 }, { -5, 82 }, { -7, 76 },
+ { -22, 125 },
+
+ /* 105 -> 135 */
+ { -7, 93 }, { -11, 87 }, { -3, 77 }, { -5, 71 },
+ { -4, 63 }, { -4, 68 }, { -12, 84 }, { -7, 62 },
+ { -7, 65 }, { 8, 61 }, { 5, 56 }, { -2, 66 },
+ { 1, 64 }, { 0, 61 }, { -2, 78 }, { 1, 50 },
+ { 7, 52 }, { 10, 35 }, { 0, 44 }, { 11, 38 },
+ { 1, 45 }, { 0, 46 }, { 5, 44 }, { 31, 17 },
+ { 1, 51 }, { 7, 50 }, { 28, 19 }, { 16, 33 },
+ { 14, 62 }, { -13, 108 },{ -15, 100 },
+
+ /* 136 -> 165 */
+ { -13, 101 },{ -13, 91 }, { -12, 94 }, { -10, 88 },
+ { -16, 84 }, { -10, 86 }, { -7, 83 }, { -13, 87 },
+ { -19, 94 }, { 1, 70 }, { 0, 72 }, { -5, 74 },
+ { 18, 59 }, { -8, 102 }, { -15, 100 }, { 0, 95 },
+ { -4, 75 }, { 2, 72 }, { -11, 75 }, { -3, 71 },
+ { 15, 46 }, { -13, 69 }, { 0, 62 }, { 0, 65 },
+ { 21, 37 }, { -15, 72 }, { 9, 57 }, { 16, 54 },
+ { 0, 62 }, { 12, 72 },
+
+ /* 166 -> 196 */
+ { 24, 0 }, { 15, 9 }, { 8, 25 }, { 13, 18 },
+ { 15, 9 }, { 13, 19 }, { 10, 37 }, { 12, 18 },
+ { 6, 29 }, { 20, 33 }, { 15, 30 }, { 4, 45 },
+ { 1, 58 }, { 0, 62 }, { 7, 61 }, { 12, 38 },
+ { 11, 45 }, { 15, 39 }, { 11, 42 }, { 13, 44 },
+ { 16, 45 }, { 12, 41 }, { 10, 49 }, { 30, 34 },
+ { 18, 42 }, { 10, 55 }, { 17, 51 }, { 17, 46 },
+ { 0, 89 }, { 26, -19 }, { 22, -17 },
+
+ /* 197 -> 226 */
+ { 26, -17 }, { 30, -25 }, { 28, -20 }, { 33, -23 },
+ { 37, -27 }, { 33, -23 }, { 40, -28 }, { 38, -17 },
+ { 33, -11 }, { 40, -15 }, { 41, -6 }, { 38, 1 },
+ { 41, 17 }, { 30, -6 }, { 27, 3 }, { 26, 22 },
+ { 37, -16 }, { 35, -4 }, { 38, -8 }, { 38, -3 },
+ { 37, 3 }, { 38, 5 }, { 42, 0 }, { 35, 16 },
+ { 39, 22 }, { 14, 48 }, { 27, 37 }, { 21, 60 },
+ { 12, 68 }, { 2, 97 },
+
+ /* 227 -> 251 */
+ { -3, 71 }, { -6, 42 }, { -5, 50 }, { -3, 54 },
+ { -2, 62 }, { 0, 58 }, { 1, 63 }, { -2, 72 },
+ { -1, 74 }, { -9, 91 }, { -5, 67 }, { -5, 27 },
+ { -3, 39 }, { -2, 44 }, { 0, 46 }, { -16, 64 },
+ { -8, 68 }, { -10, 78 }, { -6, 77 }, { -10, 86 },
+ { -12, 92 }, { -15, 55 }, { -10, 60 }, { -6, 62 },
+ { -4, 65 },
+
+ /* 252 -> 275 */
+ { -12, 73 }, { -8, 76 }, { -7, 80 }, { -9, 88 },
+ { -17, 110 },{ -11, 97 }, { -20, 84 }, { -11, 79 },
+ { -6, 73 }, { -4, 74 }, { -13, 86 }, { -13, 96 },
+ { -11, 97 }, { -19, 117 },{ -8, 78 }, { -5, 33 },
+ { -4, 48 }, { -2, 53 }, { -3, 62 }, { -13, 71 },
+ { -10, 79 }, { -12, 86 }, { -13, 90 }, { -14, 97 },
+
+ /* 276 a bit special (not used, bypass is used instead) */
+ { 0, 0 },
+
+ /* 277 -> 307 */
+ { -6, 93 }, { -6, 84 }, { -8, 79 }, { 0, 66 },
+ { -1, 71 }, { 0, 62 }, { -2, 60 }, { -2, 59 },
+ { -5, 75 }, { -3, 62 }, { -4, 58 }, { -9, 66 },
+ { -1, 79 }, { 0, 71 }, { 3, 68 }, { 10, 44 },
+ { -7, 62 }, { 15, 36 }, { 14, 40 }, { 16, 27 },
+ { 12, 29 }, { 1, 44 }, { 20, 36 }, { 18, 32 },
+ { 5, 42 }, { 1, 48 }, { 10, 62 }, { 17, 46 },
+ { 9, 64 }, { -12, 104 },{ -11, 97 },
+
+ /* 308 -> 337 */
+ { -16, 96 }, { -7, 88 }, { -8, 85 }, { -7, 85 },
+ { -9, 85 }, { -13, 88 }, { 4, 66 }, { -3, 77 },
+ { -3, 76 }, { -6, 76 }, { 10, 58 }, { -1, 76 },
+ { -1, 83 }, { -7, 99 }, { -14, 95 }, { 2, 95 },
+ { 0, 76 }, { -5, 74 }, { 0, 70 }, { -11, 75 },
+ { 1, 68 }, { 0, 65 }, { -14, 73 }, { 3, 62 },
+ { 4, 62 }, { -1, 68 }, { -13, 75 }, { 11, 55 },
+ { 5, 64 }, { 12, 70 },
+
+ /* 338 -> 368 */
+ { 15, 6 }, { 6, 19 }, { 7, 16 }, { 12, 14 },
+ { 18, 13 }, { 13, 11 }, { 13, 15 }, { 15, 16 },
+ { 12, 23 }, { 13, 23 }, { 15, 20 }, { 14, 26 },
+ { 14, 44 }, { 17, 40 }, { 17, 47 }, { 24, 17 },
+ { 21, 21 }, { 25, 22 }, { 31, 27 }, { 22, 29 },
+ { 19, 35 }, { 14, 50 }, { 10, 57 }, { 7, 63 },
+ { -2, 77 }, { -4, 82 }, { -3, 94 }, { 9, 69 },
+ { -12, 109 },{ 36, -35 }, { 36, -34 },
+
+ /* 369 -> 398 */
+ { 32, -26 }, { 37, -30 }, { 44, -32 }, { 34, -18 },
+ { 34, -15 }, { 40, -15 }, { 33, -7 }, { 35, -5 },
+ { 33, 0 }, { 38, 2 }, { 33, 13 }, { 23, 35 },
+ { 13, 58 }, { 29, -3 }, { 26, 0 }, { 22, 30 },
+ { 31, -7 }, { 35, -15 }, { 34, -3 }, { 34, 3 },
+ { 36, -1 }, { 34, 5 }, { 32, 11 }, { 35, 5 },
+ { 34, 12 }, { 39, 11 }, { 30, 29 }, { 34, 26 },
+ { 29, 39 }, { 19, 66 },
+
+ /* 399 -> 435 */
+ { 31, 21 }, { 31, 31 }, { 25, 50 },
+ { -17, 120 }, { -20, 112 }, { -18, 114 }, { -11, 85 },
+ { -15, 92 }, { -14, 89 }, { -26, 71 }, { -15, 81 },
+ { -14, 80 }, { 0, 68 }, { -14, 70 }, { -24, 56 },
+ { -23, 68 }, { -24, 50 }, { -11, 74 }, { 23, -13 },
+ { 26, -13 }, { 40, -15 }, { 49, -14 }, { 44, 3 },
+ { 45, 6 }, { 44, 34 }, { 33, 54 }, { 19, 82 },
+ { -3, 75 }, { -1, 23 }, { 1, 34 }, { 1, 43 },
+ { 0, 54 }, { -2, 55 }, { 0, 61 }, { 1, 64 },
+ { 0, 68 }, { -9, 92 },
+
+ /* 436 -> 459 */
+ { -14, 106 }, { -13, 97 }, { -15, 90 }, { -12, 90 },
+ { -18, 88 }, { -10, 73 }, { -9, 79 }, { -14, 86 },
+ { -10, 73 }, { -10, 70 }, { -10, 69 }, { -5, 66 },
+ { -9, 64 }, { -5, 58 }, { 2, 59 }, { 21, -10 },
+ { 24, -11 }, { 28, -8 }, { 28, -1 }, { 29, 3 },
+ { 29, 9 }, { 35, 20 }, { 29, 36 }, { 14, 67 },
+
+ /* 460 -> 1024 */
+ { -17, 123 }, { -12, 115 }, { -16, 122 }, { -11, 115 },
+ { -12, 63 }, { -2, 68 }, { -15, 84 }, { -13, 104 },
+ { -3, 70 }, { -8, 93 }, { -10, 90 }, { -30, 127 },
+ { -17, 123 }, { -12, 115 }, { -16, 122 }, { -11, 115 },
+ { -12, 63 }, { -2, 68 }, { -15, 84 }, { -13, 104 },
+ { -3, 70 }, { -8, 93 }, { -10, 90 }, { -30, 127 },
+ { -7, 93 }, { -11, 87 }, { -3, 77 }, { -5, 71 },
+ { -4, 63 }, { -4, 68 }, { -12, 84 }, { -7, 62 },
+ { -7, 65 }, { 8, 61 }, { 5, 56 }, { -2, 66 },
+ { 1, 64 }, { 0, 61 }, { -2, 78 }, { 1, 50 },
+ { 7, 52 }, { 10, 35 }, { 0, 44 }, { 11, 38 },
+ { 1, 45 }, { 0, 46 }, { 5, 44 }, { 31, 17 },
+ { 1, 51 }, { 7, 50 }, { 28, 19 }, { 16, 33 },
+ { 14, 62 }, { -13, 108 }, { -15, 100 }, { -13, 101 },
+ { -13, 91 }, { -12, 94 }, { -10, 88 }, { -16, 84 },
+ { -10, 86 }, { -7, 83 }, { -13, 87 }, { -19, 94 },
+ { 1, 70 }, { 0, 72 }, { -5, 74 }, { 18, 59 },
+ { -7, 93 }, { -11, 87 }, { -3, 77 }, { -5, 71 },
+ { -4, 63 }, { -4, 68 }, { -12, 84 }, { -7, 62 },
+ { -7, 65 }, { 8, 61 }, { 5, 56 }, { -2, 66 },
+ { 1, 64 }, { 0, 61 }, { -2, 78 }, { 1, 50 },
+ { 7, 52 }, { 10, 35 }, { 0, 44 }, { 11, 38 },
+ { 1, 45 }, { 0, 46 }, { 5, 44 }, { 31, 17 },
+ { 1, 51 }, { 7, 50 }, { 28, 19 }, { 16, 33 },
+ { 14, 62 }, { -13, 108 }, { -15, 100 }, { -13, 101 },
+ { -13, 91 }, { -12, 94 }, { -10, 88 }, { -16, 84 },
+ { -10, 86 }, { -7, 83 }, { -13, 87 }, { -19, 94 },
+ { 1, 70 }, { 0, 72 }, { -5, 74 }, { 18, 59 },
+ { 24, 0 }, { 15, 9 }, { 8, 25 }, { 13, 18 },
+ { 15, 9 }, { 13, 19 }, { 10, 37 }, { 12, 18 },
+ { 6, 29 }, { 20, 33 }, { 15, 30 }, { 4, 45 },
+ { 1, 58 }, { 0, 62 }, { 7, 61 }, { 12, 38 },
+ { 11, 45 }, { 15, 39 }, { 11, 42 }, { 13, 44 },
+ { 16, 45 }, { 12, 41 }, { 10, 49 }, { 30, 34 },
+ { 18, 42 }, { 10, 55 }, { 17, 51 }, { 17, 46 },
+ { 0, 89 }, { 26, -19 }, { 22, -17 }, { 26, -17 },
+ { 30, -25 }, { 28, -20 }, { 33, -23 }, { 37, -27 },
+ { 33, -23 }, { 40, -28 }, { 38, -17 }, { 33, -11 },
+ { 40, -15 }, { 41, -6 }, { 38, 1 }, { 41, 17 },
+ { 24, 0 }, { 15, 9 }, { 8, 25 }, { 13, 18 },
+ { 15, 9 }, { 13, 19 }, { 10, 37 }, { 12, 18 },
+ { 6, 29 }, { 20, 33 }, { 15, 30 }, { 4, 45 },
+ { 1, 58 }, { 0, 62 }, { 7, 61 }, { 12, 38 },
+ { 11, 45 }, { 15, 39 }, { 11, 42 }, { 13, 44 },
+ { 16, 45 }, { 12, 41 }, { 10, 49 }, { 30, 34 },
+ { 18, 42 }, { 10, 55 }, { 17, 51 }, { 17, 46 },
+ { 0, 89 }, { 26, -19 }, { 22, -17 }, { 26, -17 },
+ { 30, -25 }, { 28, -20 }, { 33, -23 }, { 37, -27 },
+ { 33, -23 }, { 40, -28 }, { 38, -17 }, { 33, -11 },
+ { 40, -15 }, { 41, -6 }, { 38, 1 }, { 41, 17 },
+ { -17, 120 }, { -20, 112 }, { -18, 114 }, { -11, 85 },
+ { -15, 92 }, { -14, 89 }, { -26, 71 }, { -15, 81 },
+ { -14, 80 }, { 0, 68 }, { -14, 70 }, { -24, 56 },
+ { -23, 68 }, { -24, 50 }, { -11, 74 }, { -14, 106 },
+ { -13, 97 }, { -15, 90 }, { -12, 90 }, { -18, 88 },
+ { -10, 73 }, { -9, 79 }, { -14, 86 }, { -10, 73 },
+ { -10, 70 }, { -10, 69 }, { -5, 66 }, { -9, 64 },
+ { -5, 58 }, { 2, 59 }, { 23, -13 }, { 26, -13 },
+ { 40, -15 }, { 49, -14 }, { 44, 3 }, { 45, 6 },
+ { 44, 34 }, { 33, 54 }, { 19, 82 }, { 21, -10 },
+ { 24, -11 }, { 28, -8 }, { 28, -1 }, { 29, 3 },
+ { 29, 9 }, { 35, 20 }, { 29, 36 }, { 14, 67 },
+ { -3, 75 }, { -1, 23 }, { 1, 34 }, { 1, 43 },
+ { 0, 54 }, { -2, 55 }, { 0, 61 }, { 1, 64 },
+ { 0, 68 }, { -9, 92 }, { -17, 120 }, { -20, 112 },
+ { -18, 114 }, { -11, 85 }, { -15, 92 }, { -14, 89 },
+ { -26, 71 }, { -15, 81 }, { -14, 80 }, { 0, 68 },
+ { -14, 70 }, { -24, 56 }, { -23, 68 }, { -24, 50 },
+ { -11, 74 }, { -14, 106 }, { -13, 97 }, { -15, 90 },
+ { -12, 90 }, { -18, 88 }, { -10, 73 }, { -9, 79 },
+ { -14, 86 }, { -10, 73 }, { -10, 70 }, { -10, 69 },
+ { -5, 66 }, { -9, 64 }, { -5, 58 }, { 2, 59 },
+ { 23, -13 }, { 26, -13 }, { 40, -15 }, { 49, -14 },
+ { 44, 3 }, { 45, 6 }, { 44, 34 }, { 33, 54 },
+ { 19, 82 }, { 21, -10 }, { 24, -11 }, { 28, -8 },
+ { 28, -1 }, { 29, 3 }, { 29, 9 }, { 35, 20 },
+ { 29, 36 }, { 14, 67 }, { -3, 75 }, { -1, 23 },
+ { 1, 34 }, { 1, 43 }, { 0, 54 }, { -2, 55 },
+ { 0, 61 }, { 1, 64 }, { 0, 68 }, { -9, 92 },
+ { -6, 93 }, { -6, 84 }, { -8, 79 }, { 0, 66 },
+ { -1, 71 }, { 0, 62 }, { -2, 60 }, { -2, 59 },
+ { -5, 75 }, { -3, 62 }, { -4, 58 }, { -9, 66 },
+ { -1, 79 }, { 0, 71 }, { 3, 68 }, { 10, 44 },
+ { -7, 62 }, { 15, 36 }, { 14, 40 }, { 16, 27 },
+ { 12, 29 }, { 1, 44 }, { 20, 36 }, { 18, 32 },
+ { 5, 42 }, { 1, 48 }, { 10, 62 }, { 17, 46 },
+ { 9, 64 }, { -12, 104 }, { -11, 97 }, { -16, 96 },
+ { -7, 88 }, { -8, 85 }, { -7, 85 }, { -9, 85 },
+ { -13, 88 }, { 4, 66 }, { -3, 77 }, { -3, 76 },
+ { -6, 76 }, { 10, 58 }, { -1, 76 }, { -1, 83 },
+ { -6, 93 }, { -6, 84 }, { -8, 79 }, { 0, 66 },
+ { -1, 71 }, { 0, 62 }, { -2, 60 }, { -2, 59 },
+ { -5, 75 }, { -3, 62 }, { -4, 58 }, { -9, 66 },
+ { -1, 79 }, { 0, 71 }, { 3, 68 }, { 10, 44 },
+ { -7, 62 }, { 15, 36 }, { 14, 40 }, { 16, 27 },
+ { 12, 29 }, { 1, 44 }, { 20, 36 }, { 18, 32 },
+ { 5, 42 }, { 1, 48 }, { 10, 62 }, { 17, 46 },
+ { 9, 64 }, { -12, 104 }, { -11, 97 }, { -16, 96 },
+ { -7, 88 }, { -8, 85 }, { -7, 85 }, { -9, 85 },
+ { -13, 88 }, { 4, 66 }, { -3, 77 }, { -3, 76 },
+ { -6, 76 }, { 10, 58 }, { -1, 76 }, { -1, 83 },
+ { 15, 6 }, { 6, 19 }, { 7, 16 }, { 12, 14 },
+ { 18, 13 }, { 13, 11 }, { 13, 15 }, { 15, 16 },
+ { 12, 23 }, { 13, 23 }, { 15, 20 }, { 14, 26 },
+ { 14, 44 }, { 17, 40 }, { 17, 47 }, { 24, 17 },
+ { 21, 21 }, { 25, 22 }, { 31, 27 }, { 22, 29 },
+ { 19, 35 }, { 14, 50 }, { 10, 57 }, { 7, 63 },
+ { -2, 77 }, { -4, 82 }, { -3, 94 }, { 9, 69 },
+ { -12, 109 }, { 36, -35 }, { 36, -34 }, { 32, -26 },
+ { 37, -30 }, { 44, -32 }, { 34, -18 }, { 34, -15 },
+ { 40, -15 }, { 33, -7 }, { 35, -5 }, { 33, 0 },
+ { 38, 2 }, { 33, 13 }, { 23, 35 }, { 13, 58 },
+ { 15, 6 }, { 6, 19 }, { 7, 16 }, { 12, 14 },
+ { 18, 13 }, { 13, 11 }, { 13, 15 }, { 15, 16 },
+ { 12, 23 }, { 13, 23 }, { 15, 20 }, { 14, 26 },
+ { 14, 44 }, { 17, 40 }, { 17, 47 }, { 24, 17 },
+ { 21, 21 }, { 25, 22 }, { 31, 27 }, { 22, 29 },
+ { 19, 35 }, { 14, 50 }, { 10, 57 }, { 7, 63 },
+ { -2, 77 }, { -4, 82 }, { -3, 94 }, { 9, 69 },
+ { -12, 109 }, { 36, -35 }, { 36, -34 }, { 32, -26 },
+ { 37, -30 }, { 44, -32 }, { 34, -18 }, { 34, -15 },
+ { 40, -15 }, { 33, -7 }, { 35, -5 }, { 33, 0 },
+ { 38, 2 }, { 33, 13 }, { 23, 35 }, { 13, 58 },
+ { -3, 71 }, { -6, 42 }, { -5, 50 }, { -3, 54 },
+ { -2, 62 }, { 0, 58 }, { 1, 63 }, { -2, 72 },
+ { -1, 74 }, { -9, 91 }, { -5, 67 }, { -5, 27 },
+ { -3, 39 }, { -2, 44 }, { 0, 46 }, { -16, 64 },
+ { -8, 68 }, { -10, 78 }, { -6, 77 }, { -10, 86 },
+ { -12, 92 }, { -15, 55 }, { -10, 60 }, { -6, 62 },
+ { -4, 65 }, { -12, 73 }, { -8, 76 }, { -7, 80 },
+ { -9, 88 }, { -17, 110 }, { -3, 71 }, { -6, 42 },
+ { -5, 50 }, { -3, 54 }, { -2, 62 }, { 0, 58 },
+ { 1, 63 }, { -2, 72 }, { -1, 74 }, { -9, 91 },
+ { -5, 67 }, { -5, 27 }, { -3, 39 }, { -2, 44 },
+ { 0, 46 }, { -16, 64 }, { -8, 68 }, { -10, 78 },
+ { -6, 77 }, { -10, 86 }, { -12, 92 }, { -15, 55 },
+ { -10, 60 }, { -6, 62 }, { -4, 65 }, { -12, 73 },
+ { -8, 76 }, { -7, 80 }, { -9, 88 }, { -17, 110 },
+ { -3, 70 }, { -8, 93 }, { -10, 90 }, { -30, 127 },
+ { -3, 70 }, { -8, 93 }, { -10, 90 }, { -30, 127 },
+ { -3, 70 }, { -8, 93 }, { -10, 90 }, { -30, 127 }
+};
+
+static const int8_t cabac_context_init_PB[3][1024][2] =
+{
+ /* i_cabac_init_idc == 0 */
+ {
+ /* 0 - 10 */
+ { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 },
+ { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 },
+ { -6, 53 }, { -1, 54 }, { 7, 51 },
+
+ /* 11 - 23 */
+ { 23, 33 }, { 23, 2 }, { 21, 0 }, { 1, 9 },
+ { 0, 49 }, { -37, 118 }, { 5, 57 }, { -13, 78 },
+ { -11, 65 }, { 1, 62 }, { 12, 49 }, { -4, 73 },
+ { 17, 50 },
+
+ /* 24 - 39 */
+ { 18, 64 }, { 9, 43 }, { 29, 0 }, { 26, 67 },
+ { 16, 90 }, { 9, 104 }, { -46, 127 }, { -20, 104 },
+ { 1, 67 }, { -13, 78 }, { -11, 65 }, { 1, 62 },
+ { -6, 86 }, { -17, 95 }, { -6, 61 }, { 9, 45 },
+
+ /* 40 - 53 */
+ { -3, 69 }, { -6, 81 }, { -11, 96 }, { 6, 55 },
+ { 7, 67 }, { -5, 86 }, { 2, 88 }, { 0, 58 },
+ { -3, 76 }, { -10, 94 }, { 5, 54 }, { 4, 69 },
+ { -3, 81 }, { 0, 88 },
+
+ /* 54 - 59 */
+ { -7, 67 }, { -5, 74 }, { -4, 74 }, { -5, 80 },
+ { -7, 72 }, { 1, 58 },
+
+ /* 60 - 69 */
+ { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 },
+ { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 },
+ { 13, 41 }, { 3, 62 },
+
+ /* 70 - 87 */
+ { 0, 45 }, { -4, 78 }, { -3, 96 }, { -27, 126 },
+ { -28, 98 }, { -25, 101 }, { -23, 67 }, { -28, 82 },
+ { -20, 94 }, { -16, 83 }, { -22, 110 }, { -21, 91 },
+ { -18, 102 }, { -13, 93 }, { -29, 127 }, { -7, 92 },
+ { -5, 89 }, { -7, 96 }, { -13, 108 }, { -3, 46 },
+ { -1, 65 }, { -1, 57 }, { -9, 93 }, { -3, 74 },
+ { -9, 92 }, { -8, 87 }, { -23, 126 }, { 5, 54 },
+ { 6, 60 }, { 6, 59 }, { 6, 69 }, { -1, 48 },
+ { 0, 68 }, { -4, 69 }, { -8, 88 },
+
+ /* 105 -> 165 */
+ { -2, 85 }, { -6, 78 }, { -1, 75 }, { -7, 77 },
+ { 2, 54 }, { 5, 50 }, { -3, 68 }, { 1, 50 },
+ { 6, 42 }, { -4, 81 }, { 1, 63 }, { -4, 70 },
+ { 0, 67 }, { 2, 57 }, { -2, 76 }, { 11, 35 },
+ { 4, 64 }, { 1, 61 }, { 11, 35 }, { 18, 25 },
+ { 12, 24 }, { 13, 29 }, { 13, 36 }, { -10, 93 },
+ { -7, 73 }, { -2, 73 }, { 13, 46 }, { 9, 49 },
+ { -7, 100 }, { 9, 53 }, { 2, 53 }, { 5, 53 },
+ { -2, 61 }, { 0, 56 }, { 0, 56 }, { -13, 63 },
+ { -5, 60 }, { -1, 62 }, { 4, 57 }, { -6, 69 },
+ { 4, 57 }, { 14, 39 }, { 4, 51 }, { 13, 68 },
+ { 3, 64 }, { 1, 61 }, { 9, 63 }, { 7, 50 },
+ { 16, 39 }, { 5, 44 }, { 4, 52 }, { 11, 48 },
+ { -5, 60 }, { -1, 59 }, { 0, 59 }, { 22, 33 },
+ { 5, 44 }, { 14, 43 }, { -1, 78 }, { 0, 60 },
+ { 9, 69 },
+
+ /* 166 - 226 */
+ { 11, 28 }, { 2, 40 }, { 3, 44 }, { 0, 49 },
+ { 0, 46 }, { 2, 44 }, { 2, 51 }, { 0, 47 },
+ { 4, 39 }, { 2, 62 }, { 6, 46 }, { 0, 54 },
+ { 3, 54 }, { 2, 58 }, { 4, 63 }, { 6, 51 },
+ { 6, 57 }, { 7, 53 }, { 6, 52 }, { 6, 55 },
+ { 11, 45 }, { 14, 36 }, { 8, 53 }, { -1, 82 },
+ { 7, 55 }, { -3, 78 }, { 15, 46 }, { 22, 31 },
+ { -1, 84 }, { 25, 7 }, { 30, -7 }, { 28, 3 },
+ { 28, 4 }, { 32, 0 }, { 34, -1 }, { 30, 6 },
+ { 30, 6 }, { 32, 9 }, { 31, 19 }, { 26, 27 },
+ { 26, 30 }, { 37, 20 }, { 28, 34 }, { 17, 70 },
+ { 1, 67 }, { 5, 59 }, { 9, 67 }, { 16, 30 },
+ { 18, 32 }, { 18, 35 }, { 22, 29 }, { 24, 31 },
+ { 23, 38 }, { 18, 43 }, { 20, 41 }, { 11, 63 },
+ { 9, 59 }, { 9, 64 }, { -1, 94 }, { -2, 89 },
+ { -9, 108 },
+
+ /* 227 - 275 */
+ { -6, 76 }, { -2, 44 }, { 0, 45 }, { 0, 52 },
+ { -3, 64 }, { -2, 59 }, { -4, 70 }, { -4, 75 },
+ { -8, 82 }, { -17, 102 }, { -9, 77 }, { 3, 24 },
+ { 0, 42 }, { 0, 48 }, { 0, 55 }, { -6, 59 },
+ { -7, 71 }, { -12, 83 }, { -11, 87 }, { -30, 119 },
+ { 1, 58 }, { -3, 29 }, { -1, 36 }, { 1, 38 },
+ { 2, 43 }, { -6, 55 }, { 0, 58 }, { 0, 64 },
+ { -3, 74 }, { -10, 90 }, { 0, 70 }, { -4, 29 },
+ { 5, 31 }, { 7, 42 }, { 1, 59 }, { -2, 58 },
+ { -3, 72 }, { -3, 81 }, { -11, 97 }, { 0, 58 },
+ { 8, 5 }, { 10, 14 }, { 14, 18 }, { 13, 27 },
+ { 2, 40 }, { 0, 58 }, { -3, 70 }, { -6, 79 },
+ { -8, 85 },
+
+ /* 276 a bit special (not used, bypass is used instead) */
+ { 0, 0 },
+
+ /* 277 - 337 */
+ { -13, 106 }, { -16, 106 }, { -10, 87 }, { -21, 114 },
+ { -18, 110 }, { -14, 98 }, { -22, 110 }, { -21, 106 },
+ { -18, 103 }, { -21, 107 }, { -23, 108 }, { -26, 112 },
+ { -10, 96 }, { -12, 95 }, { -5, 91 }, { -9, 93 },
+ { -22, 94 }, { -5, 86 }, { 9, 67 }, { -4, 80 },
+ { -10, 85 }, { -1, 70 }, { 7, 60 }, { 9, 58 },
+ { 5, 61 }, { 12, 50 }, { 15, 50 }, { 18, 49 },
+ { 17, 54 }, { 10, 41 }, { 7, 46 }, { -1, 51 },
+ { 7, 49 }, { 8, 52 }, { 9, 41 }, { 6, 47 },
+ { 2, 55 }, { 13, 41 }, { 10, 44 }, { 6, 50 },
+ { 5, 53 }, { 13, 49 }, { 4, 63 }, { 6, 64 },
+ { -2, 69 }, { -2, 59 }, { 6, 70 }, { 10, 44 },
+ { 9, 31 }, { 12, 43 }, { 3, 53 }, { 14, 34 },
+ { 10, 38 }, { -3, 52 }, { 13, 40 }, { 17, 32 },
+ { 7, 44 }, { 7, 38 }, { 13, 50 }, { 10, 57 },
+ { 26, 43 },
+
+ /* 338 - 398 */
+ { 14, 11 }, { 11, 14 }, { 9, 11 }, { 18, 11 },
+ { 21, 9 }, { 23, -2 }, { 32, -15 }, { 32, -15 },
+ { 34, -21 }, { 39, -23 }, { 42, -33 }, { 41, -31 },
+ { 46, -28 }, { 38, -12 }, { 21, 29 }, { 45, -24 },
+ { 53, -45 }, { 48, -26 }, { 65, -43 }, { 43, -19 },
+ { 39, -10 }, { 30, 9 }, { 18, 26 }, { 20, 27 },
+ { 0, 57 }, { -14, 82 }, { -5, 75 }, { -19, 97 },
+ { -35, 125 }, { 27, 0 }, { 28, 0 }, { 31, -4 },
+ { 27, 6 }, { 34, 8 }, { 30, 10 }, { 24, 22 },
+ { 33, 19 }, { 22, 32 }, { 26, 31 }, { 21, 41 },
+ { 26, 44 }, { 23, 47 }, { 16, 65 }, { 14, 71 },
+ { 8, 60 }, { 6, 63 }, { 17, 65 }, { 21, 24 },
+ { 23, 20 }, { 26, 23 }, { 27, 32 }, { 28, 23 },
+ { 28, 24 }, { 23, 40 }, { 24, 32 }, { 28, 29 },
+ { 23, 42 }, { 19, 57 }, { 22, 53 }, { 22, 61 },
+ { 11, 86 },
+
+ /* 399 - 435 */
+ { 12, 40 }, { 11, 51 }, { 14, 59 },
+ { -4, 79 }, { -7, 71 }, { -5, 69 }, { -9, 70 },
+ { -8, 66 }, { -10, 68 }, { -19, 73 }, { -12, 69 },
+ { -16, 70 }, { -15, 67 }, { -20, 62 }, { -19, 70 },
+ { -16, 66 }, { -22, 65 }, { -20, 63 }, { 9, -2 },
+ { 26, -9 }, { 33, -9 }, { 39, -7 }, { 41, -2 },
+ { 45, 3 }, { 49, 9 }, { 45, 27 }, { 36, 59 },
+ { -6, 66 }, { -7, 35 }, { -7, 42 }, { -8, 45 },
+ { -5, 48 }, { -12, 56 }, { -6, 60 }, { -5, 62 },
+ { -8, 66 }, { -8, 76 },
+
+ /* 436 - 459 */
+ { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 },
+ { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 },
+ { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 },
+ { -14, 66 }, { 0, 59 }, { 2, 59 }, { 21, -13 },
+ { 33, -14 }, { 39, -7 }, { 46, -2 }, { 51, 2 },
+ { 60, 6 }, { 61, 17 }, { 55, 34 }, { 42, 62 },
+
+ /* 460 - 1024 */
+ { -7, 92 }, { -5, 89 }, { -7, 96 }, { -13, 108 },
+ { -3, 46 }, { -1, 65 }, { -1, 57 }, { -9, 93 },
+ { -3, 74 }, { -9, 92 }, { -8, 87 }, { -23, 126 },
+ { -7, 92 }, { -5, 89 }, { -7, 96 }, { -13, 108 },
+ { -3, 46 }, { -1, 65 }, { -1, 57 }, { -9, 93 },
+ { -3, 74 }, { -9, 92 }, { -8, 87 }, { -23, 126 },
+ { -2, 85 }, { -6, 78 }, { -1, 75 }, { -7, 77 },
+ { 2, 54 }, { 5, 50 }, { -3, 68 }, { 1, 50 },
+ { 6, 42 }, { -4, 81 }, { 1, 63 }, { -4, 70 },
+ { 0, 67 }, { 2, 57 }, { -2, 76 }, { 11, 35 },
+ { 4, 64 }, { 1, 61 }, { 11, 35 }, { 18, 25 },
+ { 12, 24 }, { 13, 29 }, { 13, 36 }, { -10, 93 },
+ { -7, 73 }, { -2, 73 }, { 13, 46 }, { 9, 49 },
+ { -7, 100 }, { 9, 53 }, { 2, 53 }, { 5, 53 },
+ { -2, 61 }, { 0, 56 }, { 0, 56 }, { -13, 63 },
+ { -5, 60 }, { -1, 62 }, { 4, 57 }, { -6, 69 },
+ { 4, 57 }, { 14, 39 }, { 4, 51 }, { 13, 68 },
+ { -2, 85 }, { -6, 78 }, { -1, 75 }, { -7, 77 },
+ { 2, 54 }, { 5, 50 }, { -3, 68 }, { 1, 50 },
+ { 6, 42 }, { -4, 81 }, { 1, 63 }, { -4, 70 },
+ { 0, 67 }, { 2, 57 }, { -2, 76 }, { 11, 35 },
+ { 4, 64 }, { 1, 61 }, { 11, 35 }, { 18, 25 },
+ { 12, 24 }, { 13, 29 }, { 13, 36 }, { -10, 93 },
+ { -7, 73 }, { -2, 73 }, { 13, 46 }, { 9, 49 },
+ { -7, 100 }, { 9, 53 }, { 2, 53 }, { 5, 53 },
+ { -2, 61 }, { 0, 56 }, { 0, 56 }, { -13, 63 },
+ { -5, 60 }, { -1, 62 }, { 4, 57 }, { -6, 69 },
+ { 4, 57 }, { 14, 39 }, { 4, 51 }, { 13, 68 },
+ { 11, 28 }, { 2, 40 }, { 3, 44 }, { 0, 49 },
+ { 0, 46 }, { 2, 44 }, { 2, 51 }, { 0, 47 },
+ { 4, 39 }, { 2, 62 }, { 6, 46 }, { 0, 54 },
+ { 3, 54 }, { 2, 58 }, { 4, 63 }, { 6, 51 },
+ { 6, 57 }, { 7, 53 }, { 6, 52 }, { 6, 55 },
+ { 11, 45 }, { 14, 36 }, { 8, 53 }, { -1, 82 },
+ { 7, 55 }, { -3, 78 }, { 15, 46 }, { 22, 31 },
+ { -1, 84 }, { 25, 7 }, { 30, -7 }, { 28, 3 },
+ { 28, 4 }, { 32, 0 }, { 34, -1 }, { 30, 6 },
+ { 30, 6 }, { 32, 9 }, { 31, 19 }, { 26, 27 },
+ { 26, 30 }, { 37, 20 }, { 28, 34 }, { 17, 70 },
+ { 11, 28 }, { 2, 40 }, { 3, 44 }, { 0, 49 },
+ { 0, 46 }, { 2, 44 }, { 2, 51 }, { 0, 47 },
+ { 4, 39 }, { 2, 62 }, { 6, 46 }, { 0, 54 },
+ { 3, 54 }, { 2, 58 }, { 4, 63 }, { 6, 51 },
+ { 6, 57 }, { 7, 53 }, { 6, 52 }, { 6, 55 },
+ { 11, 45 }, { 14, 36 }, { 8, 53 }, { -1, 82 },
+ { 7, 55 }, { -3, 78 }, { 15, 46 }, { 22, 31 },
+ { -1, 84 }, { 25, 7 }, { 30, -7 }, { 28, 3 },
+ { 28, 4 }, { 32, 0 }, { 34, -1 }, { 30, 6 },
+ { 30, 6 }, { 32, 9 }, { 31, 19 }, { 26, 27 },
+ { 26, 30 }, { 37, 20 }, { 28, 34 }, { 17, 70 },
+ { -4, 79 }, { -7, 71 }, { -5, 69 }, { -9, 70 },
+ { -8, 66 }, { -10, 68 }, { -19, 73 }, { -12, 69 },
+ { -16, 70 }, { -15, 67 }, { -20, 62 }, { -19, 70 },
+ { -16, 66 }, { -22, 65 }, { -20, 63 }, { -5, 85 },
+ { -6, 81 }, { -10, 77 }, { -7, 81 }, { -17, 80 },
+ { -18, 73 }, { -4, 74 }, { -10, 83 }, { -9, 71 },
+ { -9, 67 }, { -1, 61 }, { -8, 66 }, { -14, 66 },
+ { 0, 59 }, { 2, 59 }, { 9, -2 }, { 26, -9 },
+ { 33, -9 }, { 39, -7 }, { 41, -2 }, { 45, 3 },
+ { 49, 9 }, { 45, 27 }, { 36, 59 }, { 21, -13 },
+ { 33, -14 }, { 39, -7 }, { 46, -2 }, { 51, 2 },
+ { 60, 6 }, { 61, 17 }, { 55, 34 }, { 42, 62 },
+ { -6, 66 }, { -7, 35 }, { -7, 42 }, { -8, 45 },
+ { -5, 48 }, { -12, 56 }, { -6, 60 }, { -5, 62 },
+ { -8, 66 }, { -8, 76 }, { -4, 79 }, { -7, 71 },
+ { -5, 69 }, { -9, 70 }, { -8, 66 }, { -10, 68 },
+ { -19, 73 }, { -12, 69 }, { -16, 70 }, { -15, 67 },
+ { -20, 62 }, { -19, 70 }, { -16, 66 }, { -22, 65 },
+ { -20, 63 }, { -5, 85 }, { -6, 81 }, { -10, 77 },
+ { -7, 81 }, { -17, 80 }, { -18, 73 }, { -4, 74 },
+ { -10, 83 }, { -9, 71 }, { -9, 67 }, { -1, 61 },
+ { -8, 66 }, { -14, 66 }, { 0, 59 }, { 2, 59 },
+ { 9, -2 }, { 26, -9 }, { 33, -9 }, { 39, -7 },
+ { 41, -2 }, { 45, 3 }, { 49, 9 }, { 45, 27 },
+ { 36, 59 }, { 21, -13 }, { 33, -14 }, { 39, -7 },
+ { 46, -2 }, { 51, 2 }, { 60, 6 }, { 61, 17 },
+ { 55, 34 }, { 42, 62 }, { -6, 66 }, { -7, 35 },
+ { -7, 42 }, { -8, 45 }, { -5, 48 }, { -12, 56 },
+ { -6, 60 }, { -5, 62 }, { -8, 66 }, { -8, 76 },
+ { -13, 106 }, { -16, 106 }, { -10, 87 }, { -21, 114 },
+ { -18, 110 }, { -14, 98 }, { -22, 110 }, { -21, 106 },
+ { -18, 103 }, { -21, 107 }, { -23, 108 }, { -26, 112 },
+ { -10, 96 }, { -12, 95 }, { -5, 91 }, { -9, 93 },
+ { -22, 94 }, { -5, 86 }, { 9, 67 }, { -4, 80 },
+ { -10, 85 }, { -1, 70 }, { 7, 60 }, { 9, 58 },
+ { 5, 61 }, { 12, 50 }, { 15, 50 }, { 18, 49 },
+ { 17, 54 }, { 10, 41 }, { 7, 46 }, { -1, 51 },
+ { 7, 49 }, { 8, 52 }, { 9, 41 }, { 6, 47 },
+ { 2, 55 }, { 13, 41 }, { 10, 44 }, { 6, 50 },
+ { 5, 53 }, { 13, 49 }, { 4, 63 }, { 6, 64 },
+ { -13, 106 }, { -16, 106 }, { -10, 87 }, { -21, 114 },
+ { -18, 110 }, { -14, 98 }, { -22, 110 }, { -21, 106 },
+ { -18, 103 }, { -21, 107 }, { -23, 108 }, { -26, 112 },
+ { -10, 96 }, { -12, 95 }, { -5, 91 }, { -9, 93 },
+ { -22, 94 }, { -5, 86 }, { 9, 67 }, { -4, 80 },
+ { -10, 85 }, { -1, 70 }, { 7, 60 }, { 9, 58 },
+ { 5, 61 }, { 12, 50 }, { 15, 50 }, { 18, 49 },
+ { 17, 54 }, { 10, 41 }, { 7, 46 }, { -1, 51 },
+ { 7, 49 }, { 8, 52 }, { 9, 41 }, { 6, 47 },
+ { 2, 55 }, { 13, 41 }, { 10, 44 }, { 6, 50 },
+ { 5, 53 }, { 13, 49 }, { 4, 63 }, { 6, 64 },
+ { 14, 11 }, { 11, 14 }, { 9, 11 }, { 18, 11 },
+ { 21, 9 }, { 23, -2 }, { 32, -15 }, { 32, -15 },
+ { 34, -21 }, { 39, -23 }, { 42, -33 }, { 41, -31 },
+ { 46, -28 }, { 38, -12 }, { 21, 29 }, { 45, -24 },
+ { 53, -45 }, { 48, -26 }, { 65, -43 }, { 43, -19 },
+ { 39, -10 }, { 30, 9 }, { 18, 26 }, { 20, 27 },
+ { 0, 57 }, { -14, 82 }, { -5, 75 }, { -19, 97 },
+ { -35, 125 }, { 27, 0 }, { 28, 0 }, { 31, -4 },
+ { 27, 6 }, { 34, 8 }, { 30, 10 }, { 24, 22 },
+ { 33, 19 }, { 22, 32 }, { 26, 31 }, { 21, 41 },
+ { 26, 44 }, { 23, 47 }, { 16, 65 }, { 14, 71 },
+ { 14, 11 }, { 11, 14 }, { 9, 11 }, { 18, 11 },
+ { 21, 9 }, { 23, -2 }, { 32, -15 }, { 32, -15 },
+ { 34, -21 }, { 39, -23 }, { 42, -33 }, { 41, -31 },
+ { 46, -28 }, { 38, -12 }, { 21, 29 }, { 45, -24 },
+ { 53, -45 }, { 48, -26 }, { 65, -43 }, { 43, -19 },
+ { 39, -10 }, { 30, 9 }, { 18, 26 }, { 20, 27 },
+ { 0, 57 }, { -14, 82 }, { -5, 75 }, { -19, 97 },
+ { -35, 125 }, { 27, 0 }, { 28, 0 }, { 31, -4 },
+ { 27, 6 }, { 34, 8 }, { 30, 10 }, { 24, 22 },
+ { 33, 19 }, { 22, 32 }, { 26, 31 }, { 21, 41 },
+ { 26, 44 }, { 23, 47 }, { 16, 65 }, { 14, 71 },
+ { -6, 76 }, { -2, 44 }, { 0, 45 }, { 0, 52 },
+ { -3, 64 }, { -2, 59 }, { -4, 70 }, { -4, 75 },
+ { -8, 82 }, { -17, 102 }, { -9, 77 }, { 3, 24 },
+ { 0, 42 }, { 0, 48 }, { 0, 55 }, { -6, 59 },
+ { -7, 71 }, { -12, 83 }, { -11, 87 }, { -30, 119 },
+ { 1, 58 }, { -3, 29 }, { -1, 36 }, { 1, 38 },
+ { 2, 43 }, { -6, 55 }, { 0, 58 }, { 0, 64 },
+ { -3, 74 }, { -10, 90 }, { -6, 76 }, { -2, 44 },
+ { 0, 45 }, { 0, 52 }, { -3, 64 }, { -2, 59 },
+ { -4, 70 }, { -4, 75 }, { -8, 82 }, { -17, 102 },
+ { -9, 77 }, { 3, 24 }, { 0, 42 }, { 0, 48 },
+ { 0, 55 }, { -6, 59 }, { -7, 71 }, { -12, 83 },
+ { -11, 87 }, { -30, 119 }, { 1, 58 }, { -3, 29 },
+ { -1, 36 }, { 1, 38 }, { 2, 43 }, { -6, 55 },
+ { 0, 58 }, { 0, 64 }, { -3, 74 }, { -10, 90 },
+ { -3, 74 }, { -9, 92 }, { -8, 87 }, { -23, 126 },
+ { -3, 74 }, { -9, 92 }, { -8, 87 }, { -23, 126 },
+ { -3, 74 }, { -9, 92 }, { -8, 87 }, { -23, 126 }
+ },
+
+ /* i_cabac_init_idc == 1 */
+ {
+ /* 0 - 10 */
+ { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 },
+ { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 },
+ { -6, 53 }, { -1, 54 }, { 7, 51 },
+
+ /* 11 - 23 */
+ { 22, 25 }, { 34, 0 }, { 16, 0 }, { -2, 9 },
+ { 4, 41 }, { -29, 118 }, { 2, 65 }, { -6, 71 },
+ { -13, 79 }, { 5, 52 }, { 9, 50 }, { -3, 70 },
+ { 10, 54 },
+
+ /* 24 - 39 */
+ { 26, 34 }, { 19, 22 }, { 40, 0 }, { 57, 2 },
+ { 41, 36 }, { 26, 69 }, { -45, 127 }, { -15, 101 },
+ { -4, 76 }, { -6, 71 }, { -13, 79 }, { 5, 52 },
+ { 6, 69 }, { -13, 90 }, { 0, 52 }, { 8, 43 },
+
+ /* 40 - 53 */
+ { -2, 69 },{ -5, 82 },{ -10, 96 },{ 2, 59 },
+ { 2, 75 },{ -3, 87 },{ -3, 100 },{ 1, 56 },
+ { -3, 74 },{ -6, 85 },{ 0, 59 },{ -3, 81 },
+ { -7, 86 },{ -5, 95 },
+
+ /* 54 - 59 */
+ { -1, 66 },{ -1, 77 },{ 1, 70 },{ -2, 86 },
+ { -5, 72 },{ 0, 61 },
+
+ /* 60 - 69 */
+ { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 },
+ { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 },
+ { 13, 41 }, { 3, 62 },
+
+ /* 70 - 104 */
+ { 13, 15 }, { 7, 51 }, { 2, 80 }, { -39, 127 },
+ { -18, 91 }, { -17, 96 }, { -26, 81 }, { -35, 98 },
+ { -24, 102 }, { -23, 97 }, { -27, 119 }, { -24, 99 },
+ { -21, 110 }, { -18, 102 }, { -36, 127 }, { 0, 80 },
+ { -5, 89 }, { -7, 94 }, { -4, 92 }, { 0, 39 },
+ { 0, 65 }, { -15, 84 }, { -35, 127 }, { -2, 73 },
+ { -12, 104 }, { -9, 91 }, { -31, 127 }, { 3, 55 },
+ { 7, 56 }, { 7, 55 }, { 8, 61 }, { -3, 53 },
+ { 0, 68 }, { -7, 74 }, { -9, 88 },
+
+ /* 105 -> 165 */
+ { -13, 103 }, { -13, 91 }, { -9, 89 }, { -14, 92 },
+ { -8, 76 }, { -12, 87 }, { -23, 110 }, { -24, 105 },
+ { -10, 78 }, { -20, 112 }, { -17, 99 }, { -78, 127 },
+ { -70, 127 }, { -50, 127 }, { -46, 127 }, { -4, 66 },
+ { -5, 78 }, { -4, 71 }, { -8, 72 }, { 2, 59 },
+ { -1, 55 }, { -7, 70 }, { -6, 75 }, { -8, 89 },
+ { -34, 119 }, { -3, 75 }, { 32, 20 }, { 30, 22 },
+ { -44, 127 }, { 0, 54 }, { -5, 61 }, { 0, 58 },
+ { -1, 60 }, { -3, 61 }, { -8, 67 }, { -25, 84 },
+ { -14, 74 }, { -5, 65 }, { 5, 52 }, { 2, 57 },
+ { 0, 61 }, { -9, 69 }, { -11, 70 }, { 18, 55 },
+ { -4, 71 }, { 0, 58 }, { 7, 61 }, { 9, 41 },
+ { 18, 25 }, { 9, 32 }, { 5, 43 }, { 9, 47 },
+ { 0, 44 }, { 0, 51 }, { 2, 46 }, { 19, 38 },
+ { -4, 66 }, { 15, 38 }, { 12, 42 }, { 9, 34 },
+ { 0, 89 },
+
+ /* 166 - 226 */
+ { 4, 45 }, { 10, 28 }, { 10, 31 }, { 33, -11 },
+ { 52, -43 }, { 18, 15 }, { 28, 0 }, { 35, -22 },
+ { 38, -25 }, { 34, 0 }, { 39, -18 }, { 32, -12 },
+ { 102, -94 }, { 0, 0 }, { 56, -15 }, { 33, -4 },
+ { 29, 10 }, { 37, -5 }, { 51, -29 }, { 39, -9 },
+ { 52, -34 }, { 69, -58 }, { 67, -63 }, { 44, -5 },
+ { 32, 7 }, { 55, -29 }, { 32, 1 }, { 0, 0 },
+ { 27, 36 }, { 33, -25 }, { 34, -30 }, { 36, -28 },
+ { 38, -28 }, { 38, -27 }, { 34, -18 }, { 35, -16 },
+ { 34, -14 }, { 32, -8 }, { 37, -6 }, { 35, 0 },
+ { 30, 10 }, { 28, 18 }, { 26, 25 }, { 29, 41 },
+ { 0, 75 }, { 2, 72 }, { 8, 77 }, { 14, 35 },
+ { 18, 31 }, { 17, 35 }, { 21, 30 }, { 17, 45 },
+ { 20, 42 }, { 18, 45 }, { 27, 26 }, { 16, 54 },
+ { 7, 66 }, { 16, 56 }, { 11, 73 }, { 10, 67 },
+ { -10, 116 },
+
+ /* 227 - 275 */
+ { -23, 112 }, { -15, 71 }, { -7, 61 }, { 0, 53 },
+ { -5, 66 }, { -11, 77 }, { -9, 80 }, { -9, 84 },
+ { -10, 87 }, { -34, 127 }, { -21, 101 }, { -3, 39 },
+ { -5, 53 }, { -7, 61 }, { -11, 75 }, { -15, 77 },
+ { -17, 91 }, { -25, 107 }, { -25, 111 }, { -28, 122 },
+ { -11, 76 }, { -10, 44 }, { -10, 52 }, { -10, 57 },
+ { -9, 58 }, { -16, 72 }, { -7, 69 }, { -4, 69 },
+ { -5, 74 }, { -9, 86 }, { 2, 66 }, { -9, 34 },
+ { 1, 32 }, { 11, 31 }, { 5, 52 }, { -2, 55 },
+ { -2, 67 }, { 0, 73 }, { -8, 89 }, { 3, 52 },
+ { 7, 4 }, { 10, 8 }, { 17, 8 }, { 16, 19 },
+ { 3, 37 }, { -1, 61 }, { -5, 73 }, { -1, 70 },
+ { -4, 78 },
+
+ /* 276 a bit special (not used, bypass is used instead) */
+ { 0, 0 },
+
+ /* 277 - 337 */
+ { -21, 126 }, { -23, 124 }, { -20, 110 }, { -26, 126 },
+ { -25, 124 }, { -17, 105 }, { -27, 121 }, { -27, 117 },
+ { -17, 102 }, { -26, 117 }, { -27, 116 }, { -33, 122 },
+ { -10, 95 }, { -14, 100 }, { -8, 95 }, { -17, 111 },
+ { -28, 114 }, { -6, 89 }, { -2, 80 }, { -4, 82 },
+ { -9, 85 }, { -8, 81 }, { -1, 72 }, { 5, 64 },
+ { 1, 67 }, { 9, 56 }, { 0, 69 }, { 1, 69 },
+ { 7, 69 }, { -7, 69 }, { -6, 67 }, { -16, 77 },
+ { -2, 64 }, { 2, 61 }, { -6, 67 }, { -3, 64 },
+ { 2, 57 }, { -3, 65 }, { -3, 66 }, { 0, 62 },
+ { 9, 51 }, { -1, 66 }, { -2, 71 }, { -2, 75 },
+ { -1, 70 }, { -9, 72 }, { 14, 60 }, { 16, 37 },
+ { 0, 47 }, { 18, 35 }, { 11, 37 }, { 12, 41 },
+ { 10, 41 }, { 2, 48 }, { 12, 41 }, { 13, 41 },
+ { 0, 59 }, { 3, 50 }, { 19, 40 }, { 3, 66 },
+ { 18, 50 },
+
+ /* 338 - 398 */
+ { 19, -6 }, { 18, -6 }, { 14, 0 }, { 26, -12 },
+ { 31, -16 }, { 33, -25 }, { 33, -22 }, { 37, -28 },
+ { 39, -30 }, { 42, -30 }, { 47, -42 }, { 45, -36 },
+ { 49, -34 }, { 41, -17 }, { 32, 9 }, { 69, -71 },
+ { 63, -63 }, { 66, -64 }, { 77, -74 }, { 54, -39 },
+ { 52, -35 }, { 41, -10 }, { 36, 0 }, { 40, -1 },
+ { 30, 14 }, { 28, 26 }, { 23, 37 }, { 12, 55 },
+ { 11, 65 }, { 37, -33 }, { 39, -36 }, { 40, -37 },
+ { 38, -30 }, { 46, -33 }, { 42, -30 }, { 40, -24 },
+ { 49, -29 }, { 38, -12 }, { 40, -10 }, { 38, -3 },
+ { 46, -5 }, { 31, 20 }, { 29, 30 }, { 25, 44 },
+ { 12, 48 }, { 11, 49 }, { 26, 45 }, { 22, 22 },
+ { 23, 22 }, { 27, 21 }, { 33, 20 }, { 26, 28 },
+ { 30, 24 }, { 27, 34 }, { 18, 42 }, { 25, 39 },
+ { 18, 50 }, { 12, 70 }, { 21, 54 }, { 14, 71 },
+ { 11, 83 },
+
+ /* 399 - 435 */
+ { 25, 32 }, { 21, 49 }, { 21, 54 },
+ { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 },
+ { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 },
+ { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 },
+ { -14, 66 }, { 0, 59 }, { 2, 59 }, { 17, -10 },
+ { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 },
+ { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 },
+ { -5, 71 }, { 0, 24 }, { -1, 36 }, { -2, 42 },
+ { -2, 52 }, { -9, 57 }, { -6, 63 }, { -4, 65 },
+ { -4, 67 }, { -7, 82 },
+
+ /* 436 - 459 */
+ { -3, 81 }, { -3, 76 }, { -7, 72 }, { -6, 78 },
+ { -12, 72 }, { -14, 68 }, { -3, 70 }, { -6, 76 },
+ { -5, 66 }, { -5, 62 }, { 0, 57 }, { -4, 61 },
+ { -9, 60 }, { 1, 54 }, { 2, 58 }, { 17, -10 },
+ { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 },
+ { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 },
+
+ /* 460 - 1024 */
+ { 0, 80 }, { -5, 89 }, { -7, 94 }, { -4, 92 },
+ { 0, 39 }, { 0, 65 }, { -15, 84 }, { -35, 127 },
+ { -2, 73 }, { -12, 104 }, { -9, 91 }, { -31, 127 },
+ { 0, 80 }, { -5, 89 }, { -7, 94 }, { -4, 92 },
+ { 0, 39 }, { 0, 65 }, { -15, 84 }, { -35, 127 },
+ { -2, 73 }, { -12, 104 }, { -9, 91 }, { -31, 127 },
+ { -13, 103 }, { -13, 91 }, { -9, 89 }, { -14, 92 },
+ { -8, 76 }, { -12, 87 }, { -23, 110 }, { -24, 105 },
+ { -10, 78 }, { -20, 112 }, { -17, 99 }, { -78, 127 },
+ { -70, 127 }, { -50, 127 }, { -46, 127 }, { -4, 66 },
+ { -5, 78 }, { -4, 71 }, { -8, 72 }, { 2, 59 },
+ { -1, 55 }, { -7, 70 }, { -6, 75 }, { -8, 89 },
+ { -34, 119 }, { -3, 75 }, { 32, 20 }, { 30, 22 },
+ { -44, 127 }, { 0, 54 }, { -5, 61 }, { 0, 58 },
+ { -1, 60 }, { -3, 61 }, { -8, 67 }, { -25, 84 },
+ { -14, 74 }, { -5, 65 }, { 5, 52 }, { 2, 57 },
+ { 0, 61 }, { -9, 69 }, { -11, 70 }, { 18, 55 },
+ { -13, 103 }, { -13, 91 }, { -9, 89 }, { -14, 92 },
+ { -8, 76 }, { -12, 87 }, { -23, 110 }, { -24, 105 },
+ { -10, 78 }, { -20, 112 }, { -17, 99 }, { -78, 127 },
+ { -70, 127 }, { -50, 127 }, { -46, 127 }, { -4, 66 },
+ { -5, 78 }, { -4, 71 }, { -8, 72 }, { 2, 59 },
+ { -1, 55 }, { -7, 70 }, { -6, 75 }, { -8, 89 },
+ { -34, 119 }, { -3, 75 }, { 32, 20 }, { 30, 22 },
+ { -44, 127 }, { 0, 54 }, { -5, 61 }, { 0, 58 },
+ { -1, 60 }, { -3, 61 }, { -8, 67 }, { -25, 84 },
+ { -14, 74 }, { -5, 65 }, { 5, 52 }, { 2, 57 },
+ { 0, 61 }, { -9, 69 }, { -11, 70 }, { 18, 55 },
+ { 4, 45 }, { 10, 28 }, { 10, 31 }, { 33, -11 },
+ { 52, -43 }, { 18, 15 }, { 28, 0 }, { 35, -22 },
+ { 38, -25 }, { 34, 0 }, { 39, -18 }, { 32, -12 },
+ { 102, -94 }, { 0, 0 }, { 56, -15 }, { 33, -4 },
+ { 29, 10 }, { 37, -5 }, { 51, -29 }, { 39, -9 },
+ { 52, -34 }, { 69, -58 }, { 67, -63 }, { 44, -5 },
+ { 32, 7 }, { 55, -29 }, { 32, 1 }, { 0, 0 },
+ { 27, 36 }, { 33, -25 }, { 34, -30 }, { 36, -28 },
+ { 38, -28 }, { 38, -27 }, { 34, -18 }, { 35, -16 },
+ { 34, -14 }, { 32, -8 }, { 37, -6 }, { 35, 0 },
+ { 30, 10 }, { 28, 18 }, { 26, 25 }, { 29, 41 },
+ { 4, 45 }, { 10, 28 }, { 10, 31 }, { 33, -11 },
+ { 52, -43 }, { 18, 15 }, { 28, 0 }, { 35, -22 },
+ { 38, -25 }, { 34, 0 }, { 39, -18 }, { 32, -12 },
+ { 102, -94 }, { 0, 0 }, { 56, -15 }, { 33, -4 },
+ { 29, 10 }, { 37, -5 }, { 51, -29 }, { 39, -9 },
+ { 52, -34 }, { 69, -58 }, { 67, -63 }, { 44, -5 },
+ { 32, 7 }, { 55, -29 }, { 32, 1 }, { 0, 0 },
+ { 27, 36 }, { 33, -25 }, { 34, -30 }, { 36, -28 },
+ { 38, -28 }, { 38, -27 }, { 34, -18 }, { 35, -16 },
+ { 34, -14 }, { 32, -8 }, { 37, -6 }, { 35, 0 },
+ { 30, 10 }, { 28, 18 }, { 26, 25 }, { 29, 41 },
+ { -5, 85 }, { -6, 81 }, { -10, 77 }, { -7, 81 },
+ { -17, 80 }, { -18, 73 }, { -4, 74 }, { -10, 83 },
+ { -9, 71 }, { -9, 67 }, { -1, 61 }, { -8, 66 },
+ { -14, 66 }, { 0, 59 }, { 2, 59 }, { -3, 81 },
+ { -3, 76 }, { -7, 72 }, { -6, 78 }, { -12, 72 },
+ { -14, 68 }, { -3, 70 }, { -6, 76 }, { -5, 66 },
+ { -5, 62 }, { 0, 57 }, { -4, 61 }, { -9, 60 },
+ { 1, 54 }, { 2, 58 }, { 17, -10 }, { 32, -13 },
+ { 42, -9 }, { 49, -5 }, { 53, 0 }, { 64, 3 },
+ { 68, 10 }, { 66, 27 }, { 47, 57 }, { 17, -10 },
+ { 32, -13 }, { 42, -9 }, { 49, -5 }, { 53, 0 },
+ { 64, 3 }, { 68, 10 }, { 66, 27 }, { 47, 57 },
+ { -5, 71 }, { 0, 24 }, { -1, 36 }, { -2, 42 },
+ { -2, 52 }, { -9, 57 }, { -6, 63 }, { -4, 65 },
+ { -4, 67 }, { -7, 82 }, { -5, 85 }, { -6, 81 },
+ { -10, 77 }, { -7, 81 }, { -17, 80 }, { -18, 73 },
+ { -4, 74 }, { -10, 83 }, { -9, 71 }, { -9, 67 },
+ { -1, 61 }, { -8, 66 }, { -14, 66 }, { 0, 59 },
+ { 2, 59 }, { -3, 81 }, { -3, 76 }, { -7, 72 },
+ { -6, 78 }, { -12, 72 }, { -14, 68 }, { -3, 70 },
+ { -6, 76 }, { -5, 66 }, { -5, 62 }, { 0, 57 },
+ { -4, 61 }, { -9, 60 }, { 1, 54 }, { 2, 58 },
+ { 17, -10 }, { 32, -13 }, { 42, -9 }, { 49, -5 },
+ { 53, 0 }, { 64, 3 }, { 68, 10 }, { 66, 27 },
+ { 47, 57 }, { 17, -10 }, { 32, -13 }, { 42, -9 },
+ { 49, -5 }, { 53, 0 }, { 64, 3 }, { 68, 10 },
+ { 66, 27 }, { 47, 57 }, { -5, 71 }, { 0, 24 },
+ { -1, 36 }, { -2, 42 }, { -2, 52 }, { -9, 57 },
+ { -6, 63 }, { -4, 65 }, { -4, 67 }, { -7, 82 },
+ { -21, 126 }, { -23, 124 }, { -20, 110 }, { -26, 126 },
+ { -25, 124 }, { -17, 105 }, { -27, 121 }, { -27, 117 },
+ { -17, 102 }, { -26, 117 }, { -27, 116 }, { -33, 122 },
+ { -10, 95 }, { -14, 100 }, { -8, 95 }, { -17, 111 },
+ { -28, 114 }, { -6, 89 }, { -2, 80 }, { -4, 82 },
+ { -9, 85 }, { -8, 81 }, { -1, 72 }, { 5, 64 },
+ { 1, 67 }, { 9, 56 }, { 0, 69 }, { 1, 69 },
+ { 7, 69 }, { -7, 69 }, { -6, 67 }, { -16, 77 },
+ { -2, 64 }, { 2, 61 }, { -6, 67 }, { -3, 64 },
+ { 2, 57 }, { -3, 65 }, { -3, 66 }, { 0, 62 },
+ { 9, 51 }, { -1, 66 }, { -2, 71 }, { -2, 75 },
+ { -21, 126 }, { -23, 124 }, { -20, 110 }, { -26, 126 },
+ { -25, 124 }, { -17, 105 }, { -27, 121 }, { -27, 117 },
+ { -17, 102 }, { -26, 117 }, { -27, 116 }, { -33, 122 },
+ { -10, 95 }, { -14, 100 }, { -8, 95 }, { -17, 111 },
+ { -28, 114 }, { -6, 89 }, { -2, 80 }, { -4, 82 },
+ { -9, 85 }, { -8, 81 }, { -1, 72 }, { 5, 64 },
+ { 1, 67 }, { 9, 56 }, { 0, 69 }, { 1, 69 },
+ { 7, 69 }, { -7, 69 }, { -6, 67 }, { -16, 77 },
+ { -2, 64 }, { 2, 61 }, { -6, 67 }, { -3, 64 },
+ { 2, 57 }, { -3, 65 }, { -3, 66 }, { 0, 62 },
+ { 9, 51 }, { -1, 66 }, { -2, 71 }, { -2, 75 },
+ { 19, -6 }, { 18, -6 }, { 14, 0 }, { 26, -12 },
+ { 31, -16 }, { 33, -25 }, { 33, -22 }, { 37, -28 },
+ { 39, -30 }, { 42, -30 }, { 47, -42 }, { 45, -36 },
+ { 49, -34 }, { 41, -17 }, { 32, 9 }, { 69, -71 },
+ { 63, -63 }, { 66, -64 }, { 77, -74 }, { 54, -39 },
+ { 52, -35 }, { 41, -10 }, { 36, 0 }, { 40, -1 },
+ { 30, 14 }, { 28, 26 }, { 23, 37 }, { 12, 55 },
+ { 11, 65 }, { 37, -33 }, { 39, -36 }, { 40, -37 },
+ { 38, -30 }, { 46, -33 }, { 42, -30 }, { 40, -24 },
+ { 49, -29 }, { 38, -12 }, { 40, -10 }, { 38, -3 },
+ { 46, -5 }, { 31, 20 }, { 29, 30 }, { 25, 44 },
+ { 19, -6 }, { 18, -6 }, { 14, 0 }, { 26, -12 },
+ { 31, -16 }, { 33, -25 }, { 33, -22 }, { 37, -28 },
+ { 39, -30 }, { 42, -30 }, { 47, -42 }, { 45, -36 },
+ { 49, -34 }, { 41, -17 }, { 32, 9 }, { 69, -71 },
+ { 63, -63 }, { 66, -64 }, { 77, -74 }, { 54, -39 },
+ { 52, -35 }, { 41, -10 }, { 36, 0 }, { 40, -1 },
+ { 30, 14 }, { 28, 26 }, { 23, 37 }, { 12, 55 },
+ { 11, 65 }, { 37, -33 }, { 39, -36 }, { 40, -37 },
+ { 38, -30 }, { 46, -33 }, { 42, -30 }, { 40, -24 },
+ { 49, -29 }, { 38, -12 }, { 40, -10 }, { 38, -3 },
+ { 46, -5 }, { 31, 20 }, { 29, 30 }, { 25, 44 },
+ { -23, 112 }, { -15, 71 }, { -7, 61 }, { 0, 53 },
+ { -5, 66 }, { -11, 77 }, { -9, 80 }, { -9, 84 },
+ { -10, 87 }, { -34, 127 }, { -21, 101 }, { -3, 39 },
+ { -5, 53 }, { -7, 61 }, { -11, 75 }, { -15, 77 },
+ { -17, 91 }, { -25, 107 }, { -25, 111 }, { -28, 122 },
+ { -11, 76 }, { -10, 44 }, { -10, 52 }, { -10, 57 },
+ { -9, 58 }, { -16, 72 }, { -7, 69 }, { -4, 69 },
+ { -5, 74 }, { -9, 86 }, { -23, 112 }, { -15, 71 },
+ { -7, 61 }, { 0, 53 }, { -5, 66 }, { -11, 77 },
+ { -9, 80 }, { -9, 84 }, { -10, 87 }, { -34, 127 },
+ { -21, 101 }, { -3, 39 }, { -5, 53 }, { -7, 61 },
+ { -11, 75 }, { -15, 77 }, { -17, 91 }, { -25, 107 },
+ { -25, 111 }, { -28, 122 }, { -11, 76 }, { -10, 44 },
+ { -10, 52 }, { -10, 57 }, { -9, 58 }, { -16, 72 },
+ { -7, 69 }, { -4, 69 }, { -5, 74 }, { -9, 86 },
+ { -2, 73 }, { -12, 104 }, { -9, 91 }, { -31, 127 },
+ { -2, 73 }, { -12, 104 }, { -9, 91 }, { -31, 127 },
+ { -2, 73 }, { -12, 104 }, { -9, 91 }, { -31, 127 }
+ },
+
+ /* i_cabac_init_idc == 2 */
+ {
+ /* 0 - 10 */
+ { 20, -15 }, { 2, 54 }, { 3, 74 }, { 20, -15 },
+ { 2, 54 }, { 3, 74 }, { -28, 127 }, { -23, 104 },
+ { -6, 53 }, { -1, 54 }, { 7, 51 },
+
+ /* 11 - 23 */
+ { 29, 16 }, { 25, 0 }, { 14, 0 }, { -10, 51 },
+ { -3, 62 }, { -27, 99 }, { 26, 16 }, { -4, 85 },
+ { -24, 102 }, { 5, 57 }, { 6, 57 }, { -17, 73 },
+ { 14, 57 },
+
+ /* 24 - 39 */
+ { 20, 40 }, { 20, 10 }, { 29, 0 }, { 54, 0 },
+ { 37, 42 }, { 12, 97 }, { -32, 127 }, { -22, 117 },
+ { -2, 74 }, { -4, 85 }, { -24, 102 }, { 5, 57 },
+ { -6, 93 }, { -14, 88 }, { -6, 44 }, { 4, 55 },
+
+ /* 40 - 53 */
+ { -11, 89 },{ -15, 103 },{ -21, 116 },{ 19, 57 },
+ { 20, 58 },{ 4, 84 },{ 6, 96 },{ 1, 63 },
+ { -5, 85 },{ -13, 106 },{ 5, 63 },{ 6, 75 },
+ { -3, 90 },{ -1, 101 },
+
+ /* 54 - 59 */
+ { 3, 55 },{ -4, 79 },{ -2, 75 },{ -12, 97 },
+ { -7, 50 },{ 1, 60 },
+
+ /* 60 - 69 */
+ { 0, 41 }, { 0, 63 }, { 0, 63 }, { 0, 63 },
+ { -9, 83 }, { 4, 86 }, { 0, 97 }, { -7, 72 },
+ { 13, 41 }, { 3, 62 },
+
+ /* 70 - 104 */
+ { 7, 34 }, { -9, 88 }, { -20, 127 }, { -36, 127 },
+ { -17, 91 }, { -14, 95 }, { -25, 84 }, { -25, 86 },
+ { -12, 89 }, { -17, 91 }, { -31, 127 }, { -14, 76 },
+ { -18, 103 }, { -13, 90 }, { -37, 127 }, { 11, 80 },
+ { 5, 76 }, { 2, 84 }, { 5, 78 }, { -6, 55 },
+ { 4, 61 }, { -14, 83 }, { -37, 127 }, { -5, 79 },
+ { -11, 104 }, { -11, 91 }, { -30, 127 }, { 0, 65 },
+ { -2, 79 }, { 0, 72 }, { -4, 92 }, { -6, 56 },
+ { 3, 68 }, { -8, 71 }, { -13, 98 },
+
+ /* 105 -> 165 */
+ { -4, 86 }, { -12, 88 }, { -5, 82 }, { -3, 72 },
+ { -4, 67 }, { -8, 72 }, { -16, 89 }, { -9, 69 },
+ { -1, 59 }, { 5, 66 }, { 4, 57 }, { -4, 71 },
+ { -2, 71 }, { 2, 58 }, { -1, 74 }, { -4, 44 },
+ { -1, 69 }, { 0, 62 }, { -7, 51 }, { -4, 47 },
+ { -6, 42 }, { -3, 41 }, { -6, 53 }, { 8, 76 },
+ { -9, 78 }, { -11, 83 }, { 9, 52 }, { 0, 67 },
+ { -5, 90 }, { 1, 67 }, { -15, 72 }, { -5, 75 },
+ { -8, 80 }, { -21, 83 }, { -21, 64 }, { -13, 31 },
+ { -25, 64 }, { -29, 94 }, { 9, 75 }, { 17, 63 },
+ { -8, 74 }, { -5, 35 }, { -2, 27 }, { 13, 91 },
+ { 3, 65 }, { -7, 69 }, { 8, 77 }, { -10, 66 },
+ { 3, 62 }, { -3, 68 }, { -20, 81 }, { 0, 30 },
+ { 1, 7 }, { -3, 23 }, { -21, 74 }, { 16, 66 },
+ { -23, 124 }, { 17, 37 }, { 44, -18 }, { 50, -34 },
+ { -22, 127 },
+
+ /* 166 - 226 */
+ { 4, 39 }, { 0, 42 }, { 7, 34 }, { 11, 29 },
+ { 8, 31 }, { 6, 37 }, { 7, 42 }, { 3, 40 },
+ { 8, 33 }, { 13, 43 }, { 13, 36 }, { 4, 47 },
+ { 3, 55 }, { 2, 58 }, { 6, 60 }, { 8, 44 },
+ { 11, 44 }, { 14, 42 }, { 7, 48 }, { 4, 56 },
+ { 4, 52 }, { 13, 37 }, { 9, 49 }, { 19, 58 },
+ { 10, 48 }, { 12, 45 }, { 0, 69 }, { 20, 33 },
+ { 8, 63 }, { 35, -18 }, { 33, -25 }, { 28, -3 },
+ { 24, 10 }, { 27, 0 }, { 34, -14 }, { 52, -44 },
+ { 39, -24 }, { 19, 17 }, { 31, 25 }, { 36, 29 },
+ { 24, 33 }, { 34, 15 }, { 30, 20 }, { 22, 73 },
+ { 20, 34 }, { 19, 31 }, { 27, 44 }, { 19, 16 },
+ { 15, 36 }, { 15, 36 }, { 21, 28 }, { 25, 21 },
+ { 30, 20 }, { 31, 12 }, { 27, 16 }, { 24, 42 },
+ { 0, 93 }, { 14, 56 }, { 15, 57 }, { 26, 38 },
+ { -24, 127 },
+
+ /* 227 - 275 */
+ { -24, 115 }, { -22, 82 }, { -9, 62 }, { 0, 53 },
+ { 0, 59 }, { -14, 85 }, { -13, 89 }, { -13, 94 },
+ { -11, 92 }, { -29, 127 }, { -21, 100 }, { -14, 57 },
+ { -12, 67 }, { -11, 71 }, { -10, 77 }, { -21, 85 },
+ { -16, 88 }, { -23, 104 }, { -15, 98 }, { -37, 127 },
+ { -10, 82 }, { -8, 48 }, { -8, 61 }, { -8, 66 },
+ { -7, 70 }, { -14, 75 }, { -10, 79 }, { -9, 83 },
+ { -12, 92 }, { -18, 108 }, { -4, 79 }, { -22, 69 },
+ { -16, 75 }, { -2, 58 }, { 1, 58 }, { -13, 78 },
+ { -9, 83 }, { -4, 81 }, { -13, 99 }, { -13, 81 },
+ { -6, 38 }, { -13, 62 }, { -6, 58 }, { -2, 59 },
+ { -16, 73 }, { -10, 76 }, { -13, 86 }, { -9, 83 },
+ { -10, 87 },
+
+ /* 276 a bit special (not used, bypass is used instead) */
+ { 0, 0 },
+
+ /* 277 - 337 */
+ { -22, 127 }, { -25, 127 }, { -25, 120 }, { -27, 127 },
+ { -19, 114 }, { -23, 117 }, { -25, 118 }, { -26, 117 },
+ { -24, 113 }, { -28, 118 }, { -31, 120 }, { -37, 124 },
+ { -10, 94 }, { -15, 102 }, { -10, 99 }, { -13, 106 },
+ { -50, 127 }, { -5, 92 }, { 17, 57 }, { -5, 86 },
+ { -13, 94 }, { -12, 91 }, { -2, 77 }, { 0, 71 },
+ { -1, 73 }, { 4, 64 }, { -7, 81 }, { 5, 64 },
+ { 15, 57 }, { 1, 67 }, { 0, 68 }, { -10, 67 },
+ { 1, 68 }, { 0, 77 }, { 2, 64 }, { 0, 68 },
+ { -5, 78 }, { 7, 55 }, { 5, 59 }, { 2, 65 },
+ { 14, 54 }, { 15, 44 }, { 5, 60 }, { 2, 70 },
+ { -2, 76 }, { -18, 86 }, { 12, 70 }, { 5, 64 },
+ { -12, 70 }, { 11, 55 }, { 5, 56 }, { 0, 69 },
+ { 2, 65 }, { -6, 74 }, { 5, 54 }, { 7, 54 },
+ { -6, 76 }, { -11, 82 }, { -2, 77 }, { -2, 77 },
+ { 25, 42 },
+
+ /* 338 - 398 */
+ { 17, -13 }, { 16, -9 }, { 17, -12 }, { 27, -21 },
+ { 37, -30 }, { 41, -40 }, { 42, -41 }, { 48, -47 },
+ { 39, -32 }, { 46, -40 }, { 52, -51 }, { 46, -41 },
+ { 52, -39 }, { 43, -19 }, { 32, 11 }, { 61, -55 },
+ { 56, -46 }, { 62, -50 }, { 81, -67 }, { 45, -20 },
+ { 35, -2 }, { 28, 15 }, { 34, 1 }, { 39, 1 },
+ { 30, 17 }, { 20, 38 }, { 18, 45 }, { 15, 54 },
+ { 0, 79 }, { 36, -16 }, { 37, -14 }, { 37, -17 },
+ { 32, 1 }, { 34, 15 }, { 29, 15 }, { 24, 25 },
+ { 34, 22 }, { 31, 16 }, { 35, 18 }, { 31, 28 },
+ { 33, 41 }, { 36, 28 }, { 27, 47 }, { 21, 62 },
+ { 18, 31 }, { 19, 26 }, { 36, 24 }, { 24, 23 },
+ { 27, 16 }, { 24, 30 }, { 31, 29 }, { 22, 41 },
+ { 22, 42 }, { 16, 60 }, { 15, 52 }, { 14, 60 },
+ { 3, 78 }, { -16, 123 }, { 21, 53 }, { 22, 56 },
+ { 25, 61 },
+
+ /* 399 - 435 */
+ { 21, 33 }, { 19, 50 }, { 17, 61 },
+ { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 },
+ { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 },
+ { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 },
+ { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 },
+ { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 },
+ { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 },
+ { -9, 71 }, { -7, 37 }, { -8, 44 }, { -11, 49 },
+ { -10, 56 }, { -12, 59 }, { -8, 63 }, { -9, 67 },
+ { -6, 68 }, { -10, 79 },
+
+ /* 436 - 459 */
+ { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 },
+ { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 },
+ { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 },
+ { -14, 59 }, { -9, 52 }, { -11, 68 }, { 9, -2 },
+ { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 },
+ { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 },
+
+ /* 460 - 1024 */
+ { 11, 80 }, { 5, 76 }, { 2, 84 }, { 5, 78 },
+ { -6, 55 }, { 4, 61 }, { -14, 83 }, { -37, 127 },
+ { -5, 79 }, { -11, 104 }, { -11, 91 }, { -30, 127 },
+ { 11, 80 }, { 5, 76 }, { 2, 84 }, { 5, 78 },
+ { -6, 55 }, { 4, 61 }, { -14, 83 }, { -37, 127 },
+ { -5, 79 }, { -11, 104 }, { -11, 91 }, { -30, 127 },
+ { -4, 86 }, { -12, 88 }, { -5, 82 }, { -3, 72 },
+ { -4, 67 }, { -8, 72 }, { -16, 89 }, { -9, 69 },
+ { -1, 59 }, { 5, 66 }, { 4, 57 }, { -4, 71 },
+ { -2, 71 }, { 2, 58 }, { -1, 74 }, { -4, 44 },
+ { -1, 69 }, { 0, 62 }, { -7, 51 }, { -4, 47 },
+ { -6, 42 }, { -3, 41 }, { -6, 53 }, { 8, 76 },
+ { -9, 78 }, { -11, 83 }, { 9, 52 }, { 0, 67 },
+ { -5, 90 }, { 1, 67 }, { -15, 72 }, { -5, 75 },
+ { -8, 80 }, { -21, 83 }, { -21, 64 }, { -13, 31 },
+ { -25, 64 }, { -29, 94 }, { 9, 75 }, { 17, 63 },
+ { -8, 74 }, { -5, 35 }, { -2, 27 }, { 13, 91 },
+ { -4, 86 }, { -12, 88 }, { -5, 82 }, { -3, 72 },
+ { -4, 67 }, { -8, 72 }, { -16, 89 }, { -9, 69 },
+ { -1, 59 }, { 5, 66 }, { 4, 57 }, { -4, 71 },
+ { -2, 71 }, { 2, 58 }, { -1, 74 }, { -4, 44 },
+ { -1, 69 }, { 0, 62 }, { -7, 51 }, { -4, 47 },
+ { -6, 42 }, { -3, 41 }, { -6, 53 }, { 8, 76 },
+ { -9, 78 }, { -11, 83 }, { 9, 52 }, { 0, 67 },
+ { -5, 90 }, { 1, 67 }, { -15, 72 }, { -5, 75 },
+ { -8, 80 }, { -21, 83 }, { -21, 64 }, { -13, 31 },
+ { -25, 64 }, { -29, 94 }, { 9, 75 }, { 17, 63 },
+ { -8, 74 }, { -5, 35 }, { -2, 27 }, { 13, 91 },
+ { 4, 39 }, { 0, 42 }, { 7, 34 }, { 11, 29 },
+ { 8, 31 }, { 6, 37 }, { 7, 42 }, { 3, 40 },
+ { 8, 33 }, { 13, 43 }, { 13, 36 }, { 4, 47 },
+ { 3, 55 }, { 2, 58 }, { 6, 60 }, { 8, 44 },
+ { 11, 44 }, { 14, 42 }, { 7, 48 }, { 4, 56 },
+ { 4, 52 }, { 13, 37 }, { 9, 49 }, { 19, 58 },
+ { 10, 48 }, { 12, 45 }, { 0, 69 }, { 20, 33 },
+ { 8, 63 }, { 35, -18 }, { 33, -25 }, { 28, -3 },
+ { 24, 10 }, { 27, 0 }, { 34, -14 }, { 52, -44 },
+ { 39, -24 }, { 19, 17 }, { 31, 25 }, { 36, 29 },
+ { 24, 33 }, { 34, 15 }, { 30, 20 }, { 22, 73 },
+ { 4, 39 }, { 0, 42 }, { 7, 34 }, { 11, 29 },
+ { 8, 31 }, { 6, 37 }, { 7, 42 }, { 3, 40 },
+ { 8, 33 }, { 13, 43 }, { 13, 36 }, { 4, 47 },
+ { 3, 55 }, { 2, 58 }, { 6, 60 }, { 8, 44 },
+ { 11, 44 }, { 14, 42 }, { 7, 48 }, { 4, 56 },
+ { 4, 52 }, { 13, 37 }, { 9, 49 }, { 19, 58 },
+ { 10, 48 }, { 12, 45 }, { 0, 69 }, { 20, 33 },
+ { 8, 63 }, { 35, -18 }, { 33, -25 }, { 28, -3 },
+ { 24, 10 }, { 27, 0 }, { 34, -14 }, { 52, -44 },
+ { 39, -24 }, { 19, 17 }, { 31, 25 }, { 36, 29 },
+ { 24, 33 }, { 34, 15 }, { 30, 20 }, { 22, 73 },
+ { -3, 78 }, { -8, 74 }, { -9, 72 }, { -10, 72 },
+ { -18, 75 }, { -12, 71 }, { -11, 63 }, { -5, 70 },
+ { -17, 75 }, { -14, 72 }, { -16, 67 }, { -8, 53 },
+ { -14, 59 }, { -9, 52 }, { -11, 68 }, { -3, 78 },
+ { -8, 74 }, { -9, 72 }, { -10, 72 }, { -18, 75 },
+ { -12, 71 }, { -11, 63 }, { -5, 70 }, { -17, 75 },
+ { -14, 72 }, { -16, 67 }, { -8, 53 }, { -14, 59 },
+ { -9, 52 }, { -11, 68 }, { 9, -2 }, { 30, -10 },
+ { 31, -4 }, { 33, -1 }, { 33, 7 }, { 31, 12 },
+ { 37, 23 }, { 31, 38 }, { 20, 64 }, { 9, -2 },
+ { 30, -10 }, { 31, -4 }, { 33, -1 }, { 33, 7 },
+ { 31, 12 }, { 37, 23 }, { 31, 38 }, { 20, 64 },
+ { -9, 71 }, { -7, 37 }, { -8, 44 }, { -11, 49 },
+ { -10, 56 }, { -12, 59 }, { -8, 63 }, { -9, 67 },
+ { -6, 68 }, { -10, 79 }, { -3, 78 }, { -8, 74 },
+ { -9, 72 }, { -10, 72 }, { -18, 75 }, { -12, 71 },
+ { -11, 63 }, { -5, 70 }, { -17, 75 }, { -14, 72 },
+ { -16, 67 }, { -8, 53 }, { -14, 59 }, { -9, 52 },
+ { -11, 68 }, { -3, 78 }, { -8, 74 }, { -9, 72 },
+ { -10, 72 }, { -18, 75 }, { -12, 71 }, { -11, 63 },
+ { -5, 70 }, { -17, 75 }, { -14, 72 }, { -16, 67 },
+ { -8, 53 }, { -14, 59 }, { -9, 52 }, { -11, 68 },
+ { 9, -2 }, { 30, -10 }, { 31, -4 }, { 33, -1 },
+ { 33, 7 }, { 31, 12 }, { 37, 23 }, { 31, 38 },
+ { 20, 64 }, { 9, -2 }, { 30, -10 }, { 31, -4 },
+ { 33, -1 }, { 33, 7 }, { 31, 12 }, { 37, 23 },
+ { 31, 38 }, { 20, 64 }, { -9, 71 }, { -7, 37 },
+ { -8, 44 }, { -11, 49 }, { -10, 56 }, { -12, 59 },
+ { -8, 63 }, { -9, 67 }, { -6, 68 }, { -10, 79 },
+ { -22, 127 }, { -25, 127 }, { -25, 120 }, { -27, 127 },
+ { -19, 114 }, { -23, 117 }, { -25, 118 }, { -26, 117 },
+ { -24, 113 }, { -28, 118 }, { -31, 120 }, { -37, 124 },
+ { -10, 94 }, { -15, 102 }, { -10, 99 }, { -13, 106 },
+ { -50, 127 }, { -5, 92 }, { 17, 57 }, { -5, 86 },
+ { -13, 94 }, { -12, 91 }, { -2, 77 }, { 0, 71 },
+ { -1, 73 }, { 4, 64 }, { -7, 81 }, { 5, 64 },
+ { 15, 57 }, { 1, 67 }, { 0, 68 }, { -10, 67 },
+ { 1, 68 }, { 0, 77 }, { 2, 64 }, { 0, 68 },
+ { -5, 78 }, { 7, 55 }, { 5, 59 }, { 2, 65 },
+ { 14, 54 }, { 15, 44 }, { 5, 60 }, { 2, 70 },
+ { -22, 127 }, { -25, 127 }, { -25, 120 }, { -27, 127 },
+ { -19, 114 }, { -23, 117 }, { -25, 118 }, { -26, 117 },
+ { -24, 113 }, { -28, 118 }, { -31, 120 }, { -37, 124 },
+ { -10, 94 }, { -15, 102 }, { -10, 99 }, { -13, 106 },
+ { -50, 127 }, { -5, 92 }, { 17, 57 }, { -5, 86 },
+ { -13, 94 }, { -12, 91 }, { -2, 77 }, { 0, 71 },
+ { -1, 73 }, { 4, 64 }, { -7, 81 }, { 5, 64 },
+ { 15, 57 }, { 1, 67 }, { 0, 68 }, { -10, 67 },
+ { 1, 68 }, { 0, 77 }, { 2, 64 }, { 0, 68 },
+ { -5, 78 }, { 7, 55 }, { 5, 59 }, { 2, 65 },
+ { 14, 54 }, { 15, 44 }, { 5, 60 }, { 2, 70 },
+ { 17, -13 }, { 16, -9 }, { 17, -12 }, { 27, -21 },
+ { 37, -30 }, { 41, -40 }, { 42, -41 }, { 48, -47 },
+ { 39, -32 }, { 46, -40 }, { 52, -51 }, { 46, -41 },
+ { 52, -39 }, { 43, -19 }, { 32, 11 }, { 61, -55 },
+ { 56, -46 }, { 62, -50 }, { 81, -67 }, { 45, -20 },
+ { 35, -2 }, { 28, 15 }, { 34, 1 }, { 39, 1 },
+ { 30, 17 }, { 20, 38 }, { 18, 45 }, { 15, 54 },
+ { 0, 79 }, { 36, -16 }, { 37, -14 }, { 37, -17 },
+ { 32, 1 }, { 34, 15 }, { 29, 15 }, { 24, 25 },
+ { 34, 22 }, { 31, 16 }, { 35, 18 }, { 31, 28 },
+ { 33, 41 }, { 36, 28 }, { 27, 47 }, { 21, 62 },
+ { 17, -13 }, { 16, -9 }, { 17, -12 }, { 27, -21 },
+ { 37, -30 }, { 41, -40 }, { 42, -41 }, { 48, -47 },
+ { 39, -32 }, { 46, -40 }, { 52, -51 }, { 46, -41 },
+ { 52, -39 }, { 43, -19 }, { 32, 11 }, { 61, -55 },
+ { 56, -46 }, { 62, -50 }, { 81, -67 }, { 45, -20 },
+ { 35, -2 }, { 28, 15 }, { 34, 1 }, { 39, 1 },
+ { 30, 17 }, { 20, 38 }, { 18, 45 }, { 15, 54 },
+ { 0, 79 }, { 36, -16 }, { 37, -14 }, { 37, -17 },
+ { 32, 1 }, { 34, 15 }, { 29, 15 }, { 24, 25 },
+ { 34, 22 }, { 31, 16 }, { 35, 18 }, { 31, 28 },
+ { 33, 41 }, { 36, 28 }, { 27, 47 }, { 21, 62 },
+ { -24, 115 }, { -22, 82 }, { -9, 62 }, { 0, 53 },
+ { 0, 59 }, { -14, 85 }, { -13, 89 }, { -13, 94 },
+ { -11, 92 }, { -29, 127 }, { -21, 100 }, { -14, 57 },
+ { -12, 67 }, { -11, 71 }, { -10, 77 }, { -21, 85 },
+ { -16, 88 }, { -23, 104 }, { -15, 98 }, { -37, 127 },
+ { -10, 82 }, { -8, 48 }, { -8, 61 }, { -8, 66 },
+ { -7, 70 }, { -14, 75 }, { -10, 79 }, { -9, 83 },
+ { -12, 92 }, { -18, 108 }, { -24, 115 }, { -22, 82 },
+ { -9, 62 }, { 0, 53 }, { 0, 59 }, { -14, 85 },
+ { -13, 89 }, { -13, 94 }, { -11, 92 }, { -29, 127 },
+ { -21, 100 }, { -14, 57 }, { -12, 67 }, { -11, 71 },
+ { -10, 77 }, { -21, 85 }, { -16, 88 }, { -23, 104 },
+ { -15, 98 }, { -37, 127 }, { -10, 82 }, { -8, 48 },
+ { -8, 61 }, { -8, 66 }, { -7, 70 }, { -14, 75 },
+ { -10, 79 }, { -9, 83 }, { -12, 92 }, { -18, 108 },
+ { -5, 79 }, { -11, 104 }, { -11, 91 }, { -30, 127 },
+ { -5, 79 }, { -11, 104 }, { -11, 91 }, { -30, 127 },
+ { -5, 79 }, { -11, 104 }, { -11, 91 }, { -30, 127 }
+ }
+};
+
+void ff_h264_init_cabac_states(const H264Context *h, H264SliceContext *sl)
+{
+ int i;
+ const int8_t (*tab)[2];
+ const int slice_qp = av_clip(sl->qscale - 6*(h->sps.bit_depth_luma-8), 0, 51);
+
+ if (sl->slice_type_nos == AV_PICTURE_TYPE_I) tab = cabac_context_init_I;
+ else tab = cabac_context_init_PB[sl->cabac_init_idc];
+
+ /* calculate pre-state */
+ for( i= 0; i < 1024; i++ ) {
+ int pre = 2*(((tab[i][0] * slice_qp) >>4 ) + tab[i][1]) - 127;
+
+ pre^= pre>>31;
+ if(pre > 124)
+ pre= 124 + (pre&1);
+
+ sl->cabac_state[i] = pre;
+ }
+}
+
+static int decode_cabac_field_decoding_flag(const H264Context *h, H264SliceContext *sl)
+{
+ const int mbb_xy = sl->mb_xy - 2*h->mb_stride;
+
+ unsigned long ctx = 0;
+
+ ctx += sl->mb_field_decoding_flag & !!sl->mb_x; //for FMO:(s->current_picture.mb_type[mba_xy] >> 7) & (h->slice_table[mba_xy] == h->slice_num);
+ ctx += (h->cur_pic.mb_type[mbb_xy] >> 7) & (h->slice_table[mbb_xy] == sl->slice_num);
+
+ return get_cabac_noinline( &sl->cabac, &(sl->cabac_state+70)[ctx] );
+}
+
+static int decode_cabac_intra_mb_type(H264SliceContext *sl,
+ int ctx_base, int intra_slice)
+{
+ uint8_t *state= &sl->cabac_state[ctx_base];
+ int mb_type;
+
+ if(intra_slice){
+ int ctx=0;
+ if (sl->left_type[LTOP] & (MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM))
+ ctx++;
+ if (sl->top_type & (MB_TYPE_INTRA16x16|MB_TYPE_INTRA_PCM))
+ ctx++;
+ if( get_cabac_noinline( &sl->cabac, &state[ctx] ) == 0 )
+ return 0; /* I4x4 */
+ state += 2;
+ }else{
+ if( get_cabac_noinline( &sl->cabac, state ) == 0 )
+ return 0; /* I4x4 */
+ }
+
+ if( get_cabac_terminate( &sl->cabac ) )
+ return 25; /* PCM */
+
+ mb_type = 1; /* I16x16 */
+ mb_type += 12 * get_cabac_noinline( &sl->cabac, &state[1] ); /* cbp_luma != 0 */
+ if( get_cabac_noinline( &sl->cabac, &state[2] ) ) /* cbp_chroma */
+ mb_type += 4 + 4 * get_cabac_noinline( &sl->cabac, &state[2+intra_slice] );
+ mb_type += 2 * get_cabac_noinline( &sl->cabac, &state[3+intra_slice] );
+ mb_type += 1 * get_cabac_noinline( &sl->cabac, &state[3+2*intra_slice] );
+ return mb_type;
+}
+
+static int decode_cabac_mb_skip(const H264Context *h, H264SliceContext *sl,
+ int mb_x, int mb_y)
+{
+ int mba_xy, mbb_xy;
+ int ctx = 0;
+
+ if (FRAME_MBAFF(h)) { //FIXME merge with the stuff in fill_caches?
+ int mb_xy = mb_x + (mb_y&~1)*h->mb_stride;
+ mba_xy = mb_xy - 1;
+ if( (mb_y&1)
+ && h->slice_table[mba_xy] == sl->slice_num
+ && MB_FIELD(sl) == !!IS_INTERLACED( h->cur_pic.mb_type[mba_xy] ) )
+ mba_xy += h->mb_stride;
+ if (MB_FIELD(sl)) {
+ mbb_xy = mb_xy - h->mb_stride;
+ if( !(mb_y&1)
+ && h->slice_table[mbb_xy] == sl->slice_num
+ && IS_INTERLACED( h->cur_pic.mb_type[mbb_xy] ) )
+ mbb_xy -= h->mb_stride;
+ }else
+ mbb_xy = mb_x + (mb_y-1)*h->mb_stride;
+ }else{
+ int mb_xy = sl->mb_xy;
+ mba_xy = mb_xy - 1;
+ mbb_xy = mb_xy - (h->mb_stride << FIELD_PICTURE(h));
+ }
+
+ if( h->slice_table[mba_xy] == sl->slice_num && !IS_SKIP(h->cur_pic.mb_type[mba_xy] ))
+ ctx++;
+ if( h->slice_table[mbb_xy] == sl->slice_num && !IS_SKIP(h->cur_pic.mb_type[mbb_xy] ))
+ ctx++;
+
+ if (sl->slice_type_nos == AV_PICTURE_TYPE_B)
+ ctx += 13;
+ return get_cabac_noinline( &sl->cabac, &sl->cabac_state[11+ctx] );
+}
+
+static int decode_cabac_mb_intra4x4_pred_mode(H264SliceContext *sl, int pred_mode)
+{
+ int mode = 0;
+
+ if( get_cabac( &sl->cabac, &sl->cabac_state[68] ) )
+ return pred_mode;
+
+ mode += 1 * get_cabac( &sl->cabac, &sl->cabac_state[69] );
+ mode += 2 * get_cabac( &sl->cabac, &sl->cabac_state[69] );
+ mode += 4 * get_cabac( &sl->cabac, &sl->cabac_state[69] );
+
+ return mode + ( mode >= pred_mode );
+}
+
+static int decode_cabac_mb_chroma_pre_mode(const H264Context *h, H264SliceContext *sl)
+{
+ const int mba_xy = sl->left_mb_xy[0];
+ const int mbb_xy = sl->top_mb_xy;
+
+ int ctx = 0;
+
+ /* No need to test for IS_INTRA4x4 and IS_INTRA16x16, as we set chroma_pred_mode_table to 0 */
+ if (sl->left_type[LTOP] && h->chroma_pred_mode_table[mba_xy] != 0)
+ ctx++;
+
+ if (sl->top_type && h->chroma_pred_mode_table[mbb_xy] != 0)
+ ctx++;
+
+ if( get_cabac_noinline( &sl->cabac, &sl->cabac_state[64+ctx] ) == 0 )
+ return 0;
+
+ if( get_cabac_noinline( &sl->cabac, &sl->cabac_state[64+3] ) == 0 )
+ return 1;
+ if( get_cabac_noinline( &sl->cabac, &sl->cabac_state[64+3] ) == 0 )
+ return 2;
+ else
+ return 3;
+}
+
+static int decode_cabac_mb_cbp_luma(H264SliceContext *sl)
+{
+ int cbp_b, cbp_a, ctx, cbp = 0;
+
+ cbp_a = sl->left_cbp;
+ cbp_b = sl->top_cbp;
+
+ ctx = !(cbp_a & 0x02) + 2 * !(cbp_b & 0x04);
+ cbp += get_cabac_noinline(&sl->cabac, &sl->cabac_state[73 + ctx]);
+ ctx = !(cbp & 0x01) + 2 * !(cbp_b & 0x08);
+ cbp += get_cabac_noinline(&sl->cabac, &sl->cabac_state[73 + ctx]) << 1;
+ ctx = !(cbp_a & 0x08) + 2 * !(cbp & 0x01);
+ cbp += get_cabac_noinline(&sl->cabac, &sl->cabac_state[73 + ctx]) << 2;
+ ctx = !(cbp & 0x04) + 2 * !(cbp & 0x02);
+ cbp += get_cabac_noinline(&sl->cabac, &sl->cabac_state[73 + ctx]) << 3;
+ return cbp;
+}
+static int decode_cabac_mb_cbp_chroma(H264SliceContext *sl)
+{
+ int ctx;
+ int cbp_a, cbp_b;
+
+ cbp_a = (sl->left_cbp>>4)&0x03;
+ cbp_b = (sl-> top_cbp>>4)&0x03;
+
+ ctx = 0;
+ if( cbp_a > 0 ) ctx++;
+ if( cbp_b > 0 ) ctx += 2;
+ if( get_cabac_noinline( &sl->cabac, &sl->cabac_state[77 + ctx] ) == 0 )
+ return 0;
+
+ ctx = 4;
+ if( cbp_a == 2 ) ctx++;
+ if( cbp_b == 2 ) ctx += 2;
+ return 1 + get_cabac_noinline( &sl->cabac, &sl->cabac_state[77 + ctx] );
+}
+
+static int decode_cabac_p_mb_sub_type(H264SliceContext *sl)
+{
+ if( get_cabac( &sl->cabac, &sl->cabac_state[21] ) )
+ return 0; /* 8x8 */
+ if( !get_cabac( &sl->cabac, &sl->cabac_state[22] ) )
+ return 1; /* 8x4 */
+ if( get_cabac( &sl->cabac, &sl->cabac_state[23] ) )
+ return 2; /* 4x8 */
+ return 3; /* 4x4 */
+}
+static int decode_cabac_b_mb_sub_type(H264SliceContext *sl)
+{
+ int type;
+ if( !get_cabac( &sl->cabac, &sl->cabac_state[36] ) )
+ return 0; /* B_Direct_8x8 */
+ if( !get_cabac( &sl->cabac, &sl->cabac_state[37] ) )
+ return 1 + get_cabac( &sl->cabac, &sl->cabac_state[39] ); /* B_L0_8x8, B_L1_8x8 */
+ type = 3;
+ if( get_cabac( &sl->cabac, &sl->cabac_state[38] ) ) {
+ if( get_cabac( &sl->cabac, &sl->cabac_state[39] ) )
+ return 11 + get_cabac( &sl->cabac, &sl->cabac_state[39] ); /* B_L1_4x4, B_Bi_4x4 */
+ type += 4;
+ }
+ type += 2*get_cabac( &sl->cabac, &sl->cabac_state[39] );
+ type += get_cabac( &sl->cabac, &sl->cabac_state[39] );
+ return type;
+}
+
+static int decode_cabac_mb_ref(H264SliceContext *sl, int list, int n)
+{
+ int refa = sl->ref_cache[list][scan8[n] - 1];
+ int refb = sl->ref_cache[list][scan8[n] - 8];
+ int ref = 0;
+ int ctx = 0;
+
+ if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
+ if( refa > 0 && !(sl->direct_cache[scan8[n] - 1]&(MB_TYPE_DIRECT2>>1)) )
+ ctx++;
+ if( refb > 0 && !(sl->direct_cache[scan8[n] - 8]&(MB_TYPE_DIRECT2>>1)) )
+ ctx += 2;
+ } else {
+ if( refa > 0 )
+ ctx++;
+ if( refb > 0 )
+ ctx += 2;
+ }
+
+ while( get_cabac( &sl->cabac, &sl->cabac_state[54+ctx] ) ) {
+ ref++;
+ ctx = (ctx>>2)+4;
+ if(ref >= 32 /*h->ref_list[list]*/){
+ return -1;
+ }
+ }
+ return ref;
+}
+
+static int decode_cabac_mb_mvd(H264SliceContext *sl, int ctxbase, int amvd, int *mvda)
+{
+ int mvd;
+
+ if(!get_cabac(&sl->cabac, &sl->cabac_state[ctxbase+((amvd-3)>>(INT_BIT-1))+((amvd-33)>>(INT_BIT-1))+2])){
+// if(!get_cabac(&sl->cabac, &sl->cabac_state[ctxbase+(amvd>2)+(amvd>32)])){
+ *mvda= 0;
+ return 0;
+ }
+
+ mvd= 1;
+ ctxbase+= 3;
+ while( mvd < 9 && get_cabac( &sl->cabac, &sl->cabac_state[ctxbase] ) ) {
+ if( mvd < 4 )
+ ctxbase++;
+ mvd++;
+ }
+
+ if( mvd >= 9 ) {
+ int k = 3;
+ while( get_cabac_bypass( &sl->cabac ) ) {
+ mvd += 1 << k;
+ k++;
+ if(k>24){
+ av_log(sl->h264->avctx, AV_LOG_ERROR, "overflow in decode_cabac_mb_mvd\n");
+ return INT_MIN;
+ }
+ }
+ while( k-- ) {
+ mvd += get_cabac_bypass( &sl->cabac )<<k;
+ }
+ *mvda=mvd < 70 ? mvd : 70;
+ }else
+ *mvda=mvd;
+ return get_cabac_bypass_sign( &sl->cabac, -mvd );
+}
+
+#define DECODE_CABAC_MB_MVD(sl, list, n )\
+{\
+ int amvd0 = sl->mvd_cache[list][scan8[n] - 1][0] +\
+ sl->mvd_cache[list][scan8[n] - 8][0];\
+ int amvd1 = sl->mvd_cache[list][scan8[n] - 1][1] +\
+ sl->mvd_cache[list][scan8[n] - 8][1];\
+\
+ mx += decode_cabac_mb_mvd(sl, 40, amvd0, &mpx);\
+ my += decode_cabac_mb_mvd(sl, 47, amvd1, &mpy);\
+}
+
+static av_always_inline int get_cabac_cbf_ctx(H264SliceContext *sl,
+ int cat, int idx, int max_coeff,
+ int is_dc)
+{
+ int nza, nzb;
+ int ctx = 0;
+ static const uint16_t base_ctx[14] = {85,89,93,97,101,1012,460,464,468,1016,472,476,480,1020};
+
+ if( is_dc ) {
+ if( cat == 3 ) {
+ idx -= CHROMA_DC_BLOCK_INDEX;
+ nza = (sl->left_cbp>>(6+idx))&0x01;
+ nzb = (sl-> top_cbp>>(6+idx))&0x01;
+ } else {
+ idx -= LUMA_DC_BLOCK_INDEX;
+ nza = sl->left_cbp&(0x100<<idx);
+ nzb = sl-> top_cbp&(0x100<<idx);
+ }
+ } else {
+ nza = sl->non_zero_count_cache[scan8[idx] - 1];
+ nzb = sl->non_zero_count_cache[scan8[idx] - 8];
+ }
+
+ if( nza > 0 )
+ ctx++;
+
+ if( nzb > 0 )
+ ctx += 2;
+
+ return base_ctx[cat] + ctx;
+}
+
+static av_always_inline void
+decode_cabac_residual_internal(const H264Context *h, H264SliceContext *sl,
+ int16_t *block,
+ int cat, int n, const uint8_t *scantable,
+ const uint32_t *qmul, int max_coeff,
+ int is_dc, int chroma422)
+{
+ static const int significant_coeff_flag_offset[2][14] = {
+ { 105+0, 105+15, 105+29, 105+44, 105+47, 402, 484+0, 484+15, 484+29, 660, 528+0, 528+15, 528+29, 718 },
+ { 277+0, 277+15, 277+29, 277+44, 277+47, 436, 776+0, 776+15, 776+29, 675, 820+0, 820+15, 820+29, 733 }
+ };
+ static const int last_coeff_flag_offset[2][14] = {
+ { 166+0, 166+15, 166+29, 166+44, 166+47, 417, 572+0, 572+15, 572+29, 690, 616+0, 616+15, 616+29, 748 },
+ { 338+0, 338+15, 338+29, 338+44, 338+47, 451, 864+0, 864+15, 864+29, 699, 908+0, 908+15, 908+29, 757 }
+ };
+ static const int coeff_abs_level_m1_offset[14] = {
+ 227+0, 227+10, 227+20, 227+30, 227+39, 426, 952+0, 952+10, 952+20, 708, 982+0, 982+10, 982+20, 766
+ };
+ static const uint8_t significant_coeff_flag_offset_8x8[2][63] = {
+ { 0, 1, 2, 3, 4, 5, 5, 4, 4, 3, 3, 4, 4, 4, 5, 5,
+ 4, 4, 4, 4, 3, 3, 6, 7, 7, 7, 8, 9,10, 9, 8, 7,
+ 7, 6,11,12,13,11, 6, 7, 8, 9,14,10, 9, 8, 6,11,
+ 12,13,11, 6, 9,14,10, 9,11,12,13,11,14,10,12 },
+ { 0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 7, 7, 8, 4, 5,
+ 6, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,11,12,11,
+ 9, 9,10,10, 8,11,12,11, 9, 9,10,10, 8,13,13, 9,
+ 9,10,10, 8,13,13, 9, 9,10,10,14,14,14,14,14 }
+ };
+ static const uint8_t sig_coeff_offset_dc[7] = { 0, 0, 1, 1, 2, 2, 2 };
+ /* node ctx: 0..3: abslevel1 (with abslevelgt1 == 0).
+ * 4..7: abslevelgt1 + 3 (and abslevel1 doesn't matter).
+ * map node ctx => cabac ctx for level=1 */
+ static const uint8_t coeff_abs_level1_ctx[8] = { 1, 2, 3, 4, 0, 0, 0, 0 };
+ /* map node ctx => cabac ctx for level>1 */
+ static const uint8_t coeff_abs_levelgt1_ctx[2][8] = {
+ { 5, 5, 5, 5, 6, 7, 8, 9 },
+ { 5, 5, 5, 5, 6, 7, 8, 8 }, // 422/dc case
+ };
+ static const uint8_t coeff_abs_level_transition[2][8] = {
+ /* update node ctx after decoding a level=1 */
+ { 1, 2, 3, 3, 4, 5, 6, 7 },
+ /* update node ctx after decoding a level>1 */
+ { 4, 4, 4, 4, 5, 6, 7, 7 }
+ };
+
+ int index[64];
+
+ int last;
+ int coeff_count = 0;
+ int node_ctx = 0;
+
+ uint8_t *significant_coeff_ctx_base;
+ uint8_t *last_coeff_ctx_base;
+ uint8_t *abs_level_m1_ctx_base;
+
+#if !ARCH_X86
+#define CABAC_ON_STACK
+#endif
+#ifdef CABAC_ON_STACK
+#define CC &cc
+ CABACContext cc;
+ cc.range = sl->cabac.range;
+ cc.low = sl->cabac.low;
+ cc.bytestream= sl->cabac.bytestream;
+#if !UNCHECKED_BITSTREAM_READER || ARCH_AARCH64
+ cc.bytestream_end = sl->cabac.bytestream_end;
+#endif
+#else
+#define CC &sl->cabac
+#endif
+
+ significant_coeff_ctx_base = sl->cabac_state
+ + significant_coeff_flag_offset[MB_FIELD(sl)][cat];
+ last_coeff_ctx_base = sl->cabac_state
+ + last_coeff_flag_offset[MB_FIELD(sl)][cat];
+ abs_level_m1_ctx_base = sl->cabac_state
+ + coeff_abs_level_m1_offset[cat];
+
+ if( !is_dc && max_coeff == 64 ) {
+#define DECODE_SIGNIFICANCE( coefs, sig_off, last_off ) \
+ for(last= 0; last < coefs; last++) { \
+ uint8_t *sig_ctx = significant_coeff_ctx_base + sig_off; \
+ if( get_cabac( CC, sig_ctx )) { \
+ uint8_t *last_ctx = last_coeff_ctx_base + last_off; \
+ index[coeff_count++] = last; \
+ if( get_cabac( CC, last_ctx ) ) { \
+ last= max_coeff; \
+ break; \
+ } \
+ } \
+ }\
+ if( last == max_coeff -1 ) {\
+ index[coeff_count++] = last;\
+ }
+ const uint8_t *sig_off = significant_coeff_flag_offset_8x8[MB_FIELD(sl)];
+#ifdef decode_significance
+ coeff_count = decode_significance_8x8(CC, significant_coeff_ctx_base, index,
+ last_coeff_ctx_base, sig_off);
+ } else {
+ if (is_dc && chroma422) { // dc 422
+ DECODE_SIGNIFICANCE(7, sig_coeff_offset_dc[last], sig_coeff_offset_dc[last]);
+ } else {
+ coeff_count = decode_significance(CC, max_coeff, significant_coeff_ctx_base, index,
+ last_coeff_ctx_base-significant_coeff_ctx_base);
+ }
+#else
+ DECODE_SIGNIFICANCE( 63, sig_off[last], ff_h264_last_coeff_flag_offset_8x8[last] );
+ } else {
+ if (is_dc && chroma422) { // dc 422
+ DECODE_SIGNIFICANCE(7, sig_coeff_offset_dc[last], sig_coeff_offset_dc[last]);
+ } else {
+ DECODE_SIGNIFICANCE(max_coeff - 1, last, last);
+ }
+#endif
+ }
+ av_assert2(coeff_count > 0);
+
+ if( is_dc ) {
+ if( cat == 3 )
+ h->cbp_table[sl->mb_xy] |= 0x40 << (n - CHROMA_DC_BLOCK_INDEX);
+ else
+ h->cbp_table[sl->mb_xy] |= 0x100 << (n - LUMA_DC_BLOCK_INDEX);
+ sl->non_zero_count_cache[scan8[n]] = coeff_count;
+ } else {
+ if( max_coeff == 64 )
+ fill_rectangle(&sl->non_zero_count_cache[scan8[n]], 2, 2, 8, coeff_count, 1);
+ else {
+ av_assert2( cat == 1 || cat == 2 || cat == 4 || cat == 7 || cat == 8 || cat == 11 || cat == 12 );
+ sl->non_zero_count_cache[scan8[n]] = coeff_count;
+ }
+ }
+
+#define STORE_BLOCK(type) \
+ do { \
+ uint8_t *ctx = coeff_abs_level1_ctx[node_ctx] + abs_level_m1_ctx_base; \
+ \
+ int j= scantable[index[--coeff_count]]; \
+ \
+ if( get_cabac( CC, ctx ) == 0 ) { \
+ node_ctx = coeff_abs_level_transition[0][node_ctx]; \
+ if( is_dc ) { \
+ ((type*)block)[j] = get_cabac_bypass_sign( CC, -1); \
+ }else{ \
+ ((type*)block)[j] = (get_cabac_bypass_sign( CC, -qmul[j]) + 32) >> 6; \
+ } \
+ } else { \
+ int coeff_abs = 2; \
+ ctx = coeff_abs_levelgt1_ctx[is_dc && chroma422][node_ctx] + abs_level_m1_ctx_base; \
+ node_ctx = coeff_abs_level_transition[1][node_ctx]; \
+\
+ while( coeff_abs < 15 && get_cabac( CC, ctx ) ) { \
+ coeff_abs++; \
+ } \
+\
+ if( coeff_abs >= 15 ) { \
+ int j = 0; \
+ while (get_cabac_bypass(CC) && j < 30) { \
+ j++; \
+ } \
+\
+ coeff_abs=1; \
+ while( j-- ) { \
+ coeff_abs += coeff_abs + get_cabac_bypass( CC ); \
+ } \
+ coeff_abs+= 14U; \
+ } \
+\
+ if( is_dc ) { \
+ ((type*)block)[j] = get_cabac_bypass_sign( CC, -coeff_abs ); \
+ }else{ \
+ ((type*)block)[j] = ((int)(get_cabac_bypass_sign( CC, -coeff_abs ) * qmul[j] + 32)) >> 6; \
+ } \
+ } \
+ } while ( coeff_count );
+
+ if (h->pixel_shift) {
+ STORE_BLOCK(int32_t)
+ } else {
+ STORE_BLOCK(int16_t)
+ }
+#ifdef CABAC_ON_STACK
+ sl->cabac.range = cc.range ;
+ sl->cabac.low = cc.low ;
+ sl->cabac.bytestream= cc.bytestream;
+#endif
+
+}
+
+static av_noinline void decode_cabac_residual_dc_internal(const H264Context *h,
+ H264SliceContext *sl,
+ int16_t *block,
+ int cat, int n,
+ const uint8_t *scantable,
+ int max_coeff)
+{
+ decode_cabac_residual_internal(h, sl, block, cat, n, scantable, NULL, max_coeff, 1, 0);
+}
+
+static av_noinline void decode_cabac_residual_dc_internal_422(const H264Context *h,
+ H264SliceContext *sl,
+ int16_t *block,
+ int cat, int n,
+ const uint8_t *scantable,
+ int max_coeff)
+{
+ decode_cabac_residual_internal(h, sl, block, cat, n, scantable, NULL, max_coeff, 1, 1);
+}
+
+static av_noinline void decode_cabac_residual_nondc_internal(const H264Context *h,
+ H264SliceContext *sl,
+ int16_t *block,
+ int cat, int n,
+ const uint8_t *scantable,
+ const uint32_t *qmul,
+ int max_coeff)
+{
+ decode_cabac_residual_internal(h, sl, block, cat, n, scantable, qmul, max_coeff, 0, 0);
+}
+
+/* cat: 0-> DC 16x16 n = 0
+ * 1-> AC 16x16 n = luma4x4idx
+ * 2-> Luma4x4 n = luma4x4idx
+ * 3-> DC Chroma n = iCbCr
+ * 4-> AC Chroma n = 16 + 4 * iCbCr + chroma4x4idx
+ * 5-> Luma8x8 n = 4 * luma8x8idx */
+
+/* Partially inline the CABAC residual decode: inline the coded block flag.
+ * This has very little impact on binary size and improves performance
+ * because it allows improved constant propagation into get_cabac_cbf_ctx,
+ * as well as because most blocks have zero CBFs. */
+
+static av_always_inline void decode_cabac_residual_dc(const H264Context *h,
+ H264SliceContext *sl,
+ int16_t *block,
+ int cat, int n,
+ const uint8_t *scantable,
+ int max_coeff)
+{
+ /* read coded block flag */
+ if( get_cabac( &sl->cabac, &sl->cabac_state[get_cabac_cbf_ctx(sl, cat, n, max_coeff, 1)]) == 0 ) {
+ sl->non_zero_count_cache[scan8[n]] = 0;
+ return;
+ }
+ decode_cabac_residual_dc_internal(h, sl, block, cat, n, scantable, max_coeff);
+}
+
+static av_always_inline void
+decode_cabac_residual_dc_422(const H264Context *h, H264SliceContext *sl,
+ int16_t *block,
+ int cat, int n, const uint8_t *scantable,
+ int max_coeff)
+{
+ /* read coded block flag */
+ if (get_cabac(&sl->cabac, &sl->cabac_state[get_cabac_cbf_ctx(sl, cat, n, max_coeff, 1)]) == 0) {
+ sl->non_zero_count_cache[scan8[n]] = 0;
+ return;
+ }
+ decode_cabac_residual_dc_internal_422(h, sl, block, cat, n, scantable, max_coeff);
+}
+
+static av_always_inline void decode_cabac_residual_nondc(const H264Context *h,
+ H264SliceContext *sl,
+ int16_t *block,
+ int cat, int n,
+ const uint8_t *scantable,
+ const uint32_t *qmul,
+ int max_coeff)
+{
+ /* read coded block flag */
+ if( (cat != 5 || CHROMA444(h)) && get_cabac( &sl->cabac, &sl->cabac_state[get_cabac_cbf_ctx(sl, cat, n, max_coeff, 0)]) == 0) {
+ if( max_coeff == 64 ) {
+ fill_rectangle(&sl->non_zero_count_cache[scan8[n]], 2, 2, 8, 0, 1);
+ } else {
+ sl->non_zero_count_cache[scan8[n]] = 0;
+ }
+ return;
+ }
+ decode_cabac_residual_nondc_internal(h, sl, block, cat, n, scantable, qmul, max_coeff);
+}
+
+static av_always_inline void decode_cabac_luma_residual(const H264Context *h, H264SliceContext *sl,
+ const uint8_t *scan, const uint8_t *scan8x8,
+ int pixel_shift, int mb_type, int cbp, int p)
+{
+ static const uint8_t ctx_cat[4][3] = {{0,6,10},{1,7,11},{2,8,12},{5,9,13}};
+ const uint32_t *qmul;
+ int i8x8, i4x4;
+ int qscale = p == 0 ? sl->qscale : sl->chroma_qp[p - 1];
+ if( IS_INTRA16x16( mb_type ) ) {
+ AV_ZERO128(sl->mb_luma_dc[p]+0);
+ AV_ZERO128(sl->mb_luma_dc[p]+8);
+ AV_ZERO128(sl->mb_luma_dc[p]+16);
+ AV_ZERO128(sl->mb_luma_dc[p]+24);
+ decode_cabac_residual_dc(h, sl, sl->mb_luma_dc[p], ctx_cat[0][p], LUMA_DC_BLOCK_INDEX+p, scan, 16);
+
+ if( cbp&15 ) {
+ qmul = h->dequant4_coeff[p][qscale];
+ for( i4x4 = 0; i4x4 < 16; i4x4++ ) {
+ const int index = 16*p + i4x4;
+ decode_cabac_residual_nondc(h, sl, sl->mb + (16*index << pixel_shift), ctx_cat[1][p], index, scan + 1, qmul, 15);
+ }
+ } else {
+ fill_rectangle(&sl->non_zero_count_cache[scan8[16*p]], 4, 4, 8, 0, 1);
+ }
+ } else {
+ int cqm = (IS_INTRA( mb_type ) ? 0:3) + p;
+ for( i8x8 = 0; i8x8 < 4; i8x8++ ) {
+ if( cbp & (1<<i8x8) ) {
+ if( IS_8x8DCT(mb_type) ) {
+ const int index = 16*p + 4*i8x8;
+ decode_cabac_residual_nondc(h, sl, sl->mb + (16*index << pixel_shift), ctx_cat[3][p], index,
+ scan8x8, h->dequant8_coeff[cqm][qscale], 64);
+ } else {
+ qmul = h->dequant4_coeff[cqm][qscale];
+ for( i4x4 = 0; i4x4 < 4; i4x4++ ) {
+ const int index = 16*p + 4*i8x8 + i4x4;
+//START_TIMER
+ decode_cabac_residual_nondc(h, sl, sl->mb + (16*index << pixel_shift), ctx_cat[2][p], index, scan, qmul, 16);
+//STOP_TIMER("decode_residual")
+ }
+ }
+ } else {
+ fill_rectangle(&sl->non_zero_count_cache[scan8[4*i8x8+16*p]], 2, 2, 8, 0, 1);
+ }
+ }
+ }
+}
+
+/**
+ * Decode a macroblock.
+ * @return 0 if OK, ER_AC_ERROR / ER_DC_ERROR / ER_MV_ERROR if an error is noticed
+ */
+int ff_h264_decode_mb_cabac(const H264Context *h, H264SliceContext *sl)
+{
+ int mb_xy;
+ int mb_type, partition_count, cbp = 0;
+ int dct8x8_allowed= h->pps.transform_8x8_mode;
+ int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;
+ const int pixel_shift = h->pixel_shift;
+
+ mb_xy = sl->mb_xy = sl->mb_x + sl->mb_y*h->mb_stride;
+
+ ff_tlog(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, sl->mb_x, sl->mb_y);
+ if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {
+ int skip;
+ /* a skipped mb needs the aff flag from the following mb */
+ if (FRAME_MBAFF(h) && (sl->mb_y & 1) == 1 && sl->prev_mb_skipped)
+ skip = sl->next_mb_skipped;
+ else
+ skip = decode_cabac_mb_skip(h, sl, sl->mb_x, sl->mb_y );
+ /* read skip flags */
+ if( skip ) {
+ if (FRAME_MBAFF(h) && (sl->mb_y & 1) == 0) {
+ h->cur_pic.mb_type[mb_xy] = MB_TYPE_SKIP;
+ sl->next_mb_skipped = decode_cabac_mb_skip(h, sl, sl->mb_x, sl->mb_y+1 );
+ if(!sl->next_mb_skipped)
+ sl->mb_mbaff = sl->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h, sl);
+ }
+
+ decode_mb_skip(h, sl);
+
+ h->cbp_table[mb_xy] = 0;
+ h->chroma_pred_mode_table[mb_xy] = 0;
+ sl->last_qscale_diff = 0;
+
+ return 0;
+
+ }
+ }
+ if (FRAME_MBAFF(h)) {
+ if ((sl->mb_y & 1) == 0)
+ sl->mb_mbaff =
+ sl->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h, sl);
+ }
+
+ sl->prev_mb_skipped = 0;
+
+ fill_decode_neighbors(h, sl, -(MB_FIELD(sl)));
+
+ if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
+ int ctx = 0;
+ av_assert2(sl->slice_type_nos == AV_PICTURE_TYPE_B);
+
+ if (!IS_DIRECT(sl->left_type[LTOP] - 1))
+ ctx++;
+ if (!IS_DIRECT(sl->top_type - 1))
+ ctx++;
+
+ if( !get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+ctx] ) ){
+ mb_type= 0; /* B_Direct_16x16 */
+ }else if( !get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+3] ) ) {
+ mb_type= 1 + get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] ); /* B_L[01]_16x16 */
+ }else{
+ int bits;
+ bits = get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+4] ) << 3;
+ bits+= get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] ) << 2;
+ bits+= get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] ) << 1;
+ bits+= get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] );
+ if( bits < 8 ){
+ mb_type= bits + 3; /* B_Bi_16x16 through B_L1_L0_16x8 */
+ }else if( bits == 13 ){
+ mb_type = decode_cabac_intra_mb_type(sl, 32, 0);
+ goto decode_intra_mb;
+ }else if( bits == 14 ){
+ mb_type= 11; /* B_L1_L0_8x16 */
+ }else if( bits == 15 ){
+ mb_type= 22; /* B_8x8 */
+ }else{
+ bits= ( bits<<1 ) + get_cabac_noinline( &sl->cabac, &sl->cabac_state[27+5] );
+ mb_type= bits - 4; /* B_L0_Bi_* through B_Bi_Bi_* */
+ }
+ }
+ partition_count= b_mb_type_info[mb_type].partition_count;
+ mb_type= b_mb_type_info[mb_type].type;
+ } else if (sl->slice_type_nos == AV_PICTURE_TYPE_P) {
+ if( get_cabac_noinline( &sl->cabac, &sl->cabac_state[14] ) == 0 ) {
+ /* P-type */
+ if( get_cabac_noinline( &sl->cabac, &sl->cabac_state[15] ) == 0 ) {
+ /* P_L0_D16x16, P_8x8 */
+ mb_type= 3 * get_cabac_noinline( &sl->cabac, &sl->cabac_state[16] );
+ } else {
+ /* P_L0_D8x16, P_L0_D16x8 */
+ mb_type= 2 - get_cabac_noinline( &sl->cabac, &sl->cabac_state[17] );
+ }
+ partition_count= p_mb_type_info[mb_type].partition_count;
+ mb_type= p_mb_type_info[mb_type].type;
+ } else {
+ mb_type = decode_cabac_intra_mb_type(sl, 17, 0);
+ goto decode_intra_mb;
+ }
+ } else {
+ mb_type = decode_cabac_intra_mb_type(sl, 3, 1);
+ if (sl->slice_type == AV_PICTURE_TYPE_SI && mb_type)
+ mb_type--;
+ av_assert2(sl->slice_type_nos == AV_PICTURE_TYPE_I);
+decode_intra_mb:
+ partition_count = 0;
+ cbp= i_mb_type_info[mb_type].cbp;
+ sl->intra16x16_pred_mode = i_mb_type_info[mb_type].pred_mode;
+ mb_type= i_mb_type_info[mb_type].type;
+ }
+ if (MB_FIELD(sl))
+ mb_type |= MB_TYPE_INTERLACED;
+
+ h->slice_table[mb_xy] = sl->slice_num;
+
+ if(IS_INTRA_PCM(mb_type)) {
+ const int mb_size = ff_h264_mb_sizes[h->sps.chroma_format_idc] *
+ h->sps.bit_depth_luma >> 3;
+ const uint8_t *ptr;
+ int ret;
+
+ // We assume these blocks are very rare so we do not optimize it.
+ // FIXME The two following lines get the bitstream position in the cabac
+ // decode, I think it should be done by a function in cabac.h (or cabac.c).
+ ptr= sl->cabac.bytestream;
+ if(sl->cabac.low&0x1) ptr--;
+ if(CABAC_BITS==16){
+ if(sl->cabac.low&0x1FF) ptr--;
+ }
+
+ // The pixels are stored in the same order as levels in h->mb array.
+ if ((int) (sl->cabac.bytestream_end - ptr) < mb_size)
+ return -1;
+ sl->intra_pcm_ptr = ptr;
+ ptr += mb_size;
+
+ ret = ff_init_cabac_decoder(&sl->cabac, ptr, sl->cabac.bytestream_end - ptr);
+ if (ret < 0)
+ return ret;
+
+ // All blocks are present
+ h->cbp_table[mb_xy] = 0xf7ef;
+ h->chroma_pred_mode_table[mb_xy] = 0;
+ // In deblocking, the quantizer is 0
+ h->cur_pic.qscale_table[mb_xy] = 0;
+ // All coeffs are present
+ memset(h->non_zero_count[mb_xy], 16, 48);
+ h->cur_pic.mb_type[mb_xy] = mb_type;
+ sl->last_qscale_diff = 0;
+ return 0;
+ }
+
+ fill_decode_caches(h, sl, mb_type);
+
+ if( IS_INTRA( mb_type ) ) {
+ int i, pred_mode;
+ if( IS_INTRA4x4( mb_type ) ) {
+ if (dct8x8_allowed && get_cabac_noinline(&sl->cabac, &sl->cabac_state[399 + sl->neighbor_transform_size])) {
+ mb_type |= MB_TYPE_8x8DCT;
+ for( i = 0; i < 16; i+=4 ) {
+ int pred = pred_intra_mode(h, sl, i);
+ int mode = decode_cabac_mb_intra4x4_pred_mode(sl, pred);
+ fill_rectangle(&sl->intra4x4_pred_mode_cache[scan8[i]], 2, 2, 8, mode, 1);
+ }
+ } else {
+ for( i = 0; i < 16; i++ ) {
+ int pred = pred_intra_mode(h, sl, i);
+ sl->intra4x4_pred_mode_cache[scan8[i]] = decode_cabac_mb_intra4x4_pred_mode(sl, pred);
+
+ ff_tlog(h->avctx, "i4x4 pred=%d mode=%d\n", pred,
+ sl->intra4x4_pred_mode_cache[scan8[i]]);
+ }
+ }
+ write_back_intra_pred_mode(h, sl);
+ if (ff_h264_check_intra4x4_pred_mode(h, sl) < 0 ) return -1;
+ } else {
+ sl->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, sl, sl->intra16x16_pred_mode, 0);
+ if (sl->intra16x16_pred_mode < 0) return -1;
+ }
+ if(decode_chroma){
+ h->chroma_pred_mode_table[mb_xy] =
+ pred_mode = decode_cabac_mb_chroma_pre_mode(h, sl);
+
+ pred_mode= ff_h264_check_intra_pred_mode(h, sl, pred_mode, 1 );
+ if( pred_mode < 0 ) return -1;
+ sl->chroma_pred_mode = pred_mode;
+ } else {
+ sl->chroma_pred_mode = DC_128_PRED8x8;
+ }
+ } else if( partition_count == 4 ) {
+ int i, j, sub_partition_count[4], list, ref[2][4];
+
+ if (sl->slice_type_nos == AV_PICTURE_TYPE_B ) {
+ for( i = 0; i < 4; i++ ) {
+ sl->sub_mb_type[i] = decode_cabac_b_mb_sub_type(sl);
+ sub_partition_count[i] = b_sub_mb_type_info[sl->sub_mb_type[i]].partition_count;
+ sl->sub_mb_type[i] = b_sub_mb_type_info[sl->sub_mb_type[i]].type;
+ }
+ if (IS_DIRECT(sl->sub_mb_type[0] | sl->sub_mb_type[1] |
+ sl->sub_mb_type[2] | sl->sub_mb_type[3])) {
+ ff_h264_pred_direct_motion(h, sl, &mb_type);
+ sl->ref_cache[0][scan8[4]] =
+ sl->ref_cache[1][scan8[4]] =
+ sl->ref_cache[0][scan8[12]] =
+ sl->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;
+ for( i = 0; i < 4; i++ )
+ fill_rectangle(&sl->direct_cache[scan8[4*i]], 2, 2, 8, (sl->sub_mb_type[i] >> 1) & 0xFF, 1);
+ }
+ } else {
+ for( i = 0; i < 4; i++ ) {
+ sl->sub_mb_type[i] = decode_cabac_p_mb_sub_type(sl);
+ sub_partition_count[i] = p_sub_mb_type_info[sl->sub_mb_type[i]].partition_count;
+ sl->sub_mb_type[i] = p_sub_mb_type_info[sl->sub_mb_type[i]].type;
+ }
+ }
+
+ for( list = 0; list < sl->list_count; list++ ) {
+ for( i = 0; i < 4; i++ ) {
+ if(IS_DIRECT(sl->sub_mb_type[i])) continue;
+ if(IS_DIR(sl->sub_mb_type[i], 0, list)){
+ unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
+ if (rc > 1) {
+ ref[list][i] = decode_cabac_mb_ref(sl, list, 4 * i);
+ if (ref[list][i] >= rc) {
+ av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref[list][i], rc);
+ return -1;
+ }
+ }else
+ ref[list][i] = 0;
+ } else {
+ ref[list][i] = -1;
+ }
+ sl->ref_cache[list][scan8[4 * i] + 1] =
+ sl->ref_cache[list][scan8[4 * i] + 8] = sl->ref_cache[list][scan8[4 * i] + 9] = ref[list][i];
+ }
+ }
+
+ if(dct8x8_allowed)
+ dct8x8_allowed = get_dct8x8_allowed(h, sl);
+
+ for (list = 0; list < sl->list_count; list++) {
+ for(i=0; i<4; i++){
+ sl->ref_cache[list][scan8[4 * i]] = sl->ref_cache[list][scan8[4 * i] + 1];
+ if(IS_DIRECT(sl->sub_mb_type[i])){
+ fill_rectangle(sl->mvd_cache[list][scan8[4*i]], 2, 2, 8, 0, 2);
+ continue;
+ }
+
+ if(IS_DIR(sl->sub_mb_type[i], 0, list) && !IS_DIRECT(sl->sub_mb_type[i])){
+ const int sub_mb_type= sl->sub_mb_type[i];
+ const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1;
+ for(j=0; j<sub_partition_count[i]; j++){
+ int mpx, mpy;
+ int mx, my;
+ const int index= 4*i + block_width*j;
+ int16_t (* mv_cache)[2] = &sl->mv_cache[list][ scan8[index] ];
+ uint8_t (* mvd_cache)[2]= &sl->mvd_cache[list][ scan8[index] ];
+ pred_motion(h, sl, index, block_width, list, sl->ref_cache[list][ scan8[index] ], &mx, &my);
+ DECODE_CABAC_MB_MVD(sl, list, index)
+ ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
+
+ if(IS_SUB_8X8(sub_mb_type)){
+ mv_cache[ 1 ][0]=
+ mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx;
+ mv_cache[ 1 ][1]=
+ mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my;
+
+ mvd_cache[ 1 ][0]=
+ mvd_cache[ 8 ][0]= mvd_cache[ 9 ][0]= mpx;
+ mvd_cache[ 1 ][1]=
+ mvd_cache[ 8 ][1]= mvd_cache[ 9 ][1]= mpy;
+ }else if(IS_SUB_8X4(sub_mb_type)){
+ mv_cache[ 1 ][0]= mx;
+ mv_cache[ 1 ][1]= my;
+
+ mvd_cache[ 1 ][0]= mpx;
+ mvd_cache[ 1 ][1]= mpy;
+ }else if(IS_SUB_4X8(sub_mb_type)){
+ mv_cache[ 8 ][0]= mx;
+ mv_cache[ 8 ][1]= my;
+
+ mvd_cache[ 8 ][0]= mpx;
+ mvd_cache[ 8 ][1]= mpy;
+ }
+ mv_cache[ 0 ][0]= mx;
+ mv_cache[ 0 ][1]= my;
+
+ mvd_cache[ 0 ][0]= mpx;
+ mvd_cache[ 0 ][1]= mpy;
+ }
+ }else{
+ fill_rectangle(sl->mv_cache [list][ scan8[4*i] ], 2, 2, 8, 0, 4);
+ fill_rectangle(sl->mvd_cache[list][ scan8[4*i] ], 2, 2, 8, 0, 2);
+ }
+ }
+ }
+ } else if( IS_DIRECT(mb_type) ) {
+ ff_h264_pred_direct_motion(h, sl, &mb_type);
+ fill_rectangle(sl->mvd_cache[0][scan8[0]], 4, 4, 8, 0, 2);
+ fill_rectangle(sl->mvd_cache[1][scan8[0]], 4, 4, 8, 0, 2);
+ dct8x8_allowed &= h->sps.direct_8x8_inference_flag;
+ } else {
+ int list, i;
+ if(IS_16X16(mb_type)){
+ for (list = 0; list < sl->list_count; list++) {
+ if(IS_DIR(mb_type, 0, list)){
+ int ref;
+ unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
+ if (rc > 1) {
+ ref= decode_cabac_mb_ref(sl, list, 0);
+ if (ref >= rc) {
+ av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
+ return -1;
+ }
+ }else
+ ref=0;
+ fill_rectangle(&sl->ref_cache[list][ scan8[0] ], 4, 4, 8, ref, 1);
+ }
+ }
+ for (list = 0; list < sl->list_count; list++) {
+ if(IS_DIR(mb_type, 0, list)){
+ int mx,my,mpx,mpy;
+ pred_motion(h, sl, 0, 4, list, sl->ref_cache[list][ scan8[0] ], &mx, &my);
+ DECODE_CABAC_MB_MVD(sl, list, 0)
+ ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
+
+ fill_rectangle(sl->mvd_cache[list][ scan8[0] ], 4, 4, 8, pack8to16(mpx,mpy), 2);
+ fill_rectangle(sl->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
+ }
+ }
+ }
+ else if(IS_16X8(mb_type)){
+ for (list = 0; list < sl->list_count; list++) {
+ for(i=0; i<2; i++){
+ if(IS_DIR(mb_type, i, list)){
+ int ref;
+ unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
+ if (rc > 1) {
+ ref= decode_cabac_mb_ref(sl, list, 8 * i);
+ if (ref >= rc) {
+ av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
+ return -1;
+ }
+ }else
+ ref=0;
+ fill_rectangle(&sl->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, ref, 1);
+ }else
+ fill_rectangle(&sl->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, (LIST_NOT_USED&0xFF), 1);
+ }
+ }
+ for (list = 0; list < sl->list_count; list++) {
+ for(i=0; i<2; i++){
+ if(IS_DIR(mb_type, i, list)){
+ int mx,my,mpx,mpy;
+ pred_16x8_motion(h, sl, 8*i, list, sl->ref_cache[list][scan8[0] + 16*i], &mx, &my);
+ DECODE_CABAC_MB_MVD(sl, list, 8*i)
+ ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
+
+ fill_rectangle(sl->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack8to16(mpx,mpy), 2);
+ fill_rectangle(sl->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4);
+ }else{
+ fill_rectangle(sl->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 2);
+ fill_rectangle(sl->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4);
+ }
+ }
+ }
+ }else{
+ av_assert2(IS_8X16(mb_type));
+ for (list = 0; list < sl->list_count; list++) {
+ for(i=0; i<2; i++){
+ if(IS_DIR(mb_type, i, list)){ //FIXME optimize
+ int ref;
+ unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
+ if (rc > 1) {
+ ref = decode_cabac_mb_ref(sl, list, 4 * i);
+ if (ref >= rc) {
+ av_log(h->avctx, AV_LOG_ERROR, "Reference %d >= %d\n", ref, rc);
+ return -1;
+ }
+ }else
+ ref=0;
+ fill_rectangle(&sl->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, ref, 1);
+ }else
+ fill_rectangle(&sl->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, (LIST_NOT_USED&0xFF), 1);
+ }
+ }
+ for (list = 0; list < sl->list_count; list++) {
+ for(i=0; i<2; i++){
+ if(IS_DIR(mb_type, i, list)){
+ int mx,my,mpx,mpy;
+ pred_8x16_motion(h, sl, i*4, list, sl->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);
+ DECODE_CABAC_MB_MVD(sl, list, 4*i)
+
+ ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
+ fill_rectangle(sl->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack8to16(mpx,mpy), 2);
+ fill_rectangle(sl->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4);
+ }else{
+ fill_rectangle(sl->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 2);
+ fill_rectangle(sl->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4);
+ }
+ }
+ }
+ }
+ }
+
+ if( IS_INTER( mb_type ) ) {
+ h->chroma_pred_mode_table[mb_xy] = 0;
+ write_back_motion(h, sl, mb_type);
+ }
+
+ if( !IS_INTRA16x16( mb_type ) ) {
+ cbp = decode_cabac_mb_cbp_luma(sl);
+ if(decode_chroma)
+ cbp |= decode_cabac_mb_cbp_chroma(sl) << 4;
+ } else {
+ if (!decode_chroma && cbp>15) {
+ av_log(h->avctx, AV_LOG_ERROR, "gray chroma\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ h->cbp_table[mb_xy] = sl->cbp = cbp;
+
+ if( dct8x8_allowed && (cbp&15) && !IS_INTRA( mb_type ) ) {
+ mb_type |= MB_TYPE_8x8DCT * get_cabac_noinline(&sl->cabac, &sl->cabac_state[399 + sl->neighbor_transform_size]);
+ }
+
+ /* It would be better to do this in fill_decode_caches, but we don't know
+ * the transform mode of the current macroblock there. */
+ if (CHROMA444(h) && IS_8x8DCT(mb_type)){
+ int i;
+ uint8_t *nnz_cache = sl->non_zero_count_cache;
+ for (i = 0; i < 2; i++){
+ if (sl->left_type[LEFT(i)] && !IS_8x8DCT(sl->left_type[LEFT(i)])) {
+ nnz_cache[3+8* 1 + 2*8*i]=
+ nnz_cache[3+8* 2 + 2*8*i]=
+ nnz_cache[3+8* 6 + 2*8*i]=
+ nnz_cache[3+8* 7 + 2*8*i]=
+ nnz_cache[3+8*11 + 2*8*i]=
+ nnz_cache[3+8*12 + 2*8*i]= IS_INTRA(mb_type) ? 64 : 0;
+ }
+ }
+ if (sl->top_type && !IS_8x8DCT(sl->top_type)){
+ uint32_t top_empty = CABAC(h) && !IS_INTRA(mb_type) ? 0 : 0x40404040;
+ AV_WN32A(&nnz_cache[4+8* 0], top_empty);
+ AV_WN32A(&nnz_cache[4+8* 5], top_empty);
+ AV_WN32A(&nnz_cache[4+8*10], top_empty);
+ }
+ }
+ h->cur_pic.mb_type[mb_xy] = mb_type;
+
+ if( cbp || IS_INTRA16x16( mb_type ) ) {
+ const uint8_t *scan, *scan8x8;
+ const uint32_t *qmul;
+
+ if(IS_INTERLACED(mb_type)){
+ scan8x8 = sl->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;
+ scan = sl->qscale ? h->field_scan : h->field_scan_q0;
+ }else{
+ scan8x8 = sl->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;
+ scan = sl->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
+ }
+
+ // decode_cabac_mb_dqp
+ if(get_cabac_noinline( &sl->cabac, &sl->cabac_state[60 + (sl->last_qscale_diff != 0)])){
+ int val = 1;
+ int ctx= 2;
+ const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
+
+ while( get_cabac_noinline( &sl->cabac, &sl->cabac_state[60 + ctx] ) ) {
+ ctx= 3;
+ val++;
+ if(val > 2*max_qp){ //prevent infinite loop
+ av_log(h->avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", sl->mb_x, sl->mb_y);
+ return -1;
+ }
+ }
+
+ if( val&0x01 )
+ val= (val + 1)>>1 ;
+ else
+ val= -((val + 1)>>1);
+ sl->last_qscale_diff = val;
+ sl->qscale += val;
+ if (((unsigned)sl->qscale) > max_qp){
+ if (sl->qscale < 0) sl->qscale += max_qp + 1;
+ else sl->qscale -= max_qp + 1;
+ }
+ sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale);
+ sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale);
+ }else
+ sl->last_qscale_diff=0;
+
+ decode_cabac_luma_residual(h, sl, scan, scan8x8, pixel_shift, mb_type, cbp, 0);
+ if (CHROMA444(h)) {
+ decode_cabac_luma_residual(h, sl, scan, scan8x8, pixel_shift, mb_type, cbp, 1);
+ decode_cabac_luma_residual(h, sl, scan, scan8x8, pixel_shift, mb_type, cbp, 2);
+ } else if (CHROMA422(h)) {
+ if( cbp&0x30 ){
+ int c;
+ for (c = 0; c < 2; c++)
+ decode_cabac_residual_dc_422(h, sl, sl->mb + ((256 + 16*16*c) << pixel_shift), 3,
+ CHROMA_DC_BLOCK_INDEX + c,
+ chroma422_dc_scan, 8);
+ }
+
+ if( cbp&0x20 ) {
+ int c, i, i8x8;
+ for( c = 0; c < 2; c++ ) {
+ int16_t *mb = sl->mb + (16*(16 + 16*c) << pixel_shift);
+ qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][sl->chroma_qp[c]];
+ for (i8x8 = 0; i8x8 < 2; i8x8++) {
+ for (i = 0; i < 4; i++) {
+ const int index = 16 + 16 * c + 8*i8x8 + i;
+ decode_cabac_residual_nondc(h, sl, mb, 4, index, scan + 1, qmul, 15);
+ mb += 16<<pixel_shift;
+ }
+ }
+ }
+ } else {
+ fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
+ fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
+ }
+ } else /* yuv420 */ {
+ if( cbp&0x30 ){
+ int c;
+ for (c = 0; c < 2; c++)
+ decode_cabac_residual_dc(h, sl, sl->mb + ((256 + 16*16*c) << pixel_shift), 3, CHROMA_DC_BLOCK_INDEX+c, chroma_dc_scan, 4);
+ }
+
+ if( cbp&0x20 ) {
+ int c, i;
+ for( c = 0; c < 2; c++ ) {
+ qmul = h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][sl->chroma_qp[c]];
+ for( i = 0; i < 4; i++ ) {
+ const int index = 16 + 16 * c + i;
+ decode_cabac_residual_nondc(h, sl, sl->mb + (16*index << pixel_shift), 4, index, scan + 1, qmul, 15);
+ }
+ }
+ } else {
+ fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
+ fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
+ }
+ }
+ } else {
+ fill_rectangle(&sl->non_zero_count_cache[scan8[ 0]], 4, 4, 8, 0, 1);
+ fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
+ fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
+ sl->last_qscale_diff = 0;
+ }
+
+ h->cur_pic.qscale_table[mb_xy] = sl->qscale;
+ write_back_non_zero_count(h, sl);
+
+ return 0;
+}
diff --git a/ffmpeg-2-8-12/libavcodec/h264_cavlc.c b/ffmpeg-2-8-12/libavcodec/h264_cavlc.c
new file mode 100644
index 0000000..7a7dd39
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/h264_cavlc.c
@@ -0,0 +1,1182 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... cavlc bitstream decoding
+ * Copyright (c) 2003 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * H.264 / AVC / MPEG4 part10 cavlc bitstream decoding.
+ * @author Michael Niedermayer <michaelni at gmx.at>
+ */
+
+#define CABAC(h) 0
+#define UNCHECKED_BITSTREAM_READER 1
+
+#include "internal.h"
+#include "avcodec.h"
+#include "h264.h"
+#include "h264data.h" // FIXME FIXME FIXME
+#include "h264_mvpred.h"
+#include "golomb.h"
+#include "mpegutils.h"
+#include "libavutil/avassert.h"
+
+
+static const uint8_t golomb_to_inter_cbp_gray[16]={
+ 0, 1, 2, 4, 8, 3, 5,10,12,15, 7,11,13,14, 6, 9,
+};
+
+static const uint8_t golomb_to_intra4x4_cbp_gray[16]={
+15, 0, 7,11,13,14, 3, 5,10,12, 1, 2, 4, 8, 6, 9,
+};
+
+static const uint8_t chroma_dc_coeff_token_len[4*5]={
+ 2, 0, 0, 0,
+ 6, 1, 0, 0,
+ 6, 6, 3, 0,
+ 6, 7, 7, 6,
+ 6, 8, 8, 7,
+};
+
+static const uint8_t chroma_dc_coeff_token_bits[4*5]={
+ 1, 0, 0, 0,
+ 7, 1, 0, 0,
+ 4, 6, 1, 0,
+ 3, 3, 2, 5,
+ 2, 3, 2, 0,
+};
+
+static const uint8_t chroma422_dc_coeff_token_len[4*9]={
+ 1, 0, 0, 0,
+ 7, 2, 0, 0,
+ 7, 7, 3, 0,
+ 9, 7, 7, 5,
+ 9, 9, 7, 6,
+ 10, 10, 9, 7,
+ 11, 11, 10, 7,
+ 12, 12, 11, 10,
+ 13, 12, 12, 11,
+};
+
+static const uint8_t chroma422_dc_coeff_token_bits[4*9]={
+ 1, 0, 0, 0,
+ 15, 1, 0, 0,
+ 14, 13, 1, 0,
+ 7, 12, 11, 1,
+ 6, 5, 10, 1,
+ 7, 6, 4, 9,
+ 7, 6, 5, 8,
+ 7, 6, 5, 4,
+ 7, 5, 4, 4,
+};
+
+static const uint8_t coeff_token_len[4][4*17]={
+{
+ 1, 0, 0, 0,
+ 6, 2, 0, 0, 8, 6, 3, 0, 9, 8, 7, 5, 10, 9, 8, 6,
+ 11,10, 9, 7, 13,11,10, 8, 13,13,11, 9, 13,13,13,10,
+ 14,14,13,11, 14,14,14,13, 15,15,14,14, 15,15,15,14,
+ 16,15,15,15, 16,16,16,15, 16,16,16,16, 16,16,16,16,
+},
+{
+ 2, 0, 0, 0,
+ 6, 2, 0, 0, 6, 5, 3, 0, 7, 6, 6, 4, 8, 6, 6, 4,
+ 8, 7, 7, 5, 9, 8, 8, 6, 11, 9, 9, 6, 11,11,11, 7,
+ 12,11,11, 9, 12,12,12,11, 12,12,12,11, 13,13,13,12,
+ 13,13,13,13, 13,14,13,13, 14,14,14,13, 14,14,14,14,
+},
+{
+ 4, 0, 0, 0,
+ 6, 4, 0, 0, 6, 5, 4, 0, 6, 5, 5, 4, 7, 5, 5, 4,
+ 7, 5, 5, 4, 7, 6, 6, 4, 7, 6, 6, 4, 8, 7, 7, 5,
+ 8, 8, 7, 6, 9, 8, 8, 7, 9, 9, 8, 8, 9, 9, 9, 8,
+ 10, 9, 9, 9, 10,10,10,10, 10,10,10,10, 10,10,10,10,
+},
+{
+ 6, 0, 0, 0,
+ 6, 6, 0, 0, 6, 6, 6, 0, 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, 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, 6, 6, 6, 6, 6, 6,
+}
+};
+
+static const uint8_t coeff_token_bits[4][4*17]={
+{
+ 1, 0, 0, 0,
+ 5, 1, 0, 0, 7, 4, 1, 0, 7, 6, 5, 3, 7, 6, 5, 3,
+ 7, 6, 5, 4, 15, 6, 5, 4, 11,14, 5, 4, 8,10,13, 4,
+ 15,14, 9, 4, 11,10,13,12, 15,14, 9,12, 11,10,13, 8,
+ 15, 1, 9,12, 11,14,13, 8, 7,10, 9,12, 4, 6, 5, 8,
+},
+{
+ 3, 0, 0, 0,
+ 11, 2, 0, 0, 7, 7, 3, 0, 7,10, 9, 5, 7, 6, 5, 4,
+ 4, 6, 5, 6, 7, 6, 5, 8, 15, 6, 5, 4, 11,14,13, 4,
+ 15,10, 9, 4, 11,14,13,12, 8,10, 9, 8, 15,14,13,12,
+ 11,10, 9,12, 7,11, 6, 8, 9, 8,10, 1, 7, 6, 5, 4,
+},
+{
+ 15, 0, 0, 0,
+ 15,14, 0, 0, 11,15,13, 0, 8,12,14,12, 15,10,11,11,
+ 11, 8, 9,10, 9,14,13, 9, 8,10, 9, 8, 15,14,13,13,
+ 11,14,10,12, 15,10,13,12, 11,14, 9,12, 8,10,13, 8,
+ 13, 7, 9,12, 9,12,11,10, 5, 8, 7, 6, 1, 4, 3, 2,
+},
+{
+ 3, 0, 0, 0,
+ 0, 1, 0, 0, 4, 5, 6, 0, 8, 9,10,11, 12,13,14,15,
+ 16,17,18,19, 20,21,22,23, 24,25,26,27, 28,29,30,31,
+ 32,33,34,35, 36,37,38,39, 40,41,42,43, 44,45,46,47,
+ 48,49,50,51, 52,53,54,55, 56,57,58,59, 60,61,62,63,
+}
+};
+
+static const uint8_t total_zeros_len[16][16]= {
+ {1,3,3,4,4,5,5,6,6,7,7,8,8,9,9,9},
+ {3,3,3,3,3,4,4,4,4,5,5,6,6,6,6},
+ {4,3,3,3,4,4,3,3,4,5,5,6,5,6},
+ {5,3,4,4,3,3,3,4,3,4,5,5,5},
+ {4,4,4,3,3,3,3,3,4,5,4,5},
+ {6,5,3,3,3,3,3,3,4,3,6},
+ {6,5,3,3,3,2,3,4,3,6},
+ {6,4,5,3,2,2,3,3,6},
+ {6,6,4,2,2,3,2,5},
+ {5,5,3,2,2,2,4},
+ {4,4,3,3,1,3},
+ {4,4,2,1,3},
+ {3,3,1,2},
+ {2,2,1},
+ {1,1},
+};
+
+static const uint8_t total_zeros_bits[16][16]= {
+ {1,3,2,3,2,3,2,3,2,3,2,3,2,3,2,1},
+ {7,6,5,4,3,5,4,3,2,3,2,3,2,1,0},
+ {5,7,6,5,4,3,4,3,2,3,2,1,1,0},
+ {3,7,5,4,6,5,4,3,3,2,2,1,0},
+ {5,4,3,7,6,5,4,3,2,1,1,0},
+ {1,1,7,6,5,4,3,2,1,1,0},
+ {1,1,5,4,3,3,2,1,1,0},
+ {1,1,1,3,3,2,2,1,0},
+ {1,0,1,3,2,1,1,1},
+ {1,0,1,3,2,1,1},
+ {0,1,1,2,1,3},
+ {0,1,1,1,1},
+ {0,1,1,1},
+ {0,1,1},
+ {0,1},
+};
+
+static const uint8_t chroma_dc_total_zeros_len[3][4]= {
+ { 1, 2, 3, 3,},
+ { 1, 2, 2, 0,},
+ { 1, 1, 0, 0,},
+};
+
+static const uint8_t chroma_dc_total_zeros_bits[3][4]= {
+ { 1, 1, 1, 0,},
+ { 1, 1, 0, 0,},
+ { 1, 0, 0, 0,},
+};
+
+static const uint8_t chroma422_dc_total_zeros_len[7][8]= {
+ { 1, 3, 3, 4, 4, 4, 5, 5 },
+ { 3, 2, 3, 3, 3, 3, 3 },
+ { 3, 3, 2, 2, 3, 3 },
+ { 3, 2, 2, 2, 3 },
+ { 2, 2, 2, 2 },
+ { 2, 2, 1 },
+ { 1, 1 },
+};
+
+static const uint8_t chroma422_dc_total_zeros_bits[7][8]= {
+ { 1, 2, 3, 2, 3, 1, 1, 0 },
+ { 0, 1, 1, 4, 5, 6, 7 },
+ { 0, 1, 1, 2, 6, 7 },
+ { 6, 0, 1, 2, 7 },
+ { 0, 1, 2, 3 },
+ { 0, 1, 1 },
+ { 0, 1 },
+};
+
+static const uint8_t run_len[7][16]={
+ {1,1},
+ {1,2,2},
+ {2,2,2,2},
+ {2,2,2,3,3},
+ {2,2,3,3,3,3},
+ {2,3,3,3,3,3,3},
+ {3,3,3,3,3,3,3,4,5,6,7,8,9,10,11},
+};
+
+static const uint8_t run_bits[7][16]={
+ {1,0},
+ {1,1,0},
+ {3,2,1,0},
+ {3,2,1,1,0},
+ {3,2,3,2,1,0},
+ {3,0,1,3,2,5,4},
+ {7,6,5,4,3,2,1,1,1,1,1,1,1,1,1},
+};
+
+static VLC coeff_token_vlc[4];
+static VLC_TYPE coeff_token_vlc_tables[520+332+280+256][2];
+static const int coeff_token_vlc_tables_size[4]={520,332,280,256};
+
+static VLC chroma_dc_coeff_token_vlc;
+static VLC_TYPE chroma_dc_coeff_token_vlc_table[256][2];
+static const int chroma_dc_coeff_token_vlc_table_size = 256;
+
+static VLC chroma422_dc_coeff_token_vlc;
+static VLC_TYPE chroma422_dc_coeff_token_vlc_table[8192][2];
+static const int chroma422_dc_coeff_token_vlc_table_size = 8192;
+
+static VLC total_zeros_vlc[15];
+static VLC_TYPE total_zeros_vlc_tables[15][512][2];
+static const int total_zeros_vlc_tables_size = 512;
+
+static VLC chroma_dc_total_zeros_vlc[3];
+static VLC_TYPE chroma_dc_total_zeros_vlc_tables[3][8][2];
+static const int chroma_dc_total_zeros_vlc_tables_size = 8;
+
+static VLC chroma422_dc_total_zeros_vlc[7];
+static VLC_TYPE chroma422_dc_total_zeros_vlc_tables[7][32][2];
+static const int chroma422_dc_total_zeros_vlc_tables_size = 32;
+
+static VLC run_vlc[6];
+static VLC_TYPE run_vlc_tables[6][8][2];
+static const int run_vlc_tables_size = 8;
+
+static VLC run7_vlc;
+static VLC_TYPE run7_vlc_table[96][2];
+static const int run7_vlc_table_size = 96;
+
+#define LEVEL_TAB_BITS 8
+static int8_t cavlc_level_tab[7][1<<LEVEL_TAB_BITS][2];
+
+#define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8
+#define CHROMA422_DC_COEFF_TOKEN_VLC_BITS 13
+#define COEFF_TOKEN_VLC_BITS 8
+#define TOTAL_ZEROS_VLC_BITS 9
+#define CHROMA_DC_TOTAL_ZEROS_VLC_BITS 3
+#define CHROMA422_DC_TOTAL_ZEROS_VLC_BITS 5
+#define RUN_VLC_BITS 3
+#define RUN7_VLC_BITS 6
+
+/**
+ * Get the predicted number of non-zero coefficients.
+ * @param n block index
+ */
+static inline int pred_non_zero_count(const H264Context *h, H264SliceContext *sl, int n)
+{
+ const int index8= scan8[n];
+ const int left = sl->non_zero_count_cache[index8 - 1];
+ const int top = sl->non_zero_count_cache[index8 - 8];
+ int i= left + top;
+
+ if(i<64) i= (i+1)>>1;
+
+ ff_tlog(h->avctx, "pred_nnz L%X T%X n%d s%d P%X\n", left, top, n, scan8[n], i&31);
+
+ return i&31;
+}
+
+static av_cold void init_cavlc_level_tab(void){
+ int suffix_length;
+ unsigned int i;
+
+ for(suffix_length=0; suffix_length<7; suffix_length++){
+ for(i=0; i<(1<<LEVEL_TAB_BITS); i++){
+ int prefix= LEVEL_TAB_BITS - av_log2(2*i);
+
+ if(prefix + 1 + suffix_length <= LEVEL_TAB_BITS){
+ int level_code = (prefix << suffix_length) +
+ (i >> (av_log2(i) - suffix_length)) - (1 << suffix_length);
+ int mask = -(level_code&1);
+ level_code = (((2 + level_code) >> 1) ^ mask) - mask;
+ cavlc_level_tab[suffix_length][i][0]= level_code;
+ cavlc_level_tab[suffix_length][i][1]= prefix + 1 + suffix_length;
+ }else if(prefix + 1 <= LEVEL_TAB_BITS){
+ cavlc_level_tab[suffix_length][i][0]= prefix+100;
+ cavlc_level_tab[suffix_length][i][1]= prefix + 1;
+ }else{
+ cavlc_level_tab[suffix_length][i][0]= LEVEL_TAB_BITS+100;
+ cavlc_level_tab[suffix_length][i][1]= LEVEL_TAB_BITS;
+ }
+ }
+ }
+}
+
+av_cold void ff_h264_decode_init_vlc(void){
+ static int done = 0;
+
+ 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);
+
+ 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].table = chroma_dc_total_zeros_vlc_tables[i];
+ chroma_dc_total_zeros_vlc[i].table_allocated = chroma_dc_total_zeros_vlc_tables_size;
+ init_vlc(&chroma_dc_total_zeros_vlc[i],
+ 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].table = chroma422_dc_total_zeros_vlc_tables[i];
+ chroma422_dc_total_zeros_vlc[i].table_allocated = chroma422_dc_total_zeros_vlc_tables_size;
+ init_vlc(&chroma422_dc_total_zeros_vlc[i],
+ 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].table = total_zeros_vlc_tables[i];
+ total_zeros_vlc[i].table_allocated = total_zeros_vlc_tables_size;
+ init_vlc(&total_zeros_vlc[i],
+ 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].table = run_vlc_tables[i];
+ run_vlc[i].table_allocated = run_vlc_tables_size;
+ init_vlc(&run_vlc[i],
+ 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){
+ unsigned int buf;
+ int log;
+
+ OPEN_READER(re, gb);
+ UPDATE_CACHE(re, gb);
+ buf=GET_CACHE(re, gb);
+
+ log= 32 - av_log2(buf);
+#ifdef TRACE
+ print_bin(buf>>(32-log), log);
+ av_log(NULL, AV_LOG_DEBUG, "%5d %2d %3d lpr @%5d in %s get_level_prefix\n", buf>>(32-log), log, log-1, get_bits_count(gb), __FILE__);
+#endif
+
+ LAST_SKIP_BITS(re, gb, log);
+ CLOSE_READER(re, gb);
+
+ return log-1;
+}
+
+/**
+ * Decode a residual block.
+ * @param n block index
+ * @param scantable scantable
+ * @param max_coeff number of coefficients in the block
+ * @return <0 if an error occurred
+ */
+static int decode_residual(const H264Context *h, H264SliceContext *sl,
+ GetBitContext *gb, int16_t *block, int n,
+ const uint8_t *scantable, const uint32_t *qmul,
+ int max_coeff)
+{
+ static const int coeff_token_table_index[17]= {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3};
+ int level[16];
+ int zeros_left, coeff_token, total_coeff, i, trailing_ones, run_before;
+
+ //FIXME put trailing_onex into the context
+
+ if(max_coeff <= 8){
+ if (max_coeff == 4)
+ coeff_token = get_vlc2(gb, chroma_dc_coeff_token_vlc.table, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1);
+ else
+ coeff_token = get_vlc2(gb, chroma422_dc_coeff_token_vlc.table, CHROMA422_DC_COEFF_TOKEN_VLC_BITS, 1);
+ total_coeff= coeff_token>>2;
+ }else{
+ if(n >= LUMA_DC_BLOCK_INDEX){
+ total_coeff= pred_non_zero_count(h, sl, (n - LUMA_DC_BLOCK_INDEX)*16);
+ coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2);
+ total_coeff= coeff_token>>2;
+ }else{
+ total_coeff= pred_non_zero_count(h, sl, n);
+ coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2);
+ total_coeff= coeff_token>>2;
+ }
+ }
+ sl->non_zero_count_cache[scan8[n]] = total_coeff;
+
+ //FIXME set last_non_zero?
+
+ if(total_coeff==0)
+ return 0;
+ if(total_coeff > (unsigned)max_coeff) {
+ av_log(h->avctx, AV_LOG_ERROR, "corrupted macroblock %d %d (total_coeff=%d)\n", sl->mb_x, sl->mb_y, total_coeff);
+ return -1;
+ }
+
+ trailing_ones= coeff_token&3;
+ ff_tlog(h->avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff);
+ av_assert2(total_coeff<=16);
+
+ i = show_bits(gb, 3);
+ skip_bits(gb, trailing_ones);
+ level[0] = 1-((i&4)>>1);
+ level[1] = 1-((i&2) );
+ level[2] = 1-((i&1)<<1);
+
+ if(trailing_ones<total_coeff) {
+ int mask, prefix;
+ int suffix_length = total_coeff > 10 & trailing_ones < 3;
+ int bitsi= show_bits(gb, LEVEL_TAB_BITS);
+ int level_code= cavlc_level_tab[suffix_length][bitsi][0];
+
+ skip_bits(gb, cavlc_level_tab[suffix_length][bitsi][1]);
+ if(level_code >= 100){
+ prefix= level_code - 100;
+ if(prefix == LEVEL_TAB_BITS)
+ prefix += get_level_prefix(gb);
+
+ //first coefficient has suffix_length equal to 0 or 1
+ if(prefix<14){ //FIXME try to build a large unified VLC table for all this
+ if(suffix_length)
+ level_code= (prefix<<1) + get_bits1(gb); //part
+ else
+ level_code= prefix; //part
+ }else if(prefix==14){
+ if(suffix_length)
+ level_code= (prefix<<1) + get_bits1(gb); //part
+ else
+ level_code= prefix + get_bits(gb, 4); //part
+ }else{
+ level_code= 30;
+ if(prefix>=16){
+ if(prefix > 25+3){
+ av_log(h->avctx, AV_LOG_ERROR, "Invalid level prefix\n");
+ return -1;
+ }
+ level_code += (1<<(prefix-3))-4096;
+ }
+ level_code += get_bits(gb, prefix-3); //part
+ }
+
+ if(trailing_ones < 3) level_code += 2;
+
+ suffix_length = 2;
+ mask= -(level_code&1);
+ level[trailing_ones]= (((2+level_code)>>1) ^ mask) - mask;
+ }else{
+ level_code += ((level_code>>31)|1) & -(trailing_ones < 3);
+
+ suffix_length = 1 + (level_code + 3U > 6U);
+ level[trailing_ones]= level_code;
+ }
+
+ //remaining coefficients have suffix_length > 0
+ for(i=trailing_ones+1;i<total_coeff;i++) {
+ static const unsigned int suffix_limit[7] = {0,3,6,12,24,48,INT_MAX };
+ int bitsi= show_bits(gb, LEVEL_TAB_BITS);
+ level_code= cavlc_level_tab[suffix_length][bitsi][0];
+
+ skip_bits(gb, cavlc_level_tab[suffix_length][bitsi][1]);
+ if(level_code >= 100){
+ prefix= level_code - 100;
+ if(prefix == LEVEL_TAB_BITS){
+ prefix += get_level_prefix(gb);
+ }
+ if(prefix<15){
+ level_code = (prefix<<suffix_length) + get_bits(gb, suffix_length);
+ }else{
+ level_code = 15<<suffix_length;
+ if (prefix>=16) {
+ if(prefix > 25+3){
+ av_log(h->avctx, AV_LOG_ERROR, "Invalid level prefix\n");
+ return AVERROR_INVALIDDATA;
+ }
+ level_code += (1<<(prefix-3))-4096;
+ }
+ level_code += get_bits(gb, prefix-3);
+ }
+ mask= -(level_code&1);
+ level_code= (((2+level_code)>>1) ^ mask) - mask;
+ }
+ level[i]= level_code;
+ suffix_length+= suffix_limit[suffix_length] + level_code > 2U*suffix_limit[suffix_length];
+ }
+ }
+
+ if(total_coeff == max_coeff)
+ zeros_left=0;
+ else{
+ if (max_coeff <= 8) {
+ if (max_coeff == 4)
+ zeros_left = get_vlc2(gb, (chroma_dc_total_zeros_vlc-1)[total_coeff].table,
+ CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1);
+ else
+ zeros_left = get_vlc2(gb, (chroma422_dc_total_zeros_vlc-1)[total_coeff].table,
+ CHROMA422_DC_TOTAL_ZEROS_VLC_BITS, 1);
+ } else {
+ zeros_left= get_vlc2(gb, (total_zeros_vlc-1)[ total_coeff ].table, TOTAL_ZEROS_VLC_BITS, 1);
+ }
+ }
+
+#define STORE_BLOCK(type) \
+ scantable += zeros_left + total_coeff - 1; \
+ if(n >= LUMA_DC_BLOCK_INDEX){ \
+ ((type*)block)[*scantable] = level[0]; \
+ for(i=1;i<total_coeff && zeros_left > 0;i++) { \
+ if(zeros_left < 7) \
+ run_before= get_vlc2(gb, (run_vlc-1)[zeros_left].table, RUN_VLC_BITS, 1); \
+ else \
+ run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2); \
+ zeros_left -= run_before; \
+ scantable -= 1 + run_before; \
+ ((type*)block)[*scantable]= level[i]; \
+ } \
+ for(;i<total_coeff;i++) { \
+ scantable--; \
+ ((type*)block)[*scantable]= level[i]; \
+ } \
+ }else{ \
+ ((type*)block)[*scantable] = ((int)(level[0] * qmul[*scantable] + 32))>>6; \
+ for(i=1;i<total_coeff && zeros_left > 0;i++) { \
+ if(zeros_left < 7) \
+ run_before= get_vlc2(gb, (run_vlc-1)[zeros_left].table, RUN_VLC_BITS, 1); \
+ else \
+ run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2); \
+ zeros_left -= run_before; \
+ scantable -= 1 + run_before; \
+ ((type*)block)[*scantable]= ((int)(level[i] * qmul[*scantable] + 32))>>6; \
+ } \
+ for(;i<total_coeff;i++) { \
+ scantable--; \
+ ((type*)block)[*scantable]= ((int)(level[i] * qmul[*scantable] + 32))>>6; \
+ } \
+ }
+
+ if (h->pixel_shift) {
+ STORE_BLOCK(int32_t)
+ } else {
+ STORE_BLOCK(int16_t)
+ }
+
+ if(zeros_left<0){
+ av_log(h->avctx, AV_LOG_ERROR, "negative number of zero coeffs at %d %d\n", sl->mb_x, sl->mb_y);
+ return -1;
+ }
+
+ return 0;
+}
+
+static av_always_inline
+int decode_luma_residual(const H264Context *h, H264SliceContext *sl,
+ GetBitContext *gb, const uint8_t *scan,
+ const uint8_t *scan8x8, int pixel_shift,
+ int mb_type, int cbp, int p)
+{
+ int i4x4, i8x8;
+ int qscale = p == 0 ? sl->qscale : sl->chroma_qp[p - 1];
+ if(IS_INTRA16x16(mb_type)){
+ AV_ZERO128(sl->mb_luma_dc[p]+0);
+ AV_ZERO128(sl->mb_luma_dc[p]+8);
+ AV_ZERO128(sl->mb_luma_dc[p]+16);
+ AV_ZERO128(sl->mb_luma_dc[p]+24);
+ if (decode_residual(h, sl, gb, sl->mb_luma_dc[p], LUMA_DC_BLOCK_INDEX + p, scan, NULL, 16) < 0) {
+ return -1; //FIXME continue if partitioned and other return -1 too
+ }
+
+ av_assert2((cbp&15) == 0 || (cbp&15) == 15);
+
+ if(cbp&15){
+ for(i8x8=0; i8x8<4; i8x8++){
+ for(i4x4=0; i4x4<4; i4x4++){
+ const int index= i4x4 + 4*i8x8 + p*16;
+ if( decode_residual(h, sl, gb, sl->mb + (16*index << pixel_shift),
+ index, scan + 1, h->dequant4_coeff[p][qscale], 15) < 0 ){
+ return -1;
+ }
+ }
+ }
+ return 0xf;
+ }else{
+ fill_rectangle(&sl->non_zero_count_cache[scan8[p*16]], 4, 4, 8, 0, 1);
+ return 0;
+ }
+ }else{
+ int cqm = (IS_INTRA( mb_type ) ? 0:3)+p;
+ /* For CAVLC 4:4:4, we need to keep track of the luma 8x8 CBP for deblocking nnz purposes. */
+ int new_cbp = 0;
+ for(i8x8=0; i8x8<4; i8x8++){
+ if(cbp & (1<<i8x8)){
+ if(IS_8x8DCT(mb_type)){
+ int16_t *buf = &sl->mb[64*i8x8+256*p << pixel_shift];
+ uint8_t *nnz;
+ for(i4x4=0; i4x4<4; i4x4++){
+ const int index= i4x4 + 4*i8x8 + p*16;
+ if( decode_residual(h, sl, gb, buf, index, scan8x8+16*i4x4,
+ h->dequant8_coeff[cqm][qscale], 16) < 0 )
+ return -1;
+ }
+ nnz = &sl->non_zero_count_cache[scan8[4 * i8x8 + p * 16]];
+ nnz[0] += nnz[1] + nnz[8] + nnz[9];
+ new_cbp |= !!nnz[0] << i8x8;
+ }else{
+ for(i4x4=0; i4x4<4; i4x4++){
+ const int index= i4x4 + 4*i8x8 + p*16;
+ if( decode_residual(h, sl, gb, sl->mb + (16*index << pixel_shift), index,
+ scan, h->dequant4_coeff[cqm][qscale], 16) < 0 ){
+ return -1;
+ }
+ new_cbp |= sl->non_zero_count_cache[scan8[index]] << i8x8;
+ }
+ }
+ }else{
+ uint8_t * const nnz = &sl->non_zero_count_cache[scan8[4 * i8x8 + p * 16]];
+ nnz[0] = nnz[1] = nnz[8] = nnz[9] = 0;
+ }
+ }
+ return new_cbp;
+ }
+}
+
+int ff_h264_decode_mb_cavlc(const H264Context *h, H264SliceContext *sl)
+{
+ int mb_xy;
+ int partition_count;
+ unsigned int mb_type, cbp;
+ int dct8x8_allowed= h->pps.transform_8x8_mode;
+ int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;
+ const int pixel_shift = h->pixel_shift;
+
+ mb_xy = sl->mb_xy = sl->mb_x + sl->mb_y*h->mb_stride;
+
+ ff_tlog(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, sl->mb_x, sl->mb_y);
+ cbp = 0; /* avoid warning. FIXME: find a solution without slowing
+ down the code */
+ if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {
+ if (sl->mb_skip_run == -1)
+ sl->mb_skip_run = get_ue_golomb_long(&sl->gb);
+
+ if (sl->mb_skip_run--) {
+ if (FRAME_MBAFF(h) && (sl->mb_y & 1) == 0) {
+ if (sl->mb_skip_run == 0)
+ sl->mb_mbaff = sl->mb_field_decoding_flag = get_bits1(&sl->gb);
+ }
+ decode_mb_skip(h, sl);
+ return 0;
+ }
+ }
+ if (FRAME_MBAFF(h)) {
+ if ((sl->mb_y & 1) == 0)
+ sl->mb_mbaff = sl->mb_field_decoding_flag = get_bits1(&sl->gb);
+ }
+
+ sl->prev_mb_skipped = 0;
+
+ mb_type= get_ue_golomb(&sl->gb);
+ if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
+ if(mb_type < 23){
+ partition_count= b_mb_type_info[mb_type].partition_count;
+ mb_type= b_mb_type_info[mb_type].type;
+ }else{
+ mb_type -= 23;
+ goto decode_intra_mb;
+ }
+ } else if (sl->slice_type_nos == AV_PICTURE_TYPE_P) {
+ if(mb_type < 5){
+ partition_count= p_mb_type_info[mb_type].partition_count;
+ mb_type= p_mb_type_info[mb_type].type;
+ }else{
+ mb_type -= 5;
+ goto decode_intra_mb;
+ }
+ }else{
+ av_assert2(sl->slice_type_nos == AV_PICTURE_TYPE_I);
+ if (sl->slice_type == AV_PICTURE_TYPE_SI && mb_type)
+ mb_type--;
+decode_intra_mb:
+ if(mb_type > 25){
+ av_log(h->avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_picture_type_char(sl->slice_type), sl->mb_x, sl->mb_y);
+ return -1;
+ }
+ partition_count=0;
+ cbp= i_mb_type_info[mb_type].cbp;
+ sl->intra16x16_pred_mode = i_mb_type_info[mb_type].pred_mode;
+ mb_type= i_mb_type_info[mb_type].type;
+ }
+
+ if (MB_FIELD(sl))
+ mb_type |= MB_TYPE_INTERLACED;
+
+ h->slice_table[mb_xy] = sl->slice_num;
+
+ if(IS_INTRA_PCM(mb_type)){
+ const int mb_size = ff_h264_mb_sizes[h->sps.chroma_format_idc] *
+ h->sps.bit_depth_luma;
+
+ // We assume these blocks are very rare so we do not optimize it.
+ sl->intra_pcm_ptr = align_get_bits(&sl->gb);
+ if (get_bits_left(&sl->gb) < mb_size) {
+ av_log(h->avctx, AV_LOG_ERROR, "Not enough data for an intra PCM block.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ skip_bits_long(&sl->gb, mb_size);
+
+ // In deblocking, the quantizer is 0
+ h->cur_pic.qscale_table[mb_xy] = 0;
+ // All coeffs are present
+ memset(h->non_zero_count[mb_xy], 16, 48);
+
+ h->cur_pic.mb_type[mb_xy] = mb_type;
+ return 0;
+ }
+
+ fill_decode_neighbors(h, sl, mb_type);
+ fill_decode_caches(h, sl, mb_type);
+
+ //mb_pred
+ if(IS_INTRA(mb_type)){
+ int pred_mode;
+// init_top_left_availability(h);
+ if(IS_INTRA4x4(mb_type)){
+ int i;
+ int di = 1;
+ if(dct8x8_allowed && get_bits1(&sl->gb)){
+ mb_type |= MB_TYPE_8x8DCT;
+ di = 4;
+ }
+
+// fill_intra4x4_pred_table(h);
+ for(i=0; i<16; i+=di){
+ int mode = pred_intra_mode(h, sl, i);
+
+ if(!get_bits1(&sl->gb)){
+ const int rem_mode= get_bits(&sl->gb, 3);
+ mode = rem_mode + (rem_mode >= mode);
+ }
+
+ if(di==4)
+ fill_rectangle(&sl->intra4x4_pred_mode_cache[ scan8[i] ], 2, 2, 8, mode, 1);
+ else
+ sl->intra4x4_pred_mode_cache[scan8[i]] = mode;
+ }
+ write_back_intra_pred_mode(h, sl);
+ if (ff_h264_check_intra4x4_pred_mode(h, sl) < 0)
+ return -1;
+ }else{
+ sl->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, sl, sl->intra16x16_pred_mode, 0);
+ if (sl->intra16x16_pred_mode < 0)
+ return -1;
+ }
+ if(decode_chroma){
+ pred_mode= ff_h264_check_intra_pred_mode(h, sl, get_ue_golomb_31(&sl->gb), 1);
+ if(pred_mode < 0)
+ return -1;
+ sl->chroma_pred_mode = pred_mode;
+ } else {
+ sl->chroma_pred_mode = DC_128_PRED8x8;
+ }
+ }else if(partition_count==4){
+ int i, j, sub_partition_count[4], list, ref[2][4];
+
+ if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
+ for(i=0; i<4; i++){
+ sl->sub_mb_type[i]= get_ue_golomb_31(&sl->gb);
+ if(sl->sub_mb_type[i] >=13){
+ av_log(h->avctx, AV_LOG_ERROR, "B sub_mb_type %u out of range at %d %d\n", sl->sub_mb_type[i], sl->mb_x, sl->mb_y);
+ return -1;
+ }
+ sub_partition_count[i]= b_sub_mb_type_info[ sl->sub_mb_type[i] ].partition_count;
+ sl->sub_mb_type[i]= b_sub_mb_type_info[ sl->sub_mb_type[i] ].type;
+ }
+ if( IS_DIRECT(sl->sub_mb_type[0]|sl->sub_mb_type[1]|sl->sub_mb_type[2]|sl->sub_mb_type[3])) {
+ ff_h264_pred_direct_motion(h, sl, &mb_type);
+ sl->ref_cache[0][scan8[4]] =
+ sl->ref_cache[1][scan8[4]] =
+ sl->ref_cache[0][scan8[12]] =
+ sl->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;
+ }
+ }else{
+ av_assert2(sl->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?
+ for(i=0; i<4; i++){
+ sl->sub_mb_type[i]= get_ue_golomb_31(&sl->gb);
+ if(sl->sub_mb_type[i] >=4){
+ av_log(h->avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", sl->sub_mb_type[i], sl->mb_x, sl->mb_y);
+ return -1;
+ }
+ sub_partition_count[i]= p_sub_mb_type_info[ sl->sub_mb_type[i] ].partition_count;
+ sl->sub_mb_type[i]= p_sub_mb_type_info[ sl->sub_mb_type[i] ].type;
+ }
+ }
+
+ for (list = 0; list < sl->list_count; list++) {
+ int ref_count = IS_REF0(mb_type) ? 1 : sl->ref_count[list] << MB_MBAFF(sl);
+ for(i=0; i<4; i++){
+ if(IS_DIRECT(sl->sub_mb_type[i])) continue;
+ if(IS_DIR(sl->sub_mb_type[i], 0, list)){
+ unsigned int tmp;
+ if(ref_count == 1){
+ tmp= 0;
+ }else if(ref_count == 2){
+ tmp= get_bits1(&sl->gb)^1;
+ }else{
+ tmp= get_ue_golomb_31(&sl->gb);
+ if(tmp>=ref_count){
+ av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp);
+ return -1;
+ }
+ }
+ ref[list][i]= tmp;
+ }else{
+ //FIXME
+ ref[list][i] = -1;
+ }
+ }
+ }
+
+ if(dct8x8_allowed)
+ dct8x8_allowed = get_dct8x8_allowed(h, sl);
+
+ for (list = 0; list < sl->list_count; list++) {
+ for(i=0; i<4; i++){
+ if(IS_DIRECT(sl->sub_mb_type[i])) {
+ sl->ref_cache[list][ scan8[4*i] ] = sl->ref_cache[list][ scan8[4*i]+1 ];
+ continue;
+ }
+ sl->ref_cache[list][ scan8[4*i] ]=sl->ref_cache[list][ scan8[4*i]+1 ]=
+ sl->ref_cache[list][ scan8[4*i]+8 ]=sl->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i];
+
+ if(IS_DIR(sl->sub_mb_type[i], 0, list)){
+ const int sub_mb_type= sl->sub_mb_type[i];
+ const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1;
+ for(j=0; j<sub_partition_count[i]; j++){
+ int mx, my;
+ const int index= 4*i + block_width*j;
+ int16_t (* mv_cache)[2]= &sl->mv_cache[list][ scan8[index] ];
+ pred_motion(h, sl, index, block_width, list, sl->ref_cache[list][ scan8[index] ], &mx, &my);
+ mx += get_se_golomb(&sl->gb);
+ my += get_se_golomb(&sl->gb);
+ ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
+
+ if(IS_SUB_8X8(sub_mb_type)){
+ mv_cache[ 1 ][0]=
+ mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx;
+ mv_cache[ 1 ][1]=
+ mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my;
+ }else if(IS_SUB_8X4(sub_mb_type)){
+ mv_cache[ 1 ][0]= mx;
+ mv_cache[ 1 ][1]= my;
+ }else if(IS_SUB_4X8(sub_mb_type)){
+ mv_cache[ 8 ][0]= mx;
+ mv_cache[ 8 ][1]= my;
+ }
+ mv_cache[ 0 ][0]= mx;
+ mv_cache[ 0 ][1]= my;
+ }
+ }else{
+ uint32_t *p= (uint32_t *)&sl->mv_cache[list][ scan8[4*i] ][0];
+ p[0] = p[1]=
+ p[8] = p[9]= 0;
+ }
+ }
+ }
+ }else if(IS_DIRECT(mb_type)){
+ ff_h264_pred_direct_motion(h, sl, &mb_type);
+ dct8x8_allowed &= h->sps.direct_8x8_inference_flag;
+ }else{
+ int list, mx, my, i;
+ //FIXME we should set ref_idx_l? to 0 if we use that later ...
+ if(IS_16X16(mb_type)){
+ for (list = 0; list < sl->list_count; list++) {
+ unsigned int val;
+ if(IS_DIR(mb_type, 0, list)){
+ unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
+ if (rc == 1) {
+ val= 0;
+ } else if (rc == 2) {
+ val= get_bits1(&sl->gb)^1;
+ }else{
+ val= get_ue_golomb_31(&sl->gb);
+ if (val >= rc) {
+ av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+ return -1;
+ }
+ }
+ fill_rectangle(&sl->ref_cache[list][ scan8[0] ], 4, 4, 8, val, 1);
+ }
+ }
+ for (list = 0; list < sl->list_count; list++) {
+ if(IS_DIR(mb_type, 0, list)){
+ pred_motion(h, sl, 0, 4, list, sl->ref_cache[list][ scan8[0] ], &mx, &my);
+ mx += get_se_golomb(&sl->gb);
+ my += get_se_golomb(&sl->gb);
+ ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
+
+ fill_rectangle(sl->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);
+ }
+ }
+ }
+ else if(IS_16X8(mb_type)){
+ for (list = 0; list < sl->list_count; list++) {
+ for(i=0; i<2; i++){
+ unsigned int val;
+ if(IS_DIR(mb_type, i, list)){
+ unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
+ if (rc == 1) {
+ val= 0;
+ } else if (rc == 2) {
+ val= get_bits1(&sl->gb)^1;
+ }else{
+ val= get_ue_golomb_31(&sl->gb);
+ if (val >= rc) {
+ av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+ return -1;
+ }
+ }
+ }else
+ val= LIST_NOT_USED&0xFF;
+ fill_rectangle(&sl->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 1);
+ }
+ }
+ for (list = 0; list < sl->list_count; list++) {
+ for(i=0; i<2; i++){
+ unsigned int val;
+ if(IS_DIR(mb_type, i, list)){
+ pred_16x8_motion(h, sl, 8*i, list, sl->ref_cache[list][scan8[0] + 16*i], &mx, &my);
+ mx += get_se_golomb(&sl->gb);
+ my += get_se_golomb(&sl->gb);
+ ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
+
+ val= pack16to32(mx,my);
+ }else
+ val=0;
+ fill_rectangle(sl->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 4);
+ }
+ }
+ }else{
+ av_assert2(IS_8X16(mb_type));
+ for (list = 0; list < sl->list_count; list++) {
+ for(i=0; i<2; i++){
+ unsigned int val;
+ if(IS_DIR(mb_type, i, list)){ //FIXME optimize
+ unsigned rc = sl->ref_count[list] << MB_MBAFF(sl);
+ if (rc == 1) {
+ val= 0;
+ } else if (rc == 2) {
+ val= get_bits1(&sl->gb)^1;
+ }else{
+ val= get_ue_golomb_31(&sl->gb);
+ if (val >= rc) {
+ av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);
+ return -1;
+ }
+ }
+ }else
+ val= LIST_NOT_USED&0xFF;
+ fill_rectangle(&sl->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 1);
+ }
+ }
+ for (list = 0; list < sl->list_count; list++) {
+ for(i=0; i<2; i++){
+ unsigned int val;
+ if(IS_DIR(mb_type, i, list)){
+ pred_8x16_motion(h, sl, i*4, list, sl->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);
+ mx += get_se_golomb(&sl->gb);
+ my += get_se_golomb(&sl->gb);
+ ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);
+
+ val= pack16to32(mx,my);
+ }else
+ val=0;
+ fill_rectangle(sl->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 4);
+ }
+ }
+ }
+ }
+
+ if(IS_INTER(mb_type))
+ write_back_motion(h, sl, mb_type);
+
+ if(!IS_INTRA16x16(mb_type)){
+ cbp= get_ue_golomb(&sl->gb);
+
+ if(decode_chroma){
+ if(cbp > 47){
+ av_log(h->avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, sl->mb_x, sl->mb_y);
+ return -1;
+ }
+ if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp[cbp];
+ else cbp= golomb_to_inter_cbp [cbp];
+ }else{
+ if(cbp > 15){
+ av_log(h->avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, sl->mb_x, sl->mb_y);
+ return -1;
+ }
+ if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp];
+ else cbp= golomb_to_inter_cbp_gray[cbp];
+ }
+ } else {
+ if (!decode_chroma && cbp>15) {
+ av_log(h->avctx, AV_LOG_ERROR, "gray chroma\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if(dct8x8_allowed && (cbp&15) && !IS_INTRA(mb_type)){
+ mb_type |= MB_TYPE_8x8DCT*get_bits1(&sl->gb);
+ }
+ sl->cbp=
+ h->cbp_table[mb_xy]= cbp;
+ h->cur_pic.mb_type[mb_xy] = mb_type;
+
+ if(cbp || IS_INTRA16x16(mb_type)){
+ int i4x4, i8x8, chroma_idx;
+ int dquant;
+ int ret;
+ GetBitContext *gb = &sl->gb;
+ const uint8_t *scan, *scan8x8;
+ const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
+
+ if(IS_INTERLACED(mb_type)){
+ scan8x8 = sl->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;
+ scan = sl->qscale ? h->field_scan : h->field_scan_q0;
+ }else{
+ scan8x8 = sl->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0;
+ scan = sl->qscale ? h->zigzag_scan : h->zigzag_scan_q0;
+ }
+
+ dquant= get_se_golomb(&sl->gb);
+
+ sl->qscale += (unsigned)dquant;
+
+ if (((unsigned)sl->qscale) > max_qp){
+ if (sl->qscale < 0) sl->qscale += max_qp + 1;
+ else sl->qscale -= max_qp+1;
+ if (((unsigned)sl->qscale) > max_qp){
+ av_log(h->avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, sl->mb_x, sl->mb_y);
+ return -1;
+ }
+ }
+
+ sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale);
+ sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale);
+
+ if ((ret = decode_luma_residual(h, sl, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 0)) < 0 ) {
+ return -1;
+ }
+ h->cbp_table[mb_xy] |= ret << 12;
+ if (CHROMA444(h)) {
+ if (decode_luma_residual(h, sl, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 1) < 0 ) {
+ return -1;
+ }
+ if (decode_luma_residual(h, sl, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 2) < 0 ) {
+ return -1;
+ }
+ } else {
+ const int num_c8x8 = h->sps.chroma_format_idc;
+
+ if(cbp&0x30){
+ for(chroma_idx=0; chroma_idx<2; chroma_idx++)
+ if (decode_residual(h, sl, gb, sl->mb + ((256 + 16*16*chroma_idx) << pixel_shift),
+ CHROMA_DC_BLOCK_INDEX+chroma_idx,
+ CHROMA422(h) ? chroma422_dc_scan : chroma_dc_scan,
+ NULL, 4*num_c8x8) < 0) {
+ return -1;
+ }
+ }
+
+ if(cbp&0x20){
+ for(chroma_idx=0; chroma_idx<2; chroma_idx++){
+ const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][sl->chroma_qp[chroma_idx]];
+ int16_t *mb = sl->mb + (16*(16 + 16*chroma_idx) << pixel_shift);
+ for (i8x8 = 0; i8x8<num_c8x8; i8x8++) {
+ for (i4x4 = 0; i4x4 < 4; i4x4++) {
+ const int index = 16 + 16*chroma_idx + 8*i8x8 + i4x4;
+ if (decode_residual(h, sl, gb, mb, index, scan + 1, qmul, 15) < 0)
+ return -1;
+ mb += 16 << pixel_shift;
+ }
+ }
+ }
+ }else{
+ fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
+ fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
+ }
+ }
+ }else{
+ fill_rectangle(&sl->non_zero_count_cache[scan8[ 0]], 4, 4, 8, 0, 1);
+ fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
+ fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
+ }
+ h->cur_pic.qscale_table[mb_xy] = sl->qscale;
+ write_back_non_zero_count(h, sl);
+
+ return 0;
+}
diff --git a/ffmpeg-2-8-12/libavcodec/h264_direct.c b/ffmpeg-2-8-12/libavcodec/h264_direct.c
new file mode 100644
index 0000000..008aede
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/h264_direct.c
@@ -0,0 +1,709 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... direct mb/block decoding
+ * Copyright (c) 2003 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * H.264 / AVC / MPEG4 part10 direct mb/block decoding.
+ * @author Michael Niedermayer <michaelni at gmx.at>
+ */
+
+#include "internal.h"
+#include "avcodec.h"
+#include "h264.h"
+#include "mpegutils.h"
+#include "rectangle.h"
+#include "thread.h"
+
+#include <assert.h>
+
+static int get_scale_factor(H264SliceContext *sl,
+ int poc, int poc1, int i)
+{
+ int poc0 = sl->ref_list[0][i].poc;
+ int td = av_clip_int8(poc1 - poc0);
+ if (td == 0 || sl->ref_list[0][i].parent->long_ref) {
+ return 256;
+ } else {
+ int tb = av_clip_int8(poc - poc0);
+ int tx = (16384 + (FFABS(td) >> 1)) / td;
+ return av_clip_intp2((tb * tx + 32) >> 6, 10);
+ }
+}
+
+void ff_h264_direct_dist_scale_factor(const H264Context *const h,
+ H264SliceContext *sl)
+{
+ const int poc = FIELD_PICTURE(h) ? h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD]
+ : h->cur_pic_ptr->poc;
+ const int poc1 = sl->ref_list[1][0].poc;
+ int i, field;
+
+ if (FRAME_MBAFF(h))
+ for (field = 0; field < 2; field++) {
+ const int poc = h->cur_pic_ptr->field_poc[field];
+ const int poc1 = sl->ref_list[1][0].parent->field_poc[field];
+ for (i = 0; i < 2 * sl->ref_count[0]; i++)
+ sl->dist_scale_factor_field[field][i ^ field] =
+ get_scale_factor(sl, poc, poc1, i + 16);
+ }
+
+ for (i = 0; i < sl->ref_count[0]; i++)
+ sl->dist_scale_factor[i] = get_scale_factor(sl, poc, poc1, i);
+}
+
+static void fill_colmap(const H264Context *h, H264SliceContext *sl,
+ int map[2][16 + 32], int list,
+ int field, int colfield, int mbafi)
+{
+ H264Picture *const ref1 = sl->ref_list[1][0].parent;
+ int j, old_ref, rfield;
+ int start = mbafi ? 16 : 0;
+ int end = mbafi ? 16 + 2 * sl->ref_count[0] : sl->ref_count[0];
+ int interl = mbafi || h->picture_structure != PICT_FRAME;
+
+ /* bogus; fills in for missing frames */
+ memset(map[list], 0, sizeof(map[list]));
+
+ for (rfield = 0; rfield < 2; rfield++) {
+ for (old_ref = 0; old_ref < ref1->ref_count[colfield][list]; old_ref++) {
+ int poc = ref1->ref_poc[colfield][list][old_ref];
+
+ if (!interl)
+ poc |= 3;
+ // FIXME: store all MBAFF references so this is not needed
+ else if (interl && (poc & 3) == 3)
+ poc = (poc & ~3) + rfield + 1;
+
+ for (j = start; j < end; j++) {
+ if (4 * sl->ref_list[0][j].parent->frame_num +
+ (sl->ref_list[0][j].reference & 3) == poc) {
+ int cur_ref = mbafi ? (j - 16) ^ field : j;
+ if (ref1->mbaff)
+ map[list][2 * old_ref + (rfield ^ field) + 16] = cur_ref;
+ if (rfield == field || !interl)
+ map[list][old_ref] = cur_ref;
+ break;
+ }
+ }
+ }
+ }
+}
+
+void ff_h264_direct_ref_list_init(const H264Context *const h, H264SliceContext *sl)
+{
+ H264Ref *const ref1 = &sl->ref_list[1][0];
+ H264Picture *const cur = h->cur_pic_ptr;
+ int list, j, field;
+ int sidx = (h->picture_structure & 1) ^ 1;
+ int ref1sidx = (ref1->reference & 1) ^ 1;
+
+ for (list = 0; list < sl->list_count; list++) {
+ cur->ref_count[sidx][list] = sl->ref_count[list];
+ for (j = 0; j < sl->ref_count[list]; j++)
+ cur->ref_poc[sidx][list][j] = 4 * sl->ref_list[list][j].parent->frame_num +
+ (sl->ref_list[list][j].reference & 3);
+ }
+
+ if (h->picture_structure == PICT_FRAME) {
+ memcpy(cur->ref_count[1], cur->ref_count[0], sizeof(cur->ref_count[0]));
+ memcpy(cur->ref_poc[1], cur->ref_poc[0], sizeof(cur->ref_poc[0]));
+ }
+
+ cur->mbaff = FRAME_MBAFF(h);
+
+ sl->col_fieldoff = 0;
+
+ if (sl->list_count != 2 || !sl->ref_count[1])
+ return;
+
+ if (h->picture_structure == PICT_FRAME) {
+ int cur_poc = h->cur_pic_ptr->poc;
+ int *col_poc = sl->ref_list[1][0].parent->field_poc;
+ sl->col_parity = (FFABS(col_poc[0] - cur_poc) >=
+ FFABS(col_poc[1] - cur_poc));
+ ref1sidx =
+ sidx = sl->col_parity;
+ // FL -> FL & differ parity
+ } else if (!(h->picture_structure & sl->ref_list[1][0].reference) &&
+ !sl->ref_list[1][0].parent->mbaff) {
+ sl->col_fieldoff = 2 * sl->ref_list[1][0].reference - 3;
+ }
+
+ if (sl->slice_type_nos != AV_PICTURE_TYPE_B || sl->direct_spatial_mv_pred)
+ return;
+
+ for (list = 0; list < 2; list++) {
+ fill_colmap(h, sl, sl->map_col_to_list0, list, sidx, ref1sidx, 0);
+ if (FRAME_MBAFF(h))
+ for (field = 0; field < 2; field++)
+ fill_colmap(h, sl, sl->map_col_to_list0_field[field], list, field,
+ field, 1);
+ }
+}
+
+static void await_reference_mb_row(const H264Context *const h, H264Ref *ref,
+ int mb_y)
+{
+ int ref_field = ref->reference - 1;
+ int ref_field_picture = ref->parent->field_picture;
+ int ref_height = 16 * h->mb_height >> ref_field_picture;
+
+ if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_FRAME))
+ return;
+
+ /* FIXME: It can be safe to access mb stuff
+ * even if pixels aren't deblocked yet. */
+
+ ff_thread_await_progress(&ref->parent->tf,
+ FFMIN(16 * mb_y >> ref_field_picture,
+ ref_height - 1),
+ ref_field_picture && ref_field);
+}
+
+static void pred_spatial_direct_motion(const H264Context *const h, H264SliceContext *sl,
+ int *mb_type)
+{
+ int b8_stride = 2;
+ int b4_stride = h->b_stride;
+ int mb_xy = sl->mb_xy, mb_y = sl->mb_y;
+ int mb_type_col[2];
+ const int16_t (*l1mv0)[2], (*l1mv1)[2];
+ const int8_t *l1ref0, *l1ref1;
+ const int is_b8x8 = IS_8X8(*mb_type);
+ unsigned int sub_mb_type = MB_TYPE_L0L1;
+ int i8, i4;
+ int ref[2];
+ int mv[2];
+ int list;
+
+ assert(sl->ref_list[1][0].reference & 3);
+
+ await_reference_mb_row(h, &sl->ref_list[1][0],
+ sl->mb_y + !!IS_INTERLACED(*mb_type));
+
+#define MB_TYPE_16x16_OR_INTRA (MB_TYPE_16x16 | MB_TYPE_INTRA4x4 | \
+ MB_TYPE_INTRA16x16 | MB_TYPE_INTRA_PCM)
+
+ /* ref = min(neighbors) */
+ for (list = 0; list < 2; list++) {
+ int left_ref = sl->ref_cache[list][scan8[0] - 1];
+ int top_ref = sl->ref_cache[list][scan8[0] - 8];
+ int refc = sl->ref_cache[list][scan8[0] - 8 + 4];
+ const int16_t *C = sl->mv_cache[list][scan8[0] - 8 + 4];
+ if (refc == PART_NOT_AVAILABLE) {
+ refc = sl->ref_cache[list][scan8[0] - 8 - 1];
+ C = sl->mv_cache[list][scan8[0] - 8 - 1];
+ }
+ ref[list] = FFMIN3((unsigned)left_ref,
+ (unsigned)top_ref,
+ (unsigned)refc);
+ if (ref[list] >= 0) {
+ /* This is just pred_motion() but with the cases removed that
+ * cannot happen for direct blocks. */
+ const int16_t *const A = sl->mv_cache[list][scan8[0] - 1];
+ const int16_t *const B = sl->mv_cache[list][scan8[0] - 8];
+
+ int match_count = (left_ref == ref[list]) +
+ (top_ref == ref[list]) +
+ (refc == ref[list]);
+
+ if (match_count > 1) { // most common
+ mv[list] = pack16to32(mid_pred(A[0], B[0], C[0]),
+ mid_pred(A[1], B[1], C[1]));
+ } else {
+ assert(match_count == 1);
+ if (left_ref == ref[list])
+ mv[list] = AV_RN32A(A);
+ else if (top_ref == ref[list])
+ mv[list] = AV_RN32A(B);
+ else
+ mv[list] = AV_RN32A(C);
+ }
+ av_assert2(ref[list] < (sl->ref_count[list] << !!FRAME_MBAFF(h)));
+ } else {
+ int mask = ~(MB_TYPE_L0 << (2 * list));
+ mv[list] = 0;
+ ref[list] = -1;
+ if (!is_b8x8)
+ *mb_type &= mask;
+ sub_mb_type &= mask;
+ }
+ }
+ if (ref[0] < 0 && ref[1] < 0) {
+ ref[0] = ref[1] = 0;
+ if (!is_b8x8)
+ *mb_type |= MB_TYPE_L0L1;
+ sub_mb_type |= MB_TYPE_L0L1;
+ }
+
+ if (!(is_b8x8 | mv[0] | mv[1])) {
+ fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1);
+ fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1);
+ fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4);
+ fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, 0, 4);
+ *mb_type = (*mb_type & ~(MB_TYPE_8x8 | MB_TYPE_16x8 | MB_TYPE_8x16 |
+ MB_TYPE_P1L0 | MB_TYPE_P1L1)) |
+ MB_TYPE_16x16 | MB_TYPE_DIRECT2;
+ return;
+ }
+
+ if (IS_INTERLACED(sl->ref_list[1][0].parent->mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
+ if (!IS_INTERLACED(*mb_type)) { // AFR/FR -> AFL/FL
+ mb_y = (sl->mb_y & ~1) + sl->col_parity;
+ mb_xy = sl->mb_x +
+ ((sl->mb_y & ~1) + sl->col_parity) * h->mb_stride;
+ b8_stride = 0;
+ } else {
+ mb_y += sl->col_fieldoff;
+ mb_xy += h->mb_stride * sl->col_fieldoff; // non-zero for FL -> FL & differ parity
+ }
+ goto single_col;
+ } else { // AFL/AFR/FR/FL -> AFR/FR
+ if (IS_INTERLACED(*mb_type)) { // AFL /FL -> AFR/FR
+ mb_y = sl->mb_y & ~1;
+ mb_xy = (sl->mb_y & ~1) * h->mb_stride + sl->mb_x;
+ mb_type_col[0] = sl->ref_list[1][0].parent->mb_type[mb_xy];
+ mb_type_col[1] = sl->ref_list[1][0].parent->mb_type[mb_xy + h->mb_stride];
+ b8_stride = 2 + 4 * h->mb_stride;
+ b4_stride *= 6;
+ if (IS_INTERLACED(mb_type_col[0]) !=
+ IS_INTERLACED(mb_type_col[1])) {
+ mb_type_col[0] &= ~MB_TYPE_INTERLACED;
+ mb_type_col[1] &= ~MB_TYPE_INTERLACED;
+ }
+
+ sub_mb_type |= MB_TYPE_16x16 | MB_TYPE_DIRECT2; /* B_SUB_8x8 */
+ if ((mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) &&
+ (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) &&
+ !is_b8x8) {
+ *mb_type |= MB_TYPE_16x8 | MB_TYPE_DIRECT2; /* B_16x8 */
+ } else {
+ *mb_type |= MB_TYPE_8x8;
+ }
+ } else { // AFR/FR -> AFR/FR
+single_col:
+ mb_type_col[0] =
+ mb_type_col[1] = sl->ref_list[1][0].parent->mb_type[mb_xy];
+
+ sub_mb_type |= MB_TYPE_16x16 | MB_TYPE_DIRECT2; /* B_SUB_8x8 */
+ if (!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)) {
+ *mb_type |= MB_TYPE_16x16 | MB_TYPE_DIRECT2; /* B_16x16 */
+ } else if (!is_b8x8 &&
+ (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16))) {
+ *mb_type |= MB_TYPE_DIRECT2 |
+ (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16));
+ } else {
+ if (!h->sps.direct_8x8_inference_flag) {
+ /* FIXME: Save sub mb types from previous frames (or derive
+ * from MVs) so we know exactly what block size to use. */
+ sub_mb_type += (MB_TYPE_8x8 - MB_TYPE_16x16); /* B_SUB_4x4 */
+ }
+ *mb_type |= MB_TYPE_8x8;
+ }
+ }
+ }
+
+ await_reference_mb_row(h, &sl->ref_list[1][0], mb_y);
+
+ l1mv0 = (void*)&sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]];
+ l1mv1 = (void*)&sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]];
+ l1ref0 = &sl->ref_list[1][0].parent->ref_index[0][4 * mb_xy];
+ l1ref1 = &sl->ref_list[1][0].parent->ref_index[1][4 * mb_xy];
+ if (!b8_stride) {
+ if (sl->mb_y & 1) {
+ l1ref0 += 2;
+ l1ref1 += 2;
+ l1mv0 += 2 * b4_stride;
+ l1mv1 += 2 * b4_stride;
+ }
+ }
+
+ if (IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])) {
+ int n = 0;
+ for (i8 = 0; i8 < 4; i8++) {
+ int x8 = i8 & 1;
+ int y8 = i8 >> 1;
+ int xy8 = x8 + y8 * b8_stride;
+ int xy4 = x8 * 3 + y8 * b4_stride;
+ int a, b;
+
+ if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
+ continue;
+ sl->sub_mb_type[i8] = sub_mb_type;
+
+ fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
+ (uint8_t)ref[0], 1);
+ fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8,
+ (uint8_t)ref[1], 1);
+ if (!IS_INTRA(mb_type_col[y8]) && !sl->ref_list[1][0].parent->long_ref &&
+ ((l1ref0[xy8] == 0 &&
+ FFABS(l1mv0[xy4][0]) <= 1 &&
+ FFABS(l1mv0[xy4][1]) <= 1) ||
+ (l1ref0[xy8] < 0 &&
+ l1ref1[xy8] == 0 &&
+ FFABS(l1mv1[xy4][0]) <= 1 &&
+ FFABS(l1mv1[xy4][1]) <= 1))) {
+ a =
+ b = 0;
+ if (ref[0] > 0)
+ a = mv[0];
+ if (ref[1] > 0)
+ b = mv[1];
+ n++;
+ } else {
+ a = mv[0];
+ b = mv[1];
+ }
+ fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, a, 4);
+ fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, b, 4);
+ }
+ if (!is_b8x8 && !(n & 3))
+ *mb_type = (*mb_type & ~(MB_TYPE_8x8 | MB_TYPE_16x8 | MB_TYPE_8x16 |
+ MB_TYPE_P1L0 | MB_TYPE_P1L1)) |
+ MB_TYPE_16x16 | MB_TYPE_DIRECT2;
+ } else if (IS_16X16(*mb_type)) {
+ int a, b;
+
+ fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, (uint8_t)ref[0], 1);
+ fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, (uint8_t)ref[1], 1);
+ if (!IS_INTRA(mb_type_col[0]) && !sl->ref_list[1][0].parent->long_ref &&
+ ((l1ref0[0] == 0 &&
+ FFABS(l1mv0[0][0]) <= 1 &&
+ FFABS(l1mv0[0][1]) <= 1) ||
+ (l1ref0[0] < 0 && !l1ref1[0] &&
+ FFABS(l1mv1[0][0]) <= 1 &&
+ FFABS(l1mv1[0][1]) <= 1 &&
+ h->x264_build > 33U))) {
+ a = b = 0;
+ if (ref[0] > 0)
+ a = mv[0];
+ if (ref[1] > 0)
+ b = mv[1];
+ } else {
+ a = mv[0];
+ b = mv[1];
+ }
+ fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, a, 4);
+ fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, b, 4);
+ } else {
+ int n = 0;
+ for (i8 = 0; i8 < 4; i8++) {
+ const int x8 = i8 & 1;
+ const int y8 = i8 >> 1;
+
+ if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
+ continue;
+ sl->sub_mb_type[i8] = sub_mb_type;
+
+ fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, mv[0], 4);
+ fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, mv[1], 4);
+ fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
+ (uint8_t)ref[0], 1);
+ fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8,
+ (uint8_t)ref[1], 1);
+
+ assert(b8_stride == 2);
+ /* col_zero_flag */
+ if (!IS_INTRA(mb_type_col[0]) && !sl->ref_list[1][0].parent->long_ref &&
+ (l1ref0[i8] == 0 ||
+ (l1ref0[i8] < 0 &&
+ l1ref1[i8] == 0 &&
+ h->x264_build > 33U))) {
+ const int16_t (*l1mv)[2] = l1ref0[i8] == 0 ? l1mv0 : l1mv1;
+ if (IS_SUB_8X8(sub_mb_type)) {
+ const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride];
+ if (FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1) {
+ if (ref[0] == 0)
+ fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2,
+ 8, 0, 4);
+ if (ref[1] == 0)
+ fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2,
+ 8, 0, 4);
+ n += 4;
+ }
+ } else {
+ int m = 0;
+ for (i4 = 0; i4 < 4; i4++) {
+ const int16_t *mv_col = l1mv[x8 * 2 + (i4 & 1) +
+ (y8 * 2 + (i4 >> 1)) * b4_stride];
+ if (FFABS(mv_col[0]) <= 1 && FFABS(mv_col[1]) <= 1) {
+ if (ref[0] == 0)
+ AV_ZERO32(sl->mv_cache[0][scan8[i8 * 4 + i4]]);
+ if (ref[1] == 0)
+ AV_ZERO32(sl->mv_cache[1][scan8[i8 * 4 + i4]]);
+ m++;
+ }
+ }
+ if (!(m & 3))
+ sl->sub_mb_type[i8] += MB_TYPE_16x16 - MB_TYPE_8x8;
+ n += m;
+ }
+ }
+ }
+ if (!is_b8x8 && !(n & 15))
+ *mb_type = (*mb_type & ~(MB_TYPE_8x8 | MB_TYPE_16x8 | MB_TYPE_8x16 |
+ MB_TYPE_P1L0 | MB_TYPE_P1L1)) |
+ MB_TYPE_16x16 | MB_TYPE_DIRECT2;
+ }
+}
+
+static void pred_temp_direct_motion(const H264Context *const h, H264SliceContext *sl,
+ int *mb_type)
+{
+ int b8_stride = 2;
+ int b4_stride = h->b_stride;
+ int mb_xy = sl->mb_xy, mb_y = sl->mb_y;
+ int mb_type_col[2];
+ const int16_t (*l1mv0)[2], (*l1mv1)[2];
+ const int8_t *l1ref0, *l1ref1;
+ const int is_b8x8 = IS_8X8(*mb_type);
+ unsigned int sub_mb_type;
+ int i8, i4;
+
+ assert(sl->ref_list[1][0].reference & 3);
+
+ await_reference_mb_row(h, &sl->ref_list[1][0],
+ sl->mb_y + !!IS_INTERLACED(*mb_type));
+
+ if (IS_INTERLACED(sl->ref_list[1][0].parent->mb_type[mb_xy])) { // AFL/AFR/FR/FL -> AFL/FL
+ if (!IS_INTERLACED(*mb_type)) { // AFR/FR -> AFL/FL
+ mb_y = (sl->mb_y & ~1) + sl->col_parity;
+ mb_xy = sl->mb_x +
+ ((sl->mb_y & ~1) + sl->col_parity) * h->mb_stride;
+ b8_stride = 0;
+ } else {
+ mb_y += sl->col_fieldoff;
+ mb_xy += h->mb_stride * sl->col_fieldoff; // non-zero for FL -> FL & differ parity
+ }
+ goto single_col;
+ } else { // AFL/AFR/FR/FL -> AFR/FR
+ if (IS_INTERLACED(*mb_type)) { // AFL /FL -> AFR/FR
+ mb_y = sl->mb_y & ~1;
+ mb_xy = sl->mb_x + (sl->mb_y & ~1) * h->mb_stride;
+ mb_type_col[0] = sl->ref_list[1][0].parent->mb_type[mb_xy];
+ mb_type_col[1] = sl->ref_list[1][0].parent->mb_type[mb_xy + h->mb_stride];
+ b8_stride = 2 + 4 * h->mb_stride;
+ b4_stride *= 6;
+ if (IS_INTERLACED(mb_type_col[0]) !=
+ IS_INTERLACED(mb_type_col[1])) {
+ mb_type_col[0] &= ~MB_TYPE_INTERLACED;
+ mb_type_col[1] &= ~MB_TYPE_INTERLACED;
+ }
+
+ sub_mb_type = MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
+ MB_TYPE_DIRECT2; /* B_SUB_8x8 */
+
+ if ((mb_type_col[0] & MB_TYPE_16x16_OR_INTRA) &&
+ (mb_type_col[1] & MB_TYPE_16x16_OR_INTRA) &&
+ !is_b8x8) {
+ *mb_type |= MB_TYPE_16x8 | MB_TYPE_L0L1 |
+ MB_TYPE_DIRECT2; /* B_16x8 */
+ } else {
+ *mb_type |= MB_TYPE_8x8 | MB_TYPE_L0L1;
+ }
+ } else { // AFR/FR -> AFR/FR
+single_col:
+ mb_type_col[0] =
+ mb_type_col[1] = sl->ref_list[1][0].parent->mb_type[mb_xy];
+
+ sub_mb_type = MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
+ MB_TYPE_DIRECT2; /* B_SUB_8x8 */
+ if (!is_b8x8 && (mb_type_col[0] & MB_TYPE_16x16_OR_INTRA)) {
+ *mb_type |= MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
+ MB_TYPE_DIRECT2; /* B_16x16 */
+ } else if (!is_b8x8 &&
+ (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16))) {
+ *mb_type |= MB_TYPE_L0L1 | MB_TYPE_DIRECT2 |
+ (mb_type_col[0] & (MB_TYPE_16x8 | MB_TYPE_8x16));
+ } else {
+ if (!h->sps.direct_8x8_inference_flag) {
+ /* FIXME: save sub mb types from previous frames (or derive
+ * from MVs) so we know exactly what block size to use */
+ sub_mb_type = MB_TYPE_8x8 | MB_TYPE_P0L0 | MB_TYPE_P0L1 |
+ MB_TYPE_DIRECT2; /* B_SUB_4x4 */
+ }
+ *mb_type |= MB_TYPE_8x8 | MB_TYPE_L0L1;
+ }
+ }
+ }
+
+ await_reference_mb_row(h, &sl->ref_list[1][0], mb_y);
+
+ l1mv0 = (void*)&sl->ref_list[1][0].parent->motion_val[0][h->mb2b_xy[mb_xy]];
+ l1mv1 = (void*)&sl->ref_list[1][0].parent->motion_val[1][h->mb2b_xy[mb_xy]];
+ l1ref0 = &sl->ref_list[1][0].parent->ref_index[0][4 * mb_xy];
+ l1ref1 = &sl->ref_list[1][0].parent->ref_index[1][4 * mb_xy];
+ if (!b8_stride) {
+ if (sl->mb_y & 1) {
+ l1ref0 += 2;
+ l1ref1 += 2;
+ l1mv0 += 2 * b4_stride;
+ l1mv1 += 2 * b4_stride;
+ }
+ }
+
+ {
+ const int *map_col_to_list0[2] = { sl->map_col_to_list0[0],
+ sl->map_col_to_list0[1] };
+ const int *dist_scale_factor = sl->dist_scale_factor;
+ int ref_offset;
+
+ if (FRAME_MBAFF(h) && IS_INTERLACED(*mb_type)) {
+ map_col_to_list0[0] = sl->map_col_to_list0_field[sl->mb_y & 1][0];
+ map_col_to_list0[1] = sl->map_col_to_list0_field[sl->mb_y & 1][1];
+ dist_scale_factor = sl->dist_scale_factor_field[sl->mb_y & 1];
+ }
+ ref_offset = (sl->ref_list[1][0].parent->mbaff << 4) & (mb_type_col[0] >> 3);
+
+ if (IS_INTERLACED(*mb_type) != IS_INTERLACED(mb_type_col[0])) {
+ int y_shift = 2 * !IS_INTERLACED(*mb_type);
+ assert(h->sps.direct_8x8_inference_flag);
+
+ for (i8 = 0; i8 < 4; i8++) {
+ const int x8 = i8 & 1;
+ const int y8 = i8 >> 1;
+ int ref0, scale;
+ const int16_t (*l1mv)[2] = l1mv0;
+
+ if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
+ continue;
+ sl->sub_mb_type[i8] = sub_mb_type;
+
+ fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 1);
+ if (IS_INTRA(mb_type_col[y8])) {
+ fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 1);
+ fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4);
+ fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4);
+ continue;
+ }
+
+ ref0 = l1ref0[x8 + y8 * b8_stride];
+ if (ref0 >= 0)
+ ref0 = map_col_to_list0[0][ref0 + ref_offset];
+ else {
+ ref0 = map_col_to_list0[1][l1ref1[x8 + y8 * b8_stride] +
+ ref_offset];
+ l1mv = l1mv1;
+ }
+ scale = dist_scale_factor[ref0];
+ fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
+ ref0, 1);
+
+ {
+ const int16_t *mv_col = l1mv[x8 * 3 + y8 * b4_stride];
+ int my_col = (mv_col[1] * (1 << y_shift)) / 2;
+ int mx = (scale * mv_col[0] + 128) >> 8;
+ int my = (scale * my_col + 128) >> 8;
+ fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8,
+ pack16to32(mx, my), 4);
+ fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8,
+ pack16to32(mx - mv_col[0], my - my_col), 4);
+ }
+ }
+ return;
+ }
+
+ /* one-to-one mv scaling */
+
+ if (IS_16X16(*mb_type)) {
+ int ref, mv0, mv1;
+
+ fill_rectangle(&sl->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1);
+ if (IS_INTRA(mb_type_col[0])) {
+ ref = mv0 = mv1 = 0;
+ } else {
+ const int ref0 = l1ref0[0] >= 0 ? map_col_to_list0[0][l1ref0[0] + ref_offset]
+ : map_col_to_list0[1][l1ref1[0] + ref_offset];
+ const int scale = dist_scale_factor[ref0];
+ const int16_t *mv_col = l1ref0[0] >= 0 ? l1mv0[0] : l1mv1[0];
+ int mv_l0[2];
+ mv_l0[0] = (scale * mv_col[0] + 128) >> 8;
+ mv_l0[1] = (scale * mv_col[1] + 128) >> 8;
+ ref = ref0;
+ mv0 = pack16to32(mv_l0[0], mv_l0[1]);
+ mv1 = pack16to32(mv_l0[0] - mv_col[0], mv_l0[1] - mv_col[1]);
+ }
+ fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, ref, 1);
+ fill_rectangle(&sl->mv_cache[0][scan8[0]], 4, 4, 8, mv0, 4);
+ fill_rectangle(&sl->mv_cache[1][scan8[0]], 4, 4, 8, mv1, 4);
+ } else {
+ for (i8 = 0; i8 < 4; i8++) {
+ const int x8 = i8 & 1;
+ const int y8 = i8 >> 1;
+ int ref0, scale;
+ const int16_t (*l1mv)[2] = l1mv0;
+
+ if (is_b8x8 && !IS_DIRECT(sl->sub_mb_type[i8]))
+ continue;
+ sl->sub_mb_type[i8] = sub_mb_type;
+ fill_rectangle(&sl->ref_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 1);
+ if (IS_INTRA(mb_type_col[0])) {
+ fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 1);
+ fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8, 0, 4);
+ fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8, 0, 4);
+ continue;
+ }
+
+ assert(b8_stride == 2);
+ ref0 = l1ref0[i8];
+ if (ref0 >= 0)
+ ref0 = map_col_to_list0[0][ref0 + ref_offset];
+ else {
+ ref0 = map_col_to_list0[1][l1ref1[i8] + ref_offset];
+ l1mv = l1mv1;
+ }
+ scale = dist_scale_factor[ref0];
+
+ fill_rectangle(&sl->ref_cache[0][scan8[i8 * 4]], 2, 2, 8,
+ ref0, 1);
+ if (IS_SUB_8X8(sub_mb_type)) {
+ const int16_t *mv_col = l1mv[x8 * 3 + y8 * 3 * b4_stride];
+ int mx = (scale * mv_col[0] + 128) >> 8;
+ int my = (scale * mv_col[1] + 128) >> 8;
+ fill_rectangle(&sl->mv_cache[0][scan8[i8 * 4]], 2, 2, 8,
+ pack16to32(mx, my), 4);
+ fill_rectangle(&sl->mv_cache[1][scan8[i8 * 4]], 2, 2, 8,
+ pack16to32(mx - mv_col[0], my - mv_col[1]), 4);
+ } else {
+ for (i4 = 0; i4 < 4; i4++) {
+ const int16_t *mv_col = l1mv[x8 * 2 + (i4 & 1) +
+ (y8 * 2 + (i4 >> 1)) * b4_stride];
+ int16_t *mv_l0 = sl->mv_cache[0][scan8[i8 * 4 + i4]];
+ mv_l0[0] = (scale * mv_col[0] + 128) >> 8;
+ mv_l0[1] = (scale * mv_col[1] + 128) >> 8;
+ AV_WN32A(sl->mv_cache[1][scan8[i8 * 4 + i4]],
+ pack16to32(mv_l0[0] - mv_col[0],
+ mv_l0[1] - mv_col[1]));
+ }
+ }
+ }
+ }
+ }
+}
+
+void ff_h264_pred_direct_motion(const H264Context *const h, H264SliceContext *sl,
+ int *mb_type)
+{
+ if (sl->direct_spatial_mv_pred)
+ pred_spatial_direct_motion(h, sl, mb_type);
+ else
+ pred_temp_direct_motion(h, sl, mb_type);
+}
diff --git a/ffmpeg-2-8-11/libavcodec/h264_loopfilter.c b/ffmpeg-2-8-12/libavcodec/h264_loopfilter.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264_loopfilter.c
rename to ffmpeg-2-8-12/libavcodec/h264_loopfilter.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264_mb.c b/ffmpeg-2-8-12/libavcodec/h264_mb.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264_mb.c
rename to ffmpeg-2-8-12/libavcodec/h264_mb.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264_mb_template.c b/ffmpeg-2-8-12/libavcodec/h264_mb_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264_mb_template.c
rename to ffmpeg-2-8-12/libavcodec/h264_mb_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264_mc_template.c b/ffmpeg-2-8-12/libavcodec/h264_mc_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264_mc_template.c
rename to ffmpeg-2-8-12/libavcodec/h264_mc_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264_mp4toannexb_bsf.c b/ffmpeg-2-8-12/libavcodec/h264_mp4toannexb_bsf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264_mp4toannexb_bsf.c
rename to ffmpeg-2-8-12/libavcodec/h264_mp4toannexb_bsf.c
diff --git a/ffmpeg-2-8-12/libavcodec/h264_mvpred.h b/ffmpeg-2-8-12/libavcodec/h264_mvpred.h
new file mode 100644
index 0000000..18de4b0
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/h264_mvpred.h
@@ -0,0 +1,836 @@
+/*
+ * H.26L/H.264/AVC/JVT/14496-10/... motion vector predicion
+ * Copyright (c) 2003 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * H.264 / AVC / MPEG4 part10 motion vector predicion.
+ * @author Michael Niedermayer <michaelni at gmx.at>
+ */
+
+#ifndef AVCODEC_H264_MVPRED_H
+#define AVCODEC_H264_MVPRED_H
+
+#include "internal.h"
+#include "avcodec.h"
+#include "h264.h"
+#include "mpegutils.h"
+#include "libavutil/avassert.h"
+
+
+static av_always_inline int fetch_diagonal_mv(const H264Context *h, H264SliceContext *sl,
+ const int16_t **C,
+ int i, int list, int part_width)
+{
+ const int topright_ref = sl->ref_cache[list][i - 8 + part_width];
+
+ /* there is no consistent mapping of mvs to neighboring locations that will
+ * make mbaff happy, so we can't move all this logic to fill_caches */
+ if (FRAME_MBAFF(h)) {
+#define SET_DIAG_MV(MV_OP, REF_OP, XY, Y4) \
+ const int xy = XY, y4 = Y4; \
+ const int mb_type = mb_types[xy + (y4 >> 2) * h->mb_stride]; \
+ if (!USES_LIST(mb_type, list)) \
+ return LIST_NOT_USED; \
+ mv = h->cur_pic_ptr->motion_val[list][h->mb2b_xy[xy] + 3 + y4 * h->b_stride]; \
+ sl->mv_cache[list][scan8[0] - 2][0] = mv[0]; \
+ sl->mv_cache[list][scan8[0] - 2][1] = mv[1] MV_OP; \
+ return h->cur_pic_ptr->ref_index[list][4 * xy + 1 + (y4 & ~1)] REF_OP;
+
+ if (topright_ref == PART_NOT_AVAILABLE
+ && i >= scan8[0] + 8 && (i & 7) == 4
+ && sl->ref_cache[list][scan8[0] - 1] != PART_NOT_AVAILABLE) {
+ const uint32_t *mb_types = h->cur_pic_ptr->mb_type;
+ const int16_t *mv;
+ AV_ZERO32(sl->mv_cache[list][scan8[0] - 2]);
+ *C = sl->mv_cache[list][scan8[0] - 2];
+
+ if (!MB_FIELD(sl) && IS_INTERLACED(sl->left_type[0])) {
+ SET_DIAG_MV(* 2, >> 1, sl->left_mb_xy[0] + h->mb_stride,
+ (sl->mb_y & 1) * 2 + (i >> 5));
+ }
+ if (MB_FIELD(sl) && !IS_INTERLACED(sl->left_type[0])) {
+ // left shift will turn LIST_NOT_USED into PART_NOT_AVAILABLE, but that's OK.
+ SET_DIAG_MV(/ 2, *2, sl->left_mb_xy[i >= 36], ((i >> 2)) & 3);
+ }
+ }
+#undef SET_DIAG_MV
+ }
+
+ if (topright_ref != PART_NOT_AVAILABLE) {
+ *C = sl->mv_cache[list][i - 8 + part_width];
+ return topright_ref;
+ } else {
+ ff_tlog(h->avctx, "topright MV not available\n");
+
+ *C = sl->mv_cache[list][i - 8 - 1];
+ return sl->ref_cache[list][i - 8 - 1];
+ }
+}
+
+/**
+ * Get the predicted MV.
+ * @param n the block index
+ * @param part_width the width of the partition (4, 8,16) -> (1, 2, 4)
+ * @param mx the x component of the predicted motion vector
+ * @param my the y component of the predicted motion vector
+ */
+static av_always_inline void pred_motion(const H264Context *const h,
+ H264SliceContext *sl,
+ int n,
+ int part_width, int list, int ref,
+ int *const mx, int *const my)
+{
+ const int index8 = scan8[n];
+ const int top_ref = sl->ref_cache[list][index8 - 8];
+ const int left_ref = sl->ref_cache[list][index8 - 1];
+ const int16_t *const A = sl->mv_cache[list][index8 - 1];
+ const int16_t *const B = sl->mv_cache[list][index8 - 8];
+ const int16_t *C;
+ int diagonal_ref, match_count;
+
+ av_assert2(part_width == 1 || part_width == 2 || part_width == 4);
+
+/* mv_cache
+ * B . . A T T T T
+ * U . . L . . , .
+ * U . . L . . . .
+ * U . . L . . , .
+ * . . . L . . . .
+ */
+
+ diagonal_ref = fetch_diagonal_mv(h, sl, &C, index8, list, part_width);
+ match_count = (diagonal_ref == ref) + (top_ref == ref) + (left_ref == ref);
+ ff_tlog(h->avctx, "pred_motion match_count=%d\n", match_count);
+ if (match_count > 1) { //most common
+ *mx = mid_pred(A[0], B[0], C[0]);
+ *my = mid_pred(A[1], B[1], C[1]);
+ } else if (match_count == 1) {
+ if (left_ref == ref) {
+ *mx = A[0];
+ *my = A[1];
+ } else if (top_ref == ref) {
+ *mx = B[0];
+ *my = B[1];
+ } else {
+ *mx = C[0];
+ *my = C[1];
+ }
+ } else {
+ if (top_ref == PART_NOT_AVAILABLE &&
+ diagonal_ref == PART_NOT_AVAILABLE &&
+ left_ref != PART_NOT_AVAILABLE) {
+ *mx = A[0];
+ *my = A[1];
+ } else {
+ *mx = mid_pred(A[0], B[0], C[0]);
+ *my = mid_pred(A[1], B[1], C[1]);
+ }
+ }
+
+ ff_tlog(h->avctx,
+ "pred_motion (%2d %2d %2d) (%2d %2d %2d) (%2d %2d %2d) -> (%2d %2d %2d) at %2d %2d %d list %d\n",
+ top_ref, B[0], B[1], diagonal_ref, C[0], C[1], left_ref,
+ A[0], A[1], ref, *mx, *my, sl->mb_x, sl->mb_y, n, list);
+}
+
+/**
+ * Get the directionally predicted 16x8 MV.
+ * @param n the block index
+ * @param mx the x component of the predicted motion vector
+ * @param my the y component of the predicted motion vector
+ */
+static av_always_inline void pred_16x8_motion(const H264Context *const h,
+ H264SliceContext *sl,
+ int n, int list, int ref,
+ int *const mx, int *const my)
+{
+ if (n == 0) {
+ const int top_ref = sl->ref_cache[list][scan8[0] - 8];
+ const int16_t *const B = sl->mv_cache[list][scan8[0] - 8];
+
+ ff_tlog(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
+ top_ref, B[0], B[1], sl->mb_x, sl->mb_y, n, list);
+
+ if (top_ref == ref) {
+ *mx = B[0];
+ *my = B[1];
+ return;
+ }
+ } else {
+ const int left_ref = sl->ref_cache[list][scan8[8] - 1];
+ const int16_t *const A = sl->mv_cache[list][scan8[8] - 1];
+
+ ff_tlog(h->avctx, "pred_16x8: (%2d %2d %2d) at %2d %2d %d list %d\n",
+ left_ref, A[0], A[1], sl->mb_x, sl->mb_y, n, list);
+
+ if (left_ref == ref) {
+ *mx = A[0];
+ *my = A[1];
+ return;
+ }
+ }
+
+ //RARE
+ pred_motion(h, sl, n, 4, list, ref, mx, my);
+}
+
+/**
+ * Get the directionally predicted 8x16 MV.
+ * @param n the block index
+ * @param mx the x component of the predicted motion vector
+ * @param my the y component of the predicted motion vector
+ */
+static av_always_inline void pred_8x16_motion(const H264Context *const h,
+ H264SliceContext *sl,
+ int n, int list, int ref,
+ int *const mx, int *const my)
+{
+ if (n == 0) {
+ const int left_ref = sl->ref_cache[list][scan8[0] - 1];
+ const int16_t *const A = sl->mv_cache[list][scan8[0] - 1];
+
+ ff_tlog(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
+ left_ref, A[0], A[1], sl->mb_x, sl->mb_y, n, list);
+
+ if (left_ref == ref) {
+ *mx = A[0];
+ *my = A[1];
+ return;
+ }
+ } else {
+ const int16_t *C;
+ int diagonal_ref;
+
+ diagonal_ref = fetch_diagonal_mv(h, sl, &C, scan8[4], list, 2);
+
+ ff_tlog(h->avctx, "pred_8x16: (%2d %2d %2d) at %2d %2d %d list %d\n",
+ diagonal_ref, C[0], C[1], sl->mb_x, sl->mb_y, n, list);
+
+ if (diagonal_ref == ref) {
+ *mx = C[0];
+ *my = C[1];
+ return;
+ }
+ }
+
+ //RARE
+ pred_motion(h, sl, n, 2, list, ref, mx, my);
+}
+
+#define FIX_MV_MBAFF(type, refn, mvn, idx) \
+ if (FRAME_MBAFF(h)) { \
+ if (MB_FIELD(sl)) { \
+ if (!IS_INTERLACED(type)) { \
+ refn <<= 1; \
+ AV_COPY32(mvbuf[idx], mvn); \
+ mvbuf[idx][1] /= 2; \
+ mvn = mvbuf[idx]; \
+ } \
+ } else { \
+ if (IS_INTERLACED(type)) { \
+ refn >>= 1; \
+ AV_COPY32(mvbuf[idx], mvn); \
+ mvbuf[idx][1] *= 2; \
+ mvn = mvbuf[idx]; \
+ } \
+ } \
+ }
+
+static av_always_inline void pred_pskip_motion(const H264Context *const h,
+ H264SliceContext *sl)
+{
+ DECLARE_ALIGNED(4, static const int16_t, zeromv)[2] = { 0 };
+ DECLARE_ALIGNED(4, int16_t, mvbuf)[3][2];
+ int8_t *ref = h->cur_pic.ref_index[0];
+ int16_t(*mv)[2] = h->cur_pic.motion_val[0];
+ int top_ref, left_ref, diagonal_ref, match_count, mx, my;
+ const int16_t *A, *B, *C;
+ int b_stride = h->b_stride;
+
+ fill_rectangle(&sl->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1);
+
+ /* To avoid doing an entire fill_decode_caches, we inline the relevant
+ * parts here.
+ * FIXME: this is a partial duplicate of the logic in fill_decode_caches,
+ * but it's faster this way. Is there a way to avoid this duplication?
+ */
+ if (USES_LIST(sl->left_type[LTOP], 0)) {
+ left_ref = ref[4 * sl->left_mb_xy[LTOP] + 1 + (sl->left_block[0] & ~1)];
+ A = mv[h->mb2b_xy[sl->left_mb_xy[LTOP]] + 3 + b_stride * sl->left_block[0]];
+ FIX_MV_MBAFF(sl->left_type[LTOP], left_ref, A, 0);
+ if (!(left_ref | AV_RN32A(A)))
+ goto zeromv;
+ } else if (sl->left_type[LTOP]) {
+ left_ref = LIST_NOT_USED;
+ A = zeromv;
+ } else {
+ goto zeromv;
+ }
+
+ if (USES_LIST(sl->top_type, 0)) {
+ top_ref = ref[4 * sl->top_mb_xy + 2];
+ B = mv[h->mb2b_xy[sl->top_mb_xy] + 3 * b_stride];
+ FIX_MV_MBAFF(sl->top_type, top_ref, B, 1);
+ if (!(top_ref | AV_RN32A(B)))
+ goto zeromv;
+ } else if (sl->top_type) {
+ top_ref = LIST_NOT_USED;
+ B = zeromv;
+ } else {
+ goto zeromv;
+ }
+
+ ff_tlog(h->avctx, "pred_pskip: (%d) (%d) at %2d %2d\n",
+ top_ref, left_ref, sl->mb_x, sl->mb_y);
+
+ if (USES_LIST(sl->topright_type, 0)) {
+ diagonal_ref = ref[4 * sl->topright_mb_xy + 2];
+ C = mv[h->mb2b_xy[sl->topright_mb_xy] + 3 * b_stride];
+ FIX_MV_MBAFF(sl->topright_type, diagonal_ref, C, 2);
+ } else if (sl->topright_type) {
+ diagonal_ref = LIST_NOT_USED;
+ C = zeromv;
+ } else {
+ if (USES_LIST(sl->topleft_type, 0)) {
+ diagonal_ref = ref[4 * sl->topleft_mb_xy + 1 +
+ (sl->topleft_partition & 2)];
+ C = mv[h->mb2b_xy[sl->topleft_mb_xy] + 3 + b_stride +
+ (sl->topleft_partition & 2 * b_stride)];
+ FIX_MV_MBAFF(sl->topleft_type, diagonal_ref, C, 2);
+ } else if (sl->topleft_type) {
+ diagonal_ref = LIST_NOT_USED;
+ C = zeromv;
+ } else {
+ diagonal_ref = PART_NOT_AVAILABLE;
+ C = zeromv;
+ }
+ }
+
+ match_count = !diagonal_ref + !top_ref + !left_ref;
+ ff_tlog(h->avctx, "pred_pskip_motion match_count=%d\n", match_count);
+ if (match_count > 1) {
+ mx = mid_pred(A[0], B[0], C[0]);
+ my = mid_pred(A[1], B[1], C[1]);
+ } else if (match_count == 1) {
+ if (!left_ref) {
+ mx = A[0];
+ my = A[1];
+ } else if (!top_ref) {
+ mx = B[0];
+ my = B[1];
+ } else {
+ mx = C[0];
+ my = C[1];
+ }
+ } else {
+ mx = mid_pred(A[0], B[0], C[0]);
+ my = mid_pred(A[1], B[1], C[1]);
+ }
+
+ fill_rectangle(sl->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mx, my), 4);
+ return;
+
+zeromv:
+ fill_rectangle(sl->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4);
+ return;
+}
+
+static void fill_decode_neighbors(const H264Context *h, H264SliceContext *sl, int mb_type)
+{
+ const int mb_xy = sl->mb_xy;
+ int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS];
+ static const uint8_t left_block_options[4][32] = {
+ { 0, 1, 2, 3, 7, 10, 8, 11, 3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4, 3 + 3 * 4, 1 + 4 * 4, 1 + 8 * 4, 1 + 5 * 4, 1 + 9 * 4 },
+ { 2, 2, 3, 3, 8, 11, 8, 11, 3 + 2 * 4, 3 + 2 * 4, 3 + 3 * 4, 3 + 3 * 4, 1 + 5 * 4, 1 + 9 * 4, 1 + 5 * 4, 1 + 9 * 4 },
+ { 0, 0, 1, 1, 7, 10, 7, 10, 3 + 0 * 4, 3 + 0 * 4, 3 + 1 * 4, 3 + 1 * 4, 1 + 4 * 4, 1 + 8 * 4, 1 + 4 * 4, 1 + 8 * 4 },
+ { 0, 2, 0, 2, 7, 10, 7, 10, 3 + 0 * 4, 3 + 2 * 4, 3 + 0 * 4, 3 + 2 * 4, 1 + 4 * 4, 1 + 8 * 4, 1 + 4 * 4, 1 + 8 * 4 }
+ };
+
+ sl->topleft_partition = -1;
+
+ top_xy = mb_xy - (h->mb_stride << MB_FIELD(sl));
+
+ /* Wow, what a mess, why didn't they simplify the interlacing & intra
+ * stuff, I can't imagine that these complex rules are worth it. */
+
+ topleft_xy = top_xy - 1;
+ topright_xy = top_xy + 1;
+ left_xy[LBOT] = left_xy[LTOP] = mb_xy - 1;
+ sl->left_block = left_block_options[0];
+ if (FRAME_MBAFF(h)) {
+ const int left_mb_field_flag = IS_INTERLACED(h->cur_pic.mb_type[mb_xy - 1]);
+ const int curr_mb_field_flag = IS_INTERLACED(mb_type);
+ if (sl->mb_y & 1) {
+ if (left_mb_field_flag != curr_mb_field_flag) {
+ left_xy[LBOT] = left_xy[LTOP] = mb_xy - h->mb_stride - 1;
+ if (curr_mb_field_flag) {
+ left_xy[LBOT] += h->mb_stride;
+ sl->left_block = left_block_options[3];
+ } else {
+ topleft_xy += h->mb_stride;
+ /* take top left mv from the middle of the mb, as opposed
+ * to all other modes which use the bottom right partition */
+ sl->topleft_partition = 0;
+ sl->left_block = left_block_options[1];
+ }
+ }
+ } else {
+ if (curr_mb_field_flag) {
+ topleft_xy += h->mb_stride & (((h->cur_pic.mb_type[top_xy - 1] >> 7) & 1) - 1);
+ topright_xy += h->mb_stride & (((h->cur_pic.mb_type[top_xy + 1] >> 7) & 1) - 1);
+ top_xy += h->mb_stride & (((h->cur_pic.mb_type[top_xy] >> 7) & 1) - 1);
+ }
+ if (left_mb_field_flag != curr_mb_field_flag) {
+ if (curr_mb_field_flag) {
+ left_xy[LBOT] += h->mb_stride;
+ sl->left_block = left_block_options[3];
+ } else {
+ sl->left_block = left_block_options[2];
+ }
+ }
+ }
+ }
+
+ sl->topleft_mb_xy = topleft_xy;
+ sl->top_mb_xy = top_xy;
+ sl->topright_mb_xy = topright_xy;
+ sl->left_mb_xy[LTOP] = left_xy[LTOP];
+ sl->left_mb_xy[LBOT] = left_xy[LBOT];
+ //FIXME do we need all in the context?
+
+ sl->topleft_type = h->cur_pic.mb_type[topleft_xy];
+ sl->top_type = h->cur_pic.mb_type[top_xy];
+ sl->topright_type = h->cur_pic.mb_type[topright_xy];
+ sl->left_type[LTOP] = h->cur_pic.mb_type[left_xy[LTOP]];
+ sl->left_type[LBOT] = h->cur_pic.mb_type[left_xy[LBOT]];
+
+ if (FMO) {
+ if (h->slice_table[topleft_xy] != sl->slice_num)
+ sl->topleft_type = 0;
+ if (h->slice_table[top_xy] != sl->slice_num)
+ sl->top_type = 0;
+ if (h->slice_table[left_xy[LTOP]] != sl->slice_num)
+ sl->left_type[LTOP] = sl->left_type[LBOT] = 0;
+ } else {
+ if (h->slice_table[topleft_xy] != sl->slice_num) {
+ sl->topleft_type = 0;
+ if (h->slice_table[top_xy] != sl->slice_num)
+ sl->top_type = 0;
+ if (h->slice_table[left_xy[LTOP]] != sl->slice_num)
+ sl->left_type[LTOP] = sl->left_type[LBOT] = 0;
+ }
+ }
+ if (h->slice_table[topright_xy] != sl->slice_num)
+ sl->topright_type = 0;
+}
+
+static void fill_decode_caches(const H264Context *h, H264SliceContext *sl, int mb_type)
+{
+ int topleft_xy, top_xy, topright_xy, left_xy[LEFT_MBS];
+ int topleft_type, top_type, topright_type, left_type[LEFT_MBS];
+ const uint8_t *left_block = sl->left_block;
+ int i;
+ uint8_t *nnz;
+ uint8_t *nnz_cache;
+
+ topleft_xy = sl->topleft_mb_xy;
+ top_xy = sl->top_mb_xy;
+ topright_xy = sl->topright_mb_xy;
+ left_xy[LTOP] = sl->left_mb_xy[LTOP];
+ left_xy[LBOT] = sl->left_mb_xy[LBOT];
+ topleft_type = sl->topleft_type;
+ top_type = sl->top_type;
+ topright_type = sl->topright_type;
+ left_type[LTOP] = sl->left_type[LTOP];
+ left_type[LBOT] = sl->left_type[LBOT];
+
+ if (!IS_SKIP(mb_type)) {
+ if (IS_INTRA(mb_type)) {
+ int type_mask = h->pps.constrained_intra_pred ? IS_INTRA(-1) : -1;
+ sl->topleft_samples_available =
+ sl->top_samples_available =
+ sl->left_samples_available = 0xFFFF;
+ sl->topright_samples_available = 0xEEEA;
+
+ if (!(top_type & type_mask)) {
+ sl->topleft_samples_available = 0xB3FF;
+ sl->top_samples_available = 0x33FF;
+ sl->topright_samples_available = 0x26EA;
+ }
+ if (IS_INTERLACED(mb_type) != IS_INTERLACED(left_type[LTOP])) {
+ if (IS_INTERLACED(mb_type)) {
+ if (!(left_type[LTOP] & type_mask)) {
+ sl->topleft_samples_available &= 0xDFFF;
+ sl->left_samples_available &= 0x5FFF;
+ }
+ if (!(left_type[LBOT] & type_mask)) {
+ sl->topleft_samples_available &= 0xFF5F;
+ sl->left_samples_available &= 0xFF5F;
+ }
+ } else {
+ int left_typei = h->cur_pic.mb_type[left_xy[LTOP] + h->mb_stride];
+
+ av_assert2(left_xy[LTOP] == left_xy[LBOT]);
+ if (!((left_typei & type_mask) && (left_type[LTOP] & type_mask))) {
+ sl->topleft_samples_available &= 0xDF5F;
+ sl->left_samples_available &= 0x5F5F;
+ }
+ }
+ } else {
+ if (!(left_type[LTOP] & type_mask)) {
+ sl->topleft_samples_available &= 0xDF5F;
+ sl->left_samples_available &= 0x5F5F;
+ }
+ }
+
+ if (!(topleft_type & type_mask))
+ sl->topleft_samples_available &= 0x7FFF;
+
+ if (!(topright_type & type_mask))
+ sl->topright_samples_available &= 0xFBFF;
+
+ if (IS_INTRA4x4(mb_type)) {
+ if (IS_INTRA4x4(top_type)) {
+ AV_COPY32(sl->intra4x4_pred_mode_cache + 4 + 8 * 0, sl->intra4x4_pred_mode + h->mb2br_xy[top_xy]);
+ } else {
+ sl->intra4x4_pred_mode_cache[4 + 8 * 0] =
+ sl->intra4x4_pred_mode_cache[5 + 8 * 0] =
+ sl->intra4x4_pred_mode_cache[6 + 8 * 0] =
+ sl->intra4x4_pred_mode_cache[7 + 8 * 0] = 2 - 3 * !(top_type & type_mask);
+ }
+ for (i = 0; i < 2; i++) {
+ if (IS_INTRA4x4(left_type[LEFT(i)])) {
+ int8_t *mode = sl->intra4x4_pred_mode + h->mb2br_xy[left_xy[LEFT(i)]];
+ sl->intra4x4_pred_mode_cache[3 + 8 * 1 + 2 * 8 * i] = mode[6 - left_block[0 + 2 * i]];
+ sl->intra4x4_pred_mode_cache[3 + 8 * 2 + 2 * 8 * i] = mode[6 - left_block[1 + 2 * i]];
+ } else {
+ sl->intra4x4_pred_mode_cache[3 + 8 * 1 + 2 * 8 * i] =
+ sl->intra4x4_pred_mode_cache[3 + 8 * 2 + 2 * 8 * i] = 2 - 3 * !(left_type[LEFT(i)] & type_mask);
+ }
+ }
+ }
+ }
+
+ /*
+ * 0 . T T. T T T T
+ * 1 L . .L . . . .
+ * 2 L . .L . . . .
+ * 3 . T TL . . . .
+ * 4 L . .L . . . .
+ * 5 L . .. . . . .
+ */
+ /* FIXME: constraint_intra_pred & partitioning & nnz
+ * (let us hope this is just a typo in the spec) */
+ nnz_cache = sl->non_zero_count_cache;
+ if (top_type) {
+ nnz = h->non_zero_count[top_xy];
+ AV_COPY32(&nnz_cache[4 + 8 * 0], &nnz[4 * 3]);
+ if (!h->chroma_y_shift) {
+ AV_COPY32(&nnz_cache[4 + 8 * 5], &nnz[4 * 7]);
+ AV_COPY32(&nnz_cache[4 + 8 * 10], &nnz[4 * 11]);
+ } else {
+ AV_COPY32(&nnz_cache[4 + 8 * 5], &nnz[4 * 5]);
+ AV_COPY32(&nnz_cache[4 + 8 * 10], &nnz[4 * 9]);
+ }
+ } else {
+ uint32_t top_empty = CABAC(h) && !IS_INTRA(mb_type) ? 0 : 0x40404040;
+ AV_WN32A(&nnz_cache[4 + 8 * 0], top_empty);
+ AV_WN32A(&nnz_cache[4 + 8 * 5], top_empty);
+ AV_WN32A(&nnz_cache[4 + 8 * 10], top_empty);
+ }
+
+ for (i = 0; i < 2; i++) {
+ if (left_type[LEFT(i)]) {
+ nnz = h->non_zero_count[left_xy[LEFT(i)]];
+ nnz_cache[3 + 8 * 1 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i]];
+ nnz_cache[3 + 8 * 2 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i]];
+ if (CHROMA444(h)) {
+ nnz_cache[3 + 8 * 6 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] + 4 * 4];
+ nnz_cache[3 + 8 * 7 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] + 4 * 4];
+ nnz_cache[3 + 8 * 11 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] + 8 * 4];
+ nnz_cache[3 + 8 * 12 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] + 8 * 4];
+ } else if (CHROMA422(h)) {
+ nnz_cache[3 + 8 * 6 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] - 2 + 4 * 4];
+ nnz_cache[3 + 8 * 7 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] - 2 + 4 * 4];
+ nnz_cache[3 + 8 * 11 + 2 * 8 * i] = nnz[left_block[8 + 0 + 2 * i] - 2 + 8 * 4];
+ nnz_cache[3 + 8 * 12 + 2 * 8 * i] = nnz[left_block[8 + 1 + 2 * i] - 2 + 8 * 4];
+ } else {
+ nnz_cache[3 + 8 * 6 + 8 * i] = nnz[left_block[8 + 4 + 2 * i]];
+ nnz_cache[3 + 8 * 11 + 8 * i] = nnz[left_block[8 + 5 + 2 * i]];
+ }
+ } else {
+ nnz_cache[3 + 8 * 1 + 2 * 8 * i] =
+ nnz_cache[3 + 8 * 2 + 2 * 8 * i] =
+ nnz_cache[3 + 8 * 6 + 2 * 8 * i] =
+ nnz_cache[3 + 8 * 7 + 2 * 8 * i] =
+ nnz_cache[3 + 8 * 11 + 2 * 8 * i] =
+ nnz_cache[3 + 8 * 12 + 2 * 8 * i] = CABAC(h) && !IS_INTRA(mb_type) ? 0 : 64;
+ }
+ }
+
+ if (CABAC(h)) {
+ // top_cbp
+ if (top_type)
+ sl->top_cbp = h->cbp_table[top_xy];
+ else
+ sl->top_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F;
+ // left_cbp
+ if (left_type[LTOP]) {
+ sl->left_cbp = (h->cbp_table[left_xy[LTOP]] & 0x7F0) |
+ ((h->cbp_table[left_xy[LTOP]] >> (left_block[0] & (~1))) & 2) |
+ (((h->cbp_table[left_xy[LBOT]] >> (left_block[2] & (~1))) & 2) << 2);
+ } else {
+ sl->left_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F;
+ }
+ }
+ }
+
+ if (IS_INTER(mb_type) || (IS_DIRECT(mb_type) && sl->direct_spatial_mv_pred)) {
+ int list;
+ int b_stride = h->b_stride;
+ for (list = 0; list < sl->list_count; list++) {
+ int8_t *ref_cache = &sl->ref_cache[list][scan8[0]];
+ int8_t *ref = h->cur_pic.ref_index[list];
+ int16_t(*mv_cache)[2] = &sl->mv_cache[list][scan8[0]];
+ int16_t(*mv)[2] = h->cur_pic.motion_val[list];
+ if (!USES_LIST(mb_type, list))
+ continue;
+ av_assert2(!(IS_DIRECT(mb_type) && !sl->direct_spatial_mv_pred));
+
+ if (USES_LIST(top_type, list)) {
+ const int b_xy = h->mb2b_xy[top_xy] + 3 * b_stride;
+ AV_COPY128(mv_cache[0 - 1 * 8], mv[b_xy + 0]);
+ ref_cache[0 - 1 * 8] =
+ ref_cache[1 - 1 * 8] = ref[4 * top_xy + 2];
+ ref_cache[2 - 1 * 8] =
+ ref_cache[3 - 1 * 8] = ref[4 * top_xy + 3];
+ } else {
+ AV_ZERO128(mv_cache[0 - 1 * 8]);
+ AV_WN32A(&ref_cache[0 - 1 * 8],
+ ((top_type ? LIST_NOT_USED : PART_NOT_AVAILABLE) & 0xFF) * 0x01010101u);
+ }
+
+ if (mb_type & (MB_TYPE_16x8 | MB_TYPE_8x8)) {
+ for (i = 0; i < 2; i++) {
+ int cache_idx = -1 + i * 2 * 8;
+ if (USES_LIST(left_type[LEFT(i)], list)) {
+ const int b_xy = h->mb2b_xy[left_xy[LEFT(i)]] + 3;
+ const int b8_xy = 4 * left_xy[LEFT(i)] + 1;
+ AV_COPY32(mv_cache[cache_idx],
+ mv[b_xy + b_stride * left_block[0 + i * 2]]);
+ AV_COPY32(mv_cache[cache_idx + 8],
+ mv[b_xy + b_stride * left_block[1 + i * 2]]);
+ ref_cache[cache_idx] = ref[b8_xy + (left_block[0 + i * 2] & ~1)];
+ ref_cache[cache_idx + 8] = ref[b8_xy + (left_block[1 + i * 2] & ~1)];
+ } else {
+ AV_ZERO32(mv_cache[cache_idx]);
+ AV_ZERO32(mv_cache[cache_idx + 8]);
+ ref_cache[cache_idx] =
+ ref_cache[cache_idx + 8] = (left_type[LEFT(i)]) ? LIST_NOT_USED
+ : PART_NOT_AVAILABLE;
+ }
+ }
+ } else {
+ if (USES_LIST(left_type[LTOP], list)) {
+ const int b_xy = h->mb2b_xy[left_xy[LTOP]] + 3;
+ const int b8_xy = 4 * left_xy[LTOP] + 1;
+ AV_COPY32(mv_cache[-1], mv[b_xy + b_stride * left_block[0]]);
+ ref_cache[-1] = ref[b8_xy + (left_block[0] & ~1)];
+ } else {
+ AV_ZERO32(mv_cache[-1]);
+ ref_cache[-1] = left_type[LTOP] ? LIST_NOT_USED
+ : PART_NOT_AVAILABLE;
+ }
+ }
+
+ if (USES_LIST(topright_type, list)) {
+ const int b_xy = h->mb2b_xy[topright_xy] + 3 * b_stride;
+ AV_COPY32(mv_cache[4 - 1 * 8], mv[b_xy]);
+ ref_cache[4 - 1 * 8] = ref[4 * topright_xy + 2];
+ } else {
+ AV_ZERO32(mv_cache[4 - 1 * 8]);
+ ref_cache[4 - 1 * 8] = topright_type ? LIST_NOT_USED
+ : PART_NOT_AVAILABLE;
+ }
+ if(ref_cache[2 - 1*8] < 0 || ref_cache[4 - 1 * 8] < 0) {
+ if (USES_LIST(topleft_type, list)) {
+ const int b_xy = h->mb2b_xy[topleft_xy] + 3 + b_stride +
+ (sl->topleft_partition & 2 * b_stride);
+ const int b8_xy = 4 * topleft_xy + 1 + (sl->topleft_partition & 2);
+ AV_COPY32(mv_cache[-1 - 1 * 8], mv[b_xy]);
+ ref_cache[-1 - 1 * 8] = ref[b8_xy];
+ } else {
+ AV_ZERO32(mv_cache[-1 - 1 * 8]);
+ ref_cache[-1 - 1 * 8] = topleft_type ? LIST_NOT_USED
+ : PART_NOT_AVAILABLE;
+ }
+ }
+
+ if ((mb_type & (MB_TYPE_SKIP | MB_TYPE_DIRECT2)) && !FRAME_MBAFF(h))
+ continue;
+
+ if (!(mb_type & (MB_TYPE_SKIP | MB_TYPE_DIRECT2))) {
+ uint8_t(*mvd_cache)[2] = &sl->mvd_cache[list][scan8[0]];
+ uint8_t(*mvd)[2] = sl->mvd_table[list];
+ ref_cache[2 + 8 * 0] =
+ ref_cache[2 + 8 * 2] = PART_NOT_AVAILABLE;
+ AV_ZERO32(mv_cache[2 + 8 * 0]);
+ AV_ZERO32(mv_cache[2 + 8 * 2]);
+
+ if (CABAC(h)) {
+ if (USES_LIST(top_type, list)) {
+ const int b_xy = h->mb2br_xy[top_xy];
+ AV_COPY64(mvd_cache[0 - 1 * 8], mvd[b_xy + 0]);
+ } else {
+ AV_ZERO64(mvd_cache[0 - 1 * 8]);
+ }
+ if (USES_LIST(left_type[LTOP], list)) {
+ const int b_xy = h->mb2br_xy[left_xy[LTOP]] + 6;
+ AV_COPY16(mvd_cache[-1 + 0 * 8], mvd[b_xy - left_block[0]]);
+ AV_COPY16(mvd_cache[-1 + 1 * 8], mvd[b_xy - left_block[1]]);
+ } else {
+ AV_ZERO16(mvd_cache[-1 + 0 * 8]);
+ AV_ZERO16(mvd_cache[-1 + 1 * 8]);
+ }
+ if (USES_LIST(left_type[LBOT], list)) {
+ const int b_xy = h->mb2br_xy[left_xy[LBOT]] + 6;
+ AV_COPY16(mvd_cache[-1 + 2 * 8], mvd[b_xy - left_block[2]]);
+ AV_COPY16(mvd_cache[-1 + 3 * 8], mvd[b_xy - left_block[3]]);
+ } else {
+ AV_ZERO16(mvd_cache[-1 + 2 * 8]);
+ AV_ZERO16(mvd_cache[-1 + 3 * 8]);
+ }
+ AV_ZERO16(mvd_cache[2 + 8 * 0]);
+ AV_ZERO16(mvd_cache[2 + 8 * 2]);
+ if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
+ uint8_t *direct_cache = &sl->direct_cache[scan8[0]];
+ uint8_t *direct_table = h->direct_table;
+ fill_rectangle(direct_cache, 4, 4, 8, MB_TYPE_16x16 >> 1, 1);
+
+ if (IS_DIRECT(top_type)) {
+ AV_WN32A(&direct_cache[-1 * 8],
+ 0x01010101u * (MB_TYPE_DIRECT2 >> 1));
+ } else if (IS_8X8(top_type)) {
+ int b8_xy = 4 * top_xy;
+ direct_cache[0 - 1 * 8] = direct_table[b8_xy + 2];
+ direct_cache[2 - 1 * 8] = direct_table[b8_xy + 3];
+ } else {
+ AV_WN32A(&direct_cache[-1 * 8],
+ 0x01010101 * (MB_TYPE_16x16 >> 1));
+ }
+
+ if (IS_DIRECT(left_type[LTOP]))
+ direct_cache[-1 + 0 * 8] = MB_TYPE_DIRECT2 >> 1;
+ else if (IS_8X8(left_type[LTOP]))
+ direct_cache[-1 + 0 * 8] = direct_table[4 * left_xy[LTOP] + 1 + (left_block[0] & ~1)];
+ else
+ direct_cache[-1 + 0 * 8] = MB_TYPE_16x16 >> 1;
+
+ if (IS_DIRECT(left_type[LBOT]))
+ direct_cache[-1 + 2 * 8] = MB_TYPE_DIRECT2 >> 1;
+ else if (IS_8X8(left_type[LBOT]))
+ direct_cache[-1 + 2 * 8] = direct_table[4 * left_xy[LBOT] + 1 + (left_block[2] & ~1)];
+ else
+ direct_cache[-1 + 2 * 8] = MB_TYPE_16x16 >> 1;
+ }
+ }
+ }
+
+#define MAP_MVS \
+ MAP_F2F(scan8[0] - 1 - 1 * 8, topleft_type) \
+ MAP_F2F(scan8[0] + 0 - 1 * 8, top_type) \
+ MAP_F2F(scan8[0] + 1 - 1 * 8, top_type) \
+ MAP_F2F(scan8[0] + 2 - 1 * 8, top_type) \
+ MAP_F2F(scan8[0] + 3 - 1 * 8, top_type) \
+ MAP_F2F(scan8[0] + 4 - 1 * 8, topright_type) \
+ MAP_F2F(scan8[0] - 1 + 0 * 8, left_type[LTOP]) \
+ MAP_F2F(scan8[0] - 1 + 1 * 8, left_type[LTOP]) \
+ MAP_F2F(scan8[0] - 1 + 2 * 8, left_type[LBOT]) \
+ MAP_F2F(scan8[0] - 1 + 3 * 8, left_type[LBOT])
+
+ if (FRAME_MBAFF(h)) {
+ if (MB_FIELD(sl)) {
+
+#define MAP_F2F(idx, mb_type) \
+ if (!IS_INTERLACED(mb_type) && sl->ref_cache[list][idx] >= 0) { \
+ sl->ref_cache[list][idx] *= 2; \
+ sl->mv_cache[list][idx][1] /= 2; \
+ sl->mvd_cache[list][idx][1] >>= 1; \
+ }
+
+ MAP_MVS
+ } else {
+
+#undef MAP_F2F
+#define MAP_F2F(idx, mb_type) \
+ if (IS_INTERLACED(mb_type) && sl->ref_cache[list][idx] >= 0) { \
+ sl->ref_cache[list][idx] >>= 1; \
+ sl->mv_cache[list][idx][1] *= 2; \
+ sl->mvd_cache[list][idx][1] <<= 1; \
+ }
+
+ MAP_MVS
+#undef MAP_F2F
+ }
+ }
+ }
+ }
+
+ sl->neighbor_transform_size = !!IS_8x8DCT(top_type) + !!IS_8x8DCT(left_type[LTOP]);
+}
+
+/**
+ * decodes a P_SKIP or B_SKIP macroblock
+ */
+static void av_unused decode_mb_skip(const H264Context *h, H264SliceContext *sl)
+{
+ const int mb_xy = sl->mb_xy;
+ int mb_type = 0;
+
+ memset(h->non_zero_count[mb_xy], 0, 48);
+
+ if (MB_FIELD(sl))
+ mb_type |= MB_TYPE_INTERLACED;
+
+ if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {
+ // just for fill_caches. pred_direct_motion will set the real mb_type
+ mb_type |= MB_TYPE_L0L1 | MB_TYPE_DIRECT2 | MB_TYPE_SKIP;
+ if (sl->direct_spatial_mv_pred) {
+ fill_decode_neighbors(h, sl, mb_type);
+ fill_decode_caches(h, sl, mb_type); //FIXME check what is needed and what not ...
+ }
+ ff_h264_pred_direct_motion(h, sl, &mb_type);
+ mb_type |= MB_TYPE_SKIP;
+ } else {
+ mb_type |= MB_TYPE_16x16 | MB_TYPE_P0L0 | MB_TYPE_P1L0 | MB_TYPE_SKIP;
+
+ fill_decode_neighbors(h, sl, mb_type);
+ pred_pskip_motion(h, sl);
+ }
+
+ write_back_motion(h, sl, mb_type);
+ h->cur_pic.mb_type[mb_xy] = mb_type;
+ h->cur_pic.qscale_table[mb_xy] = sl->qscale;
+ h->slice_table[mb_xy] = sl->slice_num;
+ sl->prev_mb_skipped = 1;
+}
+
+#endif /* AVCODEC_H264_MVPRED_H */
diff --git a/ffmpeg-2-8-11/libavcodec/h264_parser.c b/ffmpeg-2-8-12/libavcodec/h264_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264_parser.c
rename to ffmpeg-2-8-12/libavcodec/h264_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264_picture.c b/ffmpeg-2-8-12/libavcodec/h264_picture.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264_picture.c
rename to ffmpeg-2-8-12/libavcodec/h264_picture.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264_ps.c b/ffmpeg-2-8-12/libavcodec/h264_ps.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264_ps.c
rename to ffmpeg-2-8-12/libavcodec/h264_ps.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264_refs.c b/ffmpeg-2-8-12/libavcodec/h264_refs.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264_refs.c
rename to ffmpeg-2-8-12/libavcodec/h264_refs.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264_sei.c b/ffmpeg-2-8-12/libavcodec/h264_sei.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264_sei.c
rename to ffmpeg-2-8-12/libavcodec/h264_sei.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264_slice.c b/ffmpeg-2-8-12/libavcodec/h264_slice.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264_slice.c
rename to ffmpeg-2-8-12/libavcodec/h264_slice.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264addpx_template.c b/ffmpeg-2-8-12/libavcodec/h264addpx_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264addpx_template.c
rename to ffmpeg-2-8-12/libavcodec/h264addpx_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264chroma.c b/ffmpeg-2-8-12/libavcodec/h264chroma.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264chroma.c
rename to ffmpeg-2-8-12/libavcodec/h264chroma.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264chroma.h b/ffmpeg-2-8-12/libavcodec/h264chroma.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264chroma.h
rename to ffmpeg-2-8-12/libavcodec/h264chroma.h
diff --git a/ffmpeg-2-8-11/libavcodec/h264chroma_template.c b/ffmpeg-2-8-12/libavcodec/h264chroma_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264chroma_template.c
rename to ffmpeg-2-8-12/libavcodec/h264chroma_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264data.h b/ffmpeg-2-8-12/libavcodec/h264data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264data.h
rename to ffmpeg-2-8-12/libavcodec/h264data.h
diff --git a/ffmpeg-2-8-11/libavcodec/h264dsp.c b/ffmpeg-2-8-12/libavcodec/h264dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264dsp.c
rename to ffmpeg-2-8-12/libavcodec/h264dsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264dsp.h b/ffmpeg-2-8-12/libavcodec/h264dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264dsp.h
rename to ffmpeg-2-8-12/libavcodec/h264dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/h264dsp_template.c b/ffmpeg-2-8-12/libavcodec/h264dsp_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264dsp_template.c
rename to ffmpeg-2-8-12/libavcodec/h264dsp_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264idct.c b/ffmpeg-2-8-12/libavcodec/h264idct.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264idct.c
rename to ffmpeg-2-8-12/libavcodec/h264idct.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264idct.h b/ffmpeg-2-8-12/libavcodec/h264idct.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264idct.h
rename to ffmpeg-2-8-12/libavcodec/h264idct.h
diff --git a/ffmpeg-2-8-11/libavcodec/h264idct_template.c b/ffmpeg-2-8-12/libavcodec/h264idct_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264idct_template.c
rename to ffmpeg-2-8-12/libavcodec/h264idct_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264pred.c b/ffmpeg-2-8-12/libavcodec/h264pred.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264pred.c
rename to ffmpeg-2-8-12/libavcodec/h264pred.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264pred.h b/ffmpeg-2-8-12/libavcodec/h264pred.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264pred.h
rename to ffmpeg-2-8-12/libavcodec/h264pred.h
diff --git a/ffmpeg-2-8-11/libavcodec/h264pred_template.c b/ffmpeg-2-8-12/libavcodec/h264pred_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264pred_template.c
rename to ffmpeg-2-8-12/libavcodec/h264pred_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264qpel.c b/ffmpeg-2-8-12/libavcodec/h264qpel.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264qpel.c
rename to ffmpeg-2-8-12/libavcodec/h264qpel.c
diff --git a/ffmpeg-2-8-11/libavcodec/h264qpel.h b/ffmpeg-2-8-12/libavcodec/h264qpel.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264qpel.h
rename to ffmpeg-2-8-12/libavcodec/h264qpel.h
diff --git a/ffmpeg-2-8-11/libavcodec/h264qpel_template.c b/ffmpeg-2-8-12/libavcodec/h264qpel_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/h264qpel_template.c
rename to ffmpeg-2-8-12/libavcodec/h264qpel_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/hap.c b/ffmpeg-2-8-12/libavcodec/hap.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hap.c
rename to ffmpeg-2-8-12/libavcodec/hap.c
diff --git a/ffmpeg-2-8-11/libavcodec/hap.h b/ffmpeg-2-8-12/libavcodec/hap.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hap.h
rename to ffmpeg-2-8-12/libavcodec/hap.h
diff --git a/ffmpeg-2-8-11/libavcodec/hapdec.c b/ffmpeg-2-8-12/libavcodec/hapdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hapdec.c
rename to ffmpeg-2-8-12/libavcodec/hapdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/hapenc.c b/ffmpeg-2-8-12/libavcodec/hapenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hapenc.c
rename to ffmpeg-2-8-12/libavcodec/hapenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/hevc.c b/ffmpeg-2-8-12/libavcodec/hevc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevc.c
rename to ffmpeg-2-8-12/libavcodec/hevc.c
diff --git a/ffmpeg-2-8-11/libavcodec/hevc.h b/ffmpeg-2-8-12/libavcodec/hevc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevc.h
rename to ffmpeg-2-8-12/libavcodec/hevc.h
diff --git a/ffmpeg-2-8-11/libavcodec/hevc_cabac.c b/ffmpeg-2-8-12/libavcodec/hevc_cabac.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevc_cabac.c
rename to ffmpeg-2-8-12/libavcodec/hevc_cabac.c
diff --git a/ffmpeg-2-8-11/libavcodec/hevc_data.c b/ffmpeg-2-8-12/libavcodec/hevc_data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevc_data.c
rename to ffmpeg-2-8-12/libavcodec/hevc_data.c
diff --git a/ffmpeg-2-8-11/libavcodec/hevc_filter.c b/ffmpeg-2-8-12/libavcodec/hevc_filter.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevc_filter.c
rename to ffmpeg-2-8-12/libavcodec/hevc_filter.c
diff --git a/ffmpeg-2-8-11/libavcodec/hevc_mp4toannexb_bsf.c b/ffmpeg-2-8-12/libavcodec/hevc_mp4toannexb_bsf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevc_mp4toannexb_bsf.c
rename to ffmpeg-2-8-12/libavcodec/hevc_mp4toannexb_bsf.c
diff --git a/ffmpeg-2-8-11/libavcodec/hevc_mvs.c b/ffmpeg-2-8-12/libavcodec/hevc_mvs.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevc_mvs.c
rename to ffmpeg-2-8-12/libavcodec/hevc_mvs.c
diff --git a/ffmpeg-2-8-11/libavcodec/hevc_parse.c b/ffmpeg-2-8-12/libavcodec/hevc_parse.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevc_parse.c
rename to ffmpeg-2-8-12/libavcodec/hevc_parse.c
diff --git a/ffmpeg-2-8-11/libavcodec/hevc_parser.c b/ffmpeg-2-8-12/libavcodec/hevc_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevc_parser.c
rename to ffmpeg-2-8-12/libavcodec/hevc_parser.c
diff --git a/ffmpeg-2-8-12/libavcodec/hevc_ps.c b/ffmpeg-2-8-12/libavcodec/hevc_ps.c
new file mode 100644
index 0000000..02b6454
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/hevc_ps.c
@@ -0,0 +1,1618 @@
+/*
+ * HEVC Parameter Set decoding
+ *
+ * Copyright (C) 2012 - 2103 Guillaume Martres
+ * Copyright (C) 2012 - 2103 Mickael Raulet
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ * Copyright (C) 2013 Vittorio Giovara
+ *
+ * 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 "golomb.h"
+#include "hevc.h"
+
+static const uint8_t default_scaling_list_intra[] = {
+ 16, 16, 16, 16, 17, 18, 21, 24,
+ 16, 16, 16, 16, 17, 19, 22, 25,
+ 16, 16, 17, 18, 20, 22, 25, 29,
+ 16, 16, 18, 21, 24, 27, 31, 36,
+ 17, 17, 20, 24, 30, 35, 41, 47,
+ 18, 19, 22, 27, 35, 44, 54, 65,
+ 21, 22, 25, 31, 41, 54, 70, 88,
+ 24, 25, 29, 36, 47, 65, 88, 115
+};
+
+static const uint8_t default_scaling_list_inter[] = {
+ 16, 16, 16, 16, 17, 18, 20, 24,
+ 16, 16, 16, 17, 18, 20, 24, 25,
+ 16, 16, 17, 18, 20, 24, 25, 28,
+ 16, 17, 18, 20, 24, 25, 28, 33,
+ 17, 18, 20, 24, 25, 28, 33, 41,
+ 18, 20, 24, 25, 28, 33, 41, 54,
+ 20, 24, 25, 28, 33, 41, 54, 71,
+ 24, 25, 28, 33, 41, 54, 71, 91
+};
+
+static const AVRational vui_sar[] = {
+ { 0, 1 },
+ { 1, 1 },
+ { 12, 11 },
+ { 10, 11 },
+ { 16, 11 },
+ { 40, 33 },
+ { 24, 11 },
+ { 20, 11 },
+ { 32, 11 },
+ { 80, 33 },
+ { 18, 11 },
+ { 15, 11 },
+ { 64, 33 },
+ { 160, 99 },
+ { 4, 3 },
+ { 3, 2 },
+ { 2, 1 },
+};
+
+static void remove_pps(HEVCParamSets *s, int id)
+{
+ if (s->pps_list[id] && s->pps == (const HEVCPPS*)s->pps_list[id]->data)
+ s->pps = NULL;
+ av_buffer_unref(&s->pps_list[id]);
+}
+
+static void remove_sps(HEVCParamSets *s, int id)
+{
+ int i;
+ if (s->sps_list[id]) {
+ if (s->sps == (const HEVCSPS*)s->sps_list[id]->data)
+ s->sps = NULL;
+
+ /* drop all PPS that depend on this SPS */
+ for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++)
+ if (s->pps_list[i] && ((HEVCPPS*)s->pps_list[i]->data)->sps_id == id)
+ remove_pps(s, i);
+
+ av_assert0(!(s->sps_list[id] && s->sps == (HEVCSPS*)s->sps_list[id]->data));
+ }
+ av_buffer_unref(&s->sps_list[id]);
+}
+
+static void remove_vps(HEVCParamSets *s, int id)
+{
+ int i;
+ if (s->vps_list[id]) {
+ if (s->vps == (const HEVCVPS*)s->vps_list[id]->data)
+ s->vps = NULL;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s->sps_list); i++)
+ if (s->sps_list[i] && ((HEVCSPS*)s->sps_list[i]->data)->vps_id == id)
+ remove_sps(s, i);
+ }
+ av_buffer_unref(&s->vps_list[id]);
+}
+
+int ff_hevc_decode_short_term_rps(GetBitContext *gb, AVCodecContext *avctx,
+ ShortTermRPS *rps, const HEVCSPS *sps, int is_slice_header)
+{
+ uint8_t rps_predict = 0;
+ int delta_poc;
+ int k0 = 0;
+ int k1 = 0;
+ int k = 0;
+ int i;
+
+ if (rps != sps->st_rps && sps->nb_st_rps)
+ rps_predict = get_bits1(gb);
+
+ if (rps_predict) {
+ const ShortTermRPS *rps_ridx;
+ int delta_rps;
+ unsigned abs_delta_rps;
+ uint8_t use_delta_flag = 0;
+ uint8_t delta_rps_sign;
+
+ if (is_slice_header) {
+ unsigned int delta_idx = get_ue_golomb_long(gb) + 1;
+ if (delta_idx > sps->nb_st_rps) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid value of delta_idx in slice header RPS: %d > %d.\n",
+ delta_idx, sps->nb_st_rps);
+ return AVERROR_INVALIDDATA;
+ }
+ rps_ridx = &sps->st_rps[sps->nb_st_rps - delta_idx];
+ rps->rps_idx_num_delta_pocs = rps_ridx->num_delta_pocs;
+ } else
+ rps_ridx = &sps->st_rps[rps - sps->st_rps - 1];
+
+ delta_rps_sign = get_bits1(gb);
+ abs_delta_rps = get_ue_golomb_long(gb) + 1;
+ if (abs_delta_rps < 1 || abs_delta_rps > 32768) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid value of abs_delta_rps: %d\n",
+ abs_delta_rps);
+ return AVERROR_INVALIDDATA;
+ }
+ delta_rps = (1 - (delta_rps_sign << 1)) * abs_delta_rps;
+ for (i = 0; i <= rps_ridx->num_delta_pocs; i++) {
+ int used = rps->used[k] = get_bits1(gb);
+
+ if (!used)
+ use_delta_flag = get_bits1(gb);
+
+ if (used || use_delta_flag) {
+ if (i < rps_ridx->num_delta_pocs)
+ delta_poc = delta_rps + rps_ridx->delta_poc[i];
+ else
+ delta_poc = delta_rps;
+ rps->delta_poc[k] = delta_poc;
+ if (delta_poc < 0)
+ k0++;
+ else
+ k1++;
+ k++;
+ }
+ }
+
+ if (k >= FF_ARRAY_ELEMS(rps->used)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid num_delta_pocs: %d\n", k);
+ return AVERROR_INVALIDDATA;
+ }
+
+ rps->num_delta_pocs = k;
+ rps->num_negative_pics = k0;
+ // sort in increasing order (smallest first)
+ if (rps->num_delta_pocs != 0) {
+ int used, tmp;
+ for (i = 1; i < rps->num_delta_pocs; i++) {
+ delta_poc = rps->delta_poc[i];
+ used = rps->used[i];
+ for (k = i - 1; k >= 0; k--) {
+ tmp = rps->delta_poc[k];
+ if (delta_poc < tmp) {
+ rps->delta_poc[k + 1] = tmp;
+ rps->used[k + 1] = rps->used[k];
+ rps->delta_poc[k] = delta_poc;
+ rps->used[k] = used;
+ }
+ }
+ }
+ }
+ if ((rps->num_negative_pics >> 1) != 0) {
+ int used;
+ k = rps->num_negative_pics - 1;
+ // flip the negative values to largest first
+ for (i = 0; i < rps->num_negative_pics >> 1; i++) {
+ delta_poc = rps->delta_poc[i];
+ used = rps->used[i];
+ rps->delta_poc[i] = rps->delta_poc[k];
+ rps->used[i] = rps->used[k];
+ rps->delta_poc[k] = delta_poc;
+ rps->used[k] = used;
+ k--;
+ }
+ }
+ } else {
+ unsigned int prev, nb_positive_pics;
+ rps->num_negative_pics = get_ue_golomb_long(gb);
+ nb_positive_pics = get_ue_golomb_long(gb);
+
+ if (rps->num_negative_pics >= MAX_REFS ||
+ nb_positive_pics >= MAX_REFS) {
+ av_log(avctx, AV_LOG_ERROR, "Too many refs in a short term RPS.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ rps->num_delta_pocs = rps->num_negative_pics + nb_positive_pics;
+ if (rps->num_delta_pocs) {
+ prev = 0;
+ for (i = 0; i < rps->num_negative_pics; i++) {
+ delta_poc = get_ue_golomb_long(gb) + 1;
+ prev -= delta_poc;
+ rps->delta_poc[i] = prev;
+ rps->used[i] = get_bits1(gb);
+ }
+ prev = 0;
+ for (i = 0; i < nb_positive_pics; i++) {
+ delta_poc = get_ue_golomb_long(gb) + 1;
+ prev += delta_poc;
+ rps->delta_poc[rps->num_negative_pics + i] = prev;
+ rps->used[rps->num_negative_pics + i] = get_bits1(gb);
+ }
+ }
+ }
+ return 0;
+}
+
+
+static int decode_profile_tier_level(GetBitContext *gb, AVCodecContext *avctx,
+ PTLCommon *ptl)
+{
+ int i;
+
+ if (get_bits_left(gb) < 2+1+5 + 32 + 4 + 16 + 16 + 12)
+ return -1;
+
+ ptl->profile_space = get_bits(gb, 2);
+ ptl->tier_flag = get_bits1(gb);
+ ptl->profile_idc = get_bits(gb, 5);
+ if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN)
+ av_log(avctx, AV_LOG_DEBUG, "Main profile bitstream\n");
+ else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_10)
+ av_log(avctx, AV_LOG_DEBUG, "Main 10 profile bitstream\n");
+ else if (ptl->profile_idc == FF_PROFILE_HEVC_MAIN_STILL_PICTURE)
+ av_log(avctx, AV_LOG_DEBUG, "Main Still Picture profile bitstream\n");
+ else if (ptl->profile_idc == FF_PROFILE_HEVC_REXT)
+ av_log(avctx, AV_LOG_DEBUG, "Range Extension profile bitstream\n");
+ else
+ av_log(avctx, AV_LOG_WARNING, "Unknown HEVC profile: %d\n", ptl->profile_idc);
+
+ for (i = 0; i < 32; i++)
+ ptl->profile_compatibility_flag[i] = get_bits1(gb);
+ ptl->progressive_source_flag = get_bits1(gb);
+ ptl->interlaced_source_flag = get_bits1(gb);
+ ptl->non_packed_constraint_flag = get_bits1(gb);
+ ptl->frame_only_constraint_flag = get_bits1(gb);
+
+ skip_bits(gb, 16); // XXX_reserved_zero_44bits[0..15]
+ skip_bits(gb, 16); // XXX_reserved_zero_44bits[16..31]
+ skip_bits(gb, 12); // XXX_reserved_zero_44bits[32..43]
+
+ return 0;
+}
+
+static int parse_ptl(GetBitContext *gb, AVCodecContext *avctx,
+ PTL *ptl, int max_num_sub_layers)
+{
+ int i;
+ if (decode_profile_tier_level(gb, avctx, &ptl->general_ptl) < 0 ||
+ get_bits_left(gb) < 8 + 8*2) {
+ av_log(avctx, AV_LOG_ERROR, "PTL information too short\n");
+ return -1;
+ }
+
+ ptl->general_ptl.level_idc = get_bits(gb, 8);
+
+ for (i = 0; i < max_num_sub_layers - 1; i++) {
+ ptl->sub_layer_profile_present_flag[i] = get_bits1(gb);
+ ptl->sub_layer_level_present_flag[i] = get_bits1(gb);
+ }
+
+ if (max_num_sub_layers - 1> 0)
+ for (i = max_num_sub_layers - 1; i < 8; i++)
+ skip_bits(gb, 2); // reserved_zero_2bits[i]
+ for (i = 0; i < max_num_sub_layers - 1; i++) {
+ if (ptl->sub_layer_profile_present_flag[i] &&
+ decode_profile_tier_level(gb, avctx, &ptl->sub_layer_ptl[i]) < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "PTL information for sublayer %i too short\n", i);
+ return -1;
+ }
+ if (ptl->sub_layer_level_present_flag[i]) {
+ if (get_bits_left(gb) < 8) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Not enough data for sublayer %i level_idc\n", i);
+ return -1;
+ } else
+ ptl->sub_layer_ptl[i].level_idc = get_bits(gb, 8);
+ }
+ }
+
+ return 0;
+}
+
+static void decode_sublayer_hrd(GetBitContext *gb, unsigned int nb_cpb,
+ int subpic_params_present)
+{
+ int i;
+
+ for (i = 0; i < nb_cpb; i++) {
+ get_ue_golomb_long(gb); // bit_rate_value_minus1
+ get_ue_golomb_long(gb); // cpb_size_value_minus1
+
+ if (subpic_params_present) {
+ get_ue_golomb_long(gb); // cpb_size_du_value_minus1
+ get_ue_golomb_long(gb); // bit_rate_du_value_minus1
+ }
+ skip_bits1(gb); // cbr_flag
+ }
+}
+
+static int decode_hrd(GetBitContext *gb, int common_inf_present,
+ int max_sublayers)
+{
+ int nal_params_present = 0, vcl_params_present = 0;
+ int subpic_params_present = 0;
+ int i;
+
+ if (common_inf_present) {
+ nal_params_present = get_bits1(gb);
+ vcl_params_present = get_bits1(gb);
+
+ if (nal_params_present || vcl_params_present) {
+ subpic_params_present = get_bits1(gb);
+
+ if (subpic_params_present) {
+ skip_bits(gb, 8); // tick_divisor_minus2
+ skip_bits(gb, 5); // du_cpb_removal_delay_increment_length_minus1
+ skip_bits(gb, 1); // sub_pic_cpb_params_in_pic_timing_sei_flag
+ skip_bits(gb, 5); // dpb_output_delay_du_length_minus1
+ }
+
+ skip_bits(gb, 4); // bit_rate_scale
+ skip_bits(gb, 4); // cpb_size_scale
+
+ if (subpic_params_present)
+ skip_bits(gb, 4); // cpb_size_du_scale
+
+ skip_bits(gb, 5); // initial_cpb_removal_delay_length_minus1
+ skip_bits(gb, 5); // au_cpb_removal_delay_length_minus1
+ skip_bits(gb, 5); // dpb_output_delay_length_minus1
+ }
+ }
+
+ for (i = 0; i < max_sublayers; i++) {
+ int low_delay = 0;
+ unsigned int nb_cpb = 1;
+ int fixed_rate = get_bits1(gb);
+
+ if (!fixed_rate)
+ fixed_rate = get_bits1(gb);
+
+ if (fixed_rate)
+ get_ue_golomb_long(gb); // elemental_duration_in_tc_minus1
+ else
+ low_delay = get_bits1(gb);
+
+ if (!low_delay) {
+ nb_cpb = get_ue_golomb_long(gb) + 1;
+ if (nb_cpb < 1 || nb_cpb > 32) {
+ av_log(NULL, AV_LOG_ERROR, "nb_cpb %d invalid\n", nb_cpb);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if (nal_params_present)
+ decode_sublayer_hrd(gb, nb_cpb, subpic_params_present);
+ if (vcl_params_present)
+ decode_sublayer_hrd(gb, nb_cpb, subpic_params_present);
+ }
+ return 0;
+}
+
+int ff_hevc_decode_nal_vps(GetBitContext *gb, AVCodecContext *avctx,
+ HEVCParamSets *ps)
+{
+ int i,j;
+ int vps_id = 0;
+ HEVCVPS *vps;
+ AVBufferRef *vps_buf = av_buffer_allocz(sizeof(*vps));
+
+ if (!vps_buf)
+ return AVERROR(ENOMEM);
+ vps = (HEVCVPS*)vps_buf->data;
+
+ av_log(avctx, AV_LOG_DEBUG, "Decoding VPS\n");
+
+ vps_id = get_bits(gb, 4);
+ if (vps_id >= MAX_VPS_COUNT) {
+ av_log(avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", vps_id);
+ goto err;
+ }
+
+ if (get_bits(gb, 2) != 3) { // vps_reserved_three_2bits
+ av_log(avctx, AV_LOG_ERROR, "vps_reserved_three_2bits is not three\n");
+ goto err;
+ }
+
+ vps->vps_max_layers = get_bits(gb, 6) + 1;
+ vps->vps_max_sub_layers = get_bits(gb, 3) + 1;
+ vps->vps_temporal_id_nesting_flag = get_bits1(gb);
+
+ if (get_bits(gb, 16) != 0xffff) { // vps_reserved_ffff_16bits
+ av_log(avctx, AV_LOG_ERROR, "vps_reserved_ffff_16bits is not 0xffff\n");
+ goto err;
+ }
+
+ if (vps->vps_max_sub_layers > MAX_SUB_LAYERS) {
+ av_log(avctx, AV_LOG_ERROR, "vps_max_sub_layers out of range: %d\n",
+ vps->vps_max_sub_layers);
+ goto err;
+ }
+
+ if (parse_ptl(gb, avctx, &vps->ptl, vps->vps_max_sub_layers) < 0)
+ goto err;
+
+ vps->vps_sub_layer_ordering_info_present_flag = get_bits1(gb);
+
+ i = vps->vps_sub_layer_ordering_info_present_flag ? 0 : vps->vps_max_sub_layers - 1;
+ for (; i < vps->vps_max_sub_layers; i++) {
+ vps->vps_max_dec_pic_buffering[i] = get_ue_golomb_long(gb) + 1;
+ vps->vps_num_reorder_pics[i] = get_ue_golomb_long(gb);
+ vps->vps_max_latency_increase[i] = get_ue_golomb_long(gb) - 1;
+
+ if (vps->vps_max_dec_pic_buffering[i] > MAX_DPB_SIZE || !vps->vps_max_dec_pic_buffering[i]) {
+ av_log(avctx, AV_LOG_ERROR, "vps_max_dec_pic_buffering_minus1 out of range: %d\n",
+ vps->vps_max_dec_pic_buffering[i] - 1);
+ goto err;
+ }
+ if (vps->vps_num_reorder_pics[i] > vps->vps_max_dec_pic_buffering[i] - 1) {
+ av_log(avctx, AV_LOG_WARNING, "vps_max_num_reorder_pics out of range: %d\n",
+ vps->vps_num_reorder_pics[i]);
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ goto err;
+ }
+ }
+
+ vps->vps_max_layer_id = get_bits(gb, 6);
+ vps->vps_num_layer_sets = get_ue_golomb_long(gb) + 1;
+ if (vps->vps_num_layer_sets < 1 || vps->vps_num_layer_sets > 1024 ||
+ (vps->vps_num_layer_sets - 1LL) * (vps->vps_max_layer_id + 1LL) > get_bits_left(gb)) {
+ av_log(avctx, AV_LOG_ERROR, "too many layer_id_included_flags\n");
+ goto err;
+ }
+
+ for (i = 1; i < vps->vps_num_layer_sets; i++)
+ for (j = 0; j <= vps->vps_max_layer_id; j++)
+ skip_bits(gb, 1); // layer_id_included_flag[i][j]
+
+ vps->vps_timing_info_present_flag = get_bits1(gb);
+ if (vps->vps_timing_info_present_flag) {
+ vps->vps_num_units_in_tick = get_bits_long(gb, 32);
+ vps->vps_time_scale = get_bits_long(gb, 32);
+ vps->vps_poc_proportional_to_timing_flag = get_bits1(gb);
+ if (vps->vps_poc_proportional_to_timing_flag)
+ vps->vps_num_ticks_poc_diff_one = get_ue_golomb_long(gb) + 1;
+ vps->vps_num_hrd_parameters = get_ue_golomb_long(gb);
+ if (vps->vps_num_hrd_parameters > (unsigned)vps->vps_num_layer_sets) {
+ av_log(avctx, AV_LOG_ERROR,
+ "vps_num_hrd_parameters %d is invalid\n", vps->vps_num_hrd_parameters);
+ goto err;
+ }
+ for (i = 0; i < vps->vps_num_hrd_parameters; i++) {
+ int common_inf_present = 1;
+
+ get_ue_golomb_long(gb); // hrd_layer_set_idx
+ if (i)
+ common_inf_present = get_bits1(gb);
+ decode_hrd(gb, common_inf_present, vps->vps_max_sub_layers);
+ }
+ }
+ get_bits1(gb); /* vps_extension_flag */
+
+ if (get_bits_left(gb) < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Overread VPS by %d bits\n", -get_bits_left(gb));
+ if (ps->vps_list[vps_id])
+ goto err;
+ }
+
+ if (ps->vps_list[vps_id] &&
+ !memcmp(ps->vps_list[vps_id]->data, vps_buf->data, vps_buf->size)) {
+ av_buffer_unref(&vps_buf);
+ } else {
+ remove_vps(ps, vps_id);
+ ps->vps_list[vps_id] = vps_buf;
+ }
+
+ return 0;
+
+err:
+ av_buffer_unref(&vps_buf);
+ return AVERROR_INVALIDDATA;
+}
+
+static void decode_vui(GetBitContext *gb, AVCodecContext *avctx,
+ int apply_defdispwin, HEVCSPS *sps)
+{
+ VUI *vui = &sps->vui;
+ GetBitContext backup;
+ int sar_present, alt = 0;
+
+ av_log(avctx, AV_LOG_DEBUG, "Decoding VUI\n");
+
+ sar_present = get_bits1(gb);
+ if (sar_present) {
+ uint8_t sar_idx = get_bits(gb, 8);
+ if (sar_idx < FF_ARRAY_ELEMS(vui_sar))
+ vui->sar = vui_sar[sar_idx];
+ else if (sar_idx == 255) {
+ vui->sar.num = get_bits(gb, 16);
+ vui->sar.den = get_bits(gb, 16);
+ } else
+ av_log(avctx, AV_LOG_WARNING,
+ "Unknown SAR index: %u.\n", sar_idx);
+ }
+
+ vui->overscan_info_present_flag = get_bits1(gb);
+ if (vui->overscan_info_present_flag)
+ vui->overscan_appropriate_flag = get_bits1(gb);
+
+ vui->video_signal_type_present_flag = get_bits1(gb);
+ if (vui->video_signal_type_present_flag) {
+ vui->video_format = get_bits(gb, 3);
+ vui->video_full_range_flag = get_bits1(gb);
+ vui->colour_description_present_flag = get_bits1(gb);
+ if (vui->video_full_range_flag && sps->pix_fmt == AV_PIX_FMT_YUV420P)
+ sps->pix_fmt = AV_PIX_FMT_YUVJ420P;
+ if (vui->colour_description_present_flag) {
+ vui->colour_primaries = get_bits(gb, 8);
+ vui->transfer_characteristic = get_bits(gb, 8);
+ vui->matrix_coeffs = get_bits(gb, 8);
+
+ // Set invalid values to "unspecified"
+ if (vui->colour_primaries >= AVCOL_PRI_NB)
+ vui->colour_primaries = AVCOL_PRI_UNSPECIFIED;
+ if (vui->transfer_characteristic >= AVCOL_TRC_NB)
+ vui->transfer_characteristic = AVCOL_TRC_UNSPECIFIED;
+ if (vui->matrix_coeffs >= AVCOL_SPC_NB)
+ vui->matrix_coeffs = AVCOL_SPC_UNSPECIFIED;
+ }
+ }
+
+ vui->chroma_loc_info_present_flag = get_bits1(gb);
+ if (vui->chroma_loc_info_present_flag) {
+ vui->chroma_sample_loc_type_top_field = get_ue_golomb_long(gb);
+ vui->chroma_sample_loc_type_bottom_field = get_ue_golomb_long(gb);
+ }
+
+ vui->neutra_chroma_indication_flag = get_bits1(gb);
+ vui->field_seq_flag = get_bits1(gb);
+ vui->frame_field_info_present_flag = get_bits1(gb);
+
+ if (get_bits_left(gb) >= 68 && show_bits_long(gb, 21) == 0x100000) {
+ vui->default_display_window_flag = 0;
+ av_log(avctx, AV_LOG_WARNING, "Invalid default display window\n");
+ } else
+ vui->default_display_window_flag = get_bits1(gb);
+ // Backup context in case an alternate header is detected
+ memcpy(&backup, gb, sizeof(backup));
+
+ if (vui->default_display_window_flag) {
+ //TODO: * 2 is only valid for 420
+ vui->def_disp_win.left_offset = get_ue_golomb_long(gb) * 2;
+ vui->def_disp_win.right_offset = get_ue_golomb_long(gb) * 2;
+ vui->def_disp_win.top_offset = get_ue_golomb_long(gb) * 2;
+ vui->def_disp_win.bottom_offset = get_ue_golomb_long(gb) * 2;
+
+ if (apply_defdispwin &&
+ avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) {
+ av_log(avctx, AV_LOG_DEBUG,
+ "discarding vui default display window, "
+ "original values are l:%u r:%u t:%u b:%u\n",
+ vui->def_disp_win.left_offset,
+ vui->def_disp_win.right_offset,
+ vui->def_disp_win.top_offset,
+ vui->def_disp_win.bottom_offset);
+
+ vui->def_disp_win.left_offset =
+ vui->def_disp_win.right_offset =
+ vui->def_disp_win.top_offset =
+ vui->def_disp_win.bottom_offset = 0;
+ }
+ }
+
+ vui->vui_timing_info_present_flag = get_bits1(gb);
+
+ if (vui->vui_timing_info_present_flag) {
+ if( get_bits_left(gb) < 66) {
+ // The alternate syntax seem to have timing info located
+ // at where def_disp_win is normally located
+ av_log(avctx, AV_LOG_WARNING,
+ "Strange VUI timing information, retrying...\n");
+ vui->default_display_window_flag = 0;
+ memset(&vui->def_disp_win, 0, sizeof(vui->def_disp_win));
+ memcpy(gb, &backup, sizeof(backup));
+ alt = 1;
+ }
+ vui->vui_num_units_in_tick = get_bits_long(gb, 32);
+ vui->vui_time_scale = get_bits_long(gb, 32);
+ if (alt) {
+ av_log(avctx, AV_LOG_INFO, "Retry got %i/%i fps\n",
+ vui->vui_time_scale, vui->vui_num_units_in_tick);
+ }
+ vui->vui_poc_proportional_to_timing_flag = get_bits1(gb);
+ if (vui->vui_poc_proportional_to_timing_flag)
+ vui->vui_num_ticks_poc_diff_one_minus1 = get_ue_golomb_long(gb);
+ vui->vui_hrd_parameters_present_flag = get_bits1(gb);
+ if (vui->vui_hrd_parameters_present_flag)
+ decode_hrd(gb, 1, sps->max_sub_layers);
+ }
+
+ vui->bitstream_restriction_flag = get_bits1(gb);
+ if (vui->bitstream_restriction_flag) {
+ vui->tiles_fixed_structure_flag = get_bits1(gb);
+ vui->motion_vectors_over_pic_boundaries_flag = get_bits1(gb);
+ vui->restricted_ref_pic_lists_flag = get_bits1(gb);
+ vui->min_spatial_segmentation_idc = get_ue_golomb_long(gb);
+ vui->max_bytes_per_pic_denom = get_ue_golomb_long(gb);
+ vui->max_bits_per_min_cu_denom = get_ue_golomb_long(gb);
+ vui->log2_max_mv_length_horizontal = get_ue_golomb_long(gb);
+ vui->log2_max_mv_length_vertical = get_ue_golomb_long(gb);
+ }
+}
+
+static void set_default_scaling_list_data(ScalingList *sl)
+{
+ int matrixId;
+
+ for (matrixId = 0; matrixId < 6; matrixId++) {
+ // 4x4 default is 16
+ memset(sl->sl[0][matrixId], 16, 16);
+ sl->sl_dc[0][matrixId] = 16; // default for 16x16
+ sl->sl_dc[1][matrixId] = 16; // default for 32x32
+ }
+ memcpy(sl->sl[1][0], default_scaling_list_intra, 64);
+ memcpy(sl->sl[1][1], default_scaling_list_intra, 64);
+ memcpy(sl->sl[1][2], default_scaling_list_intra, 64);
+ memcpy(sl->sl[1][3], default_scaling_list_inter, 64);
+ memcpy(sl->sl[1][4], default_scaling_list_inter, 64);
+ memcpy(sl->sl[1][5], default_scaling_list_inter, 64);
+ memcpy(sl->sl[2][0], default_scaling_list_intra, 64);
+ memcpy(sl->sl[2][1], default_scaling_list_intra, 64);
+ memcpy(sl->sl[2][2], default_scaling_list_intra, 64);
+ memcpy(sl->sl[2][3], default_scaling_list_inter, 64);
+ memcpy(sl->sl[2][4], default_scaling_list_inter, 64);
+ memcpy(sl->sl[2][5], default_scaling_list_inter, 64);
+ memcpy(sl->sl[3][0], default_scaling_list_intra, 64);
+ memcpy(sl->sl[3][1], default_scaling_list_intra, 64);
+ memcpy(sl->sl[3][2], default_scaling_list_intra, 64);
+ memcpy(sl->sl[3][3], default_scaling_list_inter, 64);
+ memcpy(sl->sl[3][4], default_scaling_list_inter, 64);
+ memcpy(sl->sl[3][5], default_scaling_list_inter, 64);
+}
+
+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];
+ int size_id, matrix_id, pos;
+ int i;
+
+ for (size_id = 0; size_id < 4; size_id++)
+ for (matrix_id = 0; matrix_id < 6; matrix_id += ((size_id == 3) ? 3 : 1)) {
+ scaling_list_pred_mode_flag = get_bits1(gb);
+ if (!scaling_list_pred_mode_flag) {
+ unsigned int delta = get_ue_golomb_long(gb);
+ /* Only need to handle non-zero delta. Zero means default,
+ * which should already be in the arrays. */
+ if (delta) {
+ // Copy from previous array.
+ if (matrix_id < delta) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid delta in scaling list data: %d.\n", delta);
+ return AVERROR_INVALIDDATA;
+ }
+
+ memcpy(sl->sl[size_id][matrix_id],
+ sl->sl[size_id][matrix_id - delta],
+ size_id > 0 ? 64 : 16);
+ if (size_id > 1)
+ sl->sl_dc[size_id - 2][matrix_id] = sl->sl_dc[size_id - 2][matrix_id - delta];
+ }
+ } else {
+ int next_coef, coef_num;
+ int32_t scaling_list_delta_coef;
+
+ next_coef = 8;
+ coef_num = FFMIN(64, 1 << (4 + (size_id << 1)));
+ if (size_id > 1) {
+ scaling_list_dc_coef[size_id - 2][matrix_id] = get_se_golomb(gb) + 8;
+ next_coef = scaling_list_dc_coef[size_id - 2][matrix_id];
+ sl->sl_dc[size_id - 2][matrix_id] = next_coef;
+ }
+ for (i = 0; i < coef_num; i++) {
+ if (size_id == 0)
+ pos = 4 * ff_hevc_diag_scan4x4_y[i] +
+ ff_hevc_diag_scan4x4_x[i];
+ else
+ pos = 8 * ff_hevc_diag_scan8x8_y[i] +
+ ff_hevc_diag_scan8x8_x[i];
+
+ scaling_list_delta_coef = get_se_golomb(gb);
+ next_coef = (next_coef + 256U + scaling_list_delta_coef) % 256;
+ sl->sl[size_id][matrix_id][pos] = next_coef;
+ }
+ }
+ }
+
+ if (sps->chroma_format_idc == 3) {
+ for (i = 0; i < 64; i++) {
+ sl->sl[3][1][i] = sl->sl[2][1][i];
+ sl->sl[3][2][i] = sl->sl[2][2][i];
+ sl->sl[3][4][i] = sl->sl[2][4][i];
+ sl->sl[3][5][i] = sl->sl[2][5][i];
+ }
+ sl->sl_dc[1][1] = sl->sl_dc[0][1];
+ sl->sl_dc[1][2] = sl->sl_dc[0][2];
+ sl->sl_dc[1][4] = sl->sl_dc[0][4];
+ sl->sl_dc[1][5] = sl->sl_dc[0][5];
+ }
+
+
+ return 0;
+}
+
+static int map_pixel_format(AVCodecContext *avctx, HEVCSPS *sps)
+{
+ const AVPixFmtDescriptor *desc;
+ switch (sps->bit_depth) {
+ case 8:
+ if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY8;
+ if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P;
+ if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P;
+ if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P;
+ break;
+ case 9:
+ if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;
+ if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P9;
+ if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P9;
+ if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P9;
+ break;
+ case 10:
+ if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;
+ if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P10;
+ if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P10;
+ if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P10;
+ break;
+ case 12:
+ if (sps->chroma_format_idc == 0) sps->pix_fmt = AV_PIX_FMT_GRAY16;
+ if (sps->chroma_format_idc == 1) sps->pix_fmt = AV_PIX_FMT_YUV420P12;
+ if (sps->chroma_format_idc == 2) sps->pix_fmt = AV_PIX_FMT_YUV422P12;
+ if (sps->chroma_format_idc == 3) sps->pix_fmt = AV_PIX_FMT_YUV444P12;
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR,
+ "4:2:0, 4:2:2, 4:4:4 supports are currently specified for 8, 10 and 12 bits.\n");
+ av_log(avctx, AV_LOG_ERROR,
+ "chroma_format_idc is %d, depth is %d",
+ sps->chroma_format_idc, sps->bit_depth);
+ return AVERROR_INVALIDDATA;
+ }
+
+ desc = av_pix_fmt_desc_get(sps->pix_fmt);
+ if (!desc)
+ return AVERROR(EINVAL);
+
+ sps->hshift[0] = sps->vshift[0] = 0;
+ sps->hshift[2] = sps->hshift[1] = desc->log2_chroma_w;
+ sps->vshift[2] = sps->vshift[1] = desc->log2_chroma_h;
+
+ sps->pixel_shift = sps->bit_depth > 8;
+
+ return 0;
+}
+
+int ff_hevc_parse_sps(HEVCSPS *sps, GetBitContext *gb, unsigned int *sps_id,
+ int apply_defdispwin, AVBufferRef **vps_list, AVCodecContext *avctx)
+{
+ int ret = 0;
+ int log2_diff_max_min_transform_block_size;
+ int bit_depth_chroma, start, vui_present, sublayer_ordering_info;
+ int i;
+
+ // Coded parameters
+
+ sps->vps_id = get_bits(gb, 4);
+ if (sps->vps_id >= MAX_VPS_COUNT) {
+ av_log(avctx, AV_LOG_ERROR, "VPS id out of range: %d\n", sps->vps_id);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (vps_list && !vps_list[sps->vps_id]) {
+ av_log(avctx, AV_LOG_ERROR, "VPS %d does not exist\n",
+ sps->vps_id);
+ return AVERROR_INVALIDDATA;
+ }
+
+ sps->max_sub_layers = get_bits(gb, 3) + 1;
+ if (sps->max_sub_layers > MAX_SUB_LAYERS) {
+ av_log(avctx, AV_LOG_ERROR, "sps_max_sub_layers out of range: %d\n",
+ sps->max_sub_layers);
+ return AVERROR_INVALIDDATA;
+ }
+
+ skip_bits1(gb); // temporal_id_nesting_flag
+
+ if ((ret = parse_ptl(gb, avctx, &sps->ptl, sps->max_sub_layers)) < 0)
+ return ret;
+
+ *sps_id = get_ue_golomb_long(gb);
+ if (*sps_id >= MAX_SPS_COUNT) {
+ av_log(avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", *sps_id);
+ return AVERROR_INVALIDDATA;
+ }
+
+ sps->chroma_format_idc = get_ue_golomb_long(gb);
+ if (sps->chroma_format_idc > 3U) {
+ av_log(avctx, AV_LOG_ERROR, "chroma_format_idc %d is invalid\n", sps->chroma_format_idc);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (sps->chroma_format_idc == 3)
+ sps->separate_colour_plane_flag = get_bits1(gb);
+
+ if (sps->separate_colour_plane_flag)
+ sps->chroma_format_idc = 0;
+
+ sps->width = get_ue_golomb_long(gb);
+ sps->height = get_ue_golomb_long(gb);
+ if ((ret = av_image_check_size(sps->width,
+ sps->height, 0, avctx)) < 0)
+ return ret;
+
+ if (get_bits1(gb)) { // pic_conformance_flag
+ //TODO: * 2 is only valid for 420
+ sps->pic_conf_win.left_offset = get_ue_golomb_long(gb) * 2;
+ sps->pic_conf_win.right_offset = get_ue_golomb_long(gb) * 2;
+ sps->pic_conf_win.top_offset = get_ue_golomb_long(gb) * 2;
+ sps->pic_conf_win.bottom_offset = get_ue_golomb_long(gb) * 2;
+
+ if (avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP) {
+ av_log(avctx, AV_LOG_DEBUG,
+ "discarding sps conformance window, "
+ "original values are l:%u r:%u t:%u b:%u\n",
+ sps->pic_conf_win.left_offset,
+ sps->pic_conf_win.right_offset,
+ sps->pic_conf_win.top_offset,
+ sps->pic_conf_win.bottom_offset);
+
+ sps->pic_conf_win.left_offset =
+ sps->pic_conf_win.right_offset =
+ sps->pic_conf_win.top_offset =
+ sps->pic_conf_win.bottom_offset = 0;
+ }
+ sps->output_window = sps->pic_conf_win;
+ }
+
+ sps->bit_depth = get_ue_golomb_long(gb) + 8;
+ bit_depth_chroma = get_ue_golomb_long(gb) + 8;
+ if (sps->chroma_format_idc && bit_depth_chroma != sps->bit_depth) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Luma bit depth (%d) is different from chroma bit depth (%d), "
+ "this is unsupported.\n",
+ sps->bit_depth, bit_depth_chroma);
+ return AVERROR_INVALIDDATA;
+ }
+
+ ret = map_pixel_format(avctx, sps);
+ if (ret < 0)
+ return ret;
+
+ sps->log2_max_poc_lsb = get_ue_golomb_long(gb) + 4;
+ if (sps->log2_max_poc_lsb > 16) {
+ av_log(avctx, AV_LOG_ERROR, "log2_max_pic_order_cnt_lsb_minus4 out range: %d\n",
+ sps->log2_max_poc_lsb - 4);
+ return AVERROR_INVALIDDATA;
+ }
+
+ sublayer_ordering_info = get_bits1(gb);
+ start = sublayer_ordering_info ? 0 : sps->max_sub_layers - 1;
+ for (i = start; i < sps->max_sub_layers; i++) {
+ sps->temporal_layer[i].max_dec_pic_buffering = get_ue_golomb_long(gb) + 1;
+ sps->temporal_layer[i].num_reorder_pics = get_ue_golomb_long(gb);
+ sps->temporal_layer[i].max_latency_increase = get_ue_golomb_long(gb) - 1;
+ if (sps->temporal_layer[i].max_dec_pic_buffering > MAX_DPB_SIZE) {
+ av_log(avctx, AV_LOG_ERROR, "sps_max_dec_pic_buffering_minus1 out of range: %d\n",
+ sps->temporal_layer[i].max_dec_pic_buffering - 1);
+ return AVERROR_INVALIDDATA;
+ }
+ if (sps->temporal_layer[i].num_reorder_pics > sps->temporal_layer[i].max_dec_pic_buffering - 1) {
+ av_log(avctx, AV_LOG_WARNING, "sps_max_num_reorder_pics out of range: %d\n",
+ sps->temporal_layer[i].num_reorder_pics);
+ if (avctx->err_recognition & AV_EF_EXPLODE ||
+ sps->temporal_layer[i].num_reorder_pics > MAX_DPB_SIZE - 1) {
+ return AVERROR_INVALIDDATA;
+ }
+ sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[i].num_reorder_pics + 1;
+ }
+ }
+
+ if (!sublayer_ordering_info) {
+ for (i = 0; i < start; i++) {
+ sps->temporal_layer[i].max_dec_pic_buffering = sps->temporal_layer[start].max_dec_pic_buffering;
+ sps->temporal_layer[i].num_reorder_pics = sps->temporal_layer[start].num_reorder_pics;
+ sps->temporal_layer[i].max_latency_increase = sps->temporal_layer[start].max_latency_increase;
+ }
+ }
+
+ sps->log2_min_cb_size = get_ue_golomb_long(gb) + 3;
+ sps->log2_diff_max_min_coding_block_size = get_ue_golomb_long(gb);
+ sps->log2_min_tb_size = get_ue_golomb_long(gb) + 2;
+ log2_diff_max_min_transform_block_size = get_ue_golomb_long(gb);
+ sps->log2_max_trafo_size = log2_diff_max_min_transform_block_size +
+ sps->log2_min_tb_size;
+
+ if (sps->log2_min_cb_size < 3 || sps->log2_min_cb_size > 30) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid value %d for log2_min_cb_size", sps->log2_min_cb_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (sps->log2_diff_max_min_coding_block_size > 30) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid value %d for log2_diff_max_min_coding_block_size", sps->log2_diff_max_min_coding_block_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (sps->log2_min_tb_size >= sps->log2_min_cb_size || sps->log2_min_tb_size < 2) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid value for log2_min_tb_size");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (log2_diff_max_min_transform_block_size < 0 || log2_diff_max_min_transform_block_size > 30) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid value %d for log2_diff_max_min_transform_block_size", log2_diff_max_min_transform_block_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ sps->max_transform_hierarchy_depth_inter = get_ue_golomb_long(gb);
+ sps->max_transform_hierarchy_depth_intra = get_ue_golomb_long(gb);
+
+ sps->scaling_list_enable_flag = get_bits1(gb);
+ if (sps->scaling_list_enable_flag) {
+ set_default_scaling_list_data(&sps->scaling_list);
+
+ if (get_bits1(gb)) {
+ ret = scaling_list_data(gb, avctx, &sps->scaling_list, sps);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ sps->amp_enabled_flag = get_bits1(gb);
+ sps->sao_enabled = get_bits1(gb);
+
+ sps->pcm_enabled_flag = get_bits1(gb);
+ if (sps->pcm_enabled_flag) {
+ sps->pcm.bit_depth = get_bits(gb, 4) + 1;
+ sps->pcm.bit_depth_chroma = get_bits(gb, 4) + 1;
+ sps->pcm.log2_min_pcm_cb_size = get_ue_golomb_long(gb) + 3;
+ sps->pcm.log2_max_pcm_cb_size = sps->pcm.log2_min_pcm_cb_size +
+ get_ue_golomb_long(gb);
+ if (sps->pcm.bit_depth > sps->bit_depth) {
+ av_log(avctx, AV_LOG_ERROR,
+ "PCM bit depth (%d) is greater than normal bit depth (%d)\n",
+ sps->pcm.bit_depth, sps->bit_depth);
+ return AVERROR_INVALIDDATA;
+ }
+
+ sps->pcm.loop_filter_disable_flag = get_bits1(gb);
+ }
+
+ sps->nb_st_rps = get_ue_golomb_long(gb);
+ if (sps->nb_st_rps > MAX_SHORT_TERM_RPS_COUNT) {
+ av_log(avctx, AV_LOG_ERROR, "Too many short term RPS: %d.\n",
+ sps->nb_st_rps);
+ return AVERROR_INVALIDDATA;
+ }
+ for (i = 0; i < sps->nb_st_rps; i++) {
+ if ((ret = ff_hevc_decode_short_term_rps(gb, avctx, &sps->st_rps[i],
+ sps, 0)) < 0)
+ return ret;
+ }
+
+ sps->long_term_ref_pics_present_flag = get_bits1(gb);
+ if (sps->long_term_ref_pics_present_flag) {
+ sps->num_long_term_ref_pics_sps = get_ue_golomb_long(gb);
+ if (sps->num_long_term_ref_pics_sps > 31U) {
+ av_log(avctx, AV_LOG_ERROR, "num_long_term_ref_pics_sps %d is out of range.\n",
+ sps->num_long_term_ref_pics_sps);
+ return AVERROR_INVALIDDATA;
+ }
+ for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) {
+ sps->lt_ref_pic_poc_lsb_sps[i] = get_bits(gb, sps->log2_max_poc_lsb);
+ sps->used_by_curr_pic_lt_sps_flag[i] = get_bits1(gb);
+ }
+ }
+
+ sps->sps_temporal_mvp_enabled_flag = get_bits1(gb);
+ sps->sps_strong_intra_smoothing_enable_flag = get_bits1(gb);
+ sps->vui.sar = (AVRational){0, 1};
+ vui_present = get_bits1(gb);
+ if (vui_present)
+ decode_vui(gb, avctx, apply_defdispwin, sps);
+
+ if (get_bits1(gb)) { // sps_extension_flag
+ int sps_extension_flag[1];
+ for (i = 0; i < 1; i++)
+ sps_extension_flag[i] = get_bits1(gb);
+ skip_bits(gb, 7); //sps_extension_7bits = get_bits(gb, 7);
+ if (sps_extension_flag[0]) {
+ int extended_precision_processing_flag;
+ int high_precision_offsets_enabled_flag;
+ int cabac_bypass_alignment_enabled_flag;
+
+ sps->transform_skip_rotation_enabled_flag = get_bits1(gb);
+ sps->transform_skip_context_enabled_flag = get_bits1(gb);
+ sps->implicit_rdpcm_enabled_flag = get_bits1(gb);
+
+ sps->explicit_rdpcm_enabled_flag = get_bits1(gb);
+
+ extended_precision_processing_flag = get_bits1(gb);
+ if (extended_precision_processing_flag)
+ av_log(avctx, AV_LOG_WARNING,
+ "extended_precision_processing_flag not yet implemented\n");
+
+ sps->intra_smoothing_disabled_flag = get_bits1(gb);
+ high_precision_offsets_enabled_flag = get_bits1(gb);
+ if (high_precision_offsets_enabled_flag)
+ av_log(avctx, AV_LOG_WARNING,
+ "high_precision_offsets_enabled_flag not yet implemented\n");
+
+ sps->persistent_rice_adaptation_enabled_flag = get_bits1(gb);
+
+ cabac_bypass_alignment_enabled_flag = get_bits1(gb);
+ if (cabac_bypass_alignment_enabled_flag)
+ av_log(avctx, AV_LOG_WARNING,
+ "cabac_bypass_alignment_enabled_flag not yet implemented\n");
+ }
+ }
+ if (apply_defdispwin) {
+ sps->output_window.left_offset += sps->vui.def_disp_win.left_offset;
+ sps->output_window.right_offset += sps->vui.def_disp_win.right_offset;
+ sps->output_window.top_offset += sps->vui.def_disp_win.top_offset;
+ sps->output_window.bottom_offset += sps->vui.def_disp_win.bottom_offset;
+ }
+ if (sps->output_window.left_offset & (0x1F >> (sps->pixel_shift)) &&
+ !(avctx->flags & AV_CODEC_FLAG_UNALIGNED)) {
+ sps->output_window.left_offset &= ~(0x1F >> (sps->pixel_shift));
+ av_log(avctx, AV_LOG_WARNING, "Reducing left output window to %d "
+ "chroma samples to preserve alignment.\n",
+ sps->output_window.left_offset);
+ }
+ sps->output_width = sps->width -
+ (sps->output_window.left_offset + sps->output_window.right_offset);
+ sps->output_height = sps->height -
+ (sps->output_window.top_offset + sps->output_window.bottom_offset);
+ if (sps->width <= sps->output_window.left_offset + (int64_t)sps->output_window.right_offset ||
+ sps->height <= sps->output_window.top_offset + (int64_t)sps->output_window.bottom_offset) {
+ av_log(avctx, AV_LOG_WARNING, "Invalid visible frame dimensions: %dx%d.\n",
+ sps->output_width, sps->output_height);
+ if (avctx->err_recognition & AV_EF_EXPLODE) {
+ return AVERROR_INVALIDDATA;
+ }
+ av_log(avctx, AV_LOG_WARNING,
+ "Displaying the whole video surface.\n");
+ memset(&sps->pic_conf_win, 0, sizeof(sps->pic_conf_win));
+ memset(&sps->output_window, 0, sizeof(sps->output_window));
+ sps->output_width = sps->width;
+ sps->output_height = sps->height;
+ }
+
+ // Inferred parameters
+ sps->log2_ctb_size = sps->log2_min_cb_size +
+ sps->log2_diff_max_min_coding_block_size;
+ sps->log2_min_pu_size = sps->log2_min_cb_size - 1;
+
+ if (sps->log2_ctb_size > MAX_LOG2_CTB_SIZE) {
+ av_log(avctx, AV_LOG_ERROR, "CTB size out of range: 2^%d\n", sps->log2_ctb_size);
+ return AVERROR_INVALIDDATA;
+ }
+ if (sps->log2_ctb_size < 4) {
+ av_log(avctx,
+ AV_LOG_ERROR,
+ "log2_ctb_size %d differs from the bounds of any known profile\n",
+ sps->log2_ctb_size);
+ avpriv_request_sample(avctx, "log2_ctb_size %d", sps->log2_ctb_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ sps->ctb_width = (sps->width + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;
+ sps->ctb_height = (sps->height + (1 << sps->log2_ctb_size) - 1) >> sps->log2_ctb_size;
+ sps->ctb_size = sps->ctb_width * sps->ctb_height;
+
+ sps->min_cb_width = sps->width >> sps->log2_min_cb_size;
+ sps->min_cb_height = sps->height >> sps->log2_min_cb_size;
+ sps->min_tb_width = sps->width >> sps->log2_min_tb_size;
+ sps->min_tb_height = sps->height >> sps->log2_min_tb_size;
+ sps->min_pu_width = sps->width >> sps->log2_min_pu_size;
+ sps->min_pu_height = sps->height >> sps->log2_min_pu_size;
+ sps->tb_mask = (1 << (sps->log2_ctb_size - sps->log2_min_tb_size)) - 1;
+
+ sps->qp_bd_offset = 6 * (sps->bit_depth - 8);
+
+ if (av_mod_uintp2(sps->width, sps->log2_min_cb_size) ||
+ av_mod_uintp2(sps->height, sps->log2_min_cb_size)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid coded frame dimensions.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (sps->max_transform_hierarchy_depth_inter > sps->log2_ctb_size - sps->log2_min_tb_size) {
+ av_log(avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_inter out of range: %d\n",
+ sps->max_transform_hierarchy_depth_inter);
+ return AVERROR_INVALIDDATA;
+ }
+ if (sps->max_transform_hierarchy_depth_intra > sps->log2_ctb_size - sps->log2_min_tb_size) {
+ av_log(avctx, AV_LOG_ERROR, "max_transform_hierarchy_depth_intra out of range: %d\n",
+ sps->max_transform_hierarchy_depth_intra);
+ return AVERROR_INVALIDDATA;
+ }
+ if (sps->log2_max_trafo_size > FFMIN(sps->log2_ctb_size, 5)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "max transform block size out of range: %d\n",
+ sps->log2_max_trafo_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (get_bits_left(gb) < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Overread SPS by %d bits\n", -get_bits_left(gb));
+ return AVERROR_INVALIDDATA;
+ }
+
+ return 0;
+}
+
+int ff_hevc_decode_nal_sps(GetBitContext *gb, AVCodecContext *avctx,
+ HEVCParamSets *ps, int apply_defdispwin)
+{
+ HEVCSPS *sps;
+ AVBufferRef *sps_buf = av_buffer_allocz(sizeof(*sps));
+ unsigned int sps_id;
+ int ret;
+
+ if (!sps_buf)
+ return AVERROR(ENOMEM);
+ sps = (HEVCSPS*)sps_buf->data;
+
+ av_log(avctx, AV_LOG_DEBUG, "Decoding SPS\n");
+
+ ret = ff_hevc_parse_sps(sps, gb, &sps_id,
+ apply_defdispwin,
+ ps->vps_list, avctx);
+ if (ret < 0) {
+ av_buffer_unref(&sps_buf);
+ return ret;
+ }
+
+ if (avctx->debug & FF_DEBUG_BITSTREAM) {
+ av_log(avctx, AV_LOG_DEBUG,
+ "Parsed SPS: id %d; coded wxh: %dx%d; "
+ "cropped wxh: %dx%d; pix_fmt: %s.\n",
+ sps_id, sps->width, sps->height,
+ sps->output_width, sps->output_height,
+ av_get_pix_fmt_name(sps->pix_fmt));
+ }
+
+ /* check if this is a repeat of an already parsed SPS, then keep the
+ * original one.
+ * otherwise drop all PPSes that depend on it */
+ if (ps->sps_list[sps_id] &&
+ !memcmp(ps->sps_list[sps_id]->data, sps_buf->data, sps_buf->size)) {
+ av_buffer_unref(&sps_buf);
+ } else {
+ remove_sps(ps, sps_id);
+ ps->sps_list[sps_id] = sps_buf;
+ }
+
+ return 0;
+}
+
+static void hevc_pps_free(void *opaque, uint8_t *data)
+{
+ HEVCPPS *pps = (HEVCPPS*)data;
+
+ av_freep(&pps->column_width);
+ av_freep(&pps->row_height);
+ av_freep(&pps->col_bd);
+ av_freep(&pps->row_bd);
+ av_freep(&pps->col_idxX);
+ av_freep(&pps->ctb_addr_rs_to_ts);
+ av_freep(&pps->ctb_addr_ts_to_rs);
+ av_freep(&pps->tile_pos_rs);
+ av_freep(&pps->tile_id);
+ av_freep(&pps->min_tb_addr_zs_tab);
+
+ av_freep(&pps);
+}
+
+static int pps_range_extensions(GetBitContext *gb, AVCodecContext *avctx,
+ HEVCPPS *pps, HEVCSPS *sps) {
+ int i;
+
+ if (pps->transform_skip_enabled_flag) {
+ pps->log2_max_transform_skip_block_size = get_ue_golomb_long(gb) + 2;
+ }
+ pps->cross_component_prediction_enabled_flag = get_bits1(gb);
+ pps->chroma_qp_offset_list_enabled_flag = get_bits1(gb);
+ if (pps->chroma_qp_offset_list_enabled_flag) {
+ pps->diff_cu_chroma_qp_offset_depth = get_ue_golomb_long(gb);
+ pps->chroma_qp_offset_list_len_minus1 = get_ue_golomb_long(gb);
+ if (pps->chroma_qp_offset_list_len_minus1 && pps->chroma_qp_offset_list_len_minus1 >= 5) {
+ av_log(avctx, AV_LOG_ERROR,
+ "chroma_qp_offset_list_len_minus1 shall be in the range [0, 5].\n");
+ return AVERROR_INVALIDDATA;
+ }
+ for (i = 0; i <= pps->chroma_qp_offset_list_len_minus1; i++) {
+ pps->cb_qp_offset_list[i] = get_se_golomb_long(gb);
+ if (pps->cb_qp_offset_list[i]) {
+ av_log(avctx, AV_LOG_WARNING,
+ "cb_qp_offset_list not tested yet.\n");
+ }
+ pps->cr_qp_offset_list[i] = get_se_golomb_long(gb);
+ if (pps->cr_qp_offset_list[i]) {
+ av_log(avctx, AV_LOG_WARNING,
+ "cb_qp_offset_list not tested yet.\n");
+ }
+ }
+ }
+ pps->log2_sao_offset_scale_luma = get_ue_golomb_long(gb);
+ pps->log2_sao_offset_scale_chroma = get_ue_golomb_long(gb);
+
+ return(0);
+}
+
+static inline int setup_pps(AVCodecContext *avctx, GetBitContext *gb,
+ HEVCPPS *pps, HEVCSPS *sps)
+{
+ int log2_diff;
+ int pic_area_in_ctbs;
+ int i, j, x, y, ctb_addr_rs, tile_id;
+
+ // Inferred parameters
+ pps->col_bd = av_malloc_array(pps->num_tile_columns + 1, sizeof(*pps->col_bd));
+ pps->row_bd = av_malloc_array(pps->num_tile_rows + 1, sizeof(*pps->row_bd));
+ pps->col_idxX = av_malloc_array(sps->ctb_width, sizeof(*pps->col_idxX));
+ if (!pps->col_bd || !pps->row_bd || !pps->col_idxX)
+ return AVERROR(ENOMEM);
+
+ if (pps->uniform_spacing_flag) {
+ if (!pps->column_width) {
+ pps->column_width = av_malloc_array(pps->num_tile_columns, sizeof(*pps->column_width));
+ pps->row_height = av_malloc_array(pps->num_tile_rows, sizeof(*pps->row_height));
+ }
+ if (!pps->column_width || !pps->row_height)
+ return AVERROR(ENOMEM);
+
+ for (i = 0; i < pps->num_tile_columns; i++) {
+ pps->column_width[i] = ((i + 1) * sps->ctb_width) / pps->num_tile_columns -
+ (i * sps->ctb_width) / pps->num_tile_columns;
+ }
+
+ for (i = 0; i < pps->num_tile_rows; i++) {
+ pps->row_height[i] = ((i + 1) * sps->ctb_height) / pps->num_tile_rows -
+ (i * sps->ctb_height) / pps->num_tile_rows;
+ }
+ }
+
+ pps->col_bd[0] = 0;
+ for (i = 0; i < pps->num_tile_columns; i++)
+ pps->col_bd[i + 1] = pps->col_bd[i] + pps->column_width[i];
+
+ pps->row_bd[0] = 0;
+ for (i = 0; i < pps->num_tile_rows; i++)
+ pps->row_bd[i + 1] = pps->row_bd[i] + pps->row_height[i];
+
+ for (i = 0, j = 0; i < sps->ctb_width; i++) {
+ if (i > pps->col_bd[j])
+ j++;
+ pps->col_idxX[i] = j;
+ }
+
+ /**
+ * 6.5
+ */
+ pic_area_in_ctbs = sps->ctb_width * sps->ctb_height;
+
+ pps->ctb_addr_rs_to_ts = av_malloc_array(pic_area_in_ctbs, sizeof(*pps->ctb_addr_rs_to_ts));
+ pps->ctb_addr_ts_to_rs = av_malloc_array(pic_area_in_ctbs, sizeof(*pps->ctb_addr_ts_to_rs));
+ pps->tile_id = av_malloc_array(pic_area_in_ctbs, sizeof(*pps->tile_id));
+ pps->min_tb_addr_zs_tab = av_malloc_array((sps->tb_mask+2) * (sps->tb_mask+2), sizeof(*pps->min_tb_addr_zs_tab));
+ if (!pps->ctb_addr_rs_to_ts || !pps->ctb_addr_ts_to_rs ||
+ !pps->tile_id || !pps->min_tb_addr_zs_tab) {
+ return AVERROR(ENOMEM);
+ }
+
+ for (ctb_addr_rs = 0; ctb_addr_rs < pic_area_in_ctbs; ctb_addr_rs++) {
+ int tb_x = ctb_addr_rs % sps->ctb_width;
+ int tb_y = ctb_addr_rs / sps->ctb_width;
+ int tile_x = 0;
+ int tile_y = 0;
+ int val = 0;
+
+ for (i = 0; i < pps->num_tile_columns; i++) {
+ if (tb_x < pps->col_bd[i + 1]) {
+ tile_x = i;
+ break;
+ }
+ }
+
+ for (i = 0; i < pps->num_tile_rows; i++) {
+ if (tb_y < pps->row_bd[i + 1]) {
+ tile_y = i;
+ break;
+ }
+ }
+
+ for (i = 0; i < tile_x; i++)
+ val += pps->row_height[tile_y] * pps->column_width[i];
+ for (i = 0; i < tile_y; i++)
+ val += sps->ctb_width * pps->row_height[i];
+
+ val += (tb_y - pps->row_bd[tile_y]) * pps->column_width[tile_x] +
+ tb_x - pps->col_bd[tile_x];
+
+ pps->ctb_addr_rs_to_ts[ctb_addr_rs] = val;
+ pps->ctb_addr_ts_to_rs[val] = ctb_addr_rs;
+ }
+
+ for (j = 0, tile_id = 0; j < pps->num_tile_rows; j++)
+ for (i = 0; i < pps->num_tile_columns; i++, tile_id++)
+ for (y = pps->row_bd[j]; y < pps->row_bd[j + 1]; y++)
+ for (x = pps->col_bd[i]; x < pps->col_bd[i + 1]; x++)
+ pps->tile_id[pps->ctb_addr_rs_to_ts[y * sps->ctb_width + x]] = tile_id;
+
+ pps->tile_pos_rs = av_malloc_array(tile_id, sizeof(*pps->tile_pos_rs));
+ if (!pps->tile_pos_rs)
+ return AVERROR(ENOMEM);
+
+ for (j = 0; j < pps->num_tile_rows; j++)
+ for (i = 0; i < pps->num_tile_columns; i++)
+ pps->tile_pos_rs[j * pps->num_tile_columns + i] =
+ pps->row_bd[j] * sps->ctb_width + pps->col_bd[i];
+
+ log2_diff = sps->log2_ctb_size - sps->log2_min_tb_size;
+ pps->min_tb_addr_zs = &pps->min_tb_addr_zs_tab[1*(sps->tb_mask+2)+1];
+ for (y = 0; y < sps->tb_mask+2; y++) {
+ pps->min_tb_addr_zs_tab[y*(sps->tb_mask+2)] = -1;
+ pps->min_tb_addr_zs_tab[y] = -1;
+ }
+ for (y = 0; y < sps->tb_mask+1; y++) {
+ for (x = 0; x < sps->tb_mask+1; x++) {
+ int tb_x = x >> log2_diff;
+ int tb_y = y >> log2_diff;
+ int rs = sps->ctb_width * tb_y + tb_x;
+ int val = pps->ctb_addr_rs_to_ts[rs] << (log2_diff * 2);
+ for (i = 0; i < log2_diff; i++) {
+ int m = 1 << i;
+ val += (m & x ? m * m : 0) + (m & y ? 2 * m * m : 0);
+ }
+ pps->min_tb_addr_zs[y * (sps->tb_mask+2) + x] = val;
+ }
+ }
+
+ return 0;
+}
+
+int ff_hevc_decode_nal_pps(GetBitContext *gb, AVCodecContext *avctx,
+ HEVCParamSets *ps)
+{
+ HEVCSPS *sps = NULL;
+ int i, ret = 0;
+ unsigned int pps_id = 0;
+
+ AVBufferRef *pps_buf;
+ HEVCPPS *pps = av_mallocz(sizeof(*pps));
+
+ if (!pps)
+ return AVERROR(ENOMEM);
+
+ pps_buf = av_buffer_create((uint8_t *)pps, sizeof(*pps),
+ hevc_pps_free, NULL, 0);
+ if (!pps_buf) {
+ av_freep(&pps);
+ return AVERROR(ENOMEM);
+ }
+
+ av_log(avctx, AV_LOG_DEBUG, "Decoding PPS\n");
+
+ // Default values
+ pps->loop_filter_across_tiles_enabled_flag = 1;
+ pps->num_tile_columns = 1;
+ pps->num_tile_rows = 1;
+ pps->uniform_spacing_flag = 1;
+ pps->disable_dbf = 0;
+ pps->beta_offset = 0;
+ pps->tc_offset = 0;
+ pps->log2_max_transform_skip_block_size = 2;
+
+ // Coded parameters
+ pps_id = get_ue_golomb_long(gb);
+ if (pps_id >= MAX_PPS_COUNT) {
+ av_log(avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ pps->sps_id = get_ue_golomb_long(gb);
+ if (pps->sps_id >= MAX_SPS_COUNT) {
+ av_log(avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", pps->sps_id);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ if (!ps->sps_list[pps->sps_id]) {
+ av_log(avctx, AV_LOG_ERROR, "SPS %u does not exist.\n", pps->sps_id);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ sps = (HEVCSPS *)ps->sps_list[pps->sps_id]->data;
+
+ pps->dependent_slice_segments_enabled_flag = get_bits1(gb);
+ pps->output_flag_present_flag = get_bits1(gb);
+ pps->num_extra_slice_header_bits = get_bits(gb, 3);
+
+ pps->sign_data_hiding_flag = get_bits1(gb);
+
+ pps->cabac_init_present_flag = get_bits1(gb);
+
+ pps->num_ref_idx_l0_default_active = get_ue_golomb_long(gb) + 1;
+ pps->num_ref_idx_l1_default_active = get_ue_golomb_long(gb) + 1;
+
+ pps->pic_init_qp_minus26 = get_se_golomb(gb);
+
+ pps->constrained_intra_pred_flag = get_bits1(gb);
+ pps->transform_skip_enabled_flag = get_bits1(gb);
+
+ pps->cu_qp_delta_enabled_flag = get_bits1(gb);
+ pps->diff_cu_qp_delta_depth = 0;
+ if (pps->cu_qp_delta_enabled_flag)
+ pps->diff_cu_qp_delta_depth = get_ue_golomb_long(gb);
+
+ if (pps->diff_cu_qp_delta_depth < 0 ||
+ pps->diff_cu_qp_delta_depth > sps->log2_diff_max_min_coding_block_size) {
+ av_log(avctx, AV_LOG_ERROR, "diff_cu_qp_delta_depth %d is invalid\n",
+ pps->diff_cu_qp_delta_depth);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+
+ pps->cb_qp_offset = get_se_golomb(gb);
+ if (pps->cb_qp_offset < -12 || pps->cb_qp_offset > 12) {
+ av_log(avctx, AV_LOG_ERROR, "pps_cb_qp_offset out of range: %d\n",
+ pps->cb_qp_offset);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ pps->cr_qp_offset = get_se_golomb(gb);
+ if (pps->cr_qp_offset < -12 || pps->cr_qp_offset > 12) {
+ av_log(avctx, AV_LOG_ERROR, "pps_cr_qp_offset out of range: %d\n",
+ pps->cr_qp_offset);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ pps->pic_slice_level_chroma_qp_offsets_present_flag = get_bits1(gb);
+
+ pps->weighted_pred_flag = get_bits1(gb);
+ pps->weighted_bipred_flag = get_bits1(gb);
+
+ pps->transquant_bypass_enable_flag = get_bits1(gb);
+ pps->tiles_enabled_flag = get_bits1(gb);
+ pps->entropy_coding_sync_enabled_flag = get_bits1(gb);
+
+ if (pps->tiles_enabled_flag) {
+ pps->num_tile_columns = get_ue_golomb_long(gb) + 1;
+ pps->num_tile_rows = get_ue_golomb_long(gb) + 1;
+ if (pps->num_tile_columns <= 0 ||
+ pps->num_tile_columns >= sps->width) {
+ av_log(avctx, AV_LOG_ERROR, "num_tile_columns_minus1 out of range: %d\n",
+ pps->num_tile_columns - 1);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ if (pps->num_tile_rows <= 0 ||
+ pps->num_tile_rows >= sps->height) {
+ av_log(avctx, AV_LOG_ERROR, "num_tile_rows_minus1 out of range: %d\n",
+ pps->num_tile_rows - 1);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+
+ pps->column_width = av_malloc_array(pps->num_tile_columns, sizeof(*pps->column_width));
+ pps->row_height = av_malloc_array(pps->num_tile_rows, sizeof(*pps->row_height));
+ if (!pps->column_width || !pps->row_height) {
+ ret = AVERROR(ENOMEM);
+ goto err;
+ }
+
+ pps->uniform_spacing_flag = get_bits1(gb);
+ if (!pps->uniform_spacing_flag) {
+ uint64_t sum = 0;
+ for (i = 0; i < pps->num_tile_columns - 1; i++) {
+ pps->column_width[i] = get_ue_golomb_long(gb) + 1;
+ sum += pps->column_width[i];
+ }
+ if (sum >= sps->ctb_width) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid tile widths.\n");
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ pps->column_width[pps->num_tile_columns - 1] = sps->ctb_width - sum;
+
+ sum = 0;
+ for (i = 0; i < pps->num_tile_rows - 1; i++) {
+ pps->row_height[i] = get_ue_golomb_long(gb) + 1;
+ sum += pps->row_height[i];
+ }
+ if (sum >= sps->ctb_height) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid tile heights.\n");
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ pps->row_height[pps->num_tile_rows - 1] = sps->ctb_height - sum;
+ }
+ pps->loop_filter_across_tiles_enabled_flag = get_bits1(gb);
+ }
+
+ pps->seq_loop_filter_across_slices_enabled_flag = get_bits1(gb);
+
+ pps->deblocking_filter_control_present_flag = get_bits1(gb);
+ if (pps->deblocking_filter_control_present_flag) {
+ pps->deblocking_filter_override_enabled_flag = get_bits1(gb);
+ pps->disable_dbf = get_bits1(gb);
+ if (!pps->disable_dbf) {
+ pps->beta_offset = get_se_golomb(gb) * 2;
+ pps->tc_offset = get_se_golomb(gb) * 2;
+ if (pps->beta_offset/2 < -6 || pps->beta_offset/2 > 6) {
+ av_log(avctx, AV_LOG_ERROR, "pps_beta_offset_div2 out of range: %d\n",
+ pps->beta_offset/2);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ if (pps->tc_offset/2 < -6 || pps->tc_offset/2 > 6) {
+ av_log(avctx, AV_LOG_ERROR, "pps_tc_offset_div2 out of range: %d\n",
+ pps->tc_offset/2);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+ }
+ }
+
+ pps->scaling_list_data_present_flag = get_bits1(gb);
+ if (pps->scaling_list_data_present_flag) {
+ set_default_scaling_list_data(&pps->scaling_list);
+ ret = scaling_list_data(gb, avctx, &pps->scaling_list, sps);
+ if (ret < 0)
+ goto err;
+ }
+ pps->lists_modification_present_flag = get_bits1(gb);
+ pps->log2_parallel_merge_level = get_ue_golomb_long(gb) + 2;
+ if (pps->log2_parallel_merge_level > sps->log2_ctb_size) {
+ av_log(avctx, AV_LOG_ERROR, "log2_parallel_merge_level_minus2 out of range: %d\n",
+ pps->log2_parallel_merge_level - 2);
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+
+ pps->slice_header_extension_present_flag = get_bits1(gb);
+
+ if (get_bits1(gb)) { // pps_extension_present_flag
+ int pps_range_extensions_flag = get_bits1(gb);
+ /* int pps_extension_7bits = */ get_bits(gb, 7);
+ if (sps->ptl.general_ptl.profile_idc == FF_PROFILE_HEVC_REXT && pps_range_extensions_flag) {
+ if ((ret = pps_range_extensions(gb, avctx, pps, sps)) < 0)
+ goto err;
+ }
+ }
+
+ ret = setup_pps(avctx, gb, pps, sps);
+ if (ret < 0)
+ goto err;
+
+ if (get_bits_left(gb) < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Overread PPS by %d bits\n", -get_bits_left(gb));
+ goto err;
+ }
+
+ remove_pps(ps, pps_id);
+ ps->pps_list[pps_id] = pps_buf;
+
+ return 0;
+
+err:
+ av_buffer_unref(&pps_buf);
+ return ret;
+}
diff --git a/ffmpeg-2-8-11/libavcodec/hevc_ps_enc.c b/ffmpeg-2-8-12/libavcodec/hevc_ps_enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevc_ps_enc.c
rename to ffmpeg-2-8-12/libavcodec/hevc_ps_enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/hevc_refs.c b/ffmpeg-2-8-12/libavcodec/hevc_refs.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevc_refs.c
rename to ffmpeg-2-8-12/libavcodec/hevc_refs.c
diff --git a/ffmpeg-2-8-12/libavcodec/hevc_sei.c b/ffmpeg-2-8-12/libavcodec/hevc_sei.c
new file mode 100644
index 0000000..9eb41c3
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/hevc_sei.c
@@ -0,0 +1,266 @@
+/*
+ * HEVC Supplementary Enhancement Information messages
+ *
+ * Copyright (C) 2012 - 2013 Guillaume Martres
+ * Copyright (C) 2012 - 2013 Gildas Cocherel
+ * Copyright (C) 2013 Vittorio Giovara
+ *
+ * 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 "golomb.h"
+#include "hevc.h"
+
+enum HEVC_SEI_TYPE {
+ SEI_TYPE_BUFFERING_PERIOD = 0,
+ SEI_TYPE_PICTURE_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_SCENE_INFO = 9,
+ SEI_TYPE_FULL_FRAME_SNAPSHOT = 15,
+ SEI_TYPE_PROGRESSIVE_REFINEMENT_SEGMENT_START = 16,
+ SEI_TYPE_PROGRESSIVE_REFINEMENT_SEGMENT_END = 17,
+ SEI_TYPE_FILM_GRAIN_CHARACTERISTICS = 19,
+ SEI_TYPE_POST_FILTER_HINT = 22,
+ SEI_TYPE_TONE_MAPPING_INFO = 23,
+ SEI_TYPE_FRAME_PACKING = 45,
+ SEI_TYPE_DISPLAY_ORIENTATION = 47,
+ SEI_TYPE_SOP_DESCRIPTION = 128,
+ SEI_TYPE_ACTIVE_PARAMETER_SETS = 129,
+ SEI_TYPE_DECODING_UNIT_INFO = 130,
+ SEI_TYPE_TEMPORAL_LEVEL0_INDEX = 131,
+ SEI_TYPE_DECODED_PICTURE_HASH = 132,
+ SEI_TYPE_SCALABLE_NESTING = 133,
+ SEI_TYPE_REGION_REFRESH_INFO = 134,
+ SEI_TYPE_MASTERING_DISPLAY_INFO = 137,
+ SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO = 144,
+};
+
+static int decode_nal_sei_decoded_picture_hash(HEVCContext *s)
+{
+ int cIdx, i;
+ uint8_t hash_type;
+ //uint16_t picture_crc;
+ //uint32_t picture_checksum;
+ GetBitContext *gb = &s->HEVClc->gb;
+ hash_type = get_bits(gb, 8);
+
+ for (cIdx = 0; cIdx < 3/*((s->sps->chroma_format_idc == 0) ? 1 : 3)*/; cIdx++) {
+ if (hash_type == 0) {
+ s->is_md5 = 1;
+ for (i = 0; i < 16; i++)
+ s->md5[cIdx][i] = get_bits(gb, 8);
+ } else if (hash_type == 1) {
+ // picture_crc = get_bits(gb, 16);
+ skip_bits(gb, 16);
+ } else if (hash_type == 2) {
+ // picture_checksum = get_bits_long(gb, 32);
+ skip_bits(gb, 32);
+ }
+ }
+ return 0;
+}
+
+static int decode_nal_sei_frame_packing_arrangement(HEVCContext *s)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+
+ get_ue_golomb(gb); // frame_packing_arrangement_id
+ s->sei_frame_packing_present = !get_bits1(gb);
+
+ if (s->sei_frame_packing_present) {
+ s->frame_packing_arrangement_type = get_bits(gb, 7);
+ s->quincunx_subsampling = get_bits1(gb);
+ s->content_interpretation_type = get_bits(gb, 6);
+
+ // the following skips spatial_flipping_flag frame0_flipped_flag
+ // field_views_flag current_frame_is_frame0_flag
+ // frame0_self_contained_flag frame1_self_contained_flag
+ skip_bits(gb, 6);
+
+ if (!s->quincunx_subsampling && s->frame_packing_arrangement_type != 5)
+ skip_bits(gb, 16); // frame[01]_grid_position_[xy]
+ skip_bits(gb, 8); // frame_packing_arrangement_reserved_byte
+ skip_bits1(gb); // frame_packing_arrangement_persistance_flag
+ }
+ skip_bits1(gb); // upsampled_aspect_ratio_flag
+ return 0;
+}
+
+static int decode_nal_sei_display_orientation(HEVCContext *s)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+
+ s->sei_display_orientation_present = !get_bits1(gb);
+
+ if (s->sei_display_orientation_present) {
+ s->sei_hflip = get_bits1(gb); // hor_flip
+ s->sei_vflip = get_bits1(gb); // ver_flip
+
+ s->sei_anticlockwise_rotation = get_bits(gb, 16);
+ skip_bits1(gb); // display_orientation_persistence_flag
+ }
+
+ return 0;
+}
+
+static int decode_pic_timing(HEVCContext *s, int size)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+ HEVCSPS *sps;
+
+ if (!s->ps.sps_list[s->active_seq_parameter_set_id])
+ return(AVERROR(ENOMEM));
+ sps = (HEVCSPS*)s->ps.sps_list[s->active_seq_parameter_set_id]->data;
+
+ if (sps->vui.frame_field_info_present_flag) {
+ int pic_struct = get_bits(gb, 4);
+ s->picture_struct = AV_PICTURE_STRUCTURE_UNKNOWN;
+ if (pic_struct == 2) {
+ av_log(s->avctx, AV_LOG_DEBUG, "BOTTOM Field\n");
+ s->picture_struct = AV_PICTURE_STRUCTURE_BOTTOM_FIELD;
+ } else if (pic_struct == 1) {
+ av_log(s->avctx, AV_LOG_DEBUG, "TOP Field\n");
+ s->picture_struct = AV_PICTURE_STRUCTURE_TOP_FIELD;
+ }
+ get_bits(gb, 2); // source_scan_type
+ get_bits(gb, 1); // duplicate_flag
+ skip_bits1(gb);
+ size--;
+ }
+ skip_bits_long(gb, 8 * size);
+
+ return 0;
+}
+
+static int active_parameter_sets(HEVCContext *s)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+ int num_sps_ids_minus1;
+ int i;
+ unsigned active_seq_parameter_set_id;
+
+ get_bits(gb, 4); // active_video_parameter_set_id
+ get_bits(gb, 1); // self_contained_cvs_flag
+ get_bits(gb, 1); // num_sps_ids_minus1
+ num_sps_ids_minus1 = get_ue_golomb_long(gb); // num_sps_ids_minus1
+
+ if (num_sps_ids_minus1 < 0 || num_sps_ids_minus1 > 15) {
+ av_log(s->avctx, AV_LOG_ERROR, "num_sps_ids_minus1 %d invalid\n", num_sps_ids_minus1);
+ return AVERROR_INVALIDDATA;
+ }
+
+ active_seq_parameter_set_id = get_ue_golomb_long(gb);
+ if (active_seq_parameter_set_id >= MAX_SPS_COUNT) {
+ av_log(s->avctx, AV_LOG_ERROR, "active_parameter_set_id %d invalid\n", active_seq_parameter_set_id);
+ return AVERROR_INVALIDDATA;
+ }
+ s->active_seq_parameter_set_id = active_seq_parameter_set_id;
+
+ for (i = 1; i <= num_sps_ids_minus1; i++)
+ get_ue_golomb_long(gb); // active_seq_parameter_set_id[i]
+
+ return 0;
+}
+
+static int decode_nal_sei_prefix(HEVCContext *s, int type, int size)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+
+ switch (type) {
+ case 256: // Mismatched value from HM 8.1
+ return decode_nal_sei_decoded_picture_hash(s);
+ case SEI_TYPE_FRAME_PACKING:
+ return decode_nal_sei_frame_packing_arrangement(s);
+ case SEI_TYPE_DISPLAY_ORIENTATION:
+ return decode_nal_sei_display_orientation(s);
+ case SEI_TYPE_PICTURE_TIMING:
+ {
+ int ret = decode_pic_timing(s, size);
+ av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
+ return ret;
+ }
+ case SEI_TYPE_ACTIVE_PARAMETER_SETS:
+ active_parameter_sets(s);
+ av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
+ return 0;
+ default:
+ av_log(s->avctx, AV_LOG_DEBUG, "Skipped PREFIX SEI %d\n", type);
+ skip_bits_long(gb, 8 * size);
+ return 0;
+ }
+}
+
+static int decode_nal_sei_suffix(HEVCContext *s, int type, int size)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+
+ switch (type) {
+ case SEI_TYPE_DECODED_PICTURE_HASH:
+ return decode_nal_sei_decoded_picture_hash(s);
+ default:
+ av_log(s->avctx, AV_LOG_DEBUG, "Skipped SUFFIX SEI %d\n", type);
+ skip_bits_long(gb, 8 * size);
+ return 0;
+ }
+}
+
+static int decode_nal_sei_message(HEVCContext *s)
+{
+ GetBitContext *gb = &s->HEVClc->gb;
+
+ int payload_type = 0;
+ int payload_size = 0;
+ int byte = 0xFF;
+ av_log(s->avctx, AV_LOG_DEBUG, "Decoding SEI\n");
+
+ while (byte == 0xFF) {
+ byte = get_bits(gb, 8);
+ payload_type += byte;
+ }
+ byte = 0xFF;
+ while (byte == 0xFF) {
+ byte = get_bits(gb, 8);
+ payload_size += byte;
+ }
+ if (s->nal_unit_type == NAL_SEI_PREFIX) {
+ return decode_nal_sei_prefix(s, payload_type, payload_size);
+ } else { /* nal_unit_type == NAL_SEI_SUFFIX */
+ return decode_nal_sei_suffix(s, payload_type, payload_size);
+ }
+ return 1;
+}
+
+static int more_rbsp_data(GetBitContext *gb)
+{
+ return get_bits_left(gb) > 0 && show_bits(gb, 8) != 0x80;
+}
+
+int ff_hevc_decode_nal_sei(HEVCContext *s)
+{
+ int ret;
+
+ do {
+ ret = decode_nal_sei_message(s);
+ if (ret < 0)
+ return(AVERROR(ENOMEM));
+ } while (more_rbsp_data(&s->HEVClc->gb));
+ return 1;
+}
diff --git a/ffmpeg-2-8-11/libavcodec/hevcdsp.c b/ffmpeg-2-8-12/libavcodec/hevcdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevcdsp.c
rename to ffmpeg-2-8-12/libavcodec/hevcdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/hevcdsp.h b/ffmpeg-2-8-12/libavcodec/hevcdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevcdsp.h
rename to ffmpeg-2-8-12/libavcodec/hevcdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/hevcdsp_template.c b/ffmpeg-2-8-12/libavcodec/hevcdsp_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevcdsp_template.c
rename to ffmpeg-2-8-12/libavcodec/hevcdsp_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/hevcpred.c b/ffmpeg-2-8-12/libavcodec/hevcpred.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevcpred.c
rename to ffmpeg-2-8-12/libavcodec/hevcpred.c
diff --git a/ffmpeg-2-8-11/libavcodec/hevcpred.h b/ffmpeg-2-8-12/libavcodec/hevcpred.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevcpred.h
rename to ffmpeg-2-8-12/libavcodec/hevcpred.h
diff --git a/ffmpeg-2-8-11/libavcodec/hevcpred_template.c b/ffmpeg-2-8-12/libavcodec/hevcpred_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hevcpred_template.c
rename to ffmpeg-2-8-12/libavcodec/hevcpred_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/hnm4video.c b/ffmpeg-2-8-12/libavcodec/hnm4video.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hnm4video.c
rename to ffmpeg-2-8-12/libavcodec/hnm4video.c
diff --git a/ffmpeg-2-8-11/libavcodec/hpel_template.c b/ffmpeg-2-8-12/libavcodec/hpel_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hpel_template.c
rename to ffmpeg-2-8-12/libavcodec/hpel_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/hpeldsp.c b/ffmpeg-2-8-12/libavcodec/hpeldsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hpeldsp.c
rename to ffmpeg-2-8-12/libavcodec/hpeldsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/hpeldsp.h b/ffmpeg-2-8-12/libavcodec/hpeldsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hpeldsp.h
rename to ffmpeg-2-8-12/libavcodec/hpeldsp.h
diff --git a/ffmpeg-2-8-12/libavcodec/hq_hqa.c b/ffmpeg-2-8-12/libavcodec/hq_hqa.c
new file mode 100644
index 0000000..d184647
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/hq_hqa.c
@@ -0,0 +1,387 @@
+/*
+ * Canopus HQ/HQA 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 <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/intreadwrite.h"
+
+#include "avcodec.h"
+#include "canopus.h"
+#include "internal.h"
+
+#include "hq_hqa.h"
+#include "hq_hqadsp.h"
+
+/* HQ/HQA slices are a set of macroblocks belonging to a frame, and
+ * they usually form a pseudorandom pattern (probably because it is
+ * nicer to display on partial decode).
+ *
+ * For HQA it just happens that each slice is on every 8th macroblock,
+ * but they can be on any frame width like
+ * X.......X.
+ * ......X...
+ * ....X.....
+ * ..X.......
+ * etc.
+ *
+ * The original decoder has special handling for edge macroblocks,
+ * while lavc simply aligns coded_width and coded_height.
+ */
+
+static inline void put_blocks(HQContext *c, AVFrame *pic,
+ int plane, int x, int y, int ilace,
+ int16_t *block0, int16_t *block1)
+{
+ uint8_t *p = pic->data[plane] + x;
+
+ c->hqhqadsp.idct_put(p + y * pic->linesize[plane],
+ pic->linesize[plane] << ilace, block0);
+ c->hqhqadsp.idct_put(p + (y + (ilace ? 1 : 8)) * pic->linesize[plane],
+ pic->linesize[plane] << ilace, block1);
+}
+
+static int hq_decode_block(HQContext *c, GetBitContext *gb, int16_t block[64],
+ int qsel, int is_chroma, int is_hqa)
+{
+ const int32_t *q;
+ int val, pos = 1;
+
+ memset(block, 0, 64 * sizeof(*block));
+
+ if (!is_hqa) {
+ block[0] = get_sbits(gb, 9) * 64;
+ q = ff_hq_quants[qsel][is_chroma][get_bits(gb, 2)];
+ } else {
+ q = ff_hq_quants[qsel][is_chroma][get_bits(gb, 2)];
+ block[0] = get_sbits(gb, 9) * 64;
+ }
+
+ for (;;) {
+ val = get_vlc2(gb, c->hq_ac_vlc.table, 9, 2);
+ if (val < 0)
+ return AVERROR_INVALIDDATA;
+
+ pos += ff_hq_ac_skips[val];
+ if (pos >= 64)
+ break;
+ block[ff_zigzag_direct[pos]] = (int)(ff_hq_ac_syms[val] * (unsigned)q[pos]) >> 12;
+ pos++;
+ }
+
+ return 0;
+}
+
+static int hq_decode_mb(HQContext *c, AVFrame *pic,
+ GetBitContext *gb, int x, int y)
+{
+ int qgroup, flag;
+ int i, ret;
+
+ qgroup = get_bits(gb, 4);
+ flag = get_bits1(gb);
+
+ for (i = 0; i < 8; i++) {
+ ret = hq_decode_block(c, gb, c->block[i], qgroup, i >= 4, 0);
+ if (ret < 0)
+ return ret;
+ }
+
+ put_blocks(c, pic, 0, x, y, flag, c->block[0], c->block[2]);
+ put_blocks(c, pic, 0, x + 8, y, flag, c->block[1], c->block[3]);
+ put_blocks(c, pic, 2, x >> 1, y, flag, c->block[4], c->block[5]);
+ put_blocks(c, pic, 1, x >> 1, y, flag, c->block[6], c->block[7]);
+
+ return 0;
+}
+
+static int hq_decode_frame(HQContext *ctx, AVFrame *pic,
+ int prof_num, size_t data_size)
+{
+ const HQProfile *profile;
+ GetBitContext gb;
+ const uint8_t *perm, *src = ctx->gbc.buffer;
+ uint32_t slice_off[21];
+ int slice, start_off, next_off, i, ret;
+
+ if ((unsigned)prof_num >= NUM_HQ_PROFILES) {
+ profile = &ff_hq_profile[0];
+ avpriv_request_sample(ctx->avctx, "HQ Profile %d", prof_num);
+ } else {
+ profile = &ff_hq_profile[prof_num];
+ av_log(ctx->avctx, AV_LOG_VERBOSE, "HQ Profile %d\n", prof_num);
+ }
+
+ ctx->avctx->coded_width = FFALIGN(profile->width, 16);
+ ctx->avctx->coded_height = FFALIGN(profile->height, 16);
+ ctx->avctx->width = profile->width;
+ ctx->avctx->height = profile->height;
+ ctx->avctx->bits_per_raw_sample = 8;
+ ctx->avctx->pix_fmt = AV_PIX_FMT_YUV422P;
+
+ ret = ff_get_buffer(ctx->avctx, pic, 0);
+ if (ret < 0)
+ return ret;
+
+ /* Offsets are stored from CUV position, so adjust them accordingly. */
+ for (i = 0; i < profile->num_slices + 1; i++)
+ slice_off[i] = bytestream2_get_be24(&ctx->gbc) - 4;
+
+ next_off = 0;
+ for (slice = 0; slice < profile->num_slices; slice++) {
+ start_off = next_off;
+ next_off = profile->tab_h * (slice + 1) / profile->num_slices;
+ perm = profile->perm_tab + start_off * profile->tab_w * 2;
+
+ if (slice_off[slice] < (profile->num_slices + 1) * 3 ||
+ slice_off[slice] >= slice_off[slice + 1] ||
+ slice_off[slice + 1] > data_size) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Invalid slice size %zu.\n", data_size);
+ break;
+ }
+ init_get_bits(&gb, src + slice_off[slice],
+ (slice_off[slice + 1] - slice_off[slice]) * 8);
+
+ for (i = 0; i < (next_off - start_off) * profile->tab_w; i++) {
+ ret = hq_decode_mb(ctx, pic, &gb, perm[0] * 16, perm[1] * 16);
+ if (ret < 0) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Error decoding macroblock %d at slice %d.\n", i, slice);
+ return ret;
+ }
+ perm += 2;
+ }
+ }
+
+ return 0;
+}
+
+static int hqa_decode_mb(HQContext *c, AVFrame *pic, int qgroup,
+ GetBitContext *gb, int x, int y)
+{
+ int flag = 0;
+ int i, ret, cbp;
+
+ cbp = get_vlc2(gb, c->hqa_cbp_vlc.table, 5, 1);
+
+ for (i = 0; i < 12; i++)
+ memset(c->block[i], 0, sizeof(*c->block));
+ for (i = 0; i < 12; i++)
+ c->block[i][0] = -128 * (1 << 6);
+
+ if (cbp) {
+ flag = get_bits1(gb);
+
+ cbp |= cbp << 4;
+ if (cbp & 0x3)
+ cbp |= 0x500;
+ if (cbp & 0xC)
+ cbp |= 0xA00;
+ for (i = 0; i < 12; i++) {
+ if (!(cbp & (1 << i)))
+ continue;
+ ret = hq_decode_block(c, gb, c->block[i], qgroup, i >= 8, 1);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ put_blocks(c, pic, 3, x, y, flag, c->block[ 0], c->block[ 2]);
+ put_blocks(c, pic, 3, x + 8, y, flag, c->block[ 1], c->block[ 3]);
+ put_blocks(c, pic, 0, x, y, flag, c->block[ 4], c->block[ 6]);
+ put_blocks(c, pic, 0, x + 8, y, flag, c->block[ 5], c->block[ 7]);
+ put_blocks(c, pic, 2, x >> 1, y, flag, c->block[ 8], c->block[ 9]);
+ put_blocks(c, pic, 1, x >> 1, y, flag, c->block[10], c->block[11]);
+
+ return 0;
+}
+
+static int hqa_decode_slice(HQContext *ctx, AVFrame *pic, GetBitContext *gb,
+ int quant, int slice_no, int w, int h)
+{
+ int i, j, off;
+ int ret;
+
+ for (i = 0; i < h; i += 16) {
+ off = (slice_no * 16 + i * 3) & 0x70;
+ for (j = off; j < w; j += 128) {
+ ret = hqa_decode_mb(ctx, pic, quant, gb, j, i);
+ if (ret < 0) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Error decoding macroblock at %dx%d.\n", i, j);
+ return ret;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int hqa_decode_frame(HQContext *ctx, AVFrame *pic, size_t data_size)
+{
+ GetBitContext gb;
+ const int num_slices = 8;
+ uint32_t slice_off[9];
+ int i, slice, ret;
+ int width, height, quant;
+ const uint8_t *src = ctx->gbc.buffer;
+
+ width = bytestream2_get_be16(&ctx->gbc);
+ height = bytestream2_get_be16(&ctx->gbc);
+
+ ctx->avctx->coded_width = FFALIGN(width, 16);
+ ctx->avctx->coded_height = FFALIGN(height, 16);
+ ctx->avctx->width = width;
+ ctx->avctx->height = height;
+ ctx->avctx->bits_per_raw_sample = 8;
+ ctx->avctx->pix_fmt = AV_PIX_FMT_YUVA422P;
+
+ av_log(ctx->avctx, AV_LOG_VERBOSE, "HQA Profile\n");
+
+ quant = bytestream2_get_byte(&ctx->gbc);
+ bytestream2_skip(&ctx->gbc, 3);
+ if (quant >= NUM_HQ_QUANTS) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Invalid quantization matrix %d.\n", quant);
+ return AVERROR_INVALIDDATA;
+ }
+
+ ret = ff_get_buffer(ctx->avctx, pic, 0);
+ if (ret < 0)
+ return ret;
+
+ /* Offsets are stored from HQA1 position, so adjust them accordingly. */
+ for (i = 0; i < num_slices + 1; i++)
+ slice_off[i] = bytestream2_get_be32(&ctx->gbc) - 4;
+
+ for (slice = 0; slice < num_slices; slice++) {
+ if (slice_off[slice] < (num_slices + 1) * 3 ||
+ slice_off[slice] >= slice_off[slice + 1] ||
+ slice_off[slice + 1] > data_size) {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Invalid slice size %zu.\n", data_size);
+ break;
+ }
+ init_get_bits(&gb, src + slice_off[slice],
+ (slice_off[slice + 1] - slice_off[slice]) * 8);
+
+ ret = hqa_decode_slice(ctx, pic, &gb, quant, slice, width, height);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int hq_hqa_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame, AVPacket *avpkt)
+{
+ HQContext *ctx = avctx->priv_data;
+ AVFrame *pic = data;
+ uint32_t info_tag;
+ unsigned int data_size;
+ int ret;
+ unsigned tag;
+
+ bytestream2_init(&ctx->gbc, avpkt->data, avpkt->size);
+ if (bytestream2_get_bytes_left(&ctx->gbc) < 4 + 4) {
+ av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", avpkt->size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ info_tag = bytestream2_peek_le32(&ctx->gbc);
+ if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
+ int info_size;
+ bytestream2_skip(&ctx->gbc, 4);
+ info_size = bytestream2_get_le32(&ctx->gbc);
+ if (bytestream2_get_bytes_left(&ctx->gbc) < info_size) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid INFO size (%d).\n", info_size);
+ return AVERROR_INVALIDDATA;
+ }
+ ff_canopus_parse_info_tag(avctx, ctx->gbc.buffer, info_size);
+
+ bytestream2_skip(&ctx->gbc, info_size);
+ }
+
+ data_size = bytestream2_get_bytes_left(&ctx->gbc);
+ if (data_size < 4) {
+ av_log(avctx, AV_LOG_ERROR, "Frame is too small (%d).\n", data_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* HQ defines dimensions and number of slices, and thus slice traversal
+ * order. HQA has no size constraint and a fixed number of slices, so it
+ * needs a separate scheme for it. */
+ tag = bytestream2_get_le32(&ctx->gbc);
+ if ((tag & 0x00FFFFFF) == (MKTAG('U', 'V', 'C', ' ') & 0x00FFFFFF)) {
+ ret = hq_decode_frame(ctx, pic, tag >> 24, data_size);
+ } else if (tag == MKTAG('H', 'Q', 'A', '1')) {
+ ret = hqa_decode_frame(ctx, pic, data_size);
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "Not a HQ/HQA frame.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error decoding frame.\n");
+ return ret;
+ }
+
+ pic->key_frame = 1;
+ pic->pict_type = AV_PICTURE_TYPE_I;
+
+ *got_frame = 1;
+
+ return avpkt->size;
+}
+
+static av_cold int hq_hqa_decode_init(AVCodecContext *avctx)
+{
+ HQContext *ctx = avctx->priv_data;
+ ctx->avctx = avctx;
+
+ ff_hqdsp_init(&ctx->hqhqadsp);
+
+ return ff_hq_init_vlcs(ctx);
+}
+
+static av_cold int hq_hqa_decode_close(AVCodecContext *avctx)
+{
+ HQContext *ctx = avctx->priv_data;
+
+ ff_free_vlc(&ctx->hq_ac_vlc);
+ ff_free_vlc(&ctx->hqa_cbp_vlc);
+
+ return 0;
+}
+
+AVCodec ff_hq_hqa_decoder = {
+ .name = "hq_hqa",
+ .long_name = NULL_IF_CONFIG_SMALL("Canopus HQ/HQA"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_HQ_HQA,
+ .priv_data_size = sizeof(HQContext),
+ .init = hq_hqa_decode_init,
+ .decode = hq_hqa_decode_frame,
+ .close = hq_hqa_decode_close,
+ .capabilities = AV_CODEC_CAP_DR1,
+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
+ FF_CODEC_CAP_INIT_CLEANUP,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/hq_hqa.h b/ffmpeg-2-8-12/libavcodec/hq_hqa.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hq_hqa.h
rename to ffmpeg-2-8-12/libavcodec/hq_hqa.h
diff --git a/ffmpeg-2-8-11/libavcodec/hq_hqadata.c b/ffmpeg-2-8-12/libavcodec/hq_hqadata.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hq_hqadata.c
rename to ffmpeg-2-8-12/libavcodec/hq_hqadata.c
diff --git a/ffmpeg-2-8-11/libavcodec/hq_hqadsp.c b/ffmpeg-2-8-12/libavcodec/hq_hqadsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hq_hqadsp.c
rename to ffmpeg-2-8-12/libavcodec/hq_hqadsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/hq_hqadsp.h b/ffmpeg-2-8-12/libavcodec/hq_hqadsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hq_hqadsp.h
rename to ffmpeg-2-8-12/libavcodec/hq_hqadsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/hqx.c b/ffmpeg-2-8-12/libavcodec/hqx.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hqx.c
rename to ffmpeg-2-8-12/libavcodec/hqx.c
diff --git a/ffmpeg-2-8-11/libavcodec/hqx.h b/ffmpeg-2-8-12/libavcodec/hqx.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hqx.h
rename to ffmpeg-2-8-12/libavcodec/hqx.h
diff --git a/ffmpeg-2-8-12/libavcodec/hqxdsp.c b/ffmpeg-2-8-12/libavcodec/hqxdsp.c
new file mode 100644
index 0000000..7f8044e
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/hqxdsp.c
@@ -0,0 +1,131 @@
+/*
+ * HQX DSP routines
+ *
+ * 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 <stdint.h>
+
+#include "libavutil/common.h"
+
+#include "hqxdsp.h"
+
+static inline void idct_col(int16_t *blk, const uint8_t *quant)
+{
+ int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, tA, tB, tC, tD, tE, tF;
+ int t10, t11, t12, t13;
+ int s0, s1, s2, s3, s4, s5, s6, s7;
+
+ s0 = (int) blk[0 * 8] * quant[0 * 8];
+ s1 = (int) blk[1 * 8] * quant[1 * 8];
+ s2 = (int) blk[2 * 8] * quant[2 * 8];
+ s3 = (int) blk[3 * 8] * quant[3 * 8];
+ s4 = (int) blk[4 * 8] * quant[4 * 8];
+ s5 = (int) blk[5 * 8] * quant[5 * 8];
+ s6 = (int) blk[6 * 8] * quant[6 * 8];
+ s7 = (int) blk[7 * 8] * quant[7 * 8];
+
+ t0 = (int)(s3 * 19266U + s5 * 12873U) >> 15;
+ t1 = (int)(s5 * 19266U - s3 * 12873U) >> 15;
+ t2 = ((int)(s7 * 4520U + s1 * 22725U) >> 15) - t0;
+ t3 = ((int)(s1 * 4520U - s7 * 22725U) >> 15) - t1;
+ t4 = t0 * 2 + t2;
+ t5 = t1 * 2 + t3;
+ t6 = t2 - t3;
+ t7 = t3 * 2 + t6;
+ t8 = (int)(t6 * 11585U) >> 14;
+ t9 = (int)(t7 * 11585U) >> 14;
+ tA = (int)(s2 * 8867U - s6 * 21407U) >> 14;
+ tB = (int)(s6 * 8867U + s2 * 21407U) >> 14;
+ tC = (s0 >> 1) - (s4 >> 1);
+ tD = (s4 >> 1) * 2 + tC;
+ tE = tC - (tA >> 1);
+ tF = tD - (tB >> 1);
+ t10 = tF - t5;
+ t11 = tE - t8;
+ t12 = tE + (tA >> 1) * 2 - t9;
+ t13 = tF + (tB >> 1) * 2 - t4;
+
+ blk[0 * 8] = t13 + t4 * 2;
+ blk[1 * 8] = t12 + t9 * 2;
+ blk[2 * 8] = t11 + t8 * 2;
+ blk[3 * 8] = t10 + t5 * 2;
+ blk[4 * 8] = t10;
+ blk[5 * 8] = t11;
+ blk[6 * 8] = t12;
+ blk[7 * 8] = t13;
+}
+
+static inline void idct_row(int16_t *blk)
+{
+ int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9, tA, tB, tC, tD, tE, tF;
+ int t10, t11, t12, t13;
+
+ t0 = (blk[3] * 19266 + blk[5] * 12873) >> 14;
+ t1 = (blk[5] * 19266 - blk[3] * 12873) >> 14;
+ t2 = ((blk[7] * 4520 + blk[1] * 22725) >> 14) - t0;
+ t3 = ((blk[1] * 4520 - blk[7] * 22725) >> 14) - t1;
+ t4 = t0 * 2 + t2;
+ t5 = t1 * 2 + t3;
+ t6 = t2 - t3;
+ t7 = t3 * 2 + t6;
+ t8 = (t6 * 11585) >> 14;
+ t9 = (t7 * 11585) >> 14;
+ tA = (blk[2] * 8867 - blk[6] * 21407) >> 14;
+ tB = (blk[6] * 8867 + blk[2] * 21407) >> 14;
+ tC = blk[0] - blk[4];
+ tD = blk[4] * 2 + tC;
+ tE = tC - tA;
+ tF = tD - tB;
+ t10 = tF - t5;
+ t11 = tE - t8;
+ t12 = tE + tA * 2 - t9;
+ t13 = tF + tB * 2 - t4;
+
+ blk[0] = (t13 + t4 * 2 + 4) >> 3;
+ blk[1] = (t12 + t9 * 2 + 4) >> 3;
+ blk[2] = (t11 + t8 * 2 + 4) >> 3;
+ blk[3] = (t10 + t5 * 2 + 4) >> 3;
+ blk[4] = (t10 + 4) >> 3;
+ blk[5] = (t11 + 4) >> 3;
+ blk[6] = (t12 + 4) >> 3;
+ blk[7] = (t13 + 4) >> 3;
+}
+
+static void hqx_idct_put(uint16_t *dst, ptrdiff_t stride,
+ int16_t *block, const uint8_t *quant)
+{
+ int i, j;
+
+ for (i = 0; i < 8; i++)
+ idct_col(block + i, quant + i);
+ for (i = 0; i < 8; i++)
+ idct_row(block + i * 8);
+
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < 8; j++) {
+ int v = av_clip_uintp2(block[j + i * 8] + 0x800, 12);
+ dst[j] = (v << 4) | (v >> 8);
+ }
+ dst += stride >> 1;
+ }
+}
+
+av_cold void ff_hqxdsp_init(HQXDSPContext *c)
+{
+ c->idct_put = hqx_idct_put;
+}
diff --git a/ffmpeg-2-8-11/libavcodec/hqxdsp.h b/ffmpeg-2-8-12/libavcodec/hqxdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hqxdsp.h
rename to ffmpeg-2-8-12/libavcodec/hqxdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/hqxvlc.c b/ffmpeg-2-8-12/libavcodec/hqxvlc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/hqxvlc.c
rename to ffmpeg-2-8-12/libavcodec/hqxvlc.c
diff --git a/ffmpeg-2-8-11/libavcodec/huffman.c b/ffmpeg-2-8-12/libavcodec/huffman.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/huffman.c
rename to ffmpeg-2-8-12/libavcodec/huffman.c
diff --git a/ffmpeg-2-8-11/libavcodec/huffman.h b/ffmpeg-2-8-12/libavcodec/huffman.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/huffman.h
rename to ffmpeg-2-8-12/libavcodec/huffman.h
diff --git a/ffmpeg-2-8-11/libavcodec/huffyuv.c b/ffmpeg-2-8-12/libavcodec/huffyuv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/huffyuv.c
rename to ffmpeg-2-8-12/libavcodec/huffyuv.c
diff --git a/ffmpeg-2-8-11/libavcodec/huffyuv.h b/ffmpeg-2-8-12/libavcodec/huffyuv.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/huffyuv.h
rename to ffmpeg-2-8-12/libavcodec/huffyuv.h
diff --git a/ffmpeg-2-8-11/libavcodec/huffyuvdec.c b/ffmpeg-2-8-12/libavcodec/huffyuvdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/huffyuvdec.c
rename to ffmpeg-2-8-12/libavcodec/huffyuvdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/huffyuvdsp.c b/ffmpeg-2-8-12/libavcodec/huffyuvdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/huffyuvdsp.c
rename to ffmpeg-2-8-12/libavcodec/huffyuvdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/huffyuvdsp.h b/ffmpeg-2-8-12/libavcodec/huffyuvdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/huffyuvdsp.h
rename to ffmpeg-2-8-12/libavcodec/huffyuvdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/huffyuvenc.c b/ffmpeg-2-8-12/libavcodec/huffyuvenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/huffyuvenc.c
rename to ffmpeg-2-8-12/libavcodec/huffyuvenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/huffyuvencdsp.c b/ffmpeg-2-8-12/libavcodec/huffyuvencdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/huffyuvencdsp.c
rename to ffmpeg-2-8-12/libavcodec/huffyuvencdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/huffyuvencdsp.h b/ffmpeg-2-8-12/libavcodec/huffyuvencdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/huffyuvencdsp.h
rename to ffmpeg-2-8-12/libavcodec/huffyuvencdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/idcinvideo.c b/ffmpeg-2-8-12/libavcodec/idcinvideo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/idcinvideo.c
rename to ffmpeg-2-8-12/libavcodec/idcinvideo.c
diff --git a/ffmpeg-2-8-11/libavcodec/idctdsp.c b/ffmpeg-2-8-12/libavcodec/idctdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/idctdsp.c
rename to ffmpeg-2-8-12/libavcodec/idctdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/idctdsp.h b/ffmpeg-2-8-12/libavcodec/idctdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/idctdsp.h
rename to ffmpeg-2-8-12/libavcodec/idctdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/iff.c b/ffmpeg-2-8-12/libavcodec/iff.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/iff.c
rename to ffmpeg-2-8-12/libavcodec/iff.c
diff --git a/ffmpeg-2-8-11/libavcodec/iirfilter.c b/ffmpeg-2-8-12/libavcodec/iirfilter.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/iirfilter.c
rename to ffmpeg-2-8-12/libavcodec/iirfilter.c
diff --git a/ffmpeg-2-8-11/libavcodec/iirfilter.h b/ffmpeg-2-8-12/libavcodec/iirfilter.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/iirfilter.h
rename to ffmpeg-2-8-12/libavcodec/iirfilter.h
diff --git a/ffmpeg-2-8-11/libavcodec/imc.c b/ffmpeg-2-8-12/libavcodec/imc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/imc.c
rename to ffmpeg-2-8-12/libavcodec/imc.c
diff --git a/ffmpeg-2-8-11/libavcodec/imcdata.h b/ffmpeg-2-8-12/libavcodec/imcdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/imcdata.h
rename to ffmpeg-2-8-12/libavcodec/imcdata.h
diff --git a/ffmpeg-2-8-11/libavcodec/imdct15.c b/ffmpeg-2-8-12/libavcodec/imdct15.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/imdct15.c
rename to ffmpeg-2-8-12/libavcodec/imdct15.c
diff --git a/ffmpeg-2-8-11/libavcodec/imdct15.h b/ffmpeg-2-8-12/libavcodec/imdct15.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/imdct15.h
rename to ffmpeg-2-8-12/libavcodec/imdct15.h
diff --git a/ffmpeg-2-8-11/libavcodec/imgconvert.c b/ffmpeg-2-8-12/libavcodec/imgconvert.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/imgconvert.c
rename to ffmpeg-2-8-12/libavcodec/imgconvert.c
diff --git a/ffmpeg-2-8-11/libavcodec/imgconvert.h b/ffmpeg-2-8-12/libavcodec/imgconvert.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/imgconvert.h
rename to ffmpeg-2-8-12/libavcodec/imgconvert.h
diff --git a/ffmpeg-2-8-11/libavcodec/imx_dump_header_bsf.c b/ffmpeg-2-8-12/libavcodec/imx_dump_header_bsf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/imx_dump_header_bsf.c
rename to ffmpeg-2-8-12/libavcodec/imx_dump_header_bsf.c
diff --git a/ffmpeg-2-8-12/libavcodec/indeo2.c b/ffmpeg-2-8-12/libavcodec/indeo2.c
new file mode 100644
index 0000000..ce8167b
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/indeo2.c
@@ -0,0 +1,276 @@
+/*
+ * Intel Indeo 2 codec
+ * Copyright (c) 2005 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
+ */
+
+/**
+ * @file
+ * Intel Indeo 2 decoder.
+ */
+
+#define BITSTREAM_READER_LE
+#include "libavutil/attributes.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "indeo2data.h"
+#include "internal.h"
+#include "mathops.h"
+
+typedef struct Ir2Context{
+ AVCodecContext *avctx;
+ AVFrame *picture;
+ GetBitContext gb;
+ int decode_delta;
+} Ir2Context;
+
+#define CODE_VLC_BITS 14
+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;
+}
+
+static int ir2_decode_plane(Ir2Context *ctx, int width, int height, uint8_t *dst,
+ int pitch, const uint8_t *table)
+{
+ int i;
+ int j;
+ int out = 0;
+
+ if (width & 1)
+ return AVERROR_INVALIDDATA;
+
+ /* first line contain absolute values, other lines contain deltas */
+ while (out < width) {
+ int c = ir2_get_code(&ctx->gb);
+ if (c >= 0x80) { /* we have a run */
+ c -= 0x7F;
+ if (out + c*2 > width)
+ return AVERROR_INVALIDDATA;
+ for (i = 0; i < c * 2; i++)
+ dst[out++] = 0x80;
+ } else { /* copy two values from table */
+ if (c <= 0)
+ return AVERROR_INVALIDDATA;
+ dst[out++] = table[c * 2];
+ dst[out++] = table[(c * 2) + 1];
+ }
+ }
+ dst += pitch;
+
+ for (j = 1; j < height; j++) {
+ out = 0;
+ if (get_bits_left(&ctx->gb) <= 0)
+ return AVERROR_INVALIDDATA;
+ while (out < width) {
+ int c = ir2_get_code(&ctx->gb);
+ if (c >= 0x80) { /* we have a skip */
+ c -= 0x7F;
+ if (out + c*2 > width)
+ return AVERROR_INVALIDDATA;
+ for (i = 0; i < c * 2; i++) {
+ dst[out] = dst[out - pitch];
+ out++;
+ }
+ } else { /* add two deltas from table */
+ int t;
+ if (c <= 0)
+ return AVERROR_INVALIDDATA;
+ t = dst[out - pitch] + (table[c * 2] - 128);
+ t = av_clip_uint8(t);
+ dst[out] = t;
+ out++;
+ t = dst[out - pitch] + (table[(c * 2) + 1] - 128);
+ t = av_clip_uint8(t);
+ dst[out] = t;
+ out++;
+ }
+ }
+ dst += pitch;
+ }
+ return 0;
+}
+
+static int ir2_decode_plane_inter(Ir2Context *ctx, int width, int height, uint8_t *dst,
+ int pitch, const uint8_t *table)
+{
+ int j;
+ int out = 0;
+ int c;
+ int t;
+
+ if (width & 1)
+ return AVERROR_INVALIDDATA;
+
+ for (j = 0; j < height; j++) {
+ out = 0;
+ if (get_bits_left(&ctx->gb) <= 0)
+ return AVERROR_INVALIDDATA;
+ while (out < width) {
+ c = ir2_get_code(&ctx->gb);
+ if (c >= 0x80) { /* we have a skip */
+ c -= 0x7F;
+ out += c * 2;
+ } else { /* add two deltas from table */
+ if (c <= 0)
+ return AVERROR_INVALIDDATA;
+ t = dst[out] + (((table[c * 2] - 128)*3) >> 2);
+ t = av_clip_uint8(t);
+ dst[out] = t;
+ out++;
+ t = dst[out] + (((table[(c * 2) + 1] - 128)*3) >> 2);
+ t = av_clip_uint8(t);
+ dst[out] = t;
+ out++;
+ }
+ }
+ dst += pitch;
+ }
+ return 0;
+}
+
+static int ir2_decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ Ir2Context * const s = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ AVFrame *picture = data;
+ AVFrame * const p = s->picture;
+ int start, ret;
+ int ltab, ctab;
+
+ if ((ret = ff_reget_buffer(avctx, p)) < 0)
+ return ret;
+
+ start = 48; /* hardcoded for now */
+
+ if (start >= buf_size) {
+ av_log(s->avctx, AV_LOG_ERROR, "input buffer size too small (%d)\n", buf_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ 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
+
+ init_get_bits(&s->gb, buf + start, (buf_size - start) * 8);
+
+ ltab = buf[0x22] & 3;
+ ctab = buf[0x22] >> 2;
+
+ if (ctab > 3) {
+ av_log(avctx, AV_LOG_ERROR, "ctab %d is invalid\n", ctab);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->decode_delta) { /* intraframe */
+ if ((ret = ir2_decode_plane(s, avctx->width, avctx->height,
+ p->data[0], p->linesize[0],
+ ir2_delta_table[ltab])) < 0)
+ return ret;
+
+ /* swapped U and V */
+ if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
+ p->data[2], p->linesize[2],
+ ir2_delta_table[ctab])) < 0)
+ return ret;
+ if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2,
+ p->data[1], p->linesize[1],
+ ir2_delta_table[ctab])) < 0)
+ return ret;
+ } else { /* interframe */
+ if ((ret = ir2_decode_plane_inter(s, avctx->width, avctx->height,
+ p->data[0], p->linesize[0],
+ ir2_delta_table[ltab])) < 0)
+ return ret;
+ /* swapped U and V */
+ if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
+ p->data[2], p->linesize[2],
+ ir2_delta_table[ctab])) < 0)
+ return ret;
+ if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2,
+ p->data[1], p->linesize[1],
+ ir2_delta_table[ctab])) < 0)
+ return ret;
+ }
+
+ if ((ret = av_frame_ref(picture, p)) < 0)
+ return ret;
+
+ *got_frame = 1;
+
+ return buf_size;
+}
+
+static av_cold int ir2_decode_init(AVCodecContext *avctx)
+{
+ Ir2Context * const ic = avctx->priv_data;
+ static VLC_TYPE vlc_tables[1 << CODE_VLC_BITS][2];
+
+ ic->avctx = avctx;
+
+ avctx->pix_fmt= AV_PIX_FMT_YUV410P;
+
+ ic->picture = av_frame_alloc();
+ 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
+
+ return 0;
+}
+
+static av_cold int ir2_decode_end(AVCodecContext *avctx)
+{
+ Ir2Context * const ic = avctx->priv_data;
+
+ av_frame_free(&ic->picture);
+
+ return 0;
+}
+
+AVCodec ff_indeo2_decoder = {
+ .name = "indeo2",
+ .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo 2"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_INDEO2,
+ .priv_data_size = sizeof(Ir2Context),
+ .init = ir2_decode_init,
+ .close = ir2_decode_end,
+ .decode = ir2_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/indeo2data.h b/ffmpeg-2-8-12/libavcodec/indeo2data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/indeo2data.h
rename to ffmpeg-2-8-12/libavcodec/indeo2data.h
diff --git a/ffmpeg-2-8-11/libavcodec/indeo3.c b/ffmpeg-2-8-12/libavcodec/indeo3.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/indeo3.c
rename to ffmpeg-2-8-12/libavcodec/indeo3.c
diff --git a/ffmpeg-2-8-11/libavcodec/indeo3data.h b/ffmpeg-2-8-12/libavcodec/indeo3data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/indeo3data.h
rename to ffmpeg-2-8-12/libavcodec/indeo3data.h
diff --git a/ffmpeg-2-8-11/libavcodec/indeo4.c b/ffmpeg-2-8-12/libavcodec/indeo4.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/indeo4.c
rename to ffmpeg-2-8-12/libavcodec/indeo4.c
diff --git a/ffmpeg-2-8-11/libavcodec/indeo4data.h b/ffmpeg-2-8-12/libavcodec/indeo4data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/indeo4data.h
rename to ffmpeg-2-8-12/libavcodec/indeo4data.h
diff --git a/ffmpeg-2-8-11/libavcodec/indeo5.c b/ffmpeg-2-8-12/libavcodec/indeo5.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/indeo5.c
rename to ffmpeg-2-8-12/libavcodec/indeo5.c
diff --git a/ffmpeg-2-8-11/libavcodec/indeo5data.h b/ffmpeg-2-8-12/libavcodec/indeo5data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/indeo5data.h
rename to ffmpeg-2-8-12/libavcodec/indeo5data.h
diff --git a/ffmpeg-2-8-11/libavcodec/intelh263dec.c b/ffmpeg-2-8-12/libavcodec/intelh263dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/intelh263dec.c
rename to ffmpeg-2-8-12/libavcodec/intelh263dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/internal.h b/ffmpeg-2-8-12/libavcodec/internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/internal.h
rename to ffmpeg-2-8-12/libavcodec/internal.h
diff --git a/ffmpeg-2-8-11/libavcodec/interplayvideo.c b/ffmpeg-2-8-12/libavcodec/interplayvideo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/interplayvideo.c
rename to ffmpeg-2-8-12/libavcodec/interplayvideo.c
diff --git a/ffmpeg-2-8-11/libavcodec/intrax8.c b/ffmpeg-2-8-12/libavcodec/intrax8.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/intrax8.c
rename to ffmpeg-2-8-12/libavcodec/intrax8.c
diff --git a/ffmpeg-2-8-11/libavcodec/intrax8.h b/ffmpeg-2-8-12/libavcodec/intrax8.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/intrax8.h
rename to ffmpeg-2-8-12/libavcodec/intrax8.h
diff --git a/ffmpeg-2-8-11/libavcodec/intrax8dsp.c b/ffmpeg-2-8-12/libavcodec/intrax8dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/intrax8dsp.c
rename to ffmpeg-2-8-12/libavcodec/intrax8dsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/intrax8dsp.h b/ffmpeg-2-8-12/libavcodec/intrax8dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/intrax8dsp.h
rename to ffmpeg-2-8-12/libavcodec/intrax8dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/intrax8huf.h b/ffmpeg-2-8-12/libavcodec/intrax8huf.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/intrax8huf.h
rename to ffmpeg-2-8-12/libavcodec/intrax8huf.h
diff --git a/ffmpeg-2-8-12/libavcodec/ituh263dec.c b/ffmpeg-2-8-12/libavcodec/ituh263dec.c
new file mode 100644
index 0000000..2d83bf3
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/ituh263dec.c
@@ -0,0 +1,1161 @@
+/*
+ * ITU H263 bitstream decoder
+ * Copyright (c) 2000,2001 Fabrice Bellard
+ * H263+ support.
+ * Copyright (c) 2001 Juan J. Sierralta P
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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
+ * h263 decoder.
+ */
+
+#define UNCHECKED_BITSTREAM_READER 1
+#include <limits.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
+#include "libavutil/mathematics.h"
+#include "avcodec.h"
+#include "mpegvideo.h"
+#include "h263.h"
+#include "h263data.h"
+#include "internal.h"
+#include "mathops.h"
+#include "mpegutils.h"
+#include "unary.h"
+#include "flv.h"
+#include "rv10.h"
+#include "mpeg4video.h"
+#include "mpegvideodata.h"
+
+// The defines below define the number of bits that are read at once for
+// reading vlc values. Changing these may improve speed and data cache needs
+// be aware though that decreasing them may need the number of stages that is
+// passed to get_vlc* to be increased.
+#define MV_VLC_BITS 9
+#define H263_MBTYPE_B_VLC_BITS 6
+#define CBPC_B_VLC_BITS 3
+
+static const int h263_mb_type_b_map[15]= {
+ MB_TYPE_DIRECT2 | MB_TYPE_L0L1,
+ MB_TYPE_DIRECT2 | MB_TYPE_L0L1 | MB_TYPE_CBP,
+ MB_TYPE_DIRECT2 | MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_QUANT,
+ MB_TYPE_L0 | MB_TYPE_16x16,
+ MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_16x16,
+ MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_QUANT | MB_TYPE_16x16,
+ MB_TYPE_L1 | MB_TYPE_16x16,
+ MB_TYPE_L1 | MB_TYPE_CBP | MB_TYPE_16x16,
+ MB_TYPE_L1 | MB_TYPE_CBP | MB_TYPE_QUANT | MB_TYPE_16x16,
+ MB_TYPE_L0L1 | MB_TYPE_16x16,
+ MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_16x16,
+ MB_TYPE_L0L1 | MB_TYPE_CBP | MB_TYPE_QUANT | MB_TYPE_16x16,
+ 0, //stuffing
+ MB_TYPE_INTRA4x4 | MB_TYPE_CBP,
+ MB_TYPE_INTRA4x4 | MB_TYPE_CBP | MB_TYPE_QUANT,
+};
+
+void ff_h263_show_pict_info(MpegEncContext *s){
+ if(s->avctx->debug&FF_DEBUG_PICT_INFO){
+ av_log(s->avctx, AV_LOG_DEBUG, "qp:%d %c size:%d rnd:%d%s%s%s%s%s%s%s%s%s %d/%d\n",
+ s->qscale, av_get_picture_type_char(s->pict_type),
+ s->gb.size_in_bits, 1-s->no_rounding,
+ s->obmc ? " AP" : "",
+ s->umvplus ? " UMV" : "",
+ s->h263_long_vectors ? " LONG" : "",
+ s->h263_plus ? " +" : "",
+ s->h263_aic ? " AIC" : "",
+ s->alt_inter_vlc ? " AIV" : "",
+ s->modified_quant ? " MQ" : "",
+ s->loop_filter ? " LOOP" : "",
+ s->h263_slice_structured ? " SS" : "",
+ s->avctx->framerate.num, s->avctx->framerate.den
+ );
+ }
+}
+
+/***********************************************/
+/* decoding */
+
+VLC ff_h263_intra_MCBPC_vlc;
+VLC ff_h263_inter_MCBPC_vlc;
+VLC ff_h263_cbpy_vlc;
+static VLC mv_vlc;
+static VLC h263_mbtype_b_vlc;
+static VLC cbpc_b_vlc;
+
+/* init vlcs */
+
+/* XXX: find a better solution to handle static init */
+av_cold void ff_h263_decode_init_vlc(void)
+{
+ static volatile int done = 0;
+
+ if (!done) {
+ INIT_VLC_STATIC(&ff_h263_intra_MCBPC_vlc, INTRA_MCBPC_VLC_BITS, 9,
+ ff_h263_intra_MCBPC_bits, 1, 1,
+ ff_h263_intra_MCBPC_code, 1, 1, 72);
+ INIT_VLC_STATIC(&ff_h263_inter_MCBPC_vlc, INTER_MCBPC_VLC_BITS, 28,
+ ff_h263_inter_MCBPC_bits, 1, 1,
+ ff_h263_inter_MCBPC_code, 1, 1, 198);
+ 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,
+ &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]);
+ INIT_VLC_RL(ff_h263_rl_inter, 554);
+ INIT_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);
+ INIT_VLC_STATIC(&cbpc_b_vlc, CBPC_B_VLC_BITS, 4,
+ &ff_cbpc_b_tab[0][1], 2, 1,
+ &ff_cbpc_b_tab[0][0], 2, 1, 8);
+ done = 1;
+ }
+}
+
+int ff_h263_decode_mba(MpegEncContext *s)
+{
+ int i, mb_pos;
+
+ for (i = 0; i < 6; i++)
+ if (s->mb_num - 1 <= ff_mba_max[i])
+ break;
+ mb_pos = get_bits(&s->gb, ff_mba_length[i]);
+ s->mb_x = mb_pos % s->mb_width;
+ s->mb_y = mb_pos / s->mb_width;
+
+ return mb_pos;
+}
+
+/**
+ * Decode the group of blocks header or slice header.
+ * @return <0 if an error occurred
+ */
+static int h263_decode_gob_header(MpegEncContext *s)
+{
+ unsigned int val, gob_number;
+ int left;
+
+ /* Check for GOB Start Code */
+ val = show_bits(&s->gb, 16);
+ if(val)
+ return -1;
+
+ /* We have a GBSC probably with GSTUFF */
+ skip_bits(&s->gb, 16); /* Drop the zeros */
+ left= get_bits_left(&s->gb);
+ left = FFMIN(left, 32);
+ //MN: we must check the bits left or we might end in a infinite loop (or segfault)
+ for(;left>13; left--){
+ if(get_bits1(&s->gb)) break; /* Seek the '1' bit */
+ }
+ if(left<=13)
+ return -1;
+
+ if(s->h263_slice_structured){
+ if(check_marker(&s->gb, "before MBA")==0)
+ return -1;
+
+ ff_h263_decode_mba(s);
+
+ if(s->mb_num > 1583)
+ if(check_marker(&s->gb, "after MBA")==0)
+ return -1;
+
+ s->qscale = get_bits(&s->gb, 5); /* SQUANT */
+ if(check_marker(&s->gb, "after SQUANT")==0)
+ return -1;
+ skip_bits(&s->gb, 2); /* GFID */
+ }else{
+ gob_number = get_bits(&s->gb, 5); /* GN */
+ s->mb_x= 0;
+ s->mb_y= s->gob_index* gob_number;
+ skip_bits(&s->gb, 2); /* GFID */
+ s->qscale = get_bits(&s->gb, 5); /* GQUANT */
+ }
+
+ if(s->mb_y >= s->mb_height)
+ return -1;
+
+ if(s->qscale==0)
+ return -1;
+
+ return 0;
+}
+
+/**
+ * Decode the group of blocks / video packet header.
+ * @return bit position of the resync_marker, or <0 if none was found
+ */
+int ff_h263_resync(MpegEncContext *s){
+ int left, pos, ret;
+
+ if(s->codec_id==AV_CODEC_ID_MPEG4){
+ skip_bits1(&s->gb);
+ align_get_bits(&s->gb);
+ }
+
+ if(show_bits(&s->gb, 16)==0){
+ pos= get_bits_count(&s->gb);
+ if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4)
+ ret= ff_mpeg4_decode_video_packet_header(s->avctx->priv_data);
+ else
+ ret= h263_decode_gob_header(s);
+ if(ret>=0)
+ return pos;
+ }
+ //OK, it's not where it is supposed to be ...
+ s->gb= s->last_resync_gb;
+ align_get_bits(&s->gb);
+ left= get_bits_left(&s->gb);
+
+ for(;left>16+1+5+5; left-=8){
+ if(show_bits(&s->gb, 16)==0){
+ GetBitContext bak= s->gb;
+
+ pos= get_bits_count(&s->gb);
+ if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4)
+ ret= ff_mpeg4_decode_video_packet_header(s->avctx->priv_data);
+ else
+ ret= h263_decode_gob_header(s);
+ if(ret>=0)
+ return pos;
+
+ s->gb= bak;
+ }
+ skip_bits(&s->gb, 8);
+ }
+
+ return -1;
+}
+
+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);
+
+ if (code == 0)
+ return pred;
+ if (code < 0)
+ return 0xffff;
+
+ sign = get_bits1(&s->gb);
+ shift = f_code - 1;
+ val = code;
+ if (shift) {
+ val = (val - 1) << shift;
+ val |= get_bits(&s->gb, shift);
+ val++;
+ }
+ if (sign)
+ val = -val;
+ val += pred;
+
+ /* modulo decoding */
+ if (!s->h263_long_vectors) {
+ val = sign_extend(val, 5 + f_code);
+ } else {
+ /* horrible h263 long vector mode */
+ if (pred < -31 && val < -63)
+ val += 64;
+ if (pred > 32 && val > 63)
+ val -= 64;
+
+ }
+ return val;
+}
+
+
+/* Decode RVLC of H.263+ UMV */
+static int h263p_decode_umotion(MpegEncContext * s, int pred)
+{
+ int code = 0, sign;
+
+ if (get_bits1(&s->gb)) /* Motion difference = 0 */
+ return pred;
+
+ code = 2 + get_bits1(&s->gb);
+
+ while (get_bits1(&s->gb))
+ {
+ code <<= 1;
+ code += get_bits1(&s->gb);
+ }
+ sign = code & 1;
+ code >>= 1;
+
+ code = (sign) ? (pred - code) : (pred + code);
+ ff_tlog(s->avctx,"H.263+ UMV Motion = %d\n", code);
+ return code;
+
+}
+
+/**
+ * read the next MVs for OBMC. yes this is a ugly hack, feel free to send a patch :)
+ */
+static void preview_obmc(MpegEncContext *s){
+ GetBitContext gb= s->gb;
+
+ int cbpc, i, pred_x, pred_y, mx, my;
+ int16_t *mot_val;
+ const int xy= s->mb_x + 1 + s->mb_y * s->mb_stride;
+ const int stride= s->b8_stride*2;
+
+ for(i=0; i<4; i++)
+ s->block_index[i]+= 2;
+ for(i=4; i<6; i++)
+ s->block_index[i]+= 1;
+ s->mb_x++;
+
+ av_assert2(s->pict_type == AV_PICTURE_TYPE_P);
+
+ do{
+ if (get_bits1(&s->gb)) {
+ /* skip mb */
+ mot_val = s->current_picture.motion_val[0][s->block_index[0]];
+ mot_val[0 ]= mot_val[2 ]=
+ mot_val[0+stride]= mot_val[2+stride]= 0;
+ mot_val[1 ]= mot_val[3 ]=
+ mot_val[1+stride]= mot_val[3+stride]= 0;
+
+ s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+ goto end;
+ }
+ cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
+ }while(cbpc == 20);
+
+ if(cbpc & 4){
+ s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
+ }else{
+ get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+ if (cbpc & 8) {
+ if(s->modified_quant){
+ if(get_bits1(&s->gb)) skip_bits(&s->gb, 1);
+ else skip_bits(&s->gb, 5);
+ }else
+ skip_bits(&s->gb, 2);
+ }
+
+ if ((cbpc & 16) == 0) {
+ s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+ /* 16x16 motion prediction */
+ mot_val= ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
+ if (s->umvplus)
+ mx = h263p_decode_umotion(s, pred_x);
+ else
+ mx = ff_h263_decode_motion(s, pred_x, 1);
+
+ if (s->umvplus)
+ my = h263p_decode_umotion(s, pred_y);
+ else
+ my = ff_h263_decode_motion(s, pred_y, 1);
+
+ mot_val[0 ]= mot_val[2 ]=
+ mot_val[0+stride]= mot_val[2+stride]= mx;
+ mot_val[1 ]= mot_val[3 ]=
+ mot_val[1+stride]= mot_val[3+stride]= my;
+ } else {
+ s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
+ for(i=0;i<4;i++) {
+ mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
+ if (s->umvplus)
+ mx = h263p_decode_umotion(s, pred_x);
+ else
+ mx = ff_h263_decode_motion(s, pred_x, 1);
+
+ if (s->umvplus)
+ my = h263p_decode_umotion(s, pred_y);
+ else
+ my = ff_h263_decode_motion(s, pred_y, 1);
+ if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1)
+ skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */
+ mot_val[0] = mx;
+ mot_val[1] = my;
+ }
+ }
+ }
+end:
+
+ for(i=0; i<4; i++)
+ s->block_index[i]-= 2;
+ for(i=4; i<6; i++)
+ s->block_index[i]-= 1;
+ s->mb_x--;
+
+ s->gb= gb;
+}
+
+static void h263_decode_dquant(MpegEncContext *s){
+ static const int8_t quant_tab[4] = { -1, -2, 1, 2 };
+
+ if(s->modified_quant){
+ if(get_bits1(&s->gb))
+ s->qscale= ff_modified_quant_tab[get_bits1(&s->gb)][ s->qscale ];
+ else
+ s->qscale= get_bits(&s->gb, 5);
+ }else
+ s->qscale += quant_tab[get_bits(&s->gb, 2)];
+ ff_set_qscale(s, s->qscale);
+}
+
+static int h263_decode_block(MpegEncContext * s, int16_t * block,
+ int n, int coded)
+{
+ int level, i, j, run;
+ RLTable *rl = &ff_h263_rl_inter;
+ const uint8_t *scan_table;
+ GetBitContext gb= s->gb;
+
+ scan_table = s->intra_scantable.permutated;
+ if (s->h263_aic && s->mb_intra) {
+ rl = &ff_rl_intra_aic;
+ i = 0;
+ if (s->ac_pred) {
+ if (s->h263_aic_dir)
+ scan_table = s->intra_v_scantable.permutated; /* left */
+ else
+ scan_table = s->intra_h_scantable.permutated; /* top */
+ }
+ } else if (s->mb_intra) {
+ /* DC coef */
+ if (CONFIG_RV10_DECODER && s->codec_id == AV_CODEC_ID_RV10) {
+ if (s->rv10_version == 3 && s->pict_type == AV_PICTURE_TYPE_I) {
+ int component, diff;
+ component = (n <= 3 ? 0 : n - 4 + 1);
+ level = s->last_dc[component];
+ if (s->rv10_first_dc_coded[component]) {
+ diff = ff_rv_decode_dc(s, n);
+ if (diff == 0xffff)
+ return -1;
+ level += diff;
+ level = level & 0xff; /* handle wrap round */
+ s->last_dc[component] = level;
+ } else {
+ s->rv10_first_dc_coded[component] = 1;
+ }
+ } else {
+ level = get_bits(&s->gb, 8);
+ if (level == 255)
+ level = 128;
+ }
+ }else{
+ level = get_bits(&s->gb, 8);
+ if((level&0x7F) == 0){
+ av_log(s->avctx, AV_LOG_ERROR, "illegal dc %d at %d %d\n", level, s->mb_x, s->mb_y);
+ if (s->avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))
+ return -1;
+ }
+ if (level == 255)
+ level = 128;
+ }
+ block[0] = level;
+ i = 1;
+ } else {
+ i = 0;
+ }
+ if (!coded) {
+ if (s->mb_intra && s->h263_aic)
+ goto not_coded;
+ s->block_last_index[n] = i - 1;
+ return 0;
+ }
+retry:
+ {
+ OPEN_READER(re, &s->gb);
+ i--; // offset by -1 to allow direct indexing of scan_table
+ for(;;) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+ if (run == 66) {
+ if (level){
+ CLOSE_READER(re, &s->gb);
+ av_log(s->avctx, AV_LOG_ERROR, "illegal ac vlc code at %dx%d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ /* escape */
+ if (CONFIG_FLV_DECODER && s->h263_flv > 1) {
+ int is11 = SHOW_UBITS(re, &s->gb, 1);
+ SKIP_CACHE(re, &s->gb, 1);
+ run = SHOW_UBITS(re, &s->gb, 7) + 1;
+ if (is11) {
+ SKIP_COUNTER(re, &s->gb, 1 + 7);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 11);
+ SKIP_COUNTER(re, &s->gb, 11);
+ } else {
+ SKIP_CACHE(re, &s->gb, 7);
+ level = SHOW_SBITS(re, &s->gb, 7);
+ SKIP_COUNTER(re, &s->gb, 1 + 7 + 7);
+ }
+ } else {
+ run = SHOW_UBITS(re, &s->gb, 7) + 1;
+ SKIP_CACHE(re, &s->gb, 7);
+ level = (int8_t)SHOW_UBITS(re, &s->gb, 8);
+ SKIP_COUNTER(re, &s->gb, 7 + 8);
+ if(level == -128){
+ UPDATE_CACHE(re, &s->gb);
+ if (s->codec_id == AV_CODEC_ID_RV10) {
+ /* XXX: should patch encoder too */
+ level = SHOW_SBITS(re, &s->gb, 12);
+ SKIP_COUNTER(re, &s->gb, 12);
+ }else{
+ level = SHOW_UBITS(re, &s->gb, 5);
+ SKIP_CACHE(re, &s->gb, 5);
+ level |= SHOW_SBITS(re, &s->gb, 6) * (1<<5);
+ SKIP_COUNTER(re, &s->gb, 5 + 6);
+ }
+ }
+ }
+ } else {
+ if (SHOW_UBITS(re, &s->gb, 1))
+ level = -level;
+ SKIP_COUNTER(re, &s->gb, 1);
+ }
+ i += run;
+ if (i >= 64){
+ CLOSE_READER(re, &s->gb);
+ // redo update without last flag, revert -1 offset
+ i = i - run + ((run-1)&63) + 1;
+ if (i < 64) {
+ // only last marker, no overrun
+ block[scan_table[i]] = level;
+ break;
+ }
+ if(s->alt_inter_vlc && rl == &ff_h263_rl_inter && !s->mb_intra){
+ //Looks like a hack but no, it's the way it is supposed to work ...
+ rl = &ff_rl_intra_aic;
+ i = 0;
+ s->gb= gb;
+ s->bdsp.clear_block(block);
+ goto retry;
+ }
+ av_log(s->avctx, AV_LOG_ERROR, "run overflow at %dx%d i:%d\n", s->mb_x, s->mb_y, s->mb_intra);
+ return -1;
+ }
+ j = scan_table[i];
+ block[j] = level;
+ }
+ }
+not_coded:
+ if (s->mb_intra && s->h263_aic) {
+ ff_h263_pred_acdc(s, block, n);
+ i = 63;
+ }
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+static int h263_skip_b_part(MpegEncContext *s, int cbp)
+{
+ LOCAL_ALIGNED_16(int16_t, dblock, [64]);
+ int i, mbi;
+ int bli[6];
+
+ /* we have to set s->mb_intra to zero to decode B-part of PB-frame correctly
+ * but real value should be restored in order to be used later (in OBMC condition)
+ */
+ mbi = s->mb_intra;
+ memcpy(bli, s->block_last_index, sizeof(bli));
+ s->mb_intra = 0;
+ for (i = 0; i < 6; i++) {
+ if (h263_decode_block(s, dblock, i, cbp&32) < 0)
+ return -1;
+ cbp+=cbp;
+ }
+ s->mb_intra = mbi;
+ memcpy(s->block_last_index, bli, sizeof(bli));
+ return 0;
+}
+
+static int h263_get_modb(GetBitContext *gb, int pb_frame, int *cbpb)
+{
+ int c, mv = 1;
+
+ if (pb_frame < 3) { // h.263 Annex G and i263 PB-frame
+ c = get_bits1(gb);
+ if (pb_frame == 2 && c)
+ mv = !get_bits1(gb);
+ } else { // h.263 Annex M improved PB-frame
+ mv = get_unary(gb, 0, 4) + 1;
+ c = mv & 1;
+ mv = !!(mv & 2);
+ }
+ if(c)
+ *cbpb = get_bits(gb, 6);
+ return mv;
+}
+
+int ff_h263_decode_mb(MpegEncContext *s,
+ int16_t block[6][64])
+{
+ int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
+ int16_t *mot_val;
+ const int xy= s->mb_x + s->mb_y * s->mb_stride;
+ int cbpb = 0, pb_mv_count = 0;
+
+ av_assert2(!s->h263_pred);
+
+ if (s->pict_type == AV_PICTURE_TYPE_P) {
+ do{
+ if (get_bits1(&s->gb)) {
+ /* skip mb */
+ s->mb_intra = 0;
+ for(i=0;i<6;i++)
+ s->block_last_index[i] = -1;
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ s->current_picture.mb_type[xy] = MB_TYPE_SKIP | MB_TYPE_16x16 | MB_TYPE_L0;
+ s->mv[0][0][0] = 0;
+ s->mv[0][0][1] = 0;
+ s->mb_skipped = !(s->obmc | s->loop_filter);
+ goto end;
+ }
+ cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
+ if (cbpc < 0){
+ av_log(s->avctx, AV_LOG_ERROR, "cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ }while(cbpc == 20);
+
+ s->bdsp.clear_blocks(s->block[0]);
+
+ dquant = cbpc & 8;
+ s->mb_intra = ((cbpc & 4) != 0);
+ if (s->mb_intra) goto intra;
+
+ if(s->pb_frame && get_bits1(&s->gb))
+ pb_mv_count = h263_get_modb(&s->gb, s->pb_frame, &cbpb);
+ cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+
+ if(s->alt_inter_vlc==0 || (cbpc & 3)!=3)
+ cbpy ^= 0xF;
+
+ cbp = (cbpc & 3) | (cbpy << 2);
+ if (dquant) {
+ h263_decode_dquant(s);
+ }
+
+ s->mv_dir = MV_DIR_FORWARD;
+ if ((cbpc & 16) == 0) {
+ s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+ /* 16x16 motion prediction */
+ s->mv_type = MV_TYPE_16X16;
+ ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
+ if (s->umvplus)
+ mx = h263p_decode_umotion(s, pred_x);
+ else
+ mx = ff_h263_decode_motion(s, pred_x, 1);
+
+ if (mx >= 0xffff)
+ return -1;
+
+ if (s->umvplus)
+ my = h263p_decode_umotion(s, pred_y);
+ else
+ my = ff_h263_decode_motion(s, pred_y, 1);
+
+ if (my >= 0xffff)
+ return -1;
+ s->mv[0][0][0] = mx;
+ s->mv[0][0][1] = my;
+
+ if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1)
+ skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */
+ } else {
+ s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
+ s->mv_type = MV_TYPE_8X8;
+ for(i=0;i<4;i++) {
+ mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
+ if (s->umvplus)
+ mx = h263p_decode_umotion(s, pred_x);
+ else
+ mx = ff_h263_decode_motion(s, pred_x, 1);
+ if (mx >= 0xffff)
+ return -1;
+
+ if (s->umvplus)
+ my = h263p_decode_umotion(s, pred_y);
+ else
+ my = ff_h263_decode_motion(s, pred_y, 1);
+ if (my >= 0xffff)
+ return -1;
+ s->mv[0][i][0] = mx;
+ s->mv[0][i][1] = my;
+ if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1)
+ skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */
+ mot_val[0] = mx;
+ mot_val[1] = my;
+ }
+ }
+ } else if(s->pict_type==AV_PICTURE_TYPE_B) {
+ int mb_type;
+ const int stride= s->b8_stride;
+ int16_t *mot_val0 = s->current_picture.motion_val[0][2 * (s->mb_x + s->mb_y * stride)];
+ int16_t *mot_val1 = s->current_picture.motion_val[1][2 * (s->mb_x + s->mb_y * stride)];
+// const int mv_xy= s->mb_x + 1 + s->mb_y * s->mb_stride;
+
+ //FIXME ugly
+ mot_val0[0 ]= mot_val0[2 ]= mot_val0[0+2*stride]= mot_val0[2+2*stride]=
+ mot_val0[1 ]= mot_val0[3 ]= mot_val0[1+2*stride]= mot_val0[3+2*stride]=
+ mot_val1[0 ]= mot_val1[2 ]= mot_val1[0+2*stride]= mot_val1[2+2*stride]=
+ mot_val1[1 ]= mot_val1[3 ]= mot_val1[1+2*stride]= mot_val1[3+2*stride]= 0;
+
+ do{
+ mb_type= get_vlc2(&s->gb, h263_mbtype_b_vlc.table, H263_MBTYPE_B_VLC_BITS, 2);
+ if (mb_type < 0){
+ av_log(s->avctx, AV_LOG_ERROR, "b mb_type damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+
+ mb_type= h263_mb_type_b_map[ mb_type ];
+ }while(!mb_type);
+
+ s->mb_intra = IS_INTRA(mb_type);
+ if(HAS_CBP(mb_type)){
+ s->bdsp.clear_blocks(s->block[0]);
+ cbpc = get_vlc2(&s->gb, cbpc_b_vlc.table, CBPC_B_VLC_BITS, 1);
+ if(s->mb_intra){
+ dquant = IS_QUANT(mb_type);
+ goto intra;
+ }
+
+ cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+
+ if (cbpy < 0){
+ av_log(s->avctx, AV_LOG_ERROR, "b cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+
+ if(s->alt_inter_vlc==0 || (cbpc & 3)!=3)
+ cbpy ^= 0xF;
+
+ cbp = (cbpc & 3) | (cbpy << 2);
+ }else
+ cbp=0;
+
+ av_assert2(!s->mb_intra);
+
+ if(IS_QUANT(mb_type)){
+ h263_decode_dquant(s);
+ }
+
+ if(IS_DIRECT(mb_type)){
+ s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
+ mb_type |= ff_mpeg4_set_direct_mv(s, 0, 0);
+ }else{
+ s->mv_dir = 0;
+ s->mv_type= MV_TYPE_16X16;
+//FIXME UMV
+
+ if(USES_LIST(mb_type, 0)){
+ int16_t *mot_val= ff_h263_pred_motion(s, 0, 0, &mx, &my);
+ s->mv_dir = MV_DIR_FORWARD;
+
+ mx = ff_h263_decode_motion(s, mx, 1);
+ my = ff_h263_decode_motion(s, my, 1);
+
+ s->mv[0][0][0] = mx;
+ s->mv[0][0][1] = my;
+ mot_val[0 ]= mot_val[2 ]= mot_val[0+2*stride]= mot_val[2+2*stride]= mx;
+ mot_val[1 ]= mot_val[3 ]= mot_val[1+2*stride]= mot_val[3+2*stride]= my;
+ }
+
+ if(USES_LIST(mb_type, 1)){
+ int16_t *mot_val= ff_h263_pred_motion(s, 0, 1, &mx, &my);
+ s->mv_dir |= MV_DIR_BACKWARD;
+
+ mx = ff_h263_decode_motion(s, mx, 1);
+ my = ff_h263_decode_motion(s, my, 1);
+
+ s->mv[1][0][0] = mx;
+ s->mv[1][0][1] = my;
+ mot_val[0 ]= mot_val[2 ]= mot_val[0+2*stride]= mot_val[2+2*stride]= mx;
+ mot_val[1 ]= mot_val[3 ]= mot_val[1+2*stride]= mot_val[3+2*stride]= my;
+ }
+ }
+
+ s->current_picture.mb_type[xy] = mb_type;
+ } else { /* I-Frame */
+ do{
+ cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
+ if (cbpc < 0){
+ av_log(s->avctx, AV_LOG_ERROR, "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ }while(cbpc == 8);
+
+ s->bdsp.clear_blocks(s->block[0]);
+
+ dquant = cbpc & 4;
+ s->mb_intra = 1;
+intra:
+ s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
+ if (s->h263_aic) {
+ s->ac_pred = get_bits1(&s->gb);
+ if(s->ac_pred){
+ s->current_picture.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
+
+ s->h263_aic_dir = get_bits1(&s->gb);
+ }
+ }else
+ s->ac_pred = 0;
+
+ if(s->pb_frame && get_bits1(&s->gb))
+ pb_mv_count = h263_get_modb(&s->gb, s->pb_frame, &cbpb);
+ cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+ if(cbpy<0){
+ av_log(s->avctx, AV_LOG_ERROR, "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ cbp = (cbpc & 3) | (cbpy << 2);
+ if (dquant) {
+ h263_decode_dquant(s);
+ }
+
+ pb_mv_count += !!s->pb_frame;
+ }
+
+ while(pb_mv_count--){
+ ff_h263_decode_motion(s, 0, 1);
+ ff_h263_decode_motion(s, 0, 1);
+ }
+
+ /* decode each block */
+ for (i = 0; i < 6; i++) {
+ if (h263_decode_block(s, block[i], i, cbp&32) < 0)
+ return -1;
+ cbp+=cbp;
+ }
+
+ if(s->pb_frame && h263_skip_b_part(s, cbpb) < 0)
+ return -1;
+ if(s->obmc && !s->mb_intra){
+ if(s->pict_type == AV_PICTURE_TYPE_P && s->mb_x+1<s->mb_width && s->mb_num_left != 1)
+ preview_obmc(s);
+ }
+end:
+
+ /* per-MB end of slice check */
+ {
+ int v= show_bits(&s->gb, 16);
+
+ if (get_bits_left(&s->gb) < 16) {
+ v >>= 16 - get_bits_left(&s->gb);
+ }
+
+ if(v==0)
+ return SLICE_END;
+ }
+
+ return SLICE_OK;
+}
+
+/* most is hardcoded. should extend to handle all h263 streams */
+int ff_h263_decode_picture_header(MpegEncContext *s)
+{
+ int format, width, height, i, ret;
+ uint32_t startcode;
+
+ align_get_bits(&s->gb);
+
+ if (show_bits(&s->gb, 2) == 2 && s->avctx->frame_number == 0) {
+ av_log(s->avctx, AV_LOG_WARNING, "Header looks like RTP instead of H.263\n");
+ }
+
+ startcode= get_bits(&s->gb, 22-8);
+
+ for(i= get_bits_left(&s->gb); i>24; i-=8) {
+ startcode = ((startcode << 8) | get_bits(&s->gb, 8)) & 0x003FFFFF;
+
+ if(startcode == 0x20)
+ break;
+ }
+
+ if (startcode != 0x20) {
+ av_log(s->avctx, AV_LOG_ERROR, "Bad picture start code\n");
+ return -1;
+ }
+ /* temporal reference */
+ i = get_bits(&s->gb, 8); /* picture timestamp */
+ if( (s->picture_number&~0xFF)+i < s->picture_number)
+ i+= 256;
+ s->picture_number= (s->picture_number&~0xFF) + i;
+
+ /* PTYPE starts here */
+ if (check_marker(&s->gb, "in PTYPE") != 1) {
+ return -1;
+ }
+ if (get_bits1(&s->gb) != 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Bad H263 id\n");
+ return -1; /* h263 id */
+ }
+ skip_bits1(&s->gb); /* split screen off */
+ skip_bits1(&s->gb); /* camera off */
+ skip_bits1(&s->gb); /* freeze picture release off */
+
+ format = get_bits(&s->gb, 3);
+ /*
+ 0 forbidden
+ 1 sub-QCIF
+ 10 QCIF
+ 7 extended PTYPE (PLUSPTYPE)
+ */
+
+ if (format != 7 && format != 6) {
+ s->h263_plus = 0;
+ /* H.263v1 */
+ width = ff_h263_format[format][0];
+ height = ff_h263_format[format][1];
+ if (!width)
+ return -1;
+
+ s->pict_type = AV_PICTURE_TYPE_I + get_bits1(&s->gb);
+
+ s->h263_long_vectors = get_bits1(&s->gb);
+
+ if (get_bits1(&s->gb) != 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "H263 SAC not supported\n");
+ return -1; /* SAC: off */
+ }
+ s->obmc= get_bits1(&s->gb); /* Advanced prediction mode */
+ s->unrestricted_mv = s->h263_long_vectors || s->obmc;
+
+ s->pb_frame = get_bits1(&s->gb);
+ s->chroma_qscale= s->qscale = get_bits(&s->gb, 5);
+ skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */
+
+ s->width = width;
+ s->height = height;
+ s->avctx->sample_aspect_ratio= (AVRational){12,11};
+ s->avctx->framerate = (AVRational){ 30000, 1001 };
+ } else {
+ int ufep;
+
+ /* H.263v2 */
+ s->h263_plus = 1;
+ ufep = get_bits(&s->gb, 3); /* Update Full Extended PTYPE */
+
+ /* ufep other than 0 and 1 are reserved */
+ if (ufep == 1) {
+ /* OPPTYPE */
+ format = get_bits(&s->gb, 3);
+ ff_dlog(s->avctx, "ufep=1, format: %d\n", format);
+ s->custom_pcf= get_bits1(&s->gb);
+ s->umvplus = get_bits1(&s->gb); /* Unrestricted Motion Vector */
+ if (get_bits1(&s->gb) != 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Syntax-based Arithmetic Coding (SAC) not supported\n");
+ }
+ s->obmc= get_bits1(&s->gb); /* Advanced prediction mode */
+ s->h263_aic = get_bits1(&s->gb); /* Advanced Intra Coding (AIC) */
+ s->loop_filter= get_bits1(&s->gb);
+ s->unrestricted_mv = s->umvplus || s->obmc || s->loop_filter;
+ if(s->avctx->lowres)
+ s->loop_filter = 0;
+
+ s->h263_slice_structured= get_bits1(&s->gb);
+ if (get_bits1(&s->gb) != 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Reference Picture Selection not supported\n");
+ }
+ if (get_bits1(&s->gb) != 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Independent Segment Decoding not supported\n");
+ }
+ s->alt_inter_vlc= get_bits1(&s->gb);
+ s->modified_quant= get_bits1(&s->gb);
+ if(s->modified_quant)
+ s->chroma_qscale_table= ff_h263_chroma_qscale_table;
+
+ skip_bits(&s->gb, 1); /* Prevent start code emulation */
+
+ skip_bits(&s->gb, 3); /* Reserved */
+ } else if (ufep != 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Bad UFEP type (%d)\n", ufep);
+ return -1;
+ }
+
+ /* MPPTYPE */
+ s->pict_type = get_bits(&s->gb, 3);
+ switch(s->pict_type){
+ case 0: s->pict_type= AV_PICTURE_TYPE_I;break;
+ case 1: s->pict_type= AV_PICTURE_TYPE_P;break;
+ case 2: s->pict_type= AV_PICTURE_TYPE_P;s->pb_frame = 3;break;
+ case 3: s->pict_type= AV_PICTURE_TYPE_B;break;
+ case 7: s->pict_type= AV_PICTURE_TYPE_I;break; //ZYGO
+ default:
+ return -1;
+ }
+ skip_bits(&s->gb, 2);
+ s->no_rounding = get_bits1(&s->gb);
+ skip_bits(&s->gb, 4);
+
+ /* Get the picture dimensions */
+ if (ufep) {
+ if (format == 6) {
+ /* Custom Picture Format (CPFMT) */
+ s->aspect_ratio_info = get_bits(&s->gb, 4);
+ ff_dlog(s->avctx, "aspect: %d\n", s->aspect_ratio_info);
+ /* aspect ratios:
+ 0 - forbidden
+ 1 - 1:1
+ 2 - 12:11 (CIF 4:3)
+ 3 - 10:11 (525-type 4:3)
+ 4 - 16:11 (CIF 16:9)
+ 5 - 40:33 (525-type 16:9)
+ 6-14 - reserved
+ */
+ width = (get_bits(&s->gb, 9) + 1) * 4;
+ check_marker(&s->gb, "in dimensions");
+ height = get_bits(&s->gb, 9) * 4;
+ ff_dlog(s->avctx, "\nH.263+ Custom picture: %dx%d\n",width,height);
+ if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) {
+ /* aspected dimensions */
+ s->avctx->sample_aspect_ratio.num= get_bits(&s->gb, 8);
+ s->avctx->sample_aspect_ratio.den= get_bits(&s->gb, 8);
+ }else{
+ s->avctx->sample_aspect_ratio= ff_h263_pixel_aspect[s->aspect_ratio_info];
+ }
+ } else {
+ width = ff_h263_format[format][0];
+ height = ff_h263_format[format][1];
+ s->avctx->sample_aspect_ratio= (AVRational){12,11};
+ }
+ s->avctx->sample_aspect_ratio.den <<= s->ehc_mode;
+ if ((width == 0) || (height == 0))
+ return -1;
+ s->width = width;
+ s->height = height;
+
+ if(s->custom_pcf){
+ int gcd;
+ s->avctx->framerate.num = 1800000;
+ s->avctx->framerate.den = 1000 + get_bits1(&s->gb);
+ s->avctx->framerate.den *= get_bits(&s->gb, 7);
+ if(s->avctx->framerate.den == 0){
+ av_log(s, AV_LOG_ERROR, "zero framerate\n");
+ return -1;
+ }
+ gcd= av_gcd(s->avctx->framerate.den, s->avctx->framerate.num);
+ s->avctx->framerate.den /= gcd;
+ s->avctx->framerate.num /= gcd;
+ }else{
+ s->avctx->framerate = (AVRational){ 30000, 1001 };
+ }
+ }
+
+ if(s->custom_pcf){
+ skip_bits(&s->gb, 2); //extended Temporal reference
+ }
+
+ if (ufep) {
+ if (s->umvplus) {
+ if(get_bits1(&s->gb)==0) /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */
+ skip_bits1(&s->gb);
+ }
+ if(s->h263_slice_structured){
+ if (get_bits1(&s->gb) != 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "rectangular slices not supported\n");
+ }
+ if (get_bits1(&s->gb) != 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "unordered slices not supported\n");
+ }
+ }
+ }
+
+ s->qscale = get_bits(&s->gb, 5);
+ }
+
+ if ((ret = av_image_check_size(s->width, s->height, 0, s)) < 0)
+ return ret;
+
+ s->mb_width = (s->width + 15) / 16;
+ s->mb_height = (s->height + 15) / 16;
+ s->mb_num = s->mb_width * s->mb_height;
+
+ if (s->pb_frame) {
+ skip_bits(&s->gb, 3); /* Temporal reference for B-pictures */
+ if (s->custom_pcf)
+ skip_bits(&s->gb, 2); //extended Temporal reference
+ skip_bits(&s->gb, 2); /* Quantization information for B-pictures */
+ }
+
+ if (s->pict_type!=AV_PICTURE_TYPE_B) {
+ s->time = s->picture_number;
+ s->pp_time = s->time - s->last_non_b_time;
+ s->last_non_b_time = s->time;
+ }else{
+ s->time = s->picture_number;
+ s->pb_time = s->pp_time - (s->last_non_b_time - s->time);
+ if (s->pp_time <=s->pb_time ||
+ s->pp_time <= s->pp_time - s->pb_time ||
+ s->pp_time <= 0){
+ s->pp_time = 2;
+ s->pb_time = 1;
+ }
+ ff_mpeg4_init_direct_mv(s);
+ }
+
+ /* PEI */
+ if (skip_1stop_8data_bits(&s->gb) < 0)
+ return AVERROR_INVALIDDATA;
+
+ if(s->h263_slice_structured){
+ if (check_marker(&s->gb, "SEPB1") != 1) {
+ return -1;
+ }
+
+ ff_h263_decode_mba(s);
+
+ if (check_marker(&s->gb, "SEPB2") != 1) {
+ return -1;
+ }
+ }
+ s->f_code = 1;
+
+ if(s->h263_aic){
+ s->y_dc_scale_table=
+ s->c_dc_scale_table= ff_aic_dc_scale_table;
+ }else{
+ s->y_dc_scale_table=
+ s->c_dc_scale_table= ff_mpeg1_dc_scale_table;
+ }
+
+ ff_h263_show_pict_info(s);
+ if (s->pict_type == AV_PICTURE_TYPE_I && s->codec_tag == AV_RL32("ZYGO") && get_bits_left(&s->gb) >= 85 + 13*3*16 + 50){
+ int i,j;
+ for(i=0; i<85; i++) av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&s->gb));
+ av_log(s->avctx, AV_LOG_DEBUG, "\n");
+ for(i=0; i<13; i++){
+ for(j=0; j<3; j++){
+ int v= get_bits(&s->gb, 8);
+ v |= get_sbits(&s->gb, 8)<<8;
+ av_log(s->avctx, AV_LOG_DEBUG, " %5d", v);
+ }
+ av_log(s->avctx, AV_LOG_DEBUG, "\n");
+ }
+ for(i=0; i<50; i++) av_log(s->avctx, AV_LOG_DEBUG, "%d", get_bits1(&s->gb));
+ }
+
+ return 0;
+}
diff --git a/ffmpeg-2-8-11/libavcodec/ituh263enc.c b/ffmpeg-2-8-12/libavcodec/ituh263enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ituh263enc.c
rename to ffmpeg-2-8-12/libavcodec/ituh263enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/ivi.c b/ffmpeg-2-8-12/libavcodec/ivi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ivi.c
rename to ffmpeg-2-8-12/libavcodec/ivi.c
diff --git a/ffmpeg-2-8-11/libavcodec/ivi.h b/ffmpeg-2-8-12/libavcodec/ivi.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ivi.h
rename to ffmpeg-2-8-12/libavcodec/ivi.h
diff --git a/ffmpeg-2-8-12/libavcodec/ivi_dsp.c b/ffmpeg-2-8-12/libavcodec/ivi_dsp.c
new file mode 100644
index 0000000..2286c58
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/ivi_dsp.c
@@ -0,0 +1,846 @@
+/*
+ * DSP functions for Indeo Video Interactive codecs (Indeo4 and Indeo5)
+ *
+ * Copyright (c) 2009-2011 Maxim Poliakovski
+ *
+ * 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
+ * DSP functions (inverse transforms, motion compensation, wavelet recompostions)
+ * for Indeo Video Interactive codecs.
+ */
+
+#include "avcodec.h"
+#include "ivi.h"
+#include "ivi_dsp.h"
+
+void ff_ivi_recompose53(const IVIPlaneDesc *plane, uint8_t *dst,
+ const int dst_pitch)
+{
+ int x, y, indx;
+ int32_t p0, p1, p2, p3, tmp0, tmp1, tmp2;
+ int32_t b0_1, b0_2, b1_1, b1_2, b1_3, b2_1, b2_2, b2_3, b2_4, b2_5, b2_6;
+ int32_t b3_1, b3_2, b3_3, b3_4, b3_5, b3_6, b3_7, b3_8, b3_9;
+ int32_t pitch, back_pitch;
+ const short *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
+ const int num_bands = 4;
+
+ /* all bands should have the same pitch */
+ pitch = plane->bands[0].pitch;
+
+ /* pixels at the position "y-1" will be set to pixels at the "y" for the 1st iteration */
+ back_pitch = 0;
+
+ /* get pointers to the wavelet bands */
+ b0_ptr = plane->bands[0].buf;
+ b1_ptr = plane->bands[1].buf;
+ b2_ptr = plane->bands[2].buf;
+ b3_ptr = plane->bands[3].buf;
+
+ for (y = 0; y < plane->height; y += 2) {
+
+ if (y+2 >= plane->height)
+ pitch= 0;
+ /* load storage variables with values */
+ if (num_bands > 0) {
+ b0_1 = b0_ptr[0];
+ b0_2 = b0_ptr[pitch];
+ }
+
+ if (num_bands > 1) {
+ b1_1 = b1_ptr[back_pitch];
+ b1_2 = b1_ptr[0];
+ b1_3 = b1_1 - b1_2*6 + b1_ptr[pitch];
+ }
+
+ if (num_bands > 2) {
+ b2_2 = b2_ptr[0]; // b2[x, y ]
+ b2_3 = b2_2; // b2[x+1,y ] = b2[x,y]
+ b2_5 = b2_ptr[pitch]; // b2[x ,y+1]
+ b2_6 = b2_5; // b2[x+1,y+1] = b2[x,y+1]
+ }
+
+ if (num_bands > 3) {
+ b3_2 = b3_ptr[back_pitch]; // b3[x ,y-1]
+ b3_3 = b3_2; // b3[x+1,y-1] = b3[x ,y-1]
+ b3_5 = b3_ptr[0]; // b3[x ,y ]
+ b3_6 = b3_5; // b3[x+1,y ] = b3[x ,y ]
+ b3_8 = b3_2 - b3_5*6 + b3_ptr[pitch];
+ b3_9 = b3_8;
+ }
+
+ for (x = 0, indx = 0; x < plane->width; x+=2, indx++) {
+ if (x+2 >= plane->width) {
+ b0_ptr --;
+ b1_ptr --;
+ b2_ptr --;
+ b3_ptr --;
+ }
+
+ /* some values calculated in the previous iterations can */
+ /* be reused in the next ones, so do appropriate copying */
+ b2_1 = b2_2; // b2[x-1,y ] = b2[x, y ]
+ b2_2 = b2_3; // b2[x ,y ] = b2[x+1,y ]
+ b2_4 = b2_5; // b2[x-1,y+1] = b2[x ,y+1]
+ b2_5 = b2_6; // b2[x ,y+1] = b2[x+1,y+1]
+ b3_1 = b3_2; // b3[x-1,y-1] = b3[x ,y-1]
+ b3_2 = b3_3; // b3[x ,y-1] = b3[x+1,y-1]
+ b3_4 = b3_5; // b3[x-1,y ] = b3[x ,y ]
+ b3_5 = b3_6; // b3[x ,y ] = b3[x+1,y ]
+ b3_7 = b3_8; // vert_HPF(x-1)
+ b3_8 = b3_9; // vert_HPF(x )
+
+ p0 = p1 = p2 = p3 = 0;
+
+ /* process the LL-band by applying LPF both vertically and horizontally */
+ if (num_bands > 0) {
+ tmp0 = b0_1;
+ tmp2 = b0_2;
+ b0_1 = b0_ptr[indx+1];
+ b0_2 = b0_ptr[pitch+indx+1];
+ tmp1 = tmp0 + b0_1;
+
+ p0 = tmp0 * 16;
+ p1 = tmp1 * 8;
+ p2 = (tmp0 + tmp2) * 8;
+ p3 = (tmp1 + tmp2 + b0_2) * 4;
+ }
+
+ /* process the HL-band by applying HPF vertically and LPF horizontally */
+ if (num_bands > 1) {
+ tmp0 = b1_2;
+ tmp1 = b1_1;
+ b1_2 = b1_ptr[indx+1];
+ b1_1 = b1_ptr[back_pitch+indx+1];
+
+ tmp2 = tmp1 - tmp0*6 + b1_3;
+ b1_3 = b1_1 - b1_2*6 + b1_ptr[pitch+indx+1];
+
+ p0 += (tmp0 + tmp1) * 8;
+ p1 += (tmp0 + tmp1 + b1_1 + b1_2) * 4;
+ p2 += tmp2 * 4;
+ p3 += (tmp2 + b1_3) * 2;
+ }
+
+ /* process the LH-band by applying LPF vertically and HPF horizontally */
+ if (num_bands > 2) {
+ b2_3 = b2_ptr[indx+1];
+ b2_6 = b2_ptr[pitch+indx+1];
+
+ tmp0 = b2_1 + b2_2;
+ tmp1 = b2_1 - b2_2*6 + b2_3;
+
+ p0 += tmp0 * 8;
+ p1 += tmp1 * 4;
+ p2 += (tmp0 + b2_4 + b2_5) * 4;
+ p3 += (tmp1 + b2_4 - b2_5*6 + b2_6) * 2;
+ }
+
+ /* process the HH-band by applying HPF both vertically and horizontally */
+ if (num_bands > 3) {
+ b3_6 = b3_ptr[indx+1]; // b3[x+1,y ]
+ b3_3 = b3_ptr[back_pitch+indx+1]; // b3[x+1,y-1]
+
+ tmp0 = b3_1 + b3_4;
+ tmp1 = b3_2 + b3_5;
+ tmp2 = b3_3 + b3_6;
+
+ b3_9 = b3_3 - b3_6*6 + b3_ptr[pitch+indx+1];
+
+ p0 += (tmp0 + tmp1) * 4;
+ p1 += (tmp0 - tmp1*6 + tmp2) * 2;
+ p2 += (b3_7 + b3_8) * 2;
+ p3 += b3_7 - b3_8*6 + b3_9;
+ }
+
+ /* output four pixels */
+ dst[x] = av_clip_uint8((p0 >> 6) + 128);
+ dst[x+1] = av_clip_uint8((p1 >> 6) + 128);
+ dst[dst_pitch+x] = av_clip_uint8((p2 >> 6) + 128);
+ dst[dst_pitch+x+1] = av_clip_uint8((p3 >> 6) + 128);
+ }// for x
+
+ dst += dst_pitch << 1;
+
+ back_pitch = -pitch;
+
+ b0_ptr += pitch + 1;
+ b1_ptr += pitch + 1;
+ b2_ptr += pitch + 1;
+ b3_ptr += pitch + 1;
+ }
+}
+
+void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst,
+ const int dst_pitch)
+{
+ int x, y, indx, b0, b1, b2, b3, p0, p1, p2, p3;
+ const short *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;
+ int32_t pitch;
+
+ /* all bands should have the same pitch */
+ pitch = plane->bands[0].pitch;
+
+ /* get pointers to the wavelet bands */
+ b0_ptr = plane->bands[0].buf;
+ b1_ptr = plane->bands[1].buf;
+ b2_ptr = plane->bands[2].buf;
+ b3_ptr = plane->bands[3].buf;
+
+ for (y = 0; y < plane->height; y += 2) {
+ for (x = 0, indx = 0; x < plane->width; x += 2, indx++) {
+ /* load coefficients */
+ b0 = b0_ptr[indx]; //should be: b0 = (num_bands > 0) ? b0_ptr[indx] : 0;
+ b1 = b1_ptr[indx]; //should be: b1 = (num_bands > 1) ? b1_ptr[indx] : 0;
+ b2 = b2_ptr[indx]; //should be: b2 = (num_bands > 2) ? b2_ptr[indx] : 0;
+ b3 = b3_ptr[indx]; //should be: b3 = (num_bands > 3) ? b3_ptr[indx] : 0;
+
+ /* haar wavelet recomposition */
+ p0 = (b0 + b1 + b2 + b3 + 2) >> 2;
+ p1 = (b0 + b1 - b2 - b3 + 2) >> 2;
+ p2 = (b0 - b1 + b2 - b3 + 2) >> 2;
+ p3 = (b0 - b1 - b2 + b3 + 2) >> 2;
+
+ /* bias, convert and output four pixels */
+ dst[x] = av_clip_uint8(p0 + 128);
+ dst[x + 1] = av_clip_uint8(p1 + 128);
+ dst[dst_pitch + x] = av_clip_uint8(p2 + 128);
+ dst[dst_pitch + x + 1] = av_clip_uint8(p3 + 128);
+ }// for x
+
+ dst += dst_pitch << 1;
+
+ b0_ptr += pitch;
+ b1_ptr += pitch;
+ b2_ptr += pitch;
+ b3_ptr += pitch;
+ }// for y
+}
+
+/** butterfly operation for the inverse Haar transform */
+#define IVI_HAAR_BFLY(s1, s2, o1, o2, t) \
+ t = ((s1) - (s2)) >> 1;\
+ o1 = ((s1) + (s2)) >> 1;\
+ o2 = (t);\
+
+/** inverse 8-point Haar transform */
+#define INV_HAAR8(s1, s5, s3, s7, s2, s4, s6, s8,\
+ d1, d2, d3, d4, d5, d6, d7, d8,\
+ t0, t1, t2, t3, t4, t5, t6, t7, t8) {\
+ t1 = (s1) * 2; t5 = (s5) * 2;\
+ IVI_HAAR_BFLY(t1, t5, t1, t5, t0); IVI_HAAR_BFLY(t1, s3, t1, t3, t0);\
+ IVI_HAAR_BFLY(t5, s7, t5, t7, t0); IVI_HAAR_BFLY(t1, s2, t1, t2, t0);\
+ IVI_HAAR_BFLY(t3, s4, t3, t4, t0); IVI_HAAR_BFLY(t5, s6, t5, t6, t0);\
+ IVI_HAAR_BFLY(t7, s8, t7, t8, t0);\
+ d1 = COMPENSATE(t1);\
+ d2 = COMPENSATE(t2);\
+ d3 = COMPENSATE(t3);\
+ d4 = COMPENSATE(t4);\
+ d5 = COMPENSATE(t5);\
+ d6 = COMPENSATE(t6);\
+ d7 = COMPENSATE(t7);\
+ d8 = COMPENSATE(t8); }
+
+/** inverse 4-point Haar transform */
+#define INV_HAAR4(s1, s3, s5, s7, d1, d2, d3, d4, t0, t1, t2, t3, t4) {\
+ IVI_HAAR_BFLY(s1, s3, t0, t1, t4);\
+ IVI_HAAR_BFLY(t0, s5, t2, t3, t4);\
+ d1 = COMPENSATE(t2);\
+ d2 = COMPENSATE(t3);\
+ IVI_HAAR_BFLY(t1, s7, t2, t3, t4);\
+ d3 = COMPENSATE(t2);\
+ d4 = COMPENSATE(t3); }
+
+void ff_ivi_inverse_haar_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
+ const uint8_t *flags)
+{
+ int i, shift, sp1, sp2, sp3, sp4;
+ const int32_t *src;
+ int32_t *dst;
+ int tmp[64];
+ int t0, t1, t2, t3, t4, t5, t6, t7, t8;
+
+ /* apply the InvHaar8 to all columns */
+#define COMPENSATE(x) (x)
+ src = in;
+ dst = tmp;
+ for (i = 0; i < 8; i++) {
+ if (flags[i]) {
+ /* pre-scaling */
+ shift = !(i & 4);
+ sp1 = src[ 0] * (1 << shift);
+ sp2 = src[ 8] * (1 << shift);
+ sp3 = src[16] * (1 << shift);
+ sp4 = src[24] * (1 << shift);
+ INV_HAAR8( sp1, sp2, sp3, sp4,
+ src[32], src[40], src[48], src[56],
+ dst[ 0], dst[ 8], dst[16], dst[24],
+ dst[32], dst[40], dst[48], dst[56],
+ t0, t1, t2, t3, t4, t5, t6, t7, t8);
+ } else
+ dst[ 0] = dst[ 8] = dst[16] = dst[24] =
+ dst[32] = dst[40] = dst[48] = dst[56] = 0;
+
+ src++;
+ dst++;
+ }
+#undef COMPENSATE
+
+ /* apply the InvHaar8 to all rows */
+#define COMPENSATE(x) (x)
+ src = tmp;
+ for (i = 0; i < 8; i++) {
+ if ( !src[0] && !src[1] && !src[2] && !src[3]
+ && !src[4] && !src[5] && !src[6] && !src[7]) {
+ memset(out, 0, 8 * sizeof(out[0]));
+ } else {
+ INV_HAAR8(src[0], src[1], src[2], src[3],
+ src[4], src[5], src[6], src[7],
+ out[0], out[1], out[2], out[3],
+ out[4], out[5], out[6], out[7],
+ t0, t1, t2, t3, t4, t5, t6, t7, t8);
+ }
+ src += 8;
+ out += pitch;
+ }
+#undef COMPENSATE
+}
+
+void ff_ivi_row_haar8(const int32_t *in, int16_t *out, uint32_t pitch,
+ const uint8_t *flags)
+{
+ int i;
+ int t0, t1, t2, t3, t4, t5, t6, t7, t8;
+
+ /* apply the InvHaar8 to all rows */
+#define COMPENSATE(x) (x)
+ for (i = 0; i < 8; i++) {
+ if ( !in[0] && !in[1] && !in[2] && !in[3]
+ && !in[4] && !in[5] && !in[6] && !in[7]) {
+ memset(out, 0, 8 * sizeof(out[0]));
+ } else {
+ INV_HAAR8(in[0], in[1], in[2], in[3],
+ in[4], in[5], in[6], in[7],
+ out[0], out[1], out[2], out[3],
+ out[4], out[5], out[6], out[7],
+ t0, t1, t2, t3, t4, t5, t6, t7, t8);
+ }
+ in += 8;
+ out += pitch;
+ }
+#undef COMPENSATE
+}
+
+void ff_ivi_col_haar8(const int32_t *in, int16_t *out, uint32_t pitch,
+ const uint8_t *flags)
+{
+ int i;
+ int t0, t1, t2, t3, t4, t5, t6, t7, t8;
+
+ /* apply the InvHaar8 to all columns */
+#define COMPENSATE(x) (x)
+ for (i = 0; i < 8; i++) {
+ if (flags[i]) {
+ INV_HAAR8(in[ 0], in[ 8], in[16], in[24],
+ in[32], in[40], in[48], in[56],
+ out[0 * pitch], out[1 * pitch],
+ out[2 * pitch], out[3 * pitch],
+ out[4 * pitch], out[5 * pitch],
+ out[6 * pitch], out[7 * pitch],
+ t0, t1, t2, t3, t4, t5, t6, t7, t8);
+ } else
+ out[0 * pitch] = out[1 * pitch] =
+ out[2 * pitch] = out[3 * pitch] =
+ out[4 * pitch] = out[5 * pitch] =
+ out[6 * pitch] = out[7 * pitch] = 0;
+
+ in++;
+ out++;
+ }
+#undef COMPENSATE
+}
+
+void ff_ivi_inverse_haar_4x4(const int32_t *in, int16_t *out, uint32_t pitch,
+ const uint8_t *flags)
+{
+ int i, shift, sp1, sp2;
+ const int32_t *src;
+ int32_t *dst;
+ int tmp[16];
+ int t0, t1, t2, t3, t4;
+
+ /* apply the InvHaar4 to all columns */
+#define COMPENSATE(x) (x)
+ src = in;
+ dst = tmp;
+ for (i = 0; i < 4; i++) {
+ if (flags[i]) {
+ /* pre-scaling */
+ shift = !(i & 2);
+ sp1 = src[0] * (1 << shift);
+ sp2 = src[4] * (1 << shift);
+ INV_HAAR4( sp1, sp2, src[8], src[12],
+ dst[0], dst[4], dst[8], dst[12],
+ t0, t1, t2, t3, t4);
+ } else
+ dst[0] = dst[4] = dst[8] = dst[12] = 0;
+
+ src++;
+ dst++;
+ }
+#undef COMPENSATE
+
+ /* apply the InvHaar8 to all rows */
+#define COMPENSATE(x) (x)
+ src = tmp;
+ for (i = 0; i < 4; i++) {
+ if (!src[0] && !src[1] && !src[2] && !src[3]) {
+ memset(out, 0, 4 * sizeof(out[0]));
+ } else {
+ INV_HAAR4(src[0], src[1], src[2], src[3],
+ out[0], out[1], out[2], out[3],
+ t0, t1, t2, t3, t4);
+ }
+ src += 4;
+ out += pitch;
+ }
+#undef COMPENSATE
+}
+
+void ff_ivi_row_haar4(const int32_t *in, int16_t *out, uint32_t pitch,
+ const uint8_t *flags)
+{
+ int i;
+ int t0, t1, t2, t3, t4;
+
+ /* apply the InvHaar4 to all rows */
+#define COMPENSATE(x) (x)
+ for (i = 0; i < 4; i++) {
+ if (!in[0] && !in[1] && !in[2] && !in[3]) {
+ memset(out, 0, 4 * sizeof(out[0]));
+ } else {
+ INV_HAAR4(in[0], in[1], in[2], in[3],
+ out[0], out[1], out[2], out[3],
+ t0, t1, t2, t3, t4);
+ }
+ in += 4;
+ out += pitch;
+ }
+#undef COMPENSATE
+}
+
+void ff_ivi_col_haar4(const int32_t *in, int16_t *out, uint32_t pitch,
+ const uint8_t *flags)
+{
+ int i;
+ int t0, t1, t2, t3, t4;
+
+ /* apply the InvHaar8 to all columns */
+#define COMPENSATE(x) (x)
+ for (i = 0; i < 4; i++) {
+ if (flags[i]) {
+ INV_HAAR4(in[0], in[4], in[8], in[12],
+ out[0 * pitch], out[1 * pitch],
+ out[2 * pitch], out[3 * pitch],
+ t0, t1, t2, t3, t4);
+ } else
+ out[0 * pitch] = out[1 * pitch] =
+ out[2 * pitch] = out[3 * pitch] = 0;
+
+ in++;
+ out++;
+ }
+#undef COMPENSATE
+}
+
+void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch,
+ int blk_size)
+{
+ int x, y;
+ int16_t dc_coeff;
+
+ dc_coeff = (*in + 0) >> 3;
+
+ for (y = 0; y < blk_size; out += pitch, y++) {
+ for (x = 0; x < blk_size; x++)
+ out[x] = dc_coeff;
+ }
+}
+
+/** butterfly operation for the inverse slant transform */
+#define IVI_SLANT_BFLY(s1, s2, o1, o2, t) \
+ t = (s1) - (s2);\
+ o1 = (s1) + (s2);\
+ o2 = (t);\
+
+/** This is a reflection a,b = 1/2, 5/4 for the inverse slant transform */
+#define IVI_IREFLECT(s1, s2, o1, o2, t) \
+ t = (((s1) + (s2)*2 + 2) >> 2) + (s1);\
+ o2 = (((s1)*2 - (s2) + 2) >> 2) - (s2);\
+ o1 = (t);\
+
+/** This is a reflection a,b = 1/2, 7/8 for the inverse slant transform */
+#define IVI_SLANT_PART4(s1, s2, o1, o2, t) \
+ t = (s2) + (((s1)*4 - (s2) + 4) >> 3);\
+ o2 = (s1) + ((-(s1) - (s2)*4 + 4) >> 3);\
+ o1 = (t);\
+
+/** inverse slant8 transform */
+#define IVI_INV_SLANT8(s1, s4, s8, s5, s2, s6, s3, s7,\
+ d1, d2, d3, d4, d5, d6, d7, d8,\
+ t0, t1, t2, t3, t4, t5, t6, t7, t8) {\
+ IVI_SLANT_PART4(s4, s5, t4, t5, t0);\
+\
+ IVI_SLANT_BFLY(s1, t5, t1, t5, t0); IVI_SLANT_BFLY(s2, s6, t2, t6, t0);\
+ IVI_SLANT_BFLY(s7, s3, t7, t3, t0); IVI_SLANT_BFLY(t4, s8, t4, t8, t0);\
+\
+ IVI_SLANT_BFLY(t1, t2, t1, t2, t0); IVI_IREFLECT (t4, t3, t4, t3, t0);\
+ IVI_SLANT_BFLY(t5, t6, t5, t6, t0); IVI_IREFLECT (t8, t7, t8, t7, t0);\
+ IVI_SLANT_BFLY(t1, t4, t1, t4, t0); IVI_SLANT_BFLY(t2, t3, t2, t3, t0);\
+ IVI_SLANT_BFLY(t5, t8, t5, t8, t0); IVI_SLANT_BFLY(t6, t7, t6, t7, t0);\
+ d1 = COMPENSATE(t1);\
+ d2 = COMPENSATE(t2);\
+ d3 = COMPENSATE(t3);\
+ d4 = COMPENSATE(t4);\
+ d5 = COMPENSATE(t5);\
+ d6 = COMPENSATE(t6);\
+ d7 = COMPENSATE(t7);\
+ d8 = COMPENSATE(t8);}
+
+/** inverse slant4 transform */
+#define IVI_INV_SLANT4(s1, s4, s2, s3, d1, d2, d3, d4, t0, t1, t2, t3, t4) {\
+ IVI_SLANT_BFLY(s1, s2, t1, t2, t0); IVI_IREFLECT (s4, s3, t4, t3, t0);\
+\
+ IVI_SLANT_BFLY(t1, t4, t1, t4, t0); IVI_SLANT_BFLY(t2, t3, t2, t3, t0);\
+ d1 = COMPENSATE(t1);\
+ d2 = COMPENSATE(t2);\
+ d3 = COMPENSATE(t3);\
+ d4 = COMPENSATE(t4);}
+
+void ff_ivi_inverse_slant_8x8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
+{
+ int i;
+ const int32_t *src;
+ int32_t *dst;
+ int tmp[64];
+ int t0, t1, t2, t3, t4, t5, t6, t7, t8;
+
+#define COMPENSATE(x) (x)
+ src = in;
+ dst = tmp;
+ for (i = 0; i < 8; i++) {
+ if (flags[i]) {
+ IVI_INV_SLANT8(src[0], src[8], src[16], src[24], src[32], src[40], src[48], src[56],
+ dst[0], dst[8], dst[16], dst[24], dst[32], dst[40], dst[48], dst[56],
+ t0, t1, t2, t3, t4, t5, t6, t7, t8);
+ } else
+ dst[0] = dst[8] = dst[16] = dst[24] = dst[32] = dst[40] = dst[48] = dst[56] = 0;
+
+ src++;
+ dst++;
+ }
+#undef COMPENSATE
+
+#define COMPENSATE(x) (((x) + 1)>>1)
+ src = tmp;
+ for (i = 0; i < 8; i++) {
+ if (!src[0] && !src[1] && !src[2] && !src[3] && !src[4] && !src[5] && !src[6] && !src[7]) {
+ memset(out, 0, 8*sizeof(out[0]));
+ } else {
+ IVI_INV_SLANT8(src[0], src[1], src[2], src[3], src[4], src[5], src[6], src[7],
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ t0, t1, t2, t3, t4, t5, t6, t7, t8);
+ }
+ src += 8;
+ out += pitch;
+ }
+#undef COMPENSATE
+}
+
+void ff_ivi_inverse_slant_4x4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
+{
+ int i;
+ const int32_t *src;
+ int32_t *dst;
+ int tmp[16];
+ int t0, t1, t2, t3, t4;
+
+#define COMPENSATE(x) (x)
+ src = in;
+ dst = tmp;
+ for (i = 0; i < 4; i++) {
+ if (flags[i]) {
+ IVI_INV_SLANT4(src[0], src[4], src[8], src[12],
+ dst[0], dst[4], dst[8], dst[12],
+ t0, t1, t2, t3, t4);
+ } else
+ dst[0] = dst[4] = dst[8] = dst[12] = 0;
+
+ src++;
+ dst++;
+ }
+#undef COMPENSATE
+
+#define COMPENSATE(x) (((x) + 1)>>1)
+ src = tmp;
+ for (i = 0; i < 4; i++) {
+ if (!src[0] && !src[1] && !src[2] && !src[3]) {
+ out[0] = out[1] = out[2] = out[3] = 0;
+ } else {
+ IVI_INV_SLANT4(src[0], src[1], src[2], src[3],
+ out[0], out[1], out[2], out[3],
+ t0, t1, t2, t3, t4);
+ }
+ src += 4;
+ out += pitch;
+ }
+#undef COMPENSATE
+}
+
+void ff_ivi_dc_slant_2d(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size)
+{
+ int x, y;
+ int16_t dc_coeff;
+
+ dc_coeff = (*in + 1) >> 1;
+
+ for (y = 0; y < blk_size; out += pitch, y++) {
+ for (x = 0; x < blk_size; x++)
+ out[x] = dc_coeff;
+ }
+}
+
+void ff_ivi_row_slant8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
+{
+ int i;
+ int t0, t1, t2, t3, t4, t5, t6, t7, t8;
+
+#define COMPENSATE(x) (((x) + 1)>>1)
+ for (i = 0; i < 8; i++) {
+ if (!in[0] && !in[1] && !in[2] && !in[3] && !in[4] && !in[5] && !in[6] && !in[7]) {
+ memset(out, 0, 8*sizeof(out[0]));
+ } else {
+ IVI_INV_SLANT8( in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7],
+ out[0], out[1], out[2], out[3], out[4], out[5], out[6], out[7],
+ t0, t1, t2, t3, t4, t5, t6, t7, t8);
+ }
+ in += 8;
+ out += pitch;
+ }
+#undef COMPENSATE
+}
+
+void ff_ivi_dc_row_slant(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size)
+{
+ int x, y;
+ int16_t dc_coeff;
+
+ dc_coeff = (*in + 1) >> 1;
+
+ for (x = 0; x < blk_size; x++)
+ out[x] = dc_coeff;
+
+ out += pitch;
+
+ for (y = 1; y < blk_size; out += pitch, y++) {
+ for (x = 0; x < blk_size; x++)
+ out[x] = 0;
+ }
+}
+
+void ff_ivi_col_slant8(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
+{
+ int i, row2, row4, row8;
+ int t0, t1, t2, t3, t4, t5, t6, t7, t8;
+
+ row2 = pitch << 1;
+ row4 = pitch << 2;
+ row8 = pitch << 3;
+
+#define COMPENSATE(x) (((x) + 1)>>1)
+ for (i = 0; i < 8; i++) {
+ if (flags[i]) {
+ IVI_INV_SLANT8(in[0], in[8], in[16], in[24], in[32], in[40], in[48], in[56],
+ out[0], out[pitch], out[row2], out[row2 + pitch], out[row4],
+ out[row4 + pitch], out[row4 + row2], out[row8 - pitch],
+ t0, t1, t2, t3, t4, t5, t6, t7, t8);
+ } else {
+ out[0] = out[pitch] = out[row2] = out[row2 + pitch] = out[row4] =
+ out[row4 + pitch] = out[row4 + row2] = out[row8 - pitch] = 0;
+ }
+
+ in++;
+ out++;
+ }
+#undef COMPENSATE
+}
+
+void ff_ivi_dc_col_slant(const int32_t *in, int16_t *out, uint32_t pitch, int blk_size)
+{
+ int x, y;
+ int16_t dc_coeff;
+
+ dc_coeff = (*in + 1) >> 1;
+
+ for (y = 0; y < blk_size; out += pitch, y++) {
+ out[0] = dc_coeff;
+ for (x = 1; x < blk_size; x++)
+ out[x] = 0;
+ }
+}
+
+void ff_ivi_row_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
+{
+ int i;
+ int t0, t1, t2, t3, t4;
+
+#define COMPENSATE(x) (((x) + 1)>>1)
+ for (i = 0; i < 4; i++) {
+ if (!in[0] && !in[1] && !in[2] && !in[3]) {
+ memset(out, 0, 4*sizeof(out[0]));
+ } else {
+ IVI_INV_SLANT4( in[0], in[1], in[2], in[3],
+ out[0], out[1], out[2], out[3],
+ t0, t1, t2, t3, t4);
+ }
+ in += 4;
+ out += pitch;
+ }
+#undef COMPENSATE
+}
+
+void ff_ivi_col_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const uint8_t *flags)
+{
+ int i, row2;
+ int t0, t1, t2, t3, t4;
+
+ row2 = pitch << 1;
+
+#define COMPENSATE(x) (((x) + 1)>>1)
+ for (i = 0; i < 4; i++) {
+ if (flags[i]) {
+ IVI_INV_SLANT4(in[0], in[4], in[8], in[12],
+ out[0], out[pitch], out[row2], out[row2 + pitch],
+ t0, t1, t2, t3, t4);
+ } else {
+ out[0] = out[pitch] = out[row2] = out[row2 + pitch] = 0;
+ }
+
+ in++;
+ out++;
+ }
+#undef COMPENSATE
+}
+
+void ff_ivi_put_pixels_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
+ const uint8_t *flags)
+{
+ int x, y;
+
+ for (y = 0; y < 8; out += pitch, in += 8, y++)
+ for (x = 0; x < 8; x++)
+ out[x] = in[x];
+}
+
+void ff_ivi_put_dc_pixel_8x8(const int32_t *in, int16_t *out, uint32_t pitch,
+ int blk_size)
+{
+ int y;
+
+ out[0] = in[0];
+ memset(out + 1, 0, 7*sizeof(out[0]));
+ out += pitch;
+
+ for (y = 1; y < 8; out += pitch, y++)
+ memset(out, 0, 8*sizeof(out[0]));
+}
+
+#define IVI_MC_TEMPLATE(size, suffix, OP) \
+static void ivi_mc_ ## size ##x## size ## suffix(int16_t *buf, \
+ uint32_t dpitch, \
+ const int16_t *ref_buf, \
+ uint32_t pitch, int mc_type) \
+{ \
+ int i, j; \
+ const int16_t *wptr; \
+\
+ switch (mc_type) { \
+ case 0: /* fullpel (no interpolation) */ \
+ for (i = 0; i < size; i++, buf += dpitch, ref_buf += pitch) { \
+ for (j = 0; j < size; j++) {\
+ OP(buf[j], ref_buf[j]); \
+ } \
+ } \
+ break; \
+ case 1: /* horizontal halfpel interpolation */ \
+ for (i = 0; i < size; i++, buf += dpitch, ref_buf += pitch) \
+ for (j = 0; j < size; j++) \
+ OP(buf[j], (ref_buf[j] + ref_buf[j+1]) >> 1); \
+ break; \
+ case 2: /* vertical halfpel interpolation */ \
+ wptr = ref_buf + pitch; \
+ for (i = 0; i < size; i++, buf += dpitch, wptr += pitch, ref_buf += pitch) \
+ for (j = 0; j < size; j++) \
+ OP(buf[j], (ref_buf[j] + wptr[j]) >> 1); \
+ break; \
+ case 3: /* vertical and horizontal halfpel interpolation */ \
+ wptr = ref_buf + pitch; \
+ for (i = 0; i < size; i++, buf += dpitch, wptr += pitch, ref_buf += pitch) \
+ for (j = 0; j < size; j++) \
+ OP(buf[j], (ref_buf[j] + ref_buf[j+1] + wptr[j] + wptr[j+1]) >> 2); \
+ break; \
+ } \
+} \
+\
+void ff_ivi_mc_ ## size ##x## size ## suffix(int16_t *buf, const int16_t *ref_buf, \
+ uint32_t pitch, int mc_type) \
+{ \
+ ivi_mc_ ## size ##x## size ## suffix(buf, pitch, ref_buf, pitch, mc_type); \
+} \
+
+#define IVI_MC_AVG_TEMPLATE(size, suffix, OP) \
+void ff_ivi_mc_avg_ ## size ##x## size ## suffix(int16_t *buf, \
+ const int16_t *ref_buf, \
+ const int16_t *ref_buf2, \
+ uint32_t pitch, \
+ int mc_type, int mc_type2) \
+{ \
+ int16_t tmp[size * size]; \
+ int i, j; \
+\
+ ivi_mc_ ## size ##x## size ## _no_delta(tmp, size, ref_buf, pitch, mc_type); \
+ ivi_mc_ ## size ##x## size ## _delta(tmp, size, ref_buf2, pitch, mc_type2); \
+ for (i = 0; i < size; i++, buf += pitch) { \
+ for (j = 0; j < size; j++) {\
+ OP(buf[j], tmp[i * size + j] >> 1); \
+ } \
+ } \
+} \
+
+#define OP_PUT(a, b) (a) = (b)
+#define OP_ADD(a, b) (a) += (b)
+
+IVI_MC_TEMPLATE(8, _no_delta, OP_PUT)
+IVI_MC_TEMPLATE(8, _delta, OP_ADD)
+IVI_MC_TEMPLATE(4, _no_delta, OP_PUT)
+IVI_MC_TEMPLATE(4, _delta, OP_ADD)
+IVI_MC_AVG_TEMPLATE(8, _no_delta, OP_PUT)
+IVI_MC_AVG_TEMPLATE(8, _delta, OP_ADD)
+IVI_MC_AVG_TEMPLATE(4, _no_delta, OP_PUT)
+IVI_MC_AVG_TEMPLATE(4, _delta, OP_ADD)
diff --git a/ffmpeg-2-8-11/libavcodec/ivi_dsp.h b/ffmpeg-2-8-12/libavcodec/ivi_dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ivi_dsp.h
rename to ffmpeg-2-8-12/libavcodec/ivi_dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/j2kenc.c b/ffmpeg-2-8-12/libavcodec/j2kenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/j2kenc.c
rename to ffmpeg-2-8-12/libavcodec/j2kenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/jacosub.h b/ffmpeg-2-8-12/libavcodec/jacosub.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jacosub.h
rename to ffmpeg-2-8-12/libavcodec/jacosub.h
diff --git a/ffmpeg-2-8-11/libavcodec/jacosubdec.c b/ffmpeg-2-8-12/libavcodec/jacosubdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jacosubdec.c
rename to ffmpeg-2-8-12/libavcodec/jacosubdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/jfdctfst.c b/ffmpeg-2-8-12/libavcodec/jfdctfst.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jfdctfst.c
rename to ffmpeg-2-8-12/libavcodec/jfdctfst.c
diff --git a/ffmpeg-2-8-11/libavcodec/jfdctint.c b/ffmpeg-2-8-12/libavcodec/jfdctint.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jfdctint.c
rename to ffmpeg-2-8-12/libavcodec/jfdctint.c
diff --git a/ffmpeg-2-8-11/libavcodec/jfdctint_template.c b/ffmpeg-2-8-12/libavcodec/jfdctint_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jfdctint_template.c
rename to ffmpeg-2-8-12/libavcodec/jfdctint_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/jpeg2000.c b/ffmpeg-2-8-12/libavcodec/jpeg2000.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jpeg2000.c
rename to ffmpeg-2-8-12/libavcodec/jpeg2000.c
diff --git a/ffmpeg-2-8-12/libavcodec/jpeg2000.h b/ffmpeg-2-8-12/libavcodec/jpeg2000.h
new file mode 100644
index 0000000..873e450
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/jpeg2000.h
@@ -0,0 +1,291 @@
+/*
+ * JPEG 2000 common defines, structures and functions
+ * Copyright (c) 2007 Kamil Nowosad
+ * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu at gmail.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 AVCODEC_JPEG2000_H
+#define AVCODEC_JPEG2000_H
+
+/**
+ * @file
+ * JPEG 2000 structures and defines common
+ * to encoder and decoder
+ */
+
+#include <stdint.h>
+
+#include "avcodec.h"
+#include "mqc.h"
+#include "jpeg2000dwt.h"
+
+enum Jpeg2000Markers {
+ JPEG2000_SOC = 0xff4f, // start of codestream
+ JPEG2000_SIZ = 0xff51, // image and tile size
+ JPEG2000_COD, // coding style default
+ JPEG2000_COC, // coding style component
+ JPEG2000_TLM = 0xff55, // packed packet headers, tile-part header
+ JPEG2000_PLM = 0xff57, // tile-part lengths
+ JPEG2000_PLT, // packet length, main header
+ JPEG2000_QCD = 0xff5c, // quantization default
+ JPEG2000_QCC, // quantization component
+ JPEG2000_RGN, // region of interest
+ JPEG2000_POC, // progression order change
+ JPEG2000_PPM, // packet length, tile-part header
+ JPEG2000_PPT, // packed packet headers, main header
+ JPEG2000_CRG = 0xff63, // component registration
+ JPEG2000_COM, // comment
+ JPEG2000_SOT = 0xff90, // start of tile-part
+ JPEG2000_SOP, // start of packet
+ JPEG2000_EPH, // end of packet header
+ JPEG2000_SOD, // start of data
+ JPEG2000_EOC = 0xffd9, // end of codestream
+};
+
+#define JPEG2000_SOP_FIXED_BYTES 0xFF910004
+#define JPEG2000_SOP_BYTE_LENGTH 6
+
+enum Jpeg2000Quantsty { // quantization style
+ JPEG2000_QSTY_NONE, // no quantization
+ JPEG2000_QSTY_SI, // scalar derived
+ JPEG2000_QSTY_SE // scalar expounded
+};
+
+#define JPEG2000_MAX_DECLEVELS 33
+#define JPEG2000_MAX_RESLEVELS (JPEG2000_MAX_DECLEVELS + 1)
+
+#define JPEG2000_MAX_PASSES 100
+
+// T1 flags
+// flags determining significance of neighbor coefficients
+#define JPEG2000_T1_SIG_N 0x0001
+#define JPEG2000_T1_SIG_E 0x0002
+#define JPEG2000_T1_SIG_W 0x0004
+#define JPEG2000_T1_SIG_S 0x0008
+#define JPEG2000_T1_SIG_NE 0x0010
+#define JPEG2000_T1_SIG_NW 0x0020
+#define JPEG2000_T1_SIG_SE 0x0040
+#define JPEG2000_T1_SIG_SW 0x0080
+#define JPEG2000_T1_SIG_NB (JPEG2000_T1_SIG_N | JPEG2000_T1_SIG_E | \
+ JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_W | \
+ JPEG2000_T1_SIG_NE | JPEG2000_T1_SIG_NW | \
+ JPEG2000_T1_SIG_SE | JPEG2000_T1_SIG_SW)
+// flags determining sign bit of neighbor coefficients
+#define JPEG2000_T1_SGN_N 0x0100
+#define JPEG2000_T1_SGN_S 0x0200
+#define JPEG2000_T1_SGN_W 0x0400
+#define JPEG2000_T1_SGN_E 0x0800
+
+#define JPEG2000_T1_VIS 0x1000
+#define JPEG2000_T1_SIG 0x2000
+#define JPEG2000_T1_REF 0x4000
+
+#define JPEG2000_T1_SGN 0x8000
+
+// Codeblock coding styles
+#define JPEG2000_CBLK_BYPASS 0x01 // Selective arithmetic coding bypass
+#define JPEG2000_CBLK_RESET 0x02 // Reset context probabilities
+#define JPEG2000_CBLK_TERMALL 0x04 // Terminate after each coding pass
+#define JPEG2000_CBLK_VSC 0x08 // Vertical stripe causal context formation
+#define JPEG2000_CBLK_PREDTERM 0x10 // Predictable termination
+#define JPEG2000_CBLK_SEGSYM 0x20 // Segmentation symbols present
+
+// Coding styles
+#define JPEG2000_CSTY_PREC 0x01 // Precincts defined in coding style
+#define JPEG2000_CSTY_SOP 0x02 // SOP marker present
+#define JPEG2000_CSTY_EPH 0x04 // EPH marker present
+
+// Progression orders
+#define JPEG2000_PGOD_LRCP 0x00 // Layer-resolution level-component-position progression
+#define JPEG2000_PGOD_RLCP 0x01 // Resolution level-layer-component-position progression
+#define JPEG2000_PGOD_RPCL 0x02 // Resolution level-position-component-layer progression
+#define JPEG2000_PGOD_PCRL 0x03 // Position-component-resolution level-layer progression
+#define JPEG2000_PGOD_CPRL 0x04 // Component-position-resolution level-layer progression
+
+typedef struct Jpeg2000T1Context {
+ int data[6144];
+ uint16_t flags[6156];
+ MqcState mqc;
+ int stride;
+} Jpeg2000T1Context;
+
+typedef struct Jpeg2000TgtNode {
+ uint8_t val;
+ uint8_t vis;
+ struct Jpeg2000TgtNode *parent;
+} Jpeg2000TgtNode;
+
+typedef struct Jpeg2000CodingStyle {
+ int nreslevels; // number of resolution levels
+ int nreslevels2decode; // number of resolution levels to decode
+ uint8_t log2_cblk_width,
+ log2_cblk_height; // exponent of codeblock size
+ uint8_t transform; // DWT type
+ uint8_t csty; // coding style
+ uint8_t nlayers; // number of layers
+ uint8_t mct; // multiple component transformation
+ uint8_t cblk_style; // codeblock coding style
+ 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?
+} Jpeg2000CodingStyle;
+
+typedef struct Jpeg2000QuantStyle {
+ uint8_t expn[JPEG2000_MAX_DECLEVELS * 3]; // quantization exponent
+ uint16_t mant[JPEG2000_MAX_DECLEVELS * 3]; // quantization mantissa
+ uint8_t quantsty; // quantization style
+ uint8_t nguardbits; // number of guard bits
+} Jpeg2000QuantStyle;
+
+typedef struct Jpeg2000Pass {
+ uint16_t rate;
+ int64_t disto;
+ uint8_t flushed[4];
+ int flushed_len;
+} Jpeg2000Pass;
+
+typedef struct Jpeg2000Cblk {
+ uint8_t npasses;
+ uint8_t ninclpasses; // number coding of passes included in codestream
+ uint8_t nonzerobits;
+ uint16_t length;
+ uint16_t lengthinc[JPEG2000_MAX_PASSES];
+ uint8_t nb_lengthinc;
+ uint8_t lblock;
+ uint8_t zero;
+ uint8_t data[8192];
+ int nb_terminations;
+ int nb_terminationsinc;
+ int data_start[JPEG2000_MAX_PASSES];
+ Jpeg2000Pass passes[JPEG2000_MAX_PASSES];
+ int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
+} Jpeg2000Cblk; // code block
+
+typedef struct Jpeg2000Prec {
+ int nb_codeblocks_width;
+ int nb_codeblocks_height;
+ Jpeg2000TgtNode *zerobits;
+ Jpeg2000TgtNode *cblkincl;
+ Jpeg2000Cblk *cblk;
+ int decoded_layers;
+ int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
+} Jpeg2000Prec; // precinct
+
+typedef struct Jpeg2000Band {
+ int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
+ uint16_t log2_cblk_width, log2_cblk_height;
+ int i_stepsize; // quantization stepsize
+ float f_stepsize; // quantization stepsize
+ Jpeg2000Prec *prec;
+} Jpeg2000Band; // subband
+
+typedef struct Jpeg2000ResLevel {
+ uint8_t nbands;
+ int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
+ int num_precincts_x, num_precincts_y; // number of precincts in x/y direction
+ uint8_t log2_prec_width, log2_prec_height; // exponent of precinct size
+ Jpeg2000Band *band;
+} Jpeg2000ResLevel; // resolution level
+
+typedef struct Jpeg2000Component {
+ Jpeg2000ResLevel *reslevel;
+ DWTContext dwt;
+ float *f_data;
+ int *i_data;
+ int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}} -- can be reduced with lowres option
+ int coord_o[2][2]; // border coordinates {{x0, x1}, {y0, y1}} -- original values from jpeg2000 headers
+} Jpeg2000Component;
+
+/* misc tools */
+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)
+{
+ return (a + (int64_t)b - 1) / b;
+}
+
+/* TIER-1 routines */
+
+/* Set up lookup tables used in TIER-1. */
+void ff_jpeg2000_init_tier1_luts(void);
+
+/* Update significance of a coefficient at current position (x,y) and
+ * for neighbors. */
+void ff_jpeg2000_set_significance(Jpeg2000T1Context *t1,
+ int x, int y, int negative);
+
+extern uint8_t ff_jpeg2000_sigctxno_lut[256][4];
+
+/* Get context label (number in range[0..8]) of a coefficient for significance
+ * propagation and cleanup coding passes. */
+static inline int ff_jpeg2000_getsigctxno(int flag, int bandno)
+{
+ return ff_jpeg2000_sigctxno_lut[flag & 255][bandno];
+}
+
+static const uint8_t refctxno_lut[2][2] = { { 14, 15 }, { 16, 16 } };
+
+/* Get context label (number in range[14..16]) of a coefficient for magnitude
+ * refinement pass. */
+static inline int ff_jpeg2000_getrefctxno(int flag)
+{
+ return refctxno_lut[(flag >> 14) & 1][(flag & 255) != 0];
+}
+
+extern uint8_t ff_jpeg2000_sgnctxno_lut[16][16];
+extern uint8_t ff_jpeg2000_xorbit_lut[16][16];
+
+/* Get context label (number in range[9..13]) for sign decoding. */
+static inline int ff_jpeg2000_getsgnctxno(int flag, int *xorbit)
+{
+ *xorbit = ff_jpeg2000_xorbit_lut[flag & 15][(flag >> 8) & 15];
+ return ff_jpeg2000_sgnctxno_lut[flag & 15][(flag >> 8) & 15];
+}
+
+int ff_jpeg2000_init_component(Jpeg2000Component *comp,
+ Jpeg2000CodingStyle *codsty,
+ Jpeg2000QuantStyle *qntsty,
+ int cbps, int dx, int dy,
+ AVCodecContext *ctx);
+
+void ff_jpeg2000_reinit(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty);
+
+void ff_jpeg2000_cleanup(Jpeg2000Component *comp, Jpeg2000CodingStyle *codsty);
+
+static inline int needs_termination(int style, int passno) {
+ if (style & JPEG2000_CBLK_BYPASS) {
+ int type = passno % 3;
+ passno /= 3;
+ if (type == 0 && passno > 2)
+ return 2;
+ if (type == 2 && passno > 2)
+ return 1;
+ if (style & JPEG2000_CBLK_TERMALL) {
+ return passno > 2 ? 2 : 1;
+ }
+ }
+ if (style & JPEG2000_CBLK_TERMALL)
+ return 1;
+ return 0;
+}
+
+#endif /* AVCODEC_JPEG2000_H */
diff --git a/ffmpeg-2-8-12/libavcodec/jpeg2000dec.c b/ffmpeg-2-8-12/libavcodec/jpeg2000dec.c
new file mode 100644
index 0000000..27dad4a
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/jpeg2000dec.c
@@ -0,0 +1,2205 @@
+/*
+ * JPEG 2000 image decoder
+ * Copyright (c) 2007 Kamil Nowosad
+ * Copyright (c) 2013 Nicolas Bertrand <nicoinattendu at gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * JPEG 2000 image decoder
+ */
+
+#include <inttypes.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
+#include "libavutil/common.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+#include "thread.h"
+#include "jpeg2000.h"
+#include "jpeg2000dsp.h"
+
+#define JP2_SIG_TYPE 0x6A502020
+#define JP2_SIG_VALUE 0x0D0A870A
+#define JP2_CODESTREAM 0x6A703263
+#define JP2_HEADER 0x6A703268
+
+#define HAD_COC 0x01
+#define HAD_QCC 0x02
+
+#define MAX_POCS 32
+
+typedef struct Jpeg2000POCEntry {
+ uint16_t LYEpoc;
+ uint16_t CSpoc;
+ uint16_t CEpoc;
+ uint8_t RSpoc;
+ uint8_t REpoc;
+ uint8_t Ppoc;
+} Jpeg2000POCEntry;
+
+typedef struct Jpeg2000POC {
+ Jpeg2000POCEntry poc[MAX_POCS];
+ int nb_poc;
+ int is_default;
+} Jpeg2000POC;
+
+typedef struct Jpeg2000TilePart {
+ uint8_t tile_index; // Tile index who refers the tile-part
+ const uint8_t *tp_end;
+ GetByteContext tpg; // bit stream in tile-part
+} Jpeg2000TilePart;
+
+/* RMK: For JPEG2000 DCINEMA 3 tile-parts in a tile
+ * one per component, so tile_part elements have a size of 3 */
+typedef struct Jpeg2000Tile {
+ Jpeg2000Component *comp;
+ uint8_t properties[4];
+ Jpeg2000CodingStyle codsty[4];
+ Jpeg2000QuantStyle qntsty[4];
+ Jpeg2000POC poc;
+ Jpeg2000TilePart tile_part[256];
+ uint16_t tp_idx; // Tile-part index
+ int coord[2][2]; // border coordinates {{x0, x1}, {y0, y1}}
+} Jpeg2000Tile;
+
+typedef struct Jpeg2000DecoderContext {
+ AVClass *class;
+ AVCodecContext *avctx;
+ GetByteContext g;
+
+ int width, height;
+ int image_offset_x, image_offset_y;
+ int tile_offset_x, tile_offset_y;
+ uint8_t cbps[4]; // bits per sample in particular components
+ uint8_t sgnd[4]; // if a component is signed
+ uint8_t properties[4];
+ int cdx[4], cdy[4];
+ int precision;
+ int ncomponents;
+ int colour_space;
+ uint32_t palette[256];
+ int8_t pal8;
+ int cdef[4];
+ int tile_width, tile_height;
+ unsigned numXtiles, numYtiles;
+ int maxtilelen;
+
+ Jpeg2000CodingStyle codsty[4];
+ Jpeg2000QuantStyle qntsty[4];
+ Jpeg2000POC poc;
+
+ int bit_index;
+
+ int curtileno;
+
+ Jpeg2000Tile *tile;
+ Jpeg2000DSPContext dsp;
+
+ /*options parameters*/
+ int reduction_factor;
+} Jpeg2000DecoderContext;
+
+/* get_bits functions for JPEG2000 packet bitstream
+ * It is a get_bit function with a bit-stuffing routine. If the value of the
+ * byte is 0xFF, the next byte includes an extra zero bit stuffed into the MSB.
+ * cf. ISO-15444-1:2002 / B.10.1 Bit-stuffing routine */
+static int get_bits(Jpeg2000DecoderContext *s, int n)
+{
+ int res = 0;
+
+ while (--n >= 0) {
+ res <<= 1;
+ if (s->bit_index == 0) {
+ s->bit_index = 7 + (bytestream2_get_byte(&s->g) != 0xFFu);
+ }
+ s->bit_index--;
+ res |= (bytestream2_peek_byte(&s->g) >> s->bit_index) & 1;
+ }
+ return res;
+}
+
+static void jpeg2000_flush(Jpeg2000DecoderContext *s)
+{
+ if (bytestream2_get_byte(&s->g) == 0xff)
+ bytestream2_skip(&s->g, 1);
+ s->bit_index = 8;
+}
+
+/* decode the value stored in node */
+static int tag_tree_decode(Jpeg2000DecoderContext *s, Jpeg2000TgtNode *node,
+ int threshold)
+{
+ Jpeg2000TgtNode *stack[30];
+ int sp = -1, curval = 0;
+
+ if (!node) {
+ av_log(s->avctx, AV_LOG_ERROR, "missing node\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ while (node && !node->vis) {
+ stack[++sp] = node;
+ node = node->parent;
+ }
+
+ if (node)
+ curval = node->val;
+ else
+ curval = stack[sp]->val;
+
+ while (curval < threshold && sp >= 0) {
+ if (curval < stack[sp]->val)
+ curval = stack[sp]->val;
+ while (curval < threshold) {
+ int ret;
+ if ((ret = get_bits(s, 1)) > 0) {
+ stack[sp]->vis++;
+ break;
+ } else if (!ret)
+ curval++;
+ else
+ return ret;
+ }
+ stack[sp]->val = curval;
+ sp--;
+ }
+ return curval;
+}
+
+static int pix_fmt_match(enum AVPixelFormat pix_fmt, int components,
+ int bpc, uint32_t log2_chroma_wh, int pal8)
+{
+ int match = 1;
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
+
+ av_assert2(desc);
+
+ if (desc->nb_components != components) {
+ return 0;
+ }
+
+ switch (components) {
+ case 4:
+ match = match && desc->comp[3].depth_minus1 + 1 >= bpc &&
+ (log2_chroma_wh >> 14 & 3) == 0 &&
+ (log2_chroma_wh >> 12 & 3) == 0;
+ case 3:
+ match = match && desc->comp[2].depth_minus1 + 1 >= bpc &&
+ (log2_chroma_wh >> 10 & 3) == desc->log2_chroma_w &&
+ (log2_chroma_wh >> 8 & 3) == desc->log2_chroma_h;
+ case 2:
+ match = match && desc->comp[1].depth_minus1 + 1 >= bpc &&
+ (log2_chroma_wh >> 6 & 3) == desc->log2_chroma_w &&
+ (log2_chroma_wh >> 4 & 3) == desc->log2_chroma_h;
+
+ case 1:
+ match = match && desc->comp[0].depth_minus1 + 1 >= bpc &&
+ (log2_chroma_wh >> 2 & 3) == 0 &&
+ (log2_chroma_wh & 3) == 0 &&
+ (desc->flags & AV_PIX_FMT_FLAG_PAL) == pal8 * AV_PIX_FMT_FLAG_PAL;
+ }
+ return match;
+}
+
+// pix_fmts with lower bpp have to be listed before
+// similar pix_fmts with higher bpp.
+#define RGB_PIXEL_FORMATS AV_PIX_FMT_PAL8,AV_PIX_FMT_RGB24,AV_PIX_FMT_RGBA,AV_PIX_FMT_RGB48,AV_PIX_FMT_RGBA64
+#define GRAY_PIXEL_FORMATS AV_PIX_FMT_GRAY8,AV_PIX_FMT_GRAY8A,AV_PIX_FMT_GRAY16,AV_PIX_FMT_YA16
+#define YUV_PIXEL_FORMATS AV_PIX_FMT_YUV410P,AV_PIX_FMT_YUV411P,AV_PIX_FMT_YUVA420P, \
+ AV_PIX_FMT_YUV420P,AV_PIX_FMT_YUV422P,AV_PIX_FMT_YUVA422P, \
+ AV_PIX_FMT_YUV440P,AV_PIX_FMT_YUV444P,AV_PIX_FMT_YUVA444P, \
+ AV_PIX_FMT_YUV420P9,AV_PIX_FMT_YUV422P9,AV_PIX_FMT_YUV444P9, \
+ AV_PIX_FMT_YUVA420P9,AV_PIX_FMT_YUVA422P9,AV_PIX_FMT_YUVA444P9, \
+ AV_PIX_FMT_YUV420P10,AV_PIX_FMT_YUV422P10,AV_PIX_FMT_YUV444P10, \
+ AV_PIX_FMT_YUVA420P10,AV_PIX_FMT_YUVA422P10,AV_PIX_FMT_YUVA444P10, \
+ 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_YUV420P16,AV_PIX_FMT_YUV422P16,AV_PIX_FMT_YUV444P16, \
+ AV_PIX_FMT_YUVA420P16,AV_PIX_FMT_YUVA422P16,AV_PIX_FMT_YUVA444P16
+#define XYZ_PIXEL_FORMATS AV_PIX_FMT_XYZ12
+
+static const enum AVPixelFormat rgb_pix_fmts[] = {RGB_PIXEL_FORMATS};
+static const enum AVPixelFormat gray_pix_fmts[] = {GRAY_PIXEL_FORMATS};
+static const enum AVPixelFormat yuv_pix_fmts[] = {YUV_PIXEL_FORMATS};
+static const enum AVPixelFormat xyz_pix_fmts[] = {XYZ_PIXEL_FORMATS,
+ YUV_PIXEL_FORMATS};
+static const enum AVPixelFormat all_pix_fmts[] = {RGB_PIXEL_FORMATS,
+ GRAY_PIXEL_FORMATS,
+ YUV_PIXEL_FORMATS,
+ XYZ_PIXEL_FORMATS};
+
+/* marker segments */
+/* get sizes and offsets of image, tiles; number of components */
+static int get_siz(Jpeg2000DecoderContext *s)
+{
+ int i;
+ int ncomponents;
+ uint32_t log2_chroma_wh = 0;
+ const enum AVPixelFormat *possible_fmts = NULL;
+ int possible_fmts_nb = 0;
+ int ret;
+
+ if (bytestream2_get_bytes_left(&s->g) < 36) {
+ av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for SIZ\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->avctx->profile = bytestream2_get_be16u(&s->g); // Rsiz
+ s->width = bytestream2_get_be32u(&s->g); // Width
+ s->height = bytestream2_get_be32u(&s->g); // Height
+ s->image_offset_x = bytestream2_get_be32u(&s->g); // X0Siz
+ s->image_offset_y = bytestream2_get_be32u(&s->g); // Y0Siz
+ s->tile_width = bytestream2_get_be32u(&s->g); // XTSiz
+ s->tile_height = bytestream2_get_be32u(&s->g); // YTSiz
+ s->tile_offset_x = bytestream2_get_be32u(&s->g); // XT0Siz
+ s->tile_offset_y = bytestream2_get_be32u(&s->g); // YT0Siz
+ 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_size(s->width, s->height, 0, s->avctx)) {
+ avpriv_request_sample(s->avctx, "Large Dimensions");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if (ncomponents <= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid number of components: %d\n",
+ s->ncomponents);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (ncomponents > 4) {
+ avpriv_request_sample(s->avctx, "Support for %d components",
+ ncomponents);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if (s->tile_offset_x < 0 || s->tile_offset_y < 0 ||
+ s->image_offset_x < s->tile_offset_x ||
+ s->image_offset_y < s->tile_offset_y ||
+ s->tile_width + (int64_t)s->tile_offset_x <= s->image_offset_x ||
+ s->tile_height + (int64_t)s->tile_offset_y <= s->image_offset_y
+ ) {
+ av_log(s->avctx, AV_LOG_ERROR, "Tile offsets are invalid\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->ncomponents = ncomponents;
+
+ if (s->tile_width <= 0 || s->tile_height <= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid tile dimension %dx%d.\n",
+ s->tile_width, s->tile_height);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (bytestream2_get_bytes_left(&s->g) < 3 * s->ncomponents) {
+ av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for %d components in SIZ\n", s->ncomponents);
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (i = 0; i < s->ncomponents; i++) { // Ssiz_i XRsiz_i, YRsiz_i
+ uint8_t x = bytestream2_get_byteu(&s->g);
+ s->cbps[i] = (x & 0x7f) + 1;
+ s->precision = FFMAX(s->cbps[i], s->precision);
+ s->sgnd[i] = !!(x & 0x80);
+ s->cdx[i] = bytestream2_get_byteu(&s->g);
+ s->cdy[i] = bytestream2_get_byteu(&s->g);
+ if ( !s->cdx[i] || s->cdx[i] == 3 || s->cdx[i] > 4
+ || !s->cdy[i] || s->cdy[i] == 3 || s->cdy[i] > 4) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid sample separation %d/%d\n", s->cdx[i], s->cdy[i]);
+ return AVERROR_INVALIDDATA;
+ }
+ log2_chroma_wh |= s->cdy[i] >> 1 << i * 4 | s->cdx[i] >> 1 << i * 4 + 2;
+ }
+
+ s->numXtiles = ff_jpeg2000_ceildiv(s->width - s->tile_offset_x, s->tile_width);
+ s->numYtiles = ff_jpeg2000_ceildiv(s->height - s->tile_offset_y, s->tile_height);
+
+ if (s->numXtiles * (uint64_t)s->numYtiles > INT_MAX/sizeof(*s->tile)) {
+ s->numXtiles = s->numYtiles = 0;
+ return AVERROR(EINVAL);
+ }
+
+ s->tile = av_mallocz_array(s->numXtiles * s->numYtiles, sizeof(*s->tile));
+ if (!s->tile) {
+ s->numXtiles = s->numYtiles = 0;
+ return AVERROR(ENOMEM);
+ }
+
+ for (i = 0; i < s->numXtiles * s->numYtiles; i++) {
+ Jpeg2000Tile *tile = s->tile + i;
+
+ tile->comp = av_mallocz(s->ncomponents * sizeof(*tile->comp));
+ if (!tile->comp)
+ return AVERROR(ENOMEM);
+ }
+
+ /* 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));
+ if (ret < 0)
+ return ret;
+
+ if (s->avctx->profile == FF_PROFILE_JPEG2000_DCINEMA_2K ||
+ s->avctx->profile == FF_PROFILE_JPEG2000_DCINEMA_4K) {
+ possible_fmts = xyz_pix_fmts;
+ possible_fmts_nb = FF_ARRAY_ELEMS(xyz_pix_fmts);
+ } else {
+ switch (s->colour_space) {
+ case 16:
+ possible_fmts = rgb_pix_fmts;
+ possible_fmts_nb = FF_ARRAY_ELEMS(rgb_pix_fmts);
+ break;
+ case 17:
+ possible_fmts = gray_pix_fmts;
+ possible_fmts_nb = FF_ARRAY_ELEMS(gray_pix_fmts);
+ break;
+ case 18:
+ possible_fmts = yuv_pix_fmts;
+ possible_fmts_nb = FF_ARRAY_ELEMS(yuv_pix_fmts);
+ break;
+ default:
+ possible_fmts = all_pix_fmts;
+ possible_fmts_nb = FF_ARRAY_ELEMS(all_pix_fmts);
+ break;
+ }
+ }
+ for (i = 0; i < possible_fmts_nb; ++i) {
+ if (pix_fmt_match(possible_fmts[i], ncomponents, s->precision, log2_chroma_wh, s->pal8)) {
+ s->avctx->pix_fmt = possible_fmts[i];
+ break;
+ }
+ }
+
+ if (i == possible_fmts_nb) {
+ if (ncomponents == 4 &&
+ s->cdy[0] == 1 && s->cdx[0] == 1 &&
+ s->cdy[1] == 1 && s->cdx[1] == 1 &&
+ s->cdy[2] == s->cdy[3] && s->cdx[2] == s->cdx[3]) {
+ if (s->precision == 8 && s->cdy[2] == 2 && s->cdx[2] == 2 && !s->pal8) {
+ s->avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
+ s->cdef[0] = 0;
+ s->cdef[1] = 1;
+ s->cdef[2] = 2;
+ s->cdef[3] = 3;
+ i = 0;
+ }
+ }
+ }
+
+
+ if (i == possible_fmts_nb) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Unknown pix_fmt, profile: %d, colour_space: %d, "
+ "components: %d, precision: %d\n"
+ "cdx[0]: %d, cdy[0]: %d\n"
+ "cdx[1]: %d, cdy[1]: %d\n"
+ "cdx[2]: %d, cdy[2]: %d\n"
+ "cdx[3]: %d, cdy[3]: %d\n",
+ s->avctx->profile, s->colour_space, ncomponents, s->precision,
+ s->cdx[0],
+ s->cdy[0],
+ ncomponents > 1 ? s->cdx[1] : 0,
+ ncomponents > 1 ? s->cdy[1] : 0,
+ ncomponents > 2 ? s->cdx[2] : 0,
+ ncomponents > 2 ? s->cdy[2] : 0,
+ ncomponents > 3 ? s->cdx[3] : 0,
+ ncomponents > 3 ? s->cdy[3] : 0);
+ return AVERROR_PATCHWELCOME;
+ }
+ s->avctx->bits_per_raw_sample = s->precision;
+ return 0;
+}
+
+/* get common part for COD and COC segments */
+static int get_cox(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c)
+{
+ uint8_t byte;
+
+ if (bytestream2_get_bytes_left(&s->g) < 5) {
+ av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for COX\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* nreslevels = number of resolution levels
+ = number of decomposition level +1 */
+ c->nreslevels = bytestream2_get_byteu(&s->g) + 1;
+ if (c->nreslevels >= JPEG2000_MAX_RESLEVELS) {
+ av_log(s->avctx, AV_LOG_ERROR, "nreslevels %d is invalid\n", c->nreslevels);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (c->nreslevels <= s->reduction_factor) {
+ /* we are forced to update reduction_factor as its requested value is
+ not compatible with this bitstream, and as we might have used it
+ already in setup earlier we have to fail this frame until
+ reinitialization is implemented */
+ av_log(s->avctx, AV_LOG_ERROR, "reduction_factor too large for this bitstream, max is %d\n", c->nreslevels - 1);
+ s->reduction_factor = c->nreslevels - 1;
+ return AVERROR(EINVAL);
+ }
+
+ /* compute number of resolution levels to decode */
+ c->nreslevels2decode = c->nreslevels - s->reduction_factor;
+
+ c->log2_cblk_width = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk width
+ c->log2_cblk_height = (bytestream2_get_byteu(&s->g) & 15) + 2; // cblk height
+
+ if (c->log2_cblk_width > 10 || c->log2_cblk_height > 10 ||
+ c->log2_cblk_width + c->log2_cblk_height > 12) {
+ av_log(s->avctx, AV_LOG_ERROR, "cblk size invalid\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ c->cblk_style = bytestream2_get_byteu(&s->g);
+ if (c->cblk_style != 0) { // cblk style
+ av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style);
+ if (c->cblk_style & JPEG2000_CBLK_BYPASS)
+ av_log(s->avctx, AV_LOG_WARNING, "Selective arithmetic coding bypass\n");
+ }
+ c->transform = bytestream2_get_byteu(&s->g); // DWT transformation type
+ /* set integer 9/7 DWT in case of BITEXACT flag */
+ if ((s->avctx->flags & AV_CODEC_FLAG_BITEXACT) && (c->transform == FF_DWT97))
+ c->transform = FF_DWT97_INT;
+ else if (c->transform == FF_DWT53) {
+ s->avctx->properties |= FF_CODEC_PROPERTY_LOSSLESS;
+ }
+
+ if (c->csty & JPEG2000_CSTY_PREC) {
+ int i;
+ for (i = 0; i < c->nreslevels; i++) {
+ byte = bytestream2_get_byte(&s->g);
+ c->log2_prec_widths[i] = byte & 0x0F; // precinct PPx
+ c->log2_prec_heights[i] = (byte >> 4) & 0x0F; // precinct PPy
+ if (i)
+ if (c->log2_prec_widths[i] == 0 || c->log2_prec_heights[i] == 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "PPx %d PPy %d invalid\n",
+ c->log2_prec_widths[i], c->log2_prec_heights[i]);
+ c->log2_prec_widths[i] = c->log2_prec_heights[i] = 1;
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ } else {
+ memset(c->log2_prec_widths , 15, sizeof(c->log2_prec_widths ));
+ memset(c->log2_prec_heights, 15, sizeof(c->log2_prec_heights));
+ }
+ return 0;
+}
+
+/* get coding parameters for a particular tile or whole image*/
+static int get_cod(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c,
+ uint8_t *properties)
+{
+ Jpeg2000CodingStyle tmp;
+ int compno, ret;
+
+ if (bytestream2_get_bytes_left(&s->g) < 5) {
+ av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for COD\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ tmp.csty = bytestream2_get_byteu(&s->g);
+
+ // get progression order
+ tmp.prog_order = bytestream2_get_byteu(&s->g);
+
+ tmp.nlayers = bytestream2_get_be16u(&s->g);
+ tmp.mct = bytestream2_get_byteu(&s->g); // multiple component transformation
+
+ if (tmp.mct && s->ncomponents < 3) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "MCT %"PRIu8" with too few components (%d)\n",
+ tmp.mct, s->ncomponents);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if ((ret = get_cox(s, &tmp)) < 0)
+ return ret;
+
+ for (compno = 0; compno < s->ncomponents; compno++)
+ if (!(properties[compno] & HAD_COC))
+ memcpy(c + compno, &tmp, sizeof(tmp));
+ return 0;
+}
+
+/* Get coding parameters for a component in the whole image or a
+ * particular tile. */
+static int get_coc(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c,
+ uint8_t *properties)
+{
+ int compno, ret;
+
+ if (bytestream2_get_bytes_left(&s->g) < 2) {
+ av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for COC\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ compno = bytestream2_get_byteu(&s->g);
+
+ if (compno >= s->ncomponents) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid compno %d. There are %d components in the image.\n",
+ compno, s->ncomponents);
+ return AVERROR_INVALIDDATA;
+ }
+
+ c += compno;
+ c->csty = bytestream2_get_byteu(&s->g);
+
+ if ((ret = get_cox(s, c)) < 0)
+ return ret;
+
+ properties[compno] |= HAD_COC;
+ return 0;
+}
+
+/* Get common part for QCD and QCC segments. */
+static int get_qcx(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q)
+{
+ int i, x;
+
+ if (bytestream2_get_bytes_left(&s->g) < 1)
+ return AVERROR_INVALIDDATA;
+
+ x = bytestream2_get_byteu(&s->g); // Sqcd
+
+ q->nguardbits = x >> 5;
+ q->quantsty = x & 0x1f;
+
+ if (q->quantsty == JPEG2000_QSTY_NONE) {
+ n -= 3;
+ if (bytestream2_get_bytes_left(&s->g) < n ||
+ n > JPEG2000_MAX_DECLEVELS*3)
+ return AVERROR_INVALIDDATA;
+ for (i = 0; i < n; i++)
+ q->expn[i] = bytestream2_get_byteu(&s->g) >> 3;
+ } else if (q->quantsty == JPEG2000_QSTY_SI) {
+ if (bytestream2_get_bytes_left(&s->g) < 2)
+ return AVERROR_INVALIDDATA;
+ x = bytestream2_get_be16u(&s->g);
+ q->expn[0] = x >> 11;
+ q->mant[0] = x & 0x7ff;
+ for (i = 1; i < JPEG2000_MAX_DECLEVELS * 3; i++) {
+ int curexpn = FFMAX(0, q->expn[0] - (i - 1) / 3);
+ q->expn[i] = curexpn;
+ q->mant[i] = q->mant[0];
+ }
+ } else {
+ n = (n - 3) >> 1;
+ if (bytestream2_get_bytes_left(&s->g) < 2 * n ||
+ n > JPEG2000_MAX_DECLEVELS*3)
+ return AVERROR_INVALIDDATA;
+ for (i = 0; i < n; i++) {
+ x = bytestream2_get_be16u(&s->g);
+ q->expn[i] = x >> 11;
+ q->mant[i] = x & 0x7ff;
+ }
+ }
+ return 0;
+}
+
+/* Get quantization parameters for a particular tile or a whole image. */
+static int get_qcd(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q,
+ uint8_t *properties)
+{
+ Jpeg2000QuantStyle tmp;
+ int compno, ret;
+
+ memset(&tmp, 0, sizeof(tmp));
+
+ if ((ret = get_qcx(s, n, &tmp)) < 0)
+ return ret;
+ for (compno = 0; compno < s->ncomponents; compno++)
+ if (!(properties[compno] & HAD_QCC))
+ memcpy(q + compno, &tmp, sizeof(tmp));
+ return 0;
+}
+
+/* Get quantization parameters for a component in the whole image
+ * on in a particular tile. */
+static int get_qcc(Jpeg2000DecoderContext *s, int n, Jpeg2000QuantStyle *q,
+ uint8_t *properties)
+{
+ int compno;
+
+ if (bytestream2_get_bytes_left(&s->g) < 1)
+ return AVERROR_INVALIDDATA;
+
+ compno = bytestream2_get_byteu(&s->g);
+
+ if (compno >= s->ncomponents) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid compno %d. There are %d components in the image.\n",
+ compno, s->ncomponents);
+ return AVERROR_INVALIDDATA;
+ }
+
+ properties[compno] |= HAD_QCC;
+ return get_qcx(s, n - 1, q + compno);
+}
+
+static int get_poc(Jpeg2000DecoderContext *s, int size, Jpeg2000POC *p)
+{
+ int i;
+ int elem_size = s->ncomponents <= 257 ? 7 : 9;
+ Jpeg2000POC tmp = {{{0}}};
+
+ if (bytestream2_get_bytes_left(&s->g) < 5 || size < 2 + elem_size) {
+ av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for POC\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (elem_size > 7) {
+ avpriv_request_sample(s->avctx, "Fat POC not supported");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ tmp.nb_poc = (size - 2) / elem_size;
+ if (tmp.nb_poc > MAX_POCS) {
+ avpriv_request_sample(s->avctx, "Too many POCs (%d)", tmp.nb_poc);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ for (i = 0; i<tmp.nb_poc; i++) {
+ Jpeg2000POCEntry *e = &tmp.poc[i];
+ e->RSpoc = bytestream2_get_byteu(&s->g);
+ e->CSpoc = bytestream2_get_byteu(&s->g);
+ e->LYEpoc = bytestream2_get_be16u(&s->g);
+ e->REpoc = bytestream2_get_byteu(&s->g);
+ e->CEpoc = bytestream2_get_byteu(&s->g);
+ e->Ppoc = bytestream2_get_byteu(&s->g);
+ if (!e->CEpoc)
+ e->CEpoc = 256;
+ if (e->CEpoc > s->ncomponents)
+ e->CEpoc = s->ncomponents;
+ if ( e->RSpoc >= e->REpoc || e->REpoc > 33
+ || e->CSpoc >= e->CEpoc || e->CEpoc > s->ncomponents
+ || !e->LYEpoc) {
+ av_log(s->avctx, AV_LOG_ERROR, "POC Entry %d is invalid (%d, %d, %d, %d, %d, %d)\n", i,
+ e->RSpoc, e->CSpoc, e->LYEpoc, e->REpoc, e->CEpoc, e->Ppoc
+ );
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if (!p->nb_poc || p->is_default) {
+ *p = tmp;
+ } else {
+ if (p->nb_poc + tmp.nb_poc > MAX_POCS) {
+ av_log(s->avctx, AV_LOG_ERROR, "Insufficient space for POC\n");
+ return AVERROR_INVALIDDATA;
+ }
+ memcpy(p->poc + p->nb_poc, tmp.poc, tmp.nb_poc * sizeof(tmp.poc[0]));
+ p->nb_poc += tmp.nb_poc;
+ }
+
+ p->is_default = 0;
+
+ return 0;
+}
+
+
+/* Get start of tile segment. */
+static int get_sot(Jpeg2000DecoderContext *s, int n)
+{
+ Jpeg2000TilePart *tp;
+ uint16_t Isot;
+ uint32_t Psot;
+ unsigned TPsot;
+
+ if (bytestream2_get_bytes_left(&s->g) < 8)
+ return AVERROR_INVALIDDATA;
+
+ s->curtileno = 0;
+ Isot = bytestream2_get_be16u(&s->g); // Isot
+ if (Isot >= s->numXtiles * s->numYtiles)
+ return AVERROR_INVALIDDATA;
+
+ s->curtileno = Isot;
+ Psot = bytestream2_get_be32u(&s->g); // Psot
+ TPsot = bytestream2_get_byteu(&s->g); // TPsot
+
+ /* Read TNSot but not used */
+ bytestream2_get_byteu(&s->g); // TNsot
+
+ if (!Psot)
+ Psot = bytestream2_get_bytes_left(&s->g) + n + 2;
+
+ if (Psot > bytestream2_get_bytes_left(&s->g) + n + 2) {
+ av_log(s->avctx, AV_LOG_ERROR, "Psot %"PRIu32" too big\n", Psot);
+ return AVERROR_INVALIDDATA;
+ }
+
+ av_assert0(TPsot < FF_ARRAY_ELEMS(s->tile[Isot].tile_part));
+
+ s->tile[Isot].tp_idx = TPsot;
+ tp = s->tile[Isot].tile_part + TPsot;
+ tp->tile_index = Isot;
+ tp->tp_end = s->g.buffer + Psot - n - 2;
+
+ if (!TPsot) {
+ Jpeg2000Tile *tile = s->tile + s->curtileno;
+
+ /* copy defaults */
+ memcpy(tile->codsty, s->codsty, s->ncomponents * sizeof(Jpeg2000CodingStyle));
+ memcpy(tile->qntsty, s->qntsty, s->ncomponents * sizeof(Jpeg2000QuantStyle));
+ memcpy(&tile->poc , &s->poc , sizeof(tile->poc));
+ tile->poc.is_default = 1;
+ }
+
+ return 0;
+}
+
+/* Tile-part lengths: see ISO 15444-1:2002, section A.7.1
+ * Used to know the number of tile parts and lengths.
+ * There may be multiple TLMs in the header.
+ * TODO: The function is not used for tile-parts management, nor anywhere else.
+ * It can be useful to allocate memory for tile parts, before managing the SOT
+ * markers. Parsing the TLM header is needed to increment the input header
+ * buffer.
+ * This marker is mandatory for DCI. */
+static uint8_t get_tlm(Jpeg2000DecoderContext *s, int n)
+{
+ uint8_t Stlm, ST, SP, tile_tlm, i;
+ bytestream2_get_byte(&s->g); /* Ztlm: skipped */
+ Stlm = bytestream2_get_byte(&s->g);
+
+ // too complex ? ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
+ ST = (Stlm >> 4) & 0x03;
+ // TODO: Manage case of ST = 0b11 --> raise error
+ SP = (Stlm >> 6) & 0x01;
+ tile_tlm = (n - 4) / ((SP + 1) * 2 + ST);
+ for (i = 0; i < tile_tlm; i++) {
+ switch (ST) {
+ case 0:
+ break;
+ case 1:
+ bytestream2_get_byte(&s->g);
+ break;
+ case 2:
+ bytestream2_get_be16(&s->g);
+ break;
+ case 3:
+ bytestream2_get_be32(&s->g);
+ break;
+ }
+ if (SP == 0) {
+ bytestream2_get_be16(&s->g);
+ } else {
+ bytestream2_get_be32(&s->g);
+ }
+ }
+ return 0;
+}
+
+static uint8_t get_plt(Jpeg2000DecoderContext *s, int n)
+{
+ int i;
+
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "PLT marker at pos 0x%X\n", bytestream2_tell(&s->g) - 4);
+
+ /*Zplt =*/ bytestream2_get_byte(&s->g);
+
+ for (i = 0; i < n - 3; i++) {
+ bytestream2_get_byte(&s->g);
+ }
+
+ return 0;
+}
+
+static int init_tile(Jpeg2000DecoderContext *s, int tileno)
+{
+ int compno;
+ int tilex = tileno % s->numXtiles;
+ int tiley = tileno / s->numXtiles;
+ Jpeg2000Tile *tile = s->tile + tileno;
+
+ if (!tile->comp)
+ return AVERROR(ENOMEM);
+
+ tile->coord[0][0] = av_clip(tilex * (int64_t)s->tile_width + s->tile_offset_x, s->image_offset_x, s->width);
+ tile->coord[0][1] = av_clip((tilex + 1) * (int64_t)s->tile_width + s->tile_offset_x, s->image_offset_x, s->width);
+ tile->coord[1][0] = av_clip(tiley * (int64_t)s->tile_height + s->tile_offset_y, s->image_offset_y, s->height);
+ tile->coord[1][1] = av_clip((tiley + 1) * (int64_t)s->tile_height + s->tile_offset_y, s->image_offset_y, s->height);
+
+ for (compno = 0; compno < s->ncomponents; compno++) {
+ Jpeg2000Component *comp = tile->comp + compno;
+ Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+ Jpeg2000QuantStyle *qntsty = tile->qntsty + compno;
+ int ret; // global bandno
+
+ comp->coord_o[0][0] = tile->coord[0][0];
+ 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[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);
+ comp->coord[1][0] = ff_jpeg2000_ceildivpow2(comp->coord_o[1][0], s->reduction_factor);
+ comp->coord[1][1] = ff_jpeg2000_ceildivpow2(comp->coord_o[1][1], s->reduction_factor);
+
+ if (ret = ff_jpeg2000_init_component(comp, codsty, qntsty,
+ s->cbps[compno], s->cdx[compno],
+ s->cdy[compno], s->avctx))
+ return ret;
+ }
+ return 0;
+}
+
+/* Read the number of coding passes. */
+static int getnpasses(Jpeg2000DecoderContext *s)
+{
+ int num;
+ if (!get_bits(s, 1))
+ return 1;
+ if (!get_bits(s, 1))
+ return 2;
+ if ((num = get_bits(s, 2)) != 3)
+ return num < 0 ? num : 3 + num;
+ if ((num = get_bits(s, 5)) != 31)
+ return num < 0 ? num : 6 + num;
+ num = get_bits(s, 7);
+ return num < 0 ? num : 37 + num;
+}
+
+static int getlblockinc(Jpeg2000DecoderContext *s)
+{
+ int res = 0, ret;
+ while (ret = get_bits(s, 1)) {
+ if (ret < 0)
+ return ret;
+ res++;
+ }
+ return res;
+}
+
+static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, int *tp_index,
+ Jpeg2000CodingStyle *codsty,
+ Jpeg2000ResLevel *rlevel, int precno,
+ int layno, uint8_t *expn, int numgbits)
+{
+ int bandno, cblkno, ret, nb_code_blocks;
+ int cwsno;
+
+ if (layno < rlevel->band[0].prec[precno].decoded_layers)
+ return 0;
+ rlevel->band[0].prec[precno].decoded_layers = layno + 1;
+
+ 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;
+ }
+ }
+
+ if (bytestream2_peek_be32(&s->g) == JPEG2000_SOP_FIXED_BYTES)
+ bytestream2_skip(&s->g, JPEG2000_SOP_BYTE_LENGTH);
+
+ if (!(ret = get_bits(s, 1))) {
+ jpeg2000_flush(s);
+ return 0;
+ } else if (ret < 0)
+ return ret;
+
+ for (bandno = 0; bandno < rlevel->nbands; bandno++) {
+ Jpeg2000Band *band = rlevel->band + bandno;
+ Jpeg2000Prec *prec = band->prec + precno;
+
+ if (band->coord[0][0] == band->coord[0][1] ||
+ band->coord[1][0] == band->coord[1][1])
+ continue;
+ nb_code_blocks = prec->nb_codeblocks_height *
+ prec->nb_codeblocks_width;
+ for (cblkno = 0; cblkno < nb_code_blocks; cblkno++) {
+ Jpeg2000Cblk *cblk = prec->cblk + cblkno;
+ int incl, newpasses, llen;
+
+ if (cblk->npasses)
+ incl = get_bits(s, 1);
+ else
+ incl = tag_tree_decode(s, prec->cblkincl + cblkno, layno + 1) == layno;
+ if (!incl)
+ continue;
+ else if (incl < 0)
+ return incl;
+
+ if (!cblk->npasses) {
+ int v = expn[bandno] + numgbits - 1 -
+ tag_tree_decode(s, prec->zerobits + cblkno, 100);
+ if (v < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "nonzerobits %d invalid\n", v);
+ return AVERROR_INVALIDDATA;
+ }
+ cblk->nonzerobits = v;
+ }
+ if ((newpasses = getnpasses(s)) < 0)
+ return newpasses;
+ av_assert2(newpasses > 0);
+ if (cblk->npasses + newpasses >= JPEG2000_MAX_PASSES) {
+ avpriv_request_sample(s->avctx, "Too many passes");
+ return AVERROR_PATCHWELCOME;
+ }
+ if ((llen = getlblockinc(s)) < 0)
+ return llen;
+ if (cblk->lblock + llen + av_log2(newpasses) > 16) {
+ avpriv_request_sample(s->avctx,
+ "Block with length beyond 16 bits");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ cblk->lblock += llen;
+
+ cblk->nb_lengthinc = 0;
+ cblk->nb_terminationsinc = 0;
+ do {
+ int newpasses1 = 0;
+
+ while (newpasses1 < newpasses) {
+ newpasses1 ++;
+ if (needs_termination(codsty->cblk_style, cblk->npasses + newpasses1 - 1)) {
+ cblk->nb_terminationsinc ++;
+ break;
+ }
+ }
+
+ if ((ret = get_bits(s, av_log2(newpasses1) + cblk->lblock)) < 0)
+ return ret;
+ if (ret > sizeof(cblk->data)) {
+ avpriv_request_sample(s->avctx,
+ "Block with lengthinc greater than %"SIZE_SPECIFIER"",
+ sizeof(cblk->data));
+ return AVERROR_PATCHWELCOME;
+ }
+ cblk->lengthinc[cblk->nb_lengthinc++] = ret;
+ cblk->npasses += newpasses1;
+ newpasses -= newpasses1;
+ } while(newpasses);
+ }
+ }
+ jpeg2000_flush(s);
+
+ 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));
+ }
+
+ for (bandno = 0; bandno < rlevel->nbands; bandno++) {
+ Jpeg2000Band *band = rlevel->band + bandno;
+ Jpeg2000Prec *prec = band->prec + precno;
+
+ nb_code_blocks = prec->nb_codeblocks_height * prec->nb_codeblocks_width;
+ for (cblkno = 0; cblkno < nb_code_blocks; cblkno++) {
+ Jpeg2000Cblk *cblk = prec->cblk + cblkno;
+ for (cwsno = 0; cwsno < cblk->nb_lengthinc; cwsno ++) {
+ if ( bytestream2_get_bytes_left(&s->g) < cblk->lengthinc[cwsno]
+ || sizeof(cblk->data) < cblk->length + cblk->lengthinc[cwsno] + 4
+ ) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Block length %"PRIu16" or lengthinc %d is too large, left %d\n",
+ cblk->length, cblk->lengthinc[cwsno], bytestream2_get_bytes_left(&s->g));
+ return AVERROR_INVALIDDATA;
+ }
+
+ bytestream2_get_bufferu(&s->g, cblk->data + cblk->length, cblk->lengthinc[cwsno]);
+ cblk->length += cblk->lengthinc[cwsno];
+ cblk->lengthinc[cwsno] = 0;
+ if (cblk->nb_terminationsinc) {
+ cblk->nb_terminationsinc--;
+ cblk->nb_terminations++;
+ cblk->data[cblk->length++] = 0xFF;
+ cblk->data[cblk->length++] = 0xFF;
+ cblk->data_start[cblk->nb_terminations] = cblk->length;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+static int jpeg2000_decode_packets_po_iteration(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
+ int RSpoc, int CSpoc,
+ int LYEpoc, int REpoc, int CEpoc,
+ int Ppoc, int *tp_index)
+{
+ int ret = 0;
+ int layno, reslevelno, compno, precno, ok_reslevel;
+ int x, y;
+ int step_x, step_y;
+
+ switch (Ppoc) {
+ case JPEG2000_PGOD_RLCP:
+ av_log(s->avctx, AV_LOG_DEBUG, "Progression order RLCP\n");
+ ok_reslevel = 1;
+ for (reslevelno = RSpoc; ok_reslevel && reslevelno < REpoc; reslevelno++) {
+ ok_reslevel = 0;
+ for (layno = 0; layno < LYEpoc; layno++) {
+ for (compno = CSpoc; compno < CEpoc; compno++) {
+ Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+ Jpeg2000QuantStyle *qntsty = tile->qntsty + compno;
+ if (reslevelno < codsty->nreslevels) {
+ Jpeg2000ResLevel *rlevel = tile->comp[compno].reslevel +
+ reslevelno;
+ ok_reslevel = 1;
+ for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++)
+ if ((ret = jpeg2000_decode_packet(s, tile, tp_index,
+ codsty, rlevel,
+ precno, layno,
+ qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+ qntsty->nguardbits)) < 0)
+ return ret;
+ }
+ }
+ }
+ }
+ break;
+
+ case JPEG2000_PGOD_LRCP:
+ av_log(s->avctx, AV_LOG_DEBUG, "Progression order LRCP\n");
+ for (layno = 0; layno < LYEpoc; layno++) {
+ ok_reslevel = 1;
+ for (reslevelno = RSpoc; ok_reslevel && reslevelno < REpoc; reslevelno++) {
+ ok_reslevel = 0;
+ for (compno = CSpoc; compno < CEpoc; compno++) {
+ Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+ Jpeg2000QuantStyle *qntsty = tile->qntsty + compno;
+ if (reslevelno < codsty->nreslevels) {
+ Jpeg2000ResLevel *rlevel = tile->comp[compno].reslevel +
+ reslevelno;
+ ok_reslevel = 1;
+ for (precno = 0; precno < rlevel->num_precincts_x * rlevel->num_precincts_y; precno++)
+ if ((ret = jpeg2000_decode_packet(s, tile, tp_index,
+ codsty, rlevel,
+ precno, layno,
+ qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+ qntsty->nguardbits)) < 0)
+ return ret;
+ }
+ }
+ }
+ }
+ break;
+
+ case JPEG2000_PGOD_CPRL:
+ av_log(s->avctx, AV_LOG_DEBUG, "Progression order CPRL\n");
+ for (compno = CSpoc; compno < CEpoc; compno++) {
+ Jpeg2000Component *comp = tile->comp + compno;
+ Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+ Jpeg2000QuantStyle *qntsty = tile->qntsty + compno;
+ step_x = 32;
+ step_y = 32;
+
+ for (reslevelno = RSpoc; reslevelno < FFMIN(codsty->nreslevels, REpoc); 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);
+ }
+ av_assert0(step_x < 32 && step_y < 32);
+ step_x = 1<<step_x;
+ step_y = 1<<step_y;
+
+ for (y = tile->coord[1][0]; y < tile->coord[1][1]; y = (y/step_y + 1)*step_y) {
+ for (x = tile->coord[0][0]; x < tile->coord[0][1]; x = (x/step_x + 1)*step_x) {
+ 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 xc = x / s->cdx[compno];
+ int yc = y / s->cdy[compno];
+
+ if (yc % (1 << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check
+ continue;
+
+ if (xc % (1 << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check
+ 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_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;
+
+ precno = prcx + rlevel->num_precincts_x * prcy;
+
+ if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y) {
+ av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n",
+ prcx, prcy, rlevel->num_precincts_x, rlevel->num_precincts_y);
+ continue;
+ }
+
+ for (layno = 0; layno < LYEpoc; layno++) {
+ if ((ret = jpeg2000_decode_packet(s, tile, tp_index, codsty, rlevel,
+ precno, layno,
+ qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+ qntsty->nguardbits)) < 0)
+ return ret;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case JPEG2000_PGOD_RPCL:
+ av_log(s->avctx, AV_LOG_WARNING, "Progression order RPCL\n");
+ ok_reslevel = 1;
+ for (reslevelno = RSpoc; ok_reslevel && reslevelno < REpoc; reslevelno++) {
+ ok_reslevel = 0;
+ step_x = 30;
+ step_y = 30;
+ for (compno = CSpoc; compno < CEpoc; compno++) {
+ Jpeg2000Component *comp = tile->comp + compno;
+ Jpeg2000CodingStyle *codsty = tile->codsty + 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<<step_x;
+ step_y = 1<<step_y;
+
+ for (y = tile->coord[1][0]; y < tile->coord[1][1]; y = (y/step_y + 1)*step_y) {
+ for (x = tile->coord[0][0]; x < tile->coord[0][1]; x = (x/step_x + 1)*step_x) {
+ for (compno = CSpoc; compno < CEpoc; compno++) {
+ Jpeg2000Component *comp = tile->comp + compno;
+ Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+ Jpeg2000QuantStyle *qntsty = tile->qntsty + compno;
+ uint8_t reducedresno = codsty->nreslevels - 1 -reslevelno; // ==> N_L - r
+ Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;
+ unsigned prcx, prcy;
+
+ int xc = x / s->cdx[compno];
+ int yc = y / s->cdy[compno];
+
+ if (reslevelno >= codsty->nreslevels)
+ continue;
+
+ if (yc % (1 << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check
+ continue;
+
+ if (xc % (1 << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check
+ 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_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;
+
+ precno = prcx + rlevel->num_precincts_x * prcy;
+
+ ok_reslevel = 1;
+ if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y) {
+ av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n",
+ prcx, prcy, rlevel->num_precincts_x, rlevel->num_precincts_y);
+ continue;
+ }
+
+ for (layno = 0; layno < LYEpoc; layno++) {
+ if ((ret = jpeg2000_decode_packet(s, tile, tp_index,
+ codsty, rlevel,
+ precno, layno,
+ qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+ qntsty->nguardbits)) < 0)
+ return ret;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ case JPEG2000_PGOD_PCRL:
+ av_log(s->avctx, AV_LOG_WARNING, "Progression order PCRL\n");
+ step_x = 32;
+ step_y = 32;
+ for (compno = CSpoc; compno < CEpoc; compno++) {
+ Jpeg2000Component *comp = tile->comp + compno;
+ Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+
+ for (reslevelno = RSpoc; reslevelno < FFMIN(codsty->nreslevels, REpoc); 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);
+ }
+ }
+ step_x = 1<<step_x;
+ step_y = 1<<step_y;
+
+ for (y = tile->coord[1][0]; y < tile->coord[1][1]; y = (y/step_y + 1)*step_y) {
+ for (x = tile->coord[0][0]; x < tile->coord[0][1]; x = (x/step_x + 1)*step_x) {
+ for (compno = CSpoc; compno < CEpoc; compno++) {
+ 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];
+
+ 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;
+
+ if (yc % (1 << (rlevel->log2_prec_height + reducedresno)) && y != tile->coord[1][0]) //FIXME this is a subset of the check
+ continue;
+
+ if (xc % (1 << (rlevel->log2_prec_width + reducedresno)) && x != tile->coord[0][0]) //FIXME this is a subset of the check
+ 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_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;
+
+ precno = prcx + rlevel->num_precincts_x * prcy;
+
+ if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y) {
+ av_log(s->avctx, AV_LOG_WARNING, "prc %d %d outside limits %d %d\n",
+ prcx, prcy, rlevel->num_precincts_x, rlevel->num_precincts_y);
+ continue;
+ }
+
+ for (layno = 0; layno < LYEpoc; layno++) {
+ if ((ret = jpeg2000_decode_packet(s, tile, tp_index, codsty, rlevel,
+ precno, layno,
+ qntsty->expn + (reslevelno ? 3 * (reslevelno - 1) + 1 : 0),
+ qntsty->nguardbits)) < 0)
+ return ret;
+ }
+ }
+ }
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
+{
+ int ret = AVERROR_BUG;
+ int i;
+ int tp_index = 0;
+
+ s->bit_index = 8;
+ if (tile->poc.nb_poc) {
+ for (i=0; i<tile->poc.nb_poc; i++) {
+ Jpeg2000POCEntry *e = &tile->poc.poc[i];
+ ret = jpeg2000_decode_packets_po_iteration(s, tile,
+ e->RSpoc, e->CSpoc,
+ FFMIN(e->LYEpoc, tile->codsty[0].nlayers),
+ e->REpoc,
+ FFMIN(e->CEpoc, s->ncomponents),
+ e->Ppoc, &tp_index
+ );
+ if (ret < 0)
+ return ret;
+ }
+ } else {
+ ret = jpeg2000_decode_packets_po_iteration(s, tile,
+ 0, 0,
+ tile->codsty[0].nlayers,
+ 33,
+ s->ncomponents,
+ tile->codsty[0].prog_order,
+ &tp_index
+ );
+ }
+ /* EOC marker reached */
+ bytestream2_skip(&s->g, 2);
+
+ return ret;
+}
+
+/* TIER-1 routines */
+static void decode_sigpass(Jpeg2000T1Context *t1, int width, int height,
+ int bpno, int bandno,
+ int vert_causal_ctx_csty_symbol)
+{
+ int mask = 3 << (bpno - 1), y0, x, y;
+
+ for (y0 = 0; y0 < height; y0 += 4)
+ for (x = 0; x < width; x++)
+ for (y = y0; y < height && y < y0 + 4; y++) {
+ int flags_mask = -1;
+ if (vert_causal_ctx_csty_symbol && y == y0 + 3)
+ flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S);
+ if ((t1->flags[(y+1) * t1->stride + x+1] & JPEG2000_T1_SIG_NB & flags_mask)
+ && !(t1->flags[(y+1) * t1->stride + x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {
+ if (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[(y+1) * t1->stride + x+1] & flags_mask, bandno))) {
+ int xorbit, ctxno = ff_jpeg2000_getsgnctxno(t1->flags[(y+1) * t1->stride + x+1] & flags_mask, &xorbit);
+ if (t1->mqc.raw)
+ t1->data[(y) * t1->stride + x] = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ? -mask : mask;
+ else
+ t1->data[(y) * t1->stride + x] = (ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ctxno) ^ xorbit) ?
+ -mask : mask;
+
+ ff_jpeg2000_set_significance(t1, x, y,
+ t1->data[(y) * t1->stride + x] < 0);
+ }
+ t1->flags[(y + 1) * t1->stride + x + 1] |= JPEG2000_T1_VIS;
+ }
+ }
+}
+
+static void decode_refpass(Jpeg2000T1Context *t1, int width, int height,
+ int bpno, int vert_causal_ctx_csty_symbol)
+{
+ int phalf, nhalf;
+ int y0, x, y;
+
+ phalf = 1 << (bpno - 1);
+ nhalf = -phalf;
+
+ for (y0 = 0; y0 < height; y0 += 4)
+ for (x = 0; x < width; x++)
+ for (y = y0; y < height && y < y0 + 4; y++)
+ if ((t1->flags[(y + 1) * t1->stride + x + 1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS)) == JPEG2000_T1_SIG) {
+ int flags_mask = (vert_causal_ctx_csty_symbol && y == y0 + 3) ?
+ ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S) : -1;
+ int ctxno = ff_jpeg2000_getrefctxno(t1->flags[(y + 1) * t1->stride + x + 1] & flags_mask);
+ int r = ff_mqc_decode(&t1->mqc,
+ t1->mqc.cx_states + ctxno)
+ ? phalf : nhalf;
+ t1->data[(y) * t1->stride + x] += t1->data[(y) * t1->stride + x] < 0 ? -r : r;
+ t1->flags[(y + 1) * t1->stride + x + 1] |= JPEG2000_T1_REF;
+ }
+}
+
+static void decode_clnpass(Jpeg2000DecoderContext *s, Jpeg2000T1Context *t1,
+ int width, int height, int bpno, int bandno,
+ int seg_symbols, int vert_causal_ctx_csty_symbol)
+{
+ int mask = 3 << (bpno - 1), y0, x, y, runlen, dec;
+
+ for (y0 = 0; y0 < height; y0 += 4) {
+ for (x = 0; x < width; x++) {
+ int flags_mask = -1;
+ if (vert_causal_ctx_csty_symbol)
+ flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S);
+ if (y0 + 3 < height &&
+ !((t1->flags[(y0 + 1) * t1->stride + x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
+ (t1->flags[(y0 + 2) * t1->stride + x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
+ (t1->flags[(y0 + 3) * t1->stride + x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG)) ||
+ (t1->flags[(y0 + 4) * t1->stride + x + 1] & (JPEG2000_T1_SIG_NB | JPEG2000_T1_VIS | JPEG2000_T1_SIG) & flags_mask))) {
+ if (!ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_RL))
+ continue;
+ runlen = ff_mqc_decode(&t1->mqc,
+ t1->mqc.cx_states + MQC_CX_UNI);
+ runlen = (runlen << 1) | ff_mqc_decode(&t1->mqc,
+ t1->mqc.cx_states +
+ MQC_CX_UNI);
+ dec = 1;
+ } else {
+ runlen = 0;
+ dec = 0;
+ }
+
+ for (y = y0 + runlen; y < y0 + 4 && y < height; y++) {
+ int flags_mask = -1;
+ if (vert_causal_ctx_csty_symbol && y == y0 + 3)
+ flags_mask &= ~(JPEG2000_T1_SIG_S | JPEG2000_T1_SIG_SW | JPEG2000_T1_SIG_SE | JPEG2000_T1_SGN_S);
+ if (!dec) {
+ if (!(t1->flags[(y+1) * t1->stride + x+1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {
+ dec = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + ff_jpeg2000_getsigctxno(t1->flags[(y+1) * t1->stride + x+1] & flags_mask,
+ bandno));
+ }
+ }
+ if (dec) {
+ int xorbit;
+ int ctxno = ff_jpeg2000_getsgnctxno(t1->flags[(y + 1) * t1->stride + x + 1] & flags_mask,
+ &xorbit);
+ t1->data[(y) * t1->stride + x] = (ff_mqc_decode(&t1->mqc,
+ t1->mqc.cx_states + ctxno) ^
+ xorbit)
+ ? -mask : mask;
+ ff_jpeg2000_set_significance(t1, x, y, t1->data[(y) * t1->stride + x] < 0);
+ }
+ dec = 0;
+ t1->flags[(y + 1) * t1->stride + x + 1] &= ~JPEG2000_T1_VIS;
+ }
+ }
+ }
+ if (seg_symbols) {
+ int val;
+ val = ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
+ val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
+ val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
+ val = (val << 1) + ff_mqc_decode(&t1->mqc, t1->mqc.cx_states + MQC_CX_UNI);
+ if (val != 0xa)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Segmentation symbol value incorrect\n");
+ }
+}
+
+static int decode_cblk(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty,
+ Jpeg2000T1Context *t1, Jpeg2000Cblk *cblk,
+ int width, int height, int bandpos)
+{
+ int passno = cblk->npasses, pass_t = 2, bpno = cblk->nonzerobits - 1;
+ int pass_cnt = 0;
+ int vert_causal_ctx_csty_symbol = codsty->cblk_style & JPEG2000_CBLK_VSC;
+ int term_cnt = 0;
+ int coder_type;
+
+ av_assert0(width <= 1024U && height <= 1024U);
+ av_assert0(width*height <= 4096);
+
+ memset(t1->data, 0, t1->stride * height * sizeof(*t1->data));
+
+ /* If code-block contains no compressed data: nothing to do. */
+ if (!cblk->length)
+ return 0;
+
+ memset(t1->flags, 0, t1->stride * (height + 2) * sizeof(*t1->flags));
+
+ cblk->data[cblk->length] = 0xff;
+ cblk->data[cblk->length+1] = 0xff;
+ ff_mqc_initdec(&t1->mqc, cblk->data, 0, 1);
+
+ while (passno--) {
+ if (bpno < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "bpno became negative\n");
+ return AVERROR_INVALIDDATA;
+ }
+ switch(pass_t) {
+ case 0:
+ decode_sigpass(t1, width, height, bpno + 1, bandpos,
+ vert_causal_ctx_csty_symbol);
+ break;
+ case 1:
+ decode_refpass(t1, width, height, bpno + 1, vert_causal_ctx_csty_symbol);
+ break;
+ case 2:
+ av_assert2(!t1->mqc.raw);
+ decode_clnpass(s, t1, width, height, bpno + 1, bandpos,
+ codsty->cblk_style & JPEG2000_CBLK_SEGSYM,
+ vert_causal_ctx_csty_symbol);
+ break;
+ }
+ if (codsty->cblk_style & JPEG2000_CBLK_RESET) // XXX no testcase for just this
+ ff_mqc_init_contexts(&t1->mqc);
+
+ if (passno && (coder_type = needs_termination(codsty->cblk_style, pass_cnt))) {
+ if (term_cnt >= cblk->nb_terminations) {
+ av_log(s->avctx, AV_LOG_ERROR, "Missing needed termination \n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (FFABS(cblk->data + cblk->data_start[term_cnt + 1] - 2 - t1->mqc.bp) > 0) {
+ av_log(s->avctx, AV_LOG_WARNING, "Mid mismatch %"PTRDIFF_SPECIFIER" in pass %d of %d\n",
+ cblk->data + cblk->data_start[term_cnt + 1] - 2 - t1->mqc.bp,
+ pass_cnt, cblk->npasses);
+ }
+
+ ff_mqc_initdec(&t1->mqc, cblk->data + cblk->data_start[++term_cnt], coder_type == 2, 0);
+ }
+
+ pass_t++;
+ if (pass_t == 3) {
+ bpno--;
+ pass_t = 0;
+ }
+ pass_cnt ++;
+ }
+
+ if (cblk->data + cblk->length - 2*(term_cnt < cblk->nb_terminations) != 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);
+ }
+
+ return 0;
+}
+
+/* TODO: Verify dequantization for lossless case
+ * comp->data can be float or int
+ * band->stepsize can be float or int
+ * depending on the type of DWT transformation.
+ * see ISO/IEC 15444-1:2002 A.6.1 */
+
+/* Float dequantization of a codeblock.*/
+static void dequantization_float(int x, int y, Jpeg2000Cblk *cblk,
+ Jpeg2000Component *comp,
+ Jpeg2000T1Context *t1, Jpeg2000Band *band)
+{
+ int i, j;
+ int w = cblk->coord[0][1] - cblk->coord[0][0];
+ for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j) {
+ float *datap = &comp->f_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];
+ int *src = t1->data + j*t1->stride;
+ for (i = 0; i < w; ++i)
+ datap[i] = src[i] * band->f_stepsize;
+ }
+}
+
+/* Integer dequantization of a codeblock.*/
+static void dequantization_int(int x, int y, Jpeg2000Cblk *cblk,
+ Jpeg2000Component *comp,
+ Jpeg2000T1Context *t1, Jpeg2000Band *band)
+{
+ int i, j;
+ int w = cblk->coord[0][1] - cblk->coord[0][0];
+ for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j) {
+ int32_t *datap = &comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];
+ int *src = t1->data + j*t1->stride;
+ if (band->i_stepsize == 32768) {
+ for (i = 0; i < w; ++i)
+ datap[i] = src[i] / 2;
+ } else {
+ // This should be VERY uncommon
+ for (i = 0; i < w; ++i)
+ datap[i] = (src[i] * (int64_t)band->i_stepsize) / 65536;
+ }
+ }
+}
+
+static void dequantization_int_97(int x, int y, Jpeg2000Cblk *cblk,
+ Jpeg2000Component *comp,
+ Jpeg2000T1Context *t1, Jpeg2000Band *band)
+{
+ int i, j;
+ int w = cblk->coord[0][1] - cblk->coord[0][0];
+ for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j) {
+ int32_t *datap = &comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];
+ int *src = t1->data + j*t1->stride;
+ for (i = 0; i < w; ++i)
+ datap[i] = (src[i] * (int64_t)band->i_stepsize + (1<<15)) >> 16;
+ }
+}
+
+static inline void mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile)
+{
+ int i, csize = 1;
+ void *src[3];
+
+ for (i = 1; i < 3; i++) {
+ if (tile->codsty[0].transform != tile->codsty[i].transform) {
+ av_log(s->avctx, AV_LOG_ERROR, "Transforms mismatch, MCT not supported\n");
+ return;
+ }
+ if (memcmp(tile->comp[0].coord, tile->comp[i].coord, sizeof(tile->comp[0].coord))) {
+ av_log(s->avctx, AV_LOG_ERROR, "Coords mismatch, MCT not supported\n");
+ return;
+ }
+ }
+
+ for (i = 0; i < 3; i++)
+ if (tile->codsty[0].transform == FF_DWT97)
+ src[i] = tile->comp[i].f_data;
+ else
+ src[i] = tile->comp[i].i_data;
+
+ for (i = 0; i < 2; i++)
+ csize *= tile->comp[0].coord[i][1] - tile->comp[0].coord[i][0];
+
+ s->dsp.mct_decode[tile->codsty[0].transform](src[0], src[1], src[2], csize);
+}
+
+static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile,
+ AVFrame *picture)
+{
+ const AVPixFmtDescriptor *pixdesc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
+ int compno, reslevelno, bandno;
+ int x, y;
+ int planar = !!(pixdesc->flags & AV_PIX_FMT_FLAG_PLANAR);
+ int pixelsize = planar ? 1 : pixdesc->nb_components;
+
+ uint8_t *line;
+ Jpeg2000T1Context t1;
+
+ /* Loop on tile components */
+ for (compno = 0; compno < s->ncomponents; compno++) {
+ Jpeg2000Component *comp = tile->comp + compno;
+ Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+
+ t1.stride = (1<<codsty->log2_cblk_width) + 2;
+
+ /* Loop on resolution levels */
+ for (reslevelno = 0; reslevelno < codsty->nreslevels2decode; reslevelno++) {
+ Jpeg2000ResLevel *rlevel = comp->reslevel + reslevelno;
+ /* Loop on bands */
+ for (bandno = 0; bandno < rlevel->nbands; bandno++) {
+ int nb_precincts, precno;
+ Jpeg2000Band *band = rlevel->band + bandno;
+ int cblkno = 0, bandpos;
+
+ bandpos = bandno + (reslevelno > 0);
+
+ if (band->coord[0][0] == band->coord[0][1] ||
+ band->coord[1][0] == band->coord[1][1])
+ continue;
+
+ nb_precincts = rlevel->num_precincts_x * rlevel->num_precincts_y;
+ /* Loop on precincts */
+ for (precno = 0; precno < nb_precincts; precno++) {
+ Jpeg2000Prec *prec = band->prec + precno;
+
+ /* Loop on codeblocks */
+ for (cblkno = 0; cblkno < prec->nb_codeblocks_width * prec->nb_codeblocks_height; cblkno++) {
+ int x, y;
+ Jpeg2000Cblk *cblk = prec->cblk + cblkno;
+ decode_cblk(s, codsty, &t1, cblk,
+ cblk->coord[0][1] - cblk->coord[0][0],
+ cblk->coord[1][1] - cblk->coord[1][0],
+ bandpos);
+
+ x = cblk->coord[0][0] - band->coord[0][0];
+ y = cblk->coord[1][0] - band->coord[1][0];
+
+ if (codsty->transform == FF_DWT97)
+ dequantization_float(x, y, cblk, comp, &t1, band);
+ else if (codsty->transform == FF_DWT97_INT)
+ dequantization_int_97(x, y, cblk, comp, &t1, band);
+ else
+ dequantization_int(x, y, cblk, comp, &t1, band);
+ } /* end cblk */
+ } /*end prec */
+ } /* end band */
+ } /* end reslevel */
+
+ /* inverse DWT */
+ ff_dwt_decode(&comp->dwt, codsty->transform == FF_DWT97 ? (void*)comp->f_data : (void*)comp->i_data);
+ } /*end comp */
+
+ /* inverse MCT transformation */
+ if (tile->codsty[0].mct)
+ mct_decode(s, tile);
+
+ for (x = 0; x < s->ncomponents; x++) {
+ if (s->cdef[x] < 0) {
+ for (x = 0; x < s->ncomponents; x++) {
+ s->cdef[x] = x + 1;
+ }
+ if ((s->ncomponents & 1) == 0)
+ s->cdef[s->ncomponents-1] = 0;
+ break;
+ }
+ }
+
+ if (s->precision <= 8) {
+ for (compno = 0; compno < s->ncomponents; compno++) {
+ Jpeg2000Component *comp = tile->comp + compno;
+ Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+ 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 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];
+ line = picture->data[plane] + y * picture->linesize[plane];
+ for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y ++) {
+ uint8_t *dst;
+
+ x = tile->comp[compno].coord[0][0] - s->image_offset_x / s->cdx[compno];
+ dst = line + x * pixelsize + compno*!planar;
+
+ if (codsty->transform == FF_DWT97) {
+ for (; x < w; x ++) {
+ int val = lrintf(*datap) + (1 << (cbps - 1));
+ /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+ val = av_clip(val, 0, (1 << cbps) - 1);
+ *dst = val << (8 - cbps);
+ datap++;
+ dst += pixelsize;
+ }
+ } else {
+ for (; x < w; x ++) {
+ int val = *i_datap + (1 << (cbps - 1));
+ /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+ val = av_clip(val, 0, (1 << cbps) - 1);
+ *dst = val << (8 - cbps);
+ i_datap++;
+ dst += pixelsize;
+ }
+ }
+ line += picture->linesize[plane];
+ }
+ }
+ } else {
+ int precision = picture->format == AV_PIX_FMT_XYZ12 ||
+ picture->format == AV_PIX_FMT_RGB48 ||
+ picture->format == AV_PIX_FMT_RGBA64 ||
+ picture->format == AV_PIX_FMT_GRAY16 ? 16 : s->precision;
+
+ for (compno = 0; compno < s->ncomponents; compno++) {
+ Jpeg2000Component *comp = tile->comp + compno;
+ Jpeg2000CodingStyle *codsty = tile->codsty + compno;
+ float *datap = comp->f_data;
+ int32_t *i_datap = comp->i_data;
+ uint16_t *linel;
+ int cbps = s->cbps[compno];
+ int w = tile->comp[compno].coord[0][1] - s->image_offset_x;
+ 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];
+ linel = (uint16_t *)picture->data[plane] + y * (picture->linesize[plane] >> 1);
+ for (; y < tile->comp[compno].coord[1][1] - s->image_offset_y; y ++) {
+ uint16_t *dst;
+
+ x = tile->comp[compno].coord[0][0] - s->image_offset_x / s->cdx[compno];
+ dst = linel + (x * pixelsize + compno*!planar);
+ if (codsty->transform == FF_DWT97) {
+ for (; x < w; x ++) {
+ int val = lrintf(*datap) + (1 << (cbps - 1));
+ /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+ val = av_clip(val, 0, (1 << cbps) - 1);
+ /* align 12 bit values in little-endian mode */
+ *dst = val << (precision - cbps);
+ datap++;
+ dst += pixelsize;
+ }
+ } else {
+ for (; x < w; x ++) {
+ int val = *i_datap + (1 << (cbps - 1));
+ /* DC level shift and clip see ISO 15444-1:2002 G.1.2 */
+ val = av_clip(val, 0, (1 << cbps) - 1);
+ /* align 12 bit values in little-endian mode */
+ *dst = val << (precision - cbps);
+ i_datap++;
+ dst += pixelsize;
+ }
+ }
+ linel += picture->linesize[plane] >> 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void jpeg2000_dec_cleanup(Jpeg2000DecoderContext *s)
+{
+ int tileno, compno;
+ for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++) {
+ if (s->tile[tileno].comp) {
+ for (compno = 0; compno < s->ncomponents; compno++) {
+ Jpeg2000Component *comp = s->tile[tileno].comp + compno;
+ Jpeg2000CodingStyle *codsty = s->tile[tileno].codsty + compno;
+
+ ff_jpeg2000_cleanup(comp, codsty);
+ }
+ av_freep(&s->tile[tileno].comp);
+ }
+ }
+ av_freep(&s->tile);
+ memset(s->codsty, 0, sizeof(s->codsty));
+ memset(s->qntsty, 0, sizeof(s->qntsty));
+ memset(s->properties, 0, sizeof(s->properties));
+ memset(&s->poc , 0, sizeof(s->poc));
+ s->numXtiles = s->numYtiles = 0;
+ s->ncomponents = 0;
+}
+
+static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s)
+{
+ Jpeg2000CodingStyle *codsty = s->codsty;
+ Jpeg2000QuantStyle *qntsty = s->qntsty;
+ Jpeg2000POC *poc = &s->poc;
+ uint8_t *properties = s->properties;
+
+ for (;;) {
+ int len, ret = 0;
+ uint16_t marker;
+ int oldpos;
+
+ if (bytestream2_get_bytes_left(&s->g) < 2) {
+ av_log(s->avctx, AV_LOG_ERROR, "Missing EOC\n");
+ break;
+ }
+
+ marker = bytestream2_get_be16u(&s->g);
+ oldpos = bytestream2_tell(&s->g);
+
+ if (marker == JPEG2000_SOD) {
+ Jpeg2000Tile *tile;
+ Jpeg2000TilePart *tp;
+
+ if (!s->tile) {
+ av_log(s->avctx, AV_LOG_ERROR, "Missing SIZ\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->curtileno < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Missing SOT\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ tile = s->tile + s->curtileno;
+ tp = tile->tile_part + tile->tp_idx;
+ if (tp->tp_end < s->g.buffer) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid tpend\n");
+ return AVERROR_INVALIDDATA;
+ }
+ bytestream2_init(&tp->tpg, s->g.buffer, tp->tp_end - s->g.buffer);
+ bytestream2_skip(&s->g, tp->tp_end - s->g.buffer);
+
+ continue;
+ }
+ if (marker == JPEG2000_EOC)
+ break;
+
+ len = bytestream2_get_be16(&s->g);
+ if (len < 2 || bytestream2_get_bytes_left(&s->g) < len - 2) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid len %d left=%d\n", len, bytestream2_get_bytes_left(&s->g));
+ return AVERROR_INVALIDDATA;
+ }
+
+ switch (marker) {
+ case JPEG2000_SIZ:
+ if (s->ncomponents) {
+ av_log(s->avctx, AV_LOG_ERROR, "Duplicate SIZ\n");
+ return AVERROR_INVALIDDATA;
+ }
+ ret = get_siz(s);
+ if (!s->tile)
+ s->numXtiles = s->numYtiles = 0;
+ break;
+ case JPEG2000_COC:
+ ret = get_coc(s, codsty, properties);
+ break;
+ case JPEG2000_COD:
+ ret = get_cod(s, codsty, properties);
+ break;
+ case JPEG2000_QCC:
+ ret = get_qcc(s, len, qntsty, properties);
+ break;
+ case JPEG2000_QCD:
+ ret = get_qcd(s, len, qntsty, properties);
+ break;
+ case JPEG2000_POC:
+ ret = get_poc(s, len, poc);
+ break;
+ case JPEG2000_SOT:
+ if (!(ret = get_sot(s, len))) {
+ av_assert1(s->curtileno >= 0);
+ codsty = s->tile[s->curtileno].codsty;
+ qntsty = s->tile[s->curtileno].qntsty;
+ poc = &s->tile[s->curtileno].poc;
+ properties = s->tile[s->curtileno].properties;
+ }
+ break;
+ case JPEG2000_COM:
+ // the comment is ignored
+ bytestream2_skip(&s->g, len - 2);
+ break;
+ case JPEG2000_TLM:
+ // Tile-part lengths
+ ret = get_tlm(s, len);
+ break;
+ case JPEG2000_PLT:
+ // Packet length, tile-part header
+ ret = get_plt(s, len);
+ break;
+ default:
+ av_log(s->avctx, AV_LOG_ERROR,
+ "unsupported marker 0x%.4"PRIX16" at pos 0x%X\n",
+ marker, bytestream2_tell(&s->g) - 4);
+ bytestream2_skip(&s->g, len - 2);
+ break;
+ }
+ if (bytestream2_tell(&s->g) - oldpos != len || ret) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "error during processing marker segment %.4"PRIx16"\n",
+ marker);
+ return ret ? ret : -1;
+ }
+ }
+ return 0;
+}
+
+/* Read bit stream packets --> T2 operation. */
+static int jpeg2000_read_bitstream_packets(Jpeg2000DecoderContext *s)
+{
+ int ret = 0;
+ int tileno;
+
+ for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++) {
+ Jpeg2000Tile *tile = s->tile + tileno;
+
+ if ((ret = init_tile(s, tileno)) < 0)
+ return ret;
+
+ s->g = tile->tile_part[0].tpg;
+ if ((ret = jpeg2000_decode_packets(s, tile)) < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int jp2_find_codestream(Jpeg2000DecoderContext *s)
+{
+ uint32_t atom_size, atom, atom_end;
+ int search_range = 10;
+
+ while (search_range
+ &&
+ bytestream2_get_bytes_left(&s->g) >= 8) {
+ atom_size = bytestream2_get_be32u(&s->g);
+ atom = bytestream2_get_be32u(&s->g);
+ atom_end = bytestream2_tell(&s->g) + atom_size - 8;
+
+ if (atom == JP2_CODESTREAM)
+ return 1;
+
+ if (bytestream2_get_bytes_left(&s->g) < atom_size || atom_end < atom_size)
+ return 0;
+
+ if (atom == JP2_HEADER &&
+ atom_size >= 16) {
+ uint32_t atom2_size, atom2, atom2_end;
+ do {
+ atom2_size = bytestream2_get_be32u(&s->g);
+ atom2 = bytestream2_get_be32u(&s->g);
+ atom2_end = bytestream2_tell(&s->g) + atom2_size - 8;
+ if (atom2_size < 8 || atom2_end > atom_end || atom2_end < atom2_size)
+ break;
+ if (atom2 == JP2_CODESTREAM) {
+ return 1;
+ } else if (atom2 == MKBETAG('c','o','l','r') && atom2_size >= 7) {
+ int method = bytestream2_get_byteu(&s->g);
+ bytestream2_skipu(&s->g, 2);
+ if (method == 1) {
+ s->colour_space = bytestream2_get_be32u(&s->g);
+ }
+ } else if (atom2 == MKBETAG('p','c','l','r') && atom2_size >= 6) {
+ int i, size, colour_count, colour_channels, colour_depth[3];
+ uint32_t r, g, b;
+ colour_count = bytestream2_get_be16u(&s->g);
+ colour_channels = bytestream2_get_byteu(&s->g);
+ // FIXME: Do not ignore channel_sign
+ colour_depth[0] = (bytestream2_get_byteu(&s->g) & 0x7f) + 1;
+ colour_depth[1] = (bytestream2_get_byteu(&s->g) & 0x7f) + 1;
+ colour_depth[2] = (bytestream2_get_byteu(&s->g) & 0x7f) + 1;
+ size = (colour_depth[0] + 7 >> 3) * colour_count +
+ (colour_depth[1] + 7 >> 3) * colour_count +
+ (colour_depth[2] + 7 >> 3) * colour_count;
+ if (colour_count > 256 ||
+ colour_channels != 3 ||
+ colour_depth[0] > 16 ||
+ colour_depth[1] > 16 ||
+ colour_depth[2] > 16 ||
+ atom2_size < size) {
+ avpriv_request_sample(s->avctx, "Unknown palette");
+ bytestream2_seek(&s->g, atom2_end, SEEK_SET);
+ continue;
+ }
+ s->pal8 = 1;
+ for (i = 0; i < colour_count; i++) {
+ if (colour_depth[0] <= 8) {
+ r = bytestream2_get_byteu(&s->g) << 8 - colour_depth[0];
+ r |= r >> colour_depth[0];
+ } else {
+ r = bytestream2_get_be16u(&s->g) >> colour_depth[0] - 8;
+ }
+ if (colour_depth[1] <= 8) {
+ g = bytestream2_get_byteu(&s->g) << 8 - colour_depth[1];
+ r |= r >> colour_depth[1];
+ } else {
+ g = bytestream2_get_be16u(&s->g) >> colour_depth[1] - 8;
+ }
+ if (colour_depth[2] <= 8) {
+ b = bytestream2_get_byteu(&s->g) << 8 - colour_depth[2];
+ r |= r >> colour_depth[2];
+ } else {
+ b = bytestream2_get_be16u(&s->g) >> colour_depth[2] - 8;
+ }
+ s->palette[i] = 0xffu << 24 | r << 16 | g << 8 | b;
+ }
+ } else if (atom2 == MKBETAG('c','d','e','f') && atom2_size >= 2) {
+ int n = bytestream2_get_be16u(&s->g);
+ for (; n>0; n--) {
+ int cn = bytestream2_get_be16(&s->g);
+ int av_unused typ = bytestream2_get_be16(&s->g);
+ int asoc = bytestream2_get_be16(&s->g);
+ if (cn < 4 && asoc < 4)
+ s->cdef[cn] = asoc;
+ }
+ }
+ bytestream2_seek(&s->g, atom2_end, SEEK_SET);
+ } while (atom_end - atom2_end >= 8);
+ } else {
+ search_range--;
+ }
+ bytestream2_seek(&s->g, atom_end, SEEK_SET);
+ }
+
+ return 0;
+}
+
+static av_cold int jpeg2000_decode_init(AVCodecContext *avctx)
+{
+ Jpeg2000DecoderContext *s = avctx->priv_data;
+
+ ff_jpeg2000dsp_init(&s->dsp);
+
+ return 0;
+}
+
+static int jpeg2000_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame, AVPacket *avpkt)
+{
+ Jpeg2000DecoderContext *s = avctx->priv_data;
+ ThreadFrame frame = { .f = data };
+ AVFrame *picture = data;
+ int tileno, ret;
+
+ s->avctx = avctx;
+ bytestream2_init(&s->g, avpkt->data, avpkt->size);
+ s->curtileno = -1;
+ memset(s->cdef, -1, sizeof(s->cdef));
+
+ if (bytestream2_get_bytes_left(&s->g) < 2) {
+ ret = AVERROR_INVALIDDATA;
+ goto end;
+ }
+
+ // check if the image is in jp2 format
+ if (bytestream2_get_bytes_left(&s->g) >= 12 &&
+ (bytestream2_get_be32u(&s->g) == 12) &&
+ (bytestream2_get_be32u(&s->g) == JP2_SIG_TYPE) &&
+ (bytestream2_get_be32u(&s->g) == JP2_SIG_VALUE)) {
+ if (!jp2_find_codestream(s)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Could not find Jpeg2000 codestream atom.\n");
+ ret = AVERROR_INVALIDDATA;
+ goto end;
+ }
+ } else {
+ bytestream2_seek(&s->g, 0, SEEK_SET);
+ }
+
+ while (bytestream2_get_bytes_left(&s->g) >= 3 && bytestream2_peek_be16(&s->g) != JPEG2000_SOC)
+ bytestream2_skip(&s->g, 1);
+
+ if (bytestream2_get_be16u(&s->g) != JPEG2000_SOC) {
+ av_log(avctx, AV_LOG_ERROR, "SOC marker not present\n");
+ ret = AVERROR_INVALIDDATA;
+ goto end;
+ }
+ if (ret = jpeg2000_read_main_headers(s))
+ goto end;
+
+ /* get picture buffer */
+ if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+ goto end;
+ picture->pict_type = AV_PICTURE_TYPE_I;
+ picture->key_frame = 1;
+
+ if (ret = jpeg2000_read_bitstream_packets(s))
+ goto end;
+
+ for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++)
+ if (ret = jpeg2000_decode_tile(s, s->tile + tileno, picture))
+ goto end;
+
+ jpeg2000_dec_cleanup(s);
+
+ *got_frame = 1;
+
+ if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
+ memcpy(picture->data[1], s->palette, 256 * sizeof(uint32_t));
+
+ return bytestream2_tell(&s->g);
+
+end:
+ jpeg2000_dec_cleanup(s);
+ return ret;
+}
+
+static av_cold void jpeg2000_init_static_data(AVCodec *codec)
+{
+ ff_jpeg2000_init_tier1_luts();
+ ff_mqc_init_context_tables();
+}
+
+#define OFFSET(x) offsetof(Jpeg2000DecoderContext, 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(reduction_factor), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, JPEG2000_MAX_RESLEVELS - 1, VD },
+ { NULL },
+};
+
+static const AVProfile profiles[] = {
+ { FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_0, "JPEG 2000 codestream restriction 0" },
+ { FF_PROFILE_JPEG2000_CSTREAM_RESTRICTION_1, "JPEG 2000 codestream restriction 1" },
+ { FF_PROFILE_JPEG2000_CSTREAM_NO_RESTRICTION, "JPEG 2000 no codestream restrictions" },
+ { FF_PROFILE_JPEG2000_DCINEMA_2K, "JPEG 2000 digital cinema 2K" },
+ { FF_PROFILE_JPEG2000_DCINEMA_4K, "JPEG 2000 digital cinema 4K" },
+ { FF_PROFILE_UNKNOWN },
+};
+
+static const AVClass jpeg2000_class = {
+ .class_name = "jpeg2000",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_jpeg2000_decoder = {
+ .name = "jpeg2000",
+ .long_name = NULL_IF_CONFIG_SMALL("JPEG 2000"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_JPEG2000,
+ .capabilities = AV_CODEC_CAP_FRAME_THREADS | AV_CODEC_CAP_DR1,
+ .priv_data_size = sizeof(Jpeg2000DecoderContext),
+ .init_static_data = jpeg2000_init_static_data,
+ .init = jpeg2000_decode_init,
+ .decode = jpeg2000_decode_frame,
+ .priv_class = &jpeg2000_class,
+ .max_lowres = 5,
+ .profiles = NULL_IF_CONFIG_SMALL(profiles)
+};
diff --git a/ffmpeg-2-8-11/libavcodec/jpeg2000dsp.c b/ffmpeg-2-8-12/libavcodec/jpeg2000dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jpeg2000dsp.c
rename to ffmpeg-2-8-12/libavcodec/jpeg2000dsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/jpeg2000dsp.h b/ffmpeg-2-8-12/libavcodec/jpeg2000dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jpeg2000dsp.h
rename to ffmpeg-2-8-12/libavcodec/jpeg2000dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/jpeg2000dwt.c b/ffmpeg-2-8-12/libavcodec/jpeg2000dwt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jpeg2000dwt.c
rename to ffmpeg-2-8-12/libavcodec/jpeg2000dwt.c
diff --git a/ffmpeg-2-8-11/libavcodec/jpeg2000dwt.h b/ffmpeg-2-8-12/libavcodec/jpeg2000dwt.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jpeg2000dwt.h
rename to ffmpeg-2-8-12/libavcodec/jpeg2000dwt.h
diff --git a/ffmpeg-2-8-11/libavcodec/jpegls.c b/ffmpeg-2-8-12/libavcodec/jpegls.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jpegls.c
rename to ffmpeg-2-8-12/libavcodec/jpegls.c
diff --git a/ffmpeg-2-8-11/libavcodec/jpegls.h b/ffmpeg-2-8-12/libavcodec/jpegls.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jpegls.h
rename to ffmpeg-2-8-12/libavcodec/jpegls.h
diff --git a/ffmpeg-2-8-12/libavcodec/jpeglsdec.c b/ffmpeg-2-8-12/libavcodec/jpeglsdec.c
new file mode 100644
index 0000000..20b4044
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/jpeglsdec.c
@@ -0,0 +1,532 @@
+/*
+ * JPEG-LS decoder
+ * Copyright (c) 2003 Michael Niedermayer
+ * Copyright (c) 2006 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
+ */
+
+/**
+ * @file
+ * JPEG-LS decoder.
+ */
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "golomb.h"
+#include "internal.h"
+#include "mathops.h"
+#include "mjpeg.h"
+#include "mjpegdec.h"
+#include "jpegls.h"
+#include "jpeglsdec.h"
+
+/*
+ * Uncomment this to significantly speed up decoding of broken JPEG-LS
+ * (or test broken JPEG-LS decoder) and slow down ordinary decoding a bit.
+ *
+ * There is no Golomb code with length >= 32 bits possible, so check and
+ * avoid situation of 32 zeros, FFmpeg Golomb decoder is painfully slow
+ * on this errors.
+ */
+//#define JLS_BROKEN
+
+/**
+ * Decode LSE block with initialization parameters
+ */
+int ff_jpegls_decode_lse(MJpegDecodeContext *s)
+{
+ int id;
+ int tid, wt, maxtab, i, j;
+
+ int len = get_bits(&s->gb, 16);
+ id = get_bits(&s->gb, 8);
+
+ switch (id) {
+ case 1:
+ if (len < 13)
+ return AVERROR_INVALIDDATA;
+
+ s->maxval = get_bits(&s->gb, 16);
+ s->t1 = get_bits(&s->gb, 16);
+ s->t2 = get_bits(&s->gb, 16);
+ s->t3 = get_bits(&s->gb, 16);
+ s->reset = get_bits(&s->gb, 16);
+
+ if(s->avctx->debug & FF_DEBUG_PICT_INFO) {
+ av_log(s->avctx, AV_LOG_DEBUG, "Coding parameters maxval:%d T1:%d T2:%d T3:%d reset:%d\n",
+ s->maxval, s->t1, s->t2, s->t3, s->reset);
+ }
+
+// ff_jpegls_reset_coding_parameters(s, 0);
+ //FIXME quant table?
+ break;
+ case 2:
+ s->palette_index = 0;
+ case 3:
+ tid= get_bits(&s->gb, 8);
+ wt = get_bits(&s->gb, 8);
+
+ if (len < 5)
+ return AVERROR_INVALIDDATA;
+
+ if (wt < 1 || wt > MAX_COMPONENTS) {
+ avpriv_request_sample(s->avctx, "wt %d", wt);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if (!s->maxval)
+ maxtab = 255;
+ else if ((5 + wt*(s->maxval+1)) < 65535)
+ maxtab = s->maxval;
+ else
+ maxtab = 65530/wt - 1;
+
+ if(s->avctx->debug & FF_DEBUG_PICT_INFO) {
+ av_log(s->avctx, AV_LOG_DEBUG, "LSE palette %d tid:%d wt:%d maxtab:%d\n", id, tid, wt, maxtab);
+ }
+ if (maxtab >= 256) {
+ avpriv_request_sample(s->avctx, ">8bit palette");
+ return AVERROR_PATCHWELCOME;
+ }
+ maxtab = FFMIN(maxtab, (len - 5) / wt + s->palette_index);
+
+ if (s->palette_index > maxtab)
+ return AVERROR_INVALIDDATA;
+
+ if ((s->avctx->pix_fmt == AV_PIX_FMT_GRAY8 || s->avctx->pix_fmt == AV_PIX_FMT_PAL8) &&
+ (s->picture_ptr->format == AV_PIX_FMT_GRAY8 || s->picture_ptr->format == AV_PIX_FMT_PAL8)) {
+ uint32_t *pal = (uint32_t *)s->picture_ptr->data[1];
+ int shift = 0;
+
+ if (s->avctx->bits_per_raw_sample > 0 && s->avctx->bits_per_raw_sample < 8) {
+ maxtab = FFMIN(maxtab, (1<<s->avctx->bits_per_raw_sample)-1);
+ shift = 8 - s->avctx->bits_per_raw_sample;
+ }
+
+ s->picture_ptr->format =
+ s->avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ for (i=s->palette_index; i<=maxtab; i++) {
+ uint8_t k = i << shift;
+ pal[k] = 0;
+ for (j=0; j<wt; j++) {
+ pal[k] |= get_bits(&s->gb, 8) << (8*(wt-j-1));
+ }
+ }
+ s->palette_index = i;
+ }
+ break;
+ case 4:
+ avpriv_request_sample(s->avctx, "oversize image");
+ return AVERROR(ENOSYS);
+ default:
+ av_log(s->avctx, AV_LOG_ERROR, "invalid id %d\n", id);
+ return AVERROR_INVALIDDATA;
+ }
+ ff_dlog(s->avctx, "ID=%i, T=%i,%i,%i\n", id, s->t1, s->t2, s->t3);
+
+ return 0;
+}
+
+/**
+ * Get context-dependent Golomb code, decode it and update context
+ */
+static inline int ls_get_code_regular(GetBitContext *gb, JLSState *state, int Q)
+{
+ int k, ret;
+
+ for (k = 0; (state->N[Q] << k) < state->A[Q]; k++)
+ ;
+
+#ifdef JLS_BROKEN
+ if (!show_bits_long(gb, 32))
+ return -1;
+#endif
+ ret = get_ur_golomb_jpegls(gb, k, state->limit, state->qbpp);
+
+ /* decode mapped error */
+ if (ret & 1)
+ ret = -(ret + 1 >> 1);
+ else
+ ret >>= 1;
+
+ /* for NEAR=0, k=0 and 2*B[Q] <= - N[Q] mapping is reversed */
+ if (!state->near && !k && (2 * state->B[Q] <= -state->N[Q]))
+ ret = -(ret + 1);
+
+ ret = ff_jpegls_update_state_regular(state, Q, ret);
+
+ return ret;
+}
+
+/**
+ * Get Golomb code, decode it and update state for run termination
+ */
+static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state,
+ int RItype, int limit_add)
+{
+ int k, ret, temp, map;
+ int Q = 365 + RItype;
+
+ temp = state->A[Q];
+ if (RItype)
+ temp += state->N[Q] >> 1;
+
+ for (k = 0; (state->N[Q] << k) < temp; k++)
+ ;
+
+#ifdef JLS_BROKEN
+ if (!show_bits_long(gb, 32))
+ return -1;
+#endif
+ ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1,
+ state->qbpp);
+
+ /* decode mapped error */
+ map = 0;
+ if (!k && (RItype || ret) && (2 * state->B[Q] < state->N[Q]))
+ map = 1;
+ ret += RItype + map;
+
+ if (ret & 1) {
+ ret = map - (ret + 1 >> 1);
+ state->B[Q]++;
+ } else {
+ ret = ret >> 1;
+ }
+
+ if(FFABS(ret) > 0xFFFF)
+ return -0x10000;
+ /* update state */
+ state->A[Q] += FFABS(ret) - RItype;
+ ret *= state->twonear;
+ ff_jpegls_downscale_state(state, Q);
+
+ return ret;
+}
+
+/**
+ * Decode one line of image
+ */
+static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s,
+ void *last, void *dst, int last2, int w,
+ int stride, int comp, int bits)
+{
+ int i, x = 0;
+ int Ra, Rb, Rc, Rd;
+ int D0, D1, D2;
+
+ while (x < w) {
+ int err, pred;
+
+ /* compute gradients */
+ Ra = x ? R(dst, 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);
+ D0 = Rd - Rb;
+ D1 = Rb - Rc;
+ D2 = Rc - Ra;
+ /* run mode */
+ if ((FFABS(D0) <= state->near) &&
+ (FFABS(D1) <= state->near) &&
+ (FFABS(D2) <= state->near)) {
+ int r;
+ int RItype;
+
+ /* decode full runs while available */
+ while (get_bits1(&s->gb)) {
+ int r;
+ r = 1 << ff_log2_run[state->run_index[comp]];
+ if (x + r * stride > w)
+ r = (w - x) / stride;
+ for (i = 0; i < r; i++) {
+ W(dst, x, Ra);
+ x += stride;
+ }
+ /* if EOL reached, we stop decoding */
+ if (r != 1 << ff_log2_run[state->run_index[comp]])
+ return;
+ if (state->run_index[comp] < 31)
+ state->run_index[comp]++;
+ if (x + stride > w)
+ return;
+ }
+ /* decode aborted run */
+ r = ff_log2_run[state->run_index[comp]];
+ if (r)
+ r = get_bits_long(&s->gb, r);
+ if (x + r * stride > w) {
+ r = (w - x) / stride;
+ }
+ for (i = 0; i < r; i++) {
+ W(dst, x, Ra);
+ x += stride;
+ }
+
+ if (x >= w) {
+ av_log(NULL, AV_LOG_ERROR, "run overflow\n");
+ av_assert0(x <= w);
+ return;
+ }
+
+ /* decode run termination value */
+ Rb = R(last, x);
+ RItype = (FFABS(Ra - Rb) <= state->near) ? 1 : 0;
+ err = ls_get_code_runterm(&s->gb, state, RItype,
+ ff_log2_run[state->run_index[comp]]);
+ if (state->run_index[comp])
+ state->run_index[comp]--;
+
+ if (state->near && RItype) {
+ pred = Ra + err;
+ } else {
+ if (Rb < Ra)
+ pred = Rb - err;
+ else
+ pred = Rb + err;
+ }
+ } else { /* regular mode */
+ int context, sign;
+
+ context = ff_jpegls_quantize(state, D0) * 81 +
+ ff_jpegls_quantize(state, D1) * 9 +
+ ff_jpegls_quantize(state, D2);
+ pred = mid_pred(Ra, Ra + Rb - Rc, Rb);
+
+ if (context < 0) {
+ context = -context;
+ sign = 1;
+ } else {
+ sign = 0;
+ }
+
+ if (sign) {
+ pred = av_clip(pred - state->C[context], 0, state->maxval);
+ err = -ls_get_code_regular(&s->gb, state, context);
+ } else {
+ pred = av_clip(pred + state->C[context], 0, state->maxval);
+ err = ls_get_code_regular(&s->gb, state, context);
+ }
+
+ /* we have to do something more for near-lossless coding */
+ pred += err;
+ }
+ if (state->near) {
+ if (pred < -state->near)
+ pred += state->range * state->twonear;
+ else if (pred > state->maxval + state->near)
+ pred -= state->range * state->twonear;
+ pred = av_clip(pred, 0, state->maxval);
+ }
+
+ pred &= state->maxval;
+ W(dst, x, pred);
+ x += stride;
+ }
+}
+
+int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near,
+ int point_transform, int ilv)
+{
+ int i, t = 0;
+ uint8_t *zero, *last, *cur;
+ JLSState *state;
+ int off = 0, stride = 1, width, shift, ret = 0;
+
+ zero = av_mallocz(s->picture_ptr->linesize[0]);
+ if (!zero)
+ return AVERROR(ENOMEM);
+ last = zero;
+ cur = s->picture_ptr->data[0];
+
+ state = av_mallocz(sizeof(JLSState));
+ if (!state) {
+ av_free(zero);
+ return AVERROR(ENOMEM);
+ }
+ /* initialize JPEG-LS state from JPEG parameters */
+ state->near = near;
+ state->bpp = (s->bits < 2) ? 2 : s->bits;
+ state->maxval = s->maxval;
+ state->T1 = s->t1;
+ state->T2 = s->t2;
+ state->T3 = s->t3;
+ state->reset = s->reset;
+ ff_jpegls_reset_coding_parameters(state, 0);
+ ff_jpegls_init_state(state);
+
+ if (s->bits <= 8)
+ shift = point_transform + (8 - s->bits);
+ else
+ shift = point_transform + (16 - s->bits);
+
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) "
+ "RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n",
+ s->width, s->height, state->near, state->maxval,
+ state->T1, state->T2, state->T3,
+ state->reset, state->limit, state->qbpp, state->range);
+ av_log(s->avctx, AV_LOG_DEBUG, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n",
+ ilv, point_transform, s->bits, s->cur_scan);
+ }
+ if (get_bits_left(&s->gb) < s->height) {
+ ret = AVERROR_INVALIDDATA;
+ goto end;
+ }
+ if (ilv == 0) { /* separate planes */
+ if (s->cur_scan > s->nb_components) {
+ ret = AVERROR_INVALIDDATA;
+ goto end;
+ }
+ stride = (s->nb_components > 1) ? 3 : 1;
+ off = av_clip(s->cur_scan - 1, 0, stride - 1);
+ width = s->width * stride;
+ cur += off;
+ for (i = 0; i < s->height; i++) {
+ if (s->bits <= 8) {
+ ls_decode_line(state, s, last, cur, t, width, stride, off, 8);
+ t = last[0];
+ } else {
+ ls_decode_line(state, s, last, cur, t, width, stride, off, 16);
+ t = *((uint16_t *)last);
+ }
+ last = cur;
+ cur += s->picture_ptr->linesize[0];
+
+ if (s->restart_interval && !--s->restart_count) {
+ align_get_bits(&s->gb);
+ skip_bits(&s->gb, 16); /* skip RSTn */
+ }
+ }
+ } else if (ilv == 1) { /* line interleaving */
+ int j;
+ int Rc[3] = { 0, 0, 0 };
+ stride = (s->nb_components > 1) ? 3 : 1;
+ memset(cur, 0, s->picture_ptr->linesize[0]);
+ width = s->width * stride;
+ for (i = 0; i < s->height; i++) {
+ for (j = 0; j < stride; j++) {
+ ls_decode_line(state, s, last + j, cur + j,
+ Rc[j], width, stride, j, 8);
+ Rc[j] = last[j];
+
+ if (s->restart_interval && !--s->restart_count) {
+ align_get_bits(&s->gb);
+ skip_bits(&s->gb, 16); /* skip RSTn */
+ }
+ }
+ last = cur;
+ cur += s->picture_ptr->linesize[0];
+ }
+ } else if (ilv == 2) { /* sample interleaving */
+ avpriv_report_missing_feature(s->avctx, "Sample interleaved images");
+ ret = AVERROR_PATCHWELCOME;
+ goto end;
+ }
+
+ if (s->xfrm && s->nb_components == 3) {
+ int x, w;
+
+ w = s->width * s->nb_components;
+
+ if (s->bits <= 8) {
+ uint8_t *src = s->picture_ptr->data[0];
+
+ for (i = 0; i < s->height; i++) {
+ switch(s->xfrm) {
+ case 1:
+ for (x = off; x < w; x += 3) {
+ src[x ] += src[x+1] + 128;
+ src[x+2] += src[x+1] + 128;
+ }
+ break;
+ case 2:
+ for (x = off; x < w; x += 3) {
+ src[x ] += src[x+1] + 128;
+ src[x+2] += ((src[x ] + src[x+1])>>1) + 128;
+ }
+ break;
+ case 3:
+ for (x = off; x < w; x += 3) {
+ int g = src[x+0] - ((src[x+2]+src[x+1])>>2) + 64;
+ src[x+0] = src[x+2] + g + 128;
+ src[x+2] = src[x+1] + g + 128;
+ src[x+1] = g;
+ }
+ break;
+ case 4:
+ for (x = off; x < w; x += 3) {
+ int r = src[x+0] - (( 359 * (src[x+2]-128) + 490) >> 8);
+ int g = src[x+0] - (( 88 * (src[x+1]-128) - 183 * (src[x+2]-128) + 30) >> 8);
+ int b = src[x+0] + ((454 * (src[x+1]-128) + 574) >> 8);
+ src[x+0] = av_clip_uint8(r);
+ src[x+1] = av_clip_uint8(g);
+ src[x+2] = av_clip_uint8(b);
+ }
+ break;
+ }
+ src += s->picture_ptr->linesize[0];
+ }
+ }else
+ avpriv_report_missing_feature(s->avctx, "16bit xfrm");
+ }
+
+ if (shift) { /* we need to do point transform or normalize samples */
+ int x, w;
+
+ w = s->width * s->nb_components;
+
+ if (s->bits <= 8) {
+ uint8_t *src = s->picture_ptr->data[0];
+
+ for (i = 0; i < s->height; i++) {
+ for (x = off; x < w; x += stride)
+ src[x] <<= shift;
+ src += s->picture_ptr->linesize[0];
+ }
+ } else {
+ uint16_t *src = (uint16_t *)s->picture_ptr->data[0];
+
+ for (i = 0; i < s->height; i++) {
+ for (x = 0; x < w; x++)
+ src[x] <<= shift;
+ src += s->picture_ptr->linesize[0] / 2;
+ }
+ }
+ }
+
+end:
+ av_free(state);
+ av_free(zero);
+
+ return ret;
+}
+
+AVCodec ff_jpegls_decoder = {
+ .name = "jpegls",
+ .long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_JPEGLS,
+ .priv_data_size = sizeof(MJpegDecodeContext),
+ .init = ff_mjpeg_decode_init,
+ .close = ff_mjpeg_decode_end,
+ .decode = ff_mjpeg_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/jpeglsdec.h b/ffmpeg-2-8-12/libavcodec/jpeglsdec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jpeglsdec.h
rename to ffmpeg-2-8-12/libavcodec/jpeglsdec.h
diff --git a/ffmpeg-2-8-11/libavcodec/jpeglsenc.c b/ffmpeg-2-8-12/libavcodec/jpeglsenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jpeglsenc.c
rename to ffmpeg-2-8-12/libavcodec/jpeglsenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/jpegtables.c b/ffmpeg-2-8-12/libavcodec/jpegtables.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jpegtables.c
rename to ffmpeg-2-8-12/libavcodec/jpegtables.c
diff --git a/ffmpeg-2-8-11/libavcodec/jpegtables.h b/ffmpeg-2-8-12/libavcodec/jpegtables.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jpegtables.h
rename to ffmpeg-2-8-12/libavcodec/jpegtables.h
diff --git a/ffmpeg-2-8-11/libavcodec/jrevdct.c b/ffmpeg-2-8-12/libavcodec/jrevdct.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jrevdct.c
rename to ffmpeg-2-8-12/libavcodec/jrevdct.c
diff --git a/ffmpeg-2-8-11/libavcodec/jvdec.c b/ffmpeg-2-8-12/libavcodec/jvdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/jvdec.c
rename to ffmpeg-2-8-12/libavcodec/jvdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/kbdwin.c b/ffmpeg-2-8-12/libavcodec/kbdwin.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/kbdwin.c
rename to ffmpeg-2-8-12/libavcodec/kbdwin.c
diff --git a/ffmpeg-2-8-11/libavcodec/kbdwin.h b/ffmpeg-2-8-12/libavcodec/kbdwin.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/kbdwin.h
rename to ffmpeg-2-8-12/libavcodec/kbdwin.h
diff --git a/ffmpeg-2-8-11/libavcodec/kgv1dec.c b/ffmpeg-2-8-12/libavcodec/kgv1dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/kgv1dec.c
rename to ffmpeg-2-8-12/libavcodec/kgv1dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/kmvc.c b/ffmpeg-2-8-12/libavcodec/kmvc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/kmvc.c
rename to ffmpeg-2-8-12/libavcodec/kmvc.c
diff --git a/ffmpeg-2-8-12/libavcodec/lagarith.c b/ffmpeg-2-8-12/libavcodec/lagarith.c
new file mode 100644
index 0000000..ea069b3
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/lagarith.c
@@ -0,0 +1,754 @@
+/*
+ * Lagarith lossless decoder
+ * Copyright (c) 2009 Nathan Caldwell <saintdev (at) gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Lagarith lossless decoder
+ * @author Nathan Caldwell
+ */
+
+#include <inttypes.h>
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "mathops.h"
+#include "huffyuvdsp.h"
+#include "lagarithrac.h"
+#include "thread.h"
+
+enum LagarithFrameType {
+ FRAME_RAW = 1, /**< uncompressed */
+ FRAME_U_RGB24 = 2, /**< unaligned RGB24 */
+ FRAME_ARITH_YUY2 = 3, /**< arithmetic coded YUY2 */
+ FRAME_ARITH_RGB24 = 4, /**< arithmetic coded RGB24 */
+ FRAME_SOLID_GRAY = 5, /**< solid grayscale color frame */
+ FRAME_SOLID_COLOR = 6, /**< solid non-grayscale color frame */
+ FRAME_OLD_ARITH_RGB = 7, /**< obsolete arithmetic coded RGB (no longer encoded by upstream since version 1.1.0) */
+ FRAME_ARITH_RGBA = 8, /**< arithmetic coded RGBA */
+ FRAME_SOLID_RGBA = 9, /**< solid RGBA color frame */
+ FRAME_ARITH_YV12 = 10, /**< arithmetic coded YV12 */
+ FRAME_REDUCED_RES = 11, /**< reduced resolution YV12 frame */
+};
+
+typedef struct LagarithContext {
+ AVCodecContext *avctx;
+ HuffYUVDSPContext hdsp;
+ int zeros; /**< number of consecutive zero bytes encountered */
+ int zeros_rem; /**< number of zero bytes remaining to output */
+ uint8_t *rgb_planes;
+ int rgb_planes_allocated;
+ int rgb_stride;
+} LagarithContext;
+
+/**
+ * Compute the 52bit mantissa of 1/(double)denom.
+ * This crazy format uses floats in an entropy coder and we have to match x86
+ * rounding exactly, thus ordinary floats aren't portable enough.
+ * @param denom denominator
+ * @return 52bit mantissa
+ * @see softfloat_mul
+ */
+static uint64_t softfloat_reciprocal(uint32_t denom)
+{
+ int shift = av_log2(denom - 1) + 1;
+ uint64_t ret = (1ULL << 52) / denom;
+ uint64_t err = (1ULL << 52) - ret * denom;
+ ret <<= shift;
+ err <<= shift;
+ err += denom / 2;
+ return ret + err / denom;
+}
+
+/**
+ * (uint32_t)(x*f), where f has the given mantissa, and exponent 0
+ * Used in combination with softfloat_reciprocal computes x/(double)denom.
+ * @param x 32bit integer factor
+ * @param mantissa mantissa of f with exponent 0
+ * @return 32bit integer value (x*f)
+ * @see softfloat_reciprocal
+ */
+static uint32_t softfloat_mul(uint32_t x, uint64_t mantissa)
+{
+ uint64_t l = x * (mantissa & 0xffffffff);
+ uint64_t h = x * (mantissa >> 32);
+ h += l >> 32;
+ l &= 0xffffffff;
+ l += 1 << av_log2(h >> 21);
+ h += l >> 32;
+ return h >> 20;
+}
+
+static uint8_t lag_calc_zero_run(int8_t x)
+{
+ return (x * 2) ^ (x >> 7);
+}
+
+static int lag_decode_prob(GetBitContext *gb, uint32_t *value)
+{
+ static const uint8_t series[] = { 1, 2, 3, 5, 8, 13, 21 };
+ int i;
+ int bit = 0;
+ int bits = 0;
+ int prevbit = 0;
+ unsigned val;
+
+ for (i = 0; i < 7; i++) {
+ if (prevbit && bit)
+ break;
+ prevbit = bit;
+ bit = get_bits1(gb);
+ if (bit && !prevbit)
+ bits += series[i];
+ }
+ bits--;
+ if (bits < 0 || bits > 31) {
+ *value = 0;
+ return -1;
+ } else if (bits == 0) {
+ *value = 0;
+ return 0;
+ }
+
+ val = get_bits_long(gb, bits);
+ val |= 1U << bits;
+
+ *value = val - 1;
+
+ return 0;
+}
+
+static int lag_read_prob_header(lag_rac *rac, GetBitContext *gb)
+{
+ int i, j, scale_factor;
+ unsigned prob, cumulative_target;
+ unsigned cumul_prob = 0;
+ unsigned scaled_cumul_prob = 0;
+
+ rac->prob[0] = 0;
+ rac->prob[257] = UINT_MAX;
+ /* Read probabilities from bitstream */
+ for (i = 1; i < 257; i++) {
+ if (lag_decode_prob(gb, &rac->prob[i]) < 0) {
+ av_log(rac->avctx, AV_LOG_ERROR, "Invalid probability encountered.\n");
+ return -1;
+ }
+ if ((uint64_t)cumul_prob + rac->prob[i] > UINT_MAX) {
+ av_log(rac->avctx, AV_LOG_ERROR, "Integer overflow encountered in cumulative probability calculation.\n");
+ return -1;
+ }
+ cumul_prob += rac->prob[i];
+ if (!rac->prob[i]) {
+ if (lag_decode_prob(gb, &prob)) {
+ av_log(rac->avctx, AV_LOG_ERROR, "Invalid probability run encountered.\n");
+ return -1;
+ }
+ if (prob > 256 - i)
+ prob = 256 - i;
+ for (j = 0; j < prob; j++)
+ rac->prob[++i] = 0;
+ }
+ }
+
+ if (!cumul_prob) {
+ av_log(rac->avctx, AV_LOG_ERROR, "All probabilities are 0!\n");
+ return -1;
+ }
+
+ /* Scale probabilities so cumulative probability is an even power of 2. */
+ scale_factor = av_log2(cumul_prob);
+
+ if (cumul_prob & (cumul_prob - 1)) {
+ uint64_t mul = softfloat_reciprocal(cumul_prob);
+ for (i = 1; i <= 128; i++) {
+ rac->prob[i] = softfloat_mul(rac->prob[i], mul);
+ scaled_cumul_prob += rac->prob[i];
+ }
+ if (scaled_cumul_prob <= 0) {
+ av_log(rac->avctx, AV_LOG_ERROR, "Scaled probabilities invalid\n");
+ return AVERROR_INVALIDDATA;
+ }
+ for (; i < 257; i++) {
+ rac->prob[i] = softfloat_mul(rac->prob[i], mul);
+ scaled_cumul_prob += rac->prob[i];
+ }
+
+ scale_factor++;
+ if (scale_factor >= 32U)
+ return AVERROR_INVALIDDATA;
+ cumulative_target = 1U << scale_factor;
+
+ if (scaled_cumul_prob > cumulative_target) {
+ av_log(rac->avctx, AV_LOG_ERROR,
+ "Scaled probabilities are larger than target!\n");
+ return -1;
+ }
+
+ scaled_cumul_prob = cumulative_target - scaled_cumul_prob;
+
+ for (i = 1; scaled_cumul_prob; i = (i & 0x7f) + 1) {
+ if (rac->prob[i]) {
+ rac->prob[i]++;
+ scaled_cumul_prob--;
+ }
+ /* Comment from reference source:
+ * if (b & 0x80 == 0) { // order of operations is 'wrong'; it has been left this way
+ * // since the compression change is negligible and fixing it
+ * // breaks backwards compatibility
+ * b =- (signed int)b;
+ * b &= 0xFF;
+ * } else {
+ * b++;
+ * b &= 0x7f;
+ * }
+ */
+ }
+ }
+
+ rac->scale = scale_factor;
+
+ /* Fill probability array with cumulative probability for each symbol. */
+ for (i = 1; i < 257; i++)
+ rac->prob[i] += rac->prob[i - 1];
+
+ return 0;
+}
+
+static void add_lag_median_prediction(uint8_t *dst, uint8_t *src1,
+ uint8_t *diff, int w, int *left,
+ int *left_top)
+{
+ /* This is almost identical to add_hfyu_median_pred in huffyuvdsp.h.
+ * However the &0xFF on the gradient predictor yealds incorrect output
+ * for lagarith.
+ */
+ int i;
+ uint8_t l, lt;
+
+ l = *left;
+ lt = *left_top;
+
+ for (i = 0; i < w; i++) {
+ l = mid_pred(l, src1[i], l + src1[i] - lt) + diff[i];
+ lt = src1[i];
+ dst[i] = l;
+ }
+
+ *left = l;
+ *left_top = lt;
+}
+
+static void lag_pred_line(LagarithContext *l, uint8_t *buf,
+ int width, int stride, int line)
+{
+ int L, TL;
+
+ if (!line) {
+ /* Left prediction only for first line */
+ L = l->hdsp.add_hfyu_left_pred(buf, buf, width, 0);
+ } else {
+ /* Left pixel is actually prev_row[width] */
+ L = buf[width - stride - 1];
+
+ if (line == 1) {
+ /* Second line, left predict first pixel, the rest of the line is median predicted
+ * NOTE: In the case of RGB this pixel is top predicted */
+ TL = l->avctx->pix_fmt == AV_PIX_FMT_YUV420P ? buf[-stride] : L;
+ } else {
+ /* Top left is 2 rows back, last pixel */
+ TL = buf[width - (2 * stride) - 1];
+ }
+
+ add_lag_median_prediction(buf, buf - stride, buf,
+ width, &L, &TL);
+ }
+}
+
+static void lag_pred_line_yuy2(LagarithContext *l, uint8_t *buf,
+ int width, int stride, int line,
+ int is_luma)
+{
+ int L, TL;
+
+ if (!line) {
+ L= buf[0];
+ if (is_luma)
+ buf[0] = 0;
+ l->hdsp.add_hfyu_left_pred(buf, buf, width, 0);
+ if (is_luma)
+ buf[0] = L;
+ return;
+ }
+ if (line == 1) {
+ const int HEAD = is_luma ? 4 : 2;
+ int i;
+
+ L = buf[width - stride - 1];
+ TL = buf[HEAD - stride - 1];
+ for (i = 0; i < HEAD; i++) {
+ L += buf[i];
+ buf[i] = L;
+ }
+ for (; i < width; i++) {
+ L = mid_pred(L & 0xFF, buf[i - stride], (L + buf[i - stride] - TL) & 0xFF) + buf[i];
+ TL = buf[i - stride];
+ buf[i] = L;
+ }
+ } else {
+ TL = buf[width - (2 * stride) - 1];
+ L = buf[width - stride - 1];
+ l->hdsp.add_hfyu_median_pred(buf, buf - stride, buf, width, &L, &TL);
+ }
+}
+
+static int lag_decode_line(LagarithContext *l, lag_rac *rac,
+ uint8_t *dst, int width, int stride,
+ int esc_count)
+{
+ int i = 0;
+ int ret = 0;
+
+ if (!esc_count)
+ esc_count = -1;
+
+ /* Output any zeros remaining from the previous run */
+handle_zeros:
+ if (l->zeros_rem) {
+ int count = FFMIN(l->zeros_rem, width - i);
+ memset(dst + i, 0, count);
+ i += count;
+ l->zeros_rem -= count;
+ }
+
+ while (i < width) {
+ dst[i] = lag_get_rac(rac);
+ ret++;
+
+ if (dst[i])
+ l->zeros = 0;
+ else
+ l->zeros++;
+
+ i++;
+ if (l->zeros == esc_count) {
+ int index = lag_get_rac(rac);
+ ret++;
+
+ l->zeros = 0;
+
+ l->zeros_rem = lag_calc_zero_run(index);
+ goto handle_zeros;
+ }
+ }
+ return ret;
+}
+
+static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst,
+ const uint8_t *src, const uint8_t *src_end,
+ int width, int esc_count)
+{
+ int i = 0;
+ int count;
+ uint8_t zero_run = 0;
+ const uint8_t *src_start = src;
+ uint8_t mask1 = -(esc_count < 2);
+ uint8_t mask2 = -(esc_count < 3);
+ uint8_t *end = dst + (width - 2);
+
+ avpriv_request_sample(l->avctx, "zero_run_line");
+
+ memset(dst, 0, width);
+
+output_zeros:
+ if (l->zeros_rem) {
+ count = FFMIN(l->zeros_rem, width - i);
+ if (end - dst < count) {
+ av_log(l->avctx, AV_LOG_ERROR, "Too many zeros remaining.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ memset(dst, 0, count);
+ l->zeros_rem -= count;
+ dst += count;
+ }
+
+ while (dst < end) {
+ i = 0;
+ while (!zero_run && dst + i < end) {
+ i++;
+ if (i+2 >= src_end - src)
+ return AVERROR_INVALIDDATA;
+ zero_run =
+ !(src[i] | (src[i + 1] & mask1) | (src[i + 2] & mask2));
+ }
+ if (zero_run) {
+ zero_run = 0;
+ i += esc_count;
+ memcpy(dst, src, i);
+ dst += i;
+ l->zeros_rem = lag_calc_zero_run(src[i]);
+
+ src += i + 1;
+ goto output_zeros;
+ } else {
+ memcpy(dst, src, i);
+ src += i;
+ dst += i;
+ }
+ }
+ return src - src_start;
+}
+
+
+
+static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst,
+ int width, int height, int stride,
+ const uint8_t *src, int src_size)
+{
+ int i = 0;
+ int read = 0;
+ uint32_t length;
+ uint32_t offset = 1;
+ int esc_count;
+ GetBitContext gb;
+ lag_rac rac;
+ const uint8_t *src_end = src + src_size;
+ int ret;
+
+ rac.avctx = l->avctx;
+ l->zeros = 0;
+
+ if(src_size < 2)
+ return AVERROR_INVALIDDATA;
+
+ esc_count = src[0];
+ if (esc_count < 4) {
+ length = width * height;
+ if(src_size < 5)
+ return AVERROR_INVALIDDATA;
+ if (esc_count && AV_RL32(src + 1) < length) {
+ length = AV_RL32(src + 1);
+ offset += 4;
+ }
+
+ if ((ret = init_get_bits8(&gb, src + offset, src_size - offset)) < 0)
+ return ret;
+
+ if (lag_read_prob_header(&rac, &gb) < 0)
+ return -1;
+
+ ff_lag_rac_init(&rac, &gb, length - stride);
+
+ for (i = 0; i < height; i++)
+ read += lag_decode_line(l, &rac, dst + (i * stride), width,
+ stride, esc_count);
+
+ if (read > length)
+ av_log(l->avctx, AV_LOG_WARNING,
+ "Output more bytes than length (%d of %"PRIu32")\n", read,
+ length);
+ } else if (esc_count < 8) {
+ esc_count -= 4;
+ src ++;
+ src_size --;
+ if (esc_count > 0) {
+ /* Zero run coding only, no range coding. */
+ for (i = 0; i < height; i++) {
+ int res = lag_decode_zero_run_line(l, dst + (i * stride), src,
+ src_end, width, esc_count);
+ if (res < 0)
+ return res;
+ src += res;
+ }
+ } else {
+ if (src_size < width * height)
+ return AVERROR_INVALIDDATA; // buffer not big enough
+ /* Plane is stored uncompressed */
+ for (i = 0; i < height; i++) {
+ memcpy(dst + (i * stride), src, width);
+ src += width;
+ }
+ }
+ } else if (esc_count == 0xff) {
+ /* Plane is a solid run of given value */
+ for (i = 0; i < height; i++)
+ memset(dst + i * stride, src[1], width);
+ /* Do not apply prediction.
+ Note: memset to 0 above, setting first value to src[1]
+ and applying prediction gives the same result. */
+ return 0;
+ } else {
+ av_log(l->avctx, AV_LOG_ERROR,
+ "Invalid zero run escape code! (%#x)\n", esc_count);
+ return -1;
+ }
+
+ if (l->avctx->pix_fmt != AV_PIX_FMT_YUV422P) {
+ for (i = 0; i < height; i++) {
+ lag_pred_line(l, dst, width, stride, i);
+ dst += stride;
+ }
+ } else {
+ for (i = 0; i < height; i++) {
+ lag_pred_line_yuy2(l, dst, width, stride, i,
+ width == l->avctx->width);
+ dst += stride;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Decode a frame.
+ * @param avctx codec context
+ * @param data output AVFrame
+ * @param data_size size of output data or 0 if no picture is returned
+ * @param avpkt input packet
+ * @return number of consumed bytes on success or negative if decode fails
+ */
+static int lag_decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame, AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ unsigned int buf_size = avpkt->size;
+ LagarithContext *l = avctx->priv_data;
+ ThreadFrame frame = { .f = data };
+ AVFrame *const p = data;
+ uint8_t frametype = 0;
+ uint32_t offset_gu = 0, offset_bv = 0, offset_ry = 9;
+ uint32_t offs[4];
+ uint8_t *srcs[4], *dst;
+ int i, j, planes = 3;
+ int ret;
+
+ p->key_frame = 1;
+
+ frametype = buf[0];
+
+ offset_gu = AV_RL32(buf + 1);
+ offset_bv = AV_RL32(buf + 5);
+
+ switch (frametype) {
+ case FRAME_SOLID_RGBA:
+ avctx->pix_fmt = AV_PIX_FMT_RGB32;
+ case FRAME_SOLID_GRAY:
+ if (frametype == FRAME_SOLID_GRAY)
+ if (avctx->bits_per_coded_sample == 24) {
+ avctx->pix_fmt = AV_PIX_FMT_RGB24;
+ } else {
+ avctx->pix_fmt = AV_PIX_FMT_0RGB32;
+ planes = 4;
+ }
+
+ if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+ return ret;
+
+ dst = p->data[0];
+ if (frametype == FRAME_SOLID_RGBA) {
+ for (j = 0; j < avctx->height; j++) {
+ for (i = 0; i < avctx->width; i++)
+ AV_WN32(dst + i * 4, offset_gu);
+ dst += p->linesize[0];
+ }
+ } else {
+ for (j = 0; j < avctx->height; j++) {
+ memset(dst, buf[1], avctx->width * planes);
+ dst += p->linesize[0];
+ }
+ }
+ break;
+ case FRAME_SOLID_COLOR:
+ if (avctx->bits_per_coded_sample == 24) {
+ avctx->pix_fmt = AV_PIX_FMT_RGB24;
+ } else {
+ avctx->pix_fmt = AV_PIX_FMT_RGB32;
+ offset_gu |= 0xFFU << 24;
+ }
+
+ if ((ret = ff_thread_get_buffer(avctx, &frame,0)) < 0)
+ return ret;
+
+ dst = p->data[0];
+ for (j = 0; j < avctx->height; j++) {
+ for (i = 0; i < avctx->width; i++)
+ if (avctx->bits_per_coded_sample == 24) {
+ AV_WB24(dst + i * 3, offset_gu);
+ } else {
+ AV_WN32(dst + i * 4, offset_gu);
+ }
+ dst += p->linesize[0];
+ }
+ break;
+ case FRAME_ARITH_RGBA:
+ avctx->pix_fmt = AV_PIX_FMT_RGB32;
+ planes = 4;
+ offset_ry += 4;
+ offs[3] = AV_RL32(buf + 9);
+ case FRAME_ARITH_RGB24:
+ case FRAME_U_RGB24:
+ if (frametype == FRAME_ARITH_RGB24 || frametype == FRAME_U_RGB24)
+ avctx->pix_fmt = AV_PIX_FMT_RGB24;
+
+ if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+ return ret;
+
+ offs[0] = offset_bv;
+ offs[1] = offset_gu;
+ offs[2] = offset_ry;
+
+ l->rgb_stride = FFALIGN(avctx->width, 16);
+ av_fast_malloc(&l->rgb_planes, &l->rgb_planes_allocated,
+ l->rgb_stride * avctx->height * planes + 1);
+ if (!l->rgb_planes) {
+ av_log(avctx, AV_LOG_ERROR, "cannot allocate temporary buffer\n");
+ return AVERROR(ENOMEM);
+ }
+ for (i = 0; i < planes; i++)
+ srcs[i] = l->rgb_planes + (i + 1) * l->rgb_stride * avctx->height - l->rgb_stride;
+ for (i = 0; i < planes; i++)
+ if (buf_size <= offs[i]) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid frame offsets\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (i = 0; i < planes; i++)
+ lag_decode_arith_plane(l, srcs[i],
+ avctx->width, avctx->height,
+ -l->rgb_stride, buf + offs[i],
+ buf_size - offs[i]);
+ dst = p->data[0];
+ for (i = 0; i < planes; i++)
+ srcs[i] = l->rgb_planes + i * l->rgb_stride * avctx->height;
+ for (j = 0; j < avctx->height; j++) {
+ for (i = 0; i < avctx->width; i++) {
+ uint8_t r, g, b, a;
+ r = srcs[0][i];
+ g = srcs[1][i];
+ b = srcs[2][i];
+ r += g;
+ b += g;
+ if (frametype == FRAME_ARITH_RGBA) {
+ a = srcs[3][i];
+ AV_WN32(dst + i * 4, MKBETAG(a, r, g, b));
+ } else {
+ dst[i * 3 + 0] = r;
+ dst[i * 3 + 1] = g;
+ dst[i * 3 + 2] = b;
+ }
+ }
+ dst += p->linesize[0];
+ for (i = 0; i < planes; i++)
+ srcs[i] += l->rgb_stride;
+ }
+ break;
+ case FRAME_ARITH_YUY2:
+ avctx->pix_fmt = AV_PIX_FMT_YUV422P;
+
+ if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+ return ret;
+
+ if (offset_ry >= buf_size ||
+ offset_gu >= buf_size ||
+ offset_bv >= buf_size) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid frame offsets\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
+ p->linesize[0], buf + offset_ry,
+ buf_size - offset_ry);
+ lag_decode_arith_plane(l, p->data[1], (avctx->width + 1) / 2,
+ avctx->height, p->linesize[1],
+ buf + offset_gu, buf_size - offset_gu);
+ lag_decode_arith_plane(l, p->data[2], (avctx->width + 1) / 2,
+ avctx->height, p->linesize[2],
+ buf + offset_bv, buf_size - offset_bv);
+ break;
+ case FRAME_ARITH_YV12:
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+ if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+ return ret;
+ if (buf_size <= offset_ry || buf_size <= offset_gu || buf_size <= offset_bv) {
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (offset_ry >= buf_size ||
+ offset_gu >= buf_size ||
+ offset_bv >= buf_size) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid frame offsets\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height,
+ p->linesize[0], buf + offset_ry,
+ buf_size - offset_ry);
+ lag_decode_arith_plane(l, p->data[2], (avctx->width + 1) / 2,
+ (avctx->height + 1) / 2, p->linesize[2],
+ buf + offset_gu, buf_size - offset_gu);
+ lag_decode_arith_plane(l, p->data[1], (avctx->width + 1) / 2,
+ (avctx->height + 1) / 2, p->linesize[1],
+ buf + offset_bv, buf_size - offset_bv);
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR,
+ "Unsupported Lagarith frame type: %#"PRIx8"\n", frametype);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ *got_frame = 1;
+
+ return buf_size;
+}
+
+static av_cold int lag_decode_init(AVCodecContext *avctx)
+{
+ LagarithContext *l = avctx->priv_data;
+ l->avctx = avctx;
+
+ ff_huffyuvdsp_init(&l->hdsp);
+
+ return 0;
+}
+
+static av_cold int lag_decode_end(AVCodecContext *avctx)
+{
+ LagarithContext *l = avctx->priv_data;
+
+ av_freep(&l->rgb_planes);
+
+ return 0;
+}
+
+AVCodec ff_lagarith_decoder = {
+ .name = "lagarith",
+ .long_name = NULL_IF_CONFIG_SMALL("Lagarith lossless"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_LAGARITH,
+ .priv_data_size = sizeof(LagarithContext),
+ .init = lag_decode_init,
+ .close = lag_decode_end,
+ .decode = lag_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/lagarithrac.c b/ffmpeg-2-8-12/libavcodec/lagarithrac.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lagarithrac.c
rename to ffmpeg-2-8-12/libavcodec/lagarithrac.c
diff --git a/ffmpeg-2-8-11/libavcodec/lagarithrac.h b/ffmpeg-2-8-12/libavcodec/lagarithrac.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lagarithrac.h
rename to ffmpeg-2-8-12/libavcodec/lagarithrac.h
diff --git a/ffmpeg-2-8-11/libavcodec/latm_parser.c b/ffmpeg-2-8-12/libavcodec/latm_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/latm_parser.c
rename to ffmpeg-2-8-12/libavcodec/latm_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/lcl.h b/ffmpeg-2-8-12/libavcodec/lcl.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lcl.h
rename to ffmpeg-2-8-12/libavcodec/lcl.h
diff --git a/ffmpeg-2-8-11/libavcodec/lcldec.c b/ffmpeg-2-8-12/libavcodec/lcldec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lcldec.c
rename to ffmpeg-2-8-12/libavcodec/lcldec.c
diff --git a/ffmpeg-2-8-11/libavcodec/lclenc.c b/ffmpeg-2-8-12/libavcodec/lclenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lclenc.c
rename to ffmpeg-2-8-12/libavcodec/lclenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libaacplus.c b/ffmpeg-2-8-12/libavcodec/libaacplus.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libaacplus.c
rename to ffmpeg-2-8-12/libavcodec/libaacplus.c
diff --git a/ffmpeg-2-8-11/libavcodec/libavcodec.v b/ffmpeg-2-8-12/libavcodec/libavcodec.v
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libavcodec.v
rename to ffmpeg-2-8-12/libavcodec/libavcodec.v
diff --git a/ffmpeg-2-8-11/libavcodec/libcelt_dec.c b/ffmpeg-2-8-12/libavcodec/libcelt_dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libcelt_dec.c
rename to ffmpeg-2-8-12/libavcodec/libcelt_dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/libdcadec.c b/ffmpeg-2-8-12/libavcodec/libdcadec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libdcadec.c
rename to ffmpeg-2-8-12/libavcodec/libdcadec.c
diff --git a/ffmpeg-2-8-11/libavcodec/libfaac.c b/ffmpeg-2-8-12/libavcodec/libfaac.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libfaac.c
rename to ffmpeg-2-8-12/libavcodec/libfaac.c
diff --git a/ffmpeg-2-8-12/libavcodec/libfdk-aacdec.c b/ffmpeg-2-8-12/libavcodec/libfdk-aacdec.c
new file mode 100644
index 0000000..2857b94
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/libfdk-aacdec.c
@@ -0,0 +1,385 @@
+/*
+ * AAC decoder wrapper
+ * Copyright (c) 2012 Martin Storsjo
+ *
+ * This file is part of FFmpeg.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <fdk-aac/aacdecoder_lib.h>
+
+#include "libavutil/channel_layout.h"
+#include "libavutil/common.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "internal.h"
+
+/* The version macro is introduced the same time as the setting enum was
+ * changed, so this check should suffice. */
+#ifndef AACDECODER_LIB_VL0
+#define AAC_PCM_MAX_OUTPUT_CHANNELS AAC_PCM_OUTPUT_CHANNELS
+#endif
+
+enum ConcealMethod {
+ CONCEAL_METHOD_SPECTRAL_MUTING = 0,
+ CONCEAL_METHOD_NOISE_SUBSTITUTION = 1,
+ CONCEAL_METHOD_ENERGY_INTERPOLATION = 2,
+ CONCEAL_METHOD_NB,
+};
+
+typedef struct FDKAACDecContext {
+ const AVClass *class;
+ HANDLE_AACDECODER handle;
+ uint8_t *decoder_buffer;
+ int decoder_buffer_size;
+ uint8_t *anc_buffer;
+ int conceal_method;
+ int drc_level;
+ int drc_boost;
+ int drc_heavy;
+ int drc_cut;
+ int level_limit;
+} FDKAACDecContext;
+
+
+#define DMX_ANC_BUFFSIZE 128
+#define DECODER_MAX_CHANNELS 8
+#define DECODER_BUFFSIZE 2048 * sizeof(INT_PCM)
+
+#define OFFSET(x) offsetof(FDKAACDecContext, x)
+#define AD AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption fdk_aac_dec_options[] = {
+ { "conceal", "Error concealment method", OFFSET(conceal_method), AV_OPT_TYPE_INT, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION }, CONCEAL_METHOD_SPECTRAL_MUTING, CONCEAL_METHOD_NB - 1, AD, "conceal" },
+ { "spectral", "Spectral muting", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_SPECTRAL_MUTING }, INT_MIN, INT_MAX, AD, "conceal" },
+ { "noise", "Noise Substitution", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_NOISE_SUBSTITUTION }, INT_MIN, INT_MAX, AD, "conceal" },
+ { "energy", "Energy Interpolation", 0, AV_OPT_TYPE_CONST, { .i64 = CONCEAL_METHOD_ENERGY_INTERPOLATION }, INT_MIN, INT_MAX, AD, "conceal" },
+ { "drc_boost", "Dynamic Range Control: boost, where [0] is none and [127] is max boost",
+ OFFSET(drc_boost), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 127, AD, NULL },
+ { "drc_cut", "Dynamic Range Control: attenuation factor, where [0] is none and [127] is max compression",
+ OFFSET(drc_cut), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 127, AD, NULL },
+ { "drc_level", "Dynamic Range Control: reference level, quantized to 0.25dB steps where [0] is 0dB and [127] is -31.75dB",
+ OFFSET(drc_level), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 127, AD, NULL },
+ { "drc_heavy", "Dynamic Range Control: heavy compression, where [1] is on (RF mode) and [0] is off",
+ OFFSET(drc_heavy), AV_OPT_TYPE_INT, { .i64 = -1}, -1, 1, AD, NULL },
+#ifdef AACDECODER_LIB_VL0
+ { "level_limit", "Signal level limiting", OFFSET(level_limit), AV_OPT_TYPE_INT, { .i64 = 0 }, -1, 1, AD },
+#endif
+ { NULL }
+};
+
+static const AVClass fdk_aac_dec_class = {
+ "libfdk-aac decoder", av_default_item_name, fdk_aac_dec_options, LIBAVUTIL_VERSION_INT
+};
+
+static int get_stream_info(AVCodecContext *avctx)
+{
+ FDKAACDecContext *s = avctx->priv_data;
+ CStreamInfo *info = aacDecoder_GetStreamInfo(s->handle);
+ int channel_counts[0x24] = { 0 };
+ int i, ch_error = 0;
+ uint64_t ch_layout = 0;
+
+ if (!info) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to get stream info\n");
+ return AVERROR_UNKNOWN;
+ }
+
+ if (info->sampleRate <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Stream info not initialized\n");
+ return AVERROR_UNKNOWN;
+ }
+ avctx->sample_rate = info->sampleRate;
+ avctx->frame_size = info->frameSize;
+
+ for (i = 0; i < info->numChannels; i++) {
+ AUDIO_CHANNEL_TYPE ctype = info->pChannelType[i];
+ if (ctype <= ACT_NONE || ctype >= FF_ARRAY_ELEMS(channel_counts)) {
+ av_log(avctx, AV_LOG_WARNING, "unknown channel type\n");
+ break;
+ }
+ channel_counts[ctype]++;
+ }
+ av_log(avctx, AV_LOG_DEBUG,
+ "%d channels - front:%d side:%d back:%d lfe:%d top:%d\n",
+ info->numChannels,
+ channel_counts[ACT_FRONT], channel_counts[ACT_SIDE],
+ channel_counts[ACT_BACK], channel_counts[ACT_LFE],
+ channel_counts[ACT_FRONT_TOP] + channel_counts[ACT_SIDE_TOP] +
+ channel_counts[ACT_BACK_TOP] + channel_counts[ACT_TOP]);
+
+ switch (channel_counts[ACT_FRONT]) {
+ case 4:
+ ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_LEFT_OF_CENTER |
+ AV_CH_FRONT_RIGHT_OF_CENTER;
+ break;
+ case 3:
+ ch_layout |= AV_CH_LAYOUT_STEREO | AV_CH_FRONT_CENTER;
+ break;
+ case 2:
+ ch_layout |= AV_CH_LAYOUT_STEREO;
+ break;
+ case 1:
+ ch_layout |= AV_CH_FRONT_CENTER;
+ break;
+ default:
+ av_log(avctx, AV_LOG_WARNING,
+ "unsupported number of front channels: %d\n",
+ channel_counts[ACT_FRONT]);
+ ch_error = 1;
+ break;
+ }
+ if (channel_counts[ACT_SIDE] > 0) {
+ if (channel_counts[ACT_SIDE] == 2) {
+ ch_layout |= AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT;
+ } else {
+ av_log(avctx, AV_LOG_WARNING,
+ "unsupported number of side channels: %d\n",
+ channel_counts[ACT_SIDE]);
+ ch_error = 1;
+ }
+ }
+ if (channel_counts[ACT_BACK] > 0) {
+ switch (channel_counts[ACT_BACK]) {
+ case 3:
+ ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT | AV_CH_BACK_CENTER;
+ break;
+ case 2:
+ ch_layout |= AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT;
+ break;
+ case 1:
+ ch_layout |= AV_CH_BACK_CENTER;
+ break;
+ default:
+ av_log(avctx, AV_LOG_WARNING,
+ "unsupported number of back channels: %d\n",
+ channel_counts[ACT_BACK]);
+ ch_error = 1;
+ break;
+ }
+ }
+ if (channel_counts[ACT_LFE] > 0) {
+ if (channel_counts[ACT_LFE] == 1) {
+ ch_layout |= AV_CH_LOW_FREQUENCY;
+ } else {
+ av_log(avctx, AV_LOG_WARNING,
+ "unsupported number of LFE channels: %d\n",
+ channel_counts[ACT_LFE]);
+ ch_error = 1;
+ }
+ }
+ if (!ch_error &&
+ av_get_channel_layout_nb_channels(ch_layout) != info->numChannels) {
+ av_log(avctx, AV_LOG_WARNING, "unsupported channel configuration\n");
+ ch_error = 1;
+ }
+ if (ch_error)
+ avctx->channel_layout = 0;
+ else
+ avctx->channel_layout = ch_layout;
+
+ avctx->channels = info->numChannels;
+
+ return 0;
+}
+
+static av_cold int fdk_aac_decode_close(AVCodecContext *avctx)
+{
+ FDKAACDecContext *s = avctx->priv_data;
+
+ if (s->handle)
+ aacDecoder_Close(s->handle);
+ av_freep(&s->decoder_buffer);
+ av_freep(&s->anc_buffer);
+
+ return 0;
+}
+
+static av_cold int fdk_aac_decode_init(AVCodecContext *avctx)
+{
+ FDKAACDecContext *s = avctx->priv_data;
+ AAC_DECODER_ERROR err;
+
+ s->handle = aacDecoder_Open(avctx->extradata_size ? TT_MP4_RAW : TT_MP4_ADTS, 1);
+ if (!s->handle) {
+ av_log(avctx, AV_LOG_ERROR, "Error opening decoder\n");
+ return AVERROR_UNKNOWN;
+ }
+
+ if (avctx->extradata_size) {
+ if ((err = aacDecoder_ConfigRaw(s->handle, &avctx->extradata,
+ &avctx->extradata_size)) != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to set extradata\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if ((err = aacDecoder_SetParam(s->handle, AAC_CONCEAL_METHOD,
+ s->conceal_method)) != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to set error concealment method\n");
+ return AVERROR_UNKNOWN;
+ }
+
+ if (avctx->request_channel_layout > 0 &&
+ avctx->request_channel_layout != AV_CH_LAYOUT_NATIVE) {
+ int downmix_channels = -1;
+
+ switch (avctx->request_channel_layout) {
+ case AV_CH_LAYOUT_STEREO:
+ case AV_CH_LAYOUT_STEREO_DOWNMIX:
+ downmix_channels = 2;
+ break;
+ case AV_CH_LAYOUT_MONO:
+ downmix_channels = 1;
+ break;
+ default:
+ av_log(avctx, AV_LOG_WARNING, "Invalid request_channel_layout\n");
+ break;
+ }
+
+ if (downmix_channels != -1) {
+ if (aacDecoder_SetParam(s->handle, AAC_PCM_MAX_OUTPUT_CHANNELS,
+ downmix_channels) != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_WARNING, "Unable to set output channels in the decoder\n");
+ } else {
+ s->anc_buffer = av_malloc(DMX_ANC_BUFFSIZE);
+ if (!s->anc_buffer) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to allocate ancillary buffer for the decoder\n");
+ return AVERROR(ENOMEM);
+ }
+ if (aacDecoder_AncDataInit(s->handle, s->anc_buffer, DMX_ANC_BUFFSIZE)) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to register downmix ancillary buffer in the decoder\n");
+ return AVERROR_UNKNOWN;
+ }
+ }
+ }
+ }
+
+ if (s->drc_boost != -1) {
+ if (aacDecoder_SetParam(s->handle, AAC_DRC_BOOST_FACTOR, s->drc_boost) != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to set DRC boost factor in the decoder\n");
+ return AVERROR_UNKNOWN;
+ }
+ }
+
+ if (s->drc_cut != -1) {
+ if (aacDecoder_SetParam(s->handle, AAC_DRC_ATTENUATION_FACTOR, s->drc_cut) != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to set DRC attenuation factor in the decoder\n");
+ return AVERROR_UNKNOWN;
+ }
+ }
+
+ if (s->drc_level != -1) {
+ if (aacDecoder_SetParam(s->handle, AAC_DRC_REFERENCE_LEVEL, s->drc_level) != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to set DRC reference level in the decoder\n");
+ return AVERROR_UNKNOWN;
+ }
+ }
+
+ if (s->drc_heavy != -1) {
+ if (aacDecoder_SetParam(s->handle, AAC_DRC_HEAVY_COMPRESSION, s->drc_heavy) != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to set DRC heavy compression in the decoder\n");
+ return AVERROR_UNKNOWN;
+ }
+ }
+
+#ifdef AACDECODER_LIB_VL0
+ if (aacDecoder_SetParam(s->handle, AAC_PCM_LIMITER_ENABLE, s->level_limit) != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_ERROR, "Unable to set in signal level limiting in the decoder\n");
+ return AVERROR_UNKNOWN;
+ }
+#endif
+
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ s->decoder_buffer_size = DECODER_BUFFSIZE * DECODER_MAX_CHANNELS;
+ s->decoder_buffer = av_malloc(s->decoder_buffer_size);
+ if (!s->decoder_buffer)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static int fdk_aac_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ FDKAACDecContext *s = avctx->priv_data;
+ AVFrame *frame = data;
+ int ret;
+ AAC_DECODER_ERROR err;
+ UINT valid = avpkt->size;
+
+ err = aacDecoder_Fill(s->handle, &avpkt->data, &avpkt->size, &valid);
+ if (err != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_ERROR, "aacDecoder_Fill() failed: %x\n", err);
+ return AVERROR_INVALIDDATA;
+ }
+
+ err = aacDecoder_DecodeFrame(s->handle, (INT_PCM *) s->decoder_buffer, s->decoder_buffer_size / sizeof(INT_PCM), 0);
+ if (err == AAC_DEC_NOT_ENOUGH_BITS) {
+ ret = avpkt->size - valid;
+ goto end;
+ }
+ if (err != AAC_DEC_OK) {
+ av_log(avctx, AV_LOG_ERROR,
+ "aacDecoder_DecodeFrame() failed: %x\n", err);
+ ret = AVERROR_UNKNOWN;
+ goto end;
+ }
+
+ if ((ret = get_stream_info(avctx)) < 0)
+ goto end;
+ frame->nb_samples = avctx->frame_size;
+
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ goto end;
+
+ memcpy(frame->extended_data[0], s->decoder_buffer,
+ avctx->channels * avctx->frame_size *
+ av_get_bytes_per_sample(avctx->sample_fmt));
+
+ *got_frame_ptr = 1;
+ ret = avpkt->size - valid;
+
+end:
+ return ret;
+}
+
+static av_cold void fdk_aac_decode_flush(AVCodecContext *avctx)
+{
+ FDKAACDecContext *s = avctx->priv_data;
+ AAC_DECODER_ERROR err;
+
+ if (!s->handle)
+ return;
+
+ if ((err = aacDecoder_SetParam(s->handle,
+ AAC_TPDEC_CLEAR_BUFFER, 1)) != AAC_DEC_OK)
+ av_log(avctx, AV_LOG_WARNING, "failed to clear buffer when flushing\n");
+}
+
+AVCodec ff_libfdk_aac_decoder = {
+ .name = "libfdk_aac",
+ .long_name = NULL_IF_CONFIG_SMALL("Fraunhofer FDK AAC"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_AAC,
+ .priv_data_size = sizeof(FDKAACDecContext),
+ .init = fdk_aac_decode_init,
+ .decode = fdk_aac_decode_frame,
+ .close = fdk_aac_decode_close,
+ .flush = fdk_aac_decode_flush,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_CHANNEL_CONF,
+ .priv_class = &fdk_aac_dec_class,
+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
+ FF_CODEC_CAP_INIT_CLEANUP,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/libfdk-aacenc.c b/ffmpeg-2-8-12/libavcodec/libfdk-aacenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libfdk-aacenc.c
rename to ffmpeg-2-8-12/libavcodec/libfdk-aacenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libgsmdec.c b/ffmpeg-2-8-12/libavcodec/libgsmdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libgsmdec.c
rename to ffmpeg-2-8-12/libavcodec/libgsmdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/libgsmenc.c b/ffmpeg-2-8-12/libavcodec/libgsmenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libgsmenc.c
rename to ffmpeg-2-8-12/libavcodec/libgsmenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libilbc.c b/ffmpeg-2-8-12/libavcodec/libilbc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libilbc.c
rename to ffmpeg-2-8-12/libavcodec/libilbc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libkvazaar.c b/ffmpeg-2-8-12/libavcodec/libkvazaar.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libkvazaar.c
rename to ffmpeg-2-8-12/libavcodec/libkvazaar.c
diff --git a/ffmpeg-2-8-11/libavcodec/libmp3lame.c b/ffmpeg-2-8-12/libavcodec/libmp3lame.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libmp3lame.c
rename to ffmpeg-2-8-12/libavcodec/libmp3lame.c
diff --git a/ffmpeg-2-8-11/libavcodec/libopencore-amr.c b/ffmpeg-2-8-12/libavcodec/libopencore-amr.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libopencore-amr.c
rename to ffmpeg-2-8-12/libavcodec/libopencore-amr.c
diff --git a/ffmpeg-2-8-11/libavcodec/libopenh264enc.c b/ffmpeg-2-8-12/libavcodec/libopenh264enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libopenh264enc.c
rename to ffmpeg-2-8-12/libavcodec/libopenh264enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libopenjpegdec.c b/ffmpeg-2-8-12/libavcodec/libopenjpegdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libopenjpegdec.c
rename to ffmpeg-2-8-12/libavcodec/libopenjpegdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/libopenjpegenc.c b/ffmpeg-2-8-12/libavcodec/libopenjpegenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libopenjpegenc.c
rename to ffmpeg-2-8-12/libavcodec/libopenjpegenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libopus.c b/ffmpeg-2-8-12/libavcodec/libopus.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libopus.c
rename to ffmpeg-2-8-12/libavcodec/libopus.c
diff --git a/ffmpeg-2-8-11/libavcodec/libopus.h b/ffmpeg-2-8-12/libavcodec/libopus.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libopus.h
rename to ffmpeg-2-8-12/libavcodec/libopus.h
diff --git a/ffmpeg-2-8-11/libavcodec/libopusdec.c b/ffmpeg-2-8-12/libavcodec/libopusdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libopusdec.c
rename to ffmpeg-2-8-12/libavcodec/libopusdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/libopusenc.c b/ffmpeg-2-8-12/libavcodec/libopusenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libopusenc.c
rename to ffmpeg-2-8-12/libavcodec/libopusenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libschroedinger.c b/ffmpeg-2-8-12/libavcodec/libschroedinger.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libschroedinger.c
rename to ffmpeg-2-8-12/libavcodec/libschroedinger.c
diff --git a/ffmpeg-2-8-11/libavcodec/libschroedinger.h b/ffmpeg-2-8-12/libavcodec/libschroedinger.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libschroedinger.h
rename to ffmpeg-2-8-12/libavcodec/libschroedinger.h
diff --git a/ffmpeg-2-8-11/libavcodec/libschroedingerdec.c b/ffmpeg-2-8-12/libavcodec/libschroedingerdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libschroedingerdec.c
rename to ffmpeg-2-8-12/libavcodec/libschroedingerdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/libschroedingerenc.c b/ffmpeg-2-8-12/libavcodec/libschroedingerenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libschroedingerenc.c
rename to ffmpeg-2-8-12/libavcodec/libschroedingerenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libshine.c b/ffmpeg-2-8-12/libavcodec/libshine.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libshine.c
rename to ffmpeg-2-8-12/libavcodec/libshine.c
diff --git a/ffmpeg-2-8-11/libavcodec/libspeexdec.c b/ffmpeg-2-8-12/libavcodec/libspeexdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libspeexdec.c
rename to ffmpeg-2-8-12/libavcodec/libspeexdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/libspeexenc.c b/ffmpeg-2-8-12/libavcodec/libspeexenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libspeexenc.c
rename to ffmpeg-2-8-12/libavcodec/libspeexenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libstagefright.cpp b/ffmpeg-2-8-12/libavcodec/libstagefright.cpp
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libstagefright.cpp
rename to ffmpeg-2-8-12/libavcodec/libstagefright.cpp
diff --git a/ffmpeg-2-8-11/libavcodec/libtheoraenc.c b/ffmpeg-2-8-12/libavcodec/libtheoraenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libtheoraenc.c
rename to ffmpeg-2-8-12/libavcodec/libtheoraenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libtwolame.c b/ffmpeg-2-8-12/libavcodec/libtwolame.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libtwolame.c
rename to ffmpeg-2-8-12/libavcodec/libtwolame.c
diff --git a/ffmpeg-2-8-11/libavcodec/libutvideo.h b/ffmpeg-2-8-12/libavcodec/libutvideo.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libutvideo.h
rename to ffmpeg-2-8-12/libavcodec/libutvideo.h
diff --git a/ffmpeg-2-8-11/libavcodec/libutvideodec.cpp b/ffmpeg-2-8-12/libavcodec/libutvideodec.cpp
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libutvideodec.cpp
rename to ffmpeg-2-8-12/libavcodec/libutvideodec.cpp
diff --git a/ffmpeg-2-8-11/libavcodec/libutvideoenc.cpp b/ffmpeg-2-8-12/libavcodec/libutvideoenc.cpp
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libutvideoenc.cpp
rename to ffmpeg-2-8-12/libavcodec/libutvideoenc.cpp
diff --git a/ffmpeg-2-8-11/libavcodec/libvo-aacenc.c b/ffmpeg-2-8-12/libavcodec/libvo-aacenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libvo-aacenc.c
rename to ffmpeg-2-8-12/libavcodec/libvo-aacenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libvo-amrwbenc.c b/ffmpeg-2-8-12/libavcodec/libvo-amrwbenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libvo-amrwbenc.c
rename to ffmpeg-2-8-12/libavcodec/libvo-amrwbenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libvorbisdec.c b/ffmpeg-2-8-12/libavcodec/libvorbisdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libvorbisdec.c
rename to ffmpeg-2-8-12/libavcodec/libvorbisdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/libvorbisenc.c b/ffmpeg-2-8-12/libavcodec/libvorbisenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libvorbisenc.c
rename to ffmpeg-2-8-12/libavcodec/libvorbisenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libvpx.c b/ffmpeg-2-8-12/libavcodec/libvpx.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libvpx.c
rename to ffmpeg-2-8-12/libavcodec/libvpx.c
diff --git a/ffmpeg-2-8-11/libavcodec/libvpx.h b/ffmpeg-2-8-12/libavcodec/libvpx.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libvpx.h
rename to ffmpeg-2-8-12/libavcodec/libvpx.h
diff --git a/ffmpeg-2-8-11/libavcodec/libvpxdec.c b/ffmpeg-2-8-12/libavcodec/libvpxdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libvpxdec.c
rename to ffmpeg-2-8-12/libavcodec/libvpxdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/libvpxenc.c b/ffmpeg-2-8-12/libavcodec/libvpxenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libvpxenc.c
rename to ffmpeg-2-8-12/libavcodec/libvpxenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libwavpackenc.c b/ffmpeg-2-8-12/libavcodec/libwavpackenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libwavpackenc.c
rename to ffmpeg-2-8-12/libavcodec/libwavpackenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libwebpenc.c b/ffmpeg-2-8-12/libavcodec/libwebpenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libwebpenc.c
rename to ffmpeg-2-8-12/libavcodec/libwebpenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libwebpenc_animencoder.c b/ffmpeg-2-8-12/libavcodec/libwebpenc_animencoder.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libwebpenc_animencoder.c
rename to ffmpeg-2-8-12/libavcodec/libwebpenc_animencoder.c
diff --git a/ffmpeg-2-8-11/libavcodec/libwebpenc_common.c b/ffmpeg-2-8-12/libavcodec/libwebpenc_common.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libwebpenc_common.c
rename to ffmpeg-2-8-12/libavcodec/libwebpenc_common.c
diff --git a/ffmpeg-2-8-11/libavcodec/libwebpenc_common.h b/ffmpeg-2-8-12/libavcodec/libwebpenc_common.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libwebpenc_common.h
rename to ffmpeg-2-8-12/libavcodec/libwebpenc_common.h
diff --git a/ffmpeg-2-8-11/libavcodec/libx264.c b/ffmpeg-2-8-12/libavcodec/libx264.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libx264.c
rename to ffmpeg-2-8-12/libavcodec/libx264.c
diff --git a/ffmpeg-2-8-11/libavcodec/libx265.c b/ffmpeg-2-8-12/libavcodec/libx265.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libx265.c
rename to ffmpeg-2-8-12/libavcodec/libx265.c
diff --git a/ffmpeg-2-8-11/libavcodec/libxavs.c b/ffmpeg-2-8-12/libavcodec/libxavs.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libxavs.c
rename to ffmpeg-2-8-12/libavcodec/libxavs.c
diff --git a/ffmpeg-2-8-11/libavcodec/libxvid.c b/ffmpeg-2-8-12/libavcodec/libxvid.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libxvid.c
rename to ffmpeg-2-8-12/libavcodec/libxvid.c
diff --git a/ffmpeg-2-8-11/libavcodec/libxvid.h b/ffmpeg-2-8-12/libavcodec/libxvid.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libxvid.h
rename to ffmpeg-2-8-12/libavcodec/libxvid.h
diff --git a/ffmpeg-2-8-11/libavcodec/libxvid_rc.c b/ffmpeg-2-8-12/libavcodec/libxvid_rc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libxvid_rc.c
rename to ffmpeg-2-8-12/libavcodec/libxvid_rc.c
diff --git a/ffmpeg-2-8-11/libavcodec/libzvbi-teletextdec.c b/ffmpeg-2-8-12/libavcodec/libzvbi-teletextdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/libzvbi-teletextdec.c
rename to ffmpeg-2-8-12/libavcodec/libzvbi-teletextdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/ljpegenc.c b/ffmpeg-2-8-12/libavcodec/ljpegenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ljpegenc.c
rename to ffmpeg-2-8-12/libavcodec/ljpegenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/loco.c b/ffmpeg-2-8-12/libavcodec/loco.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/loco.c
rename to ffmpeg-2-8-12/libavcodec/loco.c
diff --git a/ffmpeg-2-8-11/libavcodec/log2_tab.c b/ffmpeg-2-8-12/libavcodec/log2_tab.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/log2_tab.c
rename to ffmpeg-2-8-12/libavcodec/log2_tab.c
diff --git a/ffmpeg-2-8-11/libavcodec/lossless_audiodsp.c b/ffmpeg-2-8-12/libavcodec/lossless_audiodsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lossless_audiodsp.c
rename to ffmpeg-2-8-12/libavcodec/lossless_audiodsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/lossless_audiodsp.h b/ffmpeg-2-8-12/libavcodec/lossless_audiodsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lossless_audiodsp.h
rename to ffmpeg-2-8-12/libavcodec/lossless_audiodsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/lossless_videodsp.c b/ffmpeg-2-8-12/libavcodec/lossless_videodsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lossless_videodsp.c
rename to ffmpeg-2-8-12/libavcodec/lossless_videodsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/lossless_videodsp.h b/ffmpeg-2-8-12/libavcodec/lossless_videodsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lossless_videodsp.h
rename to ffmpeg-2-8-12/libavcodec/lossless_videodsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/lpc.c b/ffmpeg-2-8-12/libavcodec/lpc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lpc.c
rename to ffmpeg-2-8-12/libavcodec/lpc.c
diff --git a/ffmpeg-2-8-11/libavcodec/lpc.h b/ffmpeg-2-8-12/libavcodec/lpc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lpc.h
rename to ffmpeg-2-8-12/libavcodec/lpc.h
diff --git a/ffmpeg-2-8-11/libavcodec/lsp.c b/ffmpeg-2-8-12/libavcodec/lsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lsp.c
rename to ffmpeg-2-8-12/libavcodec/lsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/lsp.h b/ffmpeg-2-8-12/libavcodec/lsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lsp.h
rename to ffmpeg-2-8-12/libavcodec/lsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/lzw.c b/ffmpeg-2-8-12/libavcodec/lzw.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lzw.c
rename to ffmpeg-2-8-12/libavcodec/lzw.c
diff --git a/ffmpeg-2-8-11/libavcodec/lzw.h b/ffmpeg-2-8-12/libavcodec/lzw.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lzw.h
rename to ffmpeg-2-8-12/libavcodec/lzw.h
diff --git a/ffmpeg-2-8-11/libavcodec/lzwenc.c b/ffmpeg-2-8-12/libavcodec/lzwenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/lzwenc.c
rename to ffmpeg-2-8-12/libavcodec/lzwenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/mace.c b/ffmpeg-2-8-12/libavcodec/mace.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mace.c
rename to ffmpeg-2-8-12/libavcodec/mace.c
diff --git a/ffmpeg-2-8-11/libavcodec/mathops.c b/ffmpeg-2-8-12/libavcodec/mathops.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mathops.c
rename to ffmpeg-2-8-12/libavcodec/mathops.c
diff --git a/ffmpeg-2-8-11/libavcodec/mathops.h b/ffmpeg-2-8-12/libavcodec/mathops.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mathops.h
rename to ffmpeg-2-8-12/libavcodec/mathops.h
diff --git a/ffmpeg-2-8-11/libavcodec/mathtables.c b/ffmpeg-2-8-12/libavcodec/mathtables.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mathtables.c
rename to ffmpeg-2-8-12/libavcodec/mathtables.c
diff --git a/ffmpeg-2-8-11/libavcodec/mdct_fixed.c b/ffmpeg-2-8-12/libavcodec/mdct_fixed.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mdct_fixed.c
rename to ffmpeg-2-8-12/libavcodec/mdct_fixed.c
diff --git a/ffmpeg-2-8-11/libavcodec/mdct_fixed_32.c b/ffmpeg-2-8-12/libavcodec/mdct_fixed_32.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mdct_fixed_32.c
rename to ffmpeg-2-8-12/libavcodec/mdct_fixed_32.c
diff --git a/ffmpeg-2-8-11/libavcodec/mdct_float.c b/ffmpeg-2-8-12/libavcodec/mdct_float.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mdct_float.c
rename to ffmpeg-2-8-12/libavcodec/mdct_float.c
diff --git a/ffmpeg-2-8-11/libavcodec/mdct_template.c b/ffmpeg-2-8-12/libavcodec/mdct_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mdct_template.c
rename to ffmpeg-2-8-12/libavcodec/mdct_template.c
diff --git a/ffmpeg-2-8-12/libavcodec/mdec.c b/ffmpeg-2-8-12/libavcodec/mdec.c
new file mode 100644
index 0000000..61ca012
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/mdec.c
@@ -0,0 +1,267 @@
+/*
+ * Sony PlayStation MDEC (Motion DECoder)
+ * Copyright (c) 2003 Michael Niedermayer
+ *
+ * based upon code from Sebastian Jedruszkiewicz <elf at frogger.rules.pl>
+ *
+ * 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
+ * Sony PlayStation MDEC (Motion DECoder)
+ * This is very similar to intra-only MPEG-1.
+ */
+
+#include "avcodec.h"
+#include "blockdsp.h"
+#include "bswapdsp.h"
+#include "idctdsp.h"
+#include "mpegvideo.h"
+#include "mpeg12.h"
+#include "thread.h"
+
+typedef struct MDECContext {
+ AVCodecContext *avctx;
+ BlockDSPContext bdsp;
+ BswapDSPContext bbdsp;
+ IDCTDSPContext idsp;
+ ThreadFrame frame;
+ GetBitContext gb;
+ ScanTable scantable;
+ int version;
+ int qscale;
+ int last_dc[3];
+ int mb_width;
+ int mb_height;
+ int mb_x, mb_y;
+ DECLARE_ALIGNED(16, int16_t, block)[6][64];
+ uint8_t *bitstream_buffer;
+ unsigned int bitstream_buffer_size;
+ int block_last_index[6];
+} MDECContext;
+
+//very similar to MPEG-1
+static inline int mdec_decode_block_intra(MDECContext *a, int16_t *block, int n)
+{
+ int level, diff, i, j, run;
+ int component;
+ RLTable *rl = &ff_rl_mpeg1;
+ uint8_t * const scantable = a->scantable.permutated;
+ const uint16_t *quant_matrix = ff_mpeg1_default_intra_matrix;
+ const int qscale = a->qscale;
+
+ /* DC coefficient */
+ if (a->version == 2) {
+ block[0] = 2 * get_sbits(&a->gb, 10) + 1024;
+ } 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);
+ }
+
+ i = 0;
+ {
+ OPEN_READER(re, &a->gb);
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ UPDATE_CACHE(re, &a->gb);
+ GET_RL_VLC(level, run, re, &a->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+
+ if (level == 127) {
+ break;
+ } else if (level != 0) {
+ i += run;
+ if (i > 63) {
+ av_log(a->avctx, AV_LOG_ERROR,
+ "ac-tex damaged at %d %d\n", a->mb_x, a->mb_y);
+ return AVERROR_INVALIDDATA;
+ }
+ j = scantable[i];
+ level = (level * qscale * quant_matrix[j]) >> 3;
+ level = (level ^ SHOW_SBITS(re, &a->gb, 1)) - SHOW_SBITS(re, &a->gb, 1);
+ LAST_SKIP_BITS(re, &a->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &a->gb, 6)+1; LAST_SKIP_BITS(re, &a->gb, 6);
+ UPDATE_CACHE(re, &a->gb);
+ level = SHOW_SBITS(re, &a->gb, 10); SKIP_BITS(re, &a->gb, 10);
+ i += run;
+ if (i > 63) {
+ av_log(a->avctx, AV_LOG_ERROR,
+ "ac-tex damaged at %d %d\n", a->mb_x, a->mb_y);
+ return AVERROR_INVALIDDATA;
+ }
+ j = scantable[i];
+ if (level < 0) {
+ level = -level;
+ level = (level * (unsigned)qscale * quant_matrix[j]) >> 3;
+ level = (level - 1) | 1;
+ level = -level;
+ } else {
+ level = (level * (unsigned)qscale * quant_matrix[j]) >> 3;
+ level = (level - 1) | 1;
+ }
+ }
+
+ block[j] = level;
+ }
+ CLOSE_READER(re, &a->gb);
+ }
+ a->block_last_index[n] = i;
+ return 0;
+}
+
+static inline int decode_mb(MDECContext *a, int16_t block[6][64])
+{
+ int i, ret;
+ static const int block_index[6] = { 5, 4, 0, 1, 2, 3 };
+
+ a->bdsp.clear_blocks(block[0]);
+
+ for (i = 0; i < 6; i++) {
+ if ((ret = mdec_decode_block_intra(a, block[block_index[i]],
+ block_index[i])) < 0)
+ return ret;
+ if (get_bits_left(&a->gb) < 0)
+ return AVERROR_INVALIDDATA;
+ }
+ return 0;
+}
+
+static inline void idct_put(MDECContext *a, AVFrame *frame, int mb_x, int mb_y)
+{
+ int16_t (*block)[64] = a->block;
+ int linesize = frame->linesize[0];
+
+ uint8_t *dest_y = frame->data[0] + (mb_y * 16* linesize ) + mb_x * 16;
+ uint8_t *dest_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8;
+ uint8_t *dest_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8;
+
+ a->idsp.idct_put(dest_y, linesize, block[0]);
+ a->idsp.idct_put(dest_y + 8, linesize, block[1]);
+ a->idsp.idct_put(dest_y + 8 * linesize, linesize, block[2]);
+ a->idsp.idct_put(dest_y + 8 * linesize + 8, linesize, block[3]);
+
+ if (!(a->avctx->flags & AV_CODEC_FLAG_GRAY)) {
+ a->idsp.idct_put(dest_cb, frame->linesize[1], block[4]);
+ a->idsp.idct_put(dest_cr, frame->linesize[2], block[5]);
+ }
+}
+
+static int decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ MDECContext * const a = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ ThreadFrame frame = { .f = data };
+ int ret;
+
+ if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
+ return ret;
+ frame.f->pict_type = AV_PICTURE_TYPE_I;
+ frame.f->key_frame = 1;
+
+ av_fast_padded_malloc(&a->bitstream_buffer, &a->bitstream_buffer_size, buf_size);
+ if (!a->bitstream_buffer)
+ return AVERROR(ENOMEM);
+ a->bbdsp.bswap16_buf((uint16_t *)a->bitstream_buffer, (uint16_t *)buf, (buf_size + 1) / 2);
+ if ((ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size)) < 0)
+ return ret;
+
+ /* skip over 4 preamble bytes in stream (typically 0xXX 0xXX 0x00 0x38) */
+ skip_bits(&a->gb, 32);
+
+ a->qscale = get_bits(&a->gb, 16);
+ a->version = get_bits(&a->gb, 16);
+
+ a->last_dc[0] = a->last_dc[1] = a->last_dc[2] = 128;
+
+ for (a->mb_x = 0; a->mb_x < a->mb_width; a->mb_x++) {
+ for (a->mb_y = 0; a->mb_y < a->mb_height; a->mb_y++) {
+ if ((ret = decode_mb(a, a->block)) < 0)
+ return ret;
+
+ idct_put(a, frame.f, a->mb_x, a->mb_y);
+ }
+ }
+
+ *got_frame = 1;
+
+ return (get_bits_count(&a->gb) + 31) / 32 * 4;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ MDECContext * const a = avctx->priv_data;
+
+ a->mb_width = (avctx->coded_width + 15) / 16;
+ a->mb_height = (avctx->coded_height + 15) / 16;
+
+ a->avctx = avctx;
+
+ ff_blockdsp_init(&a->bdsp, avctx);
+ ff_bswapdsp_init(&a->bbdsp);
+ ff_idctdsp_init(&a->idsp, avctx);
+ ff_mpeg12_init_vlcs();
+ ff_init_scantable(a->idsp.idct_permutation, &a->scantable,
+ ff_zigzag_direct);
+
+ if (avctx->idct_algo == FF_IDCT_AUTO)
+ avctx->idct_algo = FF_IDCT_SIMPLE;
+ avctx->pix_fmt = AV_PIX_FMT_YUVJ420P;
+ avctx->color_range = AVCOL_RANGE_JPEG;
+
+ return 0;
+}
+
+static av_cold int decode_init_thread_copy(AVCodecContext *avctx)
+{
+ MDECContext * const a = avctx->priv_data;
+
+ a->avctx = avctx;
+
+ return 0;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ MDECContext * const a = avctx->priv_data;
+
+ av_freep(&a->bitstream_buffer);
+ a->bitstream_buffer_size = 0;
+
+ return 0;
+}
+
+AVCodec ff_mdec_decoder = {
+ .name = "mdec",
+ .long_name = NULL_IF_CONFIG_SMALL("Sony PlayStation MDEC (Motion DECoder)"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MDEC,
+ .priv_data_size = sizeof(MDECContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy)
+};
diff --git a/ffmpeg-2-8-11/libavcodec/me_cmp.c b/ffmpeg-2-8-12/libavcodec/me_cmp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/me_cmp.c
rename to ffmpeg-2-8-12/libavcodec/me_cmp.c
diff --git a/ffmpeg-2-8-11/libavcodec/me_cmp.h b/ffmpeg-2-8-12/libavcodec/me_cmp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/me_cmp.h
rename to ffmpeg-2-8-12/libavcodec/me_cmp.h
diff --git a/ffmpeg-2-8-11/libavcodec/metasound.c b/ffmpeg-2-8-12/libavcodec/metasound.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/metasound.c
rename to ffmpeg-2-8-12/libavcodec/metasound.c
diff --git a/ffmpeg-2-8-11/libavcodec/metasound_data.c b/ffmpeg-2-8-12/libavcodec/metasound_data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/metasound_data.c
rename to ffmpeg-2-8-12/libavcodec/metasound_data.c
diff --git a/ffmpeg-2-8-11/libavcodec/metasound_data.h b/ffmpeg-2-8-12/libavcodec/metasound_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/metasound_data.h
rename to ffmpeg-2-8-12/libavcodec/metasound_data.h
diff --git a/ffmpeg-2-8-11/libavcodec/microdvddec.c b/ffmpeg-2-8-12/libavcodec/microdvddec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/microdvddec.c
rename to ffmpeg-2-8-12/libavcodec/microdvddec.c
diff --git a/ffmpeg-2-8-12/libavcodec/mimic.c b/ffmpeg-2-8-12/libavcodec/mimic.c
new file mode 100644
index 0000000..8948d4e
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/mimic.c
@@ -0,0 +1,487 @@
+/*
+ * Copyright (C) 2005 Ole André Vadla Ravnås <oleavr at gmail.com>
+ * Copyright (C) 2008 Ramiro Polla
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "avcodec.h"
+#include "blockdsp.h"
+#include "internal.h"
+#include "get_bits.h"
+#include "bytestream.h"
+#include "bswapdsp.h"
+#include "hpeldsp.h"
+#include "idctdsp.h"
+#include "thread.h"
+
+#define MIMIC_HEADER_SIZE 20
+
+typedef struct MimicContext {
+ AVCodecContext *avctx;
+
+ int num_vblocks[3];
+ int num_hblocks[3];
+
+ void *swap_buf;
+ int swap_buf_size;
+
+ int cur_index;
+ int prev_index;
+
+ ThreadFrame frames [16];
+ AVPicture flipped_ptrs[16];
+
+ DECLARE_ALIGNED(16, int16_t, dct_block)[64];
+
+ GetBitContext gb;
+ ScanTable scantable;
+ BlockDSPContext bdsp;
+ 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 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,
+};
+
+static const uint8_t col_zag[64] = {
+ 0, 8, 1, 2, 9, 16, 24, 17,
+ 10, 3, 4, 11, 18, 25, 32, 40,
+ 33, 26, 19, 12, 5, 6, 13, 20,
+ 27, 34, 41, 48, 56, 49, 42, 35,
+ 28, 21, 14, 7, 15, 22, 29, 36,
+ 43, 50, 57, 58, 51, 44, 37, 30,
+ 23, 31, 38, 45, 52, 59, 39, 46,
+ 53, 60, 61, 54, 47, 55, 62, 63,
+};
+
+static av_cold int mimic_decode_end(AVCodecContext *avctx)
+{
+ MimicContext *ctx = avctx->priv_data;
+ int i;
+
+ av_freep(&ctx->swap_buf);
+ ctx->swap_buf_size = 0;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(ctx->frames); i++) {
+ if (ctx->frames[i].f)
+ ff_thread_release_buffer(avctx, &ctx->frames[i]);
+ av_frame_free(&ctx->frames[i].f);
+ }
+
+ if (!avctx->internal->is_copy)
+ ff_free_vlc(&ctx->vlc);
+
+ return 0;
+}
+
+static av_cold int mimic_decode_init(AVCodecContext *avctx)
+{
+ MimicContext *ctx = avctx->priv_data;
+ int ret, i;
+
+ avctx->internal->allocate_progress = 1;
+
+ 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);
+ ff_idctdsp_init(&ctx->idsp, avctx);
+ ff_init_scantable(ctx->idsp.idct_permutation, &ctx->scantable, col_zag);
+
+ 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);
+ return AVERROR(ENOMEM);
+ }
+ }
+
+ return 0;
+}
+
+static int mimic_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from)
+{
+ MimicContext *dst = avctx->priv_data, *src = avctx_from->priv_data;
+ int i, ret;
+
+ if (avctx == avctx_from)
+ return 0;
+
+ dst->cur_index = src->next_cur_index;
+ dst->prev_index = src->next_prev_index;
+
+ memcpy(dst->flipped_ptrs, src->flipped_ptrs, sizeof(src->flipped_ptrs));
+
+ for (i = 0; i < FF_ARRAY_ELEMS(dst->frames); i++) {
+ ff_thread_release_buffer(avctx, &dst->frames[i]);
+ if (i != src->next_cur_index && src->frames[i].f->data[0]) {
+ ret = ff_thread_ref_frame(&dst->frames[i], &src->frames[i]);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static const int8_t vlcdec_lookup[9][64] = {
+ { 0, },
+ { -1, 1, },
+ { -3, 3, -2, 2, },
+ { -7, 7, -6, 6, -5, 5, -4, 4, },
+ { -15, 15, -14, 14, -13, 13, -12, 12,
+ -11, 11, -10, 10, -9, 9, -8, 8, },
+ { -31, 31, -30, 30, -29, 29, -28, 28,
+ -27, 27, -26, 26, -25, 25, -24, 24,
+ -23, 23, -22, 22, -21, 21, -20, 20,
+ -19, 19, -18, 18, -17, 17, -16, 16, },
+ { -63, 63, -62, 62, -61, 61, -60, 60,
+ -59, 59, -58, 58, -57, 57, -56, 56,
+ -55, 55, -54, 54, -53, 53, -52, 52,
+ -51, 51, -50, 50, -49, 49, -48, 48,
+ -47, 47, -46, 46, -45, 45, -44, 44,
+ -43, 43, -42, 42, -41, 41, -40, 40,
+ -39, 39, -38, 38, -37, 37, -36, 36,
+ -35, 35, -34, 34, -33, 33, -32, 32, },
+ { -127, 127, -126, 126, -125, 125, -124, 124,
+ -123, 123, -122, 122, -121, 121, -120, 120,
+ -119, 119, -118, 118, -117, 117, -116, 116,
+ -115, 115, -114, 114, -113, 113, -112, 112,
+ -111, 111, -110, 110, -109, 109, -108, 108,
+ -107, 107, -106, 106, -105, 105, -104, 104,
+ -103, 103, -102, 102, -101, 101, -100, 100,
+ -99, 99, -98, 98, -97, 97, -96, 96, },
+ { -95, 95, -94, 94, -93, 93, -92, 92,
+ -91, 91, -90, 90, -89, 89, -88, 88,
+ -87, 87, -86, 86, -85, 85, -84, 84,
+ -83, 83, -82, 82, -81, 81, -80, 80,
+ -79, 79, -78, 78, -77, 77, -76, 76,
+ -75, 75, -74, 74, -73, 73, -72, 72,
+ -71, 71, -70, 70, -69, 69, -68, 68,
+ -67, 67, -66, 66, -65, 65, -64, 64, },
+};
+
+static int vlc_decode_block(MimicContext *ctx, int num_coeffs, int qscale)
+{
+ int16_t *block = ctx->dct_block;
+ unsigned int pos;
+
+ ctx->bdsp.clear_block(block);
+
+ block[0] = get_bits(&ctx->gb, 8) << 3;
+
+ for (pos = 1; pos < num_coeffs; pos++) {
+ uint32_t vlc, num_bits;
+ int value;
+ int coeff;
+
+ vlc = get_vlc2(&ctx->gb, ctx->vlc.table, ctx->vlc.bits, 3);
+ if (!vlc) /* end-of-block code */
+ return 0;
+ if (vlc == -1)
+ return AVERROR_INVALIDDATA;
+
+ /* pos_add and num_bits are coded in the vlc code */
+ pos += vlc & 15; // pos_add
+ num_bits = vlc >> 4; // num_bits
+
+ if (pos >= 64)
+ return AVERROR_INVALIDDATA;
+
+ value = get_bits(&ctx->gb, num_bits);
+
+ /* FFmpeg's IDCT behaves somewhat different from the original code, so
+ * a factor of 4 was added to the input */
+
+ coeff = vlcdec_lookup[num_bits][value];
+ if (pos < 3)
+ coeff *= 16;
+ else /* TODO Use >> 10 instead of / 1001 */
+ coeff = (coeff * qscale) / 1001;
+
+ block[ctx->scantable.permutated[pos]] = coeff;
+ }
+
+ return 0;
+}
+
+static int decode(MimicContext *ctx, int quality, int num_coeffs,
+ int is_iframe)
+{
+ int ret, y, x, plane, cur_row = 0;
+
+ for (plane = 0; plane < 3; plane++) {
+ const int is_chroma = !!plane;
+ const int qscale = av_clip(10000 - quality, is_chroma ? 1000 : 2000,
+ 10000) << 2;
+ const int stride = ctx->flipped_ptrs[ctx->cur_index ].linesize[plane];
+ const uint8_t *src = ctx->flipped_ptrs[ctx->prev_index].data[plane];
+ uint8_t *dst = ctx->flipped_ptrs[ctx->cur_index ].data[plane];
+
+ for (y = 0; y < ctx->num_vblocks[plane]; y++) {
+ for (x = 0; x < ctx->num_hblocks[plane]; x++) {
+ /* Check for a change condition in the current block.
+ * - iframes always change.
+ * - Luma plane changes on get_bits1 == 0
+ * - Chroma planes change on get_bits1 == 1 */
+ if (is_iframe || get_bits1(&ctx->gb) == is_chroma) {
+ /* Luma planes may use a backreference from the 15 last
+ * frames preceding the previous. (get_bits1 == 1)
+ * Chroma planes don't use backreferences. */
+ if (is_chroma || is_iframe || !get_bits1(&ctx->gb)) {
+ if ((ret = vlc_decode_block(ctx, num_coeffs,
+ qscale)) < 0) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Error decoding "
+ "block.\n");
+ return ret;
+ }
+ ctx->idsp.idct_put(dst, stride, ctx->dct_block);
+ } else {
+ unsigned int backref = get_bits(&ctx->gb, 4);
+ int index = (ctx->cur_index + backref) & 15;
+ uint8_t *p = ctx->flipped_ptrs[index].data[0];
+
+ if (index != ctx->cur_index && p) {
+ ff_thread_await_progress(&ctx->frames[index],
+ cur_row, 0);
+ p += src -
+ ctx->flipped_ptrs[ctx->prev_index].data[plane];
+ ctx->hdsp.put_pixels_tab[1][0](dst, p, stride, 8);
+ } else {
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "No such backreference! Buggy sample.\n");
+ }
+ }
+ } else {
+ ff_thread_await_progress(&ctx->frames[ctx->prev_index],
+ cur_row, 0);
+ ctx->hdsp.put_pixels_tab[1][0](dst, src, stride, 8);
+ }
+ src += 8;
+ dst += 8;
+ }
+ src += (stride - ctx->num_hblocks[plane]) << 3;
+ dst += (stride - ctx->num_hblocks[plane]) << 3;
+
+ ff_thread_report_progress(&ctx->frames[ctx->cur_index],
+ cur_row++, 0);
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Flip the buffer upside-down and put it in the YVU order to match the
+ * way Mimic encodes frames.
+ */
+static void prepare_avpic(MimicContext *ctx, AVPicture *dst, AVFrame *src)
+{
+ int i;
+ dst->data[0] = src->data[0] + ( ctx->avctx->height - 1) * src->linesize[0];
+ dst->data[1] = src->data[2] + ((ctx->avctx->height >> 1) - 1) * src->linesize[2];
+ dst->data[2] = src->data[1] + ((ctx->avctx->height >> 1) - 1) * src->linesize[1];
+ for (i = 0; i < 3; i++)
+ dst->linesize[i] = -src->linesize[i];
+}
+
+static int mimic_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame, AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ int swap_buf_size = buf_size - MIMIC_HEADER_SIZE;
+ MimicContext *ctx = avctx->priv_data;
+ GetByteContext gb;
+ int is_pframe;
+ int width, height;
+ int quality, num_coeffs;
+ int res;
+
+ if (buf_size <= MIMIC_HEADER_SIZE) {
+ av_log(avctx, AV_LOG_ERROR, "insufficient data\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ bytestream2_init(&gb, buf, MIMIC_HEADER_SIZE);
+ bytestream2_skip(&gb, 2); /* some constant (always 256) */
+ quality = bytestream2_get_le16u(&gb);
+ width = bytestream2_get_le16u(&gb);
+ height = bytestream2_get_le16u(&gb);
+ bytestream2_skip(&gb, 4); /* some constant */
+ is_pframe = bytestream2_get_le32u(&gb);
+ num_coeffs = bytestream2_get_byteu(&gb);
+ bytestream2_skip(&gb, 3); /* some constant */
+
+ if (!ctx->avctx) {
+ int i;
+
+ if (!(width == 160 && height == 120) &&
+ !(width == 320 && height == 240)) {
+ av_log(avctx, AV_LOG_ERROR, "invalid width/height!\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ res = ff_set_dimensions(avctx, width, height);
+ if (res < 0)
+ return res;
+
+ ctx->avctx = avctx;
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+ for (i = 0; i < 3; i++) {
+ ctx->num_vblocks[i] = FF_CEIL_RSHIFT(height, 3 + !!i);
+ ctx->num_hblocks[i] = width >> (3 + !!i);
+ }
+ } else if (width != ctx->avctx->width || height != ctx->avctx->height) {
+ avpriv_request_sample(avctx, "Resolution changing");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if (is_pframe && !ctx->frames[ctx->prev_index].f->data[0]) {
+ av_log(avctx, AV_LOG_ERROR, "decoding must start with keyframe\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
+ ctx->frames[ctx->cur_index].f->pict_type = is_pframe ? AV_PICTURE_TYPE_P :
+ AV_PICTURE_TYPE_I;
+ if ((res = ff_thread_get_buffer(avctx, &ctx->frames[ctx->cur_index],
+ AV_GET_BUFFER_FLAG_REF)) < 0)
+ return res;
+
+ ctx->next_prev_index = ctx->cur_index;
+ ctx->next_cur_index = (ctx->cur_index - 1) & 15;
+
+ prepare_avpic(ctx, &ctx->flipped_ptrs[ctx->cur_index],
+ ctx->frames[ctx->cur_index].f);
+
+ ff_thread_finish_setup(avctx);
+
+ av_fast_padded_malloc(&ctx->swap_buf, &ctx->swap_buf_size, swap_buf_size);
+ if (!ctx->swap_buf)
+ return AVERROR(ENOMEM);
+
+ ctx->bbdsp.bswap_buf(ctx->swap_buf,
+ (const uint32_t *) (buf + MIMIC_HEADER_SIZE),
+ swap_buf_size >> 2);
+ init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3);
+
+ res = decode(ctx, quality, num_coeffs, !is_pframe);
+ ff_thread_report_progress(&ctx->frames[ctx->cur_index], INT_MAX, 0);
+ if (res < 0) {
+ if (!(avctx->active_thread_type & FF_THREAD_FRAME)) {
+ ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
+ return res;
+ }
+ }
+
+ if ((res = av_frame_ref(data, ctx->frames[ctx->cur_index].f)) < 0)
+ return res;
+ *got_frame = 1;
+
+ ctx->prev_index = ctx->next_prev_index;
+ ctx->cur_index = ctx->next_cur_index;
+
+ /* Only release frames that aren't used for backreferences anymore */
+ ff_thread_release_buffer(avctx, &ctx->frames[ctx->cur_index]);
+
+ return buf_size;
+}
+
+static av_cold int mimic_init_thread_copy(AVCodecContext *avctx)
+{
+ MimicContext *ctx = avctx->priv_data;
+ int i;
+
+ 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);
+ return AVERROR(ENOMEM);
+ }
+ }
+
+ return 0;
+}
+
+AVCodec ff_mimic_decoder = {
+ .name = "mimic",
+ .long_name = NULL_IF_CONFIG_SMALL("Mimic"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MIMIC,
+ .priv_data_size = sizeof(MimicContext),
+ .init = mimic_decode_init,
+ .close = mimic_decode_end,
+ .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),
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(mimic_init_thread_copy),
+};
diff --git a/ffmpeg-2-8-11/libavcodec/mips/Makefile b/ffmpeg-2-8-12/libavcodec/mips/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/Makefile
rename to ffmpeg-2-8-12/libavcodec/mips/Makefile
diff --git a/ffmpeg-2-8-11/libavcodec/mips/aaccoder_mips.c b/ffmpeg-2-8-12/libavcodec/mips/aaccoder_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/aaccoder_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/aaccoder_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/aacdec_mips.c b/ffmpeg-2-8-12/libavcodec/mips/aacdec_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/aacdec_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/aacdec_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/aacdec_mips.h b/ffmpeg-2-8-12/libavcodec/mips/aacdec_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/aacdec_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/aacdec_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/aacpsdsp_mips.c b/ffmpeg-2-8-12/libavcodec/mips/aacpsdsp_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/aacpsdsp_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/aacpsdsp_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/aacpsy_mips.h b/ffmpeg-2-8-12/libavcodec/mips/aacpsy_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/aacpsy_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/aacpsy_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/aacsbr_mips.c b/ffmpeg-2-8-12/libavcodec/mips/aacsbr_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/aacsbr_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/aacsbr_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/aacsbr_mips.h b/ffmpeg-2-8-12/libavcodec/mips/aacsbr_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/aacsbr_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/aacsbr_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/ac3dsp_mips.c b/ffmpeg-2-8-12/libavcodec/mips/ac3dsp_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/ac3dsp_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/ac3dsp_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/acelp_filters_mips.c b/ffmpeg-2-8-12/libavcodec/mips/acelp_filters_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/acelp_filters_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/acelp_filters_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/acelp_vectors_mips.c b/ffmpeg-2-8-12/libavcodec/mips/acelp_vectors_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/acelp_vectors_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/acelp_vectors_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/amrwbdec_mips.c b/ffmpeg-2-8-12/libavcodec/mips/amrwbdec_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/amrwbdec_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/amrwbdec_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/amrwbdec_mips.h b/ffmpeg-2-8-12/libavcodec/mips/amrwbdec_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/amrwbdec_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/amrwbdec_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/blockdsp_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/blockdsp_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/blockdsp_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/blockdsp_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/blockdsp_mips.h b/ffmpeg-2-8-12/libavcodec/mips/blockdsp_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/blockdsp_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/blockdsp_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/blockdsp_mmi.c b/ffmpeg-2-8-12/libavcodec/mips/blockdsp_mmi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/blockdsp_mmi.c
rename to ffmpeg-2-8-12/libavcodec/mips/blockdsp_mmi.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/blockdsp_msa.c b/ffmpeg-2-8-12/libavcodec/mips/blockdsp_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/blockdsp_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/blockdsp_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/celp_filters_mips.c b/ffmpeg-2-8-12/libavcodec/mips/celp_filters_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/celp_filters_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/celp_filters_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/celp_math_mips.c b/ffmpeg-2-8-12/libavcodec/mips/celp_math_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/celp_math_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/celp_math_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/compute_antialias_fixed.h b/ffmpeg-2-8-12/libavcodec/mips/compute_antialias_fixed.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/compute_antialias_fixed.h
rename to ffmpeg-2-8-12/libavcodec/mips/compute_antialias_fixed.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/compute_antialias_float.h b/ffmpeg-2-8-12/libavcodec/mips/compute_antialias_float.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/compute_antialias_float.h
rename to ffmpeg-2-8-12/libavcodec/mips/compute_antialias_float.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/constants.c b/ffmpeg-2-8-12/libavcodec/mips/constants.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/constants.c
rename to ffmpeg-2-8-12/libavcodec/mips/constants.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/constants.h b/ffmpeg-2-8-12/libavcodec/mips/constants.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/constants.h
rename to ffmpeg-2-8-12/libavcodec/mips/constants.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/fft_mips.c b/ffmpeg-2-8-12/libavcodec/mips/fft_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/fft_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/fft_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/fmtconvert_mips.c b/ffmpeg-2-8-12/libavcodec/mips/fmtconvert_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/fmtconvert_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/fmtconvert_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h263dsp_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/h263dsp_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h263dsp_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/h263dsp_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h263dsp_mips.h b/ffmpeg-2-8-12/libavcodec/mips/h263dsp_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h263dsp_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/h263dsp_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h263dsp_msa.c b/ffmpeg-2-8-12/libavcodec/mips/h263dsp_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h263dsp_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/h263dsp_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264chroma_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/h264chroma_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264chroma_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/h264chroma_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264chroma_mips.h b/ffmpeg-2-8-12/libavcodec/mips/h264chroma_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264chroma_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/h264chroma_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264chroma_mmi.c b/ffmpeg-2-8-12/libavcodec/mips/h264chroma_mmi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264chroma_mmi.c
rename to ffmpeg-2-8-12/libavcodec/mips/h264chroma_mmi.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264chroma_msa.c b/ffmpeg-2-8-12/libavcodec/mips/h264chroma_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264chroma_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/h264chroma_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264dsp_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/h264dsp_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264dsp_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/h264dsp_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264dsp_mips.h b/ffmpeg-2-8-12/libavcodec/mips/h264dsp_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264dsp_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/h264dsp_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264dsp_mmi.c b/ffmpeg-2-8-12/libavcodec/mips/h264dsp_mmi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264dsp_mmi.c
rename to ffmpeg-2-8-12/libavcodec/mips/h264dsp_mmi.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264dsp_msa.c b/ffmpeg-2-8-12/libavcodec/mips/h264dsp_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264dsp_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/h264dsp_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264idct_msa.c b/ffmpeg-2-8-12/libavcodec/mips/h264idct_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264idct_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/h264idct_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264pred_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/h264pred_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264pred_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/h264pred_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264pred_mips.h b/ffmpeg-2-8-12/libavcodec/mips/h264pred_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264pred_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/h264pred_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264pred_mmi.c b/ffmpeg-2-8-12/libavcodec/mips/h264pred_mmi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264pred_mmi.c
rename to ffmpeg-2-8-12/libavcodec/mips/h264pred_mmi.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264pred_msa.c b/ffmpeg-2-8-12/libavcodec/mips/h264pred_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264pred_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/h264pred_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264qpel_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/h264qpel_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264qpel_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/h264qpel_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264qpel_mmi.c b/ffmpeg-2-8-12/libavcodec/mips/h264qpel_mmi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264qpel_mmi.c
rename to ffmpeg-2-8-12/libavcodec/mips/h264qpel_mmi.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/h264qpel_msa.c b/ffmpeg-2-8-12/libavcodec/mips/h264qpel_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/h264qpel_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/h264qpel_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hevc_idct_msa.c b/ffmpeg-2-8-12/libavcodec/mips/hevc_idct_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hevc_idct_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/hevc_idct_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hevc_lpf_sao_msa.c b/ffmpeg-2-8-12/libavcodec/mips/hevc_lpf_sao_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hevc_lpf_sao_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/hevc_lpf_sao_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hevc_macros_msa.h b/ffmpeg-2-8-12/libavcodec/mips/hevc_macros_msa.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hevc_macros_msa.h
rename to ffmpeg-2-8-12/libavcodec/mips/hevc_macros_msa.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hevc_mc_bi_msa.c b/ffmpeg-2-8-12/libavcodec/mips/hevc_mc_bi_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hevc_mc_bi_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/hevc_mc_bi_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hevc_mc_biw_msa.c b/ffmpeg-2-8-12/libavcodec/mips/hevc_mc_biw_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hevc_mc_biw_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/hevc_mc_biw_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hevc_mc_uni_msa.c b/ffmpeg-2-8-12/libavcodec/mips/hevc_mc_uni_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hevc_mc_uni_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/hevc_mc_uni_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hevc_mc_uniw_msa.c b/ffmpeg-2-8-12/libavcodec/mips/hevc_mc_uniw_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hevc_mc_uniw_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/hevc_mc_uniw_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hevcdsp_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/hevcdsp_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hevcdsp_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/hevcdsp_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hevcdsp_mips.h b/ffmpeg-2-8-12/libavcodec/mips/hevcdsp_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hevcdsp_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/hevcdsp_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hevcdsp_msa.c b/ffmpeg-2-8-12/libavcodec/mips/hevcdsp_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hevcdsp_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/hevcdsp_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hevcpred_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/hevcpred_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hevcpred_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/hevcpred_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hevcpred_mips.h b/ffmpeg-2-8-12/libavcodec/mips/hevcpred_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hevcpred_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/hevcpred_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hevcpred_msa.c b/ffmpeg-2-8-12/libavcodec/mips/hevcpred_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hevcpred_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/hevcpred_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hpeldsp_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/hpeldsp_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hpeldsp_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/hpeldsp_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hpeldsp_mips.h b/ffmpeg-2-8-12/libavcodec/mips/hpeldsp_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hpeldsp_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/hpeldsp_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/hpeldsp_msa.c b/ffmpeg-2-8-12/libavcodec/mips/hpeldsp_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/hpeldsp_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/hpeldsp_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/idctdsp_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/idctdsp_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/idctdsp_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/idctdsp_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/idctdsp_mips.h b/ffmpeg-2-8-12/libavcodec/mips/idctdsp_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/idctdsp_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/idctdsp_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/idctdsp_mmi.c b/ffmpeg-2-8-12/libavcodec/mips/idctdsp_mmi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/idctdsp_mmi.c
rename to ffmpeg-2-8-12/libavcodec/mips/idctdsp_mmi.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/idctdsp_msa.c b/ffmpeg-2-8-12/libavcodec/mips/idctdsp_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/idctdsp_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/idctdsp_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/iirfilter_mips.c b/ffmpeg-2-8-12/libavcodec/mips/iirfilter_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/iirfilter_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/iirfilter_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/lsp_mips.h b/ffmpeg-2-8-12/libavcodec/mips/lsp_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/lsp_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/lsp_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/mathops.h b/ffmpeg-2-8-12/libavcodec/mips/mathops.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/mathops.h
rename to ffmpeg-2-8-12/libavcodec/mips/mathops.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/me_cmp_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/me_cmp_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/me_cmp_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/me_cmp_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/me_cmp_mips.h b/ffmpeg-2-8-12/libavcodec/mips/me_cmp_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/me_cmp_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/me_cmp_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/me_cmp_msa.c b/ffmpeg-2-8-12/libavcodec/mips/me_cmp_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/me_cmp_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/me_cmp_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/mpegaudiodsp_mips_fixed.c b/ffmpeg-2-8-12/libavcodec/mips/mpegaudiodsp_mips_fixed.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/mpegaudiodsp_mips_fixed.c
rename to ffmpeg-2-8-12/libavcodec/mips/mpegaudiodsp_mips_fixed.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/mpegaudiodsp_mips_float.c b/ffmpeg-2-8-12/libavcodec/mips/mpegaudiodsp_mips_float.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/mpegaudiodsp_mips_float.c
rename to ffmpeg-2-8-12/libavcodec/mips/mpegaudiodsp_mips_float.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/mpegvideo_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/mpegvideo_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/mpegvideo_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/mpegvideo_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/mpegvideo_mips.h b/ffmpeg-2-8-12/libavcodec/mips/mpegvideo_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/mpegvideo_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/mpegvideo_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/mpegvideo_mmi.c b/ffmpeg-2-8-12/libavcodec/mips/mpegvideo_mmi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/mpegvideo_mmi.c
rename to ffmpeg-2-8-12/libavcodec/mips/mpegvideo_mmi.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/mpegvideo_msa.c b/ffmpeg-2-8-12/libavcodec/mips/mpegvideo_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/mpegvideo_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/mpegvideo_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/mpegvideoencdsp_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/mpegvideoencdsp_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/mpegvideoencdsp_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/mpegvideoencdsp_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/mpegvideoencdsp_msa.c b/ffmpeg-2-8-12/libavcodec/mips/mpegvideoencdsp_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/mpegvideoencdsp_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/mpegvideoencdsp_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/pixblockdsp_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/pixblockdsp_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/pixblockdsp_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/pixblockdsp_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/pixblockdsp_mips.h b/ffmpeg-2-8-12/libavcodec/mips/pixblockdsp_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/pixblockdsp_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/pixblockdsp_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/pixblockdsp_mmi.c b/ffmpeg-2-8-12/libavcodec/mips/pixblockdsp_mmi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/pixblockdsp_mmi.c
rename to ffmpeg-2-8-12/libavcodec/mips/pixblockdsp_mmi.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/pixblockdsp_msa.c b/ffmpeg-2-8-12/libavcodec/mips/pixblockdsp_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/pixblockdsp_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/pixblockdsp_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/qpeldsp_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/qpeldsp_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/qpeldsp_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/qpeldsp_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/qpeldsp_mips.h b/ffmpeg-2-8-12/libavcodec/mips/qpeldsp_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/qpeldsp_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/qpeldsp_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/qpeldsp_msa.c b/ffmpeg-2-8-12/libavcodec/mips/qpeldsp_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/qpeldsp_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/qpeldsp_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/sbrdsp_mips.c b/ffmpeg-2-8-12/libavcodec/mips/sbrdsp_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/sbrdsp_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/sbrdsp_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/simple_idct_mmi.c b/ffmpeg-2-8-12/libavcodec/mips/simple_idct_mmi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/simple_idct_mmi.c
rename to ffmpeg-2-8-12/libavcodec/mips/simple_idct_mmi.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/simple_idct_msa.c b/ffmpeg-2-8-12/libavcodec/mips/simple_idct_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/simple_idct_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/simple_idct_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/vp8_idct_msa.c b/ffmpeg-2-8-12/libavcodec/mips/vp8_idct_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/vp8_idct_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/vp8_idct_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/vp8_lpf_msa.c b/ffmpeg-2-8-12/libavcodec/mips/vp8_lpf_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/vp8_lpf_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/vp8_lpf_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/vp8_mc_msa.c b/ffmpeg-2-8-12/libavcodec/mips/vp8_mc_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/vp8_mc_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/vp8_mc_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/vp8dsp_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/vp8dsp_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/vp8dsp_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/vp8dsp_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/vp8dsp_mips.h b/ffmpeg-2-8-12/libavcodec/mips/vp8dsp_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/vp8dsp_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/vp8dsp_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/vp9_idct_msa.c b/ffmpeg-2-8-12/libavcodec/mips/vp9_idct_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/vp9_idct_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/vp9_idct_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/vp9_intra_msa.c b/ffmpeg-2-8-12/libavcodec/mips/vp9_intra_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/vp9_intra_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/vp9_intra_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/vp9_lpf_msa.c b/ffmpeg-2-8-12/libavcodec/mips/vp9_lpf_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/vp9_lpf_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/vp9_lpf_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/vp9_mc_msa.c b/ffmpeg-2-8-12/libavcodec/mips/vp9_mc_msa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/vp9_mc_msa.c
rename to ffmpeg-2-8-12/libavcodec/mips/vp9_mc_msa.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/vp9dsp_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/vp9dsp_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/vp9dsp_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/vp9dsp_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/vp9dsp_mips.h b/ffmpeg-2-8-12/libavcodec/mips/vp9dsp_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/vp9dsp_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/vp9dsp_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mips/xvid_idct_mmi.c b/ffmpeg-2-8-12/libavcodec/mips/xvid_idct_mmi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/xvid_idct_mmi.c
rename to ffmpeg-2-8-12/libavcodec/mips/xvid_idct_mmi.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/xvididct_init_mips.c b/ffmpeg-2-8-12/libavcodec/mips/xvididct_init_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/xvididct_init_mips.c
rename to ffmpeg-2-8-12/libavcodec/mips/xvididct_init_mips.c
diff --git a/ffmpeg-2-8-11/libavcodec/mips/xvididct_mips.h b/ffmpeg-2-8-12/libavcodec/mips/xvididct_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mips/xvididct_mips.h
rename to ffmpeg-2-8-12/libavcodec/mips/xvididct_mips.h
diff --git a/ffmpeg-2-8-11/libavcodec/mjpeg.h b/ffmpeg-2-8-12/libavcodec/mjpeg.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mjpeg.h
rename to ffmpeg-2-8-12/libavcodec/mjpeg.h
diff --git a/ffmpeg-2-8-11/libavcodec/mjpeg2jpeg_bsf.c b/ffmpeg-2-8-12/libavcodec/mjpeg2jpeg_bsf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mjpeg2jpeg_bsf.c
rename to ffmpeg-2-8-12/libavcodec/mjpeg2jpeg_bsf.c
diff --git a/ffmpeg-2-8-11/libavcodec/mjpeg_parser.c b/ffmpeg-2-8-12/libavcodec/mjpeg_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mjpeg_parser.c
rename to ffmpeg-2-8-12/libavcodec/mjpeg_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/mjpega_dump_header_bsf.c b/ffmpeg-2-8-12/libavcodec/mjpega_dump_header_bsf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mjpega_dump_header_bsf.c
rename to ffmpeg-2-8-12/libavcodec/mjpega_dump_header_bsf.c
diff --git a/ffmpeg-2-8-11/libavcodec/mjpegbdec.c b/ffmpeg-2-8-12/libavcodec/mjpegbdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mjpegbdec.c
rename to ffmpeg-2-8-12/libavcodec/mjpegbdec.c
diff --git a/ffmpeg-2-8-12/libavcodec/mjpegdec.c b/ffmpeg-2-8-12/libavcodec/mjpegdec.c
new file mode 100644
index 0000000..b51ebf4
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/mjpegdec.c
@@ -0,0 +1,2499 @@
+/*
+ * MJPEG decoder
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2003 Alex Beregszaszi
+ * Copyright (c) 2003-2004 Michael Niedermayer
+ *
+ * Support for external huffman table, various fixes (AVID workaround),
+ * aspecting, new decode_frame mechanism and apple mjpeg-b support
+ * by Alex Beregszaszi
+ *
+ * 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
+ * MJPEG decoder.
+ */
+
+#include "libavutil/imgutils.h"
+#include "libavutil/avassert.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "blockdsp.h"
+#include "copy_block.h"
+#include "idctdsp.h"
+#include "internal.h"
+#include "jpegtables.h"
+#include "mjpeg.h"
+#include "mjpegdec.h"
+#include "jpeglsdec.h"
+#include "put_bits.h"
+#include "tiff.h"
+#include "exif.h"
+#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 void build_basic_mjpeg_vlc(MJpegDecodeContext *s)
+{
+ build_vlc(&s->vlcs[0][0], avpriv_mjpeg_bits_dc_luminance,
+ avpriv_mjpeg_val_dc, 12, 0, 0);
+ build_vlc(&s->vlcs[0][1], avpriv_mjpeg_bits_dc_chrominance,
+ avpriv_mjpeg_val_dc, 12, 0, 0);
+ build_vlc(&s->vlcs[1][0], avpriv_mjpeg_bits_ac_luminance,
+ avpriv_mjpeg_val_ac_luminance, 251, 0, 1);
+ build_vlc(&s->vlcs[1][1], avpriv_mjpeg_bits_ac_chrominance,
+ avpriv_mjpeg_val_ac_chrominance, 251, 0, 1);
+ build_vlc(&s->vlcs[2][0], avpriv_mjpeg_bits_ac_luminance,
+ avpriv_mjpeg_val_ac_luminance, 251, 0, 0);
+ build_vlc(&s->vlcs[2][1], avpriv_mjpeg_bits_ac_chrominance,
+ avpriv_mjpeg_val_ac_chrominance, 251, 0, 0);
+}
+
+static void parse_avid(MJpegDecodeContext *s, uint8_t *buf, int len)
+{
+ s->buggy_avid = 1;
+ if (len > 14 && buf[12] == 1) /* 1 - NTSC */
+ s->interlace_polarity = 1;
+ if (len > 14 && buf[12] == 2) /* 2 - PAL */
+ s->interlace_polarity = 0;
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_INFO, "AVID: len:%d %d\n", len, len > 14 ? buf[12] : -1);
+}
+
+static void init_idct(AVCodecContext *avctx)
+{
+ MJpegDecodeContext *s = avctx->priv_data;
+
+ ff_idctdsp_init(&s->idsp, avctx);
+ ff_init_scantable(s->idsp.idct_permutation, &s->scantable,
+ ff_zigzag_direct);
+}
+
+av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx)
+{
+ MJpegDecodeContext *s = avctx->priv_data;
+
+ if (!s->picture_ptr) {
+ s->picture = av_frame_alloc();
+ if (!s->picture)
+ return AVERROR(ENOMEM);
+ s->picture_ptr = s->picture;
+ }
+
+ s->avctx = avctx;
+ ff_blockdsp_init(&s->bdsp, avctx);
+ ff_hpeldsp_init(&s->hdsp, avctx->flags);
+ init_idct(avctx);
+ s->buffer_size = 0;
+ s->buffer = NULL;
+ s->start_code = -1;
+ s->first_picture = 1;
+ s->got_picture = 0;
+ s->org_height = avctx->coded_height;
+ avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
+ avctx->colorspace = AVCOL_SPC_BT470BG;
+
+ build_basic_mjpeg_vlc(s);
+
+ if (s->extern_huff) {
+ av_log(avctx, AV_LOG_INFO, "using external huffman table\n");
+ init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size * 8);
+ if (ff_mjpeg_decode_dht(s)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "error using external huffman table, switching back to internal\n");
+ build_basic_mjpeg_vlc(s);
+ }
+ }
+ if (avctx->field_order == AV_FIELD_BB) { /* quicktime icefloe 019 */
+ s->interlace_polarity = 1; /* bottom field first */
+ av_log(avctx, AV_LOG_DEBUG, "bottom field first\n");
+ } else if (avctx->field_order == AV_FIELD_UNKNOWN) {
+ if (avctx->codec_tag == AV_RL32("MJPG"))
+ s->interlace_polarity = 1;
+ }
+
+ if ( avctx->extradata_size > 8
+ && AV_RL32(avctx->extradata) == 0x2C
+ && AV_RL32(avctx->extradata+4) == 0x18) {
+ parse_avid(s, avctx->extradata, avctx->extradata_size);
+ }
+
+ if (avctx->codec->id == AV_CODEC_ID_AMV)
+ s->flipped = 1;
+
+ return 0;
+}
+
+
+/* quantize tables */
+int ff_mjpeg_decode_dqt(MJpegDecodeContext *s)
+{
+ int len, index, i, j;
+
+ len = get_bits(&s->gb, 16) - 2;
+
+ if (8*len > get_bits_left(&s->gb)) {
+ av_log(s->avctx, AV_LOG_ERROR, "dqt: len %d is too large\n", len);
+ return AVERROR_INVALIDDATA;
+ }
+
+ while (len >= 65) {
+ int pr = get_bits(&s->gb, 4);
+ if (pr > 1) {
+ av_log(s->avctx, AV_LOG_ERROR, "dqt: invalid precision\n");
+ return AVERROR_INVALIDDATA;
+ }
+ index = get_bits(&s->gb, 4);
+ if (index >= 4)
+ return -1;
+ av_log(s->avctx, AV_LOG_DEBUG, "index=%d\n", index);
+ /* read quant table */
+ for (i = 0; i < 64; i++) {
+ j = s->scantable.permutated[i];
+ s->quant_matrixes[index][j] = get_bits(&s->gb, pr ? 16 : 8);
+ }
+
+ // XXX FIXME finetune, and perhaps add dc too
+ s->qscale[index] = FFMAX(s->quant_matrixes[index][s->scantable.permutated[1]],
+ s->quant_matrixes[index][s->scantable.permutated[8]]) >> 1;
+ av_log(s->avctx, AV_LOG_DEBUG, "qscale[%d]: %d\n",
+ index, s->qscale[index]);
+ len -= 1 + 64 * (1+pr);
+ }
+ return 0;
+}
+
+/* decode huffman tables and build VLC decoders */
+int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
+{
+ int len, index, i, class, n, v, code_max;
+ uint8_t bits_table[17];
+ uint8_t val_table[256];
+ int ret = 0;
+
+ len = get_bits(&s->gb, 16) - 2;
+
+ if (8*len > get_bits_left(&s->gb)) {
+ av_log(s->avctx, AV_LOG_ERROR, "dht: len %d is too large\n", len);
+ return AVERROR_INVALIDDATA;
+ }
+
+ while (len > 0) {
+ if (len < 17)
+ return AVERROR_INVALIDDATA;
+ class = get_bits(&s->gb, 4);
+ if (class >= 2)
+ return AVERROR_INVALIDDATA;
+ index = get_bits(&s->gb, 4);
+ if (index >= 4)
+ return AVERROR_INVALIDDATA;
+ n = 0;
+ for (i = 1; i <= 16; i++) {
+ bits_table[i] = get_bits(&s->gb, 8);
+ n += bits_table[i];
+ }
+ len -= 17;
+ 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;
+
+ /* 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)
+ 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)
+ return ret;
+ }
+ }
+ return 0;
+}
+
+int ff_mjpeg_decode_sof(MJpegDecodeContext *s)
+{
+ int len, nb_components, i, width, height, bits, ret;
+ unsigned pix_fmt_id;
+ int h_count[MAX_COMPONENTS] = { 0 };
+ int v_count[MAX_COMPONENTS] = { 0 };
+
+ s->cur_scan = 0;
+ memset(s->upscale_h, 0, sizeof(s->upscale_h));
+ memset(s->upscale_v, 0, sizeof(s->upscale_v));
+
+ /* XXX: verify len field validity */
+ len = get_bits(&s->gb, 16);
+ bits = get_bits(&s->gb, 8);
+
+ if (bits > 16 || bits < 1) {
+ av_log(s->avctx, AV_LOG_ERROR, "bits %d is invalid\n", bits);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->avctx->bits_per_raw_sample != bits) {
+ av_log(s->avctx, AV_LOG_INFO, "Changeing bps to %d\n", bits);
+ s->avctx->bits_per_raw_sample = bits;
+ init_idct(s->avctx);
+ }
+ if (s->pegasus_rct)
+ bits = 9;
+ if (bits == 9 && !s->pegasus_rct)
+ s->rct = 1; // FIXME ugly
+
+ if(s->lossless && s->avctx->lowres){
+ av_log(s->avctx, AV_LOG_ERROR, "lowres is not possible with lossless jpeg\n");
+ return -1;
+ }
+
+ height = get_bits(&s->gb, 16);
+ width = get_bits(&s->gb, 16);
+
+ // HACK for odd_height.mov
+ if (s->interlaced && s->width == width && s->height == height + 1)
+ height= s->height;
+
+ av_log(s->avctx, AV_LOG_DEBUG, "sof0: picture: %dx%d\n", width, height);
+ if (av_image_check_size(width, height, 0, s->avctx))
+ return AVERROR_INVALIDDATA;
+
+ nb_components = get_bits(&s->gb, 8);
+ if (nb_components <= 0 ||
+ nb_components > MAX_COMPONENTS)
+ return -1;
+ if (s->interlaced && (s->bottom_field == !s->interlace_polarity)) {
+ if (nb_components != s->nb_components) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "nb_components changing in interlaced picture\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ if (s->ls && !(bits <= 8 || nb_components == 1)) {
+ avpriv_report_missing_feature(s->avctx,
+ "JPEG-LS that is not <= 8 "
+ "bits/component or 16-bit gray");
+ return AVERROR_PATCHWELCOME;
+ }
+ s->nb_components = nb_components;
+ s->h_max = 1;
+ s->v_max = 1;
+ for (i = 0; i < nb_components; i++) {
+ /* component id */
+ s->component_id[i] = get_bits(&s->gb, 8) - 1;
+ h_count[i] = get_bits(&s->gb, 4);
+ v_count[i] = get_bits(&s->gb, 4);
+ /* compute hmax and vmax (only used in interleaved case) */
+ if (h_count[i] > s->h_max)
+ s->h_max = h_count[i];
+ if (v_count[i] > s->v_max)
+ s->v_max = v_count[i];
+ s->quant_index[i] = get_bits(&s->gb, 8);
+ if (s->quant_index[i] >= 4) {
+ av_log(s->avctx, AV_LOG_ERROR, "quant_index is invalid\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (!h_count[i] || !v_count[i]) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid sampling factor in component %d %d:%d\n",
+ i, h_count[i], v_count[i]);
+ return AVERROR_INVALIDDATA;
+ }
+
+ av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n",
+ i, h_count[i], v_count[i],
+ s->component_id[i], s->quant_index[i]);
+ }
+ if ( nb_components == 4
+ && s->component_id[0] == 'C' - 1
+ && s->component_id[1] == 'M' - 1
+ && s->component_id[2] == 'Y' - 1
+ && s->component_id[3] == 'K' - 1)
+ s->adobe_transform = 0;
+
+ if (s->ls && (s->h_max > 1 || s->v_max > 1)) {
+ avpriv_report_missing_feature(s->avctx, "Subsampling in JPEG-LS");
+ return AVERROR_PATCHWELCOME;
+ }
+
+
+ /* if different size, realloc/alloc picture */
+ if (width != s->width || height != s->height || bits != s->bits ||
+ memcmp(s->h_count, h_count, sizeof(h_count)) ||
+ memcmp(s->v_count, v_count, sizeof(v_count))) {
+
+ s->width = width;
+ s->height = height;
+ s->bits = bits;
+ memcpy(s->h_count, h_count, sizeof(h_count));
+ memcpy(s->v_count, v_count, sizeof(v_count));
+ s->interlaced = 0;
+ s->got_picture = 0;
+
+ /* 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->interlaced = 1;
+ s->bottom_field = s->interlace_polarity;
+ s->picture_ptr->interlaced_frame = 1;
+ s->picture_ptr->top_field_first = !s->interlace_polarity;
+ height *= 2;
+ }
+
+ ret = ff_set_dimensions(s->avctx, width, height);
+ if (ret < 0)
+ return ret;
+
+ s->first_picture = 0;
+ }
+
+ if (s->got_picture && s->interlaced && (s->bottom_field == !s->interlace_polarity)) {
+ if (s->progressive) {
+ avpriv_request_sample(s->avctx, "progressively coded interlaced picture");
+ return AVERROR_INVALIDDATA;
+ }
+ } else{
+ if (s->v_max == 1 && s->h_max == 1 && s->lossless==1 && (nb_components==3 || nb_components==4))
+ s->rgb = 1;
+ else if (!s->lossless)
+ s->rgb = 0;
+ /* XXX: not complete test ! */
+ pix_fmt_id = ((unsigned)s->h_count[0] << 28) | (s->v_count[0] << 24) |
+ (s->h_count[1] << 20) | (s->v_count[1] << 16) |
+ (s->h_count[2] << 12) | (s->v_count[2] << 8) |
+ (s->h_count[3] << 4) | s->v_count[3];
+ av_log(s->avctx, AV_LOG_DEBUG, "pix fmt id %x\n", pix_fmt_id);
+ /* NOTE we do not allocate pictures large enough for the possible
+ * padding of h/v_count being 4 */
+ if (!(pix_fmt_id & 0xD0D0D0D0))
+ pix_fmt_id -= (pix_fmt_id & 0xF0F0F0F0) >> 1;
+ if (!(pix_fmt_id & 0x0D0D0D0D))
+ pix_fmt_id -= (pix_fmt_id & 0x0F0F0F0F) >> 1;
+
+ for (i = 0; i < 8; i++) {
+ int j = 6 + (i&1) - (i&6);
+ int is = (pix_fmt_id >> (4*i)) & 0xF;
+ int js = (pix_fmt_id >> (4*j)) & 0xF;
+
+ if (is == 1 && js != 2 && (i < 2 || i > 5))
+ js = (pix_fmt_id >> ( 8 + 4*(i&1))) & 0xF;
+ if (is == 1 && js != 2 && (i < 2 || i > 5))
+ js = (pix_fmt_id >> (16 + 4*(i&1))) & 0xF;
+
+ if (is == 1 && js == 2) {
+ if (i & 1) s->upscale_h[j/2] = 1;
+ else s->upscale_v[j/2] = 1;
+ }
+ }
+
+ switch (pix_fmt_id) {
+ case 0x11111100:
+ if (s->rgb)
+ s->avctx->pix_fmt = s->bits <= 9 ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_BGR48;
+ else {
+ if (s->component_id[0] == 'Q' && s->component_id[1] == 'F' && s->component_id[2] == 'A') {
+ s->avctx->pix_fmt = s->bits <= 8 ? AV_PIX_FMT_GBRP : AV_PIX_FMT_GBRP16;
+ } else {
+ if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
+ else s->avctx->pix_fmt = AV_PIX_FMT_YUV444P16;
+ s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ }
+ }
+ av_assert0(s->nb_components == 3);
+ break;
+ case 0x11111111:
+ if (s->rgb)
+ s->avctx->pix_fmt = s->bits <= 9 ? AV_PIX_FMT_ABGR : AV_PIX_FMT_RGBA64;
+ else {
+ if (s->adobe_transform == 0 && s->bits <= 8) {
+ s->avctx->pix_fmt = AV_PIX_FMT_GBRAP;
+ } else {
+ s->avctx->pix_fmt = s->bits <= 8 ? AV_PIX_FMT_YUVA444P : AV_PIX_FMT_YUVA444P16;
+ s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ }
+ }
+ av_assert0(s->nb_components == 4);
+ break;
+ case 0x22111122:
+ case 0x22111111:
+ if (s->adobe_transform == 0 && s->bits <= 8) {
+ s->avctx->pix_fmt = AV_PIX_FMT_GBRAP;
+ s->upscale_v[1] = s->upscale_v[2] = 1;
+ s->upscale_h[1] = s->upscale_h[2] = 1;
+ } else if (s->adobe_transform == 2 && s->bits <= 8) {
+ s->avctx->pix_fmt = AV_PIX_FMT_YUVA444P;
+ s->upscale_v[1] = s->upscale_v[2] = 1;
+ s->upscale_h[1] = s->upscale_h[2] = 1;
+ s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ } else {
+ if (s->bits <= 8) s->avctx->pix_fmt = AV_PIX_FMT_YUVA420P;
+ else s->avctx->pix_fmt = AV_PIX_FMT_YUVA420P16;
+ s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ }
+ av_assert0(s->nb_components == 4);
+ break;
+ case 0x12121100:
+ case 0x22122100:
+ case 0x21211100:
+ case 0x22211200:
+ if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
+ else
+ goto unk_pixfmt;
+ s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ break;
+ case 0x22221100:
+ case 0x22112200:
+ case 0x11222200:
+ if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
+ else
+ goto unk_pixfmt;
+ s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ break;
+ case 0x11000000:
+ case 0x13000000:
+ case 0x14000000:
+ case 0x31000000:
+ case 0x33000000:
+ case 0x34000000:
+ case 0x41000000:
+ case 0x43000000:
+ case 0x44000000:
+ if(s->bits <= 8)
+ s->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+ else
+ s->avctx->pix_fmt = AV_PIX_FMT_GRAY16;
+ break;
+ case 0x12111100:
+ case 0x14121200:
+ case 0x14111100:
+ case 0x22211100:
+ case 0x22112100:
+ if (s->component_id[0] == 'Q' && s->component_id[1] == 'F' && s->component_id[2] == 'A') {
+ if (s->bits <= 8) s->avctx->pix_fmt = AV_PIX_FMT_GBRP;
+ else
+ goto unk_pixfmt;
+ s->upscale_v[0] = s->upscale_v[1] = 1;
+ } else {
+ if (pix_fmt_id == 0x14111100)
+ s->upscale_v[1] = s->upscale_v[2] = 1;
+ if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV440P : AV_PIX_FMT_YUVJ440P;
+ else
+ goto unk_pixfmt;
+ s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ }
+ break;
+ case 0x21111100:
+ if (s->component_id[0] == 'Q' && s->component_id[1] == 'F' && s->component_id[2] == 'A') {
+ if (s->bits <= 8) s->avctx->pix_fmt = AV_PIX_FMT_GBRP;
+ else
+ goto unk_pixfmt;
+ s->upscale_h[0] = s->upscale_h[1] = 1;
+ } else {
+ if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P;
+ else s->avctx->pix_fmt = AV_PIX_FMT_YUV422P16;
+ s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ }
+ break;
+ case 0x31111100:
+ if (s->bits > 8)
+ goto unk_pixfmt;
+ s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_YUVJ444P;
+ s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ s->upscale_h[1] = s->upscale_h[2] = 2;
+ break;
+ case 0x22121100:
+ case 0x22111200:
+ if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV422P : AV_PIX_FMT_YUVJ422P;
+ else
+ goto unk_pixfmt;
+ s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ break;
+ case 0x22111100:
+ case 0x42111100:
+ case 0x24111100:
+ if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUVJ420P;
+ else s->avctx->pix_fmt = AV_PIX_FMT_YUV420P16;
+ s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ if (pix_fmt_id == 0x42111100) {
+ if (s->bits > 8)
+ goto unk_pixfmt;
+ s->upscale_h[1] = s->upscale_h[2] = 1;
+ } else if (pix_fmt_id == 0x24111100) {
+ if (s->bits > 8)
+ goto unk_pixfmt;
+ s->upscale_v[1] = s->upscale_v[2] = 1;
+ }
+ break;
+ case 0x41111100:
+ if (s->bits <= 8) s->avctx->pix_fmt = s->cs_itu601 ? AV_PIX_FMT_YUV411P : AV_PIX_FMT_YUVJ411P;
+ else
+ goto unk_pixfmt;
+ s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG;
+ break;
+ default:
+unk_pixfmt:
+ av_log(s->avctx, AV_LOG_ERROR, "Unhandled pixel format 0x%x bits:%d\n", pix_fmt_id, s->bits);
+ memset(s->upscale_h, 0, sizeof(s->upscale_h));
+ memset(s->upscale_v, 0, sizeof(s->upscale_v));
+ return AVERROR_PATCHWELCOME;
+ }
+ if ((AV_RB32(s->upscale_h) || AV_RB32(s->upscale_v)) && s->avctx->lowres) {
+ av_log(s->avctx, AV_LOG_ERROR, "lowres not supported for weird subsampling\n");
+ return AVERROR_PATCHWELCOME;
+ }
+ if (s->ls) {
+ memset(s->upscale_h, 0, sizeof(s->upscale_h));
+ memset(s->upscale_v, 0, sizeof(s->upscale_v));
+ if (s->nb_components == 3) {
+ s->avctx->pix_fmt = AV_PIX_FMT_RGB24;
+ } else if (s->nb_components != 1) {
+ av_log(s->avctx, AV_LOG_ERROR, "Unsupported number of components %d\n", s->nb_components);
+ return AVERROR_PATCHWELCOME;
+ } else if (s->palette_index && s->bits <= 8)
+ s->avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ else if (s->bits <= 8)
+ s->avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+ else
+ s->avctx->pix_fmt = AV_PIX_FMT_GRAY16;
+ }
+
+ s->pix_desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
+ if (!s->pix_desc) {
+ av_log(s->avctx, AV_LOG_ERROR, "Could not get a pixel format descriptor.\n");
+ return AVERROR_BUG;
+ }
+
+ av_frame_unref(s->picture_ptr);
+ if (ff_get_buffer(s->avctx, s->picture_ptr, AV_GET_BUFFER_FLAG_REF) < 0)
+ return -1;
+ s->picture_ptr->pict_type = AV_PICTURE_TYPE_I;
+ s->picture_ptr->key_frame = 1;
+ s->got_picture = 1;
+
+ for (i = 0; i < 4; i++)
+ s->linesize[i] = s->picture_ptr->linesize[i] << s->interlaced;
+
+ ff_dlog(s->avctx, "%d %d %d %d %d %d\n",
+ s->width, s->height, s->linesize[0], s->linesize[1],
+ s->interlaced, s->avctx->height);
+
+ if (len != (8 + (3 * nb_components)))
+ av_log(s->avctx, AV_LOG_DEBUG, "decode_sof0: error, len(%d) mismatch\n", len);
+ }
+
+ if ((s->rgb && !s->lossless && !s->ls) ||
+ (!s->rgb && s->ls && s->nb_components > 1)) {
+ av_log(s->avctx, AV_LOG_ERROR, "Unsupported coding and pixel format combination\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ /* totally blank picture as progressive JPEG will only add details to it */
+ if (s->progressive) {
+ int bw = (width + s->h_max * 8 - 1) / (s->h_max * 8);
+ int bh = (height + s->v_max * 8 - 1) / (s->v_max * 8);
+ for (i = 0; i < s->nb_components; i++) {
+ int size = bw * bh * s->h_count[i] * s->v_count[i];
+ av_freep(&s->blocks[i]);
+ av_freep(&s->last_nnz[i]);
+ s->blocks[i] = av_mallocz_array(size, sizeof(**s->blocks));
+ s->last_nnz[i] = av_mallocz_array(size, sizeof(**s->last_nnz));
+ if (!s->blocks[i] || !s->last_nnz[i])
+ return AVERROR(ENOMEM);
+ s->block_stride[i] = bw * s->h_count[i];
+ }
+ memset(s->coefs_finished, 0, sizeof(s->coefs_finished));
+ }
+ return 0;
+}
+
+static inline int mjpeg_decode_dc(MJpegDecodeContext *s, int dc_index)
+{
+ int code;
+ code = get_vlc2(&s->gb, s->vlcs[0][dc_index].table, 9, 2);
+ if (code < 0 || code > 16) {
+ av_log(s->avctx, AV_LOG_WARNING,
+ "mjpeg_decode_dc: bad vlc: %d:%d (%p)\n",
+ 0, dc_index, &s->vlcs[0][dc_index]);
+ return 0xfffff;
+ }
+
+ if (code)
+ return get_xbits(&s->gb, code);
+ else
+ return 0;
+}
+
+/* decode block and dequantize */
+static int decode_block(MJpegDecodeContext *s, int16_t *block, int component,
+ int dc_index, int ac_index, int16_t *quant_matrix)
+{
+ int code, i, j, level, val;
+
+ /* DC coef */
+ val = mjpeg_decode_dc(s, dc_index);
+ if (val == 0xfffff) {
+ av_log(s->avctx, AV_LOG_ERROR, "error dc\n");
+ return AVERROR_INVALIDDATA;
+ }
+ val = val * quant_matrix[0] + s->last_dc[component];
+ val = FFMIN(val, 32767);
+ s->last_dc[component] = val;
+ block[0] = val;
+ /* AC coefs */
+ i = 0;
+ {OPEN_READER(re, &s->gb);
+ do {
+ UPDATE_CACHE(re, &s->gb);
+ GET_VLC(code, re, &s->gb, s->vlcs[1][ac_index].table, 9, 2);
+
+ i += ((unsigned)code) >> 4;
+ code &= 0xf;
+ if (code) {
+ if (code > MIN_CACHE_BITS - 16)
+ UPDATE_CACHE(re, &s->gb);
+
+ {
+ int cache = GET_CACHE(re, &s->gb);
+ int sign = (~cache) >> 31;
+ level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign;
+ }
+
+ LAST_SKIP_BITS(re, &s->gb, code);
+
+ if (i > 63) {
+ av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i);
+ return AVERROR_INVALIDDATA;
+ }
+ j = s->scantable.permutated[i];
+ block[j] = level * quant_matrix[j];
+ }
+ } while (i < 63);
+ CLOSE_READER(re, &s->gb);}
+
+ return 0;
+}
+
+static int decode_dc_progressive(MJpegDecodeContext *s, int16_t *block,
+ int component, int dc_index,
+ int16_t *quant_matrix, int Al)
+{
+ unsigned val;
+ s->bdsp.clear_block(block);
+ val = mjpeg_decode_dc(s, dc_index);
+ if (val == 0xfffff) {
+ av_log(s->avctx, AV_LOG_ERROR, "error dc\n");
+ return AVERROR_INVALIDDATA;
+ }
+ val = (val * (quant_matrix[0] << Al)) + s->last_dc[component];
+ s->last_dc[component] = val;
+ block[0] = val;
+ return 0;
+}
+
+/* decode block and dequantize - progressive JPEG version */
+static int decode_block_progressive(MJpegDecodeContext *s, int16_t *block,
+ uint8_t *last_nnz, int ac_index,
+ int16_t *quant_matrix,
+ int ss, int se, int Al, int *EOBRUN)
+{
+ int code, i, j, val, run;
+ unsigned level;
+
+ if (*EOBRUN) {
+ (*EOBRUN)--;
+ return 0;
+ }
+
+ {
+ OPEN_READER(re, &s->gb);
+ for (i = ss; ; i++) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_VLC(code, re, &s->gb, s->vlcs[2][ac_index].table, 9, 2);
+
+ run = ((unsigned) code) >> 4;
+ code &= 0xF;
+ if (code) {
+ i += run;
+ if (code > MIN_CACHE_BITS - 16)
+ UPDATE_CACHE(re, &s->gb);
+
+ {
+ int cache = GET_CACHE(re, &s->gb);
+ int sign = (~cache) >> 31;
+ level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign;
+ }
+
+ LAST_SKIP_BITS(re, &s->gb, code);
+
+ if (i >= se) {
+ if (i == se) {
+ j = s->scantable.permutated[se];
+ block[j] = level * (quant_matrix[j] << Al);
+ break;
+ }
+ av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i);
+ return AVERROR_INVALIDDATA;
+ }
+ j = s->scantable.permutated[i];
+ block[j] = level * (quant_matrix[j] << Al);
+ } else {
+ if (run == 0xF) {// ZRL - skip 15 coefficients
+ i += 15;
+ if (i >= se) {
+ av_log(s->avctx, AV_LOG_ERROR, "ZRL overflow: %d\n", i);
+ return AVERROR_INVALIDDATA;
+ }
+ } else {
+ val = (1 << run);
+ if (run) {
+ UPDATE_CACHE(re, &s->gb);
+ val += NEG_USR32(GET_CACHE(re, &s->gb), run);
+ LAST_SKIP_BITS(re, &s->gb, run);
+ }
+ *EOBRUN = val - 1;
+ break;
+ }
+ }
+ }
+ CLOSE_READER(re, &s->gb);
+ }
+
+ if (i > *last_nnz)
+ *last_nnz = i;
+
+ return 0;
+}
+
+#define REFINE_BIT(j) { \
+ UPDATE_CACHE(re, &s->gb); \
+ sign = block[j] >> 15; \
+ block[j] += SHOW_UBITS(re, &s->gb, 1) * \
+ ((quant_matrix[j] ^ sign) - sign) << Al; \
+ LAST_SKIP_BITS(re, &s->gb, 1); \
+}
+
+#define ZERO_RUN \
+for (; ; i++) { \
+ if (i > last) { \
+ i += run; \
+ if (i > se) { \
+ av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i); \
+ return -1; \
+ } \
+ break; \
+ } \
+ j = s->scantable.permutated[i]; \
+ if (block[j]) \
+ REFINE_BIT(j) \
+ else if (run-- == 0) \
+ break; \
+}
+
+/* decode block and dequantize - progressive JPEG refinement pass */
+static int decode_block_refinement(MJpegDecodeContext *s, int16_t *block,
+ uint8_t *last_nnz,
+ int ac_index, int16_t *quant_matrix,
+ int ss, int se, int Al, int *EOBRUN)
+{
+ int code, i = ss, j, sign, val, run;
+ int last = FFMIN(se, *last_nnz);
+
+ OPEN_READER(re, &s->gb);
+ if (*EOBRUN) {
+ (*EOBRUN)--;
+ } else {
+ for (; ; i++) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_VLC(code, re, &s->gb, s->vlcs[2][ac_index].table, 9, 2);
+
+ if (code & 0xF) {
+ run = ((unsigned) code) >> 4;
+ UPDATE_CACHE(re, &s->gb);
+ val = SHOW_UBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ ZERO_RUN;
+ j = s->scantable.permutated[i];
+ val--;
+ block[j] = ((quant_matrix[j] << Al) ^ val) - val;
+ if (i == se) {
+ if (i > *last_nnz)
+ *last_nnz = i;
+ CLOSE_READER(re, &s->gb);
+ return 0;
+ }
+ } else {
+ run = ((unsigned) code) >> 4;
+ if (run == 0xF) {
+ ZERO_RUN;
+ } else {
+ val = run;
+ run = (1 << run);
+ if (val) {
+ UPDATE_CACHE(re, &s->gb);
+ run += SHOW_UBITS(re, &s->gb, val);
+ LAST_SKIP_BITS(re, &s->gb, val);
+ }
+ *EOBRUN = run - 1;
+ break;
+ }
+ }
+ }
+
+ if (i > *last_nnz)
+ *last_nnz = i;
+ }
+
+ for (; i <= last; i++) {
+ j = s->scantable.permutated[i];
+ if (block[j])
+ REFINE_BIT(j)
+ }
+ CLOSE_READER(re, &s->gb);
+
+ return 0;
+}
+#undef REFINE_BIT
+#undef ZERO_RUN
+
+static int handle_rstn(MJpegDecodeContext *s, int nb_components)
+{
+ int i;
+ int reset = 0;
+
+ if (s->restart_interval) {
+ s->restart_count--;
+ if(s->restart_count == 0 && s->avctx->codec_id == AV_CODEC_ID_THP){
+ align_get_bits(&s->gb);
+ for (i = 0; i < nb_components; i++) /* reset dc */
+ s->last_dc[i] = (4 << s->bits);
+ }
+
+ i = 8 + ((-get_bits_count(&s->gb)) & 7);
+ /* skip RSTn */
+ if (s->restart_count == 0) {
+ if( show_bits(&s->gb, i) == (1 << i) - 1
+ || show_bits(&s->gb, i) == 0xFF) {
+ int pos = get_bits_count(&s->gb);
+ align_get_bits(&s->gb);
+ while (get_bits_left(&s->gb) >= 8 && show_bits(&s->gb, 8) == 0xFF)
+ skip_bits(&s->gb, 8);
+ if (get_bits_left(&s->gb) >= 8 && (get_bits(&s->gb, 8) & 0xF8) == 0xD0) {
+ for (i = 0; i < nb_components; i++) /* reset dc */
+ s->last_dc[i] = (4 << s->bits);
+ reset = 1;
+ } else
+ skip_bits_long(&s->gb, pos - get_bits_count(&s->gb));
+ }
+ }
+ }
+ return reset;
+}
+
+static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int predictor, int point_transform)
+{
+ int i, mb_x, mb_y;
+ uint16_t (*buffer)[4];
+ int left[4], top[4], topleft[4];
+ const int linesize = s->linesize[0];
+ const int mask = ((1 << s->bits) - 1) << point_transform;
+ int resync_mb_y = 0;
+ int resync_mb_x = 0;
+
+ if (s->nb_components != 3 && s->nb_components != 4)
+ return AVERROR_INVALIDDATA;
+ if (s->v_max != 1 || s->h_max != 1 || !s->lossless)
+ return AVERROR_INVALIDDATA;
+
+
+ s->restart_count = s->restart_interval;
+
+ av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size,
+ (unsigned)s->mb_width * 4 * sizeof(s->ljpeg_buffer[0][0]));
+ buffer = s->ljpeg_buffer;
+
+ for (i = 0; i < 4; i++)
+ buffer[0][i] = 1 << (s->bits - 1);
+
+ for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
+ uint8_t *ptr = s->picture_ptr->data[0] + (linesize * mb_y);
+
+ if (s->interlaced && s->bottom_field)
+ ptr += linesize >> 1;
+
+ for (i = 0; i < 4; i++)
+ top[i] = left[i] = topleft[i] = buffer[0][i];
+
+ for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+ int modified_predictor = predictor;
+
+ if (s->restart_interval && !s->restart_count){
+ s->restart_count = s->restart_interval;
+ resync_mb_x = mb_x;
+ resync_mb_y = mb_y;
+ for(i=0; i<4; i++)
+ top[i] = left[i]= topleft[i]= 1 << (s->bits - 1);
+ }
+ if (mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x || !mb_x)
+ modified_predictor = 1;
+
+ for (i=0;i<nb_components;i++) {
+ int pred, dc;
+
+ topleft[i] = top[i];
+ top[i] = buffer[mb_x][i];
+
+ PREDICT(pred, topleft[i], top[i], left[i], modified_predictor);
+
+ dc = mjpeg_decode_dc(s, s->dc_index[i]);
+ if(dc == 0xFFFFF)
+ return -1;
+
+ left[i] = buffer[mb_x][i] =
+ mask & (pred + (dc * (1 << point_transform)));
+ }
+
+ if (s->restart_interval && !--s->restart_count) {
+ align_get_bits(&s->gb);
+ skip_bits(&s->gb, 16); /* skip RSTn */
+ }
+ }
+ if (s->rct && s->nb_components == 4) {
+ for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+ ptr[4*mb_x + 2] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200) >> 2);
+ ptr[4*mb_x + 1] = buffer[mb_x][1] + ptr[4*mb_x + 2];
+ ptr[4*mb_x + 3] = buffer[mb_x][2] + ptr[4*mb_x + 2];
+ ptr[4*mb_x + 0] = buffer[mb_x][3];
+ }
+ } else if (s->nb_components == 4) {
+ for(i=0; i<nb_components; i++) {
+ int c= s->comp_index[i];
+ if (s->bits <= 8) {
+ for(mb_x = 0; mb_x < s->mb_width; mb_x++) {
+ ptr[4*mb_x+3-c] = buffer[mb_x][i];
+ }
+ } else if(s->bits == 9) {
+ return AVERROR_PATCHWELCOME;
+ } else {
+ for(mb_x = 0; mb_x < s->mb_width; mb_x++) {
+ ((uint16_t*)ptr)[4*mb_x+c] = buffer[mb_x][i];
+ }
+ }
+ }
+ } else if (s->rct) {
+ for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+ ptr[3*mb_x + 1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200) >> 2);
+ ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1];
+ ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*mb_x + 1];
+ }
+ } else if (s->pegasus_rct) {
+ for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+ ptr[3*mb_x + 1] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2]) >> 2);
+ ptr[3*mb_x + 0] = buffer[mb_x][1] + ptr[3*mb_x + 1];
+ ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*mb_x + 1];
+ }
+ } else {
+ for(i=0; i<nb_components; i++) {
+ int c= s->comp_index[i];
+ if (s->bits <= 8) {
+ for(mb_x = 0; mb_x < s->mb_width; mb_x++) {
+ ptr[3*mb_x+2-c] = buffer[mb_x][i];
+ }
+ } else if(s->bits == 9) {
+ return AVERROR_PATCHWELCOME;
+ } else {
+ for(mb_x = 0; mb_x < s->mb_width; mb_x++) {
+ ((uint16_t*)ptr)[3*mb_x+2-c] = buffer[mb_x][i];
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor,
+ int point_transform, int nb_components)
+{
+ int i, mb_x, mb_y, mask;
+ int bits= (s->bits+7)&~7;
+ int resync_mb_y = 0;
+ int resync_mb_x = 0;
+
+ point_transform += bits - s->bits;
+ mask = ((1 << s->bits) - 1) << point_transform;
+
+ av_assert0(nb_components>=1 && nb_components<=4);
+
+ for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
+ for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+ if (get_bits_left(&s->gb) < 1) {
+ av_log(s->avctx, AV_LOG_ERROR, "bitstream end in yuv_scan\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->restart_interval && !s->restart_count){
+ s->restart_count = s->restart_interval;
+ resync_mb_x = mb_x;
+ resync_mb_y = mb_y;
+ }
+
+ if(!mb_x || mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x || s->interlaced){
+ int toprow = mb_y == resync_mb_y || mb_y == resync_mb_y+1 && mb_x < resync_mb_x;
+ int leftcol = !mb_x || mb_y == resync_mb_y && mb_x == resync_mb_x;
+ for (i = 0; i < nb_components; i++) {
+ uint8_t *ptr;
+ uint16_t *ptr16;
+ int n, h, v, x, y, c, j, linesize;
+ n = s->nb_blocks[i];
+ c = s->comp_index[i];
+ h = s->h_scount[i];
+ v = s->v_scount[i];
+ x = 0;
+ y = 0;
+ linesize= s->linesize[c];
+
+ if(bits>8) linesize /= 2;
+
+ for(j=0; j<n; j++) {
+ int pred, dc;
+
+ dc = mjpeg_decode_dc(s, s->dc_index[i]);
+ if(dc == 0xFFFFF)
+ return -1;
+ if ( h * mb_x + x >= s->width
+ || v * mb_y + y >= s->height) {
+ // Nothing to do
+ } else if (bits<=8) {
+ ptr = s->picture_ptr->data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap
+ if(y==0 && toprow){
+ if(x==0 && leftcol){
+ pred= 1 << (bits - 1);
+ }else{
+ pred= ptr[-1];
+ }
+ }else{
+ if(x==0 && leftcol){
+ pred= ptr[-linesize];
+ }else{
+ PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
+ }
+ }
+
+ if (s->interlaced && s->bottom_field)
+ ptr += linesize >> 1;
+ pred &= mask;
+ *ptr= pred + ((unsigned)dc << point_transform);
+ }else{
+ ptr16 = (uint16_t*)(s->picture_ptr->data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap
+ if(y==0 && toprow){
+ if(x==0 && leftcol){
+ pred= 1 << (bits - 1);
+ }else{
+ pred= ptr16[-1];
+ }
+ }else{
+ if(x==0 && leftcol){
+ pred= ptr16[-linesize];
+ }else{
+ PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor);
+ }
+ }
+
+ if (s->interlaced && s->bottom_field)
+ ptr16 += linesize >> 1;
+ pred &= mask;
+ *ptr16= pred + ((unsigned)dc << point_transform);
+ }
+ if (++x == h) {
+ x = 0;
+ y++;
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < nb_components; i++) {
+ uint8_t *ptr;
+ uint16_t *ptr16;
+ int n, h, v, x, y, c, j, linesize, dc;
+ n = s->nb_blocks[i];
+ c = s->comp_index[i];
+ h = s->h_scount[i];
+ v = s->v_scount[i];
+ x = 0;
+ y = 0;
+ linesize = s->linesize[c];
+
+ if(bits>8) linesize /= 2;
+
+ for (j = 0; j < n; j++) {
+ int pred;
+
+ dc = mjpeg_decode_dc(s, s->dc_index[i]);
+ if(dc == 0xFFFFF)
+ return -1;
+ if ( h * mb_x + x >= s->width
+ || v * mb_y + y >= s->height) {
+ // Nothing to do
+ } else if (bits<=8) {
+ ptr = s->picture_ptr->data[c] +
+ (linesize * (v * mb_y + y)) +
+ (h * mb_x + x); //FIXME optimize this crap
+ PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor);
+
+ pred &= mask;
+ *ptr = pred + ((unsigned)dc << point_transform);
+ }else{
+ ptr16 = (uint16_t*)(s->picture_ptr->data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap
+ PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor);
+
+ pred &= mask;
+ *ptr16= pred + ((unsigned)dc << point_transform);
+ }
+
+ if (++x == h) {
+ x = 0;
+ y++;
+ }
+ }
+ }
+ }
+ if (s->restart_interval && !--s->restart_count) {
+ align_get_bits(&s->gb);
+ skip_bits(&s->gb, 16); /* skip RSTn */
+ }
+ }
+ }
+ return 0;
+}
+
+static av_always_inline void mjpeg_copy_block(MJpegDecodeContext *s,
+ uint8_t *dst, const uint8_t *src,
+ int linesize, int lowres)
+{
+ switch (lowres) {
+ case 0: s->hdsp.put_pixels_tab[1][0](dst, src, linesize, 8);
+ break;
+ case 1: copy_block4(dst, src, linesize, linesize, 4);
+ break;
+ case 2: copy_block2(dst, src, linesize, linesize, 2);
+ break;
+ case 3: *dst = *src;
+ break;
+ }
+}
+
+static void shift_output(MJpegDecodeContext *s, uint8_t *ptr, int linesize)
+{
+ int block_x, block_y;
+ int size = 8 >> s->avctx->lowres;
+ if (s->bits > 8) {
+ for (block_y=0; block_y<size; block_y++)
+ for (block_x=0; block_x<size; block_x++)
+ *(uint16_t*)(ptr + 2*block_x + block_y*linesize) <<= 16 - s->bits;
+ } else {
+ for (block_y=0; block_y<size; block_y++)
+ for (block_x=0; block_x<size; block_x++)
+ *(ptr + block_x + block_y*linesize) <<= 8 - s->bits;
+ }
+}
+
+static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,
+ int Al, const uint8_t *mb_bitmask,
+ int mb_bitmask_size,
+ const AVFrame *reference)
+{
+ int i, mb_x, mb_y, chroma_h_shift, chroma_v_shift, chroma_width, chroma_height;
+ uint8_t *data[MAX_COMPONENTS];
+ const uint8_t *reference_data[MAX_COMPONENTS];
+ int linesize[MAX_COMPONENTS];
+ GetBitContext mb_bitmask_gb = {0}; // initialize to silence gcc warning
+ int bytes_per_pixel = 1 + (s->bits > 8);
+
+ if (mb_bitmask) {
+ if (mb_bitmask_size != (s->mb_width * s->mb_height + 7)>>3) {
+ av_log(s->avctx, AV_LOG_ERROR, "mb_bitmask_size mismatches\n");
+ return AVERROR_INVALIDDATA;
+ }
+ init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height);
+ }
+
+ s->restart_count = 0;
+
+ av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt, &chroma_h_shift,
+ &chroma_v_shift);
+ chroma_width = FF_CEIL_RSHIFT(s->width, chroma_h_shift);
+ chroma_height = FF_CEIL_RSHIFT(s->height, chroma_v_shift);
+
+ for (i = 0; i < nb_components; i++) {
+ int c = s->comp_index[i];
+ data[c] = s->picture_ptr->data[c];
+ reference_data[c] = reference ? reference->data[c] : NULL;
+ linesize[c] = s->linesize[c];
+ s->coefs_finished[c] |= 1;
+ }
+
+ for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
+ for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
+ const int copy_mb = mb_bitmask && !get_bits1(&mb_bitmask_gb);
+
+ if (s->restart_interval && !s->restart_count)
+ s->restart_count = s->restart_interval;
+
+ if (get_bits_left(&s->gb) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "overread %d\n",
+ -get_bits_left(&s->gb));
+ return AVERROR_INVALIDDATA;
+ }
+ for (i = 0; i < nb_components; i++) {
+ uint8_t *ptr;
+ int n, h, v, x, y, c, j;
+ int block_offset;
+ n = s->nb_blocks[i];
+ c = s->comp_index[i];
+ h = s->h_scount[i];
+ v = s->v_scount[i];
+ x = 0;
+ y = 0;
+ for (j = 0; j < n; j++) {
+ block_offset = (((linesize[c] * (v * mb_y + y) * 8) +
+ (h * mb_x + x) * 8 * bytes_per_pixel) >> s->avctx->lowres);
+
+ if (s->interlaced && s->bottom_field)
+ block_offset += linesize[c] >> 1;
+ if ( 8*(h * mb_x + x) < ((c == 1) || (c == 2) ? chroma_width : s->width)
+ && 8*(v * mb_y + y) < ((c == 1) || (c == 2) ? chroma_height : s->height)) {
+ ptr = data[c] + block_offset;
+ } else
+ ptr = NULL;
+ if (!s->progressive) {
+ if (copy_mb) {
+ if (ptr)
+ mjpeg_copy_block(s, ptr, reference_data[c] + block_offset,
+ linesize[c], s->avctx->lowres);
+
+ } else {
+ s->bdsp.clear_block(s->block);
+ if (decode_block(s, s->block, i,
+ s->dc_index[i], s->ac_index[i],
+ s->quant_matrixes[s->quant_sindex[i]]) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "error y=%d x=%d\n", mb_y, mb_x);
+ return AVERROR_INVALIDDATA;
+ }
+ if (ptr) {
+ s->idsp.idct_put(ptr, linesize[c], s->block);
+ if (s->bits & 7)
+ shift_output(s, ptr, linesize[c]);
+ }
+ }
+ } else {
+ int block_idx = s->block_stride[c] * (v * mb_y + y) +
+ (h * mb_x + x);
+ int16_t *block = s->blocks[c][block_idx];
+ if (Ah)
+ block[0] += get_bits1(&s->gb) *
+ s->quant_matrixes[s->quant_sindex[i]][0] << Al;
+ else if (decode_dc_progressive(s, block, i, s->dc_index[i],
+ s->quant_matrixes[s->quant_sindex[i]],
+ Al) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "error y=%d x=%d\n", mb_y, mb_x);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ ff_dlog(s->avctx, "mb: %d %d processed\n", mb_y, mb_x);
+ ff_dlog(s->avctx, "%d %d %d %d %d %d %d %d \n",
+ mb_x, mb_y, x, y, c, s->bottom_field,
+ (v * mb_y + y) * 8, (h * mb_x + x) * 8);
+ if (++x == h) {
+ x = 0;
+ y++;
+ }
+ }
+ }
+
+ handle_rstn(s, nb_components);
+ }
+ }
+ return 0;
+}
+
+static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss,
+ int se, int Ah, int Al)
+{
+ int mb_x, mb_y;
+ int EOBRUN = 0;
+ int c = s->comp_index[0];
+ int16_t *quant_matrix = s->quant_matrixes[s->quant_sindex[0]];
+
+ av_assert0(ss>=0 && Ah>=0 && Al>=0);
+ if (se < ss || se > 63) {
+ av_log(s->avctx, AV_LOG_ERROR, "SS/SE %d/%d is invalid\n", ss, se);
+ return AVERROR_INVALIDDATA;
+ }
+
+ // s->coefs_finished is a bitmask for coefficients coded
+ // ss and se are parameters telling start and end coefficients
+ s->coefs_finished[c] |= (2ULL << se) - (1ULL << ss);
+
+ s->restart_count = 0;
+
+ for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
+ int block_idx = mb_y * s->block_stride[c];
+ int16_t (*block)[64] = &s->blocks[c][block_idx];
+ uint8_t *last_nnz = &s->last_nnz[c][block_idx];
+ if (get_bits_left(&s->gb) <= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "bitstream truncated in mjpeg_decode_scan_progressive_ac\n");
+ return AVERROR_INVALIDDATA;
+ }
+ for (mb_x = 0; mb_x < s->mb_width; mb_x++, block++, last_nnz++) {
+ int ret;
+ if (s->restart_interval && !s->restart_count)
+ s->restart_count = s->restart_interval;
+
+ if (Ah)
+ ret = decode_block_refinement(s, *block, last_nnz, s->ac_index[0],
+ quant_matrix, ss, se, Al, &EOBRUN);
+ else
+ ret = decode_block_progressive(s, *block, last_nnz, s->ac_index[0],
+ quant_matrix, ss, se, Al, &EOBRUN);
+ if (ret < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "error y=%d x=%d\n", mb_y, mb_x);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (handle_rstn(s, 0))
+ EOBRUN = 0;
+ }
+ }
+ return 0;
+}
+
+static void mjpeg_idct_scan_progressive_ac(MJpegDecodeContext *s)
+{
+ int mb_x, mb_y;
+ int c;
+ const int bytes_per_pixel = 1 + (s->bits > 8);
+ const int block_size = s->lossless ? 1 : 8;
+
+ for (c = 0; c < s->nb_components; c++) {
+ uint8_t *data = s->picture_ptr->data[c];
+ int linesize = s->linesize[c];
+ int h = s->h_max / s->h_count[c];
+ int v = s->v_max / s->v_count[c];
+ int mb_width = (s->width + h * block_size - 1) / (h * block_size);
+ int mb_height = (s->height + v * block_size - 1) / (v * block_size);
+
+ if (~s->coefs_finished[c])
+ av_log(s->avctx, AV_LOG_WARNING, "component %d is incomplete\n", c);
+
+ if (s->interlaced && s->bottom_field)
+ data += linesize >> 1;
+
+ for (mb_y = 0; mb_y < mb_height; mb_y++) {
+ uint8_t *ptr = data + (mb_y * linesize * 8 >> s->avctx->lowres);
+ int block_idx = mb_y * s->block_stride[c];
+ int16_t (*block)[64] = &s->blocks[c][block_idx];
+ for (mb_x = 0; mb_x < mb_width; mb_x++, block++) {
+ s->idsp.idct_put(ptr, linesize, *block);
+ if (s->bits & 7)
+ shift_output(s, ptr, linesize);
+ ptr += bytes_per_pixel*8 >> s->avctx->lowres;
+ }
+ }
+ }
+}
+
+int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask,
+ int mb_bitmask_size, const AVFrame *reference)
+{
+ int len, nb_components, i, h, v, predictor, point_transform;
+ int index, id, ret;
+ const int block_size = s->lossless ? 1 : 8;
+ int ilv, prev_shift;
+
+ if (!s->got_picture) {
+ av_log(s->avctx, AV_LOG_WARNING,
+ "Can not process SOS before SOF, skipping\n");
+ return -1;
+ }
+
+ if (reference) {
+ if (reference->width != s->picture_ptr->width ||
+ reference->height != s->picture_ptr->height ||
+ reference->format != s->picture_ptr->format) {
+ av_log(s->avctx, AV_LOG_ERROR, "Reference mismatching\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ av_assert0(s->picture_ptr->data[0]);
+ /* XXX: verify len field validity */
+ len = get_bits(&s->gb, 16);
+ nb_components = get_bits(&s->gb, 8);
+ if (nb_components == 0 || nb_components > MAX_COMPONENTS) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "decode_sos: nb_components (%d) unsupported\n", nb_components);
+ return AVERROR_PATCHWELCOME;
+ }
+ if (len != 6 + 2 * nb_components) {
+ av_log(s->avctx, AV_LOG_ERROR, "decode_sos: invalid len (%d)\n", len);
+ return AVERROR_INVALIDDATA;
+ }
+ for (i = 0; i < nb_components; i++) {
+ id = get_bits(&s->gb, 8) - 1;
+ av_log(s->avctx, AV_LOG_DEBUG, "component: %d\n", id);
+ /* find component index */
+ for (index = 0; index < s->nb_components; index++)
+ if (id == s->component_id[index])
+ break;
+ if (index == s->nb_components) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "decode_sos: index(%d) out of components\n", index);
+ return AVERROR_INVALIDDATA;
+ }
+ /* Metasoft MJPEG codec has Cb and Cr swapped */
+ if (s->avctx->codec_tag == MKTAG('M', 'T', 'S', 'J')
+ && nb_components == 3 && s->nb_components == 3 && i)
+ index = 3 - i;
+
+ s->quant_sindex[i] = s->quant_index[index];
+ s->nb_blocks[i] = s->h_count[index] * s->v_count[index];
+ s->h_scount[i] = s->h_count[index];
+ s->v_scount[i] = s->v_count[index];
+
+ if(nb_components == 3 && s->nb_components == 3 && s->avctx->pix_fmt == AV_PIX_FMT_GBR24P)
+ index = (i+2)%3;
+ if(nb_components == 1 && s->nb_components == 3 && s->avctx->pix_fmt == AV_PIX_FMT_GBR24P)
+ index = (index+2)%3;
+
+ s->comp_index[i] = index;
+
+ s->dc_index[i] = get_bits(&s->gb, 4);
+ s->ac_index[i] = get_bits(&s->gb, 4);
+
+ if (s->dc_index[i] < 0 || s->ac_index[i] < 0 ||
+ s->dc_index[i] >= 4 || s->ac_index[i] >= 4)
+ goto out_of_range;
+ if (!s->vlcs[0][s->dc_index[i]].table || !(s->progressive ? s->vlcs[2][s->ac_index[0]].table : s->vlcs[1][s->ac_index[i]].table))
+ goto out_of_range;
+ }
+
+ predictor = get_bits(&s->gb, 8); /* JPEG Ss / lossless JPEG predictor /JPEG-LS NEAR */
+ ilv = get_bits(&s->gb, 8); /* JPEG Se / JPEG-LS ILV */
+ if(s->avctx->codec_tag != AV_RL32("CJPG")){
+ prev_shift = get_bits(&s->gb, 4); /* Ah */
+ point_transform = get_bits(&s->gb, 4); /* Al */
+ }else
+ prev_shift = point_transform = 0;
+
+ if (nb_components > 1) {
+ /* interleaved stream */
+ s->mb_width = (s->width + s->h_max * block_size - 1) / (s->h_max * block_size);
+ s->mb_height = (s->height + s->v_max * block_size - 1) / (s->v_max * block_size);
+ } else if (!s->ls) { /* skip this for JPEG-LS */
+ h = s->h_max / s->h_scount[0];
+ v = s->v_max / s->v_scount[0];
+ s->mb_width = (s->width + h * block_size - 1) / (h * block_size);
+ s->mb_height = (s->height + v * block_size - 1) / (v * block_size);
+ s->nb_blocks[0] = 1;
+ s->h_scount[0] = 1;
+ s->v_scount[0] = 1;
+ }
+
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_DEBUG, "%s %s p:%d >>:%d ilv:%d bits:%d skip:%d %s comp:%d\n",
+ s->lossless ? "lossless" : "sequential DCT", s->rgb ? "RGB" : "",
+ predictor, point_transform, ilv, s->bits, s->mjpb_skiptosod,
+ s->pegasus_rct ? "PRCT" : (s->rct ? "RCT" : ""), nb_components);
+
+
+ /* mjpeg-b can have padding bytes between sos and image data, skip them */
+ for (i = s->mjpb_skiptosod; i > 0; i--)
+ skip_bits(&s->gb, 8);
+
+next_field:
+ for (i = 0; i < nb_components; i++)
+ s->last_dc[i] = (4 << s->bits);
+
+ if (s->lossless) {
+ av_assert0(s->picture_ptr == s->picture);
+ if (CONFIG_JPEGLS_DECODER && s->ls) {
+// for () {
+// reset_ls_coding_parameters(s, 0);
+
+ if ((ret = ff_jpegls_decode_picture(s, predictor,
+ point_transform, ilv)) < 0)
+ return ret;
+ } else {
+ if (s->rgb) {
+ if ((ret = ljpeg_decode_rgb_scan(s, nb_components, predictor, point_transform)) < 0)
+ return ret;
+ } else {
+ if ((ret = ljpeg_decode_yuv_scan(s, predictor,
+ point_transform,
+ nb_components)) < 0)
+ return ret;
+ }
+ }
+ } else {
+ if (s->progressive && predictor) {
+ av_assert0(s->picture_ptr == s->picture);
+ if ((ret = mjpeg_decode_scan_progressive_ac(s, predictor,
+ ilv, prev_shift,
+ point_transform)) < 0)
+ return ret;
+ } else {
+ if ((ret = mjpeg_decode_scan(s, nb_components,
+ prev_shift, point_transform,
+ mb_bitmask, mb_bitmask_size, reference)) < 0)
+ return ret;
+ }
+ }
+
+ if (s->interlaced &&
+ get_bits_left(&s->gb) > 32 &&
+ show_bits(&s->gb, 8) == 0xFF) {
+ GetBitContext bak = s->gb;
+ align_get_bits(&bak);
+ if (show_bits(&bak, 16) == 0xFFD1) {
+ av_log(s->avctx, AV_LOG_DEBUG, "AVRn interlaced picture marker found\n");
+ s->gb = bak;
+ skip_bits(&s->gb, 16);
+ s->bottom_field ^= 1;
+
+ goto next_field;
+ }
+ }
+
+ emms_c();
+ return 0;
+ out_of_range:
+ av_log(s->avctx, AV_LOG_ERROR, "decode_sos: ac/dc index out of range\n");
+ return AVERROR_INVALIDDATA;
+}
+
+static int mjpeg_decode_dri(MJpegDecodeContext *s)
+{
+ if (get_bits(&s->gb, 16) != 4)
+ return AVERROR_INVALIDDATA;
+ s->restart_interval = get_bits(&s->gb, 16);
+ s->restart_count = 0;
+ av_log(s->avctx, AV_LOG_DEBUG, "restart interval: %d\n",
+ s->restart_interval);
+
+ return 0;
+}
+
+static int mjpeg_decode_app(MJpegDecodeContext *s)
+{
+ int len, id, i;
+
+ len = get_bits(&s->gb, 16);
+ if (len < 6)
+ return AVERROR_INVALIDDATA;
+ if (8 * len > get_bits_left(&s->gb))
+ return AVERROR_INVALIDDATA;
+
+ id = get_bits_long(&s->gb, 32);
+ len -= 6;
+
+ if (s->avctx->debug & FF_DEBUG_STARTCODE) {
+ char id_str[32];
+ av_get_codec_tag_string(id_str, sizeof(id_str), av_bswap32(id));
+ av_log(s->avctx, AV_LOG_DEBUG, "APPx (%s / %8X) len=%d\n", id_str, id, len);
+ }
+
+ /* Buggy AVID, it puts EOI only at every 10th frame. */
+ /* Also, this fourcc is used by non-avid files too, it holds some
+ information, but it's always present in AVID-created files. */
+ if (id == AV_RB32("AVI1")) {
+ /* structure:
+ 4bytes AVI1
+ 1bytes polarity
+ 1bytes always zero
+ 4bytes field_size
+ 4bytes field_size_less_padding
+ */
+ s->buggy_avid = 1;
+ i = get_bits(&s->gb, 8); len--;
+ av_log(s->avctx, AV_LOG_DEBUG, "polarity %d\n", i);
+#if 0
+ skip_bits(&s->gb, 8);
+ skip_bits(&s->gb, 32);
+ skip_bits(&s->gb, 32);
+ len -= 10;
+#endif
+ goto out;
+ }
+
+// len -= 2;
+
+ if (id == AV_RB32("JFIF")) {
+ int t_w, t_h, v1, v2;
+ skip_bits(&s->gb, 8); /* the trailing zero-byte */
+ v1 = get_bits(&s->gb, 8);
+ v2 = get_bits(&s->gb, 8);
+ skip_bits(&s->gb, 8);
+
+ s->avctx->sample_aspect_ratio.num = get_bits(&s->gb, 16);
+ s->avctx->sample_aspect_ratio.den = get_bits(&s->gb, 16);
+ ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio);
+
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_INFO,
+ "mjpeg: JFIF header found (version: %x.%x) SAR=%d/%d\n",
+ v1, v2,
+ s->avctx->sample_aspect_ratio.num,
+ s->avctx->sample_aspect_ratio.den);
+
+ t_w = get_bits(&s->gb, 8);
+ t_h = get_bits(&s->gb, 8);
+ if (t_w && t_h) {
+ /* skip thumbnail */
+ if (len -10 - (t_w * t_h * 3) > 0)
+ len -= t_w * t_h * 3;
+ }
+ len -= 10;
+ goto out;
+ }
+
+ if (id == AV_RB32("Adob") && (get_bits(&s->gb, 8) == 'e')) {
+ skip_bits(&s->gb, 16); /* version */
+ skip_bits(&s->gb, 16); /* flags0 */
+ skip_bits(&s->gb, 16); /* flags1 */
+ s->adobe_transform = get_bits(&s->gb, 8);
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_INFO, "mjpeg: Adobe header found, transform=%d\n", s->adobe_transform);
+ len -= 7;
+ goto out;
+ }
+
+ if (id == AV_RB32("LJIF")) {
+ int rgb = s->rgb;
+ int pegasus_rct = s->pegasus_rct;
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_INFO,
+ "Pegasus lossless jpeg header found\n");
+ skip_bits(&s->gb, 16); /* version ? */
+ skip_bits(&s->gb, 16); /* unknown always 0? */
+ skip_bits(&s->gb, 16); /* unknown always 0? */
+ skip_bits(&s->gb, 16); /* unknown always 0? */
+ switch (i=get_bits(&s->gb, 8)) {
+ case 1:
+ rgb = 1;
+ pegasus_rct = 0;
+ break;
+ case 2:
+ rgb = 1;
+ pegasus_rct = 1;
+ break;
+ default:
+ av_log(s->avctx, AV_LOG_ERROR, "unknown colorspace %d\n", i);
+ }
+
+ len -= 9;
+ if (s->got_picture)
+ if (rgb != s->rgb || pegasus_rct != s->pegasus_rct) {
+ av_log(s->avctx, AV_LOG_WARNING, "Mismatching LJIF tag\n");
+ goto out;
+ }
+
+ s->rgb = rgb;
+ s->pegasus_rct = pegasus_rct;
+
+ goto out;
+ }
+ if (id == AV_RL32("colr") && len > 0) {
+ s->colr = get_bits(&s->gb, 8);
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_INFO, "COLR %d\n", s->colr);
+ len --;
+ goto out;
+ }
+ if (id == AV_RL32("xfrm") && len > 0) {
+ s->xfrm = get_bits(&s->gb, 8);
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_INFO, "XFRM %d\n", s->xfrm);
+ len --;
+ goto out;
+ }
+
+ /* JPS extension by VRex */
+ if (s->start_code == APP3 && id == AV_RB32("_JPS") && len >= 10) {
+ int flags, layout, type;
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_INFO, "_JPSJPS_\n");
+
+ skip_bits(&s->gb, 32); len -= 4; /* JPS_ */
+ skip_bits(&s->gb, 16); len -= 2; /* block length */
+ skip_bits(&s->gb, 8); /* reserved */
+ flags = get_bits(&s->gb, 8);
+ layout = get_bits(&s->gb, 8);
+ type = get_bits(&s->gb, 8);
+ len -= 4;
+
+ s->stereo3d = av_stereo3d_alloc();
+ if (!s->stereo3d) {
+ goto out;
+ }
+ if (type == 0) {
+ s->stereo3d->type = AV_STEREO3D_2D;
+ } else if (type == 1) {
+ switch (layout) {
+ case 0x01:
+ s->stereo3d->type = AV_STEREO3D_LINES;
+ break;
+ case 0x02:
+ s->stereo3d->type = AV_STEREO3D_SIDEBYSIDE;
+ break;
+ case 0x03:
+ s->stereo3d->type = AV_STEREO3D_TOPBOTTOM;
+ break;
+ }
+ if (!(flags & 0x04)) {
+ s->stereo3d->flags = AV_STEREO3D_FLAG_INVERT;
+ }
+ }
+ goto out;
+ }
+
+ /* EXIF metadata */
+ if (s->start_code == APP1 && id == AV_RB32("Exif") && len >= 2) {
+ GetByteContext gbytes;
+ int ret, le, ifd_offset, bytes_read;
+ const uint8_t *aligned;
+
+ skip_bits(&s->gb, 16); // skip padding
+ len -= 2;
+
+ // init byte wise reading
+ aligned = align_get_bits(&s->gb);
+ bytestream2_init(&gbytes, aligned, len);
+
+ // read TIFF header
+ ret = ff_tdecode_header(&gbytes, &le, &ifd_offset);
+ if (ret) {
+ av_log(s->avctx, AV_LOG_ERROR, "mjpeg: invalid TIFF header in EXIF data\n");
+ } else {
+ bytestream2_seek(&gbytes, ifd_offset, SEEK_SET);
+
+ // read 0th IFD and store the metadata
+ // (return values > 0 indicate the presence of subimage metadata)
+ ret = avpriv_exif_decode_ifd(s->avctx, &gbytes, le, 0, &s->exif_metadata);
+ if (ret < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "mjpeg: error decoding EXIF data\n");
+ }
+ }
+
+ bytes_read = bytestream2_tell(&gbytes);
+ skip_bits(&s->gb, bytes_read << 3);
+ len -= bytes_read;
+
+ goto out;
+ }
+
+ /* Apple MJPEG-A */
+ if ((s->start_code == APP1) && (len > (0x28 - 8))) {
+ id = get_bits_long(&s->gb, 32);
+ len -= 4;
+ /* Apple MJPEG-A */
+ if (id == AV_RB32("mjpg")) {
+#if 0
+ skip_bits(&s->gb, 32); /* field size */
+ skip_bits(&s->gb, 32); /* pad field size */
+ skip_bits(&s->gb, 32); /* next off */
+ skip_bits(&s->gb, 32); /* quant off */
+ skip_bits(&s->gb, 32); /* huff off */
+ skip_bits(&s->gb, 32); /* image off */
+ skip_bits(&s->gb, 32); /* scan off */
+ skip_bits(&s->gb, 32); /* data off */
+#endif
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_INFO, "mjpeg: Apple MJPEG-A header found\n");
+ }
+ }
+
+out:
+ /* slow but needed for extreme adobe jpegs */
+ if (len < 0)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "mjpeg: error, decode_app parser read over the end\n");
+ while (--len > 0)
+ skip_bits(&s->gb, 8);
+
+ return 0;
+}
+
+static int mjpeg_decode_com(MJpegDecodeContext *s)
+{
+ int len = get_bits(&s->gb, 16);
+ if (len >= 2 && 8 * len - 16 <= get_bits_left(&s->gb)) {
+ char *cbuf = av_malloc(len - 1);
+ if (cbuf) {
+ int i;
+ for (i = 0; i < len - 2; i++)
+ cbuf[i] = get_bits(&s->gb, 8);
+ if (i > 0 && cbuf[i - 1] == '\n')
+ cbuf[i - 1] = 0;
+ else
+ cbuf[i] = 0;
+
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_INFO, "comment: '%s'\n", cbuf);
+
+ /* buggy avid, it puts EOI only at every 10th frame */
+ if (!strncmp(cbuf, "AVID", 4)) {
+ parse_avid(s, cbuf, len);
+ } else if (!strcmp(cbuf, "CS=ITU601"))
+ s->cs_itu601 = 1;
+ else if ((!strncmp(cbuf, "Intel(R) JPEG Library, version 1", 32) && s->avctx->codec_tag) ||
+ (!strncmp(cbuf, "Metasoft MJPEG Codec", 20)))
+ s->flipped = 1;
+ else if (!strcmp(cbuf, "MULTISCOPE II"))
+ s->multiscope = 2;
+
+ av_free(cbuf);
+ }
+ }
+
+ return 0;
+}
+
+/* return the 8 bit start code value and update the search
+ state. Return -1 if no start code found */
+static int find_marker(const uint8_t **pbuf_ptr, const uint8_t *buf_end)
+{
+ const uint8_t *buf_ptr;
+ unsigned int v, v2;
+ int val;
+ int skipped = 0;
+
+ buf_ptr = *pbuf_ptr;
+ while (buf_end - buf_ptr > 1) {
+ v = *buf_ptr++;
+ v2 = *buf_ptr;
+ if ((v == 0xff) && (v2 >= 0xc0) && (v2 <= 0xfe) && buf_ptr < buf_end) {
+ val = *buf_ptr++;
+ goto found;
+ }
+ skipped++;
+ }
+ buf_ptr = buf_end;
+ val = -1;
+found:
+ ff_dlog(NULL, "find_marker skipped %d bytes\n", skipped);
+ *pbuf_ptr = buf_ptr;
+ return val;
+}
+
+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 start_code;
+ start_code = find_marker(buf_ptr, buf_end);
+
+ av_fast_padded_malloc(&s->buffer, &s->buffer_size, buf_end - *buf_ptr);
+ if (!s->buffer)
+ return AVERROR(ENOMEM);
+
+ /* unescape buffer of SOS, use special treatment for JPEG-LS */
+ if (start_code == SOS && !s->ls) {
+ const uint8_t *src = *buf_ptr;
+ uint8_t *dst = s->buffer;
+
+ while (src < buf_end) {
+ uint8_t x = *(src++);
+
+ *(dst++) = x;
+ if (s->avctx->codec_id != AV_CODEC_ID_THP) {
+ if (x == 0xff) {
+ while (src < buf_end && x == 0xff)
+ x = *(src++);
+
+ if (x >= 0xd0 && x <= 0xd7)
+ *(dst++) = x;
+ else if (x)
+ break;
+ }
+ }
+ }
+ *unescaped_buf_ptr = s->buffer;
+ *unescaped_buf_size = dst - s->buffer;
+ memset(s->buffer + *unescaped_buf_size, 0,
+ AV_INPUT_BUFFER_PADDING_SIZE);
+
+ av_log(s->avctx, AV_LOG_DEBUG, "escaping removed %"PTRDIFF_SPECIFIER" bytes\n",
+ (buf_end - *buf_ptr) - (dst - s->buffer));
+ } else if (start_code == SOS && s->ls) {
+ const uint8_t *src = *buf_ptr;
+ uint8_t *dst = s->buffer;
+ int bit_count = 0;
+ int t = 0, b = 0;
+ PutBitContext pb;
+
+ /* find marker */
+ while (src + t < buf_end) {
+ uint8_t x = src[t++];
+ if (x == 0xff) {
+ while ((src + t < buf_end) && x == 0xff)
+ x = src[t++];
+ if (x & 0x80) {
+ t -= FFMIN(2, t);
+ break;
+ }
+ }
+ }
+ bit_count = t * 8;
+ init_put_bits(&pb, dst, t);
+
+ /* unescape bitstream */
+ while (b < t) {
+ uint8_t x = src[b++];
+ put_bits(&pb, 8, x);
+ if (x == 0xFF && b < t) {
+ x = src[b++];
+ if (x & 0x80) {
+ av_log(s->avctx, AV_LOG_WARNING, "Invalid escape sequence\n");
+ x &= 0x7f;
+ }
+ put_bits(&pb, 7, x);
+ bit_count--;
+ }
+ }
+ flush_put_bits(&pb);
+
+ *unescaped_buf_ptr = dst;
+ *unescaped_buf_size = (bit_count + 7) >> 3;
+ memset(s->buffer + *unescaped_buf_size, 0,
+ AV_INPUT_BUFFER_PADDING_SIZE);
+ } else {
+ *unescaped_buf_ptr = *buf_ptr;
+ *unescaped_buf_size = buf_end - *buf_ptr;
+ }
+
+ return start_code;
+}
+
+int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ 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;
+ int hshift, vshift;
+ int unescaped_buf_size;
+ int start_code;
+ int i, index;
+ int ret = 0;
+ int is16bit;
+
+ av_dict_free(&s->exif_metadata);
+ av_freep(&s->stereo3d);
+ s->adobe_transform = -1;
+
+ buf_ptr = buf;
+ buf_end = buf + buf_size;
+ while (buf_ptr < buf_end) {
+ /* find start next marker */
+ start_code = ff_mjpeg_find_marker(s, &buf_ptr, buf_end,
+ &unescaped_buf_ptr,
+ &unescaped_buf_size);
+ /* EOF */
+ if (start_code < 0) {
+ break;
+ } else if (unescaped_buf_size > INT_MAX / 8) {
+ av_log(avctx, AV_LOG_ERROR,
+ "MJPEG packet 0x%x too big (%d/%d), corrupt data?\n",
+ start_code, unescaped_buf_size, buf_size);
+ return AVERROR_INVALIDDATA;
+ }
+ av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%"PTRDIFF_SPECIFIER"\n",
+ start_code, buf_end - buf_ptr);
+
+ ret = init_get_bits8(&s->gb, unescaped_buf_ptr, unescaped_buf_size);
+
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "invalid buffer\n");
+ goto fail;
+ }
+
+ s->start_code = start_code;
+ if (s->avctx->debug & FF_DEBUG_STARTCODE)
+ av_log(avctx, AV_LOG_DEBUG, "startcode: %X\n", start_code);
+
+ /* process markers */
+ if (start_code >= 0xd0 && start_code <= 0xd7)
+ av_log(avctx, AV_LOG_DEBUG,
+ "restart marker: %d\n", start_code & 0x0f);
+ /* APP fields */
+ else if (start_code >= APP0 && start_code <= APP15)
+ mjpeg_decode_app(s);
+ /* Comment */
+ else if (start_code == COM)
+ mjpeg_decode_com(s);
+
+ ret = -1;
+
+ if (!CONFIG_JPEGLS_DECODER &&
+ (start_code == SOF48 || start_code == LSE)) {
+ av_log(avctx, AV_LOG_ERROR, "JPEG-LS support not enabled.\n");
+ return AVERROR(ENOSYS);
+ }
+
+ switch (start_code) {
+ case SOI:
+ s->restart_interval = 0;
+ s->restart_count = 0;
+ /* nothing to do on SOI */
+ break;
+ case DQT:
+ ff_mjpeg_decode_dqt(s);
+ break;
+ case DHT:
+ if ((ret = ff_mjpeg_decode_dht(s)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n");
+ goto fail;
+ }
+ break;
+ case SOF0:
+ case SOF1:
+ s->lossless = 0;
+ s->ls = 0;
+ s->progressive = 0;
+ if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+ goto fail;
+ break;
+ case SOF2:
+ s->lossless = 0;
+ s->ls = 0;
+ s->progressive = 1;
+ if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+ goto fail;
+ break;
+ case SOF3:
+ s->avctx->properties |= FF_CODEC_PROPERTY_LOSSLESS;
+ s->lossless = 1;
+ s->ls = 0;
+ s->progressive = 0;
+ if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+ goto fail;
+ break;
+ case SOF48:
+ s->avctx->properties |= FF_CODEC_PROPERTY_LOSSLESS;
+ s->lossless = 1;
+ s->ls = 1;
+ s->progressive = 0;
+ if ((ret = ff_mjpeg_decode_sof(s)) < 0)
+ goto fail;
+ break;
+ case LSE:
+ if (!CONFIG_JPEGLS_DECODER ||
+ (ret = ff_jpegls_decode_lse(s)) < 0)
+ goto fail;
+ break;
+ case EOI:
+eoi_parser:
+ if (avctx->skip_frame != AVDISCARD_ALL && s->progressive && s->cur_scan && s->got_picture)
+ mjpeg_idct_scan_progressive_ac(s);
+ s->cur_scan = 0;
+ if (!s->got_picture) {
+ av_log(avctx, AV_LOG_WARNING,
+ "Found EOI before any SOF, ignoring\n");
+ break;
+ }
+ if (s->interlaced) {
+ s->bottom_field ^= 1;
+ /* if not bottom field, do not output image yet */
+ if (s->bottom_field == !s->interlace_polarity)
+ break;
+ }
+ if ((ret = av_frame_ref(frame, s->picture_ptr)) < 0)
+ return ret;
+ *got_frame = 1;
+ s->got_picture = 0;
+
+ if (!s->lossless) {
+ int qp = FFMAX3(s->qscale[0],
+ s->qscale[1],
+ s->qscale[2]);
+ int qpw = (s->width + 15) / 16;
+ AVBufferRef *qp_table_buf = av_buffer_alloc(qpw);
+ if (qp_table_buf) {
+ memset(qp_table_buf->data, qp, qpw);
+ av_frame_set_qp_table(data, qp_table_buf, 0, FF_QSCALE_TYPE_MPEG1);
+ }
+
+ if(avctx->debug & FF_DEBUG_QP)
+ av_log(avctx, AV_LOG_DEBUG, "QP: %d\n", qp);
+ }
+
+ goto the_end;
+ case SOS:
+ s->cur_scan++;
+ if ((ret = ff_mjpeg_decode_sos(s, NULL, 0, NULL)) < 0 &&
+ (avctx->err_recognition & AV_EF_EXPLODE))
+ goto fail;
+ break;
+ case DRI:
+ mjpeg_decode_dri(s);
+ break;
+ case SOF5:
+ case SOF6:
+ case SOF7:
+ case SOF9:
+ case SOF10:
+ case SOF11:
+ case SOF13:
+ case SOF14:
+ case SOF15:
+ case JPG:
+ av_log(avctx, AV_LOG_ERROR,
+ "mjpeg: unsupported coding type (%x)\n", start_code);
+ break;
+ }
+
+ /* eof process start code */
+ buf_ptr += (get_bits_count(&s->gb) + 7) / 8;
+ av_log(avctx, AV_LOG_DEBUG,
+ "marker parser used %d bytes (%d bits)\n",
+ (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb));
+ }
+ if (s->got_picture && s->cur_scan) {
+ av_log(avctx, AV_LOG_WARNING, "EOI missing, emulating\n");
+ goto eoi_parser;
+ }
+ av_log(avctx, AV_LOG_FATAL, "No JPEG data found in image\n");
+ return AVERROR_INVALIDDATA;
+fail:
+ s->got_picture = 0;
+ return ret;
+the_end:
+
+ is16bit = av_pix_fmt_desc_get(s->avctx->pix_fmt)->comp[0].step_minus1;
+
+ if (AV_RB32(s->upscale_h)) {
+ int p;
+ av_assert0(avctx->pix_fmt == AV_PIX_FMT_YUVJ444P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV444P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVJ440P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV440P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVA444P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVJ420P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV420P16||
+ avctx->pix_fmt == AV_PIX_FMT_YUVA420P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVA420P16||
+ avctx->pix_fmt == AV_PIX_FMT_GBRP ||
+ avctx->pix_fmt == AV_PIX_FMT_GBRAP
+ );
+ avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift);
+ for (p = 0; p<4; p++) {
+ uint8_t *line = s->picture_ptr->data[p];
+ int w = s->width;
+ int h = s->height;
+ if (!s->upscale_h[p])
+ continue;
+ if (p==1 || p==2) {
+ w = FF_CEIL_RSHIFT(w, hshift);
+ h = FF_CEIL_RSHIFT(h, vshift);
+ }
+ if (s->upscale_v[p])
+ h = (h+1)>>1;
+ av_assert0(w > 0);
+ for (i = 0; i < h; i++) {
+ if (s->upscale_h[p] == 1) {
+ if (is16bit) ((uint16_t*)line)[w - 1] = ((uint16_t*)line)[(w - 1) / 2];
+ else line[w - 1] = line[(w - 1) / 2];
+ for (index = w - 2; index > 0; index--) {
+ if (is16bit)
+ ((uint16_t*)line)[index] = (((uint16_t*)line)[index / 2] + ((uint16_t*)line)[(index + 1) / 2]) >> 1;
+ else
+ line[index] = (line[index / 2] + line[(index + 1) / 2]) >> 1;
+ }
+ } else if (s->upscale_h[p] == 2) {
+ if (is16bit) {
+ ((uint16_t*)line)[w - 1] = ((uint16_t*)line)[(w - 1) / 3];
+ if (w > 1)
+ ((uint16_t*)line)[w - 2] = ((uint16_t*)line)[w - 1];
+ } else {
+ line[w - 1] = line[(w - 1) / 3];
+ if (w > 1)
+ line[w - 2] = line[w - 1];
+ }
+ for (index = w - 3; index > 0; index--) {
+ line[index] = (line[index / 3] + line[(index + 1) / 3] + line[(index + 2) / 3] + 1) / 3;
+ }
+ }
+ line += s->linesize[p];
+ }
+ }
+ }
+ if (AV_RB32(s->upscale_v)) {
+ int p;
+ av_assert0(avctx->pix_fmt == AV_PIX_FMT_YUVJ444P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV444P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVJ422P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV422P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVJ420P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV420P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUV440P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVJ440P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVA444P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVA420P ||
+ avctx->pix_fmt == AV_PIX_FMT_YUVA420P16||
+ avctx->pix_fmt == AV_PIX_FMT_GBRP ||
+ avctx->pix_fmt == AV_PIX_FMT_GBRAP
+ );
+ avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift);
+ for (p = 0; p < 4; p++) {
+ uint8_t *dst;
+ int w = s->width;
+ int h = s->height;
+ if (!s->upscale_v[p])
+ continue;
+ if (p==1 || p==2) {
+ w = FF_CEIL_RSHIFT(w, hshift);
+ h = FF_CEIL_RSHIFT(h, vshift);
+ }
+ dst = &((uint8_t *)s->picture_ptr->data[p])[(h - 1) * s->linesize[p]];
+ for (i = h - 1; i; i--) {
+ uint8_t *src1 = &((uint8_t *)s->picture_ptr->data[p])[i / 2 * s->linesize[p]];
+ uint8_t *src2 = &((uint8_t *)s->picture_ptr->data[p])[(i + 1) / 2 * s->linesize[p]];
+ if (src1 == src2 || i == h - 1) {
+ memcpy(dst, src1, w);
+ } else {
+ for (index = 0; index < w; index++)
+ dst[index] = (src1[index] + src2[index]) >> 1;
+ }
+ dst -= s->linesize[p];
+ }
+ }
+ }
+ if (s->flipped && !s->rgb) {
+ int j;
+ avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift);
+ for (index=0; index<4; index++) {
+ uint8_t *dst = s->picture_ptr->data[index];
+ int w = s->picture_ptr->width;
+ int h = s->picture_ptr->height;
+ if(index && index<3){
+ w = FF_CEIL_RSHIFT(w, hshift);
+ h = FF_CEIL_RSHIFT(h, vshift);
+ }
+ if(dst){
+ uint8_t *dst2 = dst + s->picture_ptr->linesize[index]*(h-1);
+ for (i=0; i<h/2; i++) {
+ for (j=0; j<w; j++)
+ FFSWAP(int, dst[j], dst2[j]);
+ dst += s->picture_ptr->linesize[index];
+ dst2 -= s->picture_ptr->linesize[index];
+ }
+ }
+ }
+ }
+ if (s->adobe_transform == 0 && s->avctx->pix_fmt == AV_PIX_FMT_GBRAP) {
+ int w = s->picture_ptr->width;
+ int h = s->picture_ptr->height;
+ for (i=0; i<h; i++) {
+ int j;
+ uint8_t *dst[4];
+ for (index=0; index<4; index++) {
+ dst[index] = s->picture_ptr->data[index]
+ + s->picture_ptr->linesize[index]*i;
+ }
+ for (j=0; j<w; j++) {
+ int k = dst[3][j];
+ int r = dst[0][j] * k;
+ int g = dst[1][j] * k;
+ int b = dst[2][j] * k;
+ dst[0][j] = g*257 >> 16;
+ dst[1][j] = b*257 >> 16;
+ dst[2][j] = r*257 >> 16;
+ dst[3][j] = 255;
+ }
+ }
+ }
+ if (s->adobe_transform == 2 && s->avctx->pix_fmt == AV_PIX_FMT_YUVA444P) {
+ int w = s->picture_ptr->width;
+ int h = s->picture_ptr->height;
+ for (i=0; i<h; i++) {
+ int j;
+ uint8_t *dst[4];
+ for (index=0; index<4; index++) {
+ dst[index] = s->picture_ptr->data[index]
+ + s->picture_ptr->linesize[index]*i;
+ }
+ for (j=0; j<w; j++) {
+ int k = dst[3][j];
+ int r = (255 - dst[0][j]) * k;
+ int g = (128 - dst[1][j]) * k;
+ int b = (128 - dst[2][j]) * k;
+ dst[0][j] = r*257 >> 16;
+ dst[1][j] = (g*257 >> 16) + 128;
+ dst[2][j] = (b*257 >> 16) + 128;
+ dst[3][j] = 255;
+ }
+ }
+ }
+
+ if (s->stereo3d) {
+ AVStereo3D *stereo = av_stereo3d_create_side_data(data);
+ if (stereo) {
+ stereo->type = s->stereo3d->type;
+ stereo->flags = s->stereo3d->flags;
+ }
+ av_freep(&s->stereo3d);
+ }
+
+ av_dict_copy(avpriv_frame_get_metadatap(data), s->exif_metadata, 0);
+ av_dict_free(&s->exif_metadata);
+
+ av_log(avctx, AV_LOG_DEBUG, "decode frame unused %"PTRDIFF_SPECIFIER" bytes\n",
+ buf_end - buf_ptr);
+// return buf_end - buf_ptr;
+ return buf_ptr - buf;
+}
+
+av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx)
+{
+ MJpegDecodeContext *s = avctx->priv_data;
+ int i, j;
+
+ if (s->interlaced && s->bottom_field == !s->interlace_polarity && s->got_picture && !avctx->frame_number) {
+ av_log(avctx, AV_LOG_INFO, "Single field\n");
+ }
+
+ if (s->picture) {
+ av_frame_free(&s->picture);
+ s->picture_ptr = NULL;
+ } else if (s->picture_ptr)
+ av_frame_unref(s->picture_ptr);
+
+ av_freep(&s->buffer);
+ av_freep(&s->stereo3d);
+ av_freep(&s->ljpeg_buffer);
+ s->ljpeg_buffer_size = 0;
+
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 4; j++)
+ ff_free_vlc(&s->vlcs[i][j]);
+ }
+ for (i = 0; i < MAX_COMPONENTS; i++) {
+ av_freep(&s->blocks[i]);
+ av_freep(&s->last_nnz[i]);
+ }
+ av_dict_free(&s->exif_metadata);
+ return 0;
+}
+
+static void decode_flush(AVCodecContext *avctx)
+{
+ MJpegDecodeContext *s = avctx->priv_data;
+ s->got_picture = 0;
+}
+
+#if CONFIG_MJPEG_DECODER
+#define OFFSET(x) offsetof(MJpegDecodeContext, x)
+#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
+static const AVOption options[] = {
+ { "extern_huff", "Use external huffman table.",
+ OFFSET(extern_huff), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VD },
+ { NULL },
+};
+
+static const AVClass mjpegdec_class = {
+ .class_name = "MJPEG decoder",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_mjpeg_decoder = {
+ .name = "mjpeg",
+ .long_name = NULL_IF_CONFIG_SMALL("MJPEG (Motion JPEG)"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MJPEG,
+ .priv_data_size = sizeof(MJpegDecodeContext),
+ .init = ff_mjpeg_decode_init,
+ .close = ff_mjpeg_decode_end,
+ .decode = ff_mjpeg_decode_frame,
+ .flush = decode_flush,
+ .capabilities = AV_CODEC_CAP_DR1,
+ .max_lowres = 3,
+ .priv_class = &mjpegdec_class,
+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
+};
+#endif
+#if CONFIG_THP_DECODER
+AVCodec ff_thp_decoder = {
+ .name = "thp",
+ .long_name = NULL_IF_CONFIG_SMALL("Nintendo Gamecube THP video"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_THP,
+ .priv_data_size = sizeof(MJpegDecodeContext),
+ .init = ff_mjpeg_decode_init,
+ .close = ff_mjpeg_decode_end,
+ .decode = ff_mjpeg_decode_frame,
+ .flush = decode_flush,
+ .capabilities = AV_CODEC_CAP_DR1,
+ .max_lowres = 3,
+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
+};
+#endif
diff --git a/ffmpeg-2-8-11/libavcodec/mjpegdec.h b/ffmpeg-2-8-12/libavcodec/mjpegdec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mjpegdec.h
rename to ffmpeg-2-8-12/libavcodec/mjpegdec.h
diff --git a/ffmpeg-2-8-11/libavcodec/mjpegenc.c b/ffmpeg-2-8-12/libavcodec/mjpegenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mjpegenc.c
rename to ffmpeg-2-8-12/libavcodec/mjpegenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/mjpegenc.h b/ffmpeg-2-8-12/libavcodec/mjpegenc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mjpegenc.h
rename to ffmpeg-2-8-12/libavcodec/mjpegenc.h
diff --git a/ffmpeg-2-8-11/libavcodec/mjpegenc_common.c b/ffmpeg-2-8-12/libavcodec/mjpegenc_common.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mjpegenc_common.c
rename to ffmpeg-2-8-12/libavcodec/mjpegenc_common.c
diff --git a/ffmpeg-2-8-11/libavcodec/mjpegenc_common.h b/ffmpeg-2-8-12/libavcodec/mjpegenc_common.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mjpegenc_common.h
rename to ffmpeg-2-8-12/libavcodec/mjpegenc_common.h
diff --git a/ffmpeg-2-8-11/libavcodec/mlp.c b/ffmpeg-2-8-12/libavcodec/mlp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mlp.c
rename to ffmpeg-2-8-12/libavcodec/mlp.c
diff --git a/ffmpeg-2-8-11/libavcodec/mlp.h b/ffmpeg-2-8-12/libavcodec/mlp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mlp.h
rename to ffmpeg-2-8-12/libavcodec/mlp.h
diff --git a/ffmpeg-2-8-11/libavcodec/mlp_parser.c b/ffmpeg-2-8-12/libavcodec/mlp_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mlp_parser.c
rename to ffmpeg-2-8-12/libavcodec/mlp_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/mlp_parser.h b/ffmpeg-2-8-12/libavcodec/mlp_parser.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mlp_parser.h
rename to ffmpeg-2-8-12/libavcodec/mlp_parser.h
diff --git a/ffmpeg-2-8-12/libavcodec/mlpdec.c b/ffmpeg-2-8-12/libavcodec/mlpdec.c
new file mode 100644
index 0000000..b339d11
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/mlpdec.c
@@ -0,0 +1,1341 @@
+/*
+ * MLP decoder
+ * Copyright (c) 2007-2008 Ian Caulfield
+ *
+ * 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
+ * MLP decoder
+ */
+
+#include <stdint.h>
+
+#include "avcodec.h"
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/channel_layout.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "libavutil/crc.h"
+#include "parser.h"
+#include "mlp_parser.h"
+#include "mlpdsp.h"
+#include "mlp.h"
+#include "config.h"
+
+/** number of bits used for VLC lookup - longest Huffman code is 9 */
+#if ARCH_ARM
+#define VLC_BITS 5
+#define VLC_STATIC_SIZE 64
+#else
+#define VLC_BITS 9
+#define VLC_STATIC_SIZE 512
+#endif
+
+typedef struct SubStream {
+ /// Set if a valid restart header has been read. Otherwise the substream cannot be decoded.
+ uint8_t restart_seen;
+
+ //@{
+ /** restart header data */
+ /// The type of noise to be used in the rematrix stage.
+ uint16_t noise_type;
+
+ /// The index of the first channel coded in this substream.
+ uint8_t min_channel;
+ /// The index of the last channel coded in this substream.
+ uint8_t max_channel;
+ /// The number of channels input into the rematrix stage.
+ uint8_t max_matrix_channel;
+ /// For each channel output by the matrix, the output channel to map it to
+ uint8_t ch_assign[MAX_CHANNELS];
+ /// The channel layout for this substream
+ uint64_t ch_layout;
+ /// The matrix encoding mode for this substream
+ enum AVMatrixEncoding matrix_encoding;
+
+ /// Channel coding parameters for channels in the substream
+ ChannelParams channel_params[MAX_CHANNELS];
+
+ /// The left shift applied to random noise in 0x31ea substreams.
+ uint8_t noise_shift;
+ /// The current seed value for the pseudorandom noise generator(s).
+ uint32_t noisegen_seed;
+
+ /// Set if the substream contains extra info to check the size of VLC blocks.
+ uint8_t data_check_present;
+
+ /// Bitmask of which parameter sets are conveyed in a decoding parameter block.
+ uint8_t param_presence_flags;
+#define PARAM_BLOCKSIZE (1 << 7)
+#define PARAM_MATRIX (1 << 6)
+#define PARAM_OUTSHIFT (1 << 5)
+#define PARAM_QUANTSTEP (1 << 4)
+#define PARAM_FIR (1 << 3)
+#define PARAM_IIR (1 << 2)
+#define PARAM_HUFFOFFSET (1 << 1)
+#define PARAM_PRESENCE (1 << 0)
+ //@}
+
+ //@{
+ /** matrix data */
+
+ /// Number of matrices to be applied.
+ uint8_t num_primitive_matrices;
+
+ /// matrix output channel
+ uint8_t matrix_out_ch[MAX_MATRICES];
+
+ /// Whether the LSBs of the matrix output are encoded in the bitstream.
+ uint8_t lsb_bypass[MAX_MATRICES];
+ /// Matrix coefficients, stored as 2.14 fixed point.
+ DECLARE_ALIGNED(32, int32_t, matrix_coeff)[MAX_MATRICES][MAX_CHANNELS];
+ /// Left shift to apply to noise values in 0x31eb substreams.
+ uint8_t matrix_noise_shift[MAX_MATRICES];
+ //@}
+
+ /// Left shift to apply to Huffman-decoded residuals.
+ uint8_t quant_step_size[MAX_CHANNELS];
+
+ /// number of PCM samples in current audio block
+ uint16_t blocksize;
+ /// Number of PCM samples decoded so far in this frame.
+ uint16_t blockpos;
+
+ /// Left shift to apply to decoded PCM values to get final 24-bit output.
+ int8_t output_shift[MAX_CHANNELS];
+
+ /// Running XOR of all output samples.
+ int32_t lossless_check_data;
+
+} SubStream;
+
+typedef struct MLPDecodeContext {
+ AVCodecContext *avctx;
+
+ /// Current access unit being read has a major sync.
+ int is_major_sync_unit;
+
+ /// Size of the major sync unit, in bytes
+ int major_sync_header_size;
+
+ /// Set if a valid major sync block has been read. Otherwise no decoding is possible.
+ uint8_t params_valid;
+
+ /// Number of substreams contained within this stream.
+ uint8_t num_substreams;
+
+ /// Index of the last substream to decode - further substreams are skipped.
+ uint8_t max_decoded_substream;
+
+ /// Stream needs channel reordering to comply with FFmpeg's channel order
+ uint8_t needs_reordering;
+
+ /// number of PCM samples contained in each frame
+ int access_unit_size;
+ /// next power of two above the number of samples in each frame
+ int access_unit_size_pow2;
+
+ SubStream substream[MAX_SUBSTREAMS];
+
+ int matrix_changed;
+ int filter_changed[MAX_CHANNELS][NUM_FILTERS];
+
+ int8_t noise_buffer[MAX_BLOCKSIZE_POW2];
+ int8_t bypassed_lsbs[MAX_BLOCKSIZE][MAX_CHANNELS];
+ DECLARE_ALIGNED(32, int32_t, sample_buffer)[MAX_BLOCKSIZE][MAX_CHANNELS];
+
+ MLPDSPContext dsp;
+} MLPDecodeContext;
+
+static const uint64_t thd_channel_order[] = {
+ AV_CH_FRONT_LEFT, AV_CH_FRONT_RIGHT, // LR
+ AV_CH_FRONT_CENTER, // C
+ AV_CH_LOW_FREQUENCY, // LFE
+ AV_CH_SIDE_LEFT, AV_CH_SIDE_RIGHT, // LRs
+ AV_CH_TOP_FRONT_LEFT, AV_CH_TOP_FRONT_RIGHT, // LRvh
+ AV_CH_FRONT_LEFT_OF_CENTER, AV_CH_FRONT_RIGHT_OF_CENTER, // LRc
+ AV_CH_BACK_LEFT, AV_CH_BACK_RIGHT, // LRrs
+ AV_CH_BACK_CENTER, // Cs
+ AV_CH_TOP_CENTER, // Ts
+ AV_CH_SURROUND_DIRECT_LEFT, AV_CH_SURROUND_DIRECT_RIGHT, // LRsd
+ AV_CH_WIDE_LEFT, AV_CH_WIDE_RIGHT, // LRw
+ AV_CH_TOP_FRONT_CENTER, // Cvh
+ AV_CH_LOW_FREQUENCY_2, // LFE2
+};
+
+static uint64_t thd_channel_layout_extract_channel(uint64_t channel_layout,
+ int index)
+{
+ int i;
+
+ if (av_get_channel_layout_nb_channels(channel_layout) <= index)
+ return 0;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(thd_channel_order); i++)
+ if (channel_layout & thd_channel_order[i] && !index--)
+ return thd_channel_order[i];
+ return 0;
+}
+
+static VLC huff_vlc[3];
+
+/** Initialize static data, constant between all invocations of the codec. */
+
+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);
+ }
+
+ ff_mlp_init_crc();
+}
+
+static inline int32_t calculate_sign_huff(MLPDecodeContext *m,
+ unsigned int substr, unsigned int ch)
+{
+ SubStream *s = &m->substream[substr];
+ ChannelParams *cp = &s->channel_params[ch];
+ int lsb_bits = cp->huff_lsbs - s->quant_step_size[ch];
+ int sign_shift = lsb_bits + (cp->codebook ? 2 - cp->codebook : -1);
+ int32_t sign_huff_offset = cp->huff_offset;
+
+ if (cp->codebook > 0)
+ sign_huff_offset -= 7 << lsb_bits;
+
+ if (sign_shift >= 0)
+ sign_huff_offset -= 1 << sign_shift;
+
+ return sign_huff_offset;
+}
+
+/** Read a sample, consisting of either, both or neither of entropy-coded MSBs
+ * and plain LSBs. */
+
+static inline int read_huff_channels(MLPDecodeContext *m, GetBitContext *gbp,
+ unsigned int substr, unsigned int pos)
+{
+ SubStream *s = &m->substream[substr];
+ unsigned int mat, channel;
+
+ for (mat = 0; mat < s->num_primitive_matrices; mat++)
+ if (s->lsb_bypass[mat])
+ m->bypassed_lsbs[pos + s->blockpos][mat] = get_bits1(gbp);
+
+ for (channel = s->min_channel; channel <= s->max_channel; channel++) {
+ ChannelParams *cp = &s->channel_params[channel];
+ int codebook = cp->codebook;
+ int quant_step_size = s->quant_step_size[channel];
+ int lsb_bits = cp->huff_lsbs - quant_step_size;
+ int result = 0;
+
+ if (codebook > 0)
+ result = get_vlc2(gbp, huff_vlc[codebook-1].table,
+ VLC_BITS, (9 + VLC_BITS - 1) / VLC_BITS);
+
+ if (result < 0)
+ return AVERROR_INVALIDDATA;
+
+ if (lsb_bits > 0)
+ result = (result << lsb_bits) + get_bits(gbp, lsb_bits);
+
+ result += cp->sign_huff_offset;
+ result *= 1 << quant_step_size;
+
+ m->sample_buffer[pos + s->blockpos][channel] = result;
+ }
+
+ return 0;
+}
+
+static av_cold int mlp_decode_init(AVCodecContext *avctx)
+{
+ 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);
+
+ return 0;
+}
+
+/** Read a major sync info header - contains high level information about
+ * the stream - sample rate, channel arrangement etc. Most of this
+ * information is not actually necessary for decoding, only for playback.
+ */
+
+static int read_major_sync(MLPDecodeContext *m, GetBitContext *gb)
+{
+ MLPHeaderInfo mh;
+ int substr, ret;
+
+ if ((ret = ff_mlp_read_major_sync(m->avctx, &mh, gb)) != 0)
+ return ret;
+
+ if (mh.group1_bits == 0) {
+ av_log(m->avctx, AV_LOG_ERROR, "invalid/unknown bits per sample\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (mh.group2_bits > mh.group1_bits) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "Channel group 2 cannot have more bits per sample than group 1.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (mh.group2_samplerate && mh.group2_samplerate != mh.group1_samplerate) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "Channel groups with differing sample rates are not currently supported.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (mh.group1_samplerate == 0) {
+ av_log(m->avctx, AV_LOG_ERROR, "invalid/unknown sampling rate\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (mh.group1_samplerate > MAX_SAMPLERATE) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "Sampling rate %d is greater than the supported maximum (%d).\n",
+ mh.group1_samplerate, MAX_SAMPLERATE);
+ return AVERROR_INVALIDDATA;
+ }
+ if (mh.access_unit_size > MAX_BLOCKSIZE) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "Block size %d is greater than the supported maximum (%d).\n",
+ mh.access_unit_size, MAX_BLOCKSIZE);
+ return AVERROR_INVALIDDATA;
+ }
+ if (mh.access_unit_size_pow2 > MAX_BLOCKSIZE_POW2) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "Block size pow2 %d is greater than the supported maximum (%d).\n",
+ mh.access_unit_size_pow2, MAX_BLOCKSIZE_POW2);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (mh.num_substreams == 0)
+ return AVERROR_INVALIDDATA;
+ if (m->avctx->codec_id == AV_CODEC_ID_MLP && mh.num_substreams > 2) {
+ av_log(m->avctx, AV_LOG_ERROR, "MLP only supports up to 2 substreams.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (mh.num_substreams > MAX_SUBSTREAMS) {
+ avpriv_request_sample(m->avctx,
+ "%d substreams (more than the "
+ "maximum supported by the decoder)",
+ mh.num_substreams);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ m->major_sync_header_size = mh.header_size;
+
+ m->access_unit_size = mh.access_unit_size;
+ m->access_unit_size_pow2 = mh.access_unit_size_pow2;
+
+ m->num_substreams = mh.num_substreams;
+
+ /* limit to decoding 3 substreams, as the 4th is used by Dolby Atmos for non-audio data */
+ m->max_decoded_substream = FFMIN(m->num_substreams - 1, 2);
+
+ m->avctx->sample_rate = mh.group1_samplerate;
+ m->avctx->frame_size = mh.access_unit_size;
+
+ m->avctx->bits_per_raw_sample = mh.group1_bits;
+ if (mh.group1_bits > 16)
+ m->avctx->sample_fmt = AV_SAMPLE_FMT_S32;
+ else
+ m->avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ m->dsp.mlp_pack_output = m->dsp.mlp_select_pack_output(m->substream[m->max_decoded_substream].ch_assign,
+ m->substream[m->max_decoded_substream].output_shift,
+ m->substream[m->max_decoded_substream].max_matrix_channel,
+ m->avctx->sample_fmt == AV_SAMPLE_FMT_S32);
+
+ m->params_valid = 1;
+ for (substr = 0; substr < MAX_SUBSTREAMS; substr++)
+ m->substream[substr].restart_seen = 0;
+
+ /* Set the layout for each substream. When there's more than one, the first
+ * substream is Stereo. Subsequent substreams' layouts are indicated in the
+ * major sync. */
+ if (m->avctx->codec_id == AV_CODEC_ID_MLP) {
+ if (mh.stream_type != 0xbb) {
+ avpriv_request_sample(m->avctx,
+ "unexpected stream_type %X in MLP",
+ mh.stream_type);
+ return AVERROR_PATCHWELCOME;
+ }
+ if ((substr = (mh.num_substreams > 1)))
+ m->substream[0].ch_layout = AV_CH_LAYOUT_STEREO;
+ m->substream[substr].ch_layout = mh.channel_layout_mlp;
+ } else {
+ if (mh.stream_type != 0xba) {
+ avpriv_request_sample(m->avctx,
+ "unexpected stream_type %X in !MLP",
+ mh.stream_type);
+ return AVERROR_PATCHWELCOME;
+ }
+ if ((substr = (mh.num_substreams > 1)))
+ m->substream[0].ch_layout = AV_CH_LAYOUT_STEREO;
+ if (mh.num_substreams > 2)
+ if (mh.channel_layout_thd_stream2)
+ m->substream[2].ch_layout = mh.channel_layout_thd_stream2;
+ else
+ m->substream[2].ch_layout = mh.channel_layout_thd_stream1;
+ m->substream[substr].ch_layout = mh.channel_layout_thd_stream1;
+
+ if (m->avctx->channels<=2 && m->substream[substr].ch_layout == AV_CH_LAYOUT_MONO && m->max_decoded_substream == 1) {
+ av_log(m->avctx, AV_LOG_DEBUG, "Mono stream with 2 substreams, ignoring 2nd\n");
+ m->max_decoded_substream = 0;
+ if (m->avctx->channels==2)
+ m->avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+ }
+ }
+
+ m->needs_reordering = mh.channel_arrangement >= 18 && mh.channel_arrangement <= 20;
+
+ /* Parse the TrueHD decoder channel modifiers and set each substream's
+ * AVMatrixEncoding accordingly.
+ *
+ * The meaning of the modifiers depends on the channel layout:
+ *
+ * - THD_CH_MODIFIER_LTRT, THD_CH_MODIFIER_LBINRBIN only apply to 2-channel
+ *
+ * - THD_CH_MODIFIER_MONO applies to 1-channel or 2-channel (dual mono)
+ *
+ * - THD_CH_MODIFIER_SURROUNDEX, THD_CH_MODIFIER_NOTSURROUNDEX only apply to
+ * layouts with an Ls/Rs channel pair
+ */
+ for (substr = 0; substr < MAX_SUBSTREAMS; substr++)
+ m->substream[substr].matrix_encoding = AV_MATRIX_ENCODING_NONE;
+ if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD) {
+ if (mh.num_substreams > 2 &&
+ mh.channel_layout_thd_stream2 & AV_CH_SIDE_LEFT &&
+ mh.channel_layout_thd_stream2 & AV_CH_SIDE_RIGHT &&
+ mh.channel_modifier_thd_stream2 == THD_CH_MODIFIER_SURROUNDEX)
+ m->substream[2].matrix_encoding = AV_MATRIX_ENCODING_DOLBYEX;
+
+ if (mh.num_substreams > 1 &&
+ mh.channel_layout_thd_stream1 & AV_CH_SIDE_LEFT &&
+ mh.channel_layout_thd_stream1 & AV_CH_SIDE_RIGHT &&
+ mh.channel_modifier_thd_stream1 == THD_CH_MODIFIER_SURROUNDEX)
+ m->substream[1].matrix_encoding = AV_MATRIX_ENCODING_DOLBYEX;
+
+ if (mh.num_substreams > 0)
+ switch (mh.channel_modifier_thd_stream0) {
+ case THD_CH_MODIFIER_LTRT:
+ m->substream[0].matrix_encoding = AV_MATRIX_ENCODING_DOLBY;
+ break;
+ case THD_CH_MODIFIER_LBINRBIN:
+ m->substream[0].matrix_encoding = AV_MATRIX_ENCODING_DOLBYHEADPHONE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
+/** Read a restart header from a block in a substream. This contains parameters
+ * required to decode the audio that do not change very often. Generally
+ * (always) present only in blocks following a major sync. */
+
+static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp,
+ const uint8_t *buf, unsigned int substr)
+{
+ SubStream *s = &m->substream[substr];
+ unsigned int ch;
+ int sync_word, tmp;
+ uint8_t checksum;
+ uint8_t lossless_check;
+ int start_count = get_bits_count(gbp);
+ int min_channel, max_channel, max_matrix_channel;
+ const int std_max_matrix_channel = m->avctx->codec_id == AV_CODEC_ID_MLP
+ ? MAX_MATRIX_CHANNEL_MLP
+ : MAX_MATRIX_CHANNEL_TRUEHD;
+
+ sync_word = get_bits(gbp, 13);
+
+ if (sync_word != 0x31ea >> 1) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "restart header sync incorrect (got 0x%04x)\n", sync_word);
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->noise_type = get_bits1(gbp);
+
+ if (m->avctx->codec_id == AV_CODEC_ID_MLP && s->noise_type) {
+ av_log(m->avctx, AV_LOG_ERROR, "MLP must have 0x31ea sync word.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ skip_bits(gbp, 16); /* Output timestamp */
+
+ min_channel = get_bits(gbp, 4);
+ max_channel = get_bits(gbp, 4);
+ max_matrix_channel = get_bits(gbp, 4);
+
+ if (max_matrix_channel > std_max_matrix_channel) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "Max matrix channel cannot be greater than %d.\n",
+ std_max_matrix_channel);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (max_channel != max_matrix_channel) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "Max channel must be equal max matrix channel.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* This should happen for TrueHD streams with >6 channels and MLP's noise
+ * type. It is not yet known if this is allowed. */
+ if (max_channel > MAX_MATRIX_CHANNEL_MLP && !s->noise_type) {
+ avpriv_request_sample(m->avctx,
+ "%d channels (more than the "
+ "maximum supported by the decoder)",
+ max_channel + 2);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if (min_channel > max_channel) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "Substream min channel cannot be greater than max channel.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->min_channel = min_channel;
+ s->max_channel = max_channel;
+ s->max_matrix_channel = max_matrix_channel;
+
+#if FF_API_REQUEST_CHANNELS
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (m->avctx->request_channels > 0 &&
+ m->avctx->request_channels <= s->max_channel + 1 &&
+ m->max_decoded_substream > substr) {
+ av_log(m->avctx, AV_LOG_DEBUG,
+ "Extracting %d-channel downmix from substream %d. "
+ "Further substreams will be skipped.\n",
+ s->max_channel + 1, substr);
+ m->max_decoded_substream = substr;
+FF_ENABLE_DEPRECATION_WARNINGS
+ } else
+#endif
+ if (m->avctx->request_channel_layout && (s->ch_layout & m->avctx->request_channel_layout) ==
+ m->avctx->request_channel_layout && m->max_decoded_substream > substr) {
+ av_log(m->avctx, AV_LOG_DEBUG,
+ "Extracting %d-channel downmix (0x%"PRIx64") from substream %d. "
+ "Further substreams will be skipped.\n",
+ s->max_channel + 1, s->ch_layout, substr);
+ m->max_decoded_substream = substr;
+ }
+
+ s->noise_shift = get_bits(gbp, 4);
+ s->noisegen_seed = get_bits(gbp, 23);
+
+ skip_bits(gbp, 19);
+
+ s->data_check_present = get_bits1(gbp);
+ lossless_check = get_bits(gbp, 8);
+ if (substr == m->max_decoded_substream
+ && s->lossless_check_data != 0xffffffff) {
+ tmp = xor_32_to_8(s->lossless_check_data);
+ if (tmp != lossless_check)
+ av_log(m->avctx, AV_LOG_WARNING,
+ "Lossless check failed - expected %02x, calculated %02x.\n",
+ lossless_check, tmp);
+ }
+
+ skip_bits(gbp, 16);
+
+ memset(s->ch_assign, 0, sizeof(s->ch_assign));
+
+ for (ch = 0; ch <= s->max_matrix_channel; ch++) {
+ int ch_assign = get_bits(gbp, 6);
+ if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD) {
+ uint64_t channel = thd_channel_layout_extract_channel(s->ch_layout,
+ ch_assign);
+ ch_assign = av_get_channel_layout_channel_index(s->ch_layout,
+ channel);
+ }
+ if (ch_assign < 0 || ch_assign > s->max_matrix_channel) {
+ avpriv_request_sample(m->avctx,
+ "Assignment of matrix channel %d to invalid output channel %d",
+ ch, ch_assign);
+ return AVERROR_PATCHWELCOME;
+ }
+ s->ch_assign[ch_assign] = ch;
+ }
+
+ checksum = ff_mlp_restart_checksum(buf, get_bits_count(gbp) - start_count);
+
+ if (checksum != get_bits(gbp, 8))
+ av_log(m->avctx, AV_LOG_ERROR, "restart header checksum error\n");
+
+ /* Set default decoding parameters. */
+ s->param_presence_flags = 0xff;
+ s->num_primitive_matrices = 0;
+ s->blocksize = 8;
+ s->lossless_check_data = 0;
+
+ memset(s->output_shift , 0, sizeof(s->output_shift ));
+ memset(s->quant_step_size, 0, sizeof(s->quant_step_size));
+
+ for (ch = s->min_channel; ch <= s->max_channel; ch++) {
+ ChannelParams *cp = &s->channel_params[ch];
+ cp->filter_params[FIR].order = 0;
+ cp->filter_params[IIR].order = 0;
+ cp->filter_params[FIR].shift = 0;
+ cp->filter_params[IIR].shift = 0;
+
+ /* Default audio coding is 24-bit raw PCM. */
+ cp->huff_offset = 0;
+ cp->sign_huff_offset = (-1) << 23;
+ cp->codebook = 0;
+ cp->huff_lsbs = 24;
+ }
+
+ if (substr == m->max_decoded_substream) {
+ m->avctx->channels = s->max_matrix_channel + 1;
+ m->avctx->channel_layout = s->ch_layout;
+ m->dsp.mlp_pack_output = m->dsp.mlp_select_pack_output(s->ch_assign,
+ s->output_shift,
+ s->max_matrix_channel,
+ m->avctx->sample_fmt == AV_SAMPLE_FMT_S32);
+
+ if (m->avctx->codec_id == AV_CODEC_ID_MLP && m->needs_reordering) {
+ if (m->avctx->channel_layout == (AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY) ||
+ m->avctx->channel_layout == AV_CH_LAYOUT_5POINT0_BACK) {
+ int i = s->ch_assign[4];
+ s->ch_assign[4] = s->ch_assign[3];
+ s->ch_assign[3] = s->ch_assign[2];
+ s->ch_assign[2] = i;
+ } else if (m->avctx->channel_layout == AV_CH_LAYOUT_5POINT1_BACK) {
+ FFSWAP(int, s->ch_assign[2], s->ch_assign[4]);
+ FFSWAP(int, s->ch_assign[3], s->ch_assign[5]);
+ }
+ }
+
+ }
+
+ return 0;
+}
+
+/** Read parameters for one of the prediction filters. */
+
+static int read_filter_params(MLPDecodeContext *m, GetBitContext *gbp,
+ unsigned int substr, unsigned int channel,
+ unsigned int filter)
+{
+ SubStream *s = &m->substream[substr];
+ FilterParams *fp = &s->channel_params[channel].filter_params[filter];
+ const int max_order = filter ? MAX_IIR_ORDER : MAX_FIR_ORDER;
+ const char fchar = filter ? 'I' : 'F';
+ int i, order;
+
+ // Filter is 0 for FIR, 1 for IIR.
+ av_assert0(filter < 2);
+
+ if (m->filter_changed[channel][filter]++ > 1) {
+ av_log(m->avctx, AV_LOG_ERROR, "Filters may change only once per access unit.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ order = get_bits(gbp, 4);
+ if (order > max_order) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "%cIR filter order %d is greater than maximum %d.\n",
+ fchar, order, max_order);
+ return AVERROR_INVALIDDATA;
+ }
+ fp->order = order;
+
+ if (order > 0) {
+ int32_t *fcoeff = s->channel_params[channel].coeff[filter];
+ int coeff_bits, coeff_shift;
+
+ fp->shift = get_bits(gbp, 4);
+
+ coeff_bits = get_bits(gbp, 5);
+ coeff_shift = get_bits(gbp, 3);
+ if (coeff_bits < 1 || coeff_bits > 16) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "%cIR filter coeff_bits must be between 1 and 16.\n",
+ fchar);
+ return AVERROR_INVALIDDATA;
+ }
+ if (coeff_bits + coeff_shift > 16) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "Sum of coeff_bits and coeff_shift for %cIR filter must be 16 or less.\n",
+ fchar);
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (i = 0; i < order; i++)
+ fcoeff[i] = get_sbits(gbp, coeff_bits) * (1 << coeff_shift);
+
+ if (get_bits1(gbp)) {
+ int state_bits, state_shift;
+
+ if (filter == FIR) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "FIR filter has state data specified.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ state_bits = get_bits(gbp, 4);
+ state_shift = get_bits(gbp, 4);
+
+ /* TODO: Check validity of state data. */
+
+ for (i = 0; i < order; i++)
+ fp->state[i] = state_bits ? get_sbits(gbp, state_bits) * (1 << state_shift) : 0;
+ }
+ }
+
+ return 0;
+}
+
+/** Read parameters for primitive matrices. */
+
+static int read_matrix_params(MLPDecodeContext *m, unsigned int substr, GetBitContext *gbp)
+{
+ SubStream *s = &m->substream[substr];
+ unsigned int mat, ch;
+ const int max_primitive_matrices = m->avctx->codec_id == AV_CODEC_ID_MLP
+ ? MAX_MATRICES_MLP
+ : MAX_MATRICES_TRUEHD;
+
+ if (m->matrix_changed++ > 1) {
+ av_log(m->avctx, AV_LOG_ERROR, "Matrices may change only once per access unit.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->num_primitive_matrices = get_bits(gbp, 4);
+
+ if (s->num_primitive_matrices > max_primitive_matrices) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "Number of primitive matrices cannot be greater than %d.\n",
+ max_primitive_matrices);
+ goto error;
+ }
+
+ for (mat = 0; mat < s->num_primitive_matrices; mat++) {
+ int frac_bits, max_chan;
+ s->matrix_out_ch[mat] = get_bits(gbp, 4);
+ frac_bits = get_bits(gbp, 4);
+ s->lsb_bypass [mat] = get_bits1(gbp);
+
+ if (s->matrix_out_ch[mat] > s->max_matrix_channel) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "Invalid channel %d specified as output from matrix.\n",
+ s->matrix_out_ch[mat]);
+ goto error;
+ }
+ if (frac_bits > 14) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "Too many fractional bits specified.\n");
+ goto error;
+ }
+
+ max_chan = s->max_matrix_channel;
+ if (!s->noise_type)
+ max_chan+=2;
+
+ for (ch = 0; ch <= max_chan; ch++) {
+ int coeff_val = 0;
+ if (get_bits1(gbp))
+ coeff_val = get_sbits(gbp, frac_bits + 2);
+
+ s->matrix_coeff[mat][ch] = coeff_val * (1 << (14 - frac_bits));
+ }
+
+ if (s->noise_type)
+ s->matrix_noise_shift[mat] = get_bits(gbp, 4);
+ else
+ s->matrix_noise_shift[mat] = 0;
+ }
+
+ return 0;
+error:
+ s->num_primitive_matrices = 0;
+ memset(s->matrix_out_ch, 0, sizeof(s->matrix_out_ch));
+
+ return AVERROR_INVALIDDATA;
+}
+
+/** Read channel parameters. */
+
+static int read_channel_params(MLPDecodeContext *m, unsigned int substr,
+ GetBitContext *gbp, unsigned int ch)
+{
+ SubStream *s = &m->substream[substr];
+ ChannelParams *cp = &s->channel_params[ch];
+ FilterParams *fir = &cp->filter_params[FIR];
+ FilterParams *iir = &cp->filter_params[IIR];
+ int ret;
+
+ if (s->param_presence_flags & PARAM_FIR)
+ if (get_bits1(gbp))
+ if ((ret = read_filter_params(m, gbp, substr, ch, FIR)) < 0)
+ return ret;
+
+ if (s->param_presence_flags & PARAM_IIR)
+ if (get_bits1(gbp))
+ if ((ret = read_filter_params(m, gbp, substr, ch, IIR)) < 0)
+ return ret;
+
+ if (fir->order + iir->order > 8) {
+ av_log(m->avctx, AV_LOG_ERROR, "Total filter orders too high.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (fir->order && iir->order &&
+ fir->shift != iir->shift) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "FIR and IIR filters must use the same precision.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ /* The FIR and IIR filters must have the same precision.
+ * To simplify the filtering code, only the precision of the
+ * FIR filter is considered. If only the IIR filter is employed,
+ * the FIR filter precision is set to that of the IIR filter, so
+ * that the filtering code can use it. */
+ if (!fir->order && iir->order)
+ fir->shift = iir->shift;
+
+ if (s->param_presence_flags & PARAM_HUFFOFFSET)
+ if (get_bits1(gbp))
+ cp->huff_offset = get_sbits(gbp, 15);
+
+ cp->codebook = get_bits(gbp, 2);
+ cp->huff_lsbs = get_bits(gbp, 5);
+
+ if (cp->huff_lsbs > 24) {
+ av_log(m->avctx, AV_LOG_ERROR, "Invalid huff_lsbs.\n");
+ cp->huff_lsbs = 0;
+ return AVERROR_INVALIDDATA;
+ }
+
+ cp->sign_huff_offset = calculate_sign_huff(m, substr, ch);
+
+ return 0;
+}
+
+/** Read decoding parameters that change more often than those in the restart
+ * header. */
+
+static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp,
+ unsigned int substr)
+{
+ SubStream *s = &m->substream[substr];
+ unsigned int ch;
+ int ret;
+
+ if (s->param_presence_flags & PARAM_PRESENCE)
+ if (get_bits1(gbp))
+ s->param_presence_flags = get_bits(gbp, 8);
+
+ if (s->param_presence_flags & PARAM_BLOCKSIZE)
+ if (get_bits1(gbp)) {
+ s->blocksize = get_bits(gbp, 9);
+ if (s->blocksize < 8 || s->blocksize > m->access_unit_size) {
+ av_log(m->avctx, AV_LOG_ERROR, "Invalid blocksize.\n");
+ s->blocksize = 0;
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if (s->param_presence_flags & PARAM_MATRIX)
+ if (get_bits1(gbp))
+ if ((ret = read_matrix_params(m, substr, gbp)) < 0)
+ return ret;
+
+ if (s->param_presence_flags & PARAM_OUTSHIFT)
+ if (get_bits1(gbp)) {
+ for (ch = 0; ch <= s->max_matrix_channel; ch++)
+ s->output_shift[ch] = get_sbits(gbp, 4);
+ if (substr == m->max_decoded_substream)
+ m->dsp.mlp_pack_output = m->dsp.mlp_select_pack_output(s->ch_assign,
+ s->output_shift,
+ s->max_matrix_channel,
+ m->avctx->sample_fmt == AV_SAMPLE_FMT_S32);
+ }
+
+ if (s->param_presence_flags & PARAM_QUANTSTEP)
+ if (get_bits1(gbp))
+ for (ch = 0; ch <= s->max_channel; ch++) {
+ ChannelParams *cp = &s->channel_params[ch];
+
+ s->quant_step_size[ch] = get_bits(gbp, 4);
+
+ cp->sign_huff_offset = calculate_sign_huff(m, substr, ch);
+ }
+
+ for (ch = s->min_channel; ch <= s->max_channel; ch++)
+ if (get_bits1(gbp))
+ if ((ret = read_channel_params(m, substr, gbp, ch)) < 0)
+ return ret;
+
+ return 0;
+}
+
+#define MSB_MASK(bits) (-1u << (bits))
+
+/** Generate PCM samples using the prediction filters and residual values
+ * read from the data stream, and update the filter state. */
+
+static void filter_channel(MLPDecodeContext *m, unsigned int substr,
+ unsigned int channel)
+{
+ SubStream *s = &m->substream[substr];
+ const int32_t *fircoeff = s->channel_params[channel].coeff[FIR];
+ int32_t state_buffer[NUM_FILTERS][MAX_BLOCKSIZE + MAX_FIR_ORDER];
+ int32_t *firbuf = state_buffer[FIR] + MAX_BLOCKSIZE;
+ int32_t *iirbuf = state_buffer[IIR] + MAX_BLOCKSIZE;
+ FilterParams *fir = &s->channel_params[channel].filter_params[FIR];
+ FilterParams *iir = &s->channel_params[channel].filter_params[IIR];
+ unsigned int filter_shift = fir->shift;
+ int32_t mask = MSB_MASK(s->quant_step_size[channel]);
+
+ memcpy(firbuf, fir->state, MAX_FIR_ORDER * sizeof(int32_t));
+ memcpy(iirbuf, iir->state, MAX_IIR_ORDER * sizeof(int32_t));
+
+ m->dsp.mlp_filter_channel(firbuf, fircoeff,
+ fir->order, iir->order,
+ filter_shift, mask, s->blocksize,
+ &m->sample_buffer[s->blockpos][channel]);
+
+ memcpy(fir->state, firbuf - s->blocksize, MAX_FIR_ORDER * sizeof(int32_t));
+ memcpy(iir->state, iirbuf - s->blocksize, MAX_IIR_ORDER * sizeof(int32_t));
+}
+
+/** Read a block of PCM residual data (or actual if no filtering active). */
+
+static int read_block_data(MLPDecodeContext *m, GetBitContext *gbp,
+ unsigned int substr)
+{
+ SubStream *s = &m->substream[substr];
+ unsigned int i, ch, expected_stream_pos = 0;
+ int ret;
+
+ if (s->data_check_present) {
+ expected_stream_pos = get_bits_count(gbp);
+ expected_stream_pos += get_bits(gbp, 16);
+ avpriv_request_sample(m->avctx,
+ "Substreams with VLC block size check info");
+ }
+
+ if (s->blockpos + s->blocksize > m->access_unit_size) {
+ av_log(m->avctx, AV_LOG_ERROR, "too many audio samples in frame\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ memset(&m->bypassed_lsbs[s->blockpos][0], 0,
+ s->blocksize * sizeof(m->bypassed_lsbs[0]));
+
+ for (i = 0; i < s->blocksize; i++)
+ if ((ret = read_huff_channels(m, gbp, substr, i)) < 0)
+ return ret;
+
+ for (ch = s->min_channel; ch <= s->max_channel; ch++)
+ filter_channel(m, substr, ch);
+
+ s->blockpos += s->blocksize;
+
+ if (s->data_check_present) {
+ if (get_bits_count(gbp) != expected_stream_pos)
+ av_log(m->avctx, AV_LOG_ERROR, "block data length mismatch\n");
+ skip_bits(gbp, 8);
+ }
+
+ return 0;
+}
+
+/** Data table used for TrueHD noise generation function. */
+
+static const int8_t noise_table[256] = {
+ 30, 51, 22, 54, 3, 7, -4, 38, 14, 55, 46, 81, 22, 58, -3, 2,
+ 52, 31, -7, 51, 15, 44, 74, 30, 85, -17, 10, 33, 18, 80, 28, 62,
+ 10, 32, 23, 69, 72, 26, 35, 17, 73, 60, 8, 56, 2, 6, -2, -5,
+ 51, 4, 11, 50, 66, 76, 21, 44, 33, 47, 1, 26, 64, 48, 57, 40,
+ 38, 16, -10, -28, 92, 22, -18, 29, -10, 5, -13, 49, 19, 24, 70, 34,
+ 61, 48, 30, 14, -6, 25, 58, 33, 42, 60, 67, 17, 54, 17, 22, 30,
+ 67, 44, -9, 50, -11, 43, 40, 32, 59, 82, 13, 49, -14, 55, 60, 36,
+ 48, 49, 31, 47, 15, 12, 4, 65, 1, 23, 29, 39, 45, -2, 84, 69,
+ 0, 72, 37, 57, 27, 41, -15, -16, 35, 31, 14, 61, 24, 0, 27, 24,
+ 16, 41, 55, 34, 53, 9, 56, 12, 25, 29, 53, 5, 20, -20, -8, 20,
+ 13, 28, -3, 78, 38, 16, 11, 62, 46, 29, 21, 24, 46, 65, 43, -23,
+ 89, 18, 74, 21, 38, -12, 19, 12, -19, 8, 15, 33, 4, 57, 9, -8,
+ 36, 35, 26, 28, 7, 83, 63, 79, 75, 11, 3, 87, 37, 47, 34, 40,
+ 39, 19, 20, 42, 27, 34, 39, 77, 13, 42, 59, 64, 45, -1, 32, 37,
+ 45, -5, 53, -6, 7, 36, 50, 23, 6, 32, 9, -21, 18, 71, 27, 52,
+ -25, 31, 35, 42, -1, 68, 63, 52, 26, 43, 66, 37, 41, 25, 40, 70,
+};
+
+/** Noise generation functions.
+ * I'm not sure what these are for - they seem to be some kind of pseudorandom
+ * sequence generators, used to generate noise data which is used when the
+ * channels are rematrixed. I'm not sure if they provide a practical benefit
+ * to compression, or just obfuscate the decoder. Are they for some kind of
+ * dithering? */
+
+/** Generate two channels of noise, used in the matrix when
+ * restart sync word == 0x31ea. */
+
+static void generate_2_noise_channels(MLPDecodeContext *m, unsigned int substr)
+{
+ SubStream *s = &m->substream[substr];
+ unsigned int i;
+ uint32_t seed = s->noisegen_seed;
+ unsigned int maxchan = s->max_matrix_channel;
+
+ for (i = 0; i < s->blockpos; i++) {
+ uint16_t seed_shr7 = seed >> 7;
+ m->sample_buffer[i][maxchan+1] = ((int8_t)(seed >> 15)) * (1 << s->noise_shift);
+ m->sample_buffer[i][maxchan+2] = ((int8_t) seed_shr7) * (1 << s->noise_shift);
+
+ seed = (seed << 16) ^ seed_shr7 ^ (seed_shr7 << 5);
+ }
+
+ s->noisegen_seed = seed;
+}
+
+/** Generate a block of noise, used when restart sync word == 0x31eb. */
+
+static void fill_noise_buffer(MLPDecodeContext *m, unsigned int substr)
+{
+ SubStream *s = &m->substream[substr];
+ unsigned int i;
+ uint32_t seed = s->noisegen_seed;
+
+ for (i = 0; i < m->access_unit_size_pow2; i++) {
+ uint8_t seed_shr15 = seed >> 15;
+ m->noise_buffer[i] = noise_table[seed_shr15];
+ seed = (seed << 8) ^ seed_shr15 ^ (seed_shr15 << 5);
+ }
+
+ s->noisegen_seed = seed;
+}
+
+/** Write the audio data into the output buffer. */
+
+static int output_data(MLPDecodeContext *m, unsigned int substr,
+ AVFrame *frame, int *got_frame_ptr)
+{
+ AVCodecContext *avctx = m->avctx;
+ SubStream *s = &m->substream[substr];
+ unsigned int mat;
+ unsigned int maxchan;
+ int ret;
+ int is32 = (m->avctx->sample_fmt == AV_SAMPLE_FMT_S32);
+
+ if (m->avctx->channels != s->max_matrix_channel + 1) {
+ av_log(m->avctx, AV_LOG_ERROR, "channel count mismatch\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!s->blockpos) {
+ av_log(avctx, AV_LOG_ERROR, "No samples to output.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ maxchan = s->max_matrix_channel;
+ if (!s->noise_type) {
+ generate_2_noise_channels(m, substr);
+ maxchan += 2;
+ } else {
+ fill_noise_buffer(m, substr);
+ }
+
+ /* Apply the channel matrices in turn to reconstruct the original audio
+ * samples. */
+ for (mat = 0; mat < s->num_primitive_matrices; mat++) {
+ unsigned int dest_ch = s->matrix_out_ch[mat];
+ m->dsp.mlp_rematrix_channel(&m->sample_buffer[0][0],
+ s->matrix_coeff[mat],
+ &m->bypassed_lsbs[0][mat],
+ m->noise_buffer,
+ s->num_primitive_matrices - mat,
+ dest_ch,
+ s->blockpos,
+ maxchan,
+ s->matrix_noise_shift[mat],
+ m->access_unit_size_pow2,
+ MSB_MASK(s->quant_step_size[dest_ch]));
+ }
+
+ /* get output buffer */
+ frame->nb_samples = s->blockpos;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+ s->lossless_check_data = m->dsp.mlp_pack_output(s->lossless_check_data,
+ s->blockpos,
+ m->sample_buffer,
+ frame->data[0],
+ s->ch_assign,
+ s->output_shift,
+ s->max_matrix_channel,
+ is32);
+
+ /* Update matrix encoding side data */
+ if ((ret = ff_side_data_update_matrix_encoding(frame, s->matrix_encoding)) < 0)
+ return ret;
+
+ *got_frame_ptr = 1;
+
+ return 0;
+}
+
+/** Read an access unit from the stream.
+ * @return negative on error, 0 if not enough data is present in the input stream,
+ * otherwise the number of bytes consumed. */
+
+static int read_access_unit(AVCodecContext *avctx, void* data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ MLPDecodeContext *m = avctx->priv_data;
+ GetBitContext gb;
+ unsigned int length, substr;
+ unsigned int substream_start;
+ unsigned int header_size = 4;
+ unsigned int substr_header_size = 0;
+ uint8_t substream_parity_present[MAX_SUBSTREAMS];
+ uint16_t substream_data_len[MAX_SUBSTREAMS];
+ uint8_t parity_bits;
+ int ret;
+
+ if (buf_size < 4)
+ return AVERROR_INVALIDDATA;
+
+ length = (AV_RB16(buf) & 0xfff) * 2;
+
+ if (length < 4 || length > buf_size)
+ return AVERROR_INVALIDDATA;
+
+ init_get_bits(&gb, (buf + 4), (length - 4) * 8);
+
+ m->is_major_sync_unit = 0;
+ if (show_bits_long(&gb, 31) == (0xf8726fba >> 1)) {
+ if (read_major_sync(m, &gb) < 0)
+ goto error;
+ m->is_major_sync_unit = 1;
+ header_size += m->major_sync_header_size;
+ }
+
+ if (!m->params_valid) {
+ av_log(m->avctx, AV_LOG_WARNING,
+ "Stream parameters not seen; skipping frame.\n");
+ *got_frame_ptr = 0;
+ return length;
+ }
+
+ substream_start = 0;
+
+ for (substr = 0; substr < m->num_substreams; substr++) {
+ int extraword_present, checkdata_present, end, nonrestart_substr;
+
+ extraword_present = get_bits1(&gb);
+ nonrestart_substr = get_bits1(&gb);
+ checkdata_present = get_bits1(&gb);
+ skip_bits1(&gb);
+
+ end = get_bits(&gb, 12) * 2;
+
+ substr_header_size += 2;
+
+ if (extraword_present) {
+ if (m->avctx->codec_id == AV_CODEC_ID_MLP) {
+ av_log(m->avctx, AV_LOG_ERROR, "There must be no extraword for MLP.\n");
+ goto error;
+ }
+ skip_bits(&gb, 16);
+ substr_header_size += 2;
+ }
+
+ if (length < header_size + substr_header_size) {
+ av_log(m->avctx, AV_LOG_ERROR, "Insuffient data for headers\n");
+ goto error;
+ }
+
+ if (!(nonrestart_substr ^ m->is_major_sync_unit)) {
+ av_log(m->avctx, AV_LOG_ERROR, "Invalid nonrestart_substr.\n");
+ goto error;
+ }
+
+ if (end + header_size + substr_header_size > length) {
+ av_log(m->avctx, AV_LOG_ERROR,
+ "Indicated length of substream %d data goes off end of "
+ "packet.\n", substr);
+ end = length - header_size - substr_header_size;
+ }
+
+ if (end < substream_start) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Indicated end offset of substream %d data "
+ "is smaller than calculated start offset.\n",
+ substr);
+ goto error;
+ }
+
+ if (substr > m->max_decoded_substream)
+ continue;
+
+ substream_parity_present[substr] = checkdata_present;
+ substream_data_len[substr] = end - substream_start;
+ substream_start = end;
+ }
+
+ parity_bits = ff_mlp_calculate_parity(buf, 4);
+ parity_bits ^= ff_mlp_calculate_parity(buf + header_size, substr_header_size);
+
+ if ((((parity_bits >> 4) ^ parity_bits) & 0xF) != 0xF) {
+ av_log(avctx, AV_LOG_ERROR, "Parity check failed.\n");
+ goto error;
+ }
+
+ buf += header_size + substr_header_size;
+
+ for (substr = 0; substr <= m->max_decoded_substream; substr++) {
+ SubStream *s = &m->substream[substr];
+ init_get_bits(&gb, buf, substream_data_len[substr] * 8);
+
+ m->matrix_changed = 0;
+ memset(m->filter_changed, 0, sizeof(m->filter_changed));
+
+ s->blockpos = 0;
+ do {
+ if (get_bits1(&gb)) {
+ if (get_bits1(&gb)) {
+ /* A restart header should be present. */
+ if (read_restart_header(m, &gb, buf, substr) < 0)
+ goto next_substr;
+ s->restart_seen = 1;
+ }
+
+ if (!s->restart_seen)
+ goto next_substr;
+ if (read_decoding_params(m, &gb, substr) < 0)
+ goto next_substr;
+ }
+
+ if (!s->restart_seen)
+ goto next_substr;
+
+ if ((ret = read_block_data(m, &gb, substr)) < 0)
+ return ret;
+
+ if (get_bits_count(&gb) >= substream_data_len[substr] * 8)
+ goto substream_length_mismatch;
+
+ } while (!get_bits1(&gb));
+
+ skip_bits(&gb, (-get_bits_count(&gb)) & 15);
+
+ if (substream_data_len[substr] * 8 - get_bits_count(&gb) >= 32) {
+ int shorten_by;
+
+ if (get_bits(&gb, 16) != 0xD234)
+ return AVERROR_INVALIDDATA;
+
+ shorten_by = get_bits(&gb, 16);
+ if (m->avctx->codec_id == AV_CODEC_ID_TRUEHD && shorten_by & 0x2000)
+ s->blockpos -= FFMIN(shorten_by & 0x1FFF, s->blockpos);
+ else if (m->avctx->codec_id == AV_CODEC_ID_MLP && shorten_by != 0xD234)
+ return AVERROR_INVALIDDATA;
+
+ if (substr == m->max_decoded_substream)
+ av_log(m->avctx, AV_LOG_INFO, "End of stream indicated.\n");
+ }
+
+ if (substream_parity_present[substr]) {
+ uint8_t parity, checksum;
+
+ if (substream_data_len[substr] * 8 - get_bits_count(&gb) != 16)
+ goto substream_length_mismatch;
+
+ parity = ff_mlp_calculate_parity(buf, substream_data_len[substr] - 2);
+ checksum = ff_mlp_checksum8 (buf, substream_data_len[substr] - 2);
+
+ if ((get_bits(&gb, 8) ^ parity) != 0xa9 )
+ av_log(m->avctx, AV_LOG_ERROR, "Substream %d parity check failed.\n", substr);
+ if ( get_bits(&gb, 8) != checksum)
+ av_log(m->avctx, AV_LOG_ERROR, "Substream %d checksum failed.\n" , substr);
+ }
+
+ if (substream_data_len[substr] * 8 != get_bits_count(&gb))
+ goto substream_length_mismatch;
+
+next_substr:
+ if (!s->restart_seen)
+ av_log(m->avctx, AV_LOG_ERROR,
+ "No restart header present in substream %d.\n", substr);
+
+ buf += substream_data_len[substr];
+ }
+
+ if ((ret = output_data(m, m->max_decoded_substream, data, got_frame_ptr)) < 0)
+ return ret;
+
+ return length;
+
+substream_length_mismatch:
+ av_log(m->avctx, AV_LOG_ERROR, "substream %d length mismatch\n", substr);
+ return AVERROR_INVALIDDATA;
+
+error:
+ m->params_valid = 0;
+ return AVERROR_INVALIDDATA;
+}
+
+#if CONFIG_MLP_DECODER
+AVCodec ff_mlp_decoder = {
+ .name = "mlp",
+ .long_name = NULL_IF_CONFIG_SMALL("MLP (Meridian Lossless Packing)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_MLP,
+ .priv_data_size = sizeof(MLPDecodeContext),
+ .init = mlp_decode_init,
+ .decode = read_access_unit,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
+#endif
+#if CONFIG_TRUEHD_DECODER
+AVCodec ff_truehd_decoder = {
+ .name = "truehd",
+ .long_name = NULL_IF_CONFIG_SMALL("TrueHD"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_TRUEHD,
+ .priv_data_size = sizeof(MLPDecodeContext),
+ .init = mlp_decode_init,
+ .decode = read_access_unit,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
+#endif /* CONFIG_TRUEHD_DECODER */
diff --git a/ffmpeg-2-8-12/libavcodec/mlpdsp.c b/ffmpeg-2-8-12/libavcodec/mlpdsp.c
new file mode 100644
index 0000000..fbafa92
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/mlpdsp.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2007-2008 Ian Caulfield
+ * 2009 Ramiro Polla
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "libavutil/attributes.h"
+#include "mlpdsp.h"
+#include "mlp.h"
+
+static void mlp_filter_channel(int32_t *state, const int32_t *coeff,
+ int firorder, int iirorder,
+ unsigned int filter_shift, int32_t mask,
+ int blocksize, int32_t *sample_buffer)
+{
+ int32_t *firbuf = state;
+ int32_t *iirbuf = state + MAX_BLOCKSIZE + MAX_FIR_ORDER;
+ const int32_t *fircoeff = coeff;
+ const int32_t *iircoeff = coeff + MAX_FIR_ORDER;
+ int i;
+
+ for (i = 0; i < blocksize; i++) {
+ int32_t residual = *sample_buffer;
+ unsigned int order;
+ int64_t accum = 0;
+ int32_t result;
+
+ for (order = 0; order < firorder; order++)
+ accum += (int64_t) firbuf[order] * fircoeff[order];
+ for (order = 0; order < iirorder; order++)
+ accum += (int64_t) iirbuf[order] * iircoeff[order];
+
+ accum = accum >> filter_shift;
+ result = (accum + residual) & mask;
+
+ *--firbuf = result;
+ *--iirbuf = result - accum;
+
+ *sample_buffer = result;
+ sample_buffer += MAX_CHANNELS;
+ }
+}
+
+void ff_mlp_rematrix_channel(int32_t *samples,
+ const int32_t *coeffs,
+ const uint8_t *bypassed_lsbs,
+ const int8_t *noise_buffer,
+ int index,
+ unsigned int dest_ch,
+ uint16_t blockpos,
+ unsigned int maxchan,
+ int matrix_noise_shift,
+ int access_unit_size_pow2,
+ int32_t mask)
+{
+ unsigned int src_ch, i;
+ int index2 = 2 * index + 1;
+ for (i = 0; i < blockpos; i++) {
+ int64_t accum = 0;
+
+ for (src_ch = 0; src_ch <= maxchan; src_ch++)
+ accum += (int64_t) samples[src_ch] * coeffs[src_ch];
+
+ if (matrix_noise_shift) {
+ index &= access_unit_size_pow2 - 1;
+ accum += noise_buffer[index] << (matrix_noise_shift + 7);
+ index += index2;
+ }
+
+ samples[dest_ch] = ((accum >> 14) & mask) + *bypassed_lsbs;
+ bypassed_lsbs += MAX_CHANNELS;
+ samples += MAX_CHANNELS;
+ }
+}
+
+static int32_t (*mlp_select_pack_output(uint8_t *ch_assign,
+ int8_t *output_shift,
+ uint8_t max_matrix_channel,
+ int is32))(int32_t, uint16_t, int32_t (*)[], void *, uint8_t*, int8_t *, uint8_t, int)
+{
+ return ff_mlp_pack_output;
+}
+
+int32_t ff_mlp_pack_output(int32_t lossless_check_data,
+ uint16_t blockpos,
+ int32_t (*sample_buffer)[MAX_CHANNELS],
+ void *data,
+ uint8_t *ch_assign,
+ int8_t *output_shift,
+ uint8_t max_matrix_channel,
+ int is32)
+{
+ unsigned int i, out_ch = 0;
+ int32_t *data_32 = data;
+ int16_t *data_16 = data;
+
+ for (i = 0; i < blockpos; i++) {
+ for (out_ch = 0; out_ch <= max_matrix_channel; out_ch++) {
+ int mat_ch = ch_assign[out_ch];
+ int32_t sample = sample_buffer[i][mat_ch] *
+ (1U << output_shift[mat_ch]);
+ lossless_check_data ^= (sample & 0xffffff) << mat_ch;
+ if (is32)
+ *data_32++ = sample << 8;
+ else
+ *data_16++ = sample >> 8;
+ }
+ }
+ return lossless_check_data;
+}
+
+av_cold void ff_mlpdsp_init(MLPDSPContext *c)
+{
+ c->mlp_filter_channel = mlp_filter_channel;
+ c->mlp_rematrix_channel = ff_mlp_rematrix_channel;
+ c->mlp_select_pack_output = mlp_select_pack_output;
+ c->mlp_pack_output = ff_mlp_pack_output;
+ if (ARCH_ARM)
+ ff_mlpdsp_init_arm(c);
+ if (ARCH_X86)
+ ff_mlpdsp_init_x86(c);
+}
diff --git a/ffmpeg-2-8-11/libavcodec/mlpdsp.h b/ffmpeg-2-8-12/libavcodec/mlpdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mlpdsp.h
rename to ffmpeg-2-8-12/libavcodec/mlpdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/mmaldec.c b/ffmpeg-2-8-12/libavcodec/mmaldec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mmaldec.c
rename to ffmpeg-2-8-12/libavcodec/mmaldec.c
diff --git a/ffmpeg-2-8-11/libavcodec/mmvideo.c b/ffmpeg-2-8-12/libavcodec/mmvideo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mmvideo.c
rename to ffmpeg-2-8-12/libavcodec/mmvideo.c
diff --git a/ffmpeg-2-8-11/libavcodec/motion-test.c b/ffmpeg-2-8-12/libavcodec/motion-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/motion-test.c
rename to ffmpeg-2-8-12/libavcodec/motion-test.c
diff --git a/ffmpeg-2-8-11/libavcodec/motion_est.c b/ffmpeg-2-8-12/libavcodec/motion_est.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/motion_est.c
rename to ffmpeg-2-8-12/libavcodec/motion_est.c
diff --git a/ffmpeg-2-8-11/libavcodec/motion_est.h b/ffmpeg-2-8-12/libavcodec/motion_est.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/motion_est.h
rename to ffmpeg-2-8-12/libavcodec/motion_est.h
diff --git a/ffmpeg-2-8-11/libavcodec/motion_est_template.c b/ffmpeg-2-8-12/libavcodec/motion_est_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/motion_est_template.c
rename to ffmpeg-2-8-12/libavcodec/motion_est_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/motionpixels.c b/ffmpeg-2-8-12/libavcodec/motionpixels.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/motionpixels.c
rename to ffmpeg-2-8-12/libavcodec/motionpixels.c
diff --git a/ffmpeg-2-8-11/libavcodec/motionpixels_tablegen.c b/ffmpeg-2-8-12/libavcodec/motionpixels_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/motionpixels_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/motionpixels_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/motionpixels_tablegen.h b/ffmpeg-2-8-12/libavcodec/motionpixels_tablegen.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/motionpixels_tablegen.h
rename to ffmpeg-2-8-12/libavcodec/motionpixels_tablegen.h
diff --git a/ffmpeg-2-8-11/libavcodec/movsub_bsf.c b/ffmpeg-2-8-12/libavcodec/movsub_bsf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/movsub_bsf.c
rename to ffmpeg-2-8-12/libavcodec/movsub_bsf.c
diff --git a/ffmpeg-2-8-11/libavcodec/movtextdec.c b/ffmpeg-2-8-12/libavcodec/movtextdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/movtextdec.c
rename to ffmpeg-2-8-12/libavcodec/movtextdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/movtextenc.c b/ffmpeg-2-8-12/libavcodec/movtextenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/movtextenc.c
rename to ffmpeg-2-8-12/libavcodec/movtextenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/mp3_header_decompress_bsf.c b/ffmpeg-2-8-12/libavcodec/mp3_header_decompress_bsf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mp3_header_decompress_bsf.c
rename to ffmpeg-2-8-12/libavcodec/mp3_header_decompress_bsf.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpc.c b/ffmpeg-2-8-12/libavcodec/mpc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpc.c
rename to ffmpeg-2-8-12/libavcodec/mpc.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpc.h b/ffmpeg-2-8-12/libavcodec/mpc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpc.h
rename to ffmpeg-2-8-12/libavcodec/mpc.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpc7.c b/ffmpeg-2-8-12/libavcodec/mpc7.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpc7.c
rename to ffmpeg-2-8-12/libavcodec/mpc7.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpc7data.h b/ffmpeg-2-8-12/libavcodec/mpc7data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpc7data.h
rename to ffmpeg-2-8-12/libavcodec/mpc7data.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpc8.c b/ffmpeg-2-8-12/libavcodec/mpc8.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpc8.c
rename to ffmpeg-2-8-12/libavcodec/mpc8.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpc8data.h b/ffmpeg-2-8-12/libavcodec/mpc8data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpc8data.h
rename to ffmpeg-2-8-12/libavcodec/mpc8data.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpc8huff.h b/ffmpeg-2-8-12/libavcodec/mpc8huff.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpc8huff.h
rename to ffmpeg-2-8-12/libavcodec/mpc8huff.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpcdata.h b/ffmpeg-2-8-12/libavcodec/mpcdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpcdata.h
rename to ffmpeg-2-8-12/libavcodec/mpcdata.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg12.c b/ffmpeg-2-8-12/libavcodec/mpeg12.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg12.c
rename to ffmpeg-2-8-12/libavcodec/mpeg12.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg12.h b/ffmpeg-2-8-12/libavcodec/mpeg12.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg12.h
rename to ffmpeg-2-8-12/libavcodec/mpeg12.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg12data.c b/ffmpeg-2-8-12/libavcodec/mpeg12data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg12data.c
rename to ffmpeg-2-8-12/libavcodec/mpeg12data.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg12data.h b/ffmpeg-2-8-12/libavcodec/mpeg12data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg12data.h
rename to ffmpeg-2-8-12/libavcodec/mpeg12data.h
diff --git a/ffmpeg-2-8-12/libavcodec/mpeg12dec.c b/ffmpeg-2-8-12/libavcodec/mpeg12dec.c
new file mode 100644
index 0000000..9872e67
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/mpeg12dec.c
@@ -0,0 +1,2993 @@
+/*
+ * MPEG-1/2 decoder
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ * Copyright (c) 2002-2013 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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-1/2 decoder
+ */
+
+#define UNCHECKED_BITSTREAM_READER 1
+#include <inttypes.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
+#include "libavutil/stereo3d.h"
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "error_resilience.h"
+#include "idctdsp.h"
+#include "internal.h"
+#include "mpeg_er.h"
+#include "mpeg12.h"
+#include "mpeg12data.h"
+#include "mpegutils.h"
+#include "mpegvideo.h"
+#include "mpegvideodata.h"
+#include "thread.h"
+#include "version.h"
+#include "vdpau_compat.h"
+#include "xvmc_internal.h"
+
+typedef struct Mpeg1Context {
+ MpegEncContext mpeg_enc_ctx;
+ int mpeg_enc_ctx_allocated; /* true if decoding context allocated */
+ int repeat_field; /* true if we must repeat the field */
+ AVPanScan pan_scan; /* some temporary storage for the panscan */
+ AVStereo3D stereo3d;
+ int has_stereo3d;
+ uint8_t *a53_caption;
+ int a53_caption_size;
+ uint8_t afd;
+ int has_afd;
+ int slice_count;
+ AVRational save_aspect;
+ int save_width, save_height, save_progressive_seq;
+ AVRational frame_rate_ext; /* MPEG-2 specific framerate modificator */
+ int sync; /* Did we reach a sync point like a GOP/SEQ/KEYFrame? */
+ int tmpgexs;
+ int first_slice;
+ int extradata_decoded;
+} Mpeg1Context;
+
+#define MB_TYPE_ZERO_MV 0x20000000
+
+static const uint32_t ptype2mb_type[7] = {
+ MB_TYPE_INTRA,
+ MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
+ MB_TYPE_L0,
+ MB_TYPE_L0 | MB_TYPE_CBP,
+ MB_TYPE_QUANT | MB_TYPE_INTRA,
+ MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP | MB_TYPE_ZERO_MV | MB_TYPE_16x16,
+ MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP,
+};
+
+static const uint32_t btype2mb_type[11] = {
+ MB_TYPE_INTRA,
+ MB_TYPE_L1,
+ MB_TYPE_L1 | MB_TYPE_CBP,
+ MB_TYPE_L0,
+ MB_TYPE_L0 | MB_TYPE_CBP,
+ MB_TYPE_L0L1,
+ MB_TYPE_L0L1 | MB_TYPE_CBP,
+ MB_TYPE_QUANT | MB_TYPE_INTRA,
+ MB_TYPE_QUANT | MB_TYPE_L1 | MB_TYPE_CBP,
+ MB_TYPE_QUANT | MB_TYPE_L0 | MB_TYPE_CBP,
+ MB_TYPE_QUANT | MB_TYPE_L0L1 | MB_TYPE_CBP,
+};
+
+static const uint8_t non_linear_qscale[32] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 10, 12, 14, 16, 18, 20, 22,
+ 24, 28, 32, 36, 40, 44, 48, 52,
+ 56, 64, 72, 80, 88, 96, 104, 112,
+};
+
+/* as H.263, but only 17 codes */
+static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred)
+{
+ int code, sign, val, shift;
+
+ code = get_vlc2(&s->gb, ff_mv_vlc.table, MV_VLC_BITS, 2);
+ if (code == 0)
+ return pred;
+ if (code < 0)
+ return 0xffff;
+
+ sign = get_bits1(&s->gb);
+ shift = fcode - 1;
+ val = code;
+ if (shift) {
+ val = (val - 1) << shift;
+ val |= get_bits(&s->gb, shift);
+ val++;
+ }
+ if (sign)
+ val = -val;
+ val += pred;
+
+ /* modulo decoding */
+ return sign_extend(val, 5 + shift);
+}
+
+#define check_scantable_index(ctx, x) \
+ do { \
+ if ((x) > 63) { \
+ av_log(ctx->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", \
+ ctx->mb_x, ctx->mb_y); \
+ return AVERROR_INVALIDDATA; \
+ } \
+ } while (0)
+
+static inline int mpeg1_decode_block_intra(MpegEncContext *s,
+ int16_t *block, int n)
+{
+ int level, dc, diff, i, j, run;
+ int component;
+ RLTable *rl = &ff_rl_mpeg1;
+ uint8_t *const scantable = s->intra_scantable.permutated;
+ const uint16_t *quant_matrix = s->intra_matrix;
+ const int qscale = s->qscale;
+
+ /* DC coefficient */
+ component = (n <= 3 ? 0 : n - 4 + 1);
+ diff = decode_dc(&s->gb, component);
+ if (diff >= 0xffff)
+ return AVERROR_INVALIDDATA;
+ dc = s->last_dc[component];
+ dc += diff;
+ s->last_dc[component] = dc;
+ block[0] = dc * quant_matrix[0];
+ ff_tlog(s->avctx, "dc=%d diff=%d\n", dc, diff);
+ i = 0;
+ {
+ OPEN_READER(re, &s->gb);
+ UPDATE_CACHE(re, &s->gb);
+ if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+ goto end;
+
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0],
+ TEX_VLC_BITS, 2, 0);
+
+ if (level != 0) {
+ i += run;
+ check_scantable_index(s, i);
+ j = scantable[i];
+ level = (level * qscale * quant_matrix[j]) >> 4;
+ level = (level - 1) | 1;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
+ SHOW_SBITS(re, &s->gb, 1);
+ SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6) + 1;
+ LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 8);
+ SKIP_BITS(re, &s->gb, 8);
+ if (level == -128) {
+ level = SHOW_UBITS(re, &s->gb, 8) - 256;
+ SKIP_BITS(re, &s->gb, 8);
+ } else if (level == 0) {
+ level = SHOW_UBITS(re, &s->gb, 8);
+ SKIP_BITS(re, &s->gb, 8);
+ }
+ i += run;
+ check_scantable_index(s, i);
+ j = scantable[i];
+ if (level < 0) {
+ level = -level;
+ level = (level * qscale * quant_matrix[j]) >> 4;
+ level = (level - 1) | 1;
+ level = -level;
+ } else {
+ level = (level * qscale * quant_matrix[j]) >> 4;
+ level = (level - 1) | 1;
+ }
+ }
+
+ block[j] = level;
+ if (((int32_t)GET_CACHE(re, &s->gb)) <= (int32_t)0xBFFFFFFF)
+ break;
+
+ UPDATE_CACHE(re, &s->gb);
+ }
+end:
+ LAST_SKIP_BITS(re, &s->gb, 2);
+ CLOSE_READER(re, &s->gb);
+ }
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+int ff_mpeg1_decode_block_intra(MpegEncContext *s, int16_t *block, int n)
+{
+ return mpeg1_decode_block_intra(s, block, n);
+}
+
+static inline int mpeg1_decode_block_inter(MpegEncContext *s,
+ int16_t *block, int n)
+{
+ int level, i, j, run;
+ RLTable *rl = &ff_rl_mpeg1;
+ uint8_t *const scantable = s->intra_scantable.permutated;
+ const uint16_t *quant_matrix = s->inter_matrix;
+ const int qscale = s->qscale;
+
+ {
+ OPEN_READER(re, &s->gb);
+ i = -1;
+ // special case for first coefficient, no need to add second VLC table
+ UPDATE_CACHE(re, &s->gb);
+ if (((int32_t) GET_CACHE(re, &s->gb)) < 0) {
+ level = (3 * qscale * quant_matrix[0]) >> 5;
+ level = (level - 1) | 1;
+ if (GET_CACHE(re, &s->gb) & 0x40000000)
+ level = -level;
+ block[0] = level;
+ i++;
+ SKIP_BITS(re, &s->gb, 2);
+ if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF)
+ goto end;
+ }
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0],
+ TEX_VLC_BITS, 2, 0);
+
+ if (level != 0) {
+ i += run;
+ check_scantable_index(s, i);
+ j = scantable[i];
+ level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+ level = (level - 1) | 1;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
+ SHOW_SBITS(re, &s->gb, 1);
+ SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6) + 1;
+ LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 8);
+ SKIP_BITS(re, &s->gb, 8);
+ if (level == -128) {
+ level = SHOW_UBITS(re, &s->gb, 8) - 256;
+ SKIP_BITS(re, &s->gb, 8);
+ } else if (level == 0) {
+ level = SHOW_UBITS(re, &s->gb, 8);
+ SKIP_BITS(re, &s->gb, 8);
+ }
+ i += run;
+ check_scantable_index(s, i);
+ j = scantable[i];
+ if (level < 0) {
+ level = -level;
+ level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+ level = (level - 1) | 1;
+ level = -level;
+ } else {
+ level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+ level = (level - 1) | 1;
+ }
+ }
+
+ block[j] = level;
+ if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF)
+ break;
+ UPDATE_CACHE(re, &s->gb);
+ }
+end:
+ LAST_SKIP_BITS(re, &s->gb, 2);
+ CLOSE_READER(re, &s->gb);
+ }
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+/**
+ * Note: this function can read out of range and crash for corrupt streams.
+ * Changing this would eat up any speed benefits it has.
+ * Do not use "fast" flag if you need the code to be robust.
+ */
+static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s,
+ int16_t *block, int n)
+{
+ int level, i, j, run;
+ RLTable *rl = &ff_rl_mpeg1;
+ uint8_t *const scantable = s->intra_scantable.permutated;
+ const int qscale = s->qscale;
+
+ {
+ OPEN_READER(re, &s->gb);
+ i = -1;
+ // Special case for first coefficient, no need to add second VLC table.
+ UPDATE_CACHE(re, &s->gb);
+ if (((int32_t) GET_CACHE(re, &s->gb)) < 0) {
+ level = (3 * qscale) >> 1;
+ level = (level - 1) | 1;
+ if (GET_CACHE(re, &s->gb) & 0x40000000)
+ level = -level;
+ block[0] = level;
+ i++;
+ SKIP_BITS(re, &s->gb, 2);
+ if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF)
+ goto end;
+ }
+
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0],
+ TEX_VLC_BITS, 2, 0);
+
+ if (level != 0) {
+ i += run;
+ check_scantable_index(s, i);
+ j = scantable[i];
+ level = ((level * 2 + 1) * qscale) >> 1;
+ level = (level - 1) | 1;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
+ SHOW_SBITS(re, &s->gb, 1);
+ SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6) + 1;
+ LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 8);
+ SKIP_BITS(re, &s->gb, 8);
+ if (level == -128) {
+ level = SHOW_UBITS(re, &s->gb, 8) - 256;
+ SKIP_BITS(re, &s->gb, 8);
+ } else if (level == 0) {
+ level = SHOW_UBITS(re, &s->gb, 8);
+ SKIP_BITS(re, &s->gb, 8);
+ }
+ i += run;
+ check_scantable_index(s, i);
+ j = scantable[i];
+ if (level < 0) {
+ level = -level;
+ level = ((level * 2 + 1) * qscale) >> 1;
+ level = (level - 1) | 1;
+ level = -level;
+ } else {
+ level = ((level * 2 + 1) * qscale) >> 1;
+ level = (level - 1) | 1;
+ }
+ }
+
+ block[j] = level;
+ if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF)
+ break;
+ UPDATE_CACHE(re, &s->gb);
+ }
+end:
+ LAST_SKIP_BITS(re, &s->gb, 2);
+ CLOSE_READER(re, &s->gb);
+ }
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+static inline int mpeg2_decode_block_non_intra(MpegEncContext *s,
+ int16_t *block, int n)
+{
+ int level, i, j, run;
+ RLTable *rl = &ff_rl_mpeg1;
+ uint8_t *const scantable = s->intra_scantable.permutated;
+ const uint16_t *quant_matrix;
+ const int qscale = s->qscale;
+ int mismatch;
+
+ mismatch = 1;
+
+ {
+ OPEN_READER(re, &s->gb);
+ i = -1;
+ if (n < 4)
+ quant_matrix = s->inter_matrix;
+ else
+ quant_matrix = s->chroma_inter_matrix;
+
+ // Special case for first coefficient, no need to add second VLC table.
+ UPDATE_CACHE(re, &s->gb);
+ if (((int32_t) GET_CACHE(re, &s->gb)) < 0) {
+ level = (3 * qscale * quant_matrix[0]) >> 5;
+ if (GET_CACHE(re, &s->gb) & 0x40000000)
+ level = -level;
+ block[0] = level;
+ mismatch ^= level;
+ i++;
+ SKIP_BITS(re, &s->gb, 2);
+ if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF)
+ goto end;
+ }
+
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0],
+ TEX_VLC_BITS, 2, 0);
+
+ if (level != 0) {
+ i += run;
+ check_scantable_index(s, i);
+ j = scantable[i];
+ level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
+ SHOW_SBITS(re, &s->gb, 1);
+ SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6) + 1;
+ LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 12);
+ SKIP_BITS(re, &s->gb, 12);
+
+ i += run;
+ check_scantable_index(s, i);
+ j = scantable[i];
+ if (level < 0) {
+ level = ((-level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+ level = -level;
+ } else {
+ level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5;
+ }
+ }
+
+ mismatch ^= level;
+ block[j] = level;
+ if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF)
+ break;
+ UPDATE_CACHE(re, &s->gb);
+ }
+end:
+ LAST_SKIP_BITS(re, &s->gb, 2);
+ CLOSE_READER(re, &s->gb);
+ }
+ block[63] ^= (mismatch & 1);
+
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+/**
+ * Note: this function can read out of range and crash for corrupt streams.
+ * Changing this would eat up any speed benefits it has.
+ * Do not use "fast" flag if you need the code to be robust.
+ */
+static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s,
+ int16_t *block, int n)
+{
+ int level, i, j, run;
+ RLTable *rl = &ff_rl_mpeg1;
+ uint8_t *const scantable = s->intra_scantable.permutated;
+ const int qscale = s->qscale;
+ OPEN_READER(re, &s->gb);
+ i = -1;
+
+ // special case for first coefficient, no need to add second VLC table
+ UPDATE_CACHE(re, &s->gb);
+ if (((int32_t) GET_CACHE(re, &s->gb)) < 0) {
+ level = (3 * qscale) >> 1;
+ if (GET_CACHE(re, &s->gb) & 0x40000000)
+ level = -level;
+ block[0] = level;
+ i++;
+ SKIP_BITS(re, &s->gb, 2);
+ if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF)
+ goto end;
+ }
+
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
+
+ if (level != 0) {
+ i += run;
+ j = scantable[i];
+ level = ((level * 2 + 1) * qscale) >> 1;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
+ SHOW_SBITS(re, &s->gb, 1);
+ SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6) + 1;
+ LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 12);
+ SKIP_BITS(re, &s->gb, 12);
+
+ i += run;
+ j = scantable[i];
+ if (level < 0) {
+ level = ((-level * 2 + 1) * qscale) >> 1;
+ level = -level;
+ } else {
+ level = ((level * 2 + 1) * qscale) >> 1;
+ }
+ }
+
+ block[j] = level;
+ if (((int32_t) GET_CACHE(re, &s->gb)) <= (int32_t) 0xBFFFFFFF || i > 63)
+ break;
+
+ UPDATE_CACHE(re, &s->gb);
+ }
+end:
+ LAST_SKIP_BITS(re, &s->gb, 2);
+ CLOSE_READER(re, &s->gb);
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+static inline int mpeg2_decode_block_intra(MpegEncContext *s,
+ int16_t *block, int n)
+{
+ int level, dc, diff, i, j, run;
+ int component;
+ RLTable *rl;
+ uint8_t *const scantable = s->intra_scantable.permutated;
+ const uint16_t *quant_matrix;
+ const int qscale = s->qscale;
+ int mismatch;
+
+ /* DC coefficient */
+ if (n < 4) {
+ quant_matrix = s->intra_matrix;
+ component = 0;
+ } else {
+ quant_matrix = s->chroma_intra_matrix;
+ component = (n & 1) + 1;
+ }
+ diff = decode_dc(&s->gb, component);
+ if (diff >= 0xffff)
+ return AVERROR_INVALIDDATA;
+ dc = s->last_dc[component];
+ dc += diff;
+ s->last_dc[component] = dc;
+ block[0] = dc * (1 << (3 - s->intra_dc_precision));
+ ff_tlog(s->avctx, "dc=%d\n", block[0]);
+ mismatch = block[0] ^ 1;
+ i = 0;
+ if (s->intra_vlc_format)
+ rl = &ff_rl_mpeg2;
+ else
+ rl = &ff_rl_mpeg1;
+
+ {
+ OPEN_READER(re, &s->gb);
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0],
+ TEX_VLC_BITS, 2, 0);
+
+ if (level == 127) {
+ break;
+ } else if (level != 0) {
+ i += run;
+ check_scantable_index(s, i);
+ j = scantable[i];
+ level = (level * qscale * quant_matrix[j]) >> 4;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
+ SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6) + 1;
+ LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 12);
+ SKIP_BITS(re, &s->gb, 12);
+ i += run;
+ check_scantable_index(s, i);
+ j = scantable[i];
+ if (level < 0) {
+ level = (-level * qscale * quant_matrix[j]) >> 4;
+ level = -level;
+ } else {
+ level = (level * qscale * quant_matrix[j]) >> 4;
+ }
+ }
+
+ mismatch ^= level;
+ block[j] = level;
+ }
+ CLOSE_READER(re, &s->gb);
+ }
+ block[63] ^= mismatch & 1;
+
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+/**
+ * Note: this function can read out of range and crash for corrupt streams.
+ * Changing this would eat up any speed benefits it has.
+ * Do not use "fast" flag if you need the code to be robust.
+ */
+static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s,
+ int16_t *block, int n)
+{
+ int level, dc, diff, i, j, run;
+ int component;
+ RLTable *rl;
+ uint8_t *const scantable = s->intra_scantable.permutated;
+ const uint16_t *quant_matrix;
+ const int qscale = s->qscale;
+
+ /* DC coefficient */
+ if (n < 4) {
+ quant_matrix = s->intra_matrix;
+ component = 0;
+ } else {
+ quant_matrix = s->chroma_intra_matrix;
+ component = (n & 1) + 1;
+ }
+ diff = decode_dc(&s->gb, component);
+ if (diff >= 0xffff)
+ return AVERROR_INVALIDDATA;
+ dc = s->last_dc[component];
+ dc += diff;
+ s->last_dc[component] = dc;
+ block[0] = dc << (3 - s->intra_dc_precision);
+ i = 0;
+ if (s->intra_vlc_format)
+ rl = &ff_rl_mpeg2;
+ else
+ rl = &ff_rl_mpeg1;
+
+ {
+ OPEN_READER(re, &s->gb);
+ /* now quantify & encode AC coefficients */
+ for (;;) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_RL_VLC(level, run, re, &s->gb, rl->rl_vlc[0],
+ TEX_VLC_BITS, 2, 0);
+
+ if (level >= 64 || i > 63) {
+ break;
+ } else if (level != 0) {
+ i += run;
+ j = scantable[i];
+ level = (level * qscale * quant_matrix[j]) >> 4;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) -
+ SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ } else {
+ /* escape */
+ run = SHOW_UBITS(re, &s->gb, 6) + 1;
+ LAST_SKIP_BITS(re, &s->gb, 6);
+ UPDATE_CACHE(re, &s->gb);
+ level = SHOW_SBITS(re, &s->gb, 12);
+ SKIP_BITS(re, &s->gb, 12);
+ i += run;
+ j = scantable[i];
+ if (level < 0) {
+ level = (-level * qscale * quant_matrix[j]) >> 4;
+ level = -level;
+ } else {
+ level = (level * qscale * quant_matrix[j]) >> 4;
+ }
+ }
+
+ block[j] = level;
+ }
+ CLOSE_READER(re, &s->gb);
+ }
+
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+/******************************************/
+/* decoding */
+
+static inline int get_dmv(MpegEncContext *s)
+{
+ if (get_bits1(&s->gb))
+ return 1 - (get_bits1(&s->gb) << 1);
+ else
+ return 0;
+}
+
+static inline int get_qscale(MpegEncContext *s)
+{
+ int qscale = get_bits(&s->gb, 5);
+ if (s->q_scale_type)
+ return non_linear_qscale[qscale];
+ else
+ return qscale << 1;
+}
+
+
+/* motion type (for MPEG-2) */
+#define MT_FIELD 1
+#define MT_FRAME 2
+#define MT_16X8 2
+#define MT_DMV 3
+
+static int mpeg_decode_mb(MpegEncContext *s, int16_t block[12][64])
+{
+ int i, j, k, cbp, val, mb_type, motion_type;
+ const int mb_block_count = 4 + (1 << s->chroma_format);
+ int ret;
+
+ ff_tlog(s->avctx, "decode_mb: x=%d y=%d\n", s->mb_x, s->mb_y);
+
+ av_assert2(s->mb_skipped == 0);
+
+ if (s->mb_skip_run-- != 0) {
+ if (s->pict_type == AV_PICTURE_TYPE_P) {
+ s->mb_skipped = 1;
+ s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] =
+ MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
+ } else {
+ int mb_type;
+
+ if (s->mb_x)
+ mb_type = s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride - 1];
+ else
+ // FIXME not sure if this is allowed in MPEG at all
+ mb_type = s->current_picture.mb_type[s->mb_width + (s->mb_y - 1) * s->mb_stride - 1];
+ if (IS_INTRA(mb_type)) {
+ av_log(s->avctx, AV_LOG_ERROR, "skip with previntra\n");
+ return AVERROR_INVALIDDATA;
+ }
+ s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] =
+ mb_type | MB_TYPE_SKIP;
+
+ if ((s->mv[0][0][0] | s->mv[0][0][1] | s->mv[1][0][0] | s->mv[1][0][1]) == 0)
+ s->mb_skipped = 1;
+ }
+
+ return 0;
+ }
+
+ switch (s->pict_type) {
+ default:
+ case AV_PICTURE_TYPE_I:
+ if (get_bits1(&s->gb) == 0) {
+ if (get_bits1(&s->gb) == 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "invalid mb type in I Frame at %d %d\n",
+ s->mb_x, s->mb_y);
+ return AVERROR_INVALIDDATA;
+ }
+ mb_type = MB_TYPE_QUANT | MB_TYPE_INTRA;
+ } else {
+ mb_type = MB_TYPE_INTRA;
+ }
+ break;
+ case AV_PICTURE_TYPE_P:
+ mb_type = get_vlc2(&s->gb, ff_mb_ptype_vlc.table, MB_PTYPE_VLC_BITS, 1);
+ if (mb_type < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "invalid mb type in P Frame at %d %d\n", s->mb_x, s->mb_y);
+ return AVERROR_INVALIDDATA;
+ }
+ mb_type = ptype2mb_type[mb_type];
+ break;
+ case AV_PICTURE_TYPE_B:
+ mb_type = get_vlc2(&s->gb, ff_mb_btype_vlc.table, MB_BTYPE_VLC_BITS, 1);
+ if (mb_type < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "invalid mb type in B Frame at %d %d\n", s->mb_x, s->mb_y);
+ return AVERROR_INVALIDDATA;
+ }
+ mb_type = btype2mb_type[mb_type];
+ break;
+ }
+ ff_tlog(s->avctx, "mb_type=%x\n", mb_type);
+// motion_type = 0; /* avoid warning */
+ if (IS_INTRA(mb_type)) {
+ s->bdsp.clear_blocks(s->block[0]);
+
+ if (!s->chroma_y_shift)
+ s->bdsp.clear_blocks(s->block[6]);
+
+ /* compute DCT type */
+ // FIXME: add an interlaced_dct coded var?
+ if (s->picture_structure == PICT_FRAME &&
+ !s->frame_pred_frame_dct)
+ s->interlaced_dct = get_bits1(&s->gb);
+
+ if (IS_QUANT(mb_type))
+ s->qscale = get_qscale(s);
+
+ if (s->concealment_motion_vectors) {
+ /* just parse them */
+ if (s->picture_structure != PICT_FRAME)
+ skip_bits1(&s->gb); /* field select */
+
+ s->mv[0][0][0] =
+ s->last_mv[0][0][0] =
+ s->last_mv[0][1][0] = mpeg_decode_motion(s, s->mpeg_f_code[0][0],
+ s->last_mv[0][0][0]);
+ s->mv[0][0][1] =
+ s->last_mv[0][0][1] =
+ s->last_mv[0][1][1] = mpeg_decode_motion(s, s->mpeg_f_code[0][1],
+ s->last_mv[0][0][1]);
+
+ check_marker(&s->gb, "after concealment_motion_vectors");
+ } else {
+ /* reset mv prediction */
+ memset(s->last_mv, 0, sizeof(s->last_mv));
+ }
+ s->mb_intra = 1;
+ // if 1, we memcpy blocks in xvmcvideo
+ if ((CONFIG_MPEG1_XVMC_HWACCEL || CONFIG_MPEG2_XVMC_HWACCEL) && s->pack_pblocks)
+ ff_xvmc_pack_pblocks(s, -1); // inter are always full blocks
+
+ if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+ if (s->avctx->flags2 & AV_CODEC_FLAG2_FAST) {
+ for (i = 0; i < 6; i++)
+ mpeg2_fast_decode_block_intra(s, *s->pblocks[i], i);
+ } else {
+ for (i = 0; i < mb_block_count; i++)
+ if ((ret = mpeg2_decode_block_intra(s, *s->pblocks[i], i)) < 0)
+ return ret;
+ }
+ } else {
+ for (i = 0; i < 6; i++)
+ if ((ret = mpeg1_decode_block_intra(s, *s->pblocks[i], i)) < 0)
+ return ret;
+ }
+ } else {
+ if (mb_type & MB_TYPE_ZERO_MV) {
+ av_assert2(mb_type & MB_TYPE_CBP);
+
+ s->mv_dir = MV_DIR_FORWARD;
+ if (s->picture_structure == PICT_FRAME) {
+ if (s->picture_structure == PICT_FRAME
+ && !s->frame_pred_frame_dct)
+ s->interlaced_dct = get_bits1(&s->gb);
+ s->mv_type = MV_TYPE_16X16;
+ } else {
+ s->mv_type = MV_TYPE_FIELD;
+ mb_type |= MB_TYPE_INTERLACED;
+ s->field_select[0][0] = s->picture_structure - 1;
+ }
+
+ if (IS_QUANT(mb_type))
+ s->qscale = get_qscale(s);
+
+ s->last_mv[0][0][0] = 0;
+ s->last_mv[0][0][1] = 0;
+ s->last_mv[0][1][0] = 0;
+ s->last_mv[0][1][1] = 0;
+ s->mv[0][0][0] = 0;
+ s->mv[0][0][1] = 0;
+ } else {
+ av_assert2(mb_type & MB_TYPE_L0L1);
+ // FIXME decide if MBs in field pictures are MB_TYPE_INTERLACED
+ /* get additional motion vector type */
+ if (s->picture_structure == PICT_FRAME && s->frame_pred_frame_dct) {
+ motion_type = MT_FRAME;
+ } else {
+ motion_type = get_bits(&s->gb, 2);
+ if (s->picture_structure == PICT_FRAME && HAS_CBP(mb_type))
+ s->interlaced_dct = get_bits1(&s->gb);
+ }
+
+ if (IS_QUANT(mb_type))
+ s->qscale = get_qscale(s);
+
+ /* motion vectors */
+ s->mv_dir = (mb_type >> 13) & 3;
+ ff_tlog(s->avctx, "motion_type=%d\n", motion_type);
+ switch (motion_type) {
+ case MT_FRAME: /* or MT_16X8 */
+ if (s->picture_structure == PICT_FRAME) {
+ mb_type |= MB_TYPE_16x16;
+ s->mv_type = MV_TYPE_16X16;
+ for (i = 0; i < 2; i++) {
+ if (USES_LIST(mb_type, i)) {
+ /* MT_FRAME */
+ s->mv[i][0][0] =
+ s->last_mv[i][0][0] =
+ s->last_mv[i][1][0] =
+ mpeg_decode_motion(s, s->mpeg_f_code[i][0],
+ s->last_mv[i][0][0]);
+ s->mv[i][0][1] =
+ s->last_mv[i][0][1] =
+ s->last_mv[i][1][1] =
+ mpeg_decode_motion(s, s->mpeg_f_code[i][1],
+ s->last_mv[i][0][1]);
+ /* full_pel: only for MPEG-1 */
+ if (s->full_pel[i]) {
+ s->mv[i][0][0] *= 2;
+ s->mv[i][0][1] *= 2;
+ }
+ }
+ }
+ } else {
+ mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
+ s->mv_type = MV_TYPE_16X8;
+ for (i = 0; i < 2; i++) {
+ if (USES_LIST(mb_type, i)) {
+ /* MT_16X8 */
+ for (j = 0; j < 2; j++) {
+ s->field_select[i][j] = get_bits1(&s->gb);
+ for (k = 0; k < 2; k++) {
+ val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
+ s->last_mv[i][j][k]);
+ s->last_mv[i][j][k] = val;
+ s->mv[i][j][k] = val;
+ }
+ }
+ }
+ }
+ }
+ break;
+ case MT_FIELD:
+ s->mv_type = MV_TYPE_FIELD;
+ if (s->picture_structure == PICT_FRAME) {
+ mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
+ for (i = 0; i < 2; i++) {
+ if (USES_LIST(mb_type, i)) {
+ for (j = 0; j < 2; j++) {
+ s->field_select[i][j] = get_bits1(&s->gb);
+ val = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
+ s->last_mv[i][j][0]);
+ s->last_mv[i][j][0] = val;
+ s->mv[i][j][0] = val;
+ ff_tlog(s->avctx, "fmx=%d\n", val);
+ val = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
+ s->last_mv[i][j][1] >> 1);
+ s->last_mv[i][j][1] = 2 * val;
+ s->mv[i][j][1] = val;
+ ff_tlog(s->avctx, "fmy=%d\n", val);
+ }
+ }
+ }
+ } else {
+ av_assert0(!s->progressive_sequence);
+ mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
+ for (i = 0; i < 2; i++) {
+ if (USES_LIST(mb_type, i)) {
+ s->field_select[i][0] = get_bits1(&s->gb);
+ for (k = 0; k < 2; k++) {
+ val = mpeg_decode_motion(s, s->mpeg_f_code[i][k],
+ s->last_mv[i][0][k]);
+ s->last_mv[i][0][k] = val;
+ s->last_mv[i][1][k] = val;
+ s->mv[i][0][k] = val;
+ }
+ }
+ }
+ }
+ break;
+ case MT_DMV:
+ if (s->progressive_sequence){
+ av_log(s->avctx, AV_LOG_ERROR, "MT_DMV in progressive_sequence\n");
+ return AVERROR_INVALIDDATA;
+ }
+ s->mv_type = MV_TYPE_DMV;
+ for (i = 0; i < 2; i++) {
+ if (USES_LIST(mb_type, i)) {
+ int dmx, dmy, mx, my, m;
+ const int my_shift = s->picture_structure == PICT_FRAME;
+
+ mx = mpeg_decode_motion(s, s->mpeg_f_code[i][0],
+ s->last_mv[i][0][0]);
+ s->last_mv[i][0][0] = mx;
+ s->last_mv[i][1][0] = mx;
+ dmx = get_dmv(s);
+ my = mpeg_decode_motion(s, s->mpeg_f_code[i][1],
+ s->last_mv[i][0][1] >> my_shift);
+ dmy = get_dmv(s);
+
+
+ s->last_mv[i][0][1] = my * (1 << my_shift);
+ s->last_mv[i][1][1] = my * (1 << my_shift);
+
+ s->mv[i][0][0] = mx;
+ s->mv[i][0][1] = my;
+ s->mv[i][1][0] = mx; // not used
+ s->mv[i][1][1] = my; // not used
+
+ if (s->picture_structure == PICT_FRAME) {
+ mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
+
+ // m = 1 + 2 * s->top_field_first;
+ m = s->top_field_first ? 1 : 3;
+
+ /* top -> top pred */
+ s->mv[i][2][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
+ s->mv[i][2][1] = ((my * m + (my > 0)) >> 1) + dmy - 1;
+ m = 4 - m;
+ s->mv[i][3][0] = ((mx * m + (mx > 0)) >> 1) + dmx;
+ s->mv[i][3][1] = ((my * m + (my > 0)) >> 1) + dmy + 1;
+ } else {
+ mb_type |= MB_TYPE_16x16;
+
+ s->mv[i][2][0] = ((mx + (mx > 0)) >> 1) + dmx;
+ s->mv[i][2][1] = ((my + (my > 0)) >> 1) + dmy;
+ if (s->picture_structure == PICT_TOP_FIELD)
+ s->mv[i][2][1]--;
+ else
+ s->mv[i][2][1]++;
+ }
+ }
+ }
+ break;
+ default:
+ av_log(s->avctx, AV_LOG_ERROR,
+ "00 motion_type at %d %d\n", s->mb_x, s->mb_y);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ s->mb_intra = 0;
+ if (HAS_CBP(mb_type)) {
+ s->bdsp.clear_blocks(s->block[0]);
+
+ cbp = get_vlc2(&s->gb, ff_mb_pat_vlc.table, MB_PAT_VLC_BITS, 1);
+ if (mb_block_count > 6) {
+ cbp *= 1 << mb_block_count - 6;
+ cbp |= get_bits(&s->gb, mb_block_count - 6);
+ s->bdsp.clear_blocks(s->block[6]);
+ }
+ if (cbp <= 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "invalid cbp %d at %d %d\n", cbp, s->mb_x, s->mb_y);
+ return AVERROR_INVALIDDATA;
+ }
+
+ // if 1, we memcpy blocks in xvmcvideo
+ if ((CONFIG_MPEG1_XVMC_HWACCEL || CONFIG_MPEG2_XVMC_HWACCEL) && s->pack_pblocks)
+ ff_xvmc_pack_pblocks(s, cbp);
+
+ if (s->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+ if (s->avctx->flags2 & AV_CODEC_FLAG2_FAST) {
+ for (i = 0; i < 6; i++) {
+ if (cbp & 32)
+ mpeg2_fast_decode_block_non_intra(s, *s->pblocks[i], i);
+ else
+ s->block_last_index[i] = -1;
+ cbp += cbp;
+ }
+ } else {
+ cbp <<= 12 - mb_block_count;
+
+ for (i = 0; i < mb_block_count; i++) {
+ if (cbp & (1 << 11)) {
+ if ((ret = mpeg2_decode_block_non_intra(s, *s->pblocks[i], i)) < 0)
+ return ret;
+ } else {
+ s->block_last_index[i] = -1;
+ }
+ cbp += cbp;
+ }
+ }
+ } else {
+ if (s->avctx->flags2 & AV_CODEC_FLAG2_FAST) {
+ for (i = 0; i < 6; i++) {
+ if (cbp & 32)
+ mpeg1_fast_decode_block_inter(s, *s->pblocks[i], i);
+ else
+ s->block_last_index[i] = -1;
+ cbp += cbp;
+ }
+ } else {
+ for (i = 0; i < 6; i++) {
+ if (cbp & 32) {
+ if ((ret = mpeg1_decode_block_inter(s, *s->pblocks[i], i)) < 0)
+ return ret;
+ } else {
+ s->block_last_index[i] = -1;
+ }
+ cbp += cbp;
+ }
+ }
+ }
+ } else {
+ for (i = 0; i < 12; i++)
+ s->block_last_index[i] = -1;
+ }
+ }
+
+ s->current_picture.mb_type[s->mb_x + s->mb_y * s->mb_stride] = mb_type;
+
+ return 0;
+}
+
+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);
+ ff_mpeg12_common_init(&s->mpeg_enc_ctx);
+ ff_mpeg12_init_vlcs();
+
+ s->mpeg_enc_ctx_allocated = 0;
+ s->mpeg_enc_ctx.picture_number = 0;
+ s->repeat_field = 0;
+ s->mpeg_enc_ctx.codec_id = avctx->codec->id;
+ avctx->color_range = AVCOL_RANGE_MPEG;
+ return 0;
+}
+
+static int mpeg_decode_update_thread_context(AVCodecContext *avctx,
+ const AVCodecContext *avctx_from)
+{
+ Mpeg1Context *ctx = avctx->priv_data, *ctx_from = avctx_from->priv_data;
+ MpegEncContext *s = &ctx->mpeg_enc_ctx, *s1 = &ctx_from->mpeg_enc_ctx;
+ int err;
+
+ if (avctx == avctx_from ||
+ !ctx_from->mpeg_enc_ctx_allocated ||
+ !s1->context_initialized)
+ return 0;
+
+ err = ff_mpeg_update_thread_context(avctx, avctx_from);
+ if (err)
+ return err;
+
+ if (!ctx->mpeg_enc_ctx_allocated)
+ memcpy(s + 1, s1 + 1, sizeof(Mpeg1Context) - sizeof(MpegEncContext));
+
+ if (!(s->pict_type == AV_PICTURE_TYPE_B || s->low_delay))
+ s->picture_number++;
+
+ return 0;
+}
+
+static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm,
+ const uint8_t *new_perm)
+{
+ uint16_t temp_matrix[64];
+ int i;
+
+ memcpy(temp_matrix, matrix, 64 * sizeof(uint16_t));
+
+ for (i = 0; i < 64; i++)
+ matrix[new_perm[i]] = temp_matrix[old_perm[i]];
+}
+
+static const enum AVPixelFormat mpeg1_hwaccel_pixfmt_list_420[] = {
+#if CONFIG_MPEG1_XVMC_HWACCEL
+ AV_PIX_FMT_XVMC,
+#endif
+#if CONFIG_MPEG1_VDPAU_DECODER && FF_API_VDPAU
+ AV_PIX_FMT_VDPAU_MPEG1,
+#endif
+#if CONFIG_MPEG1_VDPAU_HWACCEL
+ AV_PIX_FMT_VDPAU,
+#endif
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_NONE
+};
+
+static const enum AVPixelFormat mpeg2_hwaccel_pixfmt_list_420[] = {
+#if CONFIG_MPEG2_XVMC_HWACCEL
+ AV_PIX_FMT_XVMC,
+#endif
+#if CONFIG_MPEG_VDPAU_DECODER && FF_API_VDPAU
+ AV_PIX_FMT_VDPAU_MPEG2,
+#endif
+#if CONFIG_MPEG2_VDPAU_HWACCEL
+ AV_PIX_FMT_VDPAU,
+#endif
+#if CONFIG_MPEG2_DXVA2_HWACCEL
+ AV_PIX_FMT_DXVA2_VLD,
+#endif
+#if CONFIG_MPEG2_D3D11VA_HWACCEL
+ AV_PIX_FMT_D3D11VA_VLD,
+#endif
+#if CONFIG_MPEG2_VAAPI_HWACCEL
+ AV_PIX_FMT_VAAPI,
+#endif
+#if CONFIG_MPEG2_VIDEOTOOLBOX_HWACCEL
+ AV_PIX_FMT_VIDEOTOOLBOX,
+#endif
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_NONE
+};
+
+static const enum AVPixelFormat mpeg12_pixfmt_list_422[] = {
+ AV_PIX_FMT_YUV422P,
+ AV_PIX_FMT_NONE
+};
+
+static const enum AVPixelFormat mpeg12_pixfmt_list_444[] = {
+ AV_PIX_FMT_YUV444P,
+ AV_PIX_FMT_NONE
+};
+
+#if FF_API_VDPAU
+static inline int uses_vdpau(AVCodecContext *avctx) {
+ return avctx->pix_fmt == AV_PIX_FMT_VDPAU_MPEG1 || avctx->pix_fmt == AV_PIX_FMT_VDPAU_MPEG2;
+}
+#endif
+
+static enum AVPixelFormat mpeg_get_pixelformat(AVCodecContext *avctx)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+ const enum AVPixelFormat *pix_fmts;
+
+ if (CONFIG_GRAY && (avctx->flags & AV_CODEC_FLAG_GRAY))
+ return AV_PIX_FMT_GRAY8;
+
+ if (s->chroma_format < 2)
+ pix_fmts = avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO ?
+ mpeg1_hwaccel_pixfmt_list_420 :
+ mpeg2_hwaccel_pixfmt_list_420;
+ else if (s->chroma_format == 2)
+ pix_fmts = mpeg12_pixfmt_list_422;
+ else
+ pix_fmts = mpeg12_pixfmt_list_444;
+
+ return ff_thread_get_format(avctx, pix_fmts);
+}
+
+static void setup_hwaccel_for_pixfmt(AVCodecContext *avctx)
+{
+ // until then pix_fmt may be changed right after codec init
+ if (avctx->hwaccel
+#if FF_API_VDPAU
+ || uses_vdpau(avctx)
+#endif
+ )
+ if (avctx->idct_algo == FF_IDCT_AUTO)
+ avctx->idct_algo = FF_IDCT_SIMPLE;
+
+ if (avctx->hwaccel && avctx->pix_fmt == AV_PIX_FMT_XVMC) {
+ Mpeg1Context *s1 = avctx->priv_data;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+
+ s->pack_pblocks = 1;
+#if FF_API_XVMC
+FF_DISABLE_DEPRECATION_WARNINGS
+ avctx->xvmc_acceleration = 2;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_XVMC */
+ }
+}
+
+/* Call this function when we know all parameters.
+ * It may be called in different places for MPEG-1 and MPEG-2. */
+static int mpeg_decode_postinit(AVCodecContext *avctx)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+ uint8_t old_permutation[64];
+ int ret;
+
+ if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
+ // MPEG-1 aspect
+ AVRational aspect_inv = av_d2q(ff_mpeg1_aspect[s->aspect_ratio_info], 255);
+ avctx->sample_aspect_ratio = (AVRational) { aspect_inv.den, aspect_inv.num };
+ } else { // MPEG-2
+ // MPEG-2 aspect
+ if (s->aspect_ratio_info > 1) {
+ AVRational dar =
+ av_mul_q(av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
+ (AVRational) { s1->pan_scan.width,
+ s1->pan_scan.height }),
+ (AVRational) { s->width, s->height });
+
+ /* We ignore the spec here and guess a bit as reality does not
+ * match the spec, see for example res_change_ffmpeg_aspect.ts
+ * and sequence-display-aspect.mpg.
+ * issue1613, 621, 562 */
+ if ((s1->pan_scan.width == 0) || (s1->pan_scan.height == 0) ||
+ (av_cmp_q(dar, (AVRational) { 4, 3 }) &&
+ av_cmp_q(dar, (AVRational) { 16, 9 }))) {
+ s->avctx->sample_aspect_ratio =
+ av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
+ (AVRational) { s->width, s->height });
+ } else {
+ s->avctx->sample_aspect_ratio =
+ av_div_q(ff_mpeg2_aspect[s->aspect_ratio_info],
+ (AVRational) { s1->pan_scan.width, s1->pan_scan.height });
+// issue1613 4/3 16/9 -> 16/9
+// res_change_ffmpeg_aspect.ts 4/3 225/44 ->4/3
+// widescreen-issue562.mpg 4/3 16/9 -> 16/9
+// s->avctx->sample_aspect_ratio = av_mul_q(s->avctx->sample_aspect_ratio, (AVRational) {s->width, s->height});
+ ff_dlog(avctx, "aspect A %d/%d\n",
+ ff_mpeg2_aspect[s->aspect_ratio_info].num,
+ ff_mpeg2_aspect[s->aspect_ratio_info].den);
+ ff_dlog(avctx, "aspect B %d/%d\n", s->avctx->sample_aspect_ratio.num,
+ s->avctx->sample_aspect_ratio.den);
+ }
+ } else {
+ s->avctx->sample_aspect_ratio =
+ ff_mpeg2_aspect[s->aspect_ratio_info];
+ }
+ } // MPEG-2
+
+ if (av_image_check_sar(s->width, s->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 ((s1->mpeg_enc_ctx_allocated == 0) ||
+ avctx->coded_width != s->width ||
+ avctx->coded_height != s->height ||
+ s1->save_width != s->width ||
+ s1->save_height != s->height ||
+ av_cmp_q(s1->save_aspect, s->avctx->sample_aspect_ratio) ||
+ (s1->save_progressive_seq != s->progressive_sequence && FFALIGN(s->height, 16) != FFALIGN(s->height, 32)) ||
+ 0) {
+ if (s1->mpeg_enc_ctx_allocated) {
+ ParseContext pc = s->parse_context;
+ s->parse_context.buffer = 0;
+ ff_mpv_common_end(s);
+ s->parse_context = pc;
+ s1->mpeg_enc_ctx_allocated = 0;
+ }
+
+ ret = ff_set_dimensions(avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
+
+ if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO && s->bit_rate) {
+ avctx->rc_max_rate = s->bit_rate;
+ } else if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && s->bit_rate &&
+ (s->bit_rate != 0x3FFFF*400 || s->vbv_delay != 0xFFFF)) {
+ avctx->bit_rate = s->bit_rate;
+ }
+ s1->save_aspect = s->avctx->sample_aspect_ratio;
+ s1->save_width = s->width;
+ s1->save_height = s->height;
+ s1->save_progressive_seq = s->progressive_sequence;
+
+ /* low_delay may be forced, in this case we will have B-frames
+ * that behave like P-frames. */
+ avctx->has_b_frames = !s->low_delay;
+
+ if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
+ // MPEG-1 fps
+ avctx->framerate = ff_mpeg12_frame_rate_tab[s->frame_rate_index];
+ avctx->ticks_per_frame = 1;
+
+ avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
+ } else { // MPEG-2
+ // MPEG-2 fps
+ av_reduce(&s->avctx->framerate.num,
+ &s->avctx->framerate.den,
+ ff_mpeg12_frame_rate_tab[s->frame_rate_index].num * s1->frame_rate_ext.num,
+ ff_mpeg12_frame_rate_tab[s->frame_rate_index].den * s1->frame_rate_ext.den,
+ 1 << 30);
+ avctx->ticks_per_frame = 2;
+
+ switch (s->chroma_format) {
+ case 1: avctx->chroma_sample_location = AVCHROMA_LOC_LEFT; break;
+ case 2:
+ case 3: avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; break;
+ default: av_assert0(0);
+ }
+ } // MPEG-2
+
+ avctx->pix_fmt = mpeg_get_pixelformat(avctx);
+ setup_hwaccel_for_pixfmt(avctx);
+
+ /* Quantization matrices may need reordering
+ * if DCT permutation is changed. */
+ memcpy(old_permutation, s->idsp.idct_permutation, 64 * sizeof(uint8_t));
+
+ ff_mpv_idct_init(s);
+ if ((ret = ff_mpv_common_init(s)) < 0)
+ return ret;
+
+ quant_matrix_rebuild(s->intra_matrix, old_permutation, s->idsp.idct_permutation);
+ quant_matrix_rebuild(s->inter_matrix, old_permutation, s->idsp.idct_permutation);
+ quant_matrix_rebuild(s->chroma_intra_matrix, old_permutation, s->idsp.idct_permutation);
+ quant_matrix_rebuild(s->chroma_inter_matrix, old_permutation, s->idsp.idct_permutation);
+
+ s1->mpeg_enc_ctx_allocated = 1;
+ }
+ return 0;
+}
+
+static int mpeg1_decode_picture(AVCodecContext *avctx, const uint8_t *buf,
+ int buf_size)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+ int ref, f_code, vbv_delay;
+
+ init_get_bits(&s->gb, buf, buf_size * 8);
+
+ ref = get_bits(&s->gb, 10); /* temporal ref */
+ s->pict_type = get_bits(&s->gb, 3);
+ if (s->pict_type == 0 || s->pict_type > 3)
+ return AVERROR_INVALIDDATA;
+
+ vbv_delay = get_bits(&s->gb, 16);
+ s->vbv_delay = vbv_delay;
+ if (s->pict_type == AV_PICTURE_TYPE_P ||
+ s->pict_type == AV_PICTURE_TYPE_B) {
+ s->full_pel[0] = get_bits1(&s->gb);
+ f_code = get_bits(&s->gb, 3);
+ if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)))
+ return AVERROR_INVALIDDATA;
+ f_code += !f_code;
+ s->mpeg_f_code[0][0] = f_code;
+ s->mpeg_f_code[0][1] = f_code;
+ }
+ if (s->pict_type == AV_PICTURE_TYPE_B) {
+ s->full_pel[1] = get_bits1(&s->gb);
+ f_code = get_bits(&s->gb, 3);
+ if (f_code == 0 && (avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)))
+ return AVERROR_INVALIDDATA;
+ f_code += !f_code;
+ s->mpeg_f_code[1][0] = f_code;
+ s->mpeg_f_code[1][1] = f_code;
+ }
+ s->current_picture.f->pict_type = s->pict_type;
+ s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I;
+
+ if (avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(avctx, AV_LOG_DEBUG,
+ "vbv_delay %d, ref %d type:%d\n", vbv_delay, ref, s->pict_type);
+
+ s->y_dc_scale = 8;
+ s->c_dc_scale = 8;
+ return 0;
+}
+
+static void mpeg_decode_sequence_extension(Mpeg1Context *s1)
+{
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+ int horiz_size_ext, vert_size_ext;
+ int bit_rate_ext;
+
+ skip_bits(&s->gb, 1); /* profile and level esc*/
+ s->avctx->profile = get_bits(&s->gb, 3);
+ s->avctx->level = get_bits(&s->gb, 4);
+ s->progressive_sequence = get_bits1(&s->gb); /* progressive_sequence */
+ s->chroma_format = get_bits(&s->gb, 2); /* chroma_format 1=420, 2=422, 3=444 */
+
+ if (!s->chroma_format) {
+ s->chroma_format = 1;
+ av_log(s->avctx, AV_LOG_WARNING, "Chroma format invalid\n");
+ }
+
+ horiz_size_ext = get_bits(&s->gb, 2);
+ vert_size_ext = get_bits(&s->gb, 2);
+ s->width |= (horiz_size_ext << 12);
+ s->height |= (vert_size_ext << 12);
+ bit_rate_ext = get_bits(&s->gb, 12); /* XXX: handle it */
+ s->bit_rate += (bit_rate_ext << 18) * 400LL;
+ check_marker(&s->gb, "after bit rate extension");
+ s->avctx->rc_buffer_size += get_bits(&s->gb, 8) * 1024 * 16 << 10;
+
+ s->low_delay = get_bits1(&s->gb);
+ if (s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY)
+ s->low_delay = 1;
+
+ s1->frame_rate_ext.num = get_bits(&s->gb, 2) + 1;
+ s1->frame_rate_ext.den = get_bits(&s->gb, 5) + 1;
+
+ ff_dlog(s->avctx, "sequence extension\n");
+ s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
+
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "profile: %d, level: %d ps: %d cf:%d vbv buffer: %d, bitrate:%"PRId64"\n",
+ s->avctx->profile, s->avctx->level, s->progressive_sequence, s->chroma_format,
+ s->avctx->rc_buffer_size, s->bit_rate);
+}
+
+static void mpeg_decode_sequence_display_extension(Mpeg1Context *s1)
+{
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+ int color_description, w, h;
+
+ skip_bits(&s->gb, 3); /* video format */
+ color_description = get_bits1(&s->gb);
+ if (color_description) {
+ s->avctx->color_primaries = get_bits(&s->gb, 8);
+ s->avctx->color_trc = get_bits(&s->gb, 8);
+ s->avctx->colorspace = get_bits(&s->gb, 8);
+ }
+ w = get_bits(&s->gb, 14);
+ skip_bits(&s->gb, 1); // marker
+ h = get_bits(&s->gb, 14);
+ // remaining 3 bits are zero padding
+
+ s1->pan_scan.width = 16 * w;
+ s1->pan_scan.height = 16 * h;
+
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_DEBUG, "sde w:%d, h:%d\n", w, h);
+}
+
+static void mpeg_decode_picture_display_extension(Mpeg1Context *s1)
+{
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+ int i, nofco;
+
+ nofco = 1;
+ if (s->progressive_sequence) {
+ if (s->repeat_first_field) {
+ nofco++;
+ if (s->top_field_first)
+ nofco++;
+ }
+ } else {
+ if (s->picture_structure == PICT_FRAME) {
+ nofco++;
+ if (s->repeat_first_field)
+ nofco++;
+ }
+ }
+ for (i = 0; i < nofco; i++) {
+ s1->pan_scan.position[i][0] = get_sbits(&s->gb, 16);
+ skip_bits(&s->gb, 1); // marker
+ s1->pan_scan.position[i][1] = get_sbits(&s->gb, 16);
+ skip_bits(&s->gb, 1); // marker
+ }
+
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "pde (%"PRId16",%"PRId16") (%"PRId16",%"PRId16") (%"PRId16",%"PRId16")\n",
+ s1->pan_scan.position[0][0], s1->pan_scan.position[0][1],
+ s1->pan_scan.position[1][0], s1->pan_scan.position[1][1],
+ s1->pan_scan.position[2][0], s1->pan_scan.position[2][1]);
+}
+
+static int load_matrix(MpegEncContext *s, uint16_t matrix0[64],
+ uint16_t matrix1[64], int intra)
+{
+ int i;
+
+ for (i = 0; i < 64; i++) {
+ int j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
+ int v = get_bits(&s->gb, 8);
+ if (v == 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "matrix damaged\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (intra && i == 0 && v != 8) {
+ av_log(s->avctx, AV_LOG_DEBUG, "intra matrix specifies invalid DC quantizer %d, ignoring\n", v);
+ v = 8; // needed by pink.mpg / issue1046
+ }
+ matrix0[j] = v;
+ if (matrix1)
+ matrix1[j] = v;
+ }
+ return 0;
+}
+
+static void mpeg_decode_quant_matrix_extension(MpegEncContext *s)
+{
+ ff_dlog(s->avctx, "matrix extension\n");
+
+ if (get_bits1(&s->gb))
+ load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1);
+ if (get_bits1(&s->gb))
+ load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0);
+ if (get_bits1(&s->gb))
+ load_matrix(s, s->chroma_intra_matrix, NULL, 1);
+ if (get_bits1(&s->gb))
+ load_matrix(s, s->chroma_inter_matrix, NULL, 0);
+}
+
+static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1)
+{
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+
+ s->full_pel[0] = s->full_pel[1] = 0;
+ s->mpeg_f_code[0][0] = get_bits(&s->gb, 4);
+ s->mpeg_f_code[0][1] = get_bits(&s->gb, 4);
+ s->mpeg_f_code[1][0] = get_bits(&s->gb, 4);
+ s->mpeg_f_code[1][1] = get_bits(&s->gb, 4);
+ if (!s->pict_type && s1->mpeg_enc_ctx_allocated) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Missing picture start code, guessing missing values\n");
+ if (s->mpeg_f_code[1][0] == 15 && s->mpeg_f_code[1][1] == 15) {
+ if (s->mpeg_f_code[0][0] == 15 && s->mpeg_f_code[0][1] == 15)
+ s->pict_type = AV_PICTURE_TYPE_I;
+ else
+ s->pict_type = AV_PICTURE_TYPE_P;
+ } else
+ s->pict_type = AV_PICTURE_TYPE_B;
+ s->current_picture.f->pict_type = s->pict_type;
+ s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I;
+ }
+ s->mpeg_f_code[0][0] += !s->mpeg_f_code[0][0];
+ s->mpeg_f_code[0][1] += !s->mpeg_f_code[0][1];
+ s->mpeg_f_code[1][0] += !s->mpeg_f_code[1][0];
+ s->mpeg_f_code[1][1] += !s->mpeg_f_code[1][1];
+
+ s->intra_dc_precision = get_bits(&s->gb, 2);
+ s->picture_structure = get_bits(&s->gb, 2);
+ s->top_field_first = get_bits1(&s->gb);
+ s->frame_pred_frame_dct = get_bits1(&s->gb);
+ s->concealment_motion_vectors = get_bits1(&s->gb);
+ s->q_scale_type = get_bits1(&s->gb);
+ s->intra_vlc_format = get_bits1(&s->gb);
+ s->alternate_scan = get_bits1(&s->gb);
+ s->repeat_first_field = get_bits1(&s->gb);
+ s->chroma_420_type = get_bits1(&s->gb);
+ s->progressive_frame = get_bits1(&s->gb);
+
+ if (s->alternate_scan) {
+ ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan);
+ } else {
+ ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
+ }
+
+ /* composite display not parsed */
+ ff_dlog(s->avctx, "intra_dc_precision=%d\n", s->intra_dc_precision);
+ ff_dlog(s->avctx, "picture_structure=%d\n", s->picture_structure);
+ ff_dlog(s->avctx, "top field first=%d\n", s->top_field_first);
+ ff_dlog(s->avctx, "repeat first field=%d\n", s->repeat_first_field);
+ ff_dlog(s->avctx, "conceal=%d\n", s->concealment_motion_vectors);
+ ff_dlog(s->avctx, "intra_vlc_format=%d\n", s->intra_vlc_format);
+ ff_dlog(s->avctx, "alternate_scan=%d\n", s->alternate_scan);
+ ff_dlog(s->avctx, "frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct);
+ ff_dlog(s->avctx, "progressive_frame=%d\n", s->progressive_frame);
+}
+
+static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size)
+{
+ AVCodecContext *avctx = s->avctx;
+ Mpeg1Context *s1 = (Mpeg1Context *) s;
+ int ret;
+
+ /* start frame decoding */
+ if (s->first_field || s->picture_structure == PICT_FRAME) {
+ AVFrameSideData *pan_scan;
+
+ if ((ret = ff_mpv_frame_start(s, avctx)) < 0)
+ return ret;
+
+ ff_mpeg_er_frame_start(s);
+
+ /* first check if we must repeat the frame */
+ s->current_picture_ptr->f->repeat_pict = 0;
+ if (s->repeat_first_field) {
+ if (s->progressive_sequence) {
+ if (s->top_field_first)
+ s->current_picture_ptr->f->repeat_pict = 4;
+ else
+ s->current_picture_ptr->f->repeat_pict = 2;
+ } else if (s->progressive_frame) {
+ s->current_picture_ptr->f->repeat_pict = 1;
+ }
+ }
+
+ pan_scan = av_frame_new_side_data(s->current_picture_ptr->f,
+ AV_FRAME_DATA_PANSCAN,
+ sizeof(s1->pan_scan));
+ if (!pan_scan)
+ return AVERROR(ENOMEM);
+ memcpy(pan_scan->data, &s1->pan_scan, sizeof(s1->pan_scan));
+
+ if (s1->a53_caption) {
+ AVFrameSideData *sd = av_frame_new_side_data(
+ 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);
+ avctx->properties |= FF_CODEC_PROPERTY_CLOSED_CAPTIONS;
+ }
+
+ if (s1->has_stereo3d) {
+ AVStereo3D *stereo = av_stereo3d_create_side_data(s->current_picture_ptr->f);
+ if (!stereo)
+ return AVERROR(ENOMEM);
+
+ *stereo = s1->stereo3d;
+ s1->has_stereo3d = 0;
+ }
+
+ if (s1->has_afd) {
+ AVFrameSideData *sd =
+ av_frame_new_side_data(s->current_picture_ptr->f,
+ AV_FRAME_DATA_AFD, 1);
+ if (!sd)
+ return AVERROR(ENOMEM);
+
+ *sd->data = s1->afd;
+ s1->has_afd = 0;
+ }
+
+ if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_FRAME))
+ ff_thread_finish_setup(avctx);
+ } else { // second field
+ int i;
+
+ if (!s->current_picture_ptr) {
+ av_log(s->avctx, AV_LOG_ERROR, "first field missing\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->avctx->hwaccel &&
+ (s->avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) {
+ if ((ret = s->avctx->hwaccel->end_frame(s->avctx)) < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "hardware accelerator failed to decode first field\n");
+ return ret;
+ }
+ }
+
+ for (i = 0; i < 4; i++) {
+ s->current_picture.f->data[i] = s->current_picture_ptr->f->data[i];
+ if (s->picture_structure == PICT_BOTTOM_FIELD)
+ s->current_picture.f->data[i] +=
+ s->current_picture_ptr->f->linesize[i];
+ }
+ }
+
+ if (avctx->hwaccel) {
+ if ((ret = avctx->hwaccel->start_frame(avctx, buf, buf_size)) < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+#define DECODE_SLICE_ERROR -1
+#define DECODE_SLICE_OK 0
+
+/**
+ * Decode a slice.
+ * MpegEncContext.mb_y must be set to the MB row from the startcode.
+ * @return DECODE_SLICE_ERROR if the slice is damaged,
+ * DECODE_SLICE_OK if this slice is OK
+ */
+static int mpeg_decode_slice(MpegEncContext *s, int mb_y,
+ const uint8_t **buf, int buf_size)
+{
+ AVCodecContext *avctx = s->avctx;
+ const int lowres = s->avctx->lowres;
+ const int field_pic = s->picture_structure != PICT_FRAME;
+ int ret;
+
+ s->resync_mb_x =
+ s->resync_mb_y = -1;
+
+ av_assert0(mb_y < s->mb_height);
+
+ init_get_bits(&s->gb, *buf, buf_size * 8);
+ if (s->codec_id != AV_CODEC_ID_MPEG1VIDEO && s->mb_height > 2800/16)
+ skip_bits(&s->gb, 3);
+
+ ff_mpeg1_clean_buffers(s);
+ s->interlaced_dct = 0;
+
+ s->qscale = get_qscale(s);
+
+ if (s->qscale == 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* extra slice info */
+ if (skip_1stop_8data_bits(&s->gb) < 0)
+ return AVERROR_INVALIDDATA;
+
+ s->mb_x = 0;
+
+ if (mb_y == 0 && s->codec_tag == AV_RL32("SLIF")) {
+ skip_bits1(&s->gb);
+ } else {
+ while (get_bits_left(&s->gb) > 0) {
+ int code = get_vlc2(&s->gb, ff_mbincr_vlc.table,
+ MBINCR_VLC_BITS, 2);
+ if (code < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (code >= 33) {
+ if (code == 33)
+ s->mb_x += 33;
+ /* otherwise, stuffing, nothing to do */
+ } else {
+ s->mb_x += code;
+ break;
+ }
+ }
+ }
+
+ if (s->mb_x >= (unsigned) s->mb_width) {
+ av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (avctx->hwaccel && avctx->hwaccel->decode_slice) {
+ const uint8_t *buf_end, *buf_start = *buf - 4; /* include start_code */
+ int start_code = -1;
+ buf_end = avpriv_find_start_code(buf_start + 2, *buf + buf_size, &start_code);
+ if (buf_end < *buf + buf_size)
+ buf_end -= 4;
+ s->mb_y = mb_y;
+ if (avctx->hwaccel->decode_slice(avctx, buf_start, buf_end - buf_start) < 0)
+ return DECODE_SLICE_ERROR;
+ *buf = buf_end;
+ return DECODE_SLICE_OK;
+ }
+
+ s->resync_mb_x = s->mb_x;
+ s->resync_mb_y = s->mb_y = mb_y;
+ s->mb_skip_run = 0;
+ ff_init_block_index(s);
+
+ if (s->mb_y == 0 && s->mb_x == 0 && (s->first_field || s->picture_structure == PICT_FRAME)) {
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n",
+ s->qscale,
+ s->mpeg_f_code[0][0], s->mpeg_f_code[0][1],
+ s->mpeg_f_code[1][0], s->mpeg_f_code[1][1],
+ s->pict_type == AV_PICTURE_TYPE_I ? "I" :
+ (s->pict_type == AV_PICTURE_TYPE_P ? "P" :
+ (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")),
+ s->progressive_sequence ? "ps" : "",
+ s->progressive_frame ? "pf" : "",
+ s->alternate_scan ? "alt" : "",
+ s->top_field_first ? "top" : "",
+ s->intra_dc_precision, s->picture_structure,
+ s->frame_pred_frame_dct, s->concealment_motion_vectors,
+ s->q_scale_type, s->intra_vlc_format,
+ s->repeat_first_field, s->chroma_420_type ? "420" : "");
+ }
+ }
+
+ for (;;) {
+ // If 1, we memcpy blocks in xvmcvideo.
+ if ((CONFIG_MPEG1_XVMC_HWACCEL || CONFIG_MPEG2_XVMC_HWACCEL) && s->pack_pblocks)
+ ff_xvmc_init_block(s); // set s->block
+
+ if ((ret = mpeg_decode_mb(s, s->block)) < 0)
+ return ret;
+
+ // Note motion_val is normally NULL unless we want to extract the MVs.
+ if (s->current_picture.motion_val[0] && !s->encoding) {
+ const int wrap = s->b8_stride;
+ int xy = s->mb_x * 2 + s->mb_y * 2 * wrap;
+ int b8_xy = 4 * (s->mb_x + s->mb_y * s->mb_stride);
+ int motion_x, motion_y, dir, i;
+
+ for (i = 0; i < 2; i++) {
+ for (dir = 0; dir < 2; dir++) {
+ if (s->mb_intra ||
+ (dir == 1 && s->pict_type != AV_PICTURE_TYPE_B)) {
+ motion_x = motion_y = 0;
+ } else if (s->mv_type == MV_TYPE_16X16 ||
+ (s->mv_type == MV_TYPE_FIELD && field_pic)) {
+ motion_x = s->mv[dir][0][0];
+ motion_y = s->mv[dir][0][1];
+ } else { /* if ((s->mv_type == MV_TYPE_FIELD) || (s->mv_type == MV_TYPE_16X8)) */
+ motion_x = s->mv[dir][i][0];
+ motion_y = s->mv[dir][i][1];
+ }
+
+ s->current_picture.motion_val[dir][xy][0] = motion_x;
+ s->current_picture.motion_val[dir][xy][1] = motion_y;
+ s->current_picture.motion_val[dir][xy + 1][0] = motion_x;
+ s->current_picture.motion_val[dir][xy + 1][1] = motion_y;
+ s->current_picture.ref_index [dir][b8_xy] =
+ s->current_picture.ref_index [dir][b8_xy + 1] = s->field_select[dir][i];
+ av_assert2(s->field_select[dir][i] == 0 ||
+ s->field_select[dir][i] == 1);
+ }
+ xy += wrap;
+ b8_xy += 2;
+ }
+ }
+
+ s->dest[0] += 16 >> lowres;
+ s->dest[1] +=(16 >> lowres) >> s->chroma_x_shift;
+ s->dest[2] +=(16 >> lowres) >> s->chroma_x_shift;
+
+ ff_mpv_decode_mb(s, s->block);
+
+ if (++s->mb_x >= s->mb_width) {
+ const int mb_size = 16 >> s->avctx->lowres;
+
+ ff_mpeg_draw_horiz_band(s, mb_size * (s->mb_y >> field_pic), mb_size);
+ ff_mpv_report_decode_progress(s);
+
+ s->mb_x = 0;
+ s->mb_y += 1 << field_pic;
+
+ if (s->mb_y >= s->mb_height) {
+ int left = get_bits_left(&s->gb);
+ int is_d10 = s->chroma_format == 2 &&
+ s->pict_type == AV_PICTURE_TYPE_I &&
+ avctx->profile == 0 && avctx->level == 5 &&
+ s->intra_dc_precision == 2 &&
+ s->q_scale_type == 1 && s->alternate_scan == 0 &&
+ s->progressive_frame == 0
+ /* vbv_delay == 0xBBB || 0xE10 */;
+
+ if (left >= 32 && !is_d10) {
+ GetBitContext gb = s->gb;
+ align_get_bits(&gb);
+ if (show_bits(&gb, 24) == 0x060E2B) {
+ av_log(avctx, AV_LOG_DEBUG, "Invalid MXF data found in video stream\n");
+ is_d10 = 1;
+ }
+ }
+
+ if (left < 0 ||
+ (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10) ||
+ ((avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_AGGRESSIVE)) && left > 8)) {
+ av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n",
+ left, left>0 ? show_bits(&s->gb, FFMIN(left, 23)) : 0);
+ return AVERROR_INVALIDDATA;
+ } else
+ goto eos;
+ }
+ // There are some files out there which are missing the last slice
+ // in cases where the slice is completely outside the visible
+ // area, we detect this here instead of running into the end expecting
+ // more data
+ if (s->mb_y >= ((s->height + 15) >> 4) &&
+ !s->progressive_sequence &&
+ get_bits_left(&s->gb) <= 8 &&
+ get_bits_left(&s->gb) >= 0 &&
+ s->mb_skip_run == -1 &&
+ show_bits(&s->gb, 8) == 0)
+ goto eos;
+
+ ff_init_block_index(s);
+ }
+
+ /* skip mb handling */
+ if (s->mb_skip_run == -1) {
+ /* read increment again */
+ s->mb_skip_run = 0;
+ for (;;) {
+ int code = get_vlc2(&s->gb, ff_mbincr_vlc.table,
+ MBINCR_VLC_BITS, 2);
+ if (code < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "mb incr damaged\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (code >= 33) {
+ if (code == 33) {
+ s->mb_skip_run += 33;
+ } else if (code == 35) {
+ if (s->mb_skip_run != 0 || show_bits(&s->gb, 15) != 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "slice mismatch\n");
+ return AVERROR_INVALIDDATA;
+ }
+ goto eos; /* end of slice */
+ }
+ /* otherwise, stuffing, nothing to do */
+ } else {
+ s->mb_skip_run += code;
+ break;
+ }
+ }
+ if (s->mb_skip_run) {
+ int i;
+ if (s->pict_type == AV_PICTURE_TYPE_I) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "skipped MB in I frame at %d %d\n", s->mb_x, s->mb_y);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* skip mb */
+ s->mb_intra = 0;
+ for (i = 0; i < 12; i++)
+ s->block_last_index[i] = -1;
+ if (s->picture_structure == PICT_FRAME)
+ s->mv_type = MV_TYPE_16X16;
+ else
+ s->mv_type = MV_TYPE_FIELD;
+ if (s->pict_type == AV_PICTURE_TYPE_P) {
+ /* if P type, zero motion vector is implied */
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv[0][0][0] = s->mv[0][0][1] = 0;
+ s->last_mv[0][0][0] = s->last_mv[0][0][1] = 0;
+ s->last_mv[0][1][0] = s->last_mv[0][1][1] = 0;
+ s->field_select[0][0] = (s->picture_structure - 1) & 1;
+ } else {
+ /* if B type, reuse previous vectors and directions */
+ s->mv[0][0][0] = s->last_mv[0][0][0];
+ s->mv[0][0][1] = s->last_mv[0][0][1];
+ s->mv[1][0][0] = s->last_mv[1][0][0];
+ s->mv[1][0][1] = s->last_mv[1][0][1];
+ }
+ }
+ }
+ }
+eos: // end of slice
+ if (get_bits_left(&s->gb) < 0) {
+ av_log(s, AV_LOG_ERROR, "overread %d\n", -get_bits_left(&s->gb));
+ return AVERROR_INVALIDDATA;
+ }
+ *buf += (get_bits_count(&s->gb) - 1) / 8;
+ ff_dlog(s, "Slice start:%d %d end:%d %d\n", s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y);
+ return 0;
+}
+
+static int slice_decode_thread(AVCodecContext *c, void *arg)
+{
+ MpegEncContext *s = *(void **) arg;
+ const uint8_t *buf = s->gb.buffer;
+ int mb_y = s->start_mb_y;
+ const int field_pic = s->picture_structure != PICT_FRAME;
+
+ s->er.error_count = (3 * (s->end_mb_y - s->start_mb_y) * s->mb_width) >> field_pic;
+
+ for (;;) {
+ uint32_t start_code;
+ int ret;
+
+ ret = mpeg_decode_slice(s, mb_y, &buf, s->gb.buffer_end - buf);
+ emms_c();
+ ff_dlog(c, "ret:%d resync:%d/%d mb:%d/%d ts:%d/%d ec:%d\n",
+ ret, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y,
+ s->start_mb_y, s->end_mb_y, s->er.error_count);
+ if (ret < 0) {
+ if (c->err_recognition & AV_EF_EXPLODE)
+ return ret;
+ if (s->resync_mb_x >= 0 && s->resync_mb_y >= 0)
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x, s->mb_y,
+ ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
+ } else {
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x - 1, s->mb_y,
+ ER_AC_END | ER_DC_END | ER_MV_END);
+ }
+
+ if (s->mb_y == s->end_mb_y)
+ return 0;
+
+ start_code = -1;
+ buf = avpriv_find_start_code(buf, s->gb.buffer_end, &start_code);
+ mb_y = start_code - SLICE_MIN_START_CODE;
+ if (s->codec_id != AV_CODEC_ID_MPEG1VIDEO && s->mb_height > 2800/16)
+ mb_y += (*buf&0xE0)<<2;
+ mb_y <<= field_pic;
+ if (s->picture_structure == PICT_BOTTOM_FIELD)
+ mb_y++;
+ if (mb_y < 0 || mb_y >= s->end_mb_y)
+ return AVERROR_INVALIDDATA;
+ }
+}
+
+/**
+ * Handle slice ends.
+ * @return 1 if it seems to be the last slice
+ */
+static int slice_end(AVCodecContext *avctx, AVFrame *pict)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+
+ if (!s1->mpeg_enc_ctx_allocated || !s->current_picture_ptr)
+ return 0;
+
+ if (s->avctx->hwaccel) {
+ int ret = s->avctx->hwaccel->end_frame(s->avctx);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "hardware accelerator failed to decode picture\n");
+ return ret;
+ }
+ }
+
+ /* end of slice reached */
+ if (/* s->mb_y << field_pic == s->mb_height && */ !s->first_field && !s1->first_slice) {
+ /* end of image */
+
+ ff_er_frame_end(&s->er);
+
+ ff_mpv_frame_end(s);
+
+ if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
+ int ret = av_frame_ref(pict, s->current_picture_ptr->f);
+ if (ret < 0)
+ return ret;
+ ff_print_debug_info(s, s->current_picture_ptr, pict);
+ ff_mpv_export_qp_table(s, pict, s->current_picture_ptr, FF_QSCALE_TYPE_MPEG2);
+ } else {
+ if (avctx->active_thread_type & FF_THREAD_FRAME)
+ s->picture_number++;
+ /* latency of 1 frame for I- and P-frames */
+ /* XXX: use another variable than picture_number */
+ if (s->last_picture_ptr) {
+ int ret = av_frame_ref(pict, s->last_picture_ptr->f);
+ if (ret < 0)
+ return ret;
+ ff_print_debug_info(s, s->last_picture_ptr, pict);
+ ff_mpv_export_qp_table(s, pict, s->last_picture_ptr, FF_QSCALE_TYPE_MPEG2);
+ }
+ }
+
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static int mpeg1_decode_sequence(AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+ int width, height;
+ int i, v, j;
+
+ init_get_bits(&s->gb, buf, buf_size * 8);
+
+ width = get_bits(&s->gb, 12);
+ height = get_bits(&s->gb, 12);
+ if (width == 0 || height == 0) {
+ av_log(avctx, AV_LOG_WARNING,
+ "Invalid horizontal or vertical size value.\n");
+ if (avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT))
+ return AVERROR_INVALIDDATA;
+ }
+ s->aspect_ratio_info = get_bits(&s->gb, 4);
+ if (s->aspect_ratio_info == 0) {
+ av_log(avctx, AV_LOG_ERROR, "aspect ratio has forbidden 0 value\n");
+ if (avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_COMPLIANT))
+ return AVERROR_INVALIDDATA;
+ }
+ s->frame_rate_index = get_bits(&s->gb, 4);
+ if (s->frame_rate_index == 0 || s->frame_rate_index > 13) {
+ av_log(avctx, AV_LOG_WARNING,
+ "frame_rate_index %d is invalid\n", s->frame_rate_index);
+ s->frame_rate_index = 1;
+ }
+ s->bit_rate = get_bits(&s->gb, 18) * 400LL;
+ if (check_marker(&s->gb, "in sequence header") == 0) {
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->avctx->rc_buffer_size = get_bits(&s->gb, 10) * 1024 * 16;
+ skip_bits(&s->gb, 1);
+
+ /* get matrix */
+ if (get_bits1(&s->gb)) {
+ load_matrix(s, s->chroma_intra_matrix, s->intra_matrix, 1);
+ } else {
+ for (i = 0; i < 64; i++) {
+ j = s->idsp.idct_permutation[i];
+ v = ff_mpeg1_default_intra_matrix[i];
+ s->intra_matrix[j] = v;
+ s->chroma_intra_matrix[j] = v;
+ }
+ }
+ if (get_bits1(&s->gb)) {
+ load_matrix(s, s->chroma_inter_matrix, s->inter_matrix, 0);
+ } else {
+ for (i = 0; i < 64; i++) {
+ int j = s->idsp.idct_permutation[i];
+ v = ff_mpeg1_default_non_intra_matrix[i];
+ s->inter_matrix[j] = v;
+ s->chroma_inter_matrix[j] = v;
+ }
+ }
+
+ if (show_bits(&s->gb, 23) != 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "sequence header damaged\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->width = width;
+ s->height = height;
+
+ /* We set MPEG-2 parameters so that it emulates MPEG-1. */
+ s->progressive_sequence = 1;
+ s->progressive_frame = 1;
+ s->picture_structure = PICT_FRAME;
+ s->first_field = 0;
+ s->frame_pred_frame_dct = 1;
+ s->chroma_format = 1;
+ s->codec_id =
+ s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO;
+ s->out_format = FMT_MPEG1;
+ s->swap_uv = 0; // AFAIK VCR2 does not have SEQ_HEADER
+ if (s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY)
+ s->low_delay = 1;
+
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_DEBUG, "vbv buffer: %d, bitrate:%"PRId64", aspect_ratio_info: %d \n",
+ s->avctx->rc_buffer_size, s->bit_rate, s->aspect_ratio_info);
+
+ return 0;
+}
+
+static int vcr2_init_sequence(AVCodecContext *avctx)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+ int i, v, ret;
+
+ /* start new MPEG-1 context decoding */
+ s->out_format = FMT_MPEG1;
+ if (s1->mpeg_enc_ctx_allocated) {
+ ff_mpv_common_end(s);
+ s1->mpeg_enc_ctx_allocated = 0;
+ }
+ s->width = avctx->coded_width;
+ s->height = avctx->coded_height;
+ avctx->has_b_frames = 0; // true?
+ s->low_delay = 1;
+
+ avctx->pix_fmt = mpeg_get_pixelformat(avctx);
+ setup_hwaccel_for_pixfmt(avctx);
+
+ ff_mpv_idct_init(s);
+ if ((ret = ff_mpv_common_init(s)) < 0)
+ return ret;
+ s1->mpeg_enc_ctx_allocated = 1;
+
+ for (i = 0; i < 64; i++) {
+ int j = s->idsp.idct_permutation[i];
+ v = ff_mpeg1_default_intra_matrix[i];
+ s->intra_matrix[j] = v;
+ s->chroma_intra_matrix[j] = v;
+
+ v = ff_mpeg1_default_non_intra_matrix[i];
+ s->inter_matrix[j] = v;
+ s->chroma_inter_matrix[j] = v;
+ }
+
+ s->progressive_sequence = 1;
+ s->progressive_frame = 1;
+ s->picture_structure = PICT_FRAME;
+ s->first_field = 0;
+ s->frame_pred_frame_dct = 1;
+ s->chroma_format = 1;
+ if (s->codec_tag == AV_RL32("BW10")) {
+ s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO;
+ } else {
+ s->swap_uv = 1; // in case of xvmc we need to swap uv for each MB
+ s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO;
+ }
+ s1->save_width = s->width;
+ s1->save_height = s->height;
+ s1->save_progressive_seq = s->progressive_sequence;
+ return 0;
+}
+
+static int mpeg_decode_a53_cc(AVCodecContext *avctx,
+ const uint8_t *p, int buf_size)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
+
+ if (buf_size >= 6 &&
+ p[0] == 'G' && p[1] == 'A' && p[2] == '9' && p[3] == '4' &&
+ p[4] == 3 && (p[5] & 0x40)) {
+ /* 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)
+ memcpy(s1->a53_caption, p + 7, s1->a53_caption_size);
+ }
+ return 1;
+ } else if (buf_size >= 11 &&
+ p[0] == 'C' && p[1] == 'C' && p[2] == 0x01 && p[3] == 0xf8) {
+ /* extract DVD CC data */
+ int cc_count = 0;
+ int i;
+ // There is a caption count field in the data, but it is often
+ // incorect. 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) {
+ uint8_t field1 = !!(p[4] & 0x80);
+ uint8_t *cap = s1->a53_caption;
+ p += 5;
+ for (i = 0; i < cc_count; i++) {
+ cap[0] = (p[0] == 0xff && field1) ? 0xfc : 0xfd;
+ cap[1] = p[1];
+ cap[2] = p[2];
+ cap[3] = (p[3] == 0xff && !field1) ? 0xfc : 0xfd;
+ cap[4] = p[4];
+ cap[5] = p[5];
+ cap += 6;
+ p += 6;
+ }
+ }
+ }
+ return 1;
+ }
+ return 0;
+}
+
+static void mpeg_decode_user_data(AVCodecContext *avctx,
+ const uint8_t *p, int buf_size)
+{
+ Mpeg1Context *s = avctx->priv_data;
+ const uint8_t *buf_end = p + buf_size;
+ Mpeg1Context *s1 = avctx->priv_data;
+
+#if 0
+ int i;
+ for(i=0; !(!p[i-2] && !p[i-1] && p[i]==1) && i<buf_size; i++){
+ av_log(avctx, AV_LOG_ERROR, "%c", p[i]);
+ }
+ av_log(avctx, AV_LOG_ERROR, "\n");
+#endif
+
+ if (buf_size > 29){
+ int i;
+ for(i=0; i<20; i++)
+ if (!memcmp(p+i, "\0TMPGEXS\0", 9)){
+ s->tmpgexs= 1;
+ }
+ }
+ /* we parse the DTG active format information */
+ if (buf_end - p >= 5 &&
+ p[0] == 'D' && p[1] == 'T' && p[2] == 'G' && p[3] == '1') {
+ int flags = p[4];
+ p += 5;
+ if (flags & 0x80) {
+ /* skip event id */
+ p += 2;
+ }
+ if (flags & 0x40) {
+ if (buf_end - p < 1)
+ return;
+#if FF_API_AFD
+FF_DISABLE_DEPRECATION_WARNINGS
+ avctx->dtg_active_format = p[0] & 0x0f;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif /* FF_API_AFD */
+ s1->has_afd = 1;
+ s1->afd = p[0] & 0x0f;
+ }
+ } else if (buf_end - p >= 6 &&
+ p[0] == 'J' && p[1] == 'P' && p[2] == '3' && p[3] == 'D' &&
+ p[4] == 0x03) { // S3D_video_format_length
+ // the 0x7F mask ignores the reserved_bit value
+ const uint8_t S3D_video_format_type = p[5] & 0x7F;
+
+ if (S3D_video_format_type == 0x03 ||
+ S3D_video_format_type == 0x04 ||
+ S3D_video_format_type == 0x08 ||
+ S3D_video_format_type == 0x23) {
+
+ s1->has_stereo3d = 1;
+
+ switch (S3D_video_format_type) {
+ case 0x03:
+ s1->stereo3d.type = AV_STEREO3D_SIDEBYSIDE;
+ break;
+ case 0x04:
+ s1->stereo3d.type = AV_STEREO3D_TOPBOTTOM;
+ break;
+ case 0x08:
+ s1->stereo3d.type = AV_STEREO3D_2D;
+ break;
+ case 0x23:
+ s1->stereo3d.type = AV_STEREO3D_SIDEBYSIDE_QUINCUNX;
+ break;
+ }
+ }
+ } else if (mpeg_decode_a53_cc(avctx, p, buf_size)) {
+ return;
+ }
+}
+
+static void mpeg_decode_gop(AVCodecContext *avctx,
+ const uint8_t *buf, int buf_size)
+{
+ Mpeg1Context *s1 = avctx->priv_data;
+ MpegEncContext *s = &s1->mpeg_enc_ctx;
+ int broken_link;
+ int64_t tc;
+
+ init_get_bits(&s->gb, buf, buf_size * 8);
+
+ tc = avctx->timecode_frame_start = get_bits(&s->gb, 25);
+
+ s->closed_gop = get_bits1(&s->gb);
+ /* broken_link indicates that after editing the
+ * reference frames of the first B-Frames after GOP I-Frame
+ * are missing (open gop) */
+ broken_link = get_bits1(&s->gb);
+
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
+ char tcbuf[AV_TIMECODE_STR_SIZE];
+ av_timecode_make_mpeg_tc_string(tcbuf, tc);
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "GOP (%s) closed_gop=%d broken_link=%d\n",
+ tcbuf, s->closed_gop, broken_link);
+ }
+}
+
+static int decode_chunks(AVCodecContext *avctx, AVFrame *picture,
+ int *got_output, const uint8_t *buf, int buf_size)
+{
+ Mpeg1Context *s = avctx->priv_data;
+ MpegEncContext *s2 = &s->mpeg_enc_ctx;
+ const uint8_t *buf_ptr = buf;
+ const uint8_t *buf_end = buf + buf_size;
+ int ret, input_size;
+ int last_code = 0, skip_frame = 0;
+ int picture_start_code_seen = 0;
+
+ for (;;) {
+ /* find next start code */
+ uint32_t start_code = -1;
+ buf_ptr = avpriv_find_start_code(buf_ptr, buf_end, &start_code);
+ if (start_code > 0x1ff) {
+ if (!skip_frame) {
+ if (HAVE_THREADS &&
+ (avctx->active_thread_type & FF_THREAD_SLICE) &&
+ !avctx->hwaccel) {
+ int i;
+ av_assert0(avctx->thread_count > 1);
+
+ avctx->execute(avctx, slice_decode_thread,
+ &s2->thread_context[0], NULL,
+ s->slice_count, sizeof(void *));
+ for (i = 0; i < s->slice_count; i++)
+ s2->er.error_count += s2->thread_context[i]->er.error_count;
+ }
+
+#if FF_API_VDPAU
+ if ((CONFIG_MPEG_VDPAU_DECODER || CONFIG_MPEG1_VDPAU_DECODER)
+ && uses_vdpau(avctx))
+ ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count);
+#endif
+
+ ret = slice_end(avctx, picture);
+ if (ret < 0)
+ return ret;
+ else if (ret) {
+ // FIXME: merge with the stuff in mpeg_decode_slice
+ if (s2->last_picture_ptr || s2->low_delay)
+ *got_output = 1;
+ }
+ }
+ s2->pict_type = 0;
+
+ if (avctx->err_recognition & AV_EF_EXPLODE && s2->er.error_count)
+ return AVERROR_INVALIDDATA;
+
+ return FFMAX(0, buf_ptr - buf - s2->parse_context.last_index);
+ }
+
+ input_size = buf_end - buf_ptr;
+
+ if (avctx->debug & FF_DEBUG_STARTCODE)
+ av_log(avctx, AV_LOG_DEBUG, "%3"PRIX32" at %"PTRDIFF_SPECIFIER" left %d\n",
+ start_code, buf_ptr - buf, input_size);
+
+ /* prepare data for next start code */
+ switch (start_code) {
+ case SEQ_START_CODE:
+ if (last_code == 0) {
+ mpeg1_decode_sequence(avctx, buf_ptr, input_size);
+ if (buf != avctx->extradata)
+ s->sync = 1;
+ } else {
+ av_log(avctx, AV_LOG_ERROR,
+ "ignoring SEQ_START_CODE after %X\n", last_code);
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ }
+ break;
+
+ case PICTURE_START_CODE:
+ if (picture_start_code_seen && s2->picture_structure == PICT_FRAME) {
+ /* If it's a frame picture, there can't be more than one picture header.
+ Yet, it does happen and we need to handle it. */
+ av_log(avctx, AV_LOG_WARNING, "ignoring extra picture following a frame-picture\n");
+ break;
+ }
+ picture_start_code_seen = 1;
+
+ if (s2->width <= 0 || s2->height <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d.\n",
+ s2->width, s2->height);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->tmpgexs){
+ s2->intra_dc_precision= 3;
+ s2->intra_matrix[0]= 1;
+ }
+ if (HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE) &&
+ !avctx->hwaccel && s->slice_count) {
+ int i;
+
+ avctx->execute(avctx, slice_decode_thread,
+ s2->thread_context, NULL,
+ s->slice_count, sizeof(void *));
+ for (i = 0; i < s->slice_count; i++)
+ s2->er.error_count += s2->thread_context[i]->er.error_count;
+ s->slice_count = 0;
+ }
+ if (last_code == 0 || last_code == SLICE_MIN_START_CODE) {
+ ret = mpeg_decode_postinit(avctx);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "mpeg_decode_postinit() failure\n");
+ return ret;
+ }
+
+ /* We have a complete image: we try to decompress it. */
+ if (mpeg1_decode_picture(avctx, buf_ptr, input_size) < 0)
+ s2->pict_type = 0;
+ s->first_slice = 1;
+ last_code = PICTURE_START_CODE;
+ } else {
+ av_log(avctx, AV_LOG_ERROR,
+ "ignoring pic after %X\n", last_code);
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ }
+ break;
+ case EXT_START_CODE:
+ init_get_bits(&s2->gb, buf_ptr, input_size * 8);
+
+ switch (get_bits(&s2->gb, 4)) {
+ case 0x1:
+ if (last_code == 0) {
+ mpeg_decode_sequence_extension(s);
+ } else {
+ av_log(avctx, AV_LOG_ERROR,
+ "ignoring seq ext after %X\n", last_code);
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ }
+ break;
+ case 0x2:
+ mpeg_decode_sequence_display_extension(s);
+ break;
+ case 0x3:
+ mpeg_decode_quant_matrix_extension(s2);
+ break;
+ case 0x7:
+ mpeg_decode_picture_display_extension(s);
+ break;
+ case 0x8:
+ if (last_code == PICTURE_START_CODE) {
+ mpeg_decode_picture_coding_extension(s);
+ } else {
+ av_log(avctx, AV_LOG_ERROR,
+ "ignoring pic cod ext after %X\n", last_code);
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ }
+ break;
+ }
+ break;
+ case USER_START_CODE:
+ mpeg_decode_user_data(avctx, buf_ptr, input_size);
+ break;
+ case GOP_START_CODE:
+ if (last_code == 0) {
+ s2->first_field = 0;
+ mpeg_decode_gop(avctx, buf_ptr, input_size);
+ s->sync = 1;
+ } else {
+ av_log(avctx, AV_LOG_ERROR,
+ "ignoring GOP_START_CODE after %X\n", last_code);
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ }
+ break;
+ default:
+ if (start_code >= SLICE_MIN_START_CODE &&
+ start_code <= SLICE_MAX_START_CODE && last_code == PICTURE_START_CODE) {
+ if (s2->progressive_sequence && !s2->progressive_frame) {
+ s2->progressive_frame = 1;
+ av_log(s2->avctx, AV_LOG_ERROR,
+ "interlaced frame in progressive sequence, ignoring\n");
+ }
+
+ if (s2->picture_structure == 0 ||
+ (s2->progressive_frame && s2->picture_structure != PICT_FRAME)) {
+ av_log(s2->avctx, AV_LOG_ERROR,
+ "picture_structure %d invalid, ignoring\n",
+ s2->picture_structure);
+ s2->picture_structure = PICT_FRAME;
+ }
+
+ if (s2->progressive_sequence && !s2->frame_pred_frame_dct)
+ av_log(s2->avctx, AV_LOG_WARNING, "invalid frame_pred_frame_dct\n");
+
+ if (s2->picture_structure == PICT_FRAME) {
+ s2->first_field = 0;
+ s2->v_edge_pos = 16 * s2->mb_height;
+ } else {
+ s2->first_field ^= 1;
+ s2->v_edge_pos = 8 * s2->mb_height;
+ memset(s2->mbskip_table, 0, s2->mb_stride * s2->mb_height);
+ }
+ }
+ if (start_code >= SLICE_MIN_START_CODE &&
+ start_code <= SLICE_MAX_START_CODE && last_code != 0) {
+ const int field_pic = s2->picture_structure != PICT_FRAME;
+ int mb_y = start_code - SLICE_MIN_START_CODE;
+ last_code = SLICE_MIN_START_CODE;
+ if (s2->codec_id != AV_CODEC_ID_MPEG1VIDEO && s2->mb_height > 2800/16)
+ mb_y += (*buf_ptr&0xE0)<<2;
+
+ mb_y <<= field_pic;
+ if (s2->picture_structure == PICT_BOTTOM_FIELD)
+ mb_y++;
+
+ if (buf_end - buf_ptr < 2) {
+ av_log(s2->avctx, AV_LOG_ERROR, "slice too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (mb_y >= s2->mb_height) {
+ av_log(s2->avctx, AV_LOG_ERROR,
+ "slice below image (%d >= %d)\n", mb_y, s2->mb_height);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!s2->last_picture_ptr) {
+ /* Skip B-frames if we do not have reference frames and
+ * GOP is not closed. */
+ if (s2->pict_type == AV_PICTURE_TYPE_B) {
+ if (!s2->closed_gop) {
+ skip_frame = 1;
+ break;
+ }
+ }
+ }
+ if (s2->pict_type == AV_PICTURE_TYPE_I || (s2->avctx->flags2 & AV_CODEC_FLAG2_SHOW_ALL))
+ s->sync = 1;
+ if (!s2->next_picture_ptr) {
+ /* Skip P-frames if we do not have a reference frame or
+ * we have an invalid header. */
+ if (s2->pict_type == AV_PICTURE_TYPE_P && !s->sync) {
+ skip_frame = 1;
+ break;
+ }
+ }
+ if ((avctx->skip_frame >= AVDISCARD_NONREF &&
+ s2->pict_type == AV_PICTURE_TYPE_B) ||
+ (avctx->skip_frame >= AVDISCARD_NONKEY &&
+ s2->pict_type != AV_PICTURE_TYPE_I) ||
+ avctx->skip_frame >= AVDISCARD_ALL) {
+ skip_frame = 1;
+ break;
+ }
+
+ if (!s->mpeg_enc_ctx_allocated)
+ break;
+
+ if (s2->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
+ if (mb_y < avctx->skip_top ||
+ mb_y >= s2->mb_height - avctx->skip_bottom)
+ break;
+ }
+
+ if (!s2->pict_type) {
+ av_log(avctx, AV_LOG_ERROR, "Missing picture start code\n");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ break;
+ }
+
+ if (s->first_slice) {
+ skip_frame = 0;
+ s->first_slice = 0;
+ if ((ret = mpeg_field_start(s2, buf, buf_size)) < 0)
+ return ret;
+ }
+ if (!s2->current_picture_ptr) {
+ av_log(avctx, AV_LOG_ERROR,
+ "current_picture not initialized\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+#if FF_API_VDPAU
+ if (uses_vdpau(avctx)) {
+ s->slice_count++;
+ break;
+ }
+#endif
+
+ if (HAVE_THREADS &&
+ (avctx->active_thread_type & FF_THREAD_SLICE) &&
+ !avctx->hwaccel) {
+ int threshold = (s2->mb_height * s->slice_count +
+ s2->slice_context_count / 2) /
+ s2->slice_context_count;
+ av_assert0(avctx->thread_count > 1);
+ if (threshold <= mb_y) {
+ MpegEncContext *thread_context = s2->thread_context[s->slice_count];
+
+ thread_context->start_mb_y = mb_y;
+ thread_context->end_mb_y = s2->mb_height;
+ if (s->slice_count) {
+ s2->thread_context[s->slice_count - 1]->end_mb_y = mb_y;
+ ret = ff_update_duplicate_context(thread_context, s2);
+ if (ret < 0)
+ return ret;
+ }
+ init_get_bits(&thread_context->gb, buf_ptr, input_size * 8);
+ s->slice_count++;
+ }
+ buf_ptr += 2; // FIXME add minimum number of bytes per slice
+ } else {
+ ret = mpeg_decode_slice(s2, mb_y, &buf_ptr, input_size);
+ emms_c();
+
+ if (ret < 0) {
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return ret;
+ if (s2->resync_mb_x >= 0 && s2->resync_mb_y >= 0)
+ ff_er_add_slice(&s2->er, s2->resync_mb_x,
+ s2->resync_mb_y, s2->mb_x, s2->mb_y,
+ ER_AC_ERROR | ER_DC_ERROR | ER_MV_ERROR);
+ } else {
+ ff_er_add_slice(&s2->er, s2->resync_mb_x,
+ s2->resync_mb_y, s2->mb_x - 1, s2->mb_y,
+ ER_AC_END | ER_DC_END | ER_MV_END);
+ }
+ }
+ }
+ break;
+ }
+ }
+}
+
+static int mpeg_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_output, AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int ret;
+ int buf_size = avpkt->size;
+ Mpeg1Context *s = avctx->priv_data;
+ AVFrame *picture = data;
+ MpegEncContext *s2 = &s->mpeg_enc_ctx;
+
+ if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) {
+ /* special case for last picture */
+ if (s2->low_delay == 0 && s2->next_picture_ptr) {
+ int ret = av_frame_ref(picture, s2->next_picture_ptr->f);
+ if (ret < 0)
+ return ret;
+
+ s2->next_picture_ptr = NULL;
+
+ *got_output = 1;
+ }
+ return buf_size;
+ }
+
+ if (s2->avctx->flags & AV_CODEC_FLAG_TRUNCATED) {
+ int next = ff_mpeg1_find_frame_end(&s2->parse_context, buf,
+ buf_size, NULL);
+
+ if (ff_combine_frame(&s2->parse_context, next,
+ (const uint8_t **) &buf, &buf_size) < 0)
+ return buf_size;
+ }
+
+ s2->codec_tag = avpriv_toupper4(avctx->codec_tag);
+ if (s->mpeg_enc_ctx_allocated == 0 && ( s2->codec_tag == AV_RL32("VCR2")
+ || s2->codec_tag == AV_RL32("BW10")
+ ))
+ vcr2_init_sequence(avctx);
+
+ s->slice_count = 0;
+
+ if (avctx->extradata && !s->extradata_decoded) {
+ ret = decode_chunks(avctx, picture, got_output,
+ avctx->extradata, avctx->extradata_size);
+ if (*got_output) {
+ av_log(avctx, AV_LOG_ERROR, "picture in extradata\n");
+ av_frame_unref(picture);
+ *got_output = 0;
+ }
+ s->extradata_decoded = 1;
+ if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) {
+ s2->current_picture_ptr = NULL;
+ return ret;
+ }
+ }
+
+ ret = decode_chunks(avctx, picture, got_output, buf, buf_size);
+ if (ret<0 || *got_output)
+ s2->current_picture_ptr = NULL;
+
+ return ret;
+}
+
+static void flush(AVCodecContext *avctx)
+{
+ Mpeg1Context *s = avctx->priv_data;
+
+ s->sync = 0;
+
+ ff_mpeg_flush(avctx);
+}
+
+static av_cold int mpeg_decode_end(AVCodecContext *avctx)
+{
+ Mpeg1Context *s = avctx->priv_data;
+
+ if (s->mpeg_enc_ctx_allocated)
+ ff_mpv_common_end(&s->mpeg_enc_ctx);
+ av_freep(&s->a53_caption);
+ return 0;
+}
+
+static const AVProfile mpeg2_video_profiles[] = {
+ { FF_PROFILE_MPEG2_422, "4:2:2" },
+ { FF_PROFILE_MPEG2_HIGH, "High" },
+ { FF_PROFILE_MPEG2_SS, "Spatially Scalable" },
+ { FF_PROFILE_MPEG2_SNR_SCALABLE, "SNR Scalable" },
+ { FF_PROFILE_MPEG2_MAIN, "Main" },
+ { FF_PROFILE_MPEG2_SIMPLE, "Simple" },
+ { FF_PROFILE_RESERVED, "Reserved" },
+ { FF_PROFILE_RESERVED, "Reserved" },
+ { FF_PROFILE_UNKNOWN },
+};
+
+AVCodec ff_mpeg1video_decoder = {
+ .name = "mpeg1video",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MPEG1VIDEO,
+ .priv_data_size = sizeof(Mpeg1Context),
+ .init = mpeg_decode_init,
+ .close = mpeg_decode_end,
+ .decode = mpeg_decode_frame,
+ .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
+ AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_SLICE_THREADS,
+ .flush = flush,
+ .max_lowres = 3,
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context)
+};
+
+AVCodec ff_mpeg2video_decoder = {
+ .name = "mpeg2video",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 video"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MPEG2VIDEO,
+ .priv_data_size = sizeof(Mpeg1Context),
+ .init = mpeg_decode_init,
+ .close = mpeg_decode_end,
+ .decode = mpeg_decode_frame,
+ .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
+ AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_SLICE_THREADS,
+ .flush = flush,
+ .max_lowres = 3,
+ .profiles = NULL_IF_CONFIG_SMALL(mpeg2_video_profiles),
+};
+
+//legacy decoder
+AVCodec ff_mpegvideo_decoder = {
+ .name = "mpegvideo",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MPEG2VIDEO,
+ .priv_data_size = sizeof(Mpeg1Context),
+ .init = mpeg_decode_init,
+ .close = mpeg_decode_end,
+ .decode = mpeg_decode_frame,
+ .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS,
+ .flush = flush,
+ .max_lowres = 3,
+};
+
+#if FF_API_XVMC
+#if CONFIG_MPEG_XVMC_DECODER
+FF_DISABLE_DEPRECATION_WARNINGS
+static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx)
+{
+ if (avctx->active_thread_type & FF_THREAD_SLICE)
+ return -1;
+ if (!(avctx->slice_flags & SLICE_FLAG_CODED_ORDER))
+ return -1;
+ if (!(avctx->slice_flags & SLICE_FLAG_ALLOW_FIELD)) {
+ ff_dlog(avctx, "mpeg12.c: XvMC decoder will work better if SLICE_FLAG_ALLOW_FIELD is set\n");
+ }
+ mpeg_decode_init(avctx);
+
+ avctx->pix_fmt = AV_PIX_FMT_XVMC_MPEG2_IDCT;
+ avctx->xvmc_acceleration = 2; // 2 - the blocks are packed!
+
+ return 0;
+}
+
+AVCodec ff_mpeg_xvmc_decoder = {
+ .name = "mpegvideo_xvmc",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video XvMC (X-Video Motion Compensation)"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MPEG2VIDEO_XVMC,
+ .priv_data_size = sizeof(Mpeg1Context),
+ .init = mpeg_mc_decode_init,
+ .close = mpeg_decode_end,
+ .decode = mpeg_decode_frame,
+ .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 |
+ AV_CODEC_CAP_TRUNCATED | CODEC_CAP_HWACCEL |
+ AV_CODEC_CAP_DELAY,
+ .flush = flush,
+};
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+#endif /* FF_API_XVMC */
+
+#if CONFIG_MPEG_VDPAU_DECODER && FF_API_VDPAU
+AVCodec ff_mpeg_vdpau_decoder = {
+ .name = "mpegvideo_vdpau",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1/2 video (VDPAU acceleration)"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MPEG2VIDEO,
+ .priv_data_size = sizeof(Mpeg1Context),
+ .init = mpeg_decode_init,
+ .close = mpeg_decode_end,
+ .decode = mpeg_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED |
+ AV_CODEC_CAP_HWACCEL_VDPAU | AV_CODEC_CAP_DELAY,
+ .flush = flush,
+};
+#endif
+
+#if CONFIG_MPEG1_VDPAU_DECODER && FF_API_VDPAU
+AVCodec ff_mpeg1_vdpau_decoder = {
+ .name = "mpeg1video_vdpau",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 video (VDPAU acceleration)"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MPEG1VIDEO,
+ .priv_data_size = sizeof(Mpeg1Context),
+ .init = mpeg_decode_init,
+ .close = mpeg_decode_end,
+ .decode = mpeg_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED |
+ AV_CODEC_CAP_HWACCEL_VDPAU | AV_CODEC_CAP_DELAY,
+ .flush = flush,
+};
+#endif
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg12enc.c b/ffmpeg-2-8-12/libavcodec/mpeg12enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg12enc.c
rename to ffmpeg-2-8-12/libavcodec/mpeg12enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg12vlc.h b/ffmpeg-2-8-12/libavcodec/mpeg12vlc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg12vlc.h
rename to ffmpeg-2-8-12/libavcodec/mpeg12vlc.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg4_unpack_bframes_bsf.c b/ffmpeg-2-8-12/libavcodec/mpeg4_unpack_bframes_bsf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg4_unpack_bframes_bsf.c
rename to ffmpeg-2-8-12/libavcodec/mpeg4_unpack_bframes_bsf.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg4audio.c b/ffmpeg-2-8-12/libavcodec/mpeg4audio.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg4audio.c
rename to ffmpeg-2-8-12/libavcodec/mpeg4audio.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg4audio.h b/ffmpeg-2-8-12/libavcodec/mpeg4audio.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg4audio.h
rename to ffmpeg-2-8-12/libavcodec/mpeg4audio.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg4data.h b/ffmpeg-2-8-12/libavcodec/mpeg4data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg4data.h
rename to ffmpeg-2-8-12/libavcodec/mpeg4data.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg4video.c b/ffmpeg-2-8-12/libavcodec/mpeg4video.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg4video.c
rename to ffmpeg-2-8-12/libavcodec/mpeg4video.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg4video.h b/ffmpeg-2-8-12/libavcodec/mpeg4video.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg4video.h
rename to ffmpeg-2-8-12/libavcodec/mpeg4video.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg4video_parser.c b/ffmpeg-2-8-12/libavcodec/mpeg4video_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg4video_parser.c
rename to ffmpeg-2-8-12/libavcodec/mpeg4video_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg4video_parser.h b/ffmpeg-2-8-12/libavcodec/mpeg4video_parser.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg4video_parser.h
rename to ffmpeg-2-8-12/libavcodec/mpeg4video_parser.h
diff --git a/ffmpeg-2-8-12/libavcodec/mpeg4videodec.c b/ffmpeg-2-8-12/libavcodec/mpeg4videodec.c
new file mode 100644
index 0000000..75f079c
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/mpeg4videodec.c
@@ -0,0 +1,2868 @@
+/*
+ * MPEG4 decoder.
+ * Copyright (c) 2000,2001 Fabrice Bellard
+ * Copyright (c) 2002-2010 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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
+ */
+
+#define UNCHECKED_BITSTREAM_READER 1
+
+#include "libavutil/internal.h"
+#include "libavutil/opt.h"
+#include "error_resilience.h"
+#include "idctdsp.h"
+#include "internal.h"
+#include "mpegutils.h"
+#include "mpegvideo.h"
+#include "mpegvideodata.h"
+#include "mpeg4video.h"
+#include "h263.h"
+#include "thread.h"
+#include "xvididct.h"
+
+/* The defines below define the number of bits that are read at once for
+ * reading vlc values. Changing these may improve speed and data cache needs
+ * be aware though that decreasing them may need the number of stages that is
+ * passed to get_vlc* to be increased. */
+#define SPRITE_TRAJ_VLC_BITS 6
+#define DC_VLC_BITS 9
+#define MB_TYPE_B_VLC_BITS 4
+
+static VLC dc_lum, dc_chrom;
+static VLC sprite_trajectory;
+static VLC mb_type_b_vlc;
+
+static const int mb_type_b_map[4] = {
+ MB_TYPE_DIRECT2 | MB_TYPE_L0L1,
+ MB_TYPE_L0L1 | MB_TYPE_16x16,
+ MB_TYPE_L1 | MB_TYPE_16x16,
+ MB_TYPE_L0 | MB_TYPE_16x16,
+};
+
+/**
+ * Predict the ac.
+ * @param n block index (0-3 are luma, 4-5 are chroma)
+ * @param dir the ac prediction direction
+ */
+void ff_mpeg4_pred_ac(MpegEncContext *s, int16_t *block, int n, int dir)
+{
+ int i;
+ int16_t *ac_val, *ac_val1;
+ int8_t *const qscale_table = s->current_picture.qscale_table;
+
+ /* find prediction */
+ ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+ ac_val1 = ac_val;
+ if (s->ac_pred) {
+ if (dir == 0) {
+ const int xy = s->mb_x - 1 + s->mb_y * s->mb_stride;
+ /* left prediction */
+ ac_val -= 16;
+
+ if (s->mb_x == 0 || s->qscale == qscale_table[xy] ||
+ n == 1 || n == 3) {
+ /* same qscale */
+ for (i = 1; i < 8; i++)
+ block[s->idsp.idct_permutation[i << 3]] += ac_val[i];
+ } else {
+ /* different qscale, we must rescale */
+ for (i = 1; i < 8; i++)
+ block[s->idsp.idct_permutation[i << 3]] += ROUNDED_DIV(ac_val[i] * qscale_table[xy], s->qscale);
+ }
+ } else {
+ const int xy = s->mb_x + s->mb_y * s->mb_stride - s->mb_stride;
+ /* top prediction */
+ ac_val -= 16 * s->block_wrap[n];
+
+ if (s->mb_y == 0 || s->qscale == qscale_table[xy] ||
+ n == 2 || n == 3) {
+ /* same qscale */
+ for (i = 1; i < 8; i++)
+ block[s->idsp.idct_permutation[i]] += ac_val[i + 8];
+ } else {
+ /* different qscale, we must rescale */
+ for (i = 1; i < 8; i++)
+ block[s->idsp.idct_permutation[i]] += ROUNDED_DIV(ac_val[i + 8] * qscale_table[xy], s->qscale);
+ }
+ }
+ }
+ /* left copy */
+ for (i = 1; i < 8; i++)
+ ac_val1[i] = block[s->idsp.idct_permutation[i << 3]];
+
+ /* top copy */
+ for (i = 1; i < 8; i++)
+ ac_val1[8 + i] = block[s->idsp.idct_permutation[i]];
+}
+
+/**
+ * check if the next stuff is a resync marker or the end.
+ * @return 0 if not
+ */
+static inline int mpeg4_is_resync(Mpeg4DecContext *ctx)
+{
+ MpegEncContext *s = &ctx->m;
+ int bits_count = get_bits_count(&s->gb);
+ int v = show_bits(&s->gb, 16);
+
+ if (s->workaround_bugs & FF_BUG_NO_PADDING && !ctx->resync_marker)
+ return 0;
+
+ while (v <= 0xFF) {
+ if (s->pict_type == AV_PICTURE_TYPE_B ||
+ (v >> (8 - s->pict_type) != 1) || s->partitioned_frame)
+ break;
+ skip_bits(&s->gb, 8 + s->pict_type);
+ bits_count += 8 + s->pict_type;
+ v = show_bits(&s->gb, 16);
+ }
+
+ if (bits_count + 8 >= s->gb.size_in_bits) {
+ v >>= 8;
+ v |= 0x7F >> (7 - (bits_count & 7));
+
+ if (v == 0x7F)
+ return s->mb_num;
+ } else {
+ if (v == ff_mpeg4_resync_prefix[bits_count & 7]) {
+ int len, mb_num;
+ int mb_num_bits = av_log2(s->mb_num - 1) + 1;
+ GetBitContext gb = s->gb;
+
+ skip_bits(&s->gb, 1);
+ align_get_bits(&s->gb);
+
+ for (len = 0; len < 32; len++)
+ if (get_bits1(&s->gb))
+ break;
+
+ mb_num = get_bits(&s->gb, mb_num_bits);
+ if (!mb_num || mb_num > s->mb_num || get_bits_count(&s->gb)+6 > s->gb.size_in_bits)
+ mb_num= -1;
+
+ s->gb = gb;
+
+ if (len >= ff_mpeg4_get_video_packet_prefix_length(s))
+ return mb_num;
+ }
+ }
+ return 0;
+}
+
+static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *gb)
+{
+ MpegEncContext *s = &ctx->m;
+ int a = 2 << s->sprite_warping_accuracy;
+ int rho = 3 - s->sprite_warping_accuracy;
+ int r = 16 / a;
+ int alpha = 0;
+ int beta = 0;
+ int w = s->width;
+ int h = s->height;
+ int min_ab, i, w2, h2, w3, h3;
+ int sprite_ref[4][2];
+ int virtual_ref[2][2];
+ int64_t sprite_offset[2][2];
+
+ // only true for rectangle shapes
+ const int vop_ref[4][2] = { { 0, 0 }, { s->width, 0 },
+ { 0, s->height }, { s->width, s->height } };
+ int d[4][2] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } };
+
+ if (w <= 0 || h <= 0)
+ return AVERROR_INVALIDDATA;
+
+ for (i = 0; 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);
+ if (length > 0)
+ x = get_xbits(gb, length);
+
+ if (!(ctx->divx_version == 500 && ctx->divx_build == 413))
+ check_marker(gb, "before sprite_trajectory");
+
+ length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3);
+ if (length > 0)
+ y = get_xbits(gb, length);
+
+ check_marker(gb, "after sprite_trajectory");
+ ctx->sprite_traj[i][0] = d[i][0] = x;
+ ctx->sprite_traj[i][1] = d[i][1] = y;
+ }
+ for (; i < 4; i++)
+ ctx->sprite_traj[i][0] = ctx->sprite_traj[i][1] = 0;
+
+ while ((1 << alpha) < w)
+ alpha++;
+ while ((1 << beta) < h)
+ beta++; /* typo in the mpeg4 std for the definition of w' and h' */
+ w2 = 1 << alpha;
+ h2 = 1 << beta;
+
+ // Note, the 4th point isn't used for GMC
+ if (ctx->divx_version == 500 && ctx->divx_build == 413) {
+ sprite_ref[0][0] = a * vop_ref[0][0] + d[0][0];
+ sprite_ref[0][1] = a * vop_ref[0][1] + d[0][1];
+ sprite_ref[1][0] = a * vop_ref[1][0] + d[0][0] + d[1][0];
+ sprite_ref[1][1] = a * vop_ref[1][1] + d[0][1] + d[1][1];
+ sprite_ref[2][0] = a * vop_ref[2][0] + d[0][0] + d[2][0];
+ sprite_ref[2][1] = a * vop_ref[2][1] + d[0][1] + d[2][1];
+ } else {
+ sprite_ref[0][0] = (a >> 1) * (2 * vop_ref[0][0] + d[0][0]);
+ sprite_ref[0][1] = (a >> 1) * (2 * vop_ref[0][1] + d[0][1]);
+ sprite_ref[1][0] = (a >> 1) * (2 * vop_ref[1][0] + d[0][0] + d[1][0]);
+ sprite_ref[1][1] = (a >> 1) * (2 * vop_ref[1][1] + d[0][1] + d[1][1]);
+ sprite_ref[2][0] = (a >> 1) * (2 * vop_ref[2][0] + d[0][0] + d[2][0]);
+ sprite_ref[2][1] = (a >> 1) * (2 * vop_ref[2][1] + d[0][1] + d[2][1]);
+ }
+ /* sprite_ref[3][0] = (a >> 1) * (2 * vop_ref[3][0] + d[0][0] + d[1][0] + d[2][0] + d[3][0]);
+ * sprite_ref[3][1] = (a >> 1) * (2 * vop_ref[3][1] + d[0][1] + d[1][1] + d[2][1] + d[3][1]); */
+
+ /* this is mostly identical to the mpeg4 std (and is totally unreadable
+ * because of that...). Perhaps it should be reordered to be more readable.
+ * The idea behind this virtual_ref mess is to be able to use shifts later
+ * per pixel instead of divides so the distance between points is converted
+ * from w&h based to w2&h2 based which are of the 2^x form. */
+ virtual_ref[0][0] = 16 * (vop_ref[0][0] + w2) +
+ ROUNDED_DIV(((w - w2) *
+ (r * sprite_ref[0][0] - 16 * vop_ref[0][0]) +
+ w2 * (r * sprite_ref[1][0] - 16 * vop_ref[1][0])), w);
+ virtual_ref[0][1] = 16 * vop_ref[0][1] +
+ ROUNDED_DIV(((w - w2) *
+ (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) +
+ w2 * (r * sprite_ref[1][1] - 16 * vop_ref[1][1])), w);
+ virtual_ref[1][0] = 16 * vop_ref[0][0] +
+ ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][0] - 16 * vop_ref[0][0]) +
+ h2 * (r * sprite_ref[2][0] - 16 * vop_ref[2][0])), h);
+ virtual_ref[1][1] = 16 * (vop_ref[0][1] + h2) +
+ ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) +
+ h2 * (r * sprite_ref[2][1] - 16 * vop_ref[2][1])), h);
+
+ switch (ctx->num_sprite_warping_points) {
+ case 0:
+ sprite_offset[0][0] =
+ sprite_offset[0][1] =
+ sprite_offset[1][0] =
+ sprite_offset[1][1] = 0;
+ s->sprite_delta[0][0] = a;
+ s->sprite_delta[0][1] =
+ s->sprite_delta[1][0] = 0;
+ s->sprite_delta[1][1] = a;
+ ctx->sprite_shift[0] =
+ ctx->sprite_shift[1] = 0;
+ break;
+ case 1: // GMC only
+ sprite_offset[0][0] = sprite_ref[0][0] - a * vop_ref[0][0];
+ sprite_offset[0][1] = sprite_ref[0][1] - a * vop_ref[0][1];
+ sprite_offset[1][0] = ((sprite_ref[0][0] >> 1) | (sprite_ref[0][0] & 1)) -
+ a * (vop_ref[0][0] / 2);
+ sprite_offset[1][1] = ((sprite_ref[0][1] >> 1) | (sprite_ref[0][1] & 1)) -
+ a * (vop_ref[0][1] / 2);
+ s->sprite_delta[0][0] = a;
+ s->sprite_delta[0][1] =
+ s->sprite_delta[1][0] = 0;
+ s->sprite_delta[1][1] = a;
+ ctx->sprite_shift[0] =
+ ctx->sprite_shift[1] = 0;
+ break;
+ case 2:
+ sprite_offset[0][0] = (sprite_ref[0][0] * (1 << alpha + rho)) +
+ (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+ (-vop_ref[0][0]) +
+ (r * sprite_ref[0][1] - virtual_ref[0][1]) *
+ (-vop_ref[0][1]) + (1 << (alpha + rho - 1));
+ sprite_offset[0][1] = (sprite_ref[0][1] * (1 << alpha + rho)) +
+ (-r * sprite_ref[0][1] + virtual_ref[0][1]) *
+ (-vop_ref[0][0]) +
+ (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+ (-vop_ref[0][1]) + (1 << (alpha + rho - 1));
+ sprite_offset[1][0] = ((-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+ (-2 * vop_ref[0][0] + 1) +
+ (r * sprite_ref[0][1] - virtual_ref[0][1]) *
+ (-2 * vop_ref[0][1] + 1) + 2 * w2 * r *
+ sprite_ref[0][0] - 16 * w2 + (1 << (alpha + rho + 1)));
+ sprite_offset[1][1] = ((-r * sprite_ref[0][1] + virtual_ref[0][1]) *
+ (-2 * vop_ref[0][0] + 1) +
+ (-r * sprite_ref[0][0] + virtual_ref[0][0]) *
+ (-2 * vop_ref[0][1] + 1) + 2 * w2 * r *
+ sprite_ref[0][1] - 16 * w2 + (1 << (alpha + rho + 1)));
+ s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]);
+ s->sprite_delta[0][1] = (+r * sprite_ref[0][1] - virtual_ref[0][1]);
+ s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]);
+ s->sprite_delta[1][1] = (-r * sprite_ref[0][0] + virtual_ref[0][0]);
+
+ ctx->sprite_shift[0] = alpha + rho;
+ ctx->sprite_shift[1] = alpha + rho + 2;
+ break;
+ case 3:
+ min_ab = FFMIN(alpha, beta);
+ w3 = w2 >> min_ab;
+ h3 = h2 >> min_ab;
+ sprite_offset[0][0] = ((int64_t)sprite_ref[0][0] * (1 << (alpha + beta + rho - min_ab))) +
+ ((int64_t)-r * sprite_ref[0][0] + virtual_ref[0][0]) * h3 * (-vop_ref[0][0]) +
+ ((int64_t)-r * sprite_ref[0][0] + virtual_ref[1][0]) * w3 * (-vop_ref[0][1]) +
+ ((int64_t)1 << (alpha + beta + rho - min_ab - 1));
+ sprite_offset[0][1] = ((int64_t)sprite_ref[0][1] * (1 << (alpha + beta + rho - min_ab))) +
+ ((int64_t)-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3 * (-vop_ref[0][0]) +
+ ((int64_t)-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3 * (-vop_ref[0][1]) +
+ ((int64_t)1 << (alpha + beta + rho - min_ab - 1));
+ sprite_offset[1][0] = ((int64_t)-r * sprite_ref[0][0] + virtual_ref[0][0]) * h3 * (-2 * vop_ref[0][0] + 1) +
+ ((int64_t)-r * sprite_ref[0][0] + virtual_ref[1][0]) * w3 * (-2 * vop_ref[0][1] + 1) +
+ (int64_t)2 * w2 * h3 * r * sprite_ref[0][0] - 16 * w2 * h3 +
+ ((int64_t)1 << (alpha + beta + rho - min_ab + 1));
+ sprite_offset[1][1] = ((int64_t)-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3 * (-2 * vop_ref[0][0] + 1) +
+ ((int64_t)-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3 * (-2 * vop_ref[0][1] + 1) +
+ (int64_t)2 * w2 * h3 * r * sprite_ref[0][1] - 16 * w2 * h3 +
+ ((int64_t)1 << (alpha + beta + rho - min_ab + 1));
+ s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]) * h3;
+ s->sprite_delta[0][1] = (-r * sprite_ref[0][0] + virtual_ref[1][0]) * w3;
+ s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3;
+ s->sprite_delta[1][1] = (-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3;
+
+ ctx->sprite_shift[0] = alpha + beta + rho - min_ab;
+ ctx->sprite_shift[1] = alpha + beta + rho - min_ab + 2;
+ break;
+ }
+ /* try to simplify the situation */
+ if (s->sprite_delta[0][0] == a << ctx->sprite_shift[0] &&
+ s->sprite_delta[0][1] == 0 &&
+ s->sprite_delta[1][0] == 0 &&
+ s->sprite_delta[1][1] == a << ctx->sprite_shift[0]) {
+ sprite_offset[0][0] >>= ctx->sprite_shift[0];
+ sprite_offset[0][1] >>= ctx->sprite_shift[0];
+ sprite_offset[1][0] >>= ctx->sprite_shift[1];
+ sprite_offset[1][1] >>= ctx->sprite_shift[1];
+ s->sprite_delta[0][0] = a;
+ s->sprite_delta[0][1] = 0;
+ s->sprite_delta[1][0] = 0;
+ s->sprite_delta[1][1] = a;
+ ctx->sprite_shift[0] = 0;
+ ctx->sprite_shift[1] = 0;
+ s->real_sprite_warping_points = 1;
+ } else {
+ int shift_y = 16 - ctx->sprite_shift[0];
+ int shift_c = 16 - ctx->sprite_shift[1];
+
+ if (shift_c < 0 || shift_y < 0 ||
+ FFABS(sprite_offset[0][0]) >= INT_MAX >> shift_y ||
+ FFABS(sprite_offset[1][0]) >= INT_MAX >> shift_c ||
+ FFABS(sprite_offset[0][1]) >= INT_MAX >> shift_y ||
+ FFABS(sprite_offset[1][1]) >= INT_MAX >> shift_c
+ ) {
+ avpriv_request_sample(s->avctx, "Too large sprite shift or offset");
+ goto overflow;
+ }
+
+ for (i = 0; i < 2; i++) {
+ sprite_offset[0][i] *= 1 << shift_y;
+ sprite_offset[1][i] *= 1 << shift_c;
+ s->sprite_delta[0][i] *= 1 << shift_y;
+ s->sprite_delta[1][i] *= 1 << shift_y;
+ ctx->sprite_shift[i] = 16;
+
+ }
+ for (i = 0; i < 2; i++) {
+ int64_t sd[2] = {
+ s->sprite_delta[i][0] - a * (1LL<<16),
+ s->sprite_delta[i][1] - a * (1LL<<16)
+ };
+
+ if (llabs(sprite_offset[0][i] + s->sprite_delta[i][0] * (w+16LL)) >= INT_MAX ||
+ llabs(sprite_offset[0][i] + s->sprite_delta[i][1] * (h+16LL)) >= INT_MAX ||
+ llabs(sprite_offset[0][i] + s->sprite_delta[i][0] * (w+16LL) + s->sprite_delta[i][1] * (h+16LL)) >= INT_MAX ||
+ llabs(s->sprite_delta[i][0] * (w+16LL)) >= INT_MAX ||
+ llabs(s->sprite_delta[i][1] * (w+16LL)) >= INT_MAX ||
+ llabs(sd[0]) >= INT_MAX ||
+ llabs(sd[1]) >= INT_MAX ||
+ llabs(sprite_offset[0][i] + sd[0] * (w+16LL)) >= INT_MAX ||
+ llabs(sprite_offset[0][i] + sd[1] * (h+16LL)) >= INT_MAX ||
+ llabs(sprite_offset[0][i] + sd[0] * (w+16LL) + sd[1] * (h+16LL)) >= INT_MAX
+ ) {
+ avpriv_request_sample(s->avctx, "Overflow on sprite points");
+ goto overflow;
+ }
+ }
+ s->real_sprite_warping_points = ctx->num_sprite_warping_points;
+ }
+
+ s->sprite_offset[0][0] = sprite_offset[0][0];
+ s->sprite_offset[0][1] = sprite_offset[0][1];
+ s->sprite_offset[1][0] = sprite_offset[1][0];
+ s->sprite_offset[1][1] = sprite_offset[1][1];
+
+ return 0;
+overflow:
+ memset(s->sprite_offset, 0, sizeof(s->sprite_offset));
+ memset(s->sprite_delta, 0, sizeof(s->sprite_delta));
+ return AVERROR_PATCHWELCOME;
+}
+
+static int decode_new_pred(Mpeg4DecContext *ctx, GetBitContext *gb) {
+ int len = FFMIN(ctx->time_increment_bits + 3, 15);
+
+ get_bits(gb, len);
+ if (get_bits1(gb))
+ get_bits(gb, len);
+ check_marker(gb, "after new_pred");
+
+ return 0;
+}
+
+/**
+ * Decode the next video packet.
+ * @return <0 if something went wrong
+ */
+int ff_mpeg4_decode_video_packet_header(Mpeg4DecContext *ctx)
+{
+ MpegEncContext *s = &ctx->m;
+
+ int mb_num_bits = av_log2(s->mb_num - 1) + 1;
+ int header_extension = 0, mb_num, len;
+
+ /* is there enough space left for a video packet + header */
+ if (get_bits_count(&s->gb) > s->gb.size_in_bits - 20)
+ return -1;
+
+ for (len = 0; len < 32; len++)
+ if (get_bits1(&s->gb))
+ break;
+
+ if (len != ff_mpeg4_get_video_packet_prefix_length(s)) {
+ av_log(s->avctx, AV_LOG_ERROR, "marker does not match f_code\n");
+ return -1;
+ }
+
+ if (ctx->shape != RECT_SHAPE) {
+ header_extension = get_bits1(&s->gb);
+ // FIXME more stuff here
+ }
+
+ mb_num = get_bits(&s->gb, mb_num_bits);
+ if (mb_num >= s->mb_num) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "illegal mb_num in video packet (%d %d) \n", mb_num, s->mb_num);
+ return -1;
+ }
+
+ s->mb_x = mb_num % s->mb_width;
+ s->mb_y = mb_num / s->mb_width;
+
+ if (ctx->shape != BIN_ONLY_SHAPE) {
+ int qscale = get_bits(&s->gb, s->quant_precision);
+ if (qscale)
+ s->chroma_qscale = s->qscale = qscale;
+ }
+
+ if (ctx->shape == RECT_SHAPE)
+ header_extension = get_bits1(&s->gb);
+
+ if (header_extension) {
+ int time_incr = 0;
+
+ while (get_bits1(&s->gb) != 0)
+ time_incr++;
+
+ check_marker(&s->gb, "before time_increment in video packed header");
+ skip_bits(&s->gb, ctx->time_increment_bits); /* time_increment */
+ check_marker(&s->gb, "before vop_coding_type in video packed header");
+
+ skip_bits(&s->gb, 2); /* vop coding type */
+ // FIXME not rect stuff here
+
+ if (ctx->shape != BIN_ONLY_SHAPE) {
+ skip_bits(&s->gb, 3); /* intra dc vlc threshold */
+ // FIXME don't just ignore everything
+ if (s->pict_type == AV_PICTURE_TYPE_S &&
+ ctx->vol_sprite_usage == GMC_SPRITE) {
+ if (mpeg4_decode_sprite_trajectory(ctx, &s->gb) < 0)
+ return AVERROR_INVALIDDATA;
+ av_log(s->avctx, AV_LOG_ERROR, "untested\n");
+ }
+
+ // FIXME reduced res stuff here
+
+ if (s->pict_type != AV_PICTURE_TYPE_I) {
+ int f_code = get_bits(&s->gb, 3); /* fcode_for */
+ if (f_code == 0)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Error, video packet header damaged (f_code=0)\n");
+ }
+ if (s->pict_type == AV_PICTURE_TYPE_B) {
+ int b_code = get_bits(&s->gb, 3);
+ if (b_code == 0)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Error, video packet header damaged (b_code=0)\n");
+ }
+ }
+ }
+ if (ctx->new_pred)
+ decode_new_pred(ctx, &s->gb);
+
+ return 0;
+}
+
+/**
+ * Get the average motion vector for a GMC MB.
+ * @param n either 0 for the x component or 1 for y
+ * @return the average MV for a GMC MB
+ */
+static inline int get_amv(Mpeg4DecContext *ctx, int n)
+{
+ MpegEncContext *s = &ctx->m;
+ int x, y, mb_v, sum, dx, dy, shift;
+ int len = 1 << (s->f_code + 4);
+ const int a = s->sprite_warping_accuracy;
+
+ if (s->workaround_bugs & FF_BUG_AMV)
+ len >>= s->quarter_sample;
+
+ if (s->real_sprite_warping_points == 1) {
+ if (ctx->divx_version == 500 && ctx->divx_build == 413)
+ sum = s->sprite_offset[0][n] / (1 << (a - s->quarter_sample));
+ else
+ sum = RSHIFT(s->sprite_offset[0][n] * (1 << s->quarter_sample), a);
+ } else {
+ dx = s->sprite_delta[n][0];
+ dy = s->sprite_delta[n][1];
+ shift = ctx->sprite_shift[0];
+ if (n)
+ dy -= 1 << (shift + a + 1);
+ else
+ dx -= 1 << (shift + a + 1);
+ mb_v = s->sprite_offset[0][n] + dx * s->mb_x * 16 + dy * s->mb_y * 16;
+
+ sum = 0;
+ for (y = 0; y < 16; y++) {
+ int v;
+
+ v = mb_v + dy * y;
+ // FIXME optimize
+ for (x = 0; x < 16; x++) {
+ sum += v >> shift;
+ v += dx;
+ }
+ }
+ sum = RSHIFT(sum, a + 8 - s->quarter_sample);
+ }
+
+ if (sum < -len)
+ sum = -len;
+ else if (sum >= len)
+ sum = len - 1;
+
+ return sum;
+}
+
+/**
+ * Decode the dc value.
+ * @param n block index (0-3 are luma, 4-5 are chroma)
+ * @param dir_ptr the prediction direction will be stored here
+ * @return the quantized dc
+ */
+static inline int mpeg4_decode_dc(MpegEncContext *s, int n, int *dir_ptr)
+{
+ int level, code;
+
+ if (n < 4)
+ code = get_vlc2(&s->gb, dc_lum.table, DC_VLC_BITS, 1);
+ else
+ code = get_vlc2(&s->gb, dc_chrom.table, DC_VLC_BITS, 1);
+
+ if (code < 0 || code > 9 /* && s->nbit < 9 */) {
+ av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n");
+ return -1;
+ }
+
+ if (code == 0) {
+ level = 0;
+ } else {
+ if (IS_3IV1) {
+ if (code == 1)
+ level = 2 * get_bits1(&s->gb) - 1;
+ else {
+ if (get_bits1(&s->gb))
+ level = get_bits(&s->gb, code - 1) + (1 << (code - 1));
+ else
+ level = -get_bits(&s->gb, code - 1) - (1 << (code - 1));
+ }
+ } else {
+ level = get_xbits(&s->gb, code);
+ }
+
+ if (code > 8) {
+ if (get_bits1(&s->gb) == 0) { /* marker */
+ if (s->avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT)) {
+ av_log(s->avctx, AV_LOG_ERROR, "dc marker bit missing\n");
+ return -1;
+ }
+ }
+ }
+ }
+
+ return ff_mpeg4_pred_dc(s, n, level, dir_ptr, 0);
+}
+
+/**
+ * Decode first partition.
+ * @return number of MBs decoded or <0 if an error occurred
+ */
+static int mpeg4_decode_partition_a(Mpeg4DecContext *ctx)
+{
+ MpegEncContext *s = &ctx->m;
+ int mb_num = 0;
+ static const int8_t quant_tab[4] = { -1, -2, 1, 2 };
+
+ /* decode first partition */
+ s->first_slice_line = 1;
+ for (; s->mb_y < s->mb_height; s->mb_y++) {
+ ff_init_block_index(s);
+ for (; s->mb_x < s->mb_width; s->mb_x++) {
+ const int xy = s->mb_x + s->mb_y * s->mb_stride;
+ int cbpc;
+ int dir = 0;
+
+ mb_num++;
+ ff_update_block_index(s);
+ if (s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y + 1)
+ s->first_slice_line = 0;
+
+ if (s->pict_type == AV_PICTURE_TYPE_I) {
+ int i;
+
+ do {
+ if (show_bits_long(&s->gb, 19) == DC_MARKER)
+ return mb_num - 1;
+
+ cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
+ if (cbpc < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "mcbpc corrupted at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ } while (cbpc == 8);
+
+ s->cbp_table[xy] = cbpc & 3;
+ s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
+ s->mb_intra = 1;
+
+ if (cbpc & 4)
+ ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
+
+ s->current_picture.qscale_table[xy] = s->qscale;
+
+ s->mbintra_table[xy] = 1;
+ for (i = 0; i < 6; i++) {
+ int dc_pred_dir;
+ int dc = mpeg4_decode_dc(s, i, &dc_pred_dir);
+ if (dc < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "DC corrupted at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ dir <<= 1;
+ if (dc_pred_dir)
+ dir |= 1;
+ }
+ s->pred_dir_table[xy] = dir;
+ } else { /* P/S_TYPE */
+ int mx, my, pred_x, pred_y, bits;
+ int16_t *const mot_val = s->current_picture.motion_val[0][s->block_index[0]];
+ const int stride = s->b8_stride * 2;
+
+try_again:
+ bits = show_bits(&s->gb, 17);
+ if (bits == MOTION_MARKER)
+ return mb_num - 1;
+
+ skip_bits1(&s->gb);
+ if (bits & 0x10000) {
+ /* skip mb */
+ if (s->pict_type == AV_PICTURE_TYPE_S &&
+ ctx->vol_sprite_usage == GMC_SPRITE) {
+ s->current_picture.mb_type[xy] = MB_TYPE_SKIP |
+ MB_TYPE_16x16 |
+ MB_TYPE_GMC |
+ MB_TYPE_L0;
+ mx = get_amv(ctx, 0);
+ my = get_amv(ctx, 1);
+ } else {
+ s->current_picture.mb_type[xy] = MB_TYPE_SKIP |
+ MB_TYPE_16x16 |
+ MB_TYPE_L0;
+ mx = my = 0;
+ }
+ mot_val[0] =
+ mot_val[2] =
+ mot_val[0 + stride] =
+ mot_val[2 + stride] = mx;
+ mot_val[1] =
+ mot_val[3] =
+ mot_val[1 + stride] =
+ mot_val[3 + stride] = my;
+
+ if (s->mbintra_table[xy])
+ ff_clean_intra_table_entries(s);
+ continue;
+ }
+
+ cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
+ if (cbpc < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "mcbpc corrupted at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ if (cbpc == 20)
+ goto try_again;
+
+ s->cbp_table[xy] = cbpc & (8 + 3); // 8 is dquant
+
+ s->mb_intra = ((cbpc & 4) != 0);
+
+ if (s->mb_intra) {
+ s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
+ s->mbintra_table[xy] = 1;
+ mot_val[0] =
+ mot_val[2] =
+ mot_val[0 + stride] =
+ mot_val[2 + stride] = 0;
+ mot_val[1] =
+ mot_val[3] =
+ mot_val[1 + stride] =
+ mot_val[3 + stride] = 0;
+ } else {
+ if (s->mbintra_table[xy])
+ ff_clean_intra_table_entries(s);
+
+ if (s->pict_type == AV_PICTURE_TYPE_S &&
+ ctx->vol_sprite_usage == GMC_SPRITE &&
+ (cbpc & 16) == 0)
+ s->mcsel = get_bits1(&s->gb);
+ else
+ s->mcsel = 0;
+
+ if ((cbpc & 16) == 0) {
+ /* 16x16 motion prediction */
+
+ ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
+ if (!s->mcsel) {
+ mx = ff_h263_decode_motion(s, pred_x, s->f_code);
+ if (mx >= 0xffff)
+ return -1;
+
+ my = ff_h263_decode_motion(s, pred_y, s->f_code);
+ if (my >= 0xffff)
+ return -1;
+ s->current_picture.mb_type[xy] = MB_TYPE_16x16 |
+ MB_TYPE_L0;
+ } else {
+ mx = get_amv(ctx, 0);
+ my = get_amv(ctx, 1);
+ s->current_picture.mb_type[xy] = MB_TYPE_16x16 |
+ MB_TYPE_GMC |
+ MB_TYPE_L0;
+ }
+
+ mot_val[0] =
+ mot_val[2] =
+ mot_val[0 + stride] =
+ mot_val[2 + stride] = mx;
+ mot_val[1] =
+ mot_val[3] =
+ mot_val[1 + stride] =
+ mot_val[3 + stride] = my;
+ } else {
+ int i;
+ s->current_picture.mb_type[xy] = MB_TYPE_8x8 |
+ MB_TYPE_L0;
+ for (i = 0; i < 4; i++) {
+ int16_t *mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
+ mx = ff_h263_decode_motion(s, pred_x, s->f_code);
+ if (mx >= 0xffff)
+ return -1;
+
+ my = ff_h263_decode_motion(s, pred_y, s->f_code);
+ if (my >= 0xffff)
+ return -1;
+ mot_val[0] = mx;
+ mot_val[1] = my;
+ }
+ }
+ }
+ }
+ }
+ s->mb_x = 0;
+ }
+
+ return mb_num;
+}
+
+/**
+ * decode second partition.
+ * @return <0 if an error occurred
+ */
+static int mpeg4_decode_partition_b(MpegEncContext *s, int mb_count)
+{
+ int mb_num = 0;
+ static const int8_t quant_tab[4] = { -1, -2, 1, 2 };
+
+ s->mb_x = s->resync_mb_x;
+ s->first_slice_line = 1;
+ for (s->mb_y = s->resync_mb_y; mb_num < mb_count; s->mb_y++) {
+ ff_init_block_index(s);
+ for (; mb_num < mb_count && s->mb_x < s->mb_width; s->mb_x++) {
+ const int xy = s->mb_x + s->mb_y * s->mb_stride;
+
+ mb_num++;
+ ff_update_block_index(s);
+ if (s->mb_x == s->resync_mb_x && s->mb_y == s->resync_mb_y + 1)
+ s->first_slice_line = 0;
+
+ if (s->pict_type == AV_PICTURE_TYPE_I) {
+ int ac_pred = get_bits1(&s->gb);
+ int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+ if (cbpy < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+
+ s->cbp_table[xy] |= cbpy << 2;
+ s->current_picture.mb_type[xy] |= ac_pred * MB_TYPE_ACPRED;
+ } else { /* P || S_TYPE */
+ if (IS_INTRA(s->current_picture.mb_type[xy])) {
+ int i;
+ int dir = 0;
+ int ac_pred = get_bits1(&s->gb);
+ int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+
+ if (cbpy < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "I cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+
+ if (s->cbp_table[xy] & 8)
+ ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
+ s->current_picture.qscale_table[xy] = s->qscale;
+
+ for (i = 0; i < 6; i++) {
+ int dc_pred_dir;
+ int dc = mpeg4_decode_dc(s, i, &dc_pred_dir);
+ if (dc < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "DC corrupted at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ dir <<= 1;
+ if (dc_pred_dir)
+ dir |= 1;
+ }
+ s->cbp_table[xy] &= 3; // remove dquant
+ s->cbp_table[xy] |= cbpy << 2;
+ s->current_picture.mb_type[xy] |= ac_pred * MB_TYPE_ACPRED;
+ s->pred_dir_table[xy] = dir;
+ } else if (IS_SKIP(s->current_picture.mb_type[xy])) {
+ s->current_picture.qscale_table[xy] = s->qscale;
+ s->cbp_table[xy] = 0;
+ } else {
+ int cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+
+ if (cbpy < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "P cbpy corrupted at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+
+ if (s->cbp_table[xy] & 8)
+ ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
+ s->current_picture.qscale_table[xy] = s->qscale;
+
+ s->cbp_table[xy] &= 3; // remove dquant
+ s->cbp_table[xy] |= (cbpy ^ 0xf) << 2;
+ }
+ }
+ }
+ if (mb_num >= mb_count)
+ return 0;
+ s->mb_x = 0;
+ }
+ return 0;
+}
+
+/**
+ * Decode the first and second partition.
+ * @return <0 if error (and sets error type in the error_status_table)
+ */
+int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx)
+{
+ MpegEncContext *s = &ctx->m;
+ int mb_num;
+ const int part_a_error = s->pict_type == AV_PICTURE_TYPE_I ? (ER_DC_ERROR | ER_MV_ERROR) : ER_MV_ERROR;
+ const int part_a_end = s->pict_type == AV_PICTURE_TYPE_I ? (ER_DC_END | ER_MV_END) : ER_MV_END;
+
+ mb_num = mpeg4_decode_partition_a(ctx);
+ if (mb_num <= 0) {
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x, s->mb_y, part_a_error);
+ return -1;
+ }
+
+ if (s->resync_mb_x + s->resync_mb_y * s->mb_width + mb_num > s->mb_num) {
+ av_log(s->avctx, AV_LOG_ERROR, "slice below monitor ...\n");
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x, s->mb_y, part_a_error);
+ return -1;
+ }
+
+ s->mb_num_left = mb_num;
+
+ if (s->pict_type == AV_PICTURE_TYPE_I) {
+ while (show_bits(&s->gb, 9) == 1)
+ skip_bits(&s->gb, 9);
+ if (get_bits_long(&s->gb, 19) != DC_MARKER) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "marker missing after first I partition at %d %d\n",
+ s->mb_x, s->mb_y);
+ return -1;
+ }
+ } else {
+ while (show_bits(&s->gb, 10) == 1)
+ skip_bits(&s->gb, 10);
+ if (get_bits(&s->gb, 17) != MOTION_MARKER) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "marker missing after first P partition at %d %d\n",
+ s->mb_x, s->mb_y);
+ return -1;
+ }
+ }
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x - 1, s->mb_y, part_a_end);
+
+ if (mpeg4_decode_partition_b(s, mb_num) < 0) {
+ if (s->pict_type == AV_PICTURE_TYPE_P)
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x, s->mb_y, ER_DC_ERROR);
+ return -1;
+ } else {
+ if (s->pict_type == AV_PICTURE_TYPE_P)
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y,
+ s->mb_x - 1, s->mb_y, ER_DC_END);
+ }
+
+ return 0;
+}
+
+/**
+ * Decode a block.
+ * @return <0 if an error occurred
+ */
+static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block,
+ int n, int coded, int intra, int rvlc)
+{
+ MpegEncContext *s = &ctx->m;
+ int level, i, last, run, qmul, qadd;
+ int av_uninit(dc_pred_dir);
+ RLTable *rl;
+ RL_VLC_ELEM *rl_vlc;
+ const uint8_t *scan_table;
+
+ // Note intra & rvlc should be optimized away if this is inlined
+
+ if (intra) {
+ if (ctx->use_intra_dc_vlc) {
+ /* DC coef */
+ if (s->partitioned_frame) {
+ level = s->dc_val[0][s->block_index[n]];
+ if (n < 4)
+ level = FASTDIV((level + (s->y_dc_scale >> 1)), s->y_dc_scale);
+ else
+ level = FASTDIV((level + (s->c_dc_scale >> 1)), s->c_dc_scale);
+ dc_pred_dir = (s->pred_dir_table[s->mb_x + s->mb_y * s->mb_stride] << n) & 32;
+ } else {
+ level = mpeg4_decode_dc(s, n, &dc_pred_dir);
+ if (level < 0)
+ return -1;
+ }
+ block[0] = level;
+ i = 0;
+ } else {
+ i = -1;
+ ff_mpeg4_pred_dc(s, n, 0, &dc_pred_dir, 0);
+ }
+ if (!coded)
+ goto not_coded;
+
+ if (rvlc) {
+ rl = &ff_rvlc_rl_intra;
+ rl_vlc = ff_rvlc_rl_intra.rl_vlc[0];
+ } else {
+ rl = &ff_mpeg4_rl_intra;
+ rl_vlc = ff_mpeg4_rl_intra.rl_vlc[0];
+ }
+ if (s->ac_pred) {
+ if (dc_pred_dir == 0)
+ scan_table = s->intra_v_scantable.permutated; /* left */
+ else
+ scan_table = s->intra_h_scantable.permutated; /* top */
+ } else {
+ scan_table = s->intra_scantable.permutated;
+ }
+ qmul = 1;
+ qadd = 0;
+ } else {
+ i = -1;
+ if (!coded) {
+ s->block_last_index[n] = i;
+ return 0;
+ }
+ if (rvlc)
+ rl = &ff_rvlc_rl_inter;
+ else
+ rl = &ff_h263_rl_inter;
+
+ scan_table = s->intra_scantable.permutated;
+
+ if (s->mpeg_quant) {
+ qmul = 1;
+ qadd = 0;
+ if (rvlc)
+ rl_vlc = ff_rvlc_rl_inter.rl_vlc[0];
+ else
+ rl_vlc = ff_h263_rl_inter.rl_vlc[0];
+ } else {
+ qmul = s->qscale << 1;
+ qadd = (s->qscale - 1) | 1;
+ if (rvlc)
+ rl_vlc = ff_rvlc_rl_inter.rl_vlc[s->qscale];
+ else
+ rl_vlc = ff_h263_rl_inter.rl_vlc[s->qscale];
+ }
+ }
+ {
+ OPEN_READER(re, &s->gb);
+ for (;;) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0);
+ if (level == 0) {
+ /* escape */
+ if (rvlc) {
+ if (SHOW_UBITS(re, &s->gb, 1) == 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "1. marker bit missing in rvlc esc\n");
+ return -1;
+ }
+ SKIP_CACHE(re, &s->gb, 1);
+
+ last = SHOW_UBITS(re, &s->gb, 1);
+ SKIP_CACHE(re, &s->gb, 1);
+ run = SHOW_UBITS(re, &s->gb, 6);
+ SKIP_COUNTER(re, &s->gb, 1 + 1 + 6);
+ UPDATE_CACHE(re, &s->gb);
+
+ if (SHOW_UBITS(re, &s->gb, 1) == 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "2. marker bit missing in rvlc esc\n");
+ return -1;
+ }
+ SKIP_CACHE(re, &s->gb, 1);
+
+ level = SHOW_UBITS(re, &s->gb, 11);
+ SKIP_CACHE(re, &s->gb, 11);
+
+ if (SHOW_UBITS(re, &s->gb, 5) != 0x10) {
+ av_log(s->avctx, AV_LOG_ERROR, "reverse esc missing\n");
+ return -1;
+ }
+ SKIP_CACHE(re, &s->gb, 5);
+
+ level = level * qmul + qadd;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ SKIP_COUNTER(re, &s->gb, 1 + 11 + 5 + 1);
+
+ i += run + 1;
+ if (last)
+ i += 192;
+ } else {
+ int cache;
+ cache = GET_CACHE(re, &s->gb);
+
+ if (IS_3IV1)
+ cache ^= 0xC0000000;
+
+ if (cache & 0x80000000) {
+ if (cache & 0x40000000) {
+ /* third escape */
+ SKIP_CACHE(re, &s->gb, 2);
+ last = SHOW_UBITS(re, &s->gb, 1);
+ SKIP_CACHE(re, &s->gb, 1);
+ run = SHOW_UBITS(re, &s->gb, 6);
+ SKIP_COUNTER(re, &s->gb, 2 + 1 + 6);
+ UPDATE_CACHE(re, &s->gb);
+
+ if (IS_3IV1) {
+ level = SHOW_SBITS(re, &s->gb, 12);
+ LAST_SKIP_BITS(re, &s->gb, 12);
+ } else {
+ if (SHOW_UBITS(re, &s->gb, 1) == 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "1. marker bit missing in 3. esc\n");
+ if (!(s->avctx->err_recognition & AV_EF_IGNORE_ERR))
+ return -1;
+ }
+ SKIP_CACHE(re, &s->gb, 1);
+
+ level = SHOW_SBITS(re, &s->gb, 12);
+ SKIP_CACHE(re, &s->gb, 12);
+
+ if (SHOW_UBITS(re, &s->gb, 1) == 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "2. marker bit missing in 3. esc\n");
+ if (!(s->avctx->err_recognition & AV_EF_IGNORE_ERR))
+ return -1;
+ }
+
+ SKIP_COUNTER(re, &s->gb, 1 + 12 + 1);
+ }
+
+#if 0
+ if (s->error_recognition >= FF_ER_COMPLIANT) {
+ const int abs_level= FFABS(level);
+ if (abs_level<=MAX_LEVEL && run<=MAX_RUN) {
+ const int run1= run - rl->max_run[last][abs_level] - 1;
+ if (abs_level <= rl->max_level[last][run]) {
+ av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n");
+ return -1;
+ }
+ if (s->error_recognition > FF_ER_COMPLIANT) {
+ if (abs_level <= rl->max_level[last][run]*2) {
+ av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n");
+ return -1;
+ }
+ if (run1 >= 0 && abs_level <= rl->max_level[last][run1]) {
+ av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 2 encoding possible\n");
+ return -1;
+ }
+ }
+ }
+ }
+#endif
+ if (level > 0)
+ level = level * qmul + qadd;
+ else
+ level = level * qmul - qadd;
+
+ if ((unsigned)(level + 2048) > 4095) {
+ if (s->avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_AGGRESSIVE)) {
+ if (level > 2560 || level < -2560) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "|level| overflow in 3. esc, qp=%d\n",
+ s->qscale);
+ return -1;
+ }
+ }
+ level = level < 0 ? -2048 : 2047;
+ }
+
+ i += run + 1;
+ if (last)
+ i += 192;
+ } else {
+ /* second escape */
+ SKIP_BITS(re, &s->gb, 2);
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
+ i += run + rl->max_run[run >> 7][level / qmul] + 1; // FIXME opt indexing
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ }
+ } else {
+ /* first escape */
+ SKIP_BITS(re, &s->gb, 1);
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
+ i += run;
+ level = level + rl->max_level[run >> 7][(run - 1) & 63] * qmul; // FIXME opt indexing
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ }
+ }
+ } else {
+ i += run;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+ }
+ ff_tlog(s->avctx, "dct[%d][%d] = %- 4d end?:%d\n", scan_table[i&63]&7, scan_table[i&63] >> 3, level, i>62);
+ if (i > 62) {
+ i -= 192;
+ if (i & (~63)) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+
+ block[scan_table[i]] = level;
+ break;
+ }
+
+ block[scan_table[i]] = level;
+ }
+ CLOSE_READER(re, &s->gb);
+ }
+
+not_coded:
+ if (intra) {
+ if (!ctx->use_intra_dc_vlc) {
+ block[0] = ff_mpeg4_pred_dc(s, n, block[0], &dc_pred_dir, 0);
+
+ i -= i >> 31; // if (i == -1) i = 0;
+ }
+
+ ff_mpeg4_pred_ac(s, block, n, dc_pred_dir);
+ if (s->ac_pred)
+ i = 63; // FIXME not optimal
+ }
+ s->block_last_index[n] = i;
+ return 0;
+}
+
+/**
+ * decode partition C of one MB.
+ * @return <0 if an error occurred
+ */
+static int mpeg4_decode_partitioned_mb(MpegEncContext *s, int16_t block[6][64])
+{
+ Mpeg4DecContext *ctx = (Mpeg4DecContext *)s;
+ int cbp, mb_type;
+ const int xy = s->mb_x + s->mb_y * s->mb_stride;
+
+ mb_type = s->current_picture.mb_type[xy];
+ cbp = s->cbp_table[xy];
+
+ ctx->use_intra_dc_vlc = s->qscale < ctx->intra_dc_threshold;
+
+ if (s->current_picture.qscale_table[xy] != s->qscale)
+ ff_set_qscale(s, s->current_picture.qscale_table[xy]);
+
+ if (s->pict_type == AV_PICTURE_TYPE_P ||
+ s->pict_type == AV_PICTURE_TYPE_S) {
+ int i;
+ for (i = 0; i < 4; i++) {
+ s->mv[0][i][0] = s->current_picture.motion_val[0][s->block_index[i]][0];
+ s->mv[0][i][1] = s->current_picture.motion_val[0][s->block_index[i]][1];
+ }
+ s->mb_intra = IS_INTRA(mb_type);
+
+ if (IS_SKIP(mb_type)) {
+ /* skip mb */
+ for (i = 0; i < 6; i++)
+ s->block_last_index[i] = -1;
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ if (s->pict_type == AV_PICTURE_TYPE_S
+ && ctx->vol_sprite_usage == GMC_SPRITE) {
+ s->mcsel = 1;
+ s->mb_skipped = 0;
+ } else {
+ s->mcsel = 0;
+ s->mb_skipped = 1;
+ }
+ } else if (s->mb_intra) {
+ s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]);
+ } else if (!s->mb_intra) {
+ // s->mcsel = 0; // FIXME do we need to init that?
+
+ s->mv_dir = MV_DIR_FORWARD;
+ if (IS_8X8(mb_type)) {
+ s->mv_type = MV_TYPE_8X8;
+ } else {
+ s->mv_type = MV_TYPE_16X16;
+ }
+ }
+ } else { /* I-Frame */
+ s->mb_intra = 1;
+ s->ac_pred = IS_ACPRED(s->current_picture.mb_type[xy]);
+ }
+
+ if (!IS_SKIP(mb_type)) {
+ int i;
+ s->bdsp.clear_blocks(s->block[0]);
+ /* decode each block */
+ for (i = 0; i < 6; i++) {
+ if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, s->mb_intra, ctx->rvlc) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "texture corrupted at %d %d %d\n",
+ s->mb_x, s->mb_y, s->mb_intra);
+ return -1;
+ }
+ cbp += cbp;
+ }
+ }
+
+ /* per-MB end of slice check */
+ if (--s->mb_num_left <= 0) {
+ if (mpeg4_is_resync(ctx))
+ return SLICE_END;
+ else
+ return SLICE_NOEND;
+ } else {
+ if (mpeg4_is_resync(ctx)) {
+ const int delta = s->mb_x + 1 == s->mb_width ? 2 : 1;
+ if (s->cbp_table[xy + delta])
+ return SLICE_END;
+ }
+ return SLICE_OK;
+ }
+}
+
+static int mpeg4_decode_mb(MpegEncContext *s, int16_t block[6][64])
+{
+ Mpeg4DecContext *ctx = (Mpeg4DecContext *)s;
+ int cbpc, cbpy, i, cbp, pred_x, pred_y, mx, my, dquant;
+ int16_t *mot_val;
+ static const int8_t quant_tab[4] = { -1, -2, 1, 2 };
+ const int xy = s->mb_x + s->mb_y * s->mb_stride;
+
+ av_assert2(s->h263_pred);
+
+ if (s->pict_type == AV_PICTURE_TYPE_P ||
+ s->pict_type == AV_PICTURE_TYPE_S) {
+ do {
+ if (get_bits1(&s->gb)) {
+ /* skip mb */
+ s->mb_intra = 0;
+ for (i = 0; i < 6; i++)
+ s->block_last_index[i] = -1;
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ if (s->pict_type == AV_PICTURE_TYPE_S &&
+ ctx->vol_sprite_usage == GMC_SPRITE) {
+ s->current_picture.mb_type[xy] = MB_TYPE_SKIP |
+ MB_TYPE_GMC |
+ MB_TYPE_16x16 |
+ MB_TYPE_L0;
+ s->mcsel = 1;
+ s->mv[0][0][0] = get_amv(ctx, 0);
+ s->mv[0][0][1] = get_amv(ctx, 1);
+ s->mb_skipped = 0;
+ } else {
+ s->current_picture.mb_type[xy] = MB_TYPE_SKIP |
+ MB_TYPE_16x16 |
+ MB_TYPE_L0;
+ s->mcsel = 0;
+ s->mv[0][0][0] = 0;
+ s->mv[0][0][1] = 0;
+ s->mb_skipped = 1;
+ }
+ goto end;
+ }
+ cbpc = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
+ if (cbpc < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "mcbpc damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ } while (cbpc == 20);
+
+ s->bdsp.clear_blocks(s->block[0]);
+ dquant = cbpc & 8;
+ s->mb_intra = ((cbpc & 4) != 0);
+ if (s->mb_intra)
+ goto intra;
+
+ if (s->pict_type == AV_PICTURE_TYPE_S &&
+ ctx->vol_sprite_usage == GMC_SPRITE && (cbpc & 16) == 0)
+ s->mcsel = get_bits1(&s->gb);
+ else
+ s->mcsel = 0;
+ cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1) ^ 0x0F;
+ if (cbpy < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "P cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
+ return AVERROR_INVALIDDATA;
+ }
+
+ cbp = (cbpc & 3) | (cbpy << 2);
+ if (dquant)
+ ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
+ if ((!s->progressive_sequence) &&
+ (cbp || (s->workaround_bugs & FF_BUG_XVID_ILACE)))
+ s->interlaced_dct = get_bits1(&s->gb);
+
+ s->mv_dir = MV_DIR_FORWARD;
+ if ((cbpc & 16) == 0) {
+ if (s->mcsel) {
+ s->current_picture.mb_type[xy] = MB_TYPE_GMC |
+ MB_TYPE_16x16 |
+ MB_TYPE_L0;
+ /* 16x16 global motion prediction */
+ s->mv_type = MV_TYPE_16X16;
+ mx = get_amv(ctx, 0);
+ my = get_amv(ctx, 1);
+ s->mv[0][0][0] = mx;
+ s->mv[0][0][1] = my;
+ } else if ((!s->progressive_sequence) && get_bits1(&s->gb)) {
+ s->current_picture.mb_type[xy] = MB_TYPE_16x8 |
+ MB_TYPE_L0 |
+ MB_TYPE_INTERLACED;
+ /* 16x8 field motion prediction */
+ s->mv_type = MV_TYPE_FIELD;
+
+ s->field_select[0][0] = get_bits1(&s->gb);
+ s->field_select[0][1] = get_bits1(&s->gb);
+
+ ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
+
+ for (i = 0; i < 2; i++) {
+ mx = ff_h263_decode_motion(s, pred_x, s->f_code);
+ if (mx >= 0xffff)
+ return -1;
+
+ my = ff_h263_decode_motion(s, pred_y / 2, s->f_code);
+ if (my >= 0xffff)
+ return -1;
+
+ s->mv[0][i][0] = mx;
+ s->mv[0][i][1] = my;
+ }
+ } else {
+ s->current_picture.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0;
+ /* 16x16 motion prediction */
+ s->mv_type = MV_TYPE_16X16;
+ ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
+ mx = ff_h263_decode_motion(s, pred_x, s->f_code);
+
+ if (mx >= 0xffff)
+ return -1;
+
+ my = ff_h263_decode_motion(s, pred_y, s->f_code);
+
+ if (my >= 0xffff)
+ return -1;
+ s->mv[0][0][0] = mx;
+ s->mv[0][0][1] = my;
+ }
+ } else {
+ s->current_picture.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0;
+ s->mv_type = MV_TYPE_8X8;
+ for (i = 0; i < 4; i++) {
+ mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y);
+ mx = ff_h263_decode_motion(s, pred_x, s->f_code);
+ if (mx >= 0xffff)
+ return -1;
+
+ my = ff_h263_decode_motion(s, pred_y, s->f_code);
+ if (my >= 0xffff)
+ return -1;
+ s->mv[0][i][0] = mx;
+ s->mv[0][i][1] = my;
+ mot_val[0] = mx;
+ mot_val[1] = my;
+ }
+ }
+ } else if (s->pict_type == AV_PICTURE_TYPE_B) {
+ int modb1; // first bit of modb
+ int modb2; // second bit of modb
+ int mb_type;
+
+ s->mb_intra = 0; // B-frames never contain intra blocks
+ s->mcsel = 0; // ... true gmc blocks
+
+ if (s->mb_x == 0) {
+ for (i = 0; i < 2; i++) {
+ s->last_mv[i][0][0] =
+ s->last_mv[i][0][1] =
+ s->last_mv[i][1][0] =
+ s->last_mv[i][1][1] = 0;
+ }
+
+ ff_thread_await_progress(&s->next_picture_ptr->tf, s->mb_y, 0);
+ }
+
+ /* if we skipped it in the future P Frame than skip it now too */
+ s->mb_skipped = s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]; // Note, skiptab=0 if last was GMC
+
+ if (s->mb_skipped) {
+ /* skip mb */
+ for (i = 0; i < 6; i++)
+ s->block_last_index[i] = -1;
+
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ s->mv[0][0][0] =
+ s->mv[0][0][1] =
+ s->mv[1][0][0] =
+ s->mv[1][0][1] = 0;
+ s->current_picture.mb_type[xy] = MB_TYPE_SKIP |
+ MB_TYPE_16x16 |
+ MB_TYPE_L0;
+ goto end;
+ }
+
+ modb1 = get_bits1(&s->gb);
+ if (modb1) {
+ // like MB_TYPE_B_DIRECT but no vectors coded
+ mb_type = MB_TYPE_DIRECT2 | MB_TYPE_SKIP | MB_TYPE_L0L1;
+ cbp = 0;
+ } else {
+ modb2 = get_bits1(&s->gb);
+ mb_type = get_vlc2(&s->gb, mb_type_b_vlc.table, MB_TYPE_B_VLC_BITS, 1);
+ if (mb_type < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "illegal MB_type\n");
+ return -1;
+ }
+ mb_type = mb_type_b_map[mb_type];
+ if (modb2) {
+ cbp = 0;
+ } else {
+ s->bdsp.clear_blocks(s->block[0]);
+ cbp = get_bits(&s->gb, 6);
+ }
+
+ if ((!IS_DIRECT(mb_type)) && cbp) {
+ if (get_bits1(&s->gb))
+ ff_set_qscale(s, s->qscale + get_bits1(&s->gb) * 4 - 2);
+ }
+
+ if (!s->progressive_sequence) {
+ if (cbp)
+ s->interlaced_dct = get_bits1(&s->gb);
+
+ if (!IS_DIRECT(mb_type) && get_bits1(&s->gb)) {
+ mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
+ mb_type &= ~MB_TYPE_16x16;
+
+ if (USES_LIST(mb_type, 0)) {
+ s->field_select[0][0] = get_bits1(&s->gb);
+ s->field_select[0][1] = get_bits1(&s->gb);
+ }
+ if (USES_LIST(mb_type, 1)) {
+ s->field_select[1][0] = get_bits1(&s->gb);
+ s->field_select[1][1] = get_bits1(&s->gb);
+ }
+ }
+ }
+
+ s->mv_dir = 0;
+ if ((mb_type & (MB_TYPE_DIRECT2 | MB_TYPE_INTERLACED)) == 0) {
+ s->mv_type = MV_TYPE_16X16;
+
+ if (USES_LIST(mb_type, 0)) {
+ s->mv_dir = MV_DIR_FORWARD;
+
+ mx = ff_h263_decode_motion(s, s->last_mv[0][0][0], s->f_code);
+ my = ff_h263_decode_motion(s, s->last_mv[0][0][1], s->f_code);
+ s->last_mv[0][1][0] =
+ s->last_mv[0][0][0] =
+ s->mv[0][0][0] = mx;
+ s->last_mv[0][1][1] =
+ s->last_mv[0][0][1] =
+ s->mv[0][0][1] = my;
+ }
+
+ if (USES_LIST(mb_type, 1)) {
+ s->mv_dir |= MV_DIR_BACKWARD;
+
+ mx = ff_h263_decode_motion(s, s->last_mv[1][0][0], s->b_code);
+ my = ff_h263_decode_motion(s, s->last_mv[1][0][1], s->b_code);
+ s->last_mv[1][1][0] =
+ s->last_mv[1][0][0] =
+ s->mv[1][0][0] = mx;
+ s->last_mv[1][1][1] =
+ s->last_mv[1][0][1] =
+ s->mv[1][0][1] = my;
+ }
+ } else if (!IS_DIRECT(mb_type)) {
+ s->mv_type = MV_TYPE_FIELD;
+
+ if (USES_LIST(mb_type, 0)) {
+ s->mv_dir = MV_DIR_FORWARD;
+
+ for (i = 0; i < 2; i++) {
+ mx = ff_h263_decode_motion(s, s->last_mv[0][i][0], s->f_code);
+ my = ff_h263_decode_motion(s, s->last_mv[0][i][1] / 2, s->f_code);
+ s->last_mv[0][i][0] =
+ s->mv[0][i][0] = mx;
+ s->last_mv[0][i][1] = (s->mv[0][i][1] = my) * 2;
+ }
+ }
+
+ if (USES_LIST(mb_type, 1)) {
+ s->mv_dir |= MV_DIR_BACKWARD;
+
+ for (i = 0; i < 2; i++) {
+ mx = ff_h263_decode_motion(s, s->last_mv[1][i][0], s->b_code);
+ my = ff_h263_decode_motion(s, s->last_mv[1][i][1] / 2, s->b_code);
+ s->last_mv[1][i][0] =
+ s->mv[1][i][0] = mx;
+ s->last_mv[1][i][1] = (s->mv[1][i][1] = my) * 2;
+ }
+ }
+ }
+ }
+
+ if (IS_DIRECT(mb_type)) {
+ if (IS_SKIP(mb_type)) {
+ mx =
+ my = 0;
+ } else {
+ mx = ff_h263_decode_motion(s, 0, 1);
+ my = ff_h263_decode_motion(s, 0, 1);
+ }
+
+ s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT;
+ mb_type |= ff_mpeg4_set_direct_mv(s, mx, my);
+ }
+ s->current_picture.mb_type[xy] = mb_type;
+ } else { /* I-Frame */
+ do {
+ cbpc = get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
+ if (cbpc < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "I cbpc damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ } while (cbpc == 8);
+
+ dquant = cbpc & 4;
+ s->mb_intra = 1;
+
+intra:
+ s->ac_pred = get_bits1(&s->gb);
+ if (s->ac_pred)
+ s->current_picture.mb_type[xy] = MB_TYPE_INTRA | MB_TYPE_ACPRED;
+ else
+ s->current_picture.mb_type[xy] = MB_TYPE_INTRA;
+
+ cbpy = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+ if (cbpy < 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "I cbpy damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ cbp = (cbpc & 3) | (cbpy << 2);
+
+ ctx->use_intra_dc_vlc = s->qscale < ctx->intra_dc_threshold;
+
+ if (dquant)
+ ff_set_qscale(s, s->qscale + quant_tab[get_bits(&s->gb, 2)]);
+
+ if (!s->progressive_sequence)
+ s->interlaced_dct = get_bits1(&s->gb);
+
+ s->bdsp.clear_blocks(s->block[0]);
+ /* decode each block */
+ for (i = 0; i < 6; i++) {
+ if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, 1, 0) < 0)
+ return -1;
+ cbp += cbp;
+ }
+ goto end;
+ }
+
+ /* decode each block */
+ for (i = 0; i < 6; i++) {
+ if (mpeg4_decode_block(ctx, block[i], i, cbp & 32, 0, 0) < 0)
+ return -1;
+ cbp += cbp;
+ }
+
+end:
+ /* per-MB end of slice check */
+ if (s->codec_id == AV_CODEC_ID_MPEG4) {
+ int next = mpeg4_is_resync(ctx);
+ if (next) {
+ if (s->mb_x + s->mb_y*s->mb_width + 1 > next && (s->avctx->err_recognition & AV_EF_AGGRESSIVE)) {
+ return -1;
+ } else if (s->mb_x + s->mb_y*s->mb_width + 1 >= next)
+ return SLICE_END;
+
+ if (s->pict_type == AV_PICTURE_TYPE_B) {
+ const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1;
+ ff_thread_await_progress(&s->next_picture_ptr->tf,
+ (s->mb_x + delta >= s->mb_width)
+ ? FFMIN(s->mb_y + 1, s->mb_height - 1)
+ : s->mb_y, 0);
+ if (s->next_picture.mbskip_table[xy + delta])
+ return SLICE_OK;
+ }
+
+ return SLICE_END;
+ }
+ }
+
+ return SLICE_OK;
+}
+
+static int mpeg4_decode_gop_header(MpegEncContext *s, GetBitContext *gb)
+{
+ int hours, minutes, seconds;
+
+ if (!show_bits(gb, 23)) {
+ av_log(s->avctx, AV_LOG_WARNING, "GOP header invalid\n");
+ return -1;
+ }
+
+ hours = get_bits(gb, 5);
+ minutes = get_bits(gb, 6);
+ check_marker(gb, "in gop_header");
+ seconds = get_bits(gb, 6);
+
+ s->time_base = seconds + 60*(minutes + 60*hours);
+
+ skip_bits1(gb);
+ skip_bits1(gb);
+
+ return 0;
+}
+
+static int mpeg4_decode_profile_level(MpegEncContext *s, GetBitContext *gb)
+{
+
+ s->avctx->profile = get_bits(gb, 4);
+ s->avctx->level = get_bits(gb, 4);
+
+ // for Simple profile, level 0
+ if (s->avctx->profile == 0 && s->avctx->level == 8) {
+ s->avctx->level = 0;
+ }
+
+ return 0;
+}
+
+static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb)
+{
+ MpegEncContext *s = &ctx->m;
+ int width, height, vo_ver_id;
+
+ /* vol header */
+ skip_bits(gb, 1); /* random access */
+ s->vo_type = get_bits(gb, 8);
+ if (get_bits1(gb) != 0) { /* is_ol_id */
+ vo_ver_id = get_bits(gb, 4); /* vo_ver_id */
+ skip_bits(gb, 3); /* vo_priority */
+ } else {
+ vo_ver_id = 1;
+ }
+ s->aspect_ratio_info = get_bits(gb, 4);
+ if (s->aspect_ratio_info == FF_ASPECT_EXTENDED) {
+ s->avctx->sample_aspect_ratio.num = get_bits(gb, 8); // par_width
+ s->avctx->sample_aspect_ratio.den = get_bits(gb, 8); // par_height
+ } else {
+ s->avctx->sample_aspect_ratio = ff_h263_pixel_aspect[s->aspect_ratio_info];
+ }
+
+ if ((ctx->vol_control_parameters = get_bits1(gb))) { /* vol control parameter */
+ int chroma_format = get_bits(gb, 2);
+ if (chroma_format != CHROMA_420)
+ av_log(s->avctx, AV_LOG_ERROR, "illegal chroma format\n");
+
+ s->low_delay = get_bits1(gb);
+ if (get_bits1(gb)) { /* vbv parameters */
+ get_bits(gb, 15); /* first_half_bitrate */
+ check_marker(gb, "after first_half_bitrate");
+ get_bits(gb, 15); /* latter_half_bitrate */
+ check_marker(gb, "after latter_half_bitrate");
+ get_bits(gb, 15); /* first_half_vbv_buffer_size */
+ check_marker(gb, "after first_half_vbv_buffer_size");
+ get_bits(gb, 3); /* latter_half_vbv_buffer_size */
+ get_bits(gb, 11); /* first_half_vbv_occupancy */
+ check_marker(gb, "after first_half_vbv_occupancy");
+ get_bits(gb, 15); /* latter_half_vbv_occupancy */
+ check_marker(gb, "after latter_half_vbv_occupancy");
+ }
+ } else {
+ /* is setting low delay flag only once the smartest thing to do?
+ * low delay detection won't be overridden. */
+ if (s->picture_number == 0)
+ s->low_delay = 0;
+ }
+
+ ctx->shape = get_bits(gb, 2); /* vol shape */
+ if (ctx->shape != RECT_SHAPE)
+ av_log(s->avctx, AV_LOG_ERROR, "only rectangular vol supported\n");
+ if (ctx->shape == GRAY_SHAPE && vo_ver_id != 1) {
+ av_log(s->avctx, AV_LOG_ERROR, "Gray shape not supported\n");
+ skip_bits(gb, 4); /* video_object_layer_shape_extension */
+ }
+
+ check_marker(gb, "before time_increment_resolution");
+
+ s->avctx->framerate.num = get_bits(gb, 16);
+ if (!s->avctx->framerate.num) {
+ av_log(s->avctx, AV_LOG_ERROR, "framerate==0\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ ctx->time_increment_bits = av_log2(s->avctx->framerate.num - 1) + 1;
+ if (ctx->time_increment_bits < 1)
+ ctx->time_increment_bits = 1;
+
+ check_marker(gb, "before fixed_vop_rate");
+
+ if (get_bits1(gb) != 0) /* fixed_vop_rate */
+ s->avctx->framerate.den = get_bits(gb, ctx->time_increment_bits);
+ else
+ s->avctx->framerate.den = 1;
+
+ s->avctx->time_base = av_inv_q(av_mul_q(s->avctx->framerate, (AVRational){s->avctx->ticks_per_frame, 1}));
+
+ ctx->t_frame = 0;
+
+ if (ctx->shape != BIN_ONLY_SHAPE) {
+ if (ctx->shape == RECT_SHAPE) {
+ check_marker(gb, "before width");
+ width = get_bits(gb, 13);
+ check_marker(gb, "before height");
+ height = get_bits(gb, 13);
+ check_marker(gb, "after height");
+ if (width && height && /* they should be non zero but who knows */
+ !(s->width && s->codec_tag == AV_RL32("MP4S"))) {
+ if (s->width && s->height &&
+ (s->width != width || s->height != height))
+ s->context_reinit = 1;
+ s->width = width;
+ s->height = height;
+ }
+ }
+
+ s->progressive_sequence =
+ s->progressive_frame = get_bits1(gb) ^ 1;
+ s->interlaced_dct = 0;
+ if (!get_bits1(gb) && (s->avctx->debug & FF_DEBUG_PICT_INFO))
+ av_log(s->avctx, AV_LOG_INFO, /* OBMC Disable */
+ "MPEG4 OBMC not supported (very likely buggy encoder)\n");
+ if (vo_ver_id == 1)
+ ctx->vol_sprite_usage = get_bits1(gb); /* vol_sprite_usage */
+ else
+ ctx->vol_sprite_usage = get_bits(gb, 2); /* vol_sprite_usage */
+
+ if (ctx->vol_sprite_usage == STATIC_SPRITE)
+ av_log(s->avctx, AV_LOG_ERROR, "Static Sprites not supported\n");
+ if (ctx->vol_sprite_usage == STATIC_SPRITE ||
+ ctx->vol_sprite_usage == GMC_SPRITE) {
+ if (ctx->vol_sprite_usage == STATIC_SPRITE) {
+ skip_bits(gb, 13); // sprite_width
+ check_marker(gb, "after sprite_width");
+ skip_bits(gb, 13); // sprite_height
+ check_marker(gb, "after sprite_height");
+ skip_bits(gb, 13); // sprite_left
+ check_marker(gb, "after sprite_left");
+ skip_bits(gb, 13); // sprite_top
+ check_marker(gb, "after sprite_top");
+ }
+ ctx->num_sprite_warping_points = get_bits(gb, 6);
+ if (ctx->num_sprite_warping_points > 3) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "%d sprite_warping_points\n",
+ ctx->num_sprite_warping_points);
+ ctx->num_sprite_warping_points = 0;
+ return AVERROR_INVALIDDATA;
+ }
+ s->sprite_warping_accuracy = get_bits(gb, 2);
+ ctx->sprite_brightness_change = get_bits1(gb);
+ if (ctx->vol_sprite_usage == STATIC_SPRITE)
+ skip_bits1(gb); // low_latency_sprite
+ }
+ // FIXME sadct disable bit if verid!=1 && shape not rect
+
+ if (get_bits1(gb) == 1) { /* not_8_bit */
+ s->quant_precision = get_bits(gb, 4); /* quant_precision */
+ if (get_bits(gb, 4) != 8) /* bits_per_pixel */
+ av_log(s->avctx, AV_LOG_ERROR, "N-bit not supported\n");
+ if (s->quant_precision != 5)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "quant precision %d\n", s->quant_precision);
+ if (s->quant_precision<3 || s->quant_precision>9) {
+ s->quant_precision = 5;
+ }
+ } else {
+ s->quant_precision = 5;
+ }
+
+ // FIXME a bunch of grayscale shape things
+
+ if ((s->mpeg_quant = get_bits1(gb))) { /* vol_quant_type */
+ int i, v;
+
+ /* load default matrixes */
+ for (i = 0; i < 64; i++) {
+ int j = s->idsp.idct_permutation[i];
+ v = ff_mpeg4_default_intra_matrix[i];
+ s->intra_matrix[j] = v;
+ s->chroma_intra_matrix[j] = v;
+
+ v = ff_mpeg4_default_non_intra_matrix[i];
+ s->inter_matrix[j] = v;
+ s->chroma_inter_matrix[j] = v;
+ }
+
+ /* load custom intra matrix */
+ if (get_bits1(gb)) {
+ int last = 0;
+ for (i = 0; i < 64; i++) {
+ int j;
+ if (get_bits_left(gb) < 8) {
+ av_log(s->avctx, AV_LOG_ERROR, "insufficient data for custom matrix\n");
+ return AVERROR_INVALIDDATA;
+ }
+ v = get_bits(gb, 8);
+ if (v == 0)
+ break;
+
+ last = v;
+ j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
+ s->intra_matrix[j] = last;
+ s->chroma_intra_matrix[j] = last;
+ }
+
+ /* replicate last value */
+ for (; i < 64; i++) {
+ int j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
+ s->intra_matrix[j] = last;
+ s->chroma_intra_matrix[j] = last;
+ }
+ }
+
+ /* load custom non intra matrix */
+ if (get_bits1(gb)) {
+ int last = 0;
+ for (i = 0; i < 64; i++) {
+ int j;
+ if (get_bits_left(gb) < 8) {
+ av_log(s->avctx, AV_LOG_ERROR, "insufficient data for custom matrix\n");
+ return AVERROR_INVALIDDATA;
+ }
+ v = get_bits(gb, 8);
+ if (v == 0)
+ break;
+
+ last = v;
+ j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
+ s->inter_matrix[j] = v;
+ s->chroma_inter_matrix[j] = v;
+ }
+
+ /* replicate last value */
+ for (; i < 64; i++) {
+ int j = s->idsp.idct_permutation[ff_zigzag_direct[i]];
+ s->inter_matrix[j] = last;
+ s->chroma_inter_matrix[j] = last;
+ }
+ }
+
+ // FIXME a bunch of grayscale shape things
+ }
+
+ if (vo_ver_id != 1)
+ s->quarter_sample = get_bits1(gb);
+ else
+ s->quarter_sample = 0;
+
+ if (get_bits_left(gb) < 4) {
+ av_log(s->avctx, AV_LOG_ERROR, "VOL Header truncated\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!get_bits1(gb)) {
+ int pos = get_bits_count(gb);
+ int estimation_method = get_bits(gb, 2);
+ if (estimation_method < 2) {
+ if (!get_bits1(gb)) {
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* opaque */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* transparent */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* intra_cae */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* inter_cae */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* no_update */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* upampling */
+ }
+ if (!get_bits1(gb)) {
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* intra_blocks */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* inter_blocks */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* inter4v_blocks */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* not coded blocks */
+ }
+ if (!check_marker(gb, "in complexity estimation part 1")) {
+ skip_bits_long(gb, pos - get_bits_count(gb));
+ goto no_cplx_est;
+ }
+ if (!get_bits1(gb)) {
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* dct_coeffs */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* dct_lines */
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* vlc_syms */
+ ctx->cplx_estimation_trash_i += 4 * get_bits1(gb); /* vlc_bits */
+ }
+ if (!get_bits1(gb)) {
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* apm */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* npm */
+ ctx->cplx_estimation_trash_b += 8 * get_bits1(gb); /* interpolate_mc_q */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* forwback_mc_q */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* halfpel2 */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* halfpel4 */
+ }
+ if (!check_marker(gb, "in complexity estimation part 2")) {
+ skip_bits_long(gb, pos - get_bits_count(gb));
+ goto no_cplx_est;
+ }
+ if (estimation_method == 1) {
+ ctx->cplx_estimation_trash_i += 8 * get_bits1(gb); /* sadct */
+ ctx->cplx_estimation_trash_p += 8 * get_bits1(gb); /* qpel */
+ }
+ } else
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid Complexity estimation method %d\n",
+ estimation_method);
+ } else {
+
+no_cplx_est:
+ ctx->cplx_estimation_trash_i =
+ ctx->cplx_estimation_trash_p =
+ ctx->cplx_estimation_trash_b = 0;
+ }
+
+ ctx->resync_marker = !get_bits1(gb); /* resync_marker_disabled */
+
+ s->data_partitioning = get_bits1(gb);
+ if (s->data_partitioning)
+ ctx->rvlc = get_bits1(gb);
+
+ if (vo_ver_id != 1) {
+ ctx->new_pred = get_bits1(gb);
+ if (ctx->new_pred) {
+ av_log(s->avctx, AV_LOG_ERROR, "new pred not supported\n");
+ skip_bits(gb, 2); /* requested upstream message type */
+ skip_bits1(gb); /* newpred segment type */
+ }
+ if (get_bits1(gb)) // reduced_res_vop
+ av_log(s->avctx, AV_LOG_ERROR,
+ "reduced resolution VOP not supported\n");
+ } else {
+ ctx->new_pred = 0;
+ }
+
+ ctx->scalability = get_bits1(gb);
+
+ if (ctx->scalability) {
+ GetBitContext bak = *gb;
+ int h_sampling_factor_n;
+ int h_sampling_factor_m;
+ int v_sampling_factor_n;
+ int v_sampling_factor_m;
+
+ skip_bits1(gb); // hierarchy_type
+ skip_bits(gb, 4); /* ref_layer_id */
+ skip_bits1(gb); /* ref_layer_sampling_dir */
+ h_sampling_factor_n = get_bits(gb, 5);
+ h_sampling_factor_m = get_bits(gb, 5);
+ v_sampling_factor_n = get_bits(gb, 5);
+ v_sampling_factor_m = get_bits(gb, 5);
+ ctx->enhancement_type = get_bits1(gb);
+
+ if (h_sampling_factor_n == 0 || h_sampling_factor_m == 0 ||
+ v_sampling_factor_n == 0 || v_sampling_factor_m == 0) {
+ /* illegal scalability header (VERY broken encoder),
+ * trying to workaround */
+ ctx->scalability = 0;
+ *gb = bak;
+ } else
+ av_log(s->avctx, AV_LOG_ERROR, "scalability not supported\n");
+
+ // bin shape stuff FIXME
+ }
+ }
+
+ if (s->avctx->debug&FF_DEBUG_PICT_INFO) {
+ av_log(s->avctx, AV_LOG_DEBUG, "tb %d/%d, tincrbits:%d, qp_prec:%d, ps:%d, %s%s%s%s\n",
+ s->avctx->framerate.den, s->avctx->framerate.num,
+ ctx->time_increment_bits,
+ s->quant_precision,
+ s->progressive_sequence,
+ ctx->scalability ? "scalability " :"" , s->quarter_sample ? "qpel " : "",
+ s->data_partitioning ? "partition " : "", ctx->rvlc ? "rvlc " : ""
+ );
+ }
+
+ return 0;
+}
+
+/**
+ * Decode the user data stuff in the header.
+ * Also initializes divx/xvid/lavc_version/build.
+ */
+static int decode_user_data(Mpeg4DecContext *ctx, GetBitContext *gb)
+{
+ MpegEncContext *s = &ctx->m;
+ char buf[256];
+ int i;
+ int e;
+ int ver = 0, build = 0, ver2 = 0, ver3 = 0;
+ char last;
+
+ for (i = 0; i < 255 && get_bits_count(gb) < gb->size_in_bits; i++) {
+ if (show_bits(gb, 23) == 0)
+ break;
+ buf[i] = get_bits(gb, 8);
+ }
+ buf[i] = 0;
+
+ /* divx detection */
+ e = sscanf(buf, "DivX%dBuild%d%c", &ver, &build, &last);
+ if (e < 2)
+ e = sscanf(buf, "DivX%db%d%c", &ver, &build, &last);
+ if (e >= 2) {
+ ctx->divx_version = ver;
+ ctx->divx_build = build;
+ s->divx_packed = e == 3 && last == 'p';
+ }
+
+ /* libavcodec detection */
+ e = sscanf(buf, "FFmpe%*[^b]b%d", &build) + 3;
+ if (e != 4)
+ e = sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build);
+ if (e != 4) {
+ e = sscanf(buf, "Lavc%d.%d.%d", &ver, &ver2, &ver3) + 1;
+ if (e > 1)
+ build = (ver << 16) + (ver2 << 8) + ver3;
+ }
+ if (e != 4) {
+ if (strcmp(buf, "ffmpeg") == 0)
+ ctx->lavc_build = 4600;
+ }
+ if (e == 4)
+ ctx->lavc_build = build;
+
+ /* Xvid detection */
+ e = sscanf(buf, "XviD%d", &build);
+ if (e == 1)
+ ctx->xvid_build = build;
+
+ return 0;
+}
+
+int ff_mpeg4_workaround_bugs(AVCodecContext *avctx)
+{
+ Mpeg4DecContext *ctx = avctx->priv_data;
+ MpegEncContext *s = &ctx->m;
+
+ if (ctx->xvid_build == -1 && ctx->divx_version == -1 && ctx->lavc_build == -1) {
+ if (s->codec_tag == AV_RL32("XVID") ||
+ s->codec_tag == AV_RL32("XVIX") ||
+ s->codec_tag == AV_RL32("RMP4") ||
+ s->codec_tag == AV_RL32("ZMP4") ||
+ s->codec_tag == AV_RL32("SIPP"))
+ ctx->xvid_build = 0;
+ }
+
+ if (ctx->xvid_build == -1 && ctx->divx_version == -1 && ctx->lavc_build == -1)
+ if (s->codec_tag == AV_RL32("DIVX") && s->vo_type == 0 &&
+ ctx->vol_control_parameters == 0)
+ ctx->divx_version = 400; // divx 4
+
+ if (ctx->xvid_build >= 0 && ctx->divx_version >= 0) {
+ ctx->divx_version =
+ ctx->divx_build = -1;
+ }
+
+ if (s->workaround_bugs & FF_BUG_AUTODETECT) {
+ if (s->codec_tag == AV_RL32("XVIX"))
+ s->workaround_bugs |= FF_BUG_XVID_ILACE;
+
+ if (s->codec_tag == AV_RL32("UMP4"))
+ s->workaround_bugs |= FF_BUG_UMP4;
+
+ if (ctx->divx_version >= 500 && ctx->divx_build < 1814)
+ s->workaround_bugs |= FF_BUG_QPEL_CHROMA;
+
+ if (ctx->divx_version > 502 && ctx->divx_build < 1814)
+ s->workaround_bugs |= FF_BUG_QPEL_CHROMA2;
+
+ if (ctx->xvid_build <= 3U)
+ s->padding_bug_score = 256 * 256 * 256 * 64;
+
+ if (ctx->xvid_build <= 1U)
+ s->workaround_bugs |= FF_BUG_QPEL_CHROMA;
+
+ if (ctx->xvid_build <= 12U)
+ s->workaround_bugs |= FF_BUG_EDGE;
+
+ if (ctx->xvid_build <= 32U)
+ s->workaround_bugs |= FF_BUG_DC_CLIP;
+
+#define SET_QPEL_FUNC(postfix1, postfix2) \
+ s->qdsp.put_ ## postfix1 = ff_put_ ## postfix2; \
+ s->qdsp.put_no_rnd_ ## postfix1 = ff_put_no_rnd_ ## postfix2; \
+ s->qdsp.avg_ ## postfix1 = ff_avg_ ## postfix2;
+
+ if (ctx->lavc_build < 4653U)
+ s->workaround_bugs |= FF_BUG_STD_QPEL;
+
+ if (ctx->lavc_build < 4655U)
+ s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE;
+
+ if (ctx->lavc_build < 4670U)
+ s->workaround_bugs |= FF_BUG_EDGE;
+
+ if (ctx->lavc_build <= 4712U)
+ s->workaround_bugs |= FF_BUG_DC_CLIP;
+
+ if (ctx->divx_version >= 0)
+ s->workaround_bugs |= FF_BUG_DIRECT_BLOCKSIZE;
+ if (ctx->divx_version == 501 && ctx->divx_build == 20020416)
+ s->padding_bug_score = 256 * 256 * 256 * 64;
+
+ if (ctx->divx_version < 500U)
+ s->workaround_bugs |= FF_BUG_EDGE;
+
+ if (ctx->divx_version >= 0)
+ s->workaround_bugs |= FF_BUG_HPEL_CHROMA;
+ }
+
+ if (s->workaround_bugs & FF_BUG_STD_QPEL) {
+ SET_QPEL_FUNC(qpel_pixels_tab[0][5], qpel16_mc11_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][7], qpel16_mc31_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][9], qpel16_mc12_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][11], qpel16_mc32_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][13], qpel16_mc13_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[0][15], qpel16_mc33_old_c)
+
+ SET_QPEL_FUNC(qpel_pixels_tab[1][5], qpel8_mc11_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][7], qpel8_mc31_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][9], qpel8_mc12_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][11], qpel8_mc32_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][13], qpel8_mc13_old_c)
+ SET_QPEL_FUNC(qpel_pixels_tab[1][15], qpel8_mc33_old_c)
+ }
+
+ if (avctx->debug & FF_DEBUG_BUGS)
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "bugs: %X lavc_build:%d xvid_build:%d divx_version:%d divx_build:%d %s\n",
+ s->workaround_bugs, ctx->lavc_build, ctx->xvid_build,
+ ctx->divx_version, ctx->divx_build, s->divx_packed ? "p" : "");
+
+ if (CONFIG_MPEG4_DECODER && ctx->xvid_build >= 0 &&
+ s->codec_id == AV_CODEC_ID_MPEG4 &&
+ avctx->idct_algo == FF_IDCT_AUTO) {
+ avctx->idct_algo = FF_IDCT_XVID;
+ ff_mpv_idct_init(s);
+ return 1;
+ }
+
+ return 0;
+}
+
+static int decode_vop_header(Mpeg4DecContext *ctx, GetBitContext *gb)
+{
+ MpegEncContext *s = &ctx->m;
+ int time_incr, time_increment;
+ int64_t pts;
+
+ s->pict_type = get_bits(gb, 2) + AV_PICTURE_TYPE_I; /* pict type: I = 0 , P = 1 */
+ if (s->pict_type == AV_PICTURE_TYPE_B && s->low_delay &&
+ ctx->vol_control_parameters == 0 && !(s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY)) {
+ av_log(s->avctx, AV_LOG_ERROR, "low_delay flag set incorrectly, clearing it\n");
+ s->low_delay = 0;
+ }
+
+ s->partitioned_frame = s->data_partitioning && s->pict_type != AV_PICTURE_TYPE_B;
+ if (s->partitioned_frame)
+ s->decode_mb = mpeg4_decode_partitioned_mb;
+ else
+ s->decode_mb = mpeg4_decode_mb;
+
+ time_incr = 0;
+ while (get_bits1(gb) != 0)
+ time_incr++;
+
+ check_marker(gb, "before time_increment");
+
+ if (ctx->time_increment_bits == 0 ||
+ !(show_bits(gb, ctx->time_increment_bits + 1) & 1)) {
+ av_log(s->avctx, AV_LOG_WARNING,
+ "time_increment_bits %d is invalid in relation to the current bitstream, this is likely caused by a missing VOL header\n", ctx->time_increment_bits);
+
+ for (ctx->time_increment_bits = 1;
+ ctx->time_increment_bits < 16;
+ ctx->time_increment_bits++) {
+ if (s->pict_type == AV_PICTURE_TYPE_P ||
+ (s->pict_type == AV_PICTURE_TYPE_S &&
+ ctx->vol_sprite_usage == GMC_SPRITE)) {
+ if ((show_bits(gb, ctx->time_increment_bits + 6) & 0x37) == 0x30)
+ break;
+ } else if ((show_bits(gb, ctx->time_increment_bits + 5) & 0x1F) == 0x18)
+ break;
+ }
+
+ av_log(s->avctx, AV_LOG_WARNING,
+ "time_increment_bits set to %d bits, based on bitstream analysis\n", ctx->time_increment_bits);
+ if (s->avctx->framerate.num && 4*s->avctx->framerate.num < 1<<ctx->time_increment_bits) {
+ s->avctx->framerate.num = 1<<ctx->time_increment_bits;
+ s->avctx->time_base = av_inv_q(av_mul_q(s->avctx->framerate, (AVRational){s->avctx->ticks_per_frame, 1}));
+ }
+ }
+
+ if (IS_3IV1)
+ time_increment = get_bits1(gb); // FIXME investigate further
+ else
+ time_increment = get_bits(gb, ctx->time_increment_bits);
+
+ if (s->pict_type != AV_PICTURE_TYPE_B) {
+ s->last_time_base = s->time_base;
+ s->time_base += time_incr;
+ s->time = s->time_base * s->avctx->framerate.num + time_increment;
+ if (s->workaround_bugs & FF_BUG_UMP4) {
+ if (s->time < s->last_non_b_time) {
+ /* header is not mpeg-4-compatible, broken encoder,
+ * trying to workaround */
+ s->time_base++;
+ s->time += s->avctx->framerate.num;
+ }
+ }
+ s->pp_time = s->time - s->last_non_b_time;
+ s->last_non_b_time = s->time;
+ } else {
+ s->time = (s->last_time_base + time_incr) * s->avctx->framerate.num + time_increment;
+ s->pb_time = s->pp_time - (s->last_non_b_time - s->time);
+ if (s->pp_time <= s->pb_time ||
+ s->pp_time <= s->pp_time - s->pb_time ||
+ s->pp_time <= 0) {
+ /* messed up order, maybe after seeking? skipping current b-frame */
+ return FRAME_SKIPPED;
+ }
+ ff_mpeg4_init_direct_mv(s);
+
+ if (ctx->t_frame == 0)
+ ctx->t_frame = s->pb_time;
+ if (ctx->t_frame == 0)
+ ctx->t_frame = 1; // 1/0 protection
+ s->pp_field_time = (ROUNDED_DIV(s->last_non_b_time, ctx->t_frame) -
+ ROUNDED_DIV(s->last_non_b_time - s->pp_time, ctx->t_frame)) * 2;
+ s->pb_field_time = (ROUNDED_DIV(s->time, ctx->t_frame) -
+ ROUNDED_DIV(s->last_non_b_time - s->pp_time, ctx->t_frame)) * 2;
+ if (s->pp_field_time <= s->pb_field_time || s->pb_field_time <= 1) {
+ s->pb_field_time = 2;
+ s->pp_field_time = 4;
+ if (!s->progressive_sequence)
+ return FRAME_SKIPPED;
+ }
+ }
+
+ if (s->avctx->framerate.den)
+ pts = ROUNDED_DIV(s->time, s->avctx->framerate.den);
+ else
+ pts = AV_NOPTS_VALUE;
+ ff_dlog(s->avctx, "MPEG4 PTS: %"PRId64"\n", pts);
+
+ check_marker(gb, "before vop_coded");
+
+ /* vop coded */
+ if (get_bits1(gb) != 1) {
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_ERROR, "vop not coded\n");
+ return FRAME_SKIPPED;
+ }
+ if (ctx->new_pred)
+ decode_new_pred(ctx, gb);
+
+ if (ctx->shape != BIN_ONLY_SHAPE &&
+ (s->pict_type == AV_PICTURE_TYPE_P ||
+ (s->pict_type == AV_PICTURE_TYPE_S &&
+ ctx->vol_sprite_usage == GMC_SPRITE))) {
+ /* rounding type for motion estimation */
+ s->no_rounding = get_bits1(gb);
+ } else {
+ s->no_rounding = 0;
+ }
+ // FIXME reduced res stuff
+
+ if (ctx->shape != RECT_SHAPE) {
+ if (ctx->vol_sprite_usage != 1 || s->pict_type != AV_PICTURE_TYPE_I) {
+ skip_bits(gb, 13); /* width */
+ check_marker(gb, "after width");
+ skip_bits(gb, 13); /* height */
+ check_marker(gb, "after height");
+ skip_bits(gb, 13); /* hor_spat_ref */
+ check_marker(gb, "after hor_spat_ref");
+ skip_bits(gb, 13); /* ver_spat_ref */
+ }
+ skip_bits1(gb); /* change_CR_disable */
+
+ if (get_bits1(gb) != 0)
+ skip_bits(gb, 8); /* constant_alpha_value */
+ }
+
+ // FIXME complexity estimation stuff
+
+ if (ctx->shape != BIN_ONLY_SHAPE) {
+ skip_bits_long(gb, ctx->cplx_estimation_trash_i);
+ if (s->pict_type != AV_PICTURE_TYPE_I)
+ skip_bits_long(gb, ctx->cplx_estimation_trash_p);
+ if (s->pict_type == AV_PICTURE_TYPE_B)
+ skip_bits_long(gb, ctx->cplx_estimation_trash_b);
+
+ if (get_bits_left(gb) < 3) {
+ av_log(s->avctx, AV_LOG_ERROR, "Header truncated\n");
+ return AVERROR_INVALIDDATA;
+ }
+ ctx->intra_dc_threshold = ff_mpeg4_dc_threshold[get_bits(gb, 3)];
+ if (!s->progressive_sequence) {
+ s->top_field_first = get_bits1(gb);
+ s->alternate_scan = get_bits1(gb);
+ } else
+ s->alternate_scan = 0;
+ }
+
+ if (s->alternate_scan) {
+ ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_alternate_vertical_scan);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
+ } else {
+ ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);
+ ff_init_scantable(s->idsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);
+ }
+
+ if (s->pict_type == AV_PICTURE_TYPE_S) {
+ if((ctx->vol_sprite_usage == STATIC_SPRITE ||
+ ctx->vol_sprite_usage == GMC_SPRITE)) {
+ if (mpeg4_decode_sprite_trajectory(ctx, gb) < 0)
+ return AVERROR_INVALIDDATA;
+ if (ctx->sprite_brightness_change)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "sprite_brightness_change not supported\n");
+ if (ctx->vol_sprite_usage == STATIC_SPRITE)
+ av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n");
+ } else {
+ memset(s->sprite_offset, 0, sizeof(s->sprite_offset));
+ memset(s->sprite_delta, 0, sizeof(s->sprite_delta));
+ }
+ }
+
+ if (ctx->shape != BIN_ONLY_SHAPE) {
+ s->chroma_qscale = s->qscale = get_bits(gb, s->quant_precision);
+ if (s->qscale == 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Error, header damaged or not MPEG4 header (qscale=0)\n");
+ return AVERROR_INVALIDDATA; // makes no sense to continue, as there is nothing left from the image then
+ }
+
+ if (s->pict_type != AV_PICTURE_TYPE_I) {
+ s->f_code = get_bits(gb, 3); /* fcode_for */
+ if (s->f_code == 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Error, header damaged or not MPEG4 header (f_code=0)\n");
+ s->f_code = 1;
+ return AVERROR_INVALIDDATA; // makes no sense to continue, as there is nothing left from the image then
+ }
+ } else
+ s->f_code = 1;
+
+ if (s->pict_type == AV_PICTURE_TYPE_B) {
+ s->b_code = get_bits(gb, 3);
+ if (s->b_code == 0) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Error, header damaged or not MPEG4 header (b_code=0)\n");
+ s->b_code=1;
+ return AVERROR_INVALIDDATA; // makes no sense to continue, as the MV decoding will break very quickly
+ }
+ } else
+ s->b_code = 1;
+
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO) {
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "qp:%d fc:%d,%d %s size:%d pro:%d alt:%d top:%d %spel part:%d resync:%d w:%d a:%d rnd:%d vot:%d%s dc:%d ce:%d/%d/%d time:%"PRId64" tincr:%d\n",
+ s->qscale, s->f_code, s->b_code,
+ s->pict_type == AV_PICTURE_TYPE_I ? "I" : (s->pict_type == AV_PICTURE_TYPE_P ? "P" : (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")),
+ gb->size_in_bits,s->progressive_sequence, s->alternate_scan,
+ s->top_field_first, s->quarter_sample ? "q" : "h",
+ s->data_partitioning, ctx->resync_marker,
+ ctx->num_sprite_warping_points, s->sprite_warping_accuracy,
+ 1 - s->no_rounding, s->vo_type,
+ ctx->vol_control_parameters ? " VOLC" : " ", ctx->intra_dc_threshold,
+ ctx->cplx_estimation_trash_i, ctx->cplx_estimation_trash_p,
+ ctx->cplx_estimation_trash_b,
+ s->time,
+ time_increment
+ );
+ }
+
+ if (!ctx->scalability) {
+ if (ctx->shape != RECT_SHAPE && s->pict_type != AV_PICTURE_TYPE_I)
+ skip_bits1(gb); // vop shape coding type
+ } else {
+ if (ctx->enhancement_type) {
+ int load_backward_shape = get_bits1(gb);
+ if (load_backward_shape)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "load backward shape isn't supported\n");
+ }
+ skip_bits(gb, 2); // ref_select_code
+ }
+ }
+ /* detect buggy encoders which don't set the low_delay flag
+ * (divx4/xvid/opendivx). Note we cannot detect divx5 without b-frames
+ * easily (although it's buggy too) */
+ if (s->vo_type == 0 && ctx->vol_control_parameters == 0 &&
+ ctx->divx_version == -1 && s->picture_number == 0) {
+ av_log(s->avctx, AV_LOG_WARNING,
+ "looks like this file was encoded with (divx4/(old)xvid/opendivx) -> forcing low_delay flag\n");
+ s->low_delay = 1;
+ }
+
+ s->picture_number++; // better than pic number==0 always ;)
+
+ // FIXME add short header support
+ s->y_dc_scale_table = ff_mpeg4_y_dc_scale_table;
+ s->c_dc_scale_table = ff_mpeg4_c_dc_scale_table;
+
+ if (s->workaround_bugs & FF_BUG_EDGE) {
+ s->h_edge_pos = s->width;
+ s->v_edge_pos = s->height;
+ }
+ return 0;
+}
+
+/**
+ * Decode mpeg4 headers.
+ * @return <0 if no VOP found (or a damaged one)
+ * FRAME_SKIPPED if a not coded VOP is found
+ * 0 if a VOP is found
+ */
+int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb)
+{
+ MpegEncContext *s = &ctx->m;
+ unsigned startcode, v;
+ int ret;
+ int vol = 0;
+
+ /* search next start code */
+ align_get_bits(gb);
+
+ if (s->codec_tag == AV_RL32("WV1F") && show_bits(gb, 24) == 0x575630) {
+ skip_bits(gb, 24);
+ if (get_bits(gb, 8) == 0xF0)
+ goto end;
+ }
+
+ startcode = 0xff;
+ for (;;) {
+ if (get_bits_count(gb) >= gb->size_in_bits) {
+ if (gb->size_in_bits == 8 &&
+ (ctx->divx_version >= 0 || ctx->xvid_build >= 0) || s->codec_tag == AV_RL32("QMP4")) {
+ av_log(s->avctx, AV_LOG_VERBOSE, "frame skip %d\n", gb->size_in_bits);
+ return FRAME_SKIPPED; // divx bug
+ } else
+ return -1; // end of stream
+ }
+
+ /* use the bits after the test */
+ v = get_bits(gb, 8);
+ startcode = ((startcode << 8) | v) & 0xffffffff;
+
+ if ((startcode & 0xFFFFFF00) != 0x100)
+ continue; // no startcode
+
+ if (s->avctx->debug & FF_DEBUG_STARTCODE) {
+ av_log(s->avctx, AV_LOG_DEBUG, "startcode: %3X ", startcode);
+ if (startcode <= 0x11F)
+ av_log(s->avctx, AV_LOG_DEBUG, "Video Object Start");
+ else if (startcode <= 0x12F)
+ av_log(s->avctx, AV_LOG_DEBUG, "Video Object Layer Start");
+ else if (startcode <= 0x13F)
+ av_log(s->avctx, AV_LOG_DEBUG, "Reserved");
+ else if (startcode <= 0x15F)
+ av_log(s->avctx, AV_LOG_DEBUG, "FGS bp start");
+ else if (startcode <= 0x1AF)
+ av_log(s->avctx, AV_LOG_DEBUG, "Reserved");
+ else if (startcode == 0x1B0)
+ av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq Start");
+ else if (startcode == 0x1B1)
+ av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Seq End");
+ else if (startcode == 0x1B2)
+ av_log(s->avctx, AV_LOG_DEBUG, "User Data");
+ else if (startcode == 0x1B3)
+ av_log(s->avctx, AV_LOG_DEBUG, "Group of VOP start");
+ else if (startcode == 0x1B4)
+ av_log(s->avctx, AV_LOG_DEBUG, "Video Session Error");
+ else if (startcode == 0x1B5)
+ av_log(s->avctx, AV_LOG_DEBUG, "Visual Object Start");
+ else if (startcode == 0x1B6)
+ av_log(s->avctx, AV_LOG_DEBUG, "Video Object Plane start");
+ else if (startcode == 0x1B7)
+ av_log(s->avctx, AV_LOG_DEBUG, "slice start");
+ else if (startcode == 0x1B8)
+ av_log(s->avctx, AV_LOG_DEBUG, "extension start");
+ else if (startcode == 0x1B9)
+ av_log(s->avctx, AV_LOG_DEBUG, "fgs start");
+ else if (startcode == 0x1BA)
+ av_log(s->avctx, AV_LOG_DEBUG, "FBA Object start");
+ else if (startcode == 0x1BB)
+ av_log(s->avctx, AV_LOG_DEBUG, "FBA Object Plane start");
+ else if (startcode == 0x1BC)
+ av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object start");
+ else if (startcode == 0x1BD)
+ av_log(s->avctx, AV_LOG_DEBUG, "Mesh Object Plane start");
+ else if (startcode == 0x1BE)
+ av_log(s->avctx, AV_LOG_DEBUG, "Still Texture Object start");
+ else if (startcode == 0x1BF)
+ av_log(s->avctx, AV_LOG_DEBUG, "Texture Spatial Layer start");
+ else if (startcode == 0x1C0)
+ av_log(s->avctx, AV_LOG_DEBUG, "Texture SNR Layer start");
+ else if (startcode == 0x1C1)
+ av_log(s->avctx, AV_LOG_DEBUG, "Texture Tile start");
+ else if (startcode == 0x1C2)
+ av_log(s->avctx, AV_LOG_DEBUG, "Texture Shape Layer start");
+ else if (startcode == 0x1C3)
+ av_log(s->avctx, AV_LOG_DEBUG, "stuffing start");
+ else if (startcode <= 0x1C5)
+ av_log(s->avctx, AV_LOG_DEBUG, "reserved");
+ else if (startcode <= 0x1FF)
+ av_log(s->avctx, AV_LOG_DEBUG, "System start");
+ av_log(s->avctx, AV_LOG_DEBUG, " at %d\n", get_bits_count(gb));
+ }
+
+ if (startcode >= 0x120 && startcode <= 0x12F) {
+ if (vol) {
+ av_log(s->avctx, AV_LOG_ERROR, "Multiple VOL headers");
+ return AVERROR_INVALIDDATA;
+ }
+ vol++;
+ if ((ret = decode_vol_header(ctx, gb)) < 0)
+ return ret;
+ } else if (startcode == USER_DATA_STARTCODE) {
+ decode_user_data(ctx, gb);
+ } else if (startcode == GOP_STARTCODE) {
+ mpeg4_decode_gop_header(s, gb);
+ } else if (startcode == VOS_STARTCODE) {
+ mpeg4_decode_profile_level(s, gb);
+ } else if (startcode == VOP_STARTCODE) {
+ break;
+ }
+
+ align_get_bits(gb);
+ startcode = 0xff;
+ }
+
+end:
+ if (s->avctx->flags & AV_CODEC_FLAG_LOW_DELAY)
+ s->low_delay = 1;
+ s->avctx->has_b_frames = !s->low_delay;
+
+ return decode_vop_header(ctx, gb);
+}
+
+av_cold void ff_mpeg4videodec_static_init(void) {
+ static int done = 0;
+
+ if (!done) {
+ 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_VLC_RL(ff_rvlc_rl_inter, 1072);
+ INIT_VLC_RL(ff_rvlc_rl_intra, 1072);
+ INIT_VLC_STATIC(&dc_lum, DC_VLC_BITS, 10 /* 13 */,
+ &ff_mpeg4_DCtab_lum[0][1], 2, 1,
+ &ff_mpeg4_DCtab_lum[0][0], 2, 1, 512);
+ 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(&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);
+ done = 1;
+ }
+}
+
+int ff_mpeg4_frame_end(AVCodecContext *avctx, const uint8_t *buf, int buf_size)
+{
+ Mpeg4DecContext *ctx = avctx->priv_data;
+ MpegEncContext *s = &ctx->m;
+
+ /* divx 5.01+ bitstream reorder stuff */
+ /* Since this clobbers the input buffer and hwaccel codecs still need the
+ * data during hwaccel->end_frame we should not do this any earlier */
+ if (s->divx_packed) {
+ int current_pos = s->gb.buffer == s->bitstream_buffer ? 0 : (get_bits_count(&s->gb) >> 3);
+ int startcode_found = 0;
+
+ if (buf_size - current_pos > 7) {
+
+ int i;
+ for (i = current_pos; i < buf_size - 4; i++)
+
+ if (buf[i] == 0 &&
+ buf[i + 1] == 0 &&
+ buf[i + 2] == 1 &&
+ buf[i + 3] == 0xB6) {
+ startcode_found = !(buf[i + 4] & 0x40);
+ break;
+ }
+ }
+
+ if (startcode_found) {
+ if (!ctx->showed_packed_warning) {
+ av_log(s->avctx, AV_LOG_INFO, "Video uses a non-standard and "
+ "wasteful way to store B-frames ('packed B-frames'). "
+ "Consider using the mpeg4_unpack_bframes bitstream filter without encoding but stream copy to fix it.\n");
+ ctx->showed_packed_warning = 1;
+ }
+ av_fast_padded_malloc(&s->bitstream_buffer,
+ &s->allocated_bitstream_buffer_size,
+ buf_size - current_pos);
+ if (!s->bitstream_buffer) {
+ s->bitstream_buffer_size = 0;
+ return AVERROR(ENOMEM);
+ }
+ memcpy(s->bitstream_buffer, buf + current_pos,
+ buf_size - current_pos);
+ s->bitstream_buffer_size = buf_size - current_pos;
+ }
+ }
+
+ return 0;
+}
+
+static int mpeg4_update_thread_context(AVCodecContext *dst,
+ const AVCodecContext *src)
+{
+ Mpeg4DecContext *s = dst->priv_data;
+ const Mpeg4DecContext *s1 = src->priv_data;
+ int init = s->m.context_initialized;
+
+ int ret = ff_mpeg_update_thread_context(dst, src);
+
+ if (ret < 0)
+ return ret;
+
+ memcpy(((uint8_t*)s) + sizeof(MpegEncContext), ((uint8_t*)s1) + sizeof(MpegEncContext), sizeof(Mpeg4DecContext) - sizeof(MpegEncContext));
+
+ if (CONFIG_MPEG4_DECODER && !init && s1->xvid_build >= 0)
+ ff_xvid_idct_init(&s->m.idsp, dst);
+
+ return 0;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ Mpeg4DecContext *ctx = avctx->priv_data;
+ MpegEncContext *s = &ctx->m;
+ int ret;
+
+ ctx->divx_version =
+ ctx->divx_build =
+ ctx->xvid_build =
+ ctx->lavc_build = -1;
+
+ if ((ret = ff_h263_decode_init(avctx)) < 0)
+ return ret;
+
+ ff_mpeg4videodec_static_init();
+
+ s->h263_pred = 1;
+ s->low_delay = 0; /* default, might be overridden in the vol header during header parsing */
+ s->decode_mb = mpeg4_decode_mb;
+ ctx->time_increment_bits = 4; /* default value for broken headers */
+
+ avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
+ avctx->internal->allocate_progress = 1;
+
+ return 0;
+}
+
+static const AVProfile mpeg4_video_profiles[] = {
+ { FF_PROFILE_MPEG4_SIMPLE, "Simple Profile" },
+ { FF_PROFILE_MPEG4_SIMPLE_SCALABLE, "Simple Scalable Profile" },
+ { FF_PROFILE_MPEG4_CORE, "Core Profile" },
+ { FF_PROFILE_MPEG4_MAIN, "Main Profile" },
+ { FF_PROFILE_MPEG4_N_BIT, "N-bit Profile" },
+ { FF_PROFILE_MPEG4_SCALABLE_TEXTURE, "Scalable Texture Profile" },
+ { FF_PROFILE_MPEG4_SIMPLE_FACE_ANIMATION, "Simple Face Animation Profile" },
+ { FF_PROFILE_MPEG4_BASIC_ANIMATED_TEXTURE, "Basic Animated Texture Profile" },
+ { FF_PROFILE_MPEG4_HYBRID, "Hybrid Profile" },
+ { FF_PROFILE_MPEG4_ADVANCED_REAL_TIME, "Advanced Real Time Simple Profile" },
+ { FF_PROFILE_MPEG4_CORE_SCALABLE, "Code Scalable Profile" },
+ { FF_PROFILE_MPEG4_ADVANCED_CODING, "Advanced Coding Profile" },
+ { FF_PROFILE_MPEG4_ADVANCED_CORE, "Advanced Core Profile" },
+ { FF_PROFILE_MPEG4_ADVANCED_SCALABLE_TEXTURE, "Advanced Scalable Texture Profile" },
+ { FF_PROFILE_MPEG4_SIMPLE_STUDIO, "Simple Studio Profile" },
+ { FF_PROFILE_MPEG4_ADVANCED_SIMPLE, "Advanced Simple Profile" },
+ { FF_PROFILE_UNKNOWN },
+};
+
+static const AVOption mpeg4_options[] = {
+ {"quarter_sample", "1/4 subpel MC", offsetof(MpegEncContext, quarter_sample), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, 0},
+ {"divx_packed", "divx style packed b frames", offsetof(MpegEncContext, divx_packed), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, 0},
+ {NULL}
+};
+
+static const AVClass mpeg4_class = {
+ "MPEG4 Video Decoder",
+ av_default_item_name,
+ mpeg4_options,
+ LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_mpeg4_decoder = {
+ .name = "mpeg4",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MPEG4,
+ .priv_data_size = sizeof(Mpeg4DecContext),
+ .init = decode_init,
+ .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 |
+ AV_CODEC_CAP_FRAME_THREADS,
+ .flush = ff_mpeg_flush,
+ .max_lowres = 3,
+ .pix_fmts = ff_h263_hwaccel_pixfmt_list_420,
+ .profiles = NULL_IF_CONFIG_SMALL(mpeg4_video_profiles),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(mpeg4_update_thread_context),
+ .priv_class = &mpeg4_class,
+};
+
+
+#if CONFIG_MPEG4_VDPAU_DECODER && FF_API_VDPAU
+static const AVClass mpeg4_vdpau_class = {
+ "MPEG4 Video VDPAU Decoder",
+ av_default_item_name,
+ mpeg4_options,
+ LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_mpeg4_vdpau_decoder = {
+ .name = "mpeg4_vdpau",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 (VDPAU)"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MPEG4,
+ .priv_data_size = sizeof(Mpeg4DecContext),
+ .init = decode_init,
+ .close = ff_h263_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_HWACCEL_VDPAU,
+ .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_VDPAU_MPEG4,
+ AV_PIX_FMT_NONE },
+ .priv_class = &mpeg4_vdpau_class,
+};
+#endif
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg4videoenc.c b/ffmpeg-2-8-12/libavcodec/mpeg4videoenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg4videoenc.c
rename to ffmpeg-2-8-12/libavcodec/mpeg4videoenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg_er.c b/ffmpeg-2-8-12/libavcodec/mpeg_er.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg_er.c
rename to ffmpeg-2-8-12/libavcodec/mpeg_er.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpeg_er.h b/ffmpeg-2-8-12/libavcodec/mpeg_er.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpeg_er.h
rename to ffmpeg-2-8-12/libavcodec/mpeg_er.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudio.c b/ffmpeg-2-8-12/libavcodec/mpegaudio.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudio.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudio.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudio.h b/ffmpeg-2-8-12/libavcodec/mpegaudio.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudio.h
rename to ffmpeg-2-8-12/libavcodec/mpegaudio.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudio_parser.c b/ffmpeg-2-8-12/libavcodec/mpegaudio_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudio_parser.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudio_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudio_tablegen.c b/ffmpeg-2-8-12/libavcodec/mpegaudio_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudio_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudio_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudio_tablegen.h b/ffmpeg-2-8-12/libavcodec/mpegaudio_tablegen.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudio_tablegen.h
rename to ffmpeg-2-8-12/libavcodec/mpegaudio_tablegen.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiodata.c b/ffmpeg-2-8-12/libavcodec/mpegaudiodata.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudiodata.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudiodata.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiodata.h b/ffmpeg-2-8-12/libavcodec/mpegaudiodata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudiodata.h
rename to ffmpeg-2-8-12/libavcodec/mpegaudiodata.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiodec_fixed.c b/ffmpeg-2-8-12/libavcodec/mpegaudiodec_fixed.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudiodec_fixed.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudiodec_fixed.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiodec_float.c b/ffmpeg-2-8-12/libavcodec/mpegaudiodec_float.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudiodec_float.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudiodec_float.c
diff --git a/ffmpeg-2-8-12/libavcodec/mpegaudiodec_template.c b/ffmpeg-2-8-12/libavcodec/mpegaudiodec_template.c
new file mode 100644
index 0000000..b5ca664
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/mpegaudiodec_template.c
@@ -0,0 +1,2003 @@
+/*
+ * MPEG Audio decoder
+ * Copyright (c) 2001, 2002 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * MPEG Audio decoder
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/avassert.h"
+#include "libavutil/channel_layout.h"
+#include "libavutil/float_dsp.h"
+#include "libavutil/libm.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "mathops.h"
+#include "mpegaudiodsp.h"
+
+/*
+ * TODO:
+ * - test lsf / mpeg25 extensively.
+ */
+
+#include "mpegaudio.h"
+#include "mpegaudiodecheader.h"
+
+#define BACKSTEP_SIZE 512
+#define EXTRABYTES 24
+#define LAST_BUF_SIZE 2 * BACKSTEP_SIZE + EXTRABYTES
+
+/* layer 3 "granule" */
+typedef struct GranuleDef {
+ uint8_t scfsi;
+ int part2_3_length;
+ int big_values;
+ int global_gain;
+ int scalefac_compress;
+ uint8_t block_type;
+ uint8_t switch_point;
+ int table_select[3];
+ int subblock_gain[3];
+ uint8_t scalefac_scale;
+ uint8_t count1table_select;
+ int region_size[3]; /* number of huffman codes in each region */
+ int preflag;
+ int short_start, long_end; /* long/short band indexes */
+ uint8_t scale_factors[40];
+ DECLARE_ALIGNED(16, INTFLOAT, sb_hybrid)[SBLIMIT * 18]; /* 576 samples */
+} GranuleDef;
+
+typedef struct MPADecodeContext {
+ MPA_DECODE_HEADER
+ uint8_t last_buf[LAST_BUF_SIZE];
+ int last_buf_size;
+ /* next header (used in free format parsing) */
+ uint32_t free_format_next_header;
+ GetBitContext gb;
+ GetBitContext in_gb;
+ DECLARE_ALIGNED(32, MPA_INT, synth_buf)[MPA_MAX_CHANNELS][512 * 2];
+ int synth_buf_offset[MPA_MAX_CHANNELS];
+ DECLARE_ALIGNED(32, INTFLOAT, sb_samples)[MPA_MAX_CHANNELS][36][SBLIMIT];
+ INTFLOAT mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */
+ GranuleDef granules[2][2]; /* Used in Layer 3 */
+ int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3
+ int dither_state;
+ int err_recognition;
+ AVCodecContext* avctx;
+ MPADSPContext mpadsp;
+ AVFloatDSPContext *fdsp;
+ AVFrame *frame;
+} MPADecodeContext;
+
+#define HEADER_SIZE 4
+
+#include "mpegaudiodata.h"
+#include "mpegaudiodectab.h"
+
+/* vlc structure for decoding layer 3 huffman tables */
+static VLC huff_vlc[16];
+static VLC_TYPE huff_vlc_tables[
+ 0 + 128 + 128 + 128 + 130 + 128 + 154 + 166 +
+ 142 + 204 + 190 + 170 + 542 + 460 + 662 + 414
+ ][2];
+static const int huff_vlc_tables_sizes[16] = {
+ 0, 128, 128, 128, 130, 128, 154, 166,
+ 142, 204, 190, 170, 542, 460, 662, 414
+};
+static VLC huff_quad_vlc[2];
+static VLC_TYPE huff_quad_vlc_tables[128+16][2];
+static const int huff_quad_vlc_tables_sizes[2] = { 128, 16 };
+/* computed from band_size_long */
+static uint16_t band_index_long[9][23];
+#include "mpegaudio_tablegen.h"
+/* intensity stereo coef table */
+static INTFLOAT is_table[2][16];
+static INTFLOAT is_table_lsf[2][2][16];
+static INTFLOAT csa_table[8][4];
+
+static int16_t division_tab3[1<<6 ];
+static int16_t division_tab5[1<<8 ];
+static int16_t division_tab9[1<<11];
+
+static int16_t * const division_tabs[4] = {
+ division_tab3, division_tab5, NULL, division_tab9
+};
+
+/* lower 2 bits: modulo 3, higher bits: shift */
+static uint16_t scale_factor_modshift[64];
+/* [i][j]: 2^(-j/3) * FRAC_ONE * 2^(i+2) / (2^(i+2) - 1) */
+static int32_t scale_factor_mult[15][3];
+/* mult table for layer 2 group quantization */
+
+#define SCALE_GEN(v) \
+{ FIXR_OLD(1.0 * (v)), FIXR_OLD(0.7937005259 * (v)), FIXR_OLD(0.6299605249 * (v)) }
+
+static const int32_t scale_factor_mult2[3][3] = {
+ SCALE_GEN(4.0 / 3.0), /* 3 steps */
+ SCALE_GEN(4.0 / 5.0), /* 5 steps */
+ SCALE_GEN(4.0 / 9.0), /* 9 steps */
+};
+
+/**
+ * Convert region offsets to region sizes and truncate
+ * size to big_values.
+ */
+static void region_offset2size(GranuleDef *g)
+{
+ int i, k, j = 0;
+ g->region_size[2] = 576 / 2;
+ for (i = 0; i < 3; i++) {
+ k = FFMIN(g->region_size[i], g->big_values);
+ g->region_size[i] = k - j;
+ j = k;
+ }
+}
+
+static void init_short_region(MPADecodeContext *s, GranuleDef *g)
+{
+ if (g->block_type == 2) {
+ if (s->sample_rate_index != 8)
+ g->region_size[0] = (36 / 2);
+ else
+ g->region_size[0] = (72 / 2);
+ } else {
+ if (s->sample_rate_index <= 2)
+ g->region_size[0] = (36 / 2);
+ else if (s->sample_rate_index != 8)
+ g->region_size[0] = (54 / 2);
+ else
+ g->region_size[0] = (108 / 2);
+ }
+ g->region_size[1] = (576 / 2);
+}
+
+static void init_long_region(MPADecodeContext *s, GranuleDef *g,
+ int ra1, int ra2)
+{
+ int l;
+ g->region_size[0] = band_index_long[s->sample_rate_index][ra1 + 1] >> 1;
+ /* should not overflow */
+ l = FFMIN(ra1 + ra2 + 2, 22);
+ g->region_size[1] = band_index_long[s->sample_rate_index][ l] >> 1;
+}
+
+static void compute_band_indexes(MPADecodeContext *s, GranuleDef *g)
+{
+ if (g->block_type == 2) {
+ if (g->switch_point) {
+ if(s->sample_rate_index == 8)
+ avpriv_request_sample(s->avctx, "switch point in 8khz");
+ /* if switched mode, we handle the 36 first samples as
+ long blocks. For 8000Hz, we handle the 72 first
+ exponents as long blocks */
+ if (s->sample_rate_index <= 2)
+ g->long_end = 8;
+ else
+ g->long_end = 6;
+
+ g->short_start = 3;
+ } else {
+ g->long_end = 0;
+ g->short_start = 0;
+ }
+ } else {
+ g->short_start = 13;
+ g->long_end = 22;
+ }
+}
+
+/* layer 1 unscaling */
+/* n = number of bits of the mantissa minus 1 */
+static inline int l1_unscale(int n, int mant, int scale_factor)
+{
+ int shift, mod;
+ int64_t val;
+
+ shift = scale_factor_modshift[scale_factor];
+ mod = shift & 3;
+ shift >>= 2;
+ val = MUL64((int)(mant + (-1U << n) + 1), scale_factor_mult[n-1][mod]);
+ shift += n;
+ /* NOTE: at this point, 1 <= shift >= 21 + 15 */
+ return (int)((val + (1LL << (shift - 1))) >> shift);
+}
+
+static inline int l2_unscale_group(int steps, int mant, int scale_factor)
+{
+ int shift, mod, val;
+
+ shift = scale_factor_modshift[scale_factor];
+ mod = shift & 3;
+ shift >>= 2;
+
+ val = (mant - (steps >> 1)) * scale_factor_mult2[steps >> 2][mod];
+ /* NOTE: at this point, 0 <= shift <= 21 */
+ if (shift > 0)
+ val = (val + (1 << (shift - 1))) >> shift;
+ return val;
+}
+
+/* compute value^(4/3) * 2^(exponent/4). It normalized to FRAC_BITS */
+static inline int l3_unscale(int value, int exponent)
+{
+ unsigned int m;
+ int e;
+
+ e = table_4_3_exp [4 * value + (exponent & 3)];
+ m = table_4_3_value[4 * value + (exponent & 3)];
+ e -= exponent >> 2;
+#ifdef DEBUG
+ if(e < 1)
+ av_log(NULL, AV_LOG_WARNING, "l3_unscale: e is %d\n", e);
+#endif
+ if (e > 31)
+ return 0;
+ m = (m + ((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);
+ }
+
+ /* scale factor multiply for layer 1 */
+ for (i = 0; i < 15; i++) {
+ int n, norm;
+ n = i + 2;
+ norm = ((INT64_C(1) << n) * FRAC_ONE) / ((1 << n) - 1);
+ scale_factor_mult[i][0] = MULLx(norm, FIXR(1.0 * 2.0), FRAC_BITS);
+ scale_factor_mult[i][1] = MULLx(norm, FIXR(0.7937005259 * 2.0), FRAC_BITS);
+ scale_factor_mult[i][2] = MULLx(norm, FIXR(0.6299605249 * 2.0), FRAC_BITS);
+ ff_dlog(NULL, "%d: norm=%x s=%x %x %x\n", i, norm,
+ scale_factor_mult[i][0],
+ scale_factor_mult[i][1],
+ scale_factor_mult[i][2]);
+ }
+
+ RENAME(ff_mpa_synth_init)(RENAME(ff_mpa_synth_window));
+
+ /* huffman decode tables */
+ offset = 0;
+ for (i = 1; i < 16; i++) {
+ const HuffTable *h = &mpa_huff_tables[i];
+ int xsize, x, y;
+ uint8_t tmp_bits [512] = { 0 };
+ uint16_t tmp_codes[512] = { 0 };
+
+ xsize = h->xsize;
+
+ j = 0;
+ for (x = 0; x < xsize; x++) {
+ for (y = 0; y < xsize; y++) {
+ tmp_bits [(x << 5) | y | ((x&&y)<<4)]= h->bits [j ];
+ tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++];
+ }
+ }
+
+ /* XXX: fail test */
+ huff_vlc[i].table = huff_vlc_tables+offset;
+ huff_vlc[i].table_allocated = huff_vlc_tables_sizes[i];
+ init_vlc(&huff_vlc[i], 7, 512,
+ tmp_bits, 1, 1, tmp_codes, 2, 2,
+ INIT_VLC_USE_NEW_STATIC);
+ offset += huff_vlc_tables_sizes[i];
+ }
+ av_assert0(offset == FF_ARRAY_ELEMS(huff_vlc_tables));
+
+ offset = 0;
+ for (i = 0; i < 2; i++) {
+ huff_quad_vlc[i].table = huff_quad_vlc_tables+offset;
+ huff_quad_vlc[i].table_allocated = huff_quad_vlc_tables_sizes[i];
+ init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16,
+ mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1,
+ INIT_VLC_USE_NEW_STATIC);
+ offset += huff_quad_vlc_tables_sizes[i];
+ }
+ av_assert0(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables));
+
+ for (i = 0; i < 9; i++) {
+ k = 0;
+ for (j = 0; j < 22; j++) {
+ band_index_long[i][j] = k;
+ k += band_size_long[i][j];
+ }
+ band_index_long[i][22] = k;
+ }
+
+ /* compute n ^ (4/3) and store it in mantissa/exp format */
+
+ mpegaudio_tableinit();
+
+ for (i = 0; i < 4; i++) {
+ if (ff_mpa_quant_bits[i] < 0) {
+ for (j = 0; j < (1 << (-ff_mpa_quant_bits[i]+1)); j++) {
+ int val1, val2, val3, steps;
+ int val = j;
+ steps = ff_mpa_quant_steps[i];
+ val1 = val % steps;
+ val /= steps;
+ val2 = val % steps;
+ val3 = val / steps;
+ division_tabs[i][j] = val1 + (val2 << 4) + (val3 << 8);
+ }
+ }
+ }
+
+
+ for (i = 0; i < 7; i++) {
+ float f;
+ INTFLOAT v;
+ if (i != 6) {
+ f = tan((double)i * M_PI / 12.0);
+ v = FIXR(f / (1.0 + f));
+ } else {
+ v = FIXR(1.0);
+ }
+ is_table[0][ i] = v;
+ is_table[1][6 - i] = v;
+ }
+ /* invalid values */
+ for (i = 7; i < 16; i++)
+ is_table[0][i] = is_table[1][i] = 0.0;
+
+ for (i = 0; i < 16; i++) {
+ double f;
+ int e, k;
+
+ for (j = 0; j < 2; j++) {
+ e = -(j + 1) * ((i + 1) >> 1);
+ f = exp2(e / 4.0);
+ k = i & 1;
+ is_table_lsf[j][k ^ 1][i] = FIXR(f);
+ is_table_lsf[j][k ][i] = FIXR(1.0);
+ ff_dlog(NULL, "is_table_lsf %d %d: %f %f\n",
+ i, j, (float) is_table_lsf[j][0][i],
+ (float) is_table_lsf[j][1][i]);
+ }
+ }
+
+ for (i = 0; i < 8; i++) {
+ 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
+ }
+}
+
+#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;
+ 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);
+#endif
+
+ ff_mpadsp_init(&s->mpadsp);
+
+ if (avctx->request_sample_fmt == OUT_FMT &&
+ avctx->codec_id != AV_CODEC_ID_MP3ON4)
+ avctx->sample_fmt = OUT_FMT;
+ else
+ avctx->sample_fmt = OUT_FMT_P;
+ s->err_recognition = avctx->err_recognition;
+
+ if (avctx->codec_id == AV_CODEC_ID_MP3ADU)
+ s->adu_mode = 1;
+
+ return 0;
+}
+
+#define C3 FIXHR(0.86602540378443864676/2)
+#define C4 FIXHR(0.70710678118654752439/2) //0.5 / cos(pi*(9)/36)
+#define C5 FIXHR(0.51763809020504152469/2) //0.5 / cos(pi*(5)/36)
+#define C6 FIXHR(1.93185165257813657349/4) //0.5 / cos(pi*(15)/36)
+
+/* 12 points IMDCT. We compute it "by hand" by factorizing obvious
+ cases. */
+static void imdct12(INTFLOAT *out, INTFLOAT *in)
+{
+ INTFLOAT in0, in1, in2, in3, in4, in5, t1, t2;
+
+ in0 = in[0*3];
+ in1 = in[1*3] + in[0*3];
+ in2 = in[2*3] + in[1*3];
+ in3 = in[3*3] + in[2*3];
+ in4 = in[4*3] + in[3*3];
+ in5 = in[5*3] + in[4*3];
+ in5 += in3;
+ in3 += in1;
+
+ in2 = MULH3(in2, C3, 2);
+ in3 = MULH3(in3, C3, 4);
+
+ t1 = in0 - in4;
+ t2 = MULH3(in1 - in5, C4, 2);
+
+ out[ 7] =
+ out[10] = t1 + t2;
+ out[ 1] =
+ out[ 4] = t1 - t2;
+
+ in0 += SHR(in4, 1);
+ in4 = in0 + in2;
+ in5 += 2*in1;
+ in1 = MULH3(in5 + in3, C5, 1);
+ out[ 8] =
+ out[ 9] = in4 + in1;
+ out[ 2] =
+ out[ 3] = in4 - in1;
+
+ in0 -= in2;
+ in5 = MULH3(in5 - in3, C6, 2);
+ out[ 0] =
+ out[ 5] = in0 - in5;
+ out[ 6] =
+ out[11] = in0 + in5;
+}
+
+/* return the number of decoded frames */
+static int mp_decode_layer1(MPADecodeContext *s)
+{
+ int bound, i, v, n, ch, j, mant;
+ uint8_t allocation[MPA_MAX_CHANNELS][SBLIMIT];
+ uint8_t scale_factors[MPA_MAX_CHANNELS][SBLIMIT];
+
+ if (s->mode == MPA_JSTEREO)
+ bound = (s->mode_ext + 1) * 4;
+ else
+ bound = SBLIMIT;
+
+ /* allocation bits */
+ for (i = 0; i < bound; i++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
+ allocation[ch][i] = get_bits(&s->gb, 4);
+ }
+ }
+ for (i = bound; i < SBLIMIT; i++)
+ allocation[0][i] = get_bits(&s->gb, 4);
+
+ /* scale factors */
+ for (i = 0; i < bound; i++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
+ if (allocation[ch][i])
+ scale_factors[ch][i] = get_bits(&s->gb, 6);
+ }
+ }
+ for (i = bound; i < SBLIMIT; i++) {
+ if (allocation[0][i]) {
+ scale_factors[0][i] = get_bits(&s->gb, 6);
+ scale_factors[1][i] = get_bits(&s->gb, 6);
+ }
+ }
+
+ /* compute samples */
+ for (j = 0; j < 12; j++) {
+ for (i = 0; i < bound; i++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
+ n = allocation[ch][i];
+ if (n) {
+ mant = get_bits(&s->gb, n + 1);
+ v = l1_unscale(n, mant, scale_factors[ch][i]);
+ } else {
+ v = 0;
+ }
+ s->sb_samples[ch][j][i] = v;
+ }
+ }
+ for (i = bound; i < SBLIMIT; i++) {
+ n = allocation[0][i];
+ if (n) {
+ mant = get_bits(&s->gb, n + 1);
+ v = l1_unscale(n, mant, scale_factors[0][i]);
+ s->sb_samples[0][j][i] = v;
+ v = l1_unscale(n, mant, scale_factors[1][i]);
+ s->sb_samples[1][j][i] = v;
+ } else {
+ s->sb_samples[0][j][i] = 0;
+ s->sb_samples[1][j][i] = 0;
+ }
+ }
+ }
+ return 12;
+}
+
+static int mp_decode_layer2(MPADecodeContext *s)
+{
+ int sblimit; /* number of used subbands */
+ const unsigned char *alloc_table;
+ int table, bit_alloc_bits, i, j, ch, bound, v;
+ unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT];
+ unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT];
+ unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3], *sf;
+ int scale, qindex, bits, steps, k, l, m, b;
+
+ /* select decoding table */
+ table = ff_mpa_l2_select_table(s->bit_rate / 1000, s->nb_channels,
+ s->sample_rate, s->lsf);
+ sblimit = ff_mpa_sblimit_table[table];
+ alloc_table = ff_mpa_alloc_tables[table];
+
+ if (s->mode == MPA_JSTEREO)
+ bound = (s->mode_ext + 1) * 4;
+ else
+ bound = sblimit;
+
+ ff_dlog(s->avctx, "bound=%d sblimit=%d\n", bound, sblimit);
+
+ /* sanity check */
+ if (bound > sblimit)
+ bound = sblimit;
+
+ /* parse bit allocation */
+ j = 0;
+ for (i = 0; i < bound; i++) {
+ bit_alloc_bits = alloc_table[j];
+ for (ch = 0; ch < s->nb_channels; ch++)
+ bit_alloc[ch][i] = get_bits(&s->gb, bit_alloc_bits);
+ j += 1 << bit_alloc_bits;
+ }
+ for (i = bound; i < sblimit; i++) {
+ bit_alloc_bits = alloc_table[j];
+ v = get_bits(&s->gb, bit_alloc_bits);
+ bit_alloc[0][i] = v;
+ bit_alloc[1][i] = v;
+ j += 1 << bit_alloc_bits;
+ }
+
+ /* scale codes */
+ for (i = 0; i < sblimit; i++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
+ if (bit_alloc[ch][i])
+ scale_code[ch][i] = get_bits(&s->gb, 2);
+ }
+ }
+
+ /* scale factors */
+ for (i = 0; i < sblimit; i++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
+ if (bit_alloc[ch][i]) {
+ sf = scale_factors[ch][i];
+ switch (scale_code[ch][i]) {
+ default:
+ case 0:
+ sf[0] = get_bits(&s->gb, 6);
+ sf[1] = get_bits(&s->gb, 6);
+ sf[2] = get_bits(&s->gb, 6);
+ break;
+ case 2:
+ sf[0] = get_bits(&s->gb, 6);
+ sf[1] = sf[0];
+ sf[2] = sf[0];
+ break;
+ case 1:
+ sf[0] = get_bits(&s->gb, 6);
+ sf[2] = get_bits(&s->gb, 6);
+ sf[1] = sf[0];
+ break;
+ case 3:
+ sf[0] = get_bits(&s->gb, 6);
+ sf[2] = get_bits(&s->gb, 6);
+ sf[1] = sf[2];
+ break;
+ }
+ }
+ }
+ }
+
+ /* samples */
+ for (k = 0; k < 3; k++) {
+ for (l = 0; l < 12; l += 3) {
+ j = 0;
+ for (i = 0; i < bound; i++) {
+ bit_alloc_bits = alloc_table[j];
+ for (ch = 0; ch < s->nb_channels; ch++) {
+ b = bit_alloc[ch][i];
+ if (b) {
+ scale = scale_factors[ch][i][k];
+ qindex = alloc_table[j+b];
+ bits = ff_mpa_quant_bits[qindex];
+ if (bits < 0) {
+ int v2;
+ /* 3 values at the same time */
+ v = get_bits(&s->gb, -bits);
+ v2 = division_tabs[qindex][v];
+ steps = ff_mpa_quant_steps[qindex];
+
+ s->sb_samples[ch][k * 12 + l + 0][i] =
+ l2_unscale_group(steps, v2 & 15, scale);
+ s->sb_samples[ch][k * 12 + l + 1][i] =
+ l2_unscale_group(steps, (v2 >> 4) & 15, scale);
+ s->sb_samples[ch][k * 12 + l + 2][i] =
+ l2_unscale_group(steps, v2 >> 8 , scale);
+ } else {
+ for (m = 0; m < 3; m++) {
+ v = get_bits(&s->gb, bits);
+ v = l1_unscale(bits - 1, v, scale);
+ s->sb_samples[ch][k * 12 + l + m][i] = v;
+ }
+ }
+ } else {
+ s->sb_samples[ch][k * 12 + l + 0][i] = 0;
+ s->sb_samples[ch][k * 12 + l + 1][i] = 0;
+ s->sb_samples[ch][k * 12 + l + 2][i] = 0;
+ }
+ }
+ /* next subband in alloc table */
+ j += 1 << bit_alloc_bits;
+ }
+ /* XXX: find a way to avoid this duplication of code */
+ for (i = bound; i < sblimit; i++) {
+ bit_alloc_bits = alloc_table[j];
+ b = bit_alloc[0][i];
+ if (b) {
+ int mant, scale0, scale1;
+ scale0 = scale_factors[0][i][k];
+ scale1 = scale_factors[1][i][k];
+ qindex = alloc_table[j+b];
+ bits = ff_mpa_quant_bits[qindex];
+ if (bits < 0) {
+ /* 3 values at the same time */
+ v = get_bits(&s->gb, -bits);
+ steps = ff_mpa_quant_steps[qindex];
+ mant = v % steps;
+ v = v / steps;
+ s->sb_samples[0][k * 12 + l + 0][i] =
+ l2_unscale_group(steps, mant, scale0);
+ s->sb_samples[1][k * 12 + l + 0][i] =
+ l2_unscale_group(steps, mant, scale1);
+ mant = v % steps;
+ v = v / steps;
+ s->sb_samples[0][k * 12 + l + 1][i] =
+ l2_unscale_group(steps, mant, scale0);
+ s->sb_samples[1][k * 12 + l + 1][i] =
+ l2_unscale_group(steps, mant, scale1);
+ s->sb_samples[0][k * 12 + l + 2][i] =
+ l2_unscale_group(steps, v, scale0);
+ s->sb_samples[1][k * 12 + l + 2][i] =
+ l2_unscale_group(steps, v, scale1);
+ } else {
+ for (m = 0; m < 3; m++) {
+ mant = get_bits(&s->gb, bits);
+ s->sb_samples[0][k * 12 + l + m][i] =
+ l1_unscale(bits - 1, mant, scale0);
+ s->sb_samples[1][k * 12 + l + m][i] =
+ l1_unscale(bits - 1, mant, scale1);
+ }
+ }
+ } else {
+ s->sb_samples[0][k * 12 + l + 0][i] = 0;
+ s->sb_samples[0][k * 12 + l + 1][i] = 0;
+ s->sb_samples[0][k * 12 + l + 2][i] = 0;
+ s->sb_samples[1][k * 12 + l + 0][i] = 0;
+ s->sb_samples[1][k * 12 + l + 1][i] = 0;
+ s->sb_samples[1][k * 12 + l + 2][i] = 0;
+ }
+ /* next subband in alloc table */
+ j += 1 << bit_alloc_bits;
+ }
+ /* fill remaining samples to zero */
+ for (i = sblimit; i < SBLIMIT; i++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
+ s->sb_samples[ch][k * 12 + l + 0][i] = 0;
+ s->sb_samples[ch][k * 12 + l + 1][i] = 0;
+ s->sb_samples[ch][k * 12 + l + 2][i] = 0;
+ }
+ }
+ }
+ }
+ return 3 * 12;
+}
+
+#define SPLIT(dst,sf,n) \
+ if (n == 3) { \
+ int m = (sf * 171) >> 9; \
+ dst = sf - 3 * m; \
+ sf = m; \
+ } else if (n == 4) { \
+ dst = sf & 3; \
+ sf >>= 2; \
+ } else if (n == 5) { \
+ int m = (sf * 205) >> 10; \
+ dst = sf - 5 * m; \
+ sf = m; \
+ } else if (n == 6) { \
+ int m = (sf * 171) >> 10; \
+ dst = sf - 6 * m; \
+ sf = m; \
+ } else { \
+ dst = 0; \
+ }
+
+static av_always_inline void lsf_sf_expand(int *slen, int sf, int n1, int n2,
+ int n3)
+{
+ SPLIT(slen[3], sf, n3)
+ SPLIT(slen[2], sf, n2)
+ SPLIT(slen[1], sf, n1)
+ slen[0] = sf;
+}
+
+static void exponents_from_scale_factors(MPADecodeContext *s, GranuleDef *g,
+ int16_t *exponents)
+{
+ const uint8_t *bstab, *pretab;
+ int len, i, j, k, l, v0, shift, gain, gains[3];
+ int16_t *exp_ptr;
+
+ exp_ptr = exponents;
+ gain = g->global_gain - 210;
+ shift = g->scalefac_scale + 1;
+
+ bstab = band_size_long[s->sample_rate_index];
+ pretab = mpa_pretab[g->preflag];
+ for (i = 0; i < g->long_end; i++) {
+ v0 = gain - ((g->scale_factors[i] + pretab[i]) << shift) + 400;
+ len = bstab[i];
+ for (j = len; j > 0; j--)
+ *exp_ptr++ = v0;
+ }
+
+ if (g->short_start < 13) {
+ bstab = band_size_short[s->sample_rate_index];
+ gains[0] = gain - (g->subblock_gain[0] << 3);
+ gains[1] = gain - (g->subblock_gain[1] << 3);
+ gains[2] = gain - (g->subblock_gain[2] << 3);
+ k = g->long_end;
+ for (i = g->short_start; i < 13; i++) {
+ len = bstab[i];
+ for (l = 0; l < 3; l++) {
+ v0 = gains[l] - (g->scale_factors[k++] << shift) + 400;
+ for (j = len; j > 0; j--)
+ *exp_ptr++ = v0;
+ }
+ }
+ }
+}
+
+/* handle n = 0 too */
+static inline int get_bitsz(GetBitContext *s, int n)
+{
+ return n ? get_bits(s, n) : 0;
+}
+
+
+static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos,
+ int *end_pos2)
+{
+ if (s->in_gb.buffer && *pos >= s->gb.size_in_bits) {
+ s->gb = s->in_gb;
+ s->in_gb.buffer = NULL;
+ av_assert2((get_bits_count(&s->gb) & 7) == 0);
+ skip_bits_long(&s->gb, *pos - *end_pos);
+ *end_pos2 =
+ *end_pos = *end_pos2 + get_bits_count(&s->gb) - *pos;
+ *pos = get_bits_count(&s->gb);
+ }
+}
+
+/* Following is a optimized code for
+ INTFLOAT v = *src
+ if(get_bits1(&s->gb))
+ v = -v;
+ *dst = v;
+*/
+#if USE_FLOATS
+#define READ_FLIP_SIGN(dst,src) \
+ v = AV_RN32A(src) ^ (get_bits1(&s->gb) << 31); \
+ AV_WN32A(dst, v);
+#else
+#define READ_FLIP_SIGN(dst,src) \
+ v = -get_bits1(&s->gb); \
+ *(dst) = (*(src) ^ v) - v;
+#endif
+
+static int huffman_decode(MPADecodeContext *s, GranuleDef *g,
+ int16_t *exponents, int end_pos2)
+{
+ int s_index;
+ int i;
+ int last_pos, bits_left;
+ VLC *vlc;
+ int end_pos = FFMIN(end_pos2, s->gb.size_in_bits);
+
+ /* low frequencies (called big values) */
+ s_index = 0;
+ for (i = 0; i < 3; i++) {
+ int j, k, l, linbits;
+ j = g->region_size[i];
+ if (j == 0)
+ continue;
+ /* select vlc table */
+ k = g->table_select[i];
+ l = mpa_huff_data[k][0];
+ linbits = mpa_huff_data[k][1];
+ vlc = &huff_vlc[l];
+
+ if (!l) {
+ memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * 2 * j);
+ s_index += 2 * j;
+ continue;
+ }
+
+ /* read huffcode and compute each couple */
+ for (; j > 0; j--) {
+ int exponent, x, y;
+ int v;
+ int pos = get_bits_count(&s->gb);
+
+ if (pos >= end_pos){
+ switch_buffer(s, &pos, &end_pos, &end_pos2);
+ if (pos >= end_pos)
+ break;
+ }
+ y = get_vlc2(&s->gb, vlc->table, 7, 3);
+
+ if (!y) {
+ g->sb_hybrid[s_index ] =
+ g->sb_hybrid[s_index+1] = 0;
+ s_index += 2;
+ continue;
+ }
+
+ exponent= exponents[s_index];
+
+ ff_dlog(s->avctx, "region=%d n=%d x=%d y=%d exp=%d\n",
+ i, g->region_size[i] - j, x, y, exponent);
+ if (y & 16) {
+ x = y >> 5;
+ y = y & 0x0f;
+ if (x < 15) {
+ READ_FLIP_SIGN(g->sb_hybrid + s_index, RENAME(expval_table)[exponent] + x)
+ } else {
+ x += get_bitsz(&s->gb, linbits);
+ v = l3_unscale(x, exponent);
+ if (get_bits1(&s->gb))
+ v = -v;
+ g->sb_hybrid[s_index] = v;
+ }
+ if (y < 15) {
+ READ_FLIP_SIGN(g->sb_hybrid + s_index + 1, RENAME(expval_table)[exponent] + y)
+ } else {
+ y += get_bitsz(&s->gb, linbits);
+ v = l3_unscale(y, exponent);
+ if (get_bits1(&s->gb))
+ v = -v;
+ g->sb_hybrid[s_index+1] = v;
+ }
+ } else {
+ x = y >> 5;
+ y = y & 0x0f;
+ x += y;
+ if (x < 15) {
+ READ_FLIP_SIGN(g->sb_hybrid + s_index + !!y, RENAME(expval_table)[exponent] + x)
+ } else {
+ x += get_bitsz(&s->gb, linbits);
+ v = l3_unscale(x, exponent);
+ if (get_bits1(&s->gb))
+ v = -v;
+ g->sb_hybrid[s_index+!!y] = v;
+ }
+ g->sb_hybrid[s_index + !y] = 0;
+ }
+ s_index += 2;
+ }
+ }
+
+ /* high frequencies */
+ vlc = &huff_quad_vlc[g->count1table_select];
+ last_pos = 0;
+ while (s_index <= 572) {
+ int pos, code;
+ pos = get_bits_count(&s->gb);
+ if (pos >= end_pos) {
+ if (pos > end_pos2 && last_pos) {
+ /* some encoders generate an incorrect size for this
+ part. We must go back into the data */
+ s_index -= 4;
+ skip_bits_long(&s->gb, last_pos - pos);
+ av_log(s->avctx, AV_LOG_INFO, "overread, skip %d enddists: %d %d\n", last_pos - pos, end_pos-pos, end_pos2-pos);
+ if(s->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))
+ s_index=0;
+ break;
+ }
+ switch_buffer(s, &pos, &end_pos, &end_pos2);
+ if (pos >= end_pos)
+ break;
+ }
+ last_pos = pos;
+
+ code = get_vlc2(&s->gb, vlc->table, vlc->bits, 1);
+ 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;
+ while (code) {
+ static const int idxtab[16] = { 3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0 };
+ int v;
+ int pos = s_index + idxtab[code];
+ code ^= 8 >> idxtab[code];
+ READ_FLIP_SIGN(g->sb_hybrid + pos, RENAME(exp_table)+exponents[pos])
+ }
+ s_index += 4;
+ }
+ /* skip extension bits */
+ bits_left = end_pos2 - get_bits_count(&s->gb);
+ if (bits_left < 0 && (s->err_recognition & (AV_EF_BUFFER|AV_EF_COMPLIANT))) {
+ av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
+ s_index=0;
+ } else if (bits_left > 0 && (s->err_recognition & (AV_EF_BUFFER|AV_EF_AGGRESSIVE))) {
+ av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left);
+ s_index = 0;
+ }
+ memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * (576 - s_index));
+ skip_bits_long(&s->gb, bits_left);
+
+ i = get_bits_count(&s->gb);
+ switch_buffer(s, &i, &end_pos, &end_pos2);
+
+ return 0;
+}
+
+/* Reorder short blocks from bitstream order to interleaved order. It
+ would be faster to do it in parsing, but the code would be far more
+ complicated */
+static void reorder_block(MPADecodeContext *s, GranuleDef *g)
+{
+ int i, j, len;
+ INTFLOAT *ptr, *dst, *ptr1;
+ INTFLOAT tmp[576];
+
+ if (g->block_type != 2)
+ return;
+
+ if (g->switch_point) {
+ if (s->sample_rate_index != 8)
+ ptr = g->sb_hybrid + 36;
+ else
+ ptr = g->sb_hybrid + 72;
+ } else {
+ ptr = g->sb_hybrid;
+ }
+
+ for (i = g->short_start; i < 13; i++) {
+ len = band_size_short[s->sample_rate_index][i];
+ ptr1 = ptr;
+ dst = tmp;
+ for (j = len; j > 0; j--) {
+ *dst++ = ptr[0*len];
+ *dst++ = ptr[1*len];
+ *dst++ = ptr[2*len];
+ ptr++;
+ }
+ ptr += 2 * len;
+ memcpy(ptr1, tmp, len * 3 * sizeof(*ptr1));
+ }
+}
+
+#define ISQRT2 FIXR(0.70710678118654752440)
+
+static void compute_stereo(MPADecodeContext *s, GranuleDef *g0, GranuleDef *g1)
+{
+ int i, j, k, l;
+ int sf_max, sf, len, non_zero_found;
+ INTFLOAT (*is_tab)[16], *tab0, *tab1, tmp0, tmp1, v1, v2;
+ int non_zero_found_short[3];
+
+ /* intensity stereo */
+ if (s->mode_ext & MODE_EXT_I_STEREO) {
+ if (!s->lsf) {
+ is_tab = is_table;
+ sf_max = 7;
+ } else {
+ is_tab = is_table_lsf[g1->scalefac_compress & 1];
+ sf_max = 16;
+ }
+
+ tab0 = g0->sb_hybrid + 576;
+ tab1 = g1->sb_hybrid + 576;
+
+ non_zero_found_short[0] = 0;
+ non_zero_found_short[1] = 0;
+ non_zero_found_short[2] = 0;
+ k = (13 - g1->short_start) * 3 + g1->long_end - 3;
+ for (i = 12; i >= g1->short_start; i--) {
+ /* for last band, use previous scale factor */
+ if (i != 11)
+ k -= 3;
+ len = band_size_short[s->sample_rate_index][i];
+ for (l = 2; l >= 0; l--) {
+ tab0 -= len;
+ tab1 -= len;
+ if (!non_zero_found_short[l]) {
+ /* test if non zero band. if so, stop doing i-stereo */
+ for (j = 0; j < len; j++) {
+ if (tab1[j] != 0) {
+ non_zero_found_short[l] = 1;
+ goto found1;
+ }
+ }
+ sf = g1->scale_factors[k + l];
+ if (sf >= sf_max)
+ goto found1;
+
+ v1 = is_tab[0][sf];
+ v2 = is_tab[1][sf];
+ for (j = 0; j < len; j++) {
+ tmp0 = tab0[j];
+ tab0[j] = MULLx(tmp0, v1, FRAC_BITS);
+ tab1[j] = MULLx(tmp0, v2, FRAC_BITS);
+ }
+ } else {
+found1:
+ if (s->mode_ext & MODE_EXT_MS_STEREO) {
+ /* lower part of the spectrum : do ms stereo
+ if enabled */
+ for (j = 0; j < len; j++) {
+ tmp0 = tab0[j];
+ tmp1 = tab1[j];
+ tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS);
+ tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS);
+ }
+ }
+ }
+ }
+ }
+
+ non_zero_found = non_zero_found_short[0] |
+ non_zero_found_short[1] |
+ non_zero_found_short[2];
+
+ for (i = g1->long_end - 1;i >= 0;i--) {
+ len = band_size_long[s->sample_rate_index][i];
+ tab0 -= len;
+ tab1 -= len;
+ /* test if non zero band. if so, stop doing i-stereo */
+ if (!non_zero_found) {
+ for (j = 0; j < len; j++) {
+ if (tab1[j] != 0) {
+ non_zero_found = 1;
+ goto found2;
+ }
+ }
+ /* for last band, use previous scale factor */
+ k = (i == 21) ? 20 : i;
+ sf = g1->scale_factors[k];
+ if (sf >= sf_max)
+ goto found2;
+ v1 = is_tab[0][sf];
+ v2 = is_tab[1][sf];
+ for (j = 0; j < len; j++) {
+ tmp0 = tab0[j];
+ tab0[j] = MULLx(tmp0, v1, FRAC_BITS);
+ tab1[j] = MULLx(tmp0, v2, FRAC_BITS);
+ }
+ } else {
+found2:
+ if (s->mode_ext & MODE_EXT_MS_STEREO) {
+ /* lower part of the spectrum : do ms stereo
+ if enabled */
+ for (j = 0; j < len; j++) {
+ tmp0 = tab0[j];
+ tmp1 = tab1[j];
+ tab0[j] = MULLx(tmp0 + tmp1, ISQRT2, FRAC_BITS);
+ tab1[j] = MULLx(tmp0 - tmp1, ISQRT2, FRAC_BITS);
+ }
+ }
+ }
+ }
+ } else if (s->mode_ext & MODE_EXT_MS_STEREO) {
+ /* ms stereo ONLY */
+ /* NOTE: the 1/sqrt(2) normalization factor is included in the
+ global gain */
+#if USE_FLOATS
+ s->fdsp->butterflies_float(g0->sb_hybrid, g1->sb_hybrid, 576);
+#else
+ tab0 = g0->sb_hybrid;
+ tab1 = g1->sb_hybrid;
+ for (i = 0; i < 576; i++) {
+ tmp0 = tab0[i];
+ tmp1 = tab1[i];
+ tab0[i] = tmp0 + tmp1;
+ tab1[i] = tmp0 - tmp1;
+ }
+#endif
+ }
+}
+
+#if USE_FLOATS
+#if HAVE_MIPSFPU
+# include "mips/compute_antialias_float.h"
+#endif /* HAVE_MIPSFPU */
+#else
+#if HAVE_MIPSDSPR1
+# include "mips/compute_antialias_fixed.h"
+#endif /* HAVE_MIPSDSPR1 */
+#endif /* USE_FLOATS */
+
+#ifndef compute_antialias
+#if USE_FLOATS
+#define AA(j) do { \
+ float tmp0 = ptr[-1-j]; \
+ float tmp1 = ptr[ j]; \
+ ptr[-1-j] = tmp0 * csa_table[j][0] - tmp1 * csa_table[j][1]; \
+ ptr[ j] = tmp0 * csa_table[j][1] + tmp1 * csa_table[j][0]; \
+ } while (0)
+#else
+#define AA(j) do { \
+ int tmp0 = ptr[-1-j]; \
+ int tmp1 = ptr[ j]; \
+ int tmp2 = MULH(tmp0 + tmp1, csa_table[j][0]); \
+ ptr[-1-j] = 4 * (tmp2 - MULH(tmp1, csa_table[j][2])); \
+ ptr[ j] = 4 * (tmp2 + MULH(tmp0, csa_table[j][3])); \
+ } while (0)
+#endif
+
+static void compute_antialias(MPADecodeContext *s, GranuleDef *g)
+{
+ INTFLOAT *ptr;
+ int n, i;
+
+ /* we antialias only "long" bands */
+ if (g->block_type == 2) {
+ if (!g->switch_point)
+ return;
+ /* XXX: check this for 8000Hz case */
+ n = 1;
+ } else {
+ n = SBLIMIT - 1;
+ }
+
+ ptr = g->sb_hybrid + 18;
+ for (i = n; i > 0; i--) {
+ AA(0);
+ AA(1);
+ AA(2);
+ AA(3);
+ AA(4);
+ AA(5);
+ AA(6);
+ AA(7);
+
+ ptr += 18;
+ }
+}
+#endif /* compute_antialias */
+
+static void compute_imdct(MPADecodeContext *s, GranuleDef *g,
+ INTFLOAT *sb_samples, INTFLOAT *mdct_buf)
+{
+ INTFLOAT *win, *out_ptr, *ptr, *buf, *ptr1;
+ INTFLOAT out2[12];
+ int i, j, mdct_long_end, sblimit;
+
+ /* find last non zero block */
+ ptr = g->sb_hybrid + 576;
+ ptr1 = g->sb_hybrid + 2 * 18;
+ while (ptr >= ptr1) {
+ int32_t *p;
+ ptr -= 6;
+ p = (int32_t*)ptr;
+ if (p[0] | p[1] | p[2] | p[3] | p[4] | p[5])
+ break;
+ }
+ sblimit = ((ptr - g->sb_hybrid) / 18) + 1;
+
+ if (g->block_type == 2) {
+ /* XXX: check for 8000 Hz */
+ if (g->switch_point)
+ mdct_long_end = 2;
+ else
+ mdct_long_end = 0;
+ } else {
+ mdct_long_end = sblimit;
+ }
+
+ s->mpadsp.RENAME(imdct36_blocks)(sb_samples, mdct_buf, g->sb_hybrid,
+ mdct_long_end, g->switch_point,
+ g->block_type);
+
+ buf = mdct_buf + 4*18*(mdct_long_end >> 2) + (mdct_long_end & 3);
+ ptr = g->sb_hybrid + 18 * mdct_long_end;
+
+ for (j = mdct_long_end; j < sblimit; j++) {
+ /* select frequency inversion */
+ win = RENAME(ff_mdct_win)[2 + (4 & -(j & 1))];
+ out_ptr = sb_samples + j;
+
+ for (i = 0; i < 6; i++) {
+ *out_ptr = buf[4*i];
+ out_ptr += SBLIMIT;
+ }
+ imdct12(out2, ptr + 0);
+ for (i = 0; i < 6; i++) {
+ *out_ptr = MULH3(out2[i ], win[i ], 1) + buf[4*(i + 6*1)];
+ buf[4*(i + 6*2)] = MULH3(out2[i + 6], win[i + 6], 1);
+ out_ptr += SBLIMIT;
+ }
+ imdct12(out2, ptr + 1);
+ for (i = 0; i < 6; i++) {
+ *out_ptr = MULH3(out2[i ], win[i ], 1) + buf[4*(i + 6*2)];
+ buf[4*(i + 6*0)] = MULH3(out2[i + 6], win[i + 6], 1);
+ out_ptr += SBLIMIT;
+ }
+ imdct12(out2, ptr + 2);
+ for (i = 0; i < 6; i++) {
+ buf[4*(i + 6*0)] = MULH3(out2[i ], win[i ], 1) + buf[4*(i + 6*0)];
+ buf[4*(i + 6*1)] = MULH3(out2[i + 6], win[i + 6], 1);
+ buf[4*(i + 6*2)] = 0;
+ }
+ ptr += 18;
+ buf += (j&3) != 3 ? 1 : (4*18-3);
+ }
+ /* zero bands */
+ for (j = sblimit; j < SBLIMIT; j++) {
+ /* overlap */
+ out_ptr = sb_samples + j;
+ for (i = 0; i < 18; i++) {
+ *out_ptr = buf[4*i];
+ buf[4*i] = 0;
+ out_ptr += SBLIMIT;
+ }
+ buf += (j&3) != 3 ? 1 : (4*18-3);
+ }
+}
+
+/* main layer3 decoding function */
+static int mp_decode_layer3(MPADecodeContext *s)
+{
+ int nb_granules, main_data_begin;
+ int gr, ch, blocksplit_flag, i, j, k, n, bits_pos;
+ GranuleDef *g;
+ int16_t exponents[576]; //FIXME try INTFLOAT
+
+ /* read side info */
+ if (s->lsf) {
+ main_data_begin = get_bits(&s->gb, 8);
+ skip_bits(&s->gb, s->nb_channels);
+ nb_granules = 1;
+ } else {
+ main_data_begin = get_bits(&s->gb, 9);
+ if (s->nb_channels == 2)
+ skip_bits(&s->gb, 3);
+ else
+ skip_bits(&s->gb, 5);
+ nb_granules = 2;
+ for (ch = 0; ch < s->nb_channels; ch++) {
+ s->granules[ch][0].scfsi = 0;/* all scale factors are transmitted */
+ s->granules[ch][1].scfsi = get_bits(&s->gb, 4);
+ }
+ }
+
+ for (gr = 0; gr < nb_granules; gr++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
+ ff_dlog(s->avctx, "gr=%d ch=%d: side_info\n", gr, ch);
+ g = &s->granules[ch][gr];
+ g->part2_3_length = get_bits(&s->gb, 12);
+ g->big_values = get_bits(&s->gb, 9);
+ if (g->big_values > 288) {
+ av_log(s->avctx, AV_LOG_ERROR, "big_values too big\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ g->global_gain = get_bits(&s->gb, 8);
+ /* if MS stereo only is selected, we precompute the
+ 1/sqrt(2) renormalization factor */
+ if ((s->mode_ext & (MODE_EXT_MS_STEREO | MODE_EXT_I_STEREO)) ==
+ MODE_EXT_MS_STEREO)
+ g->global_gain -= 2;
+ if (s->lsf)
+ g->scalefac_compress = get_bits(&s->gb, 9);
+ else
+ g->scalefac_compress = get_bits(&s->gb, 4);
+ blocksplit_flag = get_bits1(&s->gb);
+ if (blocksplit_flag) {
+ g->block_type = get_bits(&s->gb, 2);
+ if (g->block_type == 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid block type\n");
+ return AVERROR_INVALIDDATA;
+ }
+ g->switch_point = get_bits1(&s->gb);
+ for (i = 0; i < 2; i++)
+ g->table_select[i] = get_bits(&s->gb, 5);
+ for (i = 0; i < 3; i++)
+ g->subblock_gain[i] = get_bits(&s->gb, 3);
+ init_short_region(s, g);
+ } else {
+ int region_address1, region_address2;
+ g->block_type = 0;
+ g->switch_point = 0;
+ for (i = 0; i < 3; i++)
+ g->table_select[i] = get_bits(&s->gb, 5);
+ /* compute huffman coded region sizes */
+ region_address1 = get_bits(&s->gb, 4);
+ region_address2 = get_bits(&s->gb, 3);
+ ff_dlog(s->avctx, "region1=%d region2=%d\n",
+ region_address1, region_address2);
+ init_long_region(s, g, region_address1, region_address2);
+ }
+ region_offset2size(g);
+ compute_band_indexes(s, g);
+
+ g->preflag = 0;
+ if (!s->lsf)
+ g->preflag = get_bits1(&s->gb);
+ g->scalefac_scale = get_bits1(&s->gb);
+ g->count1table_select = get_bits1(&s->gb);
+ ff_dlog(s->avctx, "block_type=%d switch_point=%d\n",
+ g->block_type, g->switch_point);
+ }
+ }
+
+ if (!s->adu_mode) {
+ int skip;
+ const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3);
+ int extrasize = av_clip(get_bits_left(&s->gb) >> 3, 0, EXTRABYTES);
+ av_assert1((get_bits_count(&s->gb) & 7) == 0);
+ /* now we get bits from the main_data_begin offset */
+ ff_dlog(s->avctx, "seekback:%d, lastbuf:%d\n",
+ main_data_begin, s->last_buf_size);
+
+ memcpy(s->last_buf + s->last_buf_size, ptr, extrasize);
+ s->in_gb = s->gb;
+ init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8);
+#if !UNCHECKED_BITSTREAM_READER
+ s->gb.size_in_bits_plus8 += FFMAX(extrasize, LAST_BUF_SIZE - s->last_buf_size) * 8;
+#endif
+ s->last_buf_size <<= 3;
+ for (gr = 0; gr < nb_granules && (s->last_buf_size >> 3) < main_data_begin; gr++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
+ g = &s->granules[ch][gr];
+ s->last_buf_size += g->part2_3_length;
+ memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid));
+ compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]);
+ }
+ }
+ skip = s->last_buf_size - 8 * main_data_begin;
+ if (skip >= s->gb.size_in_bits && s->in_gb.buffer) {
+ skip_bits_long(&s->in_gb, skip - s->gb.size_in_bits);
+ s->gb = s->in_gb;
+ s->in_gb.buffer = NULL;
+ } else {
+ skip_bits_long(&s->gb, skip);
+ }
+ } else {
+ gr = 0;
+ }
+
+ for (; gr < nb_granules; gr++) {
+ for (ch = 0; ch < s->nb_channels; ch++) {
+ g = &s->granules[ch][gr];
+ bits_pos = get_bits_count(&s->gb);
+
+ if (!s->lsf) {
+ uint8_t *sc;
+ int slen, slen1, slen2;
+
+ /* MPEG1 scale factors */
+ slen1 = slen_table[0][g->scalefac_compress];
+ slen2 = slen_table[1][g->scalefac_compress];
+ ff_dlog(s->avctx, "slen1=%d slen2=%d\n", slen1, slen2);
+ if (g->block_type == 2) {
+ n = g->switch_point ? 17 : 18;
+ j = 0;
+ if (slen1) {
+ for (i = 0; i < n; i++)
+ g->scale_factors[j++] = get_bits(&s->gb, slen1);
+ } else {
+ for (i = 0; i < n; i++)
+ g->scale_factors[j++] = 0;
+ }
+ if (slen2) {
+ for (i = 0; i < 18; i++)
+ g->scale_factors[j++] = get_bits(&s->gb, slen2);
+ for (i = 0; i < 3; i++)
+ g->scale_factors[j++] = 0;
+ } else {
+ for (i = 0; i < 21; i++)
+ g->scale_factors[j++] = 0;
+ }
+ } else {
+ sc = s->granules[ch][0].scale_factors;
+ j = 0;
+ for (k = 0; k < 4; k++) {
+ n = k == 0 ? 6 : 5;
+ if ((g->scfsi & (0x8 >> k)) == 0) {
+ slen = (k < 2) ? slen1 : slen2;
+ if (slen) {
+ for (i = 0; i < n; i++)
+ g->scale_factors[j++] = get_bits(&s->gb, slen);
+ } else {
+ for (i = 0; i < n; i++)
+ g->scale_factors[j++] = 0;
+ }
+ } else {
+ /* simply copy from last granule */
+ for (i = 0; i < n; i++) {
+ g->scale_factors[j] = sc[j];
+ j++;
+ }
+ }
+ }
+ g->scale_factors[j++] = 0;
+ }
+ } else {
+ int tindex, tindex2, slen[4], sl, sf;
+
+ /* LSF scale factors */
+ if (g->block_type == 2)
+ tindex = g->switch_point ? 2 : 1;
+ else
+ tindex = 0;
+
+ sf = g->scalefac_compress;
+ if ((s->mode_ext & MODE_EXT_I_STEREO) && ch == 1) {
+ /* intensity stereo case */
+ sf >>= 1;
+ if (sf < 180) {
+ lsf_sf_expand(slen, sf, 6, 6, 0);
+ tindex2 = 3;
+ } else if (sf < 244) {
+ lsf_sf_expand(slen, sf - 180, 4, 4, 0);
+ tindex2 = 4;
+ } else {
+ lsf_sf_expand(slen, sf - 244, 3, 0, 0);
+ tindex2 = 5;
+ }
+ } else {
+ /* normal case */
+ if (sf < 400) {
+ lsf_sf_expand(slen, sf, 5, 4, 4);
+ tindex2 = 0;
+ } else if (sf < 500) {
+ lsf_sf_expand(slen, sf - 400, 5, 4, 0);
+ tindex2 = 1;
+ } else {
+ lsf_sf_expand(slen, sf - 500, 3, 0, 0);
+ tindex2 = 2;
+ g->preflag = 1;
+ }
+ }
+
+ j = 0;
+ for (k = 0; k < 4; k++) {
+ n = lsf_nsf_table[tindex2][tindex][k];
+ sl = slen[k];
+ if (sl) {
+ for (i = 0; i < n; i++)
+ g->scale_factors[j++] = get_bits(&s->gb, sl);
+ } else {
+ for (i = 0; i < n; i++)
+ g->scale_factors[j++] = 0;
+ }
+ }
+ /* XXX: should compute exact size */
+ for (; j < 40; j++)
+ g->scale_factors[j] = 0;
+ }
+
+ exponents_from_scale_factors(s, g, exponents);
+
+ /* read Huffman coded residue */
+ huffman_decode(s, g, exponents, bits_pos + g->part2_3_length);
+ } /* ch */
+
+ if (s->mode == MPA_JSTEREO)
+ compute_stereo(s, &s->granules[0][gr], &s->granules[1][gr]);
+
+ for (ch = 0; ch < s->nb_channels; ch++) {
+ g = &s->granules[ch][gr];
+
+ reorder_block(s, g);
+ compute_antialias(s, g);
+ compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]);
+ }
+ } /* gr */
+ if (get_bits_count(&s->gb) < 0)
+ skip_bits_long(&s->gb, -get_bits_count(&s->gb));
+ return nb_granules * 18;
+}
+
+static int mp_decode_frame(MPADecodeContext *s, OUT_INT **samples,
+ const uint8_t *buf, int buf_size)
+{
+ int i, nb_frames, ch, ret;
+ OUT_INT *samples_ptr;
+
+ init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE) * 8);
+
+ /* skip error protection field */
+ if (s->error_protection)
+ skip_bits(&s->gb, 16);
+
+ switch(s->layer) {
+ case 1:
+ s->avctx->frame_size = 384;
+ nb_frames = mp_decode_layer1(s);
+ break;
+ case 2:
+ s->avctx->frame_size = 1152;
+ nb_frames = mp_decode_layer2(s);
+ break;
+ case 3:
+ s->avctx->frame_size = s->lsf ? 576 : 1152;
+ default:
+ nb_frames = mp_decode_layer3(s);
+
+ s->last_buf_size=0;
+ if (s->in_gb.buffer) {
+ align_get_bits(&s->gb);
+ i = get_bits_left(&s->gb)>>3;
+ if (i >= 0 && i <= BACKSTEP_SIZE) {
+ memmove(s->last_buf, s->gb.buffer + (get_bits_count(&s->gb)>>3), i);
+ s->last_buf_size=i;
+ } else
+ av_log(s->avctx, AV_LOG_ERROR, "invalid old backstep %d\n", i);
+ s->gb = s->in_gb;
+ s->in_gb.buffer = NULL;
+ }
+
+ align_get_bits(&s->gb);
+ av_assert1((get_bits_count(&s->gb) & 7) == 0);
+ i = get_bits_left(&s->gb) >> 3;
+
+ if (i < 0 || i > BACKSTEP_SIZE || nb_frames < 0) {
+ if (i < 0)
+ av_log(s->avctx, AV_LOG_ERROR, "invalid new backstep %d\n", i);
+ i = FFMIN(BACKSTEP_SIZE, buf_size - HEADER_SIZE);
+ }
+ av_assert1(i <= buf_size - HEADER_SIZE && i >= 0);
+ memcpy(s->last_buf + s->last_buf_size, s->gb.buffer + buf_size - HEADER_SIZE - i, i);
+ s->last_buf_size += i;
+ }
+
+ if(nb_frames < 0)
+ return nb_frames;
+
+ /* get output buffer */
+ if (!samples) {
+ av_assert0(s->frame);
+ s->frame->nb_samples = s->avctx->frame_size;
+ if ((ret = ff_get_buffer(s->avctx, s->frame, 0)) < 0)
+ return ret;
+ samples = (OUT_INT **)s->frame->extended_data;
+ }
+
+ /* apply the synthesis filter */
+ for (ch = 0; ch < s->nb_channels; ch++) {
+ int sample_stride;
+ if (s->avctx->sample_fmt == OUT_FMT_P) {
+ samples_ptr = samples[ch];
+ sample_stride = 1;
+ } else {
+ samples_ptr = samples[0] + ch;
+ sample_stride = s->nb_channels;
+ }
+ for (i = 0; i < nb_frames; i++) {
+ RENAME(ff_mpa_synth_filter)(&s->mpadsp, s->synth_buf[ch],
+ &(s->synth_buf_offset[ch]),
+ RENAME(ff_mpa_synth_window),
+ &s->dither_state, samples_ptr,
+ sample_stride, s->sb_samples[ch][i]);
+ samples_ptr += 32 * sample_stride;
+ }
+ }
+
+ return nb_frames * 32 * sizeof(OUT_INT) * s->nb_channels;
+}
+
+static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ MPADecodeContext *s = avctx->priv_data;
+ uint32_t header;
+ int ret;
+
+ int skipped = 0;
+ while(buf_size && !*buf){
+ buf++;
+ buf_size--;
+ skipped++;
+ }
+
+ if (buf_size < HEADER_SIZE)
+ return AVERROR_INVALIDDATA;
+
+ header = AV_RB32(buf);
+ if (header>>8 == AV_RB32("TAG")>>8) {
+ av_log(avctx, AV_LOG_DEBUG, "discarding ID3 tag\n");
+ return buf_size + skipped;
+ }
+ if (ff_mpa_check_header(header) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Header missing\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header) == 1) {
+ /* free format: prepare to compute frame size */
+ s->frame_size = -1;
+ return AVERROR_INVALIDDATA;
+ }
+ /* update codec info */
+ avctx->channels = s->nb_channels;
+ avctx->channel_layout = s->nb_channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
+ if (!avctx->bit_rate)
+ avctx->bit_rate = s->bit_rate;
+
+ if (s->frame_size <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "incomplete frame\n");
+ return AVERROR_INVALIDDATA;
+ } else if (s->frame_size < buf_size) {
+ av_log(avctx, AV_LOG_DEBUG, "incorrect frame size - multiple frames in buffer?\n");
+ buf_size= s->frame_size;
+ }
+
+ s->frame = data;
+
+ ret = mp_decode_frame(s, NULL, buf, buf_size);
+ if (ret >= 0) {
+ s->frame->nb_samples = avctx->frame_size;
+ *got_frame_ptr = 1;
+ avctx->sample_rate = s->sample_rate;
+ //FIXME maybe move the other codec info stuff from above here too
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n");
+ /* Only return an error if the bad frame makes up the whole packet or
+ * the error is related to buffer management.
+ * If there is more data in the packet, just consume the bad frame
+ * instead of returning an error, which would discard the whole
+ * packet. */
+ *got_frame_ptr = 0;
+ if (buf_size == avpkt->size || ret != AVERROR_INVALIDDATA)
+ return ret;
+ }
+ s->frame_size = 0;
+ return buf_size + skipped;
+}
+
+static void mp_flush(MPADecodeContext *ctx)
+{
+ memset(ctx->synth_buf, 0, sizeof(ctx->synth_buf));
+ memset(ctx->mdct_buf, 0, sizeof(ctx->mdct_buf));
+ ctx->last_buf_size = 0;
+ ctx->dither_state = 0;
+}
+
+static void flush(AVCodecContext *avctx)
+{
+ mp_flush(avctx->priv_data);
+}
+
+#if CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER
+static int decode_frame_adu(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ MPADecodeContext *s = avctx->priv_data;
+ uint32_t header;
+ int len, ret;
+ int av_unused out_size;
+
+ len = buf_size;
+
+ // Discard too short frames
+ if (buf_size < HEADER_SIZE) {
+ av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+
+ if (len > MPA_MAX_CODED_FRAME_SIZE)
+ len = MPA_MAX_CODED_FRAME_SIZE;
+
+ // Get header and restore sync word
+ header = AV_RB32(buf) | 0xffe00000;
+
+ if (ff_mpa_check_header(header) < 0) { // Bad header, discard frame
+ av_log(avctx, AV_LOG_ERROR, "Invalid frame header\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header);
+ /* update codec info */
+ avctx->sample_rate = s->sample_rate;
+ avctx->channels = s->nb_channels;
+ avctx->channel_layout = s->nb_channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO;
+ if (!avctx->bit_rate)
+ avctx->bit_rate = s->bit_rate;
+
+ s->frame_size = len;
+
+ s->frame = data;
+
+ ret = mp_decode_frame(s, NULL, buf, buf_size);
+ if (ret < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n");
+ return ret;
+ }
+
+ *got_frame_ptr = 1;
+
+ return buf_size;
+}
+#endif /* CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER */
+
+#if CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER
+
+/**
+ * Context for MP3On4 decoder
+ */
+typedef struct MP3On4DecodeContext {
+ int frames; ///< number of mp3 frames per block (number of mp3 decoder instances)
+ int syncword; ///< syncword patch
+ const uint8_t *coff; ///< channel offsets in output buffer
+ MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance
+} MP3On4DecodeContext;
+
+#include "mpeg4audio.h"
+
+/* Next 3 arrays are indexed by channel config number (passed via codecdata) */
+
+/* number of mp3 decoder instances */
+static const uint8_t mp3Frames[8] = { 0, 1, 1, 2, 3, 3, 4, 5 };
+
+/* offsets into output buffer, assume output order is FL FR C LFE BL BR SL SR */
+static const uint8_t chan_offset[8][5] = {
+ { 0 },
+ { 0 }, // C
+ { 0 }, // FLR
+ { 2, 0 }, // C FLR
+ { 2, 0, 3 }, // C FLR BS
+ { 2, 0, 3 }, // C FLR BLRS
+ { 2, 0, 4, 3 }, // C FLR BLRS LFE
+ { 2, 0, 6, 4, 3 }, // C FLR BLRS BLR LFE
+};
+
+/* mp3on4 channel layouts */
+static const int16_t chan_layout[8] = {
+ 0,
+ AV_CH_LAYOUT_MONO,
+ AV_CH_LAYOUT_STEREO,
+ AV_CH_LAYOUT_SURROUND,
+ AV_CH_LAYOUT_4POINT0,
+ AV_CH_LAYOUT_5POINT0,
+ AV_CH_LAYOUT_5POINT1,
+ AV_CH_LAYOUT_7POINT1
+};
+
+static av_cold int decode_close_mp3on4(AVCodecContext * avctx)
+{
+ MP3On4DecodeContext *s = avctx->priv_data;
+ int i;
+
+ for (i = 0; i < s->frames; i++)
+ av_freep(&s->mp3decctx[i]);
+
+ return 0;
+}
+
+
+static av_cold int decode_init_mp3on4(AVCodecContext * avctx)
+{
+ MP3On4DecodeContext *s = avctx->priv_data;
+ MPEG4AudioConfig cfg;
+ int i;
+
+ if ((avctx->extradata_size < 2) || !avctx->extradata) {
+ av_log(avctx, AV_LOG_ERROR, "Codec extradata missing or too short.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ avpriv_mpeg4audio_get_config(&cfg, avctx->extradata,
+ avctx->extradata_size * 8, 1);
+ if (!cfg.chan_config || cfg.chan_config > 7) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ s->frames = mp3Frames[cfg.chan_config];
+ s->coff = chan_offset[cfg.chan_config];
+ avctx->channels = ff_mpeg4audio_channels[cfg.chan_config];
+ avctx->channel_layout = chan_layout[cfg.chan_config];
+
+ if (cfg.sample_rate < 16000)
+ s->syncword = 0xffe00000;
+ else
+ s->syncword = 0xfff00000;
+
+ /* Init the first mp3 decoder in standard way, so that all tables get builded
+ * We replace avctx->priv_data with the context of the first decoder so that
+ * decode_init() does not have to be changed.
+ * Other decoders will be initialized here copying data from the first context
+ */
+ // Allocate zeroed memory for the first decoder context
+ s->mp3decctx[0] = av_mallocz(sizeof(MPADecodeContext));
+ if (!s->mp3decctx[0])
+ goto alloc_fail;
+ // Put decoder context in place to make init_decode() happy
+ avctx->priv_data = s->mp3decctx[0];
+ decode_init(avctx);
+ // Restore mp3on4 context pointer
+ avctx->priv_data = s;
+ s->mp3decctx[0]->adu_mode = 1; // Set adu mode
+
+ /* Create a separate codec/context for each frame (first is already ok).
+ * Each frame is 1 or 2 channels - up to 5 frames allowed
+ */
+ for (i = 1; i < s->frames; i++) {
+ s->mp3decctx[i] = av_mallocz(sizeof(MPADecodeContext));
+ if (!s->mp3decctx[i])
+ goto alloc_fail;
+ s->mp3decctx[i]->adu_mode = 1;
+ s->mp3decctx[i]->avctx = avctx;
+ s->mp3decctx[i]->mpadsp = s->mp3decctx[0]->mpadsp;
+ s->mp3decctx[i]->fdsp = s->mp3decctx[0]->fdsp;
+ }
+
+ return 0;
+alloc_fail:
+ decode_close_mp3on4(avctx);
+ return AVERROR(ENOMEM);
+}
+
+
+static void flush_mp3on4(AVCodecContext *avctx)
+{
+ int i;
+ MP3On4DecodeContext *s = avctx->priv_data;
+
+ for (i = 0; i < s->frames; i++)
+ mp_flush(s->mp3decctx[i]);
+}
+
+
+static int decode_frame_mp3on4(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ AVFrame *frame = data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ MP3On4DecodeContext *s = avctx->priv_data;
+ MPADecodeContext *m;
+ int fsize, len = buf_size, out_size = 0;
+ uint32_t header;
+ OUT_INT **out_samples;
+ OUT_INT *outptr[2];
+ int fr, ch, ret;
+
+ /* get output buffer */
+ frame->nb_samples = MPA_FRAME_SIZE;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+ out_samples = (OUT_INT **)frame->extended_data;
+
+ // Discard too short frames
+ if (buf_size < HEADER_SIZE)
+ return AVERROR_INVALIDDATA;
+
+ avctx->bit_rate = 0;
+
+ ch = 0;
+ for (fr = 0; fr < s->frames; fr++) {
+ fsize = AV_RB16(buf) >> 4;
+ fsize = FFMIN3(fsize, len, MPA_MAX_CODED_FRAME_SIZE);
+ m = s->mp3decctx[fr];
+ av_assert1(m);
+
+ if (fsize < HEADER_SIZE) {
+ av_log(avctx, AV_LOG_ERROR, "Frame size smaller than header size\n");
+ return AVERROR_INVALIDDATA;
+ }
+ header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header
+
+ if (ff_mpa_check_header(header) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Bad header, discard block\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header);
+
+ if (ch + m->nb_channels > avctx->channels ||
+ s->coff[fr] + m->nb_channels > avctx->channels) {
+ av_log(avctx, AV_LOG_ERROR, "frame channel count exceeds codec "
+ "channel count\n");
+ return AVERROR_INVALIDDATA;
+ }
+ ch += m->nb_channels;
+
+ outptr[0] = out_samples[s->coff[fr]];
+ if (m->nb_channels > 1)
+ outptr[1] = out_samples[s->coff[fr] + 1];
+
+ if ((ret = mp_decode_frame(m, outptr, buf, fsize)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "failed to decode channel %d\n", ch);
+ memset(outptr[0], 0, MPA_FRAME_SIZE*sizeof(OUT_INT));
+ if (m->nb_channels > 1)
+ memset(outptr[1], 0, MPA_FRAME_SIZE*sizeof(OUT_INT));
+ ret = m->nb_channels * MPA_FRAME_SIZE*sizeof(OUT_INT);
+ }
+
+ out_size += ret;
+ buf += fsize;
+ len -= fsize;
+
+ avctx->bit_rate += m->bit_rate;
+ }
+ if (ch != avctx->channels) {
+ av_log(avctx, AV_LOG_ERROR, "failed to decode all channels\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* update codec info */
+ avctx->sample_rate = s->mp3decctx[0]->sample_rate;
+
+ frame->nb_samples = out_size / (avctx->channels * sizeof(OUT_INT));
+ *got_frame_ptr = 1;
+
+ return buf_size;
+}
+#endif /* CONFIG_MP3ON4_DECODER || CONFIG_MP3ON4FLOAT_DECODER */
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiodecheader.c b/ffmpeg-2-8-12/libavcodec/mpegaudiodecheader.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudiodecheader.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudiodecheader.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiodecheader.h b/ffmpeg-2-8-12/libavcodec/mpegaudiodecheader.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudiodecheader.h
rename to ffmpeg-2-8-12/libavcodec/mpegaudiodecheader.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiodectab.h b/ffmpeg-2-8-12/libavcodec/mpegaudiodectab.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudiodectab.h
rename to ffmpeg-2-8-12/libavcodec/mpegaudiodectab.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiodsp.c b/ffmpeg-2-8-12/libavcodec/mpegaudiodsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudiodsp.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudiodsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiodsp.h b/ffmpeg-2-8-12/libavcodec/mpegaudiodsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudiodsp.h
rename to ffmpeg-2-8-12/libavcodec/mpegaudiodsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiodsp_data.c b/ffmpeg-2-8-12/libavcodec/mpegaudiodsp_data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudiodsp_data.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudiodsp_data.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiodsp_fixed.c b/ffmpeg-2-8-12/libavcodec/mpegaudiodsp_fixed.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudiodsp_fixed.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudiodsp_fixed.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiodsp_float.c b/ffmpeg-2-8-12/libavcodec/mpegaudiodsp_float.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudiodsp_float.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudiodsp_float.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiodsp_template.c b/ffmpeg-2-8-12/libavcodec/mpegaudiodsp_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudiodsp_template.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudiodsp_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudioenc_fixed.c b/ffmpeg-2-8-12/libavcodec/mpegaudioenc_fixed.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudioenc_fixed.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudioenc_fixed.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudioenc_float.c b/ffmpeg-2-8-12/libavcodec/mpegaudioenc_float.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudioenc_float.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudioenc_float.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudioenc_template.c b/ffmpeg-2-8-12/libavcodec/mpegaudioenc_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudioenc_template.c
rename to ffmpeg-2-8-12/libavcodec/mpegaudioenc_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegaudiotab.h b/ffmpeg-2-8-12/libavcodec/mpegaudiotab.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegaudiotab.h
rename to ffmpeg-2-8-12/libavcodec/mpegaudiotab.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpegpicture.c b/ffmpeg-2-8-12/libavcodec/mpegpicture.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegpicture.c
rename to ffmpeg-2-8-12/libavcodec/mpegpicture.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegpicture.h b/ffmpeg-2-8-12/libavcodec/mpegpicture.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegpicture.h
rename to ffmpeg-2-8-12/libavcodec/mpegpicture.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpegutils.c b/ffmpeg-2-8-12/libavcodec/mpegutils.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegutils.c
rename to ffmpeg-2-8-12/libavcodec/mpegutils.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegutils.h b/ffmpeg-2-8-12/libavcodec/mpegutils.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegutils.h
rename to ffmpeg-2-8-12/libavcodec/mpegutils.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpegvideo.c b/ffmpeg-2-8-12/libavcodec/mpegvideo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegvideo.c
rename to ffmpeg-2-8-12/libavcodec/mpegvideo.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegvideo.h b/ffmpeg-2-8-12/libavcodec/mpegvideo.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegvideo.h
rename to ffmpeg-2-8-12/libavcodec/mpegvideo.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpegvideo_enc.c b/ffmpeg-2-8-12/libavcodec/mpegvideo_enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegvideo_enc.c
rename to ffmpeg-2-8-12/libavcodec/mpegvideo_enc.c
diff --git a/ffmpeg-2-8-12/libavcodec/mpegvideo_motion.c b/ffmpeg-2-8-12/libavcodec/mpegvideo_motion.c
new file mode 100644
index 0000000..2d3a778
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/mpegvideo_motion.c
@@ -0,0 +1,990 @@
+/*
+ * Copyright (c) 2000,2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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 <string.h>
+
+#include "libavutil/avassert.h"
+#include "libavutil/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 <limits.h>
+
+static void gmc1_motion(MpegEncContext *s,
+ uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+ uint8_t **ref_picture)
+{
+ uint8_t *ptr;
+ int src_x, src_y, motion_x, motion_y;
+ ptrdiff_t offset, linesize, uvlinesize;
+ int emu = 0;
+
+ motion_x = s->sprite_offset[0][0];
+ motion_y = s->sprite_offset[0][1];
+ src_x = s->mb_x * 16 + (motion_x >> (s->sprite_warping_accuracy + 1));
+ src_y = s->mb_y * 16 + (motion_y >> (s->sprite_warping_accuracy + 1));
+ motion_x *= 1 << (3 - s->sprite_warping_accuracy);
+ motion_y *= 1 << (3 - s->sprite_warping_accuracy);
+ src_x = av_clip(src_x, -16, s->width);
+ if (src_x == s->width)
+ motion_x = 0;
+ src_y = av_clip(src_y, -16, s->height);
+ if (src_y == s->height)
+ motion_y = 0;
+
+ linesize = s->linesize;
+ uvlinesize = s->uvlinesize;
+
+ ptr = ref_picture[0] + src_y * linesize + src_x;
+
+ if ((unsigned)src_x >= FFMAX(s->h_edge_pos - 17, 0) ||
+ (unsigned)src_y >= FFMAX(s->v_edge_pos - 17, 0)) {
+ s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
+ linesize, linesize,
+ 17, 17,
+ src_x, src_y,
+ s->h_edge_pos, s->v_edge_pos);
+ ptr = s->sc.edge_emu_buffer;
+ }
+
+ if ((motion_x | motion_y) & 7) {
+ s->mdsp.gmc1(dest_y, ptr, linesize, 16,
+ motion_x & 15, motion_y & 15, 128 - s->no_rounding);
+ s->mdsp.gmc1(dest_y + 8, ptr + 8, linesize, 16,
+ motion_x & 15, motion_y & 15, 128 - s->no_rounding);
+ } else {
+ int dxy;
+
+ dxy = ((motion_x >> 3) & 1) | ((motion_y >> 2) & 2);
+ if (s->no_rounding) {
+ s->hdsp.put_no_rnd_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
+ } else {
+ s->hdsp.put_pixels_tab[0][dxy](dest_y, ptr, linesize, 16);
+ }
+ }
+
+ if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
+ return;
+
+ motion_x = s->sprite_offset[1][0];
+ motion_y = s->sprite_offset[1][1];
+ src_x = s->mb_x * 8 + (motion_x >> (s->sprite_warping_accuracy + 1));
+ src_y = s->mb_y * 8 + (motion_y >> (s->sprite_warping_accuracy + 1));
+ motion_x *= 1 << (3 - s->sprite_warping_accuracy);
+ motion_y *= 1 << (3 - s->sprite_warping_accuracy);
+ src_x = av_clip(src_x, -8, s->width >> 1);
+ if (src_x == s->width >> 1)
+ motion_x = 0;
+ src_y = av_clip(src_y, -8, s->height >> 1);
+ if (src_y == s->height >> 1)
+ motion_y = 0;
+
+ offset = (src_y * uvlinesize) + src_x;
+ ptr = ref_picture[1] + offset;
+ if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - 9, 0) ||
+ (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - 9, 0)) {
+ s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
+ uvlinesize, uvlinesize,
+ 9, 9,
+ src_x, src_y,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ ptr = s->sc.edge_emu_buffer;
+ emu = 1;
+ }
+ s->mdsp.gmc1(dest_cb, ptr, uvlinesize, 8,
+ motion_x & 15, motion_y & 15, 128 - s->no_rounding);
+
+ ptr = ref_picture[2] + offset;
+ if (emu) {
+ s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
+ uvlinesize, uvlinesize,
+ 9, 9,
+ src_x, src_y,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ ptr = s->sc.edge_emu_buffer;
+ }
+ s->mdsp.gmc1(dest_cr, ptr, uvlinesize, 8,
+ motion_x & 15, motion_y & 15, 128 - s->no_rounding);
+}
+
+static void gmc_motion(MpegEncContext *s,
+ uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+ uint8_t **ref_picture)
+{
+ uint8_t *ptr;
+ int linesize, uvlinesize;
+ const int a = s->sprite_warping_accuracy;
+ int ox, oy;
+
+ linesize = s->linesize;
+ uvlinesize = s->uvlinesize;
+
+ ptr = ref_picture[0];
+
+ ox = s->sprite_offset[0][0] + s->sprite_delta[0][0] * s->mb_x * 16 +
+ s->sprite_delta[0][1] * s->mb_y * 16;
+ oy = s->sprite_offset[0][1] + s->sprite_delta[1][0] * s->mb_x * 16 +
+ s->sprite_delta[1][1] * s->mb_y * 16;
+
+ s->mdsp.gmc(dest_y, ptr, linesize, 16,
+ ox, oy,
+ s->sprite_delta[0][0], s->sprite_delta[0][1],
+ s->sprite_delta[1][0], s->sprite_delta[1][1],
+ a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+ s->h_edge_pos, s->v_edge_pos);
+ s->mdsp.gmc(dest_y + 8, ptr, linesize, 16,
+ ox + s->sprite_delta[0][0] * 8,
+ oy + s->sprite_delta[1][0] * 8,
+ s->sprite_delta[0][0], s->sprite_delta[0][1],
+ s->sprite_delta[1][0], s->sprite_delta[1][1],
+ a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+ s->h_edge_pos, s->v_edge_pos);
+
+ if (CONFIG_GRAY && s->avctx->flags & AV_CODEC_FLAG_GRAY)
+ return;
+
+ ox = s->sprite_offset[1][0] + s->sprite_delta[0][0] * s->mb_x * 8 +
+ s->sprite_delta[0][1] * s->mb_y * 8;
+ oy = s->sprite_offset[1][1] + s->sprite_delta[1][0] * s->mb_x * 8 +
+ s->sprite_delta[1][1] * s->mb_y * 8;
+
+ ptr = ref_picture[1];
+ s->mdsp.gmc(dest_cb, ptr, uvlinesize, 8,
+ ox, oy,
+ s->sprite_delta[0][0], s->sprite_delta[0][1],
+ s->sprite_delta[1][0], s->sprite_delta[1][1],
+ a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+ (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1);
+
+ ptr = ref_picture[2];
+ s->mdsp.gmc(dest_cr, ptr, uvlinesize, 8,
+ ox, oy,
+ s->sprite_delta[0][0], s->sprite_delta[0][1],
+ s->sprite_delta[1][0], s->sprite_delta[1][1],
+ a + 1, (1 << (2 * a + 1)) - s->no_rounding,
+ (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1);
+}
+
+static inline int hpel_motion(MpegEncContext *s,
+ uint8_t *dest, uint8_t *src,
+ int src_x, int src_y,
+ op_pixels_func *pix_op,
+ int motion_x, int motion_y)
+{
+ int dxy = 0;
+ int emu = 0;
+
+ src_x += motion_x >> 1;
+ src_y += motion_y >> 1;
+
+ /* WARNING: do no forget half pels */
+ src_x = av_clip(src_x, -16, s->width); // FIXME unneeded for emu?
+ if (src_x != s->width)
+ dxy |= motion_x & 1;
+ src_y = av_clip(src_y, -16, s->height);
+ if (src_y != s->height)
+ 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;
+ }
+ pix_op[dxy](dest, src, s->linesize, 8);
+ return emu;
+}
+
+static av_always_inline
+void mpeg_motion_internal(MpegEncContext *s,
+ uint8_t *dest_y,
+ uint8_t *dest_cb,
+ uint8_t *dest_cr,
+ int field_based,
+ int bottom_field,
+ int field_select,
+ uint8_t **ref_picture,
+ op_pixels_func (*pix_op)[4],
+ int motion_x,
+ int motion_y,
+ int h,
+ int is_mpeg12,
+ int mb_y)
+{
+ uint8_t *ptr_y, *ptr_cb, *ptr_cr;
+ int dxy, uvdxy, mx, my, src_x, src_y,
+ uvsrc_x, uvsrc_y, v_edge_pos;
+ ptrdiff_t uvlinesize, linesize;
+
+#if 0
+ if (s->quarter_sample) {
+ motion_x >>= 1;
+ motion_y >>= 1;
+ }
+#endif
+
+ v_edge_pos = s->v_edge_pos >> field_based;
+ linesize = s->current_picture.f->linesize[0] << field_based;
+ uvlinesize = s->current_picture.f->linesize[1] << field_based;
+
+ dxy = ((motion_y & 1) << 1) | (motion_x & 1);
+ src_x = s->mb_x * 16 + (motion_x >> 1);
+ src_y = (mb_y << (4 - field_based)) + (motion_y >> 1);
+
+ if (!is_mpeg12 && s->out_format == FMT_H263) {
+ if ((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based) {
+ mx = (motion_x >> 1) | (motion_x & 1);
+ my = motion_y >> 1;
+ uvdxy = ((my & 1) << 1) | (mx & 1);
+ uvsrc_x = s->mb_x * 8 + (mx >> 1);
+ uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1);
+ } else {
+ uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1);
+ uvsrc_x = src_x >> 1;
+ uvsrc_y = src_y >> 1;
+ }
+ // Even chroma mv's are full pel in H261
+ } else if (!is_mpeg12 && s->out_format == FMT_H261) {
+ mx = motion_x / 4;
+ my = motion_y / 4;
+ uvdxy = 0;
+ uvsrc_x = s->mb_x * 8 + mx;
+ uvsrc_y = mb_y * 8 + my;
+ } else {
+ if (s->chroma_y_shift) {
+ mx = motion_x / 2;
+ my = motion_y / 2;
+ uvdxy = ((my & 1) << 1) | (mx & 1);
+ uvsrc_x = s->mb_x * 8 + (mx >> 1);
+ uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1);
+ } else {
+ if (s->chroma_x_shift) {
+ // Chroma422
+ mx = motion_x / 2;
+ uvdxy = ((motion_y & 1) << 1) | (mx & 1);
+ uvsrc_x = s->mb_x * 8 + (mx >> 1);
+ uvsrc_y = src_y;
+ } else {
+ // Chroma444
+ uvdxy = dxy;
+ uvsrc_x = src_x;
+ uvsrc_y = src_y;
+ }
+ }
+ }
+
+ ptr_y = ref_picture[0] + src_y * linesize + src_x;
+ ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
+ ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
+
+ if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 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) {
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "MPEG motion vector out of boundary (%d %d)\n", src_x,
+ src_y);
+ return;
+ }
+ src_y = (unsigned)src_y << field_based;
+ s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr_y,
+ s->linesize, s->linesize,
+ 17, 17 + field_based,
+ src_x, src_y,
+ s->h_edge_pos, s->v_edge_pos);
+ ptr_y = s->sc.edge_emu_buffer;
+ if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
+ uint8_t *ubuf = s->sc.edge_emu_buffer + 18 * s->linesize;
+ uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
+ uvsrc_y = (unsigned)uvsrc_y << field_based;
+ s->vdsp.emulated_edge_mc(ubuf, ptr_cb,
+ s->uvlinesize, s->uvlinesize,
+ 9, 9 + field_based,
+ uvsrc_x, uvsrc_y,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ s->vdsp.emulated_edge_mc(vbuf, ptr_cr,
+ s->uvlinesize, s->uvlinesize,
+ 9, 9 + field_based,
+ uvsrc_x, uvsrc_y,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ ptr_cb = ubuf;
+ ptr_cr = vbuf;
+ }
+ }
+
+ /* FIXME use this for field pix too instead of the obnoxious hack which
+ * changes picture.data */
+ if (bottom_field) {
+ dest_y += s->linesize;
+ dest_cb += s->uvlinesize;
+ dest_cr += s->uvlinesize;
+ }
+
+ if (field_select) {
+ ptr_y += s->linesize;
+ ptr_cb += s->uvlinesize;
+ ptr_cr += s->uvlinesize;
+ }
+
+ pix_op[0][dxy](dest_y, ptr_y, linesize, h);
+
+ if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
+ pix_op[s->chroma_x_shift][uvdxy]
+ (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift);
+ pix_op[s->chroma_x_shift][uvdxy]
+ (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift);
+ }
+ if (!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) &&
+ s->out_format == FMT_H261) {
+ ff_h261_loop_filter(s);
+ }
+}
+/* apply one mpeg motion vector to the three components */
+static void mpeg_motion(MpegEncContext *s,
+ uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr,
+ int field_select, uint8_t **ref_picture,
+ op_pixels_func (*pix_op)[4],
+ int motion_x, int motion_y, int h, int mb_y)
+{
+#if !CONFIG_SMALL
+ if (s->out_format == FMT_MPEG1)
+ mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0,
+ field_select, ref_picture, pix_op,
+ motion_x, motion_y, h, 1, mb_y);
+ else
+#endif
+ mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 0, 0,
+ field_select, ref_picture, pix_op,
+ motion_x, motion_y, h, 0, mb_y);
+}
+
+static void mpeg_motion_field(MpegEncContext *s, uint8_t *dest_y,
+ uint8_t *dest_cb, uint8_t *dest_cr,
+ int bottom_field, int field_select,
+ uint8_t **ref_picture,
+ op_pixels_func (*pix_op)[4],
+ int motion_x, int motion_y, int h, int mb_y)
+{
+#if !CONFIG_SMALL
+ if (s->out_format == FMT_MPEG1)
+ mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1,
+ bottom_field, field_select, ref_picture, pix_op,
+ motion_x, motion_y, h, 1, mb_y);
+ else
+#endif
+ mpeg_motion_internal(s, dest_y, dest_cb, dest_cr, 1,
+ bottom_field, field_select, ref_picture, pix_op,
+ motion_x, motion_y, h, 0, mb_y);
+}
+
+// FIXME: SIMDify, avg variant, 16x16 version
+static inline void put_obmc(uint8_t *dst, uint8_t *src[5], int stride)
+{
+ int x;
+ uint8_t *const top = src[1];
+ uint8_t *const left = src[2];
+ uint8_t *const mid = src[0];
+ uint8_t *const right = src[3];
+ uint8_t *const bottom = src[4];
+#define OBMC_FILTER(x, t, l, m, r, b)\
+ dst[x]= (t*top[x] + l*left[x] + m*mid[x] + r*right[x] + b*bottom[x] + 4)>>3
+#define OBMC_FILTER4(x, t, l, m, r, b)\
+ OBMC_FILTER(x , t, l, m, r, b);\
+ OBMC_FILTER(x+1 , t, l, m, r, b);\
+ OBMC_FILTER(x +stride, t, l, m, r, b);\
+ OBMC_FILTER(x+1+stride, t, l, m, r, b);
+
+ x = 0;
+ OBMC_FILTER (x , 2, 2, 4, 0, 0);
+ OBMC_FILTER (x + 1, 2, 1, 5, 0, 0);
+ OBMC_FILTER4(x + 2, 2, 1, 5, 0, 0);
+ OBMC_FILTER4(x + 4, 2, 0, 5, 1, 0);
+ OBMC_FILTER (x + 6, 2, 0, 5, 1, 0);
+ OBMC_FILTER (x + 7, 2, 0, 4, 2, 0);
+ x += stride;
+ OBMC_FILTER (x , 1, 2, 5, 0, 0);
+ OBMC_FILTER (x + 1, 1, 2, 5, 0, 0);
+ OBMC_FILTER (x + 6, 1, 0, 5, 2, 0);
+ OBMC_FILTER (x + 7, 1, 0, 5, 2, 0);
+ x += stride;
+ OBMC_FILTER4(x , 1, 2, 5, 0, 0);
+ OBMC_FILTER4(x + 2, 1, 1, 6, 0, 0);
+ OBMC_FILTER4(x + 4, 1, 0, 6, 1, 0);
+ OBMC_FILTER4(x + 6, 1, 0, 5, 2, 0);
+ x += 2 * stride;
+ OBMC_FILTER4(x , 0, 2, 5, 0, 1);
+ OBMC_FILTER4(x + 2, 0, 1, 6, 0, 1);
+ OBMC_FILTER4(x + 4, 0, 0, 6, 1, 1);
+ OBMC_FILTER4(x + 6, 0, 0, 5, 2, 1);
+ x += 2*stride;
+ OBMC_FILTER (x , 0, 2, 5, 0, 1);
+ OBMC_FILTER (x + 1, 0, 2, 5, 0, 1);
+ OBMC_FILTER4(x + 2, 0, 1, 5, 0, 2);
+ OBMC_FILTER4(x + 4, 0, 0, 5, 1, 2);
+ OBMC_FILTER (x + 6, 0, 0, 5, 2, 1);
+ OBMC_FILTER (x + 7, 0, 0, 5, 2, 1);
+ x += stride;
+ OBMC_FILTER (x , 0, 2, 4, 0, 2);
+ OBMC_FILTER (x + 1, 0, 1, 5, 0, 2);
+ OBMC_FILTER (x + 6, 0, 0, 5, 1, 2);
+ OBMC_FILTER (x + 7, 0, 0, 4, 2, 2);
+}
+
+/* obmc for 1 8x8 luma block */
+static inline void obmc_motion(MpegEncContext *s,
+ uint8_t *dest, uint8_t *src,
+ int src_x, int src_y,
+ op_pixels_func *pix_op,
+ int16_t mv[5][2] /* mid top left right bottom */)
+#define MID 0
+{
+ int i;
+ uint8_t *ptr[5];
+
+ av_assert2(s->quarter_sample == 0);
+
+ for (i = 0; i < 5; i++) {
+ if (i && mv[i][0] == mv[MID][0] && mv[i][1] == mv[MID][1]) {
+ ptr[i] = ptr[MID];
+ } else {
+ ptr[i] = s->sc.obmc_scratchpad + 8 * (i & 1) +
+ s->linesize * 8 * (i >> 1);
+ hpel_motion(s, ptr[i], src, src_x, src_y, pix_op,
+ mv[i][0], mv[i][1]);
+ }
+ }
+
+ put_obmc(dest, ptr, s->linesize);
+}
+
+static inline void qpel_motion(MpegEncContext *s,
+ uint8_t *dest_y,
+ uint8_t *dest_cb,
+ uint8_t *dest_cr,
+ int field_based, int bottom_field,
+ int field_select, uint8_t **ref_picture,
+ op_pixels_func (*pix_op)[4],
+ qpel_mc_func (*qpix_op)[16],
+ int motion_x, int motion_y, int h)
+{
+ uint8_t *ptr_y, *ptr_cb, *ptr_cr;
+ int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos;
+ ptrdiff_t linesize, uvlinesize;
+
+ dxy = ((motion_y & 3) << 2) | (motion_x & 3);
+
+ src_x = s->mb_x * 16 + (motion_x >> 2);
+ src_y = s->mb_y * (16 >> field_based) + (motion_y >> 2);
+
+ v_edge_pos = s->v_edge_pos >> field_based;
+ linesize = s->linesize << field_based;
+ uvlinesize = s->uvlinesize << field_based;
+
+ if (field_based) {
+ mx = motion_x / 2;
+ my = motion_y >> 1;
+ } else if (s->workaround_bugs & FF_BUG_QPEL_CHROMA2) {
+ static const int rtab[8] = { 0, 0, 1, 1, 0, 0, 0, 1 };
+ mx = (motion_x >> 1) + rtab[motion_x & 7];
+ my = (motion_y >> 1) + rtab[motion_y & 7];
+ } else if (s->workaround_bugs & FF_BUG_QPEL_CHROMA) {
+ mx = (motion_x >> 1) | (motion_x & 1);
+ my = (motion_y >> 1) | (motion_y & 1);
+ } else {
+ mx = motion_x / 2;
+ my = motion_y / 2;
+ }
+ mx = (mx >> 1) | (mx & 1);
+ my = (my >> 1) | (my & 1);
+
+ uvdxy = (mx & 1) | ((my & 1) << 1);
+ mx >>= 1;
+ my >>= 1;
+
+ uvsrc_x = s->mb_x * 8 + mx;
+ uvsrc_y = s->mb_y * (8 >> field_based) + my;
+
+ ptr_y = ref_picture[0] + src_y * linesize + src_x;
+ ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x;
+ ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x;
+
+ if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 3) - 15 , 0) ||
+ (unsigned)src_y >= FFMAX( v_edge_pos - (motion_y & 3) - h + 1, 0)) {
+ s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr_y,
+ s->linesize, s->linesize,
+ 17, 17 + field_based,
+ src_x, src_y << field_based,
+ s->h_edge_pos, s->v_edge_pos);
+ ptr_y = s->sc.edge_emu_buffer;
+ if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
+ uint8_t *ubuf = s->sc.edge_emu_buffer + 18 * s->linesize;
+ uint8_t *vbuf = ubuf + 9 * s->uvlinesize;
+ s->vdsp.emulated_edge_mc(ubuf, ptr_cb,
+ s->uvlinesize, s->uvlinesize,
+ 9, 9 + field_based,
+ uvsrc_x, uvsrc_y << field_based,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ s->vdsp.emulated_edge_mc(vbuf, ptr_cr,
+ s->uvlinesize, s->uvlinesize,
+ 9, 9 + field_based,
+ uvsrc_x, uvsrc_y << field_based,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ ptr_cb = ubuf;
+ ptr_cr = vbuf;
+ }
+ }
+
+ if (!field_based)
+ qpix_op[0][dxy](dest_y, ptr_y, linesize);
+ else {
+ if (bottom_field) {
+ dest_y += s->linesize;
+ dest_cb += s->uvlinesize;
+ dest_cr += s->uvlinesize;
+ }
+
+ if (field_select) {
+ ptr_y += s->linesize;
+ ptr_cb += s->uvlinesize;
+ ptr_cr += s->uvlinesize;
+ }
+ // damn interlaced mode
+ // FIXME boundary mirroring is not exactly correct here
+ qpix_op[1][dxy](dest_y, ptr_y, linesize);
+ qpix_op[1][dxy](dest_y + 8, ptr_y + 8, linesize);
+ }
+ if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
+ pix_op[1][uvdxy](dest_cr, ptr_cr, uvlinesize, h >> 1);
+ pix_op[1][uvdxy](dest_cb, ptr_cb, uvlinesize, h >> 1);
+ }
+}
+
+/**
+ * h263 chroma 4mv motion compensation.
+ */
+static void chroma_4mv_motion(MpegEncContext *s,
+ uint8_t *dest_cb, uint8_t *dest_cr,
+ uint8_t **ref_picture,
+ op_pixels_func *pix_op,
+ int mx, int my)
+{
+ uint8_t *ptr;
+ int src_x, src_y, dxy, emu = 0;
+ ptrdiff_t offset;
+
+ /* In case of 8X8, we construct a single chroma motion vector
+ * with a special rounding */
+ mx = ff_h263_round_chroma(mx);
+ my = ff_h263_round_chroma(my);
+
+ dxy = ((my & 1) << 1) | (mx & 1);
+ mx >>= 1;
+ my >>= 1;
+
+ src_x = s->mb_x * 8 + mx;
+ src_y = s->mb_y * 8 + my;
+ src_x = av_clip(src_x, -8, (s->width >> 1));
+ if (src_x == (s->width >> 1))
+ dxy &= ~1;
+ src_y = av_clip(src_y, -8, (s->height >> 1));
+ if (src_y == (s->height >> 1))
+ dxy &= ~2;
+
+ offset = src_y * s->uvlinesize + src_x;
+ ptr = ref_picture[1] + offset;
+ if ((unsigned)src_x >= FFMAX((s->h_edge_pos >> 1) - (dxy & 1) - 7, 0) ||
+ (unsigned)src_y >= FFMAX((s->v_edge_pos >> 1) - (dxy >> 1) - 7, 0)) {
+ s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
+ s->uvlinesize, s->uvlinesize,
+ 9, 9, src_x, src_y,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ ptr = s->sc.edge_emu_buffer;
+ emu = 1;
+ }
+ pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8);
+
+ ptr = ref_picture[2] + offset;
+ if (emu) {
+ s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
+ s->uvlinesize, s->uvlinesize,
+ 9, 9, src_x, src_y,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ ptr = s->sc.edge_emu_buffer;
+ }
+ pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8);
+}
+
+static inline void prefetch_motion(MpegEncContext *s, uint8_t **pix, int dir)
+{
+ /* fetch pixels for estimated mv 4 macroblocks ahead
+ * optimized for 64byte cache lines */
+ const int shift = s->quarter_sample ? 2 : 1;
+ const int mx = (s->mv[dir][0][0] >> shift) + 16 * s->mb_x + 8;
+ const int my = (s->mv[dir][0][1] >> shift) + 16 * s->mb_y;
+ int off = mx + (my + (s->mb_x & 3) * 4) * s->linesize + 64;
+
+ s->vdsp.prefetch(pix[0] + off, s->linesize, 4);
+ off = (mx >> 1) + ((my >> 1) + (s->mb_x & 7)) * s->uvlinesize + 64;
+ s->vdsp.prefetch(pix[1] + off, pix[2] - pix[1], 2);
+}
+
+static inline void apply_obmc(MpegEncContext *s,
+ uint8_t *dest_y,
+ uint8_t *dest_cb,
+ uint8_t *dest_cr,
+ uint8_t **ref_picture,
+ op_pixels_func (*pix_op)[4])
+{
+ LOCAL_ALIGNED_8(int16_t, mv_cache, [4], [4][2]);
+ Picture *cur_frame = &s->current_picture;
+ int mb_x = s->mb_x;
+ int mb_y = s->mb_y;
+ const int xy = mb_x + mb_y * s->mb_stride;
+ const int mot_stride = s->b8_stride;
+ const int mot_xy = mb_x * 2 + mb_y * 2 * mot_stride;
+ int mx, my, i;
+
+ av_assert2(!s->mb_skipped);
+
+ AV_COPY32(mv_cache[1][1], cur_frame->motion_val[0][mot_xy]);
+ AV_COPY32(mv_cache[1][2], cur_frame->motion_val[0][mot_xy + 1]);
+
+ AV_COPY32(mv_cache[2][1],
+ cur_frame->motion_val[0][mot_xy + mot_stride]);
+ AV_COPY32(mv_cache[2][2],
+ cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
+
+ AV_COPY32(mv_cache[3][1],
+ cur_frame->motion_val[0][mot_xy + mot_stride]);
+ AV_COPY32(mv_cache[3][2],
+ cur_frame->motion_val[0][mot_xy + mot_stride + 1]);
+
+ if (mb_y == 0 || IS_INTRA(cur_frame->mb_type[xy - s->mb_stride])) {
+ AV_COPY32(mv_cache[0][1], mv_cache[1][1]);
+ AV_COPY32(mv_cache[0][2], mv_cache[1][2]);
+ } else {
+ AV_COPY32(mv_cache[0][1],
+ cur_frame->motion_val[0][mot_xy - mot_stride]);
+ AV_COPY32(mv_cache[0][2],
+ cur_frame->motion_val[0][mot_xy - mot_stride + 1]);
+ }
+
+ if (mb_x == 0 || IS_INTRA(cur_frame->mb_type[xy - 1])) {
+ AV_COPY32(mv_cache[1][0], mv_cache[1][1]);
+ AV_COPY32(mv_cache[2][0], mv_cache[2][1]);
+ } else {
+ AV_COPY32(mv_cache[1][0], cur_frame->motion_val[0][mot_xy - 1]);
+ AV_COPY32(mv_cache[2][0],
+ cur_frame->motion_val[0][mot_xy - 1 + mot_stride]);
+ }
+
+ if (mb_x + 1 >= s->mb_width || IS_INTRA(cur_frame->mb_type[xy + 1])) {
+ AV_COPY32(mv_cache[1][3], mv_cache[1][2]);
+ AV_COPY32(mv_cache[2][3], mv_cache[2][2]);
+ } else {
+ AV_COPY32(mv_cache[1][3], cur_frame->motion_val[0][mot_xy + 2]);
+ AV_COPY32(mv_cache[2][3],
+ cur_frame->motion_val[0][mot_xy + 2 + mot_stride]);
+ }
+
+ mx = 0;
+ my = 0;
+ for (i = 0; i < 4; i++) {
+ const int x = (i & 1) + 1;
+ const int y = (i >> 1) + 1;
+ int16_t mv[5][2] = {
+ { mv_cache[y][x][0], mv_cache[y][x][1] },
+ { mv_cache[y - 1][x][0], mv_cache[y - 1][x][1] },
+ { mv_cache[y][x - 1][0], mv_cache[y][x - 1][1] },
+ { mv_cache[y][x + 1][0], mv_cache[y][x + 1][1] },
+ { mv_cache[y + 1][x][0], mv_cache[y + 1][x][1] }
+ };
+ // FIXME cleanup
+ obmc_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
+ ref_picture[0],
+ mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >> 1) * 8,
+ pix_op[1],
+ mv);
+
+ mx += mv[0][0];
+ my += mv[0][1];
+ }
+ if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))
+ chroma_4mv_motion(s, dest_cb, dest_cr,
+ ref_picture, pix_op[1],
+ mx, my);
+}
+
+static inline void apply_8x8(MpegEncContext *s,
+ uint8_t *dest_y,
+ uint8_t *dest_cb,
+ uint8_t *dest_cr,
+ int dir,
+ uint8_t **ref_picture,
+ qpel_mc_func (*qpix_op)[16],
+ op_pixels_func (*pix_op)[4])
+{
+ int dxy, mx, my, src_x, src_y;
+ int i;
+ int mb_x = s->mb_x;
+ int mb_y = s->mb_y;
+ uint8_t *ptr, *dest;
+
+ mx = 0;
+ my = 0;
+ if (s->quarter_sample) {
+ for (i = 0; i < 4; i++) {
+ int motion_x = s->mv[dir][i][0];
+ int motion_y = s->mv[dir][i][1];
+
+ dxy = ((motion_y & 3) << 2) | (motion_x & 3);
+ src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8;
+ src_y = mb_y * 16 + (motion_y >> 2) + (i >> 1) * 8;
+
+ /* WARNING: do no forget half pels */
+ src_x = av_clip(src_x, -16, s->width);
+ if (src_x == s->width)
+ dxy &= ~3;
+ src_y = av_clip(src_y, -16, s->height);
+ if (src_y == s->height)
+ dxy &= ~12;
+
+ ptr = ref_picture[0] + (src_y * s->linesize) + (src_x);
+ if ((unsigned)src_x >= FFMAX(s->h_edge_pos - (motion_x & 3) - 7, 0) ||
+ (unsigned)src_y >= FFMAX(s->v_edge_pos - (motion_y & 3) - 7, 0)) {
+ s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr,
+ s->linesize, s->linesize,
+ 9, 9,
+ src_x, src_y,
+ s->h_edge_pos,
+ s->v_edge_pos);
+ ptr = s->sc.edge_emu_buffer;
+ }
+ dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize;
+ qpix_op[1][dxy](dest, ptr, s->linesize);
+
+ mx += s->mv[dir][i][0] / 2;
+ my += s->mv[dir][i][1] / 2;
+ }
+ } else {
+ for (i = 0; i < 4; i++) {
+ hpel_motion(s,
+ dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize,
+ ref_picture[0],
+ mb_x * 16 + (i & 1) * 8,
+ mb_y * 16 + (i >> 1) * 8,
+ pix_op[1],
+ s->mv[dir][i][0],
+ s->mv[dir][i][1]);
+
+ mx += s->mv[dir][i][0];
+ my += s->mv[dir][i][1];
+ }
+ }
+
+ if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY))
+ chroma_4mv_motion(s, dest_cb, dest_cr,
+ ref_picture, pix_op[1], mx, my);
+}
+
+/**
+ * motion compensation of a single macroblock
+ * @param s context
+ * @param dest_y luma destination pointer
+ * @param dest_cb chroma cb/u destination pointer
+ * @param dest_cr chroma cr/v destination pointer
+ * @param dir direction (0->forward, 1->backward)
+ * @param ref_picture array[3] of pointers to the 3 planes of the reference picture
+ * @param pix_op halfpel motion compensation function (average or put normally)
+ * @param qpix_op qpel motion compensation function (average or put normally)
+ * the motion vectors are taken from s->mv and the MV type from s->mv_type
+ */
+static av_always_inline void mpv_motion_internal(MpegEncContext *s,
+ uint8_t *dest_y,
+ uint8_t *dest_cb,
+ uint8_t *dest_cr,
+ int dir,
+ uint8_t **ref_picture,
+ op_pixels_func (*pix_op)[4],
+ qpel_mc_func (*qpix_op)[16],
+ int is_mpeg12)
+{
+ int i;
+ int mb_y = s->mb_y;
+
+ prefetch_motion(s, ref_picture, dir);
+
+ if (!is_mpeg12 && s->obmc && s->pict_type != AV_PICTURE_TYPE_B) {
+ apply_obmc(s, dest_y, dest_cb, dest_cr, ref_picture, pix_op);
+ return;
+ }
+
+ switch (s->mv_type) {
+ case MV_TYPE_16X16:
+ if (s->mcsel) {
+ if (s->real_sprite_warping_points == 1) {
+ gmc1_motion(s, dest_y, dest_cb, dest_cr,
+ ref_picture);
+ } else {
+ gmc_motion(s, dest_y, dest_cb, dest_cr,
+ ref_picture);
+ }
+ } else if (!is_mpeg12 && s->quarter_sample) {
+ qpel_motion(s, dest_y, dest_cb, dest_cr,
+ 0, 0, 0,
+ ref_picture, pix_op, qpix_op,
+ s->mv[dir][0][0], s->mv[dir][0][1], 16);
+ } else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) &&
+ s->mspel && s->codec_id == AV_CODEC_ID_WMV2) {
+ ff_mspel_motion(s, dest_y, dest_cb, dest_cr,
+ ref_picture, pix_op,
+ s->mv[dir][0][0], s->mv[dir][0][1], 16);
+ } else {
+ mpeg_motion(s, dest_y, dest_cb, dest_cr, 0,
+ ref_picture, pix_op,
+ s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y);
+ }
+ break;
+ case MV_TYPE_8X8:
+ if (!is_mpeg12)
+ apply_8x8(s, dest_y, dest_cb, dest_cr,
+ dir, ref_picture, qpix_op, pix_op);
+ break;
+ case MV_TYPE_FIELD:
+ if (s->picture_structure == PICT_FRAME) {
+ if (!is_mpeg12 && s->quarter_sample) {
+ for (i = 0; i < 2; i++)
+ qpel_motion(s, dest_y, dest_cb, dest_cr,
+ 1, i, s->field_select[dir][i],
+ ref_picture, pix_op, qpix_op,
+ s->mv[dir][i][0], s->mv[dir][i][1], 8);
+ } else {
+ /* top field */
+ mpeg_motion_field(s, dest_y, dest_cb, dest_cr,
+ 0, s->field_select[dir][0],
+ ref_picture, pix_op,
+ s->mv[dir][0][0], s->mv[dir][0][1], 8, mb_y);
+ /* bottom field */
+ mpeg_motion_field(s, dest_y, dest_cb, dest_cr,
+ 1, s->field_select[dir][1],
+ ref_picture, pix_op,
+ s->mv[dir][1][0], s->mv[dir][1][1], 8, mb_y);
+ }
+ } else {
+ if ( s->picture_structure != s->field_select[dir][0] + 1 && s->pict_type != AV_PICTURE_TYPE_B && !s->first_field
+ || !ref_picture[0]) {
+ ref_picture = s->current_picture_ptr->f->data;
+ }
+
+ mpeg_motion(s, dest_y, dest_cb, dest_cr,
+ s->field_select[dir][0],
+ ref_picture, pix_op,
+ s->mv[dir][0][0], s->mv[dir][0][1], 16, mb_y >> 1);
+ }
+ 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] + 16 * i,
+ 8, mb_y >> 1);
+
+ dest_y += 16 * s->linesize;
+ dest_cb += (16 >> s->chroma_y_shift) * s->uvlinesize;
+ dest_cr += (16 >> s->chroma_y_shift) * s->uvlinesize;
+ }
+ 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;
+ }
+ 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, 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;
+ default: av_assert2(0);
+ }
+}
+
+void ff_mpv_motion(MpegEncContext *s,
+ uint8_t *dest_y, uint8_t *dest_cb,
+ uint8_t *dest_cr, int dir,
+ uint8_t **ref_picture,
+ op_pixels_func (*pix_op)[4],
+ qpel_mc_func (*qpix_op)[16])
+{
+#if !CONFIG_SMALL
+ if (s->out_format == FMT_MPEG1)
+ mpv_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
+ ref_picture, pix_op, qpix_op, 1);
+ else
+#endif
+ mpv_motion_internal(s, dest_y, dest_cb, dest_cr, dir,
+ ref_picture, pix_op, qpix_op, 0);
+}
diff --git a/ffmpeg-2-8-11/libavcodec/mpegvideo_parser.c b/ffmpeg-2-8-12/libavcodec/mpegvideo_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegvideo_parser.c
rename to ffmpeg-2-8-12/libavcodec/mpegvideo_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegvideo_xvmc.c b/ffmpeg-2-8-12/libavcodec/mpegvideo_xvmc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegvideo_xvmc.c
rename to ffmpeg-2-8-12/libavcodec/mpegvideo_xvmc.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegvideodata.c b/ffmpeg-2-8-12/libavcodec/mpegvideodata.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegvideodata.c
rename to ffmpeg-2-8-12/libavcodec/mpegvideodata.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegvideodata.h b/ffmpeg-2-8-12/libavcodec/mpegvideodata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegvideodata.h
rename to ffmpeg-2-8-12/libavcodec/mpegvideodata.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpegvideodsp.c b/ffmpeg-2-8-12/libavcodec/mpegvideodsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegvideodsp.c
rename to ffmpeg-2-8-12/libavcodec/mpegvideodsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegvideodsp.h b/ffmpeg-2-8-12/libavcodec/mpegvideodsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegvideodsp.h
rename to ffmpeg-2-8-12/libavcodec/mpegvideodsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpegvideoencdsp.c b/ffmpeg-2-8-12/libavcodec/mpegvideoencdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegvideoencdsp.c
rename to ffmpeg-2-8-12/libavcodec/mpegvideoencdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/mpegvideoencdsp.h b/ffmpeg-2-8-12/libavcodec/mpegvideoencdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpegvideoencdsp.h
rename to ffmpeg-2-8-12/libavcodec/mpegvideoencdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/mpl2dec.c b/ffmpeg-2-8-12/libavcodec/mpl2dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mpl2dec.c
rename to ffmpeg-2-8-12/libavcodec/mpl2dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/mqc.c b/ffmpeg-2-8-12/libavcodec/mqc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mqc.c
rename to ffmpeg-2-8-12/libavcodec/mqc.c
diff --git a/ffmpeg-2-8-11/libavcodec/mqc.h b/ffmpeg-2-8-12/libavcodec/mqc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mqc.h
rename to ffmpeg-2-8-12/libavcodec/mqc.h
diff --git a/ffmpeg-2-8-11/libavcodec/mqcdec.c b/ffmpeg-2-8-12/libavcodec/mqcdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mqcdec.c
rename to ffmpeg-2-8-12/libavcodec/mqcdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/mqcenc.c b/ffmpeg-2-8-12/libavcodec/mqcenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mqcenc.c
rename to ffmpeg-2-8-12/libavcodec/mqcenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/msgsmdec.c b/ffmpeg-2-8-12/libavcodec/msgsmdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/msgsmdec.c
rename to ffmpeg-2-8-12/libavcodec/msgsmdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/msgsmdec.h b/ffmpeg-2-8-12/libavcodec/msgsmdec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/msgsmdec.h
rename to ffmpeg-2-8-12/libavcodec/msgsmdec.h
diff --git a/ffmpeg-2-8-11/libavcodec/msmpeg4.c b/ffmpeg-2-8-12/libavcodec/msmpeg4.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/msmpeg4.c
rename to ffmpeg-2-8-12/libavcodec/msmpeg4.c
diff --git a/ffmpeg-2-8-11/libavcodec/msmpeg4.h b/ffmpeg-2-8-12/libavcodec/msmpeg4.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/msmpeg4.h
rename to ffmpeg-2-8-12/libavcodec/msmpeg4.h
diff --git a/ffmpeg-2-8-11/libavcodec/msmpeg4data.c b/ffmpeg-2-8-12/libavcodec/msmpeg4data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/msmpeg4data.c
rename to ffmpeg-2-8-12/libavcodec/msmpeg4data.c
diff --git a/ffmpeg-2-8-11/libavcodec/msmpeg4data.h b/ffmpeg-2-8-12/libavcodec/msmpeg4data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/msmpeg4data.h
rename to ffmpeg-2-8-12/libavcodec/msmpeg4data.h
diff --git a/ffmpeg-2-8-12/libavcodec/msmpeg4dec.c b/ffmpeg-2-8-12/libavcodec/msmpeg4dec.c
new file mode 100644
index 0000000..f407910
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/msmpeg4dec.c
@@ -0,0 +1,995 @@
+/*
+ * MSMPEG4 backend for encoder and decoder
+ * Copyright (c) 2001 Fabrice Bellard
+ * Copyright (c) 2002-2013 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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 "mpegutils.h"
+#include "mpegvideo.h"
+#include "msmpeg4.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/x86/asm.h"
+#include "h263.h"
+#include "mpeg4video.h"
+#include "msmpeg4data.h"
+#include "vc1data.h"
+#include "wmv2.h"
+
+#define DC_VLC_BITS 9
+#define V2_INTRA_CBPC_VLC_BITS 3
+#define V2_MB_TYPE_VLC_BITS 7
+#define MV_VLC_BITS 9
+#define V2_MV_VLC_BITS 9
+#define TEX_VLC_BITS 9
+
+#define DEFAULT_INTER_INDEX 3
+
+static inline int msmpeg4v1_pred_dc(MpegEncContext * s, int n,
+ int32_t **dc_val_ptr)
+{
+ int i;
+
+ if (n < 4) {
+ i= 0;
+ } else {
+ i= n-3;
+ }
+
+ *dc_val_ptr= &s->last_dc[i];
+ return s->last_dc[i];
+}
+
+/****************************************/
+/* decoding stuff */
+
+VLC ff_mb_non_intra_vlc[4];
+static VLC v2_dc_lum_vlc;
+static VLC v2_dc_chroma_vlc;
+static VLC v2_intra_cbpc_vlc;
+static VLC v2_mb_type_vlc;
+static VLC v2_mv_vlc;
+VLC ff_inter_intra_vlc;
+
+/* This is identical to h263 except that its range is multiplied by 2. */
+static int msmpeg4v2_decode_motion(MpegEncContext * s, int pred, int f_code)
+{
+ int code, val, sign, shift;
+
+ code = get_vlc2(&s->gb, v2_mv_vlc.table, V2_MV_VLC_BITS, 2);
+ 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;
+
+ if (code == 0)
+ return pred;
+ sign = get_bits1(&s->gb);
+ shift = f_code - 1;
+ val = code;
+ if (shift) {
+ val = (val - 1) << shift;
+ val |= get_bits(&s->gb, shift);
+ val++;
+ }
+ if (sign)
+ val = -val;
+
+ val += pred;
+ if (val <= -64)
+ val += 64;
+ else if (val >= 64)
+ val -= 64;
+
+ return val;
+}
+
+static int msmpeg4v12_decode_mb(MpegEncContext *s, int16_t block[6][64])
+{
+ int cbp, code, i;
+ uint32_t * const mb_type_ptr = &s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride];
+
+ if (s->pict_type == AV_PICTURE_TYPE_P) {
+ if (s->use_skip_mb_code) {
+ if (get_bits1(&s->gb)) {
+ /* skip mb */
+ s->mb_intra = 0;
+ for(i=0;i<6;i++)
+ s->block_last_index[i] = -1;
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ s->mv[0][0][0] = 0;
+ s->mv[0][0][1] = 0;
+ s->mb_skipped = 1;
+ *mb_type_ptr = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
+ return 0;
+ }
+ }
+
+ if(s->msmpeg4_version==2)
+ code = get_vlc2(&s->gb, v2_mb_type_vlc.table, V2_MB_TYPE_VLC_BITS, 1);
+ else
+ code = get_vlc2(&s->gb, ff_h263_inter_MCBPC_vlc.table, INTER_MCBPC_VLC_BITS, 2);
+ if(code<0 || code>7){
+ av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", code, s->mb_x, s->mb_y);
+ return -1;
+ }
+
+ s->mb_intra = code >>2;
+
+ cbp = code & 0x3;
+ } else {
+ s->mb_intra = 1;
+ if(s->msmpeg4_version==2)
+ cbp= get_vlc2(&s->gb, v2_intra_cbpc_vlc.table, V2_INTRA_CBPC_VLC_BITS, 1);
+ else
+ cbp= get_vlc2(&s->gb, ff_h263_intra_MCBPC_vlc.table, INTRA_MCBPC_VLC_BITS, 2);
+ if(cbp<0 || cbp>3){
+ av_log(s->avctx, AV_LOG_ERROR, "cbpc %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y);
+ return -1;
+ }
+ }
+
+ if (!s->mb_intra) {
+ int mx, my, cbpy;
+
+ cbpy= get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+ if(cbpy<0){
+ av_log(s->avctx, AV_LOG_ERROR, "cbpy %d invalid at %d %d\n", cbp, s->mb_x, s->mb_y);
+ return -1;
+ }
+
+ cbp|= cbpy<<2;
+ if(s->msmpeg4_version==1 || (cbp&3) != 3) cbp^= 0x3C;
+
+ ff_h263_pred_motion(s, 0, 0, &mx, &my);
+ mx= msmpeg4v2_decode_motion(s, mx, 1);
+ my= msmpeg4v2_decode_motion(s, my, 1);
+
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ s->mv[0][0][0] = mx;
+ s->mv[0][0][1] = my;
+ *mb_type_ptr = MB_TYPE_L0 | MB_TYPE_16x16;
+ } else {
+ int v;
+ if(s->msmpeg4_version==2){
+ s->ac_pred = get_bits1(&s->gb);
+ v = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+ if (v < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "cbpy vlc invalid\n");
+ return -1;
+ }
+ cbp|= v<<2;
+ } else{
+ s->ac_pred = 0;
+ v = get_vlc2(&s->gb, ff_h263_cbpy_vlc.table, CBPY_VLC_BITS, 1);
+ if (v < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "cbpy vlc invalid\n");
+ return -1;
+ }
+ cbp|= v<<2;
+ if(s->pict_type==AV_PICTURE_TYPE_P) cbp^=0x3C;
+ }
+ *mb_type_ptr = MB_TYPE_INTRA;
+ }
+
+ s->bdsp.clear_blocks(s->block[0]);
+ for (i = 0; i < 6; i++) {
+ if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
+ {
+ av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int msmpeg4v34_decode_mb(MpegEncContext *s, int16_t block[6][64])
+{
+ int cbp, code, i;
+ uint8_t *coded_val;
+ uint32_t * const mb_type_ptr = &s->current_picture.mb_type[s->mb_x + s->mb_y*s->mb_stride];
+
+ if (s->pict_type == AV_PICTURE_TYPE_P) {
+ if (s->use_skip_mb_code) {
+ if (get_bits1(&s->gb)) {
+ /* skip mb */
+ s->mb_intra = 0;
+ for(i=0;i<6;i++)
+ s->block_last_index[i] = -1;
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ s->mv[0][0][0] = 0;
+ s->mv[0][0][1] = 0;
+ s->mb_skipped = 1;
+ *mb_type_ptr = MB_TYPE_SKIP | MB_TYPE_L0 | MB_TYPE_16x16;
+
+ return 0;
+ }
+ }
+
+ code = get_vlc2(&s->gb, ff_mb_non_intra_vlc[DEFAULT_INTER_INDEX].table, MB_NON_INTRA_VLC_BITS, 3);
+ if (code < 0)
+ return -1;
+ //s->mb_intra = (code & 0x40) ? 0 : 1;
+ s->mb_intra = (~code & 0x40) >> 6;
+
+ cbp = code & 0x3f;
+ } else {
+ s->mb_intra = 1;
+ code = get_vlc2(&s->gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
+ if (code < 0)
+ return -1;
+ /* predict coded block pattern */
+ cbp = 0;
+ for(i=0;i<6;i++) {
+ int val = ((code >> (5 - i)) & 1);
+ if (i < 4) {
+ int pred = ff_msmpeg4_coded_block_pred(s, i, &coded_val);
+ val = val ^ pred;
+ *coded_val = val;
+ }
+ cbp |= val << (5 - i);
+ }
+ }
+
+ if (!s->mb_intra) {
+ int mx, my;
+ if(s->per_mb_rl_table && cbp){
+ s->rl_table_index = decode012(&s->gb);
+ s->rl_chroma_table_index = s->rl_table_index;
+ }
+ ff_h263_pred_motion(s, 0, 0, &mx, &my);
+ if (ff_msmpeg4_decode_motion(s, &mx, &my) < 0)
+ return -1;
+ s->mv_dir = MV_DIR_FORWARD;
+ s->mv_type = MV_TYPE_16X16;
+ s->mv[0][0][0] = mx;
+ s->mv[0][0][1] = my;
+ *mb_type_ptr = MB_TYPE_L0 | MB_TYPE_16x16;
+ } else {
+ ff_dlog(s, "I at %d %d %d %06X\n", s->mb_x, s->mb_y,
+ ((cbp & 3) ? 1 : 0) +((cbp & 0x3C)? 2 : 0),
+ show_bits(&s->gb, 24));
+ s->ac_pred = get_bits1(&s->gb);
+ *mb_type_ptr = MB_TYPE_INTRA;
+ if(s->inter_intra_pred){
+ s->h263_aic_dir= get_vlc2(&s->gb, ff_inter_intra_vlc.table, INTER_INTRA_VLC_BITS, 1);
+ ff_dlog(s, "%d%d %d %d/",
+ s->ac_pred, s->h263_aic_dir, s->mb_x, s->mb_y);
+ }
+ if(s->per_mb_rl_table && cbp){
+ s->rl_table_index = decode012(&s->gb);
+ s->rl_chroma_table_index = s->rl_table_index;
+ }
+ }
+
+ s->bdsp.clear_blocks(s->block[0]);
+ for (i = 0; i < 6; i++) {
+ if (ff_msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1, NULL) < 0)
+ {
+ av_log(s->avctx, AV_LOG_ERROR, "\nerror while decoding block: %d x %d (%d)\n", s->mb_x, s->mb_y, i);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/* init all vlc decoding tables */
+av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx)
+{
+ MpegEncContext *s = avctx->priv_data;
+ static volatile int done = 0;
+ int i, ret;
+ MVTable *mv;
+
+ if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
+ return ret;
+
+ if (ff_h263_decode_init(avctx) < 0)
+ return -1;
+
+ ff_msmpeg4_common_init(s);
+
+ if (!done) {
+ for(i=0;i<NB_RL_TABLES;i++) {
+ ff_rl_init(&ff_rl_table[i], ff_static_rl_table_store[i]);
+ }
+ INIT_VLC_RL(ff_rl_table[0], 642);
+ INIT_VLC_RL(ff_rl_table[1], 1104);
+ INIT_VLC_RL(ff_rl_table[2], 554);
+ INIT_VLC_RL(ff_rl_table[3], 940);
+ INIT_VLC_RL(ff_rl_table[4], 962);
+ INIT_VLC_RL(ff_rl_table[5], 554);
+
+ mv = &ff_mv_tables[0];
+ INIT_VLC_STATIC(&mv->vlc, MV_VLC_BITS, mv->n + 1,
+ mv->table_mv_bits, 1, 1,
+ mv->table_mv_code, 2, 2, 3714);
+ mv = &ff_mv_tables[1];
+ INIT_VLC_STATIC(&mv->vlc, MV_VLC_BITS, mv->n + 1,
+ mv->table_mv_bits, 1, 1,
+ mv->table_mv_code, 2, 2, 2694);
+
+ INIT_VLC_STATIC(&ff_msmp4_dc_luma_vlc[0], DC_VLC_BITS, 120,
+ &ff_table0_dc_lum[0][1], 8, 4,
+ &ff_table0_dc_lum[0][0], 8, 4, 1158);
+ INIT_VLC_STATIC(&ff_msmp4_dc_chroma_vlc[0], DC_VLC_BITS, 120,
+ &ff_table0_dc_chroma[0][1], 8, 4,
+ &ff_table0_dc_chroma[0][0], 8, 4, 1118);
+ INIT_VLC_STATIC(&ff_msmp4_dc_luma_vlc[1], DC_VLC_BITS, 120,
+ &ff_table1_dc_lum[0][1], 8, 4,
+ &ff_table1_dc_lum[0][0], 8, 4, 1476);
+ INIT_VLC_STATIC(&ff_msmp4_dc_chroma_vlc[1], DC_VLC_BITS, 120,
+ &ff_table1_dc_chroma[0][1], 8, 4,
+ &ff_table1_dc_chroma[0][0], 8, 4, 1216);
+
+ INIT_VLC_STATIC(&v2_dc_lum_vlc, DC_VLC_BITS, 512,
+ &ff_v2_dc_lum_table[0][1], 8, 4,
+ &ff_v2_dc_lum_table[0][0], 8, 4, 1472);
+ INIT_VLC_STATIC(&v2_dc_chroma_vlc, DC_VLC_BITS, 512,
+ &ff_v2_dc_chroma_table[0][1], 8, 4,
+ &ff_v2_dc_chroma_table[0][0], 8, 4, 1506);
+
+ INIT_VLC_STATIC(&v2_intra_cbpc_vlc, V2_INTRA_CBPC_VLC_BITS, 4,
+ &ff_v2_intra_cbpc[0][1], 2, 1,
+ &ff_v2_intra_cbpc[0][0], 2, 1, 8);
+ INIT_VLC_STATIC(&v2_mb_type_vlc, V2_MB_TYPE_VLC_BITS, 8,
+ &ff_v2_mb_type[0][1], 2, 1,
+ &ff_v2_mb_type[0][0], 2, 1, 128);
+ INIT_VLC_STATIC(&v2_mv_vlc, V2_MV_VLC_BITS, 33,
+ &ff_mvtab[0][1], 2, 1,
+ &ff_mvtab[0][0], 2, 1, 538);
+
+ INIT_VLC_STATIC(&ff_mb_non_intra_vlc[0], MB_NON_INTRA_VLC_BITS, 128,
+ &ff_wmv2_inter_table[0][0][1], 8, 4,
+ &ff_wmv2_inter_table[0][0][0], 8, 4, 1636);
+ INIT_VLC_STATIC(&ff_mb_non_intra_vlc[1], MB_NON_INTRA_VLC_BITS, 128,
+ &ff_wmv2_inter_table[1][0][1], 8, 4,
+ &ff_wmv2_inter_table[1][0][0], 8, 4, 2648);
+ INIT_VLC_STATIC(&ff_mb_non_intra_vlc[2], MB_NON_INTRA_VLC_BITS, 128,
+ &ff_wmv2_inter_table[2][0][1], 8, 4,
+ &ff_wmv2_inter_table[2][0][0], 8, 4, 1532);
+ INIT_VLC_STATIC(&ff_mb_non_intra_vlc[3], MB_NON_INTRA_VLC_BITS, 128,
+ &ff_wmv2_inter_table[3][0][1], 8, 4,
+ &ff_wmv2_inter_table[3][0][0], 8, 4, 2488);
+
+ INIT_VLC_STATIC(&ff_msmp4_mb_i_vlc, MB_INTRA_VLC_BITS, 64,
+ &ff_msmp4_mb_i_table[0][1], 4, 2,
+ &ff_msmp4_mb_i_table[0][0], 4, 2, 536);
+
+ INIT_VLC_STATIC(&ff_inter_intra_vlc, INTER_INTRA_VLC_BITS, 4,
+ &ff_table_inter_intra[0][1], 2, 1,
+ &ff_table_inter_intra[0][0], 2, 1, 8);
+ done = 1;
+ }
+
+ switch(s->msmpeg4_version){
+ case 1:
+ case 2:
+ s->decode_mb= msmpeg4v12_decode_mb;
+ break;
+ case 3:
+ case 4:
+ s->decode_mb= msmpeg4v34_decode_mb;
+ break;
+ case 5:
+ if (CONFIG_WMV2_DECODER)
+ s->decode_mb= ff_wmv2_decode_mb;
+ case 6:
+ //FIXME + TODO VC1 decode mb
+ break;
+ }
+
+ s->slice_height= s->mb_height; //to avoid 1/0 if the first frame is not a keyframe
+
+ return 0;
+}
+
+int ff_msmpeg4_decode_picture_header(MpegEncContext * s)
+{
+ int code;
+
+ if(s->msmpeg4_version==1){
+ int start_code = get_bits_long(&s->gb, 32);
+ if(start_code!=0x00000100){
+ av_log(s->avctx, AV_LOG_ERROR, "invalid startcode\n");
+ return -1;
+ }
+
+ skip_bits(&s->gb, 5); // frame number */
+ }
+
+ s->pict_type = get_bits(&s->gb, 2) + 1;
+ if (s->pict_type != AV_PICTURE_TYPE_I &&
+ s->pict_type != AV_PICTURE_TYPE_P){
+ av_log(s->avctx, AV_LOG_ERROR, "invalid picture type\n");
+ return -1;
+ }
+#if 0
+{
+ static int had_i=0;
+ if(s->pict_type == AV_PICTURE_TYPE_I) had_i=1;
+ if(!had_i) return -1;
+}
+#endif
+ s->chroma_qscale= s->qscale = get_bits(&s->gb, 5);
+ if(s->qscale==0){
+ av_log(s->avctx, AV_LOG_ERROR, "invalid qscale\n");
+ return -1;
+ }
+
+ if (s->pict_type == AV_PICTURE_TYPE_I) {
+ code = get_bits(&s->gb, 5);
+ if(s->msmpeg4_version==1){
+ if(code==0 || code>s->mb_height){
+ av_log(s->avctx, AV_LOG_ERROR, "invalid slice height %d\n", code);
+ return -1;
+ }
+
+ s->slice_height = code;
+ }else{
+ /* 0x17: one slice, 0x18: two slices, ... */
+ if (code < 0x17){
+ av_log(s->avctx, AV_LOG_ERROR, "error, slice code was %X\n", code);
+ return -1;
+ }
+
+ s->slice_height = s->mb_height / (code - 0x16);
+ }
+
+ switch(s->msmpeg4_version){
+ case 1:
+ case 2:
+ s->rl_chroma_table_index = 2;
+ s->rl_table_index = 2;
+
+ s->dc_table_index = 0; //not used
+ break;
+ case 3:
+ s->rl_chroma_table_index = decode012(&s->gb);
+ s->rl_table_index = decode012(&s->gb);
+
+ s->dc_table_index = get_bits1(&s->gb);
+ break;
+ case 4:
+ ff_msmpeg4_decode_ext_header(s, (2+5+5+17+7)/8);
+
+ if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb);
+ else s->per_mb_rl_table= 0;
+
+ if(!s->per_mb_rl_table){
+ s->rl_chroma_table_index = decode012(&s->gb);
+ s->rl_table_index = decode012(&s->gb);
+ }
+
+ s->dc_table_index = get_bits1(&s->gb);
+ s->inter_intra_pred= 0;
+ break;
+ }
+ s->no_rounding = 1;
+ if(s->avctx->debug&FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_DEBUG, "qscale:%d rlc:%d rl:%d dc:%d mbrl:%d slice:%d \n",
+ s->qscale,
+ s->rl_chroma_table_index,
+ s->rl_table_index,
+ s->dc_table_index,
+ s->per_mb_rl_table,
+ s->slice_height);
+ } else {
+ switch(s->msmpeg4_version){
+ case 1:
+ case 2:
+ if(s->msmpeg4_version==1)
+ s->use_skip_mb_code = 1;
+ else
+ s->use_skip_mb_code = get_bits1(&s->gb);
+ s->rl_table_index = 2;
+ s->rl_chroma_table_index = s->rl_table_index;
+ s->dc_table_index = 0; //not used
+ s->mv_table_index = 0;
+ break;
+ case 3:
+ s->use_skip_mb_code = get_bits1(&s->gb);
+ s->rl_table_index = decode012(&s->gb);
+ s->rl_chroma_table_index = s->rl_table_index;
+
+ s->dc_table_index = get_bits1(&s->gb);
+
+ s->mv_table_index = get_bits1(&s->gb);
+ break;
+ case 4:
+ s->use_skip_mb_code = get_bits1(&s->gb);
+
+ if(s->bit_rate > MBAC_BITRATE) s->per_mb_rl_table= get_bits1(&s->gb);
+ else s->per_mb_rl_table= 0;
+
+ if(!s->per_mb_rl_table){
+ s->rl_table_index = decode012(&s->gb);
+ s->rl_chroma_table_index = s->rl_table_index;
+ }
+
+ s->dc_table_index = get_bits1(&s->gb);
+
+ s->mv_table_index = get_bits1(&s->gb);
+ s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE);
+ break;
+ }
+
+ if(s->avctx->debug&FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_DEBUG, "skip:%d rl:%d rlc:%d dc:%d mv:%d mbrl:%d qp:%d \n",
+ s->use_skip_mb_code,
+ s->rl_table_index,
+ s->rl_chroma_table_index,
+ s->dc_table_index,
+ s->mv_table_index,
+ s->per_mb_rl_table,
+ s->qscale);
+
+ if(s->flipflop_rounding){
+ s->no_rounding ^= 1;
+ }else{
+ s->no_rounding = 0;
+ }
+ }
+ ff_dlog(s->avctx, "%d %"PRId64" %d %d %d\n", s->pict_type, s->bit_rate,
+ s->inter_intra_pred, s->width, s->height);
+
+ s->esc3_level_length= 0;
+ s->esc3_run_length= 0;
+
+ return 0;
+}
+
+int ff_msmpeg4_decode_ext_header(MpegEncContext * s, int buf_size)
+{
+ int left= buf_size*8 - get_bits_count(&s->gb);
+ int length= s->msmpeg4_version>=3 ? 17 : 16;
+ /* the alt_bitstream reader could read over the end so we need to check it */
+ if(left>=length && left<length+8)
+ {
+ skip_bits(&s->gb, 5); /* fps */
+ s->bit_rate= get_bits(&s->gb, 11)*1024;
+ if(s->msmpeg4_version>=3)
+ s->flipflop_rounding= get_bits1(&s->gb);
+ else
+ s->flipflop_rounding= 0;
+ }
+ else if(left<length+8)
+ {
+ s->flipflop_rounding= 0;
+ if(s->msmpeg4_version != 2)
+ av_log(s->avctx, AV_LOG_ERROR, "ext header missing, %d left\n", left);
+ }
+ else
+ {
+ av_log(s->avctx, AV_LOG_ERROR, "I frame too long, ignoring ext header\n");
+ }
+
+ return 0;
+}
+
+static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr)
+{
+ int level, pred;
+
+ if(s->msmpeg4_version<=2){
+ if (n < 4) {
+ level = get_vlc2(&s->gb, v2_dc_lum_vlc.table, DC_VLC_BITS, 3);
+ } else {
+ level = get_vlc2(&s->gb, v2_dc_chroma_vlc.table, DC_VLC_BITS, 3);
+ }
+ if (level < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n");
+ *dir_ptr = 0;
+ return -1;
+ }
+ level-=256;
+ }else{ //FIXME optimize use unified tables & index
+ if (n < 4) {
+ level = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+ } else {
+ level = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+ }
+ if (level < 0){
+ av_log(s->avctx, AV_LOG_ERROR, "illegal dc vlc\n");
+ *dir_ptr = 0;
+ return -1;
+ }
+
+ if (level == DC_MAX) {
+ level = get_bits(&s->gb, 8);
+ if (get_bits1(&s->gb))
+ level = -level;
+ } else if (level != 0) {
+ if (get_bits1(&s->gb))
+ level = -level;
+ }
+ }
+
+ if(s->msmpeg4_version==1){
+ int32_t *dc_val;
+ pred = msmpeg4v1_pred_dc(s, n, &dc_val);
+ level += pred;
+
+ /* update predictor */
+ *dc_val= level;
+ }else{
+ int16_t *dc_val;
+ pred = ff_msmpeg4_pred_dc(s, n, &dc_val, dir_ptr);
+ level += pred;
+
+ /* update predictor */
+ if (n < 4) {
+ *dc_val = level * s->y_dc_scale;
+ } else {
+ *dc_val = level * s->c_dc_scale;
+ }
+ }
+
+ return level;
+}
+
+//#define ERROR_DETAILS
+int ff_msmpeg4_decode_block(MpegEncContext * s, int16_t * block,
+ int n, int coded, const uint8_t *scan_table)
+{
+ int level, i, last, run, run_diff;
+ int av_uninit(dc_pred_dir);
+ RLTable *rl;
+ RL_VLC_ELEM *rl_vlc;
+ int qmul, qadd;
+
+ if (s->mb_intra) {
+ qmul=1;
+ qadd=0;
+
+ /* DC coef */
+ level = msmpeg4_decode_dc(s, n, &dc_pred_dir);
+
+ if (level < 0){
+ av_log(s->avctx, AV_LOG_ERROR, "dc overflow- block: %d qscale: %d//\n", n, s->qscale);
+ if(s->inter_intra_pred) level=0;
+ }
+ if (n < 4) {
+ rl = &ff_rl_table[s->rl_table_index];
+ if(level > 256*s->y_dc_scale){
+ av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ L qscale: %d//\n", s->qscale);
+ if(!s->inter_intra_pred) return -1;
+ }
+ } else {
+ rl = &ff_rl_table[3 + s->rl_chroma_table_index];
+ if(level > 256*s->c_dc_scale){
+ av_log(s->avctx, AV_LOG_ERROR, "dc overflow+ C qscale: %d//\n", s->qscale);
+ if(!s->inter_intra_pred) return -1;
+ }
+ }
+ block[0] = level;
+
+ run_diff = s->msmpeg4_version >= 4;
+ i = 0;
+ if (!coded) {
+ goto not_coded;
+ }
+ if (s->ac_pred) {
+ if (dc_pred_dir == 0)
+ scan_table = s->intra_v_scantable.permutated; /* left */
+ else
+ scan_table = s->intra_h_scantable.permutated; /* top */
+ } else {
+ scan_table = s->intra_scantable.permutated;
+ }
+ rl_vlc= rl->rl_vlc[0];
+ } else {
+ qmul = s->qscale << 1;
+ qadd = (s->qscale - 1) | 1;
+ i = -1;
+ rl = &ff_rl_table[3 + s->rl_table_index];
+
+ if(s->msmpeg4_version==2)
+ run_diff = 0;
+ else
+ run_diff = 1;
+
+ if (!coded) {
+ s->block_last_index[n] = i;
+ return 0;
+ }
+ if(!scan_table)
+ scan_table = s->inter_scantable.permutated;
+ rl_vlc= rl->rl_vlc[s->qscale];
+ }
+ {
+ OPEN_READER(re, &s->gb);
+ for(;;) {
+ UPDATE_CACHE(re, &s->gb);
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 0);
+ if (level==0) {
+ int cache;
+ cache= GET_CACHE(re, &s->gb);
+ /* escape */
+ if (s->msmpeg4_version==1 || (cache&0x80000000)==0) {
+ if (s->msmpeg4_version==1 || (cache&0x40000000)==0) {
+ /* third escape */
+ if(s->msmpeg4_version!=1) LAST_SKIP_BITS(re, &s->gb, 2);
+ UPDATE_CACHE(re, &s->gb);
+ if(s->msmpeg4_version<=3){
+ last= SHOW_UBITS(re, &s->gb, 1); SKIP_CACHE(re, &s->gb, 1);
+ run= SHOW_UBITS(re, &s->gb, 6); SKIP_CACHE(re, &s->gb, 6);
+ level= SHOW_SBITS(re, &s->gb, 8);
+ SKIP_COUNTER(re, &s->gb, 1+6+8);
+ }else{
+ int sign;
+ last= SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1);
+ if(!s->esc3_level_length){
+ int ll;
+ ff_dlog(s->avctx, "ESC-3 %X at %d %d\n",
+ show_bits(&s->gb, 24), s->mb_x, s->mb_y);
+ if(s->qscale<8){
+ ll= SHOW_UBITS(re, &s->gb, 3); SKIP_BITS(re, &s->gb, 3);
+ if(ll==0){
+ ll= 8+SHOW_UBITS(re, &s->gb, 1); SKIP_BITS(re, &s->gb, 1);
+ }
+ }else{
+ ll=2;
+ while(ll<8 && SHOW_UBITS(re, &s->gb, 1)==0){
+ ll++;
+ SKIP_BITS(re, &s->gb, 1);
+ }
+ if(ll<8) SKIP_BITS(re, &s->gb, 1);
+ }
+
+ s->esc3_level_length= ll;
+ s->esc3_run_length= SHOW_UBITS(re, &s->gb, 2) + 3; SKIP_BITS(re, &s->gb, 2);
+ UPDATE_CACHE(re, &s->gb);
+ }
+ run= SHOW_UBITS(re, &s->gb, s->esc3_run_length);
+ SKIP_BITS(re, &s->gb, s->esc3_run_length);
+
+ sign= SHOW_UBITS(re, &s->gb, 1);
+ SKIP_BITS(re, &s->gb, 1);
+
+ level= SHOW_UBITS(re, &s->gb, s->esc3_level_length);
+ SKIP_BITS(re, &s->gb, s->esc3_level_length);
+ if(sign) level= -level;
+ }
+
+#if 0 // waste of time / this will detect very few errors
+ {
+ const int abs_level= FFABS(level);
+ const int run1= run - rl->max_run[last][abs_level] - run_diff;
+ if(abs_level<=MAX_LEVEL && run<=MAX_RUN){
+ if(abs_level <= rl->max_level[last][run]){
+ av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, vlc encoding possible\n");
+ return DECODING_AC_LOST;
+ }
+ if(abs_level <= rl->max_level[last][run]*2){
+ av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 1 encoding possible\n");
+ return DECODING_AC_LOST;
+ }
+ if(run1>=0 && abs_level <= rl->max_level[last][run1]){
+ av_log(s->avctx, AV_LOG_ERROR, "illegal 3. esc, esc 2 encoding possible\n");
+ return DECODING_AC_LOST;
+ }
+ }
+ }
+#endif
+ //level = level * qmul + (level>0) * qadd - (level<=0) * qadd ;
+ if (level>0) level= level * qmul + qadd;
+ else level= level * qmul - qadd;
+#if 0 // waste of time too :(
+ if(level>2048 || level<-2048){
+ av_log(s->avctx, AV_LOG_ERROR, "|level| overflow in 3. esc\n");
+ return DECODING_AC_LOST;
+ }
+#endif
+ i+= run + 1;
+ if(last) i+=192;
+#ifdef ERROR_DETAILS
+ if(run==66)
+ av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC3 level=%d\n", level);
+ else if((i>62 && i<192) || i>192+63)
+ av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC3 i=%d run=%d level=%d\n", i, run, level);
+#endif
+ } else {
+ /* second escape */
+ SKIP_BITS(re, &s->gb, 2);
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
+ i+= run + rl->max_run[run>>7][level/qmul] + run_diff; //FIXME opt indexing
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+#ifdef ERROR_DETAILS
+ if(run==66)
+ av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC2 level=%d\n", level);
+ else if((i>62 && i<192) || i>192+63)
+ av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC2 i=%d run=%d level=%d\n", i, run, level);
+#endif
+ }
+ } else {
+ /* first escape */
+ SKIP_BITS(re, &s->gb, 1);
+ GET_RL_VLC(level, run, re, &s->gb, rl_vlc, TEX_VLC_BITS, 2, 1);
+ i+= run;
+ level = level + rl->max_level[run>>7][(run-1)&63] * qmul;//FIXME opt indexing
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+#ifdef ERROR_DETAILS
+ if(run==66)
+ av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code in ESC1 level=%d\n", level);
+ else if((i>62 && i<192) || i>192+63)
+ av_log(s->avctx, AV_LOG_ERROR, "run overflow in ESC1 i=%d run=%d level=%d\n", i, run, level);
+#endif
+ }
+ } else {
+ i+= run;
+ level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1);
+ LAST_SKIP_BITS(re, &s->gb, 1);
+#ifdef ERROR_DETAILS
+ if(run==66)
+ av_log(s->avctx, AV_LOG_ERROR, "illegal vlc code level=%d\n", level);
+ else if((i>62 && i<192) || i>192+63)
+ av_log(s->avctx, AV_LOG_ERROR, "run overflow i=%d run=%d level=%d\n", i, run, level);
+#endif
+ }
+ if (i > 62){
+ i-= 192;
+ if(i&(~63)){
+ const int left= get_bits_left(&s->gb);
+ if (((i + 192 == 64 && level / qmul == -1) ||
+ !(s->avctx->err_recognition & (AV_EF_BITSTREAM|AV_EF_COMPLIANT))) &&
+ left >= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "ignoring overflow at %d %d\n", s->mb_x, s->mb_y);
+ i = 63;
+ break;
+ }else{
+ av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ }
+
+ block[scan_table[i]] = level;
+ break;
+ }
+
+ block[scan_table[i]] = level;
+ }
+ CLOSE_READER(re, &s->gb);
+ }
+ not_coded:
+ if (s->mb_intra) {
+ ff_mpeg4_pred_ac(s, block, n, dc_pred_dir);
+ if (s->ac_pred) {
+ i = 63; /* XXX: not optimal */
+ }
+ }
+ if(s->msmpeg4_version>=4 && i>0) i=63; //FIXME/XXX optimize
+ s->block_last_index[n] = i;
+
+ return 0;
+}
+
+int ff_msmpeg4_decode_motion(MpegEncContext * s,
+ int *mx_ptr, int *my_ptr)
+{
+ MVTable *mv;
+ int code, mx, my;
+
+ mv = &ff_mv_tables[s->mv_table_index];
+
+ code = get_vlc2(&s->gb, mv->vlc.table, MV_VLC_BITS, 2);
+ if (code < 0){
+ av_log(s->avctx, AV_LOG_ERROR, "illegal MV code at %d %d\n", s->mb_x, s->mb_y);
+ return -1;
+ }
+ if (code == mv->n) {
+ mx = get_bits(&s->gb, 6);
+ my = get_bits(&s->gb, 6);
+ } else {
+ mx = mv->table_mvx[code];
+ my = mv->table_mvy[code];
+ }
+
+ mx += *mx_ptr - 32;
+ my += *my_ptr - 32;
+ /* WARNING : they do not do exactly modulo encoding */
+ if (mx <= -64)
+ mx += 64;
+ else if (mx >= 64)
+ mx -= 64;
+
+ if (my <= -64)
+ my += 64;
+ else if (my >= 64)
+ my -= 64;
+ *mx_ptr = mx;
+ *my_ptr = my;
+ return 0;
+}
+
+AVCodec ff_msmpeg4v1_decoder = {
+ .name = "msmpeg4v1",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 1"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MSMPEG4V1,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = ff_msmpeg4_decode_init,
+ .close = ff_h263_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
+ .max_lowres = 3,
+ .pix_fmts = (const enum AVPixelFormat[]) {
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_NONE
+ },
+};
+
+AVCodec ff_msmpeg4v2_decoder = {
+ .name = "msmpeg4v2",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 2"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MSMPEG4V2,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = ff_msmpeg4_decode_init,
+ .close = ff_h263_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
+ .max_lowres = 3,
+ .pix_fmts = (const enum AVPixelFormat[]) {
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_NONE
+ },
+};
+
+AVCodec ff_msmpeg4v3_decoder = {
+ .name = "msmpeg4",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 part 2 Microsoft variant version 3"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MSMPEG4V3,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = ff_msmpeg4_decode_init,
+ .close = ff_h263_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
+ .max_lowres = 3,
+ .pix_fmts = (const enum AVPixelFormat[]) {
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_NONE
+ },
+};
+
+AVCodec ff_wmv1_decoder = {
+ .name = "wmv1",
+ .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 7"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_WMV1,
+ .priv_data_size = sizeof(MpegEncContext),
+ .init = ff_msmpeg4_decode_init,
+ .close = ff_h263_decode_end,
+ .decode = ff_h263_decode_frame,
+ .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1,
+ .max_lowres = 3,
+ .pix_fmts = (const enum AVPixelFormat[]) {
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_NONE
+ },
+};
diff --git a/ffmpeg-2-8-11/libavcodec/msmpeg4enc.c b/ffmpeg-2-8-12/libavcodec/msmpeg4enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/msmpeg4enc.c
rename to ffmpeg-2-8-12/libavcodec/msmpeg4enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/msrle.c b/ffmpeg-2-8-12/libavcodec/msrle.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/msrle.c
rename to ffmpeg-2-8-12/libavcodec/msrle.c
diff --git a/ffmpeg-2-8-11/libavcodec/msrledec.c b/ffmpeg-2-8-12/libavcodec/msrledec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/msrledec.c
rename to ffmpeg-2-8-12/libavcodec/msrledec.c
diff --git a/ffmpeg-2-8-11/libavcodec/msrledec.h b/ffmpeg-2-8-12/libavcodec/msrledec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/msrledec.h
rename to ffmpeg-2-8-12/libavcodec/msrledec.h
diff --git a/ffmpeg-2-8-11/libavcodec/mss1.c b/ffmpeg-2-8-12/libavcodec/mss1.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mss1.c
rename to ffmpeg-2-8-12/libavcodec/mss1.c
diff --git a/ffmpeg-2-8-11/libavcodec/mss12.c b/ffmpeg-2-8-12/libavcodec/mss12.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mss12.c
rename to ffmpeg-2-8-12/libavcodec/mss12.c
diff --git a/ffmpeg-2-8-11/libavcodec/mss12.h b/ffmpeg-2-8-12/libavcodec/mss12.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mss12.h
rename to ffmpeg-2-8-12/libavcodec/mss12.h
diff --git a/ffmpeg-2-8-11/libavcodec/mss2.c b/ffmpeg-2-8-12/libavcodec/mss2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mss2.c
rename to ffmpeg-2-8-12/libavcodec/mss2.c
diff --git a/ffmpeg-2-8-11/libavcodec/mss2dsp.c b/ffmpeg-2-8-12/libavcodec/mss2dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mss2dsp.c
rename to ffmpeg-2-8-12/libavcodec/mss2dsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/mss2dsp.h b/ffmpeg-2-8-12/libavcodec/mss2dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mss2dsp.h
rename to ffmpeg-2-8-12/libavcodec/mss2dsp.h
diff --git a/ffmpeg-2-8-12/libavcodec/mss3.c b/ffmpeg-2-8-12/libavcodec/mss3.c
new file mode 100644
index 0000000..8344bfe
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/mss3.c
@@ -0,0 +1,874 @@
+/*
+ * Microsoft Screen 3 (aka Microsoft ATC Screen) decoder
+ * Copyright (c) 2012 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
+ */
+
+/**
+ * @file
+ * Microsoft Screen 3 (aka Microsoft ATC Screen) decoder
+ */
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+#include "mathops.h"
+#include "mss34dsp.h"
+
+#define HEADER_SIZE 27
+
+#define MODEL2_SCALE 13
+#define MODEL_SCALE 15
+#define MODEL256_SEC_SCALE 9
+
+typedef struct Model2 {
+ int upd_val, till_rescale;
+ unsigned zero_freq, zero_weight;
+ unsigned total_freq, total_weight;
+} Model2;
+
+typedef struct Model {
+ int weights[16], freqs[16];
+ int num_syms;
+ int tot_weight;
+ int upd_val, max_upd_val, till_rescale;
+} Model;
+
+typedef struct Model256 {
+ int weights[256], freqs[256];
+ int tot_weight;
+ int secondary[68];
+ int sec_size;
+ int upd_val, max_upd_val, till_rescale;
+} Model256;
+
+#define RAC_BOTTOM 0x01000000
+typedef struct RangeCoder {
+ const uint8_t *src, *src_end;
+
+ uint32_t range, low;
+ int got_error;
+} RangeCoder;
+
+enum BlockType {
+ FILL_BLOCK = 0,
+ IMAGE_BLOCK,
+ DCT_BLOCK,
+ HAAR_BLOCK,
+ SKIP_BLOCK
+};
+
+typedef struct BlockTypeContext {
+ int last_type;
+ Model bt_model[5];
+} BlockTypeContext;
+
+typedef struct FillBlockCoder {
+ int fill_val;
+ Model coef_model;
+} FillBlockCoder;
+
+typedef struct ImageBlockCoder {
+ Model256 esc_model, vec_entry_model;
+ Model vec_size_model;
+ Model vq_model[125];
+} ImageBlockCoder;
+
+typedef struct DCTBlockCoder {
+ int *prev_dc;
+ int prev_dc_stride;
+ int prev_dc_height;
+ int quality;
+ uint16_t qmat[64];
+ Model dc_model;
+ Model2 sign_model;
+ Model256 ac_model;
+} DCTBlockCoder;
+
+typedef struct HaarBlockCoder {
+ int quality, scale;
+ Model256 coef_model;
+ Model coef_hi_model;
+} HaarBlockCoder;
+
+typedef struct MSS3Context {
+ AVCodecContext *avctx;
+ AVFrame *pic;
+
+ int got_error;
+ RangeCoder coder;
+ BlockTypeContext btype[3];
+ FillBlockCoder fill_coder[3];
+ ImageBlockCoder image_coder[3];
+ DCTBlockCoder dct_coder[3];
+ HaarBlockCoder haar_coder[3];
+
+ int dctblock[64];
+ int hblock[16 * 16];
+} MSS3Context;
+
+
+static void model2_reset(Model2 *m)
+{
+ m->zero_weight = 1;
+ m->total_weight = 2;
+ m->zero_freq = 0x1000;
+ m->total_freq = 0x2000;
+ m->upd_val = 4;
+ m->till_rescale = 4;
+}
+
+static void model2_update(Model2 *m, int bit)
+{
+ unsigned scale;
+
+ if (!bit)
+ m->zero_weight++;
+ m->till_rescale--;
+ if (m->till_rescale)
+ return;
+
+ m->total_weight += m->upd_val;
+ if (m->total_weight > 0x2000) {
+ m->total_weight = (m->total_weight + 1) >> 1;
+ m->zero_weight = (m->zero_weight + 1) >> 1;
+ if (m->total_weight == m->zero_weight)
+ m->total_weight = m->zero_weight + 1;
+ }
+ m->upd_val = m->upd_val * 5 >> 2;
+ if (m->upd_val > 64)
+ m->upd_val = 64;
+ scale = 0x80000000u / m->total_weight;
+ m->zero_freq = m->zero_weight * scale >> 18;
+ m->total_freq = m->total_weight * scale >> 18;
+ m->till_rescale = m->upd_val;
+}
+
+static void model_update(Model *m, int val)
+{
+ int i, sum = 0;
+ unsigned scale;
+
+ m->weights[val]++;
+ m->till_rescale--;
+ if (m->till_rescale)
+ return;
+ m->tot_weight += m->upd_val;
+
+ if (m->tot_weight > 0x8000) {
+ m->tot_weight = 0;
+ for (i = 0; i < m->num_syms; i++) {
+ m->weights[i] = (m->weights[i] + 1) >> 1;
+ m->tot_weight += m->weights[i];
+ }
+ }
+ scale = 0x80000000u / m->tot_weight;
+ for (i = 0; i < m->num_syms; i++) {
+ m->freqs[i] = sum * scale >> 16;
+ sum += m->weights[i];
+ }
+
+ m->upd_val = m->upd_val * 5 >> 2;
+ if (m->upd_val > m->max_upd_val)
+ m->upd_val = m->max_upd_val;
+ m->till_rescale = m->upd_val;
+}
+
+static void model_reset(Model *m)
+{
+ int i;
+
+ m->tot_weight = 0;
+ for (i = 0; i < m->num_syms - 1; i++)
+ m->weights[i] = 1;
+ m->weights[m->num_syms - 1] = 0;
+
+ m->upd_val = m->num_syms;
+ m->till_rescale = 1;
+ model_update(m, m->num_syms - 1);
+ m->till_rescale =
+ m->upd_val = (m->num_syms + 6) >> 1;
+}
+
+static av_cold void model_init(Model *m, int num_syms)
+{
+ m->num_syms = num_syms;
+ m->max_upd_val = 8 * num_syms + 48;
+
+ model_reset(m);
+}
+
+static void model256_update(Model256 *m, int val)
+{
+ int i, sum = 0;
+ unsigned scale;
+ int send, sidx = 1;
+
+ m->weights[val]++;
+ m->till_rescale--;
+ if (m->till_rescale)
+ return;
+ m->tot_weight += m->upd_val;
+
+ if (m->tot_weight > 0x8000) {
+ m->tot_weight = 0;
+ for (i = 0; i < 256; i++) {
+ m->weights[i] = (m->weights[i] + 1) >> 1;
+ m->tot_weight += m->weights[i];
+ }
+ }
+ scale = 0x80000000u / m->tot_weight;
+ m->secondary[0] = 0;
+ for (i = 0; i < 256; i++) {
+ m->freqs[i] = sum * scale >> 16;
+ sum += m->weights[i];
+ send = m->freqs[i] >> MODEL256_SEC_SCALE;
+ while (sidx <= send)
+ m->secondary[sidx++] = i - 1;
+ }
+ while (sidx < m->sec_size)
+ m->secondary[sidx++] = 255;
+
+ m->upd_val = m->upd_val * 5 >> 2;
+ if (m->upd_val > m->max_upd_val)
+ m->upd_val = m->max_upd_val;
+ m->till_rescale = m->upd_val;
+}
+
+static void model256_reset(Model256 *m)
+{
+ int i;
+
+ for (i = 0; i < 255; i++)
+ m->weights[i] = 1;
+ m->weights[255] = 0;
+
+ m->tot_weight = 0;
+ m->upd_val = 256;
+ m->till_rescale = 1;
+ model256_update(m, 255);
+ m->till_rescale =
+ m->upd_val = (256 + 6) >> 1;
+}
+
+static av_cold void model256_init(Model256 *m)
+{
+ m->max_upd_val = 8 * 256 + 48;
+ m->sec_size = (1 << 6) + 2;
+
+ model256_reset(m);
+}
+
+static void rac_init(RangeCoder *c, const uint8_t *src, int size)
+{
+ int i;
+
+ c->src = src;
+ c->src_end = src + size;
+ c->low = 0;
+ for (i = 0; i < FFMIN(size, 4); i++)
+ c->low = (c->low << 8) | *c->src++;
+ c->range = 0xFFFFFFFF;
+ c->got_error = 0;
+}
+
+static void rac_normalise(RangeCoder *c)
+{
+ for (;;) {
+ c->range <<= 8;
+ c->low <<= 8;
+ if (c->src < c->src_end) {
+ c->low |= *c->src++;
+ } else if (!c->low) {
+ c->got_error = 1;
+ c->low = 1;
+ }
+ if (c->range >= RAC_BOTTOM)
+ return;
+ }
+}
+
+static int rac_get_bit(RangeCoder *c)
+{
+ int bit;
+
+ c->range >>= 1;
+
+ bit = (c->range <= c->low);
+ if (bit)
+ c->low -= c->range;
+
+ if (c->range < RAC_BOTTOM)
+ rac_normalise(c);
+
+ return bit;
+}
+
+static int rac_get_bits(RangeCoder *c, int nbits)
+{
+ int val;
+
+ c->range >>= nbits;
+ val = c->low / c->range;
+ c->low -= c->range * val;
+
+ if (c->range < RAC_BOTTOM)
+ rac_normalise(c);
+
+ return val;
+}
+
+static int rac_get_model2_sym(RangeCoder *c, Model2 *m)
+{
+ int bit, helper;
+
+ helper = m->zero_freq * (c->range >> MODEL2_SCALE);
+ bit = (c->low >= helper);
+ if (bit) {
+ c->low -= helper;
+ c->range -= helper;
+ } else {
+ c->range = helper;
+ }
+
+ if (c->range < RAC_BOTTOM)
+ rac_normalise(c);
+
+ model2_update(m, bit);
+
+ return bit;
+}
+
+static int rac_get_model_sym(RangeCoder *c, Model *m)
+{
+ int val;
+ int end, end2;
+ unsigned prob, prob2, helper;
+
+ prob = 0;
+ prob2 = c->range;
+ c->range >>= MODEL_SCALE;
+ val = 0;
+ end = m->num_syms >> 1;
+ end2 = m->num_syms;
+ do {
+ helper = m->freqs[end] * c->range;
+ if (helper <= c->low) {
+ val = end;
+ prob = helper;
+ } else {
+ end2 = end;
+ prob2 = helper;
+ }
+ end = (end2 + val) >> 1;
+ } while (end != val);
+ c->low -= prob;
+ c->range = prob2 - prob;
+ if (c->range < RAC_BOTTOM)
+ rac_normalise(c);
+
+ model_update(m, val);
+
+ return val;
+}
+
+static int rac_get_model256_sym(RangeCoder *c, Model256 *m)
+{
+ int prob, prob2, helper, val;
+ int start, end;
+ int ssym;
+
+ prob2 = c->range;
+ c->range >>= MODEL_SCALE;
+
+ helper = c->low / c->range;
+ ssym = helper >> MODEL256_SEC_SCALE;
+ val = m->secondary[ssym];
+
+ end = start = m->secondary[ssym + 1] + 1;
+ while (end > val + 1) {
+ ssym = (end + val) >> 1;
+ if (m->freqs[ssym] <= helper) {
+ end = start;
+ val = ssym;
+ } else {
+ end = (end + val) >> 1;
+ start = ssym;
+ }
+ }
+ prob = m->freqs[val] * c->range;
+ if (val != 255)
+ prob2 = m->freqs[val + 1] * c->range;
+
+ c->low -= prob;
+ c->range = prob2 - prob;
+ if (c->range < RAC_BOTTOM)
+ rac_normalise(c);
+
+ model256_update(m, val);
+
+ return val;
+}
+
+static int decode_block_type(RangeCoder *c, BlockTypeContext *bt)
+{
+ bt->last_type = rac_get_model_sym(c, &bt->bt_model[bt->last_type]);
+
+ return bt->last_type;
+}
+
+static int decode_coeff(RangeCoder *c, Model *m)
+{
+ int val, sign;
+
+ val = rac_get_model_sym(c, m);
+ if (val) {
+ sign = rac_get_bit(c);
+ if (val > 1) {
+ val--;
+ val = (1 << val) + rac_get_bits(c, val);
+ }
+ if (!sign)
+ val = -val;
+ }
+
+ return val;
+}
+
+static void decode_fill_block(RangeCoder *c, FillBlockCoder *fc,
+ uint8_t *dst, int stride, int block_size)
+{
+ int i;
+
+ fc->fill_val += decode_coeff(c, &fc->coef_model);
+
+ for (i = 0; i < block_size; i++, dst += stride)
+ memset(dst, fc->fill_val, block_size);
+}
+
+static void decode_image_block(RangeCoder *c, ImageBlockCoder *ic,
+ uint8_t *dst, int stride, int block_size)
+{
+ int i, j;
+ int vec_size;
+ int vec[4];
+ int prev_line[16];
+ int A, B, C;
+
+ vec_size = rac_get_model_sym(c, &ic->vec_size_model) + 2;
+ for (i = 0; i < vec_size; i++)
+ vec[i] = rac_get_model256_sym(c, &ic->vec_entry_model);
+ for (; i < 4; i++)
+ vec[i] = 0;
+ memset(prev_line, 0, sizeof(prev_line));
+
+ for (j = 0; j < block_size; j++) {
+ A = 0;
+ B = 0;
+ for (i = 0; i < block_size; i++) {
+ C = B;
+ B = prev_line[i];
+ A = rac_get_model_sym(c, &ic->vq_model[A + B * 5 + C * 25]);
+
+ prev_line[i] = A;
+ if (A < 4)
+ dst[i] = vec[A];
+ else
+ dst[i] = rac_get_model256_sym(c, &ic->esc_model);
+ }
+ dst += stride;
+ }
+}
+
+static int decode_dct(RangeCoder *c, DCTBlockCoder *bc, int *block,
+ int bx, int by)
+{
+ int skip, val, sign, pos = 1, zz_pos, dc;
+ int blk_pos = bx + by * bc->prev_dc_stride;
+
+ memset(block, 0, sizeof(*block) * 64);
+
+ dc = decode_coeff(c, &bc->dc_model);
+ if (by) {
+ if (bx) {
+ int l, tl, t;
+
+ l = bc->prev_dc[blk_pos - 1];
+ tl = bc->prev_dc[blk_pos - 1 - bc->prev_dc_stride];
+ t = bc->prev_dc[blk_pos - bc->prev_dc_stride];
+
+ if (FFABS(t - tl) <= FFABS(l - tl))
+ dc += l;
+ else
+ dc += t;
+ } else {
+ dc += bc->prev_dc[blk_pos - bc->prev_dc_stride];
+ }
+ } else if (bx) {
+ dc += bc->prev_dc[bx - 1];
+ }
+ bc->prev_dc[blk_pos] = dc;
+ block[0] = dc * bc->qmat[0];
+
+ while (pos < 64) {
+ val = rac_get_model256_sym(c, &bc->ac_model);
+ if (!val)
+ return 0;
+ if (val == 0xF0) {
+ pos += 16;
+ continue;
+ }
+ skip = val >> 4;
+ val = val & 0xF;
+ if (!val)
+ return -1;
+ pos += skip;
+ if (pos >= 64)
+ return -1;
+
+ sign = rac_get_model2_sym(c, &bc->sign_model);
+ if (val > 1) {
+ val--;
+ val = (1 << val) + rac_get_bits(c, val);
+ }
+ if (!sign)
+ val = -val;
+
+ zz_pos = ff_zigzag_direct[pos];
+ block[zz_pos] = val * bc->qmat[zz_pos];
+ pos++;
+ }
+
+ return pos == 64 ? 0 : -1;
+}
+
+static void decode_dct_block(RangeCoder *c, DCTBlockCoder *bc,
+ uint8_t *dst, int stride, int block_size,
+ int *block, int mb_x, int mb_y)
+{
+ int i, j;
+ int bx, by;
+ int nblocks = block_size >> 3;
+
+ bx = mb_x * nblocks;
+ by = mb_y * nblocks;
+
+ for (j = 0; j < nblocks; j++) {
+ for (i = 0; i < nblocks; i++) {
+ if (decode_dct(c, bc, block, bx + i, by + j)) {
+ c->got_error = 1;
+ return;
+ }
+ ff_mss34_dct_put(dst + i * 8, stride, block);
+ }
+ dst += 8 * stride;
+ }
+}
+
+static void decode_haar_block(RangeCoder *c, HaarBlockCoder *hc,
+ uint8_t *dst, int stride, int block_size,
+ int *block)
+{
+ const int hsize = block_size >> 1;
+ int A, B, C, D, t1, t2, t3, t4;
+ int i, j;
+
+ for (j = 0; j < block_size; j++) {
+ for (i = 0; i < block_size; i++) {
+ if (i < hsize && j < hsize)
+ block[i] = rac_get_model256_sym(c, &hc->coef_model);
+ else
+ block[i] = decode_coeff(c, &hc->coef_hi_model);
+ block[i] *= hc->scale;
+ }
+ block += block_size;
+ }
+ block -= block_size * block_size;
+
+ for (j = 0; j < hsize; j++) {
+ for (i = 0; i < hsize; i++) {
+ A = block[i];
+ B = block[i + hsize];
+ C = block[i + hsize * block_size];
+ D = block[i + hsize * block_size + hsize];
+
+ t1 = A - B;
+ t2 = C - D;
+ t3 = A + B;
+ t4 = C + D;
+ dst[i * 2] = av_clip_uint8(t1 - t2);
+ dst[i * 2 + stride] = av_clip_uint8(t1 + t2);
+ dst[i * 2 + 1] = av_clip_uint8(t3 - t4);
+ dst[i * 2 + 1 + stride] = av_clip_uint8(t3 + t4);
+ }
+ block += block_size;
+ dst += stride * 2;
+ }
+}
+
+static void reset_coders(MSS3Context *ctx, int quality)
+{
+ int i, j;
+
+ for (i = 0; i < 3; i++) {
+ ctx->btype[i].last_type = SKIP_BLOCK;
+ for (j = 0; j < 5; j++)
+ model_reset(&ctx->btype[i].bt_model[j]);
+ ctx->fill_coder[i].fill_val = 0;
+ model_reset(&ctx->fill_coder[i].coef_model);
+ model256_reset(&ctx->image_coder[i].esc_model);
+ model256_reset(&ctx->image_coder[i].vec_entry_model);
+ model_reset(&ctx->image_coder[i].vec_size_model);
+ for (j = 0; j < 125; j++)
+ model_reset(&ctx->image_coder[i].vq_model[j]);
+ if (ctx->dct_coder[i].quality != quality) {
+ ctx->dct_coder[i].quality = quality;
+ ff_mss34_gen_quant_mat(ctx->dct_coder[i].qmat, quality, !i);
+ }
+ memset(ctx->dct_coder[i].prev_dc, 0,
+ sizeof(*ctx->dct_coder[i].prev_dc) *
+ ctx->dct_coder[i].prev_dc_stride *
+ ctx->dct_coder[i].prev_dc_height);
+ model_reset(&ctx->dct_coder[i].dc_model);
+ model2_reset(&ctx->dct_coder[i].sign_model);
+ model256_reset(&ctx->dct_coder[i].ac_model);
+ if (ctx->haar_coder[i].quality != quality) {
+ ctx->haar_coder[i].quality = quality;
+ ctx->haar_coder[i].scale = 17 - 7 * quality / 50;
+ }
+ model_reset(&ctx->haar_coder[i].coef_hi_model);
+ model256_reset(&ctx->haar_coder[i].coef_model);
+ }
+}
+
+static av_cold void init_coders(MSS3Context *ctx)
+{
+ int i, j;
+
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 5; j++)
+ model_init(&ctx->btype[i].bt_model[j], 5);
+ model_init(&ctx->fill_coder[i].coef_model, 12);
+ model256_init(&ctx->image_coder[i].esc_model);
+ model256_init(&ctx->image_coder[i].vec_entry_model);
+ model_init(&ctx->image_coder[i].vec_size_model, 3);
+ for (j = 0; j < 125; j++)
+ model_init(&ctx->image_coder[i].vq_model[j], 5);
+ model_init(&ctx->dct_coder[i].dc_model, 12);
+ model256_init(&ctx->dct_coder[i].ac_model);
+ model_init(&ctx->haar_coder[i].coef_hi_model, 12);
+ model256_init(&ctx->haar_coder[i].coef_model);
+ }
+}
+
+static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ MSS3Context *c = avctx->priv_data;
+ RangeCoder *acoder = &c->coder;
+ GetByteContext gb;
+ uint8_t *dst[3];
+ int dec_width, dec_height, dec_x, dec_y, quality, keyframe;
+ int x, y, i, mb_width, mb_height, blk_size, btype;
+ int ret;
+
+ if (buf_size < HEADER_SIZE) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Frame should have at least %d bytes, got %d instead\n",
+ HEADER_SIZE, buf_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ bytestream2_init(&gb, buf, buf_size);
+ keyframe = bytestream2_get_be32(&gb);
+ if (keyframe & ~0x301) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid frame type %X\n", keyframe);
+ return AVERROR_INVALIDDATA;
+ }
+ keyframe = !(keyframe & 1);
+ bytestream2_skip(&gb, 6);
+ dec_x = bytestream2_get_be16(&gb);
+ dec_y = bytestream2_get_be16(&gb);
+ dec_width = bytestream2_get_be16(&gb);
+ dec_height = bytestream2_get_be16(&gb);
+
+ if (dec_x + dec_width > avctx->width ||
+ dec_y + dec_height > avctx->height ||
+ (dec_width | dec_height) & 0xF) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d +%d,%d\n",
+ dec_width, dec_height, dec_x, dec_y);
+ return AVERROR_INVALIDDATA;
+ }
+ bytestream2_skip(&gb, 4);
+ quality = bytestream2_get_byte(&gb);
+ if (quality < 1 || quality > 100) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid quality setting %d\n", quality);
+ return AVERROR_INVALIDDATA;
+ }
+ bytestream2_skip(&gb, 4);
+
+ if (keyframe && !bytestream2_get_bytes_left(&gb)) {
+ av_log(avctx, AV_LOG_ERROR, "Keyframe without data found\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (!keyframe && c->got_error)
+ return buf_size;
+ c->got_error = 0;
+
+ if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)
+ return ret;
+ c->pic->key_frame = keyframe;
+ c->pic->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+ if (!bytestream2_get_bytes_left(&gb)) {
+ if ((ret = av_frame_ref(data, c->pic)) < 0)
+ return ret;
+ *got_frame = 1;
+
+ return buf_size;
+ }
+
+ reset_coders(c, quality);
+
+ rac_init(acoder, buf + HEADER_SIZE, buf_size - HEADER_SIZE);
+
+ mb_width = dec_width >> 4;
+ mb_height = dec_height >> 4;
+ dst[0] = c->pic->data[0] + dec_x + dec_y * c->pic->linesize[0];
+ dst[1] = c->pic->data[1] + dec_x / 2 + (dec_y / 2) * c->pic->linesize[1];
+ dst[2] = c->pic->data[2] + dec_x / 2 + (dec_y / 2) * c->pic->linesize[2];
+ for (y = 0; y < mb_height; y++) {
+ for (x = 0; x < mb_width; x++) {
+ for (i = 0; i < 3; i++) {
+ blk_size = 8 << !i;
+
+ btype = decode_block_type(acoder, c->btype + i);
+ switch (btype) {
+ case FILL_BLOCK:
+ decode_fill_block(acoder, c->fill_coder + i,
+ dst[i] + x * blk_size,
+ c->pic->linesize[i], blk_size);
+ break;
+ case IMAGE_BLOCK:
+ decode_image_block(acoder, c->image_coder + i,
+ dst[i] + x * blk_size,
+ c->pic->linesize[i], blk_size);
+ break;
+ case DCT_BLOCK:
+ decode_dct_block(acoder, c->dct_coder + i,
+ dst[i] + x * blk_size,
+ c->pic->linesize[i], blk_size,
+ c->dctblock, x, y);
+ break;
+ case HAAR_BLOCK:
+ decode_haar_block(acoder, c->haar_coder + i,
+ dst[i] + x * blk_size,
+ c->pic->linesize[i], blk_size,
+ c->hblock);
+ break;
+ }
+ if (c->got_error || acoder->got_error) {
+ av_log(avctx, AV_LOG_ERROR, "Error decoding block %d,%d\n",
+ x, y);
+ c->got_error = 1;
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ }
+ dst[0] += c->pic->linesize[0] * 16;
+ dst[1] += c->pic->linesize[1] * 8;
+ dst[2] += c->pic->linesize[2] * 8;
+ }
+
+ if ((ret = av_frame_ref(data, c->pic)) < 0)
+ return ret;
+
+ *got_frame = 1;
+
+ return buf_size;
+}
+
+static av_cold int mss3_decode_end(AVCodecContext *avctx)
+{
+ MSS3Context * const c = avctx->priv_data;
+ int i;
+
+ av_frame_free(&c->pic);
+ for (i = 0; i < 3; i++)
+ av_freep(&c->dct_coder[i].prev_dc);
+
+ return 0;
+}
+
+static av_cold int mss3_decode_init(AVCodecContext *avctx)
+{
+ MSS3Context * const c = avctx->priv_data;
+ int i;
+
+ c->avctx = avctx;
+
+ if ((avctx->width & 0xF) || (avctx->height & 0xF)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Image dimensions should be a multiple of 16.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ c->got_error = 0;
+ for (i = 0; i < 3; i++) {
+ int b_width = avctx->width >> (2 + !!i);
+ int b_height = avctx->height >> (2 + !!i);
+ c->dct_coder[i].prev_dc_stride = b_width;
+ c->dct_coder[i].prev_dc_height = b_height;
+ c->dct_coder[i].prev_dc = av_malloc(sizeof(*c->dct_coder[i].prev_dc) *
+ 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);
+ return AVERROR(ENOMEM);
+ }
+
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+ init_coders(c);
+
+ return 0;
+}
+
+AVCodec ff_msa1_decoder = {
+ .name = "msa1",
+ .long_name = NULL_IF_CONFIG_SMALL("MS ATC Screen"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MSA1,
+ .priv_data_size = sizeof(MSS3Context),
+ .init = mss3_decode_init,
+ .close = mss3_decode_end,
+ .decode = mss3_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-12/libavcodec/mss34dsp.c b/ffmpeg-2-8-12/libavcodec/mss34dsp.c
new file mode 100644
index 0000000..4965ac5
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/mss34dsp.c
@@ -0,0 +1,114 @@
+/*
+ * Common stuff for some Microsoft Screen codecs
+ * Copyright (C) 2012 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 <stdint.h>
+#include "libavutil/common.h"
+#include "mss34dsp.h"
+
+static const uint8_t luma_quant[64] = {
+ 16, 11, 10, 16, 24, 40, 51, 61,
+ 12, 12, 14, 19, 26, 58, 60, 55,
+ 14, 13, 16, 24, 40, 57, 69, 56,
+ 14, 17, 22, 29, 51, 87, 80, 62,
+ 18, 22, 37, 56, 68, 109, 103, 77,
+ 24, 35, 55, 64, 81, 104, 113, 92,
+ 49, 64, 78, 87, 103, 121, 120, 101,
+ 72, 92, 95, 98, 112, 100, 103, 99
+};
+
+static const uint8_t chroma_quant[64] = {
+ 17, 18, 24, 47, 99, 99, 99, 99,
+ 18, 21, 26, 66, 99, 99, 99, 99,
+ 24, 26, 56, 99, 99, 99, 99, 99,
+ 47, 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
+};
+
+void ff_mss34_gen_quant_mat(uint16_t *qmat, int quality, int luma)
+{
+ int i;
+ const uint8_t *qsrc = luma ? luma_quant : chroma_quant;
+
+ if (quality >= 50) {
+ int scale = 200 - 2 * quality;
+
+ for (i = 0; i < 64; i++)
+ qmat[i] = (qsrc[i] * scale + 50) / 100;
+ } else {
+ for (i = 0; i < 64; i++)
+ qmat[i] = (5000 * qsrc[i] / quality + 50) / 100;
+ }
+}
+
+#define DCT_TEMPLATE(blk, step, SOP, shift) \
+ const unsigned t0 =-39409U * blk[7 * step] - 58980U * blk[1 * step]; \
+ const unsigned t1 = 39410U * blk[1 * step] - 58980U * blk[7 * step]; \
+ const unsigned t2 =-33410U * blk[5 * step] -167963U * blk[3 * step]; \
+ const unsigned t3 = 33410U * blk[3 * step] -167963U * blk[5 * step]; \
+ const unsigned t4 = blk[3 * step] + blk[7 * step]; \
+ const unsigned t5 = blk[1 * step] + blk[5 * step]; \
+ const unsigned t6 = 77062U * t4 + 51491U * t5; \
+ const unsigned t7 = 77062U * t5 - 51491U * t4; \
+ const unsigned t8 = 35470U * blk[2 * step] - 85623U * blk[6 * step]; \
+ const unsigned t9 = 35470U * blk[6 * step] + 85623U * blk[2 * step]; \
+ const unsigned tA = SOP(blk[0 * step] - blk[4 * step]); \
+ const unsigned tB = SOP(blk[0 * step] + blk[4 * step]); \
+ \
+ blk[0 * step] = (int)( t1 + t6 + t9 + tB) >> shift; \
+ blk[1 * step] = (int)( t3 + t7 + t8 + tA) >> shift; \
+ blk[2 * step] = (int)( t2 + t6 - t8 + tA) >> shift; \
+ blk[3 * step] = (int)( t0 + t7 - t9 + tB) >> shift; \
+ blk[4 * step] = (int)(-(t0 + t7) - t9 + tB) >> shift; \
+ blk[5 * step] = (int)(-(t2 + t6) - t8 + tA) >> shift; \
+ blk[6 * step] = (int)(-(t3 + t7) + t8 + tA) >> shift; \
+ blk[7 * step] = (int)(-(t1 + t6) + t9 + tB) >> shift; \
+
+#define SOP_ROW(a) (((a) * (1U << 16)) + 0x2000)
+#define SOP_COL(a) (((a) + 32) * (1U << 16))
+
+void ff_mss34_dct_put(uint8_t *dst, int stride, int *block)
+{
+ int i, j;
+ int *ptr;
+
+ ptr = block;
+ for (i = 0; i < 8; i++) {
+ DCT_TEMPLATE(ptr, 1, SOP_ROW, 13);
+ ptr += 8;
+ }
+
+ ptr = block;
+ for (i = 0; i < 8; i++) {
+ DCT_TEMPLATE(ptr, 8, SOP_COL, 22);
+ ptr++;
+ }
+
+ ptr = block;
+ for (j = 0; j < 8; j++) {
+ for (i = 0; i < 8; i++)
+ dst[i] = av_clip_uint8(ptr[i] + 128);
+ dst += stride;
+ ptr += 8;
+ }
+}
diff --git a/ffmpeg-2-8-11/libavcodec/mss34dsp.h b/ffmpeg-2-8-12/libavcodec/mss34dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mss34dsp.h
rename to ffmpeg-2-8-12/libavcodec/mss34dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/mss4.c b/ffmpeg-2-8-12/libavcodec/mss4.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mss4.c
rename to ffmpeg-2-8-12/libavcodec/mss4.c
diff --git a/ffmpeg-2-8-12/libavcodec/msvideo1.c b/ffmpeg-2-8-12/libavcodec/msvideo1.c
new file mode 100644
index 0000000..c53ca82
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/msvideo1.c
@@ -0,0 +1,359 @@
+/*
+ * Microsoft Video-1 Decoder
+ * Copyright (c) 2003 The FFmpeg Project
+ *
+ * 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 Video-1 Decoder by Mike Melanson (melanson at pcisys.net)
+ * For more information about the MS Video-1 format, visit:
+ * http://www.pcisys.net/~melanson/codecs/
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "internal.h"
+
+#define PALETTE_COUNT 256
+#define CHECK_STREAM_PTR(n) \
+ if ((stream_ptr + n) > s->size ) { \
+ av_log(s->avctx, AV_LOG_ERROR, " MS Video-1 warning: stream_ptr out of bounds (%d >= %d)\n", \
+ stream_ptr + n, s->size); \
+ return; \
+ }
+
+typedef struct Msvideo1Context {
+
+ AVCodecContext *avctx;
+ AVFrame *frame;
+
+ const unsigned char *buf;
+ int size;
+
+ int mode_8bit; /* if it's not 8-bit, it's 16-bit */
+
+ uint32_t pal[256];
+} Msvideo1Context;
+
+static av_cold int msvideo1_decode_init(AVCodecContext *avctx)
+{
+ Msvideo1Context *s = avctx->priv_data;
+
+ s->avctx = avctx;
+
+ /* figure out the colorspace based on the presence of a palette */
+ if (s->avctx->bits_per_coded_sample == 8) {
+ s->mode_8bit = 1;
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ if (avctx->extradata_size >= AVPALETTE_SIZE)
+ memcpy(s->pal, avctx->extradata, AVPALETTE_SIZE);
+ } else {
+ s->mode_8bit = 0;
+ avctx->pix_fmt = AV_PIX_FMT_RGB555;
+ }
+
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static void msvideo1_decode_8bit(Msvideo1Context *s)
+{
+ int block_ptr, pixel_ptr;
+ int total_blocks;
+ int pixel_x, pixel_y; /* pixel width and height iterators */
+ int block_x, block_y; /* block width and height iterators */
+ int blocks_wide, blocks_high; /* width and height in 4x4 blocks */
+ int block_inc;
+ int row_dec;
+
+ /* decoding parameters */
+ int stream_ptr;
+ unsigned char byte_a, byte_b;
+ unsigned short flags;
+ int skip_blocks;
+ unsigned char colors[8];
+ unsigned char *pixels = s->frame->data[0];
+ int stride = s->frame->linesize[0];
+
+ stream_ptr = 0;
+ skip_blocks = 0;
+ blocks_wide = s->avctx->width / 4;
+ blocks_high = s->avctx->height / 4;
+ total_blocks = blocks_wide * blocks_high;
+ block_inc = 4;
+ row_dec = stride + 4;
+
+ for (block_y = blocks_high; block_y > 0; block_y--) {
+ block_ptr = ((block_y * 4) - 1) * stride;
+ for (block_x = blocks_wide; block_x > 0; block_x--) {
+ /* check if this block should be skipped */
+ if (skip_blocks) {
+ block_ptr += block_inc;
+ skip_blocks--;
+ total_blocks--;
+ continue;
+ }
+
+ pixel_ptr = block_ptr;
+
+ /* get the next two bytes in the encoded data stream */
+ CHECK_STREAM_PTR(2);
+ byte_a = s->buf[stream_ptr++];
+ byte_b = s->buf[stream_ptr++];
+
+ /* check if the decode is finished */
+ if ((byte_a == 0) && (byte_b == 0) && (total_blocks == 0))
+ return;
+ else if ((byte_b & 0xFC) == 0x84) {
+ /* skip code, but don't count the current block */
+ skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1;
+ } else if (byte_b < 0x80) {
+ /* 2-color encoding */
+ flags = (byte_b << 8) | byte_a;
+
+ CHECK_STREAM_PTR(2);
+ colors[0] = s->buf[stream_ptr++];
+ colors[1] = s->buf[stream_ptr++];
+
+ for (pixel_y = 0; pixel_y < 4; pixel_y++) {
+ for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
+ pixels[pixel_ptr++] = colors[(flags & 0x1) ^ 1];
+ pixel_ptr -= row_dec;
+ }
+ } else if (byte_b >= 0x90) {
+ /* 8-color encoding */
+ flags = (byte_b << 8) | byte_a;
+
+ CHECK_STREAM_PTR(8);
+ memcpy(colors, &s->buf[stream_ptr], 8);
+ stream_ptr += 8;
+
+ for (pixel_y = 0; pixel_y < 4; pixel_y++) {
+ for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
+ pixels[pixel_ptr++] =
+ colors[((pixel_y & 0x2) << 1) +
+ (pixel_x & 0x2) + ((flags & 0x1) ^ 1)];
+ pixel_ptr -= row_dec;
+ }
+ } else {
+ /* 1-color encoding */
+ colors[0] = byte_a;
+
+ for (pixel_y = 0; pixel_y < 4; pixel_y++) {
+ for (pixel_x = 0; pixel_x < 4; pixel_x++)
+ pixels[pixel_ptr++] = colors[0];
+ pixel_ptr -= row_dec;
+ }
+ }
+
+ block_ptr += block_inc;
+ total_blocks--;
+ }
+ }
+
+ /* make the palette available on the way out */
+ if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
+ memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);
+}
+
+static void msvideo1_decode_16bit(Msvideo1Context *s)
+{
+ int block_ptr, pixel_ptr;
+ int total_blocks;
+ int pixel_x, pixel_y; /* pixel width and height iterators */
+ int block_x, block_y; /* block width and height iterators */
+ int blocks_wide, blocks_high; /* width and height in 4x4 blocks */
+ int block_inc;
+ int row_dec;
+
+ /* decoding parameters */
+ int stream_ptr;
+ unsigned char byte_a, byte_b;
+ unsigned short flags;
+ int skip_blocks;
+ unsigned short colors[8];
+ unsigned short *pixels = (unsigned short *)s->frame->data[0];
+ int stride = s->frame->linesize[0] / 2;
+
+ stream_ptr = 0;
+ skip_blocks = 0;
+ blocks_wide = s->avctx->width / 4;
+ blocks_high = s->avctx->height / 4;
+ total_blocks = blocks_wide * blocks_high;
+ block_inc = 4;
+ row_dec = stride + 4;
+
+ for (block_y = blocks_high; block_y > 0; block_y--) {
+ block_ptr = ((block_y * 4) - 1) * stride;
+ for (block_x = blocks_wide; block_x > 0; block_x--) {
+ /* check if this block should be skipped */
+ if (skip_blocks) {
+ block_ptr += block_inc;
+ skip_blocks--;
+ total_blocks--;
+ continue;
+ }
+
+ pixel_ptr = block_ptr;
+
+ /* get the next two bytes in the encoded data stream */
+ CHECK_STREAM_PTR(2);
+ byte_a = s->buf[stream_ptr++];
+ byte_b = s->buf[stream_ptr++];
+
+ /* check if the decode is finished */
+ if ((byte_a == 0) && (byte_b == 0) && (total_blocks == 0)) {
+ return;
+ } else if ((byte_b & 0xFC) == 0x84) {
+ /* skip code, but don't count the current block */
+ skip_blocks = ((byte_b - 0x84) << 8) + byte_a - 1;
+ } else if (byte_b < 0x80) {
+ /* 2- or 8-color encoding modes */
+ flags = (byte_b << 8) | byte_a;
+
+ CHECK_STREAM_PTR(4);
+ colors[0] = AV_RL16(&s->buf[stream_ptr]);
+ stream_ptr += 2;
+ colors[1] = AV_RL16(&s->buf[stream_ptr]);
+ stream_ptr += 2;
+
+ if (colors[0] & 0x8000) {
+ /* 8-color encoding */
+ CHECK_STREAM_PTR(12);
+ colors[2] = AV_RL16(&s->buf[stream_ptr]);
+ stream_ptr += 2;
+ colors[3] = AV_RL16(&s->buf[stream_ptr]);
+ stream_ptr += 2;
+ colors[4] = AV_RL16(&s->buf[stream_ptr]);
+ stream_ptr += 2;
+ colors[5] = AV_RL16(&s->buf[stream_ptr]);
+ stream_ptr += 2;
+ colors[6] = AV_RL16(&s->buf[stream_ptr]);
+ stream_ptr += 2;
+ colors[7] = AV_RL16(&s->buf[stream_ptr]);
+ stream_ptr += 2;
+
+ for (pixel_y = 0; pixel_y < 4; pixel_y++) {
+ for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
+ pixels[pixel_ptr++] =
+ colors[((pixel_y & 0x2) << 1) +
+ (pixel_x & 0x2) + ((flags & 0x1) ^ 1)];
+ pixel_ptr -= row_dec;
+ }
+ } else {
+ /* 2-color encoding */
+ for (pixel_y = 0; pixel_y < 4; pixel_y++) {
+ for (pixel_x = 0; pixel_x < 4; pixel_x++, flags >>= 1)
+ pixels[pixel_ptr++] = colors[(flags & 0x1) ^ 1];
+ pixel_ptr -= row_dec;
+ }
+ }
+ } else {
+ /* otherwise, it's a 1-color block */
+ colors[0] = (byte_b << 8) | byte_a;
+
+ for (pixel_y = 0; pixel_y < 4; pixel_y++) {
+ for (pixel_x = 0; pixel_x < 4; pixel_x++)
+ pixels[pixel_ptr++] = colors[0];
+ pixel_ptr -= row_dec;
+ }
+ }
+
+ block_ptr += block_inc;
+ total_blocks--;
+ }
+ }
+}
+
+static int msvideo1_decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ Msvideo1Context *s = avctx->priv_data;
+ int ret;
+
+ s->buf = buf;
+ s->size = buf_size;
+
+ // Discard frame if its smaller than the minimum frame size
+ if (buf_size < (avctx->width/4) * (avctx->height/4) / 512) {
+ av_log(avctx, AV_LOG_ERROR, "Packet is too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
+ return ret;
+
+ if (s->mode_8bit) {
+ int size;
+ const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, &size);
+
+ if (pal && size == AVPALETTE_SIZE) {
+ memcpy(s->pal, pal, AVPALETTE_SIZE);
+ s->frame->palette_has_changed = 1;
+ } else if (pal) {
+ av_log(avctx, AV_LOG_ERROR, "Palette size %d is wrong\n", size);
+ }
+ }
+
+ if (s->mode_8bit)
+ msvideo1_decode_8bit(s);
+ else
+ msvideo1_decode_16bit(s);
+
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
+ return ret;
+
+ *got_frame = 1;
+
+ /* report that the buffer was completely consumed */
+ return buf_size;
+}
+
+static av_cold int msvideo1_decode_end(AVCodecContext *avctx)
+{
+ Msvideo1Context *s = avctx->priv_data;
+
+ av_frame_free(&s->frame);
+
+ return 0;
+}
+
+AVCodec ff_msvideo1_decoder = {
+ .name = "msvideo1",
+ .long_name = NULL_IF_CONFIG_SMALL("Microsoft Video 1"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_MSVIDEO1,
+ .priv_data_size = sizeof(Msvideo1Context),
+ .init = msvideo1_decode_init,
+ .close = msvideo1_decode_end,
+ .decode = msvideo1_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/msvideo1enc.c b/ffmpeg-2-8-12/libavcodec/msvideo1enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/msvideo1enc.c
rename to ffmpeg-2-8-12/libavcodec/msvideo1enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/mvcdec.c b/ffmpeg-2-8-12/libavcodec/mvcdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mvcdec.c
rename to ffmpeg-2-8-12/libavcodec/mvcdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/mxpegdec.c b/ffmpeg-2-8-12/libavcodec/mxpegdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/mxpegdec.c
rename to ffmpeg-2-8-12/libavcodec/mxpegdec.c
diff --git a/ffmpeg-2-8-12/libavcodec/nellymoser.c b/ffmpeg-2-8-12/libavcodec/nellymoser.c
new file mode 100644
index 0000000..d6d5b7a
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/nellymoser.c
@@ -0,0 +1,224 @@
+/*
+ * Common code between Nellymoser encoder and decoder
+ * Copyright (c) 2007 a840bda5870ba11f19698ff6eb9581dfb0f95fa5,
+ * 539459aeb7d425140b62a3ec7dbf6dc8e408a306, and
+ * 520e17cd55896441042b14df2566a6eb610ed444
+ * Copyright (c) 2007 Loic Minier <lool at dooz.org>
+ * Benjamin Larsson
+ *
+ * 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.
+ */
+
+/**
+ * @file
+ * The 3 alphanumeric copyright notices are md5summed they are from the original
+ * implementors. The original code is available from http://code.google.com/p/nelly2pcm/
+ */
+
+#include "nellymoser.h"
+#include "avcodec.h"
+
+#define BITSTREAM_READER_LE
+#include "get_bits.h"
+
+const float ff_nelly_dequantization_table[127] = {
+ 0.0000000000,
+
+-0.8472560048, 0.7224709988,
+
+-1.5247479677,-0.4531480074, 0.3753609955, 1.4717899561,
+
+-1.9822579622,-1.1929379702,-0.5829370022,-0.0693780035, 0.3909569979, 0.9069200158, 1.4862740040, 2.2215409279,
+
+-2.3887870312,-1.8067539930,-1.4105420113,-1.0773609877,-0.7995010018,-0.5558109879,-0.3334020078,-0.1324490011,
+ 0.0568020009, 0.2548770010, 0.4773550034, 0.7386850119, 1.0443060398, 1.3954459429, 1.8098750114, 2.3918759823,
+
+-2.3893830776,-1.9884680510,-1.7514040470,-1.5643119812,-1.3922129869,-1.2164649963,-1.0469499826,-0.8905100226,
+-0.7645580173,-0.6454579830,-0.5259280205,-0.4059549868,-0.3029719889,-0.2096900046,-0.1239869967,-0.0479229987,
+ 0.0257730000, 0.1001340002, 0.1737180054, 0.2585540116, 0.3522900045, 0.4569880068, 0.5767750144, 0.7003160119,
+ 0.8425520062, 1.0093879700, 1.1821349859, 1.3534560204, 1.5320819616, 1.7332619429, 1.9722349644, 2.3978140354,
+
+-2.5756309032,-2.0573320389,-1.8984919786,-1.7727810144,-1.6662600040,-1.5742180347,-1.4993319511,-1.4316639900,
+-1.3652280569,-1.3000990152,-1.2280930281,-1.1588579416,-1.0921250582,-1.0135740042,-0.9202849865,-0.8287050128,
+-0.7374889851,-0.6447759867,-0.5590940118,-0.4857139885,-0.4110319912,-0.3459700048,-0.2851159871,-0.2341620028,
+-0.1870580018,-0.1442500055,-0.1107169986,-0.0739680007,-0.0365610011,-0.0073290002, 0.0203610007, 0.0479039997,
+ 0.0751969963, 0.0980999991, 0.1220389977, 0.1458999962, 0.1694349945, 0.1970459968, 0.2252430022, 0.2556869984,
+ 0.2870100141, 0.3197099864, 0.3525829911, 0.3889069855, 0.4334920049, 0.4769459963, 0.5204820037, 0.5644530058,
+ 0.6122040153, 0.6685929894, 0.7341650128, 0.8032159805, 0.8784040213, 0.9566209912, 1.0397069454, 1.1293770075,
+ 1.2211159468, 1.3080279827, 1.4024800062, 1.5056819916, 1.6227730513, 1.7724959850, 1.9430880547, 2.2903931141
+};
+
+const uint8_t ff_nelly_band_sizes_table[NELLY_BANDS] = {
+2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 12, 14, 15
+};
+
+const uint16_t ff_nelly_init_table[64] = {
+3134, 5342, 6870, 7792, 8569, 9185, 9744, 10191, 10631, 11061, 11434, 11770,
+12116, 12513, 12925, 13300, 13674, 14027, 14352, 14716, 15117, 15477, 15824,
+16157, 16513, 16804, 17090, 17401, 17679, 17948, 18238, 18520, 18764, 19078,
+19381, 19640, 19921, 20205, 20500, 20813, 21162, 21465, 21794, 22137, 22453,
+22756, 23067, 23350, 23636, 23926, 24227, 24521, 24819, 25107, 25414, 25730,
+26120, 26497, 26895, 27344, 27877, 28463, 29426, 31355
+};
+
+const int16_t ff_nelly_delta_table[32] = {
+-11725, -9420, -7910, -6801, -5948, -5233, -4599, -4039, -3507, -3030, -2596,
+-2170, -1774, -1383, -1016, -660, -329, -1, 337, 696, 1085, 1512, 1962, 2433,
+2968, 3569, 4314, 5279, 6622, 8154, 10076, 12975
+};
+
+static inline int signed_shift(int i, int shift) {
+ if (shift > 0)
+ return (unsigned)i << shift;
+ return i >> -shift;
+}
+
+static int sum_bits(short *buf, short shift, short off)
+{
+ int i, ret = 0;
+
+ for (i = 0; i < NELLY_FILL_LEN; i++) {
+ int b = buf[i]-off;
+ b = ((b>>(shift-1))+1)>>1;
+ ret += av_clip(b, 0, NELLY_BIT_CAP);
+ }
+
+ return ret;
+}
+
+static int headroom(int *la)
+{
+ int l;
+ if (*la == 0) {
+ return 31;
+ }
+ l = 30 - av_log2(FFABS(*la));
+ *la *= 1<<l;
+ return l;
+}
+
+
+void ff_nelly_get_sample_bits(const float *buf, int *bits)
+{
+ int i, j;
+ short sbuf[128];
+ int bitsum = 0, last_bitsum, small_bitsum, big_bitsum;
+ short shift, shift_saved;
+ int max, sum, last_off, tmp;
+ int big_off, small_off;
+ int off;
+
+ max = 0;
+ for (i = 0; i < NELLY_FILL_LEN; i++) {
+ max = FFMAX(max, buf[i]);
+ }
+ shift = -16;
+ shift += headroom(&max);
+
+ sum = 0;
+ for (i = 0; i < NELLY_FILL_LEN; i++) {
+ sbuf[i] = signed_shift(buf[i], shift);
+ sbuf[i] = (3*sbuf[i])>>2;
+ sum += sbuf[i];
+ }
+
+ shift += 11;
+ shift_saved = shift;
+ sum -= NELLY_DETAIL_BITS << shift;
+ shift += headroom(&sum);
+ small_off = (NELLY_BASE_OFF * (sum>>16)) >> 15;
+ shift = shift_saved - (NELLY_BASE_SHIFT+shift-31);
+
+ small_off = signed_shift(small_off, shift);
+
+ bitsum = sum_bits(sbuf, shift_saved, small_off);
+
+ if (bitsum != NELLY_DETAIL_BITS) {
+ off = bitsum - NELLY_DETAIL_BITS;
+
+ for(shift=0; FFABS(off) <= 16383; shift++)
+ off *= 2;
+
+ off = (off * NELLY_BASE_OFF) >> 15;
+ shift = shift_saved-(NELLY_BASE_SHIFT+shift-15);
+
+ off = signed_shift(off, shift);
+
+ for (j = 1; j < 20; j++) {
+ last_off = small_off;
+ small_off += off;
+ last_bitsum = bitsum;
+
+ bitsum = sum_bits(sbuf, shift_saved, small_off);
+
+ if ((bitsum-NELLY_DETAIL_BITS) * (last_bitsum-NELLY_DETAIL_BITS) <= 0)
+ break;
+ }
+
+ if (bitsum > NELLY_DETAIL_BITS) {
+ big_off = small_off;
+ small_off = last_off;
+ big_bitsum=bitsum;
+ small_bitsum=last_bitsum;
+ } else {
+ big_off = last_off;
+ big_bitsum=last_bitsum;
+ small_bitsum=bitsum;
+ }
+
+ while (bitsum != NELLY_DETAIL_BITS && j <= 19) {
+ off = (big_off+small_off)>>1;
+ bitsum = sum_bits(sbuf, shift_saved, off);
+ if (bitsum > NELLY_DETAIL_BITS) {
+ big_off=off;
+ big_bitsum=bitsum;
+ } else {
+ small_off = off;
+ small_bitsum=bitsum;
+ }
+ j++;
+ }
+
+ if (abs(big_bitsum-NELLY_DETAIL_BITS) >=
+ abs(small_bitsum-NELLY_DETAIL_BITS)) {
+ bitsum = small_bitsum;
+ } else {
+ small_off = big_off;
+ bitsum = big_bitsum;
+ }
+ }
+
+ for (i = 0; i < NELLY_FILL_LEN; i++) {
+ tmp = sbuf[i]-small_off;
+ tmp = ((tmp>>(shift_saved-1))+1)>>1;
+ bits[i] = av_clip(tmp, 0, NELLY_BIT_CAP);
+ }
+
+ if (bitsum > NELLY_DETAIL_BITS) {
+ tmp = i = 0;
+ while (tmp < NELLY_DETAIL_BITS) {
+ tmp += bits[i];
+ i++;
+ }
+
+ bits[i-1] -= tmp - NELLY_DETAIL_BITS;
+ for(; i < NELLY_FILL_LEN; i++)
+ bits[i] = 0;
+ }
+}
diff --git a/ffmpeg-2-8-11/libavcodec/nellymoser.h b/ffmpeg-2-8-12/libavcodec/nellymoser.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/nellymoser.h
rename to ffmpeg-2-8-12/libavcodec/nellymoser.h
diff --git a/ffmpeg-2-8-11/libavcodec/nellymoserdec.c b/ffmpeg-2-8-12/libavcodec/nellymoserdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/nellymoserdec.c
rename to ffmpeg-2-8-12/libavcodec/nellymoserdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/nellymoserenc.c b/ffmpeg-2-8-12/libavcodec/nellymoserenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/nellymoserenc.c
rename to ffmpeg-2-8-12/libavcodec/nellymoserenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/neon/Makefile b/ffmpeg-2-8-12/libavcodec/neon/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/neon/Makefile
rename to ffmpeg-2-8-12/libavcodec/neon/Makefile
diff --git a/ffmpeg-2-8-11/libavcodec/neon/mpegvideo.c b/ffmpeg-2-8-12/libavcodec/neon/mpegvideo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/neon/mpegvideo.c
rename to ffmpeg-2-8-12/libavcodec/neon/mpegvideo.c
diff --git a/ffmpeg-2-8-11/libavcodec/noise_bsf.c b/ffmpeg-2-8-12/libavcodec/noise_bsf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/noise_bsf.c
rename to ffmpeg-2-8-12/libavcodec/noise_bsf.c
diff --git a/ffmpeg-2-8-11/libavcodec/nuv.c b/ffmpeg-2-8-12/libavcodec/nuv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/nuv.c
rename to ffmpeg-2-8-12/libavcodec/nuv.c
diff --git a/ffmpeg-2-8-11/libavcodec/nvenc.c b/ffmpeg-2-8-12/libavcodec/nvenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/nvenc.c
rename to ffmpeg-2-8-12/libavcodec/nvenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/old_codec_ids.h b/ffmpeg-2-8-12/libavcodec/old_codec_ids.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/old_codec_ids.h
rename to ffmpeg-2-8-12/libavcodec/old_codec_ids.h
diff --git a/ffmpeg-2-8-11/libavcodec/on2avc.c b/ffmpeg-2-8-12/libavcodec/on2avc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/on2avc.c
rename to ffmpeg-2-8-12/libavcodec/on2avc.c
diff --git a/ffmpeg-2-8-11/libavcodec/on2avcdata.c b/ffmpeg-2-8-12/libavcodec/on2avcdata.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/on2avcdata.c
rename to ffmpeg-2-8-12/libavcodec/on2avcdata.c
diff --git a/ffmpeg-2-8-11/libavcodec/on2avcdata.h b/ffmpeg-2-8-12/libavcodec/on2avcdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/on2avcdata.h
rename to ffmpeg-2-8-12/libavcodec/on2avcdata.h
diff --git a/ffmpeg-2-8-12/libavcodec/options.c b/ffmpeg-2-8-12/libavcodec/options.c
new file mode 100644
index 0000000..dfd1100
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/options.c
@@ -0,0 +1,491 @@
+/*
+ * Copyright (c) 2001 Fabrice Bellard
+ * Copyright (c) 2002-2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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
+ * Options definition for AVCodecContext.
+ */
+
+#include "avcodec.h"
+#include "internal.h"
+#include "libavutil/avassert.h"
+#include "libavutil/internal.h"
+#include "libavutil/mem.h"
+#include "libavutil/opt.h"
+#include <float.h> /* FLT_MIN, FLT_MAX */
+#include <string.h>
+
+FF_DISABLE_DEPRECATION_WARNINGS
+#include "options_table.h"
+FF_ENABLE_DEPRECATION_WARNINGS
+
+static const char* context_to_name(void* ptr) {
+ AVCodecContext *avc= ptr;
+
+ if(avc && avc->codec && avc->codec->name)
+ return avc->codec->name;
+ else
+ return "NULL";
+}
+
+static void *codec_child_next(void *obj, void *prev)
+{
+ AVCodecContext *s = obj;
+ if (!prev && s->codec && s->codec->priv_class && s->priv_data)
+ return s->priv_data;
+ return NULL;
+}
+
+static const AVClass *codec_child_class_next(const AVClass *prev)
+{
+ AVCodec *c = NULL;
+
+ /* find the codec that corresponds to prev */
+ while (prev && (c = av_codec_next(c)))
+ if (c->priv_class == prev)
+ break;
+
+ /* find next codec with priv options */
+ while (c = av_codec_next(c))
+ if (c->priv_class)
+ return c->priv_class;
+ return NULL;
+}
+
+static AVClassCategory get_category(void *ptr)
+{
+ AVCodecContext* avctx = ptr;
+ if(avctx->codec && avctx->codec->decode) return AV_CLASS_CATEGORY_DECODER;
+ else return AV_CLASS_CATEGORY_ENCODER;
+}
+
+static const AVClass av_codec_context_class = {
+ .class_name = "AVCodecContext",
+ .item_name = context_to_name,
+ .option = avcodec_options,
+ .version = LIBAVUTIL_VERSION_INT,
+ .log_level_offset_offset = offsetof(AVCodecContext, log_level_offset),
+ .child_next = codec_child_next,
+ .child_class_next = codec_child_class_next,
+ .category = AV_CLASS_CATEGORY_ENCODER,
+ .get_category = get_category,
+};
+
+int avcodec_get_context_defaults3(AVCodecContext *s, const AVCodec *codec)
+{
+ int flags=0;
+ memset(s, 0, sizeof(AVCodecContext));
+
+ s->av_class = &av_codec_context_class;
+
+ s->codec_type = codec ? codec->type : AVMEDIA_TYPE_UNKNOWN;
+ if (codec) {
+ s->codec = codec;
+ s->codec_id = codec->id;
+ }
+
+ if(s->codec_type == AVMEDIA_TYPE_AUDIO)
+ flags= AV_OPT_FLAG_AUDIO_PARAM;
+ else if(s->codec_type == AVMEDIA_TYPE_VIDEO)
+ flags= AV_OPT_FLAG_VIDEO_PARAM;
+ else if(s->codec_type == AVMEDIA_TYPE_SUBTITLE)
+ flags= AV_OPT_FLAG_SUBTITLE_PARAM;
+ av_opt_set_defaults2(s, flags, flags);
+
+ s->time_base = (AVRational){0,1};
+ s->framerate = (AVRational){ 0, 1 };
+ s->pkt_timebase = (AVRational){ 0, 1 };
+ s->get_buffer2 = avcodec_default_get_buffer2;
+ s->get_format = avcodec_default_get_format;
+ s->execute = avcodec_default_execute;
+ s->execute2 = avcodec_default_execute2;
+ s->sample_aspect_ratio = (AVRational){0,1};
+ s->pix_fmt = AV_PIX_FMT_NONE;
+ s->sample_fmt = AV_SAMPLE_FMT_NONE;
+
+ s->reordered_opaque = AV_NOPTS_VALUE;
+ if(codec && codec->priv_data_size){
+ if(!s->priv_data){
+ s->priv_data= av_mallocz(codec->priv_data_size);
+ if (!s->priv_data) {
+ return AVERROR(ENOMEM);
+ }
+ }
+ if(codec->priv_class){
+ *(const AVClass**)s->priv_data = codec->priv_class;
+ av_opt_set_defaults(s->priv_data);
+ }
+ }
+ if (codec && codec->defaults) {
+ int ret;
+ const AVCodecDefault *d = codec->defaults;
+ while (d->key) {
+ ret = av_opt_set(s, d->key, d->value, 0);
+ av_assert0(ret >= 0);
+ d++;
+ }
+ }
+ return 0;
+}
+
+AVCodecContext *avcodec_alloc_context3(const AVCodec *codec)
+{
+ AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext));
+
+ if (!avctx)
+ return NULL;
+
+ if(avcodec_get_context_defaults3(avctx, codec) < 0){
+ av_free(avctx);
+ return NULL;
+ }
+
+ return avctx;
+}
+
+void avcodec_free_context(AVCodecContext **pavctx)
+{
+ AVCodecContext *avctx = *pavctx;
+
+ if (!avctx)
+ return;
+
+ avcodec_close(avctx);
+
+ av_freep(&avctx->extradata);
+ av_freep(&avctx->subtitle_header);
+ av_freep(&avctx->intra_matrix);
+ av_freep(&avctx->inter_matrix);
+ av_freep(&avctx->rc_override);
+
+ av_freep(pavctx);
+}
+
+static void copy_context_reset(AVCodecContext *avctx)
+{
+ 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_freep(&avctx->rc_override);
+ av_freep(&avctx->intra_matrix);
+ av_freep(&avctx->inter_matrix);
+ av_freep(&avctx->extradata);
+ av_freep(&avctx->subtitle_header);
+ avctx->subtitle_header_size = 0;
+ avctx->extradata_size = 0;
+}
+
+int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src)
+{
+ const AVCodec *orig_codec = dest->codec;
+ uint8_t *orig_priv_data = dest->priv_data;
+
+ if (avcodec_is_open(dest)) { // check that the dest context is uninitialized
+ av_log(dest, AV_LOG_ERROR,
+ "Tried to copy AVCodecContext %p into already-initialized %p\n",
+ src, dest);
+ return AVERROR(EINVAL);
+ }
+
+ copy_context_reset(dest);
+
+ memcpy(dest, src, sizeof(*dest));
+ av_opt_copy(dest, src);
+
+ dest->priv_data = orig_priv_data;
+ dest->codec = orig_codec;
+
+ if (orig_priv_data && src->codec && src->codec->priv_class &&
+ dest->codec && dest->codec->priv_class)
+ av_opt_copy(orig_priv_data, src->priv_data);
+
+
+ /* set values specific to opened codecs back to their default state */
+ dest->slice_offset = NULL;
+ dest->hwaccel = NULL;
+ dest->internal = NULL;
+#if FF_API_CODED_FRAME
+FF_DISABLE_DEPRECATION_WARNINGS
+ dest->coded_frame = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ /* reallocate values that should be allocated separately */
+ dest->extradata = NULL;
+ dest->intra_matrix = NULL;
+ dest->inter_matrix = NULL;
+ dest->rc_override = NULL;
+ dest->subtitle_header = NULL;
+
+#define alloc_and_copy_or_fail(obj, size, pad) \
+ if (src->obj && size > 0) { \
+ dest->obj = av_malloc(size + pad); \
+ if (!dest->obj) \
+ goto fail; \
+ memcpy(dest->obj, src->obj, size); \
+ if (pad) \
+ memset(((uint8_t *) dest->obj) + size, 0, pad); \
+ }
+ alloc_and_copy_or_fail(extradata, src->extradata_size,
+ AV_INPUT_BUFFER_PADDING_SIZE);
+ dest->extradata_size = src->extradata_size;
+ alloc_and_copy_or_fail(intra_matrix, 64 * sizeof(int16_t), 0);
+ alloc_and_copy_or_fail(inter_matrix, 64 * sizeof(int16_t), 0);
+ alloc_and_copy_or_fail(rc_override, src->rc_override_count * sizeof(*src->rc_override), 0);
+ alloc_and_copy_or_fail(subtitle_header, src->subtitle_header_size, 1);
+ av_assert0(dest->subtitle_header_size == src->subtitle_header_size);
+#undef alloc_and_copy_or_fail
+
+ return 0;
+
+fail:
+ copy_context_reset(dest);
+ return AVERROR(ENOMEM);
+}
+
+const AVClass *avcodec_get_class(void)
+{
+ return &av_codec_context_class;
+}
+
+#define FOFFSET(x) offsetof(AVFrame,x)
+
+static const AVOption frame_options[]={
+{"best_effort_timestamp", "", FOFFSET(best_effort_timestamp), AV_OPT_TYPE_INT64, {.i64 = AV_NOPTS_VALUE }, INT64_MIN, INT64_MAX, 0},
+{"pkt_pos", "", FOFFSET(pkt_pos), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0},
+{"pkt_size", "", FOFFSET(pkt_size), AV_OPT_TYPE_INT64, {.i64 = -1 }, INT64_MIN, INT64_MAX, 0},
+{"sample_aspect_ratio", "", FOFFSET(sample_aspect_ratio), AV_OPT_TYPE_RATIONAL, {.dbl = 0 }, 0, INT_MAX, 0},
+{"width", "", FOFFSET(width), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"height", "", FOFFSET(height), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"format", "", FOFFSET(format), AV_OPT_TYPE_INT, {.i64 = -1 }, 0, INT_MAX, 0},
+{"channel_layout", "", FOFFSET(channel_layout), AV_OPT_TYPE_INT64, {.i64 = 0 }, 0, INT64_MAX, 0},
+{"sample_rate", "", FOFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{NULL},
+};
+
+static const AVClass av_frame_class = {
+ .class_name = "AVFrame",
+ .item_name = NULL,
+ .option = frame_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+const AVClass *avcodec_get_frame_class(void)
+{
+ return &av_frame_class;
+}
+
+#define SROFFSET(x) offsetof(AVSubtitleRect,x)
+
+static const AVOption subtitle_rect_options[]={
+{"x", "", SROFFSET(x), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"y", "", SROFFSET(y), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"w", "", SROFFSET(w), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"h", "", SROFFSET(h), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"type", "", SROFFSET(type), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, 0},
+{"flags", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0, "flags"},
+{"forced", "", SROFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, 1, 0},
+{NULL},
+};
+
+static const AVClass av_subtitle_rect_class = {
+ .class_name = "AVSubtitleRect",
+ .item_name = NULL,
+ .option = subtitle_rect_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+const AVClass *avcodec_get_subtitle_rect_class(void)
+{
+ return &av_subtitle_rect_class;
+}
+
+#ifdef TEST
+static int dummy_init(AVCodecContext *ctx)
+{
+ //TODO: this code should set every possible pointer that could be set by codec and is not an option;
+ ctx->extradata_size = 8;
+ ctx->extradata = av_malloc(ctx->extradata_size);
+ return 0;
+}
+
+static int dummy_close(AVCodecContext *ctx)
+{
+ av_freep(&ctx->extradata);
+ ctx->extradata_size = 0;
+ return 0;
+}
+
+static int dummy_encode(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
+{
+ return AVERROR(ENOSYS);
+}
+
+typedef struct Dummy12Context {
+ AVClass *av_class;
+ int num;
+ char* str;
+} Dummy12Context;
+
+typedef struct Dummy3Context {
+ void *fake_av_class;
+ int num;
+ char* str;
+} Dummy3Context;
+
+#define OFFSET(x) offsetof(Dummy12Context, x)
+#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption dummy_options[] = {
+ { "str", "set str", OFFSET(str), AV_OPT_TYPE_STRING, { .str = "i'm src default value" }, 0, 0, VE},
+ { "num", "set num", OFFSET(num), AV_OPT_TYPE_INT, { .i64 = 1500100900 }, 0, INT_MAX, VE},
+ { NULL },
+};
+
+static const AVClass dummy_v1_class = {
+ .class_name = "dummy_v1_class",
+ .item_name = av_default_item_name,
+ .option = dummy_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static const AVClass dummy_v2_class = {
+ .class_name = "dummy_v2_class",
+ .item_name = av_default_item_name,
+ .option = dummy_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+/* codec with options */
+static AVCodec dummy_v1_encoder = {
+ .name = "dummy_v1_codec",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_NONE - 1,
+ .encode2 = dummy_encode,
+ .init = dummy_init,
+ .close = dummy_close,
+ .priv_class = &dummy_v1_class,
+ .priv_data_size = sizeof(Dummy12Context),
+};
+
+/* codec with options, different class */
+static AVCodec dummy_v2_encoder = {
+ .name = "dummy_v2_codec",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_NONE - 2,
+ .encode2 = dummy_encode,
+ .init = dummy_init,
+ .close = dummy_close,
+ .priv_class = &dummy_v2_class,
+ .priv_data_size = sizeof(Dummy12Context),
+};
+
+/* codec with priv data, but no class */
+static AVCodec dummy_v3_encoder = {
+ .name = "dummy_v3_codec",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_NONE - 3,
+ .encode2 = dummy_encode,
+ .init = dummy_init,
+ .close = dummy_close,
+ .priv_data_size = sizeof(Dummy3Context),
+};
+
+/* codec without priv data */
+static AVCodec dummy_v4_encoder = {
+ .name = "dummy_v4_codec",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_NONE - 4,
+ .encode2 = dummy_encode,
+ .init = dummy_init,
+ .close = dummy_close,
+};
+
+static void test_copy_print_codec(const AVCodecContext *ctx)
+{
+ printf("%-14s: %dx%d prv: %s",
+ ctx->codec ? ctx->codec->name : "NULL",
+ ctx->width, ctx->height,
+ ctx->priv_data ? "set" : "null");
+ if (ctx->codec && ctx->codec->priv_class && ctx->codec->priv_data_size) {
+ int64_t i64;
+ char *str = NULL;
+ av_opt_get_int(ctx->priv_data, "num", 0, &i64);
+ av_opt_get(ctx->priv_data, "str", 0, (uint8_t**)&str);
+ printf(" opts: %"PRId64" %s", i64, str);
+ av_free(str);
+ }
+ printf("\n");
+}
+
+static void test_copy(const AVCodec *c1, const AVCodec *c2)
+{
+ AVCodecContext *ctx1, *ctx2;
+ printf("%s -> %s\nclosed:\n", c1 ? c1->name : "NULL", c2 ? c2->name : "NULL");
+ ctx1 = avcodec_alloc_context3(c1);
+ ctx2 = avcodec_alloc_context3(c2);
+ ctx1->width = ctx1->height = 128;
+ if (ctx2->codec && ctx2->codec->priv_class && ctx2->codec->priv_data_size) {
+ av_opt_set(ctx2->priv_data, "num", "667", 0);
+ av_opt_set(ctx2->priv_data, "str", "i'm dest value before copy", 0);
+ }
+ avcodec_copy_context(ctx2, ctx1);
+ test_copy_print_codec(ctx1);
+ test_copy_print_codec(ctx2);
+ if (ctx1->codec) {
+ printf("opened:\n");
+ avcodec_open2(ctx1, ctx1->codec, NULL);
+ if (ctx2->codec && ctx2->codec->priv_class && ctx2->codec->priv_data_size) {
+ av_opt_set(ctx2->priv_data, "num", "667", 0);
+ av_opt_set(ctx2->priv_data, "str", "i'm dest value before copy", 0);
+ }
+ avcodec_copy_context(ctx2, ctx1);
+ test_copy_print_codec(ctx1);
+ test_copy_print_codec(ctx2);
+ avcodec_close(ctx1);
+ }
+ avcodec_free_context(&ctx1);
+ avcodec_free_context(&ctx2);
+}
+
+int main(void)
+{
+ AVCodec *dummy_codec[] = {
+ &dummy_v1_encoder,
+ &dummy_v2_encoder,
+ &dummy_v3_encoder,
+ &dummy_v4_encoder,
+ NULL,
+ };
+ int i, j;
+
+ for (i = 0; dummy_codec[i]; i++)
+ avcodec_register(dummy_codec[i]);
+
+ printf("testing avcodec_copy_context()\n");
+ for (i = 0; i < FF_ARRAY_ELEMS(dummy_codec); i++)
+ for (j = 0; j < FF_ARRAY_ELEMS(dummy_codec); j++)
+ test_copy(dummy_codec[i], dummy_codec[j]);
+ return 0;
+}
+#endif
diff --git a/ffmpeg-2-8-11/libavcodec/options_table.h b/ffmpeg-2-8-12/libavcodec/options_table.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/options_table.h
rename to ffmpeg-2-8-12/libavcodec/options_table.h
diff --git a/ffmpeg-2-8-11/libavcodec/opus.c b/ffmpeg-2-8-12/libavcodec/opus.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/opus.c
rename to ffmpeg-2-8-12/libavcodec/opus.c
diff --git a/ffmpeg-2-8-11/libavcodec/opus.h b/ffmpeg-2-8-12/libavcodec/opus.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/opus.h
rename to ffmpeg-2-8-12/libavcodec/opus.h
diff --git a/ffmpeg-2-8-11/libavcodec/opus_celt.c b/ffmpeg-2-8-12/libavcodec/opus_celt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/opus_celt.c
rename to ffmpeg-2-8-12/libavcodec/opus_celt.c
diff --git a/ffmpeg-2-8-11/libavcodec/opus_parser.c b/ffmpeg-2-8-12/libavcodec/opus_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/opus_parser.c
rename to ffmpeg-2-8-12/libavcodec/opus_parser.c
diff --git a/ffmpeg-2-8-12/libavcodec/opus_silk.c b/ffmpeg-2-8-12/libavcodec/opus_silk.c
new file mode 100644
index 0000000..408e4bf
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/opus_silk.c
@@ -0,0 +1,1596 @@
+/*
+ * Copyright (c) 2012 Andrew D'Addesio
+ * Copyright (c) 2013-2014 Mozilla 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 FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Opus SILK decoder
+ */
+
+#include <stdint.h>
+
+#include "opus.h"
+
+typedef struct SilkFrame {
+ int coded;
+ int log_gain;
+ int16_t nlsf[16];
+ float lpc[16];
+
+ float output [2 * SILK_HISTORY];
+ float lpc_history[2 * SILK_HISTORY];
+ int primarylag;
+
+ int prev_voiced;
+} SilkFrame;
+
+struct SilkContext {
+ AVCodecContext *avctx;
+ int output_channels;
+
+ int midonly;
+ int subframes;
+ int sflength;
+ int flength;
+ int nlsf_interp_factor;
+
+ enum OpusBandwidth bandwidth;
+ int wb;
+
+ SilkFrame frame[2];
+ float prev_stereo_weights[2];
+ float stereo_weights[2];
+
+ int prev_coded_channels;
+};
+
+static const uint16_t silk_model_stereo_s1[] = {
+ 256, 7, 9, 10, 11, 12, 22, 46, 54, 55, 56, 59, 82, 174, 197, 200,
+ 201, 202, 210, 234, 244, 245, 246, 247, 249, 256
+};
+
+static const uint16_t silk_model_stereo_s2[] = {256, 85, 171, 256};
+
+static const uint16_t silk_model_stereo_s3[] = {256, 51, 102, 154, 205, 256};
+
+static const uint16_t silk_model_mid_only[] = {256, 192, 256};
+
+static const uint16_t silk_model_frame_type_inactive[] = {256, 26, 256};
+
+static const uint16_t silk_model_frame_type_active[] = {256, 24, 98, 246, 256};
+
+static const uint16_t silk_model_gain_highbits[3][9] = {
+ {256, 32, 144, 212, 241, 253, 254, 255, 256},
+ {256, 2, 19, 64, 124, 186, 233, 252, 256},
+ {256, 1, 4, 30, 101, 195, 245, 254, 256}
+};
+
+static const uint16_t silk_model_gain_lowbits[] = {256, 32, 64, 96, 128, 160, 192, 224, 256};
+
+static const uint16_t silk_model_gain_delta[] = {
+ 256, 6, 11, 22, 53, 185, 206, 214, 218, 221, 223, 225, 227, 228, 229, 230,
+ 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
+ 247, 248, 249, 250, 251, 252, 253, 254, 255, 256
+};
+static const uint16_t silk_model_lsf_s1[2][2][33] = {
+ {
+ { // NB or MB, unvoiced
+ 256, 44, 78, 108, 127, 148, 160, 171, 174, 177, 179, 195, 197, 199, 200, 205,
+ 207, 208, 211, 214, 215, 216, 218, 220, 222, 225, 226, 235, 244, 246, 253, 255, 256
+ }, { // NB or MB, voiced
+ 256, 1, 11, 12, 20, 23, 31, 39, 53, 66, 80, 81, 95, 107, 120, 131,
+ 142, 154, 165, 175, 185, 196, 204, 213, 221, 228, 236, 237, 238, 244, 245, 251, 256
+ }
+ }, {
+ { // WB, unvoiced
+ 256, 31, 52, 55, 72, 73, 81, 98, 102, 103, 121, 137, 141, 143, 146, 147,
+ 157, 158, 161, 177, 188, 204, 206, 208, 211, 213, 224, 225, 229, 238, 246, 253, 256
+ }, { // WB, voiced
+ 256, 1, 5, 21, 26, 44, 55, 60, 74, 89, 90, 93, 105, 118, 132, 146,
+ 152, 166, 178, 180, 186, 187, 199, 211, 222, 232, 235, 245, 250, 251, 252, 253, 256
+ }
+ }
+};
+
+static const uint16_t silk_model_lsf_s2[32][10] = {
+ // NB, MB
+ { 256, 1, 2, 3, 18, 242, 253, 254, 255, 256 },
+ { 256, 1, 2, 4, 38, 221, 253, 254, 255, 256 },
+ { 256, 1, 2, 6, 48, 197, 252, 254, 255, 256 },
+ { 256, 1, 2, 10, 62, 185, 246, 254, 255, 256 },
+ { 256, 1, 4, 20, 73, 174, 248, 254, 255, 256 },
+ { 256, 1, 4, 21, 76, 166, 239, 254, 255, 256 },
+ { 256, 1, 8, 32, 85, 159, 226, 252, 255, 256 },
+ { 256, 1, 2, 20, 83, 161, 219, 249, 255, 256 },
+
+ // WB
+ { 256, 1, 2, 3, 12, 244, 253, 254, 255, 256 },
+ { 256, 1, 2, 4, 32, 218, 253, 254, 255, 256 },
+ { 256, 1, 2, 5, 47, 199, 252, 254, 255, 256 },
+ { 256, 1, 2, 12, 61, 187, 252, 254, 255, 256 },
+ { 256, 1, 5, 24, 72, 172, 249, 254, 255, 256 },
+ { 256, 1, 2, 16, 70, 170, 242, 254, 255, 256 },
+ { 256, 1, 2, 17, 78, 165, 226, 251, 255, 256 },
+ { 256, 1, 8, 29, 79, 156, 237, 254, 255, 256 }
+};
+
+static const uint16_t silk_model_lsf_s2_ext[] = { 256, 156, 216, 240, 249, 253, 255, 256 };
+
+static const uint16_t silk_model_lsf_interpolation_offset[] = { 256, 13, 35, 64, 75, 256 };
+
+static const uint16_t silk_model_pitch_highbits[] = {
+ 256, 3, 6, 12, 23, 44, 74, 106, 125, 136, 146, 158, 171, 184, 196, 207,
+ 216, 224, 231, 237, 241, 243, 245, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256
+};
+
+static const uint16_t silk_model_pitch_lowbits_nb[]= { 256, 64, 128, 192, 256 };
+
+static const uint16_t silk_model_pitch_lowbits_mb[]= { 256, 43, 85, 128, 171, 213, 256 };
+
+static const uint16_t silk_model_pitch_lowbits_wb[]= { 256, 32, 64, 96, 128, 160, 192, 224, 256 };
+
+static const uint16_t silk_model_pitch_delta[] = {
+ 256, 46, 48, 50, 53, 57, 63, 73, 88, 114, 152, 182, 204, 219, 229, 236,
+ 242, 246, 250, 252, 254, 256
+};
+
+static const uint16_t silk_model_pitch_contour_nb10ms[] = { 256, 143, 193, 256 };
+
+static const uint16_t silk_model_pitch_contour_nb20ms[] = {
+ 256, 68, 80, 101, 118, 137, 159, 189, 213, 230, 246, 256
+};
+
+static const uint16_t silk_model_pitch_contour_mbwb10ms[] = {
+ 256, 91, 137, 176, 195, 209, 221, 229, 236, 242, 247, 252, 256
+};
+
+static const uint16_t silk_model_pitch_contour_mbwb20ms[] = {
+ 256, 33, 55, 73, 89, 104, 118, 132, 145, 158, 168, 177, 186, 194, 200, 206,
+ 212, 217, 221, 225, 229, 232, 235, 238, 240, 242, 244, 246, 248, 250, 252, 253,
+ 254, 255, 256
+};
+
+static const uint16_t silk_model_ltp_filter[] = { 256, 77, 157, 256 };
+
+static const uint16_t silk_model_ltp_filter0_sel[] = {
+ 256, 185, 200, 213, 226, 235, 244, 250, 256
+};
+
+static const uint16_t silk_model_ltp_filter1_sel[] = {
+ 256, 57, 91, 112, 132, 147, 160, 172, 185, 195, 205, 214, 224, 233, 241, 248, 256
+};
+
+static const uint16_t silk_model_ltp_filter2_sel[] = {
+ 256, 15, 31, 45, 57, 69, 81, 92, 103, 114, 124, 133, 142, 151, 160, 168,
+ 176, 184, 192, 199, 206, 212, 218, 223, 227, 232, 236, 240, 244, 247, 251, 254, 256
+};
+
+static const uint16_t silk_model_ltp_scale_index[] = { 256, 128, 192, 256 };
+
+static const uint16_t silk_model_lcg_seed[] = { 256, 64, 128, 192, 256 };
+
+static const uint16_t silk_model_exc_rate[2][10] = {
+ { 256, 15, 66, 78, 124, 169, 182, 215, 242, 256 }, // unvoiced
+ { 256, 33, 63, 99, 116, 150, 199, 217, 238, 256 } // voiced
+};
+
+static const uint16_t silk_model_pulse_count[11][19] = {
+ { 256, 131, 205, 230, 238, 241, 244, 245, 246,
+ 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 },
+ { 256, 58, 151, 211, 234, 241, 244, 245, 246,
+ 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 },
+ { 256, 43, 94, 140, 173, 197, 213, 224, 232,
+ 238, 241, 244, 247, 249, 250, 251, 253, 254, 256 },
+ { 256, 17, 69, 140, 197, 228, 240, 245, 246,
+ 247, 248, 249, 250, 251, 252, 253, 254, 255, 256 },
+ { 256, 6, 27, 68, 121, 170, 205, 226, 237,
+ 243, 246, 248, 250, 251, 252, 253, 254, 255, 256 },
+ { 256, 7, 21, 43, 71, 100, 128, 153, 173,
+ 190, 203, 214, 223, 230, 235, 239, 243, 246, 256 },
+ { 256, 2, 7, 21, 50, 92, 138, 179, 210,
+ 229, 240, 246, 249, 251, 252, 253, 254, 255, 256 },
+ { 256, 1, 3, 7, 17, 36, 65, 100, 137,
+ 171, 199, 219, 233, 241, 246, 250, 252, 254, 256 },
+ { 256, 1, 3, 5, 10, 19, 33, 53, 77,
+ 104, 132, 158, 181, 201, 216, 227, 235, 241, 256 },
+ { 256, 1, 2, 3, 9, 36, 94, 150, 189,
+ 214, 228, 238, 244, 247, 250, 252, 253, 254, 256 },
+ { 256, 2, 3, 9, 36, 94, 150, 189, 214,
+ 228, 238, 244, 247, 250, 252, 253, 254, 256, 256 }
+};
+
+static const uint16_t silk_model_pulse_location[4][168] = {
+ {
+ 256, 126, 256,
+ 256, 56, 198, 256,
+ 256, 25, 126, 230, 256,
+ 256, 12, 72, 180, 244, 256,
+ 256, 7, 42, 126, 213, 250, 256,
+ 256, 4, 24, 83, 169, 232, 253, 256,
+ 256, 3, 15, 53, 125, 200, 242, 254, 256,
+ 256, 2, 10, 35, 89, 162, 221, 248, 255, 256,
+ 256, 2, 7, 24, 63, 126, 191, 233, 251, 255, 256,
+ 256, 1, 5, 17, 45, 94, 157, 211, 241, 252, 255, 256,
+ 256, 1, 5, 13, 33, 70, 125, 182, 223, 245, 253, 255, 256,
+ 256, 1, 4, 11, 26, 54, 98, 151, 199, 232, 248, 254, 255, 256,
+ 256, 1, 3, 9, 21, 42, 77, 124, 172, 212, 237, 249, 254, 255, 256,
+ 256, 1, 2, 6, 16, 33, 60, 97, 144, 187, 220, 241, 250, 254, 255, 256,
+ 256, 1, 2, 3, 11, 25, 47, 80, 120, 163, 201, 229, 245, 253, 254, 255, 256,
+ 256, 1, 2, 3, 4, 17, 35, 62, 98, 139, 180, 214, 238, 252, 253, 254, 255, 256
+ },{
+ 256, 127, 256,
+ 256, 53, 202, 256,
+ 256, 22, 127, 233, 256,
+ 256, 11, 72, 183, 246, 256,
+ 256, 6, 41, 127, 215, 251, 256,
+ 256, 4, 24, 83, 170, 232, 253, 256,
+ 256, 3, 16, 56, 127, 200, 241, 254, 256,
+ 256, 3, 12, 39, 92, 162, 218, 246, 255, 256,
+ 256, 3, 11, 30, 67, 124, 185, 229, 249, 255, 256,
+ 256, 3, 10, 25, 53, 97, 151, 200, 233, 250, 255, 256,
+ 256, 1, 8, 21, 43, 77, 123, 171, 209, 237, 251, 255, 256,
+ 256, 1, 2, 13, 35, 62, 97, 139, 186, 219, 244, 254, 255, 256,
+ 256, 1, 2, 8, 22, 48, 85, 128, 171, 208, 234, 248, 254, 255, 256,
+ 256, 1, 2, 6, 16, 36, 67, 107, 149, 189, 220, 240, 250, 254, 255, 256,
+ 256, 1, 2, 5, 13, 29, 55, 90, 128, 166, 201, 227, 243, 251, 254, 255, 256,
+ 256, 1, 2, 4, 10, 22, 43, 73, 109, 147, 183, 213, 234, 246, 252, 254, 255, 256
+ },{
+ 256, 127, 256,
+ 256, 49, 206, 256,
+ 256, 20, 127, 236, 256,
+ 256, 11, 71, 184, 246, 256,
+ 256, 7, 43, 127, 214, 250, 256,
+ 256, 6, 30, 87, 169, 229, 252, 256,
+ 256, 5, 23, 62, 126, 194, 236, 252, 256,
+ 256, 6, 20, 49, 96, 157, 209, 239, 253, 256,
+ 256, 1, 16, 39, 74, 125, 175, 215, 245, 255, 256,
+ 256, 1, 2, 23, 55, 97, 149, 195, 236, 254, 255, 256,
+ 256, 1, 7, 23, 50, 86, 128, 170, 206, 233, 249, 255, 256,
+ 256, 1, 6, 18, 39, 70, 108, 148, 186, 217, 238, 250, 255, 256,
+ 256, 1, 4, 13, 30, 56, 90, 128, 166, 200, 226, 243, 252, 255, 256,
+ 256, 1, 4, 11, 25, 47, 76, 110, 146, 180, 209, 231, 245, 252, 255, 256,
+ 256, 1, 3, 8, 19, 37, 62, 93, 128, 163, 194, 219, 237, 248, 253, 255, 256,
+ 256, 1, 2, 6, 15, 30, 51, 79, 111, 145, 177, 205, 226, 241, 250, 254, 255, 256
+ },{
+ 256, 128, 256,
+ 256, 42, 214, 256,
+ 256, 21, 128, 235, 256,
+ 256, 12, 72, 184, 245, 256,
+ 256, 8, 42, 128, 214, 249, 256,
+ 256, 8, 31, 86, 176, 231, 251, 256,
+ 256, 5, 20, 58, 130, 202, 238, 253, 256,
+ 256, 6, 18, 45, 97, 174, 221, 241, 251, 256,
+ 256, 6, 25, 53, 88, 128, 168, 203, 231, 250, 256,
+ 256, 4, 18, 40, 71, 108, 148, 185, 216, 238, 252, 256,
+ 256, 3, 13, 31, 57, 90, 128, 166, 199, 225, 243, 253, 256,
+ 256, 2, 10, 23, 44, 73, 109, 147, 183, 212, 233, 246, 254, 256,
+ 256, 1, 6, 16, 33, 58, 90, 128, 166, 198, 223, 240, 250, 255, 256,
+ 256, 1, 5, 12, 25, 46, 75, 110, 146, 181, 210, 231, 244, 251, 255, 256,
+ 256, 1, 3, 8, 18, 35, 60, 92, 128, 164, 196, 221, 238, 248, 253, 255, 256,
+ 256, 1, 3, 7, 14, 27, 48, 76, 110, 146, 180, 208, 229, 242, 249, 253, 255, 256
+ }
+};
+
+static const uint16_t silk_model_excitation_lsb[] = {256, 136, 256};
+
+static const uint16_t silk_model_excitation_sign[3][2][7][3] = {
+ { // Inactive
+ { // Low offset
+ {256, 2, 256},
+ {256, 207, 256},
+ {256, 189, 256},
+ {256, 179, 256},
+ {256, 174, 256},
+ {256, 163, 256},
+ {256, 157, 256}
+ }, { // High offset
+ {256, 58, 256},
+ {256, 245, 256},
+ {256, 238, 256},
+ {256, 232, 256},
+ {256, 225, 256},
+ {256, 220, 256},
+ {256, 211, 256}
+ }
+ }, { // Unvoiced
+ { // Low offset
+ {256, 1, 256},
+ {256, 210, 256},
+ {256, 190, 256},
+ {256, 178, 256},
+ {256, 169, 256},
+ {256, 162, 256},
+ {256, 152, 256}
+ }, { // High offset
+ {256, 48, 256},
+ {256, 242, 256},
+ {256, 235, 256},
+ {256, 224, 256},
+ {256, 214, 256},
+ {256, 205, 256},
+ {256, 190, 256}
+ }
+ }, { // Voiced
+ { // Low offset
+ {256, 1, 256},
+ {256, 162, 256},
+ {256, 152, 256},
+ {256, 147, 256},
+ {256, 144, 256},
+ {256, 141, 256},
+ {256, 138, 256}
+ }, { // High offset
+ {256, 8, 256},
+ {256, 203, 256},
+ {256, 187, 256},
+ {256, 176, 256},
+ {256, 168, 256},
+ {256, 161, 256},
+ {256, 154, 256}
+ }
+ }
+};
+
+static const int16_t silk_stereo_weights[] = {
+ -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820,
+ 820, 2950, 5000, 6500, 7526, 8266, 10050, 13732
+};
+
+static const uint8_t silk_lsf_s2_model_sel_nbmb[32][10] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 3, 1, 2, 2, 1, 2, 1, 1, 1 },
+ { 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ { 1, 2, 2, 2, 2, 1, 2, 1, 1, 1 },
+ { 2, 3, 3, 3, 3, 2, 2, 2, 2, 2 },
+ { 0, 5, 3, 3, 2, 2, 2, 2, 1, 1 },
+ { 0, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
+ { 2, 3, 6, 4, 4, 4, 5, 4, 5, 5 },
+ { 2, 4, 5, 5, 4, 5, 4, 6, 4, 4 },
+ { 2, 4, 4, 7, 4, 5, 4, 5, 5, 4 },
+ { 4, 3, 3, 3, 2, 3, 2, 2, 2, 2 },
+ { 1, 5, 5, 6, 4, 5, 4, 5, 5, 5 },
+ { 2, 7, 4, 6, 5, 5, 5, 5, 5, 5 },
+ { 2, 7, 5, 5, 5, 5, 5, 6, 5, 4 },
+ { 3, 3, 5, 4, 4, 5, 4, 5, 4, 4 },
+ { 2, 3, 3, 5, 5, 4, 4, 4, 4, 4 },
+ { 2, 4, 4, 6, 4, 5, 4, 5, 5, 5 },
+ { 2, 5, 4, 6, 5, 5, 5, 4, 5, 4 },
+ { 2, 7, 4, 5, 4, 5, 4, 5, 5, 5 },
+ { 2, 5, 4, 6, 7, 6, 5, 6, 5, 4 },
+ { 3, 6, 7, 4, 6, 5, 5, 6, 4, 5 },
+ { 2, 7, 6, 4, 4, 4, 5, 4, 5, 5 },
+ { 4, 5, 5, 4, 6, 6, 5, 6, 5, 4 },
+ { 2, 5, 5, 6, 5, 6, 4, 6, 4, 4 },
+ { 4, 5, 5, 5, 3, 7, 4, 5, 5, 4 },
+ { 2, 3, 4, 5, 5, 6, 4, 5, 5, 4 },
+ { 2, 3, 2, 3, 3, 4, 2, 3, 3, 3 },
+ { 1, 1, 2, 2, 2, 2, 2, 3, 2, 2 },
+ { 4, 5, 5, 6, 6, 6, 5, 6, 4, 5 },
+ { 3, 5, 5, 4, 4, 4, 4, 3, 3, 2 },
+ { 2, 5, 3, 7, 5, 5, 4, 4, 5, 4 },
+ { 4, 4, 5, 4, 5, 6, 5, 6, 5, 4 }
+};
+
+static const uint8_t silk_lsf_s2_model_sel_wb[32][16] = {
+ { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 },
+ { 10, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 8, 11 },
+ { 10, 13, 13, 11, 15, 12, 12, 13, 10, 13, 12, 13, 13, 12, 11, 11 },
+ { 8, 10, 9, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9 },
+ { 8, 14, 13, 12, 14, 12, 15, 13, 12, 12, 12, 13, 13, 12, 12, 11 },
+ { 8, 11, 13, 13, 12, 11, 11, 13, 11, 11, 11, 11, 11, 11, 10, 12 },
+ { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 },
+ { 8, 10, 14, 11, 15, 10, 13, 11, 12, 13, 13, 12, 11, 11, 10, 11 },
+ { 8, 14, 10, 14, 14, 12, 13, 12, 14, 13, 12, 12, 13, 11, 11, 11 },
+ { 10, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 },
+ { 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9 },
+ { 10, 10, 11, 12, 13, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 11 },
+ { 10, 10, 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, 11, 10, 9, 11 },
+ { 11, 12, 12, 12, 14, 12, 12, 13, 11, 13, 12, 12, 13, 12, 11, 12 },
+ { 8, 14, 12, 13, 12, 15, 13, 10, 14, 13, 15, 12, 12, 11, 13, 11 },
+ { 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 9, 8 },
+ { 9, 14, 13, 15, 13, 12, 13, 11, 12, 13, 12, 12, 12, 11, 11, 12 },
+ { 9, 11, 11, 12, 12, 11, 11, 13, 10, 11, 11, 13, 13, 13, 11, 12 },
+ { 10, 11, 11, 10, 10, 10, 11, 10, 9, 10, 9, 10, 9, 9, 9, 12 },
+ { 8, 10, 11, 13, 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 8 },
+ { 11, 12, 11, 13, 11, 11, 10, 10, 9, 9, 9, 9, 9, 10, 10, 12 },
+ { 10, 14, 11, 15, 15, 12, 13, 12, 13, 11, 13, 11, 11, 10, 11, 11 },
+ { 10, 11, 13, 14, 14, 11, 13, 11, 12, 12, 11, 11, 11, 11, 10, 12 },
+ { 9, 11, 11, 12, 12, 12, 12, 11, 13, 13, 13, 11, 9, 9, 9, 9 },
+ { 10, 13, 11, 14, 14, 12, 15, 12, 12, 13, 11, 12, 12, 11, 11, 11 },
+ { 8, 14, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 },
+ { 8, 14, 14, 11, 13, 10, 13, 13, 11, 12, 12, 15, 15, 12, 12, 12 },
+ { 11, 11, 15, 11, 13, 12, 11, 11, 11, 10, 10, 11, 11, 11, 10, 11 },
+ { 8, 8, 9, 8, 8, 8, 10, 9, 10, 9, 9, 10, 10, 10, 9, 9 },
+ { 8, 11, 10, 13, 11, 11, 10, 11, 10, 9, 8, 8, 9, 8, 8, 9 },
+ { 11, 13, 13, 12, 15, 13, 11, 11, 10, 11, 10, 10, 9, 8, 9, 8 },
+ { 10, 11, 13, 11, 12, 11, 11, 11, 10, 9, 10, 14, 12, 8, 8, 8 }
+};
+
+static const uint8_t silk_lsf_pred_weights_nbmb[2][9] = {
+ {179, 138, 140, 148, 151, 149, 153, 151, 163},
+ {116, 67, 82, 59, 92, 72, 100, 89, 92}
+};
+
+static const uint8_t silk_lsf_pred_weights_wb[2][15] = {
+ {175, 148, 160, 176, 178, 173, 174, 164, 177, 174, 196, 182, 198, 192, 182},
+ { 68, 62, 66, 60, 72, 117, 85, 90, 118, 136, 151, 142, 160, 142, 155}
+};
+
+static const uint8_t silk_lsf_weight_sel_nbmb[32][9] = {
+ { 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 1, 1, 0, 0, 0, 0, 1, 0 },
+ { 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 1, 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 0, 1, 1, 0, 0, 0, 1, 0 },
+ { 0, 1, 1, 0, 0, 1, 1, 0, 0 },
+ { 0, 0, 1, 1, 0, 1, 0, 1, 1 },
+ { 0, 0, 1, 1, 0, 0, 1, 1, 1 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 1, 0, 1, 1, 1, 1, 1, 0 },
+ { 0, 1, 0, 1, 1, 1, 1, 1, 0 },
+ { 0, 1, 1, 1, 1, 1, 1, 1, 0 },
+ { 1, 0, 1, 1, 0, 1, 1, 1, 1 },
+ { 0, 1, 1, 1, 1, 1, 0, 1, 0 },
+ { 0, 0, 1, 1, 0, 1, 0, 1, 0 },
+ { 0, 0, 1, 1, 1, 0, 1, 1, 1 },
+ { 0, 1, 1, 0, 0, 1, 1, 1, 0 },
+ { 0, 0, 0, 1, 1, 1, 0, 1, 0 },
+ { 0, 1, 1, 0, 0, 1, 0, 1, 0 },
+ { 0, 1, 1, 0, 0, 0, 1, 1, 0 },
+ { 0, 0, 0, 0, 0, 1, 1, 1, 1 },
+ { 0, 0, 1, 1, 0, 0, 0, 1, 1 },
+ { 0, 0, 0, 1, 0, 1, 1, 1, 1 },
+ { 0, 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, 1, 0, 1, 1, 0, 1, 0 },
+ { 1, 0, 0, 1, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 1, 1, 0, 1, 0, 1 },
+ { 1, 0, 1, 1, 0, 1, 1, 1, 1 }
+};
+
+static const uint8_t silk_lsf_weight_sel_wb[32][15] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
+ { 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0 },
+ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 },
+ { 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1 },
+ { 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0 },
+ { 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
+ { 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0 },
+ { 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 },
+ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
+ { 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0 },
+ { 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0 },
+ { 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
+ { 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0 },
+ { 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1 },
+ { 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
+ { 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0 }
+};
+
+static const uint8_t silk_lsf_codebook_nbmb[32][10] = {
+ { 12, 35, 60, 83, 108, 132, 157, 180, 206, 228 },
+ { 15, 32, 55, 77, 101, 125, 151, 175, 201, 225 },
+ { 19, 42, 66, 89, 114, 137, 162, 184, 209, 230 },
+ { 12, 25, 50, 72, 97, 120, 147, 172, 200, 223 },
+ { 26, 44, 69, 90, 114, 135, 159, 180, 205, 225 },
+ { 13, 22, 53, 80, 106, 130, 156, 180, 205, 228 },
+ { 15, 25, 44, 64, 90, 115, 142, 168, 196, 222 },
+ { 19, 24, 62, 82, 100, 120, 145, 168, 190, 214 },
+ { 22, 31, 50, 79, 103, 120, 151, 170, 203, 227 },
+ { 21, 29, 45, 65, 106, 124, 150, 171, 196, 224 },
+ { 30, 49, 75, 97, 121, 142, 165, 186, 209, 229 },
+ { 19, 25, 52, 70, 93, 116, 143, 166, 192, 219 },
+ { 26, 34, 62, 75, 97, 118, 145, 167, 194, 217 },
+ { 25, 33, 56, 70, 91, 113, 143, 165, 196, 223 },
+ { 21, 34, 51, 72, 97, 117, 145, 171, 196, 222 },
+ { 20, 29, 50, 67, 90, 117, 144, 168, 197, 221 },
+ { 22, 31, 48, 66, 95, 117, 146, 168, 196, 222 },
+ { 24, 33, 51, 77, 116, 134, 158, 180, 200, 224 },
+ { 21, 28, 70, 87, 106, 124, 149, 170, 194, 217 },
+ { 26, 33, 53, 64, 83, 117, 152, 173, 204, 225 },
+ { 27, 34, 65, 95, 108, 129, 155, 174, 210, 225 },
+ { 20, 26, 72, 99, 113, 131, 154, 176, 200, 219 },
+ { 34, 43, 61, 78, 93, 114, 155, 177, 205, 229 },
+ { 23, 29, 54, 97, 124, 138, 163, 179, 209, 229 },
+ { 30, 38, 56, 89, 118, 129, 158, 178, 200, 231 },
+ { 21, 29, 49, 63, 85, 111, 142, 163, 193, 222 },
+ { 27, 48, 77, 103, 133, 158, 179, 196, 215, 232 },
+ { 29, 47, 74, 99, 124, 151, 176, 198, 220, 237 },
+ { 33, 42, 61, 76, 93, 121, 155, 174, 207, 225 },
+ { 29, 53, 87, 112, 136, 154, 170, 188, 208, 227 },
+ { 24, 30, 52, 84, 131, 150, 166, 186, 203, 229 },
+ { 37, 48, 64, 84, 104, 118, 156, 177, 201, 230 }
+};
+
+static const uint8_t silk_lsf_codebook_wb[32][16] = {
+ { 7, 23, 38, 54, 69, 85, 100, 116, 131, 147, 162, 178, 193, 208, 223, 239 },
+ { 13, 25, 41, 55, 69, 83, 98, 112, 127, 142, 157, 171, 187, 203, 220, 236 },
+ { 15, 21, 34, 51, 61, 78, 92, 106, 126, 136, 152, 167, 185, 205, 225, 240 },
+ { 10, 21, 36, 50, 63, 79, 95, 110, 126, 141, 157, 173, 189, 205, 221, 237 },
+ { 17, 20, 37, 51, 59, 78, 89, 107, 123, 134, 150, 164, 184, 205, 224, 240 },
+ { 10, 15, 32, 51, 67, 81, 96, 112, 129, 142, 158, 173, 189, 204, 220, 236 },
+ { 8, 21, 37, 51, 65, 79, 98, 113, 126, 138, 155, 168, 179, 192, 209, 218 },
+ { 12, 15, 34, 55, 63, 78, 87, 108, 118, 131, 148, 167, 185, 203, 219, 236 },
+ { 16, 19, 32, 36, 56, 79, 91, 108, 118, 136, 154, 171, 186, 204, 220, 237 },
+ { 11, 28, 43, 58, 74, 89, 105, 120, 135, 150, 165, 180, 196, 211, 226, 241 },
+ { 6, 16, 33, 46, 60, 75, 92, 107, 123, 137, 156, 169, 185, 199, 214, 225 },
+ { 11, 19, 30, 44, 57, 74, 89, 105, 121, 135, 152, 169, 186, 202, 218, 234 },
+ { 12, 19, 29, 46, 57, 71, 88, 100, 120, 132, 148, 165, 182, 199, 216, 233 },
+ { 17, 23, 35, 46, 56, 77, 92, 106, 123, 134, 152, 167, 185, 204, 222, 237 },
+ { 14, 17, 45, 53, 63, 75, 89, 107, 115, 132, 151, 171, 188, 206, 221, 240 },
+ { 9, 16, 29, 40, 56, 71, 88, 103, 119, 137, 154, 171, 189, 205, 222, 237 },
+ { 16, 19, 36, 48, 57, 76, 87, 105, 118, 132, 150, 167, 185, 202, 218, 236 },
+ { 12, 17, 29, 54, 71, 81, 94, 104, 126, 136, 149, 164, 182, 201, 221, 237 },
+ { 15, 28, 47, 62, 79, 97, 115, 129, 142, 155, 168, 180, 194, 208, 223, 238 },
+ { 8, 14, 30, 45, 62, 78, 94, 111, 127, 143, 159, 175, 192, 207, 223, 239 },
+ { 17, 30, 49, 62, 79, 92, 107, 119, 132, 145, 160, 174, 190, 204, 220, 235 },
+ { 14, 19, 36, 45, 61, 76, 91, 108, 121, 138, 154, 172, 189, 205, 222, 238 },
+ { 12, 18, 31, 45, 60, 76, 91, 107, 123, 138, 154, 171, 187, 204, 221, 236 },
+ { 13, 17, 31, 43, 53, 70, 83, 103, 114, 131, 149, 167, 185, 203, 220, 237 },
+ { 17, 22, 35, 42, 58, 78, 93, 110, 125, 139, 155, 170, 188, 206, 224, 240 },
+ { 8, 15, 34, 50, 67, 83, 99, 115, 131, 146, 162, 178, 193, 209, 224, 239 },
+ { 13, 16, 41, 66, 73, 86, 95, 111, 128, 137, 150, 163, 183, 206, 225, 241 },
+ { 17, 25, 37, 52, 63, 75, 92, 102, 119, 132, 144, 160, 175, 191, 212, 231 },
+ { 19, 31, 49, 65, 83, 100, 117, 133, 147, 161, 174, 187, 200, 213, 227, 242 },
+ { 18, 31, 52, 68, 88, 103, 117, 126, 138, 149, 163, 177, 192, 207, 223, 239 },
+ { 16, 29, 47, 61, 76, 90, 106, 119, 133, 147, 161, 176, 193, 209, 224, 240 },
+ { 15, 21, 35, 50, 61, 73, 86, 97, 110, 119, 129, 141, 175, 198, 218, 237 }
+};
+
+static const uint16_t silk_lsf_min_spacing_nbmb[] = {
+ 250, 3, 6, 3, 3, 3, 4, 3, 3, 3, 461
+};
+
+static const uint16_t silk_lsf_min_spacing_wb[] = {
+ 100, 3, 40, 3, 3, 3, 5, 14, 14, 10, 11, 3, 8, 9, 7, 3, 347
+};
+
+static const uint8_t silk_lsf_ordering_nbmb[] = {
+ 0, 9, 6, 3, 4, 5, 8, 1, 2, 7
+};
+
+static const uint8_t silk_lsf_ordering_wb[] = {
+ 0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1
+};
+
+static const int16_t silk_cosine[] = { /* (0.12) */
+ 4096, 4095, 4091, 4085,
+ 4076, 4065, 4052, 4036,
+ 4017, 3997, 3973, 3948,
+ 3920, 3889, 3857, 3822,
+ 3784, 3745, 3703, 3659,
+ 3613, 3564, 3513, 3461,
+ 3406, 3349, 3290, 3229,
+ 3166, 3102, 3035, 2967,
+ 2896, 2824, 2751, 2676,
+ 2599, 2520, 2440, 2359,
+ 2276, 2191, 2106, 2019,
+ 1931, 1842, 1751, 1660,
+ 1568, 1474, 1380, 1285,
+ 1189, 1093, 995, 897,
+ 799, 700, 601, 501,
+ 401, 301, 201, 101,
+ 0, -101, -201, -301,
+ -401, -501, -601, -700,
+ -799, -897, -995, -1093,
+ -1189, -1285, -1380, -1474,
+ -1568, -1660, -1751, -1842,
+ -1931, -2019, -2106, -2191,
+ -2276, -2359, -2440, -2520,
+ -2599, -2676, -2751, -2824,
+ -2896, -2967, -3035, -3102,
+ -3166, -3229, -3290, -3349,
+ -3406, -3461, -3513, -3564,
+ -3613, -3659, -3703, -3745,
+ -3784, -3822, -3857, -3889,
+ -3920, -3948, -3973, -3997,
+ -4017, -4036, -4052, -4065,
+ -4076, -4085, -4091, -4095,
+ -4096
+};
+
+static const uint16_t silk_pitch_scale[] = { 4, 6, 8};
+
+static const uint16_t silk_pitch_min_lag[] = { 16, 24, 32};
+
+static const uint16_t silk_pitch_max_lag[] = {144, 216, 288};
+
+static const int8_t silk_pitch_offset_nb10ms[3][2] = {
+ { 0, 0},
+ { 1, 0},
+ { 0, 1}
+};
+
+static const int8_t silk_pitch_offset_nb20ms[11][4] = {
+ { 0, 0, 0, 0},
+ { 2, 1, 0, -1},
+ {-1, 0, 1, 2},
+ {-1, 0, 0, 1},
+ {-1, 0, 0, 0},
+ { 0, 0, 0, 1},
+ { 0, 0, 1, 1},
+ { 1, 1, 0, 0},
+ { 1, 0, 0, 0},
+ { 0, 0, 0, -1},
+ { 1, 0, 0, -1}
+};
+
+static const int8_t silk_pitch_offset_mbwb10ms[12][2] = {
+ { 0, 0},
+ { 0, 1},
+ { 1, 0},
+ {-1, 1},
+ { 1, -1},
+ {-1, 2},
+ { 2, -1},
+ {-2, 2},
+ { 2, -2},
+ {-2, 3},
+ { 3, -2},
+ {-3, 3}
+};
+
+static const int8_t silk_pitch_offset_mbwb20ms[34][4] = {
+ { 0, 0, 0, 0},
+ { 0, 0, 1, 1},
+ { 1, 1, 0, 0},
+ {-1, 0, 0, 0},
+ { 0, 0, 0, 1},
+ { 1, 0, 0, 0},
+ {-1, 0, 0, 1},
+ { 0, 0, 0, -1},
+ {-1, 0, 1, 2},
+ { 1, 0, 0, -1},
+ {-2, -1, 1, 2},
+ { 2, 1, 0, -1},
+ {-2, 0, 0, 2},
+ {-2, 0, 1, 3},
+ { 2, 1, -1, -2},
+ {-3, -1, 1, 3},
+ { 2, 0, 0, -2},
+ { 3, 1, 0, -2},
+ {-3, -1, 2, 4},
+ {-4, -1, 1, 4},
+ { 3, 1, -1, -3},
+ {-4, -1, 2, 5},
+ { 4, 2, -1, -3},
+ { 4, 1, -1, -4},
+ {-5, -1, 2, 6},
+ { 5, 2, -1, -4},
+ {-6, -2, 2, 6},
+ {-5, -2, 2, 5},
+ { 6, 2, -1, -5},
+ {-7, -2, 3, 8},
+ { 6, 2, -2, -6},
+ { 5, 2, -2, -5},
+ { 8, 3, -2, -7},
+ {-9, -3, 3, 9}
+};
+
+static const int8_t silk_ltp_filter0_taps[8][5] = {
+ { 4, 6, 24, 7, 5},
+ { 0, 0, 2, 0, 0},
+ { 12, 28, 41, 13, -4},
+ { -9, 15, 42, 25, 14},
+ { 1, -2, 62, 41, -9},
+ {-10, 37, 65, -4, 3},
+ { -6, 4, 66, 7, -8},
+ { 16, 14, 38, -3, 33}
+};
+
+static const int8_t silk_ltp_filter1_taps[16][5] = {
+ { 13, 22, 39, 23, 12},
+ { -1, 36, 64, 27, -6},
+ { -7, 10, 55, 43, 17},
+ { 1, 1, 8, 1, 1},
+ { 6, -11, 74, 53, -9},
+ {-12, 55, 76, -12, 8},
+ { -3, 3, 93, 27, -4},
+ { 26, 39, 59, 3, -8},
+ { 2, 0, 77, 11, 9},
+ { -8, 22, 44, -6, 7},
+ { 40, 9, 26, 3, 9},
+ { -7, 20, 101, -7, 4},
+ { 3, -8, 42, 26, 0},
+ {-15, 33, 68, 2, 23},
+ { -2, 55, 46, -2, 15},
+ { 3, -1, 21, 16, 41}
+};
+
+static const int8_t silk_ltp_filter2_taps[32][5] = {
+ { -6, 27, 61, 39, 5},
+ {-11, 42, 88, 4, 1},
+ { -2, 60, 65, 6, -4},
+ { -1, -5, 73, 56, 1},
+ { -9, 19, 94, 29, -9},
+ { 0, 12, 99, 6, 4},
+ { 8, -19, 102, 46, -13},
+ { 3, 2, 13, 3, 2},
+ { 9, -21, 84, 72, -18},
+ {-11, 46, 104, -22, 8},
+ { 18, 38, 48, 23, 0},
+ {-16, 70, 83, -21, 11},
+ { 5, -11, 117, 22, -8},
+ { -6, 23, 117, -12, 3},
+ { 3, -8, 95, 28, 4},
+ {-10, 15, 77, 60, -15},
+ { -1, 4, 124, 2, -4},
+ { 3, 38, 84, 24, -25},
+ { 2, 13, 42, 13, 31},
+ { 21, -4, 56, 46, -1},
+ { -1, 35, 79, -13, 19},
+ { -7, 65, 88, -9, -14},
+ { 20, 4, 81, 49, -29},
+ { 20, 0, 75, 3, -17},
+ { 5, -9, 44, 92, -8},
+ { 1, -3, 22, 69, 31},
+ { -6, 95, 41, -12, 5},
+ { 39, 67, 16, -4, 1},
+ { 0, -6, 120, 55, -36},
+ {-13, 44, 122, 4, -24},
+ { 81, 5, 11, 3, 7},
+ { 2, 0, 9, 10, 88}
+};
+
+static const uint16_t silk_ltp_scale_factor[] = {15565, 12288, 8192};
+
+static const uint8_t silk_shell_blocks[3][2] = {
+ { 5, 10}, // NB
+ { 8, 15}, // MB
+ {10, 20} // WB
+};
+
+static const uint8_t silk_quant_offset[2][2] = { /* (0.23) */
+ {25, 60}, // Inactive or Unvoiced
+ { 8, 25} // Voiced
+};
+
+static const int silk_stereo_interp_len[3] = {
+ 64, 96, 128
+};
+
+static inline void silk_stabilize_lsf(int16_t nlsf[16], int order, const uint16_t min_delta[17])
+{
+ int pass, i;
+ for (pass = 0; pass < 20; pass++) {
+ int k, min_diff = 0;
+ for (i = 0; i < order+1; i++) {
+ int low = i != 0 ? nlsf[i-1] : 0;
+ int high = i != order ? nlsf[i] : 32768;
+ int diff = (high - low) - (min_delta[i]);
+
+ if (diff < min_diff) {
+ min_diff = diff;
+ k = i;
+
+ if (pass == 20)
+ break;
+ }
+ }
+ if (min_diff == 0) /* no issues; stabilized */
+ return;
+
+ /* wiggle one or two LSFs */
+ if (k == 0) {
+ /* repel away from lower bound */
+ nlsf[0] = min_delta[0];
+ } else if (k == order) {
+ /* repel away from higher bound */
+ nlsf[order-1] = 32768 - min_delta[order];
+ } else {
+ /* repel away from current position */
+ int min_center = 0, max_center = 32768, center_val;
+
+ /* lower extent */
+ for (i = 0; i < k; i++)
+ min_center += min_delta[i];
+ min_center += min_delta[k] >> 1;
+
+ /* upper extent */
+ for (i = order; i > k; i--)
+ max_center -= min_delta[i];
+ max_center -= min_delta[k] >> 1;
+
+ /* move apart */
+ center_val = nlsf[k - 1] + nlsf[k];
+ center_val = (center_val >> 1) + (center_val & 1); // rounded divide by 2
+ center_val = FFMIN(max_center, FFMAX(min_center, center_val));
+
+ nlsf[k - 1] = center_val - (min_delta[k] >> 1);
+ nlsf[k] = nlsf[k - 1] + min_delta[k];
+ }
+ }
+
+ /* resort to the fall-back method, the standard method for LSF stabilization */
+
+ /* sort; as the LSFs should be nearly sorted, use insertion sort */
+ for (i = 1; i < order; i++) {
+ int j, value = nlsf[i];
+ for (j = i - 1; j >= 0 && nlsf[j] > value; j--)
+ nlsf[j + 1] = nlsf[j];
+ nlsf[j + 1] = value;
+ }
+
+ /* push forwards to increase distance */
+ if (nlsf[0] < min_delta[0])
+ nlsf[0] = min_delta[0];
+ for (i = 1; i < order; i++)
+ nlsf[i] = FFMAX(nlsf[i], FFMIN(nlsf[i - 1] + min_delta[i], 32767));
+
+ /* push backwards to increase distance */
+ if (nlsf[order-1] > 32768 - min_delta[order])
+ nlsf[order-1] = 32768 - min_delta[order];
+ for (i = order-2; i >= 0; i--)
+ if (nlsf[i] > nlsf[i + 1] - min_delta[i+1])
+ nlsf[i] = nlsf[i + 1] - min_delta[i+1];
+
+ return;
+}
+
+static inline int silk_is_lpc_stable(const int16_t lpc[16], int order)
+{
+ int k, j, DC_resp = 0;
+ int32_t lpc32[2][16]; // Q24
+ int totalinvgain = 1 << 30; // 1.0 in Q30
+ int32_t *row = lpc32[0], *prevrow;
+
+ /* initialize the first row for the Levinson recursion */
+ for (k = 0; k < order; k++) {
+ DC_resp += lpc[k];
+ row[k] = lpc[k] * 4096;
+ }
+
+ if (DC_resp >= 4096)
+ return 0;
+
+ /* check if prediction gain pushes any coefficients too far */
+ for (k = order - 1; 1; k--) {
+ int rc; // Q31; reflection coefficient
+ int gaindiv; // Q30; inverse of the gain (the divisor)
+ int gain; // gain for this reflection coefficient
+ int fbits; // fractional bits used for the gain
+ int error; // Q29; estimate of the error of our partial estimate of 1/gaindiv
+
+ if (FFABS(row[k]) > 16773022)
+ return 0;
+
+ rc = -(row[k] * 128);
+ gaindiv = (1 << 30) - MULH(rc, rc);
+
+ totalinvgain = MULH(totalinvgain, gaindiv) << 2;
+ if (k == 0)
+ return (totalinvgain >= 107374);
+
+ /* approximate 1.0/gaindiv */
+ fbits = opus_ilog(gaindiv);
+ gain = ((1 << 29) - 1) / (gaindiv >> (fbits + 1 - 16)); // Q<fbits-16>
+ error = (1 << 29) - MULL(gaindiv << (15 + 16 - fbits), gain, 16);
+ gain = ((gain << 16) + (error * gain >> 13));
+
+ /* switch to the next row of the LPC coefficients */
+ prevrow = row;
+ row = lpc32[k & 1];
+
+ for (j = 0; j < k; j++) {
+ int x = prevrow[j] - ROUND_MULL(prevrow[k - j - 1], rc, 31);
+ row[j] = ROUND_MULL(x, gain, fbits);
+ }
+ }
+}
+
+static void silk_lsp2poly(const int32_t lsp[16], int32_t pol[16], int half_order)
+{
+ int i, j;
+
+ pol[0] = 65536; // 1.0 in Q16
+ pol[1] = -lsp[0];
+
+ for (i = 1; i < half_order; i++) {
+ pol[i + 1] = pol[i - 1] * 2 - ROUND_MULL(lsp[2 * i], pol[i], 16);
+ for (j = i; j > 1; j--)
+ pol[j] += pol[j - 2] - ROUND_MULL(lsp[2 * i], pol[j - 1], 16);
+
+ pol[1] -= lsp[2 * i];
+ }
+}
+
+static void silk_lsf2lpc(const int16_t nlsf[16], float lpcf[16], int order)
+{
+ int i, k;
+ int32_t lsp[16]; // Q17; 2*cos(LSF)
+ int32_t p[9], q[9]; // Q16
+ int32_t lpc32[16]; // Q17
+ int16_t lpc[16]; // Q12
+
+ /* convert the LSFs to LSPs, i.e. 2*cos(LSF) */
+ for (k = 0; k < order; k++) {
+ int index = nlsf[k] >> 8;
+ int offset = nlsf[k] & 255;
+ int k2 = (order == 10) ? silk_lsf_ordering_nbmb[k] : silk_lsf_ordering_wb[k];
+
+ /* interpolate and round */
+ lsp[k2] = silk_cosine[index] * 256;
+ lsp[k2] += (silk_cosine[index + 1] - silk_cosine[index]) * offset;
+ lsp[k2] = (lsp[k2] + 4) >> 3;
+ }
+
+ silk_lsp2poly(lsp , p, order >> 1);
+ silk_lsp2poly(lsp + 1, q, order >> 1);
+
+ /* reconstruct A(z) */
+ for (k = 0; k < order>>1; k++) {
+ lpc32[k] = -p[k + 1] - p[k] - q[k + 1] + q[k];
+ lpc32[order-k-1] = -p[k + 1] - p[k] + q[k + 1] - q[k];
+ }
+
+ /* limit the range of the LPC coefficients to each fit within an int16_t */
+ for (i = 0; i < 10; i++) {
+ int j;
+ unsigned int maxabs = 0;
+ for (j = 0, k = 0; j < order; j++) {
+ unsigned int x = FFABS(lpc32[k]);
+ if (x > maxabs) {
+ maxabs = x; // Q17
+ k = j;
+ }
+ }
+
+ maxabs = (maxabs + 16) >> 5; // convert to Q12
+
+ if (maxabs > 32767) {
+ /* perform bandwidth expansion */
+ unsigned int chirp, chirp_base; // Q16
+ maxabs = FFMIN(maxabs, 163838); // anything above this overflows chirp's numerator
+ chirp_base = chirp = 65470 - ((maxabs - 32767) << 14) / ((maxabs * (k+1)) >> 2);
+
+ for (k = 0; k < order; k++) {
+ lpc32[k] = ROUND_MULL(lpc32[k], chirp, 16);
+ chirp = (chirp_base * chirp + 32768) >> 16;
+ }
+ } else break;
+ }
+
+ if (i == 10) {
+ /* time's up: just clamp */
+ for (k = 0; k < order; k++) {
+ int x = (lpc32[k] + 16) >> 5;
+ lpc[k] = av_clip_int16(x);
+ lpc32[k] = lpc[k] << 5; // shortcut mandated by the spec; drops lower 5 bits
+ }
+ } else {
+ for (k = 0; k < order; k++)
+ lpc[k] = (lpc32[k] + 16) >> 5;
+ }
+
+ /* if the prediction gain causes the LPC filter to become unstable,
+ apply further bandwidth expansion on the Q17 coefficients */
+ for (i = 1; i <= 16 && !silk_is_lpc_stable(lpc, order); i++) {
+ unsigned int chirp, chirp_base;
+ chirp_base = chirp = 65536 - (1 << i);
+
+ for (k = 0; k < order; k++) {
+ lpc32[k] = ROUND_MULL(lpc32[k], chirp, 16);
+ lpc[k] = (lpc32[k] + 16) >> 5;
+ chirp = (chirp_base * chirp + 32768) >> 16;
+ }
+ }
+
+ for (i = 0; i < order; i++)
+ lpcf[i] = lpc[i] / 4096.0f;
+}
+
+static inline void silk_decode_lpc(SilkContext *s, SilkFrame *frame,
+ OpusRangeCoder *rc,
+ float lpc_leadin[16], float lpc[16],
+ int *lpc_order, int *has_lpc_leadin, int voiced)
+{
+ int i;
+ int order; // order of the LP polynomial; 10 for NB/MB and 16 for WB
+ int8_t lsf_i1, lsf_i2[16]; // stage-1 and stage-2 codebook indices
+ int16_t lsf_res[16]; // residual as a Q10 value
+ int16_t nlsf[16]; // Q15
+
+ *lpc_order = order = s->wb ? 16 : 10;
+
+ /* obtain LSF stage-1 and stage-2 indices */
+ lsf_i1 = opus_rc_getsymbol(rc, silk_model_lsf_s1[s->wb][voiced]);
+ for (i = 0; i < order; i++) {
+ int index = s->wb ? silk_lsf_s2_model_sel_wb [lsf_i1][i] :
+ silk_lsf_s2_model_sel_nbmb[lsf_i1][i];
+ lsf_i2[i] = opus_rc_getsymbol(rc, silk_model_lsf_s2[index]) - 4;
+ if (lsf_i2[i] == -4)
+ lsf_i2[i] -= opus_rc_getsymbol(rc, silk_model_lsf_s2_ext);
+ else if (lsf_i2[i] == 4)
+ lsf_i2[i] += opus_rc_getsymbol(rc, silk_model_lsf_s2_ext);
+ }
+
+ /* reverse the backwards-prediction step */
+ for (i = order - 1; i >= 0; i--) {
+ int qstep = s->wb ? 9830 : 11796;
+
+ lsf_res[i] = lsf_i2[i] * 1024;
+ if (lsf_i2[i] < 0) lsf_res[i] += 102;
+ else if (lsf_i2[i] > 0) lsf_res[i] -= 102;
+ lsf_res[i] = (lsf_res[i] * qstep) >> 16;
+
+ if (i + 1 < order) {
+ int weight = s->wb ? silk_lsf_pred_weights_wb [silk_lsf_weight_sel_wb [lsf_i1][i]][i] :
+ silk_lsf_pred_weights_nbmb[silk_lsf_weight_sel_nbmb[lsf_i1][i]][i];
+ lsf_res[i] += (lsf_res[i+1] * weight) >> 8;
+ }
+ }
+
+ /* reconstruct the NLSF coefficients from the supplied indices */
+ for (i = 0; i < order; i++) {
+ const uint8_t * codebook = s->wb ? silk_lsf_codebook_wb [lsf_i1] :
+ silk_lsf_codebook_nbmb[lsf_i1];
+ int cur, prev, next, weight_sq, weight, ipart, fpart, y, value;
+
+ /* find the weight of the residual */
+ /* TODO: precompute */
+ cur = codebook[i];
+ prev = i ? codebook[i - 1] : 0;
+ next = i + 1 < order ? codebook[i + 1] : 256;
+ weight_sq = (1024 / (cur - prev) + 1024 / (next - cur)) << 16;
+
+ /* approximate square-root with mandated fixed-point arithmetic */
+ ipart = opus_ilog(weight_sq);
+ fpart = (weight_sq >> (ipart-8)) & 127;
+ y = ((ipart & 1) ? 32768 : 46214) >> ((32 - ipart)>>1);
+ weight = y + ((213 * fpart * y) >> 16);
+
+ value = cur * 128 + (lsf_res[i] * 16384) / weight;
+ nlsf[i] = av_clip_uintp2(value, 15);
+ }
+
+ /* stabilize the NLSF coefficients */
+ silk_stabilize_lsf(nlsf, order, s->wb ? silk_lsf_min_spacing_wb :
+ silk_lsf_min_spacing_nbmb);
+
+ /* produce an interpolation for the first 2 subframes, */
+ /* and then convert both sets of NLSFs to LPC coefficients */
+ *has_lpc_leadin = 0;
+ if (s->subframes == 4) {
+ int offset = opus_rc_getsymbol(rc, silk_model_lsf_interpolation_offset);
+ if (offset != 4 && frame->coded) {
+ *has_lpc_leadin = 1;
+ if (offset != 0) {
+ int16_t nlsf_leadin[16];
+ for (i = 0; i < order; i++)
+ nlsf_leadin[i] = frame->nlsf[i] +
+ ((nlsf[i] - frame->nlsf[i]) * offset >> 2);
+ silk_lsf2lpc(nlsf_leadin, lpc_leadin, order);
+ } else /* avoid re-computation for a (roughly) 1-in-4 occurrence */
+ memcpy(lpc_leadin, frame->lpc, 16 * sizeof(float));
+ } else
+ offset = 4;
+ s->nlsf_interp_factor = offset;
+
+ silk_lsf2lpc(nlsf, lpc, order);
+ } else {
+ s->nlsf_interp_factor = 4;
+ silk_lsf2lpc(nlsf, lpc, order);
+ }
+
+ memcpy(frame->nlsf, nlsf, order * sizeof(nlsf[0]));
+ memcpy(frame->lpc, lpc, order * sizeof(lpc[0]));
+}
+
+static inline void silk_count_children(OpusRangeCoder *rc, int model, int32_t total,
+ int32_t child[2])
+{
+ if (total != 0) {
+ child[0] = opus_rc_getsymbol(rc,
+ silk_model_pulse_location[model] + (((total - 1 + 5) * (total - 1)) >> 1));
+ child[1] = total - child[0];
+ } else {
+ child[0] = 0;
+ child[1] = 0;
+ }
+}
+
+static inline void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc,
+ float* excitationf,
+ int qoffset_high, int active, int voiced)
+{
+ int i;
+ uint32_t seed;
+ int shellblocks;
+ int ratelevel;
+ uint8_t pulsecount[20]; // total pulses in each shell block
+ uint8_t lsbcount[20] = {0}; // raw lsbits defined for each pulse in each shell block
+ int32_t excitation[320]; // Q23
+
+ /* excitation parameters */
+ seed = opus_rc_getsymbol(rc, silk_model_lcg_seed);
+ shellblocks = silk_shell_blocks[s->bandwidth][s->subframes >> 2];
+ ratelevel = opus_rc_getsymbol(rc, silk_model_exc_rate[voiced]);
+
+ for (i = 0; i < shellblocks; i++) {
+ pulsecount[i] = opus_rc_getsymbol(rc, silk_model_pulse_count[ratelevel]);
+ if (pulsecount[i] == 17) {
+ while (pulsecount[i] == 17 && ++lsbcount[i] != 10)
+ pulsecount[i] = opus_rc_getsymbol(rc, silk_model_pulse_count[9]);
+ if (lsbcount[i] == 10)
+ pulsecount[i] = opus_rc_getsymbol(rc, silk_model_pulse_count[10]);
+ }
+ }
+
+ /* decode pulse locations using PVQ */
+ for (i = 0; i < shellblocks; i++) {
+ if (pulsecount[i] != 0) {
+ int a, b, c, d;
+ int32_t * location = excitation + 16*i;
+ int32_t branch[4][2];
+ branch[0][0] = pulsecount[i];
+
+ /* unrolled tail recursion */
+ for (a = 0; a < 1; a++) {
+ silk_count_children(rc, 0, branch[0][a], branch[1]);
+ for (b = 0; b < 2; b++) {
+ silk_count_children(rc, 1, branch[1][b], branch[2]);
+ for (c = 0; c < 2; c++) {
+ silk_count_children(rc, 2, branch[2][c], branch[3]);
+ for (d = 0; d < 2; d++) {
+ silk_count_children(rc, 3, branch[3][d], location);
+ location += 2;
+ }
+ }
+ }
+ }
+ } else
+ memset(excitation + 16*i, 0, 16*sizeof(int32_t));
+ }
+
+ /* decode least significant bits */
+ for (i = 0; i < shellblocks << 4; i++) {
+ int bit;
+ for (bit = 0; bit < lsbcount[i >> 4]; bit++)
+ excitation[i] = (excitation[i] << 1) |
+ opus_rc_getsymbol(rc, silk_model_excitation_lsb);
+ }
+
+ /* decode signs */
+ for (i = 0; i < shellblocks << 4; i++) {
+ if (excitation[i] != 0) {
+ int sign = opus_rc_getsymbol(rc, silk_model_excitation_sign[active +
+ voiced][qoffset_high][FFMIN(pulsecount[i >> 4], 6)]);
+ if (sign == 0)
+ excitation[i] *= -1;
+ }
+ }
+
+ /* assemble the excitation */
+ for (i = 0; i < shellblocks << 4; i++) {
+ int value = excitation[i];
+ excitation[i] = value * 256 | silk_quant_offset[voiced][qoffset_high];
+ if (value < 0) excitation[i] += 20;
+ else if (value > 0) excitation[i] -= 20;
+
+ /* invert samples pseudorandomly */
+ seed = 196314165 * seed + 907633515;
+ if (seed & 0x80000000)
+ excitation[i] *= -1;
+ seed += value;
+
+ excitationf[i] = excitation[i] / 8388608.0f;
+ }
+}
+
+/** Maximum residual history according to 4.2.7.6.1 */
+#define SILK_MAX_LAG (288 + LTP_ORDER / 2)
+
+/** Order of the LTP filter */
+#define LTP_ORDER 5
+
+static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
+ int frame_num, int channel, int coded_channels, int active, int active1)
+{
+ /* per frame */
+ int voiced; // combines with active to indicate inactive, active, or active+voiced
+ int qoffset_high;
+ int order; // order of the LPC coefficients
+ float lpc_leadin[16], lpc_body[16], residual[SILK_MAX_LAG + SILK_HISTORY];
+ int has_lpc_leadin;
+ float ltpscale;
+
+ /* per subframe */
+ struct {
+ float gain;
+ int pitchlag;
+ float ltptaps[5];
+ } sf[4];
+
+ SilkFrame * const frame = s->frame + channel;
+
+ int i;
+
+ /* obtain stereo weights */
+ if (coded_channels == 2 && channel == 0) {
+ int n, wi[2], ws[2], w[2];
+ n = opus_rc_getsymbol(rc, silk_model_stereo_s1);
+ wi[0] = opus_rc_getsymbol(rc, silk_model_stereo_s2) + 3 * (n / 5);
+ ws[0] = opus_rc_getsymbol(rc, silk_model_stereo_s3);
+ wi[1] = opus_rc_getsymbol(rc, silk_model_stereo_s2) + 3 * (n % 5);
+ ws[1] = opus_rc_getsymbol(rc, silk_model_stereo_s3);
+
+ for (i = 0; i < 2; i++)
+ w[i] = silk_stereo_weights[wi[i]] +
+ (((silk_stereo_weights[wi[i] + 1] - silk_stereo_weights[wi[i]]) * 6554) >> 16)
+ * (ws[i]*2 + 1);
+
+ s->stereo_weights[0] = (w[0] - w[1]) / 8192.0;
+ s->stereo_weights[1] = w[1] / 8192.0;
+
+ /* and read the mid-only flag */
+ s->midonly = active1 ? 0 : opus_rc_getsymbol(rc, silk_model_mid_only);
+ }
+
+ /* obtain frame type */
+ if (!active) {
+ qoffset_high = opus_rc_getsymbol(rc, silk_model_frame_type_inactive);
+ voiced = 0;
+ } else {
+ int type = opus_rc_getsymbol(rc, silk_model_frame_type_active);
+ qoffset_high = type & 1;
+ voiced = type >> 1;
+ }
+
+ /* obtain subframe quantization gains */
+ for (i = 0; i < s->subframes; i++) {
+ int log_gain; //Q7
+ int ipart, fpart, lingain;
+
+ if (i == 0 && (frame_num == 0 || !frame->coded)) {
+ /* gain is coded absolute */
+ int x = opus_rc_getsymbol(rc, silk_model_gain_highbits[active + voiced]);
+ log_gain = (x<<3) | opus_rc_getsymbol(rc, silk_model_gain_lowbits);
+
+ if (frame->coded)
+ log_gain = FFMAX(log_gain, frame->log_gain - 16);
+ } else {
+ /* gain is coded relative */
+ int delta_gain = opus_rc_getsymbol(rc, silk_model_gain_delta);
+ log_gain = av_clip_uintp2(FFMAX((delta_gain<<1) - 16,
+ frame->log_gain + delta_gain - 4), 6);
+ }
+
+ frame->log_gain = log_gain;
+
+ /* approximate 2**(x/128) with a Q7 (i.e. non-integer) input */
+ log_gain = (log_gain * 0x1D1C71 >> 16) + 2090;
+ ipart = log_gain >> 7;
+ fpart = log_gain & 127;
+ lingain = (1 << ipart) + ((-174 * fpart * (128-fpart) >>16) + fpart) * ((1<<ipart) >> 7);
+ sf[i].gain = lingain / 65536.0f;
+ }
+
+ /* obtain LPC filter coefficients */
+ silk_decode_lpc(s, frame, rc, lpc_leadin, lpc_body, &order, &has_lpc_leadin, voiced);
+
+ /* obtain pitch lags, if this is a voiced frame */
+ if (voiced) {
+ int lag_absolute = (!frame_num || !frame->prev_voiced);
+ int primarylag; // primary pitch lag for the entire SILK frame
+ int ltpfilter;
+ const int8_t * offsets;
+
+ if (!lag_absolute) {
+ int delta = opus_rc_getsymbol(rc, silk_model_pitch_delta);
+ if (delta)
+ primarylag = frame->primarylag + delta - 9;
+ else
+ lag_absolute = 1;
+ }
+
+ if (lag_absolute) {
+ /* primary lag is coded absolute */
+ int highbits, lowbits;
+ const uint16_t *model[] = {
+ silk_model_pitch_lowbits_nb, silk_model_pitch_lowbits_mb,
+ silk_model_pitch_lowbits_wb
+ };
+ highbits = opus_rc_getsymbol(rc, silk_model_pitch_highbits);
+ lowbits = opus_rc_getsymbol(rc, model[s->bandwidth]);
+
+ primarylag = silk_pitch_min_lag[s->bandwidth] +
+ highbits*silk_pitch_scale[s->bandwidth] + lowbits;
+ }
+ frame->primarylag = primarylag;
+
+ if (s->subframes == 2)
+ offsets = (s->bandwidth == OPUS_BANDWIDTH_NARROWBAND)
+ ? silk_pitch_offset_nb10ms[opus_rc_getsymbol(rc,
+ silk_model_pitch_contour_nb10ms)]
+ : silk_pitch_offset_mbwb10ms[opus_rc_getsymbol(rc,
+ silk_model_pitch_contour_mbwb10ms)];
+ else
+ offsets = (s->bandwidth == OPUS_BANDWIDTH_NARROWBAND)
+ ? silk_pitch_offset_nb20ms[opus_rc_getsymbol(rc,
+ silk_model_pitch_contour_nb20ms)]
+ : silk_pitch_offset_mbwb20ms[opus_rc_getsymbol(rc,
+ silk_model_pitch_contour_mbwb20ms)];
+
+ for (i = 0; i < s->subframes; i++)
+ sf[i].pitchlag = av_clip(primarylag + offsets[i],
+ silk_pitch_min_lag[s->bandwidth],
+ silk_pitch_max_lag[s->bandwidth]);
+
+ /* obtain LTP filter coefficients */
+ ltpfilter = opus_rc_getsymbol(rc, silk_model_ltp_filter);
+ for (i = 0; i < s->subframes; i++) {
+ int index, j;
+ const uint16_t *filter_sel[] = {
+ silk_model_ltp_filter0_sel, silk_model_ltp_filter1_sel,
+ silk_model_ltp_filter2_sel
+ };
+ const int8_t (*filter_taps[])[5] = {
+ silk_ltp_filter0_taps, silk_ltp_filter1_taps, silk_ltp_filter2_taps
+ };
+ index = opus_rc_getsymbol(rc, filter_sel[ltpfilter]);
+ for (j = 0; j < 5; j++)
+ sf[i].ltptaps[j] = filter_taps[ltpfilter][index][j] / 128.0f;
+ }
+ }
+
+ /* obtain LTP scale factor */
+ if (voiced && frame_num == 0)
+ ltpscale = silk_ltp_scale_factor[opus_rc_getsymbol(rc,
+ silk_model_ltp_scale_index)] / 16384.0f;
+ else ltpscale = 15565.0f/16384.0f;
+
+ /* generate the excitation signal for the entire frame */
+ silk_decode_excitation(s, rc, residual + SILK_MAX_LAG, qoffset_high,
+ active, voiced);
+
+ /* skip synthesising the side channel if we want mono-only */
+ if (s->output_channels == channel)
+ return;
+
+ /* generate the output signal */
+ for (i = 0; i < s->subframes; i++) {
+ const float * lpc_coeff = (i < 2 && has_lpc_leadin) ? lpc_leadin : lpc_body;
+ float *dst = frame->output + SILK_HISTORY + i * s->sflength;
+ float *resptr = residual + SILK_MAX_LAG + i * s->sflength;
+ float *lpc = frame->lpc_history + SILK_HISTORY + i * s->sflength;
+ float sum;
+ int j, k;
+
+ if (voiced) {
+ int out_end;
+ float scale;
+
+ if (i < 2 || s->nlsf_interp_factor == 4) {
+ out_end = -i * s->sflength;
+ scale = ltpscale;
+ } else {
+ out_end = -(i - 2) * s->sflength;
+ scale = 1.0f;
+ }
+
+ /* when the LPC coefficients change, a re-whitening filter is used */
+ /* to produce a residual that accounts for the change */
+ for (j = - sf[i].pitchlag - LTP_ORDER/2; j < out_end; j++) {
+ sum = dst[j];
+ for (k = 0; k < order; k++)
+ sum -= lpc_coeff[k] * dst[j - k - 1];
+ resptr[j] = av_clipf(sum, -1.0f, 1.0f) * scale / sf[i].gain;
+ }
+
+ if (out_end) {
+ float rescale = sf[i-1].gain / sf[i].gain;
+ for (j = out_end; j < 0; j++)
+ resptr[j] *= rescale;
+ }
+
+ /* LTP synthesis */
+ for (j = 0; j < s->sflength; j++) {
+ sum = resptr[j];
+ for (k = 0; k < LTP_ORDER; k++)
+ sum += sf[i].ltptaps[k] * resptr[j - sf[i].pitchlag + LTP_ORDER/2 - k];
+ resptr[j] = sum;
+ }
+ }
+
+ /* LPC synthesis */
+ for (j = 0; j < s->sflength; j++) {
+ sum = resptr[j] * sf[i].gain;
+ for (k = 1; k <= order; k++)
+ sum += lpc_coeff[k - 1] * lpc[j - k];
+
+ lpc[j] = sum;
+ dst[j] = av_clipf(sum, -1.0f, 1.0f);
+ }
+ }
+
+ frame->prev_voiced = voiced;
+ memmove(frame->lpc_history, frame->lpc_history + s->flength, SILK_HISTORY * sizeof(float));
+ memmove(frame->output, frame->output + s->flength, SILK_HISTORY * sizeof(float));
+
+ frame->coded = 1;
+}
+
+static void silk_unmix_ms(SilkContext *s, float *l, float *r)
+{
+ float *mid = s->frame[0].output + SILK_HISTORY - s->flength;
+ float *side = s->frame[1].output + SILK_HISTORY - s->flength;
+ float w0_prev = s->prev_stereo_weights[0];
+ float w1_prev = s->prev_stereo_weights[1];
+ float w0 = s->stereo_weights[0];
+ float w1 = s->stereo_weights[1];
+ int n1 = silk_stereo_interp_len[s->bandwidth];
+ int i;
+
+ for (i = 0; i < n1; i++) {
+ float interp0 = w0_prev + i * (w0 - w0_prev) / n1;
+ float interp1 = w1_prev + i * (w1 - w1_prev) / n1;
+ float p0 = 0.25 * (mid[i - 2] + 2 * mid[i - 1] + mid[i]);
+
+ l[i] = av_clipf((1 + interp1) * mid[i - 1] + side[i - 1] + interp0 * p0, -1.0, 1.0);
+ r[i] = av_clipf((1 - interp1) * mid[i - 1] - side[i - 1] - interp0 * p0, -1.0, 1.0);
+ }
+
+ for (; i < s->flength; i++) {
+ float p0 = 0.25 * (mid[i - 2] + 2 * mid[i - 1] + mid[i]);
+
+ l[i] = av_clipf((1 + w1) * mid[i - 1] + side[i - 1] + w0 * p0, -1.0, 1.0);
+ r[i] = av_clipf((1 - w1) * mid[i - 1] - side[i - 1] - w0 * p0, -1.0, 1.0);
+ }
+
+ memcpy(s->prev_stereo_weights, s->stereo_weights, sizeof(s->stereo_weights));
+}
+
+static void silk_flush_frame(SilkFrame *frame)
+{
+ if (!frame->coded)
+ return;
+
+ memset(frame->output, 0, sizeof(frame->output));
+ memset(frame->lpc_history, 0, sizeof(frame->lpc_history));
+
+ memset(frame->lpc, 0, sizeof(frame->lpc));
+ memset(frame->nlsf, 0, sizeof(frame->nlsf));
+
+ frame->log_gain = 0;
+
+ frame->primarylag = 0;
+ frame->prev_voiced = 0;
+ frame->coded = 0;
+}
+
+int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc,
+ float *output[2],
+ enum OpusBandwidth bandwidth,
+ int coded_channels,
+ int duration_ms)
+{
+ int active[2][6], redundancy[2];
+ int nb_frames, i, j;
+
+ if (bandwidth > OPUS_BANDWIDTH_WIDEBAND ||
+ coded_channels > 2 || duration_ms > 60) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid parameters passed "
+ "to the SILK decoder.\n");
+ return AVERROR(EINVAL);
+ }
+
+ nb_frames = 1 + (duration_ms > 20) + (duration_ms > 40);
+ s->subframes = duration_ms / nb_frames / 5; // 5ms subframes
+ s->sflength = 20 * (bandwidth + 2);
+ s->flength = s->sflength * s->subframes;
+ s->bandwidth = bandwidth;
+ s->wb = bandwidth == OPUS_BANDWIDTH_WIDEBAND;
+
+ /* make sure to flush the side channel when switching from mono to stereo */
+ if (coded_channels > s->prev_coded_channels)
+ silk_flush_frame(&s->frame[1]);
+ s->prev_coded_channels = coded_channels;
+
+ /* read the LP-layer header bits */
+ for (i = 0; i < coded_channels; i++) {
+ for (j = 0; j < nb_frames; j++)
+ active[i][j] = opus_rc_p2model(rc, 1);
+
+ redundancy[i] = opus_rc_p2model(rc, 1);
+ if (redundancy[i]) {
+ av_log(s->avctx, AV_LOG_ERROR, "LBRR frames present; this is unsupported\n");
+ return AVERROR_PATCHWELCOME;
+ }
+ }
+
+ for (i = 0; i < nb_frames; i++) {
+ for (j = 0; j < coded_channels && !s->midonly; j++)
+ silk_decode_frame(s, rc, i, j, coded_channels, active[j][i], active[1][i]);
+
+ /* reset the side channel if it is not coded */
+ if (s->midonly && s->frame[1].coded)
+ silk_flush_frame(&s->frame[1]);
+
+ if (coded_channels == 1 || s->output_channels == 1) {
+ for (j = 0; j < s->output_channels; j++) {
+ memcpy(output[j] + i * s->flength,
+ s->frame[0].output + SILK_HISTORY - s->flength - 2,
+ s->flength * sizeof(float));
+ }
+ } else {
+ silk_unmix_ms(s, output[0] + i * s->flength, output[1] + i * s->flength);
+ }
+
+ s->midonly = 0;
+ }
+
+ return nb_frames * s->flength;
+}
+
+void ff_silk_free(SilkContext **ps)
+{
+ av_freep(ps);
+}
+
+void ff_silk_flush(SilkContext *s)
+{
+ silk_flush_frame(&s->frame[0]);
+ silk_flush_frame(&s->frame[1]);
+
+ memset(s->prev_stereo_weights, 0, sizeof(s->prev_stereo_weights));
+}
+
+int ff_silk_init(AVCodecContext *avctx, SilkContext **ps, int output_channels)
+{
+ SilkContext *s;
+
+ if (output_channels != 1 && output_channels != 2) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid number of output channels: %d\n",
+ output_channels);
+ return AVERROR(EINVAL);
+ }
+
+ s = av_mallocz(sizeof(*s));
+ if (!s)
+ return AVERROR(ENOMEM);
+
+ s->avctx = avctx;
+ s->output_channels = output_channels;
+
+ ff_silk_flush(s);
+
+ *ps = s;
+
+ return 0;
+}
diff --git a/ffmpeg-2-8-11/libavcodec/opusdec.c b/ffmpeg-2-8-12/libavcodec/opusdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/opusdec.c
rename to ffmpeg-2-8-12/libavcodec/opusdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/paf.h b/ffmpeg-2-8-12/libavcodec/paf.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/paf.h
rename to ffmpeg-2-8-12/libavcodec/paf.h
diff --git a/ffmpeg-2-8-11/libavcodec/pafaudio.c b/ffmpeg-2-8-12/libavcodec/pafaudio.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pafaudio.c
rename to ffmpeg-2-8-12/libavcodec/pafaudio.c
diff --git a/ffmpeg-2-8-12/libavcodec/pafvideo.c b/ffmpeg-2-8-12/libavcodec/pafvideo.c
new file mode 100644
index 0000000..1618a3e
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/pafvideo.c
@@ -0,0 +1,404 @@
+/*
+ * Packed Animation File video decoder
+ * Copyright (c) 2012 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 "avcodec.h"
+#include "bytestream.h"
+#include "copy_block.h"
+#include "internal.h"
+
+
+static const uint8_t block_sequences[16][8] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0 },
+ { 2, 0, 0, 0, 0, 0, 0, 0 },
+ { 5, 7, 0, 0, 0, 0, 0, 0 },
+ { 5, 0, 0, 0, 0, 0, 0, 0 },
+ { 6, 0, 0, 0, 0, 0, 0, 0 },
+ { 5, 7, 5, 7, 0, 0, 0, 0 },
+ { 5, 7, 5, 0, 0, 0, 0, 0 },
+ { 5, 7, 6, 0, 0, 0, 0, 0 },
+ { 5, 5, 0, 0, 0, 0, 0, 0 },
+ { 3, 0, 0, 0, 0, 0, 0, 0 },
+ { 6, 6, 0, 0, 0, 0, 0, 0 },
+ { 2, 4, 0, 0, 0, 0, 0, 0 },
+ { 2, 4, 5, 7, 0, 0, 0, 0 },
+ { 2, 4, 5, 0, 0, 0, 0, 0 },
+ { 2, 4, 6, 0, 0, 0, 0, 0 },
+ { 2, 4, 5, 7, 5, 7, 0, 0 },
+};
+
+typedef struct PAFVideoDecContext {
+ AVFrame *pic;
+ GetByteContext gb;
+
+ int width;
+ int height;
+
+ int current_frame;
+ uint8_t *frame[4];
+ int frame_size;
+ int video_size;
+
+ uint8_t *opcodes;
+} PAFVideoDecContext;
+
+static av_cold int paf_video_close(AVCodecContext *avctx)
+{
+ PAFVideoDecContext *c = avctx->priv_data;
+ int i;
+
+ av_frame_free(&c->pic);
+
+ for (i = 0; i < 4; i++)
+ av_freep(&c->frame[i]);
+
+ return 0;
+}
+
+static av_cold int paf_video_init(AVCodecContext *avctx)
+{
+ PAFVideoDecContext *c = avctx->priv_data;
+ int i;
+
+ c->width = avctx->width;
+ c->height = avctx->height;
+
+ if (avctx->height & 3 || avctx->width & 3) {
+ av_log(avctx, AV_LOG_ERROR,
+ "width %d and height %d must be multiplie of 4.\n",
+ avctx->width, avctx->height);
+ return AVERROR_INVALIDDATA;
+ }
+
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
+ c->pic = av_frame_alloc();
+ if (!c->pic)
+ return AVERROR(ENOMEM);
+
+ c->frame_size = avctx->width * FFALIGN(avctx->height, 256);
+ 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);
+ return AVERROR(ENOMEM);
+ }
+ }
+
+ return 0;
+}
+
+static void read4x4block(PAFVideoDecContext *c, uint8_t *dst, int width)
+{
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ bytestream2_get_buffer(&c->gb, dst, 4);
+ dst += width;
+ }
+}
+
+static void copy_color_mask(uint8_t *dst, int width, uint8_t mask, uint8_t color)
+{
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (mask & (1 << 7 - i))
+ dst[i] = color;
+ if (mask & (1 << 3 - i))
+ dst[width + i] = color;
+ }
+}
+
+static void copy_src_mask(uint8_t *dst, int width, uint8_t mask, const uint8_t *src)
+{
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (mask & (1 << 7 - i))
+ dst[i] = src[i];
+ if (mask & (1 << 3 - i))
+ dst[width + i] = src[width + i];
+ }
+}
+
+static void set_src_position(PAFVideoDecContext *c,
+ const uint8_t **p,
+ const uint8_t **pend)
+{
+ int val = bytestream2_get_be16(&c->gb);
+ int page = val >> 14;
+ int x = (val & 0x7F);
+ int y = ((val >> 7) & 0x7F);
+
+ *p = c->frame[page] + x * 2 + y * 2 * c->width;
+ *pend = c->frame[page] + c->frame_size;
+}
+
+static int decode_0(PAFVideoDecContext *c, uint8_t *pkt, uint8_t code)
+{
+ uint32_t opcode_size, offset;
+ uint8_t *dst, *dend, mask = 0, color = 0;
+ const uint8_t *src, *send, *opcodes;
+ int i, j, op = 0;
+
+ i = bytestream2_get_byte(&c->gb);
+ if (i) {
+ if (code & 0x10) {
+ int align;
+
+ align = bytestream2_tell(&c->gb) & 3;
+ if (align)
+ bytestream2_skip(&c->gb, 4 - align);
+ }
+ do {
+ int page, val, x, y;
+ val = bytestream2_get_be16(&c->gb);
+ page = val >> 14;
+ x = (val & 0x7F) * 2;
+ y = ((val >> 7) & 0x7F) * 2;
+ dst = c->frame[page] + x + y * c->width;
+ dend = c->frame[page] + c->frame_size;
+ offset = (x & 0x7F) * 2;
+ j = bytestream2_get_le16(&c->gb) + offset;
+ do {
+ offset++;
+ if (dst + 3 * c->width + 4 > dend)
+ return AVERROR_INVALIDDATA;
+ read4x4block(c, dst, c->width);
+ if ((offset & 0x3F) == 0)
+ dst += c->width * 3;
+ dst += 4;
+ } while (offset < j);
+ } while (--i);
+ }
+
+ dst = c->frame[c->current_frame];
+ dend = c->frame[c->current_frame] + c->frame_size;
+ do {
+ set_src_position(c, &src, &send);
+ if ((src + 3 * c->width + 4 > send) ||
+ (dst + 3 * c->width + 4 > dend))
+ return AVERROR_INVALIDDATA;
+ copy_block4(dst, src, c->width, c->width, 4);
+ i++;
+ if ((i & 0x3F) == 0)
+ dst += c->width * 3;
+ dst += 4;
+ } while (i < c->video_size / 16);
+
+ opcode_size = bytestream2_get_le16(&c->gb);
+ bytestream2_skip(&c->gb, 2);
+
+ if (bytestream2_get_bytes_left(&c->gb) < opcode_size)
+ return AVERROR_INVALIDDATA;
+
+ opcodes = pkt + bytestream2_tell(&c->gb);
+ bytestream2_skipu(&c->gb, opcode_size);
+
+ dst = c->frame[c->current_frame];
+
+ for (i = 0; i < c->height; i += 4, dst += c->width * 3)
+ for (j = 0; j < c->width; j += 4, dst += 4) {
+ int opcode, k = 0;
+ if (op > opcode_size)
+ return AVERROR_INVALIDDATA;
+ if (j & 4) {
+ opcode = opcodes[op] & 15;
+ op++;
+ } else {
+ opcode = opcodes[op] >> 4;
+ }
+
+ while (block_sequences[opcode][k]) {
+ offset = c->width * 2;
+ code = block_sequences[opcode][k++];
+
+ switch (code) {
+ case 2:
+ offset = 0;
+ case 3:
+ color = bytestream2_get_byte(&c->gb);
+ case 4:
+ mask = bytestream2_get_byte(&c->gb);
+ copy_color_mask(dst + offset, c->width, mask, color);
+ break;
+ case 5:
+ offset = 0;
+ case 6:
+ set_src_position(c, &src, &send);
+ case 7:
+ if (src + offset + c->width + 4 > send)
+ return AVERROR_INVALIDDATA;
+ mask = bytestream2_get_byte(&c->gb);
+ copy_src_mask(dst + offset, c->width, mask, src + offset);
+ break;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int paf_video_decode(AVCodecContext *avctx, void *data,
+ int *got_frame, AVPacket *pkt)
+{
+ PAFVideoDecContext *c = avctx->priv_data;
+ uint8_t code, *dst, *end;
+ int i, frame, ret;
+
+ if (pkt->size < 2)
+ return AVERROR_INVALIDDATA;
+
+ bytestream2_init(&c->gb, pkt->data, pkt->size);
+
+ code = bytestream2_get_byte(&c->gb);
+ if ((code & 0xF) > 4) {
+ avpriv_request_sample(avctx, "unknown/invalid code");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)
+ return ret;
+
+ if (code & 0x20) { // frame is keyframe
+ for (i = 0; i < 4; i++)
+ memset(c->frame[i], 0, c->frame_size);
+
+ memset(c->pic->data[1], 0, AVPALETTE_SIZE);
+ c->current_frame = 0;
+ c->pic->key_frame = 1;
+ c->pic->pict_type = AV_PICTURE_TYPE_I;
+ } else {
+ c->pic->key_frame = 0;
+ c->pic->pict_type = AV_PICTURE_TYPE_P;
+ }
+
+ if (code & 0x40) { // palette update
+ uint32_t *out = (uint32_t *)c->pic->data[1];
+ int index, count;
+
+ index = bytestream2_get_byte(&c->gb);
+ count = bytestream2_get_byte(&c->gb) + 1;
+
+ if (index + count > 256)
+ return AVERROR_INVALIDDATA;
+ if (bytestream2_get_bytes_left(&c->gb) < 3 * count)
+ return AVERROR_INVALIDDATA;
+
+ out += index;
+ for (i = 0; i < count; i++) {
+ unsigned r, g, b;
+
+ r = bytestream2_get_byteu(&c->gb);
+ r = r << 2 | r >> 4;
+ g = bytestream2_get_byteu(&c->gb);
+ g = g << 2 | g >> 4;
+ b = bytestream2_get_byteu(&c->gb);
+ b = b << 2 | b >> 4;
+ *out++ = (0xFFU << 24) | (r << 16) | (g << 8) | b;
+ }
+ c->pic->palette_has_changed = 1;
+ }
+
+ switch (code & 0x0F) {
+ case 0:
+ /* Block-based motion compensation using 4x4 blocks with either
+ * horizontal or vertical vectors; might incorporate VQ as well. */
+ if ((ret = decode_0(c, pkt->data, code)) < 0)
+ return ret;
+ break;
+ case 1:
+ /* Uncompressed data. This mode specifies that (width * height) bytes
+ * should be copied directly from the encoded buffer into the output. */
+ dst = c->frame[c->current_frame];
+ // possibly chunk length data
+ bytestream2_skip(&c->gb, 2);
+ if (bytestream2_get_bytes_left(&c->gb) < c->video_size)
+ return AVERROR_INVALIDDATA;
+ bytestream2_get_bufferu(&c->gb, dst, c->video_size);
+ break;
+ case 2:
+ /* Copy reference frame: Consume the next byte in the stream as the
+ * reference frame (which should be 0, 1, 2, or 3, and should not be
+ * the same as the current frame number). */
+ frame = bytestream2_get_byte(&c->gb);
+ if (frame > 3)
+ return AVERROR_INVALIDDATA;
+ if (frame != c->current_frame)
+ memcpy(c->frame[c->current_frame], c->frame[frame], c->frame_size);
+ break;
+ case 4:
+ /* Run length encoding.*/
+ dst = c->frame[c->current_frame];
+ end = dst + c->video_size;
+
+ bytestream2_skip(&c->gb, 2);
+
+ while (dst < end) {
+ int8_t code;
+ int count;
+
+ if (bytestream2_get_bytes_left(&c->gb) < 2)
+ return AVERROR_INVALIDDATA;
+
+ code = bytestream2_get_byteu(&c->gb);
+ count = FFABS(code) + 1;
+
+ if (dst + count > end)
+ return AVERROR_INVALIDDATA;
+ if (code < 0)
+ memset(dst, bytestream2_get_byteu(&c->gb), count);
+ else
+ bytestream2_get_buffer(&c->gb, dst, count);
+ dst += count;
+ }
+ break;
+ default:
+ av_assert0(0);
+ }
+
+ av_image_copy_plane(c->pic->data[0], c->pic->linesize[0],
+ c->frame[c->current_frame], c->width,
+ c->width, c->height);
+
+ c->current_frame = (c->current_frame + 1) & 3;
+ if ((ret = av_frame_ref(data, c->pic)) < 0)
+ return ret;
+
+ *got_frame = 1;
+
+ return pkt->size;
+}
+
+AVCodec ff_paf_video_decoder = {
+ .name = "paf_video",
+ .long_name = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Video"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_PAF_VIDEO,
+ .priv_data_size = sizeof(PAFVideoDecContext),
+ .init = paf_video_init,
+ .close = paf_video_close,
+ .decode = paf_video_decode,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/pamenc.c b/ffmpeg-2-8-12/libavcodec/pamenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pamenc.c
rename to ffmpeg-2-8-12/libavcodec/pamenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/parser.c b/ffmpeg-2-8-12/libavcodec/parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/parser.c
rename to ffmpeg-2-8-12/libavcodec/parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/parser.h b/ffmpeg-2-8-12/libavcodec/parser.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/parser.h
rename to ffmpeg-2-8-12/libavcodec/parser.h
diff --git a/ffmpeg-2-8-11/libavcodec/pcm-bluray.c b/ffmpeg-2-8-12/libavcodec/pcm-bluray.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pcm-bluray.c
rename to ffmpeg-2-8-12/libavcodec/pcm-bluray.c
diff --git a/ffmpeg-2-8-11/libavcodec/pcm-dvd.c b/ffmpeg-2-8-12/libavcodec/pcm-dvd.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pcm-dvd.c
rename to ffmpeg-2-8-12/libavcodec/pcm-dvd.c
diff --git a/ffmpeg-2-8-11/libavcodec/pcm.c b/ffmpeg-2-8-12/libavcodec/pcm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pcm.c
rename to ffmpeg-2-8-12/libavcodec/pcm.c
diff --git a/ffmpeg-2-8-11/libavcodec/pcm_tablegen.c b/ffmpeg-2-8-12/libavcodec/pcm_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pcm_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/pcm_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/pcm_tablegen.h b/ffmpeg-2-8-12/libavcodec/pcm_tablegen.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pcm_tablegen.h
rename to ffmpeg-2-8-12/libavcodec/pcm_tablegen.h
diff --git a/ffmpeg-2-8-11/libavcodec/pcx.c b/ffmpeg-2-8-12/libavcodec/pcx.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pcx.c
rename to ffmpeg-2-8-12/libavcodec/pcx.c
diff --git a/ffmpeg-2-8-11/libavcodec/pcxenc.c b/ffmpeg-2-8-12/libavcodec/pcxenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pcxenc.c
rename to ffmpeg-2-8-12/libavcodec/pcxenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/pel_template.c b/ffmpeg-2-8-12/libavcodec/pel_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pel_template.c
rename to ffmpeg-2-8-12/libavcodec/pel_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/pgssubdec.c b/ffmpeg-2-8-12/libavcodec/pgssubdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pgssubdec.c
rename to ffmpeg-2-8-12/libavcodec/pgssubdec.c
diff --git a/ffmpeg-2-8-12/libavcodec/pictordec.c b/ffmpeg-2-8-12/libavcodec/pictordec.c
new file mode 100644
index 0000000..a09ee37
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/pictordec.c
@@ -0,0 +1,267 @@
+/*
+ * Pictor/PC Paint decoder
+ * Copyright (c) 2010 Peter Ross <pross at 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
+ * Pictor/PC Paint decoder
+ */
+
+#include "libavutil/imgutils.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "cga_data.h"
+#include "internal.h"
+
+typedef struct PicContext {
+ int width, height;
+ int nb_planes;
+ GetByteContext g;
+} PicContext;
+
+static void picmemset_8bpp(PicContext *s, AVFrame *frame, int value, int run,
+ int *x, int *y)
+{
+ while (run > 0) {
+ uint8_t *d = frame->data[0] + *y * frame->linesize[0];
+ if (*x + run >= s->width) {
+ int n = s->width - *x;
+ memset(d + *x, value, n);
+ run -= n;
+ *x = 0;
+ *y -= 1;
+ if (*y < 0)
+ break;
+ } else {
+ memset(d + *x, value, run);
+ *x += run;
+ break;
+ }
+ }
+}
+
+static void picmemset(PicContext *s, AVFrame *frame, int value, int run,
+ int *x, int *y, int *plane, int bits_per_plane)
+{
+ uint8_t *d;
+ int shift = *plane * bits_per_plane;
+ int mask = ((1 << bits_per_plane) - 1) << shift;
+ value <<= shift;
+
+ while (run > 0) {
+ int j;
+ for (j = 8-bits_per_plane; j >= 0; j -= bits_per_plane) {
+ d = frame->data[0] + *y * frame->linesize[0];
+ d[*x] |= (value >> j) & mask;
+ *x += 1;
+ if (*x == s->width) {
+ *y -= 1;
+ *x = 0;
+ if (*y < 0) {
+ *y = s->height - 1;
+ *plane += 1;
+ if (*plane >= s->nb_planes)
+ return;
+ value <<= bits_per_plane;
+ mask <<= bits_per_plane;
+ }
+ }
+ }
+ run--;
+ }
+}
+
+static const uint8_t cga_mode45_index[6][4] = {
+ [0] = { 0, 3, 5, 7 }, // mode4, palette#1, low intensity
+ [1] = { 0, 2, 4, 6 }, // mode4, palette#2, low intensity
+ [2] = { 0, 3, 4, 7 }, // mode5, low intensity
+ [3] = { 0, 11, 13, 15 }, // mode4, palette#1, high intensity
+ [4] = { 0, 10, 12, 14 }, // mode4, palette#2, high intensity
+ [5] = { 0, 11, 12, 15 }, // mode5, high intensity
+};
+
+static int decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ PicContext *s = avctx->priv_data;
+ AVFrame *frame = data;
+ uint32_t *palette;
+ int bits_per_plane, bpp, etype, esize, npal, pos_after_pal;
+ int i, x, y, plane, tmp, ret, val;
+
+ bytestream2_init(&s->g, avpkt->data, avpkt->size);
+
+ if (bytestream2_get_bytes_left(&s->g) < 11)
+ return AVERROR_INVALIDDATA;
+
+ if (bytestream2_get_le16u(&s->g) != 0x1234)
+ return AVERROR_INVALIDDATA;
+
+ s->width = bytestream2_get_le16u(&s->g);
+ s->height = bytestream2_get_le16u(&s->g);
+ bytestream2_skip(&s->g, 4);
+ tmp = bytestream2_get_byteu(&s->g);
+ bits_per_plane = tmp & 0xF;
+ s->nb_planes = (tmp >> 4) + 1;
+ bpp = bits_per_plane * s->nb_planes;
+ if (bits_per_plane > 8 || bpp < 1 || bpp > 32) {
+ avpriv_request_sample(avctx, "Unsupported bit depth");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if (bytestream2_peek_byte(&s->g) == 0xFF || bpp == 1 || bpp == 4 || bpp == 8) {
+ bytestream2_skip(&s->g, 2);
+ etype = bytestream2_get_le16(&s->g);
+ esize = bytestream2_get_le16(&s->g);
+ if (bytestream2_get_bytes_left(&s->g) < esize)
+ return AVERROR_INVALIDDATA;
+ } else {
+ etype = -1;
+ esize = 0;
+ }
+
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
+ if (av_image_check_size(s->width, s->height, 0, avctx) < 0)
+ return -1;
+ if (s->width != avctx->width || s->height != avctx->height) {
+ ret = ff_set_dimensions(avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
+ }
+
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+ memset(frame->data[0], 0, s->height * frame->linesize[0]);
+ frame->pict_type = AV_PICTURE_TYPE_I;
+ frame->palette_has_changed = 1;
+
+ pos_after_pal = bytestream2_tell(&s->g) + esize;
+ palette = (uint32_t*)frame->data[1];
+ if (etype == 1 && esize > 1 && bytestream2_peek_byte(&s->g) < 6) {
+ int idx = bytestream2_get_byte(&s->g);
+ npal = 4;
+ for (i = 0; i < npal; i++)
+ palette[i] = ff_cga_palette[ cga_mode45_index[idx][i] ];
+ } else if (etype == 2) {
+ npal = FFMIN(esize, 16);
+ for (i = 0; i < npal; i++) {
+ int pal_idx = bytestream2_get_byte(&s->g);
+ palette[i] = ff_cga_palette[FFMIN(pal_idx, 15)];
+ }
+ } else if (etype == 3) {
+ npal = FFMIN(esize, 16);
+ for (i = 0; i < npal; i++) {
+ int pal_idx = bytestream2_get_byte(&s->g);
+ palette[i] = ff_ega_palette[FFMIN(pal_idx, 63)];
+ }
+ } else if (etype == 4 || etype == 5) {
+ npal = FFMIN(esize / 3, 256);
+ for (i = 0; i < npal; i++) {
+ palette[i] = bytestream2_get_be24(&s->g) << 2;
+ palette[i] |= 0xFFU << 24 | palette[i] >> 6 & 0x30303;
+ }
+ } else {
+ if (bpp == 1) {
+ npal = 2;
+ palette[0] = 0xFF000000;
+ palette[1] = 0xFFFFFFFF;
+ } else if (bpp == 2) {
+ npal = 4;
+ for (i = 0; i < npal; i++)
+ palette[i] = ff_cga_palette[ cga_mode45_index[0][i] ];
+ } else {
+ npal = 16;
+ memcpy(palette, ff_cga_palette, npal * 4);
+ }
+ }
+ // fill remaining palette entries
+ memset(palette + npal, 0, AVPALETTE_SIZE - npal * 4);
+ // skip remaining palette bytes
+ bytestream2_seek(&s->g, pos_after_pal, SEEK_SET);
+
+ val = 0;
+ y = s->height - 1;
+ if (bytestream2_get_le16(&s->g)) {
+ x = 0;
+ plane = 0;
+ while (bytestream2_get_bytes_left(&s->g) >= 6) {
+ int stop_size, marker, t1, t2;
+
+ t1 = bytestream2_get_bytes_left(&s->g);
+ t2 = bytestream2_get_le16(&s->g);
+ stop_size = t1 - FFMIN(t1, t2);
+ // ignore uncompressed block size
+ bytestream2_skip(&s->g, 2);
+ marker = bytestream2_get_byte(&s->g);
+
+ while (plane < s->nb_planes &&
+ bytestream2_get_bytes_left(&s->g) > stop_size) {
+ int run = 1;
+ val = bytestream2_get_byte(&s->g);
+ if (val == marker) {
+ run = bytestream2_get_byte(&s->g);
+ if (run == 0)
+ run = bytestream2_get_le16(&s->g);
+ val = bytestream2_get_byte(&s->g);
+ }
+ if (!bytestream2_get_bytes_left(&s->g))
+ break;
+
+ if (bits_per_plane == 8) {
+ picmemset_8bpp(s, frame, val, run, &x, &y);
+ if (y < 0)
+ goto finish;
+ } else {
+ picmemset(s, frame, val, run, &x, &y, &plane, bits_per_plane);
+ }
+ }
+ }
+
+ if (plane < s->nb_planes && x < avctx->width) {
+ int run = (y + 1) * avctx->width - x;
+ if (bits_per_plane == 8)
+ picmemset_8bpp(s, frame, val, run, &x, &y);
+ else
+ picmemset(s, frame, val, run / (8 / bits_per_plane), &x, &y, &plane, bits_per_plane);
+ }
+ } else {
+ while (y >= 0 && bytestream2_get_bytes_left(&s->g) > 0) {
+ memcpy(frame->data[0] + y * frame->linesize[0], s->g.buffer, FFMIN(avctx->width, bytestream2_get_bytes_left(&s->g)));
+ bytestream2_skip(&s->g, avctx->width);
+ y--;
+ }
+ }
+finish:
+
+ *got_frame = 1;
+ return avpkt->size;
+}
+
+AVCodec ff_pictor_decoder = {
+ .name = "pictor",
+ .long_name = NULL_IF_CONFIG_SMALL("Pictor/PC Paint"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_PICTOR,
+ .priv_data_size = sizeof(PicContext),
+ .decode = decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/pixblockdsp.c b/ffmpeg-2-8-12/libavcodec/pixblockdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pixblockdsp.c
rename to ffmpeg-2-8-12/libavcodec/pixblockdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/pixblockdsp.h b/ffmpeg-2-8-12/libavcodec/pixblockdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pixblockdsp.h
rename to ffmpeg-2-8-12/libavcodec/pixblockdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/pixblockdsp_template.c b/ffmpeg-2-8-12/libavcodec/pixblockdsp_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pixblockdsp_template.c
rename to ffmpeg-2-8-12/libavcodec/pixblockdsp_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/pixels.h b/ffmpeg-2-8-12/libavcodec/pixels.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pixels.h
rename to ffmpeg-2-8-12/libavcodec/pixels.h
diff --git a/ffmpeg-2-8-11/libavcodec/png.c b/ffmpeg-2-8-12/libavcodec/png.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/png.c
rename to ffmpeg-2-8-12/libavcodec/png.c
diff --git a/ffmpeg-2-8-11/libavcodec/png.h b/ffmpeg-2-8-12/libavcodec/png.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/png.h
rename to ffmpeg-2-8-12/libavcodec/png.h
diff --git a/ffmpeg-2-8-11/libavcodec/png_parser.c b/ffmpeg-2-8-12/libavcodec/png_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/png_parser.c
rename to ffmpeg-2-8-12/libavcodec/png_parser.c
diff --git a/ffmpeg-2-8-12/libavcodec/pngdec.c b/ffmpeg-2-8-12/libavcodec/pngdec.c
new file mode 100644
index 0000000..ba1b39e
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/pngdec.c
@@ -0,0 +1,1497 @@
+/*
+ * PNG image format
+ * Copyright (c) 2003 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
+ */
+
+//#define DEBUG
+
+#include "libavutil/avassert.h"
+#include "libavutil/bprint.h"
+#include "libavutil/imgutils.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+#include "apng.h"
+#include "png.h"
+#include "pngdsp.h"
+#include "thread.h"
+
+#include <zlib.h>
+
+typedef struct PNGDecContext {
+ PNGDSPContext dsp;
+ AVCodecContext *avctx;
+
+ GetByteContext gb;
+ ThreadFrame previous_picture;
+ ThreadFrame last_picture;
+ ThreadFrame picture;
+
+ int state;
+ int width, height;
+ int cur_w, cur_h;
+ int last_w, last_h;
+ int x_offset, y_offset;
+ int last_x_offset, last_y_offset;
+ uint8_t dispose_op, blend_op;
+ uint8_t last_dispose_op;
+ int bit_depth;
+ int color_type;
+ int compression_type;
+ int interlace_type;
+ int filter_type;
+ int channels;
+ int bits_per_pixel;
+ int bpp;
+ int has_trns;
+ uint8_t transparent_color_be[6];
+
+ uint8_t *image_buf;
+ int image_linesize;
+ uint32_t palette[256];
+ uint8_t *crow_buf;
+ uint8_t *last_row;
+ unsigned int last_row_size;
+ uint8_t *tmp_row;
+ unsigned int tmp_row_size;
+ uint8_t *buffer;
+ int buffer_size;
+ int pass;
+ int crow_size; /* compressed row size (include filter type) */
+ int row_size; /* decompressed row size */
+ int pass_row_size; /* decompress row size of the current pass */
+ int y;
+ z_stream zstream;
+} PNGDecContext;
+
+/* Mask to determine which pixels are valid in a pass */
+static const uint8_t png_pass_mask[NB_PASSES] = {
+ 0x01, 0x01, 0x11, 0x11, 0x55, 0x55, 0xff,
+};
+
+/* Mask to determine which y pixels can be written in a pass */
+static const uint8_t png_pass_dsp_ymask[NB_PASSES] = {
+ 0xff, 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55,
+};
+
+/* Mask to determine which pixels to overwrite while displaying */
+static const uint8_t png_pass_dsp_mask[NB_PASSES] = {
+ 0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff
+};
+
+/* NOTE: we try to construct a good looking image at each pass. width
+ * is the original image width. We also do pixel format conversion at
+ * this stage */
+static void png_put_interlaced_row(uint8_t *dst, int width,
+ int bits_per_pixel, int pass,
+ int color_type, const uint8_t *src)
+{
+ int x, mask, dsp_mask, j, src_x, b, bpp;
+ uint8_t *d;
+ const uint8_t *s;
+
+ mask = png_pass_mask[pass];
+ dsp_mask = png_pass_dsp_mask[pass];
+
+ switch (bits_per_pixel) {
+ case 1:
+ src_x = 0;
+ for (x = 0; x < width; x++) {
+ j = (x & 7);
+ if ((dsp_mask << j) & 0x80) {
+ b = (src[src_x >> 3] >> (7 - (src_x & 7))) & 1;
+ dst[x >> 3] &= 0xFF7F>>j;
+ dst[x >> 3] |= b << (7 - j);
+ }
+ if ((mask << j) & 0x80)
+ src_x++;
+ }
+ break;
+ case 2:
+ src_x = 0;
+ for (x = 0; x < width; x++) {
+ int j2 = 2 * (x & 3);
+ j = (x & 7);
+ if ((dsp_mask << j) & 0x80) {
+ b = (src[src_x >> 2] >> (6 - 2*(src_x & 3))) & 3;
+ dst[x >> 2] &= 0xFF3F>>j2;
+ dst[x >> 2] |= b << (6 - j2);
+ }
+ if ((mask << j) & 0x80)
+ src_x++;
+ }
+ break;
+ case 4:
+ src_x = 0;
+ for (x = 0; x < width; x++) {
+ int j2 = 4*(x&1);
+ j = (x & 7);
+ if ((dsp_mask << j) & 0x80) {
+ b = (src[src_x >> 1] >> (4 - 4*(src_x & 1))) & 15;
+ dst[x >> 1] &= 0xFF0F>>j2;
+ dst[x >> 1] |= b << (4 - j2);
+ }
+ if ((mask << j) & 0x80)
+ src_x++;
+ }
+ break;
+ default:
+ bpp = bits_per_pixel >> 3;
+ d = dst;
+ s = src;
+ for (x = 0; x < width; x++) {
+ j = x & 7;
+ if ((dsp_mask << j) & 0x80) {
+ memcpy(d, s, bpp);
+ }
+ d += bpp;
+ if ((mask << j) & 0x80)
+ s += bpp;
+ }
+ break;
+ }
+}
+
+void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top,
+ int w, int bpp)
+{
+ int i;
+ for (i = 0; i < w; i++) {
+ int a, b, c, p, pa, pb, pc;
+
+ a = dst[i - bpp];
+ b = top[i];
+ c = top[i - bpp];
+
+ p = b - c;
+ pc = a - c;
+
+ pa = abs(p);
+ pb = abs(pc);
+ pc = abs(p + pc);
+
+ if (pa <= pb && pa <= pc)
+ p = a;
+ else if (pb <= pc)
+ p = b;
+ else
+ p = c;
+ dst[i] = p + src[i];
+ }
+}
+
+#define UNROLL1(bpp, op) \
+ { \
+ r = dst[0]; \
+ if (bpp >= 2) \
+ g = dst[1]; \
+ if (bpp >= 3) \
+ b = dst[2]; \
+ if (bpp >= 4) \
+ a = dst[3]; \
+ for (; i <= size - bpp; i += bpp) { \
+ dst[i + 0] = r = op(r, src[i + 0], last[i + 0]); \
+ if (bpp == 1) \
+ continue; \
+ dst[i + 1] = g = op(g, src[i + 1], last[i + 1]); \
+ if (bpp == 2) \
+ continue; \
+ dst[i + 2] = b = op(b, src[i + 2], last[i + 2]); \
+ if (bpp == 3) \
+ continue; \
+ dst[i + 3] = a = op(a, src[i + 3], last[i + 3]); \
+ } \
+ }
+
+#define UNROLL_FILTER(op) \
+ if (bpp == 1) { \
+ UNROLL1(1, op) \
+ } else if (bpp == 2) { \
+ UNROLL1(2, op) \
+ } else if (bpp == 3) { \
+ UNROLL1(3, op) \
+ } else if (bpp == 4) { \
+ UNROLL1(4, op) \
+ } \
+ for (; i < size; i++) { \
+ dst[i] = op(dst[i - bpp], src[i], last[i]); \
+ }
+
+/* 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)
+{
+ int i, p, r, g, b, a;
+
+ switch (filter_type) {
+ case PNG_FILTER_VALUE_NONE:
+ memcpy(dst, src, size);
+ break;
+ case PNG_FILTER_VALUE_SUB:
+ for (i = 0; i < bpp; i++)
+ dst[i] = src[i];
+ if (bpp == 4) {
+ p = *(int *)dst;
+ for (; i < size; i += bpp) {
+ unsigned s = *(int *)(src + i);
+ p = ((s & 0x7f7f7f7f) + (p & 0x7f7f7f7f)) ^ ((s ^ p) & 0x80808080);
+ *(int *)(dst + i) = p;
+ }
+ } else {
+#define OP_SUB(x, s, l) ((x) + (s))
+ UNROLL_FILTER(OP_SUB);
+ }
+ break;
+ case PNG_FILTER_VALUE_UP:
+ dsp->add_bytes_l2(dst, src, last, size);
+ break;
+ case PNG_FILTER_VALUE_AVG:
+ for (i = 0; i < bpp; i++) {
+ p = (last[i] >> 1);
+ dst[i] = p + src[i];
+ }
+#define OP_AVG(x, s, l) (((((x) + (l)) >> 1) + (s)) & 0xff)
+ UNROLL_FILTER(OP_AVG);
+ break;
+ case PNG_FILTER_VALUE_PAETH:
+ for (i = 0; i < bpp; i++) {
+ p = last[i];
+ dst[i] = p + src[i];
+ }
+ if (bpp > 2 && size > 4) {
+ /* would write off the end of the array if we let it process
+ * the last pixel with bpp=3 */
+ int w = (bpp & 3) ? size - 3 : size;
+
+ if (w > i) {
+ dsp->add_paeth_prediction(dst + i, src + i, last + i, size - i, bpp);
+ i = w;
+ }
+ }
+ ff_add_png_paeth_prediction(dst + i, src + i, last + i, size - i, bpp);
+ break;
+ }
+}
+
+/* This used to be called "deloco" in FFmpeg
+ * and is actually an inverse reversible colorspace transformation */
+#define YUV2RGB(NAME, TYPE) \
+static void deloco_ ## NAME(TYPE *dst, int size, int alpha) \
+{ \
+ int i; \
+ for (i = 0; i < size; i += 3 + alpha) { \
+ int g = dst [i + 1]; \
+ dst[i + 0] += g; \
+ dst[i + 2] += g; \
+ } \
+}
+
+YUV2RGB(rgb8, uint8_t)
+YUV2RGB(rgb16, uint16_t)
+
+/* process exactly one decompressed row */
+static void png_handle_row(PNGDecContext *s)
+{
+ 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;
+ if (s->y == 0)
+ last_row = s->last_row;
+ else
+ last_row = ptr - s->image_linesize;
+
+ 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,
+ s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
+ } else {
+ deloco_rgb8(ptr - s->image_linesize, s->row_size,
+ s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
+ }
+ }
+ s->y++;
+ if (s->y == s->cur_h) {
+ s->state |= PNG_ALLIMAGE;
+ if (s->filter_type == PNG_FILTER_TYPE_LOCO) {
+ if (s->bit_depth == 16) {
+ deloco_rgb16((uint16_t *)ptr, s->row_size / 2,
+ s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
+ } else {
+ deloco_rgb8(ptr, s->row_size,
+ s->color_type == PNG_COLOR_TYPE_RGB_ALPHA);
+ }
+ }
+ }
+ } else {
+ got_line = 0;
+ for (;;) {
+ ptr = s->image_buf + s->image_linesize * (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);
+ FFSWAP(uint8_t *, s->last_row, s->tmp_row);
+ FFSWAP(unsigned int, s->last_row_size, s->tmp_row_size);
+ got_line = 1;
+ }
+ if ((png_pass_dsp_ymask[s->pass] << (s->y & 7)) & 0x80) {
+ png_put_interlaced_row(ptr, s->cur_w, s->bits_per_pixel, s->pass,
+ s->color_type, s->last_row);
+ }
+ s->y++;
+ if (s->y == s->cur_h) {
+ memset(s->last_row, 0, s->row_size);
+ for (;;) {
+ if (s->pass == NB_PASSES - 1) {
+ s->state |= PNG_ALLIMAGE;
+ goto the_end;
+ } else {
+ s->pass++;
+ s->y = 0;
+ s->pass_row_size = ff_png_pass_row_size(s->pass,
+ s->bits_per_pixel,
+ s->cur_w);
+ s->crow_size = s->pass_row_size + 1;
+ if (s->pass_row_size != 0)
+ break;
+ /* skip pass if empty row */
+ }
+ }
+ }
+ }
+the_end:;
+ }
+}
+
+static int png_decode_idat(PNGDecContext *s, int length)
+{
+ int ret;
+ s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb));
+ s->zstream.next_in = (unsigned char *)s->gb.buffer;
+ 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->state & PNG_ALLIMAGE)) {
+ png_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(NULL, AV_LOG_WARNING,
+ "%d undecompressed bytes left in buffer\n", s->zstream.avail_in);
+ return 0;
+ }
+ }
+ return 0;
+}
+
+static int decode_zbuf(AVBPrint *bp, const uint8_t *data,
+ const uint8_t *data_end)
+{
+ z_stream zstream;
+ unsigned char *buf;
+ unsigned buf_size;
+ int ret;
+
+ zstream.zalloc = ff_png_zalloc;
+ zstream.zfree = ff_png_zfree;
+ zstream.opaque = NULL;
+ if (inflateInit(&zstream) != Z_OK)
+ return AVERROR_EXTERNAL;
+ zstream.next_in = (unsigned char *)data;
+ zstream.avail_in = data_end - data;
+ av_bprint_init(bp, 0, -1);
+
+ while (zstream.avail_in > 0) {
+ av_bprint_get_buffer(bp, 2, &buf, &buf_size);
+ if (buf_size < 2) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ zstream.next_out = buf;
+ zstream.avail_out = buf_size - 1;
+ ret = inflate(&zstream, Z_PARTIAL_FLUSH);
+ if (ret != Z_OK && ret != Z_STREAM_END) {
+ ret = AVERROR_EXTERNAL;
+ goto fail;
+ }
+ bp->len += zstream.next_out - buf;
+ if (ret == Z_STREAM_END)
+ break;
+ }
+ inflateEnd(&zstream);
+ bp->str[bp->len] = 0;
+ return 0;
+
+fail:
+ inflateEnd(&zstream);
+ av_bprint_finalize(bp, NULL);
+ return ret;
+}
+
+static uint8_t *iso88591_to_utf8(const uint8_t *in, size_t size_in)
+{
+ size_t extra = 0, i;
+ uint8_t *out, *q;
+
+ for (i = 0; i < size_in; i++)
+ extra += in[i] >= 0x80;
+ if (size_in == SIZE_MAX || extra > SIZE_MAX - size_in - 1)
+ return NULL;
+ q = out = av_malloc(size_in + extra + 1);
+ if (!out)
+ return NULL;
+ for (i = 0; i < size_in; i++) {
+ if (in[i] >= 0x80) {
+ *(q++) = 0xC0 | (in[i] >> 6);
+ *(q++) = 0x80 | (in[i] & 0x3F);
+ } else {
+ *(q++) = in[i];
+ }
+ }
+ *(q++) = 0;
+ return out;
+}
+
+static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed,
+ AVDictionary **dict)
+{
+ int ret, method;
+ const uint8_t *data = s->gb.buffer;
+ const uint8_t *data_end = data + length;
+ const uint8_t *keyword = data;
+ const uint8_t *keyword_end = memchr(keyword, 0, data_end - keyword);
+ uint8_t *kw_utf8 = NULL, *text, *txt_utf8 = NULL;
+ unsigned text_len;
+ AVBPrint bp;
+
+ if (!keyword_end)
+ return AVERROR_INVALIDDATA;
+ data = keyword_end + 1;
+
+ if (compressed) {
+ if (data == data_end)
+ return AVERROR_INVALIDDATA;
+ method = *(data++);
+ if (method)
+ return AVERROR_INVALIDDATA;
+ if ((ret = decode_zbuf(&bp, data, data_end)) < 0)
+ return ret;
+ text_len = bp.len;
+ av_bprint_finalize(&bp, (char **)&text);
+ if (!text)
+ return AVERROR(ENOMEM);
+ } else {
+ text = (uint8_t *)data;
+ text_len = data_end - text;
+ }
+
+ kw_utf8 = iso88591_to_utf8(keyword, keyword_end - keyword);
+ txt_utf8 = iso88591_to_utf8(text, text_len);
+ if (text != data)
+ av_free(text);
+ if (!(kw_utf8 && txt_utf8)) {
+ av_free(kw_utf8);
+ av_free(txt_utf8);
+ return AVERROR(ENOMEM);
+ }
+
+ av_dict_set(dict, kw_utf8, txt_utf8,
+ AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
+ return 0;
+}
+
+static int decode_ihdr_chunk(AVCodecContext *avctx, PNGDecContext *s,
+ uint32_t length)
+{
+ if (length != 13)
+ return AVERROR_INVALIDDATA;
+
+ if (s->state & PNG_IDAT) {
+ av_log(avctx, AV_LOG_ERROR, "IHDR after IDAT\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->state & PNG_IHDR) {
+ av_log(avctx, AV_LOG_ERROR, "Multiple IHDR\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->width = s->cur_w = bytestream2_get_be32(&s->gb);
+ s->height = s->cur_h = bytestream2_get_be32(&s->gb);
+ if (av_image_check_size(s->width, s->height, 0, avctx)) {
+ s->cur_w = s->cur_h = s->width = s->height = 0;
+ av_log(avctx, AV_LOG_ERROR, "Invalid image size\n");
+ return AVERROR_INVALIDDATA;
+ }
+ s->bit_depth = bytestream2_get_byte(&s->gb);
+ if (s->bit_depth != 1 && s->bit_depth != 2 && s->bit_depth != 4 &&
+ s->bit_depth != 8 && s->bit_depth != 16) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid bit depth\n");
+ goto error;
+ }
+ s->color_type = bytestream2_get_byte(&s->gb);
+ s->compression_type = bytestream2_get_byte(&s->gb);
+ s->filter_type = bytestream2_get_byte(&s->gb);
+ s->interlace_type = bytestream2_get_byte(&s->gb);
+ bytestream2_skip(&s->gb, 4); /* crc */
+ s->state |= PNG_IHDR;
+ if (avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(avctx, AV_LOG_DEBUG, "width=%d height=%d depth=%d color_type=%d "
+ "compression_type=%d filter_type=%d interlace_type=%d\n",
+ s->width, s->height, s->bit_depth, s->color_type,
+ s->compression_type, s->filter_type, s->interlace_type);
+
+ return 0;
+error:
+ s->cur_w = s->cur_h = s->width = s->height = 0;
+ s->bit_depth = 8;
+ return AVERROR_INVALIDDATA;
+}
+
+static int decode_phys_chunk(AVCodecContext *avctx, PNGDecContext *s)
+{
+ if (s->state & PNG_IDAT) {
+ av_log(avctx, AV_LOG_ERROR, "pHYs after IDAT\n");
+ return AVERROR_INVALIDDATA;
+ }
+ avctx->sample_aspect_ratio.num = bytestream2_get_be32(&s->gb);
+ avctx->sample_aspect_ratio.den = bytestream2_get_be32(&s->gb);
+ if (avctx->sample_aspect_ratio.num < 0 || avctx->sample_aspect_ratio.den < 0)
+ avctx->sample_aspect_ratio = (AVRational){ 0, 1 };
+ bytestream2_skip(&s->gb, 1); /* unit specifier */
+ bytestream2_skip(&s->gb, 4); /* crc */
+
+ return 0;
+}
+
+static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s,
+ uint32_t length, AVFrame *p)
+{
+ int ret;
+ size_t byte_depth = s->bit_depth > 8 ? 2 : 1;
+
+ if (!(s->state & PNG_IHDR)) {
+ av_log(avctx, AV_LOG_ERROR, "IDAT without IHDR\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (!(s->state & PNG_IDAT)) {
+ /* init image info */
+ ret = ff_set_dimensions(avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
+
+ s->channels = ff_png_get_nb_channels(s->color_type);
+ s->bits_per_pixel = s->bit_depth * s->channels;
+ s->bpp = (s->bits_per_pixel + 7) >> 3;
+ s->row_size = (s->cur_w * s->bits_per_pixel + 7) >> 3;
+
+ if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
+ s->color_type == PNG_COLOR_TYPE_RGB) {
+ avctx->pix_fmt = AV_PIX_FMT_RGB24;
+ } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
+ s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
+ avctx->pix_fmt = AV_PIX_FMT_RGBA;
+ } else if ((s->bit_depth == 2 || s->bit_depth == 4 || s->bit_depth == 8) &&
+ s->color_type == PNG_COLOR_TYPE_GRAY) {
+ avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+ } else if (s->bit_depth == 16 &&
+ s->color_type == PNG_COLOR_TYPE_GRAY) {
+ avctx->pix_fmt = AV_PIX_FMT_GRAY16BE;
+ } else if (s->bit_depth == 16 &&
+ s->color_type == PNG_COLOR_TYPE_RGB) {
+ avctx->pix_fmt = AV_PIX_FMT_RGB48BE;
+ } else if (s->bit_depth == 16 &&
+ s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
+ avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
+ } else if ((s->bits_per_pixel == 1 || s->bits_per_pixel == 2 || s->bits_per_pixel == 4 || s->bits_per_pixel == 8) &&
+ s->color_type == PNG_COLOR_TYPE_PALETTE) {
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ } else if (s->bit_depth == 1 && s->bits_per_pixel == 1 && avctx->codec_id != AV_CODEC_ID_APNG) {
+ avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
+ } else if (s->bit_depth == 8 &&
+ s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+ avctx->pix_fmt = AV_PIX_FMT_YA8;
+ } else if (s->bit_depth == 16 &&
+ s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) {
+ avctx->pix_fmt = AV_PIX_FMT_YA16BE;
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "unsupported bit depth %d "
+ "and color type %d\n",
+ s->bit_depth, s->color_type);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE) {
+ switch (avctx->pix_fmt) {
+ case AV_PIX_FMT_RGB24:
+ avctx->pix_fmt = AV_PIX_FMT_RGBA;
+ break;
+
+ case AV_PIX_FMT_RGB48BE:
+ avctx->pix_fmt = AV_PIX_FMT_RGBA64BE;
+ break;
+
+ case AV_PIX_FMT_GRAY8:
+ avctx->pix_fmt = AV_PIX_FMT_YA8;
+ break;
+
+ case AV_PIX_FMT_GRAY16BE:
+ avctx->pix_fmt = AV_PIX_FMT_YA16BE;
+ break;
+
+ default:
+ avpriv_request_sample(avctx, "bit depth %d "
+ "and color type %d with TRNS",
+ s->bit_depth, s->color_type);
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->bpp += byte_depth;
+ }
+
+ 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;
+ }
+ ff_thread_finish_setup(avctx);
+
+ p->pict_type = AV_PICTURE_TYPE_I;
+ p->key_frame = 1;
+ p->interlaced_frame = !!s->interlace_type;
+
+ /* compute the compressed row size */
+ if (!s->interlace_type) {
+ s->crow_size = s->row_size + 1;
+ } else {
+ s->pass = 0;
+ s->pass_row_size = ff_png_pass_row_size(s->pass,
+ s->bits_per_pixel,
+ s->cur_w);
+ s->crow_size = s->pass_row_size + 1;
+ }
+ 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));
+ /* empty row is used if differencing to the first row */
+ av_fast_padded_mallocz(&s->last_row, &s->last_row_size, s->row_size);
+ if (!s->last_row)
+ return AVERROR_INVALIDDATA;
+ if (s->interlace_type ||
+ s->color_type == PNG_COLOR_TYPE_RGB_ALPHA) {
+ av_fast_padded_malloc(&s->tmp_row, &s->tmp_row_size, s->row_size);
+ if (!s->tmp_row)
+ return AVERROR_INVALIDDATA;
+ }
+ /* compressed row */
+ av_fast_padded_malloc(&s->buffer, &s->buffer_size, s->row_size + 16);
+ if (!s->buffer)
+ return AVERROR(ENOMEM);
+
+ /* we want crow_buf+1 to be 16-byte aligned */
+ s->crow_buf = s->buffer + 15;
+ s->zstream.avail_out = s->crow_size;
+ s->zstream.next_out = s->crow_buf;
+ }
+
+ s->state |= PNG_IDAT;
+
+ /* set image to non-transparent bpp while decompressing */
+ if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE)
+ s->bpp -= byte_depth;
+
+ ret = png_decode_idat(s, length);
+
+ if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE)
+ s->bpp += byte_depth;
+
+ if (ret < 0)
+ return ret;
+
+ bytestream2_skip(&s->gb, 4); /* crc */
+
+ return 0;
+}
+
+static int decode_plte_chunk(AVCodecContext *avctx, PNGDecContext *s,
+ uint32_t length)
+{
+ int n, i, r, g, b;
+
+ if ((length % 3) != 0 || length > 256 * 3)
+ return AVERROR_INVALIDDATA;
+ /* read the palette */
+ n = length / 3;
+ for (i = 0; i < n; i++) {
+ r = bytestream2_get_byte(&s->gb);
+ g = bytestream2_get_byte(&s->gb);
+ b = bytestream2_get_byte(&s->gb);
+ s->palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | b;
+ }
+ for (; i < 256; i++)
+ s->palette[i] = (0xFFU << 24);
+ s->state |= PNG_PLTE;
+ bytestream2_skip(&s->gb, 4); /* crc */
+
+ return 0;
+}
+
+static int decode_trns_chunk(AVCodecContext *avctx, PNGDecContext *s,
+ uint32_t length)
+{
+ int v, i;
+
+ if (!(s->state & PNG_IHDR)) {
+ av_log(avctx, AV_LOG_ERROR, "trns before IHDR\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->state & PNG_IDAT) {
+ av_log(avctx, AV_LOG_ERROR, "trns after IDAT\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
+ if (length > 256 || !(s->state & PNG_PLTE))
+ return AVERROR_INVALIDDATA;
+
+ for (i = 0; i < length; i++) {
+ unsigned v = bytestream2_get_byte(&s->gb);
+ s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24);
+ }
+ } else if (s->color_type == PNG_COLOR_TYPE_GRAY || s->color_type == PNG_COLOR_TYPE_RGB) {
+ if ((s->color_type == PNG_COLOR_TYPE_GRAY && length != 2) ||
+ (s->color_type == PNG_COLOR_TYPE_RGB && length != 6) ||
+ s->bit_depth == 1)
+ return AVERROR_INVALIDDATA;
+
+ for (i = 0; i < length / 2; i++) {
+ /* only use the least significant bits */
+ v = bytestream2_get_be16(&s->gb) & ((1 << s->bit_depth) - 1);
+
+ if (s->bit_depth > 8)
+ AV_WB16(&s->transparent_color_be[2 * i], v);
+ else
+ s->transparent_color_be[i] = v;
+ }
+ } else {
+ return AVERROR_INVALIDDATA;
+ }
+
+ bytestream2_skip(&s->gb, 4); /* crc */
+ s->has_trns = 1;
+
+ return 0;
+}
+
+static void handle_small_bpp(PNGDecContext *s, AVFrame *p)
+{
+ if (s->bits_per_pixel == 1 && s->color_type == PNG_COLOR_TYPE_PALETTE) {
+ int i, j, k;
+ uint8_t *pd = p->data[0];
+ for (j = 0; j < s->height; j++) {
+ i = s->width / 8;
+ for (k = 7; k >= 1; k--)
+ if ((s->width&7) >= k)
+ pd[8*i + k - 1] = (pd[i]>>8-k) & 1;
+ for (i--; i >= 0; i--) {
+ pd[8*i + 7]= pd[i] & 1;
+ pd[8*i + 6]= (pd[i]>>1) & 1;
+ pd[8*i + 5]= (pd[i]>>2) & 1;
+ pd[8*i + 4]= (pd[i]>>3) & 1;
+ pd[8*i + 3]= (pd[i]>>4) & 1;
+ pd[8*i + 2]= (pd[i]>>5) & 1;
+ pd[8*i + 1]= (pd[i]>>6) & 1;
+ pd[8*i + 0]= pd[i]>>7;
+ }
+ pd += s->image_linesize;
+ }
+ } else if (s->bits_per_pixel == 2) {
+ int i, j;
+ uint8_t *pd = p->data[0];
+ for (j = 0; j < s->height; j++) {
+ i = s->width / 4;
+ if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
+ if ((s->width&3) >= 3) pd[4*i + 2]= (pd[i] >> 2) & 3;
+ if ((s->width&3) >= 2) pd[4*i + 1]= (pd[i] >> 4) & 3;
+ if ((s->width&3) >= 1) pd[4*i + 0]= pd[i] >> 6;
+ for (i--; i >= 0; i--) {
+ pd[4*i + 3]= pd[i] & 3;
+ pd[4*i + 2]= (pd[i]>>2) & 3;
+ pd[4*i + 1]= (pd[i]>>4) & 3;
+ pd[4*i + 0]= pd[i]>>6;
+ }
+ } else {
+ if ((s->width&3) >= 3) pd[4*i + 2]= ((pd[i]>>2) & 3)*0x55;
+ if ((s->width&3) >= 2) pd[4*i + 1]= ((pd[i]>>4) & 3)*0x55;
+ if ((s->width&3) >= 1) pd[4*i + 0]= ( pd[i]>>6 )*0x55;
+ for (i--; i >= 0; i--) {
+ pd[4*i + 3]= ( pd[i] & 3)*0x55;
+ pd[4*i + 2]= ((pd[i]>>2) & 3)*0x55;
+ pd[4*i + 1]= ((pd[i]>>4) & 3)*0x55;
+ pd[4*i + 0]= ( pd[i]>>6 )*0x55;
+ }
+ }
+ pd += s->image_linesize;
+ }
+ } else if (s->bits_per_pixel == 4) {
+ int i, j;
+ uint8_t *pd = p->data[0];
+ for (j = 0; j < s->height; j++) {
+ i = s->width/2;
+ if (s->color_type == PNG_COLOR_TYPE_PALETTE) {
+ if (s->width&1) pd[2*i+0]= pd[i]>>4;
+ for (i--; i >= 0; i--) {
+ pd[2*i + 1] = pd[i] & 15;
+ pd[2*i + 0] = pd[i] >> 4;
+ }
+ } else {
+ if (s->width & 1) pd[2*i + 0]= (pd[i] >> 4) * 0x11;
+ for (i--; i >= 0; i--) {
+ pd[2*i + 1] = (pd[i] & 15) * 0x11;
+ pd[2*i + 0] = (pd[i] >> 4) * 0x11;
+ }
+ }
+ pd += s->image_linesize;
+ }
+ }
+}
+
+static int decode_fctl_chunk(AVCodecContext *avctx, PNGDecContext *s,
+ uint32_t length)
+{
+ uint32_t sequence_number;
+ int cur_w, cur_h, x_offset, y_offset, dispose_op, blend_op;
+
+ if (length != 26)
+ return AVERROR_INVALIDDATA;
+
+ if (!(s->state & PNG_IHDR)) {
+ av_log(avctx, AV_LOG_ERROR, "fctl before IHDR\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->last_w = s->cur_w;
+ s->last_h = s->cur_h;
+ s->last_x_offset = s->x_offset;
+ s->last_y_offset = s->y_offset;
+ s->last_dispose_op = s->dispose_op;
+
+ sequence_number = bytestream2_get_be32(&s->gb);
+ cur_w = bytestream2_get_be32(&s->gb);
+ cur_h = bytestream2_get_be32(&s->gb);
+ x_offset = bytestream2_get_be32(&s->gb);
+ y_offset = bytestream2_get_be32(&s->gb);
+ bytestream2_skip(&s->gb, 4); /* delay_num (2), delay_den (2) */
+ dispose_op = bytestream2_get_byte(&s->gb);
+ blend_op = bytestream2_get_byte(&s->gb);
+ bytestream2_skip(&s->gb, 4); /* crc */
+
+ if (sequence_number == 0 &&
+ (cur_w != s->width ||
+ cur_h != s->height ||
+ x_offset != 0 ||
+ y_offset != 0) ||
+ cur_w <= 0 || cur_h <= 0 ||
+ x_offset < 0 || y_offset < 0 ||
+ cur_w > s->width - x_offset|| cur_h > s->height - y_offset)
+ return AVERROR_INVALIDDATA;
+
+ if (blend_op != APNG_BLEND_OP_OVER && blend_op != APNG_BLEND_OP_SOURCE) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid blend_op %d\n", blend_op);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (sequence_number == 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
+ dispose_op = APNG_DISPOSE_OP_BACKGROUND;
+ }
+
+ if (blend_op == APNG_BLEND_OP_OVER && !s->has_trns && (
+ avctx->pix_fmt == AV_PIX_FMT_RGB24 ||
+ avctx->pix_fmt == AV_PIX_FMT_RGB48BE ||
+ avctx->pix_fmt == AV_PIX_FMT_PAL8 ||
+ avctx->pix_fmt == AV_PIX_FMT_GRAY8 ||
+ avctx->pix_fmt == AV_PIX_FMT_GRAY16BE ||
+ avctx->pix_fmt == AV_PIX_FMT_MONOBLACK
+ )) {
+ // APNG_BLEND_OP_OVER is the same as APNG_BLEND_OP_SOURCE when there is no alpha channel
+ blend_op = APNG_BLEND_OP_SOURCE;
+ }
+
+ s->cur_w = cur_w;
+ s->cur_h = cur_h;
+ s->x_offset = x_offset;
+ s->y_offset = y_offset;
+ s->dispose_op = dispose_op;
+ s->blend_op = blend_op;
+
+ return 0;
+}
+
+static void handle_p_frame_png(PNGDecContext *s, AVFrame *p)
+{
+ int i, j;
+ uint8_t *pd = p->data[0];
+ uint8_t *pd_last = s->last_picture.f->data[0];
+ int ls = FFMIN(av_image_get_linesize(p->format, s->width, 0), s->width * s->bpp);
+
+ ff_thread_await_progress(&s->last_picture, INT_MAX, 0);
+ 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;
+ }
+}
+
+// divide by 255 and round to nearest
+// apply a fast variant: (X+127)/255 = ((X+127)*257+257)>>16 = ((X+128)*257)>>16
+#define FAST_DIV255(x) ((((x) + 128) * 257) >> 16)
+
+static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s,
+ AVFrame *p)
+{
+ size_t x, y;
+ uint8_t *buffer = av_malloc(s->image_linesize * s->height);
+
+ if (!buffer)
+ return AVERROR(ENOMEM);
+
+ if (s->blend_op == APNG_BLEND_OP_OVER &&
+ avctx->pix_fmt != AV_PIX_FMT_RGBA &&
+ avctx->pix_fmt != AV_PIX_FMT_GRAY8A &&
+ avctx->pix_fmt != AV_PIX_FMT_PAL8) {
+ avpriv_request_sample(avctx, "Blending with pixel format %s",
+ av_get_pix_fmt_name(avctx->pix_fmt));
+ return AVERROR_PATCHWELCOME;
+ }
+
+ // 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);
+
+ 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);
+
+ 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);
+ }
+
+ // Perform blending
+ if (s->blend_op == APNG_BLEND_OP_SOURCE) {
+ 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;
+ 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;
+ uint8_t output[10];
+
+ // Since we might be blending alpha onto alpha, we use the following equations:
+ // output_alpha = foreground_alpha + (1 - foreground_alpha) * background_alpha
+ // output = (foreground_alpha * foreground + (1 - foreground_alpha) * background_alpha * background) / output_alpha
+
+ switch (avctx->pix_fmt) {
+ case AV_PIX_FMT_RGBA:
+ foreground_alpha = foreground[3];
+ background_alpha = background[3];
+ break;
+
+ case AV_PIX_FMT_GRAY8A:
+ foreground_alpha = foreground[1];
+ background_alpha = background[1];
+ break;
+
+ case AV_PIX_FMT_PAL8:
+ foreground_alpha = s->palette[foreground[0]] >> 24;
+ background_alpha = s->palette[background[0]] >> 24;
+ break;
+ }
+
+ if (foreground_alpha == 0)
+ continue;
+
+ if (foreground_alpha == 255) {
+ memcpy(background, foreground, 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;
+ }
+
+ output_alpha = foreground_alpha + FAST_DIV255((255 - foreground_alpha) * background_alpha);
+
+ av_assert0(s->bpp <= 10);
+
+ for (b = 0; b < s->bpp - 1; ++b) {
+ if (output_alpha == 0) {
+ output[b] = 0;
+ } else if (background_alpha == 255) {
+ output[b] = FAST_DIV255(foreground_alpha * foreground[b] + (255 - foreground_alpha) * background[b]);
+ } else {
+ output[b] = (255 * foreground_alpha * foreground[b] + (255 - foreground_alpha) * background_alpha * background[b]) / (255 * output_alpha);
+ }
+ }
+ output[b] = output_alpha;
+ memcpy(background, 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)
+{
+ AVDictionary *metadata = NULL;
+ uint32_t tag, length;
+ int decode_next_dat = 0;
+ int ret;
+
+ for (;;) {
+ length = bytestream2_get_bytes_left(&s->gb);
+ if (length <= 0) {
+ if (CONFIG_APNG_DECODER && avctx->codec_id == AV_CODEC_ID_APNG && length == 0) {
+ if (!(s->state & PNG_IDAT))
+ return 0;
+ else
+ goto exit_loop;
+ }
+ av_log(avctx, AV_LOG_ERROR, "%d bytes left\n", length);
+ if ( s->state & PNG_ALLIMAGE
+ && avctx->strict_std_compliance <= FF_COMPLIANCE_NORMAL)
+ goto exit_loop;
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ length = bytestream2_get_be32(&s->gb);
+ if (length > 0x7fffffff || length > bytestream2_get_bytes_left(&s->gb)) {
+ av_log(avctx, AV_LOG_ERROR, "chunk too big\n");
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ tag = bytestream2_get_le32(&s->gb);
+ if (avctx->debug & FF_DEBUG_STARTCODE)
+ av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n",
+ (tag & 0xff),
+ ((tag >> 8) & 0xff),
+ ((tag >> 16) & 0xff),
+ ((tag >> 24) & 0xff), length);
+ switch (tag) {
+ case MKTAG('I', 'H', 'D', 'R'):
+ if ((ret = decode_ihdr_chunk(avctx, s, length)) < 0)
+ goto fail;
+ break;
+ case MKTAG('p', 'H', 'Y', 's'):
+ if ((ret = decode_phys_chunk(avctx, s)) < 0)
+ goto fail;
+ break;
+ case MKTAG('f', 'c', 'T', 'L'):
+ if (!CONFIG_APNG_DECODER || avctx->codec_id != AV_CODEC_ID_APNG)
+ goto skip_tag;
+ if ((ret = decode_fctl_chunk(avctx, s, length)) < 0)
+ goto fail;
+ decode_next_dat = 1;
+ break;
+ case MKTAG('f', 'd', 'A', 'T'):
+ if (!CONFIG_APNG_DECODER || avctx->codec_id != AV_CODEC_ID_APNG)
+ goto skip_tag;
+ if (!decode_next_dat) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ bytestream2_get_be32(&s->gb);
+ length -= 4;
+ /* fallthrough */
+ case MKTAG('I', 'D', 'A', 'T'):
+ if (CONFIG_APNG_DECODER && avctx->codec_id == AV_CODEC_ID_APNG && !decode_next_dat)
+ goto skip_tag;
+ if ((ret = decode_idat_chunk(avctx, s, length, p)) < 0)
+ goto fail;
+ break;
+ case MKTAG('P', 'L', 'T', 'E'):
+ if (decode_plte_chunk(avctx, s, length) < 0)
+ goto skip_tag;
+ break;
+ case MKTAG('t', 'R', 'N', 'S'):
+ if (decode_trns_chunk(avctx, s, length) < 0)
+ goto skip_tag;
+ break;
+ case MKTAG('t', 'E', 'X', 't'):
+ if (decode_text_chunk(s, length, 0, &metadata) < 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, &metadata) < 0)
+ av_log(avctx, AV_LOG_WARNING, "Broken zTXt chunk\n");
+ bytestream2_skip(&s->gb, length + 4);
+ break;
+ case MKTAG('I', 'E', 'N', 'D'):
+ if (!(s->state & PNG_ALLIMAGE))
+ av_log(avctx, AV_LOG_ERROR, "IEND without all image\n");
+ if (!(s->state & (PNG_ALLIMAGE|PNG_IDAT))) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ bytestream2_skip(&s->gb, 4); /* crc */
+ goto exit_loop;
+ default:
+ /* skip tag */
+skip_tag:
+ bytestream2_skip(&s->gb, length + 4);
+ break;
+ }
+ }
+exit_loop:
+
+ if (s->bits_per_pixel <= 4)
+ handle_small_bpp(s, p);
+
+ /* apply transparency if needed */
+ if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE) {
+ size_t byte_depth = s->bit_depth > 8 ? 2 : 1;
+ size_t raw_bpp = s->bpp - byte_depth;
+ unsigned x, y;
+
+ av_assert0(s->bit_depth > 1);
+
+ for (y = 0; y < s->height; ++y) {
+ uint8_t *row = &s->image_buf[s->image_linesize * y];
+
+ /* since we're updating in-place, we have to go from right to left */
+ for (x = s->width; x > 0; --x) {
+ uint8_t *pixel = &row[s->bpp * (x - 1)];
+ memmove(pixel, &row[raw_bpp * (x - 1)], raw_bpp);
+
+ if (!memcmp(pixel, s->transparent_color_be, raw_bpp)) {
+ memset(&pixel[raw_bpp], 0, byte_depth);
+ } else {
+ memset(&pixel[raw_bpp], 0xff, byte_depth);
+ }
+ }
+ }
+ }
+
+ /* handle p-frames only if a predecessor frame is available */
+ if (s->last_picture.f->data[0]) {
+ if ( !(avpkt->flags & AV_PKT_FLAG_KEY) && avctx->codec_tag != AV_RL32("MPNG")
+ && s->last_picture.f->width == p->width
+ && s->last_picture.f->height== p->height
+ && s->last_picture.f->format== p->format
+ ) {
+ if (CONFIG_PNG_DECODER && avctx->codec_id != AV_CODEC_ID_APNG)
+ handle_p_frame_png(s, p);
+ else if (CONFIG_APNG_DECODER &&
+ 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);
+
+ av_frame_set_metadata(p, metadata);
+ metadata = NULL;
+ return 0;
+
+fail:
+ av_dict_free(&metadata);
+ ff_thread_report_progress(&s->picture, INT_MAX, 0);
+ return ret;
+}
+
+#if CONFIG_PNG_DECODER
+static int decode_frame_png(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ PNGDecContext *const s = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ AVFrame *p;
+ int64_t sig;
+ int ret;
+
+ ff_thread_release_buffer(avctx, &s->last_picture);
+ FFSWAP(ThreadFrame, s->picture, s->last_picture);
+ p = s->picture.f;
+
+ bytestream2_init(&s->gb, buf, buf_size);
+
+ /* check signature */
+ sig = bytestream2_get_be64(&s->gb);
+ if (sig != PNGSIG &&
+ sig != MNGSIG) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid PNG signature 0x%08"PRIX64".\n", sig);
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->y = s->state = s->has_trns = 0;
+
+ /* init the zlib */
+ s->zstream.zalloc = ff_png_zalloc;
+ s->zstream.zfree = ff_png_zfree;
+ s->zstream.opaque = NULL;
+ ret = inflateInit(&s->zstream);
+ if (ret != Z_OK) {
+ av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret);
+ return AVERROR_EXTERNAL;
+ }
+
+ if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0)
+ goto the_end;
+
+ if ((ret = av_frame_ref(data, s->picture.f)) < 0)
+ return ret;
+
+ *got_frame = 1;
+
+ ret = bytestream2_tell(&s->gb);
+the_end:
+ inflateEnd(&s->zstream);
+ s->crow_buf = NULL;
+ return ret;
+}
+#endif
+
+#if CONFIG_APNG_DECODER
+static int decode_frame_apng(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ PNGDecContext *const s = avctx->priv_data;
+ int ret;
+ AVFrame *p;
+
+ ff_thread_release_buffer(avctx, &s->last_picture);
+ FFSWAP(ThreadFrame, s->picture, s->last_picture);
+ p = s->picture.f;
+
+ if (!(s->state & PNG_IHDR)) {
+ if (!avctx->extradata_size)
+ return AVERROR_INVALIDDATA;
+
+ /* only init fields, there is no zlib use in extradata */
+ s->zstream.zalloc = ff_png_zalloc;
+ s->zstream.zfree = ff_png_zfree;
+
+ bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size);
+ if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0)
+ goto end;
+ }
+
+ /* reset state for a new frame */
+ if ((ret = inflateInit(&s->zstream)) != Z_OK) {
+ av_log(avctx, AV_LOG_ERROR, "inflateInit returned error %d\n", ret);
+ ret = AVERROR_EXTERNAL;
+ goto end;
+ }
+ s->y = 0;
+ s->state &= ~(PNG_IDAT | PNG_ALLIMAGE);
+ bytestream2_init(&s->gb, avpkt->data, avpkt->size);
+ if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0)
+ goto end;
+
+ if (!(s->state & PNG_ALLIMAGE))
+ av_log(avctx, AV_LOG_WARNING, "Frame did not contain a complete image\n");
+ if (!(s->state & (PNG_ALLIMAGE|PNG_IDAT))) {
+ ret = AVERROR_INVALIDDATA;
+ goto end;
+ }
+ if ((ret = av_frame_ref(data, s->picture.f)) < 0)
+ goto end;
+
+ *got_frame = 1;
+ ret = bytestream2_tell(&s->gb);
+
+end:
+ inflateEnd(&s->zstream);
+ return ret;
+}
+#endif
+
+static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
+{
+ PNGDecContext *psrc = src->priv_data;
+ PNGDecContext *pdst = dst->priv_data;
+ 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;
+ pdst->color_type = psrc->color_type;
+ pdst->compression_type = psrc->compression_type;
+ pdst->interlace_type = psrc->interlace_type;
+ pdst->filter_type = psrc->filter_type;
+ pdst->cur_w = psrc->cur_w;
+ pdst->cur_h = psrc->cur_h;
+ pdst->x_offset = psrc->x_offset;
+ pdst->y_offset = psrc->y_offset;
+ pdst->has_trns = psrc->has_trns;
+ memcpy(pdst->transparent_color_be, psrc->transparent_color_be, sizeof(pdst->transparent_color_be));
+
+ pdst->dispose_op = psrc->dispose_op;
+
+ memcpy(pdst->palette, psrc->palette, sizeof(pdst->palette));
+
+ pdst->state |= psrc->state & (PNG_IHDR | PNG_PLTE);
+
+ 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;
+
+ 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)
+ return ret;
+ }
+
+ return 0;
+}
+
+static av_cold int png_dec_init(AVCodecContext *avctx)
+{
+ PNGDecContext *s = avctx->priv_data;
+
+ avctx->color_range = AVCOL_RANGE_JPEG;
+
+ 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);
+ av_frame_free(&s->last_picture.f);
+ av_frame_free(&s->picture.f);
+ return AVERROR(ENOMEM);
+ }
+
+ if (!avctx->internal->is_copy) {
+ avctx->internal->allocate_progress = 1;
+ ff_pngdsp_init(&s->dsp);
+ }
+
+ return 0;
+}
+
+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);
+ av_frame_free(&s->picture.f);
+ av_freep(&s->buffer);
+ s->buffer_size = 0;
+ av_freep(&s->last_row);
+ s->last_row_size = 0;
+ av_freep(&s->tmp_row);
+ s->tmp_row_size = 0;
+
+ return 0;
+}
+
+#if CONFIG_APNG_DECODER
+AVCodec ff_apng_decoder = {
+ .name = "apng",
+ .long_name = NULL_IF_CONFIG_SMALL("APNG (Animated Portable Network Graphics) image"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_APNG,
+ .priv_data_size = sizeof(PNGDecContext),
+ .init = png_dec_init,
+ .close = png_dec_end,
+ .decode = decode_frame_apng,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(png_dec_init),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/,
+};
+#endif
+
+#if CONFIG_PNG_DECODER
+AVCodec ff_png_decoder = {
+ .name = "png",
+ .long_name = NULL_IF_CONFIG_SMALL("PNG (Portable Network Graphics) image"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_PNG,
+ .priv_data_size = sizeof(PNGDecContext),
+ .init = png_dec_init,
+ .close = png_dec_end,
+ .decode = decode_frame_png,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(png_dec_init),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/,
+};
+#endif
diff --git a/ffmpeg-2-8-11/libavcodec/pngdsp.c b/ffmpeg-2-8-12/libavcodec/pngdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pngdsp.c
rename to ffmpeg-2-8-12/libavcodec/pngdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/pngdsp.h b/ffmpeg-2-8-12/libavcodec/pngdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pngdsp.h
rename to ffmpeg-2-8-12/libavcodec/pngdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/pngenc.c b/ffmpeg-2-8-12/libavcodec/pngenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pngenc.c
rename to ffmpeg-2-8-12/libavcodec/pngenc.c
diff --git a/ffmpeg-2-8-12/libavcodec/pnm.c b/ffmpeg-2-8-12/libavcodec/pnm.c
new file mode 100644
index 0000000..8b4a4ac
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/pnm.c
@@ -0,0 +1,201 @@
+/*
+ * PNM image format
+ * Copyright (c) 2002, 2003 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 <stdlib.h>
+#include <string.h>
+
+#include "libavutil/imgutils.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "pnm.h"
+
+static inline int pnm_space(int c)
+{
+ return c == ' ' || c == '\n' || c == '\r' || c == '\t';
+}
+
+static void pnm_get(PNMContext *sc, char *str, int buf_size)
+{
+ char *s;
+ int c;
+
+ /* skip spaces and comments */
+ while (sc->bytestream < sc->bytestream_end) {
+ c = *sc->bytestream++;
+ if (c == '#') {
+ while (c != '\n' && sc->bytestream < sc->bytestream_end) {
+ c = *sc->bytestream++;
+ }
+ } else if (!pnm_space(c)) {
+ break;
+ }
+ }
+
+ s = str;
+ while (sc->bytestream < sc->bytestream_end && !pnm_space(c)) {
+ if ((s - str) < buf_size - 1)
+ *s++ = c;
+ c = *sc->bytestream++;
+ }
+ *s = '\0';
+}
+
+int ff_pnm_decode_header(AVCodecContext *avctx, PNMContext * const s)
+{
+ char buf1[32], tuple_type[32];
+ int h, w, depth, maxval;
+ int ret;
+
+ pnm_get(s, buf1, sizeof(buf1));
+ if(buf1[0] != 'P')
+ return AVERROR_INVALIDDATA;
+ s->type= buf1[1]-'0';
+
+ if (s->type==1 || s->type==4) {
+ avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
+ } else if (s->type==2 || s->type==5) {
+ if (avctx->codec_id == AV_CODEC_ID_PGMYUV)
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+ else
+ avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+ } else if (s->type==3 || s->type==6) {
+ avctx->pix_fmt = AV_PIX_FMT_RGB24;
+ } else if (s->type==7) {
+ w = -1;
+ h = -1;
+ maxval = -1;
+ depth = -1;
+ tuple_type[0] = '\0';
+ for (;;) {
+ pnm_get(s, buf1, sizeof(buf1));
+ if (!strcmp(buf1, "WIDTH")) {
+ pnm_get(s, buf1, sizeof(buf1));
+ w = strtol(buf1, NULL, 10);
+ } else if (!strcmp(buf1, "HEIGHT")) {
+ pnm_get(s, buf1, sizeof(buf1));
+ h = strtol(buf1, NULL, 10);
+ } else if (!strcmp(buf1, "DEPTH")) {
+ pnm_get(s, buf1, sizeof(buf1));
+ depth = strtol(buf1, NULL, 10);
+ } else if (!strcmp(buf1, "MAXVAL")) {
+ pnm_get(s, buf1, sizeof(buf1));
+ maxval = strtol(buf1, NULL, 10);
+ } else if (!strcmp(buf1, "TUPLTYPE") ||
+ /* libavcodec used to write invalid files */
+ !strcmp(buf1, "TUPLETYPE")) {
+ pnm_get(s, tuple_type, sizeof(tuple_type));
+ } else if (!strcmp(buf1, "ENDHDR")) {
+ break;
+ } else {
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ /* check that all tags are present */
+ if (w <= 0 || h <= 0 || maxval <= 0 || depth <= 0 || tuple_type[0] == '\0' || av_image_check_size(w, h, 0, avctx) || s->bytestream >= s->bytestream_end)
+ return AVERROR_INVALIDDATA;
+
+ ret = ff_set_dimensions(avctx, w, h);
+ if (ret < 0)
+ return ret;
+ s->maxval = maxval;
+ if (depth == 1) {
+ if (maxval == 1) {
+ avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
+ } else if (maxval < 256) {
+ avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+ } else {
+ avctx->pix_fmt = AV_PIX_FMT_GRAY16;
+ }
+ } else if (depth == 2) {
+ if (maxval < 256) {
+ avctx->pix_fmt = AV_PIX_FMT_GRAY8A;
+ } else {
+ avctx->pix_fmt = AV_PIX_FMT_YA16;
+ }
+ } else if (depth == 3) {
+ if (maxval < 256) {
+ avctx->pix_fmt = AV_PIX_FMT_RGB24;
+ } else {
+ avctx->pix_fmt = AV_PIX_FMT_RGB48;
+ }
+ } else if (depth == 4) {
+ if (maxval < 256) {
+ avctx->pix_fmt = AV_PIX_FMT_RGBA;
+ } else {
+ avctx->pix_fmt = AV_PIX_FMT_RGBA64;
+ }
+ } else {
+ return AVERROR_INVALIDDATA;
+ }
+ return 0;
+ } else {
+ return AVERROR_INVALIDDATA;
+ }
+ pnm_get(s, buf1, sizeof(buf1));
+ w = atoi(buf1);
+ pnm_get(s, buf1, sizeof(buf1));
+ h = atoi(buf1);
+ if(w <= 0 || h <= 0 || av_image_check_size(w, h, 0, avctx) || s->bytestream >= s->bytestream_end)
+ return AVERROR_INVALIDDATA;
+
+ ret = ff_set_dimensions(avctx, w, h);
+ if (ret < 0)
+ return ret;
+
+ if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE && avctx->pix_fmt != AV_PIX_FMT_MONOBLACK) {
+ pnm_get(s, buf1, sizeof(buf1));
+ s->maxval = atoi(buf1);
+ if (s->maxval <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid maxval: %d\n", s->maxval);
+ s->maxval = 255;
+ }
+ if (s->maxval >= 256) {
+ if (avctx->pix_fmt == AV_PIX_FMT_GRAY8) {
+ avctx->pix_fmt = AV_PIX_FMT_GRAY16;
+ } else if (avctx->pix_fmt == AV_PIX_FMT_RGB24) {
+ avctx->pix_fmt = AV_PIX_FMT_RGB48;
+ } else if (avctx->pix_fmt == AV_PIX_FMT_YUV420P && s->maxval < 65536) {
+ if (s->maxval < 512)
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P9;
+ else if (s->maxval < 1024)
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P10;
+ else
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P16;
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format\n");
+ avctx->pix_fmt = AV_PIX_FMT_NONE;
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ }else
+ s->maxval=1;
+ /* more check if YUV420 */
+ if (av_pix_fmt_desc_get(avctx->pix_fmt)->flags & AV_PIX_FMT_FLAG_PLANAR) {
+ if ((avctx->width & 1) != 0)
+ return AVERROR_INVALIDDATA;
+ h = (avctx->height * 2);
+ if ((h % 3) != 0)
+ return AVERROR_INVALIDDATA;
+ h /= 3;
+ avctx->height = h;
+ }
+ return 0;
+}
diff --git a/ffmpeg-2-8-11/libavcodec/pnm.h b/ffmpeg-2-8-12/libavcodec/pnm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pnm.h
rename to ffmpeg-2-8-12/libavcodec/pnm.h
diff --git a/ffmpeg-2-8-11/libavcodec/pnm_parser.c b/ffmpeg-2-8-12/libavcodec/pnm_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pnm_parser.c
rename to ffmpeg-2-8-12/libavcodec/pnm_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/pnmdec.c b/ffmpeg-2-8-12/libavcodec/pnmdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pnmdec.c
rename to ffmpeg-2-8-12/libavcodec/pnmdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/pnmenc.c b/ffmpeg-2-8-12/libavcodec/pnmenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pnmenc.c
rename to ffmpeg-2-8-12/libavcodec/pnmenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/Makefile b/ffmpeg-2-8-12/libavcodec/ppc/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/Makefile
rename to ffmpeg-2-8-12/libavcodec/ppc/Makefile
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/asm.S b/ffmpeg-2-8-12/libavcodec/ppc/asm.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/asm.S
rename to ffmpeg-2-8-12/libavcodec/ppc/asm.S
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/audiodsp.c b/ffmpeg-2-8-12/libavcodec/ppc/audiodsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/audiodsp.c
rename to ffmpeg-2-8-12/libavcodec/ppc/audiodsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/blockdsp.c b/ffmpeg-2-8-12/libavcodec/ppc/blockdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/blockdsp.c
rename to ffmpeg-2-8-12/libavcodec/ppc/blockdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/dct-test.c b/ffmpeg-2-8-12/libavcodec/ppc/dct-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/dct-test.c
rename to ffmpeg-2-8-12/libavcodec/ppc/dct-test.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/fdct.h b/ffmpeg-2-8-12/libavcodec/ppc/fdct.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/fdct.h
rename to ffmpeg-2-8-12/libavcodec/ppc/fdct.h
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/fdctdsp.c b/ffmpeg-2-8-12/libavcodec/ppc/fdctdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/fdctdsp.c
rename to ffmpeg-2-8-12/libavcodec/ppc/fdctdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/fft_altivec.S b/ffmpeg-2-8-12/libavcodec/ppc/fft_altivec.S
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/fft_altivec.S
rename to ffmpeg-2-8-12/libavcodec/ppc/fft_altivec.S
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/fft_init.c b/ffmpeg-2-8-12/libavcodec/ppc/fft_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/fft_init.c
rename to ffmpeg-2-8-12/libavcodec/ppc/fft_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/fft_vsx.c b/ffmpeg-2-8-12/libavcodec/ppc/fft_vsx.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/fft_vsx.c
rename to ffmpeg-2-8-12/libavcodec/ppc/fft_vsx.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/fft_vsx.h b/ffmpeg-2-8-12/libavcodec/ppc/fft_vsx.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/fft_vsx.h
rename to ffmpeg-2-8-12/libavcodec/ppc/fft_vsx.h
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/fmtconvert_altivec.c b/ffmpeg-2-8-12/libavcodec/ppc/fmtconvert_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/fmtconvert_altivec.c
rename to ffmpeg-2-8-12/libavcodec/ppc/fmtconvert_altivec.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/h264chroma_init.c b/ffmpeg-2-8-12/libavcodec/ppc/h264chroma_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/h264chroma_init.c
rename to ffmpeg-2-8-12/libavcodec/ppc/h264chroma_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/h264chroma_template.c b/ffmpeg-2-8-12/libavcodec/ppc/h264chroma_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/h264chroma_template.c
rename to ffmpeg-2-8-12/libavcodec/ppc/h264chroma_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/h264dsp.c b/ffmpeg-2-8-12/libavcodec/ppc/h264dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/h264dsp.c
rename to ffmpeg-2-8-12/libavcodec/ppc/h264dsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/h264qpel.c b/ffmpeg-2-8-12/libavcodec/ppc/h264qpel.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/h264qpel.c
rename to ffmpeg-2-8-12/libavcodec/ppc/h264qpel.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/h264qpel_template.c b/ffmpeg-2-8-12/libavcodec/ppc/h264qpel_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/h264qpel_template.c
rename to ffmpeg-2-8-12/libavcodec/ppc/h264qpel_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/hpeldsp_altivec.c b/ffmpeg-2-8-12/libavcodec/ppc/hpeldsp_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/hpeldsp_altivec.c
rename to ffmpeg-2-8-12/libavcodec/ppc/hpeldsp_altivec.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/hpeldsp_altivec.h b/ffmpeg-2-8-12/libavcodec/ppc/hpeldsp_altivec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/hpeldsp_altivec.h
rename to ffmpeg-2-8-12/libavcodec/ppc/hpeldsp_altivec.h
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/huffyuvdsp_altivec.c b/ffmpeg-2-8-12/libavcodec/ppc/huffyuvdsp_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/huffyuvdsp_altivec.c
rename to ffmpeg-2-8-12/libavcodec/ppc/huffyuvdsp_altivec.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/idctdsp.c b/ffmpeg-2-8-12/libavcodec/ppc/idctdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/idctdsp.c
rename to ffmpeg-2-8-12/libavcodec/ppc/idctdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/lossless_audiodsp_altivec.c b/ffmpeg-2-8-12/libavcodec/ppc/lossless_audiodsp_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/lossless_audiodsp_altivec.c
rename to ffmpeg-2-8-12/libavcodec/ppc/lossless_audiodsp_altivec.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/mathops.h b/ffmpeg-2-8-12/libavcodec/ppc/mathops.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/mathops.h
rename to ffmpeg-2-8-12/libavcodec/ppc/mathops.h
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/me_cmp.c b/ffmpeg-2-8-12/libavcodec/ppc/me_cmp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/me_cmp.c
rename to ffmpeg-2-8-12/libavcodec/ppc/me_cmp.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/mpegaudiodsp_altivec.c b/ffmpeg-2-8-12/libavcodec/ppc/mpegaudiodsp_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/mpegaudiodsp_altivec.c
rename to ffmpeg-2-8-12/libavcodec/ppc/mpegaudiodsp_altivec.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/mpegvideo_altivec.c b/ffmpeg-2-8-12/libavcodec/ppc/mpegvideo_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/mpegvideo_altivec.c
rename to ffmpeg-2-8-12/libavcodec/ppc/mpegvideo_altivec.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/mpegvideodsp.c b/ffmpeg-2-8-12/libavcodec/ppc/mpegvideodsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/mpegvideodsp.c
rename to ffmpeg-2-8-12/libavcodec/ppc/mpegvideodsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/mpegvideoencdsp.c b/ffmpeg-2-8-12/libavcodec/ppc/mpegvideoencdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/mpegvideoencdsp.c
rename to ffmpeg-2-8-12/libavcodec/ppc/mpegvideoencdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/pixblockdsp.c b/ffmpeg-2-8-12/libavcodec/ppc/pixblockdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/pixblockdsp.c
rename to ffmpeg-2-8-12/libavcodec/ppc/pixblockdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/svq1enc_altivec.c b/ffmpeg-2-8-12/libavcodec/ppc/svq1enc_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/svq1enc_altivec.c
rename to ffmpeg-2-8-12/libavcodec/ppc/svq1enc_altivec.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/vc1dsp_altivec.c b/ffmpeg-2-8-12/libavcodec/ppc/vc1dsp_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/vc1dsp_altivec.c
rename to ffmpeg-2-8-12/libavcodec/ppc/vc1dsp_altivec.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/videodsp_ppc.c b/ffmpeg-2-8-12/libavcodec/ppc/videodsp_ppc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/videodsp_ppc.c
rename to ffmpeg-2-8-12/libavcodec/ppc/videodsp_ppc.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/vorbisdsp_altivec.c b/ffmpeg-2-8-12/libavcodec/ppc/vorbisdsp_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/vorbisdsp_altivec.c
rename to ffmpeg-2-8-12/libavcodec/ppc/vorbisdsp_altivec.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/vp3dsp_altivec.c b/ffmpeg-2-8-12/libavcodec/ppc/vp3dsp_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/vp3dsp_altivec.c
rename to ffmpeg-2-8-12/libavcodec/ppc/vp3dsp_altivec.c
diff --git a/ffmpeg-2-8-11/libavcodec/ppc/vp8dsp_altivec.c b/ffmpeg-2-8-12/libavcodec/ppc/vp8dsp_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ppc/vp8dsp_altivec.c
rename to ffmpeg-2-8-12/libavcodec/ppc/vp8dsp_altivec.c
diff --git a/ffmpeg-2-8-11/libavcodec/proresdata.c b/ffmpeg-2-8-12/libavcodec/proresdata.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/proresdata.c
rename to ffmpeg-2-8-12/libavcodec/proresdata.c
diff --git a/ffmpeg-2-8-11/libavcodec/proresdata.h b/ffmpeg-2-8-12/libavcodec/proresdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/proresdata.h
rename to ffmpeg-2-8-12/libavcodec/proresdata.h
diff --git a/ffmpeg-2-8-11/libavcodec/proresdec.h b/ffmpeg-2-8-12/libavcodec/proresdec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/proresdec.h
rename to ffmpeg-2-8-12/libavcodec/proresdec.h
diff --git a/ffmpeg-2-8-11/libavcodec/proresdec2.c b/ffmpeg-2-8-12/libavcodec/proresdec2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/proresdec2.c
rename to ffmpeg-2-8-12/libavcodec/proresdec2.c
diff --git a/ffmpeg-2-8-11/libavcodec/proresdec_lgpl.c b/ffmpeg-2-8-12/libavcodec/proresdec_lgpl.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/proresdec_lgpl.c
rename to ffmpeg-2-8-12/libavcodec/proresdec_lgpl.c
diff --git a/ffmpeg-2-8-11/libavcodec/proresdsp.c b/ffmpeg-2-8-12/libavcodec/proresdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/proresdsp.c
rename to ffmpeg-2-8-12/libavcodec/proresdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/proresdsp.h b/ffmpeg-2-8-12/libavcodec/proresdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/proresdsp.h
rename to ffmpeg-2-8-12/libavcodec/proresdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/proresenc_anatoliy.c b/ffmpeg-2-8-12/libavcodec/proresenc_anatoliy.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/proresenc_anatoliy.c
rename to ffmpeg-2-8-12/libavcodec/proresenc_anatoliy.c
diff --git a/ffmpeg-2-8-11/libavcodec/proresenc_kostya.c b/ffmpeg-2-8-12/libavcodec/proresenc_kostya.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/proresenc_kostya.c
rename to ffmpeg-2-8-12/libavcodec/proresenc_kostya.c
diff --git a/ffmpeg-2-8-11/libavcodec/psymodel.c b/ffmpeg-2-8-12/libavcodec/psymodel.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/psymodel.c
rename to ffmpeg-2-8-12/libavcodec/psymodel.c
diff --git a/ffmpeg-2-8-11/libavcodec/psymodel.h b/ffmpeg-2-8-12/libavcodec/psymodel.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/psymodel.h
rename to ffmpeg-2-8-12/libavcodec/psymodel.h
diff --git a/ffmpeg-2-8-11/libavcodec/pthread.c b/ffmpeg-2-8-12/libavcodec/pthread.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pthread.c
rename to ffmpeg-2-8-12/libavcodec/pthread.c
diff --git a/ffmpeg-2-8-11/libavcodec/pthread_frame.c b/ffmpeg-2-8-12/libavcodec/pthread_frame.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pthread_frame.c
rename to ffmpeg-2-8-12/libavcodec/pthread_frame.c
diff --git a/ffmpeg-2-8-11/libavcodec/pthread_internal.h b/ffmpeg-2-8-12/libavcodec/pthread_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pthread_internal.h
rename to ffmpeg-2-8-12/libavcodec/pthread_internal.h
diff --git a/ffmpeg-2-8-11/libavcodec/pthread_slice.c b/ffmpeg-2-8-12/libavcodec/pthread_slice.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/pthread_slice.c
rename to ffmpeg-2-8-12/libavcodec/pthread_slice.c
diff --git a/ffmpeg-2-8-11/libavcodec/ptx.c b/ffmpeg-2-8-12/libavcodec/ptx.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ptx.c
rename to ffmpeg-2-8-12/libavcodec/ptx.c
diff --git a/ffmpeg-2-8-11/libavcodec/put_bits.h b/ffmpeg-2-8-12/libavcodec/put_bits.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/put_bits.h
rename to ffmpeg-2-8-12/libavcodec/put_bits.h
diff --git a/ffmpeg-2-8-11/libavcodec/qcelpdata.h b/ffmpeg-2-8-12/libavcodec/qcelpdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qcelpdata.h
rename to ffmpeg-2-8-12/libavcodec/qcelpdata.h
diff --git a/ffmpeg-2-8-11/libavcodec/qcelpdec.c b/ffmpeg-2-8-12/libavcodec/qcelpdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qcelpdec.c
rename to ffmpeg-2-8-12/libavcodec/qcelpdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/qdm2.c b/ffmpeg-2-8-12/libavcodec/qdm2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qdm2.c
rename to ffmpeg-2-8-12/libavcodec/qdm2.c
diff --git a/ffmpeg-2-8-11/libavcodec/qdm2_tablegen.c b/ffmpeg-2-8-12/libavcodec/qdm2_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qdm2_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/qdm2_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/qdm2_tablegen.h b/ffmpeg-2-8-12/libavcodec/qdm2_tablegen.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qdm2_tablegen.h
rename to ffmpeg-2-8-12/libavcodec/qdm2_tablegen.h
diff --git a/ffmpeg-2-8-11/libavcodec/qdm2data.h b/ffmpeg-2-8-12/libavcodec/qdm2data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qdm2data.h
rename to ffmpeg-2-8-12/libavcodec/qdm2data.h
diff --git a/ffmpeg-2-8-12/libavcodec/qdrw.c b/ffmpeg-2-8-12/libavcodec/qdrw.c
new file mode 100644
index 0000000..a7ea45f
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/qdrw.c
@@ -0,0 +1,347 @@
+/*
+ * QuickDraw (qdrw) codec
+ * Copyright (c) 2004 Konstantin Shishkov
+ * Copyright (c) 2015 Vittorio Giovara
+ *
+ * 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
+ * Apple QuickDraw codec.
+ * https://developer.apple.com/legacy/library/documentation/mac/QuickDraw/QuickDraw-461.html
+ */
+
+#include "libavutil/common.h"
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+
+enum QuickdrawOpcodes {
+ PACKBITSRECT = 0x0098,
+ PACKBITSRGN,
+ DIRECTBITSRECT,
+ DIRECTBITSRGN,
+
+ EOP = 0x00FF,
+};
+
+static int parse_palette(AVCodecContext *avctx, GetByteContext *gbc,
+ uint32_t *pal, int colors)
+{
+ int i;
+
+ for (i = 0; i <= colors; i++) {
+ uint8_t r, g, b;
+ unsigned int idx = bytestream2_get_be16(gbc); /* color index */
+ if (idx > 255) {
+ av_log(avctx, AV_LOG_WARNING,
+ "Palette index out of range: %u\n", idx);
+ bytestream2_skip(gbc, 6);
+ continue;
+ }
+ if (avctx->pix_fmt != AV_PIX_FMT_PAL8)
+ return AVERROR_INVALIDDATA;
+ r = bytestream2_get_byte(gbc);
+ bytestream2_skip(gbc, 1);
+ g = bytestream2_get_byte(gbc);
+ bytestream2_skip(gbc, 1);
+ b = bytestream2_get_byte(gbc);
+ bytestream2_skip(gbc, 1);
+ pal[idx] = (0xFFU << 24) | (r << 16) | (g << 8) | b;
+ }
+ return 0;
+}
+
+static int decode_rle(AVCodecContext *avctx, AVFrame *p, GetByteContext *gbc,
+ int step)
+{
+ int i, j;
+ int offset = avctx->width * step;
+ uint8_t *outdata = p->data[0];
+
+ for (i = 0; i < avctx->height; i++) {
+ int size, left, code, pix;
+ uint8_t *out = outdata;
+ int pos = 0;
+
+ /* size of packed line */
+ size = left = bytestream2_get_be16(gbc);
+ if (bytestream2_get_bytes_left(gbc) < size)
+ return AVERROR_INVALIDDATA;
+
+ /* decode line */
+ while (left > 0) {
+ code = bytestream2_get_byte(gbc);
+ if (code & 0x80 ) { /* run */
+ pix = bytestream2_get_byte(gbc);
+ for (j = 0; j < 257 - code; j++) {
+ out[pos] = pix;
+ pos += step;
+ if (pos >= offset) {
+ pos -= offset;
+ pos++;
+ }
+ if (pos >= offset)
+ return AVERROR_INVALIDDATA;
+ }
+ left -= 2;
+ } else { /* copy */
+ for (j = 0; j < code + 1; j++) {
+ out[pos] = bytestream2_get_byte(gbc);
+ pos += step;
+ if (pos >= offset) {
+ pos -= offset;
+ pos++;
+ }
+ if (pos >= offset)
+ return AVERROR_INVALIDDATA;
+ }
+ left -= 2 + code;
+ }
+ }
+ outdata += p->linesize[0];
+ }
+ return 0;
+}
+
+static int check_header(const char *buf, int buf_size)
+{
+ unsigned w, h, v0, v1;
+
+ if (buf_size < 40)
+ return 0;
+
+ w = AV_RB16(buf+6);
+ h = AV_RB16(buf+8);
+ v0 = AV_RB16(buf+10);
+ v1 = AV_RB16(buf+12);
+
+ if (!w || !h)
+ return 0;
+
+ if (v0 == 0x1101)
+ return 1;
+ if (v0 == 0x0011 && v1 == 0x02FF)
+ return 2;
+ return 0;
+}
+
+
+static int decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ AVFrame * const p = data;
+ GetByteContext gbc;
+ int colors;
+ int w, h, ret;
+ int ver;
+
+ bytestream2_init(&gbc, avpkt->data, avpkt->size);
+ if ( bytestream2_get_bytes_left(&gbc) >= 552
+ && check_header(gbc.buffer + 512, bytestream2_get_bytes_left(&gbc) - 512)
+ )
+ bytestream2_skip(&gbc, 512);
+
+ ver = check_header(gbc.buffer, bytestream2_get_bytes_left(&gbc));
+
+ /* smallest PICT header */
+ if (bytestream2_get_bytes_left(&gbc) < 40) {
+ av_log(avctx, AV_LOG_ERROR, "Frame is too small %d\n",
+ bytestream2_get_bytes_left(&gbc));
+ return AVERROR_INVALIDDATA;
+ }
+
+ bytestream2_skip(&gbc, 6);
+ h = bytestream2_get_be16(&gbc);
+ w = bytestream2_get_be16(&gbc);
+
+ ret = ff_set_dimensions(avctx, w, h);
+ if (ret < 0)
+ return ret;
+
+ /* version 1 is identified by 0x1101
+ * it uses byte-aligned opcodes rather than word-aligned */
+ if (ver == 1) {
+ avpriv_request_sample(avctx, "QuickDraw version 1");
+ return AVERROR_PATCHWELCOME;
+ } else if (ver != 2) {
+ avpriv_request_sample(avctx, "QuickDraw version unknown (%X)", bytestream2_get_be32(&gbc));
+ return AVERROR_PATCHWELCOME;
+ }
+
+ bytestream2_skip(&gbc, 4+26);
+
+ while (bytestream2_get_bytes_left(&gbc) >= 4) {
+ int bppcnt, bpp;
+ int rowbytes, pack_type;
+ int opcode = bytestream2_get_be16(&gbc);
+
+ switch(opcode) {
+ case PACKBITSRECT:
+ case PACKBITSRGN:
+ av_log(avctx, AV_LOG_DEBUG, "Parsing Packbit opcode\n");
+
+ bytestream2_skip(&gbc, 30);
+ bppcnt = bytestream2_get_be16(&gbc); /* cmpCount */
+ bpp = bytestream2_get_be16(&gbc); /* cmpSize */
+
+ av_log(avctx, AV_LOG_DEBUG, "bppcount %d bpp %d\n", bppcnt, bpp);
+ if (bppcnt == 1 && bpp == 8) {
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ } else {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid pixel format (bppcnt %d bpp %d) in Packbit\n",
+ bppcnt, bpp);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* jump to palette */
+ bytestream2_skip(&gbc, 18);
+ colors = bytestream2_get_be16(&gbc);
+
+ if (colors < 0 || colors > 256) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Error color count - %i(0x%X)\n", colors, colors);
+ return AVERROR_INVALIDDATA;
+ }
+ if (bytestream2_get_bytes_left(&gbc) < (colors + 1) * 8) {
+ av_log(avctx, AV_LOG_ERROR, "Palette is too small %d\n",
+ bytestream2_get_bytes_left(&gbc));
+ return AVERROR_INVALIDDATA;
+ }
+ if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
+ return ret;
+
+ ret = parse_palette(avctx, &gbc, (uint32_t *)p->data[1], colors);
+ if (ret < 0)
+ return ret;
+ p->palette_has_changed = 1;
+
+ /* jump to image data */
+ bytestream2_skip(&gbc, 18);
+
+ if (opcode == PACKBITSRGN) {
+ bytestream2_skip(&gbc, 2 + 8); /* size + rect */
+ avpriv_report_missing_feature(avctx, "Packbit mask region");
+ }
+
+ ret = decode_rle(avctx, p, &gbc, bppcnt);
+ if (ret < 0)
+ return ret;
+ *got_frame = 1;
+ break;
+ case DIRECTBITSRECT:
+ case DIRECTBITSRGN:
+ av_log(avctx, AV_LOG_DEBUG, "Parsing Directbit opcode\n");
+
+ bytestream2_skip(&gbc, 4);
+ rowbytes = bytestream2_get_be16(&gbc) & 0x3FFF;
+ if (rowbytes <= 250) {
+ avpriv_report_missing_feature(avctx, "Short rowbytes");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ bytestream2_skip(&gbc, 10);
+ pack_type = bytestream2_get_be16(&gbc);
+
+ bytestream2_skip(&gbc, 16);
+ bppcnt = bytestream2_get_be16(&gbc); /* cmpCount */
+ bpp = bytestream2_get_be16(&gbc); /* cmpSize */
+
+ av_log(avctx, AV_LOG_DEBUG, "bppcount %d bpp %d\n", bppcnt, bpp);
+ if (bppcnt == 3 && bpp == 8) {
+ avctx->pix_fmt = AV_PIX_FMT_RGB24;
+ } else if (bppcnt == 4 && bpp == 8) {
+ avctx->pix_fmt = AV_PIX_FMT_ARGB;
+ } else {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid pixel format (bppcnt %d bpp %d) in Directbit\n",
+ bppcnt, bpp);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* set packing when default is selected */
+ if (pack_type == 0)
+ pack_type = bppcnt;
+
+ if (pack_type != 3 && pack_type != 4) {
+ avpriv_request_sample(avctx, "Pack type %d", pack_type);
+ return AVERROR_PATCHWELCOME;
+ }
+ if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+
+ /* jump to data */
+ bytestream2_skip(&gbc, 30);
+
+ if (opcode == DIRECTBITSRGN) {
+ bytestream2_skip(&gbc, 2 + 8); /* size + rect */
+ avpriv_report_missing_feature(avctx, "DirectBit mask region");
+ }
+
+ ret = decode_rle(avctx, p, &gbc, bppcnt);
+ if (ret < 0)
+ return ret;
+ *got_frame = 1;
+ break;
+ default:
+ av_log(avctx, AV_LOG_TRACE, "Unknown 0x%04X opcode\n", opcode);
+ break;
+ }
+ /* exit the loop when a known pixel block has been found */
+ if (*got_frame) {
+ int eop, trail;
+
+ /* re-align to a word */
+ bytestream2_skip(&gbc, bytestream2_get_bytes_left(&gbc) % 2);
+
+ eop = bytestream2_get_be16(&gbc);
+ trail = bytestream2_get_bytes_left(&gbc);
+ if (eop != EOP)
+ av_log(avctx, AV_LOG_WARNING,
+ "Missing end of picture opcode (found 0x%04X)\n", eop);
+ if (trail)
+ av_log(avctx, AV_LOG_WARNING, "Got %d trailing bytes\n", trail);
+ break;
+ }
+ }
+
+ if (*got_frame) {
+ p->pict_type = AV_PICTURE_TYPE_I;
+ p->key_frame = 1;
+
+ return avpkt->size;
+ } else {
+ av_log(avctx, AV_LOG_ERROR, "Frame contained no usable data\n");
+
+ return AVERROR_INVALIDDATA;
+ }
+}
+
+AVCodec ff_qdraw_decoder = {
+ .name = "qdraw",
+ .long_name = NULL_IF_CONFIG_SMALL("Apple QuickDraw"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_QDRAW,
+ .decode = decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/qpeg.c b/ffmpeg-2-8-12/libavcodec/qpeg.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qpeg.c
rename to ffmpeg-2-8-12/libavcodec/qpeg.c
diff --git a/ffmpeg-2-8-11/libavcodec/qpel_template.c b/ffmpeg-2-8-12/libavcodec/qpel_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qpel_template.c
rename to ffmpeg-2-8-12/libavcodec/qpel_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/qpeldsp.c b/ffmpeg-2-8-12/libavcodec/qpeldsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qpeldsp.c
rename to ffmpeg-2-8-12/libavcodec/qpeldsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/qpeldsp.h b/ffmpeg-2-8-12/libavcodec/qpeldsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qpeldsp.h
rename to ffmpeg-2-8-12/libavcodec/qpeldsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/qsv.c b/ffmpeg-2-8-12/libavcodec/qsv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qsv.c
rename to ffmpeg-2-8-12/libavcodec/qsv.c
diff --git a/ffmpeg-2-8-11/libavcodec/qsv.h b/ffmpeg-2-8-12/libavcodec/qsv.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qsv.h
rename to ffmpeg-2-8-12/libavcodec/qsv.h
diff --git a/ffmpeg-2-8-11/libavcodec/qsv_api.c b/ffmpeg-2-8-12/libavcodec/qsv_api.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qsv_api.c
rename to ffmpeg-2-8-12/libavcodec/qsv_api.c
diff --git a/ffmpeg-2-8-11/libavcodec/qsv_internal.h b/ffmpeg-2-8-12/libavcodec/qsv_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qsv_internal.h
rename to ffmpeg-2-8-12/libavcodec/qsv_internal.h
diff --git a/ffmpeg-2-8-11/libavcodec/qsvdec.c b/ffmpeg-2-8-12/libavcodec/qsvdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qsvdec.c
rename to ffmpeg-2-8-12/libavcodec/qsvdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/qsvdec.h b/ffmpeg-2-8-12/libavcodec/qsvdec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qsvdec.h
rename to ffmpeg-2-8-12/libavcodec/qsvdec.h
diff --git a/ffmpeg-2-8-11/libavcodec/qsvdec_h2645.c b/ffmpeg-2-8-12/libavcodec/qsvdec_h2645.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qsvdec_h2645.c
rename to ffmpeg-2-8-12/libavcodec/qsvdec_h2645.c
diff --git a/ffmpeg-2-8-11/libavcodec/qsvdec_mpeg2.c b/ffmpeg-2-8-12/libavcodec/qsvdec_mpeg2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qsvdec_mpeg2.c
rename to ffmpeg-2-8-12/libavcodec/qsvdec_mpeg2.c
diff --git a/ffmpeg-2-8-11/libavcodec/qsvdec_vc1.c b/ffmpeg-2-8-12/libavcodec/qsvdec_vc1.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qsvdec_vc1.c
rename to ffmpeg-2-8-12/libavcodec/qsvdec_vc1.c
diff --git a/ffmpeg-2-8-11/libavcodec/qsvenc.c b/ffmpeg-2-8-12/libavcodec/qsvenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qsvenc.c
rename to ffmpeg-2-8-12/libavcodec/qsvenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/qsvenc.h b/ffmpeg-2-8-12/libavcodec/qsvenc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qsvenc.h
rename to ffmpeg-2-8-12/libavcodec/qsvenc.h
diff --git a/ffmpeg-2-8-11/libavcodec/qsvenc_h264.c b/ffmpeg-2-8-12/libavcodec/qsvenc_h264.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qsvenc_h264.c
rename to ffmpeg-2-8-12/libavcodec/qsvenc_h264.c
diff --git a/ffmpeg-2-8-11/libavcodec/qsvenc_hevc.c b/ffmpeg-2-8-12/libavcodec/qsvenc_hevc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qsvenc_hevc.c
rename to ffmpeg-2-8-12/libavcodec/qsvenc_hevc.c
diff --git a/ffmpeg-2-8-11/libavcodec/qsvenc_mpeg2.c b/ffmpeg-2-8-12/libavcodec/qsvenc_mpeg2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qsvenc_mpeg2.c
rename to ffmpeg-2-8-12/libavcodec/qsvenc_mpeg2.c
diff --git a/ffmpeg-2-8-11/libavcodec/qtrle.c b/ffmpeg-2-8-12/libavcodec/qtrle.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qtrle.c
rename to ffmpeg-2-8-12/libavcodec/qtrle.c
diff --git a/ffmpeg-2-8-11/libavcodec/qtrleenc.c b/ffmpeg-2-8-12/libavcodec/qtrleenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/qtrleenc.c
rename to ffmpeg-2-8-12/libavcodec/qtrleenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/r210dec.c b/ffmpeg-2-8-12/libavcodec/r210dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/r210dec.c
rename to ffmpeg-2-8-12/libavcodec/r210dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/r210enc.c b/ffmpeg-2-8-12/libavcodec/r210enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/r210enc.c
rename to ffmpeg-2-8-12/libavcodec/r210enc.c
diff --git a/ffmpeg-2-8-12/libavcodec/ra144.c b/ffmpeg-2-8-12/libavcodec/ra144.c
new file mode 100644
index 0000000..da1af66
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/ra144.c
@@ -0,0 +1,1724 @@
+/*
+ * Real Audio 1.0 (14.4K)
+ * Copyright (c) 2003 The FFmpeg Project
+ *
+ * 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 <stdint.h>
+#include "avcodec.h"
+#include "celp_filters.h"
+#include "mathops.h"
+#include "ra144.h"
+
+const int16_t ff_gain_val_tab[256][3] = {
+ { 541, 956, 768}, { 877, 581, 568}, { 675,1574, 635}, {1248,1464, 668},
+ {1246, 839, 1394}, {2560,1386, 991}, { 925, 687, 608}, {2208, 797, 1144},
+ { 535, 832, 799}, { 762, 605, 1154}, { 832,1122, 1003}, {1180, 687, 1176},
+ {1292, 901, 732}, {1656, 689, 896}, {1750,1248, 848}, {2284, 942, 1022},
+ { 824,1472, 643}, { 517, 765, 512}, { 562,1816, 1522}, { 694,1826, 2700},
+ { 704, 524, 672}, {1442, 757, 2232}, { 884, 551, 1266}, {2232,1007, 1692},
+ { 932, 746, 777}, {1132, 822, 926}, {1226, 771, 611}, {2948,1342, 1008},
+ {1302, 594, 1158}, {1602, 636, 1128}, {3408, 910, 1438}, {1996, 614, 575},
+ { 665, 935, 628}, { 631,1192, 829}, { 644, 926, 1052}, { 879, 988, 1226},
+ { 941,2768, 2772}, { 565,1344, 2304}, { 547, 628, 740}, { 639, 532, 1074},
+ { 955,1208, 598}, {1124,1160, 900}, {1206, 899, 1242}, { 746, 533, 624},
+ {1458,1028, 735}, {1706,1102, 692}, {1898,1018, 1004}, {2176, 988, 735},
+ {1578, 782, 1642}, { 897, 516, 754}, {2068, 702, 1656}, {2344, 818, 1526},
+ { 907, 652, 592}, {1056, 652, 642}, {2124,1416, 780}, {2664,1250, 727},
+ {1894, 727, 1108}, {2196, 657, 981}, {4840, 920, 1704}, {4992,1238, 983},
+ {2420, 909, 1094}, {2760, 935, 1032}, {2800, 612, 853}, {3068, 832, 574},
+ { 523,1796, 923}, { 722,1916, 1382}, {1226,1542, 928}, { 758, 757, 584},
+ { 512,1134, 577}, { 615,1276, 698}, { 574,2568, 2356}, { 993,2728, 3512},
+ { 539, 890, 913}, { 694, 928, 1088}, { 805, 600, 1360}, {2160, 951, 3128},
+ { 816, 950, 590}, { 955, 847, 811}, {1094, 883, 556}, {1304, 888, 604},
+ { 863,1170, 855}, {1023, 997, 1032}, { 932,1228, 1280}, { 627, 564, 573},
+ { 876, 900, 1448}, {1030, 857, 1792}, {1294, 953, 1758}, {1612, 854, 1714},
+ {1090,1166, 631}, {1314,1202, 751}, {1480, 905, 795}, {1682,1016, 568},
+ {1494,1178, 983}, { 878, 613, 526}, {1728,1446, 779}, {2136,1348, 774},
+ { 950, 649, 939}, {1180, 703, 899}, {1236, 527, 1158}, {1450, 647, 972},
+ {1282, 647, 707}, {1460, 663, 644}, {1614, 572, 578}, {3516,1222, 821},
+ {2668, 729, 1682}, {3128, 585, 1502}, {3208, 733, 976}, {6800, 871, 1416},
+ {3480, 743, 1408}, {3764, 899, 1170}, {3772, 632, 875}, {4092, 732, 638},
+ {3112, 753, 2620}, {3372, 945, 1890}, {3768, 969, 2288}, {2016, 559, 854},
+ {1736, 729, 787}, {1940, 686, 547}, {2140, 635, 674}, {4480,1272, 828},
+ {3976, 592, 1666}, {4384, 621, 1388}, {4400, 801, 955}, {4656, 522, 646},
+ {4848, 625, 1636}, {4984, 591, 874}, {5352, 535, 1001}, {11216,938, 1184},
+ { 925,3280, 1476}, { 735,1580, 1088}, {1150,1576, 674}, { 655, 783, 528},
+ { 527,2052, 1354}, { 782,1704, 1880}, { 578, 910, 1026}, { 692, 882, 1468},
+ { 586, 683, 715}, { 739, 609, 717}, { 778, 773, 697}, { 922, 785, 813},
+ { 766, 651, 984}, { 978, 596, 1030}, {1070, 757, 1080}, {1324, 687, 1178},
+ {1108,2144, 979}, { 723, 982, 690}, { 936, 956, 527}, {1180,1002, 547},
+ { 517,1306, 825}, { 832,1184, 974}, {1024, 957, 903}, {1262,1090, 906},
+ {1028, 720, 649}, {1192, 679, 694}, {2468,1480, 979}, {2844,1370, 877},
+ {1310, 835, 848}, {1508, 839, 698}, {1742,1030, 769}, {1910, 852, 573},
+ {1280, 859, 1174}, {1584, 863, 1108}, {1686, 708, 1364}, {1942, 768, 1104},
+ { 891, 536, 690}, {1016, 560, 663}, {2172, 870, 1348}, {2404, 999, 1170},
+ {1890, 966, 889}, {2116, 912, 777}, {2296,1020, 714}, {4872,1844, 932},
+ {2392, 778, 929}, {2604, 772, 744}, {2764, 957, 722}, {5832,1532, 984},
+ {2188, 519, 1264}, {2332, 532, 922}, {5064, 995, 2412}, {2708, 571, 874},
+ {2408, 545, 666}, {5016,1084, 875}, {5376, 983, 1196}, {5536, 979, 730},
+ {5344, 634, 1744}, {5688, 706, 1348}, {5912, 977, 1190}, {6072, 905, 763},
+ {6048, 582, 1526}, {11968,1013,1816}, {12864,937, 1900}, {12560,1086, 998},
+ {1998, 684, 1884}, {2504, 633, 1992}, {1252, 567, 835}, {1478, 571, 973},
+ {2620, 769, 1414}, {2808, 952, 1142}, {2908, 712, 1028}, {2976, 686, 741},
+ {1462, 552, 714}, {3296, 991, 1452}, {1590, 615, 544}, {3480,1150, 824},
+ {3212, 832, 923}, {3276, 839, 531}, {3548, 786, 852}, {3732, 764, 570},
+ {5728, 906, 2616}, {6272, 804, 2252}, {3096, 535, 876}, {3228, 598, 649},
+ {6536, 759, 1436}, {6648, 993, 846}, {6864, 567, 1210},{14016,1012, 1302},
+ {3408, 548, 1098}, {7160,1008, 1742}, {7136,1000, 1182}, {7480,1032, 836},
+ {7448, 612, 1552}, {7744, 614, 816}, {8384, 777, 1438}, {8784, 694, 786},
+ { 882,1508, 1068}, { 597, 837, 766}, {1270, 954, 1408}, { 803, 550, 798},
+ {1398,1308, 798}, {1848,1534, 738}, { 970, 675, 608}, {1264, 706, 684},
+ {1716, 767, 1126}, {2108, 765, 1404}, {2236, 924, 1003}, {2472,1048, 611},
+ { 999, 942, 963}, {1094, 857, 935}, {2936, 926, 1138}, {1934, 746, 551},
+ {3336, 633, 1762}, {3764, 701, 1454}, {1890, 564, 636}, {4096,1126, 793},
+ {3936, 556, 1140}, {3936, 540, 740}, {4216, 764, 874}, {8480,1328, 1014},
+ {2184, 515, 1042}, {4432, 934, 1344}, {4784, 945, 1112}, {5016,1062, 733},
+ {9216,1020, 2028}, {9968, 924, 1188}, {5424, 909, 1206}, {6512, 744, 1086}
+};
+
+const uint8_t ff_gain_exp_tab[256] = {
+ 15, 15, 15, 15, 15, 16, 14, 15, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 13, 14, 14, 13, 14, 13, 14, 13, 13, 13, 14, 13, 13, 14, 13,
+ 13, 13, 13, 13, 14, 13, 12, 12, 13, 13, 13, 12, 13, 13, 13, 13,
+ 13, 12, 13, 13, 12, 12, 13, 13, 13, 13, 14, 14, 13, 13, 13, 13,
+ 13, 13, 13, 12, 12, 12, 13, 13, 12, 12, 12, 13, 12, 12, 12, 12,
+ 12, 12, 12, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 11, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 13, 13, 13, 13,
+ 13, 13, 13, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 14,
+ 13, 12, 12, 11, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 12, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 11, 11, 11, 11,
+ 12, 12, 12, 12, 11, 11, 12, 12, 12, 12, 12, 13, 12, 12, 12, 13,
+ 12, 12, 13, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14,
+ 12, 12, 11, 11, 12, 12, 12, 12, 11, 12, 11, 12, 12, 12, 12, 12,
+ 13, 13, 12, 12, 13, 13, 13, 14, 12, 13, 13, 13, 13, 13, 13, 13,
+ 11, 10, 11, 10, 11, 11, 10, 10, 11, 11, 11, 11, 10, 9, 11, 10,
+ 12, 12, 11, 12, 12, 12, 12, 13, 11, 12, 12, 12, 13, 13, 12, 12
+};
+
+const int8_t ff_cb1_vects[128][40]={
+ {
+ 38, -4, 15, -4, 14, -13, 12, -11, -2, -6,
+ -6, -11, -45, -16, -11, -13, -7, 6, -12, 4,
+ -20, 3, -16, 12, -1, 12, 46, 24, 0, 33,
+ -3, 9, -12, -12, -8, -7, 17, -6, 0, -2,
+ }, {
+ 60, -16, 3, -22, 10, -32, 0, -28, -17, -18,
+ -3, -25, -37, -23, -10, 3, 2, 3, 0, 3,
+ -14, 0, -14, -1, 0, 2, 32, 9, -1, 25,
+ 7, 13, -5, 13, 8, 1, 2, 8, -10, 6,
+ }, {
+ 27, -12, 28, -2, 6, -7, 15, 9, -11, 1,
+ -13, -11, -40, 4, -29, -14, -19, -5, -23, -8,
+ -30, -13, -17, 0, -14, 12, 34, 20, -2, 25,
+ 2, -16, -4, -12, 15, 16, 29, 7, 24, 10,
+ }, {
+ 49, -24, 16, -20, 2, -26, 2, -7, -25, -10,
+ -11, -25, -32, -3, -27, 2, -8, -8, -11, -9,
+ -24, -17, -16, -14, -13, 2, 20, 5, -4, 17,
+ 14, -12, 3, 13, 33, 25, 14, 23, 15, 19,
+ }, {
+ 46, -6, 21, 8, -2, -16, -5, -8, -11, 4,
+ 8, 15, -24, 4, -2, -26, -3, -16, -16, -14,
+ -9, -2, -1, 4, 19, 7, 36, 17, 9, 13,
+ 0, 31, -5, -12, 7, -8, 11, -15, -13, -4,
+ }, {
+ 68, -18, 9, -9, -6, -35, -18, -25, -26, -7,
+ 10, 1, -16, -3, -1, -9, 6, -19, -4, -15,
+ -4, -6, 0, -8, 20, -2, 23, 2, 7, 5,
+ 12, 35, 1, 13, 24, 0, -3, 0, -22, 4,
+ }, {
+ 35, -14, 34, 10, -10, -10, -1, 12, -20, 12,
+ 0, 15, -18, 24, -20, -27, -14, -28, -27, -27,
+ -20, -19, -2, -8, 5, 7, 25, 13, 5, 5,
+ 6, 5, 2, -12, 31, 15, 23, -1, 12, 8,
+ }, {
+ 57, -26, 22, -7, -14, -28, -14, -3, -35, 0,
+ 3, 1, -11, 16, -18, -10, -4, -31, -15, -28,
+ -14, -23, -1, -21, 7, -2, 11, -1, 3, -1,
+ 18, 9, 10, 13, 49, 24, 8, 14, 2, 16,
+ }, {
+ 25, 15, 22, 11, 18, 4, 15, -22, 8, -2,
+ -17, -9, -48, -20, -30, -17, -16, 11, -1, 16,
+ 2, 10, -5, 26, -2, -4, 22, 0, 2, 10,
+ -6, 13, -14, 10, -23, 0, 10, -2, 1, 0,
+ }, {
+ 47, 3, 11, -6, 15, -13, 2, -38, -6, -13,
+ -15, -22, -40, -28, -28, 0, -5, 8, 10, 15,
+ 7, 7, -4, 13, -1, -14, 9, -14, 0, 2,
+ 4, 18, -7, 36, -6, 8, -3, 13, -7, 8,
+ }, {
+ 14, 7, 36, 13, 10, 10, 18, 0, 0, 5,
+ -25, -8, -43, 0, -48, -18, -27, 0, -12, 3,
+ -7, -6, -7, 13, -15, -5, 11, -3, 0, 2,
+ 0, -12, -6, 10, 0, 23, 22, 11, 26, 12,
+ }, {
+ 36, -5, 24, -4, 7, -7, 6, -17, -14, -5,
+ -22, -22, -35, -8, -46, -1, -17, -3, 0, 2,
+ -2, -10, -5, 0, -14, -15, -2, -18, -2, -4,
+ 11, -7, 1, 36, 18, 32, 7, 27, 17, 20,
+ }, {
+ 33, 13, 29, 24, 1, 1, -2, -18, 0, 9,
+ -3, 17, -27, 0, -21, -30, -12, -11, -5, -2,
+ 12, 4, 9, 19, 18, -9, 13, -6, 11, -8,
+ -2, 35, -8, 10, -7, -1, 4, -11, -10, -2,
+ }, {
+ 55, 1, 17, 6, -1, -16, -15, -35, -15, -2,
+ 0, 4, -19, -8, -20, -13, -1, -14, 7, -3,
+ 18, 0, 10, 5, 19, -19, 0, -21, 8, -16,
+ 9, 39, 0, 36, 10, 7, -9, 4, -20, 5,
+ }, {
+ 22, 5, 42, 26, -6, 8, 1, 2, -9, 17,
+ -10, 18, -21, 19, -39, -31, -23, -23, -16, -15,
+ 2, -12, 7, 6, 5, -9, 1, -10, 7, -16,
+ 4, 9, 0, 10, 17, 22, 16, 2, 14, 9,
+ }, {
+ 44, -6, 30, 8, -9, -10, -11, -14, -23, 5,
+ -8, 4, -14, 12, -37, -14, -12, -26, -4, -16,
+ 8, -16, 9, -7, 6, -19, -12, -25, 5, -24,
+ 15, 13, 8, 36, 34, 31, 1, 18, 4, 18,
+ }, {
+ -3, -5, -9, -7, 15, -1, 5, 13, 2, 12,
+ 5, 2, -21, -23, -2, -16, 0, 5, -6, 13,
+ -23, 3, -32, 10, -15, 8, 44, 28, 9, 37,
+ -2, 13, -9, -15, -12, -27, -7, -12, 0, -11,
+ }, {
+ 18, -17, -21, -25, 11, -19, -6, -3, -11, 0,
+ 7, -11, -13, -31, -1, 0, 9, 1, 5, 12,
+ -18, 0, -31, -2, -13, -1, 30, 14, 7, 29,
+ 9, 18, -1, 10, 4, -18, -22, 3, -10, -2,
+ }, {
+ -13, -13, 3, -5, 7, 4, 9, 34, -5, 20,
+ -2, 3, -16, -3, -20, -17, -11, -7, -17, 0,
+ -34, -13, -33, -2, -28, 8, 32, 24, 5, 29,
+ 3, -12, 0, -15, 11, -3, 3, 2, 24, 1,
+ }, {
+ 8, -25, -8, -23, 3, -13, -3, 17, -20, 8,
+ 0, -10, -8, -11, -18, 0, -1, -10, -5, 0,
+ -28, -17, -32, -15, -26, -1, 19, 9, 3, 21,
+ 15, -7, 6, 9, 29, 5, -10, 17, 15, 9,
+ }, {
+ 4, -6, -3, 5, -1, -4, -11, 16, -6, 23,
+ 19, 29, 0, -3, 6, -30, 3, -17, -10, -5,
+ -13, -2, -17, 3, 5, 3, 35, 21, 17, 17,
+ 2, 35, -2, -15, 3, -28, -13, -21, -13, -13,
+ }, {
+ 26, -19, -15, -12, -5, -22, -24, 0, -21, 12,
+ 21, 15, 8, -11, 7, -12, 14, -20, 2, -6,
+ -7, -6, -16, -9, 6, -5, 21, 7, 15, 10,
+ 13, 39, 5, 10, 20, -19, -28, -5, -22, -5,
+ }, {
+ -5, -15, 9, 7, -9, 2, -8, 37, -14, 31,
+ 11, 29, 5, 16, -11, -30, -7, -29, -21, -18,
+ -23, -19, -18, -9, -7, 3, 23, 17, 14, 9,
+ 8, 9, 6, -15, 27, -4, -2, -6, 12, -1,
+ }, {
+ 16, -27, -2, -10, -13, -16, -20, 20, -29, 20,
+ 14, 16, 13, 8, -9, -13, 2, -33, -9, -19,
+ -17, -23, -17, -22, -6, -6, 9, 2, 12, 2,
+ 20, 13, 13, 10, 45, 4, -16, 8, 2, 7,
+ }, {
+ -16, 14, -2, 8, 20, 17, 9, 2, 14, 16,
+ -6, 5, -24, -28, -21, -20, -8, 9, 4, 25,
+ -1, 11, -22, 24, -15, -8, 21, 5, 11, 14,
+ -5, 18, -11, 7, -27, -20, -14, -7, 1, -9,
+ }, {
+ 6, 2, -14, -9, 16, -1, -3, -14, 0, 5,
+ -3, -8, -16, -36, -19, -3, 1, 6, 17, 24,
+ 4, 7, -21, 11, -14, -18, 7, -9, 9, 7,
+ 6, 22, -3, 33, -10, -11, -28, 7, -7, 0,
+ }, {
+ -26, 6, 11, 10, 12, 23, 12, 23, 5, 24,
+ -13, 5, -19, -8, -38, -21, -20, -2, -6, 12,
+ -11, -5, -23, 11, -29, -9, 9, 0, 7, 6,
+ 1, -7, -2, 7, -3, 3, -2, 6, 27, 3,
+ }, {
+ -4, -6, 0, -7, 8, 4, 0, 6, -9, 13,
+ -11, -7, -11, -15, -37, -4, -9, -5, 5, 11,
+ -5, -9, -22, -1, -27, -18, -4, -14, 5, 0,
+ 12, -3, 4, 32, 14, 12, -17, 22, 17, 11,
+ }, {
+ -8, 12, 3, 21, 3, 14, -8, 5, 4, 28,
+ 7, 32, -2, -8, -12, -34, -4, -12, 1, 6,
+ 9, 4, -7, 17, 4, -13, 11, -1, 19, -4,
+ 0, 39, -4, 7, -11, -21, -20, -16, -10, -11,
+ }, {
+ 13, 0, -8, 3, 0, -4, -21, -11, -9, 16,
+ 10, 18, 5, -16, -10, -16, 5, -15, 13, 5,
+ 15, 1, -6, 4, 6, -23, -2, -16, 17, -12,
+ 10, 44, 3, 33, 6, -12, -34, -1, -20, -3,
+ }, {
+ -18, 4, 17, 23, -4, 20, -4, 26, -3, 36,
+ 0, 32, 2, 12, -29, -34, -16, -24, -10, -6,
+ 0, -12, -8, 4, -8, -13, 0, -6, 16, -12,
+ 5, 13, 3, 7, 13, 3, -8, -2, 14, 0,
+ }, {
+ 3, -7, 5, 5, -8, 2, -17, 9, -18, 24,
+ 2, 19, 10, 4, -28, -17, -5, -28, 2, -7,
+ 4, -15, -7, -8, -6, -23, -13, -21, 14, -20,
+ 17, 18, 11, 33, 30, 11, -23, 13, 5, 9,
+ }, {
+ 60, 10, 7, -1, 9, -8, 6, -13, 2, -15,
+ -1, -10, -13, -11, 15, 0, 6, 9, -1, 0,
+ -13, 1, -11, -3, -13, 21, 13, 26, -7, 31,
+ -10, -7, -16, -33, -31, -10, 22, -8, 1, -2,
+ }, {
+ 82, -1, -4, -19, 6, -27, -6, -29, -12, -26,
+ 1, -24, -5, -18, 17, 17, 17, 6, 10, 0,
+ -7, -2, -9, -16, -12, 11, 0, 11, -9, 23,
+ 0, -3, -8, -8, -13, -1, 8, 7, -7, 6,
+ }, {
+ 49, 2, 21, 0, 1, -2, 9, 8, -6, -6,
+ -8, -10, -8, 9, -2, 0, -4, -2, -13, -12,
+ -23, -15, -12, -16, -26, 21, 2, 21, -11, 23,
+ -4, -33, -7, -33, -6, 13, 34, 5, 27, 10,
+ }, {
+ 71, -10, 9, -17, -1, -20, -3, -8, -21, -18,
+ -6, -24, 0, 1, 0, 16, 6, -5, 0, -13,
+ -17, -19, -11, -29, -25, 11, -11, 6, -13, 15,
+ 7, -29, 0, -8, 11, 22, 20, 21, 17, 18,
+ }, {
+ 67, 8, 14, 11, -7, -11, -11, -9, -7, -3,
+ 13, 16, 8, 9, 24, -12, 10, -13, -5, -17,
+ -2, -4, 3, -10, 6, 17, 4, 19, 0, 11,
+ -6, 13, -9, -33, -14, -10, 16, -17, -10, -4,
+ }, {
+ 90, -3, 2, -6, -10, -29, -24, -26, -21, -15,
+ 15, 2, 16, 1, 25, 4, 21, -16, 6, -18,
+ 3, -8, 5, -24, 8, 7, -9, 4, -1, 3,
+ 5, 18, -1, -7, 2, -1, 2, -1, -19, 3,
+ }, {
+ 57, 0, 27, 13, -14, -5, -7, 11, -15, 4,
+ 5, 16, 13, 29, 6, -13, 0, -25, -16, -31,
+ -12, -22, 2, -23, -6, 16, -7, 14, -2, 3,
+ 0, -12, 0, -33, 9, 13, 28, -3, 14, 7,
+ }, {
+ 79, -11, 15, -4, -18, -23, -20, -5, -30, -7,
+ 7, 2, 21, 21, 8, 3, 10, -28, -4, -31,
+ -6, -25, 3, -37, -4, 7, -20, 0, -4, -4,
+ 11, -7, 6, -8, 27, 22, 14, 12, 5, 16,
+ }, {
+ 47, 30, 15, 14, 14, 9, 9, -23, 13, -10,
+ -12, -7, -16, -15, -3, -3, -1, 14, 9, 12,
+ 9, 8, 0, 10, -14, 4, -9, 2, -5, 8,
+ -13, -3, -18, -10, -45, -3, 16, -4, 4, 0,
+ }, {
+ 69, 17, 3, -3, 10, -8, -3, -40, -1, -21,
+ -10, -21, -8, -23, -1, 13, 8, 11, 21, 11,
+ 15, 4, 0, -2, -13, -5, -23, -12, -7, 0,
+ -1, 0, -10, 14, -28, 5, 1, 11, -5, 7,
+ }, {
+ 36, 21, 28, 16, 6, 16, 12, -2, 4, -2,
+ -20, -7, -11, 4, -20, -4, -12, 2, -1, 0,
+ 0, -8, -2, -2, -27, 4, -21, -2, -9, 0,
+ -6, -29, -9, -10, -21, 21, 28, 10, 29, 11,
+ }, {
+ 58, 9, 16, -1, 2, -2, 0, -19, -10, -13,
+ -17, -21, -3, -3, -19, 12, -2, 0, 10, -1,
+ 5, -12, 0, -15, -26, -5, -34, -16, -11, -7,
+ 4, -25, -2, 14, -3, 29, 13, 25, 20, 20,
+ }, {
+ 55, 28, 21, 27, -2, 7, -8, -20, 4, 1,
+ 1, 18, 5, 4, 5, -16, 2, -8, 5, -5,
+ 19, 2, 14, 3, 6, 0, -18, -4, 2, -11,
+ -8, 18, -11, -10, -29, -3, 10, -13, -8, -3,
+ }, {
+ 77, 16, 9, 9, -6, -11, -21, -37, -10, -10,
+ 4, 5, 13, -3, 7, 0, 13, -11, 17, -6,
+ 25, -1, 15, -9, 7, -9, -32, -19, 0, -18,
+ 2, 22, -3, 15, -12, 5, -4, 2, -17, 5,
+ }, {
+ 44, 20, 34, 29, -10, 13, -4, 0, -4, 9,
+ -5, 19, 10, 24, -11, -17, -8, -20, -5, -19,
+ 9, -14, 12, -9, -6, 0, -30, -9, 0, -19,
+ -2, -7, -2, -10, -5, 20, 21, 1, 17, 9,
+ }, {
+ 66, 8, 23, 11, -14, -5, -17, -16, -19, -2,
+ -3, 5, 18, 17, -10, 0, 1, -23, 6, -20,
+ 15, -18, 14, -22, -5, -10, -44, -23, -2, -26,
+ 9, -3, 4, 14, 12, 29, 7, 16, 7, 18,
+ }, {
+ 18, 9, -17, -4, 11, 3, 0, 11, 7, 4,
+ 10, 3, 10, -18, 24, -3, 14, 7, 4, 10,
+ -16, 1, -27, -4, -27, 17, 12, 30, 0, 35,
+ -9, -3, -12, -36, -35, -30, -2, -13, 2, -11,
+ }, {
+ 40, -2, -29, -22, 7, -14, -12, -5, -7, -7,
+ 12, -9, 18, -26, 26, 14, 24, 4, 16, 9,
+ -10, -2, -26, -18, -26, 7, -1, 15, -1, 27,
+ 2, 0, -4, -11, -17, -21, -16, 1, -7, -3,
+ }, {
+ 8, 1, -3, -2, 3, 10, 3, 32, -1, 12,
+ 2, 4, 15, 1, 7, -3, 2, -4, -6, -3,
+ -26, -15, -29, -17, -40, 17, 0, 26, -2, 27,
+ -2, -29, -4, -36, -10, -6, 9, 0, 27, 0,
+ }, {
+ 30, -11, -15, -20, 0, -8, -9, 15, -15, 0,
+ 5, -9, 23, -6, 8, 13, 13, -7, 5, -3,
+ -20, -19, -27, -31, -39, 7, -13, 11, -4, 19,
+ 8, -25, 3, -11, 7, 2, -4, 16, 18, 9,
+ }, {
+ 26, 7, -11, 8, -5, 1, -17, 14, -1, 15,
+ 24, 30, 32, 1, 33, -16, 18, -14, 0, -8,
+ -6, -4, -12, -12, -6, 13, 2, 23, 8, 15,
+ -4, 17, -5, -36, -18, -30, -8, -22, -10, -14,
+ }, {
+ 48, -4, -23, -9, -9, -17, -30, -2, -16, 3,
+ 26, 16, 40, -6, 35, 1, 28, -17, 12, -9,
+ 0, -8, -11, -25, -5, 3, -10, 8, 6, 7,
+ 6, 22, 1, -11, -1, -21, -22, -7, -19, -5,
+ }, {
+ 15, 0, 2, 10, -13, 7, -14, 35, -10, 23,
+ 16, 31, 37, 21, 16, -17, 6, -26, -10, -21,
+ -16, -21, -13, -25, -19, 13, -8, 19, 5, 7,
+ 1, -8, 2, -36, 5, -6, 3, -8, 15, -1,
+ }, {
+ 37, -12, -9, -7, -17, -11, -26, 18, -25, 12,
+ 19, 17, 45, 14, 17, 0, 17, -30, 1, -22,
+ -10, -25, -12, -38, -18, 3, -22, 4, 3, 0,
+ 13, -3, 10, -11, 23, 2, -10, 7, 5, 7,
+ }, {
+ 5, 29, -9, 11, 15, 22, 3, 0, 18, 8,
+ -1, 6, 7, -23, 6, -6, 5, 12, 15, 21,
+ 5, 8, -17, 9, -28, 0, -11, 6, 2, 12,
+ -11, 0, -14, -13, -49, -22, -8, -9, 4, -9,
+ }, {
+ 27, 16, -21, -6, 12, 3, -9, -16, 3, -2,
+ 1, -7, 15, -31, 7, 10, 16, 9, 27, 21,
+ 11, 5, -16, -3, -26, -9, -24, -7, 0, 4,
+ 0, 4, -6, 11, -32, -14, -23, 6, -5, -1,
+ }, {
+ -4, 20, 3, 13, 8, 28, 6, 21, 10, 16,
+ -8, 7, 12, -3, -11, -7, -5, 0, 4, 8,
+ -4, -8, -18, -3, -41, 0, -22, 2, 0, 4,
+ -5, -25, -6, -14, -25, 1, 2, 4, 29, 2,
+ }, {
+ 17, 8, -8, -4, 4, 10, -6, 5, -4, 5,
+ -6, -6, 20, -10, -9, 9, 4, -2, 16, 7,
+ 1, -12, -17, -16, -39, -9, -36, -12, -2, -3,
+ 6, -21, 1, 11, -7, 10, -11, 20, 20, 11,
+ }, {
+ 13, 27, -3, 24, -1, 19, -14, 3, 9, 20,
+ 12, 33, 29, -3, 15, -20, 9, -9, 11, 3,
+ 16, 2, -2, 2, -7, -3, -20, 0, 10, -7,
+ -7, 22, -7, -13, -33, -23, -14, -18, -7, -12,
+ }, {
+ 35, 15, -15, 6, -4, 1, -27, -12, -5, 8,
+ 15, 19, 37, -11, 16, -2, 20, -12, 23, 2,
+ 22, -1, -1, -11, -5, -13, -34, -14, 8, -14,
+ 4, 26, 0, 11, -16, -14, -29, -2, -17, -3,
+ }, {
+ 3, 19, 9, 26, -8, 26, -10, 24, 0, 28,
+ 5, 33, 34, 17, -2, -20, -1, -22, 0, -10,
+ 6, -14, -3, -10, -20, -4, -32, -4, 7, -15,
+ 0, -3, 0, -13, -9, 0, -3, -4, 17, 0,
+ }, {
+ 25, 7, -2, 8, -12, 7, -23, 8, -13, 16,
+ 7, 20, 42, 9, 0, -3, 9, -25, 12, -10,
+ 12, -18, -2, -24, -19, -13, -46, -19, 5, -22,
+ 10, 0, 8, 11, 8, 9, -17, 11, 7, 8,
+ }, {
+ -25, -7, 2, -8, 12, -7, 23, -8, 13, -16,
+ -7, -20, -42, -9, 0, 3, -9, 25, -12, 10,
+ -12, 18, 2, 24, 19, 13, 46, 19, -5, 22,
+ -10, 0, -8, -11, -8, -9, 17, -11, -7, -8,
+ }, {
+ -3, -19, -9, -26, 8, -26, 10, -24, 0, -28,
+ -5, -33, -34, -17, 2, 20, 1, 22, 0, 10,
+ -6, 14, 3, 10, 20, 4, 32, 4, -7, 15,
+ 0, 3, 0, 13, 9, 0, 3, 4, -17, 0,
+ }, {
+ -35, -15, 15, -6, 4, -1, 27, 12, 5, -8,
+ -15, -19, -37, 11, -16, 2, -20, 12, -23, -2,
+ -22, 1, 1, 11, 5, 13, 34, 14, -8, 14,
+ -4, -26, 0, -11, 16, 14, 29, 2, 17, 3,
+ }, {
+ -13, -27, 3, -24, 1, -19, 14, -3, -9, -20,
+ -12, -33, -29, 3, -15, 20, -9, 9, -11, -3,
+ -16, -2, 2, -2, 7, 3, 20, 0, -10, 7,
+ 7, -22, 7, 13, 33, 23, 14, 18, 7, 12,
+ }, {
+ -17, -8, 8, 4, -4, -10, 6, -5, 4, -5,
+ 6, 6, -20, 10, 9, -9, -4, 2, -16, -7,
+ -1, 12, 17, 16, 39, 9, 36, 12, 2, 3,
+ -6, 21, -1, -11, 7, -10, 11, -20, -20, -11,
+ }, {
+ 4, -20, -3, -13, -8, -28, -6, -21, -10, -16,
+ 8, -7, -12, 3, 11, 7, 5, 0, -4, -8,
+ 4, 8, 18, 3, 41, 0, 22, -2, 0, -4,
+ 5, 25, 6, 14, 25, -1, -2, -4, -29, -2,
+ }, {
+ -27, -16, 21, 6, -12, -3, 9, 16, -3, 2,
+ -1, 7, -15, 31, -7, -10, -16, -9, -27, -21,
+ -11, -5, 16, 3, 26, 9, 24, 7, 0, -4,
+ 0, -4, 6, -11, 32, 14, 23, -6, 5, 1,
+ }, {
+ -5, -29, 9, -11, -15, -22, -3, 0, -18, -8,
+ 1, -6, -7, 23, -6, 6, -5, -12, -15, -21,
+ -5, -8, 17, -9, 28, 0, 11, -6, -2, -12,
+ 11, 0, 14, 13, 49, 22, 8, 9, -4, 9,
+ }, {
+ -37, 12, 9, 7, 17, 11, 26, -18, 25, -12,
+ -19, -17, -45, -14, -17, 0, -17, 30, -1, 22,
+ 10, 25, 12, 38, 18, -3, 22, -4, -3, 0,
+ -13, 3, -10, 11, -23, -2, 10, -7, -5, -7,
+ }, {
+ -15, 0, -2, -10, 13, -7, 14, -35, 10, -23,
+ -16, -31, -37, -21, -16, 17, -6, 26, 10, 21,
+ 16, 21, 13, 25, 19, -13, 8, -19, -5, -7,
+ -1, 8, -2, 36, -5, 6, -3, 8, -15, 1,
+ }, {
+ -48, 4, 23, 9, 9, 17, 30, 2, 16, -3,
+ -26, -16, -40, 6, -35, -1, -28, 17, -12, 9,
+ 0, 8, 11, 25, 5, -3, 10, -8, -6, -7,
+ -6, -22, -1, 11, 1, 21, 22, 7, 19, 5,
+ }, {
+ -26, -7, 11, -8, 5, -1, 17, -14, 1, -15,
+ -24, -30, -32, -1, -33, 16, -18, 14, 0, 8,
+ 6, 4, 12, 12, 6, -13, -2, -23, -8, -15,
+ 4, -17, 5, 36, 18, 30, 8, 22, 10, 14,
+ }, {
+ -30, 11, 15, 20, 0, 8, 9, -15, 15, 0,
+ -5, 9, -23, 6, -8, -13, -13, 7, -5, 3,
+ 20, 19, 27, 31, 39, -7, 13, -11, 4, -19,
+ -8, 25, -3, 11, -7, -2, 4, -16, -18, -9,
+ }, {
+ -8, -1, 3, 2, -3, -10, -3, -32, 1, -12,
+ -2, -4, -15, -1, -7, 3, -2, 4, 6, 3,
+ 26, 15, 29, 17, 40, -17, 0, -26, 2, -27,
+ 2, 29, 4, 36, 10, 6, -9, 0, -27, 0,
+ }, {
+ -40, 2, 29, 22, -7, 14, 12, 5, 7, 7,
+ -12, 9, -18, 26, -26, -14, -24, -4, -16, -9,
+ 10, 2, 26, 18, 26, -7, 1, -15, 1, -27,
+ -2, 0, 4, 11, 17, 21, 16, -1, 7, 3,
+ }, {
+ -18, -9, 17, 4, -11, -3, 0, -11, -7, -4,
+ -10, -3, -10, 18, -24, 3, -14, -7, -4, -10,
+ 16, -1, 27, 4, 27, -17, -12, -30, 0, -35,
+ 9, 3, 12, 36, 35, 30, 2, 13, -2, 11,
+ }, {
+ -66, -8, -23, -11, 14, 5, 17, 16, 19, 2,
+ 3, -5, -18, -17, 10, 0, -1, 23, -6, 20,
+ -15, 18, -14, 22, 5, 10, 44, 23, 2, 26,
+ -9, 3, -4, -14, -12, -29, -7, -16, -7, -18,
+ }, {
+ -44, -20, -34, -29, 10, -13, 4, 0, 4, -9,
+ 5, -19, -10, -24, 11, 17, 8, 20, 5, 19,
+ -9, 14, -12, 9, 6, 0, 30, 9, 0, 19,
+ 2, 7, 2, 10, 5, -20, -21, -1, -17, -9,
+ }, {
+ -77, -16, -9, -9, 6, 11, 21, 37, 10, 10,
+ -4, -5, -13, 3, -7, 0, -13, 11, -17, 6,
+ -25, 1, -15, 9, -7, 9, 32, 19, 0, 18,
+ -2, -22, 3, -15, 12, -5, 4, -2, 17, -5,
+ }, {
+ -55, -28, -21, -27, 2, -7, 8, 20, -4, -1,
+ -1, -18, -5, -4, -5, 16, -2, 8, -5, 5,
+ -19, -2, -14, -3, -6, 0, 18, 4, -2, 11,
+ 8, -18, 11, 10, 29, 3, -10, 13, 8, 3,
+ }, {
+ -58, -9, -16, 1, -2, 2, 0, 19, 10, 13,
+ 17, 21, 3, 3, 19, -12, 2, 0, -10, 1,
+ -5, 12, 0, 15, 26, 5, 34, 16, 11, 7,
+ -4, 25, 2, -14, 3, -29, -13, -25, -20, -20,
+ }, {
+ -36, -21, -28, -16, -6, -16, -12, 2, -4, 2,
+ 20, 7, 11, -4, 20, 4, 12, -2, 1, 0,
+ 0, 8, 2, 2, 27, -4, 21, 2, 9, 0,
+ 6, 29, 9, 10, 21, -21, -28, -10, -29, -11,
+ }, {
+ -69, -17, -3, 3, -10, 8, 3, 40, 1, 21,
+ 10, 21, 8, 23, 1, -13, -8, -11, -21, -11,
+ -15, -4, 0, 2, 13, 5, 23, 12, 7, 0,
+ 1, 0, 10, -14, 28, -5, -1, -11, 5, -7,
+ }, {
+ -47, -30, -15, -14, -14, -9, -9, 23, -13, 10,
+ 12, 7, 16, 15, 3, 3, 1, -14, -9, -12,
+ -9, -8, 0, -10, 14, -4, 9, -2, 5, -8,
+ 13, 3, 18, 10, 45, 3, -16, 4, -4, 0,
+ }, {
+ -79, 11, -15, 4, 18, 23, 20, 5, 30, 7,
+ -7, -2, -21, -21, -8, -3, -10, 28, 4, 31,
+ 6, 25, -3, 37, 4, -7, 20, 0, 4, 4,
+ -11, 7, -6, 8, -27, -22, -14, -12, -5, -16,
+ }, {
+ -57, 0, -27, -13, 14, 5, 7, -11, 15, -4,
+ -5, -16, -13, -29, -6, 13, 0, 25, 16, 31,
+ 12, 22, -2, 23, 6, -16, 7, -14, 2, -3,
+ 0, 12, 0, 33, -9, -13, -28, 3, -14, -7,
+ }, {
+ -90, 3, -2, 6, 10, 29, 24, 26, 21, 15,
+ -15, -2, -16, -1, -25, -4, -21, 16, -6, 18,
+ -3, 8, -5, 24, -8, -7, 9, -4, 1, -3,
+ -5, -18, 1, 7, -2, 1, -2, 1, 19, -3,
+ }, {
+ -67, -8, -14, -11, 7, 11, 11, 9, 7, 3,
+ -13, -16, -8, -9, -24, 12, -10, 13, 5, 17,
+ 2, 4, -3, 10, -6, -17, -4, -19, 0, -11,
+ 6, -13, 9, 33, 14, 10, -16, 17, 10, 4,
+ }, {
+ -71, 10, -9, 17, 1, 20, 3, 8, 21, 18,
+ 6, 24, 0, -1, 0, -16, -6, 5, 0, 13,
+ 17, 19, 11, 29, 25, -11, 11, -6, 13, -15,
+ -7, 29, 0, 8, -11, -22, -20, -21, -17, -18,
+ }, {
+ -49, -2, -21, 0, -1, 2, -9, -8, 6, 6,
+ 8, 10, 8, -9, 2, 0, 4, 2, 13, 12,
+ 23, 15, 12, 16, 26, -21, -2, -21, 11, -23,
+ 4, 33, 7, 33, 6, -13, -34, -5, -27, -10,
+ }, {
+ -82, 1, 4, 19, -6, 27, 6, 29, 12, 26,
+ -1, 24, 5, 18, -17, -17, -17, -6, -10, 0,
+ 7, 2, 9, 16, 12, -11, 0, -11, 9, -23,
+ 0, 3, 8, 8, 13, 1, -8, -7, 7, -6,
+ }, {
+ -60, -10, -7, 1, -9, 8, -6, 13, -2, 15,
+ 1, 10, 13, 11, -15, 0, -6, -9, 1, 0,
+ 13, -1, 11, 3, 13, -21, -13, -26, 7, -31,
+ 10, 7, 16, 33, 31, 10, -22, 8, -1, 2,
+ }, {
+ -3, 7, -5, -5, 8, -2, 17, -9, 18, -24,
+ -2, -19, -10, -4, 28, 17, 5, 28, -2, 7,
+ -4, 15, 7, 8, 6, 23, 13, 21, -14, 20,
+ -17, -18, -11, -33, -30, -11, 23, -13, -5, -9,
+ }, {
+ 18, -4, -17, -23, 4, -20, 4, -26, 3, -36,
+ 0, -32, -2, -12, 29, 34, 16, 24, 10, 6,
+ 0, 12, 8, -4, 8, 13, 0, 6, -16, 12,
+ -5, -13, -3, -7, -13, -3, 8, 2, -14, 0,
+ }, {
+ -13, 0, 8, -3, 0, 4, 21, 11, 9, -16,
+ -10, -18, -5, 16, 10, 16, -5, 15, -13, -5,
+ -15, -1, 6, -4, -6, 23, 2, 16, -17, 12,
+ -10, -44, -3, -33, -6, 12, 34, 1, 20, 3,
+ }, {
+ 8, -12, -3, -21, -3, -14, 8, -5, -4, -28,
+ -7, -32, 2, 8, 12, 34, 4, 12, -1, -6,
+ -9, -4, 7, -17, -4, 13, -11, 1, -19, 4,
+ 0, -39, 4, -7, 11, 21, 20, 16, 10, 11,
+ }, {
+ 4, 6, 0, 7, -8, -4, 0, -6, 9, -13,
+ 11, 7, 11, 15, 37, 4, 9, 5, -5, -11,
+ 5, 9, 22, 1, 27, 18, 4, 14, -5, 0,
+ -12, 3, -4, -32, -14, -12, 17, -22, -17, -11,
+ }, {
+ 26, -6, -11, -10, -12, -23, -12, -23, -5, -24,
+ 13, -5, 19, 8, 38, 21, 20, 2, 6, -12,
+ 11, 5, 23, -11, 29, 9, -9, 0, -7, -6,
+ -1, 7, 2, -7, 3, -3, 2, -6, -27, -3,
+ }, {
+ -6, -2, 14, 9, -16, 1, 3, 14, 0, -5,
+ 3, 8, 16, 36, 19, 3, -1, -6, -17, -24,
+ -4, -7, 21, -11, 14, 18, -7, 9, -9, -7,
+ -6, -22, 3, -33, 10, 11, 28, -7, 7, 0,
+ }, {
+ 16, -14, 2, -8, -20, -17, -9, -2, -14, -16,
+ 6, -5, 24, 28, 21, 20, 8, -9, -4, -25,
+ 1, -11, 22, -24, 15, 8, -21, -5, -11, -14,
+ 5, -18, 11, -7, 27, 20, 14, 7, -1, 9,
+ }, {
+ -16, 27, 2, 10, 13, 16, 20, -20, 29, -20,
+ -14, -16, -13, -8, 9, 13, -2, 33, 9, 19,
+ 17, 23, 17, 22, 6, 6, -9, -2, -12, -2,
+ -20, -13, -13, -10, -45, -4, 16, -8, -2, -7,
+ }, {
+ 5, 15, -9, -7, 9, -2, 8, -37, 14, -31,
+ -11, -29, -5, -16, 11, 30, 7, 29, 21, 18,
+ 23, 19, 18, 9, 7, -3, -23, -17, -14, -9,
+ -8, -9, -6, 15, -27, 4, 2, 6, -12, 1,
+ }, {
+ -26, 19, 15, 12, 5, 22, 24, 0, 21, -12,
+ -21, -15, -8, 11, -7, 12, -14, 20, -2, 6,
+ 7, 6, 16, 9, -6, 5, -21, -7, -15, -10,
+ -13, -39, -5, -10, -20, 19, 28, 5, 22, 5,
+ }, {
+ -4, 6, 3, -5, 1, 4, 11, -16, 6, -23,
+ -19, -29, 0, 3, -6, 30, -3, 17, 10, 5,
+ 13, 2, 17, -3, -5, -3, -35, -21, -17, -17,
+ -2, -35, 2, 15, -3, 28, 13, 21, 13, 13,
+ }, {
+ -8, 25, 8, 23, -3, 13, 3, -17, 20, -8,
+ 0, 10, 8, 11, 18, 0, 1, 10, 5, 0,
+ 28, 17, 32, 15, 26, 1, -19, -9, -3, -21,
+ -15, 7, -6, -9, -29, -5, 10, -17, -15, -9,
+ }, {
+ 13, 13, -3, 5, -7, -4, -9, -34, 5, -20,
+ 2, -3, 16, 3, 20, 17, 11, 7, 17, 0,
+ 34, 13, 33, 2, 28, -8, -32, -24, -5, -29,
+ -3, 12, 0, 15, -11, 3, -3, -2, -24, -1,
+ }, {
+ -18, 17, 21, 25, -11, 19, 6, 3, 11, 0,
+ -7, 11, 13, 31, 1, 0, -9, -1, -5, -12,
+ 18, 0, 31, 2, 13, 1, -30, -14, -7, -29,
+ -9, -18, 1, -10, -4, 18, 22, -3, 10, 2,
+ }, {
+ 3, 5, 9, 7, -15, 1, -5, -13, -2, -12,
+ -5, -2, 21, 23, 2, 16, 0, -5, 6, -13,
+ 23, -3, 32, -10, 15, -8, -44, -28, -9, -37,
+ 2, -13, 9, 15, 12, 27, 7, 12, 0, 11,
+ }, {
+ -44, 6, -30, -8, 9, 10, 11, 14, 23, -5,
+ 8, -4, 14, -12, 37, 14, 12, 26, 4, 16,
+ -8, 16, -9, 7, -6, 19, 12, 25, -5, 24,
+ -15, -13, -8, -36, -34, -31, -1, -18, -4, -18,
+ }, {
+ -22, -5, -42, -26, 6, -8, -1, -2, 9, -17,
+ 10, -18, 21, -19, 39, 31, 23, 23, 16, 15,
+ -2, 12, -7, -6, -5, 9, -1, 10, -7, 16,
+ -4, -9, 0, -10, -17, -22, -16, -2, -14, -9,
+ }, {
+ -55, -1, -17, -6, 1, 16, 15, 35, 15, 2,
+ 0, -4, 19, 8, 20, 13, 1, 14, -7, 3,
+ -18, 0, -10, -5, -19, 19, 0, 21, -8, 16,
+ -9, -39, 0, -36, -10, -7, 9, -4, 20, -5,
+ }, {
+ -33, -13, -29, -24, -1, -1, 2, 18, 0, -9,
+ 3, -17, 27, 0, 21, 30, 12, 11, 5, 2,
+ -12, -4, -9, -19, -18, 9, -13, 6, -11, 8,
+ 2, -35, 8, -10, 7, 1, -4, 11, 10, 2,
+ }, {
+ -36, 5, -24, 4, -7, 7, -6, 17, 14, 5,
+ 22, 22, 35, 8, 46, 1, 17, 3, 0, -2,
+ 2, 10, 5, 0, 14, 15, 2, 18, 2, 4,
+ -11, 7, -1, -36, -18, -32, -7, -27, -17, -20,
+ }, {
+ -14, -7, -36, -13, -10, -10, -18, 0, 0, -5,
+ 25, 8, 43, 0, 48, 18, 27, 0, 12, -3,
+ 7, 6, 7, -13, 15, 5, -11, 3, 0, -2,
+ 0, 12, 6, -10, 0, -23, -22, -11, -26, -12,
+ }, {
+ -47, -3, -11, 6, -15, 13, -2, 38, 6, 13,
+ 15, 22, 40, 28, 28, 0, 5, -8, -10, -15,
+ -7, -7, 4, -13, 1, 14, -9, 14, 0, -2,
+ -4, -18, 7, -36, 6, -8, 3, -13, 7, -8,
+ }, {
+ -25, -15, -22, -11, -18, -4, -15, 22, -8, 2,
+ 17, 9, 48, 20, 30, 17, 16, -11, 1, -16,
+ -2, -10, 5, -26, 2, 4, -22, 0, -2, -10,
+ 6, -13, 14, -10, 23, 0, -10, 2, -1, 0,
+ }, {
+ -57, 26, -22, 7, 14, 28, 14, 3, 35, 0,
+ -3, -1, 11, -16, 18, 10, 4, 31, 15, 28,
+ 14, 23, 1, 21, -7, 2, -11, 1, -3, 1,
+ -18, -9, -10, -13, -49, -24, -8, -14, -2, -16,
+ }, {
+ -35, 14, -34, -10, 10, 10, 1, -12, 20, -12,
+ 0, -15, 18, -24, 20, 27, 14, 28, 27, 27,
+ 20, 19, 2, 8, -5, -7, -25, -13, -5, -5,
+ -6, -5, -2, 12, -31, -15, -23, 1, -12, -8,
+ }, {
+ -68, 18, -9, 9, 6, 35, 18, 25, 26, 7,
+ -10, -1, 16, 3, 1, 9, -6, 19, 4, 15,
+ 4, 6, 0, 8, -20, 2, -23, -2, -7, -5,
+ -12, -35, -1, -13, -24, 0, 3, 0, 22, -4,
+ }, {
+ -46, 6, -21, -8, 2, 16, 5, 8, 11, -4,
+ -8, -15, 24, -4, 2, 26, 3, 16, 16, 14,
+ 9, 2, 1, -4, -19, -7, -36, -17, -9, -13,
+ 0, -31, 5, 12, -7, 8, -11, 15, 13, 4,
+ }, {
+ -49, 24, -16, 20, -2, 26, -2, 7, 25, 10,
+ 11, 25, 32, 3, 27, -2, 8, 8, 11, 9,
+ 24, 17, 16, 14, 13, -2, -20, -5, 4, -17,
+ -14, 12, -3, -13, -33, -25, -14, -23, -15, -19,
+ }, {
+ -27, 12, -28, 2, -6, 7, -15, -9, 11, -1,
+ 13, 11, 40, -4, 29, 14, 19, 5, 23, 8,
+ 30, 13, 17, 0, 14, -12, -34, -20, 2, -25,
+ -2, 16, 4, 12, -15, -16, -29, -7, -24, -10,
+ }, {
+ -60, 16, -3, 22, -10, 32, 0, 28, 17, 18,
+ 3, 25, 37, 23, 10, -3, -2, -3, 0, -3,
+ 14, 0, 14, 1, 0, -2, -32, -9, 1, -25,
+ -7, -13, 5, -13, -8, -1, -2, -8, 10, -6,
+ }, {
+ -38, 4, -15, 4, -14, 13, -12, 11, 2, 6,
+ 6, 11, 45, 16, 11, 13, 7, -6, 12, -4,
+ 20, -3, 16, -12, 1, -12, -46, -24, 0, -33,
+ 3, -9, 12, 12, 8, 7, -17, 6, 0, 2
+ }
+};
+
+const int8_t ff_cb2_vects[128][40]={
+ {
+ 73, -32, -60, -15, -26, 59, 2, -33, 30, -10,
+ -3, -17, 8, 30, -1, -26, -4, -22, 10, 16,
+ -36, -5, -11, 56, 37, 6, -10, -5, -13, -3,
+ 6, -5, 11, 4, -19, -5, -16, 41, 24, 13,
+ }, {
+ 4, -11, -37, 23, -5, 46, -2, -29, -5, -39,
+ -21, -9, 0, 49, 12, -9, -16, -26, 22, 15,
+ -45, -20, -5, 40, 22, 17, -26, 31, -14, 2,
+ -14, 10, 30, 20, -27, -9, -39, 39, 18, 5,
+ }, {
+ 34, -25, -48, -28, -11, 34, -2, -41, 9, -7,
+ -17, 21, 20, 24, -17, -33, 0, -24, 10, 42,
+ 3, -5, 10, 42, 11, 8, -3, 3, 16, 9,
+ 22, -2, 0, -33, -10, 18, 7, 58, 10, 28,
+ }, {
+ -34, -4, -25, 10, 9, 21, -7, -36, -26, -36,
+ -35, 28, 12, 42, -3, -16, -12, -28, 21, 42,
+ -5, -21, 16, 26, -4, 19, -19, 39, 15, 15,
+ 1, 13, 19, -17, -17, 14, -15, 55, 4, 19,
+ }, {
+ 28, -20, -51, -14, -6, 7, 0, -26, 27, -4,
+ 18, -40, -6, 16, -1, -15, 0, -55, -5, -16,
+ -19, 14, -3, 49, 14, 1, -22, -30, -12, 0,
+ 24, 15, 9, -17, -45, -29, 4, 28, 51, 35,
+ }, {
+ -40, 0, -28, 24, 14, -5, -4, -21, -7, -33,
+ 0, -32, -15, 35, 12, 1, -11, -58, 5, -16,
+ -28, 0, 1, 33, 0, 11, -39, 5, -14, 6,
+ 3, 31, 28, -1, -53, -33, -19, 25, 46, 26,
+ }, {
+ -11, -14, -39, -27, 9, -17, -4, -33, 6, 0,
+ 4, -1, 5, 10, -17, -22, 5, -57, -5, 9,
+ 20, 13, 18, 35, -11, 3, -16, -22, 17, 13,
+ 40, 19, -1, -55, -35, -5, 27, 44, 37, 49,
+ }, {
+ -80, 6, -16, 11, 30, -30, -9, -28, -28, -29,
+ -13, 6, -2, 28, -3, -5, -7, -60, 5, 9,
+ 11, -1, 24, 19, -27, 13, -32, 13, 15, 19,
+ 19, 35, 17, -39, -43, -9, 4, 42, 32, 41,
+ }, {
+ 78, -21, -43, 4, -38, 17, 17, -5, 55, 24,
+ -15, -36, 14, 4, 24, -24, 12, 5, 17, 31,
+ -54, -5, -2, 27, 43, -12, 2, 9, -9, -15,
+ 22, -3, 28, 21, -20, 3, 20, 28, 9, -5,
+ }, {
+ 9, -1, -20, 43, -17, 3, 12, 0, 20, -4,
+ -33, -29, 6, 22, 38, -7, 0, 1, 29, 30,
+ -63, -21, 3, 11, 27, -1, -14, 45, -10, -9,
+ 1, 12, 47, 37, -28, 0, -2, 26, 4, -13,
+ }, {
+ 39, -14, -30, -8, -22, -8, 12, -12, 34, 27,
+ -29, 2, 26, -2, 8, -31, 16, 3, 17, 57,
+ -14, -6, 19, 13, 16, -10, 8, 17, 20, -2,
+ 38, 0, 17, -16, -11, 27, 44, 45, -4, 8,
+ }, {
+ -29, 5, -7, 30, -1, -21, 7, -7, 0, 0,
+ -47, 9, 18, 15, 22, -14, 4, 0, 28, 57,
+ -23, -21, 25, -2, 1, 0, -7, 53, 19, 3,
+ 17, 15, 36, 0, -19, 24, 21, 43, -9, 0,
+ }, {
+ 33, -10, -34, 5, -17, -35, 15, 1, 53, 30,
+ 6, -59, 0, -10, 24, -13, 17, -27, 1, -1,
+ -37, 13, 4, 20, 20, -18, -10, -16, -8, -11,
+ 39, 18, 26, 0, -46, -20, 41, 15, 37, 15,
+ }, {
+ -35, 10, -11, 44, 3, -48, 10, 6, 17, 2,
+ -11, -51, -8, 8, 38, 3, 4, -31, 12, -2,
+ -46, -1, 10, 4, 5, -7, -26, 19, -10, -5,
+ 18, 34, 45, 15, -54, -24, 18, 13, 31, 7,
+ }, {
+ -5, -3, -21, -7, -2, -60, 10, -5, 32, 34,
+ -7, -20, 11, -16, 8, -20, 21, -29, 1, 24,
+ 2, 13, 27, 6, -5, -15, -3, -8, 21, 1,
+ 55, 21, 15, -38, -37, 3, 65, 32, 23, 30,
+ }, {
+ -74, 17, 0, 31, 18, -73, 5, 0, -3, 5,
+ -25, -12, 3, 1, 22, -3, 9, -33, 12, 24,
+ -6, -2, 33, -9, -21, -5, -20, 27, 19, 7,
+ 34, 37, 34, -22, -44, 0, 41, 29, 17, 21,
+ }, {
+ 76, -35, -31, -28, -49, 43, -40, 0, 29, -14,
+ 8, 5, 10, 18, -26, -46, 0, 7, 6, 3,
+ -25, -7, -2, 40, 28, 14, 18, -3, -27, -28,
+ -8, -45, -13, 34, -13, -27, -15, 31, 12, 3,
+ }, {
+ 7, -15, -9, 9, -28, 29, -45, 5, -6, -43,
+ -9, 12, 2, 36, -12, -30, -11, 3, 17, 3,
+ -34, -22, 3, 24, 12, 24, 2, 32, -28, -22,
+ -29, -29, 5, 50, -21, -31, -38, 29, 7, -5,
+ }, {
+ 36, -29, -19, -41, -34, 18, -45, -6, 8, -10,
+ -5, 43, 23, 11, -42, -53, 5, 5, 6, 30,
+ 14, -8, 20, 26, 1, 16, 25, 4, 3, -15,
+ 7, -41, -23, -3, -4, -3, 8, 48, -1, 17,
+ }, {
+ -32, -8, 3, -2, -13, 4, -50, -1, -27, -39,
+ -23, 51, 15, 30, -27, -37, -7, 1, 17, 29,
+ 5, -23, 25, 10, -14, 26, 8, 41, 1, -9,
+ -13, -26, -5, 12, -12, -7, -14, 45, -6, 9,
+ }, {
+ 31, -24, -23, -27, -29, -9, -43, 8, 26, -7,
+ 30, -17, -4, 3, -26, -35, 5, -24, -10, -28,
+ -9, 12, 5, 33, 5, 8, 5, -29, -26, -24,
+ 9, -23, -14, 12, -39, -52, 5, 18, 39, 24,
+ }, {
+ -37, -3, 0, 10, -7, -22, -48, 12, -8, -36,
+ 12, -9, -12, 22, -12, -19, -6, -28, 0, -29,
+ -18, -3, 11, 17, -10, 18, -10, 7, -27, -18,
+ -11, -7, 3, 28, -47, -55, -18, 15, 34, 16,
+ }, {
+ -8, -17, -10, -40, -13, -34, -47, 0, 5, -4,
+ 16, 21, 8, -2, -42, -43, 10, -26, -10, -2,
+ 31, 11, 27, 19, -21, 10, 12, -20, 3, -11,
+ 25, -20, -25, -25, -29, -28, 28, 34, 25, 38,
+ }, {
+ -77, 2, 11, -1, 7, -47, -52, 5, -29, -33,
+ -1, 28, 0, 15, -28, -26, -2, -30, 0, -2,
+ 22, -4, 33, 3, -36, 21, -3, 15, 2, -5,
+ 4, -4, -6, -9, -37, -31, 5, 32, 20, 30,
+ }, {
+ 81, -25, -14, -8, -61, 0, -25, 28, 54, 20,
+ -3, -14, 17, -8, 0, -44, 16, 35, 13, 18,
+ -43, -7, 6, 11, 33, -4, 30, 11, -22, -40,
+ 6, -43, 3, 50, -14, -18, 22, 18, -1, -16,
+ }, {
+ 12, -4, 8, 29, -39, -12, -30, 33, 19, -8,
+ -21, -6, 8, 9, 13, -28, 4, 31, 24, 18,
+ -52, -23, 12, -4, 18, 5, 14, 47, -24, -34,
+ -14, -27, 22, 66, -22, -22, -1, 16, -6, -24,
+ }, {
+ 41, -18, -2, -21, -45, -24, -30, 21, 33, 24,
+ -17, 24, 29, -15, -16, -51, 21, 33, 13, 45,
+ -3, -8, 28, -2, 7, -2, 37, 19, 7, -27,
+ 22, -39, -7, 12, -5, 5, 45, 35, -15, -1,
+ }, {
+ -27, 1, 20, 17, -24, -38, -35, 26, -1, -4,
+ -35, 32, 21, 3, -2, -35, 8, 29, 24, 44,
+ -12, -24, 34, -18, -8, 7, 21, 55, 5, -21,
+ 2, -23, 11, 28, -13, 1, 22, 33, -21, -10,
+ }, {
+ 36, -13, -5, -7, -40, -51, -28, 36, 52, 27,
+ 18, -36, 2, -22, 0, -33, 21, 2, -3, -13,
+ -26, 11, 14, 4, 10, -10, 18, -14, -22, -36,
+ 24, -21, 1, 28, -40, -42, 42, 5, 25, 5,
+ }, {
+ -32, 6, 17, 31, -19, -65, -33, 41, 16, -1,
+ 0, -29, -6, -4, 13, -17, 9, -1, 8, -14,
+ -35, -3, 19, -11, -4, 0, 1, 21, -23, -30,
+ 3, -5, 20, 44, -48, -46, 19, 3, 20, -3,
+ }, {
+ -3, -7, 6, -20, -25, -77, -32, 29, 31, 30,
+ 4, 2, 14, -29, -16, -40, 26, 0, -3, 12,
+ 13, 10, 36, -9, -15, -8, 24, -6, 7, -22,
+ 40, -17, -8, -9, -31, -18, 66, 22, 11, 19,
+ }, {
+ -72, 13, 29, 18, -4, -90, -37, 34, -4, 1,
+ -13, 9, 6, -11, -2, -24, 13, -3, 7, 11,
+ 4, -4, 42, -25, -31, 1, 8, 29, 6, -17,
+ 19, -2, 10, 6, -38, -22, 42, 19, 6, 11,
+ }, {
+ 116, -20, -68, -30, -28, 83, 28, -18, 32, -22,
+ -13, -21, 5, 28, 5, -7, -24, -8, -22, 17,
+ -23, 30, -25, 45, 15, -9, -11, -18, 22, -10,
+ 4, -2, 19, -12, 23, 3, -43, 2, 12, -4,
+ }, {
+ 47, 0, -45, 7, -7, 69, 23, -13, -2, -51,
+ -32, -14, -3, 47, 19, 8, -37, -11, -10, 16,
+ -32, 15, -19, 29, 0, 1, -28, 18, 20, -4,
+ -16, 13, 38, 3, 15, 0, -66, 0, 7, -13,
+ }, {
+ 77, -13, -56, -43, -13, 57, 23, -26, 11, -19,
+ -27, 16, 17, 22, -10, -15, -19, -10, -22, 43,
+ 16, 30, -2, 31, -11, -6, -5, -9, 52, 2,
+ 20, 0, 8, -50, 33, 27, -19, 19, -1, 9,
+ }, {
+ 8, 6, -33, -4, 7, 44, 18, -21, -23, -48,
+ -46, 24, 9, 40, 3, 1, -32, -13, -11, 43,
+ 7, 14, 3, 15, -26, 3, -21, 26, 50, 8,
+ 0, 16, 27, -34, 25, 23, -43, 17, -6, 1,
+ }, {
+ 71, -9, -59, -29, -8, 30, 26, -11, 30, -16,
+ 8, -44, -9, 14, 5, 2, -19, -40, -38, -15,
+ -7, 50, -17, 38, -7, -14, -24, -43, 22, -6,
+ 22, 19, 17, -34, -2, -20, -23, -10, 39, 16,
+ }, {
+ 2, 11, -36, 9, 13, 17, 21, -6, -5, -45,
+ -10, -36, -18, 33, 19, 19, -31, -44, -27, -15,
+ -16, 34, -11, 22, -22, -4, -40, -7, 21, 0,
+ 1, 35, 36, -18, -10, -24, -46, -12, 34, 8,
+ }, {
+ 32, -2, -47, -42, 7, 5, 21, -18, 9, -12,
+ -5, -5, 2, 8, -10, -4, -14, -42, -38, 10,
+ 33, 49, 5, 24, -33, -12, -17, -35, 52, 6,
+ 38, 22, 7, -72, 7, 3, 0, 6, 25, 30,
+ }, {
+ -36, 18, -24, -3, 28, -7, 16, -13, -26, -41,
+ -24, 1, -5, 26, 3, 12, -27, -46, -27, 10,
+ 24, 34, 10, 8, -49, -2, -34, 0, 51, 12,
+ 17, 38, 25, -56, 0, 0, -22, 3, 20, 22,
+ }, {
+ 121, -9, -50, -10, -40, 40, 43, 9, 58, 12,
+ -25, -41, 11, 2, 31, -5, -8, 19, -15, 32,
+ -41, 30, -16, 16, 20, -28, 0, -3, 26, -22,
+ 19, 0, 36, 4, 22, 12, -6, -9, -1, -24,
+ }, {
+ 52, 10, -27, 27, -18, 26, 38, 14, 23, -16,
+ -44, -33, 3, 20, 45, 10, -20, 15, -3, 31,
+ -50, 14, -10, 0, 5, -17, -15, 32, 24, -16,
+ -1, 15, 55, 20, 14, 8, -29, -12, -7, -32,
+ }, {
+ 82, -3, -38, -23, -24, 15, 38, 2, 37, 15,
+ -39, -2, 23, -4, 15, -12, -3, 17, -15, 58,
+ -1, 29, 6, 2, -5, -26, 7, 4, 56, -9,
+ 35, 3, 25, -33, 32, 36, 17, 7, -15, -9,
+ }, {
+ 13, 17, -15, 15, -3, 1, 33, 7, 1, -12,
+ -58, 5, 15, 13, 29, 3, -16, 13, -4, 57,
+ -10, 13, 11, -13, -21, -15, -9, 40, 55, -3,
+ 14, 19, 44, -17, 24, 32, -5, 4, -21, -18,
+ }, {
+ 76, 1, -41, -9, -19, -12, 41, 17, 55, 18,
+ -3, -63, -3, -12, 30, 5, -3, -12, -31, 0,
+ -24, 49, -8, 9, -1, -33, -12, -29, 27, -18,
+ 37, 21, 34, -17, -3, -11, 14, -23, 25, -2,
+ }, {
+ 7, 22, -18, 29, 1, -25, 36, 21, 20, -9,
+ -22, -56, -11, 6, 45, 21, -15, -16, -20, -1,
+ -33, 34, -2, -6, -17, -23, -28, 6, 25, -12,
+ 16, 37, 53, -1, -11, -15, -8, -25, 20, -11,
+ }, {
+ 37, 8, -29, -22, -4, -37, 36, 9, 34, 22,
+ -17, -24, 8, -18, 15, -2, 1, -14, -31, 25,
+ 15, 48, 13, -4, -28, -31, -5, -21, 57, -4,
+ 53, 24, 23, -55, 6, 12, 37, -6, 11, 11,
+ }, {
+ -31, 28, -6, 16, 16, -50, 31, 14, 0, -6,
+ -36, -17, 0, 0, 29, 14, -11, -18, -20, 25,
+ 6, 33, 19, -20, -43, -21, -21, 14, 55, 0,
+ 32, 40, 42, -39, -1, 8, 14, -8, 6, 3,
+ }, {
+ 119, -24, -39, -44, -51, 66, -14, 15, 31, -26,
+ -1, 0, 7, 16, -19, -28, -19, 22, -26, 4,
+ -13, 28, -16, 29, 5, -1, 16, -16, 8, -35,
+ -10, -42, -4, 17, 29, -19, -42, -7, 0, -15,
+ }, {
+ 50, -3, -16, -5, -30, 53, -19, 20, -3, -55,
+ -19, 8, 0, 34, -5, -11, -32, 18, -15, 4,
+ -22, 13, -10, 13, -9, 8, 0, 19, 7, -29,
+ -31, -26, 13, 33, 21, -22, -65, -9, -4, -23,
+ }, {
+ 79, -17, -27, -56, -36, 41, -19, 8, 10, -22,
+ -15, 39, 20, 9, -35, -35, -15, 20, -26, 31,
+ 26, 27, 6, 15, -20, 0, 23, -8, 38, -22,
+ 5, -38, -15, -20, 39, 4, -18, 9, -13, -1,
+ }, {
+ 10, 3, -4, -18, -15, 27, -24, 13, -24, -51,
+ -34, 47, 12, 28, -21, -19, -27, 16, -15, 30,
+ 17, 12, 12, 0, -36, 10, 7, 27, 37, -16,
+ -15, -22, 3, -4, 31, 1, -42, 7, -18, -9,
+ }, {
+ 74, -12, -30, -42, -30, 14, -16, 23, 29, -19,
+ 20, -21, -7, 1, -19, -17, -14, -10, -43, -27,
+ 3, 48, -8, 22, -16, -7, 4, -42, 9, -31,
+ 6, -20, -6, -4, 3, -43, -22, -20, 28, 5,
+ }, {
+ 5, 7, -7, -4, -9, 0, -21, 28, -6, -48,
+ 2, -14, -15, 20, -5, 0, -27, -14, -32, -28,
+ -5, 32, -2, 6, -32, 3, -12, -5, 8, -25,
+ -14, -4, 12, 11, -4, -47, -45, -22, 22, -2,
+ }, {
+ 34, -6, -18, -55, -15, -11, -21, 16, 8, -16,
+ 6, 16, 5, -4, -35, -24, -10, -12, -43, -1,
+ 43, 47, 14, 8, -43, -5, 10, -34, 39, -18,
+ 22, -16, -17, -42, 13, -19, 1, -3, 14, 20,
+ }, {
+ -34, 14, 4, -17, 5, -24, -26, 20, -27, -45,
+ -12, 24, -2, 13, -21, -8, -22, -16, -32, -2,
+ 34, 31, 20, -7, -58, 5, -5, 2, 38, -12,
+ 2, -1, 1, -26, 5, -23, -21, -6, 8, 11,
+ }, {
+ 124, -13, -21, -23, -62, 23, 0, 43, 57, 8,
+ -13, -18, 14, -10, 6, -26, -3, 49, -19, 19,
+ -31, 27, -7, 0, 11, -20, 29, -1, 12, -47,
+ 4, -39, 11, 34, 28, -9, -5, -19, -13, -34,
+ }, {
+ 55, 6, 1, 14, -41, 10, -4, 48, 22, -20,
+ -31, -10, 5, 7, 20, -9, -16, 45, -8, 19,
+ -40, 12, -1, -15, -4, -10, 12, 34, 11, -41,
+ -16, -24, 30, 49, 20, -13, -28, -22, -18, -43,
+ }, {
+ 84, -6, -9, -36, -47, -1, -4, 36, 36, 12,
+ -27, 20, 26, -17, -9, -33, 1, 47, -19, 46,
+ 9, 27, 15, -13, -15, -18, 35, 6, 42, -33,
+ 20, -36, 1, -4, 38, 14, 18, -2, -27, -20,
+ }, {
+ 15, 13, 13, 1, -26, -14, -9, 41, 1, -16,
+ -46, 27, 18, 1, 4, -16, -11, 43, -8, 45,
+ 0, 11, 21, -29, -30, -8, 19, 42, 41, -28,
+ 0, -20, 20, 11, 30, 10, -4, -5, -32, -28,
+ }, {
+ 79, -2, -12, -22, -42, -28, -1, 51, 54, 15,
+ 8, -41, 0, -24, 6, -15, 1, 17, -36, -12,
+ -14, 47, 0, -6, -11, -26, 16, -27, 13, -43,
+ 22, -18, 10, 12, 2, -34, 15, -33, 13, -13,
+ }, {
+ 10, 18, 10, 15, -21, -41, -6, 56, 19, -13,
+ -9, -33, -9, -6, 20, 1, -11, 13, -24, -13,
+ -23, 32, 6, -22, -26, -15, 0, 8, 12, -37,
+ 1, -2, 28, 27, -5, -37, -7, -35, 8, -21,
+ }, {
+ 39, 4, 0, -35, -27, -53, -6, 44, 33, 18,
+ -5, -2, 11, -31, -9, -22, 6, 15, -36, 13,
+ 25, 46, 23, -20, -37, -24, 23, -19, 43, -29,
+ 38, -14, 0, -26, 12, -10, 38, -16, 0, 0,
+ }, {
+ -29, 25, 22, 2, -6, -67, -11, 49, -1, -10,
+ -24, 5, 3, -13, 4, -5, -6, 11, -25, 12,
+ 16, 31, 28, -36, -53, -13, 6, 16, 42, -24,
+ 17, 1, 18, -10, 4, -13, 15, -18, -5, -7,
+ }, {
+ 29, -25, -22, -2, 6, 67, 11, -49, 1, 10,
+ 24, -5, -3, 13, -4, 5, 6, -11, 25, -12,
+ -16, -31, -28, 36, 53, 13, -6, -16, -42, 24,
+ -17, -1, -18, 10, -4, 13, -15, 18, 5, 7,
+ }, {
+ -39, -4, 0, 35, 27, 53, 6, -44, -33, -18,
+ 5, 2, -11, 31, 9, 22, -6, -15, 36, -13,
+ -25, -46, -23, 20, 37, 24, -23, 19, -43, 29,
+ -38, 14, 0, 26, -12, 10, -38, 16, 0, 0,
+ }, {
+ -10, -18, -10, -15, 21, 41, 6, -56, -19, 13,
+ 9, 33, 9, 6, -20, -1, 11, -13, 24, 13,
+ 23, -32, -6, 22, 26, 15, 0, -8, -12, 37,
+ -1, 2, -28, -27, 5, 37, 7, 35, -8, 21,
+ }, {
+ -79, 2, 12, 22, 42, 28, 1, -51, -54, -15,
+ -8, 41, 0, 24, -6, 15, -1, -17, 36, 12,
+ 14, -47, 0, 6, 11, 26, -16, 27, -13, 43,
+ -22, 18, -10, -12, -2, 34, -15, 33, -13, 13,
+ }, {
+ -15, -13, -13, -1, 26, 14, 9, -41, -1, 16,
+ 46, -27, -18, -1, -4, 16, 11, -43, 8, -45,
+ 0, -11, -21, 29, 30, 8, -19, -42, -41, 28,
+ 0, 20, -20, -11, -30, -10, 4, 5, 32, 28,
+ }, {
+ -84, 6, 9, 36, 47, 1, 4, -36, -36, -12,
+ 27, -20, -26, 17, 9, 33, -1, -47, 19, -46,
+ -9, -27, -15, 13, 15, 18, -35, -6, -42, 33,
+ -20, 36, -1, 4, -38, -14, -18, 2, 27, 20,
+ }, {
+ -55, -6, -1, -14, 41, -10, 4, -48, -22, 20,
+ 31, 10, -5, -7, -20, 9, 16, -45, 8, -19,
+ 40, -12, 1, 15, 4, 10, -12, -34, -11, 41,
+ 16, 24, -30, -49, -20, 13, 28, 22, 18, 43,
+ }, {
+ -124, 13, 21, 23, 62, -23, 0, -43, -57, -8,
+ 13, 18, -14, 10, -6, 26, 3, -49, 19, -19,
+ 31, -27, 7, 0, -11, 20, -29, 1, -12, 47,
+ -4, 39, -11, -34, -28, 9, 5, 19, 13, 34,
+ }, {
+ 34, -14, -4, 17, -5, 24, 26, -20, 27, 45,
+ 12, -24, 2, -13, 21, 8, 22, 16, 32, 2,
+ -34, -31, -20, 7, 58, -5, 5, -2, -38, 12,
+ -2, 1, -1, 26, -5, 23, 21, 6, -8, -11,
+ }, {
+ -34, 6, 18, 55, 15, 11, 21, -16, -8, 16,
+ -6, -16, -5, 4, 35, 24, 10, 12, 43, 1,
+ -43, -47, -14, -8, 43, 5, -10, 34, -39, 18,
+ -22, 16, 17, 42, -13, 19, -1, 3, -14, -20,
+ }, {
+ -5, -7, 7, 4, 9, 0, 21, -28, 6, 48,
+ -2, 14, 15, -20, 5, 0, 27, 14, 32, 28,
+ 5, -32, 2, -6, 32, -3, 12, 5, -8, 25,
+ 14, 4, -12, -11, 4, 47, 45, 22, -22, 2,
+ }, {
+ -74, 12, 30, 42, 30, -14, 16, -23, -29, 19,
+ -20, 21, 7, -1, 19, 17, 14, 10, 43, 27,
+ -3, -48, 8, -22, 16, 7, -4, 42, -9, 31,
+ -6, 20, 6, 4, -3, 43, 22, 20, -28, -5,
+ }, {
+ -10, -3, 4, 18, 15, -27, 24, -13, 24, 51,
+ 34, -47, -12, -28, 21, 19, 27, -16, 15, -30,
+ -17, -12, -12, 0, 36, -10, -7, -27, -37, 16,
+ 15, 22, -3, 4, -31, -1, 42, -7, 18, 9,
+ }, {
+ -79, 17, 27, 56, 36, -41, 19, -8, -10, 22,
+ 15, -39, -20, -9, 35, 35, 15, -20, 26, -31,
+ -26, -27, -6, -15, 20, 0, -23, 8, -38, 22,
+ -5, 38, 15, 20, -39, -4, 18, -9, 13, 1,
+ }, {
+ -50, 3, 16, 5, 30, -53, 19, -20, 3, 55,
+ 19, -8, 0, -34, 5, 11, 32, -18, 15, -4,
+ 22, -13, 10, -13, 9, -8, 0, -19, -7, 29,
+ 31, 26, -13, -33, -21, 22, 65, 9, 4, 23,
+ }, {
+ -119, 24, 39, 44, 51, -66, 14, -15, -31, 26,
+ 1, 0, -7, -16, 19, 28, 19, -22, 26, -4,
+ 13, -28, 16, -29, -5, 1, -16, 16, -8, 35,
+ 10, 42, 4, -17, -29, 19, 42, 7, 0, 15,
+ }, {
+ 31, -28, 6, -16, -16, 50, -31, -14, 0, 6,
+ 36, 17, 0, 0, -29, -14, 11, 18, 20, -25,
+ -6, -33, -19, 20, 43, 21, 21, -14, -55, 0,
+ -32, -40, -42, 39, 1, -8, -14, 8, -6, -3,
+ }, {
+ -37, -8, 29, 22, 4, 37, -36, -9, -34, -22,
+ 17, 24, -8, 18, -15, 2, -1, 14, 31, -25,
+ -15, -48, -13, 4, 28, 31, 5, 21, -57, 4,
+ -53, -24, -23, 55, -6, -12, -37, 6, -11, -11,
+ }, {
+ -7, -22, 18, -29, -1, 25, -36, -21, -20, 9,
+ 22, 56, 11, -6, -45, -21, 15, 16, 20, 1,
+ 33, -34, 2, 6, 17, 23, 28, -6, -25, 12,
+ -16, -37, -53, 1, 11, 15, 8, 25, -20, 11,
+ }, {
+ -76, -1, 41, 9, 19, 12, -41, -17, -55, -18,
+ 3, 63, 3, 12, -30, -5, 3, 12, 31, 0,
+ 24, -49, 8, -9, 1, 33, 12, 29, -27, 18,
+ -37, -21, -34, 17, 3, 11, -14, 23, -25, 2,
+ }, {
+ -13, -17, 15, -15, 3, -1, -33, -7, -1, 12,
+ 58, -5, -15, -13, -29, -3, 16, -13, 4, -57,
+ 10, -13, -11, 13, 21, 15, 9, -40, -55, 3,
+ -14, -19, -44, 17, -24, -32, 5, -4, 21, 18,
+ }, {
+ -82, 3, 38, 23, 24, -15, -38, -2, -37, -15,
+ 39, 2, -23, 4, -15, 12, 3, -17, 15, -58,
+ 1, -29, -6, -2, 5, 26, -7, -4, -56, 9,
+ -35, -3, -25, 33, -32, -36, -17, -7, 15, 9,
+ }, {
+ -52, -10, 27, -27, 18, -26, -38, -14, -23, 16,
+ 44, 33, -3, -20, -45, -10, 20, -15, 3, -31,
+ 50, -14, 10, 0, -5, 17, 15, -32, -24, 16,
+ 1, -15, -55, -20, -14, -8, 29, 12, 7, 32,
+ }, {
+ -121, 9, 50, 10, 40, -40, -43, -9, -58, -12,
+ 25, 41, -11, -2, -31, 5, 8, -19, 15, -32,
+ 41, -30, 16, -16, -20, 28, 0, 3, -26, 22,
+ -19, 0, -36, -4, -22, -12, 6, 9, 1, 24,
+ }, {
+ 36, -18, 24, 3, -28, 7, -16, 13, 26, 41,
+ 24, -1, 5, -26, -3, -12, 27, 46, 27, -10,
+ -24, -34, -10, -8, 49, 2, 34, 0, -51, -12,
+ -17, -38, -25, 56, 0, 0, 22, -3, -20, -22,
+ }, {
+ -32, 2, 47, 42, -7, -5, -21, 18, -9, 12,
+ 5, 5, -2, -8, 10, 4, 14, 42, 38, -10,
+ -33, -49, -5, -24, 33, 12, 17, 35, -52, -6,
+ -38, -22, -7, 72, -7, -3, 0, -6, -25, -30,
+ }, {
+ -2, -11, 36, -9, -13, -17, -21, 6, 5, 45,
+ 10, 36, 18, -33, -19, -19, 31, 44, 27, 15,
+ 16, -34, 11, -22, 22, 4, 40, 7, -21, 0,
+ -1, -35, -36, 18, 10, 24, 46, 12, -34, -8,
+ }, {
+ -71, 9, 59, 29, 8, -30, -26, 11, -30, 16,
+ -8, 44, 9, -14, -5, -2, 19, 40, 38, 15,
+ 7, -50, 17, -38, 7, 14, 24, 43, -22, 6,
+ -22, -19, -17, 34, 2, 20, 23, 10, -39, -16,
+ }, {
+ -8, -6, 33, 4, -7, -44, -18, 21, 23, 48,
+ 46, -24, -9, -40, -3, -1, 32, 13, 11, -43,
+ -7, -14, -3, -15, 26, -3, 21, -26, -50, -8,
+ 0, -16, -27, 34, -25, -23, 43, -17, 6, -1,
+ }, {
+ -77, 13, 56, 43, 13, -57, -23, 26, -11, 19,
+ 27, -16, -17, -22, 10, 15, 19, 10, 22, -43,
+ -16, -30, 2, -31, 11, 6, 5, 9, -52, -2,
+ -20, 0, -8, 50, -33, -27, 19, -19, 1, -9,
+ }, {
+ -47, 0, 45, -7, 7, -69, -23, 13, 2, 51,
+ 32, 14, 3, -47, -19, -8, 37, 11, 10, -16,
+ 32, -15, 19, -29, 0, -1, 28, -18, -20, 4,
+ 16, -13, -38, -3, -15, 0, 66, 0, -7, 13,
+ }, {
+ -116, 20, 68, 30, 28, -83, -28, 18, -32, 22,
+ 13, 21, -5, -28, -5, 7, 24, 8, 22, -17,
+ 23, -30, 25, -45, -15, 9, 11, 18, -22, 10,
+ -4, 2, -19, 12, -23, -3, 43, -2, -12, 4,
+ }, {
+ 72, -13, -29, -18, 4, 90, 37, -34, 4, -1,
+ 13, -9, -6, 11, 2, 24, -13, 3, -7, -11,
+ -4, 4, -42, 25, 31, -1, -8, -29, -6, 17,
+ -19, 2, -10, -6, 38, 22, -42, -19, -6, -11,
+ }, {
+ 3, 7, -6, 20, 25, 77, 32, -29, -31, -30,
+ -4, -2, -14, 29, 16, 40, -26, 0, 3, -12,
+ -13, -10, -36, 9, 15, 8, -24, 6, -7, 22,
+ -40, 17, 8, 9, 31, 18, -66, -22, -11, -19,
+ }, {
+ 32, -6, -17, -31, 19, 65, 33, -41, -16, 1,
+ 0, 29, 6, 4, -13, 17, -9, 1, -8, 14,
+ 35, 3, -19, 11, 4, 0, -1, -21, 23, 30,
+ -3, 5, -20, -44, 48, 46, -19, -3, -20, 3,
+ }, {
+ -36, 13, 5, 7, 40, 51, 28, -36, -52, -27,
+ -18, 36, -2, 22, 0, 33, -21, -2, 3, 13,
+ 26, -11, -14, -4, -10, 10, -18, 14, 22, 36,
+ -24, 21, -1, -28, 40, 42, -42, -5, -25, -5,
+ }, {
+ 27, -1, -20, -17, 24, 38, 35, -26, 1, 4,
+ 35, -32, -21, -3, 2, 35, -8, -29, -24, -44,
+ 12, 24, -34, 18, 8, -7, -21, -55, -5, 21,
+ -2, 23, -11, -28, 13, -1, -22, -33, 21, 10,
+ }, {
+ -41, 18, 2, 21, 45, 24, 30, -21, -33, -24,
+ 17, -24, -29, 15, 16, 51, -21, -33, -13, -45,
+ 3, 8, -28, 2, -7, 2, -37, -19, -7, 27,
+ -22, 39, 7, -12, 5, -5, -45, -35, 15, 1,
+ }, {
+ -12, 4, -8, -29, 39, 12, 30, -33, -19, 8,
+ 21, 6, -8, -9, -13, 28, -4, -31, -24, -18,
+ 52, 23, -12, 4, -18, -5, -14, -47, 24, 34,
+ 14, 27, -22, -66, 22, 22, 1, -16, 6, 24,
+ }, {
+ -81, 25, 14, 8, 61, 0, 25, -28, -54, -20,
+ 3, 14, -17, 8, 0, 44, -16, -35, -13, -18,
+ 43, 7, -6, -11, -33, 4, -30, -11, 22, 40,
+ -6, 43, -3, -50, 14, 18, -22, -18, 1, 16,
+ }, {
+ 77, -2, -11, 1, -7, 47, 52, -5, 29, 33,
+ 1, -28, 0, -15, 28, 26, 2, 30, 0, 2,
+ -22, 4, -33, -3, 36, -21, 3, -15, -2, 5,
+ -4, 4, 6, 9, 37, 31, -5, -32, -20, -30,
+ }, {
+ 8, 17, 10, 40, 13, 34, 47, 0, -5, 4,
+ -16, -21, -8, 2, 42, 43, -10, 26, 10, 2,
+ -31, -11, -27, -19, 21, -10, -12, 20, -3, 11,
+ -25, 20, 25, 25, 29, 28, -28, -34, -25, -38,
+ }, {
+ 37, 3, 0, -10, 7, 22, 48, -12, 8, 36,
+ -12, 9, 12, -22, 12, 19, 6, 28, 0, 29,
+ 18, 3, -11, -17, 10, -18, 10, -7, 27, 18,
+ 11, 7, -3, -28, 47, 55, 18, -15, -34, -16,
+ }, {
+ -31, 24, 23, 27, 29, 9, 43, -8, -26, 7,
+ -30, 17, 4, -3, 26, 35, -5, 24, 10, 28,
+ 9, -12, -5, -33, -5, -8, -5, 29, 26, 24,
+ -9, 23, 14, -12, 39, 52, -5, -18, -39, -24,
+ }, {
+ 32, 8, -3, 2, 13, -4, 50, 1, 27, 39,
+ 23, -51, -15, -30, 27, 37, 7, -1, -17, -29,
+ -5, 23, -25, -10, 14, -26, -8, -41, -1, 9,
+ 13, 26, 5, -12, 12, 7, 14, -45, 6, -9,
+ }, {
+ -36, 29, 19, 41, 34, -18, 45, 6, -8, 10,
+ 5, -43, -23, -11, 42, 53, -5, -5, -6, -30,
+ -14, 8, -20, -26, -1, -16, -25, -4, -3, 15,
+ -7, 41, 23, 3, 4, 3, -8, -48, 1, -17,
+ }, {
+ -7, 15, 9, -9, 28, -29, 45, -5, 6, 43,
+ 9, -12, -2, -36, 12, 30, 11, -3, -17, -3,
+ 34, 22, -3, -24, -12, -24, -2, -32, 28, 22,
+ 29, 29, -5, -50, 21, 31, 38, -29, -7, 5,
+ }, {
+ -76, 35, 31, 28, 49, -43, 40, 0, -29, 14,
+ -8, -5, -10, -18, 26, 46, 0, -7, -6, -3,
+ 25, 7, 2, -40, -28, -14, -18, 3, 27, 28,
+ 8, 45, 13, -34, 13, 27, 15, -31, -12, -3,
+ }, {
+ 74, -17, 0, -31, -18, 73, -5, 0, 3, -5,
+ 25, 12, -3, -1, -22, 3, -9, 33, -12, -24,
+ 6, 2, -33, 9, 21, 5, 20, -27, -19, -7,
+ -34, -37, -34, 22, 44, 0, -41, -29, -17, -21,
+ }, {
+ 5, 3, 21, 7, 2, 60, -10, 5, -32, -34,
+ 7, 20, -11, 16, -8, 20, -21, 29, -1, -24,
+ -2, -13, -27, -6, 5, 15, 3, 8, -21, -1,
+ -55, -21, -15, 38, 37, -3, -65, -32, -23, -30,
+ }, {
+ 35, -10, 11, -44, -3, 48, -10, -6, -17, -2,
+ 11, 51, 8, -8, -38, -3, -4, 31, -12, 2,
+ 46, 1, -10, -4, -5, 7, 26, -19, 10, 5,
+ -18, -34, -45, -15, 54, 24, -18, -13, -31, -7,
+ }, {
+ -33, 10, 34, -5, 17, 35, -15, -1, -53, -30,
+ -6, 59, 0, 10, -24, 13, -17, 27, -1, 1,
+ 37, -13, -4, -20, -20, 18, 10, 16, 8, 11,
+ -39, -18, -26, 0, 46, 20, -41, -15, -37, -15,
+ }, {
+ 29, -5, 7, -30, 1, 21, -7, 7, 0, 0,
+ 47, -9, -18, -15, -22, 14, -4, 0, -28, -57,
+ 23, 21, -25, 2, -1, 0, 7, -53, -19, -3,
+ -17, -15, -36, 0, 19, -24, -21, -43, 9, 0,
+ }, {
+ -39, 14, 30, 8, 22, 8, -12, 12, -34, -27,
+ 29, -2, -26, 2, -8, 31, -16, -3, -17, -57,
+ 14, 6, -19, -13, -16, 10, -8, -17, -20, 2,
+ -38, 0, -17, 16, 11, -27, -44, -45, 4, -8,
+ }, {
+ -9, 1, 20, -43, 17, -3, -12, 0, -20, 4,
+ 33, 29, -6, -22, -38, 7, 0, -1, -29, -30,
+ 63, 21, -3, -11, -27, 1, 14, -45, 10, 9,
+ -1, -12, -47, -37, 28, 0, 2, -26, -4, 13,
+ }, {
+ -78, 21, 43, -4, 38, -17, -17, 5, -55, -24,
+ 15, 36, -14, -4, -24, 24, -12, -5, -17, -31,
+ 54, 5, 2, -27, -43, 12, -2, -9, 9, 15,
+ -22, 3, -28, -21, 20, -3, -20, -28, -9, 5,
+ }, {
+ 80, -6, 16, -11, -30, 30, 9, 28, 28, 29,
+ 13, -6, 2, -28, 3, 5, 7, 60, -5, -9,
+ -11, 1, -24, -19, 27, -13, 32, -13, -15, -19,
+ -19, -35, -17, 39, 43, 9, -4, -42, -32, -41,
+ }, {
+ 11, 14, 39, 27, -9, 17, 4, 33, -6, 0,
+ -4, 1, -5, -10, 17, 22, -5, 57, 5, -9,
+ -20, -13, -18, -35, 11, -3, 16, 22, -17, -13,
+ -40, -19, 1, 55, 35, 5, -27, -44, -37, -49,
+ }, {
+ 40, 0, 28, -24, -14, 5, 4, 21, 7, 33,
+ 0, 32, 15, -35, -12, -1, 11, 58, -5, 16,
+ 28, 0, -1, -33, 0, -11, 39, -5, 14, -6,
+ -3, -31, -28, 1, 53, 33, 19, -25, -46, -26,
+ }, {
+ -28, 20, 51, 14, 6, -7, 0, 26, -27, 4,
+ -18, 40, 6, -16, 1, 15, 0, 55, 5, 16,
+ 19, -14, 3, -49, -14, -1, 22, 30, 12, 0,
+ -24, -15, -9, 17, 45, 29, -4, -28, -51, -35,
+ }, {
+ 34, 4, 25, -10, -9, -21, 7, 36, 26, 36,
+ 35, -28, -12, -42, 3, 16, 12, 28, -21, -42,
+ 5, 21, -16, -26, 4, -19, 19, -39, -15, -15,
+ -1, -13, -19, 17, 17, -14, 15, -55, -4, -19,
+ }, {
+ -34, 25, 48, 28, 11, -34, 2, 41, -9, 7,
+ 17, -21, -20, -24, 17, 33, 0, 24, -10, -42,
+ -3, 5, -10, -42, -11, -8, 3, -3, -16, -9,
+ -22, 2, 0, 33, 10, -18, -7, -58, -10, -28,
+ }, {
+ -4, 11, 37, -23, 5, -46, 2, 29, 5, 39,
+ 21, 9, 0, -49, -12, 9, 16, 26, -22, -15,
+ 45, 20, 5, -40, -22, -17, 26, -31, 14, -2,
+ 14, -10, -30, -20, 27, 9, 39, -39, -18, -5,
+ }, {
+ -73, 32, 60, 15, 26, -59, -2, 33, -30, 10,
+ 3, 17, -8, -30, 1, 26, 4, 22, -10, -16,
+ 36, 5, 11, -56, -37, -6, 10, 5, 13, 3,
+ -6, 5, -11, -4, 19, 5, 16, -41, -24, -13
+ }
+};
+
+const uint16_t ff_cb1_base[128]={
+ 19657, 18474, 18365, 17520, 21048, 18231, 18584, 16671,
+ 20363, 19069, 19409, 18430, 21844, 18753, 19613, 17411,
+ 20389, 21772, 20129, 21702, 20978, 20472, 19627, 19387,
+ 21477, 23134, 21841, 23919, 22089, 21519, 21134, 20852,
+ 19675, 17821, 19044, 17477, 19986, 16955, 18446, 16086,
+ 21138, 18899, 20952, 18929, 21452, 17833, 20104, 17159,
+ 19770, 20056, 20336, 20866, 19329, 18217, 18908, 18004,
+ 21556, 21948, 23079, 23889, 20922, 19544, 20984, 19781,
+ 19781, 20984, 19544, 20922, 23889, 23079, 21948, 21556,
+ 18004, 18908, 18217, 19329, 20866, 20336, 20056, 19770,
+ 17159, 20104, 17833, 21452, 18929, 20952, 18899, 21138,
+ 16086, 18446, 16955, 19986, 17477, 19044, 17821, 19675,
+ 20852, 21134, 21519, 22089, 23919, 21841, 23134, 21477,
+ 19387, 19627, 20472, 20978, 21702, 20129, 21772, 20389,
+ 17411, 19613, 18753, 21844, 18430, 19409, 19069, 20363,
+ 16671, 18584, 18231, 21048, 17520, 18365, 18474, 19657,
+};
+
+const uint16_t ff_cb2_base[128]={
+ 12174, 13380, 13879, 13832, 13170, 13227, 13204, 12053,
+ 12410, 13988, 14348, 14631, 13100, 13415, 13224, 12268,
+ 11982, 13825, 13499, 14210, 13877, 14788, 13811, 13109,
+ 11449, 13275, 12833, 13717, 12728, 13696, 12759, 12405,
+ 10230, 12185, 11628, 13161, 11762, 13458, 12312, 12818,
+ 10443, 12773, 12011, 14020, 11818, 13825, 12453, 13226,
+ 10446, 13162, 11881, 14300, 12859, 16288, 13490, 15053,
+ 10155, 12820, 11519, 13973, 12041, 15081, 12635, 14198,
+ 14198, 12635, 15081, 12041, 13973, 11519, 12820, 10155,
+ 15053, 13490, 16288, 12859, 14300, 11881, 13162, 10446,
+ 13226, 12453, 13825, 11818, 14020, 12011, 12773, 10443,
+ 12818, 12312, 13458, 11762, 13161, 11628, 12185, 10230,
+ 12405, 12759, 13696, 12728, 13717, 12833, 13275, 11449,
+ 13109, 13811, 14788, 13877, 14210, 13499, 13825, 11982,
+ 12268, 13224, 13415, 13100, 14631, 14348, 13988, 12410,
+ 12053, 13204, 13227, 13170, 13832, 13879, 13380, 12174,
+};
+
+const int16_t ff_energy_tab[32]={
+ 0, 16, 20, 25, 32, 41, 51, 65,
+ 81, 103, 129, 163, 205, 259, 326, 410,
+ 516, 650, 819, 1031, 1298, 1634, 2057, 2590,
+ 3261, 4105, 5168, 6507, 8192, 10313, 12983, 16345
+};
+
+static const int16_t lpc_refl_cb1[64]={
+ -4041, -4018, -3998, -3977, -3954, -3930, -3906, -3879,
+ -3852, -3825, -3795, -3764, -3731, -3699, -3666, -3631,
+ -3594, -3555, -3513, -3468, -3420, -3372, -3321, -3268,
+ -3212, -3153, -3090, -3021, -2944, -2863, -2772, -2676,
+ -2565, -2445, -2328, -2202, -2072, -1941, -1808, -1660,
+ -1508, -1348, -1185, -994, -798, -600, -374, -110,
+ 152, 447, 720, 982, 1229, 1456, 1682, 1916,
+ 2130, 2353, 2595, 2853, 3118, 3363, 3588, 3814
+};
+
+static const int16_t lpc_refl_cb2[32]={
+ -3091, -2386, -1871, -1425, -1021, -649, -316, -20,
+ 267, 544, 810, 1065, 1305, 1534, 1756, 1970,
+ 2171, 2359, 2536, 2700, 2854, 2996, 3133, 3263,
+ 3386, 3499, 3603, 3701, 3789, 3870, 3947, 4020
+};
+
+static const int16_t lpc_refl_cb3[32]={
+ -3525, -3295, -3081, -2890, -2696, -2511, -2328, -2149,
+ -1979, -1817, -1658, -1498, -1341, -1188, -1032, -876,
+ -721, -561, -394, -228, -54, 119, 296, 484,
+ 683, 895, 1123, 1373, 1651, 1965, 2360, 2854
+};
+
+static const int16_t lpc_refl_cb4[16]={
+ -1845, -1057, -522, -77, 301, 647, 975, 1285,
+ 1582, 1873, 2163, 2452, 2735, 3017, 3299, 3569
+};
+
+static const int16_t lpc_refl_cb5[16]={
+ -2691, -2187, -1788, -1435, -1118, -837, -571, -316,
+ -59, 201, 470, 759, 1077, 1457, 1908, 2495
+};
+
+static const int16_t lpc_refl_cb6[8]={
+ -1372, -474, 133, 632, 1100, 1571, 2075, 2672
+};
+
+static const int16_t lpc_refl_cb7[8]={
+ -2389, -1787, -1231, -717, -239, 234, 770, 1474
+};
+
+static const int16_t lpc_refl_cb8[8]={
+ -1569, -864, -296, 200, 670, 1151, 1709, 2385
+};
+
+static const int16_t lpc_refl_cb9[8]={
+ -2200, -1608, -1062, -569, -120, 338, 863, 1621
+};
+
+static const int16_t lpc_refl_cb10[4]={
+ -617, 190, 802, 1483
+};
+
+const int16_t * const ff_lpc_refl_cb[10]={
+ lpc_refl_cb1, lpc_refl_cb2, lpc_refl_cb3, lpc_refl_cb4, lpc_refl_cb5,
+ lpc_refl_cb6, lpc_refl_cb7, lpc_refl_cb8, lpc_refl_cb9, lpc_refl_cb10
+};
+
+static void add_wav(int16_t *dest, int n, int skip_first, int *m,
+ const int16_t *s1, const int8_t *s2, const int8_t *s3)
+{
+ int i;
+ int v[3];
+
+ v[0] = 0;
+ for (i=!skip_first; i<3; i++)
+ v[i] = (ff_gain_val_tab[n][i] * (unsigned)m[i]) >> ff_gain_exp_tab[n];
+
+ if (v[0]) {
+ for (i=0; i < BLOCKSIZE; i++)
+ dest[i] = (s1[i]*v[0] + s2[i]*v[1] + s3[i]*v[2]) >> 12;
+ } else {
+ for (i=0; i < BLOCKSIZE; i++)
+ dest[i] = ( s2[i]*v[1] + s3[i]*v[2]) >> 12;
+ }
+}
+
+/**
+ * Copy the last offset values of *source to *target. If those values are not
+ * enough to fill the target buffer, fill it with another copy of those values.
+ */
+void ff_copy_and_dup(int16_t *target, const int16_t *source, int offset)
+{
+ source += BUFFERSIZE - offset;
+
+ memcpy(target, source, FFMIN(BLOCKSIZE, offset)*sizeof(*target));
+ if (offset < BLOCKSIZE)
+ memcpy(target + offset, source, (BLOCKSIZE - offset)*sizeof(*target));
+}
+
+/**
+ * Evaluate the reflection coefficients from the filter coefficients.
+ *
+ * @return 1 if one of the reflection coefficients is greater than
+ * 4095, 0 if not.
+ */
+int ff_eval_refl(int *refl, const int16_t *coefs, AVCodecContext *avctx)
+{
+ int b, i, j;
+ int buffer1[LPC_ORDER];
+ int buffer2[LPC_ORDER];
+ int *bp1 = buffer1;
+ int *bp2 = buffer2;
+
+ for (i=0; i < LPC_ORDER; i++)
+ buffer2[i] = coefs[i];
+
+ refl[LPC_ORDER-1] = bp2[LPC_ORDER-1];
+
+ if ((unsigned) bp2[LPC_ORDER-1] + 0x1000 > 0x1fff) {
+ av_log(avctx, AV_LOG_ERROR, "Overflow. Broken sample?\n");
+ return 1;
+ }
+
+ for (i = LPC_ORDER-2; i >= 0; i--) {
+ b = 0x1000-((bp2[i+1] * bp2[i+1]) >> 12);
+
+ if (!b)
+ b = -2;
+
+ b = 0x1000000 / b;
+ for (j=0; j <= i; j++) {
+#if CONFIG_FTRAPV
+ int a = bp2[j] - ((refl[i+1] * bp2[i-j]) >> 12);
+ if((int)(a*(unsigned)b) != a*(int64_t)b)
+ return 1;
+#endif
+ bp1[j] = (int)((bp2[j] - ((refl[i+1] * bp2[i-j]) >> 12)) * (unsigned)b) >> 12;
+ }
+
+ if ((unsigned) bp1[i] + 0x1000 > 0x1fff)
+ return 1;
+
+ refl[i] = bp1[i];
+
+ FFSWAP(int *, bp1, bp2);
+ }
+ return 0;
+}
+
+/**
+ * Evaluate the LPC filter coefficients from the reflection coefficients.
+ * Does the inverse of the ff_eval_refl() function.
+ */
+void ff_eval_coefs(int *coefs, const int *refl)
+{
+ int buffer[LPC_ORDER];
+ int *b1 = buffer;
+ int *b2 = coefs;
+ int i, j;
+
+ for (i=0; i < LPC_ORDER; i++) {
+ b1[i] = refl[i] * 16;
+
+ for (j=0; j < i; j++)
+ b1[j] = ((refl[i] * b2[i-j-1]) >> 12) + b2[j];
+
+ FFSWAP(int *, b1, b2);
+ }
+
+ for (i=0; i < LPC_ORDER; i++)
+ coefs[i] >>= 4;
+}
+
+void ff_int_to_int16(int16_t *out, const int *inp)
+{
+ int i;
+
+ for (i = 0; i < LPC_ORDER; i++)
+ *out++ = *inp++;
+}
+
+/**
+ * Evaluate sqrt(x << 24). x must fit in 20 bits. This value is evaluated in an
+ * odd way to make the output identical to the binary decoder.
+ */
+int ff_t_sqrt(unsigned int x)
+{
+ int s = 2;
+ while (x > 0xfff) {
+ s++;
+ x >>= 2;
+ }
+
+ return ff_sqrt(x << 20) << s;
+}
+
+unsigned int ff_rms(const int *data)
+{
+ int i;
+ unsigned int res = 0x10000;
+ int b = LPC_ORDER;
+
+ for (i = 0; i < LPC_ORDER; i++) {
+ res = (((0x1000000 - data[i]*data[i]) >> 12) * res) >> 12;
+
+ if (res == 0)
+ return 0;
+
+ while (res <= 0x3fff) {
+ b++;
+ res <<= 2;
+ }
+ }
+
+ return ff_t_sqrt(res) >> b;
+}
+
+int ff_interp(RA144Context *ractx, int16_t *out, int a, int copyold, int energy)
+{
+ int work[LPC_ORDER];
+ int b = NBLOCKS - a;
+ int i;
+
+ // Interpolate block coefficients from the this frame's forth block and
+ // last frame's forth block.
+ for (i = 0; i < LPC_ORDER; i++)
+ out[i] = (a * ractx->lpc_coef[0][i] + b * ractx->lpc_coef[1][i])>> 2;
+
+ if (ff_eval_refl(work, out, ractx->avctx)) {
+ // The interpolated coefficients are unstable, copy either new or old
+ // coefficients.
+ ff_int_to_int16(out, ractx->lpc_coef[copyold]);
+ return ff_rescale_rms(ractx->lpc_refl_rms[copyold], energy);
+ } else {
+ return ff_rescale_rms(ff_rms(work), energy);
+ }
+}
+
+unsigned int ff_rescale_rms(unsigned int rms, unsigned int energy)
+{
+ return (rms * energy) >> 10;
+}
+
+/** inverse root mean square */
+int ff_irms(AudioDSPContext *adsp, const int16_t *data)
+{
+ unsigned int sum = adsp->scalarproduct_int16(data, data, BLOCKSIZE);
+
+ if (sum == 0)
+ return 0; /* OOPS - division by zero */
+
+ return 0x20000000 / (ff_t_sqrt(sum) >> 8);
+}
+
+void ff_subblock_synthesis(RA144Context *ractx, const int16_t *lpc_coefs,
+ int cba_idx, int cb1_idx, int cb2_idx,
+ int gval, int gain)
+{
+ int16_t *block;
+ int m[3];
+
+ if (cba_idx) {
+ cba_idx += BLOCKSIZE/2 - 1;
+ ff_copy_and_dup(ractx->buffer_a, ractx->adapt_cb, cba_idx);
+ m[0] = (ff_irms(&ractx->adsp, ractx->buffer_a) * (unsigned)gval) >> 12;
+ } else {
+ m[0] = 0;
+ }
+ m[1] = (ff_cb1_base[cb1_idx] * gval) >> 8;
+ m[2] = (ff_cb2_base[cb2_idx] * gval) >> 8;
+ memmove(ractx->adapt_cb, ractx->adapt_cb + BLOCKSIZE,
+ (BUFFERSIZE - BLOCKSIZE) * sizeof(*ractx->adapt_cb));
+
+ block = ractx->adapt_cb + BUFFERSIZE - BLOCKSIZE;
+
+ add_wav(block, gain, cba_idx, m, cba_idx? ractx->buffer_a: NULL,
+ ff_cb1_vects[cb1_idx], ff_cb2_vects[cb2_idx]);
+
+ memcpy(ractx->curr_sblock, ractx->curr_sblock + BLOCKSIZE,
+ LPC_ORDER*sizeof(*ractx->curr_sblock));
+
+ if (ff_celp_lp_synthesis_filter(ractx->curr_sblock + LPC_ORDER, lpc_coefs,
+ block, BLOCKSIZE, LPC_ORDER, 1, 0, 0xfff))
+ memset(ractx->curr_sblock, 0, (LPC_ORDER+BLOCKSIZE)*sizeof(*ractx->curr_sblock));
+}
diff --git a/ffmpeg-2-8-11/libavcodec/ra144.h b/ffmpeg-2-8-12/libavcodec/ra144.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ra144.h
rename to ffmpeg-2-8-12/libavcodec/ra144.h
diff --git a/ffmpeg-2-8-12/libavcodec/ra144dec.c b/ffmpeg-2-8-12/libavcodec/ra144dec.c
new file mode 100644
index 0000000..c716c32
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/ra144dec.c
@@ -0,0 +1,138 @@
+/*
+ * Real Audio 1.0 (14.4K)
+ *
+ * Copyright (c) 2008 Vitor Sessak
+ * Copyright (c) 2003 Nick Kurshev
+ * Based on public domain decoder at http://www.honeypot.net/audio
+ *
+ * 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 "avcodec.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "ra144.h"
+
+
+static av_cold int ra144_decode_init(AVCodecContext * avctx)
+{
+ RA144Context *ractx = avctx->priv_data;
+
+ ractx->avctx = avctx;
+ ff_audiodsp_init(&ractx->adsp);
+
+ ractx->lpc_coef[0] = ractx->lpc_tables[0];
+ ractx->lpc_coef[1] = ractx->lpc_tables[1];
+
+ avctx->channels = 1;
+ avctx->channel_layout = AV_CH_LAYOUT_MONO;
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ return 0;
+}
+
+static void do_output_subblock(RA144Context *ractx, const int16_t *lpc_coefs,
+ int gval, GetBitContext *gb)
+{
+ int cba_idx = get_bits(gb, 7); // index of the adaptive CB, 0 if none
+ int gain = get_bits(gb, 8);
+ int cb1_idx = get_bits(gb, 7);
+ int cb2_idx = get_bits(gb, 7);
+
+ ff_subblock_synthesis(ractx, lpc_coefs, cba_idx, cb1_idx, cb2_idx, gval,
+ gain);
+}
+
+/** Uncompress one block (20 bytes -> 160*2 bytes). */
+static int ra144_decode_frame(AVCodecContext * avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ AVFrame *frame = data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ static const uint8_t sizes[LPC_ORDER] = {6, 5, 5, 4, 4, 3, 3, 3, 3, 2};
+ unsigned int refl_rms[NBLOCKS]; // RMS of the reflection coefficients
+ int16_t block_coefs[NBLOCKS][LPC_ORDER]; // LPC coefficients of each sub-block
+ unsigned int lpc_refl[LPC_ORDER]; // LPC reflection coefficients of the frame
+ int i, j;
+ int ret;
+ int16_t *samples;
+ unsigned int energy;
+
+ RA144Context *ractx = avctx->priv_data;
+ GetBitContext gb;
+
+ if (buf_size < FRAME_SIZE) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Frame too small (%d bytes). Truncated file?\n", buf_size);
+ *got_frame_ptr = 0;
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* get output buffer */
+ frame->nb_samples = NBLOCKS * BLOCKSIZE;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+ samples = (int16_t *)frame->data[0];
+
+ init_get_bits8(&gb, buf, FRAME_SIZE);
+
+ for (i = 0; i < LPC_ORDER; i++)
+ lpc_refl[i] = ff_lpc_refl_cb[i][get_bits(&gb, sizes[i])];
+
+ ff_eval_coefs(ractx->lpc_coef[0], lpc_refl);
+ ractx->lpc_refl_rms[0] = ff_rms(lpc_refl);
+
+ energy = ff_energy_tab[get_bits(&gb, 5)];
+
+ refl_rms[0] = ff_interp(ractx, block_coefs[0], 1, 1, ractx->old_energy);
+ refl_rms[1] = ff_interp(ractx, block_coefs[1], 2,
+ energy <= ractx->old_energy,
+ ff_t_sqrt(energy*ractx->old_energy) >> 12);
+ refl_rms[2] = ff_interp(ractx, block_coefs[2], 3, 0, energy);
+ refl_rms[3] = ff_rescale_rms(ractx->lpc_refl_rms[0], energy);
+
+ ff_int_to_int16(block_coefs[3], ractx->lpc_coef[0]);
+
+ for (i=0; i < NBLOCKS; i++) {
+ do_output_subblock(ractx, block_coefs[i], refl_rms[i], &gb);
+
+ for (j=0; j < BLOCKSIZE; j++)
+ *samples++ = av_clip_int16(ractx->curr_sblock[j + 10] * (1 << 2));
+ }
+
+ ractx->old_energy = energy;
+ ractx->lpc_refl_rms[1] = ractx->lpc_refl_rms[0];
+
+ FFSWAP(unsigned int *, ractx->lpc_coef[0], ractx->lpc_coef[1]);
+
+ *got_frame_ptr = 1;
+
+ return FRAME_SIZE;
+}
+
+AVCodec ff_ra_144_decoder = {
+ .name = "real_144",
+ .long_name = NULL_IF_CONFIG_SMALL("RealAudio 1.0 (14.4K)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_RA_144,
+ .priv_data_size = sizeof(RA144Context),
+ .init = ra144_decode_init,
+ .decode = ra144_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/ra144enc.c b/ffmpeg-2-8-12/libavcodec/ra144enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ra144enc.c
rename to ffmpeg-2-8-12/libavcodec/ra144enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/ra288.c b/ffmpeg-2-8-12/libavcodec/ra288.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ra288.c
rename to ffmpeg-2-8-12/libavcodec/ra288.c
diff --git a/ffmpeg-2-8-11/libavcodec/ra288.h b/ffmpeg-2-8-12/libavcodec/ra288.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ra288.h
rename to ffmpeg-2-8-12/libavcodec/ra288.h
diff --git a/ffmpeg-2-8-11/libavcodec/ralf.c b/ffmpeg-2-8-12/libavcodec/ralf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ralf.c
rename to ffmpeg-2-8-12/libavcodec/ralf.c
diff --git a/ffmpeg-2-8-11/libavcodec/ralfdata.h b/ffmpeg-2-8-12/libavcodec/ralfdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ralfdata.h
rename to ffmpeg-2-8-12/libavcodec/ralfdata.h
diff --git a/ffmpeg-2-8-11/libavcodec/rangecoder.c b/ffmpeg-2-8-12/libavcodec/rangecoder.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rangecoder.c
rename to ffmpeg-2-8-12/libavcodec/rangecoder.c
diff --git a/ffmpeg-2-8-11/libavcodec/rangecoder.h b/ffmpeg-2-8-12/libavcodec/rangecoder.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rangecoder.h
rename to ffmpeg-2-8-12/libavcodec/rangecoder.h
diff --git a/ffmpeg-2-8-11/libavcodec/ratecontrol.c b/ffmpeg-2-8-12/libavcodec/ratecontrol.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ratecontrol.c
rename to ffmpeg-2-8-12/libavcodec/ratecontrol.c
diff --git a/ffmpeg-2-8-11/libavcodec/ratecontrol.h b/ffmpeg-2-8-12/libavcodec/ratecontrol.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ratecontrol.h
rename to ffmpeg-2-8-12/libavcodec/ratecontrol.h
diff --git a/ffmpeg-2-8-11/libavcodec/raw.c b/ffmpeg-2-8-12/libavcodec/raw.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/raw.c
rename to ffmpeg-2-8-12/libavcodec/raw.c
diff --git a/ffmpeg-2-8-11/libavcodec/raw.h b/ffmpeg-2-8-12/libavcodec/raw.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/raw.h
rename to ffmpeg-2-8-12/libavcodec/raw.h
diff --git a/ffmpeg-2-8-11/libavcodec/rawdec.c b/ffmpeg-2-8-12/libavcodec/rawdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rawdec.c
rename to ffmpeg-2-8-12/libavcodec/rawdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/rawenc.c b/ffmpeg-2-8-12/libavcodec/rawenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rawenc.c
rename to ffmpeg-2-8-12/libavcodec/rawenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/rdft.c b/ffmpeg-2-8-12/libavcodec/rdft.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rdft.c
rename to ffmpeg-2-8-12/libavcodec/rdft.c
diff --git a/ffmpeg-2-8-11/libavcodec/rdft.h b/ffmpeg-2-8-12/libavcodec/rdft.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rdft.h
rename to ffmpeg-2-8-12/libavcodec/rdft.h
diff --git a/ffmpeg-2-8-11/libavcodec/realtextdec.c b/ffmpeg-2-8-12/libavcodec/realtextdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/realtextdec.c
rename to ffmpeg-2-8-12/libavcodec/realtextdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/rectangle.h b/ffmpeg-2-8-12/libavcodec/rectangle.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rectangle.h
rename to ffmpeg-2-8-12/libavcodec/rectangle.h
diff --git a/ffmpeg-2-8-11/libavcodec/remove_extradata_bsf.c b/ffmpeg-2-8-12/libavcodec/remove_extradata_bsf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/remove_extradata_bsf.c
rename to ffmpeg-2-8-12/libavcodec/remove_extradata_bsf.c
diff --git a/ffmpeg-2-8-11/libavcodec/resample.c b/ffmpeg-2-8-12/libavcodec/resample.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/resample.c
rename to ffmpeg-2-8-12/libavcodec/resample.c
diff --git a/ffmpeg-2-8-11/libavcodec/resample2.c b/ffmpeg-2-8-12/libavcodec/resample2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/resample2.c
rename to ffmpeg-2-8-12/libavcodec/resample2.c
diff --git a/ffmpeg-2-8-11/libavcodec/reverse.c b/ffmpeg-2-8-12/libavcodec/reverse.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/reverse.c
rename to ffmpeg-2-8-12/libavcodec/reverse.c
diff --git a/ffmpeg-2-8-11/libavcodec/rl.c b/ffmpeg-2-8-12/libavcodec/rl.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rl.c
rename to ffmpeg-2-8-12/libavcodec/rl.c
diff --git a/ffmpeg-2-8-11/libavcodec/rl.h b/ffmpeg-2-8-12/libavcodec/rl.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rl.h
rename to ffmpeg-2-8-12/libavcodec/rl.h
diff --git a/ffmpeg-2-8-11/libavcodec/rl2.c b/ffmpeg-2-8-12/libavcodec/rl2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rl2.c
rename to ffmpeg-2-8-12/libavcodec/rl2.c
diff --git a/ffmpeg-2-8-11/libavcodec/rle.c b/ffmpeg-2-8-12/libavcodec/rle.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rle.c
rename to ffmpeg-2-8-12/libavcodec/rle.c
diff --git a/ffmpeg-2-8-11/libavcodec/rle.h b/ffmpeg-2-8-12/libavcodec/rle.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rle.h
rename to ffmpeg-2-8-12/libavcodec/rle.h
diff --git a/ffmpeg-2-8-11/libavcodec/rnd_avg.h b/ffmpeg-2-8-12/libavcodec/rnd_avg.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rnd_avg.h
rename to ffmpeg-2-8-12/libavcodec/rnd_avg.h
diff --git a/ffmpeg-2-8-11/libavcodec/roqaudioenc.c b/ffmpeg-2-8-12/libavcodec/roqaudioenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/roqaudioenc.c
rename to ffmpeg-2-8-12/libavcodec/roqaudioenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/roqvideo.c b/ffmpeg-2-8-12/libavcodec/roqvideo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/roqvideo.c
rename to ffmpeg-2-8-12/libavcodec/roqvideo.c
diff --git a/ffmpeg-2-8-11/libavcodec/roqvideo.h b/ffmpeg-2-8-12/libavcodec/roqvideo.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/roqvideo.h
rename to ffmpeg-2-8-12/libavcodec/roqvideo.h
diff --git a/ffmpeg-2-8-11/libavcodec/roqvideodec.c b/ffmpeg-2-8-12/libavcodec/roqvideodec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/roqvideodec.c
rename to ffmpeg-2-8-12/libavcodec/roqvideodec.c
diff --git a/ffmpeg-2-8-11/libavcodec/roqvideoenc.c b/ffmpeg-2-8-12/libavcodec/roqvideoenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/roqvideoenc.c
rename to ffmpeg-2-8-12/libavcodec/roqvideoenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/rpza.c b/ffmpeg-2-8-12/libavcodec/rpza.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rpza.c
rename to ffmpeg-2-8-12/libavcodec/rpza.c
diff --git a/ffmpeg-2-8-11/libavcodec/rtjpeg.c b/ffmpeg-2-8-12/libavcodec/rtjpeg.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rtjpeg.c
rename to ffmpeg-2-8-12/libavcodec/rtjpeg.c
diff --git a/ffmpeg-2-8-11/libavcodec/rtjpeg.h b/ffmpeg-2-8-12/libavcodec/rtjpeg.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rtjpeg.h
rename to ffmpeg-2-8-12/libavcodec/rtjpeg.h
diff --git a/ffmpeg-2-8-11/libavcodec/rv10.c b/ffmpeg-2-8-12/libavcodec/rv10.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv10.c
rename to ffmpeg-2-8-12/libavcodec/rv10.c
diff --git a/ffmpeg-2-8-11/libavcodec/rv10.h b/ffmpeg-2-8-12/libavcodec/rv10.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv10.h
rename to ffmpeg-2-8-12/libavcodec/rv10.h
diff --git a/ffmpeg-2-8-11/libavcodec/rv10enc.c b/ffmpeg-2-8-12/libavcodec/rv10enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv10enc.c
rename to ffmpeg-2-8-12/libavcodec/rv10enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/rv20enc.c b/ffmpeg-2-8-12/libavcodec/rv20enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv20enc.c
rename to ffmpeg-2-8-12/libavcodec/rv20enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/rv30.c b/ffmpeg-2-8-12/libavcodec/rv30.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv30.c
rename to ffmpeg-2-8-12/libavcodec/rv30.c
diff --git a/ffmpeg-2-8-11/libavcodec/rv30data.h b/ffmpeg-2-8-12/libavcodec/rv30data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv30data.h
rename to ffmpeg-2-8-12/libavcodec/rv30data.h
diff --git a/ffmpeg-2-8-11/libavcodec/rv30dsp.c b/ffmpeg-2-8-12/libavcodec/rv30dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv30dsp.c
rename to ffmpeg-2-8-12/libavcodec/rv30dsp.c
diff --git a/ffmpeg-2-8-12/libavcodec/rv34.c b/ffmpeg-2-8-12/libavcodec/rv34.c
new file mode 100644
index 0000000..bcdbf88
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/rv34.c
@@ -0,0 +1,1845 @@
+/*
+ * RV30/40 decoder common data
+ * Copyright (c) 2007 Mike Melanson, 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
+ */
+
+/**
+ * @file
+ * RV30/40 decoder common data
+ */
+
+#include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
+
+#include "avcodec.h"
+#include "error_resilience.h"
+#include "mpegutils.h"
+#include "mpegvideo.h"
+#include "golomb.h"
+#include "internal.h"
+#include "mathops.h"
+#include "mpeg_er.h"
+#include "qpeldsp.h"
+#include "rectangle.h"
+#include "thread.h"
+
+#include "rv34vlc.h"
+#include "rv34data.h"
+#include "rv34.h"
+
+static inline void ZERO8x2(void* dst, int stride)
+{
+ fill_rectangle(dst, 1, 2, stride, 0, 4);
+ fill_rectangle(((uint8_t*)(dst))+4, 1, 2, stride, 0, 4);
+}
+
+/** translation of RV30/40 macroblock types to lavc ones */
+static const int rv34_mb_type_to_lavc[12] = {
+ MB_TYPE_INTRA,
+ MB_TYPE_INTRA16x16 | MB_TYPE_SEPARATE_DC,
+ MB_TYPE_16x16 | MB_TYPE_L0,
+ MB_TYPE_8x8 | MB_TYPE_L0,
+ MB_TYPE_16x16 | MB_TYPE_L0,
+ MB_TYPE_16x16 | MB_TYPE_L1,
+ MB_TYPE_SKIP,
+ MB_TYPE_DIRECT2 | MB_TYPE_16x16,
+ MB_TYPE_16x8 | MB_TYPE_L0,
+ MB_TYPE_8x16 | MB_TYPE_L0,
+ MB_TYPE_16x16 | MB_TYPE_L0L1,
+ MB_TYPE_16x16 | MB_TYPE_L0 | MB_TYPE_SEPARATE_DC
+};
+
+
+static RV34VLC intra_vlcs[NUM_INTRA_TABLES], inter_vlcs[NUM_INTER_TABLES];
+
+static int rv34_decode_mv(RV34DecContext *r, int block_type);
+
+/**
+ * @name RV30/40 VLC generating functions
+ * @{
+ */
+
+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];
+
+/**
+ * Generate VLC from codeword lengths.
+ * @param bits codeword lengths (zeroes are accepted)
+ * @param size length of input data
+ * @param vlc output VLC
+ * @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)
+{
+ 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;
+
+ 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]]++;
+ }
+ }
+
+ codes[0] = 0;
+ for(i = 0; i < 16; i++)
+ codes[i+1] = (codes[i] + counts[i]) << 1;
+ for(i = 0; i < realsize; i++)
+ cw[i] = codes[bits2[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,
+ cw, 2, 2,
+ syms, 2, 2, INIT_VLC_USE_NEW_STATIC);
+}
+
+/**
+ * Initialize all tables.
+ */
+static av_cold void rv34_init_tables(void)
+{
+ int i, j, k;
+
+ 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);
+ 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);
+ }
+ }
+ 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_intra_coeff[i], COEFF_VLC_SIZE, &intra_vlcs[i].coefficient, NULL, 19*i + 18);
+ }
+
+ 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);
+ 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);
+ }
+ 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_inter_coeff[i], COEFF_VLC_SIZE, &inter_vlcs[i].coefficient, NULL, i*12 + 106);
+ }
+}
+
+/** @} */ // vlc group
+
+/**
+ * @name RV30/40 4x4 block decoding functions
+ * @{
+ */
+
+/**
+ * Decode coded block pattern.
+ */
+static int rv34_decode_cbp(GetBitContext *gb, RV34VLC *vlc, int table)
+{
+ int pattern, code, cbp=0;
+ int ones;
+ static const int cbp_masks[3] = {0x100000, 0x010000, 0x110000};
+ static const int shifts[4] = { 0, 2, 8, 10 };
+ const int *curshift = shifts;
+ int i, t, mask;
+
+ code = get_vlc2(gb, vlc->cbppattern[table].table, 9, 2);
+ pattern = code & 0xF;
+ code >>= 4;
+
+ ones = rv34_count_ones[pattern];
+
+ for(mask = 8; mask; mask >>= 1, curshift++){
+ if(pattern & mask)
+ cbp |= get_vlc2(gb, vlc->cbp[table][ones].table, vlc->cbp[table][ones].bits, 1) << curshift[0];
+ }
+
+ for(i = 0; i < 4; i++){
+ t = (modulo_three_table[code] >> (6 - 2*i)) & 3;
+ if(t == 1)
+ cbp |= cbp_masks[get_bits1(gb)] << i;
+ if(t == 2)
+ cbp |= cbp_masks[2] << i;
+ }
+ return cbp;
+}
+
+/**
+ * Get one coefficient value from the bitstream and store it.
+ */
+static inline void decode_coeff(int16_t *dst, int coef, int esc, GetBitContext *gb, VLC* vlc, int q)
+{
+ if(coef){
+ if(coef == esc){
+ coef = get_vlc2(gb, vlc->table, 9, 2);
+ if(coef > 23){
+ coef -= 23;
+ coef = 22 + ((1 << coef) | get_bits(gb, coef));
+ }
+ coef += esc;
+ }
+ if(get_bits1(gb))
+ coef = -coef;
+ *dst = (coef*q + 8) >> 4;
+ }
+}
+
+/**
+ * Decode 2x2 subblock of coefficients.
+ */
+static inline void decode_subblock(int16_t *dst, int code, const int is_block2, GetBitContext *gb, VLC *vlc, int q)
+{
+ int flags = modulo_three_table[code];
+
+ decode_coeff( dst+0*4+0, (flags >> 6) , 3, gb, vlc, q);
+ if(is_block2){
+ decode_coeff(dst+1*4+0, (flags >> 4) & 3, 2, gb, vlc, q);
+ decode_coeff(dst+0*4+1, (flags >> 2) & 3, 2, gb, vlc, q);
+ }else{
+ decode_coeff(dst+0*4+1, (flags >> 4) & 3, 2, gb, vlc, q);
+ decode_coeff(dst+1*4+0, (flags >> 2) & 3, 2, gb, vlc, q);
+ }
+ decode_coeff( dst+1*4+1, (flags >> 0) & 3, 2, gb, vlc, q);
+}
+
+/**
+ * Decode a single coefficient.
+ */
+static inline void decode_subblock1(int16_t *dst, int code, GetBitContext *gb, VLC *vlc, int q)
+{
+ int coeff = modulo_three_table[code] >> 6;
+ decode_coeff(dst, coeff, 3, gb, vlc, q);
+}
+
+static inline void decode_subblock3(int16_t *dst, int code, GetBitContext *gb, VLC *vlc,
+ int q_dc, int q_ac1, int q_ac2)
+{
+ int flags = modulo_three_table[code];
+
+ decode_coeff(dst+0*4+0, (flags >> 6) , 3, gb, vlc, q_dc);
+ decode_coeff(dst+0*4+1, (flags >> 4) & 3, 2, gb, vlc, q_ac1);
+ decode_coeff(dst+1*4+0, (flags >> 2) & 3, 2, gb, vlc, q_ac1);
+ decode_coeff(dst+1*4+1, (flags >> 0) & 3, 2, gb, vlc, q_ac2);
+}
+
+/**
+ * Decode coefficients for 4x4 block.
+ *
+ * This is done by filling 2x2 subblocks with decoded coefficients
+ * in this order (the same for subblocks and subblock coefficients):
+ * o--o
+ * /
+ * /
+ * o--o
+ */
+
+static int rv34_decode_block(int16_t *dst, GetBitContext *gb, RV34VLC *rvlc, int fc, int sc, int q_dc, int q_ac1, int q_ac2)
+{
+ int code, pattern, has_ac = 1;
+
+ code = get_vlc2(gb, rvlc->first_pattern[fc].table, 9, 2);
+
+ pattern = code & 0x7;
+
+ code >>= 3;
+
+ if (modulo_three_table[code] & 0x3F) {
+ decode_subblock3(dst, code, gb, &rvlc->coefficient, q_dc, q_ac1, q_ac2);
+ } else {
+ decode_subblock1(dst, code, gb, &rvlc->coefficient, q_dc);
+ if (!pattern)
+ return 0;
+ has_ac = 0;
+ }
+
+ if(pattern & 4){
+ code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
+ decode_subblock(dst + 4*0+2, code, 0, gb, &rvlc->coefficient, q_ac2);
+ }
+ if(pattern & 2){ // Looks like coefficients 1 and 2 are swapped for this block
+ code = get_vlc2(gb, rvlc->second_pattern[sc].table, 9, 2);
+ decode_subblock(dst + 4*2+0, code, 1, gb, &rvlc->coefficient, q_ac2);
+ }
+ if(pattern & 1){
+ code = get_vlc2(gb, rvlc->third_pattern[sc].table, 9, 2);
+ decode_subblock(dst + 4*2+2, code, 0, gb, &rvlc->coefficient, q_ac2);
+ }
+ return has_ac | pattern;
+}
+
+/**
+ * @name RV30/40 bitstream parsing
+ * @{
+ */
+
+/**
+ * Decode starting slice position.
+ * @todo Maybe replace with ff_h263_decode_mba() ?
+ */
+int ff_rv34_get_start_offset(GetBitContext *gb, int mb_size)
+{
+ int i;
+ for(i = 0; i < 5; i++)
+ if(rv34_mb_max_sizes[i] >= mb_size - 1)
+ break;
+ return rv34_mb_bits_sizes[i];
+}
+
+/**
+ * Select VLC set for decoding from current quantizer, modifier and frame type.
+ */
+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)]];
+}
+
+/**
+ * Decode intra macroblock header and return CBP in case of success, -1 otherwise.
+ */
+static int rv34_decode_intra_mb_header(RV34DecContext *r, int8_t *intra_types)
+{
+ MpegEncContext *s = &r->s;
+ GetBitContext *gb = &s->gb;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int t;
+
+ r->is16 = get_bits1(gb);
+ if(r->is16){
+ s->current_picture_ptr->mb_type[mb_pos] = MB_TYPE_INTRA16x16;
+ r->block_type = RV34_MB_TYPE_INTRA16x16;
+ t = get_bits(gb, 2);
+ fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
+ r->luma_vlc = 2;
+ }else{
+ if(!r->rv30){
+ if(!get_bits1(gb))
+ av_log(s->avctx, AV_LOG_ERROR, "Need DQUANT\n");
+ }
+ s->current_picture_ptr->mb_type[mb_pos] = MB_TYPE_INTRA;
+ r->block_type = RV34_MB_TYPE_INTRA;
+ if(r->decode_intra_types(r, gb, intra_types) < 0)
+ return -1;
+ r->luma_vlc = 1;
+ }
+
+ r->chroma_vlc = 0;
+ r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
+
+ return rv34_decode_cbp(gb, r->cur_vlcs, r->is16);
+}
+
+/**
+ * Decode inter macroblock header and return CBP in case of success, -1 otherwise.
+ */
+static int rv34_decode_inter_mb_header(RV34DecContext *r, int8_t *intra_types)
+{
+ MpegEncContext *s = &r->s;
+ GetBitContext *gb = &s->gb;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int i, t;
+
+ r->block_type = r->decode_mb_info(r);
+ if(r->block_type == -1)
+ return -1;
+ s->current_picture_ptr->mb_type[mb_pos] = rv34_mb_type_to_lavc[r->block_type];
+ r->mb_type[mb_pos] = r->block_type;
+ if(r->block_type == RV34_MB_SKIP){
+ if(s->pict_type == AV_PICTURE_TYPE_P)
+ r->mb_type[mb_pos] = RV34_MB_P_16x16;
+ if(s->pict_type == AV_PICTURE_TYPE_B)
+ r->mb_type[mb_pos] = RV34_MB_B_DIRECT;
+ }
+ r->is16 = !!IS_INTRA16x16(s->current_picture_ptr->mb_type[mb_pos]);
+ rv34_decode_mv(r, r->block_type);
+ if(r->block_type == RV34_MB_SKIP){
+ fill_rectangle(intra_types, 4, 4, r->intra_types_stride, 0, sizeof(intra_types[0]));
+ return 0;
+ }
+ r->chroma_vlc = 1;
+ r->luma_vlc = 0;
+
+ if(IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
+ if(r->is16){
+ t = get_bits(gb, 2);
+ fill_rectangle(intra_types, 4, 4, r->intra_types_stride, t, sizeof(intra_types[0]));
+ r->luma_vlc = 2;
+ }else{
+ if(r->decode_intra_types(r, gb, intra_types) < 0)
+ return -1;
+ r->luma_vlc = 1;
+ }
+ r->chroma_vlc = 0;
+ r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
+ }else{
+ for(i = 0; i < 16; i++)
+ intra_types[(i & 3) + (i>>2) * r->intra_types_stride] = 0;
+ r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
+ if(r->mb_type[mb_pos] == RV34_MB_P_MIX16x16){
+ r->is16 = 1;
+ r->chroma_vlc = 1;
+ r->luma_vlc = 2;
+ r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 0);
+ }
+ }
+
+ return rv34_decode_cbp(gb, r->cur_vlcs, r->is16);
+}
+
+/** @} */ //bitstream functions
+
+/**
+ * @name motion vector related code (prediction, reconstruction, motion compensation)
+ * @{
+ */
+
+/** macroblock partition width in 8x8 blocks */
+static const uint8_t part_sizes_w[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2 };
+
+/** macroblock partition height in 8x8 blocks */
+static const uint8_t part_sizes_h[RV34_MB_TYPES] = { 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2 };
+
+/** availability index for subblocks */
+static const uint8_t avail_indexes[4] = { 6, 7, 10, 11 };
+
+/**
+ * motion vector prediction
+ *
+ * Motion prediction performed for the block by using median prediction of
+ * motion vectors from the left, top and right top blocks but in corner cases
+ * some other vectors may be used instead.
+ */
+static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int dmv_no)
+{
+ MpegEncContext *s = &r->s;
+ int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
+ int A[2] = {0}, B[2], C[2];
+ int i, j;
+ int mx, my;
+ int* avail = r->avail_cache + avail_indexes[subblock_no];
+ int c_off = part_sizes_w[block_type];
+
+ mv_pos += (subblock_no & 1) + (subblock_no >> 1)*s->b8_stride;
+ if(subblock_no == 3)
+ c_off = -1;
+
+ if(avail[-1]){
+ A[0] = s->current_picture_ptr->motion_val[0][mv_pos-1][0];
+ A[1] = s->current_picture_ptr->motion_val[0][mv_pos-1][1];
+ }
+ if(avail[-4]){
+ B[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][0];
+ B[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][1];
+ }else{
+ B[0] = A[0];
+ B[1] = A[1];
+ }
+ if(!avail[c_off-4]){
+ if(avail[-4] && (avail[-1] || r->rv30)){
+ C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][0];
+ C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][1];
+ }else{
+ C[0] = A[0];
+ C[1] = A[1];
+ }
+ }else{
+ C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][0];
+ C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+c_off][1];
+ }
+ mx = mid_pred(A[0], B[0], C[0]);
+ my = mid_pred(A[1], B[1], C[1]);
+ mx += r->dmv[dmv_no][0];
+ my += r->dmv[dmv_no][1];
+ for(j = 0; j < part_sizes_h[block_type]; j++){
+ for(i = 0; i < part_sizes_w[block_type]; i++){
+ s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx;
+ s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my;
+ }
+ }
+}
+
+#define GET_PTS_DIFF(a, b) (((a) - (b) + 8192) & 0x1FFF)
+
+/**
+ * Calculate motion vector component that should be added for direct blocks.
+ */
+static int calc_add_mv(RV34DecContext *r, int dir, int val)
+{
+ int mul = dir ? -r->mv_weight2 : r->mv_weight1;
+
+ return (val * mul + 0x2000) >> 14;
+}
+
+/**
+ * Predict motion vector for B-frame macroblock.
+ */
+static inline void rv34_pred_b_vector(int A[2], int B[2], int C[2],
+ int A_avail, int B_avail, int C_avail,
+ int *mx, int *my)
+{
+ if(A_avail + B_avail + C_avail != 3){
+ *mx = A[0] + B[0] + C[0];
+ *my = A[1] + B[1] + C[1];
+ if(A_avail + B_avail + C_avail == 2){
+ *mx /= 2;
+ *my /= 2;
+ }
+ }else{
+ *mx = mid_pred(A[0], B[0], C[0]);
+ *my = mid_pred(A[1], B[1], C[1]);
+ }
+}
+
+/**
+ * motion vector prediction for B-frames
+ */
+static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir)
+{
+ MpegEncContext *s = &r->s;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
+ int A[2] = { 0 }, B[2] = { 0 }, C[2] = { 0 };
+ int has_A = 0, has_B = 0, has_C = 0;
+ int mx, my;
+ int i, j;
+ Picture *cur_pic = s->current_picture_ptr;
+ const int mask = dir ? MB_TYPE_L1 : MB_TYPE_L0;
+ int type = cur_pic->mb_type[mb_pos];
+
+ if((r->avail_cache[6-1] & type) & mask){
+ A[0] = cur_pic->motion_val[dir][mv_pos - 1][0];
+ A[1] = cur_pic->motion_val[dir][mv_pos - 1][1];
+ has_A = 1;
+ }
+ if((r->avail_cache[6-4] & type) & mask){
+ B[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][0];
+ B[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride][1];
+ has_B = 1;
+ }
+ if(r->avail_cache[6-4] && (r->avail_cache[6-2] & type) & mask){
+ C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][0];
+ C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride + 2][1];
+ has_C = 1;
+ }else if((s->mb_x+1) == s->mb_width && (r->avail_cache[6-5] & type) & mask){
+ C[0] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][0];
+ C[1] = cur_pic->motion_val[dir][mv_pos - s->b8_stride - 1][1];
+ has_C = 1;
+ }
+
+ rv34_pred_b_vector(A, B, C, has_A, has_B, has_C, &mx, &my);
+
+ mx += r->dmv[dir][0];
+ my += r->dmv[dir][1];
+
+ for(j = 0; j < 2; j++){
+ for(i = 0; i < 2; i++){
+ cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][0] = mx;
+ cur_pic->motion_val[dir][mv_pos + i + j*s->b8_stride][1] = my;
+ }
+ }
+ if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD){
+ ZERO8x2(cur_pic->motion_val[!dir][mv_pos], s->b8_stride);
+ }
+}
+
+/**
+ * motion vector prediction - RV3 version
+ */
+static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir)
+{
+ MpegEncContext *s = &r->s;
+ int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
+ int A[2] = {0}, B[2], C[2];
+ int i, j, k;
+ int mx, my;
+ int* avail = r->avail_cache + avail_indexes[0];
+
+ if(avail[-1]){
+ A[0] = s->current_picture_ptr->motion_val[0][mv_pos - 1][0];
+ A[1] = s->current_picture_ptr->motion_val[0][mv_pos - 1][1];
+ }
+ if(avail[-4]){
+ B[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][0];
+ B[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride][1];
+ }else{
+ B[0] = A[0];
+ B[1] = A[1];
+ }
+ if(!avail[-4 + 2]){
+ if(avail[-4] && (avail[-1])){
+ C[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride - 1][0];
+ C[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride - 1][1];
+ }else{
+ C[0] = A[0];
+ C[1] = A[1];
+ }
+ }else{
+ C[0] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride + 2][0];
+ C[1] = s->current_picture_ptr->motion_val[0][mv_pos - s->b8_stride + 2][1];
+ }
+ mx = mid_pred(A[0], B[0], C[0]);
+ my = mid_pred(A[1], B[1], C[1]);
+ mx += r->dmv[0][0];
+ my += r->dmv[0][1];
+ for(j = 0; j < 2; j++){
+ for(i = 0; i < 2; i++){
+ for(k = 0; k < 2; k++){
+ s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][0] = mx;
+ s->current_picture_ptr->motion_val[k][mv_pos + i + j*s->b8_stride][1] = my;
+ }
+ }
+ }
+}
+
+static const int chroma_coeffs[3] = { 0, 3, 5 };
+
+/**
+ * generic motion compensation function
+ *
+ * @param r decoder context
+ * @param block_type type of the current block
+ * @param xoff horizontal offset from the start of the current block
+ * @param yoff vertical offset from the start of the current block
+ * @param mv_off offset to the motion vector information
+ * @param width width of the current partition in 8x8 blocks
+ * @param height height of the current partition in 8x8 blocks
+ * @param dir motion compensation direction (i.e. from the last or the next reference frame)
+ * @param thirdpel motion vectors are specified in 1/3 of pixel
+ * @param qpel_mc a set of functions used to perform luma motion compensation
+ * @param chroma_mc a set of functions used to perform chroma motion compensation
+ */
+static inline void rv34_mc(RV34DecContext *r, const int block_type,
+ const int xoff, const int yoff, int mv_off,
+ const int width, const int height, int dir,
+ const int thirdpel, int weighted,
+ qpel_mc_func (*qpel_mc)[16],
+ h264_chroma_mc_func (*chroma_mc))
+{
+ MpegEncContext *s = &r->s;
+ uint8_t *Y, *U, *V, *srcY, *srcU, *srcV;
+ int dxy, mx, my, umx, umy, lx, ly, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
+ int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride + mv_off;
+ int is16x16 = 1;
+ int emu = 0;
+
+ if(thirdpel){
+ int chroma_mx, chroma_my;
+ mx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) / 3 - (1 << 24);
+ my = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) / 3 - (1 << 24);
+ lx = (s->current_picture_ptr->motion_val[dir][mv_pos][0] + (3 << 24)) % 3;
+ ly = (s->current_picture_ptr->motion_val[dir][mv_pos][1] + (3 << 24)) % 3;
+ chroma_mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2;
+ chroma_my = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2;
+ umx = (chroma_mx + (3 << 24)) / 3 - (1 << 24);
+ umy = (chroma_my + (3 << 24)) / 3 - (1 << 24);
+ uvmx = chroma_coeffs[(chroma_mx + (3 << 24)) % 3];
+ uvmy = chroma_coeffs[(chroma_my + (3 << 24)) % 3];
+ }else{
+ int cx, cy;
+ mx = s->current_picture_ptr->motion_val[dir][mv_pos][0] >> 2;
+ my = s->current_picture_ptr->motion_val[dir][mv_pos][1] >> 2;
+ lx = s->current_picture_ptr->motion_val[dir][mv_pos][0] & 3;
+ ly = s->current_picture_ptr->motion_val[dir][mv_pos][1] & 3;
+ cx = s->current_picture_ptr->motion_val[dir][mv_pos][0] / 2;
+ cy = s->current_picture_ptr->motion_val[dir][mv_pos][1] / 2;
+ umx = cx >> 2;
+ umy = cy >> 2;
+ uvmx = (cx & 3) << 1;
+ uvmy = (cy & 3) << 1;
+ //due to some flaw RV40 uses the same MC compensation routine for H2V2 and H3V3
+ if(uvmx == 6 && uvmy == 6)
+ uvmx = uvmy = 4;
+ }
+
+ if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) {
+ /* wait for the referenced mb row to be finished */
+ int mb_row = s->mb_y + ((yoff + my + 5 + 8 * height) >> 4);
+ ThreadFrame *f = dir ? &s->next_picture_ptr->tf : &s->last_picture_ptr->tf;
+ ff_thread_await_progress(f, mb_row, 0);
+ }
+
+ dxy = ly*4 + lx;
+ srcY = dir ? s->next_picture_ptr->f->data[0] : s->last_picture_ptr->f->data[0];
+ srcU = dir ? s->next_picture_ptr->f->data[1] : s->last_picture_ptr->f->data[1];
+ srcV = dir ? s->next_picture_ptr->f->data[2] : s->last_picture_ptr->f->data[2];
+ src_x = s->mb_x * 16 + xoff + mx;
+ src_y = s->mb_y * 16 + yoff + my;
+ uvsrc_x = s->mb_x * 8 + (xoff >> 1) + umx;
+ uvsrc_y = s->mb_y * 8 + (yoff >> 1) + umy;
+ srcY += src_y * s->linesize + src_x;
+ srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
+ srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
+ if(s->h_edge_pos - (width << 3) < 6 || s->v_edge_pos - (height << 3) < 6 ||
+ (unsigned)(src_x - !!lx*2) > s->h_edge_pos - !!lx*2 - (width <<3) - 4 ||
+ (unsigned)(src_y - !!ly*2) > s->v_edge_pos - !!ly*2 - (height<<3) - 4) {
+ srcY -= 2 + 2*s->linesize;
+ s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, srcY,
+ s->linesize, s->linesize,
+ (width << 3) + 6, (height << 3) + 6,
+ src_x - 2, src_y - 2,
+ s->h_edge_pos, s->v_edge_pos);
+ srcY = s->sc.edge_emu_buffer + 2 + 2*s->linesize;
+ emu = 1;
+ }
+ if(!weighted){
+ Y = s->dest[0] + xoff + yoff *s->linesize;
+ U = s->dest[1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
+ V = s->dest[2] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
+ }else{
+ Y = r->tmp_b_block_y [dir] + xoff + yoff *s->linesize;
+ U = r->tmp_b_block_uv[dir*2] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
+ V = r->tmp_b_block_uv[dir*2+1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
+ }
+
+ if(block_type == RV34_MB_P_16x8){
+ qpel_mc[1][dxy](Y, srcY, s->linesize);
+ Y += 8;
+ srcY += 8;
+ }else if(block_type == RV34_MB_P_8x16){
+ qpel_mc[1][dxy](Y, srcY, s->linesize);
+ Y += 8 * s->linesize;
+ srcY += 8 * s->linesize;
+ }
+ is16x16 = (block_type != RV34_MB_P_8x8) && (block_type != RV34_MB_P_16x8) && (block_type != RV34_MB_P_8x16);
+ qpel_mc[!is16x16][dxy](Y, srcY, s->linesize);
+ if (emu) {
+ uint8_t *uvbuf = s->sc.edge_emu_buffer;
+
+ s->vdsp.emulated_edge_mc(uvbuf, srcU,
+ s->uvlinesize, s->uvlinesize,
+ (width << 2) + 1, (height << 2) + 1,
+ uvsrc_x, uvsrc_y,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ srcU = uvbuf;
+ uvbuf += 9*s->uvlinesize;
+
+ s->vdsp.emulated_edge_mc(uvbuf, srcV,
+ s->uvlinesize, s->uvlinesize,
+ (width << 2) + 1, (height << 2) + 1,
+ uvsrc_x, uvsrc_y,
+ s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+ srcV = uvbuf;
+ }
+ chroma_mc[2-width] (U, srcU, s->uvlinesize, height*4, uvmx, uvmy);
+ chroma_mc[2-width] (V, srcV, s->uvlinesize, height*4, uvmx, uvmy);
+}
+
+static void rv34_mc_1mv(RV34DecContext *r, const int block_type,
+ const int xoff, const int yoff, int mv_off,
+ const int width, const int height, int dir)
+{
+ rv34_mc(r, block_type, xoff, yoff, mv_off, width, height, dir, r->rv30, 0,
+ r->rdsp.put_pixels_tab,
+ r->rdsp.put_chroma_pixels_tab);
+}
+
+static void rv4_weight(RV34DecContext *r)
+{
+ r->rdsp.rv40_weight_pixels_tab[r->scaled_weight][0](r->s.dest[0],
+ r->tmp_b_block_y[0],
+ r->tmp_b_block_y[1],
+ r->weight1,
+ r->weight2,
+ r->s.linesize);
+ r->rdsp.rv40_weight_pixels_tab[r->scaled_weight][1](r->s.dest[1],
+ r->tmp_b_block_uv[0],
+ r->tmp_b_block_uv[2],
+ r->weight1,
+ r->weight2,
+ r->s.uvlinesize);
+ r->rdsp.rv40_weight_pixels_tab[r->scaled_weight][1](r->s.dest[2],
+ r->tmp_b_block_uv[1],
+ r->tmp_b_block_uv[3],
+ r->weight1,
+ r->weight2,
+ r->s.uvlinesize);
+}
+
+static void rv34_mc_2mv(RV34DecContext *r, const int block_type)
+{
+ int weighted = !r->rv30 && block_type != RV34_MB_B_BIDIR && r->weight1 != 8192;
+
+ rv34_mc(r, block_type, 0, 0, 0, 2, 2, 0, r->rv30, weighted,
+ r->rdsp.put_pixels_tab,
+ r->rdsp.put_chroma_pixels_tab);
+ if(!weighted){
+ rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, 0,
+ r->rdsp.avg_pixels_tab,
+ r->rdsp.avg_chroma_pixels_tab);
+ }else{
+ rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, 1,
+ r->rdsp.put_pixels_tab,
+ r->rdsp.put_chroma_pixels_tab);
+ rv4_weight(r);
+ }
+}
+
+static void rv34_mc_2mv_skip(RV34DecContext *r)
+{
+ int i, j;
+ int weighted = !r->rv30 && r->weight1 != 8192;
+
+ for(j = 0; j < 2; j++)
+ for(i = 0; i < 2; i++){
+ rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 0, r->rv30,
+ weighted,
+ r->rdsp.put_pixels_tab,
+ r->rdsp.put_chroma_pixels_tab);
+ rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 1, r->rv30,
+ weighted,
+ weighted ? r->rdsp.put_pixels_tab : r->rdsp.avg_pixels_tab,
+ weighted ? r->rdsp.put_chroma_pixels_tab : r->rdsp.avg_chroma_pixels_tab);
+ }
+ if(weighted)
+ rv4_weight(r);
+}
+
+/** number of motion vectors in each macroblock type */
+static const int num_mvs[RV34_MB_TYPES] = { 0, 0, 1, 4, 1, 1, 0, 0, 2, 2, 2, 1 };
+
+/**
+ * Decode motion vector differences
+ * and perform motion vector reconstruction and motion compensation.
+ */
+static int rv34_decode_mv(RV34DecContext *r, int block_type)
+{
+ MpegEncContext *s = &r->s;
+ GetBitContext *gb = &s->gb;
+ int i, j, k, l;
+ int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
+ int next_bt;
+
+ memset(r->dmv, 0, sizeof(r->dmv));
+ for(i = 0; i < num_mvs[block_type]; i++){
+ r->dmv[i][0] = svq3_get_se_golomb(gb);
+ r->dmv[i][1] = svq3_get_se_golomb(gb);
+ }
+ switch(block_type){
+ case RV34_MB_TYPE_INTRA:
+ case RV34_MB_TYPE_INTRA16x16:
+ ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+ return 0;
+ case RV34_MB_SKIP:
+ if(s->pict_type == AV_PICTURE_TYPE_P){
+ ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+ rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
+ break;
+ }
+ case RV34_MB_B_DIRECT:
+ //surprisingly, it uses motion scheme from next reference frame
+ /* wait for the current mb row to be finished */
+ if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
+ ff_thread_await_progress(&s->next_picture_ptr->tf, FFMAX(0, s->mb_y-1), 0);
+
+ next_bt = s->next_picture_ptr->mb_type[s->mb_x + s->mb_y * s->mb_stride];
+ if(IS_INTRA(next_bt) || IS_SKIP(next_bt)){
+ ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+ ZERO8x2(s->current_picture_ptr->motion_val[1][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+ }else
+ for(j = 0; j < 2; j++)
+ for(i = 0; i < 2; i++)
+ for(k = 0; k < 2; k++)
+ for(l = 0; l < 2; l++)
+ s->current_picture_ptr->motion_val[l][mv_pos + i + j*s->b8_stride][k] = calc_add_mv(r, l, s->next_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][k]);
+ if(!(IS_16X8(next_bt) || IS_8X16(next_bt) || IS_8X8(next_bt))) //we can use whole macroblock MC
+ rv34_mc_2mv(r, block_type);
+ else
+ rv34_mc_2mv_skip(r);
+ ZERO8x2(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], s->b8_stride);
+ break;
+ case RV34_MB_P_16x16:
+ case RV34_MB_P_MIX16x16:
+ rv34_pred_mv(r, block_type, 0, 0);
+ rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, 0);
+ break;
+ case RV34_MB_B_FORWARD:
+ case RV34_MB_B_BACKWARD:
+ r->dmv[1][0] = r->dmv[0][0];
+ r->dmv[1][1] = r->dmv[0][1];
+ if(r->rv30)
+ rv34_pred_mv_rv3(r, block_type, block_type == RV34_MB_B_BACKWARD);
+ else
+ rv34_pred_mv_b (r, block_type, block_type == RV34_MB_B_BACKWARD);
+ rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, block_type == RV34_MB_B_BACKWARD);
+ break;
+ case RV34_MB_P_16x8:
+ case RV34_MB_P_8x16:
+ rv34_pred_mv(r, block_type, 0, 0);
+ rv34_pred_mv(r, block_type, 1 + (block_type == RV34_MB_P_16x8), 1);
+ if(block_type == RV34_MB_P_16x8){
+ rv34_mc_1mv(r, block_type, 0, 0, 0, 2, 1, 0);
+ rv34_mc_1mv(r, block_type, 0, 8, s->b8_stride, 2, 1, 0);
+ }
+ if(block_type == RV34_MB_P_8x16){
+ rv34_mc_1mv(r, block_type, 0, 0, 0, 1, 2, 0);
+ rv34_mc_1mv(r, block_type, 8, 0, 1, 1, 2, 0);
+ }
+ break;
+ case RV34_MB_B_BIDIR:
+ rv34_pred_mv_b (r, block_type, 0);
+ rv34_pred_mv_b (r, block_type, 1);
+ rv34_mc_2mv (r, block_type);
+ break;
+ case RV34_MB_P_8x8:
+ for(i=0;i< 4;i++){
+ rv34_pred_mv(r, block_type, i, i);
+ rv34_mc_1mv (r, block_type, (i&1)<<3, (i&2)<<2, (i&1)+(i>>1)*s->b8_stride, 1, 1, 0);
+ }
+ break;
+ }
+
+ return 0;
+}
+/** @} */ // mv group
+
+/**
+ * @name Macroblock reconstruction functions
+ * @{
+ */
+/** mapping of RV30/40 intra prediction types to standard H.264 types */
+static const int ittrans[9] = {
+ DC_PRED, VERT_PRED, HOR_PRED, DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_LEFT_PRED,
+ VERT_RIGHT_PRED, VERT_LEFT_PRED, HOR_UP_PRED, HOR_DOWN_PRED,
+};
+
+/** mapping of RV30/40 intra 16x16 prediction types to standard H.264 types */
+static const int ittrans16[4] = {
+ DC_PRED8x8, VERT_PRED8x8, HOR_PRED8x8, PLANE_PRED8x8,
+};
+
+/**
+ * Perform 4x4 intra prediction.
+ */
+static void rv34_pred_4x4_block(RV34DecContext *r, uint8_t *dst, int stride, int itype, int up, int left, int down, int right)
+{
+ uint8_t *prev = dst - stride + 4;
+ uint32_t topleft;
+
+ if(!up && !left)
+ itype = DC_128_PRED;
+ else if(!up){
+ if(itype == VERT_PRED) itype = HOR_PRED;
+ if(itype == DC_PRED) itype = LEFT_DC_PRED;
+ }else if(!left){
+ if(itype == HOR_PRED) itype = VERT_PRED;
+ if(itype == DC_PRED) itype = TOP_DC_PRED;
+ if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN;
+ }
+ if(!down){
+ if(itype == DIAG_DOWN_LEFT_PRED) itype = DIAG_DOWN_LEFT_PRED_RV40_NODOWN;
+ if(itype == HOR_UP_PRED) itype = HOR_UP_PRED_RV40_NODOWN;
+ if(itype == VERT_LEFT_PRED) itype = VERT_LEFT_PRED_RV40_NODOWN;
+ }
+ if(!right && up){
+ topleft = dst[-stride + 3] * 0x01010101u;
+ prev = (uint8_t*)&topleft;
+ }
+ r->h.pred4x4[itype](dst, prev, stride);
+}
+
+static inline int adjust_pred16(int itype, int up, int left)
+{
+ if(!up && !left)
+ itype = DC_128_PRED8x8;
+ else if(!up){
+ if(itype == PLANE_PRED8x8)itype = HOR_PRED8x8;
+ if(itype == VERT_PRED8x8) itype = HOR_PRED8x8;
+ if(itype == DC_PRED8x8) itype = LEFT_DC_PRED8x8;
+ }else if(!left){
+ if(itype == PLANE_PRED8x8)itype = VERT_PRED8x8;
+ if(itype == HOR_PRED8x8) itype = VERT_PRED8x8;
+ if(itype == DC_PRED8x8) itype = TOP_DC_PRED8x8;
+ }
+ return itype;
+}
+
+static inline void rv34_process_block(RV34DecContext *r,
+ uint8_t *pdst, int stride,
+ int fc, int sc, int q_dc, int q_ac)
+{
+ MpegEncContext *s = &r->s;
+ int16_t *ptr = s->block[0];
+ int has_ac = rv34_decode_block(ptr, &s->gb, r->cur_vlcs,
+ fc, sc, q_dc, q_ac, q_ac);
+ if(has_ac){
+ r->rdsp.rv34_idct_add(pdst, stride, ptr);
+ }else{
+ r->rdsp.rv34_idct_dc_add(pdst, stride, ptr[0]);
+ ptr[0] = 0;
+ }
+}
+
+static void rv34_output_i16x16(RV34DecContext *r, int8_t *intra_types, int cbp)
+{
+ LOCAL_ALIGNED_16(int16_t, block16, [16]);
+ MpegEncContext *s = &r->s;
+ GetBitContext *gb = &s->gb;
+ int q_dc = rv34_qscale_tab[ r->luma_dc_quant_i[s->qscale] ],
+ q_ac = rv34_qscale_tab[s->qscale];
+ uint8_t *dst = s->dest[0];
+ int16_t *ptr = s->block[0];
+ int i, j, itype, has_ac;
+
+ memset(block16, 0, 16 * sizeof(*block16));
+
+ has_ac = rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0, q_dc, q_dc, q_ac);
+ if(has_ac)
+ r->rdsp.rv34_inv_transform(block16);
+ else
+ r->rdsp.rv34_inv_transform_dc(block16);
+
+ itype = ittrans16[intra_types[0]];
+ itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
+ r->h.pred16x16[itype](dst, s->linesize);
+
+ for(j = 0; j < 4; j++){
+ for(i = 0; i < 4; i++, cbp >>= 1){
+ int dc = block16[i + j*4];
+
+ if(cbp & 1){
+ has_ac = rv34_decode_block(ptr, gb, r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac);
+ }else
+ has_ac = 0;
+
+ if(has_ac){
+ ptr[0] = dc;
+ r->rdsp.rv34_idct_add(dst+4*i, s->linesize, ptr);
+ }else
+ r->rdsp.rv34_idct_dc_add(dst+4*i, s->linesize, dc);
+ }
+
+ dst += 4*s->linesize;
+ }
+
+ itype = ittrans16[intra_types[0]];
+ if(itype == PLANE_PRED8x8) itype = DC_PRED8x8;
+ itype = adjust_pred16(itype, r->avail_cache[6-4], r->avail_cache[6-1]);
+
+ q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
+ q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];
+
+ for(j = 1; j < 3; j++){
+ dst = s->dest[j];
+ r->h.pred8x8[itype](dst, s->uvlinesize);
+ for(i = 0; i < 4; i++, cbp >>= 1){
+ uint8_t *pdst;
+ if(!(cbp & 1)) continue;
+ pdst = dst + (i&1)*4 + (i&2)*2*s->uvlinesize;
+
+ rv34_process_block(r, pdst, s->uvlinesize,
+ r->chroma_vlc, 1, q_dc, q_ac);
+ }
+ }
+}
+
+static void rv34_output_intra(RV34DecContext *r, int8_t *intra_types, int cbp)
+{
+ MpegEncContext *s = &r->s;
+ uint8_t *dst = s->dest[0];
+ int avail[6*8] = {0};
+ int i, j, k;
+ int idx, q_ac, q_dc;
+
+ // Set neighbour information.
+ if(r->avail_cache[1])
+ avail[0] = 1;
+ if(r->avail_cache[2])
+ avail[1] = avail[2] = 1;
+ if(r->avail_cache[3])
+ avail[3] = avail[4] = 1;
+ if(r->avail_cache[4])
+ avail[5] = 1;
+ if(r->avail_cache[5])
+ avail[8] = avail[16] = 1;
+ if(r->avail_cache[9])
+ avail[24] = avail[32] = 1;
+
+ q_ac = rv34_qscale_tab[s->qscale];
+ for(j = 0; j < 4; j++){
+ idx = 9 + j*8;
+ for(i = 0; i < 4; i++, cbp >>= 1, dst += 4, idx++){
+ rv34_pred_4x4_block(r, dst, s->linesize, ittrans[intra_types[i]], avail[idx-8], avail[idx-1], avail[idx+7], avail[idx-7]);
+ avail[idx] = 1;
+ if(!(cbp & 1)) continue;
+
+ rv34_process_block(r, dst, s->linesize,
+ r->luma_vlc, 0, q_ac, q_ac);
+ }
+ dst += s->linesize * 4 - 4*4;
+ intra_types += r->intra_types_stride;
+ }
+
+ intra_types -= r->intra_types_stride * 4;
+
+ q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
+ q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];
+
+ for(k = 0; k < 2; k++){
+ dst = s->dest[1+k];
+ fill_rectangle(r->avail_cache + 6, 2, 2, 4, 0, 4);
+
+ for(j = 0; j < 2; j++){
+ int* acache = r->avail_cache + 6 + j*4;
+ for(i = 0; i < 2; i++, cbp >>= 1, acache++){
+ int itype = ittrans[intra_types[i*2+j*2*r->intra_types_stride]];
+ rv34_pred_4x4_block(r, dst+4*i, s->uvlinesize, itype, acache[-4], acache[-1], !i && !j, acache[-3]);
+ acache[0] = 1;
+
+ if(!(cbp&1)) continue;
+
+ rv34_process_block(r, dst + 4*i, s->uvlinesize,
+ r->chroma_vlc, 1, q_dc, q_ac);
+ }
+
+ dst += 4*s->uvlinesize;
+ }
+ }
+}
+
+static int is_mv_diff_gt_3(int16_t (*motion_val)[2], int step)
+{
+ int d;
+ d = motion_val[0][0] - motion_val[-step][0];
+ if(d < -3 || d > 3)
+ return 1;
+ d = motion_val[0][1] - motion_val[-step][1];
+ if(d < -3 || d > 3)
+ return 1;
+ return 0;
+}
+
+static int rv34_set_deblock_coef(RV34DecContext *r)
+{
+ MpegEncContext *s = &r->s;
+ int hmvmask = 0, vmvmask = 0, i, j;
+ int midx = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
+ int16_t (*motion_val)[2] = &s->current_picture_ptr->motion_val[0][midx];
+ for(j = 0; j < 16; j += 8){
+ for(i = 0; i < 2; i++){
+ if(is_mv_diff_gt_3(motion_val + i, 1))
+ vmvmask |= 0x11 << (j + i*2);
+ if((j || s->mb_y) && is_mv_diff_gt_3(motion_val + i, s->b8_stride))
+ hmvmask |= 0x03 << (j + i*2);
+ }
+ motion_val += s->b8_stride;
+ }
+ if(s->first_slice_line)
+ hmvmask &= ~0x000F;
+ if(!s->mb_x)
+ vmvmask &= ~0x1111;
+ if(r->rv30){ //RV30 marks both subblocks on the edge for filtering
+ vmvmask |= (vmvmask & 0x4444) >> 1;
+ hmvmask |= (hmvmask & 0x0F00) >> 4;
+ if(s->mb_x)
+ r->deblock_coefs[s->mb_x - 1 + s->mb_y*s->mb_stride] |= (vmvmask & 0x1111) << 3;
+ if(!s->first_slice_line)
+ r->deblock_coefs[s->mb_x + (s->mb_y - 1)*s->mb_stride] |= (hmvmask & 0xF) << 12;
+ }
+ return hmvmask | vmvmask;
+}
+
+static int rv34_decode_inter_macroblock(RV34DecContext *r, int8_t *intra_types)
+{
+ MpegEncContext *s = &r->s;
+ GetBitContext *gb = &s->gb;
+ uint8_t *dst = s->dest[0];
+ int16_t *ptr = s->block[0];
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+ int cbp, cbp2;
+ int q_dc, q_ac, has_ac;
+ int i, j;
+ int dist;
+
+ // Calculate which neighbours are available. Maybe it's worth optimizing too.
+ memset(r->avail_cache, 0, sizeof(r->avail_cache));
+ fill_rectangle(r->avail_cache + 6, 2, 2, 4, 1, 4);
+ dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
+ if(s->mb_x && dist)
+ r->avail_cache[5] =
+ r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1];
+ if(dist >= s->mb_width)
+ r->avail_cache[2] =
+ r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride];
+ if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
+ r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1];
+ if(s->mb_x && dist > s->mb_width)
+ r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1];
+
+ s->qscale = r->si.quant;
+ cbp = cbp2 = rv34_decode_inter_mb_header(r, intra_types);
+ r->cbp_luma [mb_pos] = cbp;
+ r->cbp_chroma[mb_pos] = cbp >> 16;
+ r->deblock_coefs[mb_pos] = rv34_set_deblock_coef(r) | r->cbp_luma[mb_pos];
+ s->current_picture_ptr->qscale_table[mb_pos] = s->qscale;
+
+ if(cbp == -1)
+ return -1;
+
+ if (IS_INTRA(s->current_picture_ptr->mb_type[mb_pos])){
+ if(r->is16) rv34_output_i16x16(r, intra_types, cbp);
+ else rv34_output_intra(r, intra_types, cbp);
+ return 0;
+ }
+
+ if(r->is16){
+ // Only for RV34_MB_P_MIX16x16
+ LOCAL_ALIGNED_16(int16_t, block16, [16]);
+ memset(block16, 0, 16 * sizeof(*block16));
+ q_dc = rv34_qscale_tab[ r->luma_dc_quant_p[s->qscale] ];
+ q_ac = rv34_qscale_tab[s->qscale];
+ if (rv34_decode_block(block16, gb, r->cur_vlcs, 3, 0, q_dc, q_dc, q_ac))
+ r->rdsp.rv34_inv_transform(block16);
+ else
+ r->rdsp.rv34_inv_transform_dc(block16);
+
+ q_ac = rv34_qscale_tab[s->qscale];
+
+ for(j = 0; j < 4; j++){
+ for(i = 0; i < 4; i++, cbp >>= 1){
+ int dc = block16[i + j*4];
+
+ if(cbp & 1){
+ has_ac = rv34_decode_block(ptr, gb, r->cur_vlcs, r->luma_vlc, 0, q_ac, q_ac, q_ac);
+ }else
+ has_ac = 0;
+
+ if(has_ac){
+ ptr[0] = dc;
+ r->rdsp.rv34_idct_add(dst+4*i, s->linesize, ptr);
+ }else
+ r->rdsp.rv34_idct_dc_add(dst+4*i, s->linesize, dc);
+ }
+
+ dst += 4*s->linesize;
+ }
+
+ r->cur_vlcs = choose_vlc_set(r->si.quant, r->si.vlc_set, 1);
+ }else{
+ q_ac = rv34_qscale_tab[s->qscale];
+
+ for(j = 0; j < 4; j++){
+ for(i = 0; i < 4; i++, cbp >>= 1){
+ if(!(cbp & 1)) continue;
+
+ rv34_process_block(r, dst + 4*i, s->linesize,
+ r->luma_vlc, 0, q_ac, q_ac);
+ }
+ dst += 4*s->linesize;
+ }
+ }
+
+ q_dc = rv34_qscale_tab[rv34_chroma_quant[1][s->qscale]];
+ q_ac = rv34_qscale_tab[rv34_chroma_quant[0][s->qscale]];
+
+ for(j = 1; j < 3; j++){
+ dst = s->dest[j];
+ for(i = 0; i < 4; i++, cbp >>= 1){
+ uint8_t *pdst;
+ if(!(cbp & 1)) continue;
+ pdst = dst + (i&1)*4 + (i&2)*2*s->uvlinesize;
+
+ rv34_process_block(r, pdst, s->uvlinesize,
+ r->chroma_vlc, 1, q_dc, q_ac);
+ }
+ }
+
+ return 0;
+}
+
+static int rv34_decode_intra_macroblock(RV34DecContext *r, int8_t *intra_types)
+{
+ MpegEncContext *s = &r->s;
+ int cbp, dist;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+
+ // Calculate which neighbours are available. Maybe it's worth optimizing too.
+ memset(r->avail_cache, 0, sizeof(r->avail_cache));
+ fill_rectangle(r->avail_cache + 6, 2, 2, 4, 1, 4);
+ dist = (s->mb_x - s->resync_mb_x) + (s->mb_y - s->resync_mb_y) * s->mb_width;
+ if(s->mb_x && dist)
+ r->avail_cache[5] =
+ r->avail_cache[9] = s->current_picture_ptr->mb_type[mb_pos - 1];
+ if(dist >= s->mb_width)
+ r->avail_cache[2] =
+ r->avail_cache[3] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride];
+ if(((s->mb_x+1) < s->mb_width) && dist >= s->mb_width - 1)
+ r->avail_cache[4] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride + 1];
+ if(s->mb_x && dist > s->mb_width)
+ r->avail_cache[1] = s->current_picture_ptr->mb_type[mb_pos - s->mb_stride - 1];
+
+ s->qscale = r->si.quant;
+ cbp = rv34_decode_intra_mb_header(r, intra_types);
+ r->cbp_luma [mb_pos] = cbp;
+ r->cbp_chroma[mb_pos] = cbp >> 16;
+ r->deblock_coefs[mb_pos] = 0xFFFF;
+ s->current_picture_ptr->qscale_table[mb_pos] = s->qscale;
+
+ if(cbp == -1)
+ return -1;
+
+ if(r->is16){
+ rv34_output_i16x16(r, intra_types, cbp);
+ return 0;
+ }
+
+ rv34_output_intra(r, intra_types, cbp);
+ return 0;
+}
+
+static int check_slice_end(RV34DecContext *r, MpegEncContext *s)
+{
+ int bits;
+ if(s->mb_y >= s->mb_height)
+ return 1;
+ if(!s->mb_num_left)
+ return 1;
+ if(r->s.mb_skip_run > 1)
+ return 0;
+ bits = get_bits_left(&s->gb);
+ if(bits <= 0 || (bits < 8 && !show_bits(&s->gb, bits)))
+ return 1;
+ return 0;
+}
+
+
+static void rv34_decoder_free(RV34DecContext *r)
+{
+ av_freep(&r->intra_types_hist);
+ r->intra_types = NULL;
+ av_freep(&r->tmp_b_block_base);
+ av_freep(&r->mb_type);
+ av_freep(&r->cbp_luma);
+ av_freep(&r->cbp_chroma);
+ av_freep(&r->deblock_coefs);
+}
+
+
+static int rv34_decoder_alloc(RV34DecContext *r)
+{
+ r->intra_types_stride = r->s.mb_width * 4 + 4;
+
+ r->cbp_chroma = av_mallocz(r->s.mb_stride * r->s.mb_height *
+ sizeof(*r->cbp_chroma));
+ r->cbp_luma = av_mallocz(r->s.mb_stride * r->s.mb_height *
+ sizeof(*r->cbp_luma));
+ r->deblock_coefs = av_mallocz(r->s.mb_stride * r->s.mb_height *
+ sizeof(*r->deblock_coefs));
+ r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 *
+ sizeof(*r->intra_types_hist));
+ r->mb_type = av_mallocz(r->s.mb_stride * r->s.mb_height *
+ sizeof(*r->mb_type));
+
+ if (!(r->cbp_chroma && r->cbp_luma && r->deblock_coefs &&
+ r->intra_types_hist && r->mb_type)) {
+ rv34_decoder_free(r);
+ return AVERROR(ENOMEM);
+ }
+
+ r->intra_types = r->intra_types_hist + r->intra_types_stride * 4;
+
+ return 0;
+}
+
+
+static int rv34_decoder_realloc(RV34DecContext *r)
+{
+ rv34_decoder_free(r);
+ return rv34_decoder_alloc(r);
+}
+
+
+static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int buf_size)
+{
+ MpegEncContext *s = &r->s;
+ GetBitContext *gb = &s->gb;
+ int mb_pos, slice_type;
+ int res;
+
+ init_get_bits(&r->s.gb, buf, buf_size*8);
+ res = r->parse_slice_header(r, gb, &r->si);
+ if(res < 0){
+ av_log(s->avctx, AV_LOG_ERROR, "Incorrect or unknown slice header\n");
+ return -1;
+ }
+
+ slice_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I;
+ if (slice_type != s->pict_type) {
+ av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->width != r->si.width || s->height != r->si.height) {
+ av_log(s->avctx, AV_LOG_ERROR, "Size mismatch\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ r->si.end = end;
+ s->qscale = r->si.quant;
+ s->mb_num_left = r->si.end - r->si.start;
+ r->s.mb_skip_run = 0;
+
+ mb_pos = s->mb_x + s->mb_y * s->mb_width;
+ if(r->si.start != mb_pos){
+ av_log(s->avctx, AV_LOG_ERROR, "Slice indicates MB offset %d, got %d\n", r->si.start, mb_pos);
+ s->mb_x = r->si.start % s->mb_width;
+ s->mb_y = r->si.start / s->mb_width;
+ }
+ memset(r->intra_types_hist, -1, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
+ s->first_slice_line = 1;
+ s->resync_mb_x = s->mb_x;
+ s->resync_mb_y = s->mb_y;
+
+ ff_init_block_index(s);
+ while(!check_slice_end(r, s)) {
+ ff_update_block_index(s);
+
+ if(r->si.type)
+ res = rv34_decode_inter_macroblock(r, r->intra_types + s->mb_x * 4 + 4);
+ else
+ res = rv34_decode_intra_macroblock(r, r->intra_types + s->mb_x * 4 + 4);
+ if(res < 0){
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_ERROR);
+ return -1;
+ }
+ if (++s->mb_x == s->mb_width) {
+ s->mb_x = 0;
+ s->mb_y++;
+ ff_init_block_index(s);
+
+ memmove(r->intra_types_hist, r->intra_types, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist));
+ memset(r->intra_types, -1, r->intra_types_stride * 4 * sizeof(*r->intra_types_hist));
+
+ if(r->loop_filter && s->mb_y >= 2)
+ r->loop_filter(r, s->mb_y - 2);
+
+ if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
+ ff_thread_report_progress(&s->current_picture_ptr->tf,
+ s->mb_y - 2, 0);
+
+ }
+ if(s->mb_x == s->resync_mb_x)
+ s->first_slice_line=0;
+ s->mb_num_left--;
+ }
+ ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);
+
+ return s->mb_y == s->mb_height;
+}
+
+/** @} */ // recons group end
+
+/**
+ * Initialize decoder.
+ */
+av_cold int ff_rv34_decode_init(AVCodecContext *avctx)
+{
+ 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;
+
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+ avctx->has_b_frames = 1;
+ s->low_delay = 0;
+
+ ff_mpv_idct_init(s);
+ if ((ret = ff_mpv_common_init(s)) < 0)
+ return ret;
+
+ ff_h264_pred_init(&r->h, AV_CODEC_ID_RV40, 8, 1);
+
+#if CONFIG_RV30_DECODER
+ if (avctx->codec_id == AV_CODEC_ID_RV30)
+ ff_rv30dsp_init(&r->rdsp);
+#endif
+#if CONFIG_RV40_DECODER
+ if (avctx->codec_id == AV_CODEC_ID_RV40)
+ ff_rv40dsp_init(&r->rdsp);
+#endif
+
+ if ((ret = rv34_decoder_alloc(r)) < 0) {
+ ff_mpv_common_end(&r->s);
+ return ret;
+ }
+
+ if(!intra_vlcs[0].cbppattern[0].bits)
+ rv34_init_tables();
+
+ avctx->internal->allocate_progress = 1;
+
+ return 0;
+}
+
+int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx)
+{
+ int err;
+ RV34DecContext *r = avctx->priv_data;
+
+ r->s.avctx = avctx;
+
+ if (avctx->internal->is_copy) {
+ r->tmp_b_block_base = NULL;
+ r->cbp_chroma = NULL;
+ r->cbp_luma = NULL;
+ r->deblock_coefs = NULL;
+ r->intra_types_hist = NULL;
+ r->mb_type = NULL;
+
+ ff_mpv_idct_init(&r->s);
+
+ if ((err = ff_mpv_common_init(&r->s)) < 0)
+ return err;
+ if ((err = rv34_decoder_alloc(r)) < 0) {
+ ff_mpv_common_end(&r->s);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
+{
+ RV34DecContext *r = dst->priv_data, *r1 = src->priv_data;
+ MpegEncContext * const s = &r->s, * const s1 = &r1->s;
+ int err;
+
+ if (dst == src || !s1->context_initialized)
+ return 0;
+
+ if (s->height != s1->height || s->width != s1->width) {
+ s->height = s1->height;
+ s->width = s1->width;
+ if ((err = ff_mpv_common_frame_size_change(s)) < 0)
+ return err;
+ if ((err = rv34_decoder_realloc(r)) < 0)
+ return err;
+ }
+
+ r->cur_pts = r1->cur_pts;
+ r->last_pts = r1->last_pts;
+ r->next_pts = r1->next_pts;
+
+ memset(&r->si, 0, sizeof(r->si));
+
+ // Do no call ff_mpeg_update_thread_context on a partially initialized
+ // decoder context.
+ if (!s1->linesize)
+ return 0;
+
+ return ff_mpeg_update_thread_context(dst, src);
+}
+
+static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n, int slice_count, int buf_size)
+{
+ if (n < slice_count) {
+ if(avctx->slice_count) return avctx->slice_offset[n];
+ else return AV_RL32(buf + n*8 - 4) == 1 ? AV_RL32(buf + n*8) : AV_RB32(buf + n*8);
+ } else
+ return buf_size;
+}
+
+static int finish_frame(AVCodecContext *avctx, AVFrame *pict)
+{
+ RV34DecContext *r = avctx->priv_data;
+ MpegEncContext *s = &r->s;
+ int got_picture = 0, ret;
+
+ ff_er_frame_end(&s->er);
+ ff_mpv_frame_end(s);
+ s->mb_num_left = 0;
+
+ if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))
+ ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);
+
+ if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {
+ if ((ret = av_frame_ref(pict, s->current_picture_ptr->f)) < 0)
+ return ret;
+ ff_print_debug_info(s, s->current_picture_ptr, pict);
+ ff_mpv_export_qp_table(s, pict, s->current_picture_ptr, FF_QSCALE_TYPE_MPEG1);
+ got_picture = 1;
+ } else if (s->last_picture_ptr) {
+ if ((ret = av_frame_ref(pict, s->last_picture_ptr->f)) < 0)
+ return ret;
+ ff_print_debug_info(s, s->last_picture_ptr, pict);
+ ff_mpv_export_qp_table(s, pict, s->last_picture_ptr, FF_QSCALE_TYPE_MPEG1);
+ got_picture = 1;
+ }
+
+ return got_picture;
+}
+
+static AVRational update_sar(int old_w, int old_h, AVRational sar, int new_w, int new_h)
+{
+ // attempt to keep aspect during typical resolution switches
+ if (!sar.num)
+ sar = (AVRational){1, 1};
+
+ sar = av_mul_q(sar, av_mul_q((AVRational){new_h, new_w}, (AVRational){old_w, old_h}));
+ return sar;
+}
+
+int ff_rv34_decode_frame(AVCodecContext *avctx,
+ void *data, int *got_picture_ptr,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ RV34DecContext *r = avctx->priv_data;
+ MpegEncContext *s = &r->s;
+ AVFrame *pict = data;
+ SliceInfo si;
+ int i, ret;
+ int slice_count;
+ const uint8_t *slices_hdr = NULL;
+ int last = 0;
+ int offset;
+
+ /* no supplementary picture */
+ if (buf_size == 0) {
+ /* special case for last picture */
+ if (s->low_delay==0 && s->next_picture_ptr) {
+ if ((ret = av_frame_ref(pict, s->next_picture_ptr->f)) < 0)
+ return ret;
+ s->next_picture_ptr = NULL;
+
+ *got_picture_ptr = 1;
+ }
+ return 0;
+ }
+
+ if(!avctx->slice_count){
+ slice_count = (*buf++) + 1;
+ slices_hdr = buf + 4;
+ buf += 8 * slice_count;
+ buf_size -= 1 + 8 * slice_count;
+ }else
+ slice_count = avctx->slice_count;
+
+ offset = get_slice_offset(avctx, slices_hdr, 0, slice_count, buf_size);
+ //parse first slice header to check whether this frame can be decoded
+ if(offset < 0 || offset > buf_size){
+ av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
+ return AVERROR_INVALIDDATA;
+ }
+ init_get_bits(&s->gb, buf+offset, (buf_size-offset)*8);
+ if(r->parse_slice_header(r, &r->s.gb, &si) < 0 || si.start){
+ av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if ((!s->last_picture_ptr || !s->last_picture_ptr->f->data[0]) &&
+ si.type == AV_PICTURE_TYPE_B) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid decoder state: B-frame without "
+ "reference data.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if( (avctx->skip_frame >= AVDISCARD_NONREF && si.type==AV_PICTURE_TYPE_B)
+ || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=AV_PICTURE_TYPE_I)
+ || avctx->skip_frame >= AVDISCARD_ALL)
+ return avpkt->size;
+
+ /* first slice */
+ if (si.start == 0) {
+ 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);
+ ff_mpv_frame_end(s);
+ }
+
+ if (s->width != si.width || s->height != si.height) {
+ int err;
+
+ av_log(s->avctx, AV_LOG_WARNING, "Changing dimensions to %dx%d\n",
+ si.width, si.height);
+
+ if (av_image_check_size(si.width, si.height, 0, s->avctx))
+ return AVERROR_INVALIDDATA;
+
+ s->avctx->sample_aspect_ratio = update_sar(
+ s->width, s->height, s->avctx->sample_aspect_ratio,
+ si.width, si.height);
+ s->width = si.width;
+ s->height = si.height;
+
+ err = ff_set_dimensions(s->avctx, s->width, s->height);
+ if (err < 0)
+ return err;
+
+ if ((err = ff_mpv_common_frame_size_change(s)) < 0)
+ return err;
+ if ((err = rv34_decoder_realloc(r)) < 0)
+ return err;
+ }
+ s->pict_type = si.type ? si.type : AV_PICTURE_TYPE_I;
+ if (ff_mpv_frame_start(s, s->avctx) < 0)
+ return -1;
+ ff_mpeg_er_frame_start(s);
+ if (!r->tmp_b_block_base) {
+ int i;
+
+ r->tmp_b_block_base = av_malloc(s->linesize * 48);
+ for (i = 0; i < 2; i++)
+ r->tmp_b_block_y[i] = r->tmp_b_block_base
+ + i * 16 * s->linesize;
+ for (i = 0; i < 4; i++)
+ r->tmp_b_block_uv[i] = r->tmp_b_block_base + 32 * s->linesize
+ + (i >> 1) * 8 * s->uvlinesize
+ + (i & 1) * 16;
+ }
+ r->cur_pts = si.pts;
+ if (s->pict_type != AV_PICTURE_TYPE_B) {
+ r->last_pts = r->next_pts;
+ r->next_pts = r->cur_pts;
+ } else {
+ int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts);
+ int dist0 = GET_PTS_DIFF(r->cur_pts, r->last_pts);
+ int dist1 = GET_PTS_DIFF(r->next_pts, r->cur_pts);
+
+ if(!refdist){
+ r->mv_weight1 = r->mv_weight2 = r->weight1 = r->weight2 = 8192;
+ r->scaled_weight = 0;
+ }else{
+ r->mv_weight1 = (dist0 << 14) / refdist;
+ r->mv_weight2 = (dist1 << 14) / refdist;
+ if((r->mv_weight1|r->mv_weight2) & 511){
+ r->weight1 = r->mv_weight1;
+ r->weight2 = r->mv_weight2;
+ r->scaled_weight = 0;
+ }else{
+ r->weight1 = r->mv_weight1 >> 9;
+ r->weight2 = r->mv_weight2 >> 9;
+ r->scaled_weight = 1;
+ }
+ }
+ }
+ s->mb_x = s->mb_y = 0;
+ ff_thread_finish_setup(s->avctx);
+ } 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 "
+ "multithreading mode (start MB is %d).\n", si.start);
+ return AVERROR_INVALIDDATA;
+ }
+
+ for(i = 0; i < slice_count; i++){
+ int offset = get_slice_offset(avctx, slices_hdr, i , slice_count, buf_size);
+ int offset1 = get_slice_offset(avctx, slices_hdr, i+1, slice_count, buf_size);
+ int size;
+
+ if(offset < 0 || offset > offset1 || offset1 > buf_size){
+ av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
+ break;
+ }
+ size = offset1 - offset;
+
+ r->si.end = s->mb_width * s->mb_height;
+ s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start;
+
+ if(i+1 < slice_count){
+ int offset2 = get_slice_offset(avctx, slices_hdr, i+2, slice_count, buf_size);
+ if (offset2 < offset1 || offset2 > buf_size) {
+ av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n");
+ break;
+ }
+ init_get_bits(&s->gb, buf+offset1, (buf_size-offset1)*8);
+ if(r->parse_slice_header(r, &r->s.gb, &si) < 0){
+ size = offset2 - offset;
+ }else
+ r->si.end = si.start;
+ }
+ av_assert0 (size >= 0 && size <= buf_size - offset);
+ last = rv34_decode_slice(r, r->si.end, buf + offset, size);
+ if(last)
+ break;
+ }
+
+ if (s->current_picture_ptr) {
+ if (last) {
+ if(r->loop_filter)
+ r->loop_filter(r, s->mb_height - 1);
+
+ ret = finish_frame(avctx, pict);
+ if (ret < 0)
+ return ret;
+ *got_picture_ptr = ret;
+ } else if (HAVE_THREADS &&
+ (s->avctx->active_thread_type & FF_THREAD_FRAME)) {
+ av_log(avctx, AV_LOG_INFO, "marking unfished frame as finished\n");
+ /* always mark the current frame as finished, frame-mt supports
+ * only complete frames */
+ ff_er_frame_end(&s->er);
+ ff_mpv_frame_end(s);
+ s->mb_num_left = 0;
+ ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ return avpkt->size;
+}
+
+av_cold int ff_rv34_decode_end(AVCodecContext *avctx)
+{
+ RV34DecContext *r = avctx->priv_data;
+
+ ff_mpv_common_end(&r->s);
+ rv34_decoder_free(r);
+
+ return 0;
+}
diff --git a/ffmpeg-2-8-11/libavcodec/rv34.h b/ffmpeg-2-8-12/libavcodec/rv34.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv34.h
rename to ffmpeg-2-8-12/libavcodec/rv34.h
diff --git a/ffmpeg-2-8-11/libavcodec/rv34_parser.c b/ffmpeg-2-8-12/libavcodec/rv34_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv34_parser.c
rename to ffmpeg-2-8-12/libavcodec/rv34_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/rv34data.h b/ffmpeg-2-8-12/libavcodec/rv34data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv34data.h
rename to ffmpeg-2-8-12/libavcodec/rv34data.h
diff --git a/ffmpeg-2-8-11/libavcodec/rv34dsp.c b/ffmpeg-2-8-12/libavcodec/rv34dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv34dsp.c
rename to ffmpeg-2-8-12/libavcodec/rv34dsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/rv34dsp.h b/ffmpeg-2-8-12/libavcodec/rv34dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv34dsp.h
rename to ffmpeg-2-8-12/libavcodec/rv34dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/rv34vlc.h b/ffmpeg-2-8-12/libavcodec/rv34vlc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv34vlc.h
rename to ffmpeg-2-8-12/libavcodec/rv34vlc.h
diff --git a/ffmpeg-2-8-12/libavcodec/rv40.c b/ffmpeg-2-8-12/libavcodec/rv40.c
new file mode 100644
index 0000000..e4c8400
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/rv40.c
@@ -0,0 +1,588 @@
+/*
+ * RV40 decoder
+ * Copyright (c) 2007 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
+ */
+
+/**
+ * @file
+ * RV40 decoder
+ */
+
+#include "libavutil/imgutils.h"
+
+#include "avcodec.h"
+#include "mpegutils.h"
+#include "mpegvideo.h"
+#include "golomb.h"
+
+#include "rv34.h"
+#include "rv40vlc2.h"
+#include "rv40data.h"
+
+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
+};
+
+/**
+ * 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];
+ 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);
+ 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);
+ }
+ 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(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);
+ }
+ 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);
+ }
+}
+
+/**
+ * Get stored dimension from bitstream.
+ *
+ * If the width/height is the standard one then it's coded as a 3-bit index.
+ * Otherwise it is coded as escaped 8-bit portions.
+ */
+static int get_dimension(GetBitContext *gb, const int *dim)
+{
+ int t = get_bits(gb, 3);
+ int val = dim[t];
+ if(val < 0)
+ val = dim[get_bits1(gb) - val];
+ if(!val){
+ do{
+ if (get_bits_left(gb) < 8)
+ return AVERROR_INVALIDDATA;
+ t = get_bits(gb, 8);
+ val += t << 2;
+ }while(t == 0xFF);
+ }
+ return val;
+}
+
+/**
+ * Get encoded picture size - usually this is called from rv40_parse_slice_header.
+ */
+static void rv40_parse_picture_size(GetBitContext *gb, int *w, int *h)
+{
+ *w = get_dimension(gb, rv40_standard_widths);
+ *h = get_dimension(gb, rv40_standard_heights);
+}
+
+static int rv40_parse_slice_header(RV34DecContext *r, GetBitContext *gb, SliceInfo *si)
+{
+ int mb_bits;
+ int w = r->s.width, h = r->s.height;
+ int mb_size;
+ int ret;
+
+ memset(si, 0, sizeof(SliceInfo));
+ if(get_bits1(gb))
+ return AVERROR_INVALIDDATA;
+ si->type = get_bits(gb, 2);
+ if(si->type == 1) si->type = 0;
+ si->quant = get_bits(gb, 5);
+ if(get_bits(gb, 2))
+ return AVERROR_INVALIDDATA;
+ si->vlc_set = get_bits(gb, 2);
+ skip_bits1(gb);
+ si->pts = get_bits(gb, 13);
+ if(!si->type || !get_bits1(gb))
+ rv40_parse_picture_size(gb, &w, &h);
+ if ((ret = av_image_check_size(w, h, 0, r->s.avctx)) < 0)
+ return ret;
+ si->width = w;
+ si->height = h;
+ mb_size = ((w + 15) >> 4) * ((h + 15) >> 4);
+ mb_bits = ff_rv34_get_start_offset(gb, mb_size);
+ si->start = get_bits(gb, mb_bits);
+
+ return 0;
+}
+
+/**
+ * Decode 4x4 intra types array.
+ */
+static int rv40_decode_intra_types(RV34DecContext *r, GetBitContext *gb, int8_t *dst)
+{
+ MpegEncContext *s = &r->s;
+ int i, j, k, v;
+ int A, B, C;
+ int pattern;
+ int8_t *ptr;
+
+ for(i = 0; i < 4; i++, dst += r->intra_types_stride){
+ if(!i && s->first_slice_line){
+ pattern = get_vlc2(gb, aic_top_vlc.table, AIC_TOP_BITS, 1);
+ dst[0] = (pattern >> 2) & 2;
+ dst[1] = (pattern >> 1) & 2;
+ dst[2] = pattern & 2;
+ dst[3] = (pattern << 1) & 2;
+ continue;
+ }
+ ptr = dst;
+ for(j = 0; j < 4; j++){
+ /* Coefficients are read using VLC chosen by the prediction pattern
+ * The first one (used for retrieving a pair of coefficients) is
+ * constructed from the top, top right and left coefficients
+ * The second one (used for retrieving only one coefficient) is
+ * top + 10 * left.
+ */
+ A = ptr[-r->intra_types_stride + 1]; // it won't be used for the last coefficient in a row
+ B = ptr[-r->intra_types_stride];
+ C = ptr[-1];
+ pattern = A + B * (1 << 4) + C * (1 << 8);
+ for(k = 0; k < MODE2_PATTERNS_NUM; k++)
+ 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;
+ j++;
+ }else{
+ if(B != -1 && C != -1)
+ v = get_vlc2(gb, aic_mode1_vlc[B + C*10].table, AIC_MODE1_BITS, 1);
+ else{ // tricky decoding
+ v = 0;
+ switch(C){
+ case -1: // code 0 -> 1, 1 -> 0
+ if(B < 2)
+ v = get_bits1(gb) ^ 1;
+ break;
+ case 0:
+ case 2: // code 0 -> 2, 1 -> 0
+ v = (get_bits1(gb) ^ 1) << 1;
+ break;
+ }
+ }
+ *ptr++ = v;
+ }
+ }
+ }
+ return 0;
+}
+
+/**
+ * Decode macroblock information.
+ */
+static int rv40_decode_mb_info(RV34DecContext *r)
+{
+ MpegEncContext *s = &r->s;
+ GetBitContext *gb = &s->gb;
+ int q, i;
+ int prev_type = 0;
+ int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+
+ if(!r->s.mb_skip_run) {
+ r->s.mb_skip_run = svq3_get_ue_golomb(gb) + 1;
+ if(r->s.mb_skip_run > (unsigned)s->mb_num)
+ return -1;
+ }
+
+ if(--r->s.mb_skip_run)
+ return RV34_MB_SKIP;
+
+ if(r->avail_cache[6-4]){
+ int blocks[RV34_MB_TYPES] = {0};
+ int count = 0;
+ if(r->avail_cache[6-1])
+ blocks[r->mb_type[mb_pos - 1]]++;
+ blocks[r->mb_type[mb_pos - s->mb_stride]]++;
+ if(r->avail_cache[6-2])
+ blocks[r->mb_type[mb_pos - s->mb_stride + 1]]++;
+ if(r->avail_cache[6-5])
+ blocks[r->mb_type[mb_pos - s->mb_stride - 1]]++;
+ for(i = 0; i < RV34_MB_TYPES; i++){
+ if(blocks[i] > count){
+ count = blocks[i];
+ prev_type = i;
+ if(count>1)
+ break;
+ }
+ }
+ } else if (r->avail_cache[6-1])
+ prev_type = r->mb_type[mb_pos - 1];
+
+ if(s->pict_type == AV_PICTURE_TYPE_P){
+ prev_type = block_num_to_ptype_vlc_num[prev_type];
+ q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1);
+ if(q < PBTYPE_ESCAPE)
+ return q;
+ q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1);
+ av_log(s->avctx, AV_LOG_ERROR, "Dquant for P-frame\n");
+ }else{
+ prev_type = block_num_to_btype_vlc_num[prev_type];
+ q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1);
+ if(q < PBTYPE_ESCAPE)
+ return q;
+ q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1);
+ av_log(s->avctx, AV_LOG_ERROR, "Dquant for B-frame\n");
+ }
+ return 0;
+}
+
+enum RV40BlockPos{
+ POS_CUR,
+ POS_TOP,
+ POS_LEFT,
+ POS_BOTTOM,
+};
+
+#define MASK_CUR 0x0001
+#define MASK_RIGHT 0x0008
+#define MASK_BOTTOM 0x0010
+#define MASK_TOP 0x1000
+#define MASK_Y_TOP_ROW 0x000F
+#define MASK_Y_LAST_ROW 0xF000
+#define MASK_Y_LEFT_COL 0x1111
+#define MASK_Y_RIGHT_COL 0x8888
+#define MASK_C_TOP_ROW 0x0003
+#define MASK_C_LAST_ROW 0x000C
+#define MASK_C_LEFT_COL 0x0005
+#define MASK_C_RIGHT_COL 0x000A
+
+static const int neighbour_offs_x[4] = { 0, 0, -1, 0 };
+static const int neighbour_offs_y[4] = { 0, -1, 0, 1 };
+
+static void rv40_adaptive_loop_filter(RV34DSPContext *rdsp,
+ uint8_t *src, int stride, int dmode,
+ int lim_q1, int lim_p1,
+ int alpha, int beta, int beta2,
+ int chroma, int edge, int dir)
+{
+ int filter_p1, filter_q1;
+ int strong;
+ int lims;
+
+ strong = rdsp->rv40_loop_filter_strength[dir](src, stride, beta, beta2,
+ edge, &filter_p1, &filter_q1);
+
+ lims = filter_p1 + filter_q1 + ((lim_q1 + lim_p1) >> 1) + 1;
+
+ if (strong) {
+ rdsp->rv40_strong_loop_filter[dir](src, stride, alpha,
+ lims, dmode, chroma);
+ } else if (filter_p1 & filter_q1) {
+ rdsp->rv40_weak_loop_filter[dir](src, stride, 1, 1, alpha, beta,
+ lims, lim_q1, lim_p1);
+ } else if (filter_p1 | filter_q1) {
+ rdsp->rv40_weak_loop_filter[dir](src, stride, filter_p1, filter_q1,
+ alpha, beta, lims >> 1, lim_q1 >> 1,
+ lim_p1 >> 1);
+ }
+}
+
+/**
+ * RV40 loop filtering function
+ */
+static void rv40_loop_filter(RV34DecContext *r, int row)
+{
+ MpegEncContext *s = &r->s;
+ int mb_pos, mb_x;
+ int i, j, k;
+ uint8_t *Y, *C;
+ int alpha, beta, betaY, betaC;
+ int q;
+ int mbtype[4]; ///< current macroblock and its neighbours types
+ /**
+ * flags indicating that macroblock can be filtered with strong filter
+ * it is set only for intra coded MB and MB with DCs coded separately
+ */
+ int mb_strong[4];
+ int clip[4]; ///< MB filter clipping value calculated from filtering strength
+ /**
+ * coded block patterns for luma part of current macroblock and its neighbours
+ * Format:
+ * LSB corresponds to the top left block,
+ * each nibble represents one row of subblocks.
+ */
+ int cbp[4];
+ /**
+ * coded block patterns for chroma part of current macroblock and its neighbours
+ * Format is the same as for luma with two subblocks in a row.
+ */
+ int uvcbp[4][2];
+ /**
+ * This mask represents the pattern of luma subblocks that should be filtered
+ * in addition to the coded ones because they lie at the edge of
+ * 8x8 block with different enough motion vectors
+ */
+ unsigned mvmasks[4];
+
+ mb_pos = row * s->mb_stride;
+ for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
+ int mbtype = s->current_picture_ptr->mb_type[mb_pos];
+ if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype))
+ r->cbp_luma [mb_pos] = r->deblock_coefs[mb_pos] = 0xFFFF;
+ if(IS_INTRA(mbtype))
+ r->cbp_chroma[mb_pos] = 0xFF;
+ }
+ mb_pos = row * s->mb_stride;
+ for(mb_x = 0; mb_x < s->mb_width; mb_x++, mb_pos++){
+ int y_h_deblock, y_v_deblock;
+ int c_v_deblock[2], c_h_deblock[2];
+ int clip_left;
+ int avail[4];
+ unsigned y_to_deblock;
+ int c_to_deblock[2];
+
+ q = s->current_picture_ptr->qscale_table[mb_pos];
+ alpha = rv40_alpha_tab[q];
+ beta = rv40_beta_tab [q];
+ betaY = betaC = beta * 3;
+ if(s->width * s->height <= 176*144)
+ betaY += beta;
+
+ avail[0] = 1;
+ avail[1] = row;
+ avail[2] = mb_x;
+ avail[3] = row < s->mb_height - 1;
+ for(i = 0; i < 4; i++){
+ if(avail[i]){
+ int pos = mb_pos + neighbour_offs_x[i] + neighbour_offs_y[i]*s->mb_stride;
+ mvmasks[i] = r->deblock_coefs[pos];
+ mbtype [i] = s->current_picture_ptr->mb_type[pos];
+ cbp [i] = r->cbp_luma[pos];
+ uvcbp[i][0] = r->cbp_chroma[pos] & 0xF;
+ uvcbp[i][1] = r->cbp_chroma[pos] >> 4;
+ }else{
+ mvmasks[i] = 0;
+ mbtype [i] = mbtype[0];
+ cbp [i] = 0;
+ uvcbp[i][0] = uvcbp[i][1] = 0;
+ }
+ mb_strong[i] = IS_INTRA(mbtype[i]) || IS_SEPARATE_DC(mbtype[i]);
+ clip[i] = rv40_filter_clip_tbl[mb_strong[i] + 1][q];
+ }
+ y_to_deblock = mvmasks[POS_CUR]
+ | (mvmasks[POS_BOTTOM] << 16);
+ /* This pattern contains bits signalling that horizontal edges of
+ * the current block can be filtered.
+ * That happens when either of adjacent subblocks is coded or lies on
+ * the edge of 8x8 blocks with motion vectors differing by more than
+ * 3/4 pel in any component (any edge orientation for some reason).
+ */
+ y_h_deblock = y_to_deblock
+ | ((cbp[POS_CUR] << 4) & ~MASK_Y_TOP_ROW)
+ | ((cbp[POS_TOP] & MASK_Y_LAST_ROW) >> 12);
+ /* This pattern contains bits signalling that vertical edges of
+ * the current block can be filtered.
+ * That happens when either of adjacent subblocks is coded or lies on
+ * the edge of 8x8 blocks with motion vectors differing by more than
+ * 3/4 pel in any component (any edge orientation for some reason).
+ */
+ y_v_deblock = y_to_deblock
+ | ((cbp[POS_CUR] << 1) & ~MASK_Y_LEFT_COL)
+ | ((cbp[POS_LEFT] & MASK_Y_RIGHT_COL) >> 3);
+ if(!mb_x)
+ y_v_deblock &= ~MASK_Y_LEFT_COL;
+ if(!row)
+ y_h_deblock &= ~MASK_Y_TOP_ROW;
+ if(row == s->mb_height - 1 || (mb_strong[POS_CUR] | mb_strong[POS_BOTTOM]))
+ y_h_deblock &= ~(MASK_Y_TOP_ROW << 16);
+ /* Calculating chroma patterns is similar and easier since there is
+ * no motion vector pattern for them.
+ */
+ for(i = 0; i < 2; i++){
+ c_to_deblock[i] = (uvcbp[POS_BOTTOM][i] << 4) | uvcbp[POS_CUR][i];
+ c_v_deblock[i] = c_to_deblock[i]
+ | ((uvcbp[POS_CUR] [i] << 1) & ~MASK_C_LEFT_COL)
+ | ((uvcbp[POS_LEFT][i] & MASK_C_RIGHT_COL) >> 1);
+ c_h_deblock[i] = c_to_deblock[i]
+ | ((uvcbp[POS_TOP][i] & MASK_C_LAST_ROW) >> 2)
+ | (uvcbp[POS_CUR][i] << 2);
+ if(!mb_x)
+ c_v_deblock[i] &= ~MASK_C_LEFT_COL;
+ if(!row)
+ c_h_deblock[i] &= ~MASK_C_TOP_ROW;
+ if(row == s->mb_height - 1 || (mb_strong[POS_CUR] | mb_strong[POS_BOTTOM]))
+ c_h_deblock[i] &= ~(MASK_C_TOP_ROW << 4);
+ }
+
+ for(j = 0; j < 16; j += 4){
+ Y = s->current_picture_ptr->f->data[0] + mb_x*16 + (row*16 + j) * s->linesize;
+ for(i = 0; i < 4; i++, Y += 4){
+ int ij = i + j;
+ int clip_cur = y_to_deblock & (MASK_CUR << ij) ? clip[POS_CUR] : 0;
+ int dither = j ? ij : i*4;
+
+ // if bottom block is coded then we can filter its top edge
+ // (or bottom edge of this block, which is the same)
+ if(y_h_deblock & (MASK_BOTTOM << ij)){
+ rv40_adaptive_loop_filter(&r->rdsp, Y+4*s->linesize,
+ s->linesize, dither,
+ y_to_deblock & (MASK_BOTTOM << ij) ? clip[POS_CUR] : 0,
+ clip_cur, alpha, beta, betaY,
+ 0, 0, 0);
+ }
+ // filter left block edge in ordinary mode (with low filtering strength)
+ if(y_v_deblock & (MASK_CUR << ij) && (i || !(mb_strong[POS_CUR] | mb_strong[POS_LEFT]))){
+ if(!i)
+ clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0;
+ else
+ clip_left = y_to_deblock & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0;
+ rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither,
+ clip_cur,
+ clip_left,
+ alpha, beta, betaY, 0, 0, 1);
+ }
+ // filter top edge of the current macroblock when filtering strength is high
+ if(!j && y_h_deblock & (MASK_CUR << i) && (mb_strong[POS_CUR] | mb_strong[POS_TOP])){
+ rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither,
+ clip_cur,
+ mvmasks[POS_TOP] & (MASK_TOP << i) ? clip[POS_TOP] : 0,
+ alpha, beta, betaY, 0, 1, 0);
+ }
+ // filter left block edge in edge mode (with high filtering strength)
+ if(y_v_deblock & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] | mb_strong[POS_LEFT])){
+ clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0;
+ rv40_adaptive_loop_filter(&r->rdsp, Y, s->linesize, dither,
+ clip_cur,
+ clip_left,
+ alpha, beta, betaY, 0, 1, 1);
+ }
+ }
+ }
+ for(k = 0; k < 2; k++){
+ for(j = 0; j < 2; j++){
+ C = s->current_picture_ptr->f->data[k + 1] + mb_x*8 + (row*8 + j*4) * s->uvlinesize;
+ for(i = 0; i < 2; i++, C += 4){
+ int ij = i + j*2;
+ int clip_cur = c_to_deblock[k] & (MASK_CUR << ij) ? clip[POS_CUR] : 0;
+ if(c_h_deblock[k] & (MASK_CUR << (ij+2))){
+ int clip_bot = c_to_deblock[k] & (MASK_CUR << (ij+2)) ? clip[POS_CUR] : 0;
+ rv40_adaptive_loop_filter(&r->rdsp, C+4*s->uvlinesize, s->uvlinesize, i*8,
+ clip_bot,
+ clip_cur,
+ alpha, beta, betaC, 1, 0, 0);
+ }
+ if((c_v_deblock[k] & (MASK_CUR << ij)) && (i || !(mb_strong[POS_CUR] | mb_strong[POS_LEFT]))){
+ if(!i)
+ clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0;
+ else
+ clip_left = c_to_deblock[k] & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0;
+ rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, j*8,
+ clip_cur,
+ clip_left,
+ alpha, beta, betaC, 1, 0, 1);
+ }
+ if(!j && c_h_deblock[k] & (MASK_CUR << ij) && (mb_strong[POS_CUR] | mb_strong[POS_TOP])){
+ int clip_top = uvcbp[POS_TOP][k] & (MASK_CUR << (ij+2)) ? clip[POS_TOP] : 0;
+ rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, i*8,
+ clip_cur,
+ clip_top,
+ alpha, beta, betaC, 1, 1, 0);
+ }
+ if(c_v_deblock[k] & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] | mb_strong[POS_LEFT])){
+ clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0;
+ rv40_adaptive_loop_filter(&r->rdsp, C, s->uvlinesize, j*8,
+ clip_cur,
+ clip_left,
+ alpha, beta, betaC, 1, 1, 1);
+ }
+ }
+ }
+ }
+ }
+}
+
+/**
+ * Initialize decoder.
+ */
+static av_cold int rv40_decode_init(AVCodecContext *avctx)
+{
+ RV34DecContext *r = avctx->priv_data;
+ int ret;
+
+ r->rv30 = 0;
+ if ((ret = ff_rv34_decode_init(avctx)) < 0)
+ return ret;
+ if(!aic_top_vlc.bits)
+ rv40_init_tables();
+ r->parse_slice_header = rv40_parse_slice_header;
+ r->decode_intra_types = rv40_decode_intra_types;
+ r->decode_mb_info = rv40_decode_mb_info;
+ r->loop_filter = rv40_loop_filter;
+ r->luma_dc_quant_i = rv40_luma_dc_quant[0];
+ r->luma_dc_quant_p = rv40_luma_dc_quant[1];
+ return 0;
+}
+
+AVCodec ff_rv40_decoder = {
+ .name = "rv40",
+ .long_name = NULL_IF_CONFIG_SMALL("RealVideo 4.0"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_RV40,
+ .priv_data_size = sizeof(RV34DecContext),
+ .init = rv40_decode_init,
+ .close = ff_rv34_decode_end,
+ .decode = ff_rv34_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY |
+ AV_CODEC_CAP_FRAME_THREADS,
+ .flush = ff_mpeg_flush,
+ .pix_fmts = (const enum AVPixelFormat[]) {
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_NONE
+ },
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_init_thread_copy),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(ff_rv34_decode_update_thread_context),
+};
diff --git a/ffmpeg-2-8-11/libavcodec/rv40data.h b/ffmpeg-2-8-12/libavcodec/rv40data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv40data.h
rename to ffmpeg-2-8-12/libavcodec/rv40data.h
diff --git a/ffmpeg-2-8-12/libavcodec/rv40dsp.c b/ffmpeg-2-8-12/libavcodec/rv40dsp.c
new file mode 100644
index 0000000..95ba0a9
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/rv40dsp.c
@@ -0,0 +1,709 @@
+/*
+ * RV40 decoder motion compensation functions
+ * Copyright (c) 2008 Konstantin Shishkov
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * RV40 decoder motion compensation functions
+ */
+
+#include "libavutil/common.h"
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "h264qpel.h"
+#include "mathops.h"
+#include "pixels.h"
+#include "rnd_avg.h"
+#include "rv34dsp.h"
+#include "libavutil/avassert.h"
+
+#define RV40_LOWPASS(OPNAME, OP) \
+static void OPNAME ## rv40_qpel8_h_lowpass(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride,\
+ const int h, const int C1, const int C2, const int SHIFT){\
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;\
+ int i;\
+ for(i = 0; i < h; i++)\
+ {\
+ OP(dst[0], (src[-2] + src[ 3] - 5*(src[-1]+src[2]) + src[0]*C1 + src[1]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ OP(dst[1], (src[-1] + src[ 4] - 5*(src[ 0]+src[3]) + src[1]*C1 + src[2]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ OP(dst[2], (src[ 0] + src[ 5] - 5*(src[ 1]+src[4]) + src[2]*C1 + src[3]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ OP(dst[3], (src[ 1] + src[ 6] - 5*(src[ 2]+src[5]) + src[3]*C1 + src[4]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ OP(dst[4], (src[ 2] + src[ 7] - 5*(src[ 3]+src[6]) + src[4]*C1 + src[5]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ OP(dst[5], (src[ 3] + src[ 8] - 5*(src[ 4]+src[7]) + src[5]*C1 + src[6]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ OP(dst[6], (src[ 4] + src[ 9] - 5*(src[ 5]+src[8]) + src[6]*C1 + src[7]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ OP(dst[7], (src[ 5] + src[10] - 5*(src[ 6]+src[9]) + src[7]*C1 + src[8]*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ dst += dstStride;\
+ src += srcStride;\
+ }\
+}\
+\
+static void OPNAME ## rv40_qpel8_v_lowpass(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride,\
+ const int w, const int C1, const int C2, const int SHIFT){\
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;\
+ int i;\
+ for(i = 0; i < w; i++)\
+ {\
+ const int srcB = src[-2*srcStride];\
+ const int srcA = src[-1*srcStride];\
+ const int src0 = src[0 *srcStride];\
+ const int src1 = src[1 *srcStride];\
+ const int src2 = src[2 *srcStride];\
+ const int src3 = src[3 *srcStride];\
+ const int src4 = src[4 *srcStride];\
+ const int src5 = src[5 *srcStride];\
+ const int src6 = src[6 *srcStride];\
+ const int src7 = src[7 *srcStride];\
+ const int src8 = src[8 *srcStride];\
+ const int src9 = src[9 *srcStride];\
+ const int src10 = src[10*srcStride];\
+ OP(dst[0*dstStride], (srcB + src3 - 5*(srcA+src2) + src0*C1 + src1*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ OP(dst[1*dstStride], (srcA + src4 - 5*(src0+src3) + src1*C1 + src2*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ OP(dst[2*dstStride], (src0 + src5 - 5*(src1+src4) + src2*C1 + src3*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ OP(dst[3*dstStride], (src1 + src6 - 5*(src2+src5) + src3*C1 + src4*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ OP(dst[4*dstStride], (src2 + src7 - 5*(src3+src6) + src4*C1 + src5*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ OP(dst[5*dstStride], (src3 + src8 - 5*(src4+src7) + src5*C1 + src6*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ OP(dst[6*dstStride], (src4 + src9 - 5*(src5+src8) + src6*C1 + src7*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ OP(dst[7*dstStride], (src5 + src10 - 5*(src6+src9) + src7*C1 + src8*C2 + (1<<(SHIFT-1))) >> SHIFT);\
+ dst++;\
+ src++;\
+ }\
+}\
+\
+static void OPNAME ## rv40_qpel16_v_lowpass(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride,\
+ const int w, const int C1, const int C2, const int SHIFT){\
+ OPNAME ## rv40_qpel8_v_lowpass(dst , src , dstStride, srcStride, 8, C1, C2, SHIFT);\
+ OPNAME ## rv40_qpel8_v_lowpass(dst+8, src+8, dstStride, srcStride, 8, C1, C2, SHIFT);\
+ src += 8*srcStride;\
+ dst += 8*dstStride;\
+ OPNAME ## rv40_qpel8_v_lowpass(dst , src , dstStride, srcStride, w-8, C1, C2, SHIFT);\
+ OPNAME ## rv40_qpel8_v_lowpass(dst+8, src+8, dstStride, srcStride, w-8, C1, C2, SHIFT);\
+}\
+\
+static void OPNAME ## rv40_qpel16_h_lowpass(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride,\
+ const int h, const int C1, const int C2, const int SHIFT){\
+ OPNAME ## rv40_qpel8_h_lowpass(dst , src , dstStride, srcStride, 8, C1, C2, SHIFT);\
+ OPNAME ## rv40_qpel8_h_lowpass(dst+8, src+8, dstStride, srcStride, 8, C1, C2, SHIFT);\
+ src += 8*srcStride;\
+ dst += 8*dstStride;\
+ OPNAME ## rv40_qpel8_h_lowpass(dst , src , dstStride, srcStride, h-8, C1, C2, SHIFT);\
+ OPNAME ## rv40_qpel8_h_lowpass(dst+8, src+8, dstStride, srcStride, h-8, C1, C2, SHIFT);\
+}\
+\
+
+#define RV40_MC(OPNAME, SIZE) \
+static void OPNAME ## rv40_qpel ## SIZE ## _mc10_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
+{\
+ OPNAME ## rv40_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride, SIZE, 52, 20, 6);\
+}\
+\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc30_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
+{\
+ OPNAME ## rv40_qpel ## SIZE ## _h_lowpass(dst, src, stride, stride, SIZE, 20, 52, 6);\
+}\
+\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc01_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
+{\
+ OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, src, stride, stride, SIZE, 52, 20, 6);\
+}\
+\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc11_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
+{\
+ uint8_t full[SIZE*(SIZE+5)];\
+ uint8_t * const full_mid = full + SIZE*2;\
+ put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\
+ OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\
+}\
+\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc21_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
+{\
+ uint8_t full[SIZE*(SIZE+5)];\
+ uint8_t * const full_mid = full + SIZE*2;\
+ put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\
+ OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\
+}\
+\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc31_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
+{\
+ uint8_t full[SIZE*(SIZE+5)];\
+ uint8_t * const full_mid = full + SIZE*2;\
+ put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 52, 6);\
+ OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 52, 20, 6);\
+}\
+\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc12_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
+{\
+ uint8_t full[SIZE*(SIZE+5)];\
+ uint8_t * const full_mid = full + SIZE*2;\
+ put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\
+ OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\
+}\
+\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc22_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
+{\
+ uint8_t full[SIZE*(SIZE+5)];\
+ uint8_t * const full_mid = full + SIZE*2;\
+ put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\
+ OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\
+}\
+\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc32_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
+{\
+ uint8_t full[SIZE*(SIZE+5)];\
+ uint8_t * const full_mid = full + SIZE*2;\
+ put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 52, 6);\
+ OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 20, 5);\
+}\
+\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc03_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
+{\
+ OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, src, stride, stride, SIZE, 20, 52, 6);\
+}\
+\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc13_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
+{\
+ uint8_t full[SIZE*(SIZE+5)];\
+ uint8_t * const full_mid = full + SIZE*2;\
+ put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 52, 20, 6);\
+ OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 52, 6);\
+}\
+\
+static void OPNAME ## rv40_qpel ## SIZE ## _mc23_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)\
+{\
+ uint8_t full[SIZE*(SIZE+5)];\
+ uint8_t * const full_mid = full + SIZE*2;\
+ put_rv40_qpel ## SIZE ## _h_lowpass(full, src - 2*stride, SIZE, stride, SIZE+5, 20, 20, 5);\
+ OPNAME ## rv40_qpel ## SIZE ## _v_lowpass(dst, full_mid, stride, SIZE, SIZE, 20, 52, 6);\
+}\
+\
+
+#define op_avg(a, b) a = (((a)+cm[b]+1)>>1)
+#define op_put(a, b) a = cm[b]
+
+RV40_LOWPASS(put_ , op_put)
+RV40_LOWPASS(avg_ , op_avg)
+
+#undef op_avg
+#undef op_put
+
+RV40_MC(put_, 8)
+RV40_MC(put_, 16)
+RV40_MC(avg_, 8)
+RV40_MC(avg_, 16)
+
+#define PIXOP2(OPNAME, OP) \
+static inline void OPNAME ## _pixels8_xy2_8_c(uint8_t *block, \
+ const uint8_t *pixels, \
+ ptrdiff_t line_size, \
+ int h) \
+{ \
+ /* FIXME HIGH BIT DEPTH */ \
+ int j; \
+ \
+ for (j = 0; j < 2; j++) { \
+ int i; \
+ const uint32_t a = AV_RN32(pixels); \
+ const uint32_t b = AV_RN32(pixels + 1); \
+ uint32_t l0 = (a & 0x03030303UL) + \
+ (b & 0x03030303UL) + \
+ 0x02020202UL; \
+ uint32_t h0 = ((a & 0xFCFCFCFCUL) >> 2) + \
+ ((b & 0xFCFCFCFCUL) >> 2); \
+ uint32_t l1, h1; \
+ \
+ pixels += line_size; \
+ for (i = 0; i < h; i += 2) { \
+ uint32_t a = AV_RN32(pixels); \
+ uint32_t b = AV_RN32(pixels + 1); \
+ l1 = (a & 0x03030303UL) + \
+ (b & 0x03030303UL); \
+ h1 = ((a & 0xFCFCFCFCUL) >> 2) + \
+ ((b & 0xFCFCFCFCUL) >> 2); \
+ OP(*((uint32_t *) block), \
+ h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL)); \
+ pixels += line_size; \
+ block += line_size; \
+ a = AV_RN32(pixels); \
+ b = AV_RN32(pixels + 1); \
+ l0 = (a & 0x03030303UL) + \
+ (b & 0x03030303UL) + \
+ 0x02020202UL; \
+ h0 = ((a & 0xFCFCFCFCUL) >> 2) + \
+ ((b & 0xFCFCFCFCUL) >> 2); \
+ OP(*((uint32_t *) block), \
+ h0 + h1 + (((l0 + l1) >> 2) & 0x0F0F0F0FUL)); \
+ pixels += line_size; \
+ block += line_size; \
+ } \
+ pixels += 4 - line_size * (h + 1); \
+ block += 4 - line_size * h; \
+ } \
+} \
+ \
+CALL_2X_PIXELS(OPNAME ## _pixels16_xy2_8_c, \
+ OPNAME ## _pixels8_xy2_8_c, \
+ 8) \
+
+#define op_avg(a, b) a = rnd_avg32(a, b)
+#define op_put(a, b) a = b
+PIXOP2(avg, op_avg)
+PIXOP2(put, op_put)
+#undef op_avg
+#undef op_put
+
+static void put_rv40_qpel16_mc33_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
+{
+ put_pixels16_xy2_8_c(dst, src, stride, 16);
+}
+static void avg_rv40_qpel16_mc33_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
+{
+ avg_pixels16_xy2_8_c(dst, src, stride, 16);
+}
+static void put_rv40_qpel8_mc33_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
+{
+ put_pixels8_xy2_8_c(dst, src, stride, 8);
+}
+static void avg_rv40_qpel8_mc33_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
+{
+ avg_pixels8_xy2_8_c(dst, src, stride, 8);
+}
+
+static const int rv40_bias[4][4] = {
+ { 0, 16, 32, 16 },
+ { 32, 28, 32, 28 },
+ { 0, 32, 16, 32 },
+ { 32, 28, 32, 28 }
+};
+
+#define RV40_CHROMA_MC(OPNAME, OP)\
+static void OPNAME ## rv40_chroma_mc4_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\
+ const int A = (8-x) * (8-y);\
+ const int B = ( x) * (8-y);\
+ const int C = (8-x) * ( y);\
+ const int D = ( x) * ( y);\
+ int i;\
+ int bias = rv40_bias[y>>1][x>>1];\
+ \
+ av_assert2(x<8 && y<8 && x>=0 && y>=0);\
+\
+ if(D){\
+ for(i = 0; i < h; i++){\
+ OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1] + bias));\
+ OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + bias));\
+ OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + bias));\
+ OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + bias));\
+ dst += stride;\
+ src += stride;\
+ }\
+ }else{\
+ const int E = B + C;\
+ const int step = C ? stride : 1;\
+ for(i = 0; i < h; i++){\
+ OP(dst[0], (A*src[0] + E*src[step+0] + bias));\
+ OP(dst[1], (A*src[1] + E*src[step+1] + bias));\
+ OP(dst[2], (A*src[2] + E*src[step+2] + bias));\
+ OP(dst[3], (A*src[3] + E*src[step+3] + bias));\
+ dst += stride;\
+ src += stride;\
+ }\
+ }\
+}\
+\
+static void OPNAME ## rv40_chroma_mc8_c(uint8_t *dst/*align 8*/, uint8_t *src/*align 1*/, int stride, int h, int x, int y){\
+ const int A = (8-x) * (8-y);\
+ const int B = ( x) * (8-y);\
+ const int C = (8-x) * ( y);\
+ const int D = ( x) * ( y);\
+ int i;\
+ int bias = rv40_bias[y>>1][x>>1];\
+ \
+ av_assert2(x<8 && y<8 && x>=0 && y>=0);\
+\
+ if(D){\
+ for(i = 0; i < h; i++){\
+ OP(dst[0], (A*src[0] + B*src[1] + C*src[stride+0] + D*src[stride+1] + bias));\
+ OP(dst[1], (A*src[1] + B*src[2] + C*src[stride+1] + D*src[stride+2] + bias));\
+ OP(dst[2], (A*src[2] + B*src[3] + C*src[stride+2] + D*src[stride+3] + bias));\
+ OP(dst[3], (A*src[3] + B*src[4] + C*src[stride+3] + D*src[stride+4] + bias));\
+ OP(dst[4], (A*src[4] + B*src[5] + C*src[stride+4] + D*src[stride+5] + bias));\
+ OP(dst[5], (A*src[5] + B*src[6] + C*src[stride+5] + D*src[stride+6] + bias));\
+ OP(dst[6], (A*src[6] + B*src[7] + C*src[stride+6] + D*src[stride+7] + bias));\
+ OP(dst[7], (A*src[7] + B*src[8] + C*src[stride+7] + D*src[stride+8] + bias));\
+ dst += stride;\
+ src += stride;\
+ }\
+ }else{\
+ const int E = B + C;\
+ const int step = C ? stride : 1;\
+ for(i = 0; i < h; i++){\
+ OP(dst[0], (A*src[0] + E*src[step+0] + bias));\
+ OP(dst[1], (A*src[1] + E*src[step+1] + bias));\
+ OP(dst[2], (A*src[2] + E*src[step+2] + bias));\
+ OP(dst[3], (A*src[3] + E*src[step+3] + bias));\
+ OP(dst[4], (A*src[4] + E*src[step+4] + bias));\
+ OP(dst[5], (A*src[5] + E*src[step+5] + bias));\
+ OP(dst[6], (A*src[6] + E*src[step+6] + bias));\
+ OP(dst[7], (A*src[7] + E*src[step+7] + bias));\
+ dst += stride;\
+ src += stride;\
+ }\
+ }\
+}
+
+#define op_avg(a, b) a = (((a)+((b)>>6)+1)>>1)
+#define op_put(a, b) a = ((b)>>6)
+
+RV40_CHROMA_MC(put_, op_put)
+RV40_CHROMA_MC(avg_, op_avg)
+
+#define RV40_WEIGHT_FUNC(size) \
+static void rv40_weight_func_rnd_ ## size (uint8_t *dst, uint8_t *src1, uint8_t *src2, int w1, int w2, ptrdiff_t stride)\
+{\
+ int i, j;\
+\
+ for (j = 0; j < size; j++) {\
+ for (i = 0; i < size; i++)\
+ dst[i] = (((w2 * src1[i]) >> 9) + ((w1 * src2[i]) >> 9) + 0x10) >> 5;\
+ src1 += stride;\
+ src2 += stride;\
+ dst += stride;\
+ }\
+}\
+static void rv40_weight_func_nornd_ ## size (uint8_t *dst, uint8_t *src1, uint8_t *src2, int w1, int w2, ptrdiff_t stride)\
+{\
+ int i, j;\
+\
+ for (j = 0; j < size; j++) {\
+ for (i = 0; i < size; i++)\
+ dst[i] = (w2 * src1[i] + w1 * src2[i] + 0x10) >> 5;\
+ src1 += stride;\
+ src2 += stride;\
+ dst += stride;\
+ }\
+}
+
+RV40_WEIGHT_FUNC(16)
+RV40_WEIGHT_FUNC(8)
+
+/**
+ * dither values for deblocking filter - left/top values
+ */
+static const uint8_t rv40_dither_l[16] = {
+ 0x40, 0x50, 0x20, 0x60, 0x30, 0x50, 0x40, 0x30,
+ 0x50, 0x40, 0x50, 0x30, 0x60, 0x20, 0x50, 0x40
+};
+
+/**
+ * dither values for deblocking filter - right/bottom values
+ */
+static const uint8_t rv40_dither_r[16] = {
+ 0x40, 0x30, 0x60, 0x20, 0x50, 0x30, 0x30, 0x40,
+ 0x40, 0x40, 0x50, 0x30, 0x20, 0x60, 0x30, 0x40
+};
+
+#define CLIP_SYMM(a, b) av_clip(a, -(b), b)
+/**
+ * weaker deblocking very similar to the one described in 4.4.2 of JVT-A003r1
+ */
+static av_always_inline void rv40_weak_loop_filter(uint8_t *src,
+ const int step,
+ const ptrdiff_t stride,
+ const int filter_p1,
+ const int filter_q1,
+ const int alpha,
+ const int beta,
+ const int lim_p0q0,
+ const int lim_q1,
+ const int lim_p1)
+{
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int i, t, u, diff;
+
+ for (i = 0; i < 4; i++, src += stride) {
+ int diff_p1p0 = src[-2*step] - src[-1*step];
+ int diff_q1q0 = src[ 1*step] - src[ 0*step];
+ int diff_p1p2 = src[-2*step] - src[-3*step];
+ int diff_q1q2 = src[ 1*step] - src[ 2*step];
+
+ t = src[0*step] - src[-1*step];
+ if (!t)
+ continue;
+
+ u = (alpha * FFABS(t)) >> 7;
+ if (u > 3 - (filter_p1 && filter_q1))
+ continue;
+
+ t *= 1 << 2;
+ if (filter_p1 && filter_q1)
+ t += src[-2*step] - src[1*step];
+
+ diff = CLIP_SYMM((t + 4) >> 3, lim_p0q0);
+ src[-1*step] = cm[src[-1*step] + diff];
+ src[ 0*step] = cm[src[ 0*step] - diff];
+
+ if (filter_p1 && FFABS(diff_p1p2) <= beta) {
+ t = (diff_p1p0 + diff_p1p2 - diff) >> 1;
+ src[-2*step] = cm[src[-2*step] - CLIP_SYMM(t, lim_p1)];
+ }
+
+ if (filter_q1 && FFABS(diff_q1q2) <= beta) {
+ t = (diff_q1q0 + diff_q1q2 + diff) >> 1;
+ src[ 1*step] = cm[src[ 1*step] - CLIP_SYMM(t, lim_q1)];
+ }
+ }
+}
+
+static void rv40_h_weak_loop_filter(uint8_t *src, const ptrdiff_t stride,
+ const int filter_p1, const int filter_q1,
+ const int alpha, const int beta,
+ const int lim_p0q0, const int lim_q1,
+ const int lim_p1)
+{
+ rv40_weak_loop_filter(src, stride, 1, filter_p1, filter_q1,
+ alpha, beta, lim_p0q0, lim_q1, lim_p1);
+}
+
+static void rv40_v_weak_loop_filter(uint8_t *src, const ptrdiff_t stride,
+ const int filter_p1, const int filter_q1,
+ const int alpha, const int beta,
+ const int lim_p0q0, const int lim_q1,
+ const int lim_p1)
+{
+ rv40_weak_loop_filter(src, 1, stride, filter_p1, filter_q1,
+ alpha, beta, lim_p0q0, lim_q1, lim_p1);
+}
+
+static av_always_inline void rv40_strong_loop_filter(uint8_t *src,
+ const int step,
+ const ptrdiff_t stride,
+ const int alpha,
+ const int lims,
+ const int dmode,
+ const int chroma)
+{
+ int i;
+
+ for(i = 0; i < 4; i++, src += stride){
+ int sflag, p0, q0, p1, q1;
+ int t = src[0*step] - src[-1*step];
+
+ if (!t)
+ continue;
+
+ sflag = (alpha * FFABS(t)) >> 7;
+ if (sflag > 1)
+ continue;
+
+ p0 = (25*src[-3*step] + 26*src[-2*step] + 26*src[-1*step] +
+ 26*src[ 0*step] + 25*src[ 1*step] +
+ rv40_dither_l[dmode + i]) >> 7;
+
+ q0 = (25*src[-2*step] + 26*src[-1*step] + 26*src[ 0*step] +
+ 26*src[ 1*step] + 25*src[ 2*step] +
+ rv40_dither_r[dmode + i]) >> 7;
+
+ if (sflag) {
+ p0 = av_clip(p0, src[-1*step] - lims, src[-1*step] + lims);
+ q0 = av_clip(q0, src[ 0*step] - lims, src[ 0*step] + lims);
+ }
+
+ p1 = (25*src[-4*step] + 26*src[-3*step] + 26*src[-2*step] + 26*p0 +
+ 25*src[ 0*step] + rv40_dither_l[dmode + i]) >> 7;
+ q1 = (25*src[-1*step] + 26*q0 + 26*src[ 1*step] + 26*src[ 2*step] +
+ 25*src[ 3*step] + rv40_dither_r[dmode + i]) >> 7;
+
+ if (sflag) {
+ p1 = av_clip(p1, src[-2*step] - lims, src[-2*step] + lims);
+ q1 = av_clip(q1, src[ 1*step] - lims, src[ 1*step] + lims);
+ }
+
+ src[-2*step] = p1;
+ src[-1*step] = p0;
+ src[ 0*step] = q0;
+ src[ 1*step] = q1;
+
+ if(!chroma){
+ src[-3*step] = (25*src[-1*step] + 26*src[-2*step] +
+ 51*src[-3*step] + 26*src[-4*step] + 64) >> 7;
+ src[ 2*step] = (25*src[ 0*step] + 26*src[ 1*step] +
+ 51*src[ 2*step] + 26*src[ 3*step] + 64) >> 7;
+ }
+ }
+}
+
+static void rv40_h_strong_loop_filter(uint8_t *src, const ptrdiff_t stride,
+ const int alpha, const int lims,
+ const int dmode, const int chroma)
+{
+ rv40_strong_loop_filter(src, stride, 1, alpha, lims, dmode, chroma);
+}
+
+static void rv40_v_strong_loop_filter(uint8_t *src, const ptrdiff_t stride,
+ const int alpha, const int lims,
+ const int dmode, const int chroma)
+{
+ rv40_strong_loop_filter(src, 1, stride, alpha, lims, dmode, chroma);
+}
+
+static av_always_inline int rv40_loop_filter_strength(uint8_t *src,
+ int step, ptrdiff_t stride,
+ int beta, int beta2,
+ int edge,
+ int *p1, int *q1)
+{
+ int sum_p1p0 = 0, sum_q1q0 = 0, sum_p1p2 = 0, sum_q1q2 = 0;
+ int strong0 = 0, strong1 = 0;
+ uint8_t *ptr;
+ int i;
+
+ for (i = 0, ptr = src; i < 4; i++, ptr += stride) {
+ sum_p1p0 += ptr[-2*step] - ptr[-1*step];
+ sum_q1q0 += ptr[ 1*step] - ptr[ 0*step];
+ }
+
+ *p1 = FFABS(sum_p1p0) < (beta << 2);
+ *q1 = FFABS(sum_q1q0) < (beta << 2);
+
+ if(!*p1 && !*q1)
+ return 0;
+
+ if (!edge)
+ return 0;
+
+ for (i = 0, ptr = src; i < 4; i++, ptr += stride) {
+ sum_p1p2 += ptr[-2*step] - ptr[-3*step];
+ sum_q1q2 += ptr[ 1*step] - ptr[ 2*step];
+ }
+
+ strong0 = *p1 && (FFABS(sum_p1p2) < beta2);
+ strong1 = *q1 && (FFABS(sum_q1q2) < beta2);
+
+ return strong0 && strong1;
+}
+
+static int rv40_h_loop_filter_strength(uint8_t *src, ptrdiff_t stride,
+ int beta, int beta2, int edge,
+ int *p1, int *q1)
+{
+ return rv40_loop_filter_strength(src, stride, 1, beta, beta2, edge, p1, q1);
+}
+
+static int rv40_v_loop_filter_strength(uint8_t *src, ptrdiff_t stride,
+ int beta, int beta2, int edge,
+ int *p1, int *q1)
+{
+ return rv40_loop_filter_strength(src, 1, stride, beta, beta2, edge, p1, q1);
+}
+
+av_cold void ff_rv40dsp_init(RV34DSPContext *c)
+{
+ H264QpelContext qpel;
+
+ ff_rv34dsp_init(c);
+ ff_h264qpel_init(&qpel, 8);
+
+ c->put_pixels_tab[0][ 0] = qpel.put_h264_qpel_pixels_tab[0][0];
+ c->put_pixels_tab[0][ 1] = put_rv40_qpel16_mc10_c;
+ c->put_pixels_tab[0][ 2] = qpel.put_h264_qpel_pixels_tab[0][2];
+ c->put_pixels_tab[0][ 3] = put_rv40_qpel16_mc30_c;
+ c->put_pixels_tab[0][ 4] = put_rv40_qpel16_mc01_c;
+ c->put_pixels_tab[0][ 5] = put_rv40_qpel16_mc11_c;
+ c->put_pixels_tab[0][ 6] = put_rv40_qpel16_mc21_c;
+ c->put_pixels_tab[0][ 7] = put_rv40_qpel16_mc31_c;
+ c->put_pixels_tab[0][ 8] = qpel.put_h264_qpel_pixels_tab[0][8];
+ c->put_pixels_tab[0][ 9] = put_rv40_qpel16_mc12_c;
+ c->put_pixels_tab[0][10] = put_rv40_qpel16_mc22_c;
+ c->put_pixels_tab[0][11] = put_rv40_qpel16_mc32_c;
+ c->put_pixels_tab[0][12] = put_rv40_qpel16_mc03_c;
+ c->put_pixels_tab[0][13] = put_rv40_qpel16_mc13_c;
+ c->put_pixels_tab[0][14] = put_rv40_qpel16_mc23_c;
+ c->put_pixels_tab[0][15] = put_rv40_qpel16_mc33_c;
+ c->avg_pixels_tab[0][ 0] = qpel.avg_h264_qpel_pixels_tab[0][0];
+ c->avg_pixels_tab[0][ 1] = avg_rv40_qpel16_mc10_c;
+ c->avg_pixels_tab[0][ 2] = qpel.avg_h264_qpel_pixels_tab[0][2];
+ c->avg_pixels_tab[0][ 3] = avg_rv40_qpel16_mc30_c;
+ c->avg_pixels_tab[0][ 4] = avg_rv40_qpel16_mc01_c;
+ c->avg_pixels_tab[0][ 5] = avg_rv40_qpel16_mc11_c;
+ c->avg_pixels_tab[0][ 6] = avg_rv40_qpel16_mc21_c;
+ c->avg_pixels_tab[0][ 7] = avg_rv40_qpel16_mc31_c;
+ c->avg_pixels_tab[0][ 8] = qpel.avg_h264_qpel_pixels_tab[0][8];
+ c->avg_pixels_tab[0][ 9] = avg_rv40_qpel16_mc12_c;
+ c->avg_pixels_tab[0][10] = avg_rv40_qpel16_mc22_c;
+ c->avg_pixels_tab[0][11] = avg_rv40_qpel16_mc32_c;
+ c->avg_pixels_tab[0][12] = avg_rv40_qpel16_mc03_c;
+ c->avg_pixels_tab[0][13] = avg_rv40_qpel16_mc13_c;
+ c->avg_pixels_tab[0][14] = avg_rv40_qpel16_mc23_c;
+ c->avg_pixels_tab[0][15] = avg_rv40_qpel16_mc33_c;
+ c->put_pixels_tab[1][ 0] = qpel.put_h264_qpel_pixels_tab[1][0];
+ c->put_pixels_tab[1][ 1] = put_rv40_qpel8_mc10_c;
+ c->put_pixels_tab[1][ 2] = qpel.put_h264_qpel_pixels_tab[1][2];
+ c->put_pixels_tab[1][ 3] = put_rv40_qpel8_mc30_c;
+ c->put_pixels_tab[1][ 4] = put_rv40_qpel8_mc01_c;
+ c->put_pixels_tab[1][ 5] = put_rv40_qpel8_mc11_c;
+ c->put_pixels_tab[1][ 6] = put_rv40_qpel8_mc21_c;
+ c->put_pixels_tab[1][ 7] = put_rv40_qpel8_mc31_c;
+ c->put_pixels_tab[1][ 8] = qpel.put_h264_qpel_pixels_tab[1][8];
+ c->put_pixels_tab[1][ 9] = put_rv40_qpel8_mc12_c;
+ c->put_pixels_tab[1][10] = put_rv40_qpel8_mc22_c;
+ c->put_pixels_tab[1][11] = put_rv40_qpel8_mc32_c;
+ c->put_pixels_tab[1][12] = put_rv40_qpel8_mc03_c;
+ c->put_pixels_tab[1][13] = put_rv40_qpel8_mc13_c;
+ c->put_pixels_tab[1][14] = put_rv40_qpel8_mc23_c;
+ c->put_pixels_tab[1][15] = put_rv40_qpel8_mc33_c;
+ c->avg_pixels_tab[1][ 0] = qpel.avg_h264_qpel_pixels_tab[1][0];
+ c->avg_pixels_tab[1][ 1] = avg_rv40_qpel8_mc10_c;
+ c->avg_pixels_tab[1][ 2] = qpel.avg_h264_qpel_pixels_tab[1][2];
+ c->avg_pixels_tab[1][ 3] = avg_rv40_qpel8_mc30_c;
+ c->avg_pixels_tab[1][ 4] = avg_rv40_qpel8_mc01_c;
+ c->avg_pixels_tab[1][ 5] = avg_rv40_qpel8_mc11_c;
+ c->avg_pixels_tab[1][ 6] = avg_rv40_qpel8_mc21_c;
+ c->avg_pixels_tab[1][ 7] = avg_rv40_qpel8_mc31_c;
+ c->avg_pixels_tab[1][ 8] = qpel.avg_h264_qpel_pixels_tab[1][8];
+ c->avg_pixels_tab[1][ 9] = avg_rv40_qpel8_mc12_c;
+ c->avg_pixels_tab[1][10] = avg_rv40_qpel8_mc22_c;
+ c->avg_pixels_tab[1][11] = avg_rv40_qpel8_mc32_c;
+ c->avg_pixels_tab[1][12] = avg_rv40_qpel8_mc03_c;
+ c->avg_pixels_tab[1][13] = avg_rv40_qpel8_mc13_c;
+ c->avg_pixels_tab[1][14] = avg_rv40_qpel8_mc23_c;
+ c->avg_pixels_tab[1][15] = avg_rv40_qpel8_mc33_c;
+
+ c->put_chroma_pixels_tab[0] = put_rv40_chroma_mc8_c;
+ c->put_chroma_pixels_tab[1] = put_rv40_chroma_mc4_c;
+ c->avg_chroma_pixels_tab[0] = avg_rv40_chroma_mc8_c;
+ c->avg_chroma_pixels_tab[1] = avg_rv40_chroma_mc4_c;
+
+ c->rv40_weight_pixels_tab[0][0] = rv40_weight_func_rnd_16;
+ c->rv40_weight_pixels_tab[0][1] = rv40_weight_func_rnd_8;
+ c->rv40_weight_pixels_tab[1][0] = rv40_weight_func_nornd_16;
+ c->rv40_weight_pixels_tab[1][1] = rv40_weight_func_nornd_8;
+
+ c->rv40_weak_loop_filter[0] = rv40_h_weak_loop_filter;
+ c->rv40_weak_loop_filter[1] = rv40_v_weak_loop_filter;
+ c->rv40_strong_loop_filter[0] = rv40_h_strong_loop_filter;
+ c->rv40_strong_loop_filter[1] = rv40_v_strong_loop_filter;
+ c->rv40_loop_filter_strength[0] = rv40_h_loop_filter_strength;
+ c->rv40_loop_filter_strength[1] = rv40_v_loop_filter_strength;
+
+ if (ARCH_AARCH64)
+ ff_rv40dsp_init_aarch64(c);
+ if (ARCH_ARM)
+ ff_rv40dsp_init_arm(c);
+ if (ARCH_X86)
+ ff_rv40dsp_init_x86(c);
+}
diff --git a/ffmpeg-2-8-11/libavcodec/rv40vlc2.h b/ffmpeg-2-8-12/libavcodec/rv40vlc2.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/rv40vlc2.h
rename to ffmpeg-2-8-12/libavcodec/rv40vlc2.h
diff --git a/ffmpeg-2-8-12/libavcodec/s302m.c b/ffmpeg-2-8-12/libavcodec/s302m.c
new file mode 100644
index 0000000..a68ac79
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/s302m.c
@@ -0,0 +1,230 @@
+/*
+ * SMPTE 302M decoder
+ * Copyright (c) 2008 Laurent Aimar <fenrir at videolan.org>
+ * Copyright (c) 2009 Baptiste Coudurier <baptiste.coudurier at gmail.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 "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
+#include "libavutil/log.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "mathops.h"
+
+#define AES3_HEADER_LEN 4
+
+typedef struct S302Context {
+ AVClass *class;
+ int non_pcm_mode;
+} S302Context;
+
+static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf,
+ int buf_size)
+{
+ uint32_t h;
+ int frame_size, channels, bits;
+
+ if (buf_size <= AES3_HEADER_LEN) {
+ av_log(avctx, AV_LOG_ERROR, "frame is too short\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /*
+ * AES3 header :
+ * size: 16
+ * number channels 2
+ * channel_id 8
+ * bits per samples 2
+ * alignments 4
+ */
+
+ h = AV_RB32(buf);
+ frame_size = (h >> 16) & 0xffff;
+ channels = ((h >> 14) & 0x0003) * 2 + 2;
+ bits = ((h >> 4) & 0x0003) * 4 + 16;
+
+ if (AES3_HEADER_LEN + frame_size != buf_size || bits > 24) {
+ av_log(avctx, AV_LOG_ERROR, "frame has invalid header\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* Set output properties */
+ avctx->bits_per_raw_sample = bits;
+ if (bits > 16)
+ avctx->sample_fmt = AV_SAMPLE_FMT_S32;
+ else
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+
+ avctx->channels = channels;
+ switch(channels) {
+ case 2:
+ avctx->channel_layout = AV_CH_LAYOUT_STEREO;
+ break;
+ case 4:
+ avctx->channel_layout = AV_CH_LAYOUT_QUAD;
+ break;
+ case 6:
+ avctx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK;
+ break;
+ case 8:
+ avctx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX;
+ }
+
+ return frame_size;
+}
+
+static int s302m_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ S302Context *s = avctx->priv_data;
+ AVFrame *frame = data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ int block_size, ret;
+ int i;
+ int non_pcm_data_type = -1;
+
+ int frame_size = s302m_parse_frame_header(avctx, buf, buf_size);
+ if (frame_size < 0)
+ return frame_size;
+
+ buf_size -= AES3_HEADER_LEN;
+ buf += AES3_HEADER_LEN;
+
+ /* get output buffer */
+ block_size = (avctx->bits_per_raw_sample + 4) / 4;
+ frame->nb_samples = 2 * (buf_size / block_size) / avctx->channels;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+
+ avctx->bit_rate = 48000 * avctx->channels * (avctx->bits_per_raw_sample + 4) +
+ 32 * 48000 / frame->nb_samples;
+ buf_size = (frame->nb_samples * avctx->channels / 2) * block_size;
+
+ if (avctx->bits_per_raw_sample == 24) {
+ uint32_t *o = (uint32_t *)frame->data[0];
+ for (; buf_size > 6; buf_size -= 7) {
+ *o++ = ((unsigned)ff_reverse[buf[2]] << 24) |
+ (ff_reverse[buf[1]] << 16) |
+ (ff_reverse[buf[0]] << 8);
+ *o++ = ((unsigned)ff_reverse[buf[6] & 0xf0] << 28) |
+ (ff_reverse[buf[5]] << 20) |
+ (ff_reverse[buf[4]] << 12) |
+ (ff_reverse[buf[3] & 0x0f] << 4);
+ buf += 7;
+ }
+ o = (uint32_t *)frame->data[0];
+ if (avctx->channels == 2)
+ for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
+ if (o[i] || o[i+1] || o[i+2] || o[i+3])
+ break;
+ if (o[i+4] == 0x96F87200U && o[i+5] == 0xA54E1F00) {
+ non_pcm_data_type = (o[i+6] >> 16) & 0x1F;
+ break;
+ }
+ }
+ } else if (avctx->bits_per_raw_sample == 20) {
+ uint32_t *o = (uint32_t *)frame->data[0];
+ for (; buf_size > 5; buf_size -= 6) {
+ *o++ = ((unsigned)ff_reverse[buf[2] & 0xf0] << 28) |
+ (ff_reverse[buf[1]] << 20) |
+ (ff_reverse[buf[0]] << 12);
+ *o++ = ((unsigned)ff_reverse[buf[5] & 0xf0] << 28) |
+ (ff_reverse[buf[4]] << 20) |
+ (ff_reverse[buf[3]] << 12);
+ buf += 6;
+ }
+ o = (uint32_t *)frame->data[0];
+ if (avctx->channels == 2)
+ for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
+ if (o[i] || o[i+1] || o[i+2] || o[i+3])
+ break;
+ if (o[i+4] == 0x6F872000U && o[i+5] == 0x54E1F000) {
+ non_pcm_data_type = (o[i+6] >> 16) & 0x1F;
+ break;
+ }
+ }
+ } else {
+ uint16_t *o = (uint16_t *)frame->data[0];
+ for (; buf_size > 4; buf_size -= 5) {
+ *o++ = (ff_reverse[buf[1]] << 8) |
+ ff_reverse[buf[0]];
+ *o++ = (ff_reverse[buf[4] & 0xf0] << 12) |
+ (ff_reverse[buf[3]] << 4) |
+ (ff_reverse[buf[2]] >> 4);
+ buf += 5;
+ }
+ o = (uint16_t *)frame->data[0];
+ if (avctx->channels == 2)
+ for (i=0; i<frame->nb_samples * 2 - 6; i+=2) {
+ if (o[i] || o[i+1] || o[i+2] || o[i+3])
+ break;
+ if (o[i+4] == 0xF872U && o[i+5] == 0x4E1F) {
+ non_pcm_data_type = (o[i+6] & 0x1F);
+ break;
+ }
+ }
+ }
+
+ if (non_pcm_data_type != -1) {
+ if (s->non_pcm_mode == 3) {
+ av_log(avctx, AV_LOG_ERROR,
+ "S302 non PCM mode with data type %d not supported\n",
+ non_pcm_data_type);
+ return AVERROR_PATCHWELCOME;
+ }
+ if (s->non_pcm_mode & 1) {
+ return avpkt->size;
+ }
+ }
+
+ avctx->sample_rate = 48000;
+
+ *got_frame_ptr = 1;
+
+ return avpkt->size;
+}
+
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM
+static const AVOption s302m_options[] = {
+ {"non_pcm_mode", "Chooses what to do with NON-PCM", offsetof(S302Context, non_pcm_mode), AV_OPT_TYPE_INT, {.i64 = 3}, 0, 3, FLAGS, "non_pcm_mode"},
+ {"copy" , "Pass NON-PCM through unchanged" , 0, AV_OPT_TYPE_CONST, {.i64 = 0}, 0, 3, FLAGS, "non_pcm_mode"},
+ {"drop" , "Drop NON-PCM" , 0, AV_OPT_TYPE_CONST, {.i64 = 1}, 0, 3, FLAGS, "non_pcm_mode"},
+ {"decode_copy" , "Decode if possible else passthrough", 0, AV_OPT_TYPE_CONST, {.i64 = 2}, 0, 3, FLAGS, "non_pcm_mode"},
+ {"decode_drop" , "Decode if possible else drop" , 0, AV_OPT_TYPE_CONST, {.i64 = 3}, 0, 3, FLAGS, "non_pcm_mode"},
+ {NULL}
+};
+
+static const AVClass s302m_class = {
+ "SMPTE 302M Decoder",
+ av_default_item_name,
+ s302m_options,
+ LIBAVUTIL_VERSION_INT,
+};
+
+AVCodec ff_s302m_decoder = {
+ .name = "s302m",
+ .long_name = NULL_IF_CONFIG_SMALL("SMPTE 302M"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_S302M,
+ .priv_data_size = sizeof(S302Context),
+ .decode = s302m_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+ .priv_class = &s302m_class,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/s302menc.c b/ffmpeg-2-8-12/libavcodec/s302menc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/s302menc.c
rename to ffmpeg-2-8-12/libavcodec/s302menc.c
diff --git a/ffmpeg-2-8-11/libavcodec/samidec.c b/ffmpeg-2-8-12/libavcodec/samidec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/samidec.c
rename to ffmpeg-2-8-12/libavcodec/samidec.c
diff --git a/ffmpeg-2-8-12/libavcodec/sanm.c b/ffmpeg-2-8-12/libavcodec/sanm.c
new file mode 100644
index 0000000..065bf7a
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/sanm.c
@@ -0,0 +1,1529 @@
+/*
+ * LucasArts Smush video decoder
+ * Copyright (c) 2006 Cyril Zorin
+ * Copyright (c) 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 "libavutil/avassert.h"
+#include "libavutil/bswap.h"
+#include "libavutil/imgutils.h"
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "copy_block.h"
+#include "internal.h"
+
+#define NGLYPHS 256
+#define GLYPH_COORD_VECT_SIZE 16
+#define PALETTE_SIZE 256
+#define PALETTE_DELTA 768
+
+static const int8_t glyph4_x[GLYPH_COORD_VECT_SIZE] = {
+ 0, 1, 2, 3, 3, 3, 3, 2, 1, 0, 0, 0, 1, 2, 2, 1
+};
+
+static const int8_t glyph4_y[GLYPH_COORD_VECT_SIZE] = {
+ 0, 0, 0, 0, 1, 2, 3, 3, 3, 3, 2, 1, 1, 1, 2, 2
+};
+
+static const int8_t glyph8_x[GLYPH_COORD_VECT_SIZE] = {
+ 0, 2, 5, 7, 7, 7, 7, 7, 7, 5, 2, 0, 0, 0, 0, 0
+};
+
+static const int8_t glyph8_y[GLYPH_COORD_VECT_SIZE] = {
+ 0, 0, 0, 0, 1, 3, 4, 6, 7, 7, 7, 7, 6, 4, 3, 1
+};
+
+static const int8_t motion_vectors[256][2] = {
+ { 0, 0 }, { -1, -43 }, { 6, -43 }, { -9, -42 }, { 13, -41 },
+ { -16, -40 }, { 19, -39 }, { -23, -36 }, { 26, -34 }, { -2, -33 },
+ { 4, -33 }, { -29, -32 }, { -9, -32 }, { 11, -31 }, { -16, -29 },
+ { 32, -29 }, { 18, -28 }, { -34, -26 }, { -22, -25 }, { -1, -25 },
+ { 3, -25 }, { -7, -24 }, { 8, -24 }, { 24, -23 }, { 36, -23 },
+ { -12, -22 }, { 13, -21 }, { -38, -20 }, { 0, -20 }, { -27, -19 },
+ { -4, -19 }, { 4, -19 }, { -17, -18 }, { -8, -17 }, { 8, -17 },
+ { 18, -17 }, { 28, -17 }, { 39, -17 }, { -12, -15 }, { 12, -15 },
+ { -21, -14 }, { -1, -14 }, { 1, -14 }, { -41, -13 }, { -5, -13 },
+ { 5, -13 }, { 21, -13 }, { -31, -12 }, { -15, -11 }, { -8, -11 },
+ { 8, -11 }, { 15, -11 }, { -2, -10 }, { 1, -10 }, { 31, -10 },
+ { -23, -9 }, { -11, -9 }, { -5, -9 }, { 4, -9 }, { 11, -9 },
+ { 42, -9 }, { 6, -8 }, { 24, -8 }, { -18, -7 }, { -7, -7 },
+ { -3, -7 }, { -1, -7 }, { 2, -7 }, { 18, -7 }, { -43, -6 },
+ { -13, -6 }, { -4, -6 }, { 4, -6 }, { 8, -6 }, { -33, -5 },
+ { -9, -5 }, { -2, -5 }, { 0, -5 }, { 2, -5 }, { 5, -5 },
+ { 13, -5 }, { -25, -4 }, { -6, -4 }, { -3, -4 }, { 3, -4 },
+ { 9, -4 }, { -19, -3 }, { -7, -3 }, { -4, -3 }, { -2, -3 },
+ { -1, -3 }, { 0, -3 }, { 1, -3 }, { 2, -3 }, { 4, -3 },
+ { 6, -3 }, { 33, -3 }, { -14, -2 }, { -10, -2 }, { -5, -2 },
+ { -3, -2 }, { -2, -2 }, { -1, -2 }, { 0, -2 }, { 1, -2 },
+ { 2, -2 }, { 3, -2 }, { 5, -2 }, { 7, -2 }, { 14, -2 },
+ { 19, -2 }, { 25, -2 }, { 43, -2 }, { -7, -1 }, { -3, -1 },
+ { -2, -1 }, { -1, -1 }, { 0, -1 }, { 1, -1 }, { 2, -1 },
+ { 3, -1 }, { 10, -1 }, { -5, 0 }, { -3, 0 }, { -2, 0 },
+ { -1, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 }, { 5, 0 },
+ { 7, 0 }, { -10, 1 }, { -7, 1 }, { -3, 1 }, { -2, 1 },
+ { -1, 1 }, { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 },
+ { -43, 2 }, { -25, 2 }, { -19, 2 }, { -14, 2 }, { -5, 2 },
+ { -3, 2 }, { -2, 2 }, { -1, 2 }, { 0, 2 }, { 1, 2 },
+ { 2, 2 }, { 3, 2 }, { 5, 2 }, { 7, 2 }, { 10, 2 },
+ { 14, 2 }, { -33, 3 }, { -6, 3 }, { -4, 3 }, { -2, 3 },
+ { -1, 3 }, { 0, 3 }, { 1, 3 }, { 2, 3 }, { 4, 3 },
+ { 19, 3 }, { -9, 4 }, { -3, 4 }, { 3, 4 }, { 7, 4 },
+ { 25, 4 }, { -13, 5 }, { -5, 5 }, { -2, 5 }, { 0, 5 },
+ { 2, 5 }, { 5, 5 }, { 9, 5 }, { 33, 5 }, { -8, 6 },
+ { -4, 6 }, { 4, 6 }, { 13, 6 }, { 43, 6 }, { -18, 7 },
+ { -2, 7 }, { 0, 7 }, { 2, 7 }, { 7, 7 }, { 18, 7 },
+ { -24, 8 }, { -6, 8 }, { -42, 9 }, { -11, 9 }, { -4, 9 },
+ { 5, 9 }, { 11, 9 }, { 23, 9 }, { -31, 10 }, { -1, 10 },
+ { 2, 10 }, { -15, 11 }, { -8, 11 }, { 8, 11 }, { 15, 11 },
+ { 31, 12 }, { -21, 13 }, { -5, 13 }, { 5, 13 }, { 41, 13 },
+ { -1, 14 }, { 1, 14 }, { 21, 14 }, { -12, 15 }, { 12, 15 },
+ { -39, 17 }, { -28, 17 }, { -18, 17 }, { -8, 17 }, { 8, 17 },
+ { 17, 18 }, { -4, 19 }, { 0, 19 }, { 4, 19 }, { 27, 19 },
+ { 38, 20 }, { -13, 21 }, { 12, 22 }, { -36, 23 }, { -24, 23 },
+ { -8, 24 }, { 7, 24 }, { -3, 25 }, { 1, 25 }, { 22, 25 },
+ { 34, 26 }, { -18, 28 }, { -32, 29 }, { 16, 29 }, { -11, 31 },
+ { 9, 32 }, { 29, 32 }, { -4, 33 }, { 2, 33 }, { -26, 34 },
+ { 23, 36 }, { -19, 39 }, { 16, 40 }, { -13, 41 }, { 9, 42 },
+ { -6, 43 }, { 1, 43 }, { 0, 0 }, { 0, 0 }, { 0, 0 },
+};
+
+static const int8_t c37_mv[] = {
+ 0, 0, 1, 0, 2, 0, 3, 0, 5, 0,
+ 8, 0, 13, 0, 21, 0, -1, 0, -2, 0,
+ -3, 0, -5, 0, -8, 0, -13, 0, -17, 0,
+ -21, 0, 0, 1, 1, 1, 2, 1, 3, 1,
+ 5, 1, 8, 1, 13, 1, 21, 1, -1, 1,
+ -2, 1, -3, 1, -5, 1, -8, 1, -13, 1,
+ -17, 1, -21, 1, 0, 2, 1, 2, 2, 2,
+ 3, 2, 5, 2, 8, 2, 13, 2, 21, 2,
+ -1, 2, -2, 2, -3, 2, -5, 2, -8, 2,
+ -13, 2, -17, 2, -21, 2, 0, 3, 1, 3,
+ 2, 3, 3, 3, 5, 3, 8, 3, 13, 3,
+ 21, 3, -1, 3, -2, 3, -3, 3, -5, 3,
+ -8, 3, -13, 3, -17, 3, -21, 3, 0, 5,
+ 1, 5, 2, 5, 3, 5, 5, 5, 8, 5,
+ 13, 5, 21, 5, -1, 5, -2, 5, -3, 5,
+ -5, 5, -8, 5, -13, 5, -17, 5, -21, 5,
+ 0, 8, 1, 8, 2, 8, 3, 8, 5, 8,
+ 8, 8, 13, 8, 21, 8, -1, 8, -2, 8,
+ -3, 8, -5, 8, -8, 8, -13, 8, -17, 8,
+ -21, 8, 0, 13, 1, 13, 2, 13, 3, 13,
+ 5, 13, 8, 13, 13, 13, 21, 13, -1, 13,
+ -2, 13, -3, 13, -5, 13, -8, 13, -13, 13,
+ -17, 13, -21, 13, 0, 21, 1, 21, 2, 21,
+ 3, 21, 5, 21, 8, 21, 13, 21, 21, 21,
+ -1, 21, -2, 21, -3, 21, -5, 21, -8, 21,
+ -13, 21, -17, 21, -21, 21, 0, -1, 1, -1,
+ 2, -1, 3, -1, 5, -1, 8, -1, 13, -1,
+ 21, -1, -1, -1, -2, -1, -3, -1, -5, -1,
+ -8, -1, -13, -1, -17, -1, -21, -1, 0, -2,
+ 1, -2, 2, -2, 3, -2, 5, -2, 8, -2,
+ 13, -2, 21, -2, -1, -2, -2, -2, -3, -2,
+ -5, -2, -8, -2, -13, -2, -17, -2, -21, -2,
+ 0, -3, 1, -3, 2, -3, 3, -3, 5, -3,
+ 8, -3, 13, -3, 21, -3, -1, -3, -2, -3,
+ -3, -3, -5, -3, -8, -3, -13, -3, -17, -3,
+ -21, -3, 0, -5, 1, -5, 2, -5, 3, -5,
+ 5, -5, 8, -5, 13, -5, 21, -5, -1, -5,
+ -2, -5, -3, -5, -5, -5, -8, -5, -13, -5,
+ -17, -5, -21, -5, 0, -8, 1, -8, 2, -8,
+ 3, -8, 5, -8, 8, -8, 13, -8, 21, -8,
+ -1, -8, -2, -8, -3, -8, -5, -8, -8, -8,
+ -13, -8, -17, -8, -21, -8, 0, -13, 1, -13,
+ 2, -13, 3, -13, 5, -13, 8, -13, 13, -13,
+ 21, -13, -1, -13, -2, -13, -3, -13, -5, -13,
+ -8, -13, -13, -13, -17, -13, -21, -13, 0, -17,
+ 1, -17, 2, -17, 3, -17, 5, -17, 8, -17,
+ 13, -17, 21, -17, -1, -17, -2, -17, -3, -17,
+ -5, -17, -8, -17, -13, -17, -17, -17, -21, -17,
+ 0, -21, 1, -21, 2, -21, 3, -21, 5, -21,
+ 8, -21, 13, -21, 21, -21, -1, -21, -2, -21,
+ -3, -21, -5, -21, -8, -21, -13, -21, -17, -21,
+ 0, 0, -8, -29, 8, -29, -18, -25, 17, -25,
+ 0, -23, -6, -22, 6, -22, -13, -19, 12, -19,
+ 0, -18, 25, -18, -25, -17, -5, -17, 5, -17,
+ -10, -15, 10, -15, 0, -14, -4, -13, 4, -13,
+ 19, -13, -19, -12, -8, -11, -2, -11, 0, -11,
+ 2, -11, 8, -11, -15, -10, -4, -10, 4, -10,
+ 15, -10, -6, -9, -1, -9, 1, -9, 6, -9,
+ -29, -8, -11, -8, -8, -8, -3, -8, 3, -8,
+ 8, -8, 11, -8, 29, -8, -5, -7, -2, -7,
+ 0, -7, 2, -7, 5, -7, -22, -6, -9, -6,
+ -6, -6, -3, -6, -1, -6, 1, -6, 3, -6,
+ 6, -6, 9, -6, 22, -6, -17, -5, -7, -5,
+ -4, -5, -2, -5, 0, -5, 2, -5, 4, -5,
+ 7, -5, 17, -5, -13, -4, -10, -4, -5, -4,
+ -3, -4, -1, -4, 0, -4, 1, -4, 3, -4,
+ 5, -4, 10, -4, 13, -4, -8, -3, -6, -3,
+ -4, -3, -3, -3, -2, -3, -1, -3, 0, -3,
+ 1, -3, 2, -3, 4, -3, 6, -3, 8, -3,
+ -11, -2, -7, -2, -5, -2, -3, -2, -2, -2,
+ -1, -2, 0, -2, 1, -2, 2, -2, 3, -2,
+ 5, -2, 7, -2, 11, -2, -9, -1, -6, -1,
+ -4, -1, -3, -1, -2, -1, -1, -1, 0, -1,
+ 1, -1, 2, -1, 3, -1, 4, -1, 6, -1,
+ 9, -1, -31, 0, -23, 0, -18, 0, -14, 0,
+ -11, 0, -7, 0, -5, 0, -4, 0, -3, 0,
+ -2, 0, -1, 0, 0, -31, 1, 0, 2, 0,
+ 3, 0, 4, 0, 5, 0, 7, 0, 11, 0,
+ 14, 0, 18, 0, 23, 0, 31, 0, -9, 1,
+ -6, 1, -4, 1, -3, 1, -2, 1, -1, 1,
+ 0, 1, 1, 1, 2, 1, 3, 1, 4, 1,
+ 6, 1, 9, 1, -11, 2, -7, 2, -5, 2,
+ -3, 2, -2, 2, -1, 2, 0, 2, 1, 2,
+ 2, 2, 3, 2, 5, 2, 7, 2, 11, 2,
+ -8, 3, -6, 3, -4, 3, -2, 3, -1, 3,
+ 0, 3, 1, 3, 2, 3, 3, 3, 4, 3,
+ 6, 3, 8, 3, -13, 4, -10, 4, -5, 4,
+ -3, 4, -1, 4, 0, 4, 1, 4, 3, 4,
+ 5, 4, 10, 4, 13, 4, -17, 5, -7, 5,
+ -4, 5, -2, 5, 0, 5, 2, 5, 4, 5,
+ 7, 5, 17, 5, -22, 6, -9, 6, -6, 6,
+ -3, 6, -1, 6, 1, 6, 3, 6, 6, 6,
+ 9, 6, 22, 6, -5, 7, -2, 7, 0, 7,
+ 2, 7, 5, 7, -29, 8, -11, 8, -8, 8,
+ -3, 8, 3, 8, 8, 8, 11, 8, 29, 8,
+ -6, 9, -1, 9, 1, 9, 6, 9, -15, 10,
+ -4, 10, 4, 10, 15, 10, -8, 11, -2, 11,
+ 0, 11, 2, 11, 8, 11, 19, 12, -19, 13,
+ -4, 13, 4, 13, 0, 14, -10, 15, 10, 15,
+ -5, 17, 5, 17, 25, 17, -25, 18, 0, 18,
+ -12, 19, 13, 19, -6, 22, 6, 22, 0, 23,
+ -17, 25, 18, 25, -8, 29, 8, 29, 0, 31,
+ 0, 0, -6, -22, 6, -22, -13, -19, 12, -19,
+ 0, -18, -5, -17, 5, -17, -10, -15, 10, -15,
+ 0, -14, -4, -13, 4, -13, 19, -13, -19, -12,
+ -8, -11, -2, -11, 0, -11, 2, -11, 8, -11,
+ -15, -10, -4, -10, 4, -10, 15, -10, -6, -9,
+ -1, -9, 1, -9, 6, -9, -11, -8, -8, -8,
+ -3, -8, 0, -8, 3, -8, 8, -8, 11, -8,
+ -5, -7, -2, -7, 0, -7, 2, -7, 5, -7,
+ -22, -6, -9, -6, -6, -6, -3, -6, -1, -6,
+ 1, -6, 3, -6, 6, -6, 9, -6, 22, -6,
+ -17, -5, -7, -5, -4, -5, -2, -5, -1, -5,
+ 0, -5, 1, -5, 2, -5, 4, -5, 7, -5,
+ 17, -5, -13, -4, -10, -4, -5, -4, -3, -4,
+ -2, -4, -1, -4, 0, -4, 1, -4, 2, -4,
+ 3, -4, 5, -4, 10, -4, 13, -4, -8, -3,
+ -6, -3, -4, -3, -3, -3, -2, -3, -1, -3,
+ 0, -3, 1, -3, 2, -3, 3, -3, 4, -3,
+ 6, -3, 8, -3, -11, -2, -7, -2, -5, -2,
+ -4, -2, -3, -2, -2, -2, -1, -2, 0, -2,
+ 1, -2, 2, -2, 3, -2, 4, -2, 5, -2,
+ 7, -2, 11, -2, -9, -1, -6, -1, -5, -1,
+ -4, -1, -3, -1, -2, -1, -1, -1, 0, -1,
+ 1, -1, 2, -1, 3, -1, 4, -1, 5, -1,
+ 6, -1, 9, -1, -23, 0, -18, 0, -14, 0,
+ -11, 0, -7, 0, -5, 0, -4, 0, -3, 0,
+ -2, 0, -1, 0, 0, -23, 1, 0, 2, 0,
+ 3, 0, 4, 0, 5, 0, 7, 0, 11, 0,
+ 14, 0, 18, 0, 23, 0, -9, 1, -6, 1,
+ -5, 1, -4, 1, -3, 1, -2, 1, -1, 1,
+ 0, 1, 1, 1, 2, 1, 3, 1, 4, 1,
+ 5, 1, 6, 1, 9, 1, -11, 2, -7, 2,
+ -5, 2, -4, 2, -3, 2, -2, 2, -1, 2,
+ 0, 2, 1, 2, 2, 2, 3, 2, 4, 2,
+ 5, 2, 7, 2, 11, 2, -8, 3, -6, 3,
+ -4, 3, -3, 3, -2, 3, -1, 3, 0, 3,
+ 1, 3, 2, 3, 3, 3, 4, 3, 6, 3,
+ 8, 3, -13, 4, -10, 4, -5, 4, -3, 4,
+ -2, 4, -1, 4, 0, 4, 1, 4, 2, 4,
+ 3, 4, 5, 4, 10, 4, 13, 4, -17, 5,
+ -7, 5, -4, 5, -2, 5, -1, 5, 0, 5,
+ 1, 5, 2, 5, 4, 5, 7, 5, 17, 5,
+ -22, 6, -9, 6, -6, 6, -3, 6, -1, 6,
+ 1, 6, 3, 6, 6, 6, 9, 6, 22, 6,
+ -5, 7, -2, 7, 0, 7, 2, 7, 5, 7,
+ -11, 8, -8, 8, -3, 8, 0, 8, 3, 8,
+ 8, 8, 11, 8, -6, 9, -1, 9, 1, 9,
+ 6, 9, -15, 10, -4, 10, 4, 10, 15, 10,
+ -8, 11, -2, 11, 0, 11, 2, 11, 8, 11,
+ 19, 12, -19, 13, -4, 13, 4, 13, 0, 14,
+ -10, 15, 10, 15, -5, 17, 5, 17, 0, 18,
+ -12, 19, 13, 19, -6, 22, 6, 22, 0, 23,
+};
+
+typedef struct SANMVideoContext {
+ AVCodecContext *avctx;
+ GetByteContext gb;
+
+ int version, subversion;
+ uint32_t pal[PALETTE_SIZE];
+ int16_t delta_pal[PALETTE_DELTA];
+
+ int pitch;
+ int width, height;
+ int aligned_width, aligned_height;
+ int prev_seq;
+
+ AVFrame *frame;
+ uint16_t *frm0, *frm1, *frm2;
+ uint8_t *stored_frame;
+ uint32_t frm0_size, frm1_size, frm2_size;
+ uint32_t stored_frame_size;
+
+ uint8_t *rle_buf;
+ unsigned int rle_buf_size;
+
+ int rotate_code;
+
+ long npixels, buf_size;
+
+ uint16_t codebook[256];
+ uint16_t small_codebook[4];
+
+ int8_t p4x4glyphs[NGLYPHS][16];
+ int8_t p8x8glyphs[NGLYPHS][64];
+} SANMVideoContext;
+
+typedef struct SANMFrameHeader {
+ int seq_num, codec, rotate_code, rle_output_size;
+
+ uint16_t bg_color;
+ uint32_t width, height;
+} SANMFrameHeader;
+
+enum GlyphEdge {
+ LEFT_EDGE,
+ TOP_EDGE,
+ RIGHT_EDGE,
+ BOTTOM_EDGE,
+ NO_EDGE
+};
+
+enum GlyphDir {
+ DIR_LEFT,
+ DIR_UP,
+ DIR_RIGHT,
+ DIR_DOWN,
+ NO_DIR
+};
+
+/**
+ * Return enum GlyphEdge of box where point (x, y) lies.
+ *
+ * @param x x point coordinate
+ * @param y y point coordinate
+ * @param edge_size box width/height.
+ */
+static enum GlyphEdge which_edge(int x, int y, int edge_size)
+{
+ const int edge_max = edge_size - 1;
+
+ if (!y)
+ return BOTTOM_EDGE;
+ else if (y == edge_max)
+ return TOP_EDGE;
+ else if (!x)
+ return LEFT_EDGE;
+ else if (x == edge_max)
+ return RIGHT_EDGE;
+ else
+ return NO_EDGE;
+}
+
+static enum GlyphDir which_direction(enum GlyphEdge edge0, enum GlyphEdge edge1)
+{
+ if ((edge0 == LEFT_EDGE && edge1 == RIGHT_EDGE) ||
+ (edge1 == LEFT_EDGE && edge0 == RIGHT_EDGE) ||
+ (edge0 == BOTTOM_EDGE && edge1 != TOP_EDGE) ||
+ (edge1 == BOTTOM_EDGE && edge0 != TOP_EDGE))
+ return DIR_UP;
+ else if ((edge0 == TOP_EDGE && edge1 != BOTTOM_EDGE) ||
+ (edge1 == TOP_EDGE && edge0 != BOTTOM_EDGE))
+ return DIR_DOWN;
+ else if ((edge0 == LEFT_EDGE && edge1 != RIGHT_EDGE) ||
+ (edge1 == LEFT_EDGE && edge0 != RIGHT_EDGE))
+ return DIR_LEFT;
+ else if ((edge0 == TOP_EDGE && edge1 == BOTTOM_EDGE) ||
+ (edge1 == TOP_EDGE && edge0 == BOTTOM_EDGE) ||
+ (edge0 == RIGHT_EDGE && edge1 != LEFT_EDGE) ||
+ (edge1 == RIGHT_EDGE && edge0 != LEFT_EDGE))
+ return DIR_RIGHT;
+
+ return NO_DIR;
+}
+
+/* Interpolate two points. */
+static void interp_point(int8_t *points, int x0, int y0, int x1, int y1,
+ int pos, int npoints)
+{
+ if (npoints) {
+ points[0] = (x0 * pos + x1 * (npoints - pos) + (npoints >> 1)) / npoints;
+ points[1] = (y0 * pos + y1 * (npoints - pos) + (npoints >> 1)) / npoints;
+ } else {
+ points[0] = x0;
+ points[1] = y0;
+ }
+}
+
+/**
+ * Construct glyphs by iterating through vector coordinates.
+ *
+ * @param pglyphs pointer to table where glyphs are stored
+ * @param xvec pointer to x component of vector coordinates
+ * @param yvec pointer to y component of vector coordinates
+ * @param side_length glyph width/height.
+ */
+static void make_glyphs(int8_t *pglyphs, const int8_t *xvec, const int8_t *yvec,
+ const int side_length)
+{
+ const int glyph_size = side_length * side_length;
+ int8_t *pglyph = pglyphs;
+
+ int i, j;
+ for (i = 0; i < GLYPH_COORD_VECT_SIZE; i++) {
+ int x0 = xvec[i];
+ int y0 = yvec[i];
+ enum GlyphEdge edge0 = which_edge(x0, y0, side_length);
+
+ for (j = 0; j < GLYPH_COORD_VECT_SIZE; j++, pglyph += glyph_size) {
+ int x1 = xvec[j];
+ int y1 = yvec[j];
+ enum GlyphEdge edge1 = which_edge(x1, y1, side_length);
+ enum GlyphDir dir = which_direction(edge0, edge1);
+ int npoints = FFMAX(FFABS(x1 - x0), FFABS(y1 - y0));
+ int ipoint;
+
+ for (ipoint = 0; ipoint <= npoints; ipoint++) {
+ int8_t point[2];
+ int irow, icol;
+
+ interp_point(point, x0, y0, x1, y1, ipoint, npoints);
+
+ switch (dir) {
+ case DIR_UP:
+ for (irow = point[1]; irow >= 0; irow--)
+ pglyph[point[0] + irow * side_length] = 1;
+ break;
+
+ case DIR_DOWN:
+ for (irow = point[1]; irow < side_length; irow++)
+ pglyph[point[0] + irow * side_length] = 1;
+ break;
+
+ case DIR_LEFT:
+ for (icol = point[0]; icol >= 0; icol--)
+ pglyph[icol + point[1] * side_length] = 1;
+ break;
+
+ case DIR_RIGHT:
+ for (icol = point[0]; icol < side_length; icol++)
+ pglyph[icol + point[1] * side_length] = 1;
+ break;
+ }
+ }
+ }
+ }
+}
+
+static void init_sizes(SANMVideoContext *ctx, int width, int height)
+{
+ ctx->width = width;
+ ctx->height = height;
+ ctx->npixels = width * height;
+
+ ctx->aligned_width = FFALIGN(width, 8);
+ ctx->aligned_height = FFALIGN(height, 8);
+
+ ctx->buf_size = ctx->aligned_width * ctx->aligned_height * sizeof(ctx->frm0[0]);
+ ctx->pitch = width;
+}
+
+static void destroy_buffers(SANMVideoContext *ctx)
+{
+ av_freep(&ctx->frm0);
+ av_freep(&ctx->frm1);
+ av_freep(&ctx->frm2);
+ av_freep(&ctx->stored_frame);
+ av_freep(&ctx->rle_buf);
+ ctx->frm0_size =
+ ctx->frm1_size =
+ ctx->frm2_size = 0;
+ init_sizes(ctx, 0, 0);
+}
+
+static av_cold int init_buffers(SANMVideoContext *ctx)
+{
+ av_fast_padded_mallocz(&ctx->frm0, &ctx->frm0_size, ctx->buf_size);
+ av_fast_padded_mallocz(&ctx->frm1, &ctx->frm1_size, ctx->buf_size);
+ av_fast_padded_mallocz(&ctx->frm2, &ctx->frm2_size, ctx->buf_size);
+ if (!ctx->version)
+ av_fast_padded_mallocz(&ctx->stored_frame,
+ &ctx->stored_frame_size, ctx->buf_size);
+
+ if (!ctx->frm0 || !ctx->frm1 || !ctx->frm2 ||
+ (!ctx->stored_frame && !ctx->version)) {
+ destroy_buffers(ctx);
+ return AVERROR(ENOMEM);
+ }
+
+ return 0;
+}
+
+static void rotate_bufs(SANMVideoContext *ctx, int rotate_code)
+{
+ if (rotate_code == 2)
+ FFSWAP(uint16_t*, ctx->frm1, ctx->frm2);
+ FFSWAP(uint16_t*, ctx->frm2, ctx->frm0);
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ SANMVideoContext *ctx = avctx->priv_data;
+
+ ctx->avctx = avctx;
+ ctx->version = !avctx->extradata_size;
+
+ avctx->pix_fmt = ctx->version ? AV_PIX_FMT_RGB565 : AV_PIX_FMT_PAL8;
+
+ init_sizes(ctx, avctx->width, avctx->height);
+ if (init_buffers(ctx)) {
+ av_log(avctx, AV_LOG_ERROR, "Error allocating buffers.\n");
+ return AVERROR(ENOMEM);
+ }
+
+ make_glyphs(ctx->p4x4glyphs[0], glyph4_x, glyph4_y, 4);
+ make_glyphs(ctx->p8x8glyphs[0], glyph8_x, glyph8_y, 8);
+
+ if (!ctx->version) {
+ int i;
+
+ if (avctx->extradata_size < 1026) {
+ av_log(avctx, AV_LOG_ERROR, "Not enough extradata.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ ctx->subversion = AV_RL16(avctx->extradata);
+ for (i = 0; i < PALETTE_SIZE; i++)
+ ctx->pal[i] = 0xFFU << 24 | AV_RL32(avctx->extradata + 2 + i * 4);
+ }
+
+ return 0;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ SANMVideoContext *ctx = avctx->priv_data;
+
+ destroy_buffers(ctx);
+
+ return 0;
+}
+
+static int rle_decode(SANMVideoContext *ctx, uint8_t *dst, const int out_size)
+{
+ int opcode, color, run_len, left = out_size;
+
+ while (left > 0) {
+ opcode = bytestream2_get_byte(&ctx->gb);
+ run_len = (opcode >> 1) + 1;
+ if (run_len > left || bytestream2_get_bytes_left(&ctx->gb) <= 0)
+ return AVERROR_INVALIDDATA;
+
+ if (opcode & 1) {
+ color = bytestream2_get_byte(&ctx->gb);
+ memset(dst, color, run_len);
+ } else {
+ if (bytestream2_get_bytes_left(&ctx->gb) < run_len)
+ return AVERROR_INVALIDDATA;
+ bytestream2_get_bufferu(&ctx->gb, dst, run_len);
+ }
+
+ dst += run_len;
+ left -= run_len;
+ }
+
+ return 0;
+}
+
+static int old_codec1(SANMVideoContext *ctx, int top,
+ int left, int width, int height)
+{
+ uint8_t *dst = ((uint8_t *)ctx->frm0) + left + top * ctx->pitch;
+ int i, j, len, flag, code, val, pos, end;
+
+ for (i = 0; i < height; i++) {
+ pos = 0;
+
+ if (bytestream2_get_bytes_left(&ctx->gb) < 2)
+ return AVERROR_INVALIDDATA;
+
+ len = bytestream2_get_le16u(&ctx->gb);
+ end = bytestream2_tell(&ctx->gb) + len;
+
+ while (bytestream2_tell(&ctx->gb) < end) {
+ if (bytestream2_get_bytes_left(&ctx->gb) < 2)
+ return AVERROR_INVALIDDATA;
+
+ code = bytestream2_get_byteu(&ctx->gb);
+ flag = code & 1;
+ code = (code >> 1) + 1;
+ if (pos + code > width)
+ return AVERROR_INVALIDDATA;
+ if (flag) {
+ val = bytestream2_get_byteu(&ctx->gb);
+ if (val)
+ memset(dst + pos, val, code);
+ pos += code;
+ } else {
+ if (bytestream2_get_bytes_left(&ctx->gb) < code)
+ return AVERROR_INVALIDDATA;
+ for (j = 0; j < code; j++) {
+ val = bytestream2_get_byteu(&ctx->gb);
+ if (val)
+ dst[pos] = val;
+ pos++;
+ }
+ }
+ }
+ dst += ctx->pitch;
+ }
+ ctx->rotate_code = 0;
+
+ return 0;
+}
+
+static inline void codec37_mv(uint8_t *dst, const uint8_t *src,
+ int height, int stride, int x, int y)
+{
+ int pos, i, j;
+
+ pos = x + y * stride;
+ for (j = 0; j < 4; j++) {
+ for (i = 0; i < 4; i++) {
+ if ((pos + i) < 0 || (pos + i) >= height * stride)
+ dst[i] = 0;
+ else
+ dst[i] = src[i];
+ }
+ dst += stride;
+ src += stride;
+ pos += stride;
+ }
+}
+
+static int old_codec37(SANMVideoContext *ctx, int top,
+ int left, int width, int height)
+{
+ int stride = ctx->pitch;
+ int i, j, k, t;
+ uint8_t *dst, *prev;
+ int skip_run = 0;
+ int compr = bytestream2_get_byte(&ctx->gb);
+ int mvoff = bytestream2_get_byte(&ctx->gb);
+ int seq = bytestream2_get_le16(&ctx->gb);
+ uint32_t decoded_size = bytestream2_get_le32(&ctx->gb);
+ int flags;
+
+ bytestream2_skip(&ctx->gb, 4);
+ flags = bytestream2_get_byte(&ctx->gb);
+ bytestream2_skip(&ctx->gb, 3);
+
+ if (decoded_size > ctx->height * stride - left - top * stride) {
+ decoded_size = ctx->height * stride - left - top * stride;
+ av_log(ctx->avctx, AV_LOG_WARNING, "Decoded size is too large.\n");
+ }
+
+ ctx->rotate_code = 0;
+
+ if (((seq & 1) || !(flags & 1)) && (compr && compr != 2))
+ rotate_bufs(ctx, 1);
+
+ dst = ((uint8_t*)ctx->frm0) + left + top * stride;
+ prev = ((uint8_t*)ctx->frm2) + left + top * stride;
+
+ if (mvoff > 2) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Invalid motion base value %d.\n", mvoff);
+ return AVERROR_INVALIDDATA;
+ }
+
+ switch (compr) {
+ case 0:
+ for (i = 0; i < height; i++) {
+ bytestream2_get_buffer(&ctx->gb, dst, width);
+ dst += stride;
+ }
+ memset(ctx->frm1, 0, ctx->height * stride);
+ memset(ctx->frm2, 0, ctx->height * stride);
+ break;
+ case 2:
+ if (rle_decode(ctx, dst, decoded_size))
+ return AVERROR_INVALIDDATA;
+ memset(ctx->frm1, 0, ctx->frm1_size);
+ memset(ctx->frm2, 0, ctx->frm2_size);
+ break;
+ case 3:
+ case 4:
+ if (flags & 4) {
+ for (j = 0; j < height; j += 4) {
+ for (i = 0; i < width; i += 4) {
+ int code;
+ if (skip_run) {
+ skip_run--;
+ copy_block4(dst + i, prev + i, stride, stride, 4);
+ continue;
+ }
+ if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+ return AVERROR_INVALIDDATA;
+ code = bytestream2_get_byteu(&ctx->gb);
+ switch (code) {
+ case 0xFF:
+ if (bytestream2_get_bytes_left(&ctx->gb) < 16)
+ return AVERROR_INVALIDDATA;
+ for (k = 0; k < 4; k++)
+ bytestream2_get_bufferu(&ctx->gb, dst + i + k * stride, 4);
+ break;
+ case 0xFE:
+ if (bytestream2_get_bytes_left(&ctx->gb) < 4)
+ return AVERROR_INVALIDDATA;
+ for (k = 0; k < 4; k++)
+ memset(dst + i + k * stride, bytestream2_get_byteu(&ctx->gb), 4);
+ break;
+ case 0xFD:
+ if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+ return AVERROR_INVALIDDATA;
+ t = bytestream2_get_byteu(&ctx->gb);
+ for (k = 0; k < 4; k++)
+ memset(dst + i + k * stride, t, 4);
+ break;
+ default:
+ if (compr == 4 && !code) {
+ if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+ return AVERROR_INVALIDDATA;
+ skip_run = bytestream2_get_byteu(&ctx->gb) + 1;
+ i -= 4;
+ } else {
+ int mx, my;
+
+ mx = c37_mv[(mvoff * 255 + code) * 2];
+ my = c37_mv[(mvoff * 255 + code) * 2 + 1];
+ codec37_mv(dst + i, prev + i + mx + my * stride,
+ ctx->height, stride, i + mx, j + my);
+ }
+ }
+ }
+ dst += stride * 4;
+ prev += stride * 4;
+ }
+ } else {
+ for (j = 0; j < height; j += 4) {
+ for (i = 0; i < width; i += 4) {
+ int code;
+ if (skip_run) {
+ skip_run--;
+ copy_block4(dst + i, prev + i, stride, stride, 4);
+ continue;
+ }
+ code = bytestream2_get_byte(&ctx->gb);
+ if (code == 0xFF) {
+ if (bytestream2_get_bytes_left(&ctx->gb) < 16)
+ return AVERROR_INVALIDDATA;
+ for (k = 0; k < 4; k++)
+ bytestream2_get_bufferu(&ctx->gb, dst + i + k * stride, 4);
+ } else if (compr == 4 && !code) {
+ if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+ return AVERROR_INVALIDDATA;
+ skip_run = bytestream2_get_byteu(&ctx->gb) + 1;
+ i -= 4;
+ } else {
+ int mx, my;
+
+ mx = c37_mv[(mvoff * 255 + code) * 2];
+ my = c37_mv[(mvoff * 255 + code) * 2 + 1];
+ codec37_mv(dst + i, prev + i + mx + my * stride,
+ ctx->height, stride, i + mx, j + my);
+ }
+ }
+ dst += stride * 4;
+ prev += stride * 4;
+ }
+ }
+ break;
+ default:
+ avpriv_report_missing_feature(ctx->avctx,
+ "Subcodec 37 compression %d", compr);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ return 0;
+}
+
+static int process_block(SANMVideoContext *ctx, uint8_t *dst, uint8_t *prev1,
+ uint8_t *prev2, int stride, int tbl, int size)
+{
+ int code, k, t;
+ uint8_t colors[2];
+ int8_t *pglyph;
+
+ if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+ return AVERROR_INVALIDDATA;
+
+ code = bytestream2_get_byteu(&ctx->gb);
+ if (code >= 0xF8) {
+ switch (code) {
+ case 0xFF:
+ if (size == 2) {
+ if (bytestream2_get_bytes_left(&ctx->gb) < 4)
+ return AVERROR_INVALIDDATA;
+ dst[0] = bytestream2_get_byteu(&ctx->gb);
+ dst[1] = bytestream2_get_byteu(&ctx->gb);
+ dst[0 + stride] = bytestream2_get_byteu(&ctx->gb);
+ dst[1 + stride] = bytestream2_get_byteu(&ctx->gb);
+ } else {
+ size >>= 1;
+ if (process_block(ctx, dst, prev1, prev2, stride, tbl, size))
+ return AVERROR_INVALIDDATA;
+ if (process_block(ctx, dst + size, prev1 + size, prev2 + size,
+ stride, tbl, size))
+ return AVERROR_INVALIDDATA;
+ dst += size * stride;
+ prev1 += size * stride;
+ prev2 += size * stride;
+ if (process_block(ctx, dst, prev1, prev2, stride, tbl, size))
+ return AVERROR_INVALIDDATA;
+ if (process_block(ctx, dst + size, prev1 + size, prev2 + size,
+ stride, tbl, size))
+ return AVERROR_INVALIDDATA;
+ }
+ break;
+ case 0xFE:
+ if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+ return AVERROR_INVALIDDATA;
+
+ t = bytestream2_get_byteu(&ctx->gb);
+ for (k = 0; k < size; k++)
+ memset(dst + k * stride, t, size);
+ break;
+ case 0xFD:
+ if (bytestream2_get_bytes_left(&ctx->gb) < 3)
+ return AVERROR_INVALIDDATA;
+
+ code = bytestream2_get_byteu(&ctx->gb);
+ pglyph = (size == 8) ? ctx->p8x8glyphs[code] : ctx->p4x4glyphs[code];
+ bytestream2_get_bufferu(&ctx->gb, colors, 2);
+
+ for (k = 0; k < size; k++)
+ for (t = 0; t < size; t++)
+ dst[t + k * stride] = colors[!*pglyph++];
+ break;
+ case 0xFC:
+ for (k = 0; k < size; k++)
+ memcpy(dst + k * stride, prev1 + k * stride, size);
+ break;
+ default:
+ k = bytestream2_tell(&ctx->gb);
+ bytestream2_seek(&ctx->gb, tbl + (code & 7), SEEK_SET);
+ t = bytestream2_get_byte(&ctx->gb);
+ bytestream2_seek(&ctx->gb, k, SEEK_SET);
+ for (k = 0; k < size; k++)
+ memset(dst + k * stride, t, size);
+ }
+ } else {
+ int mx = motion_vectors[code][0];
+ int my = motion_vectors[code][1];
+ int index = prev2 - (const uint8_t *)ctx->frm2;
+
+ av_assert2(index >= 0 && index < (ctx->buf_size >> 1));
+
+ if (index < -mx - my * stride ||
+ (ctx->buf_size >> 1) - index < mx + size + (my + size - 1) * stride) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "MV is invalid.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (k = 0; k < size; k++)
+ memcpy(dst + k * stride, prev2 + mx + (my + k) * stride, size);
+ }
+
+ return 0;
+}
+
+static int old_codec47(SANMVideoContext *ctx, int top,
+ int left, int width, int height)
+{
+ uint32_t decoded_size;
+ int i, j;
+ int stride = ctx->pitch;
+ uint8_t *dst = (uint8_t *)ctx->frm0 + left + top * stride;
+ uint8_t *prev1 = (uint8_t *)ctx->frm1;
+ uint8_t *prev2 = (uint8_t *)ctx->frm2;
+ int tbl_pos = bytestream2_tell(&ctx->gb);
+ int seq = bytestream2_get_le16(&ctx->gb);
+ int compr = bytestream2_get_byte(&ctx->gb);
+ int new_rot = bytestream2_get_byte(&ctx->gb);
+ int skip = bytestream2_get_byte(&ctx->gb);
+
+ bytestream2_skip(&ctx->gb, 9);
+ decoded_size = bytestream2_get_le32(&ctx->gb);
+ bytestream2_skip(&ctx->gb, 8);
+
+ if (decoded_size > ctx->height * stride - left - top * stride) {
+ decoded_size = ctx->height * stride - left - top * stride;
+ av_log(ctx->avctx, AV_LOG_WARNING, "Decoded size is too large.\n");
+ }
+
+ if (skip & 1)
+ bytestream2_skip(&ctx->gb, 0x8080);
+ if (!seq) {
+ ctx->prev_seq = -1;
+ memset(prev1, 0, ctx->height * stride);
+ memset(prev2, 0, ctx->height * stride);
+ }
+
+ switch (compr) {
+ case 0:
+ if (bytestream2_get_bytes_left(&ctx->gb) < width * height)
+ return AVERROR_INVALIDDATA;
+ for (j = 0; j < height; j++) {
+ bytestream2_get_bufferu(&ctx->gb, dst, width);
+ dst += stride;
+ }
+ break;
+ case 1:
+ if (bytestream2_get_bytes_left(&ctx->gb) < ((width + 1) >> 1) * ((height + 1) >> 1))
+ return AVERROR_INVALIDDATA;
+ for (j = 0; j < height; j += 2) {
+ for (i = 0; i < width; i += 2) {
+ dst[i] =
+ dst[i + 1] =
+ dst[stride + i] =
+ dst[stride + i + 1] = bytestream2_get_byteu(&ctx->gb);
+ }
+ dst += stride * 2;
+ }
+ break;
+ case 2:
+ if (seq == ctx->prev_seq + 1) {
+ for (j = 0; j < height; j += 8) {
+ for (i = 0; i < width; i += 8)
+ if (process_block(ctx, dst + i, prev1 + i, prev2 + i, stride,
+ tbl_pos + 8, 8))
+ return AVERROR_INVALIDDATA;
+ dst += stride * 8;
+ prev1 += stride * 8;
+ prev2 += stride * 8;
+ }
+ }
+ break;
+ case 3:
+ memcpy(ctx->frm0, ctx->frm2, ctx->pitch * ctx->height);
+ break;
+ case 4:
+ memcpy(ctx->frm0, ctx->frm1, ctx->pitch * ctx->height);
+ break;
+ case 5:
+ if (rle_decode(ctx, dst, decoded_size))
+ return AVERROR_INVALIDDATA;
+ break;
+ default:
+ avpriv_report_missing_feature(ctx->avctx,
+ "Subcodec 47 compression %d", compr);
+ return AVERROR_PATCHWELCOME;
+ }
+ if (seq == ctx->prev_seq + 1)
+ ctx->rotate_code = new_rot;
+ else
+ ctx->rotate_code = 0;
+ ctx->prev_seq = seq;
+
+ return 0;
+}
+
+static int process_frame_obj(SANMVideoContext *ctx)
+{
+ uint16_t codec = bytestream2_get_le16u(&ctx->gb);
+ uint16_t left = bytestream2_get_le16u(&ctx->gb);
+ uint16_t top = bytestream2_get_le16u(&ctx->gb);
+ uint16_t w = bytestream2_get_le16u(&ctx->gb);
+ uint16_t h = bytestream2_get_le16u(&ctx->gb);
+
+ if (!w || !h) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Dimensions are invalid.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (ctx->width < left + w || ctx->height < top + h) {
+ int ret = ff_set_dimensions(ctx->avctx, FFMAX(left + w, ctx->width),
+ FFMAX(top + h, ctx->height));
+ if (ret < 0)
+ return ret;
+ init_sizes(ctx, FFMAX(left + w, ctx->width),
+ FFMAX(top + h, ctx->height));
+ if (init_buffers(ctx)) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Error resizing buffers.\n");
+ return AVERROR(ENOMEM);
+ }
+ }
+ bytestream2_skip(&ctx->gb, 4);
+
+ switch (codec) {
+ case 1:
+ case 3:
+ return old_codec1(ctx, top, left, w, h);
+ break;
+ case 37:
+ return old_codec37(ctx, top, left, w, h);
+ break;
+ case 47:
+ return old_codec47(ctx, top, left, w, h);
+ break;
+ default:
+ avpriv_request_sample(ctx->avctx, "Subcodec %d", codec);
+ return AVERROR_PATCHWELCOME;
+ }
+}
+
+static int decode_0(SANMVideoContext *ctx)
+{
+ uint16_t *frm = ctx->frm0;
+ int x, y;
+
+ if (bytestream2_get_bytes_left(&ctx->gb) < ctx->width * ctx->height * 2) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Insufficient data for raw frame.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ for (y = 0; y < ctx->height; y++) {
+ for (x = 0; x < ctx->width; x++)
+ frm[x] = bytestream2_get_le16u(&ctx->gb);
+ frm += ctx->pitch;
+ }
+ return 0;
+}
+
+static int decode_nop(SANMVideoContext *ctx)
+{
+ avpriv_request_sample(ctx->avctx, "Unknown/unsupported compression type");
+ return AVERROR_PATCHWELCOME;
+}
+
+static void copy_block(uint16_t *pdest, uint16_t *psrc, int block_size, int pitch)
+{
+ uint8_t *dst = (uint8_t *)pdest;
+ uint8_t *src = (uint8_t *)psrc;
+ int stride = pitch * 2;
+
+ switch (block_size) {
+ case 2:
+ copy_block4(dst, src, stride, stride, 2);
+ break;
+ case 4:
+ copy_block8(dst, src, stride, stride, 4);
+ break;
+ case 8:
+ copy_block16(dst, src, stride, stride, 8);
+ break;
+ }
+}
+
+static void fill_block(uint16_t *pdest, uint16_t color, int block_size, int pitch)
+{
+ int x, y;
+
+ pitch -= block_size;
+ for (y = 0; y < block_size; y++, pdest += pitch)
+ for (x = 0; x < block_size; x++)
+ *pdest++ = color;
+}
+
+static int draw_glyph(SANMVideoContext *ctx, uint16_t *dst, int index,
+ uint16_t fg_color, uint16_t bg_color, int block_size,
+ int pitch)
+{
+ int8_t *pglyph;
+ uint16_t colors[2] = { fg_color, bg_color };
+ int x, y;
+
+ if (index >= NGLYPHS) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Ignoring nonexistent glyph #%u.\n", index);
+ return AVERROR_INVALIDDATA;
+ }
+
+ pglyph = block_size == 8 ? ctx->p8x8glyphs[index] : ctx->p4x4glyphs[index];
+ pitch -= block_size;
+
+ for (y = 0; y < block_size; y++, dst += pitch)
+ for (x = 0; x < block_size; x++)
+ *dst++ = colors[*pglyph++];
+ return 0;
+}
+
+static int opcode_0xf7(SANMVideoContext *ctx, int cx, int cy, int block_size, int pitch)
+{
+ uint16_t *dst = ctx->frm0 + cx + cy * ctx->pitch;
+
+ if (block_size == 2) {
+ uint32_t indices;
+
+ if (bytestream2_get_bytes_left(&ctx->gb) < 4)
+ return AVERROR_INVALIDDATA;
+
+ indices = bytestream2_get_le32u(&ctx->gb);
+ dst[0] = ctx->codebook[indices & 0xFF];
+ indices >>= 8;
+ dst[1] = ctx->codebook[indices & 0xFF];
+ indices >>= 8;
+ dst[pitch] = ctx->codebook[indices & 0xFF];
+ indices >>= 8;
+ dst[pitch + 1] = ctx->codebook[indices & 0xFF];
+ } else {
+ uint16_t fgcolor, bgcolor;
+ int glyph;
+
+ if (bytestream2_get_bytes_left(&ctx->gb) < 3)
+ return AVERROR_INVALIDDATA;
+
+ glyph = bytestream2_get_byteu(&ctx->gb);
+ bgcolor = ctx->codebook[bytestream2_get_byteu(&ctx->gb)];
+ fgcolor = ctx->codebook[bytestream2_get_byteu(&ctx->gb)];
+
+ draw_glyph(ctx, dst, glyph, fgcolor, bgcolor, block_size, pitch);
+ }
+ return 0;
+}
+
+static int opcode_0xf8(SANMVideoContext *ctx, int cx, int cy, int block_size, int pitch)
+{
+ uint16_t *dst = ctx->frm0 + cx + cy * ctx->pitch;
+
+ if (block_size == 2) {
+ if (bytestream2_get_bytes_left(&ctx->gb) < 8)
+ return AVERROR_INVALIDDATA;
+
+ dst[0] = bytestream2_get_le16u(&ctx->gb);
+ dst[1] = bytestream2_get_le16u(&ctx->gb);
+ dst[pitch] = bytestream2_get_le16u(&ctx->gb);
+ dst[pitch + 1] = bytestream2_get_le16u(&ctx->gb);
+ } else {
+ uint16_t fgcolor, bgcolor;
+ int glyph;
+
+ if (bytestream2_get_bytes_left(&ctx->gb) < 5)
+ return AVERROR_INVALIDDATA;
+
+ glyph = bytestream2_get_byteu(&ctx->gb);
+ bgcolor = bytestream2_get_le16u(&ctx->gb);
+ fgcolor = bytestream2_get_le16u(&ctx->gb);
+
+ draw_glyph(ctx, dst, glyph, fgcolor, bgcolor, block_size, pitch);
+ }
+ return 0;
+}
+
+static int good_mvec(SANMVideoContext *ctx, int cx, int cy, int mx, int my,
+ int block_size)
+{
+ int start_pos = cx + mx + (cy + my) * ctx->pitch;
+ int end_pos = start_pos + (block_size - 1) * (ctx->pitch + 1);
+
+ int good = start_pos >= 0 && end_pos < (ctx->buf_size >> 1);
+
+ if (!good)
+ av_log(ctx->avctx, AV_LOG_ERROR,
+ "Ignoring invalid motion vector (%i, %i)->(%u, %u), block size = %u\n",
+ cx + mx, cy + my, cx, cy, block_size);
+
+ return good;
+}
+
+static int codec2subblock(SANMVideoContext *ctx, int cx, int cy, int blk_size)
+{
+ int16_t mx, my, index;
+ int opcode;
+
+ if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+ return AVERROR_INVALIDDATA;
+
+ opcode = bytestream2_get_byteu(&ctx->gb);
+
+ switch (opcode) {
+ default:
+ mx = motion_vectors[opcode][0];
+ my = motion_vectors[opcode][1];
+
+ if (good_mvec(ctx, cx, cy, mx, my, blk_size)) {
+ copy_block(ctx->frm0 + cx + ctx->pitch * cy,
+ ctx->frm2 + cx + mx + ctx->pitch * (cy + my),
+ blk_size, ctx->pitch);
+ }
+ break;
+ case 0xF5:
+ if (bytestream2_get_bytes_left(&ctx->gb) < 2)
+ return AVERROR_INVALIDDATA;
+ index = bytestream2_get_le16u(&ctx->gb);
+
+ mx = index % ctx->width;
+ my = index / ctx->width;
+
+ if (good_mvec(ctx, cx, cy, mx, my, blk_size)) {
+ copy_block(ctx->frm0 + cx + ctx->pitch * cy,
+ ctx->frm2 + cx + mx + ctx->pitch * (cy + my),
+ blk_size, ctx->pitch);
+ }
+ break;
+ case 0xF6:
+ copy_block(ctx->frm0 + cx + ctx->pitch * cy,
+ ctx->frm1 + cx + ctx->pitch * cy,
+ blk_size, ctx->pitch);
+ break;
+ case 0xF7:
+ opcode_0xf7(ctx, cx, cy, blk_size, ctx->pitch);
+ break;
+
+ case 0xF8:
+ opcode_0xf8(ctx, cx, cy, blk_size, ctx->pitch);
+ break;
+ case 0xF9:
+ case 0xFA:
+ case 0xFB:
+ case 0xFC:
+ fill_block(ctx->frm0 + cx + cy * ctx->pitch,
+ ctx->small_codebook[opcode - 0xf9], blk_size, ctx->pitch);
+ break;
+ case 0xFD:
+ if (bytestream2_get_bytes_left(&ctx->gb) < 1)
+ return AVERROR_INVALIDDATA;
+ fill_block(ctx->frm0 + cx + cy * ctx->pitch,
+ ctx->codebook[bytestream2_get_byteu(&ctx->gb)], blk_size, ctx->pitch);
+ break;
+ case 0xFE:
+ if (bytestream2_get_bytes_left(&ctx->gb) < 2)
+ return AVERROR_INVALIDDATA;
+ fill_block(ctx->frm0 + cx + cy * ctx->pitch,
+ bytestream2_get_le16u(&ctx->gb), blk_size, ctx->pitch);
+ break;
+ case 0xFF:
+ if (blk_size == 2) {
+ opcode_0xf8(ctx, cx, cy, blk_size, ctx->pitch);
+ } else {
+ blk_size >>= 1;
+ if (codec2subblock(ctx, cx, cy, blk_size))
+ return AVERROR_INVALIDDATA;
+ if (codec2subblock(ctx, cx + blk_size, cy, blk_size))
+ return AVERROR_INVALIDDATA;
+ if (codec2subblock(ctx, cx, cy + blk_size, blk_size))
+ return AVERROR_INVALIDDATA;
+ if (codec2subblock(ctx, cx + blk_size, cy + blk_size, blk_size))
+ return AVERROR_INVALIDDATA;
+ }
+ break;
+ }
+ return 0;
+}
+
+static int decode_2(SANMVideoContext *ctx)
+{
+ int cx, cy, ret;
+
+ for (cy = 0; cy < ctx->aligned_height; cy += 8)
+ for (cx = 0; cx < ctx->aligned_width; cx += 8)
+ if (ret = codec2subblock(ctx, cx, cy, 8))
+ return ret;
+
+ return 0;
+}
+
+static int decode_3(SANMVideoContext *ctx)
+{
+ memcpy(ctx->frm0, ctx->frm2, ctx->frm2_size);
+ return 0;
+}
+
+static int decode_4(SANMVideoContext *ctx)
+{
+ memcpy(ctx->frm0, ctx->frm1, ctx->frm1_size);
+ return 0;
+}
+
+static int decode_5(SANMVideoContext *ctx)
+{
+#if HAVE_BIGENDIAN
+ uint16_t *frm;
+ int npixels;
+#endif
+ uint8_t *dst = (uint8_t*)ctx->frm0;
+
+ if (rle_decode(ctx, dst, ctx->buf_size))
+ return AVERROR_INVALIDDATA;
+
+#if HAVE_BIGENDIAN
+ npixels = ctx->npixels;
+ frm = ctx->frm0;
+ while (npixels--) {
+ *frm = av_bswap16(*frm);
+ frm++;
+ }
+#endif
+
+ return 0;
+}
+
+static int decode_6(SANMVideoContext *ctx)
+{
+ int npixels = ctx->npixels;
+ uint16_t *frm = ctx->frm0;
+
+ if (bytestream2_get_bytes_left(&ctx->gb) < npixels) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Insufficient data for frame.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ while (npixels--)
+ *frm++ = ctx->codebook[bytestream2_get_byteu(&ctx->gb)];
+
+ return 0;
+}
+
+static int decode_8(SANMVideoContext *ctx)
+{
+ uint16_t *pdest = ctx->frm0;
+ uint8_t *rsrc;
+ long npixels = ctx->npixels;
+
+ av_fast_malloc(&ctx->rle_buf, &ctx->rle_buf_size, npixels);
+ if (!ctx->rle_buf) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "RLE buffer allocation failed.\n");
+ return AVERROR(ENOMEM);
+ }
+ rsrc = ctx->rle_buf;
+
+ if (rle_decode(ctx, rsrc, npixels))
+ return AVERROR_INVALIDDATA;
+
+ while (npixels--)
+ *pdest++ = ctx->codebook[*rsrc++];
+
+ return 0;
+}
+
+typedef int (*frm_decoder)(SANMVideoContext *ctx);
+
+static const frm_decoder v1_decoders[] = {
+ decode_0, decode_nop, decode_2, decode_3, decode_4, decode_5,
+ decode_6, decode_nop, decode_8
+};
+
+static int read_frame_header(SANMVideoContext *ctx, SANMFrameHeader *hdr)
+{
+ int i, ret;
+
+ if ((ret = bytestream2_get_bytes_left(&ctx->gb)) < 560) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Input frame too short (%d bytes).\n",
+ ret);
+ return AVERROR_INVALIDDATA;
+ }
+ bytestream2_skip(&ctx->gb, 8); // skip pad
+
+ hdr->width = bytestream2_get_le32u(&ctx->gb);
+ hdr->height = bytestream2_get_le32u(&ctx->gb);
+
+ if (hdr->width != ctx->width || hdr->height != ctx->height) {
+ avpriv_report_missing_feature(ctx->avctx, "Variable size frames");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ hdr->seq_num = bytestream2_get_le16u(&ctx->gb);
+ hdr->codec = bytestream2_get_byteu(&ctx->gb);
+ hdr->rotate_code = bytestream2_get_byteu(&ctx->gb);
+
+ bytestream2_skip(&ctx->gb, 4); // skip pad
+
+ for (i = 0; i < 4; i++)
+ ctx->small_codebook[i] = bytestream2_get_le16u(&ctx->gb);
+ hdr->bg_color = bytestream2_get_le16u(&ctx->gb);
+
+ bytestream2_skip(&ctx->gb, 2); // skip pad
+
+ hdr->rle_output_size = bytestream2_get_le32u(&ctx->gb);
+ for (i = 0; i < 256; i++)
+ ctx->codebook[i] = bytestream2_get_le16u(&ctx->gb);
+
+ bytestream2_skip(&ctx->gb, 8); // skip pad
+
+ return 0;
+}
+
+static void fill_frame(uint16_t *pbuf, int buf_size, uint16_t color)
+{
+ while (buf_size--)
+ *pbuf++ = color;
+}
+
+static int copy_output(SANMVideoContext *ctx, SANMFrameHeader *hdr)
+{
+ uint8_t *dst;
+ const uint8_t *src = (uint8_t*) ctx->frm0;
+ int ret, dstpitch, height = ctx->height;
+ int srcpitch = ctx->pitch * (hdr ? sizeof(ctx->frm0[0]) : 1);
+
+ if ((ret = ff_get_buffer(ctx->avctx, ctx->frame, 0)) < 0)
+ return ret;
+
+ dst = ctx->frame->data[0];
+ dstpitch = ctx->frame->linesize[0];
+
+ while (height--) {
+ memcpy(dst, src, srcpitch);
+ src += srcpitch;
+ dst += dstpitch;
+ }
+
+ return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *pkt)
+{
+ SANMVideoContext *ctx = avctx->priv_data;
+ int i, ret;
+
+ ctx->frame = data;
+ bytestream2_init(&ctx->gb, pkt->data, pkt->size);
+
+ if (!ctx->version) {
+ int to_store = 0;
+
+ while (bytestream2_get_bytes_left(&ctx->gb) >= 8) {
+ uint32_t sig, size;
+ int pos;
+
+ sig = bytestream2_get_be32u(&ctx->gb);
+ size = bytestream2_get_be32u(&ctx->gb);
+ pos = bytestream2_tell(&ctx->gb);
+
+ if (bytestream2_get_bytes_left(&ctx->gb) < size) {
+ av_log(avctx, AV_LOG_ERROR, "Incorrect chunk size %"PRIu32".\n", size);
+ break;
+ }
+ switch (sig) {
+ case MKBETAG('N', 'P', 'A', 'L'):
+ if (size != PALETTE_SIZE * 3) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Incorrect palette block size %"PRIu32".\n", size);
+ return AVERROR_INVALIDDATA;
+ }
+ for (i = 0; i < PALETTE_SIZE; i++)
+ ctx->pal[i] = 0xFFU << 24 | bytestream2_get_be24u(&ctx->gb);
+ break;
+ case MKBETAG('F', 'O', 'B', 'J'):
+ if (size < 16)
+ return AVERROR_INVALIDDATA;
+ if (ret = process_frame_obj(ctx))
+ return ret;
+ break;
+ case MKBETAG('X', 'P', 'A', 'L'):
+ if (size == 6 || size == 4) {
+ uint8_t tmp[3];
+ int j;
+
+ for (i = 0; i < PALETTE_SIZE; i++) {
+ for (j = 0; j < 3; j++) {
+ int t = (ctx->pal[i] >> (16 - j * 8)) & 0xFF;
+ tmp[j] = av_clip_uint8((t * 129 + ctx->delta_pal[i * 3 + j]) >> 7);
+ }
+ ctx->pal[i] = 0xFFU << 24 | AV_RB24(tmp);
+ }
+ } else {
+ if (size < PALETTE_DELTA * 2 + 4) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Incorrect palette change block size %"PRIu32".\n",
+ size);
+ return AVERROR_INVALIDDATA;
+ }
+ bytestream2_skipu(&ctx->gb, 4);
+ for (i = 0; i < PALETTE_DELTA; i++)
+ ctx->delta_pal[i] = bytestream2_get_le16u(&ctx->gb);
+ if (size >= PALETTE_DELTA * 5 + 4) {
+ for (i = 0; i < PALETTE_SIZE; i++)
+ ctx->pal[i] = 0xFFU << 24 | bytestream2_get_be24u(&ctx->gb);
+ } else {
+ memset(ctx->pal, 0, sizeof(ctx->pal));
+ }
+ }
+ break;
+ case MKBETAG('S', 'T', 'O', 'R'):
+ to_store = 1;
+ break;
+ case MKBETAG('F', 'T', 'C', 'H'):
+ memcpy(ctx->frm0, ctx->stored_frame, ctx->buf_size);
+ break;
+ default:
+ bytestream2_skip(&ctx->gb, size);
+ av_log(avctx, AV_LOG_DEBUG,
+ "Unknown/unsupported chunk %"PRIx32".\n", sig);
+ break;
+ }
+
+ bytestream2_seek(&ctx->gb, pos + size, SEEK_SET);
+ if (size & 1)
+ bytestream2_skip(&ctx->gb, 1);
+ }
+ if (to_store)
+ memcpy(ctx->stored_frame, ctx->frm0, ctx->buf_size);
+ if ((ret = copy_output(ctx, NULL)))
+ return ret;
+ memcpy(ctx->frame->data[1], ctx->pal, 1024);
+ } else {
+ SANMFrameHeader header;
+
+ if ((ret = read_frame_header(ctx, &header)))
+ return ret;
+
+ ctx->rotate_code = header.rotate_code;
+ if ((ctx->frame->key_frame = !header.seq_num)) {
+ ctx->frame->pict_type = AV_PICTURE_TYPE_I;
+ fill_frame(ctx->frm1, ctx->npixels, header.bg_color);
+ fill_frame(ctx->frm2, ctx->npixels, header.bg_color);
+ } else {
+ ctx->frame->pict_type = AV_PICTURE_TYPE_P;
+ }
+
+ if (header.codec < FF_ARRAY_ELEMS(v1_decoders)) {
+ if ((ret = v1_decoders[header.codec](ctx))) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Subcodec %d: error decoding frame.\n", header.codec);
+ return ret;
+ }
+ } else {
+ avpriv_request_sample(avctx, "Subcodec %d", header.codec);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if ((ret = copy_output(ctx, &header)))
+ return ret;
+ }
+ if (ctx->rotate_code)
+ rotate_bufs(ctx, ctx->rotate_code);
+
+ *got_frame_ptr = 1;
+
+ return pkt->size;
+}
+
+AVCodec ff_sanm_decoder = {
+ .name = "sanm",
+ .long_name = NULL_IF_CONFIG_SMALL("LucasArts SANM/Smush video"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_SANM,
+ .priv_data_size = sizeof(SANMVideoContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/sbr.h b/ffmpeg-2-8-12/libavcodec/sbr.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sbr.h
rename to ffmpeg-2-8-12/libavcodec/sbr.h
diff --git a/ffmpeg-2-8-11/libavcodec/sbrdsp.c b/ffmpeg-2-8-12/libavcodec/sbrdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sbrdsp.c
rename to ffmpeg-2-8-12/libavcodec/sbrdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/sbrdsp.h b/ffmpeg-2-8-12/libavcodec/sbrdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sbrdsp.h
rename to ffmpeg-2-8-12/libavcodec/sbrdsp.h
diff --git a/ffmpeg-2-8-12/libavcodec/sbrdsp_fixed.c b/ffmpeg-2-8-12/libavcodec/sbrdsp_fixed.c
new file mode 100644
index 0000000..924da83
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/sbrdsp_fixed.c
@@ -0,0 +1,291 @@
+/*
+ * AAC Spectral Band Replication decoding functions
+ * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
+ * Copyright (c) 2009-2010 Alex Converse <alex.converse at gmail.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
+ *
+ * Note: Rounding-to-nearest used unless otherwise stated
+ *
+ */
+
+#define USE_FIXED 1
+
+#include "aac.h"
+#include "config.h"
+#include "libavutil/attributes.h"
+#include "libavutil/intfloat.h"
+#include "sbrdsp.h"
+
+static SoftFloat sbr_sum_square_c(int (*x)[2], int n)
+{
+ SoftFloat ret;
+ int64_t accu = 0;
+ int i, nz, round;
+
+ for (i = 0; i < n; i += 2) {
+ // Larger values are inavlid and could cause overflows of accu.
+ av_assert2(FFABS(x[i + 0][0]) >> 29 == 0);
+ accu += (int64_t)x[i + 0][0] * x[i + 0][0];
+ av_assert2(FFABS(x[i + 0][1]) >> 29 == 0);
+ accu += (int64_t)x[i + 0][1] * x[i + 0][1];
+ av_assert2(FFABS(x[i + 1][0]) >> 29 == 0);
+ accu += (int64_t)x[i + 1][0] * x[i + 1][0];
+ av_assert2(FFABS(x[i + 1][1]) >> 29 == 0);
+ accu += (int64_t)x[i + 1][1] * x[i + 1][1];
+ }
+
+ i = (int)(accu >> 32);
+ if (i == 0) {
+ nz = 1;
+ } else {
+ nz = 0;
+ while (FFABS(i) < 0x40000000) {
+ i <<= 1;
+ nz++;
+ }
+ nz = 32 - nz;
+ }
+
+ round = 1 << (nz-1);
+ i = (int)((accu + round) >> nz);
+ i >>= 1;
+ ret = av_int2sf(i, 15 - nz);
+
+ return ret;
+}
+
+static void sbr_neg_odd_64_c(int *x)
+{
+ int i;
+ for (i = 1; i < 64; i += 2)
+ x[i] = -x[i];
+}
+
+static void sbr_qmf_pre_shuffle_c(int *z)
+{
+ int k;
+ z[64] = z[0];
+ z[65] = z[1];
+ for (k = 1; k < 32; k++) {
+ z[64+2*k ] = -z[64 - k];
+ z[64+2*k+1] = z[ k + 1];
+ }
+}
+
+static void sbr_qmf_post_shuffle_c(int W[32][2], const int *z)
+{
+ int k;
+ for (k = 0; k < 32; k++) {
+ W[k][0] = -z[63-k];
+ W[k][1] = z[k];
+ }
+}
+
+static void sbr_qmf_deint_neg_c(int *v, const int *src)
+{
+ int i;
+ for (i = 0; i < 32; i++) {
+ v[ i] = ( src[63 - 2*i ] + 0x10) >> 5;
+ v[63 - i] = (-src[63 - 2*i - 1] + 0x10) >> 5;
+ }
+}
+
+static av_always_inline SoftFloat autocorr_calc(int64_t accu)
+{
+ int nz, mant, expo, round;
+ int i = (int)(accu >> 32);
+ if (i == 0) {
+ nz = 1;
+ } else {
+ nz = 0;
+ while (FFABS(i) < 0x40000000) {
+ i <<= 1;
+ nz++;
+ }
+ nz = 32-nz;
+ }
+
+ round = 1 << (nz-1);
+ mant = (int)((accu + round) >> nz);
+ mant = (mant + 0x40)>>7;
+ mant <<= 6;
+ expo = nz + 15;
+ return av_int2sf(mant, 30 - expo);
+}
+
+static av_always_inline void autocorrelate(const int x[40][2], SoftFloat phi[3][2][2], int lag)
+{
+ int i;
+ int64_t real_sum, imag_sum;
+ int64_t accu_re = 0, accu_im = 0;
+
+ if (lag) {
+ for (i = 1; i < 38; i++) {
+ accu_re += (int64_t)x[i][0] * x[i+lag][0];
+ accu_re += (int64_t)x[i][1] * x[i+lag][1];
+ accu_im += (int64_t)x[i][0] * x[i+lag][1];
+ accu_im -= (int64_t)x[i][1] * x[i+lag][0];
+ }
+
+ real_sum = accu_re;
+ imag_sum = accu_im;
+
+ accu_re += (int64_t)x[ 0][0] * x[lag][0];
+ accu_re += (int64_t)x[ 0][1] * x[lag][1];
+ accu_im += (int64_t)x[ 0][0] * x[lag][1];
+ accu_im -= (int64_t)x[ 0][1] * x[lag][0];
+
+ phi[2-lag][1][0] = autocorr_calc(accu_re);
+ phi[2-lag][1][1] = autocorr_calc(accu_im);
+
+ if (lag == 1) {
+ accu_re = real_sum;
+ accu_im = imag_sum;
+ accu_re += (int64_t)x[38][0] * x[39][0];
+ accu_re += (int64_t)x[38][1] * x[39][1];
+ accu_im += (int64_t)x[38][0] * x[39][1];
+ accu_im -= (int64_t)x[38][1] * x[39][0];
+
+ phi[0][0][0] = autocorr_calc(accu_re);
+ phi[0][0][1] = autocorr_calc(accu_im);
+ }
+ } else {
+ for (i = 1; i < 38; i++) {
+ accu_re += (int64_t)x[i][0] * x[i][0];
+ accu_re += (int64_t)x[i][1] * x[i][1];
+ }
+ real_sum = accu_re;
+ accu_re += (int64_t)x[ 0][0] * x[ 0][0];
+ accu_re += (int64_t)x[ 0][1] * x[ 0][1];
+
+ phi[2][1][0] = autocorr_calc(accu_re);
+
+ accu_re = real_sum;
+ accu_re += (int64_t)x[38][0] * x[38][0];
+ accu_re += (int64_t)x[38][1] * x[38][1];
+
+ phi[1][0][0] = autocorr_calc(accu_re);
+ }
+}
+
+static void sbr_autocorrelate_c(const int x[40][2], SoftFloat phi[3][2][2])
+{
+ autocorrelate(x, phi, 0);
+ autocorrelate(x, phi, 1);
+ autocorrelate(x, phi, 2);
+}
+
+static void sbr_hf_gen_c(int (*X_high)[2], const int (*X_low)[2],
+ const int alpha0[2], const int alpha1[2],
+ int bw, int start, int end)
+{
+ int alpha[4];
+ int i;
+ int64_t accu;
+
+ accu = (int64_t)alpha0[0] * bw;
+ alpha[2] = (int)((accu + 0x40000000) >> 31);
+ accu = (int64_t)alpha0[1] * bw;
+ alpha[3] = (int)((accu + 0x40000000) >> 31);
+ accu = (int64_t)bw * bw;
+ bw = (int)((accu + 0x40000000) >> 31);
+ accu = (int64_t)alpha1[0] * bw;
+ alpha[0] = (int)((accu + 0x40000000) >> 31);
+ accu = (int64_t)alpha1[1] * bw;
+ alpha[1] = (int)((accu + 0x40000000) >> 31);
+
+ for (i = start; i < end; i++) {
+ accu = (int64_t)X_low[i][0] * 0x20000000;
+ accu += (int64_t)X_low[i - 2][0] * alpha[0];
+ accu -= (int64_t)X_low[i - 2][1] * alpha[1];
+ accu += (int64_t)X_low[i - 1][0] * alpha[2];
+ accu -= (int64_t)X_low[i - 1][1] * alpha[3];
+ X_high[i][0] = (int)((accu + 0x10000000) >> 29);
+
+ accu = (int64_t)X_low[i][1] * 0x20000000;
+ accu += (int64_t)X_low[i - 2][1] * alpha[0];
+ accu += (int64_t)X_low[i - 2][0] * alpha[1];
+ accu += (int64_t)X_low[i - 1][1] * alpha[2];
+ accu += (int64_t)X_low[i - 1][0] * alpha[3];
+ X_high[i][1] = (int)((accu + 0x10000000) >> 29);
+ }
+}
+
+static void sbr_hf_g_filt_c(int (*Y)[2], const int (*X_high)[40][2],
+ const SoftFloat *g_filt, int m_max, intptr_t ixh)
+{
+ int m;
+ int64_t accu;
+
+ for (m = 0; m < m_max; m++) {
+ int64_t r = 1LL << (22-g_filt[m].exp);
+ accu = (int64_t)X_high[m][ixh][0] * ((g_filt[m].mant + 0x40)>>7);
+ Y[m][0] = (int)((accu + r) >> (23-g_filt[m].exp));
+
+ accu = (int64_t)X_high[m][ixh][1] * ((g_filt[m].mant + 0x40)>>7);
+ Y[m][1] = (int)((accu + r) >> (23-g_filt[m].exp));
+ }
+}
+
+static av_always_inline void sbr_hf_apply_noise(int (*Y)[2],
+ const SoftFloat *s_m,
+ const SoftFloat *q_filt,
+ int noise,
+ int phi_sign0,
+ int phi_sign1,
+ int m_max)
+{
+ int m;
+
+ for (m = 0; m < m_max; m++) {
+ int y0 = Y[m][0];
+ int y1 = Y[m][1];
+ noise = (noise + 1) & 0x1ff;
+ if (s_m[m].mant) {
+ int shift, round;
+
+ shift = 22 - s_m[m].exp;
+ if (shift < 30) {
+ round = 1 << (shift-1);
+ y0 += (s_m[m].mant * phi_sign0 + round) >> shift;
+ y1 += (s_m[m].mant * phi_sign1 + round) >> shift;
+ }
+ } else {
+ int shift, round, tmp;
+ int64_t accu;
+
+ shift = 22 - q_filt[m].exp;
+ if (shift < 30) {
+ round = 1 << (shift-1);
+
+ accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][0];
+ tmp = (int)((accu + 0x40000000) >> 31);
+ y0 += (tmp + round) >> shift;
+
+ accu = (int64_t)q_filt[m].mant * ff_sbr_noise_table_fixed[noise][1];
+ tmp = (int)((accu + 0x40000000) >> 31);
+ y1 += (tmp + round) >> shift;
+ }
+ }
+ Y[m][0] = y0;
+ Y[m][1] = y1;
+ phi_sign1 = -phi_sign1;
+ }
+}
+
+#include "sbrdsp_template.c"
diff --git a/ffmpeg-2-8-12/libavcodec/sbrdsp_template.c b/ffmpeg-2-8-12/libavcodec/sbrdsp_template.c
new file mode 100644
index 0000000..897a3bb
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/sbrdsp_template.c
@@ -0,0 +1,102 @@
+/*
+ * AAC Spectral Band Replication decoding functions
+ * Copyright (c) 2008-2009 Robert Swain ( rob opendot cl )
+ * Copyright (c) 2009-2010 Alex Converse <alex.converse at gmail.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
+ */
+
+static void sbr_sum64x5_c(INTFLOAT *z)
+{
+ int k;
+ for (k = 0; k < 64; k++) {
+ INTFLOAT f = z[k] + z[k + 64] + z[k + 128] + z[k + 192] + z[k + 256];
+ z[k] = f;
+ }
+}
+
+static void sbr_qmf_deint_bfly_c(INTFLOAT *v, const INTFLOAT *src0, const INTFLOAT *src1)
+{
+ int i;
+ for (i = 0; i < 64; i++) {
+#if USE_FIXED
+ v[ i] = (int)(0x10U + src0[i] - src1[63 - i]) >> 5;
+ v[127 - i] = (int)(0x10U + src0[i] + src1[63 - i]) >> 5;
+#else
+ v[ i] = src0[i] - src1[63 - i];
+ v[127 - i] = src0[i] + src1[63 - i];
+#endif
+ }
+}
+
+static void sbr_hf_apply_noise_0(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m,
+ const AAC_FLOAT *q_filt, int noise,
+ int kx, int m_max)
+{
+ sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)1.0, (INTFLOAT)0.0, m_max);
+}
+
+static void sbr_hf_apply_noise_1(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m,
+ const AAC_FLOAT *q_filt, int noise,
+ int kx, int m_max)
+{
+ INTFLOAT phi_sign = 1 - 2 * (kx & 1);
+ sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)0.0, phi_sign, m_max);
+}
+
+static void sbr_hf_apply_noise_2(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m,
+ const AAC_FLOAT *q_filt, int noise,
+ int kx, int m_max)
+{
+ sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)-1.0, (INTFLOAT)0.0, m_max);
+}
+
+static void sbr_hf_apply_noise_3(INTFLOAT (*Y)[2], const AAC_FLOAT *s_m,
+ const AAC_FLOAT *q_filt, int noise,
+ int kx, int m_max)
+{
+ INTFLOAT phi_sign = 1 - 2 * (kx & 1);
+ sbr_hf_apply_noise(Y, s_m, q_filt, noise, (INTFLOAT)0.0, -phi_sign, m_max);
+}
+
+av_cold void AAC_RENAME(ff_sbrdsp_init)(SBRDSPContext *s)
+{
+ s->sum64x5 = sbr_sum64x5_c;
+ s->sum_square = sbr_sum_square_c;
+ s->neg_odd_64 = sbr_neg_odd_64_c;
+ s->qmf_pre_shuffle = sbr_qmf_pre_shuffle_c;
+ s->qmf_post_shuffle = sbr_qmf_post_shuffle_c;
+ s->qmf_deint_neg = sbr_qmf_deint_neg_c;
+ s->qmf_deint_bfly = sbr_qmf_deint_bfly_c;
+ s->autocorrelate = sbr_autocorrelate_c;
+ s->hf_gen = sbr_hf_gen_c;
+ s->hf_g_filt = sbr_hf_g_filt_c;
+
+ s->hf_apply_noise[0] = sbr_hf_apply_noise_0;
+ s->hf_apply_noise[1] = sbr_hf_apply_noise_1;
+ s->hf_apply_noise[2] = sbr_hf_apply_noise_2;
+ s->hf_apply_noise[3] = sbr_hf_apply_noise_3;
+
+#if !USE_FIXED
+ if (ARCH_ARM)
+ ff_sbrdsp_init_arm(s);
+ if (ARCH_X86)
+ ff_sbrdsp_init_x86(s);
+ if (ARCH_MIPS)
+ ff_sbrdsp_init_mips(s);
+#endif /* !USE_FIXED */
+}
diff --git a/ffmpeg-2-8-11/libavcodec/sgi.h b/ffmpeg-2-8-12/libavcodec/sgi.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sgi.h
rename to ffmpeg-2-8-12/libavcodec/sgi.h
diff --git a/ffmpeg-2-8-11/libavcodec/sgidec.c b/ffmpeg-2-8-12/libavcodec/sgidec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sgidec.c
rename to ffmpeg-2-8-12/libavcodec/sgidec.c
diff --git a/ffmpeg-2-8-11/libavcodec/sgienc.c b/ffmpeg-2-8-12/libavcodec/sgienc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sgienc.c
rename to ffmpeg-2-8-12/libavcodec/sgienc.c
diff --git a/ffmpeg-2-8-11/libavcodec/sgirledec.c b/ffmpeg-2-8-12/libavcodec/sgirledec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sgirledec.c
rename to ffmpeg-2-8-12/libavcodec/sgirledec.c
diff --git a/ffmpeg-2-8-11/libavcodec/sh4/README b/ffmpeg-2-8-12/libavcodec/sh4/README
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sh4/README
rename to ffmpeg-2-8-12/libavcodec/sh4/README
diff --git a/ffmpeg-2-8-12/libavcodec/shorten.c b/ffmpeg-2-8-12/libavcodec/shorten.c
new file mode 100644
index 0000000..32f808b
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/shorten.c
@@ -0,0 +1,690 @@
+/*
+ * Shorten decoder
+ * Copyright (c) 2005 Jeff Muizelaar
+ *
+ * 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
+ * Shorten decoder
+ * @author Jeff Muizelaar
+ *
+ */
+
+#include <limits.h>
+#include "avcodec.h"
+#include "bytestream.h"
+#include "get_bits.h"
+#include "golomb.h"
+#include "internal.h"
+
+#define MAX_CHANNELS 8
+#define MAX_BLOCKSIZE 65535
+
+#define OUT_BUFFER_SIZE 16384
+
+#define ULONGSIZE 2
+
+#define WAVE_FORMAT_PCM 0x0001
+
+#define DEFAULT_BLOCK_SIZE 256
+
+#define TYPESIZE 4
+#define CHANSIZE 0
+#define LPCQSIZE 2
+#define ENERGYSIZE 3
+#define BITSHIFTSIZE 2
+
+#define TYPE_S8 1
+#define TYPE_U8 2
+#define TYPE_S16HL 3
+#define TYPE_U16HL 4
+#define TYPE_S16LH 5
+#define TYPE_U16LH 6
+
+#define NWRAP 3
+#define NSKIPSIZE 1
+
+#define LPCQUANT 5
+#define V2LPCQOFFSET (1 << LPCQUANT)
+
+#define FNSIZE 2
+#define FN_DIFF0 0
+#define FN_DIFF1 1
+#define FN_DIFF2 2
+#define FN_DIFF3 3
+#define FN_QUIT 4
+#define FN_BLOCKSIZE 5
+#define FN_BITSHIFT 6
+#define FN_QLPC 7
+#define FN_ZERO 8
+#define FN_VERBATIM 9
+
+/** indicates if the FN_* command is audio or non-audio */
+static const uint8_t is_audio_command[10] = { 1, 1, 1, 1, 0, 0, 0, 1, 1, 0 };
+
+#define VERBATIM_CKSIZE_SIZE 5
+#define VERBATIM_BYTE_SIZE 8
+#define CANONICAL_HEADER_SIZE 44
+
+typedef struct ShortenContext {
+ AVCodecContext *avctx;
+ GetBitContext gb;
+
+ int min_framesize, max_framesize;
+ unsigned channels;
+
+ int32_t *decoded[MAX_CHANNELS];
+ int32_t *decoded_base[MAX_CHANNELS];
+ int32_t *offset[MAX_CHANNELS];
+ int *coeffs;
+ uint8_t *bitstream;
+ int bitstream_size;
+ int bitstream_index;
+ unsigned int allocated_bitstream_size;
+ int header_size;
+ uint8_t header[OUT_BUFFER_SIZE];
+ int version;
+ int cur_chan;
+ int bitshift;
+ int nmean;
+ int internal_ftype;
+ int nwrap;
+ int blocksize;
+ int bitindex;
+ int32_t lpcqoffset;
+ int got_header;
+ int got_quit_command;
+} ShortenContext;
+
+static av_cold int shorten_decode_init(AVCodecContext *avctx)
+{
+ ShortenContext *s = avctx->priv_data;
+ s->avctx = avctx;
+
+ return 0;
+}
+
+static int allocate_buffers(ShortenContext *s)
+{
+ int i, chan, err;
+
+ for (chan = 0; chan < s->channels; chan++) {
+ if (FFMAX(1, s->nmean) >= UINT_MAX / sizeof(int32_t)) {
+ av_log(s->avctx, AV_LOG_ERROR, "nmean too large\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->blocksize + (uint64_t)s->nwrap >= UINT_MAX / sizeof(int32_t)) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "s->blocksize + s->nwrap too large\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if ((err = av_reallocp_array(&s->offset[chan],
+ sizeof(int32_t),
+ FFMAX(1, s->nmean))) < 0)
+ return err;
+
+ if ((err = av_reallocp_array(&s->decoded_base[chan], (s->blocksize + s->nwrap),
+ sizeof(s->decoded_base[0][0]))) < 0)
+ return err;
+ for (i = 0; i < s->nwrap; i++)
+ s->decoded_base[chan][i] = 0;
+ s->decoded[chan] = s->decoded_base[chan] + s->nwrap;
+ }
+
+ if ((err = av_reallocp_array(&s->coeffs, s->nwrap, sizeof(*s->coeffs))) < 0)
+ return err;
+
+ return 0;
+}
+
+static inline unsigned int get_uint(ShortenContext *s, int k)
+{
+ if (s->version != 0) {
+ k = get_ur_golomb_shorten(&s->gb, ULONGSIZE);
+ if (k > 31U)
+ return AVERROR_INVALIDDATA;
+ }
+ return get_ur_golomb_shorten(&s->gb, k);
+}
+
+static void fix_bitshift(ShortenContext *s, int32_t *buffer)
+{
+ int i;
+
+ if (s->bitshift != 0)
+ for (i = 0; i < s->blocksize; i++)
+ buffer[i] <<= s->bitshift;
+}
+
+static int init_offset(ShortenContext *s)
+{
+ int32_t mean = 0;
+ int chan, i;
+ int nblock = FFMAX(1, s->nmean);
+ /* initialise offset */
+ switch (s->internal_ftype) {
+ case TYPE_U8:
+ s->avctx->sample_fmt = AV_SAMPLE_FMT_U8P;
+ mean = 0x80;
+ break;
+ case TYPE_S16HL:
+ case TYPE_S16LH:
+ s->avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+ break;
+ default:
+ av_log(s->avctx, AV_LOG_ERROR, "unknown audio type\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ for (chan = 0; chan < s->channels; chan++)
+ for (i = 0; i < nblock; i++)
+ s->offset[chan][i] = mean;
+ return 0;
+}
+
+static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header,
+ int header_size)
+{
+ int len, bps;
+ short wave_format;
+ GetByteContext gb;
+
+ bytestream2_init(&gb, header, header_size);
+
+ if (bytestream2_get_le32(&gb) != MKTAG('R', 'I', 'F', 'F')) {
+ av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ bytestream2_skip(&gb, 4); /* chunk size */
+
+ if (bytestream2_get_le32(&gb) != MKTAG('W', 'A', 'V', 'E')) {
+ av_log(avctx, AV_LOG_ERROR, "missing WAVE tag\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ while (bytestream2_get_le32(&gb) != MKTAG('f', 'm', 't', ' ')) {
+ len = bytestream2_get_le32(&gb);
+ bytestream2_skip(&gb, len);
+ if (len < 0 || bytestream2_get_bytes_left(&gb) < 16) {
+ av_log(avctx, AV_LOG_ERROR, "no fmt chunk found\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ len = bytestream2_get_le32(&gb);
+
+ if (len < 16) {
+ av_log(avctx, AV_LOG_ERROR, "fmt chunk was too short\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ wave_format = bytestream2_get_le16(&gb);
+
+ switch (wave_format) {
+ case WAVE_FORMAT_PCM:
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "unsupported wave format\n");
+ return AVERROR(ENOSYS);
+ }
+
+ bytestream2_skip(&gb, 2); // skip channels (already got from shorten header)
+ avctx->sample_rate = bytestream2_get_le32(&gb);
+ bytestream2_skip(&gb, 4); // skip bit rate (represents original uncompressed bit rate)
+ bytestream2_skip(&gb, 2); // skip block align (not needed)
+ bps = bytestream2_get_le16(&gb);
+ avctx->bits_per_coded_sample = bps;
+
+ if (bps != 16 && bps != 8) {
+ av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample: %d\n", bps);
+ return AVERROR(ENOSYS);
+ }
+
+ len -= 16;
+ if (len > 0)
+ av_log(avctx, AV_LOG_INFO, "%d header bytes unparsed\n", len);
+
+ return 0;
+}
+
+static const int fixed_coeffs[][3] = {
+ { 0, 0, 0 },
+ { 1, 0, 0 },
+ { 2, -1, 0 },
+ { 3, -3, 1 }
+};
+
+static int decode_subframe_lpc(ShortenContext *s, int command, int channel,
+ int residual_size, int32_t coffset)
+{
+ int pred_order, sum, qshift, init_sum, i, j;
+ const int *coeffs;
+
+ if (command == FN_QLPC) {
+ /* read/validate prediction order */
+ pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE);
+ if ((unsigned)pred_order > s->nwrap) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n",
+ pred_order);
+ return AVERROR(EINVAL);
+ }
+ /* read LPC coefficients */
+ for (i = 0; i < pred_order; i++)
+ s->coeffs[i] = get_sr_golomb_shorten(&s->gb, LPCQUANT);
+ coeffs = s->coeffs;
+
+ qshift = LPCQUANT;
+ } else {
+ /* fixed LPC coeffs */
+ pred_order = command;
+ if (pred_order >= FF_ARRAY_ELEMS(fixed_coeffs)) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n",
+ pred_order);
+ return AVERROR_INVALIDDATA;
+ }
+ coeffs = fixed_coeffs[pred_order];
+ qshift = 0;
+ }
+
+ /* subtract offset from previous samples to use in prediction */
+ if (command == FN_QLPC && coffset)
+ for (i = -pred_order; i < 0; i++)
+ s->decoded[channel][i] -= coffset;
+
+ /* decode residual and do LPC prediction */
+ init_sum = pred_order ? (command == FN_QLPC ? s->lpcqoffset : 0) : coffset;
+ for (i = 0; i < s->blocksize; i++) {
+ sum = init_sum;
+ for (j = 0; j < pred_order; j++)
+ sum += coeffs[j] * s->decoded[channel][i - j - 1];
+ s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) +
+ (sum >> qshift);
+ }
+
+ /* add offset to current samples */
+ if (command == FN_QLPC && coffset)
+ for (i = 0; i < s->blocksize; i++)
+ s->decoded[channel][i] += coffset;
+
+ return 0;
+}
+
+static int read_header(ShortenContext *s)
+{
+ int i, ret;
+ int maxnlpc = 0;
+ /* shorten signature */
+ if (get_bits_long(&s->gb, 32) != AV_RB32("ajkg")) {
+ av_log(s->avctx, AV_LOG_ERROR, "missing shorten magic 'ajkg'\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->lpcqoffset = 0;
+ s->blocksize = DEFAULT_BLOCK_SIZE;
+ s->nmean = -1;
+ s->version = get_bits(&s->gb, 8);
+ s->internal_ftype = get_uint(s, TYPESIZE);
+
+ s->channels = get_uint(s, CHANSIZE);
+ if (!s->channels) {
+ av_log(s->avctx, AV_LOG_ERROR, "No channels reported\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->channels > MAX_CHANNELS) {
+ av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels);
+ s->channels = 0;
+ return AVERROR_INVALIDDATA;
+ }
+ s->avctx->channels = s->channels;
+
+ /* get blocksize if version > 0 */
+ if (s->version > 0) {
+ int skip_bytes;
+ unsigned blocksize;
+
+ blocksize = get_uint(s, av_log2(DEFAULT_BLOCK_SIZE));
+ if (!blocksize || blocksize > MAX_BLOCKSIZE) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "invalid or unsupported block size: %d\n",
+ blocksize);
+ return AVERROR(EINVAL);
+ }
+ s->blocksize = blocksize;
+
+ maxnlpc = get_uint(s, LPCQSIZE);
+ s->nmean = get_uint(s, 0);
+
+ skip_bytes = get_uint(s, NSKIPSIZE);
+ if ((unsigned)skip_bytes > get_bits_left(&s->gb)/8) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid skip_bytes: %d\n", skip_bytes);
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (i = 0; i < skip_bytes; i++)
+ skip_bits(&s->gb, 8);
+ }
+ s->nwrap = FFMAX(NWRAP, maxnlpc);
+
+ if ((ret = allocate_buffers(s)) < 0)
+ return ret;
+
+ if ((ret = init_offset(s)) < 0)
+ return ret;
+
+ if (s->version > 1)
+ s->lpcqoffset = V2LPCQOFFSET;
+
+ if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "missing verbatim section at beginning of stream\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->header_size = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
+ if (s->header_size >= OUT_BUFFER_SIZE ||
+ s->header_size < CANONICAL_HEADER_SIZE) {
+ av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n",
+ s->header_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (i = 0; i < s->header_size; i++)
+ s->header[i] = (char)get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
+
+ if ((ret = decode_wave_header(s->avctx, s->header, s->header_size)) < 0)
+ return ret;
+
+ s->cur_chan = 0;
+ s->bitshift = 0;
+
+ s->got_header = 1;
+
+ return 0;
+}
+
+static int shorten_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ AVFrame *frame = data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ ShortenContext *s = avctx->priv_data;
+ int i, input_buf_size = 0;
+ int ret;
+
+ /* allocate internal bitstream buffer */
+ if (s->max_framesize == 0) {
+ void *tmp_ptr;
+ s->max_framesize = 8192; // should hopefully be enough for the first header
+ tmp_ptr = av_fast_realloc(s->bitstream, &s->allocated_bitstream_size,
+ s->max_framesize + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!tmp_ptr) {
+ av_log(avctx, AV_LOG_ERROR, "error allocating bitstream buffer\n");
+ return AVERROR(ENOMEM);
+ }
+ memset(tmp_ptr, 0, s->allocated_bitstream_size);
+ s->bitstream = tmp_ptr;
+ }
+
+ /* append current packet data to bitstream buffer */
+ if (1 && s->max_framesize) { //FIXME truncated
+ buf_size = FFMIN(buf_size, s->max_framesize - s->bitstream_size);
+ input_buf_size = buf_size;
+
+ if (s->bitstream_index + s->bitstream_size + buf_size + AV_INPUT_BUFFER_PADDING_SIZE >
+ s->allocated_bitstream_size) {
+ memmove(s->bitstream, &s->bitstream[s->bitstream_index],
+ s->bitstream_size);
+ s->bitstream_index = 0;
+ }
+ if (buf)
+ memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf,
+ buf_size);
+ buf = &s->bitstream[s->bitstream_index];
+ buf_size += s->bitstream_size;
+ s->bitstream_size = buf_size;
+
+ /* do not decode until buffer has at least max_framesize bytes or
+ * the end of the file has been reached */
+ if (buf_size < s->max_framesize && avpkt->data) {
+ *got_frame_ptr = 0;
+ return input_buf_size;
+ }
+ }
+ /* init and position bitstream reader */
+ if ((ret = init_get_bits8(&s->gb, buf, buf_size)) < 0)
+ return ret;
+ skip_bits(&s->gb, s->bitindex);
+
+ /* process header or next subblock */
+ if (!s->got_header) {
+ if ((ret = read_header(s)) < 0)
+ return ret;
+ *got_frame_ptr = 0;
+ goto finish_frame;
+ }
+
+ /* if quit command was read previously, don't decode anything */
+ if (s->got_quit_command) {
+ *got_frame_ptr = 0;
+ return avpkt->size;
+ }
+
+ s->cur_chan = 0;
+ while (s->cur_chan < s->channels) {
+ unsigned cmd;
+ int len;
+
+ if (get_bits_left(&s->gb) < 3 + FNSIZE) {
+ *got_frame_ptr = 0;
+ break;
+ }
+
+ cmd = get_ur_golomb_shorten(&s->gb, FNSIZE);
+
+ if (cmd > FN_VERBATIM) {
+ av_log(avctx, AV_LOG_ERROR, "unknown shorten function %d\n", cmd);
+ *got_frame_ptr = 0;
+ break;
+ }
+
+ if (!is_audio_command[cmd]) {
+ /* process non-audio command */
+ switch (cmd) {
+ case FN_VERBATIM:
+ len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE);
+ while (len--)
+ get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE);
+ break;
+ case FN_BITSHIFT: {
+ unsigned bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE);
+ if (bitshift > 31) {
+ av_log(avctx, AV_LOG_ERROR, "bitshift %d is invalid\n",
+ bitshift);
+ return AVERROR_INVALIDDATA;
+ }
+ s->bitshift = bitshift;
+ break;
+ }
+ case FN_BLOCKSIZE: {
+ unsigned blocksize = get_uint(s, av_log2(s->blocksize));
+ if (blocksize > s->blocksize) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Increasing block size is not supported\n");
+ return AVERROR_PATCHWELCOME;
+ }
+ if (!blocksize || blocksize > MAX_BLOCKSIZE) {
+ av_log(avctx, AV_LOG_ERROR, "invalid or unsupported "
+ "block size: %d\n", blocksize);
+ return AVERROR(EINVAL);
+ }
+ s->blocksize = blocksize;
+ break;
+ }
+ case FN_QUIT:
+ s->got_quit_command = 1;
+ break;
+ }
+ if (cmd == FN_BLOCKSIZE || cmd == FN_QUIT) {
+ *got_frame_ptr = 0;
+ break;
+ }
+ } else {
+ /* process audio command */
+ int residual_size = 0;
+ int channel = s->cur_chan;
+ int32_t coffset;
+
+ /* get Rice code for residual decoding */
+ if (cmd != FN_ZERO) {
+ residual_size = get_ur_golomb_shorten(&s->gb, ENERGYSIZE);
+ /* This is a hack as version 0 differed in the definition
+ * of get_sr_golomb_shorten(). */
+ if (s->version == 0)
+ residual_size--;
+ }
+
+ /* calculate sample offset using means from previous blocks */
+ if (s->nmean == 0)
+ coffset = s->offset[channel][0];
+ else {
+ int32_t sum = (s->version < 2) ? 0 : s->nmean / 2;
+ for (i = 0; i < s->nmean; i++)
+ sum += s->offset[channel][i];
+ coffset = sum / s->nmean;
+ if (s->version >= 2)
+ coffset = s->bitshift == 0 ? coffset : coffset >> s->bitshift - 1 >> 1;
+ }
+
+ /* decode samples for this channel */
+ if (cmd == FN_ZERO) {
+ for (i = 0; i < s->blocksize; i++)
+ s->decoded[channel][i] = 0;
+ } else {
+ if ((ret = decode_subframe_lpc(s, cmd, channel,
+ residual_size, coffset)) < 0)
+ return ret;
+ }
+
+ /* update means with info from the current block */
+ if (s->nmean > 0) {
+ int32_t sum = (s->version < 2) ? 0 : s->blocksize / 2;
+ for (i = 0; i < s->blocksize; i++)
+ sum += s->decoded[channel][i];
+
+ for (i = 1; i < s->nmean; i++)
+ s->offset[channel][i - 1] = s->offset[channel][i];
+
+ if (s->version < 2)
+ s->offset[channel][s->nmean - 1] = sum / s->blocksize;
+ else
+ s->offset[channel][s->nmean - 1] = (sum / s->blocksize) << s->bitshift;
+ }
+
+ /* copy wrap samples for use with next block */
+ for (i = -s->nwrap; i < 0; i++)
+ s->decoded[channel][i] = s->decoded[channel][i + s->blocksize];
+
+ /* shift samples to add in unused zero bits which were removed
+ * during encoding */
+ fix_bitshift(s, s->decoded[channel]);
+
+ /* if this is the last channel in the block, output the samples */
+ s->cur_chan++;
+ if (s->cur_chan == s->channels) {
+ uint8_t *samples_u8;
+ int16_t *samples_s16;
+ int chan;
+
+ /* get output buffer */
+ frame->nb_samples = s->blocksize;
+ if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
+ return ret;
+
+ for (chan = 0; chan < s->channels; chan++) {
+ samples_u8 = ((uint8_t **)frame->extended_data)[chan];
+ samples_s16 = ((int16_t **)frame->extended_data)[chan];
+ for (i = 0; i < s->blocksize; i++) {
+ switch (s->internal_ftype) {
+ case TYPE_U8:
+ *samples_u8++ = av_clip_uint8(s->decoded[chan][i]);
+ break;
+ case TYPE_S16HL:
+ case TYPE_S16LH:
+ *samples_s16++ = av_clip_int16(s->decoded[chan][i]);
+ break;
+ }
+ }
+ }
+
+ *got_frame_ptr = 1;
+ }
+ }
+ }
+ if (s->cur_chan < s->channels)
+ *got_frame_ptr = 0;
+
+finish_frame:
+ s->bitindex = get_bits_count(&s->gb) - 8 * (get_bits_count(&s->gb) / 8);
+ i = get_bits_count(&s->gb) / 8;
+ if (i > buf_size) {
+ av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size);
+ s->bitstream_size = 0;
+ s->bitstream_index = 0;
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->bitstream_size) {
+ s->bitstream_index += i;
+ s->bitstream_size -= i;
+ return input_buf_size;
+ } else
+ return i;
+}
+
+static av_cold int shorten_decode_close(AVCodecContext *avctx)
+{
+ ShortenContext *s = avctx->priv_data;
+ int i;
+
+ for (i = 0; i < s->channels; i++) {
+ s->decoded[i] = NULL;
+ av_freep(&s->decoded_base[i]);
+ av_freep(&s->offset[i]);
+ }
+ av_freep(&s->bitstream);
+ av_freep(&s->coeffs);
+
+ return 0;
+}
+
+AVCodec ff_shorten_decoder = {
+ .name = "shorten",
+ .long_name = NULL_IF_CONFIG_SMALL("Shorten"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_SHORTEN,
+ .priv_data_size = sizeof(ShortenContext),
+ .init = shorten_decode_init,
+ .close = shorten_decode_close,
+ .decode = shorten_decode_frame,
+ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1,
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P,
+ AV_SAMPLE_FMT_U8P,
+ AV_SAMPLE_FMT_NONE },
+};
diff --git a/ffmpeg-2-8-11/libavcodec/simple_idct.c b/ffmpeg-2-8-12/libavcodec/simple_idct.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/simple_idct.c
rename to ffmpeg-2-8-12/libavcodec/simple_idct.c
diff --git a/ffmpeg-2-8-11/libavcodec/simple_idct.h b/ffmpeg-2-8-12/libavcodec/simple_idct.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/simple_idct.h
rename to ffmpeg-2-8-12/libavcodec/simple_idct.h
diff --git a/ffmpeg-2-8-11/libavcodec/simple_idct_template.c b/ffmpeg-2-8-12/libavcodec/simple_idct_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/simple_idct_template.c
rename to ffmpeg-2-8-12/libavcodec/simple_idct_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/sinewin.c b/ffmpeg-2-8-12/libavcodec/sinewin.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sinewin.c
rename to ffmpeg-2-8-12/libavcodec/sinewin.c
diff --git a/ffmpeg-2-8-11/libavcodec/sinewin.h b/ffmpeg-2-8-12/libavcodec/sinewin.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sinewin.h
rename to ffmpeg-2-8-12/libavcodec/sinewin.h
diff --git a/ffmpeg-2-8-11/libavcodec/sinewin_fixed.c b/ffmpeg-2-8-12/libavcodec/sinewin_fixed.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sinewin_fixed.c
rename to ffmpeg-2-8-12/libavcodec/sinewin_fixed.c
diff --git a/ffmpeg-2-8-11/libavcodec/sinewin_fixed_tablegen.c b/ffmpeg-2-8-12/libavcodec/sinewin_fixed_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sinewin_fixed_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/sinewin_fixed_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/sinewin_tablegen.c b/ffmpeg-2-8-12/libavcodec/sinewin_tablegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sinewin_tablegen.c
rename to ffmpeg-2-8-12/libavcodec/sinewin_tablegen.c
diff --git a/ffmpeg-2-8-11/libavcodec/sinewin_tablegen.h b/ffmpeg-2-8-12/libavcodec/sinewin_tablegen.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sinewin_tablegen.h
rename to ffmpeg-2-8-12/libavcodec/sinewin_tablegen.h
diff --git a/ffmpeg-2-8-11/libavcodec/sinewin_tablegen_template.c b/ffmpeg-2-8-12/libavcodec/sinewin_tablegen_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sinewin_tablegen_template.c
rename to ffmpeg-2-8-12/libavcodec/sinewin_tablegen_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/sipr.c b/ffmpeg-2-8-12/libavcodec/sipr.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sipr.c
rename to ffmpeg-2-8-12/libavcodec/sipr.c
diff --git a/ffmpeg-2-8-11/libavcodec/sipr.h b/ffmpeg-2-8-12/libavcodec/sipr.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sipr.h
rename to ffmpeg-2-8-12/libavcodec/sipr.h
diff --git a/ffmpeg-2-8-11/libavcodec/sipr16k.c b/ffmpeg-2-8-12/libavcodec/sipr16k.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sipr16k.c
rename to ffmpeg-2-8-12/libavcodec/sipr16k.c
diff --git a/ffmpeg-2-8-11/libavcodec/sipr16kdata.h b/ffmpeg-2-8-12/libavcodec/sipr16kdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sipr16kdata.h
rename to ffmpeg-2-8-12/libavcodec/sipr16kdata.h
diff --git a/ffmpeg-2-8-11/libavcodec/siprdata.h b/ffmpeg-2-8-12/libavcodec/siprdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/siprdata.h
rename to ffmpeg-2-8-12/libavcodec/siprdata.h
diff --git a/ffmpeg-2-8-11/libavcodec/smacker.c b/ffmpeg-2-8-12/libavcodec/smacker.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/smacker.c
rename to ffmpeg-2-8-12/libavcodec/smacker.c
diff --git a/ffmpeg-2-8-12/libavcodec/smc.c b/ffmpeg-2-8-12/libavcodec/smc.c
new file mode 100644
index 0000000..18174fa
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/smc.c
@@ -0,0 +1,480 @@
+/*
+ * Quicktime Graphics (SMC) Video Decoder
+ * Copyright (c) 2003 The FFmpeg Project
+ *
+ * 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
+ * QT SMC Video Decoder by Mike Melanson (melanson at pcisys.net)
+ * For more information about the SMC format, visit:
+ * http://www.pcisys.net/~melanson/codecs/
+ *
+ * The SMC decoder outputs PAL8 colorspace data.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+
+#define CPAIR 2
+#define CQUAD 4
+#define COCTET 8
+
+#define COLORS_PER_TABLE 256
+
+typedef struct SmcContext {
+
+ AVCodecContext *avctx;
+ AVFrame *frame;
+
+ GetByteContext gb;
+
+ /* SMC color tables */
+ unsigned char color_pairs[COLORS_PER_TABLE * CPAIR];
+ unsigned char color_quads[COLORS_PER_TABLE * CQUAD];
+ unsigned char color_octets[COLORS_PER_TABLE * COCTET];
+
+ uint32_t pal[256];
+} SmcContext;
+
+#define GET_BLOCK_COUNT() \
+ (opcode & 0x10) ? (1 + bytestream2_get_byte(&s->gb)) : 1 + (opcode & 0x0F);
+
+#define ADVANCE_BLOCK() \
+{ \
+ pixel_ptr += 4; \
+ if (pixel_ptr >= width) \
+ { \
+ pixel_ptr = 0; \
+ row_ptr += stride * 4; \
+ } \
+ total_blocks--; \
+ if (total_blocks < !!n_blocks) \
+ { \
+ av_log(s->avctx, AV_LOG_INFO, "warning: block counter just went negative (this should not happen)\n"); \
+ return; \
+ } \
+}
+
+static void smc_decode_stream(SmcContext *s)
+{
+ int width = s->avctx->width;
+ int height = s->avctx->height;
+ int stride = s->frame->linesize[0];
+ int i;
+ int chunk_size;
+ int buf_size = bytestream2_size(&s->gb);
+ unsigned char opcode;
+ int n_blocks;
+ unsigned int color_flags;
+ unsigned int color_flags_a;
+ unsigned int color_flags_b;
+ unsigned int flag_mask;
+
+ unsigned char *pixels = s->frame->data[0];
+
+ int image_size = height * s->frame->linesize[0];
+ int row_ptr = 0;
+ int pixel_ptr = 0;
+ int pixel_x, pixel_y;
+ int row_inc = stride - 4;
+ int block_ptr;
+ int prev_block_ptr;
+ int prev_block_ptr1, prev_block_ptr2;
+ int prev_block_flag;
+ int total_blocks;
+ int color_table_index; /* indexes to color pair, quad, or octet tables */
+ int pixel;
+
+ int color_pair_index = 0;
+ int color_quad_index = 0;
+ int color_octet_index = 0;
+
+ /* make the palette available */
+ memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE);
+
+ bytestream2_skip(&s->gb, 1);
+ chunk_size = bytestream2_get_be24(&s->gb);
+ if (chunk_size != buf_size)
+ av_log(s->avctx, AV_LOG_INFO, "warning: MOV chunk size != encoded chunk size (%d != %d); using MOV chunk size\n",
+ chunk_size, buf_size);
+
+ chunk_size = buf_size;
+ total_blocks = ((s->avctx->width + 3) / 4) * ((s->avctx->height + 3) / 4);
+
+ /* traverse through the blocks */
+ while (total_blocks) {
+ /* sanity checks */
+ /* make sure the row pointer hasn't gone wild */
+ if (row_ptr >= image_size) {
+ av_log(s->avctx, AV_LOG_INFO, "SMC decoder just went out of bounds (row ptr = %d, height = %d)\n",
+ row_ptr, image_size);
+ return;
+ }
+ if (bytestream2_get_bytes_left(&s->gb) < 1) {
+ av_log(s->avctx, AV_LOG_ERROR, "input too small\n");
+ return;
+ }
+
+ opcode = bytestream2_get_byte(&s->gb);
+ switch (opcode & 0xF0) {
+ /* skip n blocks */
+ case 0x00:
+ case 0x10:
+ n_blocks = GET_BLOCK_COUNT();
+ while (n_blocks--) {
+ ADVANCE_BLOCK();
+ }
+ break;
+
+ /* repeat last block n times */
+ case 0x20:
+ case 0x30:
+ n_blocks = GET_BLOCK_COUNT();
+
+ /* sanity check */
+ if ((row_ptr == 0) && (pixel_ptr == 0)) {
+ av_log(s->avctx, AV_LOG_INFO, "encountered repeat block opcode (%02X) but no blocks rendered yet\n",
+ opcode & 0xF0);
+ return;
+ }
+
+ /* figure out where the previous block started */
+ if (pixel_ptr == 0)
+ prev_block_ptr1 =
+ (row_ptr - s->avctx->width * 4) + s->avctx->width - 4;
+ else
+ prev_block_ptr1 = row_ptr + pixel_ptr - 4;
+
+ while (n_blocks--) {
+ block_ptr = row_ptr + pixel_ptr;
+ prev_block_ptr = prev_block_ptr1;
+ for (pixel_y = 0; pixel_y < 4; pixel_y++) {
+ for (pixel_x = 0; pixel_x < 4; pixel_x++) {
+ pixels[block_ptr++] = pixels[prev_block_ptr++];
+ }
+ block_ptr += row_inc;
+ prev_block_ptr += row_inc;
+ }
+ ADVANCE_BLOCK();
+ }
+ break;
+
+ /* repeat previous pair of blocks n times */
+ case 0x40:
+ case 0x50:
+ n_blocks = GET_BLOCK_COUNT();
+ n_blocks *= 2;
+
+ /* sanity check */
+ if ((row_ptr == 0) && (pixel_ptr < 2 * 4)) {
+ av_log(s->avctx, AV_LOG_INFO, "encountered repeat block opcode (%02X) but not enough blocks rendered yet\n",
+ opcode & 0xF0);
+ return;
+ }
+
+ /* figure out where the previous 2 blocks started */
+ if (pixel_ptr == 0)
+ prev_block_ptr1 = (row_ptr - s->avctx->width * 4) +
+ s->avctx->width - 4 * 2;
+ else if (pixel_ptr == 4)
+ prev_block_ptr1 = (row_ptr - s->avctx->width * 4) + row_inc;
+ else
+ prev_block_ptr1 = row_ptr + pixel_ptr - 4 * 2;
+
+ if (pixel_ptr == 0)
+ prev_block_ptr2 = (row_ptr - s->avctx->width * 4) + row_inc;
+ else
+ prev_block_ptr2 = row_ptr + pixel_ptr - 4;
+
+ prev_block_flag = 0;
+ while (n_blocks--) {
+ block_ptr = row_ptr + pixel_ptr;
+ if (prev_block_flag)
+ prev_block_ptr = prev_block_ptr2;
+ else
+ prev_block_ptr = prev_block_ptr1;
+ prev_block_flag = !prev_block_flag;
+
+ for (pixel_y = 0; pixel_y < 4; pixel_y++) {
+ for (pixel_x = 0; pixel_x < 4; pixel_x++) {
+ pixels[block_ptr++] = pixels[prev_block_ptr++];
+ }
+ block_ptr += row_inc;
+ prev_block_ptr += row_inc;
+ }
+ ADVANCE_BLOCK();
+ }
+ break;
+
+ /* 1-color block encoding */
+ case 0x60:
+ case 0x70:
+ n_blocks = GET_BLOCK_COUNT();
+ pixel = bytestream2_get_byte(&s->gb);
+
+ while (n_blocks--) {
+ block_ptr = row_ptr + pixel_ptr;
+ for (pixel_y = 0; pixel_y < 4; pixel_y++) {
+ for (pixel_x = 0; pixel_x < 4; pixel_x++) {
+ pixels[block_ptr++] = pixel;
+ }
+ block_ptr += row_inc;
+ }
+ ADVANCE_BLOCK();
+ }
+ break;
+
+ /* 2-color block encoding */
+ case 0x80:
+ case 0x90:
+ n_blocks = (opcode & 0x0F) + 1;
+
+ /* figure out which color pair to use to paint the 2-color block */
+ if ((opcode & 0xF0) == 0x80) {
+ /* fetch the next 2 colors from bytestream and store in next
+ * available entry in the color pair table */
+ for (i = 0; i < CPAIR; i++) {
+ pixel = bytestream2_get_byte(&s->gb);
+ color_table_index = CPAIR * color_pair_index + i;
+ s->color_pairs[color_table_index] = pixel;
+ }
+ /* this is the base index to use for this block */
+ color_table_index = CPAIR * color_pair_index;
+ color_pair_index++;
+ /* wraparound */
+ if (color_pair_index == COLORS_PER_TABLE)
+ color_pair_index = 0;
+ } else
+ color_table_index = CPAIR * bytestream2_get_byte(&s->gb);
+
+ while (n_blocks--) {
+ color_flags = bytestream2_get_be16(&s->gb);
+ flag_mask = 0x8000;
+ block_ptr = row_ptr + pixel_ptr;
+ for (pixel_y = 0; pixel_y < 4; pixel_y++) {
+ for (pixel_x = 0; pixel_x < 4; pixel_x++) {
+ if (color_flags & flag_mask)
+ pixel = color_table_index + 1;
+ else
+ pixel = color_table_index;
+ flag_mask >>= 1;
+ pixels[block_ptr++] = s->color_pairs[pixel];
+ }
+ block_ptr += row_inc;
+ }
+ ADVANCE_BLOCK();
+ }
+ break;
+
+ /* 4-color block encoding */
+ case 0xA0:
+ case 0xB0:
+ n_blocks = (opcode & 0x0F) + 1;
+
+ /* figure out which color quad to use to paint the 4-color block */
+ if ((opcode & 0xF0) == 0xA0) {
+ /* fetch the next 4 colors from bytestream and store in next
+ * available entry in the color quad table */
+ for (i = 0; i < CQUAD; i++) {
+ pixel = bytestream2_get_byte(&s->gb);
+ color_table_index = CQUAD * color_quad_index + i;
+ s->color_quads[color_table_index] = pixel;
+ }
+ /* this is the base index to use for this block */
+ color_table_index = CQUAD * color_quad_index;
+ color_quad_index++;
+ /* wraparound */
+ if (color_quad_index == COLORS_PER_TABLE)
+ color_quad_index = 0;
+ } else
+ color_table_index = CQUAD * bytestream2_get_byte(&s->gb);
+
+ while (n_blocks--) {
+ color_flags = bytestream2_get_be32(&s->gb);
+ /* flag mask actually acts as a bit shift count here */
+ flag_mask = 30;
+ block_ptr = row_ptr + pixel_ptr;
+ for (pixel_y = 0; pixel_y < 4; pixel_y++) {
+ for (pixel_x = 0; pixel_x < 4; pixel_x++) {
+ pixel = color_table_index +
+ ((color_flags >> flag_mask) & 0x03);
+ flag_mask -= 2;
+ pixels[block_ptr++] = s->color_quads[pixel];
+ }
+ block_ptr += row_inc;
+ }
+ ADVANCE_BLOCK();
+ }
+ break;
+
+ /* 8-color block encoding */
+ case 0xC0:
+ case 0xD0:
+ n_blocks = (opcode & 0x0F) + 1;
+
+ /* figure out which color octet to use to paint the 8-color block */
+ if ((opcode & 0xF0) == 0xC0) {
+ /* fetch the next 8 colors from bytestream and store in next
+ * available entry in the color octet table */
+ for (i = 0; i < COCTET; i++) {
+ pixel = bytestream2_get_byte(&s->gb);
+ color_table_index = COCTET * color_octet_index + i;
+ s->color_octets[color_table_index] = pixel;
+ }
+ /* this is the base index to use for this block */
+ color_table_index = COCTET * color_octet_index;
+ color_octet_index++;
+ /* wraparound */
+ if (color_octet_index == COLORS_PER_TABLE)
+ color_octet_index = 0;
+ } else
+ color_table_index = COCTET * bytestream2_get_byte(&s->gb);
+
+ while (n_blocks--) {
+ /*
+ For this input of 6 hex bytes:
+ 01 23 45 67 89 AB
+ Mangle it to this output:
+ flags_a = xx012456, flags_b = xx89A37B
+ */
+ /* build the color flags */
+ int val1 = bytestream2_get_be16(&s->gb);
+ int val2 = bytestream2_get_be16(&s->gb);
+ int val3 = bytestream2_get_be16(&s->gb);
+ color_flags_a = ((val1 & 0xFFF0) << 8) | (val2 >> 4);
+ color_flags_b = ((val3 & 0xFFF0) << 8) |
+ ((val1 & 0x0F) << 8) | ((val2 & 0x0F) << 4) | (val3 & 0x0F);
+
+ color_flags = color_flags_a;
+ /* flag mask actually acts as a bit shift count here */
+ flag_mask = 21;
+ block_ptr = row_ptr + pixel_ptr;
+ for (pixel_y = 0; pixel_y < 4; pixel_y++) {
+ /* reload flags at third row (iteration pixel_y == 2) */
+ if (pixel_y == 2) {
+ color_flags = color_flags_b;
+ flag_mask = 21;
+ }
+ for (pixel_x = 0; pixel_x < 4; pixel_x++) {
+ pixel = color_table_index +
+ ((color_flags >> flag_mask) & 0x07);
+ flag_mask -= 3;
+ pixels[block_ptr++] = s->color_octets[pixel];
+ }
+ block_ptr += row_inc;
+ }
+ ADVANCE_BLOCK();
+ }
+ break;
+
+ /* 16-color block encoding (every pixel is a different color) */
+ case 0xE0:
+ n_blocks = (opcode & 0x0F) + 1;
+
+ while (n_blocks--) {
+ block_ptr = row_ptr + pixel_ptr;
+ for (pixel_y = 0; pixel_y < 4; pixel_y++) {
+ for (pixel_x = 0; pixel_x < 4; pixel_x++) {
+ pixels[block_ptr++] = bytestream2_get_byte(&s->gb);
+ }
+ block_ptr += row_inc;
+ }
+ ADVANCE_BLOCK();
+ }
+ break;
+
+ case 0xF0:
+ avpriv_request_sample(s->avctx, "0xF0 opcode");
+ break;
+ }
+ }
+
+ return;
+}
+
+static av_cold int smc_decode_init(AVCodecContext *avctx)
+{
+ SmcContext *s = avctx->priv_data;
+
+ s->avctx = avctx;
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static int smc_decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ SmcContext *s = avctx->priv_data;
+ const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL);
+ int ret;
+
+ bytestream2_init(&s->gb, buf, buf_size);
+
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
+ return ret;
+
+ if (pal) {
+ s->frame->palette_has_changed = 1;
+ memcpy(s->pal, pal, AVPALETTE_SIZE);
+ }
+
+ smc_decode_stream(s);
+
+ *got_frame = 1;
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
+ return ret;
+
+ /* always report that the buffer was completely consumed */
+ return buf_size;
+}
+
+static av_cold int smc_decode_end(AVCodecContext *avctx)
+{
+ SmcContext *s = avctx->priv_data;
+
+ av_frame_free(&s->frame);
+
+ return 0;
+}
+
+AVCodec ff_smc_decoder = {
+ .name = "smc",
+ .long_name = NULL_IF_CONFIG_SMALL("QuickTime Graphics (SMC)"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_SMC,
+ .priv_data_size = sizeof(SmcContext),
+ .init = smc_decode_init,
+ .close = smc_decode_end,
+ .decode = smc_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/smvjpegdec.c b/ffmpeg-2-8-12/libavcodec/smvjpegdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/smvjpegdec.c
rename to ffmpeg-2-8-12/libavcodec/smvjpegdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/snappy.c b/ffmpeg-2-8-12/libavcodec/snappy.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/snappy.c
rename to ffmpeg-2-8-12/libavcodec/snappy.c
diff --git a/ffmpeg-2-8-11/libavcodec/snappy.h b/ffmpeg-2-8-12/libavcodec/snappy.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/snappy.h
rename to ffmpeg-2-8-12/libavcodec/snappy.h
diff --git a/ffmpeg-2-8-11/libavcodec/snow.c b/ffmpeg-2-8-12/libavcodec/snow.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/snow.c
rename to ffmpeg-2-8-12/libavcodec/snow.c
diff --git a/ffmpeg-2-8-12/libavcodec/snow.h b/ffmpeg-2-8-12/libavcodec/snow.h
new file mode 100644
index 0000000..0778f2a
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/snow.h
@@ -0,0 +1,730 @@
+/*
+ * Copyright (C) 2004 Michael Niedermayer <michaelni at gmx.at>
+ * Copyright (C) 2006 Robert Edele <yartrebo at earthlink.net>
+ *
+ * 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_SNOW_H
+#define AVCODEC_SNOW_H
+
+#include "libavutil/motion_vector.h"
+
+#include "hpeldsp.h"
+#include "me_cmp.h"
+#include "qpeldsp.h"
+#include "snow_dwt.h"
+
+#include "rangecoder.h"
+#include "mathops.h"
+
+#define FF_MPV_OFFSET(x) (offsetof(MpegEncContext, x) + offsetof(SnowContext, m))
+#include "mpegvideo.h"
+#include "h264qpel.h"
+
+#define MID_STATE 128
+
+#define MAX_PLANES 4
+#define QSHIFT 5
+#define QROOT (1<<QSHIFT)
+#define LOSSLESS_QLOG -128
+#define FRAC_BITS 4
+#define MAX_REF_FRAMES 8
+
+#define LOG2_OBMC_MAX 8
+#define OBMC_MAX (1<<(LOG2_OBMC_MAX))
+typedef struct BlockNode{
+ int16_t mx;
+ int16_t my;
+ uint8_t ref;
+ uint8_t color[3];
+ uint8_t type;
+//#define TYPE_SPLIT 1
+#define BLOCK_INTRA 1
+#define BLOCK_OPT 2
+//#define TYPE_NOCOLOR 4
+ uint8_t level; //FIXME merge into type?
+}BlockNode;
+
+static const BlockNode null_block= { //FIXME add border maybe
+ .color= {128,128,128},
+ .mx= 0,
+ .my= 0,
+ .ref= 0,
+ .type= 0,
+ .level= 0,
+};
+
+#define LOG2_MB_SIZE 4
+#define MB_SIZE (1<<LOG2_MB_SIZE)
+#define ENCODER_EXTRA_BITS 4
+#define HTAPS_MAX 8
+
+typedef struct x_and_coeff{
+ int16_t x;
+ uint16_t coeff;
+} x_and_coeff;
+
+typedef struct SubBand{
+ int level;
+ int stride;
+ int width;
+ int height;
+ int qlog; ///< log(qscale)/log[2^(1/6)]
+ DWTELEM *buf;
+ IDWTELEM *ibuf;
+ int buf_x_offset;
+ int buf_y_offset;
+ int stride_line; ///< Stride measured in lines, not pixels.
+ x_and_coeff * x_coeff;
+ struct SubBand *parent;
+ uint8_t state[/*7*2*/ 7 + 512][32];
+}SubBand;
+
+typedef struct Plane{
+ int width;
+ int height;
+ SubBand band[MAX_DECOMPOSITIONS][4];
+
+ int htaps;
+ int8_t hcoeff[HTAPS_MAX/2];
+ int diag_mc;
+ int fast_mc;
+
+ int last_htaps;
+ int8_t last_hcoeff[HTAPS_MAX/2];
+ int last_diag_mc;
+}Plane;
+
+typedef struct SnowContext{
+ AVClass *class;
+ AVCodecContext *avctx;
+ RangeCoder c;
+ MECmpContext mecc;
+ HpelDSPContext hdsp;
+ QpelDSPContext qdsp;
+ VideoDSPContext vdsp;
+ H264QpelContext h264qpel;
+ MpegvideoEncDSPContext mpvencdsp;
+ SnowDWTContext dwt;
+ const AVFrame *new_picture;
+ AVFrame *input_picture; ///< new_picture with the internal linesizes
+ AVFrame *current_picture;
+ AVFrame *last_picture[MAX_REF_FRAMES];
+ uint8_t *halfpel_plane[MAX_REF_FRAMES][4][4];
+ AVFrame *mconly_picture;
+// uint8_t q_context[16];
+ uint8_t header_state[32];
+ uint8_t block_state[128 + 32*128];
+ int keyframe;
+ int always_reset;
+ int version;
+ int spatial_decomposition_type;
+ int last_spatial_decomposition_type;
+ int temporal_decomposition_type;
+ int spatial_decomposition_count;
+ int last_spatial_decomposition_count;
+ int temporal_decomposition_count;
+ int max_ref_frames;
+ int ref_frames;
+ int16_t (*ref_mvs[MAX_REF_FRAMES])[2];
+ uint32_t *ref_scores[MAX_REF_FRAMES];
+ DWTELEM *spatial_dwt_buffer;
+ DWTELEM *temp_dwt_buffer;
+ IDWTELEM *spatial_idwt_buffer;
+ IDWTELEM *temp_idwt_buffer;
+ int *run_buffer;
+ int colorspace_type;
+ int chroma_h_shift;
+ int chroma_v_shift;
+ int spatial_scalability;
+ int qlog;
+ int last_qlog;
+ int lambda;
+ int lambda2;
+ int pass1_rc;
+ int mv_scale;
+ int last_mv_scale;
+ int qbias;
+ int last_qbias;
+#define QBIAS_SHIFT 3
+ int b_width;
+ int b_height;
+ int block_max_depth;
+ int last_block_max_depth;
+ int nb_planes;
+ Plane plane[MAX_PLANES];
+ BlockNode *block;
+#define ME_CACHE_SIZE 1024
+ unsigned me_cache[ME_CACHE_SIZE];
+ unsigned me_cache_generation;
+ slice_buffer sb;
+ int memc_only;
+ int no_bitstream;
+ int intra_penalty;
+ int motion_est;
+ int iterative_dia_size;
+
+ MpegEncContext m; // needed for motion estimation, should not be used for anything else, the idea is to eventually make the motion estimation independent of MpegEncContext, so this will be removed then (FIXME/XXX)
+
+ uint8_t *scratchbuf;
+ uint8_t *emu_edge_buffer;
+
+ AVMotionVector *avmv;
+ int avmv_index;
+}SnowContext;
+
+/* Tables */
+extern const uint8_t * const ff_obmc_tab[4];
+extern uint8_t ff_qexp[QROOT];
+extern int ff_scale_mv_ref[MAX_REF_FRAMES][MAX_REF_FRAMES];
+
+/* C bits used by mmx/sse2/altivec */
+
+static av_always_inline void snow_interleave_line_header(int * i, int width, IDWTELEM * low, IDWTELEM * high){
+ (*i) = (width) - 2;
+
+ if (width & 1){
+ low[(*i)+1] = low[((*i)+1)>>1];
+ (*i)--;
+ }
+}
+
+static av_always_inline void snow_interleave_line_footer(int * i, IDWTELEM * low, IDWTELEM * high){
+ for (; (*i)>=0; (*i)-=2){
+ low[(*i)+1] = high[(*i)>>1];
+ low[*i] = low[(*i)>>1];
+ }
+}
+
+static av_always_inline void snow_horizontal_compose_lift_lead_out(int i, IDWTELEM * dst, IDWTELEM * src, IDWTELEM * ref, int width, int w, int lift_high, int mul, int add, int shift){
+ for(; i<w; i++){
+ dst[i] = src[i] - ((mul * (ref[i] + ref[i + 1]) + add) >> shift);
+ }
+
+ if((width^lift_high)&1){
+ dst[w] = src[w] - ((mul * 2 * ref[w] + add) >> shift);
+ }
+}
+
+static av_always_inline void snow_horizontal_compose_liftS_lead_out(int i, IDWTELEM * dst, IDWTELEM * src, IDWTELEM * ref, int width, int w){
+ for(; i<w; i++){
+ dst[i] = src[i] + ((ref[i] + ref[(i+1)]+W_BO + 4 * src[i]) >> W_BS);
+ }
+
+ if(width&1){
+ dst[w] = src[w] + ((2 * ref[w] + W_BO + 4 * src[w]) >> W_BS);
+ }
+}
+
+/* common code */
+
+int ff_snow_common_init(AVCodecContext *avctx);
+int ff_snow_common_init_after_header(AVCodecContext *avctx);
+void ff_snow_common_end(SnowContext *s);
+void ff_snow_release_buffer(AVCodecContext *avctx);
+void ff_snow_reset_contexts(SnowContext *s);
+int ff_snow_alloc_blocks(SnowContext *s);
+int ff_snow_frame_start(SnowContext *s);
+void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, ptrdiff_t stride,
+ int sx, int sy, int b_w, int b_h, const BlockNode *block,
+ int plane_index, int w, int h);
+int ff_snow_get_buffer(SnowContext *s, AVFrame *frame);
+/* common inline functions */
+//XXX doublecheck all of them should stay inlined
+
+static inline void snow_set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){
+ const int w= s->b_width << s->block_max_depth;
+ const int rem_depth= s->block_max_depth - level;
+ const int index= (x + y*w) << rem_depth;
+ const int block_w= 1<<rem_depth;
+ BlockNode block;
+ int i,j;
+
+ block.color[0]= l;
+ block.color[1]= cb;
+ block.color[2]= cr;
+ block.mx= mx;
+ block.my= my;
+ block.ref= ref;
+ block.type= type;
+ block.level= level;
+
+ for(j=0; j<block_w; j++){
+ for(i=0; i<block_w; i++){
+ s->block[index + i + j*w]= block;
+ }
+ }
+}
+
+static inline void pred_mv(SnowContext *s, int *mx, int *my, int ref,
+ const BlockNode *left, const BlockNode *top, const BlockNode *tr){
+ if(s->ref_frames == 1){
+ *mx = mid_pred(left->mx, top->mx, tr->mx);
+ *my = mid_pred(left->my, top->my, tr->my);
+ }else{
+ const int *scale = ff_scale_mv_ref[ref];
+ *mx = mid_pred((left->mx * scale[left->ref] + 128) >>8,
+ (top ->mx * scale[top ->ref] + 128) >>8,
+ (tr ->mx * scale[tr ->ref] + 128) >>8);
+ *my = mid_pred((left->my * scale[left->ref] + 128) >>8,
+ (top ->my * scale[top ->ref] + 128) >>8,
+ (tr ->my * scale[tr ->ref] + 128) >>8);
+ }
+}
+
+static av_always_inline int same_block(BlockNode *a, BlockNode *b){
+ if((a->type&BLOCK_INTRA) && (b->type&BLOCK_INTRA)){
+ return !((a->color[0] - b->color[0]) | (a->color[1] - b->color[1]) | (a->color[2] - b->color[2]));
+ }else{
+ return !((a->mx - b->mx) | (a->my - b->my) | (a->ref - b->ref) | ((a->type ^ b->type)&BLOCK_INTRA));
+ }
+}
+
+//FIXME name cleanup (b_w, block_w, b_width stuff)
+//XXX should we really inline it?
+static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer *sb, IDWTELEM *dst, uint8_t *dst8, const uint8_t *obmc, int src_x, int src_y, int b_w, int b_h, int w, int h, int dst_stride, int src_stride, int obmc_stride, int b_x, int b_y, int add, int offset_dst, int plane_index){
+ const int b_width = s->b_width << s->block_max_depth;
+ const int b_height= s->b_height << s->block_max_depth;
+ const int b_stride= b_width;
+ BlockNode *lt= &s->block[b_x + b_y*b_stride];
+ BlockNode *rt= lt+1;
+ BlockNode *lb= lt+b_stride;
+ BlockNode *rb= lb+1;
+ uint8_t *block[4];
+ // When src_stride is large enough, it is possible to interleave the blocks.
+ // Otherwise the blocks are written sequentially in the tmp buffer.
+ int tmp_step= src_stride >= 7*MB_SIZE ? MB_SIZE : MB_SIZE*src_stride;
+ uint8_t *tmp = s->scratchbuf;
+ uint8_t *ptmp;
+ int x,y;
+
+ if(b_x<0){
+ lt= rt;
+ lb= rb;
+ }else if(b_x + 1 >= b_width){
+ rt= lt;
+ rb= lb;
+ }
+ if(b_y<0){
+ lt= lb;
+ rt= rb;
+ }else if(b_y + 1 >= b_height){
+ lb= lt;
+ rb= rt;
+ }
+
+ if(src_x<0){ //FIXME merge with prev & always round internal width up to *16
+ obmc -= src_x;
+ b_w += src_x;
+ if(!sliced && !offset_dst)
+ dst -= src_x;
+ src_x=0;
+ }
+ if(src_x + b_w > w){
+ b_w = w - src_x;
+ }
+ if(src_y<0){
+ obmc -= src_y*obmc_stride;
+ b_h += src_y;
+ if(!sliced && !offset_dst)
+ dst -= src_y*dst_stride;
+ src_y=0;
+ }
+ if(src_y + b_h> h){
+ b_h = h - src_y;
+ }
+
+ if(b_w<=0 || b_h<=0) return;
+
+ if(!sliced && offset_dst)
+ dst += src_x + src_y*dst_stride;
+ dst8+= src_x + src_y*src_stride;
+// src += src_x + src_y*src_stride;
+
+ ptmp= tmp + 3*tmp_step;
+ block[0]= ptmp;
+ ptmp+=tmp_step;
+ ff_snow_pred_block(s, block[0], tmp, src_stride, src_x, src_y, b_w, b_h, lt, plane_index, w, h);
+
+ if(same_block(lt, rt)){
+ block[1]= block[0];
+ }else{
+ block[1]= ptmp;
+ ptmp+=tmp_step;
+ ff_snow_pred_block(s, block[1], tmp, src_stride, src_x, src_y, b_w, b_h, rt, plane_index, w, h);
+ }
+
+ if(same_block(lt, lb)){
+ block[2]= block[0];
+ }else if(same_block(rt, lb)){
+ block[2]= block[1];
+ }else{
+ block[2]= ptmp;
+ ptmp+=tmp_step;
+ ff_snow_pred_block(s, block[2], tmp, src_stride, src_x, src_y, b_w, b_h, lb, plane_index, w, h);
+ }
+
+ if(same_block(lt, rb) ){
+ block[3]= block[0];
+ }else if(same_block(rt, rb)){
+ block[3]= block[1];
+ }else if(same_block(lb, rb)){
+ block[3]= block[2];
+ }else{
+ block[3]= ptmp;
+ ff_snow_pred_block(s, block[3], tmp, src_stride, src_x, src_y, b_w, b_h, rb, plane_index, w, h);
+ }
+ if(sliced){
+ s->dwt.inner_add_yblock(obmc, obmc_stride, block, b_w, b_h, src_x,src_y, src_stride, sb, add, dst8);
+ }else{
+ for(y=0; y<b_h; y++){
+ //FIXME ugly misuse of obmc_stride
+ const uint8_t *obmc1= obmc + y*obmc_stride;
+ const uint8_t *obmc2= obmc1+ (obmc_stride>>1);
+ const uint8_t *obmc3= obmc1+ obmc_stride*(obmc_stride>>1);
+ const uint8_t *obmc4= obmc3+ (obmc_stride>>1);
+ for(x=0; x<b_w; x++){
+ int v= obmc1[x] * block[3][x + y*src_stride]
+ +obmc2[x] * block[2][x + y*src_stride]
+ +obmc3[x] * block[1][x + y*src_stride]
+ +obmc4[x] * block[0][x + y*src_stride];
+
+ v <<= 8 - LOG2_OBMC_MAX;
+ if(FRAC_BITS != 8){
+ v >>= 8 - FRAC_BITS;
+ }
+ if(add){
+ v += dst[x + y*dst_stride];
+ v = (v + (1<<(FRAC_BITS-1))) >> FRAC_BITS;
+ if(v&(~255)) v= ~(v>>31);
+ dst8[x + y*src_stride] = v;
+ }else{
+ dst[x + y*dst_stride] -= v;
+ }
+ }
+ }
+ }
+}
+
+static av_always_inline void predict_slice(SnowContext *s, IDWTELEM *buf, int plane_index, int add, int mb_y){
+ Plane *p= &s->plane[plane_index];
+ const int mb_w= s->b_width << s->block_max_depth;
+ const int mb_h= s->b_height << s->block_max_depth;
+ int x, y, mb_x;
+ int block_size = MB_SIZE >> s->block_max_depth;
+ int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size;
+ int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size;
+ const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth];
+ const int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
+ int ref_stride= s->current_picture->linesize[plane_index];
+ uint8_t *dst8= s->current_picture->data[plane_index];
+ int w= p->width;
+ int h= p->height;
+ av_assert2(s->chroma_h_shift == s->chroma_v_shift); // obmc params assume squares
+ if(s->keyframe || (s->avctx->debug&512)){
+ if(mb_y==mb_h)
+ return;
+
+ if(add){
+ for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
+ for(x=0; x<w; x++){
+ int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
+ v >>= FRAC_BITS;
+ if(v&(~255)) v= ~(v>>31);
+ dst8[x + y*ref_stride]= v;
+ }
+ }
+ }else{
+ for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
+ for(x=0; x<w; x++){
+ buf[x + y*w]-= 128<<FRAC_BITS;
+ }
+ }
+ }
+
+ return;
+ }
+
+ for(mb_x=0; mb_x<=mb_w; mb_x++){
+ add_yblock(s, 0, NULL, buf, dst8, obmc,
+ block_w*mb_x - block_w/2,
+ block_h*mb_y - block_h/2,
+ block_w, block_h,
+ w, h,
+ w, ref_stride, obmc_stride,
+ mb_x - 1, mb_y - 1,
+ add, 1, plane_index);
+ }
+}
+
+static av_always_inline void predict_plane(SnowContext *s, IDWTELEM *buf, int plane_index, int add){
+ const int mb_h= s->b_height << s->block_max_depth;
+ int mb_y;
+ for(mb_y=0; mb_y<=mb_h; mb_y++)
+ predict_slice(s, buf, plane_index, add, mb_y);
+}
+
+static inline void set_blocks(SnowContext *s, int level, int x, int y, int l, int cb, int cr, int mx, int my, int ref, int type){
+ const int w= s->b_width << s->block_max_depth;
+ const int rem_depth= s->block_max_depth - level;
+ const int index= (x + y*w) << rem_depth;
+ const int block_w= 1<<rem_depth;
+ const int block_h= 1<<rem_depth; //FIXME "w!=h"
+ BlockNode block;
+ int i,j;
+
+ block.color[0]= l;
+ block.color[1]= cb;
+ block.color[2]= cr;
+ block.mx= mx;
+ block.my= my;
+ block.ref= ref;
+ block.type= type;
+ block.level= level;
+
+ for(j=0; j<block_h; j++){
+ for(i=0; i<block_w; i++){
+ s->block[index + i + j*w]= block;
+ }
+ }
+}
+
+static inline void init_ref(MotionEstContext *c, uint8_t *src[3], uint8_t *ref[3], uint8_t *ref2[3], int x, int y, int ref_index){
+ SnowContext *s = c->avctx->priv_data;
+ const int offset[3]= {
+ y*c-> stride + x,
+ ((y*c->uvstride + x)>>s->chroma_h_shift),
+ ((y*c->uvstride + x)>>s->chroma_h_shift),
+ };
+ int i;
+ for(i=0; i<3; i++){
+ c->src[0][i]= src [i];
+ c->ref[0][i]= ref [i] + offset[i];
+ }
+ av_assert2(!ref_index);
+}
+
+
+/* bitstream functions */
+
+extern const int8_t ff_quant3bA[256];
+
+#define QEXPSHIFT (7-FRAC_BITS+8) //FIXME try to change this to 0
+
+static inline void put_symbol(RangeCoder *c, uint8_t *state, int v, int is_signed){
+ int i;
+
+ if(v){
+ const int a= FFABS(v);
+ const int e= av_log2(a);
+ const int el= FFMIN(e, 10);
+ put_rac(c, state+0, 0);
+
+ for(i=0; i<el; i++){
+ put_rac(c, state+1+i, 1); //1..10
+ }
+ for(; i<e; i++){
+ put_rac(c, state+1+9, 1); //1..10
+ }
+ put_rac(c, state+1+FFMIN(i,9), 0);
+
+ for(i=e-1; i>=el; i--){
+ put_rac(c, state+22+9, (a>>i)&1); //22..31
+ }
+ for(; i>=0; i--){
+ put_rac(c, state+22+i, (a>>i)&1); //22..31
+ }
+
+ if(is_signed)
+ put_rac(c, state+11 + el, v < 0); //11..21
+ }else{
+ put_rac(c, state+0, 1);
+ }
+}
+
+static inline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){
+ if(get_rac(c, state+0))
+ return 0;
+ else{
+ int i, e;
+ unsigned a;
+ e= 0;
+ while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10
+ e++;
+ if (e > 31)
+ return AVERROR_INVALIDDATA;
+ }
+
+ a= 1;
+ for(i=e-1; i>=0; i--){
+ a += a + get_rac(c, state+22 + FFMIN(i,9)); //22..31
+ }
+
+ e= -(is_signed && get_rac(c, state+11 + FFMIN(e,10))); //11..21
+ return (a^e)-e;
+ }
+}
+
+static inline void put_symbol2(RangeCoder *c, uint8_t *state, int v, int log2){
+ int i;
+ int r= log2>=0 ? 1<<log2 : 1;
+
+ av_assert2(v>=0);
+ av_assert2(log2>=-4);
+
+ while(v >= r){
+ put_rac(c, state+4+log2, 1);
+ v -= r;
+ log2++;
+ if(log2>0) r+=r;
+ }
+ put_rac(c, state+4+log2, 0);
+
+ for(i=log2-1; i>=0; i--){
+ put_rac(c, state+31-i, (v>>i)&1);
+ }
+}
+
+static inline int get_symbol2(RangeCoder *c, uint8_t *state, int log2){
+ int i;
+ int r= log2>=0 ? 1<<log2 : 1;
+ int v=0;
+
+ av_assert2(log2>=-4);
+
+ while(log2<28 && get_rac(c, state+4+log2)){
+ v+= r;
+ log2++;
+ if(log2>0) r+=r;
+ }
+
+ for(i=log2-1; i>=0; i--){
+ v+= get_rac(c, state+31-i)<<i;
+ }
+
+ return v;
+}
+
+static inline void unpack_coeffs(SnowContext *s, SubBand *b, SubBand * parent, int orientation){
+ const int w= b->width;
+ const int h= b->height;
+ int x,y;
+
+ int run, runs;
+ x_and_coeff *xc= b->x_coeff;
+ x_and_coeff *prev_xc= NULL;
+ x_and_coeff *prev2_xc= xc;
+ x_and_coeff *parent_xc= parent ? parent->x_coeff : NULL;
+ x_and_coeff *prev_parent_xc= parent_xc;
+
+ runs= get_symbol2(&s->c, b->state[30], 0);
+ if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3);
+ else run= INT_MAX;
+
+ for(y=0; y<h; y++){
+ int v=0;
+ int lt=0, t=0, rt=0;
+
+ if(y && prev_xc->x == 0){
+ rt= prev_xc->coeff;
+ }
+ for(x=0; x<w; x++){
+ int p=0;
+ const int l= v;
+
+ lt= t; t= rt;
+
+ if(y){
+ if(prev_xc->x <= x)
+ prev_xc++;
+ if(prev_xc->x == x + 1)
+ rt= prev_xc->coeff;
+ else
+ rt=0;
+ }
+ if(parent_xc){
+ if(x>>1 > parent_xc->x){
+ parent_xc++;
+ }
+ if(x>>1 == parent_xc->x){
+ p= parent_xc->coeff;
+ }
+ }
+ if(/*ll|*/l|lt|t|rt|p){
+ int context= av_log2(/*FFABS(ll) + */3*(l>>1) + (lt>>1) + (t&~1) + (rt>>1) + (p>>1));
+
+ v=get_rac(&s->c, &b->state[0][context]);
+ if(v){
+ v= 2*(get_symbol2(&s->c, b->state[context + 2], context-4) + 1);
+ v+=get_rac(&s->c, &b->state[0][16 + 1 + 3 + ff_quant3bA[l&0xFF] + 3*ff_quant3bA[t&0xFF]]);
+ if ((uint16_t)v != v) {
+ av_log(s->avctx, AV_LOG_ERROR, "Coefficient damaged\n");
+ v = 1;
+ }
+ xc->x=x;
+ (xc++)->coeff= v;
+ }
+ }else{
+ if(!run){
+ if(runs-- > 0) run= get_symbol2(&s->c, b->state[1], 3);
+ else run= INT_MAX;
+ v= 2*(get_symbol2(&s->c, b->state[0 + 2], 0-4) + 1);
+ v+=get_rac(&s->c, &b->state[0][16 + 1 + 3]);
+ if ((uint16_t)v != v) {
+ av_log(s->avctx, AV_LOG_ERROR, "Coefficient damaged\n");
+ v = 1;
+ }
+
+ xc->x=x;
+ (xc++)->coeff= v;
+ }else{
+ int max_run;
+ run--;
+ v=0;
+ av_assert2(run >= 0);
+ if(y) max_run= FFMIN(run, prev_xc->x - x - 2);
+ else max_run= FFMIN(run, w-x-1);
+ if(parent_xc)
+ max_run= FFMIN(max_run, 2*parent_xc->x - x - 1);
+ av_assert2(max_run >= 0 && max_run <= run);
+
+ x+= max_run;
+ run-= max_run;
+ }
+ }
+ }
+ (xc++)->x= w+1; //end marker
+ prev_xc= prev2_xc;
+ prev2_xc= xc;
+
+ if(parent_xc){
+ if(y&1){
+ while(parent_xc->x != parent->width+1)
+ parent_xc++;
+ parent_xc++;
+ prev_parent_xc= parent_xc;
+ }else{
+ parent_xc= prev_parent_xc;
+ }
+ }
+ }
+
+ (xc++)->x= w+1; //end marker
+}
+
+#endif /* AVCODEC_SNOW_H */
diff --git a/ffmpeg-2-8-11/libavcodec/snow_dwt.c b/ffmpeg-2-8-12/libavcodec/snow_dwt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/snow_dwt.c
rename to ffmpeg-2-8-12/libavcodec/snow_dwt.c
diff --git a/ffmpeg-2-8-11/libavcodec/snow_dwt.h b/ffmpeg-2-8-12/libavcodec/snow_dwt.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/snow_dwt.h
rename to ffmpeg-2-8-12/libavcodec/snow_dwt.h
diff --git a/ffmpeg-2-8-11/libavcodec/snowdata.h b/ffmpeg-2-8-12/libavcodec/snowdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/snowdata.h
rename to ffmpeg-2-8-12/libavcodec/snowdata.h
diff --git a/ffmpeg-2-8-12/libavcodec/snowdec.c b/ffmpeg-2-8-12/libavcodec/snowdec.c
new file mode 100644
index 0000000..e5051c4
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/snowdec.c
@@ -0,0 +1,657 @@
+/*
+ * Copyright (C) 2004 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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/intmath.h"
+#include "libavutil/log.h"
+#include "libavutil/opt.h"
+#include "avcodec.h"
+#include "snow_dwt.h"
+#include "internal.h"
+#include "snow.h"
+
+#include "rangecoder.h"
+#include "mathops.h"
+
+#include "mpegvideo.h"
+#include "h263.h"
+
+static av_always_inline void predict_slice_buffered(SnowContext *s, slice_buffer * sb, IDWTELEM * old_buffer, int plane_index, int add, int mb_y){
+ Plane *p= &s->plane[plane_index];
+ const int mb_w= s->b_width << s->block_max_depth;
+ const int mb_h= s->b_height << s->block_max_depth;
+ int x, y, mb_x;
+ int block_size = MB_SIZE >> s->block_max_depth;
+ int block_w = plane_index ? block_size>>s->chroma_h_shift : block_size;
+ int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size;
+ const uint8_t *obmc = plane_index ? ff_obmc_tab[s->block_max_depth+s->chroma_h_shift] : ff_obmc_tab[s->block_max_depth];
+ int obmc_stride= plane_index ? (2*block_size)>>s->chroma_h_shift : 2*block_size;
+ int ref_stride= s->current_picture->linesize[plane_index];
+ uint8_t *dst8= s->current_picture->data[plane_index];
+ int w= p->width;
+ int h= p->height;
+
+ if(s->keyframe || (s->avctx->debug&512)){
+ if(mb_y==mb_h)
+ return;
+
+ if(add){
+ for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
+// DWTELEM * line = slice_buffer_get_line(sb, y);
+ IDWTELEM * line = sb->line[y];
+ for(x=0; x<w; x++){
+// int v= buf[x + y*w] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
+ int v= line[x] + (128<<FRAC_BITS) + (1<<(FRAC_BITS-1));
+ v >>= FRAC_BITS;
+ if(v&(~255)) v= ~(v>>31);
+ dst8[x + y*ref_stride]= v;
+ }
+ }
+ }else{
+ for(y=block_h*mb_y; y<FFMIN(h,block_h*(mb_y+1)); y++){
+// DWTELEM * line = slice_buffer_get_line(sb, y);
+ IDWTELEM * line = sb->line[y];
+ for(x=0; x<w; x++){
+ line[x] -= 128 << FRAC_BITS;
+// buf[x + y*w]-= 128<<FRAC_BITS;
+ }
+ }
+ }
+
+ return;
+ }
+
+ for(mb_x=0; mb_x<=mb_w; mb_x++){
+ add_yblock(s, 1, sb, old_buffer, dst8, obmc,
+ block_w*mb_x - block_w/2,
+ block_h*mb_y - block_h/2,
+ block_w, block_h,
+ w, h,
+ w, ref_stride, obmc_stride,
+ mb_x - 1, mb_y - 1,
+ add, 0, plane_index);
+ }
+
+ if(s->avmv && mb_y < mb_h && plane_index == 0)
+ for(mb_x=0; mb_x<mb_w; mb_x++){
+ AVMotionVector *avmv = s->avmv + s->avmv_index;
+ const int b_width = s->b_width << s->block_max_depth;
+ const int b_stride= b_width;
+ BlockNode *bn= &s->block[mb_x + mb_y*b_stride];
+
+ if (bn->type)
+ continue;
+
+ s->avmv_index++;
+
+ avmv->w = block_w;
+ avmv->h = block_h;
+ avmv->dst_x = block_w*mb_x - block_w/2;
+ avmv->dst_y = block_h*mb_y - block_h/2;
+ avmv->src_x = avmv->dst_x + (bn->mx * s->mv_scale)/8;
+ avmv->src_y = avmv->dst_y + (bn->my * s->mv_scale)/8;
+ avmv->source= -1 - bn->ref;
+ avmv->flags = 0;
+ }
+}
+
+static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, slice_buffer * sb, int start_y, int h, int save_state[1]){
+ const int w= b->width;
+ int y;
+ const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
+ int qmul= ff_qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
+ int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
+ int new_index = 0;
+
+ if(b->ibuf == s->spatial_idwt_buffer || s->qlog == LOSSLESS_QLOG){
+ qadd= 0;
+ qmul= 1<<QEXPSHIFT;
+ }
+
+ /* If we are on the second or later slice, restore our index. */
+ if (start_y != 0)
+ new_index = save_state[0];
+
+
+ for(y=start_y; y<h; y++){
+ int x = 0;
+ int v;
+ IDWTELEM * line = slice_buffer_get_line(sb, y * b->stride_line + b->buf_y_offset) + b->buf_x_offset;
+ memset(line, 0, b->width*sizeof(IDWTELEM));
+ v = b->x_coeff[new_index].coeff;
+ x = b->x_coeff[new_index++].x;
+ while(x < w){
+ register int t= ( (v>>1)*qmul + qadd)>>QEXPSHIFT;
+ register int u= -(v&1);
+ line[x] = (t^u) - u;
+
+ v = b->x_coeff[new_index].coeff;
+ x = b->x_coeff[new_index++].x;
+ }
+ }
+
+ /* Save our variables for the next slice. */
+ save_state[0] = new_index;
+
+ return;
+}
+
+static int decode_q_branch(SnowContext *s, int level, int x, int y){
+ const int w= s->b_width << s->block_max_depth;
+ const int rem_depth= s->block_max_depth - level;
+ const int index= (x + y*w) << rem_depth;
+ int trx= (x+1)<<rem_depth;
+ const BlockNode *left = x ? &s->block[index-1] : &null_block;
+ const BlockNode *top = y ? &s->block[index-w] : &null_block;
+ const BlockNode *tl = y && x ? &s->block[index-w-1] : left;
+ const BlockNode *tr = y && trx<w && ((x&1)==0 || level==0) ? &s->block[index-w+(1<<rem_depth)] : tl; //FIXME use lt
+ int s_context= 2*left->level + 2*top->level + tl->level + tr->level;
+ int res;
+
+ if(s->keyframe){
+ set_blocks(s, level, x, y, null_block.color[0], null_block.color[1], null_block.color[2], null_block.mx, null_block.my, null_block.ref, BLOCK_INTRA);
+ return 0;
+ }
+
+ if(level==s->block_max_depth || get_rac(&s->c, &s->block_state[4 + s_context])){
+ int type, mx, my;
+ int l = left->color[0];
+ int cb= left->color[1];
+ int cr= left->color[2];
+ unsigned ref = 0;
+ int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref);
+ int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 0*av_log2(2*FFABS(tr->mx - top->mx));
+ int my_context= av_log2(2*FFABS(left->my - top->my)) + 0*av_log2(2*FFABS(tr->my - top->my));
+
+ type= get_rac(&s->c, &s->block_state[1 + left->type + top->type]) ? BLOCK_INTRA : 0;
+
+ if(type){
+ pred_mv(s, &mx, &my, 0, left, top, tr);
+ l += get_symbol(&s->c, &s->block_state[32], 1);
+ if (s->nb_planes > 2) {
+ cb+= get_symbol(&s->c, &s->block_state[64], 1);
+ cr+= get_symbol(&s->c, &s->block_state[96], 1);
+ }
+ }else{
+ if(s->ref_frames > 1)
+ ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0);
+ if (ref >= s->ref_frames) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid ref\n");
+ return AVERROR_INVALIDDATA;
+ }
+ pred_mv(s, &mx, &my, ref, left, top, tr);
+ mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1);
+ my+= get_symbol(&s->c, &s->block_state[128 + 32*(my_context + 16*!!ref)], 1);
+ }
+ set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type);
+ }else{
+ if ((res = decode_q_branch(s, level+1, 2*x+0, 2*y+0)) < 0 ||
+ (res = decode_q_branch(s, level+1, 2*x+1, 2*y+0)) < 0 ||
+ (res = decode_q_branch(s, level+1, 2*x+0, 2*y+1)) < 0 ||
+ (res = decode_q_branch(s, level+1, 2*x+1, 2*y+1)) < 0)
+ return res;
+ }
+ return 0;
+}
+
+static void dequantize_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int start_y, int end_y){
+ const int w= b->width;
+ const int qlog= av_clip(s->qlog + b->qlog, 0, QROOT*16);
+ const int qmul= ff_qexp[qlog&(QROOT-1)]<<(qlog>>QSHIFT);
+ const int qadd= (s->qbias*qmul)>>QBIAS_SHIFT;
+ int x,y;
+
+ if(s->qlog == LOSSLESS_QLOG) return;
+
+ for(y=start_y; y<end_y; y++){
+// DWTELEM * line = slice_buffer_get_line_from_address(sb, src + (y * stride));
+ IDWTELEM * line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
+ for(x=0; x<w; x++){
+ int i= line[x];
+ if(i<0){
+ line[x]= -((-i*qmul + qadd)>>(QEXPSHIFT)); //FIXME try different bias
+ }else if(i>0){
+ line[x]= (( i*qmul + qadd)>>(QEXPSHIFT));
+ }
+ }
+ }
+}
+
+static void correlate_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int inverse, int use_median, int start_y, int end_y){
+ const int w= b->width;
+ int x,y;
+
+ IDWTELEM * line=0; // silence silly "could be used without having been initialized" warning
+ IDWTELEM * prev;
+
+ if (start_y != 0)
+ line = slice_buffer_get_line(sb, ((start_y - 1) * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
+
+ for(y=start_y; y<end_y; y++){
+ prev = line;
+// line = slice_buffer_get_line_from_address(sb, src + (y * stride));
+ line = slice_buffer_get_line(sb, (y * b->stride_line) + b->buf_y_offset) + b->buf_x_offset;
+ for(x=0; x<w; x++){
+ if(x){
+ if(use_median){
+ if(y && x+1<w) line[x] += mid_pred(line[x - 1], prev[x], prev[x + 1]);
+ else line[x] += line[x - 1];
+ }else{
+ if(y) line[x] += mid_pred(line[x - 1], prev[x], line[x - 1] + prev[x] - prev[x - 1]);
+ else line[x] += line[x - 1];
+ }
+ }else{
+ if(y) line[x] += prev[x];
+ }
+ }
+ }
+}
+
+static void decode_qlogs(SnowContext *s){
+ int plane_index, level, orientation;
+
+ for(plane_index=0; plane_index < s->nb_planes; plane_index++){
+ for(level=0; level<s->spatial_decomposition_count; level++){
+ for(orientation=level ? 1:0; orientation<4; orientation++){
+ int q;
+ if (plane_index==2) q= s->plane[1].band[level][orientation].qlog;
+ else if(orientation==2) q= s->plane[plane_index].band[level][1].qlog;
+ else q= get_symbol(&s->c, s->header_state, 1);
+ s->plane[plane_index].band[level][orientation].qlog= q;
+ }
+ }
+ }
+}
+
+#define GET_S(dst, check) \
+ tmp= get_symbol(&s->c, s->header_state, 0);\
+ if(!(check)){\
+ av_log(s->avctx, AV_LOG_ERROR, "Error " #dst " is %d\n", tmp);\
+ return AVERROR_INVALIDDATA;\
+ }\
+ dst= tmp;
+
+static int decode_header(SnowContext *s){
+ int plane_index, tmp;
+ uint8_t kstate[32];
+
+ memset(kstate, MID_STATE, sizeof(kstate));
+
+ s->keyframe= get_rac(&s->c, kstate);
+ if(s->keyframe || s->always_reset){
+ ff_snow_reset_contexts(s);
+ s->spatial_decomposition_type=
+ s->qlog=
+ s->qbias=
+ s->mv_scale=
+ s->block_max_depth= 0;
+ }
+ if(s->keyframe){
+ GET_S(s->version, tmp <= 0U)
+ s->always_reset= get_rac(&s->c, s->header_state);
+ s->temporal_decomposition_type= get_symbol(&s->c, s->header_state, 0);
+ s->temporal_decomposition_count= get_symbol(&s->c, s->header_state, 0);
+ GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS)
+ s->colorspace_type= get_symbol(&s->c, s->header_state, 0);
+ if (s->colorspace_type == 1) {
+ s->avctx->pix_fmt= AV_PIX_FMT_GRAY8;
+ s->nb_planes = 1;
+ } else if(s->colorspace_type == 0) {
+ s->chroma_h_shift= get_symbol(&s->c, s->header_state, 0);
+ s->chroma_v_shift= get_symbol(&s->c, s->header_state, 0);
+
+ if(s->chroma_h_shift == 1 && s->chroma_v_shift==1){
+ s->avctx->pix_fmt= AV_PIX_FMT_YUV420P;
+ }else if(s->chroma_h_shift == 0 && s->chroma_v_shift==0){
+ s->avctx->pix_fmt= AV_PIX_FMT_YUV444P;
+ }else if(s->chroma_h_shift == 2 && s->chroma_v_shift==2){
+ s->avctx->pix_fmt= AV_PIX_FMT_YUV410P;
+ } else {
+ av_log(s, AV_LOG_ERROR, "unsupported color subsample mode %d %d\n", s->chroma_h_shift, s->chroma_v_shift);
+ s->chroma_h_shift = s->chroma_v_shift = 1;
+ s->avctx->pix_fmt= AV_PIX_FMT_YUV420P;
+ return AVERROR_INVALIDDATA;
+ }
+ s->nb_planes = 3;
+ } else {
+ av_log(s, AV_LOG_ERROR, "unsupported color space\n");
+ s->chroma_h_shift = s->chroma_v_shift = 1;
+ s->avctx->pix_fmt= AV_PIX_FMT_YUV420P;
+ return AVERROR_INVALIDDATA;
+ }
+
+
+ s->spatial_scalability= get_rac(&s->c, s->header_state);
+// s->rate_scalability= get_rac(&s->c, s->header_state);
+ GET_S(s->max_ref_frames, tmp < (unsigned)MAX_REF_FRAMES)
+ s->max_ref_frames++;
+
+ decode_qlogs(s);
+ }
+
+ if(!s->keyframe){
+ if(get_rac(&s->c, s->header_state)){
+ for(plane_index=0; plane_index<FFMIN(s->nb_planes, 2); plane_index++){
+ int htaps, i, sum=0;
+ Plane *p= &s->plane[plane_index];
+ p->diag_mc= get_rac(&s->c, s->header_state);
+ htaps= get_symbol(&s->c, s->header_state, 0)*2 + 2;
+ if((unsigned)htaps > HTAPS_MAX || htaps==0)
+ return AVERROR_INVALIDDATA;
+ p->htaps= htaps;
+ for(i= htaps/2; i; i--){
+ p->hcoeff[i]= get_symbol(&s->c, s->header_state, 0) * (1-2*(i&1));
+ sum += p->hcoeff[i];
+ }
+ p->hcoeff[0]= 32-sum;
+ }
+ s->plane[2].diag_mc= s->plane[1].diag_mc;
+ s->plane[2].htaps = s->plane[1].htaps;
+ memcpy(s->plane[2].hcoeff, s->plane[1].hcoeff, sizeof(s->plane[1].hcoeff));
+ }
+ if(get_rac(&s->c, s->header_state)){
+ GET_S(s->spatial_decomposition_count, 0 < tmp && tmp <= MAX_DECOMPOSITIONS)
+ decode_qlogs(s);
+ }
+ }
+
+ s->spatial_decomposition_type+= get_symbol(&s->c, s->header_state, 1);
+ if(s->spatial_decomposition_type > 1U){
+ av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_type %d not supported\n", s->spatial_decomposition_type);
+ return AVERROR_INVALIDDATA;
+ }
+ if(FFMIN(s->avctx-> width>>s->chroma_h_shift,
+ s->avctx->height>>s->chroma_v_shift) >> (s->spatial_decomposition_count-1) <= 1){
+ av_log(s->avctx, AV_LOG_ERROR, "spatial_decomposition_count %d too large for size\n", s->spatial_decomposition_count);
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->avctx->width > 65536-4) {
+ av_log(s->avctx, AV_LOG_ERROR, "Width %d is too large\n", s->avctx->width);
+ return AVERROR_INVALIDDATA;
+ }
+
+
+ s->qlog += get_symbol(&s->c, s->header_state, 1);
+ s->mv_scale += get_symbol(&s->c, s->header_state, 1);
+ s->qbias += get_symbol(&s->c, s->header_state, 1);
+ s->block_max_depth+= get_symbol(&s->c, s->header_state, 1);
+ if(s->block_max_depth > 1 || s->block_max_depth < 0){
+ av_log(s->avctx, AV_LOG_ERROR, "block_max_depth= %d is too large\n", s->block_max_depth);
+ s->block_max_depth= 0;
+ return AVERROR_INVALIDDATA;
+ }
+ if (FFABS(s->qbias) > 127) {
+ av_log(s->avctx, AV_LOG_ERROR, "qbias %d is too large\n", s->qbias);
+ s->qbias = 0;
+ return AVERROR_INVALIDDATA;
+ }
+
+ 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;
+ int h= s->b_height;
+ int res;
+
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ if ((res = decode_q_branch(s, 0, x, y)) < 0)
+ return res;
+ }
+ }
+ return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ SnowContext *s = avctx->priv_data;
+ RangeCoder * const c= &s->c;
+ int bytes_read;
+ AVFrame *picture = data;
+ int level, orientation, plane_index;
+ int res;
+
+ ff_init_range_decoder(c, buf, buf_size);
+ ff_build_rac_states(c, 0.05*(1LL<<32), 256-8);
+
+ s->current_picture->pict_type= AV_PICTURE_TYPE_I; //FIXME I vs. P
+ if ((res = decode_header(s)) < 0)
+ return res;
+ if ((res=ff_snow_common_init_after_header(avctx)) < 0)
+ return res;
+
+ // realloc slice buffer for the case that spatial_decomposition_count changed
+ ff_slice_buffer_destroy(&s->sb);
+ if ((res = ff_slice_buffer_init(&s->sb, s->plane[0].height,
+ (MB_SIZE >> s->block_max_depth) +
+ s->spatial_decomposition_count * 11 + 1,
+ s->plane[0].width,
+ s->spatial_idwt_buffer)) < 0)
+ return res;
+
+ for(plane_index=0; plane_index < s->nb_planes; plane_index++){
+ Plane *p= &s->plane[plane_index];
+ p->fast_mc= p->diag_mc && p->htaps==6 && p->hcoeff[0]==40
+ && p->hcoeff[1]==-10
+ && p->hcoeff[2]==2;
+ }
+
+ ff_snow_alloc_blocks(s);
+
+ if((res = ff_snow_frame_start(s)) < 0)
+ return res;
+
+ s->current_picture->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+
+ //keyframe flag duplication mess FIXME
+ if(avctx->debug&FF_DEBUG_PICT_INFO)
+ av_log(avctx, AV_LOG_ERROR,
+ "keyframe:%d qlog:%d qbias: %d mvscale: %d "
+ "decomposition_type:%d decomposition_count:%d\n",
+ s->keyframe, s->qlog, s->qbias, s->mv_scale,
+ s->spatial_decomposition_type,
+ s->spatial_decomposition_count
+ );
+
+ av_assert0(!s->avmv);
+ if (s->avctx->flags2 & AV_CODEC_FLAG2_EXPORT_MVS) {
+ s->avmv = av_malloc_array(s->b_width * s->b_height, sizeof(AVMotionVector) << (s->block_max_depth*2));
+ }
+ s->avmv_index = 0;
+
+ if ((res = decode_blocks(s)) < 0)
+ return res;
+
+ for(plane_index=0; plane_index < s->nb_planes; plane_index++){
+ Plane *p= &s->plane[plane_index];
+ int w= p->width;
+ int h= p->height;
+ int x, y;
+ int decode_state[MAX_DECOMPOSITIONS][4][1]; /* Stored state info for unpack_coeffs. 1 variable per instance. */
+
+ if(s->avctx->debug&2048){
+ memset(s->spatial_dwt_buffer, 0, sizeof(DWTELEM)*w*h);
+ predict_plane(s, s->spatial_idwt_buffer, plane_index, 1);
+
+ for(y=0; y<h; y++){
+ for(x=0; x<w; x++){
+ int v= s->current_picture->data[plane_index][y*s->current_picture->linesize[plane_index] + x];
+ s->mconly_picture->data[plane_index][y*s->mconly_picture->linesize[plane_index] + x]= v;
+ }
+ }
+ }
+
+ {
+ for(level=0; level<s->spatial_decomposition_count; level++){
+ for(orientation=level ? 1 : 0; orientation<4; orientation++){
+ SubBand *b= &p->band[level][orientation];
+ unpack_coeffs(s, b, b->parent, orientation);
+ }
+ }
+ }
+
+ {
+ const int mb_h= s->b_height << s->block_max_depth;
+ const int block_size = MB_SIZE >> s->block_max_depth;
+ const int block_h = plane_index ? block_size>>s->chroma_v_shift : block_size;
+ int mb_y;
+ DWTCompose cs[MAX_DECOMPOSITIONS];
+ int yd=0, yq=0;
+ int y;
+ int end_y;
+
+ ff_spatial_idwt_buffered_init(cs, &s->sb, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count);
+ for(mb_y=0; mb_y<=mb_h; mb_y++){
+
+ int slice_starty = block_h*mb_y;
+ int slice_h = block_h*(mb_y+1);
+
+ if (!(s->keyframe || s->avctx->debug&512)){
+ slice_starty = FFMAX(0, slice_starty - (block_h >> 1));
+ slice_h -= (block_h >> 1);
+ }
+
+ for(level=0; level<s->spatial_decomposition_count; level++){
+ for(orientation=level ? 1 : 0; orientation<4; orientation++){
+ SubBand *b= &p->band[level][orientation];
+ int start_y;
+ int end_y;
+ int our_mb_start = mb_y;
+ int our_mb_end = (mb_y + 1);
+ const int extra= 3;
+ start_y = (mb_y ? ((block_h * our_mb_start) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra: 0);
+ end_y = (((block_h * our_mb_end) >> (s->spatial_decomposition_count - level)) + s->spatial_decomposition_count - level + extra);
+ if (!(s->keyframe || s->avctx->debug&512)){
+ start_y = FFMAX(0, start_y - (block_h >> (1+s->spatial_decomposition_count - level)));
+ end_y = FFMAX(0, end_y - (block_h >> (1+s->spatial_decomposition_count - level)));
+ }
+ start_y = FFMIN(b->height, start_y);
+ end_y = FFMIN(b->height, end_y);
+
+ if (start_y != end_y){
+ if (orientation == 0){
+ SubBand * correlate_band = &p->band[0][0];
+ int correlate_end_y = FFMIN(b->height, end_y + 1);
+ int correlate_start_y = FFMIN(b->height, (start_y ? start_y + 1 : 0));
+ decode_subband_slice_buffered(s, correlate_band, &s->sb, correlate_start_y, correlate_end_y, decode_state[0][0]);
+ correlate_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, 1, 0, correlate_start_y, correlate_end_y);
+ dequantize_slice_buffered(s, &s->sb, correlate_band, correlate_band->ibuf, correlate_band->stride, start_y, end_y);
+ }
+ else
+ decode_subband_slice_buffered(s, b, &s->sb, start_y, end_y, decode_state[level][orientation]);
+ }
+ }
+ }
+
+ for(; yd<slice_h; yd+=4){
+ ff_spatial_idwt_buffered_slice(&s->dwt, cs, &s->sb, s->temp_idwt_buffer, w, h, 1, s->spatial_decomposition_type, s->spatial_decomposition_count, yd);
+ }
+
+ if(s->qlog == LOSSLESS_QLOG){
+ for(; yq<slice_h && yq<h; yq++){
+ IDWTELEM * line = slice_buffer_get_line(&s->sb, yq);
+ for(x=0; x<w; x++){
+ line[x] <<= FRAC_BITS;
+ }
+ }
+ }
+
+ predict_slice_buffered(s, &s->sb, s->spatial_idwt_buffer, plane_index, 1, mb_y);
+
+ y = FFMIN(p->height, slice_starty);
+ end_y = FFMIN(p->height, slice_h);
+ while(y < end_y)
+ ff_slice_buffer_release(&s->sb, y++);
+ }
+
+ ff_slice_buffer_flush(&s->sb);
+ }
+
+ }
+
+ emms_c();
+
+ ff_snow_release_buffer(avctx);
+
+ if(!(s->avctx->debug&2048))
+ res = av_frame_ref(picture, s->current_picture);
+ else
+ res = av_frame_ref(picture, s->mconly_picture);
+ if (res >= 0 && s->avmv_index) {
+ AVFrameSideData *sd;
+
+ sd = av_frame_new_side_data(picture, AV_FRAME_DATA_MOTION_VECTORS, s->avmv_index * sizeof(AVMotionVector));
+ if (!sd)
+ return AVERROR(ENOMEM);
+ memcpy(sd->data, s->avmv, s->avmv_index * sizeof(AVMotionVector));
+ }
+
+ av_freep(&s->avmv);
+
+ if (res < 0)
+ return res;
+
+ *got_frame = 1;
+
+ bytes_read= c->bytestream - c->bytestream_start;
+ if(bytes_read ==0) av_log(s->avctx, AV_LOG_ERROR, "error at end of frame\n"); //FIXME
+
+ return bytes_read;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ SnowContext *s = avctx->priv_data;
+
+ ff_slice_buffer_destroy(&s->sb);
+
+ ff_snow_common_end(s);
+
+ return 0;
+}
+
+AVCodec ff_snow_decoder = {
+ .name = "snow",
+ .long_name = NULL_IF_CONFIG_SMALL("Snow"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_SNOW,
+ .priv_data_size = sizeof(SnowContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 /*| AV_CODEC_CAP_DRAW_HORIZ_BAND*/,
+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE |
+ FF_CODEC_CAP_INIT_CLEANUP,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/snowenc.c b/ffmpeg-2-8-12/libavcodec/snowenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/snowenc.c
rename to ffmpeg-2-8-12/libavcodec/snowenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/sonic.c b/ffmpeg-2-8-12/libavcodec/sonic.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sonic.c
rename to ffmpeg-2-8-12/libavcodec/sonic.c
diff --git a/ffmpeg-2-8-11/libavcodec/sp5x.h b/ffmpeg-2-8-12/libavcodec/sp5x.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sp5x.h
rename to ffmpeg-2-8-12/libavcodec/sp5x.h
diff --git a/ffmpeg-2-8-11/libavcodec/sp5xdec.c b/ffmpeg-2-8-12/libavcodec/sp5xdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sp5xdec.c
rename to ffmpeg-2-8-12/libavcodec/sp5xdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/sparc/README b/ffmpeg-2-8-12/libavcodec/sparc/README
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sparc/README
rename to ffmpeg-2-8-12/libavcodec/sparc/README
diff --git a/ffmpeg-2-8-12/libavcodec/srtdec.c b/ffmpeg-2-8-12/libavcodec/srtdec.c
new file mode 100644
index 0000000..0fd651c
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/srtdec.c
@@ -0,0 +1,267 @@
+/*
+ * SubRip subtitle decoder
+ * Copyright (c) 2010 Aurelien Jacobs <aurel at gnuage.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
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/common.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/parseutils.h"
+#include "avcodec.h"
+#include "ass.h"
+
+static int html_color_parse(AVCodecContext *avctx, const char *str)
+{
+ uint8_t rgba[4];
+ if (av_parse_color(rgba, str, strcspn(str, "\" >"), avctx) < 0)
+ return -1;
+ return rgba[0] | rgba[1] << 8 | rgba[2] << 16;
+}
+
+enum {
+ PARAM_UNKNOWN = -1,
+ PARAM_SIZE,
+ PARAM_COLOR,
+ PARAM_FACE,
+ PARAM_NUMBER
+};
+
+typedef struct SrtStack {
+ char tag[128];
+ char param[PARAM_NUMBER][128];
+} SrtStack;
+
+static void rstrip_spaces_buf(AVBPrint *buf)
+{
+ if (av_bprint_is_complete(buf))
+ while (buf->len > 0 && buf->str[buf->len - 1] == ' ')
+ buf->str[--buf->len] = 0;
+}
+
+static int srt_to_ass(AVCodecContext *avctx, AVBPrint *dst,
+ const char *in, int x1, int y1, int x2, int y2)
+{
+ char *param, buffer[128], tmp[128];
+ int len, tag_close, sptr = 1, line_start = 1, an = 0, end = 0;
+ SrtStack stack[16];
+
+ stack[0].tag[0] = 0;
+ strcpy(stack[0].param[PARAM_SIZE], "{\\fs}");
+ strcpy(stack[0].param[PARAM_COLOR], "{\\c}");
+ strcpy(stack[0].param[PARAM_FACE], "{\\fn}");
+
+ if (x1 >= 0 && y1 >= 0) {
+ /* XXX: here we rescale coordinate assuming they are in DVD resolution
+ * (720x480) since we don't have anything better */
+
+ if (x2 >= 0 && y2 >= 0 && (x2 != x1 || y2 != y1) && x2 >= x1 && y2 >= y1) {
+ /* text rectangle defined, write the text at the center of the rectangle */
+ const int cx = x1 + (x2 - x1)/2;
+ const int cy = y1 + (y2 - y1)/2;
+ const int scaled_x = cx * (int64_t)ASS_DEFAULT_PLAYRESX / 720;
+ const int scaled_y = cy * (int64_t)ASS_DEFAULT_PLAYRESY / 480;
+ av_bprintf(dst, "{\\an5}{\\pos(%d,%d)}", scaled_x, scaled_y);
+ } else {
+ /* only the top left corner, assume the text starts in that corner */
+ const int scaled_x = x1 * (int64_t)ASS_DEFAULT_PLAYRESX / 720;
+ const int scaled_y = y1 * (int64_t)ASS_DEFAULT_PLAYRESY / 480;
+ av_bprintf(dst, "{\\an1}{\\pos(%d,%d)}", scaled_x, scaled_y);
+ }
+ }
+
+ for (; !end && *in; in++) {
+ switch (*in) {
+ case '\r':
+ break;
+ case '\n':
+ if (line_start) {
+ end = 1;
+ break;
+ }
+ rstrip_spaces_buf(dst);
+ av_bprintf(dst, "\\N");
+ line_start = 1;
+ break;
+ case ' ':
+ if (!line_start)
+ av_bprint_chars(dst, *in, 1);
+ break;
+ case '{': /* skip all {\xxx} substrings except for {\an%d}
+ and all microdvd like styles such as {Y:xxx} */
+ len = 0;
+ an += sscanf(in, "{\\an%*1u}%n", &len) >= 0 && len > 0;
+ if ((an != 1 && (len = 0, sscanf(in, "{\\%*[^}]}%n", &len) >= 0 && len > 0)) ||
+ (len = 0, sscanf(in, "{%*1[CcFfoPSsYy]:%*[^}]}%n", &len) >= 0 && len > 0)) {
+ in += len - 1;
+ } else
+ av_bprint_chars(dst, *in, 1);
+ break;
+ case '<':
+ tag_close = in[1] == '/';
+ len = 0;
+ if (sscanf(in+tag_close+1, "%127[^>]>%n", buffer, &len) >= 1 && len > 0) {
+ if ((param = strchr(buffer, ' ')))
+ *param++ = 0;
+ if ((!tag_close && sptr < FF_ARRAY_ELEMS(stack)) ||
+ ( tag_close && sptr > 0 && !strcmp(stack[sptr-1].tag, buffer))) {
+ int i, j, unknown = 0;
+ in += len + tag_close;
+ if (!tag_close)
+ memset(stack+sptr, 0, sizeof(*stack));
+ if (!strcmp(buffer, "font")) {
+ if (tag_close) {
+ for (i=PARAM_NUMBER-1; i>=0; i--)
+ if (stack[sptr-1].param[i][0])
+ for (j=sptr-2; j>=0; j--)
+ if (stack[j].param[i][0]) {
+ av_bprintf(dst, "%s", stack[j].param[i]);
+ break;
+ }
+ } else {
+ while (param) {
+ if (!strncmp(param, "size=", 5)) {
+ unsigned font_size;
+ param += 5 + (param[5] == '"');
+ if (sscanf(param, "%u", &font_size) == 1) {
+ snprintf(stack[sptr].param[PARAM_SIZE],
+ sizeof(stack[0].param[PARAM_SIZE]),
+ "{\\fs%u}", font_size);
+ }
+ } else if (!strncmp(param, "color=", 6)) {
+ param += 6 + (param[6] == '"');
+ snprintf(stack[sptr].param[PARAM_COLOR],
+ sizeof(stack[0].param[PARAM_COLOR]),
+ "{\\c&H%X&}",
+ html_color_parse(avctx, param));
+ } else if (!strncmp(param, "face=", 5)) {
+ param += 5 + (param[5] == '"');
+ len = strcspn(param,
+ param[-1] == '"' ? "\"" :" ");
+ av_strlcpy(tmp, param,
+ FFMIN(sizeof(tmp), len+1));
+ param += len;
+ snprintf(stack[sptr].param[PARAM_FACE],
+ sizeof(stack[0].param[PARAM_FACE]),
+ "{\\fn%s}", tmp);
+ }
+ if ((param = strchr(param, ' ')))
+ param++;
+ }
+ for (i=0; i<PARAM_NUMBER; i++)
+ if (stack[sptr].param[i][0])
+ av_bprintf(dst, "%s", stack[sptr].param[i]);
+ }
+ } else if (!buffer[1] && strspn(buffer, "bisu") == 1) {
+ av_bprintf(dst, "{\\%c%d}", buffer[0], !tag_close);
+ } else {
+ unknown = 1;
+ snprintf(tmp, sizeof(tmp), "</%s>", buffer);
+ }
+ if (tag_close) {
+ sptr--;
+ } else if (unknown && !strstr(in, tmp)) {
+ in -= len + tag_close;
+ av_bprint_chars(dst, *in, 1);
+ } else
+ av_strlcpy(stack[sptr++].tag, buffer,
+ sizeof(stack[0].tag));
+ break;
+ }
+ }
+ default:
+ av_bprint_chars(dst, *in, 1);
+ break;
+ }
+ if (*in != ' ' && *in != '\r' && *in != '\n')
+ line_start = 0;
+ }
+
+ if (!av_bprint_is_complete(dst))
+ return AVERROR(ENOMEM);
+
+ while (dst->len >= 2 && !strncmp(&dst->str[dst->len - 2], "\\N", 2))
+ dst->len -= 2;
+ dst->str[dst->len] = 0;
+ rstrip_spaces_buf(dst);
+
+ return 0;
+}
+
+static int srt_decode_frame(AVCodecContext *avctx,
+ void *data, int *got_sub_ptr, AVPacket *avpkt)
+{
+ AVSubtitle *sub = data;
+ AVBPrint buffer;
+ int ts_start, ts_end, x1 = -1, y1 = -1, x2 = -1, y2 = -1;
+ int size, ret;
+ const uint8_t *p = av_packet_get_side_data(avpkt, AV_PKT_DATA_SUBTITLE_POSITION, &size);
+
+ if (p && size == 16) {
+ x1 = AV_RL32(p );
+ y1 = AV_RL32(p + 4);
+ x2 = AV_RL32(p + 8);
+ y2 = AV_RL32(p + 12);
+ }
+
+ if (avpkt->size <= 0)
+ return avpkt->size;
+
+ av_bprint_init(&buffer, 0, AV_BPRINT_SIZE_UNLIMITED);
+
+ // TODO: reindent
+ // Do final divide-by-10 outside rescale to force rounding down.
+ ts_start = av_rescale_q(avpkt->pts,
+ avctx->time_base,
+ (AVRational){1,100});
+ ts_end = av_rescale_q(avpkt->pts + avpkt->duration,
+ avctx->time_base,
+ (AVRational){1,100});
+
+ srt_to_ass(avctx, &buffer, avpkt->data, x1, y1, x2, y2);
+ ret = ff_ass_add_rect_bprint(sub, &buffer, ts_start, ts_end-ts_start);
+ av_bprint_finalize(&buffer, NULL);
+ if (ret < 0)
+ return ret;
+
+ *got_sub_ptr = sub->num_rects > 0;
+ return avpkt->size;
+}
+
+#if CONFIG_SRT_DECODER
+/* deprecated decoder */
+AVCodec ff_srt_decoder = {
+ .name = "srt",
+ .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
+ .type = AVMEDIA_TYPE_SUBTITLE,
+ .id = AV_CODEC_ID_SUBRIP,
+ .init = ff_ass_subtitle_header_default,
+ .decode = srt_decode_frame,
+};
+#endif
+
+#if CONFIG_SUBRIP_DECODER
+AVCodec ff_subrip_decoder = {
+ .name = "subrip",
+ .long_name = NULL_IF_CONFIG_SMALL("SubRip subtitle"),
+ .type = AVMEDIA_TYPE_SUBTITLE,
+ .id = AV_CODEC_ID_SUBRIP,
+ .init = ff_ass_subtitle_header_default,
+ .decode = srt_decode_frame,
+};
+#endif
diff --git a/ffmpeg-2-8-11/libavcodec/srtenc.c b/ffmpeg-2-8-12/libavcodec/srtenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/srtenc.c
rename to ffmpeg-2-8-12/libavcodec/srtenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/startcode.c b/ffmpeg-2-8-12/libavcodec/startcode.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/startcode.c
rename to ffmpeg-2-8-12/libavcodec/startcode.c
diff --git a/ffmpeg-2-8-11/libavcodec/startcode.h b/ffmpeg-2-8-12/libavcodec/startcode.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/startcode.h
rename to ffmpeg-2-8-12/libavcodec/startcode.h
diff --git a/ffmpeg-2-8-11/libavcodec/subviewerdec.c b/ffmpeg-2-8-12/libavcodec/subviewerdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/subviewerdec.c
rename to ffmpeg-2-8-12/libavcodec/subviewerdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/sunrast.c b/ffmpeg-2-8-12/libavcodec/sunrast.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sunrast.c
rename to ffmpeg-2-8-12/libavcodec/sunrast.c
diff --git a/ffmpeg-2-8-11/libavcodec/sunrast.h b/ffmpeg-2-8-12/libavcodec/sunrast.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sunrast.h
rename to ffmpeg-2-8-12/libavcodec/sunrast.h
diff --git a/ffmpeg-2-8-11/libavcodec/sunrastenc.c b/ffmpeg-2-8-12/libavcodec/sunrastenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/sunrastenc.c
rename to ffmpeg-2-8-12/libavcodec/sunrastenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/svq1.c b/ffmpeg-2-8-12/libavcodec/svq1.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/svq1.c
rename to ffmpeg-2-8-12/libavcodec/svq1.c
diff --git a/ffmpeg-2-8-11/libavcodec/svq1.h b/ffmpeg-2-8-12/libavcodec/svq1.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/svq1.h
rename to ffmpeg-2-8-12/libavcodec/svq1.h
diff --git a/ffmpeg-2-8-11/libavcodec/svq13.c b/ffmpeg-2-8-12/libavcodec/svq13.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/svq13.c
rename to ffmpeg-2-8-12/libavcodec/svq13.c
diff --git a/ffmpeg-2-8-11/libavcodec/svq1_cb.h b/ffmpeg-2-8-12/libavcodec/svq1_cb.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/svq1_cb.h
rename to ffmpeg-2-8-12/libavcodec/svq1_cb.h
diff --git a/ffmpeg-2-8-11/libavcodec/svq1_vlc.h b/ffmpeg-2-8-12/libavcodec/svq1_vlc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/svq1_vlc.h
rename to ffmpeg-2-8-12/libavcodec/svq1_vlc.h
diff --git a/ffmpeg-2-8-11/libavcodec/svq1dec.c b/ffmpeg-2-8-12/libavcodec/svq1dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/svq1dec.c
rename to ffmpeg-2-8-12/libavcodec/svq1dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/svq1enc.c b/ffmpeg-2-8-12/libavcodec/svq1enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/svq1enc.c
rename to ffmpeg-2-8-12/libavcodec/svq1enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/svq1enc.h b/ffmpeg-2-8-12/libavcodec/svq1enc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/svq1enc.h
rename to ffmpeg-2-8-12/libavcodec/svq1enc.h
diff --git a/ffmpeg-2-8-11/libavcodec/svq1enc_cb.h b/ffmpeg-2-8-12/libavcodec/svq1enc_cb.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/svq1enc_cb.h
rename to ffmpeg-2-8-12/libavcodec/svq1enc_cb.h
diff --git a/ffmpeg-2-8-12/libavcodec/svq3.c b/ffmpeg-2-8-12/libavcodec/svq3.c
new file mode 100644
index 0000000..e05cab5
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/svq3.c
@@ -0,0 +1,1422 @@
+/*
+ * Copyright (c) 2003 The FFmpeg Project
+ *
+ * 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
+ */
+
+/*
+ * How to use this decoder:
+ * SVQ3 data is transported within Apple Quicktime files. Quicktime files
+ * have stsd atoms to describe media trak properties. A stsd atom for a
+ * video trak contains 1 or more ImageDescription atoms. These atoms begin
+ * with the 4-byte length of the atom followed by the codec fourcc. Some
+ * decoders need information in this atom to operate correctly. Such
+ * is the case with SVQ3. In order to get the best use out of this decoder,
+ * the calling app must make the SVQ3 ImageDescription atom available
+ * via the AVCodecContext's extradata[_size] field:
+ *
+ * AVCodecContext.extradata = pointer to ImageDescription, first characters
+ * are expected to be 'S', 'V', 'Q', and '3', NOT the 4-byte atom length
+ * AVCodecContext.extradata_size = size of ImageDescription atom memory
+ * buffer (which will be the same as the ImageDescription atom size field
+ * from the QT file, minus 4 bytes since the length is missing)
+ *
+ * You will know you have these parameters passed correctly when the decoder
+ * correctly decodes this file:
+ * http://samples.mplayerhq.hu/V-codecs/SVQ3/Vertical400kbit.sorenson3.mov
+ */
+
+#include <inttypes.h>
+
+#include "libavutil/attributes.h"
+#include "internal.h"
+#include "avcodec.h"
+#include "mpegutils.h"
+#include "h264.h"
+
+#include "h264data.h" // FIXME FIXME FIXME
+
+#include "h264_mvpred.h"
+#include "golomb.h"
+#include "hpeldsp.h"
+#include "rectangle.h"
+#include "tpeldsp.h"
+#include "vdpau_internal.h"
+
+#if CONFIG_ZLIB
+#include <zlib.h>
+#endif
+
+#include "svq1.h"
+#include "svq3.h"
+
+/**
+ * @file
+ * svq3 decoder.
+ */
+
+typedef struct SVQ3Context {
+ H264Context h;
+ HpelDSPContext hdsp;
+ TpelDSPContext tdsp;
+ H264Picture *cur_pic;
+ H264Picture *next_pic;
+ H264Picture *last_pic;
+ int halfpel_flag;
+ int thirdpel_flag;
+ int has_watermark;
+ int next_slice_index;
+ uint32_t watermark_key;
+ uint8_t *buf;
+ int buf_size;
+ int adaptive_quant;
+ int next_p_frame_damaged;
+ int h_edge_pos;
+ int v_edge_pos;
+ int last_frame_output;
+} SVQ3Context;
+
+#define FULLPEL_MODE 1
+#define HALFPEL_MODE 2
+#define THIRDPEL_MODE 3
+#define PREDICT_MODE 4
+
+/* dual scan (from some older h264 draft)
+ * o-->o-->o o
+ * | /|
+ * o o o / o
+ * | / | |/ |
+ * o o o o
+ * /
+ * o-->o-->o-->o
+ */
+static const uint8_t svq3_scan[16] = {
+ 0 + 0 * 4, 1 + 0 * 4, 2 + 0 * 4, 2 + 1 * 4,
+ 2 + 2 * 4, 3 + 0 * 4, 3 + 1 * 4, 3 + 2 * 4,
+ 0 + 1 * 4, 0 + 2 * 4, 1 + 1 * 4, 1 + 2 * 4,
+ 0 + 3 * 4, 1 + 3 * 4, 2 + 3 * 4, 3 + 3 * 4,
+};
+
+static const uint8_t luma_dc_zigzag_scan[16] = {
+ 0 * 16 + 0 * 64, 1 * 16 + 0 * 64, 2 * 16 + 0 * 64, 0 * 16 + 2 * 64,
+ 3 * 16 + 0 * 64, 0 * 16 + 1 * 64, 1 * 16 + 1 * 64, 2 * 16 + 1 * 64,
+ 1 * 16 + 2 * 64, 2 * 16 + 2 * 64, 3 * 16 + 2 * 64, 0 * 16 + 3 * 64,
+ 3 * 16 + 1 * 64, 1 * 16 + 3 * 64, 2 * 16 + 3 * 64, 3 * 16 + 3 * 64,
+};
+
+static const uint8_t svq3_pred_0[25][2] = {
+ { 0, 0 },
+ { 1, 0 }, { 0, 1 },
+ { 0, 2 }, { 1, 1 }, { 2, 0 },
+ { 3, 0 }, { 2, 1 }, { 1, 2 }, { 0, 3 },
+ { 0, 4 }, { 1, 3 }, { 2, 2 }, { 3, 1 }, { 4, 0 },
+ { 4, 1 }, { 3, 2 }, { 2, 3 }, { 1, 4 },
+ { 2, 4 }, { 3, 3 }, { 4, 2 },
+ { 4, 3 }, { 3, 4 },
+ { 4, 4 }
+};
+
+static const int8_t svq3_pred_1[6][6][5] = {
+ { { 2, -1, -1, -1, -1 }, { 2, 1, -1, -1, -1 }, { 1, 2, -1, -1, -1 },
+ { 2, 1, -1, -1, -1 }, { 1, 2, -1, -1, -1 }, { 1, 2, -1, -1, -1 } },
+ { { 0, 2, -1, -1, -1 }, { 0, 2, 1, 4, 3 }, { 0, 1, 2, 4, 3 },
+ { 0, 2, 1, 4, 3 }, { 2, 0, 1, 3, 4 }, { 0, 4, 2, 1, 3 } },
+ { { 2, 0, -1, -1, -1 }, { 2, 1, 0, 4, 3 }, { 1, 2, 4, 0, 3 },
+ { 2, 1, 0, 4, 3 }, { 2, 1, 4, 3, 0 }, { 1, 2, 4, 0, 3 } },
+ { { 2, 0, -1, -1, -1 }, { 2, 0, 1, 4, 3 }, { 1, 2, 0, 4, 3 },
+ { 2, 1, 0, 4, 3 }, { 2, 1, 3, 4, 0 }, { 2, 4, 1, 0, 3 } },
+ { { 0, 2, -1, -1, -1 }, { 0, 2, 1, 3, 4 }, { 1, 2, 3, 0, 4 },
+ { 2, 0, 1, 3, 4 }, { 2, 1, 3, 0, 4 }, { 2, 0, 4, 3, 1 } },
+ { { 0, 2, -1, -1, -1 }, { 0, 2, 4, 1, 3 }, { 1, 4, 2, 0, 3 },
+ { 4, 2, 0, 1, 3 }, { 2, 0, 1, 4, 3 }, { 4, 2, 1, 0, 3 } },
+};
+
+static const struct {
+ uint8_t run;
+ uint8_t level;
+} svq3_dct_tables[2][16] = {
+ { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 2, 1 }, { 0, 2 }, { 3, 1 }, { 4, 1 }, { 5, 1 },
+ { 0, 3 }, { 1, 2 }, { 2, 2 }, { 6, 1 }, { 7, 1 }, { 8, 1 }, { 9, 1 }, { 0, 4 } },
+ { { 0, 0 }, { 0, 1 }, { 1, 1 }, { 0, 2 }, { 2, 1 }, { 0, 3 }, { 0, 4 }, { 0, 5 },
+ { 3, 1 }, { 4, 1 }, { 1, 2 }, { 1, 3 }, { 0, 6 }, { 0, 7 }, { 0, 8 }, { 0, 9 } }
+};
+
+static const uint32_t svq3_dequant_coeff[32] = {
+ 3881, 4351, 4890, 5481, 6154, 6914, 7761, 8718,
+ 9781, 10987, 12339, 13828, 15523, 17435, 19561, 21873,
+ 24552, 27656, 30847, 34870, 38807, 43747, 49103, 54683,
+ 61694, 68745, 77615, 89113, 100253, 109366, 126635, 141533
+};
+
+static int svq3_decode_end(AVCodecContext *avctx);
+
+void ff_svq3_luma_dc_dequant_idct_c(int16_t *output, int16_t *input, int qp)
+{
+ const unsigned qmul = svq3_dequant_coeff[qp];
+#define stride 16
+ int i;
+ int temp[16];
+ static const uint8_t x_offset[4] = { 0, 1 * stride, 4 * stride, 5 * stride };
+
+ for (i = 0; i < 4; i++) {
+ const int z0 = 13 * (input[4 * i + 0] + input[4 * i + 2]);
+ const int z1 = 13 * (input[4 * i + 0] - input[4 * i + 2]);
+ const int z2 = 7 * input[4 * i + 1] - 17 * input[4 * i + 3];
+ const int z3 = 17 * input[4 * i + 1] + 7 * input[4 * i + 3];
+
+ temp[4 * i + 0] = z0 + z3;
+ temp[4 * i + 1] = z1 + z2;
+ temp[4 * i + 2] = z1 - z2;
+ temp[4 * i + 3] = z0 - z3;
+ }
+
+ for (i = 0; i < 4; i++) {
+ const int offset = x_offset[i];
+ const int z0 = 13 * (temp[4 * 0 + i] + temp[4 * 2 + i]);
+ const int z1 = 13 * (temp[4 * 0 + i] - temp[4 * 2 + i]);
+ const int z2 = 7 * temp[4 * 1 + i] - 17 * temp[4 * 3 + i];
+ const int z3 = 17 * temp[4 * 1 + i] + 7 * temp[4 * 3 + i];
+
+ output[stride * 0 + offset] = (int)((z0 + z3) * qmul + 0x80000) >> 20;
+ output[stride * 2 + offset] = (int)((z1 + z2) * qmul + 0x80000) >> 20;
+ output[stride * 8 + offset] = (int)((z1 - z2) * qmul + 0x80000) >> 20;
+ output[stride * 10 + offset] = (int)((z0 - z3) * qmul + 0x80000) >> 20;
+ }
+}
+#undef stride
+
+void ff_svq3_add_idct_c(uint8_t *dst, int16_t *block,
+ int stride, int qp, int dc)
+{
+ const int qmul = svq3_dequant_coeff[qp];
+ int i;
+
+ if (dc) {
+ dc = 13 * 13 * (dc == 1 ? 1538U* block[0]
+ : qmul * (block[0] >> 3) / 2);
+ block[0] = 0;
+ }
+
+ for (i = 0; i < 4; i++) {
+ const int z0 = 13 * (block[0 + 4 * i] + block[2 + 4 * i]);
+ const int z1 = 13 * (block[0 + 4 * i] - block[2 + 4 * i]);
+ const int z2 = 7 * block[1 + 4 * i] - 17 * block[3 + 4 * i];
+ const int z3 = 17 * block[1 + 4 * i] + 7 * block[3 + 4 * i];
+
+ block[0 + 4 * i] = z0 + z3;
+ block[1 + 4 * i] = z1 + z2;
+ block[2 + 4 * i] = z1 - z2;
+ block[3 + 4 * i] = z0 - z3;
+ }
+
+ for (i = 0; i < 4; i++) {
+ const unsigned z0 = 13 * (block[i + 4 * 0] + block[i + 4 * 2]);
+ const unsigned z1 = 13 * (block[i + 4 * 0] - block[i + 4 * 2]);
+ const unsigned z2 = 7 * block[i + 4 * 1] - 17 * block[i + 4 * 3];
+ const unsigned z3 = 17 * block[i + 4 * 1] + 7 * block[i + 4 * 3];
+ const int rr = (dc + 0x80000);
+
+ dst[i + stride * 0] = av_clip_uint8(dst[i + stride * 0] + ((int)((z0 + z3) * qmul + rr) >> 20));
+ dst[i + stride * 1] = av_clip_uint8(dst[i + stride * 1] + ((int)((z1 + z2) * qmul + rr) >> 20));
+ dst[i + stride * 2] = av_clip_uint8(dst[i + stride * 2] + ((int)((z1 - z2) * qmul + rr) >> 20));
+ dst[i + stride * 3] = av_clip_uint8(dst[i + stride * 3] + ((int)((z0 - z3) * qmul + rr) >> 20));
+ }
+
+ memset(block, 0, 16 * sizeof(int16_t));
+}
+
+static inline int svq3_decode_block(GetBitContext *gb, int16_t *block,
+ int index, const int type)
+{
+ static const uint8_t *const scan_patterns[4] =
+ { luma_dc_zigzag_scan, zigzag_scan, svq3_scan, chroma_dc_scan };
+
+ int run, level, sign, limit;
+ unsigned vlc;
+ const int intra = 3 * type >> 2;
+ const uint8_t *const scan = scan_patterns[type];
+
+ for (limit = (16 >> intra); index < 16; index = limit, limit += 8) {
+ for (; (vlc = svq3_get_ue_golomb(gb)) != 0; index++) {
+ if ((int32_t)vlc < 0)
+ return -1;
+
+ sign = (vlc & 1) ? 0 : -1;
+ vlc = vlc + 1 >> 1;
+
+ if (type == 3) {
+ if (vlc < 3) {
+ run = 0;
+ level = vlc;
+ } else if (vlc < 4) {
+ run = 1;
+ level = 1;
+ } else {
+ run = vlc & 0x3;
+ level = (vlc + 9 >> 2) - run;
+ }
+ } else {
+ if (vlc < 16U) {
+ run = svq3_dct_tables[intra][vlc].run;
+ level = svq3_dct_tables[intra][vlc].level;
+ } else if (intra) {
+ run = vlc & 0x7;
+ level = (vlc >> 3) + ((run == 0) ? 8 : ((run < 2) ? 2 : ((run < 5) ? 0 : -1)));
+ } else {
+ run = vlc & 0xF;
+ level = (vlc >> 4) + ((run == 0) ? 4 : ((run < 3) ? 2 : ((run < 10) ? 1 : 0)));
+ }
+ }
+
+
+ if ((index += run) >= limit)
+ return -1;
+
+ block[scan[index]] = (level ^ sign) - sign;
+ }
+
+ if (type != 2) {
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static inline void svq3_mc_dir_part(SVQ3Context *s,
+ int x, int y, int width, int height,
+ int mx, int my, int dxy,
+ int thirdpel, int dir, int avg)
+{
+ H264Context *h = &s->h;
+ H264SliceContext *sl = &h->slice_ctx[0];
+ const H264Picture *pic = (dir == 0) ? s->last_pic : s->next_pic;
+ uint8_t *src, *dest;
+ int i, emu = 0;
+ int blocksize = 2 - (width >> 3); // 16->0, 8->1, 4->2
+
+ mx += x;
+ my += y;
+
+ if (mx < 0 || mx >= s->h_edge_pos - width - 1 ||
+ my < 0 || my >= s->v_edge_pos - height - 1) {
+ emu = 1;
+ mx = av_clip(mx, -16, s->h_edge_pos - width + 15);
+ my = av_clip(my, -16, s->v_edge_pos - height + 15);
+ }
+
+ /* form component predictions */
+ dest = h->cur_pic.f->data[0] + x + y * sl->linesize;
+ src = pic->f->data[0] + mx + my * sl->linesize;
+
+ if (emu) {
+ h->vdsp.emulated_edge_mc(sl->edge_emu_buffer, src,
+ sl->linesize, sl->linesize,
+ width + 1, height + 1,
+ mx, my, s->h_edge_pos, s->v_edge_pos);
+ src = sl->edge_emu_buffer;
+ }
+ if (thirdpel)
+ (avg ? s->tdsp.avg_tpel_pixels_tab
+ : s->tdsp.put_tpel_pixels_tab)[dxy](dest, src, sl->linesize,
+ width, height);
+ else
+ (avg ? s->hdsp.avg_pixels_tab
+ : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src, sl->linesize,
+ height);
+
+ if (!(h->flags & AV_CODEC_FLAG_GRAY)) {
+ mx = mx + (mx < (int) x) >> 1;
+ my = my + (my < (int) y) >> 1;
+ width = width >> 1;
+ height = height >> 1;
+ blocksize++;
+
+ for (i = 1; i < 3; i++) {
+ dest = h->cur_pic.f->data[i] + (x >> 1) + (y >> 1) * sl->uvlinesize;
+ src = pic->f->data[i] + mx + my * sl->uvlinesize;
+
+ if (emu) {
+ h->vdsp.emulated_edge_mc(sl->edge_emu_buffer, src,
+ sl->uvlinesize, sl->uvlinesize,
+ width + 1, height + 1,
+ mx, my, (s->h_edge_pos >> 1),
+ s->v_edge_pos >> 1);
+ src = sl->edge_emu_buffer;
+ }
+ if (thirdpel)
+ (avg ? s->tdsp.avg_tpel_pixels_tab
+ : s->tdsp.put_tpel_pixels_tab)[dxy](dest, src,
+ sl->uvlinesize,
+ width, height);
+ else
+ (avg ? s->hdsp.avg_pixels_tab
+ : s->hdsp.put_pixels_tab)[blocksize][dxy](dest, src,
+ sl->uvlinesize,
+ height);
+ }
+ }
+}
+
+static inline int svq3_mc_dir(SVQ3Context *s, int size, int mode,
+ int dir, int avg)
+{
+ int i, j, k, mx, my, dx, dy, x, y;
+ H264Context *h = &s->h;
+ H264SliceContext *sl = &h->slice_ctx[0];
+ const int part_width = ((size & 5) == 4) ? 4 : 16 >> (size & 1);
+ const int part_height = 16 >> ((unsigned)(size + 1) / 3);
+ const int extra_width = (mode == PREDICT_MODE) ? -16 * 6 : 0;
+ const int h_edge_pos = 6 * (s->h_edge_pos - part_width) - extra_width;
+ const int v_edge_pos = 6 * (s->v_edge_pos - part_height) - extra_width;
+
+ for (i = 0; i < 16; i += part_height)
+ for (j = 0; j < 16; j += part_width) {
+ const int b_xy = (4 * sl->mb_x + (j >> 2)) +
+ (4 * sl->mb_y + (i >> 2)) * h->b_stride;
+ int dxy;
+ x = 16 * sl->mb_x + j;
+ y = 16 * sl->mb_y + i;
+ k = (j >> 2 & 1) + (i >> 1 & 2) +
+ (j >> 1 & 4) + (i & 8);
+
+ if (mode != PREDICT_MODE) {
+ pred_motion(h, sl, k, part_width >> 2, dir, 1, &mx, &my);
+ } else {
+ mx = s->next_pic->motion_val[0][b_xy][0] * 2;
+ my = s->next_pic->motion_val[0][b_xy][1] * 2;
+
+ if (dir == 0) {
+ mx = mx * h->frame_num_offset /
+ h->prev_frame_num_offset + 1 >> 1;
+ my = my * h->frame_num_offset /
+ h->prev_frame_num_offset + 1 >> 1;
+ } else {
+ mx = mx * (h->frame_num_offset - h->prev_frame_num_offset) /
+ h->prev_frame_num_offset + 1 >> 1;
+ my = my * (h->frame_num_offset - h->prev_frame_num_offset) /
+ h->prev_frame_num_offset + 1 >> 1;
+ }
+ }
+
+ /* clip motion vector prediction to frame border */
+ mx = av_clip(mx, extra_width - 6 * x, h_edge_pos - 6 * x);
+ my = av_clip(my, extra_width - 6 * y, v_edge_pos - 6 * y);
+
+ /* get (optional) motion vector differential */
+ if (mode == PREDICT_MODE) {
+ dx = dy = 0;
+ } else {
+ dy = svq3_get_se_golomb(&h->gb);
+ dx = svq3_get_se_golomb(&h->gb);
+
+ if (dx == INVALID_VLC || dy == INVALID_VLC) {
+ av_log(h->avctx, AV_LOG_ERROR, "invalid MV vlc\n");
+ return -1;
+ }
+ }
+
+ /* compute motion vector */
+ if (mode == THIRDPEL_MODE) {
+ int fx, fy;
+ mx = (mx + 1 >> 1) + dx;
+ my = (my + 1 >> 1) + dy;
+ fx = (unsigned)(mx + 0x30000) / 3 - 0x10000;
+ fy = (unsigned)(my + 0x30000) / 3 - 0x10000;
+ dxy = (mx - 3 * fx) + 4 * (my - 3 * fy);
+
+ svq3_mc_dir_part(s, x, y, part_width, part_height,
+ fx, fy, dxy, 1, dir, avg);
+ mx += mx;
+ my += my;
+ } else if (mode == HALFPEL_MODE || mode == PREDICT_MODE) {
+ mx = (unsigned)(mx + 1 + 0x30000) / 3 + dx - 0x10000;
+ my = (unsigned)(my + 1 + 0x30000) / 3 + dy - 0x10000;
+ dxy = (mx & 1) + 2 * (my & 1);
+
+ svq3_mc_dir_part(s, x, y, part_width, part_height,
+ mx >> 1, my >> 1, dxy, 0, dir, avg);
+ mx *= 3;
+ my *= 3;
+ } else {
+ mx = (unsigned)(mx + 3 + 0x60000) / 6 + dx - 0x10000;
+ my = (unsigned)(my + 3 + 0x60000) / 6 + dy - 0x10000;
+
+ svq3_mc_dir_part(s, x, y, part_width, part_height,
+ mx, my, 0, 0, dir, avg);
+ mx *= 6;
+ my *= 6;
+ }
+
+ /* update mv_cache */
+ if (mode != PREDICT_MODE) {
+ int32_t mv = pack16to32(mx, my);
+
+ if (part_height == 8 && i < 8) {
+ AV_WN32A(sl->mv_cache[dir][scan8[k] + 1 * 8], mv);
+
+ if (part_width == 8 && j < 8)
+ AV_WN32A(sl->mv_cache[dir][scan8[k] + 1 + 1 * 8], mv);
+ }
+ if (part_width == 8 && j < 8)
+ AV_WN32A(sl->mv_cache[dir][scan8[k] + 1], mv);
+ if (part_width == 4 || part_height == 4)
+ AV_WN32A(sl->mv_cache[dir][scan8[k]], mv);
+ }
+
+ /* write back motion vectors */
+ fill_rectangle(h->cur_pic.motion_val[dir][b_xy],
+ part_width >> 2, part_height >> 2, h->b_stride,
+ pack16to32(mx, my), 4);
+ }
+
+ return 0;
+}
+
+static int svq3_decode_mb(SVQ3Context *s, unsigned int mb_type)
+{
+ H264Context *h = &s->h;
+ H264SliceContext *sl = &h->slice_ctx[0];
+ int i, j, k, m, dir, mode;
+ int cbp = 0;
+ uint32_t vlc;
+ int8_t *top, *left;
+ const int mb_xy = sl->mb_xy;
+ const int b_xy = 4 * sl->mb_x + 4 * sl->mb_y * h->b_stride;
+
+ sl->top_samples_available = (sl->mb_y == 0) ? 0x33FF : 0xFFFF;
+ sl->left_samples_available = (sl->mb_x == 0) ? 0x5F5F : 0xFFFF;
+ sl->topright_samples_available = 0xFFFF;
+
+ if (mb_type == 0) { /* SKIP */
+ if (h->pict_type == AV_PICTURE_TYPE_P ||
+ s->next_pic->mb_type[mb_xy] == -1) {
+ svq3_mc_dir_part(s, 16 * sl->mb_x, 16 * sl->mb_y, 16, 16,
+ 0, 0, 0, 0, 0, 0);
+
+ if (h->pict_type == AV_PICTURE_TYPE_B)
+ svq3_mc_dir_part(s, 16 * sl->mb_x, 16 * sl->mb_y, 16, 16,
+ 0, 0, 0, 0, 1, 1);
+
+ mb_type = MB_TYPE_SKIP;
+ } else {
+ mb_type = FFMIN(s->next_pic->mb_type[mb_xy], 6);
+ if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 0, 0) < 0)
+ return -1;
+ if (svq3_mc_dir(s, mb_type, PREDICT_MODE, 1, 1) < 0)
+ return -1;
+
+ mb_type = MB_TYPE_16x16;
+ }
+ } else if (mb_type < 8) { /* INTER */
+ if (s->thirdpel_flag && s->halfpel_flag == !get_bits1(&h->gb))
+ mode = THIRDPEL_MODE;
+ else if (s->halfpel_flag &&
+ s->thirdpel_flag == !get_bits1(&h->gb))
+ mode = HALFPEL_MODE;
+ else
+ mode = FULLPEL_MODE;
+
+ /* fill caches */
+ /* note ref_cache should contain here:
+ * ????????
+ * ???11111
+ * N??11111
+ * N??11111
+ * N??11111
+ */
+
+ for (m = 0; m < 2; m++) {
+ if (sl->mb_x > 0 && sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6] != -1) {
+ for (i = 0; i < 4; i++)
+ AV_COPY32(sl->mv_cache[m][scan8[0] - 1 + i * 8],
+ h->cur_pic.motion_val[m][b_xy - 1 + i * h->b_stride]);
+ } else {
+ for (i = 0; i < 4; i++)
+ AV_ZERO32(sl->mv_cache[m][scan8[0] - 1 + i * 8]);
+ }
+ if (sl->mb_y > 0) {
+ memcpy(sl->mv_cache[m][scan8[0] - 1 * 8],
+ h->cur_pic.motion_val[m][b_xy - h->b_stride],
+ 4 * 2 * sizeof(int16_t));
+ memset(&sl->ref_cache[m][scan8[0] - 1 * 8],
+ (sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4);
+
+ if (sl->mb_x < h->mb_width - 1) {
+ AV_COPY32(sl->mv_cache[m][scan8[0] + 4 - 1 * 8],
+ h->cur_pic.motion_val[m][b_xy - h->b_stride + 4]);
+ sl->ref_cache[m][scan8[0] + 4 - 1 * 8] =
+ (sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride + 1] + 6] == -1 ||
+ sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1;
+ } else
+ sl->ref_cache[m][scan8[0] + 4 - 1 * 8] = PART_NOT_AVAILABLE;
+ if (sl->mb_x > 0) {
+ AV_COPY32(sl->mv_cache[m][scan8[0] - 1 - 1 * 8],
+ h->cur_pic.motion_val[m][b_xy - h->b_stride - 1]);
+ sl->ref_cache[m][scan8[0] - 1 - 1 * 8] =
+ (sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] == -1) ? PART_NOT_AVAILABLE : 1;
+ } else
+ sl->ref_cache[m][scan8[0] - 1 - 1 * 8] = PART_NOT_AVAILABLE;
+ } else
+ memset(&sl->ref_cache[m][scan8[0] - 1 * 8 - 1],
+ PART_NOT_AVAILABLE, 8);
+
+ if (h->pict_type != AV_PICTURE_TYPE_B)
+ break;
+ }
+
+ /* decode motion vector(s) and form prediction(s) */
+ if (h->pict_type == AV_PICTURE_TYPE_P) {
+ if (svq3_mc_dir(s, mb_type - 1, mode, 0, 0) < 0)
+ return -1;
+ } else { /* AV_PICTURE_TYPE_B */
+ if (mb_type != 2) {
+ if (svq3_mc_dir(s, 0, mode, 0, 0) < 0)
+ return -1;
+ } else {
+ for (i = 0; i < 4; i++)
+ memset(h->cur_pic.motion_val[0][b_xy + i * h->b_stride],
+ 0, 4 * 2 * sizeof(int16_t));
+ }
+ if (mb_type != 1) {
+ if (svq3_mc_dir(s, 0, mode, 1, mb_type == 3) < 0)
+ return -1;
+ } else {
+ for (i = 0; i < 4; i++)
+ memset(h->cur_pic.motion_val[1][b_xy + i * h->b_stride],
+ 0, 4 * 2 * sizeof(int16_t));
+ }
+ }
+
+ mb_type = MB_TYPE_16x16;
+ } else if (mb_type == 8 || mb_type == 33) { /* INTRA4x4 */
+ memset(sl->intra4x4_pred_mode_cache, -1, 8 * 5 * sizeof(int8_t));
+
+ if (mb_type == 8) {
+ if (sl->mb_x > 0) {
+ for (i = 0; i < 4; i++)
+ sl->intra4x4_pred_mode_cache[scan8[0] - 1 + i * 8] = sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1] + 6 - i];
+ if (sl->intra4x4_pred_mode_cache[scan8[0] - 1] == -1)
+ sl->left_samples_available = 0x5F5F;
+ }
+ if (sl->mb_y > 0) {
+ sl->intra4x4_pred_mode_cache[4 + 8 * 0] = sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 0];
+ sl->intra4x4_pred_mode_cache[5 + 8 * 0] = sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 1];
+ sl->intra4x4_pred_mode_cache[6 + 8 * 0] = sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 2];
+ sl->intra4x4_pred_mode_cache[7 + 8 * 0] = sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride] + 3];
+
+ if (sl->intra4x4_pred_mode_cache[4 + 8 * 0] == -1)
+ sl->top_samples_available = 0x33FF;
+ }
+
+ /* decode prediction codes for luma blocks */
+ for (i = 0; i < 16; i += 2) {
+ vlc = svq3_get_ue_golomb(&h->gb);
+
+ if (vlc >= 25U) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "luma prediction:%"PRIu32"\n", vlc);
+ return -1;
+ }
+
+ left = &sl->intra4x4_pred_mode_cache[scan8[i] - 1];
+ top = &sl->intra4x4_pred_mode_cache[scan8[i] - 8];
+
+ left[1] = svq3_pred_1[top[0] + 1][left[0] + 1][svq3_pred_0[vlc][0]];
+ left[2] = svq3_pred_1[top[1] + 1][left[1] + 1][svq3_pred_0[vlc][1]];
+
+ if (left[1] == -1 || left[2] == -1) {
+ av_log(h->avctx, AV_LOG_ERROR, "weird prediction\n");
+ return -1;
+ }
+ }
+ } else { /* mb_type == 33, DC_128_PRED block type */
+ for (i = 0; i < 4; i++)
+ memset(&sl->intra4x4_pred_mode_cache[scan8[0] + 8 * i], DC_PRED, 4);
+ }
+
+ write_back_intra_pred_mode(h, sl);
+
+ if (mb_type == 8) {
+ ff_h264_check_intra4x4_pred_mode(h, sl);
+
+ sl->top_samples_available = (sl->mb_y == 0) ? 0x33FF : 0xFFFF;
+ sl->left_samples_available = (sl->mb_x == 0) ? 0x5F5F : 0xFFFF;
+ } else {
+ for (i = 0; i < 4; i++)
+ memset(&sl->intra4x4_pred_mode_cache[scan8[0] + 8 * i], DC_128_PRED, 4);
+
+ sl->top_samples_available = 0x33FF;
+ sl->left_samples_available = 0x5F5F;
+ }
+
+ mb_type = MB_TYPE_INTRA4x4;
+ } else { /* INTRA16x16 */
+ dir = i_mb_type_info[mb_type - 8].pred_mode;
+ dir = (dir >> 1) ^ 3 * (dir & 1) ^ 1;
+
+ if ((sl->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, sl, dir, 0)) < 0) {
+ av_log(h->avctx, AV_LOG_ERROR, "ff_h264_check_intra_pred_mode < 0\n");
+ return sl->intra16x16_pred_mode;
+ }
+
+ cbp = i_mb_type_info[mb_type - 8].cbp;
+ mb_type = MB_TYPE_INTRA16x16;
+ }
+
+ if (!IS_INTER(mb_type) && h->pict_type != AV_PICTURE_TYPE_I) {
+ for (i = 0; i < 4; i++)
+ memset(h->cur_pic.motion_val[0][b_xy + i * h->b_stride],
+ 0, 4 * 2 * sizeof(int16_t));
+ if (h->pict_type == AV_PICTURE_TYPE_B) {
+ for (i = 0; i < 4; i++)
+ memset(h->cur_pic.motion_val[1][b_xy + i * h->b_stride],
+ 0, 4 * 2 * sizeof(int16_t));
+ }
+ }
+ if (!IS_INTRA4x4(mb_type)) {
+ memset(sl->intra4x4_pred_mode + h->mb2br_xy[mb_xy], DC_PRED, 8);
+ }
+ if (!IS_SKIP(mb_type) || h->pict_type == AV_PICTURE_TYPE_B) {
+ memset(sl->non_zero_count_cache + 8, 0, 14 * 8 * sizeof(uint8_t));
+ }
+
+ if (!IS_INTRA16x16(mb_type) &&
+ (!IS_SKIP(mb_type) || h->pict_type == AV_PICTURE_TYPE_B)) {
+ if ((vlc = svq3_get_ue_golomb(&h->gb)) >= 48U){
+ av_log(h->avctx, AV_LOG_ERROR, "cbp_vlc=%"PRIu32"\n", vlc);
+ return -1;
+ }
+
+ cbp = IS_INTRA(mb_type) ? golomb_to_intra4x4_cbp[vlc]
+ : golomb_to_inter_cbp[vlc];
+ }
+ if (IS_INTRA16x16(mb_type) ||
+ (h->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) {
+ sl->qscale += svq3_get_se_golomb(&h->gb);
+
+ if (sl->qscale > 31u) {
+ av_log(h->avctx, AV_LOG_ERROR, "qscale:%d\n", sl->qscale);
+ return -1;
+ }
+ }
+ if (IS_INTRA16x16(mb_type)) {
+ AV_ZERO128(sl->mb_luma_dc[0] + 0);
+ AV_ZERO128(sl->mb_luma_dc[0] + 8);
+ if (svq3_decode_block(&h->gb, sl->mb_luma_dc[0], 0, 1)) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "error while decoding intra luma dc\n");
+ return -1;
+ }
+ }
+
+ if (cbp) {
+ const int index = IS_INTRA16x16(mb_type) ? 1 : 0;
+ const int type = ((sl->qscale < 24 && IS_INTRA4x4(mb_type)) ? 2 : 1);
+
+ for (i = 0; i < 4; i++)
+ if ((cbp & (1 << i))) {
+ for (j = 0; j < 4; j++) {
+ k = index ? (1 * (j & 1) + 2 * (i & 1) +
+ 2 * (j & 2) + 4 * (i & 2))
+ : (4 * i + j);
+ sl->non_zero_count_cache[scan8[k]] = 1;
+
+ if (svq3_decode_block(&h->gb, &sl->mb[16 * k], index, type)) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "error while decoding block\n");
+ return -1;
+ }
+ }
+ }
+
+ if ((cbp & 0x30)) {
+ for (i = 1; i < 3; ++i)
+ if (svq3_decode_block(&h->gb, &sl->mb[16 * 16 * i], 0, 3)) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "error while decoding chroma dc block\n");
+ return -1;
+ }
+
+ if ((cbp & 0x20)) {
+ for (i = 1; i < 3; i++) {
+ for (j = 0; j < 4; j++) {
+ k = 16 * i + j;
+ sl->non_zero_count_cache[scan8[k]] = 1;
+
+ if (svq3_decode_block(&h->gb, &sl->mb[16 * k], 1, 1)) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "error while decoding chroma ac block\n");
+ return -1;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ sl->cbp = cbp;
+ h->cur_pic.mb_type[mb_xy] = mb_type;
+
+ if (IS_INTRA(mb_type))
+ sl->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, sl, DC_PRED8x8, 1);
+
+ return 0;
+}
+
+static int svq3_decode_slice_header(AVCodecContext *avctx)
+{
+ SVQ3Context *s = avctx->priv_data;
+ H264Context *h = &s->h;
+ H264SliceContext *sl = &h->slice_ctx[0];
+ const int mb_xy = sl->mb_xy;
+ int i, header;
+ unsigned slice_id;
+
+ header = get_bits(&h->gb, 8);
+
+ if (((header & 0x9F) != 1 && (header & 0x9F) != 2) || (header & 0x60) == 0) {
+ /* TODO: what? */
+ av_log(avctx, AV_LOG_ERROR, "unsupported slice header (%02X)\n", header);
+ return -1;
+ } else {
+ int length = header >> 5 & 3;
+
+ s->next_slice_index = get_bits_count(&h->gb) +
+ 8 * show_bits(&h->gb, 8 * length) +
+ 8 * length;
+
+ if (s->next_slice_index > h->gb.size_in_bits) {
+ av_log(avctx, AV_LOG_ERROR, "slice after bitstream end\n");
+ return -1;
+ }
+
+ h->gb.size_in_bits = s->next_slice_index - 8 * (length - 1);
+ skip_bits(&h->gb, 8);
+
+ if (s->watermark_key) {
+ uint32_t header = AV_RL32(&h->gb.buffer[(get_bits_count(&h->gb) >> 3) + 1]);
+ AV_WL32(&h->gb.buffer[(get_bits_count(&h->gb) >> 3) + 1],
+ header ^ s->watermark_key);
+ }
+ if (length > 0) {
+ memmove((uint8_t *) &h->gb.buffer[get_bits_count(&h->gb) >> 3],
+ &h->gb.buffer[h->gb.size_in_bits >> 3], length - 1);
+ }
+ skip_bits_long(&h->gb, 0);
+ }
+
+ if ((slice_id = svq3_get_ue_golomb(&h->gb)) >= 3) {
+ av_log(h->avctx, AV_LOG_ERROR, "illegal slice type %u \n", slice_id);
+ return -1;
+ }
+
+ sl->slice_type = golomb_to_pict_type[slice_id];
+
+ if ((header & 0x9F) == 2) {
+ i = (h->mb_num < 64) ? 6 : (1 + av_log2(h->mb_num - 1));
+ sl->mb_skip_run = get_bits(&h->gb, i) -
+ (sl->mb_y * h->mb_width + sl->mb_x);
+ } else {
+ skip_bits1(&h->gb);
+ sl->mb_skip_run = 0;
+ }
+
+ sl->slice_num = get_bits(&h->gb, 8);
+ sl->qscale = get_bits(&h->gb, 5);
+ s->adaptive_quant = get_bits1(&h->gb);
+
+ /* unknown fields */
+ skip_bits1(&h->gb);
+
+ if (s->has_watermark)
+ skip_bits1(&h->gb);
+
+ skip_bits1(&h->gb);
+ skip_bits(&h->gb, 2);
+
+ if (skip_1stop_8data_bits(&h->gb) < 0)
+ return AVERROR_INVALIDDATA;
+
+ /* reset intra predictors and invalidate motion vector references */
+ if (sl->mb_x > 0) {
+ memset(sl->intra4x4_pred_mode + h->mb2br_xy[mb_xy - 1] + 3,
+ -1, 4 * sizeof(int8_t));
+ memset(sl->intra4x4_pred_mode + h->mb2br_xy[mb_xy - sl->mb_x],
+ -1, 8 * sizeof(int8_t) * sl->mb_x);
+ }
+ if (sl->mb_y > 0) {
+ memset(sl->intra4x4_pred_mode + h->mb2br_xy[mb_xy - h->mb_stride],
+ -1, 8 * sizeof(int8_t) * (h->mb_width - sl->mb_x));
+
+ if (sl->mb_x > 0)
+ sl->intra4x4_pred_mode[h->mb2br_xy[mb_xy - h->mb_stride - 1] + 3] = -1;
+ }
+
+ return 0;
+}
+
+static av_cold int svq3_decode_init(AVCodecContext *avctx)
+{
+ SVQ3Context *s = avctx->priv_data;
+ H264Context *h = &s->h;
+ H264SliceContext *sl;
+ int m;
+ unsigned char *extradata;
+ unsigned char *extradata_end;
+ unsigned int size;
+ int marker_found = 0;
+ int ret;
+
+ s->cur_pic = av_mallocz(sizeof(*s->cur_pic));
+ s->last_pic = av_mallocz(sizeof(*s->last_pic));
+ s->next_pic = av_mallocz(sizeof(*s->next_pic));
+ if (!s->next_pic || !s->last_pic || !s->cur_pic) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ s->cur_pic->f = av_frame_alloc();
+ s->last_pic->f = av_frame_alloc();
+ s->next_pic->f = av_frame_alloc();
+ if (!s->cur_pic->f || !s->last_pic->f || !s->next_pic->f)
+ return AVERROR(ENOMEM);
+
+ if ((ret = ff_h264_decode_init(avctx)) < 0)
+ goto fail;
+
+ // we will overwrite it later during decoding
+ av_frame_free(&h->cur_pic.f);
+
+ av_frame_free(&h->last_pic_for_ec.f);
+
+ ff_h264dsp_init(&h->h264dsp, 8, 1);
+ av_assert0(h->sps.bit_depth_chroma == 0);
+ ff_h264_pred_init(&h->hpc, AV_CODEC_ID_SVQ3, 8, 1);
+ ff_videodsp_init(&h->vdsp, 8);
+
+ memset(h->pps.scaling_matrix4, 16, 6 * 16 * sizeof(uint8_t));
+ memset(h->pps.scaling_matrix8, 16, 2 * 64 * sizeof(uint8_t));
+
+ avctx->bits_per_raw_sample = 8;
+ h->sps.bit_depth_luma = 8;
+ h->chroma_format_idc = 1;
+
+ ff_hpeldsp_init(&s->hdsp, avctx->flags);
+ ff_tpeldsp_init(&s->tdsp);
+
+ sl = h->slice_ctx;
+
+ h->flags = avctx->flags;
+ sl->is_complex = 1;
+ h->sps.chroma_format_idc = 1;
+ h->picture_structure = PICT_FRAME;
+ avctx->pix_fmt = AV_PIX_FMT_YUVJ420P;
+ avctx->color_range = AVCOL_RANGE_JPEG;
+
+ h->slice_ctx[0].chroma_qp[0] = h->slice_ctx[0].chroma_qp[1] = 4;
+ h->chroma_x_shift = h->chroma_y_shift = 1;
+
+ s->halfpel_flag = 1;
+ s->thirdpel_flag = 1;
+ s->has_watermark = 0;
+
+ /* prowl for the "SEQH" marker in the extradata */
+ extradata = (unsigned char *)avctx->extradata;
+ extradata_end = avctx->extradata + avctx->extradata_size;
+ if (extradata) {
+ for (m = 0; m + 8 < avctx->extradata_size; m++) {
+ if (!memcmp(extradata, "SEQH", 4)) {
+ marker_found = 1;
+ break;
+ }
+ extradata++;
+ }
+ }
+
+ /* if a match was found, parse the extra data */
+ if (marker_found) {
+ GetBitContext gb;
+ int frame_size_code;
+ int unk0, unk1, unk2, unk3, unk4;
+
+ size = AV_RB32(&extradata[4]);
+ if (size > extradata_end - extradata - 8) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ init_get_bits(&gb, extradata + 8, size * 8);
+
+ /* 'frame size code' and optional 'width, height' */
+ frame_size_code = get_bits(&gb, 3);
+ switch (frame_size_code) {
+ case 0:
+ avctx->width = 160;
+ avctx->height = 120;
+ break;
+ case 1:
+ avctx->width = 128;
+ avctx->height = 96;
+ break;
+ case 2:
+ avctx->width = 176;
+ avctx->height = 144;
+ break;
+ case 3:
+ avctx->width = 352;
+ avctx->height = 288;
+ break;
+ case 4:
+ avctx->width = 704;
+ avctx->height = 576;
+ break;
+ case 5:
+ avctx->width = 240;
+ avctx->height = 180;
+ break;
+ case 6:
+ avctx->width = 320;
+ avctx->height = 240;
+ break;
+ case 7:
+ avctx->width = get_bits(&gb, 12);
+ avctx->height = get_bits(&gb, 12);
+ break;
+ }
+
+ s->halfpel_flag = get_bits1(&gb);
+ s->thirdpel_flag = get_bits1(&gb);
+
+ /* unknown fields */
+ unk0 = get_bits1(&gb);
+ unk1 = get_bits1(&gb);
+ unk2 = get_bits1(&gb);
+ unk3 = get_bits1(&gb);
+
+ h->low_delay = get_bits1(&gb);
+
+ /* unknown field */
+ unk4 = get_bits1(&gb);
+
+ 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;
+ }
+
+ s->has_watermark = get_bits1(&gb);
+ avctx->has_b_frames = !h->low_delay;
+ if (s->has_watermark) {
+#if CONFIG_ZLIB
+ unsigned watermark_width = svq3_get_ue_golomb(&gb);
+ unsigned watermark_height = svq3_get_ue_golomb(&gb);
+ int u1 = svq3_get_ue_golomb(&gb);
+ int u2 = get_bits(&gb, 8);
+ int u3 = get_bits(&gb, 2);
+ int u4 = svq3_get_ue_golomb(&gb);
+ unsigned long buf_len = watermark_width *
+ watermark_height * 4;
+ int offset = get_bits_count(&gb) + 7 >> 3;
+ uint8_t *buf;
+
+ if (watermark_height <= 0 ||
+ (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height) {
+ ret = -1;
+ goto fail;
+ }
+
+ buf = av_malloc(buf_len);
+ if (!buf) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ av_log(avctx, AV_LOG_DEBUG, "watermark size: %ux%u\n",
+ watermark_width, watermark_height);
+ av_log(avctx, AV_LOG_DEBUG,
+ "u1: %x u2: %x u3: %x compressed data size: %d offset: %d\n",
+ u1, u2, u3, u4, offset);
+ if (uncompress(buf, &buf_len, extradata + 8 + offset,
+ size - offset) != Z_OK) {
+ av_log(avctx, AV_LOG_ERROR,
+ "could not uncompress watermark logo\n");
+ av_free(buf);
+ ret = -1;
+ goto fail;
+ }
+ s->watermark_key = ff_svq1_packet_checksum(buf, buf_len, 0);
+ s->watermark_key = s->watermark_key << 16 | s->watermark_key;
+ av_log(avctx, AV_LOG_DEBUG,
+ "watermark key %#"PRIx32"\n", s->watermark_key);
+ av_free(buf);
+#else
+ av_log(avctx, AV_LOG_ERROR,
+ "this svq3 file contains watermark which need zlib support compiled in\n");
+ ret = -1;
+ goto fail;
+#endif
+ }
+ }
+
+ h->width = avctx->width;
+ h->height = avctx->height;
+ h->mb_width = (h->width + 15) / 16;
+ h->mb_height = (h->height + 15) / 16;
+ h->mb_stride = h->mb_width + 1;
+ h->mb_num = h->mb_width * h->mb_height;
+ h->b_stride = 4 * h->mb_width;
+ s->h_edge_pos = h->mb_width * 16;
+ s->v_edge_pos = h->mb_height * 16;
+
+ if ((ret = ff_h264_alloc_tables(h)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "svq3 memory allocation failed\n");
+ goto fail;
+ }
+
+ return 0;
+fail:
+ svq3_decode_end(avctx);
+ return ret;
+}
+
+static void free_picture(AVCodecContext *avctx, H264Picture *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_buffer_unref(&pic->mb_type_buf);
+
+ av_frame_unref(pic->f);
+}
+
+static int get_buffer(AVCodecContext *avctx, H264Picture *pic)
+{
+ SVQ3Context *s = avctx->priv_data;
+ H264Context *h = &s->h;
+ H264SliceContext *sl = &h->slice_ctx[0];
+ const int big_mb_num = h->mb_stride * (h->mb_height + 1) + 1;
+ const int mb_array_size = h->mb_stride * h->mb_height;
+ const int b4_stride = h->mb_width * 4 + 1;
+ const int b4_array_size = b4_stride * h->mb_height * 4;
+ int ret;
+
+ if (!pic->motion_val_buf[0]) {
+ int i;
+
+ pic->mb_type_buf = av_buffer_allocz((big_mb_num + h->mb_stride) * sizeof(uint32_t));
+ if (!pic->mb_type_buf)
+ return AVERROR(ENOMEM);
+ pic->mb_type = (uint32_t*)pic->mb_type_buf->data + 2 * h->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]) {
+ 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->reference = !(h->pict_type == AV_PICTURE_TYPE_B);
+
+ ret = ff_get_buffer(avctx, pic->f,
+ pic->reference ? AV_GET_BUFFER_FLAG_REF : 0);
+ if (ret < 0)
+ goto fail;
+
+ if (!sl->edge_emu_buffer) {
+ sl->edge_emu_buffer = av_mallocz_array(pic->f->linesize[0], 17);
+ if (!sl->edge_emu_buffer)
+ return AVERROR(ENOMEM);
+ }
+
+ sl->linesize = pic->f->linesize[0];
+ sl->uvlinesize = pic->f->linesize[1];
+
+ return 0;
+fail:
+ free_picture(avctx, pic);
+ return ret;
+}
+
+static int svq3_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame, AVPacket *avpkt)
+{
+ SVQ3Context *s = avctx->priv_data;
+ H264Context *h = &s->h;
+ H264SliceContext *sl = &h->slice_ctx[0];
+ int buf_size = avpkt->size;
+ int left;
+ uint8_t *buf;
+ int ret, m, i;
+
+ /* special case for last picture */
+ if (buf_size == 0) {
+ if (s->next_pic->f->data[0] && !h->low_delay && !s->last_frame_output) {
+ ret = av_frame_ref(data, s->next_pic->f);
+ if (ret < 0)
+ return ret;
+ s->last_frame_output = 1;
+ *got_frame = 1;
+ }
+ return 0;
+ }
+
+ sl->mb_x = sl->mb_y = sl->mb_xy = 0;
+
+ if (s->watermark_key) {
+ av_fast_padded_malloc(&s->buf, &s->buf_size, buf_size);
+ if (!s->buf)
+ return AVERROR(ENOMEM);
+ memcpy(s->buf, avpkt->data, buf_size);
+ buf = s->buf;
+ } else {
+ buf = avpkt->data;
+ }
+
+ init_get_bits(&h->gb, buf, 8 * buf_size);
+
+ if (svq3_decode_slice_header(avctx))
+ return -1;
+
+ h->pict_type = sl->slice_type;
+
+ if (h->pict_type != AV_PICTURE_TYPE_B)
+ FFSWAP(H264Picture*, s->next_pic, s->last_pic);
+
+ av_frame_unref(s->cur_pic->f);
+
+ /* for skipping the frame */
+ s->cur_pic->f->pict_type = h->pict_type;
+ s->cur_pic->f->key_frame = (h->pict_type == AV_PICTURE_TYPE_I);
+
+ ret = get_buffer(avctx, s->cur_pic);
+ if (ret < 0)
+ return ret;
+
+ h->cur_pic_ptr = s->cur_pic;
+ h->cur_pic = *s->cur_pic;
+
+ for (i = 0; i < 16; i++) {
+ h->block_offset[i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * sl->linesize * ((scan8[i] - scan8[0]) >> 3);
+ h->block_offset[48 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * sl->linesize * ((scan8[i] - scan8[0]) >> 3);
+ }
+ for (i = 0; i < 16; i++) {
+ h->block_offset[16 + i] =
+ h->block_offset[32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 4 * sl->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+ h->block_offset[48 + 16 + i] =
+ h->block_offset[48 + 32 + i] = (4 * ((scan8[i] - scan8[0]) & 7)) + 8 * sl->uvlinesize * ((scan8[i] - scan8[0]) >> 3);
+ }
+
+ if (h->pict_type != AV_PICTURE_TYPE_I) {
+ if (!s->last_pic->f->data[0]) {
+ av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
+ av_frame_unref(s->last_pic->f);
+ ret = get_buffer(avctx, s->last_pic);
+ if (ret < 0)
+ return ret;
+ memset(s->last_pic->f->data[0], 0, avctx->height * s->last_pic->f->linesize[0]);
+ memset(s->last_pic->f->data[1], 0x80, (avctx->height / 2) *
+ s->last_pic->f->linesize[1]);
+ memset(s->last_pic->f->data[2], 0x80, (avctx->height / 2) *
+ s->last_pic->f->linesize[2]);
+ }
+
+ if (h->pict_type == AV_PICTURE_TYPE_B && !s->next_pic->f->data[0]) {
+ av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n");
+ av_frame_unref(s->next_pic->f);
+ ret = get_buffer(avctx, s->next_pic);
+ if (ret < 0)
+ return ret;
+ memset(s->next_pic->f->data[0], 0, avctx->height * s->next_pic->f->linesize[0]);
+ memset(s->next_pic->f->data[1], 0x80, (avctx->height / 2) *
+ s->next_pic->f->linesize[1]);
+ memset(s->next_pic->f->data[2], 0x80, (avctx->height / 2) *
+ s->next_pic->f->linesize[2]);
+ }
+ }
+
+ if (avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(h->avctx, AV_LOG_DEBUG,
+ "%c hpel:%d, tpel:%d aqp:%d qp:%d, slice_num:%02X\n",
+ av_get_picture_type_char(h->pict_type),
+ s->halfpel_flag, s->thirdpel_flag,
+ s->adaptive_quant, h->slice_ctx[0].qscale, sl->slice_num);
+
+ if (avctx->skip_frame >= AVDISCARD_NONREF && h->pict_type == AV_PICTURE_TYPE_B ||
+ avctx->skip_frame >= AVDISCARD_NONKEY && h->pict_type != AV_PICTURE_TYPE_I ||
+ avctx->skip_frame >= AVDISCARD_ALL)
+ return 0;
+
+ if (s->next_p_frame_damaged) {
+ if (h->pict_type == AV_PICTURE_TYPE_B)
+ return 0;
+ else
+ s->next_p_frame_damaged = 0;
+ }
+
+ if (h->pict_type == AV_PICTURE_TYPE_B) {
+ h->frame_num_offset = sl->slice_num - h->prev_frame_num;
+
+ if (h->frame_num_offset < 0)
+ h->frame_num_offset += 256;
+ if (h->frame_num_offset == 0 ||
+ h->frame_num_offset >= h->prev_frame_num_offset) {
+ av_log(h->avctx, AV_LOG_ERROR, "error in B-frame picture id\n");
+ return -1;
+ }
+ } else {
+ h->prev_frame_num = h->frame_num;
+ h->frame_num = sl->slice_num;
+ h->prev_frame_num_offset = h->frame_num - h->prev_frame_num;
+
+ if (h->prev_frame_num_offset < 0)
+ h->prev_frame_num_offset += 256;
+ }
+
+ for (m = 0; m < 2; m++) {
+ int i;
+ for (i = 0; i < 4; i++) {
+ int j;
+ for (j = -1; j < 4; j++)
+ sl->ref_cache[m][scan8[0] + 8 * i + j] = 1;
+ if (i < 3)
+ sl->ref_cache[m][scan8[0] + 8 * i + j] = PART_NOT_AVAILABLE;
+ }
+ }
+
+ for (sl->mb_y = 0; sl->mb_y < h->mb_height; sl->mb_y++) {
+ for (sl->mb_x = 0; sl->mb_x < h->mb_width; sl->mb_x++) {
+ unsigned mb_type;
+ sl->mb_xy = sl->mb_x + sl->mb_y * h->mb_stride;
+
+ if ((get_bits_count(&h->gb) + 7) >= h->gb.size_in_bits &&
+ ((get_bits_count(&h->gb) & 7) == 0 ||
+ show_bits(&h->gb, -get_bits_count(&h->gb) & 7) == 0)) {
+ skip_bits(&h->gb, s->next_slice_index - get_bits_count(&h->gb));
+ h->gb.size_in_bits = 8 * buf_size;
+
+ if (svq3_decode_slice_header(avctx))
+ return -1;
+
+ /* TODO: support s->mb_skip_run */
+ }
+
+ mb_type = svq3_get_ue_golomb(&h->gb);
+
+ if (h->pict_type == AV_PICTURE_TYPE_I)
+ mb_type += 8;
+ else if (h->pict_type == AV_PICTURE_TYPE_B && mb_type >= 4)
+ mb_type += 4;
+ if (mb_type > 33 || svq3_decode_mb(s, mb_type)) {
+ av_log(h->avctx, AV_LOG_ERROR,
+ "error while decoding MB %d %d\n", sl->mb_x, sl->mb_y);
+ return -1;
+ }
+
+ if (mb_type != 0 || sl->cbp)
+ ff_h264_hl_decode_mb(h, &h->slice_ctx[0]);
+
+ if (h->pict_type != AV_PICTURE_TYPE_B && !h->low_delay)
+ h->cur_pic.mb_type[sl->mb_x + sl->mb_y * h->mb_stride] =
+ (h->pict_type == AV_PICTURE_TYPE_P && mb_type < 8) ? (mb_type - 1) : -1;
+ }
+
+ ff_draw_horiz_band(avctx, s->cur_pic->f,
+ s->last_pic->f->data[0] ? s->last_pic->f : NULL,
+ 16 * sl->mb_y, 16, h->picture_structure, 0,
+ h->low_delay);
+ }
+
+ left = buf_size*8 - get_bits_count(&h->gb);
+
+ if (sl->mb_y != h->mb_height || sl->mb_x != h->mb_width) {
+ av_log(avctx, AV_LOG_INFO, "frame num %d incomplete pic x %d y %d left %d\n", avctx->frame_number, sl->mb_y, sl->mb_x, left);
+ //av_hex_dump(stderr, buf+buf_size-8, 8);
+ }
+
+ if (left < 0) {
+ av_log(avctx, AV_LOG_ERROR, "frame num %d left %d\n", avctx->frame_number, left);
+ return -1;
+ }
+
+ if (h->pict_type == AV_PICTURE_TYPE_B || h->low_delay)
+ ret = av_frame_ref(data, s->cur_pic->f);
+ else if (s->last_pic->f->data[0])
+ ret = av_frame_ref(data, s->last_pic->f);
+ if (ret < 0)
+ return ret;
+
+ /* Do not output the last pic after seeking. */
+ if (s->last_pic->f->data[0] || h->low_delay)
+ *got_frame = 1;
+
+ if (h->pict_type != AV_PICTURE_TYPE_B) {
+ FFSWAP(H264Picture*, s->cur_pic, s->next_pic);
+ } else {
+ av_frame_unref(s->cur_pic->f);
+ }
+
+ return buf_size;
+}
+
+static av_cold int svq3_decode_end(AVCodecContext *avctx)
+{
+ SVQ3Context *s = avctx->priv_data;
+ H264Context *h = &s->h;
+
+ free_picture(avctx, s->cur_pic);
+ free_picture(avctx, s->next_pic);
+ free_picture(avctx, s->last_pic);
+ 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);
+
+ memset(&h->cur_pic, 0, sizeof(h->cur_pic));
+
+ ff_h264_free_context(h);
+
+ av_freep(&s->buf);
+ s->buf_size = 0;
+
+ return 0;
+}
+
+AVCodec ff_svq3_decoder = {
+ .name = "svq3",
+ .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 3 / Sorenson Video 3 / SVQ3"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_SVQ3,
+ .priv_data_size = sizeof(SVQ3Context),
+ .init = svq3_decode_init,
+ .close = svq3_decode_end,
+ .decode = svq3_decode_frame,
+ .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND |
+ AV_CODEC_CAP_DR1 |
+ AV_CODEC_CAP_DELAY,
+ .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P,
+ AV_PIX_FMT_NONE},
+};
diff --git a/ffmpeg-2-8-11/libavcodec/svq3.h b/ffmpeg-2-8-12/libavcodec/svq3.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/svq3.h
rename to ffmpeg-2-8-12/libavcodec/svq3.h
diff --git a/ffmpeg-2-8-11/libavcodec/synth_filter.c b/ffmpeg-2-8-12/libavcodec/synth_filter.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/synth_filter.c
rename to ffmpeg-2-8-12/libavcodec/synth_filter.c
diff --git a/ffmpeg-2-8-11/libavcodec/synth_filter.h b/ffmpeg-2-8-12/libavcodec/synth_filter.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/synth_filter.h
rename to ffmpeg-2-8-12/libavcodec/synth_filter.h
diff --git a/ffmpeg-2-8-11/libavcodec/tableprint.h b/ffmpeg-2-8-12/libavcodec/tableprint.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tableprint.h
rename to ffmpeg-2-8-12/libavcodec/tableprint.h
diff --git a/ffmpeg-2-8-11/libavcodec/tableprint_vlc.h b/ffmpeg-2-8-12/libavcodec/tableprint_vlc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tableprint_vlc.h
rename to ffmpeg-2-8-12/libavcodec/tableprint_vlc.h
diff --git a/ffmpeg-2-8-11/libavcodec/tak.c b/ffmpeg-2-8-12/libavcodec/tak.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tak.c
rename to ffmpeg-2-8-12/libavcodec/tak.c
diff --git a/ffmpeg-2-8-11/libavcodec/tak.h b/ffmpeg-2-8-12/libavcodec/tak.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tak.h
rename to ffmpeg-2-8-12/libavcodec/tak.h
diff --git a/ffmpeg-2-8-11/libavcodec/tak_parser.c b/ffmpeg-2-8-12/libavcodec/tak_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tak_parser.c
rename to ffmpeg-2-8-12/libavcodec/tak_parser.c
diff --git a/ffmpeg-2-8-12/libavcodec/takdec.c b/ffmpeg-2-8-12/libavcodec/takdec.c
new file mode 100644
index 0000000..17a848b
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/takdec.c
@@ -0,0 +1,956 @@
+/*
+ * TAK decoder
+ * Copyright (c) 2012 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
+ * TAK (Tom's lossless Audio Kompressor) decoder
+ * @author Paul B Mahol
+ */
+
+#include "libavutil/internal.h"
+#include "libavutil/samplefmt.h"
+#include "tak.h"
+#include "audiodsp.h"
+#include "thread.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "unary.h"
+
+#define MAX_SUBFRAMES 8 ///< max number of subframes per channel
+#define MAX_PREDICTORS 256
+
+typedef struct MCDParam {
+ int8_t present; ///< decorrelation parameter availability for this channel
+ int8_t index; ///< index into array of decorrelation types
+ int8_t chan1;
+ int8_t chan2;
+} MCDParam;
+
+typedef struct TAKDecContext {
+ AVCodecContext *avctx; ///< parent AVCodecContext
+ AudioDSPContext adsp;
+ TAKStreamInfo ti;
+ GetBitContext gb; ///< bitstream reader initialized to start at the current frame
+
+ int uval;
+ int nb_samples; ///< number of samples in the current frame
+ uint8_t *decode_buffer;
+ unsigned int decode_buffer_size;
+ int32_t *decoded[TAK_MAX_CHANNELS]; ///< decoded samples for each channel
+
+ int8_t lpc_mode[TAK_MAX_CHANNELS];
+ int8_t sample_shift[TAK_MAX_CHANNELS]; ///< shift applied to every sample in the channel
+ int16_t predictors[MAX_PREDICTORS];
+ int nb_subframes; ///< number of subframes in the current frame
+ int16_t subframe_len[MAX_SUBFRAMES]; ///< subframe length in samples
+ int subframe_scale;
+
+ int8_t dmode; ///< channel decorrelation type in the current frame
+
+ MCDParam mcdparams[TAK_MAX_CHANNELS]; ///< multichannel decorrelation parameters
+
+ int8_t coding_mode[128];
+ DECLARE_ALIGNED(16, int16_t, filter)[MAX_PREDICTORS];
+ DECLARE_ALIGNED(16, int16_t, residues)[544];
+} TAKDecContext;
+
+static const int8_t mc_dmodes[] = { 1, 3, 4, 6, };
+
+static const uint16_t predictor_sizes[] = {
+ 4, 8, 12, 16, 24, 32, 48, 64, 80, 96, 128, 160, 192, 224, 256, 0,
+};
+
+static const struct CParam {
+ int init;
+ int escape;
+ int scale;
+ int aescape;
+ int bias;
+} xcodes[50] = {
+ { 0x01, 0x0000001, 0x0000001, 0x0000003, 0x0000008 },
+ { 0x02, 0x0000003, 0x0000001, 0x0000007, 0x0000006 },
+ { 0x03, 0x0000005, 0x0000002, 0x000000E, 0x000000D },
+ { 0x03, 0x0000003, 0x0000003, 0x000000D, 0x0000018 },
+ { 0x04, 0x000000B, 0x0000004, 0x000001C, 0x0000019 },
+ { 0x04, 0x0000006, 0x0000006, 0x000001A, 0x0000030 },
+ { 0x05, 0x0000016, 0x0000008, 0x0000038, 0x0000032 },
+ { 0x05, 0x000000C, 0x000000C, 0x0000034, 0x0000060 },
+ { 0x06, 0x000002C, 0x0000010, 0x0000070, 0x0000064 },
+ { 0x06, 0x0000018, 0x0000018, 0x0000068, 0x00000C0 },
+ { 0x07, 0x0000058, 0x0000020, 0x00000E0, 0x00000C8 },
+ { 0x07, 0x0000030, 0x0000030, 0x00000D0, 0x0000180 },
+ { 0x08, 0x00000B0, 0x0000040, 0x00001C0, 0x0000190 },
+ { 0x08, 0x0000060, 0x0000060, 0x00001A0, 0x0000300 },
+ { 0x09, 0x0000160, 0x0000080, 0x0000380, 0x0000320 },
+ { 0x09, 0x00000C0, 0x00000C0, 0x0000340, 0x0000600 },
+ { 0x0A, 0x00002C0, 0x0000100, 0x0000700, 0x0000640 },
+ { 0x0A, 0x0000180, 0x0000180, 0x0000680, 0x0000C00 },
+ { 0x0B, 0x0000580, 0x0000200, 0x0000E00, 0x0000C80 },
+ { 0x0B, 0x0000300, 0x0000300, 0x0000D00, 0x0001800 },
+ { 0x0C, 0x0000B00, 0x0000400, 0x0001C00, 0x0001900 },
+ { 0x0C, 0x0000600, 0x0000600, 0x0001A00, 0x0003000 },
+ { 0x0D, 0x0001600, 0x0000800, 0x0003800, 0x0003200 },
+ { 0x0D, 0x0000C00, 0x0000C00, 0x0003400, 0x0006000 },
+ { 0x0E, 0x0002C00, 0x0001000, 0x0007000, 0x0006400 },
+ { 0x0E, 0x0001800, 0x0001800, 0x0006800, 0x000C000 },
+ { 0x0F, 0x0005800, 0x0002000, 0x000E000, 0x000C800 },
+ { 0x0F, 0x0003000, 0x0003000, 0x000D000, 0x0018000 },
+ { 0x10, 0x000B000, 0x0004000, 0x001C000, 0x0019000 },
+ { 0x10, 0x0006000, 0x0006000, 0x001A000, 0x0030000 },
+ { 0x11, 0x0016000, 0x0008000, 0x0038000, 0x0032000 },
+ { 0x11, 0x000C000, 0x000C000, 0x0034000, 0x0060000 },
+ { 0x12, 0x002C000, 0x0010000, 0x0070000, 0x0064000 },
+ { 0x12, 0x0018000, 0x0018000, 0x0068000, 0x00C0000 },
+ { 0x13, 0x0058000, 0x0020000, 0x00E0000, 0x00C8000 },
+ { 0x13, 0x0030000, 0x0030000, 0x00D0000, 0x0180000 },
+ { 0x14, 0x00B0000, 0x0040000, 0x01C0000, 0x0190000 },
+ { 0x14, 0x0060000, 0x0060000, 0x01A0000, 0x0300000 },
+ { 0x15, 0x0160000, 0x0080000, 0x0380000, 0x0320000 },
+ { 0x15, 0x00C0000, 0x00C0000, 0x0340000, 0x0600000 },
+ { 0x16, 0x02C0000, 0x0100000, 0x0700000, 0x0640000 },
+ { 0x16, 0x0180000, 0x0180000, 0x0680000, 0x0C00000 },
+ { 0x17, 0x0580000, 0x0200000, 0x0E00000, 0x0C80000 },
+ { 0x17, 0x0300000, 0x0300000, 0x0D00000, 0x1800000 },
+ { 0x18, 0x0B00000, 0x0400000, 0x1C00000, 0x1900000 },
+ { 0x18, 0x0600000, 0x0600000, 0x1A00000, 0x3000000 },
+ { 0x19, 0x1600000, 0x0800000, 0x3800000, 0x3200000 },
+ { 0x19, 0x0C00000, 0x0C00000, 0x3400000, 0x6000000 },
+ { 0x1A, 0x2C00000, 0x1000000, 0x7000000, 0x6400000 },
+ { 0x1A, 0x1800000, 0x1800000, 0x6800000, 0xC000000 },
+};
+
+static int set_bps_params(AVCodecContext *avctx)
+{
+ switch (avctx->bits_per_raw_sample) {
+ case 8:
+ avctx->sample_fmt = AV_SAMPLE_FMT_U8P;
+ break;
+ case 16:
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+ break;
+ case 24:
+ avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "invalid/unsupported bits per sample: %d\n",
+ avctx->bits_per_raw_sample);
+ return AVERROR_INVALIDDATA;
+ }
+
+ return 0;
+}
+
+static void set_sample_rate_params(AVCodecContext *avctx)
+{
+ TAKDecContext *s = avctx->priv_data;
+ int shift = 3 - (avctx->sample_rate / 11025);
+ shift = FFMAX(0, shift);
+ s->uval = FFALIGN(avctx->sample_rate + 511 >> 9, 4) << shift;
+ s->subframe_scale = FFALIGN(avctx->sample_rate + 511 >> 9, 4) << 1;
+}
+
+static av_cold int tak_decode_init(AVCodecContext *avctx)
+{
+ TAKDecContext *s = avctx->priv_data;
+
+ ff_audiodsp_init(&s->adsp);
+
+ s->avctx = avctx;
+ avctx->bits_per_raw_sample = avctx->bits_per_coded_sample;
+
+ set_sample_rate_params(avctx);
+
+ return set_bps_params(avctx);
+}
+
+static void decode_lpc(int32_t *coeffs, int mode, int length)
+{
+ int i;
+
+ if (length < 2)
+ return;
+
+ if (mode == 1) {
+ int a1 = *coeffs++;
+ for (i = 0; i < length - 1 >> 1; i++) {
+ *coeffs += a1;
+ coeffs[1] += *coeffs;
+ a1 = coeffs[1];
+ coeffs += 2;
+ }
+ if (length - 1 & 1)
+ *coeffs += a1;
+ } else if (mode == 2) {
+ int a1 = coeffs[1];
+ int a2 = a1 + *coeffs;
+ coeffs[1] = a2;
+ if (length > 2) {
+ coeffs += 2;
+ for (i = 0; i < length - 2 >> 1; i++) {
+ int a3 = *coeffs + a1;
+ int a4 = a3 + a2;
+ *coeffs = a4;
+ a1 = coeffs[1] + a3;
+ a2 = a1 + a4;
+ coeffs[1] = a2;
+ coeffs += 2;
+ }
+ if (length & 1)
+ *coeffs += a1 + a2;
+ }
+ } else if (mode == 3) {
+ int a1 = coeffs[1];
+ int a2 = a1 + *coeffs;
+ coeffs[1] = a2;
+ if (length > 2) {
+ int a3 = coeffs[2];
+ int a4 = a3 + a1;
+ int a5 = a4 + a2;
+ coeffs[2] = a5;
+ coeffs += 3;
+ for (i = 0; i < length - 3; i++) {
+ a3 += *coeffs;
+ a4 += a3;
+ a5 += a4;
+ *coeffs = a5;
+ coeffs++;
+ }
+ }
+ }
+}
+
+static int decode_segment(TAKDecContext *s, int8_t mode, int32_t *decoded, int len)
+{
+ struct CParam code;
+ GetBitContext *gb = &s->gb;
+ int i;
+
+ if (!mode) {
+ memset(decoded, 0, len * sizeof(*decoded));
+ return 0;
+ }
+
+ if (mode > FF_ARRAY_ELEMS(xcodes))
+ return AVERROR_INVALIDDATA;
+ code = xcodes[mode - 1];
+
+ for (i = 0; i < len; i++) {
+ unsigned x = get_bits_long(gb, code.init);
+ if (x >= code.escape && get_bits1(gb)) {
+ x |= 1 << code.init;
+ if (x >= code.aescape) {
+ unsigned scale = get_unary(gb, 1, 9);
+ if (scale == 9) {
+ int scale_bits = get_bits(gb, 3);
+ if (scale_bits > 0) {
+ if (scale_bits == 7) {
+ scale_bits += get_bits(gb, 5);
+ if (scale_bits > 29)
+ return AVERROR_INVALIDDATA;
+ }
+ scale = get_bits_long(gb, scale_bits) + 1;
+ x += code.scale * scale;
+ }
+ x += code.bias;
+ } else
+ x += code.scale * scale - code.escape;
+ } else
+ x -= code.escape;
+ }
+ decoded[i] = (x >> 1) ^ -(x & 1);
+ }
+
+ return 0;
+}
+
+static int decode_residues(TAKDecContext *s, int32_t *decoded, int length)
+{
+ GetBitContext *gb = &s->gb;
+ int i, mode, ret;
+
+ if (length > s->nb_samples)
+ return AVERROR_INVALIDDATA;
+
+ if (get_bits1(gb)) {
+ int wlength, rval;
+
+ wlength = length / s->uval;
+
+ rval = length - (wlength * s->uval);
+
+ if (rval < s->uval / 2)
+ rval += s->uval;
+ else
+ wlength++;
+
+ if (wlength <= 1 || wlength > 128)
+ return AVERROR_INVALIDDATA;
+
+ s->coding_mode[0] = mode = get_bits(gb, 6);
+
+ for (i = 1; i < wlength; i++) {
+ int c = get_unary(gb, 1, 6);
+
+ switch (c) {
+ case 6:
+ mode = get_bits(gb, 6);
+ break;
+ case 5:
+ case 4:
+ case 3: {
+ /* mode += sign ? (1 - c) : (c - 1) */
+ int sign = get_bits1(gb);
+ mode += (-sign ^ (c - 1)) + sign;
+ break;
+ }
+ case 2:
+ mode++;
+ break;
+ case 1:
+ mode--;
+ break;
+ }
+ s->coding_mode[i] = mode;
+ }
+
+ i = 0;
+ while (i < wlength) {
+ int len = 0;
+
+ mode = s->coding_mode[i];
+ do {
+ if (i >= wlength - 1)
+ len += rval;
+ else
+ len += s->uval;
+ i++;
+
+ if (i == wlength)
+ break;
+ } while (s->coding_mode[i] == mode);
+
+ if ((ret = decode_segment(s, mode, decoded, len)) < 0)
+ return ret;
+ decoded += len;
+ }
+ } else {
+ mode = get_bits(gb, 6);
+ if ((ret = decode_segment(s, mode, decoded, length)) < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static int get_bits_esc4(GetBitContext *gb)
+{
+ if (get_bits1(gb))
+ return get_bits(gb, 4) + 1;
+ else
+ return 0;
+}
+
+static int decode_subframe(TAKDecContext *s, int32_t *decoded,
+ int subframe_size, int prev_subframe_size)
+{
+ GetBitContext *gb = &s->gb;
+ int x, y, i, j, ret = 0;
+ int dshift, size, filter_quant, filter_order;
+ int tfilter[MAX_PREDICTORS];
+
+ if (!get_bits1(gb))
+ return decode_residues(s, decoded, subframe_size);
+
+ filter_order = predictor_sizes[get_bits(gb, 4)];
+
+ if (prev_subframe_size > 0 && get_bits1(gb)) {
+ if (filter_order > prev_subframe_size)
+ return AVERROR_INVALIDDATA;
+
+ decoded -= filter_order;
+ subframe_size += filter_order;
+
+ if (filter_order > subframe_size)
+ return AVERROR_INVALIDDATA;
+ } else {
+ int lpc_mode;
+
+ if (filter_order > subframe_size)
+ return AVERROR_INVALIDDATA;
+
+ lpc_mode = get_bits(gb, 2);
+ if (lpc_mode > 2)
+ return AVERROR_INVALIDDATA;
+
+ if ((ret = decode_residues(s, decoded, filter_order)) < 0)
+ return ret;
+
+ if (lpc_mode)
+ decode_lpc(decoded, lpc_mode, filter_order);
+ }
+
+ dshift = get_bits_esc4(gb);
+ size = get_bits1(gb) + 6;
+
+ filter_quant = 10;
+ if (get_bits1(gb)) {
+ filter_quant -= get_bits(gb, 3) + 1;
+ if (filter_quant < 3)
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->predictors[0] = get_sbits(gb, 10);
+ s->predictors[1] = get_sbits(gb, 10);
+ s->predictors[2] = get_sbits(gb, size) * (1 << (10 - size));
+ s->predictors[3] = get_sbits(gb, size) * (1 << (10 - size));
+ if (filter_order > 4) {
+ int tmp = size - get_bits1(gb);
+
+ for (i = 4; i < filter_order; i++) {
+ if (!(i & 3))
+ x = tmp - get_bits(gb, 2);
+ s->predictors[i] = get_sbits(gb, x) * (1 << (10 - size));
+ }
+ }
+
+ tfilter[0] = s->predictors[0] * 64;
+ for (i = 1; i < filter_order; i++) {
+ int32_t *p1 = &tfilter[0];
+ int32_t *p2 = &tfilter[i - 1];
+
+ for (j = 0; j < (i + 1) / 2; j++) {
+ x = *p1 + (s->predictors[i] * *p2 + 256 >> 9);
+ *p2 += s->predictors[i] * *p1 + 256 >> 9;
+ *p1++ = x;
+ p2--;
+ }
+
+ tfilter[i] = s->predictors[i] * 64;
+ }
+
+ x = 1 << (32 - (15 - filter_quant));
+ y = 1 << ((15 - filter_quant) - 1);
+ for (i = 0, j = filter_order - 1; i < filter_order / 2; i++, j--) {
+ s->filter[j] = x - ((tfilter[i] + y) >> (15 - filter_quant));
+ s->filter[i] = x - ((tfilter[j] + y) >> (15 - filter_quant));
+ }
+
+ if ((ret = decode_residues(s, &decoded[filter_order],
+ subframe_size - filter_order)) < 0)
+ return ret;
+
+ for (i = 0; i < filter_order; i++)
+ s->residues[i] = *decoded++ >> dshift;
+
+ y = FF_ARRAY_ELEMS(s->residues) - filter_order;
+ x = subframe_size - filter_order;
+ while (x > 0) {
+ int tmp = FFMIN(y, x);
+
+ for (i = 0; i < tmp; i++) {
+ int v = 1 << (filter_quant - 1);
+
+ if (filter_order & -16)
+ v += s->adsp.scalarproduct_int16(&s->residues[i], s->filter,
+ filter_order & -16);
+ for (j = filter_order & -16; j < filter_order; j += 4) {
+ v += s->residues[i + j + 3] * s->filter[j + 3] +
+ s->residues[i + j + 2] * s->filter[j + 2] +
+ s->residues[i + j + 1] * s->filter[j + 1] +
+ s->residues[i + j ] * s->filter[j ];
+ }
+ v = (av_clip_intp2(v >> filter_quant, 13) * (1 << dshift)) - *decoded;
+ *decoded++ = v;
+ s->residues[filter_order + i] = v >> dshift;
+ }
+
+ x -= tmp;
+ if (x > 0)
+ memcpy(s->residues, &s->residues[y], 2 * filter_order);
+ }
+
+ emms_c();
+
+ return 0;
+}
+
+static int decode_channel(TAKDecContext *s, int chan)
+{
+ AVCodecContext *avctx = s->avctx;
+ GetBitContext *gb = &s->gb;
+ int32_t *decoded = s->decoded[chan];
+ int left = s->nb_samples - 1;
+ int i = 0, ret, prev = 0;
+
+ s->sample_shift[chan] = get_bits_esc4(gb);
+ if (s->sample_shift[chan] >= avctx->bits_per_raw_sample)
+ return AVERROR_INVALIDDATA;
+
+ *decoded++ = get_sbits(gb, avctx->bits_per_raw_sample - s->sample_shift[chan]);
+ s->lpc_mode[chan] = get_bits(gb, 2);
+ s->nb_subframes = get_bits(gb, 3) + 1;
+
+ if (s->nb_subframes > 1) {
+ if (get_bits_left(gb) < (s->nb_subframes - 1) * 6)
+ return AVERROR_INVALIDDATA;
+
+ for (; i < s->nb_subframes - 1; i++) {
+ int v = get_bits(gb, 6);
+
+ s->subframe_len[i] = (v - prev) * s->subframe_scale;
+ if (s->subframe_len[i] <= 0)
+ return AVERROR_INVALIDDATA;
+
+ left -= s->subframe_len[i];
+ prev = v;
+ }
+
+ if (left <= 0)
+ return AVERROR_INVALIDDATA;
+ }
+ s->subframe_len[i] = left;
+
+ prev = 0;
+ for (i = 0; i < s->nb_subframes; i++) {
+ if ((ret = decode_subframe(s, decoded, s->subframe_len[i], prev)) < 0)
+ return ret;
+ decoded += s->subframe_len[i];
+ prev = s->subframe_len[i];
+ }
+
+ return 0;
+}
+
+static int decorrelate(TAKDecContext *s, int c1, int c2, int length)
+{
+ GetBitContext *gb = &s->gb;
+ int32_t *p1 = s->decoded[c1] + 1;
+ int32_t *p2 = s->decoded[c2] + 1;
+ int i;
+ int dshift, dfactor;
+
+ switch (s->dmode) {
+ case 1: /* left/side */
+ for (i = 0; i < length; i++) {
+ int32_t a = p1[i];
+ int32_t b = p2[i];
+ p2[i] = a + b;
+ }
+ break;
+ case 2: /* side/right */
+ for (i = 0; i < length; i++) {
+ int32_t a = p1[i];
+ int32_t b = p2[i];
+ p1[i] = b - a;
+ }
+ break;
+ case 3: /* side/mid */
+ for (i = 0; i < length; i++) {
+ int32_t a = p1[i];
+ int32_t b = p2[i];
+ a -= b >> 1;
+ p1[i] = a;
+ p2[i] = a + b;
+ }
+ break;
+ case 4: /* side/left with scale factor */
+ FFSWAP(int32_t*, p1, p2);
+ case 5: /* side/right with scale factor */
+ dshift = get_bits_esc4(gb);
+ dfactor = get_sbits(gb, 10);
+ for (i = 0; i < length; i++) {
+ int32_t a = p1[i];
+ int32_t b = p2[i];
+ b = dfactor * (b >> dshift) + 128 >> 8 << dshift;
+ p1[i] = b - a;
+ }
+ break;
+ case 6:
+ FFSWAP(int32_t*, p1, p2);
+ case 7: {
+ int length2, order_half, filter_order, dval1, dval2;
+ int tmp, x, code_size;
+
+ if (length < 256)
+ return AVERROR_INVALIDDATA;
+
+ dshift = get_bits_esc4(gb);
+ filter_order = 8 << get_bits1(gb);
+ dval1 = get_bits1(gb);
+ dval2 = get_bits1(gb);
+
+ for (i = 0; i < filter_order; i++) {
+ if (!(i & 3))
+ code_size = 14 - get_bits(gb, 3);
+ s->filter[i] = get_sbits(gb, code_size);
+ }
+
+ order_half = filter_order / 2;
+ length2 = length - (filter_order - 1);
+
+ /* decorrelate beginning samples */
+ if (dval1) {
+ for (i = 0; i < order_half; i++) {
+ int32_t a = p1[i];
+ int32_t b = p2[i];
+ p1[i] = a + b;
+ }
+ }
+
+ /* decorrelate ending samples */
+ if (dval2) {
+ for (i = length2 + order_half; i < length; i++) {
+ int32_t a = p1[i];
+ int32_t b = p2[i];
+ p1[i] = a + b;
+ }
+ }
+
+
+ for (i = 0; i < filter_order; i++)
+ s->residues[i] = *p2++ >> dshift;
+
+ p1 += order_half;
+ x = FF_ARRAY_ELEMS(s->residues) - filter_order;
+ for (; length2 > 0; length2 -= tmp) {
+ tmp = FFMIN(length2, x);
+
+ for (i = 0; i < tmp - (tmp == length2); i++)
+ s->residues[filter_order + i] = *p2++ >> dshift;
+
+ for (i = 0; i < tmp; i++) {
+ int v = 1 << 9;
+
+ if (filter_order == 16) {
+ v += s->adsp.scalarproduct_int16(&s->residues[i], s->filter,
+ filter_order);
+ } else {
+ v += s->residues[i + 7] * s->filter[7] +
+ s->residues[i + 6] * s->filter[6] +
+ s->residues[i + 5] * s->filter[5] +
+ s->residues[i + 4] * s->filter[4] +
+ s->residues[i + 3] * s->filter[3] +
+ s->residues[i + 2] * s->filter[2] +
+ s->residues[i + 1] * s->filter[1] +
+ s->residues[i ] * s->filter[0];
+ }
+
+ v = (av_clip_intp2(v >> 10, 13) << dshift) - *p1;
+ *p1++ = v;
+ }
+
+ memmove(s->residues, &s->residues[tmp], 2 * filter_order);
+ }
+
+ emms_c();
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int tak_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *pkt)
+{
+ TAKDecContext *s = avctx->priv_data;
+ AVFrame *frame = data;
+ ThreadFrame tframe = { .f = data };
+ GetBitContext *gb = &s->gb;
+ int chan, i, ret, hsize;
+
+ if (pkt->size < TAK_MIN_FRAME_HEADER_BYTES)
+ return AVERROR_INVALIDDATA;
+
+ if ((ret = init_get_bits8(gb, pkt->data, pkt->size)) < 0)
+ return ret;
+
+ if ((ret = ff_tak_decode_frame_header(avctx, gb, &s->ti, 0)) < 0)
+ return ret;
+
+ hsize = get_bits_count(gb) / 8;
+ if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_COMPLIANT)) {
+ if (ff_tak_check_crc(pkt->data, hsize)) {
+ av_log(avctx, AV_LOG_ERROR, "CRC error\n");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if (s->ti.codec != TAK_CODEC_MONO_STEREO &&
+ s->ti.codec != TAK_CODEC_MULTICHANNEL) {
+ av_log(avctx, AV_LOG_ERROR, "unsupported codec: %d\n", s->ti.codec);
+ return AVERROR_PATCHWELCOME;
+ }
+ if (s->ti.data_type) {
+ av_log(avctx, AV_LOG_ERROR,
+ "unsupported data type: %d\n", s->ti.data_type);
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->ti.codec == TAK_CODEC_MONO_STEREO && s->ti.channels > 2) {
+ av_log(avctx, AV_LOG_ERROR,
+ "invalid number of channels: %d\n", s->ti.channels);
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->ti.channels > 6) {
+ av_log(avctx, AV_LOG_ERROR,
+ "unsupported number of channels: %d\n", s->ti.channels);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->ti.frame_samples <= 0) {
+ av_log(avctx, AV_LOG_ERROR, "unsupported/invalid number of samples\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ avctx->bits_per_raw_sample = s->ti.bps;
+ if ((ret = set_bps_params(avctx)) < 0)
+ return ret;
+ if (s->ti.sample_rate != avctx->sample_rate) {
+ avctx->sample_rate = s->ti.sample_rate;
+ set_sample_rate_params(avctx);
+ }
+ if (s->ti.ch_layout)
+ avctx->channel_layout = s->ti.ch_layout;
+ avctx->channels = s->ti.channels;
+
+ s->nb_samples = s->ti.last_frame_samples ? s->ti.last_frame_samples
+ : s->ti.frame_samples;
+
+ frame->nb_samples = s->nb_samples;
+ if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
+ return ret;
+ ff_thread_finish_setup(avctx);
+
+ if (avctx->bits_per_raw_sample <= 16) {
+ int buf_size = av_samples_get_buffer_size(NULL, avctx->channels,
+ s->nb_samples,
+ AV_SAMPLE_FMT_S32P, 0);
+ if (buf_size < 0)
+ return buf_size;
+ av_fast_malloc(&s->decode_buffer, &s->decode_buffer_size, buf_size);
+ if (!s->decode_buffer)
+ return AVERROR(ENOMEM);
+ ret = av_samples_fill_arrays((uint8_t **)s->decoded, NULL,
+ s->decode_buffer, avctx->channels,
+ s->nb_samples, AV_SAMPLE_FMT_S32P, 0);
+ if (ret < 0)
+ return ret;
+ } else {
+ for (chan = 0; chan < avctx->channels; chan++)
+ s->decoded[chan] = (int32_t *)frame->extended_data[chan];
+ }
+
+ if (s->nb_samples < 16) {
+ for (chan = 0; chan < avctx->channels; chan++) {
+ int32_t *decoded = s->decoded[chan];
+ for (i = 0; i < s->nb_samples; i++)
+ decoded[i] = get_sbits(gb, avctx->bits_per_raw_sample);
+ }
+ } else {
+ if (s->ti.codec == TAK_CODEC_MONO_STEREO) {
+ for (chan = 0; chan < avctx->channels; chan++)
+ if (ret = decode_channel(s, chan))
+ return ret;
+
+ if (avctx->channels == 2) {
+ s->nb_subframes = get_bits(gb, 1) + 1;
+ if (s->nb_subframes > 1) {
+ s->subframe_len[1] = get_bits(gb, 6);
+ }
+
+ s->dmode = get_bits(gb, 3);
+ if (ret = decorrelate(s, 0, 1, s->nb_samples - 1))
+ return ret;
+ }
+ } else if (s->ti.codec == TAK_CODEC_MULTICHANNEL) {
+ if (get_bits1(gb)) {
+ int ch_mask = 0;
+
+ chan = get_bits(gb, 4) + 1;
+ if (chan > avctx->channels)
+ return AVERROR_INVALIDDATA;
+
+ for (i = 0; i < chan; i++) {
+ int nbit = get_bits(gb, 4);
+
+ if (nbit >= avctx->channels)
+ return AVERROR_INVALIDDATA;
+
+ if (ch_mask & 1 << nbit)
+ return AVERROR_INVALIDDATA;
+
+ s->mcdparams[i].present = get_bits1(gb);
+ if (s->mcdparams[i].present) {
+ s->mcdparams[i].index = get_bits(gb, 2);
+ s->mcdparams[i].chan2 = get_bits(gb, 4);
+ if (s->mcdparams[i].chan2 >= avctx->channels) {
+ av_log(avctx, AV_LOG_ERROR,
+ "invalid channel 2 (%d) for %d channel(s)\n",
+ s->mcdparams[i].chan2, avctx->channels);
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->mcdparams[i].index == 1) {
+ if ((nbit == s->mcdparams[i].chan2) ||
+ (ch_mask & 1 << s->mcdparams[i].chan2))
+ return AVERROR_INVALIDDATA;
+
+ ch_mask |= 1 << s->mcdparams[i].chan2;
+ } else if (!(ch_mask & 1 << s->mcdparams[i].chan2)) {
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ s->mcdparams[i].chan1 = nbit;
+
+ ch_mask |= 1 << nbit;
+ }
+ } else {
+ chan = avctx->channels;
+ for (i = 0; i < chan; i++) {
+ s->mcdparams[i].present = 0;
+ s->mcdparams[i].chan1 = i;
+ }
+ }
+
+ for (i = 0; i < chan; i++) {
+ if (s->mcdparams[i].present && s->mcdparams[i].index == 1)
+ if (ret = decode_channel(s, s->mcdparams[i].chan2))
+ return ret;
+
+ if (ret = decode_channel(s, s->mcdparams[i].chan1))
+ return ret;
+
+ if (s->mcdparams[i].present) {
+ s->dmode = mc_dmodes[s->mcdparams[i].index];
+ if (ret = decorrelate(s,
+ s->mcdparams[i].chan2,
+ s->mcdparams[i].chan1,
+ s->nb_samples - 1))
+ return ret;
+ }
+ }
+ }
+
+ for (chan = 0; chan < avctx->channels; chan++) {
+ int32_t *decoded = s->decoded[chan];
+
+ if (s->lpc_mode[chan])
+ decode_lpc(decoded, s->lpc_mode[chan], s->nb_samples);
+
+ if (s->sample_shift[chan] > 0)
+ for (i = 0; i < s->nb_samples; i++)
+ decoded[i] *= 1 << s->sample_shift[chan];
+ }
+ }
+
+ align_get_bits(gb);
+ skip_bits(gb, 24);
+ if (get_bits_left(gb) < 0)
+ av_log(avctx, AV_LOG_DEBUG, "overread\n");
+ else if (get_bits_left(gb) > 0)
+ av_log(avctx, AV_LOG_DEBUG, "underread\n");
+
+ if (avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_COMPLIANT)) {
+ if (ff_tak_check_crc(pkt->data + hsize,
+ get_bits_count(gb) / 8 - hsize)) {
+ av_log(avctx, AV_LOG_ERROR, "CRC error\n");
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ /* convert to output buffer */
+ switch (avctx->sample_fmt) {
+ case AV_SAMPLE_FMT_U8P:
+ for (chan = 0; chan < avctx->channels; chan++) {
+ uint8_t *samples = (uint8_t *)frame->extended_data[chan];
+ int32_t *decoded = s->decoded[chan];
+ for (i = 0; i < s->nb_samples; i++)
+ samples[i] = decoded[i] + 0x80;
+ }
+ break;
+ case AV_SAMPLE_FMT_S16P:
+ for (chan = 0; chan < avctx->channels; chan++) {
+ int16_t *samples = (int16_t *)frame->extended_data[chan];
+ int32_t *decoded = s->decoded[chan];
+ for (i = 0; i < s->nb_samples; i++)
+ samples[i] = decoded[i];
+ }
+ break;
+ case AV_SAMPLE_FMT_S32P:
+ for (chan = 0; chan < avctx->channels; chan++) {
+ int32_t *samples = (int32_t *)frame->extended_data[chan];
+ for (i = 0; i < s->nb_samples; i++)
+ samples[i] *= 1 << 8;
+ }
+ break;
+ }
+
+ *got_frame_ptr = 1;
+
+ return pkt->size;
+}
+
+static int init_thread_copy(AVCodecContext *avctx)
+{
+ TAKDecContext *s = avctx->priv_data;
+ s->avctx = avctx;
+ return 0;
+}
+
+static int update_thread_context(AVCodecContext *dst,
+ const AVCodecContext *src)
+{
+ TAKDecContext *tsrc = src->priv_data;
+ TAKDecContext *tdst = dst->priv_data;
+
+ if (dst == src)
+ return 0;
+ memcpy(&tdst->ti, &tsrc->ti, sizeof(TAKStreamInfo));
+ return 0;
+}
+
+static av_cold int tak_decode_close(AVCodecContext *avctx)
+{
+ TAKDecContext *s = avctx->priv_data;
+
+ av_freep(&s->decode_buffer);
+
+ return 0;
+}
+
+AVCodec ff_tak_decoder = {
+ .name = "tak",
+ .long_name = NULL_IF_CONFIG_SMALL("TAK (Tom's lossless Audio Kompressor)"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_TAK,
+ .priv_data_size = sizeof(TAKDecContext),
+ .init = tak_decode_init,
+ .close = tak_decode_close,
+ .decode = tak_decode_frame,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(update_thread_context),
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_U8P,
+ AV_SAMPLE_FMT_S16P,
+ AV_SAMPLE_FMT_S32P,
+ AV_SAMPLE_FMT_NONE },
+};
diff --git a/ffmpeg-2-8-11/libavcodec/targa.c b/ffmpeg-2-8-12/libavcodec/targa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/targa.c
rename to ffmpeg-2-8-12/libavcodec/targa.c
diff --git a/ffmpeg-2-8-11/libavcodec/targa.h b/ffmpeg-2-8-12/libavcodec/targa.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/targa.h
rename to ffmpeg-2-8-12/libavcodec/targa.h
diff --git a/ffmpeg-2-8-12/libavcodec/targa_y216dec.c b/ffmpeg-2-8-12/libavcodec/targa_y216dec.c
new file mode 100644
index 0000000..443d48a
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/targa_y216dec.c
@@ -0,0 +1,84 @@
+/*
+ * Pinnacle TARGA CineWave YUV16 decoder
+ * Copyright (c) 2012 Carl Eugen Hoyos
+ *
+ * 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"
+
+static av_cold int y216_decode_init(AVCodecContext *avctx)
+{
+ avctx->pix_fmt = AV_PIX_FMT_YUV422P16;
+ avctx->bits_per_raw_sample = 14;
+
+ return 0;
+}
+
+static int y216_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame, AVPacket *avpkt)
+{
+ AVFrame *pic = data;
+ const uint16_t *src = (uint16_t *)avpkt->data;
+ uint16_t *y, *u, *v;
+ int aligned_width = FFALIGN(avctx->width, 4);
+ int i, j, ret;
+
+ if (avpkt->size < 4 * avctx->height * aligned_width) {
+ av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
+ return AVERROR(EINVAL);
+ }
+
+ if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
+ return ret;
+
+ pic->key_frame = 1;
+ pic->pict_type = AV_PICTURE_TYPE_I;
+
+ y = (uint16_t *)pic->data[0];
+ u = (uint16_t *)pic->data[1];
+ v = (uint16_t *)pic->data[2];
+
+ for (i = 0; i < avctx->height; i++) {
+ for (j = 0; j < avctx->width >> 1; j++) {
+ u[ j ] = src[4 * j ] << 2 | src[4 * j ] >> 14;
+ y[2 * j ] = src[4 * j + 1] << 2 | src[4 * j + 1] >> 14;
+ v[ j ] = src[4 * j + 2] << 2 | src[4 * j + 2] >> 14;
+ y[2 * j + 1] = src[4 * j + 3] << 2 | src[4 * j + 3] >> 14;
+ }
+
+ y += pic->linesize[0] >> 1;
+ u += pic->linesize[1] >> 1;
+ v += pic->linesize[2] >> 1;
+ src += aligned_width << 1;
+ }
+
+ *got_frame = 1;
+
+ return avpkt->size;
+}
+
+AVCodec ff_targa_y216_decoder = {
+ .name = "targa_y216",
+ .long_name = NULL_IF_CONFIG_SMALL("Pinnacle TARGA CineWave YUV16"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_TARGA_Y216,
+ .init = y216_decode_init,
+ .decode = y216_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/targaenc.c b/ffmpeg-2-8-12/libavcodec/targaenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/targaenc.c
rename to ffmpeg-2-8-12/libavcodec/targaenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/tdsc.c b/ffmpeg-2-8-12/libavcodec/tdsc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tdsc.c
rename to ffmpeg-2-8-12/libavcodec/tdsc.c
diff --git a/ffmpeg-2-8-11/libavcodec/textdec.c b/ffmpeg-2-8-12/libavcodec/textdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/textdec.c
rename to ffmpeg-2-8-12/libavcodec/textdec.c
diff --git a/ffmpeg-2-8-12/libavcodec/texturedsp.c b/ffmpeg-2-8-12/libavcodec/texturedsp.c
new file mode 100644
index 0000000..9e30f8c
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/texturedsp.c
@@ -0,0 +1,610 @@
+/*
+ * Texture block decompression
+ * Copyright (C) 2009 Benjamin Dobell, Glass Echidna
+ * Copyright (C) 2012 Matthäus G. "Anteru" Chajdas (http://anteru.net)
+ * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara at gmail.com>
+ *
+ * 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 <stddef.h>
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/common.h"
+#include "libavutil/intreadwrite.h"
+
+#include "texturedsp.h"
+
+#define RGBA(r, g, b, a) ((r) | ((g) << 8) | ((b) << 16) | ((a) << 24))
+
+static av_always_inline void extract_color(uint32_t colors[4],
+ uint16_t color0,
+ uint16_t color1,
+ int dxtn, int alpha)
+{
+ int tmp;
+ uint8_t r0, g0, b0, r1, g1, b1;
+ uint8_t a = dxtn ? 0 : 255;
+
+ tmp = (color0 >> 11) * 255 + 16;
+ r0 = (uint8_t) ((tmp / 32 + tmp) / 32);
+ tmp = ((color0 & 0x07E0) >> 5) * 255 + 32;
+ g0 = (uint8_t) ((tmp / 64 + tmp) / 64);
+ tmp = (color0 & 0x001F) * 255 + 16;
+ b0 = (uint8_t) ((tmp / 32 + tmp) / 32);
+
+ tmp = (color1 >> 11) * 255 + 16;
+ r1 = (uint8_t) ((tmp / 32 + tmp) / 32);
+ tmp = ((color1 & 0x07E0) >> 5) * 255 + 32;
+ g1 = (uint8_t) ((tmp / 64 + tmp) / 64);
+ tmp = (color1 & 0x001F) * 255 + 16;
+ b1 = (uint8_t) ((tmp / 32 + tmp) / 32);
+
+ if (dxtn || color0 > color1) {
+ colors[0] = RGBA(r0, g0, b0, a);
+ colors[1] = RGBA(r1, g1, b1, a);
+ colors[2] = RGBA((2 * r0 + r1) / 3,
+ (2 * g0 + g1) / 3,
+ (2 * b0 + b1) / 3,
+ a);
+ colors[3] = RGBA((2 * r1 + r0) / 3,
+ (2 * g1 + g0) / 3,
+ (2 * b1 + b0) / 3,
+ a);
+ } else {
+ colors[0] = RGBA(r0, g0, b0, a);
+ colors[1] = RGBA(r1, g1, b1, a);
+ colors[2] = RGBA((r0 + r1) / 2,
+ (g0 + g1) / 2,
+ (b0 + b1) / 2,
+ a);
+ colors[3] = RGBA(0, 0, 0, alpha);
+ }
+}
+
+static inline void dxt1_block_internal(uint8_t *dst, ptrdiff_t stride,
+ const uint8_t *block, uint8_t alpha)
+{
+ int x, y;
+ uint32_t colors[4];
+ uint16_t color0 = AV_RL16(block + 0);
+ uint16_t color1 = AV_RL16(block + 2);
+ uint32_t code = AV_RL32(block + 4);
+
+ extract_color(colors, color0, color1, 0, alpha);
+
+ for (y = 0; y < 4; y++) {
+ for (x = 0; x < 4; x++) {
+ uint32_t pixel = colors[code & 3];
+ code >>= 2;
+ AV_WL32(dst + x * 4, pixel);
+ }
+ dst += stride;
+ }
+}
+
+/**
+ * Decompress one block of a DXT1 texture and store the resulting
+ * RGBA pixels in 'dst'. Alpha component is fully opaque.
+ *
+ * @param dst output buffer.
+ * @param stride scanline in bytes.
+ * @param block block to decompress.
+ * @return how much texture data has been consumed.
+ */
+static int dxt1_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
+{
+ dxt1_block_internal(dst, stride, block, 255);
+
+ return 8;
+}
+
+/**
+ * Decompress one block of a DXT1 with 1-bit alpha texture and store
+ * the resulting RGBA pixels in 'dst'. Alpha is either fully opaque or
+ * fully transparent.
+ *
+ * @param dst output buffer.
+ * @param stride scanline in bytes.
+ * @param block block to decompress.
+ * @return how much texture data has been consumed.
+ */
+static int dxt1a_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
+{
+ dxt1_block_internal(dst, stride, block, 0);
+
+ return 8;
+}
+
+static inline void dxt3_block_internal(uint8_t *dst, ptrdiff_t stride,
+ const uint8_t *block)
+{
+ int x, y;
+ uint32_t colors[4];
+ uint16_t color0 = AV_RL16(block + 8);
+ uint16_t color1 = AV_RL16(block + 10);
+ uint32_t code = AV_RL32(block + 12);
+
+ extract_color(colors, color0, color1, 1, 0);
+
+ for (y = 0; y < 4; y++) {
+ const uint16_t alpha_code = AV_RL16(block + 2 * y);
+ uint8_t alpha_values[4];
+
+ alpha_values[0] = ((alpha_code >> 0) & 0x0F) * 17;
+ alpha_values[1] = ((alpha_code >> 4) & 0x0F) * 17;
+ alpha_values[2] = ((alpha_code >> 8) & 0x0F) * 17;
+ alpha_values[3] = ((alpha_code >> 12) & 0x0F) * 17;
+
+ for (x = 0; x < 4; x++) {
+ uint8_t alpha = alpha_values[x];
+ uint32_t pixel = colors[code & 3] | ((unsigned)alpha << 24);
+ code >>= 2;
+
+ AV_WL32(dst + x * 4, pixel);
+ }
+ dst += stride;
+ }
+}
+
+/** Convert a premultiplied alpha pixel to a straigth alpha pixel. */
+static av_always_inline void premult2straight(uint8_t *src)
+{
+ int r = src[0];
+ int g = src[1];
+ int b = src[2];
+ int a = src[3]; /* unchanged */
+
+ src[0] = (uint8_t) r * a / 255;
+ src[1] = (uint8_t) g * a / 255;
+ src[2] = (uint8_t) b * a / 255;
+}
+
+/**
+ * Decompress one block of a DXT2 texture and store the resulting
+ * RGBA pixels in 'dst'.
+ *
+ * @param dst output buffer.
+ * @param stride scanline in bytes.
+ * @param block block to decompress.
+ * @return how much texture data has been consumed.
+ */
+static int dxt2_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
+{
+ int x, y;
+
+ dxt3_block_internal(dst, stride, block);
+
+ /* This format is DXT3, but returns premultiplied alpha. It needs to be
+ * converted because it's what lavc outputs (and swscale expects). */
+ for (y = 0; y < 4; y++)
+ for (x = 0; x < 4; x++)
+ premult2straight(dst + x * 4 + y * stride);
+
+ return 16;
+}
+
+/**
+ * Decompress one block of a DXT3 texture and store the resulting
+ * RGBA pixels in 'dst'.
+ *
+ * @param dst output buffer.
+ * @param stride scanline in bytes.
+ * @param block block to decompress.
+ * @return how much texture data has been consumed.
+ */
+static int dxt3_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
+{
+ dxt3_block_internal(dst, stride, block);
+
+ return 16;
+}
+
+/**
+ * Decompress a BC 16x3 index block stored as
+ * h g f e
+ * d c b a
+ * p o n m
+ * l k j i
+ *
+ * Bits packed as
+ * | h | g | f | e | d | c | b | a | // Entry
+ * |765 432 107 654 321 076 543 210| // Bit
+ * |0000000000111111111112222222222| // Byte
+ *
+ * into 16 8-bit indices.
+ */
+static void decompress_indices(uint8_t *dst, const uint8_t *src)
+{
+ int block, i;
+
+ for (block = 0; block < 2; block++) {
+ int tmp = AV_RL24(src);
+
+ /* Unpack 8x3 bit from last 3 byte block */
+ for (i = 0; i < 8; i++)
+ dst[i] = (tmp >> (i * 3)) & 0x7;
+
+ src += 3;
+ dst += 8;
+ }
+}
+
+static inline void dxt5_block_internal(uint8_t *dst, ptrdiff_t stride,
+ const uint8_t *block)
+{
+ int x, y;
+ uint32_t colors[4];
+ uint8_t alpha_indices[16];
+ uint16_t color0 = AV_RL16(block + 8);
+ uint16_t color1 = AV_RL16(block + 10);
+ uint32_t code = AV_RL32(block + 12);
+ uint8_t alpha0 = *(block);
+ uint8_t alpha1 = *(block + 1);
+
+ decompress_indices(alpha_indices, block + 2);
+
+ extract_color(colors, color0, color1, 1, 0);
+
+ for (y = 0; y < 4; y++) {
+ for (x = 0; x < 4; x++) {
+ int alpha_code = alpha_indices[x + y * 4];
+ uint32_t pixel;
+ uint8_t alpha;
+
+ if (alpha_code == 0) {
+ alpha = alpha0;
+ } else if (alpha_code == 1) {
+ alpha = alpha1;
+ } else {
+ if (alpha0 > alpha1) {
+ alpha = (uint8_t) (((8 - alpha_code) * alpha0 +
+ (alpha_code - 1) * alpha1) / 7);
+ } else {
+ if (alpha_code == 6) {
+ alpha = 0;
+ } else if (alpha_code == 7) {
+ alpha = 255;
+ } else {
+ alpha = (uint8_t) (((6 - alpha_code) * alpha0 +
+ (alpha_code - 1) * alpha1) / 5);
+ }
+ }
+ }
+ pixel = colors[code & 3] | ((unsigned)alpha << 24);
+ code >>= 2;
+ AV_WL32(dst + x * 4, pixel);
+ }
+ dst += stride;
+ }
+}
+
+/**
+ * Decompress one block of a DXT4 texture and store the resulting
+ * RGBA pixels in 'dst'.
+ *
+ * @param dst output buffer.
+ * @param stride scanline in bytes.
+ * @param block block to decompress.
+ * @return how much texture data has been consumed.
+ */
+static int dxt4_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
+{
+ int x, y;
+
+ dxt5_block_internal(dst, stride, block);
+
+ /* This format is DXT5, but returns premultiplied alpha. It needs to be
+ * converted because it's what lavc outputs (and swscale expects). */
+ for (y = 0; y < 4; y++)
+ for (x = 0; x < 4; x++)
+ premult2straight(dst + x * 4 + y * stride);
+
+ return 16;
+}
+
+/**
+ * Decompress one block of a DXT5 texture and store the resulting
+ * RGBA pixels in 'dst'.
+ *
+ * @param dst output buffer.
+ * @param stride scanline in bytes.
+ * @param block block to decompress.
+ * @return how much texture data has been consumed.
+ */
+static int dxt5_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
+{
+ dxt5_block_internal(dst, stride, block);
+
+ return 16;
+}
+
+/**
+ * Convert a YCoCg buffer to RGBA.
+ *
+ * @param src input buffer.
+ * @param scaled variant with scaled chroma components and opaque alpha.
+ */
+static av_always_inline void ycocg2rgba(uint8_t *src, int scaled)
+{
+ int r = src[0];
+ int g = src[1];
+ int b = src[2];
+ int a = src[3];
+
+ int s = scaled ? (b >> 3) + 1 : 1;
+ int y = a;
+ int co = (r - 128) / s;
+ int cg = (g - 128) / s;
+
+ src[0] = av_clip_uint8(y + co - cg);
+ src[1] = av_clip_uint8(y + cg);
+ src[2] = av_clip_uint8(y - co - cg);
+ src[3] = scaled ? 255 : b;
+}
+
+/**
+ * Decompress one block of a DXT5 texture with classic YCoCg and store
+ * the resulting RGBA pixels in 'dst'. Alpha component is fully opaque.
+ *
+ * @param dst output buffer.
+ * @param stride scanline in bytes.
+ * @param block block to decompress.
+ * @return how much texture data has been consumed.
+ */
+static int dxt5y_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
+{
+ int x, y;
+
+ /* This format is basically DXT5, with luma stored in alpha.
+ * Run a normal decompress and then reorder the components. */
+ dxt5_block_internal(dst, stride, block);
+
+ for (y = 0; y < 4; y++)
+ for (x = 0; x < 4; x++)
+ ycocg2rgba(dst + x * 4 + y * stride, 0);
+
+ return 16;
+}
+
+/**
+ * Decompress one block of a DXT5 texture with scaled YCoCg and store
+ * the resulting RGBA pixels in 'dst'. Alpha component is fully opaque.
+ *
+ * @param dst output buffer.
+ * @param stride scanline in bytes.
+ * @param block block to decompress.
+ * @return how much texture data has been consumed.
+ */
+static int dxt5ys_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
+{
+ int x, y;
+
+ /* This format is basically DXT5, with luma stored in alpha.
+ * Run a normal decompress and then reorder the components. */
+ dxt5_block_internal(dst, stride, block);
+
+ for (y = 0; y < 4; y++)
+ for (x = 0; x < 4; x++)
+ ycocg2rgba(dst + x * 4 + y * stride, 1);
+
+ return 16;
+}
+
+static inline void rgtc_block_internal(uint8_t *dst, ptrdiff_t stride,
+ const uint8_t *block,
+ const int *color_tab)
+{
+ uint8_t indices[16];
+ int x, y;
+
+ decompress_indices(indices, block + 2);
+
+ /* Only one or two channels are stored at most, since it only used to
+ * compress specular (black and white) or normal (red and green) maps.
+ * Although the standard says to zero out unused components, many
+ * implementations fill all of them with the same value. */
+ for (y = 0; y < 4; y++) {
+ for (x = 0; x < 4; x++) {
+ int i = indices[x + y * 4];
+ /* Interval expansion from [-1 1] or [0 1] to [0 255]. */
+ int c = color_tab[i];
+ uint32_t pixel = RGBA(c, c, c, 255U);
+ AV_WL32(dst + x * 4 + y * stride, pixel);
+ }
+ }
+}
+
+static inline void rgtc1_block_internal(uint8_t *dst, ptrdiff_t stride,
+ const uint8_t *block, int sign)
+{
+ int color_table[8];
+ int r0, r1;
+
+ if (sign) {
+ /* signed data is in [-128 127] so just offset it to unsigned
+ * and it can be treated exactly the same */
+ r0 = ((int8_t) block[0]) + 128;
+ r1 = ((int8_t) block[1]) + 128;
+ } else {
+ r0 = block[0];
+ r1 = block[1];
+ }
+
+ color_table[0] = r0;
+ color_table[1] = r1;
+
+ if (r0 > r1) {
+ /* 6 interpolated color values */
+ color_table[2] = (6 * r0 + 1 * r1) / 7; // bit code 010
+ color_table[3] = (5 * r0 + 2 * r1) / 7; // bit code 011
+ color_table[4] = (4 * r0 + 3 * r1) / 7; // bit code 100
+ color_table[5] = (3 * r0 + 4 * r1) / 7; // bit code 101
+ color_table[6] = (2 * r0 + 5 * r1) / 7; // bit code 110
+ color_table[7] = (1 * r0 + 6 * r1) / 7; // bit code 111
+ } else {
+ /* 4 interpolated color values */
+ color_table[2] = (4 * r0 + 1 * r1) / 5; // bit code 010
+ color_table[3] = (3 * r0 + 2 * r1) / 5; // bit code 011
+ color_table[4] = (2 * r0 + 3 * r1) / 5; // bit code 100
+ color_table[5] = (1 * r0 + 4 * r1) / 5; // bit code 101
+ color_table[6] = 0; /* min range */ // bit code 110
+ color_table[7] = 255; /* max range */ // bit code 111
+ }
+
+ rgtc_block_internal(dst, stride, block, color_table);
+}
+
+/**
+ * Decompress one block of a RGRC1 texture with signed components
+ * and store the resulting RGBA pixels in 'dst'.
+ *
+ * @param dst output buffer.
+ * @param stride scanline in bytes.
+ * @param block block to decompress.
+ * @return how much texture data has been consumed.
+ */
+static int rgtc1s_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
+{
+ rgtc1_block_internal(dst, stride, block, 1);
+
+ return 8;
+}
+
+/**
+ * Decompress one block of a RGRC1 texture with unsigned components
+ * and store the resulting RGBA pixels in 'dst'.
+ *
+ * @param dst output buffer.
+ * @param stride scanline in bytes.
+ * @param block block to decompress.
+ * @return how much texture data has been consumed.
+ */
+static int rgtc1u_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
+{
+ rgtc1_block_internal(dst, stride, block, 0);
+
+ return 8;
+}
+
+static inline void rgtc2_block_internal(uint8_t *dst, ptrdiff_t stride,
+ const uint8_t *block, int sign)
+{
+ /* 4x4 block containing 4 component pixels. */
+ uint8_t c0[4 * 4 * 4];
+ uint8_t c1[4 * 4 * 4];
+ int x, y;
+
+ /* Decompress the two channels separately and interleave them afterwards. */
+ rgtc1_block_internal(c0, 16, block, sign);
+ rgtc1_block_internal(c1, 16, block + 8, sign);
+
+ /* B is rebuilt exactly like a normal map. */
+ for (y = 0; y < 4; y++) {
+ for (x = 0; x < 4; x++) {
+ uint8_t *p = dst + x * 4 + y * stride;
+ int r = c0[x * 4 + y * 16];
+ int g = c1[x * 4 + y * 16];
+ int b = 127;
+
+ int d = (255 * 255 - r * r - g * g) / 2;
+ if (d > 0)
+ b = rint(sqrtf(d));
+
+ p[0] = r;
+ p[1] = g;
+ p[2] = b;
+ p[3] = 255;
+ }
+ }
+}
+
+/**
+ * Decompress one block of a RGRC2 texture with signed components
+ * and store the resulting RGBA pixels in 'dst'. Alpha is fully opaque.
+ *
+ * @param dst output buffer.
+ * @param stride scanline in bytes.
+ * @param block block to decompress.
+ * @return how much texture data has been consumed.
+ */
+static int rgtc2s_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
+{
+ rgtc2_block_internal(dst, stride, block, 1);
+
+ return 16;
+}
+
+/**
+ * Decompress one block of a RGRC2 texture with unsigned components
+ * and store the resulting RGBA pixels in 'dst'. Alpha is fully opaque.
+ *
+ * @param dst output buffer.
+ * @param stride scanline in bytes.
+ * @param block block to decompress.
+ * @return how much texture data has been consumed.
+ */
+static int rgtc2u_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
+{
+ rgtc2_block_internal(dst, stride, block, 0);
+
+ return 16;
+}
+
+/**
+ * Decompress one block of a 3Dc texture with unsigned components
+ * and store the resulting RGBA pixels in 'dst'. Alpha is fully opaque.
+ *
+ * @param dst output buffer.
+ * @param stride scanline in bytes.
+ * @param block block to decompress.
+ * @return how much texture data has been consumed.
+ */
+static int dxn3dc_block(uint8_t *dst, ptrdiff_t stride, const uint8_t *block)
+{
+ int x, y;
+ rgtc2_block_internal(dst, stride, block, 0);
+
+ /* This is the 3Dc variant of RGTC2, with swapped R and G. */
+ for (y = 0; y < 4; y++) {
+ for (x = 0; x < 4; x++) {
+ uint8_t *p = dst + x * 4 + y * stride;
+ FFSWAP(uint8_t, p[0], p[1]);
+ }
+ }
+
+ return 16;
+}
+
+av_cold void ff_texturedsp_init(TextureDSPContext *c)
+{
+ c->dxt1_block = dxt1_block;
+ c->dxt1a_block = dxt1a_block;
+ c->dxt2_block = dxt2_block;
+ c->dxt3_block = dxt3_block;
+ c->dxt4_block = dxt4_block;
+ c->dxt5_block = dxt5_block;
+ c->dxt5y_block = dxt5y_block;
+ c->dxt5ys_block = dxt5ys_block;
+ c->rgtc1s_block = rgtc1s_block;
+ c->rgtc1u_block = rgtc1u_block;
+ c->rgtc2s_block = rgtc2s_block;
+ c->rgtc2u_block = rgtc2u_block;
+ c->dxn3dc_block = dxn3dc_block;
+}
diff --git a/ffmpeg-2-8-11/libavcodec/texturedsp.h b/ffmpeg-2-8-12/libavcodec/texturedsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/texturedsp.h
rename to ffmpeg-2-8-12/libavcodec/texturedsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/texturedspenc.c b/ffmpeg-2-8-12/libavcodec/texturedspenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/texturedspenc.c
rename to ffmpeg-2-8-12/libavcodec/texturedspenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/thread.h b/ffmpeg-2-8-12/libavcodec/thread.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/thread.h
rename to ffmpeg-2-8-12/libavcodec/thread.h
diff --git a/ffmpeg-2-8-12/libavcodec/tiertexseqv.c b/ffmpeg-2-8-12/libavcodec/tiertexseqv.c
new file mode 100644
index 0000000..f86ae2a
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/tiertexseqv.c
@@ -0,0 +1,274 @@
+/*
+ * Tiertex Limited SEQ Video Decoder
+ * Copyright (c) 2006 Gregory Montoir (cyx at users.sourceforge.net)
+ *
+ * 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
+ * Tiertex Limited SEQ video decoder
+ */
+
+#include "avcodec.h"
+#define BITSTREAM_READER_LE
+#include "get_bits.h"
+#include "internal.h"
+
+
+typedef struct SeqVideoContext {
+ AVCodecContext *avctx;
+ AVFrame *frame;
+} SeqVideoContext;
+
+
+static const unsigned char *seq_unpack_rle_block(const unsigned char *src,
+ const unsigned char *src_end,
+ unsigned char *dst, int dst_size)
+{
+ int i, len, sz;
+ GetBitContext gb;
+ int code_table[64];
+
+ /* get the rle codes */
+ init_get_bits(&gb, src, (src_end - src) * 8);
+ for (i = 0, sz = 0; i < 64 && sz < dst_size; i++) {
+ if (get_bits_left(&gb) < 4)
+ return NULL;
+ code_table[i] = get_sbits(&gb, 4);
+ sz += FFABS(code_table[i]);
+ }
+ src += (get_bits_count(&gb) + 7) / 8;
+
+ /* do the rle unpacking */
+ for (i = 0; i < 64 && dst_size > 0; i++) {
+ len = code_table[i];
+ if (len < 0) {
+ len = -len;
+ if (src_end - src < 1)
+ return NULL;
+ memset(dst, *src++, FFMIN(len, dst_size));
+ } else {
+ if (src_end - src < len)
+ return NULL;
+ memcpy(dst, src, FFMIN(len, dst_size));
+ src += len;
+ }
+ dst += len;
+ dst_size -= len;
+ }
+ return src;
+}
+
+static const unsigned char *seq_decode_op1(SeqVideoContext *seq,
+ const unsigned char *src,
+ const unsigned char *src_end,
+ unsigned char *dst)
+{
+ const unsigned char *color_table;
+ int b, i, len, bits;
+ GetBitContext gb;
+ unsigned char block[8 * 8];
+
+ if (src_end - src < 1)
+ return NULL;
+ len = *src++;
+ if (len & 0x80) {
+ switch (len & 3) {
+ case 1:
+ src = seq_unpack_rle_block(src, src_end, block, sizeof(block));
+ for (b = 0; b < 8; b++) {
+ memcpy(dst, &block[b * 8], 8);
+ dst += seq->frame->linesize[0];
+ }
+ break;
+ case 2:
+ src = seq_unpack_rle_block(src, src_end, block, sizeof(block));
+ for (i = 0; i < 8; i++) {
+ for (b = 0; b < 8; b++)
+ dst[b * seq->frame->linesize[0]] = block[i * 8 + b];
+ ++dst;
+ }
+ break;
+ }
+ } else {
+ if (len <= 0)
+ return NULL;
+ bits = ff_log2_tab[len - 1] + 1;
+ if (src_end - src < len + 8 * bits)
+ return NULL;
+ color_table = src;
+ src += len;
+ init_get_bits(&gb, src, bits * 8 * 8); src += bits * 8;
+ for (b = 0; b < 8; b++) {
+ for (i = 0; i < 8; i++)
+ dst[i] = color_table[get_bits(&gb, bits)];
+ dst += seq->frame->linesize[0];
+ }
+ }
+
+ return src;
+}
+
+static const unsigned char *seq_decode_op2(SeqVideoContext *seq,
+ const unsigned char *src,
+ const unsigned char *src_end,
+ unsigned char *dst)
+{
+ int i;
+
+ if (src_end - src < 8 * 8)
+ return NULL;
+
+ for (i = 0; i < 8; i++) {
+ memcpy(dst, src, 8);
+ src += 8;
+ dst += seq->frame->linesize[0];
+ }
+
+ return src;
+}
+
+static const unsigned char *seq_decode_op3(SeqVideoContext *seq,
+ const unsigned char *src,
+ const unsigned char *src_end,
+ unsigned char *dst)
+{
+ int pos, offset;
+
+ do {
+ if (src_end - src < 2)
+ return NULL;
+ pos = *src++;
+ offset = ((pos >> 3) & 7) * seq->frame->linesize[0] + (pos & 7);
+ dst[offset] = *src++;
+ } while (!(pos & 0x80));
+
+ return src;
+}
+
+static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size)
+{
+ const unsigned char *data_end = data + data_size;
+ GetBitContext gb;
+ int flags, i, j, x, y, op;
+ unsigned char c[3];
+ unsigned char *dst;
+ uint32_t *palette;
+
+ flags = *data++;
+
+ if (flags & 1) {
+ palette = (uint32_t *)seq->frame->data[1];
+ if (data_end - data < 256 * 3)
+ return AVERROR_INVALIDDATA;
+ for (i = 0; i < 256; i++) {
+ for (j = 0; j < 3; j++, data++)
+ c[j] = (*data << 2) | (*data >> 4);
+ palette[i] = 0xFFU << 24 | AV_RB24(c);
+ }
+ seq->frame->palette_has_changed = 1;
+ }
+
+ if (flags & 2) {
+ if (data_end - data < 128)
+ return AVERROR_INVALIDDATA;
+ init_get_bits(&gb, data, 128 * 8); data += 128;
+ for (y = 0; y < 128; y += 8)
+ for (x = 0; x < 256; x += 8) {
+ dst = &seq->frame->data[0][y * seq->frame->linesize[0] + x];
+ op = get_bits(&gb, 2);
+ switch (op) {
+ case 1:
+ data = seq_decode_op1(seq, data, data_end, dst);
+ break;
+ case 2:
+ data = seq_decode_op2(seq, data, data_end, dst);
+ break;
+ case 3:
+ data = seq_decode_op3(seq, data, data_end, dst);
+ break;
+ }
+ if (!data)
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ return 0;
+}
+
+static av_cold int seqvideo_decode_init(AVCodecContext *avctx)
+{
+ SeqVideoContext *seq = avctx->priv_data;
+ int ret;
+
+ seq->avctx = avctx;
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+
+ ret = ff_set_dimensions(avctx, 256, 128);
+ if (ret < 0)
+ return ret;
+
+ seq->frame = av_frame_alloc();
+ if (!seq->frame)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static int seqvideo_decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ int ret;
+
+ SeqVideoContext *seq = avctx->priv_data;
+
+ if ((ret = ff_reget_buffer(avctx, seq->frame)) < 0)
+ return ret;
+
+ if (seqvideo_decode(seq, buf, buf_size))
+ return AVERROR_INVALIDDATA;
+
+ if ((ret = av_frame_ref(data, seq->frame)) < 0)
+ return ret;
+ *got_frame = 1;
+
+ return buf_size;
+}
+
+static av_cold int seqvideo_decode_end(AVCodecContext *avctx)
+{
+ SeqVideoContext *seq = avctx->priv_data;
+
+ av_frame_free(&seq->frame);
+
+ return 0;
+}
+
+AVCodec ff_tiertexseqvideo_decoder = {
+ .name = "tiertexseqvideo",
+ .long_name = NULL_IF_CONFIG_SMALL("Tiertex Limited SEQ video"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_TIERTEXSEQVIDEO,
+ .priv_data_size = sizeof(SeqVideoContext),
+ .init = seqvideo_decode_init,
+ .close = seqvideo_decode_end,
+ .decode = seqvideo_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-12/libavcodec/tiff.c b/ffmpeg-2-8-12/libavcodec/tiff.c
new file mode 100644
index 0000000..c46f771
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/tiff.c
@@ -0,0 +1,1411 @@
+/*
+ * Copyright (c) 2006 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
+ */
+
+/**
+ * @file
+ * TIFF image decoder
+ * @author Konstantin Shishkov
+ */
+
+#include "config.h"
+#if CONFIG_ZLIB
+#include <zlib.h>
+#endif
+#if CONFIG_LZMA
+#define LZMA_API_STATIC
+#include <lzma.h>
+#endif
+
+#include "libavutil/attributes.h"
+#include "libavutil/avstring.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/imgutils.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "faxcompr.h"
+#include "internal.h"
+#include "lzw.h"
+#include "mathops.h"
+#include "tiff.h"
+#include "tiff_data.h"
+#include "thread.h"
+
+typedef struct TiffContext {
+ AVCodecContext *avctx;
+ GetByteContext gb;
+
+ int width, height;
+ unsigned int bpp, bppcount;
+ uint32_t palette[256];
+ int palette_is_set;
+ int le;
+ enum TiffCompr compr;
+ enum TiffPhotometric photometric;
+ int planar;
+ int subsampling[2];
+ int fax_opts;
+ int predictor;
+ int fill_order;
+ uint32_t res[4];
+
+ int strips, rps, sstype;
+ int sot;
+ int stripsizesoff, stripsize, stripoff, strippos;
+ LZWState *lzw;
+
+ uint8_t *deinvert_buf;
+ int deinvert_buf_size;
+ uint8_t *yuv_line;
+ unsigned int yuv_line_size;
+
+ int geotag_count;
+ TiffGeoTag *geotags;
+} TiffContext;
+
+static void free_geotags(TiffContext *const s)
+{
+ int i;
+ for (i = 0; i < s->geotag_count; i++) {
+ if (s->geotags[i].val)
+ av_freep(&s->geotags[i].val);
+ }
+ av_freep(&s->geotags);
+ s->geotag_count = 0;
+}
+
+#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;
+
+static const char *get_geokey_name(int key)
+{
+ RET_GEOKEY(VERT, vert, name);
+ RET_GEOKEY(PROJ, proj, name);
+ RET_GEOKEY(GEOG, geog, name);
+ RET_GEOKEY(CONF, conf, name);
+
+ return NULL;
+}
+
+static int get_geokey_type(int key)
+{
+ RET_GEOKEY(VERT, vert, type);
+ RET_GEOKEY(PROJ, proj, type);
+ RET_GEOKEY(GEOG, geog, type);
+ RET_GEOKEY(CONF, conf, type);
+
+ return AVERROR_INVALIDDATA;
+}
+
+static int cmp_id_key(const void *id, const void *k)
+{
+ return *(const int*)id - ((const TiffGeoTagKeyName*)k)->key;
+}
+
+static const char *search_keyval(const TiffGeoTagKeyName *keys, int n, int id)
+{
+ TiffGeoTagKeyName *r = bsearch(&id, keys, n, sizeof(keys[0]), cmp_id_key);
+ if(r)
+ return r->name;
+
+ return NULL;
+}
+
+static char *get_geokey_val(int key, int val)
+{
+ char *ap;
+
+ if (val == TIFF_GEO_KEY_UNDEFINED)
+ return av_strdup("undefined");
+ if (val == TIFF_GEO_KEY_USER_DEFINED)
+ return av_strdup("User-Defined");
+
+#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]);
+
+ switch (key) {
+ case TIFF_GT_MODEL_TYPE_GEOKEY:
+ RET_GEOKEY_VAL(GT_MODEL_TYPE, gt_model_type);
+ break;
+ case TIFF_GT_RASTER_TYPE_GEOKEY:
+ RET_GEOKEY_VAL(GT_RASTER_TYPE, gt_raster_type);
+ break;
+ case TIFF_GEOG_LINEAR_UNITS_GEOKEY:
+ case TIFF_PROJ_LINEAR_UNITS_GEOKEY:
+ case TIFF_VERTICAL_UNITS_GEOKEY:
+ RET_GEOKEY_VAL(LINEAR_UNIT, linear_unit);
+ break;
+ case TIFF_GEOG_ANGULAR_UNITS_GEOKEY:
+ case TIFF_GEOG_AZIMUTH_UNITS_GEOKEY:
+ RET_GEOKEY_VAL(ANGULAR_UNIT, angular_unit);
+ break;
+ case TIFF_GEOGRAPHIC_TYPE_GEOKEY:
+ RET_GEOKEY_VAL(GCS_TYPE, gcs_type);
+ RET_GEOKEY_VAL(GCSE_TYPE, gcse_type);
+ break;
+ case TIFF_GEOG_GEODETIC_DATUM_GEOKEY:
+ RET_GEOKEY_VAL(GEODETIC_DATUM, geodetic_datum);
+ RET_GEOKEY_VAL(GEODETIC_DATUM_E, geodetic_datum_e);
+ break;
+ case TIFF_GEOG_ELLIPSOID_GEOKEY:
+ RET_GEOKEY_VAL(ELLIPSOID, ellipsoid);
+ break;
+ case TIFF_GEOG_PRIME_MERIDIAN_GEOKEY:
+ 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));
+ 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));
+ if(ap) return ap;
+ break;
+ case TIFF_PROJ_COORD_TRANS_GEOKEY:
+ RET_GEOKEY_VAL(COORD_TRANS, coord_trans);
+ break;
+ case TIFF_VERTICAL_CS_TYPE_GEOKEY:
+ RET_GEOKEY_VAL(VERT_CS, vert_cs);
+ RET_GEOKEY_VAL(ORTHO_VERT_CS, ortho_vert_cs);
+ break;
+
+ }
+
+ ap = av_malloc(14);
+ if (ap)
+ snprintf(ap, 14, "Unknown-%d", val);
+ return ap;
+}
+
+static char *doubles2str(double *dp, int count, const char *sep)
+{
+ int i;
+ char *ap, *ap0;
+ uint64_t component_len;
+ if (!sep) sep = ", ";
+ component_len = 24LL + strlen(sep);
+ if (count >= (INT_MAX - 1)/component_len)
+ return NULL;
+ ap = av_malloc(component_len * count + 1);
+ if (!ap)
+ return NULL;
+ ap0 = ap;
+ ap[0] = '\0';
+ for (i = 0; i < count; i++) {
+ unsigned l = snprintf(ap, component_len, "%.15g%s", dp[i], sep);
+ if(l >= component_len) {
+ av_free(ap0);
+ return NULL;
+ }
+ ap += l;
+ }
+ ap0[strlen(ap0) - strlen(sep)] = '\0';
+ return ap0;
+}
+
+static int add_metadata(int count, int type,
+ const char *name, const char *sep, TiffContext *s, AVFrame *frame)
+{
+ switch(type) {
+ case TIFF_DOUBLE: return ff_tadd_doubles_metadata(count, name, sep, &s->gb, s->le, avpriv_frame_get_metadatap(frame));
+ case TIFF_SHORT : return ff_tadd_shorts_metadata(count, name, sep, &s->gb, s->le, 0, avpriv_frame_get_metadatap(frame));
+ case TIFF_STRING: return ff_tadd_string_metadata(count, name, &s->gb, s->le, avpriv_frame_get_metadatap(frame));
+ default : return AVERROR_INVALIDDATA;
+ };
+}
+
+static void av_always_inline horizontal_fill(unsigned int bpp, uint8_t* dst,
+ int usePtr, const uint8_t *src,
+ uint8_t c, int width, int offset)
+{
+ switch (bpp) {
+ case 1:
+ while (--width >= 0) {
+ dst[(width+offset)*8+7] = (usePtr ? src[width] : c) & 0x1;
+ dst[(width+offset)*8+6] = (usePtr ? src[width] : c) >> 1 & 0x1;
+ dst[(width+offset)*8+5] = (usePtr ? src[width] : c) >> 2 & 0x1;
+ dst[(width+offset)*8+4] = (usePtr ? src[width] : c) >> 3 & 0x1;
+ dst[(width+offset)*8+3] = (usePtr ? src[width] : c) >> 4 & 0x1;
+ dst[(width+offset)*8+2] = (usePtr ? src[width] : c) >> 5 & 0x1;
+ dst[(width+offset)*8+1] = (usePtr ? src[width] : c) >> 6 & 0x1;
+ dst[(width+offset)*8+0] = (usePtr ? src[width] : c) >> 7;
+ }
+ break;
+ case 2:
+ while (--width >= 0) {
+ dst[(width+offset)*4+3] = (usePtr ? src[width] : c) & 0x3;
+ dst[(width+offset)*4+2] = (usePtr ? src[width] : c) >> 2 & 0x3;
+ dst[(width+offset)*4+1] = (usePtr ? src[width] : c) >> 4 & 0x3;
+ dst[(width+offset)*4+0] = (usePtr ? src[width] : c) >> 6;
+ }
+ break;
+ case 4:
+ while (--width >= 0) {
+ dst[(width+offset)*2+1] = (usePtr ? src[width] : c) & 0xF;
+ dst[(width+offset)*2+0] = (usePtr ? src[width] : c) >> 4;
+ }
+ break;
+ default:
+ if (usePtr) {
+ memcpy(dst + offset, src, width);
+ } else {
+ memset(dst + offset, c, width);
+ }
+ }
+}
+
+static int deinvert_buffer(TiffContext *s, const uint8_t *src, int size)
+{
+ int i;
+
+ av_fast_padded_malloc(&s->deinvert_buf, &s->deinvert_buf_size, size);
+ if (!s->deinvert_buf)
+ return AVERROR(ENOMEM);
+ for (i = 0; i < size; i++)
+ s->deinvert_buf[i] = ff_reverse[src[i]];
+
+ return 0;
+}
+
+static void unpack_yuv(TiffContext *s, AVFrame *p,
+ const uint8_t *src, int lnum)
+{
+ int i, j, k;
+ int w = (s->width - 1) / s->subsampling[0] + 1;
+ uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]];
+ uint8_t *pv = &p->data[2][lnum / s->subsampling[1] * p->linesize[2]];
+ if (s->width % s->subsampling[0] || s->height % s->subsampling[1]) {
+ for (i = 0; i < w; i++) {
+ for (j = 0; j < s->subsampling[1]; j++)
+ for (k = 0; k < s->subsampling[0]; k++)
+ p->data[0][FFMIN(lnum + j, s->height-1) * p->linesize[0] +
+ FFMIN(i * s->subsampling[0] + k, s->width-1)] = *src++;
+ *pu++ = *src++;
+ *pv++ = *src++;
+ }
+ }else{
+ for (i = 0; i < w; i++) {
+ for (j = 0; j < s->subsampling[1]; j++)
+ for (k = 0; k < s->subsampling[0]; k++)
+ p->data[0][(lnum + j) * p->linesize[0] +
+ i * s->subsampling[0] + k] = *src++;
+ *pu++ = *src++;
+ *pv++ = *src++;
+ }
+ }
+}
+
+#if CONFIG_ZLIB
+static int tiff_uncompress(uint8_t *dst, unsigned long *len, const uint8_t *src,
+ int size)
+{
+ z_stream zstream = { 0 };
+ int zret;
+
+ zstream.next_in = (uint8_t *)src;
+ zstream.avail_in = size;
+ zstream.next_out = dst;
+ zstream.avail_out = *len;
+ zret = inflateInit(&zstream);
+ if (zret != Z_OK) {
+ av_log(NULL, AV_LOG_ERROR, "Inflate init error: %d\n", zret);
+ return zret;
+ }
+ zret = inflate(&zstream, Z_SYNC_FLUSH);
+ inflateEnd(&zstream);
+ *len = zstream.total_out;
+ return zret == Z_STREAM_END ? Z_OK : zret;
+}
+
+static int tiff_unpack_zlib(TiffContext *s, AVFrame *p, uint8_t *dst, int stride,
+ const uint8_t *src, int size, int width, int lines,
+ int strip_start, int is_yuv)
+{
+ uint8_t *zbuf;
+ unsigned long outlen;
+ int ret, line;
+ outlen = width * lines;
+ zbuf = av_malloc(outlen);
+ if (!zbuf)
+ return AVERROR(ENOMEM);
+ if (s->fill_order) {
+ if ((ret = deinvert_buffer(s, src, size)) < 0) {
+ av_free(zbuf);
+ return ret;
+ }
+ src = s->deinvert_buf;
+ }
+ ret = tiff_uncompress(zbuf, &outlen, src, size);
+ if (ret != Z_OK) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Uncompressing failed (%lu of %lu) with error %d\n", outlen,
+ (unsigned long)width * lines, ret);
+ av_free(zbuf);
+ return AVERROR_UNKNOWN;
+ }
+ src = zbuf;
+ for (line = 0; line < lines; line++) {
+ if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
+ horizontal_fill(s->bpp, dst, 1, src, 0, width, 0);
+ } else {
+ memcpy(dst, src, width);
+ }
+ if (is_yuv) {
+ unpack_yuv(s, p, dst, strip_start + line);
+ line += s->subsampling[1] - 1;
+ }
+ dst += stride;
+ src += width;
+ }
+ av_free(zbuf);
+ return 0;
+}
+#endif
+
+#if CONFIG_LZMA
+static int tiff_uncompress_lzma(uint8_t *dst, uint64_t *len, const uint8_t *src,
+ int size)
+{
+ lzma_stream stream = LZMA_STREAM_INIT;
+ lzma_ret ret;
+
+ stream.next_in = (uint8_t *)src;
+ stream.avail_in = size;
+ stream.next_out = dst;
+ stream.avail_out = *len;
+ ret = lzma_stream_decoder(&stream, UINT64_MAX, 0);
+ if (ret != LZMA_OK) {
+ av_log(NULL, AV_LOG_ERROR, "LZMA init error: %d\n", ret);
+ return ret;
+ }
+ ret = lzma_code(&stream, LZMA_RUN);
+ lzma_end(&stream);
+ *len = stream.total_out;
+ return ret == LZMA_STREAM_END ? LZMA_OK : ret;
+}
+
+static int tiff_unpack_lzma(TiffContext *s, AVFrame *p, uint8_t *dst, int stride,
+ const uint8_t *src, int size, int width, int lines,
+ int strip_start, int is_yuv)
+{
+ uint64_t outlen = width * (uint64_t)lines;
+ int ret, line;
+ uint8_t *buf = av_malloc(outlen);
+ if (!buf)
+ return AVERROR(ENOMEM);
+ if (s->fill_order) {
+ if ((ret = deinvert_buffer(s, src, size)) < 0) {
+ av_free(buf);
+ return ret;
+ }
+ src = s->deinvert_buf;
+ }
+ ret = tiff_uncompress_lzma(buf, &outlen, src, size);
+ if (ret != LZMA_OK) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Uncompressing failed (%"PRIu64" of %"PRIu64") with error %d\n", outlen,
+ (uint64_t)width * lines, ret);
+ av_free(buf);
+ return AVERROR_UNKNOWN;
+ }
+ src = buf;
+ for (line = 0; line < lines; line++) {
+ if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
+ horizontal_fill(s->bpp, dst, 1, src, 0, width, 0);
+ } else {
+ memcpy(dst, src, width);
+ }
+ if (is_yuv) {
+ unpack_yuv(s, p, dst, strip_start + line);
+ line += s->subsampling[1] - 1;
+ }
+ dst += stride;
+ src += width;
+ }
+ av_free(buf);
+ return 0;
+}
+#endif
+
+static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, int stride,
+ const uint8_t *src, int size, int width, int lines)
+{
+ int i, ret = 0;
+ int line;
+ uint8_t *src2 = av_malloc((unsigned)size +
+ AV_INPUT_BUFFER_PADDING_SIZE);
+
+ if (!src2) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Error allocating temporary buffer\n");
+ return AVERROR(ENOMEM);
+ }
+
+ if (!s->fill_order) {
+ memcpy(src2, src, size);
+ } else {
+ for (i = 0; i < size; i++)
+ src2[i] = ff_reverse[src[i]];
+ }
+ memset(src2 + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ ret = ff_ccitt_unpack(s->avctx, src2, size, dst, lines, stride,
+ s->compr, s->fax_opts);
+ if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
+ for (line = 0; line < lines; line++) {
+ horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
+ dst += stride;
+ }
+ av_free(src2);
+ return ret;
+}
+
+static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int stride,
+ const uint8_t *src, int size, int strip_start, int lines)
+{
+ PutByteContext pb;
+ int c, line, pixels, code, ret;
+ const uint8_t *ssrc = src;
+ int width = ((s->width * s->bpp) + 7) >> 3;
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(p->format);
+ int is_yuv = !(desc->flags & AV_PIX_FMT_FLAG_RGB) &&
+ (desc->flags & AV_PIX_FMT_FLAG_PLANAR) &&
+ desc->nb_components >= 3;
+
+ if (s->planar)
+ width /= s->bppcount;
+
+ if (size <= 0)
+ return AVERROR_INVALIDDATA;
+
+ if (is_yuv) {
+ int bytes_per_row = (((s->width - 1) / s->subsampling[0] + 1) * s->bpp *
+ s->subsampling[0] * s->subsampling[1] + 7) >> 3;
+ av_fast_padded_malloc(&s->yuv_line, &s->yuv_line_size, bytes_per_row);
+ if (s->yuv_line == NULL) {
+ av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n");
+ return AVERROR(ENOMEM);
+ }
+ dst = s->yuv_line;
+ stride = 0;
+
+ width = (s->width - 1) / s->subsampling[0] + 1;
+ width = width * s->subsampling[0] * s->subsampling[1] + 2*width;
+ av_assert0(width <= bytes_per_row);
+ av_assert0(s->bpp == 24);
+ }
+
+ if (s->compr == TIFF_DEFLATE || s->compr == TIFF_ADOBE_DEFLATE) {
+#if CONFIG_ZLIB
+ return tiff_unpack_zlib(s, p, dst, stride, src, size, width, lines,
+ strip_start, is_yuv);
+#else
+ av_log(s->avctx, AV_LOG_ERROR,
+ "zlib support not enabled, "
+ "deflate compression not supported\n");
+ return AVERROR(ENOSYS);
+#endif
+ }
+ if (s->compr == TIFF_LZMA) {
+#if CONFIG_LZMA
+ return tiff_unpack_lzma(s, p, dst, stride, src, size, width, lines,
+ strip_start, is_yuv);
+#else
+ av_log(s->avctx, AV_LOG_ERROR,
+ "LZMA support not enabled\n");
+ return AVERROR(ENOSYS);
+#endif
+ }
+ if (s->compr == TIFF_LZW) {
+ if (s->fill_order) {
+ if ((ret = deinvert_buffer(s, src, size)) < 0)
+ return ret;
+ ssrc = src = s->deinvert_buf;
+ }
+ if (size > 1 && !src[0] && (src[1]&1)) {
+ av_log(s->avctx, AV_LOG_ERROR, "Old style LZW is unsupported\n");
+ }
+ if ((ret = ff_lzw_decode_init(s->lzw, 8, src, size, FF_LZW_TIFF)) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n");
+ return ret;
+ }
+ for (line = 0; line < lines; line++) {
+ pixels = ff_lzw_decode(s->lzw, dst, width);
+ if (pixels < width) {
+ av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n",
+ pixels, width);
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->bpp < 8 && s->avctx->pix_fmt == AV_PIX_FMT_PAL8)
+ horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0);
+ if (is_yuv) {
+ unpack_yuv(s, p, dst, strip_start + line);
+ line += s->subsampling[1] - 1;
+ }
+ dst += stride;
+ }
+ return 0;
+ }
+ if (s->compr == TIFF_CCITT_RLE ||
+ s->compr == TIFF_G3 ||
+ s->compr == TIFF_G4) {
+ if (is_yuv)
+ return AVERROR_INVALIDDATA;
+
+ return tiff_unpack_fax(s, dst, stride, src, size, width, lines);
+ }
+
+ bytestream2_init(&s->gb, src, size);
+ bytestream2_init_writer(&pb, dst, is_yuv ? s->yuv_line_size : (stride * lines));
+
+ for (line = 0; line < lines; line++) {
+ if (src - ssrc > size) {
+ av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (bytestream2_get_bytes_left(&s->gb) == 0 || bytestream2_get_eof(&pb))
+ break;
+ bytestream2_seek_p(&pb, stride * line, SEEK_SET);
+ switch (s->compr) {
+ case TIFF_RAW:
+ if (ssrc + size - src < width)
+ return AVERROR_INVALIDDATA;
+
+ if (!s->fill_order) {
+ horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
+ dst, 1, src, 0, width, 0);
+ } else {
+ int i;
+ for (i = 0; i < width; i++)
+ dst[i] = ff_reverse[src[i]];
+ }
+ src += width;
+ break;
+ case TIFF_PACKBITS:
+ for (pixels = 0; pixels < width;) {
+ if (ssrc + size - src < 2) {
+ av_log(s->avctx, AV_LOG_ERROR, "Read went out of bounds\n");
+ return AVERROR_INVALIDDATA;
+ }
+ code = s->fill_order ? (int8_t) ff_reverse[*src++]: (int8_t) *src++;
+ if (code >= 0) {
+ code++;
+ if (pixels + code > width ||
+ ssrc + size - src < code) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Copy went out of bounds\n");
+ return AVERROR_INVALIDDATA;
+ }
+ horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
+ dst, 1, src, 0, code, pixels);
+ src += code;
+ pixels += code;
+ } else if (code != -128) { // -127..-1
+ code = (-code) + 1;
+ if (pixels + code > width) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Run went out of bounds\n");
+ return AVERROR_INVALIDDATA;
+ }
+ c = *src++;
+ horizontal_fill(s->bpp * (s->avctx->pix_fmt == AV_PIX_FMT_PAL8),
+ dst, 0, NULL, c, code, pixels);
+ pixels += code;
+ }
+ }
+ if (s->fill_order) {
+ int i;
+ for (i = 0; i < width; i++)
+ dst[i] = ff_reverse[dst[i]];
+ }
+ break;
+ }
+ if (is_yuv) {
+ unpack_yuv(s, p, dst, strip_start + line);
+ line += s->subsampling[1] - 1;
+ }
+ dst += stride;
+ }
+ return 0;
+}
+
+static int init_image(TiffContext *s, ThreadFrame *frame)
+{
+ int ret;
+ int create_gray_palette = 0;
+
+ // make sure there is no aliasing in the following switch
+ if (s->bpp >= 100 || s->bppcount >= 10) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Unsupported image parameters: bpp=%d, bppcount=%d\n",
+ s->bpp, s->bppcount);
+ return AVERROR_INVALIDDATA;
+ }
+
+ switch (s->planar * 1000 + s->bpp * 10 + s->bppcount) {
+ case 11:
+ if (!s->palette_is_set) {
+ s->avctx->pix_fmt = AV_PIX_FMT_MONOBLACK;
+ break;
+ }
+ case 21:
+ case 41:
+ s->avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ if (!s->palette_is_set) {
+ create_gray_palette = 1;
+ }
+ break;
+ case 81:
+ s->avctx->pix_fmt = s->palette_is_set ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_GRAY8;
+ break;
+ case 243:
+ if (s->photometric == TIFF_PHOTOMETRIC_YCBCR) {
+ if (s->subsampling[0] == 1 && s->subsampling[1] == 1) {
+ s->avctx->pix_fmt = AV_PIX_FMT_YUV444P;
+ } else if (s->subsampling[0] == 2 && s->subsampling[1] == 1) {
+ s->avctx->pix_fmt = AV_PIX_FMT_YUV422P;
+ } else if (s->subsampling[0] == 4 && s->subsampling[1] == 1) {
+ s->avctx->pix_fmt = AV_PIX_FMT_YUV411P;
+ } else if (s->subsampling[0] == 1 && s->subsampling[1] == 2) {
+ s->avctx->pix_fmt = AV_PIX_FMT_YUV440P;
+ } else if (s->subsampling[0] == 2 && s->subsampling[1] == 2) {
+ s->avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+ } else if (s->subsampling[0] == 4 && s->subsampling[1] == 4) {
+ s->avctx->pix_fmt = AV_PIX_FMT_YUV410P;
+ } else {
+ av_log(s->avctx, AV_LOG_ERROR, "Unsupported YCbCr subsampling\n");
+ return AVERROR_PATCHWELCOME;
+ }
+ } else
+ s->avctx->pix_fmt = AV_PIX_FMT_RGB24;
+ break;
+ case 161:
+ s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GRAY16LE : AV_PIX_FMT_GRAY16BE;
+ break;
+ case 162:
+ s->avctx->pix_fmt = AV_PIX_FMT_YA8;
+ break;
+ case 322:
+ s->avctx->pix_fmt = s->le ? AV_PIX_FMT_YA16LE : AV_PIX_FMT_YA16BE;
+ break;
+ case 324:
+ s->avctx->pix_fmt = AV_PIX_FMT_RGBA;
+ break;
+ case 483:
+ s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGB48LE : AV_PIX_FMT_RGB48BE;
+ break;
+ case 644:
+ s->avctx->pix_fmt = s->le ? AV_PIX_FMT_RGBA64LE : AV_PIX_FMT_RGBA64BE;
+ break;
+ case 1243:
+ s->avctx->pix_fmt = AV_PIX_FMT_GBRP;
+ break;
+ case 1324:
+ s->avctx->pix_fmt = AV_PIX_FMT_GBRAP;
+ break;
+ case 1483:
+ s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GBRP16LE : AV_PIX_FMT_GBRP16BE;
+ break;
+ case 1644:
+ s->avctx->pix_fmt = s->le ? AV_PIX_FMT_GBRAP16LE : AV_PIX_FMT_GBRAP16BE;
+ break;
+ default:
+ av_log(s->avctx, AV_LOG_ERROR,
+ "This format is not supported (bpp=%d, bppcount=%d)\n",
+ s->bpp, s->bppcount);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->photometric == TIFF_PHOTOMETRIC_YCBCR) {
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
+ if((desc->flags & AV_PIX_FMT_FLAG_RGB) ||
+ !(desc->flags & AV_PIX_FMT_FLAG_PLANAR) ||
+ desc->nb_components < 3) {
+ av_log(s->avctx, AV_LOG_ERROR, "Unsupported YCbCr variant\n");
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if (s->width != s->avctx->width || s->height != s->avctx->height) {
+ ret = ff_set_dimensions(s->avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
+ }
+ if ((ret = ff_thread_get_buffer(s->avctx, frame, 0)) < 0)
+ return ret;
+ if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8) {
+ if (!create_gray_palette)
+ memcpy(frame->f->data[1], s->palette, sizeof(s->palette));
+ else {
+ /* make default grayscale pal */
+ int i;
+ uint32_t *pal = (uint32_t *)frame->f->data[1];
+ for (i = 0; i < 1<<s->bpp; i++)
+ pal[i] = 0xFFU << 24 | i * 255 / ((1<<s->bpp) - 1) * 0x010101;
+ }
+ }
+ return 0;
+}
+
+static void set_sar(TiffContext *s, unsigned tag, unsigned num, unsigned den)
+{
+ int offset = tag == TIFF_YRES ? 2 : 0;
+ s->res[offset++] = num;
+ s->res[offset] = den;
+ if (s->res[0] && s->res[1] && s->res[2] && s->res[3])
+ av_reduce(&s->avctx->sample_aspect_ratio.num, &s->avctx->sample_aspect_ratio.den,
+ s->res[2] * (uint64_t)s->res[1], s->res[0] * (uint64_t)s->res[3], INT32_MAX);
+}
+
+static int tiff_decode_tag(TiffContext *s, AVFrame *frame)
+{
+ unsigned tag, type, count, off, value = 0, value2 = 0;
+ int i, start;
+ int pos;
+ int ret;
+ double *dp;
+
+ ret = ff_tread_tag(&s->gb, s->le, &tag, &type, &count, &start);
+ if (ret < 0) {
+ goto end;
+ }
+
+ off = bytestream2_tell(&s->gb);
+ if (count == 1) {
+ switch (type) {
+ case TIFF_BYTE:
+ case TIFF_SHORT:
+ case TIFF_LONG:
+ value = ff_tget(&s->gb, type, s->le);
+ break;
+ case TIFF_RATIONAL:
+ value = ff_tget(&s->gb, TIFF_LONG, s->le);
+ value2 = ff_tget(&s->gb, TIFF_LONG, s->le);
+ break;
+ case TIFF_STRING:
+ if (count <= 4) {
+ break;
+ }
+ default:
+ value = UINT_MAX;
+ }
+ }
+
+ switch (tag) {
+ case TIFF_WIDTH:
+ s->width = value;
+ break;
+ case TIFF_HEIGHT:
+ s->height = value;
+ break;
+ case TIFF_BPP:
+ if (count > 4U) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "This format is not supported (bpp=%d, %d components)\n",
+ value, count);
+ return AVERROR_INVALIDDATA;
+ }
+ s->bppcount = count;
+ if (count == 1)
+ s->bpp = value;
+ else {
+ switch (type) {
+ case TIFF_BYTE:
+ case TIFF_SHORT:
+ case TIFF_LONG:
+ s->bpp = 0;
+ if (bytestream2_get_bytes_left(&s->gb) < type_sizes[type] * count)
+ return AVERROR_INVALIDDATA;
+ for (i = 0; i < count; i++)
+ s->bpp += ff_tget(&s->gb, type, s->le);
+ break;
+ default:
+ s->bpp = -1;
+ }
+ }
+ break;
+ case TIFF_SAMPLES_PER_PIXEL:
+ if (count != 1) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Samples per pixel requires a single value, many provided\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (value > 4U) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Samples per pixel %d is too large\n", value);
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->bppcount == 1)
+ s->bpp *= value;
+ s->bppcount = value;
+ break;
+ case TIFF_COMPR:
+ s->compr = value;
+ s->predictor = 0;
+ switch (s->compr) {
+ case TIFF_RAW:
+ case TIFF_PACKBITS:
+ case TIFF_LZW:
+ case TIFF_CCITT_RLE:
+ break;
+ case TIFF_G3:
+ case TIFF_G4:
+ s->fax_opts = 0;
+ break;
+ case TIFF_DEFLATE:
+ case TIFF_ADOBE_DEFLATE:
+#if CONFIG_ZLIB
+ break;
+#else
+ av_log(s->avctx, AV_LOG_ERROR, "Deflate: ZLib not compiled in\n");
+ return AVERROR(ENOSYS);
+#endif
+ case TIFF_JPEG:
+ case TIFF_NEWJPEG:
+ avpriv_report_missing_feature(s->avctx, "JPEG compression");
+ return AVERROR_PATCHWELCOME;
+ case TIFF_LZMA:
+#if CONFIG_LZMA
+ break;
+#else
+ av_log(s->avctx, AV_LOG_ERROR, "LZMA not compiled in\n");
+ return AVERROR(ENOSYS);
+#endif
+ default:
+ av_log(s->avctx, AV_LOG_ERROR, "Unknown compression method %i\n",
+ s->compr);
+ return AVERROR_INVALIDDATA;
+ }
+ break;
+ case TIFF_ROWSPERSTRIP:
+ if (!value || (type == TIFF_LONG && value == UINT_MAX))
+ value = s->height;
+ s->rps = FFMIN(value, s->height);
+ break;
+ case TIFF_STRIP_OFFS:
+ if (count == 1) {
+ if (value > INT_MAX) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "strippos %u too large\n", value);
+ return AVERROR_INVALIDDATA;
+ }
+ s->strippos = 0;
+ s->stripoff = value;
+ } else
+ s->strippos = off;
+ s->strips = count;
+ if (s->strips == 1)
+ s->rps = s->height;
+ s->sot = type;
+ break;
+ case TIFF_STRIP_SIZE:
+ if (count == 1) {
+ if (value > INT_MAX) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "stripsize %u too large\n", value);
+ return AVERROR_INVALIDDATA;
+ }
+ s->stripsizesoff = 0;
+ s->stripsize = value;
+ s->strips = 1;
+ } else {
+ s->stripsizesoff = off;
+ }
+ s->strips = count;
+ s->sstype = type;
+ break;
+ case TIFF_XRES:
+ case TIFF_YRES:
+ set_sar(s, tag, value, value2);
+ break;
+ case TIFF_TILE_BYTE_COUNTS:
+ case TIFF_TILE_LENGTH:
+ case TIFF_TILE_OFFSETS:
+ case TIFF_TILE_WIDTH:
+ av_log(s->avctx, AV_LOG_ERROR, "Tiled images are not supported\n");
+ return AVERROR_PATCHWELCOME;
+ break;
+ case TIFF_PREDICTOR:
+ s->predictor = value;
+ break;
+ case TIFF_PHOTOMETRIC:
+ switch (value) {
+ case TIFF_PHOTOMETRIC_WHITE_IS_ZERO:
+ case TIFF_PHOTOMETRIC_BLACK_IS_ZERO:
+ case TIFF_PHOTOMETRIC_RGB:
+ case TIFF_PHOTOMETRIC_PALETTE:
+ case TIFF_PHOTOMETRIC_YCBCR:
+ s->photometric = value;
+ break;
+ case TIFF_PHOTOMETRIC_ALPHA_MASK:
+ case TIFF_PHOTOMETRIC_SEPARATED:
+ case TIFF_PHOTOMETRIC_CIE_LAB:
+ case TIFF_PHOTOMETRIC_ICC_LAB:
+ case TIFF_PHOTOMETRIC_ITU_LAB:
+ case TIFF_PHOTOMETRIC_CFA:
+ case TIFF_PHOTOMETRIC_LOG_L:
+ case TIFF_PHOTOMETRIC_LOG_LUV:
+ case TIFF_PHOTOMETRIC_LINEAR_RAW:
+ avpriv_report_missing_feature(s->avctx,
+ "PhotometricInterpretation 0x%04X",
+ value);
+ return AVERROR_PATCHWELCOME;
+ default:
+ av_log(s->avctx, AV_LOG_ERROR, "PhotometricInterpretation %u is "
+ "unknown\n", value);
+ return AVERROR_INVALIDDATA;
+ }
+ break;
+ case TIFF_FILL_ORDER:
+ if (value < 1 || value > 2) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Unknown FillOrder value %d, trying default one\n", value);
+ value = 1;
+ }
+ s->fill_order = value - 1;
+ break;
+ case TIFF_PAL: {
+ GetByteContext pal_gb[3];
+ off = type_sizes[type];
+ if (count / 3 > 256 ||
+ bytestream2_get_bytes_left(&s->gb) < count / 3 * off * 3)
+ return AVERROR_INVALIDDATA;
+
+ pal_gb[0] = pal_gb[1] = pal_gb[2] = s->gb;
+ bytestream2_skip(&pal_gb[1], count / 3 * off);
+ bytestream2_skip(&pal_gb[2], count / 3 * off * 2);
+
+ off = (type_sizes[type] - 1) << 3;
+ for (i = 0; i < count / 3; i++) {
+ uint32_t p = 0xFF000000;
+ p |= (ff_tget(&pal_gb[0], type, s->le) >> off) << 16;
+ p |= (ff_tget(&pal_gb[1], type, s->le) >> off) << 8;
+ p |= ff_tget(&pal_gb[2], type, s->le) >> off;
+ s->palette[i] = p;
+ }
+ s->palette_is_set = 1;
+ break;
+ }
+ case TIFF_PLANAR:
+ s->planar = value == 2;
+ break;
+ case TIFF_YCBCR_SUBSAMPLING:
+ if (count != 2) {
+ av_log(s->avctx, AV_LOG_ERROR, "subsample count invalid\n");
+ return AVERROR_INVALIDDATA;
+ }
+ for (i = 0; i < count; i++) {
+ s->subsampling[i] = ff_tget(&s->gb, type, s->le);
+ if (s->subsampling[i] <= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "subsampling %d is invalid\n", s->subsampling[i]);
+ s->subsampling[i] = 1;
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ break;
+ case TIFF_T4OPTIONS:
+ if (s->compr == TIFF_G3)
+ s->fax_opts = value;
+ break;
+ case TIFF_T6OPTIONS:
+ if (s->compr == TIFF_G4)
+ s->fax_opts = value;
+ break;
+#define ADD_METADATA(count, name, sep)\
+ if ((ret = add_metadata(count, type, name, sep, s, frame)) < 0) {\
+ av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");\
+ goto end;\
+ }
+ case TIFF_MODEL_PIXEL_SCALE:
+ ADD_METADATA(count, "ModelPixelScaleTag", NULL);
+ break;
+ case TIFF_MODEL_TRANSFORMATION:
+ ADD_METADATA(count, "ModelTransformationTag", NULL);
+ break;
+ case TIFF_MODEL_TIEPOINT:
+ ADD_METADATA(count, "ModelTiepointTag", NULL);
+ break;
+ case TIFF_GEO_KEY_DIRECTORY:
+ if (s->geotag_count) {
+ avpriv_request_sample(s->avctx, "Multiple geo key directories\n");
+ return AVERROR_INVALIDDATA;
+ }
+ ADD_METADATA(1, "GeoTIFF_Version", NULL);
+ ADD_METADATA(2, "GeoTIFF_Key_Revision", ".");
+ s->geotag_count = ff_tget_short(&s->gb, s->le);
+ if (s->geotag_count > count / 4 - 1) {
+ s->geotag_count = count / 4 - 1;
+ av_log(s->avctx, AV_LOG_WARNING, "GeoTIFF key directory buffer shorter than specified\n");
+ }
+ if ( bytestream2_get_bytes_left(&s->gb) < s->geotag_count * sizeof(int16_t) * 4
+ || s->geotag_count == 0) {
+ s->geotag_count = 0;
+ return -1;
+ }
+ s->geotags = av_mallocz_array(s->geotag_count, sizeof(TiffGeoTag));
+ if (!s->geotags) {
+ av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
+ s->geotag_count = 0;
+ goto end;
+ }
+ for (i = 0; i < s->geotag_count; i++) {
+ s->geotags[i].key = ff_tget_short(&s->gb, s->le);
+ s->geotags[i].type = ff_tget_short(&s->gb, s->le);
+ s->geotags[i].count = ff_tget_short(&s->gb, s->le);
+
+ if (!s->geotags[i].type)
+ s->geotags[i].val = get_geokey_val(s->geotags[i].key, ff_tget_short(&s->gb, s->le));
+ else
+ s->geotags[i].offset = ff_tget_short(&s->gb, s->le);
+ }
+ break;
+ case TIFF_GEO_DOUBLE_PARAMS:
+ if (count >= INT_MAX / sizeof(int64_t))
+ return AVERROR_INVALIDDATA;
+ if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int64_t))
+ return AVERROR_INVALIDDATA;
+ dp = av_malloc_array(count, sizeof(double));
+ if (!dp) {
+ av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
+ goto end;
+ }
+ for (i = 0; i < count; i++)
+ dp[i] = ff_tget_double(&s->gb, s->le);
+ for (i = 0; i < s->geotag_count; i++) {
+ if (s->geotags[i].type == TIFF_GEO_DOUBLE_PARAMS) {
+ if (s->geotags[i].count == 0
+ || s->geotags[i].offset + s->geotags[i].count > count) {
+ av_log(s->avctx, AV_LOG_WARNING, "Invalid GeoTIFF key %d\n", s->geotags[i].key);
+ } else {
+ char *ap = doubles2str(&dp[s->geotags[i].offset], s->geotags[i].count, ", ");
+ if (!ap) {
+ av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
+ av_freep(&dp);
+ return AVERROR(ENOMEM);
+ }
+ s->geotags[i].val = ap;
+ }
+ }
+ }
+ av_freep(&dp);
+ break;
+ case TIFF_GEO_ASCII_PARAMS:
+ pos = bytestream2_tell(&s->gb);
+ for (i = 0; i < s->geotag_count; i++) {
+ if (s->geotags[i].type == TIFF_GEO_ASCII_PARAMS) {
+ if (s->geotags[i].count == 0
+ || s->geotags[i].offset + s->geotags[i].count > count) {
+ av_log(s->avctx, AV_LOG_WARNING, "Invalid GeoTIFF key %d\n", s->geotags[i].key);
+ } else {
+ char *ap;
+
+ bytestream2_seek(&s->gb, pos + s->geotags[i].offset, SEEK_SET);
+ if (bytestream2_get_bytes_left(&s->gb) < s->geotags[i].count)
+ return AVERROR_INVALIDDATA;
+ if (s->geotags[i].val)
+ return AVERROR_INVALIDDATA;
+ ap = av_malloc(s->geotags[i].count);
+ if (!ap) {
+ av_log(s->avctx, AV_LOG_ERROR, "Error allocating temporary buffer\n");
+ return AVERROR(ENOMEM);
+ }
+ bytestream2_get_bufferu(&s->gb, ap, s->geotags[i].count);
+ ap[s->geotags[i].count - 1] = '\0'; //replace the "|" delimiter with a 0 byte
+ s->geotags[i].val = ap;
+ }
+ }
+ }
+ break;
+ case TIFF_ARTIST:
+ ADD_METADATA(count, "artist", NULL);
+ break;
+ case TIFF_COPYRIGHT:
+ ADD_METADATA(count, "copyright", NULL);
+ break;
+ case TIFF_DATE:
+ ADD_METADATA(count, "date", NULL);
+ break;
+ case TIFF_DOCUMENT_NAME:
+ ADD_METADATA(count, "document_name", NULL);
+ break;
+ case TIFF_HOST_COMPUTER:
+ ADD_METADATA(count, "computer", NULL);
+ break;
+ case TIFF_IMAGE_DESCRIPTION:
+ ADD_METADATA(count, "description", NULL);
+ break;
+ case TIFF_MAKE:
+ ADD_METADATA(count, "make", NULL);
+ break;
+ case TIFF_MODEL:
+ ADD_METADATA(count, "model", NULL);
+ break;
+ case TIFF_PAGE_NAME:
+ ADD_METADATA(count, "page_name", NULL);
+ break;
+ case TIFF_PAGE_NUMBER:
+ ADD_METADATA(count, "page_number", " / ");
+ break;
+ case TIFF_SOFTWARE_NAME:
+ ADD_METADATA(count, "software", NULL);
+ break;
+ default:
+ if (s->avctx->err_recognition & AV_EF_EXPLODE) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Unknown or unsupported tag %d/0X%0X\n",
+ tag, tag);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+end:
+ if (s->bpp > 64U) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "This format is not supported (bpp=%d, %d components)\n",
+ s->bpp, count);
+ s->bpp = 0;
+ return AVERROR_INVALIDDATA;
+ }
+ bytestream2_seek(&s->gb, start, SEEK_SET);
+ return 0;
+}
+
+static int decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame, AVPacket *avpkt)
+{
+ TiffContext *const s = avctx->priv_data;
+ AVFrame *const p = data;
+ ThreadFrame frame = { .f = data };
+ unsigned off;
+ int le, ret, plane, planes;
+ int i, j, entries, stride;
+ unsigned soff, ssize;
+ uint8_t *dst;
+ GetByteContext stripsizes;
+ GetByteContext stripdata;
+
+ bytestream2_init(&s->gb, avpkt->data, avpkt->size);
+
+ // parse image header
+ if ((ret = ff_tdecode_header(&s->gb, &le, &off))) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid TIFF header\n");
+ return ret;
+ } else if (off >= UINT_MAX - 14 || avpkt->size < off + 14) {
+ av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n");
+ return AVERROR_INVALIDDATA;
+ }
+ s->le = le;
+ // TIFF_BPP is not a required tag and defaults to 1
+ s->bppcount = s->bpp = 1;
+ s->photometric = TIFF_PHOTOMETRIC_NONE;
+ s->compr = TIFF_RAW;
+ s->fill_order = 0;
+ free_geotags(s);
+
+ // Reset these offsets so we can tell if they were set this frame
+ s->stripsizesoff = s->strippos = 0;
+ /* parse image file directory */
+ bytestream2_seek(&s->gb, off, SEEK_SET);
+ entries = ff_tget_short(&s->gb, le);
+ if (bytestream2_get_bytes_left(&s->gb) < entries * 12)
+ return AVERROR_INVALIDDATA;
+ for (i = 0; i < entries; i++) {
+ if ((ret = tiff_decode_tag(s, p)) < 0)
+ return ret;
+ }
+
+ for (i = 0; i<s->geotag_count; i++) {
+ const char *keyname = get_geokey_name(s->geotags[i].key);
+ if (!keyname) {
+ av_log(avctx, AV_LOG_WARNING, "Unknown or unsupported GeoTIFF key %d\n", s->geotags[i].key);
+ continue;
+ }
+ if (get_geokey_type(s->geotags[i].key) != s->geotags[i].type) {
+ av_log(avctx, AV_LOG_WARNING, "Type of GeoTIFF key %d is wrong\n", s->geotags[i].key);
+ continue;
+ }
+ ret = av_dict_set(avpriv_frame_get_metadatap(p), keyname, s->geotags[i].val, 0);
+ if (ret<0) {
+ av_log(avctx, AV_LOG_ERROR, "Writing metadata with key '%s' failed\n", keyname);
+ return ret;
+ }
+ }
+
+ if (!s->strippos && !s->stripoff) {
+ av_log(avctx, AV_LOG_ERROR, "Image data is missing\n");
+ return AVERROR_INVALIDDATA;
+ }
+ /* now we have the data and may start decoding */
+ if ((ret = init_image(s, &frame)) < 0)
+ return ret;
+
+ if (s->strips == 1 && !s->stripsize) {
+ av_log(avctx, AV_LOG_WARNING, "Image data size missing\n");
+ s->stripsize = avpkt->size - s->stripoff;
+ }
+
+ if (s->stripsizesoff) {
+ if (s->stripsizesoff >= (unsigned)avpkt->size)
+ return AVERROR_INVALIDDATA;
+ bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff,
+ avpkt->size - s->stripsizesoff);
+ }
+ if (s->strippos) {
+ if (s->strippos >= (unsigned)avpkt->size)
+ return AVERROR_INVALIDDATA;
+ bytestream2_init(&stripdata, avpkt->data + s->strippos,
+ avpkt->size - s->strippos);
+ }
+
+ if (s->rps <= 0 || s->rps % s->subsampling[1]) {
+ av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps);
+ return AVERROR_INVALIDDATA;
+ }
+
+ planes = s->planar ? s->bppcount : 1;
+ for (plane = 0; plane < planes; plane++) {
+ stride = p->linesize[plane];
+ dst = p->data[plane];
+ for (i = 0; i < s->height; i += s->rps) {
+ if (s->stripsizesoff)
+ ssize = ff_tget(&stripsizes, s->sstype, le);
+ else
+ ssize = s->stripsize;
+
+ if (s->strippos)
+ soff = ff_tget(&stripdata, s->sot, le);
+ else
+ soff = s->stripoff;
+
+ if (soff > avpkt->size || ssize > avpkt->size - soff) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if ((ret = tiff_unpack_strip(s, p, dst, stride, avpkt->data + soff, ssize, i,
+ FFMIN(s->rps, s->height - i))) < 0) {
+ if (avctx->err_recognition & AV_EF_EXPLODE)
+ return ret;
+ break;
+ }
+ dst += s->rps * stride;
+ }
+ if (s->predictor == 2) {
+ if (s->photometric == TIFF_PHOTOMETRIC_YCBCR) {
+ av_log(s->avctx, AV_LOG_ERROR, "predictor == 2 with YUV is unsupported");
+ return AVERROR_PATCHWELCOME;
+ }
+ dst = p->data[plane];
+ soff = s->bpp >> 3;
+ if (s->planar)
+ soff = FFMAX(soff / s->bppcount, 1);
+ ssize = s->width * soff;
+ if (s->avctx->pix_fmt == AV_PIX_FMT_RGB48LE ||
+ s->avctx->pix_fmt == AV_PIX_FMT_RGBA64LE ||
+ s->avctx->pix_fmt == AV_PIX_FMT_GRAY16LE ||
+ s->avctx->pix_fmt == AV_PIX_FMT_YA16LE ||
+ s->avctx->pix_fmt == AV_PIX_FMT_GBRP16LE ||
+ s->avctx->pix_fmt == AV_PIX_FMT_GBRAP16LE) {
+ for (i = 0; i < s->height; i++) {
+ for (j = soff; j < ssize; j += 2)
+ AV_WL16(dst + j, AV_RL16(dst + j) + AV_RL16(dst + j - soff));
+ dst += stride;
+ }
+ } else if (s->avctx->pix_fmt == AV_PIX_FMT_RGB48BE ||
+ s->avctx->pix_fmt == AV_PIX_FMT_RGBA64BE ||
+ s->avctx->pix_fmt == AV_PIX_FMT_GRAY16BE ||
+ s->avctx->pix_fmt == AV_PIX_FMT_YA16BE ||
+ s->avctx->pix_fmt == AV_PIX_FMT_GBRP16BE ||
+ s->avctx->pix_fmt == AV_PIX_FMT_GBRAP16BE) {
+ for (i = 0; i < s->height; i++) {
+ for (j = soff; j < ssize; j += 2)
+ AV_WB16(dst + j, AV_RB16(dst + j) + AV_RB16(dst + j - soff));
+ dst += stride;
+ }
+ } else {
+ for (i = 0; i < s->height; i++) {
+ for (j = soff; j < ssize; j++)
+ dst[j] += dst[j - soff];
+ dst += stride;
+ }
+ }
+ }
+
+ if (s->photometric == TIFF_PHOTOMETRIC_WHITE_IS_ZERO) {
+ dst = p->data[plane];
+ for (i = 0; i < s->height; i++) {
+ for (j = 0; j < stride; j++)
+ dst[j] = (s->avctx->pix_fmt == AV_PIX_FMT_PAL8 ? (1<<s->bpp) - 1 : 255) - dst[j];
+ dst += stride;
+ }
+ }
+ }
+
+ if (s->planar && s->bppcount > 2) {
+ FFSWAP(uint8_t*, p->data[0], p->data[2]);
+ FFSWAP(int, p->linesize[0], p->linesize[2]);
+ FFSWAP(uint8_t*, p->data[0], p->data[1]);
+ FFSWAP(int, p->linesize[0], p->linesize[1]);
+ }
+
+ *got_frame = 1;
+
+ return avpkt->size;
+}
+
+static av_cold int tiff_init(AVCodecContext *avctx)
+{
+ TiffContext *s = avctx->priv_data;
+
+ s->width = 0;
+ s->height = 0;
+ s->subsampling[0] =
+ s->subsampling[1] = 1;
+ s->avctx = avctx;
+ ff_lzw_decode_open(&s->lzw);
+ ff_ccitt_unpack_init();
+
+ return 0;
+}
+
+static av_cold int tiff_end(AVCodecContext *avctx)
+{
+ TiffContext *const s = avctx->priv_data;
+
+ free_geotags(s);
+
+ ff_lzw_decode_close(&s->lzw);
+ av_freep(&s->deinvert_buf);
+ return 0;
+}
+
+AVCodec ff_tiff_decoder = {
+ .name = "tiff",
+ .long_name = NULL_IF_CONFIG_SMALL("TIFF image"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_TIFF,
+ .priv_data_size = sizeof(TiffContext),
+ .init = tiff_init,
+ .close = tiff_end,
+ .decode = decode_frame,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(tiff_init),
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/tiff.h b/ffmpeg-2-8-12/libavcodec/tiff.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tiff.h
rename to ffmpeg-2-8-12/libavcodec/tiff.h
diff --git a/ffmpeg-2-8-11/libavcodec/tiff_common.c b/ffmpeg-2-8-12/libavcodec/tiff_common.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tiff_common.c
rename to ffmpeg-2-8-12/libavcodec/tiff_common.c
diff --git a/ffmpeg-2-8-11/libavcodec/tiff_common.h b/ffmpeg-2-8-12/libavcodec/tiff_common.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tiff_common.h
rename to ffmpeg-2-8-12/libavcodec/tiff_common.h
diff --git a/ffmpeg-2-8-11/libavcodec/tiff_data.c b/ffmpeg-2-8-12/libavcodec/tiff_data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tiff_data.c
rename to ffmpeg-2-8-12/libavcodec/tiff_data.c
diff --git a/ffmpeg-2-8-11/libavcodec/tiff_data.h b/ffmpeg-2-8-12/libavcodec/tiff_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tiff_data.h
rename to ffmpeg-2-8-12/libavcodec/tiff_data.h
diff --git a/ffmpeg-2-8-11/libavcodec/tiffenc.c b/ffmpeg-2-8-12/libavcodec/tiffenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tiffenc.c
rename to ffmpeg-2-8-12/libavcodec/tiffenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/tmv.c b/ffmpeg-2-8-12/libavcodec/tmv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tmv.c
rename to ffmpeg-2-8-12/libavcodec/tmv.c
diff --git a/ffmpeg-2-8-11/libavcodec/tpeldsp.c b/ffmpeg-2-8-12/libavcodec/tpeldsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tpeldsp.c
rename to ffmpeg-2-8-12/libavcodec/tpeldsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/tpeldsp.h b/ffmpeg-2-8-12/libavcodec/tpeldsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tpeldsp.h
rename to ffmpeg-2-8-12/libavcodec/tpeldsp.h
diff --git a/ffmpeg-2-8-12/libavcodec/truemotion1.c b/ffmpeg-2-8-12/libavcodec/truemotion1.c
new file mode 100644
index 0000000..fdbc2f9
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/truemotion1.c
@@ -0,0 +1,920 @@
+/*
+ * Duck TrueMotion 1.0 Decoder
+ * Copyright (C) 2003 Alex Beregszaszi & Mike Melanson
+ *
+ * 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
+ * Duck TrueMotion v1 Video Decoder by
+ * Alex Beregszaszi and
+ * Mike Melanson (melanson at pcisys.net)
+ *
+ * The TrueMotion v1 decoder presently only decodes 16-bit TM1 data and
+ * outputs RGB555 (or RGB565) data. 24-bit TM1 data is not supported yet.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "avcodec.h"
+#include "internal.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mem.h"
+
+#include "truemotion1data.h"
+
+typedef struct TrueMotion1Context {
+ AVCodecContext *avctx;
+ AVFrame *frame;
+
+ const uint8_t *buf;
+ int size;
+
+ const uint8_t *mb_change_bits;
+ int mb_change_bits_row_size;
+ const uint8_t *index_stream;
+ int index_stream_size;
+
+ int flags;
+ int x, y, w, h;
+
+ uint32_t y_predictor_table[1024];
+ uint32_t c_predictor_table[1024];
+ uint32_t fat_y_predictor_table[1024];
+ uint32_t fat_c_predictor_table[1024];
+
+ int compression;
+ int block_type;
+ int block_width;
+ int block_height;
+
+ int16_t ydt[8];
+ int16_t cdt[8];
+ int16_t fat_ydt[8];
+ int16_t fat_cdt[8];
+
+ int last_deltaset, last_vectable;
+
+ unsigned int *vert_pred;
+ int vert_pred_size;
+
+} TrueMotion1Context;
+
+#define FLAG_SPRITE 32
+#define FLAG_KEYFRAME 16
+#define FLAG_INTERFRAME 8
+#define FLAG_INTERPOLATED 4
+
+struct frame_header {
+ uint8_t header_size;
+ uint8_t compression;
+ uint8_t deltaset;
+ uint8_t vectable;
+ uint16_t ysize;
+ uint16_t xsize;
+ uint16_t checksum;
+ uint8_t version;
+ uint8_t header_type;
+ uint8_t flags;
+ uint8_t control;
+ uint16_t xoffset;
+ uint16_t yoffset;
+ uint16_t width;
+ uint16_t height;
+};
+
+#define ALGO_NOP 0
+#define ALGO_RGB16V 1
+#define ALGO_RGB16H 2
+#define ALGO_RGB24H 3
+
+/* these are the various block sizes that can occupy a 4x4 block */
+#define BLOCK_2x2 0
+#define BLOCK_2x4 1
+#define BLOCK_4x2 2
+#define BLOCK_4x4 3
+
+typedef struct comp_types {
+ int algorithm;
+ int block_width; // vres
+ int block_height; // hres
+ int block_type;
+} comp_types;
+
+/* { valid for metatype }, algorithm, num of deltas, vert res, horiz res */
+static const comp_types compression_types[17] = {
+ { ALGO_NOP, 0, 0, 0 },
+
+ { ALGO_RGB16V, 4, 4, BLOCK_4x4 },
+ { ALGO_RGB16H, 4, 4, BLOCK_4x4 },
+ { ALGO_RGB16V, 4, 2, BLOCK_4x2 },
+ { ALGO_RGB16H, 4, 2, BLOCK_4x2 },
+
+ { ALGO_RGB16V, 2, 4, BLOCK_2x4 },
+ { ALGO_RGB16H, 2, 4, BLOCK_2x4 },
+ { ALGO_RGB16V, 2, 2, BLOCK_2x2 },
+ { ALGO_RGB16H, 2, 2, BLOCK_2x2 },
+
+ { ALGO_NOP, 4, 4, BLOCK_4x4 },
+ { ALGO_RGB24H, 4, 4, BLOCK_4x4 },
+ { ALGO_NOP, 4, 2, BLOCK_4x2 },
+ { ALGO_RGB24H, 4, 2, BLOCK_4x2 },
+
+ { ALGO_NOP, 2, 4, BLOCK_2x4 },
+ { ALGO_RGB24H, 2, 4, BLOCK_2x4 },
+ { ALGO_NOP, 2, 2, BLOCK_2x2 },
+ { ALGO_RGB24H, 2, 2, BLOCK_2x2 }
+};
+
+static void select_delta_tables(TrueMotion1Context *s, int delta_table_index)
+{
+ int i;
+
+ if (delta_table_index > 3)
+ return;
+
+ memcpy(s->ydt, ydts[delta_table_index], 8 * sizeof(int16_t));
+ memcpy(s->cdt, cdts[delta_table_index], 8 * sizeof(int16_t));
+ memcpy(s->fat_ydt, fat_ydts[delta_table_index], 8 * sizeof(int16_t));
+ memcpy(s->fat_cdt, fat_cdts[delta_table_index], 8 * sizeof(int16_t));
+
+ /* Y skinny deltas need to be halved for some reason; maybe the
+ * skinny Y deltas should be modified */
+ for (i = 0; i < 8; i++)
+ {
+ /* drop the lsb before dividing by 2-- net effect: round down
+ * when dividing a negative number (e.g., -3/2 = -2, not -1) */
+ s->ydt[i] &= 0xFFFE;
+ s->ydt[i] /= 2;
+ }
+}
+
+#if HAVE_BIGENDIAN
+static int make_ydt15_entry(int p2, int p1, int16_t *ydt)
+#else
+static int make_ydt15_entry(int p1, int p2, int16_t *ydt)
+#endif
+{
+ int lo, hi;
+
+ lo = ydt[p1];
+ lo += (lo * 32) + (lo * 1024);
+ hi = ydt[p2];
+ hi += (hi * 32) + (hi * 1024);
+ return (lo + (hi * (1U << 16))) * 2;
+}
+
+static int make_cdt15_entry(int p1, int p2, int16_t *cdt)
+{
+ int r, b, lo;
+
+ b = cdt[p2];
+ r = cdt[p1] * 1024;
+ lo = b + r;
+ return (lo + (lo * (1U << 16))) * 2;
+}
+
+#if HAVE_BIGENDIAN
+static int make_ydt16_entry(int p2, int p1, int16_t *ydt)
+#else
+static int make_ydt16_entry(int p1, int p2, int16_t *ydt)
+#endif
+{
+ int lo, hi;
+
+ lo = ydt[p1];
+ lo += (lo << 6) + (lo << 11);
+ hi = ydt[p2];
+ hi += (hi << 6) + (hi << 11);
+ return (lo + (hi << 16)) << 1;
+}
+
+static int make_cdt16_entry(int p1, int p2, int16_t *cdt)
+{
+ int r, b, lo;
+
+ b = cdt[p2];
+ r = cdt[p1] << 11;
+ lo = b + r;
+ return (lo + (lo * (1 << 16))) * 2;
+}
+
+static int make_ydt24_entry(int p1, int p2, int16_t *ydt)
+{
+ int lo, hi;
+
+ lo = ydt[p1];
+ hi = ydt[p2];
+ return (lo + (hi * (1 << 8)) + (hi * (1 << 16))) * 2;
+}
+
+static int make_cdt24_entry(int p1, int p2, int16_t *cdt)
+{
+ int r, b;
+
+ b = cdt[p2];
+ r = cdt[p1] * (1 << 16);
+ return (b+r) * 2;
+}
+
+static void gen_vector_table15(TrueMotion1Context *s, const uint8_t *sel_vector_table)
+{
+ int len, i, j;
+ unsigned char delta_pair;
+
+ for (i = 0; i < 1024; i += 4)
+ {
+ len = *sel_vector_table++ / 2;
+ for (j = 0; j < len; j++)
+ {
+ delta_pair = *sel_vector_table++;
+ s->y_predictor_table[i+j] = 0xfffffffe &
+ make_ydt15_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
+ s->c_predictor_table[i+j] = 0xfffffffe &
+ make_cdt15_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
+ }
+ s->y_predictor_table[i+(j-1)] |= 1;
+ s->c_predictor_table[i+(j-1)] |= 1;
+ }
+}
+
+static void gen_vector_table16(TrueMotion1Context *s, const uint8_t *sel_vector_table)
+{
+ int len, i, j;
+ unsigned char delta_pair;
+
+ for (i = 0; i < 1024; i += 4)
+ {
+ len = *sel_vector_table++ / 2;
+ for (j = 0; j < len; j++)
+ {
+ delta_pair = *sel_vector_table++;
+ s->y_predictor_table[i+j] = 0xfffffffe &
+ make_ydt16_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
+ s->c_predictor_table[i+j] = 0xfffffffe &
+ make_cdt16_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
+ }
+ s->y_predictor_table[i+(j-1)] |= 1;
+ s->c_predictor_table[i+(j-1)] |= 1;
+ }
+}
+
+static void gen_vector_table24(TrueMotion1Context *s, const uint8_t *sel_vector_table)
+{
+ int len, i, j;
+ unsigned char delta_pair;
+
+ for (i = 0; i < 1024; i += 4)
+ {
+ len = *sel_vector_table++ / 2;
+ for (j = 0; j < len; j++)
+ {
+ delta_pair = *sel_vector_table++;
+ s->y_predictor_table[i+j] = 0xfffffffe &
+ make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt);
+ s->c_predictor_table[i+j] = 0xfffffffe &
+ make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt);
+ s->fat_y_predictor_table[i+j] = 0xfffffffe &
+ make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_ydt);
+ s->fat_c_predictor_table[i+j] = 0xfffffffe &
+ make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_cdt);
+ }
+ s->y_predictor_table[i+(j-1)] |= 1;
+ s->c_predictor_table[i+(j-1)] |= 1;
+ s->fat_y_predictor_table[i+(j-1)] |= 1;
+ s->fat_c_predictor_table[i+(j-1)] |= 1;
+ }
+}
+
+/* Returns the number of bytes consumed from the bytestream. Returns -1 if
+ * there was an error while decoding the header */
+static int truemotion1_decode_header(TrueMotion1Context *s)
+{
+ int i, ret;
+ int width_shift = 0;
+ int new_pix_fmt;
+ struct frame_header header;
+ uint8_t header_buffer[128] = { 0 }; /* logical maximum size of the header */
+ const uint8_t *sel_vector_table;
+
+ header.header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f;
+ if (s->buf[0] < 0x10)
+ {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid header size (%d)\n", s->buf[0]);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (header.header_size + 1 > s->size) {
+ av_log(s->avctx, AV_LOG_ERROR, "Input packet too small.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* unscramble the header bytes with a XOR operation */
+ for (i = 1; i < header.header_size; i++)
+ header_buffer[i - 1] = s->buf[i] ^ s->buf[i + 1];
+
+ header.compression = header_buffer[0];
+ header.deltaset = header_buffer[1];
+ header.vectable = header_buffer[2];
+ header.ysize = AV_RL16(&header_buffer[3]);
+ header.xsize = AV_RL16(&header_buffer[5]);
+ header.checksum = AV_RL16(&header_buffer[7]);
+ header.version = header_buffer[9];
+ header.header_type = header_buffer[10];
+ header.flags = header_buffer[11];
+ header.control = header_buffer[12];
+
+ /* Version 2 */
+ if (header.version >= 2)
+ {
+ if (header.header_type > 3)
+ {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid header type (%d)\n", header.header_type);
+ return AVERROR_INVALIDDATA;
+ } else if ((header.header_type == 2) || (header.header_type == 3)) {
+ s->flags = header.flags;
+ if (!(s->flags & FLAG_INTERFRAME))
+ s->flags |= FLAG_KEYFRAME;
+ } else
+ s->flags = FLAG_KEYFRAME;
+ } else /* Version 1 */
+ s->flags = FLAG_KEYFRAME;
+
+ if (s->flags & FLAG_SPRITE) {
+ avpriv_request_sample(s->avctx, "Frame with sprite");
+ /* FIXME header.width, height, xoffset and yoffset aren't initialized */
+ return AVERROR_PATCHWELCOME;
+ } else {
+ s->w = header.xsize;
+ s->h = header.ysize;
+ if (header.header_type < 2) {
+ if ((s->w < 213) && (s->h >= 176))
+ {
+ s->flags |= FLAG_INTERPOLATED;
+ avpriv_request_sample(s->avctx, "Interpolated frame");
+ }
+ }
+ }
+
+ if (header.compression >= 17) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid compression type (%d)\n", header.compression);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if ((header.deltaset != s->last_deltaset) ||
+ (header.vectable != s->last_vectable))
+ select_delta_tables(s, header.deltaset);
+
+ if ((header.compression & 1) && header.header_type)
+ sel_vector_table = pc_tbl2;
+ else {
+ if (header.vectable > 0 && header.vectable < 4)
+ sel_vector_table = tables[header.vectable - 1];
+ else {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid vector table id (%d)\n", header.vectable);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if (compression_types[header.compression].algorithm == ALGO_RGB24H) {
+ new_pix_fmt = AV_PIX_FMT_RGB32;
+ width_shift = 1;
+ } else
+ new_pix_fmt = AV_PIX_FMT_RGB555; // RGB565 is supported as well
+
+ s->w >>= width_shift;
+ if (s->w & 1) {
+ avpriv_request_sample(s->avctx, "Frame with odd width");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if (s->w != s->avctx->width || s->h != s->avctx->height ||
+ new_pix_fmt != s->avctx->pix_fmt) {
+ av_frame_unref(s->frame);
+ s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 };
+ s->avctx->pix_fmt = new_pix_fmt;
+
+ if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0)
+ return ret;
+
+ ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio);
+
+ av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
+ if (!s->vert_pred)
+ return AVERROR(ENOMEM);
+ }
+
+ /* There is 1 change bit per 4 pixels, so each change byte represents
+ * 32 pixels; divide width by 4 to obtain the number of change bits and
+ * then round up to the nearest byte. */
+ s->mb_change_bits_row_size = ((s->avctx->width >> (2 - width_shift)) + 7) >> 3;
+
+ if ((header.deltaset != s->last_deltaset) || (header.vectable != s->last_vectable))
+ {
+ if (compression_types[header.compression].algorithm == ALGO_RGB24H)
+ gen_vector_table24(s, sel_vector_table);
+ else
+ if (s->avctx->pix_fmt == AV_PIX_FMT_RGB555)
+ gen_vector_table15(s, sel_vector_table);
+ else
+ gen_vector_table16(s, sel_vector_table);
+ }
+
+ /* set up pointers to the other key data chunks */
+ s->mb_change_bits = s->buf + header.header_size;
+ if (s->flags & FLAG_KEYFRAME) {
+ /* no change bits specified for a keyframe; only index bytes */
+ s->index_stream = s->mb_change_bits;
+ } else {
+ /* one change bit per 4x4 block */
+ s->index_stream = s->mb_change_bits +
+ (s->mb_change_bits_row_size * (s->avctx->height >> 2));
+ }
+ s->index_stream_size = s->size - (s->index_stream - s->buf);
+
+ s->last_deltaset = header.deltaset;
+ s->last_vectable = header.vectable;
+ s->compression = header.compression;
+ s->block_width = compression_types[header.compression].block_width;
+ s->block_height = compression_types[header.compression].block_height;
+ s->block_type = compression_types[header.compression].block_type;
+
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_INFO, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n",
+ s->last_deltaset, s->last_vectable, s->compression, s->block_width,
+ s->block_height, s->block_type,
+ s->flags & FLAG_KEYFRAME ? " KEY" : "",
+ s->flags & FLAG_INTERFRAME ? " INTER" : "",
+ s->flags & FLAG_SPRITE ? " SPRITE" : "",
+ s->flags & FLAG_INTERPOLATED ? " INTERPOL" : "");
+
+ return header.header_size;
+}
+
+static av_cold int truemotion1_decode_init(AVCodecContext *avctx)
+{
+ TrueMotion1Context *s = avctx->priv_data;
+
+ s->avctx = avctx;
+
+ // FIXME: it may change ?
+// if (avctx->bits_per_sample == 24)
+// avctx->pix_fmt = AV_PIX_FMT_RGB24;
+// else
+// avctx->pix_fmt = AV_PIX_FMT_RGB555;
+
+ s->frame = av_frame_alloc();
+ if (!s->frame)
+ return AVERROR(ENOMEM);
+
+ /* there is a vertical predictor for each pixel in a line; each vertical
+ * predictor is 0 to start with */
+ av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
+ if (!s->vert_pred)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+/*
+Block decoding order:
+
+dxi: Y-Y
+dxic: Y-C-Y
+dxic2: Y-C-Y-C
+
+hres,vres,i,i%vres (0 < i < 4)
+2x2 0: 0 dxic2
+2x2 1: 1 dxi
+2x2 2: 0 dxic2
+2x2 3: 1 dxi
+2x4 0: 0 dxic2
+2x4 1: 1 dxi
+2x4 2: 2 dxi
+2x4 3: 3 dxi
+4x2 0: 0 dxic
+4x2 1: 1 dxi
+4x2 2: 0 dxic
+4x2 3: 1 dxi
+4x4 0: 0 dxic
+4x4 1: 1 dxi
+4x4 2: 2 dxi
+4x4 3: 3 dxi
+*/
+
+#define GET_NEXT_INDEX() \
+{\
+ if (index_stream_index >= s->index_stream_size) { \
+ av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \
+ return; \
+ } \
+ index = s->index_stream[index_stream_index++] * 4; \
+}
+
+#define INC_INDEX \
+do { \
+ if (index >= 1023) { \
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid index value.\n"); \
+ return; \
+ } \
+ index++; \
+} while (0)
+
+#define APPLY_C_PREDICTOR() \
+ predictor_pair = s->c_predictor_table[index]; \
+ horiz_pred += (predictor_pair >> 1); \
+ if (predictor_pair & 1) { \
+ GET_NEXT_INDEX() \
+ if (!index) { \
+ GET_NEXT_INDEX() \
+ predictor_pair = s->c_predictor_table[index]; \
+ horiz_pred += ((predictor_pair >> 1) * 5); \
+ if (predictor_pair & 1) \
+ GET_NEXT_INDEX() \
+ else \
+ INC_INDEX; \
+ } \
+ } else \
+ INC_INDEX;
+
+#define APPLY_C_PREDICTOR_24() \
+ predictor_pair = s->c_predictor_table[index]; \
+ horiz_pred += (predictor_pair >> 1); \
+ if (predictor_pair & 1) { \
+ GET_NEXT_INDEX() \
+ if (!index) { \
+ GET_NEXT_INDEX() \
+ predictor_pair = s->fat_c_predictor_table[index]; \
+ horiz_pred += (predictor_pair >> 1); \
+ if (predictor_pair & 1) \
+ GET_NEXT_INDEX() \
+ else \
+ INC_INDEX; \
+ } \
+ } else \
+ INC_INDEX;
+
+
+#define APPLY_Y_PREDICTOR() \
+ predictor_pair = s->y_predictor_table[index]; \
+ horiz_pred += (predictor_pair >> 1); \
+ if (predictor_pair & 1) { \
+ GET_NEXT_INDEX() \
+ if (!index) { \
+ GET_NEXT_INDEX() \
+ predictor_pair = s->y_predictor_table[index]; \
+ horiz_pred += ((predictor_pair >> 1) * 5); \
+ if (predictor_pair & 1) \
+ GET_NEXT_INDEX() \
+ else \
+ INC_INDEX; \
+ } \
+ } else \
+ INC_INDEX;
+
+#define APPLY_Y_PREDICTOR_24() \
+ predictor_pair = s->y_predictor_table[index]; \
+ horiz_pred += (predictor_pair >> 1); \
+ if (predictor_pair & 1) { \
+ GET_NEXT_INDEX() \
+ if (!index) { \
+ GET_NEXT_INDEX() \
+ predictor_pair = s->fat_y_predictor_table[index]; \
+ horiz_pred += (predictor_pair >> 1); \
+ if (predictor_pair & 1) \
+ GET_NEXT_INDEX() \
+ else \
+ INC_INDEX; \
+ } \
+ } else \
+ INC_INDEX;
+
+#define OUTPUT_PIXEL_PAIR() \
+ *current_pixel_pair = *vert_pred + horiz_pred; \
+ *vert_pred++ = *current_pixel_pair++;
+
+static void truemotion1_decode_16bit(TrueMotion1Context *s)
+{
+ int y;
+ int pixels_left; /* remaining pixels on this line */
+ unsigned int predictor_pair;
+ unsigned int horiz_pred;
+ unsigned int *vert_pred;
+ unsigned int *current_pixel_pair;
+ unsigned char *current_line = s->frame->data[0];
+ int keyframe = s->flags & FLAG_KEYFRAME;
+
+ /* these variables are for managing the stream of macroblock change bits */
+ const unsigned char *mb_change_bits = s->mb_change_bits;
+ unsigned char mb_change_byte;
+ unsigned char mb_change_byte_mask;
+ int mb_change_index;
+
+ /* these variables are for managing the main index stream */
+ int index_stream_index = 0; /* yes, the index into the index stream */
+ int index;
+
+ /* clean out the line buffer */
+ memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int));
+
+ GET_NEXT_INDEX();
+
+ for (y = 0; y < s->avctx->height; y++) {
+
+ /* re-init variables for the next line iteration */
+ horiz_pred = 0;
+ current_pixel_pair = (unsigned int *)current_line;
+ vert_pred = s->vert_pred;
+ mb_change_index = 0;
+ mb_change_byte = mb_change_bits[mb_change_index++];
+ mb_change_byte_mask = 0x01;
+ pixels_left = s->avctx->width;
+
+ while (pixels_left > 0) {
+
+ if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
+
+ switch (y & 3) {
+ case 0:
+ /* if macroblock width is 2, apply C-Y-C-Y; else
+ * apply C-Y-Y */
+ if (s->block_width == 2) {
+ APPLY_C_PREDICTOR();
+ APPLY_Y_PREDICTOR();
+ OUTPUT_PIXEL_PAIR();
+ APPLY_C_PREDICTOR();
+ APPLY_Y_PREDICTOR();
+ OUTPUT_PIXEL_PAIR();
+ } else {
+ APPLY_C_PREDICTOR();
+ APPLY_Y_PREDICTOR();
+ OUTPUT_PIXEL_PAIR();
+ APPLY_Y_PREDICTOR();
+ OUTPUT_PIXEL_PAIR();
+ }
+ break;
+
+ case 1:
+ case 3:
+ /* always apply 2 Y predictors on these iterations */
+ APPLY_Y_PREDICTOR();
+ OUTPUT_PIXEL_PAIR();
+ APPLY_Y_PREDICTOR();
+ OUTPUT_PIXEL_PAIR();
+ break;
+
+ case 2:
+ /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
+ * depending on the macroblock type */
+ if (s->block_type == BLOCK_2x2) {
+ APPLY_C_PREDICTOR();
+ APPLY_Y_PREDICTOR();
+ OUTPUT_PIXEL_PAIR();
+ APPLY_C_PREDICTOR();
+ APPLY_Y_PREDICTOR();
+ OUTPUT_PIXEL_PAIR();
+ } else if (s->block_type == BLOCK_4x2) {
+ APPLY_C_PREDICTOR();
+ APPLY_Y_PREDICTOR();
+ OUTPUT_PIXEL_PAIR();
+ APPLY_Y_PREDICTOR();
+ OUTPUT_PIXEL_PAIR();
+ } else {
+ APPLY_Y_PREDICTOR();
+ OUTPUT_PIXEL_PAIR();
+ APPLY_Y_PREDICTOR();
+ OUTPUT_PIXEL_PAIR();
+ }
+ break;
+ }
+
+ } else {
+
+ /* skip (copy) four pixels, but reassign the horizontal
+ * predictor */
+ *vert_pred++ = *current_pixel_pair++;
+ horiz_pred = *current_pixel_pair - *vert_pred;
+ *vert_pred++ = *current_pixel_pair++;
+
+ }
+
+ if (!keyframe) {
+ mb_change_byte_mask <<= 1;
+
+ /* next byte */
+ if (!mb_change_byte_mask) {
+ mb_change_byte = mb_change_bits[mb_change_index++];
+ mb_change_byte_mask = 0x01;
+ }
+ }
+
+ pixels_left -= 4;
+ }
+
+ /* next change row */
+ if (((y + 1) & 3) == 0)
+ mb_change_bits += s->mb_change_bits_row_size;
+
+ current_line += s->frame->linesize[0];
+ }
+}
+
+static void truemotion1_decode_24bit(TrueMotion1Context *s)
+{
+ int y;
+ int pixels_left; /* remaining pixels on this line */
+ unsigned int predictor_pair;
+ unsigned int horiz_pred;
+ unsigned int *vert_pred;
+ unsigned int *current_pixel_pair;
+ unsigned char *current_line = s->frame->data[0];
+ int keyframe = s->flags & FLAG_KEYFRAME;
+
+ /* these variables are for managing the stream of macroblock change bits */
+ const unsigned char *mb_change_bits = s->mb_change_bits;
+ unsigned char mb_change_byte;
+ unsigned char mb_change_byte_mask;
+ int mb_change_index;
+
+ /* these variables are for managing the main index stream */
+ int index_stream_index = 0; /* yes, the index into the index stream */
+ int index;
+
+ /* clean out the line buffer */
+ memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int));
+
+ GET_NEXT_INDEX();
+
+ for (y = 0; y < s->avctx->height; y++) {
+
+ /* re-init variables for the next line iteration */
+ horiz_pred = 0;
+ current_pixel_pair = (unsigned int *)current_line;
+ vert_pred = s->vert_pred;
+ mb_change_index = 0;
+ mb_change_byte = mb_change_bits[mb_change_index++];
+ mb_change_byte_mask = 0x01;
+ pixels_left = s->avctx->width;
+
+ while (pixels_left > 0) {
+
+ if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) {
+
+ switch (y & 3) {
+ case 0:
+ /* if macroblock width is 2, apply C-Y-C-Y; else
+ * apply C-Y-Y */
+ if (s->block_width == 2) {
+ APPLY_C_PREDICTOR_24();
+ APPLY_Y_PREDICTOR_24();
+ OUTPUT_PIXEL_PAIR();
+ APPLY_C_PREDICTOR_24();
+ APPLY_Y_PREDICTOR_24();
+ OUTPUT_PIXEL_PAIR();
+ } else {
+ APPLY_C_PREDICTOR_24();
+ APPLY_Y_PREDICTOR_24();
+ OUTPUT_PIXEL_PAIR();
+ APPLY_Y_PREDICTOR_24();
+ OUTPUT_PIXEL_PAIR();
+ }
+ break;
+
+ case 1:
+ case 3:
+ /* always apply 2 Y predictors on these iterations */
+ APPLY_Y_PREDICTOR_24();
+ OUTPUT_PIXEL_PAIR();
+ APPLY_Y_PREDICTOR_24();
+ OUTPUT_PIXEL_PAIR();
+ break;
+
+ case 2:
+ /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y
+ * depending on the macroblock type */
+ if (s->block_type == BLOCK_2x2) {
+ APPLY_C_PREDICTOR_24();
+ APPLY_Y_PREDICTOR_24();
+ OUTPUT_PIXEL_PAIR();
+ APPLY_C_PREDICTOR_24();
+ APPLY_Y_PREDICTOR_24();
+ OUTPUT_PIXEL_PAIR();
+ } else if (s->block_type == BLOCK_4x2) {
+ APPLY_C_PREDICTOR_24();
+ APPLY_Y_PREDICTOR_24();
+ OUTPUT_PIXEL_PAIR();
+ APPLY_Y_PREDICTOR_24();
+ OUTPUT_PIXEL_PAIR();
+ } else {
+ APPLY_Y_PREDICTOR_24();
+ OUTPUT_PIXEL_PAIR();
+ APPLY_Y_PREDICTOR_24();
+ OUTPUT_PIXEL_PAIR();
+ }
+ break;
+ }
+
+ } else {
+
+ /* skip (copy) four pixels, but reassign the horizontal
+ * predictor */
+ *vert_pred++ = *current_pixel_pair++;
+ horiz_pred = *current_pixel_pair - *vert_pred;
+ *vert_pred++ = *current_pixel_pair++;
+
+ }
+
+ if (!keyframe) {
+ mb_change_byte_mask <<= 1;
+
+ /* next byte */
+ if (!mb_change_byte_mask) {
+ mb_change_byte = mb_change_bits[mb_change_index++];
+ mb_change_byte_mask = 0x01;
+ }
+ }
+
+ pixels_left -= 2;
+ }
+
+ /* next change row */
+ if (((y + 1) & 3) == 0)
+ mb_change_bits += s->mb_change_bits_row_size;
+
+ current_line += s->frame->linesize[0];
+ }
+}
+
+
+static int truemotion1_decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int ret, buf_size = avpkt->size;
+ TrueMotion1Context *s = avctx->priv_data;
+
+ s->buf = buf;
+ s->size = buf_size;
+
+ if ((ret = truemotion1_decode_header(s)) < 0)
+ return ret;
+
+ if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
+ return ret;
+
+ if (compression_types[s->compression].algorithm == ALGO_RGB24H) {
+ truemotion1_decode_24bit(s);
+ } else if (compression_types[s->compression].algorithm != ALGO_NOP) {
+ truemotion1_decode_16bit(s);
+ }
+
+ if ((ret = av_frame_ref(data, s->frame)) < 0)
+ return ret;
+
+ *got_frame = 1;
+
+ /* report that the buffer was completely consumed */
+ return buf_size;
+}
+
+static av_cold int truemotion1_decode_end(AVCodecContext *avctx)
+{
+ TrueMotion1Context *s = avctx->priv_data;
+
+ av_frame_free(&s->frame);
+ av_freep(&s->vert_pred);
+
+ return 0;
+}
+
+AVCodec ff_truemotion1_decoder = {
+ .name = "truemotion1",
+ .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_TRUEMOTION1,
+ .priv_data_size = sizeof(TrueMotion1Context),
+ .init = truemotion1_decode_init,
+ .close = truemotion1_decode_end,
+ .decode = truemotion1_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/truemotion1data.h b/ffmpeg-2-8-12/libavcodec/truemotion1data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/truemotion1data.h
rename to ffmpeg-2-8-12/libavcodec/truemotion1data.h
diff --git a/ffmpeg-2-8-12/libavcodec/truemotion2.c b/ffmpeg-2-8-12/libavcodec/truemotion2.c
new file mode 100644
index 0000000..8691d6d
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/truemotion2.c
@@ -0,0 +1,1028 @@
+/*
+ * Duck/ON2 TrueMotion 2 Decoder
+ * Copyright (c) 2005 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
+ */
+
+/**
+ * @file
+ * Duck TrueMotion2 decoder.
+ */
+
+#include <inttypes.h>
+
+#include "avcodec.h"
+#include "bswapdsp.h"
+#include "bytestream.h"
+#include "get_bits.h"
+#include "internal.h"
+
+#define TM2_ESCAPE 0x80000000
+#define TM2_DELTAS 64
+
+/* Huffman-coded streams of different types of blocks */
+enum TM2_STREAMS {
+ TM2_C_HI = 0,
+ TM2_C_LO,
+ TM2_L_HI,
+ TM2_L_LO,
+ TM2_UPD,
+ TM2_MOT,
+ TM2_TYPE,
+ TM2_NUM_STREAMS
+};
+
+/* Block types */
+enum TM2_BLOCKS {
+ TM2_HI_RES = 0,
+ TM2_MED_RES,
+ TM2_LOW_RES,
+ TM2_NULL_RES,
+ TM2_UPDATE,
+ TM2_STILL,
+ TM2_MOTION
+};
+
+typedef struct TM2Context {
+ AVCodecContext *avctx;
+ AVFrame *pic;
+
+ GetBitContext gb;
+ BswapDSPContext bdsp;
+
+ uint8_t *buffer;
+ int buffer_size;
+
+ /* TM2 streams */
+ int *tokens[TM2_NUM_STREAMS];
+ int tok_lens[TM2_NUM_STREAMS];
+ int tok_ptrs[TM2_NUM_STREAMS];
+ int deltas[TM2_NUM_STREAMS][TM2_DELTAS];
+ /* for blocks decoding */
+ int D[4];
+ int CD[4];
+ int *last;
+ int *clast;
+
+ /* data for current and previous frame */
+ int *Y1_base, *U1_base, *V1_base, *Y2_base, *U2_base, *V2_base;
+ int *Y1, *U1, *V1, *Y2, *U2, *V2;
+ int y_stride, uv_stride;
+ int cur;
+} TM2Context;
+
+/**
+* Huffman codes for each of streams
+*/
+typedef struct TM2Codes {
+ VLC vlc; ///< table for FFmpeg bitstream reader
+ int bits;
+ int *recode; ///< table for converting from code indexes to values
+ int length;
+} TM2Codes;
+
+/**
+* structure for gathering Huffman codes information
+*/
+typedef struct TM2Huff {
+ int val_bits; ///< length of literal
+ int max_bits; ///< maximum length of code
+ int min_bits; ///< minimum length of code
+ int nodes; ///< total number of nodes in tree
+ int num; ///< current number filled
+ int max_num; ///< total number of codes
+ int *nums; ///< literals
+ uint32_t *bits; ///< codes
+ int *lens; ///< codelengths
+} TM2Huff;
+
+static int tm2_read_tree(TM2Context *ctx, uint32_t prefix, int length, TM2Huff *huff)
+{
+ int ret;
+ if (length > huff->max_bits) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Tree exceeded its given depth (%i)\n",
+ huff->max_bits);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!get_bits1(&ctx->gb)) { /* literal */
+ if (length == 0) {
+ length = 1;
+ }
+ if (huff->num >= huff->max_num) {
+ av_log(ctx->avctx, AV_LOG_DEBUG, "Too many literals\n");
+ 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 0;
+ } else { /* non-terminal node */
+ if ((ret = tm2_read_tree(ctx, prefix << 1, length + 1, huff)) < 0)
+ return ret;
+ if ((ret = tm2_read_tree(ctx, (prefix << 1) | 1, length + 1, huff)) < 0)
+ return ret;
+ }
+ return 0;
+}
+
+static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code)
+{
+ TM2Huff huff;
+ int res = 0;
+
+ huff.val_bits = get_bits(&ctx->gb, 5);
+ huff.max_bits = get_bits(&ctx->gb, 5);
+ huff.min_bits = get_bits(&ctx->gb, 5);
+ huff.nodes = get_bits_long(&ctx->gb, 17);
+ huff.num = 0;
+
+ /* check for correct codes parameters */
+ if ((huff.val_bits < 1) || (huff.val_bits > 32) ||
+ (huff.max_bits < 0) || (huff.max_bits > 25)) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect tree parameters - literal "
+ "length: %i, max code length: %i\n", huff.val_bits, huff.max_bits);
+ return AVERROR_INVALIDDATA;
+ }
+ if ((huff.nodes <= 0) || (huff.nodes > 0x10000)) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of Huffman tree "
+ "nodes: %i\n", huff.nodes);
+ return AVERROR_INVALIDDATA;
+ }
+ /* one-node tree */
+ if (huff.max_bits == 0)
+ huff.max_bits = 1;
+
+ /* 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));
+
+ if (!huff.nums || !huff.bits || !huff.lens) {
+ res = AVERROR(ENOMEM);
+ goto out;
+ }
+
+ res = tm2_read_tree(ctx, 0, 0, &huff);
+
+ if (huff.num != huff.max_num) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Got less codes than expected: %i of %i\n",
+ huff.num, huff.max_num);
+ res = AVERROR_INVALIDDATA;
+ }
+
+ /* 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);
+ 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];
+ }
+ }
+
+out:
+ /* free allocated memory */
+ av_free(huff.nums);
+ av_free(huff.bits);
+ av_free(huff.lens);
+
+ return res;
+}
+
+static void tm2_free_codes(TM2Codes *code)
+{
+ av_free(code->recode);
+ if (code->vlc.table)
+ ff_free_vlc(&code->vlc);
+}
+
+static inline int tm2_get_token(GetBitContext *gb, TM2Codes *code)
+{
+ int val;
+ val = get_vlc2(gb, code->vlc.table, code->bits, 1);
+ if(val<0)
+ return -1;
+ return code->recode[val];
+}
+
+#define TM2_OLD_HEADER_MAGIC 0x00000100
+#define TM2_NEW_HEADER_MAGIC 0x00000101
+
+static inline int tm2_read_header(TM2Context *ctx, const uint8_t *buf)
+{
+ uint32_t magic = AV_RL32(buf);
+
+ switch (magic) {
+ case TM2_OLD_HEADER_MAGIC:
+ avpriv_request_sample(ctx->avctx, "Old TM2 header");
+ return 0;
+ case TM2_NEW_HEADER_MAGIC:
+ return 0;
+ default:
+ av_log(ctx->avctx, AV_LOG_ERROR, "Not a TM2 header: 0x%08"PRIX32"\n",
+ magic);
+ return AVERROR_INVALIDDATA;
+ }
+}
+
+static int tm2_read_deltas(TM2Context *ctx, int stream_id)
+{
+ int d, mb;
+ int i, v;
+
+ d = get_bits(&ctx->gb, 9);
+ mb = get_bits(&ctx->gb, 5);
+
+ av_assert2(mb < 32);
+ if ((d < 1) || (d > TM2_DELTAS) || (mb < 1)) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect delta table: %i deltas x %i bits\n", d, mb);
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (i = 0; i < d; i++) {
+ v = get_bits_long(&ctx->gb, mb);
+ if (v & (1 << (mb - 1)))
+ ctx->deltas[stream_id][i] = v - (1U << mb);
+ else
+ ctx->deltas[stream_id][i] = v;
+ }
+ for (; i < TM2_DELTAS; i++)
+ ctx->deltas[stream_id][i] = 0;
+
+ return 0;
+}
+
+static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, int buf_size)
+{
+ int i, ret;
+ int skip = 0;
+ int len, toks, pos;
+ TM2Codes codes;
+ GetByteContext gb;
+
+ if (buf_size < 4) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "not enough space for len left\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* get stream length in dwords */
+ bytestream2_init(&gb, buf, buf_size);
+ len = bytestream2_get_be32(&gb);
+ skip = len * 4 + 4;
+
+ if (len == 0)
+ return 4;
+
+ if (len >= INT_MAX/4-1 || len < 0 || skip > buf_size) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "invalid stream size\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ toks = bytestream2_get_be32(&gb);
+ if (toks & 1) {
+ len = bytestream2_get_be32(&gb);
+ if (len == TM2_ESCAPE) {
+ len = bytestream2_get_be32(&gb);
+ }
+ if (len > 0) {
+ pos = bytestream2_tell(&gb);
+ if (skip <= pos)
+ return AVERROR_INVALIDDATA;
+ init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
+ if ((ret = tm2_read_deltas(ctx, stream_id)) < 0)
+ return ret;
+ bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2);
+ }
+ }
+ /* skip unused fields */
+ len = bytestream2_get_be32(&gb);
+ if (len == TM2_ESCAPE) { /* some unknown length - could be escaped too */
+ bytestream2_skip(&gb, 8); /* unused by decoder */
+ } else {
+ bytestream2_skip(&gb, 4); /* unused by decoder */
+ }
+
+ pos = bytestream2_tell(&gb);
+ if (skip <= pos)
+ return AVERROR_INVALIDDATA;
+ init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
+ if ((ret = tm2_build_huff_table(ctx, &codes)) < 0)
+ return ret;
+ bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2);
+
+ toks >>= 1;
+ /* check if we have sane number of tokens */
+ if ((toks < 0) || (toks > 0xFFFFFF)) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks);
+ tm2_free_codes(&codes);
+ return AVERROR_INVALIDDATA;
+ }
+ ret = av_reallocp_array(&ctx->tokens[stream_id], toks, sizeof(int));
+ if (ret < 0) {
+ ctx->tok_lens[stream_id] = 0;
+ return ret;
+ }
+ ctx->tok_lens[stream_id] = toks;
+ len = bytestream2_get_be32(&gb);
+ if (len > 0) {
+ pos = bytestream2_tell(&gb);
+ if (skip <= pos)
+ return AVERROR_INVALIDDATA;
+ init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8);
+ for (i = 0; i < toks; i++) {
+ if (get_bits_left(&ctx->gb) <= 0) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks);
+ return AVERROR_INVALIDDATA;
+ }
+ ctx->tokens[stream_id][i] = tm2_get_token(&ctx->gb, &codes);
+ if (stream_id <= TM2_MOT && ctx->tokens[stream_id][i] >= TM2_DELTAS || ctx->tokens[stream_id][i]<0) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Invalid delta token index %d for type %d, n=%d\n",
+ ctx->tokens[stream_id][i], stream_id, i);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ } else {
+ for (i = 0; i < toks; i++) {
+ ctx->tokens[stream_id][i] = codes.recode[0];
+ if (stream_id <= TM2_MOT && ctx->tokens[stream_id][i] >= TM2_DELTAS) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Invalid delta token index %d for type %d, n=%d\n",
+ ctx->tokens[stream_id][i], stream_id, i);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ }
+ tm2_free_codes(&codes);
+
+ return skip;
+}
+
+static inline int GET_TOK(TM2Context *ctx,int type)
+{
+ if (ctx->tok_ptrs[type] >= ctx->tok_lens[type]) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Read token from stream %i out of bounds (%i>=%i)\n", type, ctx->tok_ptrs[type], ctx->tok_lens[type]);
+ return 0;
+ }
+ if (type <= TM2_MOT) {
+ if (ctx->tokens[type][ctx->tok_ptrs[type]] >= TM2_DELTAS) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "token %d is too large\n", ctx->tokens[type][ctx->tok_ptrs[type]]);
+ return 0;
+ }
+ return ctx->deltas[type][ctx->tokens[type][ctx->tok_ptrs[type]++]];
+ }
+ return ctx->tokens[type][ctx->tok_ptrs[type]++];
+}
+
+/* blocks decoding routines */
+
+/* common Y, U, V pointers initialisation */
+#define TM2_INIT_POINTERS() \
+ int *last, *clast; \
+ int *Y, *U, *V;\
+ int Ystride, Ustride, Vstride;\
+\
+ Ystride = ctx->y_stride;\
+ Vstride = ctx->uv_stride;\
+ Ustride = ctx->uv_stride;\
+ Y = (ctx->cur?ctx->Y2:ctx->Y1) + by * 4 * Ystride + bx * 4;\
+ V = (ctx->cur?ctx->V2:ctx->V1) + by * 2 * Vstride + bx * 2;\
+ U = (ctx->cur?ctx->U2:ctx->U1) + by * 2 * Ustride + bx * 2;\
+ last = ctx->last + bx * 4;\
+ clast = ctx->clast + bx * 4;
+
+#define TM2_INIT_POINTERS_2() \
+ int *Yo, *Uo, *Vo;\
+ int oYstride, oUstride, oVstride;\
+\
+ TM2_INIT_POINTERS();\
+ oYstride = Ystride;\
+ oVstride = Vstride;\
+ oUstride = Ustride;\
+ Yo = (ctx->cur?ctx->Y1:ctx->Y2) + by * 4 * oYstride + bx * 4;\
+ Vo = (ctx->cur?ctx->V1:ctx->V2) + by * 2 * oVstride + bx * 2;\
+ Uo = (ctx->cur?ctx->U1:ctx->U2) + by * 2 * oUstride + bx * 2;
+
+/* recalculate last and delta values for next blocks */
+#define TM2_RECALC_BLOCK(CHR, stride, last, CD) {\
+ CD[0] = CHR[1] - last[1];\
+ CD[1] = (int)CHR[stride + 1] - (int)CHR[1];\
+ last[0] = (int)CHR[stride + 0];\
+ last[1] = (int)CHR[stride + 1];}
+
+/* common operations - add deltas to 4x4 block of luma or 2x2 blocks of chroma */
+static inline void tm2_apply_deltas(TM2Context *ctx, int* Y, int stride, int *deltas, int *last)
+{
+ int ct, d;
+ int i, j;
+
+ for (j = 0; j < 4; j++){
+ ct = ctx->D[j];
+ for (i = 0; i < 4; i++){
+ d = deltas[i + j * 4];
+ ct += d;
+ last[i] += ct;
+ Y[i] = av_clip_uint8(last[i]);
+ }
+ Y += stride;
+ ctx->D[j] = ct;
+ }
+}
+
+static inline void tm2_high_chroma(int *data, int stride, int *last, int *CD, int *deltas)
+{
+ int i, j;
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < 2; i++) {
+ CD[j] += deltas[i + j * 2];
+ last[i] += CD[j];
+ data[i] = last[i];
+ }
+ data += stride;
+ }
+}
+
+static inline void tm2_low_chroma(int *data, int stride, int *clast, int *CD, int *deltas, int bx)
+{
+ int t;
+ int l;
+ int prev;
+
+ if (bx > 0)
+ prev = clast[-3];
+ else
+ prev = 0;
+ t = (CD[0] + CD[1]) >> 1;
+ l = (prev - CD[0] - CD[1] + clast[1]) >> 1;
+ CD[1] = CD[0] + CD[1] - t;
+ CD[0] = t;
+ clast[0] = l;
+
+ tm2_high_chroma(data, stride, clast, CD, deltas);
+}
+
+static inline void tm2_hi_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
+{
+ int i;
+ int deltas[16];
+ TM2_INIT_POINTERS();
+
+ /* hi-res chroma */
+ for (i = 0; i < 4; i++) {
+ deltas[i] = GET_TOK(ctx, TM2_C_HI);
+ deltas[i + 4] = GET_TOK(ctx, TM2_C_HI);
+ }
+ tm2_high_chroma(U, Ustride, clast, ctx->CD, deltas);
+ tm2_high_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas + 4);
+
+ /* hi-res luma */
+ for (i = 0; i < 16; i++)
+ deltas[i] = GET_TOK(ctx, TM2_L_HI);
+
+ tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
+}
+
+static inline void tm2_med_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
+{
+ int i;
+ int deltas[16];
+ TM2_INIT_POINTERS();
+
+ /* low-res chroma */
+ deltas[0] = GET_TOK(ctx, TM2_C_LO);
+ deltas[1] = deltas[2] = deltas[3] = 0;
+ tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx);
+
+ deltas[0] = GET_TOK(ctx, TM2_C_LO);
+ deltas[1] = deltas[2] = deltas[3] = 0;
+ tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
+
+ /* hi-res luma */
+ for (i = 0; i < 16; i++)
+ deltas[i] = GET_TOK(ctx, TM2_L_HI);
+
+ tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
+}
+
+static inline void tm2_low_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
+{
+ int i;
+ int t1, t2;
+ int deltas[16];
+ TM2_INIT_POINTERS();
+
+ /* low-res chroma */
+ deltas[0] = GET_TOK(ctx, TM2_C_LO);
+ deltas[1] = deltas[2] = deltas[3] = 0;
+ tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx);
+
+ deltas[0] = GET_TOK(ctx, TM2_C_LO);
+ deltas[1] = deltas[2] = deltas[3] = 0;
+ tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
+
+ /* low-res luma */
+ for (i = 0; i < 16; i++)
+ deltas[i] = 0;
+
+ deltas[ 0] = GET_TOK(ctx, TM2_L_LO);
+ deltas[ 2] = GET_TOK(ctx, TM2_L_LO);
+ deltas[ 8] = GET_TOK(ctx, TM2_L_LO);
+ deltas[10] = GET_TOK(ctx, TM2_L_LO);
+
+ if (bx > 0)
+ last[0] = (last[-1] - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3] + last[1]) >> 1;
+ else
+ last[0] = (last[1] - ctx->D[0] - ctx->D[1] - ctx->D[2] - ctx->D[3])>> 1;
+ last[2] = (last[1] + last[3]) >> 1;
+
+ t1 = ctx->D[0] + ctx->D[1];
+ ctx->D[0] = t1 >> 1;
+ ctx->D[1] = t1 - (t1 >> 1);
+ t2 = ctx->D[2] + ctx->D[3];
+ ctx->D[2] = t2 >> 1;
+ ctx->D[3] = t2 - (t2 >> 1);
+
+ tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
+}
+
+static inline void tm2_null_res_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
+{
+ int i;
+ int ct;
+ int left, right, diff;
+ int deltas[16];
+ TM2_INIT_POINTERS();
+
+ /* null chroma */
+ deltas[0] = deltas[1] = deltas[2] = deltas[3] = 0;
+ tm2_low_chroma(U, Ustride, clast, ctx->CD, deltas, bx);
+
+ deltas[0] = deltas[1] = deltas[2] = deltas[3] = 0;
+ tm2_low_chroma(V, Vstride, clast + 2, ctx->CD + 2, deltas, bx);
+
+ /* null luma */
+ for (i = 0; i < 16; i++)
+ deltas[i] = 0;
+
+ ct = ctx->D[0] + ctx->D[1] + ctx->D[2] + ctx->D[3];
+
+ if (bx > 0)
+ left = last[-1] - ct;
+ else
+ left = 0;
+
+ right = last[3];
+ diff = right - left;
+ last[0] = left + (diff >> 2);
+ last[1] = left + (diff >> 1);
+ last[2] = right - (diff >> 2);
+ last[3] = right;
+ {
+ int tp = left;
+
+ ctx->D[0] = (tp + (ct >> 2)) - left;
+ left += ctx->D[0];
+ ctx->D[1] = (tp + (ct >> 1)) - left;
+ left += ctx->D[1];
+ ctx->D[2] = ((tp + ct) - (ct >> 2)) - left;
+ left += ctx->D[2];
+ ctx->D[3] = (tp + ct) - left;
+ }
+ tm2_apply_deltas(ctx, Y, Ystride, deltas, last);
+}
+
+static inline void tm2_still_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
+{
+ int i, j;
+ TM2_INIT_POINTERS_2();
+
+ /* update chroma */
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < 2; i++){
+ U[i] = Uo[i];
+ V[i] = Vo[i];
+ }
+ U += Ustride; V += Vstride;
+ Uo += oUstride; Vo += oVstride;
+ }
+ U -= Ustride * 2;
+ V -= Vstride * 2;
+ TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD);
+ TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2));
+
+ /* update deltas */
+ ctx->D[0] = Yo[3] - last[3];
+ ctx->D[1] = Yo[3 + oYstride] - Yo[3];
+ ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride];
+ ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2];
+
+ for (j = 0; j < 4; j++) {
+ for (i = 0; i < 4; i++) {
+ Y[i] = Yo[i];
+ last[i] = Yo[i];
+ }
+ Y += Ystride;
+ Yo += oYstride;
+ }
+}
+
+static inline void tm2_update_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
+{
+ int i, j;
+ int d;
+ TM2_INIT_POINTERS_2();
+
+ /* update chroma */
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < 2; i++) {
+ U[i] = Uo[i] + GET_TOK(ctx, TM2_UPD);
+ V[i] = Vo[i] + GET_TOK(ctx, TM2_UPD);
+ }
+ U += Ustride;
+ V += Vstride;
+ Uo += oUstride;
+ Vo += oVstride;
+ }
+ U -= Ustride * 2;
+ V -= Vstride * 2;
+ TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD);
+ TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2));
+
+ /* update deltas */
+ ctx->D[0] = Yo[3] - last[3];
+ ctx->D[1] = Yo[3 + oYstride] - Yo[3];
+ ctx->D[2] = Yo[3 + oYstride * 2] - Yo[3 + oYstride];
+ ctx->D[3] = Yo[3 + oYstride * 3] - Yo[3 + oYstride * 2];
+
+ for (j = 0; j < 4; j++) {
+ d = last[3];
+ for (i = 0; i < 4; i++) {
+ Y[i] = Yo[i] + GET_TOK(ctx, TM2_UPD);
+ last[i] = Y[i];
+ }
+ ctx->D[j] = last[3] - d;
+ Y += Ystride;
+ Yo += oYstride;
+ }
+}
+
+static inline void tm2_motion_block(TM2Context *ctx, AVFrame *pic, int bx, int by)
+{
+ int i, j;
+ int mx, my;
+ TM2_INIT_POINTERS_2();
+
+ mx = GET_TOK(ctx, TM2_MOT);
+ my = GET_TOK(ctx, TM2_MOT);
+ mx = av_clip(mx, -(bx * 4 + 4), ctx->avctx->width - bx * 4);
+ my = av_clip(my, -(by * 4 + 4), ctx->avctx->height - by * 4);
+
+ if (4*bx+mx<0 || 4*by+my<0 || 4*bx+mx+4 > ctx->avctx->width || 4*by+my+4 > ctx->avctx->height) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "MV out of picture\n");
+ return;
+ }
+
+ Yo += my * oYstride + mx;
+ Uo += (my >> 1) * oUstride + (mx >> 1);
+ Vo += (my >> 1) * oVstride + (mx >> 1);
+
+ /* copy chroma */
+ for (j = 0; j < 2; j++) {
+ for (i = 0; i < 2; i++) {
+ U[i] = Uo[i];
+ V[i] = Vo[i];
+ }
+ U += Ustride;
+ V += Vstride;
+ Uo += oUstride;
+ Vo += oVstride;
+ }
+ U -= Ustride * 2;
+ V -= Vstride * 2;
+ TM2_RECALC_BLOCK(U, Ustride, clast, ctx->CD);
+ TM2_RECALC_BLOCK(V, Vstride, (clast + 2), (ctx->CD + 2));
+
+ /* copy luma */
+ for (j = 0; j < 4; j++) {
+ for (i = 0; i < 4; i++) {
+ Y[i] = Yo[i];
+ }
+ Y += Ystride;
+ Yo += oYstride;
+ }
+ /* calculate deltas */
+ Y -= Ystride * 4;
+ ctx->D[0] = Y[3] - last[3];
+ ctx->D[1] = Y[3 + Ystride] - Y[3];
+ ctx->D[2] = Y[3 + Ystride * 2] - Y[3 + Ystride];
+ ctx->D[3] = Y[3 + Ystride * 3] - Y[3 + Ystride * 2];
+ for (i = 0; i < 4; i++)
+ last[i] = Y[i + Ystride * 3];
+}
+
+static int tm2_decode_blocks(TM2Context *ctx, AVFrame *p)
+{
+ int i, j;
+ int w = ctx->avctx->width, h = ctx->avctx->height, bw = w >> 2, bh = h >> 2, cw = w >> 1;
+ int type;
+ int keyframe = 1;
+ int *Y, *U, *V;
+ uint8_t *dst;
+
+ for (i = 0; i < TM2_NUM_STREAMS; i++)
+ ctx->tok_ptrs[i] = 0;
+
+ if (ctx->tok_lens[TM2_TYPE]<bw*bh) {
+ av_log(ctx->avctx,AV_LOG_ERROR,"Got %i tokens for %i blocks\n",ctx->tok_lens[TM2_TYPE],bw*bh);
+ return AVERROR_INVALIDDATA;
+ }
+
+ memset(ctx->last, 0, 4 * bw * sizeof(int));
+ memset(ctx->clast, 0, 4 * bw * sizeof(int));
+
+ for (j = 0; j < bh; j++) {
+ memset(ctx->D, 0, 4 * sizeof(int));
+ memset(ctx->CD, 0, 4 * sizeof(int));
+ for (i = 0; i < bw; i++) {
+ type = GET_TOK(ctx, TM2_TYPE);
+ switch(type) {
+ case TM2_HI_RES:
+ tm2_hi_res_block(ctx, p, i, j);
+ break;
+ case TM2_MED_RES:
+ tm2_med_res_block(ctx, p, i, j);
+ break;
+ case TM2_LOW_RES:
+ tm2_low_res_block(ctx, p, i, j);
+ break;
+ case TM2_NULL_RES:
+ tm2_null_res_block(ctx, p, i, j);
+ break;
+ case TM2_UPDATE:
+ tm2_update_block(ctx, p, i, j);
+ keyframe = 0;
+ break;
+ case TM2_STILL:
+ tm2_still_block(ctx, p, i, j);
+ keyframe = 0;
+ break;
+ case TM2_MOTION:
+ tm2_motion_block(ctx, p, i, j);
+ keyframe = 0;
+ break;
+ default:
+ av_log(ctx->avctx, AV_LOG_ERROR, "Skipping unknown block type %i\n", type);
+ }
+ }
+ }
+
+ /* copy data from our buffer to AVFrame */
+ Y = (ctx->cur?ctx->Y2:ctx->Y1);
+ U = (ctx->cur?ctx->U2:ctx->U1);
+ V = (ctx->cur?ctx->V2:ctx->V1);
+ dst = p->data[0];
+ for (j = 0; j < h; j++) {
+ for (i = 0; i < w; i++) {
+ int y = Y[i], u = U[i >> 1], v = V[i >> 1];
+ dst[3*i+0] = av_clip_uint8(y + v);
+ dst[3*i+1] = av_clip_uint8(y);
+ dst[3*i+2] = av_clip_uint8(y + u);
+ }
+
+ /* horizontal edge extension */
+ Y[-4] = Y[-3] = Y[-2] = Y[-1] = Y[0];
+ Y[w + 3] = Y[w + 2] = Y[w + 1] = Y[w] = Y[w - 1];
+
+ /* vertical edge extension */
+ if (j == 0) {
+ memcpy(Y - 4 - 1 * ctx->y_stride, Y - 4, ctx->y_stride);
+ memcpy(Y - 4 - 2 * ctx->y_stride, Y - 4, ctx->y_stride);
+ memcpy(Y - 4 - 3 * ctx->y_stride, Y - 4, ctx->y_stride);
+ memcpy(Y - 4 - 4 * ctx->y_stride, Y - 4, ctx->y_stride);
+ } else if (j == h - 1) {
+ memcpy(Y - 4 + 1 * ctx->y_stride, Y - 4, ctx->y_stride);
+ memcpy(Y - 4 + 2 * ctx->y_stride, Y - 4, ctx->y_stride);
+ memcpy(Y - 4 + 3 * ctx->y_stride, Y - 4, ctx->y_stride);
+ memcpy(Y - 4 + 4 * ctx->y_stride, Y - 4, ctx->y_stride);
+ }
+
+ Y += ctx->y_stride;
+ if (j & 1) {
+ /* horizontal edge extension */
+ U[-2] = U[-1] = U[0];
+ V[-2] = V[-1] = V[0];
+ U[cw + 1] = U[cw] = U[cw - 1];
+ V[cw + 1] = V[cw] = V[cw - 1];
+
+ /* vertical edge extension */
+ if (j == 1) {
+ memcpy(U - 2 - 1 * ctx->uv_stride, U - 2, ctx->uv_stride);
+ memcpy(V - 2 - 1 * ctx->uv_stride, V - 2, ctx->uv_stride);
+ memcpy(U - 2 - 2 * ctx->uv_stride, U - 2, ctx->uv_stride);
+ memcpy(V - 2 - 2 * ctx->uv_stride, V - 2, ctx->uv_stride);
+ } else if (j == h - 1) {
+ memcpy(U - 2 + 1 * ctx->uv_stride, U - 2, ctx->uv_stride);
+ memcpy(V - 2 + 1 * ctx->uv_stride, V - 2, ctx->uv_stride);
+ memcpy(U - 2 + 2 * ctx->uv_stride, U - 2, ctx->uv_stride);
+ memcpy(V - 2 + 2 * ctx->uv_stride, V - 2, ctx->uv_stride);
+ }
+
+ U += ctx->uv_stride;
+ V += ctx->uv_stride;
+ }
+ dst += p->linesize[0];
+ }
+
+ return keyframe;
+}
+
+static const int tm2_stream_order[TM2_NUM_STREAMS] = {
+ TM2_C_HI, TM2_C_LO, TM2_L_HI, TM2_L_LO, TM2_UPD, TM2_MOT, TM2_TYPE
+};
+
+#define TM2_HEADER_SIZE 40
+
+static int decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ TM2Context * const l = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size & ~3;
+ AVFrame * const p = l->pic;
+ int offset = TM2_HEADER_SIZE;
+ int i, t, ret;
+
+ av_fast_padded_malloc(&l->buffer, &l->buffer_size, buf_size);
+ if (!l->buffer) {
+ av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n");
+ return AVERROR(ENOMEM);
+ }
+
+ if ((ret = ff_reget_buffer(avctx, p)) < 0)
+ return ret;
+
+ l->bdsp.bswap_buf((uint32_t *) l->buffer, (const uint32_t *) buf,
+ buf_size >> 2);
+
+ if ((ret = tm2_read_header(l, l->buffer)) < 0) {
+ return ret;
+ }
+
+ for (i = 0; i < TM2_NUM_STREAMS; i++) {
+ if (offset >= buf_size) {
+ av_log(avctx, AV_LOG_ERROR, "no space for tm2_read_stream\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ t = tm2_read_stream(l, l->buffer + offset, tm2_stream_order[i],
+ buf_size - offset);
+ if (t < 0) {
+ int j = tm2_stream_order[i];
+ if (l->tok_lens[j])
+ memset(l->tokens[j], 0, sizeof(**l->tokens) * l->tok_lens[j]);
+ return t;
+ }
+ offset += t;
+ }
+ p->key_frame = tm2_decode_blocks(l, p);
+ if (p->key_frame)
+ p->pict_type = AV_PICTURE_TYPE_I;
+ else
+ p->pict_type = AV_PICTURE_TYPE_P;
+
+ l->cur = !l->cur;
+ *got_frame = 1;
+ ret = av_frame_ref(data, l->pic);
+
+ return (ret < 0) ? ret : buf_size;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ TM2Context * const l = avctx->priv_data;
+ int i, 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");
+ return AVERROR(EINVAL);
+ }
+
+ l->avctx = avctx;
+ avctx->pix_fmt = AV_PIX_FMT_BGR24;
+
+ l->pic = av_frame_alloc();
+ if (!l->pic)
+ return AVERROR(ENOMEM);
+
+ 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;
+ }
+
+ 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_stride = w;
+ 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);
+ 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;
+
+ return 0;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ TM2Context * const l = avctx->priv_data;
+ int i;
+
+ av_free(l->last);
+ av_free(l->clast);
+ 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->buffer);
+ l->buffer_size = 0;
+
+ av_frame_free(&l->pic);
+
+ return 0;
+}
+
+AVCodec ff_truemotion2_decoder = {
+ .name = "truemotion2",
+ .long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_TRUEMOTION2,
+ .priv_data_size = sizeof(TM2Context),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/truespeech.c b/ffmpeg-2-8-12/libavcodec/truespeech.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/truespeech.c
rename to ffmpeg-2-8-12/libavcodec/truespeech.c
diff --git a/ffmpeg-2-8-11/libavcodec/truespeech_data.h b/ffmpeg-2-8-12/libavcodec/truespeech_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/truespeech_data.h
rename to ffmpeg-2-8-12/libavcodec/truespeech_data.h
diff --git a/ffmpeg-2-8-11/libavcodec/tscc.c b/ffmpeg-2-8-12/libavcodec/tscc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tscc.c
rename to ffmpeg-2-8-12/libavcodec/tscc.c
diff --git a/ffmpeg-2-8-11/libavcodec/tscc2.c b/ffmpeg-2-8-12/libavcodec/tscc2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tscc2.c
rename to ffmpeg-2-8-12/libavcodec/tscc2.c
diff --git a/ffmpeg-2-8-11/libavcodec/tscc2data.h b/ffmpeg-2-8-12/libavcodec/tscc2data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tscc2data.h
rename to ffmpeg-2-8-12/libavcodec/tscc2data.h
diff --git a/ffmpeg-2-8-11/libavcodec/tta.c b/ffmpeg-2-8-12/libavcodec/tta.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/tta.c
rename to ffmpeg-2-8-12/libavcodec/tta.c
diff --git a/ffmpeg-2-8-11/libavcodec/ttadata.c b/ffmpeg-2-8-12/libavcodec/ttadata.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ttadata.c
rename to ffmpeg-2-8-12/libavcodec/ttadata.c
diff --git a/ffmpeg-2-8-11/libavcodec/ttadata.h b/ffmpeg-2-8-12/libavcodec/ttadata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ttadata.h
rename to ffmpeg-2-8-12/libavcodec/ttadata.h
diff --git a/ffmpeg-2-8-11/libavcodec/ttadsp.c b/ffmpeg-2-8-12/libavcodec/ttadsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ttadsp.c
rename to ffmpeg-2-8-12/libavcodec/ttadsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/ttadsp.h b/ffmpeg-2-8-12/libavcodec/ttadsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ttadsp.h
rename to ffmpeg-2-8-12/libavcodec/ttadsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/ttaenc.c b/ffmpeg-2-8-12/libavcodec/ttaenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ttaenc.c
rename to ffmpeg-2-8-12/libavcodec/ttaenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/twinvq.c b/ffmpeg-2-8-12/libavcodec/twinvq.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/twinvq.c
rename to ffmpeg-2-8-12/libavcodec/twinvq.c
diff --git a/ffmpeg-2-8-11/libavcodec/twinvq.h b/ffmpeg-2-8-12/libavcodec/twinvq.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/twinvq.h
rename to ffmpeg-2-8-12/libavcodec/twinvq.h
diff --git a/ffmpeg-2-8-11/libavcodec/twinvq_data.h b/ffmpeg-2-8-12/libavcodec/twinvq_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/twinvq_data.h
rename to ffmpeg-2-8-12/libavcodec/twinvq_data.h
diff --git a/ffmpeg-2-8-11/libavcodec/twinvqdec.c b/ffmpeg-2-8-12/libavcodec/twinvqdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/twinvqdec.c
rename to ffmpeg-2-8-12/libavcodec/twinvqdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/txd.c b/ffmpeg-2-8-12/libavcodec/txd.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/txd.c
rename to ffmpeg-2-8-12/libavcodec/txd.c
diff --git a/ffmpeg-2-8-11/libavcodec/ulti.c b/ffmpeg-2-8-12/libavcodec/ulti.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ulti.c
rename to ffmpeg-2-8-12/libavcodec/ulti.c
diff --git a/ffmpeg-2-8-11/libavcodec/ulti_cb.h b/ffmpeg-2-8-12/libavcodec/ulti_cb.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ulti_cb.h
rename to ffmpeg-2-8-12/libavcodec/ulti_cb.h
diff --git a/ffmpeg-2-8-11/libavcodec/unary.h b/ffmpeg-2-8-12/libavcodec/unary.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/unary.h
rename to ffmpeg-2-8-12/libavcodec/unary.h
diff --git a/ffmpeg-2-8-11/libavcodec/utils.c b/ffmpeg-2-8-12/libavcodec/utils.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/utils.c
rename to ffmpeg-2-8-12/libavcodec/utils.c
diff --git a/ffmpeg-2-8-11/libavcodec/utvideo.c b/ffmpeg-2-8-12/libavcodec/utvideo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/utvideo.c
rename to ffmpeg-2-8-12/libavcodec/utvideo.c
diff --git a/ffmpeg-2-8-11/libavcodec/utvideo.h b/ffmpeg-2-8-12/libavcodec/utvideo.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/utvideo.h
rename to ffmpeg-2-8-12/libavcodec/utvideo.h
diff --git a/ffmpeg-2-8-11/libavcodec/utvideodec.c b/ffmpeg-2-8-12/libavcodec/utvideodec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/utvideodec.c
rename to ffmpeg-2-8-12/libavcodec/utvideodec.c
diff --git a/ffmpeg-2-8-11/libavcodec/utvideoenc.c b/ffmpeg-2-8-12/libavcodec/utvideoenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/utvideoenc.c
rename to ffmpeg-2-8-12/libavcodec/utvideoenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/v210dec.c b/ffmpeg-2-8-12/libavcodec/v210dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/v210dec.c
rename to ffmpeg-2-8-12/libavcodec/v210dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/v210dec.h b/ffmpeg-2-8-12/libavcodec/v210dec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/v210dec.h
rename to ffmpeg-2-8-12/libavcodec/v210dec.h
diff --git a/ffmpeg-2-8-11/libavcodec/v210enc.c b/ffmpeg-2-8-12/libavcodec/v210enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/v210enc.c
rename to ffmpeg-2-8-12/libavcodec/v210enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/v210enc.h b/ffmpeg-2-8-12/libavcodec/v210enc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/v210enc.h
rename to ffmpeg-2-8-12/libavcodec/v210enc.h
diff --git a/ffmpeg-2-8-11/libavcodec/v210x.c b/ffmpeg-2-8-12/libavcodec/v210x.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/v210x.c
rename to ffmpeg-2-8-12/libavcodec/v210x.c
diff --git a/ffmpeg-2-8-11/libavcodec/v308dec.c b/ffmpeg-2-8-12/libavcodec/v308dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/v308dec.c
rename to ffmpeg-2-8-12/libavcodec/v308dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/v308enc.c b/ffmpeg-2-8-12/libavcodec/v308enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/v308enc.c
rename to ffmpeg-2-8-12/libavcodec/v308enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/v408dec.c b/ffmpeg-2-8-12/libavcodec/v408dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/v408dec.c
rename to ffmpeg-2-8-12/libavcodec/v408dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/v408enc.c b/ffmpeg-2-8-12/libavcodec/v408enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/v408enc.c
rename to ffmpeg-2-8-12/libavcodec/v408enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/v410dec.c b/ffmpeg-2-8-12/libavcodec/v410dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/v410dec.c
rename to ffmpeg-2-8-12/libavcodec/v410dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/v410enc.c b/ffmpeg-2-8-12/libavcodec/v410enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/v410enc.c
rename to ffmpeg-2-8-12/libavcodec/v410enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/vaapi.c b/ffmpeg-2-8-12/libavcodec/vaapi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vaapi.c
rename to ffmpeg-2-8-12/libavcodec/vaapi.c
diff --git a/ffmpeg-2-8-11/libavcodec/vaapi.h b/ffmpeg-2-8-12/libavcodec/vaapi.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vaapi.h
rename to ffmpeg-2-8-12/libavcodec/vaapi.h
diff --git a/ffmpeg-2-8-11/libavcodec/vaapi_h264.c b/ffmpeg-2-8-12/libavcodec/vaapi_h264.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vaapi_h264.c
rename to ffmpeg-2-8-12/libavcodec/vaapi_h264.c
diff --git a/ffmpeg-2-8-11/libavcodec/vaapi_hevc.c b/ffmpeg-2-8-12/libavcodec/vaapi_hevc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vaapi_hevc.c
rename to ffmpeg-2-8-12/libavcodec/vaapi_hevc.c
diff --git a/ffmpeg-2-8-11/libavcodec/vaapi_internal.h b/ffmpeg-2-8-12/libavcodec/vaapi_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vaapi_internal.h
rename to ffmpeg-2-8-12/libavcodec/vaapi_internal.h
diff --git a/ffmpeg-2-8-11/libavcodec/vaapi_mpeg2.c b/ffmpeg-2-8-12/libavcodec/vaapi_mpeg2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vaapi_mpeg2.c
rename to ffmpeg-2-8-12/libavcodec/vaapi_mpeg2.c
diff --git a/ffmpeg-2-8-11/libavcodec/vaapi_mpeg4.c b/ffmpeg-2-8-12/libavcodec/vaapi_mpeg4.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vaapi_mpeg4.c
rename to ffmpeg-2-8-12/libavcodec/vaapi_mpeg4.c
diff --git a/ffmpeg-2-8-11/libavcodec/vaapi_vc1.c b/ffmpeg-2-8-12/libavcodec/vaapi_vc1.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vaapi_vc1.c
rename to ffmpeg-2-8-12/libavcodec/vaapi_vc1.c
diff --git a/ffmpeg-2-8-11/libavcodec/vb.c b/ffmpeg-2-8-12/libavcodec/vb.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vb.c
rename to ffmpeg-2-8-12/libavcodec/vb.c
diff --git a/ffmpeg-2-8-11/libavcodec/vble.c b/ffmpeg-2-8-12/libavcodec/vble.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vble.c
rename to ffmpeg-2-8-12/libavcodec/vble.c
diff --git a/ffmpeg-2-8-11/libavcodec/vc1.c b/ffmpeg-2-8-12/libavcodec/vc1.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1.c
rename to ffmpeg-2-8-12/libavcodec/vc1.c
diff --git a/ffmpeg-2-8-11/libavcodec/vc1.h b/ffmpeg-2-8-12/libavcodec/vc1.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1.h
rename to ffmpeg-2-8-12/libavcodec/vc1.h
diff --git a/ffmpeg-2-8-11/libavcodec/vc1_block.c b/ffmpeg-2-8-12/libavcodec/vc1_block.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1_block.c
rename to ffmpeg-2-8-12/libavcodec/vc1_block.c
diff --git a/ffmpeg-2-8-11/libavcodec/vc1_common.h b/ffmpeg-2-8-12/libavcodec/vc1_common.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1_common.h
rename to ffmpeg-2-8-12/libavcodec/vc1_common.h
diff --git a/ffmpeg-2-8-11/libavcodec/vc1_loopfilter.c b/ffmpeg-2-8-12/libavcodec/vc1_loopfilter.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1_loopfilter.c
rename to ffmpeg-2-8-12/libavcodec/vc1_loopfilter.c
diff --git a/ffmpeg-2-8-11/libavcodec/vc1_mc.c b/ffmpeg-2-8-12/libavcodec/vc1_mc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1_mc.c
rename to ffmpeg-2-8-12/libavcodec/vc1_mc.c
diff --git a/ffmpeg-2-8-11/libavcodec/vc1_parser.c b/ffmpeg-2-8-12/libavcodec/vc1_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1_parser.c
rename to ffmpeg-2-8-12/libavcodec/vc1_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/vc1_pred.c b/ffmpeg-2-8-12/libavcodec/vc1_pred.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1_pred.c
rename to ffmpeg-2-8-12/libavcodec/vc1_pred.c
diff --git a/ffmpeg-2-8-11/libavcodec/vc1_pred.h b/ffmpeg-2-8-12/libavcodec/vc1_pred.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1_pred.h
rename to ffmpeg-2-8-12/libavcodec/vc1_pred.h
diff --git a/ffmpeg-2-8-11/libavcodec/vc1acdata.h b/ffmpeg-2-8-12/libavcodec/vc1acdata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1acdata.h
rename to ffmpeg-2-8-12/libavcodec/vc1acdata.h
diff --git a/ffmpeg-2-8-11/libavcodec/vc1data.c b/ffmpeg-2-8-12/libavcodec/vc1data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1data.c
rename to ffmpeg-2-8-12/libavcodec/vc1data.c
diff --git a/ffmpeg-2-8-11/libavcodec/vc1data.h b/ffmpeg-2-8-12/libavcodec/vc1data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1data.h
rename to ffmpeg-2-8-12/libavcodec/vc1data.h
diff --git a/ffmpeg-2-8-11/libavcodec/vc1dec.c b/ffmpeg-2-8-12/libavcodec/vc1dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1dec.c
rename to ffmpeg-2-8-12/libavcodec/vc1dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/vc1dsp.c b/ffmpeg-2-8-12/libavcodec/vc1dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1dsp.c
rename to ffmpeg-2-8-12/libavcodec/vc1dsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/vc1dsp.h b/ffmpeg-2-8-12/libavcodec/vc1dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vc1dsp.h
rename to ffmpeg-2-8-12/libavcodec/vc1dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/vcr1.c b/ffmpeg-2-8-12/libavcodec/vcr1.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vcr1.c
rename to ffmpeg-2-8-12/libavcodec/vcr1.c
diff --git a/ffmpeg-2-8-11/libavcodec/vda.c b/ffmpeg-2-8-12/libavcodec/vda.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vda.c
rename to ffmpeg-2-8-12/libavcodec/vda.c
diff --git a/ffmpeg-2-8-11/libavcodec/vda.h b/ffmpeg-2-8-12/libavcodec/vda.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vda.h
rename to ffmpeg-2-8-12/libavcodec/vda.h
diff --git a/ffmpeg-2-8-11/libavcodec/vda_h264.c b/ffmpeg-2-8-12/libavcodec/vda_h264.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vda_h264.c
rename to ffmpeg-2-8-12/libavcodec/vda_h264.c
diff --git a/ffmpeg-2-8-11/libavcodec/vda_h264_dec.c b/ffmpeg-2-8-12/libavcodec/vda_h264_dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vda_h264_dec.c
rename to ffmpeg-2-8-12/libavcodec/vda_h264_dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/vda_vt_internal.h b/ffmpeg-2-8-12/libavcodec/vda_vt_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vda_vt_internal.h
rename to ffmpeg-2-8-12/libavcodec/vda_vt_internal.h
diff --git a/ffmpeg-2-8-11/libavcodec/vdpau.c b/ffmpeg-2-8-12/libavcodec/vdpau.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vdpau.c
rename to ffmpeg-2-8-12/libavcodec/vdpau.c
diff --git a/ffmpeg-2-8-11/libavcodec/vdpau.h b/ffmpeg-2-8-12/libavcodec/vdpau.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vdpau.h
rename to ffmpeg-2-8-12/libavcodec/vdpau.h
diff --git a/ffmpeg-2-8-11/libavcodec/vdpau_compat.h b/ffmpeg-2-8-12/libavcodec/vdpau_compat.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vdpau_compat.h
rename to ffmpeg-2-8-12/libavcodec/vdpau_compat.h
diff --git a/ffmpeg-2-8-11/libavcodec/vdpau_h264.c b/ffmpeg-2-8-12/libavcodec/vdpau_h264.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vdpau_h264.c
rename to ffmpeg-2-8-12/libavcodec/vdpau_h264.c
diff --git a/ffmpeg-2-8-12/libavcodec/vdpau_hevc.c b/ffmpeg-2-8-12/libavcodec/vdpau_hevc.c
new file mode 100644
index 0000000..3223f5e
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/vdpau_hevc.c
@@ -0,0 +1,437 @@
+/*
+ * MPEG-H Part 2 / HEVC / H.265 HW decode acceleration through VDPAU
+ *
+ * Copyright (c) 2013 Philip Langdale
+ *
+ * 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 <vdpau/vdpau.h>
+
+#include "avcodec.h"
+#include "internal.h"
+#include "hevc.h"
+#include "vdpau.h"
+#include "vdpau_internal.h"
+
+static int vdpau_hevc_start_frame(AVCodecContext *avctx,
+ const uint8_t *buffer, uint32_t size)
+{
+ HEVCContext *h = avctx->priv_data;
+ HEVCFrame *pic = h->ref;
+ struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private;
+
+ VdpPictureInfoHEVC *info = &pic_ctx->info.hevc;
+
+ const HEVCSPS *sps = h->ps.sps;
+ const HEVCPPS *pps = h->ps.pps;
+ const SliceHeader *sh = &h->sh;
+ const ScalingList *sl = pps->scaling_list_data_present_flag ?
+ &pps->scaling_list : &sps->scaling_list;
+
+ /* init VdpPictureInfoHEVC */
+
+ /* SPS */
+ info->chroma_format_idc = sps->chroma_format_idc;
+ info->separate_colour_plane_flag = sps->separate_colour_plane_flag;
+ info->pic_width_in_luma_samples = sps->width;
+ info->pic_height_in_luma_samples = sps->height;
+ info->bit_depth_luma_minus8 = sps->bit_depth - 8;
+ info->bit_depth_chroma_minus8 = sps->bit_depth - 8;
+ info->log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4;
+ /** Provides the value corresponding to the nuh_temporal_id of the frame
+ to be decoded. */
+ info->sps_max_dec_pic_buffering_minus1 = sps->temporal_layer[sps->max_sub_layers - 1].max_dec_pic_buffering - 1;
+ info->log2_min_luma_coding_block_size_minus3 = sps->log2_min_cb_size - 3;
+ info->log2_diff_max_min_luma_coding_block_size = sps->log2_diff_max_min_coding_block_size;
+ info->log2_min_transform_block_size_minus2 = sps->log2_min_tb_size - 2;
+ info->log2_diff_max_min_transform_block_size = sps->log2_max_trafo_size - sps->log2_min_tb_size;
+ info->max_transform_hierarchy_depth_inter = sps->max_transform_hierarchy_depth_inter;
+ info->max_transform_hierarchy_depth_intra = sps->max_transform_hierarchy_depth_intra;
+ info->scaling_list_enabled_flag = sps->scaling_list_enable_flag;
+ /** Scaling lists, in diagonal order, to be used for this frame. */
+ for (size_t i = 0; i < 6; i++) {
+ for (size_t j = 0; j < 16; j++) {
+ /** Scaling List for 4x4 quantization matrix,
+ indexed as ScalingList4x4[matrixId][i]. */
+ uint8_t pos = 4 * ff_hevc_diag_scan4x4_y[j] + ff_hevc_diag_scan4x4_x[j];
+ info->ScalingList4x4[i][j] = sl->sl[0][i][pos];
+ }
+ for (size_t j = 0; j < 64; j++) {
+ uint8_t pos = 8 * ff_hevc_diag_scan8x8_y[j] + ff_hevc_diag_scan8x8_x[j];
+ /** Scaling List for 8x8 quantization matrix,
+ indexed as ScalingList8x8[matrixId][i]. */
+ info->ScalingList8x8[i][j] = sl->sl[1][i][pos];
+ /** Scaling List for 16x16 quantization matrix,
+ indexed as ScalingList16x16[matrixId][i]. */
+ info->ScalingList16x16[i][j] = sl->sl[2][i][pos];
+ if (i < 2) {
+ /** Scaling List for 32x32 quantization matrix,
+ indexed as ScalingList32x32[matrixId][i]. */
+ info->ScalingList32x32[i][j] = sl->sl[3][i * 3][pos];
+ }
+ }
+ /** Scaling List DC Coefficients for 16x16,
+ indexed as ScalingListDCCoeff16x16[matrixId]. */
+ info->ScalingListDCCoeff16x16[i] = sl->sl_dc[0][i];
+ if (i < 2) {
+ /** Scaling List DC Coefficients for 32x32,
+ indexed as ScalingListDCCoeff32x32[matrixId]. */
+ info->ScalingListDCCoeff32x32[i] = sl->sl_dc[1][i * 3];
+ }
+ }
+ info->amp_enabled_flag = sps->amp_enabled_flag;
+ info->sample_adaptive_offset_enabled_flag = sps->sao_enabled;
+ info->pcm_enabled_flag = sps->pcm_enabled_flag;
+ if (info->pcm_enabled_flag) {
+ /** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
+ info->pcm_sample_bit_depth_luma_minus1 = sps->pcm.bit_depth - 1;
+ /** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
+ info->pcm_sample_bit_depth_chroma_minus1 = sps->pcm.bit_depth_chroma - 1;
+ /** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
+ info->log2_min_pcm_luma_coding_block_size_minus3 = sps->pcm.log2_min_pcm_cb_size - 3;
+ /** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
+ info->log2_diff_max_min_pcm_luma_coding_block_size = sps->pcm.log2_max_pcm_cb_size - sps->pcm.log2_min_pcm_cb_size;
+ /** Only needs to be set if pcm_enabled_flag is set. Ignored otherwise. */
+ info->pcm_loop_filter_disabled_flag = sps->pcm.loop_filter_disable_flag;
+ }
+ /** Per spec, when zero, assume short_term_ref_pic_set_sps_flag
+ is also zero. */
+ info->num_short_term_ref_pic_sets = sps->nb_st_rps;
+ info->long_term_ref_pics_present_flag = sps->long_term_ref_pics_present_flag;
+ /** Only needed if long_term_ref_pics_present_flag is set. Ignored
+ otherwise. */
+ info->num_long_term_ref_pics_sps = sps->num_long_term_ref_pics_sps;
+ info->sps_temporal_mvp_enabled_flag = sps->sps_temporal_mvp_enabled_flag;
+ info->strong_intra_smoothing_enabled_flag = sps->sps_strong_intra_smoothing_enable_flag;
+ /** @} */
+
+ /** \name HEVC Picture Parameter Set
+ *
+ * Copies of the HEVC Picture Parameter Set bitstream fields.
+ * @{ */
+ info->dependent_slice_segments_enabled_flag = pps->dependent_slice_segments_enabled_flag;
+ info->output_flag_present_flag = pps->output_flag_present_flag;
+ info->num_extra_slice_header_bits = pps->num_extra_slice_header_bits;
+ info->sign_data_hiding_enabled_flag = pps->sign_data_hiding_flag;
+ info->cabac_init_present_flag = pps->cabac_init_present_flag;
+ info->num_ref_idx_l0_default_active_minus1 = pps->num_ref_idx_l0_default_active - 1;
+ info->num_ref_idx_l1_default_active_minus1 = pps->num_ref_idx_l1_default_active - 1;
+ info->init_qp_minus26 = pps->pic_init_qp_minus26;
+ info->constrained_intra_pred_flag = pps->constrained_intra_pred_flag;
+ info->transform_skip_enabled_flag = pps->transform_skip_enabled_flag;
+ info->cu_qp_delta_enabled_flag = pps->cu_qp_delta_enabled_flag;
+ /** Only needed if cu_qp_delta_enabled_flag is set. Ignored otherwise. */
+ info->diff_cu_qp_delta_depth = pps->diff_cu_qp_delta_depth;
+ info->pps_cb_qp_offset = pps->cb_qp_offset;
+ info->pps_cr_qp_offset = pps->cr_qp_offset;
+ info->pps_slice_chroma_qp_offsets_present_flag = pps->pic_slice_level_chroma_qp_offsets_present_flag;
+ info->weighted_pred_flag = pps->weighted_pred_flag;
+ info->weighted_bipred_flag = pps->weighted_bipred_flag;
+ info->transquant_bypass_enabled_flag = pps->transquant_bypass_enable_flag;
+ info->tiles_enabled_flag = pps->tiles_enabled_flag;
+ info->entropy_coding_sync_enabled_flag = pps->entropy_coding_sync_enabled_flag;
+ if (info->tiles_enabled_flag) {
+ /** Only valid if tiles_enabled_flag is set. Ignored otherwise. */
+ info->num_tile_columns_minus1 = pps->num_tile_columns - 1;
+ /** Only valid if tiles_enabled_flag is set. Ignored otherwise. */
+ info->num_tile_rows_minus1 = pps->num_tile_rows - 1;
+ /** Only valid if tiles_enabled_flag is set. Ignored otherwise. */
+ info->uniform_spacing_flag = pps->uniform_spacing_flag;
+ /** Only need to set 0..num_tile_columns_minus1. The struct
+ definition reserves up to the maximum of 20. Invalid values are
+ ignored. */
+ for (ssize_t i = 0; i < pps->num_tile_columns; i++) {
+ info->column_width_minus1[i] = pps->column_width[i] - 1;
+ }
+ /** Only need to set 0..num_tile_rows_minus1. The struct
+ definition reserves up to the maximum of 22. Invalid values are
+ ignored.*/
+ for (ssize_t i = 0; i < pps->num_tile_rows; i++) {
+ info->row_height_minus1[i] = pps->row_height[i] - 1;
+ }
+ /** Only needed if tiles_enabled_flag is set. Invalid values are
+ ignored. */
+ info->loop_filter_across_tiles_enabled_flag = pps->loop_filter_across_tiles_enabled_flag;
+ }
+ info->pps_loop_filter_across_slices_enabled_flag = pps->seq_loop_filter_across_slices_enabled_flag;
+ info->deblocking_filter_control_present_flag = pps->deblocking_filter_control_present_flag;
+ /** Only valid if deblocking_filter_control_present_flag is set. Ignored
+ otherwise. */
+ info->deblocking_filter_override_enabled_flag = pps->deblocking_filter_override_enabled_flag;
+ /** Only valid if deblocking_filter_control_present_flag is set. Ignored
+ otherwise. */
+ info->pps_deblocking_filter_disabled_flag = pps->disable_dbf;
+ /** Only valid if deblocking_filter_control_present_flag is set and
+ pps_deblocking_filter_disabled_flag is not set. Ignored otherwise.*/
+ info->pps_beta_offset_div2 = pps->beta_offset / 2;
+ /** Only valid if deblocking_filter_control_present_flag is set and
+ pps_deblocking_filter_disabled_flag is not set. Ignored otherwise. */
+ info->pps_tc_offset_div2 = pps->tc_offset / 2;
+ info->lists_modification_present_flag = pps->lists_modification_present_flag;
+ info->log2_parallel_merge_level_minus2 = pps->log2_parallel_merge_level - 2;
+ info->slice_segment_header_extension_present_flag = pps->slice_header_extension_present_flag;
+
+ /** \name HEVC Slice Segment Header
+ *
+ * Copies of the HEVC Slice Segment Header bitstream fields and calculated
+ * values detailed in the specification.
+ * @{ */
+ /** Set to 1 if nal_unit_type is equal to IDR_W_RADL or IDR_N_LP.
+ Set to zero otherwise. */
+ info->IDRPicFlag = IS_IDR(h);
+ /** Set to 1 if nal_unit_type in the range of BLA_W_LP to
+ RSV_IRAP_VCL23, inclusive. Set to zero otherwise.*/
+ info->RAPPicFlag = IS_IRAP(h);
+ /** See section 7.4.7.1 of the specification. */
+ info->CurrRpsIdx = sps->nb_st_rps;
+ if (sh->short_term_ref_pic_set_sps_flag == 1) {
+ for (size_t i = 0; i < sps->nb_st_rps; i++) {
+ if (sh->short_term_rps == &sps->st_rps[i]) {
+ info->CurrRpsIdx = i;
+ break;
+ }
+ }
+ }
+ /** See section 7.4.7.2 of the specification. */
+ info->NumPocTotalCurr = ff_hevc_frame_nb_refs(h);
+ if (sh->short_term_ref_pic_set_sps_flag == 0 && sh->short_term_rps) {
+ /** Corresponds to specification field, NumDeltaPocs[RefRpsIdx].
+ Only applicable when short_term_ref_pic_set_sps_flag == 0.
+ Implementations will ignore this value in other cases. See 7.4.8. */
+ info->NumDeltaPocsOfRefRpsIdx = sh->short_term_rps->rps_idx_num_delta_pocs;
+ }
+ /** Section 7.6.3.1 of the H.265/HEVC Specification defines the syntax of
+ the slice_segment_header. This header contains information that
+ some VDPAU implementations may choose to skip. The VDPAU API
+ requires client applications to track the number of bits used in the
+ slice header for structures associated with short term and long term
+ reference pictures. First, VDPAU requires the number of bits used by
+ the short_term_ref_pic_set array in the slice_segment_header. */
+ info->NumShortTermPictureSliceHeaderBits = sh->short_term_ref_pic_set_size;
+ /** Second, VDPAU requires the number of bits used for long term reference
+ pictures in the slice_segment_header. This is equal to the number
+ of bits used for the contents of the block beginning with
+ "if(long_term_ref_pics_present_flag)". */
+ info->NumLongTermPictureSliceHeaderBits = sh->long_term_ref_pic_set_size;
+ /** @} */
+
+ /** Slice Decoding Process - Picture Order Count */
+ /** The value of PicOrderCntVal of the picture in the access unit
+ containing the SEI message. The picture being decoded. */
+ info->CurrPicOrderCntVal = h->poc;
+
+ /** Slice Decoding Process - Reference Picture Sets */
+ for (size_t i = 0; i < 16; i++) {
+ info->RefPics[i] = VDP_INVALID_HANDLE;
+ info->PicOrderCntVal[i] = 0;
+ info->IsLongTerm[i] = 0;
+ }
+ for (size_t i = 0, j = 0; i < FF_ARRAY_ELEMS(h->DPB); i++) {
+ const HEVCFrame *frame = &h->DPB[i];
+ if (frame != h->ref && (frame->flags & (HEVC_FRAME_FLAG_LONG_REF |
+ HEVC_FRAME_FLAG_SHORT_REF))) {
+ if (j > 15) {
+ av_log(avctx, AV_LOG_WARNING,
+ "VDPAU only supports up to 16 references in the DPB. "
+ "This frame may not be decoded correctly.\n");
+ break;
+ }
+ /** Array of video reference surfaces.
+ Set any unused positions to VDP_INVALID_HANDLE. */
+ info->RefPics[j] = ff_vdpau_get_surface_id(frame->frame);
+ /** Array of picture order counts. These correspond to positions
+ in the RefPics array. */
+ info->PicOrderCntVal[j] = frame->poc;
+ /** Array used to specify whether a particular RefPic is
+ a long term reference. A value of "1" indicates a long-term
+ reference. */
+ // XXX: Setting this caused glitches in the nvidia implementation
+ // Always setting it to zero, produces correct results
+ //info->IsLongTerm[j] = frame->flags & HEVC_FRAME_FLAG_LONG_REF;
+ info->IsLongTerm[j] = 0;
+ j++;
+ }
+ }
+ /** Copy of specification field, see Section 8.3.2 of the
+ H.265/HEVC Specification. */
+ info->NumPocStCurrBefore = h->rps[ST_CURR_BEF].nb_refs;
+ if (info->NumPocStCurrBefore > 8) {
+ av_log(avctx, AV_LOG_WARNING,
+ "VDPAU only supports up to 8 references in StCurrBefore. "
+ "This frame may not be decoded correctly.\n");
+ info->NumPocStCurrBefore = 8;
+ }
+ /** Copy of specification field, see Section 8.3.2 of the
+ H.265/HEVC Specification. */
+ info->NumPocStCurrAfter = h->rps[ST_CURR_AFT].nb_refs;
+ if (info->NumPocStCurrAfter > 8) {
+ av_log(avctx, AV_LOG_WARNING,
+ "VDPAU only supports up to 8 references in StCurrAfter. "
+ "This frame may not be decoded correctly.\n");
+ info->NumPocStCurrAfter = 8;
+ }
+ /** Copy of specification field, see Section 8.3.2 of the
+ H.265/HEVC Specification. */
+ info->NumPocLtCurr = h->rps[LT_CURR].nb_refs;
+ if (info->NumPocLtCurr > 8) {
+ av_log(avctx, AV_LOG_WARNING,
+ "VDPAU only supports up to 8 references in LtCurr. "
+ "This frame may not be decoded correctly.\n");
+ info->NumPocLtCurr = 8;
+ }
+ /** Reference Picture Set list, one of the short-term RPS. These
+ correspond to positions in the RefPics array. */
+ for (ssize_t i = 0, j = 0; i < h->rps[ST_CURR_BEF].nb_refs; i++) {
+ HEVCFrame *frame = h->rps[ST_CURR_BEF].ref[i];
+ if (frame) {
+ uint8_t found = 0;
+ uintptr_t id = ff_vdpau_get_surface_id(frame->frame);
+ for (size_t k = 0; k < 16; k++) {
+ if (id == info->RefPics[k]) {
+ info->RefPicSetStCurrBefore[j] = k;
+ j++;
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ av_log(avctx, AV_LOG_WARNING, "missing surface: %p\n",
+ (void *)id);
+ }
+ } else {
+ av_log(avctx, AV_LOG_WARNING, "missing STR Before frame: %zd\n", i);
+ }
+ }
+ /** Reference Picture Set list, one of the short-term RPS. These
+ correspond to positions in the RefPics array. */
+ for (ssize_t i = 0, j = 0; i < h->rps[ST_CURR_AFT].nb_refs; i++) {
+ HEVCFrame *frame = h->rps[ST_CURR_AFT].ref[i];
+ if (frame) {
+ uint8_t found = 0;
+ uintptr_t id = ff_vdpau_get_surface_id(frame->frame);
+ for (size_t k = 0; k < 16; k++) {
+ if (id == info->RefPics[k]) {
+ info->RefPicSetStCurrAfter[j] = k;
+ j++;
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ av_log(avctx, AV_LOG_WARNING, "missing surface: %p\n",
+ (void *)id);
+ }
+ } else {
+ av_log(avctx, AV_LOG_WARNING, "missing STR After frame: %zd\n", i);
+ }
+ }
+ /** Reference Picture Set list, one of the long-term RPS. These
+ correspond to positions in the RefPics array. */
+ for (ssize_t i = 0, j = 0; i < h->rps[LT_CURR].nb_refs; i++) {
+ HEVCFrame *frame = h->rps[LT_CURR].ref[i];
+ if (frame) {
+ uint8_t found = 0;
+ uintptr_t id = ff_vdpau_get_surface_id(frame->frame);
+ for (size_t k = 0; k < 16; k++) {
+ if (id == info->RefPics[k]) {
+ info->RefPicSetLtCurr[j] = k;
+ j++;
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ av_log(avctx, AV_LOG_WARNING, "missing surface: %p\n",
+ (void *)id);
+ }
+ } else {
+ av_log(avctx, AV_LOG_WARNING, "missing LTR frame: %zd\n", i);
+ }
+ }
+
+ return ff_vdpau_common_start_frame(pic_ctx, buffer, size);
+}
+
+static const uint8_t start_code_prefix[3] = { 0x00, 0x00, 0x01 };
+
+static int vdpau_hevc_decode_slice(AVCodecContext *avctx,
+ const uint8_t *buffer, uint32_t size)
+{
+ HEVCContext *h = avctx->priv_data;
+ struct vdpau_picture_context *pic_ctx = h->ref->hwaccel_picture_private;
+ int val;
+
+ val = ff_vdpau_add_buffer(pic_ctx, start_code_prefix, 3);
+ if (val)
+ return val;
+
+ val = ff_vdpau_add_buffer(pic_ctx, buffer, size);
+ if (val)
+ return val;
+
+ return 0;
+}
+
+static int vdpau_hevc_end_frame(AVCodecContext *avctx)
+{
+ HEVCContext *h = avctx->priv_data;
+ struct vdpau_picture_context *pic_ctx = h->ref->hwaccel_picture_private;
+ int val;
+
+ val = ff_vdpau_common_end_frame(avctx, h->ref->frame, pic_ctx);
+ if (val < 0)
+ return val;
+
+ return 0;
+}
+
+static int vdpau_hevc_init(AVCodecContext *avctx)
+{
+ VdpDecoderProfile profile;
+ uint32_t level = avctx->level;
+
+ switch (avctx->profile) {
+ case FF_PROFILE_HEVC_MAIN:
+ profile = VDP_DECODER_PROFILE_HEVC_MAIN;
+ break;
+ case FF_PROFILE_HEVC_MAIN_10:
+ profile = VDP_DECODER_PROFILE_HEVC_MAIN_10;
+ break;
+ case FF_PROFILE_HEVC_MAIN_STILL_PICTURE:
+ profile = VDP_DECODER_PROFILE_HEVC_MAIN_STILL;
+ break;
+ default:
+ return AVERROR(ENOTSUP);
+ }
+
+ return ff_vdpau_common_init(avctx, profile, level);
+}
+
+AVHWAccel ff_hevc_vdpau_hwaccel = {
+ .name = "hevc_vdpau",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_HEVC,
+ .pix_fmt = AV_PIX_FMT_VDPAU,
+ .start_frame = vdpau_hevc_start_frame,
+ .end_frame = vdpau_hevc_end_frame,
+ .decode_slice = vdpau_hevc_decode_slice,
+ .frame_priv_data_size = sizeof(struct vdpau_picture_context),
+ .init = vdpau_hevc_init,
+ .uninit = ff_vdpau_common_uninit,
+ .priv_data_size = sizeof(VDPAUContext),
+};
diff --git a/ffmpeg-2-8-11/libavcodec/vdpau_internal.h b/ffmpeg-2-8-12/libavcodec/vdpau_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vdpau_internal.h
rename to ffmpeg-2-8-12/libavcodec/vdpau_internal.h
diff --git a/ffmpeg-2-8-11/libavcodec/vdpau_mpeg12.c b/ffmpeg-2-8-12/libavcodec/vdpau_mpeg12.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vdpau_mpeg12.c
rename to ffmpeg-2-8-12/libavcodec/vdpau_mpeg12.c
diff --git a/ffmpeg-2-8-11/libavcodec/vdpau_mpeg4.c b/ffmpeg-2-8-12/libavcodec/vdpau_mpeg4.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vdpau_mpeg4.c
rename to ffmpeg-2-8-12/libavcodec/vdpau_mpeg4.c
diff --git a/ffmpeg-2-8-11/libavcodec/vdpau_vc1.c b/ffmpeg-2-8-12/libavcodec/vdpau_vc1.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vdpau_vc1.c
rename to ffmpeg-2-8-12/libavcodec/vdpau_vc1.c
diff --git a/ffmpeg-2-8-11/libavcodec/version.h b/ffmpeg-2-8-12/libavcodec/version.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/version.h
rename to ffmpeg-2-8-12/libavcodec/version.h
diff --git a/ffmpeg-2-8-11/libavcodec/videodsp.c b/ffmpeg-2-8-12/libavcodec/videodsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/videodsp.c
rename to ffmpeg-2-8-12/libavcodec/videodsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/videodsp.h b/ffmpeg-2-8-12/libavcodec/videodsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/videodsp.h
rename to ffmpeg-2-8-12/libavcodec/videodsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/videodsp_template.c b/ffmpeg-2-8-12/libavcodec/videodsp_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/videodsp_template.c
rename to ffmpeg-2-8-12/libavcodec/videodsp_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/videotoolbox.c b/ffmpeg-2-8-12/libavcodec/videotoolbox.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/videotoolbox.c
rename to ffmpeg-2-8-12/libavcodec/videotoolbox.c
diff --git a/ffmpeg-2-8-11/libavcodec/videotoolbox.h b/ffmpeg-2-8-12/libavcodec/videotoolbox.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/videotoolbox.h
rename to ffmpeg-2-8-12/libavcodec/videotoolbox.h
diff --git a/ffmpeg-2-8-11/libavcodec/vima.c b/ffmpeg-2-8-12/libavcodec/vima.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vima.c
rename to ffmpeg-2-8-12/libavcodec/vima.c
diff --git a/ffmpeg-2-8-11/libavcodec/vmdaudio.c b/ffmpeg-2-8-12/libavcodec/vmdaudio.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vmdaudio.c
rename to ffmpeg-2-8-12/libavcodec/vmdaudio.c
diff --git a/ffmpeg-2-8-11/libavcodec/vmdvideo.c b/ffmpeg-2-8-12/libavcodec/vmdvideo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vmdvideo.c
rename to ffmpeg-2-8-12/libavcodec/vmdvideo.c
diff --git a/ffmpeg-2-8-12/libavcodec/vmnc.c b/ffmpeg-2-8-12/libavcodec/vmnc.c
new file mode 100644
index 0000000..dfabfd3
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/vmnc.c
@@ -0,0 +1,575 @@
+/*
+ * VMware Screen Codec (VMnc) decoder
+ * Copyright (c) 2006 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
+ */
+
+/**
+ * @file
+ * VMware Screen Codec (VMnc) decoder
+ * As Alex Beregszaszi discovered, this is effectively RFB data dump
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "libavutil/common.h"
+#include "libavutil/intreadwrite.h"
+#include "avcodec.h"
+#include "internal.h"
+#include "bytestream.h"
+
+enum EncTypes {
+ MAGIC_WMVd = 0x574D5664,
+ MAGIC_WMVe,
+ MAGIC_WMVf,
+ MAGIC_WMVg,
+ MAGIC_WMVh,
+ MAGIC_WMVi,
+ MAGIC_WMVj
+};
+
+enum HexTile_Flags {
+ HT_RAW = 1, // tile is raw
+ HT_BKG = 2, // background color is present
+ HT_FG = 4, // foreground color is present
+ HT_SUB = 8, // subrects are present
+ HT_CLR = 16 // each subrect has own color
+};
+
+/*
+ * Decoder context
+ */
+typedef struct VmncContext {
+ AVCodecContext *avctx;
+ AVFrame *pic;
+
+ int bpp;
+ int bpp2;
+ int bigendian;
+ uint8_t pal[768];
+ int width, height;
+ GetByteContext gb;
+
+ /* cursor data */
+ int cur_w, cur_h;
+ int cur_x, cur_y;
+ int cur_hx, cur_hy;
+ uint8_t *curbits, *curmask;
+ uint8_t *screendta;
+} VmncContext;
+
+/* read pixel value from stream */
+static av_always_inline int vmnc_get_pixel(GetByteContext *gb, int bpp, int be)
+{
+ switch (bpp * 2 + be) {
+ case 2:
+ case 3:
+ return bytestream2_get_byte(gb);
+ case 4:
+ return bytestream2_get_le16(gb);
+ case 5:
+ return bytestream2_get_be16(gb);
+ case 8:
+ return bytestream2_get_le32(gb);
+ case 9:
+ return bytestream2_get_be32(gb);
+ default: return 0;
+ }
+}
+
+static void load_cursor(VmncContext *c)
+{
+ int i, j, p;
+ const int bpp = c->bpp2;
+ uint8_t *dst8 = c->curbits;
+ uint16_t *dst16 = (uint16_t *)c->curbits;
+ uint32_t *dst32 = (uint32_t *)c->curbits;
+
+ for (j = 0; j < c->cur_h; j++) {
+ for (i = 0; i < c->cur_w; i++) {
+ p = vmnc_get_pixel(&c->gb, bpp, c->bigendian);
+ if (bpp == 1)
+ *dst8++ = p;
+ if (bpp == 2)
+ *dst16++ = p;
+ if (bpp == 4)
+ *dst32++ = p;
+ }
+ }
+ dst8 = c->curmask;
+ dst16 = (uint16_t*)c->curmask;
+ dst32 = (uint32_t*)c->curmask;
+ for (j = 0; j < c->cur_h; j++) {
+ for (i = 0; i < c->cur_w; i++) {
+ p = vmnc_get_pixel(&c->gb, bpp, c->bigendian);
+ if (bpp == 1)
+ *dst8++ = p;
+ if (bpp == 2)
+ *dst16++ = p;
+ if (bpp == 4)
+ *dst32++ = p;
+ }
+ }
+}
+
+static void put_cursor(uint8_t *dst, int stride, VmncContext *c, int dx, int dy)
+{
+ int i, j;
+ int w, h, x, y;
+ w = c->cur_w;
+ if (c->width < c->cur_x + c->cur_w)
+ w = c->width - c->cur_x;
+ h = c->cur_h;
+ if (c->height < c->cur_y + c->cur_h)
+ h = c->height - c->cur_y;
+ x = c->cur_x;
+ y = c->cur_y;
+ if (x < 0) {
+ w += x;
+ x = 0;
+ }
+ if (y < 0) {
+ h += y;
+ y = 0;
+ }
+
+ if ((w < 1) || (h < 1))
+ return;
+ dst += x * c->bpp2 + y * stride;
+
+ if (c->bpp2 == 1) {
+ uint8_t *cd = c->curbits, *msk = c->curmask;
+ for (j = 0; j < h; j++) {
+ for (i = 0; i < w; i++)
+ dst[i] = (dst[i] & cd[i]) ^ msk[i];
+ msk += c->cur_w;
+ cd += c->cur_w;
+ dst += stride;
+ }
+ } else if (c->bpp2 == 2) {
+ uint16_t *cd = (uint16_t*)c->curbits, *msk = (uint16_t*)c->curmask;
+ uint16_t *dst2;
+ for (j = 0; j < h; j++) {
+ dst2 = (uint16_t*)dst;
+ for (i = 0; i < w; i++)
+ dst2[i] = (dst2[i] & cd[i]) ^ msk[i];
+ msk += c->cur_w;
+ cd += c->cur_w;
+ dst += stride;
+ }
+ } else if (c->bpp2 == 4) {
+ uint32_t *cd = (uint32_t*)c->curbits, *msk = (uint32_t*)c->curmask;
+ uint32_t *dst2;
+ for (j = 0; j < h; j++) {
+ dst2 = (uint32_t*)dst;
+ for (i = 0; i < w; i++)
+ dst2[i] = (dst2[i] & cd[i]) ^ msk[i];
+ msk += c->cur_w;
+ cd += c->cur_w;
+ dst += stride;
+ }
+ }
+}
+
+/* fill rectangle with given color */
+static av_always_inline void paint_rect(uint8_t *dst, int dx, int dy,
+ int w, int h, int color,
+ int bpp, int stride)
+{
+ int i, j;
+ dst += dx * bpp + dy * stride;
+ if (bpp == 1) {
+ for (j = 0; j < h; j++) {
+ memset(dst, color, w);
+ dst += stride;
+ }
+ } else if (bpp == 2) {
+ uint16_t *dst2;
+ for (j = 0; j < h; j++) {
+ dst2 = (uint16_t*)dst;
+ for (i = 0; i < w; i++)
+ *dst2++ = color;
+ dst += stride;
+ }
+ } else if (bpp == 4) {
+ uint32_t *dst2;
+ for (j = 0; j < h; j++) {
+ dst2 = (uint32_t*)dst;
+ for (i = 0; i < w; i++)
+ dst2[i] = color;
+ dst += stride;
+ }
+ }
+}
+
+static av_always_inline void paint_raw(uint8_t *dst, int w, int h,
+ GetByteContext *gb, int bpp,
+ int be, int stride)
+{
+ int i, j, p;
+ for (j = 0; j < h; j++) {
+ for (i = 0; i < w; i++) {
+ p = vmnc_get_pixel(gb, bpp, be);
+ switch (bpp) {
+ case 1:
+ dst[i] = p;
+ break;
+ case 2:
+ ((uint16_t*)dst)[i] = p;
+ break;
+ case 4:
+ ((uint32_t*)dst)[i] = p;
+ break;
+ }
+ }
+ dst += stride;
+ }
+}
+
+static int decode_hextile(VmncContext *c, uint8_t* dst, GetByteContext *gb,
+ int w, int h, int stride)
+{
+ int i, j, k;
+ int bg = 0, fg = 0, rects, color, flags, xy, wh;
+ const int bpp = c->bpp2;
+ uint8_t *dst2;
+ int bw = 16, bh = 16;
+
+ for (j = 0; j < h; j += 16) {
+ dst2 = dst;
+ bw = 16;
+ if (j + 16 > h)
+ bh = h - j;
+ for (i = 0; i < w; i += 16, dst2 += 16 * bpp) {
+ if (bytestream2_get_bytes_left(gb) <= 0) {
+ av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (i + 16 > w)
+ bw = w - i;
+ flags = bytestream2_get_byte(gb);
+ if (flags & HT_RAW) {
+ if (bytestream2_get_bytes_left(gb) < bw * bh * bpp) {
+ av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
+ return AVERROR_INVALIDDATA;
+ }
+ paint_raw(dst2, bw, bh, gb, bpp, c->bigendian, stride);
+ } else {
+ if (flags & HT_BKG)
+ bg = vmnc_get_pixel(gb, bpp, c->bigendian);
+ if (flags & HT_FG)
+ fg = vmnc_get_pixel(gb, bpp, c->bigendian);
+ rects = 0;
+ if (flags & HT_SUB)
+ rects = bytestream2_get_byte(gb);
+ color = !!(flags & HT_CLR);
+
+ paint_rect(dst2, 0, 0, bw, bh, bg, bpp, stride);
+
+ if (bytestream2_get_bytes_left(gb) < rects * (color * bpp + 2)) {
+ av_log(c->avctx, AV_LOG_ERROR, "Premature end of data!\n");
+ return AVERROR_INVALIDDATA;
+ }
+ for (k = 0; k < rects; k++) {
+ if (color)
+ fg = vmnc_get_pixel(gb, bpp, c->bigendian);
+ xy = bytestream2_get_byte(gb);
+ wh = bytestream2_get_byte(gb);
+ if ( (xy >> 4) + (wh >> 4) + 1 > w - i
+ || (xy & 0xF) + (wh & 0xF)+1 > h - j) {
+ av_log(c->avctx, AV_LOG_ERROR, "Rectangle outside picture\n");
+ return AVERROR_INVALIDDATA;
+ }
+ paint_rect(dst2, xy >> 4, xy & 0xF,
+ (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride);
+ }
+ }
+ }
+ dst += stride * 16;
+ }
+ return 0;
+}
+
+static void reset_buffers(VmncContext *c)
+{
+ av_freep(&c->curbits);
+ av_freep(&c->curmask);
+ av_freep(&c->screendta);
+ c->cur_w = c->cur_h = 0;
+ c->cur_hx = c->cur_hy = 0;
+
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ VmncContext * const c = avctx->priv_data;
+ GetByteContext *gb = &c->gb;
+ uint8_t *outptr;
+ int dx, dy, w, h, depth, enc, chunks, res, size_left, ret;
+
+ if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)
+ return ret;
+
+ bytestream2_init(gb, buf, buf_size);
+
+ c->pic->key_frame = 0;
+ c->pic->pict_type = AV_PICTURE_TYPE_P;
+
+ // restore screen after cursor
+ if (c->screendta) {
+ int i;
+ w = c->cur_w;
+ if (c->width < c->cur_x + w)
+ w = c->width - c->cur_x;
+ h = c->cur_h;
+ if (c->height < c->cur_y + h)
+ h = c->height - c->cur_y;
+ dx = c->cur_x;
+ if (dx < 0) {
+ w += dx;
+ dx = 0;
+ }
+ dy = c->cur_y;
+ if (dy < 0) {
+ h += dy;
+ dy = 0;
+ }
+ if ((w > 0) && (h > 0)) {
+ outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
+ for (i = 0; i < h; i++) {
+ memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2,
+ w * c->bpp2);
+ outptr += c->pic->linesize[0];
+ }
+ }
+ }
+ bytestream2_skip(gb, 2);
+ chunks = bytestream2_get_be16(gb);
+ while (chunks--) {
+ if (bytestream2_get_bytes_left(gb) < 12) {
+ av_log(avctx, AV_LOG_ERROR, "Premature end of data!\n");
+ return -1;
+ }
+ dx = bytestream2_get_be16(gb);
+ dy = bytestream2_get_be16(gb);
+ w = bytestream2_get_be16(gb);
+ h = bytestream2_get_be16(gb);
+ enc = bytestream2_get_be32(gb);
+ if ((dx + w > c->width) || (dy + h > c->height)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Incorrect frame size: %ix%i+%ix%i of %ix%i\n",
+ w, h, dx, dy, c->width, c->height);
+ return AVERROR_INVALIDDATA;
+ }
+ outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
+ size_left = bytestream2_get_bytes_left(gb);
+ switch (enc) {
+ case MAGIC_WMVd: // cursor
+ if (w*(int64_t)h*c->bpp2 > INT_MAX/2 - 2) {
+ av_log(avctx, AV_LOG_ERROR, "dimensions too large\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (size_left < 2 + w * h * c->bpp2 * 2) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Premature end of data! (need %i got %i)\n",
+ 2 + w * h * c->bpp2 * 2, size_left);
+ return AVERROR_INVALIDDATA;
+ }
+ bytestream2_skip(gb, 2);
+ c->cur_w = w;
+ c->cur_h = h;
+ c->cur_hx = dx;
+ c->cur_hy = dy;
+ if ((c->cur_hx > c->cur_w) || (c->cur_hy > c->cur_h)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Cursor hot spot is not in image: "
+ "%ix%i of %ix%i cursor size\n",
+ c->cur_hx, c->cur_hy, c->cur_w, c->cur_h);
+ c->cur_hx = c->cur_hy = 0;
+ }
+ if (c->cur_w * c->cur_h >= INT_MAX / c->bpp2) {
+ reset_buffers(c);
+ return AVERROR(EINVAL);
+ } else {
+ int screen_size = c->cur_w * c->cur_h * c->bpp2;
+ if ((ret = av_reallocp(&c->curbits, screen_size)) < 0 ||
+ (ret = av_reallocp(&c->curmask, screen_size)) < 0 ||
+ (ret = av_reallocp(&c->screendta, screen_size)) < 0) {
+ reset_buffers(c);
+ return ret;
+ }
+ }
+ load_cursor(c);
+ break;
+ case MAGIC_WMVe: // unknown
+ bytestream2_skip(gb, 2);
+ break;
+ case MAGIC_WMVf: // update cursor position
+ c->cur_x = dx - c->cur_hx;
+ c->cur_y = dy - c->cur_hy;
+ break;
+ case MAGIC_WMVg: // unknown
+ bytestream2_skip(gb, 10);
+ break;
+ case MAGIC_WMVh: // unknown
+ bytestream2_skip(gb, 4);
+ break;
+ case MAGIC_WMVi: // ServerInitialization struct
+ c->pic->key_frame = 1;
+ c->pic->pict_type = AV_PICTURE_TYPE_I;
+ depth = bytestream2_get_byte(gb);
+ if (depth != c->bpp) {
+ av_log(avctx, AV_LOG_INFO,
+ "Depth mismatch. Container %i bpp, "
+ "Frame data: %i bpp\n",
+ c->bpp, depth);
+ }
+ bytestream2_skip(gb, 1);
+ c->bigendian = bytestream2_get_byte(gb);
+ if (c->bigendian & (~1)) {
+ av_log(avctx, AV_LOG_INFO,
+ "Invalid header: bigendian flag = %i\n", c->bigendian);
+ return AVERROR_INVALIDDATA;
+ }
+ //skip the rest of pixel format data
+ bytestream2_skip(gb, 13);
+ break;
+ case MAGIC_WMVj: // unknown
+ bytestream2_skip(gb, 2);
+ break;
+ case 0x00000000: // raw rectangle data
+ if (size_left < w * h * c->bpp2) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Premature end of data! (need %i got %i)\n",
+ w * h * c->bpp2, size_left);
+ return AVERROR_INVALIDDATA;
+ }
+ paint_raw(outptr, w, h, gb, c->bpp2, c->bigendian,
+ c->pic->linesize[0]);
+ break;
+ case 0x00000005: // HexTile encoded rectangle
+ res = decode_hextile(c, outptr, gb, w, h, c->pic->linesize[0]);
+ if (res < 0)
+ return res;
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Unsupported block type 0x%08X\n", enc);
+ chunks = 0; // leave chunks decoding loop
+ }
+ }
+ if (c->screendta) {
+ int i;
+ // save screen data before painting cursor
+ w = c->cur_w;
+ if (c->width < c->cur_x + w)
+ w = c->width - c->cur_x;
+ h = c->cur_h;
+ if (c->height < c->cur_y + h)
+ h = c->height - c->cur_y;
+ dx = c->cur_x;
+ if (dx < 0) {
+ w += dx;
+ dx = 0;
+ }
+ dy = c->cur_y;
+ if (dy < 0) {
+ h += dy;
+ dy = 0;
+ }
+ if ((w > 0) && (h > 0)) {
+ outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0];
+ for (i = 0; i < h; i++) {
+ memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr,
+ w * c->bpp2);
+ outptr += c->pic->linesize[0];
+ }
+ outptr = c->pic->data[0];
+ put_cursor(outptr, c->pic->linesize[0], c, c->cur_x, c->cur_y);
+ }
+ }
+ *got_frame = 1;
+ if ((ret = av_frame_ref(data, c->pic)) < 0)
+ return ret;
+
+ /* always report that the buffer was completely consumed */
+ return buf_size;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ VmncContext * const c = avctx->priv_data;
+
+ c->avctx = avctx;
+ c->width = avctx->width;
+ c->height = avctx->height;
+ c->bpp = avctx->bits_per_coded_sample;
+
+ switch (c->bpp) {
+ case 8:
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ break;
+ case 16:
+ avctx->pix_fmt = AV_PIX_FMT_RGB555;
+ break;
+ case 24:
+ /* 24 bits is not technically supported, but some clients might
+ * mistakenly set it, so let's assume they actually meant 32 bits */
+ c->bpp = 32;
+ case 32:
+ avctx->pix_fmt = AV_PIX_FMT_0RGB32;
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", c->bpp);
+ return AVERROR_INVALIDDATA;
+ }
+ c->bpp2 = c->bpp / 8;
+
+ c->pic = av_frame_alloc();
+ if (!c->pic)
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static av_cold int decode_end(AVCodecContext *avctx)
+{
+ VmncContext * const c = avctx->priv_data;
+
+ av_frame_free(&c->pic);
+
+ av_freep(&c->curbits);
+ av_freep(&c->curmask);
+ av_freep(&c->screendta);
+ return 0;
+}
+
+AVCodec ff_vmnc_decoder = {
+ .name = "vmnc",
+ .long_name = NULL_IF_CONFIG_SMALL("VMware Screen Codec / VMware Video"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_VMNC,
+ .priv_data_size = sizeof(VmncContext),
+ .init = decode_init,
+ .close = decode_end,
+ .decode = decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/vorbis.c b/ffmpeg-2-8-12/libavcodec/vorbis.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vorbis.c
rename to ffmpeg-2-8-12/libavcodec/vorbis.c
diff --git a/ffmpeg-2-8-11/libavcodec/vorbis.h b/ffmpeg-2-8-12/libavcodec/vorbis.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vorbis.h
rename to ffmpeg-2-8-12/libavcodec/vorbis.h
diff --git a/ffmpeg-2-8-11/libavcodec/vorbis_data.c b/ffmpeg-2-8-12/libavcodec/vorbis_data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vorbis_data.c
rename to ffmpeg-2-8-12/libavcodec/vorbis_data.c
diff --git a/ffmpeg-2-8-11/libavcodec/vorbis_enc_data.h b/ffmpeg-2-8-12/libavcodec/vorbis_enc_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vorbis_enc_data.h
rename to ffmpeg-2-8-12/libavcodec/vorbis_enc_data.h
diff --git a/ffmpeg-2-8-11/libavcodec/vorbis_parser.c b/ffmpeg-2-8-12/libavcodec/vorbis_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vorbis_parser.c
rename to ffmpeg-2-8-12/libavcodec/vorbis_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/vorbis_parser.h b/ffmpeg-2-8-12/libavcodec/vorbis_parser.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vorbis_parser.h
rename to ffmpeg-2-8-12/libavcodec/vorbis_parser.h
diff --git a/ffmpeg-2-8-11/libavcodec/vorbis_parser_internal.h b/ffmpeg-2-8-12/libavcodec/vorbis_parser_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vorbis_parser_internal.h
rename to ffmpeg-2-8-12/libavcodec/vorbis_parser_internal.h
diff --git a/ffmpeg-2-8-11/libavcodec/vorbisdec.c b/ffmpeg-2-8-12/libavcodec/vorbisdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vorbisdec.c
rename to ffmpeg-2-8-12/libavcodec/vorbisdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/vorbisdsp.c b/ffmpeg-2-8-12/libavcodec/vorbisdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vorbisdsp.c
rename to ffmpeg-2-8-12/libavcodec/vorbisdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/vorbisdsp.h b/ffmpeg-2-8-12/libavcodec/vorbisdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vorbisdsp.h
rename to ffmpeg-2-8-12/libavcodec/vorbisdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/vorbisenc.c b/ffmpeg-2-8-12/libavcodec/vorbisenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vorbisenc.c
rename to ffmpeg-2-8-12/libavcodec/vorbisenc.c
diff --git a/ffmpeg-2-8-12/libavcodec/vp3.c b/ffmpeg-2-8-12/libavcodec/vp3.c
new file mode 100644
index 0000000..fe58d09
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/vp3.c
@@ -0,0 +1,2589 @@
+/*
+ * Copyright (c) 2003-2004 The FFmpeg Project
+ *
+ * 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
+ * On2 VP3 Video Decoder
+ *
+ * VP3 Video Decoder by Mike Melanson (mike at multimedia.cx)
+ * For more information about the VP3 coding process, visit:
+ * http://wiki.multimedia.cx/index.php?title=On2_VP3
+ *
+ * Theora decoder by Alex Beregszaszi
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libavutil/imgutils.h"
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "hpeldsp.h"
+#include "internal.h"
+#include "mathops.h"
+#include "thread.h"
+#include "videodsp.h"
+#include "vp3data.h"
+#include "vp3dsp.h"
+#include "xiph.h"
+
+#define FRAGMENT_PIXELS 8
+
+// FIXME split things out into their own arrays
+typedef struct Vp3Fragment {
+ int16_t dc;
+ uint8_t coding_method;
+ uint8_t qpi;
+} Vp3Fragment;
+
+#define SB_NOT_CODED 0
+#define SB_PARTIALLY_CODED 1
+#define SB_FULLY_CODED 2
+
+// This is the maximum length of a single long bit run that can be encoded
+// for superblock coding or block qps. Theora special-cases this to read a
+// bit instead of flipping the current bit to allow for runs longer than 4129.
+#define MAXIMUM_LONG_BIT_RUN 4129
+
+#define MODE_INTER_NO_MV 0
+#define MODE_INTRA 1
+#define MODE_INTER_PLUS_MV 2
+#define MODE_INTER_LAST_MV 3
+#define MODE_INTER_PRIOR_LAST 4
+#define MODE_USING_GOLDEN 5
+#define MODE_GOLDEN_MV 6
+#define MODE_INTER_FOURMV 7
+#define CODING_MODE_COUNT 8
+
+/* special internal mode */
+#define MODE_COPY 8
+
+static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb);
+static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb);
+
+
+/* There are 6 preset schemes, plus a free-form scheme */
+static const int ModeAlphabet[6][CODING_MODE_COUNT] = {
+ /* scheme 1: Last motion vector dominates */
+ { MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST,
+ MODE_INTER_PLUS_MV, MODE_INTER_NO_MV,
+ MODE_INTRA, MODE_USING_GOLDEN,
+ MODE_GOLDEN_MV, MODE_INTER_FOURMV },
+
+ /* scheme 2 */
+ { MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST,
+ MODE_INTER_NO_MV, MODE_INTER_PLUS_MV,
+ MODE_INTRA, MODE_USING_GOLDEN,
+ MODE_GOLDEN_MV, MODE_INTER_FOURMV },
+
+ /* scheme 3 */
+ { MODE_INTER_LAST_MV, MODE_INTER_PLUS_MV,
+ MODE_INTER_PRIOR_LAST, MODE_INTER_NO_MV,
+ MODE_INTRA, MODE_USING_GOLDEN,
+ MODE_GOLDEN_MV, MODE_INTER_FOURMV },
+
+ /* scheme 4 */
+ { MODE_INTER_LAST_MV, MODE_INTER_PLUS_MV,
+ MODE_INTER_NO_MV, MODE_INTER_PRIOR_LAST,
+ MODE_INTRA, MODE_USING_GOLDEN,
+ MODE_GOLDEN_MV, MODE_INTER_FOURMV },
+
+ /* scheme 5: No motion vector dominates */
+ { MODE_INTER_NO_MV, MODE_INTER_LAST_MV,
+ MODE_INTER_PRIOR_LAST, MODE_INTER_PLUS_MV,
+ MODE_INTRA, MODE_USING_GOLDEN,
+ MODE_GOLDEN_MV, MODE_INTER_FOURMV },
+
+ /* scheme 6 */
+ { MODE_INTER_NO_MV, MODE_USING_GOLDEN,
+ MODE_INTER_LAST_MV, MODE_INTER_PRIOR_LAST,
+ MODE_INTER_PLUS_MV, MODE_INTRA,
+ MODE_GOLDEN_MV, MODE_INTER_FOURMV },
+};
+
+static const uint8_t hilbert_offset[16][2] = {
+ { 0, 0 }, { 1, 0 }, { 1, 1 }, { 0, 1 },
+ { 0, 2 }, { 0, 3 }, { 1, 3 }, { 1, 2 },
+ { 2, 2 }, { 2, 3 }, { 3, 3 }, { 3, 2 },
+ { 3, 1 }, { 2, 1 }, { 2, 0 }, { 3, 0 }
+};
+
+#define MIN_DEQUANT_VAL 2
+
+typedef struct Vp3DecodeContext {
+ AVCodecContext *avctx;
+ int theora, theora_tables, theora_header;
+ int version;
+ int width, height;
+ int chroma_x_shift, chroma_y_shift;
+ ThreadFrame golden_frame;
+ ThreadFrame last_frame;
+ ThreadFrame current_frame;
+ int keyframe;
+ uint8_t idct_permutation[64];
+ uint8_t idct_scantable[64];
+ HpelDSPContext hdsp;
+ VideoDSPContext vdsp;
+ VP3DSPContext vp3dsp;
+ DECLARE_ALIGNED(16, int16_t, block)[64];
+ int flipped_image;
+ int last_slice_end;
+ int skip_loop_filter;
+
+ int qps[3];
+ int nqps;
+ int last_qps[3];
+
+ int superblock_count;
+ int y_superblock_width;
+ int y_superblock_height;
+ int y_superblock_count;
+ int c_superblock_width;
+ int c_superblock_height;
+ int c_superblock_count;
+ int u_superblock_start;
+ int v_superblock_start;
+ unsigned char *superblock_coding;
+
+ int macroblock_count;
+ int macroblock_width;
+ int macroblock_height;
+
+ int fragment_count;
+ int fragment_width[2];
+ int fragment_height[2];
+
+ Vp3Fragment *all_fragments;
+ int fragment_start[3];
+ int data_offset[3];
+ uint8_t offset_x;
+ uint8_t offset_y;
+ int offset_x_warned;
+
+ int8_t (*motion_val[2])[2];
+
+ /* tables */
+ uint16_t coded_dc_scale_factor[64];
+ uint32_t coded_ac_scale_factor[64];
+ uint8_t base_matrix[384][64];
+ uint8_t qr_count[2][3];
+ uint8_t qr_size[2][3][64];
+ uint16_t qr_base[2][3][64];
+
+ /**
+ * This is a list of all tokens in bitstream order. Reordering takes place
+ * by pulling from each level during IDCT. As a consequence, IDCT must be
+ * in Hilbert order, making the minimum slice height 64 for 4:2:0 and 32
+ * otherwise. The 32 different tokens with up to 12 bits of extradata are
+ * collapsed into 3 types, packed as follows:
+ * (from the low to high bits)
+ *
+ * 2 bits: type (0,1,2)
+ * 0: EOB run, 14 bits for run length (12 needed)
+ * 1: zero run, 7 bits for run length
+ * 7 bits for the next coefficient (3 needed)
+ * 2: coefficient, 14 bits (11 needed)
+ *
+ * Coefficients are signed, so are packed in the highest bits for automatic
+ * sign extension.
+ */
+ int16_t *dct_tokens[3][64];
+ int16_t *dct_tokens_base;
+#define TOKEN_EOB(eob_run) ((eob_run) << 2)
+#define TOKEN_ZERO_RUN(coeff, zero_run) (((coeff) * 512) + ((zero_run) << 2) + 1)
+#define TOKEN_COEFF(coeff) (((coeff) * 4) + 2)
+
+ /**
+ * number of blocks that contain DCT coefficients at
+ * the given level or higher
+ */
+ int num_coded_frags[3][64];
+ int total_num_coded_frags;
+
+ /* this is a list of indexes into the all_fragments array indicating
+ * which of the fragments are coded */
+ int *coded_fragment_list[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];
+
+ VLC superblock_run_length_vlc;
+ VLC fragment_run_length_vlc;
+ VLC mode_code_vlc;
+ VLC motion_vector_vlc;
+
+ /* these arrays need to be on 16-byte boundaries since SSE2 operations
+ * index into them */
+ DECLARE_ALIGNED(16, int16_t, qmat)[3][2][3][64]; ///< qmat[qpi][is_inter][plane]
+
+ /* This table contains superblock_count * 16 entries. Each set of 16
+ * numbers corresponds to the fragment indexes 0..15 of the superblock.
+ * An entry will be -1 to indicate that no entry corresponds to that
+ * index. */
+ int *superblock_fragments;
+
+ /* This is an array that indicates how a particular macroblock
+ * is coded. */
+ unsigned char *macroblock_coding;
+
+ 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];
+
+ uint8_t filter_limit_values[64];
+ DECLARE_ALIGNED(8, int, bounding_values_array)[256 + 2];
+} Vp3DecodeContext;
+
+/************************************************************************
+ * VP3 specific functions
+ ************************************************************************/
+
+static av_cold void free_tables(AVCodecContext *avctx)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+
+ av_freep(&s->superblock_coding);
+ av_freep(&s->all_fragments);
+ av_freep(&s->coded_fragment_list[0]);
+ av_freep(&s->dct_tokens_base);
+ av_freep(&s->superblock_fragments);
+ av_freep(&s->macroblock_coding);
+ av_freep(&s->motion_val[0]);
+ av_freep(&s->motion_val[1]);
+}
+
+static void vp3_decode_flush(AVCodecContext *avctx)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+
+ if (s->golden_frame.f)
+ ff_thread_release_buffer(avctx, &s->golden_frame);
+ if (s->last_frame.f)
+ ff_thread_release_buffer(avctx, &s->last_frame);
+ if (s->current_frame.f)
+ ff_thread_release_buffer(avctx, &s->current_frame);
+}
+
+static av_cold int vp3_decode_end(AVCodecContext *avctx)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+ int i;
+
+ free_tables(avctx);
+ av_freep(&s->edge_emu_buffer);
+
+ s->theora_tables = 0;
+
+ /* release all frames */
+ vp3_decode_flush(avctx);
+ av_frame_free(&s->current_frame.f);
+ av_frame_free(&s->last_frame.f);
+ av_frame_free(&s->golden_frame.f);
+
+ if (avctx->internal->is_copy)
+ return 0;
+
+ 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]);
+ }
+
+ ff_free_vlc(&s->superblock_run_length_vlc);
+ ff_free_vlc(&s->fragment_run_length_vlc);
+ ff_free_vlc(&s->mode_code_vlc);
+ ff_free_vlc(&s->motion_vector_vlc);
+
+ return 0;
+}
+
+/**
+ * This function sets up all of the various blocks mappings:
+ * superblocks <-> fragments, macroblocks <-> fragments,
+ * superblocks <-> macroblocks
+ *
+ * @return 0 is successful; returns 1 if *anything* went wrong.
+ */
+static int init_block_mapping(Vp3DecodeContext *s)
+{
+ int sb_x, sb_y, plane;
+ int x, y, i, j = 0;
+
+ for (plane = 0; plane < 3; plane++) {
+ int sb_width = plane ? s->c_superblock_width
+ : s->y_superblock_width;
+ int sb_height = plane ? s->c_superblock_height
+ : s->y_superblock_height;
+ int frag_width = s->fragment_width[!!plane];
+ int frag_height = s->fragment_height[!!plane];
+
+ for (sb_y = 0; sb_y < sb_height; sb_y++)
+ for (sb_x = 0; sb_x < sb_width; sb_x++)
+ for (i = 0; i < 16; i++) {
+ x = 4 * sb_x + hilbert_offset[i][0];
+ y = 4 * sb_y + hilbert_offset[i][1];
+
+ if (x < frag_width && y < frag_height)
+ s->superblock_fragments[j++] = s->fragment_start[plane] +
+ y * frag_width + x;
+ else
+ s->superblock_fragments[j++] = -1;
+ }
+ }
+
+ return 0; /* successful path out */
+}
+
+/*
+ * This function sets up the dequantization tables used for a particular
+ * frame.
+ */
+static void init_dequantizer(Vp3DecodeContext *s, int qpi)
+{
+ int ac_scale_factor = s->coded_ac_scale_factor[s->qps[qpi]];
+ int dc_scale_factor = s->coded_dc_scale_factor[s->qps[qpi]];
+ int i, plane, inter, qri, bmi, bmj, qistart;
+
+ for (inter = 0; inter < 2; inter++) {
+ for (plane = 0; plane < 3; plane++) {
+ int sum = 0;
+ for (qri = 0; qri < s->qr_count[inter][plane]; qri++) {
+ sum += s->qr_size[inter][plane][qri];
+ if (s->qps[qpi] <= sum)
+ break;
+ }
+ qistart = sum - s->qr_size[inter][plane][qri];
+ bmi = s->qr_base[inter][plane][qri];
+ bmj = s->qr_base[inter][plane][qri + 1];
+ for (i = 0; i < 64; i++) {
+ int coeff = (2 * (sum - s->qps[qpi]) * s->base_matrix[bmi][i] -
+ 2 * (qistart - s->qps[qpi]) * s->base_matrix[bmj][i] +
+ s->qr_size[inter][plane][qri]) /
+ (2 * s->qr_size[inter][plane][qri]);
+
+ int qmin = 8 << (inter + !i);
+ int qscale = i ? ac_scale_factor : dc_scale_factor;
+
+ s->qmat[qpi][inter][plane][s->idct_permutation[i]] =
+ av_clip((qscale * coeff) / 100 * 4, qmin, 4096);
+ }
+ /* all DC coefficients use the same quant so as not to interfere
+ * with DC prediction */
+ s->qmat[qpi][inter][plane][0] = s->qmat[0][inter][plane][0];
+ }
+ }
+}
+
+/*
+ * This function initializes the loop filter boundary limits if the frame's
+ * quality index is different from the previous frame's.
+ *
+ * The filter_limit_values may not be larger than 127.
+ */
+static void init_loop_filter(Vp3DecodeContext *s)
+{
+ int *bounding_values = s->bounding_values_array + 127;
+ int filter_limit;
+ int x;
+ int value;
+
+ filter_limit = s->filter_limit_values[s->qps[0]];
+ av_assert0(filter_limit < 128U);
+
+ /* set up the bounding values */
+ memset(s->bounding_values_array, 0, 256 * sizeof(int));
+ for (x = 0; x < filter_limit; x++) {
+ bounding_values[-x] = -x;
+ bounding_values[x] = x;
+ }
+ for (x = value = filter_limit; x < 128 && value; x++, value--) {
+ bounding_values[ x] = value;
+ bounding_values[-x] = -value;
+ }
+ if (value)
+ bounding_values[128] = value;
+ bounding_values[129] = bounding_values[130] = filter_limit * 0x02020202;
+}
+
+/*
+ * This function unpacks all of the superblock/macroblock/fragment coding
+ * information from the bitstream.
+ */
+static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb)
+{
+ int superblock_starts[3] = {
+ 0, s->u_superblock_start, s->v_superblock_start
+ };
+ int bit = 0;
+ int current_superblock = 0;
+ int current_run = 0;
+ int num_partial_superblocks = 0;
+
+ int i, j;
+ int current_fragment;
+ int plane;
+
+ if (s->keyframe) {
+ memset(s->superblock_coding, SB_FULLY_CODED, s->superblock_count);
+ } else {
+ /* unpack the list of partially-coded superblocks */
+ bit = get_bits1(gb) ^ 1;
+ current_run = 0;
+
+ while (current_superblock < s->superblock_count && get_bits_left(gb) > 0) {
+ if (s->theora && current_run == MAXIMUM_LONG_BIT_RUN)
+ bit = get_bits1(gb);
+ else
+ bit ^= 1;
+
+ current_run = get_vlc2(gb, s->superblock_run_length_vlc.table,
+ 6, 2) + 1;
+ if (current_run == 34)
+ current_run += get_bits(gb, 12);
+
+ if (current_run > s->superblock_count - current_superblock) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid partially coded superblock run length\n");
+ return -1;
+ }
+
+ memset(s->superblock_coding + current_superblock, bit, current_run);
+
+ current_superblock += current_run;
+ if (bit)
+ num_partial_superblocks += current_run;
+ }
+
+ /* unpack the list of fully coded superblocks if any of the blocks were
+ * not marked as partially coded in the previous step */
+ if (num_partial_superblocks < s->superblock_count) {
+ int superblocks_decoded = 0;
+
+ current_superblock = 0;
+ bit = get_bits1(gb) ^ 1;
+ current_run = 0;
+
+ while (superblocks_decoded < s->superblock_count - num_partial_superblocks &&
+ get_bits_left(gb) > 0) {
+ if (s->theora && current_run == MAXIMUM_LONG_BIT_RUN)
+ bit = get_bits1(gb);
+ else
+ bit ^= 1;
+
+ current_run = get_vlc2(gb, s->superblock_run_length_vlc.table,
+ 6, 2) + 1;
+ if (current_run == 34)
+ current_run += get_bits(gb, 12);
+
+ for (j = 0; j < current_run; current_superblock++) {
+ if (current_superblock >= s->superblock_count) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid fully coded superblock run length\n");
+ return -1;
+ }
+
+ /* skip any superblocks already marked as partially coded */
+ if (s->superblock_coding[current_superblock] == SB_NOT_CODED) {
+ s->superblock_coding[current_superblock] = 2 * bit;
+ j++;
+ }
+ }
+ superblocks_decoded += current_run;
+ }
+ }
+
+ /* if there were partial blocks, initialize bitstream for
+ * unpacking fragment codings */
+ if (num_partial_superblocks) {
+ current_run = 0;
+ bit = get_bits1(gb);
+ /* toggle the bit because as soon as the first run length is
+ * fetched the bit will be toggled again */
+ bit ^= 1;
+ }
+ }
+
+ /* figure out which fragments are coded; iterate through each
+ * superblock (all planes) */
+ s->total_num_coded_frags = 0;
+ memset(s->macroblock_coding, MODE_COPY, s->macroblock_count);
+
+ for (plane = 0; plane < 3; plane++) {
+ int sb_start = superblock_starts[plane];
+ int sb_end = sb_start + (plane ? s->c_superblock_count
+ : s->y_superblock_count);
+ int num_coded_frags = 0;
+
+ for (i = sb_start; i < sb_end && get_bits_left(gb) > 0; i++) {
+ /* iterate through all 16 fragments in a superblock */
+ for (j = 0; j < 16; j++) {
+ /* if the fragment is in bounds, check its coding status */
+ current_fragment = s->superblock_fragments[i * 16 + j];
+ if (current_fragment != -1) {
+ int coded = s->superblock_coding[i];
+
+ if (s->superblock_coding[i] == SB_PARTIALLY_CODED) {
+ /* fragment may or may not be coded; this is the case
+ * that cares about the fragment coding runs */
+ if (current_run-- == 0) {
+ bit ^= 1;
+ current_run = get_vlc2(gb, s->fragment_run_length_vlc.table, 5, 2);
+ }
+ coded = bit;
+ }
+
+ if (coded) {
+ /* default mode; actual mode will be decoded in
+ * the next phase */
+ s->all_fragments[current_fragment].coding_method =
+ MODE_INTER_NO_MV;
+ s->coded_fragment_list[plane][num_coded_frags++] =
+ current_fragment;
+ } else {
+ /* not coded; copy this fragment from the prior frame */
+ s->all_fragments[current_fragment].coding_method =
+ MODE_COPY;
+ }
+ }
+ }
+ }
+ s->total_num_coded_frags += num_coded_frags;
+ for (i = 0; i < 64; i++)
+ s->num_coded_frags[plane][i] = num_coded_frags;
+ if (plane < 2)
+ s->coded_fragment_list[plane + 1] = s->coded_fragment_list[plane] +
+ num_coded_frags;
+ }
+ return 0;
+}
+
+/*
+ * This function unpacks all the coding mode data for individual macroblocks
+ * from the bitstream.
+ */
+static int unpack_modes(Vp3DecodeContext *s, GetBitContext *gb)
+{
+ int i, j, k, sb_x, sb_y;
+ int scheme;
+ int current_macroblock;
+ int current_fragment;
+ int coding_mode;
+ int custom_mode_alphabet[CODING_MODE_COUNT];
+ const int *alphabet;
+ Vp3Fragment *frag;
+
+ if (s->keyframe) {
+ for (i = 0; i < s->fragment_count; i++)
+ s->all_fragments[i].coding_method = MODE_INTRA;
+ } else {
+ /* fetch the mode coding scheme for this frame */
+ scheme = get_bits(gb, 3);
+
+ /* is it a custom coding scheme? */
+ if (scheme == 0) {
+ for (i = 0; i < 8; i++)
+ custom_mode_alphabet[i] = MODE_INTER_NO_MV;
+ for (i = 0; i < 8; i++)
+ custom_mode_alphabet[get_bits(gb, 3)] = i;
+ alphabet = custom_mode_alphabet;
+ } else
+ alphabet = ModeAlphabet[scheme - 1];
+
+ /* iterate through all of the macroblocks that contain 1 or more
+ * coded fragments */
+ for (sb_y = 0; sb_y < s->y_superblock_height; sb_y++) {
+ for (sb_x = 0; sb_x < s->y_superblock_width; sb_x++) {
+ if (get_bits_left(gb) <= 0)
+ return -1;
+
+ for (j = 0; j < 4; j++) {
+ int mb_x = 2 * sb_x + (j >> 1);
+ int mb_y = 2 * sb_y + (((j >> 1) + j) & 1);
+ current_macroblock = mb_y * s->macroblock_width + mb_x;
+
+ if (mb_x >= s->macroblock_width ||
+ mb_y >= s->macroblock_height)
+ continue;
+
+#define BLOCK_X (2 * mb_x + (k & 1))
+#define BLOCK_Y (2 * mb_y + (k >> 1))
+ /* coding modes are only stored if the macroblock has
+ * at least one luma block coded, otherwise it must be
+ * INTER_NO_MV */
+ for (k = 0; k < 4; k++) {
+ current_fragment = BLOCK_Y *
+ s->fragment_width[0] + BLOCK_X;
+ if (s->all_fragments[current_fragment].coding_method != MODE_COPY)
+ break;
+ }
+ if (k == 4) {
+ s->macroblock_coding[current_macroblock] = MODE_INTER_NO_MV;
+ continue;
+ }
+
+ /* mode 7 means get 3 bits for each coding mode */
+ if (scheme == 7)
+ coding_mode = get_bits(gb, 3);
+ else
+ coding_mode = alphabet[get_vlc2(gb, s->mode_code_vlc.table, 3, 3)];
+
+ s->macroblock_coding[current_macroblock] = coding_mode;
+ for (k = 0; k < 4; k++) {
+ frag = s->all_fragments + BLOCK_Y * s->fragment_width[0] + BLOCK_X;
+ if (frag->coding_method != MODE_COPY)
+ frag->coding_method = coding_mode;
+ }
+
+#define SET_CHROMA_MODES \
+ if (frag[s->fragment_start[1]].coding_method != MODE_COPY) \
+ frag[s->fragment_start[1]].coding_method = coding_mode; \
+ if (frag[s->fragment_start[2]].coding_method != MODE_COPY) \
+ frag[s->fragment_start[2]].coding_method = coding_mode;
+
+ if (s->chroma_y_shift) {
+ frag = s->all_fragments + mb_y *
+ s->fragment_width[1] + mb_x;
+ SET_CHROMA_MODES
+ } else if (s->chroma_x_shift) {
+ frag = s->all_fragments +
+ 2 * mb_y * s->fragment_width[1] + mb_x;
+ for (k = 0; k < 2; k++) {
+ SET_CHROMA_MODES
+ frag += s->fragment_width[1];
+ }
+ } else {
+ for (k = 0; k < 4; k++) {
+ frag = s->all_fragments +
+ BLOCK_Y * s->fragment_width[1] + BLOCK_X;
+ SET_CHROMA_MODES
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * This function unpacks all the motion vectors for the individual
+ * macroblocks from the bitstream.
+ */
+static int unpack_vectors(Vp3DecodeContext *s, GetBitContext *gb)
+{
+ int j, k, sb_x, sb_y;
+ int coding_mode;
+ int motion_x[4];
+ int motion_y[4];
+ int last_motion_x = 0;
+ int last_motion_y = 0;
+ int prior_last_motion_x = 0;
+ int prior_last_motion_y = 0;
+ int current_macroblock;
+ int current_fragment;
+ int frag;
+
+ if (s->keyframe)
+ return 0;
+
+ /* coding mode 0 is the VLC scheme; 1 is the fixed code scheme */
+ coding_mode = get_bits1(gb);
+
+ /* iterate through all of the macroblocks that contain 1 or more
+ * coded fragments */
+ for (sb_y = 0; sb_y < s->y_superblock_height; sb_y++) {
+ for (sb_x = 0; sb_x < s->y_superblock_width; sb_x++) {
+ if (get_bits_left(gb) <= 0)
+ return -1;
+
+ for (j = 0; j < 4; j++) {
+ int mb_x = 2 * sb_x + (j >> 1);
+ int mb_y = 2 * sb_y + (((j >> 1) + j) & 1);
+ current_macroblock = mb_y * s->macroblock_width + mb_x;
+
+ if (mb_x >= s->macroblock_width ||
+ mb_y >= s->macroblock_height ||
+ s->macroblock_coding[current_macroblock] == MODE_COPY)
+ continue;
+
+ switch (s->macroblock_coding[current_macroblock]) {
+ case MODE_INTER_PLUS_MV:
+ case MODE_GOLDEN_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)];
+ } else {
+ motion_x[0] = fixed_motion_vector_table[get_bits(gb, 6)];
+ motion_y[0] = fixed_motion_vector_table[get_bits(gb, 6)];
+ }
+
+ /* vector maintenance, only on MODE_INTER_PLUS_MV */
+ if (s->macroblock_coding[current_macroblock] == MODE_INTER_PLUS_MV) {
+ prior_last_motion_x = last_motion_x;
+ prior_last_motion_y = last_motion_y;
+ last_motion_x = motion_x[0];
+ last_motion_y = motion_y[0];
+ }
+ break;
+
+ case MODE_INTER_FOURMV:
+ /* vector maintenance */
+ prior_last_motion_x = last_motion_x;
+ prior_last_motion_y = last_motion_y;
+
+ /* fetch 4 vectors from the bitstream, one for each
+ * Y fragment, then average for the C fragment vectors */
+ for (k = 0; k < 4; k++) {
+ 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)];
+ } else {
+ motion_x[k] = fixed_motion_vector_table[get_bits(gb, 6)];
+ motion_y[k] = fixed_motion_vector_table[get_bits(gb, 6)];
+ }
+ last_motion_x = motion_x[k];
+ last_motion_y = motion_y[k];
+ } else {
+ motion_x[k] = 0;
+ motion_y[k] = 0;
+ }
+ }
+ break;
+
+ case MODE_INTER_LAST_MV:
+ /* all 6 fragments use the last motion vector */
+ motion_x[0] = last_motion_x;
+ motion_y[0] = last_motion_y;
+
+ /* no vector maintenance (last vector remains the
+ * last vector) */
+ break;
+
+ case MODE_INTER_PRIOR_LAST:
+ /* all 6 fragments use the motion vector prior to the
+ * last motion vector */
+ motion_x[0] = prior_last_motion_x;
+ motion_y[0] = prior_last_motion_y;
+
+ /* vector maintenance */
+ prior_last_motion_x = last_motion_x;
+ prior_last_motion_y = last_motion_y;
+ last_motion_x = motion_x[0];
+ last_motion_y = motion_y[0];
+ break;
+
+ default:
+ /* covers intra, inter without MV, golden without MV */
+ motion_x[0] = 0;
+ motion_y[0] = 0;
+
+ /* no vector maintenance */
+ break;
+ }
+
+ /* assign the motion vectors to the correct fragments */
+ for (k = 0; k < 4; k++) {
+ current_fragment =
+ BLOCK_Y * s->fragment_width[0] + BLOCK_X;
+ if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {
+ s->motion_val[0][current_fragment][0] = motion_x[k];
+ s->motion_val[0][current_fragment][1] = motion_y[k];
+ } else {
+ s->motion_val[0][current_fragment][0] = motion_x[0];
+ s->motion_val[0][current_fragment][1] = motion_y[0];
+ }
+ }
+
+ if (s->chroma_y_shift) {
+ if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {
+ motion_x[0] = RSHIFT(motion_x[0] + motion_x[1] +
+ motion_x[2] + motion_x[3], 2);
+ motion_y[0] = RSHIFT(motion_y[0] + motion_y[1] +
+ motion_y[2] + motion_y[3], 2);
+ }
+ motion_x[0] = (motion_x[0] >> 1) | (motion_x[0] & 1);
+ motion_y[0] = (motion_y[0] >> 1) | (motion_y[0] & 1);
+ frag = mb_y * s->fragment_width[1] + mb_x;
+ s->motion_val[1][frag][0] = motion_x[0];
+ s->motion_val[1][frag][1] = motion_y[0];
+ } else if (s->chroma_x_shift) {
+ if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {
+ motion_x[0] = RSHIFT(motion_x[0] + motion_x[1], 1);
+ motion_y[0] = RSHIFT(motion_y[0] + motion_y[1], 1);
+ motion_x[1] = RSHIFT(motion_x[2] + motion_x[3], 1);
+ motion_y[1] = RSHIFT(motion_y[2] + motion_y[3], 1);
+ } else {
+ motion_x[1] = motion_x[0];
+ motion_y[1] = motion_y[0];
+ }
+ motion_x[0] = (motion_x[0] >> 1) | (motion_x[0] & 1);
+ motion_x[1] = (motion_x[1] >> 1) | (motion_x[1] & 1);
+
+ frag = 2 * mb_y * s->fragment_width[1] + mb_x;
+ for (k = 0; k < 2; k++) {
+ s->motion_val[1][frag][0] = motion_x[k];
+ s->motion_val[1][frag][1] = motion_y[k];
+ frag += s->fragment_width[1];
+ }
+ } else {
+ for (k = 0; k < 4; k++) {
+ frag = BLOCK_Y * s->fragment_width[1] + BLOCK_X;
+ if (s->macroblock_coding[current_macroblock] == MODE_INTER_FOURMV) {
+ s->motion_val[1][frag][0] = motion_x[k];
+ s->motion_val[1][frag][1] = motion_y[k];
+ } else {
+ s->motion_val[1][frag][0] = motion_x[0];
+ s->motion_val[1][frag][1] = motion_y[0];
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int unpack_block_qpis(Vp3DecodeContext *s, GetBitContext *gb)
+{
+ int qpi, i, j, bit, run_length, blocks_decoded, num_blocks_at_qpi;
+ int num_blocks = s->total_num_coded_frags;
+
+ for (qpi = 0; qpi < s->nqps - 1 && num_blocks > 0; qpi++) {
+ i = blocks_decoded = num_blocks_at_qpi = 0;
+
+ bit = get_bits1(gb) ^ 1;
+ run_length = 0;
+
+ do {
+ if (run_length == MAXIMUM_LONG_BIT_RUN)
+ bit = get_bits1(gb);
+ else
+ bit ^= 1;
+
+ run_length = get_vlc2(gb, s->superblock_run_length_vlc.table, 6, 2) + 1;
+ if (run_length == 34)
+ run_length += get_bits(gb, 12);
+ blocks_decoded += run_length;
+
+ if (!bit)
+ num_blocks_at_qpi += run_length;
+
+ for (j = 0; j < run_length; i++) {
+ if (i >= s->total_num_coded_frags)
+ return -1;
+
+ if (s->all_fragments[s->coded_fragment_list[0][i]].qpi == qpi) {
+ s->all_fragments[s->coded_fragment_list[0][i]].qpi += bit;
+ j++;
+ }
+ }
+ } while (blocks_decoded < num_blocks && get_bits_left(gb) > 0);
+
+ num_blocks -= num_blocks_at_qpi;
+ }
+
+ return 0;
+}
+
+/*
+ * This function is called by unpack_dct_coeffs() to extract the VLCs from
+ * the bitstream. The VLCs encode tokens which are used to unpack DCT
+ * data. This function unpacks all the VLCs for either the Y plane or both
+ * C planes, and is called for DC coefficients or different AC coefficient
+ * levels (since different coefficient types require different VLC tables.
+ *
+ * This function returns a residual eob run. E.g, if a particular token gave
+ * instructions to EOB the next 5 fragments and there were only 2 fragments
+ * left in the current fragment range, 3 would be returned so that it could
+ * be passed into the next call to this same function.
+ */
+static int unpack_vlcs(Vp3DecodeContext *s, GetBitContext *gb,
+ VLC *table, int coeff_index,
+ int plane,
+ int eob_run)
+{
+ int i, j = 0;
+ int token;
+ int zero_run = 0;
+ int16_t coeff = 0;
+ int bits_to_get;
+ int blocks_ended;
+ int coeff_i = 0;
+ int num_coeffs = s->num_coded_frags[plane][coeff_index];
+ int16_t *dct_tokens = s->dct_tokens[plane][coeff_index];
+
+ /* local references to structure members to avoid repeated deferences */
+ int *coded_fragment_list = s->coded_fragment_list[plane];
+ Vp3Fragment *all_fragments = s->all_fragments;
+ VLC_TYPE(*vlc_table)[2] = table->table;
+
+ if (num_coeffs < 0)
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid number of coefficents at level %d\n", coeff_index);
+
+ if (eob_run > num_coeffs) {
+ coeff_i =
+ blocks_ended = num_coeffs;
+ eob_run -= num_coeffs;
+ } else {
+ coeff_i =
+ blocks_ended = eob_run;
+ eob_run = 0;
+ }
+
+ // insert fake EOB token to cover the split between planes or zzi
+ if (blocks_ended)
+ dct_tokens[j++] = blocks_ended << 2;
+
+ while (coeff_i < num_coeffs && get_bits_left(gb) > 0) {
+ /* decode a VLC into a token */
+ token = get_vlc2(gb, vlc_table, 11, 3);
+ /* use the token to get a zero run, a coefficient, and an eob run */
+ if ((unsigned) token <= 6U) {
+ eob_run = eob_run_base[token];
+ if (eob_run_get_bits[token])
+ eob_run += get_bits(gb, eob_run_get_bits[token]);
+
+ // record only the number of blocks ended in this plane,
+ // any spill will be recorded in the next plane.
+ if (eob_run > num_coeffs - coeff_i) {
+ dct_tokens[j++] = TOKEN_EOB(num_coeffs - coeff_i);
+ blocks_ended += num_coeffs - coeff_i;
+ eob_run -= num_coeffs - coeff_i;
+ coeff_i = num_coeffs;
+ } else {
+ dct_tokens[j++] = TOKEN_EOB(eob_run);
+ blocks_ended += eob_run;
+ coeff_i += eob_run;
+ eob_run = 0;
+ }
+ } else if (token >= 0) {
+ bits_to_get = coeff_get_bits[token];
+ if (bits_to_get)
+ bits_to_get = get_bits(gb, bits_to_get);
+ coeff = coeff_tables[token][bits_to_get];
+
+ zero_run = zero_run_base[token];
+ if (zero_run_get_bits[token])
+ zero_run += get_bits(gb, zero_run_get_bits[token]);
+
+ if (zero_run) {
+ dct_tokens[j++] = TOKEN_ZERO_RUN(coeff, zero_run);
+ } else {
+ // Save DC into the fragment structure. DC prediction is
+ // done in raster order, so the actual DC can't be in with
+ // other tokens. We still need the token in dct_tokens[]
+ // however, or else the structure collapses on itself.
+ if (!coeff_index)
+ all_fragments[coded_fragment_list[coeff_i]].dc = coeff;
+
+ dct_tokens[j++] = TOKEN_COEFF(coeff);
+ }
+
+ if (coeff_index + zero_run > 64) {
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "Invalid zero run of %d with %d coeffs left\n",
+ zero_run, 64 - coeff_index);
+ zero_run = 64 - coeff_index;
+ }
+
+ // zero runs code multiple coefficients,
+ // so don't try to decode coeffs for those higher levels
+ for (i = coeff_index + 1; i <= coeff_index + zero_run; i++)
+ s->num_coded_frags[plane][i]--;
+ coeff_i++;
+ } else {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid token %d\n", token);
+ return -1;
+ }
+ }
+
+ if (blocks_ended > s->num_coded_frags[plane][coeff_index])
+ av_log(s->avctx, AV_LOG_ERROR, "More blocks ended than coded!\n");
+
+ // decrement the number of blocks that have higher coefficients for each
+ // EOB run at this level
+ if (blocks_ended)
+ for (i = coeff_index + 1; i < 64; i++)
+ s->num_coded_frags[plane][i] -= blocks_ended;
+
+ // setup the next buffer
+ if (plane < 2)
+ s->dct_tokens[plane + 1][coeff_index] = dct_tokens + j;
+ else if (coeff_index < 63)
+ s->dct_tokens[0][coeff_index + 1] = dct_tokens + j;
+
+ return eob_run;
+}
+
+static void reverse_dc_prediction(Vp3DecodeContext *s,
+ int first_fragment,
+ int fragment_width,
+ int fragment_height);
+/*
+ * This function unpacks all of the DCT coefficient data from the
+ * bitstream.
+ */
+static int unpack_dct_coeffs(Vp3DecodeContext *s, GetBitContext *gb)
+{
+ int i;
+ int dc_y_table;
+ int dc_c_table;
+ int ac_y_table;
+ int ac_c_table;
+ int residual_eob_run = 0;
+ VLC *y_tables[64];
+ VLC *c_tables[64];
+
+ s->dct_tokens[0][0] = s->dct_tokens_base;
+
+ if (get_bits_left(gb) < 16)
+ return AVERROR_INVALIDDATA;
+
+ /* fetch the DC table indexes */
+ dc_y_table = get_bits(gb, 4);
+ 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,
+ 0, residual_eob_run);
+ if (residual_eob_run < 0)
+ return residual_eob_run;
+ if (get_bits_left(gb) < 8)
+ return AVERROR_INVALIDDATA;
+
+ /* reverse prediction of the Y-plane DC coefficients */
+ 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,
+ 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,
+ 2, residual_eob_run);
+ if (residual_eob_run < 0)
+ return residual_eob_run;
+
+ /* reverse prediction of the C-plane DC coefficients */
+ if (!(s->avctx->flags & AV_CODEC_FLAG_GRAY)) {
+ reverse_dc_prediction(s, s->fragment_start[1],
+ s->fragment_width[1], s->fragment_height[1]);
+ reverse_dc_prediction(s, s->fragment_start[2],
+ s->fragment_width[1], s->fragment_height[1]);
+ }
+
+ if (get_bits_left(gb) < 8)
+ return AVERROR_INVALIDDATA;
+ /* fetch the AC table indexes */
+ ac_y_table = get_bits(gb, 4);
+ ac_c_table = get_bits(gb, 4);
+
+ /* 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];
+ }
+ 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];
+ }
+ 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];
+ }
+ 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];
+ }
+
+ /* decode all AC coefficents */
+ for (i = 1; i <= 63; i++) {
+ residual_eob_run = unpack_vlcs(s, gb, y_tables[i], i,
+ 0, residual_eob_run);
+ if (residual_eob_run < 0)
+ return residual_eob_run;
+
+ residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i,
+ 1, residual_eob_run);
+ if (residual_eob_run < 0)
+ return residual_eob_run;
+ residual_eob_run = unpack_vlcs(s, gb, c_tables[i], i,
+ 2, residual_eob_run);
+ if (residual_eob_run < 0)
+ return residual_eob_run;
+ }
+
+ return 0;
+}
+
+/*
+ * This function reverses the DC prediction for each coded fragment in
+ * the frame. Much of this function is adapted directly from the original
+ * VP3 source code.
+ */
+#define COMPATIBLE_FRAME(x) \
+ (compatible_frame[s->all_fragments[x].coding_method] == current_frame_type)
+#define DC_COEFF(u) s->all_fragments[u].dc
+
+static void reverse_dc_prediction(Vp3DecodeContext *s,
+ int first_fragment,
+ int fragment_width,
+ int fragment_height)
+{
+#define PUL 8
+#define PU 4
+#define PUR 2
+#define PL 1
+
+ int x, y;
+ int i = first_fragment;
+
+ int predicted_dc;
+
+ /* DC values for the left, up-left, up, and up-right fragments */
+ int vl, vul, vu, vur;
+
+ /* indexes for the left, up-left, up, and up-right fragments */
+ int l, ul, u, ur;
+
+ /*
+ * The 6 fields mean:
+ * 0: up-left multiplier
+ * 1: up multiplier
+ * 2: up-right multiplier
+ * 3: left multiplier
+ */
+ static const int predictor_transform[16][4] = {
+ { 0, 0, 0, 0 },
+ { 0, 0, 0, 128 }, // PL
+ { 0, 0, 128, 0 }, // PUR
+ { 0, 0, 53, 75 }, // PUR|PL
+ { 0, 128, 0, 0 }, // PU
+ { 0, 64, 0, 64 }, // PU |PL
+ { 0, 128, 0, 0 }, // PU |PUR
+ { 0, 0, 53, 75 }, // PU |PUR|PL
+ { 128, 0, 0, 0 }, // PUL
+ { 0, 0, 0, 128 }, // PUL|PL
+ { 64, 0, 64, 0 }, // PUL|PUR
+ { 0, 0, 53, 75 }, // PUL|PUR|PL
+ { 0, 128, 0, 0 }, // PUL|PU
+ { -104, 116, 0, 116 }, // PUL|PU |PL
+ { 24, 80, 24, 0 }, // PUL|PU |PUR
+ { -104, 116, 0, 116 } // PUL|PU |PUR|PL
+ };
+
+ /* This table shows which types of blocks can use other blocks for
+ * prediction. For example, INTRA is the only mode in this table to
+ * have a frame number of 0. That means INTRA blocks can only predict
+ * from other INTRA blocks. There are 2 golden frame coding types;
+ * blocks encoding in these modes can only predict from other blocks
+ * that were encoded with these 1 of these 2 modes. */
+ static const unsigned char compatible_frame[9] = {
+ 1, /* MODE_INTER_NO_MV */
+ 0, /* MODE_INTRA */
+ 1, /* MODE_INTER_PLUS_MV */
+ 1, /* MODE_INTER_LAST_MV */
+ 1, /* MODE_INTER_PRIOR_MV */
+ 2, /* MODE_USING_GOLDEN */
+ 2, /* MODE_GOLDEN_MV */
+ 1, /* MODE_INTER_FOUR_MV */
+ 3 /* MODE_COPY */
+ };
+ int current_frame_type;
+
+ /* there is a last DC predictor for each of the 3 frame types */
+ short last_dc[3];
+
+ int transform = 0;
+
+ vul =
+ vu =
+ vur =
+ vl = 0;
+ last_dc[0] =
+ last_dc[1] =
+ last_dc[2] = 0;
+
+ /* for each fragment row... */
+ for (y = 0; y < fragment_height; y++) {
+ /* for each fragment in a row... */
+ for (x = 0; x < fragment_width; x++, i++) {
+
+ /* reverse prediction if this block was coded */
+ if (s->all_fragments[i].coding_method != MODE_COPY) {
+ current_frame_type =
+ compatible_frame[s->all_fragments[i].coding_method];
+
+ transform = 0;
+ if (x) {
+ l = i - 1;
+ vl = DC_COEFF(l);
+ if (COMPATIBLE_FRAME(l))
+ transform |= PL;
+ }
+ if (y) {
+ u = i - fragment_width;
+ vu = DC_COEFF(u);
+ if (COMPATIBLE_FRAME(u))
+ transform |= PU;
+ if (x) {
+ ul = i - fragment_width - 1;
+ vul = DC_COEFF(ul);
+ if (COMPATIBLE_FRAME(ul))
+ transform |= PUL;
+ }
+ if (x + 1 < fragment_width) {
+ ur = i - fragment_width + 1;
+ vur = DC_COEFF(ur);
+ if (COMPATIBLE_FRAME(ur))
+ transform |= PUR;
+ }
+ }
+
+ if (transform == 0) {
+ /* if there were no fragments to predict from, use last
+ * DC saved */
+ predicted_dc = last_dc[current_frame_type];
+ } else {
+ /* apply the appropriate predictor transform */
+ predicted_dc =
+ (predictor_transform[transform][0] * vul) +
+ (predictor_transform[transform][1] * vu) +
+ (predictor_transform[transform][2] * vur) +
+ (predictor_transform[transform][3] * vl);
+
+ predicted_dc /= 128;
+
+ /* check for outranging on the [ul u l] and
+ * [ul u ur l] predictors */
+ if ((transform == 15) || (transform == 13)) {
+ if (FFABS(predicted_dc - vu) > 128)
+ predicted_dc = vu;
+ else if (FFABS(predicted_dc - vl) > 128)
+ predicted_dc = vl;
+ else if (FFABS(predicted_dc - vul) > 128)
+ predicted_dc = vul;
+ }
+ }
+
+ /* at long last, apply the predictor */
+ DC_COEFF(i) += predicted_dc;
+ /* save the DC */
+ last_dc[current_frame_type] = DC_COEFF(i);
+ }
+ }
+ }
+}
+
+static void apply_loop_filter(Vp3DecodeContext *s, int plane,
+ int ystart, int yend)
+{
+ int x, y;
+ int *bounding_values = s->bounding_values_array + 127;
+
+ int width = s->fragment_width[!!plane];
+ int height = s->fragment_height[!!plane];
+ int fragment = s->fragment_start[plane] + ystart * width;
+ ptrdiff_t stride = s->current_frame.f->linesize[plane];
+ uint8_t *plane_data = s->current_frame.f->data[plane];
+ if (!s->flipped_image)
+ stride = -stride;
+ plane_data += s->data_offset[plane] + 8 * ystart * stride;
+
+ for (y = ystart; y < yend; y++) {
+ for (x = 0; x < width; x++) {
+ /* This code basically just deblocks on the edges of coded blocks.
+ * However, it has to be much more complicated because of the
+ * braindamaged deblock ordering used in VP3/Theora. Order matters
+ * because some pixels get filtered twice. */
+ if (s->all_fragments[fragment].coding_method != MODE_COPY) {
+ /* do not perform left edge filter for left columns frags */
+ if (x > 0) {
+ s->vp3dsp.h_loop_filter(
+ plane_data + 8 * x,
+ stride, bounding_values);
+ }
+
+ /* do not perform top edge filter for top row fragments */
+ if (y > 0) {
+ s->vp3dsp.v_loop_filter(
+ plane_data + 8 * x,
+ stride, bounding_values);
+ }
+
+ /* do not perform right edge filter for right column
+ * fragments or if right fragment neighbor is also coded
+ * in this frame (it will be filtered in next iteration) */
+ if ((x < width - 1) &&
+ (s->all_fragments[fragment + 1].coding_method == MODE_COPY)) {
+ s->vp3dsp.h_loop_filter(
+ plane_data + 8 * x + 8,
+ stride, bounding_values);
+ }
+
+ /* do not perform bottom edge filter for bottom row
+ * fragments or if bottom fragment neighbor is also coded
+ * in this frame (it will be filtered in the next row) */
+ if ((y < height - 1) &&
+ (s->all_fragments[fragment + width].coding_method == MODE_COPY)) {
+ s->vp3dsp.v_loop_filter(
+ plane_data + 8 * x + 8 * stride,
+ stride, bounding_values);
+ }
+ }
+
+ fragment++;
+ }
+ plane_data += 8 * stride;
+ }
+}
+
+/**
+ * Pull DCT tokens from the 64 levels to decode and dequant the coefficients
+ * for the next block in coding order
+ */
+static inline int vp3_dequant(Vp3DecodeContext *s, Vp3Fragment *frag,
+ int plane, int inter, int16_t block[64])
+{
+ int16_t *dequantizer = s->qmat[frag->qpi][inter][plane];
+ uint8_t *perm = s->idct_scantable;
+ int i = 0;
+
+ do {
+ int token = *s->dct_tokens[plane][i];
+ switch (token & 3) {
+ case 0: // EOB
+ if (--token < 4) // 0-3 are token types so the EOB run must now be 0
+ s->dct_tokens[plane][i]++;
+ else
+ *s->dct_tokens[plane][i] = token & ~3;
+ goto end;
+ case 1: // zero run
+ s->dct_tokens[plane][i]++;
+ i += (token >> 2) & 0x7f;
+ if (i > 63) {
+ av_log(s->avctx, AV_LOG_ERROR, "Coefficient index overflow\n");
+ return i;
+ }
+ block[perm[i]] = (token >> 9) * dequantizer[perm[i]];
+ i++;
+ break;
+ case 2: // coeff
+ block[perm[i]] = (token >> 2) * dequantizer[perm[i]];
+ s->dct_tokens[plane][i++]++;
+ break;
+ default: // shouldn't happen
+ return i;
+ }
+ } while (i < 64);
+ // return value is expected to be a valid level
+ i--;
+end:
+ // the actual DC+prediction is in the fragment structure
+ block[0] = frag->dc * s->qmat[0][inter][plane][0];
+ return i;
+}
+
+/**
+ * called when all pixels up to row y are complete
+ */
+static void vp3_draw_horiz_band(Vp3DecodeContext *s, int y)
+{
+ int h, cy, i;
+ int offset[AV_NUM_DATA_POINTERS];
+
+ if (HAVE_THREADS && s->avctx->active_thread_type & FF_THREAD_FRAME) {
+ int y_flipped = s->flipped_image ? s->height - y : y;
+
+ /* At the end of the frame, report INT_MAX instead of the height of
+ * the frame. This makes the other threads' ff_thread_await_progress()
+ * calls cheaper, because they don't have to clip their values. */
+ ff_thread_report_progress(&s->current_frame,
+ y_flipped == s->height ? INT_MAX
+ : y_flipped - 1,
+ 0);
+ }
+
+ if (!s->avctx->draw_horiz_band)
+ return;
+
+ h = y - s->last_slice_end;
+ s->last_slice_end = y;
+ y -= h;
+
+ if (!s->flipped_image)
+ y = s->height - y - h;
+
+ cy = y >> s->chroma_y_shift;
+ offset[0] = s->current_frame.f->linesize[0] * y;
+ offset[1] = s->current_frame.f->linesize[1] * cy;
+ offset[2] = s->current_frame.f->linesize[2] * cy;
+ for (i = 3; i < AV_NUM_DATA_POINTERS; i++)
+ offset[i] = 0;
+
+ emms_c();
+ s->avctx->draw_horiz_band(s->avctx, s->current_frame.f, offset, y, 3, h);
+}
+
+/**
+ * Wait for the reference frame of the current fragment.
+ * The progress value is in luma pixel rows.
+ */
+static void await_reference_row(Vp3DecodeContext *s, Vp3Fragment *fragment,
+ int motion_y, int y)
+{
+ ThreadFrame *ref_frame;
+ int ref_row;
+ int border = motion_y & 1;
+
+ if (fragment->coding_method == MODE_USING_GOLDEN ||
+ fragment->coding_method == MODE_GOLDEN_MV)
+ ref_frame = &s->golden_frame;
+ else
+ ref_frame = &s->last_frame;
+
+ ref_row = y + (motion_y >> 1);
+ ref_row = FFMAX(FFABS(ref_row), ref_row + 8 + border);
+
+ ff_thread_await_progress(ref_frame, ref_row, 0);
+}
+
+/*
+ * Perform the final rendering for a particular slice of data.
+ * The slice number ranges from 0..(c_superblock_height - 1).
+ */
+static void render_slice(Vp3DecodeContext *s, int slice)
+{
+ int x, y, i, j, fragment;
+ int16_t *block = s->block;
+ int motion_x = 0xdeadbeef, motion_y = 0xdeadbeef;
+ int motion_halfpel_index;
+ uint8_t *motion_source;
+ int plane, first_pixel;
+
+ if (slice >= s->c_superblock_height)
+ return;
+
+ for (plane = 0; plane < 3; plane++) {
+ uint8_t *output_plane = s->current_frame.f->data[plane] +
+ s->data_offset[plane];
+ uint8_t *last_plane = s->last_frame.f->data[plane] +
+ s->data_offset[plane];
+ uint8_t *golden_plane = s->golden_frame.f->data[plane] +
+ s->data_offset[plane];
+ ptrdiff_t stride = s->current_frame.f->linesize[plane];
+ int plane_width = s->width >> (plane && s->chroma_x_shift);
+ int plane_height = s->height >> (plane && s->chroma_y_shift);
+ int8_t(*motion_val)[2] = s->motion_val[!!plane];
+
+ int sb_x, sb_y = slice << (!plane && s->chroma_y_shift);
+ int slice_height = sb_y + 1 + (!plane && s->chroma_y_shift);
+ int slice_width = plane ? s->c_superblock_width
+ : s->y_superblock_width;
+
+ int fragment_width = s->fragment_width[!!plane];
+ int fragment_height = s->fragment_height[!!plane];
+ int fragment_start = s->fragment_start[plane];
+
+ int do_await = !plane && HAVE_THREADS &&
+ (s->avctx->active_thread_type & FF_THREAD_FRAME);
+
+ if (!s->flipped_image)
+ stride = -stride;
+ if (CONFIG_GRAY && plane && (s->avctx->flags & AV_CODEC_FLAG_GRAY))
+ continue;
+
+ /* for each superblock row in the slice (both of them)... */
+ for (; sb_y < slice_height; sb_y++) {
+ /* for each superblock in a row... */
+ for (sb_x = 0; sb_x < slice_width; sb_x++) {
+ /* for each block in a superblock... */
+ for (j = 0; j < 16; j++) {
+ x = 4 * sb_x + hilbert_offset[j][0];
+ y = 4 * sb_y + hilbert_offset[j][1];
+ fragment = y * fragment_width + x;
+
+ i = fragment_start + fragment;
+
+ // bounds check
+ if (x >= fragment_width || y >= fragment_height)
+ continue;
+
+ first_pixel = 8 * y * stride + 8 * x;
+
+ if (do_await &&
+ s->all_fragments[i].coding_method != MODE_INTRA)
+ await_reference_row(s, &s->all_fragments[i],
+ motion_val[fragment][1],
+ (16 * y) >> s->chroma_y_shift);
+
+ /* transform if this block was coded */
+ if (s->all_fragments[i].coding_method != MODE_COPY) {
+ if ((s->all_fragments[i].coding_method == MODE_USING_GOLDEN) ||
+ (s->all_fragments[i].coding_method == MODE_GOLDEN_MV))
+ motion_source = golden_plane;
+ else
+ motion_source = last_plane;
+
+ motion_source += first_pixel;
+ motion_halfpel_index = 0;
+
+ /* sort out the motion vector if this fragment is coded
+ * using a motion vector method */
+ if ((s->all_fragments[i].coding_method > MODE_INTRA) &&
+ (s->all_fragments[i].coding_method != MODE_USING_GOLDEN)) {
+ int src_x, src_y;
+ motion_x = motion_val[fragment][0];
+ motion_y = motion_val[fragment][1];
+
+ src_x = (motion_x >> 1) + 8 * x;
+ src_y = (motion_y >> 1) + 8 * y;
+
+ motion_halfpel_index = motion_x & 0x01;
+ motion_source += (motion_x >> 1);
+
+ motion_halfpel_index |= (motion_y & 0x01) << 1;
+ motion_source += ((motion_y >> 1) * stride);
+
+ if (src_x < 0 || src_y < 0 ||
+ src_x + 9 >= plane_width ||
+ src_y + 9 >= plane_height) {
+ uint8_t *temp = s->edge_emu_buffer;
+ if (stride < 0)
+ temp -= 8 * stride;
+
+ s->vdsp.emulated_edge_mc(temp, motion_source,
+ stride, stride,
+ 9, 9, src_x, src_y,
+ plane_width,
+ plane_height);
+ motion_source = temp;
+ }
+ }
+
+ /* first, take care of copying a block from either the
+ * previous or the golden frame */
+ if (s->all_fragments[i].coding_method != MODE_INTRA) {
+ /* Note, it is possible to implement all MC cases
+ * with put_no_rnd_pixels_l2 which would look more
+ * like the VP3 source but this would be slower as
+ * put_no_rnd_pixels_tab is better optimzed */
+ if (motion_halfpel_index != 3) {
+ s->hdsp.put_no_rnd_pixels_tab[1][motion_halfpel_index](
+ output_plane + first_pixel,
+ motion_source, stride, 8);
+ } else {
+ /* d is 0 if motion_x and _y have the same sign,
+ * else -1 */
+ int d = (motion_x ^ motion_y) >> 31;
+ s->vp3dsp.put_no_rnd_pixels_l2(output_plane + first_pixel,
+ motion_source - d,
+ motion_source + stride + 1 + d,
+ stride, 8);
+ }
+ }
+
+ /* invert DCT and place (or add) in final output */
+
+ if (s->all_fragments[i].coding_method == MODE_INTRA) {
+ vp3_dequant(s, s->all_fragments + i,
+ plane, 0, block);
+ s->vp3dsp.idct_put(output_plane + first_pixel,
+ stride,
+ block);
+ } else {
+ if (vp3_dequant(s, s->all_fragments + i,
+ plane, 1, block)) {
+ s->vp3dsp.idct_add(output_plane + first_pixel,
+ stride,
+ block);
+ } else {
+ s->vp3dsp.idct_dc_add(output_plane + first_pixel,
+ stride, block);
+ }
+ }
+ } else {
+ /* copy directly from the previous frame */
+ s->hdsp.put_pixels_tab[1][0](
+ output_plane + first_pixel,
+ last_plane + first_pixel,
+ stride, 8);
+ }
+ }
+ }
+
+ // Filter up to the last row in the superblock row
+ if (!s->skip_loop_filter)
+ apply_loop_filter(s, plane, 4 * sb_y - !!sb_y,
+ FFMIN(4 * sb_y + 3, fragment_height - 1));
+ }
+ }
+
+ /* this looks like a good place for slice dispatch... */
+ /* algorithm:
+ * if (slice == s->macroblock_height - 1)
+ * dispatch (both last slice & 2nd-to-last slice);
+ * else if (slice > 0)
+ * dispatch (slice - 1);
+ */
+
+ vp3_draw_horiz_band(s, FFMIN((32 << s->chroma_y_shift) * (slice + 1) - 16,
+ s->height - 16));
+}
+
+/// Allocate tables for per-frame data in Vp3DecodeContext
+static av_cold int allocate_tables(AVCodecContext *avctx)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+ int y_fragment_count, c_fragment_count;
+
+ free_tables(avctx);
+
+ y_fragment_count = s->fragment_width[0] * s->fragment_height[0];
+ c_fragment_count = s->fragment_width[1] * s->fragment_height[1];
+
+ s->superblock_coding = av_mallocz(s->superblock_count);
+ s->all_fragments = av_mallocz_array(s->fragment_count, sizeof(Vp3Fragment));
+
+ s->coded_fragment_list[0] = av_mallocz_array(s->fragment_count, sizeof(int));
+
+ s->dct_tokens_base = av_mallocz_array(s->fragment_count,
+ 64 * sizeof(*s->dct_tokens_base));
+ s->motion_val[0] = av_mallocz_array(y_fragment_count, sizeof(*s->motion_val[0]));
+ s->motion_val[1] = av_mallocz_array(c_fragment_count, sizeof(*s->motion_val[1]));
+
+ /* work out the block mapping tables */
+ s->superblock_fragments = av_mallocz_array(s->superblock_count, 16 * sizeof(int));
+ s->macroblock_coding = av_mallocz(s->macroblock_count + 1);
+
+ if (!s->superblock_coding || !s->all_fragments ||
+ !s->dct_tokens_base || !s->coded_fragment_list[0] ||
+ !s->superblock_fragments || !s->macroblock_coding ||
+ !s->motion_val[0] || !s->motion_val[1]) {
+ vp3_decode_end(avctx);
+ return -1;
+ }
+
+ init_block_mapping(s);
+
+ return 0;
+}
+
+static av_cold int init_frames(Vp3DecodeContext *s)
+{
+ s->current_frame.f = av_frame_alloc();
+ 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);
+ return AVERROR(ENOMEM);
+ }
+
+ return 0;
+}
+
+static av_cold int vp3_decode_init(AVCodecContext *avctx)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+ int i, inter, plane, ret;
+ int c_width;
+ int c_height;
+ int y_fragment_count, c_fragment_count;
+
+ ret = init_frames(s);
+ if (ret < 0)
+ return ret;
+
+ avctx->internal->allocate_progress = 1;
+
+ if (avctx->codec_tag == MKTAG('V', 'P', '3', '0'))
+ s->version = 0;
+ else
+ s->version = 1;
+
+ s->avctx = avctx;
+ s->width = FFALIGN(avctx->coded_width, 16);
+ s->height = FFALIGN(avctx->coded_height, 16);
+ if (avctx->codec_id != AV_CODEC_ID_THEORA)
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+ avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
+ ff_hpeldsp_init(&s->hdsp, avctx->flags | AV_CODEC_FLAG_BITEXACT);
+ ff_videodsp_init(&s->vdsp, 8);
+ ff_vp3dsp_init(&s->vp3dsp, avctx->flags);
+
+ for (i = 0; i < 64; i++) {
+#define TRANSPOSE(x) (((x) >> 3) | (((x) & 7) << 3))
+ s->idct_permutation[i] = TRANSPOSE(i);
+ s->idct_scantable[i] = TRANSPOSE(ff_zigzag_direct[i]);
+#undef TRANSPOSE
+ }
+
+ /* initialize to an impossible value which will force a recalculation
+ * in the first frame decode */
+ for (i = 0; i < 3; i++)
+ s->qps[i] = -1;
+
+ avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift);
+
+ s->y_superblock_width = (s->width + 31) / 32;
+ s->y_superblock_height = (s->height + 31) / 32;
+ s->y_superblock_count = s->y_superblock_width * s->y_superblock_height;
+
+ /* work out the dimensions for the C planes */
+ c_width = s->width >> s->chroma_x_shift;
+ c_height = s->height >> s->chroma_y_shift;
+ s->c_superblock_width = (c_width + 31) / 32;
+ s->c_superblock_height = (c_height + 31) / 32;
+ s->c_superblock_count = s->c_superblock_width * s->c_superblock_height;
+
+ s->superblock_count = s->y_superblock_count + (s->c_superblock_count * 2);
+ s->u_superblock_start = s->y_superblock_count;
+ s->v_superblock_start = s->u_superblock_start + s->c_superblock_count;
+
+ s->macroblock_width = (s->width + 15) / 16;
+ s->macroblock_height = (s->height + 15) / 16;
+ s->macroblock_count = s->macroblock_width * s->macroblock_height;
+
+ s->fragment_width[0] = s->width / FRAGMENT_PIXELS;
+ s->fragment_height[0] = s->height / FRAGMENT_PIXELS;
+ s->fragment_width[1] = s->fragment_width[0] >> s->chroma_x_shift;
+ s->fragment_height[1] = s->fragment_height[0] >> s->chroma_y_shift;
+
+ /* fragment count covers all 8x8 blocks for all 3 planes */
+ y_fragment_count = s->fragment_width[0] * s->fragment_height[0];
+ c_fragment_count = s->fragment_width[1] * s->fragment_height[1];
+ s->fragment_count = y_fragment_count + 2 * c_fragment_count;
+ s->fragment_start[1] = y_fragment_count;
+ s->fragment_start[2] = y_fragment_count + c_fragment_count;
+
+ if (!s->theora_tables) {
+ for (i = 0; i < 64; i++) {
+ s->coded_dc_scale_factor[i] = vp31_dc_scale_factor[i];
+ s->coded_ac_scale_factor[i] = vp31_ac_scale_factor[i];
+ s->base_matrix[0][i] = vp31_intra_y_dequant[i];
+ s->base_matrix[1][i] = vp31_intra_c_dequant[i];
+ s->base_matrix[2][i] = vp31_inter_dequant[i];
+ s->filter_limit_values[i] = vp31_filter_limit_values[i];
+ }
+
+ for (inter = 0; inter < 2; inter++) {
+ for (plane = 0; plane < 3; plane++) {
+ s->qr_count[inter][plane] = 1;
+ s->qr_size[inter][plane][0] = 63;
+ s->qr_base[inter][plane][0] =
+ s->qr_base[inter][plane][1] = 2 * inter + (!!plane) * !inter;
+ }
+ }
+
+ /* init VLC tables */
+ 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);
+ }
+ } 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;
+
+ /* 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;
+ }
+ }
+
+ 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);
+
+ 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);
+
+ 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);
+
+ 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);
+
+ 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
+static int update_frames(AVCodecContext *avctx)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+ int ret = 0;
+
+ /* shuffle frames (last = current) */
+ ff_thread_release_buffer(avctx, &s->last_frame);
+ ret = ff_thread_ref_frame(&s->last_frame, &s->current_frame);
+ if (ret < 0)
+ goto fail;
+
+ if (s->keyframe) {
+ ff_thread_release_buffer(avctx, &s->golden_frame);
+ ret = ff_thread_ref_frame(&s->golden_frame, &s->current_frame);
+ }
+
+fail:
+ ff_thread_release_buffer(avctx, &s->current_frame);
+ return ret;
+}
+
+static int ref_frame(Vp3DecodeContext *s, ThreadFrame *dst, ThreadFrame *src)
+{
+ ff_thread_release_buffer(s->avctx, dst);
+ if (src->f->data[0])
+ return ff_thread_ref_frame(dst, src);
+ return 0;
+}
+
+static int ref_frames(Vp3DecodeContext *dst, Vp3DecodeContext *src)
+{
+ int ret;
+ if ((ret = ref_frame(dst, &dst->current_frame, &src->current_frame)) < 0 ||
+ (ret = ref_frame(dst, &dst->golden_frame, &src->golden_frame)) < 0 ||
+ (ret = ref_frame(dst, &dst->last_frame, &src->last_frame)) < 0)
+ return ret;
+ return 0;
+}
+
+static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
+{
+ Vp3DecodeContext *s = dst->priv_data, *s1 = src->priv_data;
+ int qps_changed = 0, i, err;
+
+#define copy_fields(to, from, start_field, end_field) \
+ memcpy(&to->start_field, &from->start_field, \
+ (char *) &to->end_field - (char *) &to->start_field)
+
+ if (!s1->current_frame.f->data[0] ||
+ s->width != s1->width || s->height != s1->height) {
+ if (s != s1)
+ ref_frames(s, s1);
+ return -1;
+ }
+
+ if (s != s1) {
+ if (!s->current_frame.f)
+ return AVERROR(ENOMEM);
+ // init tables if the first frame hasn't been decoded
+ if (!s->current_frame.f->data[0]) {
+ int y_fragment_count, c_fragment_count;
+ s->avctx = dst;
+ err = allocate_tables(dst);
+ if (err)
+ return err;
+ y_fragment_count = s->fragment_width[0] * s->fragment_height[0];
+ c_fragment_count = s->fragment_width[1] * s->fragment_height[1];
+ memcpy(s->motion_val[0], s1->motion_val[0],
+ y_fragment_count * sizeof(*s->motion_val[0]));
+ memcpy(s->motion_val[1], s1->motion_val[1],
+ c_fragment_count * sizeof(*s->motion_val[1]));
+ }
+
+ // copy previous frame data
+ if ((err = ref_frames(s, s1)) < 0)
+ return err;
+
+ s->keyframe = s1->keyframe;
+
+ // copy qscale data if necessary
+ for (i = 0; i < 3; i++) {
+ if (s->qps[i] != s1->qps[1]) {
+ qps_changed = 1;
+ memcpy(&s->qmat[i], &s1->qmat[i], sizeof(s->qmat[i]));
+ }
+ }
+
+ if (s->qps[0] != s1->qps[0])
+ memcpy(&s->bounding_values_array, &s1->bounding_values_array,
+ sizeof(s->bounding_values_array));
+
+ if (qps_changed)
+ copy_fields(s, s1, qps, superblock_count);
+#undef copy_fields
+ }
+
+ return update_frames(dst);
+}
+
+static int vp3_decode_frame(AVCodecContext *avctx,
+ void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ Vp3DecodeContext *s = avctx->priv_data;
+ GetBitContext gb;
+ int i, ret;
+
+ if ((ret = init_get_bits8(&gb, buf, buf_size)) < 0)
+ return ret;
+
+#if CONFIG_THEORA_DECODER
+ if (s->theora && get_bits1(&gb)) {
+ int type = get_bits(&gb, 7);
+ skip_bits_long(&gb, 6*8); /* "theora" */
+
+ if (s->avctx->active_thread_type&FF_THREAD_FRAME) {
+ av_log(avctx, AV_LOG_ERROR, "midstream reconfiguration with multithreading is unsupported, try -threads 1\n");
+ return AVERROR_PATCHWELCOME;
+ }
+ if (type == 0) {
+ vp3_decode_end(avctx);
+ ret = theora_decode_header(avctx, &gb);
+
+ if (ret >= 0)
+ ret = vp3_decode_init(avctx);
+ if (ret < 0) {
+ vp3_decode_end(avctx);
+ return ret;
+ }
+ return buf_size;
+ } else if (type == 2) {
+ ret = theora_decode_tables(avctx, &gb);
+ if (ret >= 0)
+ ret = vp3_decode_init(avctx);
+ if (ret < 0) {
+ vp3_decode_end(avctx);
+ return ret;
+ }
+ return buf_size;
+ }
+
+ av_log(avctx, AV_LOG_ERROR,
+ "Header packet passed to frame decoder, skipping\n");
+ return -1;
+ }
+#endif
+
+ s->keyframe = !get_bits1(&gb);
+ if (!s->all_fragments) {
+ av_log(avctx, AV_LOG_ERROR, "Data packet without prior valid headers\n");
+ return -1;
+ }
+ if (!s->theora)
+ skip_bits(&gb, 1);
+ for (i = 0; i < 3; i++)
+ s->last_qps[i] = s->qps[i];
+
+ s->nqps = 0;
+ do {
+ s->qps[s->nqps++] = get_bits(&gb, 6);
+ } while (s->theora >= 0x030200 && s->nqps < 3 && get_bits1(&gb));
+ for (i = s->nqps; i < 3; i++)
+ s->qps[i] = -1;
+
+ if (s->avctx->debug & FF_DEBUG_PICT_INFO)
+ av_log(s->avctx, AV_LOG_INFO, " VP3 %sframe #%d: Q index = %d\n",
+ s->keyframe ? "key" : "", avctx->frame_number + 1, s->qps[0]);
+
+ s->skip_loop_filter = !s->filter_limit_values[s->qps[0]] ||
+ avctx->skip_loop_filter >= (s->keyframe ? AVDISCARD_ALL
+ : AVDISCARD_NONKEY);
+
+ if (s->qps[0] != s->last_qps[0])
+ init_loop_filter(s);
+
+ for (i = 0; i < s->nqps; i++)
+ // reinit all dequantizers if the first one changed, because
+ // the DC of the first quantizer must be used for all matrices
+ if (s->qps[i] != s->last_qps[i] || s->qps[0] != s->last_qps[0])
+ init_dequantizer(s, i);
+
+ if (avctx->skip_frame >= AVDISCARD_NONKEY && !s->keyframe)
+ return buf_size;
+
+ s->current_frame.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I
+ : AV_PICTURE_TYPE_P;
+ s->current_frame.f->key_frame = s->keyframe;
+ if (ff_thread_get_buffer(avctx, &s->current_frame, AV_GET_BUFFER_FLAG_REF) < 0)
+ goto error;
+
+ if (!s->edge_emu_buffer)
+ s->edge_emu_buffer = av_malloc(9 * FFABS(s->current_frame.f->linesize[0]));
+
+ if (s->keyframe) {
+ if (!s->theora) {
+ skip_bits(&gb, 4); /* width code */
+ skip_bits(&gb, 4); /* height code */
+ if (s->version) {
+ s->version = get_bits(&gb, 5);
+ if (avctx->frame_number == 0)
+ av_log(s->avctx, AV_LOG_DEBUG,
+ "VP version: %d\n", s->version);
+ }
+ }
+ if (s->version || s->theora) {
+ if (get_bits1(&gb))
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Warning, unsupported keyframe coding type?!\n");
+ skip_bits(&gb, 2); /* reserved? */
+ }
+ } else {
+ if (!s->golden_frame.f->data[0]) {
+ av_log(s->avctx, AV_LOG_WARNING,
+ "vp3: first frame not a keyframe\n");
+
+ s->golden_frame.f->pict_type = AV_PICTURE_TYPE_I;
+ if (ff_thread_get_buffer(avctx, &s->golden_frame,
+ AV_GET_BUFFER_FLAG_REF) < 0)
+ goto error;
+ ff_thread_release_buffer(avctx, &s->last_frame);
+ if ((ret = ff_thread_ref_frame(&s->last_frame,
+ &s->golden_frame)) < 0)
+ goto error;
+ ff_thread_report_progress(&s->last_frame, INT_MAX, 0);
+ }
+ }
+
+ memset(s->all_fragments, 0, s->fragment_count * sizeof(Vp3Fragment));
+ ff_thread_finish_setup(avctx);
+
+ if (unpack_superblocks(s, &gb)) {
+ av_log(s->avctx, AV_LOG_ERROR, "error in unpack_superblocks\n");
+ goto error;
+ }
+ if (unpack_modes(s, &gb)) {
+ av_log(s->avctx, AV_LOG_ERROR, "error in unpack_modes\n");
+ goto error;
+ }
+ if (unpack_vectors(s, &gb)) {
+ av_log(s->avctx, AV_LOG_ERROR, "error in unpack_vectors\n");
+ goto error;
+ }
+ if (unpack_block_qpis(s, &gb)) {
+ av_log(s->avctx, AV_LOG_ERROR, "error in unpack_block_qpis\n");
+ goto error;
+ }
+ if (unpack_dct_coeffs(s, &gb)) {
+ av_log(s->avctx, AV_LOG_ERROR, "error in unpack_dct_coeffs\n");
+ goto error;
+ }
+
+ for (i = 0; i < 3; i++) {
+ int height = s->height >> (i && s->chroma_y_shift);
+ if (s->flipped_image)
+ s->data_offset[i] = 0;
+ else
+ s->data_offset[i] = (height - 1) * s->current_frame.f->linesize[i];
+ }
+
+ s->last_slice_end = 0;
+ for (i = 0; i < s->c_superblock_height; i++)
+ render_slice(s, i);
+
+ // filter the last row
+ for (i = 0; i < 3; i++) {
+ int row = (s->height >> (3 + (i && s->chroma_y_shift))) - 1;
+ apply_loop_filter(s, i, row, row + 1);
+ }
+ vp3_draw_horiz_band(s, s->height);
+
+ /* output frame, offset as needed */
+ if ((ret = av_frame_ref(data, s->current_frame.f)) < 0)
+ return ret;
+ for (i = 0; i < 3; i++) {
+ AVFrame *dst = data;
+ int off = (s->offset_x >> (i && s->chroma_y_shift)) +
+ (s->offset_y >> (i && s->chroma_y_shift)) * dst->linesize[i];
+ dst->data[i] += off;
+ }
+ *got_frame = 1;
+
+ if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_FRAME)) {
+ ret = update_frames(avctx);
+ if (ret < 0)
+ return ret;
+ }
+
+ return buf_size;
+
+error:
+ ff_thread_report_progress(&s->current_frame, INT_MAX, 0);
+
+ if (!HAVE_THREADS || !(s->avctx->active_thread_type & FF_THREAD_FRAME))
+ av_frame_unref(s->current_frame.f);
+
+ return -1;
+}
+
+static int read_huffman_tree(AVCodecContext *avctx, GetBitContext *gb)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+
+ if (get_bits1(gb)) {
+ int token;
+ if (s->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++;
+ } else {
+ if (s->huff_code_size >= 32) { /* 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))
+ return -1;
+ s->hbits |= 1;
+ if (read_huffman_tree(avctx, gb))
+ return -1;
+ s->hbits >>= 1;
+ s->huff_code_size--;
+ }
+ return 0;
+}
+
+static int vp3_init_thread_copy(AVCodecContext *avctx)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+
+ s->superblock_coding = NULL;
+ s->all_fragments = NULL;
+ s->coded_fragment_list[0] = NULL;
+ s->dct_tokens_base = NULL;
+ s->superblock_fragments = NULL;
+ s->macroblock_coding = NULL;
+ s->motion_val[0] = NULL;
+ s->motion_val[1] = NULL;
+ s->edge_emu_buffer = NULL;
+
+ return init_frames(s);
+}
+
+#if CONFIG_THEORA_DECODER
+static const enum AVPixelFormat theora_pix_fmts[4] = {
+ AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P
+};
+
+static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+ int visible_width, visible_height, colorspace;
+ uint8_t offset_x = 0, offset_y = 0;
+ int ret;
+ AVRational fps, aspect;
+
+ s->theora_header = 0;
+ s->theora = get_bits_long(gb, 24);
+ av_log(avctx, AV_LOG_DEBUG, "Theora bitstream version %X\n", s->theora);
+
+ /* 3.2.0 aka alpha3 has the same frame orientation as original vp3
+ * but previous versions have the image flipped relative to vp3 */
+ if (s->theora < 0x030200) {
+ s->flipped_image = 1;
+ av_log(avctx, AV_LOG_DEBUG,
+ "Old (<alpha3) Theora bitstream, flipped image\n");
+ }
+
+ visible_width =
+ s->width = get_bits(gb, 16) << 4;
+ visible_height =
+ s->height = get_bits(gb, 16) << 4;
+
+ if (s->theora >= 0x030200) {
+ visible_width = get_bits_long(gb, 24);
+ visible_height = get_bits_long(gb, 24);
+
+ offset_x = get_bits(gb, 8); /* offset x */
+ offset_y = get_bits(gb, 8); /* offset y, from bottom */
+ }
+
+ /* sanity check */
+ if (av_image_check_size(visible_width, visible_height, 0, avctx) < 0 ||
+ visible_width + offset_x > s->width ||
+ visible_height + offset_y > s->height) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid frame dimensions - w:%d h:%d x:%d y:%d (%dx%d).\n",
+ visible_width, visible_height, offset_x, offset_y,
+ s->width, s->height);
+ return AVERROR_INVALIDDATA;
+ }
+
+ fps.num = get_bits_long(gb, 32);
+ fps.den = get_bits_long(gb, 32);
+ if (fps.num && fps.den) {
+ if (fps.num < 0 || fps.den < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid framerate\n");
+ return AVERROR_INVALIDDATA;
+ }
+ av_reduce(&avctx->framerate.den, &avctx->framerate.num,
+ fps.den, fps.num, 1 << 30);
+ }
+
+ aspect.num = get_bits_long(gb, 24);
+ aspect.den = get_bits_long(gb, 24);
+ if (aspect.num && aspect.den) {
+ av_reduce(&avctx->sample_aspect_ratio.num,
+ &avctx->sample_aspect_ratio.den,
+ aspect.num, aspect.den, 1 << 30);
+ ff_set_sar(avctx, avctx->sample_aspect_ratio);
+ }
+
+ if (s->theora < 0x030200)
+ skip_bits(gb, 5); /* keyframe frequency force */
+ colorspace = get_bits(gb, 8);
+ skip_bits(gb, 24); /* bitrate */
+
+ skip_bits(gb, 6); /* quality hint */
+
+ if (s->theora >= 0x030200) {
+ skip_bits(gb, 5); /* keyframe frequency force */
+ avctx->pix_fmt = theora_pix_fmts[get_bits(gb, 2)];
+ if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid pixel format\n");
+ return AVERROR_INVALIDDATA;
+ }
+ skip_bits(gb, 3); /* reserved */
+ } else
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+ ret = ff_set_dimensions(avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
+ if (!(avctx->flags2 & AV_CODEC_FLAG2_IGNORE_CROP)) {
+ avctx->width = visible_width;
+ avctx->height = visible_height;
+ // translate offsets from theora axis ([0,0] lower left)
+ // to normal axis ([0,0] upper left)
+ s->offset_x = offset_x;
+ s->offset_y = s->height - visible_height - offset_y;
+
+ if ((s->offset_x & 0x1F) && !(avctx->flags & AV_CODEC_FLAG_UNALIGNED)) {
+ s->offset_x &= ~0x1F;
+ if (!s->offset_x_warned) {
+ s->offset_x_warned = 1;
+ av_log(avctx, AV_LOG_WARNING, "Reducing offset_x from %d to %d"
+ "chroma samples to preserve alignment.\n",
+ offset_x, s->offset_x);
+ }
+ }
+ }
+
+ if (colorspace == 1)
+ avctx->color_primaries = AVCOL_PRI_BT470M;
+ else if (colorspace == 2)
+ avctx->color_primaries = AVCOL_PRI_BT470BG;
+
+ if (colorspace == 1 || colorspace == 2) {
+ avctx->colorspace = AVCOL_SPC_BT470BG;
+ avctx->color_trc = AVCOL_TRC_BT709;
+ }
+
+ s->theora_header = 1;
+ return 0;
+}
+
+static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+ int i, n, matrices, inter, plane;
+
+ if (!s->theora_header)
+ return AVERROR_INVALIDDATA;
+
+ if (s->theora >= 0x030200) {
+ n = get_bits(gb, 3);
+ /* loop filter limit values table */
+ if (n)
+ for (i = 0; i < 64; i++)
+ s->filter_limit_values[i] = get_bits(gb, n);
+ }
+
+ if (s->theora >= 0x030200)
+ n = get_bits(gb, 4) + 1;
+ else
+ n = 16;
+ /* quality threshold table */
+ for (i = 0; i < 64; i++)
+ s->coded_ac_scale_factor[i] = get_bits(gb, n);
+
+ if (s->theora >= 0x030200)
+ n = get_bits(gb, 4) + 1;
+ else
+ n = 16;
+ /* dc scale factor table */
+ for (i = 0; i < 64; i++)
+ s->coded_dc_scale_factor[i] = get_bits(gb, n);
+
+ if (s->theora >= 0x030200)
+ matrices = get_bits(gb, 9) + 1;
+ else
+ matrices = 3;
+
+ if (matrices > 384) {
+ av_log(avctx, AV_LOG_ERROR, "invalid number of base matrixes\n");
+ return -1;
+ }
+
+ for (n = 0; n < matrices; n++)
+ for (i = 0; i < 64; i++)
+ s->base_matrix[n][i] = get_bits(gb, 8);
+
+ for (inter = 0; inter <= 1; inter++) {
+ for (plane = 0; plane <= 2; plane++) {
+ int newqr = 1;
+ if (inter || plane > 0)
+ newqr = get_bits1(gb);
+ if (!newqr) {
+ int qtj, plj;
+ if (inter && get_bits1(gb)) {
+ qtj = 0;
+ plj = plane;
+ } else {
+ qtj = (3 * inter + plane - 1) / 3;
+ plj = (plane + 2) % 3;
+ }
+ s->qr_count[inter][plane] = s->qr_count[qtj][plj];
+ memcpy(s->qr_size[inter][plane], s->qr_size[qtj][plj],
+ sizeof(s->qr_size[0][0]));
+ memcpy(s->qr_base[inter][plane], s->qr_base[qtj][plj],
+ sizeof(s->qr_base[0][0]));
+ } else {
+ int qri = 0;
+ int qi = 0;
+
+ for (;;) {
+ i = get_bits(gb, av_log2(matrices - 1) + 1);
+ if (i >= matrices) {
+ av_log(avctx, AV_LOG_ERROR,
+ "invalid base matrix index\n");
+ return -1;
+ }
+ s->qr_base[inter][plane][qri] = i;
+ if (qi >= 63)
+ break;
+ i = get_bits(gb, av_log2(63 - qi) + 1) + 1;
+ s->qr_size[inter][plane][qri++] = i;
+ qi += i;
+ }
+
+ if (qi > 63) {
+ av_log(avctx, AV_LOG_ERROR, "invalid qi %d > 63\n", qi);
+ return -1;
+ }
+ s->qr_count[inter][plane] = qri;
+ }
+ }
+ }
+
+ /* 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;
+ }
+ }
+
+ s->theora_tables = 1;
+
+ return 0;
+}
+
+static av_cold int theora_decode_init(AVCodecContext *avctx)
+{
+ Vp3DecodeContext *s = avctx->priv_data;
+ GetBitContext gb;
+ int ptype;
+ const uint8_t *header_start[3];
+ int header_len[3];
+ int i;
+ int ret;
+
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+ s->theora = 1;
+
+ if (!avctx->extradata_size) {
+ av_log(avctx, AV_LOG_ERROR, "Missing extradata!\n");
+ return -1;
+ }
+
+ if (avpriv_split_xiph_headers(avctx->extradata, avctx->extradata_size,
+ 42, header_start, header_len) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Corrupt extradata\n");
+ return -1;
+ }
+
+ for (i = 0; i < 3; i++) {
+ if (header_len[i] <= 0)
+ continue;
+ ret = init_get_bits8(&gb, header_start[i], header_len[i]);
+ if (ret < 0)
+ return ret;
+
+ ptype = get_bits(&gb, 8);
+
+ if (!(ptype & 0x80)) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid extradata!\n");
+// return -1;
+ }
+
+ // FIXME: Check for this as well.
+ skip_bits_long(&gb, 6 * 8); /* "theora" */
+
+ switch (ptype) {
+ case 0x80:
+ if (theora_decode_header(avctx, &gb) < 0)
+ return -1;
+ break;
+ case 0x81:
+// FIXME: is this needed? it breaks sometimes
+// theora_decode_comments(avctx, gb);
+ break;
+ case 0x82:
+ if (theora_decode_tables(avctx, &gb))
+ return -1;
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR,
+ "Unknown Theora config packet: %d\n", ptype & ~0x80);
+ break;
+ }
+ if (ptype != 0x81 && 8 * header_len[i] != get_bits_count(&gb))
+ av_log(avctx, AV_LOG_WARNING,
+ "%d bits left in packet %X\n",
+ 8 * header_len[i] - get_bits_count(&gb), ptype);
+ if (s->theora < 0x030200)
+ break;
+ }
+
+ return vp3_decode_init(avctx);
+}
+
+AVCodec ff_theora_decoder = {
+ .name = "theora",
+ .long_name = NULL_IF_CONFIG_SMALL("Theora"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_THEORA,
+ .priv_data_size = sizeof(Vp3DecodeContext),
+ .init = theora_decode_init,
+ .close = vp3_decode_end,
+ .decode = vp3_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
+ AV_CODEC_CAP_FRAME_THREADS,
+ .flush = vp3_decode_flush,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context)
+};
+#endif
+
+AVCodec ff_vp3_decoder = {
+ .name = "vp3",
+ .long_name = NULL_IF_CONFIG_SMALL("On2 VP3"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_VP3,
+ .priv_data_size = sizeof(Vp3DecodeContext),
+ .init = vp3_decode_init,
+ .close = vp3_decode_end,
+ .decode = vp3_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DRAW_HORIZ_BAND |
+ AV_CODEC_CAP_FRAME_THREADS,
+ .flush = vp3_decode_flush,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp3_init_thread_copy),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context),
+};
diff --git a/ffmpeg-2-8-11/libavcodec/vp3_parser.c b/ffmpeg-2-8-12/libavcodec/vp3_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp3_parser.c
rename to ffmpeg-2-8-12/libavcodec/vp3_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/vp3data.h b/ffmpeg-2-8-12/libavcodec/vp3data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp3data.h
rename to ffmpeg-2-8-12/libavcodec/vp3data.h
diff --git a/ffmpeg-2-8-12/libavcodec/vp3dsp.c b/ffmpeg-2-8-12/libavcodec/vp3dsp.c
new file mode 100644
index 0000000..3799743
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/vp3dsp.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 2004 The FFmpeg Project
+ *
+ * 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
+ * Standard C DSP-oriented functions cribbed from the original VP3
+ * source code.
+ */
+
+#include "libavutil/attributes.h"
+#include "libavutil/common.h"
+#include "libavutil/intreadwrite.h"
+
+#include "avcodec.h"
+#include "rnd_avg.h"
+#include "vp3dsp.h"
+
+#define IdctAdjustBeforeShift 8
+#define xC1S7 64277
+#define xC2S6 60547
+#define xC3S5 54491
+#define xC4S4 46341
+#define xC5S3 36410
+#define xC6S2 25080
+#define xC7S1 12785
+
+#define M(a, b) ((int)((SUINT)(a) * (b)) >> 16)
+
+static av_always_inline void idct(uint8_t *dst, int stride,
+ int16_t *input, int type)
+{
+ int16_t *ip = input;
+
+ int A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H;
+ int Ed, Gd, Add, Bdd, Fd, Hd;
+
+ int i;
+
+ /* Inverse DCT on the rows now */
+ for (i = 0; i < 8; i++) {
+ /* Check for non-zero values */
+ if (ip[0 * 8] | ip[1 * 8] | ip[2 * 8] | ip[3 * 8] |
+ ip[4 * 8] | ip[5 * 8] | ip[6 * 8] | ip[7 * 8]) {
+ A = M(xC1S7, ip[1 * 8]) + M(xC7S1, ip[7 * 8]);
+ B = M(xC7S1, ip[1 * 8]) - M(xC1S7, ip[7 * 8]);
+ C = M(xC3S5, ip[3 * 8]) + M(xC5S3, ip[5 * 8]);
+ D = M(xC3S5, ip[5 * 8]) - M(xC5S3, ip[3 * 8]);
+
+ Ad = M(xC4S4, (A - C));
+ Bd = M(xC4S4, (B - D));
+
+ Cd = A + C;
+ Dd = B + D;
+
+ E = M(xC4S4, (ip[0 * 8] + ip[4 * 8]));
+ F = M(xC4S4, (ip[0 * 8] - ip[4 * 8]));
+
+ G = M(xC2S6, ip[2 * 8]) + M(xC6S2, ip[6 * 8]);
+ H = M(xC6S2, ip[2 * 8]) - M(xC2S6, ip[6 * 8]);
+
+ Ed = E - G;
+ Gd = E + G;
+
+ Add = F + Ad;
+ Bdd = Bd - H;
+
+ Fd = F - Ad;
+ Hd = Bd + H;
+
+ /* Final sequence of operations over-write original inputs. */
+ ip[0 * 8] = Gd + Cd;
+ ip[7 * 8] = Gd - Cd;
+
+ ip[1 * 8] = Add + Hd;
+ ip[2 * 8] = Add - Hd;
+
+ ip[3 * 8] = Ed + Dd;
+ ip[4 * 8] = Ed - Dd;
+
+ ip[5 * 8] = Fd + Bdd;
+ ip[6 * 8] = Fd - Bdd;
+ }
+
+ ip += 1; /* next row */
+ }
+
+ ip = input;
+
+ for (i = 0; i < 8; i++) {
+ /* Check for non-zero values (bitwise or faster than ||) */
+ if (ip[1] | ip[2] | ip[3] |
+ ip[4] | ip[5] | ip[6] | ip[7]) {
+ A = M(xC1S7, ip[1]) + M(xC7S1, ip[7]);
+ B = M(xC7S1, ip[1]) - M(xC1S7, ip[7]);
+ C = M(xC3S5, ip[3]) + M(xC5S3, ip[5]);
+ D = M(xC3S5, ip[5]) - M(xC5S3, ip[3]);
+
+ Ad = M(xC4S4, (A - C));
+ Bd = M(xC4S4, (B - D));
+
+ Cd = A + C;
+ Dd = B + D;
+
+ E = M(xC4S4, (ip[0] + ip[4])) + 8;
+ F = M(xC4S4, (ip[0] - ip[4])) + 8;
+
+ if (type == 1) { // HACK
+ E += 16 * 128;
+ F += 16 * 128;
+ }
+
+ G = M(xC2S6, ip[2]) + M(xC6S2, ip[6]);
+ H = M(xC6S2, ip[2]) - M(xC2S6, ip[6]);
+
+ Ed = E - G;
+ Gd = E + G;
+
+ Add = F + Ad;
+ Bdd = Bd - H;
+
+ Fd = F - Ad;
+ Hd = Bd + H;
+
+ /* Final sequence of operations over-write original inputs. */
+ if (type == 1) {
+ dst[0 * stride] = av_clip_uint8((Gd + Cd) >> 4);
+ dst[7 * stride] = av_clip_uint8((Gd - Cd) >> 4);
+
+ dst[1 * stride] = av_clip_uint8((Add + Hd) >> 4);
+ dst[2 * stride] = av_clip_uint8((Add - Hd) >> 4);
+
+ dst[3 * stride] = av_clip_uint8((Ed + Dd) >> 4);
+ dst[4 * stride] = av_clip_uint8((Ed - Dd) >> 4);
+
+ dst[5 * stride] = av_clip_uint8((Fd + Bdd) >> 4);
+ dst[6 * stride] = av_clip_uint8((Fd - Bdd) >> 4);
+ } else {
+ dst[0 * stride] = av_clip_uint8(dst[0 * stride] + ((Gd + Cd) >> 4));
+ dst[7 * stride] = av_clip_uint8(dst[7 * stride] + ((Gd - Cd) >> 4));
+
+ dst[1 * stride] = av_clip_uint8(dst[1 * stride] + ((Add + Hd) >> 4));
+ dst[2 * stride] = av_clip_uint8(dst[2 * stride] + ((Add - Hd) >> 4));
+
+ dst[3 * stride] = av_clip_uint8(dst[3 * stride] + ((Ed + Dd) >> 4));
+ dst[4 * stride] = av_clip_uint8(dst[4 * stride] + ((Ed - Dd) >> 4));
+
+ dst[5 * stride] = av_clip_uint8(dst[5 * stride] + ((Fd + Bdd) >> 4));
+ dst[6 * stride] = av_clip_uint8(dst[6 * stride] + ((Fd - Bdd) >> 4));
+ }
+ } else {
+ if (type == 1) {
+ dst[0*stride] =
+ dst[1*stride] =
+ dst[2*stride] =
+ dst[3*stride] =
+ dst[4*stride] =
+ dst[5*stride] =
+ dst[6*stride] =
+ dst[7*stride] = av_clip_uint8(128 + ((xC4S4 * ip[0] + (IdctAdjustBeforeShift << 16)) >> 20));
+ } else {
+ if (ip[0]) {
+ int v = (xC4S4 * ip[0] + (IdctAdjustBeforeShift << 16)) >> 20;
+ dst[0 * stride] = av_clip_uint8(dst[0 * stride] + v);
+ dst[1 * stride] = av_clip_uint8(dst[1 * stride] + v);
+ dst[2 * stride] = av_clip_uint8(dst[2 * stride] + v);
+ dst[3 * stride] = av_clip_uint8(dst[3 * stride] + v);
+ dst[4 * stride] = av_clip_uint8(dst[4 * stride] + v);
+ dst[5 * stride] = av_clip_uint8(dst[5 * stride] + v);
+ dst[6 * stride] = av_clip_uint8(dst[6 * stride] + v);
+ dst[7 * stride] = av_clip_uint8(dst[7 * stride] + v);
+ }
+ }
+ }
+
+ ip += 8; /* next column */
+ dst++;
+ }
+}
+
+static void vp3_idct_put_c(uint8_t *dest /* align 8 */, int line_size,
+ int16_t *block /* align 16 */)
+{
+ idct(dest, line_size, block, 1);
+ memset(block, 0, sizeof(*block) * 64);
+}
+
+static void vp3_idct_add_c(uint8_t *dest /* align 8 */, int line_size,
+ int16_t *block /* align 16 */)
+{
+ idct(dest, line_size, block, 2);
+ memset(block, 0, sizeof(*block) * 64);
+}
+
+static void vp3_idct_dc_add_c(uint8_t *dest /* align 8 */, int line_size,
+ int16_t *block /* align 16 */)
+{
+ int i, dc = (block[0] + 15) >> 5;
+
+ for (i = 0; i < 8; i++) {
+ dest[0] = av_clip_uint8(dest[0] + dc);
+ dest[1] = av_clip_uint8(dest[1] + dc);
+ dest[2] = av_clip_uint8(dest[2] + dc);
+ dest[3] = av_clip_uint8(dest[3] + dc);
+ dest[4] = av_clip_uint8(dest[4] + dc);
+ dest[5] = av_clip_uint8(dest[5] + dc);
+ dest[6] = av_clip_uint8(dest[6] + dc);
+ dest[7] = av_clip_uint8(dest[7] + dc);
+ dest += line_size;
+ }
+ block[0] = 0;
+}
+
+static void vp3_v_loop_filter_c(uint8_t *first_pixel, int stride,
+ int *bounding_values)
+{
+ unsigned char *end;
+ int filter_value;
+ const int nstride = -stride;
+
+ for (end = first_pixel + 8; first_pixel < end; first_pixel++) {
+ filter_value = (first_pixel[2 * nstride] - first_pixel[stride]) +
+ (first_pixel[0] - first_pixel[nstride]) * 3;
+ filter_value = bounding_values[(filter_value + 4) >> 3];
+
+ first_pixel[nstride] = av_clip_uint8(first_pixel[nstride] + filter_value);
+ first_pixel[0] = av_clip_uint8(first_pixel[0] - filter_value);
+ }
+}
+
+static void vp3_h_loop_filter_c(uint8_t *first_pixel, int stride,
+ int *bounding_values)
+{
+ unsigned char *end;
+ int filter_value;
+
+ for (end = first_pixel + 8 * stride; first_pixel != end; first_pixel += stride) {
+ filter_value = (first_pixel[-2] - first_pixel[1]) +
+ (first_pixel[ 0] - first_pixel[-1]) * 3;
+ filter_value = bounding_values[(filter_value + 4) >> 3];
+
+ first_pixel[-1] = av_clip_uint8(first_pixel[-1] + filter_value);
+ first_pixel[ 0] = av_clip_uint8(first_pixel[ 0] - filter_value);
+ }
+}
+
+static void put_no_rnd_pixels_l2(uint8_t *dst, const uint8_t *src1,
+ const uint8_t *src2, ptrdiff_t stride, int h)
+{
+ int i;
+
+ for (i = 0; i < h; i++) {
+ uint32_t a, b;
+
+ a = AV_RN32(&src1[i * stride]);
+ b = AV_RN32(&src2[i * stride]);
+ AV_WN32A(&dst[i * stride], no_rnd_avg32(a, b));
+ a = AV_RN32(&src1[i * stride + 4]);
+ b = AV_RN32(&src2[i * stride + 4]);
+ AV_WN32A(&dst[i * stride + 4], no_rnd_avg32(a, b));
+ }
+}
+
+av_cold void ff_vp3dsp_init(VP3DSPContext *c, int flags)
+{
+ c->put_no_rnd_pixels_l2 = put_no_rnd_pixels_l2;
+
+ c->idct_put = vp3_idct_put_c;
+ c->idct_add = vp3_idct_add_c;
+ c->idct_dc_add = vp3_idct_dc_add_c;
+ c->v_loop_filter = vp3_v_loop_filter_c;
+ c->h_loop_filter = vp3_h_loop_filter_c;
+
+ if (ARCH_ARM)
+ ff_vp3dsp_init_arm(c, flags);
+ if (ARCH_PPC)
+ ff_vp3dsp_init_ppc(c, flags);
+ if (ARCH_X86)
+ ff_vp3dsp_init_x86(c, flags);
+}
diff --git a/ffmpeg-2-8-11/libavcodec/vp3dsp.h b/ffmpeg-2-8-12/libavcodec/vp3dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp3dsp.h
rename to ffmpeg-2-8-12/libavcodec/vp3dsp.h
diff --git a/ffmpeg-2-8-12/libavcodec/vp5.c b/ffmpeg-2-8-12/libavcodec/vp5.c
new file mode 100644
index 0000000..7100bb4
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/vp5.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.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
+ * VP5 compatible video decoder
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "internal.h"
+
+#include "vp56.h"
+#include "vp56data.h"
+#include "vp5data.h"
+
+
+static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
+{
+ VP56RangeCoder *c = &s->c;
+ int rows, cols;
+ int ret;
+
+ ret = ff_vp56_init_range_decoder(&s->c, buf, buf_size);
+ if (ret < 0)
+ return ret;
+ s->frames[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c);
+ vp56_rac_get(c);
+ ff_vp56_init_dequant(s, vp56_rac_gets(c, 6));
+ if (s->frames[VP56_FRAME_CURRENT]->key_frame)
+ {
+ vp56_rac_gets(c, 8);
+ if(vp56_rac_gets(c, 5) > 5)
+ return AVERROR_INVALIDDATA;
+ vp56_rac_gets(c, 2);
+ if (vp56_rac_get(c)) {
+ av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n");
+ return AVERROR_PATCHWELCOME;
+ }
+ rows = vp56_rac_gets(c, 8); /* number of stored macroblock rows */
+ cols = vp56_rac_gets(c, 8); /* number of stored macroblock cols */
+ if (!rows || !cols) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n",
+ cols << 4, rows << 4);
+ return AVERROR_INVALIDDATA;
+ }
+ vp56_rac_gets(c, 8); /* number of displayed macroblock rows */
+ vp56_rac_gets(c, 8); /* number of displayed macroblock cols */
+ vp56_rac_gets(c, 2);
+ if (!s->macroblocks || /* first frame */
+ 16*cols != s->avctx->coded_width ||
+ 16*rows != s->avctx->coded_height) {
+ int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows);
+ if (ret < 0)
+ return ret;
+ return VP56_SIZE_CHANGE;
+ }
+ } else if (!s->macroblocks)
+ return AVERROR_INVALIDDATA;
+ return 0;
+}
+
+static void vp5_parse_vector_adjustment(VP56Context *s, VP56mv *vect)
+{
+ VP56RangeCoder *c = &s->c;
+ VP56Model *model = s->modelp;
+ int comp, di;
+
+ for (comp=0; comp<2; comp++) {
+ int delta = 0;
+ if (vp56_rac_get_prob_branchy(c, model->vector_dct[comp])) {
+ int sign = vp56_rac_get_prob(c, model->vector_sig[comp]);
+ di = vp56_rac_get_prob(c, model->vector_pdi[comp][0]);
+ di |= vp56_rac_get_prob(c, model->vector_pdi[comp][1]) << 1;
+ delta = vp56_rac_get_tree(c, ff_vp56_pva_tree,
+ model->vector_pdv[comp]);
+ delta = di | (delta << 2);
+ delta = (delta ^ -sign) + sign;
+ }
+ if (!comp)
+ vect->x = delta;
+ else
+ vect->y = delta;
+ }
+}
+
+static void vp5_parse_vector_models(VP56Context *s)
+{
+ VP56RangeCoder *c = &s->c;
+ VP56Model *model = s->modelp;
+ int comp, node;
+
+ for (comp=0; comp<2; comp++) {
+ if (vp56_rac_get_prob_branchy(c, vp5_vmc_pct[comp][0]))
+ model->vector_dct[comp] = vp56_rac_gets_nn(c, 7);
+ if (vp56_rac_get_prob_branchy(c, vp5_vmc_pct[comp][1]))
+ model->vector_sig[comp] = vp56_rac_gets_nn(c, 7);
+ if (vp56_rac_get_prob_branchy(c, vp5_vmc_pct[comp][2]))
+ model->vector_pdi[comp][0] = vp56_rac_gets_nn(c, 7);
+ if (vp56_rac_get_prob_branchy(c, vp5_vmc_pct[comp][3]))
+ model->vector_pdi[comp][1] = vp56_rac_gets_nn(c, 7);
+ }
+
+ for (comp=0; comp<2; comp++)
+ for (node=0; node<7; node++)
+ if (vp56_rac_get_prob_branchy(c, vp5_vmc_pct[comp][4 + node]))
+ model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7);
+}
+
+static int vp5_parse_coeff_models(VP56Context *s)
+{
+ VP56RangeCoder *c = &s->c;
+ VP56Model *model = s->modelp;
+ uint8_t def_prob[11];
+ int node, cg, ctx;
+ int ct; /* code type */
+ int pt; /* plane type (0 for Y, 1 for U or V) */
+
+ memset(def_prob, 0x80, sizeof(def_prob));
+
+ for (pt=0; pt<2; pt++)
+ for (node=0; node<11; node++)
+ if (vp56_rac_get_prob_branchy(c, vp5_dccv_pct[pt][node])) {
+ def_prob[node] = vp56_rac_gets_nn(c, 7);
+ model->coeff_dccv[pt][node] = def_prob[node];
+ } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
+ model->coeff_dccv[pt][node] = def_prob[node];
+ }
+
+ for (ct=0; ct<3; ct++)
+ for (pt=0; pt<2; pt++)
+ for (cg=0; cg<6; cg++)
+ for (node=0; node<11; node++)
+ if (vp56_rac_get_prob_branchy(c, vp5_ract_pct[ct][pt][cg][node])) {
+ def_prob[node] = vp56_rac_gets_nn(c, 7);
+ model->coeff_ract[pt][ct][cg][node] = def_prob[node];
+ } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
+ model->coeff_ract[pt][ct][cg][node] = def_prob[node];
+ }
+
+ /* coeff_dcct is a linear combination of coeff_dccv */
+ for (pt=0; pt<2; pt++)
+ for (ctx=0; ctx<36; ctx++)
+ for (node=0; node<5; node++)
+ model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp5_dccv_lc[node][ctx][0] + 128) >> 8) + vp5_dccv_lc[node][ctx][1], 1, 254);
+
+ /* coeff_acct is a linear combination of coeff_ract */
+ for (ct=0; ct<3; ct++)
+ for (pt=0; pt<2; pt++)
+ for (cg=0; cg<3; cg++)
+ for (ctx=0; ctx<6; ctx++)
+ for (node=0; node<5; node++)
+ model->coeff_acct[pt][ct][cg][ctx][node] = av_clip(((model->coeff_ract[pt][ct][cg][node] * vp5_ract_lc[ct][cg][node][ctx][0] + 128) >> 8) + vp5_ract_lc[ct][cg][node][ctx][1], 1, 254);
+ return 0;
+}
+
+static int vp5_parse_coeff(VP56Context *s)
+{
+ VP56RangeCoder *c = &s->c;
+ VP56Model *model = s->modelp;
+ uint8_t *permute = s->idct_scantable;
+ uint8_t *model1, *model2;
+ int coeff, sign, coeff_idx;
+ int b, i, cg, idx, ctx, ctx_last;
+ int pt = 0; /* plane type (0 for Y, 1 for U or V) */
+
+ if (c->end <= c->buffer && c->bits >= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "End of AC stream reached in vp5_parse_coeff\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (b=0; b<6; b++) {
+ int ct = 1; /* code type */
+
+ if (b > 3) pt = 1;
+
+ ctx = 6*s->coeff_ctx[ff_vp56_b6to4[b]][0]
+ + s->above_blocks[s->above_block_idx[b]].not_null_dc;
+ model1 = model->coeff_dccv[pt];
+ model2 = model->coeff_dcct[pt][ctx];
+
+ coeff_idx = 0;
+ for (;;) {
+ if (vp56_rac_get_prob_branchy(c, model2[0])) {
+ if (vp56_rac_get_prob_branchy(c, model2[2])) {
+ if (vp56_rac_get_prob_branchy(c, model2[3])) {
+ s->coeff_ctx[ff_vp56_b6to4[b]][coeff_idx] = 4;
+ idx = vp56_rac_get_tree(c, ff_vp56_pc_tree, model1);
+ sign = vp56_rac_get(c);
+ coeff = ff_vp56_coeff_bias[idx+5];
+ for (i=ff_vp56_coeff_bit_length[idx]; i>=0; i--)
+ coeff += vp56_rac_get_prob(c, ff_vp56_coeff_parse_table[idx][i]) << i;
+ } else {
+ if (vp56_rac_get_prob_branchy(c, model2[4])) {
+ coeff = 3 + vp56_rac_get_prob(c, model1[5]);
+ s->coeff_ctx[ff_vp56_b6to4[b]][coeff_idx] = 3;
+ } else {
+ coeff = 2;
+ s->coeff_ctx[ff_vp56_b6to4[b]][coeff_idx] = 2;
+ }
+ sign = vp56_rac_get(c);
+ }
+ ct = 2;
+ } else {
+ ct = 1;
+ s->coeff_ctx[ff_vp56_b6to4[b]][coeff_idx] = 1;
+ sign = vp56_rac_get(c);
+ coeff = 1;
+ }
+ coeff = (coeff ^ -sign) + sign;
+ if (coeff_idx)
+ coeff *= s->dequant_ac;
+ s->block_coeff[b][permute[coeff_idx]] = coeff;
+ } else {
+ if (ct && !vp56_rac_get_prob_branchy(c, model2[1]))
+ break;
+ ct = 0;
+ s->coeff_ctx[ff_vp56_b6to4[b]][coeff_idx] = 0;
+ }
+ coeff_idx++;
+ if (coeff_idx >= 64)
+ break;
+
+ cg = vp5_coeff_groups[coeff_idx];
+ ctx = s->coeff_ctx[ff_vp56_b6to4[b]][coeff_idx];
+ model1 = model->coeff_ract[pt][ct][cg];
+ model2 = cg > 2 ? model1 : model->coeff_acct[pt][ct][cg][ctx];
+ }
+
+ ctx_last = FFMIN(s->coeff_ctx_last[ff_vp56_b6to4[b]], 24);
+ s->coeff_ctx_last[ff_vp56_b6to4[b]] = coeff_idx;
+ if (coeff_idx < ctx_last)
+ for (i=coeff_idx; i<=ctx_last; i++)
+ s->coeff_ctx[ff_vp56_b6to4[b]][i] = 5;
+ s->above_blocks[s->above_block_idx[b]].not_null_dc = s->coeff_ctx[ff_vp56_b6to4[b]][0];
+ }
+ return 0;
+}
+
+static void vp5_default_models_init(VP56Context *s)
+{
+ VP56Model *model = s->modelp;
+ int i;
+
+ for (i=0; i<2; i++) {
+ model->vector_sig[i] = 0x80;
+ model->vector_dct[i] = 0x80;
+ model->vector_pdi[i][0] = 0x55;
+ model->vector_pdi[i][1] = 0x80;
+ }
+ memcpy(model->mb_types_stats, ff_vp56_def_mb_types_stats, sizeof(model->mb_types_stats));
+ memset(model->vector_pdv, 0x80, sizeof(model->vector_pdv));
+}
+
+static av_cold int vp5_decode_init(AVCodecContext *avctx)
+{
+ VP56Context *s = avctx->priv_data;
+ int ret;
+
+ if ((ret = ff_vp56_init(avctx, 1, 0)) < 0)
+ return ret;
+ s->vp56_coord_div = vp5_coord_div;
+ s->parse_vector_adjustment = vp5_parse_vector_adjustment;
+ s->parse_coeff = vp5_parse_coeff;
+ s->default_models_init = vp5_default_models_init;
+ s->parse_vector_models = vp5_parse_vector_models;
+ s->parse_coeff_models = vp5_parse_coeff_models;
+ s->parse_header = vp5_parse_header;
+
+ return 0;
+}
+
+AVCodec ff_vp5_decoder = {
+ .name = "vp5",
+ .long_name = NULL_IF_CONFIG_SMALL("On2 VP5"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_VP5,
+ .priv_data_size = sizeof(VP56Context),
+ .init = vp5_decode_init,
+ .close = ff_vp56_free,
+ .decode = ff_vp56_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-12/libavcodec/vp56.c b/ffmpeg-2-8-12/libavcodec/vp56.c
new file mode 100644
index 0000000..bfc3d3b
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/vp56.c
@@ -0,0 +1,830 @@
+/*
+ * Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.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
+ * VP5 and VP6 compatible video decoder (common features)
+ */
+
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+#include "h264chroma.h"
+#include "vp56.h"
+#include "vp56data.h"
+
+
+void ff_vp56_init_dequant(VP56Context *s, int quantizer)
+{
+ s->quantizer = quantizer;
+ s->dequant_dc = ff_vp56_dc_dequant[quantizer] << 2;
+ s->dequant_ac = ff_vp56_ac_dequant[quantizer] << 2;
+}
+
+static int vp56_get_vectors_predictors(VP56Context *s, int row, int col,
+ VP56Frame ref_frame)
+{
+ int nb_pred = 0;
+ VP56mv vect[2] = {{0,0}, {0,0}};
+ int pos, offset;
+ VP56mv mvp;
+
+ for (pos=0; pos<12; pos++) {
+ mvp.x = col + ff_vp56_candidate_predictor_pos[pos][0];
+ mvp.y = row + ff_vp56_candidate_predictor_pos[pos][1];
+ if (mvp.x < 0 || mvp.x >= s->mb_width ||
+ mvp.y < 0 || mvp.y >= s->mb_height)
+ continue;
+ offset = mvp.x + s->mb_width*mvp.y;
+
+ if (ff_vp56_reference_frame[s->macroblocks[offset].type] != ref_frame)
+ continue;
+ if ((s->macroblocks[offset].mv.x == vect[0].x &&
+ s->macroblocks[offset].mv.y == vect[0].y) ||
+ (s->macroblocks[offset].mv.x == 0 &&
+ s->macroblocks[offset].mv.y == 0))
+ continue;
+
+ vect[nb_pred++] = s->macroblocks[offset].mv;
+ if (nb_pred > 1) {
+ nb_pred = -1;
+ break;
+ }
+ s->vector_candidate_pos = pos;
+ }
+
+ s->vector_candidate[0] = vect[0];
+ s->vector_candidate[1] = vect[1];
+
+ return nb_pred+1;
+}
+
+static void vp56_parse_mb_type_models(VP56Context *s)
+{
+ VP56RangeCoder *c = &s->c;
+ VP56Model *model = s->modelp;
+ int i, ctx, type;
+
+ for (ctx=0; ctx<3; ctx++) {
+ if (vp56_rac_get_prob_branchy(c, 174)) {
+ int idx = vp56_rac_gets(c, 4);
+ memcpy(model->mb_types_stats[ctx],
+ ff_vp56_pre_def_mb_type_stats[idx][ctx],
+ sizeof(model->mb_types_stats[ctx]));
+ }
+ if (vp56_rac_get_prob_branchy(c, 254)) {
+ for (type=0; type<10; type++) {
+ for(i=0; i<2; i++) {
+ if (vp56_rac_get_prob_branchy(c, 205)) {
+ int delta, sign = vp56_rac_get(c);
+
+ delta = vp56_rac_get_tree(c, ff_vp56_pmbtm_tree,
+ ff_vp56_mb_type_model_model);
+ if (!delta)
+ delta = 4 * vp56_rac_gets(c, 7);
+ model->mb_types_stats[ctx][type][i] += (delta ^ -sign) + sign;
+ }
+ }
+ }
+ }
+ }
+
+ /* compute MB type probability tables based on previous MB type */
+ for (ctx=0; ctx<3; ctx++) {
+ int p[10];
+
+ for (type=0; type<10; type++)
+ p[type] = 100 * model->mb_types_stats[ctx][type][1];
+
+ for (type=0; type<10; type++) {
+ int p02, p34, p0234, p17, p56, p89, p5689, p156789;
+
+ /* conservative MB type probability */
+ model->mb_type[ctx][type][0] = 255 - (255 * model->mb_types_stats[ctx][type][0]) / (1 + model->mb_types_stats[ctx][type][0] + model->mb_types_stats[ctx][type][1]);
+
+ p[type] = 0; /* same MB type => weight is null */
+
+ /* binary tree parsing probabilities */
+ p02 = p[0] + p[2];
+ p34 = p[3] + p[4];
+ p0234 = p02 + p34;
+ p17 = p[1] + p[7];
+ p56 = p[5] + p[6];
+ p89 = p[8] + p[9];
+ p5689 = p56 + p89;
+ p156789 = p17 + p5689;
+
+ model->mb_type[ctx][type][1] = 1 + 255 * p0234/(1+p0234+p156789);
+ model->mb_type[ctx][type][2] = 1 + 255 * p02 / (1+p0234);
+ model->mb_type[ctx][type][3] = 1 + 255 * p17 / (1+p156789);
+ model->mb_type[ctx][type][4] = 1 + 255 * p[0] / (1+p02);
+ model->mb_type[ctx][type][5] = 1 + 255 * p[3] / (1+p34);
+ model->mb_type[ctx][type][6] = 1 + 255 * p[1] / (1+p17);
+ model->mb_type[ctx][type][7] = 1 + 255 * p56 / (1+p5689);
+ model->mb_type[ctx][type][8] = 1 + 255 * p[5] / (1+p56);
+ model->mb_type[ctx][type][9] = 1 + 255 * p[8] / (1+p89);
+
+ /* restore initial value */
+ p[type] = 100 * model->mb_types_stats[ctx][type][1];
+ }
+ }
+}
+
+static VP56mb vp56_parse_mb_type(VP56Context *s,
+ VP56mb prev_type, int ctx)
+{
+ uint8_t *mb_type_model = s->modelp->mb_type[ctx][prev_type];
+ VP56RangeCoder *c = &s->c;
+
+ if (vp56_rac_get_prob_branchy(c, mb_type_model[0]))
+ return prev_type;
+ else
+ return vp56_rac_get_tree(c, ff_vp56_pmbt_tree, mb_type_model);
+}
+
+static void vp56_decode_4mv(VP56Context *s, int row, int col)
+{
+ VP56mv mv = {0,0};
+ int type[4];
+ int b;
+
+ /* parse each block type */
+ for (b=0; b<4; b++) {
+ type[b] = vp56_rac_gets(&s->c, 2);
+ if (type[b])
+ type[b]++; /* only returns 0, 2, 3 or 4 (all INTER_PF) */
+ }
+
+ /* get vectors */
+ for (b=0; b<4; b++) {
+ switch (type[b]) {
+ case VP56_MB_INTER_NOVEC_PF:
+ s->mv[b] = (VP56mv) {0,0};
+ break;
+ case VP56_MB_INTER_DELTA_PF:
+ s->parse_vector_adjustment(s, &s->mv[b]);
+ break;
+ case VP56_MB_INTER_V1_PF:
+ s->mv[b] = s->vector_candidate[0];
+ break;
+ case VP56_MB_INTER_V2_PF:
+ s->mv[b] = s->vector_candidate[1];
+ break;
+ }
+ mv.x += s->mv[b].x;
+ mv.y += s->mv[b].y;
+ }
+
+ /* this is the one selected for the whole MB for prediction */
+ s->macroblocks[row * s->mb_width + col].mv = s->mv[3];
+
+ /* chroma vectors are average luma vectors */
+ if (s->avctx->codec->id == AV_CODEC_ID_VP5) {
+ s->mv[4].x = s->mv[5].x = RSHIFT(mv.x,2);
+ s->mv[4].y = s->mv[5].y = RSHIFT(mv.y,2);
+ } else {
+ s->mv[4] = s->mv[5] = (VP56mv) {mv.x/4, mv.y/4};
+ }
+}
+
+static VP56mb vp56_decode_mv(VP56Context *s, int row, int col)
+{
+ VP56mv *mv, vect = {0,0};
+ int ctx, b;
+
+ ctx = vp56_get_vectors_predictors(s, row, col, VP56_FRAME_PREVIOUS);
+ s->mb_type = vp56_parse_mb_type(s, s->mb_type, ctx);
+ s->macroblocks[row * s->mb_width + col].type = s->mb_type;
+
+ switch (s->mb_type) {
+ case VP56_MB_INTER_V1_PF:
+ mv = &s->vector_candidate[0];
+ break;
+
+ case VP56_MB_INTER_V2_PF:
+ mv = &s->vector_candidate[1];
+ break;
+
+ case VP56_MB_INTER_V1_GF:
+ vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);
+ mv = &s->vector_candidate[0];
+ break;
+
+ case VP56_MB_INTER_V2_GF:
+ vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);
+ mv = &s->vector_candidate[1];
+ break;
+
+ case VP56_MB_INTER_DELTA_PF:
+ s->parse_vector_adjustment(s, &vect);
+ mv = &vect;
+ break;
+
+ case VP56_MB_INTER_DELTA_GF:
+ vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);
+ s->parse_vector_adjustment(s, &vect);
+ mv = &vect;
+ break;
+
+ case VP56_MB_INTER_4V:
+ vp56_decode_4mv(s, row, col);
+ return s->mb_type;
+
+ default:
+ mv = &vect;
+ break;
+ }
+
+ s->macroblocks[row*s->mb_width + col].mv = *mv;
+
+ /* same vector for all blocks */
+ for (b=0; b<6; b++)
+ s->mv[b] = *mv;
+
+ return s->mb_type;
+}
+
+static VP56mb vp56_conceal_mv(VP56Context *s, int row, int col)
+{
+ VP56mv *mv, vect = {0,0};
+ int b;
+
+ s->mb_type = VP56_MB_INTER_NOVEC_PF;
+ s->macroblocks[row * s->mb_width + col].type = s->mb_type;
+
+ mv = &vect;
+
+ s->macroblocks[row*s->mb_width + col].mv = *mv;
+
+ /* same vector for all blocks */
+ for (b=0; b<6; b++)
+ s->mv[b] = *mv;
+
+ return s->mb_type;
+}
+
+static void vp56_add_predictors_dc(VP56Context *s, VP56Frame ref_frame)
+{
+ int idx = s->idct_scantable[0];
+ int b;
+
+ for (b=0; b<6; b++) {
+ VP56RefDc *ab = &s->above_blocks[s->above_block_idx[b]];
+ VP56RefDc *lb = &s->left_block[ff_vp56_b6to4[b]];
+ int count = 0;
+ int dc = 0;
+ int i;
+
+ if (ref_frame == lb->ref_frame) {
+ dc += lb->dc_coeff;
+ count++;
+ }
+ if (ref_frame == ab->ref_frame) {
+ dc += ab->dc_coeff;
+ count++;
+ }
+ if (s->avctx->codec->id == AV_CODEC_ID_VP5)
+ for (i=0; i<2; i++)
+ if (count < 2 && ref_frame == ab[-1+2*i].ref_frame) {
+ dc += ab[-1+2*i].dc_coeff;
+ count++;
+ }
+ if (count == 0)
+ dc = s->prev_dc[ff_vp56_b2p[b]][ref_frame];
+ else if (count == 2)
+ dc /= 2;
+
+ s->block_coeff[b][idx] += dc;
+ s->prev_dc[ff_vp56_b2p[b]][ref_frame] = s->block_coeff[b][idx];
+ ab->dc_coeff = s->block_coeff[b][idx];
+ ab->ref_frame = ref_frame;
+ lb->dc_coeff = s->block_coeff[b][idx];
+ lb->ref_frame = ref_frame;
+ s->block_coeff[b][idx] *= s->dequant_dc;
+ }
+}
+
+static void vp56_deblock_filter(VP56Context *s, uint8_t *yuv,
+ ptrdiff_t stride, int dx, int dy)
+{
+ int t = ff_vp56_filter_threshold[s->quantizer];
+ if (dx) s->vp56dsp.edge_filter_hor(yuv + 10-dx , stride, t);
+ if (dy) s->vp56dsp.edge_filter_ver(yuv + stride*(10-dy), stride, t);
+}
+
+static void vp56_mc(VP56Context *s, int b, int plane, uint8_t *src,
+ ptrdiff_t stride, int x, int y)
+{
+ uint8_t *dst = s->frames[VP56_FRAME_CURRENT]->data[plane] + s->block_offset[b];
+ uint8_t *src_block;
+ int src_offset;
+ int overlap_offset = 0;
+ int mask = s->vp56_coord_div[b] - 1;
+ int deblock_filtering = s->deblock_filtering;
+ int dx;
+ int dy;
+
+ if (s->avctx->skip_loop_filter >= AVDISCARD_ALL ||
+ (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY
+ && !s->frames[VP56_FRAME_CURRENT]->key_frame))
+ deblock_filtering = 0;
+
+ dx = s->mv[b].x / s->vp56_coord_div[b];
+ dy = s->mv[b].y / s->vp56_coord_div[b];
+
+ if (b >= 4) {
+ x /= 2;
+ y /= 2;
+ }
+ x += dx - 2;
+ y += dy - 2;
+
+ if (x<0 || x+12>=s->plane_width[plane] ||
+ y<0 || y+12>=s->plane_height[plane]) {
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+ src + s->block_offset[b] + (dy-2)*stride + (dx-2),
+ stride, stride,
+ 12, 12, x, y,
+ s->plane_width[plane],
+ s->plane_height[plane]);
+ src_block = s->edge_emu_buffer;
+ src_offset = 2 + 2*stride;
+ } else if (deblock_filtering) {
+ /* only need a 12x12 block, but there is no such dsp function, */
+ /* so copy a 16x12 block */
+ s->hdsp.put_pixels_tab[0][0](s->edge_emu_buffer,
+ src + s->block_offset[b] + (dy-2)*stride + (dx-2),
+ stride, 12);
+ src_block = s->edge_emu_buffer;
+ src_offset = 2 + 2*stride;
+ } else {
+ src_block = src;
+ src_offset = s->block_offset[b] + dy*stride + dx;
+ }
+
+ if (deblock_filtering)
+ vp56_deblock_filter(s, src_block, stride, dx&7, dy&7);
+
+ if (s->mv[b].x & mask)
+ overlap_offset += (s->mv[b].x > 0) ? 1 : -1;
+ if (s->mv[b].y & mask)
+ overlap_offset += (s->mv[b].y > 0) ? stride : -stride;
+
+ if (overlap_offset) {
+ if (s->filter)
+ s->filter(s, dst, src_block, src_offset, src_offset+overlap_offset,
+ stride, s->mv[b], mask, s->filter_selection, b<4);
+ else
+ s->vp3dsp.put_no_rnd_pixels_l2(dst, src_block+src_offset,
+ src_block+src_offset+overlap_offset,
+ stride, 8);
+ } else {
+ s->hdsp.put_pixels_tab[1][0](dst, src_block+src_offset, stride, 8);
+ }
+}
+
+static av_always_inline void vp56_render_mb(VP56Context *s, int row, int col, int is_alpha, VP56mb mb_type)
+{
+ int b, ab, b_max, plane, off;
+ AVFrame *frame_current, *frame_ref;
+ VP56Frame ref_frame = ff_vp56_reference_frame[mb_type];
+
+ vp56_add_predictors_dc(s, ref_frame);
+
+ frame_current = s->frames[VP56_FRAME_CURRENT];
+ frame_ref = s->frames[ref_frame];
+ if (mb_type != VP56_MB_INTRA && !frame_ref->data[0])
+ return;
+
+ ab = 6*is_alpha;
+ b_max = 6 - 2*is_alpha;
+
+ switch (mb_type) {
+ case VP56_MB_INTRA:
+ for (b=0; b<b_max; b++) {
+ plane = ff_vp56_b2p[b+ab];
+ s->vp3dsp.idct_put(frame_current->data[plane] + s->block_offset[b],
+ s->stride[plane], s->block_coeff[b]);
+ }
+ break;
+
+ case VP56_MB_INTER_NOVEC_PF:
+ case VP56_MB_INTER_NOVEC_GF:
+ for (b=0; b<b_max; b++) {
+ plane = ff_vp56_b2p[b+ab];
+ off = s->block_offset[b];
+ s->hdsp.put_pixels_tab[1][0](frame_current->data[plane] + off,
+ frame_ref->data[plane] + off,
+ s->stride[plane], 8);
+ s->vp3dsp.idct_add(frame_current->data[plane] + off,
+ s->stride[plane], s->block_coeff[b]);
+ }
+ break;
+
+ case VP56_MB_INTER_DELTA_PF:
+ case VP56_MB_INTER_V1_PF:
+ case VP56_MB_INTER_V2_PF:
+ case VP56_MB_INTER_DELTA_GF:
+ case VP56_MB_INTER_4V:
+ case VP56_MB_INTER_V1_GF:
+ case VP56_MB_INTER_V2_GF:
+ for (b=0; b<b_max; b++) {
+ int x_off = b==1 || b==3 ? 8 : 0;
+ int y_off = b==2 || b==3 ? 8 : 0;
+ plane = ff_vp56_b2p[b+ab];
+ vp56_mc(s, b, plane, frame_ref->data[plane], s->stride[plane],
+ 16*col+x_off, 16*row+y_off);
+ s->vp3dsp.idct_add(frame_current->data[plane] + s->block_offset[b],
+ s->stride[plane], s->block_coeff[b]);
+ }
+ break;
+ }
+
+ if (is_alpha) {
+ s->block_coeff[4][0] = 0;
+ s->block_coeff[5][0] = 0;
+ }
+}
+
+static int vp56_decode_mb(VP56Context *s, int row, int col, int is_alpha)
+{
+ VP56mb mb_type;
+ int ret;
+
+ if (s->frames[VP56_FRAME_CURRENT]->key_frame)
+ mb_type = VP56_MB_INTRA;
+ else
+ mb_type = vp56_decode_mv(s, row, col);
+
+ ret = s->parse_coeff(s);
+ if (ret < 0)
+ return ret;
+
+ vp56_render_mb(s, row, col, is_alpha, mb_type);
+
+ return 0;
+}
+
+static int vp56_conceal_mb(VP56Context *s, int row, int col, int is_alpha)
+{
+ VP56mb mb_type;
+
+ if (s->frames[VP56_FRAME_CURRENT]->key_frame)
+ mb_type = VP56_MB_INTRA;
+ else
+ mb_type = vp56_conceal_mv(s, row, col);
+
+ vp56_render_mb(s, row, col, is_alpha, mb_type);
+
+ return 0;
+}
+
+static int vp56_size_changed(VP56Context *s)
+{
+ AVCodecContext *avctx = s->avctx;
+ int stride = s->frames[VP56_FRAME_CURRENT]->linesize[0];
+ int i;
+
+ s->plane_width[0] = s->plane_width[3] = avctx->coded_width;
+ s->plane_width[1] = s->plane_width[2] = avctx->coded_width/2;
+ s->plane_height[0] = s->plane_height[3] = avctx->coded_height;
+ s->plane_height[1] = s->plane_height[2] = avctx->coded_height/2;
+
+ s->have_undamaged_frame = 0;
+
+ for (i=0; i<4; i++)
+ s->stride[i] = s->flip * s->frames[VP56_FRAME_CURRENT]->linesize[i];
+
+ s->mb_width = (avctx->coded_width +15) / 16;
+ s->mb_height = (avctx->coded_height+15) / 16;
+
+ if (s->mb_width > 1000 || s->mb_height > 1000) {
+ ff_set_dimensions(avctx, 0, 0);
+ av_log(avctx, AV_LOG_ERROR, "picture too big\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ av_reallocp_array(&s->above_blocks, 4*s->mb_width+6,
+ sizeof(*s->above_blocks));
+ av_reallocp_array(&s->macroblocks, s->mb_width*s->mb_height,
+ sizeof(*s->macroblocks));
+ av_free(s->edge_emu_buffer_alloc);
+ s->edge_emu_buffer_alloc = av_malloc(16*stride);
+ s->edge_emu_buffer = s->edge_emu_buffer_alloc;
+ if (!s->above_blocks || !s->macroblocks || !s->edge_emu_buffer_alloc)
+ return AVERROR(ENOMEM);
+ if (s->flip < 0)
+ s->edge_emu_buffer += 15 * stride;
+
+ if (s->alpha_context)
+ return vp56_size_changed(s->alpha_context);
+
+ return 0;
+}
+
+static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *, int, int);
+
+int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ const uint8_t *buf = avpkt->data;
+ VP56Context *s = avctx->priv_data;
+ AVFrame *const p = s->frames[VP56_FRAME_CURRENT];
+ int remaining_buf_size = avpkt->size;
+ int av_uninit(alpha_offset);
+ int i, res;
+ int ret;
+
+ if (s->has_alpha) {
+ if (remaining_buf_size < 3)
+ return AVERROR_INVALIDDATA;
+ alpha_offset = bytestream_get_be24(&buf);
+ remaining_buf_size -= 3;
+ if (remaining_buf_size < alpha_offset)
+ return AVERROR_INVALIDDATA;
+ }
+
+ res = s->parse_header(s, buf, remaining_buf_size);
+ if (res < 0)
+ return res;
+
+ if (res == VP56_SIZE_CHANGE) {
+ for (i = 0; i < 4; i++) {
+ av_frame_unref(s->frames[i]);
+ if (s->alpha_context)
+ av_frame_unref(s->alpha_context->frames[i]);
+ }
+ }
+
+ ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF);
+ if (ret < 0) {
+ if (res == VP56_SIZE_CHANGE)
+ ff_set_dimensions(avctx, 0, 0);
+ return ret;
+ }
+
+ if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) {
+ av_frame_unref(s->alpha_context->frames[VP56_FRAME_CURRENT]);
+ if ((ret = av_frame_ref(s->alpha_context->frames[VP56_FRAME_CURRENT], p)) < 0) {
+ av_frame_unref(p);
+ if (res == VP56_SIZE_CHANGE)
+ ff_set_dimensions(avctx, 0, 0);
+ return ret;
+ }
+ }
+
+ if (res == VP56_SIZE_CHANGE) {
+ if (vp56_size_changed(s)) {
+ av_frame_unref(p);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) {
+ int bak_w = avctx->width;
+ int bak_h = avctx->height;
+ int bak_cw = avctx->coded_width;
+ int bak_ch = avctx->coded_height;
+ buf += alpha_offset;
+ remaining_buf_size -= alpha_offset;
+
+ res = s->alpha_context->parse_header(s->alpha_context, buf, remaining_buf_size);
+ if (res != 0) {
+ if(res==VP56_SIZE_CHANGE) {
+ av_log(avctx, AV_LOG_ERROR, "Alpha reconfiguration\n");
+ avctx->width = bak_w;
+ avctx->height = bak_h;
+ avctx->coded_width = bak_cw;
+ avctx->coded_height = bak_ch;
+ }
+ av_frame_unref(p);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ s->discard_frame = 0;
+ avctx->execute2(avctx, ff_vp56_decode_mbs, 0, 0, (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) + 1);
+
+ if (s->discard_frame)
+ return AVERROR_INVALIDDATA;
+
+ if ((res = av_frame_ref(data, p)) < 0)
+ return res;
+ *got_frame = 1;
+
+ return avpkt->size;
+}
+
+static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data,
+ int jobnr, int threadnr)
+{
+ VP56Context *s0 = avctx->priv_data;
+ int is_alpha = (jobnr == 1);
+ VP56Context *s = is_alpha ? s0->alpha_context : s0;
+ AVFrame *const p = s->frames[VP56_FRAME_CURRENT];
+ int mb_row, mb_col, mb_row_flip, mb_offset = 0;
+ int block, y, uv;
+ ptrdiff_t stride_y, stride_uv;
+ int res;
+ int damaged = 0;
+
+ if (p->key_frame) {
+ p->pict_type = AV_PICTURE_TYPE_I;
+ s->default_models_init(s);
+ for (block=0; block<s->mb_height*s->mb_width; block++)
+ s->macroblocks[block].type = VP56_MB_INTRA;
+ } else {
+ p->pict_type = AV_PICTURE_TYPE_P;
+ vp56_parse_mb_type_models(s);
+ s->parse_vector_models(s);
+ s->mb_type = VP56_MB_INTER_NOVEC_PF;
+ }
+
+ if (s->parse_coeff_models(s))
+ goto next;
+
+ memset(s->prev_dc, 0, sizeof(s->prev_dc));
+ s->prev_dc[1][VP56_FRAME_CURRENT] = 128;
+ s->prev_dc[2][VP56_FRAME_CURRENT] = 128;
+
+ for (block=0; block < 4*s->mb_width+6; block++) {
+ s->above_blocks[block].ref_frame = VP56_FRAME_NONE;
+ s->above_blocks[block].dc_coeff = 0;
+ s->above_blocks[block].not_null_dc = 0;
+ }
+ s->above_blocks[2*s->mb_width + 2].ref_frame = VP56_FRAME_CURRENT;
+ s->above_blocks[3*s->mb_width + 4].ref_frame = VP56_FRAME_CURRENT;
+
+ stride_y = p->linesize[0];
+ stride_uv = p->linesize[1];
+
+ if (s->flip < 0)
+ mb_offset = 7;
+
+ /* main macroblocks loop */
+ for (mb_row=0; mb_row<s->mb_height; mb_row++) {
+ if (s->flip < 0)
+ mb_row_flip = s->mb_height - mb_row - 1;
+ else
+ mb_row_flip = mb_row;
+
+ for (block=0; block<4; block++) {
+ s->left_block[block].ref_frame = VP56_FRAME_NONE;
+ s->left_block[block].dc_coeff = 0;
+ s->left_block[block].not_null_dc = 0;
+ }
+ memset(s->coeff_ctx, 0, sizeof(s->coeff_ctx));
+ memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last));
+
+ s->above_block_idx[0] = 1;
+ s->above_block_idx[1] = 2;
+ s->above_block_idx[2] = 1;
+ s->above_block_idx[3] = 2;
+ s->above_block_idx[4] = 2*s->mb_width + 2 + 1;
+ s->above_block_idx[5] = 3*s->mb_width + 4 + 1;
+
+ s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y;
+ s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y;
+ s->block_offset[1] = s->block_offset[0] + 8;
+ s->block_offset[3] = s->block_offset[2] + 8;
+ s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv;
+ s->block_offset[5] = s->block_offset[4];
+
+ for (mb_col=0; mb_col<s->mb_width; mb_col++) {
+ if (!damaged) {
+ int ret = vp56_decode_mb(s, mb_row, mb_col, is_alpha);
+ if (ret < 0) {
+ damaged = 1;
+ if (!s->have_undamaged_frame || !avctx->error_concealment) {
+ s->discard_frame = 1;
+ return AVERROR_INVALIDDATA;
+ }
+ }
+ }
+ if (damaged)
+ vp56_conceal_mb(s, mb_row, mb_col, is_alpha);
+
+ for (y=0; y<4; y++) {
+ s->above_block_idx[y] += 2;
+ s->block_offset[y] += 16;
+ }
+
+ for (uv=4; uv<6; uv++) {
+ s->above_block_idx[uv] += 1;
+ s->block_offset[uv] += 8;
+ }
+ }
+ }
+
+ if (!damaged)
+ s->have_undamaged_frame = 1;
+
+next:
+ if (p->key_frame || s->golden_frame) {
+ av_frame_unref(s->frames[VP56_FRAME_GOLDEN]);
+ if ((res = av_frame_ref(s->frames[VP56_FRAME_GOLDEN], p)) < 0)
+ return res;
+ }
+
+ av_frame_unref(s->frames[VP56_FRAME_PREVIOUS]);
+ FFSWAP(AVFrame *, s->frames[VP56_FRAME_CURRENT],
+ s->frames[VP56_FRAME_PREVIOUS]);
+ return 0;
+}
+
+av_cold int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha)
+{
+ VP56Context *s = avctx->priv_data;
+ return ff_vp56_init_context(avctx, s, flip, has_alpha);
+}
+
+av_cold int ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
+ int flip, int has_alpha)
+{
+ int i;
+
+ s->avctx = avctx;
+ avctx->pix_fmt = has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P;
+ if (avctx->skip_alpha) avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+
+ ff_h264chroma_init(&s->h264chroma, 8);
+ ff_hpeldsp_init(&s->hdsp, avctx->flags);
+ ff_videodsp_init(&s->vdsp, 8);
+ ff_vp3dsp_init(&s->vp3dsp, avctx->flags);
+ ff_vp56dsp_init(&s->vp56dsp, avctx->codec->id);
+ for (i = 0; i < 64; i++) {
+#define TRANSPOSE(x) (((x) >> 3) | (((x) & 7) << 3))
+ s->idct_scantable[i] = TRANSPOSE(ff_zigzag_direct[i]);
+#undef TRANSPOSE
+ }
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) {
+ s->frames[i] = av_frame_alloc();
+ if (!s->frames[i]) {
+ ff_vp56_free(avctx);
+ return AVERROR(ENOMEM);
+ }
+ }
+ s->edge_emu_buffer_alloc = NULL;
+
+ s->above_blocks = NULL;
+ s->macroblocks = NULL;
+ s->quantizer = -1;
+ s->deblock_filtering = 1;
+ s->golden_frame = 0;
+
+ s->filter = NULL;
+
+ s->has_alpha = has_alpha;
+
+ s->modelp = &s->model;
+
+ if (flip) {
+ s->flip = -1;
+ s->frbi = 2;
+ s->srbi = 0;
+ } else {
+ s->flip = 1;
+ s->frbi = 0;
+ s->srbi = 2;
+ }
+
+ return 0;
+}
+
+av_cold int ff_vp56_free(AVCodecContext *avctx)
+{
+ VP56Context *s = avctx->priv_data;
+ return ff_vp56_free_context(s);
+}
+
+av_cold int ff_vp56_free_context(VP56Context *s)
+{
+ int i;
+
+ av_freep(&s->above_blocks);
+ av_freep(&s->macroblocks);
+ av_freep(&s->edge_emu_buffer_alloc);
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++)
+ av_frame_free(&s->frames[i]);
+
+ return 0;
+}
diff --git a/ffmpeg-2-8-12/libavcodec/vp56.h b/ffmpeg-2-8-12/libavcodec/vp56.h
new file mode 100644
index 0000000..c049399
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/vp56.h
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.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
+ * VP5 and VP6 compatible video decoder (common features)
+ */
+
+#ifndef AVCODEC_VP56_H
+#define AVCODEC_VP56_H
+
+#include "get_bits.h"
+#include "hpeldsp.h"
+#include "bytestream.h"
+#include "h264chroma.h"
+#include "videodsp.h"
+#include "vp3dsp.h"
+#include "vp56dsp.h"
+
+typedef struct vp56_context VP56Context;
+
+typedef enum {
+ VP56_FRAME_NONE =-1,
+ VP56_FRAME_CURRENT = 0,
+ VP56_FRAME_PREVIOUS = 1,
+ VP56_FRAME_GOLDEN = 2,
+ VP56_FRAME_GOLDEN2 = 3,
+} VP56Frame;
+
+typedef enum {
+ VP56_MB_INTER_NOVEC_PF = 0, /**< Inter MB, no vector, from previous frame */
+ VP56_MB_INTRA = 1, /**< Intra MB */
+ VP56_MB_INTER_DELTA_PF = 2, /**< Inter MB, above/left vector + delta, from previous frame */
+ VP56_MB_INTER_V1_PF = 3, /**< Inter MB, first vector, from previous frame */
+ VP56_MB_INTER_V2_PF = 4, /**< Inter MB, second vector, from previous frame */
+ VP56_MB_INTER_NOVEC_GF = 5, /**< Inter MB, no vector, from golden frame */
+ VP56_MB_INTER_DELTA_GF = 6, /**< Inter MB, above/left vector + delta, from golden frame */
+ VP56_MB_INTER_4V = 7, /**< Inter MB, 4 vectors, from previous frame */
+ VP56_MB_INTER_V1_GF = 8, /**< Inter MB, first vector, from golden frame */
+ VP56_MB_INTER_V2_GF = 9, /**< Inter MB, second vector, from golden frame */
+} VP56mb;
+
+typedef struct VP56Tree {
+ int8_t val;
+ int8_t prob_idx;
+} VP56Tree;
+
+typedef struct VP56mv {
+ DECLARE_ALIGNED(4, int16_t, x);
+ int16_t y;
+} VP56mv;
+
+#define VP56_SIZE_CHANGE 1
+
+typedef void (*VP56ParseVectorAdjustment)(VP56Context *s,
+ VP56mv *vect);
+typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src,
+ int offset1, int offset2, int stride,
+ VP56mv mv, int mask, int select, int luma);
+typedef int (*VP56ParseCoeff)(VP56Context *s);
+typedef void (*VP56DefaultModelsInit)(VP56Context *s);
+typedef void (*VP56ParseVectorModels)(VP56Context *s);
+typedef int (*VP56ParseCoeffModels)(VP56Context *s);
+typedef int (*VP56ParseHeader)(VP56Context *s, const uint8_t *buf,
+ int buf_size);
+
+typedef struct VP56RangeCoder {
+ int high;
+ int bits; /* stored negated (i.e. negative "bits" is a positive number of
+ bits left) in order to eliminate a negate in cache refilling */
+ const uint8_t *buffer;
+ const uint8_t *end;
+ unsigned int code_word;
+} VP56RangeCoder;
+
+typedef struct VP56RefDc {
+ uint8_t not_null_dc;
+ VP56Frame ref_frame;
+ int16_t dc_coeff;
+} VP56RefDc;
+
+typedef struct VP56Macroblock {
+ uint8_t type;
+ VP56mv mv;
+} VP56Macroblock;
+
+typedef struct VP56Model {
+ uint8_t coeff_reorder[64]; /* used in vp6 only */
+ uint8_t coeff_index_to_pos[64]; /* used in vp6 only */
+ uint8_t vector_sig[2]; /* delta sign */
+ uint8_t vector_dct[2]; /* delta coding types */
+ uint8_t vector_pdi[2][2]; /* predefined delta init */
+ uint8_t vector_pdv[2][7]; /* predefined delta values */
+ uint8_t vector_fdv[2][8]; /* 8 bit delta value definition */
+ uint8_t coeff_dccv[2][11]; /* DC coeff value */
+ uint8_t coeff_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */
+ uint8_t coeff_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */
+ uint8_t coeff_dcct[2][36][5]; /* DC coeff coding type */
+ uint8_t coeff_runv[2][14]; /* run value (vp6 only) */
+ uint8_t mb_type[3][10][10]; /* model for decoding MB type */
+ uint8_t mb_types_stats[3][10][2];/* contextual, next MB type stats */
+} VP56Model;
+
+struct vp56_context {
+ AVCodecContext *avctx;
+ H264ChromaContext h264chroma;
+ HpelDSPContext hdsp;
+ VideoDSPContext vdsp;
+ VP3DSPContext vp3dsp;
+ VP56DSPContext vp56dsp;
+ uint8_t idct_scantable[64];
+ AVFrame *frames[4];
+ uint8_t *edge_emu_buffer_alloc;
+ uint8_t *edge_emu_buffer;
+ VP56RangeCoder c;
+ VP56RangeCoder cc;
+ VP56RangeCoder *ccp;
+ int sub_version;
+
+ /* frame info */
+ int golden_frame;
+ int plane_width[4];
+ int plane_height[4];
+ int mb_width; /* number of horizontal MB */
+ int mb_height; /* number of vertical MB */
+ int block_offset[6];
+
+ int quantizer;
+ uint16_t dequant_dc;
+ uint16_t dequant_ac;
+
+ /* DC predictors management */
+ VP56RefDc *above_blocks;
+ VP56RefDc left_block[4];
+ int above_block_idx[6];
+ int16_t prev_dc[3][3]; /* [plan][ref_frame] */
+
+ /* blocks / macroblock */
+ VP56mb mb_type;
+ VP56Macroblock *macroblocks;
+ DECLARE_ALIGNED(16, int16_t, block_coeff)[6][64];
+
+ /* motion vectors */
+ VP56mv mv[6]; /* vectors for each block in MB */
+ VP56mv vector_candidate[2];
+ int vector_candidate_pos;
+
+ /* filtering hints */
+ int filter_header; /* used in vp6 only */
+ int deblock_filtering;
+ int filter_selection;
+ int filter_mode;
+ int max_vector_length;
+ int sample_variance_threshold;
+
+ uint8_t coeff_ctx[4][64]; /* used in vp5 only */
+ uint8_t coeff_ctx_last[4]; /* used in vp5 only */
+
+ int has_alpha;
+
+ /* upside-down flipping hints */
+ int flip; /* are we flipping ? */
+ int frbi; /* first row block index in MB */
+ int srbi; /* second row block index in MB */
+ int stride[4]; /* stride for each plan */
+
+ const uint8_t *vp56_coord_div;
+ VP56ParseVectorAdjustment parse_vector_adjustment;
+ VP56Filter filter;
+ VP56ParseCoeff parse_coeff;
+ VP56DefaultModelsInit default_models_init;
+ VP56ParseVectorModels parse_vector_models;
+ VP56ParseCoeffModels parse_coeff_models;
+ VP56ParseHeader parse_header;
+
+ /* for "slice" parallelism between YUV and A */
+ VP56Context *alpha_context;
+
+ VP56Model *modelp;
+ VP56Model model;
+
+ /* huffman decoding */
+ int use_huffman;
+ GetBitContext gb;
+ VLC dccv_vlc[2];
+ VLC runv_vlc[2];
+ VLC ract_vlc[2][3][6];
+ unsigned int nb_null[2][2]; /* number of consecutive NULL DC/AC */
+
+ int have_undamaged_frame;
+ int discard_frame;
+};
+
+
+int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha);
+int ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
+ int flip, int has_alpha);
+int ff_vp56_free(AVCodecContext *avctx);
+int ff_vp56_free_context(VP56Context *s);
+void ff_vp56_init_dequant(VP56Context *s, int quantizer);
+int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt);
+
+
+/**
+ * vp56 specific range coder implementation
+ */
+
+extern const uint8_t ff_vp56_norm_shift[256];
+int ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size);
+
+static av_always_inline unsigned int vp56_rac_renorm(VP56RangeCoder *c)
+{
+ int shift = ff_vp56_norm_shift[c->high];
+ int bits = c->bits;
+ unsigned int code_word = c->code_word;
+
+ c->high <<= shift;
+ code_word <<= shift;
+ bits += shift;
+ if(bits >= 0 && c->buffer < c->end) {
+ code_word |= bytestream_get_be16(&c->buffer) << bits;
+ bits -= 16;
+ }
+ c->bits = bits;
+ return code_word;
+}
+
+#if ARCH_ARM
+#include "arm/vp56_arith.h"
+#elif ARCH_X86
+#include "x86/vp56_arith.h"
+#endif
+
+#ifndef vp56_rac_get_prob
+#define vp56_rac_get_prob vp56_rac_get_prob
+static av_always_inline int vp56_rac_get_prob(VP56RangeCoder *c, uint8_t prob)
+{
+ unsigned int code_word = vp56_rac_renorm(c);
+ unsigned int low = 1 + (((c->high - 1) * prob) >> 8);
+ unsigned int low_shift = low << 16;
+ int bit = code_word >= low_shift;
+
+ c->high = bit ? c->high - low : low;
+ c->code_word = bit ? code_word - low_shift : code_word;
+
+ return bit;
+}
+#endif
+
+#ifndef vp56_rac_get_prob_branchy
+// branchy variant, to be used where there's a branch based on the bit decoded
+static av_always_inline int vp56_rac_get_prob_branchy(VP56RangeCoder *c, int prob)
+{
+ unsigned long code_word = vp56_rac_renorm(c);
+ unsigned low = 1 + (((c->high - 1) * prob) >> 8);
+ unsigned low_shift = low << 16;
+
+ if (code_word >= low_shift) {
+ c->high -= low;
+ c->code_word = code_word - low_shift;
+ return 1;
+ }
+
+ c->high = low;
+ c->code_word = code_word;
+ return 0;
+}
+#endif
+
+static av_always_inline int vp56_rac_get(VP56RangeCoder *c)
+{
+ unsigned int code_word = vp56_rac_renorm(c);
+ /* equiprobable */
+ int low = (c->high + 1) >> 1;
+ unsigned int low_shift = low << 16;
+ int bit = code_word >= low_shift;
+ if (bit) {
+ c->high -= low;
+ code_word -= low_shift;
+ } else {
+ c->high = low;
+ }
+
+ c->code_word = code_word;
+ return bit;
+}
+
+// rounding is different than vp56_rac_get, is vp56_rac_get wrong?
+static av_always_inline int vp8_rac_get(VP56RangeCoder *c)
+{
+ return vp56_rac_get_prob(c, 128);
+}
+
+static int vp56_rac_gets(VP56RangeCoder *c, int bits)
+{
+ int value = 0;
+
+ while (bits--) {
+ value = (value << 1) | vp56_rac_get(c);
+ }
+
+ return value;
+}
+
+static int vp8_rac_get_uint(VP56RangeCoder *c, int bits)
+{
+ int value = 0;
+
+ while (bits--) {
+ value = (value << 1) | vp8_rac_get(c);
+ }
+
+ return value;
+}
+
+// fixme: add 1 bit to all the calls to this?
+static av_unused int vp8_rac_get_sint(VP56RangeCoder *c, int bits)
+{
+ int v;
+
+ if (!vp8_rac_get(c))
+ return 0;
+
+ v = vp8_rac_get_uint(c, bits);
+
+ if (vp8_rac_get(c))
+ v = -v;
+
+ return v;
+}
+
+// P(7)
+static av_unused int vp56_rac_gets_nn(VP56RangeCoder *c, int bits)
+{
+ int v = vp56_rac_gets(c, 7) << 1;
+ return v + !v;
+}
+
+static av_unused int vp8_rac_get_nn(VP56RangeCoder *c)
+{
+ int v = vp8_rac_get_uint(c, 7) << 1;
+ return v + !v;
+}
+
+static av_always_inline
+int vp56_rac_get_tree(VP56RangeCoder *c,
+ const VP56Tree *tree,
+ const uint8_t *probs)
+{
+ while (tree->val > 0) {
+ if (vp56_rac_get_prob_branchy(c, probs[tree->prob_idx]))
+ tree += tree->val;
+ else
+ tree++;
+ }
+ return -tree->val;
+}
+
+// how probabilities are associated with decisions is different I think
+// well, the new scheme fits in the old but this way has one fewer branches per decision
+static av_always_inline int vp8_rac_get_tree(VP56RangeCoder *c, const int8_t (*tree)[2],
+ const uint8_t *probs)
+{
+ int i = 0;
+
+ do {
+ i = tree[i][vp56_rac_get_prob(c, probs[i])];
+ } while (i > 0);
+
+ return -i;
+}
+
+// DCTextra
+static av_always_inline int vp8_rac_get_coeff(VP56RangeCoder *c, const uint8_t *prob)
+{
+ int v = 0;
+
+ do {
+ v = (v<<1) + vp56_rac_get_prob(c, *prob++);
+ } while (*prob);
+
+ return v;
+}
+
+#endif /* AVCODEC_VP56_H */
diff --git a/ffmpeg-2-8-11/libavcodec/vp56data.c b/ffmpeg-2-8-12/libavcodec/vp56data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp56data.c
rename to ffmpeg-2-8-12/libavcodec/vp56data.c
diff --git a/ffmpeg-2-8-11/libavcodec/vp56data.h b/ffmpeg-2-8-12/libavcodec/vp56data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp56data.h
rename to ffmpeg-2-8-12/libavcodec/vp56data.h
diff --git a/ffmpeg-2-8-11/libavcodec/vp56dsp.c b/ffmpeg-2-8-12/libavcodec/vp56dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp56dsp.c
rename to ffmpeg-2-8-12/libavcodec/vp56dsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/vp56dsp.h b/ffmpeg-2-8-12/libavcodec/vp56dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp56dsp.h
rename to ffmpeg-2-8-12/libavcodec/vp56dsp.h
diff --git a/ffmpeg-2-8-12/libavcodec/vp56rac.c b/ffmpeg-2-8-12/libavcodec/vp56rac.c
new file mode 100644
index 0000000..e70302b
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/vp56rac.c
@@ -0,0 +1,50 @@
+/*
+ * VP5/6/8 decoder
+ * Copyright (c) 2010 Fiona Glaser <fiona at x264.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 "libavutil/common.h"
+#include "vp56.h"
+
+const uint8_t ff_vp56_norm_shift[256]= {
+ 8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4,
+ 3,3,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,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,
+ 1,1,1,1,1,1,1,1,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,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+};
+
+int ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size)
+{
+ c->high = 255;
+ c->bits = -16;
+ c->buffer = buf;
+ c->end = buf + buf_size;
+ if (buf_size < 1)
+ return AVERROR_INVALIDDATA;
+ c->code_word = bytestream_get_be24(&c->buffer);
+ return 0;
+}
diff --git a/ffmpeg-2-8-11/libavcodec/vp5data.h b/ffmpeg-2-8-12/libavcodec/vp5data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp5data.h
rename to ffmpeg-2-8-12/libavcodec/vp5data.h
diff --git a/ffmpeg-2-8-12/libavcodec/vp6.c b/ffmpeg-2-8-12/libavcodec/vp6.c
new file mode 100644
index 0000000..4afd67b
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/vp6.c
@@ -0,0 +1,726 @@
+/*
+ * Copyright (C) 2006 Aurelien Jacobs <aurel at gnuage.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
+ * VP6 compatible video decoder
+ *
+ * The VP6F decoder accepts an optional 1 byte extradata. It is composed of:
+ * - upper 4 bits: difference between encoded width and visible width
+ * - lower 4 bits: difference between encoded height and visible height
+ */
+
+#include <stdlib.h>
+
+#include "avcodec.h"
+#include "get_bits.h"
+#include "huffman.h"
+#include "internal.h"
+
+#include "vp56.h"
+#include "vp56data.h"
+#include "vp6data.h"
+
+#define VP6_MAX_HUFF_SIZE 12
+
+static int vp6_parse_coeff(VP56Context *s);
+static int vp6_parse_coeff_huffman(VP56Context *s);
+
+static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
+{
+ VP56RangeCoder *c = &s->c;
+ int parse_filter_info = 0;
+ int coeff_offset = 0;
+ int vrt_shift = 0;
+ int sub_version;
+ int rows, cols;
+ int res = 0;
+ int ret;
+ int separated_coeff = buf[0] & 1;
+
+ s->frames[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80);
+ ff_vp56_init_dequant(s, (buf[0] >> 1) & 0x3F);
+
+ if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
+ sub_version = buf[1] >> 3;
+ if (sub_version > 8)
+ return AVERROR_INVALIDDATA;
+ s->filter_header = buf[1] & 0x06;
+ if (buf[1] & 1) {
+ avpriv_report_missing_feature(s->avctx, "Interlacing");
+ return AVERROR_PATCHWELCOME;
+ }
+ if (separated_coeff || !s->filter_header) {
+ coeff_offset = AV_RB16(buf+2) - 2;
+ buf += 2;
+ buf_size -= 2;
+ }
+
+ rows = buf[2]; /* number of stored macroblock rows */
+ cols = buf[3]; /* number of stored macroblock cols */
+ /* buf[4] is number of displayed macroblock rows */
+ /* buf[5] is number of displayed macroblock cols */
+ if (!rows || !cols) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n", cols << 4, rows << 4);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!s->macroblocks || /* first frame */
+ 16*cols != s->avctx->coded_width ||
+ 16*rows != s->avctx->coded_height) {
+ if (s->avctx->extradata_size == 0 &&
+ FFALIGN(s->avctx->width, 16) == 16 * cols &&
+ FFALIGN(s->avctx->height, 16) == 16 * rows) {
+ // We assume this is properly signalled container cropping,
+ // in an F4V file. Just set the coded_width/height, don't
+ // touch the cropped ones.
+ s->avctx->coded_width = 16 * cols;
+ s->avctx->coded_height = 16 * rows;
+ } else {
+ ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows);
+ if (ret < 0)
+ return ret;
+
+ if (s->avctx->extradata_size == 1) {
+ s->avctx->width -= s->avctx->extradata[0] >> 4;
+ s->avctx->height -= s->avctx->extradata[0] & 0x0F;
+ }
+ }
+ res = VP56_SIZE_CHANGE;
+ }
+
+ ret = ff_vp56_init_range_decoder(c, buf+6, buf_size-6);
+ if (ret < 0)
+ goto fail;
+ vp56_rac_gets(c, 2);
+
+ parse_filter_info = s->filter_header;
+ if (sub_version < 8)
+ vrt_shift = 5;
+ s->sub_version = sub_version;
+ s->golden_frame = 0;
+ } else {
+ if (!s->sub_version || !s->avctx->coded_width || !s->avctx->coded_height)
+ return AVERROR_INVALIDDATA;
+
+ if (separated_coeff || !s->filter_header) {
+ coeff_offset = AV_RB16(buf+1) - 2;
+ buf += 2;
+ buf_size -= 2;
+ }
+ ret = ff_vp56_init_range_decoder(c, buf+1, buf_size-1);
+ if (ret < 0)
+ return ret;
+
+ s->golden_frame = vp56_rac_get(c);
+ if (s->filter_header) {
+ s->deblock_filtering = vp56_rac_get(c);
+ if (s->deblock_filtering)
+ vp56_rac_get(c);
+ if (s->sub_version > 7)
+ parse_filter_info = vp56_rac_get(c);
+ }
+ }
+
+ if (parse_filter_info) {
+ if (vp56_rac_get(c)) {
+ s->filter_mode = 2;
+ s->sample_variance_threshold = vp56_rac_gets(c, 5) << vrt_shift;
+ s->max_vector_length = 2 << vp56_rac_gets(c, 3);
+ } else if (vp56_rac_get(c)) {
+ s->filter_mode = 1;
+ } else {
+ s->filter_mode = 0;
+ }
+ if (s->sub_version > 7)
+ s->filter_selection = vp56_rac_gets(c, 4);
+ else
+ s->filter_selection = 16;
+ }
+
+ s->use_huffman = vp56_rac_get(c);
+
+ s->parse_coeff = vp6_parse_coeff;
+ if (coeff_offset) {
+ buf += coeff_offset;
+ buf_size -= coeff_offset;
+ if (buf_size < 0) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ if (s->use_huffman) {
+ s->parse_coeff = vp6_parse_coeff_huffman;
+ init_get_bits(&s->gb, buf, buf_size<<3);
+ } else {
+ ret = ff_vp56_init_range_decoder(&s->cc, buf, buf_size);
+ if (ret < 0)
+ goto fail;
+ s->ccp = &s->cc;
+ }
+ } else {
+ s->ccp = &s->c;
+ }
+
+ return res;
+fail:
+ if (res == VP56_SIZE_CHANGE)
+ ff_set_dimensions(s->avctx, 0, 0);
+ return ret;
+}
+
+static void vp6_coeff_order_table_init(VP56Context *s)
+{
+ int i, pos, idx = 1;
+
+ s->modelp->coeff_index_to_pos[0] = 0;
+ for (i=0; i<16; i++)
+ for (pos=1; pos<64; pos++)
+ if (s->modelp->coeff_reorder[pos] == i)
+ s->modelp->coeff_index_to_pos[idx++] = pos;
+}
+
+static void vp6_default_models_init(VP56Context *s)
+{
+ VP56Model *model = s->modelp;
+
+ model->vector_dct[0] = 0xA2;
+ model->vector_dct[1] = 0xA4;
+ model->vector_sig[0] = 0x80;
+ model->vector_sig[1] = 0x80;
+
+ memcpy(model->mb_types_stats, ff_vp56_def_mb_types_stats, sizeof(model->mb_types_stats));
+ memcpy(model->vector_fdv, vp6_def_fdv_vector_model, sizeof(model->vector_fdv));
+ memcpy(model->vector_pdv, vp6_def_pdv_vector_model, sizeof(model->vector_pdv));
+ memcpy(model->coeff_runv, vp6_def_runv_coeff_model, sizeof(model->coeff_runv));
+ memcpy(model->coeff_reorder, vp6_def_coeff_reorder, sizeof(model->coeff_reorder));
+
+ vp6_coeff_order_table_init(s);
+}
+
+static void vp6_parse_vector_models(VP56Context *s)
+{
+ VP56RangeCoder *c = &s->c;
+ VP56Model *model = s->modelp;
+ int comp, node;
+
+ for (comp=0; comp<2; comp++) {
+ if (vp56_rac_get_prob_branchy(c, vp6_sig_dct_pct[comp][0]))
+ model->vector_dct[comp] = vp56_rac_gets_nn(c, 7);
+ if (vp56_rac_get_prob_branchy(c, vp6_sig_dct_pct[comp][1]))
+ model->vector_sig[comp] = vp56_rac_gets_nn(c, 7);
+ }
+
+ for (comp=0; comp<2; comp++)
+ for (node=0; node<7; node++)
+ if (vp56_rac_get_prob_branchy(c, vp6_pdv_pct[comp][node]))
+ model->vector_pdv[comp][node] = vp56_rac_gets_nn(c, 7);
+
+ for (comp=0; comp<2; comp++)
+ for (node=0; node<8; node++)
+ if (vp56_rac_get_prob_branchy(c, vp6_fdv_pct[comp][node]))
+ model->vector_fdv[comp][node] = vp56_rac_gets_nn(c, 7);
+}
+
+/* nodes must ascend by count, but with descending symbol order */
+static int vp6_huff_cmp(const void *va, const void *vb)
+{
+ const Node *a = va, *b = vb;
+ return (a->count - b->count)*16 + (b->sym - a->sym);
+}
+
+static int vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[],
+ const uint8_t *map, unsigned size, VLC *vlc)
+{
+ Node nodes[2*VP6_MAX_HUFF_SIZE], *tmp = &nodes[size];
+ int a, b, i;
+
+ /* first compute probabilities from model */
+ tmp[0].count = 256;
+ for (i=0; i<size-1; i++) {
+ a = tmp[i].count * coeff_model[i] >> 8;
+ b = tmp[i].count * (255 - coeff_model[i]) >> 8;
+ nodes[map[2*i ]].count = a + !a;
+ nodes[map[2*i+1]].count = b + !b;
+ }
+
+ ff_free_vlc(vlc);
+ /* then build the huffman tree according to probabilities */
+ return ff_huff_build_tree(s->avctx, vlc, size, FF_HUFFMAN_BITS,
+ nodes, vp6_huff_cmp,
+ FF_HUFFMAN_FLAG_HNODE_FIRST);
+}
+
+static int vp6_parse_coeff_models(VP56Context *s)
+{
+ VP56RangeCoder *c = &s->c;
+ VP56Model *model = s->modelp;
+ int def_prob[11];
+ int node, cg, ctx, pos;
+ int ct; /* code type */
+ int pt; /* plane type (0 for Y, 1 for U or V) */
+
+ memset(def_prob, 0x80, sizeof(def_prob));
+
+ for (pt=0; pt<2; pt++)
+ for (node=0; node<11; node++)
+ if (vp56_rac_get_prob_branchy(c, vp6_dccv_pct[pt][node])) {
+ def_prob[node] = vp56_rac_gets_nn(c, 7);
+ model->coeff_dccv[pt][node] = def_prob[node];
+ } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
+ model->coeff_dccv[pt][node] = def_prob[node];
+ }
+
+ if (vp56_rac_get(c)) {
+ for (pos=1; pos<64; pos++)
+ if (vp56_rac_get_prob_branchy(c, vp6_coeff_reorder_pct[pos]))
+ model->coeff_reorder[pos] = vp56_rac_gets(c, 4);
+ vp6_coeff_order_table_init(s);
+ }
+
+ for (cg=0; cg<2; cg++)
+ for (node=0; node<14; node++)
+ if (vp56_rac_get_prob_branchy(c, vp6_runv_pct[cg][node]))
+ model->coeff_runv[cg][node] = vp56_rac_gets_nn(c, 7);
+
+ for (ct=0; ct<3; ct++)
+ for (pt=0; pt<2; pt++)
+ for (cg=0; cg<6; cg++)
+ for (node=0; node<11; node++)
+ if (vp56_rac_get_prob_branchy(c, vp6_ract_pct[ct][pt][cg][node])) {
+ def_prob[node] = vp56_rac_gets_nn(c, 7);
+ model->coeff_ract[pt][ct][cg][node] = def_prob[node];
+ } else if (s->frames[VP56_FRAME_CURRENT]->key_frame) {
+ model->coeff_ract[pt][ct][cg][node] = def_prob[node];
+ }
+
+ if (s->use_huffman) {
+ for (pt=0; pt<2; pt++) {
+ if (vp6_build_huff_tree(s, model->coeff_dccv[pt],
+ vp6_huff_coeff_map, 12, &s->dccv_vlc[pt]))
+ return -1;
+ if (vp6_build_huff_tree(s, model->coeff_runv[pt],
+ vp6_huff_run_map, 9, &s->runv_vlc[pt]))
+ return -1;
+ for (ct=0; ct<3; ct++)
+ for (cg = 0; cg < 6; cg++)
+ if (vp6_build_huff_tree(s, model->coeff_ract[pt][ct][cg],
+ vp6_huff_coeff_map, 12,
+ &s->ract_vlc[pt][ct][cg]))
+ return -1;
+ }
+ memset(s->nb_null, 0, sizeof(s->nb_null));
+ } else {
+ /* coeff_dcct is a linear combination of coeff_dccv */
+ for (pt=0; pt<2; pt++)
+ for (ctx=0; ctx<3; ctx++)
+ for (node=0; node<5; node++)
+ model->coeff_dcct[pt][ctx][node] = av_clip(((model->coeff_dccv[pt][node] * vp6_dccv_lc[ctx][node][0] + 128) >> 8) + vp6_dccv_lc[ctx][node][1], 1, 255);
+ }
+ return 0;
+}
+
+static void vp6_parse_vector_adjustment(VP56Context *s, VP56mv *vect)
+{
+ VP56RangeCoder *c = &s->c;
+ VP56Model *model = s->modelp;
+ int comp;
+
+ *vect = (VP56mv) {0,0};
+ if (s->vector_candidate_pos < 2)
+ *vect = s->vector_candidate[0];
+
+ for (comp=0; comp<2; comp++) {
+ int i, delta = 0;
+
+ if (vp56_rac_get_prob_branchy(c, model->vector_dct[comp])) {
+ static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4};
+ for (i=0; i<sizeof(prob_order); i++) {
+ int j = prob_order[i];
+ delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][j])<<j;
+ }
+ if (delta & 0xF0)
+ delta |= vp56_rac_get_prob(c, model->vector_fdv[comp][3])<<3;
+ else
+ delta |= 8;
+ } else {
+ delta = vp56_rac_get_tree(c, ff_vp56_pva_tree,
+ model->vector_pdv[comp]);
+ }
+
+ if (delta && vp56_rac_get_prob_branchy(c, model->vector_sig[comp]))
+ delta = -delta;
+
+ if (!comp)
+ vect->x += delta;
+ else
+ vect->y += delta;
+ }
+}
+
+/**
+ * Read number of consecutive blocks with null DC or AC.
+ * This value is < 74.
+ */
+static unsigned vp6_get_nb_null(VP56Context *s)
+{
+ unsigned val = get_bits(&s->gb, 2);
+ if (val == 2)
+ val += get_bits(&s->gb, 2);
+ else if (val == 3) {
+ val = get_bits1(&s->gb) << 2;
+ val = 6+val + get_bits(&s->gb, 2+val);
+ }
+ return val;
+}
+
+static int vp6_parse_coeff_huffman(VP56Context *s)
+{
+ VP56Model *model = s->modelp;
+ uint8_t *permute = s->idct_scantable;
+ VLC *vlc_coeff;
+ int coeff, sign, coeff_idx;
+ int b, cg, idx;
+ int pt = 0; /* plane type (0 for Y, 1 for U or V) */
+
+ for (b=0; b<6; b++) {
+ int ct = 0; /* code type */
+ if (b > 3) pt = 1;
+ vlc_coeff = &s->dccv_vlc[pt];
+
+ for (coeff_idx = 0;;) {
+ int run = 1;
+ if (coeff_idx<2 && s->nb_null[coeff_idx][pt]) {
+ s->nb_null[coeff_idx][pt]--;
+ if (coeff_idx)
+ break;
+ } else {
+ if (get_bits_left(&s->gb) <= 0)
+ return AVERROR_INVALIDDATA;
+ coeff = get_vlc2(&s->gb, vlc_coeff->table, FF_HUFFMAN_BITS, 3);
+ if (coeff == 0) {
+ if (coeff_idx) {
+ int pt = (coeff_idx >= 6);
+ run += get_vlc2(&s->gb, s->runv_vlc[pt].table, FF_HUFFMAN_BITS, 3);
+ if (run >= 9)
+ run += get_bits(&s->gb, 6);
+ } else
+ s->nb_null[0][pt] = vp6_get_nb_null(s);
+ ct = 0;
+ } else if (coeff == 11) { /* end of block */
+ if (coeff_idx == 1) /* first AC coeff ? */
+ s->nb_null[1][pt] = vp6_get_nb_null(s);
+ break;
+ } else {
+ int coeff2 = ff_vp56_coeff_bias[coeff];
+ if (coeff > 4)
+ coeff2 += get_bits(&s->gb, coeff <= 9 ? coeff - 4 : 11);
+ ct = 1 + (coeff2 > 1);
+ sign = get_bits1(&s->gb);
+ coeff2 = (coeff2 ^ -sign) + sign;
+ if (coeff_idx)
+ coeff2 *= s->dequant_ac;
+ idx = model->coeff_index_to_pos[coeff_idx];
+ s->block_coeff[b][permute[idx]] = coeff2;
+ }
+ }
+ coeff_idx+=run;
+ if (coeff_idx >= 64)
+ break;
+ cg = FFMIN(vp6_coeff_groups[coeff_idx], 3);
+ vlc_coeff = &s->ract_vlc[pt][ct][cg];
+ }
+ }
+ return 0;
+}
+
+static int vp6_parse_coeff(VP56Context *s)
+{
+ VP56RangeCoder *c = s->ccp;
+ VP56Model *model = s->modelp;
+ uint8_t *permute = s->idct_scantable;
+ uint8_t *model1, *model2, *model3;
+ int coeff, sign, coeff_idx;
+ int b, i, cg, idx, ctx;
+ int pt = 0; /* plane type (0 for Y, 1 for U or V) */
+
+ if (c->end <= c->buffer && c->bits >= 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "End of AC stream reached in vp6_parse_coeff\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (b=0; b<6; b++) {
+ int ct = 1; /* code type */
+ int run = 1;
+
+ if (b > 3) pt = 1;
+
+ ctx = s->left_block[ff_vp56_b6to4[b]].not_null_dc
+ + s->above_blocks[s->above_block_idx[b]].not_null_dc;
+ model1 = model->coeff_dccv[pt];
+ model2 = model->coeff_dcct[pt][ctx];
+
+ coeff_idx = 0;
+ for (;;) {
+ if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob_branchy(c, model2[0])) {
+ /* parse a coeff */
+ if (vp56_rac_get_prob_branchy(c, model2[2])) {
+ if (vp56_rac_get_prob_branchy(c, model2[3])) {
+ idx = vp56_rac_get_tree(c, ff_vp56_pc_tree, model1);
+ coeff = ff_vp56_coeff_bias[idx+5];
+ for (i=ff_vp56_coeff_bit_length[idx]; i>=0; i--)
+ coeff += vp56_rac_get_prob(c, ff_vp56_coeff_parse_table[idx][i]) << i;
+ } else {
+ if (vp56_rac_get_prob_branchy(c, model2[4]))
+ coeff = 3 + vp56_rac_get_prob(c, model1[5]);
+ else
+ coeff = 2;
+ }
+ ct = 2;
+ } else {
+ ct = 1;
+ coeff = 1;
+ }
+ sign = vp56_rac_get(c);
+ coeff = (coeff ^ -sign) + sign;
+ if (coeff_idx)
+ coeff *= s->dequant_ac;
+ idx = model->coeff_index_to_pos[coeff_idx];
+ s->block_coeff[b][permute[idx]] = coeff;
+ run = 1;
+ } else {
+ /* parse a run */
+ ct = 0;
+ if (coeff_idx > 0) {
+ if (!vp56_rac_get_prob_branchy(c, model2[1]))
+ break;
+
+ model3 = model->coeff_runv[coeff_idx >= 6];
+ run = vp56_rac_get_tree(c, vp6_pcr_tree, model3);
+ if (!run)
+ for (run=9, i=0; i<6; i++)
+ run += vp56_rac_get_prob(c, model3[i+8]) << i;
+ }
+ }
+ coeff_idx += run;
+ if (coeff_idx >= 64)
+ break;
+ cg = vp6_coeff_groups[coeff_idx];
+ model1 = model2 = model->coeff_ract[pt][ct][cg];
+ }
+
+ s->left_block[ff_vp56_b6to4[b]].not_null_dc =
+ s->above_blocks[s->above_block_idx[b]].not_null_dc = !!s->block_coeff[b][0];
+ }
+ return 0;
+}
+
+static int vp6_block_variance(uint8_t *src, int stride)
+{
+ int sum = 0, square_sum = 0;
+ int y, x;
+
+ for (y=0; y<8; y+=2) {
+ for (x=0; x<8; x+=2) {
+ sum += src[x];
+ square_sum += src[x]*src[x];
+ }
+ src += 2*stride;
+ }
+ return (16*square_sum - sum*sum) >> 8;
+}
+
+static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride,
+ int delta, const int16_t *weights)
+{
+ int x, y;
+
+ for (y=0; y<8; y++) {
+ for (x=0; x<8; x++) {
+ dst[x] = av_clip_uint8(( src[x-delta ] * weights[0]
+ + src[x ] * weights[1]
+ + src[x+delta ] * weights[2]
+ + src[x+2*delta] * weights[3] + 64) >> 7);
+ }
+ src += stride;
+ dst += stride;
+ }
+}
+
+static void vp6_filter_diag2(VP56Context *s, uint8_t *dst, uint8_t *src,
+ int stride, int h_weight, int v_weight)
+{
+ uint8_t *tmp = s->edge_emu_buffer+16;
+ s->h264chroma.put_h264_chroma_pixels_tab[0](tmp, src, stride, 9, h_weight, 0);
+ s->h264chroma.put_h264_chroma_pixels_tab[0](dst, tmp, stride, 8, 0, v_weight);
+}
+
+static void vp6_filter(VP56Context *s, uint8_t *dst, uint8_t *src,
+ int offset1, int offset2, int stride,
+ VP56mv mv, int mask, int select, int luma)
+{
+ int filter4 = 0;
+ int x8 = mv.x & mask;
+ int y8 = mv.y & mask;
+
+ if (luma) {
+ x8 *= 2;
+ y8 *= 2;
+ filter4 = s->filter_mode;
+ if (filter4 == 2) {
+ if (s->max_vector_length &&
+ (FFABS(mv.x) > s->max_vector_length ||
+ FFABS(mv.y) > s->max_vector_length)) {
+ filter4 = 0;
+ } else if (s->sample_variance_threshold
+ && (vp6_block_variance(src+offset1, stride)
+ < s->sample_variance_threshold)) {
+ filter4 = 0;
+ }
+ }
+ }
+
+ if ((y8 && (offset2-offset1)*s->flip<0) || (!y8 && offset1 > offset2)) {
+ offset1 = offset2;
+ }
+
+ if (filter4) {
+ if (!y8) { /* left or right combine */
+ vp6_filter_hv4(dst, src+offset1, stride, 1,
+ vp6_block_copy_filter[select][x8]);
+ } else if (!x8) { /* above or below combine */
+ vp6_filter_hv4(dst, src+offset1, stride, stride,
+ vp6_block_copy_filter[select][y8]);
+ } else {
+ s->vp56dsp.vp6_filter_diag4(dst, src+offset1+((mv.x^mv.y)>>31), stride,
+ vp6_block_copy_filter[select][x8],
+ vp6_block_copy_filter[select][y8]);
+ }
+ } else {
+ if (!x8 || !y8) {
+ s->h264chroma.put_h264_chroma_pixels_tab[0](dst, src + offset1, stride, 8, x8, y8);
+ } else {
+ vp6_filter_diag2(s, dst, src+offset1 + ((mv.x^mv.y)>>31), stride, x8, y8);
+ }
+ }
+}
+
+static av_cold void vp6_decode_init_context(VP56Context *s);
+
+static av_cold int vp6_decode_init(AVCodecContext *avctx)
+{
+ VP56Context *s = avctx->priv_data;
+ int ret;
+
+ if ((ret = ff_vp56_init(avctx, avctx->codec->id == AV_CODEC_ID_VP6,
+ avctx->codec->id == AV_CODEC_ID_VP6A)) < 0)
+ return ret;
+
+ vp6_decode_init_context(s);
+
+ if (s->has_alpha) {
+ s->alpha_context = av_mallocz(sizeof(VP56Context));
+ ff_vp56_init_context(avctx, s->alpha_context,
+ s->flip == -1, s->has_alpha);
+ vp6_decode_init_context(s->alpha_context);
+ }
+
+ return 0;
+}
+
+static av_cold void vp6_decode_init_context(VP56Context *s)
+{
+ s->deblock_filtering = 0;
+ s->vp56_coord_div = vp6_coord_div;
+ s->parse_vector_adjustment = vp6_parse_vector_adjustment;
+ s->filter = vp6_filter;
+ s->default_models_init = vp6_default_models_init;
+ s->parse_vector_models = vp6_parse_vector_models;
+ s->parse_coeff_models = vp6_parse_coeff_models;
+ s->parse_header = vp6_parse_header;
+}
+
+static av_cold void vp6_decode_free_context(VP56Context *s);
+
+static av_cold int vp6_decode_free(AVCodecContext *avctx)
+{
+ VP56Context *s = avctx->priv_data;
+
+ ff_vp56_free(avctx);
+ vp6_decode_free_context(s);
+
+ if (s->alpha_context) {
+ ff_vp56_free_context(s->alpha_context);
+ vp6_decode_free_context(s->alpha_context);
+ av_freep(&s->alpha_context);
+ }
+
+ return 0;
+}
+
+static av_cold void vp6_decode_free_context(VP56Context *s)
+{
+ int pt, ct, cg;
+
+ for (pt=0; pt<2; pt++) {
+ ff_free_vlc(&s->dccv_vlc[pt]);
+ ff_free_vlc(&s->runv_vlc[pt]);
+ for (ct=0; ct<3; ct++)
+ for (cg=0; cg<6; cg++)
+ ff_free_vlc(&s->ract_vlc[pt][ct][cg]);
+ }
+}
+
+AVCodec ff_vp6_decoder = {
+ .name = "vp6",
+ .long_name = NULL_IF_CONFIG_SMALL("On2 VP6"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_VP6,
+ .priv_data_size = sizeof(VP56Context),
+ .init = vp6_decode_init,
+ .close = vp6_decode_free,
+ .decode = ff_vp56_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
+
+/* flash version, not flipped upside-down */
+AVCodec ff_vp6f_decoder = {
+ .name = "vp6f",
+ .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version)"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_VP6F,
+ .priv_data_size = sizeof(VP56Context),
+ .init = vp6_decode_init,
+ .close = vp6_decode_free,
+ .decode = ff_vp56_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
+
+/* flash version, not flipped upside-down, with alpha channel */
+AVCodec ff_vp6a_decoder = {
+ .name = "vp6a",
+ .long_name = NULL_IF_CONFIG_SMALL("On2 VP6 (Flash version, with alpha channel)"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_VP6A,
+ .priv_data_size = sizeof(VP56Context),
+ .init = vp6_decode_init,
+ .close = vp6_decode_free,
+ .decode = ff_vp56_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_SLICE_THREADS,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/vp6data.h b/ffmpeg-2-8-12/libavcodec/vp6data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp6data.h
rename to ffmpeg-2-8-12/libavcodec/vp6data.h
diff --git a/ffmpeg-2-8-11/libavcodec/vp6dsp.c b/ffmpeg-2-8-12/libavcodec/vp6dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp6dsp.c
rename to ffmpeg-2-8-12/libavcodec/vp6dsp.c
diff --git a/ffmpeg-2-8-12/libavcodec/vp8.c b/ffmpeg-2-8-12/libavcodec/vp8.c
new file mode 100644
index 0000000..da28032
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/vp8.c
@@ -0,0 +1,2874 @@
+/*
+ * VP7/VP8 compatible video decoder
+ *
+ * Copyright (C) 2010 David Conrad
+ * Copyright (C) 2010 Ronald S. Bultje
+ * Copyright (C) 2010 Fiona Glaser
+ * Copyright (C) 2012 Daniel Kang
+ * Copyright (C) 2014 Peter Ross
+ *
+ * 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 "avcodec.h"
+#include "internal.h"
+#include "rectangle.h"
+#include "thread.h"
+#include "vp8.h"
+#include "vp8data.h"
+
+#if ARCH_ARM
+# include "arm/vp8.h"
+#endif
+
+#if CONFIG_VP7_DECODER && CONFIG_VP8_DECODER
+#define VPX(vp7, f) (vp7 ? vp7_ ## f : vp8_ ## f)
+#elif CONFIG_VP7_DECODER
+#define VPX(vp7, f) vp7_ ## f
+#else // CONFIG_VP8_DECODER
+#define VPX(vp7, f) vp8_ ## f
+#endif
+
+static void free_buffers(VP8Context *s)
+{
+ int i;
+ if (s->thread_data)
+ for (i = 0; i < MAX_THREADS; i++) {
+#if HAVE_THREADS
+ pthread_cond_destroy(&s->thread_data[i].cond);
+ pthread_mutex_destroy(&s->thread_data[i].lock);
+#endif
+ av_freep(&s->thread_data[i].filter_strength);
+ }
+ av_freep(&s->thread_data);
+ av_freep(&s->macroblocks_base);
+ av_freep(&s->intra4x4_pred_mode_top);
+ av_freep(&s->top_nnz);
+ av_freep(&s->top_border);
+
+ s->macroblocks = NULL;
+}
+
+static int vp8_alloc_frame(VP8Context *s, VP8Frame *f, int ref)
+{
+ int ret;
+ if ((ret = ff_thread_get_buffer(s->avctx, &f->tf,
+ ref ? AV_GET_BUFFER_FLAG_REF : 0)) < 0)
+ return ret;
+ if (!(f->seg_map = av_buffer_allocz(s->mb_width * s->mb_height))) {
+ ff_thread_release_buffer(s->avctx, &f->tf);
+ return AVERROR(ENOMEM);
+ }
+ return 0;
+}
+
+static void vp8_release_frame(VP8Context *s, VP8Frame *f)
+{
+ av_buffer_unref(&f->seg_map);
+ ff_thread_release_buffer(s->avctx, &f->tf);
+}
+
+#if CONFIG_VP8_DECODER
+static int vp8_ref_frame(VP8Context *s, VP8Frame *dst, VP8Frame *src)
+{
+ int ret;
+
+ vp8_release_frame(s, dst);
+
+ if ((ret = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0)
+ return ret;
+ if (src->seg_map &&
+ !(dst->seg_map = av_buffer_ref(src->seg_map))) {
+ vp8_release_frame(s, dst);
+ return AVERROR(ENOMEM);
+ }
+
+ return 0;
+}
+#endif /* CONFIG_VP8_DECODER */
+
+static void vp8_decode_flush_impl(AVCodecContext *avctx, int free_mem)
+{
+ VP8Context *s = avctx->priv_data;
+ int i;
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++)
+ vp8_release_frame(s, &s->frames[i]);
+ memset(s->framep, 0, sizeof(s->framep));
+
+ if (free_mem)
+ free_buffers(s);
+}
+
+static void vp8_decode_flush(AVCodecContext *avctx)
+{
+ vp8_decode_flush_impl(avctx, 0);
+}
+
+static VP8Frame *vp8_find_free_buffer(VP8Context *s)
+{
+ VP8Frame *frame = NULL;
+ int i;
+
+ // find a free buffer
+ for (i = 0; i < 5; i++)
+ if (&s->frames[i] != s->framep[VP56_FRAME_CURRENT] &&
+ &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] &&
+ &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] &&
+ &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2]) {
+ frame = &s->frames[i];
+ break;
+ }
+ if (i == 5) {
+ av_log(s->avctx, AV_LOG_FATAL, "Ran out of free frames!\n");
+ abort();
+ }
+ if (frame->tf.f->data[0])
+ vp8_release_frame(s, frame);
+
+ return frame;
+}
+
+static av_always_inline
+int update_dimensions(VP8Context *s, int width, int height, int is_vp7)
+{
+ AVCodecContext *avctx = s->avctx;
+ int i, ret;
+
+ if (width != s->avctx->width || ((width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) && s->macroblocks_base ||
+ height != s->avctx->height) {
+ vp8_decode_flush_impl(s->avctx, 1);
+
+ ret = ff_set_dimensions(s->avctx, width, height);
+ if (ret < 0)
+ return ret;
+ }
+
+ s->mb_width = (s->avctx->coded_width + 15) / 16;
+ s->mb_height = (s->avctx->coded_height + 15) / 16;
+
+ s->mb_layout = is_vp7 || avctx->active_thread_type == FF_THREAD_SLICE &&
+ avctx->thread_count > 1;
+ if (!s->mb_layout) { // Frame threading and one thread
+ s->macroblocks_base = av_mallocz((s->mb_width + s->mb_height * 2 + 1) *
+ sizeof(*s->macroblocks));
+ s->intra4x4_pred_mode_top = av_mallocz(s->mb_width * 4);
+ } else // Sliced threading
+ s->macroblocks_base = av_mallocz((s->mb_width + 2) * (s->mb_height + 2) *
+ sizeof(*s->macroblocks));
+ s->top_nnz = av_mallocz(s->mb_width * sizeof(*s->top_nnz));
+ s->top_border = av_mallocz((s->mb_width + 1) * sizeof(*s->top_border));
+ s->thread_data = av_mallocz(MAX_THREADS * sizeof(VP8ThreadData));
+
+ if (!s->macroblocks_base || !s->top_nnz || !s->top_border ||
+ !s->thread_data || (!s->intra4x4_pred_mode_top && !s->mb_layout)) {
+ free_buffers(s);
+ return AVERROR(ENOMEM);
+ }
+
+ for (i = 0; i < MAX_THREADS; i++) {
+ s->thread_data[i].filter_strength =
+ av_mallocz(s->mb_width * sizeof(*s->thread_data[0].filter_strength));
+ if (!s->thread_data[i].filter_strength) {
+ free_buffers(s);
+ return AVERROR(ENOMEM);
+ }
+#if HAVE_THREADS
+ pthread_mutex_init(&s->thread_data[i].lock, NULL);
+ pthread_cond_init(&s->thread_data[i].cond, NULL);
+#endif
+ }
+
+ s->macroblocks = s->macroblocks_base + 1;
+
+ return 0;
+}
+
+static int vp7_update_dimensions(VP8Context *s, int width, int height)
+{
+ return update_dimensions(s, width, height, IS_VP7);
+}
+
+static int vp8_update_dimensions(VP8Context *s, int width, int height)
+{
+ return update_dimensions(s, width, height, IS_VP8);
+}
+
+
+static void parse_segment_info(VP8Context *s)
+{
+ VP56RangeCoder *c = &s->c;
+ int i;
+
+ s->segmentation.update_map = vp8_rac_get(c);
+
+ if (vp8_rac_get(c)) { // update segment feature data
+ s->segmentation.absolute_vals = vp8_rac_get(c);
+
+ for (i = 0; i < 4; i++)
+ s->segmentation.base_quant[i] = vp8_rac_get_sint(c, 7);
+
+ for (i = 0; i < 4; i++)
+ s->segmentation.filter_level[i] = vp8_rac_get_sint(c, 6);
+ }
+ if (s->segmentation.update_map)
+ for (i = 0; i < 3; i++)
+ s->prob->segmentid[i] = vp8_rac_get(c) ? vp8_rac_get_uint(c, 8) : 255;
+}
+
+static void update_lf_deltas(VP8Context *s)
+{
+ VP56RangeCoder *c = &s->c;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (vp8_rac_get(c)) {
+ s->lf_delta.ref[i] = vp8_rac_get_uint(c, 6);
+
+ if (vp8_rac_get(c))
+ s->lf_delta.ref[i] = -s->lf_delta.ref[i];
+ }
+ }
+
+ for (i = MODE_I4x4; i <= VP8_MVMODE_SPLIT; i++) {
+ if (vp8_rac_get(c)) {
+ s->lf_delta.mode[i] = vp8_rac_get_uint(c, 6);
+
+ if (vp8_rac_get(c))
+ s->lf_delta.mode[i] = -s->lf_delta.mode[i];
+ }
+ }
+}
+
+static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size)
+{
+ const uint8_t *sizes = buf;
+ int i;
+ int ret;
+
+ s->num_coeff_partitions = 1 << vp8_rac_get_uint(&s->c, 2);
+
+ buf += 3 * (s->num_coeff_partitions - 1);
+ buf_size -= 3 * (s->num_coeff_partitions - 1);
+ if (buf_size < 0)
+ return -1;
+
+ for (i = 0; i < s->num_coeff_partitions - 1; i++) {
+ int size = AV_RL24(sizes + 3 * i);
+ if (buf_size - size < 0)
+ return -1;
+
+ ret = ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size);
+ if (ret < 0)
+ return ret;
+ buf += size;
+ buf_size -= size;
+ }
+ return ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size);
+}
+
+static void vp7_get_quants(VP8Context *s)
+{
+ VP56RangeCoder *c = &s->c;
+
+ int yac_qi = vp8_rac_get_uint(c, 7);
+ int ydc_qi = vp8_rac_get(c) ? vp8_rac_get_uint(c, 7) : yac_qi;
+ int y2dc_qi = vp8_rac_get(c) ? vp8_rac_get_uint(c, 7) : yac_qi;
+ int y2ac_qi = vp8_rac_get(c) ? vp8_rac_get_uint(c, 7) : yac_qi;
+ int uvdc_qi = vp8_rac_get(c) ? vp8_rac_get_uint(c, 7) : yac_qi;
+ int uvac_qi = vp8_rac_get(c) ? vp8_rac_get_uint(c, 7) : yac_qi;
+
+ s->qmat[0].luma_qmul[0] = vp7_ydc_qlookup[ydc_qi];
+ s->qmat[0].luma_qmul[1] = vp7_yac_qlookup[yac_qi];
+ s->qmat[0].luma_dc_qmul[0] = vp7_y2dc_qlookup[y2dc_qi];
+ s->qmat[0].luma_dc_qmul[1] = vp7_y2ac_qlookup[y2ac_qi];
+ s->qmat[0].chroma_qmul[0] = FFMIN(vp7_ydc_qlookup[uvdc_qi], 132);
+ s->qmat[0].chroma_qmul[1] = vp7_yac_qlookup[uvac_qi];
+}
+
+static void vp8_get_quants(VP8Context *s)
+{
+ VP56RangeCoder *c = &s->c;
+ int i, base_qi;
+
+ int yac_qi = vp8_rac_get_uint(c, 7);
+ int ydc_delta = vp8_rac_get_sint(c, 4);
+ int y2dc_delta = vp8_rac_get_sint(c, 4);
+ int y2ac_delta = vp8_rac_get_sint(c, 4);
+ int uvdc_delta = vp8_rac_get_sint(c, 4);
+ int uvac_delta = vp8_rac_get_sint(c, 4);
+
+ for (i = 0; i < 4; i++) {
+ if (s->segmentation.enabled) {
+ base_qi = s->segmentation.base_quant[i];
+ if (!s->segmentation.absolute_vals)
+ base_qi += yac_qi;
+ } else
+ base_qi = yac_qi;
+
+ s->qmat[i].luma_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + ydc_delta, 7)];
+ s->qmat[i].luma_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi, 7)];
+ s->qmat[i].luma_dc_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + y2dc_delta, 7)] * 2;
+ /* 101581>>16 is equivalent to 155/100 */
+ s->qmat[i].luma_dc_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi + y2ac_delta, 7)] * 101581 >> 16;
+ s->qmat[i].chroma_qmul[0] = vp8_dc_qlookup[av_clip_uintp2(base_qi + uvdc_delta, 7)];
+ s->qmat[i].chroma_qmul[1] = vp8_ac_qlookup[av_clip_uintp2(base_qi + uvac_delta, 7)];
+
+ s->qmat[i].luma_dc_qmul[1] = FFMAX(s->qmat[i].luma_dc_qmul[1], 8);
+ s->qmat[i].chroma_qmul[0] = FFMIN(s->qmat[i].chroma_qmul[0], 132);
+ }
+}
+
+/**
+ * Determine which buffers golden and altref should be updated with after this frame.
+ * The spec isn't clear here, so I'm going by my understanding of what libvpx does
+ *
+ * Intra frames update all 3 references
+ * Inter frames update VP56_FRAME_PREVIOUS if the update_last flag is set
+ * If the update (golden|altref) flag is set, it's updated with the current frame
+ * if update_last is set, and VP56_FRAME_PREVIOUS otherwise.
+ * If the flag is not set, the number read means:
+ * 0: no update
+ * 1: VP56_FRAME_PREVIOUS
+ * 2: update golden with altref, or update altref with golden
+ */
+static VP56Frame ref_to_update(VP8Context *s, int update, VP56Frame ref)
+{
+ VP56RangeCoder *c = &s->c;
+
+ if (update)
+ return VP56_FRAME_CURRENT;
+
+ switch (vp8_rac_get_uint(c, 2)) {
+ case 1:
+ return VP56_FRAME_PREVIOUS;
+ case 2:
+ return (ref == VP56_FRAME_GOLDEN) ? VP56_FRAME_GOLDEN2 : VP56_FRAME_GOLDEN;
+ }
+ return VP56_FRAME_NONE;
+}
+
+static void vp78_reset_probability_tables(VP8Context *s)
+{
+ int i, j;
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 16; j++)
+ memcpy(s->prob->token[i][j], vp8_token_default_probs[i][vp8_coeff_band[j]],
+ sizeof(s->prob->token[i][j]));
+}
+
+static void vp78_update_probability_tables(VP8Context *s)
+{
+ VP56RangeCoder *c = &s->c;
+ int i, j, k, l, m;
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 8; j++)
+ for (k = 0; k < 3; k++)
+ for (l = 0; l < NUM_DCT_TOKENS-1; l++)
+ if (vp56_rac_get_prob_branchy(c, vp8_token_update_probs[i][j][k][l])) {
+ int prob = vp8_rac_get_uint(c, 8);
+ for (m = 0; vp8_coeff_band_indexes[j][m] >= 0; m++)
+ s->prob->token[i][vp8_coeff_band_indexes[j][m]][k][l] = prob;
+ }
+}
+
+#define VP7_MVC_SIZE 17
+#define VP8_MVC_SIZE 19
+
+static void vp78_update_pred16x16_pred8x8_mvc_probabilities(VP8Context *s,
+ int mvc_size)
+{
+ VP56RangeCoder *c = &s->c;
+ int i, j;
+
+ if (vp8_rac_get(c))
+ for (i = 0; i < 4; i++)
+ s->prob->pred16x16[i] = vp8_rac_get_uint(c, 8);
+ if (vp8_rac_get(c))
+ for (i = 0; i < 3; i++)
+ s->prob->pred8x8c[i] = vp8_rac_get_uint(c, 8);
+
+ // 17.2 MV probability update
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < mvc_size; j++)
+ if (vp56_rac_get_prob_branchy(c, vp8_mv_update_prob[i][j]))
+ s->prob->mvc[i][j] = vp8_rac_get_nn(c);
+}
+
+static void update_refs(VP8Context *s)
+{
+ VP56RangeCoder *c = &s->c;
+
+ int update_golden = vp8_rac_get(c);
+ int update_altref = vp8_rac_get(c);
+
+ s->update_golden = ref_to_update(s, update_golden, VP56_FRAME_GOLDEN);
+ s->update_altref = ref_to_update(s, update_altref, VP56_FRAME_GOLDEN2);
+}
+
+static void copy_chroma(AVFrame *dst, AVFrame *src, int width, int height)
+{
+ int i, j;
+
+ for (j = 1; j < 3; j++) {
+ for (i = 0; i < height / 2; i++)
+ memcpy(dst->data[j] + i * dst->linesize[j],
+ src->data[j] + i * src->linesize[j], width / 2);
+ }
+}
+
+static void fade(uint8_t *dst, int dst_linesize,
+ const uint8_t *src, int src_linesize,
+ int width, int height,
+ int alpha, int beta)
+{
+ int i, j;
+ for (j = 0; j < height; j++) {
+ for (i = 0; i < width; i++) {
+ uint8_t y = src[j * src_linesize + i];
+ dst[j * dst_linesize + i] = av_clip_uint8(y + ((y * beta) >> 8) + alpha);
+ }
+ }
+}
+
+static int vp7_fade_frame(VP8Context *s, VP56RangeCoder *c)
+{
+ int alpha = (int8_t) vp8_rac_get_uint(c, 8);
+ int beta = (int8_t) vp8_rac_get_uint(c, 8);
+ int ret;
+
+ if (!s->keyframe && (alpha || beta)) {
+ int width = s->mb_width * 16;
+ int height = s->mb_height * 16;
+ AVFrame *src, *dst;
+
+ if (!s->framep[VP56_FRAME_PREVIOUS] ||
+ !s->framep[VP56_FRAME_GOLDEN]) {
+ av_log(s->avctx, AV_LOG_WARNING, "Discarding interframe without a prior keyframe!\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ dst =
+ src = s->framep[VP56_FRAME_PREVIOUS]->tf.f;
+
+ /* preserve the golden frame, write a new previous frame */
+ if (s->framep[VP56_FRAME_GOLDEN] == s->framep[VP56_FRAME_PREVIOUS]) {
+ s->framep[VP56_FRAME_PREVIOUS] = vp8_find_free_buffer(s);
+ if ((ret = vp8_alloc_frame(s, s->framep[VP56_FRAME_PREVIOUS], 1)) < 0)
+ return ret;
+
+ dst = s->framep[VP56_FRAME_PREVIOUS]->tf.f;
+
+ copy_chroma(dst, src, width, height);
+ }
+
+ fade(dst->data[0], dst->linesize[0],
+ src->data[0], src->linesize[0],
+ width, height, alpha, beta);
+ }
+
+ return 0;
+}
+
+static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
+{
+ VP56RangeCoder *c = &s->c;
+ int part1_size, hscale, vscale, i, j, ret;
+ int width = s->avctx->width;
+ int height = s->avctx->height;
+
+ if (buf_size < 4) {
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->profile = (buf[0] >> 1) & 7;
+ if (s->profile > 1) {
+ avpriv_request_sample(s->avctx, "Unknown profile %d", s->profile);
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->keyframe = !(buf[0] & 1);
+ s->invisible = 0;
+ part1_size = AV_RL24(buf) >> 4;
+
+ if (buf_size < 4 - s->profile + part1_size) {
+ av_log(s->avctx, AV_LOG_ERROR, "Buffer size %d is too small, needed : %d\n", buf_size, 4 - s->profile + part1_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ buf += 4 - s->profile;
+ buf_size -= 4 - s->profile;
+
+ memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab, sizeof(s->put_pixels_tab));
+
+ ret = ff_vp56_init_range_decoder(c, buf, part1_size);
+ if (ret < 0)
+ return ret;
+ buf += part1_size;
+ buf_size -= part1_size;
+
+ /* A. Dimension information (keyframes only) */
+ if (s->keyframe) {
+ width = vp8_rac_get_uint(c, 12);
+ height = vp8_rac_get_uint(c, 12);
+ hscale = vp8_rac_get_uint(c, 2);
+ vscale = vp8_rac_get_uint(c, 2);
+ if (hscale || vscale)
+ avpriv_request_sample(s->avctx, "Upscaling");
+
+ s->update_golden = s->update_altref = VP56_FRAME_CURRENT;
+ vp78_reset_probability_tables(s);
+ memcpy(s->prob->pred16x16, vp8_pred16x16_prob_inter,
+ sizeof(s->prob->pred16x16));
+ memcpy(s->prob->pred8x8c, vp8_pred8x8c_prob_inter,
+ sizeof(s->prob->pred8x8c));
+ for (i = 0; i < 2; i++)
+ memcpy(s->prob->mvc[i], vp7_mv_default_prob[i],
+ sizeof(vp7_mv_default_prob[i]));
+ memset(&s->segmentation, 0, sizeof(s->segmentation));
+ memset(&s->lf_delta, 0, sizeof(s->lf_delta));
+ memcpy(s->prob[0].scan, zigzag_scan, sizeof(s->prob[0].scan));
+ }
+
+ if (s->keyframe || s->profile > 0)
+ memset(s->inter_dc_pred, 0 , sizeof(s->inter_dc_pred));
+
+ /* B. Decoding information for all four macroblock-level features */
+ for (i = 0; i < 4; i++) {
+ s->feature_enabled[i] = vp8_rac_get(c);
+ if (s->feature_enabled[i]) {
+ s->feature_present_prob[i] = vp8_rac_get_uint(c, 8);
+
+ for (j = 0; j < 3; j++)
+ s->feature_index_prob[i][j] =
+ vp8_rac_get(c) ? vp8_rac_get_uint(c, 8) : 255;
+
+ if (vp7_feature_value_size[s->profile][i])
+ for (j = 0; j < 4; j++)
+ s->feature_value[i][j] =
+ vp8_rac_get(c) ? vp8_rac_get_uint(c, vp7_feature_value_size[s->profile][i]) : 0;
+ }
+ }
+
+ s->segmentation.enabled = 0;
+ s->segmentation.update_map = 0;
+ s->lf_delta.enabled = 0;
+
+ s->num_coeff_partitions = 1;
+ ret = ff_vp56_init_range_decoder(&s->coeff_partition[0], buf, buf_size);
+ if (ret < 0)
+ return ret;
+
+ if (!s->macroblocks_base || /* first frame */
+ width != s->avctx->width || height != s->avctx->height ||
+ (width + 15) / 16 != s->mb_width || (height + 15) / 16 != s->mb_height) {
+ if ((ret = vp7_update_dimensions(s, width, height)) < 0)
+ return ret;
+ }
+
+ /* C. Dequantization indices */
+ vp7_get_quants(s);
+
+ /* D. Golden frame update flag (a Flag) for interframes only */
+ if (!s->keyframe) {
+ s->update_golden = vp8_rac_get(c) ? VP56_FRAME_CURRENT : VP56_FRAME_NONE;
+ s->sign_bias[VP56_FRAME_GOLDEN] = 0;
+ }
+
+ s->update_last = 1;
+ s->update_probabilities = 1;
+ s->fade_present = 1;
+
+ if (s->profile > 0) {
+ s->update_probabilities = vp8_rac_get(c);
+ if (!s->update_probabilities)
+ s->prob[1] = s->prob[0];
+
+ if (!s->keyframe)
+ s->fade_present = vp8_rac_get(c);
+ }
+
+ /* E. Fading information for previous frame */
+ if (s->fade_present && vp8_rac_get(c)) {
+ if ((ret = vp7_fade_frame(s ,c)) < 0)
+ return ret;
+ }
+
+ /* F. Loop filter type */
+ if (!s->profile)
+ s->filter.simple = vp8_rac_get(c);
+
+ /* G. DCT coefficient ordering specification */
+ if (vp8_rac_get(c))
+ for (i = 1; i < 16; i++)
+ s->prob[0].scan[i] = zigzag_scan[vp8_rac_get_uint(c, 4)];
+
+ /* H. Loop filter levels */
+ if (s->profile > 0)
+ s->filter.simple = vp8_rac_get(c);
+ s->filter.level = vp8_rac_get_uint(c, 6);
+ s->filter.sharpness = vp8_rac_get_uint(c, 3);
+
+ /* I. DCT coefficient probability update; 13.3 Token Probability Updates */
+ vp78_update_probability_tables(s);
+
+ s->mbskip_enabled = 0;
+
+ /* J. The remaining frame header data occurs ONLY FOR INTERFRAMES */
+ if (!s->keyframe) {
+ s->prob->intra = vp8_rac_get_uint(c, 8);
+ s->prob->last = vp8_rac_get_uint(c, 8);
+ vp78_update_pred16x16_pred8x8_mvc_probabilities(s, VP7_MVC_SIZE);
+ }
+
+ return 0;
+}
+
+static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size)
+{
+ VP56RangeCoder *c = &s->c;
+ int header_size, hscale, vscale, ret;
+ int width = s->avctx->width;
+ int height = s->avctx->height;
+
+ if (buf_size < 3) {
+ av_log(s->avctx, AV_LOG_ERROR, "Insufficent data (%d) for header\n", buf_size);
+ return AVERROR_INVALIDDATA;
+ }
+
+ s->keyframe = !(buf[0] & 1);
+ s->profile = (buf[0]>>1) & 7;
+ s->invisible = !(buf[0] & 0x10);
+ header_size = AV_RL24(buf) >> 5;
+ buf += 3;
+ buf_size -= 3;
+
+ if (s->profile > 3)
+ av_log(s->avctx, AV_LOG_WARNING, "Unknown profile %d\n", s->profile);
+
+ if (!s->profile)
+ memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab,
+ sizeof(s->put_pixels_tab));
+ else // profile 1-3 use bilinear, 4+ aren't defined so whatever
+ memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_bilinear_pixels_tab,
+ sizeof(s->put_pixels_tab));
+
+ if (header_size > buf_size - 7 * s->keyframe) {
+ av_log(s->avctx, AV_LOG_ERROR, "Header size larger than data provided\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->keyframe) {
+ if (AV_RL24(buf) != 0x2a019d) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "Invalid start code 0x%x\n", AV_RL24(buf));
+ return AVERROR_INVALIDDATA;
+ }
+ width = AV_RL16(buf + 3) & 0x3fff;
+ height = AV_RL16(buf + 5) & 0x3fff;
+ hscale = buf[4] >> 6;
+ vscale = buf[6] >> 6;
+ buf += 7;
+ buf_size -= 7;
+
+ if (hscale || vscale)
+ avpriv_request_sample(s->avctx, "Upscaling");
+
+ s->update_golden = s->update_altref = VP56_FRAME_CURRENT;
+ vp78_reset_probability_tables(s);
+ memcpy(s->prob->pred16x16, vp8_pred16x16_prob_inter,
+ sizeof(s->prob->pred16x16));
+ memcpy(s->prob->pred8x8c, vp8_pred8x8c_prob_inter,
+ sizeof(s->prob->pred8x8c));
+ memcpy(s->prob->mvc, vp8_mv_default_prob,
+ sizeof(s->prob->mvc));
+ memset(&s->segmentation, 0, sizeof(s->segmentation));
+ memset(&s->lf_delta, 0, sizeof(s->lf_delta));
+ }
+
+ ret = ff_vp56_init_range_decoder(c, buf, header_size);
+ if (ret < 0)
+ return ret;
+ buf += header_size;
+ buf_size -= header_size;
+
+ if (s->keyframe) {
+ s->colorspace = vp8_rac_get(c);
+ if (s->colorspace)
+ av_log(s->avctx, AV_LOG_WARNING, "Unspecified colorspace\n");
+ s->fullrange = vp8_rac_get(c);
+ }
+
+ if ((s->segmentation.enabled = vp8_rac_get(c)))
+ parse_segment_info(s);
+ else
+ s->segmentation.update_map = 0; // FIXME: move this to some init function?
+
+ s->filter.simple = vp8_rac_get(c);
+ s->filter.level = vp8_rac_get_uint(c, 6);
+ s->filter.sharpness = vp8_rac_get_uint(c, 3);
+
+ if ((s->lf_delta.enabled = vp8_rac_get(c)))
+ if (vp8_rac_get(c))
+ update_lf_deltas(s);
+
+ if (setup_partitions(s, buf, buf_size)) {
+ av_log(s->avctx, AV_LOG_ERROR, "Invalid partitions\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!s->macroblocks_base || /* first frame */
+ width != s->avctx->width || height != s->avctx->height ||
+ (width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height)
+ if ((ret = vp8_update_dimensions(s, width, height)) < 0)
+ return ret;
+
+ vp8_get_quants(s);
+
+ if (!s->keyframe) {
+ update_refs(s);
+ s->sign_bias[VP56_FRAME_GOLDEN] = vp8_rac_get(c);
+ s->sign_bias[VP56_FRAME_GOLDEN2 /* altref */] = vp8_rac_get(c);
+ }
+
+ // if we aren't saving this frame's probabilities for future frames,
+ // make a copy of the current probabilities
+ if (!(s->update_probabilities = vp8_rac_get(c)))
+ s->prob[1] = s->prob[0];
+
+ s->update_last = s->keyframe || vp8_rac_get(c);
+
+ vp78_update_probability_tables(s);
+
+ if ((s->mbskip_enabled = vp8_rac_get(c)))
+ s->prob->mbskip = vp8_rac_get_uint(c, 8);
+
+ if (!s->keyframe) {
+ s->prob->intra = vp8_rac_get_uint(c, 8);
+ s->prob->last = vp8_rac_get_uint(c, 8);
+ s->prob->golden = vp8_rac_get_uint(c, 8);
+ vp78_update_pred16x16_pred8x8_mvc_probabilities(s, VP8_MVC_SIZE);
+ }
+
+ return 0;
+}
+
+static av_always_inline
+void clamp_mv(VP8Context *s, VP56mv *dst, const VP56mv *src)
+{
+ dst->x = av_clip(src->x, av_clip(s->mv_min.x, INT16_MIN, INT16_MAX),
+ av_clip(s->mv_max.x, INT16_MIN, INT16_MAX));
+ dst->y = av_clip(src->y, av_clip(s->mv_min.y, INT16_MIN, INT16_MAX),
+ av_clip(s->mv_max.y, INT16_MIN, INT16_MAX));
+}
+
+/**
+ * Motion vector coding, 17.1.
+ */
+static av_always_inline int read_mv_component(VP56RangeCoder *c, const uint8_t *p, int vp7)
+{
+ int bit, x = 0;
+
+ if (vp56_rac_get_prob_branchy(c, p[0])) {
+ int i;
+
+ for (i = 0; i < 3; i++)
+ x += vp56_rac_get_prob(c, p[9 + i]) << i;
+ for (i = (vp7 ? 7 : 9); i > 3; i--)
+ x += vp56_rac_get_prob(c, p[9 + i]) << i;
+ if (!(x & (vp7 ? 0xF0 : 0xFFF0)) || vp56_rac_get_prob(c, p[12]))
+ x += 8;
+ } else {
+ // small_mvtree
+ const uint8_t *ps = p + 2;
+ bit = vp56_rac_get_prob(c, *ps);
+ ps += 1 + 3 * bit;
+ x += 4 * bit;
+ bit = vp56_rac_get_prob(c, *ps);
+ ps += 1 + bit;
+ x += 2 * bit;
+ x += vp56_rac_get_prob(c, *ps);
+ }
+
+ return (x && vp56_rac_get_prob(c, p[1])) ? -x : x;
+}
+
+static int vp7_read_mv_component(VP56RangeCoder *c, const uint8_t *p)
+{
+ return read_mv_component(c, p, 1);
+}
+
+static int vp8_read_mv_component(VP56RangeCoder *c, const uint8_t *p)
+{
+ return read_mv_component(c, p, 0);
+}
+
+static av_always_inline
+const uint8_t *get_submv_prob(uint32_t left, uint32_t top, int is_vp7)
+{
+ if (is_vp7)
+ return vp7_submv_prob;
+
+ if (left == top)
+ return vp8_submv_prob[4 - !!left];
+ if (!top)
+ return vp8_submv_prob[2];
+ return vp8_submv_prob[1 - !!left];
+}
+
+/**
+ * Split motion vector prediction, 16.4.
+ * @returns the number of motion vectors parsed (2, 4 or 16)
+ */
+static av_always_inline
+int decode_splitmvs(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb,
+ int layout, int is_vp7)
+{
+ int part_idx;
+ int n, num;
+ VP8Macroblock *top_mb;
+ VP8Macroblock *left_mb = &mb[-1];
+ const uint8_t *mbsplits_left = vp8_mbsplits[left_mb->partitioning];
+ const uint8_t *mbsplits_top, *mbsplits_cur, *firstidx;
+ VP56mv *top_mv;
+ VP56mv *left_mv = left_mb->bmv;
+ VP56mv *cur_mv = mb->bmv;
+
+ if (!layout) // layout is inlined, s->mb_layout is not
+ top_mb = &mb[2];
+ else
+ top_mb = &mb[-s->mb_width - 1];
+ mbsplits_top = vp8_mbsplits[top_mb->partitioning];
+ top_mv = top_mb->bmv;
+
+ if (vp56_rac_get_prob_branchy(c, vp8_mbsplit_prob[0])) {
+ if (vp56_rac_get_prob_branchy(c, vp8_mbsplit_prob[1]))
+ part_idx = VP8_SPLITMVMODE_16x8 + vp56_rac_get_prob(c, vp8_mbsplit_prob[2]);
+ else
+ part_idx = VP8_SPLITMVMODE_8x8;
+ } else {
+ part_idx = VP8_SPLITMVMODE_4x4;
+ }
+
+ num = vp8_mbsplit_count[part_idx];
+ mbsplits_cur = vp8_mbsplits[part_idx],
+ firstidx = vp8_mbfirstidx[part_idx];
+ mb->partitioning = part_idx;
+
+ for (n = 0; n < num; n++) {
+ int k = firstidx[n];
+ uint32_t left, above;
+ const uint8_t *submv_prob;
+
+ if (!(k & 3))
+ left = AV_RN32A(&left_mv[mbsplits_left[k + 3]]);
+ else
+ left = AV_RN32A(&cur_mv[mbsplits_cur[k - 1]]);
+ if (k <= 3)
+ above = AV_RN32A(&top_mv[mbsplits_top[k + 12]]);
+ else
+ above = AV_RN32A(&cur_mv[mbsplits_cur[k - 4]]);
+
+ submv_prob = get_submv_prob(left, above, is_vp7);
+
+ if (vp56_rac_get_prob_branchy(c, submv_prob[0])) {
+ if (vp56_rac_get_prob_branchy(c, submv_prob[1])) {
+ if (vp56_rac_get_prob_branchy(c, submv_prob[2])) {
+ mb->bmv[n].y = mb->mv.y +
+ read_mv_component(c, s->prob->mvc[0], is_vp7);
+ mb->bmv[n].x = mb->mv.x +
+ read_mv_component(c, s->prob->mvc[1], is_vp7);
+ } else {
+ AV_ZERO32(&mb->bmv[n]);
+ }
+ } else {
+ AV_WN32A(&mb->bmv[n], above);
+ }
+ } else {
+ AV_WN32A(&mb->bmv[n], left);
+ }
+ }
+
+ return num;
+}
+
+/**
+ * The vp7 reference decoder uses a padding macroblock column (added to right
+ * edge of the frame) to guard against illegal macroblock offsets. The
+ * algorithm has bugs that permit offsets to straddle the padding column.
+ * This function replicates those bugs.
+ *
+ * @param[out] edge_x macroblock x address
+ * @param[out] edge_y macroblock y address
+ *
+ * @return macroblock offset legal (boolean)
+ */
+static int vp7_calculate_mb_offset(int mb_x, int mb_y, int mb_width,
+ int xoffset, int yoffset, int boundary,
+ int *edge_x, int *edge_y)
+{
+ int vwidth = mb_width + 1;
+ int new = (mb_y + yoffset) * vwidth + mb_x + xoffset;
+ if (new < boundary || new % vwidth == vwidth - 1)
+ return 0;
+ *edge_y = new / vwidth;
+ *edge_x = new % vwidth;
+ return 1;
+}
+
+static const VP56mv *get_bmv_ptr(const VP8Macroblock *mb, int subblock)
+{
+ return &mb->bmv[mb->mode == VP8_MVMODE_SPLIT ? vp8_mbsplits[mb->partitioning][subblock] : 0];
+}
+
+static av_always_inline
+void vp7_decode_mvs(VP8Context *s, VP8Macroblock *mb,
+ int mb_x, int mb_y, int layout)
+{
+ VP8Macroblock *mb_edge[12];
+ enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR };
+ enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
+ int idx = CNT_ZERO;
+ VP56mv near_mv[3];
+ uint8_t cnt[3] = { 0 };
+ VP56RangeCoder *c = &s->c;
+ int i;
+
+ AV_ZERO32(&near_mv[0]);
+ AV_ZERO32(&near_mv[1]);
+ AV_ZERO32(&near_mv[2]);
+
+ for (i = 0; i < VP7_MV_PRED_COUNT; i++) {
+ const VP7MVPred * pred = &vp7_mv_pred[i];
+ int edge_x, edge_y;
+
+ if (vp7_calculate_mb_offset(mb_x, mb_y, s->mb_width, pred->xoffset,
+ pred->yoffset, !s->profile, &edge_x, &edge_y)) {
+ VP8Macroblock *edge = mb_edge[i] = (s->mb_layout == 1)
+ ? s->macroblocks_base + 1 + edge_x +
+ (s->mb_width + 1) * (edge_y + 1)
+ : s->macroblocks + edge_x +
+ (s->mb_height - edge_y - 1) * 2;
+ uint32_t mv = AV_RN32A(get_bmv_ptr(edge, vp7_mv_pred[i].subblock));
+ if (mv) {
+ if (AV_RN32A(&near_mv[CNT_NEAREST])) {
+ if (mv == AV_RN32A(&near_mv[CNT_NEAREST])) {
+ idx = CNT_NEAREST;
+ } else if (AV_RN32A(&near_mv[CNT_NEAR])) {
+ if (mv != AV_RN32A(&near_mv[CNT_NEAR]))
+ continue;
+ idx = CNT_NEAR;
+ } else {
+ AV_WN32A(&near_mv[CNT_NEAR], mv);
+ idx = CNT_NEAR;
+ }
+ } else {
+ AV_WN32A(&near_mv[CNT_NEAREST], mv);
+ idx = CNT_NEAREST;
+ }
+ } else {
+ idx = CNT_ZERO;
+ }
+ } else {
+ idx = CNT_ZERO;
+ }
+ cnt[idx] += vp7_mv_pred[i].score;
+ }
+
+ mb->partitioning = VP8_SPLITMVMODE_NONE;
+
+ if (vp56_rac_get_prob_branchy(c, vp7_mode_contexts[cnt[CNT_ZERO]][0])) {
+ mb->mode = VP8_MVMODE_MV;
+
+ if (vp56_rac_get_prob_branchy(c, vp7_mode_contexts[cnt[CNT_NEAREST]][1])) {
+
+ if (vp56_rac_get_prob_branchy(c, vp7_mode_contexts[cnt[CNT_NEAR]][2])) {
+
+ if (cnt[CNT_NEAREST] > cnt[CNT_NEAR])
+ AV_WN32A(&mb->mv, cnt[CNT_ZERO] > cnt[CNT_NEAREST] ? 0 : AV_RN32A(&near_mv[CNT_NEAREST]));
+ else
+ AV_WN32A(&mb->mv, cnt[CNT_ZERO] > cnt[CNT_NEAR] ? 0 : AV_RN32A(&near_mv[CNT_NEAR]));
+
+ if (vp56_rac_get_prob_branchy(c, vp7_mode_contexts[cnt[CNT_NEAR]][3])) {
+ mb->mode = VP8_MVMODE_SPLIT;
+ mb->mv = mb->bmv[decode_splitmvs(s, c, mb, layout, IS_VP7) - 1];
+ } else {
+ mb->mv.y += vp7_read_mv_component(c, s->prob->mvc[0]);
+ mb->mv.x += vp7_read_mv_component(c, s->prob->mvc[1]);
+ mb->bmv[0] = mb->mv;
+ }
+ } else {
+ mb->mv = near_mv[CNT_NEAR];
+ mb->bmv[0] = mb->mv;
+ }
+ } else {
+ mb->mv = near_mv[CNT_NEAREST];
+ mb->bmv[0] = mb->mv;
+ }
+ } else {
+ mb->mode = VP8_MVMODE_ZERO;
+ AV_ZERO32(&mb->mv);
+ mb->bmv[0] = mb->mv;
+ }
+}
+
+static av_always_inline
+void vp8_decode_mvs(VP8Context *s, VP8Macroblock *mb,
+ int mb_x, int mb_y, int layout)
+{
+ VP8Macroblock *mb_edge[3] = { 0 /* top */,
+ mb - 1 /* left */,
+ 0 /* top-left */ };
+ enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV };
+ enum { VP8_EDGE_TOP, VP8_EDGE_LEFT, VP8_EDGE_TOPLEFT };
+ int idx = CNT_ZERO;
+ int cur_sign_bias = s->sign_bias[mb->ref_frame];
+ int8_t *sign_bias = s->sign_bias;
+ VP56mv near_mv[4];
+ uint8_t cnt[4] = { 0 };
+ VP56RangeCoder *c = &s->c;
+
+ if (!layout) { // layout is inlined (s->mb_layout is not)
+ mb_edge[0] = mb + 2;
+ mb_edge[2] = mb + 1;
+ } else {
+ mb_edge[0] = mb - s->mb_width - 1;
+ mb_edge[2] = mb - s->mb_width - 2;
+ }
+
+ AV_ZERO32(&near_mv[0]);
+ AV_ZERO32(&near_mv[1]);
+ AV_ZERO32(&near_mv[2]);
+
+ /* Process MB on top, left and top-left */
+#define MV_EDGE_CHECK(n) \
+ { \
+ VP8Macroblock *edge = mb_edge[n]; \
+ int edge_ref = edge->ref_frame; \
+ if (edge_ref != VP56_FRAME_CURRENT) { \
+ uint32_t mv = AV_RN32A(&edge->mv); \
+ if (mv) { \
+ if (cur_sign_bias != sign_bias[edge_ref]) { \
+ /* SWAR negate of the values in mv. */ \
+ mv = ~mv; \
+ mv = ((mv & 0x7fff7fff) + \
+ 0x00010001) ^ (mv & 0x80008000); \
+ } \
+ if (!n || mv != AV_RN32A(&near_mv[idx])) \
+ AV_WN32A(&near_mv[++idx], mv); \
+ cnt[idx] += 1 + (n != 2); \
+ } else \
+ cnt[CNT_ZERO] += 1 + (n != 2); \
+ } \
+ }
+
+ MV_EDGE_CHECK(0)
+ MV_EDGE_CHECK(1)
+ MV_EDGE_CHECK(2)
+
+ mb->partitioning = VP8_SPLITMVMODE_NONE;
+ if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_ZERO]][0])) {
+ mb->mode = VP8_MVMODE_MV;
+
+ /* If we have three distinct MVs, merge first and last if they're the same */
+ if (cnt[CNT_SPLITMV] &&
+ AV_RN32A(&near_mv[1 + VP8_EDGE_TOP]) == AV_RN32A(&near_mv[1 + VP8_EDGE_TOPLEFT]))
+ cnt[CNT_NEAREST] += 1;
+
+ /* Swap near and nearest if necessary */
+ if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) {
+ FFSWAP(uint8_t, cnt[CNT_NEAREST], cnt[CNT_NEAR]);
+ FFSWAP( VP56mv, near_mv[CNT_NEAREST], near_mv[CNT_NEAR]);
+ }
+
+ if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAREST]][1])) {
+ if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAR]][2])) {
+ /* Choose the best mv out of 0,0 and the nearest mv */
+ clamp_mv(s, &mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]);
+ cnt[CNT_SPLITMV] = ((mb_edge[VP8_EDGE_LEFT]->mode == VP8_MVMODE_SPLIT) +
+ (mb_edge[VP8_EDGE_TOP]->mode == VP8_MVMODE_SPLIT)) * 2 +
+ (mb_edge[VP8_EDGE_TOPLEFT]->mode == VP8_MVMODE_SPLIT);
+
+ if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_SPLITMV]][3])) {
+ mb->mode = VP8_MVMODE_SPLIT;
+ mb->mv = mb->bmv[decode_splitmvs(s, c, mb, layout, IS_VP8) - 1];
+ } else {
+ mb->mv.y += vp8_read_mv_component(c, s->prob->mvc[0]);
+ mb->mv.x += vp8_read_mv_component(c, s->prob->mvc[1]);
+ mb->bmv[0] = mb->mv;
+ }
+ } else {
+ clamp_mv(s, &mb->mv, &near_mv[CNT_NEAR]);
+ mb->bmv[0] = mb->mv;
+ }
+ } else {
+ clamp_mv(s, &mb->mv, &near_mv[CNT_NEAREST]);
+ mb->bmv[0] = mb->mv;
+ }
+ } else {
+ mb->mode = VP8_MVMODE_ZERO;
+ AV_ZERO32(&mb->mv);
+ mb->bmv[0] = mb->mv;
+ }
+}
+
+static av_always_inline
+void decode_intra4x4_modes(VP8Context *s, VP56RangeCoder *c, VP8Macroblock *mb,
+ int mb_x, int keyframe, int layout)
+{
+ uint8_t *intra4x4 = mb->intra4x4_pred_mode_mb;
+
+ if (layout) {
+ VP8Macroblock *mb_top = mb - s->mb_width - 1;
+ memcpy(mb->intra4x4_pred_mode_top, mb_top->intra4x4_pred_mode_top, 4);
+ }
+ if (keyframe) {
+ int x, y;
+ uint8_t *top;
+ uint8_t *const left = s->intra4x4_pred_mode_left;
+ if (layout)
+ top = mb->intra4x4_pred_mode_top;
+ else
+ top = s->intra4x4_pred_mode_top + 4 * mb_x;
+ for (y = 0; y < 4; y++) {
+ for (x = 0; x < 4; x++) {
+ const uint8_t *ctx;
+ ctx = vp8_pred4x4_prob_intra[top[x]][left[y]];
+ *intra4x4 = vp8_rac_get_tree(c, vp8_pred4x4_tree, ctx);
+ left[y] = top[x] = *intra4x4;
+ intra4x4++;
+ }
+ }
+ } else {
+ int i;
+ for (i = 0; i < 16; i++)
+ intra4x4[i] = vp8_rac_get_tree(c, vp8_pred4x4_tree,
+ vp8_pred4x4_prob_inter);
+ }
+}
+
+static av_always_inline
+void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,
+ uint8_t *segment, uint8_t *ref, int layout, int is_vp7)
+{
+ VP56RangeCoder *c = &s->c;
+ const char *vp7_feature_name[] = { "q-index",
+ "lf-delta",
+ "partial-golden-update",
+ "blit-pitch" };
+ if (is_vp7) {
+ int i;
+ *segment = 0;
+ for (i = 0; i < 4; i++) {
+ if (s->feature_enabled[i]) {
+ if (vp56_rac_get_prob_branchy(c, s->feature_present_prob[i])) {
+ int index = vp8_rac_get_tree(c, vp7_feature_index_tree,
+ s->feature_index_prob[i]);
+ av_log(s->avctx, AV_LOG_WARNING,
+ "Feature %s present in macroblock (value 0x%x)\n",
+ vp7_feature_name[i], s->feature_value[i][index]);
+ }
+ }
+ }
+ } else if (s->segmentation.update_map) {
+ int bit = vp56_rac_get_prob(c, s->prob->segmentid[0]);
+ *segment = vp56_rac_get_prob(c, s->prob->segmentid[1+bit]) + 2*bit;
+ } else if (s->segmentation.enabled)
+ *segment = ref ? *ref : *segment;
+ mb->segment = *segment;
+
+ mb->skip = s->mbskip_enabled ? vp56_rac_get_prob(c, s->prob->mbskip) : 0;
+
+ if (s->keyframe) {
+ mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_intra,
+ vp8_pred16x16_prob_intra);
+
+ if (mb->mode == MODE_I4x4) {
+ decode_intra4x4_modes(s, c, mb, mb_x, 1, layout);
+ } else {
+ const uint32_t modes = (is_vp7 ? vp7_pred4x4_mode
+ : vp8_pred4x4_mode)[mb->mode] * 0x01010101u;
+ if (s->mb_layout)
+ AV_WN32A(mb->intra4x4_pred_mode_top, modes);
+ else
+ AV_WN32A(s->intra4x4_pred_mode_top + 4 * mb_x, modes);
+ AV_WN32A(s->intra4x4_pred_mode_left, modes);
+ }
+
+ mb->chroma_pred_mode = vp8_rac_get_tree(c, vp8_pred8x8c_tree,
+ vp8_pred8x8c_prob_intra);
+ mb->ref_frame = VP56_FRAME_CURRENT;
+ } else if (vp56_rac_get_prob_branchy(c, s->prob->intra)) {
+ // inter MB, 16.2
+ if (vp56_rac_get_prob_branchy(c, s->prob->last))
+ mb->ref_frame =
+ (!is_vp7 && vp56_rac_get_prob(c, s->prob->golden)) ? VP56_FRAME_GOLDEN2 /* altref */
+ : VP56_FRAME_GOLDEN;
+ else
+ mb->ref_frame = VP56_FRAME_PREVIOUS;
+ s->ref_count[mb->ref_frame - 1]++;
+
+ // motion vectors, 16.3
+ if (is_vp7)
+ vp7_decode_mvs(s, mb, mb_x, mb_y, layout);
+ else
+ vp8_decode_mvs(s, mb, mb_x, mb_y, layout);
+ } else {
+ // intra MB, 16.1
+ mb->mode = vp8_rac_get_tree(c, vp8_pred16x16_tree_inter, s->prob->pred16x16);
+
+ if (mb->mode == MODE_I4x4)
+ decode_intra4x4_modes(s, c, mb, mb_x, 0, layout);
+
+ mb->chroma_pred_mode = vp8_rac_get_tree(c, vp8_pred8x8c_tree,
+ s->prob->pred8x8c);
+ mb->ref_frame = VP56_FRAME_CURRENT;
+ mb->partitioning = VP8_SPLITMVMODE_NONE;
+ AV_ZERO32(&mb->bmv[0]);
+ }
+}
+
+/**
+ * @param r arithmetic bitstream reader context
+ * @param block destination for block coefficients
+ * @param probs probabilities to use when reading trees from the bitstream
+ * @param i initial coeff index, 0 unless a separate DC block is coded
+ * @param qmul array holding the dc/ac dequant factor at position 0/1
+ *
+ * @return 0 if no coeffs were decoded
+ * otherwise, the index of the last coeff decoded plus one
+ */
+static av_always_inline
+int decode_block_coeffs_internal(VP56RangeCoder *r, int16_t block[16],
+ uint8_t probs[16][3][NUM_DCT_TOKENS - 1],
+ int i, uint8_t *token_prob, int16_t qmul[2],
+ const uint8_t scan[16], int vp7)
+{
+ VP56RangeCoder c = *r;
+ goto skip_eob;
+ do {
+ int coeff;
+restart:
+ if (!vp56_rac_get_prob_branchy(&c, token_prob[0])) // DCT_EOB
+ break;
+
+skip_eob:
+ if (!vp56_rac_get_prob_branchy(&c, token_prob[1])) { // DCT_0
+ if (++i == 16)
+ break; // invalid input; blocks should end with EOB
+ token_prob = probs[i][0];
+ if (vp7)
+ goto restart;
+ goto skip_eob;
+ }
+
+ if (!vp56_rac_get_prob_branchy(&c, token_prob[2])) { // DCT_1
+ coeff = 1;
+ token_prob = probs[i + 1][1];
+ } else {
+ if (!vp56_rac_get_prob_branchy(&c, token_prob[3])) { // DCT 2,3,4
+ coeff = vp56_rac_get_prob_branchy(&c, token_prob[4]);
+ if (coeff)
+ coeff += vp56_rac_get_prob(&c, token_prob[5]);
+ coeff += 2;
+ } else {
+ // DCT_CAT*
+ if (!vp56_rac_get_prob_branchy(&c, token_prob[6])) {
+ if (!vp56_rac_get_prob_branchy(&c, token_prob[7])) { // DCT_CAT1
+ coeff = 5 + vp56_rac_get_prob(&c, vp8_dct_cat1_prob[0]);
+ } else { // DCT_CAT2
+ coeff = 7;
+ coeff += vp56_rac_get_prob(&c, vp8_dct_cat2_prob[0]) << 1;
+ coeff += vp56_rac_get_prob(&c, vp8_dct_cat2_prob[1]);
+ }
+ } else { // DCT_CAT3 and up
+ int a = vp56_rac_get_prob(&c, token_prob[8]);
+ int b = vp56_rac_get_prob(&c, token_prob[9 + a]);
+ int cat = (a << 1) + b;
+ coeff = 3 + (8 << cat);
+ coeff += vp8_rac_get_coeff(&c, ff_vp8_dct_cat_prob[cat]);
+ }
+ }
+ token_prob = probs[i + 1][2];
+ }
+ block[scan[i]] = (vp8_rac_get(&c) ? -coeff : coeff) * qmul[!!i];
+ } while (++i < 16);
+
+ *r = c;
+ return i;
+}
+
+static av_always_inline
+int inter_predict_dc(int16_t block[16], int16_t pred[2])
+{
+ int16_t dc = block[0];
+ int ret = 0;
+
+ if (pred[1] > 3) {
+ dc += pred[0];
+ ret = 1;
+ }
+
+ if (!pred[0] | !dc | ((int32_t)pred[0] ^ (int32_t)dc) >> 31) {
+ block[0] = pred[0] = dc;
+ pred[1] = 0;
+ } else {
+ if (pred[0] == dc)
+ pred[1]++;
+ block[0] = pred[0] = dc;
+ }
+
+ return ret;
+}
+
+static int vp7_decode_block_coeffs_internal(VP56RangeCoder *r,
+ int16_t block[16],
+ uint8_t probs[16][3][NUM_DCT_TOKENS - 1],
+ int i, uint8_t *token_prob,
+ int16_t qmul[2],
+ const uint8_t scan[16])
+{
+ return decode_block_coeffs_internal(r, block, probs, i,
+ token_prob, qmul, scan, IS_VP7);
+}
+
+#ifndef vp8_decode_block_coeffs_internal
+static int vp8_decode_block_coeffs_internal(VP56RangeCoder *r,
+ int16_t block[16],
+ uint8_t probs[16][3][NUM_DCT_TOKENS - 1],
+ int i, uint8_t *token_prob,
+ int16_t qmul[2])
+{
+ return decode_block_coeffs_internal(r, block, probs, i,
+ token_prob, qmul, zigzag_scan, IS_VP8);
+}
+#endif
+
+/**
+ * @param c arithmetic bitstream reader context
+ * @param block destination for block coefficients
+ * @param probs probabilities to use when reading trees from the bitstream
+ * @param i initial coeff index, 0 unless a separate DC block is coded
+ * @param zero_nhood the initial prediction context for number of surrounding
+ * all-zero blocks (only left/top, so 0-2)
+ * @param qmul array holding the dc/ac dequant factor at position 0/1
+ * @param scan scan pattern (VP7 only)
+ *
+ * @return 0 if no coeffs were decoded
+ * otherwise, the index of the last coeff decoded plus one
+ */
+static av_always_inline
+int decode_block_coeffs(VP56RangeCoder *c, int16_t block[16],
+ uint8_t probs[16][3][NUM_DCT_TOKENS - 1],
+ int i, int zero_nhood, int16_t qmul[2],
+ const uint8_t scan[16], int vp7)
+{
+ uint8_t *token_prob = probs[i][zero_nhood];
+ if (!vp56_rac_get_prob_branchy(c, token_prob[0])) // DCT_EOB
+ return 0;
+ return vp7 ? vp7_decode_block_coeffs_internal(c, block, probs, i,
+ token_prob, qmul, scan)
+ : vp8_decode_block_coeffs_internal(c, block, probs, i,
+ token_prob, qmul);
+}
+
+static av_always_inline
+void decode_mb_coeffs(VP8Context *s, VP8ThreadData *td, VP56RangeCoder *c,
+ VP8Macroblock *mb, uint8_t t_nnz[9], uint8_t l_nnz[9],
+ int is_vp7)
+{
+ int i, x, y, luma_start = 0, luma_ctx = 3;
+ int nnz_pred, nnz, nnz_total = 0;
+ int segment = mb->segment;
+ int block_dc = 0;
+
+ if (mb->mode != MODE_I4x4 && (is_vp7 || mb->mode != VP8_MVMODE_SPLIT)) {
+ nnz_pred = t_nnz[8] + l_nnz[8];
+
+ // decode DC values and do hadamard
+ nnz = decode_block_coeffs(c, td->block_dc, s->prob->token[1], 0,
+ nnz_pred, s->qmat[segment].luma_dc_qmul,
+ zigzag_scan, is_vp7);
+ l_nnz[8] = t_nnz[8] = !!nnz;
+
+ if (is_vp7 && mb->mode > MODE_I4x4) {
+ nnz |= inter_predict_dc(td->block_dc,
+ s->inter_dc_pred[mb->ref_frame - 1]);
+ }
+
+ if (nnz) {
+ nnz_total += nnz;
+ block_dc = 1;
+ if (nnz == 1)
+ s->vp8dsp.vp8_luma_dc_wht_dc(td->block, td->block_dc);
+ else
+ s->vp8dsp.vp8_luma_dc_wht(td->block, td->block_dc);
+ }
+ luma_start = 1;
+ luma_ctx = 0;
+ }
+
+ // luma blocks
+ for (y = 0; y < 4; y++)
+ for (x = 0; x < 4; x++) {
+ nnz_pred = l_nnz[y] + t_nnz[x];
+ nnz = decode_block_coeffs(c, td->block[y][x],
+ s->prob->token[luma_ctx],
+ luma_start, nnz_pred,
+ s->qmat[segment].luma_qmul,
+ s->prob[0].scan, is_vp7);
+ /* nnz+block_dc may be one more than the actual last index,
+ * but we don't care */
+ td->non_zero_count_cache[y][x] = nnz + block_dc;
+ t_nnz[x] = l_nnz[y] = !!nnz;
+ nnz_total += nnz;
+ }
+
+ // chroma blocks
+ // TODO: what to do about dimensions? 2nd dim for luma is x,
+ // but for chroma it's (y<<1)|x
+ for (i = 4; i < 6; i++)
+ for (y = 0; y < 2; y++)
+ for (x = 0; x < 2; x++) {
+ nnz_pred = l_nnz[i + 2 * y] + t_nnz[i + 2 * x];
+ nnz = decode_block_coeffs(c, td->block[i][(y << 1) + x],
+ s->prob->token[2], 0, nnz_pred,
+ s->qmat[segment].chroma_qmul,
+ s->prob[0].scan, is_vp7);
+ td->non_zero_count_cache[i][(y << 1) + x] = nnz;
+ t_nnz[i + 2 * x] = l_nnz[i + 2 * y] = !!nnz;
+ nnz_total += nnz;
+ }
+
+ // if there were no coded coeffs despite the macroblock not being marked skip,
+ // we MUST not do the inner loop filter and should not do IDCT
+ // Since skip isn't used for bitstream prediction, just manually set it.
+ if (!nnz_total)
+ mb->skip = 1;
+}
+
+static av_always_inline
+void backup_mb_border(uint8_t *top_border, uint8_t *src_y,
+ uint8_t *src_cb, uint8_t *src_cr,
+ int linesize, int uvlinesize, int simple)
+{
+ AV_COPY128(top_border, src_y + 15 * linesize);
+ if (!simple) {
+ AV_COPY64(top_border + 16, src_cb + 7 * uvlinesize);
+ AV_COPY64(top_border + 24, src_cr + 7 * uvlinesize);
+ }
+}
+
+static av_always_inline
+void xchg_mb_border(uint8_t *top_border, uint8_t *src_y, uint8_t *src_cb,
+ uint8_t *src_cr, int linesize, int uvlinesize, int mb_x,
+ int mb_y, int mb_width, int simple, int xchg)
+{
+ uint8_t *top_border_m1 = top_border - 32; // for TL prediction
+ src_y -= linesize;
+ src_cb -= uvlinesize;
+ src_cr -= uvlinesize;
+
+#define XCHG(a, b, xchg) \
+ do { \
+ if (xchg) \
+ AV_SWAP64(b, a); \
+ else \
+ AV_COPY64(b, a); \
+ } while (0)
+
+ XCHG(top_border_m1 + 8, src_y - 8, xchg);
+ XCHG(top_border, src_y, xchg);
+ XCHG(top_border + 8, src_y + 8, 1);
+ if (mb_x < mb_width - 1)
+ XCHG(top_border + 32, src_y + 16, 1);
+
+ // only copy chroma for normal loop filter
+ // or to initialize the top row to 127
+ if (!simple || !mb_y) {
+ XCHG(top_border_m1 + 16, src_cb - 8, xchg);
+ XCHG(top_border_m1 + 24, src_cr - 8, xchg);
+ XCHG(top_border + 16, src_cb, 1);
+ XCHG(top_border + 24, src_cr, 1);
+ }
+}
+
+static av_always_inline
+int check_dc_pred8x8_mode(int mode, int mb_x, int mb_y)
+{
+ if (!mb_x)
+ return mb_y ? TOP_DC_PRED8x8 : DC_128_PRED8x8;
+ else
+ return mb_y ? mode : LEFT_DC_PRED8x8;
+}
+
+static av_always_inline
+int check_tm_pred8x8_mode(int mode, int mb_x, int mb_y, int vp7)
+{
+ if (!mb_x)
+ return mb_y ? VERT_PRED8x8 : (vp7 ? DC_128_PRED8x8 : DC_129_PRED8x8);
+ else
+ return mb_y ? mode : HOR_PRED8x8;
+}
+
+static av_always_inline
+int check_intra_pred8x8_mode_emuedge(int mode, int mb_x, int mb_y, int vp7)
+{
+ switch (mode) {
+ case DC_PRED8x8:
+ return check_dc_pred8x8_mode(mode, mb_x, mb_y);
+ case VERT_PRED8x8:
+ return !mb_y ? (vp7 ? DC_128_PRED8x8 : DC_127_PRED8x8) : mode;
+ case HOR_PRED8x8:
+ return !mb_x ? (vp7 ? DC_128_PRED8x8 : DC_129_PRED8x8) : mode;
+ case PLANE_PRED8x8: /* TM */
+ return check_tm_pred8x8_mode(mode, mb_x, mb_y, vp7);
+ }
+ return mode;
+}
+
+static av_always_inline
+int check_tm_pred4x4_mode(int mode, int mb_x, int mb_y, int vp7)
+{
+ if (!mb_x) {
+ return mb_y ? VERT_VP8_PRED : (vp7 ? DC_128_PRED : DC_129_PRED);
+ } else {
+ return mb_y ? mode : HOR_VP8_PRED;
+ }
+}
+
+static av_always_inline
+int check_intra_pred4x4_mode_emuedge(int mode, int mb_x, int mb_y,
+ int *copy_buf, int vp7)
+{
+ switch (mode) {
+ case VERT_PRED:
+ if (!mb_x && mb_y) {
+ *copy_buf = 1;
+ return mode;
+ }
+ /* fall-through */
+ case DIAG_DOWN_LEFT_PRED:
+ case VERT_LEFT_PRED:
+ return !mb_y ? (vp7 ? DC_128_PRED : DC_127_PRED) : mode;
+ case HOR_PRED:
+ if (!mb_y) {
+ *copy_buf = 1;
+ return mode;
+ }
+ /* fall-through */
+ case HOR_UP_PRED:
+ return !mb_x ? (vp7 ? DC_128_PRED : DC_129_PRED) : mode;
+ case TM_VP8_PRED:
+ return check_tm_pred4x4_mode(mode, mb_x, mb_y, vp7);
+ case DC_PRED: /* 4x4 DC doesn't use the same "H.264-style" exceptions
+ * as 16x16/8x8 DC */
+ case DIAG_DOWN_RIGHT_PRED:
+ case VERT_RIGHT_PRED:
+ case HOR_DOWN_PRED:
+ if (!mb_y || !mb_x)
+ *copy_buf = 1;
+ return mode;
+ }
+ return mode;
+}
+
+static av_always_inline
+void intra_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3],
+ VP8Macroblock *mb, int mb_x, int mb_y, int is_vp7)
+{
+ int x, y, mode, nnz;
+ uint32_t tr;
+
+ /* for the first row, we need to run xchg_mb_border to init the top edge
+ * to 127 otherwise, skip it if we aren't going to deblock */
+ if (mb_y && (s->deblock_filter || !mb_y) && td->thread_nr == 0)
+ xchg_mb_border(s->top_border[mb_x + 1], dst[0], dst[1], dst[2],
+ s->linesize, s->uvlinesize, mb_x, mb_y, s->mb_width,
+ s->filter.simple, 1);
+
+ if (mb->mode < MODE_I4x4) {
+ mode = check_intra_pred8x8_mode_emuedge(mb->mode, mb_x, mb_y, is_vp7);
+ s->hpc.pred16x16[mode](dst[0], s->linesize);
+ } else {
+ uint8_t *ptr = dst[0];
+ uint8_t *intra4x4 = mb->intra4x4_pred_mode_mb;
+ const uint8_t lo = is_vp7 ? 128 : 127;
+ const uint8_t hi = is_vp7 ? 128 : 129;
+ uint8_t tr_top[4] = { lo, lo, lo, lo };
+
+ // all blocks on the right edge of the macroblock use bottom edge
+ // the top macroblock for their topright edge
+ uint8_t *tr_right = ptr - s->linesize + 16;
+
+ // if we're on the right edge of the frame, said edge is extended
+ // from the top macroblock
+ if (mb_y && mb_x == s->mb_width - 1) {
+ tr = tr_right[-1] * 0x01010101u;
+ tr_right = (uint8_t *) &tr;
+ }
+
+ if (mb->skip)
+ AV_ZERO128(td->non_zero_count_cache);
+
+ for (y = 0; y < 4; y++) {
+ uint8_t *topright = ptr + 4 - s->linesize;
+ for (x = 0; x < 4; x++) {
+ int copy = 0, linesize = s->linesize;
+ uint8_t *dst = ptr + 4 * x;
+ LOCAL_ALIGNED(4, uint8_t, copy_dst, [5 * 8]);
+
+ if ((y == 0 || x == 3) && mb_y == 0) {
+ topright = tr_top;
+ } else if (x == 3)
+ topright = tr_right;
+
+ mode = check_intra_pred4x4_mode_emuedge(intra4x4[x], mb_x + x,
+ mb_y + y, ©, is_vp7);
+ if (copy) {
+ dst = copy_dst + 12;
+ linesize = 8;
+ if (!(mb_y + y)) {
+ copy_dst[3] = lo;
+ AV_WN32A(copy_dst + 4, lo * 0x01010101U);
+ } else {
+ AV_COPY32(copy_dst + 4, ptr + 4 * x - s->linesize);
+ if (!(mb_x + x)) {
+ copy_dst[3] = hi;
+ } else {
+ copy_dst[3] = ptr[4 * x - s->linesize - 1];
+ }
+ }
+ if (!(mb_x + x)) {
+ copy_dst[11] =
+ copy_dst[19] =
+ copy_dst[27] =
+ copy_dst[35] = hi;
+ } else {
+ copy_dst[11] = ptr[4 * x - 1];
+ copy_dst[19] = ptr[4 * x + s->linesize - 1];
+ copy_dst[27] = ptr[4 * x + s->linesize * 2 - 1];
+ copy_dst[35] = ptr[4 * x + s->linesize * 3 - 1];
+ }
+ }
+ s->hpc.pred4x4[mode](dst, topright, linesize);
+ if (copy) {
+ AV_COPY32(ptr + 4 * x, copy_dst + 12);
+ AV_COPY32(ptr + 4 * x + s->linesize, copy_dst + 20);
+ AV_COPY32(ptr + 4 * x + s->linesize * 2, copy_dst + 28);
+ AV_COPY32(ptr + 4 * x + s->linesize * 3, copy_dst + 36);
+ }
+
+ nnz = td->non_zero_count_cache[y][x];
+ if (nnz) {
+ if (nnz == 1)
+ s->vp8dsp.vp8_idct_dc_add(ptr + 4 * x,
+ td->block[y][x], s->linesize);
+ else
+ s->vp8dsp.vp8_idct_add(ptr + 4 * x,
+ td->block[y][x], s->linesize);
+ }
+ topright += 4;
+ }
+
+ ptr += 4 * s->linesize;
+ intra4x4 += 4;
+ }
+ }
+
+ mode = check_intra_pred8x8_mode_emuedge(mb->chroma_pred_mode,
+ mb_x, mb_y, is_vp7);
+ s->hpc.pred8x8[mode](dst[1], s->uvlinesize);
+ s->hpc.pred8x8[mode](dst[2], s->uvlinesize);
+
+ if (mb_y && (s->deblock_filter || !mb_y) && td->thread_nr == 0)
+ xchg_mb_border(s->top_border[mb_x + 1], dst[0], dst[1], dst[2],
+ s->linesize, s->uvlinesize, mb_x, mb_y, s->mb_width,
+ s->filter.simple, 0);
+}
+
+static const uint8_t subpel_idx[3][8] = {
+ { 0, 1, 2, 1, 2, 1, 2, 1 }, // nr. of left extra pixels,
+ // also function pointer index
+ { 0, 3, 5, 3, 5, 3, 5, 3 }, // nr. of extra pixels required
+ { 0, 2, 3, 2, 3, 2, 3, 2 }, // nr. of right extra pixels
+};
+
+/**
+ * luma MC function
+ *
+ * @param s VP8 decoding context
+ * @param dst target buffer for block data at block position
+ * @param ref reference picture buffer at origin (0, 0)
+ * @param mv motion vector (relative to block position) to get pixel data from
+ * @param x_off horizontal position of block from origin (0, 0)
+ * @param y_off vertical position of block from origin (0, 0)
+ * @param block_w width of block (16, 8 or 4)
+ * @param block_h height of block (always same as block_w)
+ * @param width width of src/dst plane data
+ * @param height height of src/dst plane data
+ * @param linesize size of a single line of plane data, including padding
+ * @param mc_func motion compensation function pointers (bilinear or sixtap MC)
+ */
+static av_always_inline
+void vp8_mc_luma(VP8Context *s, VP8ThreadData *td, uint8_t *dst,
+ ThreadFrame *ref, const VP56mv *mv,
+ int x_off, int y_off, int block_w, int block_h,
+ int width, int height, ptrdiff_t linesize,
+ vp8_mc_func mc_func[3][3])
+{
+ uint8_t *src = ref->f->data[0];
+
+ if (AV_RN32A(mv)) {
+ int src_linesize = linesize;
+
+ int mx = (mv->x * 2) & 7, mx_idx = subpel_idx[0][mx];
+ int my = (mv->y * 2) & 7, my_idx = subpel_idx[0][my];
+
+ x_off += mv->x >> 2;
+ y_off += mv->y >> 2;
+
+ // edge emulation
+ ff_thread_await_progress(ref, (3 + y_off + block_h + subpel_idx[2][my]) >> 4, 0);
+ src += y_off * linesize + x_off;
+ if (x_off < mx_idx || x_off >= width - block_w - subpel_idx[2][mx] ||
+ y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
+ s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
+ src - my_idx * linesize - mx_idx,
+ EDGE_EMU_LINESIZE, linesize,
+ block_w + subpel_idx[1][mx],
+ block_h + subpel_idx[1][my],
+ x_off - mx_idx, y_off - my_idx,
+ width, height);
+ src = td->edge_emu_buffer + mx_idx + EDGE_EMU_LINESIZE * my_idx;
+ src_linesize = EDGE_EMU_LINESIZE;
+ }
+ mc_func[my_idx][mx_idx](dst, linesize, src, src_linesize, block_h, mx, my);
+ } else {
+ ff_thread_await_progress(ref, (3 + y_off + block_h) >> 4, 0);
+ mc_func[0][0](dst, linesize, src + y_off * linesize + x_off,
+ linesize, block_h, 0, 0);
+ }
+}
+
+/**
+ * chroma MC function
+ *
+ * @param s VP8 decoding context
+ * @param dst1 target buffer for block data at block position (U plane)
+ * @param dst2 target buffer for block data at block position (V plane)
+ * @param ref reference picture buffer at origin (0, 0)
+ * @param mv motion vector (relative to block position) to get pixel data from
+ * @param x_off horizontal position of block from origin (0, 0)
+ * @param y_off vertical position of block from origin (0, 0)
+ * @param block_w width of block (16, 8 or 4)
+ * @param block_h height of block (always same as block_w)
+ * @param width width of src/dst plane data
+ * @param height height of src/dst plane data
+ * @param linesize size of a single line of plane data, including padding
+ * @param mc_func motion compensation function pointers (bilinear or sixtap MC)
+ */
+static av_always_inline
+void vp8_mc_chroma(VP8Context *s, VP8ThreadData *td, uint8_t *dst1,
+ uint8_t *dst2, ThreadFrame *ref, const VP56mv *mv,
+ int x_off, int y_off, int block_w, int block_h,
+ int width, int height, ptrdiff_t linesize,
+ vp8_mc_func mc_func[3][3])
+{
+ uint8_t *src1 = ref->f->data[1], *src2 = ref->f->data[2];
+
+ if (AV_RN32A(mv)) {
+ int mx = mv->x & 7, mx_idx = subpel_idx[0][mx];
+ int my = mv->y & 7, my_idx = subpel_idx[0][my];
+
+ x_off += mv->x >> 3;
+ y_off += mv->y >> 3;
+
+ // edge emulation
+ src1 += y_off * linesize + x_off;
+ src2 += y_off * linesize + x_off;
+ ff_thread_await_progress(ref, (3 + y_off + block_h + subpel_idx[2][my]) >> 3, 0);
+ if (x_off < mx_idx || x_off >= width - block_w - subpel_idx[2][mx] ||
+ y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
+ s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
+ src1 - my_idx * linesize - mx_idx,
+ EDGE_EMU_LINESIZE, linesize,
+ block_w + subpel_idx[1][mx],
+ block_h + subpel_idx[1][my],
+ x_off - mx_idx, y_off - my_idx, width, height);
+ src1 = td->edge_emu_buffer + mx_idx + EDGE_EMU_LINESIZE * my_idx;
+ mc_func[my_idx][mx_idx](dst1, linesize, src1, EDGE_EMU_LINESIZE, block_h, mx, my);
+
+ s->vdsp.emulated_edge_mc(td->edge_emu_buffer,
+ src2 - my_idx * linesize - mx_idx,
+ EDGE_EMU_LINESIZE, linesize,
+ block_w + subpel_idx[1][mx],
+ block_h + subpel_idx[1][my],
+ x_off - mx_idx, y_off - my_idx, width, height);
+ src2 = td->edge_emu_buffer + mx_idx + EDGE_EMU_LINESIZE * my_idx;
+ mc_func[my_idx][mx_idx](dst2, linesize, src2, EDGE_EMU_LINESIZE, block_h, mx, my);
+ } else {
+ mc_func[my_idx][mx_idx](dst1, linesize, src1, linesize, block_h, mx, my);
+ mc_func[my_idx][mx_idx](dst2, linesize, src2, linesize, block_h, mx, my);
+ }
+ } else {
+ ff_thread_await_progress(ref, (3 + y_off + block_h) >> 3, 0);
+ mc_func[0][0](dst1, linesize, src1 + y_off * linesize + x_off, linesize, block_h, 0, 0);
+ mc_func[0][0](dst2, linesize, src2 + y_off * linesize + x_off, linesize, block_h, 0, 0);
+ }
+}
+
+static av_always_inline
+void vp8_mc_part(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3],
+ ThreadFrame *ref_frame, int x_off, int y_off,
+ int bx_off, int by_off, int block_w, int block_h,
+ int width, int height, VP56mv *mv)
+{
+ VP56mv uvmv = *mv;
+
+ /* Y */
+ vp8_mc_luma(s, td, dst[0] + by_off * s->linesize + bx_off,
+ ref_frame, mv, x_off + bx_off, y_off + by_off,
+ block_w, block_h, width, height, s->linesize,
+ s->put_pixels_tab[block_w == 8]);
+
+ /* U/V */
+ if (s->profile == 3) {
+ /* this block only applies VP8; it is safe to check
+ * only the profile, as VP7 profile <= 1 */
+ uvmv.x &= ~7;
+ uvmv.y &= ~7;
+ }
+ x_off >>= 1;
+ y_off >>= 1;
+ bx_off >>= 1;
+ by_off >>= 1;
+ width >>= 1;
+ height >>= 1;
+ block_w >>= 1;
+ block_h >>= 1;
+ vp8_mc_chroma(s, td, dst[1] + by_off * s->uvlinesize + bx_off,
+ dst[2] + by_off * s->uvlinesize + bx_off, ref_frame,
+ &uvmv, x_off + bx_off, y_off + by_off,
+ block_w, block_h, width, height, s->uvlinesize,
+ s->put_pixels_tab[1 + (block_w == 4)]);
+}
+
+/* Fetch pixels for estimated mv 4 macroblocks ahead.
+ * Optimized for 64-byte cache lines. Inspired by ffh264 prefetch_motion. */
+static av_always_inline
+void prefetch_motion(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y,
+ int mb_xy, int ref)
+{
+ /* Don't prefetch refs that haven't been used very often this frame. */
+ if (s->ref_count[ref - 1] > (mb_xy >> 5)) {
+ int x_off = mb_x << 4, y_off = mb_y << 4;
+ int mx = (mb->mv.x >> 2) + x_off + 8;
+ int my = (mb->mv.y >> 2) + y_off;
+ uint8_t **src = s->framep[ref]->tf.f->data;
+ int off = mx + (my + (mb_x & 3) * 4) * s->linesize + 64;
+ /* For threading, a ff_thread_await_progress here might be useful, but
+ * it actually slows down the decoder. Since a bad prefetch doesn't
+ * generate bad decoder output, we don't run it here. */
+ s->vdsp.prefetch(src[0] + off, s->linesize, 4);
+ off = (mx >> 1) + ((my >> 1) + (mb_x & 7)) * s->uvlinesize + 64;
+ s->vdsp.prefetch(src[1] + off, src[2] - src[1], 2);
+ }
+}
+
+/**
+ * Apply motion vectors to prediction buffer, chapter 18.
+ */
+static av_always_inline
+void inter_predict(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3],
+ VP8Macroblock *mb, int mb_x, int mb_y)
+{
+ int x_off = mb_x << 4, y_off = mb_y << 4;
+ int width = 16 * s->mb_width, height = 16 * s->mb_height;
+ ThreadFrame *ref = &s->framep[mb->ref_frame]->tf;
+ VP56mv *bmv = mb->bmv;
+
+ switch (mb->partitioning) {
+ case VP8_SPLITMVMODE_NONE:
+ vp8_mc_part(s, td, dst, ref, x_off, y_off,
+ 0, 0, 16, 16, width, height, &mb->mv);
+ break;
+ case VP8_SPLITMVMODE_4x4: {
+ int x, y;
+ VP56mv uvmv;
+
+ /* Y */
+ for (y = 0; y < 4; y++) {
+ for (x = 0; x < 4; x++) {
+ vp8_mc_luma(s, td, dst[0] + 4 * y * s->linesize + x * 4,
+ ref, &bmv[4 * y + x],
+ 4 * x + x_off, 4 * y + y_off, 4, 4,
+ width, height, s->linesize,
+ s->put_pixels_tab[2]);
+ }
+ }
+
+ /* U/V */
+ x_off >>= 1;
+ y_off >>= 1;
+ width >>= 1;
+ height >>= 1;
+ for (y = 0; y < 2; y++) {
+ for (x = 0; x < 2; x++) {
+ uvmv.x = mb->bmv[2 * y * 4 + 2 * x ].x +
+ mb->bmv[2 * y * 4 + 2 * x + 1].x +
+ mb->bmv[(2 * y + 1) * 4 + 2 * x ].x +
+ mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].x;
+ uvmv.y = mb->bmv[2 * y * 4 + 2 * x ].y +
+ mb->bmv[2 * y * 4 + 2 * x + 1].y +
+ mb->bmv[(2 * y + 1) * 4 + 2 * x ].y +
+ mb->bmv[(2 * y + 1) * 4 + 2 * x + 1].y;
+ uvmv.x = (uvmv.x + 2 + FF_SIGNBIT(uvmv.x)) >> 2;
+ uvmv.y = (uvmv.y + 2 + FF_SIGNBIT(uvmv.y)) >> 2;
+ if (s->profile == 3) {
+ uvmv.x &= ~7;
+ uvmv.y &= ~7;
+ }
+ vp8_mc_chroma(s, td, dst[1] + 4 * y * s->uvlinesize + x * 4,
+ dst[2] + 4 * y * s->uvlinesize + x * 4, ref,
+ &uvmv, 4 * x + x_off, 4 * y + y_off, 4, 4,
+ width, height, s->uvlinesize,
+ s->put_pixels_tab[2]);
+ }
+ }
+ break;
+ }
+ case VP8_SPLITMVMODE_16x8:
+ vp8_mc_part(s, td, dst, ref, x_off, y_off,
+ 0, 0, 16, 8, width, height, &bmv[0]);
+ vp8_mc_part(s, td, dst, ref, x_off, y_off,
+ 0, 8, 16, 8, width, height, &bmv[1]);
+ break;
+ case VP8_SPLITMVMODE_8x16:
+ vp8_mc_part(s, td, dst, ref, x_off, y_off,
+ 0, 0, 8, 16, width, height, &bmv[0]);
+ vp8_mc_part(s, td, dst, ref, x_off, y_off,
+ 8, 0, 8, 16, width, height, &bmv[1]);
+ break;
+ case VP8_SPLITMVMODE_8x8:
+ vp8_mc_part(s, td, dst, ref, x_off, y_off,
+ 0, 0, 8, 8, width, height, &bmv[0]);
+ vp8_mc_part(s, td, dst, ref, x_off, y_off,
+ 8, 0, 8, 8, width, height, &bmv[1]);
+ vp8_mc_part(s, td, dst, ref, x_off, y_off,
+ 0, 8, 8, 8, width, height, &bmv[2]);
+ vp8_mc_part(s, td, dst, ref, x_off, y_off,
+ 8, 8, 8, 8, width, height, &bmv[3]);
+ break;
+ }
+}
+
+static av_always_inline
+void idct_mb(VP8Context *s, VP8ThreadData *td, uint8_t *dst[3], VP8Macroblock *mb)
+{
+ int x, y, ch;
+
+ if (mb->mode != MODE_I4x4) {
+ uint8_t *y_dst = dst[0];
+ for (y = 0; y < 4; y++) {
+ uint32_t nnz4 = AV_RL32(td->non_zero_count_cache[y]);
+ if (nnz4) {
+ if (nnz4 & ~0x01010101) {
+ for (x = 0; x < 4; x++) {
+ if ((uint8_t) nnz4 == 1)
+ s->vp8dsp.vp8_idct_dc_add(y_dst + 4 * x,
+ td->block[y][x],
+ s->linesize);
+ else if ((uint8_t) nnz4 > 1)
+ s->vp8dsp.vp8_idct_add(y_dst + 4 * x,
+ td->block[y][x],
+ s->linesize);
+ nnz4 >>= 8;
+ if (!nnz4)
+ break;
+ }
+ } else {
+ s->vp8dsp.vp8_idct_dc_add4y(y_dst, td->block[y], s->linesize);
+ }
+ }
+ y_dst += 4 * s->linesize;
+ }
+ }
+
+ for (ch = 0; ch < 2; ch++) {
+ uint32_t nnz4 = AV_RL32(td->non_zero_count_cache[4 + ch]);
+ if (nnz4) {
+ uint8_t *ch_dst = dst[1 + ch];
+ if (nnz4 & ~0x01010101) {
+ for (y = 0; y < 2; y++) {
+ for (x = 0; x < 2; x++) {
+ if ((uint8_t) nnz4 == 1)
+ s->vp8dsp.vp8_idct_dc_add(ch_dst + 4 * x,
+ td->block[4 + ch][(y << 1) + x],
+ s->uvlinesize);
+ else if ((uint8_t) nnz4 > 1)
+ s->vp8dsp.vp8_idct_add(ch_dst + 4 * x,
+ td->block[4 + ch][(y << 1) + x],
+ s->uvlinesize);
+ nnz4 >>= 8;
+ if (!nnz4)
+ goto chroma_idct_end;
+ }
+ ch_dst += 4 * s->uvlinesize;
+ }
+ } else {
+ s->vp8dsp.vp8_idct_dc_add4uv(ch_dst, td->block[4 + ch], s->uvlinesize);
+ }
+ }
+chroma_idct_end:
+ ;
+ }
+}
+
+static av_always_inline
+void filter_level_for_mb(VP8Context *s, VP8Macroblock *mb,
+ VP8FilterStrength *f, int is_vp7)
+{
+ int interior_limit, filter_level;
+
+ if (s->segmentation.enabled) {
+ filter_level = s->segmentation.filter_level[mb->segment];
+ if (!s->segmentation.absolute_vals)
+ filter_level += s->filter.level;
+ } else
+ filter_level = s->filter.level;
+
+ if (s->lf_delta.enabled) {
+ filter_level += s->lf_delta.ref[mb->ref_frame];
+ filter_level += s->lf_delta.mode[mb->mode];
+ }
+
+ filter_level = av_clip_uintp2(filter_level, 6);
+
+ interior_limit = filter_level;
+ if (s->filter.sharpness) {
+ interior_limit >>= (s->filter.sharpness + 3) >> 2;
+ interior_limit = FFMIN(interior_limit, 9 - s->filter.sharpness);
+ }
+ interior_limit = FFMAX(interior_limit, 1);
+
+ f->filter_level = filter_level;
+ f->inner_limit = interior_limit;
+ f->inner_filter = is_vp7 || !mb->skip || mb->mode == MODE_I4x4 ||
+ mb->mode == VP8_MVMODE_SPLIT;
+}
+
+static av_always_inline
+void filter_mb(VP8Context *s, uint8_t *dst[3], VP8FilterStrength *f,
+ int mb_x, int mb_y, int is_vp7)
+{
+ int mbedge_lim, bedge_lim_y, bedge_lim_uv, hev_thresh;
+ int filter_level = f->filter_level;
+ int inner_limit = f->inner_limit;
+ int inner_filter = f->inner_filter;
+ int linesize = s->linesize;
+ int uvlinesize = s->uvlinesize;
+ static const uint8_t hev_thresh_lut[2][64] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2 }
+ };
+
+ if (!filter_level)
+ return;
+
+ if (is_vp7) {
+ bedge_lim_y = filter_level;
+ bedge_lim_uv = filter_level * 2;
+ mbedge_lim = filter_level + 2;
+ } else {
+ bedge_lim_y =
+ bedge_lim_uv = filter_level * 2 + inner_limit;
+ mbedge_lim = bedge_lim_y + 4;
+ }
+
+ hev_thresh = hev_thresh_lut[s->keyframe][filter_level];
+
+ if (mb_x) {
+ s->vp8dsp.vp8_h_loop_filter16y(dst[0], linesize,
+ mbedge_lim, inner_limit, hev_thresh);
+ s->vp8dsp.vp8_h_loop_filter8uv(dst[1], dst[2], uvlinesize,
+ mbedge_lim, inner_limit, hev_thresh);
+ }
+
+#define H_LOOP_FILTER_16Y_INNER(cond) \
+ if (cond && inner_filter) { \
+ s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 4, linesize, \
+ bedge_lim_y, inner_limit, \
+ hev_thresh); \
+ s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 8, linesize, \
+ bedge_lim_y, inner_limit, \
+ hev_thresh); \
+ s->vp8dsp.vp8_h_loop_filter16y_inner(dst[0] + 12, linesize, \
+ bedge_lim_y, inner_limit, \
+ hev_thresh); \
+ s->vp8dsp.vp8_h_loop_filter8uv_inner(dst[1] + 4, dst[2] + 4, \
+ uvlinesize, bedge_lim_uv, \
+ inner_limit, hev_thresh); \
+ }
+
+ H_LOOP_FILTER_16Y_INNER(!is_vp7)
+
+ if (mb_y) {
+ s->vp8dsp.vp8_v_loop_filter16y(dst[0], linesize,
+ mbedge_lim, inner_limit, hev_thresh);
+ s->vp8dsp.vp8_v_loop_filter8uv(dst[1], dst[2], uvlinesize,
+ mbedge_lim, inner_limit, hev_thresh);
+ }
+
+ if (inner_filter) {
+ s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 4 * linesize,
+ linesize, bedge_lim_y,
+ inner_limit, hev_thresh);
+ s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 8 * linesize,
+ linesize, bedge_lim_y,
+ inner_limit, hev_thresh);
+ s->vp8dsp.vp8_v_loop_filter16y_inner(dst[0] + 12 * linesize,
+ linesize, bedge_lim_y,
+ inner_limit, hev_thresh);
+ s->vp8dsp.vp8_v_loop_filter8uv_inner(dst[1] + 4 * uvlinesize,
+ dst[2] + 4 * uvlinesize,
+ uvlinesize, bedge_lim_uv,
+ inner_limit, hev_thresh);
+ }
+
+ H_LOOP_FILTER_16Y_INNER(is_vp7)
+}
+
+static av_always_inline
+void filter_mb_simple(VP8Context *s, uint8_t *dst, VP8FilterStrength *f,
+ int mb_x, int mb_y)
+{
+ int mbedge_lim, bedge_lim;
+ int filter_level = f->filter_level;
+ int inner_limit = f->inner_limit;
+ int inner_filter = f->inner_filter;
+ int linesize = s->linesize;
+
+ if (!filter_level)
+ return;
+
+ bedge_lim = 2 * filter_level + inner_limit;
+ mbedge_lim = bedge_lim + 4;
+
+ if (mb_x)
+ s->vp8dsp.vp8_h_loop_filter_simple(dst, linesize, mbedge_lim);
+ if (inner_filter) {
+ s->vp8dsp.vp8_h_loop_filter_simple(dst + 4, linesize, bedge_lim);
+ s->vp8dsp.vp8_h_loop_filter_simple(dst + 8, linesize, bedge_lim);
+ s->vp8dsp.vp8_h_loop_filter_simple(dst + 12, linesize, bedge_lim);
+ }
+
+ if (mb_y)
+ s->vp8dsp.vp8_v_loop_filter_simple(dst, linesize, mbedge_lim);
+ if (inner_filter) {
+ s->vp8dsp.vp8_v_loop_filter_simple(dst + 4 * linesize, linesize, bedge_lim);
+ s->vp8dsp.vp8_v_loop_filter_simple(dst + 8 * linesize, linesize, bedge_lim);
+ s->vp8dsp.vp8_v_loop_filter_simple(dst + 12 * linesize, linesize, bedge_lim);
+ }
+}
+
+#define MARGIN (16 << 2)
+static av_always_inline
+void vp78_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *curframe,
+ VP8Frame *prev_frame, int is_vp7)
+{
+ VP8Context *s = avctx->priv_data;
+ int mb_x, mb_y;
+
+ s->mv_min.y = -MARGIN;
+ s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN;
+ for (mb_y = 0; mb_y < s->mb_height; mb_y++) {
+ VP8Macroblock *mb = s->macroblocks_base +
+ ((s->mb_width + 1) * (mb_y + 1) + 1);
+ int mb_xy = mb_y * s->mb_width;
+
+ AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED * 0x01010101);
+
+ s->mv_min.x = -MARGIN;
+ s->mv_max.x = ((s->mb_width - 1) << 6) + MARGIN;
+ for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {
+ if (mb_y == 0)
+ AV_WN32A((mb - s->mb_width - 1)->intra4x4_pred_mode_top,
+ DC_PRED * 0x01010101);
+ decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,
+ prev_frame && prev_frame->seg_map ?
+ prev_frame->seg_map->data + mb_xy : NULL, 1, is_vp7);
+ s->mv_min.x -= 64;
+ s->mv_max.x -= 64;
+ }
+ s->mv_min.y -= 64;
+ s->mv_max.y -= 64;
+ }
+}
+
+static void vp7_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame,
+ VP8Frame *prev_frame)
+{
+ vp78_decode_mv_mb_modes(avctx, cur_frame, prev_frame, IS_VP7);
+}
+
+static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame,
+ VP8Frame *prev_frame)
+{
+ vp78_decode_mv_mb_modes(avctx, cur_frame, prev_frame, IS_VP8);
+}
+
+#if HAVE_THREADS
+#define check_thread_pos(td, otd, mb_x_check, mb_y_check) \
+ do { \
+ int tmp = (mb_y_check << 16) | (mb_x_check & 0xFFFF); \
+ if (otd->thread_mb_pos < tmp) { \
+ pthread_mutex_lock(&otd->lock); \
+ td->wait_mb_pos = tmp; \
+ do { \
+ if (otd->thread_mb_pos >= tmp) \
+ break; \
+ pthread_cond_wait(&otd->cond, &otd->lock); \
+ } while (1); \
+ td->wait_mb_pos = INT_MAX; \
+ pthread_mutex_unlock(&otd->lock); \
+ } \
+ } while (0)
+
+#define update_pos(td, mb_y, mb_x) \
+ do { \
+ int pos = (mb_y << 16) | (mb_x & 0xFFFF); \
+ int sliced_threading = (avctx->active_thread_type == FF_THREAD_SLICE) && \
+ (num_jobs > 1); \
+ int is_null = !next_td || !prev_td; \
+ int pos_check = (is_null) ? 1 \
+ : (next_td != td && \
+ pos >= next_td->wait_mb_pos) || \
+ (prev_td != td && \
+ pos >= prev_td->wait_mb_pos); \
+ td->thread_mb_pos = pos; \
+ if (sliced_threading && pos_check) { \
+ pthread_mutex_lock(&td->lock); \
+ pthread_cond_broadcast(&td->cond); \
+ pthread_mutex_unlock(&td->lock); \
+ } \
+ } while (0)
+#else
+#define check_thread_pos(td, otd, mb_x_check, mb_y_check) while(0)
+#define update_pos(td, mb_y, mb_x) while(0)
+#endif
+
+static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
+ int jobnr, int threadnr, int is_vp7)
+{
+ VP8Context *s = avctx->priv_data;
+ VP8ThreadData *prev_td, *next_td, *td = &s->thread_data[threadnr];
+ int mb_y = td->thread_mb_pos >> 16;
+ int mb_x, mb_xy = mb_y * s->mb_width;
+ int num_jobs = s->num_jobs;
+ VP8Frame *curframe = s->curframe, *prev_frame = s->prev_frame;
+ VP56RangeCoder *c = &s->coeff_partition[mb_y & (s->num_coeff_partitions - 1)];
+ VP8Macroblock *mb;
+ uint8_t *dst[3] = {
+ curframe->tf.f->data[0] + 16 * mb_y * s->linesize,
+ curframe->tf.f->data[1] + 8 * mb_y * s->uvlinesize,
+ curframe->tf.f->data[2] + 8 * mb_y * s->uvlinesize
+ };
+
+ if (c->end <= c->buffer && c->bits >= 0)
+ return AVERROR_INVALIDDATA;
+
+ if (mb_y == 0)
+ prev_td = td;
+ else
+ prev_td = &s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
+ if (mb_y == s->mb_height - 1)
+ next_td = td;
+ else
+ next_td = &s->thread_data[(jobnr + 1) % num_jobs];
+ if (s->mb_layout == 1)
+ mb = s->macroblocks_base + ((s->mb_width + 1) * (mb_y + 1) + 1);
+ else {
+ // Make sure the previous frame has read its segmentation map,
+ // if we re-use the same map.
+ if (prev_frame && s->segmentation.enabled &&
+ !s->segmentation.update_map)
+ ff_thread_await_progress(&prev_frame->tf, mb_y, 0);
+ mb = s->macroblocks + (s->mb_height - mb_y - 1) * 2;
+ memset(mb - 1, 0, sizeof(*mb)); // zero left macroblock
+ AV_WN32A(s->intra4x4_pred_mode_left, DC_PRED * 0x01010101);
+ }
+
+ if (!is_vp7 || mb_y == 0)
+ memset(td->left_nnz, 0, sizeof(td->left_nnz));
+
+ s->mv_min.x = -MARGIN;
+ s->mv_max.x = ((s->mb_width - 1) << 6) + MARGIN;
+
+ for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb_xy++, mb++) {
+ if (c->end <= c->buffer && c->bits >= 0)
+ return AVERROR_INVALIDDATA;
+ // Wait for previous thread to read mb_x+2, and reach mb_y-1.
+ if (prev_td != td) {
+ if (threadnr != 0) {
+ check_thread_pos(td, prev_td,
+ mb_x + (is_vp7 ? 2 : 1),
+ mb_y - (is_vp7 ? 2 : 1));
+ } else {
+ check_thread_pos(td, prev_td,
+ mb_x + (is_vp7 ? 2 : 1) + s->mb_width + 3,
+ mb_y - (is_vp7 ? 2 : 1));
+ }
+ }
+
+ s->vdsp.prefetch(dst[0] + (mb_x & 3) * 4 * s->linesize + 64,
+ s->linesize, 4);
+ s->vdsp.prefetch(dst[1] + (mb_x & 7) * s->uvlinesize + 64,
+ dst[2] - dst[1], 2);
+
+ if (!s->mb_layout)
+ decode_mb_mode(s, mb, mb_x, mb_y, curframe->seg_map->data + mb_xy,
+ prev_frame && prev_frame->seg_map ?
+ prev_frame->seg_map->data + mb_xy : NULL, 0, is_vp7);
+
+ prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_PREVIOUS);
+
+ if (!mb->skip)
+ decode_mb_coeffs(s, td, c, mb, s->top_nnz[mb_x], td->left_nnz, is_vp7);
+
+ if (mb->mode <= MODE_I4x4)
+ intra_predict(s, td, dst, mb, mb_x, mb_y, is_vp7);
+ else
+ inter_predict(s, td, dst, mb, mb_x, mb_y);
+
+ prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_GOLDEN);
+
+ if (!mb->skip) {
+ idct_mb(s, td, dst, mb);
+ } else {
+ AV_ZERO64(td->left_nnz);
+ AV_WN64(s->top_nnz[mb_x], 0); // array of 9, so unaligned
+
+ /* Reset DC block predictors if they would exist
+ * if the mb had coefficients */
+ if (mb->mode != MODE_I4x4 && mb->mode != VP8_MVMODE_SPLIT) {
+ td->left_nnz[8] = 0;
+ s->top_nnz[mb_x][8] = 0;
+ }
+ }
+
+ if (s->deblock_filter)
+ filter_level_for_mb(s, mb, &td->filter_strength[mb_x], is_vp7);
+
+ if (s->deblock_filter && num_jobs != 1 && threadnr == num_jobs - 1) {
+ if (s->filter.simple)
+ backup_mb_border(s->top_border[mb_x + 1], dst[0],
+ NULL, NULL, s->linesize, 0, 1);
+ else
+ backup_mb_border(s->top_border[mb_x + 1], dst[0],
+ dst[1], dst[2], s->linesize, s->uvlinesize, 0);
+ }
+
+ prefetch_motion(s, mb, mb_x, mb_y, mb_xy, VP56_FRAME_GOLDEN2);
+
+ dst[0] += 16;
+ dst[1] += 8;
+ dst[2] += 8;
+ s->mv_min.x -= 64;
+ s->mv_max.x -= 64;
+
+ if (mb_x == s->mb_width + 1) {
+ update_pos(td, mb_y, s->mb_width + 3);
+ } else {
+ update_pos(td, mb_y, mb_x);
+ }
+ }
+ return 0;
+}
+
+static int vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
+ int jobnr, int threadnr)
+{
+ return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1);
+}
+
+static int vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
+ int jobnr, int threadnr)
+{
+ return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0);
+}
+
+static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata,
+ int jobnr, int threadnr, int is_vp7)
+{
+ VP8Context *s = avctx->priv_data;
+ VP8ThreadData *td = &s->thread_data[threadnr];
+ int mb_x, mb_y = td->thread_mb_pos >> 16, num_jobs = s->num_jobs;
+ AVFrame *curframe = s->curframe->tf.f;
+ VP8Macroblock *mb;
+ VP8ThreadData *prev_td, *next_td;
+ uint8_t *dst[3] = {
+ curframe->data[0] + 16 * mb_y * s->linesize,
+ curframe->data[1] + 8 * mb_y * s->uvlinesize,
+ curframe->data[2] + 8 * mb_y * s->uvlinesize
+ };
+
+ if (s->mb_layout == 1)
+ mb = s->macroblocks_base + ((s->mb_width + 1) * (mb_y + 1) + 1);
+ else
+ mb = s->macroblocks + (s->mb_height - mb_y - 1) * 2;
+
+ if (mb_y == 0)
+ prev_td = td;
+ else
+ prev_td = &s->thread_data[(jobnr + num_jobs - 1) % num_jobs];
+ if (mb_y == s->mb_height - 1)
+ next_td = td;
+ else
+ next_td = &s->thread_data[(jobnr + 1) % num_jobs];
+
+ for (mb_x = 0; mb_x < s->mb_width; mb_x++, mb++) {
+ VP8FilterStrength *f = &td->filter_strength[mb_x];
+ if (prev_td != td)
+ check_thread_pos(td, prev_td,
+ (mb_x + 1) + (s->mb_width + 3), mb_y - 1);
+ if (next_td != td)
+ if (next_td != &s->thread_data[0])
+ check_thread_pos(td, next_td, mb_x + 1, mb_y + 1);
+
+ if (num_jobs == 1) {
+ if (s->filter.simple)
+ backup_mb_border(s->top_border[mb_x + 1], dst[0],
+ NULL, NULL, s->linesize, 0, 1);
+ else
+ backup_mb_border(s->top_border[mb_x + 1], dst[0],
+ dst[1], dst[2], s->linesize, s->uvlinesize, 0);
+ }
+
+ if (s->filter.simple)
+ filter_mb_simple(s, dst[0], f, mb_x, mb_y);
+ else
+ filter_mb(s, dst, f, mb_x, mb_y, is_vp7);
+ dst[0] += 16;
+ dst[1] += 8;
+ dst[2] += 8;
+
+ update_pos(td, mb_y, (s->mb_width + 3) + mb_x);
+ }
+}
+
+static void vp7_filter_mb_row(AVCodecContext *avctx, void *tdata,
+ int jobnr, int threadnr)
+{
+ filter_mb_row(avctx, tdata, jobnr, threadnr, 1);
+}
+
+static void vp8_filter_mb_row(AVCodecContext *avctx, void *tdata,
+ int jobnr, int threadnr)
+{
+ filter_mb_row(avctx, tdata, jobnr, threadnr, 0);
+}
+
+static av_always_inline
+int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr,
+ int threadnr, int is_vp7)
+{
+ VP8Context *s = avctx->priv_data;
+ VP8ThreadData *td = &s->thread_data[jobnr];
+ VP8ThreadData *next_td = NULL, *prev_td = NULL;
+ VP8Frame *curframe = s->curframe;
+ int mb_y, num_jobs = s->num_jobs;
+ int ret;
+
+ td->thread_nr = threadnr;
+ for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) {
+ td->thread_mb_pos = mb_y << 16;
+ ret = s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr);
+ if (ret < 0) {
+ update_pos(td, s->mb_height, INT_MAX & 0xFFFF);
+ return ret;
+ }
+ if (s->deblock_filter)
+ s->filter_mb_row(avctx, tdata, jobnr, threadnr);
+ update_pos(td, mb_y, INT_MAX & 0xFFFF);
+
+ s->mv_min.y -= 64;
+ s->mv_max.y -= 64;
+
+ if (avctx->active_thread_type == FF_THREAD_FRAME)
+ ff_thread_report_progress(&curframe->tf, mb_y, 0);
+ }
+
+ return 0;
+}
+
+static int vp7_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata,
+ int jobnr, int threadnr)
+{
+ return vp78_decode_mb_row_sliced(avctx, tdata, jobnr, threadnr, IS_VP7);
+}
+
+static int vp8_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata,
+ int jobnr, int threadnr)
+{
+ return vp78_decode_mb_row_sliced(avctx, tdata, jobnr, threadnr, IS_VP8);
+}
+
+
+static av_always_inline
+int vp78_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt, int is_vp7)
+{
+ VP8Context *s = avctx->priv_data;
+ int ret, i, referenced, num_jobs;
+ enum AVDiscard skip_thresh;
+ VP8Frame *av_uninit(curframe), *prev_frame;
+
+ av_assert0(avctx->pix_fmt == AV_PIX_FMT_YUVA420P || avctx->pix_fmt == AV_PIX_FMT_YUV420P);
+
+ if (is_vp7)
+ ret = vp7_decode_frame_header(s, avpkt->data, avpkt->size);
+ else
+ ret = vp8_decode_frame_header(s, avpkt->data, avpkt->size);
+
+ if (ret < 0)
+ goto err;
+
+ prev_frame = s->framep[VP56_FRAME_CURRENT];
+
+ referenced = s->update_last || s->update_golden == VP56_FRAME_CURRENT ||
+ s->update_altref == VP56_FRAME_CURRENT;
+
+ skip_thresh = !referenced ? AVDISCARD_NONREF
+ : !s->keyframe ? AVDISCARD_NONKEY
+ : AVDISCARD_ALL;
+
+ if (avctx->skip_frame >= skip_thresh) {
+ s->invisible = 1;
+ memcpy(&s->next_framep[0], &s->framep[0], sizeof(s->framep[0]) * 4);
+ goto skip_decode;
+ }
+ s->deblock_filter = s->filter.level && avctx->skip_loop_filter < skip_thresh;
+
+ // release no longer referenced frames
+ for (i = 0; i < 5; i++)
+ if (s->frames[i].tf.f->data[0] &&
+ &s->frames[i] != prev_frame &&
+ &s->frames[i] != s->framep[VP56_FRAME_PREVIOUS] &&
+ &s->frames[i] != s->framep[VP56_FRAME_GOLDEN] &&
+ &s->frames[i] != s->framep[VP56_FRAME_GOLDEN2])
+ vp8_release_frame(s, &s->frames[i]);
+
+ curframe = s->framep[VP56_FRAME_CURRENT] = vp8_find_free_buffer(s);
+
+ if (!s->colorspace)
+ avctx->colorspace = AVCOL_SPC_BT470BG;
+ if (s->fullrange)
+ avctx->color_range = AVCOL_RANGE_JPEG;
+ else
+ avctx->color_range = AVCOL_RANGE_MPEG;
+
+ /* Given that arithmetic probabilities are updated every frame, it's quite
+ * likely that the values we have on a random interframe are complete
+ * junk if we didn't start decode on a keyframe. So just don't display
+ * anything rather than junk. */
+ if (!s->keyframe && (!s->framep[VP56_FRAME_PREVIOUS] ||
+ !s->framep[VP56_FRAME_GOLDEN] ||
+ !s->framep[VP56_FRAME_GOLDEN2])) {
+ av_log(avctx, AV_LOG_WARNING,
+ "Discarding interframe without a prior keyframe!\n");
+ ret = AVERROR_INVALIDDATA;
+ goto err;
+ }
+
+ curframe->tf.f->key_frame = s->keyframe;
+ curframe->tf.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I
+ : AV_PICTURE_TYPE_P;
+ if ((ret = vp8_alloc_frame(s, curframe, referenced)) < 0)
+ goto err;
+
+ // check if golden and altref are swapped
+ if (s->update_altref != VP56_FRAME_NONE)
+ s->next_framep[VP56_FRAME_GOLDEN2] = s->framep[s->update_altref];
+ else
+ s->next_framep[VP56_FRAME_GOLDEN2] = s->framep[VP56_FRAME_GOLDEN2];
+
+ if (s->update_golden != VP56_FRAME_NONE)
+ s->next_framep[VP56_FRAME_GOLDEN] = s->framep[s->update_golden];
+ else
+ s->next_framep[VP56_FRAME_GOLDEN] = s->framep[VP56_FRAME_GOLDEN];
+
+ if (s->update_last)
+ s->next_framep[VP56_FRAME_PREVIOUS] = curframe;
+ else
+ s->next_framep[VP56_FRAME_PREVIOUS] = s->framep[VP56_FRAME_PREVIOUS];
+
+ s->next_framep[VP56_FRAME_CURRENT] = curframe;
+
+ if (avctx->codec->update_thread_context)
+ ff_thread_finish_setup(avctx);
+
+ s->linesize = curframe->tf.f->linesize[0];
+ s->uvlinesize = curframe->tf.f->linesize[1];
+
+ memset(s->top_nnz, 0, s->mb_width * sizeof(*s->top_nnz));
+ /* Zero macroblock structures for top/top-left prediction
+ * from outside the frame. */
+ if (!s->mb_layout)
+ memset(s->macroblocks + s->mb_height * 2 - 1, 0,
+ (s->mb_width + 1) * sizeof(*s->macroblocks));
+ if (!s->mb_layout && s->keyframe)
+ memset(s->intra4x4_pred_mode_top, DC_PRED, s->mb_width * 4);
+
+ memset(s->ref_count, 0, sizeof(s->ref_count));
+
+ if (s->mb_layout == 1) {
+ // Make sure the previous frame has read its segmentation map,
+ // if we re-use the same map.
+ if (prev_frame && s->segmentation.enabled &&
+ !s->segmentation.update_map)
+ ff_thread_await_progress(&prev_frame->tf, 1, 0);
+ if (is_vp7)
+ vp7_decode_mv_mb_modes(avctx, curframe, prev_frame);
+ else
+ vp8_decode_mv_mb_modes(avctx, curframe, prev_frame);
+ }
+
+ if (avctx->active_thread_type == FF_THREAD_FRAME)
+ num_jobs = 1;
+ else
+ num_jobs = FFMIN(s->num_coeff_partitions, avctx->thread_count);
+ s->num_jobs = num_jobs;
+ s->curframe = curframe;
+ s->prev_frame = prev_frame;
+ s->mv_min.y = -MARGIN;
+ s->mv_max.y = ((s->mb_height - 1) << 6) + MARGIN;
+ for (i = 0; i < MAX_THREADS; i++) {
+ s->thread_data[i].thread_mb_pos = 0;
+ s->thread_data[i].wait_mb_pos = INT_MAX;
+ }
+ if (is_vp7)
+ avctx->execute2(avctx, vp7_decode_mb_row_sliced, s->thread_data, NULL,
+ num_jobs);
+ else
+ avctx->execute2(avctx, vp8_decode_mb_row_sliced, s->thread_data, NULL,
+ num_jobs);
+
+ ff_thread_report_progress(&curframe->tf, INT_MAX, 0);
+ memcpy(&s->framep[0], &s->next_framep[0], sizeof(s->framep[0]) * 4);
+
+skip_decode:
+ // if future frames don't use the updated probabilities,
+ // reset them to the values we saved
+ if (!s->update_probabilities)
+ s->prob[0] = s->prob[1];
+
+ if (!s->invisible) {
+ if ((ret = av_frame_ref(data, curframe->tf.f)) < 0)
+ return ret;
+ *got_frame = 1;
+ }
+
+ return avpkt->size;
+err:
+ memcpy(&s->next_framep[0], &s->framep[0], sizeof(s->framep[0]) * 4);
+ return ret;
+}
+
+int ff_vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ return vp78_decode_frame(avctx, data, got_frame, avpkt, IS_VP8);
+}
+
+#if CONFIG_VP7_DECODER
+static int vp7_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ return vp78_decode_frame(avctx, data, got_frame, avpkt, IS_VP7);
+}
+#endif /* CONFIG_VP7_DECODER */
+
+av_cold int ff_vp8_decode_free(AVCodecContext *avctx)
+{
+ VP8Context *s = avctx->priv_data;
+ int i;
+
+ if (!s)
+ return 0;
+
+ vp8_decode_flush_impl(avctx, 1);
+ for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++)
+ av_frame_free(&s->frames[i].tf.f);
+
+ return 0;
+}
+
+static av_cold int vp8_init_frames(VP8Context *s)
+{
+ int i;
+ for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) {
+ s->frames[i].tf.f = av_frame_alloc();
+ if (!s->frames[i].tf.f)
+ return AVERROR(ENOMEM);
+ }
+ return 0;
+}
+
+static av_always_inline
+int vp78_decode_init(AVCodecContext *avctx, int is_vp7)
+{
+ VP8Context *s = avctx->priv_data;
+ int ret;
+
+ s->avctx = avctx;
+ s->vp7 = avctx->codec->id == AV_CODEC_ID_VP7;
+ avctx->pix_fmt = AV_PIX_FMT_YUV420P;
+ avctx->internal->allocate_progress = 1;
+
+ ff_videodsp_init(&s->vdsp, 8);
+
+ ff_vp78dsp_init(&s->vp8dsp);
+ if (CONFIG_VP7_DECODER && is_vp7) {
+ ff_h264_pred_init(&s->hpc, AV_CODEC_ID_VP7, 8, 1);
+ ff_vp7dsp_init(&s->vp8dsp);
+ s->decode_mb_row_no_filter = vp7_decode_mb_row_no_filter;
+ s->filter_mb_row = vp7_filter_mb_row;
+ } else if (CONFIG_VP8_DECODER && !is_vp7) {
+ ff_h264_pred_init(&s->hpc, AV_CODEC_ID_VP8, 8, 1);
+ ff_vp8dsp_init(&s->vp8dsp);
+ s->decode_mb_row_no_filter = vp8_decode_mb_row_no_filter;
+ s->filter_mb_row = vp8_filter_mb_row;
+ }
+
+ /* does not change for VP8 */
+ memcpy(s->prob[0].scan, zigzag_scan, sizeof(s->prob[0].scan));
+
+ if ((ret = vp8_init_frames(s)) < 0) {
+ ff_vp8_decode_free(avctx);
+ return ret;
+ }
+
+ return 0;
+}
+
+#if CONFIG_VP7_DECODER
+static int vp7_decode_init(AVCodecContext *avctx)
+{
+ return vp78_decode_init(avctx, IS_VP7);
+}
+#endif /* CONFIG_VP7_DECODER */
+
+av_cold int ff_vp8_decode_init(AVCodecContext *avctx)
+{
+ return vp78_decode_init(avctx, IS_VP8);
+}
+
+#if CONFIG_VP8_DECODER
+static av_cold int vp8_decode_init_thread_copy(AVCodecContext *avctx)
+{
+ VP8Context *s = avctx->priv_data;
+ int ret;
+
+ s->avctx = avctx;
+
+ if ((ret = vp8_init_frames(s)) < 0) {
+ ff_vp8_decode_free(avctx);
+ return ret;
+ }
+
+ return 0;
+}
+
+#define REBASE(pic) ((pic) ? (pic) - &s_src->frames[0] + &s->frames[0] : NULL)
+
+static int vp8_decode_update_thread_context(AVCodecContext *dst,
+ const AVCodecContext *src)
+{
+ VP8Context *s = dst->priv_data, *s_src = src->priv_data;
+ int i;
+
+ if (s->macroblocks_base &&
+ (s_src->mb_width != s->mb_width || s_src->mb_height != s->mb_height)) {
+ free_buffers(s);
+ s->mb_width = s_src->mb_width;
+ s->mb_height = s_src->mb_height;
+ }
+
+ s->prob[0] = s_src->prob[!s_src->update_probabilities];
+ s->segmentation = s_src->segmentation;
+ s->lf_delta = s_src->lf_delta;
+ memcpy(s->sign_bias, s_src->sign_bias, sizeof(s->sign_bias));
+
+ for (i = 0; i < FF_ARRAY_ELEMS(s_src->frames); i++) {
+ if (s_src->frames[i].tf.f->data[0]) {
+ int ret = vp8_ref_frame(s, &s->frames[i], &s_src->frames[i]);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ s->framep[0] = REBASE(s_src->next_framep[0]);
+ s->framep[1] = REBASE(s_src->next_framep[1]);
+ s->framep[2] = REBASE(s_src->next_framep[2]);
+ s->framep[3] = REBASE(s_src->next_framep[3]);
+
+ return 0;
+}
+#endif /* CONFIG_VP8_DECODER */
+
+#if CONFIG_VP7_DECODER
+AVCodec ff_vp7_decoder = {
+ .name = "vp7",
+ .long_name = NULL_IF_CONFIG_SMALL("On2 VP7"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_VP7,
+ .priv_data_size = sizeof(VP8Context),
+ .init = vp7_decode_init,
+ .close = ff_vp8_decode_free,
+ .decode = vp7_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+ .flush = vp8_decode_flush,
+};
+#endif /* CONFIG_VP7_DECODER */
+
+#if CONFIG_VP8_DECODER
+AVCodec ff_vp8_decoder = {
+ .name = "vp8",
+ .long_name = NULL_IF_CONFIG_SMALL("On2 VP8"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_VP8,
+ .priv_data_size = sizeof(VP8Context),
+ .init = ff_vp8_decode_init,
+ .close = ff_vp8_decode_free,
+ .decode = ff_vp8_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS |
+ AV_CODEC_CAP_SLICE_THREADS,
+ .flush = vp8_decode_flush,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_context),
+};
+#endif /* CONFIG_VP7_DECODER */
diff --git a/ffmpeg-2-8-12/libavcodec/vp8.h b/ffmpeg-2-8-12/libavcodec/vp8.h
new file mode 100644
index 0000000..6be0a55
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/vp8.h
@@ -0,0 +1,318 @@
+/*
+ * VP8 compatible video decoder
+ *
+ * Copyright (C) 2010 David Conrad
+ * Copyright (C) 2010 Ronald S. Bultje
+ * Copyright (C) 2010 Fiona Glaser
+ * Copyright (C) 2012 Daniel Kang
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef AVCODEC_VP8_H
+#define AVCODEC_VP8_H
+
+#include "libavutil/buffer.h"
+
+#include "h264pred.h"
+#include "thread.h"
+#include "vp56.h"
+#include "vp8dsp.h"
+
+#if HAVE_PTHREADS
+# include <pthread.h>
+#elif HAVE_OS2THREADS
+# include "compat/os2threads.h"
+#elif HAVE_W32THREADS
+# include "compat/w32pthreads.h"
+#endif
+
+#define VP8_MAX_QUANT 127
+
+enum dct_token {
+ DCT_0,
+ DCT_1,
+ DCT_2,
+ DCT_3,
+ DCT_4,
+ DCT_CAT1,
+ DCT_CAT2,
+ DCT_CAT3,
+ DCT_CAT4,
+ DCT_CAT5,
+ DCT_CAT6,
+ DCT_EOB,
+
+ NUM_DCT_TOKENS
+};
+
+// used to signal 4x4 intra pred in luma MBs
+#define MODE_I4x4 4
+
+enum inter_mvmode {
+ VP8_MVMODE_ZERO = MODE_I4x4 + 1,
+ VP8_MVMODE_MV,
+ VP8_MVMODE_SPLIT
+};
+
+enum inter_splitmvmode {
+ VP8_SPLITMVMODE_16x8 = 0, ///< 2 16x8 blocks (vertical)
+ VP8_SPLITMVMODE_8x16, ///< 2 8x16 blocks (horizontal)
+ VP8_SPLITMVMODE_8x8, ///< 2x2 blocks of 8x8px each
+ VP8_SPLITMVMODE_4x4, ///< 4x4 blocks of 4x4px each
+ VP8_SPLITMVMODE_NONE, ///< (only used in prediction) no split MVs
+};
+
+typedef struct VP8FilterStrength {
+ uint8_t filter_level;
+ uint8_t inner_limit;
+ uint8_t inner_filter;
+} VP8FilterStrength;
+
+typedef struct VP8Macroblock {
+ uint8_t skip;
+ // TODO: make it possible to check for at least (i4x4 or split_mv)
+ // in one op. are others needed?
+ uint8_t mode;
+ uint8_t ref_frame;
+ uint8_t partitioning;
+ uint8_t chroma_pred_mode;
+ uint8_t segment;
+ uint8_t intra4x4_pred_mode_mb[16];
+ DECLARE_ALIGNED(4, uint8_t, intra4x4_pred_mode_top)[4];
+ VP56mv mv;
+ VP56mv bmv[16];
+} VP8Macroblock;
+
+typedef struct VP8ThreadData {
+ DECLARE_ALIGNED(16, int16_t, block)[6][4][16];
+ DECLARE_ALIGNED(16, int16_t, block_dc)[16];
+ /**
+ * This is the index plus one of the last non-zero coeff
+ * for each of the blocks in the current macroblock.
+ * So, 0 -> no coeffs
+ * 1 -> dc-only (special transform)
+ * 2+-> full transform
+ */
+ DECLARE_ALIGNED(16, uint8_t, non_zero_count_cache)[6][4];
+ /**
+ * For coeff decode, we need to know whether the above block had non-zero
+ * coefficients. This means for each macroblock, we need data for 4 luma
+ * blocks, 2 u blocks, 2 v blocks, and the luma dc block, for a total of 9
+ * per macroblock. We keep the last row in top_nnz.
+ */
+ DECLARE_ALIGNED(8, uint8_t, left_nnz)[9];
+ int thread_nr;
+#if HAVE_THREADS
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+#endif
+ int thread_mb_pos; // (mb_y << 16) | (mb_x & 0xFFFF)
+ int wait_mb_pos; // What the current thread is waiting on.
+
+#define EDGE_EMU_LINESIZE 32
+ DECLARE_ALIGNED(16, uint8_t, edge_emu_buffer)[21 * EDGE_EMU_LINESIZE];
+ VP8FilterStrength *filter_strength;
+} VP8ThreadData;
+
+typedef struct VP8Frame {
+ ThreadFrame tf;
+ AVBufferRef *seg_map;
+} VP8Frame;
+
+typedef struct VP8intmv {
+ int x;
+ int y;
+} VP8intmv;
+
+#define MAX_THREADS 8
+typedef struct VP8Context {
+ VP8ThreadData *thread_data;
+ AVCodecContext *avctx;
+ VP8Frame *framep[4];
+ VP8Frame *next_framep[4];
+ VP8Frame *curframe;
+ VP8Frame *prev_frame;
+
+ uint16_t mb_width; /* number of horizontal MB */
+ uint16_t mb_height; /* number of vertical MB */
+ int linesize;
+ int uvlinesize;
+
+ uint8_t keyframe;
+ uint8_t deblock_filter;
+ uint8_t mbskip_enabled;
+ uint8_t profile;
+ VP8intmv mv_min;
+ VP8intmv mv_max;
+
+ int8_t sign_bias[4]; ///< one state [0, 1] per ref frame type
+ int ref_count[3];
+
+ /**
+ * Base parameters for segmentation, i.e. per-macroblock parameters.
+ * These must be kept unchanged even if segmentation is not used for
+ * a frame, since the values persist between interframes.
+ */
+ struct {
+ uint8_t enabled;
+ uint8_t absolute_vals;
+ uint8_t update_map;
+ int8_t base_quant[4];
+ int8_t filter_level[4]; ///< base loop filter level
+ } segmentation;
+
+ struct {
+ uint8_t simple;
+ uint8_t level;
+ uint8_t sharpness;
+ } filter;
+
+ VP8Macroblock *macroblocks;
+
+ uint8_t *intra4x4_pred_mode_top;
+ uint8_t intra4x4_pred_mode_left[4];
+
+ /**
+ * Macroblocks can have one of 4 different quants in a frame when
+ * segmentation is enabled.
+ * If segmentation is disabled, only the first segment's values are used.
+ */
+ struct {
+ // [0] - DC qmul [1] - AC qmul
+ int16_t luma_qmul[2];
+ int16_t luma_dc_qmul[2]; ///< luma dc-only block quant
+ int16_t chroma_qmul[2];
+ } qmat[4];
+
+ struct {
+ uint8_t enabled; ///< whether each mb can have a different strength based on mode/ref
+
+ /**
+ * filter strength adjustment for the following macroblock modes:
+ * [0-3] - i16x16 (always zero)
+ * [4] - i4x4
+ * [5] - zero mv
+ * [6] - inter modes except for zero or split mv
+ * [7] - split mv
+ * i16x16 modes never have any adjustment
+ */
+ int8_t mode[VP8_MVMODE_SPLIT + 1];
+
+ /**
+ * filter strength adjustment for macroblocks that reference:
+ * [0] - intra / VP56_FRAME_CURRENT
+ * [1] - VP56_FRAME_PREVIOUS
+ * [2] - VP56_FRAME_GOLDEN
+ * [3] - altref / VP56_FRAME_GOLDEN2
+ */
+ int8_t ref[4];
+ } lf_delta;
+
+ uint8_t (*top_border)[16 + 8 + 8];
+ uint8_t (*top_nnz)[9];
+
+ VP56RangeCoder c; ///< header context, includes mb modes and motion vectors
+
+ /**
+ * These are all of the updatable probabilities for binary decisions.
+ * They are only implictly reset on keyframes, making it quite likely
+ * for an interframe to desync if a prior frame's header was corrupt
+ * or missing outright!
+ */
+ struct {
+ uint8_t segmentid[3];
+ uint8_t mbskip;
+ uint8_t intra;
+ uint8_t last;
+ uint8_t golden;
+ uint8_t pred16x16[4];
+ uint8_t pred8x8c[3];
+ uint8_t token[4][16][3][NUM_DCT_TOKENS - 1];
+ uint8_t mvc[2][19];
+ uint8_t scan[16];
+ } prob[2];
+
+ VP8Macroblock *macroblocks_base;
+ int invisible;
+ int update_last; ///< update VP56_FRAME_PREVIOUS with the current one
+ int update_golden; ///< VP56_FRAME_NONE if not updated, or which frame to copy if so
+ int update_altref;
+
+ /**
+ * If this flag is not set, all the probability updates
+ * are discarded after this frame is decoded.
+ */
+ int update_probabilities;
+
+ /**
+ * All coefficients are contained in separate arith coding contexts.
+ * There can be 1, 2, 4, or 8 of these after the header context.
+ */
+ int num_coeff_partitions;
+ VP56RangeCoder coeff_partition[8];
+ VideoDSPContext vdsp;
+ VP8DSPContext vp8dsp;
+ H264PredContext hpc;
+ vp8_mc_func put_pixels_tab[3][3][3];
+ VP8Frame frames[5];
+
+ uint8_t colorspace; ///< 0 is the only value allowed (meaning bt601)
+ uint8_t fullrange; ///< whether we can skip clamping in dsp functions
+
+ int num_jobs;
+ /**
+ * This describes the macroblock memory layout.
+ * 0 -> Only width+height*2+1 macroblocks allocated (frame/single thread).
+ * 1 -> Macroblocks for entire frame alloced (sliced thread).
+ */
+ int mb_layout;
+
+ int (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr);
+ void (*filter_mb_row)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr);
+
+ int vp7;
+
+ /**
+ * Fade bit present in bitstream (VP7)
+ */
+ int fade_present;
+
+ /**
+ * Interframe DC prediction (VP7)
+ * [0] VP56_FRAME_PREVIOUS
+ * [1] VP56_FRAME_GOLDEN
+ */
+ uint16_t inter_dc_pred[2][2];
+
+ /**
+ * Macroblock features (VP7)
+ */
+ uint8_t feature_enabled[4];
+ uint8_t feature_present_prob[4];
+ uint8_t feature_index_prob[4][3];
+ uint8_t feature_value[4][4];
+} VP8Context;
+
+int ff_vp8_decode_init(AVCodecContext *avctx);
+
+int ff_vp8_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt);
+
+int ff_vp8_decode_free(AVCodecContext *avctx);
+
+#endif /* AVCODEC_VP8_H */
diff --git a/ffmpeg-2-8-11/libavcodec/vp8_parser.c b/ffmpeg-2-8-12/libavcodec/vp8_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp8_parser.c
rename to ffmpeg-2-8-12/libavcodec/vp8_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/vp8data.h b/ffmpeg-2-8-12/libavcodec/vp8data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp8data.h
rename to ffmpeg-2-8-12/libavcodec/vp8data.h
diff --git a/ffmpeg-2-8-12/libavcodec/vp8dsp.c b/ffmpeg-2-8-12/libavcodec/vp8dsp.c
new file mode 100644
index 0000000..fed5c67
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/vp8dsp.c
@@ -0,0 +1,743 @@
+/*
+ * Copyright (C) 2010 David Conrad
+ * Copyright (C) 2010 Ronald S. Bultje
+ * Copyright (C) 2014 Peter Ross
+ *
+ * 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
+ * VP8 compatible video decoder
+ */
+
+#include "libavutil/common.h"
+#include "libavutil/intreadwrite.h"
+
+#include "mathops.h"
+#include "vp8dsp.h"
+
+#define MK_IDCT_DC_ADD4_C(name) \
+static void name ## _idct_dc_add4uv_c(uint8_t *dst, int16_t block[4][16], \
+ ptrdiff_t stride) \
+{ \
+ name ## _idct_dc_add_c(dst + stride * 0 + 0, block[0], stride); \
+ name ## _idct_dc_add_c(dst + stride * 0 + 4, block[1], stride); \
+ name ## _idct_dc_add_c(dst + stride * 4 + 0, block[2], stride); \
+ name ## _idct_dc_add_c(dst + stride * 4 + 4, block[3], stride); \
+} \
+ \
+static void name ## _idct_dc_add4y_c(uint8_t *dst, int16_t block[4][16], \
+ ptrdiff_t stride) \
+{ \
+ name ## _idct_dc_add_c(dst + 0, block[0], stride); \
+ name ## _idct_dc_add_c(dst + 4, block[1], stride); \
+ name ## _idct_dc_add_c(dst + 8, block[2], stride); \
+ name ## _idct_dc_add_c(dst + 12, block[3], stride); \
+}
+
+#if CONFIG_VP7_DECODER
+static void vp7_luma_dc_wht_c(int16_t block[4][4][16], int16_t dc[16])
+{
+ int i;
+ unsigned a1, b1, c1, d1;
+ int16_t tmp[16];
+
+ for (i = 0; i < 4; i++) {
+ a1 = (dc[i * 4 + 0] + dc[i * 4 + 2]) * 23170;
+ b1 = (dc[i * 4 + 0] - dc[i * 4 + 2]) * 23170;
+ c1 = dc[i * 4 + 1] * 12540 - dc[i * 4 + 3] * 30274;
+ d1 = dc[i * 4 + 1] * 30274 + dc[i * 4 + 3] * 12540;
+ tmp[i * 4 + 0] = (int)(a1 + d1) >> 14;
+ tmp[i * 4 + 3] = (int)(a1 - d1) >> 14;
+ tmp[i * 4 + 1] = (int)(b1 + c1) >> 14;
+ tmp[i * 4 + 2] = (int)(b1 - c1) >> 14;
+ }
+
+ for (i = 0; i < 4; i++) {
+ a1 = (tmp[i + 0] + tmp[i + 8]) * 23170;
+ b1 = (tmp[i + 0] - tmp[i + 8]) * 23170;
+ c1 = tmp[i + 4] * 12540 - tmp[i + 12] * 30274;
+ d1 = tmp[i + 4] * 30274 + tmp[i + 12] * 12540;
+ AV_ZERO64(dc + i * 4);
+ block[0][i][0] = (int)(a1 + d1 + 0x20000) >> 18;
+ block[3][i][0] = (int)(a1 - d1 + 0x20000) >> 18;
+ block[1][i][0] = (int)(b1 + c1 + 0x20000) >> 18;
+ block[2][i][0] = (int)(b1 - c1 + 0x20000) >> 18;
+ }
+}
+
+static void vp7_luma_dc_wht_dc_c(int16_t block[4][4][16], int16_t dc[16])
+{
+ int i, val = (23170 * (23170 * dc[0] >> 14) + 0x20000) >> 18;
+ dc[0] = 0;
+
+ for (i = 0; i < 4; i++) {
+ block[i][0][0] = val;
+ block[i][1][0] = val;
+ block[i][2][0] = val;
+ block[i][3][0] = val;
+ }
+}
+
+static void vp7_idct_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
+{
+ int i;
+ unsigned a1, b1, c1, d1;
+ int16_t tmp[16];
+
+ for (i = 0; i < 4; i++) {
+ a1 = (block[i * 4 + 0] + block[i * 4 + 2]) * 23170;
+ b1 = (block[i * 4 + 0] - block[i * 4 + 2]) * 23170;
+ c1 = block[i * 4 + 1] * 12540 - block[i * 4 + 3] * 30274;
+ d1 = block[i * 4 + 1] * 30274 + block[i * 4 + 3] * 12540;
+ AV_ZERO64(block + i * 4);
+ tmp[i * 4 + 0] = (int)(a1 + d1) >> 14;
+ tmp[i * 4 + 3] = (int)(a1 - d1) >> 14;
+ tmp[i * 4 + 1] = (int)(b1 + c1) >> 14;
+ tmp[i * 4 + 2] = (int)(b1 - c1) >> 14;
+ }
+
+ for (i = 0; i < 4; i++) {
+ a1 = (tmp[i + 0] + tmp[i + 8]) * 23170;
+ b1 = (tmp[i + 0] - tmp[i + 8]) * 23170;
+ c1 = tmp[i + 4] * 12540 - tmp[i + 12] * 30274;
+ d1 = tmp[i + 4] * 30274 + tmp[i + 12] * 12540;
+ dst[0 * stride + i] = av_clip_uint8(dst[0 * stride + i] +
+ ((int)(a1 + d1 + 0x20000) >> 18));
+ dst[3 * stride + i] = av_clip_uint8(dst[3 * stride + i] +
+ ((int)(a1 - d1 + 0x20000) >> 18));
+ dst[1 * stride + i] = av_clip_uint8(dst[1 * stride + i] +
+ ((int)(b1 + c1 + 0x20000) >> 18));
+ dst[2 * stride + i] = av_clip_uint8(dst[2 * stride + i] +
+ ((int)(b1 - c1 + 0x20000) >> 18));
+ }
+}
+
+static void vp7_idct_dc_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
+{
+ int i, dc = (23170 * (23170 * block[0] >> 14) + 0x20000) >> 18;
+ block[0] = 0;
+
+ for (i = 0; i < 4; i++) {
+ dst[0] = av_clip_uint8(dst[0] + dc);
+ dst[1] = av_clip_uint8(dst[1] + dc);
+ dst[2] = av_clip_uint8(dst[2] + dc);
+ dst[3] = av_clip_uint8(dst[3] + dc);
+ dst += stride;
+ }
+}
+
+MK_IDCT_DC_ADD4_C(vp7)
+#endif /* CONFIG_VP7_DECODER */
+
+// TODO: Maybe add dequant
+#if CONFIG_VP8_DECODER
+static void vp8_luma_dc_wht_c(int16_t block[4][4][16], int16_t dc[16])
+{
+ int i, t0, t1, t2, t3;
+
+ for (i = 0; i < 4; i++) {
+ t0 = dc[0 * 4 + i] + dc[3 * 4 + i];
+ t1 = dc[1 * 4 + i] + dc[2 * 4 + i];
+ t2 = dc[1 * 4 + i] - dc[2 * 4 + i];
+ t3 = dc[0 * 4 + i] - dc[3 * 4 + i];
+
+ dc[0 * 4 + i] = t0 + t1;
+ dc[1 * 4 + i] = t3 + t2;
+ dc[2 * 4 + i] = t0 - t1;
+ dc[3 * 4 + i] = t3 - t2;
+ }
+
+ for (i = 0; i < 4; i++) {
+ t0 = dc[i * 4 + 0] + dc[i * 4 + 3] + 3; // rounding
+ t1 = dc[i * 4 + 1] + dc[i * 4 + 2];
+ t2 = dc[i * 4 + 1] - dc[i * 4 + 2];
+ t3 = dc[i * 4 + 0] - dc[i * 4 + 3] + 3; // rounding
+ AV_ZERO64(dc + i * 4);
+
+ block[i][0][0] = (t0 + t1) >> 3;
+ block[i][1][0] = (t3 + t2) >> 3;
+ block[i][2][0] = (t0 - t1) >> 3;
+ block[i][3][0] = (t3 - t2) >> 3;
+ }
+}
+
+static void vp8_luma_dc_wht_dc_c(int16_t block[4][4][16], int16_t dc[16])
+{
+ int i, val = (dc[0] + 3) >> 3;
+ dc[0] = 0;
+
+ for (i = 0; i < 4; i++) {
+ block[i][0][0] = val;
+ block[i][1][0] = val;
+ block[i][2][0] = val;
+ block[i][3][0] = val;
+ }
+}
+
+#define MUL_20091(a) ((((a) * 20091) >> 16) + (a))
+#define MUL_35468(a) (((a) * 35468) >> 16)
+
+static void vp8_idct_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
+{
+ int i, t0, t1, t2, t3;
+ int16_t tmp[16];
+
+ for (i = 0; i < 4; i++) {
+ t0 = block[0 * 4 + i] + block[2 * 4 + i];
+ t1 = block[0 * 4 + i] - block[2 * 4 + i];
+ t2 = MUL_35468(block[1 * 4 + i]) - MUL_20091(block[3 * 4 + i]);
+ t3 = MUL_20091(block[1 * 4 + i]) + MUL_35468(block[3 * 4 + i]);
+ block[0 * 4 + i] = 0;
+ block[1 * 4 + i] = 0;
+ block[2 * 4 + i] = 0;
+ block[3 * 4 + i] = 0;
+
+ tmp[i * 4 + 0] = t0 + t3;
+ tmp[i * 4 + 1] = t1 + t2;
+ tmp[i * 4 + 2] = t1 - t2;
+ tmp[i * 4 + 3] = t0 - t3;
+ }
+
+ for (i = 0; i < 4; i++) {
+ t0 = tmp[0 * 4 + i] + tmp[2 * 4 + i];
+ t1 = tmp[0 * 4 + i] - tmp[2 * 4 + i];
+ t2 = MUL_35468(tmp[1 * 4 + i]) - MUL_20091(tmp[3 * 4 + i]);
+ t3 = MUL_20091(tmp[1 * 4 + i]) + MUL_35468(tmp[3 * 4 + i]);
+
+ dst[0] = av_clip_uint8(dst[0] + ((t0 + t3 + 4) >> 3));
+ dst[1] = av_clip_uint8(dst[1] + ((t1 + t2 + 4) >> 3));
+ dst[2] = av_clip_uint8(dst[2] + ((t1 - t2 + 4) >> 3));
+ dst[3] = av_clip_uint8(dst[3] + ((t0 - t3 + 4) >> 3));
+ dst += stride;
+ }
+}
+
+static void vp8_idct_dc_add_c(uint8_t *dst, int16_t block[16], ptrdiff_t stride)
+{
+ int i, dc = (block[0] + 4) >> 3;
+ block[0] = 0;
+
+ for (i = 0; i < 4; i++) {
+ dst[0] = av_clip_uint8(dst[0] + dc);
+ dst[1] = av_clip_uint8(dst[1] + dc);
+ dst[2] = av_clip_uint8(dst[2] + dc);
+ dst[3] = av_clip_uint8(dst[3] + dc);
+ dst += stride;
+ }
+}
+
+MK_IDCT_DC_ADD4_C(vp8)
+#endif /* CONFIG_VP8_DECODER */
+
+// because I like only having two parameters to pass functions...
+#define LOAD_PIXELS \
+ int av_unused p3 = p[-4 * stride]; \
+ int av_unused p2 = p[-3 * stride]; \
+ int av_unused p1 = p[-2 * stride]; \
+ int av_unused p0 = p[-1 * stride]; \
+ int av_unused q0 = p[ 0 * stride]; \
+ int av_unused q1 = p[ 1 * stride]; \
+ int av_unused q2 = p[ 2 * stride]; \
+ int av_unused q3 = p[ 3 * stride];
+
+#define clip_int8(n) (cm[(n) + 0x80] - 0x80)
+
+static av_always_inline void filter_common(uint8_t *p, ptrdiff_t stride,
+ int is4tap, int is_vp7)
+{
+ LOAD_PIXELS
+ int a, f1, f2;
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+
+ a = 3 * (q0 - p0);
+
+ if (is4tap)
+ a += clip_int8(p1 - q1);
+
+ a = clip_int8(a);
+
+ // We deviate from the spec here with c(a+3) >> 3
+ // since that's what libvpx does.
+ f1 = FFMIN(a + 4, 127) >> 3;
+
+ if (is_vp7)
+ f2 = f1 - ((a & 7) == 4);
+ else
+ f2 = FFMIN(a + 3, 127) >> 3;
+
+ // Despite what the spec says, we do need to clamp here to
+ // be bitexact with libvpx.
+ p[-1 * stride] = cm[p0 + f2];
+ p[ 0 * stride] = cm[q0 - f1];
+
+ // only used for _inner on blocks without high edge variance
+ if (!is4tap) {
+ a = (f1 + 1) >> 1;
+ p[-2 * stride] = cm[p1 + a];
+ p[ 1 * stride] = cm[q1 - a];
+ }
+}
+
+static av_always_inline void vp7_filter_common(uint8_t *p, ptrdiff_t stride,
+ int is4tap)
+{
+ filter_common(p, stride, is4tap, IS_VP7);
+}
+
+static av_always_inline void vp8_filter_common(uint8_t *p, ptrdiff_t stride,
+ int is4tap)
+{
+ filter_common(p, stride, is4tap, IS_VP8);
+}
+
+static av_always_inline int vp7_simple_limit(uint8_t *p, ptrdiff_t stride,
+ int flim)
+{
+ LOAD_PIXELS
+ return FFABS(p0 - q0) <= flim;
+}
+
+static av_always_inline int vp8_simple_limit(uint8_t *p, ptrdiff_t stride,
+ int flim)
+{
+ LOAD_PIXELS
+ return 2 * FFABS(p0 - q0) + (FFABS(p1 - q1) >> 1) <= flim;
+}
+
+/**
+ * E - limit at the macroblock edge
+ * I - limit for interior difference
+ */
+#define NORMAL_LIMIT(vpn) \
+static av_always_inline int vp ## vpn ## _normal_limit(uint8_t *p, \
+ ptrdiff_t stride, \
+ int E, int I) \
+{ \
+ LOAD_PIXELS \
+ return vp ## vpn ## _simple_limit(p, stride, E) && \
+ FFABS(p3 - p2) <= I && FFABS(p2 - p1) <= I && \
+ FFABS(p1 - p0) <= I && FFABS(q3 - q2) <= I && \
+ FFABS(q2 - q1) <= I && FFABS(q1 - q0) <= I; \
+}
+
+NORMAL_LIMIT(7)
+NORMAL_LIMIT(8)
+
+// high edge variance
+static av_always_inline int hev(uint8_t *p, ptrdiff_t stride, int thresh)
+{
+ LOAD_PIXELS
+ return FFABS(p1 - p0) > thresh || FFABS(q1 - q0) > thresh;
+}
+
+static av_always_inline void filter_mbedge(uint8_t *p, ptrdiff_t stride)
+{
+ int a0, a1, a2, w;
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+
+ LOAD_PIXELS
+
+ w = clip_int8(p1 - q1);
+ w = clip_int8(w + 3 * (q0 - p0));
+
+ a0 = (27 * w + 63) >> 7;
+ a1 = (18 * w + 63) >> 7;
+ a2 = (9 * w + 63) >> 7;
+
+ p[-3 * stride] = cm[p2 + a2];
+ p[-2 * stride] = cm[p1 + a1];
+ p[-1 * stride] = cm[p0 + a0];
+ p[ 0 * stride] = cm[q0 - a0];
+ p[ 1 * stride] = cm[q1 - a1];
+ p[ 2 * stride] = cm[q2 - a2];
+}
+
+#define LOOP_FILTER(vpn, dir, size, stridea, strideb, maybe_inline) \
+static maybe_inline \
+void vpn ## _ ## dir ## _loop_filter ## size ## _c(uint8_t *dst, \
+ ptrdiff_t stride, \
+ int flim_E, int flim_I, \
+ int hev_thresh) \
+{ \
+ int i; \
+ for (i = 0; i < size; i++) \
+ if (vpn ## _normal_limit(dst + i * stridea, strideb, \
+ flim_E, flim_I)) { \
+ if (hev(dst + i * stridea, strideb, hev_thresh)) \
+ vpn ## _filter_common(dst + i * stridea, strideb, 1); \
+ else \
+ filter_mbedge(dst + i * stridea, strideb); \
+ } \
+} \
+ \
+static maybe_inline \
+void vpn ## _ ## dir ## _loop_filter ## size ## _inner_c(uint8_t *dst, \
+ ptrdiff_t stride, \
+ int flim_E, \
+ int flim_I, \
+ int hev_thresh) \
+{ \
+ int i; \
+ for (i = 0; i < size; i++) \
+ if (vpn ## _normal_limit(dst + i * stridea, strideb, \
+ flim_E, flim_I)) { \
+ int hv = hev(dst + i * stridea, strideb, hev_thresh); \
+ if (hv) \
+ vpn ## _filter_common(dst + i * stridea, strideb, 1); \
+ else \
+ vpn ## _filter_common(dst + i * stridea, strideb, 0); \
+ } \
+}
+
+#define UV_LOOP_FILTER(vpn, dir, stridea, strideb) \
+LOOP_FILTER(vpn, dir, 8, stridea, strideb, av_always_inline) \
+static void vpn ## _ ## dir ## _loop_filter8uv_c(uint8_t *dstU, \
+ uint8_t *dstV, \
+ ptrdiff_t stride, int fE, \
+ int fI, int hev_thresh) \
+{ \
+ vpn ## _ ## dir ## _loop_filter8_c(dstU, stride, fE, fI, hev_thresh); \
+ vpn ## _ ## dir ## _loop_filter8_c(dstV, stride, fE, fI, hev_thresh); \
+} \
+ \
+static void vpn ## _ ## dir ## _loop_filter8uv_inner_c(uint8_t *dstU, \
+ uint8_t *dstV, \
+ ptrdiff_t stride, \
+ int fE, int fI, \
+ int hev_thresh) \
+{ \
+ vpn ## _ ## dir ## _loop_filter8_inner_c(dstU, stride, fE, fI, \
+ hev_thresh); \
+ vpn ## _ ## dir ## _loop_filter8_inner_c(dstV, stride, fE, fI, \
+ hev_thresh); \
+}
+
+#define LOOP_FILTER_SIMPLE(vpn) \
+static void vpn ## _v_loop_filter_simple_c(uint8_t *dst, ptrdiff_t stride, \
+ int flim) \
+{ \
+ int i; \
+ for (i = 0; i < 16; i++) \
+ if (vpn ## _simple_limit(dst + i, stride, flim)) \
+ vpn ## _filter_common(dst + i, stride, 1); \
+} \
+ \
+static void vpn ## _h_loop_filter_simple_c(uint8_t *dst, ptrdiff_t stride, \
+ int flim) \
+{ \
+ int i; \
+ for (i = 0; i < 16; i++) \
+ if (vpn ## _simple_limit(dst + i * stride, 1, flim)) \
+ vpn ## _filter_common(dst + i * stride, 1, 1); \
+}
+
+#define LOOP_FILTERS(vpn) \
+ LOOP_FILTER(vpn, v, 16, 1, stride, ) \
+ LOOP_FILTER(vpn, h, 16, stride, 1, ) \
+ UV_LOOP_FILTER(vpn, v, 1, stride) \
+ UV_LOOP_FILTER(vpn, h, stride, 1) \
+ LOOP_FILTER_SIMPLE(vpn) \
+
+static const uint8_t subpel_filters[7][6] = {
+ { 0, 6, 123, 12, 1, 0 },
+ { 2, 11, 108, 36, 8, 1 },
+ { 0, 9, 93, 50, 6, 0 },
+ { 3, 16, 77, 77, 16, 3 },
+ { 0, 6, 50, 93, 9, 0 },
+ { 1, 8, 36, 108, 11, 2 },
+ { 0, 1, 12, 123, 6, 0 },
+};
+
+#define PUT_PIXELS(WIDTH) \
+static void put_vp8_pixels ## WIDTH ## _c(uint8_t *dst, ptrdiff_t dststride, \
+ uint8_t *src, ptrdiff_t srcstride, \
+ int h, int x, int y) \
+{ \
+ int i; \
+ for (i = 0; i < h; i++, dst += dststride, src += srcstride) \
+ memcpy(dst, src, WIDTH); \
+}
+
+PUT_PIXELS(16)
+PUT_PIXELS(8)
+PUT_PIXELS(4)
+
+#define FILTER_6TAP(src, F, stride) \
+ cm[(F[2] * src[x + 0 * stride] - F[1] * src[x - 1 * stride] + \
+ F[0] * src[x - 2 * stride] + F[3] * src[x + 1 * stride] - \
+ F[4] * src[x + 2 * stride] + F[5] * src[x + 3 * stride] + 64) >> 7]
+
+#define FILTER_4TAP(src, F, stride) \
+ cm[(F[2] * src[x + 0 * stride] - F[1] * src[x - 1 * stride] + \
+ F[3] * src[x + 1 * stride] - F[4] * src[x + 2 * stride] + 64) >> 7]
+
+#define VP8_EPEL_H(SIZE, TAPS) \
+static void put_vp8_epel ## SIZE ## _h ## TAPS ## _c(uint8_t *dst, \
+ ptrdiff_t dststride, \
+ uint8_t *src, \
+ ptrdiff_t srcstride, \
+ int h, int mx, int my) \
+{ \
+ const uint8_t *filter = subpel_filters[mx - 1]; \
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; \
+ int x, y; \
+ for (y = 0; y < h; y++) { \
+ for (x = 0; x < SIZE; x++) \
+ dst[x] = FILTER_ ## TAPS ## TAP(src, filter, 1); \
+ dst += dststride; \
+ src += srcstride; \
+ } \
+}
+
+#define VP8_EPEL_V(SIZE, TAPS) \
+static void put_vp8_epel ## SIZE ## _v ## TAPS ## _c(uint8_t *dst, \
+ ptrdiff_t dststride, \
+ uint8_t *src, \
+ ptrdiff_t srcstride, \
+ int h, int mx, int my) \
+{ \
+ const uint8_t *filter = subpel_filters[my - 1]; \
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; \
+ int x, y; \
+ for (y = 0; y < h; y++) { \
+ for (x = 0; x < SIZE; x++) \
+ dst[x] = FILTER_ ## TAPS ## TAP(src, filter, srcstride); \
+ dst += dststride; \
+ src += srcstride; \
+ } \
+}
+
+#define VP8_EPEL_HV(SIZE, HTAPS, VTAPS) \
+static void \
+put_vp8_epel ## SIZE ## _h ## HTAPS ## v ## VTAPS ## _c(uint8_t *dst, \
+ ptrdiff_t dststride, \
+ uint8_t *src, \
+ ptrdiff_t srcstride, \
+ int h, int mx, \
+ int my) \
+{ \
+ const uint8_t *filter = subpel_filters[mx - 1]; \
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; \
+ int x, y; \
+ uint8_t tmp_array[(2 * SIZE + VTAPS - 1) * SIZE]; \
+ uint8_t *tmp = tmp_array; \
+ src -= (2 - (VTAPS == 4)) * srcstride; \
+ \
+ for (y = 0; y < h + VTAPS - 1; y++) { \
+ for (x = 0; x < SIZE; x++) \
+ tmp[x] = FILTER_ ## HTAPS ## TAP(src, filter, 1); \
+ tmp += SIZE; \
+ src += srcstride; \
+ } \
+ tmp = tmp_array + (2 - (VTAPS == 4)) * SIZE; \
+ filter = subpel_filters[my - 1]; \
+ \
+ for (y = 0; y < h; y++) { \
+ for (x = 0; x < SIZE; x++) \
+ dst[x] = FILTER_ ## VTAPS ## TAP(tmp, filter, SIZE); \
+ dst += dststride; \
+ tmp += SIZE; \
+ } \
+}
+
+VP8_EPEL_H(16, 4)
+VP8_EPEL_H(8, 4)
+VP8_EPEL_H(4, 4)
+VP8_EPEL_H(16, 6)
+VP8_EPEL_H(8, 6)
+VP8_EPEL_H(4, 6)
+VP8_EPEL_V(16, 4)
+VP8_EPEL_V(8, 4)
+VP8_EPEL_V(4, 4)
+VP8_EPEL_V(16, 6)
+VP8_EPEL_V(8, 6)
+VP8_EPEL_V(4, 6)
+
+VP8_EPEL_HV(16, 4, 4)
+VP8_EPEL_HV(8, 4, 4)
+VP8_EPEL_HV(4, 4, 4)
+VP8_EPEL_HV(16, 4, 6)
+VP8_EPEL_HV(8, 4, 6)
+VP8_EPEL_HV(4, 4, 6)
+VP8_EPEL_HV(16, 6, 4)
+VP8_EPEL_HV(8, 6, 4)
+VP8_EPEL_HV(4, 6, 4)
+VP8_EPEL_HV(16, 6, 6)
+VP8_EPEL_HV(8, 6, 6)
+VP8_EPEL_HV(4, 6, 6)
+
+#define VP8_BILINEAR(SIZE) \
+static void put_vp8_bilinear ## SIZE ## _h_c(uint8_t *dst, ptrdiff_t dstride, \
+ uint8_t *src, ptrdiff_t sstride, \
+ int h, int mx, int my) \
+{ \
+ int a = 8 - mx, b = mx; \
+ int x, y; \
+ for (y = 0; y < h; y++) { \
+ for (x = 0; x < SIZE; x++) \
+ dst[x] = (a * src[x] + b * src[x + 1] + 4) >> 3; \
+ dst += dstride; \
+ src += sstride; \
+ } \
+} \
+ \
+static void put_vp8_bilinear ## SIZE ## _v_c(uint8_t *dst, ptrdiff_t dstride, \
+ uint8_t *src, ptrdiff_t sstride, \
+ int h, int mx, int my) \
+{ \
+ int c = 8 - my, d = my; \
+ int x, y; \
+ for (y = 0; y < h; y++) { \
+ for (x = 0; x < SIZE; x++) \
+ dst[x] = (c * src[x] + d * src[x + sstride] + 4) >> 3; \
+ dst += dstride; \
+ src += sstride; \
+ } \
+} \
+ \
+static void put_vp8_bilinear ## SIZE ## _hv_c(uint8_t *dst, \
+ ptrdiff_t dstride, \
+ uint8_t *src, \
+ ptrdiff_t sstride, \
+ int h, int mx, int my) \
+{ \
+ int a = 8 - mx, b = mx; \
+ int c = 8 - my, d = my; \
+ int x, y; \
+ uint8_t tmp_array[(2 * SIZE + 1) * SIZE]; \
+ uint8_t *tmp = tmp_array; \
+ for (y = 0; y < h + 1; y++) { \
+ for (x = 0; x < SIZE; x++) \
+ tmp[x] = (a * src[x] + b * src[x + 1] + 4) >> 3; \
+ tmp += SIZE; \
+ src += sstride; \
+ } \
+ tmp = tmp_array; \
+ for (y = 0; y < h; y++) { \
+ for (x = 0; x < SIZE; x++) \
+ dst[x] = (c * tmp[x] + d * tmp[x + SIZE] + 4) >> 3; \
+ dst += dstride; \
+ tmp += SIZE; \
+ } \
+}
+
+VP8_BILINEAR(16)
+VP8_BILINEAR(8)
+VP8_BILINEAR(4)
+
+#define VP78_MC_FUNC(IDX, SIZE) \
+ dsp->put_vp8_epel_pixels_tab[IDX][0][0] = put_vp8_pixels ## SIZE ## _c; \
+ dsp->put_vp8_epel_pixels_tab[IDX][0][1] = put_vp8_epel ## SIZE ## _h4_c; \
+ dsp->put_vp8_epel_pixels_tab[IDX][0][2] = put_vp8_epel ## SIZE ## _h6_c; \
+ dsp->put_vp8_epel_pixels_tab[IDX][1][0] = put_vp8_epel ## SIZE ## _v4_c; \
+ dsp->put_vp8_epel_pixels_tab[IDX][1][1] = put_vp8_epel ## SIZE ## _h4v4_c; \
+ dsp->put_vp8_epel_pixels_tab[IDX][1][2] = put_vp8_epel ## SIZE ## _h6v4_c; \
+ dsp->put_vp8_epel_pixels_tab[IDX][2][0] = put_vp8_epel ## SIZE ## _v6_c; \
+ dsp->put_vp8_epel_pixels_tab[IDX][2][1] = put_vp8_epel ## SIZE ## _h4v6_c; \
+ dsp->put_vp8_epel_pixels_tab[IDX][2][2] = put_vp8_epel ## SIZE ## _h6v6_c
+
+#define VP78_BILINEAR_MC_FUNC(IDX, SIZE) \
+ dsp->put_vp8_bilinear_pixels_tab[IDX][0][0] = put_vp8_pixels ## SIZE ## _c; \
+ dsp->put_vp8_bilinear_pixels_tab[IDX][0][1] = put_vp8_bilinear ## SIZE ## _h_c; \
+ dsp->put_vp8_bilinear_pixels_tab[IDX][0][2] = put_vp8_bilinear ## SIZE ## _h_c; \
+ dsp->put_vp8_bilinear_pixels_tab[IDX][1][0] = put_vp8_bilinear ## SIZE ## _v_c; \
+ dsp->put_vp8_bilinear_pixels_tab[IDX][1][1] = put_vp8_bilinear ## SIZE ## _hv_c; \
+ dsp->put_vp8_bilinear_pixels_tab[IDX][1][2] = put_vp8_bilinear ## SIZE ## _hv_c; \
+ dsp->put_vp8_bilinear_pixels_tab[IDX][2][0] = put_vp8_bilinear ## SIZE ## _v_c; \
+ dsp->put_vp8_bilinear_pixels_tab[IDX][2][1] = put_vp8_bilinear ## SIZE ## _hv_c; \
+ dsp->put_vp8_bilinear_pixels_tab[IDX][2][2] = put_vp8_bilinear ## SIZE ## _hv_c
+
+av_cold void ff_vp78dsp_init(VP8DSPContext *dsp)
+{
+ VP78_MC_FUNC(0, 16);
+ VP78_MC_FUNC(1, 8);
+ VP78_MC_FUNC(2, 4);
+
+ VP78_BILINEAR_MC_FUNC(0, 16);
+ VP78_BILINEAR_MC_FUNC(1, 8);
+ VP78_BILINEAR_MC_FUNC(2, 4);
+
+ if (ARCH_ARM)
+ ff_vp78dsp_init_arm(dsp);
+ if (ARCH_PPC)
+ ff_vp78dsp_init_ppc(dsp);
+ if (ARCH_X86)
+ ff_vp78dsp_init_x86(dsp);
+}
+
+#if CONFIG_VP7_DECODER
+LOOP_FILTERS(vp7)
+
+av_cold void ff_vp7dsp_init(VP8DSPContext *dsp)
+{
+ dsp->vp8_luma_dc_wht = vp7_luma_dc_wht_c;
+ dsp->vp8_luma_dc_wht_dc = vp7_luma_dc_wht_dc_c;
+ dsp->vp8_idct_add = vp7_idct_add_c;
+ dsp->vp8_idct_dc_add = vp7_idct_dc_add_c;
+ dsp->vp8_idct_dc_add4y = vp7_idct_dc_add4y_c;
+ dsp->vp8_idct_dc_add4uv = vp7_idct_dc_add4uv_c;
+
+ dsp->vp8_v_loop_filter16y = vp7_v_loop_filter16_c;
+ dsp->vp8_h_loop_filter16y = vp7_h_loop_filter16_c;
+ dsp->vp8_v_loop_filter8uv = vp7_v_loop_filter8uv_c;
+ dsp->vp8_h_loop_filter8uv = vp7_h_loop_filter8uv_c;
+
+ dsp->vp8_v_loop_filter16y_inner = vp7_v_loop_filter16_inner_c;
+ dsp->vp8_h_loop_filter16y_inner = vp7_h_loop_filter16_inner_c;
+ dsp->vp8_v_loop_filter8uv_inner = vp7_v_loop_filter8uv_inner_c;
+ dsp->vp8_h_loop_filter8uv_inner = vp7_h_loop_filter8uv_inner_c;
+
+ dsp->vp8_v_loop_filter_simple = vp7_v_loop_filter_simple_c;
+ dsp->vp8_h_loop_filter_simple = vp7_h_loop_filter_simple_c;
+}
+#endif /* CONFIG_VP7_DECODER */
+
+#if CONFIG_VP8_DECODER
+LOOP_FILTERS(vp8)
+
+av_cold void ff_vp8dsp_init(VP8DSPContext *dsp)
+{
+ dsp->vp8_luma_dc_wht = vp8_luma_dc_wht_c;
+ dsp->vp8_luma_dc_wht_dc = vp8_luma_dc_wht_dc_c;
+ dsp->vp8_idct_add = vp8_idct_add_c;
+ dsp->vp8_idct_dc_add = vp8_idct_dc_add_c;
+ dsp->vp8_idct_dc_add4y = vp8_idct_dc_add4y_c;
+ dsp->vp8_idct_dc_add4uv = vp8_idct_dc_add4uv_c;
+
+ dsp->vp8_v_loop_filter16y = vp8_v_loop_filter16_c;
+ dsp->vp8_h_loop_filter16y = vp8_h_loop_filter16_c;
+ dsp->vp8_v_loop_filter8uv = vp8_v_loop_filter8uv_c;
+ dsp->vp8_h_loop_filter8uv = vp8_h_loop_filter8uv_c;
+
+ dsp->vp8_v_loop_filter16y_inner = vp8_v_loop_filter16_inner_c;
+ dsp->vp8_h_loop_filter16y_inner = vp8_h_loop_filter16_inner_c;
+ dsp->vp8_v_loop_filter8uv_inner = vp8_v_loop_filter8uv_inner_c;
+ dsp->vp8_h_loop_filter8uv_inner = vp8_h_loop_filter8uv_inner_c;
+
+ dsp->vp8_v_loop_filter_simple = vp8_v_loop_filter_simple_c;
+ dsp->vp8_h_loop_filter_simple = vp8_h_loop_filter_simple_c;
+
+ if (ARCH_ARM)
+ ff_vp8dsp_init_arm(dsp);
+ if (ARCH_X86)
+ ff_vp8dsp_init_x86(dsp);
+ if (ARCH_MIPS)
+ ff_vp8dsp_init_mips(dsp);
+}
+#endif /* CONFIG_VP8_DECODER */
diff --git a/ffmpeg-2-8-11/libavcodec/vp8dsp.h b/ffmpeg-2-8-12/libavcodec/vp8dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp8dsp.h
rename to ffmpeg-2-8-12/libavcodec/vp8dsp.h
diff --git a/ffmpeg-2-8-12/libavcodec/vp9.c b/ffmpeg-2-8-12/libavcodec/vp9.c
new file mode 100644
index 0000000..2587083
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/vp9.c
@@ -0,0 +1,4377 @@
+/*
+ * VP9 compatible video decoder
+ *
+ * Copyright (C) 2013 Ronald S. Bultje <rsbultje gmail com>
+ * Copyright (C) 2013 Clément Bœsch <u pkh me>
+ *
+ * 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 "get_bits.h"
+#include "internal.h"
+#include "thread.h"
+#include "videodsp.h"
+#include "vp56.h"
+#include "vp9.h"
+#include "vp9data.h"
+#include "vp9dsp.h"
+#include "libavutil/avassert.h"
+#include "libavutil/pixdesc.h"
+
+#define VP9_SYNCCODE 0x498342
+
+enum CompPredMode {
+ PRED_SINGLEREF,
+ PRED_COMPREF,
+ PRED_SWITCHABLE,
+};
+
+enum BlockLevel {
+ BL_64X64,
+ BL_32X32,
+ BL_16X16,
+ BL_8X8,
+};
+
+enum BlockSize {
+ BS_64x64,
+ BS_64x32,
+ BS_32x64,
+ BS_32x32,
+ BS_32x16,
+ BS_16x32,
+ BS_16x16,
+ BS_16x8,
+ BS_8x16,
+ BS_8x8,
+ BS_8x4,
+ BS_4x8,
+ BS_4x4,
+ N_BS_SIZES,
+};
+
+struct VP9mvrefPair {
+ VP56mv mv[2];
+ int8_t ref[2];
+};
+
+typedef struct VP9Frame {
+ ThreadFrame tf;
+ AVBufferRef *extradata;
+ uint8_t *segmentation_map;
+ struct VP9mvrefPair *mv;
+ int uses_2pass;
+} VP9Frame;
+
+struct VP9Filter {
+ uint8_t level[8 * 8];
+ uint8_t /* bit=col */ mask[2 /* 0=y, 1=uv */][2 /* 0=col, 1=row */]
+ [8 /* rows */][4 /* 0=16, 1=8, 2=4, 3=inner4 */];
+};
+
+typedef struct VP9Block {
+ uint8_t seg_id, intra, comp, ref[2], mode[4], uvmode, skip;
+ enum FilterMode filter;
+ VP56mv mv[4 /* b_idx */][2 /* ref */];
+ enum BlockSize bs;
+ enum TxfmMode tx, uvtx;
+ enum BlockLevel bl;
+ enum BlockPartition bp;
+} VP9Block;
+
+typedef struct VP9Context {
+ VP9DSPContext dsp;
+ VideoDSPContext vdsp;
+ GetBitContext gb;
+ VP56RangeCoder c;
+ VP56RangeCoder *c_b;
+ unsigned c_b_size;
+ VP9Block *b_base, *b;
+ int pass;
+ int row, row7, col, col7;
+ uint8_t *dst[3];
+ ptrdiff_t y_stride, uv_stride;
+
+ // bitstream header
+ uint8_t keyframe, last_keyframe;
+ uint8_t last_bpp, bpp, bpp_index, bytesperpixel;
+ uint8_t invisible;
+ uint8_t use_last_frame_mvs;
+ uint8_t errorres;
+ uint8_t ss_h, ss_v;
+ uint8_t intraonly;
+ uint8_t resetctx;
+ uint8_t refreshrefmask;
+ uint8_t highprecisionmvs;
+ enum FilterMode filtermode;
+ uint8_t allowcompinter;
+ uint8_t fixcompref;
+ uint8_t refreshctx;
+ uint8_t parallelmode;
+ uint8_t framectxid;
+ uint8_t refidx[3];
+ uint8_t signbias[3];
+ uint8_t varcompref[2];
+ ThreadFrame refs[8], next_refs[8];
+#define CUR_FRAME 0
+#define REF_FRAME_MVPAIR 1
+#define REF_FRAME_SEGMAP 2
+ VP9Frame frames[3];
+
+ struct {
+ uint8_t level;
+ int8_t sharpness;
+ uint8_t lim_lut[64];
+ uint8_t mblim_lut[64];
+ } filter;
+ struct {
+ uint8_t enabled;
+ int8_t mode[2];
+ int8_t ref[4];
+ } lf_delta;
+ uint8_t yac_qi;
+ int8_t ydc_qdelta, uvdc_qdelta, uvac_qdelta;
+ uint8_t lossless;
+#define MAX_SEGMENT 8
+ struct {
+ uint8_t enabled;
+ uint8_t temporal;
+ uint8_t absolute_vals;
+ uint8_t update_map;
+ uint8_t ignore_refmap;
+ struct {
+ uint8_t q_enabled;
+ uint8_t lf_enabled;
+ uint8_t ref_enabled;
+ uint8_t skip_enabled;
+ uint8_t ref_val;
+ int16_t q_val;
+ int8_t lf_val;
+ int16_t qmul[2][2];
+ uint8_t lflvl[4][2];
+ } feat[MAX_SEGMENT];
+ } segmentation;
+ struct {
+ unsigned log2_tile_cols, log2_tile_rows;
+ unsigned tile_cols, tile_rows;
+ unsigned tile_row_start, tile_row_end, tile_col_start, tile_col_end;
+ } tiling;
+ unsigned sb_cols, sb_rows, rows, cols;
+ struct {
+ prob_context p;
+ uint8_t coef[4][2][2][6][6][3];
+ } prob_ctx[4];
+ struct {
+ prob_context p;
+ uint8_t coef[4][2][2][6][6][11];
+ uint8_t seg[7];
+ uint8_t segpred[3];
+ } prob;
+ struct {
+ unsigned y_mode[4][10];
+ unsigned uv_mode[10][10];
+ unsigned filter[4][3];
+ unsigned mv_mode[7][4];
+ unsigned intra[4][2];
+ unsigned comp[5][2];
+ unsigned single_ref[5][2][2];
+ unsigned comp_ref[5][2];
+ unsigned tx32p[2][4];
+ unsigned tx16p[2][3];
+ unsigned tx8p[2][2];
+ unsigned skip[3][2];
+ unsigned mv_joint[4];
+ struct {
+ unsigned sign[2];
+ unsigned classes[11];
+ unsigned class0[2];
+ unsigned bits[10][2];
+ unsigned class0_fp[2][4];
+ unsigned fp[4];
+ unsigned class0_hp[2];
+ unsigned hp[2];
+ } mv_comp[2];
+ unsigned partition[4][4][4];
+ unsigned coef[4][2][2][6][6][3];
+ unsigned eob[4][2][2][6][6][2];
+ } counts;
+ enum TxfmMode txfmmode;
+ enum CompPredMode comppredmode;
+
+ // contextual (left/above) cache
+ DECLARE_ALIGNED(16, uint8_t, left_y_nnz_ctx)[16];
+ DECLARE_ALIGNED(16, uint8_t, left_mode_ctx)[16];
+ DECLARE_ALIGNED(16, VP56mv, left_mv_ctx)[16][2];
+ DECLARE_ALIGNED(16, uint8_t, left_uv_nnz_ctx)[2][16];
+ DECLARE_ALIGNED(8, uint8_t, left_partition_ctx)[8];
+ DECLARE_ALIGNED(8, uint8_t, left_skip_ctx)[8];
+ DECLARE_ALIGNED(8, uint8_t, left_txfm_ctx)[8];
+ DECLARE_ALIGNED(8, uint8_t, left_segpred_ctx)[8];
+ DECLARE_ALIGNED(8, uint8_t, left_intra_ctx)[8];
+ DECLARE_ALIGNED(8, uint8_t, left_comp_ctx)[8];
+ DECLARE_ALIGNED(8, uint8_t, left_ref_ctx)[8];
+ DECLARE_ALIGNED(8, uint8_t, left_filter_ctx)[8];
+ uint8_t *above_partition_ctx;
+ uint8_t *above_mode_ctx;
+ // FIXME maybe merge some of the below in a flags field?
+ uint8_t *above_y_nnz_ctx;
+ uint8_t *above_uv_nnz_ctx[2];
+ uint8_t *above_skip_ctx; // 1bit
+ uint8_t *above_txfm_ctx; // 2bit
+ uint8_t *above_segpred_ctx; // 1bit
+ uint8_t *above_intra_ctx; // 1bit
+ uint8_t *above_comp_ctx; // 1bit
+ uint8_t *above_ref_ctx; // 2bit
+ uint8_t *above_filter_ctx;
+ VP56mv (*above_mv_ctx)[2];
+
+ // whole-frame cache
+ uint8_t *intra_pred_data[3];
+ struct VP9Filter *lflvl;
+ DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135 * 144 * 2];
+
+ // block reconstruction intermediates
+ int block_alloc_using_2pass;
+ int16_t *block_base, *block, *uvblock_base[2], *uvblock[2];
+ uint8_t *eob_base, *uveob_base[2], *eob, *uveob[2];
+ struct { int x, y; } min_mv, max_mv;
+ DECLARE_ALIGNED(32, uint8_t, tmp_y)[64 * 64 * 2];
+ DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][64 * 64 * 2];
+ uint16_t mvscale[3][2];
+ uint8_t mvstep[3][2];
+} VP9Context;
+
+static const uint8_t bwh_tab[2][N_BS_SIZES][2] = {
+ {
+ { 16, 16 }, { 16, 8 }, { 8, 16 }, { 8, 8 }, { 8, 4 }, { 4, 8 },
+ { 4, 4 }, { 4, 2 }, { 2, 4 }, { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 },
+ }, {
+ { 8, 8 }, { 8, 4 }, { 4, 8 }, { 4, 4 }, { 4, 2 }, { 2, 4 },
+ { 2, 2 }, { 2, 1 }, { 1, 2 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 },
+ }
+};
+
+static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f)
+{
+ VP9Context *s = ctx->priv_data;
+ int ret, sz;
+
+ if ((ret = ff_thread_get_buffer(ctx, &f->tf, AV_GET_BUFFER_FLAG_REF)) < 0)
+ return ret;
+ sz = 64 * s->sb_cols * s->sb_rows;
+ if (!(f->extradata = av_buffer_allocz(sz * (1 + sizeof(struct VP9mvrefPair))))) {
+ ff_thread_release_buffer(ctx, &f->tf);
+ return AVERROR(ENOMEM);
+ }
+
+ f->segmentation_map = f->extradata->data;
+ f->mv = (struct VP9mvrefPair *) (f->extradata->data + sz);
+
+ return 0;
+}
+
+static void vp9_unref_frame(AVCodecContext *ctx, VP9Frame *f)
+{
+ ff_thread_release_buffer(ctx, &f->tf);
+ av_buffer_unref(&f->extradata);
+ f->segmentation_map = NULL;
+}
+
+static int vp9_ref_frame(AVCodecContext *ctx, VP9Frame *dst, VP9Frame *src)
+{
+ int res;
+
+ if ((res = ff_thread_ref_frame(&dst->tf, &src->tf)) < 0) {
+ return res;
+ } else if (!(dst->extradata = av_buffer_ref(src->extradata))) {
+ vp9_unref_frame(ctx, dst);
+ return AVERROR(ENOMEM);
+ }
+
+ dst->segmentation_map = src->segmentation_map;
+ dst->mv = src->mv;
+ dst->uses_2pass = src->uses_2pass;
+
+ return 0;
+}
+
+static int update_size(AVCodecContext *ctx, int w, int h, enum AVPixelFormat fmt)
+{
+ VP9Context *s = ctx->priv_data;
+ uint8_t *p;
+ int bytesperpixel = s->bytesperpixel;
+
+ av_assert0(w > 0 && h > 0);
+
+ if (s->intra_pred_data[0] && w == ctx->width && h == ctx->height && ctx->pix_fmt == fmt)
+ return 0;
+
+ ctx->width = w;
+ ctx->height = h;
+ ctx->pix_fmt = fmt;
+ s->sb_cols = (w + 63) >> 6;
+ s->sb_rows = (h + 63) >> 6;
+ s->cols = (w + 7) >> 3;
+ s->rows = (h + 7) >> 3;
+
+#define assign(var, type, n) var = (type) p; p += s->sb_cols * (n) * sizeof(*var)
+ av_freep(&s->intra_pred_data[0]);
+ // FIXME we slightly over-allocate here for subsampled chroma, but a little
+ // bit of padding shouldn't affect performance...
+ p = av_malloc(s->sb_cols * (128 + 192 * bytesperpixel +
+ sizeof(*s->lflvl) + 16 * sizeof(*s->above_mv_ctx)));
+ if (!p)
+ return AVERROR(ENOMEM);
+ assign(s->intra_pred_data[0], uint8_t *, 64 * bytesperpixel);
+ assign(s->intra_pred_data[1], uint8_t *, 64 * bytesperpixel);
+ assign(s->intra_pred_data[2], uint8_t *, 64 * bytesperpixel);
+ assign(s->above_y_nnz_ctx, uint8_t *, 16);
+ assign(s->above_mode_ctx, uint8_t *, 16);
+ assign(s->above_mv_ctx, VP56mv(*)[2], 16);
+ assign(s->above_uv_nnz_ctx[0], uint8_t *, 16);
+ assign(s->above_uv_nnz_ctx[1], uint8_t *, 16);
+ assign(s->above_partition_ctx, uint8_t *, 8);
+ assign(s->above_skip_ctx, uint8_t *, 8);
+ assign(s->above_txfm_ctx, uint8_t *, 8);
+ assign(s->above_segpred_ctx, uint8_t *, 8);
+ assign(s->above_intra_ctx, uint8_t *, 8);
+ assign(s->above_comp_ctx, uint8_t *, 8);
+ assign(s->above_ref_ctx, uint8_t *, 8);
+ assign(s->above_filter_ctx, uint8_t *, 8);
+ assign(s->lflvl, struct VP9Filter *, 1);
+#undef assign
+
+ // these will be re-allocated a little later
+ av_freep(&s->b_base);
+ av_freep(&s->block_base);
+
+ if (s->bpp != s->last_bpp) {
+ ff_vp9dsp_init(&s->dsp, s->bpp);
+ ff_videodsp_init(&s->vdsp, s->bpp);
+ s->last_bpp = s->bpp;
+ }
+
+ return 0;
+}
+
+static int update_block_buffers(AVCodecContext *ctx)
+{
+ VP9Context *s = ctx->priv_data;
+ int chroma_blocks, chroma_eobs, bytesperpixel = s->bytesperpixel;
+
+ if (s->b_base && s->block_base && s->block_alloc_using_2pass == s->frames[CUR_FRAME].uses_2pass)
+ return 0;
+
+ av_free(s->b_base);
+ av_free(s->block_base);
+ chroma_blocks = 64 * 64 >> (s->ss_h + s->ss_v);
+ chroma_eobs = 16 * 16 >> (s->ss_h + s->ss_v);
+ if (s->frames[CUR_FRAME].uses_2pass) {
+ int sbs = s->sb_cols * s->sb_rows;
+
+ s->b_base = av_malloc_array(s->cols * s->rows, sizeof(VP9Block));
+ s->block_base = av_mallocz(((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) +
+ 16 * 16 + 2 * chroma_eobs) * sbs);
+ if (!s->b_base || !s->block_base)
+ return AVERROR(ENOMEM);
+ s->uvblock_base[0] = s->block_base + sbs * 64 * 64 * bytesperpixel;
+ s->uvblock_base[1] = s->uvblock_base[0] + sbs * chroma_blocks * bytesperpixel;
+ s->eob_base = (uint8_t *) (s->uvblock_base[1] + sbs * chroma_blocks * bytesperpixel);
+ s->uveob_base[0] = s->eob_base + 16 * 16 * sbs;
+ s->uveob_base[1] = s->uveob_base[0] + chroma_eobs * sbs;
+ } else {
+ s->b_base = av_malloc(sizeof(VP9Block));
+ s->block_base = av_mallocz((64 * 64 + 2 * chroma_blocks) * bytesperpixel * sizeof(int16_t) +
+ 16 * 16 + 2 * chroma_eobs);
+ if (!s->b_base || !s->block_base)
+ return AVERROR(ENOMEM);
+ s->uvblock_base[0] = s->block_base + 64 * 64 * bytesperpixel;
+ s->uvblock_base[1] = s->uvblock_base[0] + chroma_blocks * bytesperpixel;
+ s->eob_base = (uint8_t *) (s->uvblock_base[1] + chroma_blocks * bytesperpixel);
+ s->uveob_base[0] = s->eob_base + 16 * 16;
+ s->uveob_base[1] = s->uveob_base[0] + chroma_eobs;
+ }
+ s->block_alloc_using_2pass = s->frames[CUR_FRAME].uses_2pass;
+
+ return 0;
+}
+
+// for some reason the sign bit is at the end, not the start, of a bit sequence
+static av_always_inline int get_sbits_inv(GetBitContext *gb, int n)
+{
+ int v = get_bits(gb, n);
+ return get_bits1(gb) ? -v : v;
+}
+
+static av_always_inline int inv_recenter_nonneg(int v, int m)
+{
+ return v > 2 * m ? v : v & 1 ? m - ((v + 1) >> 1) : m + (v >> 1);
+}
+
+// differential forward probability updates
+static int update_prob(VP56RangeCoder *c, int p)
+{
+ static const int inv_map_table[255] = {
+ 7, 20, 33, 46, 59, 72, 85, 98, 111, 124, 137, 150, 163, 176,
+ 189, 202, 215, 228, 241, 254, 1, 2, 3, 4, 5, 6, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 99, 100,
+ 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 112, 113, 114, 115,
+ 116, 117, 118, 119, 120, 121, 122, 123, 125, 126, 127, 128, 129, 130,
+ 131, 132, 133, 134, 135, 136, 138, 139, 140, 141, 142, 143, 144, 145,
+ 146, 147, 148, 149, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160,
+ 161, 162, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
+ 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 203, 204, 205, 206,
+ 207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219, 220, 221,
+ 222, 223, 224, 225, 226, 227, 229, 230, 231, 232, 233, 234, 235, 236,
+ 237, 238, 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
+ 252, 253, 253,
+ };
+ int d;
+
+ /* This code is trying to do a differential probability update. For a
+ * current probability A in the range [1, 255], the difference to a new
+ * probability of any value can be expressed differentially as 1-A,255-A
+ * where some part of this (absolute range) exists both in positive as
+ * well as the negative part, whereas another part only exists in one
+ * half. We're trying to code this shared part differentially, i.e.
+ * times two where the value of the lowest bit specifies the sign, and
+ * the single part is then coded on top of this. This absolute difference
+ * then again has a value of [0,254], but a bigger value in this range
+ * indicates that we're further away from the original value A, so we
+ * can code this as a VLC code, since higher values are increasingly
+ * unlikely. The first 20 values in inv_map_table[] allow 'cheap, rough'
+ * updates vs. the 'fine, exact' updates further down the range, which
+ * adds one extra dimension to this differential update model. */
+
+ if (!vp8_rac_get(c)) {
+ d = vp8_rac_get_uint(c, 4) + 0;
+ } else if (!vp8_rac_get(c)) {
+ d = vp8_rac_get_uint(c, 4) + 16;
+ } else if (!vp8_rac_get(c)) {
+ d = vp8_rac_get_uint(c, 5) + 32;
+ } else {
+ d = vp8_rac_get_uint(c, 7);
+ if (d >= 65)
+ d = (d << 1) - 65 + vp8_rac_get(c);
+ d += 64;
+ av_assert2(d < FF_ARRAY_ELEMS(inv_map_table));
+ }
+
+ return p <= 128 ? 1 + inv_recenter_nonneg(inv_map_table[d], p - 1) :
+ 255 - inv_recenter_nonneg(inv_map_table[d], 255 - p);
+}
+
+static enum AVPixelFormat read_colorspace_details(AVCodecContext *ctx)
+{
+ static const enum AVColorSpace colorspaces[8] = {
+ AVCOL_SPC_UNSPECIFIED, AVCOL_SPC_BT470BG, AVCOL_SPC_BT709, AVCOL_SPC_SMPTE170M,
+ AVCOL_SPC_SMPTE240M, AVCOL_SPC_BT2020_NCL, AVCOL_SPC_RESERVED, AVCOL_SPC_RGB,
+ };
+ VP9Context *s = ctx->priv_data;
+ enum AVPixelFormat res;
+ int bits = ctx->profile <= 1 ? 0 : 1 + get_bits1(&s->gb); // 0:8, 1:10, 2:12
+
+ s->bpp_index = bits;
+ s->bpp = 8 + bits * 2;
+ s->bytesperpixel = (7 + s->bpp) >> 3;
+ ctx->colorspace = colorspaces[get_bits(&s->gb, 3)];
+ if (ctx->colorspace == AVCOL_SPC_RGB) { // RGB = profile 1
+ static const enum AVPixelFormat pix_fmt_rgb[3] = {
+ AV_PIX_FMT_GBRP, AV_PIX_FMT_GBRP10, AV_PIX_FMT_GBRP12
+ };
+ if (ctx->profile & 1) {
+ s->ss_h = s->ss_v = 0;
+ res = pix_fmt_rgb[bits];
+ ctx->color_range = AVCOL_RANGE_JPEG;
+ if (get_bits1(&s->gb)) {
+ av_log(ctx, AV_LOG_ERROR, "Reserved bit set in RGB\n");
+ return AVERROR_INVALIDDATA;
+ }
+ } else {
+ av_log(ctx, AV_LOG_ERROR, "RGB not supported in profile %d\n",
+ ctx->profile);
+ return AVERROR_INVALIDDATA;
+ }
+ } else {
+ static const enum AVPixelFormat pix_fmt_for_ss[3][2 /* v */][2 /* h */] = {
+ { { AV_PIX_FMT_YUV444P, AV_PIX_FMT_YUV422P },
+ { AV_PIX_FMT_YUV440P, AV_PIX_FMT_YUV420P } },
+ { { AV_PIX_FMT_YUV444P10, AV_PIX_FMT_YUV422P10 },
+ { AV_PIX_FMT_YUV440P10, AV_PIX_FMT_YUV420P10 } },
+ { { AV_PIX_FMT_YUV444P12, AV_PIX_FMT_YUV422P12 },
+ { AV_PIX_FMT_YUV440P12, AV_PIX_FMT_YUV420P12 } }
+ };
+ ctx->color_range = get_bits1(&s->gb) ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG;
+ if (ctx->profile & 1) {
+ s->ss_h = get_bits1(&s->gb);
+ s->ss_v = get_bits1(&s->gb);
+ if ((res = pix_fmt_for_ss[bits][s->ss_v][s->ss_h]) == AV_PIX_FMT_YUV420P) {
+ av_log(ctx, AV_LOG_ERROR, "YUV 4:2:0 not supported in profile %d\n",
+ ctx->profile);
+ return AVERROR_INVALIDDATA;
+ } else if (get_bits1(&s->gb)) {
+ av_log(ctx, AV_LOG_ERROR, "Profile %d color details reserved bit set\n",
+ ctx->profile);
+ return AVERROR_INVALIDDATA;
+ }
+ } else {
+ s->ss_h = s->ss_v = 1;
+ res = pix_fmt_for_ss[bits][1][1];
+ }
+ }
+
+ return res;
+}
+
+static int decode_frame_header(AVCodecContext *ctx,
+ const uint8_t *data, int size, int *ref)
+{
+ VP9Context *s = ctx->priv_data;
+ int c, i, j, k, l, m, n, w, h, max, size2, res, sharp;
+ enum AVPixelFormat fmt = ctx->pix_fmt;
+ int last_invisible;
+ const uint8_t *data2;
+
+ /* general header */
+ if ((res = init_get_bits8(&s->gb, data, size)) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Failed to initialize bitstream reader\n");
+ return res;
+ }
+ if (get_bits(&s->gb, 2) != 0x2) { // frame marker
+ av_log(ctx, AV_LOG_ERROR, "Invalid frame marker\n");
+ return AVERROR_INVALIDDATA;
+ }
+ ctx->profile = get_bits1(&s->gb);
+ ctx->profile |= get_bits1(&s->gb) << 1;
+ if (ctx->profile == 3) ctx->profile += get_bits1(&s->gb);
+ if (ctx->profile > 3) {
+ av_log(ctx, AV_LOG_ERROR, "Profile %d is not yet supported\n", ctx->profile);
+ return AVERROR_INVALIDDATA;
+ }
+ if (get_bits1(&s->gb)) {
+ *ref = get_bits(&s->gb, 3);
+ return 0;
+ }
+ s->last_keyframe = s->keyframe;
+ s->keyframe = !get_bits1(&s->gb);
+ last_invisible = s->invisible;
+ s->invisible = !get_bits1(&s->gb);
+ s->errorres = get_bits1(&s->gb);
+ s->use_last_frame_mvs = !s->errorres && !last_invisible;
+ if (s->keyframe) {
+ if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode
+ av_log(ctx, AV_LOG_ERROR, "Invalid sync code\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if ((fmt = read_colorspace_details(ctx)) < 0)
+ return fmt;
+ // for profile 1, here follows the subsampling bits
+ s->refreshrefmask = 0xff;
+ w = get_bits(&s->gb, 16) + 1;
+ h = get_bits(&s->gb, 16) + 1;
+ if (get_bits1(&s->gb)) // display size
+ skip_bits(&s->gb, 32);
+ } else {
+ s->intraonly = s->invisible ? get_bits1(&s->gb) : 0;
+ s->resetctx = s->errorres ? 0 : get_bits(&s->gb, 2);
+ if (s->intraonly) {
+ if (get_bits_long(&s->gb, 24) != VP9_SYNCCODE) { // synccode
+ av_log(ctx, AV_LOG_ERROR, "Invalid sync code\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (ctx->profile >= 1) {
+ if ((fmt = read_colorspace_details(ctx)) < 0)
+ return fmt;
+ } else {
+ s->ss_h = s->ss_v = 1;
+ s->bpp = 8;
+ s->bpp_index = 0;
+ s->bytesperpixel = 1;
+ fmt = AV_PIX_FMT_YUV420P;
+ ctx->colorspace = AVCOL_SPC_BT470BG;
+ ctx->color_range = AVCOL_RANGE_JPEG;
+ }
+ s->refreshrefmask = get_bits(&s->gb, 8);
+ w = get_bits(&s->gb, 16) + 1;
+ h = get_bits(&s->gb, 16) + 1;
+ if (get_bits1(&s->gb)) // display size
+ skip_bits(&s->gb, 32);
+ } else {
+ s->refreshrefmask = get_bits(&s->gb, 8);
+ s->refidx[0] = get_bits(&s->gb, 3);
+ s->signbias[0] = get_bits1(&s->gb) && !s->errorres;
+ s->refidx[1] = get_bits(&s->gb, 3);
+ s->signbias[1] = get_bits1(&s->gb) && !s->errorres;
+ s->refidx[2] = get_bits(&s->gb, 3);
+ s->signbias[2] = get_bits1(&s->gb) && !s->errorres;
+ if (!s->refs[s->refidx[0]].f->data[0] ||
+ !s->refs[s->refidx[1]].f->data[0] ||
+ !s->refs[s->refidx[2]].f->data[0]) {
+ av_log(ctx, AV_LOG_ERROR, "Not all references are available\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (get_bits1(&s->gb)) {
+ w = s->refs[s->refidx[0]].f->width;
+ h = s->refs[s->refidx[0]].f->height;
+ } else if (get_bits1(&s->gb)) {
+ w = s->refs[s->refidx[1]].f->width;
+ h = s->refs[s->refidx[1]].f->height;
+ } else if (get_bits1(&s->gb)) {
+ w = s->refs[s->refidx[2]].f->width;
+ h = s->refs[s->refidx[2]].f->height;
+ } else {
+ w = get_bits(&s->gb, 16) + 1;
+ h = get_bits(&s->gb, 16) + 1;
+ }
+ // Note that in this code, "CUR_FRAME" is actually before we
+ // have formally allocated a frame, and thus actually represents
+ // the _last_ frame
+ s->use_last_frame_mvs &= s->frames[CUR_FRAME].tf.f->width == w &&
+ s->frames[CUR_FRAME].tf.f->height == h;
+ if (get_bits1(&s->gb)) // display size
+ skip_bits(&s->gb, 32);
+ s->highprecisionmvs = get_bits1(&s->gb);
+ s->filtermode = get_bits1(&s->gb) ? FILTER_SWITCHABLE :
+ get_bits(&s->gb, 2);
+ s->allowcompinter = (s->signbias[0] != s->signbias[1] ||
+ s->signbias[0] != s->signbias[2]);
+ if (s->allowcompinter) {
+ if (s->signbias[0] == s->signbias[1]) {
+ s->fixcompref = 2;
+ s->varcompref[0] = 0;
+ s->varcompref[1] = 1;
+ } else if (s->signbias[0] == s->signbias[2]) {
+ s->fixcompref = 1;
+ s->varcompref[0] = 0;
+ s->varcompref[1] = 2;
+ } else {
+ s->fixcompref = 0;
+ s->varcompref[0] = 1;
+ s->varcompref[1] = 2;
+ }
+ }
+
+ for (i = 0; i < 3; i++) {
+ AVFrame *ref = s->refs[s->refidx[i]].f;
+ int refw = ref->width, refh = ref->height;
+
+ if (ref->format != fmt) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Ref pixfmt (%s) did not match current frame (%s)",
+ av_get_pix_fmt_name(ref->format),
+ av_get_pix_fmt_name(fmt));
+ return AVERROR_INVALIDDATA;
+ } else if (refw == w && refh == h) {
+ s->mvscale[i][0] = s->mvscale[i][1] = 0;
+ } else {
+ if (w * 2 < refw || h * 2 < refh || w > 16 * refw || h > 16 * refh) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Invalid ref frame dimensions %dx%d for frame size %dx%d\n",
+ refw, refh, w, h);
+ return AVERROR_INVALIDDATA;
+ }
+ s->mvscale[i][0] = (refw << 14) / w;
+ s->mvscale[i][1] = (refh << 14) / h;
+ s->mvstep[i][0] = 16 * s->mvscale[i][0] >> 14;
+ s->mvstep[i][1] = 16 * s->mvscale[i][1] >> 14;
+ }
+ }
+ }
+ }
+ s->refreshctx = s->errorres ? 0 : get_bits1(&s->gb);
+ s->parallelmode = s->errorres ? 1 : get_bits1(&s->gb);
+ s->framectxid = c = get_bits(&s->gb, 2);
+
+ /* loopfilter header data */
+ if (s->keyframe || s->errorres || s->intraonly) {
+ // reset loopfilter defaults
+ s->lf_delta.ref[0] = 1;
+ s->lf_delta.ref[1] = 0;
+ s->lf_delta.ref[2] = -1;
+ s->lf_delta.ref[3] = -1;
+ s->lf_delta.mode[0] = 0;
+ s->lf_delta.mode[1] = 0;
+ memset(s->segmentation.feat, 0, sizeof(s->segmentation.feat));
+ }
+ s->filter.level = get_bits(&s->gb, 6);
+ sharp = get_bits(&s->gb, 3);
+ // if sharpness changed, reinit lim/mblim LUTs. if it didn't change, keep
+ // the old cache values since they are still valid
+ if (s->filter.sharpness != sharp)
+ memset(s->filter.lim_lut, 0, sizeof(s->filter.lim_lut));
+ s->filter.sharpness = sharp;
+ if ((s->lf_delta.enabled = get_bits1(&s->gb))) {
+ if (get_bits1(&s->gb)) {
+ for (i = 0; i < 4; i++)
+ if (get_bits1(&s->gb))
+ s->lf_delta.ref[i] = get_sbits_inv(&s->gb, 6);
+ for (i = 0; i < 2; i++)
+ if (get_bits1(&s->gb))
+ s->lf_delta.mode[i] = get_sbits_inv(&s->gb, 6);
+ }
+ }
+
+ /* quantization header data */
+ s->yac_qi = get_bits(&s->gb, 8);
+ s->ydc_qdelta = get_bits1(&s->gb) ? get_sbits_inv(&s->gb, 4) : 0;
+ s->uvdc_qdelta = get_bits1(&s->gb) ? get_sbits_inv(&s->gb, 4) : 0;
+ s->uvac_qdelta = get_bits1(&s->gb) ? get_sbits_inv(&s->gb, 4) : 0;
+ s->lossless = s->yac_qi == 0 && s->ydc_qdelta == 0 &&
+ s->uvdc_qdelta == 0 && s->uvac_qdelta == 0;
+ if (s->lossless)
+ ctx->properties |= FF_CODEC_PROPERTY_LOSSLESS;
+
+ /* segmentation header info */
+ s->segmentation.ignore_refmap = 0;
+ if ((s->segmentation.enabled = get_bits1(&s->gb))) {
+ if ((s->segmentation.update_map = get_bits1(&s->gb))) {
+ for (i = 0; i < 7; i++)
+ s->prob.seg[i] = get_bits1(&s->gb) ?
+ get_bits(&s->gb, 8) : 255;
+ if ((s->segmentation.temporal = get_bits1(&s->gb))) {
+ for (i = 0; i < 3; i++)
+ s->prob.segpred[i] = get_bits1(&s->gb) ?
+ get_bits(&s->gb, 8) : 255;
+ }
+ }
+ if ((!s->segmentation.update_map || s->segmentation.temporal) &&
+ (w != s->frames[CUR_FRAME].tf.f->width ||
+ h != s->frames[CUR_FRAME].tf.f->height)) {
+ av_log(ctx, AV_LOG_WARNING,
+ "Reference segmap (temp=%d,update=%d) enabled on size-change!\n",
+ s->segmentation.temporal, s->segmentation.update_map);
+ s->segmentation.ignore_refmap = 1;
+ //return AVERROR_INVALIDDATA;
+ }
+
+ if (get_bits1(&s->gb)) {
+ s->segmentation.absolute_vals = get_bits1(&s->gb);
+ for (i = 0; i < 8; i++) {
+ if ((s->segmentation.feat[i].q_enabled = get_bits1(&s->gb)))
+ s->segmentation.feat[i].q_val = get_sbits_inv(&s->gb, 8);
+ if ((s->segmentation.feat[i].lf_enabled = get_bits1(&s->gb)))
+ s->segmentation.feat[i].lf_val = get_sbits_inv(&s->gb, 6);
+ if ((s->segmentation.feat[i].ref_enabled = get_bits1(&s->gb)))
+ s->segmentation.feat[i].ref_val = get_bits(&s->gb, 2);
+ s->segmentation.feat[i].skip_enabled = get_bits1(&s->gb);
+ }
+ }
+ }
+
+ // set qmul[] based on Y/UV, AC/DC and segmentation Q idx deltas
+ for (i = 0; i < (s->segmentation.enabled ? 8 : 1); i++) {
+ int qyac, qydc, quvac, quvdc, lflvl, sh;
+
+ if (s->segmentation.enabled && s->segmentation.feat[i].q_enabled) {
+ if (s->segmentation.absolute_vals)
+ qyac = av_clip_uintp2(s->segmentation.feat[i].q_val, 8);
+ else
+ qyac = av_clip_uintp2(s->yac_qi + s->segmentation.feat[i].q_val, 8);
+ } else {
+ qyac = s->yac_qi;
+ }
+ qydc = av_clip_uintp2(qyac + s->ydc_qdelta, 8);
+ quvdc = av_clip_uintp2(qyac + s->uvdc_qdelta, 8);
+ quvac = av_clip_uintp2(qyac + s->uvac_qdelta, 8);
+ qyac = av_clip_uintp2(qyac, 8);
+
+ s->segmentation.feat[i].qmul[0][0] = vp9_dc_qlookup[s->bpp_index][qydc];
+ s->segmentation.feat[i].qmul[0][1] = vp9_ac_qlookup[s->bpp_index][qyac];
+ s->segmentation.feat[i].qmul[1][0] = vp9_dc_qlookup[s->bpp_index][quvdc];
+ s->segmentation.feat[i].qmul[1][1] = vp9_ac_qlookup[s->bpp_index][quvac];
+
+ sh = s->filter.level >= 32;
+ if (s->segmentation.enabled && s->segmentation.feat[i].lf_enabled) {
+ if (s->segmentation.absolute_vals)
+ lflvl = av_clip_uintp2(s->segmentation.feat[i].lf_val, 6);
+ else
+ lflvl = av_clip_uintp2(s->filter.level + s->segmentation.feat[i].lf_val, 6);
+ } else {
+ lflvl = s->filter.level;
+ }
+ if (s->lf_delta.enabled) {
+ s->segmentation.feat[i].lflvl[0][0] =
+ s->segmentation.feat[i].lflvl[0][1] =
+ av_clip_uintp2(lflvl + (s->lf_delta.ref[0] << sh), 6);
+ for (j = 1; j < 4; j++) {
+ s->segmentation.feat[i].lflvl[j][0] =
+ av_clip_uintp2(lflvl + ((s->lf_delta.ref[j] +
+ s->lf_delta.mode[0]) * (1 << sh)), 6);
+ s->segmentation.feat[i].lflvl[j][1] =
+ av_clip_uintp2(lflvl + ((s->lf_delta.ref[j] +
+ s->lf_delta.mode[1]) * (1 << sh)), 6);
+ }
+ } else {
+ memset(s->segmentation.feat[i].lflvl, lflvl,
+ sizeof(s->segmentation.feat[i].lflvl));
+ }
+ }
+
+ /* tiling info */
+ if ((res = update_size(ctx, w, h, fmt)) < 0) {
+ av_log(ctx, AV_LOG_ERROR, "Failed to initialize decoder for %dx%d @ %d\n", w, h, fmt);
+ return res;
+ }
+ for (s->tiling.log2_tile_cols = 0;
+ (s->sb_cols >> s->tiling.log2_tile_cols) > 64;
+ s->tiling.log2_tile_cols++) ;
+ for (max = 0; (s->sb_cols >> max) >= 4; max++) ;
+ max = FFMAX(0, max - 1);
+ while (max > s->tiling.log2_tile_cols) {
+ if (get_bits1(&s->gb))
+ s->tiling.log2_tile_cols++;
+ else
+ break;
+ }
+ s->tiling.log2_tile_rows = decode012(&s->gb);
+ s->tiling.tile_rows = 1 << s->tiling.log2_tile_rows;
+ if (s->tiling.tile_cols != (1 << s->tiling.log2_tile_cols)) {
+ s->tiling.tile_cols = 1 << s->tiling.log2_tile_cols;
+ s->c_b = av_fast_realloc(s->c_b, &s->c_b_size,
+ sizeof(VP56RangeCoder) * s->tiling.tile_cols);
+ if (!s->c_b) {
+ av_log(ctx, AV_LOG_ERROR, "Ran out of memory during range coder init\n");
+ return AVERROR(ENOMEM);
+ }
+ }
+
+ if (s->keyframe || s->errorres || (s->intraonly && s->resetctx == 3)) {
+ s->prob_ctx[0].p = s->prob_ctx[1].p = s->prob_ctx[2].p =
+ s->prob_ctx[3].p = vp9_default_probs;
+ memcpy(s->prob_ctx[0].coef, vp9_default_coef_probs,
+ sizeof(vp9_default_coef_probs));
+ memcpy(s->prob_ctx[1].coef, vp9_default_coef_probs,
+ sizeof(vp9_default_coef_probs));
+ memcpy(s->prob_ctx[2].coef, vp9_default_coef_probs,
+ sizeof(vp9_default_coef_probs));
+ memcpy(s->prob_ctx[3].coef, vp9_default_coef_probs,
+ sizeof(vp9_default_coef_probs));
+ } else if (s->intraonly && s->resetctx == 2) {
+ s->prob_ctx[c].p = vp9_default_probs;
+ memcpy(s->prob_ctx[c].coef, vp9_default_coef_probs,
+ sizeof(vp9_default_coef_probs));
+ }
+
+ // next 16 bits is size of the rest of the header (arith-coded)
+ size2 = get_bits(&s->gb, 16);
+ data2 = align_get_bits(&s->gb);
+ if (size2 > size - (data2 - data)) {
+ av_log(ctx, AV_LOG_ERROR, "Invalid compressed header size\n");
+ return AVERROR_INVALIDDATA;
+ }
+ res = ff_vp56_init_range_decoder(&s->c, data2, size2);
+ if (res < 0)
+ return res;
+
+ if (vp56_rac_get_prob_branchy(&s->c, 128)) { // marker bit
+ av_log(ctx, AV_LOG_ERROR, "Marker bit was set\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (s->keyframe || s->intraonly) {
+ memset(s->counts.coef, 0, sizeof(s->counts.coef));
+ memset(s->counts.eob, 0, sizeof(s->counts.eob));
+ } else {
+ memset(&s->counts, 0, sizeof(s->counts));
+ }
+ // FIXME is it faster to not copy here, but do it down in the fw updates
+ // as explicit copies if the fw update is missing (and skip the copy upon
+ // fw update)?
+ s->prob.p = s->prob_ctx[c].p;
+
+ // txfm updates
+ if (s->lossless) {
+ s->txfmmode = TX_4X4;
+ } else {
+ s->txfmmode = vp8_rac_get_uint(&s->c, 2);
+ if (s->txfmmode == 3)
+ s->txfmmode += vp8_rac_get(&s->c);
+
+ if (s->txfmmode == TX_SWITCHABLE) {
+ for (i = 0; i < 2; i++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.tx8p[i] = update_prob(&s->c, s->prob.p.tx8p[i]);
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 2; j++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.tx16p[i][j] =
+ update_prob(&s->c, s->prob.p.tx16p[i][j]);
+ for (i = 0; i < 2; i++)
+ for (j = 0; j < 3; j++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.tx32p[i][j] =
+ update_prob(&s->c, s->prob.p.tx32p[i][j]);
+ }
+ }
+
+ // coef updates
+ for (i = 0; i < 4; i++) {
+ uint8_t (*ref)[2][6][6][3] = s->prob_ctx[c].coef[i];
+ if (vp8_rac_get(&s->c)) {
+ for (j = 0; j < 2; j++)
+ for (k = 0; k < 2; k++)
+ for (l = 0; l < 6; l++)
+ for (m = 0; m < 6; m++) {
+ uint8_t *p = s->prob.coef[i][j][k][l][m];
+ uint8_t *r = ref[j][k][l][m];
+ if (m >= 3 && l == 0) // dc only has 3 pt
+ break;
+ for (n = 0; n < 3; n++) {
+ if (vp56_rac_get_prob_branchy(&s->c, 252)) {
+ p[n] = update_prob(&s->c, r[n]);
+ } else {
+ p[n] = r[n];
+ }
+ }
+ p[3] = 0;
+ }
+ } else {
+ for (j = 0; j < 2; j++)
+ for (k = 0; k < 2; k++)
+ for (l = 0; l < 6; l++)
+ for (m = 0; m < 6; m++) {
+ uint8_t *p = s->prob.coef[i][j][k][l][m];
+ uint8_t *r = ref[j][k][l][m];
+ if (m > 3 && l == 0) // dc only has 3 pt
+ break;
+ memcpy(p, r, 3);
+ p[3] = 0;
+ }
+ }
+ if (s->txfmmode == i)
+ break;
+ }
+
+ // mode updates
+ for (i = 0; i < 3; i++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.skip[i] = update_prob(&s->c, s->prob.p.skip[i]);
+ if (!s->keyframe && !s->intraonly) {
+ for (i = 0; i < 7; i++)
+ for (j = 0; j < 3; j++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.mv_mode[i][j] =
+ update_prob(&s->c, s->prob.p.mv_mode[i][j]);
+
+ if (s->filtermode == FILTER_SWITCHABLE)
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 2; j++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.filter[i][j] =
+ update_prob(&s->c, s->prob.p.filter[i][j]);
+
+ for (i = 0; i < 4; i++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.intra[i] = update_prob(&s->c, s->prob.p.intra[i]);
+
+ if (s->allowcompinter) {
+ s->comppredmode = vp8_rac_get(&s->c);
+ if (s->comppredmode)
+ s->comppredmode += vp8_rac_get(&s->c);
+ if (s->comppredmode == PRED_SWITCHABLE)
+ for (i = 0; i < 5; i++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.comp[i] =
+ update_prob(&s->c, s->prob.p.comp[i]);
+ } else {
+ s->comppredmode = PRED_SINGLEREF;
+ }
+
+ if (s->comppredmode != PRED_COMPREF) {
+ for (i = 0; i < 5; i++) {
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.single_ref[i][0] =
+ update_prob(&s->c, s->prob.p.single_ref[i][0]);
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.single_ref[i][1] =
+ update_prob(&s->c, s->prob.p.single_ref[i][1]);
+ }
+ }
+
+ if (s->comppredmode != PRED_SINGLEREF) {
+ for (i = 0; i < 5; i++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.comp_ref[i] =
+ update_prob(&s->c, s->prob.p.comp_ref[i]);
+ }
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 9; j++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.y_mode[i][j] =
+ update_prob(&s->c, s->prob.p.y_mode[i][j]);
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 4; j++)
+ for (k = 0; k < 3; k++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.partition[3 - i][j][k] =
+ update_prob(&s->c, s->prob.p.partition[3 - i][j][k]);
+
+ // mv fields don't use the update_prob subexp model for some reason
+ for (i = 0; i < 3; i++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.mv_joint[i] = (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+
+ for (i = 0; i < 2; i++) {
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.mv_comp[i].sign = (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+
+ for (j = 0; j < 10; j++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.mv_comp[i].classes[j] =
+ (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.mv_comp[i].class0 = (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+
+ for (j = 0; j < 10; j++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.mv_comp[i].bits[j] =
+ (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+ }
+
+ for (i = 0; i < 2; i++) {
+ for (j = 0; j < 2; j++)
+ for (k = 0; k < 3; k++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.mv_comp[i].class0_fp[j][k] =
+ (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+
+ for (j = 0; j < 3; j++)
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.mv_comp[i].fp[j] =
+ (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+ }
+
+ if (s->highprecisionmvs) {
+ for (i = 0; i < 2; i++) {
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.mv_comp[i].class0_hp =
+ (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+
+ if (vp56_rac_get_prob_branchy(&s->c, 252))
+ s->prob.p.mv_comp[i].hp =
+ (vp8_rac_get_uint(&s->c, 7) << 1) | 1;
+ }
+ }
+ }
+
+ return (data2 - data) + size2;
+}
+
+static av_always_inline void clamp_mv(VP56mv *dst, const VP56mv *src,
+ VP9Context *s)
+{
+ dst->x = av_clip(src->x, s->min_mv.x, s->max_mv.x);
+ dst->y = av_clip(src->y, s->min_mv.y, s->max_mv.y);
+}
+
+static void find_ref_mvs(VP9Context *s,
+ VP56mv *pmv, int ref, int z, int idx, int sb)
+{
+ static const int8_t mv_ref_blk_off[N_BS_SIZES][8][2] = {
+ [BS_64x64] = {{ 3, -1 }, { -1, 3 }, { 4, -1 }, { -1, 4 },
+ { -1, -1 }, { 0, -1 }, { -1, 0 }, { 6, -1 }},
+ [BS_64x32] = {{ 0, -1 }, { -1, 0 }, { 4, -1 }, { -1, 2 },
+ { -1, -1 }, { 0, -3 }, { -3, 0 }, { 2, -1 }},
+ [BS_32x64] = {{ -1, 0 }, { 0, -1 }, { -1, 4 }, { 2, -1 },
+ { -1, -1 }, { -3, 0 }, { 0, -3 }, { -1, 2 }},
+ [BS_32x32] = {{ 1, -1 }, { -1, 1 }, { 2, -1 }, { -1, 2 },
+ { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }},
+ [BS_32x16] = {{ 0, -1 }, { -1, 0 }, { 2, -1 }, { -1, -1 },
+ { -1, 1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }},
+ [BS_16x32] = {{ -1, 0 }, { 0, -1 }, { -1, 2 }, { -1, -1 },
+ { 1, -1 }, { -3, 0 }, { 0, -3 }, { -3, -3 }},
+ [BS_16x16] = {{ 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, 1 },
+ { -1, -1 }, { 0, -3 }, { -3, 0 }, { -3, -3 }},
+ [BS_16x8] = {{ 0, -1 }, { -1, 0 }, { 1, -1 }, { -1, -1 },
+ { 0, -2 }, { -2, 0 }, { -2, -1 }, { -1, -2 }},
+ [BS_8x16] = {{ -1, 0 }, { 0, -1 }, { -1, 1 }, { -1, -1 },
+ { -2, 0 }, { 0, -2 }, { -1, -2 }, { -2, -1 }},
+ [BS_8x8] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
+ { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }},
+ [BS_8x4] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
+ { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }},
+ [BS_4x8] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
+ { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }},
+ [BS_4x4] = {{ 0, -1 }, { -1, 0 }, { -1, -1 }, { 0, -2 },
+ { -2, 0 }, { -1, -2 }, { -2, -1 }, { -2, -2 }},
+ };
+ VP9Block *b = s->b;
+ int row = s->row, col = s->col, row7 = s->row7;
+ const int8_t (*p)[2] = mv_ref_blk_off[b->bs];
+#define INVALID_MV 0x80008000U
+ uint32_t mem = INVALID_MV, mem_sub8x8 = INVALID_MV;
+ int i;
+
+#define RETURN_DIRECT_MV(mv) \
+ do { \
+ uint32_t m = AV_RN32A(&mv); \
+ if (!idx) { \
+ AV_WN32A(pmv, m); \
+ return; \
+ } else if (mem == INVALID_MV) { \
+ mem = m; \
+ } else if (m != mem) { \
+ AV_WN32A(pmv, m); \
+ return; \
+ } \
+ } while (0)
+
+ if (sb >= 0) {
+ if (sb == 2 || sb == 1) {
+ RETURN_DIRECT_MV(b->mv[0][z]);
+ } else if (sb == 3) {
+ RETURN_DIRECT_MV(b->mv[2][z]);
+ RETURN_DIRECT_MV(b->mv[1][z]);
+ RETURN_DIRECT_MV(b->mv[0][z]);
+ }
+
+#define RETURN_MV(mv) \
+ do { \
+ if (sb > 0) { \
+ VP56mv tmp; \
+ uint32_t m; \
+ av_assert2(idx == 1); \
+ av_assert2(mem != INVALID_MV); \
+ if (mem_sub8x8 == INVALID_MV) { \
+ clamp_mv(&tmp, &mv, s); \
+ m = AV_RN32A(&tmp); \
+ if (m != mem) { \
+ AV_WN32A(pmv, m); \
+ return; \
+ } \
+ mem_sub8x8 = AV_RN32A(&mv); \
+ } else if (mem_sub8x8 != AV_RN32A(&mv)) { \
+ clamp_mv(&tmp, &mv, s); \
+ m = AV_RN32A(&tmp); \
+ if (m != mem) { \
+ AV_WN32A(pmv, m); \
+ } else { \
+ /* BUG I'm pretty sure this isn't the intention */ \
+ AV_WN32A(pmv, 0); \
+ } \
+ return; \
+ } \
+ } else { \
+ uint32_t m = AV_RN32A(&mv); \
+ if (!idx) { \
+ clamp_mv(pmv, &mv, s); \
+ return; \
+ } else if (mem == INVALID_MV) { \
+ mem = m; \
+ } else if (m != mem) { \
+ clamp_mv(pmv, &mv, s); \
+ return; \
+ } \
+ } \
+ } while (0)
+
+ if (row > 0) {
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[(row - 1) * s->sb_cols * 8 + col];
+ if (mv->ref[0] == ref) {
+ RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][0]);
+ } else if (mv->ref[1] == ref) {
+ RETURN_MV(s->above_mv_ctx[2 * col + (sb & 1)][1]);
+ }
+ }
+ if (col > s->tiling.tile_col_start) {
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[row * s->sb_cols * 8 + col - 1];
+ if (mv->ref[0] == ref) {
+ RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][0]);
+ } else if (mv->ref[1] == ref) {
+ RETURN_MV(s->left_mv_ctx[2 * row7 + (sb >> 1)][1]);
+ }
+ }
+ i = 2;
+ } else {
+ i = 0;
+ }
+
+ // previously coded MVs in this neighbourhood, using same reference frame
+ for (; i < 8; i++) {
+ int c = p[i][0] + col, r = p[i][1] + row;
+
+ if (c >= s->tiling.tile_col_start && c < s->cols && r >= 0 && r < s->rows) {
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
+
+ if (mv->ref[0] == ref) {
+ RETURN_MV(mv->mv[0]);
+ } else if (mv->ref[1] == ref) {
+ RETURN_MV(mv->mv[1]);
+ }
+ }
+ }
+
+ // MV at this position in previous frame, using same reference frame
+ if (s->use_last_frame_mvs) {
+ struct VP9mvrefPair *mv = &s->frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col];
+
+ if (!s->frames[REF_FRAME_MVPAIR].uses_2pass)
+ ff_thread_await_progress(&s->frames[REF_FRAME_MVPAIR].tf, row >> 3, 0);
+ if (mv->ref[0] == ref) {
+ RETURN_MV(mv->mv[0]);
+ } else if (mv->ref[1] == ref) {
+ RETURN_MV(mv->mv[1]);
+ }
+ }
+
+#define RETURN_SCALE_MV(mv, scale) \
+ do { \
+ if (scale) { \
+ VP56mv mv_temp = { -mv.x, -mv.y }; \
+ RETURN_MV(mv_temp); \
+ } else { \
+ RETURN_MV(mv); \
+ } \
+ } while (0)
+
+ // previously coded MVs in this neighbourhood, using different reference frame
+ for (i = 0; i < 8; i++) {
+ int c = p[i][0] + col, r = p[i][1] + row;
+
+ if (c >= s->tiling.tile_col_start && c < s->cols && r >= 0 && r < s->rows) {
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[r * s->sb_cols * 8 + c];
+
+ if (mv->ref[0] != ref && mv->ref[0] >= 0) {
+ RETURN_SCALE_MV(mv->mv[0], s->signbias[mv->ref[0]] != s->signbias[ref]);
+ }
+ if (mv->ref[1] != ref && mv->ref[1] >= 0 &&
+ // BUG - libvpx has this condition regardless of whether
+ // we used the first ref MV and pre-scaling
+ AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) {
+ RETURN_SCALE_MV(mv->mv[1], s->signbias[mv->ref[1]] != s->signbias[ref]);
+ }
+ }
+ }
+
+ // MV at this position in previous frame, using different reference frame
+ if (s->use_last_frame_mvs) {
+ struct VP9mvrefPair *mv = &s->frames[REF_FRAME_MVPAIR].mv[row * s->sb_cols * 8 + col];
+
+ // no need to await_progress, because we already did that above
+ if (mv->ref[0] != ref && mv->ref[0] >= 0) {
+ RETURN_SCALE_MV(mv->mv[0], s->signbias[mv->ref[0]] != s->signbias[ref]);
+ }
+ if (mv->ref[1] != ref && mv->ref[1] >= 0 &&
+ // BUG - libvpx has this condition regardless of whether
+ // we used the first ref MV and pre-scaling
+ AV_RN32A(&mv->mv[0]) != AV_RN32A(&mv->mv[1])) {
+ RETURN_SCALE_MV(mv->mv[1], s->signbias[mv->ref[1]] != s->signbias[ref]);
+ }
+ }
+
+ AV_ZERO32(pmv);
+ clamp_mv(pmv, pmv, s);
+#undef INVALID_MV
+#undef RETURN_MV
+#undef RETURN_SCALE_MV
+}
+
+static av_always_inline int read_mv_component(VP9Context *s, int idx, int hp)
+{
+ int bit, sign = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].sign);
+ int n, c = vp8_rac_get_tree(&s->c, vp9_mv_class_tree,
+ s->prob.p.mv_comp[idx].classes);
+
+ s->counts.mv_comp[idx].sign[sign]++;
+ s->counts.mv_comp[idx].classes[c]++;
+ if (c) {
+ int m;
+
+ for (n = 0, m = 0; m < c; m++) {
+ bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].bits[m]);
+ n |= bit << m;
+ s->counts.mv_comp[idx].bits[m][bit]++;
+ }
+ n <<= 3;
+ bit = vp8_rac_get_tree(&s->c, vp9_mv_fp_tree, s->prob.p.mv_comp[idx].fp);
+ n |= bit << 1;
+ s->counts.mv_comp[idx].fp[bit]++;
+ if (hp) {
+ bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].hp);
+ s->counts.mv_comp[idx].hp[bit]++;
+ n |= bit;
+ } else {
+ n |= 1;
+ // bug in libvpx - we count for bw entropy purposes even if the
+ // bit wasn't coded
+ s->counts.mv_comp[idx].hp[1]++;
+ }
+ n += 8 << c;
+ } else {
+ n = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0);
+ s->counts.mv_comp[idx].class0[n]++;
+ bit = vp8_rac_get_tree(&s->c, vp9_mv_fp_tree,
+ s->prob.p.mv_comp[idx].class0_fp[n]);
+ s->counts.mv_comp[idx].class0_fp[n][bit]++;
+ n = (n << 3) | (bit << 1);
+ if (hp) {
+ bit = vp56_rac_get_prob(&s->c, s->prob.p.mv_comp[idx].class0_hp);
+ s->counts.mv_comp[idx].class0_hp[bit]++;
+ n |= bit;
+ } else {
+ n |= 1;
+ // bug in libvpx - we count for bw entropy purposes even if the
+ // bit wasn't coded
+ s->counts.mv_comp[idx].class0_hp[1]++;
+ }
+ }
+
+ return sign ? -(n + 1) : (n + 1);
+}
+
+static void fill_mv(VP9Context *s,
+ VP56mv *mv, int mode, int sb)
+{
+ VP9Block *b = s->b;
+
+ if (mode == ZEROMV) {
+ AV_ZERO64(mv);
+ } else {
+ int hp;
+
+ // FIXME cache this value and reuse for other subblocks
+ find_ref_mvs(s, &mv[0], b->ref[0], 0, mode == NEARMV,
+ mode == NEWMV ? -1 : sb);
+ // FIXME maybe move this code into find_ref_mvs()
+ if ((mode == NEWMV || sb == -1) &&
+ !(hp = s->highprecisionmvs && abs(mv[0].x) < 64 && abs(mv[0].y) < 64)) {
+ if (mv[0].y & 1) {
+ if (mv[0].y < 0)
+ mv[0].y++;
+ else
+ mv[0].y--;
+ }
+ if (mv[0].x & 1) {
+ if (mv[0].x < 0)
+ mv[0].x++;
+ else
+ mv[0].x--;
+ }
+ }
+ if (mode == NEWMV) {
+ enum MVJoint j = vp8_rac_get_tree(&s->c, vp9_mv_joint_tree,
+ s->prob.p.mv_joint);
+
+ s->counts.mv_joint[j]++;
+ if (j >= MV_JOINT_V)
+ mv[0].y += read_mv_component(s, 0, hp);
+ if (j & 1)
+ mv[0].x += read_mv_component(s, 1, hp);
+ }
+
+ if (b->comp) {
+ // FIXME cache this value and reuse for other subblocks
+ find_ref_mvs(s, &mv[1], b->ref[1], 1, mode == NEARMV,
+ mode == NEWMV ? -1 : sb);
+ if ((mode == NEWMV || sb == -1) &&
+ !(hp = s->highprecisionmvs && abs(mv[1].x) < 64 && abs(mv[1].y) < 64)) {
+ if (mv[1].y & 1) {
+ if (mv[1].y < 0)
+ mv[1].y++;
+ else
+ mv[1].y--;
+ }
+ if (mv[1].x & 1) {
+ if (mv[1].x < 0)
+ mv[1].x++;
+ else
+ mv[1].x--;
+ }
+ }
+ if (mode == NEWMV) {
+ enum MVJoint j = vp8_rac_get_tree(&s->c, vp9_mv_joint_tree,
+ s->prob.p.mv_joint);
+
+ s->counts.mv_joint[j]++;
+ if (j >= MV_JOINT_V)
+ mv[1].y += read_mv_component(s, 0, hp);
+ if (j & 1)
+ mv[1].x += read_mv_component(s, 1, hp);
+ }
+ }
+ }
+}
+
+static av_always_inline void setctx_2d(uint8_t *ptr, int w, int h,
+ ptrdiff_t stride, int v)
+{
+ switch (w) {
+ case 1:
+ do {
+ *ptr = v;
+ ptr += stride;
+ } while (--h);
+ break;
+ case 2: {
+ int v16 = v * 0x0101;
+ do {
+ AV_WN16A(ptr, v16);
+ ptr += stride;
+ } while (--h);
+ break;
+ }
+ case 4: {
+ uint32_t v32 = v * 0x01010101;
+ do {
+ AV_WN32A(ptr, v32);
+ ptr += stride;
+ } while (--h);
+ break;
+ }
+ case 8: {
+#if HAVE_FAST_64BIT
+ uint64_t v64 = v * 0x0101010101010101ULL;
+ do {
+ AV_WN64A(ptr, v64);
+ ptr += stride;
+ } while (--h);
+#else
+ uint32_t v32 = v * 0x01010101;
+ do {
+ AV_WN32A(ptr, v32);
+ AV_WN32A(ptr + 4, v32);
+ ptr += stride;
+ } while (--h);
+#endif
+ break;
+ }
+ }
+}
+
+static void decode_mode(AVCodecContext *ctx)
+{
+ static const uint8_t left_ctx[N_BS_SIZES] = {
+ 0x0, 0x8, 0x0, 0x8, 0xc, 0x8, 0xc, 0xe, 0xc, 0xe, 0xf, 0xe, 0xf
+ };
+ static const uint8_t above_ctx[N_BS_SIZES] = {
+ 0x0, 0x0, 0x8, 0x8, 0x8, 0xc, 0xc, 0xc, 0xe, 0xe, 0xe, 0xf, 0xf
+ };
+ static const uint8_t max_tx_for_bl_bp[N_BS_SIZES] = {
+ TX_32X32, TX_32X32, TX_32X32, TX_32X32, TX_16X16, TX_16X16,
+ TX_16X16, TX_8X8, TX_8X8, TX_8X8, TX_4X4, TX_4X4, TX_4X4
+ };
+ VP9Context *s = ctx->priv_data;
+ VP9Block *b = s->b;
+ int row = s->row, col = s->col, row7 = s->row7;
+ enum TxfmMode max_tx = max_tx_for_bl_bp[b->bs];
+ int bw4 = bwh_tab[1][b->bs][0], w4 = FFMIN(s->cols - col, bw4);
+ int bh4 = bwh_tab[1][b->bs][1], h4 = FFMIN(s->rows - row, bh4), y;
+ int have_a = row > 0, have_l = col > s->tiling.tile_col_start;
+ int vref, filter_id;
+
+ if (!s->segmentation.enabled) {
+ b->seg_id = 0;
+ } else if (s->keyframe || s->intraonly) {
+ b->seg_id = !s->segmentation.update_map ? 0 :
+ vp8_rac_get_tree(&s->c, vp9_segmentation_tree, s->prob.seg);
+ } else if (!s->segmentation.update_map ||
+ (s->segmentation.temporal &&
+ vp56_rac_get_prob_branchy(&s->c,
+ s->prob.segpred[s->above_segpred_ctx[col] +
+ s->left_segpred_ctx[row7]]))) {
+ if (!s->errorres && !s->segmentation.ignore_refmap) {
+ int pred = 8, x;
+ uint8_t *refsegmap = s->frames[REF_FRAME_SEGMAP].segmentation_map;
+
+ if (!s->frames[REF_FRAME_SEGMAP].uses_2pass)
+ ff_thread_await_progress(&s->frames[REF_FRAME_SEGMAP].tf, row >> 3, 0);
+ for (y = 0; y < h4; y++) {
+ int idx_base = (y + row) * 8 * s->sb_cols + col;
+ for (x = 0; x < w4; x++)
+ pred = FFMIN(pred, refsegmap[idx_base + x]);
+ }
+ av_assert1(pred < 8);
+ b->seg_id = pred;
+ } else {
+ b->seg_id = 0;
+ }
+
+ memset(&s->above_segpred_ctx[col], 1, w4);
+ memset(&s->left_segpred_ctx[row7], 1, h4);
+ } else {
+ b->seg_id = vp8_rac_get_tree(&s->c, vp9_segmentation_tree,
+ s->prob.seg);
+
+ memset(&s->above_segpred_ctx[col], 0, w4);
+ memset(&s->left_segpred_ctx[row7], 0, h4);
+ }
+ if (s->segmentation.enabled &&
+ (s->segmentation.update_map || s->keyframe || s->intraonly)) {
+ setctx_2d(&s->frames[CUR_FRAME].segmentation_map[row * 8 * s->sb_cols + col],
+ bw4, bh4, 8 * s->sb_cols, b->seg_id);
+ }
+
+ b->skip = s->segmentation.enabled &&
+ s->segmentation.feat[b->seg_id].skip_enabled;
+ if (!b->skip) {
+ int c = s->left_skip_ctx[row7] + s->above_skip_ctx[col];
+ b->skip = vp56_rac_get_prob(&s->c, s->prob.p.skip[c]);
+ s->counts.skip[c][b->skip]++;
+ }
+
+ if (s->keyframe || s->intraonly) {
+ b->intra = 1;
+ } else if (s->segmentation.enabled && s->segmentation.feat[b->seg_id].ref_enabled) {
+ b->intra = !s->segmentation.feat[b->seg_id].ref_val;
+ } else {
+ int c, bit;
+
+ if (have_a && have_l) {
+ c = s->above_intra_ctx[col] + s->left_intra_ctx[row7];
+ c += (c == 2);
+ } else {
+ c = have_a ? 2 * s->above_intra_ctx[col] :
+ have_l ? 2 * s->left_intra_ctx[row7] : 0;
+ }
+ bit = vp56_rac_get_prob(&s->c, s->prob.p.intra[c]);
+ s->counts.intra[c][bit]++;
+ b->intra = !bit;
+ }
+
+ if ((b->intra || !b->skip) && s->txfmmode == TX_SWITCHABLE) {
+ int c;
+ if (have_a) {
+ if (have_l) {
+ c = (s->above_skip_ctx[col] ? max_tx :
+ s->above_txfm_ctx[col]) +
+ (s->left_skip_ctx[row7] ? max_tx :
+ s->left_txfm_ctx[row7]) > max_tx;
+ } else {
+ c = s->above_skip_ctx[col] ? 1 :
+ (s->above_txfm_ctx[col] * 2 > max_tx);
+ }
+ } else if (have_l) {
+ c = s->left_skip_ctx[row7] ? 1 :
+ (s->left_txfm_ctx[row7] * 2 > max_tx);
+ } else {
+ c = 1;
+ }
+ switch (max_tx) {
+ case TX_32X32:
+ b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][0]);
+ if (b->tx) {
+ b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][1]);
+ if (b->tx == 2)
+ b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx32p[c][2]);
+ }
+ s->counts.tx32p[c][b->tx]++;
+ break;
+ case TX_16X16:
+ b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][0]);
+ if (b->tx)
+ b->tx += vp56_rac_get_prob(&s->c, s->prob.p.tx16p[c][1]);
+ s->counts.tx16p[c][b->tx]++;
+ break;
+ case TX_8X8:
+ b->tx = vp56_rac_get_prob(&s->c, s->prob.p.tx8p[c]);
+ s->counts.tx8p[c][b->tx]++;
+ break;
+ case TX_4X4:
+ b->tx = TX_4X4;
+ break;
+ }
+ } else {
+ b->tx = FFMIN(max_tx, s->txfmmode);
+ }
+
+ if (s->keyframe || s->intraonly) {
+ uint8_t *a = &s->above_mode_ctx[col * 2];
+ uint8_t *l = &s->left_mode_ctx[(row7) << 1];
+
+ b->comp = 0;
+ if (b->bs > BS_8x8) {
+ // FIXME the memory storage intermediates here aren't really
+ // necessary, they're just there to make the code slightly
+ // simpler for now
+ b->mode[0] = a[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
+ vp9_default_kf_ymode_probs[a[0]][l[0]]);
+ if (b->bs != BS_8x4) {
+ b->mode[1] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
+ vp9_default_kf_ymode_probs[a[1]][b->mode[0]]);
+ l[0] = a[1] = b->mode[1];
+ } else {
+ l[0] = a[1] = b->mode[1] = b->mode[0];
+ }
+ if (b->bs != BS_4x8) {
+ b->mode[2] = a[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
+ vp9_default_kf_ymode_probs[a[0]][l[1]]);
+ if (b->bs != BS_8x4) {
+ b->mode[3] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
+ vp9_default_kf_ymode_probs[a[1]][b->mode[2]]);
+ l[1] = a[1] = b->mode[3];
+ } else {
+ l[1] = a[1] = b->mode[3] = b->mode[2];
+ }
+ } else {
+ b->mode[2] = b->mode[0];
+ l[1] = a[1] = b->mode[3] = b->mode[1];
+ }
+ } else {
+ b->mode[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
+ vp9_default_kf_ymode_probs[*a][*l]);
+ b->mode[3] = b->mode[2] = b->mode[1] = b->mode[0];
+ // FIXME this can probably be optimized
+ memset(a, b->mode[0], bwh_tab[0][b->bs][0]);
+ memset(l, b->mode[0], bwh_tab[0][b->bs][1]);
+ }
+ b->uvmode = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
+ vp9_default_kf_uvmode_probs[b->mode[3]]);
+ } else if (b->intra) {
+ b->comp = 0;
+ if (b->bs > BS_8x8) {
+ b->mode[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
+ s->prob.p.y_mode[0]);
+ s->counts.y_mode[0][b->mode[0]]++;
+ if (b->bs != BS_8x4) {
+ b->mode[1] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
+ s->prob.p.y_mode[0]);
+ s->counts.y_mode[0][b->mode[1]]++;
+ } else {
+ b->mode[1] = b->mode[0];
+ }
+ if (b->bs != BS_4x8) {
+ b->mode[2] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
+ s->prob.p.y_mode[0]);
+ s->counts.y_mode[0][b->mode[2]]++;
+ if (b->bs != BS_8x4) {
+ b->mode[3] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
+ s->prob.p.y_mode[0]);
+ s->counts.y_mode[0][b->mode[3]]++;
+ } else {
+ b->mode[3] = b->mode[2];
+ }
+ } else {
+ b->mode[2] = b->mode[0];
+ b->mode[3] = b->mode[1];
+ }
+ } else {
+ static const uint8_t size_group[10] = {
+ 3, 3, 3, 3, 2, 2, 2, 1, 1, 1
+ };
+ int sz = size_group[b->bs];
+
+ b->mode[0] = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
+ s->prob.p.y_mode[sz]);
+ b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0];
+ s->counts.y_mode[sz][b->mode[3]]++;
+ }
+ b->uvmode = vp8_rac_get_tree(&s->c, vp9_intramode_tree,
+ s->prob.p.uv_mode[b->mode[3]]);
+ s->counts.uv_mode[b->mode[3]][b->uvmode]++;
+ } else {
+ static const uint8_t inter_mode_ctx_lut[14][14] = {
+ { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+ { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+ { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+ { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+ { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+ { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+ { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+ { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+ { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+ { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 },
+ { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 },
+ { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 1, 3 },
+ { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 0, 3 },
+ { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 4 },
+ };
+
+ if (s->segmentation.enabled && s->segmentation.feat[b->seg_id].ref_enabled) {
+ av_assert2(s->segmentation.feat[b->seg_id].ref_val != 0);
+ b->comp = 0;
+ b->ref[0] = s->segmentation.feat[b->seg_id].ref_val - 1;
+ } else {
+ // read comp_pred flag
+ if (s->comppredmode != PRED_SWITCHABLE) {
+ b->comp = s->comppredmode == PRED_COMPREF;
+ } else {
+ int c;
+
+ // FIXME add intra as ref=0xff (or -1) to make these easier?
+ if (have_a) {
+ if (have_l) {
+ if (s->above_comp_ctx[col] && s->left_comp_ctx[row7]) {
+ c = 4;
+ } else if (s->above_comp_ctx[col]) {
+ c = 2 + (s->left_intra_ctx[row7] ||
+ s->left_ref_ctx[row7] == s->fixcompref);
+ } else if (s->left_comp_ctx[row7]) {
+ c = 2 + (s->above_intra_ctx[col] ||
+ s->above_ref_ctx[col] == s->fixcompref);
+ } else {
+ c = (!s->above_intra_ctx[col] &&
+ s->above_ref_ctx[col] == s->fixcompref) ^
+ (!s->left_intra_ctx[row7] &&
+ s->left_ref_ctx[row & 7] == s->fixcompref);
+ }
+ } else {
+ c = s->above_comp_ctx[col] ? 3 :
+ (!s->above_intra_ctx[col] && s->above_ref_ctx[col] == s->fixcompref);
+ }
+ } else if (have_l) {
+ c = s->left_comp_ctx[row7] ? 3 :
+ (!s->left_intra_ctx[row7] && s->left_ref_ctx[row7] == s->fixcompref);
+ } else {
+ c = 1;
+ }
+ b->comp = vp56_rac_get_prob(&s->c, s->prob.p.comp[c]);
+ s->counts.comp[c][b->comp]++;
+ }
+
+ // read actual references
+ // FIXME probably cache a few variables here to prevent repetitive
+ // memory accesses below
+ if (b->comp) /* two references */ {
+ int fix_idx = s->signbias[s->fixcompref], var_idx = !fix_idx, c, bit;
+
+ b->ref[fix_idx] = s->fixcompref;
+ // FIXME can this codeblob be replaced by some sort of LUT?
+ if (have_a) {
+ if (have_l) {
+ if (s->above_intra_ctx[col]) {
+ if (s->left_intra_ctx[row7]) {
+ c = 2;
+ } else {
+ c = 1 + 2 * (s->left_ref_ctx[row7] != s->varcompref[1]);
+ }
+ } else if (s->left_intra_ctx[row7]) {
+ c = 1 + 2 * (s->above_ref_ctx[col] != s->varcompref[1]);
+ } else {
+ int refl = s->left_ref_ctx[row7], refa = s->above_ref_ctx[col];
+
+ if (refl == refa && refa == s->varcompref[1]) {
+ c = 0;
+ } else if (!s->left_comp_ctx[row7] && !s->above_comp_ctx[col]) {
+ if ((refa == s->fixcompref && refl == s->varcompref[0]) ||
+ (refl == s->fixcompref && refa == s->varcompref[0])) {
+ c = 4;
+ } else {
+ c = (refa == refl) ? 3 : 1;
+ }
+ } else if (!s->left_comp_ctx[row7]) {
+ if (refa == s->varcompref[1] && refl != s->varcompref[1]) {
+ c = 1;
+ } else {
+ c = (refl == s->varcompref[1] &&
+ refa != s->varcompref[1]) ? 2 : 4;
+ }
+ } else if (!s->above_comp_ctx[col]) {
+ if (refl == s->varcompref[1] && refa != s->varcompref[1]) {
+ c = 1;
+ } else {
+ c = (refa == s->varcompref[1] &&
+ refl != s->varcompref[1]) ? 2 : 4;
+ }
+ } else {
+ c = (refl == refa) ? 4 : 2;
+ }
+ }
+ } else {
+ if (s->above_intra_ctx[col]) {
+ c = 2;
+ } else if (s->above_comp_ctx[col]) {
+ c = 4 * (s->above_ref_ctx[col] != s->varcompref[1]);
+ } else {
+ c = 3 * (s->above_ref_ctx[col] != s->varcompref[1]);
+ }
+ }
+ } else if (have_l) {
+ if (s->left_intra_ctx[row7]) {
+ c = 2;
+ } else if (s->left_comp_ctx[row7]) {
+ c = 4 * (s->left_ref_ctx[row7] != s->varcompref[1]);
+ } else {
+ c = 3 * (s->left_ref_ctx[row7] != s->varcompref[1]);
+ }
+ } else {
+ c = 2;
+ }
+ bit = vp56_rac_get_prob(&s->c, s->prob.p.comp_ref[c]);
+ b->ref[var_idx] = s->varcompref[bit];
+ s->counts.comp_ref[c][bit]++;
+ } else /* single reference */ {
+ int bit, c;
+
+ if (have_a && !s->above_intra_ctx[col]) {
+ if (have_l && !s->left_intra_ctx[row7]) {
+ if (s->left_comp_ctx[row7]) {
+ if (s->above_comp_ctx[col]) {
+ c = 1 + (!s->fixcompref || !s->left_ref_ctx[row7] ||
+ !s->above_ref_ctx[col]);
+ } else {
+ c = (3 * !s->above_ref_ctx[col]) +
+ (!s->fixcompref || !s->left_ref_ctx[row7]);
+ }
+ } else if (s->above_comp_ctx[col]) {
+ c = (3 * !s->left_ref_ctx[row7]) +
+ (!s->fixcompref || !s->above_ref_ctx[col]);
+ } else {
+ c = 2 * !s->left_ref_ctx[row7] + 2 * !s->above_ref_ctx[col];
+ }
+ } else if (s->above_intra_ctx[col]) {
+ c = 2;
+ } else if (s->above_comp_ctx[col]) {
+ c = 1 + (!s->fixcompref || !s->above_ref_ctx[col]);
+ } else {
+ c = 4 * (!s->above_ref_ctx[col]);
+ }
+ } else if (have_l && !s->left_intra_ctx[row7]) {
+ if (s->left_intra_ctx[row7]) {
+ c = 2;
+ } else if (s->left_comp_ctx[row7]) {
+ c = 1 + (!s->fixcompref || !s->left_ref_ctx[row7]);
+ } else {
+ c = 4 * (!s->left_ref_ctx[row7]);
+ }
+ } else {
+ c = 2;
+ }
+ bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][0]);
+ s->counts.single_ref[c][0][bit]++;
+ if (!bit) {
+ b->ref[0] = 0;
+ } else {
+ // FIXME can this codeblob be replaced by some sort of LUT?
+ if (have_a) {
+ if (have_l) {
+ if (s->left_intra_ctx[row7]) {
+ if (s->above_intra_ctx[col]) {
+ c = 2;
+ } else if (s->above_comp_ctx[col]) {
+ c = 1 + 2 * (s->fixcompref == 1 ||
+ s->above_ref_ctx[col] == 1);
+ } else if (!s->above_ref_ctx[col]) {
+ c = 3;
+ } else {
+ c = 4 * (s->above_ref_ctx[col] == 1);
+ }
+ } else if (s->above_intra_ctx[col]) {
+ if (s->left_intra_ctx[row7]) {
+ c = 2;
+ } else if (s->left_comp_ctx[row7]) {
+ c = 1 + 2 * (s->fixcompref == 1 ||
+ s->left_ref_ctx[row7] == 1);
+ } else if (!s->left_ref_ctx[row7]) {
+ c = 3;
+ } else {
+ c = 4 * (s->left_ref_ctx[row7] == 1);
+ }
+ } else if (s->above_comp_ctx[col]) {
+ if (s->left_comp_ctx[row7]) {
+ if (s->left_ref_ctx[row7] == s->above_ref_ctx[col]) {
+ c = 3 * (s->fixcompref == 1 ||
+ s->left_ref_ctx[row7] == 1);
+ } else {
+ c = 2;
+ }
+ } else if (!s->left_ref_ctx[row7]) {
+ c = 1 + 2 * (s->fixcompref == 1 ||
+ s->above_ref_ctx[col] == 1);
+ } else {
+ c = 3 * (s->left_ref_ctx[row7] == 1) +
+ (s->fixcompref == 1 || s->above_ref_ctx[col] == 1);
+ }
+ } else if (s->left_comp_ctx[row7]) {
+ if (!s->above_ref_ctx[col]) {
+ c = 1 + 2 * (s->fixcompref == 1 ||
+ s->left_ref_ctx[row7] == 1);
+ } else {
+ c = 3 * (s->above_ref_ctx[col] == 1) +
+ (s->fixcompref == 1 || s->left_ref_ctx[row7] == 1);
+ }
+ } else if (!s->above_ref_ctx[col]) {
+ if (!s->left_ref_ctx[row7]) {
+ c = 3;
+ } else {
+ c = 4 * (s->left_ref_ctx[row7] == 1);
+ }
+ } else if (!s->left_ref_ctx[row7]) {
+ c = 4 * (s->above_ref_ctx[col] == 1);
+ } else {
+ c = 2 * (s->left_ref_ctx[row7] == 1) +
+ 2 * (s->above_ref_ctx[col] == 1);
+ }
+ } else {
+ if (s->above_intra_ctx[col] ||
+ (!s->above_comp_ctx[col] && !s->above_ref_ctx[col])) {
+ c = 2;
+ } else if (s->above_comp_ctx[col]) {
+ c = 3 * (s->fixcompref == 1 || s->above_ref_ctx[col] == 1);
+ } else {
+ c = 4 * (s->above_ref_ctx[col] == 1);
+ }
+ }
+ } else if (have_l) {
+ if (s->left_intra_ctx[row7] ||
+ (!s->left_comp_ctx[row7] && !s->left_ref_ctx[row7])) {
+ c = 2;
+ } else if (s->left_comp_ctx[row7]) {
+ c = 3 * (s->fixcompref == 1 || s->left_ref_ctx[row7] == 1);
+ } else {
+ c = 4 * (s->left_ref_ctx[row7] == 1);
+ }
+ } else {
+ c = 2;
+ }
+ bit = vp56_rac_get_prob(&s->c, s->prob.p.single_ref[c][1]);
+ s->counts.single_ref[c][1][bit]++;
+ b->ref[0] = 1 + bit;
+ }
+ }
+ }
+
+ if (b->bs <= BS_8x8) {
+ if (s->segmentation.enabled && s->segmentation.feat[b->seg_id].skip_enabled) {
+ b->mode[0] = b->mode[1] = b->mode[2] = b->mode[3] = ZEROMV;
+ } else {
+ static const uint8_t off[10] = {
+ 3, 0, 0, 1, 0, 0, 0, 0, 0, 0
+ };
+
+ // FIXME this needs to use the LUT tables from find_ref_mvs
+ // because not all are -1,0/0,-1
+ int c = inter_mode_ctx_lut[s->above_mode_ctx[col + off[b->bs]]]
+ [s->left_mode_ctx[row7 + off[b->bs]]];
+
+ b->mode[0] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree,
+ s->prob.p.mv_mode[c]);
+ b->mode[1] = b->mode[2] = b->mode[3] = b->mode[0];
+ s->counts.mv_mode[c][b->mode[0] - 10]++;
+ }
+ }
+
+ if (s->filtermode == FILTER_SWITCHABLE) {
+ int c;
+
+ if (have_a && s->above_mode_ctx[col] >= NEARESTMV) {
+ if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) {
+ c = s->above_filter_ctx[col] == s->left_filter_ctx[row7] ?
+ s->left_filter_ctx[row7] : 3;
+ } else {
+ c = s->above_filter_ctx[col];
+ }
+ } else if (have_l && s->left_mode_ctx[row7] >= NEARESTMV) {
+ c = s->left_filter_ctx[row7];
+ } else {
+ c = 3;
+ }
+
+ filter_id = vp8_rac_get_tree(&s->c, vp9_filter_tree,
+ s->prob.p.filter[c]);
+ s->counts.filter[c][filter_id]++;
+ b->filter = vp9_filter_lut[filter_id];
+ } else {
+ b->filter = s->filtermode;
+ }
+
+ if (b->bs > BS_8x8) {
+ int c = inter_mode_ctx_lut[s->above_mode_ctx[col]][s->left_mode_ctx[row7]];
+
+ b->mode[0] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree,
+ s->prob.p.mv_mode[c]);
+ s->counts.mv_mode[c][b->mode[0] - 10]++;
+ fill_mv(s, b->mv[0], b->mode[0], 0);
+
+ if (b->bs != BS_8x4) {
+ b->mode[1] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree,
+ s->prob.p.mv_mode[c]);
+ s->counts.mv_mode[c][b->mode[1] - 10]++;
+ fill_mv(s, b->mv[1], b->mode[1], 1);
+ } else {
+ b->mode[1] = b->mode[0];
+ AV_COPY32(&b->mv[1][0], &b->mv[0][0]);
+ AV_COPY32(&b->mv[1][1], &b->mv[0][1]);
+ }
+
+ if (b->bs != BS_4x8) {
+ b->mode[2] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree,
+ s->prob.p.mv_mode[c]);
+ s->counts.mv_mode[c][b->mode[2] - 10]++;
+ fill_mv(s, b->mv[2], b->mode[2], 2);
+
+ if (b->bs != BS_8x4) {
+ b->mode[3] = vp8_rac_get_tree(&s->c, vp9_inter_mode_tree,
+ s->prob.p.mv_mode[c]);
+ s->counts.mv_mode[c][b->mode[3] - 10]++;
+ fill_mv(s, b->mv[3], b->mode[3], 3);
+ } else {
+ b->mode[3] = b->mode[2];
+ AV_COPY32(&b->mv[3][0], &b->mv[2][0]);
+ AV_COPY32(&b->mv[3][1], &b->mv[2][1]);
+ }
+ } else {
+ b->mode[2] = b->mode[0];
+ AV_COPY32(&b->mv[2][0], &b->mv[0][0]);
+ AV_COPY32(&b->mv[2][1], &b->mv[0][1]);
+ b->mode[3] = b->mode[1];
+ AV_COPY32(&b->mv[3][0], &b->mv[1][0]);
+ AV_COPY32(&b->mv[3][1], &b->mv[1][1]);
+ }
+ } else {
+ fill_mv(s, b->mv[0], b->mode[0], -1);
+ AV_COPY32(&b->mv[1][0], &b->mv[0][0]);
+ AV_COPY32(&b->mv[2][0], &b->mv[0][0]);
+ AV_COPY32(&b->mv[3][0], &b->mv[0][0]);
+ AV_COPY32(&b->mv[1][1], &b->mv[0][1]);
+ AV_COPY32(&b->mv[2][1], &b->mv[0][1]);
+ AV_COPY32(&b->mv[3][1], &b->mv[0][1]);
+ }
+
+ vref = b->ref[b->comp ? s->signbias[s->varcompref[0]] : 0];
+ }
+
+#if HAVE_FAST_64BIT
+#define SPLAT_CTX(var, val, n) \
+ switch (n) { \
+ case 1: var = val; break; \
+ case 2: AV_WN16A(&var, val * 0x0101); break; \
+ case 4: AV_WN32A(&var, val * 0x01010101); break; \
+ case 8: AV_WN64A(&var, val * 0x0101010101010101ULL); break; \
+ case 16: { \
+ uint64_t v64 = val * 0x0101010101010101ULL; \
+ AV_WN64A( &var, v64); \
+ AV_WN64A(&((uint8_t *) &var)[8], v64); \
+ break; \
+ } \
+ }
+#else
+#define SPLAT_CTX(var, val, n) \
+ switch (n) { \
+ case 1: var = val; break; \
+ case 2: AV_WN16A(&var, val * 0x0101); break; \
+ case 4: AV_WN32A(&var, val * 0x01010101); break; \
+ case 8: { \
+ uint32_t v32 = val * 0x01010101; \
+ AV_WN32A( &var, v32); \
+ AV_WN32A(&((uint8_t *) &var)[4], v32); \
+ break; \
+ } \
+ case 16: { \
+ uint32_t v32 = val * 0x01010101; \
+ AV_WN32A( &var, v32); \
+ AV_WN32A(&((uint8_t *) &var)[4], v32); \
+ AV_WN32A(&((uint8_t *) &var)[8], v32); \
+ AV_WN32A(&((uint8_t *) &var)[12], v32); \
+ break; \
+ } \
+ }
+#endif
+
+ switch (bwh_tab[1][b->bs][0]) {
+#define SET_CTXS(dir, off, n) \
+ do { \
+ SPLAT_CTX(s->dir##_skip_ctx[off], b->skip, n); \
+ SPLAT_CTX(s->dir##_txfm_ctx[off], b->tx, n); \
+ SPLAT_CTX(s->dir##_partition_ctx[off], dir##_ctx[b->bs], n); \
+ if (!s->keyframe && !s->intraonly) { \
+ SPLAT_CTX(s->dir##_intra_ctx[off], b->intra, n); \
+ SPLAT_CTX(s->dir##_comp_ctx[off], b->comp, n); \
+ SPLAT_CTX(s->dir##_mode_ctx[off], b->mode[3], n); \
+ if (!b->intra) { \
+ SPLAT_CTX(s->dir##_ref_ctx[off], vref, n); \
+ if (s->filtermode == FILTER_SWITCHABLE) { \
+ SPLAT_CTX(s->dir##_filter_ctx[off], filter_id, n); \
+ } \
+ } \
+ } \
+ } while (0)
+ case 1: SET_CTXS(above, col, 1); break;
+ case 2: SET_CTXS(above, col, 2); break;
+ case 4: SET_CTXS(above, col, 4); break;
+ case 8: SET_CTXS(above, col, 8); break;
+ }
+ switch (bwh_tab[1][b->bs][1]) {
+ case 1: SET_CTXS(left, row7, 1); break;
+ case 2: SET_CTXS(left, row7, 2); break;
+ case 4: SET_CTXS(left, row7, 4); break;
+ case 8: SET_CTXS(left, row7, 8); break;
+ }
+#undef SPLAT_CTX
+#undef SET_CTXS
+
+ if (!s->keyframe && !s->intraonly) {
+ if (b->bs > BS_8x8) {
+ int mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]);
+
+ AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][0], &b->mv[1][0]);
+ AV_COPY32(&s->left_mv_ctx[row7 * 2 + 0][1], &b->mv[1][1]);
+ AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][0], mv0);
+ AV_WN32A(&s->left_mv_ctx[row7 * 2 + 1][1], mv1);
+ AV_COPY32(&s->above_mv_ctx[col * 2 + 0][0], &b->mv[2][0]);
+ AV_COPY32(&s->above_mv_ctx[col * 2 + 0][1], &b->mv[2][1]);
+ AV_WN32A(&s->above_mv_ctx[col * 2 + 1][0], mv0);
+ AV_WN32A(&s->above_mv_ctx[col * 2 + 1][1], mv1);
+ } else {
+ int n, mv0 = AV_RN32A(&b->mv[3][0]), mv1 = AV_RN32A(&b->mv[3][1]);
+
+ for (n = 0; n < w4 * 2; n++) {
+ AV_WN32A(&s->above_mv_ctx[col * 2 + n][0], mv0);
+ AV_WN32A(&s->above_mv_ctx[col * 2 + n][1], mv1);
+ }
+ for (n = 0; n < h4 * 2; n++) {
+ AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][0], mv0);
+ AV_WN32A(&s->left_mv_ctx[row7 * 2 + n][1], mv1);
+ }
+ }
+ }
+
+ // FIXME kinda ugly
+ for (y = 0; y < h4; y++) {
+ int x, o = (row + y) * s->sb_cols * 8 + col;
+ struct VP9mvrefPair *mv = &s->frames[CUR_FRAME].mv[o];
+
+ if (b->intra) {
+ for (x = 0; x < w4; x++) {
+ mv[x].ref[0] =
+ mv[x].ref[1] = -1;
+ }
+ } else if (b->comp) {
+ for (x = 0; x < w4; x++) {
+ mv[x].ref[0] = b->ref[0];
+ mv[x].ref[1] = b->ref[1];
+ AV_COPY32(&mv[x].mv[0], &b->mv[3][0]);
+ AV_COPY32(&mv[x].mv[1], &b->mv[3][1]);
+ }
+ } else {
+ for (x = 0; x < w4; x++) {
+ mv[x].ref[0] = b->ref[0];
+ mv[x].ref[1] = -1;
+ AV_COPY32(&mv[x].mv[0], &b->mv[3][0]);
+ }
+ }
+ }
+}
+
+// FIXME merge cnt/eob arguments?
+static av_always_inline int
+decode_coeffs_b_generic(VP56RangeCoder *c, int16_t *coef, int n_coeffs,
+ int is_tx32x32, int is8bitsperpixel, int bpp, unsigned (*cnt)[6][3],
+ unsigned (*eob)[6][2], uint8_t (*p)[6][11],
+ int nnz, const int16_t *scan, const int16_t (*nb)[2],
+ const int16_t *band_counts, const int16_t *qmul)
+{
+ int i = 0, band = 0, band_left = band_counts[band];
+ uint8_t *tp = p[0][nnz];
+ uint8_t cache[1024];
+
+ do {
+ int val, rc;
+
+ val = vp56_rac_get_prob_branchy(c, tp[0]); // eob
+ eob[band][nnz][val]++;
+ if (!val)
+ break;
+
+ skip_eob:
+ if (!vp56_rac_get_prob_branchy(c, tp[1])) { // zero
+ cnt[band][nnz][0]++;
+ if (!--band_left)
+ band_left = band_counts[++band];
+ cache[scan[i]] = 0;
+ nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1;
+ tp = p[band][nnz];
+ if (++i == n_coeffs)
+ break; //invalid input; blocks should end with EOB
+ goto skip_eob;
+ }
+
+ rc = scan[i];
+ if (!vp56_rac_get_prob_branchy(c, tp[2])) { // one
+ cnt[band][nnz][1]++;
+ val = 1;
+ cache[rc] = 1;
+ } else {
+ // fill in p[3-10] (model fill) - only once per frame for each pos
+ if (!tp[3])
+ memcpy(&tp[3], vp9_model_pareto8[tp[2]], 8);
+
+ cnt[band][nnz][2]++;
+ if (!vp56_rac_get_prob_branchy(c, tp[3])) { // 2, 3, 4
+ if (!vp56_rac_get_prob_branchy(c, tp[4])) {
+ cache[rc] = val = 2;
+ } else {
+ val = 3 + vp56_rac_get_prob(c, tp[5]);
+ cache[rc] = 3;
+ }
+ } else if (!vp56_rac_get_prob_branchy(c, tp[6])) { // cat1/2
+ cache[rc] = 4;
+ if (!vp56_rac_get_prob_branchy(c, tp[7])) {
+ val = 5 + vp56_rac_get_prob(c, 159);
+ } else {
+ val = 7 + (vp56_rac_get_prob(c, 165) << 1);
+ val += vp56_rac_get_prob(c, 145);
+ }
+ } else { // cat 3-6
+ cache[rc] = 5;
+ if (!vp56_rac_get_prob_branchy(c, tp[8])) {
+ if (!vp56_rac_get_prob_branchy(c, tp[9])) {
+ val = 11 + (vp56_rac_get_prob(c, 173) << 2);
+ val += (vp56_rac_get_prob(c, 148) << 1);
+ val += vp56_rac_get_prob(c, 140);
+ } else {
+ val = 19 + (vp56_rac_get_prob(c, 176) << 3);
+ val += (vp56_rac_get_prob(c, 155) << 2);
+ val += (vp56_rac_get_prob(c, 140) << 1);
+ val += vp56_rac_get_prob(c, 135);
+ }
+ } else if (!vp56_rac_get_prob_branchy(c, tp[10])) {
+ val = 35 + (vp56_rac_get_prob(c, 180) << 4);
+ val += (vp56_rac_get_prob(c, 157) << 3);
+ val += (vp56_rac_get_prob(c, 141) << 2);
+ val += (vp56_rac_get_prob(c, 134) << 1);
+ val += vp56_rac_get_prob(c, 130);
+ } else {
+ val = 67;
+ if (!is8bitsperpixel) {
+ if (bpp == 12) {
+ val += vp56_rac_get_prob(c, 255) << 17;
+ val += vp56_rac_get_prob(c, 255) << 16;
+ }
+ val += (vp56_rac_get_prob(c, 255) << 15);
+ val += (vp56_rac_get_prob(c, 255) << 14);
+ }
+ val += (vp56_rac_get_prob(c, 254) << 13);
+ val += (vp56_rac_get_prob(c, 254) << 12);
+ val += (vp56_rac_get_prob(c, 254) << 11);
+ val += (vp56_rac_get_prob(c, 252) << 10);
+ val += (vp56_rac_get_prob(c, 249) << 9);
+ val += (vp56_rac_get_prob(c, 243) << 8);
+ val += (vp56_rac_get_prob(c, 230) << 7);
+ val += (vp56_rac_get_prob(c, 196) << 6);
+ val += (vp56_rac_get_prob(c, 177) << 5);
+ val += (vp56_rac_get_prob(c, 153) << 4);
+ val += (vp56_rac_get_prob(c, 140) << 3);
+ val += (vp56_rac_get_prob(c, 133) << 2);
+ val += (vp56_rac_get_prob(c, 130) << 1);
+ val += vp56_rac_get_prob(c, 129);
+ }
+ }
+ }
+#define STORE_COEF(c, i, v) do { \
+ if (is8bitsperpixel) { \
+ c[i] = v; \
+ } else { \
+ AV_WN32A(&c[i * 2], v); \
+ } \
+} while (0)
+ if (!--band_left)
+ band_left = band_counts[++band];
+ if (is_tx32x32)
+ STORE_COEF(coef, rc, ((vp8_rac_get(c) ? -val : val) * qmul[!!i]) / 2);
+ else
+ STORE_COEF(coef, rc, (vp8_rac_get(c) ? -val : val) * qmul[!!i]);
+ nnz = (1 + cache[nb[i][0]] + cache[nb[i][1]]) >> 1;
+ tp = p[band][nnz];
+ } while (++i < n_coeffs);
+
+ return i;
+}
+
+static int decode_coeffs_b_8bpp(VP9Context *s, int16_t *coef, int n_coeffs,
+ unsigned (*cnt)[6][3], unsigned (*eob)[6][2],
+ uint8_t (*p)[6][11], int nnz, const int16_t *scan,
+ const int16_t (*nb)[2], const int16_t *band_counts,
+ const int16_t *qmul)
+{
+ return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 0, 1, 8, cnt, eob, p,
+ nnz, scan, nb, band_counts, qmul);
+}
+
+static int decode_coeffs_b32_8bpp(VP9Context *s, int16_t *coef, int n_coeffs,
+ unsigned (*cnt)[6][3], unsigned (*eob)[6][2],
+ uint8_t (*p)[6][11], int nnz, const int16_t *scan,
+ const int16_t (*nb)[2], const int16_t *band_counts,
+ const int16_t *qmul)
+{
+ return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 1, 1, 8, cnt, eob, p,
+ nnz, scan, nb, band_counts, qmul);
+}
+
+static int decode_coeffs_b_16bpp(VP9Context *s, int16_t *coef, int n_coeffs,
+ unsigned (*cnt)[6][3], unsigned (*eob)[6][2],
+ uint8_t (*p)[6][11], int nnz, const int16_t *scan,
+ const int16_t (*nb)[2], const int16_t *band_counts,
+ const int16_t *qmul)
+{
+ return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 0, 0, s->bpp, cnt, eob, p,
+ nnz, scan, nb, band_counts, qmul);
+}
+
+static int decode_coeffs_b32_16bpp(VP9Context *s, int16_t *coef, int n_coeffs,
+ unsigned (*cnt)[6][3], unsigned (*eob)[6][2],
+ uint8_t (*p)[6][11], int nnz, const int16_t *scan,
+ const int16_t (*nb)[2], const int16_t *band_counts,
+ const int16_t *qmul)
+{
+ return decode_coeffs_b_generic(&s->c, coef, n_coeffs, 1, 0, s->bpp, cnt, eob, p,
+ nnz, scan, nb, band_counts, qmul);
+}
+
+static av_always_inline int decode_coeffs(AVCodecContext *ctx, int is8bitsperpixel)
+{
+ VP9Context *s = ctx->priv_data;
+ VP9Block *b = s->b;
+ int row = s->row, col = s->col;
+ uint8_t (*p)[6][11] = s->prob.coef[b->tx][0 /* y */][!b->intra];
+ unsigned (*c)[6][3] = s->counts.coef[b->tx][0 /* y */][!b->intra];
+ unsigned (*e)[6][2] = s->counts.eob[b->tx][0 /* y */][!b->intra];
+ int w4 = bwh_tab[1][b->bs][0] << 1, h4 = bwh_tab[1][b->bs][1] << 1;
+ int end_x = FFMIN(2 * (s->cols - col), w4);
+ int end_y = FFMIN(2 * (s->rows - row), h4);
+ int n, pl, x, y, res;
+ int16_t (*qmul)[2] = s->segmentation.feat[b->seg_id].qmul;
+ int tx = 4 * s->lossless + b->tx;
+ const int16_t * const *yscans = vp9_scans[tx];
+ const int16_t (* const *ynbs)[2] = vp9_scans_nb[tx];
+ const int16_t *uvscan = vp9_scans[b->uvtx][DCT_DCT];
+ const int16_t (*uvnb)[2] = vp9_scans_nb[b->uvtx][DCT_DCT];
+ uint8_t *a = &s->above_y_nnz_ctx[col * 2];
+ uint8_t *l = &s->left_y_nnz_ctx[(row & 7) << 1];
+ static const int16_t band_counts[4][8] = {
+ { 1, 2, 3, 4, 3, 16 - 13 },
+ { 1, 2, 3, 4, 11, 64 - 21 },
+ { 1, 2, 3, 4, 11, 256 - 21 },
+ { 1, 2, 3, 4, 11, 1024 - 21 },
+ };
+ const int16_t *y_band_counts = band_counts[b->tx];
+ const int16_t *uv_band_counts = band_counts[b->uvtx];
+ int bytesperpixel = is8bitsperpixel ? 1 : 2;
+ int total_coeff = 0;
+
+#define MERGE(la, end, step, rd) \
+ for (n = 0; n < end; n += step) \
+ la[n] = !!rd(&la[n])
+#define MERGE_CTX(step, rd) \
+ do { \
+ MERGE(l, end_y, step, rd); \
+ MERGE(a, end_x, step, rd); \
+ } while (0)
+
+#define DECODE_Y_COEF_LOOP(step, mode_index, v) \
+ for (n = 0, y = 0; y < end_y; y += step) { \
+ for (x = 0; x < end_x; x += step, n += step * step) { \
+ enum TxfmType txtp = vp9_intra_txfm_type[b->mode[mode_index]]; \
+ res = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \
+ (s, s->block + 16 * n * bytesperpixel, 16 * step * step, \
+ c, e, p, a[x] + l[y], yscans[txtp], \
+ ynbs[txtp], y_band_counts, qmul[0]); \
+ a[x] = l[y] = !!res; \
+ total_coeff |= !!res; \
+ if (step >= 4) { \
+ AV_WN16A(&s->eob[n], res); \
+ } else { \
+ s->eob[n] = res; \
+ } \
+ } \
+ }
+
+#define SPLAT(la, end, step, cond) \
+ if (step == 2) { \
+ for (n = 1; n < end; n += step) \
+ la[n] = la[n - 1]; \
+ } else if (step == 4) { \
+ if (cond) { \
+ for (n = 0; n < end; n += step) \
+ AV_WN32A(&la[n], la[n] * 0x01010101); \
+ } else { \
+ for (n = 0; n < end; n += step) \
+ memset(&la[n + 1], la[n], FFMIN(end - n - 1, 3)); \
+ } \
+ } else /* step == 8 */ { \
+ if (cond) { \
+ if (HAVE_FAST_64BIT) { \
+ for (n = 0; n < end; n += step) \
+ AV_WN64A(&la[n], la[n] * 0x0101010101010101ULL); \
+ } else { \
+ for (n = 0; n < end; n += step) { \
+ uint32_t v32 = la[n] * 0x01010101; \
+ AV_WN32A(&la[n], v32); \
+ AV_WN32A(&la[n + 4], v32); \
+ } \
+ } \
+ } else { \
+ for (n = 0; n < end; n += step) \
+ memset(&la[n + 1], la[n], FFMIN(end - n - 1, 7)); \
+ } \
+ }
+#define SPLAT_CTX(step) \
+ do { \
+ SPLAT(a, end_x, step, end_x == w4); \
+ SPLAT(l, end_y, step, end_y == h4); \
+ } while (0)
+
+ /* y tokens */
+ switch (b->tx) {
+ case TX_4X4:
+ DECODE_Y_COEF_LOOP(1, b->bs > BS_8x8 ? n : 0,);
+ break;
+ case TX_8X8:
+ MERGE_CTX(2, AV_RN16A);
+ DECODE_Y_COEF_LOOP(2, 0,);
+ SPLAT_CTX(2);
+ break;
+ case TX_16X16:
+ MERGE_CTX(4, AV_RN32A);
+ DECODE_Y_COEF_LOOP(4, 0,);
+ SPLAT_CTX(4);
+ break;
+ case TX_32X32:
+ MERGE_CTX(8, AV_RN64A);
+ DECODE_Y_COEF_LOOP(8, 0, 32);
+ SPLAT_CTX(8);
+ break;
+ }
+
+#define DECODE_UV_COEF_LOOP(step, v) \
+ for (n = 0, y = 0; y < end_y; y += step) { \
+ for (x = 0; x < end_x; x += step, n += step * step) { \
+ res = (is8bitsperpixel ? decode_coeffs_b##v##_8bpp : decode_coeffs_b##v##_16bpp) \
+ (s, s->uvblock[pl] + 16 * n * bytesperpixel, \
+ 16 * step * step, c, e, p, a[x] + l[y], \
+ uvscan, uvnb, uv_band_counts, qmul[1]); \
+ a[x] = l[y] = !!res; \
+ total_coeff |= !!res; \
+ if (step >= 4) { \
+ AV_WN16A(&s->uveob[pl][n], res); \
+ } else { \
+ s->uveob[pl][n] = res; \
+ } \
+ } \
+ }
+
+ p = s->prob.coef[b->uvtx][1 /* uv */][!b->intra];
+ c = s->counts.coef[b->uvtx][1 /* uv */][!b->intra];
+ e = s->counts.eob[b->uvtx][1 /* uv */][!b->intra];
+ w4 >>= s->ss_h;
+ end_x >>= s->ss_h;
+ h4 >>= s->ss_v;
+ end_y >>= s->ss_v;
+ for (pl = 0; pl < 2; pl++) {
+ a = &s->above_uv_nnz_ctx[pl][col << !s->ss_h];
+ l = &s->left_uv_nnz_ctx[pl][(row & 7) << !s->ss_v];
+ switch (b->uvtx) {
+ case TX_4X4:
+ DECODE_UV_COEF_LOOP(1,);
+ break;
+ case TX_8X8:
+ MERGE_CTX(2, AV_RN16A);
+ DECODE_UV_COEF_LOOP(2,);
+ SPLAT_CTX(2);
+ break;
+ case TX_16X16:
+ MERGE_CTX(4, AV_RN32A);
+ DECODE_UV_COEF_LOOP(4,);
+ SPLAT_CTX(4);
+ break;
+ case TX_32X32:
+ MERGE_CTX(8, AV_RN64A);
+ DECODE_UV_COEF_LOOP(8, 32);
+ SPLAT_CTX(8);
+ break;
+ }
+ }
+
+ return total_coeff;
+}
+
+static int decode_coeffs_8bpp(AVCodecContext *ctx)
+{
+ return decode_coeffs(ctx, 1);
+}
+
+static int decode_coeffs_16bpp(AVCodecContext *ctx)
+{
+ return decode_coeffs(ctx, 0);
+}
+
+static av_always_inline int check_intra_mode(VP9Context *s, int mode, uint8_t **a,
+ uint8_t *dst_edge, ptrdiff_t stride_edge,
+ uint8_t *dst_inner, ptrdiff_t stride_inner,
+ uint8_t *l, int col, int x, int w,
+ int row, int y, enum TxfmMode tx,
+ int p, int ss_h, int ss_v, int bytesperpixel)
+{
+ int have_top = row > 0 || y > 0;
+ int have_left = col > s->tiling.tile_col_start || x > 0;
+ int have_right = x < w - 1;
+ int bpp = s->bpp;
+ static const uint8_t mode_conv[10][2 /* have_left */][2 /* have_top */] = {
+ [VERT_PRED] = { { DC_127_PRED, VERT_PRED },
+ { DC_127_PRED, VERT_PRED } },
+ [HOR_PRED] = { { DC_129_PRED, DC_129_PRED },
+ { HOR_PRED, HOR_PRED } },
+ [DC_PRED] = { { DC_128_PRED, TOP_DC_PRED },
+ { LEFT_DC_PRED, DC_PRED } },
+ [DIAG_DOWN_LEFT_PRED] = { { DC_127_PRED, DIAG_DOWN_LEFT_PRED },
+ { DC_127_PRED, DIAG_DOWN_LEFT_PRED } },
+ [DIAG_DOWN_RIGHT_PRED] = { { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED },
+ { DIAG_DOWN_RIGHT_PRED, DIAG_DOWN_RIGHT_PRED } },
+ [VERT_RIGHT_PRED] = { { VERT_RIGHT_PRED, VERT_RIGHT_PRED },
+ { VERT_RIGHT_PRED, VERT_RIGHT_PRED } },
+ [HOR_DOWN_PRED] = { { HOR_DOWN_PRED, HOR_DOWN_PRED },
+ { HOR_DOWN_PRED, HOR_DOWN_PRED } },
+ [VERT_LEFT_PRED] = { { DC_127_PRED, VERT_LEFT_PRED },
+ { DC_127_PRED, VERT_LEFT_PRED } },
+ [HOR_UP_PRED] = { { DC_129_PRED, DC_129_PRED },
+ { HOR_UP_PRED, HOR_UP_PRED } },
+ [TM_VP8_PRED] = { { DC_129_PRED, VERT_PRED },
+ { HOR_PRED, TM_VP8_PRED } },
+ };
+ static const struct {
+ uint8_t needs_left:1;
+ uint8_t needs_top:1;
+ uint8_t needs_topleft:1;
+ uint8_t needs_topright:1;
+ uint8_t invert_left:1;
+ } edges[N_INTRA_PRED_MODES] = {
+ [VERT_PRED] = { .needs_top = 1 },
+ [HOR_PRED] = { .needs_left = 1 },
+ [DC_PRED] = { .needs_top = 1, .needs_left = 1 },
+ [DIAG_DOWN_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 },
+ [DIAG_DOWN_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 },
+ [VERT_RIGHT_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 },
+ [HOR_DOWN_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 },
+ [VERT_LEFT_PRED] = { .needs_top = 1, .needs_topright = 1 },
+ [HOR_UP_PRED] = { .needs_left = 1, .invert_left = 1 },
+ [TM_VP8_PRED] = { .needs_left = 1, .needs_top = 1, .needs_topleft = 1 },
+ [LEFT_DC_PRED] = { .needs_left = 1 },
+ [TOP_DC_PRED] = { .needs_top = 1 },
+ [DC_128_PRED] = { 0 },
+ [DC_127_PRED] = { 0 },
+ [DC_129_PRED] = { 0 }
+ };
+
+ av_assert2(mode >= 0 && mode < 10);
+ mode = mode_conv[mode][have_left][have_top];
+ if (edges[mode].needs_top) {
+ uint8_t *top, *topleft;
+ int n_px_need = 4 << tx, n_px_have = (((s->cols - col) << !ss_h) - x) * 4;
+ int n_px_need_tr = 0;
+
+ if (tx == TX_4X4 && edges[mode].needs_topright && have_right)
+ n_px_need_tr = 4;
+
+ // if top of sb64-row, use s->intra_pred_data[] instead of
+ // dst[-stride] for intra prediction (it contains pre- instead of
+ // post-loopfilter data)
+ if (have_top) {
+ top = !(row & 7) && !y ?
+ s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel :
+ y == 0 ? &dst_edge[-stride_edge] : &dst_inner[-stride_inner];
+ if (have_left)
+ topleft = !(row & 7) && !y ?
+ s->intra_pred_data[p] + (col * (8 >> ss_h) + x * 4) * bytesperpixel :
+ y == 0 || x == 0 ? &dst_edge[-stride_edge] :
+ &dst_inner[-stride_inner];
+ }
+
+ if (have_top &&
+ (!edges[mode].needs_topleft || (have_left && top == topleft)) &&
+ (tx != TX_4X4 || !edges[mode].needs_topright || have_right) &&
+ n_px_need + n_px_need_tr <= n_px_have) {
+ *a = top;
+ } else {
+ if (have_top) {
+ if (n_px_need <= n_px_have) {
+ memcpy(*a, top, n_px_need * bytesperpixel);
+ } else {
+#define memset_bpp(c, i1, v, i2, num) do { \
+ if (bytesperpixel == 1) { \
+ memset(&(c)[(i1)], (v)[(i2)], (num)); \
+ } else { \
+ int n, val = AV_RN16A(&(v)[(i2) * 2]); \
+ for (n = 0; n < (num); n++) { \
+ AV_WN16A(&(c)[((i1) + n) * 2], val); \
+ } \
+ } \
+} while (0)
+ memcpy(*a, top, n_px_have * bytesperpixel);
+ memset_bpp(*a, n_px_have, (*a), n_px_have - 1, n_px_need - n_px_have);
+ }
+ } else {
+#define memset_val(c, val, num) do { \
+ if (bytesperpixel == 1) { \
+ memset((c), (val), (num)); \
+ } else { \
+ int n; \
+ for (n = 0; n < (num); n++) { \
+ AV_WN16A(&(c)[n * 2], (val)); \
+ } \
+ } \
+} while (0)
+ memset_val(*a, (128 << (bpp - 8)) - 1, n_px_need);
+ }
+ if (edges[mode].needs_topleft) {
+ if (have_left && have_top) {
+#define assign_bpp(c, i1, v, i2) do { \
+ if (bytesperpixel == 1) { \
+ (c)[(i1)] = (v)[(i2)]; \
+ } else { \
+ AV_COPY16(&(c)[(i1) * 2], &(v)[(i2) * 2]); \
+ } \
+} while (0)
+ assign_bpp(*a, -1, topleft, -1);
+ } else {
+#define assign_val(c, i, v) do { \
+ if (bytesperpixel == 1) { \
+ (c)[(i)] = (v); \
+ } else { \
+ AV_WN16A(&(c)[(i) * 2], (v)); \
+ } \
+} while (0)
+ assign_val((*a), -1, (128 << (bpp - 8)) + (have_top ? +1 : -1));
+ }
+ }
+ if (tx == TX_4X4 && edges[mode].needs_topright) {
+ if (have_top && have_right &&
+ n_px_need + n_px_need_tr <= n_px_have) {
+ memcpy(&(*a)[4 * bytesperpixel], &top[4 * bytesperpixel], 4 * bytesperpixel);
+ } else {
+ memset_bpp(*a, 4, *a, 3, 4);
+ }
+ }
+ }
+ }
+ if (edges[mode].needs_left) {
+ if (have_left) {
+ int n_px_need = 4 << tx, i, n_px_have = (((s->rows - row) << !ss_v) - y) * 4;
+ uint8_t *dst = x == 0 ? dst_edge : dst_inner;
+ ptrdiff_t stride = x == 0 ? stride_edge : stride_inner;
+
+ if (edges[mode].invert_left) {
+ if (n_px_need <= n_px_have) {
+ for (i = 0; i < n_px_need; i++)
+ assign_bpp(l, i, &dst[i * stride], -1);
+ } else {
+ for (i = 0; i < n_px_have; i++)
+ assign_bpp(l, i, &dst[i * stride], -1);
+ memset_bpp(l, n_px_have, l, n_px_have - 1, n_px_need - n_px_have);
+ }
+ } else {
+ if (n_px_need <= n_px_have) {
+ for (i = 0; i < n_px_need; i++)
+ assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1);
+ } else {
+ for (i = 0; i < n_px_have; i++)
+ assign_bpp(l, n_px_need - 1 - i, &dst[i * stride], -1);
+ memset_bpp(l, 0, l, n_px_need - n_px_have, n_px_need - n_px_have);
+ }
+ }
+ } else {
+ memset_val(l, (128 << (bpp - 8)) + 1, 4 << tx);
+ }
+ }
+
+ return mode;
+}
+
+static av_always_inline void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off,
+ ptrdiff_t uv_off, int bytesperpixel)
+{
+ VP9Context *s = ctx->priv_data;
+ VP9Block *b = s->b;
+ int row = s->row, col = s->col;
+ int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n;
+ int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2);
+ int end_x = FFMIN(2 * (s->cols - col), w4);
+ int end_y = FFMIN(2 * (s->rows - row), h4);
+ int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless;
+ int uvstep1d = 1 << b->uvtx, p;
+ uint8_t *dst = s->dst[0], *dst_r = s->frames[CUR_FRAME].tf.f->data[0] + y_off;
+ LOCAL_ALIGNED_32(uint8_t, a_buf, [96]);
+ LOCAL_ALIGNED_32(uint8_t, l, [64]);
+
+ for (n = 0, y = 0; y < end_y; y += step1d) {
+ uint8_t *ptr = dst, *ptr_r = dst_r;
+ for (x = 0; x < end_x; x += step1d, ptr += 4 * step1d * bytesperpixel,
+ ptr_r += 4 * step1d * bytesperpixel, n += step) {
+ int mode = b->mode[b->bs > BS_8x8 && b->tx == TX_4X4 ?
+ y * 2 + x : 0];
+ uint8_t *a = &a_buf[32];
+ enum TxfmType txtp = vp9_intra_txfm_type[mode];
+ int eob = b->skip ? 0 : b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
+
+ mode = check_intra_mode(s, mode, &a, ptr_r,
+ s->frames[CUR_FRAME].tf.f->linesize[0],
+ ptr, s->y_stride, l,
+ col, x, w4, row, y, b->tx, 0, 0, 0, bytesperpixel);
+ s->dsp.intra_pred[b->tx][mode](ptr, s->y_stride, l, a);
+ if (eob)
+ s->dsp.itxfm_add[tx][txtp](ptr, s->y_stride,
+ s->block + 16 * n * bytesperpixel, eob);
+ }
+ dst_r += 4 * step1d * s->frames[CUR_FRAME].tf.f->linesize[0];
+ dst += 4 * step1d * s->y_stride;
+ }
+
+ // U/V
+ w4 >>= s->ss_h;
+ end_x >>= s->ss_h;
+ end_y >>= s->ss_v;
+ step = 1 << (b->uvtx * 2);
+ for (p = 0; p < 2; p++) {
+ dst = s->dst[1 + p];
+ dst_r = s->frames[CUR_FRAME].tf.f->data[1 + p] + uv_off;
+ for (n = 0, y = 0; y < end_y; y += uvstep1d) {
+ uint8_t *ptr = dst, *ptr_r = dst_r;
+ for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d * bytesperpixel,
+ ptr_r += 4 * uvstep1d * bytesperpixel, n += step) {
+ int mode = b->uvmode;
+ uint8_t *a = &a_buf[32];
+ int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n];
+
+ mode = check_intra_mode(s, mode, &a, ptr_r,
+ s->frames[CUR_FRAME].tf.f->linesize[1],
+ ptr, s->uv_stride, l, col, x, w4, row, y,
+ b->uvtx, p + 1, s->ss_h, s->ss_v, bytesperpixel);
+ s->dsp.intra_pred[b->uvtx][mode](ptr, s->uv_stride, l, a);
+ if (eob)
+ s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride,
+ s->uvblock[p] + 16 * n * bytesperpixel, eob);
+ }
+ dst_r += 4 * uvstep1d * s->frames[CUR_FRAME].tf.f->linesize[1];
+ dst += 4 * uvstep1d * s->uv_stride;
+ }
+ }
+}
+
+static void intra_recon_8bpp(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
+{
+ intra_recon(ctx, y_off, uv_off, 1);
+}
+
+static void intra_recon_16bpp(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off)
+{
+ intra_recon(ctx, y_off, uv_off, 2);
+}
+
+static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func smc,
+ uint8_t *dst, ptrdiff_t dst_stride,
+ const uint8_t *ref, ptrdiff_t ref_stride,
+ ThreadFrame *ref_frame,
+ ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv,
+ int px, int py, int pw, int ph,
+ int bw, int bh, int w, int h, int bytesperpixel,
+ const uint16_t *scale, const uint8_t *step)
+{
+#define scale_mv(n, dim) (((int64_t)(n) * scale[dim]) >> 14)
+ int mx, my;
+ int refbw_m1, refbh_m1;
+ int th;
+ VP56mv mv;
+
+ mv.x = av_clip(in_mv->x, -(x + pw - px + 4) << 3, (s->cols * 8 - x + px + 3) << 3);
+ mv.y = av_clip(in_mv->y, -(y + ph - py + 4) << 3, (s->rows * 8 - y + py + 3) << 3);
+ // BUG libvpx seems to scale the two components separately. This introduces
+ // rounding errors but we have to reproduce them to be exactly compatible
+ // with the output from libvpx...
+ mx = scale_mv(mv.x * 2, 0) + scale_mv(x * 16, 0);
+ my = scale_mv(mv.y * 2, 1) + scale_mv(y * 16, 1);
+
+ y = my >> 4;
+ x = mx >> 4;
+ ref += y * ref_stride + x * bytesperpixel;
+ mx &= 15;
+ my &= 15;
+ refbw_m1 = ((bw - 1) * step[0] + mx) >> 4;
+ refbh_m1 = ((bh - 1) * step[1] + my) >> 4;
+ // FIXME bilinear filter only needs 0/1 pixels, not 3/4
+ // we use +7 because the last 7 pixels of each sbrow can be changed in
+ // the longest loopfilter of the next sbrow
+ th = (y + refbh_m1 + 4 + 7) >> 6;
+ ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);
+ if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 4 >= h - refbh_m1) {
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+ ref - 3 * ref_stride - 3 * bytesperpixel,
+ 288, ref_stride,
+ refbw_m1 + 8, refbh_m1 + 8,
+ x - 3, y - 3, w, h);
+ ref = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel;
+ ref_stride = 288;
+ }
+ smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]);
+}
+
+static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func smc,
+ uint8_t *dst_u, uint8_t *dst_v,
+ ptrdiff_t dst_stride,
+ const uint8_t *ref_u, ptrdiff_t src_stride_u,
+ const uint8_t *ref_v, ptrdiff_t src_stride_v,
+ ThreadFrame *ref_frame,
+ ptrdiff_t y, ptrdiff_t x, const VP56mv *in_mv,
+ int px, int py, int pw, int ph,
+ int bw, int bh, int w, int h, int bytesperpixel,
+ const uint16_t *scale, const uint8_t *step)
+{
+ int mx, my;
+ int refbw_m1, refbh_m1;
+ int th;
+ VP56mv mv;
+
+ if (s->ss_h) {
+ // BUG https://code.google.com/p/webm/issues/detail?id=820
+ mv.x = av_clip(in_mv->x, -(x + pw - px + 4) << 4, (s->cols * 4 - x + px + 3) << 4);
+ mx = scale_mv(mv.x, 0) + (scale_mv(x * 16, 0) & ~15) + (scale_mv(x * 32, 0) & 15);
+ } else {
+ mv.x = av_clip(in_mv->x, -(x + pw - px + 4) << 3, (s->cols * 8 - x + px + 3) << 3);
+ mx = scale_mv(mv.x << 1, 0) + scale_mv(x * 16, 0);
+ }
+ if (s->ss_v) {
+ // BUG https://code.google.com/p/webm/issues/detail?id=820
+ mv.y = av_clip(in_mv->y, -(y + ph - py + 4) << 4, (s->rows * 4 - y + py + 3) << 4);
+ my = scale_mv(mv.y, 1) + (scale_mv(y * 16, 1) & ~15) + (scale_mv(y * 32, 1) & 15);
+ } else {
+ mv.y = av_clip(in_mv->y, -(y + ph - py + 4) << 3, (s->rows * 8 - y + py + 3) << 3);
+ my = scale_mv(mv.y << 1, 1) + scale_mv(y * 16, 1);
+ }
+#undef scale_mv
+ y = my >> 4;
+ x = mx >> 4;
+ ref_u += y * src_stride_u + x * bytesperpixel;
+ ref_v += y * src_stride_v + x * bytesperpixel;
+ mx &= 15;
+ my &= 15;
+ refbw_m1 = ((bw - 1) * step[0] + mx) >> 4;
+ refbh_m1 = ((bh - 1) * step[1] + my) >> 4;
+ // FIXME bilinear filter only needs 0/1 pixels, not 3/4
+ // we use +7 because the last 7 pixels of each sbrow can be changed in
+ // the longest loopfilter of the next sbrow
+ th = (y + refbh_m1 + 4 + 7) >> (6 - s->ss_v);
+ ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);
+ if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 4 >= h - refbh_m1) {
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+ ref_u - 3 * src_stride_u - 3 * bytesperpixel,
+ 288, src_stride_u,
+ refbw_m1 + 8, refbh_m1 + 8,
+ x - 3, y - 3, w, h);
+ ref_u = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel;
+ smc(dst_u, dst_stride, ref_u, 288, bh, mx, my, step[0], step[1]);
+
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+ ref_v - 3 * src_stride_v - 3 * bytesperpixel,
+ 288, src_stride_v,
+ refbw_m1 + 8, refbh_m1 + 8,
+ x - 3, y - 3, w, h);
+ ref_v = s->edge_emu_buffer + 3 * 288 + 3 * bytesperpixel;
+ smc(dst_v, dst_stride, ref_v, 288, bh, mx, my, step[0], step[1]);
+ } else {
+ smc(dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my, step[0], step[1]);
+ smc(dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my, step[0], step[1]);
+ }
+}
+
+#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \
+ px, py, pw, ph, bw, bh, w, h, i) \
+ mc_luma_scaled(s, s->dsp.s##mc, dst, dst_ls, src, src_ls, tref, row, col, \
+ mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \
+ s->mvscale[b->ref[i]], s->mvstep[b->ref[i]])
+#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \
+ row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \
+ mc_chroma_scaled(s, s->dsp.s##mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \
+ row, col, mv, px, py, pw, ph, bw, bh, w, h, bytesperpixel, \
+ s->mvscale[b->ref[i]], s->mvstep[b->ref[i]])
+#define SCALED 1
+#define FN(x) x##_scaled_8bpp
+#define BYTES_PER_PIXEL 1
+#include "vp9_mc_template.c"
+#undef FN
+#undef BYTES_PER_PIXEL
+#define FN(x) x##_scaled_16bpp
+#define BYTES_PER_PIXEL 2
+#include "vp9_mc_template.c"
+#undef mc_luma_dir
+#undef mc_chroma_dir
+#undef FN
+#undef BYTES_PER_PIXEL
+#undef SCALED
+
+static av_always_inline void mc_luma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2],
+ uint8_t *dst, ptrdiff_t dst_stride,
+ const uint8_t *ref, ptrdiff_t ref_stride,
+ ThreadFrame *ref_frame,
+ ptrdiff_t y, ptrdiff_t x, const VP56mv *mv,
+ int bw, int bh, int w, int h, int bytesperpixel)
+{
+ int mx = mv->x, my = mv->y, th;
+
+ y += my >> 3;
+ x += mx >> 3;
+ ref += y * ref_stride + x * bytesperpixel;
+ mx &= 7;
+ my &= 7;
+ // FIXME bilinear filter only needs 0/1 pixels, not 3/4
+ // we use +7 because the last 7 pixels of each sbrow can be changed in
+ // the longest loopfilter of the next sbrow
+ th = (y + bh + 4 * !!my + 7) >> 6;
+ ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);
+ if (x < !!mx * 3 || y < !!my * 3 ||
+ x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) {
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+ ref - !!my * 3 * ref_stride - !!mx * 3 * bytesperpixel,
+ 160, ref_stride,
+ bw + !!mx * 7, bh + !!my * 7,
+ x - !!mx * 3, y - !!my * 3, w, h);
+ ref = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel;
+ ref_stride = 160;
+ }
+ mc[!!mx][!!my](dst, dst_stride, ref, ref_stride, bh, mx << 1, my << 1);
+}
+
+static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2],
+ uint8_t *dst_u, uint8_t *dst_v,
+ ptrdiff_t dst_stride,
+ const uint8_t *ref_u, ptrdiff_t src_stride_u,
+ const uint8_t *ref_v, ptrdiff_t src_stride_v,
+ ThreadFrame *ref_frame,
+ ptrdiff_t y, ptrdiff_t x, const VP56mv *mv,
+ int bw, int bh, int w, int h, int bytesperpixel)
+{
+ int mx = mv->x << !s->ss_h, my = mv->y << !s->ss_v, th;
+
+ y += my >> 4;
+ x += mx >> 4;
+ ref_u += y * src_stride_u + x * bytesperpixel;
+ ref_v += y * src_stride_v + x * bytesperpixel;
+ mx &= 15;
+ my &= 15;
+ // FIXME bilinear filter only needs 0/1 pixels, not 3/4
+ // we use +7 because the last 7 pixels of each sbrow can be changed in
+ // the longest loopfilter of the next sbrow
+ th = (y + bh + 4 * !!my + 7) >> (6 - s->ss_v);
+ ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0);
+ if (x < !!mx * 3 || y < !!my * 3 ||
+ x + !!mx * 4 > w - bw || y + !!my * 4 > h - bh) {
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+ ref_u - !!my * 3 * src_stride_u - !!mx * 3 * bytesperpixel,
+ 160, src_stride_u,
+ bw + !!mx * 7, bh + !!my * 7,
+ x - !!mx * 3, y - !!my * 3, w, h);
+ ref_u = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel;
+ mc[!!mx][!!my](dst_u, dst_stride, ref_u, 160, bh, mx, my);
+
+ s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
+ ref_v - !!my * 3 * src_stride_v - !!mx * 3 * bytesperpixel,
+ 160, src_stride_v,
+ bw + !!mx * 7, bh + !!my * 7,
+ x - !!mx * 3, y - !!my * 3, w, h);
+ ref_v = s->edge_emu_buffer + !!my * 3 * 160 + !!mx * 3 * bytesperpixel;
+ mc[!!mx][!!my](dst_v, dst_stride, ref_v, 160, bh, mx, my);
+ } else {
+ mc[!!mx][!!my](dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my);
+ mc[!!mx][!!my](dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my);
+ }
+}
+
+#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, \
+ px, py, pw, ph, bw, bh, w, h, i) \
+ mc_luma_unscaled(s, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \
+ mv, bw, bh, w, h, bytesperpixel)
+#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \
+ row, col, mv, px, py, pw, ph, bw, bh, w, h, i) \
+ mc_chroma_unscaled(s, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \
+ row, col, mv, bw, bh, w, h, bytesperpixel)
+#define SCALED 0
+#define FN(x) x##_8bpp
+#define BYTES_PER_PIXEL 1
+#include "vp9_mc_template.c"
+#undef FN
+#undef BYTES_PER_PIXEL
+#define FN(x) x##_16bpp
+#define BYTES_PER_PIXEL 2
+#include "vp9_mc_template.c"
+#undef mc_luma_dir_dir
+#undef mc_chroma_dir_dir
+#undef FN
+#undef BYTES_PER_PIXEL
+#undef SCALED
+
+static av_always_inline void inter_recon(AVCodecContext *ctx, int bytesperpixel)
+{
+ VP9Context *s = ctx->priv_data;
+ VP9Block *b = s->b;
+ int row = s->row, col = s->col;
+
+ if (s->mvscale[b->ref[0]][0] || (b->comp && s->mvscale[b->ref[1]][0])) {
+ if (bytesperpixel == 1) {
+ inter_pred_scaled_8bpp(ctx);
+ } else {
+ inter_pred_scaled_16bpp(ctx);
+ }
+ } else {
+ if (bytesperpixel == 1) {
+ inter_pred_8bpp(ctx);
+ } else {
+ inter_pred_16bpp(ctx);
+ }
+ }
+ if (!b->skip) {
+ /* mostly copied intra_recon() */
+
+ int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n;
+ int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2);
+ int end_x = FFMIN(2 * (s->cols - col), w4);
+ int end_y = FFMIN(2 * (s->rows - row), h4);
+ int tx = 4 * s->lossless + b->tx, uvtx = b->uvtx + 4 * s->lossless;
+ int uvstep1d = 1 << b->uvtx, p;
+ uint8_t *dst = s->dst[0];
+
+ // y itxfm add
+ for (n = 0, y = 0; y < end_y; y += step1d) {
+ uint8_t *ptr = dst;
+ for (x = 0; x < end_x; x += step1d,
+ ptr += 4 * step1d * bytesperpixel, n += step) {
+ int eob = b->tx > TX_8X8 ? AV_RN16A(&s->eob[n]) : s->eob[n];
+
+ if (eob)
+ s->dsp.itxfm_add[tx][DCT_DCT](ptr, s->y_stride,
+ s->block + 16 * n * bytesperpixel, eob);
+ }
+ dst += 4 * s->y_stride * step1d;
+ }
+
+ // uv itxfm add
+ end_x >>= s->ss_h;
+ end_y >>= s->ss_v;
+ step = 1 << (b->uvtx * 2);
+ for (p = 0; p < 2; p++) {
+ dst = s->dst[p + 1];
+ for (n = 0, y = 0; y < end_y; y += uvstep1d) {
+ uint8_t *ptr = dst;
+ for (x = 0; x < end_x; x += uvstep1d,
+ ptr += 4 * uvstep1d * bytesperpixel, n += step) {
+ int eob = b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n];
+
+ if (eob)
+ s->dsp.itxfm_add[uvtx][DCT_DCT](ptr, s->uv_stride,
+ s->uvblock[p] + 16 * n * bytesperpixel, eob);
+ }
+ dst += 4 * uvstep1d * s->uv_stride;
+ }
+ }
+ }
+}
+
+static void inter_recon_8bpp(AVCodecContext *ctx)
+{
+ inter_recon(ctx, 1);
+}
+
+static void inter_recon_16bpp(AVCodecContext *ctx)
+{
+ inter_recon(ctx, 2);
+}
+
+static av_always_inline void mask_edges(uint8_t (*mask)[8][4], int ss_h, int ss_v,
+ int row_and_7, int col_and_7,
+ int w, int h, int col_end, int row_end,
+ enum TxfmMode tx, int skip_inter)
+{
+ static const unsigned wide_filter_col_mask[2] = { 0x11, 0x01 };
+ static const unsigned wide_filter_row_mask[2] = { 0x03, 0x07 };
+
+ // FIXME I'm pretty sure all loops can be replaced by a single LUT if
+ // we make VP9Filter.mask uint64_t (i.e. row/col all single variable)
+ // and make the LUT 5-indexed (bl, bp, is_uv, tx and row/col), and then
+ // use row_and_7/col_and_7 as shifts (1*col_and_7+8*row_and_7)
+
+ // the intended behaviour of the vp9 loopfilter is to work on 8-pixel
+ // edges. This means that for UV, we work on two subsampled blocks at
+ // a time, and we only use the topleft block's mode information to set
+ // things like block strength. Thus, for any block size smaller than
+ // 16x16, ignore the odd portion of the block.
+ if (tx == TX_4X4 && (ss_v | ss_h)) {
+ if (h == ss_v) {
+ if (row_and_7 & 1)
+ return;
+ if (!row_end)
+ h += 1;
+ }
+ if (w == ss_h) {
+ if (col_and_7 & 1)
+ return;
+ if (!col_end)
+ w += 1;
+ }
+ }
+
+ if (tx == TX_4X4 && !skip_inter) {
+ int t = 1 << col_and_7, m_col = (t << w) - t, y;
+ // on 32-px edges, use the 8-px wide loopfilter; else, use 4-px wide
+ int m_row_8 = m_col & wide_filter_col_mask[ss_h], m_row_4 = m_col - m_row_8;
+
+ for (y = row_and_7; y < h + row_and_7; y++) {
+ int col_mask_id = 2 - !(y & wide_filter_row_mask[ss_v]);
+
+ mask[0][y][1] |= m_row_8;
+ mask[0][y][2] |= m_row_4;
+ // for odd lines, if the odd col is not being filtered,
+ // skip odd row also:
+ // .---. <-- a
+ // | |
+ // |___| <-- b
+ // ^ ^
+ // c d
+ //
+ // if a/c are even row/col and b/d are odd, and d is skipped,
+ // e.g. right edge of size-66x66.webm, then skip b also (bug)
+ if ((ss_h & ss_v) && (col_end & 1) && (y & 1)) {
+ mask[1][y][col_mask_id] |= (t << (w - 1)) - t;
+ } else {
+ mask[1][y][col_mask_id] |= m_col;
+ }
+ if (!ss_h)
+ mask[0][y][3] |= m_col;
+ if (!ss_v) {
+ if (ss_h && (col_end & 1))
+ mask[1][y][3] |= (t << (w - 1)) - t;
+ else
+ mask[1][y][3] |= m_col;
+ }
+ }
+ } else {
+ int y, t = 1 << col_and_7, m_col = (t << w) - t;
+
+ if (!skip_inter) {
+ int mask_id = (tx == TX_8X8);
+ static const unsigned masks[4] = { 0xff, 0x55, 0x11, 0x01 };
+ int l2 = tx + ss_h - 1, step1d;
+ int m_row = m_col & masks[l2];
+
+ // at odd UV col/row edges tx16/tx32 loopfilter edges, force
+ // 8wd loopfilter to prevent going off the visible edge.
+ if (ss_h && tx > TX_8X8 && (w ^ (w - 1)) == 1) {
+ int m_row_16 = ((t << (w - 1)) - t) & masks[l2];
+ int m_row_8 = m_row - m_row_16;
+
+ for (y = row_and_7; y < h + row_and_7; y++) {
+ mask[0][y][0] |= m_row_16;
+ mask[0][y][1] |= m_row_8;
+ }
+ } else {
+ for (y = row_and_7; y < h + row_and_7; y++)
+ mask[0][y][mask_id] |= m_row;
+ }
+
+ l2 = tx + ss_v - 1;
+ step1d = 1 << l2;
+ if (ss_v && tx > TX_8X8 && (h ^ (h - 1)) == 1) {
+ for (y = row_and_7; y < h + row_and_7 - 1; y += step1d)
+ mask[1][y][0] |= m_col;
+ if (y - row_and_7 == h - 1)
+ mask[1][y][1] |= m_col;
+ } else {
+ for (y = row_and_7; y < h + row_and_7; y += step1d)
+ mask[1][y][mask_id] |= m_col;
+ }
+ } else if (tx != TX_4X4) {
+ int mask_id;
+
+ mask_id = (tx == TX_8X8) || (h == ss_v);
+ mask[1][row_and_7][mask_id] |= m_col;
+ mask_id = (tx == TX_8X8) || (w == ss_h);
+ for (y = row_and_7; y < h + row_and_7; y++)
+ mask[0][y][mask_id] |= t;
+ } else {
+ int t8 = t & wide_filter_col_mask[ss_h], t4 = t - t8;
+
+ for (y = row_and_7; y < h + row_and_7; y++) {
+ mask[0][y][2] |= t4;
+ mask[0][y][1] |= t8;
+ }
+ mask[1][row_and_7][2 - !(row_and_7 & wide_filter_row_mask[ss_v])] |= m_col;
+ }
+ }
+}
+
+static void decode_b(AVCodecContext *ctx, int row, int col,
+ struct VP9Filter *lflvl, ptrdiff_t yoff, ptrdiff_t uvoff,
+ enum BlockLevel bl, enum BlockPartition bp)
+{
+ VP9Context *s = ctx->priv_data;
+ VP9Block *b = s->b;
+ enum BlockSize bs = bl * 3 + bp;
+ int bytesperpixel = s->bytesperpixel;
+ int w4 = bwh_tab[1][bs][0], h4 = bwh_tab[1][bs][1], lvl;
+ int emu[2];
+ AVFrame *f = s->frames[CUR_FRAME].tf.f;
+
+ s->row = row;
+ s->row7 = row & 7;
+ s->col = col;
+ s->col7 = col & 7;
+ s->min_mv.x = -(128 + col * 64);
+ s->min_mv.y = -(128 + row * 64);
+ s->max_mv.x = 128 + (s->cols - col - w4) * 64;
+ s->max_mv.y = 128 + (s->rows - row - h4) * 64;
+ if (s->pass < 2) {
+ b->bs = bs;
+ b->bl = bl;
+ b->bp = bp;
+ decode_mode(ctx);
+ b->uvtx = b->tx - ((s->ss_h && w4 * 2 == (1 << b->tx)) ||
+ (s->ss_v && h4 * 2 == (1 << b->tx)));
+
+ if (!b->skip) {
+ int has_coeffs;
+
+ if (bytesperpixel == 1) {
+ has_coeffs = decode_coeffs_8bpp(ctx);
+ } else {
+ has_coeffs = decode_coeffs_16bpp(ctx);
+ }
+ if (!has_coeffs && b->bs <= BS_8x8 && !b->intra) {
+ b->skip = 1;
+ memset(&s->above_skip_ctx[col], 1, w4);
+ memset(&s->left_skip_ctx[s->row7], 1, h4);
+ }
+ } else {
+ int row7 = s->row7;
+
+#define SPLAT_ZERO_CTX(v, n) \
+ switch (n) { \
+ case 1: v = 0; break; \
+ case 2: AV_ZERO16(&v); break; \
+ case 4: AV_ZERO32(&v); break; \
+ case 8: AV_ZERO64(&v); break; \
+ case 16: AV_ZERO128(&v); break; \
+ }
+#define SPLAT_ZERO_YUV(dir, var, off, n, dir2) \
+ do { \
+ SPLAT_ZERO_CTX(s->dir##_y_##var[off * 2], n * 2); \
+ if (s->ss_##dir2) { \
+ SPLAT_ZERO_CTX(s->dir##_uv_##var[0][off], n); \
+ SPLAT_ZERO_CTX(s->dir##_uv_##var[1][off], n); \
+ } else { \
+ SPLAT_ZERO_CTX(s->dir##_uv_##var[0][off * 2], n * 2); \
+ SPLAT_ZERO_CTX(s->dir##_uv_##var[1][off * 2], n * 2); \
+ } \
+ } while (0)
+
+ switch (w4) {
+ case 1: SPLAT_ZERO_YUV(above, nnz_ctx, col, 1, h); break;
+ case 2: SPLAT_ZERO_YUV(above, nnz_ctx, col, 2, h); break;
+ case 4: SPLAT_ZERO_YUV(above, nnz_ctx, col, 4, h); break;
+ case 8: SPLAT_ZERO_YUV(above, nnz_ctx, col, 8, h); break;
+ }
+ switch (h4) {
+ case 1: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 1, v); break;
+ case 2: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 2, v); break;
+ case 4: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 4, v); break;
+ case 8: SPLAT_ZERO_YUV(left, nnz_ctx, row7, 8, v); break;
+ }
+ }
+ if (s->pass == 1) {
+ s->b++;
+ s->block += w4 * h4 * 64 * bytesperpixel;
+ s->uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v);
+ s->uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_h + s->ss_v);
+ s->eob += 4 * w4 * h4;
+ s->uveob[0] += 4 * w4 * h4 >> (s->ss_h + s->ss_v);
+ s->uveob[1] += 4 * w4 * h4 >> (s->ss_h + s->ss_v);
+
+ return;
+ }
+ }
+
+ // emulated overhangs if the stride of the target buffer can't hold. This
+ // makes it possible to support emu-edge and so on even if we have large block
+ // overhangs
+ emu[0] = (col + w4) * 8 > f->linesize[0] ||
+ (row + h4) > s->rows;
+ emu[1] = (col + w4) * 4 > f->linesize[1] ||
+ (row + h4) > s->rows;
+ if (emu[0]) {
+ s->dst[0] = s->tmp_y;
+ s->y_stride = 128;
+ } else {
+ s->dst[0] = f->data[0] + yoff;
+ s->y_stride = f->linesize[0];
+ }
+ if (emu[1]) {
+ s->dst[1] = s->tmp_uv[0];
+ s->dst[2] = s->tmp_uv[1];
+ s->uv_stride = 128;
+ } else {
+ s->dst[1] = f->data[1] + uvoff;
+ s->dst[2] = f->data[2] + uvoff;
+ s->uv_stride = f->linesize[1];
+ }
+ if (b->intra) {
+ if (s->bpp > 8) {
+ intra_recon_16bpp(ctx, yoff, uvoff);
+ } else {
+ intra_recon_8bpp(ctx, yoff, uvoff);
+ }
+ } else {
+ if (s->bpp > 8) {
+ inter_recon_16bpp(ctx);
+ } else {
+ inter_recon_8bpp(ctx);
+ }
+ }
+ if (emu[0]) {
+ int w = FFMIN(s->cols - col, w4) * 8, h = FFMIN(s->rows - row, h4) * 8, n, o = 0;
+
+ for (n = 0; o < w; n++) {
+ int bw = 64 >> n;
+
+ av_assert2(n <= 4);
+ if (w & bw) {
+ s->dsp.mc[n][0][0][0][0](f->data[0] + yoff + o, f->linesize[0],
+ s->tmp_y + o, 128, h, 0, 0);
+ o += bw * bytesperpixel;
+ }
+ }
+ }
+ if (emu[1]) {
+ int w = FFMIN(s->cols - col, w4) * 8 >> s->ss_h;
+ int h = FFMIN(s->rows - row, h4) * 8 >> s->ss_v, n, o = 0;
+
+ for (n = s->ss_h; o < w; n++) {
+ int bw = 64 >> n;
+
+ av_assert2(n <= 4);
+ if (w & bw) {
+ s->dsp.mc[n][0][0][0][0](f->data[1] + uvoff + o, f->linesize[1],
+ s->tmp_uv[0] + o, 128, h, 0, 0);
+ s->dsp.mc[n][0][0][0][0](f->data[2] + uvoff + o, f->linesize[2],
+ s->tmp_uv[1] + o, 128, h, 0, 0);
+ o += bw * bytesperpixel;
+ }
+ }
+ }
+
+ // pick filter level and find edges to apply filter to
+ if (s->filter.level &&
+ (lvl = s->segmentation.feat[b->seg_id].lflvl[b->intra ? 0 : b->ref[0] + 1]
+ [b->mode[3] != ZEROMV]) > 0) {
+ int x_end = FFMIN(s->cols - col, w4), y_end = FFMIN(s->rows - row, h4);
+ int skip_inter = !b->intra && b->skip, col7 = s->col7, row7 = s->row7;
+
+ setctx_2d(&lflvl->level[row7 * 8 + col7], w4, h4, 8, lvl);
+ mask_edges(lflvl->mask[0], 0, 0, row7, col7, x_end, y_end, 0, 0, b->tx, skip_inter);
+ if (s->ss_h || s->ss_v)
+ mask_edges(lflvl->mask[1], s->ss_h, s->ss_v, row7, col7, x_end, y_end,
+ s->cols & 1 && col + w4 >= s->cols ? s->cols & 7 : 0,
+ s->rows & 1 && row + h4 >= s->rows ? s->rows & 7 : 0,
+ b->uvtx, skip_inter);
+
+ if (!s->filter.lim_lut[lvl]) {
+ int sharp = s->filter.sharpness;
+ int limit = lvl;
+
+ if (sharp > 0) {
+ limit >>= (sharp + 3) >> 2;
+ limit = FFMIN(limit, 9 - sharp);
+ }
+ limit = FFMAX(limit, 1);
+
+ s->filter.lim_lut[lvl] = limit;
+ s->filter.mblim_lut[lvl] = 2 * (lvl + 2) + limit;
+ }
+ }
+
+ if (s->pass == 2) {
+ s->b++;
+ s->block += w4 * h4 * 64 * bytesperpixel;
+ s->uvblock[0] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h);
+ s->uvblock[1] += w4 * h4 * 64 * bytesperpixel >> (s->ss_v + s->ss_h);
+ s->eob += 4 * w4 * h4;
+ s->uveob[0] += 4 * w4 * h4 >> (s->ss_v + s->ss_h);
+ s->uveob[1] += 4 * w4 * h4 >> (s->ss_v + s->ss_h);
+ }
+}
+
+static void decode_sb(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl,
+ ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl)
+{
+ VP9Context *s = ctx->priv_data;
+ int c = ((s->above_partition_ctx[col] >> (3 - bl)) & 1) |
+ (((s->left_partition_ctx[row & 0x7] >> (3 - bl)) & 1) << 1);
+ const uint8_t *p = s->keyframe || s->intraonly ? vp9_default_kf_partition_probs[bl][c] :
+ s->prob.p.partition[bl][c];
+ enum BlockPartition bp;
+ ptrdiff_t hbs = 4 >> bl;
+ AVFrame *f = s->frames[CUR_FRAME].tf.f;
+ ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1];
+ int bytesperpixel = s->bytesperpixel;
+
+ if (bl == BL_8X8) {
+ bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p);
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ } else if (col + hbs < s->cols) { // FIXME why not <=?
+ if (row + hbs < s->rows) { // FIXME why not <=?
+ bp = vp8_rac_get_tree(&s->c, vp9_partition_tree, p);
+ switch (bp) {
+ case PARTITION_NONE:
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ break;
+ case PARTITION_H:
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 8 * uv_stride >> s->ss_v;
+ decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, bl, bp);
+ break;
+ case PARTITION_V:
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ yoff += hbs * 8 * bytesperpixel;
+ uvoff += hbs * 8 * bytesperpixel >> s->ss_h;
+ decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, bl, bp);
+ break;
+ case PARTITION_SPLIT:
+ decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb(ctx, row, col + hbs, lflvl,
+ yoff + 8 * hbs * bytesperpixel,
+ uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1);
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 8 * uv_stride >> s->ss_v;
+ decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb(ctx, row + hbs, col + hbs, lflvl,
+ yoff + 8 * hbs * bytesperpixel,
+ uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1);
+ break;
+ default:
+ av_assert0(0);
+ }
+ } else if (vp56_rac_get_prob_branchy(&s->c, p[1])) {
+ bp = PARTITION_SPLIT;
+ decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb(ctx, row, col + hbs, lflvl,
+ yoff + 8 * hbs * bytesperpixel,
+ uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1);
+ } else {
+ bp = PARTITION_H;
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ }
+ } else if (row + hbs < s->rows) { // FIXME why not <=?
+ if (vp56_rac_get_prob_branchy(&s->c, p[2])) {
+ bp = PARTITION_SPLIT;
+ decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 8 * uv_stride >> s->ss_v;
+ decode_sb(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
+ } else {
+ bp = PARTITION_V;
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, bl, bp);
+ }
+ } else {
+ bp = PARTITION_SPLIT;
+ decode_sb(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
+ }
+ s->counts.partition[bl][c][bp]++;
+}
+
+static void decode_sb_mem(AVCodecContext *ctx, int row, int col, struct VP9Filter *lflvl,
+ ptrdiff_t yoff, ptrdiff_t uvoff, enum BlockLevel bl)
+{
+ VP9Context *s = ctx->priv_data;
+ VP9Block *b = s->b;
+ ptrdiff_t hbs = 4 >> bl;
+ AVFrame *f = s->frames[CUR_FRAME].tf.f;
+ ptrdiff_t y_stride = f->linesize[0], uv_stride = f->linesize[1];
+ int bytesperpixel = s->bytesperpixel;
+
+ if (bl == BL_8X8) {
+ av_assert2(b->bl == BL_8X8);
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp);
+ } else if (s->b->bl == bl) {
+ decode_b(ctx, row, col, lflvl, yoff, uvoff, b->bl, b->bp);
+ if (b->bp == PARTITION_H && row + hbs < s->rows) {
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 8 * uv_stride >> s->ss_v;
+ decode_b(ctx, row + hbs, col, lflvl, yoff, uvoff, b->bl, b->bp);
+ } else if (b->bp == PARTITION_V && col + hbs < s->cols) {
+ yoff += hbs * 8 * bytesperpixel;
+ uvoff += hbs * 8 * bytesperpixel >> s->ss_h;
+ decode_b(ctx, row, col + hbs, lflvl, yoff, uvoff, b->bl, b->bp);
+ }
+ } else {
+ decode_sb_mem(ctx, row, col, lflvl, yoff, uvoff, bl + 1);
+ if (col + hbs < s->cols) { // FIXME why not <=?
+ if (row + hbs < s->rows) {
+ decode_sb_mem(ctx, row, col + hbs, lflvl, yoff + 8 * hbs * bytesperpixel,
+ uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1);
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 8 * uv_stride >> s->ss_v;
+ decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
+ decode_sb_mem(ctx, row + hbs, col + hbs, lflvl,
+ yoff + 8 * hbs * bytesperpixel,
+ uvoff + (8 * hbs * bytesperpixel >> s->ss_h), bl + 1);
+ } else {
+ yoff += hbs * 8 * bytesperpixel;
+ uvoff += hbs * 8 * bytesperpixel >> s->ss_h;
+ decode_sb_mem(ctx, row, col + hbs, lflvl, yoff, uvoff, bl + 1);
+ }
+ } else if (row + hbs < s->rows) {
+ yoff += hbs * 8 * y_stride;
+ uvoff += hbs * 8 * uv_stride >> s->ss_v;
+ decode_sb_mem(ctx, row + hbs, col, lflvl, yoff, uvoff, bl + 1);
+ }
+ }
+}
+
+static av_always_inline void filter_plane_cols(VP9Context *s, int col, int ss_h, int ss_v,
+ uint8_t *lvl, uint8_t (*mask)[4],
+ uint8_t *dst, ptrdiff_t ls)
+{
+ int y, x, bytesperpixel = s->bytesperpixel;
+
+ // filter edges between columns (e.g. block1 | block2)
+ for (y = 0; y < 8; y += 2 << ss_v, dst += 16 * ls, lvl += 16 << ss_v) {
+ uint8_t *ptr = dst, *l = lvl, *hmask1 = mask[y], *hmask2 = mask[y + 1 + ss_v];
+ unsigned hm1 = hmask1[0] | hmask1[1] | hmask1[2], hm13 = hmask1[3];
+ unsigned hm2 = hmask2[1] | hmask2[2], hm23 = hmask2[3];
+ unsigned hm = hm1 | hm2 | hm13 | hm23;
+
+ for (x = 1; hm & ~(x - 1); x <<= 1, ptr += 8 * bytesperpixel >> ss_h) {
+ if (col || x > 1) {
+ if (hm1 & x) {
+ int L = *l, H = L >> 4;
+ int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+ if (hmask1[0] & x) {
+ if (hmask2[0] & x) {
+ av_assert2(l[8 << ss_v] == L);
+ s->dsp.loop_filter_16[0](ptr, ls, E, I, H);
+ } else {
+ s->dsp.loop_filter_8[2][0](ptr, ls, E, I, H);
+ }
+ } else if (hm2 & x) {
+ L = l[8 << ss_v];
+ H |= (L >> 4) << 8;
+ E |= s->filter.mblim_lut[L] << 8;
+ I |= s->filter.lim_lut[L] << 8;
+ s->dsp.loop_filter_mix2[!!(hmask1[1] & x)]
+ [!!(hmask2[1] & x)]
+ [0](ptr, ls, E, I, H);
+ } else {
+ s->dsp.loop_filter_8[!!(hmask1[1] & x)]
+ [0](ptr, ls, E, I, H);
+ }
+ } else if (hm2 & x) {
+ int L = l[8 << ss_v], H = L >> 4;
+ int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+ s->dsp.loop_filter_8[!!(hmask2[1] & x)]
+ [0](ptr + 8 * ls, ls, E, I, H);
+ }
+ }
+ if (ss_h) {
+ if (x & 0xAA)
+ l += 2;
+ } else {
+ if (hm13 & x) {
+ int L = *l, H = L >> 4;
+ int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+ if (hm23 & x) {
+ L = l[8 << ss_v];
+ H |= (L >> 4) << 8;
+ E |= s->filter.mblim_lut[L] << 8;
+ I |= s->filter.lim_lut[L] << 8;
+ s->dsp.loop_filter_mix2[0][0][0](ptr + 4 * bytesperpixel, ls, E, I, H);
+ } else {
+ s->dsp.loop_filter_8[0][0](ptr + 4 * bytesperpixel, ls, E, I, H);
+ }
+ } else if (hm23 & x) {
+ int L = l[8 << ss_v], H = L >> 4;
+ int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+ s->dsp.loop_filter_8[0][0](ptr + 8 * ls + 4 * bytesperpixel, ls, E, I, H);
+ }
+ l++;
+ }
+ }
+ }
+}
+
+static av_always_inline void filter_plane_rows(VP9Context *s, int row, int ss_h, int ss_v,
+ uint8_t *lvl, uint8_t (*mask)[4],
+ uint8_t *dst, ptrdiff_t ls)
+{
+ int y, x, bytesperpixel = s->bytesperpixel;
+
+ // block1
+ // filter edges between rows (e.g. ------)
+ // block2
+ for (y = 0; y < 8; y++, dst += 8 * ls >> ss_v) {
+ uint8_t *ptr = dst, *l = lvl, *vmask = mask[y];
+ unsigned vm = vmask[0] | vmask[1] | vmask[2], vm3 = vmask[3];
+
+ for (x = 1; vm & ~(x - 1); x <<= (2 << ss_h), ptr += 16 * bytesperpixel, l += 2 << ss_h) {
+ if (row || y) {
+ if (vm & x) {
+ int L = *l, H = L >> 4;
+ int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+ if (vmask[0] & x) {
+ if (vmask[0] & (x << (1 + ss_h))) {
+ av_assert2(l[1 + ss_h] == L);
+ s->dsp.loop_filter_16[1](ptr, ls, E, I, H);
+ } else {
+ s->dsp.loop_filter_8[2][1](ptr, ls, E, I, H);
+ }
+ } else if (vm & (x << (1 + ss_h))) {
+ L = l[1 + ss_h];
+ H |= (L >> 4) << 8;
+ E |= s->filter.mblim_lut[L] << 8;
+ I |= s->filter.lim_lut[L] << 8;
+ s->dsp.loop_filter_mix2[!!(vmask[1] & x)]
+ [!!(vmask[1] & (x << (1 + ss_h)))]
+ [1](ptr, ls, E, I, H);
+ } else {
+ s->dsp.loop_filter_8[!!(vmask[1] & x)]
+ [1](ptr, ls, E, I, H);
+ }
+ } else if (vm & (x << (1 + ss_h))) {
+ int L = l[1 + ss_h], H = L >> 4;
+ int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+ s->dsp.loop_filter_8[!!(vmask[1] & (x << (1 + ss_h)))]
+ [1](ptr + 8 * bytesperpixel, ls, E, I, H);
+ }
+ }
+ if (!ss_v) {
+ if (vm3 & x) {
+ int L = *l, H = L >> 4;
+ int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+ if (vm3 & (x << (1 + ss_h))) {
+ L = l[1 + ss_h];
+ H |= (L >> 4) << 8;
+ E |= s->filter.mblim_lut[L] << 8;
+ I |= s->filter.lim_lut[L] << 8;
+ s->dsp.loop_filter_mix2[0][0][1](ptr + ls * 4, ls, E, I, H);
+ } else {
+ s->dsp.loop_filter_8[0][1](ptr + ls * 4, ls, E, I, H);
+ }
+ } else if (vm3 & (x << (1 + ss_h))) {
+ int L = l[1 + ss_h], H = L >> 4;
+ int E = s->filter.mblim_lut[L], I = s->filter.lim_lut[L];
+
+ s->dsp.loop_filter_8[0][1](ptr + ls * 4 + 8 * bytesperpixel, ls, E, I, H);
+ }
+ }
+ }
+ if (ss_v) {
+ if (y & 1)
+ lvl += 16;
+ } else {
+ lvl += 8;
+ }
+ }
+}
+
+static void loopfilter_sb(AVCodecContext *ctx, struct VP9Filter *lflvl,
+ int row, int col, ptrdiff_t yoff, ptrdiff_t uvoff)
+{
+ VP9Context *s = ctx->priv_data;
+ AVFrame *f = s->frames[CUR_FRAME].tf.f;
+ uint8_t *dst = f->data[0] + yoff;
+ ptrdiff_t ls_y = f->linesize[0], ls_uv = f->linesize[1];
+ uint8_t (*uv_masks)[8][4] = lflvl->mask[s->ss_h | s->ss_v];
+ int p;
+
+ // FIXME in how far can we interleave the v/h loopfilter calls? E.g.
+ // if you think of them as acting on a 8x8 block max, we can interleave
+ // each v/h within the single x loop, but that only works if we work on
+ // 8 pixel blocks, and we won't always do that (we want at least 16px
+ // to use SSE2 optimizations, perhaps 32 for AVX2)
+
+ filter_plane_cols(s, col, 0, 0, lflvl->level, lflvl->mask[0][0], dst, ls_y);
+ filter_plane_rows(s, row, 0, 0, lflvl->level, lflvl->mask[0][1], dst, ls_y);
+
+ for (p = 0; p < 2; p++) {
+ dst = f->data[1 + p] + uvoff;
+ filter_plane_cols(s, col, s->ss_h, s->ss_v, lflvl->level, uv_masks[0], dst, ls_uv);
+ filter_plane_rows(s, row, s->ss_h, s->ss_v, lflvl->level, uv_masks[1], dst, ls_uv);
+ }
+}
+
+static void set_tile_offset(int *start, int *end, int idx, int log2_n, int n)
+{
+ int sb_start = ( idx * n) >> log2_n;
+ int sb_end = ((idx + 1) * n) >> log2_n;
+ *start = FFMIN(sb_start, n) << 3;
+ *end = FFMIN(sb_end, n) << 3;
+}
+
+static av_always_inline void adapt_prob(uint8_t *p, unsigned ct0, unsigned ct1,
+ int max_count, int update_factor)
+{
+ unsigned ct = ct0 + ct1, p2, p1;
+
+ if (!ct)
+ return;
+
+ update_factor = FASTDIV(update_factor * FFMIN(ct, max_count), max_count);
+ p1 = *p;
+ p2 = ((((int64_t) ct0) << 8) + (ct >> 1)) / ct;
+ p2 = av_clip(p2, 1, 255);
+
+ // (p1 * (256 - update_factor) + p2 * update_factor + 128) >> 8
+ *p = p1 + (((p2 - p1) * update_factor + 128) >> 8);
+}
+
+static void adapt_probs(VP9Context *s)
+{
+ int i, j, k, l, m;
+ prob_context *p = &s->prob_ctx[s->framectxid].p;
+ int uf = (s->keyframe || s->intraonly || !s->last_keyframe) ? 112 : 128;
+
+ // coefficients
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 2; j++)
+ for (k = 0; k < 2; k++)
+ for (l = 0; l < 6; l++)
+ for (m = 0; m < 6; m++) {
+ uint8_t *pp = s->prob_ctx[s->framectxid].coef[i][j][k][l][m];
+ unsigned *e = s->counts.eob[i][j][k][l][m];
+ unsigned *c = s->counts.coef[i][j][k][l][m];
+
+ if (l == 0 && m >= 3) // dc only has 3 pt
+ break;
+
+ adapt_prob(&pp[0], e[0], e[1], 24, uf);
+ adapt_prob(&pp[1], c[0], c[1] + c[2], 24, uf);
+ adapt_prob(&pp[2], c[1], c[2], 24, uf);
+ }
+
+ if (s->keyframe || s->intraonly) {
+ memcpy(p->skip, s->prob.p.skip, sizeof(p->skip));
+ memcpy(p->tx32p, s->prob.p.tx32p, sizeof(p->tx32p));
+ memcpy(p->tx16p, s->prob.p.tx16p, sizeof(p->tx16p));
+ memcpy(p->tx8p, s->prob.p.tx8p, sizeof(p->tx8p));
+ return;
+ }
+
+ // skip flag
+ for (i = 0; i < 3; i++)
+ adapt_prob(&p->skip[i], s->counts.skip[i][0], s->counts.skip[i][1], 20, 128);
+
+ // intra/inter flag
+ for (i = 0; i < 4; i++)
+ adapt_prob(&p->intra[i], s->counts.intra[i][0], s->counts.intra[i][1], 20, 128);
+
+ // comppred flag
+ if (s->comppredmode == PRED_SWITCHABLE) {
+ for (i = 0; i < 5; i++)
+ adapt_prob(&p->comp[i], s->counts.comp[i][0], s->counts.comp[i][1], 20, 128);
+ }
+
+ // reference frames
+ if (s->comppredmode != PRED_SINGLEREF) {
+ for (i = 0; i < 5; i++)
+ adapt_prob(&p->comp_ref[i], s->counts.comp_ref[i][0],
+ s->counts.comp_ref[i][1], 20, 128);
+ }
+
+ if (s->comppredmode != PRED_COMPREF) {
+ for (i = 0; i < 5; i++) {
+ uint8_t *pp = p->single_ref[i];
+ unsigned (*c)[2] = s->counts.single_ref[i];
+
+ adapt_prob(&pp[0], c[0][0], c[0][1], 20, 128);
+ adapt_prob(&pp[1], c[1][0], c[1][1], 20, 128);
+ }
+ }
+
+ // block partitioning
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 4; j++) {
+ uint8_t *pp = p->partition[i][j];
+ unsigned *c = s->counts.partition[i][j];
+
+ adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
+ adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
+ adapt_prob(&pp[2], c[2], c[3], 20, 128);
+ }
+
+ // tx size
+ if (s->txfmmode == TX_SWITCHABLE) {
+ for (i = 0; i < 2; i++) {
+ unsigned *c16 = s->counts.tx16p[i], *c32 = s->counts.tx32p[i];
+
+ adapt_prob(&p->tx8p[i], s->counts.tx8p[i][0], s->counts.tx8p[i][1], 20, 128);
+ adapt_prob(&p->tx16p[i][0], c16[0], c16[1] + c16[2], 20, 128);
+ adapt_prob(&p->tx16p[i][1], c16[1], c16[2], 20, 128);
+ adapt_prob(&p->tx32p[i][0], c32[0], c32[1] + c32[2] + c32[3], 20, 128);
+ adapt_prob(&p->tx32p[i][1], c32[1], c32[2] + c32[3], 20, 128);
+ adapt_prob(&p->tx32p[i][2], c32[2], c32[3], 20, 128);
+ }
+ }
+
+ // interpolation filter
+ if (s->filtermode == FILTER_SWITCHABLE) {
+ for (i = 0; i < 4; i++) {
+ uint8_t *pp = p->filter[i];
+ unsigned *c = s->counts.filter[i];
+
+ adapt_prob(&pp[0], c[0], c[1] + c[2], 20, 128);
+ adapt_prob(&pp[1], c[1], c[2], 20, 128);
+ }
+ }
+
+ // inter modes
+ for (i = 0; i < 7; i++) {
+ uint8_t *pp = p->mv_mode[i];
+ unsigned *c = s->counts.mv_mode[i];
+
+ adapt_prob(&pp[0], c[2], c[1] + c[0] + c[3], 20, 128);
+ adapt_prob(&pp[1], c[0], c[1] + c[3], 20, 128);
+ adapt_prob(&pp[2], c[1], c[3], 20, 128);
+ }
+
+ // mv joints
+ {
+ uint8_t *pp = p->mv_joint;
+ unsigned *c = s->counts.mv_joint;
+
+ adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
+ adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
+ adapt_prob(&pp[2], c[2], c[3], 20, 128);
+ }
+
+ // mv components
+ for (i = 0; i < 2; i++) {
+ uint8_t *pp;
+ unsigned *c, (*c2)[2], sum;
+
+ adapt_prob(&p->mv_comp[i].sign, s->counts.mv_comp[i].sign[0],
+ s->counts.mv_comp[i].sign[1], 20, 128);
+
+ pp = p->mv_comp[i].classes;
+ c = s->counts.mv_comp[i].classes;
+ sum = c[1] + c[2] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9] + c[10];
+ adapt_prob(&pp[0], c[0], sum, 20, 128);
+ sum -= c[1];
+ adapt_prob(&pp[1], c[1], sum, 20, 128);
+ sum -= c[2] + c[3];
+ adapt_prob(&pp[2], c[2] + c[3], sum, 20, 128);
+ adapt_prob(&pp[3], c[2], c[3], 20, 128);
+ sum -= c[4] + c[5];
+ adapt_prob(&pp[4], c[4] + c[5], sum, 20, 128);
+ adapt_prob(&pp[5], c[4], c[5], 20, 128);
+ sum -= c[6];
+ adapt_prob(&pp[6], c[6], sum, 20, 128);
+ adapt_prob(&pp[7], c[7] + c[8], c[9] + c[10], 20, 128);
+ adapt_prob(&pp[8], c[7], c[8], 20, 128);
+ adapt_prob(&pp[9], c[9], c[10], 20, 128);
+
+ adapt_prob(&p->mv_comp[i].class0, s->counts.mv_comp[i].class0[0],
+ s->counts.mv_comp[i].class0[1], 20, 128);
+ pp = p->mv_comp[i].bits;
+ c2 = s->counts.mv_comp[i].bits;
+ for (j = 0; j < 10; j++)
+ adapt_prob(&pp[j], c2[j][0], c2[j][1], 20, 128);
+
+ for (j = 0; j < 2; j++) {
+ pp = p->mv_comp[i].class0_fp[j];
+ c = s->counts.mv_comp[i].class0_fp[j];
+ adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
+ adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
+ adapt_prob(&pp[2], c[2], c[3], 20, 128);
+ }
+ pp = p->mv_comp[i].fp;
+ c = s->counts.mv_comp[i].fp;
+ adapt_prob(&pp[0], c[0], c[1] + c[2] + c[3], 20, 128);
+ adapt_prob(&pp[1], c[1], c[2] + c[3], 20, 128);
+ adapt_prob(&pp[2], c[2], c[3], 20, 128);
+
+ if (s->highprecisionmvs) {
+ adapt_prob(&p->mv_comp[i].class0_hp, s->counts.mv_comp[i].class0_hp[0],
+ s->counts.mv_comp[i].class0_hp[1], 20, 128);
+ adapt_prob(&p->mv_comp[i].hp, s->counts.mv_comp[i].hp[0],
+ s->counts.mv_comp[i].hp[1], 20, 128);
+ }
+ }
+
+ // y intra modes
+ for (i = 0; i < 4; i++) {
+ uint8_t *pp = p->y_mode[i];
+ unsigned *c = s->counts.y_mode[i], sum, s2;
+
+ sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9];
+ adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128);
+ sum -= c[TM_VP8_PRED];
+ adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128);
+ sum -= c[VERT_PRED];
+ adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128);
+ s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED];
+ sum -= s2;
+ adapt_prob(&pp[3], s2, sum, 20, 128);
+ s2 -= c[HOR_PRED];
+ adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128);
+ adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], 20, 128);
+ sum -= c[DIAG_DOWN_LEFT_PRED];
+ adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128);
+ sum -= c[VERT_LEFT_PRED];
+ adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128);
+ adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128);
+ }
+
+ // uv intra modes
+ for (i = 0; i < 10; i++) {
+ uint8_t *pp = p->uv_mode[i];
+ unsigned *c = s->counts.uv_mode[i], sum, s2;
+
+ sum = c[0] + c[1] + c[3] + c[4] + c[5] + c[6] + c[7] + c[8] + c[9];
+ adapt_prob(&pp[0], c[DC_PRED], sum, 20, 128);
+ sum -= c[TM_VP8_PRED];
+ adapt_prob(&pp[1], c[TM_VP8_PRED], sum, 20, 128);
+ sum -= c[VERT_PRED];
+ adapt_prob(&pp[2], c[VERT_PRED], sum, 20, 128);
+ s2 = c[HOR_PRED] + c[DIAG_DOWN_RIGHT_PRED] + c[VERT_RIGHT_PRED];
+ sum -= s2;
+ adapt_prob(&pp[3], s2, sum, 20, 128);
+ s2 -= c[HOR_PRED];
+ adapt_prob(&pp[4], c[HOR_PRED], s2, 20, 128);
+ adapt_prob(&pp[5], c[DIAG_DOWN_RIGHT_PRED], c[VERT_RIGHT_PRED], 20, 128);
+ sum -= c[DIAG_DOWN_LEFT_PRED];
+ adapt_prob(&pp[6], c[DIAG_DOWN_LEFT_PRED], sum, 20, 128);
+ sum -= c[VERT_LEFT_PRED];
+ adapt_prob(&pp[7], c[VERT_LEFT_PRED], sum, 20, 128);
+ adapt_prob(&pp[8], c[HOR_DOWN_PRED], c[HOR_UP_PRED], 20, 128);
+ }
+}
+
+static void free_buffers(VP9Context *s)
+{
+ av_freep(&s->intra_pred_data[0]);
+ av_freep(&s->b_base);
+ av_freep(&s->block_base);
+}
+
+static av_cold int vp9_decode_free(AVCodecContext *ctx)
+{
+ VP9Context *s = ctx->priv_data;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ if (s->frames[i].tf.f->data[0])
+ vp9_unref_frame(ctx, &s->frames[i]);
+ av_frame_free(&s->frames[i].tf.f);
+ }
+ for (i = 0; i < 8; i++) {
+ if (s->refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->refs[i]);
+ av_frame_free(&s->refs[i].f);
+ if (s->next_refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->next_refs[i]);
+ av_frame_free(&s->next_refs[i].f);
+ }
+ free_buffers(s);
+ av_freep(&s->c_b);
+ s->c_b_size = 0;
+
+ return 0;
+}
+
+
+static int vp9_decode_frame(AVCodecContext *ctx, void *frame,
+ int *got_frame, AVPacket *pkt)
+{
+ const uint8_t *data = pkt->data;
+ int size = pkt->size;
+ VP9Context *s = ctx->priv_data;
+ int res, tile_row, tile_col, i, ref, row, col;
+ int retain_segmap_ref = s->frames[REF_FRAME_SEGMAP].segmentation_map &&
+ (!s->segmentation.enabled || !s->segmentation.update_map);
+ ptrdiff_t yoff, uvoff, ls_y, ls_uv;
+ AVFrame *f;
+ int bytesperpixel;
+
+ if ((res = decode_frame_header(ctx, data, size, &ref)) < 0) {
+ return res;
+ } else if (res == 0) {
+ if (!s->refs[ref].f->data[0]) {
+ av_log(ctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref);
+ return AVERROR_INVALIDDATA;
+ }
+ if ((res = av_frame_ref(frame, s->refs[ref].f)) < 0)
+ return res;
+ ((AVFrame *)frame)->pkt_pts = pkt->pts;
+ ((AVFrame *)frame)->pkt_dts = pkt->dts;
+ for (i = 0; i < 8; i++) {
+ if (s->next_refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->next_refs[i]);
+ if (s->refs[i].f->data[0] &&
+ (res = ff_thread_ref_frame(&s->next_refs[i], &s->refs[i])) < 0)
+ return res;
+ }
+ *got_frame = 1;
+ return pkt->size;
+ }
+ data += res;
+ size -= res;
+
+ if (!retain_segmap_ref || s->keyframe || s->intraonly) {
+ if (s->frames[REF_FRAME_SEGMAP].tf.f->data[0])
+ vp9_unref_frame(ctx, &s->frames[REF_FRAME_SEGMAP]);
+ if (!s->keyframe && !s->intraonly && !s->errorres && s->frames[CUR_FRAME].tf.f->data[0] &&
+ (res = vp9_ref_frame(ctx, &s->frames[REF_FRAME_SEGMAP], &s->frames[CUR_FRAME])) < 0)
+ return res;
+ }
+ if (s->frames[REF_FRAME_MVPAIR].tf.f->data[0])
+ vp9_unref_frame(ctx, &s->frames[REF_FRAME_MVPAIR]);
+ if (!s->intraonly && !s->keyframe && !s->errorres && s->frames[CUR_FRAME].tf.f->data[0] &&
+ (res = vp9_ref_frame(ctx, &s->frames[REF_FRAME_MVPAIR], &s->frames[CUR_FRAME])) < 0)
+ return res;
+ if (s->frames[CUR_FRAME].tf.f->data[0])
+ vp9_unref_frame(ctx, &s->frames[CUR_FRAME]);
+ if ((res = vp9_alloc_frame(ctx, &s->frames[CUR_FRAME])) < 0)
+ return res;
+ f = s->frames[CUR_FRAME].tf.f;
+ f->key_frame = s->keyframe;
+ f->pict_type = (s->keyframe || s->intraonly) ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
+ ls_y = f->linesize[0];
+ ls_uv =f->linesize[1];
+
+ // ref frame setup
+ for (i = 0; i < 8; i++) {
+ if (s->next_refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->next_refs[i]);
+ if (s->refreshrefmask & (1 << i)) {
+ res = ff_thread_ref_frame(&s->next_refs[i], &s->frames[CUR_FRAME].tf);
+ } else if (s->refs[i].f->data[0]) {
+ res = ff_thread_ref_frame(&s->next_refs[i], &s->refs[i]);
+ }
+ if (res < 0)
+ return res;
+ }
+
+ // main tile decode loop
+ bytesperpixel = s->bytesperpixel;
+ memset(s->above_partition_ctx, 0, s->cols);
+ memset(s->above_skip_ctx, 0, s->cols);
+ if (s->keyframe || s->intraonly) {
+ memset(s->above_mode_ctx, DC_PRED, s->cols * 2);
+ } else {
+ memset(s->above_mode_ctx, NEARESTMV, s->cols);
+ }
+ memset(s->above_y_nnz_ctx, 0, s->sb_cols * 16);
+ memset(s->above_uv_nnz_ctx[0], 0, s->sb_cols * 16 >> s->ss_h);
+ memset(s->above_uv_nnz_ctx[1], 0, s->sb_cols * 16 >> s->ss_h);
+ memset(s->above_segpred_ctx, 0, s->cols);
+ s->pass = s->frames[CUR_FRAME].uses_2pass =
+ ctx->active_thread_type == FF_THREAD_FRAME && s->refreshctx && !s->parallelmode;
+ if ((res = update_block_buffers(ctx)) < 0) {
+ av_log(ctx, AV_LOG_ERROR,
+ "Failed to allocate block buffers\n");
+ return res;
+ }
+ if (s->refreshctx && s->parallelmode) {
+ int j, k, l, m;
+
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 2; j++)
+ for (k = 0; k < 2; k++)
+ for (l = 0; l < 6; l++)
+ for (m = 0; m < 6; m++)
+ memcpy(s->prob_ctx[s->framectxid].coef[i][j][k][l][m],
+ s->prob.coef[i][j][k][l][m], 3);
+ if (s->txfmmode == i)
+ break;
+ }
+ s->prob_ctx[s->framectxid].p = s->prob.p;
+ ff_thread_finish_setup(ctx);
+ } else if (!s->refreshctx) {
+ ff_thread_finish_setup(ctx);
+ }
+
+ do {
+ yoff = uvoff = 0;
+ s->b = s->b_base;
+ s->block = s->block_base;
+ s->uvblock[0] = s->uvblock_base[0];
+ s->uvblock[1] = s->uvblock_base[1];
+ s->eob = s->eob_base;
+ s->uveob[0] = s->uveob_base[0];
+ s->uveob[1] = s->uveob_base[1];
+
+ for (tile_row = 0; tile_row < s->tiling.tile_rows; tile_row++) {
+ set_tile_offset(&s->tiling.tile_row_start, &s->tiling.tile_row_end,
+ tile_row, s->tiling.log2_tile_rows, s->sb_rows);
+ if (s->pass != 2) {
+ for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
+ int64_t tile_size;
+
+ if (tile_col == s->tiling.tile_cols - 1 &&
+ tile_row == s->tiling.tile_rows - 1) {
+ tile_size = size;
+ } else {
+ tile_size = AV_RB32(data);
+ data += 4;
+ size -= 4;
+ }
+ if (tile_size > size) {
+ ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);
+ return AVERROR_INVALIDDATA;
+ }
+ res = ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size);
+ if (res < 0)
+ return res;
+ if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) { // marker bit
+ ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);
+ return AVERROR_INVALIDDATA;
+ }
+ data += tile_size;
+ size -= tile_size;
+ }
+ }
+
+ for (row = s->tiling.tile_row_start; row < s->tiling.tile_row_end;
+ row += 8, yoff += ls_y * 64, uvoff += ls_uv * 64 >> s->ss_v) {
+ struct VP9Filter *lflvl_ptr = s->lflvl;
+ ptrdiff_t yoff2 = yoff, uvoff2 = uvoff;
+
+ for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) {
+ set_tile_offset(&s->tiling.tile_col_start, &s->tiling.tile_col_end,
+ tile_col, s->tiling.log2_tile_cols, s->sb_cols);
+
+ if (s->pass != 2) {
+ memset(s->left_partition_ctx, 0, 8);
+ memset(s->left_skip_ctx, 0, 8);
+ if (s->keyframe || s->intraonly) {
+ memset(s->left_mode_ctx, DC_PRED, 16);
+ } else {
+ memset(s->left_mode_ctx, NEARESTMV, 8);
+ }
+ memset(s->left_y_nnz_ctx, 0, 16);
+ memset(s->left_uv_nnz_ctx, 0, 32);
+ memset(s->left_segpred_ctx, 0, 8);
+
+ memcpy(&s->c, &s->c_b[tile_col], sizeof(s->c));
+ }
+
+ for (col = s->tiling.tile_col_start;
+ col < s->tiling.tile_col_end;
+ col += 8, yoff2 += 64 * bytesperpixel,
+ uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) {
+ // FIXME integrate with lf code (i.e. zero after each
+ // use, similar to invtxfm coefficients, or similar)
+ if (s->pass != 1) {
+ memset(lflvl_ptr->mask, 0, sizeof(lflvl_ptr->mask));
+ }
+
+ if (s->pass == 2) {
+ decode_sb_mem(ctx, row, col, lflvl_ptr,
+ yoff2, uvoff2, BL_64X64);
+ } else {
+ decode_sb(ctx, row, col, lflvl_ptr,
+ yoff2, uvoff2, BL_64X64);
+ }
+ }
+ if (s->pass != 2) {
+ memcpy(&s->c_b[tile_col], &s->c, sizeof(s->c));
+ }
+ }
+
+ if (s->pass == 1) {
+ continue;
+ }
+
+ // backup pre-loopfilter reconstruction data for intra
+ // prediction of next row of sb64s
+ if (row + 8 < s->rows) {
+ memcpy(s->intra_pred_data[0],
+ f->data[0] + yoff + 63 * ls_y,
+ 8 * s->cols * bytesperpixel);
+ memcpy(s->intra_pred_data[1],
+ f->data[1] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv,
+ 8 * s->cols * bytesperpixel >> s->ss_h);
+ memcpy(s->intra_pred_data[2],
+ f->data[2] + uvoff + ((64 >> s->ss_v) - 1) * ls_uv,
+ 8 * s->cols * bytesperpixel >> s->ss_h);
+ }
+
+ // loopfilter one row
+ if (s->filter.level) {
+ yoff2 = yoff;
+ uvoff2 = uvoff;
+ lflvl_ptr = s->lflvl;
+ for (col = 0; col < s->cols;
+ col += 8, yoff2 += 64 * bytesperpixel,
+ uvoff2 += 64 * bytesperpixel >> s->ss_h, lflvl_ptr++) {
+ loopfilter_sb(ctx, lflvl_ptr, row, col, yoff2, uvoff2);
+ }
+ }
+
+ // FIXME maybe we can make this more finegrained by running the
+ // loopfilter per-block instead of after each sbrow
+ // In fact that would also make intra pred left preparation easier?
+ ff_thread_report_progress(&s->frames[CUR_FRAME].tf, row >> 3, 0);
+ }
+ }
+
+ if (s->pass < 2 && s->refreshctx && !s->parallelmode) {
+ adapt_probs(s);
+ ff_thread_finish_setup(ctx);
+ }
+ } while (s->pass++ == 1);
+ ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0);
+
+ // ref frame setup
+ for (i = 0; i < 8; i++) {
+ if (s->refs[i].f->data[0])
+ ff_thread_release_buffer(ctx, &s->refs[i]);
+ ff_thread_ref_frame(&s->refs[i], &s->next_refs[i]);
+ }
+
+ if (!s->invisible) {
+ if ((res = av_frame_ref(frame, s->frames[CUR_FRAME].tf.f)) < 0)
+ return res;
+ *got_frame = 1;
+ }
+
+ return pkt->size;
+}
+
+static void vp9_decode_flush(AVCodecContext *ctx)
+{
+ VP9Context *s = ctx->priv_data;
+ int i;
+
+ for (i = 0; i < 3; i++)
+ vp9_unref_frame(ctx, &s->frames[i]);
+ for (i = 0; i < 8; i++)
+ ff_thread_release_buffer(ctx, &s->refs[i]);
+}
+
+static int init_frames(AVCodecContext *ctx)
+{
+ VP9Context *s = ctx->priv_data;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ s->frames[i].tf.f = av_frame_alloc();
+ if (!s->frames[i].tf.f) {
+ vp9_decode_free(ctx);
+ av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i);
+ return AVERROR(ENOMEM);
+ }
+ }
+ for (i = 0; i < 8; i++) {
+ s->refs[i].f = av_frame_alloc();
+ s->next_refs[i].f = av_frame_alloc();
+ if (!s->refs[i].f || !s->next_refs[i].f) {
+ vp9_decode_free(ctx);
+ av_log(ctx, AV_LOG_ERROR, "Failed to allocate frame buffer %d\n", i);
+ return AVERROR(ENOMEM);
+ }
+ }
+
+ return 0;
+}
+
+static av_cold int vp9_decode_init(AVCodecContext *ctx)
+{
+ VP9Context *s = ctx->priv_data;
+
+ ctx->internal->allocate_progress = 1;
+ s->last_bpp = 0;
+ s->filter.sharpness = -1;
+
+ return init_frames(ctx);
+}
+
+static av_cold int vp9_decode_init_thread_copy(AVCodecContext *avctx)
+{
+ return init_frames(avctx);
+}
+
+static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)
+{
+ int i, res;
+ VP9Context *s = dst->priv_data, *ssrc = src->priv_data;
+
+ // detect size changes in other threads
+ if (s->intra_pred_data[0] &&
+ (!ssrc->intra_pred_data[0] || s->cols != ssrc->cols || s->rows != ssrc->rows)) {
+ free_buffers(s);
+ }
+
+ for (i = 0; i < 3; i++) {
+ if (s->frames[i].tf.f->data[0])
+ vp9_unref_frame(dst, &s->frames[i]);
+ if (ssrc->frames[i].tf.f->data[0]) {
+ if ((res = vp9_ref_frame(dst, &s->frames[i], &ssrc->frames[i])) < 0)
+ return res;
+ }
+ }
+ for (i = 0; i < 8; i++) {
+ if (s->refs[i].f->data[0])
+ ff_thread_release_buffer(dst, &s->refs[i]);
+ if (ssrc->next_refs[i].f->data[0]) {
+ if ((res = ff_thread_ref_frame(&s->refs[i], &ssrc->next_refs[i])) < 0)
+ return res;
+ }
+ }
+
+ s->invisible = ssrc->invisible;
+ s->keyframe = ssrc->keyframe;
+ s->intraonly = ssrc->intraonly;
+ s->ss_v = ssrc->ss_v;
+ s->ss_h = ssrc->ss_h;
+ s->segmentation.enabled = ssrc->segmentation.enabled;
+ s->segmentation.update_map = ssrc->segmentation.update_map;
+ s->bytesperpixel = ssrc->bytesperpixel;
+ s->bpp = ssrc->bpp;
+ s->bpp_index = ssrc->bpp_index;
+ memcpy(&s->prob_ctx, &ssrc->prob_ctx, sizeof(s->prob_ctx));
+ memcpy(&s->lf_delta, &ssrc->lf_delta, sizeof(s->lf_delta));
+ if (ssrc->segmentation.enabled) {
+ memcpy(&s->segmentation.feat, &ssrc->segmentation.feat,
+ sizeof(s->segmentation.feat));
+ }
+
+ return 0;
+}
+
+static const AVProfile profiles[] = {
+ { FF_PROFILE_VP9_0, "Profile 0" },
+ { FF_PROFILE_VP9_1, "Profile 1" },
+ { FF_PROFILE_VP9_2, "Profile 2" },
+ { FF_PROFILE_VP9_3, "Profile 3" },
+ { FF_PROFILE_UNKNOWN },
+};
+
+AVCodec ff_vp9_decoder = {
+ .name = "vp9",
+ .long_name = NULL_IF_CONFIG_SMALL("Google VP9"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_VP9,
+ .priv_data_size = sizeof(VP9Context),
+ .init = vp9_decode_init,
+ .close = vp9_decode_free,
+ .decode = vp9_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+ .flush = vp9_decode_flush,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(vp9_decode_init_thread_copy),
+ .update_thread_context = ONLY_IF_THREADS_ENABLED(vp9_decode_update_thread_context),
+ .profiles = NULL_IF_CONFIG_SMALL(profiles),
+};
diff --git a/ffmpeg-2-8-11/libavcodec/vp9.h b/ffmpeg-2-8-12/libavcodec/vp9.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp9.h
rename to ffmpeg-2-8-12/libavcodec/vp9.h
diff --git a/ffmpeg-2-8-11/libavcodec/vp9_mc_template.c b/ffmpeg-2-8-12/libavcodec/vp9_mc_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp9_mc_template.c
rename to ffmpeg-2-8-12/libavcodec/vp9_mc_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/vp9_parser.c b/ffmpeg-2-8-12/libavcodec/vp9_parser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp9_parser.c
rename to ffmpeg-2-8-12/libavcodec/vp9_parser.c
diff --git a/ffmpeg-2-8-11/libavcodec/vp9data.h b/ffmpeg-2-8-12/libavcodec/vp9data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp9data.h
rename to ffmpeg-2-8-12/libavcodec/vp9data.h
diff --git a/ffmpeg-2-8-11/libavcodec/vp9dsp.c b/ffmpeg-2-8-12/libavcodec/vp9dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp9dsp.c
rename to ffmpeg-2-8-12/libavcodec/vp9dsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/vp9dsp.h b/ffmpeg-2-8-12/libavcodec/vp9dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp9dsp.h
rename to ffmpeg-2-8-12/libavcodec/vp9dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/vp9dsp_10bpp.c b/ffmpeg-2-8-12/libavcodec/vp9dsp_10bpp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp9dsp_10bpp.c
rename to ffmpeg-2-8-12/libavcodec/vp9dsp_10bpp.c
diff --git a/ffmpeg-2-8-11/libavcodec/vp9dsp_12bpp.c b/ffmpeg-2-8-12/libavcodec/vp9dsp_12bpp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp9dsp_12bpp.c
rename to ffmpeg-2-8-12/libavcodec/vp9dsp_12bpp.c
diff --git a/ffmpeg-2-8-11/libavcodec/vp9dsp_8bpp.c b/ffmpeg-2-8-12/libavcodec/vp9dsp_8bpp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp9dsp_8bpp.c
rename to ffmpeg-2-8-12/libavcodec/vp9dsp_8bpp.c
diff --git a/ffmpeg-2-8-11/libavcodec/vp9dsp_template.c b/ffmpeg-2-8-12/libavcodec/vp9dsp_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vp9dsp_template.c
rename to ffmpeg-2-8-12/libavcodec/vp9dsp_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/vqavideo.c b/ffmpeg-2-8-12/libavcodec/vqavideo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/vqavideo.c
rename to ffmpeg-2-8-12/libavcodec/vqavideo.c
diff --git a/ffmpeg-2-8-12/libavcodec/wavpack.c b/ffmpeg-2-8-12/libavcodec/wavpack.c
new file mode 100644
index 0000000..ec8a9d9
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/wavpack.c
@@ -0,0 +1,1135 @@
+/*
+ * WavPack lossless audio decoder
+ * 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
+ */
+
+#define BITSTREAM_READER_LE
+
+#include "libavutil/channel_layout.h"
+#include "avcodec.h"
+#include "get_bits.h"
+#include "internal.h"
+#include "thread.h"
+#include "unary.h"
+#include "bytestream.h"
+#include "wavpack.h"
+
+/**
+ * @file
+ * WavPack lossless audio decoder
+ */
+
+typedef struct SavedContext {
+ int offset;
+ int size;
+ int bits_used;
+ uint32_t crc;
+} SavedContext;
+
+typedef struct WavpackFrameContext {
+ AVCodecContext *avctx;
+ int frame_flags;
+ int stereo, stereo_in;
+ int joint;
+ uint32_t CRC;
+ GetBitContext gb;
+ int got_extra_bits;
+ uint32_t crc_extra_bits;
+ GetBitContext gb_extra_bits;
+ int data_size; // in bits
+ int samples;
+ int terms;
+ Decorr decorr[MAX_TERMS];
+ int zero, one, zeroes;
+ int extra_bits;
+ int and, or, shift;
+ int post_shift;
+ int hybrid, hybrid_bitrate;
+ int hybrid_maxclip, hybrid_minclip;
+ int float_flag;
+ int float_shift;
+ int float_max_exp;
+ WvChannel ch[2];
+ int pos;
+ SavedContext sc, extra_sc;
+} WavpackFrameContext;
+
+#define WV_MAX_FRAME_DECODERS 14
+
+typedef struct WavpackContext {
+ AVCodecContext *avctx;
+
+ WavpackFrameContext *fdec[WV_MAX_FRAME_DECODERS];
+ int fdec_num;
+
+ int block;
+ int samples;
+ int ch_offset;
+} WavpackContext;
+
+#define LEVEL_DECAY(a) (((a) + 0x80) >> 8)
+
+static av_always_inline int get_tail(GetBitContext *gb, int k)
+{
+ int p, e, res;
+
+ if (k < 1)
+ return 0;
+ p = av_log2(k);
+ e = (1 << (p + 1)) - k - 1;
+ res = p ? get_bits(gb, p) : 0;
+ if (res >= e)
+ res = (res << 1) - e + get_bits1(gb);
+ return res;
+}
+
+static void update_error_limit(WavpackFrameContext *ctx)
+{
+ int i, br[2], sl[2];
+
+ for (i = 0; i <= ctx->stereo_in; i++) {
+ ctx->ch[i].bitrate_acc += ctx->ch[i].bitrate_delta;
+ br[i] = ctx->ch[i].bitrate_acc >> 16;
+ sl[i] = LEVEL_DECAY(ctx->ch[i].slow_level);
+ }
+ if (ctx->stereo_in && ctx->hybrid_bitrate) {
+ int balance = (sl[1] - sl[0] + br[1] + 1) >> 1;
+ if (balance > br[0]) {
+ br[1] = br[0] << 1;
+ br[0] = 0;
+ } else if (-balance > br[0]) {
+ br[0] <<= 1;
+ br[1] = 0;
+ } else {
+ br[1] = br[0] + balance;
+ br[0] = br[0] - balance;
+ }
+ }
+ for (i = 0; i <= ctx->stereo_in; i++) {
+ if (ctx->hybrid_bitrate) {
+ if (sl[i] - br[i] > -0x100)
+ ctx->ch[i].error_limit = wp_exp2(sl[i] - br[i] + 0x100);
+ else
+ ctx->ch[i].error_limit = 0;
+ } else {
+ ctx->ch[i].error_limit = wp_exp2(br[i]);
+ }
+ }
+}
+
+static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb,
+ int channel, int *last)
+{
+ int t, t2;
+ int sign, base, add, ret;
+ WvChannel *c = &ctx->ch[channel];
+
+ *last = 0;
+
+ if ((ctx->ch[0].median[0] < 2U) && (ctx->ch[1].median[0] < 2U) &&
+ !ctx->zero && !ctx->one) {
+ if (ctx->zeroes) {
+ ctx->zeroes--;
+ if (ctx->zeroes) {
+ c->slow_level -= LEVEL_DECAY(c->slow_level);
+ return 0;
+ }
+ } else {
+ t = get_unary_0_33(gb);
+ if (t >= 2) {
+ if (get_bits_left(gb) < t - 1)
+ goto error;
+ t = get_bits_long(gb, t - 1) | (1 << (t - 1));
+ } else {
+ if (get_bits_left(gb) < 0)
+ goto error;
+ }
+ ctx->zeroes = t;
+ if (ctx->zeroes) {
+ memset(ctx->ch[0].median, 0, sizeof(ctx->ch[0].median));
+ memset(ctx->ch[1].median, 0, sizeof(ctx->ch[1].median));
+ c->slow_level -= LEVEL_DECAY(c->slow_level);
+ return 0;
+ }
+ }
+ }
+
+ if (ctx->zero) {
+ t = 0;
+ ctx->zero = 0;
+ } else {
+ t = get_unary_0_33(gb);
+ if (get_bits_left(gb) < 0)
+ goto error;
+ if (t == 16) {
+ t2 = get_unary_0_33(gb);
+ if (t2 < 2) {
+ if (get_bits_left(gb) < 0)
+ goto error;
+ t += t2;
+ } else {
+ if (t2 >= 32 || get_bits_left(gb) < t2 - 1)
+ goto error;
+ t += get_bits_long(gb, t2 - 1) | (1 << (t2 - 1));
+ }
+ }
+
+ if (ctx->one) {
+ ctx->one = t & 1;
+ t = (t >> 1) + 1;
+ } else {
+ ctx->one = t & 1;
+ t >>= 1;
+ }
+ ctx->zero = !ctx->one;
+ }
+
+ if (ctx->hybrid && !channel)
+ update_error_limit(ctx);
+
+ if (!t) {
+ base = 0;
+ add = GET_MED(0) - 1;
+ DEC_MED(0);
+ } else if (t == 1) {
+ base = GET_MED(0);
+ add = GET_MED(1) - 1;
+ INC_MED(0);
+ DEC_MED(1);
+ } else if (t == 2) {
+ base = GET_MED(0) + GET_MED(1);
+ add = GET_MED(2) - 1;
+ INC_MED(0);
+ INC_MED(1);
+ DEC_MED(2);
+ } else {
+ base = GET_MED(0) + GET_MED(1) + GET_MED(2) * (t - 2);
+ add = GET_MED(2) - 1;
+ INC_MED(0);
+ INC_MED(1);
+ INC_MED(2);
+ }
+ if (!c->error_limit) {
+ if (add >= 0x2000000U) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "k %d is too large\n", add);
+ goto error;
+ }
+ ret = base + get_tail(gb, add);
+ if (get_bits_left(gb) <= 0)
+ goto error;
+ } else {
+ int mid = (base * 2 + add + 1) >> 1;
+ while (add > c->error_limit) {
+ if (get_bits_left(gb) <= 0)
+ goto error;
+ if (get_bits1(gb)) {
+ add -= (mid - (unsigned)base);
+ base = mid;
+ } else
+ add = mid - base - 1;
+ mid = (base * 2 + add + 1) >> 1;
+ }
+ ret = mid;
+ }
+ sign = get_bits1(gb);
+ if (ctx->hybrid_bitrate)
+ c->slow_level += wp_log2(ret) - LEVEL_DECAY(c->slow_level);
+ return sign ? ~ret : ret;
+
+error:
+ ret = get_bits_left(gb);
+ if (ret <= 0) {
+ av_log(ctx->avctx, AV_LOG_ERROR, "Too few bits (%d) left\n", ret);
+ }
+ *last = 1;
+ return 0;
+}
+
+static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc,
+ int S)
+{
+ int bit;
+
+ if (s->extra_bits) {
+ S *= 1 << s->extra_bits;
+
+ if (s->got_extra_bits &&
+ get_bits_left(&s->gb_extra_bits) >= s->extra_bits) {
+ S |= get_bits_long(&s->gb_extra_bits, s->extra_bits);
+ *crc = *crc * 9 + (S & 0xffff) * 3 + ((unsigned)S >> 16);
+ }
+ }
+
+ bit = (S & s->and) | s->or;
+ bit = ((S + bit) << s->shift) - bit;
+
+ if (s->hybrid)
+ bit = av_clip(bit, s->hybrid_minclip, s->hybrid_maxclip);
+
+ return bit << s->post_shift;
+}
+
+static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S)
+{
+ union {
+ float f;
+ uint32_t u;
+ } value;
+
+ unsigned int sign;
+ int exp = s->float_max_exp;
+
+ if (s->got_extra_bits) {
+ const int max_bits = 1 + 23 + 8 + 1;
+ const int left_bits = get_bits_left(&s->gb_extra_bits);
+
+ if (left_bits + 8 * AV_INPUT_BUFFER_PADDING_SIZE < max_bits)
+ return 0.0;
+ }
+
+ if (S) {
+ S <<= s->float_shift;
+ sign = S < 0;
+ if (sign)
+ S = -S;
+ if (S >= 0x1000000) {
+ if (s->got_extra_bits && get_bits1(&s->gb_extra_bits))
+ S = get_bits(&s->gb_extra_bits, 23);
+ else
+ S = 0;
+ exp = 255;
+ } else if (exp) {
+ int shift = 23 - av_log2(S);
+ exp = s->float_max_exp;
+ if (exp <= shift)
+ shift = --exp;
+ exp -= shift;
+
+ if (shift) {
+ S <<= shift;
+ if ((s->float_flag & WV_FLT_SHIFT_ONES) ||
+ (s->got_extra_bits &&
+ (s->float_flag & WV_FLT_SHIFT_SAME) &&
+ get_bits1(&s->gb_extra_bits))) {
+ S |= (1 << shift) - 1;
+ } else if (s->got_extra_bits &&
+ (s->float_flag & WV_FLT_SHIFT_SENT)) {
+ S |= get_bits(&s->gb_extra_bits, shift);
+ }
+ }
+ } else {
+ exp = s->float_max_exp;
+ }
+ S &= 0x7fffff;
+ } else {
+ sign = 0;
+ exp = 0;
+ if (s->got_extra_bits && (s->float_flag & WV_FLT_ZERO_SENT)) {
+ if (get_bits1(&s->gb_extra_bits)) {
+ S = get_bits(&s->gb_extra_bits, 23);
+ if (s->float_max_exp >= 25)
+ exp = get_bits(&s->gb_extra_bits, 8);
+ sign = get_bits1(&s->gb_extra_bits);
+ } else {
+ if (s->float_flag & WV_FLT_ZERO_SIGN)
+ sign = get_bits1(&s->gb_extra_bits);
+ }
+ }
+ }
+
+ *crc = *crc * 27 + S * 9 + exp * 3 + sign;
+
+ value.u = (sign << 31) | (exp << 23) | S;
+ return value.f;
+}
+
+static void wv_reset_saved_context(WavpackFrameContext *s)
+{
+ s->pos = 0;
+ s->sc.crc = s->extra_sc.crc = 0xFFFFFFFF;
+}
+
+static inline int wv_check_crc(WavpackFrameContext *s, uint32_t crc,
+ uint32_t crc_extra_bits)
+{
+ if (crc != s->CRC) {
+ av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->got_extra_bits && crc_extra_bits != s->crc_extra_bits) {
+ av_log(s->avctx, AV_LOG_ERROR, "Extra bits CRC error\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ return 0;
+}
+
+static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb,
+ void *dst_l, void *dst_r, const int type)
+{
+ int i, j, count = 0;
+ int last, t;
+ int A, B, L, L2, R, R2;
+ int pos = s->pos;
+ uint32_t crc = s->sc.crc;
+ uint32_t crc_extra_bits = s->extra_sc.crc;
+ int16_t *dst16_l = dst_l;
+ int16_t *dst16_r = dst_r;
+ int32_t *dst32_l = dst_l;
+ int32_t *dst32_r = dst_r;
+ float *dstfl_l = dst_l;
+ float *dstfl_r = dst_r;
+
+ s->one = s->zero = s->zeroes = 0;
+ do {
+ L = wv_get_value(s, gb, 0, &last);
+ if (last)
+ break;
+ R = wv_get_value(s, gb, 1, &last);
+ if (last)
+ break;
+ for (i = 0; i < s->terms; i++) {
+ t = s->decorr[i].value;
+ if (t > 0) {
+ if (t > 8) {
+ if (t & 1) {
+ A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1];
+ B = 2 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1];
+ } else {
+ A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1;
+ B = (3 * s->decorr[i].samplesB[0] - s->decorr[i].samplesB[1]) >> 1;
+ }
+ s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];
+ s->decorr[i].samplesB[1] = s->decorr[i].samplesB[0];
+ j = 0;
+ } else {
+ A = s->decorr[i].samplesA[pos];
+ B = s->decorr[i].samplesB[pos];
+ j = (pos + t) & 7;
+ }
+ if (type != AV_SAMPLE_FMT_S16P) {
+ L2 = L + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10);
+ R2 = R + ((s->decorr[i].weightB * (int64_t)B + 512) >> 10);
+ } else {
+ L2 = L + ((s->decorr[i].weightA * A + 512) >> 10);
+ R2 = R + ((s->decorr[i].weightB * B + 512) >> 10);
+ }
+ if (A && L)
+ s->decorr[i].weightA -= ((((L ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;
+ if (B && R)
+ s->decorr[i].weightB -= ((((R ^ B) >> 30) & 2) - 1) * s->decorr[i].delta;
+ s->decorr[i].samplesA[j] = L = L2;
+ s->decorr[i].samplesB[j] = R = R2;
+ } else if (t == -1) {
+ if (type != AV_SAMPLE_FMT_S16P)
+ L2 = L + ((s->decorr[i].weightA * (int64_t)s->decorr[i].samplesA[0] + 512) >> 10);
+ else
+ L2 = L + ((s->decorr[i].weightA * s->decorr[i].samplesA[0] + 512) >> 10);
+ UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, s->decorr[i].samplesA[0], L);
+ L = L2;
+ if (type != AV_SAMPLE_FMT_S16P)
+ R2 = R + ((s->decorr[i].weightB * (int64_t)L2 + 512) >> 10);
+ else
+ R2 = R + ((s->decorr[i].weightB * L2 + 512) >> 10);
+ UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, L2, R);
+ R = R2;
+ s->decorr[i].samplesA[0] = R;
+ } else {
+ if (type != AV_SAMPLE_FMT_S16P)
+ R2 = R + ((s->decorr[i].weightB * (int64_t)s->decorr[i].samplesB[0] + 512) >> 10);
+ else
+ R2 = R + ((s->decorr[i].weightB * s->decorr[i].samplesB[0] + 512) >> 10);
+ UPDATE_WEIGHT_CLIP(s->decorr[i].weightB, s->decorr[i].delta, s->decorr[i].samplesB[0], R);
+ R = R2;
+
+ if (t == -3) {
+ R2 = s->decorr[i].samplesA[0];
+ s->decorr[i].samplesA[0] = R;
+ }
+
+ if (type != AV_SAMPLE_FMT_S16P)
+ L2 = L + ((s->decorr[i].weightA * (int64_t)R2 + 512) >> 10);
+ else
+ L2 = L + ((s->decorr[i].weightA * R2 + 512) >> 10);
+ UPDATE_WEIGHT_CLIP(s->decorr[i].weightA, s->decorr[i].delta, R2, L);
+ L = L2;
+ s->decorr[i].samplesB[0] = L;
+ }
+ }
+
+ if (type == AV_SAMPLE_FMT_S16P) {
+ if (FFABS(L) + FFABS(R) > (1<<19)) {
+ av_log(s->avctx, AV_LOG_ERROR, "sample %d %d too large\n", L, R);
+ return AVERROR_INVALIDDATA;
+ }
+ }
+
+ pos = (pos + 1) & 7;
+ if (s->joint)
+ L += (R -= (L >> 1));
+ crc = (crc * 3 + L) * 3 + R;
+
+ if (type == AV_SAMPLE_FMT_FLTP) {
+ *dstfl_l++ = wv_get_value_float(s, &crc_extra_bits, L);
+ *dstfl_r++ = wv_get_value_float(s, &crc_extra_bits, R);
+ } else if (type == AV_SAMPLE_FMT_S32P) {
+ *dst32_l++ = wv_get_value_integer(s, &crc_extra_bits, L);
+ *dst32_r++ = wv_get_value_integer(s, &crc_extra_bits, R);
+ } else {
+ *dst16_l++ = wv_get_value_integer(s, &crc_extra_bits, L);
+ *dst16_r++ = wv_get_value_integer(s, &crc_extra_bits, R);
+ }
+ count++;
+ } while (!last && count < s->samples);
+
+ wv_reset_saved_context(s);
+
+ if (last && count < s->samples) {
+ int size = av_get_bytes_per_sample(type);
+ memset((uint8_t*)dst_l + count*size, 0, (s->samples-count)*size);
+ memset((uint8_t*)dst_r + count*size, 0, (s->samples-count)*size);
+ }
+
+ if ((s->avctx->err_recognition & AV_EF_CRCCHECK) &&
+ wv_check_crc(s, crc, crc_extra_bits))
+ return AVERROR_INVALIDDATA;
+
+ return 0;
+}
+
+static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb,
+ void *dst, const int type)
+{
+ int i, j, count = 0;
+ int last, t;
+ int A, S, T;
+ int pos = s->pos;
+ uint32_t crc = s->sc.crc;
+ uint32_t crc_extra_bits = s->extra_sc.crc;
+ int16_t *dst16 = dst;
+ int32_t *dst32 = dst;
+ float *dstfl = dst;
+
+ s->one = s->zero = s->zeroes = 0;
+ do {
+ T = wv_get_value(s, gb, 0, &last);
+ S = 0;
+ if (last)
+ break;
+ for (i = 0; i < s->terms; i++) {
+ t = s->decorr[i].value;
+ if (t > 8) {
+ if (t & 1)
+ A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1];
+ else
+ A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1;
+ s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];
+ j = 0;
+ } else {
+ A = s->decorr[i].samplesA[pos];
+ j = (pos + t) & 7;
+ }
+ if (type != AV_SAMPLE_FMT_S16P)
+ S = T + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10);
+ else
+ S = T + ((int)(s->decorr[i].weightA * (unsigned)A + 512) >> 10);
+ if (A && T)
+ s->decorr[i].weightA -= ((((T ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;
+ s->decorr[i].samplesA[j] = T = S;
+ }
+ pos = (pos + 1) & 7;
+ crc = crc * 3 + S;
+
+ if (type == AV_SAMPLE_FMT_FLTP) {
+ *dstfl++ = wv_get_value_float(s, &crc_extra_bits, S);
+ } else if (type == AV_SAMPLE_FMT_S32P) {
+ *dst32++ = wv_get_value_integer(s, &crc_extra_bits, S);
+ } else {
+ *dst16++ = wv_get_value_integer(s, &crc_extra_bits, S);
+ }
+ count++;
+ } while (!last && count < s->samples);
+
+ wv_reset_saved_context(s);
+
+ if (last && count < s->samples) {
+ int size = av_get_bytes_per_sample(type);
+ memset((uint8_t*)dst + count*size, 0, (s->samples-count)*size);
+ }
+
+ if (s->avctx->err_recognition & AV_EF_CRCCHECK) {
+ int ret = wv_check_crc(s, crc, crc_extra_bits);
+ if (ret < 0 && s->avctx->err_recognition & AV_EF_EXPLODE)
+ return ret;
+ }
+
+ return 0;
+}
+
+static av_cold int wv_alloc_frame_context(WavpackContext *c)
+{
+ if (c->fdec_num == WV_MAX_FRAME_DECODERS)
+ return -1;
+
+ c->fdec[c->fdec_num] = av_mallocz(sizeof(**c->fdec));
+ if (!c->fdec[c->fdec_num])
+ return -1;
+ c->fdec_num++;
+ c->fdec[c->fdec_num - 1]->avctx = c->avctx;
+ wv_reset_saved_context(c->fdec[c->fdec_num - 1]);
+
+ return 0;
+}
+
+static int init_thread_copy(AVCodecContext *avctx)
+{
+ WavpackContext *s = avctx->priv_data;
+ s->avctx = avctx;
+ return 0;
+}
+
+static av_cold int wavpack_decode_init(AVCodecContext *avctx)
+{
+ WavpackContext *s = avctx->priv_data;
+
+ s->avctx = avctx;
+
+ s->fdec_num = 0;
+
+ return 0;
+}
+
+static av_cold int wavpack_decode_end(AVCodecContext *avctx)
+{
+ WavpackContext *s = avctx->priv_data;
+ int i;
+
+ for (i = 0; i < s->fdec_num; i++)
+ av_freep(&s->fdec[i]);
+ s->fdec_num = 0;
+
+ return 0;
+}
+
+static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
+ AVFrame *frame, const uint8_t *buf, int buf_size)
+{
+ WavpackContext *wc = avctx->priv_data;
+ ThreadFrame tframe = { .f = frame };
+ WavpackFrameContext *s;
+ GetByteContext gb;
+ void *samples_l = NULL, *samples_r = NULL;
+ int ret;
+ int got_terms = 0, got_weights = 0, got_samples = 0,
+ got_entropy = 0, got_bs = 0, got_float = 0, got_hybrid = 0;
+ int i, j, id, size, ssize, weights, t;
+ int bpp, chan = 0, chmask = 0, orig_bpp, sample_rate = 0;
+ int multiblock;
+
+ if (block_no >= wc->fdec_num && wv_alloc_frame_context(wc) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "Error creating frame decode context\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ s = wc->fdec[block_no];
+ if (!s) {
+ av_log(avctx, AV_LOG_ERROR, "Context for block %d is not present\n",
+ block_no);
+ return AVERROR_INVALIDDATA;
+ }
+
+ memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr));
+ memset(s->ch, 0, sizeof(s->ch));
+ s->extra_bits = 0;
+ s->and = s->or = s->shift = 0;
+ s->got_extra_bits = 0;
+
+ bytestream2_init(&gb, buf, buf_size);
+
+ s->samples = bytestream2_get_le32(&gb);
+ if (s->samples != wc->samples) {
+ av_log(avctx, AV_LOG_ERROR, "Mismatching number of samples in "
+ "a sequence: %d and %d\n", wc->samples, s->samples);
+ return AVERROR_INVALIDDATA;
+ }
+ s->frame_flags = bytestream2_get_le32(&gb);
+ bpp = av_get_bytes_per_sample(avctx->sample_fmt);
+ orig_bpp = ((s->frame_flags & 0x03) + 1) << 3;
+ multiblock = (s->frame_flags & WV_SINGLE_BLOCK) != WV_SINGLE_BLOCK;
+
+ s->stereo = !(s->frame_flags & WV_MONO);
+ s->stereo_in = (s->frame_flags & WV_FALSE_STEREO) ? 0 : s->stereo;
+ s->joint = s->frame_flags & WV_JOINT_STEREO;
+ s->hybrid = s->frame_flags & WV_HYBRID_MODE;
+ s->hybrid_bitrate = s->frame_flags & WV_HYBRID_BITRATE;
+ s->post_shift = bpp * 8 - orig_bpp + ((s->frame_flags >> 13) & 0x1f);
+ s->hybrid_maxclip = ((1LL << (orig_bpp - 1)) - 1);
+ s->hybrid_minclip = ((-1UL << (orig_bpp - 1)));
+ s->CRC = bytestream2_get_le32(&gb);
+
+ // parse metadata blocks
+ while (bytestream2_get_bytes_left(&gb)) {
+ id = bytestream2_get_byte(&gb);
+ size = bytestream2_get_byte(&gb);
+ if (id & WP_IDF_LONG) {
+ size |= (bytestream2_get_byte(&gb)) << 8;
+ size |= (bytestream2_get_byte(&gb)) << 16;
+ }
+ size <<= 1; // size is specified in words
+ ssize = size;
+ if (id & WP_IDF_ODD)
+ size--;
+ if (size < 0) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Got incorrect block %02X with size %i\n", id, size);
+ break;
+ }
+ if (bytestream2_get_bytes_left(&gb) < ssize) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Block size %i is out of bounds\n", size);
+ break;
+ }
+ switch (id & WP_IDF_MASK) {
+ case WP_ID_DECTERMS:
+ if (size > MAX_TERMS) {
+ av_log(avctx, AV_LOG_ERROR, "Too many decorrelation terms\n");
+ s->terms = 0;
+ bytestream2_skip(&gb, ssize);
+ continue;
+ }
+ s->terms = size;
+ for (i = 0; i < s->terms; i++) {
+ uint8_t val = bytestream2_get_byte(&gb);
+ s->decorr[s->terms - i - 1].value = (val & 0x1F) - 5;
+ s->decorr[s->terms - i - 1].delta = val >> 5;
+ }
+ got_terms = 1;
+ break;
+ case WP_ID_DECWEIGHTS:
+ if (!got_terms) {
+ av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");
+ continue;
+ }
+ weights = size >> s->stereo_in;
+ if (weights > MAX_TERMS || weights > s->terms) {
+ av_log(avctx, AV_LOG_ERROR, "Too many decorrelation weights\n");
+ bytestream2_skip(&gb, ssize);
+ continue;
+ }
+ for (i = 0; i < weights; i++) {
+ t = (int8_t)bytestream2_get_byte(&gb);
+ s->decorr[s->terms - i - 1].weightA = t * (1 << 3);
+ if (s->decorr[s->terms - i - 1].weightA > 0)
+ s->decorr[s->terms - i - 1].weightA +=
+ (s->decorr[s->terms - i - 1].weightA + 64) >> 7;
+ if (s->stereo_in) {
+ t = (int8_t)bytestream2_get_byte(&gb);
+ s->decorr[s->terms - i - 1].weightB = t * (1 << 3);
+ if (s->decorr[s->terms - i - 1].weightB > 0)
+ s->decorr[s->terms - i - 1].weightB +=
+ (s->decorr[s->terms - i - 1].weightB + 64) >> 7;
+ }
+ }
+ got_weights = 1;
+ break;
+ case WP_ID_DECSAMPLES:
+ if (!got_terms) {
+ av_log(avctx, AV_LOG_ERROR, "No decorrelation terms met\n");
+ continue;
+ }
+ t = 0;
+ for (i = s->terms - 1; (i >= 0) && (t < size); i--) {
+ if (s->decorr[i].value > 8) {
+ s->decorr[i].samplesA[0] =
+ wp_exp2(bytestream2_get_le16(&gb));
+ s->decorr[i].samplesA[1] =
+ wp_exp2(bytestream2_get_le16(&gb));
+
+ if (s->stereo_in) {
+ s->decorr[i].samplesB[0] =
+ wp_exp2(bytestream2_get_le16(&gb));
+ s->decorr[i].samplesB[1] =
+ wp_exp2(bytestream2_get_le16(&gb));
+ t += 4;
+ }
+ t += 4;
+ } else if (s->decorr[i].value < 0) {
+ s->decorr[i].samplesA[0] =
+ wp_exp2(bytestream2_get_le16(&gb));
+ s->decorr[i].samplesB[0] =
+ wp_exp2(bytestream2_get_le16(&gb));
+ t += 4;
+ } else {
+ for (j = 0; j < s->decorr[i].value; j++) {
+ s->decorr[i].samplesA[j] =
+ wp_exp2(bytestream2_get_le16(&gb));
+ if (s->stereo_in) {
+ s->decorr[i].samplesB[j] =
+ wp_exp2(bytestream2_get_le16(&gb));
+ }
+ }
+ t += s->decorr[i].value * 2 * (s->stereo_in + 1);
+ }
+ }
+ got_samples = 1;
+ break;
+ case WP_ID_ENTROPY:
+ if (size != 6 * (s->stereo_in + 1)) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Entropy vars size should be %i, got %i.\n",
+ 6 * (s->stereo_in + 1), size);
+ bytestream2_skip(&gb, ssize);
+ continue;
+ }
+ for (j = 0; j <= s->stereo_in; j++)
+ for (i = 0; i < 3; i++) {
+ s->ch[j].median[i] = wp_exp2(bytestream2_get_le16(&gb));
+ }
+ got_entropy = 1;
+ break;
+ case WP_ID_HYBRID:
+ if (s->hybrid_bitrate) {
+ for (i = 0; i <= s->stereo_in; i++) {
+ s->ch[i].slow_level = wp_exp2(bytestream2_get_le16(&gb));
+ size -= 2;
+ }
+ }
+ for (i = 0; i < (s->stereo_in + 1); i++) {
+ s->ch[i].bitrate_acc = bytestream2_get_le16(&gb) << 16;
+ size -= 2;
+ }
+ if (size > 0) {
+ for (i = 0; i < (s->stereo_in + 1); i++) {
+ s->ch[i].bitrate_delta =
+ wp_exp2((int16_t)bytestream2_get_le16(&gb));
+ }
+ } else {
+ for (i = 0; i < (s->stereo_in + 1); i++)
+ s->ch[i].bitrate_delta = 0;
+ }
+ got_hybrid = 1;
+ break;
+ case WP_ID_INT32INFO: {
+ uint8_t val[4];
+ if (size != 4) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid INT32INFO, size = %i\n",
+ size);
+ bytestream2_skip(&gb, ssize - 4);
+ continue;
+ }
+ bytestream2_get_buffer(&gb, val, 4);
+ if (val[0] > 31) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid INT32INFO, extra_bits = %d (> 32)\n", val[0]);
+ continue;
+ } else if (val[0]) {
+ s->extra_bits = val[0];
+ } else if (val[1]) {
+ s->shift = val[1];
+ } else if (val[2]) {
+ s->and = s->or = 1;
+ s->shift = val[2];
+ } else if (val[3]) {
+ s->and = 1;
+ s->shift = val[3];
+ }
+ /* original WavPack decoder forces 32-bit lossy sound to be treated
+ * as 24-bit one in order to have proper clipping */
+ if (s->hybrid && bpp == 4 && s->post_shift < 8 && s->shift > 8) {
+ s->post_shift += 8;
+ s->shift -= 8;
+ s->hybrid_maxclip >>= 8;
+ s->hybrid_minclip >>= 8;
+ }
+ break;
+ }
+ case WP_ID_FLOATINFO:
+ if (size != 4) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid FLOATINFO, size = %i\n", size);
+ bytestream2_skip(&gb, ssize);
+ continue;
+ }
+ s->float_flag = bytestream2_get_byte(&gb);
+ s->float_shift = bytestream2_get_byte(&gb);
+ s->float_max_exp = bytestream2_get_byte(&gb);
+ if (s->float_shift > 31) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Invalid FLOATINFO, shift = %d (> 31)\n", s->float_shift);
+ s->float_shift = 0;
+ continue;
+ }
+ got_float = 1;
+ bytestream2_skip(&gb, 1);
+ break;
+ case WP_ID_DATA:
+ s->sc.offset = bytestream2_tell(&gb);
+ s->sc.size = size * 8;
+ if ((ret = init_get_bits8(&s->gb, gb.buffer, size)) < 0)
+ return ret;
+ s->data_size = size * 8;
+ bytestream2_skip(&gb, size);
+ got_bs = 1;
+ break;
+ case WP_ID_EXTRABITS:
+ if (size <= 4) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid EXTRABITS, size = %i\n",
+ size);
+ bytestream2_skip(&gb, size);
+ continue;
+ }
+ s->extra_sc.offset = bytestream2_tell(&gb);
+ s->extra_sc.size = size * 8;
+ if ((ret = init_get_bits8(&s->gb_extra_bits, gb.buffer, size)) < 0)
+ return ret;
+ s->crc_extra_bits = get_bits_long(&s->gb_extra_bits, 32);
+ bytestream2_skip(&gb, size);
+ s->got_extra_bits = 1;
+ break;
+ case WP_ID_CHANINFO:
+ if (size <= 1) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Insufficient channel information\n");
+ return AVERROR_INVALIDDATA;
+ }
+ chan = bytestream2_get_byte(&gb);
+ switch (size - 2) {
+ case 0:
+ chmask = bytestream2_get_byte(&gb);
+ break;
+ case 1:
+ chmask = bytestream2_get_le16(&gb);
+ break;
+ case 2:
+ chmask = bytestream2_get_le24(&gb);
+ break;
+ case 3:
+ chmask = bytestream2_get_le32(&gb);
+ break;
+ case 5:
+ size = bytestream2_get_byte(&gb);
+ if (avctx->channels != size)
+ av_log(avctx, AV_LOG_WARNING, "%i channels signalled"
+ " instead of %i.\n", size, avctx->channels);
+ chan |= (bytestream2_get_byte(&gb) & 0xF) << 8;
+ chmask = bytestream2_get_le16(&gb);
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "Invalid channel info size %d\n",
+ size);
+ chan = avctx->channels;
+ chmask = avctx->channel_layout;
+ }
+ break;
+ case WP_ID_SAMPLE_RATE:
+ if (size != 3) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid custom sample rate.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ sample_rate = bytestream2_get_le24(&gb);
+ break;
+ default:
+ bytestream2_skip(&gb, size);
+ }
+ if (id & WP_IDF_ODD)
+ bytestream2_skip(&gb, 1);
+ }
+
+ if (!got_terms) {
+ av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (!got_weights) {
+ av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (!got_samples) {
+ av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (!got_entropy) {
+ av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->hybrid && !got_hybrid) {
+ av_log(avctx, AV_LOG_ERROR, "Hybrid config not found\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (!got_bs) {
+ av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLTP) {
+ av_log(avctx, AV_LOG_ERROR, "Float information not found\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLTP) {
+ const int size = get_bits_left(&s->gb_extra_bits);
+ const int wanted = s->samples * s->extra_bits << s->stereo_in;
+ if (size < wanted) {
+ av_log(avctx, AV_LOG_ERROR, "Too small EXTRABITS\n");
+ s->got_extra_bits = 0;
+ }
+ }
+
+ if (!wc->ch_offset) {
+ int sr = (s->frame_flags >> 23) & 0xf;
+ if (sr == 0xf) {
+ if (!sample_rate) {
+ av_log(avctx, AV_LOG_ERROR, "Custom sample rate missing.\n");
+ return AVERROR_INVALIDDATA;
+ }
+ avctx->sample_rate = sample_rate;
+ } else
+ avctx->sample_rate = wv_rates[sr];
+
+ if (multiblock) {
+ if (chan)
+ avctx->channels = chan;
+ if (chmask)
+ avctx->channel_layout = chmask;
+ } else {
+ avctx->channels = s->stereo ? 2 : 1;
+ avctx->channel_layout = s->stereo ? AV_CH_LAYOUT_STEREO :
+ AV_CH_LAYOUT_MONO;
+ }
+
+ /* get output buffer */
+ frame->nb_samples = s->samples + 1;
+ if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)
+ return ret;
+ frame->nb_samples = s->samples;
+ }
+
+ if (wc->ch_offset + s->stereo >= avctx->channels) {
+ av_log(avctx, AV_LOG_WARNING, "Too many channels coded in a packet.\n");
+ return (avctx->err_recognition & AV_EF_EXPLODE) ? AVERROR_INVALIDDATA : 0;
+ }
+
+ samples_l = frame->extended_data[wc->ch_offset];
+ if (s->stereo)
+ samples_r = frame->extended_data[wc->ch_offset + 1];
+
+ wc->ch_offset += 1 + s->stereo;
+
+ if (s->stereo_in) {
+ ret = wv_unpack_stereo(s, &s->gb, samples_l, samples_r, avctx->sample_fmt);
+ if (ret < 0)
+ return ret;
+ } else {
+ ret = wv_unpack_mono(s, &s->gb, samples_l, avctx->sample_fmt);
+ if (ret < 0)
+ return ret;
+
+ if (s->stereo)
+ memcpy(samples_r, samples_l, bpp * s->samples);
+ }
+
+ return 0;
+}
+
+static void wavpack_decode_flush(AVCodecContext *avctx)
+{
+ WavpackContext *s = avctx->priv_data;
+ int i;
+
+ for (i = 0; i < s->fdec_num; i++)
+ wv_reset_saved_context(s->fdec[i]);
+}
+
+static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
+{
+ WavpackContext *s = avctx->priv_data;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ AVFrame *frame = data;
+ int frame_size, ret, frame_flags;
+
+ if (avpkt->size <= WV_HEADER_SIZE)
+ return AVERROR_INVALIDDATA;
+
+ s->block = 0;
+ s->ch_offset = 0;
+
+ /* determine number of samples */
+ s->samples = AV_RL32(buf + 20);
+ frame_flags = AV_RL32(buf + 24);
+ if (s->samples <= 0 || s->samples > WV_MAX_SAMPLES) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n",
+ s->samples);
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (frame_flags & 0x80) {
+ avctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
+ } else if ((frame_flags & 0x03) <= 1) {
+ avctx->sample_fmt = AV_SAMPLE_FMT_S16P;
+ } else {
+ avctx->sample_fmt = AV_SAMPLE_FMT_S32P;
+ avctx->bits_per_raw_sample = ((frame_flags & 0x03) + 1) << 3;
+ }
+
+ while (buf_size > 0) {
+ if (buf_size <= WV_HEADER_SIZE)
+ break;
+ frame_size = AV_RL32(buf + 4) - 12;
+ buf += 20;
+ buf_size -= 20;
+ if (frame_size <= 0 || frame_size > buf_size) {
+ av_log(avctx, AV_LOG_ERROR,
+ "Block %d has invalid size (size %d vs. %d bytes left)\n",
+ s->block, frame_size, buf_size);
+ wavpack_decode_flush(avctx);
+ return AVERROR_INVALIDDATA;
+ }
+ if ((ret = wavpack_decode_block(avctx, s->block,
+ frame, buf, frame_size)) < 0) {
+ wavpack_decode_flush(avctx);
+ return ret;
+ }
+ s->block++;
+ buf += frame_size;
+ buf_size -= frame_size;
+ }
+
+ if (s->ch_offset != avctx->channels) {
+ av_log(avctx, AV_LOG_ERROR, "Not enough channels coded in a packet.\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ *got_frame_ptr = 1;
+
+ return avpkt->size;
+}
+
+AVCodec ff_wavpack_decoder = {
+ .name = "wavpack",
+ .long_name = NULL_IF_CONFIG_SMALL("WavPack"),
+ .type = AVMEDIA_TYPE_AUDIO,
+ .id = AV_CODEC_ID_WAVPACK,
+ .priv_data_size = sizeof(WavpackContext),
+ .init = wavpack_decode_init,
+ .close = wavpack_decode_end,
+ .decode = wavpack_decode_frame,
+ .flush = wavpack_decode_flush,
+ .init_thread_copy = ONLY_IF_THREADS_ENABLED(init_thread_copy),
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/wavpack.h b/ffmpeg-2-8-12/libavcodec/wavpack.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wavpack.h
rename to ffmpeg-2-8-12/libavcodec/wavpack.h
diff --git a/ffmpeg-2-8-11/libavcodec/wavpackenc.c b/ffmpeg-2-8-12/libavcodec/wavpackenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wavpackenc.c
rename to ffmpeg-2-8-12/libavcodec/wavpackenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/wavpackenc.h b/ffmpeg-2-8-12/libavcodec/wavpackenc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wavpackenc.h
rename to ffmpeg-2-8-12/libavcodec/wavpackenc.h
diff --git a/ffmpeg-2-8-12/libavcodec/webp.c b/ffmpeg-2-8-12/libavcodec/webp.c
new file mode 100644
index 0000000..1b3b68c
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/webp.c
@@ -0,0 +1,1558 @@
+/*
+ * WebP (.webp) image decoder
+ * Copyright (c) 2013 Aneesh Dogra <aneesh at sugarlabs.org>
+ * Copyright (c) 2013 Justin Ruggles <justin.ruggles at gmail.com>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * WebP image decoder
+ *
+ * @author Aneesh Dogra <aneesh at sugarlabs.org>
+ * Container and Lossy decoding
+ *
+ * @author Justin Ruggles <justin.ruggles at gmail.com>
+ * Lossless decoder
+ * Compressed alpha for lossy
+ *
+ * @author James Almer <jamrial at gmail.com>
+ * Exif metadata
+ *
+ * Unimplemented:
+ * - Animation
+ * - ICC profile
+ * - XMP metadata
+ */
+
+#define BITSTREAM_READER_LE
+#include "libavutil/imgutils.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "exif.h"
+#include "internal.h"
+#include "get_bits.h"
+#include "thread.h"
+#include "vp8.h"
+
+#define VP8X_FLAG_ANIMATION 0x02
+#define VP8X_FLAG_XMP_METADATA 0x04
+#define VP8X_FLAG_EXIF_METADATA 0x08
+#define VP8X_FLAG_ALPHA 0x10
+#define VP8X_FLAG_ICC 0x20
+
+#define MAX_PALETTE_SIZE 256
+#define MAX_CACHE_BITS 11
+#define NUM_CODE_LENGTH_CODES 19
+#define HUFFMAN_CODES_PER_META_CODE 5
+#define NUM_LITERAL_CODES 256
+#define NUM_LENGTH_CODES 24
+#define NUM_DISTANCE_CODES 40
+#define NUM_SHORT_DISTANCES 120
+#define MAX_HUFFMAN_CODE_LENGTH 15
+
+static const uint16_t alphabet_sizes[HUFFMAN_CODES_PER_META_CODE] = {
+ NUM_LITERAL_CODES + NUM_LENGTH_CODES,
+ NUM_LITERAL_CODES, NUM_LITERAL_CODES, NUM_LITERAL_CODES,
+ NUM_DISTANCE_CODES
+};
+
+static const uint8_t code_length_code_order[NUM_CODE_LENGTH_CODES] = {
+ 17, 18, 0, 1, 2, 3, 4, 5, 16, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+};
+
+static const int8_t lz77_distance_offsets[NUM_SHORT_DISTANCES][2] = {
+ { 0, 1 }, { 1, 0 }, { 1, 1 }, { -1, 1 }, { 0, 2 }, { 2, 0 }, { 1, 2 }, { -1, 2 },
+ { 2, 1 }, { -2, 1 }, { 2, 2 }, { -2, 2 }, { 0, 3 }, { 3, 0 }, { 1, 3 }, { -1, 3 },
+ { 3, 1 }, { -3, 1 }, { 2, 3 }, { -2, 3 }, { 3, 2 }, { -3, 2 }, { 0, 4 }, { 4, 0 },
+ { 1, 4 }, { -1, 4 }, { 4, 1 }, { -4, 1 }, { 3, 3 }, { -3, 3 }, { 2, 4 }, { -2, 4 },
+ { 4, 2 }, { -4, 2 }, { 0, 5 }, { 3, 4 }, { -3, 4 }, { 4, 3 }, { -4, 3 }, { 5, 0 },
+ { 1, 5 }, { -1, 5 }, { 5, 1 }, { -5, 1 }, { 2, 5 }, { -2, 5 }, { 5, 2 }, { -5, 2 },
+ { 4, 4 }, { -4, 4 }, { 3, 5 }, { -3, 5 }, { 5, 3 }, { -5, 3 }, { 0, 6 }, { 6, 0 },
+ { 1, 6 }, { -1, 6 }, { 6, 1 }, { -6, 1 }, { 2, 6 }, { -2, 6 }, { 6, 2 }, { -6, 2 },
+ { 4, 5 }, { -4, 5 }, { 5, 4 }, { -5, 4 }, { 3, 6 }, { -3, 6 }, { 6, 3 }, { -6, 3 },
+ { 0, 7 }, { 7, 0 }, { 1, 7 }, { -1, 7 }, { 5, 5 }, { -5, 5 }, { 7, 1 }, { -7, 1 },
+ { 4, 6 }, { -4, 6 }, { 6, 4 }, { -6, 4 }, { 2, 7 }, { -2, 7 }, { 7, 2 }, { -7, 2 },
+ { 3, 7 }, { -3, 7 }, { 7, 3 }, { -7, 3 }, { 5, 6 }, { -5, 6 }, { 6, 5 }, { -6, 5 },
+ { 8, 0 }, { 4, 7 }, { -4, 7 }, { 7, 4 }, { -7, 4 }, { 8, 1 }, { 8, 2 }, { 6, 6 },
+ { -6, 6 }, { 8, 3 }, { 5, 7 }, { -5, 7 }, { 7, 5 }, { -7, 5 }, { 8, 4 }, { 6, 7 },
+ { -6, 7 }, { 7, 6 }, { -7, 6 }, { 8, 5 }, { 7, 7 }, { -7, 7 }, { 8, 6 }, { 8, 7 }
+};
+
+enum AlphaCompression {
+ ALPHA_COMPRESSION_NONE,
+ ALPHA_COMPRESSION_VP8L,
+};
+
+enum AlphaFilter {
+ ALPHA_FILTER_NONE,
+ ALPHA_FILTER_HORIZONTAL,
+ ALPHA_FILTER_VERTICAL,
+ ALPHA_FILTER_GRADIENT,
+};
+
+enum TransformType {
+ PREDICTOR_TRANSFORM = 0,
+ COLOR_TRANSFORM = 1,
+ SUBTRACT_GREEN = 2,
+ COLOR_INDEXING_TRANSFORM = 3,
+};
+
+enum PredictionMode {
+ PRED_MODE_BLACK,
+ PRED_MODE_L,
+ PRED_MODE_T,
+ PRED_MODE_TR,
+ PRED_MODE_TL,
+ PRED_MODE_AVG_T_AVG_L_TR,
+ PRED_MODE_AVG_L_TL,
+ PRED_MODE_AVG_L_T,
+ PRED_MODE_AVG_TL_T,
+ PRED_MODE_AVG_T_TR,
+ PRED_MODE_AVG_AVG_L_TL_AVG_T_TR,
+ PRED_MODE_SELECT,
+ PRED_MODE_ADD_SUBTRACT_FULL,
+ PRED_MODE_ADD_SUBTRACT_HALF,
+};
+
+enum HuffmanIndex {
+ HUFF_IDX_GREEN = 0,
+ HUFF_IDX_RED = 1,
+ HUFF_IDX_BLUE = 2,
+ HUFF_IDX_ALPHA = 3,
+ HUFF_IDX_DIST = 4
+};
+
+/* The structure of WebP lossless is an optional series of transformation data,
+ * followed by the primary image. The primary image also optionally contains
+ * an entropy group mapping if there are multiple entropy groups. There is a
+ * basic image type called an "entropy coded image" that is used for all of
+ * these. The type of each entropy coded image is referred to by the
+ * specification as its role. */
+enum ImageRole {
+ /* Primary Image: Stores the actual pixels of the image. */
+ IMAGE_ROLE_ARGB,
+
+ /* Entropy Image: Defines which Huffman group to use for different areas of
+ * the primary image. */
+ IMAGE_ROLE_ENTROPY,
+
+ /* Predictors: Defines which predictor type to use for different areas of
+ * the primary image. */
+ IMAGE_ROLE_PREDICTOR,
+
+ /* Color Transform Data: Defines the color transformation for different
+ * areas of the primary image. */
+ IMAGE_ROLE_COLOR_TRANSFORM,
+
+ /* Color Index: Stored as an image of height == 1. */
+ IMAGE_ROLE_COLOR_INDEXING,
+
+ IMAGE_ROLE_NB,
+};
+
+typedef struct HuffReader {
+ VLC vlc; /* Huffman decoder context */
+ int simple; /* whether to use simple mode */
+ int nb_symbols; /* number of coded symbols */
+ uint16_t simple_symbols[2]; /* symbols for simple mode */
+} HuffReader;
+
+typedef struct ImageContext {
+ enum ImageRole role; /* role of this image */
+ AVFrame *frame; /* AVFrame for data */
+ int color_cache_bits; /* color cache size, log2 */
+ uint32_t *color_cache; /* color cache data */
+ int nb_huffman_groups; /* number of huffman groups */
+ HuffReader *huffman_groups; /* reader for each huffman group */
+ int size_reduction; /* relative size compared to primary image, log2 */
+ int is_alpha_primary;
+} ImageContext;
+
+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 */
+ AVCodecContext *avctx; /* parent AVCodecContext */
+ int initialized; /* set once the VP8 context is initialized */
+ int has_alpha; /* has a separate alpha chunk */
+ enum AlphaCompression alpha_compression; /* compression type for alpha chunk */
+ enum AlphaFilter alpha_filter; /* filtering method for alpha chunk */
+ uint8_t *alpha_data; /* alpha chunk data */
+ int alpha_data_size; /* alpha chunk data size */
+ int has_exif; /* set after an EXIF chunk has been processed */
+ AVDictionary *exif_metadata; /* EXIF chunk data */
+ int width; /* image width */
+ int height; /* image height */
+ int lossless; /* indicates lossless or lossy */
+
+ int nb_transforms; /* number of transforms */
+ enum TransformType transforms[4]; /* transformations used in the image, in order */
+ int reduced_width; /* reduced width for index image, if applicable */
+ int nb_huffman_groups; /* number of huffman groups in the primary image */
+ ImageContext image[IMAGE_ROLE_NB]; /* image context for each role */
+} WebPContext;
+
+#define GET_PIXEL(frame, x, y) \
+ ((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x))
+
+#define GET_PIXEL_COMP(frame, x, y, c) \
+ (*((frame)->data[0] + (y) * frame->linesize[0] + 4 * (x) + c))
+
+static void image_ctx_free(ImageContext *img)
+{
+ int i, j;
+
+ av_free(img->color_cache);
+ if (img->role != IMAGE_ROLE_ARGB && !img->is_alpha_primary)
+ av_frame_free(&img->frame);
+ if (img->huffman_groups) {
+ for (i = 0; i < img->nb_huffman_groups; i++) {
+ for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; j++)
+ ff_free_vlc(&img->huffman_groups[i * HUFFMAN_CODES_PER_META_CODE + j].vlc);
+ }
+ av_free(img->huffman_groups);
+ }
+ 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) {
+ if (r->nb_symbols == 1)
+ return r->simple_symbols[0];
+ else
+ return r->simple_symbols[get_bits1(gb)];
+ } else
+ return webp_get_vlc(gb, r->vlc.table);
+}
+
+static int huff_reader_build_canonical(HuffReader *r, int *code_lengths,
+ int alphabet_size)
+{
+ int len = 0, sym, code = 0, ret;
+ int max_code_length = 0;
+ uint16_t *codes;
+
+ /* special-case 1 symbol since the vlc reader cannot handle it */
+ for (sym = 0; sym < alphabet_size; sym++) {
+ if (code_lengths[sym] > 0) {
+ len++;
+ code = sym;
+ if (len > 1)
+ break;
+ }
+ }
+ if (len == 1) {
+ r->nb_symbols = 1;
+ r->simple_symbols[0] = code;
+ r->simple = 1;
+ return 0;
+ }
+
+ for (sym = 0; sym < alphabet_size; sym++)
+ max_code_length = FFMAX(max_code_length, code_lengths[sym]);
+
+ if (max_code_length == 0 || max_code_length > MAX_HUFFMAN_CODE_LENGTH)
+ return AVERROR(EINVAL);
+
+ codes = av_malloc_array(alphabet_size, sizeof(*codes));
+ if (!codes)
+ return AVERROR(ENOMEM);
+
+ code = 0;
+ r->nb_symbols = 0;
+ for (len = 1; len <= max_code_length; len++) {
+ for (sym = 0; sym < alphabet_size; sym++) {
+ if (code_lengths[sym] != len)
+ continue;
+ codes[sym] = code++;
+ r->nb_symbols++;
+ }
+ code <<= 1;
+ }
+ if (!r->nb_symbols) {
+ av_free(codes);
+ return AVERROR_INVALIDDATA;
+ }
+
+ ret = init_vlc(&r->vlc, 8, alphabet_size,
+ code_lengths, sizeof(*code_lengths), sizeof(*code_lengths),
+ codes, sizeof(*codes), sizeof(*codes), 0);
+ if (ret < 0) {
+ av_free(codes);
+ return ret;
+ }
+ r->simple = 0;
+
+ av_free(codes);
+ return 0;
+}
+
+static void read_huffman_code_simple(WebPContext *s, HuffReader *hc)
+{
+ hc->nb_symbols = get_bits1(&s->gb) + 1;
+
+ if (get_bits1(&s->gb))
+ hc->simple_symbols[0] = get_bits(&s->gb, 8);
+ else
+ hc->simple_symbols[0] = get_bits1(&s->gb);
+
+ if (hc->nb_symbols == 2)
+ hc->simple_symbols[1] = get_bits(&s->gb, 8);
+
+ hc->simple = 1;
+}
+
+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 };
+ 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;
+
+ for (i = 0; i < num_codes; i++)
+ code_length_code_lengths[code_length_code_order[i]] = get_bits(&s->gb, 3);
+
+ ret = huff_reader_build_canonical(&code_len_hc, code_length_code_lengths,
+ NUM_CODE_LENGTH_CODES);
+ if (ret < 0)
+ goto finish;
+
+ code_lengths = av_mallocz_array(alphabet_size, sizeof(*code_lengths));
+ if (!code_lengths) {
+ ret = AVERROR(ENOMEM);
+ goto finish;
+ }
+
+ if (get_bits1(&s->gb)) {
+ int bits = 2 + 2 * get_bits(&s->gb, 3);
+ max_symbol = 2 + get_bits(&s->gb, bits);
+ if (max_symbol > alphabet_size) {
+ av_log(s->avctx, AV_LOG_ERROR, "max symbol %d > alphabet size %d\n",
+ max_symbol, alphabet_size);
+ ret = AVERROR_INVALIDDATA;
+ goto finish;
+ }
+ } else {
+ max_symbol = alphabet_size;
+ }
+
+ prev_code_len = 8;
+ symbol = 0;
+ while (symbol < alphabet_size) {
+ int code_len;
+
+ if (!max_symbol--)
+ break;
+ code_len = huff_reader_get_symbol(&code_len_hc, &s->gb);
+ if (code_len < 16) {
+ /* Code length code [0..15] indicates literal code lengths. */
+ code_lengths[symbol++] = code_len;
+ if (code_len)
+ prev_code_len = code_len;
+ } else {
+ int repeat = 0, length = 0;
+ switch (code_len) {
+ case 16:
+ /* Code 16 repeats the previous non-zero value [3..6] times,
+ * i.e., 3 + ReadBits(2) times. If code 16 is used before a
+ * non-zero value has been emitted, a value of 8 is repeated. */
+ repeat = 3 + get_bits(&s->gb, 2);
+ length = prev_code_len;
+ break;
+ case 17:
+ /* Code 17 emits a streak of zeros [3..10], i.e.,
+ * 3 + ReadBits(3) times. */
+ repeat = 3 + get_bits(&s->gb, 3);
+ break;
+ case 18:
+ /* Code 18 emits a streak of zeros of length [11..138], i.e.,
+ * 11 + ReadBits(7) times. */
+ repeat = 11 + get_bits(&s->gb, 7);
+ break;
+ }
+ if (symbol + repeat > alphabet_size) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "invalid symbol %d + repeat %d > alphabet size %d\n",
+ symbol, repeat, alphabet_size);
+ ret = AVERROR_INVALIDDATA;
+ goto finish;
+ }
+ while (repeat-- > 0)
+ code_lengths[symbol++] = length;
+ }
+ }
+
+ ret = huff_reader_build_canonical(hc, code_lengths, alphabet_size);
+
+finish:
+ ff_free_vlc(&code_len_hc.vlc);
+ av_free(code_lengths);
+ return ret;
+}
+
+static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role,
+ int w, int h);
+
+#define PARSE_BLOCK_SIZE(w, h) do { \
+ block_bits = get_bits(&s->gb, 3) + 2; \
+ blocks_w = FFALIGN((w), 1 << block_bits) >> block_bits; \
+ blocks_h = FFALIGN((h), 1 << block_bits) >> block_bits; \
+} while (0)
+
+static int decode_entropy_image(WebPContext *s)
+{
+ ImageContext *img;
+ int ret, block_bits, width, blocks_w, blocks_h, x, y, max;
+
+ width = s->width;
+ if (s->reduced_width > 0)
+ width = s->reduced_width;
+
+ PARSE_BLOCK_SIZE(width, s->height);
+
+ ret = decode_entropy_coded_image(s, IMAGE_ROLE_ENTROPY, blocks_w, blocks_h);
+ if (ret < 0)
+ return ret;
+
+ img = &s->image[IMAGE_ROLE_ENTROPY];
+ img->size_reduction = block_bits;
+
+ /* the number of huffman groups is determined by the maximum group number
+ * coded in the entropy image */
+ max = 0;
+ for (y = 0; y < img->frame->height; y++) {
+ for (x = 0; x < img->frame->width; x++) {
+ int p0 = GET_PIXEL_COMP(img->frame, x, y, 1);
+ int p1 = GET_PIXEL_COMP(img->frame, x, y, 2);
+ int p = p0 << 8 | p1;
+ max = FFMAX(max, p);
+ }
+ }
+ s->nb_huffman_groups = max + 1;
+
+ return 0;
+}
+
+static int parse_transform_predictor(WebPContext *s)
+{
+ int block_bits, blocks_w, blocks_h, ret;
+
+ PARSE_BLOCK_SIZE(s->width, s->height);
+
+ ret = decode_entropy_coded_image(s, IMAGE_ROLE_PREDICTOR, blocks_w,
+ blocks_h);
+ if (ret < 0)
+ return ret;
+
+ s->image[IMAGE_ROLE_PREDICTOR].size_reduction = block_bits;
+
+ return 0;
+}
+
+static int parse_transform_color(WebPContext *s)
+{
+ int block_bits, blocks_w, blocks_h, ret;
+
+ PARSE_BLOCK_SIZE(s->width, s->height);
+
+ ret = decode_entropy_coded_image(s, IMAGE_ROLE_COLOR_TRANSFORM, blocks_w,
+ blocks_h);
+ if (ret < 0)
+ return ret;
+
+ s->image[IMAGE_ROLE_COLOR_TRANSFORM].size_reduction = block_bits;
+
+ return 0;
+}
+
+static int parse_transform_color_indexing(WebPContext *s)
+{
+ ImageContext *img;
+ int width_bits, index_size, ret, x;
+ uint8_t *ct;
+
+ index_size = get_bits(&s->gb, 8) + 1;
+
+ if (index_size <= 2)
+ width_bits = 3;
+ else if (index_size <= 4)
+ width_bits = 2;
+ else if (index_size <= 16)
+ width_bits = 1;
+ else
+ width_bits = 0;
+
+ ret = decode_entropy_coded_image(s, IMAGE_ROLE_COLOR_INDEXING,
+ index_size, 1);
+ if (ret < 0)
+ return ret;
+
+ img = &s->image[IMAGE_ROLE_COLOR_INDEXING];
+ img->size_reduction = width_bits;
+ if (width_bits > 0)
+ s->reduced_width = (s->width + ((1 << width_bits) - 1)) >> width_bits;
+
+ /* color index values are delta-coded */
+ ct = img->frame->data[0] + 4;
+ for (x = 4; x < img->frame->width * 4; x++, ct++)
+ ct[0] += ct[-4];
+
+ return 0;
+}
+
+static HuffReader *get_huffman_group(WebPContext *s, ImageContext *img,
+ int x, int y)
+{
+ ImageContext *gimg = &s->image[IMAGE_ROLE_ENTROPY];
+ int group = 0;
+
+ if (gimg->size_reduction > 0) {
+ int group_x = x >> gimg->size_reduction;
+ int group_y = y >> gimg->size_reduction;
+ int g0 = GET_PIXEL_COMP(gimg->frame, group_x, group_y, 1);
+ int g1 = GET_PIXEL_COMP(gimg->frame, group_x, group_y, 2);
+ group = g0 << 8 | g1;
+ }
+
+ return &img->huffman_groups[group * HUFFMAN_CODES_PER_META_CODE];
+}
+
+static av_always_inline void color_cache_put(ImageContext *img, uint32_t c)
+{
+ uint32_t cache_idx = (0x1E35A7BD * c) >> (32 - img->color_cache_bits);
+ img->color_cache[cache_idx] = c;
+}
+
+static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role,
+ int w, int h)
+{
+ ImageContext *img;
+ HuffReader *hg;
+ int i, j, ret, x, y, width;
+
+ img = &s->image[role];
+ img->role = role;
+
+ if (!img->frame) {
+ img->frame = av_frame_alloc();
+ if (!img->frame)
+ return AVERROR(ENOMEM);
+ }
+
+ img->frame->format = AV_PIX_FMT_ARGB;
+ img->frame->width = w;
+ img->frame->height = h;
+
+ if (role == IMAGE_ROLE_ARGB && !img->is_alpha_primary) {
+ ThreadFrame pt = { .f = img->frame };
+ ret = ff_thread_get_buffer(s->avctx, &pt, 0);
+ } else
+ ret = av_frame_get_buffer(img->frame, 1);
+ if (ret < 0)
+ return ret;
+
+ if (get_bits1(&s->gb)) {
+ img->color_cache_bits = get_bits(&s->gb, 4);
+ if (img->color_cache_bits < 1 || img->color_cache_bits > 11) {
+ av_log(s->avctx, AV_LOG_ERROR, "invalid color cache bits: %d\n",
+ img->color_cache_bits);
+ return AVERROR_INVALIDDATA;
+ }
+ img->color_cache = av_mallocz_array(1 << img->color_cache_bits,
+ sizeof(*img->color_cache));
+ if (!img->color_cache)
+ return AVERROR(ENOMEM);
+ } else {
+ img->color_cache_bits = 0;
+ }
+
+ img->nb_huffman_groups = 1;
+ if (role == IMAGE_ROLE_ARGB && get_bits1(&s->gb)) {
+ ret = decode_entropy_image(s);
+ if (ret < 0)
+ return ret;
+ img->nb_huffman_groups = s->nb_huffman_groups;
+ }
+ img->huffman_groups = av_mallocz_array(img->nb_huffman_groups *
+ HUFFMAN_CODES_PER_META_CODE,
+ sizeof(*img->huffman_groups));
+ if (!img->huffman_groups)
+ return AVERROR(ENOMEM);
+
+ for (i = 0; i < img->nb_huffman_groups; i++) {
+ hg = &img->huffman_groups[i * HUFFMAN_CODES_PER_META_CODE];
+ for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; j++) {
+ int alphabet_size = alphabet_sizes[j];
+ if (!j && img->color_cache_bits > 0)
+ alphabet_size += 1 << img->color_cache_bits;
+
+ if (get_bits1(&s->gb)) {
+ read_huffman_code_simple(s, &hg[j]);
+ } else {
+ ret = read_huffman_code_normal(s, &hg[j], alphabet_size);
+ if (ret < 0)
+ return ret;
+ }
+ }
+ }
+
+ width = img->frame->width;
+ if (role == IMAGE_ROLE_ARGB && s->reduced_width > 0)
+ width = s->reduced_width;
+
+ x = 0; y = 0;
+ while (y < img->frame->height) {
+ int v;
+
+ hg = get_huffman_group(s, img, x, y);
+ v = huff_reader_get_symbol(&hg[HUFF_IDX_GREEN], &s->gb);
+ if (v < NUM_LITERAL_CODES) {
+ /* literal pixel values */
+ uint8_t *p = GET_PIXEL(img->frame, x, y);
+ p[2] = v;
+ p[1] = huff_reader_get_symbol(&hg[HUFF_IDX_RED], &s->gb);
+ p[3] = huff_reader_get_symbol(&hg[HUFF_IDX_BLUE], &s->gb);
+ p[0] = huff_reader_get_symbol(&hg[HUFF_IDX_ALPHA], &s->gb);
+ if (img->color_cache_bits)
+ color_cache_put(img, AV_RB32(p));
+ x++;
+ if (x == width) {
+ x = 0;
+ y++;
+ }
+ } else if (v < NUM_LITERAL_CODES + NUM_LENGTH_CODES) {
+ /* LZ77 backwards mapping */
+ int prefix_code, length, distance, ref_x, ref_y;
+
+ /* parse length and distance */
+ prefix_code = v - NUM_LITERAL_CODES;
+ if (prefix_code < 4) {
+ length = prefix_code + 1;
+ } else {
+ int extra_bits = (prefix_code - 2) >> 1;
+ int offset = 2 + (prefix_code & 1) << extra_bits;
+ length = offset + get_bits(&s->gb, extra_bits) + 1;
+ }
+ prefix_code = huff_reader_get_symbol(&hg[HUFF_IDX_DIST], &s->gb);
+ if (prefix_code > 39U) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "distance prefix code too large: %d\n", prefix_code);
+ return AVERROR_INVALIDDATA;
+ }
+ if (prefix_code < 4) {
+ distance = prefix_code + 1;
+ } else {
+ int extra_bits = prefix_code - 2 >> 1;
+ int offset = 2 + (prefix_code & 1) << extra_bits;
+ distance = offset + get_bits(&s->gb, extra_bits) + 1;
+ }
+
+ /* find reference location */
+ if (distance <= NUM_SHORT_DISTANCES) {
+ int xi = lz77_distance_offsets[distance - 1][0];
+ int yi = lz77_distance_offsets[distance - 1][1];
+ distance = FFMAX(1, xi + yi * width);
+ } else {
+ distance -= NUM_SHORT_DISTANCES;
+ }
+ ref_x = x;
+ ref_y = y;
+ if (distance <= x) {
+ ref_x -= distance;
+ distance = 0;
+ } else {
+ ref_x = 0;
+ distance -= x;
+ }
+ while (distance >= width) {
+ ref_y--;
+ distance -= width;
+ }
+ if (distance > 0) {
+ ref_x = width - distance;
+ ref_y--;
+ }
+ ref_x = FFMAX(0, ref_x);
+ ref_y = FFMAX(0, ref_y);
+
+ /* copy pixels
+ * source and dest regions can overlap and wrap lines, so just
+ * copy per-pixel */
+ for (i = 0; i < length; i++) {
+ uint8_t *p_ref = GET_PIXEL(img->frame, ref_x, ref_y);
+ uint8_t *p = GET_PIXEL(img->frame, x, y);
+
+ AV_COPY32(p, p_ref);
+ if (img->color_cache_bits)
+ color_cache_put(img, AV_RB32(p));
+ x++;
+ ref_x++;
+ if (x == width) {
+ x = 0;
+ y++;
+ }
+ if (ref_x == width) {
+ ref_x = 0;
+ ref_y++;
+ }
+ if (y == img->frame->height || ref_y == img->frame->height)
+ break;
+ }
+ } else {
+ /* read from color cache */
+ uint8_t *p = GET_PIXEL(img->frame, x, y);
+ int cache_idx = v - (NUM_LITERAL_CODES + NUM_LENGTH_CODES);
+
+ if (!img->color_cache_bits) {
+ av_log(s->avctx, AV_LOG_ERROR, "color cache not found\n");
+ return AVERROR_INVALIDDATA;
+ }
+ if (cache_idx >= 1 << img->color_cache_bits) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "color cache index out-of-bounds\n");
+ return AVERROR_INVALIDDATA;
+ }
+ AV_WB32(p, img->color_cache[cache_idx]);
+ x++;
+ if (x == width) {
+ x = 0;
+ y++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+/* PRED_MODE_BLACK */
+static void inv_predict_0(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+ const uint8_t *p_t, const uint8_t *p_tr)
+{
+ AV_WB32(p, 0xFF000000);
+}
+
+/* PRED_MODE_L */
+static void inv_predict_1(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+ const uint8_t *p_t, const uint8_t *p_tr)
+{
+ AV_COPY32(p, p_l);
+}
+
+/* PRED_MODE_T */
+static void inv_predict_2(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+ const uint8_t *p_t, const uint8_t *p_tr)
+{
+ AV_COPY32(p, p_t);
+}
+
+/* PRED_MODE_TR */
+static void inv_predict_3(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+ const uint8_t *p_t, const uint8_t *p_tr)
+{
+ AV_COPY32(p, p_tr);
+}
+
+/* PRED_MODE_TL */
+static void inv_predict_4(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+ const uint8_t *p_t, const uint8_t *p_tr)
+{
+ AV_COPY32(p, p_tl);
+}
+
+/* PRED_MODE_AVG_T_AVG_L_TR */
+static void inv_predict_5(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+ const uint8_t *p_t, const uint8_t *p_tr)
+{
+ p[0] = p_t[0] + (p_l[0] + p_tr[0] >> 1) >> 1;
+ p[1] = p_t[1] + (p_l[1] + p_tr[1] >> 1) >> 1;
+ p[2] = p_t[2] + (p_l[2] + p_tr[2] >> 1) >> 1;
+ p[3] = p_t[3] + (p_l[3] + p_tr[3] >> 1) >> 1;
+}
+
+/* PRED_MODE_AVG_L_TL */
+static void inv_predict_6(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+ const uint8_t *p_t, const uint8_t *p_tr)
+{
+ p[0] = p_l[0] + p_tl[0] >> 1;
+ p[1] = p_l[1] + p_tl[1] >> 1;
+ p[2] = p_l[2] + p_tl[2] >> 1;
+ p[3] = p_l[3] + p_tl[3] >> 1;
+}
+
+/* PRED_MODE_AVG_L_T */
+static void inv_predict_7(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+ const uint8_t *p_t, const uint8_t *p_tr)
+{
+ p[0] = p_l[0] + p_t[0] >> 1;
+ p[1] = p_l[1] + p_t[1] >> 1;
+ p[2] = p_l[2] + p_t[2] >> 1;
+ p[3] = p_l[3] + p_t[3] >> 1;
+}
+
+/* PRED_MODE_AVG_TL_T */
+static void inv_predict_8(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+ const uint8_t *p_t, const uint8_t *p_tr)
+{
+ p[0] = p_tl[0] + p_t[0] >> 1;
+ p[1] = p_tl[1] + p_t[1] >> 1;
+ p[2] = p_tl[2] + p_t[2] >> 1;
+ p[3] = p_tl[3] + p_t[3] >> 1;
+}
+
+/* PRED_MODE_AVG_T_TR */
+static void inv_predict_9(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+ const uint8_t *p_t, const uint8_t *p_tr)
+{
+ p[0] = p_t[0] + p_tr[0] >> 1;
+ p[1] = p_t[1] + p_tr[1] >> 1;
+ p[2] = p_t[2] + p_tr[2] >> 1;
+ p[3] = p_t[3] + p_tr[3] >> 1;
+}
+
+/* PRED_MODE_AVG_AVG_L_TL_AVG_T_TR */
+static void inv_predict_10(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+ const uint8_t *p_t, const uint8_t *p_tr)
+{
+ p[0] = (p_l[0] + p_tl[0] >> 1) + (p_t[0] + p_tr[0] >> 1) >> 1;
+ p[1] = (p_l[1] + p_tl[1] >> 1) + (p_t[1] + p_tr[1] >> 1) >> 1;
+ p[2] = (p_l[2] + p_tl[2] >> 1) + (p_t[2] + p_tr[2] >> 1) >> 1;
+ p[3] = (p_l[3] + p_tl[3] >> 1) + (p_t[3] + p_tr[3] >> 1) >> 1;
+}
+
+/* PRED_MODE_SELECT */
+static void inv_predict_11(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+ const uint8_t *p_t, const uint8_t *p_tr)
+{
+ int diff = (FFABS(p_l[0] - p_tl[0]) - FFABS(p_t[0] - p_tl[0])) +
+ (FFABS(p_l[1] - p_tl[1]) - FFABS(p_t[1] - p_tl[1])) +
+ (FFABS(p_l[2] - p_tl[2]) - FFABS(p_t[2] - p_tl[2])) +
+ (FFABS(p_l[3] - p_tl[3]) - FFABS(p_t[3] - p_tl[3]));
+ if (diff <= 0)
+ AV_COPY32(p, p_t);
+ else
+ AV_COPY32(p, p_l);
+}
+
+/* PRED_MODE_ADD_SUBTRACT_FULL */
+static void inv_predict_12(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+ const uint8_t *p_t, const uint8_t *p_tr)
+{
+ p[0] = av_clip_uint8(p_l[0] + p_t[0] - p_tl[0]);
+ p[1] = av_clip_uint8(p_l[1] + p_t[1] - p_tl[1]);
+ p[2] = av_clip_uint8(p_l[2] + p_t[2] - p_tl[2]);
+ p[3] = av_clip_uint8(p_l[3] + p_t[3] - p_tl[3]);
+}
+
+static av_always_inline uint8_t clamp_add_subtract_half(int a, int b, int c)
+{
+ int d = a + b >> 1;
+ return av_clip_uint8(d + (d - c) / 2);
+}
+
+/* PRED_MODE_ADD_SUBTRACT_HALF */
+static void inv_predict_13(uint8_t *p, const uint8_t *p_l, const uint8_t *p_tl,
+ const uint8_t *p_t, const uint8_t *p_tr)
+{
+ p[0] = clamp_add_subtract_half(p_l[0], p_t[0], p_tl[0]);
+ p[1] = clamp_add_subtract_half(p_l[1], p_t[1], p_tl[1]);
+ p[2] = clamp_add_subtract_half(p_l[2], p_t[2], p_tl[2]);
+ p[3] = clamp_add_subtract_half(p_l[3], p_t[3], p_tl[3]);
+}
+
+typedef void (*inv_predict_func)(uint8_t *p, const uint8_t *p_l,
+ const uint8_t *p_tl, const uint8_t *p_t,
+ const uint8_t *p_tr);
+
+static const inv_predict_func inverse_predict[14] = {
+ inv_predict_0, inv_predict_1, inv_predict_2, inv_predict_3,
+ inv_predict_4, inv_predict_5, inv_predict_6, inv_predict_7,
+ inv_predict_8, inv_predict_9, inv_predict_10, inv_predict_11,
+ inv_predict_12, inv_predict_13,
+};
+
+static void inverse_prediction(AVFrame *frame, enum PredictionMode m, int x, int y)
+{
+ uint8_t *dec, *p_l, *p_tl, *p_t, *p_tr;
+ uint8_t p[4];
+
+ dec = GET_PIXEL(frame, x, y);
+ p_l = GET_PIXEL(frame, x - 1, y);
+ p_tl = GET_PIXEL(frame, x - 1, y - 1);
+ p_t = GET_PIXEL(frame, x, y - 1);
+ if (x == frame->width - 1)
+ p_tr = GET_PIXEL(frame, 0, y);
+ else
+ p_tr = GET_PIXEL(frame, x + 1, y - 1);
+
+ inverse_predict[m](p, p_l, p_tl, p_t, p_tr);
+
+ dec[0] += p[0];
+ dec[1] += p[1];
+ dec[2] += p[2];
+ dec[3] += p[3];
+}
+
+static int apply_predictor_transform(WebPContext *s)
+{
+ ImageContext *img = &s->image[IMAGE_ROLE_ARGB];
+ ImageContext *pimg = &s->image[IMAGE_ROLE_PREDICTOR];
+ int x, y;
+
+ for (y = 0; y < img->frame->height; y++) {
+ for (x = 0; x < img->frame->width; x++) {
+ int tx = x >> pimg->size_reduction;
+ int ty = y >> pimg->size_reduction;
+ enum PredictionMode m = GET_PIXEL_COMP(pimg->frame, tx, ty, 2);
+
+ if (x == 0) {
+ if (y == 0)
+ m = PRED_MODE_BLACK;
+ else
+ m = PRED_MODE_T;
+ } else if (y == 0)
+ m = PRED_MODE_L;
+
+ if (m > 13) {
+ av_log(s->avctx, AV_LOG_ERROR,
+ "invalid predictor mode: %d\n", m);
+ return AVERROR_INVALIDDATA;
+ }
+ inverse_prediction(img->frame, m, x, y);
+ }
+ }
+ return 0;
+}
+
+static av_always_inline uint8_t color_transform_delta(uint8_t color_pred,
+ uint8_t color)
+{
+ return (int)ff_u8_to_s8(color_pred) * ff_u8_to_s8(color) >> 5;
+}
+
+static int apply_color_transform(WebPContext *s)
+{
+ ImageContext *img, *cimg;
+ int x, y, cx, cy;
+ uint8_t *p, *cp;
+
+ img = &s->image[IMAGE_ROLE_ARGB];
+ cimg = &s->image[IMAGE_ROLE_COLOR_TRANSFORM];
+
+ for (y = 0; y < img->frame->height; y++) {
+ for (x = 0; x < img->frame->width; x++) {
+ cx = x >> cimg->size_reduction;
+ cy = y >> cimg->size_reduction;
+ cp = GET_PIXEL(cimg->frame, cx, cy);
+ p = GET_PIXEL(img->frame, x, y);
+
+ p[1] += color_transform_delta(cp[3], p[2]);
+ p[3] += color_transform_delta(cp[2], p[2]) +
+ color_transform_delta(cp[1], p[1]);
+ }
+ }
+ return 0;
+}
+
+static int apply_subtract_green_transform(WebPContext *s)
+{
+ int x, y;
+ ImageContext *img = &s->image[IMAGE_ROLE_ARGB];
+
+ for (y = 0; y < img->frame->height; y++) {
+ for (x = 0; x < img->frame->width; x++) {
+ uint8_t *p = GET_PIXEL(img->frame, x, y);
+ p[1] += p[2];
+ p[3] += p[2];
+ }
+ }
+ return 0;
+}
+
+static int apply_color_indexing_transform(WebPContext *s)
+{
+ ImageContext *img;
+ ImageContext *pal;
+ int i, x, y;
+ uint8_t *p;
+
+ img = &s->image[IMAGE_ROLE_ARGB];
+ pal = &s->image[IMAGE_ROLE_COLOR_INDEXING];
+
+ if (pal->size_reduction > 0) {
+ GetBitContext gb_g;
+ uint8_t *line;
+ int pixel_bits = 8 >> pal->size_reduction;
+
+ line = av_malloc(img->frame->linesize[0] + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!line)
+ return AVERROR(ENOMEM);
+
+ for (y = 0; y < img->frame->height; y++) {
+ p = GET_PIXEL(img->frame, 0, y);
+ memcpy(line, p, img->frame->linesize[0]);
+ init_get_bits(&gb_g, line, img->frame->linesize[0] * 8);
+ skip_bits(&gb_g, 16);
+ i = 0;
+ for (x = 0; x < img->frame->width; x++) {
+ p = GET_PIXEL(img->frame, x, y);
+ p[2] = get_bits(&gb_g, pixel_bits);
+ i++;
+ if (i == 1 << pal->size_reduction) {
+ skip_bits(&gb_g, 24);
+ i = 0;
+ }
+ }
+ }
+ av_free(line);
+ }
+
+ // switch to local palette if it's worth initializing it
+ if (img->frame->height * img->frame->width > 300) {
+ uint8_t palette[256 * 4];
+ const int size = pal->frame->width * 4;
+ av_assert0(size <= 1024U);
+ memcpy(palette, GET_PIXEL(pal->frame, 0, 0), size); // copy palette
+ // set extra entries to transparent black
+ memset(palette + size, 0, 256 * 4 - size);
+ for (y = 0; y < img->frame->height; y++) {
+ for (x = 0; x < img->frame->width; x++) {
+ p = GET_PIXEL(img->frame, x, y);
+ i = p[2];
+ AV_COPY32(p, &palette[i * 4]);
+ }
+ }
+ } else {
+ for (y = 0; y < img->frame->height; y++) {
+ for (x = 0; x < img->frame->width; x++) {
+ p = GET_PIXEL(img->frame, x, y);
+ i = p[2];
+ if (i >= pal->frame->width) {
+ AV_WB32(p, 0x00000000);
+ } else {
+ const uint8_t *pi = GET_PIXEL(pal->frame, i, 0);
+ AV_COPY32(p, pi);
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static void update_canvas_size(AVCodecContext *avctx, int w, int h)
+{
+ WebPContext *s = avctx->priv_data;
+ if (s->width && s->width != w) {
+ av_log(avctx, AV_LOG_WARNING, "Width mismatch. %d != %d\n",
+ s->width, w);
+ }
+ s->width = w;
+ if (s->height && s->height != h) {
+ av_log(avctx, AV_LOG_WARNING, "Height mismatch. %d != %d\n",
+ s->height, h);
+ }
+ s->height = h;
+}
+
+static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p,
+ int *got_frame, uint8_t *data_start,
+ unsigned int data_size, int is_alpha_chunk)
+{
+ WebPContext *s = avctx->priv_data;
+ int w, h, ret, i, used;
+
+ if (!is_alpha_chunk) {
+ s->lossless = 1;
+ avctx->pix_fmt = AV_PIX_FMT_ARGB;
+ }
+
+ ret = init_get_bits8(&s->gb, data_start, data_size);
+ if (ret < 0)
+ return ret;
+
+ if (!is_alpha_chunk) {
+ if (get_bits(&s->gb, 8) != 0x2F) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless signature\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ w = get_bits(&s->gb, 14) + 1;
+ h = get_bits(&s->gb, 14) + 1;
+
+ update_canvas_size(avctx, w, h);
+
+ ret = ff_set_dimensions(avctx, s->width, s->height);
+ if (ret < 0)
+ return ret;
+
+ s->has_alpha = get_bits1(&s->gb);
+
+ if (get_bits(&s->gb, 3) != 0x0) {
+ av_log(avctx, AV_LOG_ERROR, "Invalid WebP Lossless version\n");
+ return AVERROR_INVALIDDATA;
+ }
+ } else {
+ if (!s->width || !s->height)
+ return AVERROR_BUG;
+ w = s->width;
+ h = s->height;
+ }
+
+ /* parse transformations */
+ s->nb_transforms = 0;
+ s->reduced_width = 0;
+ used = 0;
+ while (get_bits1(&s->gb)) {
+ enum TransformType transform = get_bits(&s->gb, 2);
+ if (used & (1 << transform)) {
+ av_log(avctx, AV_LOG_ERROR, "Transform %d used more than once\n",
+ transform);
+ ret = AVERROR_INVALIDDATA;
+ goto free_and_return;
+ }
+ used |= (1 << transform);
+ s->transforms[s->nb_transforms++] = transform;
+ switch (transform) {
+ case PREDICTOR_TRANSFORM:
+ ret = parse_transform_predictor(s);
+ break;
+ case COLOR_TRANSFORM:
+ ret = parse_transform_color(s);
+ break;
+ case COLOR_INDEXING_TRANSFORM:
+ ret = parse_transform_color_indexing(s);
+ break;
+ }
+ if (ret < 0)
+ goto free_and_return;
+ }
+
+ /* decode primary image */
+ s->image[IMAGE_ROLE_ARGB].frame = p;
+ if (is_alpha_chunk)
+ s->image[IMAGE_ROLE_ARGB].is_alpha_primary = 1;
+ ret = decode_entropy_coded_image(s, IMAGE_ROLE_ARGB, w, h);
+ if (ret < 0)
+ goto free_and_return;
+
+ /* apply transformations */
+ for (i = s->nb_transforms - 1; i >= 0; i--) {
+ switch (s->transforms[i]) {
+ case PREDICTOR_TRANSFORM:
+ ret = apply_predictor_transform(s);
+ break;
+ case COLOR_TRANSFORM:
+ ret = apply_color_transform(s);
+ break;
+ case SUBTRACT_GREEN:
+ ret = apply_subtract_green_transform(s);
+ break;
+ case COLOR_INDEXING_TRANSFORM:
+ ret = apply_color_indexing_transform(s);
+ break;
+ }
+ if (ret < 0)
+ goto free_and_return;
+ }
+
+ *got_frame = 1;
+ p->pict_type = AV_PICTURE_TYPE_I;
+ p->key_frame = 1;
+ ret = data_size;
+
+free_and_return:
+ for (i = 0; i < IMAGE_ROLE_NB; i++)
+ image_ctx_free(&s->image[i]);
+
+ return ret;
+}
+
+static void alpha_inverse_prediction(AVFrame *frame, enum AlphaFilter m)
+{
+ int x, y, ls;
+ uint8_t *dec;
+
+ ls = frame->linesize[3];
+
+ /* filter first row using horizontal filter */
+ dec = frame->data[3] + 1;
+ for (x = 1; x < frame->width; x++, dec++)
+ *dec += *(dec - 1);
+
+ /* filter first column using vertical filter */
+ dec = frame->data[3] + ls;
+ for (y = 1; y < frame->height; y++, dec += ls)
+ *dec += *(dec - ls);
+
+ /* filter the rest using the specified filter */
+ switch (m) {
+ case ALPHA_FILTER_HORIZONTAL:
+ for (y = 1; y < frame->height; y++) {
+ dec = frame->data[3] + y * ls + 1;
+ for (x = 1; x < frame->width; x++, dec++)
+ *dec += *(dec - 1);
+ }
+ break;
+ case ALPHA_FILTER_VERTICAL:
+ for (y = 1; y < frame->height; y++) {
+ dec = frame->data[3] + y * ls + 1;
+ for (x = 1; x < frame->width; x++, dec++)
+ *dec += *(dec - ls);
+ }
+ break;
+ case ALPHA_FILTER_GRADIENT:
+ for (y = 1; y < frame->height; y++) {
+ dec = frame->data[3] + y * ls + 1;
+ for (x = 1; x < frame->width; x++, dec++)
+ dec[0] += av_clip_uint8(*(dec - 1) + *(dec - ls) - *(dec - ls - 1));
+ }
+ break;
+ }
+}
+
+static int vp8_lossy_decode_alpha(AVCodecContext *avctx, AVFrame *p,
+ uint8_t *data_start,
+ unsigned int data_size)
+{
+ WebPContext *s = avctx->priv_data;
+ int x, y, ret;
+
+ if (s->alpha_compression == ALPHA_COMPRESSION_NONE) {
+ GetByteContext gb;
+
+ bytestream2_init(&gb, data_start, data_size);
+ for (y = 0; y < s->height; y++)
+ bytestream2_get_buffer(&gb, p->data[3] + p->linesize[3] * y,
+ s->width);
+ } else if (s->alpha_compression == ALPHA_COMPRESSION_VP8L) {
+ uint8_t *ap, *pp;
+ int alpha_got_frame = 0;
+
+ s->alpha_frame = av_frame_alloc();
+ if (!s->alpha_frame)
+ return AVERROR(ENOMEM);
+
+ ret = vp8_lossless_decode_frame(avctx, s->alpha_frame, &alpha_got_frame,
+ data_start, data_size, 1);
+ if (ret < 0) {
+ av_frame_free(&s->alpha_frame);
+ return ret;
+ }
+ if (!alpha_got_frame) {
+ av_frame_free(&s->alpha_frame);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* copy green component of alpha image to alpha plane of primary image */
+ for (y = 0; y < s->height; y++) {
+ ap = GET_PIXEL(s->alpha_frame, 0, y) + 2;
+ pp = p->data[3] + p->linesize[3] * y;
+ for (x = 0; x < s->width; x++) {
+ *pp = *ap;
+ pp++;
+ ap += 4;
+ }
+ }
+ av_frame_free(&s->alpha_frame);
+ }
+
+ /* apply alpha filtering */
+ if (s->alpha_filter)
+ alpha_inverse_prediction(p, s->alpha_filter);
+
+ return 0;
+}
+
+static int vp8_lossy_decode_frame(AVCodecContext *avctx, AVFrame *p,
+ int *got_frame, uint8_t *data_start,
+ unsigned int data_size)
+{
+ WebPContext *s = avctx->priv_data;
+ AVPacket pkt;
+ int ret;
+
+ if (!s->initialized) {
+ ff_vp8_decode_init(avctx);
+ s->initialized = 1;
+ }
+ avctx->pix_fmt = s->has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P;
+ s->lossless = 0;
+
+ if (data_size > INT_MAX) {
+ av_log(avctx, AV_LOG_ERROR, "unsupported chunk size\n");
+ return AVERROR_PATCHWELCOME;
+ }
+
+ av_init_packet(&pkt);
+ pkt.data = data_start;
+ pkt.size = data_size;
+
+ ret = ff_vp8_decode_frame(avctx, p, got_frame, &pkt);
+ if (ret < 0)
+ return ret;
+
+ if (!*got_frame)
+ return AVERROR_INVALIDDATA;
+
+ update_canvas_size(avctx, avctx->width, avctx->height);
+
+ if (s->has_alpha) {
+ ret = vp8_lossy_decode_alpha(avctx, p, s->alpha_data,
+ s->alpha_data_size);
+ if (ret < 0)
+ return ret;
+ }
+ return ret;
+}
+
+static int webp_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
+ AVPacket *avpkt)
+{
+ AVFrame * const p = data;
+ WebPContext *s = avctx->priv_data;
+ GetByteContext gb;
+ int ret;
+ uint32_t chunk_type, chunk_size;
+ int vp8x_flags = 0;
+
+ s->avctx = avctx;
+ s->width = 0;
+ s->height = 0;
+ *got_frame = 0;
+ s->has_alpha = 0;
+ s->has_exif = 0;
+ bytestream2_init(&gb, avpkt->data, avpkt->size);
+
+ if (bytestream2_get_bytes_left(&gb) < 12)
+ return AVERROR_INVALIDDATA;
+
+ if (bytestream2_get_le32(&gb) != MKTAG('R', 'I', 'F', 'F')) {
+ av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ chunk_size = bytestream2_get_le32(&gb);
+ if (bytestream2_get_bytes_left(&gb) < chunk_size)
+ return AVERROR_INVALIDDATA;
+
+ if (bytestream2_get_le32(&gb) != MKTAG('W', 'E', 'B', 'P')) {
+ av_log(avctx, AV_LOG_ERROR, "missing WEBP tag\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ av_dict_free(&s->exif_metadata);
+ while (bytestream2_get_bytes_left(&gb) > 8) {
+ char chunk_str[5] = { 0 };
+
+ chunk_type = bytestream2_get_le32(&gb);
+ chunk_size = bytestream2_get_le32(&gb);
+ if (chunk_size == UINT32_MAX)
+ return AVERROR_INVALIDDATA;
+ chunk_size += chunk_size & 1;
+
+ if (bytestream2_get_bytes_left(&gb) < chunk_size)
+ return AVERROR_INVALIDDATA;
+
+ switch (chunk_type) {
+ case MKTAG('V', 'P', '8', ' '):
+ if (!*got_frame) {
+ ret = vp8_lossy_decode_frame(avctx, p, got_frame,
+ avpkt->data + bytestream2_tell(&gb),
+ chunk_size);
+ if (ret < 0)
+ return ret;
+ }
+ bytestream2_skip(&gb, chunk_size);
+ break;
+ case MKTAG('V', 'P', '8', 'L'):
+ if (!*got_frame) {
+ ret = vp8_lossless_decode_frame(avctx, p, got_frame,
+ avpkt->data + bytestream2_tell(&gb),
+ chunk_size, 0);
+ if (ret < 0)
+ return ret;
+ avctx->properties |= FF_CODEC_PROPERTY_LOSSLESS;
+ }
+ bytestream2_skip(&gb, chunk_size);
+ break;
+ case MKTAG('V', 'P', '8', 'X'):
+ vp8x_flags = bytestream2_get_byte(&gb);
+ bytestream2_skip(&gb, 3);
+ s->width = bytestream2_get_le24(&gb) + 1;
+ s->height = bytestream2_get_le24(&gb) + 1;
+ ret = av_image_check_size(s->width, s->height, 0, avctx);
+ if (ret < 0)
+ return ret;
+ break;
+ case MKTAG('A', 'L', 'P', 'H'): {
+ int alpha_header, filter_m, compression;
+
+ if (!(vp8x_flags & VP8X_FLAG_ALPHA)) {
+ av_log(avctx, AV_LOG_WARNING,
+ "ALPHA chunk present, but alpha bit not set in the "
+ "VP8X header\n");
+ }
+ if (chunk_size == 0) {
+ av_log(avctx, AV_LOG_ERROR, "invalid ALPHA chunk size\n");
+ return AVERROR_INVALIDDATA;
+ }
+ alpha_header = bytestream2_get_byte(&gb);
+ s->alpha_data = avpkt->data + bytestream2_tell(&gb);
+ s->alpha_data_size = chunk_size - 1;
+ bytestream2_skip(&gb, s->alpha_data_size);
+
+ filter_m = (alpha_header >> 2) & 0x03;
+ compression = alpha_header & 0x03;
+
+ if (compression > ALPHA_COMPRESSION_VP8L) {
+ av_log(avctx, AV_LOG_VERBOSE,
+ "skipping unsupported ALPHA chunk\n");
+ } else {
+ s->has_alpha = 1;
+ s->alpha_compression = compression;
+ s->alpha_filter = filter_m;
+ }
+
+ break;
+ }
+ case MKTAG('E', 'X', 'I', 'F'): {
+ int le, ifd_offset, exif_offset = bytestream2_tell(&gb);
+ GetByteContext exif_gb;
+
+ if (s->has_exif) {
+ av_log(avctx, AV_LOG_VERBOSE, "Ignoring extra EXIF chunk\n");
+ goto exif_end;
+ }
+ if (!(vp8x_flags & VP8X_FLAG_EXIF_METADATA))
+ av_log(avctx, AV_LOG_WARNING,
+ "EXIF chunk present, but Exif bit not set in the "
+ "VP8X header\n");
+
+ s->has_exif = 1;
+ bytestream2_init(&exif_gb, avpkt->data + exif_offset,
+ avpkt->size - exif_offset);
+ if (ff_tdecode_header(&exif_gb, &le, &ifd_offset) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "invalid TIFF header "
+ "in Exif data\n");
+ goto exif_end;
+ }
+
+ bytestream2_seek(&exif_gb, ifd_offset, SEEK_SET);
+ if (avpriv_exif_decode_ifd(avctx, &exif_gb, le, 0, &s->exif_metadata) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "error decoding Exif data\n");
+ goto exif_end;
+ }
+
+ av_dict_copy(avpriv_frame_get_metadatap(data), s->exif_metadata, 0);
+
+exif_end:
+ av_dict_free(&s->exif_metadata);
+ bytestream2_skip(&gb, chunk_size);
+ break;
+ }
+ case MKTAG('I', 'C', 'C', 'P'):
+ case MKTAG('A', 'N', 'I', 'M'):
+ case MKTAG('A', 'N', 'M', 'F'):
+ case MKTAG('X', 'M', 'P', ' '):
+ AV_WL32(chunk_str, chunk_type);
+ av_log(avctx, AV_LOG_VERBOSE, "skipping unsupported chunk: %s\n",
+ chunk_str);
+ bytestream2_skip(&gb, chunk_size);
+ break;
+ default:
+ AV_WL32(chunk_str, chunk_type);
+ av_log(avctx, AV_LOG_VERBOSE, "skipping unknown chunk: %s\n",
+ chunk_str);
+ bytestream2_skip(&gb, chunk_size);
+ break;
+ }
+ }
+
+ if (!*got_frame) {
+ av_log(avctx, AV_LOG_ERROR, "image data not found\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ return avpkt->size;
+}
+
+static av_cold int webp_decode_close(AVCodecContext *avctx)
+{
+ WebPContext *s = avctx->priv_data;
+
+ if (s->initialized)
+ return ff_vp8_decode_free(avctx);
+
+ return 0;
+}
+
+AVCodec ff_webp_decoder = {
+ .name = "webp",
+ .long_name = NULL_IF_CONFIG_SMALL("WebP image"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_WEBP,
+ .priv_data_size = sizeof(WebPContext),
+ .decode = webp_decode_frame,
+ .close = webp_decode_close,
+ .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/webvttdec.c b/ffmpeg-2-8-12/libavcodec/webvttdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/webvttdec.c
rename to ffmpeg-2-8-12/libavcodec/webvttdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/webvttenc.c b/ffmpeg-2-8-12/libavcodec/webvttenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/webvttenc.c
rename to ffmpeg-2-8-12/libavcodec/webvttenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/wma.c b/ffmpeg-2-8-12/libavcodec/wma.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wma.c
rename to ffmpeg-2-8-12/libavcodec/wma.c
diff --git a/ffmpeg-2-8-11/libavcodec/wma.h b/ffmpeg-2-8-12/libavcodec/wma.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wma.h
rename to ffmpeg-2-8-12/libavcodec/wma.h
diff --git a/ffmpeg-2-8-11/libavcodec/wma_common.c b/ffmpeg-2-8-12/libavcodec/wma_common.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wma_common.c
rename to ffmpeg-2-8-12/libavcodec/wma_common.c
diff --git a/ffmpeg-2-8-11/libavcodec/wma_common.h b/ffmpeg-2-8-12/libavcodec/wma_common.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wma_common.h
rename to ffmpeg-2-8-12/libavcodec/wma_common.h
diff --git a/ffmpeg-2-8-11/libavcodec/wma_freqs.c b/ffmpeg-2-8-12/libavcodec/wma_freqs.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wma_freqs.c
rename to ffmpeg-2-8-12/libavcodec/wma_freqs.c
diff --git a/ffmpeg-2-8-11/libavcodec/wma_freqs.h b/ffmpeg-2-8-12/libavcodec/wma_freqs.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wma_freqs.h
rename to ffmpeg-2-8-12/libavcodec/wma_freqs.h
diff --git a/ffmpeg-2-8-11/libavcodec/wmadata.h b/ffmpeg-2-8-12/libavcodec/wmadata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wmadata.h
rename to ffmpeg-2-8-12/libavcodec/wmadata.h
diff --git a/ffmpeg-2-8-11/libavcodec/wmadec.c b/ffmpeg-2-8-12/libavcodec/wmadec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wmadec.c
rename to ffmpeg-2-8-12/libavcodec/wmadec.c
diff --git a/ffmpeg-2-8-11/libavcodec/wmaenc.c b/ffmpeg-2-8-12/libavcodec/wmaenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wmaenc.c
rename to ffmpeg-2-8-12/libavcodec/wmaenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/wmalosslessdec.c b/ffmpeg-2-8-12/libavcodec/wmalosslessdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wmalosslessdec.c
rename to ffmpeg-2-8-12/libavcodec/wmalosslessdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/wmaprodata.h b/ffmpeg-2-8-12/libavcodec/wmaprodata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wmaprodata.h
rename to ffmpeg-2-8-12/libavcodec/wmaprodata.h
diff --git a/ffmpeg-2-8-11/libavcodec/wmaprodec.c b/ffmpeg-2-8-12/libavcodec/wmaprodec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wmaprodec.c
rename to ffmpeg-2-8-12/libavcodec/wmaprodec.c
diff --git a/ffmpeg-2-8-11/libavcodec/wmavoice.c b/ffmpeg-2-8-12/libavcodec/wmavoice.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wmavoice.c
rename to ffmpeg-2-8-12/libavcodec/wmavoice.c
diff --git a/ffmpeg-2-8-11/libavcodec/wmavoice_data.h b/ffmpeg-2-8-12/libavcodec/wmavoice_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wmavoice_data.h
rename to ffmpeg-2-8-12/libavcodec/wmavoice_data.h
diff --git a/ffmpeg-2-8-11/libavcodec/wmv2.c b/ffmpeg-2-8-12/libavcodec/wmv2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wmv2.c
rename to ffmpeg-2-8-12/libavcodec/wmv2.c
diff --git a/ffmpeg-2-8-11/libavcodec/wmv2.h b/ffmpeg-2-8-12/libavcodec/wmv2.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wmv2.h
rename to ffmpeg-2-8-12/libavcodec/wmv2.h
diff --git a/ffmpeg-2-8-11/libavcodec/wmv2dec.c b/ffmpeg-2-8-12/libavcodec/wmv2dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wmv2dec.c
rename to ffmpeg-2-8-12/libavcodec/wmv2dec.c
diff --git a/ffmpeg-2-8-12/libavcodec/wmv2dsp.c b/ffmpeg-2-8-12/libavcodec/wmv2dsp.c
new file mode 100644
index 0000000..7b59d10
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/wmv2dsp.c
@@ -0,0 +1,265 @@
+/*
+ * 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 "avcodec.h"
+#include "idctdsp.h"
+#include "mathops.h"
+#include "wmv2dsp.h"
+
+#define W0 2048
+#define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */
+#define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */
+#define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */
+#define W4 2048 /* 2048*sqrt (2)*cos (4*pi/16) */
+#define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */
+#define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */
+#define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */
+
+static void wmv2_idct_row(short * b)
+{
+ int s1, s2;
+ int a0, a1, a2, a3, a4, a5, a6, a7;
+
+ /* step 1 */
+ a1 = W1 * b[1] + W7 * b[7];
+ a7 = W7 * b[1] - W1 * b[7];
+ a5 = W5 * b[5] + W3 * b[3];
+ a3 = W3 * b[5] - W5 * b[3];
+ a2 = W2 * b[2] + W6 * b[6];
+ a6 = W6 * b[2] - W2 * b[6];
+ a0 = W0 * b[0] + W0 * b[4];
+ a4 = W0 * b[0] - W0 * b[4];
+
+ /* step 2 */
+ s1 = (int)(181U * (a1 - a5 + a7 - a3) + 128) >> 8; // 1, 3, 5, 7
+ s2 = (int)(181U * (a1 - a5 - a7 + a3) + 128) >> 8;
+
+ /* step 3 */
+ b[0] = (a0 + a2 + a1 + a5 + (1 << 7)) >> 8;
+ b[1] = (a4 + a6 + s1 + (1 << 7)) >> 8;
+ b[2] = (a4 - a6 + s2 + (1 << 7)) >> 8;
+ b[3] = (a0 - a2 + a7 + a3 + (1 << 7)) >> 8;
+ b[4] = (a0 - a2 - a7 - a3 + (1 << 7)) >> 8;
+ b[5] = (a4 - a6 - s2 + (1 << 7)) >> 8;
+ b[6] = (a4 + a6 - s1 + (1 << 7)) >> 8;
+ b[7] = (a0 + a2 - a1 - a5 + (1 << 7)) >> 8;
+}
+
+static void wmv2_idct_col(short * b)
+{
+ int s1, s2;
+ int a0, a1, a2, a3, a4, a5, a6, a7;
+
+ /* step 1, with extended precision */
+ a1 = (W1 * b[8 * 1] + W7 * b[8 * 7] + 4) >> 3;
+ a7 = (W7 * b[8 * 1] - W1 * b[8 * 7] + 4) >> 3;
+ a5 = (W5 * b[8 * 5] + W3 * b[8 * 3] + 4) >> 3;
+ a3 = (W3 * b[8 * 5] - W5 * b[8 * 3] + 4) >> 3;
+ a2 = (W2 * b[8 * 2] + W6 * b[8 * 6] + 4) >> 3;
+ a6 = (W6 * b[8 * 2] - W2 * b[8 * 6] + 4) >> 3;
+ a0 = (W0 * b[8 * 0] + W0 * b[8 * 4] ) >> 3;
+ a4 = (W0 * b[8 * 0] - W0 * b[8 * 4] ) >> 3;
+
+ /* step 2 */
+ s1 = (int)(181U * (a1 - a5 + a7 - a3) + 128) >> 8;
+ s2 = (int)(181U * (a1 - a5 - a7 + a3) + 128) >> 8;
+
+ /* step 3 */
+ b[8 * 0] = (a0 + a2 + a1 + a5 + (1 << 13)) >> 14;
+ b[8 * 1] = (a4 + a6 + s1 + (1 << 13)) >> 14;
+ b[8 * 2] = (a4 - a6 + s2 + (1 << 13)) >> 14;
+ b[8 * 3] = (a0 - a2 + a7 + a3 + (1 << 13)) >> 14;
+
+ b[8 * 4] = (a0 - a2 - a7 - a3 + (1 << 13)) >> 14;
+ b[8 * 5] = (a4 - a6 - s2 + (1 << 13)) >> 14;
+ b[8 * 6] = (a4 + a6 - s1 + (1 << 13)) >> 14;
+ b[8 * 7] = (a0 + a2 - a1 - a5 + (1 << 13)) >> 14;
+}
+
+static void wmv2_idct_add_c(uint8_t *dest, int line_size, int16_t *block)
+{
+ int i;
+
+ for (i = 0; i < 64; i += 8)
+ wmv2_idct_row(block + i);
+ for (i = 0; i < 8; i++)
+ wmv2_idct_col(block + i);
+
+ for (i = 0; i < 8; i++) {
+ dest[0] = av_clip_uint8(dest[0] + block[0]);
+ dest[1] = av_clip_uint8(dest[1] + block[1]);
+ dest[2] = av_clip_uint8(dest[2] + block[2]);
+ dest[3] = av_clip_uint8(dest[3] + block[3]);
+ dest[4] = av_clip_uint8(dest[4] + block[4]);
+ dest[5] = av_clip_uint8(dest[5] + block[5]);
+ dest[6] = av_clip_uint8(dest[6] + block[6]);
+ dest[7] = av_clip_uint8(dest[7] + block[7]);
+ dest += line_size;
+ block += 8;
+ }
+}
+
+static void wmv2_idct_put_c(uint8_t *dest, int line_size, int16_t *block)
+{
+ int i;
+
+ for (i = 0; i < 64; i += 8)
+ wmv2_idct_row(block + i);
+ for (i = 0; i < 8; i++)
+ wmv2_idct_col(block + i);
+
+ for (i = 0; i < 8; i++) {
+ dest[0] = av_clip_uint8(block[0]);
+ dest[1] = av_clip_uint8(block[1]);
+ dest[2] = av_clip_uint8(block[2]);
+ dest[3] = av_clip_uint8(block[3]);
+ dest[4] = av_clip_uint8(block[4]);
+ dest[5] = av_clip_uint8(block[5]);
+ dest[6] = av_clip_uint8(block[6]);
+ dest[7] = av_clip_uint8(block[7]);
+ dest += line_size;
+ block += 8;
+ }
+}
+
+static void wmv2_mspel8_h_lowpass(uint8_t *dst, const uint8_t *src,
+ int dstStride, int srcStride, int h)
+{
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int i;
+
+ for (i = 0; i < h; i++) {
+ dst[0] = cm[(9 * (src[0] + src[1]) - (src[-1] + src[2]) + 8) >> 4];
+ dst[1] = cm[(9 * (src[1] + src[2]) - (src[0] + src[3]) + 8) >> 4];
+ dst[2] = cm[(9 * (src[2] + src[3]) - (src[1] + src[4]) + 8) >> 4];
+ dst[3] = cm[(9 * (src[3] + src[4]) - (src[2] + src[5]) + 8) >> 4];
+ dst[4] = cm[(9 * (src[4] + src[5]) - (src[3] + src[6]) + 8) >> 4];
+ dst[5] = cm[(9 * (src[5] + src[6]) - (src[4] + src[7]) + 8) >> 4];
+ dst[6] = cm[(9 * (src[6] + src[7]) - (src[5] + src[8]) + 8) >> 4];
+ dst[7] = cm[(9 * (src[7] + src[8]) - (src[6] + src[9]) + 8) >> 4];
+ dst += dstStride;
+ src += srcStride;
+ }
+}
+
+static void wmv2_mspel8_v_lowpass(uint8_t *dst, const uint8_t *src,
+ int dstStride, int srcStride, int w)
+{
+ const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP;
+ int i;
+
+ for (i = 0; i < w; i++) {
+ const int src_1 = src[-srcStride];
+ const int src0 = src[0];
+ const int src1 = src[srcStride];
+ const int src2 = src[2 * srcStride];
+ const int src3 = src[3 * srcStride];
+ const int src4 = src[4 * srcStride];
+ const int src5 = src[5 * srcStride];
+ const int src6 = src[6 * srcStride];
+ const int src7 = src[7 * srcStride];
+ const int src8 = src[8 * srcStride];
+ const int src9 = src[9 * srcStride];
+ dst[0 * dstStride] = cm[(9 * (src0 + src1) - (src_1 + src2) + 8) >> 4];
+ dst[1 * dstStride] = cm[(9 * (src1 + src2) - (src0 + src3) + 8) >> 4];
+ dst[2 * dstStride] = cm[(9 * (src2 + src3) - (src1 + src4) + 8) >> 4];
+ dst[3 * dstStride] = cm[(9 * (src3 + src4) - (src2 + src5) + 8) >> 4];
+ dst[4 * dstStride] = cm[(9 * (src4 + src5) - (src3 + src6) + 8) >> 4];
+ dst[5 * dstStride] = cm[(9 * (src5 + src6) - (src4 + src7) + 8) >> 4];
+ dst[6 * dstStride] = cm[(9 * (src6 + src7) - (src5 + src8) + 8) >> 4];
+ dst[7 * dstStride] = cm[(9 * (src7 + src8) - (src6 + src9) + 8) >> 4];
+ src++;
+ dst++;
+ }
+}
+
+static void put_mspel8_mc10_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
+{
+ uint8_t half[64];
+
+ wmv2_mspel8_h_lowpass(half, src, 8, stride, 8);
+ ff_put_pixels8_l2_8(dst, src, half, stride, stride, 8, 8);
+}
+
+static void put_mspel8_mc20_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
+{
+ wmv2_mspel8_h_lowpass(dst, src, stride, stride, 8);
+}
+
+static void put_mspel8_mc30_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
+{
+ uint8_t half[64];
+
+ wmv2_mspel8_h_lowpass(half, src, 8, stride, 8);
+ ff_put_pixels8_l2_8(dst, src + 1, half, stride, stride, 8, 8);
+}
+
+static void put_mspel8_mc02_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
+{
+ wmv2_mspel8_v_lowpass(dst, src, stride, stride, 8);
+}
+
+static void put_mspel8_mc12_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
+{
+ uint8_t halfH[88];
+ uint8_t halfV[64];
+ uint8_t halfHV[64];
+
+ wmv2_mspel8_h_lowpass(halfH, src - stride, 8, stride, 11);
+ wmv2_mspel8_v_lowpass(halfV, src, 8, stride, 8);
+ wmv2_mspel8_v_lowpass(halfHV, halfH + 8, 8, 8, 8);
+ ff_put_pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8);
+}
+
+static void put_mspel8_mc32_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
+{
+ uint8_t halfH[88];
+ uint8_t halfV[64];
+ uint8_t halfHV[64];
+
+ wmv2_mspel8_h_lowpass(halfH, src - stride, 8, stride, 11);
+ wmv2_mspel8_v_lowpass(halfV, src + 1, 8, stride, 8);
+ wmv2_mspel8_v_lowpass(halfHV, halfH + 8, 8, 8, 8);
+ ff_put_pixels8_l2_8(dst, halfV, halfHV, stride, 8, 8, 8);
+}
+
+static void put_mspel8_mc22_c(uint8_t *dst, const uint8_t *src, ptrdiff_t stride)
+{
+ uint8_t halfH[88];
+
+ wmv2_mspel8_h_lowpass(halfH, src - stride, 8, stride, 11);
+ wmv2_mspel8_v_lowpass(dst, halfH + 8, stride, 8, 8);
+}
+
+av_cold void ff_wmv2dsp_init(WMV2DSPContext *c)
+{
+ c->idct_add = wmv2_idct_add_c;
+ c->idct_put = wmv2_idct_put_c;
+ c->idct_perm = FF_IDCT_PERM_NONE;
+
+ c->put_mspel_pixels_tab[0] = ff_put_pixels8x8_c;
+ c->put_mspel_pixels_tab[1] = put_mspel8_mc10_c;
+ c->put_mspel_pixels_tab[2] = put_mspel8_mc20_c;
+ c->put_mspel_pixels_tab[3] = put_mspel8_mc30_c;
+ c->put_mspel_pixels_tab[4] = put_mspel8_mc02_c;
+ c->put_mspel_pixels_tab[5] = put_mspel8_mc12_c;
+ c->put_mspel_pixels_tab[6] = put_mspel8_mc22_c;
+ c->put_mspel_pixels_tab[7] = put_mspel8_mc32_c;
+}
diff --git a/ffmpeg-2-8-11/libavcodec/wmv2dsp.h b/ffmpeg-2-8-12/libavcodec/wmv2dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wmv2dsp.h
rename to ffmpeg-2-8-12/libavcodec/wmv2dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/wmv2enc.c b/ffmpeg-2-8-12/libavcodec/wmv2enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/wmv2enc.c
rename to ffmpeg-2-8-12/libavcodec/wmv2enc.c
diff --git a/ffmpeg-2-8-12/libavcodec/wnv1.c b/ffmpeg-2-8-12/libavcodec/wnv1.c
new file mode 100644
index 0000000..915e9c7
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/wnv1.c
@@ -0,0 +1,159 @@
+/*
+ * Winnov WNV1 codec
+ * Copyright (c) 2005 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
+ */
+
+/**
+ * @file
+ * Winnov WNV1 codec.
+ */
+
+#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 }
+};
+
+#define CODE_VLC_BITS 9
+static VLC code_vlc;
+
+/* returns modified base_value */
+static inline int wnv1_get_code(WNV1Context *w, int base_value)
+{
+ int v = get_vlc2(&w->gb, code_vlc.table, CODE_VLC_BITS, 1);
+
+ if (v == 15)
+ return ff_reverse[get_bits(&w->gb, 8 - w->shift)];
+ else
+ return base_value + ((v - 7U) << w->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;
+ unsigned char *Y,*U,*V;
+ int i, j, ret;
+ 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);
+ 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)
+ return ret;
+
+ if (buf[2] >> 4 == 6)
+ l->shift = 2;
+ else {
+ l->shift = 8 - (buf[2] >> 4);
+ if (l->shift > 4) {
+ avpriv_request_sample(avctx,
+ "Unknown WNV1 frame header value %i",
+ buf[2] >> 4);
+ l->shift = 4;
+ }
+ if (l->shift < 1) {
+ avpriv_request_sample(avctx,
+ "Unknown WNV1 frame header value %i",
+ buf[2] >> 4);
+ l->shift = 1;
+ }
+ }
+
+ Y = p->data[0];
+ U = p->data[1];
+ 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 += p->linesize[0];
+ U += p->linesize[1];
+ V += p->linesize[2];
+ }
+
+
+ *got_frame = 1;
+ av_free(rbuf);
+
+ return buf_size;
+}
+
+static av_cold int decode_init(AVCodecContext *avctx)
+{
+ static VLC_TYPE code_table[1 << CODE_VLC_BITS][2];
+
+ 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);
+
+ return 0;
+}
+
+AVCodec ff_wnv1_decoder = {
+ .name = "wnv1",
+ .long_name = NULL_IF_CONFIG_SMALL("Winnov WNV1"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_WNV1,
+ .priv_data_size = sizeof(WNV1Context),
+ .init = decode_init,
+ .decode = decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/ws-snd1.c b/ffmpeg-2-8-12/libavcodec/ws-snd1.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/ws-snd1.c
rename to ffmpeg-2-8-12/libavcodec/ws-snd1.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/Makefile b/ffmpeg-2-8-12/libavcodec/x86/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/Makefile
rename to ffmpeg-2-8-12/libavcodec/x86/Makefile
diff --git a/ffmpeg-2-8-11/libavcodec/x86/aacpsdsp.asm b/ffmpeg-2-8-12/libavcodec/x86/aacpsdsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/aacpsdsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/aacpsdsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/aacpsdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/aacpsdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/aacpsdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/aacpsdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/ac3dsp.asm b/ffmpeg-2-8-12/libavcodec/x86/ac3dsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/ac3dsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/ac3dsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/ac3dsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/ac3dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/ac3dsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/ac3dsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/audiodsp.asm b/ffmpeg-2-8-12/libavcodec/x86/audiodsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/audiodsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/audiodsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/audiodsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/audiodsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/audiodsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/audiodsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/blockdsp.asm b/ffmpeg-2-8-12/libavcodec/x86/blockdsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/blockdsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/blockdsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/blockdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/blockdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/blockdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/blockdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/bswapdsp.asm b/ffmpeg-2-8-12/libavcodec/x86/bswapdsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/bswapdsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/bswapdsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/bswapdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/bswapdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/bswapdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/bswapdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/cabac.h b/ffmpeg-2-8-12/libavcodec/x86/cabac.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/cabac.h
rename to ffmpeg-2-8-12/libavcodec/x86/cabac.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/cavsdsp.c b/ffmpeg-2-8-12/libavcodec/x86/cavsdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/cavsdsp.c
rename to ffmpeg-2-8-12/libavcodec/x86/cavsdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/constants.c b/ffmpeg-2-8-12/libavcodec/x86/constants.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/constants.c
rename to ffmpeg-2-8-12/libavcodec/x86/constants.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/constants.h b/ffmpeg-2-8-12/libavcodec/x86/constants.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/constants.h
rename to ffmpeg-2-8-12/libavcodec/x86/constants.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/dcadsp.asm b/ffmpeg-2-8-12/libavcodec/x86/dcadsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/dcadsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/dcadsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/dcadsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/dcadsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/dcadsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/dcadsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/dct-test.c b/ffmpeg-2-8-12/libavcodec/x86/dct-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/dct-test.c
rename to ffmpeg-2-8-12/libavcodec/x86/dct-test.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/dct32.asm b/ffmpeg-2-8-12/libavcodec/x86/dct32.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/dct32.asm
rename to ffmpeg-2-8-12/libavcodec/x86/dct32.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/dct_init.c b/ffmpeg-2-8-12/libavcodec/x86/dct_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/dct_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/dct_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/deinterlace.asm b/ffmpeg-2-8-12/libavcodec/x86/deinterlace.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/deinterlace.asm
rename to ffmpeg-2-8-12/libavcodec/x86/deinterlace.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/dirac_dwt.c b/ffmpeg-2-8-12/libavcodec/x86/dirac_dwt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/dirac_dwt.c
rename to ffmpeg-2-8-12/libavcodec/x86/dirac_dwt.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/dirac_dwt.h b/ffmpeg-2-8-12/libavcodec/x86/dirac_dwt.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/dirac_dwt.h
rename to ffmpeg-2-8-12/libavcodec/x86/dirac_dwt.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/diracdsp_mmx.c b/ffmpeg-2-8-12/libavcodec/x86/diracdsp_mmx.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/diracdsp_mmx.c
rename to ffmpeg-2-8-12/libavcodec/x86/diracdsp_mmx.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/diracdsp_mmx.h b/ffmpeg-2-8-12/libavcodec/x86/diracdsp_mmx.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/diracdsp_mmx.h
rename to ffmpeg-2-8-12/libavcodec/x86/diracdsp_mmx.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/diracdsp_yasm.asm b/ffmpeg-2-8-12/libavcodec/x86/diracdsp_yasm.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/diracdsp_yasm.asm
rename to ffmpeg-2-8-12/libavcodec/x86/diracdsp_yasm.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/dnxhdenc.asm b/ffmpeg-2-8-12/libavcodec/x86/dnxhdenc.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/dnxhdenc.asm
rename to ffmpeg-2-8-12/libavcodec/x86/dnxhdenc.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/dnxhdenc_init.c b/ffmpeg-2-8-12/libavcodec/x86/dnxhdenc_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/dnxhdenc_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/dnxhdenc_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/dwt_yasm.asm b/ffmpeg-2-8-12/libavcodec/x86/dwt_yasm.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/dwt_yasm.asm
rename to ffmpeg-2-8-12/libavcodec/x86/dwt_yasm.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/fdct.c b/ffmpeg-2-8-12/libavcodec/x86/fdct.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/fdct.c
rename to ffmpeg-2-8-12/libavcodec/x86/fdct.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/fdct.h b/ffmpeg-2-8-12/libavcodec/x86/fdct.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/fdct.h
rename to ffmpeg-2-8-12/libavcodec/x86/fdct.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/fdctdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/fdctdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/fdctdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/fdctdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/fft.asm b/ffmpeg-2-8-12/libavcodec/x86/fft.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/fft.asm
rename to ffmpeg-2-8-12/libavcodec/x86/fft.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/fft.h b/ffmpeg-2-8-12/libavcodec/x86/fft.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/fft.h
rename to ffmpeg-2-8-12/libavcodec/x86/fft.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/fft_init.c b/ffmpeg-2-8-12/libavcodec/x86/fft_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/fft_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/fft_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/flac_dsp_gpl.asm b/ffmpeg-2-8-12/libavcodec/x86/flac_dsp_gpl.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/flac_dsp_gpl.asm
rename to ffmpeg-2-8-12/libavcodec/x86/flac_dsp_gpl.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/flacdsp.asm b/ffmpeg-2-8-12/libavcodec/x86/flacdsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/flacdsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/flacdsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/flacdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/flacdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/flacdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/flacdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/fmtconvert.asm b/ffmpeg-2-8-12/libavcodec/x86/fmtconvert.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/fmtconvert.asm
rename to ffmpeg-2-8-12/libavcodec/x86/fmtconvert.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/fmtconvert_init.c b/ffmpeg-2-8-12/libavcodec/x86/fmtconvert_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/fmtconvert_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/fmtconvert_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/fpel.asm b/ffmpeg-2-8-12/libavcodec/x86/fpel.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/fpel.asm
rename to ffmpeg-2-8-12/libavcodec/x86/fpel.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/fpel.h b/ffmpeg-2-8-12/libavcodec/x86/fpel.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/fpel.h
rename to ffmpeg-2-8-12/libavcodec/x86/fpel.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/g722dsp.asm b/ffmpeg-2-8-12/libavcodec/x86/g722dsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/g722dsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/g722dsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/g722dsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/g722dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/g722dsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/g722dsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h263_loopfilter.asm b/ffmpeg-2-8-12/libavcodec/x86/h263_loopfilter.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h263_loopfilter.asm
rename to ffmpeg-2-8-12/libavcodec/x86/h263_loopfilter.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h263dsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/h263dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h263dsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/h263dsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_chromamc.asm b/ffmpeg-2-8-12/libavcodec/x86/h264_chromamc.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_chromamc.asm
rename to ffmpeg-2-8-12/libavcodec/x86/h264_chromamc.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_chromamc_10bit.asm b/ffmpeg-2-8-12/libavcodec/x86/h264_chromamc_10bit.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_chromamc_10bit.asm
rename to ffmpeg-2-8-12/libavcodec/x86/h264_chromamc_10bit.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_deblock.asm b/ffmpeg-2-8-12/libavcodec/x86/h264_deblock.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_deblock.asm
rename to ffmpeg-2-8-12/libavcodec/x86/h264_deblock.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_deblock_10bit.asm b/ffmpeg-2-8-12/libavcodec/x86/h264_deblock_10bit.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_deblock_10bit.asm
rename to ffmpeg-2-8-12/libavcodec/x86/h264_deblock_10bit.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_i386.h b/ffmpeg-2-8-12/libavcodec/x86/h264_i386.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_i386.h
rename to ffmpeg-2-8-12/libavcodec/x86/h264_i386.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_idct.asm b/ffmpeg-2-8-12/libavcodec/x86/h264_idct.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_idct.asm
rename to ffmpeg-2-8-12/libavcodec/x86/h264_idct.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_idct_10bit.asm b/ffmpeg-2-8-12/libavcodec/x86/h264_idct_10bit.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_idct_10bit.asm
rename to ffmpeg-2-8-12/libavcodec/x86/h264_idct_10bit.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_intrapred.asm b/ffmpeg-2-8-12/libavcodec/x86/h264_intrapred.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_intrapred.asm
rename to ffmpeg-2-8-12/libavcodec/x86/h264_intrapred.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_intrapred_10bit.asm b/ffmpeg-2-8-12/libavcodec/x86/h264_intrapred_10bit.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_intrapred_10bit.asm
rename to ffmpeg-2-8-12/libavcodec/x86/h264_intrapred_10bit.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_intrapred_init.c b/ffmpeg-2-8-12/libavcodec/x86/h264_intrapred_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_intrapred_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/h264_intrapred_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_qpel.c b/ffmpeg-2-8-12/libavcodec/x86/h264_qpel.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_qpel.c
rename to ffmpeg-2-8-12/libavcodec/x86/h264_qpel.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_qpel_10bit.asm b/ffmpeg-2-8-12/libavcodec/x86/h264_qpel_10bit.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_qpel_10bit.asm
rename to ffmpeg-2-8-12/libavcodec/x86/h264_qpel_10bit.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_qpel_8bit.asm b/ffmpeg-2-8-12/libavcodec/x86/h264_qpel_8bit.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_qpel_8bit.asm
rename to ffmpeg-2-8-12/libavcodec/x86/h264_qpel_8bit.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_weight.asm b/ffmpeg-2-8-12/libavcodec/x86/h264_weight.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_weight.asm
rename to ffmpeg-2-8-12/libavcodec/x86/h264_weight.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264_weight_10bit.asm b/ffmpeg-2-8-12/libavcodec/x86/h264_weight_10bit.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264_weight_10bit.asm
rename to ffmpeg-2-8-12/libavcodec/x86/h264_weight_10bit.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264chroma_init.c b/ffmpeg-2-8-12/libavcodec/x86/h264chroma_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264chroma_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/h264chroma_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/h264dsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/h264dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/h264dsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/h264dsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/hevc_deblock.asm b/ffmpeg-2-8-12/libavcodec/x86/hevc_deblock.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/hevc_deblock.asm
rename to ffmpeg-2-8-12/libavcodec/x86/hevc_deblock.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/hevc_idct.asm b/ffmpeg-2-8-12/libavcodec/x86/hevc_idct.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/hevc_idct.asm
rename to ffmpeg-2-8-12/libavcodec/x86/hevc_idct.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/hevc_mc.asm b/ffmpeg-2-8-12/libavcodec/x86/hevc_mc.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/hevc_mc.asm
rename to ffmpeg-2-8-12/libavcodec/x86/hevc_mc.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/hevc_res_add.asm b/ffmpeg-2-8-12/libavcodec/x86/hevc_res_add.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/hevc_res_add.asm
rename to ffmpeg-2-8-12/libavcodec/x86/hevc_res_add.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/hevc_sao.asm b/ffmpeg-2-8-12/libavcodec/x86/hevc_sao.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/hevc_sao.asm
rename to ffmpeg-2-8-12/libavcodec/x86/hevc_sao.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/hevcdsp.h b/ffmpeg-2-8-12/libavcodec/x86/hevcdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/hevcdsp.h
rename to ffmpeg-2-8-12/libavcodec/x86/hevcdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/hevcdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/hevcdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/hevcdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/hevcdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/hpeldsp.asm b/ffmpeg-2-8-12/libavcodec/x86/hpeldsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/hpeldsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/hpeldsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/hpeldsp.h b/ffmpeg-2-8-12/libavcodec/x86/hpeldsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/hpeldsp.h
rename to ffmpeg-2-8-12/libavcodec/x86/hpeldsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/hpeldsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/hpeldsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/hpeldsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/hpeldsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/hpeldsp_rnd_template.c b/ffmpeg-2-8-12/libavcodec/x86/hpeldsp_rnd_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/hpeldsp_rnd_template.c
rename to ffmpeg-2-8-12/libavcodec/x86/hpeldsp_rnd_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/huffyuvdsp.asm b/ffmpeg-2-8-12/libavcodec/x86/huffyuvdsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/huffyuvdsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/huffyuvdsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/huffyuvdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/huffyuvdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/huffyuvdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/huffyuvdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/huffyuvencdsp_mmx.c b/ffmpeg-2-8-12/libavcodec/x86/huffyuvencdsp_mmx.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/huffyuvencdsp_mmx.c
rename to ffmpeg-2-8-12/libavcodec/x86/huffyuvencdsp_mmx.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/idctdsp.asm b/ffmpeg-2-8-12/libavcodec/x86/idctdsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/idctdsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/idctdsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/idctdsp.h b/ffmpeg-2-8-12/libavcodec/x86/idctdsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/idctdsp.h
rename to ffmpeg-2-8-12/libavcodec/x86/idctdsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/idctdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/idctdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/idctdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/idctdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/imdct36.asm b/ffmpeg-2-8-12/libavcodec/x86/imdct36.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/imdct36.asm
rename to ffmpeg-2-8-12/libavcodec/x86/imdct36.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/inline_asm.h b/ffmpeg-2-8-12/libavcodec/x86/inline_asm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/inline_asm.h
rename to ffmpeg-2-8-12/libavcodec/x86/inline_asm.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/jpeg2000dsp.asm b/ffmpeg-2-8-12/libavcodec/x86/jpeg2000dsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/jpeg2000dsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/jpeg2000dsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/jpeg2000dsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/jpeg2000dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/jpeg2000dsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/jpeg2000dsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/lossless_audiodsp.asm b/ffmpeg-2-8-12/libavcodec/x86/lossless_audiodsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/lossless_audiodsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/lossless_audiodsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/lossless_audiodsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/lossless_audiodsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/lossless_audiodsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/lossless_audiodsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/lossless_videodsp.asm b/ffmpeg-2-8-12/libavcodec/x86/lossless_videodsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/lossless_videodsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/lossless_videodsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/lossless_videodsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/lossless_videodsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/lossless_videodsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/lossless_videodsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/lpc.c b/ffmpeg-2-8-12/libavcodec/x86/lpc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/lpc.c
rename to ffmpeg-2-8-12/libavcodec/x86/lpc.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/mathops.h b/ffmpeg-2-8-12/libavcodec/x86/mathops.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/mathops.h
rename to ffmpeg-2-8-12/libavcodec/x86/mathops.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/me_cmp.asm b/ffmpeg-2-8-12/libavcodec/x86/me_cmp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/me_cmp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/me_cmp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/me_cmp_init.c b/ffmpeg-2-8-12/libavcodec/x86/me_cmp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/me_cmp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/me_cmp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/mlpdsp.asm b/ffmpeg-2-8-12/libavcodec/x86/mlpdsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/mlpdsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/mlpdsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/mlpdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/mlpdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/mlpdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/mlpdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/mpegaudiodsp.c b/ffmpeg-2-8-12/libavcodec/x86/mpegaudiodsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/mpegaudiodsp.c
rename to ffmpeg-2-8-12/libavcodec/x86/mpegaudiodsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/mpegvideo.c b/ffmpeg-2-8-12/libavcodec/x86/mpegvideo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/mpegvideo.c
rename to ffmpeg-2-8-12/libavcodec/x86/mpegvideo.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/mpegvideodsp.c b/ffmpeg-2-8-12/libavcodec/x86/mpegvideodsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/mpegvideodsp.c
rename to ffmpeg-2-8-12/libavcodec/x86/mpegvideodsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/mpegvideoenc.c b/ffmpeg-2-8-12/libavcodec/x86/mpegvideoenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/mpegvideoenc.c
rename to ffmpeg-2-8-12/libavcodec/x86/mpegvideoenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/mpegvideoenc_qns_template.c b/ffmpeg-2-8-12/libavcodec/x86/mpegvideoenc_qns_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/mpegvideoenc_qns_template.c
rename to ffmpeg-2-8-12/libavcodec/x86/mpegvideoenc_qns_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/mpegvideoenc_template.c b/ffmpeg-2-8-12/libavcodec/x86/mpegvideoenc_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/mpegvideoenc_template.c
rename to ffmpeg-2-8-12/libavcodec/x86/mpegvideoenc_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/mpegvideoencdsp.asm b/ffmpeg-2-8-12/libavcodec/x86/mpegvideoencdsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/mpegvideoencdsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/mpegvideoencdsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/mpegvideoencdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/mpegvideoencdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/mpegvideoencdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/mpegvideoencdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/pixblockdsp.asm b/ffmpeg-2-8-12/libavcodec/x86/pixblockdsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/pixblockdsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/pixblockdsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/pixblockdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/pixblockdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/pixblockdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/pixblockdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/pngdsp.asm b/ffmpeg-2-8-12/libavcodec/x86/pngdsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/pngdsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/pngdsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/pngdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/pngdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/pngdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/pngdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/proresdsp.asm b/ffmpeg-2-8-12/libavcodec/x86/proresdsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/proresdsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/proresdsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/proresdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/proresdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/proresdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/proresdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/qpel.asm b/ffmpeg-2-8-12/libavcodec/x86/qpel.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/qpel.asm
rename to ffmpeg-2-8-12/libavcodec/x86/qpel.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/qpeldsp.asm b/ffmpeg-2-8-12/libavcodec/x86/qpeldsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/qpeldsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/qpeldsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/qpeldsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/qpeldsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/qpeldsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/qpeldsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/rnd_template.c b/ffmpeg-2-8-12/libavcodec/x86/rnd_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/rnd_template.c
rename to ffmpeg-2-8-12/libavcodec/x86/rnd_template.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/rv34dsp.asm b/ffmpeg-2-8-12/libavcodec/x86/rv34dsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/rv34dsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/rv34dsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/rv34dsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/rv34dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/rv34dsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/rv34dsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/rv40dsp.asm b/ffmpeg-2-8-12/libavcodec/x86/rv40dsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/rv40dsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/rv40dsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/rv40dsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/rv40dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/rv40dsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/rv40dsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/sbrdsp.asm b/ffmpeg-2-8-12/libavcodec/x86/sbrdsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/sbrdsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/sbrdsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/sbrdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/sbrdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/sbrdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/sbrdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/simple_idct.c b/ffmpeg-2-8-12/libavcodec/x86/simple_idct.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/simple_idct.c
rename to ffmpeg-2-8-12/libavcodec/x86/simple_idct.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/simple_idct.h b/ffmpeg-2-8-12/libavcodec/x86/simple_idct.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/simple_idct.h
rename to ffmpeg-2-8-12/libavcodec/x86/simple_idct.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/snowdsp.c b/ffmpeg-2-8-12/libavcodec/x86/snowdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/snowdsp.c
rename to ffmpeg-2-8-12/libavcodec/x86/snowdsp.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/svq1enc.asm b/ffmpeg-2-8-12/libavcodec/x86/svq1enc.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/svq1enc.asm
rename to ffmpeg-2-8-12/libavcodec/x86/svq1enc.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/svq1enc_init.c b/ffmpeg-2-8-12/libavcodec/x86/svq1enc_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/svq1enc_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/svq1enc_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/ttadsp.asm b/ffmpeg-2-8-12/libavcodec/x86/ttadsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/ttadsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/ttadsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/ttadsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/ttadsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/ttadsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/ttadsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/v210-init.c b/ffmpeg-2-8-12/libavcodec/x86/v210-init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/v210-init.c
rename to ffmpeg-2-8-12/libavcodec/x86/v210-init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/v210.asm b/ffmpeg-2-8-12/libavcodec/x86/v210.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/v210.asm
rename to ffmpeg-2-8-12/libavcodec/x86/v210.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/v210enc.asm b/ffmpeg-2-8-12/libavcodec/x86/v210enc.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/v210enc.asm
rename to ffmpeg-2-8-12/libavcodec/x86/v210enc.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/v210enc_init.c b/ffmpeg-2-8-12/libavcodec/x86/v210enc_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/v210enc_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/v210enc_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vc1dsp.asm b/ffmpeg-2-8-12/libavcodec/x86/vc1dsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vc1dsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/vc1dsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vc1dsp.h b/ffmpeg-2-8-12/libavcodec/x86/vc1dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vc1dsp.h
rename to ffmpeg-2-8-12/libavcodec/x86/vc1dsp.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vc1dsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/vc1dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vc1dsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/vc1dsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vc1dsp_mmx.c b/ffmpeg-2-8-12/libavcodec/x86/vc1dsp_mmx.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vc1dsp_mmx.c
rename to ffmpeg-2-8-12/libavcodec/x86/vc1dsp_mmx.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/videodsp.asm b/ffmpeg-2-8-12/libavcodec/x86/videodsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/videodsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/videodsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/videodsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/videodsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/videodsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/videodsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vorbisdsp.asm b/ffmpeg-2-8-12/libavcodec/x86/vorbisdsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vorbisdsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/vorbisdsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vorbisdsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/vorbisdsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vorbisdsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/vorbisdsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vp3dsp.asm b/ffmpeg-2-8-12/libavcodec/x86/vp3dsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vp3dsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/vp3dsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vp3dsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/vp3dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vp3dsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/vp3dsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vp56_arith.h b/ffmpeg-2-8-12/libavcodec/x86/vp56_arith.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vp56_arith.h
rename to ffmpeg-2-8-12/libavcodec/x86/vp56_arith.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vp6dsp.asm b/ffmpeg-2-8-12/libavcodec/x86/vp6dsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vp6dsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/vp6dsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vp6dsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/vp6dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vp6dsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/vp6dsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vp8dsp.asm b/ffmpeg-2-8-12/libavcodec/x86/vp8dsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vp8dsp.asm
rename to ffmpeg-2-8-12/libavcodec/x86/vp8dsp.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vp8dsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/vp8dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vp8dsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/vp8dsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vp8dsp_loopfilter.asm b/ffmpeg-2-8-12/libavcodec/x86/vp8dsp_loopfilter.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vp8dsp_loopfilter.asm
rename to ffmpeg-2-8-12/libavcodec/x86/vp8dsp_loopfilter.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vp9dsp_init.c b/ffmpeg-2-8-12/libavcodec/x86/vp9dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vp9dsp_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/vp9dsp_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vp9intrapred.asm b/ffmpeg-2-8-12/libavcodec/x86/vp9intrapred.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vp9intrapred.asm
rename to ffmpeg-2-8-12/libavcodec/x86/vp9intrapred.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vp9itxfm.asm b/ffmpeg-2-8-12/libavcodec/x86/vp9itxfm.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vp9itxfm.asm
rename to ffmpeg-2-8-12/libavcodec/x86/vp9itxfm.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vp9lpf.asm b/ffmpeg-2-8-12/libavcodec/x86/vp9lpf.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vp9lpf.asm
rename to ffmpeg-2-8-12/libavcodec/x86/vp9lpf.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/vp9mc.asm b/ffmpeg-2-8-12/libavcodec/x86/vp9mc.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/vp9mc.asm
rename to ffmpeg-2-8-12/libavcodec/x86/vp9mc.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/w64xmmtest.c b/ffmpeg-2-8-12/libavcodec/x86/w64xmmtest.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/w64xmmtest.c
rename to ffmpeg-2-8-12/libavcodec/x86/w64xmmtest.c
diff --git a/ffmpeg-2-8-11/libavcodec/x86/xvididct.asm b/ffmpeg-2-8-12/libavcodec/x86/xvididct.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/xvididct.asm
rename to ffmpeg-2-8-12/libavcodec/x86/xvididct.asm
diff --git a/ffmpeg-2-8-11/libavcodec/x86/xvididct.h b/ffmpeg-2-8-12/libavcodec/x86/xvididct.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/xvididct.h
rename to ffmpeg-2-8-12/libavcodec/x86/xvididct.h
diff --git a/ffmpeg-2-8-11/libavcodec/x86/xvididct_init.c b/ffmpeg-2-8-12/libavcodec/x86/xvididct_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/x86/xvididct_init.c
rename to ffmpeg-2-8-12/libavcodec/x86/xvididct_init.c
diff --git a/ffmpeg-2-8-11/libavcodec/xan.c b/ffmpeg-2-8-12/libavcodec/xan.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xan.c
rename to ffmpeg-2-8-12/libavcodec/xan.c
diff --git a/ffmpeg-2-8-11/libavcodec/xbmdec.c b/ffmpeg-2-8-12/libavcodec/xbmdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xbmdec.c
rename to ffmpeg-2-8-12/libavcodec/xbmdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/xbmenc.c b/ffmpeg-2-8-12/libavcodec/xbmenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xbmenc.c
rename to ffmpeg-2-8-12/libavcodec/xbmenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/xface.c b/ffmpeg-2-8-12/libavcodec/xface.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xface.c
rename to ffmpeg-2-8-12/libavcodec/xface.c
diff --git a/ffmpeg-2-8-11/libavcodec/xface.h b/ffmpeg-2-8-12/libavcodec/xface.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xface.h
rename to ffmpeg-2-8-12/libavcodec/xface.h
diff --git a/ffmpeg-2-8-11/libavcodec/xfacedec.c b/ffmpeg-2-8-12/libavcodec/xfacedec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xfacedec.c
rename to ffmpeg-2-8-12/libavcodec/xfacedec.c
diff --git a/ffmpeg-2-8-11/libavcodec/xfaceenc.c b/ffmpeg-2-8-12/libavcodec/xfaceenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xfaceenc.c
rename to ffmpeg-2-8-12/libavcodec/xfaceenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/xiph.c b/ffmpeg-2-8-12/libavcodec/xiph.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xiph.c
rename to ffmpeg-2-8-12/libavcodec/xiph.c
diff --git a/ffmpeg-2-8-11/libavcodec/xiph.h b/ffmpeg-2-8-12/libavcodec/xiph.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xiph.h
rename to ffmpeg-2-8-12/libavcodec/xiph.h
diff --git a/ffmpeg-2-8-11/libavcodec/xl.c b/ffmpeg-2-8-12/libavcodec/xl.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xl.c
rename to ffmpeg-2-8-12/libavcodec/xl.c
diff --git a/ffmpeg-2-8-11/libavcodec/xsubdec.c b/ffmpeg-2-8-12/libavcodec/xsubdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xsubdec.c
rename to ffmpeg-2-8-12/libavcodec/xsubdec.c
diff --git a/ffmpeg-2-8-11/libavcodec/xsubenc.c b/ffmpeg-2-8-12/libavcodec/xsubenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xsubenc.c
rename to ffmpeg-2-8-12/libavcodec/xsubenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/xvididct.c b/ffmpeg-2-8-12/libavcodec/xvididct.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xvididct.c
rename to ffmpeg-2-8-12/libavcodec/xvididct.c
diff --git a/ffmpeg-2-8-11/libavcodec/xvididct.h b/ffmpeg-2-8-12/libavcodec/xvididct.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xvididct.h
rename to ffmpeg-2-8-12/libavcodec/xvididct.h
diff --git a/ffmpeg-2-8-11/libavcodec/xvmc.h b/ffmpeg-2-8-12/libavcodec/xvmc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xvmc.h
rename to ffmpeg-2-8-12/libavcodec/xvmc.h
diff --git a/ffmpeg-2-8-11/libavcodec/xvmc_internal.h b/ffmpeg-2-8-12/libavcodec/xvmc_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xvmc_internal.h
rename to ffmpeg-2-8-12/libavcodec/xvmc_internal.h
diff --git a/ffmpeg-2-8-11/libavcodec/xwd.h b/ffmpeg-2-8-12/libavcodec/xwd.h
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xwd.h
rename to ffmpeg-2-8-12/libavcodec/xwd.h
diff --git a/ffmpeg-2-8-12/libavcodec/xwddec.c b/ffmpeg-2-8-12/libavcodec/xwddec.c
new file mode 100644
index 0000000..8b0845f
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/xwddec.c
@@ -0,0 +1,253 @@
+/*
+ * XWD image format
+ *
+ * Copyright (c) 2012 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 <inttypes.h>
+
+#include "libavutil/imgutils.h"
+#include "avcodec.h"
+#include "bytestream.h"
+#include "internal.h"
+#include "xwd.h"
+
+static int xwd_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame, AVPacket *avpkt)
+{
+ AVFrame *p = data;
+ const uint8_t *buf = avpkt->data;
+ int i, ret, buf_size = avpkt->size;
+ uint32_t version, header_size, vclass, ncolors;
+ uint32_t xoffset, be, bpp, lsize, rsize;
+ uint32_t pixformat, pixdepth, bunit, bitorder, bpad;
+ uint32_t rgb[3];
+ uint8_t *ptr;
+ GetByteContext gb;
+
+ if (buf_size < XWD_HEADER_SIZE)
+ return AVERROR_INVALIDDATA;
+
+ bytestream2_init(&gb, buf, buf_size);
+ header_size = bytestream2_get_be32u(&gb);
+
+ version = bytestream2_get_be32u(&gb);
+ if (version != XWD_VERSION) {
+ av_log(avctx, AV_LOG_ERROR, "unsupported version\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (buf_size < header_size || header_size < XWD_HEADER_SIZE) {
+ av_log(avctx, AV_LOG_ERROR, "invalid header size\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ pixformat = bytestream2_get_be32u(&gb);
+ pixdepth = bytestream2_get_be32u(&gb);
+ avctx->width = bytestream2_get_be32u(&gb);
+ avctx->height = bytestream2_get_be32u(&gb);
+ xoffset = bytestream2_get_be32u(&gb);
+ be = bytestream2_get_be32u(&gb);
+ bunit = bytestream2_get_be32u(&gb);
+ bitorder = bytestream2_get_be32u(&gb);
+ bpad = bytestream2_get_be32u(&gb);
+ bpp = bytestream2_get_be32u(&gb);
+ lsize = bytestream2_get_be32u(&gb);
+ vclass = bytestream2_get_be32u(&gb);
+ rgb[0] = bytestream2_get_be32u(&gb);
+ rgb[1] = bytestream2_get_be32u(&gb);
+ rgb[2] = bytestream2_get_be32u(&gb);
+ bytestream2_skipu(&gb, 8);
+ ncolors = bytestream2_get_be32u(&gb);
+ bytestream2_skipu(&gb, header_size - (XWD_HEADER_SIZE - 20));
+
+ av_log(avctx, AV_LOG_DEBUG,
+ "pixformat %"PRIu32", pixdepth %"PRIu32", bunit %"PRIu32", bitorder %"PRIu32", bpad %"PRIu32"\n",
+ pixformat, pixdepth, bunit, bitorder, bpad);
+ av_log(avctx, AV_LOG_DEBUG,
+ "vclass %"PRIu32", ncolors %"PRIu32", bpp %"PRIu32", be %"PRIu32", lsize %"PRIu32", xoffset %"PRIu32"\n",
+ vclass, ncolors, bpp, be, lsize, xoffset);
+ av_log(avctx, AV_LOG_DEBUG,
+ "red %0"PRIx32", green %0"PRIx32", blue %0"PRIx32"\n",
+ rgb[0], rgb[1], rgb[2]);
+
+ if (pixformat > XWD_Z_PIXMAP) {
+ av_log(avctx, AV_LOG_ERROR, "invalid pixmap format\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (pixdepth == 0 || pixdepth > 32) {
+ av_log(avctx, AV_LOG_ERROR, "invalid pixmap depth\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (xoffset) {
+ avpriv_request_sample(avctx, "xoffset %"PRIu32"", xoffset);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if (be > 1) {
+ av_log(avctx, AV_LOG_ERROR, "invalid byte order\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (bitorder > 1) {
+ av_log(avctx, AV_LOG_ERROR, "invalid bitmap bit order\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (bunit != 8 && bunit != 16 && bunit != 32) {
+ av_log(avctx, AV_LOG_ERROR, "invalid bitmap unit\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (bpad != 8 && bpad != 16 && bpad != 32) {
+ av_log(avctx, AV_LOG_ERROR, "invalid bitmap scan-line pad\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (bpp == 0 || bpp > 32) {
+ av_log(avctx, AV_LOG_ERROR, "invalid bits per pixel\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (ncolors > 256) {
+ av_log(avctx, AV_LOG_ERROR, "invalid number of entries in colormap\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if ((ret = av_image_check_size(avctx->width, avctx->height, 0, NULL)) < 0)
+ return ret;
+
+ rsize = FFALIGN(avctx->width * bpp, bpad) / 8;
+ if (lsize < rsize) {
+ av_log(avctx, AV_LOG_ERROR, "invalid bytes per scan-line\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (bytestream2_get_bytes_left(&gb) < ncolors * XWD_CMAP_SIZE + (uint64_t)avctx->height * lsize) {
+ av_log(avctx, AV_LOG_ERROR, "input buffer too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (pixformat != XWD_Z_PIXMAP) {
+ avpriv_report_missing_feature(avctx, "Pixmap format %"PRIu32, pixformat);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ avctx->pix_fmt = AV_PIX_FMT_NONE;
+ switch (vclass) {
+ case XWD_STATIC_GRAY:
+ case XWD_GRAY_SCALE:
+ if (bpp != 1 && bpp != 8)
+ return AVERROR_INVALIDDATA;
+ if (bpp == 1 && pixdepth == 1) {
+ avctx->pix_fmt = AV_PIX_FMT_MONOWHITE;
+ } else if (bpp == 8 && pixdepth == 8) {
+ avctx->pix_fmt = AV_PIX_FMT_GRAY8;
+ }
+ break;
+ case XWD_STATIC_COLOR:
+ case XWD_PSEUDO_COLOR:
+ if (bpp == 8)
+ avctx->pix_fmt = AV_PIX_FMT_PAL8;
+ break;
+ case XWD_TRUE_COLOR:
+ case XWD_DIRECT_COLOR:
+ if (bpp != 16 && bpp != 24 && bpp != 32)
+ return AVERROR_INVALIDDATA;
+ if (bpp == 16 && pixdepth == 15) {
+ if (rgb[0] == 0x7C00 && rgb[1] == 0x3E0 && rgb[2] == 0x1F)
+ avctx->pix_fmt = be ? AV_PIX_FMT_RGB555BE : AV_PIX_FMT_RGB555LE;
+ else if (rgb[0] == 0x1F && rgb[1] == 0x3E0 && rgb[2] == 0x7C00)
+ avctx->pix_fmt = be ? AV_PIX_FMT_BGR555BE : AV_PIX_FMT_BGR555LE;
+ } else if (bpp == 16 && pixdepth == 16) {
+ if (rgb[0] == 0xF800 && rgb[1] == 0x7E0 && rgb[2] == 0x1F)
+ avctx->pix_fmt = be ? AV_PIX_FMT_RGB565BE : AV_PIX_FMT_RGB565LE;
+ else if (rgb[0] == 0x1F && rgb[1] == 0x7E0 && rgb[2] == 0xF800)
+ avctx->pix_fmt = be ? AV_PIX_FMT_BGR565BE : AV_PIX_FMT_BGR565LE;
+ } else if (bpp == 24) {
+ if (rgb[0] == 0xFF0000 && rgb[1] == 0xFF00 && rgb[2] == 0xFF)
+ avctx->pix_fmt = be ? AV_PIX_FMT_RGB24 : AV_PIX_FMT_BGR24;
+ else if (rgb[0] == 0xFF && rgb[1] == 0xFF00 && rgb[2] == 0xFF0000)
+ avctx->pix_fmt = be ? AV_PIX_FMT_BGR24 : AV_PIX_FMT_RGB24;
+ } else if (bpp == 32) {
+ if (rgb[0] == 0xFF0000 && rgb[1] == 0xFF00 && rgb[2] == 0xFF)
+ avctx->pix_fmt = be ? AV_PIX_FMT_ARGB : AV_PIX_FMT_BGRA;
+ else if (rgb[0] == 0xFF && rgb[1] == 0xFF00 && rgb[2] == 0xFF0000)
+ avctx->pix_fmt = be ? AV_PIX_FMT_ABGR : AV_PIX_FMT_RGBA;
+ }
+ bytestream2_skipu(&gb, ncolors * XWD_CMAP_SIZE);
+ break;
+ default:
+ av_log(avctx, AV_LOG_ERROR, "invalid visual class\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (avctx->pix_fmt == AV_PIX_FMT_NONE) {
+ avpriv_request_sample(avctx,
+ "Unknown file: bpp %"PRIu32", pixdepth %"PRIu32", vclass %"PRIu32"",
+ bpp, pixdepth, vclass);
+ return AVERROR_PATCHWELCOME;
+ }
+
+ if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
+ return ret;
+
+ p->key_frame = 1;
+ p->pict_type = AV_PICTURE_TYPE_I;
+
+ if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
+ uint32_t *dst = (uint32_t *)p->data[1];
+ uint8_t red, green, blue;
+
+ for (i = 0; i < ncolors; i++) {
+
+ bytestream2_skipu(&gb, 4); // skip colormap entry number
+ red = bytestream2_get_byteu(&gb);
+ bytestream2_skipu(&gb, 1);
+ green = bytestream2_get_byteu(&gb);
+ bytestream2_skipu(&gb, 1);
+ blue = bytestream2_get_byteu(&gb);
+ bytestream2_skipu(&gb, 3); // skip bitmask flag and padding
+
+ dst[i] = red << 16 | green << 8 | blue;
+ }
+ }
+
+ ptr = p->data[0];
+ for (i = 0; i < avctx->height; i++) {
+ bytestream2_get_bufferu(&gb, ptr, rsize);
+ bytestream2_skipu(&gb, lsize - rsize);
+ ptr += p->linesize[0];
+ }
+
+ *got_frame = 1;
+
+ return buf_size;
+}
+
+AVCodec ff_xwd_decoder = {
+ .name = "xwd",
+ .long_name = NULL_IF_CONFIG_SMALL("XWD (X Window Dump) image"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_XWD,
+ .decode = xwd_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/xwdenc.c b/ffmpeg-2-8-12/libavcodec/xwdenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xwdenc.c
rename to ffmpeg-2-8-12/libavcodec/xwdenc.c
diff --git a/ffmpeg-2-8-11/libavcodec/xxan.c b/ffmpeg-2-8-12/libavcodec/xxan.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/xxan.c
rename to ffmpeg-2-8-12/libavcodec/xxan.c
diff --git a/ffmpeg-2-8-12/libavcodec/y41pdec.c b/ffmpeg-2-8-12/libavcodec/y41pdec.c
new file mode 100644
index 0000000..85a39e4
--- /dev/null
+++ b/ffmpeg-2-8-12/libavcodec/y41pdec.c
@@ -0,0 +1,92 @@
+/*
+ * y41p decoder
+ *
+ * Copyright (c) 2012 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 "avcodec.h"
+#include "internal.h"
+
+static av_cold int y41p_decode_init(AVCodecContext *avctx)
+{
+ avctx->pix_fmt = AV_PIX_FMT_YUV411P;
+ avctx->bits_per_raw_sample = 12;
+
+ if (avctx->width & 7) {
+ av_log(avctx, AV_LOG_WARNING, "y41p requires width to be divisible by 8.\n");
+ }
+
+ return 0;
+}
+
+static int y41p_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame, AVPacket *avpkt)
+{
+ AVFrame *pic = data;
+ uint8_t *src = avpkt->data;
+ uint8_t *y, *u, *v;
+ int i, j, ret;
+
+ if (avpkt->size < 3LL * avctx->height * FFALIGN(avctx->width, 8) / 2) {
+ av_log(avctx, AV_LOG_ERROR, "Insufficient input data.\n");
+ return AVERROR(EINVAL);
+ }
+
+ if ((ret = ff_get_buffer(avctx, pic, 0)) < 0)
+ return ret;
+
+ pic->key_frame = 1;
+ pic->pict_type = AV_PICTURE_TYPE_I;
+
+ for (i = avctx->height - 1; i >= 0 ; i--) {
+ y = &pic->data[0][i * pic->linesize[0]];
+ u = &pic->data[1][i * pic->linesize[1]];
+ v = &pic->data[2][i * pic->linesize[2]];
+ for (j = 0; j < avctx->width; j += 8) {
+ *(u++) = *src++;
+ *(y++) = *src++;
+ *(v++) = *src++;
+ *(y++) = *src++;
+
+ *(u++) = *src++;
+ *(y++) = *src++;
+ *(v++) = *src++;
+ *(y++) = *src++;
+
+ *(y++) = *src++;
+ *(y++) = *src++;
+ *(y++) = *src++;
+ *(y++) = *src++;
+ }
+ }
+
+ *got_frame = 1;
+
+ return avpkt->size;
+}
+
+AVCodec ff_y41p_decoder = {
+ .name = "y41p",
+ .long_name = NULL_IF_CONFIG_SMALL("Uncompressed YUV 4:1:1 12-bit"),
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_Y41P,
+ .init = y41p_decode_init,
+ .decode = y41p_decode_frame,
+ .capabilities = AV_CODEC_CAP_DR1,
+};
diff --git a/ffmpeg-2-8-11/libavcodec/y41penc.c b/ffmpeg-2-8-12/libavcodec/y41penc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/y41penc.c
rename to ffmpeg-2-8-12/libavcodec/y41penc.c
diff --git a/ffmpeg-2-8-11/libavcodec/yop.c b/ffmpeg-2-8-12/libavcodec/yop.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/yop.c
rename to ffmpeg-2-8-12/libavcodec/yop.c
diff --git a/ffmpeg-2-8-11/libavcodec/yuv4dec.c b/ffmpeg-2-8-12/libavcodec/yuv4dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/yuv4dec.c
rename to ffmpeg-2-8-12/libavcodec/yuv4dec.c
diff --git a/ffmpeg-2-8-11/libavcodec/yuv4enc.c b/ffmpeg-2-8-12/libavcodec/yuv4enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/yuv4enc.c
rename to ffmpeg-2-8-12/libavcodec/yuv4enc.c
diff --git a/ffmpeg-2-8-11/libavcodec/zerocodec.c b/ffmpeg-2-8-12/libavcodec/zerocodec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/zerocodec.c
rename to ffmpeg-2-8-12/libavcodec/zerocodec.c
diff --git a/ffmpeg-2-8-11/libavcodec/zmbv.c b/ffmpeg-2-8-12/libavcodec/zmbv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/zmbv.c
rename to ffmpeg-2-8-12/libavcodec/zmbv.c
diff --git a/ffmpeg-2-8-11/libavcodec/zmbvenc.c b/ffmpeg-2-8-12/libavcodec/zmbvenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavcodec/zmbvenc.c
rename to ffmpeg-2-8-12/libavcodec/zmbvenc.c
diff --git a/ffmpeg-2-8-11/libavdevice/Makefile b/ffmpeg-2-8-12/libavdevice/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/Makefile
rename to ffmpeg-2-8-12/libavdevice/Makefile
diff --git a/ffmpeg-2-8-11/libavdevice/alldevices.c b/ffmpeg-2-8-12/libavdevice/alldevices.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/alldevices.c
rename to ffmpeg-2-8-12/libavdevice/alldevices.c
diff --git a/ffmpeg-2-8-11/libavdevice/alsa.c b/ffmpeg-2-8-12/libavdevice/alsa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/alsa.c
rename to ffmpeg-2-8-12/libavdevice/alsa.c
diff --git a/ffmpeg-2-8-11/libavdevice/alsa.h b/ffmpeg-2-8-12/libavdevice/alsa.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/alsa.h
rename to ffmpeg-2-8-12/libavdevice/alsa.h
diff --git a/ffmpeg-2-8-11/libavdevice/alsa_dec.c b/ffmpeg-2-8-12/libavdevice/alsa_dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/alsa_dec.c
rename to ffmpeg-2-8-12/libavdevice/alsa_dec.c
diff --git a/ffmpeg-2-8-11/libavdevice/alsa_enc.c b/ffmpeg-2-8-12/libavdevice/alsa_enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/alsa_enc.c
rename to ffmpeg-2-8-12/libavdevice/alsa_enc.c
diff --git a/ffmpeg-2-8-11/libavdevice/avdevice.c b/ffmpeg-2-8-12/libavdevice/avdevice.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/avdevice.c
rename to ffmpeg-2-8-12/libavdevice/avdevice.c
diff --git a/ffmpeg-2-8-11/libavdevice/avdevice.h b/ffmpeg-2-8-12/libavdevice/avdevice.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/avdevice.h
rename to ffmpeg-2-8-12/libavdevice/avdevice.h
diff --git a/ffmpeg-2-8-11/libavdevice/avdeviceres.rc b/ffmpeg-2-8-12/libavdevice/avdeviceres.rc
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/avdeviceres.rc
rename to ffmpeg-2-8-12/libavdevice/avdeviceres.rc
diff --git a/ffmpeg-2-8-11/libavdevice/avfoundation.m b/ffmpeg-2-8-12/libavdevice/avfoundation.m
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/avfoundation.m
rename to ffmpeg-2-8-12/libavdevice/avfoundation.m
diff --git a/ffmpeg-2-8-11/libavdevice/bktr.c b/ffmpeg-2-8-12/libavdevice/bktr.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/bktr.c
rename to ffmpeg-2-8-12/libavdevice/bktr.c
diff --git a/ffmpeg-2-8-11/libavdevice/caca.c b/ffmpeg-2-8-12/libavdevice/caca.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/caca.c
rename to ffmpeg-2-8-12/libavdevice/caca.c
diff --git a/ffmpeg-2-8-11/libavdevice/decklink_common.cpp b/ffmpeg-2-8-12/libavdevice/decklink_common.cpp
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/decklink_common.cpp
rename to ffmpeg-2-8-12/libavdevice/decklink_common.cpp
diff --git a/ffmpeg-2-8-11/libavdevice/decklink_common.h b/ffmpeg-2-8-12/libavdevice/decklink_common.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/decklink_common.h
rename to ffmpeg-2-8-12/libavdevice/decklink_common.h
diff --git a/ffmpeg-2-8-11/libavdevice/decklink_common_c.h b/ffmpeg-2-8-12/libavdevice/decklink_common_c.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/decklink_common_c.h
rename to ffmpeg-2-8-12/libavdevice/decklink_common_c.h
diff --git a/ffmpeg-2-8-11/libavdevice/decklink_dec.cpp b/ffmpeg-2-8-12/libavdevice/decklink_dec.cpp
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/decklink_dec.cpp
rename to ffmpeg-2-8-12/libavdevice/decklink_dec.cpp
diff --git a/ffmpeg-2-8-11/libavdevice/decklink_dec.h b/ffmpeg-2-8-12/libavdevice/decklink_dec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/decklink_dec.h
rename to ffmpeg-2-8-12/libavdevice/decklink_dec.h
diff --git a/ffmpeg-2-8-11/libavdevice/decklink_dec_c.c b/ffmpeg-2-8-12/libavdevice/decklink_dec_c.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/decklink_dec_c.c
rename to ffmpeg-2-8-12/libavdevice/decklink_dec_c.c
diff --git a/ffmpeg-2-8-11/libavdevice/decklink_enc.cpp b/ffmpeg-2-8-12/libavdevice/decklink_enc.cpp
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/decklink_enc.cpp
rename to ffmpeg-2-8-12/libavdevice/decklink_enc.cpp
diff --git a/ffmpeg-2-8-11/libavdevice/decklink_enc.h b/ffmpeg-2-8-12/libavdevice/decklink_enc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/decklink_enc.h
rename to ffmpeg-2-8-12/libavdevice/decklink_enc.h
diff --git a/ffmpeg-2-8-11/libavdevice/decklink_enc_c.c b/ffmpeg-2-8-12/libavdevice/decklink_enc_c.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/decklink_enc_c.c
rename to ffmpeg-2-8-12/libavdevice/decklink_enc_c.c
diff --git a/ffmpeg-2-8-11/libavdevice/dshow.c b/ffmpeg-2-8-12/libavdevice/dshow.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/dshow.c
rename to ffmpeg-2-8-12/libavdevice/dshow.c
diff --git a/ffmpeg-2-8-11/libavdevice/dshow_capture.h b/ffmpeg-2-8-12/libavdevice/dshow_capture.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/dshow_capture.h
rename to ffmpeg-2-8-12/libavdevice/dshow_capture.h
diff --git a/ffmpeg-2-8-11/libavdevice/dshow_common.c b/ffmpeg-2-8-12/libavdevice/dshow_common.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/dshow_common.c
rename to ffmpeg-2-8-12/libavdevice/dshow_common.c
diff --git a/ffmpeg-2-8-11/libavdevice/dshow_crossbar.c b/ffmpeg-2-8-12/libavdevice/dshow_crossbar.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/dshow_crossbar.c
rename to ffmpeg-2-8-12/libavdevice/dshow_crossbar.c
diff --git a/ffmpeg-2-8-11/libavdevice/dshow_enummediatypes.c b/ffmpeg-2-8-12/libavdevice/dshow_enummediatypes.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/dshow_enummediatypes.c
rename to ffmpeg-2-8-12/libavdevice/dshow_enummediatypes.c
diff --git a/ffmpeg-2-8-11/libavdevice/dshow_enumpins.c b/ffmpeg-2-8-12/libavdevice/dshow_enumpins.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/dshow_enumpins.c
rename to ffmpeg-2-8-12/libavdevice/dshow_enumpins.c
diff --git a/ffmpeg-2-8-11/libavdevice/dshow_filter.c b/ffmpeg-2-8-12/libavdevice/dshow_filter.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/dshow_filter.c
rename to ffmpeg-2-8-12/libavdevice/dshow_filter.c
diff --git a/ffmpeg-2-8-11/libavdevice/dshow_pin.c b/ffmpeg-2-8-12/libavdevice/dshow_pin.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/dshow_pin.c
rename to ffmpeg-2-8-12/libavdevice/dshow_pin.c
diff --git a/ffmpeg-2-8-11/libavdevice/dv1394.c b/ffmpeg-2-8-12/libavdevice/dv1394.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/dv1394.c
rename to ffmpeg-2-8-12/libavdevice/dv1394.c
diff --git a/ffmpeg-2-8-11/libavdevice/dv1394.h b/ffmpeg-2-8-12/libavdevice/dv1394.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/dv1394.h
rename to ffmpeg-2-8-12/libavdevice/dv1394.h
diff --git a/ffmpeg-2-8-11/libavdevice/fbdev_common.c b/ffmpeg-2-8-12/libavdevice/fbdev_common.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/fbdev_common.c
rename to ffmpeg-2-8-12/libavdevice/fbdev_common.c
diff --git a/ffmpeg-2-8-11/libavdevice/fbdev_common.h b/ffmpeg-2-8-12/libavdevice/fbdev_common.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/fbdev_common.h
rename to ffmpeg-2-8-12/libavdevice/fbdev_common.h
diff --git a/ffmpeg-2-8-11/libavdevice/fbdev_dec.c b/ffmpeg-2-8-12/libavdevice/fbdev_dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/fbdev_dec.c
rename to ffmpeg-2-8-12/libavdevice/fbdev_dec.c
diff --git a/ffmpeg-2-8-11/libavdevice/fbdev_enc.c b/ffmpeg-2-8-12/libavdevice/fbdev_enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/fbdev_enc.c
rename to ffmpeg-2-8-12/libavdevice/fbdev_enc.c
diff --git a/ffmpeg-2-8-11/libavdevice/file_open.c b/ffmpeg-2-8-12/libavdevice/file_open.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/file_open.c
rename to ffmpeg-2-8-12/libavdevice/file_open.c
diff --git a/ffmpeg-2-8-11/libavdevice/gdigrab.c b/ffmpeg-2-8-12/libavdevice/gdigrab.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/gdigrab.c
rename to ffmpeg-2-8-12/libavdevice/gdigrab.c
diff --git a/ffmpeg-2-8-11/libavdevice/iec61883.c b/ffmpeg-2-8-12/libavdevice/iec61883.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/iec61883.c
rename to ffmpeg-2-8-12/libavdevice/iec61883.c
diff --git a/ffmpeg-2-8-11/libavdevice/internal.h b/ffmpeg-2-8-12/libavdevice/internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/internal.h
rename to ffmpeg-2-8-12/libavdevice/internal.h
diff --git a/ffmpeg-2-8-11/libavdevice/jack.c b/ffmpeg-2-8-12/libavdevice/jack.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/jack.c
rename to ffmpeg-2-8-12/libavdevice/jack.c
diff --git a/ffmpeg-2-8-11/libavdevice/lavfi.c b/ffmpeg-2-8-12/libavdevice/lavfi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/lavfi.c
rename to ffmpeg-2-8-12/libavdevice/lavfi.c
diff --git a/ffmpeg-2-8-11/libavdevice/libavdevice.v b/ffmpeg-2-8-12/libavdevice/libavdevice.v
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/libavdevice.v
rename to ffmpeg-2-8-12/libavdevice/libavdevice.v
diff --git a/ffmpeg-2-8-11/libavdevice/libcdio.c b/ffmpeg-2-8-12/libavdevice/libcdio.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/libcdio.c
rename to ffmpeg-2-8-12/libavdevice/libcdio.c
diff --git a/ffmpeg-2-8-11/libavdevice/libdc1394.c b/ffmpeg-2-8-12/libavdevice/libdc1394.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/libdc1394.c
rename to ffmpeg-2-8-12/libavdevice/libdc1394.c
diff --git a/ffmpeg-2-8-11/libavdevice/openal-dec.c b/ffmpeg-2-8-12/libavdevice/openal-dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/openal-dec.c
rename to ffmpeg-2-8-12/libavdevice/openal-dec.c
diff --git a/ffmpeg-2-8-11/libavdevice/opengl_enc.c b/ffmpeg-2-8-12/libavdevice/opengl_enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/opengl_enc.c
rename to ffmpeg-2-8-12/libavdevice/opengl_enc.c
diff --git a/ffmpeg-2-8-11/libavdevice/opengl_enc_shaders.h b/ffmpeg-2-8-12/libavdevice/opengl_enc_shaders.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/opengl_enc_shaders.h
rename to ffmpeg-2-8-12/libavdevice/opengl_enc_shaders.h
diff --git a/ffmpeg-2-8-11/libavdevice/oss.c b/ffmpeg-2-8-12/libavdevice/oss.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/oss.c
rename to ffmpeg-2-8-12/libavdevice/oss.c
diff --git a/ffmpeg-2-8-11/libavdevice/oss.h b/ffmpeg-2-8-12/libavdevice/oss.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/oss.h
rename to ffmpeg-2-8-12/libavdevice/oss.h
diff --git a/ffmpeg-2-8-11/libavdevice/oss_dec.c b/ffmpeg-2-8-12/libavdevice/oss_dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/oss_dec.c
rename to ffmpeg-2-8-12/libavdevice/oss_dec.c
diff --git a/ffmpeg-2-8-11/libavdevice/oss_enc.c b/ffmpeg-2-8-12/libavdevice/oss_enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/oss_enc.c
rename to ffmpeg-2-8-12/libavdevice/oss_enc.c
diff --git a/ffmpeg-2-8-11/libavdevice/pulse_audio_common.c b/ffmpeg-2-8-12/libavdevice/pulse_audio_common.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/pulse_audio_common.c
rename to ffmpeg-2-8-12/libavdevice/pulse_audio_common.c
diff --git a/ffmpeg-2-8-11/libavdevice/pulse_audio_common.h b/ffmpeg-2-8-12/libavdevice/pulse_audio_common.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/pulse_audio_common.h
rename to ffmpeg-2-8-12/libavdevice/pulse_audio_common.h
diff --git a/ffmpeg-2-8-11/libavdevice/pulse_audio_dec.c b/ffmpeg-2-8-12/libavdevice/pulse_audio_dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/pulse_audio_dec.c
rename to ffmpeg-2-8-12/libavdevice/pulse_audio_dec.c
diff --git a/ffmpeg-2-8-11/libavdevice/pulse_audio_enc.c b/ffmpeg-2-8-12/libavdevice/pulse_audio_enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/pulse_audio_enc.c
rename to ffmpeg-2-8-12/libavdevice/pulse_audio_enc.c
diff --git a/ffmpeg-2-8-11/libavdevice/qtkit.m b/ffmpeg-2-8-12/libavdevice/qtkit.m
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/qtkit.m
rename to ffmpeg-2-8-12/libavdevice/qtkit.m
diff --git a/ffmpeg-2-8-11/libavdevice/sdl.c b/ffmpeg-2-8-12/libavdevice/sdl.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/sdl.c
rename to ffmpeg-2-8-12/libavdevice/sdl.c
diff --git a/ffmpeg-2-8-11/libavdevice/sndio.c b/ffmpeg-2-8-12/libavdevice/sndio.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/sndio.c
rename to ffmpeg-2-8-12/libavdevice/sndio.c
diff --git a/ffmpeg-2-8-11/libavdevice/sndio.h b/ffmpeg-2-8-12/libavdevice/sndio.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/sndio.h
rename to ffmpeg-2-8-12/libavdevice/sndio.h
diff --git a/ffmpeg-2-8-11/libavdevice/sndio_dec.c b/ffmpeg-2-8-12/libavdevice/sndio_dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/sndio_dec.c
rename to ffmpeg-2-8-12/libavdevice/sndio_dec.c
diff --git a/ffmpeg-2-8-11/libavdevice/sndio_enc.c b/ffmpeg-2-8-12/libavdevice/sndio_enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/sndio_enc.c
rename to ffmpeg-2-8-12/libavdevice/sndio_enc.c
diff --git a/ffmpeg-2-8-11/libavdevice/timefilter.c b/ffmpeg-2-8-12/libavdevice/timefilter.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/timefilter.c
rename to ffmpeg-2-8-12/libavdevice/timefilter.c
diff --git a/ffmpeg-2-8-11/libavdevice/timefilter.h b/ffmpeg-2-8-12/libavdevice/timefilter.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/timefilter.h
rename to ffmpeg-2-8-12/libavdevice/timefilter.h
diff --git a/ffmpeg-2-8-11/libavdevice/utils.c b/ffmpeg-2-8-12/libavdevice/utils.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/utils.c
rename to ffmpeg-2-8-12/libavdevice/utils.c
diff --git a/ffmpeg-2-8-11/libavdevice/v4l.c b/ffmpeg-2-8-12/libavdevice/v4l.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/v4l.c
rename to ffmpeg-2-8-12/libavdevice/v4l.c
diff --git a/ffmpeg-2-8-11/libavdevice/v4l2-common.c b/ffmpeg-2-8-12/libavdevice/v4l2-common.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/v4l2-common.c
rename to ffmpeg-2-8-12/libavdevice/v4l2-common.c
diff --git a/ffmpeg-2-8-11/libavdevice/v4l2-common.h b/ffmpeg-2-8-12/libavdevice/v4l2-common.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/v4l2-common.h
rename to ffmpeg-2-8-12/libavdevice/v4l2-common.h
diff --git a/ffmpeg-2-8-11/libavdevice/v4l2.c b/ffmpeg-2-8-12/libavdevice/v4l2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/v4l2.c
rename to ffmpeg-2-8-12/libavdevice/v4l2.c
diff --git a/ffmpeg-2-8-11/libavdevice/v4l2enc.c b/ffmpeg-2-8-12/libavdevice/v4l2enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/v4l2enc.c
rename to ffmpeg-2-8-12/libavdevice/v4l2enc.c
diff --git a/ffmpeg-2-8-11/libavdevice/version.h b/ffmpeg-2-8-12/libavdevice/version.h
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/version.h
rename to ffmpeg-2-8-12/libavdevice/version.h
diff --git a/ffmpeg-2-8-11/libavdevice/vfwcap.c b/ffmpeg-2-8-12/libavdevice/vfwcap.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/vfwcap.c
rename to ffmpeg-2-8-12/libavdevice/vfwcap.c
diff --git a/ffmpeg-2-8-11/libavdevice/x11grab.c b/ffmpeg-2-8-12/libavdevice/x11grab.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/x11grab.c
rename to ffmpeg-2-8-12/libavdevice/x11grab.c
diff --git a/ffmpeg-2-8-11/libavdevice/xcbgrab.c b/ffmpeg-2-8-12/libavdevice/xcbgrab.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/xcbgrab.c
rename to ffmpeg-2-8-12/libavdevice/xcbgrab.c
diff --git a/ffmpeg-2-8-11/libavdevice/xv.c b/ffmpeg-2-8-12/libavdevice/xv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavdevice/xv.c
rename to ffmpeg-2-8-12/libavdevice/xv.c
diff --git a/ffmpeg-2-8-11/libavfilter/Makefile b/ffmpeg-2-8-12/libavfilter/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/Makefile
rename to ffmpeg-2-8-12/libavfilter/Makefile
diff --git a/ffmpeg-2-8-11/libavfilter/aeval.c b/ffmpeg-2-8-12/libavfilter/aeval.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/aeval.c
rename to ffmpeg-2-8-12/libavfilter/aeval.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_adelay.c b/ffmpeg-2-8-12/libavfilter/af_adelay.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_adelay.c
rename to ffmpeg-2-8-12/libavfilter/af_adelay.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_aecho.c b/ffmpeg-2-8-12/libavfilter/af_aecho.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_aecho.c
rename to ffmpeg-2-8-12/libavfilter/af_aecho.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_afade.c b/ffmpeg-2-8-12/libavfilter/af_afade.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_afade.c
rename to ffmpeg-2-8-12/libavfilter/af_afade.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_aformat.c b/ffmpeg-2-8-12/libavfilter/af_aformat.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_aformat.c
rename to ffmpeg-2-8-12/libavfilter/af_aformat.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_amerge.c b/ffmpeg-2-8-12/libavfilter/af_amerge.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_amerge.c
rename to ffmpeg-2-8-12/libavfilter/af_amerge.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_amix.c b/ffmpeg-2-8-12/libavfilter/af_amix.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_amix.c
rename to ffmpeg-2-8-12/libavfilter/af_amix.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_anull.c b/ffmpeg-2-8-12/libavfilter/af_anull.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_anull.c
rename to ffmpeg-2-8-12/libavfilter/af_anull.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_apad.c b/ffmpeg-2-8-12/libavfilter/af_apad.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_apad.c
rename to ffmpeg-2-8-12/libavfilter/af_apad.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_aphaser.c b/ffmpeg-2-8-12/libavfilter/af_aphaser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_aphaser.c
rename to ffmpeg-2-8-12/libavfilter/af_aphaser.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_aresample.c b/ffmpeg-2-8-12/libavfilter/af_aresample.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_aresample.c
rename to ffmpeg-2-8-12/libavfilter/af_aresample.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_asetnsamples.c b/ffmpeg-2-8-12/libavfilter/af_asetnsamples.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_asetnsamples.c
rename to ffmpeg-2-8-12/libavfilter/af_asetnsamples.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_asetrate.c b/ffmpeg-2-8-12/libavfilter/af_asetrate.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_asetrate.c
rename to ffmpeg-2-8-12/libavfilter/af_asetrate.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_ashowinfo.c b/ffmpeg-2-8-12/libavfilter/af_ashowinfo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_ashowinfo.c
rename to ffmpeg-2-8-12/libavfilter/af_ashowinfo.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_astats.c b/ffmpeg-2-8-12/libavfilter/af_astats.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_astats.c
rename to ffmpeg-2-8-12/libavfilter/af_astats.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_astreamsync.c b/ffmpeg-2-8-12/libavfilter/af_astreamsync.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_astreamsync.c
rename to ffmpeg-2-8-12/libavfilter/af_astreamsync.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_asyncts.c b/ffmpeg-2-8-12/libavfilter/af_asyncts.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_asyncts.c
rename to ffmpeg-2-8-12/libavfilter/af_asyncts.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_atempo.c b/ffmpeg-2-8-12/libavfilter/af_atempo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_atempo.c
rename to ffmpeg-2-8-12/libavfilter/af_atempo.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_biquads.c b/ffmpeg-2-8-12/libavfilter/af_biquads.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_biquads.c
rename to ffmpeg-2-8-12/libavfilter/af_biquads.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_bs2b.c b/ffmpeg-2-8-12/libavfilter/af_bs2b.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_bs2b.c
rename to ffmpeg-2-8-12/libavfilter/af_bs2b.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_channelmap.c b/ffmpeg-2-8-12/libavfilter/af_channelmap.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_channelmap.c
rename to ffmpeg-2-8-12/libavfilter/af_channelmap.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_channelsplit.c b/ffmpeg-2-8-12/libavfilter/af_channelsplit.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_channelsplit.c
rename to ffmpeg-2-8-12/libavfilter/af_channelsplit.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_chorus.c b/ffmpeg-2-8-12/libavfilter/af_chorus.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_chorus.c
rename to ffmpeg-2-8-12/libavfilter/af_chorus.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_compand.c b/ffmpeg-2-8-12/libavfilter/af_compand.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_compand.c
rename to ffmpeg-2-8-12/libavfilter/af_compand.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_dcshift.c b/ffmpeg-2-8-12/libavfilter/af_dcshift.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_dcshift.c
rename to ffmpeg-2-8-12/libavfilter/af_dcshift.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_dynaudnorm.c b/ffmpeg-2-8-12/libavfilter/af_dynaudnorm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_dynaudnorm.c
rename to ffmpeg-2-8-12/libavfilter/af_dynaudnorm.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_earwax.c b/ffmpeg-2-8-12/libavfilter/af_earwax.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_earwax.c
rename to ffmpeg-2-8-12/libavfilter/af_earwax.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_flanger.c b/ffmpeg-2-8-12/libavfilter/af_flanger.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_flanger.c
rename to ffmpeg-2-8-12/libavfilter/af_flanger.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_join.c b/ffmpeg-2-8-12/libavfilter/af_join.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_join.c
rename to ffmpeg-2-8-12/libavfilter/af_join.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_ladspa.c b/ffmpeg-2-8-12/libavfilter/af_ladspa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_ladspa.c
rename to ffmpeg-2-8-12/libavfilter/af_ladspa.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_pan.c b/ffmpeg-2-8-12/libavfilter/af_pan.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_pan.c
rename to ffmpeg-2-8-12/libavfilter/af_pan.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_replaygain.c b/ffmpeg-2-8-12/libavfilter/af_replaygain.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_replaygain.c
rename to ffmpeg-2-8-12/libavfilter/af_replaygain.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_resample.c b/ffmpeg-2-8-12/libavfilter/af_resample.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_resample.c
rename to ffmpeg-2-8-12/libavfilter/af_resample.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_sidechaincompress.c b/ffmpeg-2-8-12/libavfilter/af_sidechaincompress.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_sidechaincompress.c
rename to ffmpeg-2-8-12/libavfilter/af_sidechaincompress.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_silencedetect.c b/ffmpeg-2-8-12/libavfilter/af_silencedetect.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_silencedetect.c
rename to ffmpeg-2-8-12/libavfilter/af_silencedetect.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_silenceremove.c b/ffmpeg-2-8-12/libavfilter/af_silenceremove.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_silenceremove.c
rename to ffmpeg-2-8-12/libavfilter/af_silenceremove.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_volume.c b/ffmpeg-2-8-12/libavfilter/af_volume.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_volume.c
rename to ffmpeg-2-8-12/libavfilter/af_volume.c
diff --git a/ffmpeg-2-8-11/libavfilter/af_volume.h b/ffmpeg-2-8-12/libavfilter/af_volume.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_volume.h
rename to ffmpeg-2-8-12/libavfilter/af_volume.h
diff --git a/ffmpeg-2-8-11/libavfilter/af_volumedetect.c b/ffmpeg-2-8-12/libavfilter/af_volumedetect.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/af_volumedetect.c
rename to ffmpeg-2-8-12/libavfilter/af_volumedetect.c
diff --git a/ffmpeg-2-8-11/libavfilter/all_channel_layouts.inc b/ffmpeg-2-8-12/libavfilter/all_channel_layouts.inc
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/all_channel_layouts.inc
rename to ffmpeg-2-8-12/libavfilter/all_channel_layouts.inc
diff --git a/ffmpeg-2-8-11/libavfilter/allfilters.c b/ffmpeg-2-8-12/libavfilter/allfilters.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/allfilters.c
rename to ffmpeg-2-8-12/libavfilter/allfilters.c
diff --git a/ffmpeg-2-8-11/libavfilter/asink_anullsink.c b/ffmpeg-2-8-12/libavfilter/asink_anullsink.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/asink_anullsink.c
rename to ffmpeg-2-8-12/libavfilter/asink_anullsink.c
diff --git a/ffmpeg-2-8-11/libavfilter/asrc_abuffer.h b/ffmpeg-2-8-12/libavfilter/asrc_abuffer.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/asrc_abuffer.h
rename to ffmpeg-2-8-12/libavfilter/asrc_abuffer.h
diff --git a/ffmpeg-2-8-11/libavfilter/asrc_anullsrc.c b/ffmpeg-2-8-12/libavfilter/asrc_anullsrc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/asrc_anullsrc.c
rename to ffmpeg-2-8-12/libavfilter/asrc_anullsrc.c
diff --git a/ffmpeg-2-8-11/libavfilter/asrc_flite.c b/ffmpeg-2-8-12/libavfilter/asrc_flite.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/asrc_flite.c
rename to ffmpeg-2-8-12/libavfilter/asrc_flite.c
diff --git a/ffmpeg-2-8-11/libavfilter/asrc_sine.c b/ffmpeg-2-8-12/libavfilter/asrc_sine.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/asrc_sine.c
rename to ffmpeg-2-8-12/libavfilter/asrc_sine.c
diff --git a/ffmpeg-2-8-11/libavfilter/audio.c b/ffmpeg-2-8-12/libavfilter/audio.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/audio.c
rename to ffmpeg-2-8-12/libavfilter/audio.c
diff --git a/ffmpeg-2-8-11/libavfilter/audio.h b/ffmpeg-2-8-12/libavfilter/audio.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/audio.h
rename to ffmpeg-2-8-12/libavfilter/audio.h
diff --git a/ffmpeg-2-8-11/libavfilter/avcodec.c b/ffmpeg-2-8-12/libavfilter/avcodec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/avcodec.c
rename to ffmpeg-2-8-12/libavfilter/avcodec.c
diff --git a/ffmpeg-2-8-11/libavfilter/avcodec.h b/ffmpeg-2-8-12/libavfilter/avcodec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/avcodec.h
rename to ffmpeg-2-8-12/libavfilter/avcodec.h
diff --git a/ffmpeg-2-8-11/libavfilter/avf_aphasemeter.c b/ffmpeg-2-8-12/libavfilter/avf_aphasemeter.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/avf_aphasemeter.c
rename to ffmpeg-2-8-12/libavfilter/avf_aphasemeter.c
diff --git a/ffmpeg-2-8-11/libavfilter/avf_avectorscope.c b/ffmpeg-2-8-12/libavfilter/avf_avectorscope.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/avf_avectorscope.c
rename to ffmpeg-2-8-12/libavfilter/avf_avectorscope.c
diff --git a/ffmpeg-2-8-11/libavfilter/avf_concat.c b/ffmpeg-2-8-12/libavfilter/avf_concat.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/avf_concat.c
rename to ffmpeg-2-8-12/libavfilter/avf_concat.c
diff --git a/ffmpeg-2-8-11/libavfilter/avf_showcqt.c b/ffmpeg-2-8-12/libavfilter/avf_showcqt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/avf_showcqt.c
rename to ffmpeg-2-8-12/libavfilter/avf_showcqt.c
diff --git a/ffmpeg-2-8-11/libavfilter/avf_showfreqs.c b/ffmpeg-2-8-12/libavfilter/avf_showfreqs.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/avf_showfreqs.c
rename to ffmpeg-2-8-12/libavfilter/avf_showfreqs.c
diff --git a/ffmpeg-2-8-11/libavfilter/avf_showspectrum.c b/ffmpeg-2-8-12/libavfilter/avf_showspectrum.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/avf_showspectrum.c
rename to ffmpeg-2-8-12/libavfilter/avf_showspectrum.c
diff --git a/ffmpeg-2-8-11/libavfilter/avf_showvolume.c b/ffmpeg-2-8-12/libavfilter/avf_showvolume.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/avf_showvolume.c
rename to ffmpeg-2-8-12/libavfilter/avf_showvolume.c
diff --git a/ffmpeg-2-8-11/libavfilter/avf_showwaves.c b/ffmpeg-2-8-12/libavfilter/avf_showwaves.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/avf_showwaves.c
rename to ffmpeg-2-8-12/libavfilter/avf_showwaves.c
diff --git a/ffmpeg-2-8-11/libavfilter/avfilter.c b/ffmpeg-2-8-12/libavfilter/avfilter.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/avfilter.c
rename to ffmpeg-2-8-12/libavfilter/avfilter.c
diff --git a/ffmpeg-2-8-11/libavfilter/avfilter.h b/ffmpeg-2-8-12/libavfilter/avfilter.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/avfilter.h
rename to ffmpeg-2-8-12/libavfilter/avfilter.h
diff --git a/ffmpeg-2-8-12/libavfilter/avfiltergraph.c b/ffmpeg-2-8-12/libavfilter/avfiltergraph.c
new file mode 100644
index 0000000..f0ffa8e
--- /dev/null
+++ b/ffmpeg-2-8-12/libavfilter/avfiltergraph.c
@@ -0,0 +1,1394 @@
+/*
+ * filter graphs
+ * Copyright (c) 2008 Vitor Sessak
+ * Copyright (c) 2007 Bobby Bingham
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bprint.h"
+#include "libavutil/channel_layout.h"
+#include "libavutil/internal.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+
+#include "avfilter.h"
+#include "formats.h"
+#include "internal.h"
+#include "thread.h"
+
+#define OFFSET(x) offsetof(AVFilterGraph, x)
+#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
+static const AVOption filtergraph_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" },
+ { "threads", "Maximum number of threads", OFFSET(nb_threads),
+ AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS },
+ {"scale_sws_opts" , "default scale filter options" , OFFSET(scale_sws_opts) ,
+ AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+ {"aresample_swr_opts" , "default aresample filter options" , OFFSET(aresample_swr_opts) ,
+ AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, FLAGS },
+ { NULL },
+};
+
+static const AVClass filtergraph_class = {
+ .class_name = "AVFilterGraph",
+ .item_name = av_default_item_name,
+ .version = LIBAVUTIL_VERSION_INT,
+ .option = filtergraph_options,
+ .category = AV_CLASS_CATEGORY_FILTER,
+};
+
+#if !HAVE_THREADS
+void ff_graph_thread_free(AVFilterGraph *graph)
+{
+}
+
+int ff_graph_thread_init(AVFilterGraph *graph)
+{
+ graph->thread_type = 0;
+ graph->nb_threads = 1;
+ return 0;
+}
+#endif
+
+AVFilterGraph *avfilter_graph_alloc(void)
+{
+ AVFilterGraph *ret = av_mallocz(sizeof(*ret));
+ if (!ret)
+ return NULL;
+
+ ret->internal = av_mallocz(sizeof(*ret->internal));
+ if (!ret->internal) {
+ av_freep(&ret);
+ return NULL;
+ }
+
+ ret->av_class = &filtergraph_class;
+ av_opt_set_defaults(ret);
+
+ return ret;
+}
+
+void ff_filter_graph_remove_filter(AVFilterGraph *graph, AVFilterContext *filter)
+{
+ int i;
+ for (i = 0; i < graph->nb_filters; i++) {
+ if (graph->filters[i] == filter) {
+ FFSWAP(AVFilterContext*, graph->filters[i],
+ graph->filters[graph->nb_filters - 1]);
+ graph->nb_filters--;
+ return;
+ }
+ }
+}
+
+void avfilter_graph_free(AVFilterGraph **graph)
+{
+ if (!*graph)
+ return;
+
+ while ((*graph)->nb_filters)
+ avfilter_free((*graph)->filters[0]);
+
+ ff_graph_thread_free(*graph);
+
+ av_freep(&(*graph)->sink_links);
+
+ av_freep(&(*graph)->scale_sws_opts);
+ av_freep(&(*graph)->aresample_swr_opts);
+ av_freep(&(*graph)->resample_lavr_opts);
+ av_freep(&(*graph)->filters);
+ av_freep(&(*graph)->internal);
+ av_freep(graph);
+}
+
+#if FF_API_AVFILTER_OPEN
+int avfilter_graph_add_filter(AVFilterGraph *graph, AVFilterContext *filter)
+{
+ AVFilterContext **filters = av_realloc(graph->filters,
+ sizeof(*filters) * (graph->nb_filters + 1));
+ if (!filters)
+ return AVERROR(ENOMEM);
+
+ graph->filters = filters;
+ graph->filters[graph->nb_filters++] = filter;
+
+#if FF_API_FOO_COUNT
+FF_DISABLE_DEPRECATION_WARNINGS
+ graph->filter_count_unused = graph->nb_filters;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ filter->graph = graph;
+
+ return 0;
+}
+#endif
+
+int avfilter_graph_create_filter(AVFilterContext **filt_ctx, const AVFilter *filt,
+ const char *name, const char *args, void *opaque,
+ AVFilterGraph *graph_ctx)
+{
+ int ret;
+
+ *filt_ctx = avfilter_graph_alloc_filter(graph_ctx, filt, name);
+ if (!*filt_ctx)
+ return AVERROR(ENOMEM);
+
+ ret = avfilter_init_str(*filt_ctx, args);
+ if (ret < 0)
+ goto fail;
+
+ return 0;
+
+fail:
+ if (*filt_ctx)
+ avfilter_free(*filt_ctx);
+ *filt_ctx = NULL;
+ return ret;
+}
+
+void avfilter_graph_set_auto_convert(AVFilterGraph *graph, unsigned flags)
+{
+ graph->disable_auto_convert = flags;
+}
+
+AVFilterContext *avfilter_graph_alloc_filter(AVFilterGraph *graph,
+ const AVFilter *filter,
+ const char *name)
+{
+ AVFilterContext **filters, *s;
+
+ if (graph->thread_type && !graph->internal->thread_execute) {
+ if (graph->execute) {
+ graph->internal->thread_execute = graph->execute;
+ } else {
+ int ret = ff_graph_thread_init(graph);
+ if (ret < 0) {
+ av_log(graph, AV_LOG_ERROR, "Error initializing threading.\n");
+ return NULL;
+ }
+ }
+ }
+
+ s = ff_filter_alloc(filter, name);
+ if (!s)
+ return NULL;
+
+ filters = av_realloc(graph->filters, sizeof(*filters) * (graph->nb_filters + 1));
+ if (!filters) {
+ avfilter_free(s);
+ return NULL;
+ }
+
+ graph->filters = filters;
+ graph->filters[graph->nb_filters++] = s;
+
+#if FF_API_FOO_COUNT
+FF_DISABLE_DEPRECATION_WARNINGS
+ graph->filter_count_unused = graph->nb_filters;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ s->graph = graph;
+
+ return s;
+}
+
+/**
+ * Check for the validity of graph.
+ *
+ * A graph is considered valid if all its input and output pads are
+ * connected.
+ *
+ * @return >= 0 in case of success, a negative value otherwise
+ */
+static int graph_check_validity(AVFilterGraph *graph, AVClass *log_ctx)
+{
+ AVFilterContext *filt;
+ int i, j;
+
+ for (i = 0; i < graph->nb_filters; i++) {
+ const AVFilterPad *pad;
+ filt = graph->filters[i];
+
+ for (j = 0; j < filt->nb_inputs; j++) {
+ if (!filt->inputs[j] || !filt->inputs[j]->src) {
+ pad = &filt->input_pads[j];
+ av_log(log_ctx, AV_LOG_ERROR,
+ "Input pad \"%s\" with type %s of the filter instance \"%s\" of %s not connected to any source\n",
+ pad->name, av_get_media_type_string(pad->type), filt->name, filt->filter->name);
+ return AVERROR(EINVAL);
+ }
+ }
+
+ for (j = 0; j < filt->nb_outputs; j++) {
+ if (!filt->outputs[j] || !filt->outputs[j]->dst) {
+ pad = &filt->output_pads[j];
+ av_log(log_ctx, AV_LOG_ERROR,
+ "Output pad \"%s\" with type %s of the filter instance \"%s\" of %s not connected to any destination\n",
+ pad->name, av_get_media_type_string(pad->type), filt->name, filt->filter->name);
+ return AVERROR(EINVAL);
+ }
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * Configure all the links of graphctx.
+ *
+ * @return >= 0 in case of success, a negative value otherwise
+ */
+static int graph_config_links(AVFilterGraph *graph, AVClass *log_ctx)
+{
+ AVFilterContext *filt;
+ int i, ret;
+
+ for (i = 0; i < graph->nb_filters; i++) {
+ filt = graph->filters[i];
+
+ if (!filt->nb_outputs) {
+ if ((ret = avfilter_config_links(filt)))
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+AVFilterContext *avfilter_graph_get_filter(AVFilterGraph *graph, const char *name)
+{
+ int i;
+
+ for (i = 0; i < graph->nb_filters; i++)
+ if (graph->filters[i]->name && !strcmp(name, graph->filters[i]->name))
+ return graph->filters[i];
+
+ return NULL;
+}
+
+static void sanitize_channel_layouts(void *log, AVFilterChannelLayouts *l)
+{
+ if (!l)
+ return;
+ if (l->nb_channel_layouts) {
+ if (l->all_layouts || l->all_counts)
+ av_log(log, AV_LOG_WARNING, "All layouts set on non-empty list\n");
+ l->all_layouts = l->all_counts = 0;
+ } else {
+ if (l->all_counts && !l->all_layouts)
+ av_log(log, AV_LOG_WARNING, "All counts without all layouts\n");
+ l->all_layouts = 1;
+ }
+}
+
+static int filter_query_formats(AVFilterContext *ctx)
+{
+ int ret, i;
+ AVFilterFormats *formats;
+ AVFilterChannelLayouts *chlayouts;
+ AVFilterFormats *samplerates;
+ enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type :
+ ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type :
+ AVMEDIA_TYPE_VIDEO;
+
+ if ((ret = ctx->filter->query_formats(ctx)) < 0) {
+ if (ret != AVERROR(EAGAIN))
+ av_log(ctx, AV_LOG_ERROR, "Query format failed for '%s': %s\n",
+ ctx->name, av_err2str(ret));
+ return ret;
+ }
+
+ for (i = 0; i < ctx->nb_inputs; i++)
+ sanitize_channel_layouts(ctx, ctx->inputs[i]->out_channel_layouts);
+ for (i = 0; i < ctx->nb_outputs; i++)
+ sanitize_channel_layouts(ctx, ctx->outputs[i]->in_channel_layouts);
+
+ formats = ff_all_formats(type);
+ if (!formats)
+ return AVERROR(ENOMEM);
+ ff_set_common_formats(ctx, formats);
+ if (type == AVMEDIA_TYPE_AUDIO) {
+ samplerates = ff_all_samplerates();
+ if (!samplerates)
+ return AVERROR(ENOMEM);
+ ff_set_common_samplerates(ctx, samplerates);
+ chlayouts = ff_all_channel_layouts();
+ if (!chlayouts)
+ return AVERROR(ENOMEM);
+ ff_set_common_channel_layouts(ctx, chlayouts);
+ }
+ return 0;
+}
+
+static int formats_declared(AVFilterContext *f)
+{
+ int i;
+
+ for (i = 0; i < f->nb_inputs; i++) {
+ if (!f->inputs[i]->out_formats)
+ return 0;
+ if (f->inputs[i]->type == AVMEDIA_TYPE_AUDIO &&
+ !(f->inputs[i]->out_samplerates &&
+ f->inputs[i]->out_channel_layouts))
+ return 0;
+ }
+ for (i = 0; i < f->nb_outputs; i++) {
+ if (!f->outputs[i]->in_formats)
+ return 0;
+ if (f->outputs[i]->type == AVMEDIA_TYPE_AUDIO &&
+ !(f->outputs[i]->in_samplerates &&
+ f->outputs[i]->in_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 {
+ av_freep(&a->formats);
+ 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.
+ * @return >=0 if all links formats lists could be queried and merged;
+ * AVERROR(EAGAIN) some progress was made in the queries or merging
+ * and a later call may succeed;
+ * AVERROR(EIO) (may be changed) plus a log message if no progress
+ * was made and the negotiation is stuck;
+ * a negative error code if some other error happened
+ */
+static int query_formats(AVFilterGraph *graph, AVClass *log_ctx)
+{
+ int i, j, ret;
+ int scaler_count = 0, resampler_count = 0;
+ int count_queried = 0; /* successful calls to query_formats() */
+ int count_merged = 0; /* successful merge of formats lists */
+ int count_already_merged = 0; /* lists already merged */
+ int count_delayed = 0; /* lists that need to be merged later */
+
+ for (i = 0; i < graph->nb_filters; i++) {
+ AVFilterContext *f = graph->filters[i];
+ if (formats_declared(f))
+ continue;
+ if (f->filter->query_formats)
+ ret = filter_query_formats(f);
+ else
+ ret = ff_default_query_formats(f);
+ if (ret < 0 && ret != AVERROR(EAGAIN))
+ return ret;
+ /* note: EAGAIN could indicate a partial success, not counted yet */
+ count_queried += ret >= 0;
+ }
+
+ /* go through and merge as many format lists as possible */
+ for (i = 0; i < graph->nb_filters; i++) {
+ AVFilterContext *filter = graph->filters[i];
+
+ for (j = 0; j < filter->nb_inputs; j++) {
+ AVFilterLink *link = filter->inputs[j];
+ int convert_needed = 0;
+
+ 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))
+ 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))
+ convert_needed = 1;
+ }
+
+#define MERGE_DISPATCH(field, statement) \
+ if (!(link->in_ ## field && link->out_ ## field)) { \
+ count_delayed++; \
+ } else if (link->in_ ## field == link->out_ ## field) { \
+ count_already_merged++; \
+ } else if (!convert_needed) { \
+ count_merged++; \
+ statement \
+ }
+
+ 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(formats,
+ if (!ff_merge_formats(link->in_formats, link->out_formats,
+ link->type))
+ convert_needed = 1;
+ )
+#undef MERGE_DISPATCH
+
+ if (convert_needed) {
+ AVFilterContext *convert;
+ AVFilter *filter;
+ AVFilterLink *inlink, *outlink;
+ char scale_args[256];
+ char inst_name[30];
+
+ /* couldn't merge format lists. auto-insert conversion filter */
+ switch (link->type) {
+ case AVMEDIA_TYPE_VIDEO:
+ if (!(filter = avfilter_get_by_name("scale"))) {
+ av_log(log_ctx, AV_LOG_ERROR, "'scale' filter "
+ "not present, cannot convert pixel formats.\n");
+ return AVERROR(EINVAL);
+ }
+
+ snprintf(inst_name, sizeof(inst_name), "auto-inserted scaler %d",
+ scaler_count++);
+
+ if ((ret = avfilter_graph_create_filter(&convert, filter,
+ inst_name, graph->scale_sws_opts, NULL,
+ graph)) < 0)
+ return ret;
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ if (!(filter = avfilter_get_by_name("aresample"))) {
+ av_log(log_ctx, AV_LOG_ERROR, "'aresample' filter "
+ "not present, cannot convert audio formats.\n");
+ return AVERROR(EINVAL);
+ }
+
+ snprintf(inst_name, sizeof(inst_name), "auto-inserted resampler %d",
+ resampler_count++);
+ scale_args[0] = '\0';
+ if (graph->aresample_swr_opts)
+ snprintf(scale_args, sizeof(scale_args), "%s",
+ graph->aresample_swr_opts);
+ if ((ret = avfilter_graph_create_filter(&convert, filter,
+ inst_name, graph->aresample_swr_opts,
+ NULL, graph)) < 0)
+ return ret;
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+
+ if ((ret = avfilter_insert_filter(link, convert, 0, 0)) < 0)
+ return ret;
+
+ if ((ret = filter_query_formats(convert)) < 0)
+ return ret;
+
+ 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);
+ 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);
+ }
+ 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) {
+ 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;
+ }
+ }
+ }
+ }
+
+ av_log(graph, AV_LOG_DEBUG, "query_formats: "
+ "%d queried, %d merged, %d already done, %d delayed\n",
+ count_queried, count_merged, count_already_merged, count_delayed);
+ if (count_delayed) {
+ AVBPrint bp;
+
+ /* if count_queried > 0, one filter at least did set its formats,
+ that will give additional information to its neighbour;
+ if count_merged > 0, one pair of formats lists at least was merged,
+ that will give additional information to all connected filters;
+ in both cases, progress was made and a new round must be done */
+ if (count_queried || count_merged)
+ return AVERROR(EAGAIN);
+ av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC);
+ for (i = 0; i < graph->nb_filters; i++)
+ if (!formats_declared(graph->filters[i]))
+ av_bprintf(&bp, "%s%s", bp.len ? ", " : "",
+ graph->filters[i]->name);
+ av_log(graph, AV_LOG_ERROR,
+ "The following filters could not choose their formats: %s\n"
+ "Consider inserting the (a)format filter near their input or "
+ "output.\n", bp.str);
+ return AVERROR(EIO);
+ }
+ return 0;
+}
+
+static int get_fmt_score(enum AVSampleFormat dst_fmt, enum AVSampleFormat src_fmt)
+{
+ int score = 0;
+
+ if (av_sample_fmt_is_planar(dst_fmt) != av_sample_fmt_is_planar(src_fmt))
+ score ++;
+
+ if (av_get_bytes_per_sample(dst_fmt) < av_get_bytes_per_sample(src_fmt)) {
+ score += 100 * (av_get_bytes_per_sample(src_fmt) - av_get_bytes_per_sample(dst_fmt));
+ }else
+ score += 10 * (av_get_bytes_per_sample(dst_fmt) - av_get_bytes_per_sample(src_fmt));
+
+ if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_S32 &&
+ av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_FLT)
+ score += 20;
+
+ if (av_get_packed_sample_fmt(dst_fmt) == AV_SAMPLE_FMT_FLT &&
+ av_get_packed_sample_fmt(src_fmt) == AV_SAMPLE_FMT_S32)
+ score += 2;
+
+ return score;
+}
+
+static enum AVSampleFormat find_best_sample_fmt_of_2(enum AVSampleFormat dst_fmt1, enum AVSampleFormat dst_fmt2,
+ enum AVSampleFormat src_fmt)
+{
+ int score1, score2;
+
+ score1 = get_fmt_score(dst_fmt1, src_fmt);
+ score2 = get_fmt_score(dst_fmt2, src_fmt);
+
+ return score1 < score2 ? dst_fmt1 : dst_fmt2;
+}
+
+static int pick_format(AVFilterLink *link, AVFilterLink *ref)
+{
+ if (!link || !link->in_formats)
+ return 0;
+
+ if (link->type == AVMEDIA_TYPE_VIDEO) {
+ if(ref && ref->type == AVMEDIA_TYPE_VIDEO){
+ 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; i<link->in_formats->nb_formats; i++) {
+ enum AVPixelFormat p = link->in_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(ref->format), has_alpha);
+ link->in_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; i<link->in_formats->nb_formats; i++) {
+ enum AVSampleFormat p = link->in_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(ref->format));
+ link->in_formats->formats[0] = best;
+ }
+ }
+
+ link->in_formats->nb_formats = 1;
+ link->format = link->in_formats->formats[0];
+
+ if (link->type == AVMEDIA_TYPE_AUDIO) {
+ if (!link->in_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];
+
+ if (link->in_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)
+ 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];
+ 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);
+
+ return 0;
+}
+
+#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) \
+ continue; \
+ fmt = link->out_ ## 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) \
+ continue; \
+ fmts = out_link->in_ ## list; \
+ \
+ if (!out_link->in_ ## list->nb) { \
+ add_format(&out_link->in_ ##list, fmt); \
+ ret = 1; \
+ break; \
+ } \
+ \
+ for (k = 0; k < out_link->in_ ## list->nb; k++) \
+ if (fmts->var[k] == fmt) { \
+ fmts->var[0] = fmt; \
+ fmts->nb = 1; \
+ ret = 1; \
+ break; \
+ } \
+ } \
+ } \
+} while (0)
+
+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);
+ REDUCE_FORMATS(int, AVFilterFormats, samplerates, formats,
+ 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)
+ continue;
+ fmt = inlink->out_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;
+ if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1)
+ continue;
+
+ if (fmts->all_layouts &&
+ (!FF_LAYOUT2COUNT(fmt) || fmts->all_counts)) {
+ /* Turn the infinite list into a singleton */
+ fmts->all_layouts = fmts->all_counts = 0;
+ ff_add_channel_layout(&outlink->in_channel_layouts, fmt);
+ break;
+ }
+
+ for (k = 0; k < outlink->in_channel_layouts->nb_channel_layouts; k++) {
+ if (fmts->channel_layouts[k] == fmt) {
+ fmts->channel_layouts[0] = fmt;
+ fmts->nb_channel_layouts = 1;
+ ret = 1;
+ break;
+ }
+ }
+ }
+ }
+
+ return ret;
+}
+
+static void reduce_formats(AVFilterGraph *graph)
+{
+ int i, reduced;
+
+ do {
+ reduced = 0;
+
+ for (i = 0; i < graph->nb_filters; i++)
+ reduced |= reduce_formats_on_filter(graph->filters[i]);
+ } while (reduced);
+}
+
+static void swap_samplerates_on_filter(AVFilterContext *filter)
+{
+ AVFilterLink *link = NULL;
+ int sample_rate;
+ int i, j;
+
+ for (i = 0; i < filter->nb_inputs; i++) {
+ link = filter->inputs[i];
+
+ if (link->type == AVMEDIA_TYPE_AUDIO &&
+ link->out_samplerates->nb_formats== 1)
+ break;
+ }
+ if (i == filter->nb_inputs)
+ return;
+
+ sample_rate = link->out_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)
+ continue;
+
+ for (j = 0; j < outlink->in_samplerates->nb_formats; j++) {
+ int diff = abs(sample_rate - outlink->in_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
+
+ if (diff < best_diff) {
+ best_diff = diff;
+ best_idx = j;
+ }
+ }
+ FFSWAP(int, outlink->in_samplerates->formats[0],
+ outlink->in_samplerates->formats[best_idx]);
+ }
+}
+
+static void swap_samplerates(AVFilterGraph *graph)
+{
+ int i;
+
+ for (i = 0; i < graph->nb_filters; i++)
+ swap_samplerates_on_filter(graph->filters[i]);
+}
+
+#define CH_CENTER_PAIR (AV_CH_FRONT_LEFT_OF_CENTER | AV_CH_FRONT_RIGHT_OF_CENTER)
+#define CH_FRONT_PAIR (AV_CH_FRONT_LEFT | AV_CH_FRONT_RIGHT)
+#define CH_STEREO_PAIR (AV_CH_STEREO_LEFT | AV_CH_STEREO_RIGHT)
+#define CH_WIDE_PAIR (AV_CH_WIDE_LEFT | AV_CH_WIDE_RIGHT)
+#define CH_SIDE_PAIR (AV_CH_SIDE_LEFT | AV_CH_SIDE_RIGHT)
+#define CH_DIRECT_PAIR (AV_CH_SURROUND_DIRECT_LEFT | AV_CH_SURROUND_DIRECT_RIGHT)
+#define CH_BACK_PAIR (AV_CH_BACK_LEFT | AV_CH_BACK_RIGHT)
+
+/* allowable substitutions for channel pairs when comparing layouts,
+ * ordered by priority for both values */
+static const uint64_t ch_subst[][2] = {
+ { CH_FRONT_PAIR, CH_CENTER_PAIR },
+ { CH_FRONT_PAIR, CH_WIDE_PAIR },
+ { CH_FRONT_PAIR, AV_CH_FRONT_CENTER },
+ { CH_CENTER_PAIR, CH_FRONT_PAIR },
+ { CH_CENTER_PAIR, CH_WIDE_PAIR },
+ { CH_CENTER_PAIR, AV_CH_FRONT_CENTER },
+ { CH_WIDE_PAIR, CH_FRONT_PAIR },
+ { CH_WIDE_PAIR, CH_CENTER_PAIR },
+ { CH_WIDE_PAIR, AV_CH_FRONT_CENTER },
+ { AV_CH_FRONT_CENTER, CH_FRONT_PAIR },
+ { AV_CH_FRONT_CENTER, CH_CENTER_PAIR },
+ { AV_CH_FRONT_CENTER, CH_WIDE_PAIR },
+ { CH_SIDE_PAIR, CH_DIRECT_PAIR },
+ { CH_SIDE_PAIR, CH_BACK_PAIR },
+ { CH_SIDE_PAIR, AV_CH_BACK_CENTER },
+ { CH_BACK_PAIR, CH_DIRECT_PAIR },
+ { CH_BACK_PAIR, CH_SIDE_PAIR },
+ { CH_BACK_PAIR, AV_CH_BACK_CENTER },
+ { AV_CH_BACK_CENTER, CH_BACK_PAIR },
+ { AV_CH_BACK_CENTER, CH_DIRECT_PAIR },
+ { AV_CH_BACK_CENTER, CH_SIDE_PAIR },
+};
+
+static void swap_channel_layouts_on_filter(AVFilterContext *filter)
+{
+ AVFilterLink *link = NULL;
+ int i, j, k;
+
+ for (i = 0; i < filter->nb_inputs; i++) {
+ link = filter->inputs[i];
+
+ if (link->type == AVMEDIA_TYPE_AUDIO &&
+ link->out_channel_layouts->nb_channel_layouts == 1)
+ break;
+ }
+ if (i == filter->nb_inputs)
+ return;
+
+ for (i = 0; i < filter->nb_outputs; i++) {
+ AVFilterLink *outlink = filter->outputs[i];
+ 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)
+ 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];
+ 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;
+ int matched_channels, extra_channels;
+ int score = 100000;
+
+ if (FF_LAYOUT2COUNT(in_chlayout) || FF_LAYOUT2COUNT(out_chlayout)) {
+ /* Compute score in case the input or output layout encodes
+ a channel count; in this case the score is not altered by
+ the computation afterwards, as in_chlayout and
+ out_chlayout have both been set to 0 */
+ if (FF_LAYOUT2COUNT(in_chlayout))
+ in_channels = FF_LAYOUT2COUNT(in_chlayout);
+ if (FF_LAYOUT2COUNT(out_chlayout))
+ out_channels = FF_LAYOUT2COUNT(out_chlayout);
+ score -= 10000 + FFABS(out_channels - in_channels) +
+ (in_channels > out_channels ? 10000 : 0);
+ in_chlayout = out_chlayout = 0;
+ /* Let the remaining computation run, even if the score
+ value is not altered */
+ }
+
+ /* channel substitution */
+ for (k = 0; k < FF_ARRAY_ELEMS(ch_subst); k++) {
+ uint64_t cmp0 = ch_subst[k][0];
+ uint64_t cmp1 = ch_subst[k][1];
+ if (( in_chlayout & cmp0) && (!(out_chlayout & cmp0)) &&
+ (out_chlayout & cmp1) && (!( in_chlayout & cmp1))) {
+ in_chlayout &= ~cmp0;
+ out_chlayout &= ~cmp1;
+ /* add score for channel match, minus a deduction for
+ having to do the substitution */
+ score += 10 * av_get_channel_layout_nb_channels(cmp1) - 2;
+ }
+ }
+
+ /* no penalty for LFE channel mismatch */
+ if ( (in_chlayout & AV_CH_LOW_FREQUENCY) &&
+ (out_chlayout & AV_CH_LOW_FREQUENCY))
+ score += 10;
+ in_chlayout &= ~AV_CH_LOW_FREQUENCY;
+ out_chlayout &= ~AV_CH_LOW_FREQUENCY;
+
+ matched_channels = av_get_channel_layout_nb_channels(in_chlayout &
+ out_chlayout);
+ extra_channels = av_get_channel_layout_nb_channels(out_chlayout &
+ (~in_chlayout));
+ score += 10 * matched_channels - 5 * extra_channels;
+
+ if (score > best_score ||
+ (count_diff < best_count_diff && score == best_score)) {
+ best_score = score;
+ best_idx = j;
+ best_count_diff = count_diff;
+ }
+ }
+ av_assert0(best_idx >= 0);
+ FFSWAP(uint64_t, outlink->in_channel_layouts->channel_layouts[0],
+ outlink->in_channel_layouts->channel_layouts[best_idx]);
+ }
+
+}
+
+static void swap_channel_layouts(AVFilterGraph *graph)
+{
+ int i;
+
+ for (i = 0; i < graph->nb_filters; i++)
+ swap_channel_layouts_on_filter(graph->filters[i]);
+}
+
+static void swap_sample_fmts_on_filter(AVFilterContext *filter)
+{
+ AVFilterLink *link = NULL;
+ int format, bps;
+ int i, j;
+
+ for (i = 0; i < filter->nb_inputs; i++) {
+ link = filter->inputs[i];
+
+ if (link->type == AVMEDIA_TYPE_AUDIO &&
+ link->out_formats->nb_formats == 1)
+ break;
+ }
+ if (i == filter->nb_inputs)
+ return;
+
+ format = link->out_formats->formats[0];
+ bps = av_get_bytes_per_sample(format);
+
+ for (i = 0; i < filter->nb_outputs; i++) {
+ AVFilterLink *outlink = filter->outputs[i];
+ int best_idx = -1, best_score = INT_MIN;
+
+ if (outlink->type != AVMEDIA_TYPE_AUDIO ||
+ outlink->in_formats->nb_formats < 2)
+ continue;
+
+ for (j = 0; j < outlink->in_formats->nb_formats; j++) {
+ int out_format = outlink->in_formats->formats[j];
+ int out_bps = av_get_bytes_per_sample(out_format);
+ int score;
+
+ if (av_get_packed_sample_fmt(out_format) == format ||
+ av_get_planar_sample_fmt(out_format) == format) {
+ best_idx = j;
+ break;
+ }
+
+ /* for s32 and float prefer double to prevent loss of information */
+ if (bps == 4 && out_bps == 8) {
+ best_idx = j;
+ break;
+ }
+
+ /* prefer closest higher or equal bps */
+ score = -abs(out_bps - bps);
+ if (out_bps >= bps)
+ score += INT_MAX/2;
+
+ if (score > best_score) {
+ best_score = score;
+ best_idx = j;
+ }
+ }
+ av_assert0(best_idx >= 0);
+ FFSWAP(int, outlink->in_formats->formats[0],
+ outlink->in_formats->formats[best_idx]);
+ }
+}
+
+static void swap_sample_fmts(AVFilterGraph *graph)
+{
+ int i;
+
+ for (i = 0; i < graph->nb_filters; i++)
+ swap_sample_fmts_on_filter(graph->filters[i]);
+
+}
+
+static int pick_formats(AVFilterGraph *graph)
+{
+ int i, j, ret;
+ int change;
+
+ do{
+ change = 0;
+ for (i = 0; i < graph->nb_filters; i++) {
+ 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 ((ret = pick_format(filter->inputs[j], NULL)) < 0)
+ return ret;
+ change = 1;
+ }
+ }
+ }
+ 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 ((ret = pick_format(filter->outputs[j], NULL)) < 0)
+ return ret;
+ change = 1;
+ }
+ }
+ }
+ 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 ((ret = pick_format(filter->outputs[j], filter->inputs[0])) < 0)
+ return ret;
+ change = 1;
+ }
+ }
+ }
+ }
+ }while(change);
+
+ for (i = 0; i < graph->nb_filters; i++) {
+ AVFilterContext *filter = graph->filters[i];
+
+ for (j = 0; j < filter->nb_inputs; j++)
+ if ((ret = pick_format(filter->inputs[j], NULL)) < 0)
+ return ret;
+ for (j = 0; j < filter->nb_outputs; j++)
+ if ((ret = pick_format(filter->outputs[j], NULL)) < 0)
+ return ret;
+ }
+ return 0;
+}
+
+/**
+ * Configure the formats of all the links in the graph.
+ */
+static int graph_config_formats(AVFilterGraph *graph, AVClass *log_ctx)
+{
+ int ret;
+
+ /* find supported formats from sub-filters, and merge along links */
+ while ((ret = query_formats(graph, log_ctx)) == AVERROR(EAGAIN))
+ av_log(graph, AV_LOG_DEBUG, "query_formats not finished\n");
+ if (ret < 0)
+ return ret;
+
+ /* Once everything is merged, it's possible that we'll still have
+ * multiple valid media format choices. We try to minimize the amount
+ * of format conversion inside filters */
+ reduce_formats(graph);
+
+ /* for audio filters, ensure the best format, sample rate and channel layout
+ * is selected */
+ swap_sample_fmts(graph);
+ swap_samplerates(graph);
+ swap_channel_layouts(graph);
+
+ if ((ret = pick_formats(graph)) < 0)
+ return ret;
+
+ return 0;
+}
+
+static int graph_config_pointers(AVFilterGraph *graph,
+ AVClass *log_ctx)
+{
+ unsigned i, j;
+ int sink_links_count = 0, n = 0;
+ AVFilterContext *f;
+ AVFilterLink **sinks;
+
+ for (i = 0; i < graph->nb_filters; i++) {
+ f = graph->filters[i];
+ for (j = 0; j < f->nb_inputs; j++) {
+ f->inputs[j]->graph = graph;
+ f->inputs[j]->age_index = -1;
+ }
+ for (j = 0; j < f->nb_outputs; j++) {
+ f->outputs[j]->graph = graph;
+ f->outputs[j]->age_index= -1;
+ }
+ if (!f->nb_outputs) {
+ if (f->nb_inputs > INT_MAX - sink_links_count)
+ return AVERROR(EINVAL);
+ sink_links_count += f->nb_inputs;
+ }
+ }
+ sinks = av_calloc(sink_links_count, sizeof(*sinks));
+ if (!sinks)
+ return AVERROR(ENOMEM);
+ for (i = 0; i < graph->nb_filters; i++) {
+ f = graph->filters[i];
+ if (!f->nb_outputs) {
+ for (j = 0; j < f->nb_inputs; j++) {
+ sinks[n] = f->inputs[j];
+ f->inputs[j]->age_index = n++;
+ }
+ }
+ }
+ av_assert0(n == sink_links_count);
+ graph->sink_links = sinks;
+ graph->sink_links_count = sink_links_count;
+ 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;
+ 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-inserted 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)))
+ return ret;
+ if ((ret = graph_config_pointers(graphctx, log_ctx)))
+ return ret;
+
+ return 0;
+}
+
+int avfilter_graph_send_command(AVFilterGraph *graph, const char *target, const char *cmd, const char *arg, char *res, int res_len, int flags)
+{
+ int i, r = AVERROR(ENOSYS);
+
+ if (!graph)
+ return r;
+
+ if ((flags & AVFILTER_CMD_FLAG_ONE) && !(flags & AVFILTER_CMD_FLAG_FAST)) {
+ r = avfilter_graph_send_command(graph, target, cmd, arg, res, res_len, flags | AVFILTER_CMD_FLAG_FAST);
+ if (r != AVERROR(ENOSYS))
+ return r;
+ }
+
+ if (res_len && res)
+ res[0] = 0;
+
+ for (i = 0; i < graph->nb_filters; i++) {
+ AVFilterContext *filter = graph->filters[i];
+ if (!strcmp(target, "all") || (filter->name && !strcmp(target, filter->name)) || !strcmp(target, filter->filter->name)) {
+ r = avfilter_process_command(filter, cmd, arg, res, res_len, flags);
+ if (r != AVERROR(ENOSYS)) {
+ if ((flags & AVFILTER_CMD_FLAG_ONE) || r < 0)
+ return r;
+ }
+ }
+ }
+
+ return r;
+}
+
+int avfilter_graph_queue_command(AVFilterGraph *graph, const char *target, const char *command, const char *arg, int flags, double ts)
+{
+ int i;
+
+ if(!graph)
+ return 0;
+
+ for (i = 0; i < graph->nb_filters; i++) {
+ AVFilterContext *filter = graph->filters[i];
+ if(filter && (!strcmp(target, "all") || !strcmp(target, filter->name) || !strcmp(target, filter->filter->name))){
+ AVFilterCommand **queue = &filter->command_queue, *next;
+ while (*queue && (*queue)->time <= ts)
+ queue = &(*queue)->next;
+ next = *queue;
+ *queue = av_mallocz(sizeof(AVFilterCommand));
+ (*queue)->command = av_strdup(command);
+ (*queue)->arg = av_strdup(arg);
+ (*queue)->time = ts;
+ (*queue)->flags = flags;
+ (*queue)->next = next;
+ if(flags & AVFILTER_CMD_FLAG_ONE)
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+static void heap_bubble_up(AVFilterGraph *graph,
+ AVFilterLink *link, int index)
+{
+ AVFilterLink **links = graph->sink_links;
+
+ av_assert0(index >= 0);
+
+ while (index) {
+ int parent = (index - 1) >> 1;
+ if (links[parent]->current_pts >= link->current_pts)
+ break;
+ links[index] = links[parent];
+ links[index]->age_index = index;
+ index = parent;
+ }
+ links[index] = link;
+ link->age_index = index;
+}
+
+static void heap_bubble_down(AVFilterGraph *graph,
+ AVFilterLink *link, int index)
+{
+ AVFilterLink **links = graph->sink_links;
+
+ av_assert0(index >= 0);
+
+ while (1) {
+ int child = 2 * index + 1;
+ if (child >= graph->sink_links_count)
+ break;
+ if (child + 1 < graph->sink_links_count &&
+ links[child + 1]->current_pts < links[child]->current_pts)
+ child++;
+ if (link->current_pts < links[child]->current_pts)
+ break;
+ links[index] = links[child];
+ links[index]->age_index = index;
+ index = child;
+ }
+ links[index] = link;
+ link->age_index = index;
+}
+
+void ff_avfilter_graph_update_heap(AVFilterGraph *graph, AVFilterLink *link)
+{
+ heap_bubble_up (graph, link, link->age_index);
+ heap_bubble_down(graph, link, link->age_index);
+}
+
+
+int avfilter_graph_request_oldest(AVFilterGraph *graph)
+{
+ while (graph->sink_links_count) {
+ AVFilterLink *oldest = graph->sink_links[0];
+ int r = ff_request_frame(oldest);
+ if (r != AVERROR_EOF)
+ return r;
+ av_log(oldest->dst, AV_LOG_DEBUG, "EOF on sink link %s:%s.\n",
+ oldest->dst ? oldest->dst->name : "unknown",
+ oldest->dstpad ? oldest->dstpad->name : "unknown");
+ /* EOF: remove the link from the heap */
+ if (oldest->age_index < --graph->sink_links_count)
+ heap_bubble_down(graph, graph->sink_links[graph->sink_links_count],
+ oldest->age_index);
+ oldest->age_index = -1;
+ }
+ return AVERROR_EOF;
+}
diff --git a/ffmpeg-2-8-11/libavfilter/avfiltergraph.h b/ffmpeg-2-8-12/libavfilter/avfiltergraph.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/avfiltergraph.h
rename to ffmpeg-2-8-12/libavfilter/avfiltergraph.h
diff --git a/ffmpeg-2-8-11/libavfilter/avfilterres.rc b/ffmpeg-2-8-12/libavfilter/avfilterres.rc
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/avfilterres.rc
rename to ffmpeg-2-8-12/libavfilter/avfilterres.rc
diff --git a/ffmpeg-2-8-11/libavfilter/bbox.c b/ffmpeg-2-8-12/libavfilter/bbox.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/bbox.c
rename to ffmpeg-2-8-12/libavfilter/bbox.c
diff --git a/ffmpeg-2-8-11/libavfilter/bbox.h b/ffmpeg-2-8-12/libavfilter/bbox.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/bbox.h
rename to ffmpeg-2-8-12/libavfilter/bbox.h
diff --git a/ffmpeg-2-8-11/libavfilter/buffer.c b/ffmpeg-2-8-12/libavfilter/buffer.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/buffer.c
rename to ffmpeg-2-8-12/libavfilter/buffer.c
diff --git a/ffmpeg-2-8-11/libavfilter/bufferqueue.h b/ffmpeg-2-8-12/libavfilter/bufferqueue.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/bufferqueue.h
rename to ffmpeg-2-8-12/libavfilter/bufferqueue.h
diff --git a/ffmpeg-2-8-11/libavfilter/buffersink.c b/ffmpeg-2-8-12/libavfilter/buffersink.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/buffersink.c
rename to ffmpeg-2-8-12/libavfilter/buffersink.c
diff --git a/ffmpeg-2-8-11/libavfilter/buffersink.h b/ffmpeg-2-8-12/libavfilter/buffersink.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/buffersink.h
rename to ffmpeg-2-8-12/libavfilter/buffersink.h
diff --git a/ffmpeg-2-8-11/libavfilter/buffersrc.c b/ffmpeg-2-8-12/libavfilter/buffersrc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/buffersrc.c
rename to ffmpeg-2-8-12/libavfilter/buffersrc.c
diff --git a/ffmpeg-2-8-11/libavfilter/buffersrc.h b/ffmpeg-2-8-12/libavfilter/buffersrc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/buffersrc.h
rename to ffmpeg-2-8-12/libavfilter/buffersrc.h
diff --git a/ffmpeg-2-8-11/libavfilter/deshake.h b/ffmpeg-2-8-12/libavfilter/deshake.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/deshake.h
rename to ffmpeg-2-8-12/libavfilter/deshake.h
diff --git a/ffmpeg-2-8-11/libavfilter/deshake_opencl.c b/ffmpeg-2-8-12/libavfilter/deshake_opencl.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/deshake_opencl.c
rename to ffmpeg-2-8-12/libavfilter/deshake_opencl.c
diff --git a/ffmpeg-2-8-11/libavfilter/deshake_opencl.h b/ffmpeg-2-8-12/libavfilter/deshake_opencl.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/deshake_opencl.h
rename to ffmpeg-2-8-12/libavfilter/deshake_opencl.h
diff --git a/ffmpeg-2-8-11/libavfilter/deshake_opencl_kernel.h b/ffmpeg-2-8-12/libavfilter/deshake_opencl_kernel.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/deshake_opencl_kernel.h
rename to ffmpeg-2-8-12/libavfilter/deshake_opencl_kernel.h
diff --git a/ffmpeg-2-8-11/libavfilter/drawutils.c b/ffmpeg-2-8-12/libavfilter/drawutils.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/drawutils.c
rename to ffmpeg-2-8-12/libavfilter/drawutils.c
diff --git a/ffmpeg-2-8-11/libavfilter/drawutils.h b/ffmpeg-2-8-12/libavfilter/drawutils.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/drawutils.h
rename to ffmpeg-2-8-12/libavfilter/drawutils.h
diff --git a/ffmpeg-2-8-11/libavfilter/dualinput.c b/ffmpeg-2-8-12/libavfilter/dualinput.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/dualinput.c
rename to ffmpeg-2-8-12/libavfilter/dualinput.c
diff --git a/ffmpeg-2-8-11/libavfilter/dualinput.h b/ffmpeg-2-8-12/libavfilter/dualinput.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/dualinput.h
rename to ffmpeg-2-8-12/libavfilter/dualinput.h
diff --git a/ffmpeg-2-8-11/libavfilter/f_drawgraph.c b/ffmpeg-2-8-12/libavfilter/f_drawgraph.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/f_drawgraph.c
rename to ffmpeg-2-8-12/libavfilter/f_drawgraph.c
diff --git a/ffmpeg-2-8-11/libavfilter/f_ebur128.c b/ffmpeg-2-8-12/libavfilter/f_ebur128.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/f_ebur128.c
rename to ffmpeg-2-8-12/libavfilter/f_ebur128.c
diff --git a/ffmpeg-2-8-11/libavfilter/f_interleave.c b/ffmpeg-2-8-12/libavfilter/f_interleave.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/f_interleave.c
rename to ffmpeg-2-8-12/libavfilter/f_interleave.c
diff --git a/ffmpeg-2-8-11/libavfilter/f_perms.c b/ffmpeg-2-8-12/libavfilter/f_perms.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/f_perms.c
rename to ffmpeg-2-8-12/libavfilter/f_perms.c
diff --git a/ffmpeg-2-8-11/libavfilter/f_reverse.c b/ffmpeg-2-8-12/libavfilter/f_reverse.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/f_reverse.c
rename to ffmpeg-2-8-12/libavfilter/f_reverse.c
diff --git a/ffmpeg-2-8-11/libavfilter/f_select.c b/ffmpeg-2-8-12/libavfilter/f_select.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/f_select.c
rename to ffmpeg-2-8-12/libavfilter/f_select.c
diff --git a/ffmpeg-2-8-11/libavfilter/f_sendcmd.c b/ffmpeg-2-8-12/libavfilter/f_sendcmd.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/f_sendcmd.c
rename to ffmpeg-2-8-12/libavfilter/f_sendcmd.c
diff --git a/ffmpeg-2-8-11/libavfilter/f_zmq.c b/ffmpeg-2-8-12/libavfilter/f_zmq.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/f_zmq.c
rename to ffmpeg-2-8-12/libavfilter/f_zmq.c
diff --git a/ffmpeg-2-8-11/libavfilter/fifo.c b/ffmpeg-2-8-12/libavfilter/fifo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/fifo.c
rename to ffmpeg-2-8-12/libavfilter/fifo.c
diff --git a/ffmpeg-2-8-11/libavfilter/filtfmts.c b/ffmpeg-2-8-12/libavfilter/filtfmts.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/filtfmts.c
rename to ffmpeg-2-8-12/libavfilter/filtfmts.c
diff --git a/ffmpeg-2-8-11/libavfilter/formats.c b/ffmpeg-2-8-12/libavfilter/formats.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/formats.c
rename to ffmpeg-2-8-12/libavfilter/formats.c
diff --git a/ffmpeg-2-8-11/libavfilter/formats.h b/ffmpeg-2-8-12/libavfilter/formats.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/formats.h
rename to ffmpeg-2-8-12/libavfilter/formats.h
diff --git a/ffmpeg-2-8-11/libavfilter/framesync.c b/ffmpeg-2-8-12/libavfilter/framesync.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/framesync.c
rename to ffmpeg-2-8-12/libavfilter/framesync.c
diff --git a/ffmpeg-2-8-11/libavfilter/framesync.h b/ffmpeg-2-8-12/libavfilter/framesync.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/framesync.h
rename to ffmpeg-2-8-12/libavfilter/framesync.h
diff --git a/ffmpeg-2-8-11/libavfilter/generate_wave_table.c b/ffmpeg-2-8-12/libavfilter/generate_wave_table.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/generate_wave_table.c
rename to ffmpeg-2-8-12/libavfilter/generate_wave_table.c
diff --git a/ffmpeg-2-8-11/libavfilter/generate_wave_table.h b/ffmpeg-2-8-12/libavfilter/generate_wave_table.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/generate_wave_table.h
rename to ffmpeg-2-8-12/libavfilter/generate_wave_table.h
diff --git a/ffmpeg-2-8-11/libavfilter/gradfun.h b/ffmpeg-2-8-12/libavfilter/gradfun.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/gradfun.h
rename to ffmpeg-2-8-12/libavfilter/gradfun.h
diff --git a/ffmpeg-2-8-11/libavfilter/graphdump.c b/ffmpeg-2-8-12/libavfilter/graphdump.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/graphdump.c
rename to ffmpeg-2-8-12/libavfilter/graphdump.c
diff --git a/ffmpeg-2-8-11/libavfilter/graphparser.c b/ffmpeg-2-8-12/libavfilter/graphparser.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/graphparser.c
rename to ffmpeg-2-8-12/libavfilter/graphparser.c
diff --git a/ffmpeg-2-8-11/libavfilter/interlace.h b/ffmpeg-2-8-12/libavfilter/interlace.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/interlace.h
rename to ffmpeg-2-8-12/libavfilter/interlace.h
diff --git a/ffmpeg-2-8-11/libavfilter/internal.h b/ffmpeg-2-8-12/libavfilter/internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/internal.h
rename to ffmpeg-2-8-12/libavfilter/internal.h
diff --git a/ffmpeg-2-8-11/libavfilter/lavfutils.c b/ffmpeg-2-8-12/libavfilter/lavfutils.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/lavfutils.c
rename to ffmpeg-2-8-12/libavfilter/lavfutils.c
diff --git a/ffmpeg-2-8-11/libavfilter/lavfutils.h b/ffmpeg-2-8-12/libavfilter/lavfutils.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/lavfutils.h
rename to ffmpeg-2-8-12/libavfilter/lavfutils.h
diff --git a/ffmpeg-2-8-11/libavfilter/libavfilter.v b/ffmpeg-2-8-12/libavfilter/libavfilter.v
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/libavfilter.v
rename to ffmpeg-2-8-12/libavfilter/libavfilter.v
diff --git a/ffmpeg-2-8-11/libavfilter/log2_tab.c b/ffmpeg-2-8-12/libavfilter/log2_tab.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/log2_tab.c
rename to ffmpeg-2-8-12/libavfilter/log2_tab.c
diff --git a/ffmpeg-2-8-11/libavfilter/lswsutils.c b/ffmpeg-2-8-12/libavfilter/lswsutils.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/lswsutils.c
rename to ffmpeg-2-8-12/libavfilter/lswsutils.c
diff --git a/ffmpeg-2-8-11/libavfilter/lswsutils.h b/ffmpeg-2-8-12/libavfilter/lswsutils.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/lswsutils.h
rename to ffmpeg-2-8-12/libavfilter/lswsutils.h
diff --git a/ffmpeg-2-8-11/libavfilter/opencl_allkernels.c b/ffmpeg-2-8-12/libavfilter/opencl_allkernels.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/opencl_allkernels.c
rename to ffmpeg-2-8-12/libavfilter/opencl_allkernels.c
diff --git a/ffmpeg-2-8-11/libavfilter/opencl_allkernels.h b/ffmpeg-2-8-12/libavfilter/opencl_allkernels.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/opencl_allkernels.h
rename to ffmpeg-2-8-12/libavfilter/opencl_allkernels.h
diff --git a/ffmpeg-2-8-11/libavfilter/psnr.h b/ffmpeg-2-8-12/libavfilter/psnr.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/psnr.h
rename to ffmpeg-2-8-12/libavfilter/psnr.h
diff --git a/ffmpeg-2-8-11/libavfilter/pthread.c b/ffmpeg-2-8-12/libavfilter/pthread.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/pthread.c
rename to ffmpeg-2-8-12/libavfilter/pthread.c
diff --git a/ffmpeg-2-8-11/libavfilter/removegrain.h b/ffmpeg-2-8-12/libavfilter/removegrain.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/removegrain.h
rename to ffmpeg-2-8-12/libavfilter/removegrain.h
diff --git a/ffmpeg-2-8-11/libavfilter/setpts.c b/ffmpeg-2-8-12/libavfilter/setpts.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/setpts.c
rename to ffmpeg-2-8-12/libavfilter/setpts.c
diff --git a/ffmpeg-2-8-11/libavfilter/settb.c b/ffmpeg-2-8-12/libavfilter/settb.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/settb.c
rename to ffmpeg-2-8-12/libavfilter/settb.c
diff --git a/ffmpeg-2-8-11/libavfilter/split.c b/ffmpeg-2-8-12/libavfilter/split.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/split.c
rename to ffmpeg-2-8-12/libavfilter/split.c
diff --git a/ffmpeg-2-8-11/libavfilter/src_movie.c b/ffmpeg-2-8-12/libavfilter/src_movie.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/src_movie.c
rename to ffmpeg-2-8-12/libavfilter/src_movie.c
diff --git a/ffmpeg-2-8-11/libavfilter/ssim.h b/ffmpeg-2-8-12/libavfilter/ssim.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/ssim.h
rename to ffmpeg-2-8-12/libavfilter/ssim.h
diff --git a/ffmpeg-2-8-11/libavfilter/thread.h b/ffmpeg-2-8-12/libavfilter/thread.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/thread.h
rename to ffmpeg-2-8-12/libavfilter/thread.h
diff --git a/ffmpeg-2-8-11/libavfilter/tinterlace.h b/ffmpeg-2-8-12/libavfilter/tinterlace.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/tinterlace.h
rename to ffmpeg-2-8-12/libavfilter/tinterlace.h
diff --git a/ffmpeg-2-8-11/libavfilter/transform.c b/ffmpeg-2-8-12/libavfilter/transform.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/transform.c
rename to ffmpeg-2-8-12/libavfilter/transform.c
diff --git a/ffmpeg-2-8-11/libavfilter/transform.h b/ffmpeg-2-8-12/libavfilter/transform.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/transform.h
rename to ffmpeg-2-8-12/libavfilter/transform.h
diff --git a/ffmpeg-2-8-11/libavfilter/trim.c b/ffmpeg-2-8-12/libavfilter/trim.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/trim.c
rename to ffmpeg-2-8-12/libavfilter/trim.c
diff --git a/ffmpeg-2-8-11/libavfilter/unsharp.h b/ffmpeg-2-8-12/libavfilter/unsharp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/unsharp.h
rename to ffmpeg-2-8-12/libavfilter/unsharp.h
diff --git a/ffmpeg-2-8-11/libavfilter/unsharp_opencl.c b/ffmpeg-2-8-12/libavfilter/unsharp_opencl.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/unsharp_opencl.c
rename to ffmpeg-2-8-12/libavfilter/unsharp_opencl.c
diff --git a/ffmpeg-2-8-11/libavfilter/unsharp_opencl.h b/ffmpeg-2-8-12/libavfilter/unsharp_opencl.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/unsharp_opencl.h
rename to ffmpeg-2-8-12/libavfilter/unsharp_opencl.h
diff --git a/ffmpeg-2-8-11/libavfilter/unsharp_opencl_kernel.h b/ffmpeg-2-8-12/libavfilter/unsharp_opencl_kernel.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/unsharp_opencl_kernel.h
rename to ffmpeg-2-8-12/libavfilter/unsharp_opencl_kernel.h
diff --git a/ffmpeg-2-8-11/libavfilter/version.h b/ffmpeg-2-8-12/libavfilter/version.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/version.h
rename to ffmpeg-2-8-12/libavfilter/version.h
diff --git a/ffmpeg-2-8-11/libavfilter/vf_alphamerge.c b/ffmpeg-2-8-12/libavfilter/vf_alphamerge.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_alphamerge.c
rename to ffmpeg-2-8-12/libavfilter/vf_alphamerge.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_aspect.c b/ffmpeg-2-8-12/libavfilter/vf_aspect.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_aspect.c
rename to ffmpeg-2-8-12/libavfilter/vf_aspect.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_atadenoise.c b/ffmpeg-2-8-12/libavfilter/vf_atadenoise.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_atadenoise.c
rename to ffmpeg-2-8-12/libavfilter/vf_atadenoise.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_bbox.c b/ffmpeg-2-8-12/libavfilter/vf_bbox.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_bbox.c
rename to ffmpeg-2-8-12/libavfilter/vf_bbox.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_blackdetect.c b/ffmpeg-2-8-12/libavfilter/vf_blackdetect.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_blackdetect.c
rename to ffmpeg-2-8-12/libavfilter/vf_blackdetect.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_blackframe.c b/ffmpeg-2-8-12/libavfilter/vf_blackframe.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_blackframe.c
rename to ffmpeg-2-8-12/libavfilter/vf_blackframe.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_blend.c b/ffmpeg-2-8-12/libavfilter/vf_blend.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_blend.c
rename to ffmpeg-2-8-12/libavfilter/vf_blend.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_boxblur.c b/ffmpeg-2-8-12/libavfilter/vf_boxblur.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_boxblur.c
rename to ffmpeg-2-8-12/libavfilter/vf_boxblur.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_codecview.c b/ffmpeg-2-8-12/libavfilter/vf_codecview.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_codecview.c
rename to ffmpeg-2-8-12/libavfilter/vf_codecview.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_colorbalance.c b/ffmpeg-2-8-12/libavfilter/vf_colorbalance.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_colorbalance.c
rename to ffmpeg-2-8-12/libavfilter/vf_colorbalance.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_colorchannelmixer.c b/ffmpeg-2-8-12/libavfilter/vf_colorchannelmixer.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_colorchannelmixer.c
rename to ffmpeg-2-8-12/libavfilter/vf_colorchannelmixer.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_colorkey.c b/ffmpeg-2-8-12/libavfilter/vf_colorkey.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_colorkey.c
rename to ffmpeg-2-8-12/libavfilter/vf_colorkey.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_colorlevels.c b/ffmpeg-2-8-12/libavfilter/vf_colorlevels.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_colorlevels.c
rename to ffmpeg-2-8-12/libavfilter/vf_colorlevels.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_colormatrix.c b/ffmpeg-2-8-12/libavfilter/vf_colormatrix.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_colormatrix.c
rename to ffmpeg-2-8-12/libavfilter/vf_colormatrix.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_copy.c b/ffmpeg-2-8-12/libavfilter/vf_copy.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_copy.c
rename to ffmpeg-2-8-12/libavfilter/vf_copy.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_cover_rect.c b/ffmpeg-2-8-12/libavfilter/vf_cover_rect.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_cover_rect.c
rename to ffmpeg-2-8-12/libavfilter/vf_cover_rect.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_crop.c b/ffmpeg-2-8-12/libavfilter/vf_crop.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_crop.c
rename to ffmpeg-2-8-12/libavfilter/vf_crop.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_cropdetect.c b/ffmpeg-2-8-12/libavfilter/vf_cropdetect.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_cropdetect.c
rename to ffmpeg-2-8-12/libavfilter/vf_cropdetect.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_curves.c b/ffmpeg-2-8-12/libavfilter/vf_curves.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_curves.c
rename to ffmpeg-2-8-12/libavfilter/vf_curves.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_dctdnoiz.c b/ffmpeg-2-8-12/libavfilter/vf_dctdnoiz.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_dctdnoiz.c
rename to ffmpeg-2-8-12/libavfilter/vf_dctdnoiz.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_deband.c b/ffmpeg-2-8-12/libavfilter/vf_deband.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_deband.c
rename to ffmpeg-2-8-12/libavfilter/vf_deband.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_decimate.c b/ffmpeg-2-8-12/libavfilter/vf_decimate.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_decimate.c
rename to ffmpeg-2-8-12/libavfilter/vf_decimate.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_dejudder.c b/ffmpeg-2-8-12/libavfilter/vf_dejudder.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_dejudder.c
rename to ffmpeg-2-8-12/libavfilter/vf_dejudder.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_delogo.c b/ffmpeg-2-8-12/libavfilter/vf_delogo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_delogo.c
rename to ffmpeg-2-8-12/libavfilter/vf_delogo.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_deshake.c b/ffmpeg-2-8-12/libavfilter/vf_deshake.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_deshake.c
rename to ffmpeg-2-8-12/libavfilter/vf_deshake.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_detelecine.c b/ffmpeg-2-8-12/libavfilter/vf_detelecine.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_detelecine.c
rename to ffmpeg-2-8-12/libavfilter/vf_detelecine.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_drawbox.c b/ffmpeg-2-8-12/libavfilter/vf_drawbox.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_drawbox.c
rename to ffmpeg-2-8-12/libavfilter/vf_drawbox.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_drawtext.c b/ffmpeg-2-8-12/libavfilter/vf_drawtext.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_drawtext.c
rename to ffmpeg-2-8-12/libavfilter/vf_drawtext.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_edgedetect.c b/ffmpeg-2-8-12/libavfilter/vf_edgedetect.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_edgedetect.c
rename to ffmpeg-2-8-12/libavfilter/vf_edgedetect.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_elbg.c b/ffmpeg-2-8-12/libavfilter/vf_elbg.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_elbg.c
rename to ffmpeg-2-8-12/libavfilter/vf_elbg.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_eq.c b/ffmpeg-2-8-12/libavfilter/vf_eq.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_eq.c
rename to ffmpeg-2-8-12/libavfilter/vf_eq.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_eq.h b/ffmpeg-2-8-12/libavfilter/vf_eq.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_eq.h
rename to ffmpeg-2-8-12/libavfilter/vf_eq.h
diff --git a/ffmpeg-2-8-11/libavfilter/vf_extractplanes.c b/ffmpeg-2-8-12/libavfilter/vf_extractplanes.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_extractplanes.c
rename to ffmpeg-2-8-12/libavfilter/vf_extractplanes.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_fade.c b/ffmpeg-2-8-12/libavfilter/vf_fade.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_fade.c
rename to ffmpeg-2-8-12/libavfilter/vf_fade.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_fftfilt.c b/ffmpeg-2-8-12/libavfilter/vf_fftfilt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_fftfilt.c
rename to ffmpeg-2-8-12/libavfilter/vf_fftfilt.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_field.c b/ffmpeg-2-8-12/libavfilter/vf_field.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_field.c
rename to ffmpeg-2-8-12/libavfilter/vf_field.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_fieldmatch.c b/ffmpeg-2-8-12/libavfilter/vf_fieldmatch.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_fieldmatch.c
rename to ffmpeg-2-8-12/libavfilter/vf_fieldmatch.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_fieldorder.c b/ffmpeg-2-8-12/libavfilter/vf_fieldorder.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_fieldorder.c
rename to ffmpeg-2-8-12/libavfilter/vf_fieldorder.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_find_rect.c b/ffmpeg-2-8-12/libavfilter/vf_find_rect.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_find_rect.c
rename to ffmpeg-2-8-12/libavfilter/vf_find_rect.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_format.c b/ffmpeg-2-8-12/libavfilter/vf_format.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_format.c
rename to ffmpeg-2-8-12/libavfilter/vf_format.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_fps.c b/ffmpeg-2-8-12/libavfilter/vf_fps.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_fps.c
rename to ffmpeg-2-8-12/libavfilter/vf_fps.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_framepack.c b/ffmpeg-2-8-12/libavfilter/vf_framepack.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_framepack.c
rename to ffmpeg-2-8-12/libavfilter/vf_framepack.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_framerate.c b/ffmpeg-2-8-12/libavfilter/vf_framerate.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_framerate.c
rename to ffmpeg-2-8-12/libavfilter/vf_framerate.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_framestep.c b/ffmpeg-2-8-12/libavfilter/vf_framestep.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_framestep.c
rename to ffmpeg-2-8-12/libavfilter/vf_framestep.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_frei0r.c b/ffmpeg-2-8-12/libavfilter/vf_frei0r.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_frei0r.c
rename to ffmpeg-2-8-12/libavfilter/vf_frei0r.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_fspp.c b/ffmpeg-2-8-12/libavfilter/vf_fspp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_fspp.c
rename to ffmpeg-2-8-12/libavfilter/vf_fspp.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_fspp.h b/ffmpeg-2-8-12/libavfilter/vf_fspp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_fspp.h
rename to ffmpeg-2-8-12/libavfilter/vf_fspp.h
diff --git a/ffmpeg-2-8-11/libavfilter/vf_geq.c b/ffmpeg-2-8-12/libavfilter/vf_geq.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_geq.c
rename to ffmpeg-2-8-12/libavfilter/vf_geq.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_gradfun.c b/ffmpeg-2-8-12/libavfilter/vf_gradfun.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_gradfun.c
rename to ffmpeg-2-8-12/libavfilter/vf_gradfun.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_hflip.c b/ffmpeg-2-8-12/libavfilter/vf_hflip.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_hflip.c
rename to ffmpeg-2-8-12/libavfilter/vf_hflip.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_histeq.c b/ffmpeg-2-8-12/libavfilter/vf_histeq.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_histeq.c
rename to ffmpeg-2-8-12/libavfilter/vf_histeq.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_histogram.c b/ffmpeg-2-8-12/libavfilter/vf_histogram.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_histogram.c
rename to ffmpeg-2-8-12/libavfilter/vf_histogram.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_hqdn3d.c b/ffmpeg-2-8-12/libavfilter/vf_hqdn3d.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_hqdn3d.c
rename to ffmpeg-2-8-12/libavfilter/vf_hqdn3d.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_hqdn3d.h b/ffmpeg-2-8-12/libavfilter/vf_hqdn3d.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_hqdn3d.h
rename to ffmpeg-2-8-12/libavfilter/vf_hqdn3d.h
diff --git a/ffmpeg-2-8-11/libavfilter/vf_hqx.c b/ffmpeg-2-8-12/libavfilter/vf_hqx.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_hqx.c
rename to ffmpeg-2-8-12/libavfilter/vf_hqx.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_hue.c b/ffmpeg-2-8-12/libavfilter/vf_hue.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_hue.c
rename to ffmpeg-2-8-12/libavfilter/vf_hue.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_idet.c b/ffmpeg-2-8-12/libavfilter/vf_idet.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_idet.c
rename to ffmpeg-2-8-12/libavfilter/vf_idet.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_idet.h b/ffmpeg-2-8-12/libavfilter/vf_idet.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_idet.h
rename to ffmpeg-2-8-12/libavfilter/vf_idet.h
diff --git a/ffmpeg-2-8-11/libavfilter/vf_il.c b/ffmpeg-2-8-12/libavfilter/vf_il.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_il.c
rename to ffmpeg-2-8-12/libavfilter/vf_il.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_interlace.c b/ffmpeg-2-8-12/libavfilter/vf_interlace.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_interlace.c
rename to ffmpeg-2-8-12/libavfilter/vf_interlace.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_kerndeint.c b/ffmpeg-2-8-12/libavfilter/vf_kerndeint.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_kerndeint.c
rename to ffmpeg-2-8-12/libavfilter/vf_kerndeint.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_lenscorrection.c b/ffmpeg-2-8-12/libavfilter/vf_lenscorrection.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_lenscorrection.c
rename to ffmpeg-2-8-12/libavfilter/vf_lenscorrection.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_libopencv.c b/ffmpeg-2-8-12/libavfilter/vf_libopencv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_libopencv.c
rename to ffmpeg-2-8-12/libavfilter/vf_libopencv.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_lut.c b/ffmpeg-2-8-12/libavfilter/vf_lut.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_lut.c
rename to ffmpeg-2-8-12/libavfilter/vf_lut.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_lut3d.c b/ffmpeg-2-8-12/libavfilter/vf_lut3d.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_lut3d.c
rename to ffmpeg-2-8-12/libavfilter/vf_lut3d.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_mcdeint.c b/ffmpeg-2-8-12/libavfilter/vf_mcdeint.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_mcdeint.c
rename to ffmpeg-2-8-12/libavfilter/vf_mcdeint.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_mergeplanes.c b/ffmpeg-2-8-12/libavfilter/vf_mergeplanes.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_mergeplanes.c
rename to ffmpeg-2-8-12/libavfilter/vf_mergeplanes.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_mpdecimate.c b/ffmpeg-2-8-12/libavfilter/vf_mpdecimate.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_mpdecimate.c
rename to ffmpeg-2-8-12/libavfilter/vf_mpdecimate.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_neighbor.c b/ffmpeg-2-8-12/libavfilter/vf_neighbor.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_neighbor.c
rename to ffmpeg-2-8-12/libavfilter/vf_neighbor.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_noise.c b/ffmpeg-2-8-12/libavfilter/vf_noise.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_noise.c
rename to ffmpeg-2-8-12/libavfilter/vf_noise.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_noise.h b/ffmpeg-2-8-12/libavfilter/vf_noise.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_noise.h
rename to ffmpeg-2-8-12/libavfilter/vf_noise.h
diff --git a/ffmpeg-2-8-11/libavfilter/vf_null.c b/ffmpeg-2-8-12/libavfilter/vf_null.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_null.c
rename to ffmpeg-2-8-12/libavfilter/vf_null.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_overlay.c b/ffmpeg-2-8-12/libavfilter/vf_overlay.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_overlay.c
rename to ffmpeg-2-8-12/libavfilter/vf_overlay.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_owdenoise.c b/ffmpeg-2-8-12/libavfilter/vf_owdenoise.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_owdenoise.c
rename to ffmpeg-2-8-12/libavfilter/vf_owdenoise.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_pad.c b/ffmpeg-2-8-12/libavfilter/vf_pad.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_pad.c
rename to ffmpeg-2-8-12/libavfilter/vf_pad.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_palettegen.c b/ffmpeg-2-8-12/libavfilter/vf_palettegen.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_palettegen.c
rename to ffmpeg-2-8-12/libavfilter/vf_palettegen.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_paletteuse.c b/ffmpeg-2-8-12/libavfilter/vf_paletteuse.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_paletteuse.c
rename to ffmpeg-2-8-12/libavfilter/vf_paletteuse.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_perspective.c b/ffmpeg-2-8-12/libavfilter/vf_perspective.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_perspective.c
rename to ffmpeg-2-8-12/libavfilter/vf_perspective.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_phase.c b/ffmpeg-2-8-12/libavfilter/vf_phase.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_phase.c
rename to ffmpeg-2-8-12/libavfilter/vf_phase.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_pixdesctest.c b/ffmpeg-2-8-12/libavfilter/vf_pixdesctest.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_pixdesctest.c
rename to ffmpeg-2-8-12/libavfilter/vf_pixdesctest.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_pp.c b/ffmpeg-2-8-12/libavfilter/vf_pp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_pp.c
rename to ffmpeg-2-8-12/libavfilter/vf_pp.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_pp7.c b/ffmpeg-2-8-12/libavfilter/vf_pp7.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_pp7.c
rename to ffmpeg-2-8-12/libavfilter/vf_pp7.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_pp7.h b/ffmpeg-2-8-12/libavfilter/vf_pp7.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_pp7.h
rename to ffmpeg-2-8-12/libavfilter/vf_pp7.h
diff --git a/ffmpeg-2-8-11/libavfilter/vf_psnr.c b/ffmpeg-2-8-12/libavfilter/vf_psnr.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_psnr.c
rename to ffmpeg-2-8-12/libavfilter/vf_psnr.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_pullup.c b/ffmpeg-2-8-12/libavfilter/vf_pullup.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_pullup.c
rename to ffmpeg-2-8-12/libavfilter/vf_pullup.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_pullup.h b/ffmpeg-2-8-12/libavfilter/vf_pullup.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_pullup.h
rename to ffmpeg-2-8-12/libavfilter/vf_pullup.h
diff --git a/ffmpeg-2-8-11/libavfilter/vf_qp.c b/ffmpeg-2-8-12/libavfilter/vf_qp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_qp.c
rename to ffmpeg-2-8-12/libavfilter/vf_qp.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_random.c b/ffmpeg-2-8-12/libavfilter/vf_random.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_random.c
rename to ffmpeg-2-8-12/libavfilter/vf_random.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_removegrain.c b/ffmpeg-2-8-12/libavfilter/vf_removegrain.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_removegrain.c
rename to ffmpeg-2-8-12/libavfilter/vf_removegrain.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_removelogo.c b/ffmpeg-2-8-12/libavfilter/vf_removelogo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_removelogo.c
rename to ffmpeg-2-8-12/libavfilter/vf_removelogo.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_repeatfields.c b/ffmpeg-2-8-12/libavfilter/vf_repeatfields.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_repeatfields.c
rename to ffmpeg-2-8-12/libavfilter/vf_repeatfields.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_rotate.c b/ffmpeg-2-8-12/libavfilter/vf_rotate.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_rotate.c
rename to ffmpeg-2-8-12/libavfilter/vf_rotate.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_sab.c b/ffmpeg-2-8-12/libavfilter/vf_sab.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_sab.c
rename to ffmpeg-2-8-12/libavfilter/vf_sab.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_scale.c b/ffmpeg-2-8-12/libavfilter/vf_scale.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_scale.c
rename to ffmpeg-2-8-12/libavfilter/vf_scale.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_separatefields.c b/ffmpeg-2-8-12/libavfilter/vf_separatefields.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_separatefields.c
rename to ffmpeg-2-8-12/libavfilter/vf_separatefields.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_setfield.c b/ffmpeg-2-8-12/libavfilter/vf_setfield.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_setfield.c
rename to ffmpeg-2-8-12/libavfilter/vf_setfield.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_showinfo.c b/ffmpeg-2-8-12/libavfilter/vf_showinfo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_showinfo.c
rename to ffmpeg-2-8-12/libavfilter/vf_showinfo.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_showpalette.c b/ffmpeg-2-8-12/libavfilter/vf_showpalette.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_showpalette.c
rename to ffmpeg-2-8-12/libavfilter/vf_showpalette.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_shuffleplanes.c b/ffmpeg-2-8-12/libavfilter/vf_shuffleplanes.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_shuffleplanes.c
rename to ffmpeg-2-8-12/libavfilter/vf_shuffleplanes.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_signalstats.c b/ffmpeg-2-8-12/libavfilter/vf_signalstats.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_signalstats.c
rename to ffmpeg-2-8-12/libavfilter/vf_signalstats.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_smartblur.c b/ffmpeg-2-8-12/libavfilter/vf_smartblur.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_smartblur.c
rename to ffmpeg-2-8-12/libavfilter/vf_smartblur.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_spp.c b/ffmpeg-2-8-12/libavfilter/vf_spp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_spp.c
rename to ffmpeg-2-8-12/libavfilter/vf_spp.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_spp.h b/ffmpeg-2-8-12/libavfilter/vf_spp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_spp.h
rename to ffmpeg-2-8-12/libavfilter/vf_spp.h
diff --git a/ffmpeg-2-8-11/libavfilter/vf_ssim.c b/ffmpeg-2-8-12/libavfilter/vf_ssim.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_ssim.c
rename to ffmpeg-2-8-12/libavfilter/vf_ssim.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_stack.c b/ffmpeg-2-8-12/libavfilter/vf_stack.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_stack.c
rename to ffmpeg-2-8-12/libavfilter/vf_stack.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_stereo3d.c b/ffmpeg-2-8-12/libavfilter/vf_stereo3d.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_stereo3d.c
rename to ffmpeg-2-8-12/libavfilter/vf_stereo3d.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_subtitles.c b/ffmpeg-2-8-12/libavfilter/vf_subtitles.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_subtitles.c
rename to ffmpeg-2-8-12/libavfilter/vf_subtitles.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_super2xsai.c b/ffmpeg-2-8-12/libavfilter/vf_super2xsai.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_super2xsai.c
rename to ffmpeg-2-8-12/libavfilter/vf_super2xsai.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_swapuv.c b/ffmpeg-2-8-12/libavfilter/vf_swapuv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_swapuv.c
rename to ffmpeg-2-8-12/libavfilter/vf_swapuv.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_telecine.c b/ffmpeg-2-8-12/libavfilter/vf_telecine.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_telecine.c
rename to ffmpeg-2-8-12/libavfilter/vf_telecine.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_thumbnail.c b/ffmpeg-2-8-12/libavfilter/vf_thumbnail.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_thumbnail.c
rename to ffmpeg-2-8-12/libavfilter/vf_thumbnail.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_tile.c b/ffmpeg-2-8-12/libavfilter/vf_tile.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_tile.c
rename to ffmpeg-2-8-12/libavfilter/vf_tile.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_tinterlace.c b/ffmpeg-2-8-12/libavfilter/vf_tinterlace.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_tinterlace.c
rename to ffmpeg-2-8-12/libavfilter/vf_tinterlace.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_transpose.c b/ffmpeg-2-8-12/libavfilter/vf_transpose.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_transpose.c
rename to ffmpeg-2-8-12/libavfilter/vf_transpose.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_unsharp.c b/ffmpeg-2-8-12/libavfilter/vf_unsharp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_unsharp.c
rename to ffmpeg-2-8-12/libavfilter/vf_unsharp.c
diff --git a/ffmpeg-2-8-12/libavfilter/vf_uspp.c b/ffmpeg-2-8-12/libavfilter/vf_uspp.c
new file mode 100644
index 0000000..6c53680
--- /dev/null
+++ b/ffmpeg-2-8-12/libavfilter/vf_uspp.c
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 2003 Michael Niedermayer <michaelni at gmx.at>
+ * Copyright (c) 2014 Arwa Arif <arwaarif1994 at gmail.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 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.
+ */
+
+/**
+ * @file
+ * Ultra Slow/Simple Post-processing filter.
+ *
+ * Originally written by Michael Niedermayer for the MPlayer project, and
+ * ported by Arwa Arif for FFmpeg.
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/pixdesc.h"
+#include "internal.h"
+#include "avfilter.h"
+
+#define MAX_LEVEL 8 /* quality levels */
+#define BLOCK 16
+
+typedef struct {
+ const AVClass *av_class;
+ int log2_count;
+ int hsub, vsub;
+ int qp;
+ int qscale_type;
+ int temp_stride[3];
+ uint8_t *src[3];
+ uint16_t *temp[3];
+ int outbuf_size;
+ uint8_t *outbuf;
+ AVCodecContext *avctx_enc[BLOCK*BLOCK];
+ AVFrame *frame;
+ AVFrame *frame_dec;
+ uint8_t *non_b_qp_table;
+ int non_b_qp_alloc_size;
+ int use_bframe_qp;
+} USPPContext;
+
+#define OFFSET(x) offsetof(USPPContext, x)
+#define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
+static const AVOption uspp_options[] = {
+ { "quality", "set quality", OFFSET(log2_count), AV_OPT_TYPE_INT, {.i64 = 3}, 0, MAX_LEVEL, FLAGS },
+ { "qp", "force a constant quantizer parameter", OFFSET(qp), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 63, FLAGS },
+ { "use_bframe_qp", "use B-frames' QP", OFFSET(use_bframe_qp), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, FLAGS },
+ { NULL }
+};
+
+AVFILTER_DEFINE_CLASS(uspp);
+
+DECLARE_ALIGNED(8, static const uint8_t, dither)[8][8] = {
+ { 0*4, 48*4, 12*4, 60*4, 3*4, 51*4, 15*4, 63*4, },
+ { 32*4, 16*4, 44*4, 28*4, 35*4, 19*4, 47*4, 31*4, },
+ { 8*4, 56*4, 4*4, 52*4, 11*4, 59*4, 7*4, 55*4, },
+ { 40*4, 24*4, 36*4, 20*4, 43*4, 27*4, 39*4, 23*4, },
+ { 2*4, 50*4, 14*4, 62*4, 1*4, 49*4, 13*4, 61*4, },
+ { 34*4, 18*4, 46*4, 30*4, 33*4, 17*4, 45*4, 29*4, },
+ { 10*4, 58*4, 6*4, 54*4, 9*4, 57*4, 5*4, 53*4, },
+ { 42*4, 26*4, 38*4, 22*4, 41*4, 25*4, 37*4, 21*4, },
+};
+
+static const uint8_t offset[511][2] = {
+ { 0, 0},
+ { 0, 0}, { 8, 8}, // quality 1
+ { 0, 0}, { 4, 4}, {12, 8}, { 8,12}, // quality 2
+ { 0, 0}, {10, 2}, { 4, 4}, {14, 6}, { 8, 8}, { 2,10}, {12,12}, { 6,14}, // quality 3
+
+ { 0, 0}, {10, 2}, { 4, 4}, {14, 6}, { 8, 8}, { 2,10}, {12,12}, { 6,14},
+ { 5, 1}, {15, 3}, { 9, 5}, { 3, 7}, {13, 9}, { 7,11}, { 1,13}, {11,15}, // quality 4
+
+ { 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9},
+ { 2, 2}, {10, 2}, { 2,10}, {10,10}, { 7, 3}, {15, 3}, { 7,11}, {15,11},
+ { 4, 4}, {12, 4}, { 4,12}, {12,12}, { 1, 5}, { 9, 5}, { 1,13}, { 9,13},
+ { 6, 6}, {14, 6}, { 6,14}, {14,14}, { 3, 7}, {11, 7}, { 3,15}, {11,15}, // quality 5
+
+ { 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 4, 0}, {12, 0}, { 4, 8}, {12, 8},
+ { 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9},
+ { 3, 2}, {11, 2}, { 3,10}, {11,10}, { 7, 2}, {15, 2}, { 7,10}, {15,10},
+ { 2, 3}, {10, 3}, { 2,11}, {10,11}, { 6, 3}, {14, 3}, { 6,11}, {14,11},
+ { 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 4, 4}, {12, 4}, { 4,12}, {12,12},
+ { 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 5, 5}, {13, 5}, { 5,13}, {13,13},
+ { 3, 6}, {11, 6}, { 3,14}, {11,14}, { 7, 6}, {15, 6}, { 7,14}, {15,14},
+ { 2, 7}, {10, 7}, { 2,15}, {10,15}, { 6, 7}, {14, 7}, { 6,15}, {14,15}, // quality 6
+
+ { 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 0, 2}, { 8, 2}, { 0,10}, { 8,10},
+ { 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 0, 6}, { 8, 6}, { 0,14}, { 8,14},
+ { 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 1, 3}, { 9, 3}, { 1,11}, { 9,11},
+ { 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 1, 7}, { 9, 7}, { 1,15}, { 9,15},
+ { 2, 0}, {10, 0}, { 2, 8}, {10, 8}, { 2, 2}, {10, 2}, { 2,10}, {10,10},
+ { 2, 4}, {10, 4}, { 2,12}, {10,12}, { 2, 6}, {10, 6}, { 2,14}, {10,14},
+ { 3, 1}, {11, 1}, { 3, 9}, {11, 9}, { 3, 3}, {11, 3}, { 3,11}, {11,11},
+ { 3, 5}, {11, 5}, { 3,13}, {11,13}, { 3, 7}, {11, 7}, { 3,15}, {11,15},
+ { 4, 0}, {12, 0}, { 4, 8}, {12, 8}, { 4, 2}, {12, 2}, { 4,10}, {12,10},
+ { 4, 4}, {12, 4}, { 4,12}, {12,12}, { 4, 6}, {12, 6}, { 4,14}, {12,14},
+ { 5, 1}, {13, 1}, { 5, 9}, {13, 9}, { 5, 3}, {13, 3}, { 5,11}, {13,11},
+ { 5, 5}, {13, 5}, { 5,13}, {13,13}, { 5, 7}, {13, 7}, { 5,15}, {13,15},
+ { 6, 0}, {14, 0}, { 6, 8}, {14, 8}, { 6, 2}, {14, 2}, { 6,10}, {14,10},
+ { 6, 4}, {14, 4}, { 6,12}, {14,12}, { 6, 6}, {14, 6}, { 6,14}, {14,14},
+ { 7, 1}, {15, 1}, { 7, 9}, {15, 9}, { 7, 3}, {15, 3}, { 7,11}, {15,11},
+ { 7, 5}, {15, 5}, { 7,13}, {15,13}, { 7, 7}, {15, 7}, { 7,15}, {15,15}, // quality 7
+
+ { 0, 0}, { 8, 0}, { 0, 8}, { 8, 8}, { 4, 4}, {12, 4}, { 4,12}, {12,12},
+ { 0, 4}, { 8, 4}, { 0,12}, { 8,12}, { 4, 0}, {12, 0}, { 4, 8}, {12, 8},
+ { 2, 2}, {10, 2}, { 2,10}, {10,10}, { 6, 6}, {14, 6}, { 6,14}, {14,14},
+ { 2, 6}, {10, 6}, { 2,14}, {10,14}, { 6, 2}, {14, 2}, { 6,10}, {14,10},
+ { 0, 2}, { 8, 2}, { 0,10}, { 8,10}, { 4, 6}, {12, 6}, { 4,14}, {12,14},
+ { 0, 6}, { 8, 6}, { 0,14}, { 8,14}, { 4, 2}, {12, 2}, { 4,10}, {12,10},
+ { 2, 0}, {10, 0}, { 2, 8}, {10, 8}, { 6, 4}, {14, 4}, { 6,12}, {14,12},
+ { 2, 4}, {10, 4}, { 2,12}, {10,12}, { 6, 0}, {14, 0}, { 6, 8}, {14, 8},
+ { 1, 1}, { 9, 1}, { 1, 9}, { 9, 9}, { 5, 5}, {13, 5}, { 5,13}, {13,13},
+ { 1, 5}, { 9, 5}, { 1,13}, { 9,13}, { 5, 1}, {13, 1}, { 5, 9}, {13, 9},
+ { 3, 3}, {11, 3}, { 3,11}, {11,11}, { 7, 7}, {15, 7}, { 7,15}, {15,15},
+ { 3, 7}, {11, 7}, { 3,15}, {11,15}, { 7, 3}, {15, 3}, { 7,11}, {15,11},
+ { 1, 3}, { 9, 3}, { 1,11}, { 9,11}, { 5, 7}, {13, 7}, { 5,15}, {13,15},
+ { 1, 7}, { 9, 7}, { 1,15}, { 9,15}, { 5, 3}, {13, 3}, { 5,11}, {13,11}, // quality 8
+ { 3, 1}, {11, 1}, { 3, 9}, {11, 9}, { 7, 5}, {15, 5}, { 7,13}, {15,13},
+ { 3, 5}, {11, 5}, { 3,13}, {11,13}, { 7, 1}, {15, 1}, { 7, 9}, {15, 9},
+ { 0, 1}, { 8, 1}, { 0, 9}, { 8, 9}, { 4, 5}, {12, 5}, { 4,13}, {12,13},
+ { 0, 5}, { 8, 5}, { 0,13}, { 8,13}, { 4, 1}, {12, 1}, { 4, 9}, {12, 9},
+ { 2, 3}, {10, 3}, { 2,11}, {10,11}, { 6, 7}, {14, 7}, { 6,15}, {14,15},
+ { 2, 7}, {10, 7}, { 2,15}, {10,15}, { 6, 3}, {14, 3}, { 6,11}, {14,11},
+ { 0, 3}, { 8, 3}, { 0,11}, { 8,11}, { 4, 7}, {12, 7}, { 4,15}, {12,15},
+ { 0, 7}, { 8, 7}, { 0,15}, { 8,15}, { 4, 3}, {12, 3}, { 4,11}, {12,11},
+ { 2, 1}, {10, 1}, { 2, 9}, {10, 9}, { 6, 5}, {14, 5}, { 6,13}, {14,13},
+ { 2, 5}, {10, 5}, { 2,13}, {10,13}, { 6, 1}, {14, 1}, { 6, 9}, {14, 9},
+ { 1, 0}, { 9, 0}, { 1, 8}, { 9, 8}, { 5, 4}, {13, 4}, { 5,12}, {13,12},
+ { 1, 4}, { 9, 4}, { 1,12}, { 9,12}, { 5, 0}, {13, 0}, { 5, 8}, {13, 8},
+ { 3, 2}, {11, 2}, { 3,10}, {11,10}, { 7, 6}, {15, 6}, { 7,14}, {15,14},
+ { 3, 6}, {11, 6}, { 3,14}, {11,14}, { 7, 2}, {15, 2}, { 7,10}, {15,10},
+ { 1, 2}, { 9, 2}, { 1,10}, { 9,10}, { 5, 6}, {13, 6}, { 5,14}, {13,14},
+ { 1, 6}, { 9, 6}, { 1,14}, { 9,14}, { 5, 2}, {13, 2}, { 5,10}, {13,10},
+ { 3, 0}, {11, 0}, { 3, 8}, {11, 8}, { 7, 4}, {15, 4}, { 7,12}, {15,12},
+ { 3, 4}, {11, 4}, { 3,12}, {11,12}, { 7, 0}, {15, 0}, { 7, 8}, {15, 8},
+};
+
+static void store_slice_c(uint8_t *dst, const uint16_t *src,
+ int dst_stride, int src_stride,
+ int width, int height, int log2_scale)
+{
+ int y, x;
+
+#define STORE(pos) do { \
+ temp = ((src[x + y * src_stride + pos] << log2_scale) + d[pos]) >> 8; \
+ if (temp & 0x100) temp = ~(temp >> 31); \
+ dst[x + y * dst_stride + pos] = temp; \
+} while (0)
+
+ for (y = 0; y < height; y++) {
+ const uint8_t *d = dither[y&7];
+ for (x = 0; x < width; x += 8) {
+ int temp;
+ STORE(0);
+ STORE(1);
+ STORE(2);
+ STORE(3);
+ STORE(4);
+ STORE(5);
+ STORE(6);
+ STORE(7);
+ }
+ }
+}
+
+static void filter(USPPContext *p, uint8_t *dst[3], uint8_t *src[3],
+ int dst_stride[3], int src_stride[3], int width,
+ int height, uint8_t *qp_store, int qp_stride)
+{
+ int x, y, i, j;
+ const int count = 1<<p->log2_count;
+
+ for (i = 0; i < 3; i++) {
+ int is_chroma = !!i;
+ int w = FF_CEIL_RSHIFT(width, is_chroma ? p->hsub : 0);
+ int h = FF_CEIL_RSHIFT(height, is_chroma ? p->vsub : 0);
+ int stride = p->temp_stride[i];
+ int block = BLOCK >> (is_chroma ? p->hsub : 0);
+
+ if (!src[i] || !dst[i])
+ continue;
+ for (y = 0; y < h; y++) {
+ int index = block + block * stride + y * stride;
+
+ memcpy(p->src[i] + index, src[i] + y * src_stride[i], w );
+ for (x = 0; x < block; x++) {
+ p->src[i][index - x - 1] = p->src[i][index + x ];
+ p->src[i][index + w + x ] = p->src[i][index + w - x - 1];
+ }
+ }
+ for (y = 0; y < block; y++) {
+ memcpy(p->src[i] + ( block-1-y) * stride, p->src[i] + ( y+block ) * stride, stride);
+ memcpy(p->src[i] + (h+block +y) * stride, p->src[i] + (h-y+block-1) * stride, stride);
+ }
+
+ p->frame->linesize[i] = stride;
+ memset(p->temp[i], 0, (h + 2 * block) * stride * sizeof(int16_t));
+ }
+
+ if (p->qp)
+ p->frame->quality = p->qp * FF_QP2LAMBDA;
+ else {
+ int qpsum=0;
+ int qpcount = (height>>4) * (height>>4);
+
+ for (y = 0; y < (height>>4); y++) {
+ for (x = 0; x < (width>>4); x++)
+ qpsum += qp_store[x + y * qp_stride];
+ }
+ p->frame->quality = ff_norm_qscale((qpsum + qpcount/2) / qpcount, p->qscale_type) * FF_QP2LAMBDA;
+ }
+// init per MB qscale stuff FIXME
+ p->frame->height = height + BLOCK;
+ p->frame->width = width + BLOCK;
+
+ for (i = 0; i < count; i++) {
+ const int x1 = offset[i+count-1][0];
+ const int y1 = offset[i+count-1][1];
+ const int x1c = x1 >> p->hsub;
+ const int y1c = y1 >> p->vsub;
+ const int BLOCKc = BLOCK >> p->hsub;
+ int offset;
+ AVPacket pkt = {0};
+ int got_pkt_ptr;
+
+ av_init_packet(&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;
+
+ avcodec_encode_video2(p->avctx_enc[i], &pkt, p->frame, &got_pkt_ptr);
+ p->frame_dec = p->avctx_enc[i]->coded_frame;
+
+ offset = (BLOCK-x1) + (BLOCK-y1) * p->frame_dec->linesize[0];
+
+ for (y = 0; y < height; y++)
+ for (x = 0; x < width; x++)
+ p->temp[0][x + y * p->temp_stride[0]] += p->frame_dec->data[0][x + y * p->frame_dec->linesize[0] + offset];
+
+ if (!src[2] || !dst[2])
+ continue;
+
+ offset = (BLOCKc-x1c) + (BLOCKc-y1c) * p->frame_dec->linesize[1];
+
+ for (y = 0; y < FF_CEIL_RSHIFT(height, p->vsub); y++) {
+ for (x = 0; x < FF_CEIL_RSHIFT(width, p->hsub); x++) {
+ p->temp[1][x + y * p->temp_stride[1]] += p->frame_dec->data[1][x + y * p->frame_dec->linesize[1] + offset];
+ p->temp[2][x + y * p->temp_stride[2]] += p->frame_dec->data[2][x + y * p->frame_dec->linesize[2] + offset];
+ }
+ }
+ }
+
+ for (j = 0; j < 3; j++) {
+ int is_chroma = !!j;
+ if (!dst[j])
+ continue;
+ store_slice_c(dst[j], p->temp[j], dst_stride[j], p->temp_stride[j],
+ FF_CEIL_RSHIFT(width, is_chroma ? p->hsub : 0),
+ FF_CEIL_RSHIFT(height, is_chroma ? p->vsub : 0),
+ 8-p->log2_count);
+ }
+}
+
+static int query_formats(AVFilterContext *ctx)
+{
+ static const enum AVPixelFormat pix_fmts[] = {
+ AV_PIX_FMT_YUV444P,
+ AV_PIX_FMT_YUV420P,
+ AV_PIX_FMT_YUV410P,
+ AV_PIX_FMT_YUVJ444P,
+ AV_PIX_FMT_YUVJ420P,
+ AV_PIX_FMT_GRAY8,
+ 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(AVFilterLink *inlink)
+{
+
+ AVFilterContext *ctx = inlink->dst;
+ USPPContext *uspp = ctx->priv;
+ const int height = inlink->h;
+ const int width = inlink->w;
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format);
+ int i;
+
+ 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);
+ }
+
+ uspp->hsub = desc->log2_chroma_w;
+ uspp->vsub = desc->log2_chroma_h;
+
+ for (i = 0; i < 3; i++) {
+ int is_chroma = !!i;
+ int w = (width + 4 * BLOCK-1) & (~(2 * BLOCK-1));
+ int h = (height + 4 * BLOCK-1) & (~(2 * BLOCK-1));
+
+ if (is_chroma) {
+ w = FF_CEIL_RSHIFT(w, uspp->hsub);
+ h = FF_CEIL_RSHIFT(h, uspp->vsub);
+ }
+
+ uspp->temp_stride[i] = w;
+ if (!(uspp->temp[i] = av_malloc_array(uspp->temp_stride[i], h * sizeof(int16_t))))
+ return AVERROR(ENOMEM);
+ if (!(uspp->src [i] = av_malloc_array(uspp->temp_stride[i], h * sizeof(uint8_t))))
+ return AVERROR(ENOMEM);
+ }
+
+ for (i = 0; i < (1<<uspp->log2_count); i++) {
+ AVCodecContext *avctx_enc;
+ AVDictionary *opts = NULL;
+ int ret;
+
+ if (!(uspp->avctx_enc[i] = avcodec_alloc_context3(NULL)))
+ return AVERROR(ENOMEM);
+
+ avctx_enc = uspp->avctx_enc[i];
+ avctx_enc->width = width + BLOCK;
+ avctx_enc->height = height + BLOCK;
+ avctx_enc->time_base = (AVRational){1,25}; // meaningless
+ avctx_enc->gop_size = INT_MAX;
+ avctx_enc->max_b_frames = 0;
+ avctx_enc->pix_fmt = inlink->format;
+ avctx_enc->flags = AV_CODEC_FLAG_QSCALE | CODEC_FLAG_LOW_DELAY;
+ avctx_enc->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
+ avctx_enc->global_quality = 123;
+ av_dict_set(&opts, "no_bitstream", "1", 0);
+ ret = avcodec_open2(avctx_enc, enc, &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->outbuf = av_malloc(uspp->outbuf_size)))
+ return AVERROR(ENOMEM);
+
+ return 0;
+}
+
+static int filter_frame(AVFilterLink *inlink, AVFrame *in)
+{
+ AVFilterContext *ctx = inlink->dst;
+ USPPContext *uspp = ctx->priv;
+ AVFilterLink *outlink = ctx->outputs[0];
+ AVFrame *out = in;
+
+ int qp_stride = 0;
+ uint8_t *qp_table = NULL;
+
+ /* 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 (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 = FF_CEIL_RSHIFT(inlink->w, 4);
+ h = 1;
+ } else {
+ w = qp_stride;
+ h = FF_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->log2_count && !ctx->is_disabled) {
+ if (!uspp->use_bframe_qp && uspp->non_b_qp_table)
+ qp_table = uspp->non_b_qp_table;
+
+ if (qp_table || uspp->qp) {
+
+ /* get a new frame if in-place is not possible or if the dimensions
+ * are not multiple of 8 */
+ if (!av_frame_is_writable(in) || (inlink->w & 7) || (inlink->h & 7)) {
+ const int aligned_w = FFALIGN(inlink->w, 8);
+ const int aligned_h = FFALIGN(inlink->h, 8);
+
+ out = ff_get_video_buffer(outlink, aligned_w, aligned_h);
+ if (!out) {
+ av_frame_free(&in);
+ return AVERROR(ENOMEM);
+ }
+ av_frame_copy_props(out, in);
+ out->width = in->width;
+ out->height = in->height;
+ }
+
+ filter(uspp, out->data, in->data, out->linesize, in->linesize,
+ inlink->w, inlink->h, qp_table, qp_stride);
+ }
+ }
+
+ if (in != out) {
+ if (in->data[3])
+ av_image_copy_plane(out->data[3], out->linesize[3],
+ in ->data[3], in ->linesize[3],
+ inlink->w, inlink->h);
+ av_frame_free(&in);
+ }
+ return ff_filter_frame(outlink, out);
+}
+
+static av_cold void uninit(AVFilterContext *ctx)
+{
+ USPPContext *uspp = ctx->priv;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ av_freep(&uspp->temp[i]);
+ 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]);
+ }
+
+ av_freep(&uspp->non_b_qp_table);
+ av_freep(&uspp->outbuf);
+ av_frame_free(&uspp->frame);
+}
+
+static const AVFilterPad uspp_inputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .config_props = config_input,
+ .filter_frame = filter_frame,
+ },
+ { NULL }
+};
+
+static const AVFilterPad uspp_outputs[] = {
+ {
+ .name = "default",
+ .type = AVMEDIA_TYPE_VIDEO,
+ },
+ { NULL }
+};
+
+AVFilter ff_vf_uspp = {
+ .name = "uspp",
+ .description = NULL_IF_CONFIG_SMALL("Apply Ultra Simple / Slow Post-processing filter."),
+ .priv_size = sizeof(USPPContext),
+ .uninit = uninit,
+ .query_formats = query_formats,
+ .inputs = uspp_inputs,
+ .outputs = uspp_outputs,
+ .priv_class = &uspp_class,
+ .flags = AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL,
+};
diff --git a/ffmpeg-2-8-11/libavfilter/vf_vectorscope.c b/ffmpeg-2-8-12/libavfilter/vf_vectorscope.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_vectorscope.c
rename to ffmpeg-2-8-12/libavfilter/vf_vectorscope.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_vflip.c b/ffmpeg-2-8-12/libavfilter/vf_vflip.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_vflip.c
rename to ffmpeg-2-8-12/libavfilter/vf_vflip.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_vidstabdetect.c b/ffmpeg-2-8-12/libavfilter/vf_vidstabdetect.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_vidstabdetect.c
rename to ffmpeg-2-8-12/libavfilter/vf_vidstabdetect.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_vidstabtransform.c b/ffmpeg-2-8-12/libavfilter/vf_vidstabtransform.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_vidstabtransform.c
rename to ffmpeg-2-8-12/libavfilter/vf_vidstabtransform.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_vignette.c b/ffmpeg-2-8-12/libavfilter/vf_vignette.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_vignette.c
rename to ffmpeg-2-8-12/libavfilter/vf_vignette.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_w3fdif.c b/ffmpeg-2-8-12/libavfilter/vf_w3fdif.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_w3fdif.c
rename to ffmpeg-2-8-12/libavfilter/vf_w3fdif.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_waveform.c b/ffmpeg-2-8-12/libavfilter/vf_waveform.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_waveform.c
rename to ffmpeg-2-8-12/libavfilter/vf_waveform.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_xbr.c b/ffmpeg-2-8-12/libavfilter/vf_xbr.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_xbr.c
rename to ffmpeg-2-8-12/libavfilter/vf_xbr.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_yadif.c b/ffmpeg-2-8-12/libavfilter/vf_yadif.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_yadif.c
rename to ffmpeg-2-8-12/libavfilter/vf_yadif.c
diff --git a/ffmpeg-2-8-11/libavfilter/vf_zoompan.c b/ffmpeg-2-8-12/libavfilter/vf_zoompan.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vf_zoompan.c
rename to ffmpeg-2-8-12/libavfilter/vf_zoompan.c
diff --git a/ffmpeg-2-8-11/libavfilter/video.c b/ffmpeg-2-8-12/libavfilter/video.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/video.c
rename to ffmpeg-2-8-12/libavfilter/video.c
diff --git a/ffmpeg-2-8-11/libavfilter/video.h b/ffmpeg-2-8-12/libavfilter/video.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/video.h
rename to ffmpeg-2-8-12/libavfilter/video.h
diff --git a/ffmpeg-2-8-11/libavfilter/vidstabutils.c b/ffmpeg-2-8-12/libavfilter/vidstabutils.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vidstabutils.c
rename to ffmpeg-2-8-12/libavfilter/vidstabutils.c
diff --git a/ffmpeg-2-8-11/libavfilter/vidstabutils.h b/ffmpeg-2-8-12/libavfilter/vidstabutils.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vidstabutils.h
rename to ffmpeg-2-8-12/libavfilter/vidstabutils.h
diff --git a/ffmpeg-2-8-11/libavfilter/vsink_nullsink.c b/ffmpeg-2-8-12/libavfilter/vsink_nullsink.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vsink_nullsink.c
rename to ffmpeg-2-8-12/libavfilter/vsink_nullsink.c
diff --git a/ffmpeg-2-8-11/libavfilter/vsrc_cellauto.c b/ffmpeg-2-8-12/libavfilter/vsrc_cellauto.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vsrc_cellauto.c
rename to ffmpeg-2-8-12/libavfilter/vsrc_cellauto.c
diff --git a/ffmpeg-2-8-11/libavfilter/vsrc_life.c b/ffmpeg-2-8-12/libavfilter/vsrc_life.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vsrc_life.c
rename to ffmpeg-2-8-12/libavfilter/vsrc_life.c
diff --git a/ffmpeg-2-8-11/libavfilter/vsrc_mandelbrot.c b/ffmpeg-2-8-12/libavfilter/vsrc_mandelbrot.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vsrc_mandelbrot.c
rename to ffmpeg-2-8-12/libavfilter/vsrc_mandelbrot.c
diff --git a/ffmpeg-2-8-11/libavfilter/vsrc_mptestsrc.c b/ffmpeg-2-8-12/libavfilter/vsrc_mptestsrc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vsrc_mptestsrc.c
rename to ffmpeg-2-8-12/libavfilter/vsrc_mptestsrc.c
diff --git a/ffmpeg-2-8-11/libavfilter/vsrc_testsrc.c b/ffmpeg-2-8-12/libavfilter/vsrc_testsrc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/vsrc_testsrc.c
rename to ffmpeg-2-8-12/libavfilter/vsrc_testsrc.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/Makefile b/ffmpeg-2-8-12/libavfilter/x86/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/Makefile
rename to ffmpeg-2-8-12/libavfilter/x86/Makefile
diff --git a/ffmpeg-2-8-11/libavfilter/x86/af_volume.asm b/ffmpeg-2-8-12/libavfilter/x86/af_volume.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/af_volume.asm
rename to ffmpeg-2-8-12/libavfilter/x86/af_volume.asm
diff --git a/ffmpeg-2-8-11/libavfilter/x86/af_volume_init.c b/ffmpeg-2-8-12/libavfilter/x86/af_volume_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/af_volume_init.c
rename to ffmpeg-2-8-12/libavfilter/x86/af_volume_init.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_eq.c b/ffmpeg-2-8-12/libavfilter/x86/vf_eq.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_eq.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_eq.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_fspp.asm b/ffmpeg-2-8-12/libavfilter/x86/vf_fspp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_fspp.asm
rename to ffmpeg-2-8-12/libavfilter/x86/vf_fspp.asm
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_fspp_init.c b/ffmpeg-2-8-12/libavfilter/x86/vf_fspp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_fspp_init.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_fspp_init.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_gradfun.asm b/ffmpeg-2-8-12/libavfilter/x86/vf_gradfun.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_gradfun.asm
rename to ffmpeg-2-8-12/libavfilter/x86/vf_gradfun.asm
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_gradfun_init.c b/ffmpeg-2-8-12/libavfilter/x86/vf_gradfun_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_gradfun_init.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_gradfun_init.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_hqdn3d.asm b/ffmpeg-2-8-12/libavfilter/x86/vf_hqdn3d.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_hqdn3d.asm
rename to ffmpeg-2-8-12/libavfilter/x86/vf_hqdn3d.asm
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_hqdn3d_init.c b/ffmpeg-2-8-12/libavfilter/x86/vf_hqdn3d_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_hqdn3d_init.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_hqdn3d_init.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_idet.asm b/ffmpeg-2-8-12/libavfilter/x86/vf_idet.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_idet.asm
rename to ffmpeg-2-8-12/libavfilter/x86/vf_idet.asm
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_idet_init.c b/ffmpeg-2-8-12/libavfilter/x86/vf_idet_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_idet_init.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_idet_init.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_interlace.asm b/ffmpeg-2-8-12/libavfilter/x86/vf_interlace.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_interlace.asm
rename to ffmpeg-2-8-12/libavfilter/x86/vf_interlace.asm
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_interlace_init.c b/ffmpeg-2-8-12/libavfilter/x86/vf_interlace_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_interlace_init.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_interlace_init.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_noise.c b/ffmpeg-2-8-12/libavfilter/x86/vf_noise.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_noise.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_noise.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_pp7.asm b/ffmpeg-2-8-12/libavfilter/x86/vf_pp7.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_pp7.asm
rename to ffmpeg-2-8-12/libavfilter/x86/vf_pp7.asm
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_pp7_init.c b/ffmpeg-2-8-12/libavfilter/x86/vf_pp7_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_pp7_init.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_pp7_init.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_psnr.asm b/ffmpeg-2-8-12/libavfilter/x86/vf_psnr.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_psnr.asm
rename to ffmpeg-2-8-12/libavfilter/x86/vf_psnr.asm
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_psnr_init.c b/ffmpeg-2-8-12/libavfilter/x86/vf_psnr_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_psnr_init.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_psnr_init.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_pullup.asm b/ffmpeg-2-8-12/libavfilter/x86/vf_pullup.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_pullup.asm
rename to ffmpeg-2-8-12/libavfilter/x86/vf_pullup.asm
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_pullup_init.c b/ffmpeg-2-8-12/libavfilter/x86/vf_pullup_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_pullup_init.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_pullup_init.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_removegrain.asm b/ffmpeg-2-8-12/libavfilter/x86/vf_removegrain.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_removegrain.asm
rename to ffmpeg-2-8-12/libavfilter/x86/vf_removegrain.asm
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_removegrain_init.c b/ffmpeg-2-8-12/libavfilter/x86/vf_removegrain_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_removegrain_init.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_removegrain_init.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_spp.c b/ffmpeg-2-8-12/libavfilter/x86/vf_spp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_spp.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_spp.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_ssim.asm b/ffmpeg-2-8-12/libavfilter/x86/vf_ssim.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_ssim.asm
rename to ffmpeg-2-8-12/libavfilter/x86/vf_ssim.asm
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_ssim_init.c b/ffmpeg-2-8-12/libavfilter/x86/vf_ssim_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_ssim_init.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_ssim_init.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_tinterlace_init.c b/ffmpeg-2-8-12/libavfilter/x86/vf_tinterlace_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_tinterlace_init.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_tinterlace_init.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_yadif.asm b/ffmpeg-2-8-12/libavfilter/x86/vf_yadif.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_yadif.asm
rename to ffmpeg-2-8-12/libavfilter/x86/vf_yadif.asm
diff --git a/ffmpeg-2-8-11/libavfilter/x86/vf_yadif_init.c b/ffmpeg-2-8-12/libavfilter/x86/vf_yadif_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/vf_yadif_init.c
rename to ffmpeg-2-8-12/libavfilter/x86/vf_yadif_init.c
diff --git a/ffmpeg-2-8-11/libavfilter/x86/yadif-10.asm b/ffmpeg-2-8-12/libavfilter/x86/yadif-10.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/yadif-10.asm
rename to ffmpeg-2-8-12/libavfilter/x86/yadif-10.asm
diff --git a/ffmpeg-2-8-11/libavfilter/x86/yadif-16.asm b/ffmpeg-2-8-12/libavfilter/x86/yadif-16.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/x86/yadif-16.asm
rename to ffmpeg-2-8-12/libavfilter/x86/yadif-16.asm
diff --git a/ffmpeg-2-8-11/libavfilter/yadif.h b/ffmpeg-2-8-12/libavfilter/yadif.h
similarity index 100%
rename from ffmpeg-2-8-11/libavfilter/yadif.h
rename to ffmpeg-2-8-12/libavfilter/yadif.h
diff --git a/ffmpeg-2-8-11/libavformat/4xm.c b/ffmpeg-2-8-12/libavformat/4xm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/4xm.c
rename to ffmpeg-2-8-12/libavformat/4xm.c
diff --git a/ffmpeg-2-8-11/libavformat/Makefile b/ffmpeg-2-8-12/libavformat/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/Makefile
rename to ffmpeg-2-8-12/libavformat/Makefile
diff --git a/ffmpeg-2-8-11/libavformat/a64.c b/ffmpeg-2-8-12/libavformat/a64.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/a64.c
rename to ffmpeg-2-8-12/libavformat/a64.c
diff --git a/ffmpeg-2-8-11/libavformat/aacdec.c b/ffmpeg-2-8-12/libavformat/aacdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/aacdec.c
rename to ffmpeg-2-8-12/libavformat/aacdec.c
diff --git a/ffmpeg-2-8-11/libavformat/aadec.c b/ffmpeg-2-8-12/libavformat/aadec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/aadec.c
rename to ffmpeg-2-8-12/libavformat/aadec.c
diff --git a/ffmpeg-2-8-11/libavformat/ac3dec.c b/ffmpeg-2-8-12/libavformat/ac3dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ac3dec.c
rename to ffmpeg-2-8-12/libavformat/ac3dec.c
diff --git a/ffmpeg-2-8-11/libavformat/act.c b/ffmpeg-2-8-12/libavformat/act.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/act.c
rename to ffmpeg-2-8-12/libavformat/act.c
diff --git a/ffmpeg-2-8-11/libavformat/adp.c b/ffmpeg-2-8-12/libavformat/adp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/adp.c
rename to ffmpeg-2-8-12/libavformat/adp.c
diff --git a/ffmpeg-2-8-11/libavformat/adtsenc.c b/ffmpeg-2-8-12/libavformat/adtsenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/adtsenc.c
rename to ffmpeg-2-8-12/libavformat/adtsenc.c
diff --git a/ffmpeg-2-8-11/libavformat/adxdec.c b/ffmpeg-2-8-12/libavformat/adxdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/adxdec.c
rename to ffmpeg-2-8-12/libavformat/adxdec.c
diff --git a/ffmpeg-2-8-11/libavformat/aea.c b/ffmpeg-2-8-12/libavformat/aea.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/aea.c
rename to ffmpeg-2-8-12/libavformat/aea.c
diff --git a/ffmpeg-2-8-11/libavformat/afc.c b/ffmpeg-2-8-12/libavformat/afc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/afc.c
rename to ffmpeg-2-8-12/libavformat/afc.c
diff --git a/ffmpeg-2-8-11/libavformat/aiff.h b/ffmpeg-2-8-12/libavformat/aiff.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/aiff.h
rename to ffmpeg-2-8-12/libavformat/aiff.h
diff --git a/ffmpeg-2-8-11/libavformat/aiffdec.c b/ffmpeg-2-8-12/libavformat/aiffdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/aiffdec.c
rename to ffmpeg-2-8-12/libavformat/aiffdec.c
diff --git a/ffmpeg-2-8-11/libavformat/aiffenc.c b/ffmpeg-2-8-12/libavformat/aiffenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/aiffenc.c
rename to ffmpeg-2-8-12/libavformat/aiffenc.c
diff --git a/ffmpeg-2-8-11/libavformat/allformats.c b/ffmpeg-2-8-12/libavformat/allformats.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/allformats.c
rename to ffmpeg-2-8-12/libavformat/allformats.c
diff --git a/ffmpeg-2-8-11/libavformat/amr.c b/ffmpeg-2-8-12/libavformat/amr.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/amr.c
rename to ffmpeg-2-8-12/libavformat/amr.c
diff --git a/ffmpeg-2-8-11/libavformat/anm.c b/ffmpeg-2-8-12/libavformat/anm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/anm.c
rename to ffmpeg-2-8-12/libavformat/anm.c
diff --git a/ffmpeg-2-8-11/libavformat/apc.c b/ffmpeg-2-8-12/libavformat/apc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/apc.c
rename to ffmpeg-2-8-12/libavformat/apc.c
diff --git a/ffmpeg-2-8-11/libavformat/ape.c b/ffmpeg-2-8-12/libavformat/ape.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ape.c
rename to ffmpeg-2-8-12/libavformat/ape.c
diff --git a/ffmpeg-2-8-11/libavformat/apetag.c b/ffmpeg-2-8-12/libavformat/apetag.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/apetag.c
rename to ffmpeg-2-8-12/libavformat/apetag.c
diff --git a/ffmpeg-2-8-11/libavformat/apetag.h b/ffmpeg-2-8-12/libavformat/apetag.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/apetag.h
rename to ffmpeg-2-8-12/libavformat/apetag.h
diff --git a/ffmpeg-2-8-12/libavformat/apngdec.c b/ffmpeg-2-8-12/libavformat/apngdec.c
new file mode 100644
index 0000000..4b506dd
--- /dev/null
+++ b/ffmpeg-2-8-12/libavformat/apngdec.c
@@ -0,0 +1,447 @@
+/*
+ * APNG demuxer
+ * Copyright (c) 2014 Benoit Fouet
+ *
+ * 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
+ * APNG demuxer.
+ * @see https://wiki.mozilla.org/APNG_Specification
+ * @see http://www.w3.org/TR/PNG
+ */
+
+#include "avformat.h"
+#include "avio_internal.h"
+#include "internal.h"
+#include "libavutil/imgutils.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/opt.h"
+#include "libavcodec/apng.h"
+#include "libavcodec/png.h"
+#include "libavcodec/bytestream.h"
+
+#define DEFAULT_APNG_FPS 15
+
+typedef struct APNGDemuxContext {
+ const AVClass *class;
+
+ int max_fps;
+ int default_fps;
+
+ int64_t pkt_pts;
+ int pkt_duration;
+
+ int is_key_frame;
+
+ /*
+ * loop options
+ */
+ int ignore_loop;
+ uint32_t num_frames;
+ uint32_t num_play;
+ uint32_t cur_loop;
+} APNGDemuxContext;
+
+/*
+ * To be a valid APNG file, we mandate, in this order:
+ * PNGSIG
+ * IHDR
+ * ...
+ * acTL
+ * ...
+ * IDAT
+ */
+static int apng_probe(AVProbeData *p)
+{
+ GetByteContext gb;
+ int state = 0;
+ uint32_t len, tag;
+
+ bytestream2_init(&gb, p->buf, p->buf_size);
+
+ if (bytestream2_get_be64(&gb) != PNGSIG)
+ return 0;
+
+ for (;;) {
+ len = bytestream2_get_be32(&gb);
+ if (len > 0x7fffffff)
+ return 0;
+
+ tag = bytestream2_get_le32(&gb);
+ /* we don't check IDAT size, as this is the last tag
+ * we check, and it may be larger than the probe buffer */
+ if (tag != MKTAG('I', 'D', 'A', 'T') &&
+ len + 4 > bytestream2_get_bytes_left(&gb))
+ return 0;
+
+ switch (tag) {
+ case MKTAG('I', 'H', 'D', 'R'):
+ if (len != 13)
+ return 0;
+ if (av_image_check_size(bytestream2_get_be32(&gb), bytestream2_get_be32(&gb), 0, NULL))
+ return 0;
+ bytestream2_skip(&gb, 9);
+ state++;
+ break;
+ case MKTAG('a', 'c', 'T', 'L'):
+ if (state != 1 ||
+ len != 8 ||
+ bytestream2_get_be32(&gb) == 0) /* 0 is not a valid value for number of frames */
+ return 0;
+ bytestream2_skip(&gb, 8);
+ state++;
+ break;
+ case MKTAG('I', 'D', 'A', 'T'):
+ if (state != 2)
+ return 0;
+ goto end;
+ default:
+ /* skip other tags */
+ bytestream2_skip(&gb, len + 4);
+ break;
+ }
+ }
+
+end:
+ return AVPROBE_SCORE_MAX;
+}
+
+static int append_extradata(AVCodecContext *s, AVIOContext *pb, int len)
+{
+ int previous_size = s->extradata_size;
+ int new_size, ret;
+ uint8_t *new_extradata;
+
+ if (previous_size > INT_MAX - len)
+ return AVERROR_INVALIDDATA;
+
+ new_size = previous_size + len;
+ new_extradata = av_realloc(s->extradata, new_size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!new_extradata)
+ return AVERROR(ENOMEM);
+ s->extradata = new_extradata;
+ s->extradata_size = new_size;
+
+ if ((ret = avio_read(pb, s->extradata + previous_size, len)) < 0)
+ return ret;
+
+ return previous_size;
+}
+
+static int apng_read_header(AVFormatContext *s)
+{
+ APNGDemuxContext *ctx = s->priv_data;
+ AVIOContext *pb = s->pb;
+ uint32_t len, tag;
+ AVStream *st;
+ int acTL_found = 0;
+ int64_t ret = AVERROR_INVALIDDATA;
+
+ /* verify PNGSIG */
+ if (avio_rb64(pb) != PNGSIG)
+ return ret;
+
+ /* 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;
+
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ /* set the timebase to something large enough (1/100,000 of second)
+ * to hopefully cope with all sane frame durations */
+ avpriv_set_pts_info(st, 64, 1, 100000);
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = AV_CODEC_ID_APNG;
+ st->codec->width = avio_rb32(pb);
+ st->codec->height = avio_rb32(pb);
+ if ((ret = av_image_check_size(st->codec->width, st->codec->height, 0, s)) < 0)
+ return ret;
+
+ /* extradata will contain every chunk up to the first fcTL (excluded) */
+ st->codec->extradata = av_malloc(len + 12 + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (!st->codec->extradata)
+ return AVERROR(ENOMEM);
+ st->codec->extradata_size = len + 12;
+ AV_WB32(st->codec->extradata, len);
+ AV_WL32(st->codec->extradata+4, tag);
+ AV_WB32(st->codec->extradata+8, st->codec->width);
+ AV_WB32(st->codec->extradata+12, st->codec->height);
+ if ((ret = avio_read(pb, st->codec->extradata+16, 9)) < 0)
+ goto fail;
+
+ while (!avio_feof(pb)) {
+ 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;
+ } else if (offset < 0) {
+ ret = offset;
+ goto fail;
+ } 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;
+ }
+ }
+ if ((ctx->num_play == 1 || !acTL_found) &&
+ ((ret = ffio_ensure_seekback(pb, 4 /* len */ + 4 /* tag */)) < 0))
+ goto fail;
+
+ len = avio_rb32(pb);
+ if (len > 0x7fffffff) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ 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->codec, pb, len + 12)) < 0)
+ goto fail;
+ acTL_found = 1;
+ ctx->num_frames = AV_RB32(st->codec->extradata + ret + 8);
+ ctx->num_play = AV_RB32(st->codec->extradata + ret + 12);
+ av_log(s, AV_LOG_DEBUG, "num_frames: %"PRIu32", num_play: %"PRIu32"\n",
+ ctx->num_frames, ctx->num_play);
+ break;
+ case MKTAG('f', 'c', 'T', 'L'):
+ if (!acTL_found) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0)
+ goto fail;
+ return 0;
+ default:
+ if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||
+ (ret = append_extradata(st->codec, pb, len + 12)) < 0)
+ goto fail;
+ }
+ }
+
+fail:
+ if (st->codec->extradata_size) {
+ av_freep(&st->codec->extradata);
+ st->codec->extradata_size = 0;
+ }
+ return ret;
+}
+
+static int decode_fctl_chunk(AVFormatContext *s, APNGDemuxContext *ctx, AVPacket *pkt)
+{
+ uint32_t sequence_number, width, height, x_offset, y_offset;
+ uint16_t delay_num, delay_den;
+ uint8_t dispose_op, blend_op;
+
+ sequence_number = avio_rb32(s->pb);
+ width = avio_rb32(s->pb);
+ height = avio_rb32(s->pb);
+ x_offset = avio_rb32(s->pb);
+ y_offset = avio_rb32(s->pb);
+ delay_num = avio_rb16(s->pb);
+ delay_den = avio_rb16(s->pb);
+ dispose_op = avio_r8(s->pb);
+ blend_op = avio_r8(s->pb);
+ avio_skip(s->pb, 4); /* crc */
+
+ /* default is hundredths of seconds */
+ if (!delay_den)
+ delay_den = 100;
+ if (!delay_num || (ctx->max_fps && delay_den / delay_num > ctx->max_fps)) {
+ delay_num = 1;
+ delay_den = ctx->default_fps;
+ }
+ ctx->pkt_duration = av_rescale_q(delay_num,
+ (AVRational){ 1, delay_den },
+ s->streams[0]->time_base);
+
+ av_log(s, AV_LOG_DEBUG, "%s: "
+ "sequence_number: %"PRId32", "
+ "width: %"PRIu32", "
+ "height: %"PRIu32", "
+ "x_offset: %"PRIu32", "
+ "y_offset: %"PRIu32", "
+ "delay_num: %"PRIu16", "
+ "delay_den: %"PRIu16", "
+ "dispose_op: %d, "
+ "blend_op: %d\n",
+ __FUNCTION__,
+ sequence_number,
+ width,
+ height,
+ x_offset,
+ y_offset,
+ delay_num,
+ delay_den,
+ dispose_op,
+ blend_op);
+
+ if (width != s->streams[0]->codec->width ||
+ height != s->streams[0]->codec->height ||
+ x_offset != 0 ||
+ y_offset != 0) {
+ if (sequence_number == 0 ||
+ x_offset >= s->streams[0]->codec->width ||
+ width > s->streams[0]->codec->width - x_offset ||
+ y_offset >= s->streams[0]->codec->height ||
+ height > s->streams[0]->codec->height - y_offset)
+ return AVERROR_INVALIDDATA;
+ ctx->is_key_frame = 0;
+ } else {
+ if (sequence_number == 0 && dispose_op == APNG_DISPOSE_OP_PREVIOUS)
+ dispose_op = APNG_DISPOSE_OP_BACKGROUND;
+ ctx->is_key_frame = dispose_op == APNG_DISPOSE_OP_BACKGROUND ||
+ blend_op == APNG_BLEND_OP_SOURCE;
+ }
+
+ return 0;
+}
+
+static int apng_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ APNGDemuxContext *ctx = s->priv_data;
+ int64_t ret;
+ int64_t size;
+ AVIOContext *pb = s->pb;
+ uint32_t len, tag;
+
+ /*
+ * fcTL chunk length, in bytes:
+ * 4 (length)
+ * 4 (tag)
+ * 26 (actual chunk)
+ * 4 (crc) bytes
+ * and needed next:
+ * 4 (length)
+ * 4 (tag (must be fdAT or IDAT))
+ */
+ /* if num_play is not 1, then the seekback is already guaranteed */
+ if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 46)) < 0)
+ return ret;
+
+ len = avio_rb32(pb);
+ tag = avio_rl32(pb);
+ switch (tag) {
+ case MKTAG('f', 'c', 'T', 'L'):
+ if (len != 26)
+ return AVERROR_INVALIDDATA;
+
+ if ((ret = decode_fctl_chunk(s, ctx, pkt)) < 0)
+ return ret;
+
+ /* fcTL must precede fdAT or IDAT */
+ len = avio_rb32(pb);
+ tag = avio_rl32(pb);
+ if (len > 0x7fffffff ||
+ tag != MKTAG('f', 'd', 'A', 'T') &&
+ tag != MKTAG('I', 'D', 'A', 'T'))
+ return AVERROR_INVALIDDATA;
+
+ size = 38 /* fcTL */ + 8 /* len, tag */ + len + 4 /* crc */;
+ if (size > INT_MAX)
+ return AVERROR(EINVAL);
+
+ if ((ret = avio_seek(pb, -46, SEEK_CUR)) < 0 ||
+ (ret = av_append_packet(pb, pkt, size)) < 0)
+ return ret;
+
+ if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 8)) < 0)
+ return ret;
+
+ len = avio_rb32(pb);
+ tag = avio_rl32(pb);
+ while (tag &&
+ tag != MKTAG('f', 'c', 'T', 'L') &&
+ tag != MKTAG('I', 'E', 'N', 'D')) {
+ if (len > 0x7fffffff)
+ return AVERROR_INVALIDDATA;
+ if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0 ||
+ (ret = av_append_packet(pb, pkt, len + 12)) < 0)
+ return ret;
+ if (ctx->num_play == 1 && (ret = ffio_ensure_seekback(pb, 8)) < 0)
+ return ret;
+ len = avio_rb32(pb);
+ tag = avio_rl32(pb);
+ }
+ if ((ret = avio_seek(pb, -8, SEEK_CUR)) < 0)
+ return ret;
+
+ if (ctx->is_key_frame)
+ pkt->flags |= AV_PKT_FLAG_KEY;
+ pkt->pts = ctx->pkt_pts;
+ pkt->duration = ctx->pkt_duration;
+ ctx->pkt_pts += ctx->pkt_duration;
+ return ret;
+ case MKTAG('I', 'E', 'N', 'D'):
+ ctx->cur_loop++;
+ if (ctx->ignore_loop || ctx->num_play >= 1 && ctx->cur_loop == ctx->num_play) {
+ avio_seek(pb, -8, SEEK_CUR);
+ return AVERROR_EOF;
+ }
+ if ((ret = avio_seek(pb, s->streams[0]->codec->extradata_size + 8, SEEK_SET)) < 0)
+ return ret;
+ return 0;
+ default:
+ {
+ char tag_buf[32];
+
+ av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag);
+ avpriv_request_sample(s, "In-stream tag=%s (0x%08X) len=%"PRIu32, tag_buf, tag, len);
+ avio_skip(pb, len + 4);
+ }
+ }
+
+ /* Handle the unsupported yet cases */
+ return AVERROR_PATCHWELCOME;
+}
+
+static const AVOption options[] = {
+ { "ignore_loop", "ignore loop setting" , offsetof(APNGDemuxContext, ignore_loop),
+ AV_OPT_TYPE_INT, { .i64 = 1 } , 0, 1 , AV_OPT_FLAG_DECODING_PARAM },
+ { "max_fps" , "maximum framerate (0 is no limit)" , offsetof(APNGDemuxContext, max_fps),
+ AV_OPT_TYPE_INT, { .i64 = DEFAULT_APNG_FPS }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { "default_fps", "default framerate (0 is as fast as possible)", offsetof(APNGDemuxContext, default_fps),
+ AV_OPT_TYPE_INT, { .i64 = DEFAULT_APNG_FPS }, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
+ { NULL },
+};
+
+static const AVClass demuxer_class = {
+ .class_name = "APNG demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+ .category = AV_CLASS_CATEGORY_DEMUXER,
+};
+
+AVInputFormat ff_apng_demuxer = {
+ .name = "apng",
+ .long_name = NULL_IF_CONFIG_SMALL("Animated Portable Network Graphics"),
+ .priv_data_size = sizeof(APNGDemuxContext),
+ .read_probe = apng_probe,
+ .read_header = apng_read_header,
+ .read_packet = apng_read_packet,
+ .flags = AVFMT_GENERIC_INDEX,
+ .priv_class = &demuxer_class,
+};
diff --git a/ffmpeg-2-8-11/libavformat/apngenc.c b/ffmpeg-2-8-12/libavformat/apngenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/apngenc.c
rename to ffmpeg-2-8-12/libavformat/apngenc.c
diff --git a/ffmpeg-2-8-11/libavformat/aqtitledec.c b/ffmpeg-2-8-12/libavformat/aqtitledec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/aqtitledec.c
rename to ffmpeg-2-8-12/libavformat/aqtitledec.c
diff --git a/ffmpeg-2-8-11/libavformat/asf.c b/ffmpeg-2-8-12/libavformat/asf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/asf.c
rename to ffmpeg-2-8-12/libavformat/asf.c
diff --git a/ffmpeg-2-8-11/libavformat/asf.h b/ffmpeg-2-8-12/libavformat/asf.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/asf.h
rename to ffmpeg-2-8-12/libavformat/asf.h
diff --git a/ffmpeg-2-8-11/libavformat/asfcrypt.c b/ffmpeg-2-8-12/libavformat/asfcrypt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/asfcrypt.c
rename to ffmpeg-2-8-12/libavformat/asfcrypt.c
diff --git a/ffmpeg-2-8-11/libavformat/asfcrypt.h b/ffmpeg-2-8-12/libavformat/asfcrypt.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/asfcrypt.h
rename to ffmpeg-2-8-12/libavformat/asfcrypt.h
diff --git a/ffmpeg-2-8-11/libavformat/asfdec_f.c b/ffmpeg-2-8-12/libavformat/asfdec_f.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/asfdec_f.c
rename to ffmpeg-2-8-12/libavformat/asfdec_f.c
diff --git a/ffmpeg-2-8-11/libavformat/asfdec_o.c b/ffmpeg-2-8-12/libavformat/asfdec_o.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/asfdec_o.c
rename to ffmpeg-2-8-12/libavformat/asfdec_o.c
diff --git a/ffmpeg-2-8-11/libavformat/asfenc.c b/ffmpeg-2-8-12/libavformat/asfenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/asfenc.c
rename to ffmpeg-2-8-12/libavformat/asfenc.c
diff --git a/ffmpeg-2-8-11/libavformat/assdec.c b/ffmpeg-2-8-12/libavformat/assdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/assdec.c
rename to ffmpeg-2-8-12/libavformat/assdec.c
diff --git a/ffmpeg-2-8-11/libavformat/assenc.c b/ffmpeg-2-8-12/libavformat/assenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/assenc.c
rename to ffmpeg-2-8-12/libavformat/assenc.c
diff --git a/ffmpeg-2-8-11/libavformat/ast.c b/ffmpeg-2-8-12/libavformat/ast.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ast.c
rename to ffmpeg-2-8-12/libavformat/ast.c
diff --git a/ffmpeg-2-8-11/libavformat/ast.h b/ffmpeg-2-8-12/libavformat/ast.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ast.h
rename to ffmpeg-2-8-12/libavformat/ast.h
diff --git a/ffmpeg-2-8-11/libavformat/astdec.c b/ffmpeg-2-8-12/libavformat/astdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/astdec.c
rename to ffmpeg-2-8-12/libavformat/astdec.c
diff --git a/ffmpeg-2-8-11/libavformat/astenc.c b/ffmpeg-2-8-12/libavformat/astenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/astenc.c
rename to ffmpeg-2-8-12/libavformat/astenc.c
diff --git a/ffmpeg-2-8-11/libavformat/async.c b/ffmpeg-2-8-12/libavformat/async.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/async.c
rename to ffmpeg-2-8-12/libavformat/async.c
diff --git a/ffmpeg-2-8-11/libavformat/au.c b/ffmpeg-2-8-12/libavformat/au.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/au.c
rename to ffmpeg-2-8-12/libavformat/au.c
diff --git a/ffmpeg-2-8-11/libavformat/audiointerleave.c b/ffmpeg-2-8-12/libavformat/audiointerleave.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/audiointerleave.c
rename to ffmpeg-2-8-12/libavformat/audiointerleave.c
diff --git a/ffmpeg-2-8-11/libavformat/audiointerleave.h b/ffmpeg-2-8-12/libavformat/audiointerleave.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/audiointerleave.h
rename to ffmpeg-2-8-12/libavformat/audiointerleave.h
diff --git a/ffmpeg-2-8-11/libavformat/avc.c b/ffmpeg-2-8-12/libavformat/avc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/avc.c
rename to ffmpeg-2-8-12/libavformat/avc.c
diff --git a/ffmpeg-2-8-11/libavformat/avc.h b/ffmpeg-2-8-12/libavformat/avc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/avc.h
rename to ffmpeg-2-8-12/libavformat/avc.h
diff --git a/ffmpeg-2-8-11/libavformat/avformat.h b/ffmpeg-2-8-12/libavformat/avformat.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/avformat.h
rename to ffmpeg-2-8-12/libavformat/avformat.h
diff --git a/ffmpeg-2-8-11/libavformat/avformatres.rc b/ffmpeg-2-8-12/libavformat/avformatres.rc
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/avformatres.rc
rename to ffmpeg-2-8-12/libavformat/avformatres.rc
diff --git a/ffmpeg-2-8-11/libavformat/avi.h b/ffmpeg-2-8-12/libavformat/avi.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/avi.h
rename to ffmpeg-2-8-12/libavformat/avi.h
diff --git a/ffmpeg-2-8-12/libavformat/avidec.c b/ffmpeg-2-8-12/libavformat/avidec.c
new file mode 100644
index 0000000..223ddd0
--- /dev/null
+++ b/ffmpeg-2-8-12/libavformat/avidec.c
@@ -0,0 +1,1941 @@
+/*
+ * AVI demuxer
+ * Copyright (c) 2001 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <inttypes.h>
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/bswap.h"
+#include "libavutil/opt.h"
+#include "libavutil/dict.h"
+#include "libavutil/internal.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
+#include "avformat.h"
+#include "avi.h"
+#include "dv.h"
+#include "internal.h"
+#include "isom.h"
+#include "riff.h"
+#include "libavcodec/bytestream.h"
+#include "libavcodec/exif.h"
+#include "libavcodec/internal.h"
+
+typedef struct AVIStream {
+ int64_t frame_offset; /* current frame (video) or byte (audio) counter
+ * (used to compute the pts) */
+ int remaining;
+ int packet_size;
+
+ uint32_t handler;
+ uint32_t scale;
+ uint32_t rate;
+ int sample_size; /* size of one sample (or packet)
+ * (in the rate/scale sense) in bytes */
+
+ int64_t cum_len; /* temporary storage (used during seek) */
+ int prefix; /* normally 'd'<<8 + 'c' or 'w'<<8 + 'b' */
+ int prefix_count;
+ uint32_t pal[256];
+ int has_pal;
+ int dshow_block_align; /* block align variable used to emulate bugs in
+ * the MS dshow demuxer */
+
+ AVFormatContext *sub_ctx;
+ AVPacket sub_pkt;
+ uint8_t *sub_buffer;
+
+ int64_t seek_pos;
+} AVIStream;
+
+typedef struct AVIContext {
+ const AVClass *class;
+ int64_t riff_end;
+ int64_t movi_end;
+ int64_t fsize;
+ int64_t io_fsize;
+ int64_t movi_list;
+ int64_t last_pkt_pos;
+ int index_loaded;
+ int is_odml;
+ int non_interleaved;
+ int stream_index;
+ DVDemuxContext *dv_demux;
+ int odml_depth;
+ int use_odml;
+#define MAX_ODML_DEPTH 1000
+ int64_t dts_max;
+} AVIContext;
+
+
+static const AVOption options[] = {
+ { "use_odml", "use odml index", offsetof(AVIContext, use_odml), AV_OPT_TYPE_INT, {.i64 = 1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM},
+ { NULL },
+};
+
+static const AVClass demuxer_class = {
+ .class_name = "avi",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+ .category = AV_CLASS_CATEGORY_DEMUXER,
+};
+
+
+static const char avi_headers[][8] = {
+ { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' ' },
+ { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X' },
+ { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19 },
+ { 'O', 'N', '2', ' ', 'O', 'N', '2', 'f' },
+ { 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' ' },
+ { 0 }
+};
+
+static const AVMetadataConv avi_metadata_conv[] = {
+ { "strn", "title" },
+ { 0 },
+};
+
+static int avi_load_index(AVFormatContext *s);
+static int guess_ni_flag(AVFormatContext *s);
+
+#define print_tag(str, tag, size) \
+ av_log(NULL, AV_LOG_TRACE, "pos:%"PRIX64" %s: tag=%c%c%c%c size=0x%x\n", \
+ avio_tell(pb), str, tag & 0xff, \
+ (tag >> 8) & 0xff, \
+ (tag >> 16) & 0xff, \
+ (tag >> 24) & 0xff, \
+ size)
+
+static inline int get_duration(AVIStream *ast, int len)
+{
+ if (ast->sample_size)
+ return len;
+ else if (ast->dshow_block_align)
+ return (len + ast->dshow_block_align - 1) / ast->dshow_block_align;
+ else
+ return 1;
+}
+
+static int get_riff(AVFormatContext *s, AVIOContext *pb)
+{
+ AVIContext *avi = s->priv_data;
+ char header[8] = {0};
+ int i;
+
+ /* check RIFF header */
+ avio_read(pb, header, 4);
+ avi->riff_end = avio_rl32(pb); /* RIFF chunk size */
+ avi->riff_end += avio_tell(pb); /* RIFF chunk end */
+ avio_read(pb, header + 4, 4);
+
+ for (i = 0; avi_headers[i][0]; i++)
+ if (!memcmp(header, avi_headers[i], 8))
+ break;
+ if (!avi_headers[i][0])
+ return AVERROR_INVALIDDATA;
+
+ if (header[7] == 0x19)
+ av_log(s, AV_LOG_INFO,
+ "This file has been generated by a totally broken muxer.\n");
+
+ return 0;
+}
+
+static int read_braindead_odml_indx(AVFormatContext *s, int frame_num)
+{
+ AVIContext *avi = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int longs_pre_entry = avio_rl16(pb);
+ int index_sub_type = avio_r8(pb);
+ int index_type = avio_r8(pb);
+ int entries_in_use = avio_rl32(pb);
+ int chunk_id = avio_rl32(pb);
+ int64_t base = avio_rl64(pb);
+ int stream_id = ((chunk_id & 0xFF) - '0') * 10 +
+ ((chunk_id >> 8 & 0xFF) - '0');
+ AVStream *st;
+ AVIStream *ast;
+ int i;
+ int64_t last_pos = -1;
+ int64_t filesize = avi->fsize;
+
+ av_log(s, AV_LOG_TRACE,
+ "longs_pre_entry:%d index_type:%d entries_in_use:%d "
+ "chunk_id:%X base:%16"PRIX64" frame_num:%d\n",
+ longs_pre_entry,
+ index_type,
+ entries_in_use,
+ chunk_id,
+ base,
+ frame_num);
+
+ if (stream_id >= s->nb_streams || stream_id < 0)
+ return AVERROR_INVALIDDATA;
+ st = s->streams[stream_id];
+ ast = st->priv_data;
+
+ if (index_sub_type)
+ return AVERROR_INVALIDDATA;
+
+ avio_rl32(pb);
+
+ if (index_type && longs_pre_entry != 2)
+ return AVERROR_INVALIDDATA;
+ if (index_type > 1)
+ return AVERROR_INVALIDDATA;
+
+ if (filesize > 0 && base >= filesize) {
+ av_log(s, AV_LOG_ERROR, "ODML index invalid\n");
+ if (base >> 32 == (base & 0xFFFFFFFF) &&
+ (base & 0xFFFFFFFF) < filesize &&
+ filesize <= 0xFFFFFFFF)
+ base &= 0xFFFFFFFF;
+ else
+ return AVERROR_INVALIDDATA;
+ }
+
+ for (i = 0; i < entries_in_use; i++) {
+ if (index_type) {
+ int64_t pos = avio_rl32(pb) + base - 8;
+ int len = avio_rl32(pb);
+ int key = len >= 0;
+ len &= 0x7FFFFFFF;
+
+ av_log(s, AV_LOG_TRACE, "pos:%"PRId64", len:%X\n", pos, len);
+
+ if (avio_feof(pb))
+ return AVERROR_INVALIDDATA;
+
+ if (last_pos == pos || pos == base - 8)
+ avi->non_interleaved = 1;
+ if (last_pos != pos && len)
+ av_add_index_entry(st, pos, ast->cum_len, len, 0,
+ key ? AVINDEX_KEYFRAME : 0);
+
+ ast->cum_len += get_duration(ast, len);
+ last_pos = pos;
+ } else {
+ int64_t offset, pos;
+ int duration;
+ offset = avio_rl64(pb);
+ avio_rl32(pb); /* size */
+ duration = avio_rl32(pb);
+
+ if (avio_feof(pb))
+ return AVERROR_INVALIDDATA;
+
+ pos = avio_tell(pb);
+
+ if (avi->odml_depth > MAX_ODML_DEPTH) {
+ av_log(s, AV_LOG_ERROR, "Too deeply nested ODML indexes\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (avio_seek(pb, offset + 8, SEEK_SET) < 0)
+ return -1;
+ avi->odml_depth++;
+ read_braindead_odml_indx(s, frame_num);
+ avi->odml_depth--;
+ frame_num += duration;
+
+ if (avio_seek(pb, pos, SEEK_SET) < 0) {
+ av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index\n");
+ return -1;
+ }
+
+ }
+ }
+ avi->index_loaded = 2;
+ return 0;
+}
+
+static void clean_index(AVFormatContext *s)
+{
+ int i;
+ int64_t j;
+
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ AVIStream *ast = st->priv_data;
+ int n = st->nb_index_entries;
+ int max = ast->sample_size;
+ int64_t pos, size, ts;
+
+ if (n != 1 || ast->sample_size == 0)
+ continue;
+
+ while (max < 1024)
+ max += max;
+
+ pos = st->index_entries[0].pos;
+ size = st->index_entries[0].size;
+ ts = st->index_entries[0].timestamp;
+
+ for (j = 0; j < size; j += max)
+ av_add_index_entry(st, pos + j, ts + j, FFMIN(max, size - j), 0,
+ AVINDEX_KEYFRAME);
+ }
+}
+
+static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag,
+ uint32_t size)
+{
+ AVIOContext *pb = s->pb;
+ char key[5] = { 0 };
+ char *value;
+
+ size += (size & 1);
+
+ if (size == UINT_MAX)
+ return AVERROR(EINVAL);
+ value = av_malloc(size + 1);
+ if (!value)
+ return AVERROR(ENOMEM);
+ if (avio_read(pb, value, size) != size)
+ return AVERROR_INVALIDDATA;
+ value[size] = 0;
+
+ AV_WL32(key, tag);
+
+ return av_dict_set(st ? &st->metadata : &s->metadata, key, value,
+ AV_DICT_DONT_STRDUP_VAL);
+}
+
+static const char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
+
+static void avi_metadata_creation_time(AVDictionary **metadata, char *date)
+{
+ char month[4], time[9], buffer[64];
+ int i, day, year;
+ /* parse standard AVI date format (ie. "Mon Mar 10 15:04:43 2003") */
+ if (sscanf(date, "%*3s%*[ ]%3s%*[ ]%2d%*[ ]%8s%*[ ]%4d",
+ month, &day, time, &year) == 4) {
+ for (i = 0; i < 12; i++)
+ if (!av_strcasecmp(month, months[i])) {
+ snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s",
+ year, i + 1, day, time);
+ av_dict_set(metadata, "creation_time", buffer, 0);
+ }
+ } else if (date[4] == '/' && date[7] == '/') {
+ date[4] = date[7] = '-';
+ av_dict_set(metadata, "creation_time", date, 0);
+ }
+}
+
+static void avi_read_nikon(AVFormatContext *s, uint64_t end)
+{
+ while (avio_tell(s->pb) < end && !avio_feof(s->pb)) {
+ uint32_t tag = avio_rl32(s->pb);
+ uint32_t size = avio_rl32(s->pb);
+ switch (tag) {
+ case MKTAG('n', 'c', 't', 'g'): /* Nikon Tags */
+ {
+ uint64_t tag_end = avio_tell(s->pb) + size;
+ while (avio_tell(s->pb) < tag_end && !avio_feof(s->pb)) {
+ uint16_t tag = avio_rl16(s->pb);
+ uint16_t size = avio_rl16(s->pb);
+ const char *name = NULL;
+ char buffer[64] = { 0 };
+ size = FFMIN(size, tag_end - avio_tell(s->pb));
+ size -= avio_read(s->pb, buffer,
+ FFMIN(size, sizeof(buffer) - 1));
+ switch (tag) {
+ case 0x03:
+ name = "maker";
+ break;
+ case 0x04:
+ name = "model";
+ break;
+ case 0x13:
+ name = "creation_time";
+ if (buffer[4] == ':' && buffer[7] == ':')
+ buffer[4] = buffer[7] = '-';
+ break;
+ }
+ if (name)
+ av_dict_set(&s->metadata, name, buffer, 0);
+ avio_skip(s->pb, size);
+ }
+ break;
+ }
+ default:
+ avio_skip(s->pb, size);
+ break;
+ }
+ }
+}
+
+static int avi_extract_stream_metadata(AVStream *st)
+{
+ GetByteContext gb;
+ uint8_t *data = st->codec->extradata;
+ int data_size = st->codec->extradata_size;
+ int tag, offset;
+
+ if (!data || data_size < 8) {
+ return AVERROR_INVALIDDATA;
+ }
+
+ bytestream2_init(&gb, data, data_size);
+
+ tag = bytestream2_get_le32(&gb);
+
+ switch (tag) {
+ case MKTAG('A', 'V', 'I', 'F'):
+ // skip 4 byte padding
+ bytestream2_skip(&gb, 4);
+ offset = bytestream2_tell(&gb);
+ bytestream2_init(&gb, data + offset, data_size - offset);
+
+ // decode EXIF tags from IFD, AVI is always little-endian
+ return avpriv_exif_decode_ifd(st->codec, &gb, 1, 0, &st->metadata);
+ break;
+ case MKTAG('C', 'A', 'S', 'I'):
+ avpriv_request_sample(st->codec, "RIFF stream data tag type CASI (%u)", tag);
+ break;
+ case MKTAG('Z', 'o', 'r', 'a'):
+ avpriv_request_sample(st->codec, "RIFF stream data tag type Zora (%u)", tag);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int calculate_bitrate(AVFormatContext *s)
+{
+ AVIContext *avi = s->priv_data;
+ int i, j;
+ int64_t lensum = 0;
+ int64_t maxpos = 0;
+
+ for (i = 0; i<s->nb_streams; i++) {
+ int64_t len = 0;
+ AVStream *st = s->streams[i];
+
+ if (!st->nb_index_entries)
+ continue;
+
+ for (j = 0; j < st->nb_index_entries; j++)
+ len += st->index_entries[j].size;
+ maxpos = FFMAX(maxpos, st->index_entries[j-1].pos);
+ lensum += len;
+ }
+ if (maxpos < avi->io_fsize*9/10) // index does not cover the whole file
+ return 0;
+ if (lensum*9/10 > maxpos || lensum < maxpos*9/10) // frame sum and filesize mismatch
+ return 0;
+
+ for (i = 0; i<s->nb_streams; i++) {
+ int64_t len = 0;
+ AVStream *st = s->streams[i];
+ int64_t duration;
+ int64_t bitrate;
+
+ for (j = 0; j < st->nb_index_entries; j++)
+ len += st->index_entries[j].size;
+
+ if (st->nb_index_entries < 2 || st->codec->bit_rate > 0)
+ continue;
+ duration = st->index_entries[j-1].timestamp - st->index_entries[0].timestamp;
+ bitrate = av_rescale(8*len, st->time_base.den, duration * st->time_base.num);
+ if (bitrate <= INT_MAX && bitrate > 0) {
+ st->codec->bit_rate = bitrate;
+ }
+ }
+ return 1;
+}
+
+static int avi_read_header(AVFormatContext *s)
+{
+ AVIContext *avi = s->priv_data;
+ AVIOContext *pb = s->pb;
+ unsigned int tag, tag1, handler;
+ int codec_type, stream_index, frame_period;
+ unsigned int size;
+ int i;
+ AVStream *st;
+ AVIStream *ast = NULL;
+ int avih_width = 0, avih_height = 0;
+ int amv_file_format = 0;
+ uint64_t list_end = 0;
+ int ret;
+ AVDictionaryEntry *dict_entry;
+
+ avi->stream_index = -1;
+
+ ret = get_riff(s, pb);
+ if (ret < 0)
+ return ret;
+
+ av_log(avi, AV_LOG_DEBUG, "use odml:%d\n", avi->use_odml);
+
+ avi->io_fsize = avi->fsize = avio_size(pb);
+ if (avi->fsize <= 0 || avi->fsize < avi->riff_end)
+ avi->fsize = avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
+
+ /* first list tag */
+ stream_index = -1;
+ codec_type = -1;
+ frame_period = 0;
+ for (;;) {
+ if (avio_feof(pb))
+ goto fail;
+ tag = avio_rl32(pb);
+ size = avio_rl32(pb);
+
+ print_tag("tag", tag, size);
+
+ switch (tag) {
+ case MKTAG('L', 'I', 'S', 'T'):
+ list_end = avio_tell(pb) + size;
+ /* Ignored, except at start of video packets. */
+ tag1 = avio_rl32(pb);
+
+ print_tag("list", tag1, 0);
+
+ if (tag1 == MKTAG('m', 'o', 'v', 'i')) {
+ avi->movi_list = avio_tell(pb) - 4;
+ if (size)
+ avi->movi_end = avi->movi_list + size + (size & 1);
+ else
+ avi->movi_end = avi->fsize;
+ av_log(NULL, AV_LOG_TRACE, "movi end=%"PRIx64"\n", avi->movi_end);
+ goto end_of_header;
+ } else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
+ ff_read_riff_info(s, size - 4);
+ else if (tag1 == MKTAG('n', 'c', 'd', 't'))
+ avi_read_nikon(s, list_end);
+
+ break;
+ case MKTAG('I', 'D', 'I', 'T'):
+ {
+ unsigned char date[64] = { 0 };
+ size += (size & 1);
+ size -= avio_read(pb, date, FFMIN(size, sizeof(date) - 1));
+ avio_skip(pb, size);
+ avi_metadata_creation_time(&s->metadata, date);
+ break;
+ }
+ case MKTAG('d', 'm', 'l', 'h'):
+ avi->is_odml = 1;
+ avio_skip(pb, size + (size & 1));
+ break;
+ case MKTAG('a', 'm', 'v', 'h'):
+ amv_file_format = 1;
+ case MKTAG('a', 'v', 'i', 'h'):
+ /* AVI header */
+ /* using frame_period is bad idea */
+ frame_period = avio_rl32(pb);
+ avio_rl32(pb); /* max. bytes per second */
+ avio_rl32(pb);
+ avi->non_interleaved |= avio_rl32(pb) & AVIF_MUSTUSEINDEX;
+
+ avio_skip(pb, 2 * 4);
+ avio_rl32(pb);
+ avio_rl32(pb);
+ avih_width = avio_rl32(pb);
+ avih_height = avio_rl32(pb);
+
+ avio_skip(pb, size - 10 * 4);
+ break;
+ case MKTAG('s', 't', 'r', 'h'):
+ /* stream header */
+
+ tag1 = avio_rl32(pb);
+ handler = avio_rl32(pb); /* codec tag */
+
+ if (tag1 == MKTAG('p', 'a', 'd', 's')) {
+ avio_skip(pb, size - 8);
+ break;
+ } else {
+ stream_index++;
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ goto fail;
+
+ st->id = stream_index;
+ ast = av_mallocz(sizeof(AVIStream));
+ if (!ast)
+ goto fail;
+ st->priv_data = ast;
+ }
+ if (amv_file_format)
+ tag1 = stream_index ? MKTAG('a', 'u', 'd', 's')
+ : MKTAG('v', 'i', 'd', 's');
+
+ print_tag("strh", tag1, -1);
+
+ if (tag1 == MKTAG('i', 'a', 'v', 's') ||
+ tag1 == MKTAG('i', 'v', 'a', 's')) {
+ int64_t dv_dur;
+
+ /* After some consideration -- I don't think we
+ * have to support anything but DV in type1 AVIs. */
+ if (s->nb_streams != 1)
+ goto fail;
+
+ if (handler != MKTAG('d', 'v', 's', 'd') &&
+ handler != MKTAG('d', 'v', 'h', 'd') &&
+ handler != MKTAG('d', 'v', 's', 'l'))
+ goto fail;
+
+ ast = s->streams[0]->priv_data;
+ av_freep(&s->streams[0]->codec->extradata);
+ av_freep(&s->streams[0]->codec);
+ if (s->streams[0]->info)
+ av_freep(&s->streams[0]->info->duration_error);
+ av_freep(&s->streams[0]->info);
+ av_freep(&s->streams[0]);
+ s->nb_streams = 0;
+ if (CONFIG_DV_DEMUXER) {
+ avi->dv_demux = avpriv_dv_init_demux(s);
+ if (!avi->dv_demux)
+ goto fail;
+ } else
+ goto fail;
+ s->streams[0]->priv_data = ast;
+ avio_skip(pb, 3 * 4);
+ ast->scale = avio_rl32(pb);
+ ast->rate = avio_rl32(pb);
+ avio_skip(pb, 4); /* start time */
+
+ dv_dur = avio_rl32(pb);
+ if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) {
+ dv_dur *= AV_TIME_BASE;
+ s->duration = av_rescale(dv_dur, ast->scale, ast->rate);
+ }
+ /* else, leave duration alone; timing estimation in utils.c
+ * will make a guess based on bitrate. */
+
+ stream_index = s->nb_streams - 1;
+ avio_skip(pb, size - 9 * 4);
+ break;
+ }
+
+ av_assert0(stream_index < s->nb_streams);
+ ast->handler = handler;
+
+ avio_rl32(pb); /* flags */
+ avio_rl16(pb); /* priority */
+ avio_rl16(pb); /* language */
+ avio_rl32(pb); /* initial frame */
+ ast->scale = avio_rl32(pb);
+ ast->rate = avio_rl32(pb);
+ if (!(ast->scale && ast->rate)) {
+ av_log(s, AV_LOG_WARNING,
+ "scale/rate is %"PRIu32"/%"PRIu32" which is invalid. "
+ "(This file has been generated by broken software.)\n",
+ ast->scale,
+ ast->rate);
+ if (frame_period) {
+ ast->rate = 1000000;
+ ast->scale = frame_period;
+ } else {
+ ast->rate = 25;
+ ast->scale = 1;
+ }
+ }
+ avpriv_set_pts_info(st, 64, ast->scale, ast->rate);
+
+ ast->cum_len = avio_rl32(pb); /* start */
+ st->nb_frames = avio_rl32(pb);
+
+ st->start_time = 0;
+ avio_rl32(pb); /* buffer size */
+ avio_rl32(pb); /* quality */
+ if (ast->cum_len*ast->scale/ast->rate > 3600) {
+ av_log(s, AV_LOG_ERROR, "crazy start time, iam scared, giving up\n");
+ ast->cum_len = 0;
+ }
+ ast->sample_size = avio_rl32(pb); /* sample ssize */
+ ast->cum_len *= FFMAX(1, ast->sample_size);
+ av_log(s, AV_LOG_TRACE, "%"PRIu32" %"PRIu32" %d\n",
+ ast->rate, ast->scale, ast->sample_size);
+
+ switch (tag1) {
+ case MKTAG('v', 'i', 'd', 's'):
+ codec_type = AVMEDIA_TYPE_VIDEO;
+
+ ast->sample_size = 0;
+ st->avg_frame_rate = av_inv_q(st->time_base);
+ break;
+ case MKTAG('a', 'u', 'd', 's'):
+ codec_type = AVMEDIA_TYPE_AUDIO;
+ break;
+ case MKTAG('t', 'x', 't', 's'):
+ codec_type = AVMEDIA_TYPE_SUBTITLE;
+ break;
+ case MKTAG('d', 'a', 't', 's'):
+ codec_type = AVMEDIA_TYPE_DATA;
+ break;
+ default:
+ av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1);
+ }
+
+ if (ast->sample_size < 0) {
+ if (s->error_recognition & AV_EF_EXPLODE) {
+ av_log(s, AV_LOG_ERROR,
+ "Invalid sample_size %d at stream %d\n",
+ ast->sample_size,
+ stream_index);
+ goto fail;
+ }
+ av_log(s, AV_LOG_WARNING,
+ "Invalid sample_size %d at stream %d "
+ "setting it to 0\n",
+ ast->sample_size,
+ stream_index);
+ ast->sample_size = 0;
+ }
+
+ if (ast->sample_size == 0) {
+ st->duration = st->nb_frames;
+ if (st->duration > 0 && avi->io_fsize > 0 && avi->riff_end > avi->io_fsize) {
+ av_log(s, AV_LOG_DEBUG, "File is truncated adjusting duration\n");
+ st->duration = av_rescale(st->duration, avi->io_fsize, avi->riff_end);
+ }
+ }
+ ast->frame_offset = ast->cum_len;
+ avio_skip(pb, size - 12 * 4);
+ break;
+ case MKTAG('s', 't', 'r', 'f'):
+ /* stream header */
+ if (!size)
+ break;
+ if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) {
+ avio_skip(pb, size);
+ } else {
+ uint64_t cur_pos = avio_tell(pb);
+ unsigned esize;
+ if (cur_pos < list_end)
+ size = FFMIN(size, list_end - cur_pos);
+ st = s->streams[stream_index];
+ if (st->codec->codec_type != AVMEDIA_TYPE_UNKNOWN) {
+ avio_skip(pb, size);
+ break;
+ }
+ switch (codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ if (amv_file_format) {
+ st->codec->width = avih_width;
+ st->codec->height = avih_height;
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_id = AV_CODEC_ID_AMV;
+ avio_skip(pb, size);
+ break;
+ }
+ tag1 = ff_get_bmp_header(pb, st, &esize);
+
+ if (tag1 == MKTAG('D', 'X', 'S', 'B') ||
+ tag1 == MKTAG('D', 'X', 'S', 'A')) {
+ st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+ st->codec->codec_tag = tag1;
+ st->codec->codec_id = AV_CODEC_ID_XSUB;
+ break;
+ }
+
+ if (size > 10 * 4 && size < (1 << 30) && size < avi->fsize) {
+ if (esize == size-1 && (esize&1)) {
+ st->codec->extradata_size = esize - 10 * 4;
+ } else
+ st->codec->extradata_size = size - 10 * 4;
+ if (ff_get_extradata(st->codec, pb, st->codec->extradata_size) < 0)
+ return AVERROR(ENOMEM);
+ }
+
+ // FIXME: check if the encoder really did this correctly
+ if (st->codec->extradata_size & 1)
+ avio_r8(pb);
+
+ /* Extract palette from extradata if bpp <= 8.
+ * This code assumes that extradata contains only palette.
+ * This is true for all paletted codecs implemented in
+ * FFmpeg. */
+ if (st->codec->extradata_size &&
+ (st->codec->bits_per_coded_sample <= 8)) {
+ int pal_size = (1 << st->codec->bits_per_coded_sample) << 2;
+ const uint8_t *pal_src;
+
+ pal_size = FFMIN(pal_size, st->codec->extradata_size);
+ pal_src = st->codec->extradata +
+ st->codec->extradata_size - pal_size;
+ /* Exclude the "BottomUp" field from the palette */
+ if (pal_src - st->codec->extradata >= 9 &&
+ !memcmp(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9))
+ pal_src -= 9;
+ for (i = 0; i < pal_size / 4; i++)
+ ast->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i);
+ ast->has_pal = 1;
+ }
+
+ print_tag("video", tag1, 0);
+
+ st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ st->codec->codec_tag = tag1;
+ st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags,
+ tag1);
+ /* If codec is not found yet, try with the mov tags. */
+ if (!st->codec->codec_id) {
+ char tag_buf[32];
+ av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag1);
+ st->codec->codec_id =
+ ff_codec_get_id(ff_codec_movvideo_tags, tag1);
+ if (st->codec->codec_id)
+ av_log(s, AV_LOG_WARNING,
+ "mov tag found in avi (fourcc %s)\n",
+ tag_buf);
+ }
+ /* This is needed to get the pict type which is necessary
+ * for generating correct pts. */
+ st->need_parsing = AVSTREAM_PARSE_HEADERS;
+
+ if (st->codec->codec_id == AV_CODEC_ID_MPEG4 &&
+ ast->handler == MKTAG('X', 'V', 'I', 'D'))
+ st->codec->codec_tag = MKTAG('X', 'V', 'I', 'D');
+
+ if (st->codec->codec_tag == MKTAG('V', 'S', 'S', 'H'))
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+
+ if (st->codec->codec_tag == 0 && st->codec->height > 0 &&
+ st->codec->extradata_size < 1U << 30) {
+ st->codec->extradata_size += 9;
+ if ((ret = av_reallocp(&st->codec->extradata,
+ st->codec->extradata_size +
+ AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
+ st->codec->extradata_size = 0;
+ return ret;
+ } else
+ memcpy(st->codec->extradata + st->codec->extradata_size - 9,
+ "BottomUp", 9);
+ }
+ st->codec->height = FFABS(st->codec->height);
+
+// avio_skip(pb, size - 5 * 4);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ ret = ff_get_wav_header(s, pb, st->codec, size, 0);
+ if (ret < 0)
+ return ret;
+ ast->dshow_block_align = st->codec->block_align;
+ if (ast->sample_size && st->codec->block_align &&
+ ast->sample_size != st->codec->block_align) {
+ av_log(s,
+ AV_LOG_WARNING,
+ "sample size (%d) != block align (%d)\n",
+ ast->sample_size,
+ st->codec->block_align);
+ ast->sample_size = st->codec->block_align;
+ }
+ /* 2-aligned
+ * (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
+ if (size & 1)
+ avio_skip(pb, 1);
+ /* Force parsing as several audio frames can be in
+ * one packet and timestamps refer to packet start. */
+ st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
+ /* ADTS header is in extradata, AAC without header must be
+ * stored as exact frames. Parser not needed and it will
+ * fail. */
+ if (st->codec->codec_id == AV_CODEC_ID_AAC &&
+ st->codec->extradata_size)
+ st->need_parsing = AVSTREAM_PARSE_NONE;
+ // The flac parser does not work with AVSTREAM_PARSE_TIMESTAMPS
+ if (st->codec->codec_id == AV_CODEC_ID_FLAC)
+ st->need_parsing = AVSTREAM_PARSE_NONE;
+ /* AVI files with Xan DPCM audio (wrongly) declare PCM
+ * audio in the header but have Axan as stream_code_tag. */
+ if (ast->handler == AV_RL32("Axan")) {
+ st->codec->codec_id = AV_CODEC_ID_XAN_DPCM;
+ st->codec->codec_tag = 0;
+ ast->dshow_block_align = 0;
+ }
+ if (amv_file_format) {
+ st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_AMV;
+ ast->dshow_block_align = 0;
+ }
+ if ((st->codec->codec_id == AV_CODEC_ID_AAC ||
+ st->codec->codec_id == AV_CODEC_ID_FLAC ||
+ st->codec->codec_id == AV_CODEC_ID_MP2 ) && ast->dshow_block_align <= 4 && ast->dshow_block_align) {
+ av_log(s, AV_LOG_DEBUG, "overriding invalid dshow_block_align of %d\n", ast->dshow_block_align);
+ ast->dshow_block_align = 0;
+ }
+ if (st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 1024 && ast->sample_size == 1024 ||
+ st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 4096 && ast->sample_size == 4096 ||
+ st->codec->codec_id == AV_CODEC_ID_MP3 && ast->dshow_block_align == 1152 && ast->sample_size == 1152) {
+ av_log(s, AV_LOG_DEBUG, "overriding sample_size\n");
+ ast->sample_size = 0;
+ }
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+ st->request_probe= 1;
+ avio_skip(pb, size);
+ break;
+ default:
+ st->codec->codec_type = AVMEDIA_TYPE_DATA;
+ st->codec->codec_id = AV_CODEC_ID_NONE;
+ st->codec->codec_tag = 0;
+ avio_skip(pb, size);
+ break;
+ }
+ }
+ break;
+ case MKTAG('s', 't', 'r', 'd'):
+ if (stream_index >= (unsigned)s->nb_streams
+ || s->streams[stream_index]->codec->extradata_size
+ || s->streams[stream_index]->codec->codec_tag == MKTAG('H','2','6','4')) {
+ avio_skip(pb, size);
+ } else {
+ uint64_t cur_pos = avio_tell(pb);
+ if (cur_pos < list_end)
+ size = FFMIN(size, list_end - cur_pos);
+ st = s->streams[stream_index];
+
+ if (size<(1<<30)) {
+ if (ff_get_extradata(st->codec, pb, size) < 0)
+ return AVERROR(ENOMEM);
+ }
+
+ if (st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
+ avio_r8(pb);
+
+ ret = avi_extract_stream_metadata(st);
+ if (ret < 0) {
+ av_log(s, AV_LOG_WARNING, "could not decoding EXIF data in stream header.\n");
+ }
+ }
+ break;
+ case MKTAG('i', 'n', 'd', 'x'):
+ i = avio_tell(pb);
+ if (pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) &&
+ avi->use_odml &&
+ read_braindead_odml_indx(s, 0) < 0 &&
+ (s->error_recognition & AV_EF_EXPLODE))
+ goto fail;
+ avio_seek(pb, i + size, SEEK_SET);
+ break;
+ case MKTAG('v', 'p', 'r', 'p'):
+ if (stream_index < (unsigned)s->nb_streams && size > 9 * 4) {
+ AVRational active, active_aspect;
+
+ st = s->streams[stream_index];
+ avio_rl32(pb);
+ avio_rl32(pb);
+ avio_rl32(pb);
+ avio_rl32(pb);
+ avio_rl32(pb);
+
+ active_aspect.den = avio_rl16(pb);
+ active_aspect.num = avio_rl16(pb);
+ active.num = avio_rl32(pb);
+ active.den = avio_rl32(pb);
+ avio_rl32(pb); // nbFieldsPerFrame
+
+ if (active_aspect.num && active_aspect.den &&
+ active.num && active.den) {
+ st->sample_aspect_ratio = av_div_q(active_aspect, active);
+ av_log(s, AV_LOG_TRACE, "vprp %d/%d %d/%d\n",
+ active_aspect.num, active_aspect.den,
+ active.num, active.den);
+ }
+ size -= 9 * 4;
+ }
+ avio_skip(pb, size);
+ break;
+ case MKTAG('s', 't', 'r', 'n'):
+ if (s->nb_streams) {
+ ret = avi_read_tag(s, s->streams[s->nb_streams - 1], tag, size);
+ if (ret < 0)
+ return ret;
+ break;
+ }
+ default:
+ if (size > 1000000) {
+ av_log(s, AV_LOG_ERROR,
+ "Something went wrong during header parsing, "
+ "I will ignore it and try to continue anyway.\n");
+ if (s->error_recognition & AV_EF_EXPLODE)
+ goto fail;
+ avi->movi_list = avio_tell(pb) - 4;
+ avi->movi_end = avi->fsize;
+ goto end_of_header;
+ }
+ /* skip tag */
+ size += (size & 1);
+ avio_skip(pb, size);
+ break;
+ }
+ }
+
+end_of_header:
+ /* check stream number */
+ if (stream_index != s->nb_streams - 1) {
+
+fail:
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!avi->index_loaded && pb->seekable)
+ avi_load_index(s);
+ calculate_bitrate(s);
+ avi->index_loaded |= 1;
+
+ if ((ret = guess_ni_flag(s)) < 0)
+ return ret;
+
+ avi->non_interleaved |= ret | (s->flags & AVFMT_FLAG_SORT_DTS);
+
+ dict_entry = av_dict_get(s->metadata, "ISFT", NULL, 0);
+ if (dict_entry && !strcmp(dict_entry->value, "PotEncoder"))
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ if ( st->codec->codec_id == AV_CODEC_ID_MPEG1VIDEO
+ || st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO)
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+ }
+
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ if (st->nb_index_entries)
+ break;
+ }
+ // DV-in-AVI cannot be non-interleaved, if set this must be
+ // a mis-detection.
+ if (avi->dv_demux)
+ avi->non_interleaved = 0;
+ if (i == s->nb_streams && avi->non_interleaved) {
+ av_log(s, AV_LOG_WARNING,
+ "Non-interleaved AVI without index, switching to interleaved\n");
+ avi->non_interleaved = 0;
+ }
+
+ if (avi->non_interleaved) {
+ av_log(s, AV_LOG_INFO, "non-interleaved AVI\n");
+ clean_index(s);
+ }
+
+ ff_metadata_conv_ctx(s, NULL, avi_metadata_conv);
+ ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
+
+ return 0;
+}
+
+static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt)
+{
+ if (pkt->size >= 7 &&
+ pkt->size < INT_MAX - AVPROBE_PADDING_SIZE &&
+ !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data + 5) == 2) {
+ uint8_t desc[256];
+ int score = AVPROBE_SCORE_EXTENSION, ret;
+ AVIStream *ast = st->priv_data;
+ AVInputFormat *sub_demuxer;
+ AVRational time_base;
+ int size;
+ 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 (desc_len > pb->buf_end - pb->buf_ptr)
+ goto error;
+
+ ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc));
+ avio_skip(pb, desc_len - ret);
+ if (*desc)
+ av_dict_set(&st->metadata, "title", desc, 0);
+
+ avio_rl16(pb); /* flags? */
+ avio_rl32(pb); /* data size */
+
+ size = pb->buf_end - pb->buf_ptr;
+ pd = (AVProbeData) { .buf = av_mallocz(size + AVPROBE_PADDING_SIZE),
+ .buf_size = size };
+ if (!pd.buf)
+ goto error;
+ memcpy(pd.buf, pb->buf_ptr, size);
+ sub_demuxer = av_probe_input_format2(&pd, 1, &score);
+ av_freep(&pd.buf);
+ if (!sub_demuxer)
+ goto error;
+
+ if (strcmp(sub_demuxer->name, "srt") && strcmp(sub_demuxer->name, "ass"))
+ goto error;
+
+ if (!(ast->sub_ctx = avformat_alloc_context()))
+ goto error;
+
+ ast->sub_ctx->pb = pb;
+
+ if (ff_copy_whitelists(ast->sub_ctx, s) < 0)
+ goto error;
+
+ 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);
+ *st->codec = *ast->sub_ctx->streams[0]->codec;
+ ast->sub_ctx->streams[0]->codec->extradata = NULL;
+ time_base = ast->sub_ctx->streams[0]->time_base;
+ avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
+ }
+ ast->sub_buffer = pkt->data;
+ memset(pkt, 0, sizeof(*pkt));
+ return 1;
+
+error:
+ av_freep(&ast->sub_ctx);
+ av_freep(&pb);
+ }
+ return 0;
+}
+
+static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st,
+ AVPacket *pkt)
+{
+ AVIStream *ast, *next_ast = next_st->priv_data;
+ int64_t ts, next_ts, ts_min = INT64_MAX;
+ AVStream *st, *sub_st = NULL;
+ int i;
+
+ next_ts = av_rescale_q(next_ast->frame_offset, next_st->time_base,
+ AV_TIME_BASE_Q);
+
+ 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 (ts <= next_ts && ts < ts_min) {
+ ts_min = ts;
+ sub_st = st;
+ }
+ }
+ }
+
+ if (sub_st) {
+ ast = sub_st->priv_data;
+ *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;
+ }
+ return sub_st;
+}
+
+static int get_stream_idx(const unsigned *d)
+{
+ if (d[0] >= '0' && d[0] <= '9' &&
+ d[1] >= '0' && d[1] <= '9') {
+ return (d[0] - '0') * 10 + (d[1] - '0');
+ } else {
+ return 100; // invalid stream ID
+ }
+}
+
+/**
+ *
+ * @param exit_early set to 1 to just gather packet position without making the changes needed to actually read & return the packet
+ */
+static int avi_sync(AVFormatContext *s, int exit_early)
+{
+ AVIContext *avi = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int n;
+ unsigned int d[8];
+ unsigned int size;
+ int64_t i, sync;
+
+start_sync:
+ memset(d, -1, sizeof(d));
+ for (i = sync = avio_tell(pb); !avio_feof(pb); i++) {
+ int j;
+
+ for (j = 0; j < 7; j++)
+ d[j] = d[j + 1];
+ d[7] = avio_r8(pb);
+
+ size = d[4] + (d[5] << 8) + (d[6] << 16) + (d[7] << 24);
+
+ n = get_stream_idx(d + 2);
+ ff_tlog(s, "%X %X %X %X %X %X %X %X %"PRId64" %u %d\n",
+ d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
+ if (i*(avi->io_fsize>0) + (uint64_t)size > avi->fsize || d[0] > 127)
+ continue;
+
+ // parse ix##
+ if ((d[0] == 'i' && d[1] == 'x' && n < s->nb_streams) ||
+ // parse JUNK
+ (d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K') ||
+ (d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1') ||
+ (d[0] == 'i' && d[1] == 'n' && d[2] == 'd' && d[3] == 'x')) {
+ avio_skip(pb, size);
+ goto start_sync;
+ }
+
+ // parse stray LIST
+ if (d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T') {
+ avio_skip(pb, 4);
+ goto start_sync;
+ }
+
+ n = get_stream_idx(d);
+
+ if (!((i - avi->last_pkt_pos) & 1) &&
+ get_stream_idx(d + 1) < s->nb_streams)
+ continue;
+
+ // detect ##ix chunk and skip
+ if (d[2] == 'i' && d[3] == 'x' && n < s->nb_streams) {
+ avio_skip(pb, size);
+ goto start_sync;
+ }
+
+ if (avi->dv_demux && n != 0)
+ continue;
+
+ // parse ##dc/##wb
+ if (n < s->nb_streams) {
+ AVStream *st;
+ AVIStream *ast;
+ st = s->streams[n];
+ ast = st->priv_data;
+
+ if (!ast) {
+ av_log(s, AV_LOG_WARNING, "Skipping foreign stream %d packet\n", n);
+ continue;
+ }
+
+ if (s->nb_streams >= 2) {
+ AVStream *st1 = s->streams[1];
+ AVIStream *ast1 = st1->priv_data;
+ // workaround for broken small-file-bug402.avi
+ if ( d[2] == 'w' && d[3] == 'b'
+ && n == 0
+ && st ->codec->codec_type == AVMEDIA_TYPE_VIDEO
+ && st1->codec->codec_type == AVMEDIA_TYPE_AUDIO
+ && ast->prefix == 'd'*256+'c'
+ && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count)
+ ) {
+ n = 1;
+ st = st1;
+ ast = ast1;
+ av_log(s, AV_LOG_WARNING,
+ "Invalid stream + prefix combination, assuming audio.\n");
+ }
+ }
+
+ if (!avi->dv_demux &&
+ ((st->discard >= AVDISCARD_DEFAULT && size == 0) /* ||
+ // FIXME: needs a little reordering
+ (st->discard >= AVDISCARD_NONKEY &&
+ !(pkt->flags & AV_PKT_FLAG_KEY)) */
+ || st->discard >= AVDISCARD_ALL)) {
+ if (!exit_early) {
+ ast->frame_offset += get_duration(ast, size);
+ avio_skip(pb, size);
+ goto start_sync;
+ }
+ }
+
+ if (d[2] == 'p' && d[3] == 'c' && size <= 4 * 256 + 4) {
+ int k = avio_r8(pb);
+ int last = (k + avio_r8(pb) - 1) & 0xFF;
+
+ avio_rl16(pb); // flags
+
+ // b + (g << 8) + (r << 16);
+ for (; k <= last; k++)
+ ast->pal[k] = 0xFFU<<24 | avio_rb32(pb)>>8;
+
+ ast->has_pal = 1;
+ goto start_sync;
+ } else if (((ast->prefix_count < 5 || sync + 9 > i) &&
+ d[2] < 128 && d[3] < 128) ||
+ d[2] * 256 + d[3] == ast->prefix /* ||
+ (d[2] == 'd' && d[3] == 'c') ||
+ (d[2] == 'w' && d[3] == 'b') */) {
+ if (exit_early)
+ return 0;
+ if (d[2] * 256 + d[3] == ast->prefix)
+ ast->prefix_count++;
+ else {
+ ast->prefix = d[2] * 256 + d[3];
+ ast->prefix_count = 0;
+ }
+
+ avi->stream_index = n;
+ ast->packet_size = size + 8;
+ ast->remaining = size;
+
+ if (size) {
+ uint64_t pos = avio_tell(pb) - 8;
+ if (!st->index_entries || !st->nb_index_entries ||
+ st->index_entries[st->nb_index_entries - 1].pos < pos) {
+ av_add_index_entry(st, pos, ast->frame_offset, size,
+ 0, AVINDEX_KEYFRAME);
+ }
+ }
+ return 0;
+ }
+ }
+ }
+
+ if (pb->error)
+ return pb->error;
+ return AVERROR_EOF;
+}
+
+static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ AVIContext *avi = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int err;
+#if FF_API_DESTRUCT_PACKET
+ void *dstr;
+#endif
+
+ if (CONFIG_DV_DEMUXER && avi->dv_demux) {
+ int size = avpriv_dv_get_packet(avi->dv_demux, pkt);
+ if (size >= 0)
+ return size;
+ else
+ goto resync;
+ }
+
+ if (avi->non_interleaved) {
+ int best_stream_index = 0;
+ AVStream *best_st = NULL;
+ AVIStream *best_ast;
+ int64_t best_ts = INT64_MAX;
+ int i;
+
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ AVIStream *ast = st->priv_data;
+ int64_t ts = ast->frame_offset;
+ int64_t last_ts;
+
+ if (!st->nb_index_entries)
+ continue;
+
+ last_ts = st->index_entries[st->nb_index_entries - 1].timestamp;
+ if (!ast->remaining && ts > last_ts)
+ continue;
+
+ ts = av_rescale_q(ts, st->time_base,
+ (AVRational) { FFMAX(1, ast->sample_size),
+ AV_TIME_BASE });
+
+ av_log(s, AV_LOG_TRACE, "%"PRId64" %d/%d %"PRId64"\n", ts,
+ st->time_base.num, st->time_base.den, ast->frame_offset);
+ if (ts < best_ts) {
+ best_ts = ts;
+ best_st = st;
+ best_stream_index = i;
+ }
+ }
+ if (!best_st)
+ return AVERROR_EOF;
+
+ best_ast = best_st->priv_data;
+ best_ts = best_ast->frame_offset;
+ if (best_ast->remaining) {
+ i = av_index_search_timestamp(best_st,
+ best_ts,
+ AVSEEK_FLAG_ANY |
+ AVSEEK_FLAG_BACKWARD);
+ } else {
+ i = av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
+ if (i >= 0)
+ best_ast->frame_offset = best_st->index_entries[i].timestamp;
+ }
+
+ if (i >= 0) {
+ int64_t pos = best_st->index_entries[i].pos;
+ pos += best_ast->packet_size - best_ast->remaining;
+ if (avio_seek(s->pb, pos + 8, SEEK_SET) < 0)
+ return AVERROR_EOF;
+
+ av_assert0(best_ast->remaining <= best_ast->packet_size);
+
+ avi->stream_index = best_stream_index;
+ if (!best_ast->remaining)
+ best_ast->packet_size =
+ best_ast->remaining = best_st->index_entries[i].size;
+ }
+ else
+ return AVERROR_EOF;
+ }
+
+resync:
+ if (avi->stream_index >= 0) {
+ AVStream *st = s->streams[avi->stream_index];
+ AVIStream *ast = st->priv_data;
+ int size, err;
+
+ if (get_subtitle_pkt(s, st, pkt))
+ return 0;
+
+ // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
+ if (ast->sample_size <= 1)
+ size = INT_MAX;
+ else if (ast->sample_size < 32)
+ // arbitrary multiplier to avoid tiny packets for raw PCM data
+ size = 1024 * ast->sample_size;
+ else
+ size = ast->sample_size;
+
+ if (size > ast->remaining)
+ size = ast->remaining;
+ avi->last_pkt_pos = avio_tell(pb);
+ err = av_get_packet(pb, pkt, size);
+ if (err < 0)
+ return err;
+ size = err;
+
+ if (ast->has_pal && pkt->size < (unsigned)INT_MAX / 2) {
+ uint8_t *pal;
+ pal = av_packet_new_side_data(pkt,
+ AV_PKT_DATA_PALETTE,
+ AVPALETTE_SIZE);
+ if (!pal) {
+ av_log(s, AV_LOG_ERROR,
+ "Failed to allocate data for palette\n");
+ } else {
+ memcpy(pal, ast->pal, AVPALETTE_SIZE);
+ ast->has_pal = 0;
+ }
+ }
+
+ if (CONFIG_DV_DEMUXER && avi->dv_demux) {
+ AVBufferRef *avbuf = pkt->buf;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+ dstr = pkt->destruct;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
+ pkt->data, pkt->size, pkt->pos);
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+ pkt->destruct = dstr;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ pkt->buf = avbuf;
+ pkt->flags |= AV_PKT_FLAG_KEY;
+ if (size < 0)
+ av_free_packet(pkt);
+ } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE &&
+ !st->codec->codec_tag && read_gab2_sub(s, st, pkt)) {
+ ast->frame_offset++;
+ avi->stream_index = -1;
+ ast->remaining = 0;
+ goto resync;
+ } else {
+ /* XXX: How to handle B-frames in AVI? */
+ pkt->dts = ast->frame_offset;
+// pkt->dts += ast->start;
+ if (ast->sample_size)
+ pkt->dts /= ast->sample_size;
+ av_log(s, AV_LOG_TRACE,
+ "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d "
+ "base:%d st:%d size:%d\n",
+ pkt->dts,
+ ast->frame_offset,
+ ast->scale,
+ ast->rate,
+ ast->sample_size,
+ AV_TIME_BASE,
+ avi->stream_index,
+ size);
+ pkt->stream_index = avi->stream_index;
+
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->index_entries) {
+ AVIndexEntry *e;
+ int index;
+
+ index = av_index_search_timestamp(st, ast->frame_offset, AVSEEK_FLAG_ANY);
+ e = &st->index_entries[index];
+
+ if (index >= 0 && e->timestamp == ast->frame_offset) {
+ if (index == st->nb_index_entries-1) {
+ int key=1;
+ uint32_t state=-1;
+ if (st->codec->codec_id == AV_CODEC_ID_MPEG4) {
+ const uint8_t *ptr = pkt->data, *end = ptr + FFMIN(size, 256);
+ while (ptr < end) {
+ ptr = avpriv_find_start_code(ptr, end, &state);
+ if (state == 0x1B6 && ptr < end) {
+ key = !(*ptr & 0xC0);
+ break;
+ }
+ }
+ }
+ if (!key)
+ e->flags &= ~AVINDEX_KEYFRAME;
+ }
+ if (e->flags & AVINDEX_KEYFRAME)
+ pkt->flags |= AV_PKT_FLAG_KEY;
+ }
+ } else {
+ pkt->flags |= AV_PKT_FLAG_KEY;
+ }
+ ast->frame_offset += get_duration(ast, pkt->size);
+ }
+ ast->remaining -= err;
+ if (!ast->remaining) {
+ avi->stream_index = -1;
+ ast->packet_size = 0;
+ }
+
+ if (!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos) {
+ av_free_packet(pkt);
+ goto resync;
+ }
+ ast->seek_pos= 0;
+
+ if (!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1) {
+ int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);
+
+ if (avi->dts_max - dts > 2*AV_TIME_BASE) {
+ avi->non_interleaved= 1;
+ av_log(s, AV_LOG_INFO, "Switching to NI mode, due to poor interleaving\n");
+ }else if (avi->dts_max < dts)
+ avi->dts_max = dts;
+ }
+
+ return 0;
+ }
+
+ if ((err = avi_sync(s, 0)) < 0)
+ return err;
+ goto resync;
+}
+
+/* XXX: We make the implicit supposition that the positions are sorted
+ * for each stream. */
+static int avi_read_idx1(AVFormatContext *s, int size)
+{
+ AVIContext *avi = s->priv_data;
+ AVIOContext *pb = s->pb;
+ int nb_index_entries, i;
+ AVStream *st;
+ AVIStream *ast;
+ unsigned int index, tag, flags, pos, len, first_packet = 1;
+ unsigned last_pos = -1;
+ unsigned last_idx = -1;
+ int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
+ int anykey = 0;
+
+ nb_index_entries = size / 16;
+ if (nb_index_entries <= 0)
+ return AVERROR_INVALIDDATA;
+
+ idx1_pos = avio_tell(pb);
+ avio_seek(pb, avi->movi_list + 4, SEEK_SET);
+ if (avi_sync(s, 1) == 0)
+ first_packet_pos = avio_tell(pb) - 8;
+ avi->stream_index = -1;
+ avio_seek(pb, idx1_pos, SEEK_SET);
+
+ if (s->nb_streams == 1 && s->streams[0]->codec->codec_tag == AV_RL32("MMES")) {
+ first_packet_pos = 0;
+ data_offset = avi->movi_list;
+ }
+
+ /* Read the entries and sort them in each stream component. */
+ for (i = 0; i < nb_index_entries; i++) {
+ if (avio_feof(pb))
+ return -1;
+
+ tag = avio_rl32(pb);
+ flags = avio_rl32(pb);
+ pos = avio_rl32(pb);
+ len = avio_rl32(pb);
+ av_log(s, AV_LOG_TRACE, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
+ i, tag, flags, pos, len);
+
+ index = ((tag & 0xff) - '0') * 10;
+ index += (tag >> 8 & 0xff) - '0';
+ if (index >= s->nb_streams)
+ continue;
+ st = s->streams[index];
+ ast = st->priv_data;
+
+ if (first_packet && first_packet_pos) {
+ if (avi->movi_list + 4 != pos || pos + 500 > first_packet_pos)
+ data_offset = first_packet_pos - pos;
+ first_packet = 0;
+ }
+ pos += data_offset;
+
+ av_log(s, AV_LOG_TRACE, "%d cum_len=%"PRId64"\n", len, ast->cum_len);
+
+ // even if we have only a single stream, we should
+ // switch to non-interleaved to get correct timestamps
+ if (last_pos == pos)
+ avi->non_interleaved = 1;
+ if (last_idx != pos && len) {
+ av_add_index_entry(st, pos, ast->cum_len, len, 0,
+ (flags & AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
+ last_idx= pos;
+ }
+ ast->cum_len += get_duration(ast, len);
+ last_pos = pos;
+ anykey |= flags&AVIIF_INDEX;
+ }
+ if (!anykey) {
+ for (index = 0; index < s->nb_streams; index++) {
+ st = s->streams[index];
+ if (st->nb_index_entries)
+ st->index_entries[0].flags |= AVINDEX_KEYFRAME;
+ }
+ }
+ return 0;
+}
+
+/* Scan the index and consider any file with streams more than
+ * 2 seconds or 64MB apart non-interleaved. */
+static int check_stream_max_drift(AVFormatContext *s)
+{
+ int64_t min_pos, pos;
+ int i;
+ int *idx = av_mallocz_array(s->nb_streams, sizeof(*idx));
+ if (!idx)
+ return AVERROR(ENOMEM);
+ for (min_pos = pos = 0; min_pos != INT64_MAX; pos = min_pos + 1LU) {
+ int64_t max_dts = INT64_MIN / 2;
+ int64_t min_dts = INT64_MAX / 2;
+ int64_t max_buffer = 0;
+
+ min_pos = INT64_MAX;
+
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ AVIStream *ast = st->priv_data;
+ int n = st->nb_index_entries;
+ while (idx[i] < n && st->index_entries[idx[i]].pos < pos)
+ idx[i]++;
+ if (idx[i] < n) {
+ int64_t dts;
+ dts = av_rescale_q(st->index_entries[idx[i]].timestamp /
+ FFMAX(ast->sample_size, 1),
+ st->time_base, AV_TIME_BASE_Q);
+ min_dts = FFMIN(min_dts, dts);
+ min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos);
+ }
+ }
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ AVIStream *ast = st->priv_data;
+
+ if (idx[i] && min_dts != INT64_MAX / 2) {
+ int64_t dts;
+ dts = av_rescale_q(st->index_entries[idx[i] - 1].timestamp /
+ FFMAX(ast->sample_size, 1),
+ st->time_base, AV_TIME_BASE_Q);
+ max_dts = FFMAX(max_dts, dts);
+ max_buffer = FFMAX(max_buffer,
+ av_rescale(dts - min_dts,
+ st->codec->bit_rate,
+ AV_TIME_BASE));
+ }
+ }
+ if (max_dts - min_dts > 2 * AV_TIME_BASE ||
+ max_buffer > 1024 * 1024 * 8 * 8) {
+ av_free(idx);
+ return 1;
+ }
+ }
+ av_free(idx);
+ return 0;
+}
+
+static int guess_ni_flag(AVFormatContext *s)
+{
+ int i;
+ int64_t last_start = 0;
+ int64_t first_end = INT64_MAX;
+ int64_t oldpos = avio_tell(s->pb);
+
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ int n = st->nb_index_entries;
+ unsigned int size;
+
+ if (n <= 0)
+ continue;
+
+ if (n >= 2) {
+ int64_t pos = st->index_entries[0].pos;
+ unsigned tag[2];
+ avio_seek(s->pb, pos, SEEK_SET);
+ tag[0] = avio_r8(s->pb);
+ tag[1] = avio_r8(s->pb);
+ avio_rl16(s->pb);
+ size = avio_rl32(s->pb);
+ if (get_stream_idx(tag) == i && pos + size > st->index_entries[1].pos)
+ last_start = INT64_MAX;
+ if (get_stream_idx(tag) == i && size == st->index_entries[0].size + 8)
+ last_start = INT64_MAX;
+ }
+
+ if (st->index_entries[0].pos > last_start)
+ last_start = st->index_entries[0].pos;
+ if (st->index_entries[n - 1].pos < first_end)
+ first_end = st->index_entries[n - 1].pos;
+ }
+ avio_seek(s->pb, oldpos, SEEK_SET);
+
+ if (last_start > first_end)
+ return 1;
+
+ return check_stream_max_drift(s);
+}
+
+static int avi_load_index(AVFormatContext *s)
+{
+ AVIContext *avi = s->priv_data;
+ AVIOContext *pb = s->pb;
+ uint32_t tag, size;
+ int64_t pos = avio_tell(pb);
+ int64_t next;
+ int ret = -1;
+
+ if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
+ goto the_end; // maybe truncated file
+ av_log(s, AV_LOG_TRACE, "movi_end=0x%"PRIx64"\n", avi->movi_end);
+ for (;;) {
+ tag = avio_rl32(pb);
+ size = avio_rl32(pb);
+ if (avio_feof(pb))
+ break;
+ next = avio_tell(pb) + size + (size & 1);
+
+ av_log(s, AV_LOG_TRACE, "tag=%c%c%c%c size=0x%x\n",
+ tag & 0xff,
+ (tag >> 8) & 0xff,
+ (tag >> 16) & 0xff,
+ (tag >> 24) & 0xff,
+ size);
+
+ if (tag == MKTAG('i', 'd', 'x', '1') &&
+ avi_read_idx1(s, size) >= 0) {
+ avi->index_loaded=2;
+ ret = 0;
+ }else if (tag == MKTAG('L', 'I', 'S', 'T')) {
+ uint32_t tag1 = avio_rl32(pb);
+
+ if (tag1 == MKTAG('I', 'N', 'F', 'O'))
+ ff_read_riff_info(s, size - 4);
+ }else if (!ret)
+ break;
+
+ if (avio_seek(pb, next, SEEK_SET) < 0)
+ break; // something is wrong here
+ }
+
+the_end:
+ avio_seek(pb, pos, SEEK_SET);
+ return ret;
+}
+
+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_free_packet(&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);
+}
+
+static int avi_read_seek(AVFormatContext *s, int stream_index,
+ int64_t timestamp, int flags)
+{
+ AVIContext *avi = s->priv_data;
+ AVStream *st;
+ int i, index;
+ int64_t pos, pos_min;
+ AVIStream *ast;
+
+ /* Does not matter which stream is requested dv in avi has the
+ * stream information in the first video stream.
+ */
+ if (avi->dv_demux)
+ stream_index = 0;
+
+ if (!avi->index_loaded) {
+ /* we only load the index on demand */
+ avi_load_index(s);
+ avi->index_loaded |= 1;
+ }
+ av_assert0(stream_index >= 0);
+
+ st = s->streams[stream_index];
+ ast = st->priv_data;
+ index = av_index_search_timestamp(st,
+ timestamp * FFMAX(ast->sample_size, 1),
+ flags);
+ if (index < 0) {
+ if (st->nb_index_entries > 0)
+ av_log(s, AV_LOG_DEBUG, "Failed to find timestamp %"PRId64 " in index %"PRId64 " .. %"PRId64 "\n",
+ timestamp * FFMAX(ast->sample_size, 1),
+ st->index_entries[0].timestamp,
+ st->index_entries[st->nb_index_entries - 1].timestamp);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* find the position */
+ pos = st->index_entries[index].pos;
+ timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
+
+ av_log(s, AV_LOG_TRACE, "XX %"PRId64" %d %"PRId64"\n",
+ timestamp, index, st->index_entries[index].timestamp);
+
+ if (CONFIG_DV_DEMUXER && avi->dv_demux) {
+ /* One and only one real stream for DV in AVI, and it has video */
+ /* offsets. Calling with other stream indexes should have failed */
+ /* the av_index_search_timestamp call above. */
+
+ if (avio_seek(s->pb, pos, SEEK_SET) < 0)
+ return -1;
+
+ /* Feed the DV video stream version of the timestamp to the */
+ /* DV demux so it can synthesize correct timestamps. */
+ ff_dv_offset_reset(avi->dv_demux, timestamp);
+
+ avi->stream_index = -1;
+ return 0;
+ }
+
+ pos_min = pos;
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st2 = s->streams[i];
+ AVIStream *ast2 = st2->priv_data;
+
+ ast2->packet_size =
+ ast2->remaining = 0;
+
+ if (ast2->sub_ctx) {
+ seek_subtitle(st, st2, timestamp);
+ continue;
+ }
+
+ if (st2->nb_index_entries <= 0)
+ continue;
+
+// av_assert1(st2->codec->block_align);
+ index = av_index_search_timestamp(st2,
+ av_rescale_q(timestamp,
+ st->time_base,
+ st2->time_base) *
+ FFMAX(ast2->sample_size, 1),
+ flags |
+ AVSEEK_FLAG_BACKWARD |
+ (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
+ if (index < 0)
+ index = 0;
+ ast2->seek_pos = st2->index_entries[index].pos;
+ pos_min = FFMIN(pos_min,ast2->seek_pos);
+ }
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st2 = s->streams[i];
+ AVIStream *ast2 = st2->priv_data;
+
+ if (ast2->sub_ctx || st2->nb_index_entries <= 0)
+ continue;
+
+ index = av_index_search_timestamp(
+ st2,
+ av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
+ flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
+ if (index < 0)
+ index = 0;
+ while (!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min)
+ index--;
+ ast2->frame_offset = st2->index_entries[index].timestamp;
+ }
+
+ /* do the seek */
+ if (avio_seek(s->pb, pos_min, SEEK_SET) < 0) {
+ av_log(s, AV_LOG_ERROR, "Seek failed\n");
+ return -1;
+ }
+ avi->stream_index = -1;
+ avi->dts_max = INT_MIN;
+ return 0;
+}
+
+static int avi_read_close(AVFormatContext *s)
+{
+ int i;
+ AVIContext *avi = s->priv_data;
+
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ AVIStream *ast = st->priv_data;
+ if (ast) {
+ if (ast->sub_ctx) {
+ av_freep(&ast->sub_ctx->pb);
+ avformat_close_input(&ast->sub_ctx);
+ }
+ av_freep(&ast->sub_buffer);
+ av_free_packet(&ast->sub_pkt);
+ }
+ }
+
+ av_freep(&avi->dv_demux);
+
+ return 0;
+}
+
+static int avi_probe(AVProbeData *p)
+{
+ int i;
+
+ /* check file header */
+ for (i = 0; avi_headers[i][0]; i++)
+ if (AV_RL32(p->buf ) == AV_RL32(avi_headers[i] ) &&
+ AV_RL32(p->buf + 8) == AV_RL32(avi_headers[i] + 4))
+ return AVPROBE_SCORE_MAX;
+
+ return 0;
+}
+
+AVInputFormat ff_avi_demuxer = {
+ .name = "avi",
+ .long_name = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),
+ .priv_data_size = sizeof(AVIContext),
+ .extensions = "avi",
+ .read_probe = avi_probe,
+ .read_header = avi_read_header,
+ .read_packet = avi_read_packet,
+ .read_close = avi_read_close,
+ .read_seek = avi_read_seek,
+ .priv_class = &demuxer_class,
+};
diff --git a/ffmpeg-2-8-11/libavformat/avienc.c b/ffmpeg-2-8-12/libavformat/avienc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/avienc.c
rename to ffmpeg-2-8-12/libavformat/avienc.c
diff --git a/ffmpeg-2-8-11/libavformat/avio.c b/ffmpeg-2-8-12/libavformat/avio.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/avio.c
rename to ffmpeg-2-8-12/libavformat/avio.c
diff --git a/ffmpeg-2-8-11/libavformat/avio.h b/ffmpeg-2-8-12/libavformat/avio.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/avio.h
rename to ffmpeg-2-8-12/libavformat/avio.h
diff --git a/ffmpeg-2-8-11/libavformat/avio_internal.h b/ffmpeg-2-8-12/libavformat/avio_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/avio_internal.h
rename to ffmpeg-2-8-12/libavformat/avio_internal.h
diff --git a/ffmpeg-2-8-11/libavformat/aviobuf.c b/ffmpeg-2-8-12/libavformat/aviobuf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/aviobuf.c
rename to ffmpeg-2-8-12/libavformat/aviobuf.c
diff --git a/ffmpeg-2-8-11/libavformat/avisynth.c b/ffmpeg-2-8-12/libavformat/avisynth.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/avisynth.c
rename to ffmpeg-2-8-12/libavformat/avisynth.c
diff --git a/ffmpeg-2-8-11/libavformat/avlanguage.c b/ffmpeg-2-8-12/libavformat/avlanguage.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/avlanguage.c
rename to ffmpeg-2-8-12/libavformat/avlanguage.c
diff --git a/ffmpeg-2-8-11/libavformat/avlanguage.h b/ffmpeg-2-8-12/libavformat/avlanguage.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/avlanguage.h
rename to ffmpeg-2-8-12/libavformat/avlanguage.h
diff --git a/ffmpeg-2-8-11/libavformat/avr.c b/ffmpeg-2-8-12/libavformat/avr.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/avr.c
rename to ffmpeg-2-8-12/libavformat/avr.c
diff --git a/ffmpeg-2-8-11/libavformat/avs.c b/ffmpeg-2-8-12/libavformat/avs.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/avs.c
rename to ffmpeg-2-8-12/libavformat/avs.c
diff --git a/ffmpeg-2-8-11/libavformat/bethsoftvid.c b/ffmpeg-2-8-12/libavformat/bethsoftvid.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/bethsoftvid.c
rename to ffmpeg-2-8-12/libavformat/bethsoftvid.c
diff --git a/ffmpeg-2-8-11/libavformat/bfi.c b/ffmpeg-2-8-12/libavformat/bfi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/bfi.c
rename to ffmpeg-2-8-12/libavformat/bfi.c
diff --git a/ffmpeg-2-8-11/libavformat/bink.c b/ffmpeg-2-8-12/libavformat/bink.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/bink.c
rename to ffmpeg-2-8-12/libavformat/bink.c
diff --git a/ffmpeg-2-8-11/libavformat/bintext.c b/ffmpeg-2-8-12/libavformat/bintext.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/bintext.c
rename to ffmpeg-2-8-12/libavformat/bintext.c
diff --git a/ffmpeg-2-8-11/libavformat/bit.c b/ffmpeg-2-8-12/libavformat/bit.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/bit.c
rename to ffmpeg-2-8-12/libavformat/bit.c
diff --git a/ffmpeg-2-8-11/libavformat/bluray.c b/ffmpeg-2-8-12/libavformat/bluray.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/bluray.c
rename to ffmpeg-2-8-12/libavformat/bluray.c
diff --git a/ffmpeg-2-8-11/libavformat/bmv.c b/ffmpeg-2-8-12/libavformat/bmv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/bmv.c
rename to ffmpeg-2-8-12/libavformat/bmv.c
diff --git a/ffmpeg-2-8-11/libavformat/boadec.c b/ffmpeg-2-8-12/libavformat/boadec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/boadec.c
rename to ffmpeg-2-8-12/libavformat/boadec.c
diff --git a/ffmpeg-2-8-11/libavformat/brstm.c b/ffmpeg-2-8-12/libavformat/brstm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/brstm.c
rename to ffmpeg-2-8-12/libavformat/brstm.c
diff --git a/ffmpeg-2-8-11/libavformat/c93.c b/ffmpeg-2-8-12/libavformat/c93.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/c93.c
rename to ffmpeg-2-8-12/libavformat/c93.c
diff --git a/ffmpeg-2-8-11/libavformat/cache.c b/ffmpeg-2-8-12/libavformat/cache.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/cache.c
rename to ffmpeg-2-8-12/libavformat/cache.c
diff --git a/ffmpeg-2-8-11/libavformat/caf.c b/ffmpeg-2-8-12/libavformat/caf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/caf.c
rename to ffmpeg-2-8-12/libavformat/caf.c
diff --git a/ffmpeg-2-8-11/libavformat/caf.h b/ffmpeg-2-8-12/libavformat/caf.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/caf.h
rename to ffmpeg-2-8-12/libavformat/caf.h
diff --git a/ffmpeg-2-8-11/libavformat/cafdec.c b/ffmpeg-2-8-12/libavformat/cafdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/cafdec.c
rename to ffmpeg-2-8-12/libavformat/cafdec.c
diff --git a/ffmpeg-2-8-11/libavformat/cafenc.c b/ffmpeg-2-8-12/libavformat/cafenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/cafenc.c
rename to ffmpeg-2-8-12/libavformat/cafenc.c
diff --git a/ffmpeg-2-8-11/libavformat/cavsvideodec.c b/ffmpeg-2-8-12/libavformat/cavsvideodec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/cavsvideodec.c
rename to ffmpeg-2-8-12/libavformat/cavsvideodec.c
diff --git a/ffmpeg-2-8-11/libavformat/cdg.c b/ffmpeg-2-8-12/libavformat/cdg.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/cdg.c
rename to ffmpeg-2-8-12/libavformat/cdg.c
diff --git a/ffmpeg-2-8-11/libavformat/cdxl.c b/ffmpeg-2-8-12/libavformat/cdxl.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/cdxl.c
rename to ffmpeg-2-8-12/libavformat/cdxl.c
diff --git a/ffmpeg-2-8-11/libavformat/cinedec.c b/ffmpeg-2-8-12/libavformat/cinedec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/cinedec.c
rename to ffmpeg-2-8-12/libavformat/cinedec.c
diff --git a/ffmpeg-2-8-11/libavformat/concat.c b/ffmpeg-2-8-12/libavformat/concat.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/concat.c
rename to ffmpeg-2-8-12/libavformat/concat.c
diff --git a/ffmpeg-2-8-12/libavformat/concatdec.c b/ffmpeg-2-8-12/libavformat/concatdec.c
new file mode 100644
index 0000000..2b403f3
--- /dev/null
+++ b/ffmpeg-2-8-12/libavformat/concatdec.c
@@ -0,0 +1,731 @@
+/*
+ * Copyright (c) 2012 Nicolas George
+ *
+ * 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/intreadwrite.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/timestamp.h"
+#include "avformat.h"
+#include "internal.h"
+#include "url.h"
+
+typedef enum ConcatMatchMode {
+ MATCH_ONE_TO_ONE,
+ MATCH_EXACT_ID,
+} ConcatMatchMode;
+
+typedef struct ConcatStream {
+ AVBitStreamFilterContext *bsf;
+ int out_stream_index;
+} ConcatStream;
+
+typedef struct {
+ char *url;
+ int64_t start_time;
+ int64_t file_start_time;
+ int64_t file_inpoint;
+ int64_t duration;
+ ConcatStream *streams;
+ int64_t inpoint;
+ int64_t outpoint;
+ AVDictionary *metadata;
+ int nb_streams;
+} ConcatFile;
+
+typedef struct {
+ AVClass *class;
+ ConcatFile *files;
+ ConcatFile *cur_file;
+ unsigned nb_files;
+ AVFormatContext *avf;
+ int safe;
+ int seekable;
+ int eof;
+ ConcatMatchMode stream_match_mode;
+ unsigned auto_convert;
+} ConcatContext;
+
+static int concat_probe(AVProbeData *probe)
+{
+ return memcmp(probe->buf, "ffconcat version 1.0", 20) ?
+ 0 : AVPROBE_SCORE_MAX;
+}
+
+static char *get_keyword(uint8_t **cursor)
+{
+ char *ret = *cursor += strspn(*cursor, SPACE_CHARS);
+ *cursor += strcspn(*cursor, SPACE_CHARS);
+ if (**cursor) {
+ *((*cursor)++) = 0;
+ *cursor += strspn(*cursor, SPACE_CHARS);
+ }
+ return ret;
+}
+
+static int safe_filename(const char *f)
+{
+ const char *start = f;
+
+ for (; *f; f++) {
+ /* A-Za-z0-9_- */
+ if (!((unsigned)((*f | 32) - 'a') < 26 ||
+ (unsigned)(*f - '0') < 10 || *f == '_' || *f == '-')) {
+ if (f == start)
+ return 0;
+ else if (*f == '/')
+ start = f + 1;
+ else if (*f != '.')
+ return 0;
+ }
+ }
+ return 1;
+}
+
+#define FAIL(retcode) do { ret = (retcode); goto fail; } while(0)
+
+static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile,
+ unsigned *nb_files_alloc)
+{
+ ConcatContext *cat = avf->priv_data;
+ ConcatFile *file;
+ char *url = NULL;
+ const char *proto;
+ size_t url_len, proto_len;
+ int ret;
+
+ if (cat->safe > 0 && !safe_filename(filename)) {
+ av_log(avf, AV_LOG_ERROR, "Unsafe file name '%s'\n", filename);
+ FAIL(AVERROR(EPERM));
+ }
+
+ proto = avio_find_protocol_name(filename);
+ proto_len = proto ? strlen(proto) : 0;
+ if (!memcmp(filename, proto, proto_len) &&
+ (filename[proto_len] == ':' || filename[proto_len] == ',')) {
+ url = filename;
+ filename = NULL;
+ } else {
+ url_len = strlen(avf->filename) + strlen(filename) + 16;
+ if (!(url = av_malloc(url_len)))
+ FAIL(AVERROR(ENOMEM));
+ ff_make_absolute_url(url, url_len, avf->filename, filename);
+ av_freep(&filename);
+ }
+
+ if (cat->nb_files >= *nb_files_alloc) {
+ size_t n = FFMAX(*nb_files_alloc * 2, 16);
+ ConcatFile *new_files;
+ if (n <= cat->nb_files || n > SIZE_MAX / sizeof(*cat->files) ||
+ !(new_files = av_realloc(cat->files, n * sizeof(*cat->files))))
+ FAIL(AVERROR(ENOMEM));
+ cat->files = new_files;
+ *nb_files_alloc = n;
+ }
+
+ file = &cat->files[cat->nb_files++];
+ memset(file, 0, sizeof(*file));
+ *rfile = file;
+
+ file->url = url;
+ file->start_time = AV_NOPTS_VALUE;
+ file->duration = AV_NOPTS_VALUE;
+ file->inpoint = AV_NOPTS_VALUE;
+ file->outpoint = AV_NOPTS_VALUE;
+
+ return 0;
+
+fail:
+ av_free(url);
+ av_free(filename);
+ return ret;
+}
+
+static int copy_stream_props(AVStream *st, AVStream *source_st)
+{
+ int ret;
+
+ if (st->codec->codec_id || !source_st->codec->codec_id) {
+ if (st->codec->extradata_size < source_st->codec->extradata_size) {
+ ret = ff_alloc_extradata(st->codec,
+ source_st->codec->extradata_size);
+ if (ret < 0)
+ return ret;
+ }
+ memcpy(st->codec->extradata, source_st->codec->extradata,
+ source_st->codec->extradata_size);
+ return 0;
+ }
+ if ((ret = avcodec_copy_context(st->codec, source_st->codec)) < 0)
+ return ret;
+ st->r_frame_rate = source_st->r_frame_rate;
+ st->avg_frame_rate = source_st->avg_frame_rate;
+ st->time_base = source_st->time_base;
+ st->sample_aspect_ratio = source_st->sample_aspect_ratio;
+
+ av_dict_copy(&st->metadata, source_st->metadata, 0);
+ return 0;
+}
+
+static int detect_stream_specific(AVFormatContext *avf, int idx)
+{
+ ConcatContext *cat = avf->priv_data;
+ AVStream *st = cat->avf->streams[idx];
+ ConcatStream *cs = &cat->cur_file->streams[idx];
+ AVBitStreamFilterContext *bsf;
+
+ if (cat->auto_convert && st->codec->codec_id == AV_CODEC_ID_H264) {
+ if (!st->codec->extradata_size ||
+ (st->codec->extradata_size >= 3 && AV_RB24(st->codec->extradata) == 1) ||
+ (st->codec->extradata_size >= 4 && AV_RB32(st->codec->extradata) == 1))
+ return 0;
+ av_log(cat->avf, AV_LOG_INFO,
+ "Auto-inserting h264_mp4toannexb bitstream filter\n");
+ if (!(bsf = av_bitstream_filter_init("h264_mp4toannexb"))) {
+ av_log(avf, AV_LOG_ERROR, "h264_mp4toannexb bitstream filter "
+ "required for H.264 streams\n");
+ return AVERROR_BSF_NOT_FOUND;
+ }
+ cs->bsf = bsf;
+ }
+ return 0;
+}
+
+static int match_streams_one_to_one(AVFormatContext *avf)
+{
+ ConcatContext *cat = avf->priv_data;
+ AVStream *st;
+ int i, ret;
+
+ for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++) {
+ if (i < avf->nb_streams) {
+ st = avf->streams[i];
+ } else {
+ if (!(st = avformat_new_stream(avf, NULL)))
+ return AVERROR(ENOMEM);
+ }
+ if ((ret = copy_stream_props(st, cat->avf->streams[i])) < 0)
+ return ret;
+ cat->cur_file->streams[i].out_stream_index = i;
+ }
+ return 0;
+}
+
+static int match_streams_exact_id(AVFormatContext *avf)
+{
+ ConcatContext *cat = avf->priv_data;
+ AVStream *st;
+ int i, j, ret;
+
+ for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++) {
+ st = cat->avf->streams[i];
+ for (j = 0; j < avf->nb_streams; j++) {
+ if (avf->streams[j]->id == st->id) {
+ av_log(avf, AV_LOG_VERBOSE,
+ "Match slave stream #%d with stream #%d id 0x%x\n",
+ i, j, st->id);
+ if ((ret = copy_stream_props(avf->streams[j], st)) < 0)
+ return ret;
+ cat->cur_file->streams[i].out_stream_index = j;
+ }
+ }
+ }
+ return 0;
+}
+
+static int match_streams(AVFormatContext *avf)
+{
+ ConcatContext *cat = avf->priv_data;
+ ConcatStream *map;
+ int i, ret;
+
+ if (cat->cur_file->nb_streams >= cat->avf->nb_streams)
+ return 0;
+ map = av_realloc(cat->cur_file->streams,
+ cat->avf->nb_streams * sizeof(*map));
+ if (!map)
+ return AVERROR(ENOMEM);
+ cat->cur_file->streams = map;
+ memset(map + cat->cur_file->nb_streams, 0,
+ (cat->avf->nb_streams - cat->cur_file->nb_streams) * sizeof(*map));
+
+ for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++)
+ map[i].out_stream_index = -1;
+ switch (cat->stream_match_mode) {
+ case MATCH_ONE_TO_ONE:
+ ret = match_streams_one_to_one(avf);
+ break;
+ case MATCH_EXACT_ID:
+ ret = match_streams_exact_id(avf);
+ break;
+ default:
+ ret = AVERROR_BUG;
+ }
+ if (ret < 0)
+ return ret;
+ for (i = cat->cur_file->nb_streams; i < cat->avf->nb_streams; i++)
+ if ((ret = detect_stream_specific(avf, i)) < 0)
+ return ret;
+ cat->cur_file->nb_streams = cat->avf->nb_streams;
+ return 0;
+}
+
+static int open_file(AVFormatContext *avf, unsigned fileno)
+{
+ ConcatContext *cat = avf->priv_data;
+ ConcatFile *file = &cat->files[fileno];
+ int ret;
+
+ if (cat->avf)
+ avformat_close_input(&cat->avf);
+
+ cat->avf = avformat_alloc_context();
+ if (!cat->avf)
+ return AVERROR(ENOMEM);
+
+ cat->avf->interrupt_callback = avf->interrupt_callback;
+
+ if ((ret = ff_copy_whitelists(cat->avf, avf)) < 0)
+ return ret;
+
+ if ((ret = avformat_open_input(&cat->avf, file->url, NULL, NULL)) < 0 ||
+ (ret = avformat_find_stream_info(cat->avf, NULL)) < 0) {
+ av_log(avf, AV_LOG_ERROR, "Impossible to open '%s'\n", file->url);
+ avformat_close_input(&cat->avf);
+ return ret;
+ }
+ cat->cur_file = file;
+ if (file->start_time == AV_NOPTS_VALUE)
+ file->start_time = !fileno ? 0 :
+ cat->files[fileno - 1].start_time +
+ cat->files[fileno - 1].duration;
+ file->file_start_time = (cat->avf->start_time == AV_NOPTS_VALUE) ? 0 : cat->avf->start_time;
+ file->file_inpoint = (file->inpoint == AV_NOPTS_VALUE) ? file->file_start_time : file->inpoint;
+ if ((ret = match_streams(avf)) < 0)
+ return ret;
+ if (file->inpoint != AV_NOPTS_VALUE) {
+ if ((ret = avformat_seek_file(cat->avf, -1, INT64_MIN, file->inpoint, file->inpoint, 0)) < 0)
+ return ret;
+ }
+ return 0;
+}
+
+static int concat_read_close(AVFormatContext *avf)
+{
+ ConcatContext *cat = avf->priv_data;
+ unsigned i;
+
+ if (cat->avf)
+ avformat_close_input(&cat->avf);
+ for (i = 0; i < cat->nb_files; i++) {
+ av_freep(&cat->files[i].url);
+ av_freep(&cat->files[i].streams);
+ av_dict_free(&cat->files[i].metadata);
+ }
+ av_freep(&cat->files);
+ return 0;
+}
+
+static int concat_read_header(AVFormatContext *avf)
+{
+ ConcatContext *cat = avf->priv_data;
+ uint8_t buf[4096];
+ uint8_t *cursor, *keyword;
+ int ret, line = 0, i;
+ unsigned nb_files_alloc = 0;
+ ConcatFile *file = NULL;
+ int64_t time = 0;
+
+ while (1) {
+ if ((ret = ff_get_line(avf->pb, buf, sizeof(buf))) <= 0)
+ break;
+ line++;
+ cursor = buf;
+ keyword = get_keyword(&cursor);
+ if (!*keyword || *keyword == '#')
+ continue;
+
+ if (!strcmp(keyword, "file")) {
+ char *filename = av_get_token((const char **)&cursor, SPACE_CHARS);
+ if (!filename) {
+ av_log(avf, AV_LOG_ERROR, "Line %d: filename required\n", line);
+ FAIL(AVERROR_INVALIDDATA);
+ }
+ if ((ret = add_file(avf, filename, &file, &nb_files_alloc)) < 0)
+ goto fail;
+ } else if (!strcmp(keyword, "duration") || !strcmp(keyword, "inpoint") || !strcmp(keyword, "outpoint")) {
+ char *dur_str = get_keyword(&cursor);
+ int64_t dur;
+ if (!file) {
+ av_log(avf, AV_LOG_ERROR, "Line %d: %s without file\n",
+ line, keyword);
+ FAIL(AVERROR_INVALIDDATA);
+ }
+ if ((ret = av_parse_time(&dur, dur_str, 1)) < 0) {
+ av_log(avf, AV_LOG_ERROR, "Line %d: invalid %s '%s'\n",
+ line, keyword, dur_str);
+ goto fail;
+ }
+ if (!strcmp(keyword, "duration"))
+ file->duration = dur;
+ else if (!strcmp(keyword, "inpoint"))
+ file->inpoint = dur;
+ else if (!strcmp(keyword, "outpoint"))
+ file->outpoint = dur;
+ } else if (!strcmp(keyword, "file_packet_metadata")) {
+ char *metadata;
+ metadata = av_get_token((const char **)&cursor, SPACE_CHARS);
+ if (!metadata) {
+ av_log(avf, AV_LOG_ERROR, "Line %d: packet metadata required\n", line);
+ FAIL(AVERROR_INVALIDDATA);
+ }
+ if (!file) {
+ av_log(avf, AV_LOG_ERROR, "Line %d: %s without file\n",
+ line, keyword);
+ FAIL(AVERROR_INVALIDDATA);
+ }
+ if ((ret = av_dict_parse_string(&file->metadata, metadata, "=", "", 0)) < 0) {
+ av_log(avf, AV_LOG_ERROR, "Line %d: failed to parse metadata string\n", line);
+ av_freep(&metadata);
+ FAIL(AVERROR_INVALIDDATA);
+ }
+ av_freep(&metadata);
+ } else if (!strcmp(keyword, "stream")) {
+ if (!avformat_new_stream(avf, NULL))
+ FAIL(AVERROR(ENOMEM));
+ } else if (!strcmp(keyword, "exact_stream_id")) {
+ if (!avf->nb_streams) {
+ av_log(avf, AV_LOG_ERROR, "Line %d: exact_stream_id without stream\n",
+ line);
+ FAIL(AVERROR_INVALIDDATA);
+ }
+ avf->streams[avf->nb_streams - 1]->id =
+ strtol(get_keyword(&cursor), NULL, 0);
+ } else if (!strcmp(keyword, "ffconcat")) {
+ char *ver_kw = get_keyword(&cursor);
+ char *ver_val = get_keyword(&cursor);
+ if (strcmp(ver_kw, "version") || strcmp(ver_val, "1.0")) {
+ av_log(avf, AV_LOG_ERROR, "Line %d: invalid version\n", line);
+ FAIL(AVERROR_INVALIDDATA);
+ }
+ if (cat->safe < 0)
+ cat->safe = 1;
+ } else {
+ av_log(avf, AV_LOG_ERROR, "Line %d: unknown keyword '%s'\n",
+ line, keyword);
+ FAIL(AVERROR_INVALIDDATA);
+ }
+ }
+ if (ret < 0)
+ goto fail;
+ if (!cat->nb_files)
+ FAIL(AVERROR_INVALIDDATA);
+
+ for (i = 0; i < cat->nb_files; i++) {
+ if (cat->files[i].start_time == AV_NOPTS_VALUE)
+ cat->files[i].start_time = time;
+ else
+ time = cat->files[i].start_time;
+ if (cat->files[i].duration == AV_NOPTS_VALUE) {
+ if (cat->files[i].inpoint == AV_NOPTS_VALUE || cat->files[i].outpoint == AV_NOPTS_VALUE)
+ break;
+ cat->files[i].duration = cat->files[i].outpoint - cat->files[i].inpoint;
+ }
+ time += cat->files[i].duration;
+ }
+ if (i == cat->nb_files) {
+ avf->duration = time;
+ cat->seekable = 1;
+ }
+
+ cat->stream_match_mode = avf->nb_streams ? MATCH_EXACT_ID :
+ MATCH_ONE_TO_ONE;
+ if ((ret = open_file(avf, 0)) < 0)
+ goto fail;
+ return 0;
+
+fail:
+ concat_read_close(avf);
+ return ret;
+}
+
+static int open_next_file(AVFormatContext *avf)
+{
+ ConcatContext *cat = avf->priv_data;
+ unsigned fileno = cat->cur_file - cat->files;
+
+ if (cat->cur_file->duration == AV_NOPTS_VALUE) {
+ cat->cur_file->duration = cat->avf->duration;
+ if (cat->cur_file->inpoint != AV_NOPTS_VALUE)
+ cat->cur_file->duration -= (cat->cur_file->inpoint - cat->cur_file->file_start_time);
+ if (cat->cur_file->outpoint != AV_NOPTS_VALUE)
+ cat->cur_file->duration -= cat->avf->duration - (cat->cur_file->outpoint - cat->cur_file->file_start_time);
+ }
+
+ if (++fileno >= cat->nb_files) {
+ cat->eof = 1;
+ return AVERROR_EOF;
+ }
+ return open_file(avf, fileno);
+}
+
+static int filter_packet(AVFormatContext *avf, ConcatStream *cs, AVPacket *pkt)
+{
+ AVStream *st = avf->streams[cs->out_stream_index];
+ AVBitStreamFilterContext *bsf;
+ AVPacket pkt2;
+ int ret;
+
+ av_assert0(cs->out_stream_index >= 0);
+ for (bsf = cs->bsf; bsf; bsf = bsf->next) {
+ pkt2 = *pkt;
+ ret = av_bitstream_filter_filter(bsf, st->codec, NULL,
+ &pkt2.data, &pkt2.size,
+ pkt->data, pkt->size,
+ !!(pkt->flags & AV_PKT_FLAG_KEY));
+ if (ret < 0) {
+ av_packet_unref(pkt);
+ return ret;
+ }
+ av_assert0(pkt2.buf);
+ if (ret == 0 && pkt2.data != pkt->data) {
+ if ((ret = av_copy_packet(&pkt2, pkt)) < 0) {
+ av_free(pkt2.data);
+ return ret;
+ }
+ ret = 1;
+ }
+ if (ret > 0) {
+ av_free_packet(pkt);
+ pkt2.buf = av_buffer_create(pkt2.data, pkt2.size,
+ av_buffer_default_free, NULL, 0);
+ if (!pkt2.buf) {
+ av_free(pkt2.data);
+ return AVERROR(ENOMEM);
+ }
+ }
+ *pkt = pkt2;
+ }
+ return 0;
+}
+
+/* Returns true if the packet dts is greater or equal to the specified outpoint. */
+static int packet_after_outpoint(ConcatContext *cat, AVPacket *pkt)
+{
+ if (cat->cur_file->outpoint != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE) {
+ return av_compare_ts(pkt->dts, cat->avf->streams[pkt->stream_index]->time_base,
+ cat->cur_file->outpoint, AV_TIME_BASE_Q) >= 0;
+ }
+ return 0;
+}
+
+static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt)
+{
+ ConcatContext *cat = avf->priv_data;
+ int ret;
+ int64_t delta;
+ ConcatStream *cs;
+ AVStream *st;
+
+ if (cat->eof)
+ return AVERROR_EOF;
+
+ if (!cat->avf)
+ return AVERROR(EIO);
+
+ while (1) {
+ ret = av_read_frame(cat->avf, pkt);
+ if (ret == AVERROR_EOF || packet_after_outpoint(cat, pkt)) {
+ if (ret == 0)
+ av_packet_unref(pkt);
+ if ((ret = open_next_file(avf)) < 0)
+ return ret;
+ continue;
+ }
+ if (ret < 0)
+ return ret;
+ if ((ret = match_streams(avf)) < 0) {
+ av_packet_unref(pkt);
+ return ret;
+ }
+ cs = &cat->cur_file->streams[pkt->stream_index];
+ if (cs->out_stream_index < 0) {
+ av_packet_unref(pkt);
+ continue;
+ }
+ pkt->stream_index = cs->out_stream_index;
+ break;
+ }
+ if ((ret = filter_packet(avf, cs, pkt)))
+ return ret;
+
+ st = cat->avf->streams[pkt->stream_index];
+ av_log(avf, AV_LOG_DEBUG, "file:%d stream:%d pts:%s pts_time:%s dts:%s dts_time:%s",
+ (unsigned)(cat->cur_file - cat->files), pkt->stream_index,
+ av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, &st->time_base),
+ av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, &st->time_base));
+
+ delta = av_rescale_q(cat->cur_file->start_time - cat->cur_file->file_inpoint,
+ AV_TIME_BASE_Q,
+ cat->avf->streams[pkt->stream_index]->time_base);
+ if (pkt->pts != AV_NOPTS_VALUE)
+ pkt->pts += delta;
+ if (pkt->dts != AV_NOPTS_VALUE)
+ pkt->dts += delta;
+ av_log(avf, AV_LOG_DEBUG, " -> pts:%s pts_time:%s dts:%s dts_time:%s\n",
+ 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) {
+ uint8_t* metadata;
+ int metadata_len;
+ char* packed_metadata = av_packet_pack_dictionary(cat->cur_file->metadata, &metadata_len);
+ if (!packed_metadata)
+ return AVERROR(ENOMEM);
+ if (!(metadata = av_packet_new_side_data(pkt, AV_PKT_DATA_STRINGS_METADATA, metadata_len))) {
+ av_freep(&packed_metadata);
+ return AVERROR(ENOMEM);
+ }
+ memcpy(metadata, packed_metadata, metadata_len);
+ av_freep(&packed_metadata);
+ }
+ return ret;
+}
+
+static void rescale_interval(AVRational tb_in, AVRational tb_out,
+ int64_t *min_ts, int64_t *ts, int64_t *max_ts)
+{
+ *ts = av_rescale_q (* ts, tb_in, tb_out);
+ *min_ts = av_rescale_q_rnd(*min_ts, tb_in, tb_out,
+ AV_ROUND_UP | AV_ROUND_PASS_MINMAX);
+ *max_ts = av_rescale_q_rnd(*max_ts, tb_in, tb_out,
+ AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
+}
+
+static int try_seek(AVFormatContext *avf, int stream,
+ int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+ ConcatContext *cat = avf->priv_data;
+ int64_t t0 = cat->cur_file->start_time - cat->cur_file->file_inpoint;
+
+ ts -= t0;
+ min_ts = min_ts == INT64_MIN ? INT64_MIN : min_ts - t0;
+ max_ts = max_ts == INT64_MAX ? INT64_MAX : max_ts - t0;
+ if (stream >= 0) {
+ if (stream >= cat->avf->nb_streams)
+ return AVERROR(EIO);
+ rescale_interval(AV_TIME_BASE_Q, cat->avf->streams[stream]->time_base,
+ &min_ts, &ts, &max_ts);
+ }
+ return avformat_seek_file(cat->avf, stream, min_ts, ts, max_ts, flags);
+}
+
+static int real_seek(AVFormatContext *avf, int stream,
+ int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+ ConcatContext *cat = avf->priv_data;
+ int ret, left, right;
+
+ if (stream >= 0) {
+ if (stream >= avf->nb_streams)
+ return AVERROR(EINVAL);
+ rescale_interval(avf->streams[stream]->time_base, AV_TIME_BASE_Q,
+ &min_ts, &ts, &max_ts);
+ }
+
+ left = 0;
+ right = cat->nb_files;
+ while (right - left > 1) {
+ int mid = (left + right) / 2;
+ if (ts < cat->files[mid].start_time)
+ right = mid;
+ else
+ left = mid;
+ }
+
+ if ((ret = open_file(avf, left)) < 0)
+ return ret;
+
+ ret = try_seek(avf, stream, min_ts, ts, max_ts, flags);
+ if (ret < 0 &&
+ left < cat->nb_files - 1 &&
+ cat->files[left + 1].start_time < max_ts) {
+ if ((ret = open_file(avf, left + 1)) < 0)
+ return ret;
+ ret = try_seek(avf, stream, min_ts, ts, max_ts, flags);
+ }
+ return ret;
+}
+
+static int concat_seek(AVFormatContext *avf, int stream,
+ int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+ ConcatContext *cat = avf->priv_data;
+ ConcatFile *cur_file_saved = cat->cur_file;
+ AVFormatContext *cur_avf_saved = cat->avf;
+ int ret;
+
+ if (!cat->seekable)
+ return AVERROR(ESPIPE); /* XXX: can we use it? */
+ if (flags & (AVSEEK_FLAG_BYTE | AVSEEK_FLAG_FRAME))
+ return AVERROR(ENOSYS);
+ cat->avf = NULL;
+ if ((ret = real_seek(avf, stream, min_ts, ts, max_ts, flags)) < 0) {
+ if (cat->avf)
+ avformat_close_input(&cat->avf);
+ cat->avf = cur_avf_saved;
+ cat->cur_file = cur_file_saved;
+ } else {
+ avformat_close_input(&cur_avf_saved);
+ cat->eof = 0;
+ }
+ return ret;
+}
+
+#define OFFSET(x) offsetof(ConcatContext, x)
+#define DEC AV_OPT_FLAG_DECODING_PARAM
+
+static const AVOption options[] = {
+ { "safe", "enable safe mode",
+ OFFSET(safe), AV_OPT_TYPE_INT, {.i64 = 1}, -1, 1, DEC },
+ { "auto_convert", "automatically convert bitstream format",
+ OFFSET(auto_convert), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, DEC },
+ { NULL }
+};
+
+static const AVClass concat_class = {
+ .class_name = "concat demuxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+
+AVInputFormat ff_concat_demuxer = {
+ .name = "concat",
+ .long_name = NULL_IF_CONFIG_SMALL("Virtual concatenation script"),
+ .priv_data_size = sizeof(ConcatContext),
+ .read_probe = concat_probe,
+ .read_header = concat_read_header,
+ .read_packet = concat_read_packet,
+ .read_close = concat_read_close,
+ .read_seek2 = concat_seek,
+ .priv_class = &concat_class,
+};
diff --git a/ffmpeg-2-8-11/libavformat/crcenc.c b/ffmpeg-2-8-12/libavformat/crcenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/crcenc.c
rename to ffmpeg-2-8-12/libavformat/crcenc.c
diff --git a/ffmpeg-2-8-11/libavformat/crypto.c b/ffmpeg-2-8-12/libavformat/crypto.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/crypto.c
rename to ffmpeg-2-8-12/libavformat/crypto.c
diff --git a/ffmpeg-2-8-11/libavformat/cutils.c b/ffmpeg-2-8-12/libavformat/cutils.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/cutils.c
rename to ffmpeg-2-8-12/libavformat/cutils.c
diff --git a/ffmpeg-2-8-11/libavformat/dashenc.c b/ffmpeg-2-8-12/libavformat/dashenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dashenc.c
rename to ffmpeg-2-8-12/libavformat/dashenc.c
diff --git a/ffmpeg-2-8-11/libavformat/data_uri.c b/ffmpeg-2-8-12/libavformat/data_uri.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/data_uri.c
rename to ffmpeg-2-8-12/libavformat/data_uri.c
diff --git a/ffmpeg-2-8-11/libavformat/dauddec.c b/ffmpeg-2-8-12/libavformat/dauddec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dauddec.c
rename to ffmpeg-2-8-12/libavformat/dauddec.c
diff --git a/ffmpeg-2-8-11/libavformat/daudenc.c b/ffmpeg-2-8-12/libavformat/daudenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/daudenc.c
rename to ffmpeg-2-8-12/libavformat/daudenc.c
diff --git a/ffmpeg-2-8-11/libavformat/dfa.c b/ffmpeg-2-8-12/libavformat/dfa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dfa.c
rename to ffmpeg-2-8-12/libavformat/dfa.c
diff --git a/ffmpeg-2-8-11/libavformat/diracdec.c b/ffmpeg-2-8-12/libavformat/diracdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/diracdec.c
rename to ffmpeg-2-8-12/libavformat/diracdec.c
diff --git a/ffmpeg-2-8-11/libavformat/dnxhddec.c b/ffmpeg-2-8-12/libavformat/dnxhddec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dnxhddec.c
rename to ffmpeg-2-8-12/libavformat/dnxhddec.c
diff --git a/ffmpeg-2-8-11/libavformat/dsfdec.c b/ffmpeg-2-8-12/libavformat/dsfdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dsfdec.c
rename to ffmpeg-2-8-12/libavformat/dsfdec.c
diff --git a/ffmpeg-2-8-11/libavformat/dsicin.c b/ffmpeg-2-8-12/libavformat/dsicin.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dsicin.c
rename to ffmpeg-2-8-12/libavformat/dsicin.c
diff --git a/ffmpeg-2-8-11/libavformat/dss.c b/ffmpeg-2-8-12/libavformat/dss.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dss.c
rename to ffmpeg-2-8-12/libavformat/dss.c
diff --git a/ffmpeg-2-8-11/libavformat/dtsdec.c b/ffmpeg-2-8-12/libavformat/dtsdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dtsdec.c
rename to ffmpeg-2-8-12/libavformat/dtsdec.c
diff --git a/ffmpeg-2-8-11/libavformat/dtshddec.c b/ffmpeg-2-8-12/libavformat/dtshddec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dtshddec.c
rename to ffmpeg-2-8-12/libavformat/dtshddec.c
diff --git a/ffmpeg-2-8-11/libavformat/dump.c b/ffmpeg-2-8-12/libavformat/dump.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dump.c
rename to ffmpeg-2-8-12/libavformat/dump.c
diff --git a/ffmpeg-2-8-11/libavformat/dv.c b/ffmpeg-2-8-12/libavformat/dv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dv.c
rename to ffmpeg-2-8-12/libavformat/dv.c
diff --git a/ffmpeg-2-8-11/libavformat/dv.h b/ffmpeg-2-8-12/libavformat/dv.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dv.h
rename to ffmpeg-2-8-12/libavformat/dv.h
diff --git a/ffmpeg-2-8-11/libavformat/dvbsub.c b/ffmpeg-2-8-12/libavformat/dvbsub.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dvbsub.c
rename to ffmpeg-2-8-12/libavformat/dvbsub.c
diff --git a/ffmpeg-2-8-11/libavformat/dvenc.c b/ffmpeg-2-8-12/libavformat/dvenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dvenc.c
rename to ffmpeg-2-8-12/libavformat/dvenc.c
diff --git a/ffmpeg-2-8-11/libavformat/dxa.c b/ffmpeg-2-8-12/libavformat/dxa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/dxa.c
rename to ffmpeg-2-8-12/libavformat/dxa.c
diff --git a/ffmpeg-2-8-11/libavformat/eacdata.c b/ffmpeg-2-8-12/libavformat/eacdata.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/eacdata.c
rename to ffmpeg-2-8-12/libavformat/eacdata.c
diff --git a/ffmpeg-2-8-11/libavformat/electronicarts.c b/ffmpeg-2-8-12/libavformat/electronicarts.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/electronicarts.c
rename to ffmpeg-2-8-12/libavformat/electronicarts.c
diff --git a/ffmpeg-2-8-11/libavformat/epafdec.c b/ffmpeg-2-8-12/libavformat/epafdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/epafdec.c
rename to ffmpeg-2-8-12/libavformat/epafdec.c
diff --git a/ffmpeg-2-8-11/libavformat/ffm.h b/ffmpeg-2-8-12/libavformat/ffm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ffm.h
rename to ffmpeg-2-8-12/libavformat/ffm.h
diff --git a/ffmpeg-2-8-11/libavformat/ffmdec.c b/ffmpeg-2-8-12/libavformat/ffmdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ffmdec.c
rename to ffmpeg-2-8-12/libavformat/ffmdec.c
diff --git a/ffmpeg-2-8-11/libavformat/ffmenc.c b/ffmpeg-2-8-12/libavformat/ffmenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ffmenc.c
rename to ffmpeg-2-8-12/libavformat/ffmenc.c
diff --git a/ffmpeg-2-8-11/libavformat/ffmeta.h b/ffmpeg-2-8-12/libavformat/ffmeta.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ffmeta.h
rename to ffmpeg-2-8-12/libavformat/ffmeta.h
diff --git a/ffmpeg-2-8-11/libavformat/ffmetadec.c b/ffmpeg-2-8-12/libavformat/ffmetadec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ffmetadec.c
rename to ffmpeg-2-8-12/libavformat/ffmetadec.c
diff --git a/ffmpeg-2-8-11/libavformat/ffmetaenc.c b/ffmpeg-2-8-12/libavformat/ffmetaenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ffmetaenc.c
rename to ffmpeg-2-8-12/libavformat/ffmetaenc.c
diff --git a/ffmpeg-2-8-11/libavformat/file.c b/ffmpeg-2-8-12/libavformat/file.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/file.c
rename to ffmpeg-2-8-12/libavformat/file.c
diff --git a/ffmpeg-2-8-11/libavformat/file_open.c b/ffmpeg-2-8-12/libavformat/file_open.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/file_open.c
rename to ffmpeg-2-8-12/libavformat/file_open.c
diff --git a/ffmpeg-2-8-11/libavformat/filmstripdec.c b/ffmpeg-2-8-12/libavformat/filmstripdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/filmstripdec.c
rename to ffmpeg-2-8-12/libavformat/filmstripdec.c
diff --git a/ffmpeg-2-8-11/libavformat/filmstripenc.c b/ffmpeg-2-8-12/libavformat/filmstripenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/filmstripenc.c
rename to ffmpeg-2-8-12/libavformat/filmstripenc.c
diff --git a/ffmpeg-2-8-11/libavformat/flac_picture.c b/ffmpeg-2-8-12/libavformat/flac_picture.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/flac_picture.c
rename to ffmpeg-2-8-12/libavformat/flac_picture.c
diff --git a/ffmpeg-2-8-11/libavformat/flac_picture.h b/ffmpeg-2-8-12/libavformat/flac_picture.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/flac_picture.h
rename to ffmpeg-2-8-12/libavformat/flac_picture.h
diff --git a/ffmpeg-2-8-11/libavformat/flacdec.c b/ffmpeg-2-8-12/libavformat/flacdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/flacdec.c
rename to ffmpeg-2-8-12/libavformat/flacdec.c
diff --git a/ffmpeg-2-8-11/libavformat/flacenc.c b/ffmpeg-2-8-12/libavformat/flacenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/flacenc.c
rename to ffmpeg-2-8-12/libavformat/flacenc.c
diff --git a/ffmpeg-2-8-11/libavformat/flacenc.h b/ffmpeg-2-8-12/libavformat/flacenc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/flacenc.h
rename to ffmpeg-2-8-12/libavformat/flacenc.h
diff --git a/ffmpeg-2-8-11/libavformat/flacenc_header.c b/ffmpeg-2-8-12/libavformat/flacenc_header.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/flacenc_header.c
rename to ffmpeg-2-8-12/libavformat/flacenc_header.c
diff --git a/ffmpeg-2-8-11/libavformat/flic.c b/ffmpeg-2-8-12/libavformat/flic.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/flic.c
rename to ffmpeg-2-8-12/libavformat/flic.c
diff --git a/ffmpeg-2-8-11/libavformat/flv.h b/ffmpeg-2-8-12/libavformat/flv.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/flv.h
rename to ffmpeg-2-8-12/libavformat/flv.h
diff --git a/ffmpeg-2-8-11/libavformat/flvdec.c b/ffmpeg-2-8-12/libavformat/flvdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/flvdec.c
rename to ffmpeg-2-8-12/libavformat/flvdec.c
diff --git a/ffmpeg-2-8-11/libavformat/flvenc.c b/ffmpeg-2-8-12/libavformat/flvenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/flvenc.c
rename to ffmpeg-2-8-12/libavformat/flvenc.c
diff --git a/ffmpeg-2-8-11/libavformat/format.c b/ffmpeg-2-8-12/libavformat/format.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/format.c
rename to ffmpeg-2-8-12/libavformat/format.c
diff --git a/ffmpeg-2-8-11/libavformat/framecrcenc.c b/ffmpeg-2-8-12/libavformat/framecrcenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/framecrcenc.c
rename to ffmpeg-2-8-12/libavformat/framecrcenc.c
diff --git a/ffmpeg-2-8-11/libavformat/framehash.c b/ffmpeg-2-8-12/libavformat/framehash.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/framehash.c
rename to ffmpeg-2-8-12/libavformat/framehash.c
diff --git a/ffmpeg-2-8-11/libavformat/frmdec.c b/ffmpeg-2-8-12/libavformat/frmdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/frmdec.c
rename to ffmpeg-2-8-12/libavformat/frmdec.c
diff --git a/ffmpeg-2-8-11/libavformat/ftp.c b/ffmpeg-2-8-12/libavformat/ftp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ftp.c
rename to ffmpeg-2-8-12/libavformat/ftp.c
diff --git a/ffmpeg-2-8-11/libavformat/g722.c b/ffmpeg-2-8-12/libavformat/g722.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/g722.c
rename to ffmpeg-2-8-12/libavformat/g722.c
diff --git a/ffmpeg-2-8-11/libavformat/g723_1.c b/ffmpeg-2-8-12/libavformat/g723_1.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/g723_1.c
rename to ffmpeg-2-8-12/libavformat/g723_1.c
diff --git a/ffmpeg-2-8-11/libavformat/g729dec.c b/ffmpeg-2-8-12/libavformat/g729dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/g729dec.c
rename to ffmpeg-2-8-12/libavformat/g729dec.c
diff --git a/ffmpeg-2-8-11/libavformat/gif.c b/ffmpeg-2-8-12/libavformat/gif.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/gif.c
rename to ffmpeg-2-8-12/libavformat/gif.c
diff --git a/ffmpeg-2-8-11/libavformat/gifdec.c b/ffmpeg-2-8-12/libavformat/gifdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/gifdec.c
rename to ffmpeg-2-8-12/libavformat/gifdec.c
diff --git a/ffmpeg-2-8-11/libavformat/golomb_tab.c b/ffmpeg-2-8-12/libavformat/golomb_tab.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/golomb_tab.c
rename to ffmpeg-2-8-12/libavformat/golomb_tab.c
diff --git a/ffmpeg-2-8-11/libavformat/gopher.c b/ffmpeg-2-8-12/libavformat/gopher.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/gopher.c
rename to ffmpeg-2-8-12/libavformat/gopher.c
diff --git a/ffmpeg-2-8-11/libavformat/gsmdec.c b/ffmpeg-2-8-12/libavformat/gsmdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/gsmdec.c
rename to ffmpeg-2-8-12/libavformat/gsmdec.c
diff --git a/ffmpeg-2-8-11/libavformat/gxf.c b/ffmpeg-2-8-12/libavformat/gxf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/gxf.c
rename to ffmpeg-2-8-12/libavformat/gxf.c
diff --git a/ffmpeg-2-8-11/libavformat/gxf.h b/ffmpeg-2-8-12/libavformat/gxf.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/gxf.h
rename to ffmpeg-2-8-12/libavformat/gxf.h
diff --git a/ffmpeg-2-8-11/libavformat/gxfenc.c b/ffmpeg-2-8-12/libavformat/gxfenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/gxfenc.c
rename to ffmpeg-2-8-12/libavformat/gxfenc.c
diff --git a/ffmpeg-2-8-11/libavformat/h261dec.c b/ffmpeg-2-8-12/libavformat/h261dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/h261dec.c
rename to ffmpeg-2-8-12/libavformat/h261dec.c
diff --git a/ffmpeg-2-8-11/libavformat/h263dec.c b/ffmpeg-2-8-12/libavformat/h263dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/h263dec.c
rename to ffmpeg-2-8-12/libavformat/h263dec.c
diff --git a/ffmpeg-2-8-11/libavformat/h264dec.c b/ffmpeg-2-8-12/libavformat/h264dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/h264dec.c
rename to ffmpeg-2-8-12/libavformat/h264dec.c
diff --git a/ffmpeg-2-8-11/libavformat/hdsenc.c b/ffmpeg-2-8-12/libavformat/hdsenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/hdsenc.c
rename to ffmpeg-2-8-12/libavformat/hdsenc.c
diff --git a/ffmpeg-2-8-11/libavformat/hevc.c b/ffmpeg-2-8-12/libavformat/hevc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/hevc.c
rename to ffmpeg-2-8-12/libavformat/hevc.c
diff --git a/ffmpeg-2-8-11/libavformat/hevc.h b/ffmpeg-2-8-12/libavformat/hevc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/hevc.h
rename to ffmpeg-2-8-12/libavformat/hevc.h
diff --git a/ffmpeg-2-8-11/libavformat/hevcdec.c b/ffmpeg-2-8-12/libavformat/hevcdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/hevcdec.c
rename to ffmpeg-2-8-12/libavformat/hevcdec.c
diff --git a/ffmpeg-2-8-12/libavformat/hls.c b/ffmpeg-2-8-12/libavformat/hls.c
new file mode 100644
index 0000000..677421f
--- /dev/null
+++ b/ffmpeg-2-8-12/libavformat/hls.c
@@ -0,0 +1,2034 @@
+/*
+ * Apple HTTP Live Streaming demuxer
+ * Copyright (c) 2010 Martin Storsjo
+ * Copyright (c) 2013 Anssi Hannula
+ *
+ * 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
+ * Apple HTTP Live Streaming demuxer
+ * http://tools.ietf.org/html/draft-pantos-http-live-streaming
+ */
+
+#include "libavutil/avstring.h"
+#include "libavutil/avassert.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/dict.h"
+#include "libavutil/time.h"
+#include "avformat.h"
+#include "internal.h"
+#include "avio_internal.h"
+#include "url.h"
+#include "id3v2.h"
+
+#define INITIAL_BUFFER_SIZE 32768
+
+#define MAX_FIELD_LEN 64
+#define MAX_CHARACTERISTICS_LEN 512
+
+#define MPEG_TIME_BASE 90000
+#define MPEG_TIME_BASE_Q (AVRational){1, MPEG_TIME_BASE}
+
+/*
+ * An apple http stream consists of a playlist with media segment files,
+ * played sequentially. There may be several playlists with the same
+ * video content, in different bandwidth variants, that are played in
+ * parallel (preferably only one bandwidth variant at a time). In this case,
+ * the user supplied the url to a main playlist that only lists the variant
+ * playlists.
+ *
+ * If the main playlist doesn't point at any variants, we still create
+ * one anonymous toplevel variant for this, to maintain the structure.
+ */
+
+enum KeyType {
+ KEY_NONE,
+ KEY_AES_128,
+ KEY_SAMPLE_AES
+};
+
+struct segment {
+ int64_t duration;
+ int64_t url_offset;
+ int64_t size;
+ char *url;
+ char *key;
+ enum KeyType key_type;
+ uint8_t iv[16];
+ /* associated Media Initialization Section, treated as a segment */
+ struct segment *init_section;
+};
+
+struct rendition;
+
+enum PlaylistType {
+ PLS_TYPE_UNSPECIFIED,
+ PLS_TYPE_EVENT,
+ PLS_TYPE_VOD
+};
+
+/*
+ * Each playlist has its own demuxer. If it currently is active,
+ * it has an open AVIOContext too, and potentially an AVPacket
+ * containing the next packet from this stream.
+ */
+struct playlist {
+ char url[MAX_URL_SIZE];
+ AVIOContext pb;
+ uint8_t* read_buffer;
+ URLContext *input;
+ AVFormatContext *parent;
+ int index;
+ AVFormatContext *ctx;
+ AVPacket pkt;
+ int stream_offset;
+
+ int finished;
+ enum PlaylistType type;
+ int64_t target_duration;
+ int start_seq_no;
+ int n_segments;
+ struct segment **segments;
+ int needed, cur_needed;
+ int cur_seq_no;
+ int64_t cur_seg_offset;
+ int64_t last_load_time;
+
+ /* Currently active Media Initialization Section */
+ struct segment *cur_init_section;
+ uint8_t *init_sec_buf;
+ unsigned int init_sec_buf_size;
+ unsigned int init_sec_data_len;
+ unsigned int init_sec_buf_read_offset;
+
+ char key_url[MAX_URL_SIZE];
+ uint8_t key[16];
+
+ /* ID3 timestamp handling (elementary audio streams have ID3 timestamps
+ * (and possibly other ID3 tags) in the beginning of each segment) */
+ int is_id3_timestamped; /* -1: not yet known */
+ int64_t id3_mpegts_timestamp; /* in mpegts tb */
+ int64_t id3_offset; /* in stream original tb */
+ uint8_t* id3_buf; /* temp buffer for id3 parsing */
+ unsigned int id3_buf_size;
+ AVDictionary *id3_initial; /* data from first id3 tag */
+ int id3_found; /* ID3 tag found at some point */
+ int id3_changed; /* ID3 tag data has changed at some point */
+ ID3v2ExtraMeta *id3_deferred_extra; /* stored here until subdemuxer is opened */
+
+ int64_t seek_timestamp;
+ int seek_flags;
+ int seek_stream_index; /* into subdemuxer stream array */
+
+ /* Renditions associated with this playlist, if any.
+ * Alternative rendition playlists have a single rendition associated
+ * with them, and variant main Media Playlists may have
+ * multiple (playlist-less) renditions associated with them. */
+ int n_renditions;
+ struct rendition **renditions;
+
+ /* Media Initialization Sections (EXT-X-MAP) associated with this
+ * playlist, if any. */
+ int n_init_sections;
+ struct segment **init_sections;
+};
+
+/*
+ * Renditions are e.g. alternative subtitle or audio streams.
+ * The rendition may either be an external playlist or it may be
+ * contained in the main Media Playlist of the variant (in which case
+ * playlist is NULL).
+ */
+struct rendition {
+ enum AVMediaType type;
+ struct playlist *playlist;
+ char group_id[MAX_FIELD_LEN];
+ char language[MAX_FIELD_LEN];
+ char name[MAX_FIELD_LEN];
+ int disposition;
+};
+
+struct variant {
+ int bandwidth;
+
+ /* every variant contains at least the main Media Playlist in index 0 */
+ int n_playlists;
+ struct playlist **playlists;
+
+ char audio_group[MAX_FIELD_LEN];
+ char video_group[MAX_FIELD_LEN];
+ char subtitles_group[MAX_FIELD_LEN];
+};
+
+typedef struct HLSContext {
+ AVClass *class;
+ int n_variants;
+ struct variant **variants;
+ int n_playlists;
+ struct playlist **playlists;
+ int n_renditions;
+ struct rendition **renditions;
+
+ int cur_seq_no;
+ int live_start_index;
+ int first_packet;
+ int64_t first_timestamp;
+ int64_t cur_timestamp;
+ AVIOInterruptCB *interrupt_callback;
+ char *user_agent; ///< holds HTTP user agent set as an AVOption to the HTTP protocol context
+ char *cookies; ///< holds HTTP cookie values set in either the initial response or as an AVOption to the HTTP protocol context
+ char *headers; ///< holds HTTP headers set as an AVOption to the HTTP protocol context
+ AVDictionary *avio_opts;
+ char *allowed_extensions;
+} HLSContext;
+
+static int read_chomp_line(AVIOContext *s, char *buf, int maxlen)
+{
+ int len = ff_get_line(s, buf, maxlen);
+ while (len > 0 && av_isspace(buf[len - 1]))
+ buf[--len] = '\0';
+ return len;
+}
+
+static void free_segment_list(struct playlist *pls)
+{
+ int i;
+ for (i = 0; i < pls->n_segments; i++) {
+ av_freep(&pls->segments[i]->key);
+ av_freep(&pls->segments[i]->url);
+ av_freep(&pls->segments[i]);
+ }
+ av_freep(&pls->segments);
+ pls->n_segments = 0;
+}
+
+static void free_init_section_list(struct playlist *pls)
+{
+ int i;
+ for (i = 0; i < pls->n_init_sections; i++) {
+ av_freep(&pls->init_sections[i]->url);
+ av_freep(&pls->init_sections[i]);
+ }
+ av_freep(&pls->init_sections);
+ pls->n_init_sections = 0;
+}
+
+static void free_playlist_list(HLSContext *c)
+{
+ int i;
+ for (i = 0; i < c->n_playlists; i++) {
+ struct playlist *pls = c->playlists[i];
+ free_segment_list(pls);
+ free_init_section_list(pls);
+ av_freep(&pls->renditions);
+ av_freep(&pls->id3_buf);
+ av_dict_free(&pls->id3_initial);
+ ff_id3v2_free_extra_meta(&pls->id3_deferred_extra);
+ av_freep(&pls->init_sec_buf);
+ av_free_packet(&pls->pkt);
+ av_freep(&pls->pb.buffer);
+ if (pls->input)
+ ffurl_close(pls->input);
+ if (pls->ctx) {
+ pls->ctx->pb = NULL;
+ avformat_close_input(&pls->ctx);
+ }
+ av_free(pls);
+ }
+ av_freep(&c->playlists);
+ av_freep(&c->cookies);
+ av_freep(&c->user_agent);
+ c->n_playlists = 0;
+}
+
+static void free_variant_list(HLSContext *c)
+{
+ int i;
+ for (i = 0; i < c->n_variants; i++) {
+ struct variant *var = c->variants[i];
+ av_freep(&var->playlists);
+ av_free(var);
+ }
+ av_freep(&c->variants);
+ c->n_variants = 0;
+}
+
+static void free_rendition_list(HLSContext *c)
+{
+ int i;
+ for (i = 0; i < c->n_renditions; i++)
+ av_freep(&c->renditions[i]);
+ av_freep(&c->renditions);
+ c->n_renditions = 0;
+}
+
+/*
+ * Used to reset a statically allocated AVPacket to a clean slate,
+ * 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);
+ pls->seek_timestamp = AV_NOPTS_VALUE;
+
+ pls->is_id3_timestamped = -1;
+ pls->id3_mpegts_timestamp = AV_NOPTS_VALUE;
+
+ dynarray_add(&c->playlists, &c->n_playlists, pls);
+ return pls;
+}
+
+struct variant_info {
+ char bandwidth[20];
+ /* variant group ids: */
+ char audio[MAX_FIELD_LEN];
+ char video[MAX_FIELD_LEN];
+ char subtitles[MAX_FIELD_LEN];
+};
+
+static struct variant *new_variant(HLSContext *c, struct variant_info *info,
+ const char *url, const char *base)
+{
+ struct variant *var;
+ struct playlist *pls;
+
+ pls = new_playlist(c, url, base);
+ if (!pls)
+ return NULL;
+
+ var = av_mallocz(sizeof(struct variant));
+ if (!var)
+ return NULL;
+
+ if (info) {
+ var->bandwidth = atoi(info->bandwidth);
+ strcpy(var->audio_group, info->audio);
+ strcpy(var->video_group, info->video);
+ strcpy(var->subtitles_group, info->subtitles);
+ }
+
+ dynarray_add(&c->variants, &c->n_variants, var);
+ dynarray_add(&var->playlists, &var->n_playlists, pls);
+ return var;
+}
+
+static void handle_variant_args(struct variant_info *info, const char *key,
+ int key_len, char **dest, int *dest_len)
+{
+ if (!strncmp(key, "BANDWIDTH=", key_len)) {
+ *dest = info->bandwidth;
+ *dest_len = sizeof(info->bandwidth);
+ } else if (!strncmp(key, "AUDIO=", key_len)) {
+ *dest = info->audio;
+ *dest_len = sizeof(info->audio);
+ } else if (!strncmp(key, "VIDEO=", key_len)) {
+ *dest = info->video;
+ *dest_len = sizeof(info->video);
+ } else if (!strncmp(key, "SUBTITLES=", key_len)) {
+ *dest = info->subtitles;
+ *dest_len = sizeof(info->subtitles);
+ }
+}
+
+struct key_info {
+ char uri[MAX_URL_SIZE];
+ char method[11];
+ char iv[35];
+};
+
+static void handle_key_args(struct key_info *info, const char *key,
+ int key_len, char **dest, int *dest_len)
+{
+ if (!strncmp(key, "METHOD=", key_len)) {
+ *dest = info->method;
+ *dest_len = sizeof(info->method);
+ } else if (!strncmp(key, "URI=", key_len)) {
+ *dest = info->uri;
+ *dest_len = sizeof(info->uri);
+ } else if (!strncmp(key, "IV=", key_len)) {
+ *dest = info->iv;
+ *dest_len = sizeof(info->iv);
+ }
+}
+
+struct init_section_info {
+ char uri[MAX_URL_SIZE];
+ char byterange[32];
+};
+
+static struct segment *new_init_section(struct playlist *pls,
+ struct init_section_info *info,
+ const char *url_base)
+{
+ struct segment *sec;
+ char *ptr;
+ char tmp_str[MAX_URL_SIZE];
+
+ if (!info->uri[0])
+ return NULL;
+
+ sec = av_mallocz(sizeof(*sec));
+ if (!sec)
+ return NULL;
+
+ ff_make_absolute_url(tmp_str, sizeof(tmp_str), url_base, info->uri);
+ sec->url = av_strdup(tmp_str);
+ if (!sec->url) {
+ av_free(sec);
+ return NULL;
+ }
+
+ if (info->byterange[0]) {
+ sec->size = atoi(info->byterange);
+ ptr = strchr(info->byterange, '@');
+ if (ptr)
+ sec->url_offset = atoi(ptr+1);
+ } else {
+ /* the entire file is the init section */
+ sec->size = -1;
+ }
+
+ dynarray_add(&pls->init_sections, &pls->n_init_sections, sec);
+
+ return sec;
+}
+
+static void handle_init_section_args(struct init_section_info *info, const char *key,
+ int key_len, char **dest, int *dest_len)
+{
+ if (!strncmp(key, "URI=", key_len)) {
+ *dest = info->uri;
+ *dest_len = sizeof(info->uri);
+ } else if (!strncmp(key, "BYTERANGE=", key_len)) {
+ *dest = info->byterange;
+ *dest_len = sizeof(info->byterange);
+ }
+}
+
+struct rendition_info {
+ char type[16];
+ char uri[MAX_URL_SIZE];
+ char group_id[MAX_FIELD_LEN];
+ char language[MAX_FIELD_LEN];
+ char assoc_language[MAX_FIELD_LEN];
+ char name[MAX_FIELD_LEN];
+ char defaultr[4];
+ char forced[4];
+ char characteristics[MAX_CHARACTERISTICS_LEN];
+};
+
+static struct rendition *new_rendition(HLSContext *c, struct rendition_info *info,
+ const char *url_base)
+{
+ struct rendition *rend;
+ enum AVMediaType type = AVMEDIA_TYPE_UNKNOWN;
+ char *characteristic;
+ char *chr_ptr;
+ char *saveptr;
+
+ if (!strcmp(info->type, "AUDIO"))
+ type = AVMEDIA_TYPE_AUDIO;
+ else if (!strcmp(info->type, "VIDEO"))
+ type = AVMEDIA_TYPE_VIDEO;
+ else if (!strcmp(info->type, "SUBTITLES"))
+ type = AVMEDIA_TYPE_SUBTITLE;
+ else if (!strcmp(info->type, "CLOSED-CAPTIONS"))
+ /* CLOSED-CAPTIONS is ignored since we do not support CEA-608 CC in
+ * AVC SEI RBSP anyway */
+ return NULL;
+
+ if (type == AVMEDIA_TYPE_UNKNOWN)
+ return NULL;
+
+ /* URI is mandatory for subtitles as per spec */
+ if (type == AVMEDIA_TYPE_SUBTITLE && !info->uri[0])
+ return NULL;
+
+ /* TODO: handle subtitles (each segment has to parsed separately) */
+ if (type == AVMEDIA_TYPE_SUBTITLE)
+ return NULL;
+
+ rend = av_mallocz(sizeof(struct rendition));
+ if (!rend)
+ return NULL;
+
+ dynarray_add(&c->renditions, &c->n_renditions, rend);
+
+ rend->type = type;
+ strcpy(rend->group_id, info->group_id);
+ strcpy(rend->language, info->language);
+ strcpy(rend->name, info->name);
+
+ /* add the playlist if this is an external rendition */
+ if (info->uri[0]) {
+ rend->playlist = new_playlist(c, info->uri, url_base);
+ if (rend->playlist)
+ dynarray_add(&rend->playlist->renditions,
+ &rend->playlist->n_renditions, rend);
+ }
+
+ if (info->assoc_language[0]) {
+ int langlen = strlen(rend->language);
+ if (langlen < sizeof(rend->language) - 3) {
+ rend->language[langlen] = ',';
+ strncpy(rend->language + langlen + 1, info->assoc_language,
+ sizeof(rend->language) - langlen - 2);
+ }
+ }
+
+ if (!strcmp(info->defaultr, "YES"))
+ rend->disposition |= AV_DISPOSITION_DEFAULT;
+ if (!strcmp(info->forced, "YES"))
+ rend->disposition |= AV_DISPOSITION_FORCED;
+
+ chr_ptr = info->characteristics;
+ while ((characteristic = av_strtok(chr_ptr, ",", &saveptr))) {
+ if (!strcmp(characteristic, "public.accessibility.describes-music-and-sound"))
+ rend->disposition |= AV_DISPOSITION_HEARING_IMPAIRED;
+ else if (!strcmp(characteristic, "public.accessibility.describes-video"))
+ rend->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;
+
+ chr_ptr = NULL;
+ }
+
+ return rend;
+}
+
+static void handle_rendition_args(struct rendition_info *info, const char *key,
+ int key_len, char **dest, int *dest_len)
+{
+ if (!strncmp(key, "TYPE=", key_len)) {
+ *dest = info->type;
+ *dest_len = sizeof(info->type);
+ } else if (!strncmp(key, "URI=", key_len)) {
+ *dest = info->uri;
+ *dest_len = sizeof(info->uri);
+ } else if (!strncmp(key, "GROUP-ID=", key_len)) {
+ *dest = info->group_id;
+ *dest_len = sizeof(info->group_id);
+ } else if (!strncmp(key, "LANGUAGE=", key_len)) {
+ *dest = info->language;
+ *dest_len = sizeof(info->language);
+ } else if (!strncmp(key, "ASSOC-LANGUAGE=", key_len)) {
+ *dest = info->assoc_language;
+ *dest_len = sizeof(info->assoc_language);
+ } else if (!strncmp(key, "NAME=", key_len)) {
+ *dest = info->name;
+ *dest_len = sizeof(info->name);
+ } else if (!strncmp(key, "DEFAULT=", key_len)) {
+ *dest = info->defaultr;
+ *dest_len = sizeof(info->defaultr);
+ } else if (!strncmp(key, "FORCED=", key_len)) {
+ *dest = info->forced;
+ *dest_len = sizeof(info->forced);
+ } else if (!strncmp(key, "CHARACTERISTICS=", key_len)) {
+ *dest = info->characteristics;
+ *dest_len = sizeof(info->characteristics);
+ }
+ /*
+ * ignored:
+ * - AUTOSELECT: client may autoselect based on e.g. system language
+ * - INSTREAM-ID: EIA-608 closed caption number ("CC1".."CC4")
+ */
+}
+
+/* used by parse_playlist to allocate a new variant+playlist when the
+ * playlist is detected to be a Media Playlist (not Master Playlist)
+ * and we have no parent Master Playlist (parsing of which would have
+ * allocated the variant and playlist already)
+ * *pls == NULL => Master Playlist or parentless Media Playlist
+ * *pls != NULL => parented Media Playlist, playlist+variant allocated */
+static int ensure_playlist(HLSContext *c, struct playlist **pls, const char *url)
+{
+ if (*pls)
+ return 0;
+ if (!new_variant(c, NULL, url, NULL))
+ return AVERROR(ENOMEM);
+ *pls = c->playlists[c->n_playlists - 1];
+ return 0;
+}
+
+static int open_in(HLSContext *c, AVIOContext **in, const char *url)
+{
+ AVDictionary *tmp = NULL;
+ int ret;
+
+ av_dict_copy(&tmp, c->avio_opts, 0);
+
+ ret = avio_open2(in, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp);
+
+ av_dict_free(&tmp);
+ return ret;
+}
+
+static int url_connect(struct playlist *pls, AVDictionary *opts, AVDictionary *opts2)
+{
+ AVDictionary *tmp = NULL;
+ int ret;
+
+ av_dict_copy(&tmp, opts, 0);
+ av_dict_copy(&tmp, opts2, 0);
+
+ if ((ret = ffurl_connect(pls->input, &tmp)) < 0) {
+ ffurl_close(pls->input);
+ pls->input = NULL;
+ }
+
+ av_dict_free(&tmp);
+ return ret;
+}
+
+static void update_options(char **dest, const char *name, void *src)
+{
+ av_freep(dest);
+ av_opt_get(src, name, 0, (uint8_t**)dest);
+ if (*dest && !strlen(*dest))
+ av_freep(dest);
+}
+
+static int open_url(HLSContext *c, URLContext **uc, const char *url, AVDictionary *opts)
+{
+ AVDictionary *tmp = NULL;
+ int ret;
+ const char *proto_name = avio_find_protocol_name(url);
+
+ if (!proto_name)
+ return AVERROR_INVALIDDATA;
+
+ // only http(s) & file are allowed
+ if (av_strstart(proto_name, "file", NULL)) {
+ if (strcmp(c->allowed_extensions, "ALL") && !av_match_ext(url, c->allowed_extensions)) {
+ av_log(c, AV_LOG_ERROR,
+ "Filename extension of \'%s\' is not a common multimedia extension, blocked for security reasons.\n"
+ "If you wish to override this adjust allowed_extensions, you can set it to \'ALL\' to allow all\n",
+ url);
+ return AVERROR_INVALIDDATA;
+ }
+ } else if (av_strstart(proto_name, "http", NULL)) {
+ ;
+ } else
+ return AVERROR_INVALIDDATA;
+
+ if (!strncmp(proto_name, url, strlen(proto_name)) && url[strlen(proto_name)] == ':')
+ ;
+ else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5))
+ return AVERROR_INVALIDDATA;
+
+ av_dict_copy(&tmp, c->avio_opts, 0);
+ av_dict_copy(&tmp, opts, 0);
+
+ ret = ffurl_open(uc, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp);
+ if( ret >= 0) {
+ // update cookies on http response with setcookies.
+ URLContext *u = *uc;
+ update_options(&c->cookies, "cookies", u->priv_data);
+ av_dict_set(&opts, "cookies", c->cookies, 0);
+ }
+
+ av_dict_free(&tmp);
+
+ return ret;
+}
+
+static int parse_playlist(HLSContext *c, const char *url,
+ struct playlist *pls, AVIOContext *in)
+{
+ int ret = 0, is_segment = 0, is_variant = 0;
+ int64_t duration = 0;
+ enum KeyType key_type = KEY_NONE;
+ uint8_t iv[16] = "";
+ int has_iv = 0;
+ char key[MAX_URL_SIZE] = "";
+ char line[MAX_URL_SIZE];
+ const char *ptr;
+ int close_in = 0;
+ int64_t seg_offset = 0;
+ int64_t seg_size = -1;
+ uint8_t *new_url = NULL;
+ struct variant_info variant_info;
+ char tmp_str[MAX_URL_SIZE];
+ struct segment *cur_init_section = NULL;
+
+ if (!in) {
+#if 1
+ AVDictionary *opts = NULL;
+ close_in = 1;
+ /* Some HLS servers don't like being sent the range header */
+ av_dict_set(&opts, "seekable", "0", 0);
+
+ // broker prior HTTP options that should be consistent across requests
+ av_dict_set(&opts, "user-agent", c->user_agent, 0);
+ av_dict_set(&opts, "cookies", c->cookies, 0);
+ av_dict_set(&opts, "headers", c->headers, 0);
+
+ ret = avio_open2(&in, url, AVIO_FLAG_READ,
+ c->interrupt_callback, &opts);
+ av_dict_free(&opts);
+ if (ret < 0)
+ return ret;
+#else
+ ret = open_in(c, &in, url);
+ if (ret < 0)
+ return ret;
+ close_in = 1;
+#endif
+ }
+
+ if (av_opt_get(in, "location", AV_OPT_SEARCH_CHILDREN, &new_url) >= 0)
+ url = new_url;
+
+ read_chomp_line(in, line, sizeof(line));
+ if (strcmp(line, "#EXTM3U")) {
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+
+ if (pls) {
+ free_segment_list(pls);
+ pls->finished = 0;
+ pls->type = PLS_TYPE_UNSPECIFIED;
+ }
+ while (!avio_feof(in)) {
+ read_chomp_line(in, line, sizeof(line));
+ if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) {
+ is_variant = 1;
+ memset(&variant_info, 0, sizeof(variant_info));
+ ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args,
+ &variant_info);
+ } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) {
+ struct key_info info = {{0}};
+ ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_key_args,
+ &info);
+ key_type = KEY_NONE;
+ has_iv = 0;
+ if (!strcmp(info.method, "AES-128"))
+ key_type = KEY_AES_128;
+ if (!strcmp(info.method, "SAMPLE-AES"))
+ key_type = KEY_SAMPLE_AES;
+ if (!strncmp(info.iv, "0x", 2) || !strncmp(info.iv, "0X", 2)) {
+ ff_hex_to_data(iv, info.iv + 2);
+ has_iv = 1;
+ }
+ av_strlcpy(key, info.uri, sizeof(key));
+ } else if (av_strstart(line, "#EXT-X-MEDIA:", &ptr)) {
+ struct rendition_info info = {{0}};
+ ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_rendition_args,
+ &info);
+ new_rendition(c, &info, url);
+ } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) {
+ ret = ensure_playlist(c, &pls, url);
+ if (ret < 0)
+ goto fail;
+ pls->target_duration = atoi(ptr) * AV_TIME_BASE;
+ } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) {
+ ret = ensure_playlist(c, &pls, url);
+ if (ret < 0)
+ goto fail;
+ pls->start_seq_no = atoi(ptr);
+ } else if (av_strstart(line, "#EXT-X-PLAYLIST-TYPE:", &ptr)) {
+ ret = ensure_playlist(c, &pls, url);
+ if (ret < 0)
+ goto fail;
+ if (!strcmp(ptr, "EVENT"))
+ pls->type = PLS_TYPE_EVENT;
+ else if (!strcmp(ptr, "VOD"))
+ pls->type = PLS_TYPE_VOD;
+ } else if (av_strstart(line, "#EXT-X-MAP:", &ptr)) {
+ struct init_section_info info = {{0}};
+ ret = ensure_playlist(c, &pls, url);
+ if (ret < 0)
+ goto fail;
+ ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_init_section_args,
+ &info);
+ cur_init_section = new_init_section(pls, &info, url);
+ } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) {
+ if (pls)
+ pls->finished = 1;
+ } else if (av_strstart(line, "#EXTINF:", &ptr)) {
+ is_segment = 1;
+ duration = atof(ptr) * AV_TIME_BASE;
+ } else if (av_strstart(line, "#EXT-X-BYTERANGE:", &ptr)) {
+ seg_size = atoi(ptr);
+ ptr = strchr(ptr, '@');
+ if (ptr)
+ seg_offset = atoi(ptr+1);
+ } else if (av_strstart(line, "#", NULL)) {
+ continue;
+ } else if (line[0]) {
+ if (is_variant) {
+ if (!new_variant(c, &variant_info, line, url)) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ is_variant = 0;
+ }
+ if (is_segment) {
+ struct segment *seg;
+ if (!pls) {
+ if (!new_variant(c, 0, url, NULL)) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ pls = c->playlists[c->n_playlists - 1];
+ }
+ seg = av_malloc(sizeof(struct segment));
+ if (!seg) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ seg->duration = duration;
+ seg->key_type = key_type;
+ if (has_iv) {
+ memcpy(seg->iv, iv, sizeof(iv));
+ } else {
+ int seq = pls->start_seq_no + pls->n_segments;
+ memset(seg->iv, 0, sizeof(seg->iv));
+ AV_WB32(seg->iv + 12, seq);
+ }
+
+ if (key_type != KEY_NONE) {
+ ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, key);
+ seg->key = av_strdup(tmp_str);
+ if (!seg->key) {
+ av_free(seg);
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ } else {
+ seg->key = NULL;
+ }
+
+ ff_make_absolute_url(tmp_str, sizeof(tmp_str), url, line);
+ seg->url = av_strdup(tmp_str);
+ if (!seg->url) {
+ av_free(seg->key);
+ av_free(seg);
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ dynarray_add(&pls->segments, &pls->n_segments, seg);
+ is_segment = 0;
+
+ seg->size = seg_size;
+ if (seg_size >= 0) {
+ seg->url_offset = seg_offset;
+ seg_offset += seg_size;
+ seg_size = -1;
+ } else {
+ seg->url_offset = 0;
+ seg_offset = 0;
+ }
+
+ seg->init_section = cur_init_section;
+ }
+ }
+ }
+ if (pls)
+ pls->last_load_time = av_gettime_relative();
+
+fail:
+ av_free(new_url);
+ if (close_in)
+ avio_close(in);
+ return ret;
+}
+
+static struct segment *current_segment(struct playlist *pls)
+{
+ return pls->segments[pls->cur_seq_no - pls->start_seq_no];
+}
+
+enum ReadFromURLMode {
+ READ_NORMAL,
+ READ_COMPLETE,
+};
+
+/* read from URLContext, limiting read to current segment */
+static int read_from_url(struct playlist *pls, struct segment *seg,
+ uint8_t *buf, int buf_size,
+ enum ReadFromURLMode mode)
+{
+ int ret;
+
+ /* limit read if the segment was only a part of a file */
+ if (seg->size >= 0)
+ buf_size = FFMIN(buf_size, seg->size - pls->cur_seg_offset);
+
+ if (mode == READ_COMPLETE)
+ ret = ffurl_read_complete(pls->input, buf, buf_size);
+ else
+ ret = ffurl_read(pls->input, buf, buf_size);
+
+ if (ret > 0)
+ pls->cur_seg_offset += ret;
+
+ return ret;
+}
+
+/* Parse the raw ID3 data and pass contents to caller */
+static void parse_id3(AVFormatContext *s, AVIOContext *pb,
+ AVDictionary **metadata, int64_t *dts,
+ ID3v2ExtraMetaAPIC **apic, ID3v2ExtraMeta **extra_meta)
+{
+ static const char id3_priv_owner_ts[] = "com.apple.streaming.transportStreamTimestamp";
+ ID3v2ExtraMeta *meta;
+
+ ff_id3v2_read_dict(pb, metadata, ID3v2_DEFAULT_MAGIC, extra_meta);
+ for (meta = *extra_meta; meta; meta = meta->next) {
+ if (!strcmp(meta->tag, "PRIV")) {
+ ID3v2ExtraMetaPRIV *priv = meta->data;
+ if (priv->datasize == 8 && !strcmp(priv->owner, id3_priv_owner_ts)) {
+ /* 33-bit MPEG timestamp */
+ int64_t ts = AV_RB64(priv->data);
+ av_log(s, AV_LOG_DEBUG, "HLS ID3 audio timestamp %"PRId64"\n", ts);
+ if ((ts & ~((1ULL << 33) - 1)) == 0)
+ *dts = ts;
+ else
+ av_log(s, AV_LOG_ERROR, "Invalid HLS ID3 audio timestamp %"PRId64"\n", ts);
+ }
+ } else if (!strcmp(meta->tag, "APIC") && apic)
+ *apic = meta->data;
+ }
+}
+
+/* Check if the ID3 metadata contents have changed */
+static int id3_has_changed_values(struct playlist *pls, AVDictionary *metadata,
+ ID3v2ExtraMetaAPIC *apic)
+{
+ AVDictionaryEntry *entry = NULL;
+ AVDictionaryEntry *oldentry;
+ /* check that no keys have changed values */
+ while ((entry = av_dict_get(metadata, "", entry, AV_DICT_IGNORE_SUFFIX))) {
+ oldentry = av_dict_get(pls->id3_initial, entry->key, NULL, AV_DICT_MATCH_CASE);
+ if (!oldentry || strcmp(oldentry->value, entry->value) != 0)
+ return 1;
+ }
+
+ /* check if apic appeared */
+ if (apic && (pls->ctx->nb_streams != 2 || !pls->ctx->streams[1]->attached_pic.data))
+ return 1;
+
+ if (apic) {
+ int size = pls->ctx->streams[1]->attached_pic.size;
+ if (size != apic->buf->size - AV_INPUT_BUFFER_PADDING_SIZE)
+ return 1;
+
+ if (memcmp(apic->buf->data, pls->ctx->streams[1]->attached_pic.data, size) != 0)
+ return 1;
+ }
+
+ return 0;
+}
+
+/* Parse ID3 data and handle the found data */
+static void handle_id3(AVIOContext *pb, struct playlist *pls)
+{
+ AVDictionary *metadata = NULL;
+ ID3v2ExtraMetaAPIC *apic = NULL;
+ ID3v2ExtraMeta *extra_meta = NULL;
+ int64_t timestamp = AV_NOPTS_VALUE;
+
+ parse_id3(pls->ctx, pb, &metadata, ×tamp, &apic, &extra_meta);
+
+ if (timestamp != AV_NOPTS_VALUE) {
+ pls->id3_mpegts_timestamp = timestamp;
+ pls->id3_offset = 0;
+ }
+
+ if (!pls->id3_found) {
+ /* initial ID3 tags */
+ av_assert0(!pls->id3_deferred_extra);
+ pls->id3_found = 1;
+
+ /* get picture attachment and set text metadata */
+ if (pls->ctx->nb_streams)
+ ff_id3v2_parse_apic(pls->ctx, &extra_meta);
+ else
+ /* demuxer not yet opened, defer picture attachment */
+ pls->id3_deferred_extra = extra_meta;
+
+ av_dict_copy(&pls->ctx->metadata, metadata, 0);
+ pls->id3_initial = metadata;
+
+ } else {
+ if (!pls->id3_changed && id3_has_changed_values(pls, metadata, apic)) {
+ avpriv_report_missing_feature(pls->ctx, "Changing ID3 metadata in HLS audio elementary stream");
+ pls->id3_changed = 1;
+ }
+ av_dict_free(&metadata);
+ }
+
+ if (!pls->id3_deferred_extra)
+ ff_id3v2_free_extra_meta(&extra_meta);
+}
+
+/* Intercept and handle ID3 tags between URLContext and AVIOContext */
+static void intercept_id3(struct playlist *pls, uint8_t *buf,
+ int buf_size, int *len)
+{
+ /* intercept id3 tags, we do not want to pass them to the raw
+ * demuxer on all segment switches */
+ int bytes;
+ int id3_buf_pos = 0;
+ int fill_buf = 0;
+ struct segment *seg = current_segment(pls);
+
+ /* gather all the id3 tags */
+ while (1) {
+ /* see if we can retrieve enough data for ID3 header */
+ if (*len < ID3v2_HEADER_SIZE && buf_size >= ID3v2_HEADER_SIZE) {
+ bytes = read_from_url(pls, seg, buf + *len, ID3v2_HEADER_SIZE - *len, READ_COMPLETE);
+ if (bytes > 0) {
+
+ if (bytes == ID3v2_HEADER_SIZE - *len)
+ /* no EOF yet, so fill the caller buffer again after
+ * we have stripped the ID3 tags */
+ fill_buf = 1;
+
+ *len += bytes;
+
+ } else if (*len <= 0) {
+ /* error/EOF */
+ *len = bytes;
+ fill_buf = 0;
+ }
+ }
+
+ if (*len < ID3v2_HEADER_SIZE)
+ break;
+
+ if (ff_id3v2_match(buf, ID3v2_DEFAULT_MAGIC)) {
+ int64_t maxsize = seg->size >= 0 ? seg->size : 1024*1024;
+ int taglen = ff_id3v2_tag_len(buf);
+ int tag_got_bytes = FFMIN(taglen, *len);
+ int remaining = taglen - tag_got_bytes;
+
+ if (taglen > maxsize) {
+ av_log(pls->ctx, AV_LOG_ERROR, "Too large HLS ID3 tag (%d > %"PRId64" bytes)\n",
+ taglen, maxsize);
+ break;
+ }
+
+ /*
+ * Copy the id3 tag to our temporary id3 buffer.
+ * We could read a small id3 tag directly without memcpy, but
+ * we would still need to copy the large tags, and handling
+ * both of those cases together with the possibility for multiple
+ * tags would make the handling a bit complex.
+ */
+ pls->id3_buf = av_fast_realloc(pls->id3_buf, &pls->id3_buf_size, id3_buf_pos + taglen);
+ if (!pls->id3_buf)
+ break;
+ memcpy(pls->id3_buf + id3_buf_pos, buf, tag_got_bytes);
+ id3_buf_pos += tag_got_bytes;
+
+ /* strip the intercepted bytes */
+ *len -= tag_got_bytes;
+ memmove(buf, buf + tag_got_bytes, *len);
+ av_log(pls->ctx, AV_LOG_DEBUG, "Stripped %d HLS ID3 bytes\n", tag_got_bytes);
+
+ if (remaining > 0) {
+ /* read the rest of the tag in */
+ if (read_from_url(pls, seg, pls->id3_buf + id3_buf_pos, remaining, READ_COMPLETE) != remaining)
+ break;
+ id3_buf_pos += remaining;
+ av_log(pls->ctx, AV_LOG_DEBUG, "Stripped additional %d HLS ID3 bytes\n", remaining);
+ }
+
+ } else {
+ /* no more ID3 tags */
+ break;
+ }
+ }
+
+ /* re-fill buffer for the caller unless EOF */
+ if (*len >= 0 && (fill_buf || *len == 0)) {
+ bytes = read_from_url(pls, seg, buf + *len, buf_size - *len, READ_NORMAL);
+
+ /* ignore error if we already had some data */
+ if (bytes >= 0)
+ *len += bytes;
+ else if (*len == 0)
+ *len = bytes;
+ }
+
+ if (pls->id3_buf) {
+ /* Now parse all the ID3 tags */
+ AVIOContext id3ioctx;
+ ffio_init_context(&id3ioctx, pls->id3_buf, id3_buf_pos, 0, NULL, NULL, NULL, NULL);
+ handle_id3(&id3ioctx, pls);
+ }
+
+ if (pls->is_id3_timestamped == -1)
+ pls->is_id3_timestamped = (pls->id3_mpegts_timestamp != AV_NOPTS_VALUE);
+}
+
+static int open_input(HLSContext *c, struct playlist *pls, struct segment *seg)
+{
+ AVDictionary *opts = NULL;
+ int ret;
+
+ // broker prior HTTP options that should be consistent across requests
+ av_dict_set(&opts, "user-agent", c->user_agent, 0);
+ av_dict_set(&opts, "cookies", c->cookies, 0);
+ av_dict_set(&opts, "headers", c->headers, 0);
+ av_dict_set(&opts, "seekable", "0", 0);
+
+ if (seg->size >= 0) {
+ /* try to restrict the HTTP request to the part we want
+ * (if this is in fact a HTTP request) */
+ av_dict_set_int(&opts, "offset", seg->url_offset, 0);
+ av_dict_set_int(&opts, "end_offset", seg->url_offset + seg->size, 0);
+ }
+
+ av_log(pls->parent, AV_LOG_VERBOSE, "HLS request for url '%s', offset %"PRId64", playlist %d\n",
+ seg->url, seg->url_offset, pls->index);
+
+ if (seg->key_type == KEY_NONE) {
+ ret = open_url(pls->parent->priv_data, &pls->input, seg->url, opts);
+ } else if (seg->key_type == KEY_AES_128) {
+// HLSContext *c = var->parent->priv_data;
+ char iv[33], key[33], url[MAX_URL_SIZE];
+ if (strcmp(seg->key, pls->key_url)) {
+ URLContext *uc;
+ if (open_url(pls->parent->priv_data, &uc, seg->key, opts) == 0) {
+ if (ffurl_read_complete(uc, pls->key, sizeof(pls->key))
+ != sizeof(pls->key)) {
+ av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",
+ seg->key);
+ }
+ ffurl_close(uc);
+ } else {
+ av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n",
+ seg->key);
+ }
+ av_strlcpy(pls->key_url, seg->key, sizeof(pls->key_url));
+ }
+ ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);
+ ff_data_to_hex(key, pls->key, sizeof(pls->key), 0);
+ iv[32] = key[32] = '\0';
+ if (strstr(seg->url, "://"))
+ snprintf(url, sizeof(url), "crypto+%s", seg->url);
+ else
+ snprintf(url, sizeof(url), "crypto:%s", seg->url);
+
+ if ((ret = ffurl_alloc(&pls->input, url, AVIO_FLAG_READ,
+ &pls->parent->interrupt_callback)) < 0)
+ goto cleanup;
+ av_opt_set(pls->input->priv_data, "key", key, 0);
+ av_opt_set(pls->input->priv_data, "iv", iv, 0);
+
+ if ((ret = url_connect(pls, c->avio_opts, opts)) < 0) {
+ goto cleanup;
+ }
+ ret = 0;
+ } else if (seg->key_type == KEY_SAMPLE_AES) {
+ av_log(pls->parent, AV_LOG_ERROR,
+ "SAMPLE-AES encryption is not supported yet\n");
+ ret = AVERROR_PATCHWELCOME;
+ }
+ else
+ ret = AVERROR(ENOSYS);
+
+ /* Seek to the requested position. If this was a HTTP request, the offset
+ * should already be where want it to, but this allows e.g. local testing
+ * without a HTTP server. */
+ if (ret == 0 && seg->key_type == KEY_NONE && seg->url_offset) {
+ int seekret = ffurl_seek(pls->input, 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);
+ ret = seekret;
+ ffurl_close(pls->input);
+ pls->input = NULL;
+ }
+ }
+
+cleanup:
+ av_dict_free(&opts);
+ pls->cur_seg_offset = 0;
+ return ret;
+}
+
+static int update_init_section(struct playlist *pls, struct segment *seg)
+{
+ static const int max_init_section_size = 1024*1024;
+ HLSContext *c = pls->parent->priv_data;
+ int64_t sec_size;
+ int64_t urlsize;
+ int ret;
+
+ if (seg->init_section == pls->cur_init_section)
+ return 0;
+
+ pls->cur_init_section = NULL;
+
+ if (!seg->init_section)
+ return 0;
+
+ /* this will clobber playlist URLContext stuff, so this should be
+ * called between segments only */
+ ret = open_input(c, pls, seg->init_section);
+ if (ret < 0) {
+ av_log(pls->parent, AV_LOG_WARNING,
+ "Failed to open an initialization section in playlist %d\n",
+ pls->index);
+ return ret;
+ }
+
+ if (seg->init_section->size >= 0)
+ sec_size = seg->init_section->size;
+ else if ((urlsize = ffurl_size(pls->input)) >= 0)
+ sec_size = urlsize;
+ else
+ sec_size = max_init_section_size;
+
+ av_log(pls->parent, AV_LOG_DEBUG,
+ "Downloading an initialization section of size %"PRId64"\n",
+ sec_size);
+
+ sec_size = FFMIN(sec_size, max_init_section_size);
+
+ av_fast_malloc(&pls->init_sec_buf, &pls->init_sec_buf_size, sec_size);
+
+ ret = read_from_url(pls, seg->init_section, pls->init_sec_buf,
+ pls->init_sec_buf_size, READ_COMPLETE);
+ ffurl_close(pls->input);
+ pls->input = NULL;
+
+ if (ret < 0)
+ return ret;
+
+ pls->cur_init_section = seg->init_section;
+ pls->init_sec_data_len = ret;
+ pls->init_sec_buf_read_offset = 0;
+
+ /* spec says audio elementary streams do not have media initialization
+ * sections, so there should be no ID3 timestamps */
+ pls->is_id3_timestamped = 0;
+
+ return 0;
+}
+
+static int64_t default_reload_interval(struct playlist *pls)
+{
+ return pls->n_segments > 0 ?
+ pls->segments[pls->n_segments - 1]->duration :
+ pls->target_duration;
+}
+
+static int read_data(void *opaque, uint8_t *buf, int buf_size)
+{
+ struct playlist *v = opaque;
+ HLSContext *c = v->parent->priv_data;
+ int ret, i;
+ int just_opened = 0;
+
+restart:
+ if (!v->needed)
+ return AVERROR_EOF;
+
+ if (!v->input) {
+ int64_t reload_interval;
+ struct segment *seg;
+
+ /* Check that the playlist is still needed before opening a new
+ * segment. */
+ if (v->ctx && v->ctx->nb_streams &&
+ v->parent->nb_streams >= v->stream_offset + v->ctx->nb_streams) {
+ v->needed = 0;
+ for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams;
+ i++) {
+ if (v->parent->streams[i]->discard < AVDISCARD_ALL)
+ v->needed = 1;
+ }
+ }
+ if (!v->needed) {
+ av_log(v->parent, AV_LOG_INFO, "No longer receiving playlist %d\n",
+ v->index);
+ return AVERROR_EOF;
+ }
+
+ /* If this is a live stream and the reload interval has elapsed since
+ * the last playlist reload, reload the playlists now. */
+ reload_interval = default_reload_interval(v);
+
+reload:
+ if (!v->finished &&
+ av_gettime_relative() - v->last_load_time >= reload_interval) {
+ if ((ret = parse_playlist(c, v->url, v, NULL)) < 0) {
+ av_log(v->parent, AV_LOG_WARNING, "Failed to reload playlist %d\n",
+ v->index);
+ return ret;
+ }
+ /* If we need to reload the playlist again below (if
+ * there's still no more segments), switch to a reload
+ * interval of half the target duration. */
+ reload_interval = v->target_duration / 2;
+ }
+ if (v->cur_seq_no < v->start_seq_no) {
+ av_log(NULL, AV_LOG_WARNING,
+ "skipping %d segments ahead, expired from playlists\n",
+ v->start_seq_no - v->cur_seq_no);
+ v->cur_seq_no = v->start_seq_no;
+ }
+ if (v->cur_seq_no >= v->start_seq_no + v->n_segments) {
+ if (v->finished)
+ return AVERROR_EOF;
+ while (av_gettime_relative() - v->last_load_time < reload_interval) {
+ if (ff_check_interrupt(c->interrupt_callback))
+ return AVERROR_EXIT;
+ av_usleep(100*1000);
+ }
+ /* Enough time has elapsed since the last reload */
+ goto reload;
+ }
+
+ seg = current_segment(v);
+
+ /* load/update Media Initialization Section, if any */
+ ret = update_init_section(v, seg);
+ if (ret)
+ return ret;
+
+ ret = open_input(c, v, seg);
+ if (ret < 0) {
+ if (ff_check_interrupt(c->interrupt_callback))
+ return AVERROR_EXIT;
+ av_log(v->parent, AV_LOG_WARNING, "Failed to open segment of playlist %d\n",
+ v->index);
+ v->cur_seq_no += 1;
+ goto reload;
+ }
+ just_opened = 1;
+ }
+
+ if (v->init_sec_buf_read_offset < v->init_sec_data_len) {
+ /* Push init section out first before first actual segment */
+ int copy_size = FFMIN(v->init_sec_data_len - v->init_sec_buf_read_offset, buf_size);
+ memcpy(buf, v->init_sec_buf, copy_size);
+ v->init_sec_buf_read_offset += copy_size;
+ return copy_size;
+ }
+
+ ret = read_from_url(v, current_segment(v), buf, buf_size, READ_NORMAL);
+ if (ret > 0) {
+ if (just_opened && v->is_id3_timestamped != 0) {
+ /* Intercept ID3 tags here, elementary audio streams are required
+ * to convey timestamps using them in the beginning of each segment. */
+ intercept_id3(v, buf, buf_size, &ret);
+ }
+
+ return ret;
+ }
+ ffurl_close(v->input);
+ v->input = NULL;
+ v->cur_seq_no++;
+
+ c->cur_seq_no = v->cur_seq_no;
+
+ goto restart;
+}
+
+static int playlist_in_multiple_variants(HLSContext *c, struct playlist *pls)
+{
+ int variant_count = 0;
+ int i, j;
+
+ for (i = 0; i < c->n_variants && variant_count < 2; i++) {
+ struct variant *v = c->variants[i];
+
+ for (j = 0; j < v->n_playlists; j++) {
+ if (v->playlists[j] == pls) {
+ variant_count++;
+ break;
+ }
+ }
+ }
+
+ return variant_count >= 2;
+}
+
+static void add_renditions_to_variant(HLSContext *c, struct variant *var,
+ enum AVMediaType type, const char *group_id)
+{
+ int i;
+
+ for (i = 0; i < c->n_renditions; i++) {
+ struct rendition *rend = c->renditions[i];
+
+ if (rend->type == type && !strcmp(rend->group_id, group_id)) {
+
+ if (rend->playlist)
+ /* rendition is an external playlist
+ * => add the playlist to the variant */
+ dynarray_add(&var->playlists, &var->n_playlists, rend->playlist);
+ else
+ /* rendition is part of the variant main Media Playlist
+ * => add the rendition to the main Media Playlist */
+ dynarray_add(&var->playlists[0]->renditions,
+ &var->playlists[0]->n_renditions,
+ rend);
+ }
+ }
+}
+
+static void add_metadata_from_renditions(AVFormatContext *s, struct playlist *pls,
+ enum AVMediaType type)
+{
+ int rend_idx = 0;
+ int i;
+
+ for (i = 0; i < pls->ctx->nb_streams; i++) {
+ AVStream *st = s->streams[pls->stream_offset + i];
+
+ if (st->codec->codec_type != type)
+ continue;
+
+ for (; rend_idx < pls->n_renditions; rend_idx++) {
+ struct rendition *rend = pls->renditions[rend_idx];
+
+ if (rend->type != type)
+ continue;
+
+ if (rend->language[0])
+ av_dict_set(&st->metadata, "language", rend->language, 0);
+ if (rend->name[0])
+ av_dict_set(&st->metadata, "comment", rend->name, 0);
+
+ st->disposition |= rend->disposition;
+ }
+ if (rend_idx >=pls->n_renditions)
+ break;
+ }
+}
+
+/* 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)
+{
+ int i;
+ int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ?
+ 0 : c->first_timestamp;
+
+ if (timestamp < pos) {
+ *seq_no = pls->start_seq_no;
+ return 0;
+ }
+
+ for (i = 0; i < pls->n_segments; i++) {
+ int64_t diff = pos + pls->segments[i]->duration - timestamp;
+ if (diff > 0) {
+ *seq_no = pls->start_seq_no + i;
+ return 1;
+ }
+ pos += pls->segments[i]->duration;
+ }
+
+ *seq_no = pls->start_seq_no + pls->n_segments - 1;
+
+ return 0;
+}
+
+static int select_cur_seq_no(HLSContext *c, struct playlist *pls)
+{
+ int seq_no;
+
+ if (!pls->finished && !c->first_packet &&
+ av_gettime_relative() - pls->last_load_time >= default_reload_interval(pls))
+ /* reload the playlist since it was suspended */
+ parse_playlist(c, pls->url, pls, NULL);
+
+ /* If playback is already in progress (we are just selecting a new
+ * playlist) and this is a complete file, find the matching segment
+ * by counting durations. */
+ if (pls->finished && c->cur_timestamp != AV_NOPTS_VALUE) {
+ find_timestamp_in_playlist(c, pls, c->cur_timestamp, &seq_no);
+ return seq_no;
+ }
+
+ if (!pls->finished) {
+ if (!c->first_packet && /* we are doing a segment selection during playback */
+ c->cur_seq_no >= pls->start_seq_no &&
+ c->cur_seq_no < pls->start_seq_no + pls->n_segments)
+ /* While spec 3.4.3 says that we cannot assume anything about the
+ * content at the same sequence number on different playlists,
+ * in practice this seems to work and doing it otherwise would
+ * require us to download a segment to inspect its timestamps. */
+ return c->cur_seq_no;
+
+ /* If this is a live stream, start live_start_index segments from the
+ * start or end */
+ if (c->live_start_index < 0)
+ return pls->start_seq_no + FFMAX(pls->n_segments + c->live_start_index, 0);
+ else
+ return pls->start_seq_no + FFMIN(c->live_start_index, pls->n_segments - 1);
+ }
+
+ /* Otherwise just start on the first segment. */
+ return pls->start_seq_no;
+}
+
+static int save_avio_options(AVFormatContext *s)
+{
+ HLSContext *c = s->priv_data;
+ const char *opts[] = { "headers", "user_agent", "user-agent", "cookies", NULL }, **opt = opts;
+ uint8_t *buf;
+ int ret = 0;
+
+ while (*opt) {
+ if (av_opt_get(s->pb, *opt, AV_OPT_SEARCH_CHILDREN, &buf) >= 0) {
+ ret = av_dict_set(&c->avio_opts, *opt, buf,
+ AV_DICT_DONT_STRDUP_VAL);
+ if (ret < 0)
+ return ret;
+ }
+ opt++;
+ }
+
+ return ret;
+}
+
+static int hls_read_header(AVFormatContext *s)
+{
+ URLContext *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb->opaque;
+ HLSContext *c = s->priv_data;
+ int ret = 0, i, j, stream_offset = 0;
+
+ c->interrupt_callback = &s->interrupt_callback;
+
+ c->first_packet = 1;
+ c->first_timestamp = AV_NOPTS_VALUE;
+ c->cur_timestamp = AV_NOPTS_VALUE;
+
+ // if the URL context is good, read important options we must broker later
+ if (u && u->prot->priv_data_class) {
+ // get the previous user agent & set back to null if string size is zero
+ update_options(&c->user_agent, "user-agent", u->priv_data);
+
+ // get the previous cookies & set back to null if string size is zero
+ update_options(&c->cookies, "cookies", u->priv_data);
+
+ // get the previous headers & set back to null if string size is zero
+ update_options(&c->headers, "headers", u->priv_data);
+ }
+
+ if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0)
+ goto fail;
+
+ if ((ret = save_avio_options(s)) < 0)
+ goto fail;
+
+ /* Some HLS servers don't like being sent the range header */
+ av_dict_set(&c->avio_opts, "seekable", "0", 0);
+
+ if (c->n_variants == 0) {
+ av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
+ ret = AVERROR_EOF;
+ goto fail;
+ }
+ /* If the playlist only contained playlists (Master Playlist),
+ * parse each individual playlist. */
+ if (c->n_playlists > 1 || c->playlists[0]->n_segments == 0) {
+ for (i = 0; i < c->n_playlists; i++) {
+ struct playlist *pls = c->playlists[i];
+ if ((ret = parse_playlist(c, pls->url, pls, NULL)) < 0)
+ goto fail;
+ }
+ }
+
+ if (c->variants[0]->playlists[0]->n_segments == 0) {
+ av_log(NULL, AV_LOG_WARNING, "Empty playlist\n");
+ ret = AVERROR_EOF;
+ goto fail;
+ }
+
+ /* If this isn't a live stream, calculate the total duration of the
+ * stream. */
+ if (c->variants[0]->playlists[0]->finished) {
+ int64_t duration = 0;
+ for (i = 0; i < c->variants[0]->playlists[0]->n_segments; i++)
+ duration += c->variants[0]->playlists[0]->segments[i]->duration;
+ s->duration = duration;
+ }
+
+ /* Associate renditions with variants */
+ for (i = 0; i < c->n_variants; i++) {
+ struct variant *var = c->variants[i];
+
+ if (var->audio_group[0])
+ add_renditions_to_variant(c, var, AVMEDIA_TYPE_AUDIO, var->audio_group);
+ if (var->video_group[0])
+ add_renditions_to_variant(c, var, AVMEDIA_TYPE_VIDEO, var->video_group);
+ if (var->subtitles_group[0])
+ add_renditions_to_variant(c, var, AVMEDIA_TYPE_SUBTITLE, var->subtitles_group);
+ }
+
+ /* Open the demuxer for each playlist */
+ for (i = 0; i < c->n_playlists; i++) {
+ struct playlist *pls = c->playlists[i];
+ AVInputFormat *in_fmt = NULL;
+
+ if (!(pls->ctx = avformat_alloc_context())) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+
+ if (pls->n_segments == 0)
+ continue;
+
+ pls->index = i;
+ pls->needed = 1;
+ pls->parent = s;
+ pls->cur_seq_no = select_cur_seq_no(c, pls);
+
+ pls->read_buffer = av_malloc(INITIAL_BUFFER_SIZE);
+ if (!pls->read_buffer){
+ ret = AVERROR(ENOMEM);
+ avformat_free_context(pls->ctx);
+ pls->ctx = NULL;
+ goto fail;
+ }
+ ffio_init_context(&pls->pb, pls->read_buffer, INITIAL_BUFFER_SIZE, 0, pls,
+ read_data, NULL, NULL);
+ pls->pb.seekable = 0;
+ ret = av_probe_input_buffer(&pls->pb, &in_fmt, pls->segments[0]->url,
+ NULL, 0, 0);
+ 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);
+ avformat_free_context(pls->ctx);
+ pls->ctx = NULL;
+ goto fail;
+ }
+ pls->ctx->pb = &pls->pb;
+ pls->stream_offset = stream_offset;
+
+ if ((ret = ff_copy_whitelists(pls->ctx, s)) < 0)
+ goto fail;
+
+ ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, NULL);
+ if (ret < 0)
+ goto fail;
+
+ if (pls->id3_deferred_extra && pls->ctx->nb_streams == 1) {
+ ff_id3v2_parse_apic(pls->ctx, &pls->id3_deferred_extra);
+ avformat_queue_attached_pictures(pls->ctx);
+ ff_id3v2_free_extra_meta(&pls->id3_deferred_extra);
+ pls->id3_deferred_extra = NULL;
+ }
+
+ pls->ctx->ctx_flags &= ~AVFMTCTX_NOHEADER;
+ ret = avformat_find_stream_info(pls->ctx, NULL);
+ if (ret < 0)
+ goto fail;
+
+ if (pls->is_id3_timestamped == -1)
+ av_log(s, AV_LOG_WARNING, "No expected HTTP requests have been made\n");
+
+ /* Create new AVStreams for each stream in this playlist */
+ for (j = 0; j < pls->ctx->nb_streams; j++) {
+ AVStream *st = avformat_new_stream(s, NULL);
+ AVStream *ist = pls->ctx->streams[j];
+ if (!st) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ st->id = i;
+
+ avcodec_copy_context(st->codec, pls->ctx->streams[j]->codec);
+
+ if (pls->is_id3_timestamped) /* custom timestamps via id3 */
+ avpriv_set_pts_info(st, 33, 1, MPEG_TIME_BASE);
+ else
+ avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den);
+ }
+
+ add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_AUDIO);
+ add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_VIDEO);
+ add_metadata_from_renditions(s, pls, AVMEDIA_TYPE_SUBTITLE);
+
+ stream_offset += pls->ctx->nb_streams;
+ }
+
+ /* Create a program for each variant */
+ for (i = 0; i < c->n_variants; i++) {
+ struct variant *v = c->variants[i];
+ AVProgram *program;
+
+ program = av_new_program(s, i);
+ if (!program)
+ goto fail;
+ av_dict_set_int(&program->metadata, "variant_bitrate", v->bandwidth, 0);
+
+ for (j = 0; j < v->n_playlists; j++) {
+ struct playlist *pls = v->playlists[j];
+ int is_shared = playlist_in_multiple_variants(c, pls);
+ int k;
+
+ for (k = 0; k < pls->ctx->nb_streams; k++) {
+ struct AVStream *st = s->streams[pls->stream_offset + k];
+
+ ff_program_add_stream_index(s, i, pls->stream_offset + k);
+
+ /* Set variant_bitrate for streams unique to this variant */
+ if (!is_shared && v->bandwidth)
+ av_dict_set_int(&st->metadata, "variant_bitrate", v->bandwidth, 0);
+ }
+ }
+ }
+
+ return 0;
+fail:
+ free_playlist_list(c);
+ free_variant_list(c);
+ free_rendition_list(c);
+ return ret;
+}
+
+static int recheck_discard_flags(AVFormatContext *s, int first)
+{
+ HLSContext *c = s->priv_data;
+ int i, changed = 0;
+
+ /* Check if any new streams are needed */
+ for (i = 0; i < c->n_playlists; i++)
+ c->playlists[i]->cur_needed = 0;
+
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+ struct playlist *pls = c->playlists[s->streams[i]->id];
+ if (st->discard < AVDISCARD_ALL)
+ pls->cur_needed = 1;
+ }
+ for (i = 0; i < c->n_playlists; i++) {
+ struct playlist *pls = c->playlists[i];
+ if (pls->cur_needed && !pls->needed) {
+ pls->needed = 1;
+ changed = 1;
+ pls->cur_seq_no = select_cur_seq_no(c, pls);
+ pls->pb.eof_reached = 0;
+ if (c->cur_timestamp != AV_NOPTS_VALUE) {
+ /* catch up */
+ pls->seek_timestamp = c->cur_timestamp;
+ 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);
+ } else if (first && !pls->cur_needed && pls->needed) {
+ if (pls->input)
+ ffurl_close(pls->input);
+ pls->input = NULL;
+ pls->needed = 0;
+ changed = 1;
+ av_log(s, AV_LOG_INFO, "No longer receiving playlist %d\n", i);
+ }
+ }
+ return changed;
+}
+
+static void fill_timing_for_id3_timestamped_stream(struct playlist *pls)
+{
+ if (pls->id3_offset >= 0) {
+ pls->pkt.dts = pls->id3_mpegts_timestamp +
+ av_rescale_q(pls->id3_offset,
+ pls->ctx->streams[pls->pkt.stream_index]->time_base,
+ MPEG_TIME_BASE_Q);
+ 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;
+ }
+
+ 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;
+}
+
+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;
+}
+
+static int compare_ts_with_wrapdetect(int64_t ts_a, struct playlist *pls_a,
+ int64_t ts_b, struct playlist *pls_b)
+{
+ int64_t scaled_ts_a = av_rescale_q(ts_a, get_timebase(pls_a), MPEG_TIME_BASE_Q);
+ int64_t scaled_ts_b = av_rescale_q(ts_b, get_timebase(pls_b), MPEG_TIME_BASE_Q);
+
+ return av_compare_mod(scaled_ts_a, scaled_ts_b, 1LL << 33);
+}
+
+static int hls_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ HLSContext *c = s->priv_data;
+ int ret, i, minplaylist = -1;
+
+ recheck_discard_flags(s, c->first_packet);
+ c->first_packet = 0;
+
+ for (i = 0; i < c->n_playlists; i++) {
+ 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) {
+ while (1) {
+ int64_t ts_diff;
+ AVRational tb;
+ 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) {
+ /* 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,
+ get_timebase(pls), AV_TIME_BASE_Q);
+ }
+
+ if (pls->seek_timestamp == AV_NOPTS_VALUE)
+ break;
+
+ if (pls->seek_stream_index < 0 ||
+ pls->seek_stream_index == pls->pkt.stream_index) {
+
+ 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,
+ 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->seek_timestamp = AV_NOPTS_VALUE;
+ break;
+ }
+ }
+ av_free_packet(&pls->pkt);
+ reset_packet(&pls->pkt);
+ }
+ }
+ /* Check if this stream has the packet with the lowest dts */
+ 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;
+
+ if (dts == AV_NOPTS_VALUE ||
+ (mindts != AV_NOPTS_VALUE && compare_ts_with_wrapdetect(dts, pls, mindts, minpls) < 0))
+ minplaylist = i;
+ }
+ }
+ }
+
+ /* If we got a packet, return it */
+ if (minplaylist >= 0) {
+ struct playlist *pls = c->playlists[minplaylist];
+ *pkt = pls->pkt;
+ pkt->stream_index += pls->stream_offset;
+ reset_packet(&c->playlists[minplaylist]->pkt);
+
+ if (pkt->dts != AV_NOPTS_VALUE)
+ c->cur_timestamp = av_rescale_q(pkt->dts,
+ pls->ctx->streams[pls->pkt.stream_index]->time_base,
+ AV_TIME_BASE_Q);
+
+ return 0;
+ }
+ return AVERROR_EOF;
+}
+
+static int hls_close(AVFormatContext *s)
+{
+ HLSContext *c = s->priv_data;
+
+ free_playlist_list(c);
+ free_variant_list(c);
+ free_rendition_list(c);
+
+ av_dict_free(&c->avio_opts);
+
+ return 0;
+}
+
+static int hls_read_seek(AVFormatContext *s, int stream_index,
+ int64_t timestamp, int flags)
+{
+ HLSContext *c = s->priv_data;
+ struct playlist *seek_pls = NULL;
+ int i, seq_no;
+ int64_t first_timestamp, seek_timestamp, duration;
+
+ if ((flags & AVSEEK_FLAG_BYTE) ||
+ !(c->variants[0]->playlists[0]->finished || c->variants[0]->playlists[0]->type == PLS_TYPE_EVENT))
+ return AVERROR(ENOSYS);
+
+ first_timestamp = c->first_timestamp == AV_NOPTS_VALUE ?
+ 0 : c->first_timestamp;
+
+ seek_timestamp = av_rescale_rnd(timestamp, AV_TIME_BASE,
+ s->streams[stream_index]->time_base.den,
+ flags & AVSEEK_FLAG_BACKWARD ?
+ AV_ROUND_DOWN : AV_ROUND_UP);
+
+ duration = s->duration == AV_NOPTS_VALUE ?
+ 0 : s->duration;
+
+ if (0 < duration && duration < seek_timestamp - first_timestamp)
+ return AVERROR(EIO);
+
+ /* find the playlist with the specified stream */
+ for (i = 0; i < c->n_playlists; i++) {
+ struct playlist *pls = c->playlists[i];
+ if (stream_index >= pls->stream_offset &&
+ stream_index - pls->stream_offset < pls->ctx->nb_streams) {
+ seek_pls = pls;
+ break;
+ }
+ }
+ /* check if the timestamp is valid for the playlist with the
+ * specified stream index */
+ if (!seek_pls || !find_timestamp_in_playlist(c, seek_pls, seek_timestamp, &seq_no))
+ return AVERROR(EIO);
+
+ /* set segment now so we do not need to search again below */
+ seek_pls->cur_seq_no = seq_no;
+ seek_pls->seek_stream_index = stream_index - seek_pls->stream_offset;
+
+ for (i = 0; i < c->n_playlists; i++) {
+ /* Reset reading */
+ struct playlist *pls = c->playlists[i];
+ if (pls->input) {
+ ffurl_close(pls->input);
+ pls->input = NULL;
+ }
+ av_free_packet(&pls->pkt);
+ reset_packet(&pls->pkt);
+ pls->pb.eof_reached = 0;
+ /* Clear any buffered data */
+ pls->pb.buf_end = pls->pb.buf_ptr = pls->pb.buffer;
+ /* Reset the pos, to let the mpegts demuxer know we've seeked. */
+ pls->pb.pos = 0;
+ /* Flush the packet queue of the subdemuxer. */
+ ff_read_frame_flush(pls->ctx);
+
+ pls->seek_timestamp = seek_timestamp;
+ pls->seek_flags = flags;
+
+ if (pls != seek_pls) {
+ /* set closest segment seq_no for playlists not handled above */
+ find_timestamp_in_playlist(c, pls, seek_timestamp, &pls->cur_seq_no);
+ /* seek the playlist to the given position without taking
+ * keyframes into account since this playlist does not have the
+ * specified stream where we should look for the keyframes */
+ pls->seek_stream_index = -1;
+ pls->seek_flags |= AVSEEK_FLAG_ANY;
+ }
+ }
+
+ c->cur_timestamp = seek_timestamp;
+
+ return 0;
+}
+
+static int hls_probe(AVProbeData *p)
+{
+ /* Require #EXTM3U at the start, and either one of the ones below
+ * somewhere for a proper match. */
+ if (strncmp(p->buf, "#EXTM3U", 7))
+ return 0;
+ if (strstr(p->buf, "#EXT-X-STREAM-INF:") ||
+ strstr(p->buf, "#EXT-X-TARGETDURATION:") ||
+ strstr(p->buf, "#EXT-X-MEDIA-SEQUENCE:"))
+ return AVPROBE_SCORE_MAX;
+ return 0;
+}
+
+#define OFFSET(x) offsetof(HLSContext, x)
+#define FLAGS AV_OPT_FLAG_DECODING_PARAM
+static const AVOption hls_options[] = {
+ {"live_start_index", "segment index to start live streams at (negative values are from the end)",
+ 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"},
+ INT_MIN, INT_MAX, FLAGS},
+ {NULL}
+};
+
+static const AVClass hls_class = {
+ .class_name = "hls,applehttp",
+ .item_name = av_default_item_name,
+ .option = hls_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_hls_demuxer = {
+ .name = "hls,applehttp",
+ .long_name = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"),
+ .priv_class = &hls_class,
+ .priv_data_size = sizeof(HLSContext),
+ .read_probe = hls_probe,
+ .read_header = hls_read_header,
+ .read_packet = hls_read_packet,
+ .read_close = hls_close,
+ .read_seek = hls_read_seek,
+};
diff --git a/ffmpeg-2-8-11/libavformat/hlsenc.c b/ffmpeg-2-8-12/libavformat/hlsenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/hlsenc.c
rename to ffmpeg-2-8-12/libavformat/hlsenc.c
diff --git a/ffmpeg-2-8-11/libavformat/hlsproto.c b/ffmpeg-2-8-12/libavformat/hlsproto.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/hlsproto.c
rename to ffmpeg-2-8-12/libavformat/hlsproto.c
diff --git a/ffmpeg-2-8-11/libavformat/hnm.c b/ffmpeg-2-8-12/libavformat/hnm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/hnm.c
rename to ffmpeg-2-8-12/libavformat/hnm.c
diff --git a/ffmpeg-2-8-12/libavformat/http.c b/ffmpeg-2-8-12/libavformat/http.c
new file mode 100644
index 0000000..7686c92
--- /dev/null
+++ b/ffmpeg-2-8-12/libavformat/http.c
@@ -0,0 +1,1648 @@
+/*
+ * HTTP protocol for ffmpeg client
+ * Copyright (c) 2000, 2001 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+
+#if CONFIG_ZLIB
+#include <zlib.h>
+#endif /* CONFIG_ZLIB */
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/opt.h"
+
+#include "avformat.h"
+#include "http.h"
+#include "httpauth.h"
+#include "internal.h"
+#include "network.h"
+#include "os_support.h"
+#include "url.h"
+
+/* XXX: POST protocol is not completely implemented because ffmpeg uses
+ * only a subset of it. */
+
+/* The IO buffer size is unrelated to the max URL size in itself, but needs
+ * to be large enough to fit the full request headers (including long
+ * path names). */
+#define BUFFER_SIZE MAX_URL_SIZE
+#define MAX_REDIRECTS 8
+#define HTTP_SINGLE 1
+#define HTTP_MUTLI 2
+typedef enum {
+ LOWER_PROTO,
+ READ_HEADERS,
+ WRITE_REPLY_HEADERS,
+ FINISH
+}HandshakeState;
+
+typedef struct HTTPContext {
+ const AVClass *class;
+ URLContext *hd;
+ unsigned char buffer[BUFFER_SIZE], *buf_ptr, *buf_end;
+ int line_count;
+ int http_code;
+ /* Used if "Transfer-Encoding: chunked" otherwise -1. */
+ uint64_t chunksize;
+ uint64_t off, end_off, filesize;
+ char *location;
+ HTTPAuthState auth_state;
+ HTTPAuthState proxy_auth_state;
+ char *headers;
+ char *mime_type;
+ char *user_agent;
+ char *content_type;
+ /* Set if the server correctly handles Connection: close and will close
+ * the connection after feeding us the content. */
+ int willclose;
+ int seekable; /**< Control seekability, 0 = disable, 1 = enable, -1 = probe. */
+ int chunked_post;
+ /* A flag which indicates if the end of chunked encoding has been sent. */
+ int end_chunked_post;
+ /* A flag which indicates we have finished to read POST reply. */
+ int end_header;
+ /* A flag which indicates if we use persistent connections. */
+ int multiple_requests;
+ uint8_t *post_data;
+ int post_datalen;
+ int is_akamai;
+ int is_mediagateway;
+ char *cookies; ///< holds newline (\n) delimited Set-Cookie header field values (without the "Set-Cookie: " field name)
+ /* A dictionary containing cookies keyed by cookie name */
+ AVDictionary *cookie_dict;
+ int icy;
+ /* how much data was read since the last ICY metadata packet */
+ uint64_t icy_data_read;
+ /* after how many bytes of read data a new metadata packet will be found */
+ uint64_t icy_metaint;
+ char *icy_metadata_headers;
+ char *icy_metadata_packet;
+ AVDictionary *metadata;
+#if CONFIG_ZLIB
+ int compressed;
+ z_stream inflate_stream;
+ uint8_t *inflate_buffer;
+#endif /* CONFIG_ZLIB */
+ AVDictionary *chained_options;
+ int send_expect_100;
+ char *method;
+ int reconnect;
+ int listen;
+ char *resource;
+ int reply_code;
+ int is_multi_client;
+ HandshakeState handshake_step;
+ int is_connected_server;
+} HTTPContext;
+
+#define OFFSET(x) offsetof(HTTPContext, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM
+#define DEFAULT_USER_AGENT "Lavf/" AV_STRINGIFY(LIBAVFORMAT_VERSION)
+
+static const AVOption options[] = {
+ { "seekable", "control seekability of connection", OFFSET(seekable), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, D },
+ { "chunked_post", "use chunked transfer-encoding for posts", OFFSET(chunked_post), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, E },
+ { "headers", "set custom HTTP headers, can override built in default headers", OFFSET(headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D | E },
+ { "content_type", "set a specific content type for the POST messages", OFFSET(content_type), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D | E },
+ { "user_agent", "override User-Agent header", OFFSET(user_agent), AV_OPT_TYPE_STRING, { .str = DEFAULT_USER_AGENT }, 0, 0, D },
+ { "user-agent", "override User-Agent header", OFFSET(user_agent), AV_OPT_TYPE_STRING, { .str = DEFAULT_USER_AGENT }, 0, 0, D },
+ { "multiple_requests", "use persistent connections", OFFSET(multiple_requests), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D | E },
+ { "post_data", "set custom HTTP post data", OFFSET(post_data), AV_OPT_TYPE_BINARY, .flags = D | E },
+ { "mime_type", "export the MIME type", OFFSET(mime_type), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_EXPORT | AV_OPT_FLAG_READONLY },
+ { "cookies", "set cookies to be sent in applicable future requests, use newline delimited Set-Cookie HTTP field value syntax", OFFSET(cookies), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D },
+ { "icy", "request ICY metadata", OFFSET(icy), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, D },
+ { "icy_metadata_headers", "return ICY metadata headers", OFFSET(icy_metadata_headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_EXPORT },
+ { "icy_metadata_packet", "return current ICY metadata packet", OFFSET(icy_metadata_packet), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_EXPORT },
+ { "metadata", "metadata read from the bitstream", OFFSET(metadata), AV_OPT_TYPE_DICT, {0}, 0, 0, AV_OPT_FLAG_EXPORT },
+ { "auth_type", "HTTP authentication type", OFFSET(auth_state.auth_type), AV_OPT_TYPE_INT, { .i64 = HTTP_AUTH_NONE }, HTTP_AUTH_NONE, HTTP_AUTH_BASIC, D | E, "auth_type"},
+ { "none", "No auth method set, autodetect", 0, AV_OPT_TYPE_CONST, { .i64 = HTTP_AUTH_NONE }, 0, 0, D | E, "auth_type"},
+ { "basic", "HTTP basic authentication", 0, AV_OPT_TYPE_CONST, { .i64 = HTTP_AUTH_BASIC }, 0, 0, D | E, "auth_type"},
+ { "send_expect_100", "Force sending an Expect: 100-continue header for POST", OFFSET(send_expect_100), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, E },
+ { "location", "The actual location of the data received", OFFSET(location), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D | E },
+ { "offset", "initial byte offset", OFFSET(off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, D },
+ { "end_offset", "try to limit the request to bytes preceding this offset", OFFSET(end_off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, D },
+ { "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_INT, { .i64 = 0 }, 0, 1, D },
+ { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, D | E },
+ { "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
+ { "reply_code", "The http status code to return to a client", OFFSET(reply_code), AV_OPT_TYPE_INT, { .i64 = 200}, INT_MIN, 599, E},
+ { NULL }
+};
+
+static int http_connect(URLContext *h, const char *path, const char *local_path,
+ const char *hoststr, const char *auth,
+ const char *proxyauth, int *new_location);
+static int http_read_header(URLContext *h, int *new_location);
+
+void ff_http_init_auth_state(URLContext *dest, const URLContext *src)
+{
+ memcpy(&((HTTPContext *)dest->priv_data)->auth_state,
+ &((HTTPContext *)src->priv_data)->auth_state,
+ sizeof(HTTPAuthState));
+ memcpy(&((HTTPContext *)dest->priv_data)->proxy_auth_state,
+ &((HTTPContext *)src->priv_data)->proxy_auth_state,
+ sizeof(HTTPAuthState));
+}
+
+static int http_open_cnx_internal(URLContext *h, AVDictionary **options)
+{
+ const char *path, *proxy_path, *lower_proto = "tcp", *local_path;
+ char hostname[1024], hoststr[1024], proto[10];
+ char auth[1024], proxyauth[1024] = "";
+ char path1[MAX_URL_SIZE];
+ char buf[1024], urlbuf[MAX_URL_SIZE];
+ int port, use_proxy, err, location_changed = 0;
+ HTTPContext *s = h->priv_data;
+
+ av_url_split(proto, sizeof(proto), auth, sizeof(auth),
+ hostname, sizeof(hostname), &port,
+ path1, sizeof(path1), s->location);
+ ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);
+
+ proxy_path = getenv("http_proxy");
+ use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), hostname) &&
+ proxy_path && av_strstart(proxy_path, "http://", NULL);
+
+ if (!strcmp(proto, "https")) {
+ lower_proto = "tls";
+ use_proxy = 0;
+ if (port < 0)
+ port = 443;
+ }
+ if (port < 0)
+ port = 80;
+
+ if (path1[0] == '\0')
+ path = "/";
+ else
+ path = path1;
+ local_path = path;
+ if (use_proxy) {
+ /* Reassemble the request URL without auth string - we don't
+ * want to leak the auth to the proxy. */
+ ff_url_join(urlbuf, sizeof(urlbuf), proto, NULL, hostname, port, "%s",
+ path1);
+ path = urlbuf;
+ av_url_split(NULL, 0, proxyauth, sizeof(proxyauth),
+ hostname, sizeof(hostname), &port, NULL, 0, proxy_path);
+ }
+
+ ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL);
+
+ if (!s->hd) {
+ err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE,
+ &h->interrupt_callback, options);
+ if (err < 0)
+ return err;
+ }
+
+ err = http_connect(h, path, local_path, hoststr,
+ auth, proxyauth, &location_changed);
+ if (err < 0)
+ return err;
+
+ return location_changed;
+}
+
+/* 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;
+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;
+
+ location_changed = http_open_cnx_internal(h, options);
+ if (location_changed < 0)
+ goto fail;
+
+ attempts++;
+ if (s->http_code == 401) {
+ if ((cur_auth_type == HTTP_AUTH_NONE || s->auth_state.stale) &&
+ s->auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) {
+ ffurl_closep(&s->hd);
+ goto redo;
+ } else
+ goto fail;
+ }
+ if (s->http_code == 407) {
+ if ((cur_proxy_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) &&
+ s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) {
+ ffurl_closep(&s->hd);
+ goto redo;
+ } else
+ goto fail;
+ }
+ if ((s->http_code == 301 || s->http_code == 302 ||
+ s->http_code == 303 || s->http_code == 307) &&
+ location_changed == 1) {
+ /* url moved, get next */
+ ffurl_closep(&s->hd);
+ if (redirects++ >= MAX_REDIRECTS)
+ return AVERROR(EIO);
+ /* Restart the authentication process with the new target, which
+ * might use a different auth mechanism. */
+ memset(&s->auth_state, 0, sizeof(s->auth_state));
+ attempts = 0;
+ location_changed = 0;
+ goto redo;
+ }
+ return 0;
+
+fail:
+ if (s->hd)
+ ffurl_closep(&s->hd);
+ if (location_changed < 0)
+ return location_changed;
+ return ff_http_averror(s->http_code, AVERROR(EIO));
+}
+
+int ff_http_do_new_request(URLContext *h, const char *uri)
+{
+ HTTPContext *s = h->priv_data;
+ AVDictionary *options = NULL;
+ int ret;
+
+ s->off = 0;
+ s->icy_data_read = 0;
+ av_free(s->location);
+ s->location = av_strdup(uri);
+ if (!s->location)
+ return AVERROR(ENOMEM);
+
+ ret = http_open_cnx(h, &options);
+ av_dict_free(&options);
+ return ret;
+}
+
+int ff_http_averror(int status_code, int default_averror)
+{
+ switch (status_code) {
+ case 400: return AVERROR_HTTP_BAD_REQUEST;
+ case 401: return AVERROR_HTTP_UNAUTHORIZED;
+ case 403: return AVERROR_HTTP_FORBIDDEN;
+ case 404: return AVERROR_HTTP_NOT_FOUND;
+ default: break;
+ }
+ if (status_code >= 400 && status_code <= 499)
+ return AVERROR_HTTP_OTHER_4XX;
+ else if (status_code >= 500)
+ return AVERROR_HTTP_SERVER_ERROR;
+ else
+ return default_averror;
+}
+
+static int http_write_reply(URLContext* h, int status_code)
+{
+ int ret, body = 0, reply_code, message_len;
+ const char *reply_text, *content_type;
+ HTTPContext *s = h->priv_data;
+ char message[BUFFER_SIZE];
+ content_type = "text/plain";
+
+ if (status_code < 0)
+ body = 1;
+ switch (status_code) {
+ case AVERROR_HTTP_BAD_REQUEST:
+ case 400:
+ reply_code = 400;
+ reply_text = "Bad Request";
+ break;
+ case AVERROR_HTTP_FORBIDDEN:
+ case 403:
+ reply_code = 403;
+ reply_text = "Forbidden";
+ break;
+ case AVERROR_HTTP_NOT_FOUND:
+ case 404:
+ reply_code = 404;
+ reply_text = "Not Found";
+ break;
+ case 200:
+ reply_code = 200;
+ reply_text = "OK";
+ content_type = "application/octet-stream";
+ break;
+ case AVERROR_HTTP_SERVER_ERROR:
+ case 500:
+ reply_code = 500;
+ reply_text = "Internal server error";
+ break;
+ default:
+ return AVERROR(EINVAL);
+ }
+ if (body) {
+ s->chunked_post = 0;
+ message_len = snprintf(message, sizeof(message),
+ "HTTP/1.1 %03d %s\r\n"
+ "Content-Type: %s\r\n"
+ "Content-Length: %zu\r\n"
+ "\r\n"
+ "%03d %s\r\n",
+ reply_code,
+ reply_text,
+ content_type,
+ strlen(reply_text) + 6, // 3 digit status code + space + \r\n
+ reply_code,
+ reply_text);
+ } else {
+ s->chunked_post = 1;
+ message_len = snprintf(message, sizeof(message),
+ "HTTP/1.1 %03d %s\r\n"
+ "Content-Type: %s\r\n"
+ "Transfer-Encoding: chunked\r\n"
+ "\r\n",
+ reply_code,
+ reply_text,
+ content_type);
+ }
+ av_log(h, AV_LOG_TRACE, "HTTP reply header: \n%s----\n", message);
+ if ((ret = ffurl_write(s->hd, message, message_len)) < 0)
+ return ret;
+ return 0;
+}
+
+static void handle_http_errors(URLContext *h, int error)
+{
+ av_assert0(error < 0);
+ http_write_reply(h, error);
+}
+
+static int http_handshake(URLContext *c)
+{
+ int ret, err, new_location;
+ HTTPContext *ch = c->priv_data;
+ URLContext *cl = ch->hd;
+ switch (ch->handshake_step) {
+ case LOWER_PROTO:
+ av_log(c, AV_LOG_TRACE, "Lower protocol\n");
+ if ((ret = ffurl_handshake(cl)) > 0)
+ return 2 + ret;
+ if (ret < 0)
+ return ret;
+ ch->handshake_step = READ_HEADERS;
+ ch->is_connected_server = 1;
+ return 2;
+ case READ_HEADERS:
+ av_log(c, AV_LOG_TRACE, "Read headers\n");
+ if ((err = http_read_header(c, &new_location)) < 0) {
+ handle_http_errors(c, err);
+ return err;
+ }
+ ch->handshake_step = WRITE_REPLY_HEADERS;
+ return 1;
+ case WRITE_REPLY_HEADERS:
+ av_log(c, AV_LOG_TRACE, "Reply code: %d\n", ch->reply_code);
+ if ((err = http_write_reply(c, ch->reply_code)) < 0)
+ return err;
+ ch->handshake_step = FINISH;
+ return 1;
+ case FINISH:
+ return 0;
+ }
+ // this should never be reached.
+ return AVERROR(EINVAL);
+}
+
+static int http_listen(URLContext *h, const char *uri, int flags,
+ AVDictionary **options) {
+ HTTPContext *s = h->priv_data;
+ int ret;
+ char hostname[1024], proto[10];
+ char lower_url[100];
+ const char *lower_proto = "tcp";
+ int port;
+ av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
+ NULL, 0, uri);
+ if (!strcmp(proto, "https"))
+ lower_proto = "tls";
+ ff_url_join(lower_url, sizeof(lower_url), lower_proto, NULL, hostname, port,
+ NULL);
+ if ((ret = av_dict_set_int(options, "listen", s->listen, 0)) < 0)
+ goto fail;
+ if ((ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE,
+ &h->interrupt_callback, options)) < 0)
+ goto fail;
+ s->handshake_step = LOWER_PROTO;
+ if (s->listen == HTTP_SINGLE) { /* single client */
+ s->reply_code = 200;
+ while ((ret = http_handshake(h)) > 0);
+ }
+fail:
+ av_dict_free(&s->chained_options);
+ return ret;
+}
+
+static int http_open(URLContext *h, const char *uri, int flags,
+ AVDictionary **options)
+{
+ HTTPContext *s = h->priv_data;
+ int ret;
+
+ if( s->seekable == 1 )
+ h->is_streamed = 0;
+ else
+ h->is_streamed = 1;
+
+ s->filesize = UINT64_MAX;
+ s->location = av_strdup(uri);
+ if (!s->location)
+ return AVERROR(ENOMEM);
+ if (options)
+ av_dict_copy(&s->chained_options, *options, 0);
+
+ if (s->headers) {
+ int len = strlen(s->headers);
+ if (len < 2 || strcmp("\r\n", s->headers + len - 2)) {
+ av_log(h, AV_LOG_WARNING,
+ "No trailing CRLF found in HTTP header.\n");
+ ret = av_reallocp(&s->headers, len + 3);
+ if (ret < 0)
+ return ret;
+ s->headers[len] = '\r';
+ s->headers[len + 1] = '\n';
+ s->headers[len + 2] = '\0';
+ }
+ }
+
+ if (s->listen) {
+ return http_listen(h, uri, flags, options);
+ }
+ ret = http_open_cnx(h, options);
+ if (ret < 0)
+ av_dict_free(&s->chained_options);
+ return ret;
+}
+
+static int http_accept(URLContext *s, URLContext **c)
+{
+ int ret;
+ HTTPContext *sc = s->priv_data;
+ HTTPContext *cc;
+ URLContext *sl = sc->hd;
+ URLContext *cl = NULL;
+
+ av_assert0(sc->listen);
+ if ((ret = ffurl_alloc(c, s->filename, s->flags, &sl->interrupt_callback)) < 0)
+ goto fail;
+ cc = (*c)->priv_data;
+ if ((ret = ffurl_accept(sl, &cl)) < 0)
+ goto fail;
+ cc->hd = cl;
+ cc->is_multi_client = 1;
+fail:
+ return ret;
+}
+
+static int http_getc(HTTPContext *s)
+{
+ int len;
+ if (s->buf_ptr >= s->buf_end) {
+ len = ffurl_read(s->hd, s->buffer, BUFFER_SIZE);
+ if (len < 0) {
+ return len;
+ } else if (len == 0) {
+ return AVERROR_EOF;
+ } else {
+ s->buf_ptr = s->buffer;
+ s->buf_end = s->buffer + len;
+ }
+ }
+ return *s->buf_ptr++;
+}
+
+static int http_get_line(HTTPContext *s, char *line, int line_size)
+{
+ int ch;
+ char *q;
+
+ q = line;
+ for (;;) {
+ ch = http_getc(s);
+ if (ch < 0)
+ return ch;
+ if (ch == '\n') {
+ /* process line */
+ if (q > line && q[-1] == '\r')
+ q--;
+ *q = '\0';
+
+ return 0;
+ } else {
+ if ((q - line) < line_size - 1)
+ *q++ = ch;
+ }
+ }
+}
+
+static int check_http_code(URLContext *h, int http_code, const char *end)
+{
+ HTTPContext *s = h->priv_data;
+ /* error codes are 4xx and 5xx, but regard 401 as a success, so we
+ * don't abort until all headers have been parsed. */
+ if (http_code >= 400 && http_code < 600 &&
+ (http_code != 401 || s->auth_state.auth_type != HTTP_AUTH_NONE) &&
+ (http_code != 407 || s->proxy_auth_state.auth_type != HTTP_AUTH_NONE)) {
+ end += strspn(end, SPACE_CHARS);
+ av_log(h, AV_LOG_WARNING, "HTTP error %d %s\n", http_code, end);
+ return ff_http_averror(http_code, AVERROR(EIO));
+ }
+ return 0;
+}
+
+static int parse_location(HTTPContext *s, const char *p)
+{
+ char redirected_location[MAX_URL_SIZE], *new_loc;
+ ff_make_absolute_url(redirected_location, sizeof(redirected_location),
+ s->location, p);
+ new_loc = av_strdup(redirected_location);
+ if (!new_loc)
+ return AVERROR(ENOMEM);
+ av_free(s->location);
+ s->location = new_loc;
+ return 0;
+}
+
+/* "bytes $from-$to/$document_size" */
+static void parse_content_range(URLContext *h, const char *p)
+{
+ HTTPContext *s = h->priv_data;
+ const char *slash;
+
+ if (!strncmp(p, "bytes ", 6)) {
+ p += 6;
+ s->off = strtoull(p, NULL, 10);
+ if ((slash = strchr(p, '/')) && strlen(slash) > 0)
+ s->filesize = strtoull(slash + 1, NULL, 10);
+ }
+ if (s->seekable == -1 && (!s->is_akamai || s->filesize != 2147483647))
+ h->is_streamed = 0; /* we _can_ in fact seek */
+}
+
+static int parse_content_encoding(URLContext *h, const char *p)
+{
+ if (!av_strncasecmp(p, "gzip", 4) ||
+ !av_strncasecmp(p, "deflate", 7)) {
+#if CONFIG_ZLIB
+ HTTPContext *s = h->priv_data;
+
+ s->compressed = 1;
+ inflateEnd(&s->inflate_stream);
+ if (inflateInit2(&s->inflate_stream, 32 + 15) != Z_OK) {
+ av_log(h, AV_LOG_WARNING, "Error during zlib initialisation: %s\n",
+ s->inflate_stream.msg);
+ return AVERROR(ENOSYS);
+ }
+ if (zlibCompileFlags() & (1 << 17)) {
+ av_log(h, AV_LOG_WARNING,
+ "Your zlib was compiled without gzip support.\n");
+ return AVERROR(ENOSYS);
+ }
+#else
+ av_log(h, AV_LOG_WARNING,
+ "Compressed (%s) content, need zlib with gzip support\n", p);
+ return AVERROR(ENOSYS);
+#endif /* CONFIG_ZLIB */
+ } else if (!av_strncasecmp(p, "identity", 8)) {
+ // The normal, no-encoding case (although servers shouldn't include
+ // the header at all if this is the case).
+ } else {
+ av_log(h, AV_LOG_WARNING, "Unknown content coding: %s\n", p);
+ }
+ return 0;
+}
+
+// Concat all Icy- header lines
+static int parse_icy(HTTPContext *s, const char *tag, const char *p)
+{
+ int len = 4 + strlen(p) + strlen(tag);
+ int is_first = !s->icy_metadata_headers;
+ int ret;
+
+ av_dict_set(&s->metadata, tag, p, 0);
+
+ if (s->icy_metadata_headers)
+ len += strlen(s->icy_metadata_headers);
+
+ if ((ret = av_reallocp(&s->icy_metadata_headers, len)) < 0)
+ return ret;
+
+ if (is_first)
+ *s->icy_metadata_headers = '\0';
+
+ av_strlcatf(s->icy_metadata_headers, len, "%s: %s\n", tag, p);
+
+ return 0;
+}
+
+static int parse_cookie(HTTPContext *s, const char *p, AVDictionary **cookies)
+{
+ char *eql, *name;
+
+ // duplicate the cookie name (dict will dupe the value)
+ if (!(eql = strchr(p, '='))) return AVERROR(EINVAL);
+ if (!(name = av_strndup(p, eql - p))) return AVERROR(ENOMEM);
+
+ // add the cookie to the dictionary
+ av_dict_set(cookies, name, eql, AV_DICT_DONT_STRDUP_KEY);
+
+ return 0;
+}
+
+static int cookie_string(AVDictionary *dict, char **cookies)
+{
+ AVDictionaryEntry *e = NULL;
+ int len = 1;
+
+ // determine how much memory is needed for the cookies string
+ while (e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))
+ len += strlen(e->key) + strlen(e->value) + 1;
+
+ // reallocate the cookies
+ e = NULL;
+ if (*cookies) av_free(*cookies);
+ *cookies = av_malloc(len);
+ if (!*cookies) return AVERROR(ENOMEM);
+ *cookies[0] = '\0';
+
+ // write out the cookies
+ while (e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX))
+ av_strlcatf(*cookies, len, "%s%s\n", e->key, e->value);
+
+ return 0;
+}
+
+static int process_line(URLContext *h, char *line, int line_count,
+ int *new_location)
+{
+ HTTPContext *s = h->priv_data;
+ const char *auto_method = h->flags & AVIO_FLAG_READ ? "POST" : "GET";
+ char *tag, *p, *end, *method, *resource, *version;
+ int ret;
+
+ /* end of header */
+ if (line[0] == '\0') {
+ s->end_header = 1;
+ return 0;
+ }
+
+ p = line;
+ if (line_count == 0) {
+ if (s->is_connected_server) {
+ // HTTP method
+ method = p;
+ while (*p && !av_isspace(*p))
+ p++;
+ *(p++) = '\0';
+ av_log(h, AV_LOG_TRACE, "Received method: %s\n", method);
+ if (s->method) {
+ if (av_strcasecmp(s->method, method)) {
+ av_log(h, AV_LOG_ERROR, "Received and expected HTTP method do not match. (%s expected, %s received)\n",
+ s->method, method);
+ return ff_http_averror(400, AVERROR(EIO));
+ }
+ } else {
+ // use autodetected HTTP method to expect
+ av_log(h, AV_LOG_TRACE, "Autodetected %s HTTP method\n", auto_method);
+ if (av_strcasecmp(auto_method, method)) {
+ av_log(h, AV_LOG_ERROR, "Received and autodetected HTTP method did not match "
+ "(%s autodetected %s received)\n", auto_method, method);
+ return ff_http_averror(400, AVERROR(EIO));
+ }
+ if (!(s->method = av_strdup(method)))
+ return AVERROR(ENOMEM);
+ }
+
+ // HTTP resource
+ while (av_isspace(*p))
+ p++;
+ resource = p;
+ while (!av_isspace(*p))
+ p++;
+ *(p++) = '\0';
+ av_log(h, AV_LOG_TRACE, "Requested resource: %s\n", resource);
+ if (!(s->resource = av_strdup(resource)))
+ return AVERROR(ENOMEM);
+
+ // HTTP version
+ while (av_isspace(*p))
+ p++;
+ version = p;
+ while (*p && !av_isspace(*p))
+ p++;
+ *p = '\0';
+ if (av_strncasecmp(version, "HTTP/", 5)) {
+ av_log(h, AV_LOG_ERROR, "Malformed HTTP version string.\n");
+ return ff_http_averror(400, AVERROR(EIO));
+ }
+ av_log(h, AV_LOG_TRACE, "HTTP version string: %s\n", version);
+ } else {
+ while (!av_isspace(*p) && *p != '\0')
+ p++;
+ while (av_isspace(*p))
+ p++;
+ s->http_code = strtol(p, &end, 10);
+
+ av_log(h, AV_LOG_TRACE, "http_code=%d\n", s->http_code);
+
+ if ((ret = check_http_code(h, s->http_code, end)) < 0)
+ return ret;
+ }
+ } else {
+ while (*p != '\0' && *p != ':')
+ p++;
+ if (*p != ':')
+ return 1;
+
+ *p = '\0';
+ tag = line;
+ p++;
+ while (av_isspace(*p))
+ p++;
+ if (!av_strcasecmp(tag, "Location")) {
+ if ((ret = parse_location(s, p)) < 0)
+ return ret;
+ *new_location = 1;
+ } else if (!av_strcasecmp(tag, "Content-Length") &&
+ s->filesize == UINT64_MAX) {
+ s->filesize = strtoull(p, NULL, 10);
+ } else if (!av_strcasecmp(tag, "Content-Range")) {
+ parse_content_range(h, p);
+ } else if (!av_strcasecmp(tag, "Accept-Ranges") &&
+ !strncmp(p, "bytes", 5) &&
+ s->seekable == -1) {
+ h->is_streamed = 0;
+ } else if (!av_strcasecmp(tag, "Transfer-Encoding") &&
+ !av_strncasecmp(p, "chunked", 7)) {
+ s->filesize = UINT64_MAX;
+ s->chunksize = 0;
+ } else if (!av_strcasecmp(tag, "WWW-Authenticate")) {
+ ff_http_auth_handle_header(&s->auth_state, tag, p);
+ } else if (!av_strcasecmp(tag, "Authentication-Info")) {
+ ff_http_auth_handle_header(&s->auth_state, tag, p);
+ } else if (!av_strcasecmp(tag, "Proxy-Authenticate")) {
+ ff_http_auth_handle_header(&s->proxy_auth_state, tag, p);
+ } else if (!av_strcasecmp(tag, "Connection")) {
+ if (!strcmp(p, "close"))
+ s->willclose = 1;
+ } else if (!av_strcasecmp(tag, "Server")) {
+ if (!av_strcasecmp(p, "AkamaiGHost")) {
+ s->is_akamai = 1;
+ } else if (!av_strncasecmp(p, "MediaGateway", 12)) {
+ s->is_mediagateway = 1;
+ }
+ } else if (!av_strcasecmp(tag, "Content-Type")) {
+ av_free(s->mime_type);
+ s->mime_type = av_strdup(p);
+ } else if (!av_strcasecmp(tag, "Set-Cookie")) {
+ if (parse_cookie(s, p, &s->cookie_dict))
+ av_log(h, AV_LOG_WARNING, "Unable to parse '%s'\n", p);
+ } else if (!av_strcasecmp(tag, "Icy-MetaInt")) {
+ s->icy_metaint = strtoull(p, NULL, 10);
+ } else if (!av_strncasecmp(tag, "Icy-", 4)) {
+ if ((ret = parse_icy(s, tag, p)) < 0)
+ return ret;
+ } else if (!av_strcasecmp(tag, "Content-Encoding")) {
+ if ((ret = parse_content_encoding(h, p)) < 0)
+ return ret;
+ }
+ }
+ return 1;
+}
+
+/**
+ * Create a string containing cookie values for use as a HTTP cookie header
+ * field value for a particular path and domain from the cookie values stored in
+ * the HTTP protocol context. The cookie string is stored in *cookies.
+ *
+ * @return a negative value if an error condition occurred, 0 otherwise
+ */
+static int get_cookies(HTTPContext *s, char **cookies, const char *path,
+ const char *domain)
+{
+ // cookie strings will look like Set-Cookie header field values. Multiple
+ // Set-Cookie fields will result in multiple values delimited by a newline
+ int ret = 0;
+ char *next, *cookie, *set_cookies = av_strdup(s->cookies), *cset_cookies = set_cookies;
+
+ if (!set_cookies) return AVERROR(EINVAL);
+
+ // destroy any cookies in the dictionary.
+ av_dict_free(&s->cookie_dict);
+
+ *cookies = NULL;
+ while ((cookie = av_strtok(set_cookies, "\n", &next))) {
+ int domain_offset = 0;
+ char *param, *next_param, *cdomain = NULL, *cpath = NULL, *cvalue = NULL;
+ set_cookies = NULL;
+
+ // store the cookie in a dict in case it is updated in the response
+ if (parse_cookie(s, cookie, &s->cookie_dict))
+ av_log(s, AV_LOG_WARNING, "Unable to parse '%s'\n", cookie);
+
+ while ((param = av_strtok(cookie, "; ", &next_param))) {
+ if (cookie) {
+ // first key-value pair is the actual cookie value
+ cvalue = av_strdup(param);
+ cookie = NULL;
+ } else if (!av_strncasecmp("path=", param, 5)) {
+ av_free(cpath);
+ cpath = av_strdup(¶m[5]);
+ } else if (!av_strncasecmp("domain=", param, 7)) {
+ // if the cookie specifies a sub-domain, skip the leading dot thereby
+ // supporting URLs that point to sub-domains and the master domain
+ int leading_dot = (param[7] == '.');
+ av_free(cdomain);
+ cdomain = av_strdup(¶m[7+leading_dot]);
+ } else {
+ // ignore unknown attributes
+ }
+ }
+ if (!cdomain)
+ cdomain = av_strdup(domain);
+
+ // ensure all of the necessary values are valid
+ if (!cdomain || !cpath || !cvalue) {
+ av_log(s, AV_LOG_WARNING,
+ "Invalid cookie found, no value, path or domain specified\n");
+ goto done_cookie;
+ }
+
+ // check if the request path matches the cookie path
+ if (av_strncasecmp(path, cpath, strlen(cpath)))
+ goto done_cookie;
+
+ // the domain should be at least the size of our cookie domain
+ domain_offset = strlen(domain) - strlen(cdomain);
+ if (domain_offset < 0)
+ goto done_cookie;
+
+ // match the cookie domain
+ if (av_strcasecmp(&domain[domain_offset], cdomain))
+ goto done_cookie;
+
+ // cookie parameters match, so copy the value
+ if (!*cookies) {
+ if (!(*cookies = av_strdup(cvalue))) {
+ ret = AVERROR(ENOMEM);
+ goto done_cookie;
+ }
+ } else {
+ char *tmp = *cookies;
+ size_t str_size = strlen(cvalue) + strlen(*cookies) + 3;
+ if (!(*cookies = av_malloc(str_size))) {
+ ret = AVERROR(ENOMEM);
+ goto done_cookie;
+ }
+ snprintf(*cookies, str_size, "%s; %s", tmp, cvalue);
+ av_free(tmp);
+ }
+
+ done_cookie:
+ av_freep(&cdomain);
+ av_freep(&cpath);
+ av_freep(&cvalue);
+ if (ret < 0) {
+ if (*cookies) av_freep(cookies);
+ av_free(cset_cookies);
+ return ret;
+ }
+ }
+
+ av_free(cset_cookies);
+
+ return 0;
+}
+
+static inline int has_header(const char *str, const char *header)
+{
+ /* header + 2 to skip over CRLF prefix. (make sure you have one!) */
+ if (!str)
+ return 0;
+ return av_stristart(str, header + 2, NULL) || av_stristr(str, header);
+}
+
+static int http_read_header(URLContext *h, int *new_location)
+{
+ HTTPContext *s = h->priv_data;
+ char line[MAX_URL_SIZE];
+ int err = 0;
+
+ s->chunksize = UINT64_MAX;
+
+ for (;;) {
+ if ((err = http_get_line(s, line, sizeof(line))) < 0)
+ return err;
+
+ av_log(h, AV_LOG_TRACE, "header='%s'\n", line);
+
+ err = process_line(h, line, s->line_count, new_location);
+ if (err < 0)
+ return err;
+ if (err == 0)
+ break;
+ s->line_count++;
+ }
+
+ if (s->seekable == -1 && s->is_mediagateway && s->filesize == 2000000000)
+ h->is_streamed = 1; /* we can in fact _not_ seek */
+
+ // add any new cookies into the existing cookie string
+ cookie_string(s->cookie_dict, &s->cookies);
+ av_dict_free(&s->cookie_dict);
+
+ return err;
+}
+
+static int http_connect(URLContext *h, const char *path, const char *local_path,
+ const char *hoststr, const char *auth,
+ const char *proxyauth, int *new_location)
+{
+ HTTPContext *s = h->priv_data;
+ int post, err;
+ char headers[HTTP_HEADERS_SIZE] = "";
+ char *authstr = NULL, *proxyauthstr = NULL;
+ uint64_t off = s->off;
+ int len = 0;
+ const char *method;
+ int send_expect_100 = 0;
+ int ret;
+
+ /* send http header */
+ post = h->flags & AVIO_FLAG_WRITE;
+
+ if (s->post_data) {
+ /* force POST method and disable chunked encoding when
+ * custom HTTP post data is set */
+ post = 1;
+ s->chunked_post = 0;
+ }
+
+ if (s->method)
+ method = s->method;
+ else
+ method = post ? "POST" : "GET";
+
+ authstr = ff_http_auth_create_response(&s->auth_state, auth,
+ local_path, method);
+ proxyauthstr = ff_http_auth_create_response(&s->proxy_auth_state, proxyauth,
+ local_path, method);
+ if (post && !s->post_data) {
+ send_expect_100 = s->send_expect_100;
+ /* The user has supplied authentication but we don't know the auth type,
+ * send Expect: 100-continue to get the 401 response including the
+ * WWW-Authenticate header, or an 100 continue if no auth actually
+ * is needed. */
+ if (auth && *auth &&
+ s->auth_state.auth_type == HTTP_AUTH_NONE &&
+ s->http_code != 401)
+ send_expect_100 = 1;
+ }
+
+ /* set default headers if needed */
+ if (!has_header(s->headers, "\r\nUser-Agent: "))
+ len += av_strlcatf(headers + len, sizeof(headers) - len,
+ "User-Agent: %s\r\n", s->user_agent);
+ if (!has_header(s->headers, "\r\nAccept: "))
+ len += av_strlcpy(headers + len, "Accept: */*\r\n",
+ sizeof(headers) - len);
+ // Note: we send this on purpose even when s->off is 0 when we're probing,
+ // since it allows us to detect more reliably if a (non-conforming)
+ // server supports seeking by analysing the reply headers.
+ if (!has_header(s->headers, "\r\nRange: ") && !post && (s->off > 0 || s->end_off || s->seekable == -1)) {
+ len += av_strlcatf(headers + len, sizeof(headers) - len,
+ "Range: bytes=%"PRIu64"-", s->off);
+ if (s->end_off)
+ len += av_strlcatf(headers + len, sizeof(headers) - len,
+ "%"PRId64, s->end_off - 1);
+ len += av_strlcpy(headers + len, "\r\n",
+ sizeof(headers) - len);
+ }
+ if (send_expect_100 && !has_header(s->headers, "\r\nExpect: "))
+ len += av_strlcatf(headers + len, sizeof(headers) - len,
+ "Expect: 100-continue\r\n");
+
+ if (!has_header(s->headers, "\r\nConnection: ")) {
+ if (s->multiple_requests)
+ len += av_strlcpy(headers + len, "Connection: keep-alive\r\n",
+ sizeof(headers) - len);
+ else
+ len += av_strlcpy(headers + len, "Connection: close\r\n",
+ sizeof(headers) - len);
+ }
+
+ if (!has_header(s->headers, "\r\nHost: "))
+ len += av_strlcatf(headers + len, sizeof(headers) - len,
+ "Host: %s\r\n", hoststr);
+ if (!has_header(s->headers, "\r\nContent-Length: ") && s->post_data)
+ len += av_strlcatf(headers + len, sizeof(headers) - len,
+ "Content-Length: %d\r\n", s->post_datalen);
+
+ if (!has_header(s->headers, "\r\nContent-Type: ") && s->content_type)
+ len += av_strlcatf(headers + len, sizeof(headers) - len,
+ "Content-Type: %s\r\n", s->content_type);
+ if (!has_header(s->headers, "\r\nCookie: ") && s->cookies) {
+ char *cookies = NULL;
+ if (!get_cookies(s, &cookies, path, hoststr) && cookies) {
+ len += av_strlcatf(headers + len, sizeof(headers) - len,
+ "Cookie: %s\r\n", cookies);
+ av_free(cookies);
+ }
+ }
+ if (!has_header(s->headers, "\r\nIcy-MetaData: ") && s->icy)
+ len += av_strlcatf(headers + len, sizeof(headers) - len,
+ "Icy-MetaData: %d\r\n", 1);
+
+ /* now add in custom headers */
+ if (s->headers)
+ av_strlcpy(headers + len, s->headers, sizeof(headers) - len);
+
+ ret = snprintf(s->buffer, sizeof(s->buffer),
+ "%s %s HTTP/1.1\r\n"
+ "%s"
+ "%s"
+ "%s"
+ "%s%s"
+ "\r\n",
+ method,
+ path,
+ post && s->chunked_post ? "Transfer-Encoding: chunked\r\n" : "",
+ headers,
+ authstr ? authstr : "",
+ proxyauthstr ? "Proxy-" : "", proxyauthstr ? proxyauthstr : "");
+
+ av_log(h, AV_LOG_DEBUG, "request: %s\n", s->buffer);
+
+ if (strlen(headers) + 1 == sizeof(headers) ||
+ ret >= sizeof(s->buffer)) {
+ av_log(h, AV_LOG_ERROR, "overlong headers\n");
+ err = AVERROR(EINVAL);
+ goto done;
+ }
+
+
+ if ((err = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0)
+ goto done;
+
+ if (s->post_data)
+ if ((err = ffurl_write(s->hd, s->post_data, s->post_datalen)) < 0)
+ goto done;
+
+ /* init input buffer */
+ s->buf_ptr = s->buffer;
+ s->buf_end = s->buffer;
+ s->line_count = 0;
+ s->off = 0;
+ s->icy_data_read = 0;
+ s->filesize = UINT64_MAX;
+ s->willclose = 0;
+ s->end_chunked_post = 0;
+ s->end_header = 0;
+ if (post && !s->post_data && !send_expect_100) {
+ /* Pretend that it did work. We didn't read any header yet, since
+ * we've still to send the POST data, but the code calling this
+ * function will check http_code after we return. */
+ s->http_code = 200;
+ err = 0;
+ goto done;
+ }
+
+ /* wait for header */
+ err = http_read_header(h, new_location);
+ if (err < 0)
+ goto done;
+
+ if (*new_location)
+ s->off = off;
+
+ err = (off == s->off) ? 0 : -1;
+done:
+ av_freep(&authstr);
+ av_freep(&proxyauthstr);
+ return err;
+}
+
+static int http_buf_read(URLContext *h, uint8_t *buf, int size)
+{
+ HTTPContext *s = h->priv_data;
+ int len;
+
+ if (s->chunksize != UINT64_MAX) {
+ if (!s->chunksize) {
+ char line[32];
+ int err;
+
+ do {
+ if ((err = http_get_line(s, line, sizeof(line))) < 0)
+ return err;
+ } while (!*line); /* skip CR LF from last chunk */
+
+ s->chunksize = strtoull(line, NULL, 16);
+
+ av_log(h, AV_LOG_TRACE,
+ "Chunked encoding data size: %"PRIu64"'\n",
+ s->chunksize);
+
+ if (!s->chunksize)
+ return 0;
+ else if (s->chunksize == UINT64_MAX) {
+ av_log(h, AV_LOG_ERROR, "Invalid chunk size %"PRIu64"\n",
+ s->chunksize);
+ return AVERROR(EINVAL);
+ }
+ }
+ size = FFMIN(size, s->chunksize);
+ }
+
+ /* read bytes from input buffer first */
+ len = s->buf_end - s->buf_ptr;
+ if (len > 0) {
+ if (len > size)
+ len = size;
+ memcpy(buf, s->buf_ptr, len);
+ s->buf_ptr += len;
+ } else {
+ if ((!s->willclose || s->chunksize == UINT64_MAX) && s->off >= s->filesize)
+ return AVERROR_EOF;
+ len = ffurl_read(s->hd, buf, size);
+ if (!len && (!s->willclose || s->chunksize == UINT64_MAX) && s->off < s->filesize) {
+ av_log(h, AV_LOG_ERROR,
+ "Stream ends prematurely at %"PRIu64", should be %"PRIu64"\n",
+ s->off, s->filesize
+ );
+ return AVERROR(EIO);
+ }
+ }
+ if (len > 0) {
+ s->off += len;
+ if (s->chunksize > 0) {
+ av_assert0(s->chunksize >= len);
+ s->chunksize -= len;
+ }
+ }
+ return len;
+}
+
+#if CONFIG_ZLIB
+#define DECOMPRESS_BUF_SIZE (256 * 1024)
+static int http_buf_read_compressed(URLContext *h, uint8_t *buf, int size)
+{
+ HTTPContext *s = h->priv_data;
+ int ret;
+
+ if (!s->inflate_buffer) {
+ s->inflate_buffer = av_malloc(DECOMPRESS_BUF_SIZE);
+ if (!s->inflate_buffer)
+ return AVERROR(ENOMEM);
+ }
+
+ if (s->inflate_stream.avail_in == 0) {
+ int read = http_buf_read(h, s->inflate_buffer, DECOMPRESS_BUF_SIZE);
+ if (read <= 0)
+ return read;
+ s->inflate_stream.next_in = s->inflate_buffer;
+ s->inflate_stream.avail_in = read;
+ }
+
+ s->inflate_stream.avail_out = size;
+ s->inflate_stream.next_out = buf;
+
+ ret = inflate(&s->inflate_stream, Z_SYNC_FLUSH);
+ if (ret != Z_OK && ret != Z_STREAM_END)
+ av_log(h, AV_LOG_WARNING, "inflate return value: %d, %s\n",
+ ret, s->inflate_stream.msg);
+
+ return size - s->inflate_stream.avail_out;
+}
+#endif /* CONFIG_ZLIB */
+
+static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int force_reconnect);
+
+static int http_read_stream(URLContext *h, uint8_t *buf, int size)
+{
+ HTTPContext *s = h->priv_data;
+ int err, new_location, read_ret, seek_ret;
+
+ if (!s->hd)
+ return AVERROR_EOF;
+
+ if (s->end_chunked_post && !s->end_header) {
+ err = http_read_header(h, &new_location);
+ if (err < 0)
+ return err;
+ }
+
+#if CONFIG_ZLIB
+ if (s->compressed)
+ return http_buf_read_compressed(h, buf, size);
+#endif /* CONFIG_ZLIB */
+ read_ret = http_buf_read(h, buf, size);
+ if (read_ret < 0 && s->reconnect && !h->is_streamed && s->filesize > 0 && s->off < s->filesize) {
+ av_log(h, AV_LOG_INFO, "Will reconnect at %"PRIu64".\n", s->off);
+ seek_ret = http_seek_internal(h, s->off, SEEK_SET, 1);
+ if (seek_ret != s->off) {
+ av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRIu64".\n", s->off);
+ return read_ret;
+ }
+
+ read_ret = http_buf_read(h, buf, size);
+ }
+
+ return read_ret;
+}
+
+// Like http_read_stream(), but no short reads.
+// Assumes partial reads are an error.
+static int http_read_stream_all(URLContext *h, uint8_t *buf, int size)
+{
+ int pos = 0;
+ while (pos < size) {
+ int len = http_read_stream(h, buf + pos, size - pos);
+ if (len < 0)
+ return len;
+ pos += len;
+ }
+ return pos;
+}
+
+static void update_metadata(HTTPContext *s, char *data)
+{
+ char *key;
+ char *val;
+ char *end;
+ char *next = data;
+
+ while (*next) {
+ key = next;
+ val = strstr(key, "='");
+ if (!val)
+ break;
+ end = strstr(val, "';");
+ if (!end)
+ break;
+
+ *val = '\0';
+ *end = '\0';
+ val += 2;
+
+ av_dict_set(&s->metadata, key, val, 0);
+
+ next = end + 2;
+ }
+}
+
+static int store_icy(URLContext *h, int size)
+{
+ HTTPContext *s = h->priv_data;
+ /* until next metadata packet */
+ uint64_t remaining;
+
+ if (s->icy_metaint < s->icy_data_read)
+ return AVERROR_INVALIDDATA;
+ remaining = s->icy_metaint - s->icy_data_read;
+
+ if (!remaining) {
+ /* The metadata packet is variable sized. It has a 1 byte header
+ * which sets the length of the packet (divided by 16). If it's 0,
+ * the metadata doesn't change. After the packet, icy_metaint bytes
+ * of normal data follows. */
+ uint8_t ch;
+ int len = http_read_stream_all(h, &ch, 1);
+ if (len < 0)
+ return len;
+ if (ch > 0) {
+ char data[255 * 16 + 1];
+ int ret;
+ len = ch * 16;
+ ret = http_read_stream_all(h, data, len);
+ if (ret < 0)
+ return ret;
+ data[len + 1] = 0;
+ if ((ret = av_opt_set(s, "icy_metadata_packet", data, 0)) < 0)
+ return ret;
+ update_metadata(s, data);
+ }
+ s->icy_data_read = 0;
+ remaining = s->icy_metaint;
+ }
+
+ return FFMIN(size, remaining);
+}
+
+static int http_read(URLContext *h, uint8_t *buf, int size)
+{
+ HTTPContext *s = h->priv_data;
+
+ if (s->icy_metaint > 0) {
+ size = store_icy(h, size);
+ if (size < 0)
+ return size;
+ }
+
+ size = http_read_stream(h, buf, size);
+ if (size > 0)
+ s->icy_data_read += size;
+ return size;
+}
+
+/* used only when posting data */
+static int http_write(URLContext *h, const uint8_t *buf, int size)
+{
+ char temp[11] = ""; /* 32-bit hex + CRLF + nul */
+ int ret;
+ char crlf[] = "\r\n";
+ HTTPContext *s = h->priv_data;
+
+ if (!s->chunked_post) {
+ /* non-chunked data is sent without any special encoding */
+ return ffurl_write(s->hd, buf, size);
+ }
+
+ /* silently ignore zero-size data since chunk encoding that would
+ * signal EOF */
+ if (size > 0) {
+ /* upload data using chunked encoding */
+ snprintf(temp, sizeof(temp), "%x\r\n", size);
+
+ if ((ret = ffurl_write(s->hd, temp, strlen(temp))) < 0 ||
+ (ret = ffurl_write(s->hd, buf, size)) < 0 ||
+ (ret = ffurl_write(s->hd, crlf, sizeof(crlf) - 1)) < 0)
+ return ret;
+ }
+ return size;
+}
+
+static int http_shutdown(URLContext *h, int flags)
+{
+ int ret = 0;
+ char footer[] = "0\r\n\r\n";
+ HTTPContext *s = h->priv_data;
+
+ /* signal end of chunked encoding if used */
+ if (((flags & AVIO_FLAG_WRITE) && s->chunked_post) ||
+ ((flags & AVIO_FLAG_READ) && s->chunked_post && s->listen)) {
+ ret = ffurl_write(s->hd, footer, sizeof(footer) - 1);
+ ret = ret > 0 ? 0 : ret;
+ s->end_chunked_post = 1;
+ }
+
+ return ret;
+}
+
+static int http_close(URLContext *h)
+{
+ int ret = 0;
+ HTTPContext *s = h->priv_data;
+
+#if CONFIG_ZLIB
+ inflateEnd(&s->inflate_stream);
+ av_freep(&s->inflate_buffer);
+#endif /* CONFIG_ZLIB */
+
+ if (!s->end_chunked_post)
+ /* Close the write direction by sending the end of chunked encoding. */
+ ret = http_shutdown(h, h->flags);
+
+ if (s->hd)
+ ffurl_closep(&s->hd);
+ av_dict_free(&s->chained_options);
+ return ret;
+}
+
+static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int force_reconnect)
+{
+ HTTPContext *s = h->priv_data;
+ URLContext *old_hd = s->hd;
+ uint64_t old_off = s->off;
+ uint8_t old_buf[BUFFER_SIZE];
+ int old_buf_size, ret;
+ AVDictionary *options = NULL;
+
+ if (whence == AVSEEK_SIZE)
+ return s->filesize;
+ else if (!force_reconnect &&
+ ((whence == SEEK_CUR && off == 0) ||
+ (whence == SEEK_SET && off == s->off)))
+ return s->off;
+ else if ((s->filesize == UINT64_MAX && whence == SEEK_END) || h->is_streamed)
+ return AVERROR(ENOSYS);
+
+ if (whence == SEEK_CUR)
+ off += s->off;
+ else if (whence == SEEK_END)
+ off += s->filesize;
+ else if (whence != SEEK_SET)
+ return AVERROR(EINVAL);
+ if (off < 0)
+ return AVERROR(EINVAL);
+ s->off = off;
+
+ /* we save the old context in case the seek fails */
+ old_buf_size = s->buf_end - s->buf_ptr;
+ memcpy(old_buf, s->buf_ptr, old_buf_size);
+ s->hd = NULL;
+
+ /* if it fails, continue on old connection */
+ if ((ret = http_open_cnx(h, &options)) < 0) {
+ av_dict_free(&options);
+ memcpy(s->buffer, old_buf, old_buf_size);
+ s->buf_ptr = s->buffer;
+ s->buf_end = s->buffer + old_buf_size;
+ s->hd = old_hd;
+ s->off = old_off;
+ return ret;
+ }
+ av_dict_free(&options);
+ ffurl_close(old_hd);
+ return off;
+}
+
+static int64_t http_seek(URLContext *h, int64_t off, int whence)
+{
+ return http_seek_internal(h, off, whence, 0);
+}
+
+static int http_get_file_handle(URLContext *h)
+{
+ HTTPContext *s = h->priv_data;
+ return ffurl_get_file_handle(s->hd);
+}
+
+#define HTTP_CLASS(flavor) \
+static const AVClass flavor ## _context_class = { \
+ .class_name = # flavor, \
+ .item_name = av_default_item_name, \
+ .option = options, \
+ .version = LIBAVUTIL_VERSION_INT, \
+}
+
+#if CONFIG_HTTP_PROTOCOL
+HTTP_CLASS(http);
+
+URLProtocol ff_http_protocol = {
+ .name = "http",
+ .url_open2 = http_open,
+ .url_accept = http_accept,
+ .url_handshake = http_handshake,
+ .url_read = http_read,
+ .url_write = http_write,
+ .url_seek = http_seek,
+ .url_close = http_close,
+ .url_get_file_handle = http_get_file_handle,
+ .url_shutdown = http_shutdown,
+ .priv_data_size = sizeof(HTTPContext),
+ .priv_data_class = &http_context_class,
+ .flags = URL_PROTOCOL_FLAG_NETWORK,
+};
+#endif /* CONFIG_HTTP_PROTOCOL */
+
+#if CONFIG_HTTPS_PROTOCOL
+HTTP_CLASS(https);
+
+URLProtocol ff_https_protocol = {
+ .name = "https",
+ .url_open2 = http_open,
+ .url_read = http_read,
+ .url_write = http_write,
+ .url_seek = http_seek,
+ .url_close = http_close,
+ .url_get_file_handle = http_get_file_handle,
+ .url_shutdown = http_shutdown,
+ .priv_data_size = sizeof(HTTPContext),
+ .priv_data_class = &https_context_class,
+ .flags = URL_PROTOCOL_FLAG_NETWORK,
+};
+#endif /* CONFIG_HTTPS_PROTOCOL */
+
+#if CONFIG_HTTPPROXY_PROTOCOL
+static int http_proxy_close(URLContext *h)
+{
+ HTTPContext *s = h->priv_data;
+ if (s->hd)
+ ffurl_closep(&s->hd);
+ return 0;
+}
+
+static int http_proxy_open(URLContext *h, const char *uri, int flags)
+{
+ HTTPContext *s = h->priv_data;
+ char hostname[1024], hoststr[1024];
+ char auth[1024], pathbuf[1024], *path;
+ char lower_url[100];
+ int port, ret = 0, attempts = 0;
+ HTTPAuthType cur_auth_type;
+ char *authstr;
+ int new_loc;
+
+ if( s->seekable == 1 )
+ h->is_streamed = 0;
+ else
+ h->is_streamed = 1;
+
+ av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port,
+ pathbuf, sizeof(pathbuf), uri);
+ ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL);
+ path = pathbuf;
+ if (*path == '/')
+ path++;
+
+ ff_url_join(lower_url, sizeof(lower_url), "tcp", NULL, hostname, port,
+ NULL);
+redo:
+ ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE,
+ &h->interrupt_callback, NULL);
+ if (ret < 0)
+ return ret;
+
+ authstr = ff_http_auth_create_response(&s->proxy_auth_state, auth,
+ path, "CONNECT");
+ snprintf(s->buffer, sizeof(s->buffer),
+ "CONNECT %s HTTP/1.1\r\n"
+ "Host: %s\r\n"
+ "Connection: close\r\n"
+ "%s%s"
+ "\r\n",
+ path,
+ hoststr,
+ authstr ? "Proxy-" : "", authstr ? authstr : "");
+ av_freep(&authstr);
+
+ if ((ret = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0)
+ goto fail;
+
+ s->buf_ptr = s->buffer;
+ s->buf_end = s->buffer;
+ s->line_count = 0;
+ s->filesize = UINT64_MAX;
+ cur_auth_type = s->proxy_auth_state.auth_type;
+
+ /* Note: This uses buffering, potentially reading more than the
+ * HTTP header. If tunneling a protocol where the server starts
+ * the conversation, we might buffer part of that here, too.
+ * Reading that requires using the proper ffurl_read() function
+ * on this URLContext, not using the fd directly (as the tls
+ * protocol does). This shouldn't be an issue for tls though,
+ * since the client starts the conversation there, so there
+ * is no extra data that we might buffer up here.
+ */
+ ret = http_read_header(h, &new_loc);
+ if (ret < 0)
+ goto fail;
+
+ attempts++;
+ if (s->http_code == 407 &&
+ (cur_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) &&
+ s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 2) {
+ ffurl_closep(&s->hd);
+ goto redo;
+ }
+
+ if (s->http_code < 400)
+ return 0;
+ ret = ff_http_averror(s->http_code, AVERROR(EIO));
+
+fail:
+ http_proxy_close(h);
+ return ret;
+}
+
+static int http_proxy_write(URLContext *h, const uint8_t *buf, int size)
+{
+ HTTPContext *s = h->priv_data;
+ return ffurl_write(s->hd, buf, size);
+}
+
+URLProtocol ff_httpproxy_protocol = {
+ .name = "httpproxy",
+ .url_open = http_proxy_open,
+ .url_read = http_buf_read,
+ .url_write = http_proxy_write,
+ .url_close = http_proxy_close,
+ .url_get_file_handle = http_get_file_handle,
+ .priv_data_size = sizeof(HTTPContext),
+ .flags = URL_PROTOCOL_FLAG_NETWORK,
+};
+#endif /* CONFIG_HTTPPROXY_PROTOCOL */
diff --git a/ffmpeg-2-8-11/libavformat/http.h b/ffmpeg-2-8-12/libavformat/http.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/http.h
rename to ffmpeg-2-8-12/libavformat/http.h
diff --git a/ffmpeg-2-8-11/libavformat/httpauth.c b/ffmpeg-2-8-12/libavformat/httpauth.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/httpauth.c
rename to ffmpeg-2-8-12/libavformat/httpauth.c
diff --git a/ffmpeg-2-8-11/libavformat/httpauth.h b/ffmpeg-2-8-12/libavformat/httpauth.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/httpauth.h
rename to ffmpeg-2-8-12/libavformat/httpauth.h
diff --git a/ffmpeg-2-8-11/libavformat/icecast.c b/ffmpeg-2-8-12/libavformat/icecast.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/icecast.c
rename to ffmpeg-2-8-12/libavformat/icecast.c
diff --git a/ffmpeg-2-8-11/libavformat/icodec.c b/ffmpeg-2-8-12/libavformat/icodec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/icodec.c
rename to ffmpeg-2-8-12/libavformat/icodec.c
diff --git a/ffmpeg-2-8-11/libavformat/icoenc.c b/ffmpeg-2-8-12/libavformat/icoenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/icoenc.c
rename to ffmpeg-2-8-12/libavformat/icoenc.c
diff --git a/ffmpeg-2-8-11/libavformat/id3v1.c b/ffmpeg-2-8-12/libavformat/id3v1.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/id3v1.c
rename to ffmpeg-2-8-12/libavformat/id3v1.c
diff --git a/ffmpeg-2-8-11/libavformat/id3v1.h b/ffmpeg-2-8-12/libavformat/id3v1.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/id3v1.h
rename to ffmpeg-2-8-12/libavformat/id3v1.h
diff --git a/ffmpeg-2-8-11/libavformat/id3v2.c b/ffmpeg-2-8-12/libavformat/id3v2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/id3v2.c
rename to ffmpeg-2-8-12/libavformat/id3v2.c
diff --git a/ffmpeg-2-8-11/libavformat/id3v2.h b/ffmpeg-2-8-12/libavformat/id3v2.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/id3v2.h
rename to ffmpeg-2-8-12/libavformat/id3v2.h
diff --git a/ffmpeg-2-8-11/libavformat/id3v2enc.c b/ffmpeg-2-8-12/libavformat/id3v2enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/id3v2enc.c
rename to ffmpeg-2-8-12/libavformat/id3v2enc.c
diff --git a/ffmpeg-2-8-11/libavformat/idcin.c b/ffmpeg-2-8-12/libavformat/idcin.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/idcin.c
rename to ffmpeg-2-8-12/libavformat/idcin.c
diff --git a/ffmpeg-2-8-11/libavformat/idroqdec.c b/ffmpeg-2-8-12/libavformat/idroqdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/idroqdec.c
rename to ffmpeg-2-8-12/libavformat/idroqdec.c
diff --git a/ffmpeg-2-8-11/libavformat/idroqenc.c b/ffmpeg-2-8-12/libavformat/idroqenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/idroqenc.c
rename to ffmpeg-2-8-12/libavformat/idroqenc.c
diff --git a/ffmpeg-2-8-11/libavformat/iff.c b/ffmpeg-2-8-12/libavformat/iff.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/iff.c
rename to ffmpeg-2-8-12/libavformat/iff.c
diff --git a/ffmpeg-2-8-11/libavformat/ilbc.c b/ffmpeg-2-8-12/libavformat/ilbc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ilbc.c
rename to ffmpeg-2-8-12/libavformat/ilbc.c
diff --git a/ffmpeg-2-8-11/libavformat/img2.c b/ffmpeg-2-8-12/libavformat/img2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/img2.c
rename to ffmpeg-2-8-12/libavformat/img2.c
diff --git a/ffmpeg-2-8-11/libavformat/img2.h b/ffmpeg-2-8-12/libavformat/img2.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/img2.h
rename to ffmpeg-2-8-12/libavformat/img2.h
diff --git a/ffmpeg-2-8-11/libavformat/img2_alias_pix.c b/ffmpeg-2-8-12/libavformat/img2_alias_pix.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/img2_alias_pix.c
rename to ffmpeg-2-8-12/libavformat/img2_alias_pix.c
diff --git a/ffmpeg-2-8-11/libavformat/img2_brender_pix.c b/ffmpeg-2-8-12/libavformat/img2_brender_pix.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/img2_brender_pix.c
rename to ffmpeg-2-8-12/libavformat/img2_brender_pix.c
diff --git a/ffmpeg-2-8-11/libavformat/img2dec.c b/ffmpeg-2-8-12/libavformat/img2dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/img2dec.c
rename to ffmpeg-2-8-12/libavformat/img2dec.c
diff --git a/ffmpeg-2-8-11/libavformat/img2enc.c b/ffmpeg-2-8-12/libavformat/img2enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/img2enc.c
rename to ffmpeg-2-8-12/libavformat/img2enc.c
diff --git a/ffmpeg-2-8-11/libavformat/ingenientdec.c b/ffmpeg-2-8-12/libavformat/ingenientdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ingenientdec.c
rename to ffmpeg-2-8-12/libavformat/ingenientdec.c
diff --git a/ffmpeg-2-8-11/libavformat/internal.h b/ffmpeg-2-8-12/libavformat/internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/internal.h
rename to ffmpeg-2-8-12/libavformat/internal.h
diff --git a/ffmpeg-2-8-11/libavformat/ipmovie.c b/ffmpeg-2-8-12/libavformat/ipmovie.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ipmovie.c
rename to ffmpeg-2-8-12/libavformat/ipmovie.c
diff --git a/ffmpeg-2-8-11/libavformat/ircam.c b/ffmpeg-2-8-12/libavformat/ircam.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ircam.c
rename to ffmpeg-2-8-12/libavformat/ircam.c
diff --git a/ffmpeg-2-8-11/libavformat/ircam.h b/ffmpeg-2-8-12/libavformat/ircam.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ircam.h
rename to ffmpeg-2-8-12/libavformat/ircam.h
diff --git a/ffmpeg-2-8-11/libavformat/ircamdec.c b/ffmpeg-2-8-12/libavformat/ircamdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ircamdec.c
rename to ffmpeg-2-8-12/libavformat/ircamdec.c
diff --git a/ffmpeg-2-8-11/libavformat/ircamenc.c b/ffmpeg-2-8-12/libavformat/ircamenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ircamenc.c
rename to ffmpeg-2-8-12/libavformat/ircamenc.c
diff --git a/ffmpeg-2-8-11/libavformat/isom.c b/ffmpeg-2-8-12/libavformat/isom.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/isom.c
rename to ffmpeg-2-8-12/libavformat/isom.c
diff --git a/ffmpeg-2-8-11/libavformat/isom.h b/ffmpeg-2-8-12/libavformat/isom.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/isom.h
rename to ffmpeg-2-8-12/libavformat/isom.h
diff --git a/ffmpeg-2-8-11/libavformat/iss.c b/ffmpeg-2-8-12/libavformat/iss.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/iss.c
rename to ffmpeg-2-8-12/libavformat/iss.c
diff --git a/ffmpeg-2-8-11/libavformat/iv8.c b/ffmpeg-2-8-12/libavformat/iv8.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/iv8.c
rename to ffmpeg-2-8-12/libavformat/iv8.c
diff --git a/ffmpeg-2-8-11/libavformat/ivfdec.c b/ffmpeg-2-8-12/libavformat/ivfdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ivfdec.c
rename to ffmpeg-2-8-12/libavformat/ivfdec.c
diff --git a/ffmpeg-2-8-11/libavformat/ivfenc.c b/ffmpeg-2-8-12/libavformat/ivfenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ivfenc.c
rename to ffmpeg-2-8-12/libavformat/ivfenc.c
diff --git a/ffmpeg-2-8-11/libavformat/jacosubdec.c b/ffmpeg-2-8-12/libavformat/jacosubdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/jacosubdec.c
rename to ffmpeg-2-8-12/libavformat/jacosubdec.c
diff --git a/ffmpeg-2-8-11/libavformat/jacosubenc.c b/ffmpeg-2-8-12/libavformat/jacosubenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/jacosubenc.c
rename to ffmpeg-2-8-12/libavformat/jacosubenc.c
diff --git a/ffmpeg-2-8-11/libavformat/jvdec.c b/ffmpeg-2-8-12/libavformat/jvdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/jvdec.c
rename to ffmpeg-2-8-12/libavformat/jvdec.c
diff --git a/ffmpeg-2-8-11/libavformat/latmenc.c b/ffmpeg-2-8-12/libavformat/latmenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/latmenc.c
rename to ffmpeg-2-8-12/libavformat/latmenc.c
diff --git a/ffmpeg-2-8-11/libavformat/libavformat.v b/ffmpeg-2-8-12/libavformat/libavformat.v
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/libavformat.v
rename to ffmpeg-2-8-12/libavformat/libavformat.v
diff --git a/ffmpeg-2-8-11/libavformat/libgme.c b/ffmpeg-2-8-12/libavformat/libgme.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/libgme.c
rename to ffmpeg-2-8-12/libavformat/libgme.c
diff --git a/ffmpeg-2-8-11/libavformat/libmodplug.c b/ffmpeg-2-8-12/libavformat/libmodplug.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/libmodplug.c
rename to ffmpeg-2-8-12/libavformat/libmodplug.c
diff --git a/ffmpeg-2-8-11/libavformat/libnut.c b/ffmpeg-2-8-12/libavformat/libnut.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/libnut.c
rename to ffmpeg-2-8-12/libavformat/libnut.c
diff --git a/ffmpeg-2-8-11/libavformat/libquvi.c b/ffmpeg-2-8-12/libavformat/libquvi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/libquvi.c
rename to ffmpeg-2-8-12/libavformat/libquvi.c
diff --git a/ffmpeg-2-8-11/libavformat/librtmp.c b/ffmpeg-2-8-12/libavformat/librtmp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/librtmp.c
rename to ffmpeg-2-8-12/libavformat/librtmp.c
diff --git a/ffmpeg-2-8-11/libavformat/libsmbclient.c b/ffmpeg-2-8-12/libavformat/libsmbclient.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/libsmbclient.c
rename to ffmpeg-2-8-12/libavformat/libsmbclient.c
diff --git a/ffmpeg-2-8-11/libavformat/libssh.c b/ffmpeg-2-8-12/libavformat/libssh.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/libssh.c
rename to ffmpeg-2-8-12/libavformat/libssh.c
diff --git a/ffmpeg-2-8-11/libavformat/lmlm4.c b/ffmpeg-2-8-12/libavformat/lmlm4.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/lmlm4.c
rename to ffmpeg-2-8-12/libavformat/lmlm4.c
diff --git a/ffmpeg-2-8-11/libavformat/loasdec.c b/ffmpeg-2-8-12/libavformat/loasdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/loasdec.c
rename to ffmpeg-2-8-12/libavformat/loasdec.c
diff --git a/ffmpeg-2-8-11/libavformat/log2_tab.c b/ffmpeg-2-8-12/libavformat/log2_tab.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/log2_tab.c
rename to ffmpeg-2-8-12/libavformat/log2_tab.c
diff --git a/ffmpeg-2-8-11/libavformat/lrc.c b/ffmpeg-2-8-12/libavformat/lrc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/lrc.c
rename to ffmpeg-2-8-12/libavformat/lrc.c
diff --git a/ffmpeg-2-8-11/libavformat/lrc.h b/ffmpeg-2-8-12/libavformat/lrc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/lrc.h
rename to ffmpeg-2-8-12/libavformat/lrc.h
diff --git a/ffmpeg-2-8-11/libavformat/lrcdec.c b/ffmpeg-2-8-12/libavformat/lrcdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/lrcdec.c
rename to ffmpeg-2-8-12/libavformat/lrcdec.c
diff --git a/ffmpeg-2-8-11/libavformat/lrcenc.c b/ffmpeg-2-8-12/libavformat/lrcenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/lrcenc.c
rename to ffmpeg-2-8-12/libavformat/lrcenc.c
diff --git a/ffmpeg-2-8-11/libavformat/lvfdec.c b/ffmpeg-2-8-12/libavformat/lvfdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/lvfdec.c
rename to ffmpeg-2-8-12/libavformat/lvfdec.c
diff --git a/ffmpeg-2-8-11/libavformat/lxfdec.c b/ffmpeg-2-8-12/libavformat/lxfdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/lxfdec.c
rename to ffmpeg-2-8-12/libavformat/lxfdec.c
diff --git a/ffmpeg-2-8-11/libavformat/m4vdec.c b/ffmpeg-2-8-12/libavformat/m4vdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/m4vdec.c
rename to ffmpeg-2-8-12/libavformat/m4vdec.c
diff --git a/ffmpeg-2-8-11/libavformat/matroska.c b/ffmpeg-2-8-12/libavformat/matroska.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/matroska.c
rename to ffmpeg-2-8-12/libavformat/matroska.c
diff --git a/ffmpeg-2-8-11/libavformat/matroska.h b/ffmpeg-2-8-12/libavformat/matroska.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/matroska.h
rename to ffmpeg-2-8-12/libavformat/matroska.h
diff --git a/ffmpeg-2-8-11/libavformat/matroskadec.c b/ffmpeg-2-8-12/libavformat/matroskadec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/matroskadec.c
rename to ffmpeg-2-8-12/libavformat/matroskadec.c
diff --git a/ffmpeg-2-8-11/libavformat/matroskaenc.c b/ffmpeg-2-8-12/libavformat/matroskaenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/matroskaenc.c
rename to ffmpeg-2-8-12/libavformat/matroskaenc.c
diff --git a/ffmpeg-2-8-11/libavformat/md5enc.c b/ffmpeg-2-8-12/libavformat/md5enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/md5enc.c
rename to ffmpeg-2-8-12/libavformat/md5enc.c
diff --git a/ffmpeg-2-8-11/libavformat/md5proto.c b/ffmpeg-2-8-12/libavformat/md5proto.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/md5proto.c
rename to ffmpeg-2-8-12/libavformat/md5proto.c
diff --git a/ffmpeg-2-8-11/libavformat/metadata.c b/ffmpeg-2-8-12/libavformat/metadata.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/metadata.c
rename to ffmpeg-2-8-12/libavformat/metadata.c
diff --git a/ffmpeg-2-8-11/libavformat/metadata.h b/ffmpeg-2-8-12/libavformat/metadata.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/metadata.h
rename to ffmpeg-2-8-12/libavformat/metadata.h
diff --git a/ffmpeg-2-8-11/libavformat/mgsts.c b/ffmpeg-2-8-12/libavformat/mgsts.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mgsts.c
rename to ffmpeg-2-8-12/libavformat/mgsts.c
diff --git a/ffmpeg-2-8-11/libavformat/microdvddec.c b/ffmpeg-2-8-12/libavformat/microdvddec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/microdvddec.c
rename to ffmpeg-2-8-12/libavformat/microdvddec.c
diff --git a/ffmpeg-2-8-11/libavformat/microdvdenc.c b/ffmpeg-2-8-12/libavformat/microdvdenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/microdvdenc.c
rename to ffmpeg-2-8-12/libavformat/microdvdenc.c
diff --git a/ffmpeg-2-8-11/libavformat/mkvtimestamp_v2.c b/ffmpeg-2-8-12/libavformat/mkvtimestamp_v2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mkvtimestamp_v2.c
rename to ffmpeg-2-8-12/libavformat/mkvtimestamp_v2.c
diff --git a/ffmpeg-2-8-11/libavformat/mlvdec.c b/ffmpeg-2-8-12/libavformat/mlvdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mlvdec.c
rename to ffmpeg-2-8-12/libavformat/mlvdec.c
diff --git a/ffmpeg-2-8-11/libavformat/mm.c b/ffmpeg-2-8-12/libavformat/mm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mm.c
rename to ffmpeg-2-8-12/libavformat/mm.c
diff --git a/ffmpeg-2-8-11/libavformat/mmf.c b/ffmpeg-2-8-12/libavformat/mmf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mmf.c
rename to ffmpeg-2-8-12/libavformat/mmf.c
diff --git a/ffmpeg-2-8-11/libavformat/mms.c b/ffmpeg-2-8-12/libavformat/mms.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mms.c
rename to ffmpeg-2-8-12/libavformat/mms.c
diff --git a/ffmpeg-2-8-11/libavformat/mms.h b/ffmpeg-2-8-12/libavformat/mms.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mms.h
rename to ffmpeg-2-8-12/libavformat/mms.h
diff --git a/ffmpeg-2-8-11/libavformat/mmsh.c b/ffmpeg-2-8-12/libavformat/mmsh.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mmsh.c
rename to ffmpeg-2-8-12/libavformat/mmsh.c
diff --git a/ffmpeg-2-8-11/libavformat/mmst.c b/ffmpeg-2-8-12/libavformat/mmst.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mmst.c
rename to ffmpeg-2-8-12/libavformat/mmst.c
diff --git a/ffmpeg-2-8-11/libavformat/mov.c b/ffmpeg-2-8-12/libavformat/mov.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mov.c
rename to ffmpeg-2-8-12/libavformat/mov.c
diff --git a/ffmpeg-2-8-11/libavformat/mov_chan.c b/ffmpeg-2-8-12/libavformat/mov_chan.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mov_chan.c
rename to ffmpeg-2-8-12/libavformat/mov_chan.c
diff --git a/ffmpeg-2-8-11/libavformat/mov_chan.h b/ffmpeg-2-8-12/libavformat/mov_chan.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mov_chan.h
rename to ffmpeg-2-8-12/libavformat/mov_chan.h
diff --git a/ffmpeg-2-8-11/libavformat/movenc.c b/ffmpeg-2-8-12/libavformat/movenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/movenc.c
rename to ffmpeg-2-8-12/libavformat/movenc.c
diff --git a/ffmpeg-2-8-11/libavformat/movenc.h b/ffmpeg-2-8-12/libavformat/movenc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/movenc.h
rename to ffmpeg-2-8-12/libavformat/movenc.h
diff --git a/ffmpeg-2-8-11/libavformat/movenchint.c b/ffmpeg-2-8-12/libavformat/movenchint.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/movenchint.c
rename to ffmpeg-2-8-12/libavformat/movenchint.c
diff --git a/ffmpeg-2-8-11/libavformat/mp3dec.c b/ffmpeg-2-8-12/libavformat/mp3dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mp3dec.c
rename to ffmpeg-2-8-12/libavformat/mp3dec.c
diff --git a/ffmpeg-2-8-11/libavformat/mp3enc.c b/ffmpeg-2-8-12/libavformat/mp3enc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mp3enc.c
rename to ffmpeg-2-8-12/libavformat/mp3enc.c
diff --git a/ffmpeg-2-8-11/libavformat/mpc.c b/ffmpeg-2-8-12/libavformat/mpc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mpc.c
rename to ffmpeg-2-8-12/libavformat/mpc.c
diff --git a/ffmpeg-2-8-11/libavformat/mpc8.c b/ffmpeg-2-8-12/libavformat/mpc8.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mpc8.c
rename to ffmpeg-2-8-12/libavformat/mpc8.c
diff --git a/ffmpeg-2-8-12/libavformat/mpeg.c b/ffmpeg-2-8-12/libavformat/mpeg.c
new file mode 100644
index 0000000..fe02af8
--- /dev/null
+++ b/ffmpeg-2-8-12/libavformat/mpeg.c
@@ -0,0 +1,1037 @@
+/*
+ * MPEG1/2 demuxer
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avformat.h"
+#include "internal.h"
+#include "mpeg.h"
+
+#if CONFIG_VOBSUB_DEMUXER
+# include "subtitles.h"
+# include "libavutil/bprint.h"
+# include "libavutil/opt.h"
+#endif
+
+#include "libavutil/avassert.h"
+
+/*********************************************/
+/* demux code */
+
+#define MAX_SYNC_SIZE 100000
+
+static int check_pes(const uint8_t *p, const uint8_t *end)
+{
+ int pes1;
+ int pes2 = (p[3] & 0xC0) == 0x80 &&
+ (p[4] & 0xC0) != 0x40 &&
+ ((p[4] & 0xC0) == 0x00 ||
+ (p[4] & 0xC0) >> 2 == (p[6] & 0xF0));
+
+ for (p += 3; p < end && *p == 0xFF; p++) ;
+ if ((*p & 0xC0) == 0x40)
+ p += 2;
+
+ if ((*p & 0xF0) == 0x20)
+ pes1 = p[0] & p[2] & p[4] & 1;
+ else if ((*p & 0xF0) == 0x30)
+ pes1 = p[0] & p[2] & p[4] & p[5] & p[7] & p[9] & 1;
+ else
+ pes1 = *p == 0x0F;
+
+ return pes1 || pes2;
+}
+
+static int check_pack_header(const uint8_t *buf)
+{
+ return (buf[1] & 0xC0) == 0x40 || (buf[1] & 0xF0) == 0x20;
+}
+
+static int mpegps_probe(AVProbeData *p)
+{
+ uint32_t code = -1;
+ int i;
+ int sys = 0, pspack = 0, priv1 = 0, vid = 0;
+ int audio = 0, invalid = 0, score = 0;
+ int endpes = 0;
+
+ for (i = 0; i < p->buf_size; i++) {
+ code = (code << 8) + p->buf[i];
+ if ((code & 0xffffff00) == 0x100) {
+ int len = p->buf[i + 1] << 8 | p->buf[i + 2];
+ int pes = endpes <= i && check_pes(p->buf + i, p->buf + p->buf_size);
+ int pack = check_pack_header(p->buf + i);
+
+ if (code == SYSTEM_HEADER_START_CODE)
+ sys++;
+ else if (code == PACK_START_CODE && pack)
+ pspack++;
+ else if ((code & 0xf0) == VIDEO_ID && pes) {
+ endpes = i + len;
+ vid++;
+ }
+ // skip pes payload to avoid start code emulation for private
+ // and audio streams
+ else if ((code & 0xe0) == AUDIO_ID && pes) {audio++; i+=len;}
+ else if (code == PRIVATE_STREAM_1 && pes) {priv1++; i+=len;}
+ else if (code == 0x1fd && pes) vid++; //VC1
+
+ else if ((code & 0xf0) == VIDEO_ID && !pes) invalid++;
+ else if ((code & 0xe0) == AUDIO_ID && !pes) invalid++;
+ else if (code == PRIVATE_STREAM_1 && !pes) invalid++;
+ }
+ }
+
+ if (vid + audio > invalid + 1) /* invalid VDR files nd short PES streams */
+ score = AVPROBE_SCORE_EXTENSION / 2;
+
+// av_log(NULL, AV_LOG_ERROR, "vid:%d aud:%d sys:%d pspack:%d invalid:%d size:%d \n",
+// vid, audio, sys, pspack, invalid, p->buf_size);
+
+ if (sys > invalid && sys * 9 <= pspack * 10)
+ return (audio > 12 || vid > 3 || pspack > 2) ? AVPROBE_SCORE_EXTENSION + 2
+ : AVPROBE_SCORE_EXTENSION / 2 + 1; // 1 more than mp3
+ if (pspack > invalid && (priv1 + vid + audio) * 10 >= pspack * 9)
+ return pspack > 2 ? AVPROBE_SCORE_EXTENSION + 2
+ : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg
+ if ((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys &&
+ !pspack && p->buf_size > 2048 && vid + audio > invalid) /* PES stream */
+ return (audio > 12 || vid > 6 + 2 * invalid) ? AVPROBE_SCORE_EXTENSION + 2
+ : AVPROBE_SCORE_EXTENSION / 2;
+
+ // 02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1
+ // mp3_misidentified_2.mp3 has sys:0 priv1:0 pspack:0 vid:0 audio:6
+ // Have\ Yourself\ a\ Merry\ Little\ Christmas.mp3 0 0 0 5 0 1 len:21618
+ return score;
+}
+
+typedef struct MpegDemuxContext {
+ AVClass *class;
+ int32_t header_state;
+ unsigned char psm_es_type[256];
+ int sofdec;
+ int dvd;
+ int imkh_cctv;
+#if CONFIG_VOBSUB_DEMUXER
+ AVFormatContext *sub_ctx;
+ FFDemuxSubtitlesQueue q[32];
+ char *sub_name;
+#endif
+} MpegDemuxContext;
+
+static int mpegps_read_header(AVFormatContext *s)
+{
+ MpegDemuxContext *m = s->priv_data;
+ char buffer[7] = { 0 };
+ int64_t last_pos = avio_tell(s->pb);
+
+ m->header_state = 0xff;
+ s->ctx_flags |= AVFMTCTX_NOHEADER;
+
+ avio_get_str(s->pb, 6, buffer, sizeof(buffer));
+ if (!memcmp("IMKH", buffer, 4)) {
+ m->imkh_cctv = 1;
+ } else if (!memcmp("Sofdec", buffer, 6)) {
+ m->sofdec = 1;
+ } else
+ avio_seek(s->pb, last_pos, SEEK_SET);
+
+ /* no need to do more */
+ return 0;
+}
+
+static int64_t get_pts(AVIOContext *pb, int c)
+{
+ uint8_t buf[5];
+
+ buf[0] = c < 0 ? avio_r8(pb) : c;
+ avio_read(pb, buf + 1, 4);
+
+ return ff_parse_pes_pts(buf);
+}
+
+static int find_next_start_code(AVIOContext *pb, int *size_ptr,
+ int32_t *header_state)
+{
+ unsigned int state, v;
+ int val, n;
+
+ state = *header_state;
+ n = *size_ptr;
+ while (n > 0) {
+ if (avio_feof(pb))
+ break;
+ v = avio_r8(pb);
+ n--;
+ if (state == 0x000001) {
+ state = ((state << 8) | v) & 0xffffff;
+ val = state;
+ goto found;
+ }
+ state = ((state << 8) | v) & 0xffffff;
+ }
+ val = -1;
+
+found:
+ *header_state = state;
+ *size_ptr = n;
+ return val;
+}
+
+/**
+ * Extract stream types from a program stream map
+ * According to ISO/IEC 13818-1 ('MPEG-2 Systems') table 2-35
+ *
+ * @return number of bytes occupied by PSM in the bitstream
+ */
+static long mpegps_psm_parse(MpegDemuxContext *m, AVIOContext *pb)
+{
+ int psm_length, ps_info_length, es_map_length;
+
+ psm_length = avio_rb16(pb);
+ avio_r8(pb);
+ avio_r8(pb);
+ ps_info_length = avio_rb16(pb);
+
+ /* skip program_stream_info */
+ avio_skip(pb, ps_info_length);
+ /*es_map_length = */avio_rb16(pb);
+ /* Ignore es_map_length, trust psm_length */
+ es_map_length = psm_length - ps_info_length - 10;
+
+ /* at least one es available? */
+ while (es_map_length >= 4) {
+ unsigned char type = avio_r8(pb);
+ unsigned char es_id = avio_r8(pb);
+ uint16_t es_info_length = avio_rb16(pb);
+
+ /* remember mapping from stream id to stream type */
+ m->psm_es_type[es_id] = type;
+ /* skip program_stream_info */
+ avio_skip(pb, es_info_length);
+ es_map_length -= 4 + es_info_length;
+ }
+ avio_rb32(pb); /* crc32 */
+ return 2 + psm_length;
+}
+
+/* read the next PES header. Return its position in ppos
+ * (if not NULL), and its start code, pts and dts.
+ */
+static int mpegps_read_pes_header(AVFormatContext *s,
+ int64_t *ppos, int *pstart_code,
+ int64_t *ppts, int64_t *pdts)
+{
+ MpegDemuxContext *m = s->priv_data;
+ int len, size, startcode, c, flags, header_len;
+ int pes_ext, ext2_len, id_ext, skip;
+ int64_t pts, dts;
+ int64_t last_sync = avio_tell(s->pb);
+
+error_redo:
+ avio_seek(s->pb, last_sync, SEEK_SET);
+redo:
+ /* next start code (should be immediately after) */
+ m->header_state = 0xff;
+ size = MAX_SYNC_SIZE;
+ startcode = find_next_start_code(s->pb, &size, &m->header_state);
+ last_sync = avio_tell(s->pb);
+ if (startcode < 0) {
+ if (avio_feof(s->pb))
+ return AVERROR_EOF;
+ // FIXME we should remember header_state
+ return AVERROR(EAGAIN);
+ }
+
+ if (startcode == PACK_START_CODE)
+ goto redo;
+ if (startcode == SYSTEM_HEADER_START_CODE)
+ goto redo;
+ if (startcode == PADDING_STREAM) {
+ avio_skip(s->pb, avio_rb16(s->pb));
+ goto redo;
+ }
+ if (startcode == PRIVATE_STREAM_2) {
+ if (!m->sofdec) {
+ /* Need to detect whether this from a DVD or a 'Sofdec' stream */
+ int len = avio_rb16(s->pb);
+ int bytesread = 0;
+ uint8_t *ps2buf = av_malloc(len);
+
+ if (ps2buf) {
+ bytesread = avio_read(s->pb, ps2buf, len);
+
+ if (bytesread != len) {
+ avio_skip(s->pb, len - bytesread);
+ } else {
+ uint8_t *p = 0;
+ if (len >= 6)
+ p = memchr(ps2buf, 'S', len - 5);
+
+ if (p)
+ m->sofdec = !memcmp(p+1, "ofdec", 5);
+
+ m->sofdec -= !m->sofdec;
+
+ if (m->sofdec < 0) {
+ if (len == 980 && ps2buf[0] == 0) {
+ /* PCI structure? */
+ uint32_t startpts = AV_RB32(ps2buf + 0x0d);
+ uint32_t endpts = AV_RB32(ps2buf + 0x11);
+ uint8_t hours = ((ps2buf[0x19] >> 4) * 10) + (ps2buf[0x19] & 0x0f);
+ uint8_t mins = ((ps2buf[0x1a] >> 4) * 10) + (ps2buf[0x1a] & 0x0f);
+ uint8_t secs = ((ps2buf[0x1b] >> 4) * 10) + (ps2buf[0x1b] & 0x0f);
+
+ m->dvd = (hours <= 23 &&
+ mins <= 59 &&
+ secs <= 59 &&
+ (ps2buf[0x19] & 0x0f) < 10 &&
+ (ps2buf[0x1a] & 0x0f) < 10 &&
+ (ps2buf[0x1b] & 0x0f) < 10 &&
+ endpts >= startpts);
+ } else if (len == 1018 && ps2buf[0] == 1) {
+ /* DSI structure? */
+ uint8_t hours = ((ps2buf[0x1d] >> 4) * 10) + (ps2buf[0x1d] & 0x0f);
+ uint8_t mins = ((ps2buf[0x1e] >> 4) * 10) + (ps2buf[0x1e] & 0x0f);
+ uint8_t secs = ((ps2buf[0x1f] >> 4) * 10) + (ps2buf[0x1f] & 0x0f);
+
+ m->dvd = (hours <= 23 &&
+ mins <= 59 &&
+ secs <= 59 &&
+ (ps2buf[0x1d] & 0x0f) < 10 &&
+ (ps2buf[0x1e] & 0x0f) < 10 &&
+ (ps2buf[0x1f] & 0x0f) < 10);
+ }
+ }
+ }
+
+ av_free(ps2buf);
+
+ /* If this isn't a DVD packet or no memory
+ * could be allocated, just ignore it.
+ * If we did, move back to the start of the
+ * packet (plus 'length' field) */
+ if (!m->dvd || avio_skip(s->pb, -(len + 2)) < 0) {
+ /* Skip back failed.
+ * This packet will be lost but that can't be helped
+ * if we can't skip back
+ */
+ goto redo;
+ }
+ } else {
+ /* No memory */
+ avio_skip(s->pb, len);
+ goto redo;
+ }
+ } else if (!m->dvd) {
+ int len = avio_rb16(s->pb);
+ avio_skip(s->pb, len);
+ goto redo;
+ }
+ }
+ if (startcode == PROGRAM_STREAM_MAP) {
+ mpegps_psm_parse(m, s->pb);
+ goto redo;
+ }
+
+ /* find matching stream */
+ if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
+ (startcode >= 0x1e0 && startcode <= 0x1ef) ||
+ (startcode == 0x1bd) ||
+ (startcode == PRIVATE_STREAM_2) ||
+ (startcode == 0x1fd)))
+ goto redo;
+ if (ppos) {
+ *ppos = avio_tell(s->pb) - 4;
+ }
+ len = avio_rb16(s->pb);
+ pts =
+ dts = AV_NOPTS_VALUE;
+ if (startcode != PRIVATE_STREAM_2)
+ {
+ /* stuffing */
+ for (;;) {
+ if (len < 1)
+ goto error_redo;
+ c = avio_r8(s->pb);
+ len--;
+ /* XXX: for mpeg1, should test only bit 7 */
+ if (c != 0xff)
+ break;
+ }
+ if ((c & 0xc0) == 0x40) {
+ /* buffer scale & size */
+ avio_r8(s->pb);
+ c = avio_r8(s->pb);
+ len -= 2;
+ }
+ if ((c & 0xe0) == 0x20) {
+ dts =
+ pts = get_pts(s->pb, c);
+ len -= 4;
+ if (c & 0x10) {
+ dts = get_pts(s->pb, -1);
+ len -= 5;
+ }
+ } else if ((c & 0xc0) == 0x80) {
+ /* mpeg 2 PES */
+ flags = avio_r8(s->pb);
+ header_len = avio_r8(s->pb);
+ len -= 2;
+ if (header_len > len)
+ goto error_redo;
+ len -= header_len;
+ if (flags & 0x80) {
+ dts = pts = get_pts(s->pb, -1);
+ header_len -= 5;
+ if (flags & 0x40) {
+ dts = get_pts(s->pb, -1);
+ header_len -= 5;
+ }
+ }
+ if (flags & 0x3f && header_len == 0) {
+ flags &= 0xC0;
+ av_log(s, AV_LOG_WARNING, "Further flags set but no bytes left\n");
+ }
+ if (flags & 0x01) { /* PES extension */
+ pes_ext = avio_r8(s->pb);
+ header_len--;
+ /* Skip PES private data, program packet sequence counter
+ * and P-STD buffer */
+ skip = (pes_ext >> 4) & 0xb;
+ skip += skip & 0x9;
+ if (pes_ext & 0x40 || skip > header_len) {
+ av_log(s, AV_LOG_WARNING, "pes_ext %X is invalid\n", pes_ext);
+ pes_ext = skip = 0;
+ }
+ avio_skip(s->pb, skip);
+ header_len -= skip;
+
+ if (pes_ext & 0x01) { /* PES extension 2 */
+ ext2_len = avio_r8(s->pb);
+ header_len--;
+ if ((ext2_len & 0x7f) > 0) {
+ id_ext = avio_r8(s->pb);
+ if ((id_ext & 0x80) == 0)
+ startcode = ((startcode & 0xff) << 8) | id_ext;
+ header_len--;
+ }
+ }
+ }
+ if (header_len < 0)
+ goto error_redo;
+ avio_skip(s->pb, header_len);
+ } else if (c != 0xf)
+ goto redo;
+ }
+
+ if (startcode == PRIVATE_STREAM_1) {
+ startcode = avio_r8(s->pb);
+ len--;
+ }
+ if (len < 0)
+ goto error_redo;
+ if (dts != AV_NOPTS_VALUE && ppos) {
+ int i;
+ for (i = 0; i < s->nb_streams; i++) {
+ if (startcode == s->streams[i]->id &&
+ s->pb->seekable /* index useless on streams anyway */) {
+ ff_reduce_index(s, i);
+ av_add_index_entry(s->streams[i], *ppos, dts, 0, 0,
+ AVINDEX_KEYFRAME /* FIXME keyframe? */);
+ }
+ }
+ }
+
+ *pstart_code = startcode;
+ *ppts = pts;
+ *pdts = dts;
+ return len;
+}
+
+static int mpegps_read_packet(AVFormatContext *s,
+ AVPacket *pkt)
+{
+ MpegDemuxContext *m = s->priv_data;
+ AVStream *st;
+ int len, startcode, i, es_type, ret;
+ int lpcm_header_len = -1; //Init to suppress warning
+ int request_probe= 0;
+ enum AVCodecID codec_id = AV_CODEC_ID_NONE;
+ enum AVMediaType type;
+ int64_t pts, dts, dummy_pos; // dummy_pos is needed for the index building to work
+
+redo:
+ len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts);
+ if (len < 0)
+ return len;
+
+ if (startcode >= 0x80 && startcode <= 0xcf) {
+ if (len < 4)
+ goto skip;
+
+ /* audio: skip header */
+ avio_r8(s->pb);
+ lpcm_header_len = avio_rb16(s->pb);
+ len -= 3;
+ if (startcode >= 0xb0 && startcode <= 0xbf) {
+ /* MLP/TrueHD audio has a 4-byte header */
+ avio_r8(s->pb);
+ len--;
+ }
+ }
+
+ /* now find stream */
+ for (i = 0; i < s->nb_streams; i++) {
+ st = s->streams[i];
+ if (st->id == startcode)
+ goto found;
+ }
+
+ es_type = m->psm_es_type[startcode & 0xff];
+ if (es_type == STREAM_TYPE_VIDEO_MPEG1) {
+ codec_id = AV_CODEC_ID_MPEG2VIDEO;
+ type = AVMEDIA_TYPE_VIDEO;
+ } else if (es_type == STREAM_TYPE_VIDEO_MPEG2) {
+ codec_id = AV_CODEC_ID_MPEG2VIDEO;
+ type = AVMEDIA_TYPE_VIDEO;
+ } else if (es_type == STREAM_TYPE_AUDIO_MPEG1 ||
+ es_type == STREAM_TYPE_AUDIO_MPEG2) {
+ codec_id = AV_CODEC_ID_MP3;
+ type = AVMEDIA_TYPE_AUDIO;
+ } else if (es_type == STREAM_TYPE_AUDIO_AAC) {
+ codec_id = AV_CODEC_ID_AAC;
+ type = AVMEDIA_TYPE_AUDIO;
+ } else if (es_type == STREAM_TYPE_VIDEO_MPEG4) {
+ codec_id = AV_CODEC_ID_MPEG4;
+ type = AVMEDIA_TYPE_VIDEO;
+ } else if (es_type == STREAM_TYPE_VIDEO_H264) {
+ codec_id = AV_CODEC_ID_H264;
+ type = AVMEDIA_TYPE_VIDEO;
+ } else if (es_type == STREAM_TYPE_AUDIO_AC3) {
+ codec_id = AV_CODEC_ID_AC3;
+ type = AVMEDIA_TYPE_AUDIO;
+ } else if (m->imkh_cctv && es_type == 0x91) {
+ codec_id = AV_CODEC_ID_PCM_MULAW;
+ type = AVMEDIA_TYPE_AUDIO;
+ } else if (startcode >= 0x1e0 && startcode <= 0x1ef) {
+ static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 };
+ unsigned char buf[8];
+
+ avio_read(s->pb, buf, 8);
+ avio_seek(s->pb, -8, SEEK_CUR);
+ if (!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1))
+ codec_id = AV_CODEC_ID_CAVS;
+ else
+ request_probe= 1;
+ type = AVMEDIA_TYPE_VIDEO;
+ } else if (startcode == PRIVATE_STREAM_2) {
+ type = AVMEDIA_TYPE_DATA;
+ codec_id = AV_CODEC_ID_DVD_NAV;
+ } else if (startcode >= 0x1c0 && startcode <= 0x1df) {
+ type = AVMEDIA_TYPE_AUDIO;
+ if (m->sofdec > 0) {
+ codec_id = AV_CODEC_ID_ADPCM_ADX;
+ // Auto-detect AC-3
+ request_probe = 50;
+ } else if (m->imkh_cctv && startcode == 0x1c0 && len > 80) {
+ codec_id = AV_CODEC_ID_PCM_ALAW;
+ request_probe = 50;
+ } else {
+ codec_id = AV_CODEC_ID_MP2;
+ if (m->imkh_cctv)
+ request_probe = 25;
+ }
+ } else if (startcode >= 0x80 && startcode <= 0x87) {
+ type = AVMEDIA_TYPE_AUDIO;
+ codec_id = AV_CODEC_ID_AC3;
+ } else if ((startcode >= 0x88 && startcode <= 0x8f) ||
+ (startcode >= 0x98 && startcode <= 0x9f)) {
+ /* 0x90 - 0x97 is reserved for SDDS in DVD specs */
+ type = AVMEDIA_TYPE_AUDIO;
+ codec_id = AV_CODEC_ID_DTS;
+ } else if (startcode >= 0xa0 && startcode <= 0xaf) {
+ type = AVMEDIA_TYPE_AUDIO;
+ if (lpcm_header_len == 6) {
+ codec_id = AV_CODEC_ID_MLP;
+ } else {
+ codec_id = AV_CODEC_ID_PCM_DVD;
+ }
+ } else if (startcode >= 0xb0 && startcode <= 0xbf) {
+ type = AVMEDIA_TYPE_AUDIO;
+ codec_id = AV_CODEC_ID_TRUEHD;
+ } else if (startcode >= 0xc0 && startcode <= 0xcf) {
+ /* Used for both AC-3 and E-AC-3 in EVOB files */
+ type = AVMEDIA_TYPE_AUDIO;
+ codec_id = AV_CODEC_ID_AC3;
+ } else if (startcode >= 0x20 && startcode <= 0x3f) {
+ type = AVMEDIA_TYPE_SUBTITLE;
+ codec_id = AV_CODEC_ID_DVD_SUBTITLE;
+ } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) {
+ type = AVMEDIA_TYPE_VIDEO;
+ codec_id = AV_CODEC_ID_VC1;
+ } else {
+skip:
+ /* skip packet */
+ avio_skip(s->pb, len);
+ goto redo;
+ }
+ /* no stream found: add a new stream */
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ goto skip;
+ st->id = startcode;
+ st->codec->codec_type = type;
+ st->codec->codec_id = codec_id;
+ if ( st->codec->codec_id == AV_CODEC_ID_PCM_MULAW
+ || st->codec->codec_id == AV_CODEC_ID_PCM_ALAW) {
+ st->codec->channels = 1;
+ st->codec->channel_layout = AV_CH_LAYOUT_MONO;
+ st->codec->sample_rate = 8000;
+ }
+ st->request_probe = request_probe;
+ st->need_parsing = AVSTREAM_PARSE_FULL;
+
+found:
+ if (st->discard >= AVDISCARD_ALL)
+ goto skip;
+ if (startcode >= 0xa0 && startcode <= 0xaf) {
+ if (st->codec->codec_id == AV_CODEC_ID_MLP) {
+ if (len < 6)
+ goto skip;
+ avio_skip(s->pb, 6);
+ len -=6;
+ }
+ }
+ ret = av_get_packet(s->pb, pkt, len);
+
+ pkt->pts = pts;
+ pkt->dts = dts;
+ pkt->pos = dummy_pos;
+ pkt->stream_index = st->index;
+
+ if (s->debug & FF_FDEBUG_TS)
+ av_log(s, AV_LOG_TRACE, "%d: pts=%0.3f dts=%0.3f size=%d\n",
+ pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0,
+ pkt->size);
+
+ return (ret < 0) ? ret : 0;
+}
+
+static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index,
+ int64_t *ppos, int64_t pos_limit)
+{
+ int len, startcode;
+ int64_t pos, pts, dts;
+
+ pos = *ppos;
+ if (avio_seek(s->pb, pos, SEEK_SET) < 0)
+ return AV_NOPTS_VALUE;
+
+ for (;;) {
+ len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts);
+ if (len < 0) {
+ if (s->debug & FF_FDEBUG_TS)
+ av_log(s, AV_LOG_TRACE, "none (ret=%d)\n", len);
+ return AV_NOPTS_VALUE;
+ }
+ if (startcode == s->streams[stream_index]->id &&
+ dts != AV_NOPTS_VALUE) {
+ break;
+ }
+ avio_skip(s->pb, len);
+ }
+ if (s->debug & FF_FDEBUG_TS)
+ av_log(s, AV_LOG_TRACE, "pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n",
+ pos, dts, dts / 90000.0);
+ *ppos = pos;
+ return dts;
+}
+
+AVInputFormat ff_mpegps_demuxer = {
+ .name = "mpeg",
+ .long_name = NULL_IF_CONFIG_SMALL("MPEG-PS (MPEG-2 Program Stream)"),
+ .priv_data_size = sizeof(MpegDemuxContext),
+ .read_probe = mpegps_probe,
+ .read_header = mpegps_read_header,
+ .read_packet = mpegps_read_packet,
+ .read_timestamp = mpegps_read_dts,
+ .flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT,
+};
+
+#if CONFIG_VOBSUB_DEMUXER
+
+#define REF_STRING "# VobSub index file,"
+#define MAX_LINE_SIZE 2048
+
+static int vobsub_probe(AVProbeData *p)
+{
+ if (!strncmp(p->buf, REF_STRING, sizeof(REF_STRING) - 1))
+ return AVPROBE_SCORE_MAX;
+ return 0;
+}
+
+static int vobsub_read_header(AVFormatContext *s)
+{
+ int i, ret = 0, header_parsed = 0, langidx = 0;
+ MpegDemuxContext *vobsub = s->priv_data;
+ size_t fname_len;
+ char *header_str;
+ AVBPrint header;
+ int64_t delay = 0;
+ AVStream *st = NULL;
+ int stream_id = -1;
+ char id[64] = {0};
+ char alt[MAX_LINE_SIZE] = {0};
+ AVInputFormat *iformat;
+
+ if (!vobsub->sub_name) {
+ char *ext;
+ vobsub->sub_name = av_strdup(s->filename);
+ if (!vobsub->sub_name) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+
+ fname_len = strlen(vobsub->sub_name);
+ ext = vobsub->sub_name - 3 + fname_len;
+ if (fname_len < 4 || *(ext - 1) != '.') {
+ av_log(s, AV_LOG_ERROR, "The input index filename is too short "
+ "to guess the associated .SUB file\n");
+ ret = AVERROR_INVALIDDATA;
+ goto end;
+ }
+ memcpy(ext, !strncmp(ext, "IDX", 3) ? "SUB" : "sub", 3);
+ av_log(s, AV_LOG_VERBOSE, "IDX/SUB: %s -> %s\n", s->filename, vobsub->sub_name);
+ }
+
+ if (!(iformat = av_find_input_format("mpeg"))) {
+ ret = AVERROR_DEMUXER_NOT_FOUND;
+ goto end;
+ }
+
+ vobsub->sub_ctx = avformat_alloc_context();
+ if (!vobsub->sub_ctx) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+
+ if ((ret = ff_copy_whitelists(vobsub->sub_ctx, s)) < 0)
+ goto end;
+
+ ret = avformat_open_input(&vobsub->sub_ctx, vobsub->sub_name, iformat, NULL);
+ if (ret < 0) {
+ av_log(s, AV_LOG_ERROR, "Unable to open %s as MPEG subtitles\n", vobsub->sub_name);
+ goto end;
+ }
+
+ av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED);
+ while (!avio_feof(s->pb)) {
+ char line[MAX_LINE_SIZE];
+ int len = ff_get_line(s->pb, line, sizeof(line));
+
+ if (!len)
+ break;
+
+ line[strcspn(line, "\r\n")] = 0;
+
+ if (!strncmp(line, "id:", 3)) {
+ if (sscanf(line, "id: %63[^,], index: %u", id, &stream_id) != 2) {
+ av_log(s, AV_LOG_WARNING, "Unable to parse index line '%s', "
+ "assuming 'id: und, index: 0'\n", line);
+ strcpy(id, "und");
+ stream_id = 0;
+ }
+
+ if (stream_id >= FF_ARRAY_ELEMS(vobsub->q)) {
+ av_log(s, AV_LOG_ERROR, "Maximum number of subtitles streams reached\n");
+ ret = AVERROR(EINVAL);
+ goto end;
+ }
+
+ header_parsed = 1;
+ alt[0] = '\0';
+ /* We do not create the stream immediately to avoid adding empty
+ * streams. See the following timestamp entry. */
+
+ av_log(s, AV_LOG_DEBUG, "IDX stream[%d] id=%s\n", stream_id, id);
+
+ } else if (!strncmp(line, "timestamp:", 10)) {
+ AVPacket *sub;
+ int hh, mm, ss, ms;
+ int64_t pos, timestamp;
+ const char *p = line + 10;
+
+ if (stream_id == -1) {
+ av_log(s, AV_LOG_ERROR, "Timestamp declared before any stream\n");
+ ret = AVERROR_INVALIDDATA;
+ goto end;
+ }
+
+ if (!st || st->id != stream_id) {
+ st = avformat_new_stream(s, NULL);
+ if (!st) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+ st->id = stream_id;
+ st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
+ st->codec->codec_id = AV_CODEC_ID_DVD_SUBTITLE;
+ avpriv_set_pts_info(st, 64, 1, 1000);
+ av_dict_set(&st->metadata, "language", id, 0);
+ if (alt[0])
+ av_dict_set(&st->metadata, "title", alt, 0);
+ }
+
+ if (sscanf(p, "%02d:%02d:%02d:%03d, filepos: %"SCNx64,
+ &hh, &mm, &ss, &ms, &pos) != 5) {
+ av_log(s, AV_LOG_ERROR, "Unable to parse timestamp line '%s', "
+ "abort parsing\n", line);
+ ret = AVERROR_INVALIDDATA;
+ goto end;
+ }
+ timestamp = (hh*3600LL + mm*60LL + ss) * 1000LL + ms + delay;
+ timestamp = av_rescale_q(timestamp, av_make_q(1, 1000), st->time_base);
+
+ sub = ff_subtitles_queue_insert(&vobsub->q[s->nb_streams - 1], "", 0, 0);
+ if (!sub) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+ sub->pos = pos;
+ sub->pts = timestamp;
+ sub->stream_index = s->nb_streams - 1;
+
+ } else if (!strncmp(line, "alt:", 4)) {
+ const char *p = line + 4;
+
+ while (*p == ' ')
+ p++;
+ av_log(s, AV_LOG_DEBUG, "IDX stream[%d] name=%s\n", stream_id, p);
+ av_strlcpy(alt, p, sizeof(alt));
+ header_parsed = 1;
+
+ } else if (!strncmp(line, "delay:", 6)) {
+ int sign = 1, hh = 0, mm = 0, ss = 0, ms = 0;
+ const char *p = line + 6;
+
+ while (*p == ' ')
+ p++;
+ if (*p == '-' || *p == '+') {
+ sign = *p == '-' ? -1 : 1;
+ p++;
+ }
+ sscanf(p, "%d:%d:%d:%d", &hh, &mm, &ss, &ms);
+ delay = ((hh*3600LL + mm*60LL + ss) * 1000LL + ms) * sign;
+
+ } else if (!strncmp(line, "langidx:", 8)) {
+ const char *p = line + 8;
+
+ if (sscanf(p, "%d", &langidx) != 1)
+ av_log(s, AV_LOG_ERROR, "Invalid langidx specified\n");
+
+ } else if (!header_parsed) {
+ if (line[0] && line[0] != '#')
+ av_bprintf(&header, "%s\n", line);
+ }
+ }
+
+ if (langidx < s->nb_streams)
+ s->streams[langidx]->disposition |= AV_DISPOSITION_DEFAULT;
+
+ for (i = 0; i < s->nb_streams; i++) {
+ vobsub->q[i].sort = SUB_SORT_POS_TS;
+ ff_subtitles_queue_finalize(&vobsub->q[i]);
+ }
+
+ if (!av_bprint_is_complete(&header)) {
+ av_bprint_finalize(&header, NULL);
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+ av_bprint_finalize(&header, &header_str);
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *sub_st = s->streams[i];
+ sub_st->codec->extradata = av_strdup(header_str);
+ sub_st->codec->extradata_size = header.len;
+ }
+ av_free(header_str);
+
+end:
+ return ret;
+}
+
+static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ MpegDemuxContext *vobsub = s->priv_data;
+ FFDemuxSubtitlesQueue *q;
+ AVIOContext *pb = vobsub->sub_ctx->pb;
+ int ret, psize, total_read = 0, i;
+ AVPacket idx_pkt;
+
+ int64_t min_ts = INT64_MAX;
+ int sid = 0;
+ for (i = 0; i < s->nb_streams; i++) {
+ FFDemuxSubtitlesQueue *tmpq = &vobsub->q[i];
+ int64_t ts;
+ av_assert0(tmpq->nb_subs);
+ ts = tmpq->subs[tmpq->current_sub_idx].pts;
+ if (ts < min_ts) {
+ min_ts = ts;
+ sid = i;
+ }
+ }
+ q = &vobsub->q[sid];
+ ret = ff_subtitles_queue_read_packet(q, &idx_pkt);
+ if (ret < 0)
+ return ret;
+
+ /* 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 - idx_pkt.pos;
+ } else {
+ int64_t fsize = avio_size(pb);
+ psize = fsize < 0 ? 0xffff : fsize - idx_pkt.pos;
+ }
+
+ avio_seek(pb, idx_pkt.pos, SEEK_SET);
+
+ av_init_packet(pkt);
+ pkt->size = 0;
+ pkt->data = NULL;
+
+ do {
+ int n, to_read, startcode;
+ int64_t pts, dts;
+ int64_t old_pos = avio_tell(pb), new_pos;
+ int pkt_size;
+
+ ret = mpegps_read_pes_header(vobsub->sub_ctx, NULL, &startcode, &pts, &dts);
+ if (ret < 0) {
+ if (pkt->size) // raise packet even if incomplete
+ break;
+ goto fail;
+ }
+ to_read = ret & 0xffff;
+ new_pos = avio_tell(pb);
+ pkt_size = ret + (new_pos - old_pos);
+
+ /* this prevents reads above the current packet */
+ if (total_read + pkt_size > psize)
+ break;
+ total_read += pkt_size;
+
+ /* the current chunk doesn't match the stream index (unlikely) */
+ if ((startcode & 0x1f) != s->streams[idx_pkt.stream_index]->id)
+ break;
+
+ ret = av_grow_packet(pkt, to_read);
+ if (ret < 0)
+ goto fail;
+
+ n = avio_read(pb, pkt->data + (pkt->size - to_read), to_read);
+ if (n < to_read)
+ pkt->size -= to_read - n;
+ } while (total_read < psize);
+
+ pkt->pts = pkt->dts = idx_pkt.pts;
+ pkt->pos = idx_pkt.pos;
+ pkt->stream_index = idx_pkt.stream_index;
+
+ av_free_packet(&idx_pkt);
+ return 0;
+
+fail:
+ av_free_packet(pkt);
+ av_free_packet(&idx_pkt);
+ return ret;
+}
+
+static int vobsub_read_seek(AVFormatContext *s, int stream_index,
+ int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
+{
+ MpegDemuxContext *vobsub = s->priv_data;
+
+ /* Rescale requested timestamps based on the first stream (timebase is the
+ * same for all subtitles stream within a .idx/.sub). Rescaling is done just
+ * like in avformat_seek_file(). */
+ if (stream_index == -1 && s->nb_streams != 1) {
+ int i, ret = 0;
+ AVRational time_base = s->streams[0]->time_base;
+ ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base);
+ min_ts = av_rescale_rnd(min_ts, time_base.den,
+ time_base.num * (int64_t)AV_TIME_BASE,
+ AV_ROUND_UP | AV_ROUND_PASS_MINMAX);
+ max_ts = av_rescale_rnd(max_ts, time_base.den,
+ time_base.num * (int64_t)AV_TIME_BASE,
+ AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
+ for (i = 0; i < s->nb_streams; i++) {
+ int r = ff_subtitles_queue_seek(&vobsub->q[i], s, stream_index,
+ min_ts, ts, max_ts, flags);
+ if (r < 0)
+ ret = r;
+ }
+ return ret;
+ }
+
+ if (stream_index == -1) // only 1 stream
+ stream_index = 0;
+ return ff_subtitles_queue_seek(&vobsub->q[stream_index], s, stream_index,
+ min_ts, ts, max_ts, flags);
+}
+
+static int vobsub_read_close(AVFormatContext *s)
+{
+ int i;
+ MpegDemuxContext *vobsub = s->priv_data;
+
+ for (i = 0; i < s->nb_streams; i++)
+ ff_subtitles_queue_clean(&vobsub->q[i]);
+ if (vobsub->sub_ctx)
+ avformat_close_input(&vobsub->sub_ctx);
+ return 0;
+}
+
+static const AVOption options[] = {
+ { "sub_name", "URI for .sub file", offsetof(MpegDemuxContext, sub_name), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
+ { NULL }
+};
+
+static const AVClass vobsub_demuxer_class = {
+ .class_name = "vobsub",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVInputFormat ff_vobsub_demuxer = {
+ .name = "vobsub",
+ .long_name = NULL_IF_CONFIG_SMALL("VobSub subtitle format"),
+ .priv_data_size = sizeof(MpegDemuxContext),
+ .read_probe = vobsub_probe,
+ .read_header = vobsub_read_header,
+ .read_packet = vobsub_read_packet,
+ .read_seek2 = vobsub_read_seek,
+ .read_close = vobsub_read_close,
+ .flags = AVFMT_SHOW_IDS,
+ .extensions = "idx",
+ .priv_class = &vobsub_demuxer_class,
+};
+#endif
diff --git a/ffmpeg-2-8-11/libavformat/mpeg.h b/ffmpeg-2-8-12/libavformat/mpeg.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mpeg.h
rename to ffmpeg-2-8-12/libavformat/mpeg.h
diff --git a/ffmpeg-2-8-11/libavformat/mpegenc.c b/ffmpeg-2-8-12/libavformat/mpegenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mpegenc.c
rename to ffmpeg-2-8-12/libavformat/mpegenc.c
diff --git a/ffmpeg-2-8-11/libavformat/mpegts.c b/ffmpeg-2-8-12/libavformat/mpegts.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mpegts.c
rename to ffmpeg-2-8-12/libavformat/mpegts.c
diff --git a/ffmpeg-2-8-11/libavformat/mpegts.h b/ffmpeg-2-8-12/libavformat/mpegts.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mpegts.h
rename to ffmpeg-2-8-12/libavformat/mpegts.h
diff --git a/ffmpeg-2-8-11/libavformat/mpegtsenc.c b/ffmpeg-2-8-12/libavformat/mpegtsenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mpegtsenc.c
rename to ffmpeg-2-8-12/libavformat/mpegtsenc.c
diff --git a/ffmpeg-2-8-11/libavformat/mpegvideodec.c b/ffmpeg-2-8-12/libavformat/mpegvideodec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mpegvideodec.c
rename to ffmpeg-2-8-12/libavformat/mpegvideodec.c
diff --git a/ffmpeg-2-8-11/libavformat/mpjpeg.c b/ffmpeg-2-8-12/libavformat/mpjpeg.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mpjpeg.c
rename to ffmpeg-2-8-12/libavformat/mpjpeg.c
diff --git a/ffmpeg-2-8-11/libavformat/mpjpegdec.c b/ffmpeg-2-8-12/libavformat/mpjpegdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mpjpegdec.c
rename to ffmpeg-2-8-12/libavformat/mpjpegdec.c
diff --git a/ffmpeg-2-8-11/libavformat/mpl2dec.c b/ffmpeg-2-8-12/libavformat/mpl2dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mpl2dec.c
rename to ffmpeg-2-8-12/libavformat/mpl2dec.c
diff --git a/ffmpeg-2-8-11/libavformat/mpsubdec.c b/ffmpeg-2-8-12/libavformat/mpsubdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mpsubdec.c
rename to ffmpeg-2-8-12/libavformat/mpsubdec.c
diff --git a/ffmpeg-2-8-11/libavformat/msnwc_tcp.c b/ffmpeg-2-8-12/libavformat/msnwc_tcp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/msnwc_tcp.c
rename to ffmpeg-2-8-12/libavformat/msnwc_tcp.c
diff --git a/ffmpeg-2-8-11/libavformat/mtv.c b/ffmpeg-2-8-12/libavformat/mtv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mtv.c
rename to ffmpeg-2-8-12/libavformat/mtv.c
diff --git a/ffmpeg-2-8-12/libavformat/mux.c b/ffmpeg-2-8-12/libavformat/mux.c
new file mode 100644
index 0000000..df1a91e
--- /dev/null
+++ b/ffmpeg-2-8-12/libavformat/mux.c
@@ -0,0 +1,1121 @@
+/*
+ * muxing functions for use within FFmpeg
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avformat.h"
+#include "avio_internal.h"
+#include "internal.h"
+#include "libavcodec/internal.h"
+#include "libavcodec/bytestream.h"
+#include "libavutil/opt.h"
+#include "libavutil/dict.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/timestamp.h"
+#include "metadata.h"
+#include "id3v2.h"
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/internal.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/time.h"
+#include "riff.h"
+#include "audiointerleave.h"
+#include "url.h"
+#include <stdarg.h>
+#if CONFIG_NETWORK
+#include "network.h"
+#endif
+
+/**
+ * @file
+ * muxing functions for use within libavformat
+ */
+
+/* fraction handling */
+
+/**
+ * f = val + (num / den) + 0.5.
+ *
+ * 'num' is normalized so that it is such as 0 <= num < den.
+ *
+ * @param f fractional number
+ * @param val integer value
+ * @param num must be >= 0
+ * @param den must be >= 1
+ */
+static void frac_init(FFFrac *f, int64_t val, int64_t num, int64_t den)
+{
+ num += (den >> 1);
+ if (num >= den) {
+ val += num / den;
+ num = num % den;
+ }
+ f->val = val;
+ f->num = num;
+ f->den = den;
+}
+
+/**
+ * Fractional addition to f: f = f + (incr / f->den).
+ *
+ * @param f fractional number
+ * @param incr increment, can be positive or negative
+ */
+static void frac_add(FFFrac *f, int64_t incr)
+{
+ int64_t num, den;
+
+ num = f->num + incr;
+ den = f->den;
+ if (num < 0) {
+ f->val += num / den;
+ num = num % den;
+ if (num < 0) {
+ num += den;
+ f->val--;
+ }
+ } else if (num >= den) {
+ f->val += num / den;
+ num = num % den;
+ }
+ f->num = num;
+}
+
+AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precision)
+{
+ AVRational q;
+ int j;
+
+ q = st->time_base;
+
+ for (j=2; j<14; j+= 1+(j>2))
+ while (q.den / q.num < min_precision && q.num % j == 0)
+ q.num /= j;
+ while (q.den / q.num < min_precision && q.den < (1<<24))
+ q.den <<= 1;
+
+ return q;
+}
+
+enum AVChromaLocation ff_choose_chroma_location(AVFormatContext *s, AVStream *st)
+{
+ AVCodecContext *avctx = st->codec;
+ const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+
+ if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED)
+ return avctx->chroma_sample_location;
+
+ if (pix_desc) {
+ if (pix_desc->log2_chroma_h == 0) {
+ return AVCHROMA_LOC_TOPLEFT;
+ } else if (pix_desc->log2_chroma_w == 1 && pix_desc->log2_chroma_h == 1) {
+ if (avctx->field_order == AV_FIELD_UNKNOWN || avctx->field_order == AV_FIELD_PROGRESSIVE) {
+ switch (avctx->codec_id) {
+ case AV_CODEC_ID_MJPEG:
+ case AV_CODEC_ID_MPEG1VIDEO: return AVCHROMA_LOC_CENTER;
+ }
+ }
+ if (avctx->field_order == AV_FIELD_UNKNOWN || avctx->field_order != AV_FIELD_PROGRESSIVE) {
+ switch (avctx->codec_id) {
+ case AV_CODEC_ID_MPEG2VIDEO: return AVCHROMA_LOC_LEFT;
+ }
+ }
+ }
+ }
+
+ return AVCHROMA_LOC_UNSPECIFIED;
+
+}
+
+int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat,
+ const char *format, const char *filename)
+{
+ AVFormatContext *s = avformat_alloc_context();
+ int ret = 0;
+
+ *avctx = NULL;
+ if (!s)
+ goto nomem;
+
+ if (!oformat) {
+ if (format) {
+ oformat = av_guess_format(format, NULL, NULL);
+ if (!oformat) {
+ av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format);
+ ret = AVERROR(EINVAL);
+ goto error;
+ }
+ } else {
+ oformat = av_guess_format(NULL, filename, NULL);
+ if (!oformat) {
+ ret = AVERROR(EINVAL);
+ av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'\n",
+ filename);
+ goto error;
+ }
+ }
+ }
+
+ s->oformat = oformat;
+ if (s->oformat->priv_data_size > 0) {
+ s->priv_data = av_mallocz(s->oformat->priv_data_size);
+ if (!s->priv_data)
+ goto nomem;
+ if (s->oformat->priv_class) {
+ *(const AVClass**)s->priv_data= s->oformat->priv_class;
+ av_opt_set_defaults(s->priv_data);
+ }
+ } else
+ s->priv_data = NULL;
+
+ if (filename)
+ av_strlcpy(s->filename, filename, sizeof(s->filename));
+ *avctx = s;
+ return 0;
+nomem:
+ av_log(s, AV_LOG_ERROR, "Out of memory\n");
+ ret = AVERROR(ENOMEM);
+error:
+ avformat_free_context(s);
+ return ret;
+}
+
+static int validate_codec_tag(AVFormatContext *s, AVStream *st)
+{
+ const AVCodecTag *avctag;
+ int n;
+ enum AVCodecID id = AV_CODEC_ID_NONE;
+ int64_t tag = -1;
+
+ /**
+ * Check that tag + id is in the table
+ * If neither is in the table -> OK
+ * If tag is in the table with another id -> FAIL
+ * If id is in the table with another tag -> FAIL unless strict < normal
+ */
+ for (n = 0; s->oformat->codec_tag[n]; n++) {
+ avctag = s->oformat->codec_tag[n];
+ while (avctag->id != AV_CODEC_ID_NONE) {
+ if (avpriv_toupper4(avctag->tag) == avpriv_toupper4(st->codec->codec_tag)) {
+ id = avctag->id;
+ if (id == st->codec->codec_id)
+ return 1;
+ }
+ if (avctag->id == st->codec->codec_id)
+ tag = avctag->tag;
+ avctag++;
+ }
+ }
+ if (id != AV_CODEC_ID_NONE)
+ return 0;
+ if (tag >= 0 && (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL))
+ return 0;
+ return 1;
+}
+
+
+static int init_muxer(AVFormatContext *s, AVDictionary **options)
+{
+ int ret = 0, i;
+ AVStream *st;
+ AVDictionary *tmp = NULL;
+ AVCodecContext *codec = NULL;
+ AVOutputFormat *of = s->oformat;
+ AVDictionaryEntry *e;
+
+ if (options)
+ av_dict_copy(&tmp, *options, 0);
+
+ if ((ret = av_opt_set_dict(s, &tmp)) < 0)
+ goto fail;
+ if (s->priv_data && s->oformat->priv_class && *(const AVClass**)s->priv_data==s->oformat->priv_class &&
+ (ret = av_opt_set_dict2(s->priv_data, &tmp, AV_OPT_SEARCH_CHILDREN)) < 0)
+ goto fail;
+
+ if (s->nb_streams && s->streams[0]->codec->flags & AV_CODEC_FLAG_BITEXACT) {
+ if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
+#if FF_API_LAVF_BITEXACT
+ av_log(s, AV_LOG_WARNING,
+ "Setting the AVFormatContext to bitexact mode, because "
+ "the AVCodecContext is in that mode. This behavior will "
+ "change in the future. To keep the current behavior, set "
+ "AVFormatContext.flags |= AVFMT_FLAG_BITEXACT.\n");
+ s->flags |= AVFMT_FLAG_BITEXACT;
+#else
+ av_log(s, AV_LOG_WARNING,
+ "The AVFormatContext is not in set to bitexact mode, only "
+ "the AVCodecContext. If this is not intended, set "
+ "AVFormatContext.flags |= AVFMT_FLAG_BITEXACT.\n");
+#endif
+ }
+ }
+
+ // some sanity checks
+ if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) {
+ av_log(s, AV_LOG_ERROR, "No streams to mux were specified\n");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ for (i = 0; i < s->nb_streams; i++) {
+ st = s->streams[i];
+ codec = st->codec;
+
+#if FF_API_LAVF_CODEC_TB
+FF_DISABLE_DEPRECATION_WARNINGS
+ if (!st->time_base.num && codec->time_base.num) {
+ av_log(s, AV_LOG_WARNING, "Using AVStream.codec.time_base as a "
+ "timebase hint to the muxer is deprecated. Set "
+ "AVStream.time_base instead.\n");
+ avpriv_set_pts_info(st, 64, codec->time_base.num, codec->time_base.den);
+ }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+ if (!st->time_base.num) {
+ /* fall back on the default timebase values */
+ if (codec->codec_type == AVMEDIA_TYPE_AUDIO && codec->sample_rate)
+ avpriv_set_pts_info(st, 64, 1, codec->sample_rate);
+ else
+ avpriv_set_pts_info(st, 33, 1, 90000);
+ }
+
+ switch (codec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ if (codec->sample_rate <= 0) {
+ av_log(s, AV_LOG_ERROR, "sample rate not set\n");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ if (!codec->block_align)
+ codec->block_align = codec->channels *
+ av_get_bits_per_sample(codec->codec_id) >> 3;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ if ((codec->width <= 0 || codec->height <= 0) &&
+ !(of->flags & AVFMT_NODIMENSIONS)) {
+ av_log(s, AV_LOG_ERROR, "dimensions not set\n");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ if (av_cmp_q(st->sample_aspect_ratio, codec->sample_aspect_ratio)
+ && FFABS(av_q2d(st->sample_aspect_ratio) - av_q2d(codec->sample_aspect_ratio)) > 0.004*av_q2d(st->sample_aspect_ratio)
+ ) {
+ if (st->sample_aspect_ratio.num != 0 &&
+ st->sample_aspect_ratio.den != 0 &&
+ codec->sample_aspect_ratio.num != 0 &&
+ codec->sample_aspect_ratio.den != 0) {
+ av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "
+ "(%d/%d) and encoder layer (%d/%d)\n",
+ st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
+ codec->sample_aspect_ratio.num,
+ codec->sample_aspect_ratio.den);
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ }
+ break;
+ }
+
+ if (of->codec_tag) {
+ if ( codec->codec_tag
+ && codec->codec_id == AV_CODEC_ID_RAWVIDEO
+ && ( av_codec_get_tag(of->codec_tag, codec->codec_id) == 0
+ || av_codec_get_tag(of->codec_tag, codec->codec_id) == MKTAG('r', 'a', 'w', ' '))
+ && !validate_codec_tag(s, st)) {
+ // the current rawvideo encoding system ends up setting
+ // the wrong codec_tag for avi/mov, we override it here
+ codec->codec_tag = 0;
+ }
+ if (codec->codec_tag) {
+ if (!validate_codec_tag(s, st)) {
+ char tagbuf[32], tagbuf2[32];
+ av_get_codec_tag_string(tagbuf, sizeof(tagbuf), codec->codec_tag);
+ av_get_codec_tag_string(tagbuf2, sizeof(tagbuf2), av_codec_get_tag(s->oformat->codec_tag, codec->codec_id));
+ av_log(s, AV_LOG_ERROR,
+ "Tag %s/0x%08x incompatible with output codec id '%d' (%s)\n",
+ tagbuf, codec->codec_tag, codec->codec_id, tagbuf2);
+ ret = AVERROR_INVALIDDATA;
+ goto fail;
+ }
+ } else
+ codec->codec_tag = av_codec_get_tag(of->codec_tag, codec->codec_id);
+ }
+
+ if (of->flags & AVFMT_GLOBALHEADER &&
+ !(codec->flags & AV_CODEC_FLAG_GLOBAL_HEADER))
+ av_log(s, AV_LOG_WARNING,
+ "Codec for stream %d does not use global headers "
+ "but container format requires global headers\n", i);
+
+ if (codec->codec_type != AVMEDIA_TYPE_ATTACHMENT)
+ s->internal->nb_interleaved_streams++;
+ }
+
+ if (!s->priv_data && of->priv_data_size > 0) {
+ s->priv_data = av_mallocz(of->priv_data_size);
+ if (!s->priv_data) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ if (of->priv_class) {
+ *(const AVClass **)s->priv_data = of->priv_class;
+ av_opt_set_defaults(s->priv_data);
+ if ((ret = av_opt_set_dict2(s->priv_data, &tmp, AV_OPT_SEARCH_CHILDREN)) < 0)
+ goto fail;
+ }
+ }
+
+ /* set muxer identification string */
+ if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
+ av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0);
+ } else {
+ av_dict_set(&s->metadata, "encoder", NULL, 0);
+ }
+
+ for (e = NULL; e = av_dict_get(s->metadata, "encoder-", e, AV_DICT_IGNORE_SUFFIX); ) {
+ av_dict_set(&s->metadata, e->key, NULL, 0);
+ }
+
+ if (options) {
+ av_dict_free(options);
+ *options = tmp;
+ }
+
+ return 0;
+
+fail:
+ av_dict_free(&tmp);
+ return ret;
+}
+
+static int init_pts(AVFormatContext *s)
+{
+ int i;
+ AVStream *st;
+
+ /* init PTS generation */
+ for (i = 0; i < s->nb_streams; i++) {
+ int64_t den = AV_NOPTS_VALUE;
+ st = s->streams[i];
+
+ switch (st->codec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ den = (int64_t)st->time_base.num * st->codec->sample_rate;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ den = (int64_t)st->time_base.num * st->codec->time_base.den;
+ break;
+ default:
+ break;
+ }
+
+ if (!st->priv_pts)
+ st->priv_pts = av_mallocz(sizeof(*st->priv_pts));
+ if (!st->priv_pts)
+ return AVERROR(ENOMEM);
+
+ if (den != AV_NOPTS_VALUE) {
+ if (den <= 0)
+ return AVERROR_INVALIDDATA;
+
+ frac_init(st->priv_pts, 0, 0, den);
+ }
+ }
+
+ return 0;
+}
+
+int avformat_write_header(AVFormatContext *s, AVDictionary **options)
+{
+ int ret = 0;
+
+ if ((ret = init_muxer(s, options)) < 0)
+ return ret;
+
+ if (s->oformat->write_header) {
+ ret = s->oformat->write_header(s);
+ if (ret >= 0 && s->pb && s->pb->error < 0)
+ ret = s->pb->error;
+ if (ret < 0)
+ return ret;
+ if (s->flush_packets && s->pb && s->pb->error >= 0 && s->flags & AVFMT_FLAG_FLUSH_PACKETS)
+ avio_flush(s->pb);
+ }
+
+ if ((ret = init_pts(s)) < 0)
+ return ret;
+
+ if (s->avoid_negative_ts < 0) {
+ av_assert2(s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_AUTO);
+ if (s->oformat->flags & (AVFMT_TS_NEGATIVE | AVFMT_NOTIMESTAMPS)) {
+ s->avoid_negative_ts = 0;
+ } else
+ s->avoid_negative_ts = AVFMT_AVOID_NEG_TS_MAKE_NON_NEGATIVE;
+ }
+
+ return 0;
+}
+
+#define AV_PKT_FLAG_UNCODED_FRAME 0x2000
+
+/* Note: using sizeof(AVFrame) from outside lavu is unsafe in general, but
+ it is only being used internally to this file as a consistency check.
+ The value is chosen to be very unlikely to appear on its own and to cause
+ immediate failure if used anywhere as a real size. */
+#define UNCODED_FRAME_PACKET_SIZE (INT_MIN / 3 * 2 + (int)sizeof(AVFrame))
+
+
+//FIXME merge with compute_pkt_fields
+static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt)
+{
+ int delay = FFMAX(st->codec->has_b_frames, st->codec->max_b_frames > 0);
+ int num, den, i;
+ int frame_size;
+
+ if (s->debug & FF_FDEBUG_TS)
+ av_log(s, AV_LOG_TRACE, "compute_pkt_fields2: 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->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) {
+ av_log(s, AV_LOG_WARNING, "Packet with invalid duration %d 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;
+
+ //XXX/FIXME this is a temporary hack until all encoders output pts
+ if ((pkt->pts == 0 || pkt->pts == AV_NOPTS_VALUE) && pkt->dts == AV_NOPTS_VALUE && !delay) {
+ static int warned;
+ if (!warned) {
+ av_log(s, AV_LOG_WARNING, "Encoder did not produce proper pts, making some up.\n");
+ warned = 1;
+ }
+ pkt->dts =
+// pkt->pts= st->cur_dts;
+ pkt->pts = st->priv_pts->val;
+ }
+
+ //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; i<delay && st->pts_buffer[i] > st->pts_buffer[i + 1]; i++)
+ FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i + 1]);
+
+ pkt->dts = st->pts_buffer[0];
+ }
+
+ if (st->cur_dts && st->cur_dts != AV_NOPTS_VALUE &&
+ ((!(s->oformat->flags & AVFMT_TS_NONSTRICT) &&
+ st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE &&
+ st->cur_dts >= pkt->dts) || st->cur_dts > pkt->dts)) {
+ av_log(s, AV_LOG_ERROR,
+ "Application provided invalid, non monotonically increasing dts to muxer in stream %d: %s >= %s\n",
+ st->index, av_ts2str(st->cur_dts), av_ts2str(pkt->dts));
+ return AVERROR(EINVAL);
+ }
+ if (pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts) {
+ av_log(s, AV_LOG_ERROR,
+ "pts (%s) < dts (%s) in stream %d\n",
+ av_ts2str(pkt->pts), av_ts2str(pkt->dts),
+ st->index);
+ return AVERROR(EINVAL);
+ }
+
+ if (s->debug & FF_FDEBUG_TS)
+ av_log(s, AV_LOG_TRACE, "av_write_frame: pts2:%s dts2:%s\n",
+ av_ts2str(pkt->pts), av_ts2str(pkt->dts));
+
+ st->cur_dts = pkt->dts;
+ st->priv_pts->val = pkt->dts;
+
+ /* update pts */
+ switch (st->codec->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ frame_size = (pkt->flags & AV_PKT_FLAG_UNCODED_FRAME) ?
+ ((AVFrame *)pkt->data)->nb_samples :
+ av_get_audio_frame_duration(st->codec, pkt->size);
+
+ /* HACK/FIXME, we skip the initial 0 size packets as they are most
+ * likely equal to the encoder delay, but it would be better if we
+ * had the real timestamps from the encoder */
+ if (frame_size >= 0 && (pkt->size || st->priv_pts->num != st->priv_pts->den >> 1 || st->priv_pts->val)) {
+ frac_add(st->priv_pts, (int64_t)st->time_base.den * frame_size);
+ }
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ frac_add(st->priv_pts, (int64_t)st->time_base.den * st->codec->time_base.num);
+ break;
+ }
+ return 0;
+}
+
+/**
+ * Make timestamps non negative, move side data from payload to internal struct, call muxer, and restore
+ * sidedata.
+ *
+ * FIXME: this function should NEVER get undefined pts/dts beside when the
+ * AVFMT_NOTIMESTAMPS is set.
+ * Those additional safety checks should be dropped once the correct checks
+ * are set in the callers.
+ */
+static int write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ int ret, did_split;
+
+ if (s->output_ts_offset) {
+ AVStream *st = s->streams[pkt->stream_index];
+ int64_t 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;
+ }
+
+ if (s->avoid_negative_ts > 0) {
+ AVStream *st = s->streams[pkt->stream_index];
+ int64_t offset = st->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 &&
+ (ts < 0 || s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)) {
+ s->internal->offset = -ts;
+ s->internal->offset_timebase = st->time_base;
+ }
+
+ if (s->internal->offset != AV_NOPTS_VALUE && !offset) {
+ offset = st->mux_ts_offset =
+ av_rescale_q_rnd(s->internal->offset,
+ s->internal->offset_timebase,
+ st->time_base,
+ AV_ROUND_UP);
+ }
+
+ if (pkt->dts != AV_NOPTS_VALUE)
+ pkt->dts += offset;
+ if (pkt->pts != AV_NOPTS_VALUE)
+ pkt->pts += offset;
+
+ if (s->internal->avoid_negative_ts_use_pts) {
+ if (pkt->pts != AV_NOPTS_VALUE && pkt->pts < 0) {
+ av_log(s, AV_LOG_WARNING, "failed to avoid negative "
+ "pts %s in stream %d.\n"
+ "Try -avoid_negative_ts 1 as a possible workaround.\n",
+ av_ts2str(pkt->pts),
+ pkt->stream_index
+ );
+ }
+ } else {
+ av_assert2(pkt->dts == AV_NOPTS_VALUE || pkt->dts >= 0 || s->max_interleave_delta > 0);
+ if (pkt->dts != AV_NOPTS_VALUE && pkt->dts < 0) {
+ av_log(s, AV_LOG_WARNING,
+ "Packets poorly interleaved, failed to avoid negative "
+ "timestamp %s in stream %d.\n"
+ "Try -max_interleave_delta 0 as a possible workaround.\n",
+ av_ts2str(pkt->dts),
+ pkt->stream_index
+ );
+ }
+ }
+ }
+
+ did_split = av_packet_split_side_data(pkt);
+ if ((pkt->flags & AV_PKT_FLAG_UNCODED_FRAME)) {
+ AVFrame *frame = (AVFrame *)pkt->data;
+ av_assert0(pkt->size == UNCODED_FRAME_PACKET_SIZE);
+ ret = s->oformat->write_uncoded_frame(s, pkt->stream_index, &frame, 0);
+ av_frame_free(&frame);
+ } else {
+ ret = s->oformat->write_packet(s, pkt);
+ }
+
+ if (s->flush_packets && s->pb && ret >= 0 && s->flags & AVFMT_FLAG_FLUSH_PACKETS)
+ avio_flush(s->pb);
+
+ if (did_split)
+ av_packet_merge_side_data(pkt);
+
+ return ret;
+}
+
+static int check_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ if (!pkt)
+ return 0;
+
+ if (pkt->stream_index < 0 || pkt->stream_index >= s->nb_streams) {
+ av_log(s, AV_LOG_ERROR, "Invalid packet stream index: %d\n",
+ pkt->stream_index);
+ return AVERROR(EINVAL);
+ }
+
+ if (s->streams[pkt->stream_index]->codec->codec_type == AVMEDIA_TYPE_ATTACHMENT) {
+ av_log(s, AV_LOG_ERROR, "Received a packet for an attachment stream.\n");
+ return AVERROR(EINVAL);
+ }
+
+ return 0;
+}
+
+int av_write_frame(AVFormatContext *s, AVPacket *pkt)
+{
+ int ret;
+
+ ret = check_packet(s, pkt);
+ if (ret < 0)
+ return ret;
+
+ if (!pkt) {
+ if (s->oformat->flags & AVFMT_ALLOW_FLUSH) {
+ ret = s->oformat->write_packet(s, NULL);
+ if (s->flush_packets && s->pb && s->pb->error >= 0 && s->flags & AVFMT_FLAG_FLUSH_PACKETS)
+ avio_flush(s->pb);
+ if (ret >= 0 && s->pb && s->pb->error < 0)
+ ret = s->pb->error;
+ return ret;
+ }
+ return 1;
+ }
+
+ ret = compute_pkt_fields2(s, s->streams[pkt->stream_index], pkt);
+
+ if (ret < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
+ return ret;
+
+ ret = write_packet(s, pkt);
+ if (ret >= 0 && s->pb && s->pb->error < 0)
+ ret = s->pb->error;
+
+ if (ret >= 0)
+ s->streams[pkt->stream_index]->nb_frames++;
+ return ret;
+}
+
+#define CHUNK_START 0x1000
+
+int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
+ int (*compare)(AVFormatContext *, AVPacket *, AVPacket *))
+{
+ int ret;
+ AVPacketList **next_point, *this_pktl;
+ AVStream *st = s->streams[pkt->stream_index];
+ int chunked = s->max_chunk_size || s->max_chunk_duration;
+
+ this_pktl = av_mallocz(sizeof(AVPacketList));
+ if (!this_pktl)
+ return AVERROR(ENOMEM);
+ this_pktl->pkt = *pkt;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+ pkt->destruct = NULL; // do not free original but only the copy
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ pkt->buf = NULL;
+ pkt->side_data = NULL;
+ pkt->side_data_elems = 0;
+ if ((pkt->flags & AV_PKT_FLAG_UNCODED_FRAME)) {
+ av_assert0(pkt->size == UNCODED_FRAME_PACKET_SIZE);
+ av_assert0(((AVFrame *)pkt->data)->buf);
+ } else {
+ // Duplicate the packet if it uses non-allocated memory
+ if ((ret = av_dup_packet(&this_pktl->pkt)) < 0) {
+ av_free(this_pktl);
+ return ret;
+ }
+ }
+
+ if (s->streams[pkt->stream_index]->last_in_packet_buffer) {
+ next_point = &(st->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;
+ this_pktl->pkt.flags |= CHUNK_START;
+ if (max && st->interleaver_chunk_duration > max) {
+ int64_t syncoffset = (st->codec->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;
+ } else
+ st->interleaver_chunk_duration = 0;
+ }
+ }
+ if (*next_point) {
+ if (chunked && !(this_pktl->pkt.flags & CHUNK_START))
+ goto next_non_null;
+
+ if (compare(s, &s->internal->packet_buffer_end->pkt, pkt)) {
+ while ( *next_point
+ && ((chunked && !((*next_point)->pkt.flags&CHUNK_START))
+ || !compare(s, &(*next_point)->pkt, pkt)))
+ next_point = &(*next_point)->next;
+ if (*next_point)
+ goto next_non_null;
+ } else {
+ next_point = &(s->internal->packet_buffer_end->next);
+ }
+ }
+ av_assert1(!*next_point);
+
+ s->internal->packet_buffer_end = this_pktl;
+next_non_null:
+
+ this_pktl->next = *next_point;
+
+ s->streams[pkt->stream_index]->last_in_packet_buffer =
+ *next_point = this_pktl;
+
+ return 0;
+}
+
+static int interleave_compare_dts(AVFormatContext *s, AVPacket *next,
+ AVPacket *pkt)
+{
+ AVStream *st = s->streams[pkt->stream_index];
+ AVStream *st2 = s->streams[next->stream_index];
+ int comp = av_compare_ts(next->dts, st2->time_base, pkt->dts,
+ st->time_base);
+ if (s->audio_preload && ((st->codec->codec_type == AVMEDIA_TYPE_AUDIO) != (st2->codec->codec_type == AVMEDIA_TYPE_AUDIO))) {
+ int64_t ts = av_rescale_q(pkt ->dts, st ->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st ->codec->codec_type == AVMEDIA_TYPE_AUDIO);
+ int64_t ts2= av_rescale_q(next->dts, st2->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st2->codec->codec_type == AVMEDIA_TYPE_AUDIO);
+ if (ts == ts2) {
+ ts= ( pkt ->dts* st->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st ->codec->codec_type == AVMEDIA_TYPE_AUDIO)* st->time_base.den)*st2->time_base.den
+ -( next->dts*st2->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st2->codec->codec_type == AVMEDIA_TYPE_AUDIO)*st2->time_base.den)* st->time_base.den;
+ ts2=0;
+ }
+ comp= (ts>ts2) - (ts<ts2);
+ }
+
+ if (comp == 0)
+ return pkt->stream_index < next->stream_index;
+ return comp > 0;
+}
+
+int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
+ AVPacket *pkt, int flush)
+{
+ AVPacketList *pktl;
+ int stream_count = 0;
+ int noninterleaved_count = 0;
+ int i, ret;
+
+ if (pkt) {
+ if ((ret = ff_interleave_add_packet(s, pkt, interleave_compare_dts)) < 0)
+ return ret;
+ }
+
+ for (i = 0; i < s->nb_streams; i++) {
+ if (s->streams[i]->last_in_packet_buffer) {
+ ++stream_count;
+ } else if (s->streams[i]->codec->codec_type != AVMEDIA_TYPE_ATTACHMENT &&
+ s->streams[i]->codec->codec_id != AV_CODEC_ID_VP8 &&
+ s->streams[i]->codec->codec_id != AV_CODEC_ID_VP9) {
+ ++noninterleaved_count;
+ }
+ }
+
+ if (s->internal->nb_interleaved_streams == stream_count)
+ flush = 1;
+
+ if (s->max_interleave_delta > 0 &&
+ s->internal->packet_buffer &&
+ !flush &&
+ s->internal->nb_interleaved_streams == stream_count+noninterleaved_count
+ ) {
+ AVPacket *top_pkt = &s->internal->packet_buffer->pkt;
+ int64_t delta_dts = INT64_MIN;
+ int64_t top_dts = av_rescale_q(top_pkt->dts,
+ s->streams[top_pkt->stream_index]->time_base,
+ AV_TIME_BASE_Q);
+
+ for (i = 0; i < s->nb_streams; i++) {
+ int64_t last_dts;
+ const AVPacketList *last = s->streams[i]->last_in_packet_buffer;
+
+ if (!last)
+ continue;
+
+ last_dts = av_rescale_q(last->pkt.dts,
+ s->streams[i]->time_base,
+ AV_TIME_BASE_Q);
+ delta_dts = FFMAX(delta_dts, last_dts - top_dts);
+ }
+
+ if (delta_dts > s->max_interleave_delta) {
+ av_log(s, AV_LOG_DEBUG,
+ "Delay between the first packet and last packet in the "
+ "muxing queue is %"PRId64" > %"PRId64": forcing output\n",
+ delta_dts, s->max_interleave_delta);
+ flush = 1;
+ }
+ }
+
+ if (stream_count && flush) {
+ AVStream *st;
+ pktl = s->internal->packet_buffer;
+ *out = pktl->pkt;
+ st = s->streams[out->stream_index];
+
+ s->internal->packet_buffer = pktl->next;
+ if (!s->internal->packet_buffer)
+ s->internal->packet_buffer_end = NULL;
+
+ if (st->last_in_packet_buffer == pktl)
+ st->last_in_packet_buffer = NULL;
+ av_freep(&pktl);
+
+ return 1;
+ } else {
+ av_init_packet(out);
+ return 0;
+ }
+}
+
+/**
+ * Interleave an AVPacket correctly so it can be muxed.
+ * @param out the interleaved packet will be output here
+ * @param in the input packet
+ * @param flush 1 if no further packets are available as input and all
+ * remaining packets should be output
+ * @return 1 if a packet was output, 0 if no packet could be output,
+ * < 0 if an error occurred
+ */
+static int interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush)
+{
+ if (s->oformat->interleave_packet) {
+ int ret = s->oformat->interleave_packet(s, out, in, flush);
+ if (in)
+ av_free_packet(in);
+ return ret;
+ } else
+ return ff_interleave_packet_per_dts(s, out, in, flush);
+}
+
+int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
+{
+ int ret, flush = 0;
+
+ ret = check_packet(s, pkt);
+ if (ret < 0)
+ goto fail;
+
+ if (pkt) {
+ AVStream *st = s->streams[pkt->stream_index];
+
+ if (s->debug & FF_FDEBUG_TS)
+ av_log(s, AV_LOG_TRACE, "av_interleaved_write_frame size:%d dts:%s pts:%s\n",
+ pkt->size, av_ts2str(pkt->dts), av_ts2str(pkt->pts));
+
+ if ((ret = compute_pkt_fields2(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
+ goto fail;
+
+ if (pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) {
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ } else {
+ av_log(s, AV_LOG_TRACE, "av_interleaved_write_frame FLUSH\n");
+ flush = 1;
+ }
+
+ for (;; ) {
+ AVPacket opkt;
+ int ret = interleave_packet(s, &opkt, pkt, flush);
+ if (pkt) {
+ memset(pkt, 0, sizeof(*pkt));
+ av_init_packet(pkt);
+ pkt = NULL;
+ }
+ if (ret <= 0) //FIXME cleanup needed for ret<0 ?
+ return ret;
+
+ ret = write_packet(s, &opkt);
+ if (ret >= 0)
+ s->streams[opkt.stream_index]->nb_frames++;
+
+ av_free_packet(&opkt);
+
+ if (ret < 0)
+ return ret;
+ if(s->pb && s->pb->error)
+ return s->pb->error;
+ }
+fail:
+ av_packet_unref(pkt);
+ return ret;
+}
+
+int av_write_trailer(AVFormatContext *s)
+{
+ int ret, i;
+
+ for (;; ) {
+ AVPacket pkt;
+ ret = interleave_packet(s, &pkt, NULL, 1);
+ if (ret < 0)
+ goto fail;
+ if (!ret)
+ break;
+
+ ret = write_packet(s, &pkt);
+ if (ret >= 0)
+ s->streams[pkt.stream_index]->nb_frames++;
+
+ av_free_packet(&pkt);
+
+ if (ret < 0)
+ goto fail;
+ if(s->pb && s->pb->error)
+ goto fail;
+ }
+
+fail:
+ if (s->oformat->write_trailer)
+ if (ret >= 0) {
+ ret = s->oformat->write_trailer(s);
+ } else {
+ s->oformat->write_trailer(s);
+ }
+
+ if (s->pb)
+ avio_flush(s->pb);
+ if (ret == 0)
+ ret = s->pb ? s->pb->error : 0;
+ for (i = 0; i < s->nb_streams; i++) {
+ av_freep(&s->streams[i]->priv_data);
+ av_freep(&s->streams[i]->index_entries);
+ }
+ if (s->oformat->priv_class)
+ av_opt_free(s->priv_data);
+ av_freep(&s->priv_data);
+ return ret;
+}
+
+int av_get_output_timestamp(struct AVFormatContext *s, int stream,
+ int64_t *dts, int64_t *wall)
+{
+ if (!s->oformat || !s->oformat->get_output_timestamp)
+ return AVERROR(ENOSYS);
+ s->oformat->get_output_timestamp(s, stream, dts, wall);
+ return 0;
+}
+
+int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
+ AVFormatContext *src, int interleave)
+{
+ AVPacket local_pkt;
+ int ret;
+
+ local_pkt = *pkt;
+ local_pkt.stream_index = dst_stream;
+ if (pkt->pts != AV_NOPTS_VALUE)
+ local_pkt.pts = av_rescale_q(pkt->pts,
+ src->streams[pkt->stream_index]->time_base,
+ dst->streams[dst_stream]->time_base);
+ if (pkt->dts != AV_NOPTS_VALUE)
+ local_pkt.dts = av_rescale_q(pkt->dts,
+ src->streams[pkt->stream_index]->time_base,
+ dst->streams[dst_stream]->time_base);
+ if (pkt->duration)
+ local_pkt.duration = av_rescale_q(pkt->duration,
+ src->streams[pkt->stream_index]->time_base,
+ dst->streams[dst_stream]->time_base);
+
+ if (interleave) ret = av_interleaved_write_frame(dst, &local_pkt);
+ else ret = av_write_frame(dst, &local_pkt);
+ pkt->buf = local_pkt.buf;
+ pkt->side_data = local_pkt.side_data;
+ pkt->side_data_elems = local_pkt.side_data_elems;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+ pkt->destruct = local_pkt.destruct;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ return ret;
+}
+
+static int av_write_uncoded_frame_internal(AVFormatContext *s, int stream_index,
+ AVFrame *frame, int interleaved)
+{
+ AVPacket pkt, *pktp;
+
+ av_assert0(s->oformat);
+ if (!s->oformat->write_uncoded_frame)
+ return AVERROR(ENOSYS);
+
+ if (!frame) {
+ pktp = NULL;
+ } else {
+ pktp = &pkt;
+ av_init_packet(&pkt);
+ pkt.data = (void *)frame;
+ pkt.size = UNCODED_FRAME_PACKET_SIZE;
+ pkt.pts =
+ pkt.dts = frame->pts;
+ pkt.duration = av_frame_get_pkt_duration(frame);
+ 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);
+}
+
+int av_write_uncoded_frame(AVFormatContext *s, int stream_index,
+ AVFrame *frame)
+{
+ return av_write_uncoded_frame_internal(s, stream_index, frame, 0);
+}
+
+int av_interleaved_write_uncoded_frame(AVFormatContext *s, int stream_index,
+ AVFrame *frame)
+{
+ return av_write_uncoded_frame_internal(s, stream_index, frame, 1);
+}
+
+int av_write_uncoded_frame_query(AVFormatContext *s, int stream_index)
+{
+ av_assert0(s->oformat);
+ if (!s->oformat->write_uncoded_frame)
+ return AVERROR(ENOSYS);
+ return s->oformat->write_uncoded_frame(s, stream_index, NULL,
+ AV_WRITE_UNCODED_FRAME_QUERY);
+}
diff --git a/ffmpeg-2-8-11/libavformat/mvdec.c b/ffmpeg-2-8-12/libavformat/mvdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mvdec.c
rename to ffmpeg-2-8-12/libavformat/mvdec.c
diff --git a/ffmpeg-2-8-11/libavformat/mvi.c b/ffmpeg-2-8-12/libavformat/mvi.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mvi.c
rename to ffmpeg-2-8-12/libavformat/mvi.c
diff --git a/ffmpeg-2-8-11/libavformat/mxf.c b/ffmpeg-2-8-12/libavformat/mxf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mxf.c
rename to ffmpeg-2-8-12/libavformat/mxf.c
diff --git a/ffmpeg-2-8-11/libavformat/mxf.h b/ffmpeg-2-8-12/libavformat/mxf.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mxf.h
rename to ffmpeg-2-8-12/libavformat/mxf.h
diff --git a/ffmpeg-2-8-11/libavformat/mxfdec.c b/ffmpeg-2-8-12/libavformat/mxfdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mxfdec.c
rename to ffmpeg-2-8-12/libavformat/mxfdec.c
diff --git a/ffmpeg-2-8-11/libavformat/mxfenc.c b/ffmpeg-2-8-12/libavformat/mxfenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mxfenc.c
rename to ffmpeg-2-8-12/libavformat/mxfenc.c
diff --git a/ffmpeg-2-8-11/libavformat/mxg.c b/ffmpeg-2-8-12/libavformat/mxg.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/mxg.c
rename to ffmpeg-2-8-12/libavformat/mxg.c
diff --git a/ffmpeg-2-8-11/libavformat/ncdec.c b/ffmpeg-2-8-12/libavformat/ncdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/ncdec.c
rename to ffmpeg-2-8-12/libavformat/ncdec.c
diff --git a/ffmpeg-2-8-11/libavformat/network.c b/ffmpeg-2-8-12/libavformat/network.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/network.c
rename to ffmpeg-2-8-12/libavformat/network.c
diff --git a/ffmpeg-2-8-11/libavformat/network.h b/ffmpeg-2-8-12/libavformat/network.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/network.h
rename to ffmpeg-2-8-12/libavformat/network.h
diff --git a/ffmpeg-2-8-11/libavformat/nistspheredec.c b/ffmpeg-2-8-12/libavformat/nistspheredec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/nistspheredec.c
rename to ffmpeg-2-8-12/libavformat/nistspheredec.c
diff --git a/ffmpeg-2-8-11/libavformat/noproxy-test.c b/ffmpeg-2-8-12/libavformat/noproxy-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/noproxy-test.c
rename to ffmpeg-2-8-12/libavformat/noproxy-test.c
diff --git a/ffmpeg-2-8-11/libavformat/nsvdec.c b/ffmpeg-2-8-12/libavformat/nsvdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/nsvdec.c
rename to ffmpeg-2-8-12/libavformat/nsvdec.c
diff --git a/ffmpeg-2-8-11/libavformat/nullenc.c b/ffmpeg-2-8-12/libavformat/nullenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/nullenc.c
rename to ffmpeg-2-8-12/libavformat/nullenc.c
diff --git a/ffmpeg-2-8-11/libavformat/nut.c b/ffmpeg-2-8-12/libavformat/nut.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/nut.c
rename to ffmpeg-2-8-12/libavformat/nut.c
diff --git a/ffmpeg-2-8-11/libavformat/nut.h b/ffmpeg-2-8-12/libavformat/nut.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/nut.h
rename to ffmpeg-2-8-12/libavformat/nut.h
diff --git a/ffmpeg-2-8-11/libavformat/nutdec.c b/ffmpeg-2-8-12/libavformat/nutdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/nutdec.c
rename to ffmpeg-2-8-12/libavformat/nutdec.c
diff --git a/ffmpeg-2-8-11/libavformat/nutenc.c b/ffmpeg-2-8-12/libavformat/nutenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/nutenc.c
rename to ffmpeg-2-8-12/libavformat/nutenc.c
diff --git a/ffmpeg-2-8-11/libavformat/nuv.c b/ffmpeg-2-8-12/libavformat/nuv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/nuv.c
rename to ffmpeg-2-8-12/libavformat/nuv.c
diff --git a/ffmpeg-2-8-11/libavformat/oggdec.c b/ffmpeg-2-8-12/libavformat/oggdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oggdec.c
rename to ffmpeg-2-8-12/libavformat/oggdec.c
diff --git a/ffmpeg-2-8-11/libavformat/oggdec.h b/ffmpeg-2-8-12/libavformat/oggdec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oggdec.h
rename to ffmpeg-2-8-12/libavformat/oggdec.h
diff --git a/ffmpeg-2-8-11/libavformat/oggenc.c b/ffmpeg-2-8-12/libavformat/oggenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oggenc.c
rename to ffmpeg-2-8-12/libavformat/oggenc.c
diff --git a/ffmpeg-2-8-11/libavformat/oggparsecelt.c b/ffmpeg-2-8-12/libavformat/oggparsecelt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oggparsecelt.c
rename to ffmpeg-2-8-12/libavformat/oggparsecelt.c
diff --git a/ffmpeg-2-8-11/libavformat/oggparsedirac.c b/ffmpeg-2-8-12/libavformat/oggparsedirac.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oggparsedirac.c
rename to ffmpeg-2-8-12/libavformat/oggparsedirac.c
diff --git a/ffmpeg-2-8-11/libavformat/oggparseflac.c b/ffmpeg-2-8-12/libavformat/oggparseflac.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oggparseflac.c
rename to ffmpeg-2-8-12/libavformat/oggparseflac.c
diff --git a/ffmpeg-2-8-11/libavformat/oggparseogm.c b/ffmpeg-2-8-12/libavformat/oggparseogm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oggparseogm.c
rename to ffmpeg-2-8-12/libavformat/oggparseogm.c
diff --git a/ffmpeg-2-8-11/libavformat/oggparseopus.c b/ffmpeg-2-8-12/libavformat/oggparseopus.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oggparseopus.c
rename to ffmpeg-2-8-12/libavformat/oggparseopus.c
diff --git a/ffmpeg-2-8-11/libavformat/oggparseskeleton.c b/ffmpeg-2-8-12/libavformat/oggparseskeleton.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oggparseskeleton.c
rename to ffmpeg-2-8-12/libavformat/oggparseskeleton.c
diff --git a/ffmpeg-2-8-11/libavformat/oggparsespeex.c b/ffmpeg-2-8-12/libavformat/oggparsespeex.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oggparsespeex.c
rename to ffmpeg-2-8-12/libavformat/oggparsespeex.c
diff --git a/ffmpeg-2-8-11/libavformat/oggparsetheora.c b/ffmpeg-2-8-12/libavformat/oggparsetheora.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oggparsetheora.c
rename to ffmpeg-2-8-12/libavformat/oggparsetheora.c
diff --git a/ffmpeg-2-8-11/libavformat/oggparsevorbis.c b/ffmpeg-2-8-12/libavformat/oggparsevorbis.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oggparsevorbis.c
rename to ffmpeg-2-8-12/libavformat/oggparsevorbis.c
diff --git a/ffmpeg-2-8-11/libavformat/oggparsevp8.c b/ffmpeg-2-8-12/libavformat/oggparsevp8.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oggparsevp8.c
rename to ffmpeg-2-8-12/libavformat/oggparsevp8.c
diff --git a/ffmpeg-2-8-11/libavformat/oma.c b/ffmpeg-2-8-12/libavformat/oma.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oma.c
rename to ffmpeg-2-8-12/libavformat/oma.c
diff --git a/ffmpeg-2-8-11/libavformat/oma.h b/ffmpeg-2-8-12/libavformat/oma.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/oma.h
rename to ffmpeg-2-8-12/libavformat/oma.h
diff --git a/ffmpeg-2-8-11/libavformat/omadec.c b/ffmpeg-2-8-12/libavformat/omadec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/omadec.c
rename to ffmpeg-2-8-12/libavformat/omadec.c
diff --git a/ffmpeg-2-8-11/libavformat/omaenc.c b/ffmpeg-2-8-12/libavformat/omaenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/omaenc.c
rename to ffmpeg-2-8-12/libavformat/omaenc.c
diff --git a/ffmpeg-2-8-11/libavformat/options.c b/ffmpeg-2-8-12/libavformat/options.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/options.c
rename to ffmpeg-2-8-12/libavformat/options.c
diff --git a/ffmpeg-2-8-11/libavformat/options_table.h b/ffmpeg-2-8-12/libavformat/options_table.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/options_table.h
rename to ffmpeg-2-8-12/libavformat/options_table.h
diff --git a/ffmpeg-2-8-11/libavformat/os_support.c b/ffmpeg-2-8-12/libavformat/os_support.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/os_support.c
rename to ffmpeg-2-8-12/libavformat/os_support.c
diff --git a/ffmpeg-2-8-11/libavformat/os_support.h b/ffmpeg-2-8-12/libavformat/os_support.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/os_support.h
rename to ffmpeg-2-8-12/libavformat/os_support.h
diff --git a/ffmpeg-2-8-11/libavformat/paf.c b/ffmpeg-2-8-12/libavformat/paf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/paf.c
rename to ffmpeg-2-8-12/libavformat/paf.c
diff --git a/ffmpeg-2-8-11/libavformat/pcm.c b/ffmpeg-2-8-12/libavformat/pcm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/pcm.c
rename to ffmpeg-2-8-12/libavformat/pcm.c
diff --git a/ffmpeg-2-8-11/libavformat/pcm.h b/ffmpeg-2-8-12/libavformat/pcm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/pcm.h
rename to ffmpeg-2-8-12/libavformat/pcm.h
diff --git a/ffmpeg-2-8-11/libavformat/pcmdec.c b/ffmpeg-2-8-12/libavformat/pcmdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/pcmdec.c
rename to ffmpeg-2-8-12/libavformat/pcmdec.c
diff --git a/ffmpeg-2-8-11/libavformat/pcmenc.c b/ffmpeg-2-8-12/libavformat/pcmenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/pcmenc.c
rename to ffmpeg-2-8-12/libavformat/pcmenc.c
diff --git a/ffmpeg-2-8-11/libavformat/pjsdec.c b/ffmpeg-2-8-12/libavformat/pjsdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/pjsdec.c
rename to ffmpeg-2-8-12/libavformat/pjsdec.c
diff --git a/ffmpeg-2-8-11/libavformat/pmpdec.c b/ffmpeg-2-8-12/libavformat/pmpdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/pmpdec.c
rename to ffmpeg-2-8-12/libavformat/pmpdec.c
diff --git a/ffmpeg-2-8-11/libavformat/psxstr.c b/ffmpeg-2-8-12/libavformat/psxstr.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/psxstr.c
rename to ffmpeg-2-8-12/libavformat/psxstr.c
diff --git a/ffmpeg-2-8-11/libavformat/pva.c b/ffmpeg-2-8-12/libavformat/pva.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/pva.c
rename to ffmpeg-2-8-12/libavformat/pva.c
diff --git a/ffmpeg-2-8-11/libavformat/pvfdec.c b/ffmpeg-2-8-12/libavformat/pvfdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/pvfdec.c
rename to ffmpeg-2-8-12/libavformat/pvfdec.c
diff --git a/ffmpeg-2-8-11/libavformat/qcp.c b/ffmpeg-2-8-12/libavformat/qcp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/qcp.c
rename to ffmpeg-2-8-12/libavformat/qcp.c
diff --git a/ffmpeg-2-8-11/libavformat/qtpalette.h b/ffmpeg-2-8-12/libavformat/qtpalette.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/qtpalette.h
rename to ffmpeg-2-8-12/libavformat/qtpalette.h
diff --git a/ffmpeg-2-8-11/libavformat/r3d.c b/ffmpeg-2-8-12/libavformat/r3d.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/r3d.c
rename to ffmpeg-2-8-12/libavformat/r3d.c
diff --git a/ffmpeg-2-8-11/libavformat/rawdec.c b/ffmpeg-2-8-12/libavformat/rawdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rawdec.c
rename to ffmpeg-2-8-12/libavformat/rawdec.c
diff --git a/ffmpeg-2-8-11/libavformat/rawdec.h b/ffmpeg-2-8-12/libavformat/rawdec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rawdec.h
rename to ffmpeg-2-8-12/libavformat/rawdec.h
diff --git a/ffmpeg-2-8-11/libavformat/rawenc.c b/ffmpeg-2-8-12/libavformat/rawenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rawenc.c
rename to ffmpeg-2-8-12/libavformat/rawenc.c
diff --git a/ffmpeg-2-8-11/libavformat/rawenc.h b/ffmpeg-2-8-12/libavformat/rawenc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rawenc.h
rename to ffmpeg-2-8-12/libavformat/rawenc.h
diff --git a/ffmpeg-2-8-11/libavformat/rawvideodec.c b/ffmpeg-2-8-12/libavformat/rawvideodec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rawvideodec.c
rename to ffmpeg-2-8-12/libavformat/rawvideodec.c
diff --git a/ffmpeg-2-8-11/libavformat/rdt.c b/ffmpeg-2-8-12/libavformat/rdt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rdt.c
rename to ffmpeg-2-8-12/libavformat/rdt.c
diff --git a/ffmpeg-2-8-11/libavformat/rdt.h b/ffmpeg-2-8-12/libavformat/rdt.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rdt.h
rename to ffmpeg-2-8-12/libavformat/rdt.h
diff --git a/ffmpeg-2-8-11/libavformat/realtextdec.c b/ffmpeg-2-8-12/libavformat/realtextdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/realtextdec.c
rename to ffmpeg-2-8-12/libavformat/realtextdec.c
diff --git a/ffmpeg-2-8-11/libavformat/redspark.c b/ffmpeg-2-8-12/libavformat/redspark.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/redspark.c
rename to ffmpeg-2-8-12/libavformat/redspark.c
diff --git a/ffmpeg-2-8-11/libavformat/replaygain.c b/ffmpeg-2-8-12/libavformat/replaygain.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/replaygain.c
rename to ffmpeg-2-8-12/libavformat/replaygain.c
diff --git a/ffmpeg-2-8-11/libavformat/replaygain.h b/ffmpeg-2-8-12/libavformat/replaygain.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/replaygain.h
rename to ffmpeg-2-8-12/libavformat/replaygain.h
diff --git a/ffmpeg-2-8-11/libavformat/riff.c b/ffmpeg-2-8-12/libavformat/riff.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/riff.c
rename to ffmpeg-2-8-12/libavformat/riff.c
diff --git a/ffmpeg-2-8-11/libavformat/riff.h b/ffmpeg-2-8-12/libavformat/riff.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/riff.h
rename to ffmpeg-2-8-12/libavformat/riff.h
diff --git a/ffmpeg-2-8-11/libavformat/riffdec.c b/ffmpeg-2-8-12/libavformat/riffdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/riffdec.c
rename to ffmpeg-2-8-12/libavformat/riffdec.c
diff --git a/ffmpeg-2-8-11/libavformat/riffenc.c b/ffmpeg-2-8-12/libavformat/riffenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/riffenc.c
rename to ffmpeg-2-8-12/libavformat/riffenc.c
diff --git a/ffmpeg-2-8-11/libavformat/rl2.c b/ffmpeg-2-8-12/libavformat/rl2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rl2.c
rename to ffmpeg-2-8-12/libavformat/rl2.c
diff --git a/ffmpeg-2-8-11/libavformat/rm.c b/ffmpeg-2-8-12/libavformat/rm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rm.c
rename to ffmpeg-2-8-12/libavformat/rm.c
diff --git a/ffmpeg-2-8-11/libavformat/rm.h b/ffmpeg-2-8-12/libavformat/rm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rm.h
rename to ffmpeg-2-8-12/libavformat/rm.h
diff --git a/ffmpeg-2-8-11/libavformat/rmdec.c b/ffmpeg-2-8-12/libavformat/rmdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rmdec.c
rename to ffmpeg-2-8-12/libavformat/rmdec.c
diff --git a/ffmpeg-2-8-11/libavformat/rmenc.c b/ffmpeg-2-8-12/libavformat/rmenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rmenc.c
rename to ffmpeg-2-8-12/libavformat/rmenc.c
diff --git a/ffmpeg-2-8-11/libavformat/rmsipr.c b/ffmpeg-2-8-12/libavformat/rmsipr.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rmsipr.c
rename to ffmpeg-2-8-12/libavformat/rmsipr.c
diff --git a/ffmpeg-2-8-11/libavformat/rmsipr.h b/ffmpeg-2-8-12/libavformat/rmsipr.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rmsipr.h
rename to ffmpeg-2-8-12/libavformat/rmsipr.h
diff --git a/ffmpeg-2-8-11/libavformat/rpl.c b/ffmpeg-2-8-12/libavformat/rpl.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rpl.c
rename to ffmpeg-2-8-12/libavformat/rpl.c
diff --git a/ffmpeg-2-8-11/libavformat/rsd.c b/ffmpeg-2-8-12/libavformat/rsd.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rsd.c
rename to ffmpeg-2-8-12/libavformat/rsd.c
diff --git a/ffmpeg-2-8-11/libavformat/rso.c b/ffmpeg-2-8-12/libavformat/rso.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rso.c
rename to ffmpeg-2-8-12/libavformat/rso.c
diff --git a/ffmpeg-2-8-11/libavformat/rso.h b/ffmpeg-2-8-12/libavformat/rso.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rso.h
rename to ffmpeg-2-8-12/libavformat/rso.h
diff --git a/ffmpeg-2-8-11/libavformat/rsodec.c b/ffmpeg-2-8-12/libavformat/rsodec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rsodec.c
rename to ffmpeg-2-8-12/libavformat/rsodec.c
diff --git a/ffmpeg-2-8-11/libavformat/rsoenc.c b/ffmpeg-2-8-12/libavformat/rsoenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rsoenc.c
rename to ffmpeg-2-8-12/libavformat/rsoenc.c
diff --git a/ffmpeg-2-8-11/libavformat/rtmp.h b/ffmpeg-2-8-12/libavformat/rtmp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtmp.h
rename to ffmpeg-2-8-12/libavformat/rtmp.h
diff --git a/ffmpeg-2-8-11/libavformat/rtmpcrypt.c b/ffmpeg-2-8-12/libavformat/rtmpcrypt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtmpcrypt.c
rename to ffmpeg-2-8-12/libavformat/rtmpcrypt.c
diff --git a/ffmpeg-2-8-11/libavformat/rtmpcrypt.h b/ffmpeg-2-8-12/libavformat/rtmpcrypt.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtmpcrypt.h
rename to ffmpeg-2-8-12/libavformat/rtmpcrypt.h
diff --git a/ffmpeg-2-8-11/libavformat/rtmpdh.c b/ffmpeg-2-8-12/libavformat/rtmpdh.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtmpdh.c
rename to ffmpeg-2-8-12/libavformat/rtmpdh.c
diff --git a/ffmpeg-2-8-11/libavformat/rtmpdh.h b/ffmpeg-2-8-12/libavformat/rtmpdh.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtmpdh.h
rename to ffmpeg-2-8-12/libavformat/rtmpdh.h
diff --git a/ffmpeg-2-8-11/libavformat/rtmphttp.c b/ffmpeg-2-8-12/libavformat/rtmphttp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtmphttp.c
rename to ffmpeg-2-8-12/libavformat/rtmphttp.c
diff --git a/ffmpeg-2-8-11/libavformat/rtmppkt.c b/ffmpeg-2-8-12/libavformat/rtmppkt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtmppkt.c
rename to ffmpeg-2-8-12/libavformat/rtmppkt.c
diff --git a/ffmpeg-2-8-11/libavformat/rtmppkt.h b/ffmpeg-2-8-12/libavformat/rtmppkt.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtmppkt.h
rename to ffmpeg-2-8-12/libavformat/rtmppkt.h
diff --git a/ffmpeg-2-8-11/libavformat/rtmpproto.c b/ffmpeg-2-8-12/libavformat/rtmpproto.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtmpproto.c
rename to ffmpeg-2-8-12/libavformat/rtmpproto.c
diff --git a/ffmpeg-2-8-11/libavformat/rtp.c b/ffmpeg-2-8-12/libavformat/rtp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtp.c
rename to ffmpeg-2-8-12/libavformat/rtp.c
diff --git a/ffmpeg-2-8-11/libavformat/rtp.h b/ffmpeg-2-8-12/libavformat/rtp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtp.h
rename to ffmpeg-2-8-12/libavformat/rtp.h
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec.c b/ffmpeg-2-8-12/libavformat/rtpdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec.c
rename to ffmpeg-2-8-12/libavformat/rtpdec.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec.h b/ffmpeg-2-8-12/libavformat/rtpdec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec.h
rename to ffmpeg-2-8-12/libavformat/rtpdec.h
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_ac3.c b/ffmpeg-2-8-12/libavformat/rtpdec_ac3.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_ac3.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_ac3.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_amr.c b/ffmpeg-2-8-12/libavformat/rtpdec_amr.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_amr.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_amr.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_asf.c b/ffmpeg-2-8-12/libavformat/rtpdec_asf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_asf.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_asf.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_dv.c b/ffmpeg-2-8-12/libavformat/rtpdec_dv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_dv.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_dv.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_formats.h b/ffmpeg-2-8-12/libavformat/rtpdec_formats.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_formats.h
rename to ffmpeg-2-8-12/libavformat/rtpdec_formats.h
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_g726.c b/ffmpeg-2-8-12/libavformat/rtpdec_g726.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_g726.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_g726.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_h261.c b/ffmpeg-2-8-12/libavformat/rtpdec_h261.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_h261.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_h261.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_h263.c b/ffmpeg-2-8-12/libavformat/rtpdec_h263.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_h263.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_h263.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_h263_rfc2190.c b/ffmpeg-2-8-12/libavformat/rtpdec_h263_rfc2190.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_h263_rfc2190.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_h263_rfc2190.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_h264.c b/ffmpeg-2-8-12/libavformat/rtpdec_h264.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_h264.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_h264.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_hevc.c b/ffmpeg-2-8-12/libavformat/rtpdec_hevc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_hevc.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_hevc.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_ilbc.c b/ffmpeg-2-8-12/libavformat/rtpdec_ilbc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_ilbc.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_ilbc.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_jpeg.c b/ffmpeg-2-8-12/libavformat/rtpdec_jpeg.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_jpeg.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_jpeg.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_latm.c b/ffmpeg-2-8-12/libavformat/rtpdec_latm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_latm.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_latm.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_mpa_robust.c b/ffmpeg-2-8-12/libavformat/rtpdec_mpa_robust.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_mpa_robust.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_mpa_robust.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_mpeg12.c b/ffmpeg-2-8-12/libavformat/rtpdec_mpeg12.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_mpeg12.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_mpeg12.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_mpeg4.c b/ffmpeg-2-8-12/libavformat/rtpdec_mpeg4.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_mpeg4.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_mpeg4.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_mpegts.c b/ffmpeg-2-8-12/libavformat/rtpdec_mpegts.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_mpegts.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_mpegts.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_qcelp.c b/ffmpeg-2-8-12/libavformat/rtpdec_qcelp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_qcelp.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_qcelp.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_qdm2.c b/ffmpeg-2-8-12/libavformat/rtpdec_qdm2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_qdm2.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_qdm2.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_qt.c b/ffmpeg-2-8-12/libavformat/rtpdec_qt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_qt.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_qt.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_svq3.c b/ffmpeg-2-8-12/libavformat/rtpdec_svq3.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_svq3.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_svq3.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_vp8.c b/ffmpeg-2-8-12/libavformat/rtpdec_vp8.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_vp8.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_vp8.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_vp9.c b/ffmpeg-2-8-12/libavformat/rtpdec_vp9.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_vp9.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_vp9.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpdec_xiph.c b/ffmpeg-2-8-12/libavformat/rtpdec_xiph.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpdec_xiph.c
rename to ffmpeg-2-8-12/libavformat/rtpdec_xiph.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc.c b/ffmpeg-2-8-12/libavformat/rtpenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc.c
rename to ffmpeg-2-8-12/libavformat/rtpenc.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc.h b/ffmpeg-2-8-12/libavformat/rtpenc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc.h
rename to ffmpeg-2-8-12/libavformat/rtpenc.h
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc_aac.c b/ffmpeg-2-8-12/libavformat/rtpenc_aac.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc_aac.c
rename to ffmpeg-2-8-12/libavformat/rtpenc_aac.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc_amr.c b/ffmpeg-2-8-12/libavformat/rtpenc_amr.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc_amr.c
rename to ffmpeg-2-8-12/libavformat/rtpenc_amr.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc_chain.c b/ffmpeg-2-8-12/libavformat/rtpenc_chain.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc_chain.c
rename to ffmpeg-2-8-12/libavformat/rtpenc_chain.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc_chain.h b/ffmpeg-2-8-12/libavformat/rtpenc_chain.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc_chain.h
rename to ffmpeg-2-8-12/libavformat/rtpenc_chain.h
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc_h261.c b/ffmpeg-2-8-12/libavformat/rtpenc_h261.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc_h261.c
rename to ffmpeg-2-8-12/libavformat/rtpenc_h261.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc_h263.c b/ffmpeg-2-8-12/libavformat/rtpenc_h263.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc_h263.c
rename to ffmpeg-2-8-12/libavformat/rtpenc_h263.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc_h263_rfc2190.c b/ffmpeg-2-8-12/libavformat/rtpenc_h263_rfc2190.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc_h263_rfc2190.c
rename to ffmpeg-2-8-12/libavformat/rtpenc_h263_rfc2190.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc_h264_hevc.c b/ffmpeg-2-8-12/libavformat/rtpenc_h264_hevc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc_h264_hevc.c
rename to ffmpeg-2-8-12/libavformat/rtpenc_h264_hevc.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc_jpeg.c b/ffmpeg-2-8-12/libavformat/rtpenc_jpeg.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc_jpeg.c
rename to ffmpeg-2-8-12/libavformat/rtpenc_jpeg.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc_latm.c b/ffmpeg-2-8-12/libavformat/rtpenc_latm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc_latm.c
rename to ffmpeg-2-8-12/libavformat/rtpenc_latm.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc_mpegts.c b/ffmpeg-2-8-12/libavformat/rtpenc_mpegts.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc_mpegts.c
rename to ffmpeg-2-8-12/libavformat/rtpenc_mpegts.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc_mpv.c b/ffmpeg-2-8-12/libavformat/rtpenc_mpv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc_mpv.c
rename to ffmpeg-2-8-12/libavformat/rtpenc_mpv.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc_vp8.c b/ffmpeg-2-8-12/libavformat/rtpenc_vp8.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc_vp8.c
rename to ffmpeg-2-8-12/libavformat/rtpenc_vp8.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpenc_xiph.c b/ffmpeg-2-8-12/libavformat/rtpenc_xiph.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpenc_xiph.c
rename to ffmpeg-2-8-12/libavformat/rtpenc_xiph.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpproto.c b/ffmpeg-2-8-12/libavformat/rtpproto.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpproto.c
rename to ffmpeg-2-8-12/libavformat/rtpproto.c
diff --git a/ffmpeg-2-8-11/libavformat/rtpproto.h b/ffmpeg-2-8-12/libavformat/rtpproto.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtpproto.h
rename to ffmpeg-2-8-12/libavformat/rtpproto.h
diff --git a/ffmpeg-2-8-11/libavformat/rtsp.c b/ffmpeg-2-8-12/libavformat/rtsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtsp.c
rename to ffmpeg-2-8-12/libavformat/rtsp.c
diff --git a/ffmpeg-2-8-11/libavformat/rtsp.h b/ffmpeg-2-8-12/libavformat/rtsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtsp.h
rename to ffmpeg-2-8-12/libavformat/rtsp.h
diff --git a/ffmpeg-2-8-11/libavformat/rtspcodes.h b/ffmpeg-2-8-12/libavformat/rtspcodes.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtspcodes.h
rename to ffmpeg-2-8-12/libavformat/rtspcodes.h
diff --git a/ffmpeg-2-8-11/libavformat/rtspdec.c b/ffmpeg-2-8-12/libavformat/rtspdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtspdec.c
rename to ffmpeg-2-8-12/libavformat/rtspdec.c
diff --git a/ffmpeg-2-8-11/libavformat/rtspenc.c b/ffmpeg-2-8-12/libavformat/rtspenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/rtspenc.c
rename to ffmpeg-2-8-12/libavformat/rtspenc.c
diff --git a/ffmpeg-2-8-11/libavformat/samidec.c b/ffmpeg-2-8-12/libavformat/samidec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/samidec.c
rename to ffmpeg-2-8-12/libavformat/samidec.c
diff --git a/ffmpeg-2-8-11/libavformat/sapdec.c b/ffmpeg-2-8-12/libavformat/sapdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/sapdec.c
rename to ffmpeg-2-8-12/libavformat/sapdec.c
diff --git a/ffmpeg-2-8-11/libavformat/sapenc.c b/ffmpeg-2-8-12/libavformat/sapenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/sapenc.c
rename to ffmpeg-2-8-12/libavformat/sapenc.c
diff --git a/ffmpeg-2-8-11/libavformat/sauce.c b/ffmpeg-2-8-12/libavformat/sauce.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/sauce.c
rename to ffmpeg-2-8-12/libavformat/sauce.c
diff --git a/ffmpeg-2-8-11/libavformat/sauce.h b/ffmpeg-2-8-12/libavformat/sauce.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/sauce.h
rename to ffmpeg-2-8-12/libavformat/sauce.h
diff --git a/ffmpeg-2-8-11/libavformat/sbgdec.c b/ffmpeg-2-8-12/libavformat/sbgdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/sbgdec.c
rename to ffmpeg-2-8-12/libavformat/sbgdec.c
diff --git a/ffmpeg-2-8-11/libavformat/sctp.c b/ffmpeg-2-8-12/libavformat/sctp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/sctp.c
rename to ffmpeg-2-8-12/libavformat/sctp.c
diff --git a/ffmpeg-2-8-11/libavformat/sdp.c b/ffmpeg-2-8-12/libavformat/sdp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/sdp.c
rename to ffmpeg-2-8-12/libavformat/sdp.c
diff --git a/ffmpeg-2-8-11/libavformat/sdr2.c b/ffmpeg-2-8-12/libavformat/sdr2.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/sdr2.c
rename to ffmpeg-2-8-12/libavformat/sdr2.c
diff --git a/ffmpeg-2-8-11/libavformat/seek-test.c b/ffmpeg-2-8-12/libavformat/seek-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/seek-test.c
rename to ffmpeg-2-8-12/libavformat/seek-test.c
diff --git a/ffmpeg-2-8-11/libavformat/segafilm.c b/ffmpeg-2-8-12/libavformat/segafilm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/segafilm.c
rename to ffmpeg-2-8-12/libavformat/segafilm.c
diff --git a/ffmpeg-2-8-11/libavformat/segment.c b/ffmpeg-2-8-12/libavformat/segment.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/segment.c
rename to ffmpeg-2-8-12/libavformat/segment.c
diff --git a/ffmpeg-2-8-11/libavformat/sierravmd.c b/ffmpeg-2-8-12/libavformat/sierravmd.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/sierravmd.c
rename to ffmpeg-2-8-12/libavformat/sierravmd.c
diff --git a/ffmpeg-2-8-11/libavformat/siff.c b/ffmpeg-2-8-12/libavformat/siff.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/siff.c
rename to ffmpeg-2-8-12/libavformat/siff.c
diff --git a/ffmpeg-2-8-11/libavformat/smacker.c b/ffmpeg-2-8-12/libavformat/smacker.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/smacker.c
rename to ffmpeg-2-8-12/libavformat/smacker.c
diff --git a/ffmpeg-2-8-11/libavformat/smjpeg.c b/ffmpeg-2-8-12/libavformat/smjpeg.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/smjpeg.c
rename to ffmpeg-2-8-12/libavformat/smjpeg.c
diff --git a/ffmpeg-2-8-11/libavformat/smjpeg.h b/ffmpeg-2-8-12/libavformat/smjpeg.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/smjpeg.h
rename to ffmpeg-2-8-12/libavformat/smjpeg.h
diff --git a/ffmpeg-2-8-11/libavformat/smjpegdec.c b/ffmpeg-2-8-12/libavformat/smjpegdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/smjpegdec.c
rename to ffmpeg-2-8-12/libavformat/smjpegdec.c
diff --git a/ffmpeg-2-8-11/libavformat/smjpegenc.c b/ffmpeg-2-8-12/libavformat/smjpegenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/smjpegenc.c
rename to ffmpeg-2-8-12/libavformat/smjpegenc.c
diff --git a/ffmpeg-2-8-11/libavformat/smoothstreamingenc.c b/ffmpeg-2-8-12/libavformat/smoothstreamingenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/smoothstreamingenc.c
rename to ffmpeg-2-8-12/libavformat/smoothstreamingenc.c
diff --git a/ffmpeg-2-8-11/libavformat/smush.c b/ffmpeg-2-8-12/libavformat/smush.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/smush.c
rename to ffmpeg-2-8-12/libavformat/smush.c
diff --git a/ffmpeg-2-8-11/libavformat/sol.c b/ffmpeg-2-8-12/libavformat/sol.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/sol.c
rename to ffmpeg-2-8-12/libavformat/sol.c
diff --git a/ffmpeg-2-8-11/libavformat/sox.h b/ffmpeg-2-8-12/libavformat/sox.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/sox.h
rename to ffmpeg-2-8-12/libavformat/sox.h
diff --git a/ffmpeg-2-8-11/libavformat/soxdec.c b/ffmpeg-2-8-12/libavformat/soxdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/soxdec.c
rename to ffmpeg-2-8-12/libavformat/soxdec.c
diff --git a/ffmpeg-2-8-11/libavformat/soxenc.c b/ffmpeg-2-8-12/libavformat/soxenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/soxenc.c
rename to ffmpeg-2-8-12/libavformat/soxenc.c
diff --git a/ffmpeg-2-8-11/libavformat/spdif.c b/ffmpeg-2-8-12/libavformat/spdif.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/spdif.c
rename to ffmpeg-2-8-12/libavformat/spdif.c
diff --git a/ffmpeg-2-8-11/libavformat/spdif.h b/ffmpeg-2-8-12/libavformat/spdif.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/spdif.h
rename to ffmpeg-2-8-12/libavformat/spdif.h
diff --git a/ffmpeg-2-8-11/libavformat/spdifdec.c b/ffmpeg-2-8-12/libavformat/spdifdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/spdifdec.c
rename to ffmpeg-2-8-12/libavformat/spdifdec.c
diff --git a/ffmpeg-2-8-11/libavformat/spdifenc.c b/ffmpeg-2-8-12/libavformat/spdifenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/spdifenc.c
rename to ffmpeg-2-8-12/libavformat/spdifenc.c
diff --git a/ffmpeg-2-8-11/libavformat/srtdec.c b/ffmpeg-2-8-12/libavformat/srtdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/srtdec.c
rename to ffmpeg-2-8-12/libavformat/srtdec.c
diff --git a/ffmpeg-2-8-11/libavformat/srtenc.c b/ffmpeg-2-8-12/libavformat/srtenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/srtenc.c
rename to ffmpeg-2-8-12/libavformat/srtenc.c
diff --git a/ffmpeg-2-8-11/libavformat/srtp.c b/ffmpeg-2-8-12/libavformat/srtp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/srtp.c
rename to ffmpeg-2-8-12/libavformat/srtp.c
diff --git a/ffmpeg-2-8-11/libavformat/srtp.h b/ffmpeg-2-8-12/libavformat/srtp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/srtp.h
rename to ffmpeg-2-8-12/libavformat/srtp.h
diff --git a/ffmpeg-2-8-11/libavformat/srtpproto.c b/ffmpeg-2-8-12/libavformat/srtpproto.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/srtpproto.c
rename to ffmpeg-2-8-12/libavformat/srtpproto.c
diff --git a/ffmpeg-2-8-11/libavformat/stldec.c b/ffmpeg-2-8-12/libavformat/stldec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/stldec.c
rename to ffmpeg-2-8-12/libavformat/stldec.c
diff --git a/ffmpeg-2-8-11/libavformat/subfile.c b/ffmpeg-2-8-12/libavformat/subfile.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/subfile.c
rename to ffmpeg-2-8-12/libavformat/subfile.c
diff --git a/ffmpeg-2-8-11/libavformat/subtitles.c b/ffmpeg-2-8-12/libavformat/subtitles.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/subtitles.c
rename to ffmpeg-2-8-12/libavformat/subtitles.c
diff --git a/ffmpeg-2-8-11/libavformat/subtitles.h b/ffmpeg-2-8-12/libavformat/subtitles.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/subtitles.h
rename to ffmpeg-2-8-12/libavformat/subtitles.h
diff --git a/ffmpeg-2-8-11/libavformat/subviewer1dec.c b/ffmpeg-2-8-12/libavformat/subviewer1dec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/subviewer1dec.c
rename to ffmpeg-2-8-12/libavformat/subviewer1dec.c
diff --git a/ffmpeg-2-8-11/libavformat/subviewerdec.c b/ffmpeg-2-8-12/libavformat/subviewerdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/subviewerdec.c
rename to ffmpeg-2-8-12/libavformat/subviewerdec.c
diff --git a/ffmpeg-2-8-11/libavformat/supdec.c b/ffmpeg-2-8-12/libavformat/supdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/supdec.c
rename to ffmpeg-2-8-12/libavformat/supdec.c
diff --git a/ffmpeg-2-8-11/libavformat/swf.c b/ffmpeg-2-8-12/libavformat/swf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/swf.c
rename to ffmpeg-2-8-12/libavformat/swf.c
diff --git a/ffmpeg-2-8-11/libavformat/swf.h b/ffmpeg-2-8-12/libavformat/swf.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/swf.h
rename to ffmpeg-2-8-12/libavformat/swf.h
diff --git a/ffmpeg-2-8-11/libavformat/swfdec.c b/ffmpeg-2-8-12/libavformat/swfdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/swfdec.c
rename to ffmpeg-2-8-12/libavformat/swfdec.c
diff --git a/ffmpeg-2-8-11/libavformat/swfenc.c b/ffmpeg-2-8-12/libavformat/swfenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/swfenc.c
rename to ffmpeg-2-8-12/libavformat/swfenc.c
diff --git a/ffmpeg-2-8-11/libavformat/takdec.c b/ffmpeg-2-8-12/libavformat/takdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/takdec.c
rename to ffmpeg-2-8-12/libavformat/takdec.c
diff --git a/ffmpeg-2-8-11/libavformat/tcp.c b/ffmpeg-2-8-12/libavformat/tcp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/tcp.c
rename to ffmpeg-2-8-12/libavformat/tcp.c
diff --git a/ffmpeg-2-8-11/libavformat/tedcaptionsdec.c b/ffmpeg-2-8-12/libavformat/tedcaptionsdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/tedcaptionsdec.c
rename to ffmpeg-2-8-12/libavformat/tedcaptionsdec.c
diff --git a/ffmpeg-2-8-11/libavformat/tee.c b/ffmpeg-2-8-12/libavformat/tee.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/tee.c
rename to ffmpeg-2-8-12/libavformat/tee.c
diff --git a/ffmpeg-2-8-11/libavformat/thp.c b/ffmpeg-2-8-12/libavformat/thp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/thp.c
rename to ffmpeg-2-8-12/libavformat/thp.c
diff --git a/ffmpeg-2-8-11/libavformat/tiertexseq.c b/ffmpeg-2-8-12/libavformat/tiertexseq.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/tiertexseq.c
rename to ffmpeg-2-8-12/libavformat/tiertexseq.c
diff --git a/ffmpeg-2-8-11/libavformat/tls.c b/ffmpeg-2-8-12/libavformat/tls.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/tls.c
rename to ffmpeg-2-8-12/libavformat/tls.c
diff --git a/ffmpeg-2-8-11/libavformat/tls.h b/ffmpeg-2-8-12/libavformat/tls.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/tls.h
rename to ffmpeg-2-8-12/libavformat/tls.h
diff --git a/ffmpeg-2-8-11/libavformat/tls_gnutls.c b/ffmpeg-2-8-12/libavformat/tls_gnutls.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/tls_gnutls.c
rename to ffmpeg-2-8-12/libavformat/tls_gnutls.c
diff --git a/ffmpeg-2-8-11/libavformat/tls_openssl.c b/ffmpeg-2-8-12/libavformat/tls_openssl.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/tls_openssl.c
rename to ffmpeg-2-8-12/libavformat/tls_openssl.c
diff --git a/ffmpeg-2-8-11/libavformat/tls_securetransport.c b/ffmpeg-2-8-12/libavformat/tls_securetransport.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/tls_securetransport.c
rename to ffmpeg-2-8-12/libavformat/tls_securetransport.c
diff --git a/ffmpeg-2-8-11/libavformat/tmv.c b/ffmpeg-2-8-12/libavformat/tmv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/tmv.c
rename to ffmpeg-2-8-12/libavformat/tmv.c
diff --git a/ffmpeg-2-8-11/libavformat/tta.c b/ffmpeg-2-8-12/libavformat/tta.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/tta.c
rename to ffmpeg-2-8-12/libavformat/tta.c
diff --git a/ffmpeg-2-8-11/libavformat/tty.c b/ffmpeg-2-8-12/libavformat/tty.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/tty.c
rename to ffmpeg-2-8-12/libavformat/tty.c
diff --git a/ffmpeg-2-8-11/libavformat/txd.c b/ffmpeg-2-8-12/libavformat/txd.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/txd.c
rename to ffmpeg-2-8-12/libavformat/txd.c
diff --git a/ffmpeg-2-8-11/libavformat/udp.c b/ffmpeg-2-8-12/libavformat/udp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/udp.c
rename to ffmpeg-2-8-12/libavformat/udp.c
diff --git a/ffmpeg-2-8-11/libavformat/uncodedframecrcenc.c b/ffmpeg-2-8-12/libavformat/uncodedframecrcenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/uncodedframecrcenc.c
rename to ffmpeg-2-8-12/libavformat/uncodedframecrcenc.c
diff --git a/ffmpeg-2-8-11/libavformat/unix.c b/ffmpeg-2-8-12/libavformat/unix.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/unix.c
rename to ffmpeg-2-8-12/libavformat/unix.c
diff --git a/ffmpeg-2-8-11/libavformat/url-test.c b/ffmpeg-2-8-12/libavformat/url-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/url-test.c
rename to ffmpeg-2-8-12/libavformat/url-test.c
diff --git a/ffmpeg-2-8-11/libavformat/url.c b/ffmpeg-2-8-12/libavformat/url.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/url.c
rename to ffmpeg-2-8-12/libavformat/url.c
diff --git a/ffmpeg-2-8-11/libavformat/url.h b/ffmpeg-2-8-12/libavformat/url.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/url.h
rename to ffmpeg-2-8-12/libavformat/url.h
diff --git a/ffmpeg-2-8-11/libavformat/urldecode.c b/ffmpeg-2-8-12/libavformat/urldecode.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/urldecode.c
rename to ffmpeg-2-8-12/libavformat/urldecode.c
diff --git a/ffmpeg-2-8-11/libavformat/urldecode.h b/ffmpeg-2-8-12/libavformat/urldecode.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/urldecode.h
rename to ffmpeg-2-8-12/libavformat/urldecode.h
diff --git a/ffmpeg-2-8-12/libavformat/utils.c b/ffmpeg-2-8-12/libavformat/utils.c
new file mode 100644
index 0000000..a88d959
--- /dev/null
+++ b/ffmpeg-2-8-12/libavformat/utils.c
@@ -0,0 +1,4622 @@
+/*
+ * various utility functions for use within FFmpeg
+ * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdarg.h>
+#include <stdint.h>
+
+#include "config.h"
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/dict.h"
+#include "libavutil/internal.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/time.h"
+#include "libavutil/timestamp.h"
+
+#include "libavcodec/bytestream.h"
+#include "libavcodec/internal.h"
+#include "libavcodec/raw.h"
+
+#include "audiointerleave.h"
+#include "avformat.h"
+#include "avio_internal.h"
+#include "id3v2.h"
+#include "internal.h"
+#include "metadata.h"
+#if CONFIG_NETWORK
+#include "network.h"
+#endif
+#include "riff.h"
+#include "url.h"
+
+#include "libavutil/ffversion.h"
+const char av_format_ffversion[] = "FFmpeg version " FFMPEG_VERSION;
+
+/**
+ * @file
+ * various utility functions for use within FFmpeg
+ */
+
+unsigned avformat_version(void)
+{
+ av_assert0(LIBAVFORMAT_VERSION_MICRO >= 100);
+ return LIBAVFORMAT_VERSION_INT;
+}
+
+const char *avformat_configuration(void)
+{
+ return FFMPEG_CONFIGURATION;
+}
+
+const char *avformat_license(void)
+{
+#define LICENSE_PREFIX "libavformat license: "
+ return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+}
+
+#define RELATIVE_TS_BASE (INT64_MAX - (1LL<<48))
+
+static int is_relative(int64_t ts) {
+ return ts > (RELATIVE_TS_BASE - (1LL<<48));
+}
+
+/**
+ * Wrap a given time stamp, if there is an indication for an overflow
+ *
+ * @param st stream
+ * @param timestamp the time stamp to wrap
+ * @return resulting time stamp
+ */
+static int64_t wrap_timestamp(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)
+ return timestamp + (1ULL << st->pts_wrap_bits);
+ else if (st->pts_wrap_behavior == AV_PTS_WRAP_SUB_OFFSET &&
+ timestamp >= st->pts_wrap_reference)
+ return timestamp - (1ULL << st->pts_wrap_bits);
+ }
+ return timestamp;
+}
+
+MAKE_ACCESSORS(AVStream, stream, AVRational, r_frame_rate)
+MAKE_ACCESSORS(AVStream, stream, char *, recommended_encoder_configuration)
+MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, video_codec)
+MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, audio_codec)
+MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, subtitle_codec)
+MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, data_codec)
+MAKE_ACCESSORS(AVFormatContext, format, int, metadata_header_padding)
+MAKE_ACCESSORS(AVFormatContext, format, void *, opaque)
+MAKE_ACCESSORS(AVFormatContext, format, av_format_control_message, control_message_cb)
+MAKE_ACCESSORS(AVFormatContext, format, AVOpenCallback, open_cb)
+
+int64_t av_stream_get_end_pts(const AVStream *st)
+{
+ if (st->priv_pts) {
+ return st->priv_pts->val;
+ } else
+ return AV_NOPTS_VALUE;
+}
+
+struct AVCodecParserContext *av_stream_get_parser(const AVStream *st)
+{
+ return st->parser;
+}
+
+void av_format_inject_global_side_data(AVFormatContext *s)
+{
+ int i;
+ 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;
+ }
+}
+
+int ff_copy_whitelists(AVFormatContext *dst, AVFormatContext *src)
+{
+ av_assert0(!dst->codec_whitelist && !dst->format_whitelist);
+ dst-> codec_whitelist = av_strdup(src->codec_whitelist);
+ dst->format_whitelist = av_strdup(src->format_whitelist);
+ if ( (src-> codec_whitelist && !dst-> codec_whitelist)
+ || (src->format_whitelist && !dst->format_whitelist)) {
+ av_log(dst, AV_LOG_ERROR, "Failed to duplicate whitelist\n");
+ return AVERROR(ENOMEM);
+ }
+ return 0;
+}
+
+static const AVCodec *find_decoder(AVFormatContext *s, AVStream *st, enum AVCodecID codec_id)
+{
+ if (st->codec->codec)
+ return st->codec->codec;
+
+ switch (st->codec->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ if (s->video_codec) return s->video_codec;
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ if (s->audio_codec) return s->audio_codec;
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ if (s->subtitle_codec) return s->subtitle_codec;
+ break;
+ }
+
+ return avcodec_find_decoder(codec_id);
+}
+
+int av_format_get_probe_score(const AVFormatContext *s)
+{
+ return s->probe_score;
+}
+
+/* an arbitrarily chosen "sane" max packet size -- 50M */
+#define SANE_CHUNK_SIZE (50000000)
+
+int ffio_limit(AVIOContext *s, int size)
+{
+ if (s->maxsize>= 0) {
+ int64_t remaining= s->maxsize - avio_tell(s);
+ if (remaining < size) {
+ int64_t newsize = avio_size(s);
+ if (!s->maxsize || s->maxsize<newsize)
+ s->maxsize = newsize - !newsize;
+ remaining= s->maxsize - avio_tell(s);
+ remaining= FFMAX(remaining, 0);
+ }
+
+ 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;
+ }
+ }
+ return size;
+}
+
+/* Read the data in sane-sized chunks and append to pkt.
+ * Return the number of bytes read or an error. */
+static int append_packet_chunked(AVIOContext *s, AVPacket *pkt, int size)
+{
+ int64_t orig_pos = pkt->pos; // av_grow_packet might reset pos
+ int orig_size = pkt->size;
+ int ret;
+
+ do {
+ int prev_size = pkt->size;
+ int read_size;
+
+ /* When the caller requests a lot of data, limit it to the amount
+ * left in file or SANE_CHUNK_SIZE when it is not known. */
+ read_size = size;
+ if (read_size > SANE_CHUNK_SIZE/10) {
+ read_size = ffio_limit(s, read_size);
+ // If filesize/maxsize is unknown, limit to SANE_CHUNK_SIZE
+ if (s->maxsize < 0)
+ read_size = FFMIN(read_size, SANE_CHUNK_SIZE);
+ }
+
+ ret = av_grow_packet(pkt, read_size);
+ if (ret < 0)
+ break;
+
+ ret = avio_read(s, pkt->data + prev_size, read_size);
+ if (ret != read_size) {
+ av_shrink_packet(pkt, prev_size + FFMAX(ret, 0));
+ break;
+ }
+
+ size -= read_size;
+ } while (size > 0);
+ if (size > 0)
+ pkt->flags |= AV_PKT_FLAG_CORRUPT;
+
+ pkt->pos = orig_pos;
+ if (!pkt->size)
+ av_free_packet(pkt);
+ return pkt->size > orig_size ? pkt->size - orig_size : ret;
+}
+
+int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
+{
+ av_init_packet(pkt);
+ pkt->data = NULL;
+ pkt->size = 0;
+ pkt->pos = avio_tell(s);
+
+ return append_packet_chunked(s, pkt, size);
+}
+
+int av_append_packet(AVIOContext *s, AVPacket *pkt, int size)
+{
+ if (!pkt->size)
+ return av_get_packet(s, pkt, size);
+ return append_packet_chunked(s, pkt, size);
+}
+
+int av_filename_number_test(const char *filename)
+{
+ char buf[1024];
+ return filename &&
+ (av_get_frame_filename(buf, sizeof(buf), filename, 1) >= 0);
+}
+
+static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st,
+ AVProbeData *pd)
+{
+ static const struct {
+ const char *name;
+ enum AVCodecID id;
+ enum AVMediaType type;
+ } fmt_id_type[] = {
+ { "aac", AV_CODEC_ID_AAC, AVMEDIA_TYPE_AUDIO },
+ { "ac3", AV_CODEC_ID_AC3, AVMEDIA_TYPE_AUDIO },
+ { "dts", AV_CODEC_ID_DTS, AVMEDIA_TYPE_AUDIO },
+ { "dvbsub", AV_CODEC_ID_DVB_SUBTITLE,AVMEDIA_TYPE_SUBTITLE },
+ { "eac3", AV_CODEC_ID_EAC3, AVMEDIA_TYPE_AUDIO },
+ { "h264", AV_CODEC_ID_H264, AVMEDIA_TYPE_VIDEO },
+ { "hevc", AV_CODEC_ID_HEVC, AVMEDIA_TYPE_VIDEO },
+ { "loas", AV_CODEC_ID_AAC_LATM, AVMEDIA_TYPE_AUDIO },
+ { "m4v", AV_CODEC_ID_MPEG4, AVMEDIA_TYPE_VIDEO },
+ { "mp3", AV_CODEC_ID_MP3, AVMEDIA_TYPE_AUDIO },
+ { "mpegvideo", AV_CODEC_ID_MPEG2VIDEO, AVMEDIA_TYPE_VIDEO },
+ { 0 }
+ };
+ int score;
+ AVInputFormat *fmt = av_probe_input_format3(pd, 1, &score);
+
+ if (fmt && st->request_probe <= score) {
+ int i;
+ av_log(s, AV_LOG_DEBUG,
+ "Probe with size=%d, packets=%d detected %s with score=%d\n",
+ pd->buf_size, MAX_PROBE_PACKETS - st->probe_packets,
+ fmt->name, score);
+ for (i = 0; fmt_id_type[i].name; i++) {
+ if (!strcmp(fmt->name, fmt_id_type[i].name)) {
+ st->codec->codec_id = fmt_id_type[i].id;
+ st->codec->codec_type = fmt_id_type[i].type;
+ return score;
+ }
+ }
+ }
+ return 0;
+}
+
+/************************************************************/
+/* input media file */
+
+int av_demuxer_open(AVFormatContext *ic) {
+ int err;
+
+ if (ic->format_whitelist && av_match_list(ic->iformat->name, ic->format_whitelist, ',') <= 0) {
+ av_log(ic, AV_LOG_ERROR, "Format not on whitelist\n");
+ return AVERROR(EINVAL);
+ }
+
+ if (ic->iformat->read_header) {
+ err = ic->iformat->read_header(ic);
+ if (err < 0)
+ return err;
+ }
+
+ if (ic->pb && !ic->internal->data_offset)
+ ic->internal->data_offset = avio_tell(ic->pb);
+
+ return 0;
+}
+
+/* Open input file and probe the format if necessary. */
+static int init_input(AVFormatContext *s, const char *filename,
+ AVDictionary **options)
+{
+ int ret;
+ AVProbeData pd = { filename, NULL, 0 };
+ int score = AVPROBE_SCORE_RETRY;
+
+ if (s->pb) {
+ s->flags |= AVFMT_FLAG_CUSTOM_IO;
+ if (!s->iformat)
+ return av_probe_input_buffer2(s->pb, &s->iformat, filename,
+ s, 0, s->format_probesize);
+ else if (s->iformat->flags & AVFMT_NOFILE)
+ av_log(s, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
+ "will be ignored with AVFMT_NOFILE format.\n");
+ return 0;
+ }
+
+ if ((s->iformat && s->iformat->flags & AVFMT_NOFILE) ||
+ (!s->iformat && (s->iformat = av_probe_input_format2(&pd, 0, &score))))
+ return score;
+
+ if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ | s->avio_flags,
+ &s->interrupt_callback, options)) < 0)
+ return ret;
+ if (s->iformat)
+ return 0;
+ return av_probe_input_buffer2(s->pb, &s->iformat, filename,
+ s, 0, s->format_probesize);
+}
+
+static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt,
+ AVPacketList **plast_pktl)
+{
+ AVPacketList *pktl = av_mallocz(sizeof(AVPacketList));
+ if (!pktl)
+ return NULL;
+
+ if (*packet_buffer)
+ (*plast_pktl)->next = pktl;
+ else
+ *packet_buffer = pktl;
+
+ /* Add the packet in the buffered packet list. */
+ *plast_pktl = pktl;
+ pktl->pkt = *pkt;
+ return &pktl->pkt;
+}
+
+int avformat_queue_attached_pictures(AVFormatContext *s)
+{
+ int i;
+ for (i = 0; i < s->nb_streams; i++)
+ if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC &&
+ s->streams[i]->discard < AVDISCARD_ALL) {
+ AVPacket copy = s->streams[i]->attached_pic;
+ if (copy.size <= 0) {
+ av_log(s, AV_LOG_WARNING,
+ "Attached picture on stream %d has invalid size, "
+ "ignoring\n", i);
+ continue;
+ }
+ copy.buf = av_buffer_ref(copy.buf);
+ if (!copy.buf)
+ return AVERROR(ENOMEM);
+
+ add_to_pktbuf(&s->internal->raw_packet_buffer, ©,
+ &s->internal->raw_packet_buffer_end);
+ }
+ return 0;
+}
+
+int avformat_open_input(AVFormatContext **ps, const char *filename,
+ AVInputFormat *fmt, AVDictionary **options)
+{
+ AVFormatContext *s = *ps;
+ int ret = 0;
+ AVDictionary *tmp = NULL;
+ ID3v2ExtraMeta *id3v2_extra_meta = NULL;
+
+ if (!s && !(s = avformat_alloc_context()))
+ return AVERROR(ENOMEM);
+ if (!s->av_class) {
+ av_log(NULL, AV_LOG_ERROR, "Input context has not been properly allocated by avformat_alloc_context() and is not NULL either\n");
+ return AVERROR(EINVAL);
+ }
+ if (fmt)
+ s->iformat = fmt;
+
+ if (options)
+ av_dict_copy(&tmp, *options, 0);
+
+ if (s->pb) // must be before any goto fail
+ s->flags |= AVFMT_FLAG_CUSTOM_IO;
+
+ if ((ret = av_opt_set_dict(s, &tmp)) < 0)
+ goto fail;
+
+ if ((ret = init_input(s, filename, &tmp)) < 0)
+ goto fail;
+ s->probe_score = ret;
+
+ if (s->format_whitelist && av_match_list(s->iformat->name, s->format_whitelist, ',') <= 0) {
+ av_log(s, AV_LOG_ERROR, "Format not on whitelist\n");
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+
+ avio_skip(s->pb, s->skip_initial_bytes);
+
+ /* Check filename in case an image number is expected. */
+ if (s->iformat->flags & AVFMT_NEEDNUMBER) {
+ if (!av_filename_number_test(filename)) {
+ ret = AVERROR(EINVAL);
+ goto fail;
+ }
+ }
+
+ s->duration = s->start_time = AV_NOPTS_VALUE;
+ av_strlcpy(s->filename, filename ? filename : "", sizeof(s->filename));
+
+ /* Allocate private data. */
+ if (s->iformat->priv_data_size > 0) {
+ if (!(s->priv_data = av_mallocz(s->iformat->priv_data_size))) {
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ if (s->iformat->priv_class) {
+ *(const AVClass **) s->priv_data = s->iformat->priv_class;
+ av_opt_set_defaults(s->priv_data);
+ if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0)
+ goto fail;
+ }
+ }
+
+ /* e.g. AVFMT_NOFILE formats will not have a AVIOContext */
+ if (s->pb)
+ ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, 0);
+
+ if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header)
+ if ((ret = s->iformat->read_header(s)) < 0)
+ goto fail;
+
+ if (id3v2_extra_meta) {
+ if (!strcmp(s->iformat->name, "mp3") || !strcmp(s->iformat->name, "aac") ||
+ !strcmp(s->iformat->name, "tta")) {
+ if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0)
+ goto fail;
+ } else
+ av_log(s, AV_LOG_DEBUG, "demuxer does not support additional id3 data, skipping\n");
+ }
+ ff_id3v2_free_extra_meta(&id3v2_extra_meta);
+
+ if ((ret = avformat_queue_attached_pictures(s)) < 0)
+ goto fail;
+
+ if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->pb && !s->internal->data_offset)
+ s->internal->data_offset = avio_tell(s->pb);
+
+ s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
+
+ if (options) {
+ av_dict_free(options);
+ *options = tmp;
+ }
+ *ps = s;
+ return 0;
+
+fail:
+ ff_id3v2_free_extra_meta(&id3v2_extra_meta);
+ av_dict_free(&tmp);
+ if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO))
+ avio_closep(&s->pb);
+ avformat_free_context(s);
+ *ps = NULL;
+ return ret;
+}
+
+/*******************************************************/
+
+static void force_codec_ids(AVFormatContext *s, AVStream *st)
+{
+ switch (st->codec->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ if (s->video_codec_id)
+ st->codec->codec_id = s->video_codec_id;
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ if (s->audio_codec_id)
+ st->codec->codec_id = s->audio_codec_id;
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ if (s->subtitle_codec_id)
+ st->codec->codec_id = s->subtitle_codec_id;
+ break;
+ }
+}
+
+static int probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt)
+{
+ if (st->request_probe>0) {
+ AVProbeData *pd = &st->probe_data;
+ int end;
+ av_log(s, AV_LOG_DEBUG, "probing stream %d pp:%d\n", st->index, st->probe_packets);
+ --st->probe_packets;
+
+ if (pkt) {
+ uint8_t *new_buf = av_realloc(pd->buf, pd->buf_size+pkt->size+AVPROBE_PADDING_SIZE);
+ if (!new_buf) {
+ av_log(s, AV_LOG_WARNING,
+ "Failed to reallocate probe buffer for stream %d\n",
+ st->index);
+ goto no_packet;
+ }
+ pd->buf = new_buf;
+ memcpy(pd->buf + pd->buf_size, pkt->data, pkt->size);
+ pd->buf_size += pkt->size;
+ memset(pd->buf + pd->buf_size, 0, AVPROBE_PADDING_SIZE);
+ } else {
+no_packet:
+ st->probe_packets = 0;
+ if (!pd->buf_size) {
+ av_log(s, AV_LOG_WARNING,
+ "nothing to probe for stream %d\n", st->index);
+ }
+ }
+
+ end= s->internal->raw_packet_buffer_remaining_size <= 0
+ || st->probe_packets<= 0;
+
+ if (end || av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)) {
+ int score = set_codec_from_probe_data(s, st, pd);
+ if ( (st->codec->codec_id != AV_CODEC_ID_NONE && score > AVPROBE_SCORE_STREAM_RETRY)
+ || end) {
+ pd->buf_size = 0;
+ av_freep(&pd->buf);
+ st->request_probe = -1;
+ if (st->codec->codec_id != AV_CODEC_ID_NONE) {
+ av_log(s, AV_LOG_DEBUG, "probed stream %d\n", st->index);
+ } else
+ av_log(s, AV_LOG_WARNING, "probed stream %d failed\n", st->index);
+ }
+ force_codec_ids(s, st);
+ }
+ }
+ return 0;
+}
+
+static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_index, AVPacket *pkt)
+{
+ int64_t ref = pkt->dts;
+ int i, pts_wrap_behavior;
+ int64_t pts_wrap_reference;
+ AVProgram *first_program;
+
+ 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)
+ return 0;
+ ref &= (1LL << st->pts_wrap_bits)-1;
+
+ // reference time stamp should be 60 s before first time stamp
+ pts_wrap_reference = ref - av_rescale(60, st->time_base.den, st->time_base.num);
+ // if first time stamp is not more than 1/8 and 60s before the wrap point, subtract rather than add wrap offset
+ pts_wrap_behavior = (ref < (1LL << st->pts_wrap_bits) - (1LL << st->pts_wrap_bits-3)) ||
+ (ref < (1LL << st->pts_wrap_bits) - av_rescale(60, st->time_base.den, st->time_base.num)) ?
+ AV_PTS_WRAP_ADD_OFFSET : AV_PTS_WRAP_SUB_OFFSET;
+
+ first_program = av_find_program_from_stream(s, NULL, stream_index);
+
+ 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) {
+ 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;
+ }
+ }
+ 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;
+ }
+ }
+ else {
+ AVProgram *program = first_program;
+ while (program) {
+ if (program->pts_wrap_reference != AV_NOPTS_VALUE) {
+ pts_wrap_reference = program->pts_wrap_reference;
+ pts_wrap_behavior = program->pts_wrap_behavior;
+ break;
+ }
+ program = av_find_program_from_stream(s, program, stream_index);
+ }
+
+ // update every program with differing pts_wrap_reference
+ program = first_program;
+ while (program) {
+ if (program->pts_wrap_reference != pts_wrap_reference) {
+ for (i = 0; i<program->nb_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;
+ }
+
+ program->pts_wrap_reference = pts_wrap_reference;
+ program->pts_wrap_behavior = pts_wrap_behavior;
+ }
+ program = av_find_program_from_stream(s, program, stream_index);
+ }
+ }
+ return 1;
+}
+
+int ff_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ int ret, i, err;
+ AVStream *st;
+
+ for (;;) {
+ AVPacketList *pktl = s->internal->raw_packet_buffer;
+
+ if (pktl) {
+ *pkt = pktl->pkt;
+ st = s->streams[pkt->stream_index];
+ if (s->internal->raw_packet_buffer_remaining_size <= 0)
+ if ((err = probe_codec(s, st, NULL)) < 0)
+ return err;
+ if (st->request_probe <= 0) {
+ s->internal->raw_packet_buffer = pktl->next;
+ s->internal->raw_packet_buffer_remaining_size += pkt->size;
+ av_free(pktl);
+ return 0;
+ }
+ }
+
+ pkt->data = NULL;
+ pkt->size = 0;
+ av_init_packet(pkt);
+ ret = s->iformat->read_packet(s, pkt);
+ if (ret < 0) {
+ if (!pktl || ret == AVERROR(EAGAIN))
+ return ret;
+ for (i = 0; i < s->nb_streams; i++) {
+ st = s->streams[i];
+ if (st->probe_packets || st->request_probe > 0)
+ if ((err = probe_codec(s, st, NULL)) < 0)
+ return err;
+ av_assert0(st->request_probe <= 0);
+ }
+ continue;
+ }
+
+ if ((s->flags & AVFMT_FLAG_DISCARD_CORRUPT) &&
+ (pkt->flags & AV_PKT_FLAG_CORRUPT)) {
+ av_log(s, AV_LOG_WARNING,
+ "Dropped corrupted packet (stream = %d)\n",
+ pkt->stream_index);
+ av_free_packet(pkt);
+ continue;
+ }
+
+ if (pkt->stream_index >= (unsigned)s->nb_streams) {
+ av_log(s, AV_LOG_ERROR, "Invalid stream index %d\n", pkt->stream_index);
+ continue;
+ }
+
+ 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) {
+ // correct first time stamps to negative values
+ if (!is_relative(st->first_dts))
+ st->first_dts = wrap_timestamp(st, st->first_dts);
+ if (!is_relative(st->start_time))
+ st->start_time = wrap_timestamp(st, st->start_time);
+ if (!is_relative(st->cur_dts))
+ st->cur_dts = wrap_timestamp(st, st->cur_dts);
+ }
+
+ pkt->dts = wrap_timestamp(st, pkt->dts);
+ pkt->pts = wrap_timestamp(st, pkt->pts);
+
+ force_codec_ids(s, st);
+
+ /* TODO: audio: time filter; video: frame reordering (pts != dts) */
+ 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)
+ return ret;
+
+ add_to_pktbuf(&s->internal->raw_packet_buffer, pkt,
+ &s->internal->raw_packet_buffer_end);
+ s->internal->raw_packet_buffer_remaining_size -= pkt->size;
+
+ if ((err = probe_codec(s, st, pkt)) < 0)
+ return err;
+ }
+}
+
+
+/**********************************************************/
+
+static int determinable_frame_size(AVCodecContext *avctx)
+{
+ if (/*avctx->codec_id == AV_CODEC_ID_AAC ||*/
+ avctx->codec_id == AV_CODEC_ID_MP1 ||
+ avctx->codec_id == AV_CODEC_ID_MP2 ||
+ avctx->codec_id == AV_CODEC_ID_MP3/* ||
+ avctx->codec_id == AV_CODEC_ID_CELT*/)
+ return 1;
+ return 0;
+}
+
+/**
+ * Return the frame duration in seconds. Return 0 if not available.
+ */
+void ff_compute_frame_duration(AVFormatContext *s, int *pnum, int *pden, AVStream *st,
+ AVCodecParserContext *pc, AVPacket *pkt)
+{
+ AVRational codec_framerate = s->iformat ? st->codec->framerate :
+ av_mul_q(av_inv_q(st->codec->time_base), (AVRational){1, st->codec->ticks_per_frame});
+ int frame_size;
+
+ *pnum = 0;
+ *pden = 0;
+ switch (st->codec->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ if (st->r_frame_rate.num && !pc && s->iformat) {
+ *pnum = st->r_frame_rate.den;
+ *pden = st->r_frame_rate.num;
+ } else if (st->time_base.num * 1000LL > st->time_base.den) {
+ *pnum = st->time_base.num;
+ *pden = st->time_base.den;
+ } else if (codec_framerate.den * 1000LL > codec_framerate.num) {
+ av_assert0(st->codec->ticks_per_frame);
+ av_reduce(pnum, pden,
+ codec_framerate.den,
+ codec_framerate.num * (int64_t)st->codec->ticks_per_frame,
+ INT_MAX);
+
+ if (pc && pc->repeat_pict) {
+ av_assert0(s->iformat); // this may be wrong for interlaced encoding but its not used for that case
+ av_reduce(pnum, pden,
+ (*pnum) * (1LL + pc->repeat_pict),
+ (*pden),
+ INT_MAX);
+ }
+ /* If this codec can be interlaced or progressive then we need
+ * a parser to compute duration of a packet. Thus if we have
+ * no parser in such case leave duration undefined. */
+ if (st->codec->ticks_per_frame > 1 && !pc)
+ *pnum = *pden = 0;
+ }
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ frame_size = av_get_audio_frame_duration(st->codec, pkt->size);
+ if (frame_size <= 0 || st->codec->sample_rate <= 0)
+ break;
+ *pnum = frame_size;
+ *pden = st->codec->sample_rate;
+ break;
+ default:
+ break;
+ }
+}
+
+static int is_intra_only(AVCodecContext *enc) {
+ const AVCodecDescriptor *desc;
+
+ if (enc->codec_type != AVMEDIA_TYPE_VIDEO)
+ return 1;
+
+ desc = av_codec_get_codec_descriptor(enc);
+ if (!desc) {
+ desc = avcodec_descriptor_get(enc->codec_id);
+ av_codec_set_codec_descriptor(enc, desc);
+ }
+ if (desc)
+ return !!(desc->props & AV_CODEC_PROP_INTRA_ONLY);
+ return 0;
+}
+
+static int has_decode_delay_been_guessed(AVStream *st)
+{
+ if (st->codec->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
+ return 1;
+#if CONFIG_H264_DECODER
+ if (st->codec->has_b_frames &&
+ avpriv_h264_has_num_reorder_frames(st->codec) == st->codec->has_b_frames)
+ return 1;
+#endif
+ if (st->codec->has_b_frames<3)
+ return st->nb_decoded_frames >= 7;
+ else if (st->codec->has_b_frames<4)
+ return st->nb_decoded_frames >= 18;
+ else
+ return st->nb_decoded_frames >= 20;
+}
+
+static AVPacketList *get_next_pkt(AVFormatContext *s, AVStream *st, AVPacketList *pktl)
+{
+ if (pktl->next)
+ return pktl->next;
+ if (pktl == s->internal->packet_buffer_end)
+ return s->internal->parse_queue;
+ return NULL;
+}
+
+static int64_t select_from_pts_buffer(AVStream *st, int64_t *pts_buffer, int64_t dts) {
+ int onein_oneout = st->codec->codec_id != AV_CODEC_ID_H264 &&
+ st->codec->codec_id != AV_CODEC_ID_HEVC;
+
+ if(!onein_oneout) {
+ int delay = st->codec->has_b_frames;
+ int i;
+
+ if (dts == AV_NOPTS_VALUE) {
+ int64_t best_score = INT64_MAX;
+ for (i = 0; i<delay; i++) {
+ if (st->pts_reorder_error_count[i]) {
+ int64_t score = st->pts_reorder_error[i] / st->pts_reorder_error_count[i];
+ if (score < best_score) {
+ best_score = score;
+ dts = pts_buffer[i];
+ }
+ }
+ }
+ } else {
+ for (i = 0; i<delay; i++) {
+ if (pts_buffer[i] != AV_NOPTS_VALUE) {
+ int64_t diff = FFABS(pts_buffer[i] - dts)
+ + (uint64_t)st->pts_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;
+ }
+ }
+ }
+ }
+ }
+
+ if (dts == AV_NOPTS_VALUE)
+ dts = pts_buffer[0];
+
+ return dts;
+}
+
+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;
+ int64_t pts_buffer[MAX_REORDER_DELAY+1];
+ int64_t shift;
+ int i, delay;
+
+ if (st->first_dts != AV_NOPTS_VALUE ||
+ dts == AV_NOPTS_VALUE ||
+ st->cur_dts == AV_NOPTS_VALUE ||
+ is_relative(dts))
+ return;
+
+ delay = st->codec->has_b_frames;
+ st->first_dts = dts - (st->cur_dts - RELATIVE_TS_BASE);
+ st->cur_dts = dts;
+ shift = st->first_dts - RELATIVE_TS_BASE;
+
+ for (i = 0; i<MAX_REORDER_DELAY+1; i++)
+ pts_buffer[i] = AV_NOPTS_VALUE;
+
+ if (is_relative(pts))
+ pts += shift;
+
+ for (; pktl; pktl = get_next_pkt(s, st, pktl)) {
+ if (pktl->pkt.stream_index != stream_index)
+ continue;
+ if (is_relative(pktl->pkt.pts))
+ pktl->pkt.pts += shift;
+
+ if (is_relative(pktl->pkt.dts))
+ pktl->pkt.dts += shift;
+
+ if (st->start_time == AV_NOPTS_VALUE && pktl->pkt.pts != AV_NOPTS_VALUE)
+ st->start_time = pktl->pkt.pts;
+
+ if (pktl->pkt.pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY && has_decode_delay_been_guessed(st)) {
+ pts_buffer[0] = pktl->pkt.pts;
+ for (i = 0; i<delay && pts_buffer[i] > pts_buffer[i + 1]; i++)
+ FFSWAP(int64_t, pts_buffer[i], pts_buffer[i + 1]);
+
+ pktl->pkt.dts = select_from_pts_buffer(st, pts_buffer, pktl->pkt.dts);
+ }
+ }
+
+ if (st->start_time == AV_NOPTS_VALUE)
+ st->start_time = pts;
+}
+
+static void update_initial_durations(AVFormatContext *s, AVStream *st,
+ int stream_index, int duration)
+{
+ AVPacketList *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)
+ return;
+ st->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) {
+ if (pktl->pkt.pts != pktl->pkt.dts ||
+ pktl->pkt.dts != AV_NOPTS_VALUE ||
+ pktl->pkt.duration)
+ break;
+ cur_dts -= duration;
+ }
+ }
+ if (pktl && pktl->pkt.dts != st->first_dts) {
+ av_log(s, AV_LOG_DEBUG, "first_dts %s not matching first dts %s (pts %s, duration %d) in the queue\n",
+ av_ts2str(st->first_dts), av_ts2str(pktl->pkt.dts), av_ts2str(pktl->pkt.pts), pktl->pkt.duration);
+ return;
+ }
+ if (!pktl) {
+ av_log(s, AV_LOG_DEBUG, "first_dts %s but no packet with dts in the queue\n", av_ts2str(st->first_dts));
+ return;
+ }
+ pktl = s->internal->packet_buffer ? s->internal->packet_buffer : s->internal->parse_queue;
+ st->first_dts = cur_dts;
+ } else if (st->cur_dts != RELATIVE_TS_BASE)
+ return;
+
+ for (; pktl; pktl = get_next_pkt(s, st, pktl)) {
+ if (pktl->pkt.stream_index != stream_index)
+ continue;
+ if (pktl->pkt.pts == pktl->pkt.dts &&
+ (pktl->pkt.dts == AV_NOPTS_VALUE || pktl->pkt.dts == st->first_dts) &&
+ !pktl->pkt.duration) {
+ pktl->pkt.dts = cur_dts;
+ if (!st->codec->has_b_frames)
+ pktl->pkt.pts = cur_dts;
+// if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO)
+ pktl->pkt.duration = duration;
+ } else
+ break;
+ cur_dts = pktl->pkt.dts + pktl->pkt.duration;
+ }
+ if (!pktl)
+ st->cur_dts = cur_dts;
+}
+
+static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
+ AVCodecParserContext *pc, AVPacket *pkt,
+ int64_t next_dts, int64_t next_pts)
+{
+ int num, den, presentation_delayed, delay, i;
+ int64_t offset;
+ AVRational duration;
+ int onein_oneout = st->codec->codec_id != AV_CODEC_ID_H264 &&
+ st->codec->codec_id != AV_CODEC_ID_HEVC;
+
+ if (s->flags & AVFMT_FLAG_NOFILLIN)
+ return;
+
+ if (st->codec->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++;
+ } else {
+ av_log(s, st->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++;
+ }
+ if (st->dts_ordered + st->dts_misordered > 250) {
+ st->dts_ordered >>= 1;
+ st->dts_misordered >>= 1;
+ }
+ }
+
+ st->last_dts_for_order_check = pkt->dts;
+ if (st->dts_ordered < 8*st->dts_misordered && pkt->dts == pkt->pts)
+ pkt->dts = AV_NOPTS_VALUE;
+ }
+
+ if ((s->flags & AVFMT_FLAG_IGNDTS) && pkt->pts != AV_NOPTS_VALUE)
+ pkt->dts = AV_NOPTS_VALUE;
+
+ if (pc && pc->pict_type == AV_PICTURE_TYPE_B
+ && !st->codec->has_b_frames)
+ //FIXME Set low_delay = 0 when has_b_frames = 1
+ st->codec->has_b_frames = 1;
+
+ /* do we have a video B-frame ? */
+ delay = st->codec->has_b_frames;
+ presentation_delayed = 0;
+
+ /* XXX: need has_b_frame, but cannot get it if the codec is
+ * not initialized */
+ if (delay &&
+ pc && pc->pict_type != AV_PICTURE_TYPE_B)
+ presentation_delayed = 1;
+
+ if (pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE &&
+ st->pts_wrap_bits < 63 &&
+ 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;
+ } else
+ pkt->pts += 1LL << st->pts_wrap_bits;
+ }
+
+ /* Some MPEG-2 in MPEG-PS lack dts (issue #171 / input_file.mpg).
+ * We take the conservative approach and discard both.
+ * Note: If this is misbehaving for an H.264 file, then possibly
+ * presentation_delayed is not set correctly. */
+ if (delay == 1 && pkt->dts == pkt->pts &&
+ pkt->dts != AV_NOPTS_VALUE && presentation_delayed) {
+ av_log(s, AV_LOG_DEBUG, "invalid dts/pts combination %"PRIi64"\n", pkt->dts);
+ if ( strcmp(s->iformat->name, "mov,mp4,m4a,3gp,3g2,mj2")
+ && strcmp(s->iformat->name, "flv")) // otherwise we discard correct timestamps for vc1-wmapro.ism
+ pkt->dts = AV_NOPTS_VALUE;
+ }
+
+ duration = av_mul_q((AVRational) {pkt->duration, 1}, st->time_base);
+ if (pkt->duration == 0) {
+ ff_compute_frame_duration(s, &num, &den, st, pc, pkt);
+ if (den && num) {
+ duration = (AVRational) {num, den};
+ pkt->duration = av_rescale_rnd(1,
+ num * (int64_t) st->time_base.den,
+ den * (int64_t) st->time_base.num,
+ AV_ROUND_DOWN);
+ }
+ }
+
+ if (pkt->duration != 0 && (s->internal->packet_buffer || s->internal->parse_queue))
+ update_initial_durations(s, st, pkt->stream_index, pkt->duration);
+
+ /* Correct timestamps with byte offset if demuxers only have timestamps
+ * on packet boundaries */
+ if (pc && st->need_parsing == AVSTREAM_PARSE_TIMESTAMPS && pkt->size) {
+ /* this will estimate bitrate based on this frame's duration and size */
+ offset = av_rescale(pc->offset, pkt->duration, pkt->size);
+ if (pkt->pts != AV_NOPTS_VALUE)
+ pkt->pts += offset;
+ if (pkt->dts != AV_NOPTS_VALUE)
+ pkt->dts += offset;
+ }
+
+ /* This may be redundant, but it should not hurt. */
+ if (pkt->dts != AV_NOPTS_VALUE &&
+ pkt->pts != AV_NOPTS_VALUE &&
+ pkt->pts > pkt->dts)
+ presentation_delayed = 1;
+
+ if (s->debug & FF_FDEBUG_TS)
+ av_log(s, AV_LOG_TRACE,
+ "IN delayed:%d pts:%s, dts:%s cur_dts:%s st:%d pc:%p duration:%d delay:%d onein_oneout:%d\n",
+ presentation_delayed, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts),
+ pkt->stream_index, pc, pkt->duration, delay, onein_oneout);
+
+ /* Interpolate PTS and DTS if they are not present. We skip H264
+ * currently because delay and has_b_frames are not reliably set. */
+ if ((delay == 0 || (delay == 1 && pc)) &&
+ onein_oneout) {
+ if (presentation_delayed) {
+ /* DTS = decompression timestamp */
+ /* PTS = presentation timestamp */
+ if (pkt->dts == AV_NOPTS_VALUE)
+ pkt->dts = st->last_IP_pts;
+ update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts, pkt);
+ if (pkt->dts == AV_NOPTS_VALUE)
+ pkt->dts = st->cur_dts;
+
+ /* This is tricky: the dts must be incremented by the duration
+ * of the frame we are displaying, i.e. the last I- or P-frame. */
+ if (st->last_IP_duration == 0)
+ st->last_IP_duration = pkt->duration;
+ if (pkt->dts != AV_NOPTS_VALUE)
+ st->cur_dts = pkt->dts + st->last_IP_duration;
+ if (pkt->dts != AV_NOPTS_VALUE &&
+ pkt->pts == AV_NOPTS_VALUE &&
+ st->last_IP_duration > 0 &&
+ ((uint64_t)st->cur_dts - (uint64_t)next_dts + 1) <= 2 &&
+ next_dts != next_pts &&
+ next_pts != AV_NOPTS_VALUE)
+ pkt->pts = next_dts;
+
+ st->last_IP_duration = pkt->duration;
+ st->last_IP_pts = pkt->pts;
+ /* Cannot compute PTS if not present (we can compute it only
+ * by knowing the future. */
+ } else if (pkt->pts != AV_NOPTS_VALUE ||
+ pkt->dts != AV_NOPTS_VALUE ||
+ pkt->duration ) {
+
+ /* presentation is not delayed : PTS and DTS are the same */
+ if (pkt->pts == AV_NOPTS_VALUE)
+ pkt->pts = pkt->dts;
+ update_initial_timestamps(s, pkt->stream_index, pkt->pts,
+ pkt->pts, pkt);
+ if (pkt->pts == AV_NOPTS_VALUE)
+ pkt->pts = st->cur_dts;
+ pkt->dts = pkt->pts;
+ if (pkt->pts != AV_NOPTS_VALUE)
+ st->cur_dts = av_add_stable(st->time_base, pkt->pts, duration, 1);
+ }
+ }
+
+ if (pkt->pts != AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY) {
+ st->pts_buffer[0] = pkt->pts;
+ for (i = 0; i<delay && st->pts_buffer[i] > st->pts_buffer[i + 1]; i++)
+ FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i + 1]);
+
+ if(has_decode_delay_been_guessed(st))
+ pkt->dts = select_from_pts_buffer(st, st->pts_buffer, pkt->dts);
+ }
+ // We skipped it above so we try here.
+ if (!onein_oneout)
+ // This should happen on the first packet
+ update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts, pkt);
+ if (pkt->dts > st->cur_dts)
+ st->cur_dts = pkt->dts;
+
+ if (s->debug & FF_FDEBUG_TS)
+ av_log(s, AV_LOG_TRACE, "OUTdelayed:%d/%d pts:%s, dts:%s cur_dts:%s\n",
+ presentation_delayed, delay, av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts));
+
+ /* update flags */
+ if (is_intra_only(st->codec))
+ pkt->flags |= AV_PKT_FLAG_KEY;
+ if (pc)
+ pkt->convergence_duration = pc->convergence_duration;
+}
+
+static void free_packet_buffer(AVPacketList **pkt_buf, AVPacketList **pkt_buf_end)
+{
+ while (*pkt_buf) {
+ AVPacketList *pktl = *pkt_buf;
+ *pkt_buf = pktl->next;
+ av_free_packet(&pktl->pkt);
+ av_freep(&pktl);
+ }
+ *pkt_buf_end = NULL;
+}
+
+/**
+ * Parse a packet, add all split parts to parse_queue.
+ *
+ * @param pkt Packet to parse, NULL when flushing the parser at end of stream.
+ */
+static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index)
+{
+ AVPacket out_pkt = { 0 }, flush_pkt = { 0 };
+ AVStream *st = s->streams[stream_index];
+ uint8_t *data = pkt ? pkt->data : NULL;
+ int size = pkt ? pkt->size : 0;
+ int ret = 0, got_output = 0;
+
+ if (!pkt) {
+ av_init_packet(&flush_pkt);
+ pkt = &flush_pkt;
+ got_output = 1;
+ } else if (!size && 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);
+ }
+
+ while (size > 0 || (pkt == &flush_pkt && got_output)) {
+ int len;
+ int64_t next_pts = pkt->pts;
+ int64_t next_dts = pkt->dts;
+
+ av_init_packet(&out_pkt);
+ len = av_parser_parse2(st->parser, st->codec,
+ &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;
+ size -= len;
+
+ got_output = !!out_pkt.size;
+
+ if (!out_pkt.size)
+ continue;
+
+ if (pkt->side_data) {
+ 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;
+ if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+ if (st->codec->sample_rate > 0) {
+ out_pkt.duration =
+ av_rescale_q_rnd(st->parser->duration,
+ (AVRational) { 1, st->codec->sample_rate },
+ st->time_base,
+ AV_ROUND_DOWN);
+ }
+ }
+
+ out_pkt.stream_index = st->index;
+ out_pkt.pts = st->parser->pts;
+ out_pkt.dts = st->parser->dts;
+ out_pkt.pos = st->parser->pos;
+
+ if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW)
+ 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;
+
+ 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;
+
+ compute_pkt_fields(s, st, st->parser, &out_pkt, next_dts, next_pts);
+
+ if (out_pkt.data == pkt->data && out_pkt.size == pkt->size) {
+ out_pkt.buf = pkt->buf;
+ pkt->buf = NULL;
+#if FF_API_DESTRUCT_PACKET
+FF_DISABLE_DEPRECATION_WARNINGS
+ out_pkt.destruct = pkt->destruct;
+ pkt->destruct = NULL;
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+ }
+ if ((ret = av_dup_packet(&out_pkt)) < 0)
+ goto fail;
+
+ if (!add_to_pktbuf(&s->internal->parse_queue, &out_pkt, &s->internal->parse_queue_end)) {
+ av_free_packet(&out_pkt);
+ ret = AVERROR(ENOMEM);
+ goto fail;
+ }
+ }
+
+ /* end of the stream => close and free the parser */
+ if (pkt == &flush_pkt) {
+ av_parser_close(st->parser);
+ st->parser = NULL;
+ }
+
+fail:
+ av_free_packet(pkt);
+ return ret;
+}
+
+static int read_from_packet_buffer(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->codec->sample_rate, st->time_base.den);
+}
+
+static int read_frame_internal(AVFormatContext *s, AVPacket *pkt)
+{
+ int ret = 0, i, got_packet = 0;
+ AVDictionary *metadata = NULL;
+
+ av_init_packet(pkt);
+
+ while (!got_packet && !s->internal->parse_queue) {
+ AVStream *st;
+ AVPacket cur_pkt;
+
+ /* read next packet */
+ ret = ff_read_packet(s, &cur_pkt);
+ if (ret < 0) {
+ if (ret == AVERROR(EAGAIN))
+ return ret;
+ /* flush the parsers */
+ for (i = 0; i < s->nb_streams; i++) {
+ st = s->streams[i];
+ if (st->parser && st->need_parsing)
+ parse_packet(s, NULL, st->index);
+ }
+ /* all remaining packets are now in parse_queue =>
+ * really terminate parsing */
+ break;
+ }
+ ret = 0;
+ st = s->streams[cur_pkt.stream_index];
+
+ if (cur_pkt.pts != AV_NOPTS_VALUE &&
+ cur_pkt.dts != AV_NOPTS_VALUE &&
+ cur_pkt.pts < cur_pkt.dts) {
+ av_log(s, AV_LOG_WARNING,
+ "Invalid timestamps stream=%d, pts=%s, dts=%s, size=%d\n",
+ cur_pkt.stream_index,
+ av_ts2str(cur_pkt.pts),
+ av_ts2str(cur_pkt.dts),
+ cur_pkt.size);
+ }
+ if (s->debug & FF_FDEBUG_TS)
+ av_log(s, AV_LOG_DEBUG,
+ "ff_read_packet stream=%d, pts=%s, dts=%s, size=%d, duration=%d, flags=%d\n",
+ cur_pkt.stream_index,
+ av_ts2str(cur_pkt.pts),
+ av_ts2str(cur_pkt.dts),
+ cur_pkt.size, cur_pkt.duration, cur_pkt.flags);
+
+ if (st->need_parsing && !st->parser && !(s->flags & AVFMT_FLAG_NOPARSE)) {
+ st->parser = av_parser_init(st->codec->codec_id);
+ if (!st->parser) {
+ av_log(s, AV_LOG_VERBOSE, "parser not found for codec "
+ "%s, packets or times may be invalid.\n",
+ avcodec_get_name(st->codec->codec_id));
+ /* no parser available: just output the raw packets */
+ st->need_parsing = AVSTREAM_PARSE_NONE;
+ } else if (st->need_parsing == AVSTREAM_PARSE_HEADERS)
+ st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
+ else if (st->need_parsing == AVSTREAM_PARSE_FULL_ONCE)
+ st->parser->flags |= PARSER_FLAG_ONCE;
+ else if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW)
+ st->parser->flags |= PARSER_FLAG_USE_CODEC_TS;
+ }
+
+ if (!st->need_parsing || !st->parser) {
+ /* no parsing needed: we just output the packet as is */
+ *pkt = cur_pkt;
+ compute_pkt_fields(s, st, NULL, pkt, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
+ if ((s->iformat->flags & AVFMT_GENERIC_INDEX) &&
+ (pkt->flags & AV_PKT_FLAG_KEY) && pkt->dts != AV_NOPTS_VALUE) {
+ ff_reduce_index(s, st->index);
+ av_add_index_entry(st, pkt->pos, pkt->dts,
+ 0, 0, AVINDEX_KEYFRAME);
+ }
+ got_packet = 1;
+ } else if (st->discard < AVDISCARD_ALL) {
+ if ((ret = parse_packet(s, &cur_pkt, cur_pkt.stream_index)) < 0)
+ return ret;
+ } else {
+ /* free packet */
+ av_free_packet(&cur_pkt);
+ }
+ if (pkt->flags & AV_PKT_FLAG_KEY)
+ st->skip_to_keyframe = 0;
+ if (st->skip_to_keyframe) {
+ av_free_packet(&cur_pkt);
+ if (got_packet) {
+ *pkt = cur_pkt;
+ }
+ got_packet = 0;
+ }
+ }
+
+ if (!got_packet && s->internal->parse_queue)
+ ret = read_from_packet_buffer(&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) {
+ 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 (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) {
+ 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 + 4, discard_padding);
+ av_log(s, AV_LOG_DEBUG, "demuxer injecting skip %d / discard %d\n", st->skip_samples, discard_padding);
+ }
+ st->skip_samples = 0;
+ }
+
+ if (st->inject_global_side_data) {
+ for (i = 0; i < st->nb_side_data; i++) {
+ AVPacketSideData *src_sd = &st->side_data[i];
+ uint8_t *dst_data;
+
+ 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);
+ if (!dst_data) {
+ av_log(s, AV_LOG_WARNING, "Could not inject global side data\n");
+ continue;
+ }
+
+ memcpy(dst_data, src_sd->data, src_sd->size);
+ }
+ st->inject_global_side_data = 0;
+ }
+
+ if (!(s->flags & AVFMT_FLAG_KEEP_SIDE_DATA))
+ av_packet_merge_side_data(pkt);
+ }
+
+ av_opt_get_dict_val(s, "metadata", AV_OPT_SEARCH_CHILDREN, &metadata);
+ if (metadata) {
+ s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
+ av_dict_copy(&s->metadata, metadata, 0);
+ av_dict_free(&metadata);
+ av_opt_set_dict_val(s, "metadata", NULL, AV_OPT_SEARCH_CHILDREN);
+ }
+
+ if (s->debug & FF_FDEBUG_TS)
+ av_log(s, AV_LOG_DEBUG,
+ "read_frame_internal stream=%d, pts=%s, dts=%s, "
+ "size=%d, duration=%d, flags=%d\n",
+ pkt->stream_index,
+ av_ts2str(pkt->pts),
+ av_ts2str(pkt->dts),
+ pkt->size, pkt->duration, pkt->flags);
+
+ return ret;
+}
+
+int av_read_frame(AVFormatContext *s, AVPacket *pkt)
+{
+ const int genpts = s->flags & AVFMT_FLAG_GENPTS;
+ int eof = 0;
+ int ret;
+ AVStream *st;
+
+ if (!genpts) {
+ ret = s->internal->packet_buffer
+ ? read_from_packet_buffer(&s->internal->packet_buffer,
+ &s->internal->packet_buffer_end, pkt)
+ : read_frame_internal(s, pkt);
+ if (ret < 0)
+ return ret;
+ goto return_packet;
+ }
+
+ for (;;) {
+ AVPacketList *pktl = s->internal->packet_buffer;
+
+ if (pktl) {
+ AVPacket *next_pkt = &pktl->pkt;
+
+ if (next_pkt->dts != AV_NOPTS_VALUE) {
+ int wrap_bits = s->streams[next_pkt->stream_index]->pts_wrap_bits;
+ // last dts seen for this stream. if any of packets following
+ // current one had no dts, we will set this to AV_NOPTS_VALUE.
+ int64_t last_dts = next_pkt->dts;
+ while (pktl && next_pkt->pts == AV_NOPTS_VALUE) {
+ if (pktl->pkt.stream_index == next_pkt->stream_index &&
+ (av_compare_mod(next_pkt->dts, pktl->pkt.dts, 2LL << (wrap_bits - 1)) < 0)) {
+ if (av_compare_mod(pktl->pkt.pts, pktl->pkt.dts, 2LL << (wrap_bits - 1))) {
+ // not B-frame
+ next_pkt->pts = pktl->pkt.dts;
+ }
+ if (last_dts != AV_NOPTS_VALUE) {
+ // Once last dts was set to AV_NOPTS_VALUE, we don't change it.
+ last_dts = pktl->pkt.dts;
+ }
+ }
+ pktl = pktl->next;
+ }
+ if (eof && next_pkt->pts == AV_NOPTS_VALUE && last_dts != AV_NOPTS_VALUE) {
+ // Fixing the last reference frame had none pts issue (For MXF etc).
+ // We only do this when
+ // 1. eof.
+ // 2. we are not able to resolve a pts value for current packet.
+ // 3. the packets for this stream at the end of the files had valid dts.
+ next_pkt->pts = last_dts + next_pkt->duration;
+ }
+ pktl = s->internal->packet_buffer;
+ }
+
+ /* read packet from packet buffer, if there is data */
+ 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 = read_from_packet_buffer(&s->internal->packet_buffer,
+ &s->internal->packet_buffer_end, pkt);
+ goto return_packet;
+ }
+ }
+
+ ret = read_frame_internal(s, pkt);
+ if (ret < 0) {
+ if (pktl && ret != AVERROR(EAGAIN)) {
+ eof = 1;
+ continue;
+ } else
+ return ret;
+ }
+
+ if (av_dup_packet(add_to_pktbuf(&s->internal->packet_buffer, pkt,
+ &s->internal->packet_buffer_end)) < 0)
+ return AVERROR(ENOMEM);
+ }
+
+return_packet:
+
+ st = s->streams[pkt->stream_index];
+ if ((s->iformat->flags & AVFMT_GENERIC_INDEX) && pkt->flags & AV_PKT_FLAG_KEY) {
+ ff_reduce_index(s, st->index);
+ av_add_index_entry(st, pkt->pos, pkt->dts, 0, 0, AVINDEX_KEYFRAME);
+ }
+
+ if (is_relative(pkt->dts))
+ pkt->dts -= RELATIVE_TS_BASE;
+ if (is_relative(pkt->pts))
+ pkt->pts -= RELATIVE_TS_BASE;
+
+ return ret;
+}
+
+/* XXX: suppress the packet queue */
+static void flush_packet_queue(AVFormatContext *s)
+{
+ if (!s->internal)
+ return;
+ free_packet_buffer(&s->internal->parse_queue, &s->internal->parse_queue_end);
+ free_packet_buffer(&s->internal->packet_buffer, &s->internal->packet_buffer_end);
+ free_packet_buffer(&s->internal->raw_packet_buffer, &s->internal->raw_packet_buffer_end);
+
+ s->internal->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
+}
+
+/*******************************************************/
+/* seek support */
+
+int av_find_default_stream_index(AVFormatContext *s)
+{
+ int i;
+ AVStream *st;
+ int best_stream = 0;
+ int best_score = INT_MIN;
+
+ if (s->nb_streams <= 0)
+ return -1;
+ for (i = 0; i < s->nb_streams; i++) {
+ int score = 0;
+ st = s->streams[i];
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (st->disposition & AV_DISPOSITION_ATTACHED_PIC)
+ score -= 400;
+ if (st->codec->width && st->codec->height)
+ score += 50;
+ score+= 25;
+ }
+ if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+ if (st->codec->sample_rate)
+ score += 50;
+ }
+ if (st->codec_info_nb_frames)
+ score += 12;
+
+ if (st->discard != AVDISCARD_ALL)
+ score += 200;
+
+ if (score > best_score) {
+ best_score = score;
+ best_stream = i;
+ }
+ }
+ return best_stream;
+}
+
+/** Flush the frame reader. */
+void ff_read_frame_flush(AVFormatContext *s)
+{
+ AVStream *st;
+ int i, j;
+
+ flush_packet_queue(s);
+
+ /* Reset read state for each stream. */
+ for (i = 0; i < s->nb_streams; i++) {
+ st = s->streams[i];
+
+ if (st->parser) {
+ av_parser_close(st->parser);
+ st->parser = NULL;
+ }
+ st->last_IP_pts = AV_NOPTS_VALUE;
+ st->last_dts_for_order_check = AV_NOPTS_VALUE;
+ if (st->first_dts == AV_NOPTS_VALUE)
+ st->cur_dts = RELATIVE_TS_BASE;
+ else
+ /* We set the current DTS to an unspecified origin. */
+ st->cur_dts = AV_NOPTS_VALUE;
+
+ st->probe_packets = MAX_PROBE_PACKETS;
+
+ for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
+ st->pts_buffer[j] = AV_NOPTS_VALUE;
+
+ if (s->internal->inject_global_side_data)
+ st->inject_global_side_data = 1;
+
+ st->skip_samples = 0;
+ }
+}
+
+void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
+{
+ int i;
+
+ for (i = 0; i < s->nb_streams; i++) {
+ AVStream *st = s->streams[i];
+
+ st->cur_dts =
+ av_rescale(timestamp,
+ st->time_base.den * (int64_t) ref_st->time_base.num,
+ st->time_base.num * (int64_t) ref_st->time_base.den);
+ }
+}
+
+void ff_reduce_index(AVFormatContext *s, int stream_index)
+{
+ AVStream *st = s->streams[stream_index];
+ unsigned int max_entries = s->max_index_size / sizeof(AVIndexEntry);
+
+ if ((unsigned) st->nb_index_entries >= max_entries) {
+ int i;
+ for (i = 0; 2 * i < st->nb_index_entries; i++)
+ st->index_entries[i] = st->index_entries[2 * i];
+ st->nb_index_entries = i;
+ }
+}
+
+int ff_add_index_entry(AVIndexEntry **index_entries,
+ int *nb_index_entries,
+ unsigned int *index_entries_allocated_size,
+ int64_t pos, int64_t timestamp,
+ int size, int distance, int flags)
+{
+ AVIndexEntry *entries, *ie;
+ int index;
+
+ if ((unsigned) *nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
+ return -1;
+
+ if (timestamp == AV_NOPTS_VALUE)
+ return AVERROR(EINVAL);
+
+ if (size < 0 || size > 0x3FFFFFFF)
+ return AVERROR(EINVAL);
+
+ if (is_relative(timestamp)) //FIXME this maintains previous behavior but we should shift by the correct offset once known
+ timestamp -= RELATIVE_TS_BASE;
+
+ entries = av_fast_realloc(*index_entries,
+ index_entries_allocated_size,
+ (*nb_index_entries + 1) *
+ sizeof(AVIndexEntry));
+ if (!entries)
+ return -1;
+
+ *index_entries = entries;
+
+ index = ff_index_search_timestamp(*index_entries, *nb_index_entries,
+ timestamp, AVSEEK_FLAG_ANY);
+
+ if (index < 0) {
+ index = (*nb_index_entries)++;
+ ie = &entries[index];
+ av_assert0(index == 0 || ie[-1].timestamp < timestamp);
+ } else {
+ ie = &entries[index];
+ if (ie->timestamp != timestamp) {
+ if (ie->timestamp <= timestamp)
+ return -1;
+ memmove(entries + index + 1, entries + index,
+ sizeof(AVIndexEntry) * (*nb_index_entries - index));
+ (*nb_index_entries)++;
+ } else if (ie->pos == pos && distance < ie->min_distance)
+ // do not reduce the distance
+ distance = ie->min_distance;
+ }
+
+ ie->pos = pos;
+ ie->timestamp = timestamp;
+ ie->min_distance = distance;
+ ie->size = size;
+ ie->flags = flags;
+
+ return index;
+}
+
+int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
+ int size, int distance, int flags)
+{
+ timestamp = wrap_timestamp(st, timestamp);
+ return ff_add_index_entry(&st->index_entries, &st->nb_index_entries,
+ &st->index_entries_allocated_size, pos,
+ timestamp, size, distance, flags);
+}
+
+int ff_index_search_timestamp(const AVIndexEntry *entries, int nb_entries,
+ int64_t wanted_timestamp, int flags)
+{
+ int a, b, m;
+ int64_t timestamp;
+
+ a = -1;
+ b = nb_entries;
+
+ // Optimize appending index entries at the end.
+ if (b && entries[b - 1].timestamp < wanted_timestamp)
+ a = b - 1;
+
+ while (b - a > 1) {
+ m = (a + b) >> 1;
+ timestamp = entries[m].timestamp;
+ if (timestamp >= wanted_timestamp)
+ b = m;
+ if (timestamp <= wanted_timestamp)
+ a = m;
+ }
+ m = (flags & AVSEEK_FLAG_BACKWARD) ? a : b;
+
+ if (!(flags & AVSEEK_FLAG_ANY))
+ while (m >= 0 && m < nb_entries &&
+ !(entries[m].flags & AVINDEX_KEYFRAME))
+ m += (flags & AVSEEK_FLAG_BACKWARD) ? -1 : 1;
+
+ if (m == nb_entries)
+ return -1;
+ return m;
+}
+
+void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance)
+{
+ int ist1, ist2;
+ int64_t pos_delta = 0;
+ int64_t skip = 0;
+ //We could use URLProtocol flags here but as many user applications do not use URLProtocols this would be unreliable
+ const char *proto = avio_find_protocol_name(s->filename);
+
+ if (!proto) {
+ av_log(s, AV_LOG_INFO,
+ "Protocol name not provided, cannot determine if input is local or "
+ "a network protocol, buffers and access patterns cannot be configured "
+ "optimally without knowing the protocol\n");
+ }
+
+ if (proto && !(strcmp(proto, "file") && strcmp(proto, "pipe") && strcmp(proto, "cache")))
+ return;
+
+ for (ist1 = 0; ist1 < s->nb_streams; ist1++) {
+ AVStream *st1 = s->streams[ist1];
+ for (ist2 = 0; ist2 < s->nb_streams; ist2++) {
+ AVStream *st2 = s->streams[ist2];
+ int i1, i2;
+
+ if (ist1 == ist2)
+ continue;
+
+ for (i1 = i2 = 0; i1 < st1->nb_index_entries; i1++) {
+ AVIndexEntry *e1 = &st1->index_entries[i1];
+ int64_t e1_pts = av_rescale_q(e1->timestamp, st1->time_base, AV_TIME_BASE_Q);
+
+ skip = FFMAX(skip, e1->size);
+ for (; i2 < st2->nb_index_entries; i2++) {
+ AVIndexEntry *e2 = &st2->index_entries[i2];
+ int64_t e2_pts = av_rescale_q(e2->timestamp, st2->time_base, AV_TIME_BASE_Q);
+ if (e2_pts - e1_pts < time_tolerance)
+ continue;
+ pos_delta = FFMAX(pos_delta, e1->pos - e2->pos);
+ break;
+ }
+ }
+ }
+ }
+
+ pos_delta *= 2;
+ /* XXX This could be adjusted depending on protocol*/
+ if (s->pb->buffer_size < pos_delta && pos_delta < (1<<24)) {
+ av_log(s, AV_LOG_VERBOSE, "Reconfiguring buffers to size %"PRId64"\n", pos_delta);
+ ffio_set_buf_size(s->pb, pos_delta);
+ s->pb->short_seek_threshold = FFMAX(s->pb->short_seek_threshold, pos_delta/2);
+ }
+
+ if (skip < (1<<23)) {
+ s->pb->short_seek_threshold = FFMAX(s->pb->short_seek_threshold, skip);
+ }
+}
+
+int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int flags)
+{
+ return ff_index_search_timestamp(st->index_entries, st->nb_index_entries,
+ wanted_timestamp, flags);
+}
+
+static int64_t ff_read_timestamp(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit,
+ int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
+{
+ int64_t ts = read_timestamp(s, stream_index, ppos, pos_limit);
+ if (stream_index >= 0)
+ ts = wrap_timestamp(s->streams[stream_index], ts);
+ return ts;
+}
+
+int ff_seek_frame_binary(AVFormatContext *s, int stream_index,
+ int64_t target_ts, int flags)
+{
+ AVInputFormat *avif = s->iformat;
+ int64_t av_uninit(pos_min), av_uninit(pos_max), pos, pos_limit;
+ int64_t ts_min, ts_max, ts;
+ int index;
+ int64_t ret;
+ AVStream *st;
+
+ if (stream_index < 0)
+ return -1;
+
+ av_log(s, AV_LOG_TRACE, "read_seek: %d %s\n", stream_index, av_ts2str(target_ts));
+
+ ts_max =
+ ts_min = AV_NOPTS_VALUE;
+ pos_limit = -1; // GCC falsely says it may be uninitialized.
+
+ st = s->streams[stream_index];
+ if (st->index_entries) {
+ AVIndexEntry *e;
+
+ /* FIXME: Whole function must be checked for non-keyframe entries in
+ * index case, especially read_timestamp(). */
+ index = av_index_search_timestamp(st, target_ts,
+ flags | AVSEEK_FLAG_BACKWARD);
+ index = FFMAX(index, 0);
+ e = &st->index_entries[index];
+
+ if (e->timestamp <= target_ts || e->pos == e->min_distance) {
+ pos_min = e->pos;
+ ts_min = e->timestamp;
+ av_log(s, AV_LOG_TRACE, "using cached pos_min=0x%"PRIx64" dts_min=%s\n",
+ pos_min, av_ts2str(ts_min));
+ } else {
+ av_assert1(index == 0);
+ }
+
+ index = av_index_search_timestamp(st, target_ts,
+ flags & ~AVSEEK_FLAG_BACKWARD);
+ av_assert0(index < st->nb_index_entries);
+ if (index >= 0) {
+ e = &st->index_entries[index];
+ av_assert1(e->timestamp >= target_ts);
+ pos_max = e->pos;
+ ts_max = e->timestamp;
+ pos_limit = pos_max - e->min_distance;
+ av_log(s, AV_LOG_TRACE, "using cached pos_max=0x%"PRIx64" pos_limit=0x%"PRIx64
+ " dts_max=%s\n", pos_max, pos_limit, av_ts2str(ts_max));
+ }
+ }
+
+ pos = ff_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit,
+ ts_min, ts_max, flags, &ts, avif->read_timestamp);
+ if (pos < 0)
+ return -1;
+
+ /* do the seek */
+ if ((ret = avio_seek(s->pb, pos, SEEK_SET)) < 0)
+ return ret;
+
+ ff_read_frame_flush(s);
+ ff_update_cur_dts(s, st, ts);
+
+ return 0;
+}
+
+int ff_find_last_ts(AVFormatContext *s, int stream_index, int64_t *ts, int64_t *pos,
+ int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
+{
+ int64_t step = 1024;
+ int64_t limit, ts_max;
+ int64_t filesize = avio_size(s->pb);
+ int64_t pos_max = filesize - 1;
+ do {
+ limit = pos_max;
+ pos_max = FFMAX(0, (pos_max) - step);
+ ts_max = ff_read_timestamp(s, stream_index,
+ &pos_max, limit, read_timestamp);
+ step += step;
+ } while (ts_max == AV_NOPTS_VALUE && 2*limit > step);
+ if (ts_max == AV_NOPTS_VALUE)
+ return -1;
+
+ for (;;) {
+ int64_t tmp_pos = pos_max + 1;
+ int64_t tmp_ts = ff_read_timestamp(s, stream_index,
+ &tmp_pos, INT64_MAX, read_timestamp);
+ if (tmp_ts == AV_NOPTS_VALUE)
+ break;
+ av_assert0(tmp_pos > pos_max);
+ ts_max = tmp_ts;
+ pos_max = tmp_pos;
+ if (tmp_pos >= filesize)
+ break;
+ }
+
+ if (ts)
+ *ts = ts_max;
+ if (pos)
+ *pos = pos_max;
+
+ return 0;
+}
+
+int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
+ int64_t pos_min, int64_t pos_max, int64_t pos_limit,
+ int64_t ts_min, int64_t ts_max,
+ int flags, int64_t *ts_ret,
+ int64_t (*read_timestamp)(struct AVFormatContext *, int,
+ int64_t *, int64_t))
+{
+ int64_t pos, ts;
+ int64_t start_pos;
+ int no_change;
+ int ret;
+
+ av_log(s, AV_LOG_TRACE, "gen_seek: %d %s\n", stream_index, av_ts2str(target_ts));
+
+ if (ts_min == AV_NOPTS_VALUE) {
+ pos_min = s->internal->data_offset;
+ ts_min = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp);
+ if (ts_min == AV_NOPTS_VALUE)
+ return -1;
+ }
+
+ if (ts_min >= target_ts) {
+ *ts_ret = ts_min;
+ return pos_min;
+ }
+
+ if (ts_max == AV_NOPTS_VALUE) {
+ if ((ret = ff_find_last_ts(s, stream_index, &ts_max, &pos_max, read_timestamp)) < 0)
+ return ret;
+ pos_limit = pos_max;
+ }
+
+ if (ts_max <= target_ts) {
+ *ts_ret = ts_max;
+ return pos_max;
+ }
+
+ av_assert0(ts_min < ts_max);
+
+ no_change = 0;
+ while (pos_min < pos_limit) {
+ av_log(s, AV_LOG_TRACE,
+ "pos_min=0x%"PRIx64" pos_max=0x%"PRIx64" dts_min=%s dts_max=%s\n",
+ pos_min, pos_max, av_ts2str(ts_min), av_ts2str(ts_max));
+ av_assert0(pos_limit <= pos_max);
+
+ if (no_change == 0) {
+ int64_t approximate_keyframe_distance = pos_max - pos_limit;
+ // interpolate position (better than dichotomy)
+ pos = av_rescale(target_ts - ts_min, pos_max - pos_min,
+ ts_max - ts_min) +
+ pos_min - approximate_keyframe_distance;
+ } else if (no_change == 1) {
+ // bisection if interpolation did not change min / max pos last time
+ pos = (pos_min + pos_limit) >> 1;
+ } else {
+ /* linear search if bisection failed, can only happen if there
+ * are very few or no keyframes between min/max */
+ pos = pos_min;
+ }
+ if (pos <= pos_min)
+ pos = pos_min + 1;
+ else if (pos > pos_limit)
+ pos = pos_limit;
+ start_pos = pos;
+
+ // May pass pos_limit instead of -1.
+ ts = ff_read_timestamp(s, stream_index, &pos, INT64_MAX, read_timestamp);
+ if (pos == pos_max)
+ no_change++;
+ else
+ no_change = 0;
+ av_log(s, AV_LOG_TRACE, "%"PRId64" %"PRId64" %"PRId64" / %s %s %s"
+ " target:%s limit:%"PRId64" start:%"PRId64" noc:%d\n",
+ pos_min, pos, pos_max,
+ av_ts2str(ts_min), av_ts2str(ts), av_ts2str(ts_max), av_ts2str(target_ts),
+ pos_limit, start_pos, no_change);
+ if (ts == AV_NOPTS_VALUE) {
+ av_log(s, AV_LOG_ERROR, "read_timestamp() failed in the middle\n");
+ return -1;
+ }
+ if (target_ts <= ts) {
+ pos_limit = start_pos - 1;
+ pos_max = pos;
+ ts_max = ts;
+ }
+ if (target_ts >= ts) {
+ pos_min = pos;
+ ts_min = ts;
+ }
+ }
+
+ pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max;
+ ts = (flags & AVSEEK_FLAG_BACKWARD) ? ts_min : ts_max;
+#if 0
+ pos_min = pos;
+ ts_min = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp);
+ pos_min++;
+ ts_max = ff_read_timestamp(s, stream_index, &pos_min, INT64_MAX, read_timestamp);
+ av_log(s, AV_LOG_TRACE, "pos=0x%"PRIx64" %s<=%s<=%s\n",
+ pos, av_ts2str(ts_min), av_ts2str(target_ts), av_ts2str(ts_max));
+#endif
+ *ts_ret = ts;
+ return pos;
+}
+
+static int seek_frame_byte(AVFormatContext *s, int stream_index,
+ int64_t pos, int flags)
+{
+ int64_t pos_min, pos_max;
+
+ pos_min = s->internal->data_offset;
+ pos_max = avio_size(s->pb) - 1;
+
+ if (pos < pos_min)
+ pos = pos_min;
+ else if (pos > pos_max)
+ pos = pos_max;
+
+ avio_seek(s->pb, pos, SEEK_SET);
+
+ s->io_repositioned = 1;
+
+ return 0;
+}
+
+static int seek_frame_generic(AVFormatContext *s, int stream_index,
+ int64_t timestamp, int flags)
+{
+ int index;
+ int64_t ret;
+ AVStream *st;
+ AVIndexEntry *ie;
+
+ st = s->streams[stream_index];
+
+ index = av_index_search_timestamp(st, timestamp, flags);
+
+ if (index < 0 && st->nb_index_entries &&
+ timestamp < st->index_entries[0].timestamp)
+ return -1;
+
+ if (index < 0 || index == st->nb_index_entries - 1) {
+ AVPacket pkt;
+ int nonkey = 0;
+
+ if (st->nb_index_entries) {
+ av_assert0(st->index_entries);
+ ie = &st->index_entries[st->nb_index_entries - 1];
+ if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)
+ return ret;
+ ff_update_cur_dts(s, st, ie->timestamp);
+ } else {
+ if ((ret = avio_seek(s->pb, s->internal->data_offset, SEEK_SET)) < 0)
+ return ret;
+ }
+ for (;;) {
+ int read_status;
+ do {
+ read_status = av_read_frame(s, &pkt);
+ } while (read_status == AVERROR(EAGAIN));
+ if (read_status < 0)
+ break;
+ av_free_packet(&pkt);
+ if (stream_index == pkt.stream_index && pkt.dts > timestamp) {
+ if (pkt.flags & AV_PKT_FLAG_KEY)
+ break;
+ if (nonkey++ > 1000 && st->codec->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);
+ break;
+ }
+ }
+ }
+ index = av_index_search_timestamp(st, timestamp, flags);
+ }
+ if (index < 0)
+ return -1;
+
+ ff_read_frame_flush(s);
+ if (s->iformat->read_seek)
+ if (s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0)
+ return 0;
+ ie = &st->index_entries[index];
+ if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)
+ return ret;
+ ff_update_cur_dts(s, st, ie->timestamp);
+
+ return 0;
+}
+
+static int seek_frame_internal(AVFormatContext *s, int stream_index,
+ int64_t timestamp, int flags)
+{
+ int ret;
+ AVStream *st;
+
+ if (flags & AVSEEK_FLAG_BYTE) {
+ if (s->iformat->flags & AVFMT_NO_BYTE_SEEK)
+ return -1;
+ ff_read_frame_flush(s);
+ return seek_frame_byte(s, stream_index, timestamp, flags);
+ }
+
+ if (stream_index < 0) {
+ stream_index = av_find_default_stream_index(s);
+ if (stream_index < 0)
+ return -1;
+
+ st = s->streams[stream_index];
+ /* timestamp for default must be expressed in AV_TIME_BASE units */
+ timestamp = av_rescale(timestamp, st->time_base.den,
+ AV_TIME_BASE * (int64_t) st->time_base.num);
+ }
+
+ /* first, we try the format specific seek */
+ if (s->iformat->read_seek) {
+ ff_read_frame_flush(s);
+ ret = s->iformat->read_seek(s, stream_index, timestamp, flags);
+ } else
+ ret = -1;
+ if (ret >= 0)
+ return 0;
+
+ if (s->iformat->read_timestamp &&
+ !(s->iformat->flags & AVFMT_NOBINSEARCH)) {
+ ff_read_frame_flush(s);
+ return ff_seek_frame_binary(s, stream_index, timestamp, flags);
+ } else if (!(s->iformat->flags & AVFMT_NOGENSEARCH)) {
+ ff_read_frame_flush(s);
+ return seek_frame_generic(s, stream_index, timestamp, flags);
+ } else
+ return -1;
+}
+
+int av_seek_frame(AVFormatContext *s, int stream_index,
+ int64_t timestamp, int flags)
+{
+ int ret;
+
+ if (s->iformat->read_seek2 && !s->iformat->read_seek) {
+ int64_t min_ts = INT64_MIN, max_ts = INT64_MAX;
+ if ((flags & AVSEEK_FLAG_BACKWARD))
+ max_ts = timestamp;
+ else
+ min_ts = timestamp;
+ return avformat_seek_file(s, stream_index, min_ts, timestamp, max_ts,
+ flags & ~AVSEEK_FLAG_BACKWARD);
+ }
+
+ ret = seek_frame_internal(s, stream_index, timestamp, flags);
+
+ if (ret >= 0)
+ ret = avformat_queue_attached_pictures(s);
+
+ return ret;
+}
+
+int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts,
+ int64_t ts, int64_t max_ts, int flags)
+{
+ if (min_ts > ts || max_ts < ts)
+ return -1;
+ if (stream_index < -1 || stream_index >= (int)s->nb_streams)
+ return AVERROR(EINVAL);
+
+ if (s->seek2any>0)
+ flags |= AVSEEK_FLAG_ANY;
+ flags &= ~AVSEEK_FLAG_BACKWARD;
+
+ if (s->iformat->read_seek2) {
+ int ret;
+ ff_read_frame_flush(s);
+
+ if (stream_index == -1 && s->nb_streams == 1) {
+ AVRational time_base = s->streams[0]->time_base;
+ ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base);
+ min_ts = av_rescale_rnd(min_ts, time_base.den,
+ time_base.num * (int64_t)AV_TIME_BASE,
+ AV_ROUND_UP | AV_ROUND_PASS_MINMAX);
+ max_ts = av_rescale_rnd(max_ts, time_base.den,
+ time_base.num * (int64_t)AV_TIME_BASE,
+ AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
+ stream_index = 0;
+ }
+
+ ret = s->iformat->read_seek2(s, stream_index, min_ts,
+ ts, max_ts, flags);
+
+ if (ret >= 0)
+ ret = avformat_queue_attached_pictures(s);
+ return ret;
+ }
+
+ if (s->iformat->read_timestamp) {
+ // try to seek via read_timestamp()
+ }
+
+ // Fall back on old API if new is not implemented but old is.
+ // Note the old API has somewhat different semantics.
+ if (s->iformat->read_seek || 1) {
+ int dir = (ts - (uint64_t)min_ts > (uint64_t)max_ts - ts ? AVSEEK_FLAG_BACKWARD : 0);
+ int ret = av_seek_frame(s, stream_index, ts, flags | dir);
+ if (ret<0 && ts != min_ts && max_ts != ts) {
+ ret = av_seek_frame(s, stream_index, dir ? max_ts : min_ts, flags | dir);
+ if (ret >= 0)
+ ret = av_seek_frame(s, stream_index, ts, flags | (dir^AVSEEK_FLAG_BACKWARD));
+ }
+ return ret;
+ }
+
+ // try some generic seek like seek_frame_generic() but with new ts semantics
+ return -1; //unreachable
+}
+
+int avformat_flush(AVFormatContext *s)
+{
+ ff_read_frame_flush(s);
+ return 0;
+}
+
+/*******************************************************/
+
+/**
+ * Return TRUE if the stream has accurate duration in any stream.
+ *
+ * @return TRUE if the stream has accurate duration for at least one component.
+ */
+static int has_duration(AVFormatContext *ic)
+{
+ int i;
+ AVStream *st;
+
+ for (i = 0; i < ic->nb_streams; i++) {
+ st = ic->streams[i];
+ if (st->duration != AV_NOPTS_VALUE)
+ return 1;
+ }
+ if (ic->duration != AV_NOPTS_VALUE)
+ return 1;
+ return 0;
+}
+
+/**
+ * Estimate the stream timings from the one of each components.
+ *
+ * Also computes the global bitrate if possible.
+ */
+static void update_stream_timings(AVFormatContext *ic)
+{
+ int64_t start_time, start_time1, start_time_text, end_time, end_time1;
+ int64_t duration, duration1, filesize;
+ int i;
+ AVStream *st;
+ AVProgram *p;
+
+ start_time = INT64_MAX;
+ start_time_text = INT64_MAX;
+ end_time = INT64_MIN;
+ duration = INT64_MIN;
+ for (i = 0; i < ic->nb_streams; i++) {
+ st = ic->streams[i];
+ if (st->start_time != AV_NOPTS_VALUE && st->time_base.den) {
+ start_time1 = av_rescale_q(st->start_time, st->time_base,
+ AV_TIME_BASE_Q);
+ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE || st->codec->codec_type == AVMEDIA_TYPE_DATA) {
+ if (start_time1 < start_time_text)
+ start_time_text = start_time1;
+ } else
+ start_time = FFMIN(start_time, start_time1);
+ end_time1 = AV_NOPTS_VALUE;
+ if (st->duration != AV_NOPTS_VALUE) {
+ end_time1 = start_time1 +
+ av_rescale_q(st->duration, st->time_base,
+ AV_TIME_BASE_Q);
+ end_time = FFMAX(end_time, end_time1);
+ }
+ for (p = NULL; (p = av_find_program_from_stream(ic, p, i)); ) {
+ if (p->start_time == AV_NOPTS_VALUE || p->start_time > start_time1)
+ p->start_time = start_time1;
+ if (p->end_time < end_time1)
+ p->end_time = end_time1;
+ }
+ }
+ if (st->duration != AV_NOPTS_VALUE) {
+ duration1 = av_rescale_q(st->duration, st->time_base,
+ AV_TIME_BASE_Q);
+ duration = FFMAX(duration, duration1);
+ }
+ }
+ if (start_time == INT64_MAX || (start_time > start_time_text && start_time - start_time_text < AV_TIME_BASE))
+ start_time = start_time_text;
+ else if (start_time > start_time_text)
+ av_log(ic, AV_LOG_VERBOSE, "Ignoring outlier non primary stream starttime %f\n", start_time_text / (float)AV_TIME_BASE);
+
+ if (start_time != INT64_MAX) {
+ ic->start_time = start_time;
+ if (end_time != INT64_MIN) {
+ if (ic->nb_programs) {
+ for (i = 0; i < ic->nb_programs; i++) {
+ p = ic->programs[i];
+ if (p->start_time != AV_NOPTS_VALUE &&
+ p->end_time > p->start_time &&
+ p->end_time - (uint64_t)p->start_time <= INT64_MAX)
+ duration = FFMAX(duration, p->end_time - p->start_time);
+ }
+ } else if (end_time >= start_time && end_time - (uint64_t)start_time <= INT64_MAX) {
+ duration = FFMAX(duration, end_time - start_time);
+ }
+ }
+ }
+ if (duration != INT64_MIN && duration > 0 && ic->duration == AV_NOPTS_VALUE) {
+ ic->duration = duration;
+ }
+ if (ic->pb && (filesize = avio_size(ic->pb)) > 0 && ic->duration > 0) {
+ /* compute the bitrate */
+ double bitrate = (double) filesize * 8.0 * AV_TIME_BASE /
+ (double) ic->duration;
+ if (bitrate >= 0 && bitrate <= INT_MAX)
+ ic->bit_rate = bitrate;
+ }
+}
+
+static void fill_all_stream_timings(AVFormatContext *ic)
+{
+ int i;
+ AVStream *st;
+
+ update_stream_timings(ic);
+ for (i = 0; i < ic->nb_streams; i++) {
+ st = ic->streams[i];
+ if (st->start_time == AV_NOPTS_VALUE) {
+ if (ic->start_time != AV_NOPTS_VALUE)
+ st->start_time = av_rescale_q(ic->start_time, AV_TIME_BASE_Q,
+ st->time_base);
+ if (ic->duration != AV_NOPTS_VALUE)
+ st->duration = av_rescale_q(ic->duration, AV_TIME_BASE_Q,
+ st->time_base);
+ }
+ }
+}
+
+static void estimate_timings_from_bit_rate(AVFormatContext *ic)
+{
+ int64_t filesize, duration;
+ int i, show_warning = 0;
+ AVStream *st;
+
+ /* if bit_rate is already set, we believe it */
+ if (ic->bit_rate <= 0) {
+ int bit_rate = 0;
+ for (i = 0; i < ic->nb_streams; i++) {
+ st = ic->streams[i];
+ if (st->codec->bit_rate > 0) {
+ if (INT_MAX - st->codec->bit_rate < bit_rate) {
+ bit_rate = 0;
+ break;
+ }
+ bit_rate += st->codec->bit_rate;
+ } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->codec_info_nb_frames > 1) {
+ // If we have a videostream with packets but without a bitrate
+ // then consider the sum not known
+ bit_rate = 0;
+ break;
+ }
+ }
+ ic->bit_rate = bit_rate;
+ }
+
+ /* if duration is already set, we believe it */
+ if (ic->duration == AV_NOPTS_VALUE &&
+ ic->bit_rate != 0) {
+ filesize = ic->pb ? avio_size(ic->pb) : 0;
+ if (filesize > ic->internal->data_offset) {
+ filesize -= ic->internal->data_offset;
+ for (i = 0; i < ic->nb_streams; i++) {
+ st = ic->streams[i];
+ if ( st->time_base.num <= INT64_MAX / ic->bit_rate
+ && st->duration == AV_NOPTS_VALUE) {
+ duration = av_rescale(8 * filesize, st->time_base.den,
+ ic->bit_rate *
+ (int64_t) st->time_base.num);
+ st->duration = duration;
+ show_warning = 1;
+ }
+ }
+ }
+ }
+ if (show_warning)
+ av_log(ic, AV_LOG_WARNING,
+ "Estimating duration from bitrate, this may be inaccurate\n");
+}
+
+#define DURATION_MAX_READ_SIZE 250000LL
+#define DURATION_MAX_RETRY 6
+
+/* only usable for MPEG-PS streams */
+static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset)
+{
+ AVPacket pkt1, *pkt = &pkt1;
+ AVStream *st;
+ int num, den, read_size, i, ret;
+ int found_duration = 0;
+ int is_end;
+ int64_t filesize, offset, duration;
+ int retry = 0;
+
+ /* flush packet queue */
+ flush_packet_queue(ic);
+
+ for (i = 0; i < ic->nb_streams; i++) {
+ st = ic->streams[i];
+ if (st->start_time == AV_NOPTS_VALUE &&
+ st->first_dts == AV_NOPTS_VALUE &&
+ st->codec->codec_type != AVMEDIA_TYPE_UNKNOWN)
+ av_log(st->codec, AV_LOG_WARNING,
+ "start time for stream %d is not set in estimate_timings_from_pts\n", i);
+
+ if (st->parser) {
+ av_parser_close(st->parser);
+ st->parser = NULL;
+ }
+ }
+
+ av_opt_set(ic, "skip_changes", "1", AV_OPT_SEARCH_CHILDREN);
+ /* estimate the end time (duration) */
+ /* XXX: may need to support wrapping */
+ filesize = ic->pb ? avio_size(ic->pb) : 0;
+ do {
+ is_end = found_duration;
+ offset = filesize - (DURATION_MAX_READ_SIZE << retry);
+ if (offset < 0)
+ offset = 0;
+
+ avio_seek(ic->pb, offset, SEEK_SET);
+ read_size = 0;
+ for (;;) {
+ if (read_size >= DURATION_MAX_READ_SIZE << (FFMAX(retry - 1, 0)))
+ break;
+
+ do {
+ ret = ff_read_packet(ic, pkt);
+ } while (ret == AVERROR(EAGAIN));
+ if (ret != 0)
+ break;
+ read_size += pkt->size;
+ st = ic->streams[pkt->stream_index];
+ if (pkt->pts != AV_NOPTS_VALUE &&
+ (st->start_time != AV_NOPTS_VALUE ||
+ st->first_dts != AV_NOPTS_VALUE)) {
+ if (pkt->duration == 0) {
+ ff_compute_frame_duration(ic, &num, &den, st, st->parser, pkt);
+ if (den && num) {
+ pkt->duration = av_rescale_rnd(1,
+ num * (int64_t) st->time_base.den,
+ den * (int64_t) st->time_base.num,
+ AV_ROUND_DOWN);
+ }
+ }
+ duration = pkt->pts + pkt->duration;
+ found_duration = 1;
+ if (st->start_time != AV_NOPTS_VALUE)
+ duration -= st->start_time;
+ 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))
+ st->duration = duration;
+ st->info->last_duration = duration;
+ }
+ }
+ av_free_packet(pkt);
+ }
+
+ /* check if all audio/video streams have valid duration */
+ if (!is_end) {
+ is_end = 1;
+ for (i = 0; i < ic->nb_streams; i++) {
+ st = ic->streams[i];
+ switch (st->codec->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ case AVMEDIA_TYPE_AUDIO:
+ if (st->duration == AV_NOPTS_VALUE)
+ is_end = 0;
+ }
+ }
+ }
+ } while (!is_end &&
+ offset &&
+ ++retry <= DURATION_MAX_RETRY);
+
+ av_opt_set(ic, "skip_changes", "0", AV_OPT_SEARCH_CHILDREN);
+
+ /* warn about audio/video streams which duration could not be estimated */
+ for (i = 0; i < ic->nb_streams; i++) {
+ st = ic->streams[i];
+ if (st->duration == AV_NOPTS_VALUE) {
+ switch (st->codec->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ case AVMEDIA_TYPE_AUDIO:
+ if (st->start_time != AV_NOPTS_VALUE || st->first_dts != AV_NOPTS_VALUE) {
+ av_log(ic, AV_LOG_DEBUG, "stream %d : no PTS found at end of file, duration not set\n", i);
+ } else
+ av_log(ic, AV_LOG_DEBUG, "stream %d : no TS found at start of file, duration not set\n", i);
+ }
+ }
+ }
+ fill_all_stream_timings(ic);
+
+ avio_seek(ic->pb, old_offset, SEEK_SET);
+ for (i = 0; i < ic->nb_streams; i++) {
+ int j;
+
+ 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;
+ for (j = 0; j < MAX_REORDER_DELAY + 1; j++)
+ st->pts_buffer[j] = AV_NOPTS_VALUE;
+ }
+}
+
+static void estimate_timings(AVFormatContext *ic, int64_t old_offset)
+{
+ int64_t file_size;
+
+ /* get the file size, if possible */
+ if (ic->iformat->flags & AVFMT_NOFILE) {
+ file_size = 0;
+ } else {
+ file_size = avio_size(ic->pb);
+ file_size = FFMAX(0, file_size);
+ }
+
+ if ((!strcmp(ic->iformat->name, "mpeg") ||
+ !strcmp(ic->iformat->name, "mpegts")) &&
+ file_size && ic->pb->seekable) {
+ /* get accurate estimate from the PTSes */
+ estimate_timings_from_pts(ic, old_offset);
+ ic->duration_estimation_method = AVFMT_DURATION_FROM_PTS;
+ } else if (has_duration(ic)) {
+ /* at least one component has timings - we use them for all
+ * the components */
+ fill_all_stream_timings(ic);
+ ic->duration_estimation_method = AVFMT_DURATION_FROM_STREAM;
+ } else {
+ /* less precise: use bitrate info */
+ estimate_timings_from_bit_rate(ic);
+ ic->duration_estimation_method = AVFMT_DURATION_FROM_BITRATE;
+ }
+ update_stream_timings(ic);
+
+ {
+ int i;
+ AVStream av_unused *st;
+ for (i = 0; i < ic->nb_streams; i++) {
+ st = ic->streams[i];
+ av_log(ic, AV_LOG_TRACE, "%d: start_time: %0.3f duration: %0.3f\n", i,
+ (double) st->start_time / AV_TIME_BASE,
+ (double) st->duration / AV_TIME_BASE);
+ }
+ av_log(ic, AV_LOG_TRACE,
+ "stream: start_time: %0.3f duration: %0.3f bitrate=%d kb/s\n",
+ (double) ic->start_time / AV_TIME_BASE,
+ (double) ic->duration / AV_TIME_BASE,
+ ic->bit_rate / 1000);
+ }
+}
+
+static int has_codec_parameters(AVStream *st, const char **errmsg_ptr)
+{
+ AVCodecContext *avctx = st->codec;
+
+#define FAIL(errmsg) do { \
+ if (errmsg_ptr) \
+ *errmsg_ptr = errmsg; \
+ return 0; \
+ } while (0)
+
+ if ( avctx->codec_id == AV_CODEC_ID_NONE
+ && avctx->codec_type != AVMEDIA_TYPE_DATA)
+ FAIL("unknown codec");
+ switch (avctx->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ if (!avctx->frame_size && determinable_frame_size(avctx))
+ FAIL("unspecified frame size");
+ if (st->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)
+ 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)
+ FAIL("unspecified pixel format");
+ if (st->codec->codec_id == AV_CODEC_ID_RV30 || st->codec->codec_id == AV_CODEC_ID_RV40)
+ if (!st->sample_aspect_ratio.num && !st->codec->sample_aspect_ratio.num && !st->codec_info_nb_frames)
+ FAIL("no frame in rv30/40 and no sar");
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ if (avctx->codec_id == AV_CODEC_ID_HDMV_PGS_SUBTITLE && !avctx->width)
+ FAIL("unspecified size");
+ break;
+ case AVMEDIA_TYPE_DATA:
+ if (avctx->codec_id == AV_CODEC_ID_NONE) return 1;
+ }
+
+ return 1;
+}
+
+/* returns 1 or 0 if or if not decoded data was returned, or a negative error */
+static int try_decode_frame(AVFormatContext *s, AVStream *st, AVPacket *avpkt,
+ AVDictionary **options)
+{
+ const AVCodec *codec;
+ int got_picture = 1, ret = 0;
+ AVFrame *frame = av_frame_alloc();
+ AVSubtitle subtitle;
+ AVPacket pkt = *avpkt;
+
+ if (!frame)
+ return AVERROR(ENOMEM);
+
+ if (!avcodec_is_open(st->codec) &&
+ st->info->found_decoder <= 0 &&
+ (st->codec->codec_id != -st->info->found_decoder || !st->codec->codec_id)) {
+ AVDictionary *thread_opt = NULL;
+
+ codec = find_decoder(s, st, st->codec->codec_id);
+
+ if (!codec) {
+ st->info->found_decoder = -st->codec->codec_id;
+ ret = -1;
+ goto fail;
+ }
+
+ /* 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);
+ if (s->codec_whitelist)
+ av_dict_set(options ? options : &thread_opt, "codec_whitelist", s->codec_whitelist, 0);
+ ret = avcodec_open2(st->codec, codec, options ? options : &thread_opt);
+ if (!options)
+ av_dict_free(&thread_opt);
+ if (ret < 0) {
+ st->info->found_decoder = -st->codec->codec_id;
+ goto fail;
+ }
+ st->info->found_decoder = 1;
+ } else if (!st->info->found_decoder)
+ st->info->found_decoder = 1;
+
+ if (st->info->found_decoder < 0) {
+ ret = -1;
+ goto fail;
+ }
+
+ while ((pkt.size > 0 || (!pkt.data && got_picture)) &&
+ ret >= 0 &&
+ (!has_codec_parameters(st, NULL) || !has_decode_delay_been_guessed(st) ||
+ (!st->codec_info_nb_frames &&
+ (st->codec->codec->capabilities & AV_CODEC_CAP_CHANNEL_CONF)))) {
+ got_picture = 0;
+ switch (st->codec->codec_type) {
+ case AVMEDIA_TYPE_VIDEO:
+ ret = avcodec_decode_video2(st->codec, frame,
+ &got_picture, &pkt);
+ break;
+ case AVMEDIA_TYPE_AUDIO:
+ ret = avcodec_decode_audio4(st->codec, frame, &got_picture, &pkt);
+ break;
+ case AVMEDIA_TYPE_SUBTITLE:
+ ret = avcodec_decode_subtitle2(st->codec, &subtitle,
+ &got_picture, &pkt);
+ ret = pkt.size;
+ break;
+ default:
+ break;
+ }
+ if (ret >= 0) {
+ if (got_picture)
+ st->nb_decoded_frames++;
+ pkt.data += ret;
+ pkt.size -= ret;
+ ret = got_picture;
+ }
+ }
+
+ if (!pkt.data && !got_picture)
+ ret = -1;
+
+fail:
+ av_frame_free(&frame);
+ return ret;
+}
+
+unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id)
+{
+ while (tags->id != AV_CODEC_ID_NONE) {
+ if (tags->id == id)
+ return tags->tag;
+ tags++;
+ }
+ return 0;
+}
+
+enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag)
+{
+ int i;
+ for (i = 0; tags[i].id != AV_CODEC_ID_NONE; i++)
+ if (tag == tags[i].tag)
+ return tags[i].id;
+ for (i = 0; tags[i].id != AV_CODEC_ID_NONE; i++)
+ if (avpriv_toupper4(tag) == avpriv_toupper4(tags[i].tag))
+ return tags[i].id;
+ return AV_CODEC_ID_NONE;
+}
+
+enum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags)
+{
+ if (bps <= 0 || bps > 64)
+ return AV_CODEC_ID_NONE;
+
+ if (flt) {
+ switch (bps) {
+ case 32:
+ return be ? AV_CODEC_ID_PCM_F32BE : AV_CODEC_ID_PCM_F32LE;
+ case 64:
+ return be ? AV_CODEC_ID_PCM_F64BE : AV_CODEC_ID_PCM_F64LE;
+ default:
+ return AV_CODEC_ID_NONE;
+ }
+ } else {
+ bps += 7;
+ bps >>= 3;
+ if (sflags & (1 << (bps - 1))) {
+ switch (bps) {
+ case 1:
+ return AV_CODEC_ID_PCM_S8;
+ case 2:
+ return be ? AV_CODEC_ID_PCM_S16BE : AV_CODEC_ID_PCM_S16LE;
+ case 3:
+ return be ? AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
+ case 4:
+ return be ? AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
+ default:
+ return AV_CODEC_ID_NONE;
+ }
+ } else {
+ switch (bps) {
+ case 1:
+ return AV_CODEC_ID_PCM_U8;
+ case 2:
+ return be ? AV_CODEC_ID_PCM_U16BE : AV_CODEC_ID_PCM_U16LE;
+ case 3:
+ return be ? AV_CODEC_ID_PCM_U24BE : AV_CODEC_ID_PCM_U24LE;
+ case 4:
+ return be ? AV_CODEC_ID_PCM_U32BE : AV_CODEC_ID_PCM_U32LE;
+ default:
+ return AV_CODEC_ID_NONE;
+ }
+ }
+ }
+}
+
+unsigned int av_codec_get_tag(const AVCodecTag *const *tags, enum AVCodecID id)
+{
+ unsigned int tag;
+ if (!av_codec_get_tag2(tags, id, &tag))
+ return 0;
+ return tag;
+}
+
+int av_codec_get_tag2(const AVCodecTag * const *tags, enum AVCodecID id,
+ unsigned int *tag)
+{
+ int i;
+ for (i = 0; tags && tags[i]; i++) {
+ const AVCodecTag *codec_tags = tags[i];
+ while (codec_tags->id != AV_CODEC_ID_NONE) {
+ if (codec_tags->id == id) {
+ *tag = codec_tags->tag;
+ return 1;
+ }
+ codec_tags++;
+ }
+ }
+ return 0;
+}
+
+enum AVCodecID av_codec_get_id(const AVCodecTag *const *tags, unsigned int tag)
+{
+ int i;
+ for (i = 0; tags && tags[i]; i++) {
+ enum AVCodecID id = ff_codec_get_id(tags[i], tag);
+ if (id != AV_CODEC_ID_NONE)
+ return id;
+ }
+ return AV_CODEC_ID_NONE;
+}
+
+static void compute_chapters_end(AVFormatContext *s)
+{
+ unsigned int i, j;
+ int64_t 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;
+
+ for (j = 0; j < s->nb_chapters; j++) {
+ AVChapter *ch1 = s->chapters[j];
+ 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)
+ end = next_start;
+ }
+ ch->end = (end == INT64_MAX) ? ch->start : end;
+ }
+}
+
+static int get_std_framerate(int i)
+{
+ if (i < 30*12)
+ return (i + 1) * 1001;
+ i -= 30*12;
+
+ if (i < 30)
+ return (i + 31) * 1001 * 12;
+ i -= 30;
+
+ if (i < 3)
+ return ((const int[]) { 80, 120, 240})[i] * 1001 * 12;
+
+ i -= 3;
+
+ return ((const int[]) { 24, 30, 60, 12, 15, 48 })[i] * 1000 * 12;
+}
+
+/* Is the time base unreliable?
+ * This is a heuristic to balance between quick acceptance of the values in
+ * the headers vs. some extra checks.
+ * Old DivX and Xvid often have nonsense timebases like 1fps or 2fps.
+ * MPEG-2 commonly misuses field repeat flags to store different framerates.
+ * And there are "variable" fps files this needs to detect as well. */
+static int tb_unreliable(AVCodecContext *c)
+{
+ if (c->time_base.den >= 101LL * c->time_base.num ||
+ c->time_base.den < 5LL * c->time_base.num ||
+ // c->codec_tag == AV_RL32("DIVX") ||
+ // c->codec_tag == AV_RL32("XVID") ||
+ c->codec_tag == AV_RL32("mp4v") ||
+ c->codec_id == AV_CODEC_ID_MPEG2VIDEO ||
+ c->codec_id == AV_CODEC_ID_GIF ||
+ c->codec_id == AV_CODEC_ID_HEVC ||
+ c->codec_id == AV_CODEC_ID_H264)
+ return 1;
+ return 0;
+}
+
+int ff_alloc_extradata(AVCodecContext *avctx, int size)
+{
+ int ret;
+
+ if (size < 0 || size >= INT32_MAX - AV_INPUT_BUFFER_PADDING_SIZE) {
+ avctx->extradata = NULL;
+ avctx->extradata_size = 0;
+ return AVERROR(EINVAL);
+ }
+ avctx->extradata = av_malloc(size + AV_INPUT_BUFFER_PADDING_SIZE);
+ if (avctx->extradata) {
+ memset(avctx->extradata + size, 0, AV_INPUT_BUFFER_PADDING_SIZE);
+ avctx->extradata_size = size;
+ ret = 0;
+ } else {
+ avctx->extradata_size = 0;
+ ret = AVERROR(ENOMEM);
+ }
+ return ret;
+}
+
+int ff_get_extradata(AVCodecContext *avctx, AVIOContext *pb, int size)
+{
+ int ret = ff_alloc_extradata(avctx, size);
+ if (ret < 0)
+ return ret;
+ ret = avio_read(pb, avctx->extradata, size);
+ if (ret != size) {
+ av_freep(&avctx->extradata);
+ avctx->extradata_size = 0;
+ av_log(avctx, AV_LOG_ERROR, "Failed to read extradata of size %d\n", size);
+ return ret < 0 ? ret : AVERROR_INVALIDDATA;
+ }
+
+ return ret;
+}
+
+int ff_rfps_add_frame(AVFormatContext *ic, AVStream *st, int64_t ts)
+{
+ int i, j;
+ int64_t last = st->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)
+ return AVERROR(ENOMEM);
+
+// if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+// av_log(NULL, AV_LOG_ERROR, "%f\n", dts);
+ for (i = 0; i<MAX_STD_TIMEBASES; i++) {
+ if (st->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->info->duration_count++;
+ st->info->rfps_duration_sum += duration;
+
+ if (st->info->duration_count % 10 == 0) {
+ int n = st->info->duration_count;
+ for (i = 0; i<MAX_STD_TIMEBASES; i++) {
+ if (st->info->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 (error0 > 0.04 && error1 > 0.04) {
+ st->info->duration_error[0][1][i] = 2e10;
+ st->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 (ts != AV_NOPTS_VALUE)
+ st->info->last_dts = ts;
+
+ return 0;
+}
+
+void ff_rfps_calculate(AVFormatContext *ic)
+{
+ int i, j;
+
+ for (i = 0; i < ic->nb_streams; i++) {
+ AVStream *st = ic->streams[i];
+
+ if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO)
+ continue;
+ // the check for tb_unreliable() is not completely correct, since this is not about handling
+ // a unreliable/inexact time base, but a time base that is finer than necessary, as e.g.
+ // ipmovie.c produces.
+ if (tb_unreliable(st->codec) && 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
+ && tb_unreliable(st->codec)) {
+ int num = 0;
+ double best_error= 0.01;
+ AVRational ref_rate = st->r_frame_rate.num ? st->r_frame_rate : av_inv_q(st->time_base);
+
+ for (j= 0; j<MAX_STD_TIMEBASES; j++) {
+ int k;
+
+ if (st->info->codec_info_duration && st->info->codec_info_duration*av_q2d(st->time_base) < (1001*12.0)/get_std_framerate(j))
+ continue;
+ if (!st->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))
+ 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;
+
+ if (error < best_error && best_error> 0.000000001) {
+ best_error= error;
+ num = get_std_framerate(j);
+ }
+ if (error < 0.02)
+ av_log(ic, AV_LOG_DEBUG, "rfps: %f %f\n", get_std_framerate(j) / 12.0/1001, error);
+ }
+ }
+ // do not increase frame rate by more than 1 % in order to match a standard rate.
+ if (num && (!ref_rate.num || (double)num/(12*1001) < 1.01 * av_q2d(ref_rate)))
+ 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
+ ) {
+ 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;
+ }
+}
+
+int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options)
+{
+ int i, count, ret = 0, j;
+ int64_t read_size;
+ AVStream *st;
+ AVPacket pkt1, *pkt;
+ int64_t old_offset = avio_tell(ic->pb);
+ // new streams might appear, no options for those
+ int orig_nb_streams = ic->nb_streams;
+ int flush_codecs;
+#if FF_API_PROBESIZE_32
+ int64_t max_analyze_duration = ic->max_analyze_duration2;
+#else
+ int64_t max_analyze_duration = ic->max_analyze_duration;
+#endif
+ int64_t max_stream_analyze_duration;
+ int64_t max_subtitle_analyze_duration;
+#if FF_API_PROBESIZE_32
+ int64_t probesize = ic->probesize2;
+#else
+ int64_t probesize = ic->probesize;
+#endif
+
+ if (!max_analyze_duration)
+ max_analyze_duration = ic->max_analyze_duration;
+ if (ic->probesize)
+ probesize = ic->probesize;
+ flush_codecs = probesize > 0;
+
+ av_opt_set(ic, "skip_clear", "1", AV_OPT_SEARCH_CHILDREN);
+
+ max_stream_analyze_duration = max_analyze_duration;
+ max_subtitle_analyze_duration = max_analyze_duration;
+ if (!max_analyze_duration) {
+ max_stream_analyze_duration =
+ max_analyze_duration = 5*AV_TIME_BASE;
+ max_subtitle_analyze_duration = 30*AV_TIME_BASE;
+ if (!strcmp(ic->iformat->name, "flv"))
+ max_stream_analyze_duration = 30*AV_TIME_BASE;
+ }
+
+ if (ic->pb)
+ av_log(ic, AV_LOG_DEBUG, "Before avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d\n",
+ avio_tell(ic->pb), ic->pb->bytes_read, ic->pb->seek_count);
+
+ for (i = 0; i < ic->nb_streams; i++) {
+ const AVCodec *codec;
+ AVDictionary *thread_opt = NULL;
+ st = ic->streams[i];
+
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
+ st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+/* if (!st->time_base.num)
+ st->time_base = */
+ if (!st->codec->time_base.num)
+ st->codec->time_base = st->time_base;
+ }
+ // only for the split stuff
+ if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE) && st->request_probe <= 0) {
+ st->parser = av_parser_init(st->codec->codec_id);
+ if (st->parser) {
+ if (st->need_parsing == AVSTREAM_PARSE_HEADERS) {
+ st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
+ } else if (st->need_parsing == AVSTREAM_PARSE_FULL_RAW) {
+ st->parser->flags |= PARSER_FLAG_USE_CODEC_TS;
+ }
+ } else if (st->need_parsing) {
+ av_log(ic, AV_LOG_VERBOSE, "parser not found for codec "
+ "%s, packets or times may be invalid.\n",
+ avcodec_get_name(st->codec->codec_id));
+ }
+ }
+ codec = find_decoder(ic, st, st->codec->codec_id);
+
+ /* 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);
+
+ if (ic->codec_whitelist)
+ av_dict_set(options ? &options[i] : &thread_opt, "codec_whitelist", ic->codec_whitelist, 0);
+
+ /* Ensure that subtitle_header is properly set. */
+ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
+ && codec && !st->codec->codec) {
+ if (avcodec_open2(st->codec, codec, options ? &options[i] : &thread_opt) < 0)
+ av_log(ic, AV_LOG_WARNING,
+ "Failed to open codec in av_find_stream_info\n");
+ }
+
+ // Try to just open decoders, in case this is enough to get parameters.
+ if (!has_codec_parameters(st, NULL) && st->request_probe <= 0) {
+ if (codec && !st->codec->codec)
+ if (avcodec_open2(st->codec, codec, options ? &options[i] : &thread_opt) < 0)
+ av_log(ic, AV_LOG_WARNING,
+ "Failed to open codec in av_find_stream_info\n");
+ }
+ if (!options)
+ av_dict_free(&thread_opt);
+ }
+
+ for (i = 0; i < ic->nb_streams; i++) {
+#if FF_API_R_FRAME_RATE
+ ic->streams[i]->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;
+ }
+
+ count = 0;
+ read_size = 0;
+ for (;;) {
+ int analyzed_all_streams;
+ if (ff_check_interrupt(&ic->interrupt_callback)) {
+ ret = AVERROR_EXIT;
+ av_log(ic, AV_LOG_DEBUG, "interrupted\n");
+ break;
+ }
+
+ /* check if one codec still needs to be handled */
+ for (i = 0; i < ic->nb_streams; i++) {
+ int fps_analyze_framecount = 20;
+
+ st = ic->streams[i];
+ if (!has_codec_parameters(st, NULL))
+ break;
+ /* If the timebase is coarse (like the usual millisecond precision
+ * of mkv), we need to analyze more frames to reliably arrive at
+ * the correct fps. */
+ if (av_q2d(st->time_base) > 0.0005)
+ fps_analyze_framecount *= 2;
+ if (!tb_unreliable(st->codec))
+ fps_analyze_framecount = 0;
+ if (ic->fps_probe_size >= 0)
+ fps_analyze_framecount = ic->fps_probe_size;
+ if (st->disposition & AV_DISPOSITION_ATTACHED_PIC)
+ fps_analyze_framecount = 0;
+ /* variable fps and no guess at the real fps */
+ if (!(st->r_frame_rate.num && st->avg_frame_rate.num) &&
+ st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ int count = (ic->iformat->flags & AVFMT_NOTIMESTAMPS) ?
+ st->info->codec_info_duration_fields/2 :
+ st->info->duration_count;
+ if (count < fps_analyze_framecount)
+ break;
+ }
+ if (st->parser && st->parser->parser->split &&
+ !st->codec->extradata)
+ break;
+ if (st->first_dts == AV_NOPTS_VALUE &&
+ !(ic->iformat->flags & AVFMT_NOTIMESTAMPS) &&
+ st->codec_info_nb_frames < ic->max_ts_probe &&
+ (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
+ st->codec->codec_type == AVMEDIA_TYPE_AUDIO))
+ break;
+ }
+ analyzed_all_streams = 0;
+ if (i == ic->nb_streams) {
+ analyzed_all_streams = 1;
+ /* NOTE: If the format has no header, then we need to read some
+ * packets to get most of the streams, so we cannot stop here. */
+ if (!(ic->ctx_flags & AVFMTCTX_NOHEADER)) {
+ /* If we found the info for all the codecs, we can stop. */
+ ret = count;
+ av_log(ic, AV_LOG_DEBUG, "All info found\n");
+ flush_codecs = 0;
+ break;
+ }
+ }
+ /* We did not get all the codec info, but we read too much data. */
+ if (read_size >= probesize) {
+ ret = count;
+ av_log(ic, AV_LOG_DEBUG,
+ "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]->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
+ strcmp(ic->iformat->name, "image2"))
+ av_log(ic, AV_LOG_WARNING,
+ "Stream #%d: not enough frames to estimate rate; "
+ "consider increasing probesize\n", i);
+ break;
+ }
+
+ /* NOTE: A new stream can be added there if no header in file
+ * (AVFMTCTX_NOHEADER). */
+ ret = read_frame_internal(ic, &pkt1);
+ if (ret == AVERROR(EAGAIN))
+ continue;
+
+ if (ret < 0) {
+ /* EOF or error*/
+ break;
+ }
+
+ if (ic->flags & AVFMT_FLAG_NOBUFFER)
+ free_packet_buffer(&ic->internal->packet_buffer,
+ &ic->internal->packet_buffer_end);
+ {
+ pkt = add_to_pktbuf(&ic->internal->packet_buffer, &pkt1,
+ &ic->internal->packet_buffer_end);
+ if (!pkt) {
+ ret = AVERROR(ENOMEM);
+ goto find_stream_info_err;
+ }
+ if ((ret = av_dup_packet(pkt)) < 0)
+ goto find_stream_info_err;
+ }
+
+ st = ic->streams[pkt->stream_index];
+ if (!(st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+ read_size += pkt->size;
+
+ if (pkt->dts != AV_NOPTS_VALUE && st->codec_info_nb_frames > 1) {
+ /* check for non-increasing dts */
+ if (st->info->fps_last_dts != AV_NOPTS_VALUE &&
+ st->info->fps_last_dts >= pkt->dts) {
+ av_log(ic, AV_LOG_DEBUG,
+ "Non-increasing DTS in stream %d: packet %d with DTS "
+ "%"PRId64", packet %d with DTS %"PRId64"\n",
+ st->index, st->info->fps_last_dts_idx,
+ st->info->fps_last_dts, st->codec_info_nb_frames,
+ pkt->dts);
+ st->info->fps_first_dts =
+ st->info->fps_last_dts = AV_NOPTS_VALUE;
+ }
+ /* 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 - st->info->fps_last_dts) / 1000 >
+ (st->info->fps_last_dts - st->info->fps_first_dts) /
+ (st->info->fps_last_dts_idx - st->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,
+ pkt->dts);
+ st->info->fps_first_dts =
+ st->info->fps_last_dts = AV_NOPTS_VALUE;
+ }
+
+ /* update stored dts values */
+ if (st->info->fps_first_dts == AV_NOPTS_VALUE) {
+ st->info->fps_first_dts = pkt->dts;
+ st->info->fps_first_dts_idx = st->codec_info_nb_frames;
+ }
+ st->info->fps_last_dts = pkt->dts;
+ st->info->fps_last_dts_idx = st->codec_info_nb_frames;
+ }
+ if (st->codec_info_nb_frames>1) {
+ 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);
+ 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));
+
+ if (analyzed_all_streams) limit = max_analyze_duration;
+ else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) limit = max_subtitle_analyze_duration;
+ else limit = max_stream_analyze_duration;
+
+ if (t >= limit) {
+ av_log(ic, AV_LOG_VERBOSE, "max_analyze_duration %"PRId64" reached at %"PRId64" microseconds st:%d\n",
+ max_analyze_duration,
+ t, pkt->stream_index);
+ if (ic->flags & AVFMT_FLAG_NOBUFFER)
+ av_packet_unref(pkt);
+ break;
+ }
+ if (pkt->duration) {
+ st->info->codec_info_duration += pkt->duration;
+ st->info->codec_info_duration_fields += st->parser && st->need_parsing && st->codec->ticks_per_frame ==2 ? st->parser->repeat_pict + 1 : 2;
+ }
+ }
+#if FF_API_R_FRAME_RATE
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
+ ff_rfps_add_frame(ic, st, pkt->dts);
+#endif
+ if (st->parser && st->parser->parser->split && !st->codec->extradata) {
+ int i = st->parser->parser->split(st->codec, pkt->data, pkt->size);
+ if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) {
+ if (ff_alloc_extradata(st->codec, i))
+ return AVERROR(ENOMEM);
+ memcpy(st->codec->extradata, pkt->data,
+ st->codec->extradata_size);
+ }
+ }
+
+ /* If still no information, we try to open the codec and to
+ * decompress the frame. We try to avoid that in most cases as
+ * it takes longer and uses more memory. For MPEG-4, we need to
+ * decompress for QuickTime.
+ *
+ * If AV_CODEC_CAP_CHANNEL_CONF is set this will force decoding of at
+ * least one frame of codec data, this makes sure the codec initializes
+ * the channel configuration and does not only trust the values from
+ * the container. */
+ try_decode_frame(ic, st, pkt,
+ (options && i < orig_nb_streams) ? &options[i] : NULL);
+
+ if (ic->flags & AVFMT_FLAG_NOBUFFER)
+ av_packet_unref(pkt);
+
+ st->codec_info_nb_frames++;
+ count++;
+ }
+
+ if (flush_codecs) {
+ AVPacket empty_pkt = { 0 };
+ int err = 0;
+ av_init_packet(&empty_pkt);
+
+ for (i = 0; i < ic->nb_streams; i++) {
+
+ st = ic->streams[i];
+
+ /* flush the decoders */
+ if (st->info->found_decoder == 1) {
+ do {
+ err = try_decode_frame(ic, st, &empty_pkt,
+ (options && i < orig_nb_streams)
+ ? &options[i] : NULL);
+ } while (err > 0 && !has_codec_parameters(st, NULL));
+
+ if (err < 0) {
+ av_log(ic, AV_LOG_INFO,
+ "decoding for stream %d failed\n", st->index);
+ }
+ }
+ }
+ }
+
+ // close codecs which were opened in try_decode_frame()
+ for (i = 0; i < ic->nb_streams; i++) {
+ st = ic->streams[i];
+ avcodec_close(st->codec);
+ }
+
+ ff_rfps_calculate(ic);
+
+ for (i = 0; i < ic->nb_streams; i++) {
+ st = ic->streams[i];
+ if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ if (st->codec->codec_id == AV_CODEC_ID_RAWVIDEO && !st->codec->codec_tag && !st->codec->bits_per_coded_sample) {
+ uint32_t tag= avcodec_pix_fmt_to_codec_tag(st->codec->pix_fmt);
+ if (avpriv_find_pix_fmt(avpriv_get_raw_pix_fmt_tags(), tag) == st->codec->pix_fmt)
+ st->codec->codec_tag= tag;
+ }
+
+ /* estimate average framerate if not set by demuxer */
+ if (st->info->codec_info_duration_fields &&
+ !st->avg_frame_rate.num &&
+ st->info->codec_info_duration) {
+ int best_fps = 0;
+ double best_error = 0.01;
+
+ 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)
+ 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);
+
+ /* Round guessed framerate to a "standard" framerate if it's
+ * within 1% of the original estimate. */
+ for (j = 0; j < MAX_STD_TIMEBASES; j++) {
+ AVRational std_fps = { get_std_framerate(j), 12 * 1001 };
+ double error = fabs(av_q2d(st->avg_frame_rate) /
+ av_q2d(std_fps) - 1);
+
+ if (error < best_error) {
+ best_error = error;
+ best_fps = std_fps.num;
+ }
+ }
+ if (best_fps)
+ av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
+ best_fps, 12 * 1001, INT_MAX);
+ }
+
+ if (!st->r_frame_rate.num) {
+ if ( st->codec->time_base.den * (int64_t) st->time_base.num
+ <= st->codec->time_base.num * st->codec->ticks_per_frame * (int64_t) st->time_base.den) {
+ st->r_frame_rate.num = st->codec->time_base.den;
+ st->r_frame_rate.den = st->codec->time_base.num * st->codec->ticks_per_frame;
+ } else {
+ st->r_frame_rate.num = st->time_base.den;
+ st->r_frame_rate.den = st->time_base.num;
+ }
+ }
+ if (st->display_aspect_ratio.num && st->display_aspect_ratio.den) {
+ AVRational hw_ratio = { st->codec->height, st->codec->width };
+ st->sample_aspect_ratio = av_mul_q(st->display_aspect_ratio,
+ hw_ratio);
+ }
+ } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+ if (!st->codec->bits_per_coded_sample)
+ st->codec->bits_per_coded_sample =
+ av_get_bits_per_sample(st->codec->codec_id);
+ // set stream disposition based on audio service type
+ switch (st->codec->audio_service_type) {
+ case AV_AUDIO_SERVICE_TYPE_EFFECTS:
+ st->disposition = AV_DISPOSITION_CLEAN_EFFECTS;
+ break;
+ case AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED:
+ st->disposition = AV_DISPOSITION_VISUAL_IMPAIRED;
+ break;
+ case AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED:
+ st->disposition = AV_DISPOSITION_HEARING_IMPAIRED;
+ break;
+ case AV_AUDIO_SERVICE_TYPE_COMMENTARY:
+ st->disposition = AV_DISPOSITION_COMMENT;
+ break;
+ case AV_AUDIO_SERVICE_TYPE_KARAOKE:
+ st->disposition = AV_DISPOSITION_KARAOKE;
+ break;
+ }
+ }
+ }
+
+ if (probesize)
+ estimate_timings(ic, old_offset);
+
+ av_opt_set(ic, "skip_clear", "0", AV_OPT_SEARCH_CHILDREN);
+
+ if (ret >= 0 && ic->nb_streams)
+ /* We could not have all the codec parameters before EOF. */
+ ret = -1;
+ for (i = 0; i < ic->nb_streams; i++) {
+ const char *errmsg;
+ st = ic->streams[i];
+ if (!has_codec_parameters(st, &errmsg)) {
+ char buf[256];
+ avcodec_string(buf, sizeof(buf), st->codec, 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);
+ } else {
+ ret = 0;
+ }
+ }
+
+ compute_chapters_end(ic);
+
+find_stream_info_err:
+ for (i = 0; i < ic->nb_streams; i++) {
+ st = ic->streams[i];
+ if (ic->streams[i]->codec->codec_type != AVMEDIA_TYPE_AUDIO)
+ ic->streams[i]->codec->thread_count = 0;
+ if (st->info)
+ av_freep(&st->info->duration_error);
+ av_freep(&ic->streams[i]->info);
+ }
+ if (ic->pb)
+ av_log(ic, AV_LOG_DEBUG, "After avformat_find_stream_info() pos: %"PRId64" bytes read:%"PRId64" seeks:%d frames:%d\n",
+ avio_tell(ic->pb), ic->pb->bytes_read, ic->pb->seek_count, count);
+ return ret;
+}
+
+AVProgram *av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int s)
+{
+ int i, j;
+
+ for (i = 0; i < ic->nb_programs; i++) {
+ if (ic->programs[i] == last) {
+ last = NULL;
+ } else {
+ if (!last)
+ for (j = 0; j < ic->programs[i]->nb_stream_indexes; j++)
+ if (ic->programs[i]->stream_index[j] == s)
+ return ic->programs[i];
+ }
+ }
+ return NULL;
+}
+
+int av_find_best_stream(AVFormatContext *ic, enum AVMediaType type,
+ int wanted_stream_nb, int related_stream,
+ AVCodec **decoder_ret, int flags)
+{
+ int i, nb_streams = ic->nb_streams;
+ int ret = AVERROR_STREAM_NOT_FOUND, best_count = -1, best_bitrate = -1, best_multiframe = -1, count, bitrate, multiframe;
+ unsigned *program = NULL;
+ const AVCodec *decoder = NULL, *best_decoder = NULL;
+
+ if (related_stream >= 0 && wanted_stream_nb < 0) {
+ AVProgram *p = av_find_program_from_stream(ic, NULL, related_stream);
+ if (p) {
+ program = p->stream_index;
+ nb_streams = p->nb_stream_indexes;
+ }
+ }
+ for (i = 0; i < nb_streams; i++) {
+ int real_stream_index = program ? program[i] : i;
+ AVStream *st = ic->streams[real_stream_index];
+ AVCodecContext *avctx = st->codec;
+ if (avctx->codec_type != type)
+ continue;
+ if (wanted_stream_nb >= 0 && real_stream_index != wanted_stream_nb)
+ continue;
+ if (wanted_stream_nb != real_stream_index &&
+ st->disposition & (AV_DISPOSITION_HEARING_IMPAIRED |
+ AV_DISPOSITION_VISUAL_IMPAIRED))
+ continue;
+ if (type == AVMEDIA_TYPE_AUDIO && !(avctx->channels && avctx->sample_rate))
+ continue;
+ if (decoder_ret) {
+ decoder = find_decoder(ic, st, st->codec->codec_id);
+ if (!decoder) {
+ if (ret < 0)
+ ret = AVERROR_DECODER_NOT_FOUND;
+ continue;
+ }
+ }
+ count = st->codec_info_nb_frames;
+ bitrate = avctx->bit_rate;
+ if (!bitrate)
+ bitrate = avctx->rc_max_rate;
+ multiframe = FFMIN(5, count);
+ if ((best_multiframe > multiframe) ||
+ (best_multiframe == multiframe && best_bitrate > bitrate) ||
+ (best_multiframe == multiframe && best_bitrate == bitrate && best_count >= count))
+ continue;
+ best_count = count;
+ best_bitrate = bitrate;
+ best_multiframe = multiframe;
+ ret = real_stream_index;
+ best_decoder = decoder;
+ if (program && i == nb_streams - 1 && ret < 0) {
+ program = NULL;
+ nb_streams = ic->nb_streams;
+ /* no related stream found, try again with everything */
+ i = 0;
+ }
+ }
+ if (decoder_ret)
+ *decoder_ret = (AVCodec*)best_decoder;
+ return ret;
+}
+
+/*******************************************************/
+
+int av_read_play(AVFormatContext *s)
+{
+ if (s->iformat->read_play)
+ return s->iformat->read_play(s);
+ if (s->pb)
+ return avio_pause(s->pb, 0);
+ return AVERROR(ENOSYS);
+}
+
+int av_read_pause(AVFormatContext *s)
+{
+ if (s->iformat->read_pause)
+ return s->iformat->read_pause(s);
+ if (s->pb)
+ return avio_pause(s->pb, 1);
+ return AVERROR(ENOSYS);
+}
+
+void ff_free_stream(AVFormatContext *s, AVStream *st) {
+ int j;
+ av_assert0(s->nb_streams>0);
+ av_assert0(s->streams[ s->nb_streams - 1 ] == st);
+
+ for (j = 0; j < st->nb_side_data; j++)
+ av_freep(&st->side_data[j].data);
+ av_freep(&st->side_data);
+ st->nb_side_data = 0;
+
+ if (st->parser) {
+ av_parser_close(st->parser);
+ }
+ if (st->attached_pic.data)
+ av_free_packet(&st->attached_pic);
+ av_dict_free(&st->metadata);
+ av_freep(&st->probe_data.buf);
+ av_freep(&st->index_entries);
+ avcodec_free_context(&st->codec);
+ av_freep(&st->priv_data);
+ if (st->info)
+ av_freep(&st->info->duration_error);
+ av_freep(&st->info);
+ av_freep(&st->recommended_encoder_configuration);
+ av_freep(&st->priv_pts);
+ av_freep(&s->streams[ --s->nb_streams ]);
+}
+
+void avformat_free_context(AVFormatContext *s)
+{
+ int i;
+
+ if (!s)
+ return;
+
+ av_opt_free(s);
+ if (s->iformat && s->iformat->priv_class && s->priv_data)
+ av_opt_free(s->priv_data);
+ if (s->oformat && s->oformat->priv_class && s->priv_data)
+ av_opt_free(s->priv_data);
+
+ for (i = s->nb_streams - 1; i >= 0; i--) {
+ ff_free_stream(s, s->streams[i]);
+ }
+ for (i = s->nb_programs - 1; i >= 0; i--) {
+ av_dict_free(&s->programs[i]->metadata);
+ av_freep(&s->programs[i]->stream_index);
+ av_freep(&s->programs[i]);
+ }
+ av_freep(&s->programs);
+ av_freep(&s->priv_data);
+ while (s->nb_chapters--) {
+ av_dict_free(&s->chapters[s->nb_chapters]->metadata);
+ av_freep(&s->chapters[s->nb_chapters]);
+ }
+ av_freep(&s->chapters);
+ av_dict_free(&s->metadata);
+ av_freep(&s->streams);
+ av_freep(&s->internal);
+ flush_packet_queue(s);
+ av_free(s);
+}
+
+void avformat_close_input(AVFormatContext **ps)
+{
+ AVFormatContext *s;
+ AVIOContext *pb;
+
+ if (!ps || !*ps)
+ return;
+
+ s = *ps;
+ pb = s->pb;
+
+ if ((s->iformat && strcmp(s->iformat->name, "image2") && s->iformat->flags & AVFMT_NOFILE) ||
+ (s->flags & AVFMT_FLAG_CUSTOM_IO))
+ pb = NULL;
+
+ flush_packet_queue(s);
+
+ if (s->iformat)
+ if (s->iformat->read_close)
+ s->iformat->read_close(s);
+
+ avformat_free_context(s);
+
+ *ps = NULL;
+
+ avio_close(pb);
+}
+
+AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c)
+{
+ AVStream *st;
+ int i;
+ AVStream **streams;
+
+ if (s->nb_streams >= FFMIN(s->max_streams, INT_MAX/sizeof(*streams))) {
+ if (s->max_streams < INT_MAX/sizeof(*streams))
+ av_log(s, AV_LOG_ERROR, "Number of streams exceeds max_streams parameter (%d), see the documentation if you wish to increase it\n", s->max_streams);
+ return NULL;
+ }
+ streams = av_realloc_array(s->streams, s->nb_streams + 1, sizeof(*streams));
+ if (!streams)
+ return NULL;
+ s->streams = streams;
+
+ 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;
+
+ st->codec = avcodec_alloc_context3(c);
+ if (!st->codec) {
+ av_free(st->info);
+ av_free(st);
+ return NULL;
+ }
+ if (s->iformat) {
+ /* no default bitrate if decoding */
+ st->codec->bit_rate = 0;
+
+ /* default pts setting is MPEG-like */
+ avpriv_set_pts_info(st, 33, 1, 90000);
+ }
+
+ st->index = s->nb_streams;
+ st->start_time = AV_NOPTS_VALUE;
+ st->duration = AV_NOPTS_VALUE;
+ /* we set the current DTS to 0 so that formats without any timestamps
+ * but durations get some timestamps, formats with some unknown
+ * timestamps have their first few packets buffered and the
+ * timestamps corrected before they are returned to the user */
+ st->cur_dts = s->iformat ? RELATIVE_TS_BASE : 0;
+ st->first_dts = AV_NOPTS_VALUE;
+ st->probe_packets = MAX_PROBE_PACKETS;
+ st->pts_wrap_reference = AV_NOPTS_VALUE;
+ st->pts_wrap_behavior = AV_PTS_WRAP_IGNORE;
+
+ st->last_IP_pts = AV_NOPTS_VALUE;
+ st->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->sample_aspect_ratio = (AVRational) { 0, 1 };
+
+#if FF_API_R_FRAME_RATE
+ st->info->last_dts = AV_NOPTS_VALUE;
+#endif
+ st->info->fps_first_dts = AV_NOPTS_VALUE;
+ st->info->fps_last_dts = AV_NOPTS_VALUE;
+
+ st->inject_global_side_data = s->internal->inject_global_side_data;
+
+ s->streams[s->nb_streams++] = st;
+ return st;
+}
+
+AVProgram *av_new_program(AVFormatContext *ac, int id)
+{
+ AVProgram *program = NULL;
+ int i;
+
+ av_log(ac, AV_LOG_TRACE, "new_program: id=0x%04x\n", id);
+
+ for (i = 0; i < ac->nb_programs; i++)
+ if (ac->programs[i]->id == id)
+ program = ac->programs[i];
+
+ if (!program) {
+ program = av_mallocz(sizeof(AVProgram));
+ if (!program)
+ return NULL;
+ dynarray_add(&ac->programs, &ac->nb_programs, program);
+ program->discard = AVDISCARD_NONE;
+ }
+ 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;
+}
+
+AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base,
+ int64_t start, int64_t end, const char *title)
+{
+ AVChapter *chapter = NULL;
+ int i;
+
+ 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 (!chapter) {
+ chapter = av_mallocz(sizeof(AVChapter));
+ if (!chapter)
+ return NULL;
+ dynarray_add(&s->chapters, &s->nb_chapters, chapter);
+ }
+ av_dict_set(&chapter->metadata, "title", title, 0);
+ chapter->id = id;
+ chapter->time_base = time_base;
+ chapter->start = start;
+ chapter->end = end;
+
+ return chapter;
+}
+
+void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned idx)
+{
+ int i, j;
+ AVProgram *program = NULL;
+ void *tmp;
+
+ if (idx >= ac->nb_streams) {
+ av_log(ac, AV_LOG_ERROR, "stream index %d is not valid\n", idx);
+ return;
+ }
+
+ for (i = 0; i < ac->nb_programs; i++) {
+ if (ac->programs[i]->id != progid)
+ continue;
+ program = ac->programs[i];
+ for (j = 0; j < program->nb_stream_indexes; j++)
+ if (program->stream_index[j] == idx)
+ return;
+
+ tmp = av_realloc_array(program->stream_index, program->nb_stream_indexes+1, sizeof(unsigned int));
+ if (!tmp)
+ return;
+ program->stream_index = tmp;
+ program->stream_index[program->nb_stream_indexes++] = idx;
+ return;
+ }
+}
+
+uint64_t ff_ntp_time(void)
+{
+ return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
+}
+
+int av_get_frame_filename(char *buf, int buf_size, const char *path, int number)
+{
+ const char *p;
+ char *q, buf1[20], c;
+ int nd, len, percentd_found;
+
+ q = buf;
+ p = path;
+ percentd_found = 0;
+ for (;;) {
+ c = *p++;
+ if (c == '\0')
+ break;
+ if (c == '%') {
+ do {
+ nd = 0;
+ while (av_isdigit(*p))
+ nd = nd * 10 + *p++ - '0';
+ c = *p++;
+ } while (av_isdigit(c));
+
+ switch (c) {
+ case '%':
+ goto addchar;
+ case 'd':
+ if (percentd_found)
+ goto fail;
+ percentd_found = 1;
+ if (number < 0)
+ nd += 1;
+ snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
+ len = strlen(buf1);
+ if ((q - buf + len) > buf_size - 1)
+ goto fail;
+ memcpy(q, buf1, len);
+ q += len;
+ break;
+ default:
+ goto fail;
+ }
+ } else {
+addchar:
+ if ((q - buf) < buf_size - 1)
+ *q++ = c;
+ }
+ }
+ if (!percentd_found)
+ goto fail;
+ *q = '\0';
+ return 0;
+fail:
+ *q = '\0';
+ return -1;
+}
+
+void av_url_split(char *proto, int proto_size,
+ char *authorization, int authorization_size,
+ char *hostname, int hostname_size,
+ int *port_ptr, char *path, int path_size, const char *url)
+{
+ const char *p, *ls, *ls2, *at, *at2, *col, *brk;
+
+ if (port_ptr)
+ *port_ptr = -1;
+ if (proto_size > 0)
+ proto[0] = 0;
+ if (authorization_size > 0)
+ authorization[0] = 0;
+ if (hostname_size > 0)
+ hostname[0] = 0;
+ if (path_size > 0)
+ path[0] = 0;
+
+ /* parse protocol */
+ if ((p = strchr(url, ':'))) {
+ av_strlcpy(proto, url, FFMIN(proto_size, p + 1 - url));
+ p++; /* skip ':' */
+ if (*p == '/')
+ p++;
+ if (*p == '/')
+ p++;
+ } else {
+ /* no protocol means plain filename */
+ av_strlcpy(path, url, path_size);
+ return;
+ }
+
+ /* separate path from hostname */
+ ls = strchr(p, '/');
+ ls2 = strchr(p, '?');
+ if (!ls)
+ ls = ls2;
+ else if (ls && ls2)
+ ls = FFMIN(ls, ls2);
+ if (ls)
+ av_strlcpy(path, ls, path_size);
+ else
+ ls = &p[strlen(p)]; // XXX
+
+ /* the rest is hostname, use that to parse auth/port */
+ if (ls != p) {
+ /* authorization (user[:pass]@hostname) */
+ at2 = p;
+ while ((at = strchr(p, '@')) && at < ls) {
+ av_strlcpy(authorization, at2,
+ FFMIN(authorization_size, at + 1 - at2));
+ p = at + 1; /* skip '@' */
+ }
+
+ if (*p == '[' && (brk = strchr(p, ']')) && brk < ls) {
+ /* [host]:port */
+ av_strlcpy(hostname, p + 1,
+ FFMIN(hostname_size, brk - p));
+ if (brk[1] == ':' && port_ptr)
+ *port_ptr = atoi(brk + 2);
+ } else if ((col = strchr(p, ':')) && col < ls) {
+ av_strlcpy(hostname, p,
+ FFMIN(col + 1 - p, hostname_size));
+ if (port_ptr)
+ *port_ptr = atoi(col + 1);
+ } else
+ av_strlcpy(hostname, p,
+ FFMIN(ls + 1 - p, hostname_size));
+ }
+}
+
+char *ff_data_to_hex(char *buff, const uint8_t *src, int s, int lowercase)
+{
+ int i;
+ static const char hex_table_uc[16] = { '0', '1', '2', '3',
+ '4', '5', '6', '7',
+ '8', '9', 'A', 'B',
+ 'C', 'D', 'E', 'F' };
+ static const char hex_table_lc[16] = { '0', '1', '2', '3',
+ '4', '5', '6', '7',
+ '8', '9', 'a', 'b',
+ 'c', 'd', 'e', 'f' };
+ const char *hex_table = lowercase ? hex_table_lc : hex_table_uc;
+
+ for (i = 0; i < s; i++) {
+ buff[i * 2] = hex_table[src[i] >> 4];
+ buff[i * 2 + 1] = hex_table[src[i] & 0xF];
+ }
+
+ return buff;
+}
+
+int ff_hex_to_data(uint8_t *data, const char *p)
+{
+ int c, len, v;
+
+ len = 0;
+ v = 1;
+ for (;;) {
+ p += strspn(p, SPACE_CHARS);
+ if (*p == '\0')
+ break;
+ c = av_toupper((unsigned char) *p++);
+ if (c >= '0' && c <= '9')
+ c = c - '0';
+ else if (c >= 'A' && c <= 'F')
+ c = c - 'A' + 10;
+ else
+ break;
+ v = (v << 4) | c;
+ if (v & 0x100) {
+ if (data)
+ data[len] = v;
+ len++;
+ v = 1;
+ }
+ }
+ return len;
+}
+
+void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits,
+ unsigned int pts_num, unsigned int pts_den)
+{
+ AVRational new_tb;
+ if (av_reduce(&new_tb.num, &new_tb.den, pts_num, pts_den, INT_MAX)) {
+ if (new_tb.num != pts_num)
+ av_log(NULL, AV_LOG_DEBUG,
+ "st:%d removing common factor %d from timebase\n",
+ s->index, pts_num / new_tb.num);
+ } else
+ av_log(NULL, AV_LOG_WARNING,
+ "st:%d has too large timebase, reducing\n", s->index);
+
+ if (new_tb.num <= 0 || new_tb.den <= 0) {
+ av_log(NULL, AV_LOG_ERROR,
+ "Ignoring attempt to set invalid timebase %d/%d for st:%d\n",
+ new_tb.num, new_tb.den,
+ s->index);
+ return;
+ }
+ s->time_base = new_tb;
+ av_codec_set_pkt_timebase(s->codec, new_tb);
+ s->pts_wrap_bits = pts_wrap_bits;
+}
+
+void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf,
+ void *context)
+{
+ const char *ptr = str;
+
+ /* Parse key=value pairs. */
+ for (;;) {
+ const char *key;
+ char *dest = NULL, *dest_end;
+ int key_len, dest_len = 0;
+
+ /* Skip whitespace and potential commas. */
+ while (*ptr && (av_isspace(*ptr) || *ptr == ','))
+ ptr++;
+ if (!*ptr)
+ break;
+
+ key = ptr;
+
+ if (!(ptr = strchr(key, '=')))
+ break;
+ ptr++;
+ key_len = ptr - key;
+
+ callback_get_buf(context, key, key_len, &dest, &dest_len);
+ dest_end = dest + dest_len - 1;
+
+ if (*ptr == '\"') {
+ ptr++;
+ while (*ptr && *ptr != '\"') {
+ if (*ptr == '\\') {
+ if (!ptr[1])
+ break;
+ if (dest && dest < dest_end)
+ *dest++ = ptr[1];
+ ptr += 2;
+ } else {
+ if (dest && dest < dest_end)
+ *dest++ = *ptr;
+ ptr++;
+ }
+ }
+ if (*ptr == '\"')
+ ptr++;
+ } else {
+ for (; *ptr && !(av_isspace(*ptr) || *ptr == ','); ptr++)
+ if (dest && dest < dest_end)
+ *dest++ = *ptr;
+ }
+ if (dest)
+ *dest = 0;
+ }
+}
+
+int ff_find_stream_index(AVFormatContext *s, int id)
+{
+ int i;
+ for (i = 0; i < s->nb_streams; i++)
+ if (s->streams[i]->id == id)
+ return i;
+ return -1;
+}
+
+int64_t ff_iso8601_to_unix_time(const char *datestr)
+{
+ struct tm time1 = { 0 }, time2 = { 0 };
+ const char *ret1, *ret2;
+ ret1 = av_small_strptime(datestr, "%Y - %m - %d %T", &time1);
+ ret2 = av_small_strptime(datestr, "%Y - %m - %dT%T", &time2);
+ if (ret2 && !ret1)
+ return av_timegm(&time2);
+ else
+ return av_timegm(&time1);
+}
+
+int avformat_query_codec(const AVOutputFormat *ofmt, enum AVCodecID codec_id,
+ int std_compliance)
+{
+ if (ofmt) {
+ unsigned int codec_tag;
+ if (ofmt->query_codec)
+ return ofmt->query_codec(codec_id, std_compliance);
+ else if (ofmt->codec_tag)
+ return !!av_codec_get_tag2(ofmt->codec_tag, codec_id, &codec_tag);
+ else if (codec_id == ofmt->video_codec ||
+ codec_id == ofmt->audio_codec ||
+ codec_id == ofmt->subtitle_codec)
+ return 1;
+ }
+ return AVERROR_PATCHWELCOME;
+}
+
+int avformat_network_init(void)
+{
+#if CONFIG_NETWORK
+ int ret;
+ ff_network_inited_globally = 1;
+ if ((ret = ff_network_init()) < 0)
+ return ret;
+ if ((ret = ff_tls_init()) < 0)
+ return ret;
+#endif
+ return 0;
+}
+
+int avformat_network_deinit(void)
+{
+#if CONFIG_NETWORK
+ ff_network_close();
+ ff_tls_deinit();
+ ff_network_inited_globally = 0;
+#endif
+ return 0;
+}
+
+int ff_add_param_change(AVPacket *pkt, int32_t channels,
+ uint64_t channel_layout, int32_t sample_rate,
+ int32_t width, int32_t height)
+{
+ uint32_t flags = 0;
+ int size = 4;
+ uint8_t *data;
+ if (!pkt)
+ return AVERROR(EINVAL);
+ if (channels) {
+ size += 4;
+ flags |= AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_COUNT;
+ }
+ if (channel_layout) {
+ size += 8;
+ flags |= AV_SIDE_DATA_PARAM_CHANGE_CHANNEL_LAYOUT;
+ }
+ if (sample_rate) {
+ size += 4;
+ flags |= AV_SIDE_DATA_PARAM_CHANGE_SAMPLE_RATE;
+ }
+ if (width || height) {
+ size += 8;
+ flags |= AV_SIDE_DATA_PARAM_CHANGE_DIMENSIONS;
+ }
+ data = av_packet_new_side_data(pkt, AV_PKT_DATA_PARAM_CHANGE, size);
+ if (!data)
+ return AVERROR(ENOMEM);
+ bytestream_put_le32(&data, flags);
+ if (channels)
+ bytestream_put_le32(&data, channels);
+ if (channel_layout)
+ bytestream_put_le64(&data, channel_layout);
+ if (sample_rate)
+ bytestream_put_le32(&data, sample_rate);
+ if (width || height) {
+ bytestream_put_le32(&data, width);
+ bytestream_put_le32(&data, height);
+ }
+ return 0;
+}
+
+AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame)
+{
+ AVRational undef = {0, 1};
+ AVRational stream_sample_aspect_ratio = stream ? stream->sample_aspect_ratio : undef;
+ AVRational codec_sample_aspect_ratio = stream && stream->codec ? stream->codec->sample_aspect_ratio : undef;
+ AVRational frame_sample_aspect_ratio = frame ? frame->sample_aspect_ratio : codec_sample_aspect_ratio;
+
+ av_reduce(&stream_sample_aspect_ratio.num, &stream_sample_aspect_ratio.den,
+ stream_sample_aspect_ratio.num, stream_sample_aspect_ratio.den, INT_MAX);
+ if (stream_sample_aspect_ratio.num <= 0 || stream_sample_aspect_ratio.den <= 0)
+ stream_sample_aspect_ratio = undef;
+
+ av_reduce(&frame_sample_aspect_ratio.num, &frame_sample_aspect_ratio.den,
+ frame_sample_aspect_ratio.num, frame_sample_aspect_ratio.den, INT_MAX);
+ if (frame_sample_aspect_ratio.num <= 0 || frame_sample_aspect_ratio.den <= 0)
+ frame_sample_aspect_ratio = undef;
+
+ if (stream_sample_aspect_ratio.num)
+ return stream_sample_aspect_ratio;
+ else
+ return frame_sample_aspect_ratio;
+}
+
+AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *frame)
+{
+ AVRational fr = st->r_frame_rate;
+ AVRational codec_fr = st->codec->framerate;
+ AVRational avg_fr = st->avg_frame_rate;
+
+ if (avg_fr.num > 0 && avg_fr.den > 0 && fr.num > 0 && fr.den > 0 &&
+ av_q2d(avg_fr) < 70 && av_q2d(fr) > 210) {
+ fr = avg_fr;
+ }
+
+
+ if (st->codec->ticks_per_frame > 1) {
+ if ( codec_fr.num > 0 && codec_fr.den > 0 &&
+ (fr.num == 0 || av_q2d(codec_fr) < av_q2d(fr)*0.7 && fabs(1.0 - av_q2d(av_div_q(avg_fr, fr))) > 0.1))
+ fr = codec_fr;
+ }
+
+ return fr;
+}
+
+int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st,
+ const char *spec)
+{
+ if (*spec <= '9' && *spec >= '0') /* opt:index */
+ return strtol(spec, NULL, 0) == st->index;
+ else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
+ *spec == 't' || *spec == 'V') { /* opt:[vasdtV] */
+ enum AVMediaType type;
+ int nopic = 0;
+
+ switch (*spec++) {
+ case 'v': type = AVMEDIA_TYPE_VIDEO; break;
+ case 'a': type = AVMEDIA_TYPE_AUDIO; break;
+ case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
+ case 'd': type = AVMEDIA_TYPE_DATA; break;
+ case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
+ case 'V': type = AVMEDIA_TYPE_VIDEO; nopic = 1; break;
+ default: av_assert0(0);
+ }
+ if (type != st->codec->codec_type)
+ return 0;
+ if (nopic && (st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+ return 0;
+ if (*spec++ == ':') { /* possibly followed by :index */
+ int i, index = strtol(spec, NULL, 0);
+ for (i = 0; i < s->nb_streams; i++)
+ if (s->streams[i]->codec->codec_type == type &&
+ !(nopic && (st->disposition & AV_DISPOSITION_ATTACHED_PIC)) &&
+ index-- == 0)
+ return i == st->index;
+ return 0;
+ }
+ return 1;
+ } else if (*spec == 'p' && *(spec + 1) == ':') {
+ int prog_id, i, j;
+ char *endptr;
+ spec += 2;
+ prog_id = strtol(spec, &endptr, 0);
+ for (i = 0; i < s->nb_programs; i++) {
+ if (s->programs[i]->id != prog_id)
+ continue;
+
+ if (*endptr++ == ':') {
+ int stream_idx = strtol(endptr, NULL, 0);
+ return stream_idx >= 0 &&
+ stream_idx < s->programs[i]->nb_stream_indexes &&
+ st->index == s->programs[i]->stream_index[stream_idx];
+ }
+
+ for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
+ if (st->index == s->programs[i]->stream_index[j])
+ return 1;
+ }
+ return 0;
+ } else if (*spec == '#' ||
+ (*spec == 'i' && *(spec + 1) == ':')) {
+ int stream_id;
+ char *endptr;
+ spec += 1 + (*spec == 'i');
+ stream_id = strtol(spec, &endptr, 0);
+ if (!*endptr)
+ return stream_id == st->id;
+ } else if (*spec == 'm' && *(spec + 1) == ':') {
+ AVDictionaryEntry *tag;
+ char *key, *val;
+ int ret;
+
+ spec += 2;
+ val = strchr(spec, ':');
+
+ key = val ? av_strndup(spec, val - spec) : av_strdup(spec);
+ if (!key)
+ return AVERROR(ENOMEM);
+
+ tag = av_dict_get(st->metadata, key, NULL, 0);
+ if (tag) {
+ if (!val || !strcmp(tag->value, val + 1))
+ ret = 1;
+ else
+ ret = 0;
+ } else
+ ret = 0;
+
+ av_freep(&key);
+ return ret;
+ } else if (*spec == 'u') {
+ AVCodecContext *avctx = st->codec;
+ int val;
+ switch (avctx->codec_type) {
+ case AVMEDIA_TYPE_AUDIO:
+ val = avctx->sample_rate && avctx->channels;
+ if (avctx->sample_fmt == AV_SAMPLE_FMT_NONE)
+ return 0;
+ break;
+ case AVMEDIA_TYPE_VIDEO:
+ val = avctx->width && avctx->height;
+ if (avctx->pix_fmt == AV_PIX_FMT_NONE)
+ return 0;
+ break;
+ case AVMEDIA_TYPE_UNKNOWN:
+ val = 0;
+ break;
+ default:
+ val = 1;
+ break;
+ }
+ return avctx->codec_id != AV_CODEC_ID_NONE && val != 0;
+ } else if (!*spec) /* empty specifier, matches everything */
+ return 1;
+
+ av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
+ return AVERROR(EINVAL);
+}
+
+int ff_generate_avci_extradata(AVStream *st)
+{
+ static const uint8_t avci100_1080p_extradata[] = {
+ // SPS
+ 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
+ 0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
+ 0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
+ 0x18, 0x21, 0x02, 0x56, 0xb9, 0x3d, 0x7d, 0x7e,
+ 0x4f, 0xe3, 0x3f, 0x11, 0xf1, 0x9e, 0x08, 0xb8,
+ 0x8c, 0x54, 0x43, 0xc0, 0x78, 0x02, 0x27, 0xe2,
+ 0x70, 0x1e, 0x30, 0x10, 0x10, 0x14, 0x00, 0x00,
+ 0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xca,
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // PPS
+ 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
+ 0xd0
+ };
+ static const uint8_t avci100_1080i_extradata[] = {
+ // SPS
+ 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
+ 0xb6, 0xd4, 0x20, 0x22, 0x33, 0x19, 0xc6, 0x63,
+ 0x23, 0x21, 0x01, 0x11, 0x98, 0xce, 0x33, 0x19,
+ 0x18, 0x21, 0x03, 0x3a, 0x46, 0x65, 0x6a, 0x65,
+ 0x24, 0xad, 0xe9, 0x12, 0x32, 0x14, 0x1a, 0x26,
+ 0x34, 0xad, 0xa4, 0x41, 0x82, 0x23, 0x01, 0x50,
+ 0x2b, 0x1a, 0x24, 0x69, 0x48, 0x30, 0x40, 0x2e,
+ 0x11, 0x12, 0x08, 0xc6, 0x8c, 0x04, 0x41, 0x28,
+ 0x4c, 0x34, 0xf0, 0x1e, 0x01, 0x13, 0xf2, 0xe0,
+ 0x3c, 0x60, 0x20, 0x20, 0x28, 0x00, 0x00, 0x03,
+ 0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x94, 0x20,
+ // PPS
+ 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x33, 0x48,
+ 0xd0
+ };
+ static const uint8_t avci50_1080p_extradata[] = {
+ // SPS
+ 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
+ 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
+ 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
+ 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
+ 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
+ 0x6e, 0x6c, 0xd3, 0x3c, 0x05, 0xa0, 0x22, 0x7e,
+ 0x5f, 0xfc, 0x00, 0x0c, 0x00, 0x13, 0x8c, 0x04,
+ 0x04, 0x05, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00,
+ 0x00, 0x03, 0x00, 0x32, 0x84, 0x00, 0x00, 0x00,
+ // PPS
+ 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
+ 0x11
+ };
+ static const uint8_t avci50_1080i_extradata[] = {
+ // SPS
+ 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x28,
+ 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
+ 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
+ 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6e, 0x61,
+ 0x87, 0x3e, 0x73, 0x4d, 0x98, 0x0c, 0x03, 0x06,
+ 0x9c, 0x0b, 0x73, 0xe6, 0xc0, 0xb5, 0x18, 0x63,
+ 0x0d, 0x39, 0xe0, 0x5b, 0x02, 0xd4, 0xc6, 0x19,
+ 0x1a, 0x79, 0x8c, 0x32, 0x34, 0x24, 0xf0, 0x16,
+ 0x81, 0x13, 0xf7, 0xff, 0x80, 0x02, 0x00, 0x01,
+ 0xf1, 0x80, 0x80, 0x80, 0xa0, 0x00, 0x00, 0x03,
+ 0x00, 0x20, 0x00, 0x00, 0x06, 0x50, 0x80, 0x00,
+ // PPS
+ 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
+ 0x11
+ };
+ static const uint8_t avci100_720p_extradata[] = {
+ // SPS
+ 0x00, 0x00, 0x00, 0x01, 0x67, 0x7a, 0x10, 0x29,
+ 0xb6, 0xd4, 0x20, 0x2a, 0x33, 0x1d, 0xc7, 0x62,
+ 0xa1, 0x08, 0x40, 0x54, 0x66, 0x3b, 0x8e, 0xc5,
+ 0x42, 0x02, 0x10, 0x25, 0x64, 0x2c, 0x89, 0xe8,
+ 0x85, 0xe4, 0x21, 0x4b, 0x90, 0x83, 0x06, 0x95,
+ 0xd1, 0x06, 0x46, 0x97, 0x20, 0xc8, 0xd7, 0x43,
+ 0x08, 0x11, 0xc2, 0x1e, 0x4c, 0x91, 0x0f, 0x01,
+ 0x40, 0x16, 0xec, 0x07, 0x8c, 0x04, 0x04, 0x05,
+ 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03,
+ 0x00, 0x64, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // PPS
+ 0x00, 0x00, 0x00, 0x01, 0x68, 0xce, 0x31, 0x12,
+ 0x11
+ };
+ static const uint8_t avci50_720p_extradata[] = {
+ // SPS
+ 0x00, 0x00, 0x00, 0x01, 0x67, 0x6e, 0x10, 0x20,
+ 0xa6, 0xd4, 0x20, 0x32, 0x33, 0x0c, 0x71, 0x18,
+ 0x88, 0x62, 0x10, 0x19, 0x19, 0x86, 0x38, 0x8c,
+ 0x44, 0x30, 0x21, 0x02, 0x56, 0x4e, 0x6f, 0x37,
+ 0xcd, 0xf9, 0xbf, 0x81, 0x6b, 0xf3, 0x7c, 0xde,
+ 0x6e, 0x6c, 0xd3, 0x3c, 0x0f, 0x01, 0x6e, 0xff,
+ 0xc0, 0x00, 0xc0, 0x01, 0x38, 0xc0, 0x40, 0x40,
+ 0x50, 0x00, 0x00, 0x03, 0x00, 0x10, 0x00, 0x00,
+ 0x06, 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+ // PPS
+ 0x00, 0x00, 0x00, 0x01, 0x68, 0xee, 0x31, 0x12,
+ 0x11
+ };
+
+ const uint8_t *data = NULL;
+ int size = 0;
+
+ if (st->codec->width == 1920) {
+ if (st->codec->field_order == AV_FIELD_PROGRESSIVE) {
+ data = avci100_1080p_extradata;
+ size = sizeof(avci100_1080p_extradata);
+ } else {
+ data = avci100_1080i_extradata;
+ size = sizeof(avci100_1080i_extradata);
+ }
+ } else if (st->codec->width == 1440) {
+ if (st->codec->field_order == AV_FIELD_PROGRESSIVE) {
+ data = avci50_1080p_extradata;
+ size = sizeof(avci50_1080p_extradata);
+ } else {
+ data = avci50_1080i_extradata;
+ size = sizeof(avci50_1080i_extradata);
+ }
+ } else if (st->codec->width == 1280) {
+ data = avci100_720p_extradata;
+ size = sizeof(avci100_720p_extradata);
+ } else if (st->codec->width == 960) {
+ data = avci50_720p_extradata;
+ size = sizeof(avci50_720p_extradata);
+ }
+
+ if (!size)
+ return 0;
+
+ av_freep(&st->codec->extradata);
+ if (ff_alloc_extradata(st->codec, size))
+ return AVERROR(ENOMEM);
+ memcpy(st->codec->extradata, data, size);
+
+ return 0;
+}
+
+uint8_t *av_stream_get_side_data(AVStream *st, enum AVPacketSideDataType type,
+ int *size)
+{
+ int i;
+
+ for (i = 0; i < st->nb_side_data; i++) {
+ if (st->side_data[i].type == type) {
+ if (size)
+ *size = st->side_data[i].size;
+ return st->side_data[i].data;
+ }
+ }
+ return NULL;
+}
+
+uint8_t *ff_stream_new_side_data(AVStream *st, enum AVPacketSideDataType type,
+ int size)
+{
+ AVPacketSideData *sd, *tmp;
+ int i;
+ uint8_t *data = av_malloc(size);
+
+ if (!data)
+ return NULL;
+
+ for (i = 0; i < st->nb_side_data; i++) {
+ sd = &st->side_data[i];
+
+ if (sd->type == type) {
+ av_freep(&sd->data);
+ sd->data = data;
+ sd->size = size;
+ return sd->data;
+ }
+ }
+
+ tmp = av_realloc_array(st->side_data, st->nb_side_data + 1, sizeof(*tmp));
+ if (!tmp) {
+ av_freep(&data);
+ return NULL;
+ }
+
+ st->side_data = tmp;
+ st->nb_side_data++;
+
+ sd = &st->side_data[st->nb_side_data - 1];
+ sd->type = type;
+ sd->data = data;
+ sd->size = size;
+ return data;
+}
diff --git a/ffmpeg-2-8-11/libavformat/vc1test.c b/ffmpeg-2-8-12/libavformat/vc1test.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/vc1test.c
rename to ffmpeg-2-8-12/libavformat/vc1test.c
diff --git a/ffmpeg-2-8-11/libavformat/vc1testenc.c b/ffmpeg-2-8-12/libavformat/vc1testenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/vc1testenc.c
rename to ffmpeg-2-8-12/libavformat/vc1testenc.c
diff --git a/ffmpeg-2-8-11/libavformat/version.h b/ffmpeg-2-8-12/libavformat/version.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/version.h
rename to ffmpeg-2-8-12/libavformat/version.h
diff --git a/ffmpeg-2-8-11/libavformat/vivo.c b/ffmpeg-2-8-12/libavformat/vivo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/vivo.c
rename to ffmpeg-2-8-12/libavformat/vivo.c
diff --git a/ffmpeg-2-8-11/libavformat/voc.c b/ffmpeg-2-8-12/libavformat/voc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/voc.c
rename to ffmpeg-2-8-12/libavformat/voc.c
diff --git a/ffmpeg-2-8-11/libavformat/voc.h b/ffmpeg-2-8-12/libavformat/voc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/voc.h
rename to ffmpeg-2-8-12/libavformat/voc.h
diff --git a/ffmpeg-2-8-11/libavformat/vocdec.c b/ffmpeg-2-8-12/libavformat/vocdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/vocdec.c
rename to ffmpeg-2-8-12/libavformat/vocdec.c
diff --git a/ffmpeg-2-8-11/libavformat/vocenc.c b/ffmpeg-2-8-12/libavformat/vocenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/vocenc.c
rename to ffmpeg-2-8-12/libavformat/vocenc.c
diff --git a/ffmpeg-2-8-11/libavformat/vorbiscomment.c b/ffmpeg-2-8-12/libavformat/vorbiscomment.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/vorbiscomment.c
rename to ffmpeg-2-8-12/libavformat/vorbiscomment.c
diff --git a/ffmpeg-2-8-11/libavformat/vorbiscomment.h b/ffmpeg-2-8-12/libavformat/vorbiscomment.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/vorbiscomment.h
rename to ffmpeg-2-8-12/libavformat/vorbiscomment.h
diff --git a/ffmpeg-2-8-11/libavformat/vplayerdec.c b/ffmpeg-2-8-12/libavformat/vplayerdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/vplayerdec.c
rename to ffmpeg-2-8-12/libavformat/vplayerdec.c
diff --git a/ffmpeg-2-8-11/libavformat/vqf.c b/ffmpeg-2-8-12/libavformat/vqf.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/vqf.c
rename to ffmpeg-2-8-12/libavformat/vqf.c
diff --git a/ffmpeg-2-8-11/libavformat/w64.c b/ffmpeg-2-8-12/libavformat/w64.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/w64.c
rename to ffmpeg-2-8-12/libavformat/w64.c
diff --git a/ffmpeg-2-8-11/libavformat/w64.h b/ffmpeg-2-8-12/libavformat/w64.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/w64.h
rename to ffmpeg-2-8-12/libavformat/w64.h
diff --git a/ffmpeg-2-8-12/libavformat/wavdec.c b/ffmpeg-2-8-12/libavformat/wavdec.c
new file mode 100644
index 0000000..443a79c
--- /dev/null
+++ b/ffmpeg-2-8-12/libavformat/wavdec.c
@@ -0,0 +1,795 @@
+/*
+ * WAV demuxer
+ * Copyright (c) 2001, 2002 Fabrice Bellard
+ *
+ * Sony Wave64 demuxer
+ * RF64 demuxer
+ * Copyright (c) 2009 Daniel Verkamp
+ *
+ * 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 <stdint.h>
+
+#include "libavutil/avassert.h"
+#include "libavutil/dict.h"
+#include "libavutil/intreadwrite.h"
+#include "libavutil/log.h"
+#include "libavutil/mathematics.h"
+#include "libavutil/opt.h"
+#include "avformat.h"
+#include "avio.h"
+#include "avio_internal.h"
+#include "internal.h"
+#include "metadata.h"
+#include "pcm.h"
+#include "riff.h"
+#include "w64.h"
+#include "spdif.h"
+
+typedef struct WAVDemuxContext {
+ const AVClass *class;
+ int64_t data_end;
+ int w64;
+ int64_t smv_data_ofs;
+ int smv_block_size;
+ int smv_frames_per_jpeg;
+ int smv_block;
+ int smv_last_stream;
+ int smv_eof;
+ int audio_eof;
+ int ignore_length;
+ 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;
+
+#if CONFIG_WAV_DEMUXER
+
+static int64_t next_tag(AVIOContext *pb, uint32_t *tag, int big_endian)
+{
+ *tag = avio_rl32(pb);
+ if (!big_endian) {
+ return avio_rl32(pb);
+ } else {
+ return avio_rb32(pb);
+ }
+}
+
+/* RIFF chunks are always at even offsets relative to where they start. */
+static int64_t wav_seek_tag(WAVDemuxContext * wav, AVIOContext *s, int64_t offset, int whence)
+{
+ offset += offset < INT64_MAX && offset + wav->unaligned & 1;
+
+ return avio_seek(s, offset, whence);
+}
+
+/* return the size of the found tag */
+static int64_t find_tag(WAVDemuxContext * wav, AVIOContext *pb, uint32_t tag1)
+{
+ unsigned int tag;
+ int64_t size;
+
+ for (;;) {
+ if (avio_feof(pb))
+ return AVERROR_EOF;
+ size = next_tag(pb, &tag, wav->rifx);
+ if (tag == tag1)
+ break;
+ wav_seek_tag(wav, pb, size, SEEK_CUR);
+ }
+ return size;
+}
+
+static int wav_probe(AVProbeData *p)
+{
+ /* check file header */
+ if (p->buf_size <= 32)
+ return 0;
+ if (!memcmp(p->buf + 8, "WAVE", 4)) {
+ if (!memcmp(p->buf, "RIFF", 4) || !memcmp(p->buf, "RIFX", 4))
+ /* Since the ACT demuxer has a standard WAV header at the top of
+ * 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) &&
+ !memcmp(p->buf + 12, "ds64", 4))
+ return AVPROBE_SCORE_MAX;
+ }
+ return 0;
+}
+
+static void handle_stream_probing(AVStream *st)
+{
+ if (st->codec->codec_id == AV_CODEC_ID_PCM_S16LE) {
+ st->request_probe = AVPROBE_SCORE_EXTENSION;
+ st->probe_packets = FFMIN(st->probe_packets, 32);
+ }
+}
+
+static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st)
+{
+ AVIOContext *pb = s->pb;
+ WAVDemuxContext *wav = s->priv_data;
+ int ret;
+
+ /* parse fmt header */
+ *st = avformat_new_stream(s, NULL);
+ if (!*st)
+ return AVERROR(ENOMEM);
+
+ ret = ff_get_wav_header(s, pb, (*st)->codec, size, wav->rifx);
+ if (ret < 0)
+ return ret;
+ handle_stream_probing(*st);
+
+ (*st)->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+
+ avpriv_set_pts_info(*st, 64, 1, (*st)->codec->sample_rate);
+
+ return 0;
+}
+
+static inline int wav_parse_bext_string(AVFormatContext *s, const char *key,
+ int length)
+{
+ char temp[257];
+ int ret;
+
+ av_assert0(length <= sizeof(temp));
+ if ((ret = avio_read(s->pb, temp, length)) < 0)
+ return ret;
+
+ temp[length] = 0;
+
+ if (strlen(temp))
+ return av_dict_set(&s->metadata, key, temp, 0);
+
+ return 0;
+}
+
+static int wav_parse_bext_tag(AVFormatContext *s, int64_t size)
+{
+ char temp[131], *coding_history;
+ int ret, x;
+ uint64_t time_reference;
+ int64_t umid_parts[8], umid_mask = 0;
+
+ if ((ret = wav_parse_bext_string(s, "description", 256)) < 0 ||
+ (ret = wav_parse_bext_string(s, "originator", 32)) < 0 ||
+ (ret = wav_parse_bext_string(s, "originator_reference", 32)) < 0 ||
+ (ret = wav_parse_bext_string(s, "origination_date", 10)) < 0 ||
+ (ret = wav_parse_bext_string(s, "origination_time", 8)) < 0)
+ return ret;
+
+ time_reference = avio_rl64(s->pb);
+ snprintf(temp, sizeof(temp), "%"PRIu64, time_reference);
+ if ((ret = av_dict_set(&s->metadata, "time_reference", temp, 0)) < 0)
+ return ret;
+
+ /* check if version is >= 1, in which case an UMID may be present */
+ if (avio_rl16(s->pb) >= 1) {
+ for (x = 0; x < 8; x++)
+ umid_mask |= umid_parts[x] = avio_rb64(s->pb);
+
+ if (umid_mask) {
+ /* the string formatting below is per SMPTE 330M-2004 Annex C */
+ if (umid_parts[4] == 0 && umid_parts[5] == 0 &&
+ umid_parts[6] == 0 && umid_parts[7] == 0) {
+ /* basic UMID */
+ snprintf(temp, sizeof(temp),
+ "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
+ umid_parts[0], umid_parts[1],
+ umid_parts[2], umid_parts[3]);
+ } else {
+ /* extended UMID */
+ snprintf(temp, sizeof(temp),
+ "0x%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64
+ "%016"PRIX64"%016"PRIX64"%016"PRIX64"%016"PRIX64,
+ umid_parts[0], umid_parts[1],
+ umid_parts[2], umid_parts[3],
+ umid_parts[4], umid_parts[5],
+ umid_parts[6], umid_parts[7]);
+ }
+
+ if ((ret = av_dict_set(&s->metadata, "umid", temp, 0)) < 0)
+ return ret;
+ }
+
+ avio_skip(s->pb, 190);
+ } else
+ avio_skip(s->pb, 254);
+
+ if (size > 602) {
+ /* CodingHistory present */
+ size -= 602;
+
+ if (!(coding_history = av_malloc(size + 1)))
+ return AVERROR(ENOMEM);
+
+ if ((ret = avio_read(s->pb, coding_history, size)) < 0)
+ return ret;
+
+ coding_history[size] = 0;
+ if ((ret = av_dict_set(&s->metadata, "coding_history", coding_history,
+ AV_DICT_DONT_STRDUP_VAL)) < 0)
+ return ret;
+ }
+
+ return 0;
+}
+
+static const AVMetadataConv wav_metadata_conv[] = {
+ { "description", "comment" },
+ { "originator", "encoded_by" },
+ { "origination_date", "date" },
+ { "origination_time", "creation_time" },
+ { 0 },
+};
+
+/* wav input */
+static int wav_read_header(AVFormatContext *s)
+{
+ int64_t size, av_uninit(data_size);
+ int64_t sample_count = 0;
+ int rf64 = 0;
+ char start_code[32];
+ uint32_t tag;
+ AVIOContext *pb = s->pb;
+ AVStream *st = NULL;
+ WAVDemuxContext *wav = s->priv_data;
+ int ret, got_fmt = 0;
+ int64_t next_tag_ofs, data_ofs = -1;
+
+ wav->unaligned = avio_tell(s->pb) & 1;
+
+ wav->smv_data_ofs = -1;
+
+ /* read chunk ID */
+ tag = avio_rl32(pb);
+ switch (tag) {
+ case MKTAG('R', 'I', 'F', 'F'):
+ break;
+ case MKTAG('R', 'I', 'F', 'X'):
+ wav->rifx = 1;
+ break;
+ case MKTAG('R', 'F', '6', '4'):
+ rf64 = 1;
+ break;
+ default:
+ av_get_codec_tag_string(start_code, sizeof(start_code), tag);
+ av_log(s, AV_LOG_ERROR, "invalid start code %s in RIFF header\n", start_code);
+ return AVERROR_INVALIDDATA;
+ }
+
+ /* read chunk size */
+ avio_rl32(pb);
+
+ /* read format */
+ if (avio_rl32(pb) != MKTAG('W', 'A', 'V', 'E')) {
+ av_log(s, AV_LOG_ERROR, "invalid format in RIFF header\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (rf64) {
+ if (avio_rl32(pb) != MKTAG('d', 's', '6', '4'))
+ return AVERROR_INVALIDDATA;
+ size = avio_rl32(pb);
+ if (size < 24)
+ return AVERROR_INVALIDDATA;
+ avio_rl64(pb); /* RIFF size */
+
+ data_size = avio_rl64(pb);
+ sample_count = avio_rl64(pb);
+
+ if (data_size < 0 || sample_count < 0) {
+ av_log(s, AV_LOG_ERROR, "negative data_size and/or sample_count in "
+ "ds64: data_size = %"PRId64", sample_count = %"PRId64"\n",
+ data_size, sample_count);
+ return AVERROR_INVALIDDATA;
+ }
+ avio_skip(pb, size - 24); /* skip rest of ds64 chunk */
+
+ }
+
+ for (;;) {
+ AVStream *vst;
+ size = next_tag(pb, &tag, wav->rifx);
+ next_tag_ofs = avio_tell(pb) + size;
+
+ if (avio_feof(pb))
+ break;
+
+ switch (tag) {
+ case MKTAG('f', 'm', 't', ' '):
+ /* only parse the first 'fmt ' tag found */
+ if (!got_fmt && (ret = wav_parse_fmt_tag(s, size, &st)) < 0) {
+ return ret;
+ } else if (got_fmt)
+ av_log(s, AV_LOG_WARNING, "found more than one 'fmt ' tag\n");
+
+ got_fmt = 1;
+ break;
+ case MKTAG('d', 'a', 't', 'a'):
+ if (!got_fmt) {
+ av_log(s, AV_LOG_ERROR,
+ "found no 'fmt ' tag before the 'data' tag\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (rf64) {
+ next_tag_ofs = wav->data_end = avio_tell(pb) + data_size;
+ } else if (size != 0xFFFFFFFF) {
+ data_size = size;
+ next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX;
+ } else {
+ av_log(s, AV_LOG_WARNING, "Ignoring maximum wav data size, "
+ "file may be invalid\n");
+ data_size = 0;
+ next_tag_ofs = wav->data_end = INT64_MAX;
+ }
+
+ data_ofs = avio_tell(pb);
+
+ /* 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 || (!rf64 && !size))
+ goto break_loop;
+ break;
+ case MKTAG('f', 'a', 'c', 't'):
+ if (!sample_count)
+ sample_count = (!wav->rifx ? avio_rl32(pb) : avio_rb32(pb));
+ break;
+ case MKTAG('b', 'e', 'x', 't'):
+ if ((ret = wav_parse_bext_tag(s, size)) < 0)
+ return ret;
+ break;
+ case MKTAG('S','M','V','0'):
+ if (!got_fmt) {
+ av_log(s, AV_LOG_ERROR, "found no 'fmt ' tag before the 'SMV0' tag\n");
+ return AVERROR_INVALIDDATA;
+ }
+ // SMV file, a wav file with video appended.
+ if (size != MKTAG('0','2','0','0')) {
+ av_log(s, AV_LOG_ERROR, "Unknown SMV version found\n");
+ goto break_loop;
+ }
+ av_log(s, AV_LOG_DEBUG, "Found SMV data\n");
+ wav->smv_given_first = 0;
+ vst = avformat_new_stream(s, NULL);
+ if (!vst)
+ return AVERROR(ENOMEM);
+ avio_r8(pb);
+ vst->id = 1;
+ vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
+ vst->codec->codec_id = AV_CODEC_ID_SMVJPEG;
+ vst->codec->width = avio_rl24(pb);
+ vst->codec->height = avio_rl24(pb);
+ if (ff_alloc_extradata(vst->codec, 4)) {
+ av_log(s, AV_LOG_ERROR, "Could not allocate extradata.\n");
+ return AVERROR(ENOMEM);
+ }
+ size = avio_rl24(pb);
+ wav->smv_data_ofs = avio_tell(pb) + (size - 5) * 3;
+ avio_rl24(pb);
+ wav->smv_block_size = avio_rl24(pb);
+ avpriv_set_pts_info(vst, 32, 1, avio_rl24(pb));
+ vst->duration = avio_rl24(pb);
+ avio_rl24(pb);
+ avio_rl24(pb);
+ wav->smv_frames_per_jpeg = avio_rl24(pb);
+ if (wav->smv_frames_per_jpeg > 65536) {
+ av_log(s, AV_LOG_ERROR, "too many frames per jpeg\n");
+ return AVERROR_INVALIDDATA;
+ }
+ AV_WL32(vst->codec->extradata, wav->smv_frames_per_jpeg);
+ wav->smv_cur_pt = 0;
+ goto break_loop;
+ case MKTAG('L', 'I', 'S', 'T'):
+ if (size < 4) {
+ av_log(s, AV_LOG_ERROR, "too short LIST tag\n");
+ return AVERROR_INVALIDDATA;
+ }
+ switch (avio_rl32(pb)) {
+ case MKTAG('I', 'N', 'F', 'O'):
+ ff_read_riff_info(s, size - 4);
+ }
+ break;
+ }
+
+ /* seek to next tag unless we know that we'll run into EOF */
+ if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) ||
+ wav_seek_tag(wav, pb, next_tag_ofs, SEEK_SET) < 0) {
+ break;
+ }
+ }
+
+break_loop:
+ if (data_ofs < 0) {
+ av_log(s, AV_LOG_ERROR, "no 'data' tag found\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ avio_seek(pb, data_ofs, SEEK_SET);
+
+ if (data_size > (INT64_MAX>>3)) {
+ av_log(s, AV_LOG_WARNING, "Data size %"PRId64" is too large\n", data_size);
+ data_size = 0;
+ }
+
+ if ( st->codec->bit_rate > 0 && data_size > 0
+ && st->codec->sample_rate > 0
+ && sample_count > 0 && st->codec->channels > 1
+ && sample_count % st->codec->channels == 0) {
+ if (fabs(8.0 * data_size * st->codec->channels * st->codec->sample_rate /
+ sample_count /st->codec->bit_rate - 1.0) < 0.3)
+ sample_count /= st->codec->channels;
+ }
+
+ if ( data_size > 0 && sample_count && st->codec->channels
+ && (data_size << 3) / sample_count / st->codec->channels > st->codec->bits_per_coded_sample + 1) {
+ av_log(s, AV_LOG_WARNING, "ignoring wrong sample_count %"PRId64"\n", sample_count);
+ sample_count = 0;
+ }
+
+ /* G.729 hack (for Ticket4577)
+ * FIXME: Come up with cleaner, more general solution */
+ if (st->codec->codec_id == AV_CODEC_ID_G729 && sample_count && (data_size << 3) > sample_count) {
+ av_log(s, AV_LOG_WARNING, "ignoring wrong sample_count %"PRId64"\n", sample_count);
+ sample_count = 0;
+ }
+
+ if (!sample_count || av_get_exact_bits_per_sample(st->codec->codec_id) > 0)
+ if ( st->codec->channels
+ && data_size
+ && av_get_bits_per_sample(st->codec->codec_id)
+ && wav->data_end <= avio_size(pb))
+ sample_count = (data_size << 3)
+ /
+ (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
+
+ if (sample_count)
+ st->duration = sample_count;
+
+ ff_metadata_conv_ctx(s, NULL, wav_metadata_conv);
+ ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
+
+ return 0;
+}
+
+/**
+ * Find chunk with w64 GUID by skipping over other chunks.
+ * @return the size of the found chunk
+ */
+static int64_t find_guid(AVIOContext *pb, const uint8_t guid1[16])
+{
+ uint8_t guid[16];
+ int64_t size;
+
+ while (!avio_feof(pb)) {
+ avio_read(pb, guid, 16);
+ size = avio_rl64(pb);
+ if (size <= 24)
+ return AVERROR_INVALIDDATA;
+ if (!memcmp(guid, guid1, 16))
+ return size;
+ avio_skip(pb, FFALIGN(size, INT64_C(8)) - 24);
+ }
+ return AVERROR_EOF;
+}
+
+#define MAX_SIZE 4096
+
+static int wav_read_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ int ret, size;
+ int64_t left;
+ AVStream *st;
+ WAVDemuxContext *wav = s->priv_data;
+
+ if (CONFIG_SPDIF_DEMUXER && wav->spdif == 0 &&
+ s->streams[0]->codec->codec_tag == 1) {
+ enum AVCodecID codec;
+ ret = ff_spdif_probe(s->pb->buffer, s->pb->buf_end - s->pb->buffer,
+ &codec);
+ if (ret > AVPROBE_SCORE_EXTENSION) {
+ s->streams[0]->codec->codec_id = codec;
+ wav->spdif = 1;
+ } else {
+ wav->spdif = -1;
+ }
+ }
+ if (CONFIG_SPDIF_DEMUXER && wav->spdif == 1)
+ return ff_spdif_read_packet(s, pkt);
+
+ if (wav->smv_data_ofs > 0) {
+ int64_t audio_dts, video_dts;
+smv_retry:
+ audio_dts = (int32_t)s->streams[0]->cur_dts;
+ video_dts = (int32_t)s->streams[1]->cur_dts;
+
+ if (audio_dts != AV_NOPTS_VALUE && video_dts != AV_NOPTS_VALUE) {
+ /*We always return a video frame first to get the pixel format first*/
+ wav->smv_last_stream = wav->smv_given_first ?
+ av_compare_ts(video_dts, s->streams[1]->time_base,
+ audio_dts, s->streams[0]->time_base) > 0 : 0;
+ wav->smv_given_first = 1;
+ }
+ wav->smv_last_stream = !wav->smv_last_stream;
+ wav->smv_last_stream |= wav->audio_eof;
+ wav->smv_last_stream &= !wav->smv_eof;
+ if (wav->smv_last_stream) {
+ uint64_t old_pos = avio_tell(s->pb);
+ uint64_t new_pos = wav->smv_data_ofs +
+ wav->smv_block * wav->smv_block_size;
+ if (avio_seek(s->pb, new_pos, SEEK_SET) < 0) {
+ ret = AVERROR_EOF;
+ goto smv_out;
+ }
+ size = avio_rl24(s->pb);
+ ret = av_get_packet(s->pb, pkt, size);
+ 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->stream_index = 1;
+smv_out:
+ avio_seek(s->pb, old_pos, SEEK_SET);
+ if (ret == AVERROR_EOF) {
+ wav->smv_eof = 1;
+ goto smv_retry;
+ }
+ return ret;
+ }
+ }
+
+ st = s->streams[0];
+
+ left = wav->data_end - avio_tell(s->pb);
+ if (wav->ignore_length)
+ left = INT_MAX;
+ if (left <= 0) {
+ if (CONFIG_W64_DEMUXER && wav->w64)
+ left = find_guid(s->pb, ff_w64_guid_data) - 24;
+ else
+ left = find_tag(wav, s->pb, MKTAG('d', 'a', 't', 'a'));
+ if (left < 0) {
+ wav->audio_eof = 1;
+ if (wav->smv_data_ofs > 0 && !wav->smv_eof)
+ goto smv_retry;
+ return AVERROR_EOF;
+ }
+ wav->data_end = avio_tell(s->pb) + left;
+ }
+
+ size = MAX_SIZE;
+ if (st->codec->block_align > 1) {
+ if (size < st->codec->block_align)
+ size = st->codec->block_align;
+ size = (size / st->codec->block_align) * st->codec->block_align;
+ }
+ size = FFMIN(size, left);
+ ret = av_get_packet(s->pb, pkt, size);
+ if (ret < 0)
+ return ret;
+ pkt->stream_index = 0;
+
+ return ret;
+}
+
+static int wav_read_seek(AVFormatContext *s,
+ int stream_index, int64_t timestamp, int flags)
+{
+ WAVDemuxContext *wav = s->priv_data;
+ AVStream *st;
+ wav->smv_eof = 0;
+ wav->audio_eof = 0;
+ if (wav->smv_data_ofs > 0) {
+ int64_t smv_timestamp = timestamp;
+ if (stream_index == 0)
+ smv_timestamp = av_rescale_q(timestamp, s->streams[0]->time_base, s->streams[1]->time_base);
+ else
+ 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;
+ }
+ }
+
+ st = s->streams[0];
+ switch (st->codec->codec_id) {
+ case AV_CODEC_ID_MP2:
+ case AV_CODEC_ID_MP3:
+ case AV_CODEC_ID_AC3:
+ case AV_CODEC_ID_DTS:
+ /* use generic seeking with dynamically generated indexes */
+ return -1;
+ default:
+ break;
+ }
+ 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_INT, { .i64 = 0 }, 0, 1, DEC },
+ { NULL },
+};
+
+static const AVClass wav_demuxer_class = {
+ .class_name = "WAV demuxer",
+ .item_name = av_default_item_name,
+ .option = demux_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+AVInputFormat ff_wav_demuxer = {
+ .name = "wav",
+ .long_name = NULL_IF_CONFIG_SMALL("WAV / WAVE (Waveform Audio)"),
+ .priv_data_size = sizeof(WAVDemuxContext),
+ .read_probe = wav_probe,
+ .read_header = wav_read_header,
+ .read_packet = wav_read_packet,
+ .read_seek = wav_read_seek,
+ .flags = AVFMT_GENERIC_INDEX,
+ .codec_tag = (const AVCodecTag * const []) { ff_codec_wav_tags, 0 },
+ .priv_class = &wav_demuxer_class,
+};
+#endif /* CONFIG_WAV_DEMUXER */
+
+#if CONFIG_W64_DEMUXER
+static int w64_probe(AVProbeData *p)
+{
+ if (p->buf_size <= 40)
+ return 0;
+ if (!memcmp(p->buf, ff_w64_guid_riff, 16) &&
+ !memcmp(p->buf + 24, ff_w64_guid_wave, 16))
+ return AVPROBE_SCORE_MAX;
+ else
+ return 0;
+}
+
+static int w64_read_header(AVFormatContext *s)
+{
+ int64_t size, data_ofs = 0;
+ AVIOContext *pb = s->pb;
+ WAVDemuxContext *wav = s->priv_data;
+ AVStream *st;
+ uint8_t guid[16];
+ int ret;
+
+ avio_read(pb, guid, 16);
+ if (memcmp(guid, ff_w64_guid_riff, 16))
+ return AVERROR_INVALIDDATA;
+
+ /* riff + wave + fmt + sizes */
+ if (avio_rl64(pb) < 16 + 8 + 16 + 8 + 16 + 8)
+ return AVERROR_INVALIDDATA;
+
+ avio_read(pb, guid, 16);
+ if (memcmp(guid, ff_w64_guid_wave, 16)) {
+ av_log(s, AV_LOG_ERROR, "could not find wave guid\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ wav->w64 = 1;
+
+ st = avformat_new_stream(s, NULL);
+ if (!st)
+ return AVERROR(ENOMEM);
+
+ while (!avio_feof(pb)) {
+ if (avio_read(pb, guid, 16) != 16)
+ break;
+ size = avio_rl64(pb);
+ if (size <= 24 || INT64_MAX - size < avio_tell(pb))
+ return AVERROR_INVALIDDATA;
+
+ if (!memcmp(guid, ff_w64_guid_fmt, 16)) {
+ /* subtract chunk header size - normal wav file doesn't count it */
+ ret = ff_get_wav_header(s, pb, st->codec, size - 24, 0);
+ if (ret < 0)
+ return ret;
+ avio_skip(pb, FFALIGN(size, INT64_C(8)) - size);
+
+ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
+ } else if (!memcmp(guid, ff_w64_guid_fact, 16)) {
+ int64_t samples;
+
+ samples = avio_rl64(pb);
+ if (samples > 0)
+ st->duration = samples;
+ } else if (!memcmp(guid, ff_w64_guid_data, 16)) {
+ wav->data_end = avio_tell(pb) + size - 24;
+
+ data_ofs = avio_tell(pb);
+ if (!pb->seekable)
+ break;
+
+ avio_skip(pb, size - 24);
+ } else if (!memcmp(guid, ff_w64_guid_summarylist, 16)) {
+ int64_t start, end, cur;
+ uint32_t count, chunk_size, i;
+
+ start = avio_tell(pb);
+ end = start + FFALIGN(size, INT64_C(8)) - 24;
+ count = avio_rl32(pb);
+
+ for (i = 0; i < count; i++) {
+ char chunk_key[5], *value;
+
+ if (avio_feof(pb) || (cur = avio_tell(pb)) < 0 || cur > end - 8 /* = tag + size */)
+ break;
+
+ chunk_key[4] = 0;
+ avio_read(pb, chunk_key, 4);
+ chunk_size = avio_rl32(pb);
+ if (chunk_size == UINT32_MAX)
+ return AVERROR_INVALIDDATA;
+
+ value = av_mallocz(chunk_size + 1);
+ if (!value)
+ return AVERROR(ENOMEM);
+
+ ret = avio_get_str16le(pb, chunk_size, value, chunk_size);
+ avio_skip(pb, chunk_size - ret);
+
+ av_dict_set(&s->metadata, chunk_key, value, AV_DICT_DONT_STRDUP_VAL);
+ }
+
+ avio_skip(pb, end - avio_tell(pb));
+ } else {
+ av_log(s, AV_LOG_DEBUG, "unknown guid: "FF_PRI_GUID"\n", FF_ARG_GUID(guid));
+ avio_skip(pb, FFALIGN(size, INT64_C(8)) - 24);
+ }
+ }
+
+ if (!data_ofs)
+ return AVERROR_EOF;
+
+ ff_metadata_conv_ctx(s, NULL, wav_metadata_conv);
+ ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
+
+ handle_stream_probing(st);
+ st->need_parsing = AVSTREAM_PARSE_FULL_RAW;
+
+ avio_seek(pb, data_ofs, SEEK_SET);
+
+ return 0;
+}
+
+AVInputFormat ff_w64_demuxer = {
+ .name = "w64",
+ .long_name = NULL_IF_CONFIG_SMALL("Sony Wave64"),
+ .priv_data_size = sizeof(WAVDemuxContext),
+ .read_probe = w64_probe,
+ .read_header = w64_read_header,
+ .read_packet = wav_read_packet,
+ .read_seek = wav_read_seek,
+ .flags = AVFMT_GENERIC_INDEX,
+ .codec_tag = (const AVCodecTag * const []) { ff_codec_wav_tags, 0 },
+};
+#endif /* CONFIG_W64_DEMUXER */
diff --git a/ffmpeg-2-8-11/libavformat/wavenc.c b/ffmpeg-2-8-12/libavformat/wavenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/wavenc.c
rename to ffmpeg-2-8-12/libavformat/wavenc.c
diff --git a/ffmpeg-2-8-11/libavformat/wc3movie.c b/ffmpeg-2-8-12/libavformat/wc3movie.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/wc3movie.c
rename to ffmpeg-2-8-12/libavformat/wc3movie.c
diff --git a/ffmpeg-2-8-11/libavformat/webm_chunk.c b/ffmpeg-2-8-12/libavformat/webm_chunk.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/webm_chunk.c
rename to ffmpeg-2-8-12/libavformat/webm_chunk.c
diff --git a/ffmpeg-2-8-12/libavformat/webmdashenc.c b/ffmpeg-2-8-12/libavformat/webmdashenc.c
new file mode 100644
index 0000000..7c7156b
--- /dev/null
+++ b/ffmpeg-2-8-12/libavformat/webmdashenc.c
@@ -0,0 +1,558 @@
+/*
+ * WebM DASH Manifest XML muxer
+ * Copyright (c) 2014 Vignesh Venkatasubramanian
+ *
+ * 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
+ */
+
+/*
+ * WebM DASH Specification:
+ * https://sites.google.com/a/webmproject.org/wiki/adaptive-streaming/webm-dash-specification
+ * ISO DASH Specification:
+ * http://standards.iso.org/ittf/PubliclyAvailableStandards/c065274_ISO_IEC_23009-1_2014.zip
+ */
+
+#include <float.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "avformat.h"
+#include "avio_internal.h"
+#include "matroska.h"
+
+#include "libavutil/avstring.h"
+#include "libavutil/dict.h"
+#include "libavutil/opt.h"
+#include "libavutil/time_internal.h"
+
+typedef struct AdaptationSet {
+ char id[10];
+ int *streams;
+ int nb_streams;
+} AdaptationSet;
+
+typedef struct WebMDashMuxContext {
+ const AVClass *class;
+ char *adaptation_sets;
+ AdaptationSet *as;
+ int nb_as;
+ int representation_id;
+ int is_live;
+ int chunk_start_index;
+ int chunk_duration;
+ char *utc_timing_url;
+ double time_shift_buffer_depth;
+ int minimum_update_period;
+ int debug_mode;
+} WebMDashMuxContext;
+
+static const char *get_codec_name(int codec_id)
+{
+ switch (codec_id) {
+ case AV_CODEC_ID_VP8:
+ return "vp8";
+ case AV_CODEC_ID_VP9:
+ return "vp9";
+ case AV_CODEC_ID_VORBIS:
+ return "vorbis";
+ case AV_CODEC_ID_OPUS:
+ return "opus";
+ }
+ return NULL;
+}
+
+static double get_duration(AVFormatContext *s)
+{
+ int i = 0;
+ double max = 0.0;
+ for (i = 0; i < s->nb_streams; i++) {
+ AVDictionaryEntry *duration = av_dict_get(s->streams[i]->metadata,
+ DURATION, NULL, 0);
+ if (!duration || atof(duration->value) < 0) continue;
+ if (atof(duration->value) > max) max = atof(duration->value);
+ }
+ return max / 1000;
+}
+
+static int write_header(AVFormatContext *s)
+{
+ WebMDashMuxContext *w = s->priv_data;
+ double min_buffer_time = 1.0;
+ avio_printf(s->pb, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+ avio_printf(s->pb, "<MPD\n");
+ avio_printf(s->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");
+ if (!w->is_live) {
+ avio_printf(s->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",
+ 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) {
+ time_t local_time = time(NULL);
+ struct tm gmt_buffer;
+ struct tm *gmt = gmtime_r(&local_time, &gmt_buffer);
+ char gmt_iso[21];
+ if (!strftime(gmt_iso, 21, "%Y-%m-%dT%H:%M:%SZ", gmt)) {
+ return AVERROR_UNKNOWN;
+ }
+ if (w->debug_mode) {
+ 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");
+ if (w->utc_timing_url) {
+ avio_printf(s->pb, "<UTCTiming\n");
+ avio_printf(s->pb, " schemeIdUri=\"urn:mpeg:dash:utc:http-iso:2014\"\n");
+ avio_printf(s->pb, " value=\"%s\"/>\n", w->utc_timing_url);
+ }
+ }
+ return 0;
+}
+
+static void write_footer(AVFormatContext *s)
+{
+ avio_printf(s->pb, "</MPD>\n");
+}
+
+static int subsegment_alignment(AVFormatContext *s, AdaptationSet *as) {
+ int i;
+ AVDictionaryEntry *gold = av_dict_get(s->streams[as->streams[0]]->metadata,
+ CUE_TIMESTAMPS, NULL, 0);
+ if (!gold) return 0;
+ 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;
+ }
+ return 1;
+}
+
+static int bitstream_switching(AVFormatContext *s, AdaptationSet *as) {
+ int i;
+ AVDictionaryEntry *gold_track_num = av_dict_get(s->streams[as->streams[0]]->metadata,
+ TRACK_NUMBER, NULL, 0);
+ AVCodecContext *gold_codec = s->streams[as->streams[0]]->codec;
+ 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,
+ TRACK_NUMBER, NULL, 0);
+ AVCodecContext *codec = s->streams[as->streams[i]]->codec;
+ if (!track_num ||
+ strncmp(gold_track_num->value, track_num->value, strlen(gold_track_num->value)) ||
+ gold_codec->codec_id != codec->codec_id ||
+ gold_codec->extradata_size != codec->extradata_size ||
+ memcmp(gold_codec->extradata, codec->extradata, codec->extradata_size)) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/*
+ * 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,
+ int output_width, int output_height,
+ 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);
+ if ((w->is_live && (!filename)) ||
+ (!w->is_live && (!irange || !cues_start || !cues_end || !filename || !bandwidth))) {
+ return AVERROR_INVALIDDATA;
+ }
+ avio_printf(s->pb, "<Representation id=\"%s\"", id);
+ // FIXME: For live, This should be obtained from the input file or as an AVOption.
+ avio_printf(s->pb, " bandwidth=\"%s\"",
+ w->is_live ? (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO ? "128000" : "1000000") : bandwidth->value);
+ if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO && output_width)
+ avio_printf(s->pb, " width=\"%d\"", stream->codec->width);
+ if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO && output_height)
+ avio_printf(s->pb, " height=\"%d\"", stream->codec->height);
+ if (stream->codec->codec_type = AVMEDIA_TYPE_AUDIO && output_sample_rate)
+ avio_printf(s->pb, " audioSamplingRate=\"%d\"", stream->codec->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->codec->codec_id));
+ avio_printf(s->pb, " mimeType=\"%s/webm\"",
+ stream->codec->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, ">");
+ } else {
+ avio_printf(s->pb, ">\n");
+ avio_printf(s->pb, "<BaseURL>%s</BaseURL>\n", filename->value);
+ avio_printf(s->pb, "<SegmentBase\n");
+ avio_printf(s->pb, " indexRange=\"%s-%s\">\n", cues_start->value, cues_end->value);
+ avio_printf(s->pb, "<Initialization\n");
+ avio_printf(s->pb, " range=\"0-%s\" />\n", irange->value);
+ avio_printf(s->pb, "</SegmentBase>\n");
+ }
+ avio_printf(s->pb, "</Representation>\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) {
+ int first_width, i;
+ if (as->nb_streams < 2) return 1;
+ first_width = s->streams[as->streams[0]]->codec->width;
+ for (i = 1; i < as->nb_streams; i++)
+ if (first_width != s->streams[as->streams[i]]->codec->width)
+ return 0;
+ return 1;
+}
+
+/*
+ * Checks if height of all streams are the same. Returns 1 if true, 0 otherwise.
+ */
+static int check_matching_height(AVFormatContext *s, AdaptationSet *as) {
+ int first_height, i;
+ if (as->nb_streams < 2) return 1;
+ first_height = s->streams[as->streams[0]]->codec->height;
+ for (i = 1; i < as->nb_streams; i++)
+ if (first_height != s->streams[as->streams[i]]->codec->height)
+ return 0;
+ return 1;
+}
+
+/*
+ * 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) {
+ int first_sample_rate, i;
+ if (as->nb_streams < 2) return 1;
+ first_sample_rate = s->streams[as->streams[0]]->codec->sample_rate;
+ for (i = 1; i < as->nb_streams; i++)
+ if (first_sample_rate != s->streams[as->streams[i]]->codec->sample_rate)
+ return 0;
+ return 1;
+}
+
+static void free_adaptation_sets(AVFormatContext *s) {
+ WebMDashMuxContext *w = s->priv_data;
+ int i;
+ for (i = 0; i < w->nb_as; i++) {
+ av_freep(&w->as[i].streams);
+ }
+ av_freep(&w->as);
+ w->nb_as = 0;
+}
+
+/*
+ * 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.
+ *
+ * Name of the header file should conform to the following pattern:
+ * <file_description>_<representation_id>.hdr where <file_description> can be
+ * anything. The chunks should be named according to the following pattern:
+ * <file_description>_<representation_id>_<chunk_number>.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 *temp_pos = NULL;
+ char *filename_str = av_strdup(filename);
+ if (!filename_str) return AVERROR(ENOMEM);
+ temp_pos = av_stristr(filename_str, "_");
+ while (temp_pos) {
+ underscore_pos = temp_pos + 1;
+ temp_pos = av_stristr(temp_pos + 1, "_");
+ }
+ if (!underscore_pos) return AVERROR_INVALIDDATA;
+ period_pos = av_stristr(underscore_pos, ".");
+ if (!period_pos) return AVERROR_INVALIDDATA;
+ *(underscore_pos - 1) = 0;
+ if (representation_id) {
+ *representation_id = av_malloc(period_pos - underscore_pos + 1);
+ if (!(*representation_id)) return AVERROR(ENOMEM);
+ 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)) return AVERROR(ENOMEM);
+ }
+ if (media_pattern) {
+ *media_pattern = av_asprintf("%s_$RepresentationID$_$Number$.chk",
+ filename_str);
+ if (!(*media_pattern)) return AVERROR(ENOMEM);
+ }
+ av_free(filename_str);
+ return 0;
+}
+
+/*
+ * Writes an Adaptation Set. Returns 0 on success and < 0 on failure.
+ */
+static int write_adaptation_set(AVFormatContext *s, int as_index)
+{
+ WebMDashMuxContext *w = s->priv_data;
+ AdaptationSet *as = &w->as[as_index];
+ AVCodecContext *codec = s->streams[as->streams[0]]->codec;
+ AVDictionaryEntry *lang;
+ int i;
+ static const char boolean[2][6] = { "false", "true" };
+ int subsegmentStartsWithSAP = 1;
+
+ // Width, Height and Sample Rate will go in the AdaptationSet tag if they
+ // are the same for all contained Representations. otherwise, they will go
+ // on their respective Representation tag. For live streams, they always go
+ // in the Representation tag.
+ int width_in_as = 1, height_in_as = 1, sample_rate_in_as = 1;
+ if (codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+ 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, "<AdaptationSet id=\"%s\"", as->id);
+ avio_printf(s->pb, " mimeType=\"%s/webm\"",
+ codec->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio");
+ avio_printf(s->pb, " codecs=\"%s\"", get_codec_name(codec->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);
+
+ if (codec->codec_type == AVMEDIA_TYPE_VIDEO && width_in_as)
+ avio_printf(s->pb, " width=\"%d\"", codec->width);
+ if (codec->codec_type == AVMEDIA_TYPE_VIDEO && height_in_as)
+ avio_printf(s->pb, " height=\"%d\"", codec->height);
+ if (codec->codec_type == AVMEDIA_TYPE_AUDIO && sample_rate_in_as)
+ avio_printf(s->pb, " audioSamplingRate=\"%d\"", codec->sample_rate);
+
+ avio_printf(s->pb, " bitstreamSwitching=\"%s\"",
+ boolean[bitstream_switching(s, as)]);
+ avio_printf(s->pb, " subsegmentAlignment=\"%s\"",
+ boolean[w->is_live || subsegment_alignment(s, as)]);
+
+ for (i = 0; i < as->nb_streams; i++) {
+ AVDictionaryEntry *kf = av_dict_get(s->streams[as->streams[i]]->metadata,
+ 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");
+
+ 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);
+ if (ret) return ret;
+ avio_printf(s->pb, "<ContentComponent id=\"1\" type=\"%s\"/>\n",
+ codec->codec_type == AVMEDIA_TYPE_VIDEO ? "video" : "audio");
+ avio_printf(s->pb, "<SegmentTemplate");
+ avio_printf(s->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);
+ }
+
+ for (i = 0; i < as->nb_streams; i++) {
+ char *representation_id = NULL;
+ int ret;
+ if (w->is_live) {
+ AVDictionaryEntry *filename =
+ av_dict_get(s->streams[as->streams[i]]->metadata, FILENAME, NULL, 0);
+ if (!filename)
+ return AVERROR(EINVAL);
+ if (ret = parse_filename(filename->value, &representation_id, NULL, NULL))
+ return ret;
+ } else {
+ representation_id = av_asprintf("%d", w->representation_id++);
+ if (!representation_id) return AVERROR(ENOMEM);
+ }
+ ret = write_representation(s, s->streams[as->streams[i]],
+ representation_id, !width_in_as,
+ !height_in_as, !sample_rate_in_as);
+ av_free(representation_id);
+ if (ret) return ret;
+ }
+ avio_printf(s->pb, "</AdaptationSet>\n");
+ return 0;
+}
+
+static int to_integer(char *p, int len)
+{
+ int ret;
+ char *q = av_malloc(sizeof(char) * len);
+ if (!q)
+ return AVERROR(ENOMEM);
+ av_strlcpy(q, p, len);
+ ret = atoi(q);
+ av_free(q);
+ return ret;
+}
+
+static int parse_adaptation_sets(AVFormatContext *s)
+{
+ WebMDashMuxContext *w = s->priv_data;
+ char *p = w->adaptation_sets;
+ char *q;
+ enum { new_set, parsed_id, parsing_streams } state;
+ if (!w->adaptation_sets) {
+ av_log(s, AV_LOG_ERROR, "The 'adaptation_sets' option must be set.\n");
+ return AVERROR(EINVAL);
+ }
+ // syntax id=0,streams=0,1,2 id=1,streams=3,4 and so on
+ state = new_set;
+ while (p < w->adaptation_sets + strlen(w->adaptation_sets)) {
+ if (*p == ' ')
+ continue;
+ else if (state == new_set && !strncmp(p, "id=", 3)) {
+ void *mem = av_realloc(w->as, sizeof(*w->as) * (w->nb_as + 1));
+ if (mem == NULL)
+ return AVERROR(ENOMEM);
+ w->as = mem;
+ ++w->nb_as;
+ w->as[w->nb_as - 1].nb_streams = 0;
+ w->as[w->nb_as - 1].streams = NULL;
+ p += 3; // consume "id="
+ q = w->as[w->nb_as - 1].id;
+ while (*p != ',') *q++ = *p++;
+ *q = 0;
+ p++;
+ state = parsed_id;
+ } else if (state == parsed_id && !strncmp(p, "streams=", 8)) {
+ p += 8; // consume "streams="
+ state = parsing_streams;
+ } else if (state == parsing_streams) {
+ struct AdaptationSet *as = &w->as[w->nb_as - 1];
+ q = p;
+ while (*q != '\0' && *q != ',' && *q != ' ') q++;
+ as->streams = av_realloc(as->streams, sizeof(*as->streams) * ++as->nb_streams);
+ if (as->streams == NULL)
+ return AVERROR(ENOMEM);
+ as->streams[as->nb_streams - 1] = to_integer(p, q - p + 1);
+ if (as->streams[as->nb_streams - 1] < 0 ||
+ as->streams[as->nb_streams - 1] >= s->nb_streams) {
+ av_log(s, AV_LOG_ERROR, "Invalid value for 'streams' in adapation_sets.\n");
+ return AVERROR(EINVAL);
+ }
+ if (*q == '\0') break;
+ if (*q == ' ') state = new_set;
+ p = ++q;
+ } else {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int webm_dash_manifest_write_header(AVFormatContext *s)
+{
+ int i;
+ double start = 0.0;
+ int ret;
+ WebMDashMuxContext *w = s->priv_data;
+ ret = parse_adaptation_sets(s);
+ if (ret < 0) {
+ goto fail;
+ }
+ ret = write_header(s);
+ if (ret < 0) {
+ goto fail;
+ }
+ avio_printf(s->pb, "<Period id=\"0\"");
+ avio_printf(s->pb, " start=\"PT%gS\"", start);
+ if (!w->is_live) {
+ avio_printf(s->pb, " duration=\"PT%gS\"", get_duration(s));
+ }
+ avio_printf(s->pb, " >\n");
+
+ for (i = 0; i < w->nb_as; i++) {
+ ret = write_adaptation_set(s, i);
+ if (ret < 0) {
+ goto fail;
+ }
+ }
+
+ avio_printf(s->pb, "</Period>\n");
+ write_footer(s);
+fail:
+ free_adaptation_sets(s);
+ return ret < 0 ? ret : 0;
+}
+
+static int webm_dash_manifest_write_packet(AVFormatContext *s, AVPacket *pkt)
+{
+ return AVERROR_EOF;
+}
+
+static int webm_dash_manifest_write_trailer(AVFormatContext *s)
+{
+ free_adaptation_sets(s);
+ return 0;
+}
+
+#define OFFSET(x) offsetof(WebMDashMuxContext, x)
+static const AVOption options[] = {
+ { "adaptation_sets", "Adaptation sets. Syntax: id=0,streams=0,1,2 id=1,streams=3,4 and so on", OFFSET(adaptation_sets), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+ { "debug_mode", "[private option - users should never set this]. set this to 1 to create deterministic output", OFFSET(debug_mode), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
+ { "live", "set this to 1 to create a live stream manifest", OFFSET(is_live), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
+ { "chunk_start_index", "start index of the chunk", OFFSET(chunk_start_index), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ { "chunk_duration_ms", "duration of each chunk (in milliseconds)", OFFSET(chunk_duration), AV_OPT_TYPE_INT, {.i64 = 1000}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ { "utc_timing_url", "URL of the page that will return the UTC timestamp in ISO format", OFFSET(utc_timing_url), AV_OPT_TYPE_STRING, { 0 }, 0, 0, AV_OPT_FLAG_ENCODING_PARAM },
+ { "time_shift_buffer_depth", "Smallest time (in seconds) shifting buffer for which any Representation is guaranteed to be available.", OFFSET(time_shift_buffer_depth), AV_OPT_TYPE_DOUBLE, { .dbl = 60.0 }, 1.0, DBL_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ { "minimum_update_period", "Minimum Update Period (in seconds) of the manifest.", OFFSET(minimum_update_period), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM },
+ { NULL },
+};
+
+#if CONFIG_WEBM_DASH_MANIFEST_MUXER
+static const AVClass webm_dash_class = {
+ .class_name = "WebM DASH Manifest muxer",
+ .item_name = av_default_item_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+AVOutputFormat ff_webm_dash_manifest_muxer = {
+ .name = "webm_dash_manifest",
+ .long_name = NULL_IF_CONFIG_SMALL("WebM DASH Manifest"),
+ .mime_type = "application/xml",
+ .extensions = "xml",
+ .priv_data_size = sizeof(WebMDashMuxContext),
+ .write_header = webm_dash_manifest_write_header,
+ .write_packet = webm_dash_manifest_write_packet,
+ .write_trailer = webm_dash_manifest_write_trailer,
+ .priv_class = &webm_dash_class,
+};
+#endif
diff --git a/ffmpeg-2-8-11/libavformat/webpenc.c b/ffmpeg-2-8-12/libavformat/webpenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/webpenc.c
rename to ffmpeg-2-8-12/libavformat/webpenc.c
diff --git a/ffmpeg-2-8-11/libavformat/webvttdec.c b/ffmpeg-2-8-12/libavformat/webvttdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/webvttdec.c
rename to ffmpeg-2-8-12/libavformat/webvttdec.c
diff --git a/ffmpeg-2-8-11/libavformat/webvttenc.c b/ffmpeg-2-8-12/libavformat/webvttenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/webvttenc.c
rename to ffmpeg-2-8-12/libavformat/webvttenc.c
diff --git a/ffmpeg-2-8-11/libavformat/westwood_aud.c b/ffmpeg-2-8-12/libavformat/westwood_aud.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/westwood_aud.c
rename to ffmpeg-2-8-12/libavformat/westwood_aud.c
diff --git a/ffmpeg-2-8-11/libavformat/westwood_vqa.c b/ffmpeg-2-8-12/libavformat/westwood_vqa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/westwood_vqa.c
rename to ffmpeg-2-8-12/libavformat/westwood_vqa.c
diff --git a/ffmpeg-2-8-11/libavformat/wtv.h b/ffmpeg-2-8-12/libavformat/wtv.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/wtv.h
rename to ffmpeg-2-8-12/libavformat/wtv.h
diff --git a/ffmpeg-2-8-11/libavformat/wtv_common.c b/ffmpeg-2-8-12/libavformat/wtv_common.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/wtv_common.c
rename to ffmpeg-2-8-12/libavformat/wtv_common.c
diff --git a/ffmpeg-2-8-11/libavformat/wtvdec.c b/ffmpeg-2-8-12/libavformat/wtvdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/wtvdec.c
rename to ffmpeg-2-8-12/libavformat/wtvdec.c
diff --git a/ffmpeg-2-8-11/libavformat/wtvenc.c b/ffmpeg-2-8-12/libavformat/wtvenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/wtvenc.c
rename to ffmpeg-2-8-12/libavformat/wtvenc.c
diff --git a/ffmpeg-2-8-11/libavformat/wv.c b/ffmpeg-2-8-12/libavformat/wv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/wv.c
rename to ffmpeg-2-8-12/libavformat/wv.c
diff --git a/ffmpeg-2-8-11/libavformat/wv.h b/ffmpeg-2-8-12/libavformat/wv.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/wv.h
rename to ffmpeg-2-8-12/libavformat/wv.h
diff --git a/ffmpeg-2-8-11/libavformat/wvdec.c b/ffmpeg-2-8-12/libavformat/wvdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/wvdec.c
rename to ffmpeg-2-8-12/libavformat/wvdec.c
diff --git a/ffmpeg-2-8-11/libavformat/wvenc.c b/ffmpeg-2-8-12/libavformat/wvenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/wvenc.c
rename to ffmpeg-2-8-12/libavformat/wvenc.c
diff --git a/ffmpeg-2-8-11/libavformat/xa.c b/ffmpeg-2-8-12/libavformat/xa.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/xa.c
rename to ffmpeg-2-8-12/libavformat/xa.c
diff --git a/ffmpeg-2-8-11/libavformat/xmv.c b/ffmpeg-2-8-12/libavformat/xmv.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/xmv.c
rename to ffmpeg-2-8-12/libavformat/xmv.c
diff --git a/ffmpeg-2-8-11/libavformat/xwma.c b/ffmpeg-2-8-12/libavformat/xwma.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/xwma.c
rename to ffmpeg-2-8-12/libavformat/xwma.c
diff --git a/ffmpeg-2-8-11/libavformat/yop.c b/ffmpeg-2-8-12/libavformat/yop.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/yop.c
rename to ffmpeg-2-8-12/libavformat/yop.c
diff --git a/ffmpeg-2-8-11/libavformat/yuv4mpeg.h b/ffmpeg-2-8-12/libavformat/yuv4mpeg.h
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/yuv4mpeg.h
rename to ffmpeg-2-8-12/libavformat/yuv4mpeg.h
diff --git a/ffmpeg-2-8-11/libavformat/yuv4mpegdec.c b/ffmpeg-2-8-12/libavformat/yuv4mpegdec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/yuv4mpegdec.c
rename to ffmpeg-2-8-12/libavformat/yuv4mpegdec.c
diff --git a/ffmpeg-2-8-11/libavformat/yuv4mpegenc.c b/ffmpeg-2-8-12/libavformat/yuv4mpegenc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavformat/yuv4mpegenc.c
rename to ffmpeg-2-8-12/libavformat/yuv4mpegenc.c
diff --git a/ffmpeg-2-8-11/libavresample/Makefile b/ffmpeg-2-8-12/libavresample/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/Makefile
rename to ffmpeg-2-8-12/libavresample/Makefile
diff --git a/ffmpeg-2-8-11/libavresample/aarch64/Makefile b/ffmpeg-2-8-12/libavresample/aarch64/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/aarch64/Makefile
rename to ffmpeg-2-8-12/libavresample/aarch64/Makefile
diff --git a/ffmpeg-2-8-11/libavresample/aarch64/asm-offsets.h b/ffmpeg-2-8-12/libavresample/aarch64/asm-offsets.h
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/aarch64/asm-offsets.h
rename to ffmpeg-2-8-12/libavresample/aarch64/asm-offsets.h
diff --git a/ffmpeg-2-8-11/libavresample/aarch64/audio_convert_init.c b/ffmpeg-2-8-12/libavresample/aarch64/audio_convert_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/aarch64/audio_convert_init.c
rename to ffmpeg-2-8-12/libavresample/aarch64/audio_convert_init.c
diff --git a/ffmpeg-2-8-11/libavresample/aarch64/audio_convert_neon.S b/ffmpeg-2-8-12/libavresample/aarch64/audio_convert_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/aarch64/audio_convert_neon.S
rename to ffmpeg-2-8-12/libavresample/aarch64/audio_convert_neon.S
diff --git a/ffmpeg-2-8-11/libavresample/aarch64/neontest.c b/ffmpeg-2-8-12/libavresample/aarch64/neontest.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/aarch64/neontest.c
rename to ffmpeg-2-8-12/libavresample/aarch64/neontest.c
diff --git a/ffmpeg-2-8-11/libavresample/aarch64/resample_init.c b/ffmpeg-2-8-12/libavresample/aarch64/resample_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/aarch64/resample_init.c
rename to ffmpeg-2-8-12/libavresample/aarch64/resample_init.c
diff --git a/ffmpeg-2-8-11/libavresample/aarch64/resample_neon.S b/ffmpeg-2-8-12/libavresample/aarch64/resample_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/aarch64/resample_neon.S
rename to ffmpeg-2-8-12/libavresample/aarch64/resample_neon.S
diff --git a/ffmpeg-2-8-11/libavresample/arm/Makefile b/ffmpeg-2-8-12/libavresample/arm/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/arm/Makefile
rename to ffmpeg-2-8-12/libavresample/arm/Makefile
diff --git a/ffmpeg-2-8-11/libavresample/arm/asm-offsets.h b/ffmpeg-2-8-12/libavresample/arm/asm-offsets.h
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/arm/asm-offsets.h
rename to ffmpeg-2-8-12/libavresample/arm/asm-offsets.h
diff --git a/ffmpeg-2-8-11/libavresample/arm/audio_convert_init.c b/ffmpeg-2-8-12/libavresample/arm/audio_convert_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/arm/audio_convert_init.c
rename to ffmpeg-2-8-12/libavresample/arm/audio_convert_init.c
diff --git a/ffmpeg-2-8-11/libavresample/arm/audio_convert_neon.S b/ffmpeg-2-8-12/libavresample/arm/audio_convert_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/arm/audio_convert_neon.S
rename to ffmpeg-2-8-12/libavresample/arm/audio_convert_neon.S
diff --git a/ffmpeg-2-8-11/libavresample/arm/neontest.c b/ffmpeg-2-8-12/libavresample/arm/neontest.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/arm/neontest.c
rename to ffmpeg-2-8-12/libavresample/arm/neontest.c
diff --git a/ffmpeg-2-8-11/libavresample/arm/resample_init.c b/ffmpeg-2-8-12/libavresample/arm/resample_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/arm/resample_init.c
rename to ffmpeg-2-8-12/libavresample/arm/resample_init.c
diff --git a/ffmpeg-2-8-11/libavresample/arm/resample_neon.S b/ffmpeg-2-8-12/libavresample/arm/resample_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/arm/resample_neon.S
rename to ffmpeg-2-8-12/libavresample/arm/resample_neon.S
diff --git a/ffmpeg-2-8-11/libavresample/audio_convert.c b/ffmpeg-2-8-12/libavresample/audio_convert.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/audio_convert.c
rename to ffmpeg-2-8-12/libavresample/audio_convert.c
diff --git a/ffmpeg-2-8-11/libavresample/audio_convert.h b/ffmpeg-2-8-12/libavresample/audio_convert.h
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/audio_convert.h
rename to ffmpeg-2-8-12/libavresample/audio_convert.h
diff --git a/ffmpeg-2-8-11/libavresample/audio_data.c b/ffmpeg-2-8-12/libavresample/audio_data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/audio_data.c
rename to ffmpeg-2-8-12/libavresample/audio_data.c
diff --git a/ffmpeg-2-8-11/libavresample/audio_data.h b/ffmpeg-2-8-12/libavresample/audio_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/audio_data.h
rename to ffmpeg-2-8-12/libavresample/audio_data.h
diff --git a/ffmpeg-2-8-11/libavresample/audio_mix.c b/ffmpeg-2-8-12/libavresample/audio_mix.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/audio_mix.c
rename to ffmpeg-2-8-12/libavresample/audio_mix.c
diff --git a/ffmpeg-2-8-11/libavresample/audio_mix.h b/ffmpeg-2-8-12/libavresample/audio_mix.h
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/audio_mix.h
rename to ffmpeg-2-8-12/libavresample/audio_mix.h
diff --git a/ffmpeg-2-8-11/libavresample/audio_mix_matrix.c b/ffmpeg-2-8-12/libavresample/audio_mix_matrix.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/audio_mix_matrix.c
rename to ffmpeg-2-8-12/libavresample/audio_mix_matrix.c
diff --git a/ffmpeg-2-8-11/libavresample/avresample-test.c b/ffmpeg-2-8-12/libavresample/avresample-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/avresample-test.c
rename to ffmpeg-2-8-12/libavresample/avresample-test.c
diff --git a/ffmpeg-2-8-11/libavresample/avresample.h b/ffmpeg-2-8-12/libavresample/avresample.h
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/avresample.h
rename to ffmpeg-2-8-12/libavresample/avresample.h
diff --git a/ffmpeg-2-8-11/libavresample/avresampleres.rc b/ffmpeg-2-8-12/libavresample/avresampleres.rc
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/avresampleres.rc
rename to ffmpeg-2-8-12/libavresample/avresampleres.rc
diff --git a/ffmpeg-2-8-11/libavresample/dither.c b/ffmpeg-2-8-12/libavresample/dither.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/dither.c
rename to ffmpeg-2-8-12/libavresample/dither.c
diff --git a/ffmpeg-2-8-11/libavresample/dither.h b/ffmpeg-2-8-12/libavresample/dither.h
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/dither.h
rename to ffmpeg-2-8-12/libavresample/dither.h
diff --git a/ffmpeg-2-8-11/libavresample/internal.h b/ffmpeg-2-8-12/libavresample/internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/internal.h
rename to ffmpeg-2-8-12/libavresample/internal.h
diff --git a/ffmpeg-2-8-11/libavresample/libavresample.v b/ffmpeg-2-8-12/libavresample/libavresample.v
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/libavresample.v
rename to ffmpeg-2-8-12/libavresample/libavresample.v
diff --git a/ffmpeg-2-8-11/libavresample/options.c b/ffmpeg-2-8-12/libavresample/options.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/options.c
rename to ffmpeg-2-8-12/libavresample/options.c
diff --git a/ffmpeg-2-8-11/libavresample/resample.c b/ffmpeg-2-8-12/libavresample/resample.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/resample.c
rename to ffmpeg-2-8-12/libavresample/resample.c
diff --git a/ffmpeg-2-8-11/libavresample/resample.h b/ffmpeg-2-8-12/libavresample/resample.h
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/resample.h
rename to ffmpeg-2-8-12/libavresample/resample.h
diff --git a/ffmpeg-2-8-11/libavresample/resample_template.c b/ffmpeg-2-8-12/libavresample/resample_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/resample_template.c
rename to ffmpeg-2-8-12/libavresample/resample_template.c
diff --git a/ffmpeg-2-8-11/libavresample/utils.c b/ffmpeg-2-8-12/libavresample/utils.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/utils.c
rename to ffmpeg-2-8-12/libavresample/utils.c
diff --git a/ffmpeg-2-8-11/libavresample/version.h b/ffmpeg-2-8-12/libavresample/version.h
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/version.h
rename to ffmpeg-2-8-12/libavresample/version.h
diff --git a/ffmpeg-2-8-11/libavresample/x86/Makefile b/ffmpeg-2-8-12/libavresample/x86/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/x86/Makefile
rename to ffmpeg-2-8-12/libavresample/x86/Makefile
diff --git a/ffmpeg-2-8-11/libavresample/x86/audio_convert.asm b/ffmpeg-2-8-12/libavresample/x86/audio_convert.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/x86/audio_convert.asm
rename to ffmpeg-2-8-12/libavresample/x86/audio_convert.asm
diff --git a/ffmpeg-2-8-11/libavresample/x86/audio_convert_init.c b/ffmpeg-2-8-12/libavresample/x86/audio_convert_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/x86/audio_convert_init.c
rename to ffmpeg-2-8-12/libavresample/x86/audio_convert_init.c
diff --git a/ffmpeg-2-8-11/libavresample/x86/audio_mix.asm b/ffmpeg-2-8-12/libavresample/x86/audio_mix.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/x86/audio_mix.asm
rename to ffmpeg-2-8-12/libavresample/x86/audio_mix.asm
diff --git a/ffmpeg-2-8-11/libavresample/x86/audio_mix_init.c b/ffmpeg-2-8-12/libavresample/x86/audio_mix_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/x86/audio_mix_init.c
rename to ffmpeg-2-8-12/libavresample/x86/audio_mix_init.c
diff --git a/ffmpeg-2-8-11/libavresample/x86/dither.asm b/ffmpeg-2-8-12/libavresample/x86/dither.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/x86/dither.asm
rename to ffmpeg-2-8-12/libavresample/x86/dither.asm
diff --git a/ffmpeg-2-8-11/libavresample/x86/dither_init.c b/ffmpeg-2-8-12/libavresample/x86/dither_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/x86/dither_init.c
rename to ffmpeg-2-8-12/libavresample/x86/dither_init.c
diff --git a/ffmpeg-2-8-11/libavresample/x86/util.asm b/ffmpeg-2-8-12/libavresample/x86/util.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/x86/util.asm
rename to ffmpeg-2-8-12/libavresample/x86/util.asm
diff --git a/ffmpeg-2-8-11/libavresample/x86/w64xmmtest.c b/ffmpeg-2-8-12/libavresample/x86/w64xmmtest.c
similarity index 100%
rename from ffmpeg-2-8-11/libavresample/x86/w64xmmtest.c
rename to ffmpeg-2-8-12/libavresample/x86/w64xmmtest.c
diff --git a/ffmpeg-2-8-11/libavutil/Makefile b/ffmpeg-2-8-12/libavutil/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/Makefile
rename to ffmpeg-2-8-12/libavutil/Makefile
diff --git a/ffmpeg-2-8-11/libavutil/aarch64/Makefile b/ffmpeg-2-8-12/libavutil/aarch64/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/aarch64/Makefile
rename to ffmpeg-2-8-12/libavutil/aarch64/Makefile
diff --git a/ffmpeg-2-8-11/libavutil/aarch64/asm.S b/ffmpeg-2-8-12/libavutil/aarch64/asm.S
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/aarch64/asm.S
rename to ffmpeg-2-8-12/libavutil/aarch64/asm.S
diff --git a/ffmpeg-2-8-11/libavutil/aarch64/bswap.h b/ffmpeg-2-8-12/libavutil/aarch64/bswap.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/aarch64/bswap.h
rename to ffmpeg-2-8-12/libavutil/aarch64/bswap.h
diff --git a/ffmpeg-2-8-11/libavutil/aarch64/cpu.c b/ffmpeg-2-8-12/libavutil/aarch64/cpu.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/aarch64/cpu.c
rename to ffmpeg-2-8-12/libavutil/aarch64/cpu.c
diff --git a/ffmpeg-2-8-11/libavutil/aarch64/cpu.h b/ffmpeg-2-8-12/libavutil/aarch64/cpu.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/aarch64/cpu.h
rename to ffmpeg-2-8-12/libavutil/aarch64/cpu.h
diff --git a/ffmpeg-2-8-11/libavutil/aarch64/float_dsp_init.c b/ffmpeg-2-8-12/libavutil/aarch64/float_dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/aarch64/float_dsp_init.c
rename to ffmpeg-2-8-12/libavutil/aarch64/float_dsp_init.c
diff --git a/ffmpeg-2-8-11/libavutil/aarch64/float_dsp_neon.S b/ffmpeg-2-8-12/libavutil/aarch64/float_dsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/aarch64/float_dsp_neon.S
rename to ffmpeg-2-8-12/libavutil/aarch64/float_dsp_neon.S
diff --git a/ffmpeg-2-8-11/libavutil/aarch64/neontest.h b/ffmpeg-2-8-12/libavutil/aarch64/neontest.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/aarch64/neontest.h
rename to ffmpeg-2-8-12/libavutil/aarch64/neontest.h
diff --git a/ffmpeg-2-8-11/libavutil/adler32.c b/ffmpeg-2-8-12/libavutil/adler32.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/adler32.c
rename to ffmpeg-2-8-12/libavutil/adler32.c
diff --git a/ffmpeg-2-8-11/libavutil/adler32.h b/ffmpeg-2-8-12/libavutil/adler32.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/adler32.h
rename to ffmpeg-2-8-12/libavutil/adler32.h
diff --git a/ffmpeg-2-8-11/libavutil/aes.c b/ffmpeg-2-8-12/libavutil/aes.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/aes.c
rename to ffmpeg-2-8-12/libavutil/aes.c
diff --git a/ffmpeg-2-8-11/libavutil/aes.h b/ffmpeg-2-8-12/libavutil/aes.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/aes.h
rename to ffmpeg-2-8-12/libavutil/aes.h
diff --git a/ffmpeg-2-8-11/libavutil/arm/Makefile b/ffmpeg-2-8-12/libavutil/arm/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/Makefile
rename to ffmpeg-2-8-12/libavutil/arm/Makefile
diff --git a/ffmpeg-2-8-11/libavutil/arm/asm.S b/ffmpeg-2-8-12/libavutil/arm/asm.S
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/asm.S
rename to ffmpeg-2-8-12/libavutil/arm/asm.S
diff --git a/ffmpeg-2-8-11/libavutil/arm/bswap.h b/ffmpeg-2-8-12/libavutil/arm/bswap.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/bswap.h
rename to ffmpeg-2-8-12/libavutil/arm/bswap.h
diff --git a/ffmpeg-2-8-11/libavutil/arm/cpu.c b/ffmpeg-2-8-12/libavutil/arm/cpu.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/cpu.c
rename to ffmpeg-2-8-12/libavutil/arm/cpu.c
diff --git a/ffmpeg-2-8-11/libavutil/arm/cpu.h b/ffmpeg-2-8-12/libavutil/arm/cpu.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/cpu.h
rename to ffmpeg-2-8-12/libavutil/arm/cpu.h
diff --git a/ffmpeg-2-8-11/libavutil/arm/float_dsp_arm.h b/ffmpeg-2-8-12/libavutil/arm/float_dsp_arm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/float_dsp_arm.h
rename to ffmpeg-2-8-12/libavutil/arm/float_dsp_arm.h
diff --git a/ffmpeg-2-8-11/libavutil/arm/float_dsp_init_arm.c b/ffmpeg-2-8-12/libavutil/arm/float_dsp_init_arm.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/float_dsp_init_arm.c
rename to ffmpeg-2-8-12/libavutil/arm/float_dsp_init_arm.c
diff --git a/ffmpeg-2-8-11/libavutil/arm/float_dsp_init_neon.c b/ffmpeg-2-8-12/libavutil/arm/float_dsp_init_neon.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/float_dsp_init_neon.c
rename to ffmpeg-2-8-12/libavutil/arm/float_dsp_init_neon.c
diff --git a/ffmpeg-2-8-11/libavutil/arm/float_dsp_init_vfp.c b/ffmpeg-2-8-12/libavutil/arm/float_dsp_init_vfp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/float_dsp_init_vfp.c
rename to ffmpeg-2-8-12/libavutil/arm/float_dsp_init_vfp.c
diff --git a/ffmpeg-2-8-11/libavutil/arm/float_dsp_neon.S b/ffmpeg-2-8-12/libavutil/arm/float_dsp_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/float_dsp_neon.S
rename to ffmpeg-2-8-12/libavutil/arm/float_dsp_neon.S
diff --git a/ffmpeg-2-8-11/libavutil/arm/float_dsp_vfp.S b/ffmpeg-2-8-12/libavutil/arm/float_dsp_vfp.S
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/float_dsp_vfp.S
rename to ffmpeg-2-8-12/libavutil/arm/float_dsp_vfp.S
diff --git a/ffmpeg-2-8-11/libavutil/arm/intmath.h b/ffmpeg-2-8-12/libavutil/arm/intmath.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/intmath.h
rename to ffmpeg-2-8-12/libavutil/arm/intmath.h
diff --git a/ffmpeg-2-8-11/libavutil/arm/intreadwrite.h b/ffmpeg-2-8-12/libavutil/arm/intreadwrite.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/intreadwrite.h
rename to ffmpeg-2-8-12/libavutil/arm/intreadwrite.h
diff --git a/ffmpeg-2-8-11/libavutil/arm/neontest.h b/ffmpeg-2-8-12/libavutil/arm/neontest.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/neontest.h
rename to ffmpeg-2-8-12/libavutil/arm/neontest.h
diff --git a/ffmpeg-2-8-11/libavutil/arm/timer.h b/ffmpeg-2-8-12/libavutil/arm/timer.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/arm/timer.h
rename to ffmpeg-2-8-12/libavutil/arm/timer.h
diff --git a/ffmpeg-2-8-11/libavutil/atomic.c b/ffmpeg-2-8-12/libavutil/atomic.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/atomic.c
rename to ffmpeg-2-8-12/libavutil/atomic.c
diff --git a/ffmpeg-2-8-11/libavutil/atomic.h b/ffmpeg-2-8-12/libavutil/atomic.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/atomic.h
rename to ffmpeg-2-8-12/libavutil/atomic.h
diff --git a/ffmpeg-2-8-11/libavutil/atomic_gcc.h b/ffmpeg-2-8-12/libavutil/atomic_gcc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/atomic_gcc.h
rename to ffmpeg-2-8-12/libavutil/atomic_gcc.h
diff --git a/ffmpeg-2-8-11/libavutil/atomic_suncc.h b/ffmpeg-2-8-12/libavutil/atomic_suncc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/atomic_suncc.h
rename to ffmpeg-2-8-12/libavutil/atomic_suncc.h
diff --git a/ffmpeg-2-8-11/libavutil/atomic_win32.h b/ffmpeg-2-8-12/libavutil/atomic_win32.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/atomic_win32.h
rename to ffmpeg-2-8-12/libavutil/atomic_win32.h
diff --git a/ffmpeg-2-8-11/libavutil/attributes.h b/ffmpeg-2-8-12/libavutil/attributes.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/attributes.h
rename to ffmpeg-2-8-12/libavutil/attributes.h
diff --git a/ffmpeg-2-8-11/libavutil/audio_fifo.c b/ffmpeg-2-8-12/libavutil/audio_fifo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/audio_fifo.c
rename to ffmpeg-2-8-12/libavutil/audio_fifo.c
diff --git a/ffmpeg-2-8-11/libavutil/audio_fifo.h b/ffmpeg-2-8-12/libavutil/audio_fifo.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/audio_fifo.h
rename to ffmpeg-2-8-12/libavutil/audio_fifo.h
diff --git a/ffmpeg-2-8-11/libavutil/audioconvert.h b/ffmpeg-2-8-12/libavutil/audioconvert.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/audioconvert.h
rename to ffmpeg-2-8-12/libavutil/audioconvert.h
diff --git a/ffmpeg-2-8-11/libavutil/avassert.h b/ffmpeg-2-8-12/libavutil/avassert.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/avassert.h
rename to ffmpeg-2-8-12/libavutil/avassert.h
diff --git a/ffmpeg-2-8-11/libavutil/avr32/bswap.h b/ffmpeg-2-8-12/libavutil/avr32/bswap.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/avr32/bswap.h
rename to ffmpeg-2-8-12/libavutil/avr32/bswap.h
diff --git a/ffmpeg-2-8-11/libavutil/avr32/intreadwrite.h b/ffmpeg-2-8-12/libavutil/avr32/intreadwrite.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/avr32/intreadwrite.h
rename to ffmpeg-2-8-12/libavutil/avr32/intreadwrite.h
diff --git a/ffmpeg-2-8-11/libavutil/avstring.c b/ffmpeg-2-8-12/libavutil/avstring.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/avstring.c
rename to ffmpeg-2-8-12/libavutil/avstring.c
diff --git a/ffmpeg-2-8-11/libavutil/avstring.h b/ffmpeg-2-8-12/libavutil/avstring.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/avstring.h
rename to ffmpeg-2-8-12/libavutil/avstring.h
diff --git a/ffmpeg-2-8-11/libavutil/avutil.h b/ffmpeg-2-8-12/libavutil/avutil.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/avutil.h
rename to ffmpeg-2-8-12/libavutil/avutil.h
diff --git a/ffmpeg-2-8-11/libavutil/avutilres.rc b/ffmpeg-2-8-12/libavutil/avutilres.rc
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/avutilres.rc
rename to ffmpeg-2-8-12/libavutil/avutilres.rc
diff --git a/ffmpeg-2-8-11/libavutil/base64.c b/ffmpeg-2-8-12/libavutil/base64.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/base64.c
rename to ffmpeg-2-8-12/libavutil/base64.c
diff --git a/ffmpeg-2-8-11/libavutil/base64.h b/ffmpeg-2-8-12/libavutil/base64.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/base64.h
rename to ffmpeg-2-8-12/libavutil/base64.h
diff --git a/ffmpeg-2-8-11/libavutil/bfin/bswap.h b/ffmpeg-2-8-12/libavutil/bfin/bswap.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/bfin/bswap.h
rename to ffmpeg-2-8-12/libavutil/bfin/bswap.h
diff --git a/ffmpeg-2-8-11/libavutil/bfin/timer.h b/ffmpeg-2-8-12/libavutil/bfin/timer.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/bfin/timer.h
rename to ffmpeg-2-8-12/libavutil/bfin/timer.h
diff --git a/ffmpeg-2-8-11/libavutil/blowfish.c b/ffmpeg-2-8-12/libavutil/blowfish.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/blowfish.c
rename to ffmpeg-2-8-12/libavutil/blowfish.c
diff --git a/ffmpeg-2-8-11/libavutil/blowfish.h b/ffmpeg-2-8-12/libavutil/blowfish.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/blowfish.h
rename to ffmpeg-2-8-12/libavutil/blowfish.h
diff --git a/ffmpeg-2-8-11/libavutil/bprint.c b/ffmpeg-2-8-12/libavutil/bprint.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/bprint.c
rename to ffmpeg-2-8-12/libavutil/bprint.c
diff --git a/ffmpeg-2-8-11/libavutil/bprint.h b/ffmpeg-2-8-12/libavutil/bprint.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/bprint.h
rename to ffmpeg-2-8-12/libavutil/bprint.h
diff --git a/ffmpeg-2-8-11/libavutil/bswap.h b/ffmpeg-2-8-12/libavutil/bswap.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/bswap.h
rename to ffmpeg-2-8-12/libavutil/bswap.h
diff --git a/ffmpeg-2-8-11/libavutil/buffer.c b/ffmpeg-2-8-12/libavutil/buffer.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/buffer.c
rename to ffmpeg-2-8-12/libavutil/buffer.c
diff --git a/ffmpeg-2-8-11/libavutil/buffer.h b/ffmpeg-2-8-12/libavutil/buffer.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/buffer.h
rename to ffmpeg-2-8-12/libavutil/buffer.h
diff --git a/ffmpeg-2-8-11/libavutil/buffer_internal.h b/ffmpeg-2-8-12/libavutil/buffer_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/buffer_internal.h
rename to ffmpeg-2-8-12/libavutil/buffer_internal.h
diff --git a/ffmpeg-2-8-11/libavutil/camellia.c b/ffmpeg-2-8-12/libavutil/camellia.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/camellia.c
rename to ffmpeg-2-8-12/libavutil/camellia.c
diff --git a/ffmpeg-2-8-11/libavutil/camellia.h b/ffmpeg-2-8-12/libavutil/camellia.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/camellia.h
rename to ffmpeg-2-8-12/libavutil/camellia.h
diff --git a/ffmpeg-2-8-11/libavutil/cast5.c b/ffmpeg-2-8-12/libavutil/cast5.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/cast5.c
rename to ffmpeg-2-8-12/libavutil/cast5.c
diff --git a/ffmpeg-2-8-11/libavutil/cast5.h b/ffmpeg-2-8-12/libavutil/cast5.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/cast5.h
rename to ffmpeg-2-8-12/libavutil/cast5.h
diff --git a/ffmpeg-2-8-11/libavutil/channel_layout.c b/ffmpeg-2-8-12/libavutil/channel_layout.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/channel_layout.c
rename to ffmpeg-2-8-12/libavutil/channel_layout.c
diff --git a/ffmpeg-2-8-11/libavutil/channel_layout.h b/ffmpeg-2-8-12/libavutil/channel_layout.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/channel_layout.h
rename to ffmpeg-2-8-12/libavutil/channel_layout.h
diff --git a/ffmpeg-2-8-11/libavutil/color_utils.c b/ffmpeg-2-8-12/libavutil/color_utils.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/color_utils.c
rename to ffmpeg-2-8-12/libavutil/color_utils.c
diff --git a/ffmpeg-2-8-11/libavutil/color_utils.h b/ffmpeg-2-8-12/libavutil/color_utils.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/color_utils.h
rename to ffmpeg-2-8-12/libavutil/color_utils.h
diff --git a/ffmpeg-2-8-11/libavutil/colorspace.h b/ffmpeg-2-8-12/libavutil/colorspace.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/colorspace.h
rename to ffmpeg-2-8-12/libavutil/colorspace.h
diff --git a/ffmpeg-2-8-11/libavutil/common.h b/ffmpeg-2-8-12/libavutil/common.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/common.h
rename to ffmpeg-2-8-12/libavutil/common.h
diff --git a/ffmpeg-2-8-11/libavutil/cpu.c b/ffmpeg-2-8-12/libavutil/cpu.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/cpu.c
rename to ffmpeg-2-8-12/libavutil/cpu.c
diff --git a/ffmpeg-2-8-11/libavutil/cpu.h b/ffmpeg-2-8-12/libavutil/cpu.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/cpu.h
rename to ffmpeg-2-8-12/libavutil/cpu.h
diff --git a/ffmpeg-2-8-11/libavutil/cpu_internal.h b/ffmpeg-2-8-12/libavutil/cpu_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/cpu_internal.h
rename to ffmpeg-2-8-12/libavutil/cpu_internal.h
diff --git a/ffmpeg-2-8-11/libavutil/crc.c b/ffmpeg-2-8-12/libavutil/crc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/crc.c
rename to ffmpeg-2-8-12/libavutil/crc.c
diff --git a/ffmpeg-2-8-11/libavutil/crc.h b/ffmpeg-2-8-12/libavutil/crc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/crc.h
rename to ffmpeg-2-8-12/libavutil/crc.h
diff --git a/ffmpeg-2-8-11/libavutil/des.c b/ffmpeg-2-8-12/libavutil/des.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/des.c
rename to ffmpeg-2-8-12/libavutil/des.c
diff --git a/ffmpeg-2-8-11/libavutil/des.h b/ffmpeg-2-8-12/libavutil/des.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/des.h
rename to ffmpeg-2-8-12/libavutil/des.h
diff --git a/ffmpeg-2-8-11/libavutil/dict.c b/ffmpeg-2-8-12/libavutil/dict.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/dict.c
rename to ffmpeg-2-8-12/libavutil/dict.c
diff --git a/ffmpeg-2-8-11/libavutil/dict.h b/ffmpeg-2-8-12/libavutil/dict.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/dict.h
rename to ffmpeg-2-8-12/libavutil/dict.h
diff --git a/ffmpeg-2-8-11/libavutil/display.c b/ffmpeg-2-8-12/libavutil/display.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/display.c
rename to ffmpeg-2-8-12/libavutil/display.c
diff --git a/ffmpeg-2-8-11/libavutil/display.h b/ffmpeg-2-8-12/libavutil/display.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/display.h
rename to ffmpeg-2-8-12/libavutil/display.h
diff --git a/ffmpeg-2-8-11/libavutil/downmix_info.c b/ffmpeg-2-8-12/libavutil/downmix_info.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/downmix_info.c
rename to ffmpeg-2-8-12/libavutil/downmix_info.c
diff --git a/ffmpeg-2-8-11/libavutil/downmix_info.h b/ffmpeg-2-8-12/libavutil/downmix_info.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/downmix_info.h
rename to ffmpeg-2-8-12/libavutil/downmix_info.h
diff --git a/ffmpeg-2-8-11/libavutil/dynarray.h b/ffmpeg-2-8-12/libavutil/dynarray.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/dynarray.h
rename to ffmpeg-2-8-12/libavutil/dynarray.h
diff --git a/ffmpeg-2-8-11/libavutil/error.c b/ffmpeg-2-8-12/libavutil/error.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/error.c
rename to ffmpeg-2-8-12/libavutil/error.c
diff --git a/ffmpeg-2-8-11/libavutil/error.h b/ffmpeg-2-8-12/libavutil/error.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/error.h
rename to ffmpeg-2-8-12/libavutil/error.h
diff --git a/ffmpeg-2-8-11/libavutil/eval.c b/ffmpeg-2-8-12/libavutil/eval.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/eval.c
rename to ffmpeg-2-8-12/libavutil/eval.c
diff --git a/ffmpeg-2-8-11/libavutil/eval.h b/ffmpeg-2-8-12/libavutil/eval.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/eval.h
rename to ffmpeg-2-8-12/libavutil/eval.h
diff --git a/ffmpeg-2-8-11/libavutil/fifo.c b/ffmpeg-2-8-12/libavutil/fifo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/fifo.c
rename to ffmpeg-2-8-12/libavutil/fifo.c
diff --git a/ffmpeg-2-8-11/libavutil/fifo.h b/ffmpeg-2-8-12/libavutil/fifo.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/fifo.h
rename to ffmpeg-2-8-12/libavutil/fifo.h
diff --git a/ffmpeg-2-8-11/libavutil/file.c b/ffmpeg-2-8-12/libavutil/file.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/file.c
rename to ffmpeg-2-8-12/libavutil/file.c
diff --git a/ffmpeg-2-8-11/libavutil/file.h b/ffmpeg-2-8-12/libavutil/file.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/file.h
rename to ffmpeg-2-8-12/libavutil/file.h
diff --git a/ffmpeg-2-8-11/libavutil/file_open.c b/ffmpeg-2-8-12/libavutil/file_open.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/file_open.c
rename to ffmpeg-2-8-12/libavutil/file_open.c
diff --git a/ffmpeg-2-8-11/libavutil/fixed_dsp.c b/ffmpeg-2-8-12/libavutil/fixed_dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/fixed_dsp.c
rename to ffmpeg-2-8-12/libavutil/fixed_dsp.c
diff --git a/ffmpeg-2-8-11/libavutil/fixed_dsp.h b/ffmpeg-2-8-12/libavutil/fixed_dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/fixed_dsp.h
rename to ffmpeg-2-8-12/libavutil/fixed_dsp.h
diff --git a/ffmpeg-2-8-11/libavutil/float_dsp.c b/ffmpeg-2-8-12/libavutil/float_dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/float_dsp.c
rename to ffmpeg-2-8-12/libavutil/float_dsp.c
diff --git a/ffmpeg-2-8-11/libavutil/float_dsp.h b/ffmpeg-2-8-12/libavutil/float_dsp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/float_dsp.h
rename to ffmpeg-2-8-12/libavutil/float_dsp.h
diff --git a/ffmpeg-2-8-11/libavutil/frame.c b/ffmpeg-2-8-12/libavutil/frame.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/frame.c
rename to ffmpeg-2-8-12/libavutil/frame.c
diff --git a/ffmpeg-2-8-11/libavutil/frame.h b/ffmpeg-2-8-12/libavutil/frame.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/frame.h
rename to ffmpeg-2-8-12/libavutil/frame.h
diff --git a/ffmpeg-2-8-11/libavutil/hash.c b/ffmpeg-2-8-12/libavutil/hash.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/hash.c
rename to ffmpeg-2-8-12/libavutil/hash.c
diff --git a/ffmpeg-2-8-11/libavutil/hash.h b/ffmpeg-2-8-12/libavutil/hash.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/hash.h
rename to ffmpeg-2-8-12/libavutil/hash.h
diff --git a/ffmpeg-2-8-11/libavutil/hmac.c b/ffmpeg-2-8-12/libavutil/hmac.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/hmac.c
rename to ffmpeg-2-8-12/libavutil/hmac.c
diff --git a/ffmpeg-2-8-11/libavutil/hmac.h b/ffmpeg-2-8-12/libavutil/hmac.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/hmac.h
rename to ffmpeg-2-8-12/libavutil/hmac.h
diff --git a/ffmpeg-2-8-11/libavutil/imgutils.c b/ffmpeg-2-8-12/libavutil/imgutils.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/imgutils.c
rename to ffmpeg-2-8-12/libavutil/imgutils.c
diff --git a/ffmpeg-2-8-11/libavutil/imgutils.h b/ffmpeg-2-8-12/libavutil/imgutils.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/imgutils.h
rename to ffmpeg-2-8-12/libavutil/imgutils.h
diff --git a/ffmpeg-2-8-11/libavutil/integer.c b/ffmpeg-2-8-12/libavutil/integer.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/integer.c
rename to ffmpeg-2-8-12/libavutil/integer.c
diff --git a/ffmpeg-2-8-11/libavutil/integer.h b/ffmpeg-2-8-12/libavutil/integer.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/integer.h
rename to ffmpeg-2-8-12/libavutil/integer.h
diff --git a/ffmpeg-2-8-12/libavutil/internal.h b/ffmpeg-2-8-12/libavutil/internal.h
new file mode 100644
index 0000000..d84b473
--- /dev/null
+++ b/ffmpeg-2-8-12/libavutil/internal.h
@@ -0,0 +1,300 @@
+/*
+ * copyright (c) 2006 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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 internal API header
+ */
+
+#ifndef AVUTIL_INTERNAL_H
+#define AVUTIL_INTERNAL_H
+
+#if !defined(DEBUG) && !defined(NDEBUG)
+# define NDEBUG
+#endif
+
+// This can be enabled to allow detection of additional integer overflows with ubsan
+//#define CHECKED
+
+#include <limits.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <assert.h>
+#include "config.h"
+#include "attributes.h"
+#include "timer.h"
+#include "cpu.h"
+#include "dict.h"
+#include "pixfmt.h"
+#include "version.h"
+
+#if ARCH_X86
+# include "x86/emms.h"
+#endif
+
+#ifndef emms_c
+# define emms_c() while(0)
+#endif
+
+#ifndef attribute_align_arg
+#if ARCH_X86_32 && AV_GCC_VERSION_AT_LEAST(4,2)
+# define attribute_align_arg __attribute__((force_align_arg_pointer))
+#else
+# define attribute_align_arg
+#endif
+#endif
+
+#if defined(_MSC_VER) && CONFIG_SHARED
+# define av_export __declspec(dllimport)
+#else
+# define av_export
+#endif
+
+#if HAVE_PRAGMA_DEPRECATED
+# if defined(__ICL) || defined (__INTEL_COMPILER)
+# define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:1478))
+# define FF_ENABLE_DEPRECATION_WARNINGS __pragma(warning(pop))
+# elif defined(_MSC_VER)
+# define FF_DISABLE_DEPRECATION_WARNINGS __pragma(warning(push)) __pragma(warning(disable:4996))
+# define FF_ENABLE_DEPRECATION_WARNINGS __pragma(warning(pop))
+# else
+# define FF_DISABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"")
+# define FF_ENABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic warning \"-Wdeprecated-declarations\"")
+# endif
+#else
+# define FF_DISABLE_DEPRECATION_WARNINGS
+# define FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+
+#define FF_MEMORY_POISON 0x2a
+
+#define MAKE_ACCESSORS(str, name, type, field) \
+ type av_##name##_get_##field(const str *s) { return s->field; } \
+ void av_##name##_set_##field(str *s, type v) { s->field = v; }
+
+// 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.
+ */
+#define AV_CHECK_OFFSET(s, m, o) struct check_##o { \
+ 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 LOCAL_ALIGNED(a, t, v, ...) E1(LOCAL_ALIGNED_A(a, t, v, __VA_ARGS__,,))
+
+#if HAVE_LOCAL_ALIGNED_8
+# define LOCAL_ALIGNED_8(t, v, ...) E1(LOCAL_ALIGNED_D(8, t, v, __VA_ARGS__,,))
+#else
+# define LOCAL_ALIGNED_8(t, v, ...) LOCAL_ALIGNED(8, t, v, __VA_ARGS__)
+#endif
+
+#if HAVE_LOCAL_ALIGNED_16
+# define LOCAL_ALIGNED_16(t, v, ...) E1(LOCAL_ALIGNED_D(16, t, v, __VA_ARGS__,,))
+#else
+# define LOCAL_ALIGNED_16(t, v, ...) LOCAL_ALIGNED(16, t, v, __VA_ARGS__)
+#endif
+
+#if HAVE_LOCAL_ALIGNED_32
+# define LOCAL_ALIGNED_32(t, v, ...) E1(LOCAL_ALIGNED_D(32, t, v, __VA_ARGS__,,))
+#else
+# define LOCAL_ALIGNED_32(t, v, ...) LOCAL_ALIGNED(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;\
+ }\
+}
+
+#include "libm.h"
+
+/**
+ * Return NULL if CONFIG_SMALL is true, otherwise the argument
+ * without modification. Used to disable the definition of strings
+ * (for example AVCodec long_names).
+ */
+#if CONFIG_SMALL
+# define NULL_IF_CONFIG_SMALL(x) NULL
+#else
+# define NULL_IF_CONFIG_SMALL(x) x
+#endif
+
+/**
+ * Define a function with only the non-default version specified.
+ *
+ * On systems with ELF shared libraries, all symbols exported from
+ * FFmpeg libraries are tagged with the name and major version of the
+ * library to which they belong. If a function is moved from one
+ * library to another, a wrapper must be retained in the original
+ * location to preserve binary compatibility.
+ *
+ * Functions defined with this macro will never be used to resolve
+ * symbols by the build-time linker.
+ *
+ * @param type return type of function
+ * @param name name of function
+ * @param args argument list of function
+ * @param ver version tag to assign function
+ */
+#if HAVE_SYMVER_ASM_LABEL
+# define FF_SYMVER(type, name, args, ver) \
+ type ff_##name args __asm__ (EXTERN_PREFIX #name "@" ver); \
+ type ff_##name args
+#elif HAVE_SYMVER_GNU_ASM
+# define FF_SYMVER(type, name, args, ver) \
+ __asm__ (".symver ff_" #name "," EXTERN_PREFIX #name "@" ver); \
+ type ff_##name args; \
+ type ff_##name args
+#endif
+
+/**
+ * Return NULL if a threading library has not been enabled.
+ * Used to disable threading functions in AVCodec definitions
+ * when not needed.
+ */
+#if HAVE_THREADS
+# define ONLY_IF_THREADS_ENABLED(x) x
+#else
+# define ONLY_IF_THREADS_ENABLED(x) NULL
+#endif
+
+/**
+ * Log a generic warning message about a missing feature.
+ *
+ * @param[in] avc a pointer to an arbitrary struct of which the first
+ * field is a pointer to an AVClass struct
+ * @param[in] msg string containing the name of the missing feature
+ */
+void avpriv_report_missing_feature(void *avc,
+ const char *msg, ...) av_printf_format(2, 3);
+
+/**
+ * Log a generic warning message about a missing feature.
+ * Additionally request that a sample showcasing the feature be uploaded.
+ *
+ * @param[in] avc a pointer to an arbitrary struct of which the first field is
+ * a pointer to an AVClass struct
+ * @param[in] msg string containing the name of the missing feature
+ */
+void avpriv_request_sample(void *avc,
+ const char *msg, ...) av_printf_format(2, 3);
+
+#if HAVE_LIBC_MSVCRT
+#include <crtversion.h>
+#if defined(_VC_CRT_MAJOR_VERSION) && _VC_CRT_MAJOR_VERSION < 14
+#pragma comment(linker, "/include:" EXTERN_PREFIX "avpriv_strtod")
+#pragma comment(linker, "/include:" EXTERN_PREFIX "avpriv_snprintf")
+#endif
+
+#define avpriv_open ff_open
+#define PTRDIFF_SPECIFIER "Id"
+#define SIZE_SPECIFIER "Iu"
+#else
+#define PTRDIFF_SPECIFIER "td"
+#define SIZE_SPECIFIER "zu"
+#endif
+
+#ifdef DEBUG
+# define ff_dlog(ctx, ...) av_log(ctx, AV_LOG_DEBUG, __VA_ARGS__)
+#else
+# define ff_dlog(ctx, ...) do { if (0) av_log(ctx, AV_LOG_DEBUG, __VA_ARGS__); } while (0)
+#endif
+
+// For debuging we use signed operations so overflows can be detected (by ubsan)
+// For production we use unsigned so there are no undefined operations
+#ifdef CHECKED
+#define SUINT int
+#define SUINT32 int32_t
+#else
+#define SUINT unsigned
+#define SUINT32 uint32_t
+#endif
+
+/**
+ * A wrapper for open() setting O_CLOEXEC.
+ */
+int avpriv_open(const char *filename, int flags, ...);
+
+int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt);
+
+static av_always_inline av_const int avpriv_mirror(int x, int w)
+{
+ if (!w)
+ return 0;
+
+ while ((unsigned)x > (unsigned)w) {
+ x = -x;
+ if (x < 0)
+ x += 2 * w;
+ }
+ return x;
+}
+
+#if FF_API_GET_CHANNEL_LAYOUT_COMPAT
+uint64_t ff_get_channel_layout(const char *name, int compat);
+#endif
+
+void ff_check_pixfmt_descriptors(void);
+
+extern const uint8_t ff_reverse[256];
+
+#endif /* AVUTIL_INTERNAL_H */
diff --git a/ffmpeg-2-8-11/libavutil/intfloat.h b/ffmpeg-2-8-12/libavutil/intfloat.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/intfloat.h
rename to ffmpeg-2-8-12/libavutil/intfloat.h
diff --git a/ffmpeg-2-8-11/libavutil/intmath.c b/ffmpeg-2-8-12/libavutil/intmath.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/intmath.c
rename to ffmpeg-2-8-12/libavutil/intmath.c
diff --git a/ffmpeg-2-8-11/libavutil/intmath.h b/ffmpeg-2-8-12/libavutil/intmath.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/intmath.h
rename to ffmpeg-2-8-12/libavutil/intmath.h
diff --git a/ffmpeg-2-8-11/libavutil/intreadwrite.h b/ffmpeg-2-8-12/libavutil/intreadwrite.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/intreadwrite.h
rename to ffmpeg-2-8-12/libavutil/intreadwrite.h
diff --git a/ffmpeg-2-8-11/libavutil/lfg.c b/ffmpeg-2-8-12/libavutil/lfg.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/lfg.c
rename to ffmpeg-2-8-12/libavutil/lfg.c
diff --git a/ffmpeg-2-8-11/libavutil/lfg.h b/ffmpeg-2-8-12/libavutil/lfg.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/lfg.h
rename to ffmpeg-2-8-12/libavutil/lfg.h
diff --git a/ffmpeg-2-8-11/libavutil/libavutil.v b/ffmpeg-2-8-12/libavutil/libavutil.v
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/libavutil.v
rename to ffmpeg-2-8-12/libavutil/libavutil.v
diff --git a/ffmpeg-2-8-11/libavutil/libm.h b/ffmpeg-2-8-12/libavutil/libm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/libm.h
rename to ffmpeg-2-8-12/libavutil/libm.h
diff --git a/ffmpeg-2-8-11/libavutil/lls.c b/ffmpeg-2-8-12/libavutil/lls.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/lls.c
rename to ffmpeg-2-8-12/libavutil/lls.c
diff --git a/ffmpeg-2-8-11/libavutil/lls.h b/ffmpeg-2-8-12/libavutil/lls.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/lls.h
rename to ffmpeg-2-8-12/libavutil/lls.h
diff --git a/ffmpeg-2-8-11/libavutil/log.c b/ffmpeg-2-8-12/libavutil/log.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/log.c
rename to ffmpeg-2-8-12/libavutil/log.c
diff --git a/ffmpeg-2-8-11/libavutil/log.h b/ffmpeg-2-8-12/libavutil/log.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/log.h
rename to ffmpeg-2-8-12/libavutil/log.h
diff --git a/ffmpeg-2-8-11/libavutil/log2_tab.c b/ffmpeg-2-8-12/libavutil/log2_tab.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/log2_tab.c
rename to ffmpeg-2-8-12/libavutil/log2_tab.c
diff --git a/ffmpeg-2-8-11/libavutil/lzo.c b/ffmpeg-2-8-12/libavutil/lzo.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/lzo.c
rename to ffmpeg-2-8-12/libavutil/lzo.c
diff --git a/ffmpeg-2-8-11/libavutil/lzo.h b/ffmpeg-2-8-12/libavutil/lzo.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/lzo.h
rename to ffmpeg-2-8-12/libavutil/lzo.h
diff --git a/ffmpeg-2-8-11/libavutil/macros.h b/ffmpeg-2-8-12/libavutil/macros.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/macros.h
rename to ffmpeg-2-8-12/libavutil/macros.h
diff --git a/ffmpeg-2-8-11/libavutil/mathematics.c b/ffmpeg-2-8-12/libavutil/mathematics.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/mathematics.c
rename to ffmpeg-2-8-12/libavutil/mathematics.c
diff --git a/ffmpeg-2-8-11/libavutil/mathematics.h b/ffmpeg-2-8-12/libavutil/mathematics.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/mathematics.h
rename to ffmpeg-2-8-12/libavutil/mathematics.h
diff --git a/ffmpeg-2-8-11/libavutil/md5.c b/ffmpeg-2-8-12/libavutil/md5.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/md5.c
rename to ffmpeg-2-8-12/libavutil/md5.c
diff --git a/ffmpeg-2-8-11/libavutil/md5.h b/ffmpeg-2-8-12/libavutil/md5.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/md5.h
rename to ffmpeg-2-8-12/libavutil/md5.h
diff --git a/ffmpeg-2-8-11/libavutil/mem.c b/ffmpeg-2-8-12/libavutil/mem.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/mem.c
rename to ffmpeg-2-8-12/libavutil/mem.c
diff --git a/ffmpeg-2-8-11/libavutil/mem.h b/ffmpeg-2-8-12/libavutil/mem.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/mem.h
rename to ffmpeg-2-8-12/libavutil/mem.h
diff --git a/ffmpeg-2-8-11/libavutil/mem_internal.h b/ffmpeg-2-8-12/libavutil/mem_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/mem_internal.h
rename to ffmpeg-2-8-12/libavutil/mem_internal.h
diff --git a/ffmpeg-2-8-11/libavutil/mips/Makefile b/ffmpeg-2-8-12/libavutil/mips/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/mips/Makefile
rename to ffmpeg-2-8-12/libavutil/mips/Makefile
diff --git a/ffmpeg-2-8-11/libavutil/mips/asmdefs.h b/ffmpeg-2-8-12/libavutil/mips/asmdefs.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/mips/asmdefs.h
rename to ffmpeg-2-8-12/libavutil/mips/asmdefs.h
diff --git a/ffmpeg-2-8-11/libavutil/mips/float_dsp_mips.c b/ffmpeg-2-8-12/libavutil/mips/float_dsp_mips.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/mips/float_dsp_mips.c
rename to ffmpeg-2-8-12/libavutil/mips/float_dsp_mips.c
diff --git a/ffmpeg-2-8-11/libavutil/mips/generic_macros_msa.h b/ffmpeg-2-8-12/libavutil/mips/generic_macros_msa.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/mips/generic_macros_msa.h
rename to ffmpeg-2-8-12/libavutil/mips/generic_macros_msa.h
diff --git a/ffmpeg-2-8-11/libavutil/mips/intreadwrite.h b/ffmpeg-2-8-12/libavutil/mips/intreadwrite.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/mips/intreadwrite.h
rename to ffmpeg-2-8-12/libavutil/mips/intreadwrite.h
diff --git a/ffmpeg-2-8-11/libavutil/mips/libm_mips.h b/ffmpeg-2-8-12/libavutil/mips/libm_mips.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/mips/libm_mips.h
rename to ffmpeg-2-8-12/libavutil/mips/libm_mips.h
diff --git a/ffmpeg-2-8-11/libavutil/motion_vector.h b/ffmpeg-2-8-12/libavutil/motion_vector.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/motion_vector.h
rename to ffmpeg-2-8-12/libavutil/motion_vector.h
diff --git a/ffmpeg-2-8-11/libavutil/murmur3.c b/ffmpeg-2-8-12/libavutil/murmur3.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/murmur3.c
rename to ffmpeg-2-8-12/libavutil/murmur3.c
diff --git a/ffmpeg-2-8-11/libavutil/murmur3.h b/ffmpeg-2-8-12/libavutil/murmur3.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/murmur3.h
rename to ffmpeg-2-8-12/libavutil/murmur3.h
diff --git a/ffmpeg-2-8-11/libavutil/old_pix_fmts.h b/ffmpeg-2-8-12/libavutil/old_pix_fmts.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/old_pix_fmts.h
rename to ffmpeg-2-8-12/libavutil/old_pix_fmts.h
diff --git a/ffmpeg-2-8-11/libavutil/opencl.c b/ffmpeg-2-8-12/libavutil/opencl.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/opencl.c
rename to ffmpeg-2-8-12/libavutil/opencl.c
diff --git a/ffmpeg-2-8-11/libavutil/opencl.h b/ffmpeg-2-8-12/libavutil/opencl.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/opencl.h
rename to ffmpeg-2-8-12/libavutil/opencl.h
diff --git a/ffmpeg-2-8-11/libavutil/opencl_internal.c b/ffmpeg-2-8-12/libavutil/opencl_internal.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/opencl_internal.c
rename to ffmpeg-2-8-12/libavutil/opencl_internal.c
diff --git a/ffmpeg-2-8-11/libavutil/opencl_internal.h b/ffmpeg-2-8-12/libavutil/opencl_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/opencl_internal.h
rename to ffmpeg-2-8-12/libavutil/opencl_internal.h
diff --git a/ffmpeg-2-8-11/libavutil/opt.c b/ffmpeg-2-8-12/libavutil/opt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/opt.c
rename to ffmpeg-2-8-12/libavutil/opt.c
diff --git a/ffmpeg-2-8-11/libavutil/opt.h b/ffmpeg-2-8-12/libavutil/opt.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/opt.h
rename to ffmpeg-2-8-12/libavutil/opt.h
diff --git a/ffmpeg-2-8-11/libavutil/parseutils.c b/ffmpeg-2-8-12/libavutil/parseutils.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/parseutils.c
rename to ffmpeg-2-8-12/libavutil/parseutils.c
diff --git a/ffmpeg-2-8-11/libavutil/parseutils.h b/ffmpeg-2-8-12/libavutil/parseutils.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/parseutils.h
rename to ffmpeg-2-8-12/libavutil/parseutils.h
diff --git a/ffmpeg-2-8-11/libavutil/pca.c b/ffmpeg-2-8-12/libavutil/pca.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/pca.c
rename to ffmpeg-2-8-12/libavutil/pca.c
diff --git a/ffmpeg-2-8-11/libavutil/pca.h b/ffmpeg-2-8-12/libavutil/pca.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/pca.h
rename to ffmpeg-2-8-12/libavutil/pca.h
diff --git a/ffmpeg-2-8-11/libavutil/pixdesc.c b/ffmpeg-2-8-12/libavutil/pixdesc.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/pixdesc.c
rename to ffmpeg-2-8-12/libavutil/pixdesc.c
diff --git a/ffmpeg-2-8-11/libavutil/pixdesc.h b/ffmpeg-2-8-12/libavutil/pixdesc.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/pixdesc.h
rename to ffmpeg-2-8-12/libavutil/pixdesc.h
diff --git a/ffmpeg-2-8-11/libavutil/pixelutils.c b/ffmpeg-2-8-12/libavutil/pixelutils.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/pixelutils.c
rename to ffmpeg-2-8-12/libavutil/pixelutils.c
diff --git a/ffmpeg-2-8-11/libavutil/pixelutils.h b/ffmpeg-2-8-12/libavutil/pixelutils.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/pixelutils.h
rename to ffmpeg-2-8-12/libavutil/pixelutils.h
diff --git a/ffmpeg-2-8-11/libavutil/pixfmt.h b/ffmpeg-2-8-12/libavutil/pixfmt.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/pixfmt.h
rename to ffmpeg-2-8-12/libavutil/pixfmt.h
diff --git a/ffmpeg-2-8-11/libavutil/ppc/Makefile b/ffmpeg-2-8-12/libavutil/ppc/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/ppc/Makefile
rename to ffmpeg-2-8-12/libavutil/ppc/Makefile
diff --git a/ffmpeg-2-8-11/libavutil/ppc/cpu.c b/ffmpeg-2-8-12/libavutil/ppc/cpu.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/ppc/cpu.c
rename to ffmpeg-2-8-12/libavutil/ppc/cpu.c
diff --git a/ffmpeg-2-8-11/libavutil/ppc/cpu.h b/ffmpeg-2-8-12/libavutil/ppc/cpu.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/ppc/cpu.h
rename to ffmpeg-2-8-12/libavutil/ppc/cpu.h
diff --git a/ffmpeg-2-8-11/libavutil/ppc/float_dsp_altivec.c b/ffmpeg-2-8-12/libavutil/ppc/float_dsp_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/ppc/float_dsp_altivec.c
rename to ffmpeg-2-8-12/libavutil/ppc/float_dsp_altivec.c
diff --git a/ffmpeg-2-8-11/libavutil/ppc/float_dsp_altivec.h b/ffmpeg-2-8-12/libavutil/ppc/float_dsp_altivec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/ppc/float_dsp_altivec.h
rename to ffmpeg-2-8-12/libavutil/ppc/float_dsp_altivec.h
diff --git a/ffmpeg-2-8-11/libavutil/ppc/float_dsp_init.c b/ffmpeg-2-8-12/libavutil/ppc/float_dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/ppc/float_dsp_init.c
rename to ffmpeg-2-8-12/libavutil/ppc/float_dsp_init.c
diff --git a/ffmpeg-2-8-11/libavutil/ppc/float_dsp_vsx.c b/ffmpeg-2-8-12/libavutil/ppc/float_dsp_vsx.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/ppc/float_dsp_vsx.c
rename to ffmpeg-2-8-12/libavutil/ppc/float_dsp_vsx.c
diff --git a/ffmpeg-2-8-11/libavutil/ppc/float_dsp_vsx.h b/ffmpeg-2-8-12/libavutil/ppc/float_dsp_vsx.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/ppc/float_dsp_vsx.h
rename to ffmpeg-2-8-12/libavutil/ppc/float_dsp_vsx.h
diff --git a/ffmpeg-2-8-11/libavutil/ppc/intreadwrite.h b/ffmpeg-2-8-12/libavutil/ppc/intreadwrite.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/ppc/intreadwrite.h
rename to ffmpeg-2-8-12/libavutil/ppc/intreadwrite.h
diff --git a/ffmpeg-2-8-11/libavutil/ppc/timer.h b/ffmpeg-2-8-12/libavutil/ppc/timer.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/ppc/timer.h
rename to ffmpeg-2-8-12/libavutil/ppc/timer.h
diff --git a/ffmpeg-2-8-11/libavutil/ppc/types_altivec.h b/ffmpeg-2-8-12/libavutil/ppc/types_altivec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/ppc/types_altivec.h
rename to ffmpeg-2-8-12/libavutil/ppc/types_altivec.h
diff --git a/ffmpeg-2-8-11/libavutil/ppc/util_altivec.h b/ffmpeg-2-8-12/libavutil/ppc/util_altivec.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/ppc/util_altivec.h
rename to ffmpeg-2-8-12/libavutil/ppc/util_altivec.h
diff --git a/ffmpeg-2-8-11/libavutil/qsort.h b/ffmpeg-2-8-12/libavutil/qsort.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/qsort.h
rename to ffmpeg-2-8-12/libavutil/qsort.h
diff --git a/ffmpeg-2-8-11/libavutil/random_seed.c b/ffmpeg-2-8-12/libavutil/random_seed.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/random_seed.c
rename to ffmpeg-2-8-12/libavutil/random_seed.c
diff --git a/ffmpeg-2-8-11/libavutil/random_seed.h b/ffmpeg-2-8-12/libavutil/random_seed.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/random_seed.h
rename to ffmpeg-2-8-12/libavutil/random_seed.h
diff --git a/ffmpeg-2-8-11/libavutil/rational.c b/ffmpeg-2-8-12/libavutil/rational.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/rational.c
rename to ffmpeg-2-8-12/libavutil/rational.c
diff --git a/ffmpeg-2-8-11/libavutil/rational.h b/ffmpeg-2-8-12/libavutil/rational.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/rational.h
rename to ffmpeg-2-8-12/libavutil/rational.h
diff --git a/ffmpeg-2-8-11/libavutil/rc4.c b/ffmpeg-2-8-12/libavutil/rc4.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/rc4.c
rename to ffmpeg-2-8-12/libavutil/rc4.c
diff --git a/ffmpeg-2-8-11/libavutil/rc4.h b/ffmpeg-2-8-12/libavutil/rc4.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/rc4.h
rename to ffmpeg-2-8-12/libavutil/rc4.h
diff --git a/ffmpeg-2-8-11/libavutil/replaygain.h b/ffmpeg-2-8-12/libavutil/replaygain.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/replaygain.h
rename to ffmpeg-2-8-12/libavutil/replaygain.h
diff --git a/ffmpeg-2-8-11/libavutil/reverse.c b/ffmpeg-2-8-12/libavutil/reverse.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/reverse.c
rename to ffmpeg-2-8-12/libavutil/reverse.c
diff --git a/ffmpeg-2-8-11/libavutil/ripemd.c b/ffmpeg-2-8-12/libavutil/ripemd.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/ripemd.c
rename to ffmpeg-2-8-12/libavutil/ripemd.c
diff --git a/ffmpeg-2-8-11/libavutil/ripemd.h b/ffmpeg-2-8-12/libavutil/ripemd.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/ripemd.h
rename to ffmpeg-2-8-12/libavutil/ripemd.h
diff --git a/ffmpeg-2-8-11/libavutil/samplefmt.c b/ffmpeg-2-8-12/libavutil/samplefmt.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/samplefmt.c
rename to ffmpeg-2-8-12/libavutil/samplefmt.c
diff --git a/ffmpeg-2-8-11/libavutil/samplefmt.h b/ffmpeg-2-8-12/libavutil/samplefmt.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/samplefmt.h
rename to ffmpeg-2-8-12/libavutil/samplefmt.h
diff --git a/ffmpeg-2-8-11/libavutil/sh4/bswap.h b/ffmpeg-2-8-12/libavutil/sh4/bswap.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/sh4/bswap.h
rename to ffmpeg-2-8-12/libavutil/sh4/bswap.h
diff --git a/ffmpeg-2-8-11/libavutil/sha.c b/ffmpeg-2-8-12/libavutil/sha.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/sha.c
rename to ffmpeg-2-8-12/libavutil/sha.c
diff --git a/ffmpeg-2-8-11/libavutil/sha.h b/ffmpeg-2-8-12/libavutil/sha.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/sha.h
rename to ffmpeg-2-8-12/libavutil/sha.h
diff --git a/ffmpeg-2-8-11/libavutil/sha512.c b/ffmpeg-2-8-12/libavutil/sha512.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/sha512.c
rename to ffmpeg-2-8-12/libavutil/sha512.c
diff --git a/ffmpeg-2-8-11/libavutil/sha512.h b/ffmpeg-2-8-12/libavutil/sha512.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/sha512.h
rename to ffmpeg-2-8-12/libavutil/sha512.h
diff --git a/ffmpeg-2-8-11/libavutil/softfloat.c b/ffmpeg-2-8-12/libavutil/softfloat.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/softfloat.c
rename to ffmpeg-2-8-12/libavutil/softfloat.c
diff --git a/ffmpeg-2-8-12/libavutil/softfloat.h b/ffmpeg-2-8-12/libavutil/softfloat.h
new file mode 100644
index 0000000..1e77c12
--- /dev/null
+++ b/ffmpeg-2-8-12/libavutil/softfloat.h
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2006 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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_SOFTFLOAT_H
+#define AVUTIL_SOFTFLOAT_H
+
+#include <stdint.h>
+#include "common.h"
+
+#include "avassert.h"
+#include "softfloat_tables.h"
+
+#define MIN_EXP -149
+#define MAX_EXP 126
+#define ONE_BITS 29
+
+typedef struct SoftFloat{
+ int32_t mant;
+ int32_t exp;
+}SoftFloat;
+
+static const SoftFloat FLOAT_0 = { 0, MIN_EXP};
+static const SoftFloat FLOAT_05 = { 0x20000000, 0};
+static const SoftFloat FLOAT_1 = { 0x20000000, 1};
+static const SoftFloat FLOAT_EPSILON = { 0x29F16B12, -16};
+static const SoftFloat FLOAT_1584893192 = { 0x32B771ED, 1};
+static const SoftFloat FLOAT_100000 = { 0x30D40000, 17};
+static const SoftFloat FLOAT_0999999 = { 0x3FFFFBCE, 0};
+
+static inline av_const double av_sf2double(SoftFloat v) {
+ v.exp -= ONE_BITS +1;
+ if(v.exp > 0) return (double)v.mant * (double)(1 << v.exp);
+ else return (double)v.mant / (double)(1 << (-v.exp));
+}
+
+static av_const SoftFloat av_normalize_sf(SoftFloat a){
+ if(a.mant){
+#if 1
+ while((a.mant + 0x1FFFFFFFU)<0x3FFFFFFFU){
+ a.mant += a.mant;
+ a.exp -= 1;
+ }
+#else
+ int s=ONE_BITS - av_log2(FFABS(a.mant));
+ a.exp -= s;
+ a.mant <<= s;
+#endif
+ if(a.exp < MIN_EXP){
+ a.exp = MIN_EXP;
+ a.mant= 0;
+ }
+ }else{
+ a.exp= MIN_EXP;
+ }
+ return a;
+}
+
+static inline av_const SoftFloat av_normalize1_sf(SoftFloat a){
+#if 1
+ if((int32_t)(a.mant + 0x40000000U) <= 0){
+ a.exp++;
+ a.mant>>=1;
+ }
+ av_assert2(a.mant < 0x40000000 && a.mant > -0x40000000);
+ return a;
+#elif 1
+ int t= a.mant + 0x40000000 < 0;
+ return (SoftFloat){ a.mant>>t, a.exp+t};
+#else
+ int t= (a.mant + 0x3FFFFFFFU)>>31;
+ return (SoftFloat){a.mant>>t, a.exp+t};
+#endif
+}
+
+/**
+ * @return Will not be more denormalized than a*b. So if either input is
+ * normalized, then the output will not be worse then the other input.
+ * If both are normalized, then the output will be normalized.
+ */
+static inline av_const SoftFloat av_mul_sf(SoftFloat a, SoftFloat b){
+ a.exp += b.exp;
+ av_assert2((int32_t)((a.mant * (int64_t)b.mant) >> ONE_BITS) == (a.mant * (int64_t)b.mant) >> ONE_BITS);
+ a.mant = (a.mant * (int64_t)b.mant) >> ONE_BITS;
+ a = av_normalize1_sf((SoftFloat){a.mant, a.exp - 1});
+ if (!a.mant || a.exp < MIN_EXP)
+ return FLOAT_0;
+ return a;
+}
+
+/**
+ * b has to be normalized and not zero.
+ * @return Will not be more denormalized than a.
+ */
+static inline av_const SoftFloat av_div_sf(SoftFloat a, SoftFloat b){
+ int64_t temp = (int64_t)a.mant * (1<<(ONE_BITS+1));
+ temp /= b.mant;
+ a.exp -= b.exp;
+ a.mant = temp;
+ while (a.mant != temp) {
+ temp /= 2;
+ a.exp--;
+ a.mant = temp;
+ }
+ a = av_normalize1_sf(a);
+ if (!a.mant || a.exp < MIN_EXP)
+ return FLOAT_0;
+ return a;
+}
+
+static inline av_const int av_cmp_sf(SoftFloat a, SoftFloat b){
+ int t= a.exp - b.exp;
+ if (t <-31) return - b.mant ;
+ else if (t < 0) return (a.mant >> (-t)) - b.mant ;
+ else if (t < 32) return a.mant - (b.mant >> t);
+ else return a.mant ;
+}
+
+static inline av_const int av_gt_sf(SoftFloat a, SoftFloat b)
+{
+ int t= a.exp - b.exp;
+ if (t <-31) return 0 > b.mant ;
+ else if (t < 0) return (a.mant >> (-t)) > b.mant ;
+ else if (t < 32) return a.mant > (b.mant >> t);
+ else return a.mant > 0 ;
+}
+
+static inline av_const SoftFloat av_add_sf(SoftFloat a, SoftFloat b){
+ int t= a.exp - b.exp;
+ if (t <-31) return b;
+ else if (t < 0) return av_normalize_sf(av_normalize1_sf((SoftFloat){ b.mant + (a.mant >> (-t)), b.exp}));
+ else if (t < 32) return av_normalize_sf(av_normalize1_sf((SoftFloat){ a.mant + (b.mant >> t ), a.exp}));
+ else return a;
+}
+
+static inline av_const SoftFloat av_sub_sf(SoftFloat a, SoftFloat b){
+ return av_add_sf(a, (SoftFloat){ -b.mant, b.exp});
+}
+
+//FIXME log, exp, pow
+
+/**
+ * Converts a mantisse and exponent to a SoftFloat.
+ * This converts a fixed point value v with frac_bits fractional bits to a
+ * SoftFloat.
+ * @returns a SoftFloat with value v * 2^-frac_bits
+ */
+static inline av_const SoftFloat av_int2sf(int v, int frac_bits){
+ int exp_offset = 0;
+ if(v <= INT_MIN + 1){
+ exp_offset = 1;
+ v>>=1;
+ }
+ return av_normalize_sf(av_normalize1_sf((SoftFloat){v, ONE_BITS + 1 - frac_bits + exp_offset}));
+}
+
+/**
+ * Rounding is to -inf.
+ */
+static inline av_const int av_sf2int(SoftFloat v, int frac_bits){
+ v.exp += frac_bits - (ONE_BITS + 1);
+ if(v.exp >= 0) return v.mant << v.exp ;
+ else return v.mant >>(-v.exp);
+}
+
+/**
+ * Rounding-to-nearest used.
+ */
+static av_always_inline SoftFloat av_sqrt_sf(SoftFloat val)
+{
+ int tabIndex, rem;
+
+ if (val.mant == 0)
+ val.exp = MIN_EXP;
+ else if (val.mant < 0)
+ abort();
+ else
+ {
+ tabIndex = (val.mant - 0x20000000) >> 20;
+
+ rem = val.mant & 0xFFFFF;
+ val.mant = (int)(((int64_t)av_sqrttbl_sf[tabIndex] * (0x100000 - rem) +
+ (int64_t)av_sqrttbl_sf[tabIndex + 1] * rem +
+ 0x80000) >> 20);
+ val.mant = (int)(((int64_t)av_sqr_exp_multbl_sf[val.exp & 1] * val.mant +
+ 0x10000000) >> 29);
+
+ if (val.mant < 0x40000000)
+ val.exp -= 2;
+ else
+ val.mant >>= 1;
+
+ val.exp = (val.exp >> 1) + 1;
+ }
+
+ return val;
+}
+
+/**
+ * Rounding-to-nearest used.
+ */
+static av_unused void av_sincos_sf(int a, int *s, int *c)
+{
+ int idx, sign;
+ int sv, cv;
+ int st, ct;
+
+ idx = a >> 26;
+ sign = (int32_t)((unsigned)idx << 27) >> 31;
+ cv = av_costbl_1_sf[idx & 0xf];
+ cv = (cv ^ sign) - sign;
+
+ idx -= 8;
+ sign = (int32_t)((unsigned)idx << 27) >> 31;
+ sv = av_costbl_1_sf[idx & 0xf];
+ sv = (sv ^ sign) - sign;
+
+ idx = a >> 21;
+ ct = av_costbl_2_sf[idx & 0x1f];
+ st = av_sintbl_2_sf[idx & 0x1f];
+
+ idx = (int)(((int64_t)cv * ct - (int64_t)sv * st + 0x20000000) >> 30);
+
+ sv = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30);
+
+ cv = idx;
+
+ idx = a >> 16;
+ ct = av_costbl_3_sf[idx & 0x1f];
+ st = av_sintbl_3_sf[idx & 0x1f];
+
+ idx = (int)(((int64_t)cv * ct - (int64_t)sv * st + 0x20000000) >> 30);
+
+ sv = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30);
+ cv = idx;
+
+ idx = a >> 11;
+
+ ct = (int)(((int64_t)av_costbl_4_sf[idx & 0x1f] * (0x800 - (a & 0x7ff)) +
+ (int64_t)av_costbl_4_sf[(idx & 0x1f)+1]*(a & 0x7ff) +
+ 0x400) >> 11);
+ st = (int)(((int64_t)av_sintbl_4_sf[idx & 0x1f] * (0x800 - (a & 0x7ff)) +
+ (int64_t)av_sintbl_4_sf[(idx & 0x1f) + 1] * (a & 0x7ff) +
+ 0x400) >> 11);
+
+ *c = (int)(((int64_t)cv * ct + (int64_t)sv * st + 0x20000000) >> 30);
+
+ *s = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30);
+}
+
+#endif /* AVUTIL_SOFTFLOAT_H */
diff --git a/ffmpeg-2-8-11/libavutil/softfloat_tables.h b/ffmpeg-2-8-12/libavutil/softfloat_tables.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/softfloat_tables.h
rename to ffmpeg-2-8-12/libavutil/softfloat_tables.h
diff --git a/ffmpeg-2-8-11/libavutil/stereo3d.c b/ffmpeg-2-8-12/libavutil/stereo3d.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/stereo3d.c
rename to ffmpeg-2-8-12/libavutil/stereo3d.c
diff --git a/ffmpeg-2-8-11/libavutil/stereo3d.h b/ffmpeg-2-8-12/libavutil/stereo3d.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/stereo3d.h
rename to ffmpeg-2-8-12/libavutil/stereo3d.h
diff --git a/ffmpeg-2-8-11/libavutil/tea.c b/ffmpeg-2-8-12/libavutil/tea.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/tea.c
rename to ffmpeg-2-8-12/libavutil/tea.c
diff --git a/ffmpeg-2-8-11/libavutil/tea.h b/ffmpeg-2-8-12/libavutil/tea.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/tea.h
rename to ffmpeg-2-8-12/libavutil/tea.h
diff --git a/ffmpeg-2-8-11/libavutil/thread.h b/ffmpeg-2-8-12/libavutil/thread.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/thread.h
rename to ffmpeg-2-8-12/libavutil/thread.h
diff --git a/ffmpeg-2-8-11/libavutil/threadmessage.c b/ffmpeg-2-8-12/libavutil/threadmessage.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/threadmessage.c
rename to ffmpeg-2-8-12/libavutil/threadmessage.c
diff --git a/ffmpeg-2-8-11/libavutil/threadmessage.h b/ffmpeg-2-8-12/libavutil/threadmessage.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/threadmessage.h
rename to ffmpeg-2-8-12/libavutil/threadmessage.h
diff --git a/ffmpeg-2-8-11/libavutil/time.c b/ffmpeg-2-8-12/libavutil/time.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/time.c
rename to ffmpeg-2-8-12/libavutil/time.c
diff --git a/ffmpeg-2-8-11/libavutil/time.h b/ffmpeg-2-8-12/libavutil/time.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/time.h
rename to ffmpeg-2-8-12/libavutil/time.h
diff --git a/ffmpeg-2-8-11/libavutil/time_internal.h b/ffmpeg-2-8-12/libavutil/time_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/time_internal.h
rename to ffmpeg-2-8-12/libavutil/time_internal.h
diff --git a/ffmpeg-2-8-11/libavutil/timecode.c b/ffmpeg-2-8-12/libavutil/timecode.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/timecode.c
rename to ffmpeg-2-8-12/libavutil/timecode.c
diff --git a/ffmpeg-2-8-11/libavutil/timecode.h b/ffmpeg-2-8-12/libavutil/timecode.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/timecode.h
rename to ffmpeg-2-8-12/libavutil/timecode.h
diff --git a/ffmpeg-2-8-11/libavutil/timer.h b/ffmpeg-2-8-12/libavutil/timer.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/timer.h
rename to ffmpeg-2-8-12/libavutil/timer.h
diff --git a/ffmpeg-2-8-11/libavutil/timestamp.h b/ffmpeg-2-8-12/libavutil/timestamp.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/timestamp.h
rename to ffmpeg-2-8-12/libavutil/timestamp.h
diff --git a/ffmpeg-2-8-11/libavutil/tomi/intreadwrite.h b/ffmpeg-2-8-12/libavutil/tomi/intreadwrite.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/tomi/intreadwrite.h
rename to ffmpeg-2-8-12/libavutil/tomi/intreadwrite.h
diff --git a/ffmpeg-2-8-11/libavutil/tree.c b/ffmpeg-2-8-12/libavutil/tree.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/tree.c
rename to ffmpeg-2-8-12/libavutil/tree.c
diff --git a/ffmpeg-2-8-11/libavutil/tree.h b/ffmpeg-2-8-12/libavutil/tree.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/tree.h
rename to ffmpeg-2-8-12/libavutil/tree.h
diff --git a/ffmpeg-2-8-11/libavutil/twofish.c b/ffmpeg-2-8-12/libavutil/twofish.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/twofish.c
rename to ffmpeg-2-8-12/libavutil/twofish.c
diff --git a/ffmpeg-2-8-11/libavutil/twofish.h b/ffmpeg-2-8-12/libavutil/twofish.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/twofish.h
rename to ffmpeg-2-8-12/libavutil/twofish.h
diff --git a/ffmpeg-2-8-11/libavutil/utf8.c b/ffmpeg-2-8-12/libavutil/utf8.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/utf8.c
rename to ffmpeg-2-8-12/libavutil/utf8.c
diff --git a/ffmpeg-2-8-11/libavutil/utils.c b/ffmpeg-2-8-12/libavutil/utils.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/utils.c
rename to ffmpeg-2-8-12/libavutil/utils.c
diff --git a/ffmpeg-2-8-11/libavutil/version.h b/ffmpeg-2-8-12/libavutil/version.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/version.h
rename to ffmpeg-2-8-12/libavutil/version.h
diff --git a/ffmpeg-2-8-11/libavutil/wchar_filename.h b/ffmpeg-2-8-12/libavutil/wchar_filename.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/wchar_filename.h
rename to ffmpeg-2-8-12/libavutil/wchar_filename.h
diff --git a/ffmpeg-2-8-11/libavutil/x86/Makefile b/ffmpeg-2-8-12/libavutil/x86/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/Makefile
rename to ffmpeg-2-8-12/libavutil/x86/Makefile
diff --git a/ffmpeg-2-8-11/libavutil/x86/asm.h b/ffmpeg-2-8-12/libavutil/x86/asm.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/asm.h
rename to ffmpeg-2-8-12/libavutil/x86/asm.h
diff --git a/ffmpeg-2-8-11/libavutil/x86/bswap.h b/ffmpeg-2-8-12/libavutil/x86/bswap.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/bswap.h
rename to ffmpeg-2-8-12/libavutil/x86/bswap.h
diff --git a/ffmpeg-2-8-11/libavutil/x86/cpu.c b/ffmpeg-2-8-12/libavutil/x86/cpu.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/cpu.c
rename to ffmpeg-2-8-12/libavutil/x86/cpu.c
diff --git a/ffmpeg-2-8-11/libavutil/x86/cpu.h b/ffmpeg-2-8-12/libavutil/x86/cpu.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/cpu.h
rename to ffmpeg-2-8-12/libavutil/x86/cpu.h
diff --git a/ffmpeg-2-8-11/libavutil/x86/cpuid.asm b/ffmpeg-2-8-12/libavutil/x86/cpuid.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/cpuid.asm
rename to ffmpeg-2-8-12/libavutil/x86/cpuid.asm
diff --git a/ffmpeg-2-8-11/libavutil/x86/emms.asm b/ffmpeg-2-8-12/libavutil/x86/emms.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/emms.asm
rename to ffmpeg-2-8-12/libavutil/x86/emms.asm
diff --git a/ffmpeg-2-8-11/libavutil/x86/emms.h b/ffmpeg-2-8-12/libavutil/x86/emms.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/emms.h
rename to ffmpeg-2-8-12/libavutil/x86/emms.h
diff --git a/ffmpeg-2-8-11/libavutil/x86/float_dsp.asm b/ffmpeg-2-8-12/libavutil/x86/float_dsp.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/float_dsp.asm
rename to ffmpeg-2-8-12/libavutil/x86/float_dsp.asm
diff --git a/ffmpeg-2-8-11/libavutil/x86/float_dsp_init.c b/ffmpeg-2-8-12/libavutil/x86/float_dsp_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/float_dsp_init.c
rename to ffmpeg-2-8-12/libavutil/x86/float_dsp_init.c
diff --git a/ffmpeg-2-8-11/libavutil/x86/intmath.h b/ffmpeg-2-8-12/libavutil/x86/intmath.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/intmath.h
rename to ffmpeg-2-8-12/libavutil/x86/intmath.h
diff --git a/ffmpeg-2-8-11/libavutil/x86/intreadwrite.h b/ffmpeg-2-8-12/libavutil/x86/intreadwrite.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/intreadwrite.h
rename to ffmpeg-2-8-12/libavutil/x86/intreadwrite.h
diff --git a/ffmpeg-2-8-11/libavutil/x86/lls.asm b/ffmpeg-2-8-12/libavutil/x86/lls.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/lls.asm
rename to ffmpeg-2-8-12/libavutil/x86/lls.asm
diff --git a/ffmpeg-2-8-11/libavutil/x86/lls_init.c b/ffmpeg-2-8-12/libavutil/x86/lls_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/lls_init.c
rename to ffmpeg-2-8-12/libavutil/x86/lls_init.c
diff --git a/ffmpeg-2-8-11/libavutil/x86/pixelutils.asm b/ffmpeg-2-8-12/libavutil/x86/pixelutils.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/pixelutils.asm
rename to ffmpeg-2-8-12/libavutil/x86/pixelutils.asm
diff --git a/ffmpeg-2-8-11/libavutil/x86/pixelutils.h b/ffmpeg-2-8-12/libavutil/x86/pixelutils.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/pixelutils.h
rename to ffmpeg-2-8-12/libavutil/x86/pixelutils.h
diff --git a/ffmpeg-2-8-11/libavutil/x86/pixelutils_init.c b/ffmpeg-2-8-12/libavutil/x86/pixelutils_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/pixelutils_init.c
rename to ffmpeg-2-8-12/libavutil/x86/pixelutils_init.c
diff --git a/ffmpeg-2-8-11/libavutil/x86/timer.h b/ffmpeg-2-8-12/libavutil/x86/timer.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/timer.h
rename to ffmpeg-2-8-12/libavutil/x86/timer.h
diff --git a/ffmpeg-2-8-11/libavutil/x86/w64xmmtest.h b/ffmpeg-2-8-12/libavutil/x86/w64xmmtest.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/w64xmmtest.h
rename to ffmpeg-2-8-12/libavutil/x86/w64xmmtest.h
diff --git a/ffmpeg-2-8-11/libavutil/x86/x86inc.asm b/ffmpeg-2-8-12/libavutil/x86/x86inc.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/x86inc.asm
rename to ffmpeg-2-8-12/libavutil/x86/x86inc.asm
diff --git a/ffmpeg-2-8-11/libavutil/x86/x86util.asm b/ffmpeg-2-8-12/libavutil/x86/x86util.asm
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86/x86util.asm
rename to ffmpeg-2-8-12/libavutil/x86/x86util.asm
diff --git a/ffmpeg-2-8-11/libavutil/x86_cpu.h b/ffmpeg-2-8-12/libavutil/x86_cpu.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/x86_cpu.h
rename to ffmpeg-2-8-12/libavutil/x86_cpu.h
diff --git a/ffmpeg-2-8-11/libavutil/xga_font_data.c b/ffmpeg-2-8-12/libavutil/xga_font_data.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/xga_font_data.c
rename to ffmpeg-2-8-12/libavutil/xga_font_data.c
diff --git a/ffmpeg-2-8-11/libavutil/xga_font_data.h b/ffmpeg-2-8-12/libavutil/xga_font_data.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/xga_font_data.h
rename to ffmpeg-2-8-12/libavutil/xga_font_data.h
diff --git a/ffmpeg-2-8-11/libavutil/xtea.c b/ffmpeg-2-8-12/libavutil/xtea.c
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/xtea.c
rename to ffmpeg-2-8-12/libavutil/xtea.c
diff --git a/ffmpeg-2-8-11/libavutil/xtea.h b/ffmpeg-2-8-12/libavutil/xtea.h
similarity index 100%
rename from ffmpeg-2-8-11/libavutil/xtea.h
rename to ffmpeg-2-8-12/libavutil/xtea.h
diff --git a/ffmpeg-2-8-11/libpostproc/Makefile b/ffmpeg-2-8-12/libpostproc/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libpostproc/Makefile
rename to ffmpeg-2-8-12/libpostproc/Makefile
diff --git a/ffmpeg-2-8-11/libpostproc/libpostproc.v b/ffmpeg-2-8-12/libpostproc/libpostproc.v
similarity index 100%
rename from ffmpeg-2-8-11/libpostproc/libpostproc.v
rename to ffmpeg-2-8-12/libpostproc/libpostproc.v
diff --git a/ffmpeg-2-8-11/libpostproc/postprocess.c b/ffmpeg-2-8-12/libpostproc/postprocess.c
similarity index 100%
rename from ffmpeg-2-8-11/libpostproc/postprocess.c
rename to ffmpeg-2-8-12/libpostproc/postprocess.c
diff --git a/ffmpeg-2-8-11/libpostproc/postprocess.h b/ffmpeg-2-8-12/libpostproc/postprocess.h
similarity index 100%
rename from ffmpeg-2-8-11/libpostproc/postprocess.h
rename to ffmpeg-2-8-12/libpostproc/postprocess.h
diff --git a/ffmpeg-2-8-11/libpostproc/postprocess_altivec_template.c b/ffmpeg-2-8-12/libpostproc/postprocess_altivec_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libpostproc/postprocess_altivec_template.c
rename to ffmpeg-2-8-12/libpostproc/postprocess_altivec_template.c
diff --git a/ffmpeg-2-8-11/libpostproc/postprocess_internal.h b/ffmpeg-2-8-12/libpostproc/postprocess_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libpostproc/postprocess_internal.h
rename to ffmpeg-2-8-12/libpostproc/postprocess_internal.h
diff --git a/ffmpeg-2-8-11/libpostproc/postprocess_template.c b/ffmpeg-2-8-12/libpostproc/postprocess_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libpostproc/postprocess_template.c
rename to ffmpeg-2-8-12/libpostproc/postprocess_template.c
diff --git a/ffmpeg-2-8-11/libpostproc/postprocres.rc b/ffmpeg-2-8-12/libpostproc/postprocres.rc
similarity index 100%
rename from ffmpeg-2-8-11/libpostproc/postprocres.rc
rename to ffmpeg-2-8-12/libpostproc/postprocres.rc
diff --git a/ffmpeg-2-8-11/libpostproc/version.h b/ffmpeg-2-8-12/libpostproc/version.h
similarity index 100%
rename from ffmpeg-2-8-11/libpostproc/version.h
rename to ffmpeg-2-8-12/libpostproc/version.h
diff --git a/ffmpeg-2-8-11/library.mak b/ffmpeg-2-8-12/library.mak
similarity index 100%
rename from ffmpeg-2-8-11/library.mak
rename to ffmpeg-2-8-12/library.mak
diff --git a/ffmpeg-2-8-11/libswresample/Makefile b/ffmpeg-2-8-12/libswresample/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/Makefile
rename to ffmpeg-2-8-12/libswresample/Makefile
diff --git a/ffmpeg-2-8-11/libswresample/aarch64/Makefile b/ffmpeg-2-8-12/libswresample/aarch64/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/aarch64/Makefile
rename to ffmpeg-2-8-12/libswresample/aarch64/Makefile
diff --git a/ffmpeg-2-8-11/libswresample/aarch64/audio_convert_init.c b/ffmpeg-2-8-12/libswresample/aarch64/audio_convert_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/aarch64/audio_convert_init.c
rename to ffmpeg-2-8-12/libswresample/aarch64/audio_convert_init.c
diff --git a/ffmpeg-2-8-11/libswresample/aarch64/audio_convert_neon.S b/ffmpeg-2-8-12/libswresample/aarch64/audio_convert_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/aarch64/audio_convert_neon.S
rename to ffmpeg-2-8-12/libswresample/aarch64/audio_convert_neon.S
diff --git a/ffmpeg-2-8-11/libswresample/aarch64/neontest.c b/ffmpeg-2-8-12/libswresample/aarch64/neontest.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/aarch64/neontest.c
rename to ffmpeg-2-8-12/libswresample/aarch64/neontest.c
diff --git a/ffmpeg-2-8-11/libswresample/arm/Makefile b/ffmpeg-2-8-12/libswresample/arm/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/arm/Makefile
rename to ffmpeg-2-8-12/libswresample/arm/Makefile
diff --git a/ffmpeg-2-8-11/libswresample/arm/audio_convert_init.c b/ffmpeg-2-8-12/libswresample/arm/audio_convert_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/arm/audio_convert_init.c
rename to ffmpeg-2-8-12/libswresample/arm/audio_convert_init.c
diff --git a/ffmpeg-2-8-11/libswresample/arm/audio_convert_neon.S b/ffmpeg-2-8-12/libswresample/arm/audio_convert_neon.S
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/arm/audio_convert_neon.S
rename to ffmpeg-2-8-12/libswresample/arm/audio_convert_neon.S
diff --git a/ffmpeg-2-8-11/libswresample/arm/neontest.c b/ffmpeg-2-8-12/libswresample/arm/neontest.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/arm/neontest.c
rename to ffmpeg-2-8-12/libswresample/arm/neontest.c
diff --git a/ffmpeg-2-8-11/libswresample/audioconvert.c b/ffmpeg-2-8-12/libswresample/audioconvert.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/audioconvert.c
rename to ffmpeg-2-8-12/libswresample/audioconvert.c
diff --git a/ffmpeg-2-8-11/libswresample/audioconvert.h b/ffmpeg-2-8-12/libswresample/audioconvert.h
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/audioconvert.h
rename to ffmpeg-2-8-12/libswresample/audioconvert.h
diff --git a/ffmpeg-2-8-11/libswresample/dither.c b/ffmpeg-2-8-12/libswresample/dither.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/dither.c
rename to ffmpeg-2-8-12/libswresample/dither.c
diff --git a/ffmpeg-2-8-11/libswresample/dither_template.c b/ffmpeg-2-8-12/libswresample/dither_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/dither_template.c
rename to ffmpeg-2-8-12/libswresample/dither_template.c
diff --git a/ffmpeg-2-8-11/libswresample/libswresample.v b/ffmpeg-2-8-12/libswresample/libswresample.v
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/libswresample.v
rename to ffmpeg-2-8-12/libswresample/libswresample.v
diff --git a/ffmpeg-2-8-11/libswresample/log2_tab.c b/ffmpeg-2-8-12/libswresample/log2_tab.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/log2_tab.c
rename to ffmpeg-2-8-12/libswresample/log2_tab.c
diff --git a/ffmpeg-2-8-11/libswresample/noise_shaping_data.c b/ffmpeg-2-8-12/libswresample/noise_shaping_data.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/noise_shaping_data.c
rename to ffmpeg-2-8-12/libswresample/noise_shaping_data.c
diff --git a/ffmpeg-2-8-11/libswresample/options.c b/ffmpeg-2-8-12/libswresample/options.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/options.c
rename to ffmpeg-2-8-12/libswresample/options.c
diff --git a/ffmpeg-2-8-11/libswresample/rematrix.c b/ffmpeg-2-8-12/libswresample/rematrix.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/rematrix.c
rename to ffmpeg-2-8-12/libswresample/rematrix.c
diff --git a/ffmpeg-2-8-11/libswresample/rematrix_template.c b/ffmpeg-2-8-12/libswresample/rematrix_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/rematrix_template.c
rename to ffmpeg-2-8-12/libswresample/rematrix_template.c
diff --git a/ffmpeg-2-8-12/libswresample/resample.c b/ffmpeg-2-8-12/libswresample/resample.c
new file mode 100644
index 0000000..02301ff
--- /dev/null
+++ b/ffmpeg-2-8-12/libswresample/resample.c
@@ -0,0 +1,443 @@
+/*
+ * audio resampling
+ * Copyright (c) 2004-2012 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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
+ * audio resampling
+ * @author Michael Niedermayer <michaelni at gmx.at>
+ */
+
+#include "libavutil/avassert.h"
+#include "resample.h"
+
+/**
+ * 0th order modified bessel function of the first kind.
+ */
+static double bessel(double x){
+ double v=1;
+ double lastv=0;
+ double t=1;
+ int i;
+ static const double inv[100]={
+ 1.0/( 1* 1), 1.0/( 2* 2), 1.0/( 3* 3), 1.0/( 4* 4), 1.0/( 5* 5), 1.0/( 6* 6), 1.0/( 7* 7), 1.0/( 8* 8), 1.0/( 9* 9), 1.0/(10*10),
+ 1.0/(11*11), 1.0/(12*12), 1.0/(13*13), 1.0/(14*14), 1.0/(15*15), 1.0/(16*16), 1.0/(17*17), 1.0/(18*18), 1.0/(19*19), 1.0/(20*20),
+ 1.0/(21*21), 1.0/(22*22), 1.0/(23*23), 1.0/(24*24), 1.0/(25*25), 1.0/(26*26), 1.0/(27*27), 1.0/(28*28), 1.0/(29*29), 1.0/(30*30),
+ 1.0/(31*31), 1.0/(32*32), 1.0/(33*33), 1.0/(34*34), 1.0/(35*35), 1.0/(36*36), 1.0/(37*37), 1.0/(38*38), 1.0/(39*39), 1.0/(40*40),
+ 1.0/(41*41), 1.0/(42*42), 1.0/(43*43), 1.0/(44*44), 1.0/(45*45), 1.0/(46*46), 1.0/(47*47), 1.0/(48*48), 1.0/(49*49), 1.0/(50*50),
+ 1.0/(51*51), 1.0/(52*52), 1.0/(53*53), 1.0/(54*54), 1.0/(55*55), 1.0/(56*56), 1.0/(57*57), 1.0/(58*58), 1.0/(59*59), 1.0/(60*60),
+ 1.0/(61*61), 1.0/(62*62), 1.0/(63*63), 1.0/(64*64), 1.0/(65*65), 1.0/(66*66), 1.0/(67*67), 1.0/(68*68), 1.0/(69*69), 1.0/(70*70),
+ 1.0/(71*71), 1.0/(72*72), 1.0/(73*73), 1.0/(74*74), 1.0/(75*75), 1.0/(76*76), 1.0/(77*77), 1.0/(78*78), 1.0/(79*79), 1.0/(80*80),
+ 1.0/(81*81), 1.0/(82*82), 1.0/(83*83), 1.0/(84*84), 1.0/(85*85), 1.0/(86*86), 1.0/(87*87), 1.0/(88*88), 1.0/(89*89), 1.0/(90*90),
+ 1.0/(91*91), 1.0/(92*92), 1.0/(93*93), 1.0/(94*94), 1.0/(95*95), 1.0/(96*96), 1.0/(97*97), 1.0/(98*98), 1.0/(99*99), 1.0/(10000)
+ };
+
+ x= x*x/4;
+ for(i=0; v != lastv; i++){
+ lastv=v;
+ t *= x*inv[i];
+ v += t;
+ av_assert2(i<99);
+ }
+ return v;
+}
+
+/**
+ * builds a polyphase filterbank.
+ * @param factor resampling factor
+ * @param scale wanted sum of coefficients for each filter
+ * @param filter_type filter type
+ * @param kaiser_beta kaiser window beta
+ * @return 0 on success, negative on error
+ */
+static int build_filter(ResampleContext *c, void *filter, double factor, int tap_count, int alloc, int phase_count, int scale,
+ int filter_type, int kaiser_beta){
+ int ph, i;
+ double x, y, w;
+ double *tab = av_malloc_array(tap_count, sizeof(*tab));
+ const int center= (tap_count-1)/2;
+
+ if (!tab)
+ return AVERROR(ENOMEM);
+
+ /* if upsampling, only need to interpolate, no filter */
+ if (factor > 1.0)
+ factor = 1.0;
+
+ for(ph=0;ph<phase_count;ph++) {
+ double norm = 0;
+ for(i=0;i<tap_count;i++) {
+ x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;
+ if (x == 0) y = 1.0;
+ else y = sin(x) / x;
+ switch(filter_type){
+ case SWR_FILTER_TYPE_CUBIC:{
+ const float d= -0.5; //first order derivative = -0.5
+ x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);
+ if(x<1.0) y= 1 - 3*x*x + 2*x*x*x + d*( -x*x + x*x*x);
+ else y= d*(-4 + 8*x - 5*x*x + x*x*x);
+ break;}
+ case SWR_FILTER_TYPE_BLACKMAN_NUTTALL:
+ w = 2.0*x / (factor*tap_count) + M_PI;
+ y *= 0.3635819 - 0.4891775 * cos(w) + 0.1365995 * cos(2*w) - 0.0106411 * cos(3*w);
+ break;
+ case SWR_FILTER_TYPE_KAISER:
+ w = 2.0*x / (factor*tap_count*M_PI);
+ y *= bessel(kaiser_beta*sqrt(FFMAX(1-w*w, 0)));
+ break;
+ default:
+ av_assert0(0);
+ }
+
+ tab[i] = y;
+ norm += y;
+ }
+
+ /* normalize so that an uniform color remains the same */
+ switch(c->format){
+ case AV_SAMPLE_FMT_S16P:
+ for(i=0;i<tap_count;i++)
+ ((int16_t*)filter)[ph * alloc + i] = av_clip(lrintf(tab[i] * scale / norm), INT16_MIN, INT16_MAX);
+ break;
+ case AV_SAMPLE_FMT_S32P:
+ for(i=0;i<tap_count;i++)
+ ((int32_t*)filter)[ph * alloc + i] = av_clipl_int32(llrint(tab[i] * scale / norm));
+ break;
+ case AV_SAMPLE_FMT_FLTP:
+ for(i=0;i<tap_count;i++)
+ ((float*)filter)[ph * alloc + i] = tab[i] * scale / norm;
+ break;
+ case AV_SAMPLE_FMT_DBLP:
+ for(i=0;i<tap_count;i++)
+ ((double*)filter)[ph * alloc + i] = tab[i] * scale / norm;
+ break;
+ }
+ }
+#if 0
+ {
+#define LEN 1024
+ int j,k;
+ double sine[LEN + tap_count];
+ double filtered[LEN];
+ double maxff=-2, minff=2, maxsf=-2, minsf=2;
+ for(i=0; i<LEN; i++){
+ double ss=0, sf=0, ff=0;
+ for(j=0; j<LEN+tap_count; j++)
+ sine[j]= cos(i*j*M_PI/LEN);
+ for(j=0; j<LEN; j++){
+ double sum=0;
+ ph=0;
+ for(k=0; k<tap_count; k++)
+ sum += filter[ph * tap_count + k] * sine[k+j];
+ filtered[j]= sum / (1<<FILTER_SHIFT);
+ ss+= sine[j + center] * sine[j + center];
+ ff+= filtered[j] * filtered[j];
+ sf+= sine[j + center] * filtered[j];
+ }
+ ss= sqrt(2*ss/LEN);
+ ff= sqrt(2*ff/LEN);
+ sf= 2*sf/LEN;
+ maxff= FFMAX(maxff, ff);
+ minff= FFMIN(minff, ff);
+ maxsf= FFMAX(maxsf, sf);
+ minsf= FFMIN(minsf, sf);
+ if(i%11==0){
+ av_log(NULL, AV_LOG_ERROR, "i:%4d ss:%f ff:%13.6e-%13.6e sf:%13.6e-%13.6e\n", i, ss, maxff, minff, maxsf, minsf);
+ minff=minsf= 2;
+ maxff=maxsf= -2;
+ }
+ }
+ }
+#endif
+
+ av_free(tab);
+ return 0;
+}
+
+static void resample_free(ResampleContext **cc){
+ ResampleContext *c = *cc;
+ if(!c)
+ return;
+ av_freep(&c->filter_bank);
+ av_freep(cc);
+}
+
+static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_rate, int filter_size, int phase_shift, int linear,
+ double cutoff0, enum AVSampleFormat format, enum SwrFilterType filter_type, int kaiser_beta,
+ double precision, int cheby)
+{
+ double cutoff = cutoff0? cutoff0 : 0.97;
+ double factor= FFMIN(out_rate * cutoff / in_rate, 1.0);
+ int phase_count= 1<<phase_shift;
+
+ if (!c || c->phase_shift != phase_shift || c->linear!=linear || c->factor != factor
+ || c->filter_length != FFMAX((int)ceil(filter_size/factor), 1) || c->format != format
+ || c->filter_type != filter_type || c->kaiser_beta != kaiser_beta) {
+ resample_free(&c);
+ c = av_mallocz(sizeof(*c));
+ if (!c)
+ return NULL;
+
+ c->format= format;
+
+ c->felem_size= av_get_bytes_per_sample(c->format);
+
+ switch(c->format){
+ case AV_SAMPLE_FMT_S16P:
+ c->filter_shift = 15;
+ break;
+ case AV_SAMPLE_FMT_S32P:
+ c->filter_shift = 30;
+ break;
+ case AV_SAMPLE_FMT_FLTP:
+ case AV_SAMPLE_FMT_DBLP:
+ c->filter_shift = 0;
+ break;
+ default:
+ av_log(NULL, AV_LOG_ERROR, "Unsupported sample format\n");
+ av_assert0(0);
+ }
+
+ if (filter_size/factor > INT32_MAX/256) {
+ av_log(NULL, AV_LOG_ERROR, "Filter length too large\n");
+ goto error;
+ }
+
+ c->phase_shift = phase_shift;
+ c->phase_mask = phase_count - 1;
+ c->linear = linear;
+ c->factor = factor;
+ c->filter_length = FFMAX((int)ceil(filter_size/factor), 1);
+ c->filter_alloc = FFALIGN(c->filter_length, 8);
+ c->filter_bank = av_calloc(c->filter_alloc, (phase_count+1)*c->felem_size);
+ c->filter_type = filter_type;
+ c->kaiser_beta = kaiser_beta;
+ if (!c->filter_bank)
+ goto error;
+ if (build_filter(c, (void*)c->filter_bank, factor, c->filter_length, c->filter_alloc, phase_count, 1<<c->filter_shift, filter_type, kaiser_beta))
+ goto error;
+ memcpy(c->filter_bank + (c->filter_alloc*phase_count+1)*c->felem_size, c->filter_bank, (c->filter_alloc-1)*c->felem_size);
+ memcpy(c->filter_bank + (c->filter_alloc*phase_count )*c->felem_size, c->filter_bank + (c->filter_alloc - 1)*c->felem_size, c->felem_size);
+ }
+
+ c->compensation_distance= 0;
+ if(!av_reduce(&c->src_incr, &c->dst_incr, out_rate, in_rate * (int64_t)phase_count, INT32_MAX/2))
+ goto error;
+ while (c->dst_incr < (1<<20) && c->src_incr < (1<<20)) {
+ c->dst_incr *= 2;
+ c->src_incr *= 2;
+ }
+ c->ideal_dst_incr = c->dst_incr;
+ c->dst_incr_div = c->dst_incr / c->src_incr;
+ c->dst_incr_mod = c->dst_incr % c->src_incr;
+
+ c->index= -phase_count*((c->filter_length-1)/2);
+ c->frac= 0;
+
+ swri_resample_dsp_init(c);
+
+ return c;
+error:
+ av_freep(&c->filter_bank);
+ av_free(c);
+ return NULL;
+}
+
+static int set_compensation(ResampleContext *c, int sample_delta, int compensation_distance){
+ c->compensation_distance= compensation_distance;
+ if (compensation_distance)
+ c->dst_incr = c->ideal_dst_incr - c->ideal_dst_incr * (int64_t)sample_delta / compensation_distance;
+ else
+ c->dst_incr = c->ideal_dst_incr;
+
+ c->dst_incr_div = c->dst_incr / c->src_incr;
+ c->dst_incr_mod = c->dst_incr % c->src_incr;
+
+ return 0;
+}
+
+static int swri_resample(ResampleContext *c,
+ uint8_t *dst, const uint8_t *src, int *consumed,
+ int src_size, int dst_size, int update_ctx)
+{
+ if (c->filter_length == 1 && c->phase_shift == 0) {
+ int index= c->index;
+ int frac= c->frac;
+ int64_t index2= (1LL<<32)*c->frac/c->src_incr + (1LL<<32)*index;
+ int64_t incr= (1LL<<32) * c->dst_incr / c->src_incr;
+ int new_size = (src_size * (int64_t)c->src_incr - frac + c->dst_incr - 1) / c->dst_incr;
+
+ dst_size= FFMIN(dst_size, new_size);
+ c->dsp.resample_one(dst, src, dst_size, index2, incr);
+
+ index += dst_size * c->dst_incr_div;
+ index += (frac + dst_size * (int64_t)c->dst_incr_mod) / c->src_incr;
+ av_assert2(index >= 0);
+ *consumed= index;
+ if (update_ctx) {
+ c->frac = (frac + dst_size * (int64_t)c->dst_incr_mod) % c->src_incr;
+ c->index = 0;
+ }
+ } else {
+ int64_t end_index = (1LL + src_size - c->filter_length) << c->phase_shift;
+ int64_t delta_frac = (end_index - c->index) * c->src_incr - c->frac;
+ int delta_n = (delta_frac + c->dst_incr - 1) / c->dst_incr;
+
+ dst_size = FFMIN(dst_size, delta_n);
+ if (dst_size > 0) {
+ *consumed = c->dsp.resample(c, dst, src, dst_size, update_ctx);
+ } else {
+ *consumed = 0;
+ }
+ }
+
+ return dst_size;
+}
+
+static int multiple_resample(ResampleContext *c, AudioData *dst, int dst_size, AudioData *src, int src_size, int *consumed){
+ int i, ret= -1;
+ int av_unused mm_flags = av_get_cpu_flags();
+ int need_emms = c->format == AV_SAMPLE_FMT_S16P && ARCH_X86_32 &&
+ (mm_flags & (AV_CPU_FLAG_MMX2 | AV_CPU_FLAG_SSE2)) == AV_CPU_FLAG_MMX2;
+ int64_t max_src_size = (INT64_MAX >> (c->phase_shift+1)) / c->src_incr;
+
+ if (c->compensation_distance)
+ dst_size = FFMIN(dst_size, c->compensation_distance);
+ src_size = FFMIN(src_size, max_src_size);
+
+ for(i=0; i<dst->ch_count; i++){
+ ret= swri_resample(c, dst->ch[i], src->ch[i],
+ consumed, src_size, dst_size, i+1==dst->ch_count);
+ }
+ if(need_emms)
+ emms_c();
+
+ if (c->compensation_distance) {
+ c->compensation_distance -= ret;
+ if (!c->compensation_distance) {
+ c->dst_incr = c->ideal_dst_incr;
+ c->dst_incr_div = c->dst_incr / c->src_incr;
+ c->dst_incr_mod = c->dst_incr % c->src_incr;
+ }
+ }
+
+ return ret;
+}
+
+static int64_t get_delay(struct SwrContext *s, int64_t base){
+ ResampleContext *c = s->resample;
+ int64_t num = s->in_buffer_count - (c->filter_length-1)/2;
+ num *= 1 << c->phase_shift;
+ num -= c->index;
+ num *= c->src_incr;
+ num -= c->frac;
+ return av_rescale(num, base, s->in_sample_rate*(int64_t)c->src_incr << c->phase_shift);
+}
+
+static int64_t get_out_samples(struct SwrContext *s, int in_samples) {
+ ResampleContext *c = s->resample;
+ // The + 2 are added to allow implementations to be slightly inaccurate, they should not be needed currently.
+ // They also make it easier to proof that changes and optimizations do not
+ // break the upper bound.
+ int64_t num = s->in_buffer_count + 2LL + in_samples;
+ num *= 1 << c->phase_shift;
+ num -= c->index;
+ num = av_rescale_rnd(num, s->out_sample_rate, ((int64_t)s->in_sample_rate) << c->phase_shift, AV_ROUND_UP) + 2;
+
+ if (c->compensation_distance) {
+ if (num > INT_MAX)
+ return AVERROR(EINVAL);
+
+ num = FFMAX(num, (num * c->ideal_dst_incr - 1) / c->dst_incr + 1);
+ }
+ return num;
+}
+
+static int resample_flush(struct SwrContext *s) {
+ AudioData *a= &s->in_buffer;
+ int i, j, ret;
+ if((ret = swri_realloc_audio(a, s->in_buffer_index + 2*s->in_buffer_count)) < 0)
+ return ret;
+ av_assert0(a->planar);
+ for(i=0; i<a->ch_count; i++){
+ for(j=0; j<s->in_buffer_count; j++){
+ memcpy(a->ch[i] + (s->in_buffer_index+s->in_buffer_count+j )*a->bps,
+ a->ch[i] + (s->in_buffer_index+s->in_buffer_count-j-1)*a->bps, a->bps);
+ }
+ }
+ s->in_buffer_count += (s->in_buffer_count+1)/2;
+ return 0;
+}
+
+// in fact the whole handle multiple ridiculously small buffers might need more thinking...
+static int invert_initial_buffer(ResampleContext *c, AudioData *dst, const AudioData *src,
+ int in_count, int *out_idx, int *out_sz)
+{
+ int n, ch, num = FFMIN(in_count + *out_sz, c->filter_length + 1), res;
+
+ if (c->index >= 0)
+ return 0;
+
+ if ((res = swri_realloc_audio(dst, c->filter_length * 2 + 1)) < 0)
+ return res;
+
+ // copy
+ for (n = *out_sz; n < num; n++) {
+ for (ch = 0; ch < src->ch_count; ch++) {
+ memcpy(dst->ch[ch] + ((c->filter_length + n) * c->felem_size),
+ src->ch[ch] + ((n - *out_sz) * c->felem_size), c->felem_size);
+ }
+ }
+
+ // if not enough data is in, return and wait for more
+ if (num < c->filter_length + 1) {
+ *out_sz = num;
+ *out_idx = c->filter_length;
+ return INT_MAX;
+ }
+
+ // else invert
+ for (n = 1; n <= c->filter_length; n++) {
+ for (ch = 0; ch < src->ch_count; ch++) {
+ memcpy(dst->ch[ch] + ((c->filter_length - n) * c->felem_size),
+ dst->ch[ch] + ((c->filter_length + n) * c->felem_size),
+ c->felem_size);
+ }
+ }
+
+ res = num - *out_sz;
+ *out_idx = c->filter_length + (c->index >> c->phase_shift);
+ *out_sz = FFMAX(*out_sz + c->filter_length,
+ 1 + c->filter_length * 2) - *out_idx;
+ c->index &= c->phase_mask;
+
+ return FFMAX(res, 0);
+}
+
+struct Resampler const swri_resampler={
+ resample_init,
+ resample_free,
+ multiple_resample,
+ resample_flush,
+ set_compensation,
+ get_delay,
+ invert_initial_buffer,
+ get_out_samples,
+};
diff --git a/ffmpeg-2-8-11/libswresample/resample.h b/ffmpeg-2-8-12/libswresample/resample.h
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/resample.h
rename to ffmpeg-2-8-12/libswresample/resample.h
diff --git a/ffmpeg-2-8-11/libswresample/resample_dsp.c b/ffmpeg-2-8-12/libswresample/resample_dsp.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/resample_dsp.c
rename to ffmpeg-2-8-12/libswresample/resample_dsp.c
diff --git a/ffmpeg-2-8-11/libswresample/resample_template.c b/ffmpeg-2-8-12/libswresample/resample_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/resample_template.c
rename to ffmpeg-2-8-12/libswresample/resample_template.c
diff --git a/ffmpeg-2-8-11/libswresample/soxr_resample.c b/ffmpeg-2-8-12/libswresample/soxr_resample.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/soxr_resample.c
rename to ffmpeg-2-8-12/libswresample/soxr_resample.c
diff --git a/ffmpeg-2-8-11/libswresample/swresample-test.c b/ffmpeg-2-8-12/libswresample/swresample-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/swresample-test.c
rename to ffmpeg-2-8-12/libswresample/swresample-test.c
diff --git a/ffmpeg-2-8-11/libswresample/swresample.c b/ffmpeg-2-8-12/libswresample/swresample.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/swresample.c
rename to ffmpeg-2-8-12/libswresample/swresample.c
diff --git a/ffmpeg-2-8-11/libswresample/swresample.h b/ffmpeg-2-8-12/libswresample/swresample.h
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/swresample.h
rename to ffmpeg-2-8-12/libswresample/swresample.h
diff --git a/ffmpeg-2-8-11/libswresample/swresample_frame.c b/ffmpeg-2-8-12/libswresample/swresample_frame.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/swresample_frame.c
rename to ffmpeg-2-8-12/libswresample/swresample_frame.c
diff --git a/ffmpeg-2-8-11/libswresample/swresample_internal.h b/ffmpeg-2-8-12/libswresample/swresample_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/swresample_internal.h
rename to ffmpeg-2-8-12/libswresample/swresample_internal.h
diff --git a/ffmpeg-2-8-11/libswresample/swresampleres.rc b/ffmpeg-2-8-12/libswresample/swresampleres.rc
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/swresampleres.rc
rename to ffmpeg-2-8-12/libswresample/swresampleres.rc
diff --git a/ffmpeg-2-8-11/libswresample/version.h b/ffmpeg-2-8-12/libswresample/version.h
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/version.h
rename to ffmpeg-2-8-12/libswresample/version.h
diff --git a/ffmpeg-2-8-11/libswresample/x86/Makefile b/ffmpeg-2-8-12/libswresample/x86/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/x86/Makefile
rename to ffmpeg-2-8-12/libswresample/x86/Makefile
diff --git a/ffmpeg-2-8-11/libswresample/x86/audio_convert.asm b/ffmpeg-2-8-12/libswresample/x86/audio_convert.asm
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/x86/audio_convert.asm
rename to ffmpeg-2-8-12/libswresample/x86/audio_convert.asm
diff --git a/ffmpeg-2-8-11/libswresample/x86/audio_convert_init.c b/ffmpeg-2-8-12/libswresample/x86/audio_convert_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/x86/audio_convert_init.c
rename to ffmpeg-2-8-12/libswresample/x86/audio_convert_init.c
diff --git a/ffmpeg-2-8-11/libswresample/x86/rematrix.asm b/ffmpeg-2-8-12/libswresample/x86/rematrix.asm
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/x86/rematrix.asm
rename to ffmpeg-2-8-12/libswresample/x86/rematrix.asm
diff --git a/ffmpeg-2-8-11/libswresample/x86/rematrix_init.c b/ffmpeg-2-8-12/libswresample/x86/rematrix_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/x86/rematrix_init.c
rename to ffmpeg-2-8-12/libswresample/x86/rematrix_init.c
diff --git a/ffmpeg-2-8-11/libswresample/x86/resample.asm b/ffmpeg-2-8-12/libswresample/x86/resample.asm
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/x86/resample.asm
rename to ffmpeg-2-8-12/libswresample/x86/resample.asm
diff --git a/ffmpeg-2-8-11/libswresample/x86/resample_init.c b/ffmpeg-2-8-12/libswresample/x86/resample_init.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/x86/resample_init.c
rename to ffmpeg-2-8-12/libswresample/x86/resample_init.c
diff --git a/ffmpeg-2-8-11/libswresample/x86/w64xmmtest.c b/ffmpeg-2-8-12/libswresample/x86/w64xmmtest.c
similarity index 100%
rename from ffmpeg-2-8-11/libswresample/x86/w64xmmtest.c
rename to ffmpeg-2-8-12/libswresample/x86/w64xmmtest.c
diff --git a/ffmpeg-2-8-11/libswscale/Makefile b/ffmpeg-2-8-12/libswscale/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/Makefile
rename to ffmpeg-2-8-12/libswscale/Makefile
diff --git a/ffmpeg-2-8-11/libswscale/alphablend.c b/ffmpeg-2-8-12/libswscale/alphablend.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/alphablend.c
rename to ffmpeg-2-8-12/libswscale/alphablend.c
diff --git a/ffmpeg-2-8-11/libswscale/arm/Makefile b/ffmpeg-2-8-12/libswscale/arm/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/arm/Makefile
rename to ffmpeg-2-8-12/libswscale/arm/Makefile
diff --git a/ffmpeg-2-8-11/libswscale/arm/rgb2yuv_neon_16.S b/ffmpeg-2-8-12/libswscale/arm/rgb2yuv_neon_16.S
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/arm/rgb2yuv_neon_16.S
rename to ffmpeg-2-8-12/libswscale/arm/rgb2yuv_neon_16.S
diff --git a/ffmpeg-2-8-11/libswscale/arm/rgb2yuv_neon_32.S b/ffmpeg-2-8-12/libswscale/arm/rgb2yuv_neon_32.S
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/arm/rgb2yuv_neon_32.S
rename to ffmpeg-2-8-12/libswscale/arm/rgb2yuv_neon_32.S
diff --git a/ffmpeg-2-8-11/libswscale/arm/rgb2yuv_neon_common.S b/ffmpeg-2-8-12/libswscale/arm/rgb2yuv_neon_common.S
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/arm/rgb2yuv_neon_common.S
rename to ffmpeg-2-8-12/libswscale/arm/rgb2yuv_neon_common.S
diff --git a/ffmpeg-2-8-11/libswscale/arm/swscale_unscaled.c b/ffmpeg-2-8-12/libswscale/arm/swscale_unscaled.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/arm/swscale_unscaled.c
rename to ffmpeg-2-8-12/libswscale/arm/swscale_unscaled.c
diff --git a/ffmpeg-2-8-11/libswscale/bayer_template.c b/ffmpeg-2-8-12/libswscale/bayer_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/bayer_template.c
rename to ffmpeg-2-8-12/libswscale/bayer_template.c
diff --git a/ffmpeg-2-8-11/libswscale/colorspace-test.c b/ffmpeg-2-8-12/libswscale/colorspace-test.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/colorspace-test.c
rename to ffmpeg-2-8-12/libswscale/colorspace-test.c
diff --git a/ffmpeg-2-8-11/libswscale/gamma.c b/ffmpeg-2-8-12/libswscale/gamma.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/gamma.c
rename to ffmpeg-2-8-12/libswscale/gamma.c
diff --git a/ffmpeg-2-8-11/libswscale/hscale.c b/ffmpeg-2-8-12/libswscale/hscale.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/hscale.c
rename to ffmpeg-2-8-12/libswscale/hscale.c
diff --git a/ffmpeg-2-8-11/libswscale/hscale_fast_bilinear.c b/ffmpeg-2-8-12/libswscale/hscale_fast_bilinear.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/hscale_fast_bilinear.c
rename to ffmpeg-2-8-12/libswscale/hscale_fast_bilinear.c
diff --git a/ffmpeg-2-8-11/libswscale/input.c b/ffmpeg-2-8-12/libswscale/input.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/input.c
rename to ffmpeg-2-8-12/libswscale/input.c
diff --git a/ffmpeg-2-8-11/libswscale/libswscale.v b/ffmpeg-2-8-12/libswscale/libswscale.v
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/libswscale.v
rename to ffmpeg-2-8-12/libswscale/libswscale.v
diff --git a/ffmpeg-2-8-11/libswscale/log2_tab.c b/ffmpeg-2-8-12/libswscale/log2_tab.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/log2_tab.c
rename to ffmpeg-2-8-12/libswscale/log2_tab.c
diff --git a/ffmpeg-2-8-11/libswscale/options.c b/ffmpeg-2-8-12/libswscale/options.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/options.c
rename to ffmpeg-2-8-12/libswscale/options.c
diff --git a/ffmpeg-2-8-11/libswscale/output.c b/ffmpeg-2-8-12/libswscale/output.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/output.c
rename to ffmpeg-2-8-12/libswscale/output.c
diff --git a/ffmpeg-2-8-11/libswscale/ppc/Makefile b/ffmpeg-2-8-12/libswscale/ppc/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/ppc/Makefile
rename to ffmpeg-2-8-12/libswscale/ppc/Makefile
diff --git a/ffmpeg-2-8-11/libswscale/ppc/swscale_altivec.c b/ffmpeg-2-8-12/libswscale/ppc/swscale_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/ppc/swscale_altivec.c
rename to ffmpeg-2-8-12/libswscale/ppc/swscale_altivec.c
diff --git a/ffmpeg-2-8-11/libswscale/ppc/yuv2rgb_altivec.c b/ffmpeg-2-8-12/libswscale/ppc/yuv2rgb_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/ppc/yuv2rgb_altivec.c
rename to ffmpeg-2-8-12/libswscale/ppc/yuv2rgb_altivec.c
diff --git a/ffmpeg-2-8-11/libswscale/ppc/yuv2rgb_altivec.h b/ffmpeg-2-8-12/libswscale/ppc/yuv2rgb_altivec.h
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/ppc/yuv2rgb_altivec.h
rename to ffmpeg-2-8-12/libswscale/ppc/yuv2rgb_altivec.h
diff --git a/ffmpeg-2-8-11/libswscale/ppc/yuv2yuv_altivec.c b/ffmpeg-2-8-12/libswscale/ppc/yuv2yuv_altivec.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/ppc/yuv2yuv_altivec.c
rename to ffmpeg-2-8-12/libswscale/ppc/yuv2yuv_altivec.c
diff --git a/ffmpeg-2-8-11/libswscale/rgb2rgb.c b/ffmpeg-2-8-12/libswscale/rgb2rgb.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/rgb2rgb.c
rename to ffmpeg-2-8-12/libswscale/rgb2rgb.c
diff --git a/ffmpeg-2-8-11/libswscale/rgb2rgb.h b/ffmpeg-2-8-12/libswscale/rgb2rgb.h
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/rgb2rgb.h
rename to ffmpeg-2-8-12/libswscale/rgb2rgb.h
diff --git a/ffmpeg-2-8-11/libswscale/rgb2rgb_template.c b/ffmpeg-2-8-12/libswscale/rgb2rgb_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/rgb2rgb_template.c
rename to ffmpeg-2-8-12/libswscale/rgb2rgb_template.c
diff --git a/ffmpeg-2-8-11/libswscale/slice.c b/ffmpeg-2-8-12/libswscale/slice.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/slice.c
rename to ffmpeg-2-8-12/libswscale/slice.c
diff --git a/ffmpeg-2-8-12/libswscale/swscale-test.c b/ffmpeg-2-8-12/libswscale/swscale-test.c
new file mode 100644
index 0000000..45e25a3
--- /dev/null
+++ b/ffmpeg-2-8-12/libswscale/swscale-test.c
@@ -0,0 +1,417 @@
+/*
+ * Copyright (C) 2003-2011 Michael Niedermayer <michaelni at gmx.at>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <stdarg.h>
+
+#undef HAVE_AV_CONFIG_H
+#include "libavutil/imgutils.h"
+#include "libavutil/mem.h"
+#include "libavutil/avutil.h"
+#include "libavutil/crc.h"
+#include "libavutil/pixdesc.h"
+#include "libavutil/lfg.h"
+#include "swscale.h"
+
+/* HACK Duplicated from swscale_internal.h.
+ * Should be removed when a cleaner pixel format system exists. */
+#define isGray(x) \
+ ((x) == AV_PIX_FMT_GRAY8 || \
+ (x) == AV_PIX_FMT_YA8 || \
+ (x) == AV_PIX_FMT_GRAY16BE || \
+ (x) == AV_PIX_FMT_GRAY16LE || \
+ (x) == AV_PIX_FMT_YA16BE || \
+ (x) == AV_PIX_FMT_YA16LE)
+#define hasChroma(x) \
+ (!(isGray(x) || \
+ (x) == AV_PIX_FMT_MONOBLACK || \
+ (x) == AV_PIX_FMT_MONOWHITE))
+#define isALPHA(x) \
+ ((x) == AV_PIX_FMT_BGR32 || \
+ (x) == AV_PIX_FMT_BGR32_1 || \
+ (x) == AV_PIX_FMT_RGB32 || \
+ (x) == AV_PIX_FMT_RGB32_1 || \
+ (x) == AV_PIX_FMT_YUVA420P)
+
+static uint64_t getSSD(const uint8_t *src1, const uint8_t *src2, int stride1,
+ int stride2, int w, int h)
+{
+ int x, y;
+ uint64_t ssd = 0;
+
+ for (y = 0; y < h; y++) {
+ for (x = 0; x < w; x++) {
+ int d = src1[x + y * stride1] - src2[x + y * stride2];
+ ssd += d * d;
+ }
+ }
+ return ssd;
+}
+
+struct Results {
+ uint64_t ssdY;
+ uint64_t ssdU;
+ uint64_t ssdV;
+ uint64_t ssdA;
+ uint32_t crc;
+};
+
+// test by ref -> src -> dst -> out & compare out against ref
+// ref & out are YV12
+static int doTest(uint8_t *ref[4], int refStride[4], int w, int h,
+ enum AVPixelFormat srcFormat, enum AVPixelFormat dstFormat,
+ int srcW, int srcH, int dstW, int dstH, int flags,
+ struct Results *r)
+{
+ const AVPixFmtDescriptor *desc_yuva420p = av_pix_fmt_desc_get(AV_PIX_FMT_YUVA420P);
+ const AVPixFmtDescriptor *desc_src = av_pix_fmt_desc_get(srcFormat);
+ const AVPixFmtDescriptor *desc_dst = av_pix_fmt_desc_get(dstFormat);
+ static enum AVPixelFormat cur_srcFormat;
+ static int cur_srcW, cur_srcH;
+ static uint8_t *src[4];
+ static int srcStride[4];
+ uint8_t *dst[4] = { 0 };
+ uint8_t *out[4] = { 0 };
+ int dstStride[4] = {0};
+ int i;
+ uint64_t ssdY, ssdU = 0, ssdV = 0, ssdA = 0;
+ struct SwsContext *dstContext = NULL, *outContext = NULL;
+ uint32_t crc = 0;
+ int res = 0;
+
+ if (cur_srcFormat != srcFormat || cur_srcW != srcW || cur_srcH != srcH) {
+ struct SwsContext *srcContext = NULL;
+ int p;
+
+ for (p = 0; p < 4; p++)
+ av_freep(&src[p]);
+
+ av_image_fill_linesizes(srcStride, srcFormat, srcW);
+ for (p = 0; p < 4; p++) {
+ srcStride[p] = FFALIGN(srcStride[p], 16);
+ if (srcStride[p])
+ src[p] = av_mallocz(srcStride[p] * srcH + 16);
+ if (srcStride[p] && !src[p]) {
+ perror("Malloc");
+ res = -1;
+ goto end;
+ }
+ }
+ srcContext = sws_getContext(w, h, AV_PIX_FMT_YUVA420P, srcW, srcH,
+ srcFormat, SWS_BILINEAR, NULL, NULL, NULL);
+ if (!srcContext) {
+ fprintf(stderr, "Failed to get %s ---> %s\n",
+ desc_yuva420p->name,
+ desc_src->name);
+ res = -1;
+ goto end;
+ }
+ sws_scale(srcContext, (const uint8_t * const*)ref, refStride, 0, h, src, srcStride);
+ sws_freeContext(srcContext);
+
+ cur_srcFormat = srcFormat;
+ cur_srcW = srcW;
+ cur_srcH = srcH;
+ }
+
+ av_image_fill_linesizes(dstStride, dstFormat, dstW);
+ for (i = 0; i < 4; i++) {
+ /* Image buffers passed into libswscale can be allocated any way you
+ * prefer, as long as they're aligned enough for the architecture, and
+ * they're freed appropriately (such as using av_free for buffers
+ * allocated with av_malloc). */
+ /* An extra 16 bytes is being allocated because some scalers may write
+ * out of bounds. */
+ dstStride[i] = FFALIGN(dstStride[i], 16);
+ if (dstStride[i])
+ dst[i] = av_mallocz(dstStride[i] * dstH + 16);
+ if (dstStride[i] && !dst[i]) {
+ perror("Malloc");
+ res = -1;
+
+ goto end;
+ }
+ }
+
+ dstContext = sws_getContext(srcW, srcH, srcFormat, dstW, dstH, dstFormat,
+ flags, NULL, NULL, NULL);
+ if (!dstContext) {
+ fprintf(stderr, "Failed to get %s ---> %s\n",
+ desc_src->name, desc_dst->name);
+ res = -1;
+ goto end;
+ }
+
+ printf(" %s %dx%d -> %s %3dx%3d flags=%2d",
+ desc_src->name, srcW, srcH,
+ desc_dst->name, dstW, dstH,
+ flags);
+ fflush(stdout);
+
+ sws_scale(dstContext, (const uint8_t * const*)src, srcStride, 0, srcH, dst, dstStride);
+
+ for (i = 0; i < 4 && dstStride[i]; i++)
+ crc = av_crc(av_crc_get_table(AV_CRC_32_IEEE), crc, dst[i],
+ dstStride[i] * dstH);
+
+ if (r && crc == r->crc) {
+ ssdY = r->ssdY;
+ ssdU = r->ssdU;
+ ssdV = r->ssdV;
+ ssdA = r->ssdA;
+ } else {
+ for (i = 0; i < 4; i++) {
+ refStride[i] = FFALIGN(refStride[i], 16);
+ if (refStride[i])
+ out[i] = av_mallocz(refStride[i] * h);
+ if (refStride[i] && !out[i]) {
+ perror("Malloc");
+ res = -1;
+ goto end;
+ }
+ }
+ outContext = sws_getContext(dstW, dstH, dstFormat, w, h,
+ AV_PIX_FMT_YUVA420P, SWS_BILINEAR,
+ NULL, NULL, NULL);
+ if (!outContext) {
+ fprintf(stderr, "Failed to get %s ---> %s\n",
+ desc_dst->name,
+ desc_yuva420p->name);
+ res = -1;
+ goto end;
+ }
+ sws_scale(outContext, (const uint8_t * const*)dst, dstStride, 0, dstH, out, refStride);
+
+ ssdY = getSSD(ref[0], out[0], refStride[0], refStride[0], w, h);
+ if (hasChroma(srcFormat) && hasChroma(dstFormat)) {
+ //FIXME check that output is really gray
+ ssdU = getSSD(ref[1], out[1], refStride[1], refStride[1],
+ (w + 1) >> 1, (h + 1) >> 1);
+ ssdV = getSSD(ref[2], out[2], refStride[2], refStride[2],
+ (w + 1) >> 1, (h + 1) >> 1);
+ }
+ if (isALPHA(srcFormat) && isALPHA(dstFormat))
+ ssdA = getSSD(ref[3], out[3], refStride[3], refStride[3], w, h);
+
+ ssdY /= w * h;
+ ssdU /= w * h / 4;
+ ssdV /= w * h / 4;
+ ssdA /= w * h;
+
+ sws_freeContext(outContext);
+
+ for (i = 0; i < 4; i++)
+ if (refStride[i])
+ av_free(out[i]);
+ }
+
+ printf(" CRC=%08x SSD=%5"PRId64 ",%5"PRId64 ",%5"PRId64 ",%5"PRId64 "\n",
+ crc, ssdY, ssdU, ssdV, ssdA);
+
+end:
+ sws_freeContext(dstContext);
+
+ for (i = 0; i < 4; i++)
+ if (dstStride[i])
+ av_free(dst[i]);
+
+ return res;
+}
+
+static void selfTest(uint8_t *ref[4], int refStride[4], int w, int h,
+ enum AVPixelFormat srcFormat_in,
+ enum AVPixelFormat dstFormat_in)
+{
+ const int flags[] = { SWS_FAST_BILINEAR, SWS_BILINEAR, SWS_BICUBIC,
+ SWS_X, SWS_POINT, SWS_AREA, 0 };
+ const int srcW = w;
+ const int srcH = h;
+ const int dstW[] = { srcW - srcW / 3, srcW, srcW + srcW / 3, 0 };
+ const int dstH[] = { srcH - srcH / 3, srcH, srcH + srcH / 3, 0 };
+ enum AVPixelFormat srcFormat, dstFormat;
+ const AVPixFmtDescriptor *desc_src, *desc_dst;
+
+ for (srcFormat = srcFormat_in != AV_PIX_FMT_NONE ? srcFormat_in : 0;
+ srcFormat < AV_PIX_FMT_NB; srcFormat++) {
+ if (!sws_isSupportedInput(srcFormat) ||
+ !sws_isSupportedOutput(srcFormat))
+ continue;
+
+ desc_src = av_pix_fmt_desc_get(srcFormat);
+
+ for (dstFormat = dstFormat_in != AV_PIX_FMT_NONE ? dstFormat_in : 0;
+ dstFormat < AV_PIX_FMT_NB; dstFormat++) {
+ int i, j, k;
+ int res = 0;
+
+ if (!sws_isSupportedInput(dstFormat) ||
+ !sws_isSupportedOutput(dstFormat))
+ continue;
+
+ desc_dst = av_pix_fmt_desc_get(dstFormat);
+
+ printf("%s -> %s\n", desc_src->name, desc_dst->name);
+ fflush(stdout);
+
+ for (k = 0; flags[k] && !res; k++)
+ for (i = 0; dstW[i] && !res; i++)
+ for (j = 0; dstH[j] && !res; j++)
+ res = doTest(ref, refStride, w, h,
+ srcFormat, dstFormat,
+ srcW, srcH, dstW[i], dstH[j], flags[k],
+ NULL);
+ if (dstFormat_in != AV_PIX_FMT_NONE)
+ break;
+ }
+ if (srcFormat_in != AV_PIX_FMT_NONE)
+ break;
+ }
+}
+
+static int fileTest(uint8_t *ref[4], int refStride[4], int w, int h, FILE *fp,
+ enum AVPixelFormat srcFormat_in,
+ enum AVPixelFormat dstFormat_in)
+{
+ char buf[256];
+
+ while (fgets(buf, sizeof(buf), fp)) {
+ struct Results r;
+ enum AVPixelFormat srcFormat;
+ char srcStr[12];
+ int srcW = 0, srcH = 0;
+ enum AVPixelFormat dstFormat;
+ char dstStr[12];
+ int dstW = 0, dstH = 0;
+ int flags;
+ int ret;
+
+ ret = sscanf(buf,
+ " %12s %dx%d -> %12s %dx%d flags=%d CRC=%x"
+ " SSD=%"SCNd64 ", %"SCNd64 ", %"SCNd64 ", %"SCNd64 "\n",
+ srcStr, &srcW, &srcH, dstStr, &dstW, &dstH,
+ &flags, &r.crc, &r.ssdY, &r.ssdU, &r.ssdV, &r.ssdA);
+ if (ret != 12) {
+ srcStr[0] = dstStr[0] = 0;
+ ret = sscanf(buf, "%12s -> %12s\n", srcStr, dstStr);
+ }
+
+ srcFormat = av_get_pix_fmt(srcStr);
+ dstFormat = av_get_pix_fmt(dstStr);
+
+ if (srcFormat == AV_PIX_FMT_NONE || dstFormat == AV_PIX_FMT_NONE ||
+ srcW > 8192U || srcH > 8192U || dstW > 8192U || dstH > 8192U) {
+ fprintf(stderr, "malformed input file\n");
+ return -1;
+ }
+ if ((srcFormat_in != AV_PIX_FMT_NONE && srcFormat_in != srcFormat) ||
+ (dstFormat_in != AV_PIX_FMT_NONE && dstFormat_in != dstFormat))
+ continue;
+ if (ret != 12) {
+ printf("%s", buf);
+ continue;
+ }
+
+ doTest(ref, refStride, w, h,
+ srcFormat, dstFormat,
+ srcW, srcH, dstW, dstH, flags,
+ &r);
+ }
+
+ return 0;
+}
+
+#define W 96
+#define H 96
+
+int main(int argc, char **argv)
+{
+ enum AVPixelFormat srcFormat = AV_PIX_FMT_NONE;
+ enum AVPixelFormat dstFormat = AV_PIX_FMT_NONE;
+ uint8_t *rgb_data = av_malloc(W * H * 4);
+ const uint8_t * const rgb_src[4] = { rgb_data, NULL, NULL, NULL };
+ int rgb_stride[4] = { 4 * W, 0, 0, 0 };
+ uint8_t *data = av_malloc(4 * W * H);
+ uint8_t *src[4] = { data, data + W * H, data + W * H * 2, data + W * H * 3 };
+ int stride[4] = { W, W, W, W };
+ int x, y;
+ struct SwsContext *sws;
+ AVLFG rand;
+ int res = -1;
+ int i;
+ FILE *fp = NULL;
+
+ if (!rgb_data || !data)
+ return -1;
+
+ 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], "r");
+ if (!fp) {
+ fprintf(stderr, "could not open '%s'\n", argv[i + 1]);
+ goto error;
+ }
+ } else if (!strcmp(argv[i], "-src")) {
+ srcFormat = av_get_pix_fmt(argv[i + 1]);
+ if (srcFormat == AV_PIX_FMT_NONE) {
+ fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
+ return -1;
+ }
+ } else if (!strcmp(argv[i], "-dst")) {
+ dstFormat = av_get_pix_fmt(argv[i + 1]);
+ if (dstFormat == AV_PIX_FMT_NONE) {
+ fprintf(stderr, "invalid pixel format %s\n", argv[i + 1]);
+ return -1;
+ }
+ } else {
+bad_option:
+ fprintf(stderr, "bad option or argument missing (%s)\n", argv[i]);
+ goto error;
+ }
+ }
+
+ sws = sws_getContext(W / 12, H / 12, AV_PIX_FMT_RGB32, W, H,
+ AV_PIX_FMT_YUVA420P, SWS_BILINEAR, NULL, NULL, NULL);
+
+ av_lfg_init(&rand, 1);
+
+ 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, src, stride);
+ sws_freeContext(sws);
+ av_free(rgb_data);
+
+ if(fp) {
+ res = fileTest(src, stride, W, H, fp, srcFormat, dstFormat);
+ fclose(fp);
+ } else {
+ selfTest(src, stride, W, H, srcFormat, dstFormat);
+ res = 0;
+ }
+error:
+ av_free(data);
+
+ return res;
+}
diff --git a/ffmpeg-2-8-11/libswscale/swscale.c b/ffmpeg-2-8-12/libswscale/swscale.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/swscale.c
rename to ffmpeg-2-8-12/libswscale/swscale.c
diff --git a/ffmpeg-2-8-11/libswscale/swscale.h b/ffmpeg-2-8-12/libswscale/swscale.h
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/swscale.h
rename to ffmpeg-2-8-12/libswscale/swscale.h
diff --git a/ffmpeg-2-8-11/libswscale/swscale_internal.h b/ffmpeg-2-8-12/libswscale/swscale_internal.h
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/swscale_internal.h
rename to ffmpeg-2-8-12/libswscale/swscale_internal.h
diff --git a/ffmpeg-2-8-11/libswscale/swscale_unscaled.c b/ffmpeg-2-8-12/libswscale/swscale_unscaled.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/swscale_unscaled.c
rename to ffmpeg-2-8-12/libswscale/swscale_unscaled.c
diff --git a/ffmpeg-2-8-11/libswscale/swscaleres.rc b/ffmpeg-2-8-12/libswscale/swscaleres.rc
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/swscaleres.rc
rename to ffmpeg-2-8-12/libswscale/swscaleres.rc
diff --git a/ffmpeg-2-8-11/libswscale/utils.c b/ffmpeg-2-8-12/libswscale/utils.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/utils.c
rename to ffmpeg-2-8-12/libswscale/utils.c
diff --git a/ffmpeg-2-8-11/libswscale/version.h b/ffmpeg-2-8-12/libswscale/version.h
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/version.h
rename to ffmpeg-2-8-12/libswscale/version.h
diff --git a/ffmpeg-2-8-11/libswscale/vscale.c b/ffmpeg-2-8-12/libswscale/vscale.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/vscale.c
rename to ffmpeg-2-8-12/libswscale/vscale.c
diff --git a/ffmpeg-2-8-11/libswscale/x86/Makefile b/ffmpeg-2-8-12/libswscale/x86/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/x86/Makefile
rename to ffmpeg-2-8-12/libswscale/x86/Makefile
diff --git a/ffmpeg-2-8-11/libswscale/x86/hscale_fast_bilinear_simd.c b/ffmpeg-2-8-12/libswscale/x86/hscale_fast_bilinear_simd.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/x86/hscale_fast_bilinear_simd.c
rename to ffmpeg-2-8-12/libswscale/x86/hscale_fast_bilinear_simd.c
diff --git a/ffmpeg-2-8-11/libswscale/x86/input.asm b/ffmpeg-2-8-12/libswscale/x86/input.asm
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/x86/input.asm
rename to ffmpeg-2-8-12/libswscale/x86/input.asm
diff --git a/ffmpeg-2-8-11/libswscale/x86/output.asm b/ffmpeg-2-8-12/libswscale/x86/output.asm
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/x86/output.asm
rename to ffmpeg-2-8-12/libswscale/x86/output.asm
diff --git a/ffmpeg-2-8-11/libswscale/x86/rgb2rgb.c b/ffmpeg-2-8-12/libswscale/x86/rgb2rgb.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/x86/rgb2rgb.c
rename to ffmpeg-2-8-12/libswscale/x86/rgb2rgb.c
diff --git a/ffmpeg-2-8-11/libswscale/x86/rgb2rgb_template.c b/ffmpeg-2-8-12/libswscale/x86/rgb2rgb_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/x86/rgb2rgb_template.c
rename to ffmpeg-2-8-12/libswscale/x86/rgb2rgb_template.c
diff --git a/ffmpeg-2-8-11/libswscale/x86/scale.asm b/ffmpeg-2-8-12/libswscale/x86/scale.asm
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/x86/scale.asm
rename to ffmpeg-2-8-12/libswscale/x86/scale.asm
diff --git a/ffmpeg-2-8-11/libswscale/x86/swscale.c b/ffmpeg-2-8-12/libswscale/x86/swscale.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/x86/swscale.c
rename to ffmpeg-2-8-12/libswscale/x86/swscale.c
diff --git a/ffmpeg-2-8-11/libswscale/x86/swscale_template.c b/ffmpeg-2-8-12/libswscale/x86/swscale_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/x86/swscale_template.c
rename to ffmpeg-2-8-12/libswscale/x86/swscale_template.c
diff --git a/ffmpeg-2-8-11/libswscale/x86/w64xmmtest.c b/ffmpeg-2-8-12/libswscale/x86/w64xmmtest.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/x86/w64xmmtest.c
rename to ffmpeg-2-8-12/libswscale/x86/w64xmmtest.c
diff --git a/ffmpeg-2-8-11/libswscale/x86/yuv2rgb.c b/ffmpeg-2-8-12/libswscale/x86/yuv2rgb.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/x86/yuv2rgb.c
rename to ffmpeg-2-8-12/libswscale/x86/yuv2rgb.c
diff --git a/ffmpeg-2-8-11/libswscale/x86/yuv2rgb_template.c b/ffmpeg-2-8-12/libswscale/x86/yuv2rgb_template.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/x86/yuv2rgb_template.c
rename to ffmpeg-2-8-12/libswscale/x86/yuv2rgb_template.c
diff --git a/ffmpeg-2-8-11/libswscale/yuv2rgb.c b/ffmpeg-2-8-12/libswscale/yuv2rgb.c
similarity index 100%
rename from ffmpeg-2-8-11/libswscale/yuv2rgb.c
rename to ffmpeg-2-8-12/libswscale/yuv2rgb.c
diff --git a/ffmpeg-2-8-11/presets/libvpx-1080p.ffpreset b/ffmpeg-2-8-12/presets/libvpx-1080p.ffpreset
similarity index 100%
rename from ffmpeg-2-8-11/presets/libvpx-1080p.ffpreset
rename to ffmpeg-2-8-12/presets/libvpx-1080p.ffpreset
diff --git a/ffmpeg-2-8-11/presets/libvpx-1080p50_60.ffpreset b/ffmpeg-2-8-12/presets/libvpx-1080p50_60.ffpreset
similarity index 100%
rename from ffmpeg-2-8-11/presets/libvpx-1080p50_60.ffpreset
rename to ffmpeg-2-8-12/presets/libvpx-1080p50_60.ffpreset
diff --git a/ffmpeg-2-8-11/presets/libvpx-360p.ffpreset b/ffmpeg-2-8-12/presets/libvpx-360p.ffpreset
similarity index 100%
rename from ffmpeg-2-8-11/presets/libvpx-360p.ffpreset
rename to ffmpeg-2-8-12/presets/libvpx-360p.ffpreset
diff --git a/ffmpeg-2-8-11/presets/libvpx-720p.ffpreset b/ffmpeg-2-8-12/presets/libvpx-720p.ffpreset
similarity index 100%
rename from ffmpeg-2-8-11/presets/libvpx-720p.ffpreset
rename to ffmpeg-2-8-12/presets/libvpx-720p.ffpreset
diff --git a/ffmpeg-2-8-11/presets/libvpx-720p50_60.ffpreset b/ffmpeg-2-8-12/presets/libvpx-720p50_60.ffpreset
similarity index 100%
rename from ffmpeg-2-8-11/presets/libvpx-720p50_60.ffpreset
rename to ffmpeg-2-8-12/presets/libvpx-720p50_60.ffpreset
diff --git a/ffmpeg-2-8-11/tests/Makefile b/ffmpeg-2-8-12/tests/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/tests/Makefile
rename to ffmpeg-2-8-12/tests/Makefile
diff --git a/ffmpeg-2-8-11/tests/api/Makefile b/ffmpeg-2-8-12/tests/api/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/tests/api/Makefile
rename to ffmpeg-2-8-12/tests/api/Makefile
diff --git a/ffmpeg-2-8-11/tests/api/api-band-test.c b/ffmpeg-2-8-12/tests/api/api-band-test.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/api/api-band-test.c
rename to ffmpeg-2-8-12/tests/api/api-band-test.c
diff --git a/ffmpeg-2-8-11/tests/api/api-flac-test.c b/ffmpeg-2-8-12/tests/api/api-flac-test.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/api/api-flac-test.c
rename to ffmpeg-2-8-12/tests/api/api-flac-test.c
diff --git a/ffmpeg-2-8-11/tests/api/api-h264-test.c b/ffmpeg-2-8-12/tests/api/api-h264-test.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/api/api-h264-test.c
rename to ffmpeg-2-8-12/tests/api/api-h264-test.c
diff --git a/ffmpeg-2-8-11/tests/api/api-seek-test.c b/ffmpeg-2-8-12/tests/api/api-seek-test.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/api/api-seek-test.c
rename to ffmpeg-2-8-12/tests/api/api-seek-test.c
diff --git a/ffmpeg-2-8-11/tests/audiogen.c b/ffmpeg-2-8-12/tests/audiogen.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/audiogen.c
rename to ffmpeg-2-8-12/tests/audiogen.c
diff --git a/ffmpeg-2-8-11/tests/base64.c b/ffmpeg-2-8-12/tests/base64.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/base64.c
rename to ffmpeg-2-8-12/tests/base64.c
diff --git a/ffmpeg-2-8-11/tests/checkasm/Makefile b/ffmpeg-2-8-12/tests/checkasm/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/tests/checkasm/Makefile
rename to ffmpeg-2-8-12/tests/checkasm/Makefile
diff --git a/ffmpeg-2-8-11/tests/checkasm/bswapdsp.c b/ffmpeg-2-8-12/tests/checkasm/bswapdsp.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/checkasm/bswapdsp.c
rename to ffmpeg-2-8-12/tests/checkasm/bswapdsp.c
diff --git a/ffmpeg-2-8-11/tests/checkasm/checkasm.c b/ffmpeg-2-8-12/tests/checkasm/checkasm.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/checkasm/checkasm.c
rename to ffmpeg-2-8-12/tests/checkasm/checkasm.c
diff --git a/ffmpeg-2-8-11/tests/checkasm/checkasm.h b/ffmpeg-2-8-12/tests/checkasm/checkasm.h
similarity index 100%
rename from ffmpeg-2-8-11/tests/checkasm/checkasm.h
rename to ffmpeg-2-8-12/tests/checkasm/checkasm.h
diff --git a/ffmpeg-2-8-11/tests/checkasm/h264pred.c b/ffmpeg-2-8-12/tests/checkasm/h264pred.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/checkasm/h264pred.c
rename to ffmpeg-2-8-12/tests/checkasm/h264pred.c
diff --git a/ffmpeg-2-8-11/tests/checkasm/h264qpel.c b/ffmpeg-2-8-12/tests/checkasm/h264qpel.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/checkasm/h264qpel.c
rename to ffmpeg-2-8-12/tests/checkasm/h264qpel.c
diff --git a/ffmpeg-2-8-11/tests/checkasm/x86/Makefile b/ffmpeg-2-8-12/tests/checkasm/x86/Makefile
similarity index 100%
rename from ffmpeg-2-8-11/tests/checkasm/x86/Makefile
rename to ffmpeg-2-8-12/tests/checkasm/x86/Makefile
diff --git a/ffmpeg-2-8-11/tests/checkasm/x86/checkasm.asm b/ffmpeg-2-8-12/tests/checkasm/x86/checkasm.asm
similarity index 100%
rename from ffmpeg-2-8-11/tests/checkasm/x86/checkasm.asm
rename to ffmpeg-2-8-12/tests/checkasm/x86/checkasm.asm
diff --git a/ffmpeg-2-8-11/tests/copycooker.sh b/ffmpeg-2-8-12/tests/copycooker.sh
similarity index 100%
rename from ffmpeg-2-8-11/tests/copycooker.sh
rename to ffmpeg-2-8-12/tests/copycooker.sh
diff --git a/ffmpeg-2-8-11/tests/fate-run.sh b/ffmpeg-2-8-12/tests/fate-run.sh
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate-run.sh
rename to ffmpeg-2-8-12/tests/fate-run.sh
diff --git a/ffmpeg-2-8-11/tests/fate-valgrind.supp b/ffmpeg-2-8-12/tests/fate-valgrind.supp
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate-valgrind.supp
rename to ffmpeg-2-8-12/tests/fate-valgrind.supp
diff --git a/ffmpeg-2-8-11/tests/fate.sh b/ffmpeg-2-8-12/tests/fate.sh
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate.sh
rename to ffmpeg-2-8-12/tests/fate.sh
diff --git a/ffmpeg-2-8-11/tests/fate/aac.mak b/ffmpeg-2-8-12/tests/fate/aac.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/aac.mak
rename to ffmpeg-2-8-12/tests/fate/aac.mak
diff --git a/ffmpeg-2-8-11/tests/fate/ac3.mak b/ffmpeg-2-8-12/tests/fate/ac3.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/ac3.mak
rename to ffmpeg-2-8-12/tests/fate/ac3.mak
diff --git a/ffmpeg-2-8-11/tests/fate/acodec.mak b/ffmpeg-2-8-12/tests/fate/acodec.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/acodec.mak
rename to ffmpeg-2-8-12/tests/fate/acodec.mak
diff --git a/ffmpeg-2-8-11/tests/fate/adpcm.mak b/ffmpeg-2-8-12/tests/fate/adpcm.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/adpcm.mak
rename to ffmpeg-2-8-12/tests/fate/adpcm.mak
diff --git a/ffmpeg-2-8-11/tests/fate/alac.mak b/ffmpeg-2-8-12/tests/fate/alac.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/alac.mak
rename to ffmpeg-2-8-12/tests/fate/alac.mak
diff --git a/ffmpeg-2-8-11/tests/fate/als.mak b/ffmpeg-2-8-12/tests/fate/als.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/als.mak
rename to ffmpeg-2-8-12/tests/fate/als.mak
diff --git a/ffmpeg-2-8-11/tests/fate/amrnb.mak b/ffmpeg-2-8-12/tests/fate/amrnb.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/amrnb.mak
rename to ffmpeg-2-8-12/tests/fate/amrnb.mak
diff --git a/ffmpeg-2-8-11/tests/fate/amrwb.mak b/ffmpeg-2-8-12/tests/fate/amrwb.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/amrwb.mak
rename to ffmpeg-2-8-12/tests/fate/amrwb.mak
diff --git a/ffmpeg-2-8-11/tests/fate/api.mak b/ffmpeg-2-8-12/tests/fate/api.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/api.mak
rename to ffmpeg-2-8-12/tests/fate/api.mak
diff --git a/ffmpeg-2-8-11/tests/fate/atrac.mak b/ffmpeg-2-8-12/tests/fate/atrac.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/atrac.mak
rename to ffmpeg-2-8-12/tests/fate/atrac.mak
diff --git a/ffmpeg-2-8-11/tests/fate/audio.mak b/ffmpeg-2-8-12/tests/fate/audio.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/audio.mak
rename to ffmpeg-2-8-12/tests/fate/audio.mak
diff --git a/ffmpeg-2-8-11/tests/fate/avformat.mak b/ffmpeg-2-8-12/tests/fate/avformat.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/avformat.mak
rename to ffmpeg-2-8-12/tests/fate/avformat.mak
diff --git a/ffmpeg-2-8-11/tests/fate/bmp.mak b/ffmpeg-2-8-12/tests/fate/bmp.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/bmp.mak
rename to ffmpeg-2-8-12/tests/fate/bmp.mak
diff --git a/ffmpeg-2-8-11/tests/fate/cdxl.mak b/ffmpeg-2-8-12/tests/fate/cdxl.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/cdxl.mak
rename to ffmpeg-2-8-12/tests/fate/cdxl.mak
diff --git a/ffmpeg-2-8-11/tests/fate/checkasm.mak b/ffmpeg-2-8-12/tests/fate/checkasm.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/checkasm.mak
rename to ffmpeg-2-8-12/tests/fate/checkasm.mak
diff --git a/ffmpeg-2-8-11/tests/fate/cover-art.mak b/ffmpeg-2-8-12/tests/fate/cover-art.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/cover-art.mak
rename to ffmpeg-2-8-12/tests/fate/cover-art.mak
diff --git a/ffmpeg-2-8-11/tests/fate/demux.mak b/ffmpeg-2-8-12/tests/fate/demux.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/demux.mak
rename to ffmpeg-2-8-12/tests/fate/demux.mak
diff --git a/ffmpeg-2-8-11/tests/fate/dfa.mak b/ffmpeg-2-8-12/tests/fate/dfa.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/dfa.mak
rename to ffmpeg-2-8-12/tests/fate/dfa.mak
diff --git a/ffmpeg-2-8-11/tests/fate/dpcm.mak b/ffmpeg-2-8-12/tests/fate/dpcm.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/dpcm.mak
rename to ffmpeg-2-8-12/tests/fate/dpcm.mak
diff --git a/ffmpeg-2-8-11/tests/fate/ea.mak b/ffmpeg-2-8-12/tests/fate/ea.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/ea.mak
rename to ffmpeg-2-8-12/tests/fate/ea.mak
diff --git a/ffmpeg-2-8-11/tests/fate/exif.mak b/ffmpeg-2-8-12/tests/fate/exif.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/exif.mak
rename to ffmpeg-2-8-12/tests/fate/exif.mak
diff --git a/ffmpeg-2-8-11/tests/fate/ffmpeg.mak b/ffmpeg-2-8-12/tests/fate/ffmpeg.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/ffmpeg.mak
rename to ffmpeg-2-8-12/tests/fate/ffmpeg.mak
diff --git a/ffmpeg-2-8-11/tests/fate/ffprobe.mak b/ffmpeg-2-8-12/tests/fate/ffprobe.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/ffprobe.mak
rename to ffmpeg-2-8-12/tests/fate/ffprobe.mak
diff --git a/ffmpeg-2-8-11/tests/fate/fft.mak b/ffmpeg-2-8-12/tests/fate/fft.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/fft.mak
rename to ffmpeg-2-8-12/tests/fate/fft.mak
diff --git a/ffmpeg-2-8-11/tests/fate/filter-audio.mak b/ffmpeg-2-8-12/tests/fate/filter-audio.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/filter-audio.mak
rename to ffmpeg-2-8-12/tests/fate/filter-audio.mak
diff --git a/ffmpeg-2-8-11/tests/fate/filter-video.mak b/ffmpeg-2-8-12/tests/fate/filter-video.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/filter-video.mak
rename to ffmpeg-2-8-12/tests/fate/filter-video.mak
diff --git a/ffmpeg-2-8-11/tests/fate/flac.mak b/ffmpeg-2-8-12/tests/fate/flac.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/flac.mak
rename to ffmpeg-2-8-12/tests/fate/flac.mak
diff --git a/ffmpeg-2-8-11/tests/fate/gapless.mak b/ffmpeg-2-8-12/tests/fate/gapless.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/gapless.mak
rename to ffmpeg-2-8-12/tests/fate/gapless.mak
diff --git a/ffmpeg-2-8-11/tests/fate/gif.mak b/ffmpeg-2-8-12/tests/fate/gif.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/gif.mak
rename to ffmpeg-2-8-12/tests/fate/gif.mak
diff --git a/ffmpeg-2-8-11/tests/fate/h264.mak b/ffmpeg-2-8-12/tests/fate/h264.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/h264.mak
rename to ffmpeg-2-8-12/tests/fate/h264.mak
diff --git a/ffmpeg-2-8-11/tests/fate/hevc.mak b/ffmpeg-2-8-12/tests/fate/hevc.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/hevc.mak
rename to ffmpeg-2-8-12/tests/fate/hevc.mak
diff --git a/ffmpeg-2-8-11/tests/fate/image.mak b/ffmpeg-2-8-12/tests/fate/image.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/image.mak
rename to ffmpeg-2-8-12/tests/fate/image.mak
diff --git a/ffmpeg-2-8-11/tests/fate/indeo.mak b/ffmpeg-2-8-12/tests/fate/indeo.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/indeo.mak
rename to ffmpeg-2-8-12/tests/fate/indeo.mak
diff --git a/ffmpeg-2-8-11/tests/fate/libavcodec.mak b/ffmpeg-2-8-12/tests/fate/libavcodec.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/libavcodec.mak
rename to ffmpeg-2-8-12/tests/fate/libavcodec.mak
diff --git a/ffmpeg-2-8-11/tests/fate/libavdevice.mak b/ffmpeg-2-8-12/tests/fate/libavdevice.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/libavdevice.mak
rename to ffmpeg-2-8-12/tests/fate/libavdevice.mak
diff --git a/ffmpeg-2-8-11/tests/fate/libavformat.mak b/ffmpeg-2-8-12/tests/fate/libavformat.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/libavformat.mak
rename to ffmpeg-2-8-12/tests/fate/libavformat.mak
diff --git a/ffmpeg-2-8-11/tests/fate/libavresample.mak b/ffmpeg-2-8-12/tests/fate/libavresample.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/libavresample.mak
rename to ffmpeg-2-8-12/tests/fate/libavresample.mak
diff --git a/ffmpeg-2-8-11/tests/fate/libavutil.mak b/ffmpeg-2-8-12/tests/fate/libavutil.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/libavutil.mak
rename to ffmpeg-2-8-12/tests/fate/libavutil.mak
diff --git a/ffmpeg-2-8-11/tests/fate/libswresample.mak b/ffmpeg-2-8-12/tests/fate/libswresample.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/libswresample.mak
rename to ffmpeg-2-8-12/tests/fate/libswresample.mak
diff --git a/ffmpeg-2-8-11/tests/fate/lossless-audio.mak b/ffmpeg-2-8-12/tests/fate/lossless-audio.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/lossless-audio.mak
rename to ffmpeg-2-8-12/tests/fate/lossless-audio.mak
diff --git a/ffmpeg-2-8-11/tests/fate/lossless-video.mak b/ffmpeg-2-8-12/tests/fate/lossless-video.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/lossless-video.mak
rename to ffmpeg-2-8-12/tests/fate/lossless-video.mak
diff --git a/ffmpeg-2-8-11/tests/fate/microsoft.mak b/ffmpeg-2-8-12/tests/fate/microsoft.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/microsoft.mak
rename to ffmpeg-2-8-12/tests/fate/microsoft.mak
diff --git a/ffmpeg-2-8-11/tests/fate/monkeysaudio.mak b/ffmpeg-2-8-12/tests/fate/monkeysaudio.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/monkeysaudio.mak
rename to ffmpeg-2-8-12/tests/fate/monkeysaudio.mak
diff --git a/ffmpeg-2-8-11/tests/fate/mp3.mak b/ffmpeg-2-8-12/tests/fate/mp3.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/mp3.mak
rename to ffmpeg-2-8-12/tests/fate/mp3.mak
diff --git a/ffmpeg-2-8-11/tests/fate/mpc.mak b/ffmpeg-2-8-12/tests/fate/mpc.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/mpc.mak
rename to ffmpeg-2-8-12/tests/fate/mpc.mak
diff --git a/ffmpeg-2-8-11/tests/fate/mpeg4.mak b/ffmpeg-2-8-12/tests/fate/mpeg4.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/mpeg4.mak
rename to ffmpeg-2-8-12/tests/fate/mpeg4.mak
diff --git a/ffmpeg-2-8-11/tests/fate/mxf.mak b/ffmpeg-2-8-12/tests/fate/mxf.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/mxf.mak
rename to ffmpeg-2-8-12/tests/fate/mxf.mak
diff --git a/ffmpeg-2-8-11/tests/fate/opus.mak b/ffmpeg-2-8-12/tests/fate/opus.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/opus.mak
rename to ffmpeg-2-8-12/tests/fate/opus.mak
diff --git a/ffmpeg-2-8-11/tests/fate/pcm.mak b/ffmpeg-2-8-12/tests/fate/pcm.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/pcm.mak
rename to ffmpeg-2-8-12/tests/fate/pcm.mak
diff --git a/ffmpeg-2-8-11/tests/fate/probe.mak b/ffmpeg-2-8-12/tests/fate/probe.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/probe.mak
rename to ffmpeg-2-8-12/tests/fate/probe.mak
diff --git a/ffmpeg-2-8-11/tests/fate/prores.mak b/ffmpeg-2-8-12/tests/fate/prores.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/prores.mak
rename to ffmpeg-2-8-12/tests/fate/prores.mak
diff --git a/ffmpeg-2-8-11/tests/fate/qt.mak b/ffmpeg-2-8-12/tests/fate/qt.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/qt.mak
rename to ffmpeg-2-8-12/tests/fate/qt.mak
diff --git a/ffmpeg-2-8-11/tests/fate/qtrle.mak b/ffmpeg-2-8-12/tests/fate/qtrle.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/qtrle.mak
rename to ffmpeg-2-8-12/tests/fate/qtrle.mak
diff --git a/ffmpeg-2-8-11/tests/fate/real.mak b/ffmpeg-2-8-12/tests/fate/real.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/real.mak
rename to ffmpeg-2-8-12/tests/fate/real.mak
diff --git a/ffmpeg-2-8-11/tests/fate/screen.mak b/ffmpeg-2-8-12/tests/fate/screen.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/screen.mak
rename to ffmpeg-2-8-12/tests/fate/screen.mak
diff --git a/ffmpeg-2-8-11/tests/fate/seek.mak b/ffmpeg-2-8-12/tests/fate/seek.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/seek.mak
rename to ffmpeg-2-8-12/tests/fate/seek.mak
diff --git a/ffmpeg-2-8-11/tests/fate/subtitles.mak b/ffmpeg-2-8-12/tests/fate/subtitles.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/subtitles.mak
rename to ffmpeg-2-8-12/tests/fate/subtitles.mak
diff --git a/ffmpeg-2-8-11/tests/fate/utvideo.mak b/ffmpeg-2-8-12/tests/fate/utvideo.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/utvideo.mak
rename to ffmpeg-2-8-12/tests/fate/utvideo.mak
diff --git a/ffmpeg-2-8-11/tests/fate/vcodec.mak b/ffmpeg-2-8-12/tests/fate/vcodec.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/vcodec.mak
rename to ffmpeg-2-8-12/tests/fate/vcodec.mak
diff --git a/ffmpeg-2-8-11/tests/fate/video.mak b/ffmpeg-2-8-12/tests/fate/video.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/video.mak
rename to ffmpeg-2-8-12/tests/fate/video.mak
diff --git a/ffmpeg-2-8-11/tests/fate/voice.mak b/ffmpeg-2-8-12/tests/fate/voice.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/voice.mak
rename to ffmpeg-2-8-12/tests/fate/voice.mak
diff --git a/ffmpeg-2-8-11/tests/fate/vorbis.mak b/ffmpeg-2-8-12/tests/fate/vorbis.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/vorbis.mak
rename to ffmpeg-2-8-12/tests/fate/vorbis.mak
diff --git a/ffmpeg-2-8-11/tests/fate/vpx.mak b/ffmpeg-2-8-12/tests/fate/vpx.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/vpx.mak
rename to ffmpeg-2-8-12/tests/fate/vpx.mak
diff --git a/ffmpeg-2-8-11/tests/fate/vqf.mak b/ffmpeg-2-8-12/tests/fate/vqf.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/vqf.mak
rename to ffmpeg-2-8-12/tests/fate/vqf.mak
diff --git a/ffmpeg-2-8-11/tests/fate/wavpack.mak b/ffmpeg-2-8-12/tests/fate/wavpack.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/wavpack.mak
rename to ffmpeg-2-8-12/tests/fate/wavpack.mak
diff --git a/ffmpeg-2-8-11/tests/fate/wma.mak b/ffmpeg-2-8-12/tests/fate/wma.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/wma.mak
rename to ffmpeg-2-8-12/tests/fate/wma.mak
diff --git a/ffmpeg-2-8-11/tests/fate/xvid.mak b/ffmpeg-2-8-12/tests/fate/xvid.mak
similarity index 100%
rename from ffmpeg-2-8-11/tests/fate/xvid.mak
rename to ffmpeg-2-8-12/tests/fate/xvid.mak
diff --git a/ffmpeg-2-8-11/tests/ffserver-regression.sh b/ffmpeg-2-8-12/tests/ffserver-regression.sh
similarity index 100%
rename from ffmpeg-2-8-11/tests/ffserver-regression.sh
rename to ffmpeg-2-8-12/tests/ffserver-regression.sh
diff --git a/ffmpeg-2-8-11/tests/ffserver.conf b/ffmpeg-2-8-12/tests/ffserver.conf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ffserver.conf
rename to ffmpeg-2-8-12/tests/ffserver.conf
diff --git a/ffmpeg-2-8-11/tests/ffserver.regression.ref b/ffmpeg-2-8-12/tests/ffserver.regression.ref
similarity index 100%
rename from ffmpeg-2-8-11/tests/ffserver.regression.ref
rename to ffmpeg-2-8-12/tests/ffserver.regression.ref
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/alphamerge_alphaextract_rgb b/ffmpeg-2-8-12/tests/filtergraphs/alphamerge_alphaextract_rgb
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/alphamerge_alphaextract_rgb
rename to ffmpeg-2-8-12/tests/filtergraphs/alphamerge_alphaextract_rgb
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/alphamerge_alphaextract_yuv b/ffmpeg-2-8-12/tests/filtergraphs/alphamerge_alphaextract_yuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/alphamerge_alphaextract_yuv
rename to ffmpeg-2-8-12/tests/filtergraphs/alphamerge_alphaextract_yuv
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/channelmap_one_int b/ffmpeg-2-8-12/tests/filtergraphs/channelmap_one_int
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/channelmap_one_int
rename to ffmpeg-2-8-12/tests/filtergraphs/channelmap_one_int
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/channelmap_one_str b/ffmpeg-2-8-12/tests/filtergraphs/channelmap_one_str
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/channelmap_one_str
rename to ffmpeg-2-8-12/tests/filtergraphs/channelmap_one_str
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/concat b/ffmpeg-2-8-12/tests/filtergraphs/concat
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/concat
rename to ffmpeg-2-8-12/tests/filtergraphs/concat
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/gradfun b/ffmpeg-2-8-12/tests/filtergraphs/gradfun
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/gradfun
rename to ffmpeg-2-8-12/tests/filtergraphs/gradfun
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/hqdn3d b/ffmpeg-2-8-12/tests/filtergraphs/hqdn3d
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/hqdn3d
rename to ffmpeg-2-8-12/tests/filtergraphs/hqdn3d
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/lavr_mix_output_zero b/ffmpeg-2-8-12/tests/filtergraphs/lavr_mix_output_zero
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/lavr_mix_output_zero
rename to ffmpeg-2-8-12/tests/filtergraphs/lavr_mix_output_zero
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/mergeplanes b/ffmpeg-2-8-12/tests/filtergraphs/mergeplanes
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/mergeplanes
rename to ffmpeg-2-8-12/tests/filtergraphs/mergeplanes
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/overlay b/ffmpeg-2-8-12/tests/filtergraphs/overlay
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/overlay
rename to ffmpeg-2-8-12/tests/filtergraphs/overlay
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/overlay_rgb b/ffmpeg-2-8-12/tests/filtergraphs/overlay_rgb
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/overlay_rgb
rename to ffmpeg-2-8-12/tests/filtergraphs/overlay_rgb
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/overlay_yuv420 b/ffmpeg-2-8-12/tests/filtergraphs/overlay_yuv420
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/overlay_yuv420
rename to ffmpeg-2-8-12/tests/filtergraphs/overlay_yuv420
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/overlay_yuv422 b/ffmpeg-2-8-12/tests/filtergraphs/overlay_yuv422
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/overlay_yuv422
rename to ffmpeg-2-8-12/tests/filtergraphs/overlay_yuv422
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/overlay_yuv444 b/ffmpeg-2-8-12/tests/filtergraphs/overlay_yuv444
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/overlay_yuv444
rename to ffmpeg-2-8-12/tests/filtergraphs/overlay_yuv444
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/scalenorm b/ffmpeg-2-8-12/tests/filtergraphs/scalenorm
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/scalenorm
rename to ffmpeg-2-8-12/tests/filtergraphs/scalenorm
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/select-alternate b/ffmpeg-2-8-12/tests/filtergraphs/select-alternate
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/select-alternate
rename to ffmpeg-2-8-12/tests/filtergraphs/select-alternate
diff --git a/ffmpeg-2-8-11/tests/filtergraphs/setpts b/ffmpeg-2-8-12/tests/filtergraphs/setpts
similarity index 100%
rename from ffmpeg-2-8-11/tests/filtergraphs/setpts
rename to ffmpeg-2-8-12/tests/filtergraphs/setpts
diff --git a/ffmpeg-2-8-11/tests/lavf-regression.sh b/ffmpeg-2-8-12/tests/lavf-regression.sh
similarity index 100%
rename from ffmpeg-2-8-11/tests/lavf-regression.sh
rename to ffmpeg-2-8-12/tests/lavf-regression.sh
diff --git a/ffmpeg-2-8-11/tests/md5.sh b/ffmpeg-2-8-12/tests/md5.sh
similarity index 100%
rename from ffmpeg-2-8-11/tests/md5.sh
rename to ffmpeg-2-8-12/tests/md5.sh
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/adpcm-adx b/ffmpeg-2-8-12/tests/ref/acodec/adpcm-adx
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/adpcm-adx
rename to ffmpeg-2-8-12/tests/ref/acodec/adpcm-adx
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/adpcm-adx-trellis b/ffmpeg-2-8-12/tests/ref/acodec/adpcm-adx-trellis
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/adpcm-adx-trellis
rename to ffmpeg-2-8-12/tests/ref/acodec/adpcm-adx-trellis
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/adpcm-ima_qt b/ffmpeg-2-8-12/tests/ref/acodec/adpcm-ima_qt
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/adpcm-ima_qt
rename to ffmpeg-2-8-12/tests/ref/acodec/adpcm-ima_qt
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/adpcm-ima_qt-trellis b/ffmpeg-2-8-12/tests/ref/acodec/adpcm-ima_qt-trellis
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/adpcm-ima_qt-trellis
rename to ffmpeg-2-8-12/tests/ref/acodec/adpcm-ima_qt-trellis
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/adpcm-ima_wav b/ffmpeg-2-8-12/tests/ref/acodec/adpcm-ima_wav
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/adpcm-ima_wav
rename to ffmpeg-2-8-12/tests/ref/acodec/adpcm-ima_wav
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/adpcm-ima_wav-trellis b/ffmpeg-2-8-12/tests/ref/acodec/adpcm-ima_wav-trellis
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/adpcm-ima_wav-trellis
rename to ffmpeg-2-8-12/tests/ref/acodec/adpcm-ima_wav-trellis
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/adpcm-ms b/ffmpeg-2-8-12/tests/ref/acodec/adpcm-ms
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/adpcm-ms
rename to ffmpeg-2-8-12/tests/ref/acodec/adpcm-ms
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/adpcm-ms-trellis b/ffmpeg-2-8-12/tests/ref/acodec/adpcm-ms-trellis
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/adpcm-ms-trellis
rename to ffmpeg-2-8-12/tests/ref/acodec/adpcm-ms-trellis
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/adpcm-swf b/ffmpeg-2-8-12/tests/ref/acodec/adpcm-swf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/adpcm-swf
rename to ffmpeg-2-8-12/tests/ref/acodec/adpcm-swf
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/adpcm-swf-trellis b/ffmpeg-2-8-12/tests/ref/acodec/adpcm-swf-trellis
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/adpcm-swf-trellis
rename to ffmpeg-2-8-12/tests/ref/acodec/adpcm-swf-trellis
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/adpcm-yamaha b/ffmpeg-2-8-12/tests/ref/acodec/adpcm-yamaha
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/adpcm-yamaha
rename to ffmpeg-2-8-12/tests/ref/acodec/adpcm-yamaha
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/adpcm-yamaha-trellis b/ffmpeg-2-8-12/tests/ref/acodec/adpcm-yamaha-trellis
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/adpcm-yamaha-trellis
rename to ffmpeg-2-8-12/tests/ref/acodec/adpcm-yamaha-trellis
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/adpcm_ima_qt b/ffmpeg-2-8-12/tests/ref/acodec/adpcm_ima_qt
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/adpcm_ima_qt
rename to ffmpeg-2-8-12/tests/ref/acodec/adpcm_ima_qt
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/alac b/ffmpeg-2-8-12/tests/ref/acodec/alac
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/alac
rename to ffmpeg-2-8-12/tests/ref/acodec/alac
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/flac b/ffmpeg-2-8-12/tests/ref/acodec/flac
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/flac
rename to ffmpeg-2-8-12/tests/ref/acodec/flac
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/flac-exact-rice b/ffmpeg-2-8-12/tests/ref/acodec/flac-exact-rice
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/flac-exact-rice
rename to ffmpeg-2-8-12/tests/ref/acodec/flac-exact-rice
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/g723_1 b/ffmpeg-2-8-12/tests/ref/acodec/g723_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/g723_1
rename to ffmpeg-2-8-12/tests/ref/acodec/g723_1
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/mp2 b/ffmpeg-2-8-12/tests/ref/acodec/mp2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/mp2
rename to ffmpeg-2-8-12/tests/ref/acodec/mp2
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/mp2fixed b/ffmpeg-2-8-12/tests/ref/acodec/mp2fixed
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/mp2fixed
rename to ffmpeg-2-8-12/tests/ref/acodec/mp2fixed
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-alaw b/ffmpeg-2-8-12/tests/ref/acodec/pcm-alaw
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-alaw
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-alaw
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-f32be b/ffmpeg-2-8-12/tests/ref/acodec/pcm-f32be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-f32be
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-f32be
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-f32le b/ffmpeg-2-8-12/tests/ref/acodec/pcm-f32le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-f32le
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-f32le
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-f64be b/ffmpeg-2-8-12/tests/ref/acodec/pcm-f64be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-f64be
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-f64be
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-f64le b/ffmpeg-2-8-12/tests/ref/acodec/pcm-f64le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-f64le
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-f64le
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-mulaw b/ffmpeg-2-8-12/tests/ref/acodec/pcm-mulaw
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-mulaw
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-mulaw
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-s16be b/ffmpeg-2-8-12/tests/ref/acodec/pcm-s16be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-s16be
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-s16be
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-s16be_planar b/ffmpeg-2-8-12/tests/ref/acodec/pcm-s16be_planar
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-s16be_planar
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-s16be_planar
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-s16le b/ffmpeg-2-8-12/tests/ref/acodec/pcm-s16le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-s16le
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-s16le
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-s16le_planar b/ffmpeg-2-8-12/tests/ref/acodec/pcm-s16le_planar
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-s16le_planar
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-s16le_planar
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-s24be b/ffmpeg-2-8-12/tests/ref/acodec/pcm-s24be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-s24be
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-s24be
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-s24le b/ffmpeg-2-8-12/tests/ref/acodec/pcm-s24le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-s24le
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-s24le
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-s24le_planar b/ffmpeg-2-8-12/tests/ref/acodec/pcm-s24le_planar
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-s24le_planar
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-s24le_planar
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-s32be b/ffmpeg-2-8-12/tests/ref/acodec/pcm-s32be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-s32be
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-s32be
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-s32le b/ffmpeg-2-8-12/tests/ref/acodec/pcm-s32le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-s32le
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-s32le
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-s32le_planar b/ffmpeg-2-8-12/tests/ref/acodec/pcm-s32le_planar
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-s32le_planar
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-s32le_planar
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-s8 b/ffmpeg-2-8-12/tests/ref/acodec/pcm-s8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-s8
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-s8
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-s8_planar b/ffmpeg-2-8-12/tests/ref/acodec/pcm-s8_planar
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-s8_planar
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-s8_planar
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-u16be b/ffmpeg-2-8-12/tests/ref/acodec/pcm-u16be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-u16be
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-u16be
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-u16le b/ffmpeg-2-8-12/tests/ref/acodec/pcm-u16le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-u16le
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-u16le
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-u24be b/ffmpeg-2-8-12/tests/ref/acodec/pcm-u24be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-u24be
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-u24be
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-u24le b/ffmpeg-2-8-12/tests/ref/acodec/pcm-u24le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-u24le
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-u24le
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-u32be b/ffmpeg-2-8-12/tests/ref/acodec/pcm-u32be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-u32be
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-u32be
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-u32le b/ffmpeg-2-8-12/tests/ref/acodec/pcm-u32le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-u32le
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-u32le
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/pcm-u8 b/ffmpeg-2-8-12/tests/ref/acodec/pcm-u8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/pcm-u8
rename to ffmpeg-2-8-12/tests/ref/acodec/pcm-u8
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/roqaudio b/ffmpeg-2-8-12/tests/ref/acodec/roqaudio
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/roqaudio
rename to ffmpeg-2-8-12/tests/ref/acodec/roqaudio
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/s302m b/ffmpeg-2-8-12/tests/ref/acodec/s302m
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/s302m
rename to ffmpeg-2-8-12/tests/ref/acodec/s302m
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/tta b/ffmpeg-2-8-12/tests/ref/acodec/tta
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/tta
rename to ffmpeg-2-8-12/tests/ref/acodec/tta
diff --git a/ffmpeg-2-8-11/tests/ref/acodec/wavpack b/ffmpeg-2-8-12/tests/ref/acodec/wavpack
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/acodec/wavpack
rename to ffmpeg-2-8-12/tests/ref/acodec/wavpack
diff --git a/ffmpeg-2-8-11/tests/ref/fate/4xm-1 b/ffmpeg-2-8-12/tests/ref/fate/4xm-1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/4xm-1
rename to ffmpeg-2-8-12/tests/ref/fate/4xm-1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/4xm-2 b/ffmpeg-2-8-12/tests/ref/fate/4xm-2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/4xm-2
rename to ffmpeg-2-8-12/tests/ref/fate/4xm-2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/8bps b/ffmpeg-2-8-12/tests/ref/fate/8bps
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/8bps
rename to ffmpeg-2-8-12/tests/ref/fate/8bps
diff --git a/ffmpeg-2-8-11/tests/ref/fate/aasc b/ffmpeg-2-8-12/tests/ref/fate/aasc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/aasc
rename to ffmpeg-2-8-12/tests/ref/fate/aasc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/acodec-aref b/ffmpeg-2-8-12/tests/ref/fate/acodec-aref
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/acodec-aref
rename to ffmpeg-2-8-12/tests/ref/fate/acodec-aref
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-4xm b/ffmpeg-2-8-12/tests/ref/fate/adpcm-4xm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-4xm
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-4xm
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-afc b/ffmpeg-2-8-12/tests/ref/fate/adpcm-afc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-afc
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-afc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-creative b/ffmpeg-2-8-12/tests/ref/fate/adpcm-creative
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-creative
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-creative
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-creative-8-2.6bit b/ffmpeg-2-8-12/tests/ref/fate/adpcm-creative-8-2.6bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-creative-8-2.6bit
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-creative-8-2.6bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-creative-8-2bit b/ffmpeg-2-8-12/tests/ref/fate/adpcm-creative-8-2bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-creative-8-2bit
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-creative-8-2bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-creative-8-4bit b/ffmpeg-2-8-12/tests/ref/fate/adpcm-creative-8-4bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-creative-8-4bit
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-creative-8-4bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-dtk b/ffmpeg-2-8-12/tests/ref/fate/adpcm-dtk
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-dtk
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-dtk
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ea-1 b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ea-1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ea-1
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ea-1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ea-2 b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ea-2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ea-2
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ea-2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ea-maxis-xa b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ea-maxis-xa
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ea-maxis-xa
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ea-maxis-xa
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ea-r1 b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ea-r1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ea-r1
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ea-r1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ea-r2 b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ea-r2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ea-r2
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ea-r2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ea-r3 b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ea-r3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ea-r3
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ea-r3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-amv b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-amv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-amv
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-amv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-apc b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-apc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-apc
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-apc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-dk3 b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-dk3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-dk3
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-dk3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-dk4 b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-dk4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-dk4
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-dk4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-ea-eacs b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-ea-eacs
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-ea-eacs
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-ea-eacs
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-ea-sead b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-ea-sead
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-ea-sead
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-ea-sead
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-iss b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-iss
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-iss
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-iss
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-oki b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-oki
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-oki
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-oki
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-rad b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-rad
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-rad
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-rad
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-smjpeg b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-smjpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-smjpeg
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-smjpeg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-ws b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-ws
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ima-ws
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ima-ws
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ima_wav-stereo b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ima_wav-stereo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ima_wav-stereo
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ima_wav-stereo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-ms-mono b/ffmpeg-2-8-12/tests/ref/fate/adpcm-ms-mono
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-ms-mono
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-ms-mono
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-thp b/ffmpeg-2-8-12/tests/ref/fate/adpcm-thp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-thp
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-thp
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-vima b/ffmpeg-2-8-12/tests/ref/fate/adpcm-vima
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-vima
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-vima
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm-xa b/ffmpeg-2-8-12/tests/ref/fate/adpcm-xa
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm-xa
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm-xa
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adpcm_ms-stereo b/ffmpeg-2-8-12/tests/ref/fate/adpcm_ms-stereo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adpcm_ms-stereo
rename to ffmpeg-2-8-12/tests/ref/fate/adpcm_ms-stereo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/adts-demux b/ffmpeg-2-8-12/tests/ref/fate/adts-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/adts-demux
rename to ffmpeg-2-8-12/tests/ref/fate/adts-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/aea-demux b/ffmpeg-2-8-12/tests/ref/fate/aea-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/aea-demux
rename to ffmpeg-2-8-12/tests/ref/fate/aea-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/aic b/ffmpeg-2-8-12/tests/ref/fate/aic
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/aic
rename to ffmpeg-2-8-12/tests/ref/fate/aic
diff --git a/ffmpeg-2-8-11/tests/ref/fate/aic-oddsize b/ffmpeg-2-8-12/tests/ref/fate/aic-oddsize
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/aic-oddsize
rename to ffmpeg-2-8-12/tests/ref/fate/aic-oddsize
diff --git a/ffmpeg-2-8-11/tests/ref/fate/alg-mm b/ffmpeg-2-8-12/tests/ref/fate/alg-mm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/alg-mm
rename to ffmpeg-2-8-12/tests/ref/fate/alg-mm
diff --git a/ffmpeg-2-8-11/tests/ref/fate/aliaspix-bgr b/ffmpeg-2-8-12/tests/ref/fate/aliaspix-bgr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/aliaspix-bgr
rename to ffmpeg-2-8-12/tests/ref/fate/aliaspix-bgr
diff --git a/ffmpeg-2-8-11/tests/ref/fate/aliaspix-gray b/ffmpeg-2-8-12/tests/ref/fate/aliaspix-gray
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/aliaspix-gray
rename to ffmpeg-2-8-12/tests/ref/fate/aliaspix-gray
diff --git a/ffmpeg-2-8-11/tests/ref/fate/amv b/ffmpeg-2-8-12/tests/ref/fate/amv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/amv
rename to ffmpeg-2-8-12/tests/ref/fate/amv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ansi b/ffmpeg-2-8-12/tests/ref/fate/ansi
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ansi
rename to ffmpeg-2-8-12/tests/ref/fate/ansi
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ansi256 b/ffmpeg-2-8-12/tests/ref/fate/ansi256
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ansi256
rename to ffmpeg-2-8-12/tests/ref/fate/ansi256
diff --git a/ffmpeg-2-8-11/tests/ref/fate/api-h264 b/ffmpeg-2-8-12/tests/ref/fate/api-h264
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/api-h264
rename to ffmpeg-2-8-12/tests/ref/fate/api-h264
diff --git a/ffmpeg-2-8-11/tests/ref/fate/armovie-escape124 b/ffmpeg-2-8-12/tests/ref/fate/armovie-escape124
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/armovie-escape124
rename to ffmpeg-2-8-12/tests/ref/fate/armovie-escape124
diff --git a/ffmpeg-2-8-11/tests/ref/fate/armovie-escape130 b/ffmpeg-2-8-12/tests/ref/fate/armovie-escape130
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/armovie-escape130
rename to ffmpeg-2-8-12/tests/ref/fate/armovie-escape130
diff --git a/ffmpeg-2-8-11/tests/ref/fate/asf-repldata b/ffmpeg-2-8-12/tests/ref/fate/asf-repldata
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/asf-repldata
rename to ffmpeg-2-8-12/tests/ref/fate/asf-repldata
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ast b/ffmpeg-2-8-12/tests/ref/fate/ast
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ast
rename to ffmpeg-2-8-12/tests/ref/fate/ast
diff --git a/ffmpeg-2-8-11/tests/ref/fate/async b/ffmpeg-2-8-12/tests/ref/fate/async
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/async
rename to ffmpeg-2-8-12/tests/ref/fate/async
diff --git a/ffmpeg-2-8-11/tests/ref/fate/auravision-v1 b/ffmpeg-2-8-12/tests/ref/fate/auravision-v1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/auravision-v1
rename to ffmpeg-2-8-12/tests/ref/fate/auravision-v1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/auravision-v2 b/ffmpeg-2-8-12/tests/ref/fate/auravision-v2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/auravision-v2
rename to ffmpeg-2-8-12/tests/ref/fate/auravision-v2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/avio-direct b/ffmpeg-2-8-12/tests/ref/fate/avio-direct
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/avio-direct
rename to ffmpeg-2-8-12/tests/ref/fate/avio-direct
diff --git a/ffmpeg-2-8-11/tests/ref/fate/avstring b/ffmpeg-2-8-12/tests/ref/fate/avstring
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/avstring
rename to ffmpeg-2-8-12/tests/ref/fate/avstring
diff --git a/ffmpeg-2-8-11/tests/ref/fate/base64 b/ffmpeg-2-8-12/tests/ref/fate/base64
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/base64
rename to ffmpeg-2-8-12/tests/ref/fate/base64
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bcstm b/ffmpeg-2-8-12/tests/ref/fate/bcstm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bcstm
rename to ffmpeg-2-8-12/tests/ref/fate/bcstm
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bethsoft-vid b/ffmpeg-2-8-12/tests/ref/fate/bethsoft-vid
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bethsoft-vid
rename to ffmpeg-2-8-12/tests/ref/fate/bethsoft-vid
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bfi b/ffmpeg-2-8-12/tests/ref/fate/bfi
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bfi
rename to ffmpeg-2-8-12/tests/ref/fate/bfi
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bfstm b/ffmpeg-2-8-12/tests/ref/fate/bfstm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bfstm
rename to ffmpeg-2-8-12/tests/ref/fate/bfstm
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bink-demux b/ffmpeg-2-8-12/tests/ref/fate/bink-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bink-demux
rename to ffmpeg-2-8-12/tests/ref/fate/bink-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bink-video-b b/ffmpeg-2-8-12/tests/ref/fate/bink-video-b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bink-video-b
rename to ffmpeg-2-8-12/tests/ref/fate/bink-video-b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bink-video-f b/ffmpeg-2-8-12/tests/ref/fate/bink-video-f
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bink-video-f
rename to ffmpeg-2-8-12/tests/ref/fate/bink-video-f
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bink-video-i b/ffmpeg-2-8-12/tests/ref/fate/bink-video-i
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bink-video-i
rename to ffmpeg-2-8-12/tests/ref/fate/bink-video-i
diff --git a/ffmpeg-2-8-11/tests/ref/fate/binsub-mksenc b/ffmpeg-2-8-12/tests/ref/fate/binsub-mksenc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/binsub-mksenc
rename to ffmpeg-2-8-12/tests/ref/fate/binsub-mksenc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/binsub-movtextenc b/ffmpeg-2-8-12/tests/ref/fate/binsub-movtextenc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/binsub-movtextenc
rename to ffmpeg-2-8-12/tests/ref/fate/binsub-movtextenc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/blowfish b/ffmpeg-2-8-12/tests/ref/fate/blowfish
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/blowfish
rename to ffmpeg-2-8-12/tests/ref/fate/blowfish
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmp-15bit b/ffmpeg-2-8-12/tests/ref/fate/bmp-15bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmp-15bit
rename to ffmpeg-2-8-12/tests/ref/fate/bmp-15bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmp-15bit-mask b/ffmpeg-2-8-12/tests/ref/fate/bmp-15bit-mask
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmp-15bit-mask
rename to ffmpeg-2-8-12/tests/ref/fate/bmp-15bit-mask
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmp-16bit-mask b/ffmpeg-2-8-12/tests/ref/fate/bmp-16bit-mask
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmp-16bit-mask
rename to ffmpeg-2-8-12/tests/ref/fate/bmp-16bit-mask
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmp-1bit b/ffmpeg-2-8-12/tests/ref/fate/bmp-1bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmp-1bit
rename to ffmpeg-2-8-12/tests/ref/fate/bmp-1bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmp-24bit b/ffmpeg-2-8-12/tests/ref/fate/bmp-24bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmp-24bit
rename to ffmpeg-2-8-12/tests/ref/fate/bmp-24bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmp-32bit b/ffmpeg-2-8-12/tests/ref/fate/bmp-32bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmp-32bit
rename to ffmpeg-2-8-12/tests/ref/fate/bmp-32bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmp-32bit-mask b/ffmpeg-2-8-12/tests/ref/fate/bmp-32bit-mask
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmp-32bit-mask
rename to ffmpeg-2-8-12/tests/ref/fate/bmp-32bit-mask
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmp-4bit b/ffmpeg-2-8-12/tests/ref/fate/bmp-4bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmp-4bit
rename to ffmpeg-2-8-12/tests/ref/fate/bmp-4bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmp-4bit-os2 b/ffmpeg-2-8-12/tests/ref/fate/bmp-4bit-os2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmp-4bit-os2
rename to ffmpeg-2-8-12/tests/ref/fate/bmp-4bit-os2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmp-8bit b/ffmpeg-2-8-12/tests/ref/fate/bmp-8bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmp-8bit
rename to ffmpeg-2-8-12/tests/ref/fate/bmp-8bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmp-8bit-os2 b/ffmpeg-2-8-12/tests/ref/fate/bmp-8bit-os2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmp-8bit-os2
rename to ffmpeg-2-8-12/tests/ref/fate/bmp-8bit-os2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmp-rle4 b/ffmpeg-2-8-12/tests/ref/fate/bmp-rle4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmp-rle4
rename to ffmpeg-2-8-12/tests/ref/fate/bmp-rle4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmp-rle8 b/ffmpeg-2-8-12/tests/ref/fate/bmp-rle8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmp-rle8
rename to ffmpeg-2-8-12/tests/ref/fate/bmp-rle8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmpparser b/ffmpeg-2-8-12/tests/ref/fate/bmpparser
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmpparser
rename to ffmpeg-2-8-12/tests/ref/fate/bmpparser
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmv-audio b/ffmpeg-2-8-12/tests/ref/fate/bmv-audio
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmv-audio
rename to ffmpeg-2-8-12/tests/ref/fate/bmv-audio
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bmv-video b/ffmpeg-2-8-12/tests/ref/fate/bmv-video
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bmv-video
rename to ffmpeg-2-8-12/tests/ref/fate/bmv-video
diff --git a/ffmpeg-2-8-11/tests/ref/fate/bprint b/ffmpeg-2-8-12/tests/ref/fate/bprint
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/bprint
rename to ffmpeg-2-8-12/tests/ref/fate/bprint
diff --git a/ffmpeg-2-8-11/tests/ref/fate/brenderpix-24 b/ffmpeg-2-8-12/tests/ref/fate/brenderpix-24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/brenderpix-24
rename to ffmpeg-2-8-12/tests/ref/fate/brenderpix-24
diff --git a/ffmpeg-2-8-11/tests/ref/fate/brenderpix-565 b/ffmpeg-2-8-12/tests/ref/fate/brenderpix-565
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/brenderpix-565
rename to ffmpeg-2-8-12/tests/ref/fate/brenderpix-565
diff --git a/ffmpeg-2-8-11/tests/ref/fate/brenderpix-defpal b/ffmpeg-2-8-12/tests/ref/fate/brenderpix-defpal
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/brenderpix-defpal
rename to ffmpeg-2-8-12/tests/ref/fate/brenderpix-defpal
diff --git a/ffmpeg-2-8-11/tests/ref/fate/brenderpix-intpal b/ffmpeg-2-8-12/tests/ref/fate/brenderpix-intpal
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/brenderpix-intpal
rename to ffmpeg-2-8-12/tests/ref/fate/brenderpix-intpal
diff --git a/ffmpeg-2-8-11/tests/ref/fate/brenderpix-y400a b/ffmpeg-2-8-12/tests/ref/fate/brenderpix-y400a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/brenderpix-y400a
rename to ffmpeg-2-8-12/tests/ref/fate/brenderpix-y400a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/brstm b/ffmpeg-2-8-12/tests/ref/fate/brstm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/brstm
rename to ffmpeg-2-8-12/tests/ref/fate/brstm
diff --git a/ffmpeg-2-8-11/tests/ref/fate/caf b/ffmpeg-2-8-12/tests/ref/fate/caf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/caf
rename to ffmpeg-2-8-12/tests/ref/fate/caf
diff --git a/ffmpeg-2-8-11/tests/ref/fate/canopus-cllc-argb b/ffmpeg-2-8-12/tests/ref/fate/canopus-cllc-argb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/canopus-cllc-argb
rename to ffmpeg-2-8-12/tests/ref/fate/canopus-cllc-argb
diff --git a/ffmpeg-2-8-11/tests/ref/fate/canopus-cllc-rgb b/ffmpeg-2-8-12/tests/ref/fate/canopus-cllc-rgb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/canopus-cllc-rgb
rename to ffmpeg-2-8-12/tests/ref/fate/canopus-cllc-rgb
diff --git a/ffmpeg-2-8-11/tests/ref/fate/canopus-cllc-yuy2-noblock b/ffmpeg-2-8-12/tests/ref/fate/canopus-cllc-yuy2-noblock
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/canopus-cllc-yuy2-noblock
rename to ffmpeg-2-8-12/tests/ref/fate/canopus-cllc-yuy2-noblock
diff --git a/ffmpeg-2-8-11/tests/ref/fate/canopus-hq_hqa-hq b/ffmpeg-2-8-12/tests/ref/fate/canopus-hq_hqa-hq
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/canopus-hq_hqa-hq
rename to ffmpeg-2-8-12/tests/ref/fate/canopus-hq_hqa-hq
diff --git a/ffmpeg-2-8-11/tests/ref/fate/canopus-hq_hqa-hqa b/ffmpeg-2-8-12/tests/ref/fate/canopus-hq_hqa-hqa
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/canopus-hq_hqa-hqa
rename to ffmpeg-2-8-12/tests/ref/fate/canopus-hq_hqa-hqa
diff --git a/ffmpeg-2-8-11/tests/ref/fate/canopus-hq_hqa-inter b/ffmpeg-2-8-12/tests/ref/fate/canopus-hq_hqa-inter
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/canopus-hq_hqa-inter
rename to ffmpeg-2-8-12/tests/ref/fate/canopus-hq_hqa-inter
diff --git a/ffmpeg-2-8-11/tests/ref/fate/canopus-hqx422 b/ffmpeg-2-8-12/tests/ref/fate/canopus-hqx422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/canopus-hqx422
rename to ffmpeg-2-8-12/tests/ref/fate/canopus-hqx422
diff --git a/ffmpeg-2-8-11/tests/ref/fate/canopus-hqx422a b/ffmpeg-2-8-12/tests/ref/fate/canopus-hqx422a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/canopus-hqx422a
rename to ffmpeg-2-8-12/tests/ref/fate/canopus-hqx422a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cavs b/ffmpeg-2-8-12/tests/ref/fate/cavs
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cavs
rename to ffmpeg-2-8-12/tests/ref/fate/cavs
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cdgraphics b/ffmpeg-2-8-12/tests/ref/fate/cdgraphics
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cdgraphics
rename to ffmpeg-2-8-12/tests/ref/fate/cdgraphics
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cdxl-bitline-ham6 b/ffmpeg-2-8-12/tests/ref/fate/cdxl-bitline-ham6
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cdxl-bitline-ham6
rename to ffmpeg-2-8-12/tests/ref/fate/cdxl-bitline-ham6
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cdxl-demux b/ffmpeg-2-8-12/tests/ref/fate/cdxl-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cdxl-demux
rename to ffmpeg-2-8-12/tests/ref/fate/cdxl-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cdxl-ham6 b/ffmpeg-2-8-12/tests/ref/fate/cdxl-ham6
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cdxl-ham6
rename to ffmpeg-2-8-12/tests/ref/fate/cdxl-ham6
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cdxl-ham8 b/ffmpeg-2-8-12/tests/ref/fate/cdxl-ham8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cdxl-ham8
rename to ffmpeg-2-8-12/tests/ref/fate/cdxl-ham8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cdxl-pal8 b/ffmpeg-2-8-12/tests/ref/fate/cdxl-pal8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cdxl-pal8
rename to ffmpeg-2-8-12/tests/ref/fate/cdxl-pal8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cdxl-pal8-small b/ffmpeg-2-8-12/tests/ref/fate/cdxl-pal8-small
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cdxl-pal8-small
rename to ffmpeg-2-8-12/tests/ref/fate/cdxl-pal8-small
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cine-demux b/ffmpeg-2-8-12/tests/ref/fate/cine-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cine-demux
rename to ffmpeg-2-8-12/tests/ref/fate/cine-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cljr b/ffmpeg-2-8-12/tests/ref/fate/cljr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cljr
rename to ffmpeg-2-8-12/tests/ref/fate/cljr
diff --git a/ffmpeg-2-8-11/tests/ref/fate/corepng b/ffmpeg-2-8-12/tests/ref/fate/corepng
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/corepng
rename to ffmpeg-2-8-12/tests/ref/fate/corepng
diff --git a/ffmpeg-2-8-11/tests/ref/fate/crc b/ffmpeg-2-8-12/tests/ref/fate/crc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/crc
rename to ffmpeg-2-8-12/tests/ref/fate/crc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/creatureshock-avs b/ffmpeg-2-8-12/tests/ref/fate/creatureshock-avs
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/creatureshock-avs
rename to ffmpeg-2-8-12/tests/ref/fate/creatureshock-avs
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cscd b/ffmpeg-2-8-12/tests/ref/fate/cscd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cscd
rename to ffmpeg-2-8-12/tests/ref/fate/cscd
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cvid-grayscale b/ffmpeg-2-8-12/tests/ref/fate/cvid-grayscale
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cvid-grayscale
rename to ffmpeg-2-8-12/tests/ref/fate/cvid-grayscale
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cvid-palette b/ffmpeg-2-8-12/tests/ref/fate/cvid-palette
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cvid-palette
rename to ffmpeg-2-8-12/tests/ref/fate/cvid-palette
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cvid-partial b/ffmpeg-2-8-12/tests/ref/fate/cvid-partial
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cvid-partial
rename to ffmpeg-2-8-12/tests/ref/fate/cvid-partial
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cyberia-c93 b/ffmpeg-2-8-12/tests/ref/fate/cyberia-c93
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cyberia-c93
rename to ffmpeg-2-8-12/tests/ref/fate/cyberia-c93
diff --git a/ffmpeg-2-8-11/tests/ref/fate/cyuv b/ffmpeg-2-8-12/tests/ref/fate/cyuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/cyuv
rename to ffmpeg-2-8-12/tests/ref/fate/cyuv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/d-cinema-demux b/ffmpeg-2-8-12/tests/ref/fate/d-cinema-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/d-cinema-demux
rename to ffmpeg-2-8-12/tests/ref/fate/d-cinema-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/d-eavp6-demux b/ffmpeg-2-8-12/tests/ref/fate/d-eavp6-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/d-eavp6-demux
rename to ffmpeg-2-8-12/tests/ref/fate/d-eavp6-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dcinema-encode b/ffmpeg-2-8-12/tests/ref/fate/dcinema-encode
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dcinema-encode
rename to ffmpeg-2-8-12/tests/ref/fate/dcinema-encode
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-argb b/ffmpeg-2-8-12/tests/ref/fate/dds-argb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-argb
rename to ffmpeg-2-8-12/tests/ref/fate/dds-argb
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-argb-aexp b/ffmpeg-2-8-12/tests/ref/fate/dds-argb-aexp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-argb-aexp
rename to ffmpeg-2-8-12/tests/ref/fate/dds-argb-aexp
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dx10-bc1 b/ffmpeg-2-8-12/tests/ref/fate/dds-dx10-bc1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dx10-bc1
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dx10-bc1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dx10-bc1a b/ffmpeg-2-8-12/tests/ref/fate/dds-dx10-bc1a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dx10-bc1a
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dx10-bc1a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dx10-bc2 b/ffmpeg-2-8-12/tests/ref/fate/dds-dx10-bc2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dx10-bc2
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dx10-bc2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dx10-bc3 b/ffmpeg-2-8-12/tests/ref/fate/dds-dx10-bc3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dx10-bc3
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dx10-bc3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dx10-bc4 b/ffmpeg-2-8-12/tests/ref/fate/dds-dx10-bc4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dx10-bc4
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dx10-bc4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dx10-bc5 b/ffmpeg-2-8-12/tests/ref/fate/dds-dx10-bc5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dx10-bc5
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dx10-bc5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt1 b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt1
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt1-normalmap b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt1-normalmap
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt1-normalmap
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt1-normalmap
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt1a b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt1a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt1a
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt1a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt2 b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt2
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt3 b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt3
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt4 b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt4
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt5 b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt5
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-aexp b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-aexp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-aexp
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-aexp
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-normalmap b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-normalmap
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-normalmap
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-normalmap
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-normalmap-ati b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-normalmap-ati
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-normalmap-ati
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-normalmap-ati
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-rbxg b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-rbxg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-rbxg
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-rbxg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-rgxb b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-rgxb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-rgxb
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-rgxb
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-rxbg b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-rxbg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-rxbg
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-rxbg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-rxgb b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-rxgb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-rxgb
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-rxgb
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-xgbr b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-xgbr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-xgbr
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-xgbr
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-xgxr b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-xgxr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-xgxr
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-xgxr
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-xrbg b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-xrbg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-xrbg
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-xrbg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-ycocg b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-ycocg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-ycocg
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-ycocg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-ycocg-scaled b/ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-ycocg-scaled
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-dxt5-ycocg-scaled
rename to ffmpeg-2-8-12/tests/ref/fate/dds-dxt5-ycocg-scaled
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-pal b/ffmpeg-2-8-12/tests/ref/fate/dds-pal
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-pal
rename to ffmpeg-2-8-12/tests/ref/fate/dds-pal
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-pal-ati b/ffmpeg-2-8-12/tests/ref/fate/dds-pal-ati
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-pal-ati
rename to ffmpeg-2-8-12/tests/ref/fate/dds-pal-ati
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-rgb16 b/ffmpeg-2-8-12/tests/ref/fate/dds-rgb16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-rgb16
rename to ffmpeg-2-8-12/tests/ref/fate/dds-rgb16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-rgb24 b/ffmpeg-2-8-12/tests/ref/fate/dds-rgb24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-rgb24
rename to ffmpeg-2-8-12/tests/ref/fate/dds-rgb24
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-rgba b/ffmpeg-2-8-12/tests/ref/fate/dds-rgba
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-rgba
rename to ffmpeg-2-8-12/tests/ref/fate/dds-rgba
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-rgtc1s b/ffmpeg-2-8-12/tests/ref/fate/dds-rgtc1s
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-rgtc1s
rename to ffmpeg-2-8-12/tests/ref/fate/dds-rgtc1s
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-rgtc1u b/ffmpeg-2-8-12/tests/ref/fate/dds-rgtc1u
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-rgtc1u
rename to ffmpeg-2-8-12/tests/ref/fate/dds-rgtc1u
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-rgtc2s b/ffmpeg-2-8-12/tests/ref/fate/dds-rgtc2s
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-rgtc2s
rename to ffmpeg-2-8-12/tests/ref/fate/dds-rgtc2s
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-rgtc2u b/ffmpeg-2-8-12/tests/ref/fate/dds-rgtc2u
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-rgtc2u
rename to ffmpeg-2-8-12/tests/ref/fate/dds-rgtc2u
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-rgtc2u-xy b/ffmpeg-2-8-12/tests/ref/fate/dds-rgtc2u-xy
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-rgtc2u-xy
rename to ffmpeg-2-8-12/tests/ref/fate/dds-rgtc2u-xy
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-uyvy b/ffmpeg-2-8-12/tests/ref/fate/dds-uyvy
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-uyvy
rename to ffmpeg-2-8-12/tests/ref/fate/dds-uyvy
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-xbgr b/ffmpeg-2-8-12/tests/ref/fate/dds-xbgr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-xbgr
rename to ffmpeg-2-8-12/tests/ref/fate/dds-xbgr
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-xrgb b/ffmpeg-2-8-12/tests/ref/fate/dds-xrgb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-xrgb
rename to ffmpeg-2-8-12/tests/ref/fate/dds-xrgb
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-y b/ffmpeg-2-8-12/tests/ref/fate/dds-y
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-y
rename to ffmpeg-2-8-12/tests/ref/fate/dds-y
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-ya b/ffmpeg-2-8-12/tests/ref/fate/dds-ya
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-ya
rename to ffmpeg-2-8-12/tests/ref/fate/dds-ya
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-ycocg b/ffmpeg-2-8-12/tests/ref/fate/dds-ycocg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-ycocg
rename to ffmpeg-2-8-12/tests/ref/fate/dds-ycocg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dds-yuyv b/ffmpeg-2-8-12/tests/ref/fate/dds-yuyv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dds-yuyv
rename to ffmpeg-2-8-12/tests/ref/fate/dds-yuyv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/delphine-cin-audio b/ffmpeg-2-8-12/tests/ref/fate/delphine-cin-audio
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/delphine-cin-audio
rename to ffmpeg-2-8-12/tests/ref/fate/delphine-cin-audio
diff --git a/ffmpeg-2-8-11/tests/ref/fate/delphine-cin-video b/ffmpeg-2-8-12/tests/ref/fate/delphine-cin-video
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/delphine-cin-video
rename to ffmpeg-2-8-12/tests/ref/fate/delphine-cin-video
diff --git a/ffmpeg-2-8-11/tests/ref/fate/deluxepaint-anm b/ffmpeg-2-8-12/tests/ref/fate/deluxepaint-anm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/deluxepaint-anm
rename to ffmpeg-2-8-12/tests/ref/fate/deluxepaint-anm
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dfa1 b/ffmpeg-2-8-12/tests/ref/fate/dfa1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dfa1
rename to ffmpeg-2-8-12/tests/ref/fate/dfa1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dfa10 b/ffmpeg-2-8-12/tests/ref/fate/dfa10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dfa10
rename to ffmpeg-2-8-12/tests/ref/fate/dfa10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dfa11 b/ffmpeg-2-8-12/tests/ref/fate/dfa11
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dfa11
rename to ffmpeg-2-8-12/tests/ref/fate/dfa11
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dfa2 b/ffmpeg-2-8-12/tests/ref/fate/dfa2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dfa2
rename to ffmpeg-2-8-12/tests/ref/fate/dfa2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dfa3 b/ffmpeg-2-8-12/tests/ref/fate/dfa3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dfa3
rename to ffmpeg-2-8-12/tests/ref/fate/dfa3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dfa4 b/ffmpeg-2-8-12/tests/ref/fate/dfa4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dfa4
rename to ffmpeg-2-8-12/tests/ref/fate/dfa4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dfa5 b/ffmpeg-2-8-12/tests/ref/fate/dfa5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dfa5
rename to ffmpeg-2-8-12/tests/ref/fate/dfa5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dfa6 b/ffmpeg-2-8-12/tests/ref/fate/dfa6
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dfa6
rename to ffmpeg-2-8-12/tests/ref/fate/dfa6
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dfa7 b/ffmpeg-2-8-12/tests/ref/fate/dfa7
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dfa7
rename to ffmpeg-2-8-12/tests/ref/fate/dfa7
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dfa8 b/ffmpeg-2-8-12/tests/ref/fate/dfa8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dfa8
rename to ffmpeg-2-8-12/tests/ref/fate/dfa8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dfa9 b/ffmpeg-2-8-12/tests/ref/fate/dfa9
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dfa9
rename to ffmpeg-2-8-12/tests/ref/fate/dfa9
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dict b/ffmpeg-2-8-12/tests/ref/fate/dict
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dict
rename to ffmpeg-2-8-12/tests/ref/fate/dict
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dirac b/ffmpeg-2-8-12/tests/ref/fate/dirac
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dirac
rename to ffmpeg-2-8-12/tests/ref/fate/dirac
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dpcm-idroq b/ffmpeg-2-8-12/tests/ref/fate/dpcm-idroq
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dpcm-idroq
rename to ffmpeg-2-8-12/tests/ref/fate/dpcm-idroq
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dpcm-interplay b/ffmpeg-2-8-12/tests/ref/fate/dpcm-interplay
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dpcm-interplay
rename to ffmpeg-2-8-12/tests/ref/fate/dpcm-interplay
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dpcm-sierra b/ffmpeg-2-8-12/tests/ref/fate/dpcm-sierra
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dpcm-sierra
rename to ffmpeg-2-8-12/tests/ref/fate/dpcm-sierra
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dpcm-xan b/ffmpeg-2-8-12/tests/ref/fate/dpcm-xan
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dpcm-xan
rename to ffmpeg-2-8-12/tests/ref/fate/dpcm-xan
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dpx b/ffmpeg-2-8-12/tests/ref/fate/dpx
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dpx
rename to ffmpeg-2-8-12/tests/ref/fate/dpx
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dpxparser b/ffmpeg-2-8-12/tests/ref/fate/dpxparser
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dpxparser
rename to ffmpeg-2-8-12/tests/ref/fate/dpxparser
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dss-lp b/ffmpeg-2-8-12/tests/ref/fate/dss-lp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dss-lp
rename to ffmpeg-2-8-12/tests/ref/fate/dss-lp
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dss-sp b/ffmpeg-2-8-12/tests/ref/fate/dss-sp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dss-sp
rename to ffmpeg-2-8-12/tests/ref/fate/dss-sp
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dxa-feeble b/ffmpeg-2-8-12/tests/ref/fate/dxa-feeble
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dxa-feeble
rename to ffmpeg-2-8-12/tests/ref/fate/dxa-feeble
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dxa-scummvm b/ffmpeg-2-8-12/tests/ref/fate/dxa-scummvm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dxa-scummvm
rename to ffmpeg-2-8-12/tests/ref/fate/dxa-scummvm
diff --git a/ffmpeg-2-8-11/tests/ref/fate/dxtory b/ffmpeg-2-8-12/tests/ref/fate/dxtory
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/dxtory
rename to ffmpeg-2-8-12/tests/ref/fate/dxtory
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ea-cdata b/ffmpeg-2-8-12/tests/ref/fate/ea-cdata
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ea-cdata
rename to ffmpeg-2-8-12/tests/ref/fate/ea-cdata
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ea-cmv b/ffmpeg-2-8-12/tests/ref/fate/ea-cmv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ea-cmv
rename to ffmpeg-2-8-12/tests/ref/fate/ea-cmv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ea-mad b/ffmpeg-2-8-12/tests/ref/fate/ea-mad
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ea-mad
rename to ffmpeg-2-8-12/tests/ref/fate/ea-mad
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ea-tgq b/ffmpeg-2-8-12/tests/ref/fate/ea-tgq
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ea-tgq
rename to ffmpeg-2-8-12/tests/ref/fate/ea-tgq
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ea-tgv-1 b/ffmpeg-2-8-12/tests/ref/fate/ea-tgv-1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ea-tgv-1
rename to ffmpeg-2-8-12/tests/ref/fate/ea-tgv-1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ea-tgv-2 b/ffmpeg-2-8-12/tests/ref/fate/ea-tgv-2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ea-tgv-2
rename to ffmpeg-2-8-12/tests/ref/fate/ea-tgv-2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ea-tqi b/ffmpeg-2-8-12/tests/ref/fate/ea-tqi
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ea-tqi
rename to ffmpeg-2-8-12/tests/ref/fate/ea-tqi
diff --git a/ffmpeg-2-8-11/tests/ref/fate/eval b/ffmpeg-2-8-12/tests/ref/fate/eval
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/eval
rename to ffmpeg-2-8-12/tests/ref/fate/eval
diff --git a/ffmpeg-2-8-11/tests/ref/fate/exif-image-embedded b/ffmpeg-2-8-12/tests/ref/fate/exif-image-embedded
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/exif-image-embedded
rename to ffmpeg-2-8-12/tests/ref/fate/exif-image-embedded
diff --git a/ffmpeg-2-8-11/tests/ref/fate/exif-image-jpg b/ffmpeg-2-8-12/tests/ref/fate/exif-image-jpg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/exif-image-jpg
rename to ffmpeg-2-8-12/tests/ref/fate/exif-image-jpg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/exif-image-tiff b/ffmpeg-2-8-12/tests/ref/fate/exif-image-tiff
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/exif-image-tiff
rename to ffmpeg-2-8-12/tests/ref/fate/exif-image-tiff
diff --git a/ffmpeg-2-8-11/tests/ref/fate/exif-image-webp b/ffmpeg-2-8-12/tests/ref/fate/exif-image-webp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/exif-image-webp
rename to ffmpeg-2-8-12/tests/ref/fate/exif-image-webp
diff --git a/ffmpeg-2-8-11/tests/ref/fate/exr-slice-pxr24 b/ffmpeg-2-8-12/tests/ref/fate/exr-slice-pxr24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/exr-slice-pxr24
rename to ffmpeg-2-8-12/tests/ref/fate/exr-slice-pxr24
diff --git a/ffmpeg-2-8-11/tests/ref/fate/exr-slice-raw b/ffmpeg-2-8-12/tests/ref/fate/exr-slice-raw
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/exr-slice-raw
rename to ffmpeg-2-8-12/tests/ref/fate/exr-slice-raw
diff --git a/ffmpeg-2-8-11/tests/ref/fate/exr-slice-rle b/ffmpeg-2-8-12/tests/ref/fate/exr-slice-rle
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/exr-slice-rle
rename to ffmpeg-2-8-12/tests/ref/fate/exr-slice-rle
diff --git a/ffmpeg-2-8-11/tests/ref/fate/exr-slice-zip1 b/ffmpeg-2-8-12/tests/ref/fate/exr-slice-zip1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/exr-slice-zip1
rename to ffmpeg-2-8-12/tests/ref/fate/exr-slice-zip1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/exr-slice-zip16 b/ffmpeg-2-8-12/tests/ref/fate/exr-slice-zip16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/exr-slice-zip16
rename to ffmpeg-2-8-12/tests/ref/fate/exr-slice-zip16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ffmpeg-filter_complex b/ffmpeg-2-8-12/tests/ref/fate/ffmpeg-filter_complex
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ffmpeg-filter_complex
rename to ffmpeg-2-8-12/tests/ref/fate/ffmpeg-filter_complex
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ffmpeg-lavfi b/ffmpeg-2-8-12/tests/ref/fate/ffmpeg-lavfi
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ffmpeg-lavfi
rename to ffmpeg-2-8-12/tests/ref/fate/ffmpeg-lavfi
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ffprobe_compact b/ffmpeg-2-8-12/tests/ref/fate/ffprobe_compact
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ffprobe_compact
rename to ffmpeg-2-8-12/tests/ref/fate/ffprobe_compact
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ffprobe_csv b/ffmpeg-2-8-12/tests/ref/fate/ffprobe_csv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ffprobe_csv
rename to ffmpeg-2-8-12/tests/ref/fate/ffprobe_csv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ffprobe_default b/ffmpeg-2-8-12/tests/ref/fate/ffprobe_default
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ffprobe_default
rename to ffmpeg-2-8-12/tests/ref/fate/ffprobe_default
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ffprobe_flat b/ffmpeg-2-8-12/tests/ref/fate/ffprobe_flat
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ffprobe_flat
rename to ffmpeg-2-8-12/tests/ref/fate/ffprobe_flat
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ffprobe_ini b/ffmpeg-2-8-12/tests/ref/fate/ffprobe_ini
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ffprobe_ini
rename to ffmpeg-2-8-12/tests/ref/fate/ffprobe_ini
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ffprobe_json b/ffmpeg-2-8-12/tests/ref/fate/ffprobe_json
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ffprobe_json
rename to ffmpeg-2-8-12/tests/ref/fate/ffprobe_json
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ffprobe_xml b/ffmpeg-2-8-12/tests/ref/fate/ffprobe_xml
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ffprobe_xml
rename to ffmpeg-2-8-12/tests/ref/fate/ffprobe_xml
diff --git a/ffmpeg-2-8-11/tests/ref/fate/fic-avi b/ffmpeg-2-8-12/tests/ref/fate/fic-avi
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/fic-avi
rename to ffmpeg-2-8-12/tests/ref/fate/fic-avi
diff --git a/ffmpeg-2-8-11/tests/ref/fate/fifo b/ffmpeg-2-8-12/tests/ref/fate/fifo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/fifo
rename to ffmpeg-2-8-12/tests/ref/fate/fifo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/film-cvid b/ffmpeg-2-8-12/tests/ref/fate/film-cvid
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/film-cvid
rename to ffmpeg-2-8-12/tests/ref/fate/film-cvid
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-2xbr b/ffmpeg-2-8-12/tests/ref/fate/filter-2xbr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-2xbr
rename to ffmpeg-2-8-12/tests/ref/fate/filter-2xbr
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-3xbr b/ffmpeg-2-8-12/tests/ref/fate/filter-3xbr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-3xbr
rename to ffmpeg-2-8-12/tests/ref/fate/filter-3xbr
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-4xbr b/ffmpeg-2-8-12/tests/ref/fate/filter-4xbr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-4xbr
rename to ffmpeg-2-8-12/tests/ref/fate/filter-4xbr
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-adelay b/ffmpeg-2-8-12/tests/ref/fate/filter-adelay
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-adelay
rename to ffmpeg-2-8-12/tests/ref/fate/filter-adelay
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-alphaextract_alphamerge_rgb b/ffmpeg-2-8-12/tests/ref/fate/filter-alphaextract_alphamerge_rgb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-alphaextract_alphamerge_rgb
rename to ffmpeg-2-8-12/tests/ref/fate/filter-alphaextract_alphamerge_rgb
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-alphaextract_alphamerge_yuv b/ffmpeg-2-8-12/tests/ref/fate/filter-alphaextract_alphamerge_yuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-alphaextract_alphamerge_yuv
rename to ffmpeg-2-8-12/tests/ref/fate/filter-alphaextract_alphamerge_yuv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-atrim-duration b/ffmpeg-2-8-12/tests/ref/fate/filter-atrim-duration
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-atrim-duration
rename to ffmpeg-2-8-12/tests/ref/fate/filter-atrim-duration
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-atrim-mixed b/ffmpeg-2-8-12/tests/ref/fate/filter-atrim-mixed
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-atrim-mixed
rename to ffmpeg-2-8-12/tests/ref/fate/filter-atrim-mixed
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-atrim-samples b/ffmpeg-2-8-12/tests/ref/fate/filter-atrim-samples
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-atrim-samples
rename to ffmpeg-2-8-12/tests/ref/fate/filter-atrim-samples
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-atrim-time b/ffmpeg-2-8-12/tests/ref/fate/filter-atrim-time
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-atrim-time
rename to ffmpeg-2-8-12/tests/ref/fate/filter-atrim-time
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-boxblur b/ffmpeg-2-8-12/tests/ref/fate/filter-boxblur
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-boxblur
rename to ffmpeg-2-8-12/tests/ref/fate/filter-boxblur
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-codecview-mvs b/ffmpeg-2-8-12/tests/ref/fate/filter-codecview-mvs
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-codecview-mvs
rename to ffmpeg-2-8-12/tests/ref/fate/filter-codecview-mvs
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-colorchannelmixer b/ffmpeg-2-8-12/tests/ref/fate/filter-colorchannelmixer
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-colorchannelmixer
rename to ffmpeg-2-8-12/tests/ref/fate/filter-colorchannelmixer
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-colormatrix1 b/ffmpeg-2-8-12/tests/ref/fate/filter-colormatrix1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-colormatrix1
rename to ffmpeg-2-8-12/tests/ref/fate/filter-colormatrix1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-colormatrix2 b/ffmpeg-2-8-12/tests/ref/fate/filter-colormatrix2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-colormatrix2
rename to ffmpeg-2-8-12/tests/ref/fate/filter-colormatrix2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-concat b/ffmpeg-2-8-12/tests/ref/fate/filter-concat
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-concat
rename to ffmpeg-2-8-12/tests/ref/fate/filter-concat
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-crop b/ffmpeg-2-8-12/tests/ref/fate/filter-crop
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-crop
rename to ffmpeg-2-8-12/tests/ref/fate/filter-crop
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-crop_scale b/ffmpeg-2-8-12/tests/ref/fate/filter-crop_scale
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-crop_scale
rename to ffmpeg-2-8-12/tests/ref/fate/filter-crop_scale
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-crop_scale_vflip b/ffmpeg-2-8-12/tests/ref/fate/filter-crop_scale_vflip
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-crop_scale_vflip
rename to ffmpeg-2-8-12/tests/ref/fate/filter-crop_scale_vflip
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-crop_vflip b/ffmpeg-2-8-12/tests/ref/fate/filter-crop_vflip
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-crop_vflip
rename to ffmpeg-2-8-12/tests/ref/fate/filter-crop_vflip
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-curves b/ffmpeg-2-8-12/tests/ref/fate/filter-curves
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-curves
rename to ffmpeg-2-8-12/tests/ref/fate/filter-curves
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-delogo b/ffmpeg-2-8-12/tests/ref/fate/filter-delogo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-delogo
rename to ffmpeg-2-8-12/tests/ref/fate/filter-delogo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-drawbox b/ffmpeg-2-8-12/tests/ref/fate/filter-drawbox
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-drawbox
rename to ffmpeg-2-8-12/tests/ref/fate/filter-drawbox
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-edgedetect b/ffmpeg-2-8-12/tests/ref/fate/filter-edgedetect
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-edgedetect
rename to ffmpeg-2-8-12/tests/ref/fate/filter-edgedetect
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-edgedetect-colormix b/ffmpeg-2-8-12/tests/ref/fate/filter-edgedetect-colormix
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-edgedetect-colormix
rename to ffmpeg-2-8-12/tests/ref/fate/filter-edgedetect-colormix
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-fade b/ffmpeg-2-8-12/tests/ref/fate/filter-fade
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-fade
rename to ffmpeg-2-8-12/tests/ref/fate/filter-fade
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-fieldorder b/ffmpeg-2-8-12/tests/ref/fate/filter-fieldorder
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-fieldorder
rename to ffmpeg-2-8-12/tests/ref/fate/filter-fieldorder
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-formats b/ffmpeg-2-8-12/tests/ref/fate/filter-formats
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-formats
rename to ffmpeg-2-8-12/tests/ref/fate/filter-formats
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-framepack-columns b/ffmpeg-2-8-12/tests/ref/fate/filter-framepack-columns
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-framepack-columns
rename to ffmpeg-2-8-12/tests/ref/fate/filter-framepack-columns
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-framepack-frameseq b/ffmpeg-2-8-12/tests/ref/fate/filter-framepack-frameseq
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-framepack-frameseq
rename to ffmpeg-2-8-12/tests/ref/fate/filter-framepack-frameseq
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-framepack-lines b/ffmpeg-2-8-12/tests/ref/fate/filter-framepack-lines
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-framepack-lines
rename to ffmpeg-2-8-12/tests/ref/fate/filter-framepack-lines
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-framepack-sbs b/ffmpeg-2-8-12/tests/ref/fate/filter-framepack-sbs
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-framepack-sbs
rename to ffmpeg-2-8-12/tests/ref/fate/filter-framepack-sbs
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-framepack-tab b/ffmpeg-2-8-12/tests/ref/fate/filter-framepack-tab
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-framepack-tab
rename to ffmpeg-2-8-12/tests/ref/fate/filter-framepack-tab
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-gradfun b/ffmpeg-2-8-12/tests/ref/fate/filter-gradfun
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-gradfun
rename to ffmpeg-2-8-12/tests/ref/fate/filter-gradfun
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-gradfun-sample b/ffmpeg-2-8-12/tests/ref/fate/filter-gradfun-sample
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-gradfun-sample
rename to ffmpeg-2-8-12/tests/ref/fate/filter-gradfun-sample
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-histogram-levels b/ffmpeg-2-8-12/tests/ref/fate/filter-histogram-levels
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-histogram-levels
rename to ffmpeg-2-8-12/tests/ref/fate/filter-histogram-levels
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-hq2x b/ffmpeg-2-8-12/tests/ref/fate/filter-hq2x
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-hq2x
rename to ffmpeg-2-8-12/tests/ref/fate/filter-hq2x
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-hq3x b/ffmpeg-2-8-12/tests/ref/fate/filter-hq3x
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-hq3x
rename to ffmpeg-2-8-12/tests/ref/fate/filter-hq3x
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-hq4x b/ffmpeg-2-8-12/tests/ref/fate/filter-hq4x
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-hq4x
rename to ffmpeg-2-8-12/tests/ref/fate/filter-hq4x
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-hqdn3d b/ffmpeg-2-8-12/tests/ref/fate/filter-hqdn3d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-hqdn3d
rename to ffmpeg-2-8-12/tests/ref/fate/filter-hqdn3d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-hqdn3d-sample b/ffmpeg-2-8-12/tests/ref/fate/filter-hqdn3d-sample
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-hqdn3d-sample
rename to ffmpeg-2-8-12/tests/ref/fate/filter-hqdn3d-sample
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-hue b/ffmpeg-2-8-12/tests/ref/fate/filter-hue
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-hue
rename to ffmpeg-2-8-12/tests/ref/fate/filter-hue
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-idet b/ffmpeg-2-8-12/tests/ref/fate/filter-idet
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-idet
rename to ffmpeg-2-8-12/tests/ref/fate/filter-idet
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-interlace b/ffmpeg-2-8-12/tests/ref/fate/filter-interlace
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-interlace
rename to ffmpeg-2-8-12/tests/ref/fate/filter-interlace
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-lavd-life b/ffmpeg-2-8-12/tests/ref/fate/filter-lavd-life
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-lavd-life
rename to ffmpeg-2-8-12/tests/ref/fate/filter-lavd-life
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-lavd-scalenorm b/ffmpeg-2-8-12/tests/ref/fate/filter-lavd-scalenorm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-lavd-scalenorm
rename to ffmpeg-2-8-12/tests/ref/fate/filter-lavd-scalenorm
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-lavd-testsrc b/ffmpeg-2-8-12/tests/ref/fate/filter-lavd-testsrc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-lavd-testsrc
rename to ffmpeg-2-8-12/tests/ref/fate/filter-lavd-testsrc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-mcdeint-fast b/ffmpeg-2-8-12/tests/ref/fate/filter-mcdeint-fast
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-mcdeint-fast
rename to ffmpeg-2-8-12/tests/ref/fate/filter-mcdeint-fast
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-mcdeint-medium b/ffmpeg-2-8-12/tests/ref/fate/filter-mcdeint-medium
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-mcdeint-medium
rename to ffmpeg-2-8-12/tests/ref/fate/filter-mcdeint-medium
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-mergeplanes b/ffmpeg-2-8-12/tests/ref/fate/filter-mergeplanes
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-mergeplanes
rename to ffmpeg-2-8-12/tests/ref/fate/filter-mergeplanes
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-metadata-ebur128 b/ffmpeg-2-8-12/tests/ref/fate/filter-metadata-ebur128
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-metadata-ebur128
rename to ffmpeg-2-8-12/tests/ref/fate/filter-metadata-ebur128
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-metadata-scenedetect b/ffmpeg-2-8-12/tests/ref/fate/filter-metadata-scenedetect
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-metadata-scenedetect
rename to ffmpeg-2-8-12/tests/ref/fate/filter-metadata-scenedetect
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-metadata-silencedetect b/ffmpeg-2-8-12/tests/ref/fate/filter-metadata-silencedetect
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-metadata-silencedetect
rename to ffmpeg-2-8-12/tests/ref/fate/filter-metadata-silencedetect
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-negate b/ffmpeg-2-8-12/tests/ref/fate/filter-negate
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-negate
rename to ffmpeg-2-8-12/tests/ref/fate/filter-negate
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-null b/ffmpeg-2-8-12/tests/ref/fate/filter-null
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-null
rename to ffmpeg-2-8-12/tests/ref/fate/filter-null
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-overlay b/ffmpeg-2-8-12/tests/ref/fate/filter-overlay
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-overlay
rename to ffmpeg-2-8-12/tests/ref/fate/filter-overlay
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-overlay_rgb b/ffmpeg-2-8-12/tests/ref/fate/filter-overlay_rgb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-overlay_rgb
rename to ffmpeg-2-8-12/tests/ref/fate/filter-overlay_rgb
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-overlay_yuv420 b/ffmpeg-2-8-12/tests/ref/fate/filter-overlay_yuv420
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-overlay_yuv420
rename to ffmpeg-2-8-12/tests/ref/fate/filter-overlay_yuv420
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-overlay_yuv422 b/ffmpeg-2-8-12/tests/ref/fate/filter-overlay_yuv422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-overlay_yuv422
rename to ffmpeg-2-8-12/tests/ref/fate/filter-overlay_yuv422
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-overlay_yuv444 b/ffmpeg-2-8-12/tests/ref/fate/filter-overlay_yuv444
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-overlay_yuv444
rename to ffmpeg-2-8-12/tests/ref/fate/filter-overlay_yuv444
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pad b/ffmpeg-2-8-12/tests/ref/fate/filter-pad
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pad
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pad
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-palettegen-1 b/ffmpeg-2-8-12/tests/ref/fate/filter-palettegen-1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-palettegen-1
rename to ffmpeg-2-8-12/tests/ref/fate/filter-palettegen-1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-palettegen-2 b/ffmpeg-2-8-12/tests/ref/fate/filter-palettegen-2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-palettegen-2
rename to ffmpeg-2-8-12/tests/ref/fate/filter-palettegen-2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-paletteuse-bayer b/ffmpeg-2-8-12/tests/ref/fate/filter-paletteuse-bayer
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-paletteuse-bayer
rename to ffmpeg-2-8-12/tests/ref/fate/filter-paletteuse-bayer
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-paletteuse-nodither b/ffmpeg-2-8-12/tests/ref/fate/filter-paletteuse-nodither
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-paletteuse-nodither
rename to ffmpeg-2-8-12/tests/ref/fate/filter-paletteuse-nodither
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-paletteuse-sierra2_4a b/ffmpeg-2-8-12/tests/ref/fate/filter-paletteuse-sierra2_4a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-paletteuse-sierra2_4a
rename to ffmpeg-2-8-12/tests/ref/fate/filter-paletteuse-sierra2_4a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-phase b/ffmpeg-2-8-12/tests/ref/fate/filter-phase
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-phase
rename to ffmpeg-2-8-12/tests/ref/fate/filter-phase
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-0bgr b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-0bgr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-0bgr
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-0bgr
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-0rgb b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-0rgb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-0rgb
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-0rgb
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-abgr b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-abgr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-abgr
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-abgr
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-argb b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-argb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-argb
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-argb
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-ayuv64le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-ayuv64le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-ayuv64le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-ayuv64le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr0 b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr0
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr0
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr24 b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr24
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr24
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr444be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr444be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr444be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr444be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr444le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr444le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr444le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr444le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr48be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr48be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr48be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr48be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr48le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr48le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr48le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr48le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr4_byte b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr4_byte
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr4_byte
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr4_byte
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr555be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr555be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr555be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr555be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr555le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr555le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr555le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr555le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr565be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr565be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr565be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr565be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr565le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr565le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr565le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr565le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr8 b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgr8
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgr8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgra b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgra
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgra
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgra
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgra64be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgra64be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgra64be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgra64be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgra64le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgra64le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-bgra64le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-bgra64le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrap b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrap
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrap
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrap
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp10be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp10be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp10be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp10be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp10le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp10le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp10le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp10le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp12be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp12be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp12be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp12be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp12le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp12le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp12le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp12le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp14be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp14be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp14be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp14be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp14le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp14le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp14le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp14le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp9be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp9be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp9be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp9be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp9le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp9le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gbrp9le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gbrp9le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gray b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gray
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gray
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gray
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gray16be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gray16be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gray16be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gray16be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gray16le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gray16le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-gray16le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-gray16le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-monob b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-monob
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-monob
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-monob
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-monow b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-monow
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-monow
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-monow
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-nv12 b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-nv12
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-nv12
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-nv12
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-nv21 b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-nv21
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-nv21
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-nv21
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb0 b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb0
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb0
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb24 b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb24
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb24
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb444be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb444be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb444be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb444be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb444le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb444le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb444le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb444le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb48be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb48be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb48be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb48be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb48le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb48le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb48le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb48le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb4_byte b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb4_byte
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb4_byte
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb4_byte
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb555be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb555be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb555be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb555be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb555le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb555le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb555le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb555le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb565be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb565be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb565be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb565be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb565le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb565le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb565le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb565le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb8 b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgb8
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgb8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgba b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgba
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgba
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgba
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgba64be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgba64be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgba64be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgba64be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgba64le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgba64le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-rgba64le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-rgba64le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-uyvy422 b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-uyvy422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-uyvy422
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-uyvy422
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-xyz12be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-xyz12be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-xyz12be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-xyz12be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-xyz12le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-xyz12le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-xyz12le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-xyz12le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-ya8 b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-ya8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-ya8
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-ya8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv410p b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv410p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv410p
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv410p
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv411p b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv411p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv411p
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv411p
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p10be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p10be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p10be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p10be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p10le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p10le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p10le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p10le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p12be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p12be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p12be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p12be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p12le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p12le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p12le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p12le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p14be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p14be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p14be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p14be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p14le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p14le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p14le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p14le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p16be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p16be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p16be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p16be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p16le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p16le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p16le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p16le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p9be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p9be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p9be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p9be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p9le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p9le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv420p9le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv420p9le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p10be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p10be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p10be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p10be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p10le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p10le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p10le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p10le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p12be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p12be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p12be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p12be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p12le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p12le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p12le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p12le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p14be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p14be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p14be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p14be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p14le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p14le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p14le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p14le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p16be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p16be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p16be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p16be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p16le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p16le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p16le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p16le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p9be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p9be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p9be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p9be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p9le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p9le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv422p9le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv422p9le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv440p b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv440p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv440p
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv440p
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv440p10be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv440p10be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv440p10be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv440p10be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv440p10le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv440p10le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv440p10le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv440p10le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv440p12be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv440p12be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv440p12be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv440p12be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv440p12le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv440p12le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv440p12le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv440p12le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p10be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p10be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p10be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p10be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p10le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p10le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p10le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p10le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p12be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p12be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p12be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p12be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p12le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p12le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p12le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p12le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p14be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p14be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p14be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p14be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p14le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p14le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p14le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p14le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p16be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p16be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p16be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p16be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p16le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p16le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p16le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p16le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p9be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p9be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p9be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p9be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p9le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p9le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuv444p9le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuv444p9le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva420p b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva420p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva420p
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva420p
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva420p10be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva420p10be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva420p10be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva420p10be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva420p10le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva420p10le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva420p10le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva420p10le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva420p16be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva420p16be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva420p16be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva420p16be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva420p16le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva420p16le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva420p16le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva420p16le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva420p9be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva420p9be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva420p9be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva420p9be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva420p9le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva420p9le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva420p9le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva420p9le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva422p b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva422p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva422p
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva422p
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva422p10be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva422p10be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva422p10be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva422p10be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva422p10le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva422p10le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva422p10le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva422p10le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva422p16be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva422p16be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva422p16be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva422p16be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva422p16le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva422p16le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva422p16le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva422p16le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva422p9be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva422p9be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva422p9be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva422p9be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva422p9le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva422p9le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva422p9le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva422p9le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva444p b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva444p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva444p
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva444p
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva444p10be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva444p10be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva444p10be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva444p10be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva444p10le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva444p10le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva444p10le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva444p10le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva444p16be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva444p16be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva444p16be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva444p16be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva444p16le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva444p16le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva444p16le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva444p16le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva444p9be b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva444p9be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva444p9be
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva444p9be
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva444p9le b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva444p9le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuva444p9le
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuva444p9le
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuvj411p b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuvj411p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuvj411p
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuvj411p
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuvj420p b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuvj420p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuvj420p
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuvj420p
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuvj422p b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuvj422p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuvj422p
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuvj422p
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuvj440p b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuvj440p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuvj440p
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuvj440p
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuvj444p b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuvj444p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuvj444p
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuvj444p
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuyv422 b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuyv422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yuyv422
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yuyv422
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yvyu422 b/ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yvyu422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixdesc-yvyu422
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixdesc-yvyu422
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-copy b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-copy
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-copy
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-copy
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-crop b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-crop
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-crop
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-crop
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-field b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-field
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-field
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-field
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-fieldmatch b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-fieldmatch
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-fieldmatch
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-fieldmatch
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-fieldorder b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-fieldorder
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-fieldorder
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-fieldorder
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-hflip b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-hflip
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-hflip
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-hflip
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-histeq b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-histeq
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-histeq
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-histeq
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-il b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-il
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-il
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-il
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-kerndeint b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-kerndeint
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-kerndeint
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-kerndeint
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-lut b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-lut
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-lut
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-lut
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-null b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-null
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-null
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-null
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-pad b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-pad
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-pad
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-pad
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-pullup b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-pullup
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-pullup
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-pullup
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-rotate b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-rotate
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-rotate
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-rotate
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-scale b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-scale
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-scale
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-scale
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-super2xsai b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-super2xsai
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-super2xsai
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-super2xsai
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-swapuv b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-swapuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-swapuv
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-swapuv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-tinterlace_merge b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-tinterlace_merge
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-tinterlace_merge
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-tinterlace_merge
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-tinterlace_pad b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-tinterlace_pad
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-tinterlace_pad
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-tinterlace_pad
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-vflip b/ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-vflip
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pixfmts-vflip
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pixfmts-vflip
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pp b/ffmpeg-2-8-12/tests/ref/fate/filter-pp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pp
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pp
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pp1 b/ffmpeg-2-8-12/tests/ref/fate/filter-pp1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pp1
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pp1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pp2 b/ffmpeg-2-8-12/tests/ref/fate/filter-pp2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pp2
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pp2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pp3 b/ffmpeg-2-8-12/tests/ref/fate/filter-pp3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pp3
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pp3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pp4 b/ffmpeg-2-8-12/tests/ref/fate/filter-pp4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pp4
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pp4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pp5 b/ffmpeg-2-8-12/tests/ref/fate/filter-pp5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pp5
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pp5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-pp6 b/ffmpeg-2-8-12/tests/ref/fate/filter-pp6
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-pp6
rename to ffmpeg-2-8-12/tests/ref/fate/filter-pp6
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-qp b/ffmpeg-2-8-12/tests/ref/fate/filter-qp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-qp
rename to ffmpeg-2-8-12/tests/ref/fate/filter-qp
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-00 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-00
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-00
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-00
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-01 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-01
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-01
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-01
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-02 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-02
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-02
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-02
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-03 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-03
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-03
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-03
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-04 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-04
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-04
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-04
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-05 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-05
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-05
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-05
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-06 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-06
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-06
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-06
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-07 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-07
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-07
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-07
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-08 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-08
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-08
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-08
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-09 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-09
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-09
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-09
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-10 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-10
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-11 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-11
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-11
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-11
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-12 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-12
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-12
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-12
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-13 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-13
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-13
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-13
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-14 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-14
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-14
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-14
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-15 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-15
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-15
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-15
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-16 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-16
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-17 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-17
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-17
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-17
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-18 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-18
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-18
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-18
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-19 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-19
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-19
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-19
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-20 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-20
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-20
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-20
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-21 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-21
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-21
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-21
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-22 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-22
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-22
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-22
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-23 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-23
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-23
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-23
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-24 b/ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-removegrain-mode-24
rename to ffmpeg-2-8-12/tests/ref/fate/filter-removegrain-mode-24
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-scale200 b/ffmpeg-2-8-12/tests/ref/fate/filter-scale200
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-scale200
rename to ffmpeg-2-8-12/tests/ref/fate/filter-scale200
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-scale500 b/ffmpeg-2-8-12/tests/ref/fate/filter-scale500
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-scale500
rename to ffmpeg-2-8-12/tests/ref/fate/filter-scale500
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-select b/ffmpeg-2-8-12/tests/ref/fate/filter-select
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-select
rename to ffmpeg-2-8-12/tests/ref/fate/filter-select
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-select-alternate b/ffmpeg-2-8-12/tests/ref/fate/filter-select-alternate
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-select-alternate
rename to ffmpeg-2-8-12/tests/ref/fate/filter-select-alternate
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-separatefields b/ffmpeg-2-8-12/tests/ref/fate/filter-separatefields
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-separatefields
rename to ffmpeg-2-8-12/tests/ref/fate/filter-separatefields
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-setdar b/ffmpeg-2-8-12/tests/ref/fate/filter-setdar
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-setdar
rename to ffmpeg-2-8-12/tests/ref/fate/filter-setdar
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-setpts b/ffmpeg-2-8-12/tests/ref/fate/filter-setpts
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-setpts
rename to ffmpeg-2-8-12/tests/ref/fate/filter-setpts
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-setsar b/ffmpeg-2-8-12/tests/ref/fate/filter-setsar
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-setsar
rename to ffmpeg-2-8-12/tests/ref/fate/filter-setsar
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-showpalette b/ffmpeg-2-8-12/tests/ref/fate/filter-showpalette
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-showpalette
rename to ffmpeg-2-8-12/tests/ref/fate/filter-showpalette
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-shuffleplanes-dup-luma b/ffmpeg-2-8-12/tests/ref/fate/filter-shuffleplanes-dup-luma
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-shuffleplanes-dup-luma
rename to ffmpeg-2-8-12/tests/ref/fate/filter-shuffleplanes-dup-luma
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-shuffleplanes-swapuv b/ffmpeg-2-8-12/tests/ref/fate/filter-shuffleplanes-swapuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-shuffleplanes-swapuv
rename to ffmpeg-2-8-12/tests/ref/fate/filter-shuffleplanes-swapuv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-abr-ml b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-abr-ml
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-abr-ml
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-abr-ml
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-abr-mr b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-abr-mr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-abr-mr
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-abr-mr
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-al-sbsl b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-al-sbsl
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-al-sbsl
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-al-sbsl
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-ar-abl b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-ar-abl
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-ar-abl
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-ar-abl
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-abl b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-abl
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-abl
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-abl
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-abr b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-abr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-abr
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-abr
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-agmc b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-agmc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-agmc
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-agmc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-agmd b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-agmd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-agmd
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-agmd
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-agmg b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-agmg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-agmg
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-agmg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-agmh b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-agmh
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-agmh
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-agmh
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-al b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-al
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-al
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-al
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-arbg b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-arbg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-arbg
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-arbg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-arcc b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-arcc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-arcc
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-arcc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-arcd b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-arcd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-arcd
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-arcd
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-arcg b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-arcg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-arcg
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-arcg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-arch b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-arch
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-arch
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-arch
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-argg b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-argg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-argg
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-argg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-aybc b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-aybc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-aybc
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-aybc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-aybd b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-aybd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-aybd
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-aybd
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-aybg b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-aybg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-aybg
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-aybg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-aybh b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-aybh
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-aybh
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-aybh
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-sbsr b/ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-sbsr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-stereo3d-sbsl-sbsr
rename to ffmpeg-2-8-12/tests/ref/fate/filter-stereo3d-sbsl-sbsr
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-tblend b/ffmpeg-2-8-12/tests/ref/fate/filter-tblend
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-tblend
rename to ffmpeg-2-8-12/tests/ref/fate/filter-tblend
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-telecine b/ffmpeg-2-8-12/tests/ref/fate/filter-telecine
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-telecine
rename to ffmpeg-2-8-12/tests/ref/fate/filter-telecine
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-thumbnail b/ffmpeg-2-8-12/tests/ref/fate/filter-thumbnail
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-thumbnail
rename to ffmpeg-2-8-12/tests/ref/fate/filter-thumbnail
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-tile b/ffmpeg-2-8-12/tests/ref/fate/filter-tile
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-tile
rename to ffmpeg-2-8-12/tests/ref/fate/filter-tile
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-transpose b/ffmpeg-2-8-12/tests/ref/fate/filter-transpose
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-transpose
rename to ffmpeg-2-8-12/tests/ref/fate/filter-transpose
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-trim-duration b/ffmpeg-2-8-12/tests/ref/fate/filter-trim-duration
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-trim-duration
rename to ffmpeg-2-8-12/tests/ref/fate/filter-trim-duration
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-trim-frame b/ffmpeg-2-8-12/tests/ref/fate/filter-trim-frame
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-trim-frame
rename to ffmpeg-2-8-12/tests/ref/fate/filter-trim-frame
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-trim-mixed b/ffmpeg-2-8-12/tests/ref/fate/filter-trim-mixed
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-trim-mixed
rename to ffmpeg-2-8-12/tests/ref/fate/filter-trim-mixed
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-trim-time b/ffmpeg-2-8-12/tests/ref/fate/filter-trim-time
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-trim-time
rename to ffmpeg-2-8-12/tests/ref/fate/filter-trim-time
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-unsharp b/ffmpeg-2-8-12/tests/ref/fate/filter-unsharp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-unsharp
rename to ffmpeg-2-8-12/tests/ref/fate/filter-unsharp
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-vectorscope_color b/ffmpeg-2-8-12/tests/ref/fate/filter-vectorscope_color
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-vectorscope_color
rename to ffmpeg-2-8-12/tests/ref/fate/filter-vectorscope_color
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-vectorscope_color2 b/ffmpeg-2-8-12/tests/ref/fate/filter-vectorscope_color2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-vectorscope_color2
rename to ffmpeg-2-8-12/tests/ref/fate/filter-vectorscope_color2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-vectorscope_color3 b/ffmpeg-2-8-12/tests/ref/fate/filter-vectorscope_color3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-vectorscope_color3
rename to ffmpeg-2-8-12/tests/ref/fate/filter-vectorscope_color3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-vectorscope_color4 b/ffmpeg-2-8-12/tests/ref/fate/filter-vectorscope_color4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-vectorscope_color4
rename to ffmpeg-2-8-12/tests/ref/fate/filter-vectorscope_color4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-vectorscope_gray b/ffmpeg-2-8-12/tests/ref/fate/filter-vectorscope_gray
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-vectorscope_gray
rename to ffmpeg-2-8-12/tests/ref/fate/filter-vectorscope_gray
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-vectorscope_xy b/ffmpeg-2-8-12/tests/ref/fate/filter-vectorscope_xy
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-vectorscope_xy
rename to ffmpeg-2-8-12/tests/ref/fate/filter-vectorscope_xy
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-vflip b/ffmpeg-2-8-12/tests/ref/fate/filter-vflip
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-vflip
rename to ffmpeg-2-8-12/tests/ref/fate/filter-vflip
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-vflip_crop b/ffmpeg-2-8-12/tests/ref/fate/filter-vflip_crop
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-vflip_crop
rename to ffmpeg-2-8-12/tests/ref/fate/filter-vflip_crop
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-vflip_vflip b/ffmpeg-2-8-12/tests/ref/fate/filter-vflip_vflip
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-vflip_vflip
rename to ffmpeg-2-8-12/tests/ref/fate/filter-vflip_vflip
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-w3fdif-complex b/ffmpeg-2-8-12/tests/ref/fate/filter-w3fdif-complex
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-w3fdif-complex
rename to ffmpeg-2-8-12/tests/ref/fate/filter-w3fdif-complex
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-w3fdif-simple b/ffmpeg-2-8-12/tests/ref/fate/filter-w3fdif-simple
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-w3fdif-simple
rename to ffmpeg-2-8-12/tests/ref/fate/filter-w3fdif-simple
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-waveform_column b/ffmpeg-2-8-12/tests/ref/fate/filter-waveform_column
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-waveform_column
rename to ffmpeg-2-8-12/tests/ref/fate/filter-waveform_column
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-waveform_envelope b/ffmpeg-2-8-12/tests/ref/fate/filter-waveform_envelope
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-waveform_envelope
rename to ffmpeg-2-8-12/tests/ref/fate/filter-waveform_envelope
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-waveform_row b/ffmpeg-2-8-12/tests/ref/fate/filter-waveform_row
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-waveform_row
rename to ffmpeg-2-8-12/tests/ref/fate/filter-waveform_row
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-waveform_uv b/ffmpeg-2-8-12/tests/ref/fate/filter-waveform_uv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-waveform_uv
rename to ffmpeg-2-8-12/tests/ref/fate/filter-waveform_uv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-yadif-mode0 b/ffmpeg-2-8-12/tests/ref/fate/filter-yadif-mode0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-yadif-mode0
rename to ffmpeg-2-8-12/tests/ref/fate/filter-yadif-mode0
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-yadif-mode1 b/ffmpeg-2-8-12/tests/ref/fate/filter-yadif-mode1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-yadif-mode1
rename to ffmpeg-2-8-12/tests/ref/fate/filter-yadif-mode1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-yadif10 b/ffmpeg-2-8-12/tests/ref/fate/filter-yadif10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-yadif10
rename to ffmpeg-2-8-12/tests/ref/fate/filter-yadif10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/filter-yadif16 b/ffmpeg-2-8-12/tests/ref/fate/filter-yadif16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/filter-yadif16
rename to ffmpeg-2-8-12/tests/ref/fate/filter-yadif16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/flic-af11-palette-change b/ffmpeg-2-8-12/tests/ref/fate/flic-af11-palette-change
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/flic-af11-palette-change
rename to ffmpeg-2-8-12/tests/ref/fate/flic-af11-palette-change
diff --git a/ffmpeg-2-8-11/tests/ref/fate/flic-af12 b/ffmpeg-2-8-12/tests/ref/fate/flic-af12
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/flic-af12
rename to ffmpeg-2-8-12/tests/ref/fate/flic-af12
diff --git a/ffmpeg-2-8-11/tests/ref/fate/flic-magiccarpet b/ffmpeg-2-8-12/tests/ref/fate/flic-magiccarpet
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/flic-magiccarpet
rename to ffmpeg-2-8-12/tests/ref/fate/flic-magiccarpet
diff --git a/ffmpeg-2-8-11/tests/ref/fate/force_key_frames b/ffmpeg-2-8-12/tests/ref/fate/force_key_frames
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/force_key_frames
rename to ffmpeg-2-8-12/tests/ref/fate/force_key_frames
diff --git a/ffmpeg-2-8-11/tests/ref/fate/fraps-v0 b/ffmpeg-2-8-12/tests/ref/fate/fraps-v0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/fraps-v0
rename to ffmpeg-2-8-12/tests/ref/fate/fraps-v0
diff --git a/ffmpeg-2-8-11/tests/ref/fate/fraps-v1 b/ffmpeg-2-8-12/tests/ref/fate/fraps-v1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/fraps-v1
rename to ffmpeg-2-8-12/tests/ref/fate/fraps-v1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/fraps-v2 b/ffmpeg-2-8-12/tests/ref/fate/fraps-v2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/fraps-v2
rename to ffmpeg-2-8-12/tests/ref/fate/fraps-v2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/fraps-v3 b/ffmpeg-2-8-12/tests/ref/fate/fraps-v3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/fraps-v3
rename to ffmpeg-2-8-12/tests/ref/fate/fraps-v3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/fraps-v4 b/ffmpeg-2-8-12/tests/ref/fate/fraps-v4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/fraps-v4
rename to ffmpeg-2-8-12/tests/ref/fate/fraps-v4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/fraps-v5 b/ffmpeg-2-8-12/tests/ref/fate/fraps-v5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/fraps-v5
rename to ffmpeg-2-8-12/tests/ref/fate/fraps-v5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/frwu b/ffmpeg-2-8-12/tests/ref/fate/frwu
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/frwu
rename to ffmpeg-2-8-12/tests/ref/fate/frwu
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g2m2 b/ffmpeg-2-8-12/tests/ref/fate/g2m2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g2m2
rename to ffmpeg-2-8-12/tests/ref/fate/g2m2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g2m3 b/ffmpeg-2-8-12/tests/ref/fate/g2m3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g2m3
rename to ffmpeg-2-8-12/tests/ref/fate/g2m3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g2m4 b/ffmpeg-2-8-12/tests/ref/fate/g2m4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g2m4
rename to ffmpeg-2-8-12/tests/ref/fate/g2m4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g722-encode b/ffmpeg-2-8-12/tests/ref/fate/g722-encode
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g722-encode
rename to ffmpeg-2-8-12/tests/ref/fate/g722-encode
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g722dec-1 b/ffmpeg-2-8-12/tests/ref/fate/g722dec-1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g722dec-1
rename to ffmpeg-2-8-12/tests/ref/fate/g722dec-1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-1 b/ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-1
rename to ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-2 b/ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-2
rename to ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-3 b/ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-3
rename to ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-4 b/ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-4
rename to ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-5 b/ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-5
rename to ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-6 b/ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-6
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-6
rename to ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-6
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-7 b/ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-7
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-7
rename to ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-7
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-8 b/ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g723_1-dec-8
rename to ffmpeg-2-8-12/tests/ref/fate/g723_1-dec-8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g726-encode-2bit b/ffmpeg-2-8-12/tests/ref/fate/g726-encode-2bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g726-encode-2bit
rename to ffmpeg-2-8-12/tests/ref/fate/g726-encode-2bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g726-encode-3bit b/ffmpeg-2-8-12/tests/ref/fate/g726-encode-3bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g726-encode-3bit
rename to ffmpeg-2-8-12/tests/ref/fate/g726-encode-3bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g726-encode-4bit b/ffmpeg-2-8-12/tests/ref/fate/g726-encode-4bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g726-encode-4bit
rename to ffmpeg-2-8-12/tests/ref/fate/g726-encode-4bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g726-encode-5bit b/ffmpeg-2-8-12/tests/ref/fate/g726-encode-5bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g726-encode-5bit
rename to ffmpeg-2-8-12/tests/ref/fate/g726-encode-5bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g729-0 b/ffmpeg-2-8-12/tests/ref/fate/g729-0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g729-0
rename to ffmpeg-2-8-12/tests/ref/fate/g729-0
diff --git a/ffmpeg-2-8-11/tests/ref/fate/g729-1 b/ffmpeg-2-8-12/tests/ref/fate/g729-1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/g729-1
rename to ffmpeg-2-8-12/tests/ref/fate/g729-1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/gapless-mp3 b/ffmpeg-2-8-12/tests/ref/fate/gapless-mp3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/gapless-mp3
rename to ffmpeg-2-8-12/tests/ref/fate/gapless-mp3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/gif-color b/ffmpeg-2-8-12/tests/ref/fate/gif-color
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/gif-color
rename to ffmpeg-2-8-12/tests/ref/fate/gif-color
diff --git a/ffmpeg-2-8-11/tests/ref/fate/gif-demux b/ffmpeg-2-8-12/tests/ref/fate/gif-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/gif-demux
rename to ffmpeg-2-8-12/tests/ref/fate/gif-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/gif-disposal-background b/ffmpeg-2-8-12/tests/ref/fate/gif-disposal-background
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/gif-disposal-background
rename to ffmpeg-2-8-12/tests/ref/fate/gif-disposal-background
diff --git a/ffmpeg-2-8-11/tests/ref/fate/gif-disposal-restore b/ffmpeg-2-8-12/tests/ref/fate/gif-disposal-restore
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/gif-disposal-restore
rename to ffmpeg-2-8-12/tests/ref/fate/gif-disposal-restore
diff --git a/ffmpeg-2-8-11/tests/ref/fate/gif-gray b/ffmpeg-2-8-12/tests/ref/fate/gif-gray
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/gif-gray
rename to ffmpeg-2-8-12/tests/ref/fate/gif-gray
diff --git a/ffmpeg-2-8-11/tests/ref/fate/gifenc-bgr4_byte b/ffmpeg-2-8-12/tests/ref/fate/gifenc-bgr4_byte
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/gifenc-bgr4_byte
rename to ffmpeg-2-8-12/tests/ref/fate/gifenc-bgr4_byte
diff --git a/ffmpeg-2-8-11/tests/ref/fate/gifenc-bgr8 b/ffmpeg-2-8-12/tests/ref/fate/gifenc-bgr8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/gifenc-bgr8
rename to ffmpeg-2-8-12/tests/ref/fate/gifenc-bgr8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/gifenc-gray b/ffmpeg-2-8-12/tests/ref/fate/gifenc-gray
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/gifenc-gray
rename to ffmpeg-2-8-12/tests/ref/fate/gifenc-gray
diff --git a/ffmpeg-2-8-11/tests/ref/fate/gifenc-pal8 b/ffmpeg-2-8-12/tests/ref/fate/gifenc-pal8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/gifenc-pal8
rename to ffmpeg-2-8-12/tests/ref/fate/gifenc-pal8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/gifenc-rgb4_byte b/ffmpeg-2-8-12/tests/ref/fate/gifenc-rgb4_byte
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/gifenc-rgb4_byte
rename to ffmpeg-2-8-12/tests/ref/fate/gifenc-rgb4_byte
diff --git a/ffmpeg-2-8-11/tests/ref/fate/gifenc-rgb8 b/ffmpeg-2-8-12/tests/ref/fate/gifenc-rgb8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/gifenc-rgb8
rename to ffmpeg-2-8-12/tests/ref/fate/gifenc-rgb8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/gsm-ms b/ffmpeg-2-8-12/tests/ref/fate/gsm-ms
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/gsm-ms
rename to ffmpeg-2-8-12/tests/ref/fate/gsm-ms
diff --git a/ffmpeg-2-8-11/tests/ref/fate/gsm-toast b/ffmpeg-2-8-12/tests/ref/fate/gsm-toast
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/gsm-toast
rename to ffmpeg-2-8-12/tests/ref/fate/gsm-toast
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-bsf-mp4toannexb b/ffmpeg-2-8-12/tests/ref/fate/h264-bsf-mp4toannexb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-bsf-mp4toannexb
rename to ffmpeg-2-8-12/tests/ref/fate/h264-bsf-mp4toannexb
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-aud_mw_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-aud_mw_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-aud_mw_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-aud_mw_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ba1_ft_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ba1_ft_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ba1_ft_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ba1_ft_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ba1_sony_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ba1_sony_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ba1_sony_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ba1_sony_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ba2_sony_f b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ba2_sony_f
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ba2_sony_f
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ba2_sony_f
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ba3_sva_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ba3_sva_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ba3_sva_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ba3_sva_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ba_mw_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ba_mw_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ba_mw_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ba_mw_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-bamq1_jvc_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-bamq1_jvc_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-bamq1_jvc_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-bamq1_jvc_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-bamq2_jvc_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-bamq2_jvc_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-bamq2_jvc_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-bamq2_jvc_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-banm_mw_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-banm_mw_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-banm_mw_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-banm_mw_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-basqp1_sony_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-basqp1_sony_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-basqp1_sony_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-basqp1_sony_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caba1_sony_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caba1_sony_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caba1_sony_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caba1_sony_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caba1_sva_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caba1_sva_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caba1_sva_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caba1_sva_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caba2_sony_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caba2_sony_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caba2_sony_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caba2_sony_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caba2_sva_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caba2_sva_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caba2_sva_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caba2_sva_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caba3_sony_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caba3_sony_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caba3_sony_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caba3_sony_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caba3_sva_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caba3_sva_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caba3_sva_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caba3_sva_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caba3_toshiba_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caba3_toshiba_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caba3_toshiba_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caba3_toshiba_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabac_mot_fld0_full b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabac_mot_fld0_full
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabac_mot_fld0_full
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabac_mot_fld0_full
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabac_mot_frm0_full b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabac_mot_frm0_full
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabac_mot_frm0_full
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabac_mot_frm0_full
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabac_mot_mbaff0_full b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabac_mot_mbaff0_full
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabac_mot_mbaff0_full
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabac_mot_mbaff0_full
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabac_mot_picaff0_full b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabac_mot_picaff0_full
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabac_mot_picaff0_full
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabac_mot_picaff0_full
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabaci3_sony_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabaci3_sony_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabaci3_sony_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabaci3_sony_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabast3_sony_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabast3_sony_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabast3_sony_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabast3_sony_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabastbr3_sony_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabastbr3_sony_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabastbr3_sony_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabastbr3_sony_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabref3_sand_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabref3_sand_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cabref3_sand_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cabref3_sand_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cacqp3_sony_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cacqp3_sony_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cacqp3_sony_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cacqp3_sony_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cafi1_sva_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cafi1_sva_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cafi1_sva_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cafi1_sva_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cama1_sony_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cama1_sony_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cama1_sony_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cama1_sony_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cama1_toshiba_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cama1_toshiba_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cama1_toshiba_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cama1_toshiba_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cama1_vtc_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cama1_vtc_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cama1_vtc_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cama1_vtc_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cama2_vtc_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cama2_vtc_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cama2_vtc_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cama2_vtc_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cama3_sand_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cama3_sand_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cama3_sand_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cama3_sand_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cama3_vtc_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cama3_vtc_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cama3_vtc_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cama3_vtc_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-camaci3_sony_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-camaci3_sony_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-camaci3_sony_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-camaci3_sony_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-camanl1_toshiba_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-camanl1_toshiba_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-camanl1_toshiba_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-camanl1_toshiba_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-camanl2_toshiba_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-camanl2_toshiba_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-camanl2_toshiba_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-camanl2_toshiba_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-camanl3_sand_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-camanl3_sand_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-camanl3_sand_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-camanl3_sand_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-camasl3_sony_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-camasl3_sony_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-camasl3_sony_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-camasl3_sony_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-camp_mot_mbaff_l30 b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-camp_mot_mbaff_l30
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-camp_mot_mbaff_l30
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-camp_mot_mbaff_l30
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-camp_mot_mbaff_l31 b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-camp_mot_mbaff_l31
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-camp_mot_mbaff_l31
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-camp_mot_mbaff_l31
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl1_sony_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl1_sony_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl1_sony_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl1_sony_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl1_sva_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl1_sva_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl1_sva_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl1_sva_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl1_toshiba_g b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl1_toshiba_g
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl1_toshiba_g
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl1_toshiba_g
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl2_sony_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl2_sony_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl2_sony_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl2_sony_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl2_sva_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl2_sva_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl2_sva_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl2_sva_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl3_sony_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl3_sony_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl3_sony_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl3_sony_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl3_sva_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl3_sva_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl3_sva_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl3_sva_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl4_sva_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl4_sva_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canl4_sva_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canl4_sva_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canlma2_sony_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canlma2_sony_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canlma2_sony_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canlma2_sony_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canlma3_sony_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canlma3_sony_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-canlma3_sony_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-canlma3_sony_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-capa1_toshiba_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-capa1_toshiba_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-capa1_toshiba_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-capa1_toshiba_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-capama3_sand_f b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-capama3_sand_f
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-capama3_sand_f
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-capama3_sand_f
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-capcm1_sand_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-capcm1_sand_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-capcm1_sand_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-capcm1_sand_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-capcmnl1_sand_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-capcmnl1_sand_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-capcmnl1_sand_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-capcmnl1_sand_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-capm3_sony_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-capm3_sony_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-capm3_sony_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-capm3_sony_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caqp1_sony_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caqp1_sony_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-caqp1_sony_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-caqp1_sony_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cavlc_mot_fld0_full_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cavlc_mot_fld0_full_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cavlc_mot_fld0_full_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cavlc_mot_fld0_full_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cavlc_mot_frm0_full_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cavlc_mot_frm0_full_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cavlc_mot_frm0_full_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cavlc_mot_frm0_full_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cavlc_mot_mbaff0_full_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cavlc_mot_mbaff0_full_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cavlc_mot_mbaff0_full_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cavlc_mot_mbaff0_full_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cavlc_mot_picaff0_full_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cavlc_mot_picaff0_full_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cavlc_mot_picaff0_full_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cavlc_mot_picaff0_full_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cawp1_toshiba_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cawp1_toshiba_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cawp1_toshiba_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cawp1_toshiba_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cawp5_toshiba_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cawp5_toshiba_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cawp5_toshiba_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cawp5_toshiba_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ci1_ft_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ci1_ft_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ci1_ft_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ci1_ft_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ci_mw_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ci_mw_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ci_mw_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ci_mw_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvbs3_sony_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvbs3_sony_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvbs3_sony_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvbs3_sony_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvcanlma2_sony_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvcanlma2_sony_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvcanlma2_sony_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvcanlma2_sony_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvfc1_sony_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvfc1_sony_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvfc1_sony_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvfc1_sony_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvfi1_sony_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvfi1_sony_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvfi1_sony_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvfi1_sony_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvfi1_sva_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvfi1_sva_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvfi1_sva_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvfi1_sva_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvfi2_sony_h b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvfi2_sony_h
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvfi2_sony_h
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvfi2_sony_h
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvfi2_sva_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvfi2_sva_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvfi2_sva_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvfi2_sva_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvma1_sony_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvma1_sony_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvma1_sony_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvma1_sony_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvma1_toshiba_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvma1_toshiba_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvma1_toshiba_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvma1_toshiba_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvmanl1_toshiba_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvmanl1_toshiba_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvmanl1_toshiba_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvmanl1_toshiba_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvmanl2_toshiba_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvmanl2_toshiba_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvmanl2_toshiba_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvmanl2_toshiba_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvmapaqp3_sony_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvmapaqp3_sony_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvmapaqp3_sony_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvmapaqp3_sony_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvmaqp2_sony_g b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvmaqp2_sony_g
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvmaqp2_sony_g
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvmaqp2_sony_g
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvmaqp3_sony_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvmaqp3_sony_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvmaqp3_sony_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvmaqp3_sony_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvmp_mot_fld_l30_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvmp_mot_fld_l30_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvmp_mot_fld_l30_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvmp_mot_fld_l30_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvmp_mot_frm_l31_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvmp_mot_frm_l31_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvmp_mot_frm_l31_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvmp_mot_frm_l31_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvnlfi1_sony_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvnlfi1_sony_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvnlfi1_sony_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvnlfi1_sony_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvnlfi2_sony_h b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvnlfi2_sony_h
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvnlfi2_sony_h
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvnlfi2_sony_h
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvpa1_toshiba_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvpa1_toshiba_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvpa1_toshiba_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvpa1_toshiba_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvpcmnl1_sva_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvpcmnl1_sva_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvpcmnl1_sva_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvpcmnl1_sva_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvpcmnl2_sva_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvpcmnl2_sva_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvpcmnl2_sva_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvpcmnl2_sva_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvwp1_toshiba_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvwp1_toshiba_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvwp1_toshiba_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvwp1_toshiba_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvwp2_toshiba_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvwp2_toshiba_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvwp2_toshiba_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvwp2_toshiba_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvwp3_toshiba_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvwp3_toshiba_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvwp3_toshiba_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvwp3_toshiba_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvwp5_toshiba_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvwp5_toshiba_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-cvwp5_toshiba_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-cvwp5_toshiba_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-fi1_sony_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-fi1_sony_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-fi1_sony_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-fi1_sony_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-alphaconformanceg b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-alphaconformanceg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-alphaconformanceg
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-alphaconformanceg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-bcrm_freh10 b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-bcrm_freh10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-bcrm_freh10
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-bcrm_freh10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-brcm_freh11 b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-brcm_freh11
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-brcm_freh11
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-brcm_freh11
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-brcm_freh3 b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-brcm_freh3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-brcm_freh3
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-brcm_freh3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-brcm_freh4 b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-brcm_freh4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-brcm_freh4
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-brcm_freh4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-brcm_freh5 b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-brcm_freh5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-brcm_freh5
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-brcm_freh5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-brcm_freh8 b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-brcm_freh8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-brcm_freh8
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-brcm_freh8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-brcm_freh9 b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-brcm_freh9
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-brcm_freh9
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-brcm_freh9
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-freh12_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-freh12_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-freh12_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-freh12_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-freh1_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-freh1_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-freh1_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-freh1_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-freh2_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-freh2_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-freh2_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-freh2_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-freh6 b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-freh6
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-freh6
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-freh6
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-freh7_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-freh7_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-freh7_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-freh7_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-frext01_jvc_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-frext01_jvc_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-frext01_jvc_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-frext01_jvc_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-frext02_jvc_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-frext02_jvc_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-frext02_jvc_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-frext02_jvc_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-frext1_panasonic_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-frext1_panasonic_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-frext1_panasonic_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-frext1_panasonic_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-frext2_panasonic_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-frext2_panasonic_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-frext2_panasonic_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-frext2_panasonic_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-frext3_panasonic_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-frext3_panasonic_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-frext3_panasonic_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-frext3_panasonic_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-frext4_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-frext4_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-frext4_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-frext4_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-frext_mmco4_sony_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-frext_mmco4_sony_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-frext_mmco4_sony_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-frext_mmco4_sony_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hcaff1_hhi_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hcaff1_hhi_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hcaff1_hhi_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hcaff1_hhi_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hcafr1_hhi_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hcafr1_hhi_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hcafr1_hhi_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hcafr1_hhi_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hcafr2_hhi_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hcafr2_hhi_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hcafr2_hhi_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hcafr2_hhi_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hcafr3_hhi_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hcafr3_hhi_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hcafr3_hhi_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hcafr3_hhi_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hcafr4_hhi_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hcafr4_hhi_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hcafr4_hhi_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hcafr4_hhi_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hcamff1_hhi_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hcamff1_hhi_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hcamff1_hhi_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hcamff1_hhi_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hi422fr10_sony_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hi422fr10_sony_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hi422fr10_sony_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hi422fr10_sony_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hi422fr13_sony_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hi422fr13_sony_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hi422fr13_sony_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hi422fr13_sony_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hi422fr1_sony_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hi422fr1_sony_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hi422fr1_sony_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hi422fr1_sony_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hi422fr6_sony_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hi422fr6_sony_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hi422fr6_sony_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hi422fr6_sony_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpca_brcm_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpca_brcm_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpca_brcm_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpca_brcm_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcadq_brcm_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcadq_brcm_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcadq_brcm_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcadq_brcm_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcafl_bcrm_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcafl_bcrm_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcafl_bcrm_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcafl_bcrm_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcaflnl_bcrm_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcaflnl_bcrm_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcaflnl_bcrm_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcaflnl_bcrm_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcalq_brcm_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcalq_brcm_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcalq_brcm_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcalq_brcm_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcamapalq_bcrm_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcamapalq_bcrm_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcamapalq_bcrm_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcamapalq_bcrm_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcamolq_brcm_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcamolq_brcm_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcamolq_brcm_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcamolq_brcm_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcanl_brcm_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcanl_brcm_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcanl_brcm_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcanl_brcm_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcaq2lq_brcm_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcaq2lq_brcm_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcaq2lq_brcm_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcaq2lq_brcm_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcv_brcm_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcv_brcm_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcv_brcm_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcv_brcm_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcvfl_bcrm_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcvfl_bcrm_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcvfl_bcrm_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcvfl_bcrm_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcvflnl_bcrm_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcvflnl_bcrm_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcvflnl_bcrm_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcvflnl_bcrm_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcvmolq_brcm_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcvmolq_brcm_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcvmolq_brcm_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcvmolq_brcm_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcvnl_brcm_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcvnl_brcm_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-hpcvnl_brcm_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-hpcvnl_brcm_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph10i1_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph10i1_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph10i1_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph10i1_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph10i2_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph10i2_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph10i2_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph10i2_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph10i3_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph10i3_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph10i3_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph10i3_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph10i4_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph10i4_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph10i4_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph10i4_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph10i5_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph10i5_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph10i5_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph10i5_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph10i6_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph10i6_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph10i6_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph10i6_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph10i7_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph10i7_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph10i7_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph10i7_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph422i1_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph422i1_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph422i1_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph422i1_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph422i2_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph422i2_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph422i2_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph422i2_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph422i3_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph422i3_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph422i3_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph422i3_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph422i4_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph422i4_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph422i4_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph422i4_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph422i5_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph422i5_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph422i5_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph422i5_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph422i6_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph422i6_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph422i6_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph422i6_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph422i7_panasonic_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph422i7_panasonic_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-frext-pph422i7_panasonic_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-frext-pph422i7_panasonic_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-hcbp2_hhi_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-hcbp2_hhi_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-hcbp2_hhi_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-hcbp2_hhi_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-hcmp1_hhi_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-hcmp1_hhi_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-hcmp1_hhi_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-hcmp1_hhi_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ls_sva_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ls_sva_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-ls_sva_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-ls_sva_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-midr_mw_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-midr_mw_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-midr_mw_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-midr_mw_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mps_mw_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mps_mw_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mps_mw_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mps_mw_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr1_bt_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr1_bt_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr1_bt_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr1_bt_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr1_mw_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr1_mw_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr1_mw_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr1_mw_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr2_mw_a b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr2_mw_a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr2_mw_a
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr2_mw_a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr2_tandberg_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr2_tandberg_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr2_tandberg_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr2_tandberg_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr3_tandberg_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr3_tandberg_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr3_tandberg_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr3_tandberg_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr4_tandberg_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr4_tandberg_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr4_tandberg_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr4_tandberg_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr5_tandberg_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr5_tandberg_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr5_tandberg_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr5_tandberg_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr6_bt_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr6_bt_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr6_bt_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr6_bt_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr7_bt_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr7_bt_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr7_bt_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr7_bt_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr8_bt_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr8_bt_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr8_bt_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr8_bt_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr9_bt_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr9_bt_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mr9_bt_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mr9_bt_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mv1_brcm_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mv1_brcm_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-mv1_brcm_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-mv1_brcm_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-nl1_sony_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-nl1_sony_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-nl1_sony_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-nl1_sony_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-nl2_sony_h b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-nl2_sony_h
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-nl2_sony_h
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-nl2_sony_h
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-nl3_sva_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-nl3_sva_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-nl3_sva_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-nl3_sva_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-nlmq1_jvc_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-nlmq1_jvc_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-nlmq1_jvc_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-nlmq1_jvc_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-nlmq2_jvc_c b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-nlmq2_jvc_c
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-nlmq2_jvc_c
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-nlmq2_jvc_c
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-nrf_mw_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-nrf_mw_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-nrf_mw_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-nrf_mw_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sharp_mp_field_1_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sharp_mp_field_1_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sharp_mp_field_1_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sharp_mp_field_1_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sharp_mp_field_2_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sharp_mp_field_2_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sharp_mp_field_2_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sharp_mp_field_2_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sharp_mp_field_3_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sharp_mp_field_3_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sharp_mp_field_3_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sharp_mp_field_3_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sharp_mp_paff_1r2 b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sharp_mp_paff_1r2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sharp_mp_paff_1r2
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sharp_mp_paff_1r2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sharp_mp_paff_2r b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sharp_mp_paff_2r
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sharp_mp_paff_2r
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sharp_mp_paff_2r
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sl1_sva_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sl1_sva_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sl1_sva_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sl1_sva_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sva_ba1_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sva_ba1_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sva_ba1_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sva_ba1_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sva_ba2_d b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sva_ba2_d
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sva_ba2_d
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sva_ba2_d
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sva_base_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sva_base_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sva_base_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sva_base_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sva_cl1_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sva_cl1_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sva_cl1_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sva_cl1_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sva_fm1_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sva_fm1_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sva_fm1_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sva_fm1_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sva_nl1_b b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sva_nl1_b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sva_nl1_b
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sva_nl1_b
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sva_nl2_e b/ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sva_nl2_e
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-conformance-sva_nl2_e
rename to ffmpeg-2-8-12/tests/ref/fate/h264-conformance-sva_nl2_e
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-crop-to-container b/ffmpeg-2-8-12/tests/ref/fate/h264-crop-to-container
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-crop-to-container
rename to ffmpeg-2-8-12/tests/ref/fate/h264-crop-to-container
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-direct-bff b/ffmpeg-2-8-12/tests/ref/fate/h264-direct-bff
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-direct-bff
rename to ffmpeg-2-8-12/tests/ref/fate/h264-direct-bff
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-extreme-plane-pred b/ffmpeg-2-8-12/tests/ref/fate/h264-extreme-plane-pred
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-extreme-plane-pred
rename to ffmpeg-2-8-12/tests/ref/fate/h264-extreme-plane-pred
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-interlace-crop b/ffmpeg-2-8-12/tests/ref/fate/h264-interlace-crop
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-interlace-crop
rename to ffmpeg-2-8-12/tests/ref/fate/h264-interlace-crop
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-lossless b/ffmpeg-2-8-12/tests/ref/fate/h264-lossless
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-lossless
rename to ffmpeg-2-8-12/tests/ref/fate/h264-lossless
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-reinit-large_420_8-to-small_420_8 b/ffmpeg-2-8-12/tests/ref/fate/h264-reinit-large_420_8-to-small_420_8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-reinit-large_420_8-to-small_420_8
rename to ffmpeg-2-8-12/tests/ref/fate/h264-reinit-large_420_8-to-small_420_8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-reinit-small_420_8-to-large_444_10 b/ffmpeg-2-8-12/tests/ref/fate/h264-reinit-small_420_8-to-large_444_10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-reinit-small_420_8-to-large_444_10
rename to ffmpeg-2-8-12/tests/ref/fate/h264-reinit-small_420_8-to-large_444_10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-reinit-small_420_9-to-small_420_8 b/ffmpeg-2-8-12/tests/ref/fate/h264-reinit-small_420_9-to-small_420_8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-reinit-small_420_9-to-small_420_8
rename to ffmpeg-2-8-12/tests/ref/fate/h264-reinit-small_420_9-to-small_420_8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/h264-reinit-small_422_9-to-small_420_9 b/ffmpeg-2-8-12/tests/ref/fate/h264-reinit-small_422_9-to-small_420_9
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/h264-reinit-small_422_9-to-small_420_9
rename to ffmpeg-2-8-12/tests/ref/fate/h264-reinit-small_422_9-to-small_420_9
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hap-chunk b/ffmpeg-2-8-12/tests/ref/fate/hap-chunk
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hap-chunk
rename to ffmpeg-2-8-12/tests/ref/fate/hap-chunk
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hap1 b/ffmpeg-2-8-12/tests/ref/fate/hap1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hap1
rename to ffmpeg-2-8-12/tests/ref/fate/hap1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hap5 b/ffmpeg-2-8-12/tests/ref/fate/hap5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hap5
rename to ffmpeg-2-8-12/tests/ref/fate/hap5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hapy b/ffmpeg-2-8-12/tests/ref/fate/hapy
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hapy
rename to ffmpeg-2-8-12/tests/ref/fate/hapy
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ADJUST_IPRED_ANGLE_A_RExt_Mitsubishi_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMP_A_Samsung_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMP_A_Samsung_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMP_A_Samsung_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMP_A_Samsung_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMP_A_Samsung_6 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMP_A_Samsung_6
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMP_A_Samsung_6
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMP_A_Samsung_6
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMP_B_Samsung_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMP_B_Samsung_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMP_B_Samsung_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMP_B_Samsung_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMP_B_Samsung_6 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMP_B_Samsung_6
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMP_B_Samsung_6
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMP_B_Samsung_6
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMP_D_Hisilicon b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMP_D_Hisilicon
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMP_D_Hisilicon
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMP_D_Hisilicon
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMP_E_Hisilicon b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMP_E_Hisilicon
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMP_E_Hisilicon
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMP_E_Hisilicon
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMP_F_Hisilicon_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMP_F_Hisilicon_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMP_F_Hisilicon_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMP_F_Hisilicon_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMVP_A_MTK_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMVP_A_MTK_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMVP_A_MTK_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMVP_A_MTK_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMVP_B_MTK_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMVP_B_MTK_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMVP_B_MTK_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMVP_B_MTK_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMVP_C_Samsung_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMVP_C_Samsung_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMVP_C_Samsung_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMVP_C_Samsung_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMVP_C_Samsung_6 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMVP_C_Samsung_6
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-AMVP_C_Samsung_6
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-AMVP_C_Samsung_6
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-BUMPING_A_ericsson_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-BUMPING_A_ericsson_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-BUMPING_A_ericsson_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-BUMPING_A_ericsson_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_A_SHARP_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_A_SHARP_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_A_SHARP_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_A_SHARP_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_B_SHARP_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_B_SHARP_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_B_SHARP_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_B_SHARP_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_C_SHARP_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_C_SHARP_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_C_SHARP_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_C_SHARP_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_D_SHARP_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_D_SHARP_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_D_SHARP_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_D_SHARP_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_E_SHARP_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_E_SHARP_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_E_SHARP_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_E_SHARP_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_F_SHARP_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_F_SHARP_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_F_SHARP_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_F_SHARP_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_G_SHARP_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_G_SHARP_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_G_SHARP_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_G_SHARP_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_H_SHARP_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_H_SHARP_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CAINIT_H_SHARP_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CAINIT_H_SHARP_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CIP_A_Panasonic_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CIP_A_Panasonic_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CIP_A_Panasonic_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CIP_A_Panasonic_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CIP_C_Panasonic_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CIP_C_Panasonic_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CIP_C_Panasonic_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CIP_C_Panasonic_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CONFWIN_A_Sony_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CONFWIN_A_Sony_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-CONFWIN_A_Sony_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-CONFWIN_A_Sony_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_A_MAIN10_VIXS_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_A_MAIN10_VIXS_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_A_MAIN10_VIXS_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_A_MAIN10_VIXS_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_A_SONY_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_A_SONY_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_A_SONY_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_A_SONY_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_B_SONY_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_B_SONY_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_B_SONY_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_B_SONY_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_C_SONY_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_C_SONY_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_C_SONY_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_C_SONY_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_D_VIXS_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_E_VIXS_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_F_VIXS_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DBLK_G_VIXS_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DELTAQP_A_BRCM_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DELTAQP_A_BRCM_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DELTAQP_A_BRCM_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DELTAQP_A_BRCM_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DELTAQP_B_SONY_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DELTAQP_B_SONY_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DELTAQP_B_SONY_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DELTAQP_B_SONY_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DELTAQP_C_SONY_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DELTAQP_C_SONY_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DELTAQP_C_SONY_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DELTAQP_C_SONY_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DSLICE_A_HHI_5 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DSLICE_A_HHI_5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DSLICE_A_HHI_5
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DSLICE_A_HHI_5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DSLICE_B_HHI_5 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DSLICE_B_HHI_5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DSLICE_B_HHI_5
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DSLICE_B_HHI_5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DSLICE_C_HHI_5 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DSLICE_C_HHI_5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-DSLICE_C_HHI_5
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-DSLICE_C_HHI_5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ENTP_A_Qualcomm_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ENTP_A_Qualcomm_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ENTP_A_Qualcomm_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ENTP_A_Qualcomm_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ENTP_B_Qualcomm_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ENTP_B_Qualcomm_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ENTP_B_Qualcomm_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ENTP_B_Qualcomm_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ENTP_C_Qualcomm_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ENTP_C_Qualcomm_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ENTP_C_Qualcomm_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ENTP_C_Qualcomm_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-EXT_A_ericsson_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-EXT_A_ericsson_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-EXT_A_ericsson_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-EXT_A_ericsson_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-FILLER_A_Sony_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-FILLER_A_Sony_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-FILLER_A_Sony_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-FILLER_A_Sony_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-HRD_A_Fujitsu_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-HRD_A_Fujitsu_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-HRD_A_Fujitsu_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-HRD_A_Fujitsu_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-HRD_A_Fujitsu_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-HRD_A_Fujitsu_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-HRD_A_Fujitsu_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-HRD_A_Fujitsu_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-INITQP_A_Sony_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-INITQP_A_Sony_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-INITQP_A_Sony_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-INITQP_A_Sony_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-INITQP_B_Sony_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-INITQP_B_Sony_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-INITQP_B_Sony_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-INITQP_B_Sony_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-IPCM_A_RExt_NEC b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-IPCM_A_RExt_NEC
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-IPCM_A_RExt_NEC
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-IPCM_A_RExt_NEC
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-IPCM_B_RExt_NEC b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-IPCM_B_RExt_NEC
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-IPCM_B_RExt_NEC
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-IPCM_B_RExt_NEC
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-IPRED_A_docomo_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-IPRED_A_docomo_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-IPRED_A_docomo_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-IPRED_A_docomo_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-IPRED_B_Nokia_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-IPRED_B_Nokia_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-IPRED_B_Nokia_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-IPRED_B_Nokia_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-IPRED_C_Mitsubishi_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-IPRED_C_Mitsubishi_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-IPRED_C_Mitsubishi_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-IPRED_C_Mitsubishi_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-LS_A_Orange_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-LS_A_Orange_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-LS_A_Orange_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-LS_A_Orange_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-LS_B_ORANGE_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-LS_B_ORANGE_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-LS_B_ORANGE_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-LS_B_ORANGE_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-LTRPSPS_A_Qualcomm_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-LTRPSPS_A_Qualcomm_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-LTRPSPS_A_Qualcomm_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-LTRPSPS_A_Qualcomm_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MAXBINS_A_TI_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MAXBINS_A_TI_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MAXBINS_A_TI_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MAXBINS_A_TI_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MAXBINS_B_TI_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MAXBINS_B_TI_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MAXBINS_B_TI_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MAXBINS_B_TI_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MAXBINS_C_TI_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MAXBINS_C_TI_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MAXBINS_C_TI_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MAXBINS_C_TI_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MERGE_A_TI_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MERGE_A_TI_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MERGE_A_TI_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MERGE_A_TI_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MERGE_B_TI_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MERGE_B_TI_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MERGE_B_TI_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MERGE_B_TI_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MERGE_C_TI_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MERGE_C_TI_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MERGE_C_TI_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MERGE_C_TI_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MERGE_D_TI_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MERGE_D_TI_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MERGE_D_TI_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MERGE_D_TI_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MERGE_E_TI_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MERGE_E_TI_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MERGE_E_TI_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MERGE_E_TI_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MERGE_F_MTK_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MERGE_F_MTK_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MERGE_F_MTK_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MERGE_F_MTK_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MERGE_G_HHI_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MERGE_G_HHI_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MERGE_G_HHI_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MERGE_G_HHI_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MVCLIP_A_qualcomm_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MVCLIP_A_qualcomm_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MVCLIP_A_qualcomm_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MVCLIP_A_qualcomm_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MVDL1ZERO_A_docomo_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MVDL1ZERO_A_docomo_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MVDL1ZERO_A_docomo_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MVDL1ZERO_A_docomo_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MVEDGE_A_qualcomm_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MVEDGE_A_qualcomm_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-MVEDGE_A_qualcomm_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-MVEDGE_A_qualcomm_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-Main_422_10_A_RExt_Sony_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-Main_422_10_A_RExt_Sony_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-Main_422_10_A_RExt_Sony_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-Main_422_10_A_RExt_Sony_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-Main_422_10_B_RExt_Sony_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-Main_422_10_B_RExt_Sony_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-Main_422_10_B_RExt_Sony_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-Main_422_10_B_RExt_Sony_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-NUT_A_ericsson_5 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-NUT_A_ericsson_5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-NUT_A_ericsson_5
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-NUT_A_ericsson_5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-NoOutPrior_A_Qualcomm_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-NoOutPrior_A_Qualcomm_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-NoOutPrior_A_Qualcomm_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-NoOutPrior_A_Qualcomm_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-NoOutPrior_B_Qualcomm_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-NoOutPrior_B_Qualcomm_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-NoOutPrior_B_Qualcomm_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-NoOutPrior_B_Qualcomm_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-OPFLAG_A_Qualcomm_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-OPFLAG_A_Qualcomm_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-OPFLAG_A_Qualcomm_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-OPFLAG_A_Qualcomm_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-OPFLAG_B_Qualcomm_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-OPFLAG_B_Qualcomm_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-OPFLAG_B_Qualcomm_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-OPFLAG_B_Qualcomm_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-OPFLAG_C_Qualcomm_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-OPFLAG_C_Qualcomm_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-OPFLAG_C_Qualcomm_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-OPFLAG_C_Qualcomm_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PERSIST_RPARAM_A_RExt_Sony_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PERSIST_RPARAM_A_RExt_Sony_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PERSIST_RPARAM_A_RExt_Sony_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PERSIST_RPARAM_A_RExt_Sony_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PICSIZE_A_Bossen_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PICSIZE_A_Bossen_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PICSIZE_A_Bossen_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PICSIZE_A_Bossen_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PICSIZE_B_Bossen_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PICSIZE_B_Bossen_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PICSIZE_B_Bossen_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PICSIZE_B_Bossen_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PICSIZE_C_Bossen_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PICSIZE_C_Bossen_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PICSIZE_C_Bossen_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PICSIZE_C_Bossen_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PICSIZE_D_Bossen_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PICSIZE_D_Bossen_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PICSIZE_D_Bossen_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PICSIZE_D_Bossen_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PMERGE_A_TI_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PMERGE_A_TI_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PMERGE_A_TI_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PMERGE_A_TI_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PMERGE_B_TI_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PMERGE_B_TI_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PMERGE_B_TI_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PMERGE_B_TI_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PMERGE_C_TI_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PMERGE_C_TI_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PMERGE_C_TI_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PMERGE_C_TI_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PMERGE_D_TI_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PMERGE_D_TI_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PMERGE_D_TI_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PMERGE_D_TI_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PMERGE_E_TI_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PMERGE_E_TI_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PMERGE_E_TI_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PMERGE_E_TI_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-POC_A_Bossen_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-POC_A_Bossen_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-POC_A_Bossen_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-POC_A_Bossen_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PPS_A_qualcomm_7 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PPS_A_qualcomm_7
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PPS_A_qualcomm_7
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PPS_A_qualcomm_7
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PS_A_VIDYO_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PS_A_VIDYO_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PS_A_VIDYO_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PS_A_VIDYO_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PS_B_VIDYO_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PS_B_VIDYO_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-PS_B_VIDYO_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-PS_B_VIDYO_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-QMATRIX_A_RExt_Sony_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-QMATRIX_A_RExt_Sony_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-QMATRIX_A_RExt_Sony_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-QMATRIX_A_RExt_Sony_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RAP_A_docomo_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RAP_A_docomo_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RAP_A_docomo_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RAP_A_docomo_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RAP_B_Bossen_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RAP_B_Bossen_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RAP_B_Bossen_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RAP_B_Bossen_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPLM_A_qualcomm_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPLM_A_qualcomm_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPLM_A_qualcomm_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPLM_A_qualcomm_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPLM_B_qualcomm_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPLM_B_qualcomm_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPLM_B_qualcomm_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPLM_B_qualcomm_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPS_A_docomo_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPS_A_docomo_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPS_A_docomo_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPS_A_docomo_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPS_B_qualcomm_5 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPS_B_qualcomm_5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPS_B_qualcomm_5
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPS_B_qualcomm_5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPS_C_ericsson_5 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPS_C_ericsson_5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPS_C_ericsson_5
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPS_C_ericsson_5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPS_D_ericsson_6 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPS_D_ericsson_6
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPS_D_ericsson_6
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPS_D_ericsson_6
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPS_E_qualcomm_5 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPS_E_qualcomm_5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPS_E_qualcomm_5
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPS_E_qualcomm_5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPS_F_docomo_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPS_F_docomo_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RPS_F_docomo_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RPS_F_docomo_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RQT_A_HHI_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RQT_A_HHI_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RQT_A_HHI_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RQT_A_HHI_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RQT_B_HHI_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RQT_B_HHI_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RQT_B_HHI_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RQT_B_HHI_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RQT_C_HHI_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RQT_C_HHI_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RQT_C_HHI_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RQT_C_HHI_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RQT_D_HHI_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RQT_D_HHI_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RQT_D_HHI_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RQT_D_HHI_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RQT_E_HHI_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RQT_E_HHI_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RQT_E_HHI_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RQT_E_HHI_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RQT_F_HHI_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RQT_F_HHI_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RQT_F_HHI_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RQT_F_HHI_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RQT_G_HHI_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RQT_G_HHI_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-RQT_G_HHI_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-RQT_G_HHI_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_A_MediaTek_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_A_MediaTek_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_A_MediaTek_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_A_MediaTek_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_A_RExt_MediaTek_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_A_RExt_MediaTek_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_A_RExt_MediaTek_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_A_RExt_MediaTek_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_B_MediaTek_5 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_B_MediaTek_5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_B_MediaTek_5
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_B_MediaTek_5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_C_Samsung_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_C_Samsung_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_C_Samsung_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_C_Samsung_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_C_Samsung_5 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_C_Samsung_5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_C_Samsung_5
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_C_Samsung_5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_D_Samsung_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_D_Samsung_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_D_Samsung_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_D_Samsung_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_D_Samsung_5 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_D_Samsung_5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_D_Samsung_5
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_D_Samsung_5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_E_Canon_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_E_Canon_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_E_Canon_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_E_Canon_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_F_Canon_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_F_Canon_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_F_Canon_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_F_Canon_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_G_Canon_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_G_Canon_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SAO_G_Canon_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SAO_G_Canon_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SDH_A_Orange_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SDH_A_Orange_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SDH_A_Orange_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SDH_A_Orange_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SLICES_A_Rovi_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SLICES_A_Rovi_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SLICES_A_Rovi_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SLICES_A_Rovi_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SLIST_A_Sony_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SLIST_A_Sony_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SLIST_A_Sony_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SLIST_A_Sony_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SLIST_B_Sony_8 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SLIST_B_Sony_8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SLIST_B_Sony_8
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SLIST_B_Sony_8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SLIST_C_Sony_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SLIST_C_Sony_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SLIST_C_Sony_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SLIST_C_Sony_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SLIST_D_Sony_9 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SLIST_D_Sony_9
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SLIST_D_Sony_9
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SLIST_D_Sony_9
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SLPPLP_A_VIDYO_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SLPPLP_A_VIDYO_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SLPPLP_A_VIDYO_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SLPPLP_A_VIDYO_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SLPPLP_A_VIDYO_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SLPPLP_A_VIDYO_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-SLPPLP_A_VIDYO_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-SLPPLP_A_VIDYO_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-STRUCT_A_Samsung_5 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-STRUCT_A_Samsung_5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-STRUCT_A_Samsung_5
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-STRUCT_A_Samsung_5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-STRUCT_B_Samsung_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-STRUCT_B_Samsung_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-STRUCT_B_Samsung_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-STRUCT_B_Samsung_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-STRUCT_B_Samsung_6 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-STRUCT_B_Samsung_6
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-STRUCT_B_Samsung_6
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-STRUCT_B_Samsung_6
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-TILES_A_Cisco_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-TILES_A_Cisco_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-TILES_A_Cisco_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-TILES_A_Cisco_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-TILES_B_Cisco_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-TILES_B_Cisco_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-TILES_B_Cisco_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-TILES_B_Cisco_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-TMVP_A_MS_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-TMVP_A_MS_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-TMVP_A_MS_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-TMVP_A_MS_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-TSCL_A_VIDYO_5 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-TSCL_A_VIDYO_5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-TSCL_A_VIDYO_5
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-TSCL_A_VIDYO_5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-TSCL_B_VIDYO_4 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-TSCL_B_VIDYO_4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-TSCL_B_VIDYO_4
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-TSCL_B_VIDYO_4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-TSKIP_A_MS_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-TSKIP_A_MS_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-TSKIP_A_MS_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-TSKIP_A_MS_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-TUSIZE_A_Samsung_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-TUSIZE_A_Samsung_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-TUSIZE_A_Samsung_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-TUSIZE_A_Samsung_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-VPSID_A_VIDYO_1 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-VPSID_A_VIDYO_1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-VPSID_A_VIDYO_1
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-VPSID_A_VIDYO_1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-VPSID_A_VIDYO_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-VPSID_A_VIDYO_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-VPSID_A_VIDYO_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-VPSID_A_VIDYO_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN10_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN10_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN10_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN10_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_A_ericsson_MAIN_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN10_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN10_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN10_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN10_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_B_ericsson_MAIN_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN10_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN10_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN10_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN10_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_C_ericsson_MAIN_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN10_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN10_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN10_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN10_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_D_ericsson_MAIN_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN10_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN10_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN10_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN10_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_E_ericsson_MAIN_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN10_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN10_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN10_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN10_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WPP_F_ericsson_MAIN_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WP_A_MAIN10_Toshiba_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WP_A_MAIN10_Toshiba_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WP_A_MAIN10_Toshiba_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WP_A_MAIN10_Toshiba_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WP_A_Toshiba_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WP_A_Toshiba_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WP_A_Toshiba_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WP_A_Toshiba_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WP_B_Toshiba_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WP_B_Toshiba_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WP_B_Toshiba_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WP_B_Toshiba_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WP_MAIN10_B_Toshiba_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WP_MAIN10_B_Toshiba_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-WP_MAIN10_B_Toshiba_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-WP_MAIN10_B_Toshiba_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-cip_B_NEC_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-cip_B_NEC_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-cip_B_NEC_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-cip_B_NEC_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ipcm_A_NEC_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ipcm_A_NEC_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ipcm_A_NEC_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ipcm_A_NEC_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ipcm_B_NEC_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ipcm_B_NEC_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ipcm_B_NEC_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ipcm_B_NEC_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ipcm_C_NEC_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ipcm_C_NEC_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ipcm_C_NEC_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ipcm_C_NEC_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ipcm_D_NEC_3 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ipcm_D_NEC_3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ipcm_D_NEC_3
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ipcm_D_NEC_3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ipcm_E_NEC_2 b/ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ipcm_E_NEC_2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-conformance-ipcm_E_NEC_2
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-conformance-ipcm_E_NEC_2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hevc-paramchange-yuv420p-yuv420p10 b/ffmpeg-2-8-12/tests/ref/fate/hevc-paramchange-yuv420p-yuv420p10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hevc-paramchange-yuv420p-yuv420p10
rename to ffmpeg-2-8-12/tests/ref/fate/hevc-paramchange-yuv420p-yuv420p10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/hmac b/ffmpeg-2-8-12/tests/ref/fate/hmac
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/hmac
rename to ffmpeg-2-8-12/tests/ref/fate/hmac
diff --git a/ffmpeg-2-8-11/tests/ref/fate/id-cin-video b/ffmpeg-2-8-12/tests/ref/fate/id-cin-video
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/id-cin-video
rename to ffmpeg-2-8-12/tests/ref/fate/id-cin-video
diff --git a/ffmpeg-2-8-11/tests/ref/fate/idroq-video-encode b/ffmpeg-2-8-12/tests/ref/fate/idroq-video-encode
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/idroq-video-encode
rename to ffmpeg-2-8-12/tests/ref/fate/idroq-video-encode
diff --git a/ffmpeg-2-8-11/tests/ref/fate/iff-byterun1 b/ffmpeg-2-8-12/tests/ref/fate/iff-byterun1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/iff-byterun1
rename to ffmpeg-2-8-12/tests/ref/fate/iff-byterun1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/iff-fibonacci b/ffmpeg-2-8-12/tests/ref/fate/iff-fibonacci
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/iff-fibonacci
rename to ffmpeg-2-8-12/tests/ref/fate/iff-fibonacci
diff --git a/ffmpeg-2-8-11/tests/ref/fate/iff-ilbm b/ffmpeg-2-8-12/tests/ref/fate/iff-ilbm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/iff-ilbm
rename to ffmpeg-2-8-12/tests/ref/fate/iff-ilbm
diff --git a/ffmpeg-2-8-11/tests/ref/fate/iff-pcm b/ffmpeg-2-8-12/tests/ref/fate/iff-pcm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/iff-pcm
rename to ffmpeg-2-8-12/tests/ref/fate/iff-pcm
diff --git a/ffmpeg-2-8-11/tests/ref/fate/iirfilter b/ffmpeg-2-8-12/tests/ref/fate/iirfilter
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/iirfilter
rename to ffmpeg-2-8-12/tests/ref/fate/iirfilter
diff --git a/ffmpeg-2-8-11/tests/ref/fate/indeo2 b/ffmpeg-2-8-12/tests/ref/fate/indeo2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/indeo2
rename to ffmpeg-2-8-12/tests/ref/fate/indeo2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/indeo3 b/ffmpeg-2-8-12/tests/ref/fate/indeo3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/indeo3
rename to ffmpeg-2-8-12/tests/ref/fate/indeo3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/indeo3-2 b/ffmpeg-2-8-12/tests/ref/fate/indeo3-2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/indeo3-2
rename to ffmpeg-2-8-12/tests/ref/fate/indeo3-2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/indeo4 b/ffmpeg-2-8-12/tests/ref/fate/indeo4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/indeo4
rename to ffmpeg-2-8-12/tests/ref/fate/indeo4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/indeo5 b/ffmpeg-2-8-12/tests/ref/fate/indeo5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/indeo5
rename to ffmpeg-2-8-12/tests/ref/fate/indeo5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/interplay-mve-16bit b/ffmpeg-2-8-12/tests/ref/fate/interplay-mve-16bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/interplay-mve-16bit
rename to ffmpeg-2-8-12/tests/ref/fate/interplay-mve-16bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/interplay-mve-8bit b/ffmpeg-2-8-12/tests/ref/fate/interplay-mve-8bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/interplay-mve-8bit
rename to ffmpeg-2-8-12/tests/ref/fate/interplay-mve-8bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/iv8-demux b/ffmpeg-2-8-12/tests/ref/fate/iv8-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/iv8-demux
rename to ffmpeg-2-8-12/tests/ref/fate/iv8-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/j2k-dwt b/ffmpeg-2-8-12/tests/ref/fate/j2k-dwt
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/j2k-dwt
rename to ffmpeg-2-8-12/tests/ref/fate/j2k-dwt
diff --git a/ffmpeg-2-8-11/tests/ref/fate/jpeg2000-dcinema b/ffmpeg-2-8-12/tests/ref/fate/jpeg2000-dcinema
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/jpeg2000-dcinema
rename to ffmpeg-2-8-12/tests/ref/fate/jpeg2000-dcinema
diff --git a/ffmpeg-2-8-11/tests/ref/fate/jv b/ffmpeg-2-8-12/tests/ref/fate/jv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/jv
rename to ffmpeg-2-8-12/tests/ref/fate/jv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/jv-demux b/ffmpeg-2-8-12/tests/ref/fate/jv-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/jv-demux
rename to ffmpeg-2-8-12/tests/ref/fate/jv-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/kgv1 b/ffmpeg-2-8-12/tests/ref/fate/kgv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/kgv1
rename to ffmpeg-2-8-12/tests/ref/fate/kgv1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/kmvc b/ffmpeg-2-8-12/tests/ref/fate/kmvc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/kmvc
rename to ffmpeg-2-8-12/tests/ref/fate/kmvc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lagarith-red b/ffmpeg-2-8-12/tests/ref/fate/lagarith-red
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lagarith-red
rename to ffmpeg-2-8-12/tests/ref/fate/lagarith-red
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lagarith-rgb24 b/ffmpeg-2-8-12/tests/ref/fate/lagarith-rgb24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lagarith-rgb24
rename to ffmpeg-2-8-12/tests/ref/fate/lagarith-rgb24
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lagarith-rgb32 b/ffmpeg-2-8-12/tests/ref/fate/lagarith-rgb32
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lagarith-rgb32
rename to ffmpeg-2-8-12/tests/ref/fate/lagarith-rgb32
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lagarith-yuy2 b/ffmpeg-2-8-12/tests/ref/fate/lagarith-yuy2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lagarith-yuy2
rename to ffmpeg-2-8-12/tests/ref/fate/lagarith-yuy2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lagarith-yv12 b/ffmpeg-2-8-12/tests/ref/fate/lagarith-yv12
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lagarith-yv12
rename to ffmpeg-2-8-12/tests/ref/fate/lagarith-yv12
diff --git a/ffmpeg-2-8-11/tests/ref/fate/libavcodec-options b/ffmpeg-2-8-12/tests/ref/fate/libavcodec-options
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/libavcodec-options
rename to ffmpeg-2-8-12/tests/ref/fate/libavcodec-options
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lmlm4-demux b/ffmpeg-2-8-12/tests/ref/fate/lmlm4-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lmlm4-demux
rename to ffmpeg-2-8-12/tests/ref/fate/lmlm4-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/loco-rgb b/ffmpeg-2-8-12/tests/ref/fate/loco-rgb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/loco-rgb
rename to ffmpeg-2-8-12/tests/ref/fate/loco-rgb
diff --git a/ffmpeg-2-8-11/tests/ref/fate/loco-yuy2 b/ffmpeg-2-8-12/tests/ref/fate/loco-yuy2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/loco-yuy2
rename to ffmpeg-2-8-12/tests/ref/fate/loco-yuy2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lossless-alac b/ffmpeg-2-8-12/tests/ref/fate/lossless-alac
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lossless-alac
rename to ffmpeg-2-8-12/tests/ref/fate/lossless-alac
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lossless-meridianaudio b/ffmpeg-2-8-12/tests/ref/fate/lossless-meridianaudio
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lossless-meridianaudio
rename to ffmpeg-2-8-12/tests/ref/fate/lossless-meridianaudio
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lossless-monkeysaudio-399 b/ffmpeg-2-8-12/tests/ref/fate/lossless-monkeysaudio-399
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lossless-monkeysaudio-399
rename to ffmpeg-2-8-12/tests/ref/fate/lossless-monkeysaudio-399
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lossless-shorten b/ffmpeg-2-8-12/tests/ref/fate/lossless-shorten
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lossless-shorten
rename to ffmpeg-2-8-12/tests/ref/fate/lossless-shorten
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lossless-tak b/ffmpeg-2-8-12/tests/ref/fate/lossless-tak
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lossless-tak
rename to ffmpeg-2-8-12/tests/ref/fate/lossless-tak
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lossless-truehd-5.1 b/ffmpeg-2-8-12/tests/ref/fate/lossless-truehd-5.1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lossless-truehd-5.1
rename to ffmpeg-2-8-12/tests/ref/fate/lossless-truehd-5.1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lossless-truehd-5.1-downmix-2.0 b/ffmpeg-2-8-12/tests/ref/fate/lossless-truehd-5.1-downmix-2.0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lossless-truehd-5.1-downmix-2.0
rename to ffmpeg-2-8-12/tests/ref/fate/lossless-truehd-5.1-downmix-2.0
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lossless-tta b/ffmpeg-2-8-12/tests/ref/fate/lossless-tta
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lossless-tta
rename to ffmpeg-2-8-12/tests/ref/fate/lossless-tta
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lossless-tta-encrypted b/ffmpeg-2-8-12/tests/ref/fate/lossless-tta-encrypted
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lossless-tta-encrypted
rename to ffmpeg-2-8-12/tests/ref/fate/lossless-tta-encrypted
diff --git a/ffmpeg-2-8-11/tests/ref/fate/lossless-wma b/ffmpeg-2-8-12/tests/ref/fate/lossless-wma
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/lossless-wma
rename to ffmpeg-2-8-12/tests/ref/fate/lossless-wma
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mapchan-6ch-extract-2 b/ffmpeg-2-8-12/tests/ref/fate/mapchan-6ch-extract-2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mapchan-6ch-extract-2
rename to ffmpeg-2-8-12/tests/ref/fate/mapchan-6ch-extract-2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mapchan-6ch-extract-2-downmix-mono b/ffmpeg-2-8-12/tests/ref/fate/mapchan-6ch-extract-2-downmix-mono
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mapchan-6ch-extract-2-downmix-mono
rename to ffmpeg-2-8-12/tests/ref/fate/mapchan-6ch-extract-2-downmix-mono
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mapchan-silent-mono b/ffmpeg-2-8-12/tests/ref/fate/mapchan-silent-mono
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mapchan-silent-mono
rename to ffmpeg-2-8-12/tests/ref/fate/mapchan-silent-mono
diff --git a/ffmpeg-2-8-11/tests/ref/fate/maxis-xa b/ffmpeg-2-8-12/tests/ref/fate/maxis-xa
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/maxis-xa
rename to ffmpeg-2-8-12/tests/ref/fate/maxis-xa
diff --git a/ffmpeg-2-8-11/tests/ref/fate/md5 b/ffmpeg-2-8-12/tests/ref/fate/md5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/md5
rename to ffmpeg-2-8-12/tests/ref/fate/md5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mdec b/ffmpeg-2-8-12/tests/ref/fate/mdec
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mdec
rename to ffmpeg-2-8-12/tests/ref/fate/mdec
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mdec-v3 b/ffmpeg-2-8-12/tests/ref/fate/mdec-v3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mdec-v3
rename to ffmpeg-2-8-12/tests/ref/fate/mdec-v3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mimic b/ffmpeg-2-8-12/tests/ref/fate/mimic
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mimic
rename to ffmpeg-2-8-12/tests/ref/fate/mimic
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mjpegb b/ffmpeg-2-8-12/tests/ref/fate/mjpegb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mjpegb
rename to ffmpeg-2-8-12/tests/ref/fate/mjpegb
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mkv b/ffmpeg-2-8-12/tests/ref/fate/mkv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mkv
rename to ffmpeg-2-8-12/tests/ref/fate/mkv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mlv-demux b/ffmpeg-2-8-12/tests/ref/fate/mlv-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mlv-demux
rename to ffmpeg-2-8-12/tests/ref/fate/mlv-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/motionpixels b/ffmpeg-2-8-12/tests/ref/fate/motionpixels
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/motionpixels
rename to ffmpeg-2-8-12/tests/ref/fate/motionpixels
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mpc7-demux b/ffmpeg-2-8-12/tests/ref/fate/mpc7-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mpc7-demux
rename to ffmpeg-2-8-12/tests/ref/fate/mpc7-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mpc8-demux b/ffmpeg-2-8-12/tests/ref/fate/mpc8-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mpc8-demux
rename to ffmpeg-2-8-12/tests/ref/fate/mpc8-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mpeg2-field-enc b/ffmpeg-2-8-12/tests/ref/fate/mpeg2-field-enc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mpeg2-field-enc
rename to ffmpeg-2-8-12/tests/ref/fate/mpeg2-field-enc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mpeg4-als-conformance-00 b/ffmpeg-2-8-12/tests/ref/fate/mpeg4-als-conformance-00
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mpeg4-als-conformance-00
rename to ffmpeg-2-8-12/tests/ref/fate/mpeg4-als-conformance-00
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mpeg4-als-conformance-01 b/ffmpeg-2-8-12/tests/ref/fate/mpeg4-als-conformance-01
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mpeg4-als-conformance-01
rename to ffmpeg-2-8-12/tests/ref/fate/mpeg4-als-conformance-01
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mpeg4-als-conformance-02 b/ffmpeg-2-8-12/tests/ref/fate/mpeg4-als-conformance-02
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mpeg4-als-conformance-02
rename to ffmpeg-2-8-12/tests/ref/fate/mpeg4-als-conformance-02
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mpeg4-als-conformance-03 b/ffmpeg-2-8-12/tests/ref/fate/mpeg4-als-conformance-03
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mpeg4-als-conformance-03
rename to ffmpeg-2-8-12/tests/ref/fate/mpeg4-als-conformance-03
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mpeg4-als-conformance-04 b/ffmpeg-2-8-12/tests/ref/fate/mpeg4-als-conformance-04
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mpeg4-als-conformance-04
rename to ffmpeg-2-8-12/tests/ref/fate/mpeg4-als-conformance-04
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mpeg4-als-conformance-05 b/ffmpeg-2-8-12/tests/ref/fate/mpeg4-als-conformance-05
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mpeg4-als-conformance-05
rename to ffmpeg-2-8-12/tests/ref/fate/mpeg4-als-conformance-05
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mpeg4-bsf-unpack-bframes b/ffmpeg-2-8-12/tests/ref/fate/mpeg4-bsf-unpack-bframes
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mpeg4-bsf-unpack-bframes
rename to ffmpeg-2-8-12/tests/ref/fate/mpeg4-bsf-unpack-bframes
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mpeg4-resolution-change-down-down b/ffmpeg-2-8-12/tests/ref/fate/mpeg4-resolution-change-down-down
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mpeg4-resolution-change-down-down
rename to ffmpeg-2-8-12/tests/ref/fate/mpeg4-resolution-change-down-down
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mpeg4-resolution-change-down-up b/ffmpeg-2-8-12/tests/ref/fate/mpeg4-resolution-change-down-up
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mpeg4-resolution-change-down-up
rename to ffmpeg-2-8-12/tests/ref/fate/mpeg4-resolution-change-down-up
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mpeg4-resolution-change-up-down b/ffmpeg-2-8-12/tests/ref/fate/mpeg4-resolution-change-up-down
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mpeg4-resolution-change-up-down
rename to ffmpeg-2-8-12/tests/ref/fate/mpeg4-resolution-change-up-down
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mpeg4-resolution-change-up-up b/ffmpeg-2-8-12/tests/ref/fate/mpeg4-resolution-change-up-up
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mpeg4-resolution-change-up-up
rename to ffmpeg-2-8-12/tests/ref/fate/mpeg4-resolution-change-up-up
diff --git a/ffmpeg-2-8-11/tests/ref/fate/msmpeg4v1 b/ffmpeg-2-8-12/tests/ref/fate/msmpeg4v1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/msmpeg4v1
rename to ffmpeg-2-8-12/tests/ref/fate/msmpeg4v1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/msrle-8bit b/ffmpeg-2-8-12/tests/ref/fate/msrle-8bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/msrle-8bit
rename to ffmpeg-2-8-12/tests/ref/fate/msrle-8bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mss2-pal b/ffmpeg-2-8-12/tests/ref/fate/mss2-pal
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mss2-pal
rename to ffmpeg-2-8-12/tests/ref/fate/mss2-pal
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mss2-pals b/ffmpeg-2-8-12/tests/ref/fate/mss2-pals
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mss2-pals
rename to ffmpeg-2-8-12/tests/ref/fate/mss2-pals
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mss2-rgb555 b/ffmpeg-2-8-12/tests/ref/fate/mss2-rgb555
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mss2-rgb555
rename to ffmpeg-2-8-12/tests/ref/fate/mss2-rgb555
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mss2-rgb555s b/ffmpeg-2-8-12/tests/ref/fate/mss2-rgb555s
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mss2-rgb555s
rename to ffmpeg-2-8-12/tests/ref/fate/mss2-rgb555s
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mss2-wmv b/ffmpeg-2-8-12/tests/ref/fate/mss2-wmv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mss2-wmv
rename to ffmpeg-2-8-12/tests/ref/fate/mss2-wmv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/msvideo1-16bit b/ffmpeg-2-8-12/tests/ref/fate/msvideo1-16bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/msvideo1-16bit
rename to ffmpeg-2-8-12/tests/ref/fate/msvideo1-16bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/msvideo1-8bit b/ffmpeg-2-8-12/tests/ref/fate/msvideo1-8bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/msvideo1-8bit
rename to ffmpeg-2-8-12/tests/ref/fate/msvideo1-8bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mszh b/ffmpeg-2-8-12/tests/ref/fate/mszh
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mszh
rename to ffmpeg-2-8-12/tests/ref/fate/mszh
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mtv b/ffmpeg-2-8-12/tests/ref/fate/mtv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mtv
rename to ffmpeg-2-8-12/tests/ref/fate/mtv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/murmur3 b/ffmpeg-2-8-12/tests/ref/fate/murmur3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/murmur3
rename to ffmpeg-2-8-12/tests/ref/fate/murmur3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mv-mvc1 b/ffmpeg-2-8-12/tests/ref/fate/mv-mvc1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mv-mvc1
rename to ffmpeg-2-8-12/tests/ref/fate/mv-mvc1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mv-mvc2 b/ffmpeg-2-8-12/tests/ref/fate/mv-mvc2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mv-mvc2
rename to ffmpeg-2-8-12/tests/ref/fate/mv-mvc2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mv-sgirle b/ffmpeg-2-8-12/tests/ref/fate/mv-sgirle
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mv-sgirle
rename to ffmpeg-2-8-12/tests/ref/fate/mv-sgirle
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mxf-demux b/ffmpeg-2-8-12/tests/ref/fate/mxf-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mxf-demux
rename to ffmpeg-2-8-12/tests/ref/fate/mxf-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mxf-essencegroup-demux b/ffmpeg-2-8-12/tests/ref/fate/mxf-essencegroup-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mxf-essencegroup-demux
rename to ffmpeg-2-8-12/tests/ref/fate/mxf-essencegroup-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mxf-missing-index-demux b/ffmpeg-2-8-12/tests/ref/fate/mxf-missing-index-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mxf-missing-index-demux
rename to ffmpeg-2-8-12/tests/ref/fate/mxf-missing-index-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/mxpeg b/ffmpeg-2-8-12/tests/ref/fate/mxpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/mxpeg
rename to ffmpeg-2-8-12/tests/ref/fate/mxpeg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/nc-demux b/ffmpeg-2-8-12/tests/ref/fate/nc-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/nc-demux
rename to ffmpeg-2-8-12/tests/ref/fate/nc-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/nistsphere-demux b/ffmpeg-2-8-12/tests/ref/fate/nistsphere-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/nistsphere-demux
rename to ffmpeg-2-8-12/tests/ref/fate/nistsphere-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/noproxy b/ffmpeg-2-8-12/tests/ref/fate/noproxy
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/noproxy
rename to ffmpeg-2-8-12/tests/ref/fate/noproxy
diff --git a/ffmpeg-2-8-11/tests/ref/fate/nsv-demux b/ffmpeg-2-8-12/tests/ref/fate/nsv-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/nsv-demux
rename to ffmpeg-2-8-12/tests/ref/fate/nsv-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/nuv-rtjpeg b/ffmpeg-2-8-12/tests/ref/fate/nuv-rtjpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/nuv-rtjpeg
rename to ffmpeg-2-8-12/tests/ref/fate/nuv-rtjpeg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/nuv-rtjpeg-fh b/ffmpeg-2-8-12/tests/ref/fate/nuv-rtjpeg-fh
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/nuv-rtjpeg-fh
rename to ffmpeg-2-8-12/tests/ref/fate/nuv-rtjpeg-fh
diff --git a/ffmpeg-2-8-11/tests/ref/fate/oggvp8-demux b/ffmpeg-2-8-12/tests/ref/fate/oggvp8-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/oggvp8-demux
rename to ffmpeg-2-8-12/tests/ref/fate/oggvp8-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/oma-demux b/ffmpeg-2-8-12/tests/ref/fate/oma-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/oma-demux
rename to ffmpeg-2-8-12/tests/ref/fate/oma-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/on2avc b/ffmpeg-2-8-12/tests/ref/fate/on2avc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/on2avc
rename to ffmpeg-2-8-12/tests/ref/fate/on2avc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/opt b/ffmpeg-2-8-12/tests/ref/fate/opt
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/opt
rename to ffmpeg-2-8-12/tests/ref/fate/opt
diff --git a/ffmpeg-2-8-11/tests/ref/fate/paf-audio b/ffmpeg-2-8-12/tests/ref/fate/paf-audio
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/paf-audio
rename to ffmpeg-2-8-12/tests/ref/fate/paf-audio
diff --git a/ffmpeg-2-8-11/tests/ref/fate/paf-demux b/ffmpeg-2-8-12/tests/ref/fate/paf-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/paf-demux
rename to ffmpeg-2-8-12/tests/ref/fate/paf-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/paf-video b/ffmpeg-2-8-12/tests/ref/fate/paf-video
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/paf-video
rename to ffmpeg-2-8-12/tests/ref/fate/paf-video
diff --git a/ffmpeg-2-8-11/tests/ref/fate/parseutils b/ffmpeg-2-8-12/tests/ref/fate/parseutils
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/parseutils
rename to ffmpeg-2-8-12/tests/ref/fate/parseutils
diff --git a/ffmpeg-2-8-11/tests/ref/fate/pcm-planar b/ffmpeg-2-8-12/tests/ref/fate/pcm-planar
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/pcm-planar
rename to ffmpeg-2-8-12/tests/ref/fate/pcm-planar
diff --git a/ffmpeg-2-8-11/tests/ref/fate/pcm_dvd b/ffmpeg-2-8-12/tests/ref/fate/pcm_dvd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/pcm_dvd
rename to ffmpeg-2-8-12/tests/ref/fate/pcm_dvd
diff --git a/ffmpeg-2-8-11/tests/ref/fate/pcm_s16be-stereo b/ffmpeg-2-8-12/tests/ref/fate/pcm_s16be-stereo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/pcm_s16be-stereo
rename to ffmpeg-2-8-12/tests/ref/fate/pcm_s16be-stereo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/pcm_s16le-stereo b/ffmpeg-2-8-12/tests/ref/fate/pcm_s16le-stereo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/pcm_s16le-stereo
rename to ffmpeg-2-8-12/tests/ref/fate/pcm_s16le-stereo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/pcm_u8-mono b/ffmpeg-2-8-12/tests/ref/fate/pcm_u8-mono
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/pcm_u8-mono
rename to ffmpeg-2-8-12/tests/ref/fate/pcm_u8-mono
diff --git a/ffmpeg-2-8-11/tests/ref/fate/pcm_u8-stereo b/ffmpeg-2-8-12/tests/ref/fate/pcm_u8-stereo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/pcm_u8-stereo
rename to ffmpeg-2-8-12/tests/ref/fate/pcm_u8-stereo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/pict b/ffmpeg-2-8-12/tests/ref/fate/pict
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/pict
rename to ffmpeg-2-8-12/tests/ref/fate/pict
diff --git a/ffmpeg-2-8-11/tests/ref/fate/pictor b/ffmpeg-2-8-12/tests/ref/fate/pictor
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/pictor
rename to ffmpeg-2-8-12/tests/ref/fate/pictor
diff --git a/ffmpeg-2-8-11/tests/ref/fate/pixelutils b/ffmpeg-2-8-12/tests/ref/fate/pixelutils
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/pixelutils
rename to ffmpeg-2-8-12/tests/ref/fate/pixelutils
diff --git a/ffmpeg-2-8-11/tests/ref/fate/pmp-demux b/ffmpeg-2-8-12/tests/ref/fate/pmp-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/pmp-demux
rename to ffmpeg-2-8-12/tests/ref/fate/pmp-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/png-gray16 b/ffmpeg-2-8-12/tests/ref/fate/png-gray16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/png-gray16
rename to ffmpeg-2-8-12/tests/ref/fate/png-gray16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/png-gray8 b/ffmpeg-2-8-12/tests/ref/fate/png-gray8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/png-gray8
rename to ffmpeg-2-8-12/tests/ref/fate/png-gray8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/png-rgb24 b/ffmpeg-2-8-12/tests/ref/fate/png-rgb24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/png-rgb24
rename to ffmpeg-2-8-12/tests/ref/fate/png-rgb24
diff --git a/ffmpeg-2-8-11/tests/ref/fate/png-rgb48 b/ffmpeg-2-8-12/tests/ref/fate/png-rgb48
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/png-rgb48
rename to ffmpeg-2-8-12/tests/ref/fate/png-rgb48
diff --git a/ffmpeg-2-8-11/tests/ref/fate/png-rgba b/ffmpeg-2-8-12/tests/ref/fate/png-rgba
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/png-rgba
rename to ffmpeg-2-8-12/tests/ref/fate/png-rgba
diff --git a/ffmpeg-2-8-11/tests/ref/fate/png-ya16 b/ffmpeg-2-8-12/tests/ref/fate/png-ya16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/png-ya16
rename to ffmpeg-2-8-12/tests/ref/fate/png-ya16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/png-ya8 b/ffmpeg-2-8-12/tests/ref/fate/png-ya8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/png-ya8
rename to ffmpeg-2-8-12/tests/ref/fate/png-ya8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/pngparser b/ffmpeg-2-8-12/tests/ref/fate/pngparser
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/pngparser
rename to ffmpeg-2-8-12/tests/ref/fate/pngparser
diff --git a/ffmpeg-2-8-11/tests/ref/fate/prores-422 b/ffmpeg-2-8-12/tests/ref/fate/prores-422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/prores-422
rename to ffmpeg-2-8-12/tests/ref/fate/prores-422
diff --git a/ffmpeg-2-8-11/tests/ref/fate/prores-422_hq b/ffmpeg-2-8-12/tests/ref/fate/prores-422_hq
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/prores-422_hq
rename to ffmpeg-2-8-12/tests/ref/fate/prores-422_hq
diff --git a/ffmpeg-2-8-11/tests/ref/fate/prores-422_lt b/ffmpeg-2-8-12/tests/ref/fate/prores-422_lt
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/prores-422_lt
rename to ffmpeg-2-8-12/tests/ref/fate/prores-422_lt
diff --git a/ffmpeg-2-8-11/tests/ref/fate/prores-422_proxy b/ffmpeg-2-8-12/tests/ref/fate/prores-422_proxy
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/prores-422_proxy
rename to ffmpeg-2-8-12/tests/ref/fate/prores-422_proxy
diff --git a/ffmpeg-2-8-11/tests/ref/fate/prores-alpha b/ffmpeg-2-8-12/tests/ref/fate/prores-alpha
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/prores-alpha
rename to ffmpeg-2-8-12/tests/ref/fate/prores-alpha
diff --git a/ffmpeg-2-8-11/tests/ref/fate/prores-alpha_skip b/ffmpeg-2-8-12/tests/ref/fate/prores-alpha_skip
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/prores-alpha_skip
rename to ffmpeg-2-8-12/tests/ref/fate/prores-alpha_skip
diff --git a/ffmpeg-2-8-11/tests/ref/fate/prores-transparency b/ffmpeg-2-8-12/tests/ref/fate/prores-transparency
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/prores-transparency
rename to ffmpeg-2-8-12/tests/ref/fate/prores-transparency
diff --git a/ffmpeg-2-8-11/tests/ref/fate/prores-transparency_skip b/ffmpeg-2-8-12/tests/ref/fate/prores-transparency_skip
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/prores-transparency_skip
rename to ffmpeg-2-8-12/tests/ref/fate/prores-transparency_skip
diff --git a/ffmpeg-2-8-11/tests/ref/fate/psx-str-demux b/ffmpeg-2-8-12/tests/ref/fate/psx-str-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/psx-str-demux
rename to ffmpeg-2-8-12/tests/ref/fate/psx-str-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ptx b/ffmpeg-2-8-12/tests/ref/fate/ptx
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ptx
rename to ffmpeg-2-8-12/tests/ref/fate/ptx
diff --git a/ffmpeg-2-8-11/tests/ref/fate/pva-demux b/ffmpeg-2-8-12/tests/ref/fate/pva-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/pva-demux
rename to ffmpeg-2-8-12/tests/ref/fate/pva-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qcp-demux b/ffmpeg-2-8-12/tests/ref/fate/qcp-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qcp-demux
rename to ffmpeg-2-8-12/tests/ref/fate/qcp-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qpeg b/ffmpeg-2-8-12/tests/ref/fate/qpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qpeg
rename to ffmpeg-2-8-12/tests/ref/fate/qpeg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qt-alaw-mono b/ffmpeg-2-8-12/tests/ref/fate/qt-alaw-mono
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qt-alaw-mono
rename to ffmpeg-2-8-12/tests/ref/fate/qt-alaw-mono
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qt-alaw-stereo b/ffmpeg-2-8-12/tests/ref/fate/qt-alaw-stereo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qt-alaw-stereo
rename to ffmpeg-2-8-12/tests/ref/fate/qt-alaw-stereo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qt-ima4-mono b/ffmpeg-2-8-12/tests/ref/fate/qt-ima4-mono
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qt-ima4-mono
rename to ffmpeg-2-8-12/tests/ref/fate/qt-ima4-mono
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qt-ima4-stereo b/ffmpeg-2-8-12/tests/ref/fate/qt-ima4-stereo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qt-ima4-stereo
rename to ffmpeg-2-8-12/tests/ref/fate/qt-ima4-stereo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qt-mac3-mono b/ffmpeg-2-8-12/tests/ref/fate/qt-mac3-mono
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qt-mac3-mono
rename to ffmpeg-2-8-12/tests/ref/fate/qt-mac3-mono
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qt-mac3-stereo b/ffmpeg-2-8-12/tests/ref/fate/qt-mac3-stereo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qt-mac3-stereo
rename to ffmpeg-2-8-12/tests/ref/fate/qt-mac3-stereo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qt-mac6-mono b/ffmpeg-2-8-12/tests/ref/fate/qt-mac6-mono
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qt-mac6-mono
rename to ffmpeg-2-8-12/tests/ref/fate/qt-mac6-mono
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qt-mac6-stereo b/ffmpeg-2-8-12/tests/ref/fate/qt-mac6-stereo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qt-mac6-stereo
rename to ffmpeg-2-8-12/tests/ref/fate/qt-mac6-stereo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qt-ulaw-mono b/ffmpeg-2-8-12/tests/ref/fate/qt-ulaw-mono
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qt-ulaw-mono
rename to ffmpeg-2-8-12/tests/ref/fate/qt-ulaw-mono
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qt-ulaw-stereo b/ffmpeg-2-8-12/tests/ref/fate/qt-ulaw-stereo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qt-ulaw-stereo
rename to ffmpeg-2-8-12/tests/ref/fate/qt-ulaw-stereo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qtrle-16bit b/ffmpeg-2-8-12/tests/ref/fate/qtrle-16bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qtrle-16bit
rename to ffmpeg-2-8-12/tests/ref/fate/qtrle-16bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qtrle-1bit b/ffmpeg-2-8-12/tests/ref/fate/qtrle-1bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qtrle-1bit
rename to ffmpeg-2-8-12/tests/ref/fate/qtrle-1bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qtrle-24bit b/ffmpeg-2-8-12/tests/ref/fate/qtrle-24bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qtrle-24bit
rename to ffmpeg-2-8-12/tests/ref/fate/qtrle-24bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qtrle-2bit b/ffmpeg-2-8-12/tests/ref/fate/qtrle-2bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qtrle-2bit
rename to ffmpeg-2-8-12/tests/ref/fate/qtrle-2bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qtrle-32bit b/ffmpeg-2-8-12/tests/ref/fate/qtrle-32bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qtrle-32bit
rename to ffmpeg-2-8-12/tests/ref/fate/qtrle-32bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qtrle-4bit b/ffmpeg-2-8-12/tests/ref/fate/qtrle-4bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qtrle-4bit
rename to ffmpeg-2-8-12/tests/ref/fate/qtrle-4bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/qtrle-8bit b/ffmpeg-2-8-12/tests/ref/fate/qtrle-8bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/qtrle-8bit
rename to ffmpeg-2-8-12/tests/ref/fate/qtrle-8bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/quickdraw b/ffmpeg-2-8-12/tests/ref/fate/quickdraw
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/quickdraw
rename to ffmpeg-2-8-12/tests/ref/fate/quickdraw
diff --git a/ffmpeg-2-8-11/tests/ref/fate/r210 b/ffmpeg-2-8-12/tests/ref/fate/r210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/r210
rename to ffmpeg-2-8-12/tests/ref/fate/r210
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ra-144 b/ffmpeg-2-8-12/tests/ref/fate/ra-144
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ra-144
rename to ffmpeg-2-8-12/tests/ref/fate/ra-144
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ra3-144 b/ffmpeg-2-8-12/tests/ref/fate/ra3-144
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ra3-144
rename to ffmpeg-2-8-12/tests/ref/fate/ra3-144
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ralf b/ffmpeg-2-8-12/tests/ref/fate/ralf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ralf
rename to ffmpeg-2-8-12/tests/ref/fate/ralf
diff --git a/ffmpeg-2-8-11/tests/ref/fate/random_seed b/ffmpeg-2-8-12/tests/ref/fate/random_seed
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/random_seed
rename to ffmpeg-2-8-12/tests/ref/fate/random_seed
diff --git a/ffmpeg-2-8-11/tests/ref/fate/redcode-demux b/ffmpeg-2-8-12/tests/ref/fate/redcode-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/redcode-demux
rename to ffmpeg-2-8-12/tests/ref/fate/redcode-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/redspark-demux b/ffmpeg-2-8-12/tests/ref/fate/redspark-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/redspark-demux
rename to ffmpeg-2-8-12/tests/ref/fate/redspark-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ripemd b/ffmpeg-2-8-12/tests/ref/fate/ripemd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ripemd
rename to ffmpeg-2-8-12/tests/ref/fate/ripemd
diff --git a/ffmpeg-2-8-11/tests/ref/fate/rl2 b/ffmpeg-2-8-12/tests/ref/fate/rl2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/rl2
rename to ffmpeg-2-8-12/tests/ref/fate/rl2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/roqvideo b/ffmpeg-2-8-12/tests/ref/fate/roqvideo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/roqvideo
rename to ffmpeg-2-8-12/tests/ref/fate/roqvideo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/rpza b/ffmpeg-2-8-12/tests/ref/fate/rpza
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/rpza
rename to ffmpeg-2-8-12/tests/ref/fate/rpza
diff --git a/ffmpeg-2-8-11/tests/ref/fate/rsd-demux b/ffmpeg-2-8-12/tests/ref/fate/rsd-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/rsd-demux
rename to ffmpeg-2-8-12/tests/ref/fate/rsd-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/rtmpdh b/ffmpeg-2-8-12/tests/ref/fate/rtmpdh
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/rtmpdh
rename to ffmpeg-2-8-12/tests/ref/fate/rtmpdh
diff --git a/ffmpeg-2-8-11/tests/ref/fate/rv30 b/ffmpeg-2-8-12/tests/ref/fate/rv30
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/rv30
rename to ffmpeg-2-8-12/tests/ref/fate/rv30
diff --git a/ffmpeg-2-8-11/tests/ref/fate/rv40 b/ffmpeg-2-8-12/tests/ref/fate/rv40
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/rv40
rename to ffmpeg-2-8-12/tests/ref/fate/rv40
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sanm b/ffmpeg-2-8-12/tests/ref/fate/sanm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sanm
rename to ffmpeg-2-8-12/tests/ref/fate/sanm
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sgi-gray b/ffmpeg-2-8-12/tests/ref/fate/sgi-gray
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sgi-gray
rename to ffmpeg-2-8-12/tests/ref/fate/sgi-gray
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sgi-gray16 b/ffmpeg-2-8-12/tests/ref/fate/sgi-gray16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sgi-gray16
rename to ffmpeg-2-8-12/tests/ref/fate/sgi-gray16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sgi-rgb24 b/ffmpeg-2-8-12/tests/ref/fate/sgi-rgb24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sgi-rgb24
rename to ffmpeg-2-8-12/tests/ref/fate/sgi-rgb24
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sgi-rgb24-rle b/ffmpeg-2-8-12/tests/ref/fate/sgi-rgb24-rle
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sgi-rgb24-rle
rename to ffmpeg-2-8-12/tests/ref/fate/sgi-rgb24-rle
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sgi-rgb48 b/ffmpeg-2-8-12/tests/ref/fate/sgi-rgb48
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sgi-rgb48
rename to ffmpeg-2-8-12/tests/ref/fate/sgi-rgb48
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sgi-rgb48-rle b/ffmpeg-2-8-12/tests/ref/fate/sgi-rgb48-rle
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sgi-rgb48-rle
rename to ffmpeg-2-8-12/tests/ref/fate/sgi-rgb48-rle
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sgi-rgba b/ffmpeg-2-8-12/tests/ref/fate/sgi-rgba
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sgi-rgba
rename to ffmpeg-2-8-12/tests/ref/fate/sgi-rgba
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sgi-rgba64 b/ffmpeg-2-8-12/tests/ref/fate/sgi-rgba64
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sgi-rgba64
rename to ffmpeg-2-8-12/tests/ref/fate/sgi-rgba64
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sgi-rgba64-rle b/ffmpeg-2-8-12/tests/ref/fate/sgi-rgba64-rle
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sgi-rgba64-rle
rename to ffmpeg-2-8-12/tests/ref/fate/sgi-rgba64-rle
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sha b/ffmpeg-2-8-12/tests/ref/fate/sha
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sha
rename to ffmpeg-2-8-12/tests/ref/fate/sha
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sha512 b/ffmpeg-2-8-12/tests/ref/fate/sha512
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sha512
rename to ffmpeg-2-8-12/tests/ref/fate/sha512
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sierra-vmd-audio b/ffmpeg-2-8-12/tests/ref/fate/sierra-vmd-audio
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sierra-vmd-audio
rename to ffmpeg-2-8-12/tests/ref/fate/sierra-vmd-audio
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sierra-vmd-video b/ffmpeg-2-8-12/tests/ref/fate/sierra-vmd-video
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sierra-vmd-video
rename to ffmpeg-2-8-12/tests/ref/fate/sierra-vmd-video
diff --git a/ffmpeg-2-8-11/tests/ref/fate/siff-demux b/ffmpeg-2-8-12/tests/ref/fate/siff-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/siff-demux
rename to ffmpeg-2-8-12/tests/ref/fate/siff-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/smacker-audio b/ffmpeg-2-8-12/tests/ref/fate/smacker-audio
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/smacker-audio
rename to ffmpeg-2-8-12/tests/ref/fate/smacker-audio
diff --git a/ffmpeg-2-8-11/tests/ref/fate/smacker-video b/ffmpeg-2-8-12/tests/ref/fate/smacker-video
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/smacker-video
rename to ffmpeg-2-8-12/tests/ref/fate/smacker-video
diff --git a/ffmpeg-2-8-11/tests/ref/fate/smc b/ffmpeg-2-8-12/tests/ref/fate/smc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/smc
rename to ffmpeg-2-8-12/tests/ref/fate/smc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/smjpeg b/ffmpeg-2-8-12/tests/ref/fate/smjpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/smjpeg
rename to ffmpeg-2-8-12/tests/ref/fate/smjpeg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/smjpeg-demux b/ffmpeg-2-8-12/tests/ref/fate/smjpeg-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/smjpeg-demux
rename to ffmpeg-2-8-12/tests/ref/fate/smjpeg-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/smvjpeg b/ffmpeg-2-8-12/tests/ref/fate/smvjpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/smvjpeg
rename to ffmpeg-2-8-12/tests/ref/fate/smvjpeg
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sp5x b/ffmpeg-2-8-12/tests/ref/fate/sp5x
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sp5x
rename to ffmpeg-2-8-12/tests/ref/fate/sp5x
diff --git a/ffmpeg-2-8-11/tests/ref/fate/srtp b/ffmpeg-2-8-12/tests/ref/fate/srtp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/srtp
rename to ffmpeg-2-8-12/tests/ref/fate/srtp
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-aqtitle b/ffmpeg-2-8-12/tests/ref/fate/sub-aqtitle
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-aqtitle
rename to ffmpeg-2-8-12/tests/ref/fate/sub-aqtitle
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-ass-to-ass-transcode b/ffmpeg-2-8-12/tests/ref/fate/sub-ass-to-ass-transcode
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-ass-to-ass-transcode
rename to ffmpeg-2-8-12/tests/ref/fate/sub-ass-to-ass-transcode
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-cc b/ffmpeg-2-8-12/tests/ref/fate/sub-cc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-cc
rename to ffmpeg-2-8-12/tests/ref/fate/sub-cc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-charenc b/ffmpeg-2-8-12/tests/ref/fate/sub-charenc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-charenc
rename to ffmpeg-2-8-12/tests/ref/fate/sub-charenc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-jacosub b/ffmpeg-2-8-12/tests/ref/fate/sub-jacosub
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-jacosub
rename to ffmpeg-2-8-12/tests/ref/fate/sub-jacosub
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-microdvd b/ffmpeg-2-8-12/tests/ref/fate/sub-microdvd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-microdvd
rename to ffmpeg-2-8-12/tests/ref/fate/sub-microdvd
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-microdvd-remux b/ffmpeg-2-8-12/tests/ref/fate/sub-microdvd-remux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-microdvd-remux
rename to ffmpeg-2-8-12/tests/ref/fate/sub-microdvd-remux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-movtext b/ffmpeg-2-8-12/tests/ref/fate/sub-movtext
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-movtext
rename to ffmpeg-2-8-12/tests/ref/fate/sub-movtext
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-mpl2 b/ffmpeg-2-8-12/tests/ref/fate/sub-mpl2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-mpl2
rename to ffmpeg-2-8-12/tests/ref/fate/sub-mpl2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-mpsub b/ffmpeg-2-8-12/tests/ref/fate/sub-mpsub
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-mpsub
rename to ffmpeg-2-8-12/tests/ref/fate/sub-mpsub
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-mpsub-frames b/ffmpeg-2-8-12/tests/ref/fate/sub-mpsub-frames
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-mpsub-frames
rename to ffmpeg-2-8-12/tests/ref/fate/sub-mpsub-frames
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-pjs b/ffmpeg-2-8-12/tests/ref/fate/sub-pjs
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-pjs
rename to ffmpeg-2-8-12/tests/ref/fate/sub-pjs
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-realtext b/ffmpeg-2-8-12/tests/ref/fate/sub-realtext
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-realtext
rename to ffmpeg-2-8-12/tests/ref/fate/sub-realtext
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-sami b/ffmpeg-2-8-12/tests/ref/fate/sub-sami
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-sami
rename to ffmpeg-2-8-12/tests/ref/fate/sub-sami
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-srt b/ffmpeg-2-8-12/tests/ref/fate/sub-srt
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-srt
rename to ffmpeg-2-8-12/tests/ref/fate/sub-srt
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-ssa-to-ass-remux b/ffmpeg-2-8-12/tests/ref/fate/sub-ssa-to-ass-remux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-ssa-to-ass-remux
rename to ffmpeg-2-8-12/tests/ref/fate/sub-ssa-to-ass-remux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-stl b/ffmpeg-2-8-12/tests/ref/fate/sub-stl
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-stl
rename to ffmpeg-2-8-12/tests/ref/fate/sub-stl
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-subripenc b/ffmpeg-2-8-12/tests/ref/fate/sub-subripenc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-subripenc
rename to ffmpeg-2-8-12/tests/ref/fate/sub-subripenc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-subviewer b/ffmpeg-2-8-12/tests/ref/fate/sub-subviewer
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-subviewer
rename to ffmpeg-2-8-12/tests/ref/fate/sub-subviewer
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-subviewer1 b/ffmpeg-2-8-12/tests/ref/fate/sub-subviewer1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-subviewer1
rename to ffmpeg-2-8-12/tests/ref/fate/sub-subviewer1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-vplayer b/ffmpeg-2-8-12/tests/ref/fate/sub-vplayer
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-vplayer
rename to ffmpeg-2-8-12/tests/ref/fate/sub-vplayer
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-webvtt b/ffmpeg-2-8-12/tests/ref/fate/sub-webvtt
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-webvtt
rename to ffmpeg-2-8-12/tests/ref/fate/sub-webvtt
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub-webvttenc b/ffmpeg-2-8-12/tests/ref/fate/sub-webvttenc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub-webvttenc
rename to ffmpeg-2-8-12/tests/ref/fate/sub-webvttenc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sub2video b/ffmpeg-2-8-12/tests/ref/fate/sub2video
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sub2video
rename to ffmpeg-2-8-12/tests/ref/fate/sub2video
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sunraster-1bit-raw b/ffmpeg-2-8-12/tests/ref/fate/sunraster-1bit-raw
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sunraster-1bit-raw
rename to ffmpeg-2-8-12/tests/ref/fate/sunraster-1bit-raw
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sunraster-1bit-rle b/ffmpeg-2-8-12/tests/ref/fate/sunraster-1bit-rle
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sunraster-1bit-rle
rename to ffmpeg-2-8-12/tests/ref/fate/sunraster-1bit-rle
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sunraster-24bit-raw b/ffmpeg-2-8-12/tests/ref/fate/sunraster-24bit-raw
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sunraster-24bit-raw
rename to ffmpeg-2-8-12/tests/ref/fate/sunraster-24bit-raw
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sunraster-24bit-rle b/ffmpeg-2-8-12/tests/ref/fate/sunraster-24bit-rle
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sunraster-24bit-rle
rename to ffmpeg-2-8-12/tests/ref/fate/sunraster-24bit-rle
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sunraster-8bit-raw b/ffmpeg-2-8-12/tests/ref/fate/sunraster-8bit-raw
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sunraster-8bit-raw
rename to ffmpeg-2-8-12/tests/ref/fate/sunraster-8bit-raw
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sunraster-8bit-rle b/ffmpeg-2-8-12/tests/ref/fate/sunraster-8bit-rle
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sunraster-8bit-rle
rename to ffmpeg-2-8-12/tests/ref/fate/sunraster-8bit-rle
diff --git a/ffmpeg-2-8-11/tests/ref/fate/sunraster-8bit_gray-raw b/ffmpeg-2-8-12/tests/ref/fate/sunraster-8bit_gray-raw
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/sunraster-8bit_gray-raw
rename to ffmpeg-2-8-12/tests/ref/fate/sunraster-8bit_gray-raw
diff --git a/ffmpeg-2-8-11/tests/ref/fate/svq1 b/ffmpeg-2-8-12/tests/ref/fate/svq1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/svq1
rename to ffmpeg-2-8-12/tests/ref/fate/svq1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/svq1-headerswap b/ffmpeg-2-8-12/tests/ref/fate/svq1-headerswap
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/svq1-headerswap
rename to ffmpeg-2-8-12/tests/ref/fate/svq1-headerswap
diff --git a/ffmpeg-2-8-11/tests/ref/fate/svq3 b/ffmpeg-2-8-12/tests/ref/fate/svq3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/svq3
rename to ffmpeg-2-8-12/tests/ref/fate/svq3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/targa-conformance-CBW8 b/ffmpeg-2-8-12/tests/ref/fate/targa-conformance-CBW8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/targa-conformance-CBW8
rename to ffmpeg-2-8-12/tests/ref/fate/targa-conformance-CBW8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/targa-conformance-CCM8 b/ffmpeg-2-8-12/tests/ref/fate/targa-conformance-CCM8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/targa-conformance-CCM8
rename to ffmpeg-2-8-12/tests/ref/fate/targa-conformance-CCM8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/targa-conformance-CTC16 b/ffmpeg-2-8-12/tests/ref/fate/targa-conformance-CTC16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/targa-conformance-CTC16
rename to ffmpeg-2-8-12/tests/ref/fate/targa-conformance-CTC16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/targa-conformance-CTC24 b/ffmpeg-2-8-12/tests/ref/fate/targa-conformance-CTC24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/targa-conformance-CTC24
rename to ffmpeg-2-8-12/tests/ref/fate/targa-conformance-CTC24
diff --git a/ffmpeg-2-8-11/tests/ref/fate/targa-conformance-CTC32 b/ffmpeg-2-8-12/tests/ref/fate/targa-conformance-CTC32
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/targa-conformance-CTC32
rename to ffmpeg-2-8-12/tests/ref/fate/targa-conformance-CTC32
diff --git a/ffmpeg-2-8-11/tests/ref/fate/targa-conformance-UBW8 b/ffmpeg-2-8-12/tests/ref/fate/targa-conformance-UBW8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/targa-conformance-UBW8
rename to ffmpeg-2-8-12/tests/ref/fate/targa-conformance-UBW8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/targa-conformance-UCM8 b/ffmpeg-2-8-12/tests/ref/fate/targa-conformance-UCM8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/targa-conformance-UCM8
rename to ffmpeg-2-8-12/tests/ref/fate/targa-conformance-UCM8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/targa-conformance-UTC16 b/ffmpeg-2-8-12/tests/ref/fate/targa-conformance-UTC16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/targa-conformance-UTC16
rename to ffmpeg-2-8-12/tests/ref/fate/targa-conformance-UTC16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/targa-conformance-UTC24 b/ffmpeg-2-8-12/tests/ref/fate/targa-conformance-UTC24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/targa-conformance-UTC24
rename to ffmpeg-2-8-12/tests/ref/fate/targa-conformance-UTC24
diff --git a/ffmpeg-2-8-11/tests/ref/fate/targa-conformance-UTC32 b/ffmpeg-2-8-12/tests/ref/fate/targa-conformance-UTC32
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/targa-conformance-UTC32
rename to ffmpeg-2-8-12/tests/ref/fate/targa-conformance-UTC32
diff --git a/ffmpeg-2-8-11/tests/ref/fate/targa-top-to-bottom b/ffmpeg-2-8-12/tests/ref/fate/targa-top-to-bottom
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/targa-top-to-bottom
rename to ffmpeg-2-8-12/tests/ref/fate/targa-top-to-bottom
diff --git a/ffmpeg-2-8-11/tests/ref/fate/tdsc b/ffmpeg-2-8-12/tests/ref/fate/tdsc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/tdsc
rename to ffmpeg-2-8-12/tests/ref/fate/tdsc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/tea b/ffmpeg-2-8-12/tests/ref/fate/tea
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/tea
rename to ffmpeg-2-8-12/tests/ref/fate/tea
diff --git a/ffmpeg-2-8-11/tests/ref/fate/theora-coeff-level64 b/ffmpeg-2-8-12/tests/ref/fate/theora-coeff-level64
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/theora-coeff-level64
rename to ffmpeg-2-8-12/tests/ref/fate/theora-coeff-level64
diff --git a/ffmpeg-2-8-11/tests/ref/fate/theora-offset b/ffmpeg-2-8-12/tests/ref/fate/theora-offset
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/theora-offset
rename to ffmpeg-2-8-12/tests/ref/fate/theora-offset
diff --git a/ffmpeg-2-8-11/tests/ref/fate/thp b/ffmpeg-2-8-12/tests/ref/fate/thp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/thp
rename to ffmpeg-2-8-12/tests/ref/fate/thp
diff --git a/ffmpeg-2-8-11/tests/ref/fate/tiertex-seq b/ffmpeg-2-8-12/tests/ref/fate/tiertex-seq
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/tiertex-seq
rename to ffmpeg-2-8-12/tests/ref/fate/tiertex-seq
diff --git a/ffmpeg-2-8-11/tests/ref/fate/tiff-fax-g3 b/ffmpeg-2-8-12/tests/ref/fate/tiff-fax-g3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/tiff-fax-g3
rename to ffmpeg-2-8-12/tests/ref/fate/tiff-fax-g3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/tiff-fax-g3s b/ffmpeg-2-8-12/tests/ref/fate/tiff-fax-g3s
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/tiff-fax-g3s
rename to ffmpeg-2-8-12/tests/ref/fate/tiff-fax-g3s
diff --git a/ffmpeg-2-8-11/tests/ref/fate/timefilter b/ffmpeg-2-8-12/tests/ref/fate/timefilter
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/timefilter
rename to ffmpeg-2-8-12/tests/ref/fate/timefilter
diff --git a/ffmpeg-2-8-11/tests/ref/fate/tmv b/ffmpeg-2-8-12/tests/ref/fate/tmv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/tmv
rename to ffmpeg-2-8-12/tests/ref/fate/tmv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/truemotion1-15 b/ffmpeg-2-8-12/tests/ref/fate/truemotion1-15
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/truemotion1-15
rename to ffmpeg-2-8-12/tests/ref/fate/truemotion1-15
diff --git a/ffmpeg-2-8-11/tests/ref/fate/truemotion1-24 b/ffmpeg-2-8-12/tests/ref/fate/truemotion1-24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/truemotion1-24
rename to ffmpeg-2-8-12/tests/ref/fate/truemotion1-24
diff --git a/ffmpeg-2-8-11/tests/ref/fate/truemotion2 b/ffmpeg-2-8-12/tests/ref/fate/truemotion2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/truemotion2
rename to ffmpeg-2-8-12/tests/ref/fate/truemotion2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/tscc-15bit b/ffmpeg-2-8-12/tests/ref/fate/tscc-15bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/tscc-15bit
rename to ffmpeg-2-8-12/tests/ref/fate/tscc-15bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/tscc-32bit b/ffmpeg-2-8-12/tests/ref/fate/tscc-32bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/tscc-32bit
rename to ffmpeg-2-8-12/tests/ref/fate/tscc-32bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/tscc2-avi b/ffmpeg-2-8-12/tests/ref/fate/tscc2-avi
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/tscc2-avi
rename to ffmpeg-2-8-12/tests/ref/fate/tscc2-avi
diff --git a/ffmpeg-2-8-11/tests/ref/fate/tscc2-mov b/ffmpeg-2-8-12/tests/ref/fate/tscc2-mov
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/tscc2-mov
rename to ffmpeg-2-8-12/tests/ref/fate/tscc2-mov
diff --git a/ffmpeg-2-8-11/tests/ref/fate/txd-16bpp b/ffmpeg-2-8-12/tests/ref/fate/txd-16bpp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/txd-16bpp
rename to ffmpeg-2-8-12/tests/ref/fate/txd-16bpp
diff --git a/ffmpeg-2-8-11/tests/ref/fate/txd-odd b/ffmpeg-2-8-12/tests/ref/fate/txd-odd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/txd-odd
rename to ffmpeg-2-8-12/tests/ref/fate/txd-odd
diff --git a/ffmpeg-2-8-11/tests/ref/fate/txd-pal8 b/ffmpeg-2-8-12/tests/ref/fate/txd-pal8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/txd-pal8
rename to ffmpeg-2-8-12/tests/ref/fate/txd-pal8
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ulti b/ffmpeg-2-8-12/tests/ref/fate/ulti
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ulti
rename to ffmpeg-2-8-12/tests/ref/fate/ulti
diff --git a/ffmpeg-2-8-11/tests/ref/fate/unknown_layout-ac3 b/ffmpeg-2-8-12/tests/ref/fate/unknown_layout-ac3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/unknown_layout-ac3
rename to ffmpeg-2-8-12/tests/ref/fate/unknown_layout-ac3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/unknown_layout-pcm b/ffmpeg-2-8-12/tests/ref/fate/unknown_layout-pcm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/unknown_layout-pcm
rename to ffmpeg-2-8-12/tests/ref/fate/unknown_layout-pcm
diff --git a/ffmpeg-2-8-11/tests/ref/fate/url b/ffmpeg-2-8-12/tests/ref/fate/url
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/url
rename to ffmpeg-2-8-12/tests/ref/fate/url
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideo_rgb_left b/ffmpeg-2-8-12/tests/ref/fate/utvideo_rgb_left
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideo_rgb_left
rename to ffmpeg-2-8-12/tests/ref/fate/utvideo_rgb_left
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideo_rgb_median b/ffmpeg-2-8-12/tests/ref/fate/utvideo_rgb_median
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideo_rgb_median
rename to ffmpeg-2-8-12/tests/ref/fate/utvideo_rgb_median
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideo_rgba_left b/ffmpeg-2-8-12/tests/ref/fate/utvideo_rgba_left
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideo_rgba_left
rename to ffmpeg-2-8-12/tests/ref/fate/utvideo_rgba_left
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideo_rgba_median b/ffmpeg-2-8-12/tests/ref/fate/utvideo_rgba_median
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideo_rgba_median
rename to ffmpeg-2-8-12/tests/ref/fate/utvideo_rgba_median
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideo_rgba_single_symbol b/ffmpeg-2-8-12/tests/ref/fate/utvideo_rgba_single_symbol
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideo_rgba_single_symbol
rename to ffmpeg-2-8-12/tests/ref/fate/utvideo_rgba_single_symbol
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideo_yuv420_left b/ffmpeg-2-8-12/tests/ref/fate/utvideo_yuv420_left
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideo_yuv420_left
rename to ffmpeg-2-8-12/tests/ref/fate/utvideo_yuv420_left
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideo_yuv420_median b/ffmpeg-2-8-12/tests/ref/fate/utvideo_yuv420_median
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideo_yuv420_median
rename to ffmpeg-2-8-12/tests/ref/fate/utvideo_yuv420_median
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideo_yuv422_left b/ffmpeg-2-8-12/tests/ref/fate/utvideo_yuv422_left
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideo_yuv422_left
rename to ffmpeg-2-8-12/tests/ref/fate/utvideo_yuv422_left
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideo_yuv422_median b/ffmpeg-2-8-12/tests/ref/fate/utvideo_yuv422_median
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideo_yuv422_median
rename to ffmpeg-2-8-12/tests/ref/fate/utvideo_yuv422_median
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideoenc_rgb_left b/ffmpeg-2-8-12/tests/ref/fate/utvideoenc_rgb_left
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideoenc_rgb_left
rename to ffmpeg-2-8-12/tests/ref/fate/utvideoenc_rgb_left
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideoenc_rgb_median b/ffmpeg-2-8-12/tests/ref/fate/utvideoenc_rgb_median
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideoenc_rgb_median
rename to ffmpeg-2-8-12/tests/ref/fate/utvideoenc_rgb_median
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideoenc_rgb_none b/ffmpeg-2-8-12/tests/ref/fate/utvideoenc_rgb_none
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideoenc_rgb_none
rename to ffmpeg-2-8-12/tests/ref/fate/utvideoenc_rgb_none
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideoenc_rgba_left b/ffmpeg-2-8-12/tests/ref/fate/utvideoenc_rgba_left
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideoenc_rgba_left
rename to ffmpeg-2-8-12/tests/ref/fate/utvideoenc_rgba_left
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideoenc_rgba_median b/ffmpeg-2-8-12/tests/ref/fate/utvideoenc_rgba_median
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideoenc_rgba_median
rename to ffmpeg-2-8-12/tests/ref/fate/utvideoenc_rgba_median
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideoenc_rgba_none b/ffmpeg-2-8-12/tests/ref/fate/utvideoenc_rgba_none
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideoenc_rgba_none
rename to ffmpeg-2-8-12/tests/ref/fate/utvideoenc_rgba_none
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideoenc_yuv420_left b/ffmpeg-2-8-12/tests/ref/fate/utvideoenc_yuv420_left
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideoenc_yuv420_left
rename to ffmpeg-2-8-12/tests/ref/fate/utvideoenc_yuv420_left
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideoenc_yuv420_median b/ffmpeg-2-8-12/tests/ref/fate/utvideoenc_yuv420_median
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideoenc_yuv420_median
rename to ffmpeg-2-8-12/tests/ref/fate/utvideoenc_yuv420_median
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideoenc_yuv420_none b/ffmpeg-2-8-12/tests/ref/fate/utvideoenc_yuv420_none
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideoenc_yuv420_none
rename to ffmpeg-2-8-12/tests/ref/fate/utvideoenc_yuv420_none
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideoenc_yuv422_left b/ffmpeg-2-8-12/tests/ref/fate/utvideoenc_yuv422_left
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideoenc_yuv422_left
rename to ffmpeg-2-8-12/tests/ref/fate/utvideoenc_yuv422_left
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideoenc_yuv422_median b/ffmpeg-2-8-12/tests/ref/fate/utvideoenc_yuv422_median
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideoenc_yuv422_median
rename to ffmpeg-2-8-12/tests/ref/fate/utvideoenc_yuv422_median
diff --git a/ffmpeg-2-8-11/tests/ref/fate/utvideoenc_yuv422_none b/ffmpeg-2-8-12/tests/ref/fate/utvideoenc_yuv422_none
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/utvideoenc_yuv422_none
rename to ffmpeg-2-8-12/tests/ref/fate/utvideoenc_yuv422_none
diff --git a/ffmpeg-2-8-11/tests/ref/fate/v210 b/ffmpeg-2-8-12/tests/ref/fate/v210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/v210
rename to ffmpeg-2-8-12/tests/ref/fate/v210
diff --git a/ffmpeg-2-8-11/tests/ref/fate/v410dec b/ffmpeg-2-8-12/tests/ref/fate/v410dec
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/v410dec
rename to ffmpeg-2-8-12/tests/ref/fate/v410dec
diff --git a/ffmpeg-2-8-11/tests/ref/fate/v410enc b/ffmpeg-2-8-12/tests/ref/fate/v410enc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/v410enc
rename to ffmpeg-2-8-12/tests/ref/fate/v410enc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vb b/ffmpeg-2-8-12/tests/ref/fate/vb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vb
rename to ffmpeg-2-8-12/tests/ref/fate/vb
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vble b/ffmpeg-2-8-12/tests/ref/fate/vble
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vble
rename to ffmpeg-2-8-12/tests/ref/fate/vble
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vc1-ism b/ffmpeg-2-8-12/tests/ref/fate/vc1-ism
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vc1-ism
rename to ffmpeg-2-8-12/tests/ref/fate/vc1-ism
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vc1_ilaced_twomv b/ffmpeg-2-8-12/tests/ref/fate/vc1_ilaced_twomv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vc1_ilaced_twomv
rename to ffmpeg-2-8-12/tests/ref/fate/vc1_ilaced_twomv
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vc1_sa00040 b/ffmpeg-2-8-12/tests/ref/fate/vc1_sa00040
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vc1_sa00040
rename to ffmpeg-2-8-12/tests/ref/fate/vc1_sa00040
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vc1_sa00050 b/ffmpeg-2-8-12/tests/ref/fate/vc1_sa00050
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vc1_sa00050
rename to ffmpeg-2-8-12/tests/ref/fate/vc1_sa00050
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vc1_sa10091 b/ffmpeg-2-8-12/tests/ref/fate/vc1_sa10091
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vc1_sa10091
rename to ffmpeg-2-8-12/tests/ref/fate/vc1_sa10091
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vc1_sa10143 b/ffmpeg-2-8-12/tests/ref/fate/vc1_sa10143
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vc1_sa10143
rename to ffmpeg-2-8-12/tests/ref/fate/vc1_sa10143
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vc1_sa20021 b/ffmpeg-2-8-12/tests/ref/fate/vc1_sa20021
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vc1_sa20021
rename to ffmpeg-2-8-12/tests/ref/fate/vc1_sa20021
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vcr1 b/ffmpeg-2-8-12/tests/ref/fate/vcr1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vcr1
rename to ffmpeg-2-8-12/tests/ref/fate/vcr1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vcr2 b/ffmpeg-2-8-12/tests/ref/fate/vcr2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vcr2
rename to ffmpeg-2-8-12/tests/ref/fate/vcr2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/videoxl b/ffmpeg-2-8-12/tests/ref/fate/videoxl
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/videoxl
rename to ffmpeg-2-8-12/tests/ref/fate/videoxl
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vmnc-16bit b/ffmpeg-2-8-12/tests/ref/fate/vmnc-16bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vmnc-16bit
rename to ffmpeg-2-8-12/tests/ref/fate/vmnc-16bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vmnc-32bit b/ffmpeg-2-8-12/tests/ref/fate/vmnc-32bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vmnc-32bit
rename to ffmpeg-2-8-12/tests/ref/fate/vmnc-32bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp31 b/ffmpeg-2-8-12/tests/ref/fate/vp31
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp31
rename to ffmpeg-2-8-12/tests/ref/fate/vp31
diff --git a/ffmpeg-2-8-12/tests/ref/fate/vp5 b/ffmpeg-2-8-12/tests/ref/fate/vp5
new file mode 100644
index 0000000..f044567
--- /dev/null
+++ b/ffmpeg-2-8-12/tests/ref/fate/vp5
@@ -0,0 +1,248 @@
+#tb 0: 1001/24000
+0, 0, 0, 1, 233472, 0x27488413
+0, 1, 1, 1, 233472, 0x4af384b5
+0, 2, 2, 1, 233472, 0x948d845d
+0, 3, 3, 1, 233472, 0xd6ed845e
+0, 4, 4, 1, 233472, 0x230f8444
+0, 5, 5, 1, 233472, 0x230f8444
+0, 6, 6, 1, 233472, 0x230f8444
+0, 7, 7, 1, 233472, 0xa5078424
+0, 8, 8, 1, 233472, 0xa5078424
+0, 9, 9, 1, 233472, 0xa5078424
+0, 10, 10, 1, 233472, 0xa5078424
+0, 11, 11, 1, 233472, 0xa5078424
+0, 12, 12, 1, 233472, 0xa5078424
+0, 13, 13, 1, 233472, 0xa5078424
+0, 14, 14, 1, 233472, 0xa5078424
+0, 15, 15, 1, 233472, 0xa5078424
+0, 16, 16, 1, 233472, 0xa5078424
+0, 17, 17, 1, 233472, 0xa5078424
+0, 18, 18, 1, 233472, 0xa5078424
+0, 19, 19, 1, 233472, 0xa5078424
+0, 20, 20, 1, 233472, 0xa5078424
+0, 21, 21, 1, 233472, 0xa5078424
+0, 22, 22, 1, 233472, 0xa5078424
+0, 23, 23, 1, 233472, 0xa5078424
+0, 24, 24, 1, 233472, 0xa5078424
+0, 25, 25, 1, 233472, 0xa5078424
+0, 26, 26, 1, 233472, 0xa5078424
+0, 27, 27, 1, 233472, 0xa5078424
+0, 28, 28, 1, 233472, 0xa5078424
+0, 29, 29, 1, 233472, 0xa5078424
+0, 30, 30, 1, 233472, 0xa5078424
+0, 31, 31, 1, 233472, 0xa5078424
+0, 32, 32, 1, 233472, 0xa5078424
+0, 33, 33, 1, 233472, 0xa5078424
+0, 34, 34, 1, 233472, 0xa5078424
+0, 35, 35, 1, 233472, 0xa5078424
+0, 36, 36, 1, 233472, 0xa5078424
+0, 37, 37, 1, 233472, 0xa5078424
+0, 38, 38, 1, 233472, 0xa5078424
+0, 39, 39, 1, 233472, 0xa5078424
+0, 40, 40, 1, 233472, 0x05667dea
+0, 41, 41, 1, 233472, 0x6ae1823e
+0, 42, 42, 1, 233472, 0x3c8a7ea9
+0, 43, 43, 1, 233472, 0xcae2832a
+0, 44, 44, 1, 233472, 0x547a7ec2
+0, 45, 45, 1, 233472, 0xa6628327
+0, 46, 46, 1, 233472, 0xecd77edc
+0, 47, 47, 1, 233472, 0xe9538356
+0, 48, 48, 1, 233472, 0xca297eb1
+0, 49, 49, 1, 233472, 0xe5648329
+0, 50, 50, 1, 233472, 0xad8c7e94
+0, 51, 51, 1, 233472, 0xca0d82fc
+0, 52, 52, 1, 233472, 0x62277e8d
+0, 53, 53, 1, 233472, 0x7ef782f5
+0, 54, 54, 1, 233472, 0x09b27e8d
+0, 55, 55, 1, 233472, 0x66f382f5
+0, 56, 56, 1, 233472, 0x0aaa7e8d
+0, 57, 57, 1, 233472, 0x676b82f5
+0, 58, 58, 1, 233472, 0x0a8a7e8d
+0, 59, 59, 1, 233472, 0x670b82f5
+0, 60, 60, 1, 233472, 0x09fa7e8d
+0, 61, 61, 1, 233472, 0x671b82f5
+0, 62, 62, 1, 233472, 0x0ac27e8d
+0, 63, 63, 1, 233472, 0x674382f5
+0, 64, 64, 1, 233472, 0x0a727e8d
+0, 65, 65, 1, 233472, 0x673382f5
+0, 66, 66, 1, 233472, 0x0a127e8d
+0, 67, 67, 1, 233472, 0x66f382f5
+0, 68, 68, 1, 233472, 0x0aaa7e8d
+0, 69, 69, 1, 233472, 0x676b82f5
+0, 70, 70, 1, 233472, 0x0a8a7e8d
+0, 71, 71, 1, 233472, 0x670b82f5
+0, 72, 72, 1, 233472, 0x09fa7e8d
+0, 73, 73, 1, 233472, 0x671b82f5
+0, 74, 74, 1, 233472, 0x0ac27e8d
+0, 75, 75, 1, 233472, 0x674382f5
+0, 76, 76, 1, 233472, 0x0a727e8d
+0, 77, 77, 1, 233472, 0x673382f5
+0, 78, 78, 1, 233472, 0x0a127e8d
+0, 79, 79, 1, 233472, 0xa3917e7f
+0, 80, 80, 1, 233472, 0x0554868d
+0, 81, 81, 1, 233472, 0x05ba6d7a
+0, 82, 82, 1, 233472, 0x05ba6d7a
+0, 83, 83, 1, 233472, 0x05ba6d7a
+0, 84, 84, 1, 233472, 0x05ba6d7a
+0, 85, 85, 1, 233472, 0x05ba6d7a
+0, 86, 86, 1, 233472, 0x05ba6d7a
+0, 87, 87, 1, 233472, 0x05ba6d7a
+0, 88, 88, 1, 233472, 0x05ba6d7a
+0, 89, 89, 1, 233472, 0x05ba6d7a
+0, 90, 90, 1, 233472, 0x05ba6d7a
+0, 91, 91, 1, 233472, 0x05ba6d7a
+0, 92, 92, 1, 233472, 0x05ba6d7a
+0, 93, 93, 1, 233472, 0x05ba6d7a
+0, 94, 94, 1, 233472, 0x05ba6d7a
+0, 95, 95, 1, 233472, 0x05ba6d7a
+0, 96, 96, 1, 233472, 0x05ba6d7a
+0, 97, 97, 1, 233472, 0x05ba6d7a
+0, 98, 98, 1, 233472, 0x05ba6d7a
+0, 99, 99, 1, 233472, 0x05ba6d7a
+0, 100, 100, 1, 233472, 0x05ba6d7a
+0, 101, 101, 1, 233472, 0x05ba6d7a
+0, 102, 102, 1, 233472, 0x05ba6d7a
+0, 103, 103, 1, 233472, 0x05ba6d7a
+0, 104, 104, 1, 233472, 0x3a6a6d61
+0, 105, 105, 1, 233472, 0x0bab7adc
+0, 106, 106, 1, 233472, 0x12b44993
+0, 107, 107, 1, 233472, 0xa20ad6d1
+0, 108, 108, 1, 233472, 0xfd916a4a
+0, 109, 109, 1, 233472, 0xd34f3e95
+0, 110, 110, 1, 233472, 0x19571d5c
+0, 111, 111, 1, 233472, 0x7c8351ad
+0, 112, 112, 1, 233472, 0xea279823
+0, 113, 113, 1, 233472, 0xc5011cfd
+0, 114, 114, 1, 233472, 0xbd7fb9af
+0, 115, 115, 1, 233472, 0xdfb3bb7c
+0, 116, 116, 1, 233472, 0x6d631236
+0, 117, 117, 1, 233472, 0xdb579a7b
+0, 118, 118, 1, 233472, 0x47584a3e
+0, 119, 119, 1, 233472, 0x7a27a914
+0, 120, 120, 1, 233472, 0x2996270d
+0, 121, 121, 1, 233472, 0xefeaa7ed
+0, 122, 122, 1, 233472, 0xa3e74ae1
+0, 123, 123, 1, 233472, 0x8a51d61c
+0, 124, 124, 1, 233472, 0x25085ee7
+0, 125, 125, 1, 233472, 0x0a811253
+0, 126, 126, 1, 233472, 0x7d3eda84
+0, 127, 127, 1, 233472, 0xd0a0887d
+0, 128, 128, 1, 233472, 0xc9e6702c
+0, 129, 129, 1, 233472, 0x0da14346
+0, 130, 130, 1, 233472, 0x040f0605
+0, 131, 131, 1, 233472, 0x76ea841a
+0, 132, 132, 1, 233472, 0x105b6600
+0, 133, 133, 1, 233472, 0x73015e08
+0, 134, 134, 1, 233472, 0xe77d6662
+0, 135, 135, 1, 233472, 0x7514fcd1
+0, 136, 136, 1, 233472, 0xb091a850
+0, 137, 137, 1, 233472, 0x74ccdccd
+0, 138, 138, 1, 233472, 0xd1c002fc
+0, 139, 139, 1, 233472, 0x7bfcfdac
+0, 140, 140, 1, 233472, 0xf48a133f
+0, 141, 141, 1, 233472, 0x279c16dd
+0, 142, 142, 1, 233472, 0x58427907
+0, 143, 143, 1, 233472, 0x4668a8f2
+0, 144, 144, 1, 233472, 0x93fb555f
+0, 145, 145, 1, 233472, 0x49ed3cf2
+0, 146, 146, 1, 233472, 0xd620fac9
+0, 147, 147, 1, 233472, 0xe4efae83
+0, 148, 148, 1, 233472, 0xe4d377be
+0, 149, 149, 1, 233472, 0x6fc229c1
+0, 150, 150, 1, 233472, 0xab5a8898
+0, 151, 151, 1, 233472, 0x58a493dd
+0, 152, 152, 1, 233472, 0x5c1c1093
+0, 153, 153, 1, 233472, 0x2d831af9
+0, 154, 154, 1, 233472, 0x9a0d3cdf
+0, 155, 155, 1, 233472, 0x2be78f0b
+0, 156, 156, 1, 233472, 0xfc7cc656
+0, 157, 157, 1, 233472, 0xaa8624b7
+0, 158, 158, 1, 233472, 0xb9c9afc1
+0, 159, 159, 1, 233472, 0x709e8009
+0, 160, 160, 1, 233472, 0xd2260830
+0, 161, 161, 1, 233472, 0xadb3954e
+0, 162, 162, 1, 233472, 0x74fc3e65
+0, 163, 163, 1, 233472, 0xb4bcdea4
+0, 164, 164, 1, 233472, 0x60c46cf5
+0, 165, 165, 1, 233472, 0x0e48eff8
+0, 166, 166, 1, 233472, 0x60e46733
+0, 167, 167, 1, 233472, 0x708ec89f
+0, 168, 168, 1, 233472, 0x1f11264e
+0, 169, 169, 1, 233472, 0x6cba8300
+0, 170, 170, 1, 233472, 0xd1a5d756
+0, 171, 171, 1, 233472, 0xb936621e
+0, 172, 172, 1, 233472, 0x1667b4af
+0, 173, 173, 1, 233472, 0xc212276d
+0, 174, 174, 1, 233472, 0x9d7a871d
+0, 175, 175, 1, 233472, 0xb52834f9
+0, 176, 176, 1, 233472, 0x983bde84
+0, 177, 177, 1, 233472, 0xd1c63d88
+0, 178, 178, 1, 233472, 0xa38cb687
+0, 179, 179, 1, 233472, 0xd81bf8ff
+0, 180, 180, 1, 233472, 0x688b231a
+0, 181, 181, 1, 233472, 0xd5ad3038
+0, 182, 182, 1, 233472, 0xcd227f74
+0, 183, 183, 1, 233472, 0x81ec23d6
+0, 184, 184, 1, 233472, 0x52c1cd86
+0, 185, 185, 1, 233472, 0xa4199853
+0, 186, 186, 1, 233472, 0xe82c83e4
+0, 187, 187, 1, 233472, 0xe9810f88
+0, 188, 188, 1, 233472, 0x37e95ae7
+0, 189, 189, 1, 233472, 0xf6974d5d
+0, 190, 190, 1, 233472, 0x31788551
+0, 191, 191, 1, 233472, 0x00d6c539
+0, 192, 192, 1, 233472, 0xdbb52151
+0, 193, 193, 1, 233472, 0x594433d3
+0, 194, 194, 1, 233472, 0xeec44f91
+0, 195, 195, 1, 233472, 0x302894bf
+0, 196, 196, 1, 233472, 0x44f5ddc3
+0, 197, 197, 1, 233472, 0x6c1edd28
+0, 198, 198, 1, 233472, 0x7fd1e412
+0, 199, 199, 1, 233472, 0xd771f11b
+0, 200, 200, 1, 233472, 0x09c675d5
+0, 201, 201, 1, 233472, 0x8fd9112e
+0, 202, 202, 1, 233472, 0x602002e5
+0, 203, 203, 1, 233472, 0xb9a22029
+0, 204, 204, 1, 233472, 0x18e99807
+0, 205, 205, 1, 233472, 0x3d8657d8
+0, 206, 206, 1, 233472, 0x4cd73a85
+0, 207, 207, 1, 233472, 0x84ddb474
+0, 208, 208, 1, 233472, 0x69636bb8
+0, 209, 209, 1, 233472, 0xa0436d50
+0, 210, 210, 1, 233472, 0x93c86d78
+0, 211, 211, 1, 233472, 0x05ba6d7a
+0, 212, 212, 1, 233472, 0x05ba6d7a
+0, 213, 213, 1, 233472, 0x05ba6d7a
+0, 214, 214, 1, 233472, 0x126c6406
+0, 215, 215, 1, 233472, 0xe3885a3a
+0, 216, 216, 1, 233472, 0xf1256fe9
+0, 217, 217, 1, 233472, 0x5a84377e
+0, 218, 218, 1, 233472, 0x7c392d90
+0, 219, 219, 1, 233472, 0x8a74df48
+0, 220, 220, 1, 233472, 0xfa394653
+0, 221, 221, 1, 233472, 0xcbe0cc1b
+0, 222, 222, 1, 233472, 0xbf8639cf
+0, 223, 223, 1, 233472, 0x7dd2c935
+0, 224, 224, 1, 233472, 0x1093148f
+0, 225, 225, 1, 233472, 0x624d7d3e
+0, 226, 226, 1, 233472, 0xb340cd65
+0, 227, 227, 1, 233472, 0x6c0ae5c6
+0, 228, 228, 1, 233472, 0x0c5eaf73
+0, 229, 229, 1, 233472, 0x27be64ce
+0, 230, 230, 1, 233472, 0xac8990f4
+0, 231, 231, 1, 233472, 0x1f935102
+0, 232, 232, 1, 233472, 0x6e57d96f
+0, 233, 233, 1, 233472, 0xf246ea4d
+0, 234, 234, 1, 233472, 0x18058011
+0, 235, 235, 1, 233472, 0x5951fe6e
+0, 236, 236, 1, 233472, 0x0f10371d
+0, 237, 237, 1, 233472, 0xe1481043
+0, 238, 238, 1, 233472, 0xdedeefcc
+0, 239, 239, 1, 233472, 0xf8865db2
+0, 240, 240, 1, 233472, 0xe1b3d4d6
+0, 241, 241, 1, 233472, 0x81962c43
+0, 242, 242, 1, 233472, 0xe903d0bb
+0, 243, 243, 1, 233472, 0x6f530ac6
+0, 244, 244, 1, 233472, 0x94f7466c
+0, 245, 245, 1, 233472, 0xa8c1d365
+0, 246, 246, 1, 233472, 0xbf73f1b7
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp60 b/ffmpeg-2-8-12/tests/ref/fate/vp60
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp60
rename to ffmpeg-2-8-12/tests/ref/fate/vp60
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp61 b/ffmpeg-2-8-12/tests/ref/fate/vp61
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp61
rename to ffmpeg-2-8-12/tests/ref/fate/vp61
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp6a b/ffmpeg-2-8-12/tests/ref/fate/vp6a
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp6a
rename to ffmpeg-2-8-12/tests/ref/fate/vp6a
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp6a-skip_alpha b/ffmpeg-2-8-12/tests/ref/fate/vp6a-skip_alpha
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp6a-skip_alpha
rename to ffmpeg-2-8-12/tests/ref/fate/vp6a-skip_alpha
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp6f b/ffmpeg-2-8-12/tests/ref/fate/vp6f
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp6f
rename to ffmpeg-2-8-12/tests/ref/fate/vp6f
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp7 b/ffmpeg-2-8-12/tests/ref/fate/vp7
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp7
rename to ffmpeg-2-8-12/tests/ref/fate/vp7
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-alpha b/ffmpeg-2-8-12/tests/ref/fate/vp8-alpha
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-alpha
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-alpha
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-sign-bias b/ffmpeg-2-8-12/tests/ref/fate/vp8-sign-bias
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-sign-bias
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-sign-bias
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-size-change b/ffmpeg-2-8-12/tests/ref/fate/vp8-size-change
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-size-change
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-size-change
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-001 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-001
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-001
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-001
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-002 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-002
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-002
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-002
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-003 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-003
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-003
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-003
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-004 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-004
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-004
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-004
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-005 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-005
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-005
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-005
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-006 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-006
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-006
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-006
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-007 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-007
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-007
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-007
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-008 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-008
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-008
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-008
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-009 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-009
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-009
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-009
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-010 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-010
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-010
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-010
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-011 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-011
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-011
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-011
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-012 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-012
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-012
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-012
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-013 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-013
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-013
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-013
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-014 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-014
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-014
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-014
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-015 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-015
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-015
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-015
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-016 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-016
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-016
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-016
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-017 b/ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-017
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp8-test-vector-017
rename to ffmpeg-2-8-12/tests/ref/fate/vp8-test-vector-017
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-00 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-00
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-00
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-00
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-01 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-01
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-01
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-01
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-02 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-02
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-02
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-02
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-03 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-03
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-03
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-03
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-04 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-04
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-04
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-04
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-05 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-05
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-05
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-05
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-06 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-06
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-06
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-06
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-07 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-07
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-07
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-07
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-08 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-08
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-08
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-08
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-09 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-09
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-09
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-09
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-10 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-10
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-11 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-11
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-11
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-11
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-12 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-12
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-12
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-12
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-13 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-13
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-13
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-13
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-14 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-14
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-14
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-14
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-15 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-15
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-15
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-15
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-16 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-16
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-17 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-17
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-17
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-17
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-18 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-18
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-18
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-18
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-19 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-19
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-19
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-19
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-20 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-20
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-20
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-20
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-21 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-21
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-21
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-21
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-22 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-22
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-22
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-22
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-23 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-23
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-23
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-23
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-24 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-24
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-24
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-25 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-25
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-25
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-25
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-26 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-26
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-26
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-26
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-27 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-27
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-27
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-27
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-28 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-28
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-28
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-28
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-29 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-29
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-29
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-29
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-30 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-30
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-30
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-30
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-31 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-31
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-31
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-31
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-32 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-32
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-32
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-32
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-33 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-33
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-33
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-33
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-34 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-34
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-34
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-34
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-35 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-35
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-35
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-35
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-36 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-36
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-36
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-36
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-37 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-37
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-37
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-37
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-38 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-38
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-38
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-38
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-39 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-39
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-39
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-39
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-40 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-40
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-40
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-40
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-41 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-41
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-41
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-41
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-42 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-42
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-42
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-42
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-43 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-43
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-43
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-43
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-44 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-44
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-44
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-44
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-45 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-45
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-45
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-45
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-46 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-46
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-46
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-46
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-47 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-47
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-47
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-47
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-48 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-48
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-48
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-48
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-49 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-49
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-49
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-49
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-50 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-50
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-50
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-50
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-51 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-51
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-51
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-51
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-52 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-52
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-52
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-52
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-53 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-53
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-53
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-53
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-54 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-54
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-54
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-54
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-55 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-55
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-55
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-55
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-56 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-56
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-56
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-56
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-57 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-57
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-57
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-57
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-58 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-58
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-58
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-58
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-59 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-59
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-59
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-59
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-60 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-60
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-60
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-60
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-61 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-61
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-61
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-61
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-62 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-62
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-62
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-62
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-63 b/ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-63
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-00-quantizer-63
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-00-quantizer-63
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-01-sharpness-1 b/ffmpeg-2-8-12/tests/ref/fate/vp9-01-sharpness-1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-01-sharpness-1
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-01-sharpness-1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-01-sharpness-2 b/ffmpeg-2-8-12/tests/ref/fate/vp9-01-sharpness-2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-01-sharpness-2
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-01-sharpness-2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-01-sharpness-3 b/ffmpeg-2-8-12/tests/ref/fate/vp9-01-sharpness-3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-01-sharpness-3
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-01-sharpness-3
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-01-sharpness-4 b/ffmpeg-2-8-12/tests/ref/fate/vp9-01-sharpness-4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-01-sharpness-4
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-01-sharpness-4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-01-sharpness-5 b/ffmpeg-2-8-12/tests/ref/fate/vp9-01-sharpness-5
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-01-sharpness-5
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-01-sharpness-5
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-01-sharpness-6 b/ffmpeg-2-8-12/tests/ref/fate/vp9-01-sharpness-6
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-01-sharpness-6
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-01-sharpness-6
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-01-sharpness-7 b/ffmpeg-2-8-12/tests/ref/fate/vp9-01-sharpness-7
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-01-sharpness-7
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-01-sharpness-7
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x08 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x08
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x08
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x08
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x10 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x10
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x16 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x16
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x18 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x18
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x18
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x18
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x32 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x32
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x32
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x32
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x34 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x34
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x34
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x34
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x64 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x64
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x64
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x64
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x66 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x66
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-08x66
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-08x66
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x08 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x08
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x08
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x08
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x10 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x10
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x16 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x16
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x18 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x18
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x18
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x18
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x32 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x32
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x32
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x32
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x34 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x34
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x34
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x34
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x64 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x64
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x64
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x64
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x66 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x66
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-10x66
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-10x66
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x08 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x08
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x08
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x08
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x10 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x10
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x16 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x16
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x18 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x18
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x18
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x18
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x32 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x32
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x32
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x32
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x34 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x34
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x34
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x34
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x64 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x64
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x64
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x64
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x66 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x66
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-16x66
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-16x66
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x08 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x08
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x08
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x08
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x10 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x10
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x16 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x16
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x18 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x18
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x18
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x18
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x32 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x32
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x32
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x32
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x34 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x34
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x34
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x34
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x64 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x64
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x64
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x64
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x66 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x66
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-18x66
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-18x66
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x08 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x08
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x08
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x08
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x10 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x10
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x16 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x16
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x18 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x18
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x18
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x18
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x32 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x32
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x32
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x32
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x34 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x34
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x34
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x34
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x64 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x64
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x64
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x64
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x66 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x66
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-32x66
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-32x66
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x08 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x08
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x08
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x08
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x10 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x10
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x16 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x16
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x18 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x18
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x18
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x18
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x32 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x32
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x32
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x32
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x34 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x34
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x34
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x34
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x64 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x64
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x64
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x64
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x66 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x66
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-34x66
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-34x66
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x08 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x08
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x08
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x08
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x10 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x10
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x16 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x16
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x18 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x18
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x18
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x18
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x32 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x32
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x32
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x32
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x34 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x34
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x34
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x34
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x64 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x64
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x64
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x64
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x66 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x66
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-64x66
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-64x66
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x08 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x08
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x08
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x08
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x10 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x10
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x16 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x16
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x16
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x18 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x18
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x18
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x18
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x32 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x32
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x32
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x32
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x34 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x34
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x34
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x34
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x64 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x64
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x64
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x64
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x66 b/ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x66
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-02-size-66x66
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-02-size-66x66
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-deltaq b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-deltaq
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-deltaq
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-deltaq
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x196 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x196
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x196
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x196
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x198 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x198
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x198
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x198
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x200 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x200
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x200
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x200
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x202 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x202
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x202
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x202
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x208 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x208
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x208
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x208
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x210 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x210
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x210
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x224 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x224
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x224
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x224
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x226 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x226
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-196x226
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-196x226
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x196 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x196
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x196
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x196
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x198 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x198
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x198
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x198
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x200 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x200
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x200
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x200
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x202 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x202
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x202
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x202
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x208 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x208
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x208
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x208
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x210 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x210
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x210
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x224 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x224
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x224
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x224
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x226 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x226
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-198x226
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-198x226
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x196 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x196
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x196
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x196
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x198 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x198
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x198
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x198
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x200 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x200
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x200
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x200
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x202 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x202
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x202
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x202
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x208 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x208
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x208
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x208
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x210 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x210
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x210
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x224 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x224
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x224
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x224
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x226 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x226
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-200x226
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-200x226
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x196 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x196
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x196
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x196
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x198 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x198
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x198
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x198
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x200 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x200
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x200
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x200
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x202 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x202
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x202
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x202
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x208 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x208
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x208
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x208
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x210 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x210
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x210
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x224 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x224
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x224
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x224
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x226 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x226
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-202x226
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-202x226
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x196 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x196
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x196
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x196
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x198 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x198
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x198
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x198
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x200 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x200
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x200
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x200
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x202 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x202
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x202
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x202
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x208 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x208
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x208
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x208
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x210 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x210
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x210
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x224 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x224
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x224
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x224
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x226 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x226
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-208x226
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-208x226
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x196 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x196
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x196
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x196
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x198 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x198
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x198
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x198
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x200 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x200
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x200
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x200
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x202 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x202
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x202
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x202
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x208 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x208
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x208
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x208
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x210 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x210
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x210
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x224 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x224
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x224
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x224
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x226 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x226
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-210x226
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-210x226
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x196 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x196
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x196
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x196
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x198 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x198
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x198
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x198
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x200 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x200
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x200
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x200
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x202 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x202
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x202
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x202
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x208 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x208
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x208
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x208
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x210 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x210
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x210
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x224 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x224
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x224
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x224
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x226 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x226
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-224x226
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-224x226
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x196 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x196
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x196
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x196
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x198 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x198
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x198
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x198
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x200 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x200
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x200
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x200
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x202 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x202
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x202
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x202
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x208 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x208
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x208
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x208
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x210 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x210
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x210
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x224 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x224
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x224
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x224
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x226 b/ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x226
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-03-size-226x226
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-03-size-226x226
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-05-resize b/ffmpeg-2-8-12/tests/ref/fate/vp9-05-resize
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-05-resize
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-05-resize
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-06-bilinear b/ffmpeg-2-8-12/tests/ref/fate/vp9-06-bilinear
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-06-bilinear
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-06-bilinear
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-09-lf_deltas b/ffmpeg-2-8-12/tests/ref/fate/vp9-09-lf_deltas
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-09-lf_deltas
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-09-lf_deltas
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-10-show-existing-frame b/ffmpeg-2-8-12/tests/ref/fate/vp9-10-show-existing-frame
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-10-show-existing-frame
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-10-show-existing-frame
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-10-show-existing-frame2 b/ffmpeg-2-8-12/tests/ref/fate/vp9-10-show-existing-frame2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-10-show-existing-frame2
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-10-show-existing-frame2
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-15-segkey_adpq b/ffmpeg-2-8-12/tests/ref/fate/vp9-15-segkey_adpq
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-15-segkey_adpq
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-15-segkey_adpq
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-16-intra-only b/ffmpeg-2-8-12/tests/ref/fate/vp9-16-intra-only
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-16-intra-only
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-16-intra-only
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-2pass-akiyo b/ffmpeg-2-8-12/tests/ref/fate/vp9-2pass-akiyo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-2pass-akiyo
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-2pass-akiyo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-parallelmode-akiyo b/ffmpeg-2-8-12/tests/ref/fate/vp9-parallelmode-akiyo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-parallelmode-akiyo
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-parallelmode-akiyo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-segmentation-aq-akiyo b/ffmpeg-2-8-12/tests/ref/fate/vp9-segmentation-aq-akiyo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-segmentation-aq-akiyo
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-segmentation-aq-akiyo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-segmentation-sf-akiyo b/ffmpeg-2-8-12/tests/ref/fate/vp9-segmentation-sf-akiyo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-segmentation-sf-akiyo
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-segmentation-sf-akiyo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-tiling-pedestrian b/ffmpeg-2-8-12/tests/ref/fate/vp9-tiling-pedestrian
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-tiling-pedestrian
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-tiling-pedestrian
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-trac3849 b/ffmpeg-2-8-12/tests/ref/fate/vp9-trac3849
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-trac3849
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-trac3849
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9-trac4359 b/ffmpeg-2-8-12/tests/ref/fate/vp9-trac4359
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9-trac4359
rename to ffmpeg-2-8-12/tests/ref/fate/vp9-trac4359
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9p1-04-yuv422 b/ffmpeg-2-8-12/tests/ref/fate/vp9p1-04-yuv422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9p1-04-yuv422
rename to ffmpeg-2-8-12/tests/ref/fate/vp9p1-04-yuv422
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9p1-04-yuv440 b/ffmpeg-2-8-12/tests/ref/fate/vp9p1-04-yuv440
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9p1-04-yuv440
rename to ffmpeg-2-8-12/tests/ref/fate/vp9p1-04-yuv440
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9p1-04-yuv444 b/ffmpeg-2-8-12/tests/ref/fate/vp9p1-04-yuv444
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9p1-04-yuv444
rename to ffmpeg-2-8-12/tests/ref/fate/vp9p1-04-yuv444
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9p2-20-10bit-yuv420 b/ffmpeg-2-8-12/tests/ref/fate/vp9p2-20-10bit-yuv420
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9p2-20-10bit-yuv420
rename to ffmpeg-2-8-12/tests/ref/fate/vp9p2-20-10bit-yuv420
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9p2-20-12bit-yuv420 b/ffmpeg-2-8-12/tests/ref/fate/vp9p2-20-12bit-yuv420
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9p2-20-12bit-yuv420
rename to ffmpeg-2-8-12/tests/ref/fate/vp9p2-20-12bit-yuv420
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9p3-20-10bit-yuv422 b/ffmpeg-2-8-12/tests/ref/fate/vp9p3-20-10bit-yuv422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9p3-20-10bit-yuv422
rename to ffmpeg-2-8-12/tests/ref/fate/vp9p3-20-10bit-yuv422
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9p3-20-10bit-yuv440 b/ffmpeg-2-8-12/tests/ref/fate/vp9p3-20-10bit-yuv440
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9p3-20-10bit-yuv440
rename to ffmpeg-2-8-12/tests/ref/fate/vp9p3-20-10bit-yuv440
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9p3-20-10bit-yuv444 b/ffmpeg-2-8-12/tests/ref/fate/vp9p3-20-10bit-yuv444
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9p3-20-10bit-yuv444
rename to ffmpeg-2-8-12/tests/ref/fate/vp9p3-20-10bit-yuv444
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9p3-20-12bit-yuv422 b/ffmpeg-2-8-12/tests/ref/fate/vp9p3-20-12bit-yuv422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9p3-20-12bit-yuv422
rename to ffmpeg-2-8-12/tests/ref/fate/vp9p3-20-12bit-yuv422
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9p3-20-12bit-yuv440 b/ffmpeg-2-8-12/tests/ref/fate/vp9p3-20-12bit-yuv440
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9p3-20-12bit-yuv440
rename to ffmpeg-2-8-12/tests/ref/fate/vp9p3-20-12bit-yuv440
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vp9p3-20-12bit-yuv444 b/ffmpeg-2-8-12/tests/ref/fate/vp9p3-20-12bit-yuv444
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vp9p3-20-12bit-yuv444
rename to ffmpeg-2-8-12/tests/ref/fate/vp9p3-20-12bit-yuv444
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vqa-cc b/ffmpeg-2-8-12/tests/ref/fate/vqa-cc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vqa-cc
rename to ffmpeg-2-8-12/tests/ref/fate/vqa-cc
diff --git a/ffmpeg-2-8-11/tests/ref/fate/vqf-demux b/ffmpeg-2-8-12/tests/ref/fate/vqf-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/vqf-demux
rename to ffmpeg-2-8-12/tests/ref/fate/vqf-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/w64 b/ffmpeg-2-8-12/tests/ref/fate/w64
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/w64
rename to ffmpeg-2-8-12/tests/ref/fate/w64
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-channels-4.0 b/ffmpeg-2-8-12/tests/ref/fate/wavpack-channels-4.0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-channels-4.0
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-channels-4.0
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-channels-5.1 b/ffmpeg-2-8-12/tests/ref/fate/wavpack-channels-5.1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-channels-5.1
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-channels-5.1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-channels-6.1 b/ffmpeg-2-8-12/tests/ref/fate/wavpack-channels-6.1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-channels-6.1
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-channels-6.1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-channels-7.1 b/ffmpeg-2-8-12/tests/ref/fate/wavpack-channels-7.1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-channels-7.1
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-channels-7.1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-channels-monofloat b/ffmpeg-2-8-12/tests/ref/fate/wavpack-channels-monofloat
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-channels-monofloat
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-channels-monofloat
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-channels-monoint b/ffmpeg-2-8-12/tests/ref/fate/wavpack-channels-monoint
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-channels-monoint
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-channels-monoint
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-clipping b/ffmpeg-2-8-12/tests/ref/fate/wavpack-clipping
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-clipping
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-clipping
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-cuesheet b/ffmpeg-2-8-12/tests/ref/fate/wavpack-cuesheet
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-cuesheet
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-cuesheet
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-falsestereo b/ffmpeg-2-8-12/tests/ref/fate/wavpack-falsestereo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-falsestereo
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-falsestereo
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-lossless-12bit b/ffmpeg-2-8-12/tests/ref/fate/wavpack-lossless-12bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-lossless-12bit
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-lossless-12bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-lossless-16bit b/ffmpeg-2-8-12/tests/ref/fate/wavpack-lossless-16bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-lossless-16bit
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-lossless-16bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-lossless-24bit b/ffmpeg-2-8-12/tests/ref/fate/wavpack-lossless-24bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-lossless-24bit
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-lossless-24bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-lossless-32bit b/ffmpeg-2-8-12/tests/ref/fate/wavpack-lossless-32bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-lossless-32bit
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-lossless-32bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-lossless-8bit b/ffmpeg-2-8-12/tests/ref/fate/wavpack-lossless-8bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-lossless-8bit
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-lossless-8bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-lossless-float b/ffmpeg-2-8-12/tests/ref/fate/wavpack-lossless-float
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-lossless-float
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-lossless-float
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-lossy-16bit b/ffmpeg-2-8-12/tests/ref/fate/wavpack-lossy-16bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-lossy-16bit
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-lossy-16bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-lossy-24bit b/ffmpeg-2-8-12/tests/ref/fate/wavpack-lossy-24bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-lossy-24bit
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-lossy-24bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-lossy-32bit b/ffmpeg-2-8-12/tests/ref/fate/wavpack-lossy-32bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-lossy-32bit
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-lossy-32bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-lossy-8bit b/ffmpeg-2-8-12/tests/ref/fate/wavpack-lossy-8bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-lossy-8bit
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-lossy-8bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-lossy-float b/ffmpeg-2-8-12/tests/ref/fate/wavpack-lossy-float
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-lossy-float
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-lossy-float
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-matroskamode b/ffmpeg-2-8-12/tests/ref/fate/wavpack-matroskamode
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-matroskamode
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-matroskamode
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-speed-default b/ffmpeg-2-8-12/tests/ref/fate/wavpack-speed-default
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-speed-default
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-speed-default
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-speed-fast b/ffmpeg-2-8-12/tests/ref/fate/wavpack-speed-fast
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-speed-fast
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-speed-fast
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-speed-high b/ffmpeg-2-8-12/tests/ref/fate/wavpack-speed-high
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-speed-high
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-speed-high
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-speed-vhigh b/ffmpeg-2-8-12/tests/ref/fate/wavpack-speed-vhigh
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-speed-vhigh
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-speed-vhigh
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wavpack-zerolsbs b/ffmpeg-2-8-12/tests/ref/fate/wavpack-zerolsbs
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wavpack-zerolsbs
rename to ffmpeg-2-8-12/tests/ref/fate/wavpack-zerolsbs
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wc3movie-xan b/ffmpeg-2-8-12/tests/ref/fate/wc3movie-xan
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wc3movie-xan
rename to ffmpeg-2-8-12/tests/ref/fate/wc3movie-xan
diff --git a/ffmpeg-2-8-11/tests/ref/fate/webm-dash-manifest b/ffmpeg-2-8-12/tests/ref/fate/webm-dash-manifest
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/webm-dash-manifest
rename to ffmpeg-2-8-12/tests/ref/fate/webm-dash-manifest
diff --git a/ffmpeg-2-8-11/tests/ref/fate/webm-dash-manifest-live b/ffmpeg-2-8-12/tests/ref/fate/webm-dash-manifest-live
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/webm-dash-manifest-live
rename to ffmpeg-2-8-12/tests/ref/fate/webm-dash-manifest-live
diff --git a/ffmpeg-2-8-11/tests/ref/fate/webm-dash-manifest-representations b/ffmpeg-2-8-12/tests/ref/fate/webm-dash-manifest-representations
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/webm-dash-manifest-representations
rename to ffmpeg-2-8-12/tests/ref/fate/webm-dash-manifest-representations
diff --git a/ffmpeg-2-8-11/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams b/ffmpeg-2-8-12/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams
rename to ffmpeg-2-8-12/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams
diff --git a/ffmpeg-2-8-11/tests/ref/fate/webm-dash-manifest-unaligned-video-streams b/ffmpeg-2-8-12/tests/ref/fate/webm-dash-manifest-unaligned-video-streams
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/webm-dash-manifest-unaligned-video-streams
rename to ffmpeg-2-8-12/tests/ref/fate/webm-dash-manifest-unaligned-video-streams
diff --git a/ffmpeg-2-8-11/tests/ref/fate/westwood-aud b/ffmpeg-2-8-12/tests/ref/fate/westwood-aud
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/westwood-aud
rename to ffmpeg-2-8-12/tests/ref/fate/westwood-aud
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wmv8-drm b/ffmpeg-2-8-12/tests/ref/fate/wmv8-drm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wmv8-drm
rename to ffmpeg-2-8-12/tests/ref/fate/wmv8-drm
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wmv8-drm-nodec b/ffmpeg-2-8-12/tests/ref/fate/wmv8-drm-nodec
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wmv8-drm-nodec
rename to ffmpeg-2-8-12/tests/ref/fate/wmv8-drm-nodec
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wmv8-x8intra b/ffmpeg-2-8-12/tests/ref/fate/wmv8-x8intra
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wmv8-x8intra
rename to ffmpeg-2-8-12/tests/ref/fate/wmv8-x8intra
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wnv1 b/ffmpeg-2-8-12/tests/ref/fate/wnv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wnv1
rename to ffmpeg-2-8-12/tests/ref/fate/wnv1
diff --git a/ffmpeg-2-8-11/tests/ref/fate/ws_snd b/ffmpeg-2-8-12/tests/ref/fate/ws_snd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/ws_snd
rename to ffmpeg-2-8-12/tests/ref/fate/ws_snd
diff --git a/ffmpeg-2-8-11/tests/ref/fate/wtv-demux b/ffmpeg-2-8-12/tests/ref/fate/wtv-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/wtv-demux
rename to ffmpeg-2-8-12/tests/ref/fate/wtv-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/xbm10 b/ffmpeg-2-8-12/tests/ref/fate/xbm10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/xbm10
rename to ffmpeg-2-8-12/tests/ref/fate/xbm10
diff --git a/ffmpeg-2-8-11/tests/ref/fate/xbm11 b/ffmpeg-2-8-12/tests/ref/fate/xbm11
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/xbm11
rename to ffmpeg-2-8-12/tests/ref/fate/xbm11
diff --git a/ffmpeg-2-8-11/tests/ref/fate/xface b/ffmpeg-2-8-12/tests/ref/fate/xface
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/xface
rename to ffmpeg-2-8-12/tests/ref/fate/xface
diff --git a/ffmpeg-2-8-11/tests/ref/fate/xmv-demux b/ffmpeg-2-8-12/tests/ref/fate/xmv-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/xmv-demux
rename to ffmpeg-2-8-12/tests/ref/fate/xmv-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/xtea b/ffmpeg-2-8-12/tests/ref/fate/xtea
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/xtea
rename to ffmpeg-2-8-12/tests/ref/fate/xtea
diff --git a/ffmpeg-2-8-11/tests/ref/fate/xvid-custom-matrix b/ffmpeg-2-8-12/tests/ref/fate/xvid-custom-matrix
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/xvid-custom-matrix
rename to ffmpeg-2-8-12/tests/ref/fate/xvid-custom-matrix
diff --git a/ffmpeg-2-8-11/tests/ref/fate/xvid-idct b/ffmpeg-2-8-12/tests/ref/fate/xvid-idct
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/xvid-idct
rename to ffmpeg-2-8-12/tests/ref/fate/xvid-idct
diff --git a/ffmpeg-2-8-11/tests/ref/fate/xwma-demux b/ffmpeg-2-8-12/tests/ref/fate/xwma-demux
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/xwma-demux
rename to ffmpeg-2-8-12/tests/ref/fate/xwma-demux
diff --git a/ffmpeg-2-8-11/tests/ref/fate/xxan-wc4 b/ffmpeg-2-8-12/tests/ref/fate/xxan-wc4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/xxan-wc4
rename to ffmpeg-2-8-12/tests/ref/fate/xxan-wc4
diff --git a/ffmpeg-2-8-11/tests/ref/fate/yop b/ffmpeg-2-8-12/tests/ref/fate/yop
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/yop
rename to ffmpeg-2-8-12/tests/ref/fate/yop
diff --git a/ffmpeg-2-8-11/tests/ref/fate/zerocodec b/ffmpeg-2-8-12/tests/ref/fate/zerocodec
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/zerocodec
rename to ffmpeg-2-8-12/tests/ref/fate/zerocodec
diff --git a/ffmpeg-2-8-11/tests/ref/fate/zlib b/ffmpeg-2-8-12/tests/ref/fate/zlib
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/zlib
rename to ffmpeg-2-8-12/tests/ref/fate/zlib
diff --git a/ffmpeg-2-8-11/tests/ref/fate/zmbv-15bit b/ffmpeg-2-8-12/tests/ref/fate/zmbv-15bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/zmbv-15bit
rename to ffmpeg-2-8-12/tests/ref/fate/zmbv-15bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/zmbv-16bit b/ffmpeg-2-8-12/tests/ref/fate/zmbv-16bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/zmbv-16bit
rename to ffmpeg-2-8-12/tests/ref/fate/zmbv-16bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/zmbv-32bit b/ffmpeg-2-8-12/tests/ref/fate/zmbv-32bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/zmbv-32bit
rename to ffmpeg-2-8-12/tests/ref/fate/zmbv-32bit
diff --git a/ffmpeg-2-8-11/tests/ref/fate/zmbv-8bit b/ffmpeg-2-8-12/tests/ref/fate/zmbv-8bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/fate/zmbv-8bit
rename to ffmpeg-2-8-12/tests/ref/fate/zmbv-8bit
diff --git a/ffmpeg-2-8-11/tests/ref/lavf-fate/latm b/ffmpeg-2-8-12/tests/ref/lavf-fate/latm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf-fate/latm
rename to ffmpeg-2-8-12/tests/ref/lavf-fate/latm
diff --git a/ffmpeg-2-8-11/tests/ref/lavf-fate/mp3 b/ffmpeg-2-8-12/tests/ref/lavf-fate/mp3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf-fate/mp3
rename to ffmpeg-2-8-12/tests/ref/lavf-fate/mp3
diff --git a/ffmpeg-2-8-11/tests/ref/lavf-fate/ogg_vp3 b/ffmpeg-2-8-12/tests/ref/lavf-fate/ogg_vp3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf-fate/ogg_vp3
rename to ffmpeg-2-8-12/tests/ref/lavf-fate/ogg_vp3
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/aiff b/ffmpeg-2-8-12/tests/ref/lavf/aiff
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/aiff
rename to ffmpeg-2-8-12/tests/ref/lavf/aiff
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/alaw b/ffmpeg-2-8-12/tests/ref/lavf/alaw
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/alaw
rename to ffmpeg-2-8-12/tests/ref/lavf/alaw
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/asf b/ffmpeg-2-8-12/tests/ref/lavf/asf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/asf
rename to ffmpeg-2-8-12/tests/ref/lavf/asf
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/ast b/ffmpeg-2-8-12/tests/ref/lavf/ast
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/ast
rename to ffmpeg-2-8-12/tests/ref/lavf/ast
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/au b/ffmpeg-2-8-12/tests/ref/lavf/au
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/au
rename to ffmpeg-2-8-12/tests/ref/lavf/au
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/avi b/ffmpeg-2-8-12/tests/ref/lavf/avi
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/avi
rename to ffmpeg-2-8-12/tests/ref/lavf/avi
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/bmp b/ffmpeg-2-8-12/tests/ref/lavf/bmp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/bmp
rename to ffmpeg-2-8-12/tests/ref/lavf/bmp
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/caf b/ffmpeg-2-8-12/tests/ref/lavf/caf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/caf
rename to ffmpeg-2-8-12/tests/ref/lavf/caf
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/dpx b/ffmpeg-2-8-12/tests/ref/lavf/dpx
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/dpx
rename to ffmpeg-2-8-12/tests/ref/lavf/dpx
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/dv_fmt b/ffmpeg-2-8-12/tests/ref/lavf/dv_fmt
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/dv_fmt
rename to ffmpeg-2-8-12/tests/ref/lavf/dv_fmt
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/ffm b/ffmpeg-2-8-12/tests/ref/lavf/ffm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/ffm
rename to ffmpeg-2-8-12/tests/ref/lavf/ffm
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/flm b/ffmpeg-2-8-12/tests/ref/lavf/flm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/flm
rename to ffmpeg-2-8-12/tests/ref/lavf/flm
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/flv_fmt b/ffmpeg-2-8-12/tests/ref/lavf/flv_fmt
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/flv_fmt
rename to ffmpeg-2-8-12/tests/ref/lavf/flv_fmt
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/gif b/ffmpeg-2-8-12/tests/ref/lavf/gif
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/gif
rename to ffmpeg-2-8-12/tests/ref/lavf/gif
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/gxf b/ffmpeg-2-8-12/tests/ref/lavf/gxf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/gxf
rename to ffmpeg-2-8-12/tests/ref/lavf/gxf
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/ircam b/ffmpeg-2-8-12/tests/ref/lavf/ircam
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/ircam
rename to ffmpeg-2-8-12/tests/ref/lavf/ircam
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/ismv b/ffmpeg-2-8-12/tests/ref/lavf/ismv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/ismv
rename to ffmpeg-2-8-12/tests/ref/lavf/ismv
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/jpg b/ffmpeg-2-8-12/tests/ref/lavf/jpg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/jpg
rename to ffmpeg-2-8-12/tests/ref/lavf/jpg
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/mkv b/ffmpeg-2-8-12/tests/ref/lavf/mkv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/mkv
rename to ffmpeg-2-8-12/tests/ref/lavf/mkv
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/mmf b/ffmpeg-2-8-12/tests/ref/lavf/mmf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/mmf
rename to ffmpeg-2-8-12/tests/ref/lavf/mmf
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/mov b/ffmpeg-2-8-12/tests/ref/lavf/mov
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/mov
rename to ffmpeg-2-8-12/tests/ref/lavf/mov
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/mpg b/ffmpeg-2-8-12/tests/ref/lavf/mpg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/mpg
rename to ffmpeg-2-8-12/tests/ref/lavf/mpg
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/mulaw b/ffmpeg-2-8-12/tests/ref/lavf/mulaw
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/mulaw
rename to ffmpeg-2-8-12/tests/ref/lavf/mulaw
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/mxf b/ffmpeg-2-8-12/tests/ref/lavf/mxf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/mxf
rename to ffmpeg-2-8-12/tests/ref/lavf/mxf
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/mxf_d10 b/ffmpeg-2-8-12/tests/ref/lavf/mxf_d10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/mxf_d10
rename to ffmpeg-2-8-12/tests/ref/lavf/mxf_d10
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/mxf_opatom b/ffmpeg-2-8-12/tests/ref/lavf/mxf_opatom
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/mxf_opatom
rename to ffmpeg-2-8-12/tests/ref/lavf/mxf_opatom
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/mxf_opatom_audio b/ffmpeg-2-8-12/tests/ref/lavf/mxf_opatom_audio
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/mxf_opatom_audio
rename to ffmpeg-2-8-12/tests/ref/lavf/mxf_opatom_audio
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/nut b/ffmpeg-2-8-12/tests/ref/lavf/nut
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/nut
rename to ffmpeg-2-8-12/tests/ref/lavf/nut
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/ogg b/ffmpeg-2-8-12/tests/ref/lavf/ogg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/ogg
rename to ffmpeg-2-8-12/tests/ref/lavf/ogg
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/pam b/ffmpeg-2-8-12/tests/ref/lavf/pam
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/pam
rename to ffmpeg-2-8-12/tests/ref/lavf/pam
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/pbmpipe b/ffmpeg-2-8-12/tests/ref/lavf/pbmpipe
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/pbmpipe
rename to ffmpeg-2-8-12/tests/ref/lavf/pbmpipe
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/pcx b/ffmpeg-2-8-12/tests/ref/lavf/pcx
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/pcx
rename to ffmpeg-2-8-12/tests/ref/lavf/pcx
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/pgm b/ffmpeg-2-8-12/tests/ref/lavf/pgm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/pgm
rename to ffmpeg-2-8-12/tests/ref/lavf/pgm
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/pgmpipe b/ffmpeg-2-8-12/tests/ref/lavf/pgmpipe
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/pgmpipe
rename to ffmpeg-2-8-12/tests/ref/lavf/pgmpipe
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/pixfmt b/ffmpeg-2-8-12/tests/ref/lavf/pixfmt
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/pixfmt
rename to ffmpeg-2-8-12/tests/ref/lavf/pixfmt
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/png b/ffmpeg-2-8-12/tests/ref/lavf/png
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/png
rename to ffmpeg-2-8-12/tests/ref/lavf/png
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/ppm b/ffmpeg-2-8-12/tests/ref/lavf/ppm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/ppm
rename to ffmpeg-2-8-12/tests/ref/lavf/ppm
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/ppmpipe b/ffmpeg-2-8-12/tests/ref/lavf/ppmpipe
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/ppmpipe
rename to ffmpeg-2-8-12/tests/ref/lavf/ppmpipe
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/rm b/ffmpeg-2-8-12/tests/ref/lavf/rm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/rm
rename to ffmpeg-2-8-12/tests/ref/lavf/rm
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/rso b/ffmpeg-2-8-12/tests/ref/lavf/rso
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/rso
rename to ffmpeg-2-8-12/tests/ref/lavf/rso
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/sgi b/ffmpeg-2-8-12/tests/ref/lavf/sgi
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/sgi
rename to ffmpeg-2-8-12/tests/ref/lavf/sgi
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/smjpeg b/ffmpeg-2-8-12/tests/ref/lavf/smjpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/smjpeg
rename to ffmpeg-2-8-12/tests/ref/lavf/smjpeg
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/sox b/ffmpeg-2-8-12/tests/ref/lavf/sox
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/sox
rename to ffmpeg-2-8-12/tests/ref/lavf/sox
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/sunrast b/ffmpeg-2-8-12/tests/ref/lavf/sunrast
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/sunrast
rename to ffmpeg-2-8-12/tests/ref/lavf/sunrast
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/swf b/ffmpeg-2-8-12/tests/ref/lavf/swf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/swf
rename to ffmpeg-2-8-12/tests/ref/lavf/swf
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/tga b/ffmpeg-2-8-12/tests/ref/lavf/tga
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/tga
rename to ffmpeg-2-8-12/tests/ref/lavf/tga
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/tiff b/ffmpeg-2-8-12/tests/ref/lavf/tiff
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/tiff
rename to ffmpeg-2-8-12/tests/ref/lavf/tiff
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/ts b/ffmpeg-2-8-12/tests/ref/lavf/ts
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/ts
rename to ffmpeg-2-8-12/tests/ref/lavf/ts
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/voc b/ffmpeg-2-8-12/tests/ref/lavf/voc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/voc
rename to ffmpeg-2-8-12/tests/ref/lavf/voc
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/voc_s16 b/ffmpeg-2-8-12/tests/ref/lavf/voc_s16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/voc_s16
rename to ffmpeg-2-8-12/tests/ref/lavf/voc_s16
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/w64 b/ffmpeg-2-8-12/tests/ref/lavf/w64
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/w64
rename to ffmpeg-2-8-12/tests/ref/lavf/w64
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/wav b/ffmpeg-2-8-12/tests/ref/lavf/wav
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/wav
rename to ffmpeg-2-8-12/tests/ref/lavf/wav
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/wav_peak b/ffmpeg-2-8-12/tests/ref/lavf/wav_peak
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/wav_peak
rename to ffmpeg-2-8-12/tests/ref/lavf/wav_peak
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/wav_peak_only b/ffmpeg-2-8-12/tests/ref/lavf/wav_peak_only
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/wav_peak_only
rename to ffmpeg-2-8-12/tests/ref/lavf/wav_peak_only
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/wtv b/ffmpeg-2-8-12/tests/ref/lavf/wtv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/wtv
rename to ffmpeg-2-8-12/tests/ref/lavf/wtv
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/xbm b/ffmpeg-2-8-12/tests/ref/lavf/xbm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/xbm
rename to ffmpeg-2-8-12/tests/ref/lavf/xbm
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/xwd b/ffmpeg-2-8-12/tests/ref/lavf/xwd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/xwd
rename to ffmpeg-2-8-12/tests/ref/lavf/xwd
diff --git a/ffmpeg-2-8-11/tests/ref/lavf/yuv4mpeg b/ffmpeg-2-8-12/tests/ref/lavf/yuv4mpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/lavf/yuv4mpeg
rename to ffmpeg-2-8-12/tests/ref/lavf/yuv4mpeg
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-ima_qt b/ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-ima_qt
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-ima_qt
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-ima_qt
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-ima_qt-trellis b/ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-ima_qt-trellis
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-ima_qt-trellis
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-ima_qt-trellis
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-ima_wav b/ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-ima_wav
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-ima_wav
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-ima_wav
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-ima_wav-trellis b/ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-ima_wav-trellis
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-ima_wav-trellis
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-ima_wav-trellis
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-ms b/ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-ms
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-ms
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-ms
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-ms-trellis b/ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-ms-trellis
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-ms-trellis
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-ms-trellis
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-swf b/ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-swf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-swf
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-swf
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-swf-trellis b/ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-swf-trellis
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-swf-trellis
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-swf-trellis
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-yamaha b/ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-yamaha
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-yamaha
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-yamaha
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-yamaha-trellis b/ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-yamaha-trellis
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-adpcm-yamaha-trellis
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-adpcm-yamaha-trellis
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-alac b/ffmpeg-2-8-12/tests/ref/seek/acodec-alac
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-alac
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-alac
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-flac b/ffmpeg-2-8-12/tests/ref/seek/acodec-flac
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-flac
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-flac
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-mp2 b/ffmpeg-2-8-12/tests/ref/seek/acodec-mp2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-mp2
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-mp2
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-alaw b/ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-alaw
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-alaw
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-alaw
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-f32be b/ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-f32be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-f32be
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-f32be
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-f32le b/ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-f32le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-f32le
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-f32le
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-f64be b/ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-f64be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-f64be
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-f64be
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-f64le b/ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-f64le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-f64le
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-f64le
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-mulaw b/ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-mulaw
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-mulaw
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-mulaw
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-s16be b/ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-s16be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-s16be
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-s16be
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-s16le b/ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-s16le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-s16le
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-s16le
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-s24be b/ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-s24be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-s24be
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-s24be
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-s24le b/ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-s24le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-s24le
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-s24le
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-s32be b/ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-s32be
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-s32be
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-s32be
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-s32le b/ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-s32le
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-s32le
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-s32le
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-s8 b/ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-s8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-s8
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-s8
diff --git a/ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-u8 b/ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-u8
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/acodec-pcm-u8
rename to ffmpeg-2-8-12/tests/ref/seek/acodec-pcm-u8
diff --git a/ffmpeg-2-8-11/tests/ref/seek/extra-mp3 b/ffmpeg-2-8-12/tests/ref/seek/extra-mp3
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/extra-mp3
rename to ffmpeg-2-8-12/tests/ref/seek/extra-mp3
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-aiff b/ffmpeg-2-8-12/tests/ref/seek/lavf-aiff
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-aiff
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-aiff
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-alaw b/ffmpeg-2-8-12/tests/ref/seek/lavf-alaw
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-alaw
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-alaw
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-asf b/ffmpeg-2-8-12/tests/ref/seek/lavf-asf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-asf
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-asf
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-au b/ffmpeg-2-8-12/tests/ref/seek/lavf-au
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-au
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-au
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-avi b/ffmpeg-2-8-12/tests/ref/seek/lavf-avi
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-avi
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-avi
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-bmp b/ffmpeg-2-8-12/tests/ref/seek/lavf-bmp
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-bmp
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-bmp
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-dv_fmt b/ffmpeg-2-8-12/tests/ref/seek/lavf-dv_fmt
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-dv_fmt
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-dv_fmt
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-ffm b/ffmpeg-2-8-12/tests/ref/seek/lavf-ffm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-ffm
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-ffm
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-flv_fmt b/ffmpeg-2-8-12/tests/ref/seek/lavf-flv_fmt
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-flv_fmt
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-flv_fmt
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-gif b/ffmpeg-2-8-12/tests/ref/seek/lavf-gif
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-gif
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-gif
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-gxf b/ffmpeg-2-8-12/tests/ref/seek/lavf-gxf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-gxf
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-gxf
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-jpg b/ffmpeg-2-8-12/tests/ref/seek/lavf-jpg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-jpg
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-jpg
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-mkv b/ffmpeg-2-8-12/tests/ref/seek/lavf-mkv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-mkv
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-mkv
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-mmf b/ffmpeg-2-8-12/tests/ref/seek/lavf-mmf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-mmf
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-mmf
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-mov b/ffmpeg-2-8-12/tests/ref/seek/lavf-mov
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-mov
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-mov
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-mpg b/ffmpeg-2-8-12/tests/ref/seek/lavf-mpg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-mpg
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-mpg
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-mulaw b/ffmpeg-2-8-12/tests/ref/seek/lavf-mulaw
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-mulaw
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-mulaw
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-mxf b/ffmpeg-2-8-12/tests/ref/seek/lavf-mxf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-mxf
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-mxf
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-mxf_d10 b/ffmpeg-2-8-12/tests/ref/seek/lavf-mxf_d10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-mxf_d10
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-mxf_d10
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-mxf_opatom b/ffmpeg-2-8-12/tests/ref/seek/lavf-mxf_opatom
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-mxf_opatom
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-mxf_opatom
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-mxf_opatom_audio b/ffmpeg-2-8-12/tests/ref/seek/lavf-mxf_opatom_audio
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-mxf_opatom_audio
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-mxf_opatom_audio
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-nut b/ffmpeg-2-8-12/tests/ref/seek/lavf-nut
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-nut
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-nut
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-ogg b/ffmpeg-2-8-12/tests/ref/seek/lavf-ogg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-ogg
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-ogg
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-pbmpipe b/ffmpeg-2-8-12/tests/ref/seek/lavf-pbmpipe
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-pbmpipe
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-pbmpipe
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-pcx b/ffmpeg-2-8-12/tests/ref/seek/lavf-pcx
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-pcx
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-pcx
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-pgm b/ffmpeg-2-8-12/tests/ref/seek/lavf-pgm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-pgm
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-pgm
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-pgmpipe b/ffmpeg-2-8-12/tests/ref/seek/lavf-pgmpipe
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-pgmpipe
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-pgmpipe
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-ppm b/ffmpeg-2-8-12/tests/ref/seek/lavf-ppm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-ppm
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-ppm
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-ppmpipe b/ffmpeg-2-8-12/tests/ref/seek/lavf-ppmpipe
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-ppmpipe
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-ppmpipe
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-rm b/ffmpeg-2-8-12/tests/ref/seek/lavf-rm
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-rm
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-rm
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-sgi b/ffmpeg-2-8-12/tests/ref/seek/lavf-sgi
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-sgi
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-sgi
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-swf b/ffmpeg-2-8-12/tests/ref/seek/lavf-swf
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-swf
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-swf
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-tga b/ffmpeg-2-8-12/tests/ref/seek/lavf-tga
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-tga
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-tga
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-tiff b/ffmpeg-2-8-12/tests/ref/seek/lavf-tiff
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-tiff
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-tiff
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-ts b/ffmpeg-2-8-12/tests/ref/seek/lavf-ts
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-ts
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-ts
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-voc b/ffmpeg-2-8-12/tests/ref/seek/lavf-voc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-voc
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-voc
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-wav b/ffmpeg-2-8-12/tests/ref/seek/lavf-wav
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-wav
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-wav
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-wtv b/ffmpeg-2-8-12/tests/ref/seek/lavf-wtv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-wtv
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-wtv
diff --git a/ffmpeg-2-8-11/tests/ref/seek/lavf-yuv4mpeg b/ffmpeg-2-8-12/tests/ref/seek/lavf-yuv4mpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/lavf-yuv4mpeg
rename to ffmpeg-2-8-12/tests/ref/seek/lavf-yuv4mpeg
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-asv1 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-asv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-asv1
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-asv1
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-asv2 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-asv2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-asv2
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-asv2
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-dnxhd-1080i b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-dnxhd-1080i
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-dnxhd-1080i
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-dnxhd-1080i
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-dnxhd-720p b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-dnxhd-720p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-dnxhd-720p
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-dnxhd-720p
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-dnxhd-720p-rd b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-dnxhd-720p-rd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-dnxhd-720p-rd
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-dnxhd-720p-rd
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-dv b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-dv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-dv
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-dv
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-dv-411 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-dv-411
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-dv-411
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-dv-411
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-dv-50 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-dv-50
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-dv-50
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-dv-50
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-ffv1 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-ffv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-ffv1
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-ffv1
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-flashsv b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-flashsv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-flashsv
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-flashsv
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-flv b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-flv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-flv
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-flv
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-h261 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-h261
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-h261
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-h261
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-h263 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-h263
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-h263
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-h263
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-h263p b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-h263p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-h263p
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-h263p
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-huffyuv b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-huffyuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-huffyuv
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-huffyuv
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-jpegls b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-jpegls
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-jpegls
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-jpegls
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-ljpeg b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-ljpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-ljpeg
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-ljpeg
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mjpeg b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mjpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mjpeg
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mjpeg
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg1 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg1
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg1
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg1b b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg1b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg1b
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg1b
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg2-422 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg2-422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg2-422
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg2-422
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg2-idct-int b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg2-idct-int
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg2-idct-int
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg2-idct-int
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg2-ilace b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg2-ilace
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg2-ilace
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg2-ilace
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg2-ivlc-qprd b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg2-ivlc-qprd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg2-ivlc-qprd
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg2-ivlc-qprd
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg2-thread b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg2-thread
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg2-thread
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg2-thread
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg2-thread-ivlc b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg2-thread-ivlc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg2-thread-ivlc
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg2-thread-ivlc
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-adap b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-adap
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-adap
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-adap
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-adv b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-adv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-adv
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-adv
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-error b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-error
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-error
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-error
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-nr b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-nr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-nr
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-nr
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-nsse b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-nsse
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-nsse
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-nsse
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-qpel b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-qpel
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-qpel
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-qpel
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-qprd b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-qprd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-qprd
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-qprd
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-rc b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-rc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-rc
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-rc
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-thread b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-thread
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-mpeg4-thread
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-mpeg4-thread
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-msmpeg4 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-msmpeg4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-msmpeg4
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-msmpeg4
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-msmpeg4v2 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-msmpeg4v2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-msmpeg4v2
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-msmpeg4v2
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-rgb b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-rgb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-rgb
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-rgb
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-roqvideo b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-roqvideo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-roqvideo
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-roqvideo
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-rv10 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-rv10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-rv10
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-rv10
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-rv20 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-rv20
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-rv20
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-rv20
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-snow b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-snow
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-snow
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-snow
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-snow-ll b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-snow-ll
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-snow-ll
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-snow-ll
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-svq1 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-svq1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-svq1
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-svq1
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-wmv1 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-wmv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-wmv1
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-wmv1
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-wmv2 b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-wmv2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-wmv2
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-wmv2
diff --git a/ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-yuv b/ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-yuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/seek/vsynth_lena-yuv
rename to ffmpeg-2-8-12/tests/ref/seek/vsynth_lena-yuv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-amv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-amv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-amv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-amv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-asv1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-asv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-asv1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-asv1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-asv2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-asv2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-asv2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-asv2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-avui b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-avui
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-avui
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-avui
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-cinepak b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-cinepak
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-cinepak
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-cinepak
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-cljr b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-cljr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-cljr
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-cljr
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dnxhd-1080i b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dnxhd-1080i
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dnxhd-1080i
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dnxhd-1080i
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dnxhd-1080i-colr b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dnxhd-1080i-colr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dnxhd-1080i-colr
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dnxhd-1080i-colr
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dnxhd-720p b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dnxhd-720p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dnxhd-720p
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dnxhd-720p
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dnxhd-720p-10bit b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dnxhd-720p-10bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dnxhd-720p-10bit
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dnxhd-720p-10bit
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dnxhd-720p-rd b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dnxhd-720p-rd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dnxhd-720p-rd
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dnxhd-720p-rd
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dnxhd_1080i b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dnxhd_1080i
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dnxhd_1080i
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dnxhd_1080i
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dv-411 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dv-411
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dv-411
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dv-411
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dv-50 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dv-50
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dv-50
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dv-50
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dv_411 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dv_411
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-dv_411
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-dv_411
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffv1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffv1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffv1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffv1-v0 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffv1-v0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffv1-v0
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffv1-v0
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffv1-v3-bgr0 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffv1-v3-bgr0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffv1-v3-bgr0
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffv1-v3-bgr0
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffv1-v3-yuv420p b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffv1-v3-yuv420p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffv1-v3-yuv420p
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffv1-v3-yuv420p
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffv1-v3-yuv422p10 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffv1-v3-yuv422p10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffv1-v3-yuv422p10
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffv1-v3-yuv422p10
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffv1-v3-yuv444p16 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffv1-v3-yuv444p16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffv1-v3-yuv444p16
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffv1-v3-yuv444p16
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffvhuff b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffvhuff
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffvhuff
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffvhuff
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffvhuff420p12 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffvhuff420p12
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffvhuff420p12
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffvhuff420p12
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffvhuff422p10left b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffvhuff422p10left
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffvhuff422p10left
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffvhuff422p10left
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffvhuff444 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffvhuff444
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffvhuff444
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffvhuff444
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffvhuff444p16 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffvhuff444p16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ffvhuff444p16
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ffvhuff444p16
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-flashsv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-flashsv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-flashsv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-flashsv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-flashsv2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-flashsv2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-flashsv2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-flashsv2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-flv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-flv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-flv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-flv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-h261 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-h261
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-h261
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-h261
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-h261-trellis b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-h261-trellis
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-h261-trellis
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-h261-trellis
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-h263 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-h263
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-h263
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-h263
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-h263-obmc b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-h263-obmc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-h263-obmc
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-h263-obmc
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-h263p b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-h263p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-h263p
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-h263p
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-huffyuv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-huffyuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-huffyuv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-huffyuv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-huffyuvbgr24 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-huffyuvbgr24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-huffyuvbgr24
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-huffyuvbgr24
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-huffyuvbgra b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-huffyuvbgra
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-huffyuvbgra
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-huffyuvbgra
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-jpeg2000 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-jpeg2000
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-jpeg2000
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-jpeg2000
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-jpeg2000-97 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-jpeg2000-97
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-jpeg2000-97
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-jpeg2000-97
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-jpegls b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-jpegls
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-jpegls
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-jpegls
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ljpeg b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ljpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-ljpeg
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-ljpeg
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mjpeg b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mjpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mjpeg
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mjpeg
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mjpeg-422 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mjpeg-422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mjpeg-422
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mjpeg-422
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mjpeg-444 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mjpeg-444
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mjpeg-444
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mjpeg-444
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mjpeg-trell b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mjpeg-trell
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mjpeg-trell
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mjpeg-trell
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg1b b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg1b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg1b
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg1b
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg2-422 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg2-422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg2-422
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg2-422
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg2-idct-int b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg2-idct-int
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg2-idct-int
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg2-idct-int
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg2-ilace b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg2-ilace
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg2-ilace
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg2-ilace
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg2-ivlc-qprd b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg2-ivlc-qprd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg2-ivlc-qprd
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg2-ivlc-qprd
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg2-thread b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg2-thread
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg2-thread
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg2-thread
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg2-thread-ivlc b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg2-thread-ivlc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg2-thread-ivlc
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg2-thread-ivlc
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-adap b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-adap
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-adap
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-adap
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-adv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-adv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-adv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-adv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-error b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-error
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-error
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-error
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-nr b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-nr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-nr
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-nr
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-nsse b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-nsse
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-nsse
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-nsse
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-qpel b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-qpel
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-qpel
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-qpel
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-qprd b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-qprd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-qprd
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-qprd
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-rc b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-rc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-rc
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-rc
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-thread b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-thread
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpeg4-thread
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpeg4-thread
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpng b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpng
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-mpng
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-mpng
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-msmpeg4 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-msmpeg4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-msmpeg4
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-msmpeg4
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-msmpeg4v2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-msmpeg4v2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-msmpeg4v2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-msmpeg4v2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-msvideo1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-msvideo1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-msvideo1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-msvideo1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-prores b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-prores
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-prores
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-prores
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-prores_ks b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-prores_ks
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-prores_ks
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-prores_ks
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-qtrle b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-qtrle
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-qtrle
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-qtrle
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-qtrlegray b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-qtrlegray
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-qtrlegray
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-qtrlegray
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-r210 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-r210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-r210
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-r210
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-rgb b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-rgb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-rgb
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-rgb
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-roqvideo b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-roqvideo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-roqvideo
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-roqvideo
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-rv10 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-rv10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-rv10
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-rv10
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-rv20 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-rv20
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-rv20
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-rv20
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-snow b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-snow
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-snow
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-snow
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-snow-hpel b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-snow-hpel
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-snow-hpel
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-snow-hpel
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-snow-ll b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-snow-ll
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-snow-ll
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-snow-ll
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-svq1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-svq1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-svq1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-svq1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-v210 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-v210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-v210
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-v210
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-v308 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-v308
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-v308
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-v308
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-v408 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-v408
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-v408
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-v408
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-wmv1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-wmv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-wmv1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-wmv1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-wmv2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-wmv2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-wmv2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-wmv2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-xface b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-xface
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-xface
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-xface
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-y41p b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-y41p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-y41p
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-y41p
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-yuv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-yuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-yuv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-yuv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-yuv4 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-yuv4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-yuv4
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-yuv4
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-zlib b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-zlib
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-zlib
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-zlib
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-zmbv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-zmbv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth1-zmbv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth1-zmbv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-amv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-amv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-amv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-amv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-asv1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-asv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-asv1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-asv1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-asv2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-asv2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-asv2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-asv2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-avui b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-avui
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-avui
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-avui
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-cinepak b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-cinepak
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-cinepak
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-cinepak
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-cljr b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-cljr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-cljr
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-cljr
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dnxhd-1080i b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dnxhd-1080i
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dnxhd-1080i
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dnxhd-1080i
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dnxhd-1080i-colr b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dnxhd-1080i-colr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dnxhd-1080i-colr
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dnxhd-1080i-colr
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dnxhd-720p b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dnxhd-720p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dnxhd-720p
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dnxhd-720p
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dnxhd-720p-10bit b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dnxhd-720p-10bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dnxhd-720p-10bit
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dnxhd-720p-10bit
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dnxhd-720p-rd b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dnxhd-720p-rd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dnxhd-720p-rd
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dnxhd-720p-rd
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dv-411 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dv-411
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dv-411
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dv-411
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dv-50 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dv-50
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-dv-50
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-dv-50
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffv1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffv1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffv1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffv1-v0 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffv1-v0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffv1-v0
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffv1-v0
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffv1-v3-bgr0 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffv1-v3-bgr0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffv1-v3-bgr0
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffv1-v3-bgr0
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffv1-v3-yuv420p b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffv1-v3-yuv420p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffv1-v3-yuv420p
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffv1-v3-yuv420p
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffv1-v3-yuv422p10 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffv1-v3-yuv422p10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffv1-v3-yuv422p10
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffv1-v3-yuv422p10
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffv1-v3-yuv444p16 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffv1-v3-yuv444p16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffv1-v3-yuv444p16
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffv1-v3-yuv444p16
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffvhuff b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffvhuff
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffvhuff
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffvhuff
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffvhuff420p12 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffvhuff420p12
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffvhuff420p12
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffvhuff420p12
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffvhuff422p10left b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffvhuff422p10left
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffvhuff422p10left
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffvhuff422p10left
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffvhuff444 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffvhuff444
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffvhuff444
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffvhuff444
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffvhuff444p16 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffvhuff444p16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ffvhuff444p16
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ffvhuff444p16
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-flashsv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-flashsv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-flashsv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-flashsv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-flashsv2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-flashsv2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-flashsv2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-flashsv2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-flv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-flv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-flv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-flv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-h261 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-h261
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-h261
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-h261
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-h261-trellis b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-h261-trellis
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-h261-trellis
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-h261-trellis
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-h263 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-h263
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-h263
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-h263
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-h263-obmc b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-h263-obmc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-h263-obmc
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-h263-obmc
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-h263p b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-h263p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-h263p
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-h263p
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-huffyuv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-huffyuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-huffyuv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-huffyuv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-huffyuvbgr24 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-huffyuvbgr24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-huffyuvbgr24
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-huffyuvbgr24
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-huffyuvbgra b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-huffyuvbgra
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-huffyuvbgra
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-huffyuvbgra
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-jpeg2000 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-jpeg2000
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-jpeg2000
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-jpeg2000
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-jpeg2000-97 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-jpeg2000-97
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-jpeg2000-97
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-jpeg2000-97
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-jpegls b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-jpegls
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-jpegls
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-jpegls
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ljpeg b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ljpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-ljpeg
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-ljpeg
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mjpeg b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mjpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mjpeg
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mjpeg
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mjpeg-422 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mjpeg-422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mjpeg-422
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mjpeg-422
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mjpeg-444 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mjpeg-444
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mjpeg-444
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mjpeg-444
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mjpeg-trell b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mjpeg-trell
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mjpeg-trell
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mjpeg-trell
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg1b b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg1b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg1b
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg1b
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg2-422 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg2-422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg2-422
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg2-422
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg2-idct-int b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg2-idct-int
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg2-idct-int
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg2-idct-int
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg2-ilace b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg2-ilace
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg2-ilace
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg2-ilace
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg2-ivlc-qprd b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg2-ivlc-qprd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg2-ivlc-qprd
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg2-ivlc-qprd
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg2-thread b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg2-thread
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg2-thread
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg2-thread
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg2-thread-ivlc b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg2-thread-ivlc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg2-thread-ivlc
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg2-thread-ivlc
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-adap b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-adap
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-adap
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-adap
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-adv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-adv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-adv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-adv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-error b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-error
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-error
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-error
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-nr b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-nr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-nr
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-nr
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-nsse b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-nsse
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-nsse
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-nsse
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-qpel b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-qpel
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-qpel
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-qpel
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-qprd b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-qprd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-qprd
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-qprd
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-rc b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-rc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-rc
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-rc
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-thread b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-thread
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpeg4-thread
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpeg4-thread
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpng b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpng
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-mpng
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-mpng
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-msmpeg4 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-msmpeg4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-msmpeg4
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-msmpeg4
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-msmpeg4v2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-msmpeg4v2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-msmpeg4v2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-msmpeg4v2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-msvideo1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-msvideo1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-msvideo1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-msvideo1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-prores b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-prores
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-prores
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-prores
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-prores_ks b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-prores_ks
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-prores_ks
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-prores_ks
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-qtrle b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-qtrle
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-qtrle
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-qtrle
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-qtrlegray b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-qtrlegray
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-qtrlegray
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-qtrlegray
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-r210 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-r210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-r210
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-r210
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-rgb b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-rgb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-rgb
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-rgb
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-roqvideo b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-roqvideo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-roqvideo
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-roqvideo
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-rv10 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-rv10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-rv10
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-rv10
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-rv20 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-rv20
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-rv20
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-rv20
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-snow b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-snow
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-snow
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-snow
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-snow-hpel b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-snow-hpel
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-snow-hpel
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-snow-hpel
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-snow-ll b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-snow-ll
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-snow-ll
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-snow-ll
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-svq1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-svq1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-svq1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-svq1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-v210 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-v210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-v210
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-v210
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-v308 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-v308
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-v308
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-v308
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-v408 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-v408
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-v408
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-v408
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-wmv1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-wmv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-wmv1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-wmv1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-wmv2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-wmv2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-wmv2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-wmv2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-xface b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-xface
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-xface
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-xface
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-y41p b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-y41p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-y41p
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-y41p
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-yuv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-yuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-yuv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-yuv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-yuv4 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-yuv4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-yuv4
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-yuv4
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-zlib b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-zlib
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth2-zlib
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth2-zlib
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-amv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-amv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-amv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-amv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-asv1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-asv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-asv1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-asv1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-asv2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-asv2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-asv2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-asv2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-cljr b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-cljr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-cljr
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-cljr
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-dnxhd-1080i-colr b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-dnxhd-1080i-colr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-dnxhd-1080i-colr
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-dnxhd-1080i-colr
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffv1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffv1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffv1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffv1-v0 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffv1-v0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffv1-v0
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffv1-v0
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffv1-v3-bgr0 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffv1-v3-bgr0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffv1-v3-bgr0
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffv1-v3-bgr0
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffv1-v3-yuv420p b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffv1-v3-yuv420p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffv1-v3-yuv420p
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffv1-v3-yuv420p
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffv1-v3-yuv422p10 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffv1-v3-yuv422p10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffv1-v3-yuv422p10
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffv1-v3-yuv422p10
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffv1-v3-yuv444p16 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffv1-v3-yuv444p16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffv1-v3-yuv444p16
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffv1-v3-yuv444p16
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffvhuff b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffvhuff
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffvhuff
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffvhuff
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffvhuff420p12 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffvhuff420p12
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffvhuff420p12
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffvhuff420p12
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffvhuff422p10left b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffvhuff422p10left
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffvhuff422p10left
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffvhuff422p10left
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffvhuff444 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffvhuff444
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffvhuff444
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffvhuff444
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffvhuff444p16 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffvhuff444p16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ffvhuff444p16
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ffvhuff444p16
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-flashsv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-flashsv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-flashsv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-flashsv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-flashsv2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-flashsv2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-flashsv2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-flashsv2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-flv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-flv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-flv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-flv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-huffyuv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-huffyuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-huffyuv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-huffyuv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-huffyuvbgr24 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-huffyuvbgr24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-huffyuvbgr24
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-huffyuvbgr24
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-huffyuvbgra b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-huffyuvbgra
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-huffyuvbgra
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-huffyuvbgra
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-jpeg2000 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-jpeg2000
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-jpeg2000
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-jpeg2000
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-jpeg2000-97 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-jpeg2000-97
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-jpeg2000-97
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-jpeg2000-97
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-jpegls b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-jpegls
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-jpegls
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-jpegls
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ljpeg b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ljpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-ljpeg
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-ljpeg
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mjpeg b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mjpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mjpeg
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mjpeg
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mjpeg-422 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mjpeg-422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mjpeg-422
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mjpeg-422
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mjpeg-444 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mjpeg-444
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mjpeg-444
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mjpeg-444
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mjpeg-trell b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mjpeg-trell
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mjpeg-trell
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mjpeg-trell
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg1b b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg1b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg1b
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg1b
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg2-422 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg2-422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg2-422
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg2-422
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg2-idct-int b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg2-idct-int
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg2-idct-int
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg2-idct-int
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg2-ilace b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg2-ilace
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg2-ilace
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg2-ilace
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg2-ivlc-qprd b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg2-ivlc-qprd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg2-ivlc-qprd
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg2-ivlc-qprd
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg2-thread b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg2-thread
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg2-thread
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg2-thread
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg2-thread-ivlc b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg2-thread-ivlc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg2-thread-ivlc
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg2-thread-ivlc
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-adap b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-adap
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-adap
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-adap
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-adv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-adv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-adv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-adv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-error b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-error
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-error
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-error
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-nr b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-nr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-nr
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-nr
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-nsse b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-nsse
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-nsse
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-nsse
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-qpel b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-qpel
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-qpel
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-qpel
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-qprd b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-qprd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-qprd
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-qprd
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-rc b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-rc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-rc
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-rc
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-thread b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-thread
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpeg4-thread
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpeg4-thread
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpng b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpng
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-mpng
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-mpng
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-msmpeg4 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-msmpeg4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-msmpeg4
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-msmpeg4
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-msmpeg4v2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-msmpeg4v2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-msmpeg4v2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-msmpeg4v2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-prores b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-prores
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-prores
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-prores
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-prores_ks b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-prores_ks
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-prores_ks
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-prores_ks
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-qtrle b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-qtrle
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-qtrle
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-qtrle
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-r210 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-r210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-r210
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-r210
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-rgb b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-rgb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-rgb
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-rgb
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-svq1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-svq1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-svq1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-svq1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-v210 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-v210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-v210
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-v210
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-v308 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-v308
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-v308
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-v308
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-v408 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-v408
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-v408
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-v408
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-wmv1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-wmv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-wmv1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-wmv1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-wmv2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-wmv2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-wmv2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-wmv2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-xface b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-xface
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-xface
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-xface
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-yuv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-yuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-yuv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-yuv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-yuv4 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-yuv4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-yuv4
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-yuv4
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-zlib b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-zlib
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth3-zlib
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth3-zlib
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-amv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-amv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-amv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-amv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-asv1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-asv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-asv1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-asv1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-asv2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-asv2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-asv2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-asv2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-avui b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-avui
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-avui
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-avui
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-cinepak b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-cinepak
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-cinepak
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-cinepak
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-cljr b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-cljr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-cljr
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-cljr
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dnxhd-1080i b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dnxhd-1080i
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dnxhd-1080i
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dnxhd-1080i
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dnxhd-1080i-colr b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dnxhd-1080i-colr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dnxhd-1080i-colr
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dnxhd-1080i-colr
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dnxhd-720p b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dnxhd-720p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dnxhd-720p
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dnxhd-720p
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dnxhd-720p-10bit b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dnxhd-720p-10bit
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dnxhd-720p-10bit
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dnxhd-720p-10bit
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dnxhd-720p-rd b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dnxhd-720p-rd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dnxhd-720p-rd
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dnxhd-720p-rd
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dnxhd_1080i b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dnxhd_1080i
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dnxhd_1080i
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dnxhd_1080i
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dv-411 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dv-411
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dv-411
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dv-411
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dv-50 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dv-50
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dv-50
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dv-50
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dv_411 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dv_411
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-dv_411
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-dv_411
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffv1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffv1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffv1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffv1-v0 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffv1-v0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffv1-v0
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffv1-v0
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffv1-v3-bgr0 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffv1-v3-bgr0
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffv1-v3-bgr0
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffv1-v3-bgr0
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv420 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv420
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv420
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv420
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv420p b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv420p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv420p
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv420p
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv422p10 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv422p10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv422p10
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv422p10
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv444p16 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv444p16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv444p16
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffv1-v3-yuv444p16
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffvhuff b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffvhuff
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffvhuff
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffvhuff
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffvhuff420p12 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffvhuff420p12
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffvhuff420p12
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffvhuff420p12
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffvhuff422p10left b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffvhuff422p10left
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffvhuff422p10left
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffvhuff422p10left
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffvhuff444 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffvhuff444
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffvhuff444
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffvhuff444
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffvhuff444p16 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffvhuff444p16
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ffvhuff444p16
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ffvhuff444p16
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-flashsv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-flashsv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-flashsv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-flashsv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-flashsv2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-flashsv2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-flashsv2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-flashsv2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-flv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-flv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-flv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-flv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-h261 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-h261
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-h261
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-h261
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-h261-trellis b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-h261-trellis
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-h261-trellis
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-h261-trellis
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-h263 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-h263
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-h263
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-h263
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-h263-obmc b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-h263-obmc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-h263-obmc
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-h263-obmc
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-h263p b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-h263p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-h263p
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-h263p
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-huffyuv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-huffyuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-huffyuv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-huffyuv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-huffyuvbgr24 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-huffyuvbgr24
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-huffyuvbgr24
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-huffyuvbgr24
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-huffyuvbgra b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-huffyuvbgra
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-huffyuvbgra
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-huffyuvbgra
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-jpeg2000 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-jpeg2000
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-jpeg2000
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-jpeg2000
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-jpeg2000-97 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-jpeg2000-97
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-jpeg2000-97
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-jpeg2000-97
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-jpegls b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-jpegls
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-jpegls
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-jpegls
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ljpeg b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ljpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-ljpeg
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-ljpeg
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mjpeg b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mjpeg
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mjpeg
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mjpeg
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mjpeg-422 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mjpeg-422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mjpeg-422
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mjpeg-422
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mjpeg-444 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mjpeg-444
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mjpeg-444
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mjpeg-444
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mjpeg-trell b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mjpeg-trell
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mjpeg-trell
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mjpeg-trell
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg1b b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg1b
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg1b
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg1b
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg2-422 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg2-422
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg2-422
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg2-422
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg2-idct-int b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg2-idct-int
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg2-idct-int
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg2-idct-int
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg2-ilace b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg2-ilace
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg2-ilace
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg2-ilace
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg2-ivlc-qprd b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg2-ivlc-qprd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg2-ivlc-qprd
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg2-ivlc-qprd
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg2-thread b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg2-thread
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg2-thread
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg2-thread
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg2-thread-ivlc b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg2-thread-ivlc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg2-thread-ivlc
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg2-thread-ivlc
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-adap b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-adap
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-adap
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-adap
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-adv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-adv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-adv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-adv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-error b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-error
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-error
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-error
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-nr b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-nr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-nr
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-nr
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-nsse b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-nsse
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-nsse
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-nsse
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-qpel b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-qpel
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-qpel
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-qpel
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-qprd b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-qprd
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-qprd
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-qprd
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-rc b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-rc
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-rc
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-rc
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-thread b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-thread
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpeg4-thread
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpeg4-thread
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpng b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpng
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-mpng
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-mpng
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-msmpeg4 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-msmpeg4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-msmpeg4
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-msmpeg4
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-msmpeg4v2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-msmpeg4v2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-msmpeg4v2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-msmpeg4v2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-msvideo1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-msvideo1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-msvideo1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-msvideo1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-prores b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-prores
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-prores
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-prores
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-prores_ks b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-prores_ks
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-prores_ks
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-prores_ks
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-qtrle b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-qtrle
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-qtrle
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-qtrle
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-qtrlegray b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-qtrlegray
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-qtrlegray
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-qtrlegray
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-r210 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-r210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-r210
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-r210
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-rgb b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-rgb
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-rgb
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-rgb
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-roqvideo b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-roqvideo
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-roqvideo
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-roqvideo
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-rv10 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-rv10
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-rv10
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-rv10
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-rv20 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-rv20
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-rv20
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-rv20
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-snow b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-snow
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-snow
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-snow
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-snow-hpel b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-snow-hpel
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-snow-hpel
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-snow-hpel
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-snow-ll b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-snow-ll
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-snow-ll
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-snow-ll
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-svq1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-svq1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-svq1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-svq1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-v210 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-v210
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-v210
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-v210
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-v308 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-v308
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-v308
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-v308
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-v408 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-v408
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-v408
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-v408
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-wmv1 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-wmv1
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-wmv1
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-wmv1
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-wmv2 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-wmv2
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-wmv2
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-wmv2
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-xface b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-xface
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-xface
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-xface
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-y41p b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-y41p
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-y41p
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-y41p
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-yuv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-yuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-yuv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-yuv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-yuv4 b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-yuv4
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-yuv4
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-yuv4
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-zlib b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-zlib
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-zlib
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-zlib
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-zmbv b/ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-zmbv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth/vsynth_lena-zmbv
rename to ffmpeg-2-8-12/tests/ref/vsynth/vsynth_lena-zmbv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth1/cljr b/ffmpeg-2-8-12/tests/ref/vsynth1/cljr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth1/cljr
rename to ffmpeg-2-8-12/tests/ref/vsynth1/cljr
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth1/yuv b/ffmpeg-2-8-12/tests/ref/vsynth1/yuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth1/yuv
rename to ffmpeg-2-8-12/tests/ref/vsynth1/yuv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth_lena/cljr b/ffmpeg-2-8-12/tests/ref/vsynth_lena/cljr
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth_lena/cljr
rename to ffmpeg-2-8-12/tests/ref/vsynth_lena/cljr
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth_lena/huffyuv b/ffmpeg-2-8-12/tests/ref/vsynth_lena/huffyuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth_lena/huffyuv
rename to ffmpeg-2-8-12/tests/ref/vsynth_lena/huffyuv
diff --git a/ffmpeg-2-8-11/tests/ref/vsynth_lena/yuv b/ffmpeg-2-8-12/tests/ref/vsynth_lena/yuv
similarity index 100%
rename from ffmpeg-2-8-11/tests/ref/vsynth_lena/yuv
rename to ffmpeg-2-8-12/tests/ref/vsynth_lena/yuv
diff --git a/ffmpeg-2-8-11/tests/reference.pnm b/ffmpeg-2-8-12/tests/reference.pnm
similarity index 100%
rename from ffmpeg-2-8-11/tests/reference.pnm
rename to ffmpeg-2-8-12/tests/reference.pnm
diff --git a/ffmpeg-2-8-11/tests/regression-funcs.sh b/ffmpeg-2-8-12/tests/regression-funcs.sh
similarity index 100%
rename from ffmpeg-2-8-11/tests/regression-funcs.sh
rename to ffmpeg-2-8-12/tests/regression-funcs.sh
diff --git a/ffmpeg-2-8-11/tests/rotozoom.c b/ffmpeg-2-8-12/tests/rotozoom.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/rotozoom.c
rename to ffmpeg-2-8-12/tests/rotozoom.c
diff --git a/ffmpeg-2-8-11/tests/test.ffmeta b/ffmpeg-2-8-12/tests/test.ffmeta
similarity index 100%
rename from ffmpeg-2-8-11/tests/test.ffmeta
rename to ffmpeg-2-8-12/tests/test.ffmeta
diff --git a/ffmpeg-2-8-11/tests/tiny_psnr.c b/ffmpeg-2-8-12/tests/tiny_psnr.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/tiny_psnr.c
rename to ffmpeg-2-8-12/tests/tiny_psnr.c
diff --git a/ffmpeg-2-8-11/tests/tiny_ssim.c b/ffmpeg-2-8-12/tests/tiny_ssim.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/tiny_ssim.c
rename to ffmpeg-2-8-12/tests/tiny_ssim.c
diff --git a/ffmpeg-2-8-11/tests/utils.c b/ffmpeg-2-8-12/tests/utils.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/utils.c
rename to ffmpeg-2-8-12/tests/utils.c
diff --git a/ffmpeg-2-8-11/tests/videogen.c b/ffmpeg-2-8-12/tests/videogen.c
similarity index 100%
rename from ffmpeg-2-8-11/tests/videogen.c
rename to ffmpeg-2-8-12/tests/videogen.c
diff --git a/ffmpeg-2-8-11/tools/aviocat.c b/ffmpeg-2-8-12/tools/aviocat.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/aviocat.c
rename to ffmpeg-2-8-12/tools/aviocat.c
diff --git a/ffmpeg-2-8-11/tools/bisect-create b/ffmpeg-2-8-12/tools/bisect-create
similarity index 100%
rename from ffmpeg-2-8-11/tools/bisect-create
rename to ffmpeg-2-8-12/tools/bisect-create
diff --git a/ffmpeg-2-8-11/tools/bookmarklets.html b/ffmpeg-2-8-12/tools/bookmarklets.html
similarity index 100%
rename from ffmpeg-2-8-11/tools/bookmarklets.html
rename to ffmpeg-2-8-12/tools/bookmarklets.html
diff --git a/ffmpeg-2-8-11/tools/build_libstagefright b/ffmpeg-2-8-12/tools/build_libstagefright
similarity index 100%
rename from ffmpeg-2-8-11/tools/build_libstagefright
rename to ffmpeg-2-8-12/tools/build_libstagefright
diff --git a/ffmpeg-2-8-11/tools/clean-diff b/ffmpeg-2-8-12/tools/clean-diff
similarity index 100%
rename from ffmpeg-2-8-11/tools/clean-diff
rename to ffmpeg-2-8-12/tools/clean-diff
diff --git a/ffmpeg-2-8-11/tools/coverity.c b/ffmpeg-2-8-12/tools/coverity.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/coverity.c
rename to ffmpeg-2-8-12/tools/coverity.c
diff --git a/ffmpeg-2-8-11/tools/crypto_bench.c b/ffmpeg-2-8-12/tools/crypto_bench.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/crypto_bench.c
rename to ffmpeg-2-8-12/tools/crypto_bench.c
diff --git a/ffmpeg-2-8-11/tools/cws2fws.c b/ffmpeg-2-8-12/tools/cws2fws.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/cws2fws.c
rename to ffmpeg-2-8-12/tools/cws2fws.c
diff --git a/ffmpeg-2-8-11/tools/dvd2concat b/ffmpeg-2-8-12/tools/dvd2concat
similarity index 100%
rename from ffmpeg-2-8-11/tools/dvd2concat
rename to ffmpeg-2-8-12/tools/dvd2concat
diff --git a/ffmpeg-2-8-11/tools/enum_options.c b/ffmpeg-2-8-12/tools/enum_options.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/enum_options.c
rename to ffmpeg-2-8-12/tools/enum_options.c
diff --git a/ffmpeg-2-8-11/tools/ffescape.c b/ffmpeg-2-8-12/tools/ffescape.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/ffescape.c
rename to ffmpeg-2-8-12/tools/ffescape.c
diff --git a/ffmpeg-2-8-11/tools/ffeval.c b/ffmpeg-2-8-12/tools/ffeval.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/ffeval.c
rename to ffmpeg-2-8-12/tools/ffeval.c
diff --git a/ffmpeg-2-8-11/tools/ffhash.c b/ffmpeg-2-8-12/tools/ffhash.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/ffhash.c
rename to ffmpeg-2-8-12/tools/ffhash.c
diff --git a/ffmpeg-2-8-11/tools/fourcc2pixfmt.c b/ffmpeg-2-8-12/tools/fourcc2pixfmt.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/fourcc2pixfmt.c
rename to ffmpeg-2-8-12/tools/fourcc2pixfmt.c
diff --git a/ffmpeg-2-8-11/tools/gen-rc b/ffmpeg-2-8-12/tools/gen-rc
similarity index 100%
rename from ffmpeg-2-8-11/tools/gen-rc
rename to ffmpeg-2-8-12/tools/gen-rc
diff --git a/ffmpeg-2-8-11/tools/graph2dot.c b/ffmpeg-2-8-12/tools/graph2dot.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/graph2dot.c
rename to ffmpeg-2-8-12/tools/graph2dot.c
diff --git a/ffmpeg-2-8-11/tools/ismindex.c b/ffmpeg-2-8-12/tools/ismindex.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/ismindex.c
rename to ffmpeg-2-8-12/tools/ismindex.c
diff --git a/ffmpeg-2-8-11/tools/make_chlayout_test b/ffmpeg-2-8-12/tools/make_chlayout_test
similarity index 100%
rename from ffmpeg-2-8-11/tools/make_chlayout_test
rename to ffmpeg-2-8-12/tools/make_chlayout_test
diff --git a/ffmpeg-2-8-11/tools/missing_codec_desc b/ffmpeg-2-8-12/tools/missing_codec_desc
similarity index 100%
rename from ffmpeg-2-8-11/tools/missing_codec_desc
rename to ffmpeg-2-8-12/tools/missing_codec_desc
diff --git a/ffmpeg-2-8-11/tools/normalize.py b/ffmpeg-2-8-12/tools/normalize.py
similarity index 100%
rename from ffmpeg-2-8-11/tools/normalize.py
rename to ffmpeg-2-8-12/tools/normalize.py
diff --git a/ffmpeg-2-8-11/tools/patcheck b/ffmpeg-2-8-12/tools/patcheck
similarity index 100%
rename from ffmpeg-2-8-11/tools/patcheck
rename to ffmpeg-2-8-12/tools/patcheck
diff --git a/ffmpeg-2-8-11/tools/pktdumper.c b/ffmpeg-2-8-12/tools/pktdumper.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/pktdumper.c
rename to ffmpeg-2-8-12/tools/pktdumper.c
diff --git a/ffmpeg-2-8-11/tools/plotframes b/ffmpeg-2-8-12/tools/plotframes
similarity index 100%
rename from ffmpeg-2-8-11/tools/plotframes
rename to ffmpeg-2-8-12/tools/plotframes
diff --git a/ffmpeg-2-8-11/tools/probetest.c b/ffmpeg-2-8-12/tools/probetest.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/probetest.c
rename to ffmpeg-2-8-12/tools/probetest.c
diff --git a/ffmpeg-2-8-11/tools/qt-faststart.c b/ffmpeg-2-8-12/tools/qt-faststart.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/qt-faststart.c
rename to ffmpeg-2-8-12/tools/qt-faststart.c
diff --git a/ffmpeg-2-8-11/tools/seek_print.c b/ffmpeg-2-8-12/tools/seek_print.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/seek_print.c
rename to ffmpeg-2-8-12/tools/seek_print.c
diff --git a/ffmpeg-2-8-11/tools/sidxindex.c b/ffmpeg-2-8-12/tools/sidxindex.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/sidxindex.c
rename to ffmpeg-2-8-12/tools/sidxindex.c
diff --git a/ffmpeg-2-8-11/tools/trasher.c b/ffmpeg-2-8-12/tools/trasher.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/trasher.c
rename to ffmpeg-2-8-12/tools/trasher.c
diff --git a/ffmpeg-2-8-11/tools/uncoded_frame.c b/ffmpeg-2-8-12/tools/uncoded_frame.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/uncoded_frame.c
rename to ffmpeg-2-8-12/tools/uncoded_frame.c
diff --git a/ffmpeg-2-8-11/tools/unwrap-diff b/ffmpeg-2-8-12/tools/unwrap-diff
similarity index 100%
rename from ffmpeg-2-8-11/tools/unwrap-diff
rename to ffmpeg-2-8-12/tools/unwrap-diff
diff --git a/ffmpeg-2-8-11/tools/yuvcmp.c b/ffmpeg-2-8-12/tools/yuvcmp.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/yuvcmp.c
rename to ffmpeg-2-8-12/tools/yuvcmp.c
diff --git a/ffmpeg-2-8-11/tools/zmqsend.c b/ffmpeg-2-8-12/tools/zmqsend.c
similarity index 100%
rename from ffmpeg-2-8-11/tools/zmqsend.c
rename to ffmpeg-2-8-12/tools/zmqsend.c
diff --git a/ffmpeg-2-8-11/tools/zmqshell.py b/ffmpeg-2-8-12/tools/zmqshell.py
similarity index 100%
rename from ffmpeg-2-8-11/tools/zmqshell.py
rename to ffmpeg-2-8-12/tools/zmqshell.py
diff --git a/ffmpeg-2-8-11/version.sh b/ffmpeg-2-8-12/version.sh
similarity index 100%
rename from ffmpeg-2-8-11/version.sh
rename to ffmpeg-2-8-12/version.sh
--
VLC media player packaging
More information about the pkg-multimedia-commits
mailing list